webglimpse
Version:
Webglimpse is a data visualization library for the web.
401 lines • 60.9 kB
JavaScript
/*
* Copyright (c) 2014, Metron, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import { OrderedSet } from '../util/ordered_set';
import { TimelineEventStyleUi } from './timeline_event_style';
import { TimelineAnnotationStyleUi } from './timeline_annotation_style';
import { SimpleModel, XyModel } from '../misc';
import { GL, hasval, getObjectId } from '../util/util';
import { Texture2D } from '../texture';
import { Notification, Notification1, Notification2 } from '../util/notification';
import { isLeftMouseDown } from '../core';
export class TimelineUi {
constructor(model, options = {}) {
this._dispose = new Notification();
this._input = new TimelineInput();
const getPaneId = function (pane) {
const paneId = pane['webglimpse_PaneId'];
return hasval(paneId) ? paneId : getObjectId(pane);
};
this._panes = new OrderedSet([], getPaneId);
this._selection = new TimelineSelectionModel();
attachTimelineInputToSelection(this._input, this._selection, options);
this._groupUis = new OrderedSet([], (g) => g.groupGuid);
const groupUis = this._groupUis;
const addGroupUi = function (group) { groupUis.add(new TimelineGroupUi(group.groupGuid)); };
const removeGroupUi = function (group) { groupUis.removeId(group.groupGuid); };
model.groups.forEach(addGroupUi);
model.groups.valueAdded.on(addGroupUi);
model.groups.valueRemoved.on(removeGroupUi);
this._rowUis = new OrderedSet([], (r) => r.rowGuid);
const rowUis = this._rowUis;
const addRowUi = function (row) { rowUis.add(new TimelineRowUi(row.rowGuid)); };
const removeRowUi = function (row) { rowUis.removeId(row.rowGuid); };
model.rows.forEach(addRowUi);
model.rows.valueAdded.on(addRowUi);
model.rows.valueRemoved.on(removeRowUi);
this._eventStyles = new OrderedSet([], (s) => s.styleGuid);
this._annotationStyles = new OrderedSet([], (s) => s.styleGuid);
this._millisPerPx = new SimpleModel(1000);
this._imageStatus = {};
this._imageCache = {};
this._dispose.on(function () {
model.groups.valueAdded.off(addGroupUi);
model.groups.valueRemoved.off(removeGroupUi);
model.rows.valueAdded.off(addRowUi);
model.rows.valueRemoved.off(removeRowUi);
});
}
get input() {
return this._input;
}
get selection() {
return this._selection;
}
get groupUis() {
return this._groupUis;
}
groupUi(groupGuid) {
return this._groupUis.valueFor(groupGuid);
}
get rowUis() {
return this._rowUis;
}
rowUi(rowGuid) {
return this._rowUis.valueFor(rowGuid);
}
get eventStyles() {
return this._eventStyles;
}
eventStyle(styleGuid) {
return ((hasval(styleGuid) && this._eventStyles.valueFor(styleGuid)) || timelineEventStyle_DEFAULT);
}
get annotationStyles() {
return this._annotationStyles;
}
annotationStyle(styleGuid) {
return ((hasval(styleGuid) && this._annotationStyles.valueFor(styleGuid)) || timelineAnnotationStyle_DEFAULT);
}
get millisPerPx() {
return this._millisPerPx;
}
loadImage(url, onLoaded) {
if (!hasval(this._imageStatus[url])) {
this._imageStatus[url] = true;
const imageCache = this._imageCache;
const image = new Image();
image.onload = function () {
const w = image.naturalWidth;
const h = image.naturalHeight;
imageCache[url] = new Texture2D(w, h, GL.LINEAR, GL.LINEAR, function (g) { g.drawImage(image, 0, 0); });
if (onLoaded) {
onLoaded();
}
};
image.src = url;
}
return this._imageCache[url];
}
get panes() {
return this._panes;
}
addPane(paneId, pane) {
pane['webglimpse_PaneId'] = paneId;
this._panes.removeId(paneId);
this._panes.add(pane);
}
removePane(paneId) {
this._panes.removeId(paneId);
}
getPane(paneId) {
return this._panes.valueFor(paneId);
}
get dispose() { return this._dispose; }
}
export class TimelineGroupUi {
constructor(groupGuid) {
this._groupGuid = groupGuid;
}
get groupGuid() {
return this._groupGuid;
}
}
export class TimelineRowUi {
constructor(rowGuid) {
this._rowGuid = rowGuid;
this._paneFactoryChanged = new Notification();
this._paneFactory = null;
const getPaneId = function (pane) {
const paneId = pane['webglimpse_PaneId'];
return hasval(paneId) ? paneId : getObjectId(pane);
};
this._panes = new OrderedSet([], getPaneId);
}
get rowGuid() {
return this._rowGuid;
}
get paneFactoryChanged() {
return this._paneFactoryChanged;
}
get paneFactory() {
return this._paneFactory;
}
set paneFactory(paneFactory) {
if (paneFactory !== this._paneFactory) {
this._paneFactory = paneFactory;
this._paneFactoryChanged.fire();
}
}
get panes() {
return this._panes;
}
addPane(paneId, pane) {
pane['webglimpse_PaneId'] = paneId;
this._panes.removeId(paneId);
this._panes.add(pane);
}
removePane(paneId) {
this._panes.removeId(paneId);
}
getPane(paneId) {
return this._panes.valueFor(paneId);
}
}
const timelineAnnotationStyle_DEFAULT = new TimelineAnnotationStyleUi({
styleGuid: 'DEFAULT',
color: 'white',
icons: []
});
const timelineEventStyle_DEFAULT = new TimelineEventStyleUi({
styleGuid: 'DEFAULT',
icons: []
});
export class TimelineInput {
constructor() {
this._mouseMove = new Notification1();
this._mouseExit = new Notification1();
this._timeHover = new Notification2();
this._rowHover = new Notification2();
this._eventHover = new Notification2();
this._mouseDown = new Notification1();
this._mouseUp = new Notification1();
this._contextMenu = new Notification1();
}
get mouseMove() { return this._mouseMove; }
get mouseExit() { return this._mouseExit; }
get timeHover() { return this._timeHover; }
get rowHover() { return this._rowHover; }
get eventHover() { return this._eventHover; }
get mouseDown() { return this._mouseDown; }
get mouseUp() { return this._mouseUp; }
get contextMenu() { return this._contextMenu; }
}
export class TimelineSelectionModel {
constructor() {
this._mousePos = new XyModel();
this._hoveredY = new SimpleModel();
this._hoveredTime_PMILLIS = new SimpleModel();
this._selectedInterval = new TimeIntervalModel(0, 0);
this._hoveredRow = new SimpleModel();
this._hoveredEvent = new SimpleModel();
this._selectedEvents = new OrderedSet([], (e) => e.eventGuid);
this._hoveredTimeseries = new TimelineTimeseriesFragmentSelectionModel();
this._hoveredAnnotation = new SimpleModel();
}
get mousePos() { return this._mousePos; }
get hoveredY() { return this._hoveredY; }
get hoveredTime_PMILLIS() { return this._hoveredTime_PMILLIS; }
get selectedInterval() { return this._selectedInterval; }
get hoveredRow() { return this._hoveredRow; }
get hoveredEvent() { return this._hoveredEvent; }
get selectedEvents() { return this._selectedEvents; }
get hoveredTimeseries() { return this._hoveredTimeseries; }
get hoveredAnnotation() { return this._hoveredAnnotation; }
}
export class TimelineTimeseriesFragmentSelectionModel {
constructor(fragment = null, index = -1) {
this._fragment = fragment;
this._index = index;
this._changed = new Notification();
}
setValue(fragment, index) {
if (fragment !== this._fragment || index !== this._index) {
this._fragment = fragment;
this._index = index;
this._changed.fire();
}
}
clearValue() {
this.setValue(null, -1);
}
get fragment() { return this._fragment; }
get index() { return this._index; }
get changed() { return this._changed; }
get times_PMILLIS() {
if (this._fragment) {
return this._fragment.times_PMILLIS[this._index];
}
else {
return undefined;
}
}
get data() {
if (this._fragment) {
return this._fragment.data[this._index];
}
else {
return undefined;
}
}
}
export class TimeIntervalModel {
constructor(start_PMILLIS, end_PMILLIS, cursor_PMILLIS) {
this._start_PMILLIS = start_PMILLIS;
this._end_PMILLIS = end_PMILLIS;
this._cursor_PMILLIS = cursor_PMILLIS ? cursor_PMILLIS : end_PMILLIS;
this._changed = new Notification();
}
get start_PMILLIS() { return this._start_PMILLIS; }
get end_PMILLIS() { return this._end_PMILLIS; }
get cursor_PMILLIS() { return this._cursor_PMILLIS; }
get duration_MILLIS() { return this._end_PMILLIS - this._start_PMILLIS; }
get changed() { return this._changed; }
set start_PMILLIS(start_PMILLIS) {
if (start_PMILLIS !== this._start_PMILLIS) {
this._start_PMILLIS = start_PMILLIS;
this._changed.fire();
}
}
set end_PMILLIS(end_PMILLIS) {
if (end_PMILLIS !== this._end_PMILLIS) {
this._end_PMILLIS = end_PMILLIS;
this._changed.fire();
}
}
set cursor_PMILLIS(cursor_PMILLIS) {
if (cursor_PMILLIS !== this._cursor_PMILLIS) {
this._cursor_PMILLIS = cursor_PMILLIS;
this._changed.fire();
}
}
setInterval(start_PMILLIS, end_PMILLIS, cursor_PMILLIS) {
if (start_PMILLIS !== this._start_PMILLIS ||
end_PMILLIS !== this._end_PMILLIS ||
(cursor_PMILLIS && cursor_PMILLIS !== this._cursor_PMILLIS)) {
this._start_PMILLIS = start_PMILLIS;
this._end_PMILLIS = end_PMILLIS;
this._cursor_PMILLIS = cursor_PMILLIS ? cursor_PMILLIS : end_PMILLIS;
this._changed.fire();
}
}
overlaps(start_PMILLIS, end_PMILLIS) {
return (this._start_PMILLIS <= end_PMILLIS && start_PMILLIS <= this._end_PMILLIS);
}
contains(time_PMILLIS) {
return (this._start_PMILLIS <= time_PMILLIS && time_PMILLIS <= this._end_PMILLIS);
}
pan(amount_MILLIS) {
if (amount_MILLIS !== 0) {
this._start_PMILLIS += amount_MILLIS;
this._end_PMILLIS += amount_MILLIS;
this._cursor_PMILLIS += amount_MILLIS;
this._changed.fire();
}
}
scale(factor, anchor_PMILLIS) {
if (anchor_PMILLIS !== 1) {
this._start_PMILLIS = anchor_PMILLIS + factor * (this._start_PMILLIS - anchor_PMILLIS);
this._end_PMILLIS = anchor_PMILLIS + factor * (this._end_PMILLIS - anchor_PMILLIS);
this._cursor_PMILLIS = anchor_PMILLIS + factor * (this._cursor_PMILLIS - anchor_PMILLIS);
this._changed.fire();
}
}
}
function attachTimelineInputToSelection(input, selection, options) {
const allowEventMultiSelection = (hasval(options) && hasval(options.allowEventMultiSelection) ? options.allowEventMultiSelection : true);
// Mouse-pos & Time
//
input.mouseMove.on(function (ev) {
selection.mousePos.setXy(ev.i, ev.j);
});
input.mouseExit.on(function (ev) {
selection.mousePos.setXy(null, null);
});
input.rowHover.on(function (row, ev) {
selection.hoveredRow.value = row;
});
input.timeHover.on(function (time_PMILLIS, ev) {
selection.hoveredTime_PMILLIS.value = time_PMILLIS;
});
// Events
//
input.eventHover.on(function (event) {
selection.hoveredEvent.value = event;
});
if (options.allowEventMultiSelection) {
input.mouseDown.on(function (ev) {
if (isLeftMouseDown(ev.mouseEvent)) {
const event = selection.hoveredEvent.value;
if (hasval(event)) {
const multiSelectMode = (ev.mouseEvent && (ev.mouseEvent.ctrlKey || ev.mouseEvent.shiftKey));
const unselectedEventClicked = !selection.selectedEvents.hasValue(event);
if (multiSelectMode) {
if (selection.selectedEvents.hasValue(event)) {
selection.selectedEvents.removeValue(event);
}
else {
selection.selectedEvents.add(event);
}
}
else if (unselectedEventClicked) {
selection.selectedEvents.retainValues([event]);
selection.selectedEvents.add(event);
}
else {
// if a selected event is clicked, do nothing (the user is probably initiating a drag)
// if they wish to deselect the event, they need to ctrl+click the event or click on
// a deselected event
}
}
}
});
}
else {
input.mouseDown.on(function (ev) {
if (isLeftMouseDown(ev.mouseEvent)) {
const event = selection.hoveredEvent.value;
if (hasval(event)) {
selection.selectedEvents.retainValues([event]);
selection.selectedEvents.add(event);
}
}
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmVfdWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd2ViZ2xpbXBzZS90aW1lbGluZS90aW1lbGluZV91aS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMvQyxPQUFPLEVBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDbEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRixPQUFPLEVBQXNCLGVBQWUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQVE5RCxNQUFNLE9BQU8sVUFBVTtJQWtCbkIsWUFBWSxLQUFvQixFQUFFLFVBQTZCLEVBQUU7UUFDN0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUVsQyxNQUFNLFNBQVMsR0FBRyxVQUFVLElBQVU7WUFDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDekMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FB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KSAyMDE0LCBNZXRyb24sIEluYy5cclxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuICpcclxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbixcclxuICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxyXG4gKlxyXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcclxuICogICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXHJcbiAqXHJcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcclxuICogICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxyXG4gKiAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cclxuICpcclxuICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcclxuICogICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcclxuICogICAgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxyXG4gKlxyXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkRcclxuICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcclxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxyXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUlxyXG4gKiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcclxuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xyXG4gKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT05cclxuICogQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcclxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVNcclxuICogU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXHJcbiAqL1xyXG5pbXBvcnQgeyBPcmRlcmVkU2V0IH0gZnJvbSAnLi4vdXRpbC9vcmRlcmVkX3NldCc7XHJcbmltcG9ydCB7IFRpbWVsaW5lRXZlbnRTdHlsZVVpIH0gZnJvbSAnLi90aW1lbGluZV9ldmVudF9zdHlsZSc7XHJcbmltcG9ydCB7IFRpbWVsaW5lQW5ub3RhdGlvblN0eWxlVWkgfSBmcm9tICcuL3RpbWVsaW5lX2Fubm90YXRpb25fc3R5bGUnO1xyXG5pbXBvcnQgeyBTaW1wbGVNb2RlbCwgWHlNb2RlbCB9IGZyb20gJy4uL21pc2MnO1xyXG5pbXBvcnQgeyBTdHJpbmdNYXAsIEdMLCBoYXN2YWwsIGdldE9iamVjdElkIH0gZnJvbSAnLi4vdXRpbC91dGlsJztcclxuaW1wb3J0IHsgVGV4dHVyZTJEIH0gZnJvbSAnLi4vdGV4dHVyZSc7XHJcbmltcG9ydCB7IE5vdGlmaWNhdGlvbiwgTm90aWZpY2F0aW9uMSwgTm90aWZpY2F0aW9uMiB9IGZyb20gJy4uL3V0aWwvbm90aWZpY2F0aW9uJztcclxuaW1wb3J0IHsgUGFuZSwgUG9pbnRlckV2ZW50LCBpc0xlZnRNb3VzZURvd24gfSBmcm9tICcuLi9jb3JlJztcclxuaW1wb3J0IHsgVGltZWxpbmVNb2RlbCwgVGltZWxpbmVHcm91cE1vZGVsLCBUaW1lbGluZVJvd01vZGVsLCBUaW1lbGluZUV2ZW50TW9kZWwsIFRpbWVsaW5lQW5ub3RhdGlvbk1vZGVsLCBUaW1lbGluZVRpbWVzZXJpZXNGcmFnbWVudE1vZGVsIH0gZnJvbSAnLi90aW1lbGluZV9tb2RlbCc7XHJcbmltcG9ydCB7IFRpbWVsaW5lUm93UGFuZUZhY3RvcnkgfSBmcm9tICcuL3RpbWVsaW5lX3Jvdyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFRpbWVsaW5lVWlPcHRpb25zIHtcclxuICAgIGFsbG93RXZlbnRNdWx0aVNlbGVjdGlvbj86IGJvb2xlYW47XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBUaW1lbGluZVVpIHtcclxuICAgIHByaXZhdGUgX2lucHV0OiBUaW1lbGluZUlucHV0O1xyXG4gICAgcHJpdmF0ZSBfc2VsZWN0aW9uOiBUaW1lbGluZVNlbGVjdGlvbk1vZGVsO1xyXG5cclxuICAgIHByaXZhdGUgX2dyb3VwVWlzOiBPcmRlcmVkU2V0PFRpbWVsaW5lR3JvdXBVaT47XHJcbiAgICBwcml2YXRlIF9yb3dVaXM6IE9yZGVyZWRTZXQ8VGltZWxpbmVSb3dVaT47XHJcbiAgICBwcml2YXRlIF9ldmVudFN0eWxlczogT3JkZXJlZFNldDxUaW1lbGluZUV2ZW50U3R5bGVVaT47XHJcbiAgICBwcml2YXRlIF9hbm5vdGF0aW9uU3R5bGVzOiBPcmRlcmVkU2V0PFRpbWVsaW5lQW5ub3RhdGlvblN0eWxlVWk+O1xyXG5cclxuICAgIHByaXZhdGUgX21pbGxpc1BlclB4OiBTaW1wbGVNb2RlbDxudW1iZXI+O1xyXG5cclxuICAgIHByaXZhdGUgX2ltYWdlU3RhdHVzOiBTdHJpbmdNYXA8Ym9vbGVhbj47XHJcbiAgICBwcml2YXRlIF9pbWFnZUNhY2hlOiBTdHJpbmdNYXA8VGV4dHVyZTJEPjtcclxuXHJcbiAgICBwcml2YXRlIF9kaXNwb3NlOiBOb3RpZmljYXRpb247XHJcblxyXG4gICAgcHJpdmF0ZSBfcGFuZXM6IE9yZGVyZWRTZXQ8UGFuZT47XHJcblxyXG4gICAgY29uc3RydWN0b3IobW9kZWw6IFRpbWVsaW5lTW9kZWwsIG9wdGlvbnM6IFRpbWVsaW5lVWlPcHRpb25zID0ge30pIHtcclxuICAgICAgICB0aGlzLl9kaXNwb3NlID0gbmV3IE5vdGlmaWNhdGlvbigpO1xyXG4gICAgICAgIHRoaXMuX2lucHV0ID0gbmV3IFRpbWVsaW5lSW5wdXQoKTtcclxuXHJcbiAgICAgICAgY29uc3QgZ2V0UGFuZUlkID0gZnVuY3Rpb24gKHBhbmU6IFBhbmUpOiBzdHJpbmcge1xyXG4gICAgICAgICAgICBjb25zdCBwYW5lSWQgPSBwYW5lWyd3ZWJnbGltcHNlX1BhbmVJZCddO1xyXG4gICAgICAgICAgICByZXR1cm4gaGFzdmFsKHBhbmVJZCkgPyBwYW5lSWQgOiBnZXRPYmplY3RJZChwYW5lKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB0aGlzLl9wYW5lcyA9IG5ldyBPcmRlcmVkU2V0PFBhbmU+KFtdLCBnZXRQYW5lSWQpO1xyXG5cclxuICAgICAgICB0aGlzLl9zZWxlY3Rpb24gPSBuZXcgVGltZWxpbmVTZWxlY3Rpb25Nb2RlbCgpO1xyXG4gICAgICAgIGF0dGFjaFRpbWVsaW5lSW5wdXRUb1NlbGVjdGlvbih0aGlzLl9pbnB1dCwgdGhpcy5fc2VsZWN0aW9uLCBvcHRpb25zKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZ3JvdXBVaXMgPSBuZXcgT3JkZXJlZFNldDxUaW1lbGluZUdyb3VwVWk+KFtdLCAoZykgPT4gZy5ncm91cEd1aWQpO1xyXG4gICAgICAgIGNvbnN0IGdyb3VwVWlzID0gdGhpcy5fZ3JvdXBVaXM7XHJcbiAgICAgICAgY29uc3QgYWRkR3JvdXBVaSA9IGZ1bmN0aW9uIChncm91cDogVGltZWxpbmVHcm91cE1vZGVsKSB7IGdyb3VwVWlzLmFkZChuZXcgVGltZWxpbmVHcm91cFVpKGdyb3VwLmdyb3VwR3VpZCkpOyB9O1xyXG4gICAgICAgIGNvbnN0IHJlbW92ZUdyb3VwVWkgPSBmdW5jdGlvbiAoZ3JvdXA6IFRpbWVsaW5lR3JvdXBNb2RlbCkgeyBncm91cFVpcy5yZW1vdmVJZChncm91cC5ncm91cEd1aWQpOyB9O1xyXG4gICAgICAgIG1vZGVsLmdyb3Vwcy5mb3JFYWNoKGFkZEdyb3VwVWkpO1xyXG4gICAgICAgIG1vZGVsLmdyb3Vwcy52YWx1ZUFkZGVkLm9uKGFkZEdyb3VwVWkpO1xyXG4gICAgICAgIG1vZGVsLmdyb3Vwcy52YWx1ZVJlbW92ZWQub24ocmVtb3ZlR3JvdXBVaSk7XHJcblxyXG4gICAgICAgIHRoaXMuX3Jvd1VpcyA9IG5ldyBPcmRlcmVkU2V0PFRpbWVsaW5lUm93VWk+KFtdLCAocikgPT4gci5yb3dHdWlkKTtcclxuICAgICAgICBjb25zdCByb3dVaXMgPSB0aGlzLl9yb3dVaXM7XHJcbiAgICAgICAgY29uc3QgYWRkUm93VWkgPSBmdW5jdGlvbiAocm93OiBUaW1lbGluZVJvd01vZGVsKSB7IHJvd1Vpcy5hZGQobmV3IFRpbWVsaW5lUm93VWkocm93LnJvd0d1aWQpKTsgfTtcclxuICAgICAgICBjb25zdCByZW1vdmVSb3dVaSA9IGZ1bmN0aW9uIChyb3c6IFRpbWVsaW5lUm93TW9kZWwpIHsgcm93VWlzLnJlbW92ZUlkKHJvdy5yb3dHdWlkKTsgfTtcclxuICAgICAgICBtb2RlbC5yb3dzLmZvckVhY2goYWRkUm93VWkpO1xyXG4gICAgICAgIG1vZGVsLnJvd3MudmFsdWVBZGRlZC5vbihhZGRSb3dVaSk7XHJcbiAgICAgICAgbW9kZWwucm93cy52YWx1ZVJlbW92ZWQub24ocmVtb3ZlUm93VWkpO1xyXG5cclxuICAgICAgICB0aGlzLl9ldmVudFN0eWxlcyA9IG5ldyBPcmRlcmVkU2V0PFRpbWVsaW5lRXZlbnRTdHlsZVVpPihbXSwgKHMpID0+IHMuc3R5bGVHdWlkKTtcclxuICAgICAgICB0aGlzLl9hbm5vdGF0aW9uU3R5bGVzID0gbmV3IE9yZGVyZWRTZXQ8VGltZWxpbmVBbm5vdGF0aW9uU3R5bGVVaT4oW10sIChzKSA9PiBzLnN0eWxlR3VpZCk7XHJcblxyXG4gICAgICAgIHRoaXMuX21pbGxpc1BlclB4ID0gbmV3IFNpbXBsZU1vZGVsPG51bWJlcj4oMTAwMCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2ltYWdlU3RhdHVzID0ge307XHJcbiAgICAgICAgdGhpcy5faW1hZ2VDYWNoZSA9IHt9O1xyXG5cclxuICAgICAgICB0aGlzLl9kaXNwb3NlLm9uKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgbW9kZWwuZ3JvdXBzLnZhbHVlQWRkZWQub2ZmKGFkZEdyb3VwVWkpO1xyXG4gICAgICAgICAgICBtb2RlbC5ncm91cHMudmFsdWVSZW1vdmVkLm9mZihyZW1vdmVHcm91cFVpKTtcclxuICAgICAgICAgICAgbW9kZWwucm93cy52YWx1ZUFkZGVkLm9mZihhZGRSb3dVaSk7XHJcbiAgICAgICAgICAgIG1vZGVsLnJvd3MudmFsdWVSZW1vdmVkLm9mZihyZW1vdmVSb3dVaSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGlucHV0KCk6IFRpbWVsaW5lSW5wdXQge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pbnB1dDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2VsZWN0aW9uKCk6IFRpbWVsaW5lU2VsZWN0aW9uTW9kZWwge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zZWxlY3Rpb247XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGdyb3VwVWlzKCk6IE9yZGVyZWRTZXQ8VGltZWxpbmVHcm91cFVpPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dyb3VwVWlzO1xyXG4gICAgfVxyXG5cclxuICAgIGdyb3VwVWkoZ3JvdXBHdWlkOiBzdHJpbmcpOiBUaW1lbGluZUdyb3VwVWkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ncm91cFVpcy52YWx1ZUZvcihncm91cEd1aWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCByb3dVaXMoKTogT3JkZXJlZFNldDxUaW1lbGluZVJvd1VpPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvd1VpcztcclxuICAgIH1cclxuXHJcbiAgICByb3dVaShyb3dHdWlkOiBzdHJpbmcpOiBUaW1lbGluZVJvd1VpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcm93VWlzLnZhbHVlRm9yKHJvd0d1aWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBldmVudFN0eWxlcygpOiBPcmRlcmVkU2V0PFRpbWVsaW5lRXZlbnRTdHlsZVVpPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50U3R5bGVzO1xyXG4gICAgfVxyXG5cclxuICAgIGV2ZW50U3R5bGUoc3R5bGVHdWlkOiBzdHJpbmcpOiBUaW1lbGluZUV2ZW50U3R5bGVVaSB7XHJcbiAgICAgICAgcmV0dXJuICgoaGFzdmFsKHN0eWxlR3VpZCkgJiYgdGhpcy5fZXZlbnRTdHlsZXMudmFsdWVGb3Ioc3R5bGVHdWlkKSkgfHwgdGltZWxpbmVFdmVudFN0eWxlX0RFRkFVTFQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBhbm5vdGF0aW9uU3R5bGVzKCk6IE9yZGVyZWRTZXQ8VGltZWxpbmVBbm5vdGF0aW9uU3R5bGVVaT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hbm5vdGF0aW9uU3R5bGVzO1xyXG4gICAgfVxyXG5cclxuICAgIGFubm90YXRpb25TdHlsZShzdHlsZUd1aWQ6IHN0cmluZyk6IFRpbWVsaW5lQW5ub3RhdGlvblN0eWxlVWkge1xyXG4gICAgICAgIHJldHVybiAoKGhhc3ZhbChzdHlsZUd1aWQpICYmIHRoaXMuX2Fubm90YXRpb25TdHlsZXMudmFsdWVGb3Ioc3R5bGVHdWlkKSkgfHwgdGltZWxpbmVBbm5vdGF0aW9uU3R5bGVfREVGQVVMVCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1pbGxpc1BlclB4KCk6IFNpbXBsZU1vZGVsPG51bWJlcj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9taWxsaXNQZXJQeDtcclxuICAgIH1cclxuXHJcbiAgICBsb2FkSW1hZ2UodXJsOiBzdHJpbmcsIG9uTG9hZGVkOiAoKSA9PiB2b2lkKTogVGV4dHVyZTJEIHtcclxuICAgICAgICBpZiAoIWhhc3ZhbCh0aGlzLl9pbWFnZVN0YXR1c1t1cmxdKSkge1xyXG4gICAgICAgICAgICB0aGlzLl9pbWFnZVN0YXR1c1t1cmxdID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlQ2FjaGUgPSB0aGlzLl9pbWFnZUNhY2hlO1xyXG4gICAgICAgICAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xyXG4gICAgICAgICAgICBpbWFnZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3ID0gaW1hZ2UubmF0dXJhbFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaCA9IGltYWdlLm5hdHVyYWxIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICBpbWFnZUNhY2hlW3VybF0gPSBuZXcgVGV4dHVyZTJEKHcsIGgsIEdMLkxJTkVBUiwgR0wuTElORUFSLCBmdW5jdGlvbiAoZykgeyBnLmRyYXdJbWFnZShpbWFnZSwgMCwgMCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKG9uTG9hZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb25Mb2FkZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgaW1hZ2Uuc3JjID0gdXJsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5faW1hZ2VDYWNoZVt1cmxdO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwYW5lcygpOiBPcmRlcmVkU2V0PFBhbmU+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZXM7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkUGFuZShwYW5lSWQ6IHN0cmluZywgcGFuZTogUGFuZSkge1xyXG4gICAgICAgIHBhbmVbJ3dlYmdsaW1wc2VfUGFuZUlkJ10gPSBwYW5lSWQ7XHJcbiAgICAgICAgdGhpcy5fcGFuZXMucmVtb3ZlSWQocGFuZUlkKTtcclxuICAgICAgICB0aGlzLl9wYW5lcy5hZGQocGFuZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlUGFuZShwYW5lSWQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuX3BhbmVzLnJlbW92ZUlkKHBhbmVJZCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0UGFuZShwYW5lSWQ6IHN0cmluZyk6IFBhbmUge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5lcy52YWx1ZUZvcihwYW5lSWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBkaXNwb3NlKCkgeyByZXR1cm4gdGhpcy5fZGlzcG9zZTsgfVxyXG59XHJcblxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBUaW1lbGluZUdyb3VwVWkge1xyXG4gICAgcHJpdmF0ZSBfZ3JvdXBHdWlkOiBzdHJpbmc7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZ3JvdXBHdWlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9ncm91cEd1aWQgPSBncm91cEd1aWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGdyb3VwR3VpZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ncm91cEd1aWQ7XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFRpbWVsaW5lUm93VWkge1xyXG4gICAgcHJpdmF0ZSBfcm93R3VpZDogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSBfcGFuZUZhY3RvcnlDaGFuZ2VkOiBOb3RpZmljYXRpb247XHJcbiAgICBwcml2YXRlIF9wYW5lRmFjdG9yeTogVGltZWxpbmVSb3dQYW5lRmFjdG9yeTtcclxuICAgIHByaXZhdGUgX3BhbmVzOiBPcmRlcmVkU2V0PFBhbmU+O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHJvd0d1aWQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuX3Jvd0d1aWQgPSByb3dHdWlkO1xyXG4gICAgICAgIHRoaXMuX3BhbmVGYWN0b3J5Q2hhbmdlZCA9IG5ldyBOb3RpZmljYXRpb24oKTtcclxuICAgICAgICB0aGlzLl9wYW5lRmFjdG9yeSA9IG51bGw7XHJcblxyXG4gICAgICAgIGNvbnN0IGdldFBhbmVJZCA9IGZ1bmN0aW9uIChwYW5lOiBQYW5lKTogc3RyaW5nIHtcclxuICAgICAgICAgICAgY29uc3QgcGFuZUlkID0gcGFuZVsnd2ViZ2xpbXBzZV9QYW5lSWQnXTtcclxuICAgICAgICAgICAgcmV0dXJuIGhhc3ZhbChwYW5lSWQpID8gcGFuZUlkIDogZ2V0T2JqZWN0SWQocGFuZSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdGhpcy5fcGFuZXMgPSBuZXcgT3JkZXJlZFNldDxQYW5lPihbXSwgZ2V0UGFuZUlkKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgcm93R3VpZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yb3dHdWlkO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwYW5lRmFjdG9yeUNoYW5nZWQoKTogTm90aWZpY2F0aW9uIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZUZhY3RvcnlDaGFuZ2VkO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwYW5lRmFjdG9yeSgpOiBUaW1lbGluZVJvd1BhbmVGYWN0b3J5IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZUZhY3Rvcnk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHBhbmVGYWN0b3J5KHBhbmVGYWN0b3J5OiBUaW1lbGluZVJvd1BhbmVGYWN0b3J5KSB7XHJcbiAgICAgICAgaWYgKHBhbmVGYWN0b3J5ICE9PSB0aGlzLl9wYW5lRmFjdG9yeSkge1xyXG4gICAgICAgICAgICB0aGlzLl9wYW5lRmFjdG9yeSA9IHBhbmVGYWN0b3J5O1xyXG4gICAgICAgICAgICB0aGlzLl9wYW5lRmFjdG9yeUNoYW5nZWQuZmlyZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgcGFuZXMoKTogT3JkZXJlZFNldDxQYW5lPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhbmVzO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZFBhbmUocGFuZUlkOiBzdHJpbmcsIHBhbmU6IFBhbmUpIHtcclxuICAgICAgICBwYW5lWyd3ZWJnbGltcHNlX1BhbmVJZCddID0gcGFuZUlkO1xyXG4gICAgICAgIHRoaXMuX3BhbmVzLnJlbW92ZUlkKHBhbmVJZCk7XHJcbiAgICAgICAgdGhpcy5fcGFuZXMuYWRkKHBhbmUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVBhbmUocGFuZUlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9wYW5lcy5yZW1vdmVJZChwYW5lSWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFBhbmUocGFuZUlkOiBzdHJpbmcpOiBQYW5lIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZXMudmFsdWVGb3IocGFuZUlkKTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmNvbnN0IHRpbWVsaW5lQW5ub3RhdGlvblN0eWxlX0RFRkFVTFQgPSBuZXcgVGltZWxpbmVBbm5vdGF0aW9uU3R5bGVVaSh7XHJcbiAgICBzdHlsZUd1aWQ6ICdERUZBVUxUJyxcclxuICAgIGNvbG9yOiAnd2hpdGUnLFxyXG4gICAgaWNvbnM6IFtdXHJcbn0pO1xyXG5cclxuXHJcbmNvbnN0IHRpbWVsaW5lRXZlbnRTdHlsZV9ERUZBVUxUID0gbmV3IFRpbWVsaW5lRXZlbnRTdHlsZVVpKHtcclxuICAgIHN0eWxlR3VpZDogJ0RFRkFVTFQnLFxyXG4gICAgaWNvbnM6IFtdXHJcbn0pO1xyXG5cclxuXHJcblxyXG5leHBvcnQgY2xhc3MgVGltZWxpbmVJbnB1dCB7XHJcbiAgICBwcml2YXRlIF9tb3VzZU1vdmUgPSBuZXcgTm90aWZpY2F0aW9uMTxQb2ludGVyRXZlbnQ+KCk7XHJcbiAgICBwcml2YXRlIF9tb3VzZUV4aXQgPSBuZXcgTm90aWZpY2F0aW9uMTxQb2ludGVyRXZlbnQ+KCk7XHJcbiAgICBwcml2YXRlIF90aW1lSG92ZXIgPSBuZXcgTm90aWZpY2F0aW9uMjxudW1iZXIsIFBvaW50ZXJFdmVudD4oKTtcclxuICAgIHByaXZhdGUgX3Jvd0hvdmVyID0gbmV3IE5vdGlmaWNhdGlvbjI8VGltZWxpbmVSb3dNb2RlbCwgUG9pbnRlckV2ZW50PigpO1xyXG4gICAgcHJpdmF0ZSBfZXZlbnRIb3ZlciA9IG5ldyBOb3RpZmljYXRpb24yPFRpbWVsaW5lRXZlbnRNb2RlbCwgUG9pbnRlckV2ZW50PigpO1xyXG4gICAgcHJpdmF0ZSBfbW91c2VEb3duID0gbmV3IE5vdGlmaWNhdGlvbjE8UG9pbnRlckV2ZW50PigpO1xyXG4gICAgcHJpdmF0ZSBfbW91c2VVcCA9IG5ldyBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4oKTtcclxuICAgIHByaXZhdGUgX2NvbnRleHRNZW51ID0gbmV3IE5vdGlmaWNhdGlvbjE8UG9pbnRlckV2ZW50PigpO1xyXG5cclxuICAgIGdldCBtb3VzZU1vdmUoKTogTm90aWZpY2F0aW9uMTxQb2ludGVyRXZlbnQ+IHsgcmV0dXJuIHRoaXMuX21vdXNlTW92ZTsgfVxyXG4gICAgZ2V0IG1vdXNlRXhpdCgpOiBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fbW91c2VFeGl0OyB9XHJcbiAgICBnZXQgdGltZUhvdmVyKCk6IE5vdGlmaWNhdGlvbjI8bnVtYmVyLCBQb2ludGVyRXZlbnQ+IHsgcmV0dXJuIHRoaXMuX3RpbWVIb3ZlcjsgfVxyXG4gICAgZ2V0IHJvd0hvdmVyKCk6IE5vdGlmaWNhdGlvbjI8VGltZWxpbmVSb3dNb2RlbCwgUG9pbnRlckV2ZW50PiB7IHJldHVybiB0aGlzLl9yb3dIb3ZlcjsgfVxyXG4gICAgZ2V0IGV2ZW50SG92ZXIoKTogTm90aWZpY2F0aW9uMjxUaW1lbGluZUV2ZW50TW9kZWwsIFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fZXZlbnRIb3ZlcjsgfVxyXG4gICAgZ2V0IG1vdXNlRG93bigpOiBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fbW91c2VEb3duOyB9XHJcbiAgICBnZXQgbW91c2VVcCgpOiBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fbW91c2VVcDsgfVxyXG4gICAgZ2V0IGNvbnRleHRNZW51KCk6IE5vdGlmaWNhdGlvbjE8UG9pbnRlckV2ZW50PiB7IHJldHVybiB0aGlzLl9jb250ZXh0TWVudTsgfVxyXG59XHJcblxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBUaW1lbGluZVNlbGVjdGlvbk1vZGVsIHtcclxuICAgIHByaXZhdGUgX21vdXNlUG9zID0gbmV3IFh5TW9kZWwoKTtcclxuXHJcbiAgICBwcml2YXRlIF9ob3ZlcmVkWSA9IG5ldyBTaW1wbGVNb2RlbDxudW1iZXI+KCk7XHJcbiAgICBwcml2YXRlIF9ob3ZlcmVkVGltZV9QTUlMTElTID0gbmV3IFNpbXBsZU1vZGVsPG51bWJlcj4oKTtcclxuICAgIHByaXZhdGUgX3NlbGVjdGVkSW50ZXJ2YWwgPSBuZXcgVGltZUludGVydmFsTW9kZWwoMCwgMCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfaG92ZXJlZFJvdyA9IG5ldyBTaW1wbGVNb2RlbDxUaW1lbGluZVJvd01vZGVsPigpO1xyXG5cclxuICAgIHByaXZhdGUgX2hvdmVyZWRFdmVudCA9IG5ldyBTaW1wbGVNb2RlbDxUaW1lbGluZUV2ZW50TW9kZWw+KCk7XHJcbiAgICBwcml2YXRlIF9zZWxlY3RlZEV2ZW50cyA9IG5ldyBPcmRlcmVkU2V0PFRpbWVsaW5lRXZlbnRNb2RlbD4oW10sIChlKSA9PiBlLmV2ZW50R3VpZCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfaG92ZXJlZFRpbWVzZXJpZXMgPSBuZXcgVGltZWxpbmVUaW1lc2VyaWVzRnJhZ21lbnRTZWxlY3Rpb25Nb2RlbCgpO1xyXG5cclxuICAgIHByaXZhdGUgX2hvdmVyZWRBbm5vdGF0aW9uID0gbmV3IFNpbXBsZU1vZGVsPFRpbWVsaW5lQW5ub3RhdGlvbk1vZGVsPigpO1xyXG5cclxuICAgIGdldCBtb3VzZVBvcygpOiBYeU1vZGVsIHsgcmV0dXJuIHRoaXMuX21vdXNlUG9zOyB9XHJcblxyXG4gICAgZ2V0IGhvdmVyZWRZKCk6IFNpbXBsZU1vZGVsPG51