Commit d83f8865 by Patrick O'Carroll

migrated jquery.flot.events to ts

parent 0841e67d
define([ import $ from 'jquery';
'jquery', import _ from 'lodash';
'lodash', import angular from 'angular';
'angular', import Drop from 'tether-drop';
'tether-drop',
], function createAnnotationToolip(element, event, plot) {
function ($, _, angular, Drop) { let injector = angular.element(document).injector();
'use strict'; let content = document.createElement('div');
function createAnnotationToolip(element, event, plot) {
var injector = angular.element(document).injector();
var content = document.createElement('div');
content.innerHTML = '<annotation-tooltip event="event" on-edit="onEdit()"></annotation-tooltip>'; content.innerHTML = '<annotation-tooltip event="event" on-edit="onEdit()"></annotation-tooltip>';
injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) { injector.invoke([
var eventManager = plot.getOptions().events.manager; '$compile',
var tmpScope = $rootScope.$new(true); '$rootScope',
function($compile, $rootScope) {
let eventManager = plot.getOptions().events.manager;
let tmpScope = $rootScope.$new(true);
tmpScope.event = event; tmpScope.event = event;
tmpScope.onEdit = function() { tmpScope.onEdit = function() {
eventManager.editEvent(event); eventManager.editEvent(event);
...@@ -24,16 +23,16 @@ function ($, _, angular, Drop) { ...@@ -24,16 +23,16 @@ function ($, _, angular, Drop) {
tmpScope.$digest(); tmpScope.$digest();
tmpScope.$destroy(); tmpScope.$destroy();
var drop = new Drop({ let drop = new Drop({
target: element[0], target: element[0],
content: content, content: content,
position: "bottom center", position: 'bottom center',
classes: 'drop-popover drop-popover--annotation', classes: 'drop-popover drop-popover--annotation',
openOn: 'hover', openOn: 'hover',
hoverCloseDelay: 200, hoverCloseDelay: 200,
tetherOptions: { tetherOptions: {
constraints: [{to: 'window', pin: true, attachment: "both"}] constraints: [{ to: 'window', pin: true, attachment: 'both' }],
} },
}); });
drop.open(); drop.open();
...@@ -43,35 +42,38 @@ function ($, _, angular, Drop) { ...@@ -43,35 +42,38 @@ function ($, _, angular, Drop) {
drop.destroy(); drop.destroy();
}); });
}); });
}]); },
} ]);
}
var markerElementToAttachTo = null; let markerElementToAttachTo = null;
function createEditPopover(element, event, plot) { function createEditPopover(element, event, plot) {
var eventManager = plot.getOptions().events.manager; let eventManager = plot.getOptions().events.manager;
if (eventManager.editorOpen) { if (eventManager.editorOpen) {
// update marker element to attach to (needed in case of legend on the right // update marker element to attach to (needed in case of legend on the right
// when there is a double render pass and the initial marker element is removed) // when there is a double render pass and the inital marker element is removed)
markerElementToAttachTo = element; markerElementToAttachTo = element;
return; return;
} }
// mark as openend // mark as openend
eventManager.editorOpened(); eventManager.editorOpened();
// set marker element to attache to // set marker elment to attache to
markerElementToAttachTo = element; markerElementToAttachTo = element;
// wait for element to be attached and positioned // wait for element to be attached and positioned
setTimeout(function() { setTimeout(function() {
let injector = angular.element(document).injector();
var injector = angular.element(document).injector(); let content = document.createElement('div');
var content = document.createElement('div');
content.innerHTML = '<event-editor panel-ctrl="panelCtrl" event="event" close="close()"></event-editor>'; content.innerHTML = '<event-editor panel-ctrl="panelCtrl" event="event" close="close()"></event-editor>';
injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) { injector.invoke([
var scope = $rootScope.$new(true); '$compile',
var drop; '$rootScope',
function($compile, $rootScope) {
let scope = $rootScope.$new(true);
let drop;
scope.event = event; scope.event = event;
scope.panelCtrl = eventManager.panelCtrl; scope.panelCtrl = eventManager.panelCtrl;
...@@ -85,12 +87,12 @@ function ($, _, angular, Drop) { ...@@ -85,12 +87,12 @@ function ($, _, angular, Drop) {
drop = new Drop({ drop = new Drop({
target: markerElementToAttachTo[0], target: markerElementToAttachTo[0],
content: content, content: content,
position: "bottom center", position: 'bottom center',
classes: 'drop-popover drop-popover--form', classes: 'drop-popover drop-popover--form',
openOn: 'click', openOn: 'click',
tetherOptions: { tetherOptions: {
constraints: [{to: 'window', pin: true, attachment: "both"}] constraints: [{ to: 'window', pin: true, attachment: 'both' }],
} },
}); });
drop.open(); drop.open();
...@@ -104,12 +106,12 @@ function ($, _, angular, Drop) { ...@@ -104,12 +106,12 @@ function ($, _, angular, Drop) {
drop.destroy(); drop.destroy();
}); });
}); });
}]); },
]);
}, 100); }, 100);
} }
/* /*
* jquery.flot.events * jquery.flot.events
* *
* description: Flot plugin for adding events/markers to the plot * description: Flot plugin for adding events/markers to the plot
...@@ -124,52 +126,76 @@ function ($, _, angular, Drop) { ...@@ -124,52 +126,76 @@ function ($, _, angular, Drop) {
* released under MIT License and GPLv2+ * released under MIT License and GPLv2+
*/ */
/** /**
* A class that allows for the drawing an remove of some object * A class that allows for the drawing an remove of some object
*/ */
var DrawableEvent = function(object, drawFunc, clearFunc, moveFunc, left, top, width, height) { let DrawableEvent = function(object, drawFunc, clearFunc, moveFunc, left, top, width, height) {
var _object = object; let _object = object;
var _drawFunc = drawFunc; let _drawFunc = drawFunc;
var _clearFunc = clearFunc; let _clearFunc = clearFunc;
var _moveFunc = moveFunc; let _moveFunc = moveFunc;
var _position = { left: left, top: top }; let _position = { left: left, top: top };
var _width = width; let _width = width;
var _height = height; let _height = height;
this.width = function() { return _width; }; this.width = function() {
this.height = function() { return _height; }; return _width;
this.position = function() { return _position; }; };
this.draw = function() { _drawFunc(_object); }; this.height = function() {
this.clear = function() { _clearFunc(_object); }; return _height;
this.getObject = function() { return _object; }; };
this.position = function() {
return _position;
};
this.draw = function() {
_drawFunc(_object);
};
this.clear = function() {
_clearFunc(_object);
};
this.getObject = function() {
return _object;
};
this.moveTo = function(position) { this.moveTo = function(position) {
_position = position; _position = position;
_moveFunc(_object, _position); _moveFunc(_object, _position);
}; };
}; };
/** /**
* Event class that stores options (eventType, min, max, title, description) and the object to draw. * Event class that stores options (eventType, min, max, title, description) and the object to draw.
*/ */
var VisualEvent = function(options, drawableEvent) { let VisualEvent = function(options, drawableEvent) {
var _parent; let _parent;
var _options = options; let _options = options;
var _drawableEvent = drawableEvent; let _drawableEvent = drawableEvent;
var _hidden = false; let _hidden = false;
this.visual = function() { return _drawableEvent; }; this.visual = function() {
this.getOptions = function() { return _options; }; return _drawableEvent;
this.getParent = function() { return _parent; }; };
this.isHidden = function() { return _hidden; }; this.getOptions = function() {
this.hide = function() { _hidden = true; }; return _options;
this.unhide = function() { _hidden = false; }; };
this.getParent = function() {
return _parent;
};
this.isHidden = function() {
return _hidden;
}; };
this.hide = function() {
_hidden = true;
};
this.unhide = function() {
_hidden = false;
};
};
/** /**
* A Class that handles the event-markers inside the given plot * A Class that handles the event-markers inside the given plot
*/ */
var EventMarkers = function(plot) { let EventMarkers = function(plot) {
var _events = []; let _events = [];
this._types = []; this._types = [];
this._plot = plot; this._plot = plot;
...@@ -180,32 +206,37 @@ function ($, _, angular, Drop) { ...@@ -180,32 +206,37 @@ function ($, _, angular, Drop) {
}; };
this.setTypes = function(types) { this.setTypes = function(types) {
return this._types = types; return (this._types = types);
}; };
/** /**
* create internal objects for the given events * create internal objects for the given events
*/ */
this.setupEvents = function(events) { this.setupEvents = function(events) {
var that = this; let that = this;
var parts = _.partition(events, 'isRegion'); let parts = _.partition(events, 'isRegion');
var regions = parts[0]; let regions = parts[0];
events = parts[1]; events = parts[1];
$.each(events, function(index, event) { $.each(events, function(index, event) {
var ve = new VisualEvent(event, that._buildDiv(event)); let ve = new VisualEvent(event, that._buildDiv(event));
_events.push(ve); _events.push(ve);
}); });
$.each(regions, function (index, event) { $.each(regions, function(index, event) {
var vre = new VisualEvent(event, that._buildRegDiv(event)); let vre = new VisualEvent(event, that._buildRegDiv(event));
_events.push(vre); _events.push(vre);
}); });
_events.sort(function(a, b) { _events.sort(function(a, b) {
var ao = a.getOptions(), bo = b.getOptions(); let ao = a.getOptions(),
if (ao.min > bo.min) { return 1; } bo = b.getOptions();
if (ao.min < bo.min) { return -1; } if (ao.min > bo.min) {
return 1;
}
if (ao.min < bo.min) {
return -1;
}
return 0; return 0;
}); });
}; };
...@@ -214,15 +245,18 @@ function ($, _, angular, Drop) { ...@@ -214,15 +245,18 @@ function ($, _, angular, Drop) {
* draw the events to the plot * draw the events to the plot
*/ */
this.drawEvents = function() { this.drawEvents = function() {
var that = this; let that = this;
// var o = this._plot.getPlotOffset(); // let o = this._plot.getPlotOffset();
$.each(_events, function(index, event) { $.each(_events, function(index, event) {
// check event is inside the graph range // check event is inside the graph range
if (that._insidePlot(event.getOptions().min) && !event.isHidden()) { if (that._insidePlot(event.getOptions().min) && !event.isHidden()) {
event.visual().draw(); event.visual().draw();
} else { } else {
event.visual().getObject().hide(); event
.visual()
.getObject()
.hide();
} }
}); });
}; };
...@@ -231,9 +265,11 @@ function ($, _, angular, Drop) { ...@@ -231,9 +265,11 @@ function ($, _, angular, Drop) {
* update the position of the event-markers (e.g. after scrolling or zooming) * update the position of the event-markers (e.g. after scrolling or zooming)
*/ */
this.updateEvents = function() { this.updateEvents = function() {
var that = this; let that = this;
var o = this._plot.getPlotOffset(), left, top; let o = this._plot.getPlotOffset(),
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; left,
top;
let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];
$.each(_events, function(index, event) { $.each(_events, function(index, event) {
top = o.top + that._plot.height() - event.visual().height(); top = o.top + that._plot.height() - event.visual().height();
...@@ -256,21 +292,25 @@ function ($, _, angular, Drop) { ...@@ -256,21 +292,25 @@ function ($, _, angular, Drop) {
* create a DOM element for the given event * create a DOM element for the given event
*/ */
this._buildDiv = function(event) { this._buildDiv = function(event) {
var that = this; let that = this;
var container = this._plot.getPlaceholder(); let container = this._plot.getPlaceholder();
var o = this._plot.getPlotOffset(); let o = this._plot.getPlotOffset();
var axes = this._plot.getAxes(); let axes = this._plot.getAxes();
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];
var yaxis, top, left, color, markerSize, markerShow, lineStyle, lineWidth; let yaxis, top, left, color, markerSize, markerShow, lineStyle, lineWidth;
var markerTooltip; let markerTooltip;
// determine the y axis used // determine the y axis used
if (axes.yaxis && axes.yaxis.used) { yaxis = axes.yaxis; } if (axes.yaxis && axes.yaxis.used) {
if (axes.yaxis2 && axes.yaxis2.used) { yaxis = axes.yaxis2; } yaxis = axes.yaxis;
}
if (axes.yaxis2 && axes.yaxis2.used) {
yaxis = axes.yaxis2;
}
// map the eventType to a types object // map the eventType to a types object
var eventTypeId = event.eventType; let eventTypeId = event.eventType;
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) { if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) {
color = '#666'; color = '#666';
...@@ -308,84 +348,93 @@ function ($, _, angular, Drop) { ...@@ -308,84 +348,93 @@ function ($, _, angular, Drop) {
lineWidth = this._types[eventTypeId].lineWidth; lineWidth = this._types[eventTypeId].lineWidth;
} }
var topOffset = xaxis.options.eventSectionHeight || 0; let topOffset = xaxis.options.eventSectionHeight || 0;
topOffset = topOffset / 3; topOffset = topOffset / 3;
top = o.top + this._plot.height() + topOffset; top = o.top + this._plot.height() + topOffset;
left = xaxis.p2c(event.min) + o.left; left = xaxis.p2c(event.min) + o.left;
var line = $('<div class="events_line flot-temp-elem"></div>').css({ let line = $('<div class="events_line flot-temp-elem"></div>')
"position": "absolute", .css({
"opacity": 0.8, position: 'absolute',
"left": left + 'px', opacity: 0.8,
"top": 8, left: left + 'px',
"width": lineWidth + "px", top: 8,
"height": this._plot.height() + topOffset * 0.8, width: lineWidth + 'px',
"border-left-width": lineWidth + "px", height: this._plot.height() + topOffset * 0.8,
"border-left-style": lineStyle, 'border-left-width': lineWidth + 'px',
"border-left-color": color, 'border-left-style': lineStyle,
"color": color 'border-left-color': color,
color: color,
}) })
.appendTo(container); .appendTo(container);
if (markerShow) { if (markerShow) {
var marker = $('<div class="events_marker"></div>').css({ let marker = $('<div class="events_marker"></div>').css({
"position": "absolute", position: 'absolute',
"left": (-markerSize - Math.round(lineWidth / 2)) + "px", left: -markerSize - Math.round(lineWidth / 2) + 'px',
"font-size": 0, 'font-size': 0,
"line-height": 0, 'line-height': 0,
"width": 0, width: 0,
"height": 0, height: 0,
"border-left": markerSize+"px solid transparent", 'border-left': markerSize + 'px solid transparent',
"border-right": markerSize+"px solid transparent" 'border-right': markerSize + 'px solid transparent',
}); });
marker.appendTo(line); marker.appendTo(line);
if (this._types[eventTypeId] && this._types[eventTypeId].position && this._types[eventTypeId].position.toUpperCase() === 'BOTTOM') { if (
this._types[eventTypeId] &&
this._types[eventTypeId].position &&
this._types[eventTypeId].position.toUpperCase() === 'BOTTOM'
) {
marker.css({ marker.css({
"top": top-markerSize-8 +"px", top: top - markerSize - 8 + 'px',
"border-top": "none", 'border-top': 'none',
"border-bottom": markerSize+"px solid " + color 'border-bottom': markerSize + 'px solid ' + color,
}); });
} else { } else {
marker.css({ marker.css({
"top": "0px", top: '0px',
"border-top": markerSize+"px solid " + color, 'border-top': markerSize + 'px solid ' + color,
"border-bottom": "none" 'border-bottom': 'none',
}); });
} }
marker.data({ marker.data({
"event": event event: event,
}); });
var mouseenter = function() { let mouseenter = function() {
createAnnotationToolip(marker, $(this).data("event"), that._plot); createAnnotationToolip(marker, $(this).data('event'), that._plot);
}; };
if (event.editModel) { if (event.editModel) {
createEditPopover(marker, event.editModel, that._plot); createEditPopover(marker, event.editModel, that._plot);
} }
var mouseleave = function() { let mouseleave = function() {
that._plot.clearSelection(); that._plot.clearSelection();
}; };
if (markerTooltip) { if (markerTooltip) {
marker.css({ "cursor": "help" }); marker.css({ cursor: 'help' });
marker.hover(mouseenter, mouseleave); marker.hover(mouseenter, mouseleave);
} }
} }
var drawableEvent = new DrawableEvent( let drawableEvent = new DrawableEvent(
line, line,
function drawFunc(obj) { obj.show(); }, function drawFunc(obj) {
function(obj) { obj.remove(); }, obj.show();
},
function(obj) {
obj.remove();
},
function(obj, position) { function(obj, position) {
obj.css({ obj.css({
top: position.top, top: position.top,
left: position.left left: position.left,
}); });
}, },
left, left,
...@@ -400,21 +449,25 @@ function ($, _, angular, Drop) { ...@@ -400,21 +449,25 @@ function ($, _, angular, Drop) {
/** /**
* create a DOM element for the given region * create a DOM element for the given region
*/ */
this._buildRegDiv = function (event) { this._buildRegDiv = function(event) {
var that = this; let that = this;
var container = this._plot.getPlaceholder(); let container = this._plot.getPlaceholder();
var o = this._plot.getPlotOffset(); let o = this._plot.getPlotOffset();
var axes = this._plot.getAxes(); let axes = this._plot.getAxes();
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];
var yaxis, top, left, lineWidth, regionWidth, lineStyle, color, markerTooltip; let yaxis, top, left, lineWidth, regionWidth, lineStyle, color, markerTooltip;
// determine the y axis used // determine the y axis used
if (axes.yaxis && axes.yaxis.used) { yaxis = axes.yaxis; } if (axes.yaxis && axes.yaxis.used) {
if (axes.yaxis2 && axes.yaxis2.used) { yaxis = axes.yaxis2; } yaxis = axes.yaxis;
}
if (axes.yaxis2 && axes.yaxis2.used) {
yaxis = axes.yaxis2;
}
// map the eventType to a types object // map the eventType to a types object
var eventTypeId = event.eventType; let eventTypeId = event.eventType;
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) { if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) {
color = '#666'; color = '#666';
...@@ -440,73 +493,77 @@ function ($, _, angular, Drop) { ...@@ -440,73 +493,77 @@ function ($, _, angular, Drop) {
lineStyle = this._types[eventTypeId].lineStyle.toLowerCase(); lineStyle = this._types[eventTypeId].lineStyle.toLowerCase();
} }
var topOffset = 2; let topOffset = 2;
top = o.top + this._plot.height() + topOffset; top = o.top + this._plot.height() + topOffset;
var timeFrom = Math.min(event.min, event.timeEnd); let timeFrom = Math.min(event.min, event.timeEnd);
var timeTo = Math.max(event.min, event.timeEnd); let timeTo = Math.max(event.min, event.timeEnd);
left = xaxis.p2c(timeFrom) + o.left; left = xaxis.p2c(timeFrom) + o.left;
var right = xaxis.p2c(timeTo) + o.left; let right = xaxis.p2c(timeTo) + o.left;
regionWidth = right - left; regionWidth = right - left;
_.each([left, right], function(position) { _.each([left, right], function(position) {
var line = $('<div class="events_line flot-temp-elem"></div>').css({ let line = $('<div class="events_line flot-temp-elem"></div>').css({
"position": "absolute", position: 'absolute',
"opacity": 0.8, opacity: 0.8,
"left": position + 'px', left: position + 'px',
"top": 8, top: 8,
"width": lineWidth + "px", width: lineWidth + 'px',
"height": that._plot.height() + topOffset, height: that._plot.height() + topOffset,
"border-left-width": lineWidth + "px", 'border-left-width': lineWidth + 'px',
"border-left-style": lineStyle, 'border-left-style': lineStyle,
"border-left-color": color, 'border-left-color': color,
"color": color color: color,
}); });
line.appendTo(container); line.appendTo(container);
}); });
var region = $('<div class="events_marker region_marker flot-temp-elem"></div>').css({ let region = $('<div class="events_marker region_marker flot-temp-elem"></div>').css({
"position": "absolute", position: 'absolute',
"opacity": 0.5, opacity: 0.5,
"left": left + 'px', left: left + 'px',
"top": top, top: top,
"width": Math.round(regionWidth + lineWidth) + "px", width: Math.round(regionWidth + lineWidth) + 'px',
"height": "0.5rem", height: '0.5rem',
"border-left-color": color, 'border-left-color': color,
"color": color, color: color,
"background-color": color 'background-color': color,
}); });
region.appendTo(container); region.appendTo(container);
region.data({ region.data({
"event": event event: event,
}); });
var mouseenter = function () { let mouseenter = function() {
createAnnotationToolip(region, $(this).data("event"), that._plot); createAnnotationToolip(region, $(this).data('event'), that._plot);
}; };
if (event.editModel) { if (event.editModel) {
createEditPopover(region, event.editModel, that._plot); createEditPopover(region, event.editModel, that._plot);
} }
var mouseleave = function () { let mouseleave = function() {
that._plot.clearSelection(); that._plot.clearSelection();
}; };
if (markerTooltip) { if (markerTooltip) {
region.css({ "cursor": "help" }); region.css({ cursor: 'help' });
region.hover(mouseenter, mouseleave); region.hover(mouseenter, mouseleave);
} }
var drawableEvent = new DrawableEvent( let drawableEvent = new DrawableEvent(
region, region,
function drawFunc(obj) { obj.show(); }, function drawFunc(obj) {
function (obj) { obj.remove(); }, obj.show();
function (obj, position) { },
function(obj) {
obj.remove();
},
function(obj, position) {
obj.css({ obj.css({
top: position.top, top: position.top,
left: position.left left: position.left,
}); });
}, },
left, left,
...@@ -522,19 +579,19 @@ function ($, _, angular, Drop) { ...@@ -522,19 +579,19 @@ function ($, _, angular, Drop) {
* check if the event is inside visible range * check if the event is inside visible range
*/ */
this._insidePlot = function(x) { this._insidePlot = function(x) {
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];
var xc = xaxis.p2c(x); let xc = xaxis.p2c(x);
return xc > 0 && xc < xaxis.p2c(xaxis.max); return xc > 0 && xc < xaxis.p2c(xaxis.max);
}; };
}; };
/** /**
* initialize the plugin for the given plot * initialize the plugin for the given plot
*/ */
function init(plot) { function init(plot) {
/*jshint validthis:true */ /*jshint validthis:true */
var that = this; let that = this;
var eventMarkers = new EventMarkers(plot); let eventMarkers = new EventMarkers(plot);
plot.getEvents = function() { plot.getEvents = function() {
return eventMarkers._events; return eventMarkers._events;
...@@ -542,7 +599,10 @@ function ($, _, angular, Drop) { ...@@ -542,7 +599,10 @@ function ($, _, angular, Drop) {
plot.hideEvents = function() { plot.hideEvents = function() {
$.each(eventMarkers._events, function(index, event) { $.each(eventMarkers._events, function(index, event) {
event.visual().getObject().hide(); event
.visual()
.getObject()
.hide();
}); });
}; };
...@@ -570,7 +630,7 @@ function ($, _, angular, Drop) { ...@@ -570,7 +630,7 @@ function ($, _, angular, Drop) {
}); });
plot.hooks.draw.push(function(plot) { plot.hooks.draw.push(function(plot) {
var options = plot.getOptions(); let options = plot.getOptions();
if (eventMarkers.eventsEnabled) { if (eventMarkers.eventsEnabled) {
// check for first run // check for first run
...@@ -584,21 +644,20 @@ function ($, _, angular, Drop) { ...@@ -584,21 +644,20 @@ function ($, _, angular, Drop) {
eventMarkers.drawEvents(); eventMarkers.drawEvents();
}); });
} }
var defaultOptions = { let defaultOptions = {
events: { events: {
data: null, data: null,
types: null, types: null,
xaxis: 1, xaxis: 1,
position: 'BOTTOM' position: 'BOTTOM',
} },
}; };
$.plot.plugins.push({ $.plot.plugins.push({
init: init, init: init,
options: defaultOptions, options: defaultOptions,
name: "events", name: 'events',
version: "0.2.5" version: '0.2.5',
});
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment