UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

352 lines • 34.2 kB
import { matches, snakeCase } from 'lodash-es'; /** * Base navigator node. Represents a single entry in the navigator menu. * Is considered to be the basic building block of the navigator. */ export class NavigatorNode { static { this.NAME = 'NavigatorNode'; } /** * Returns information whether a navigator node has children. * @readonly */ get hasChildren() { return this.children.length > 0; } /** * Returns the ID of the navigator node. * @readonly */ get id() { return 'navigator_node_' + snakeCase(this.label); } /** * Returns the priority value of the navigator node. * @readonly */ get priority() { if (this._priority) { return this._priority; } else { const childrenPriorities = this.children.map(({ priority }) => priority || 0); if (childrenPriorities.length) { return childrenPriorities.length ? Math.max(...childrenPriorities) : 0; } return 0; } } /** * Sets the priority value of the navigator node. * * @param {number} priority Priority value. */ set priority(priority) { this._priority = priority; } constructor(data) { /** * Navigator node children (subentries). */ this.children = []; /** * Whether to pass `label` through `translate` pipe when being displayed. */ this.translateLabel = true; /** * Navigator node parent nodes. */ this.parents = []; /** * Indicates whether the navigator node should be active based on matching the node path and the URL path. * To match the URL exactly, set this option to true. * * routerLinkExact set to true: * When the URL path is set to /a/b/c and the node path to /a/b then the node will not be set active. * * routerLinkExact set to false: * When the URL path is set to /a/b/c and the node path to /a/b then the node will be set active. */ this.routerLinkExact = true; /** * Indicates that the navigator node is expanded/collapsed. */ this.open = false; /** * Indicates that the navigator node is visible/hidden. */ this.hidden = false; /** * Indicates that the navigator node is draggable. */ this.draggable = false; /** * Indicates that the navigator node is droppable. */ this.droppable = false; /** * Indicates that the navigator node is dragged. */ this.dragged = false; /** * Indicates that currently something is dragged over the node. */ this.draggedHover = false; /** * Confirmation popover displayed at the end of the process of moving the navigator menu item. */ this.confirm = undefined; this._priority = 0; this.update(data); } /** * Adds a child navigator node to the node. * * @param {NavigatorNode} node Child node. */ add(node) { if (node === this) { throw new Error('Adding node to itself'); } if (this.children.indexOf(node) === -1) { this.children.push(node); } if (node.parents.indexOf(this) === -1) { node.parents.push(this); } this.updateChildren(); } /** * Removes the child navigator node from the node. * * @param {NavigatorNode} node Child node. */ remove(node) { const ix = this.children.indexOf(node); const pix = node.parents.indexOf(this); if (ix > -1) { this.children.splice(ix, 1); } if (pix > -1) { node.parents.splice(pix, 1); } this.updateChildren(); } /** * Updates the navigator node. * * @param {NavigatorNodeData} data Data to be updated. */ update(data) { if (data) { Object.assign(this, data); if (data.hidden !== undefined) { this.parents.forEach(p => { p.updateHidden(); }); } } } /** * * Returns a child navigator node based on the predicate. * * ```ts * // The function will compare the labels to the string and return a matching result. * // The capitalization of the characters does not matter (case insensitive). * const predicate = 'group1'; * const childNode = parentNode.find(predicate); * // Check: [lodash matches](https://lodash.com/docs/4.17.15#matches) * const predicate = { label: 'group2' }; * const childNode = parentNode.find(predicate); * ``` * * @param predicate Filter criteria. * @param findBy NavigatorNode field name to compare. * */ find(predicate, findBy = 'label') { if (typeof predicate === 'string') { if (findBy === 'label') { const compareLabel = predicate.toLocaleLowerCase(); predicate = ({ label }) => compareLabel === label?.toLowerCase(); } else { const compareId = predicate; predicate = ({ featureId }) => compareId === featureId; } } if (typeof predicate === 'object') { predicate = matches(predicate); } if (typeof predicate !== 'function') { throw new Error('Invalid search predicate'); } return this.children.reduce((found, child) => found || child.find(predicate), this.children.find(predicate)); } /** * Removes children nodes. */ empty() { this.children.length = 0; } /** * @ignore */ click(_options = {}) { // do nothing } /** * This event is fired when an element is dropped on a valid drop target. * @param $event DOM event. */ drop($event) { $event.stopPropagation(); clearTimeout(this.expandDragTimeout); } /** * This event is fired when the user starts dragging an element. * @param $event DOM event. */ dragStart($event) { $event.stopPropagation(); // we can't pass a object to setData, so we do it via service // set data is still needed, to make the drag&drop work $event.dataTransfer?.setData('node', 'node'); this.dragged = true; } /** * This event is fired when a drag operation has ended. * @param $event DOM event. */ dragEnd($event) { $event.stopPropagation(); this.dragged = false; } /** * Returns information whether the navigator node is droppable. * @readonly */ get canDrop() { return this.droppable; } /** * Returns information whether navigation is possible. * @readonly */ get canNavigate() { return typeof this.path !== 'undefined'; } /** * This event is fired when a dragged element enters a valid drop target. * @param $event DOM event. */ dragEnter($event) { $event.preventDefault(); $event.stopPropagation(); this.draggedHover = true; if (!this.open) { this.expandDragTimeout = setTimeout(() => this.expand(), 1000); } } /** * This event is fired when a dragged element leaves a valid drop target. * @param $event DOM event. */ dragLeave($event) { $event.preventDefault(); $event.stopPropagation(); if ($event.currentTarget.contains($event.relatedTarget)) { return; } this.draggedHover = false; clearTimeout(this.expandDragTimeout); } /** * Expands the navigator node if it is collapsed. */ expand() { if (!this.open) { this.open = true; this.click({ open: true, expander: true }); } } /** * Performs a callback function recursively on each of the navigator node's children down the hierarchy. * * ```ts * const expandChild = (childNode) => childNode.expand(); * parentNode.traverse(expandChild); * ``` * * @param callback Function to be called. */ traverse(callback) { if (this.children) { this.children.forEach(child => { callback(child); child.traverse(callback); }); } } /** * @ignore */ destroy() { // nothing todo here } /** * Counts the amount of children nodes. */ countChildren() { return this.children.length; } /** * Identifies itself. */ toString() { return NavigatorNode.NAME; } hasChildDevices() { return false; } /** * Updates the navigator node by sorting its children and also checking their visibility. */ updateChildren() { this.sort(); this.updateHidden(); } /** * Sorts the children of the navigator node, by priority and name (ASC). * The higher the priority, the higher the position in the hierarchy. * For the same priority values, the alphabetical order will take precedence. */ sort() { this.children.sort((a, b) => { if (a.priority > b.priority) { return -1; } else if (a.priority < b.priority) { return 1; } else if ((a.label || '').toLowerCase() < (b.label || '').toLowerCase()) { return -1; } else if ((a.label || '').toLowerCase() > (b.label || '').toLowerCase()) { return 1; } else { return 0; } }); } /** * Checks if the navigator node should be hidden based on the visibility of its child nodes. */ updateHidden() { if (typeof this.path === 'undefined') { this.hidden = !this.children.some(({ hidden }) => !hidden); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2aWdhdG9yLW5vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9jb3JlL25hdmlnYXRvci9uYXZpZ2F0b3Itbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQStCL0M7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7YUFDakIsU0FBSSxHQUFHLGVBQWUsQUFBbEIsQ0FBbUI7SUEwSDlCOzs7T0FHRztJQUNILElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJLEVBQUU7UUFDSixPQUFPLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQUksUUFBUTtRQUNWLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUN4QixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDOUUsSUFBSSxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekUsQ0FBQztZQUNELE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBSSxRQUFRLENBQUMsUUFBUTtR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InNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdG9yLCBUZW1wbGF0ZVJlZiwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgbWF0Y2hlcywgc25ha2VDYXNlIH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7IE5hdmlnYXRvck5vZGVEYXRhIH0gZnJvbSAnLi9uYXZpZ2F0b3Itbm9kZS1kYXRhJztcbmltcG9ydCB7IFBvcG92ZXJDb25maXJtQ29tcG9uZW50IH0gZnJvbSAnLi4vbW9kYWwvcG9wb3Zlci1jb25maXJtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdXBwb3J0ZWRJY29uc1N1Z2dlc3Rpb25zIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9pY29uLXNlbGVjdG9yL2ljb25zJztcblxuLyoqXG4gKiBJbnRlcmZhY2UgdGhhdCBkZXRlcm1pbmVzIHRoZSBhdmFpbGFibGUgY2xpY2sgb3B0aW9ucy5cbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDbGlja09wdGlvbnMge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIHNvdXJjZSBvZiB0aGUgZXZlbnQgaXMgYSBjbGljayBvbiB0aGUgbm9kZSBpY29uLlxuICAgKi9cbiAgaWNvbj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgc291cmNlIG9mIHRoZSBldmVudCBpcyBhIGNsaWNrIG9uIHRoZSBub2RlIGV4cGFuZGVyLlxuICAgKi9cbiAgZXhwYW5kZXI/OiBib29sZWFuO1xuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIG5hdmlnYXRvciBub2RlIGlzIGV4cGFuZGVkL2NvbGxhcHNlZC5cbiAgICovXG4gIG9wZW4/OiBib29sZWFuO1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBncm91cCBub2RlIHdoaWNoIHdpbGwgY29udGFpbiBhbGwgdW5hc3NpZ25lZCBkZXZpY2VzLlxuICAgKi9cbiAgc2hvd1VuYXNzaWduZWREZXZpY2VzPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIERPTSBldmVudC5cbiAgICovXG4gICRldmVudD86IGFueTsgLy8gVE9ETzogYWRkIHByb3BlciB0eXBlXG59XG4vKipcbiAqIEJhc2UgbmF2aWdhdG9yIG5vZGUuIFJlcHJlc2VudHMgYSBzaW5nbGUgZW50cnkgaW4gdGhlIG5hdmlnYXRvciBtZW51LlxuICogSXMgY29uc2lkZXJlZCB0byBiZSB0aGUgYmFzaWMgYnVpbGRpbmcgYmxvY2sgb2YgdGhlIG5hdmlnYXRvci5cbiAqL1xuZXhwb3J0IGNsYXNzIE5hdmlnYXRvck5vZGUge1xuICBzdGF0aWMgTkFNRSA9ICdOYXZpZ2F0b3JOb2RlJztcbiAgLyoqXG4gICAqIE5hdmlnYXRvciBub2RlIGljb24uXG4gICAqL1xuICBpY29uOiBTdXBwb3J0ZWRJY29uc1N1Z2dlc3Rpb25zO1xuXG4gIC8qKlxuICAgKiBOYXZpZ2F0b3Igbm9kZSBpY29uIHdoZW4gZXhwYW5kZWQuXG4gICAqL1xuICBpY29uT3Blbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gaWNvbiB0ZW1wbGF0ZS5cbiAgICovXG4gIGljb25UZW1wbGF0ZT86IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBpY29uIGNvbXBvbmVudC5cbiAgICovXG4gIGljb25Db21wb25lbnQ/OiBUeXBlPGFueT47XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRvciBub2RlIGNoaWxkcmVuIChzdWJlbnRyaWVzKS5cbiAgICovXG4gIGNoaWxkcmVuOiBOYXZpZ2F0b3JOb2RlW10gPSBbXTtcblxuICAvKipcbiAgICogTGFiZWwgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBuYXZpZ2F0b3Igbm9kZS5cbiAgICovXG4gIGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcGFzcyBgbGFiZWxgIHRocm91Z2ggYHRyYW5zbGF0ZWAgcGlwZSB3aGVuIGJlaW5nIGRpc3BsYXllZC5cbiAgICovXG4gIHRyYW5zbGF0ZUxhYmVsID0gdHJ1ZTtcblxuICAvKipcbiAgICogVGhlIHBhdGggdG8gd2hpY2ggdGhlIFVJIHdpbGwgYmUgcmVkaXJlY3RlZCBhZnRlciBjbGlja2luZyB0aGUgbmF2aWdhdG9yIG5vZGUuXG4gICAqL1xuICBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRvciBub2RlIHBhcmVudCBub2Rlcy5cbiAgICovXG4gIHBhcmVudHM6IE5hdmlnYXRvck5vZGVbXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBMb2FkaW5nIHN0YXRlIGluZGljYXRvci5cbiAgICovXG4gIGxvYWRpbmc/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIGxvYWQgdGhlIHByb3ZpZGVycyBmb3IgdGhlIGNvbXBvbmVudHMuIElmIG5vdCBwcm92aWRlZCwgZGVmYXVsdCBpbmplY3RvciB1cyB1c2VkLlxuICAgKi9cbiAgaW5qZWN0b3I/OiBJbmplY3RvcjtcblxuICAvKipcbiAgICogQ3VzdG9tIGNvbXBvbmVudCB0byB1c2UuXG4gICAqL1xuICBjb21wb25lbnQ/OiBUeXBlPGFueT47XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBuYXZpZ2F0b3Igbm9kZSBzaG91bGQgYmUgYWN0aXZlIGJhc2VkIG9uIG1hdGNoaW5nIHRoZSBub2RlIHBhdGggYW5kIHRoZSBVUkwgcGF0aC5cbiAgICogVG8gbWF0Y2ggdGhlIFVSTCBleGFjdGx5LCBzZXQgdGhpcyBvcHRpb24gdG8gdHJ1ZS5cbiAgICpcbiAgICogcm91dGVyTGlua0V4YWN0IHNldCB0byB0cnVlOlxuICAgKiBXaGVuIHRoZSBVUkwgcGF0aCBpcyBzZXQgdG8gL2EvYi9jIGFuZCB0aGUgbm9kZSBwYXRoIHRvIC9hL2IgdGhlbiB0aGUgbm9kZSB3aWxsIG5vdCBiZSBzZXQgYWN0aXZlLlxuICAgKlxuICAgKiByb3V0ZXJMaW5rRXhhY3Qgc2V0IHRvIGZhbHNlOlxuICAgKiBXaGVuIHRoZSBVUkwgcGF0aCBpcyBzZXQgdG8gL2EvYi9jIGFuZCB0aGUgbm9kZSBwYXRoIHRvIC9hL2IgdGhlbiB0aGUgbm9kZSB3aWxsIGJlIHNldCBhY3RpdmUuXG4gICAqL1xuICByb3V0ZXJMaW5rRXhhY3QgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgbmF2aWdhdG9yIG5vZGUgaXMgZXhwYW5kZWQvY29sbGFwc2VkLlxuICAgKi9cbiAgb3BlbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgbmF2aWdhdG9yIG5vZGUgaXMgdmlzaWJsZS9oaWRkZW4uXG4gICAqL1xuICBoaWRkZW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIG5hdmlnYXRvciBub2RlIGlzIGRyYWdnYWJsZS5cbiAgICovXG4gIGRyYWdnYWJsZSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgbmF2aWdhdG9yIG5vZGUgaXMgZHJvcHBhYmxlLlxuICAgKi9cbiAgZHJvcHBhYmxlID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IHRoZSBuYXZpZ2F0b3Igbm9kZSBpcyBkcmFnZ2VkLlxuICAgKi9cbiAgZHJhZ2dlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCBjdXJyZW50bHkgc29tZXRoaW5nIGlzIGRyYWdnZWQgb3ZlciB0aGUgbm9kZS5cbiAgICovXG4gIGRyYWdnZWRIb3ZlciA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBDb25maXJtYXRpb24gcG9wb3ZlciBkaXNwbGF5ZWQgYXQgdGhlIGVuZCBvZiB0aGUgcHJvY2VzcyBvZiBtb3ZpbmcgdGhlIG5hdmlnYXRvciBtZW51IGl0ZW0uXG4gICAqL1xuICBjb25maXJtOiBQb3BvdmVyQ29uZmlybUNvbXBvbmVudCA9IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIGJyZWFkY3J1bWIgb2YgdGhlIG5vZGUsIGRpc3BsYXlpbmcgdGhlIFwicGF0aFwiLCBidXQgc3VwcG9ydHMgbXVsdGlwbGUgbGV2ZWxzLlxuICAgKiBlLmcuIChHcm91cHMgPiBMZXZlbCAxID4gTGV2ZWwgMilcbiAgICovXG4gIGJyZWFkY3J1bWI/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElkIHRvIGlkZW50aWZ5IHNwZWNpZmljIGZlYXR1cmUgbm9kZS5cbiAgICovXG4gIGZlYXR1cmVJZD86IHN0cmluZztcblxuICBwcml2YXRlIF9wcmlvcml0eSA9IDA7XG4gIHByaXZhdGUgZXhwYW5kRHJhZ1RpbWVvdXQ7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgaW5mb3JtYXRpb24gd2hldGhlciBhIG5hdmlnYXRvciBub2RlIGhhcyBjaGlsZHJlbi5cbiAgICogQHJlYWRvbmx5XG4gICAqL1xuICBnZXQgaGFzQ2hpbGRyZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBJRCBvZiB0aGUgbmF2aWdhdG9yIG5vZGUuXG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgZ2V0IGlkKCkge1xuICAgIHJldHVybiAnbmF2aWdhdG9yX25vZGVfJyArIHNuYWtlQ2FzZSh0aGlzLmxhYmVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBwcmlvcml0eSB2YWx1ZSBvZiB0aGUgbmF2aWdhdG9yIG5vZGUuXG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgZ2V0IHByaW9yaXR5KCkge1xuICAgIGlmICh0aGlzLl9wcmlvcml0eSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ByaW9yaXR5O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjaGlsZHJlblByaW9yaXRpZXMgPSB0aGlzLmNoaWxkcmVuLm1hcCgoeyBwcmlvcml0eSB9KSA9PiBwcmlvcml0eSB8fCAwKTtcbiAgICAgIGlmIChjaGlsZHJlblByaW9yaXRpZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBjaGlsZHJlblByaW9yaXRpZXMubGVuZ3RoID8gTWF0aC5tYXgoLi4uY2hpbGRyZW5Qcmlvcml0aWVzKSA6IDA7XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgcHJpb3JpdHkgdmFsdWUgb2YgdGhlIG5hdmlnYXRvciBub2RlLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcHJpb3JpdHkgUHJpb3JpdHkgdmFsdWUuXG4gICAqL1xuICBzZXQgcHJpb3JpdHkocHJpb3JpdHkpIHtcbiAgICB0aGlzLl9wcmlvcml0eSA9IHByaW9yaXR5O1xuICB9XG5cbiAgY29uc3RydWN0b3IoZGF0YT86IE5hdmlnYXRvck5vZGVEYXRhKSB7XG4gICAgdGhpcy51cGRhdGUoZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIGNoaWxkIG5hdmlnYXRvciBub2RlIHRvIHRoZSBub2RlLlxuICAgKlxuICAgKiBAcGFyYW0ge05hdmlnYXRvck5vZGV9IG5vZGUgQ2hpbGQgbm9kZS5cbiAgICovXG4gIGFkZChub2RlOiBOYXZpZ2F0b3JOb2RlKSB7XG4gICAgaWYgKG5vZGUgPT09IHRoaXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWRkaW5nIG5vZGUgdG8gaXRzZWxmJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNoaWxkcmVuLmluZGV4T2Yobm9kZSkgPT09IC0xKSB7XG4gICAgICB0aGlzLmNoaWxkcmVuLnB1c2gobm9kZSk7XG4gICAgfVxuICAgIGlmIChub2RlLnBhcmVudHMuaW5kZXhPZih0aGlzKSA9PT0gLTEpIHtcbiAgICAgIG5vZGUucGFyZW50cy5wdXNoKHRoaXMpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUNoaWxkcmVuKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgY2hpbGQgbmF2aWdhdG9yIG5vZGUgZnJvbSB0aGUgbm9kZS5cbiAgICpcbiAgICogQHBhcmFtIHtOYXZpZ2F0b3JOb2RlfSBub2RlIENoaWxkIG5vZGUuXG4gICAqL1xuICByZW1vdmUobm9kZTogTmF2aWdhdG9yTm9kZSkge1xuICAgIGNvbnN0IGl4ID0gdGhpcy5jaGlsZHJlbi5pbmRleE9mKG5vZGUpO1xuICAgIGNvbnN0IHBpeCA9IG5vZGUucGFyZW50cy5pbmRleE9mKHRoaXMpO1xuICAgIGlmIChpeCA+IC0xKSB7XG4gICAgICB0aGlzLmNoaWxkcmVuLnNwbGljZShpeCwgMSk7XG4gICAgfVxuICAgIGlmIChwaXggPiAtMSkge1xuICAgICAgbm9kZS5wYXJlbnRzLnNwbGljZShwaXgsIDEpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUNoaWxkcmVuKCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgbmF2aWdhdG9yIG5vZGUuXG4gICAqXG4gICAqIEBwYXJhbSB7TmF2aWdhdG9yTm9kZURhdGF9IGRhdGEgRGF0YSB0byBiZSB1cGRhdGVkLlxuICAgKi9cbiAgdXBkYXRlKGRhdGE/OiBOYXZpZ2F0b3JOb2RlRGF0YSkge1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGRhdGEpO1xuICAgICAgaWYgKGRhdGEuaGlkZGVuICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5wYXJlbnRzLmZvckVhY2gocCA9PiB7XG4gICAgICAgICAgcC51cGRhdGVIaWRkZW4oKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIFJldHVybnMgYSBjaGlsZCBuYXZpZ2F0b3Igbm9kZSBiYXNlZCBvbiB0aGUgcHJlZGljYXRlLlxuICAgKlxuICAgKiBgYGB0c1xuICAgKiAvLyBUaGUgZnVuY3Rpb24gd2lsbCBjb21wYXJlIHRoZSBsYWJlbHMgdG8gdGhlIHN0cmluZyBhbmQgcmV0dXJuIGEgbWF0Y2hpbmcgcmVzdWx0LlxuICAgKiAvLyBUaGUgY2FwaXRhbGl6YXRpb24gb2YgdGhlIGNoYXJhY3RlcnMgZG9lcyBub3QgbWF0dGVyIChjYXNlIGluc2Vuc2l0aXZlKS5cbiAgICogY29uc3QgcHJlZGljYXRlID0gJ2dyb3VwMSc7XG4gICAqIGNvbnN0IGNoaWxkTm9kZSA9IHBhcmVudE5vZGUuZmluZChwcmVkaWNhdGUpO1xuICAgKiAvLyBDaGVjazogW2xvZGFzaCBtYXRjaGVzXShodHRwczovL2xvZGFzaC5jb20vZG9jcy80LjE3LjE1I21hdGNoZXMpXG4gICAqIGNvbnN0IHByZWRpY2F0ZSA9IHsgbGFiZWw6ICdncm91cDInIH07XG4gICAqIGNvbnN0IGNoaWxkTm9kZSA9IHBhcmVudE5vZGUuZmluZChwcmVkaWNhdGUpO1xuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIHByZWRpY2F0ZSBGaWx0ZXIgY3JpdGVyaWEuXG4gICAqIEBwYXJhbSBmaW5kQnkgTmF2aWdhdG9yTm9kZSBmaWVsZCBuYW1lIHRvIGNvbXBhcmUuXG4gICAqXG4gICAqL1xuICBmaW5kKHByZWRpY2F0ZSwgZmluZEJ5OiBrZXlvZiBQaWNrPE5hdmlnYXRvck5vZGUsICdsYWJlbCcgfCAnZmVhdHVyZUlkJz4gPSAnbGFiZWwnKSB7XG4gICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoZmluZEJ5ID09PSAnbGFiZWwnKSB7XG4gICAgICAgIGNvbnN0IGNvbXBhcmVMYWJlbCA9IHByZWRpY2F0ZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBwcmVkaWNhdGUgPSAoeyBsYWJlbCB9KSA9PiBjb21wYXJlTGFiZWwgPT09IGxhYmVsPy50b0xvd2VyQ2FzZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY29tcGFyZUlkID0gcHJlZGljYXRlO1xuICAgICAgICBwcmVkaWNhdGUgPSAoeyBmZWF0dXJlSWQgfSkgPT4gY29tcGFyZUlkID09PSBmZWF0dXJlSWQ7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcHJlZGljYXRlID09PSAnb2JqZWN0Jykge1xuICAgICAgcHJlZGljYXRlID0gbWF0Y2hlcyhwcmVkaWNhdGUpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHByZWRpY2F0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNlYXJjaCBwcmVkaWNhdGUnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4ucmVkdWNlKFxuICAgICAgKGZvdW5kLCBjaGlsZCkgPT4gZm91bmQgfHwgY2hpbGQuZmluZChwcmVkaWNhdGUpLFxuICAgICAgdGhpcy5jaGlsZHJlbi5maW5kKHByZWRpY2F0ZSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgY2hpbGRyZW4gbm9kZXMuXG4gICAqL1xuICBlbXB0eSgpIHtcbiAgICB0aGlzLmNoaWxkcmVuLmxlbmd0aCA9IDA7XG4gIH1cblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgY2xpY2soX29wdGlvbnM6IENsaWNrT3B0aW9ucyA9IHt9KSB7XG4gICAgLy8gZG8gbm90aGluZ1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZXZlbnQgaXMgZmlyZWQgd2hlbiBhbiBlbGVtZW50IGlzIGRyb3BwZWQgb24gYSB2YWxpZCBkcm9wIHRhcmdldC5cbiAgICogQHBhcmFtICRldmVudCBET00gZXZlbnQuXG4gICAqL1xuICBkcm9wKCRldmVudCkge1xuICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5leHBhbmREcmFnVGltZW91dCk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIHRoZSB1c2VyIHN0YXJ0cyBkcmFnZ2luZyBhbiBlbGVtZW50LlxuICAgKiBAcGFyYW0gJGV2ZW50IERPTSBldmVudC5cbiAgICovXG4gIGRyYWdTdGFydCgkZXZlbnQpIHtcbiAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgLy8gd2UgY2FuJ3QgcGFzcyBhIG9iamVjdCB0byBzZXREYXRhLCBzbyB3ZSBkbyBpdCB2aWEgc2VydmljZVxuICAgIC8vIHNldCBkYXRhIGlzIHN0aWxsIG5lZWRlZCwgdG8gbWFrZSB0aGUgZHJhZyZkcm9wIHdvcmtcbiAgICAkZXZlbnQuZGF0YVRyYW5zZmVyPy5zZXREYXRhKCdub2RlJywgJ25vZGUnKTtcbiAgICB0aGlzLmRyYWdnZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZXZlbnQgaXMgZmlyZWQgd2hlbiBhIGRyYWcgb3BlcmF0aW9uIGhhcyBlbmRlZC5cbiAgICogQHBhcmFtICRldmVudCBET00gZXZlbnQuXG4gICAqL1xuICBkcmFnRW5kKCRldmVudCkge1xuICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRyYWdnZWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGluZm9ybWF0aW9uIHdoZXRoZXIgdGhlIG5hdmlnYXRvciBub2RlIGlzIGRyb3BwYWJsZS5cbiAgICogQHJlYWRvbmx5XG4gICAqL1xuICBnZXQgY2FuRHJvcCgpIHtcbiAgICByZXR1cm4gdGhpcy5kcm9wcGFibGU7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBpbmZvcm1hdGlvbiB3aGV0aGVyIG5hdmlnYXRpb24gaXMgcG9zc2libGUuXG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgZ2V0IGNhbk5hdmlnYXRlKCkge1xuICAgIHJldHVybiB0eXBlb2YgdGhpcy5wYXRoICE9PSAndW5kZWZpbmVkJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYSBkcmFnZ2VkIGVsZW1lbnQgZW50ZXJzIGEgdmFsaWQgZHJvcCB0YXJnZXQuXG4gICAqIEBwYXJhbSAkZXZlbnQgRE9NIGV2ZW50LlxuICAgKi9cbiAgZHJhZ0VudGVyKCRldmVudCkge1xuICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRyYWdnZWRIb3ZlciA9IHRydWU7XG4gICAgaWYgKCF0aGlzLm9wZW4pIHtcbiAgICAgIHRoaXMuZXhwYW5kRHJhZ1RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuZXhwYW5kKCksIDEwMDApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYSBkcmFnZ2VkIGVsZW1lbnQgbGVhdmVzIGEgdmFsaWQgZHJvcCB0YXJnZXQuXG4gICAqIEBwYXJhbSAkZXZlbnQgRE9NIGV2ZW50LlxuICAgKi9cbiAgZHJhZ0xlYXZlKCRldmVudCkge1xuICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoJGV2ZW50LmN1cnJlbnRUYXJnZXQuY29udGFpbnMoJGV2ZW50LnJlbGF0ZWRUYXJnZXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuZHJhZ2dlZEhvdmVyID0gZmFsc2U7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuZXhwYW5kRHJhZ1RpbWVvdXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZHMgdGhlIG5hdmlnYXRvciBub2RlIGlmIGl0IGlzIGNvbGxhcHNlZC5cbiAgICovXG4gIGV4cGFuZCgpIHtcbiAgICBpZiAoIXRoaXMub3Blbikge1xuICAgICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2xpY2soeyBvcGVuOiB0cnVlLCBleHBhbmRlcjogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybXMgYSBjYWxsYmFjayBmdW5jdGlvbiByZWN1cnNpdmVseSBvbiBlYWNoIG9mIHRoZSBuYXZpZ2F0b3Igbm9kZSdzIGNoaWxkcmVuIGRvd24gdGhlIGhpZXJhcmNoeS5cbiAgICpcbiAgICogYGBgdHNcbiAgICogY29uc3QgZXhwYW5kQ2hpbGQgPSAoY2hpbGROb2RlKSA9PiBjaGlsZE5vZGUuZXhwYW5kKCk7XG4gICAqIHBhcmVudE5vZGUudHJhdmVyc2UoZXhwYW5kQ2hpbGQpO1xuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGJlIGNhbGxlZC5cbiAgICovXG4gIHRyYXZlcnNlKGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuY2hpbGRyZW4pIHtcbiAgICAgIHRoaXMuY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgIGNhbGxiYWNrKGNoaWxkKTtcbiAgICAgICAgY2hpbGQudHJhdmVyc2UoY2FsbGJhY2spO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGRlc3Ryb3koKSB7XG4gICAgLy8gbm90aGluZyB0b2RvIGhlcmVcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3VudHMgdGhlIGFtb3VudCBvZiBjaGlsZHJlbiBub2Rlcy5cbiAgICovXG4gIHByb3RlY3RlZCBjb3VudENoaWxkcmVuKCkge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZGVudGlmaWVzIGl0c2VsZi5cbiAgICovXG4gIHByb3RlY3RlZCB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gTmF2aWdhdG9yTm9kZS5OQU1FO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhc0NoaWxkRGV2aWNlcygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgbmF2aWdhdG9yIG5vZGUgYnkgc29ydGluZyBpdHMgY2hpbGRyZW4gYW5kIGFsc28gY2hlY2tpbmcgdGhlaXIgdmlzaWJpbGl0eS5cbiAgICovXG4gIHByb3RlY3RlZCB1cGRhdGVDaGlsZHJlbigpIHtcbiAgICB0aGlzLnNvcnQoKTtcbiAgICB0aGlzLnVwZGF0ZUhpZGRlbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNvcnRzIHRoZSBjaGlsZHJlbiBvZiB0aGUgbmF2aWdhdG9yIG5vZGUsIGJ5IHByaW9yaXR5IGFuZCBuYW1lIChBU0MpLlxuICAgKiBUaGUgaGlnaGVyIHRoZSBwcmlvcml0eSwgdGhlIGhpZ2hlciB0aGUgcG9zaXRpb24gaW4gdGhlIGhpZXJhcmNoeS5cbiAgICogRm9yIHRoZSBzYW1lIHByaW9yaXR5IHZhbHVlcywgdGhlIGFscGhhYmV0aWNhbCBvcmRlciB3aWxsIHRha2UgcHJlY2VkZW5jZS5cbiAgICovXG4gIHByb3RlY3RlZCBzb3J0KCkge1xuICAgIHRoaXMuY2hpbGRyZW4uc29ydCgoYSwgYikgPT4ge1xuICAgICAgaWYgKGEucHJpb3JpdHkgPiBiLnByaW9yaXR5KSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH0gZWxzZSBpZiAoYS5wcmlvcml0eSA8IGIucHJpb3JpdHkpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9IGVsc2UgaWYgKChhLmxhYmVsIHx8ICcnKS50b0xvd2VyQ2FzZSgpIDwgKGIubGFiZWwgfHwgJycpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIGlmICgoYS5sYWJlbCB8fCAnJykudG9Mb3dlckNhc2UoKSA+IChiLmxhYmVsIHx8ICcnKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBuYXZpZ2F0b3Igbm9kZSBzaG91bGQgYmUgaGlkZGVuIGJhc2VkIG9uIHRoZSB2aXNpYmlsaXR5IG9mIGl0cyBjaGlsZCBub2Rlcy5cbiAgICovXG4gIHByb3RlY3RlZCB1cGRhdGVIaWRkZW4oKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnBhdGggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLmhpZGRlbiA9ICF0aGlzLmNoaWxkcmVuLnNvbWUoKHsgaGlkZGVuIH0pID0+ICFoaWRkZW4pO1xuICAgIH1cbiAgfVxufVxuIl19