ngx-spine
Version:
[](https://travis-ci.org/PoiScript/ngx-spine)
361 lines • 34.5 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "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 ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) 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 { Pool } from "../core/Utils";
export class Input {
/**
* @param {?} element
*/
constructor(element) {
this.lastX = 0;
this.lastY = 0;
this.buttonDown = false;
this.currTouch = null;
this.touchesPool = new Pool((/**
* @return {?}
*/
() => {
return new Touch(0, 0, 0);
}));
this.listeners = new Array();
this.element = element;
this.setupCallbacks(element);
}
/**
* @private
* @param {?} element
* @return {?}
*/
setupCallbacks(element) {
/** @type {?} */
let mouseDown = (/**
* @param {?} ev
* @return {?}
*/
(ev) => {
if (ev instanceof MouseEvent) {
/** @type {?} */
let rect = element.getBoundingClientRect();
/** @type {?} */
let x = ev.clientX - rect.left;
/** @type {?} */
let y = ev.clientY - rect.top;
/** @type {?} */
let listeners = this.listeners;
for (let i = 0; i < listeners.length; i++) {
listeners[i].down(x, y);
}
this.lastX = x;
this.lastY = y;
this.buttonDown = true;
document.addEventListener("mousemove", mouseMove);
document.addEventListener("mouseup", mouseUp);
}
});
/** @type {?} */
let mouseMove = (/**
* @param {?} ev
* @return {?}
*/
(ev) => {
if (ev instanceof MouseEvent) {
/** @type {?} */
let rect = element.getBoundingClientRect();
/** @type {?} */
let x = ev.clientX - rect.left;
/** @type {?} */
let y = ev.clientY - rect.top;
/** @type {?} */
let listeners = this.listeners;
for (let i = 0; i < listeners.length; i++) {
if (this.buttonDown) {
listeners[i].dragged(x, y);
}
else {
listeners[i].moved(x, y);
}
}
this.lastX = x;
this.lastY = y;
}
});
/** @type {?} */
let mouseUp = (/**
* @param {?} ev
* @return {?}
*/
(ev) => {
if (ev instanceof MouseEvent) {
/** @type {?} */
let rect = element.getBoundingClientRect();
/** @type {?} */
let x = ev.clientX - rect.left;
/** @type {?} */
let y = ev.clientY - rect.top;
/** @type {?} */
let listeners = this.listeners;
for (let i = 0; i < listeners.length; i++) {
listeners[i].up(x, y);
}
this.lastX = x;
this.lastY = y;
this.buttonDown = false;
document.removeEventListener("mousemove", mouseMove);
document.removeEventListener("mouseup", mouseUp);
}
});
element.addEventListener("mousedown", mouseDown, true);
element.addEventListener("mousemove", mouseMove, true);
element.addEventListener("mouseup", mouseUp, true);
element.addEventListener("touchstart", (/**
* @param {?} ev
* @return {?}
*/
(ev) => {
if (this.currTouch != null)
return;
/** @type {?} */
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
/** @type {?} */
var touch = touches[i];
/** @type {?} */
let rect = element.getBoundingClientRect();
/** @type {?} */
let x = touch.clientX - rect.left;
/** @type {?} */
let y = touch.clientY - rect.top;
this.currTouch = this.touchesPool.obtain();
this.currTouch.identifier = touch.identifier;
this.currTouch.x = x;
this.currTouch.y = y;
break;
}
/** @type {?} */
let listeners = this.listeners;
for (let i = 0; i < listeners.length; i++) {
listeners[i].down(this.currTouch.x, this.currTouch.y);
}
console.log("Start " + this.currTouch.x + ", " + this.currTouch.y);
this.lastX = this.currTouch.x;
this.lastY = this.currTouch.y;
this.buttonDown = true;
ev.preventDefault();
}), false);
element.addEventListener("touchend", (/**
* @param {?} ev
* @return {?}
*/
(ev) => {
/** @type {?} */
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
/** @type {?} */
var touch = touches[i];
if (this.currTouch.identifier === touch.identifier) {
/** @type {?} */
let rect = element.getBoundingClientRect();
/** @type {?} */
let x = (this.currTouch.x = touch.clientX - rect.left);
/** @type {?} */
let y = (this.currTouch.y = touch.clientY - rect.top);
this.touchesPool.free(this.currTouch);
/** @type {?} */
let listeners = this.listeners;
for (let i = 0; i < listeners.length; i++) {
listeners[i].up(x, y);
}
console.log("End " + x + ", " + y);
this.lastX = x;
this.lastY = y;
this.buttonDown = false;
this.currTouch = null;
break;
}
}
ev.preventDefault();
}), false);
element.addEventListener("touchcancel", (/**
* @param {?} ev
* @return {?}
*/
(ev) => {
/** @type {?} */
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
/** @type {?} */
var touch = touches[i];
if (this.currTouch.identifier === touch.identifier) {
/** @type {?} */
let rect = element.getBoundingClientRect();
/** @type {?} */
let x = (this.currTouch.x = touch.clientX - rect.left);
/** @type {?} */
let y = (this.currTouch.y = touch.clientY - rect.top);
this.touchesPool.free(this.currTouch);
/** @type {?} */
let listeners = this.listeners;
for (let i = 0; i < listeners.length; i++) {
listeners[i].up(x, y);
}
console.log("End " + x + ", " + y);
this.lastX = x;
this.lastY = y;
this.buttonDown = false;
this.currTouch = null;
break;
}
}
ev.preventDefault();
}), false);
element.addEventListener("touchmove", (/**
* @param {?} ev
* @return {?}
*/
(ev) => {
if (this.currTouch == null)
return;
/** @type {?} */
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
/** @type {?} */
var touch = touches[i];
if (this.currTouch.identifier === touch.identifier) {
/** @type {?} */
let rect = element.getBoundingClientRect();
/** @type {?} */
let x = touch.clientX - rect.left;
/** @type {?} */
let y = touch.clientY - rect.top;
/** @type {?} */
let listeners = this.listeners;
for (let i = 0; i < listeners.length; i++) {
listeners[i].dragged(x, y);
}
console.log("Drag " + x + ", " + y);
this.lastX = this.currTouch.x = x;
this.lastY = this.currTouch.y = y;
break;
}
}
ev.preventDefault();
}), false);
}
/**
* @param {?} listener
* @return {?}
*/
addListener(listener) {
this.listeners.push(listener);
}
/**
* @param {?} listener
* @return {?}
*/
removeListener(listener) {
/** @type {?} */
let idx = this.listeners.indexOf(listener);
if (idx > -1) {
this.listeners.splice(idx, 1);
}
}
}
if (false) {
/** @type {?} */
Input.prototype.element;
/** @type {?} */
Input.prototype.lastX;
/** @type {?} */
Input.prototype.lastY;
/** @type {?} */
Input.prototype.buttonDown;
/** @type {?} */
Input.prototype.currTouch;
/** @type {?} */
Input.prototype.touchesPool;
/**
* @type {?}
* @private
*/
Input.prototype.listeners;
}
export class Touch {
/**
* @param {?} identifier
* @param {?} x
* @param {?} y
*/
constructor(identifier, x, y) {
this.identifier = identifier;
this.x = x;
this.y = y;
}
}
if (false) {
/** @type {?} */
Touch.prototype.identifier;
/** @type {?} */
Touch.prototype.x;
/** @type {?} */
Touch.prototype.y;
}
/**
* @record
*/
export function InputListener() { }
if (false) {
/**
* @param {?} x
* @param {?} y
* @return {?}
*/
InputListener.prototype.down = function (x, y) { };
/**
* @param {?} x
* @param {?} y
* @return {?}
*/
InputListener.prototype.up = function (x, y) { };
/**
* @param {?} x
* @param {?} y
* @return {?}
*/
InputListener.prototype.moved = function (x, y) { };
/**
* @param {?} x
* @param {?} y
* @return {?}
*/
InputListener.prototype.dragged = function (x, y) { };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5wdXQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtc3BpbmUvIiwic291cmNlcyI6WyJsaWIvc3BpbmUtdHMvd2ViZ2wvSW5wdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE2QkEsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVyQyxNQUFNLE9BQU8sS0FBSzs7OztJQVVoQixZQUFZLE9BQW9CO1FBUmhDLFVBQUssR0FBRyxDQUFDLENBQUM7UUFDVixVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixjQUFTLEdBQVUsSUFBSSxDQUFDO1FBQ3hCLGdCQUFXLEdBQUcsSUFBSSxJQUFJOzs7UUFBUSxHQUFHLEVBQUU7WUFDakMsT0FBTyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzVCLENBQUMsRUFBQyxDQUFDO1FBQ0ssY0FBUyxHQUFHLElBQUksS0FBSyxFQUFpQixDQUFDO1FBRTdDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0IsQ0FBQzs7Ozs7O0lBQ08sY0FBYyxDQUFDLE9BQW9COztZQUNyQyxTQUFTOzs7O1FBQUcsQ0FBQyxFQUFXLEVBQUUsRUFBRTtZQUM5QixJQUFJLEVBQUUsWUFBWSxVQUFVLEVBQUU7O29CQUN4QixJQUFJLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixFQUFFOztvQkFDdEMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUk7O29CQUMxQixDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzs7b0JBQ3pCLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUztnQkFDOUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFD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Q0FBQyxDQUFDLENBQUM7U0FDL0I7SUFDSCxDQUFDO0NBQ0Y7OztJQXZMQyx3QkFBcUI7O0lBQ3JCLHNCQUFVOztJQUNWLHNCQUFVOztJQUNWLDJCQUFtQjs7SUFDbkIsMEJBQXdCOztJQUN4Qiw0QkFFRzs7Ozs7SUFDSCwwQkFBK0M7O0FBZ0xqRCxNQUFNLE9BQU8sS0FBSzs7Ozs7O0lBQ2hCLFlBQW1CLFVBQWtCLEVBQVMsQ0FBUyxFQUFTLENBQVM7UUFBdEQsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUFTLE1BQUMsR0FBRCxDQUFDLENBQVE7UUFBUyxNQUFDLEdBQUQsQ0FBQyxDQUFRO0lBQUcsQ0FBQztDQUM5RTs7O0lBRGEsMkJBQXlCOztJQUFFLGtCQUFnQjs7SUFBRSxrQkFBZ0I7Ozs7O0FBRTNFLG1DQUtDOzs7Ozs7O0lBSkMsbURBQWlDOzs7Ozs7SUFDakMsaURBQStCOzs7Ozs7SUFDL0Isb0RBQWtDOzs7Ozs7SUFDbEMsc0RBQW9DIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxyXG4gKiBMYXN0IHVwZGF0ZWQgTWF5IDEsIDIwMTkuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cclxuICpcclxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMTksIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xyXG4gKlxyXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcclxuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcclxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcclxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXHJcbiAqXHJcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxyXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXHJcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cclxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XHJcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxyXG4gKlxyXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWSBFWFBSRVNTXHJcbiAqIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVNcclxuICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU5cclxuICogTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsXHJcbiAqIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsXHJcbiAqIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUywgQlVTSU5FU1NcclxuICogSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWVxyXG4gKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkdcclxuICogTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLFxyXG4gKiBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxyXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcblxyXG5pbXBvcnQgeyBQb29sIH0gZnJvbSBcIi4uL2NvcmUvVXRpbHNcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBJbnB1dCB7XHJcbiAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcbiAgbGFzdFggPSAwO1xyXG4gIGxhc3RZID0gMDtcclxuICBidXR0b25Eb3duID0gZmFsc2U7XHJcbiAgY3VyclRvdWNoOiBUb3VjaCA9IG51bGw7XHJcbiAgdG91Y2hlc1Bvb2wgPSBuZXcgUG9vbDxUb3VjaD4oKCkgPT4ge1xyXG4gICAgcmV0dXJuIG5ldyBUb3VjaCgwLCAwLCAwKTtcclxuICB9KTtcclxuICBwcml2YXRlIGxpc3RlbmVycyA9IG5ldyBBcnJheTxJbnB1dExpc3RlbmVyPigpO1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XHJcbiAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5zZXR1cENhbGxiYWNrcyhlbGVtZW50KTtcclxuICB9XHJcbiAgcHJpdmF0ZSBzZXR1cENhbGxiYWNrcyhlbGVtZW50OiBIVE1MRWxlbWVudCkge1xyXG4gICAgbGV0IG1vdXNlRG93biA9IChldjogVUlFdmVudCkgPT4ge1xyXG4gICAgICBpZiAoZXYgaW5zdGFuY2VvZiBNb3VzZUV2ZW50KSB7XHJcbiAgICAgICAgbGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIGxldCB4ID0gZXYuY2xpZW50WCAtIHJlY3QubGVmdDtcclxuICAgICAgICBsZXQgeSA9IGV2LmNsaWVudFkgLSByZWN0LnRvcDtcclxuICAgICAgICBsZXQgbGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnM7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIGxpc3RlbmVyc1tpXS5kb3duKHgsIHkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmxhc3RYID0geDtcclxuICAgICAgICB0aGlzLmxhc3RZID0geTtcclxuICAgICAgICB0aGlzLmJ1dHRvbkRvd24gPSB0cnVlO1xyXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgbW91c2VNb3ZlKTtcclxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBtb3VzZVVwKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICAgIGxldCBtb3VzZU1vdmUgPSAoZXY6IFVJRXZlbnQpID0+IHtcclxuICAgICAgaWYgKGV2IGluc3RhbmNlb2YgTW91c2VFdmVudCkge1xyXG4gICAgICAgIGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICBsZXQgeCA9IGV2LmNsaWVudFggLSByZWN0LmxlZnQ7XHJcbiAgICAgICAgbGV0IHkgPSBldi5jbGllbnRZIC0gcmVjdC50b3A7XHJcbiAgICAgICAgbGV0IGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICBpZiAodGhpcy5idXR0b25Eb3duKSB7XHJcbiAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5kcmFnZ2VkKHgsIHkpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzW2ldLm1vdmVkKHgsIHkpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmxhc3RYID0geDtcclxuICAgICAgICB0aGlzLmxhc3RZID0geTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICAgIGxldCBtb3VzZVVwID0gKGV2OiBVSUV2ZW50KSA9PiB7XHJcbiAgICAgIGlmIChldiBpbnN0YW5jZW9mIE1vdXNlRXZlbnQpIHtcclxuICAgICAgICBsZXQgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgbGV0IHggPSBldi5jbGllbnRYIC0gcmVjdC5sZWZ0O1xyXG4gICAgICAgIGxldCB5ID0gZXYuY2xpZW50WSAtIHJlY3QudG9wO1xyXG4gICAgICAgIGxldCBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVycztcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgbGlzdGVuZXJzW2ldLnVwKHgsIHkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmxhc3RYID0geDtcclxuICAgICAgICB0aGlzLmxhc3RZID0geTtcclxuICAgICAgICB0aGlzLmJ1dHRvbkRvd24gPSBmYWxzZTtcclxuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIG1vdXNlTW92ZSk7XHJcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgbW91c2VVcCk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgbW91c2VEb3duLCB0cnVlKTtcclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCBtb3VzZU1vdmUsIHRydWUpO1xyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBtb3VzZVVwLCB0cnVlKTtcclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgXCJ0b3VjaHN0YXJ0XCIsXHJcbiAgICAgIChldjogVG91Y2hFdmVudCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLmN1cnJUb3VjaCAhPSBudWxsKSByZXR1cm47XHJcbiAgICAgICAgdmFyIHRvdWNoZXMgPSBldi5jaGFuZ2VkVG91Y2hlcztcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvdWNoZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIHZhciB0b3VjaCA9IHRvdWNoZXNbaV07XHJcbiAgICAgICAgICBsZXQgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgICBsZXQgeCA9IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQ7XHJcbiAgICAgICAgICBsZXQgeSA9IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcclxuICAgICAgICAgIHRoaXMuY3VyclRvdWNoID0gdGhpcy50b3VjaGVzUG9vbC5vYnRhaW4oKTtcclxuICAgICAgICAgIHRoaXMuY3VyclRvdWNoLmlkZW50aWZpZXIgPSB0b3VjaC5pZGVudGlmaWVyO1xyXG4gICAgICAgICAgdGhpcy5jdXJyVG91Y2gueCA9IHg7XHJcbiAgICAgICAgICB0aGlzLmN1cnJUb3VjaC55ID0geTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgbGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnM7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIGxpc3RlbmVyc1tpXS5kb3duKHRoaXMuY3VyclRvdWNoLngsIHRoaXMuY3VyclRvdWNoLnkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zb2xlLmxvZyhcIlN0YXJ0IFwiICsgdGhpcy5jdXJyVG91Y2gueCArIFwiLCBcIiArIHRoaXMuY3VyclRvdWNoLnkpO1xyXG4gICAgICAgIHRoaXMubGFzdFggPSB0aGlzLmN1cnJUb3VjaC54O1xyXG4gICAgICAgIHRoaXMubGFzdFkgPSB0aGlzLmN1cnJUb3VjaC55O1xyXG4gICAgICAgIHRoaXMuYnV0dG9uRG93biA9IHRydWU7XHJcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgfSxcclxuICAgICAgZmFsc2VcclxuICAgICk7XHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXHJcbiAgICAgIFwidG91Y2hlbmRcIixcclxuICAgICAgKGV2OiBUb3VjaEV2ZW50KSA9PiB7XHJcbiAgICAgICAgdmFyIHRvdWNoZXMgPSBldi5jaGFuZ2VkVG91Y2hlcztcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvdWNoZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIHZhciB0b3VjaCA9IHRvdWNoZXNbaV07XHJcbiAgICAgICAgICBpZiAodGhpcy5jdXJyVG91Y2guaWRlbnRpZmllciA9PT0gdG91Y2guaWRlbnRpZmllcikge1xyXG4gICAgICAgICAgICBsZXQgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgICAgIGxldCB4ID0gKHRoaXMuY3VyclRvdWNoLnggPSB0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0KTtcclxuICAgICAgICAgICAgbGV0IHkgPSAodGhpcy5jdXJyVG91Y2gueSA9IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcCk7XHJcbiAgICAgICAgICAgIHRoaXMudG91Y2hlc1Bvb2wuZnJlZSh0aGlzLmN1cnJUb3VjaCk7XHJcbiAgICAgICAgICAgIGxldCBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVycztcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0udXAoeCwgeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc29sZS5sb2coXCJFbmQgXCIgKyB4ICsgXCIsIFwiICsgeSk7XHJcbiAgICAgICAgICAgIHRoaXMubGFzdFggPSB4O1xyXG4gICAgICAgICAgICB0aGlzLmxhc3RZID0geTtcclxuICAgICAgICAgICAgdGhpcy5idXR0b25Eb3duID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuY3VyclRvdWNoID0gbnVsbDtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIGZhbHNlXHJcbiAgICApO1xyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxyXG4gICAgICBcInRvdWNoY2FuY2VsXCIsXHJcbiAgICAgIChldjogVG91Y2hFdmVudCkgPT4ge1xyXG4gICAgICAgIHZhciB0b3VjaGVzID0gZXYuY2hhbmdlZFRvdWNoZXM7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b3VjaGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICB2YXIgdG91Y2ggPSB0b3VjaGVzW2ldO1xyXG4gICAgICAgICAgaWYgKHRoaXMuY3VyclRvdWNoLmlkZW50aWZpZXIgPT09IHRvdWNoLmlkZW50aWZpZXIpIHtcclxuICAgICAgICAgICAgbGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgICAgICBsZXQgeCA9ICh0aGlzLmN1cnJUb3VjaC54ID0gdG91Y2guY2xpZW50WCAtIHJlY3QubGVmdCk7XHJcbiAgICAgICAgICAgIGxldCB5ID0gKHRoaXMuY3VyclRvdWNoLnkgPSB0b3VjaC5jbGllbnRZIC0gcmVjdC50b3ApO1xyXG4gICAgICAgICAgICB0aGlzLnRvdWNoZXNQb29sLmZyZWUodGhpcy5jdXJyVG91Y2gpO1xyXG4gICAgICAgICAgICBsZXQgbGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnM7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLnVwKHgsIHkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiRW5kIFwiICsgeCArIFwiLCBcIiArIHkpO1xyXG4gICAgICAgICAgICB0aGlzLmxhc3RYID0geDtcclxuICAgICAgICAgICAgdGhpcy5sYXN0WSA9IHk7XHJcbiAgICAgICAgICAgIHRoaXMuYnV0dG9uRG93biA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJUb3VjaCA9IG51bGw7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB9LFxyXG4gICAgICBmYWxzZVxyXG4gICAgKTtcclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgXCJ0b3VjaG1vdmVcIixcclxuICAgICAgKGV2OiBUb3VjaEV2ZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3VyclRvdWNoID09IG51bGwpIHJldHVybjtcclxuICAgICAgICB2YXIgdG91Y2hlcyA9IGV2LmNoYW5nZWRUb3VjaGVzO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG91Y2hlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgdmFyIHRvdWNoID0gdG91Y2hlc1tpXTtcclxuICAgICAgICAgIGlmICh0aGlzLmN1cnJUb3VjaC5pZGVudGlmaWVyID09PSB0b3VjaC5pZGVudGlmaWVyKSB7XHJcbiAgICAgICAgICAgIGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICAgICAgbGV0IHggPSB0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xyXG4gICAgICAgICAgICBsZXQgeSA9IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcclxuICAgICAgICAgICAgbGV0IGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5kcmFnZ2VkKHgsIHkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiRHJhZyBcIiArIHggKyBcIiwgXCIgKyB5KTtcclxuICAgICAgICAgICAgdGhpcy5sYXN0WCA9IHRoaXMuY3VyclRvdWNoLnggPSB4O1xyXG4gICAgICAgICAgICB0aGlzLmxhc3RZID0gdGhpcy5jdXJyVG91Y2gueSA9IHk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB9LFxyXG4gICAgICBmYWxzZVxyXG4gICAgKTtcclxuICB9XHJcbiAgYWRkTGlzdGVuZXIobGlzdGVuZXI6IElucHV0TGlzdGVuZXIpIHtcclxuICAgIHRoaXMubGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xyXG4gIH1cclxuICByZW1vdmVMaXN0ZW5lcihsaXN0ZW5lcjogSW5wdXRMaXN0ZW5lcikge1xyXG4gICAgbGV0IGlkeCA9IHRoaXMubGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xyXG4gICAgaWYgKGlkeCA+IC0xKSB7XHJcbiAgICAgIHRoaXMubGlzdGVuZXJzLnNwbGljZShpZHgsIDEpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5leHBvcnQgY2xhc3MgVG91Y2gge1xyXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBpZGVudGlmaWVyOiBudW1iZXIsIHB1YmxpYyB4OiBudW1iZXIsIHB1YmxpYyB5OiBudW1iZXIpIHt9XHJcbn1cclxuZXhwb3J0IGludGVyZmFjZSBJbnB1dExpc3RlbmVyIHtcclxuICBkb3duKHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZDtcclxuICB1cCh4OiBudW1iZXIsIHk6IG51bWJlcik6IHZvaWQ7XHJcbiAgbW92ZWQoeDogbnVtYmVyLCB5OiBudW1iZXIpOiB2b2lkO1xyXG4gIGRyYWdnZWQoeDogbnVtYmVyLCB5OiBudW1iZXIpOiB2b2lkO1xyXG59XHJcbiJdfQ==