webglimpse
Version:
Webglimpse is a data visualization library for the web.
131 lines • 17.6 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 { GL, getObjectId, hasval } from './util/util';
export function newStaticBuffer(data) {
return new StaticBufferImpl(data);
}
export function newDynamicBuffer(data = new Float32Array(0)) {
return new DynamicBufferImpl(data);
}
class BufferEntry {
constructor(gl, buffer) {
this.capacity = 0;
this.marker = null;
this.gl = gl;
this.buffer = buffer;
}
}
class AbstractBuffer {
constructor() {
this.buffers = {};
this.currentMarker = 0;
}
init(gl, target) {
throw new Error('Method is abstract');
}
update(gl, target, capacity) {
throw new Error('Method is abstract');
}
setDirty() {
this.currentMarker++;
}
bind(gl, target) {
const glId = getObjectId(gl);
if (this.buffers[glId] === undefined) {
const buffer = gl.createBuffer();
if (!hasval(buffer)) {
throw new Error('Failed to create buffer');
}
this.buffers[glId] = new BufferEntry(gl, buffer);
gl.bindBuffer(target, this.buffers[glId].buffer);
this.buffers[glId].capacity = this.init(gl, target);
this.buffers[glId].marker = this.currentMarker;
}
else if (this.buffers[glId].marker !== this.currentMarker) {
gl.bindBuffer(target, this.buffers[glId].buffer);
this.buffers[glId].capacity = this.update(gl, target, this.buffers[glId].capacity);
this.buffers[glId].marker = this.currentMarker;
}
else {
gl.bindBuffer(target, this.buffers[glId].buffer);
}
}
unbind(gl, target) {
gl.bindBuffer(target, null);
}
dispose() {
// XXX: Not sure this actually works ... may have to make each gl current or something
for (const glid in this.buffers) {
if (this.buffers.hasOwnProperty(glid)) {
const en = this.buffers[glid];
en.gl.deleteBuffer(en.buffer);
}
}
this.buffers = {};
}
}
class StaticBufferImpl extends AbstractBuffer {
constructor(data) {
super();
this._data = data;
}
init(gl, target) {
gl.bufferData(target, this._data, GL.STATIC_DRAW);
return this._data.byteLength;
}
update(gl, target, capacity) {
throw new Error('This buffer is static and should never need to be updated');
}
}
class DynamicBufferImpl extends AbstractBuffer {
constructor(data) {
super();
this._data = data;
}
setData(data) {
this._data = data;
this.setDirty();
}
init(gl, target) {
gl.bufferData(target, this._data, GL.DYNAMIC_DRAW);
return this._data.byteLength;
}
update(gl, target, capacity) {
if (this._data.byteLength <= capacity) {
gl.bufferSubData(target, 0, this._data);
return capacity;
}
else {
gl.bufferData(target, this._data, GL.DYNAMIC_DRAW);
return this._data.byteLength;
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVmZmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3dlYmdsaW1wc2UvYnVmZmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNEJHO0FBQ0gsT0FBTyxFQUFhLEVBQUUsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBWWpFLE1BQU0sVUFBVSxlQUFlLENBQUMsSUFBa0I7SUFDOUMsT0FBTyxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsT0FBcUIsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN2QyxDQUFDO0FBR0QsTUFBTSxXQUFXO0lBTWIsWUFBWSxFQUF5QixFQUFFLE1BQW1CO1FBSDFELGFBQVEsR0FBRyxDQUFDLENBQUM7UUFDYixXQUFNLEdBQVcsSUFBSSxDQUFDO1FBR2xCLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ2IsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDekIsQ0FBQztDQUNKO0FBRUQsTUFBTSxjQUFjO0lBQXBCO1FBQ1ksWUFBTyxHQUEyQixFQUFFLENBQUM7UUFDckMsa0JBQWEsR0FBRyxDQUFDLENBQUM7SUFtRDlCLENBQUM7SUFqREcsSUFBSSxDQUFDLEVBQXlCLEVBQUUsTUFBYztRQUMxQyxNQUFNLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELE1BQU0sQ0FBQyxFQUF5QixFQUFFLE1BQWMsRUFBRSxRQUFnQjtRQUM5RCxNQUFNLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsYUFBYSxFQUFFLENB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QixFQUFFLE1BQWMsRUFBRSxRQUFnQjtRQUM5RCxNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDakYsQ0FBQztDQUNKO0FBR0QsTUFBTSxpQkFBa0IsU0FBUSxjQUFjO0lBRzFDLFlBQVksSUFBa0I7UUFDMUIsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztJQUN0QixDQUFDO0lBRUQsT0FBTyxDQUFDLElBQWtCO1FBQ3RCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQsSUFBSSxDQUFDLEVBQXlCLEVBQUUsTUFBYztRQUMxQyxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNuRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO0lBQ2pDLENBQUM7SUFFRCxNQUFNLENBQUMsRUFBeUIsRUFBRSxNQUFjLEVBQUUsUUFBZ0I7UUFDOUQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsSUFBSSxRQUFRLEVBQUU7WUFDbkMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN4QyxPQUFPLFFBQVEsQ0FBQztTQUNuQjthQUNJO1lBQ0QsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDbkQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztTQUNoQztJQUNMLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIENvcHlyaWdodCAoYykgMjAxNCwgTWV0cm9uLCBJbmMuXHJcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXHJcbiAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcclxuICpcclxuICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXHJcbiAqICAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxyXG4gKlxyXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXHJcbiAqICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cclxuICogICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXHJcbiAqXHJcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXHJcbiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XHJcbiAqICAgIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cclxuICpcclxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCIgQU5EXHJcbiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXHJcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcclxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1JcclxuICogQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXHJcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcclxuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OXHJcbiAqIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXHJcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTXHJcbiAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxyXG4gKi9cclxuaW1wb3J0IHsgU3RyaW5nTWFwLCBHTCwgZ2V0T2JqZWN0SWQsIGhhc3ZhbCB9IGZyb20gJy4vdXRpbC91dGlsJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQnVmZmVyIHtcclxuICAgIGJpbmQoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdGFyZ2V0OiBudW1iZXIpOiB2b2lkO1xyXG4gICAgdW5iaW5kKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIHRhcmdldDogbnVtYmVyKTogdm9pZDtcclxuICAgIGRpc3Bvc2UoKTogdm9pZDtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljQnVmZmVyIGV4dGVuZHMgQnVmZmVyIHtcclxuICAgIHNldERhdGEobmV3RGF0YTogRmxvYXQzMkFycmF5KTogdm9pZDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1N0YXRpY0J1ZmZlcihkYXRhOiBGbG9hdDMyQXJyYXkpOiBCdWZmZXIge1xyXG4gICAgcmV0dXJuIG5ldyBTdGF0aWNCdWZmZXJJbXBsKGRhdGEpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3RHluYW1pY0J1ZmZlcihkYXRhOiBGbG9hdDMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KDApKTogRHluYW1pY0J1ZmZlciB7XHJcbiAgICByZXR1cm4gbmV3IER5bmFtaWNCdWZmZXJJbXBsKGRhdGEpO1xyXG59XHJcblxyXG5cclxuY2xhc3MgQnVmZmVyRW50cnkge1xyXG4gICAgZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcclxuICAgIGJ1ZmZlcjogV2ViR0xCdWZmZXI7XHJcbiAgICBjYXBhY2l0eSA9IDA7XHJcbiAgICBtYXJrZXI6IG51bWJlciA9IG51bGw7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgYnVmZmVyOiBXZWJHTEJ1ZmZlcikge1xyXG4gICAgICAgIHRoaXMuZ2wgPSBnbDtcclxuICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcclxuICAgIH1cclxufVxyXG5cclxuY2xhc3MgQWJzdHJhY3RCdWZmZXIgaW1wbGVtZW50cyBCdWZmZXIge1xyXG4gICAgcHJpdmF0ZSBidWZmZXJzOiBTdHJpbmdNYXA8QnVmZmVyRW50cnk+ID0ge307XHJcbiAgICBwcml2YXRlIGN1cnJlbnRNYXJrZXIgPSAwO1xyXG5cclxuICAgIGluaXQoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdGFyZ2V0OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIGlzIGFic3RyYWN0Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIHRhcmdldDogbnVtYmVyLCBjYXBhY2l0eTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBpcyBhYnN0cmFjdCcpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldERpcnR5KCkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudE1hcmtlcisrO1xyXG4gICAgfVxyXG5cclxuICAgIGJpbmQoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdGFyZ2V0OiBudW1iZXIpIHtcclxuICAgICAgICBjb25zdCBnbElkID0gZ2V0T2JqZWN0SWQoZ2wpO1xyXG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlcnNbZ2xJZF0gPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTtcclxuICAgICAgICAgICAgaWYgKCFoYXN2YWwoYnVmZmVyKSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gY3JlYXRlIGJ1ZmZlcicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyc1tnbElkXSA9IG5ldyBCdWZmZXJFbnRyeShnbCwgYnVmZmVyKTtcclxuXHJcbiAgICAgICAgICAgIGdsLmJpbmRCdWZmZXIodGFyZ2V0LCB0aGlzLmJ1ZmZlcnNbZ2xJZF0uYnVmZmVyKTtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXJzW2dsSWRdLmNhcGFjaXR5ID0gdGhpcy5pbml0KGdsLCB0YXJnZXQpO1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlcnNbZ2xJZF0ubWFya2VyID0gdGhpcy5jdXJyZW50TWFya2VyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLmJ1ZmZlcnNbZ2xJZF0ubWFya2VyICE9PSB0aGlzLmN1cnJlbnRNYXJrZXIpIHtcclxuICAgICAgICAgICAgZ2wuYmluZEJ1ZmZlcih0YXJnZXQsIHRoaXMuYnVmZmVyc1tnbElkXS5idWZmZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlcnNbZ2xJZF0uY2FwYWNpdHkgPSB0aGlzLnVwZGF0ZShnbCwgdGFyZ2V0LCB0aGlzLmJ1ZmZlcnNbZ2xJZF0uY2FwYWNpdHkpO1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlcnNbZ2xJZF0ubWFya2VyID0gdGhpcy5jdXJyZW50TWFya2VyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZ2wuYmluZEJ1ZmZlcih0YXJnZXQsIHRoaXMuYnVmZmVyc1tnbElkXS5idWZmZXIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB1bmJpbmQoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdGFyZ2V0OiBudW1iZXIpIHtcclxuICAgICAgICBnbC5iaW5kQnVmZmVyKHRhcmdldCwgbnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgZGlzcG9zZSgpIHtcclxuICAgICAgICAvLyBYWFg6IE5vdCBzdXJlIHRoaXMgYWN0dWFsbHkgd29ya3MgLi4uIG1heSBoYXZlIHRvIG1ha2UgZWFjaCBnbCBjdXJyZW50IG9yIHNvbWV0aGluZ1xyXG4gICAgICAgIGZvciAoY29uc3QgZ2xpZCBpbiB0aGlzLmJ1ZmZlcnMpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYnVmZmVycy5oYXNPd25Qcm9wZXJ0eShnbGlkKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZW4gPSB0aGlzLmJ1ZmZlcnNbZ2xpZF07XHJcbiAgICAgICAgICAgICAgICBlbi5nbC5kZWxldGVCdWZmZXIoZW4uYnVmZmVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmJ1ZmZlcnMgPSB7fTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmNsYXNzIFN0YXRpY0J1ZmZlckltcGwgZXh0ZW5kcyBBYnN0cmFjdEJ1ZmZlciB7XHJcbiAgICBwcml2YXRlIF9kYXRhOiBGbG9hdDMyQXJyYXk7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZGF0YTogRmxvYXQzMkFycmF5KSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLl9kYXRhID0gZGF0YTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0KGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIHRhcmdldDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICBnbC5idWZmZXJEYXRhKHRhcmdldCwgdGhpcy5fZGF0YSwgR0wuU1RBVElDX0RSQVcpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhLmJ5dGVMZW5ndGg7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIHRhcmdldDogbnVtYmVyLCBjYXBhY2l0eTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoaXMgYnVmZmVyIGlzIHN0YXRpYyBhbmQgc2hvdWxkIG5ldmVyIG5lZWQgdG8gYmUgdXBkYXRlZCcpO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuY2xhc3MgRHluYW1pY0J1ZmZlckltcGwgZXh0ZW5kcyBBYnN0cmFjdEJ1ZmZlciBpbXBsZW1lbnRzIER5bmFtaWNCdWZmZXIge1xyXG4gICAgcHJpdmF0ZSBfZGF0YTogRmxvYXQzMkFycmF5O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGRhdGE6IEZsb2F0MzJBcnJheSkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0RGF0YShkYXRhOiBGbG9hdDMyQXJyYXkpIHtcclxuICAgICAgICB0aGlzLl9kYXRhID0gZGF0YTtcclxuICAgICAgICB0aGlzLnNldERpcnR5KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdChnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCB0YXJnZXQ6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgZ2wuYnVmZmVyRGF0YSh0YXJnZXQsIHRoaXMuX2RhdGEsIEdMLkRZTkFNSUNfRFJBVyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGEuYnl0ZUxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGUoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdGFyZ2V0OiBudW1iZXIsIGNhcGFjaXR5OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIGlmICh0aGlzLl9kYXRhLmJ5dGVMZW5ndGggPD0gY2FwYWNpdHkpIHtcclxuICAgICAgICAgICAgZ2wuYnVmZmVyU3ViRGF0YSh0YXJnZXQsIDAsIHRoaXMuX2RhdGEpO1xyXG4gICAgICAgICAgICByZXR1cm4gY2FwYWNpdHk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBnbC5idWZmZXJEYXRhKHRhcmdldCwgdGhpcy5fZGF0YSwgR0wuRFlOQU1JQ19EUkFXKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGEuYnl0ZUxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG4iXX0=