UNPKG

@esotericsoftware/spine-webgl

Version:
247 lines 38.4 kB
/****************************************************************************** * Spine Runtimes License Agreement * Last updated April 5, 2025. Replaces all prior versions. * * Copyright (c) 2013-2025, 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. * * THE SPINE RUNTIMES ARE 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 * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ export class Input { element; mouseX = 0; mouseY = 0; buttonDown = false; touch0 = null; touch1 = null; initialPinchDistance = 0; listeners = new Array(); autoPreventDefault; // this is needed because browsers sends mousedown-mousemove-mousesup after a touch sequence, unless touch end preventDefault // but preventing default will result in preventing interaction with the page. isTouch = false; callbacks; constructor(element, autoPreventDefault = true) { this.element = element; this.autoPreventDefault = autoPreventDefault; this.callbacks = this.setupCallbacks(element); } setupCallbacks(element) { const mouseDown = (ev) => { if (ev instanceof MouseEvent && !this.isTouch) { let rect = element.getBoundingClientRect(); this.mouseX = ev.clientX - rect.left; this.mouseY = ev.clientY - rect.top; this.buttonDown = true; this.listeners.map((listener) => { if (listener.down) listener.down(this.mouseX, this.mouseY, ev); }); } }; const mouseMove = (ev) => { if (ev instanceof MouseEvent && !this.isTouch) { let rect = element.getBoundingClientRect(); this.mouseX = ev.clientX - rect.left; this.mouseY = ev.clientY - rect.top; this.listeners.map((listener) => { if (this.buttonDown) { if (listener.dragged) listener.dragged(this.mouseX, this.mouseY, ev); } else { if (listener.moved) listener.moved(this.mouseX, this.mouseY, ev); } }); } }; const mouseUp = (ev) => { if (ev instanceof MouseEvent && !this.isTouch) { let rect = element.getBoundingClientRect(); this.mouseX = ev.clientX - rect.left; ; this.mouseY = ev.clientY - rect.top; this.buttonDown = false; this.listeners.map((listener) => { if (listener.up) listener.up(this.mouseX, this.mouseY, ev); }); } }; const mouseWheel = (ev) => { if (this.autoPreventDefault) ev.preventDefault(); let deltaY = ev.deltaY; if (ev.deltaMode == WheelEvent.DOM_DELTA_LINE) deltaY *= 8; if (ev.deltaMode == WheelEvent.DOM_DELTA_PAGE) deltaY *= 24; this.listeners.map((listener) => { if (listener.wheel) listener.wheel(ev.deltaY, ev); }); }; const touchStart = (ev) => { this.isTouch = true; if (!this.touch0 || !this.touch1) { var touches = ev.changedTouches; let nativeTouch = touches.item(0); if (!nativeTouch) return; let rect = element.getBoundingClientRect(); let x = nativeTouch.clientX - rect.left; let y = nativeTouch.clientY - rect.top; let touch = new Touch(nativeTouch.identifier, x, y); this.mouseX = x; this.mouseY = y; this.buttonDown = true; if (!this.touch0) { this.touch0 = touch; this.listeners.map((listener) => { if (listener.down) listener.down(touch.x, touch.y, ev); }); } else if (!this.touch1) { this.touch1 = touch; let dx = this.touch1.x - this.touch0.x; let dy = this.touch1.x - this.touch0.x; this.initialPinchDistance = Math.sqrt(dx * dx + dy * dy); this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, this.initialPinchDistance, ev); }); } } if (this.autoPreventDefault) ev.preventDefault(); }; const touchMove = (ev) => { this.isTouch = true; if (this.touch0) { var touches = ev.changedTouches; let rect = element.getBoundingClientRect(); for (var i = 0; i < touches.length; i++) { var nativeTouch = touches[i]; let x = nativeTouch.clientX - rect.left; let y = nativeTouch.clientY - rect.top; if (this.touch0.identifier === nativeTouch.identifier) { this.touch0.x = this.mouseX = x; this.touch0.y = this.mouseY = y; this.listeners.map((listener) => { if (listener.dragged) listener.dragged(x, y, ev); }); } if (this.touch1 && this.touch1.identifier === nativeTouch.identifier) { this.touch1.x = this.mouseX = x; this.touch1.y = this.mouseY = y; } } if (this.touch0 && this.touch1) { let dx = this.touch1.x - this.touch0.x; let dy = this.touch1.x - this.touch0.x; let distance = Math.sqrt(dx * dx + dy * dy); this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, distance, ev); }); } } if (this.autoPreventDefault) ev.preventDefault(); }; const touchEnd = (ev) => { this.isTouch = true; if (this.touch0) { var touches = ev.changedTouches; let rect = element.getBoundingClientRect(); for (var i = 0; i < touches.length; i++) { var nativeTouch = touches[i]; let x = nativeTouch.clientX - rect.left; let y = nativeTouch.clientY - rect.top; if (this.touch0.identifier === nativeTouch.identifier) { this.touch0 = null; this.mouseX = x; this.mouseY = y; this.listeners.map((listener) => { if (listener.up) listener.up(x, y, ev); }); if (!this.touch1) { this.buttonDown = false; break; } else { this.touch0 = this.touch1; this.touch1 = null; this.mouseX = this.touch0.x; this.mouseX = this.touch0.x; this.buttonDown = true; this.listeners.map((listener) => { if (listener.down) listener.down(this.touch0.x, this.touch0.y, ev); }); } } if (this.touch1 && this.touch1.identifier) { this.touch1 = null; } } } if (this.autoPreventDefault) ev.preventDefault(); }; element.addEventListener("mousedown", mouseDown, true); element.addEventListener("mousemove", mouseMove, true); element.addEventListener("mouseup", mouseUp, true); element.addEventListener("wheel", mouseWheel, true); element.addEventListener("touchstart", touchStart, { passive: false, capture: false }); element.addEventListener("touchmove", touchMove, { passive: false, capture: false }); element.addEventListener("touchend", touchEnd, { passive: false, capture: false }); element.addEventListener("touchcancel", touchEnd); return { mouseDown, mouseMove, mouseUp, mouseWheel, touchStart, touchMove, touchEnd, }; } dispose() { const element = this.element; element.removeEventListener("mousedown", this.callbacks.mouseDown, true); element.removeEventListener("mousemove", this.callbacks.mouseMove, true); element.removeEventListener("mouseup", this.callbacks.mouseUp, true); element.removeEventListener("wheel", this.callbacks.mouseWheel, true); element.removeEventListener("touchstart", this.callbacks.touchStart, { capture: false }); element.removeEventListener("touchmove", this.callbacks.touchMove, { capture: false }); element.removeEventListener("touchend", this.callbacks.touchEnd, { capture: false }); element.removeEventListener("touchcancel", this.callbacks.touchEnd); this.listeners.length = 0; } addListener(listener) { this.listeners.push(listener); } removeListener(listener) { let idx = this.listeners.indexOf(listener); if (idx > -1) { this.listeners.splice(idx, 1); } } } export class Touch { identifier; x; y; constructor(identifier, x, y) { this.identifier = identifier; this.x = x; this.y = y; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5wdXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvSW5wdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE1BQU0sT0FBTyxLQUFLO0lBQ2pCLE9BQU8sQ0FBYztJQUNyQixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ1gsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNYLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDbkIsTUFBTSxHQUFpQixJQUFJLENBQUM7SUFDNUIsTUFBTSxHQUFpQixJQUFJLENBQUM7SUFDNUIsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLFNBQVMsR0FBRyxJQUFJLEtBQUssRUFBaUIsQ0FBQztJQUN2QyxrQkFBa0IsQ0FBVTtJQUVwQyw2SEFBNkg7SUFDN0gsOEVBQThFO0lBQ3RFLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsU0FBUyxDQVFmO0lBRUYsWUFBYSxPQUFvQixFQUFFLGtCQUFrQixHQUFHLElBQUk7UUFDM0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDO1FBQzdDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRU8sY0FBYyxDQUFFLE9BQW9CO1FBQzNDLE1BQU0sU0FBUyxHQUFHLENBQUMsRUFBVyxFQUFFLEVBQUU7WUFDakMsSUFBSSxFQUFFLFlBQVksVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUMvQyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQkFDM0MsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxN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QVMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNyRixPQUFPLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRCxXQUFXLENBQUUsUUFBdUI7UUFDbkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELGNBQWMsQ0FBRSxRQUF1QjtRQUN0QyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzQyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDRixDQUFDO0NBQ0Q7QUFFRCxNQUFNLE9BQU8sS0FBSztJQUNHO0lBQTJCO0lBQWtCO0lBQWpFLFlBQW9CLFVBQWtCLEVBQVMsQ0FBUyxFQUFTLENBQVM7UUFBdEQsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUFTLE1BQUMsR0FBRCxDQUFDLENBQVE7UUFBUyxNQUFDLEdBQUQsQ0FBQyxDQUFRO0lBQzFFLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgRGlzcG9zYWJsZSB9IGZyb20gXCIuL2luZGV4LmpzXCJcbmV4cG9ydCBjbGFzcyBJbnB1dCBpbXBsZW1lbnRzIERpc3Bvc2FibGUge1xuXHRlbGVtZW50OiBIVE1MRWxlbWVudDtcblx0bW91c2VYID0gMDtcblx0bW91c2VZID0gMDtcblx0YnV0dG9uRG93biA9IGZhbHNlO1xuXHR0b3VjaDA6IFRvdWNoIHwgbnVsbCA9IG51bGw7XG5cdHRvdWNoMTogVG91Y2ggfCBudWxsID0gbnVsbDtcblx0aW5pdGlhbFBpbmNoRGlzdGFuY2UgPSAwO1xuXHRwcml2YXRlIGxpc3RlbmVycyA9IG5ldyBBcnJheTxJbnB1dExpc3RlbmVyPigpO1xuXHRwcml2YXRlIGF1dG9QcmV2ZW50RGVmYXVsdDogYm9vbGVhbjtcblxuXHQvLyB0aGlzIGlzIG5lZWRlZCBiZWNhdXNlIGJyb3dzZXJzIHNlbmRzIG1vdXNlZG93bi1tb3VzZW1vdmUtbW91c2VzdXAgYWZ0ZXIgYSB0b3VjaCBzZXF1ZW5jZSwgdW5sZXNzIHRvdWNoIGVuZCBwcmV2ZW50RGVmYXVsdFxuXHQvLyBidXQgcHJldmVudGluZyBkZWZhdWx0IHdpbGwgcmVzdWx0IGluIHByZXZlbnRpbmcgaW50ZXJhY3Rpb24gd2l0aCB0aGUgcGFnZS5cblx0cHJpdmF0ZSBpc1RvdWNoID0gZmFsc2U7XG5cblx0cHJpdmF0ZSBjYWxsYmFja3M6IHtcblx0XHRtb3VzZURvd246IChldjogVUlFdmVudCkgPT4gdm9pZDtcblx0XHRtb3VzZU1vdmU6IChldjogVUlFdmVudCkgPT4gdm9pZDtcblx0XHRtb3VzZVVwOiAoZXY6IFVJRXZlbnQpID0+IHZvaWQ7XG5cdFx0bW91c2VXaGVlbDogKGV2OiBXaGVlbEV2ZW50KSA9PiB2b2lkO1xuXHRcdHRvdWNoU3RhcnQ6IChldjogVG91Y2hFdmVudCkgPT4gdm9pZDtcblx0XHR0b3VjaE1vdmU6IChldjogVG91Y2hFdmVudCkgPT4gdm9pZDtcblx0XHR0b3VjaEVuZDogKGV2OiBUb3VjaEV2ZW50KSA9PiB2b2lkO1xuXHR9O1xuXG5cdGNvbnN0cnVjdG9yIChlbGVtZW50OiBIVE1MRWxlbWVudCwgYXV0b1ByZXZlbnREZWZhdWx0ID0gdHJ1ZSkge1xuXHRcdHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cdFx0dGhpcy5hdXRvUHJldmVudERlZmF1bHQgPSBhdXRvUHJldmVudERlZmF1bHQ7XG5cdFx0dGhpcy5jYWxsYmFja3MgPSB0aGlzLnNldHVwQ2FsbGJhY2tzKGVsZW1lbnQpO1xuXHR9XG5cblx0cHJpdmF0ZSBzZXR1cENhbGxiYWNrcyAoZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcblx0XHRjb25zdCBtb3VzZURvd24gPSAoZXY6IFVJRXZlbnQpID0+IHtcblx0XHRcdGlmIChldiBpbnN0YW5jZW9mIE1vdXNlRXZlbnQgJiYgIXRoaXMuaXNUb3VjaCkge1xuXHRcdFx0XHRsZXQgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0XHRcdHRoaXMubW91c2VYID0gZXYuY2xpZW50WCAtIHJlY3QubGVmdDtcblx0XHRcdFx0dGhpcy5tb3VzZVkgPSBldi5jbGllbnRZIC0gcmVjdC50b3A7XG5cdFx0XHRcdHRoaXMuYnV0dG9uRG93biA9IHRydWU7XG5cdFx0XHRcdHRoaXMubGlzdGVuZXJzLm1hcCgobGlzdGVuZXIpID0+IHsgaWYgKGxpc3RlbmVyLmRvd24pIGxpc3RlbmVyLmRvd24odGhpcy5tb3VzZVgsIHRoaXMubW91c2VZLCBldik7IH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNvbnN0IG1vdXNlTW92ZSA9IChldjogVUlFdmVudCkgPT4ge1xuXHRcdFx0aWYgKGV2IGluc3RhbmNlb2YgTW91c2VFdmVudCAmJiAhdGhpcy5pc1RvdWNoKSB7XG5cdFx0XHRcdGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRcdFx0dGhpcy5tb3VzZVggPSBldi5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuXHRcdFx0XHR0aGlzLm1vdXNlWSA9IGV2LmNsaWVudFkgLSByZWN0LnRvcDtcblxuXHRcdFx0XHR0aGlzLmxpc3RlbmVycy5tYXAoKGxpc3RlbmVyKSA9PiB7XG5cdFx0XHRcdFx0aWYgKHRoaXMuYnV0dG9uRG93bikge1xuXHRcdFx0XHRcdFx0aWYgKGxpc3RlbmVyLmRyYWdnZWQpIGxpc3RlbmVyLmRyYWdnZWQodGhpcy5tb3VzZVgsIHRoaXMubW91c2VZLCBldik7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGlmIChsaXN0ZW5lci5tb3ZlZCkgbGlzdGVuZXIubW92ZWQodGhpcy5tb3VzZVgsIHRoaXMubW91c2VZLCBldik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0Y29uc3QgbW91c2VVcCA9IChldjogVUlFdmVudCkgPT4ge1xuXHRcdFx0aWYgKGV2IGluc3RhbmNlb2YgTW91c2VFdmVudCAmJiAhdGhpcy5pc1RvdWNoKSB7XG5cdFx0XHRcdGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRcdFx0dGhpcy5tb3VzZVggPSBldi5jbGllbnRYIC0gcmVjdC5sZWZ0Oztcblx0XHRcdFx0dGhpcy5tb3VzZVkgPSBldi5jbGllbnRZIC0gcmVjdC50b3A7XG5cdFx0XHRcdHRoaXMuYnV0dG9uRG93biA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLmxpc3RlbmVycy5tYXAoKGxpc3RlbmVyKSA9PiB7IGlmIChsaXN0ZW5lci51cCkgbGlzdGVuZXIudXAodGhpcy5tb3VzZVgsIHRoaXMubW91c2VZLCBldik7IH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNvbnN0IG1vdXNlV2hlZWwgPSAoZXY6IFdoZWVsRXZlbnQpID0+IHtcblx0XHRcdGlmICh0aGlzLmF1dG9QcmV2ZW50RGVmYXVsdCkgZXYucHJldmVudERlZmF1bHQoKTtcblx0XHRcdGxldCBkZWx0YVkgPSBldi5kZWx0YVk7XG5cdFx0XHRpZiAoZXYuZGVsdGFNb2RlID09IFdoZWVsRXZlbnQuRE9NX0RFTFRBX0xJTkUpIGRlbHRhWSAqPSA4O1xuXHRcdFx0aWYgKGV2LmRlbHRhTW9kZSA9PSBXaGVlbEV2ZW50LkRPTV9ERUxUQV9QQUdFKSBkZWx0YVkgKj0gMjQ7XG5cdFx0XHR0aGlzLmxpc3RlbmVycy5tYXAoKGxpc3RlbmVyKSA9PiB7IGlmIChsaXN0ZW5lci53aGVlbCkgbGlzdGVuZXIud2hlZWwoZXYuZGVsdGFZLCBldik7IH0pO1xuXHRcdH07XG5cblx0XHRjb25zdCB0b3VjaFN0YXJ0ID0gKGV2OiBUb3VjaEV2ZW50KSA9PiB7XG5cdFx0XHR0aGlzLmlzVG91Y2ggPSB0cnVlO1xuXHRcdFx0aWYgKCF0aGlzLnRvdWNoMCB8fCAhdGhpcy50b3VjaDEpIHtcblx0XHRcdFx0dmFyIHRvdWNoZXMgPSBldi5jaGFuZ2VkVG91Y2hlcztcblx0XHRcdFx0bGV0IG5hdGl2ZVRvdWNoID0gdG91Y2hlcy5pdGVtKDApO1xuXHRcdFx0XHRpZiAoIW5hdGl2ZVRvdWNoKSByZXR1cm47XG5cdFx0XHRcdGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRcdFx0bGV0IHggPSBuYXRpdmVUb3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuXHRcdFx0XHRsZXQgeSA9IG5hdGl2ZVRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcblx0XHRcdFx0bGV0IHRvdWNoID0gbmV3IFRvdWNoKG5hdGl2ZVRvdWNoLmlkZW50aWZpZXIsIHgsIHkpO1xuXHRcdFx0XHR0aGlzLm1vdXNlWCA9IHg7XG5cdFx0XHRcdHRoaXMubW91c2VZID0geTtcblx0XHRcdFx0dGhpcy5idXR0b25Eb3duID0gdHJ1ZTtcblxuXHRcdFx0XHRpZiAoIXRoaXMudG91Y2gwKSB7XG5cdFx0XHRcdFx0dGhpcy50b3VjaDAgPSB0b3VjaDtcblx0XHRcdFx0XHR0aGlzLmxpc3RlbmVycy5tYXAoKGxpc3RlbmVyKSA9PiB7IGlmIChsaXN0ZW5lci5kb3duKSBsaXN0ZW5lci5kb3duKHRvdWNoLngsIHRvdWNoLnksIGV2KSB9KVxuXHRcdFx0XHR9IGVsc2UgaWYgKCF0aGlzLnRvdWNoMSkge1xuXHRcdFx0XHRcdHRoaXMudG91Y2gxID0gdG91Y2g7XG5cdFx0XHRcdFx0bGV0IGR4ID0gdGhpcy50b3VjaDEueCAtIHRoaXMudG91Y2gwLng7XG5cdFx0XHRcdFx0bGV0IGR5ID0gdGhpcy50b3VjaDEueCAtIHRoaXMudG91Y2gwLng7XG5cdFx0XHRcdFx0dGhpcy5pbml0aWFsUGluY2hEaXN0YW5jZSA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cdFx0XHRcdFx0dGhpcy5saXN0ZW5lcnMubWFwKChsaXN0ZW5lcikgPT4geyBpZiAobGlzdGVuZXIuem9vbSkgbGlzdGVuZXIuem9vbSh0aGlzLmluaXRpYWxQaW5jaERpc3RhbmNlLCB0aGlzLmluaXRpYWxQaW5jaERpc3RhbmNlLCBldikgfSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICh0aGlzLmF1dG9QcmV2ZW50RGVmYXVsdCkgZXYucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cblx0XHRjb25zdCB0b3VjaE1vdmUgPSAoZXY6IFRvdWNoRXZlbnQpID0+IHtcblx0XHRcdHRoaXMuaXNUb3VjaCA9IHRydWU7XG5cdFx0XHRpZiAodGhpcy50b3VjaDApIHtcblx0XHRcdFx0dmFyIHRvdWNoZXMgPSBldi5jaGFuZ2VkVG91Y2hlcztcblx0XHRcdFx0bGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHRvdWNoZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHR2YXIgbmF0aXZlVG91Y2ggPSB0b3VjaGVzW2ldO1xuXHRcdFx0XHRcdGxldCB4ID0gbmF0aXZlVG91Y2guY2xpZW50WCAtIHJlY3QubGVmdDtcblx0XHRcdFx0XHRsZXQgeSA9IG5hdGl2ZVRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcblxuXHRcdFx0XHRcdGlmICh0aGlzLnRvdWNoMC5pZGVudGlmaWVyID09PSBuYXRpdmVUb3VjaC5pZGVudGlmaWVyKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRvdWNoMC54ID0gdGhpcy5tb3VzZVggPSB4O1xuXHRcdFx0XHRcdFx0dGhpcy50b3VjaDAueSA9IHRoaXMubW91c2VZID0geTtcblx0XHRcdFx0XHRcdHRoaXMubGlzdGVuZXJzLm1hcCgobGlzdGVuZXIpID0+IHsgaWYgKGxpc3RlbmVyLmRyYWdnZWQpIGxpc3RlbmVyLmRyYWdnZWQoeCwgeSwgZXYpIH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAodGhpcy50b3VjaDEgJiYgdGhpcy50b3VjaDEuaWRlbnRpZmllciA9PT0gbmF0aXZlVG91Y2guaWRlbnRpZmllcikge1xuXHRcdFx0XHRcdFx0dGhpcy50b3VjaDEueCA9IHRoaXMubW91c2VYID0geDtcblx0XHRcdFx0XHRcdHRoaXMudG91Y2gxLnkgPSB0aGlzLm1vdXNlWSA9IHk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICh0aGlzLnRvdWNoMCAmJiB0aGlzLnRvdWNoMSkge1xuXHRcdFx0XHRcdGxldCBkeCA9IHRoaXMudG91Y2gxLnggLSB0aGlzLnRvdWNoMC54O1xuXHRcdFx0XHRcdGxldCBkeSA9IHRoaXMudG91Y2gxLnggLSB0aGlzLnRvdWNoMC54O1xuXHRcdFx0XHRcdGxldCBkaXN0YW5jZSA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cdFx0XHRcdFx0dGhpcy5saXN0ZW5lcnMubWFwKChsaXN0ZW5lcikgPT4geyBpZiAobGlzdGVuZXIuem9vbSkgbGlzdGVuZXIuem9vbSh0aGlzLmluaXRpYWxQaW5jaERpc3RhbmNlLCBkaXN0YW5jZSwgZXYpIH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5hdXRvUHJldmVudERlZmF1bHQpIGV2LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgdG91Y2hFbmQgPSAoZXY6IFRvdWNoRXZlbnQpID0+IHtcblx0XHRcdHRoaXMuaXNUb3VjaCA9IHRydWU7XG5cdFx0XHRpZiAodGhpcy50b3VjaDApIHtcblx0XHRcdFx0dmFyIHRvdWNoZXMgPSBldi5jaGFuZ2VkVG91Y2hlcztcblx0XHRcdFx0bGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG5cdFx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgdG91Y2hlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdHZhciBuYXRpdmVUb3VjaCA9IHRvdWNoZXNbaV07XG5cdFx0XHRcdFx0bGV0IHggPSBuYXRpdmVUb3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuXHRcdFx0XHRcdGxldCB5ID0gbmF0aXZlVG91Y2guY2xpZW50WSAtIHJlY3QudG9wO1xuXG5cdFx0XHRcdFx0aWYgKHRoaXMudG91Y2gwLmlkZW50aWZpZXIgPT09IG5hdGl2ZVRvdWNoLmlkZW50aWZpZXIpIHtcblx0XHRcdFx0XHRcdHRoaXMudG91Y2gwID0gbnVsbDtcblx0XHRcdFx0XHRcdHRoaXMubW91c2VYID0geDtcblx0XHRcdFx0XHRcdHRoaXMubW91c2VZID0geTtcblx0XHRcdFx0XHRcdHRoaXMubGlzdGVuZXJzLm1hcCgobGlzdGVuZXIpID0+IHsgaWYgKGxpc3RlbmVyLnVwKSBsaXN0ZW5lci51cCh4LCB5LCBldikgfSk7XG5cblx0XHRcdFx0XHRcdGlmICghdGhpcy50b3VjaDEpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5idXR0b25Eb3duID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0dGhpcy50b3VjaDAgPSB0aGlzLnRvdWNoMTtcblx0XHRcdFx0XHRcdFx0dGhpcy50b3VjaDEgPSBudWxsO1xuXHRcdFx0XHRcdFx0XHR0aGlzLm1vdXNlWCA9IHRoaXMudG91Y2gwLng7XG5cdFx0XHRcdFx0XHRcdHRoaXMubW91c2VYID0gdGhpcy50b3VjaDAueDtcblx0XHRcdFx0XHRcdFx0dGhpcy5idXR0b25Eb3duID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0dGhpcy5saXN0ZW5lcnMubWFwKChsaXN0ZW5lcikgPT4geyBpZiAobGlzdGVuZXIuZG93bikgbGlzdGVuZXIuZG93bih0aGlzLnRvdWNoMCEueCwgdGhpcy50b3VjaDAhLnksIGV2KSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAodGhpcy50b3VjaDEgJiYgdGhpcy50b3VjaDEuaWRlbnRpZmllcikge1xuXHRcdFx0XHRcdFx0dGhpcy50b3VjaDEgPSBudWxsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuYXV0b1ByZXZlbnREZWZhdWx0KSBldi5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdH07XG5cblx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgbW91c2VEb3duLCB0cnVlKTtcblx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgbW91c2VNb3ZlLCB0cnVlKTtcblx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIG1vdXNlVXAsIHRydWUpO1xuXHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIndoZWVsXCIsIG1vdXNlV2hlZWwsIHRydWUpO1xuXHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIiwgdG91Y2hTdGFydCwgeyBwYXNzaXZlOiBmYWxzZSwgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRvdWNoTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSwgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdG91Y2hFbmQsIHsgcGFzc2l2ZTogZmFsc2UsIGNhcHR1cmU6IGZhbHNlIH0pO1xuXHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRvdWNoRW5kKTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRtb3VzZURvd24sXG5cdFx0XHRtb3VzZU1vdmUsXG5cdFx0XHRtb3VzZVVwLFxuXHRcdFx0bW91c2VXaGVlbCxcblx0XHRcdHRvdWNoU3RhcnQsXG5cdFx0XHR0b3VjaE1vdmUsXG5cdFx0XHR0b3VjaEVuZCxcblx0XHR9XG5cdH1cblxuXHRkaXNwb3NlICgpOiB2b2lkIHtcblx0XHRjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLCB0aGlzLmNhbGxiYWNrcy5tb3VzZURvd24sIHRydWUpO1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLmNhbGxiYWNrcy5tb3VzZU1vdmUsIHRydWUpO1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcy5jYWxsYmFja3MubW91c2VVcCwgdHJ1ZSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwid2hlZWxcIiwgdGhpcy5jYWxsYmFja3MubW91c2VXaGVlbCwgdHJ1ZSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0aGlzLmNhbGxiYWNrcy50b3VjaFN0YXJ0LCB7IGNhcHR1cmU6IGZhbHNlIH0pO1xuXHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCB0aGlzLmNhbGxiYWNrcy50b3VjaE1vdmUsIHsgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5jYWxsYmFja3MudG91Y2hFbmQsIHsgY2FwdHVyZTogZmFsc2UgfSk7XG5cdFx0ZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIiwgdGhpcy5jYWxsYmFja3MudG91Y2hFbmQpO1xuXHRcdHRoaXMubGlzdGVuZXJzLmxlbmd0aCA9IDA7XG5cdH1cblxuXHRhZGRMaXN0ZW5lciAobGlzdGVuZXI6IElucHV0TGlzdGVuZXIpIHtcblx0XHR0aGlzLmxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcblx0fVxuXG5cdHJlbW92ZUxpc3RlbmVyIChsaXN0ZW5lcjogSW5wdXRMaXN0ZW5lcikge1xuXHRcdGxldCBpZHggPSB0aGlzLmxpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKTtcblx0XHRpZiAoaWR4ID4gLTEpIHtcblx0XHRcdHRoaXMubGlzdGVuZXJzLnNwbGljZShpZHgsIDEpO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgVG91Y2gge1xuXHRjb25zdHJ1Y3RvciAocHVibGljIGlkZW50aWZpZXI6IG51bWJlciwgcHVibGljIHg6IG51bWJlciwgcHVibGljIHk6IG51bWJlcikge1xuXHR9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXRMaXN0ZW5lciB7XG5cdGRvd24/KHg6IG51bWJlciwgeTogbnVtYmVyLCBldj86IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogdm9pZDtcblx0dXA/KHg6IG51bWJlciwgeTogbnVtYmVyLCBldj86IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogdm9pZDtcblx0bW92ZWQ/KHg6IG51bWJlciwgeTogbnVtYmVyLCBldj86IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogdm9pZDtcblx0ZHJhZ2dlZD8oeDogbnVtYmVyLCB5OiBudW1iZXIsIGV2PzogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiB2b2lkO1xuXHR3aGVlbD8oZGVsdGE6IG51bWJlciwgZXY/OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IHZvaWQ7XG5cdHpvb20/KGluaXRpYWxEaXN0YW5jZTogbnVtYmVyLCBkaXN0YW5jZTogbnVtYmVyLCBldj86IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogdm9pZDtcbn1cbiJdfQ==