@zeainc/zea-potree
Version:
Zea Potree is a plug-in for Zea Engine that enables rendering of large point clouds .
1 lines • 98.4 kB
JavaScript
import{Box3 as i,Points as t,Vec3Attribute as l,ColorAttribute as e,Vec3 as n,AssetItem as d,NumberParameter as s,Registry as c,GLPass as F,GLPoints as o,generateShaderGeomBinding as U,GLShader as X,shaderLibrary as R,GLTexture2D as Q,GLRenderTarget as x,GLMesh as a,Plane as B,Frustum as V,libsRegistry as r}from"@zeainc/zea-engine";var u={name:"@zeainc/zea-potree",filename:"zea-potree",library:"ZeaPotree",private:!1,version:"5.0.0",description:"Zea Potree is a plug-in for Zea Engine that enables rendering of large point clouds .",main:"dist/index.cjs.js",module:"dist/index.esm.js",browser:"dist/index.umd.js",files:["dist/"],keywords:["Zea","Potree","Point clouds"],scripts:{build:"rollup -c","build:watch":"rollup -w -c",dev:"npm-run-all --parallel build:watch start:watch",prepare:"yarn build",start:"es-dev-server","start:watch":"es-dev-server --app-index testing-e2e/index.html --open --watch",dist:"yarn publish --access=public",docs:"adg --config adg.config.json","docs-w":"adg -w --config=adg.config.json","testing-server":"node testing-server/index.js",test:"karma start --single-run --browsers ChromeHeadless karma.conf.js",testBrowser:"karma start --single-run karma.conf.js",release:"standard-version"},dependencies:{"@rollup/plugin-json":"^4.1.0",binaryheap:"^0.0.3",gulp:"^4.0.2","gulp-concat":"^2.6.1","gulp-connect":"^5.7.0","gulp-util":"^3.0.8",through:"~2.3.4",webpack:"^4.41.2","worker-loader":"^2.0.0"},author:"Philip Taylor",license:"MIT",devDependencies:{"@zeainc/jsdocs2md":"^0.0.7","@zeainc/zea-engine":"^4.15.0","docsify-cli":"^4.4.1","es-dev-server":"^2.1.0",eslint:"^7.7.0","eslint-config-google":"^0.14.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","npm-run-all":"^4.1.5",prettier:"^2.0.5",rollup:"^2.10.9","rollup-plugin-terser":"^6.1.0","rollup-plugin-web-worker-loader":"^1.3.0","standard-version":"^9.0.0","webpack-cli":"^3.3.9"},"standard-version":{skip:{commit:!0}}};const b={POSITION_CARTESIAN:0,COLOR_PACKED:1,COLOR_FLOATS_1:2,COLOR_FLOATS_255:3,NORMAL_FLOATS:4,FILLER:5,INTENSITY:6,CLASSIFICATION:7,NORMAL_SPHEREMAPPED:8,NORMAL_OCT16:9,NORMAL:10,RETURN_NUMBER:11,NUMBER_OF_RETURNS:12,SOURCE_ID:13,INDICES:14,SPACING:15,GPS_TIME:16},h={DATA_TYPE_DOUBLE:{ordinal:0,size:8},DATA_TYPE_FLOAT:{ordinal:1,size:4},DATA_TYPE_INT8:{ordinal:2,size:1},DATA_TYPE_UINT8:{ordinal:3,size:1},DATA_TYPE_INT16:{ordinal:4,size:2},DATA_TYPE_UINT16:{ordinal:5,size:2},DATA_TYPE_INT32:{ordinal:6,size:4},DATA_TYPE_UINT32:{ordinal:7,size:4},DATA_TYPE_INT64:{ordinal:8,size:8},DATA_TYPE_UINT64:{ordinal:9,size:8}};let m=0;for(let i in h)h[m]=h[i],m++;class H{constructor(i,t,l){this.name=i,this.type=t,this.numElements=l,this.byteSize=this.numElements*this.type.size}}H.POSITION_CARTESIAN=new H(b.POSITION_CARTESIAN,h.DATA_TYPE_FLOAT,3),H.RGBA_PACKED=new H(b.COLOR_PACKED,h.DATA_TYPE_INT8,4),H.COLOR_PACKED=H.RGBA_PACKED,H.RGB_PACKED=new H(b.COLOR_PACKED,h.DATA_TYPE_INT8,3),H.NORMAL_FLOATS=new H(b.NORMAL_FLOATS,h.DATA_TYPE_FLOAT,3),H.FILLER_1B=new H(b.FILLER,h.DATA_TYPE_UINT8,1),H.INTENSITY=new H(b.INTENSITY,h.DATA_TYPE_UINT16,1),H.CLASSIFICATION=new H(b.CLASSIFICATION,h.DATA_TYPE_UINT8,1),H.NORMAL_SPHEREMAPPED=new H(b.NORMAL_SPHEREMAPPED,h.DATA_TYPE_UINT8,2),H.NORMAL_OCT16=new H(b.NORMAL_OCT16,h.DATA_TYPE_UINT8,2),H.NORMAL=new H(b.NORMAL,h.DATA_TYPE_FLOAT,3),H.RETURN_NUMBER=new H(b.RETURN_NUMBER,h.DATA_TYPE_UINT8,1),H.NUMBER_OF_RETURNS=new H(b.NUMBER_OF_RETURNS,h.DATA_TYPE_UINT8,1),H.SOURCE_ID=new H(b.SOURCE_ID,h.DATA_TYPE_UINT16,1),H.INDICES=new H(b.INDICES,h.DATA_TYPE_UINT32,1),H.SPACING=new H(b.SPACING,h.DATA_TYPE_FLOAT,1),H.GPS_TIME=new H(b.GPS_TIME,h.DATA_TYPE_DOUBLE,1);class g{constructor(i){if(this.attributes=[],this.byteSize=0,this.size=0,null!=i)for(let t=0;t<i.length;t++){let l=i[t],e=H[l];this.attributes.push(e),this.byteSize+=e.byteSize,this.size++}}add(i){this.attributes.push(i),this.byteSize+=i.byteSize,this.size++}hasColors(){for(let i in this.attributes){if(this.attributes[i].name===b.COLOR_PACKED)return!0}return!1}hasNormals(){for(let i in this.attributes){let t=this.attributes[i];if(t===H.NORMAL_SPHEREMAPPED||t===H.NORMAL_FLOATS||t===H.NORMAL||t===H.NORMAL_OCT16)return!0}return!1}}const S={config:{withCredentials:!1,customHeaders:[{header:null,value:null}]},createXMLHttpRequest:function(){let i=new XMLHttpRequest;if(this.config.customHeaders&&Array.isArray(this.config.customHeaders)&&this.config.customHeaders.length>0){let t=i.open,l=this.config.customHeaders;i.open=function(){t.apply(this,[].slice.call(arguments)),l.forEach((function(t){t.header&&t.value&&i.setRequestHeader(t.header,t.value)}))}}return i}};class y{static createWorker(i){let t=new Blob([i],{type:"application/javascript"});return new Worker(URL.createObjectURL(t))}static createChildAABB(t,l){let e=t.min.clone(),n=t.max.clone(),d=n.subtract(e);return(1&l)>0?e.z+=d.z/2:n.z-=d.z/2,(2&l)>0?e.y+=d.y/2:n.y-=d.y/2,(4&l)>0?e.x+=d.x/2:n.x-=d.x/2,new i(e,n)}}class Z{constructor(){this.url=null,this.octreeDir=null,this.spacing=0,this.boundingBox=null,this.root=null,this.nodes=null,this.pointAttributes=null,this.hierarchyStepSize=-1,this.loader=null}}class E extends class extends class{constructor(){this._listeners={}}addEventListener(i,t){const l=this._listeners;void 0===l[i]&&(l[i]=[]),-1===l[i].indexOf(t)&&l[i].push(t)}hasEventListener(i,t){const l=this._listeners;return void 0!==l[i]&&-1!==l[i].indexOf(t)}removeEventListener(i,t){let l=this._listeners[i];if(void 0!==l){let i=l.indexOf(t);-1!==i&&l.splice(i,1)}}removeEventListeners(i){void 0!==this._listeners[i]&&delete this._listeners[i]}dispatchEvent(i){let t=this._listeners[i.type];if(void 0!==t){i.target=this;for(let l of t.slice(0))l.call(this,i)}}}{constructor(){super()}getChildren(){throw new Error("override function")}getBoundingBox(){throw new Error("override function")}isLoaded(){throw new Error("override function")}isGeometryNode(){throw new Error("override function")}isTreeNode(){throw new Error("override function")}getLevel(){throw new Error("override function")}getBoundingSphere(){throw new Error("override function")}}{constructor(i,t,l){super(),this.id=E.IDCount++,this.name=i,this.index=parseInt(i.charAt(i.length-1)),this.pcoGeometry=t,this.geometry=null,this.boundingBox=l,this.boundingSphere=l.getBoundingSphere(),this.children={},this.numPoints=0,this.level=null,this.loaded=!1,this.oneTimeDisposeHandlers=[],this.offset=this.boundingBox.min.clone()}getLevel(){return this.level}isLoaded(){return this.loaded}getBoundingSphere(){return this.boundingSphere}getBoundingBox(){return this.boundingBox}getChildren(){let i=[];for(let t=0;t<8;t++)this.children[t]&&i.push(this.children[t]);return i}getURL(){let i="",t=this.pcoGeometry.loader.version;return t.equalOrHigher("1.5")?i=this.pcoGeometry.octreeDir+"/"+this.getHierarchyPath()+"/"+this.name:(t.equalOrHigher("1.4")||t.upTo("1.3"))&&(i=this.pcoGeometry.octreeDir+"/"+this.name),i}getHierarchyPath(){let i="r/",t=this.pcoGeometry.hierarchyStepSize,l=this.name.substr(1),e=Math.floor(l.length/t);for(let n=0;n<e;n++)i+=l.substr(n*t,t)+"/";return i=i.slice(0,-1),i}addChild(i){this.children[i.index]=i,i.parent=this}shouldLoad(){return!0!==this.loading&&!0!==this.loaded}load(){return this.loading=!0,this.loadPromise||(this.loadPromise=new Promise((i,t)=>{this.pcoGeometry.loader.version.equalOrHigher("1.5")&&this.level%this.pcoGeometry.hierarchyStepSize==0&&this.hasChildren?this.loadHierachyThenPoints().then(i):this.loadPoints().then(i)})),this.loadPromise}loadPoints(){return this.pcoGeometry.loader.load(this)}parse(d,s){const c=d.attributeBuffers,F=new t;for(let i in c){const t=c[i].buffer,n=parseInt(i);if(n===b.POSITION_CARTESIAN){const i=new l;i.data=new Float32Array(t),F.setNumVertices(i.getCount()),F.addVertexAttribute("positions",i)}else if(n===b.COLOR_PACKED){const i=new e;i.dataTypeName="RGBA",i.data=new Uint8Array(t),F.addVertexAttribute("colors",i)}else if(n===b.INDICES);else{let i;for(let t in b)if(b[t]==n){i=t;break}console.warn("Unandled Point Attribute:",i)}}this.points=F;const o=new i(new n(...d.tightBoundingBox.min),new n(...d.tightBoundingBox.max));o.max.subtract(o.min),o.min.set(0,0,0);let U=this.pcoGeometry.pointAttributes;const X=d.buffer.byteLength/U.byteSize;this.numPoints=X,this.mean=new n(...d.mean),this.tightBoundingBox=o,this.loaded=!0,this.loading=!1,this.estimatedSpacing=d.estimatedSpacing,this.dispatchEvent("loaded",{numPoints:X})}loadHierachyThenPoints(){return new Promise((i,t)=>{let l=this;if(l.level%l.pcoGeometry.hierarchyStepSize==0){let e=l.pcoGeometry.octreeDir+"/"+l.getHierarchyPath()+"/"+l.name+".hrc",n=S.createXMLHttpRequest();n.open("GET",e,!0),n.responseType="arraybuffer",n.overrideMimeType("text/plain; charset=x-user-defined"),n.onreadystatechange=()=>{if(4===n.readyState)if(200===n.status||0===n.status){let t=n.response;!function(t,l){let e=new DataView(l),n=[],d=e.getUint8(0),s=e.getUint32(1,!0);t.numPoints=s,n.push({children:d,numPoints:s,name:t.name});let c=[],F=5;for(;n.length>0;){let i=n.shift(),t=1;for(let l=0;l<8;l++){if(0!=(i.children&t)){let t=i.name+l,d=e.getUint8(F),s=e.getUint32(F+1,!0);n.push({children:d,numPoints:s,name:t}),c.push({children:d,numPoints:s,name:t}),F+=5}t*=2}if(F===l.byteLength)break}let o={};o[t.name]=t;let U=t.pcoGeometry;for(let i=0;i<c.length;i++){let t=c[i].name,l=c[i].numPoints,e=parseInt(t.charAt(t.length-1)),n=o[t.substring(0,t.length-1)],d=t.length-1,s=y.createChildAABB(n.boundingBox,e),F=new E(t,U,s);F.level=d,F.numPoints=l,F.hasChildren=c[i].children>0,F.spacing=U.spacing/Math.pow(2,d),n.addChild(F),o[t]=F}t.loadPoints().then(()=>{i()})}(l,t)}else{const i="Failed to load file! HTTP status: "+n.status+", file: "+e;console.log(i),t(i)}};try{n.send(null)}catch(i){console.log("fehler beim laden der punktwolke: "+i),t("fehler beim laden der punktwolke: "+i)}}})}getNumPoints(){return this.numPoints}dispose(){if(this.geometry&&null!=this.parent){this.geometry.dispose(),this.geometry=null,this.loaded=!1,this.loadPromise=null;for(let i=0;i<this.oneTimeDisposeHandlers.length;i++){(0,this.oneTimeDisposeHandlers[i])()}this.oneTimeDisposeHandlers=[]}}}E.IDCount=0;class p{constructor(i){this.version=i;let t=-1===i.indexOf(".")?i.length:i.indexOf(".");this.versionMajor=parseInt(i.substr(0,t)),this.versionMinor=parseInt(i.substr(t+1)),0===this.versionMinor.length&&(this.versionMinor=0)}newerThan(i){let t=new p(i);return this.versionMajor>t.versionMajor||this.versionMajor===t.versionMajor&&this.versionMinor>t.versionMinor}equalOrHigher(i){let t=new p(i);return this.versionMajor>t.versionMajor||this.versionMajor===t.versionMajor&&this.versionMinor>=t.versionMinor}upTo(i){return!this.newerThan(i)}}class G{constructor(i){this.version="string"==typeof i?new p(i):i}static progressCB(){}load(i){if(i.loaded)return;let t=i.pcoGeometry.pointAttributes,l=i.getURL();this.version.equalOrHigher("1.4")&&(l+="."+t.toLowerCase());let e=S.createXMLHttpRequest();e.open("GET",l,!0),e.responseType="arraybuffer",e.overrideMimeType("text/plain; charset=x-user-defined"),e.onreadystatechange=()=>{if(4===e.readyState)if(200===e.status||0===e.status){let t=e.response;this.parse(i,t)}else console.log("Failed to load file! HTTP status: "+e.status+", file: "+l)},e.send(null)}parse(i,t){let l=new LASFile(t),e=new L(i);l.open().then(i=>(l.isOpen=!0,l)).catch(i=>{console.log("failed to open file. :(")}).then(i=>i.getHeader().then((function(t){return[i,t]}))).then(i=>{let t=i[0],l=i[1],n=0,d=l.pointsCount,s=function(){return t.readData(1e6,0,1).then((function(i){return e.push(new LASDecoder(i.buffer,l.pointsFormatId,l.pointsStructSize,i.count,l.scale,l.offset,l.mins,l.maxs)),n+=i.count,G.progressCB(n/d),i.hasMoreData?s():(l.totalRead=n,l.versionAsString=t.versionAsString,l.isCompressed=t.isCompressed,[t,l,e])}))};return s()}).then(i=>{let t=i[0];return G.progressCB(1),t.close().then((function(){return t.isOpen=!1,i.slice(1)})).catch(i=>{if(t.isOpen)return t.close().then((function(){throw t.isOpen=!1,i}));throw i})})}handle(i,t){}}class L{constructor(i){this.node=i}push(i){let t=Potree.scriptPath+"/workers/LASDecoderWorker.js",l=Potree.workerPool.getWorker(t);this.node;l.onmessage=e=>{let n=new THREE.BufferGeometry,d=i.pointsCount,s=new Float32Array(e.data.position),c=new Uint8Array(e.data.color),F=new Float32Array(e.data.intensity),o=new Uint8Array(e.data.classification),U=new Uint8Array(e.data.returnNumber),X=new Uint8Array(e.data.numberOfReturns),R=new Uint16Array(e.data.pointSourceID),Q=new Uint8Array(e.data.indices);n.addAttribute("position",new THREE.BufferAttribute(s,3)),n.addAttribute("color",new THREE.BufferAttribute(c,4,!0)),n.addAttribute("intensity",new THREE.BufferAttribute(F,1)),n.addAttribute("classification",new THREE.BufferAttribute(o,1)),n.addAttribute("returnNumber",new THREE.BufferAttribute(U,1)),n.addAttribute("numberOfReturns",new THREE.BufferAttribute(X,1)),n.addAttribute("pointSourceID",new THREE.BufferAttribute(R,1)),n.addAttribute("indices",new THREE.BufferAttribute(Q,4)),n.attributes.indices.normalized=!0;let x=new THREE.Box3((new THREE.Vector3).fromArray(e.data.tightBoundingBox.min),(new THREE.Vector3).fromArray(e.data.tightBoundingBox.max));n.boundingBox=this.node.boundingBox,this.node.tightBoundingBox=x,this.node.geometry=n,this.node.numPoints=d,this.node.loaded=!0,this.node.loading=!1,Potree.numNodesLoading--,this.node.mean=new THREE.Vector3(...e.data.mean),Potree.workerPool.returnWorker(t,l)};let e={buffer:i.arrayb,numPoints:i.pointsCount,pointSize:i.pointSize,pointFormatID:2,scale:i.scale,offset:i.offset,mins:i.mins,maxs:i.maxs};l.postMessage(e,[e.buffer])}}const I=new class{constructor(){this.workers={}}getWorker(i){if(this.workers[i]||(this.workers[i]=[]),0===this.workers[i].length){let t=new i;this.workers[i].push(t)}return this.workers[i].pop()}returnWorker(i,t){this.workers[i].push(t)}};function J(i,t,l){var e=void 0===t?null:t,n=function(i,t){var l=atob(i);if(t){for(var e=new Uint8Array(l.length),n=0,d=l.length;n<d;++n)e[n]=l.charCodeAt(n);return String.fromCharCode.apply(null,new Uint16Array(e.buffer))}return l}(i,void 0!==l&&l),d=n.indexOf("\n",10)+1,s=n.substring(d)+(e?"//# sourceMappingURL="+e:""),c=new Blob([s],{type:"application/javascript"});return URL.createObjectURL(c)}var W,T,C,N,f=(W="Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwpjbGFzcyBle2NvbnN0cnVjdG9yKGUpe3RoaXMudmVyc2lvbj1lO2xldCB0PS0xPT09ZS5pbmRleE9mKCIuIik/ZS5sZW5ndGg6ZS5pbmRleE9mKCIuIik7dGhpcy52ZXJzaW9uTWFqb3I9cGFyc2VJbnQoZS5zdWJzdHIoMCx0KSksdGhpcy52ZXJzaW9uTWlub3I9cGFyc2VJbnQoZS5zdWJzdHIodCsxKSksMD09PXRoaXMudmVyc2lvbk1pbm9yLmxlbmd0aCYmKHRoaXMudmVyc2lvbk1pbm9yPTApfW5ld2VyVGhhbih0KXtsZXQgcj1uZXcgZSh0KTtyZXR1cm4gdGhpcy52ZXJzaW9uTWFqb3I+ci52ZXJzaW9uTWFqb3J8fHRoaXMudmVyc2lvbk1ham9yPT09ci52ZXJzaW9uTWFqb3ImJnRoaXMudmVyc2lvbk1pbm9yPnIudmVyc2lvbk1pbm9yfWVxdWFsT3JIaWdoZXIodCl7bGV0IHI9bmV3IGUodCk7cmV0dXJuIHRoaXMudmVyc2lvbk1ham9yPnIudmVyc2lvbk1ham9yfHx0aGlzLnZlcnNpb25NYWpvcj09PXIudmVyc2lvbk1ham9yJiZ0aGlzLnZlcnNpb25NaW5vcj49ci52ZXJzaW9uTWlub3J9dXBUbyhlKXtyZXR1cm4hdGhpcy5uZXdlclRoYW4oZSl9fWNvbnN0IHQ9MCxyPTEsbj00LGk9NSxhPTYscz03LEE9OCxmPTksVD0xMCxvPTExLHU9MTIsbD0xMyxfPTE0LEk9MTUsYj0xNixFPXtEQVRBX1RZUEVfRE9VQkxFOntvcmRpbmFsOjAsc2l6ZTo4fSxEQVRBX1RZUEVfRkxPQVQ6e29yZGluYWw6MSxzaXplOjR9LERBVEFfVFlQRV9JTlQ4OntvcmRpbmFsOjIsc2l6ZToxfSxEQVRBX1RZUEVfVUlOVDg6e29yZGluYWw6MyxzaXplOjF9LERBVEFfVFlQRV9JTlQxNjp7b3JkaW5hbDo0LHNpemU6Mn0sREFUQV9UWVBFX1VJTlQxNjp7b3JkaW5hbDo1LHNpemU6Mn0sREFUQV9UWVBFX0lOVDMyOntvcmRpbmFsOjYsc2l6ZTo0fSxEQVRBX1RZUEVfVUlOVDMyOntvcmRpbmFsOjcsc2l6ZTo0fSxEQVRBX1RZUEVfSU5UNjQ6e29yZGluYWw6OCxzaXplOjh9LERBVEFfVFlQRV9VSU5UNjQ6e29yZGluYWw6OSxzaXplOjh9fTtsZXQgaD0wO2ZvcihsZXQgZSBpbiBFKUVbaF09RVtlXSxoKys7Y2xhc3MgTntjb25zdHJ1Y3RvcihlLHQscil7dGhpcy5uYW1lPWUsdGhpcy50eXBlPXQsdGhpcy5udW1FbGVtZW50cz1yLHRoaXMuYnl0ZVNpemU9dGhpcy5udW1FbGVtZW50cyp0aGlzLnR5cGUuc2l6ZX19ZnVuY3Rpb24gbShlKXt0aGlzLmJ1ZmZlcj1lLHRoaXMudTg9bmV3IFVpbnQ4QXJyYXkoZSk7bGV0IHQ9bmV3IEFycmF5QnVmZmVyKDgpLHI9bmV3IEZsb2F0MzJBcnJheSh0KSxuPW5ldyBGbG9hdDY0QXJyYXkodCksaT1uZXcgVWludDhBcnJheSh0KTt0aGlzLmdldFVpbnQzMj1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcy51OFtlKzNdPDwyNHx0aGlzLnU4W2UrMl08PDE2fHRoaXMudThbZSsxXTw8OHx0aGlzLnU4W2VdfSx0aGlzLmdldFVpbnQxNj1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcy51OFtlKzFdPDw4fHRoaXMudThbZV19LHRoaXMuZ2V0RmxvYXQzMj1mdW5jdGlvbihlKXtyZXR1cm4gaVswXT10aGlzLnU4W2UrMF0saVsxXT10aGlzLnU4W2UrMV0saVsyXT10aGlzLnU4W2UrMl0saVszXT10aGlzLnU4W2UrM10sclswXX0sdGhpcy5nZXRGbG9hdDY0PWZ1bmN0aW9uKGUpe3JldHVybiBpWzBdPXRoaXMudThbZSswXSxpWzFdPXRoaXMudThbZSsxXSxpWzJdPXRoaXMudThbZSsyXSxpWzNdPXRoaXMudThbZSszXSxpWzRdPXRoaXMudThbZSs0XSxpWzVdPXRoaXMudThbZSs1XSxpWzZdPXRoaXMudThbZSs2XSxpWzddPXRoaXMudThbZSs3XSxuWzBdfSx0aGlzLmdldFVpbnQ4PWZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLnU4W2VdfX1OLlBPU0lUSU9OX0NBUlRFU0lBTj1uZXcgTih0LEUuREFUQV9UWVBFX0ZMT0FULDMpLE4uUkdCQV9QQUNLRUQ9bmV3IE4ocixFLkRBVEFfVFlQRV9JTlQ4LDQpLE4uQ09MT1JfUEFDS0VEPU4uUkdCQV9QQUNLRUQsTi5SR0JfUEFDS0VEPW5ldyBOKHIsRS5EQVRBX1RZUEVfSU5UOCwzKSxOLk5PUk1BTF9GTE9BVFM9bmV3IE4obixFLkRBVEFfVFlQRV9GTE9BVCwzKSxOLkZJTExFUl8xQj1uZXcgTihpLEUuREFUQV9UWVBFX1VJTlQ4LDEpLE4uSU5URU5TSVRZPW5ldyBOKGEsRS5EQVRBX1RZUEVfVUlOVDE2LDEpLE4uQ0xBU1NJRklDQVRJT049bmV3IE4ocyxFLkRBVEFfVFlQRV9VSU5UOCwxKSxOLk5PUk1BTF9TUEhFUkVNQVBQRUQ9bmV3IE4oQSxFLkRBVEFfVFlQRV9VSU5UOCwyKSxOLk5PUk1BTF9PQ1QxNj1uZXcgTihmLEUuREFUQV9UWVBFX1VJTlQ4LDIpLE4uTk9STUFMPW5ldyBOKFQsRS5EQVRBX1RZUEVfRkxPQVQsMyksTi5SRVRVUk5fTlVNQkVSPW5ldyBOKG8sRS5EQVRBX1RZUEVfVUlOVDgsMSksTi5OVU1CRVJfT0ZfUkVUVVJOUz1uZXcgTih1LEUuREFUQV9UWVBFX1VJTlQ4LDEpLE4uU09VUkNFX0lEPW5ldyBOKGwsRS5EQVRBX1RZUEVfVUlOVDE2LDEpLE4uSU5ESUNFUz1uZXcgTihfLEUuREFUQV9UWVBFX1VJTlQzMiwxKSxOLlNQQUNJTkc9bmV3IE4oSSxFLkRBVEFfVFlQRV9GTE9BVCwxKSxOLkdQU19USU1FPW5ldyBOKGIsRS5EQVRBX1RZUEVfRE9VQkxFLDEpLG9ubWVzc2FnZT1mdW5jdGlvbih0KXtwZXJmb3JtYW5jZS5tYXJrKCJiaW5hcnktZGVjb2Rlci1zdGFydCIpO2xldCByPXQuZGF0YS5idWZmZXIsbj10LmRhdGEucG9pbnRBdHRyaWJ1dGVzLGk9ci5ieXRlTGVuZ3RoL24uYnl0ZVNpemUsYT1uZXcgbShyKSxzPW5ldyBlKHQuZGF0YS52ZXJzaW9uKSxBPXQuZGF0YS5vZmZzZXQsZj10LmRhdGEuc2NhbGUsVD0odC5kYXRhLnNwYWNpbmcsdC5kYXRhLmhhc0NoaWxkcmVuLHQuZGF0YS5uYW1lLFtOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLE51bWJlci5QT1NJVElWRV9JTkZJTklUWV0pLG89W051bWJlci5ORUdBVElWRV9JTkZJTklUWSxOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZXSx1PVswLDAsMF0sbD17fSxfPTA7Zm9yKGxldCBlIG9mIG4uYXR0cmlidXRlcyl7aWYoZS5uYW1lPT09Ti5QT1NJVElPTl9DQVJURVNJQU4ubmFtZSl7bGV0IHQ9bmV3IEFycmF5QnVmZmVyKDQqaSozKSxyPW5ldyBGbG9hdDMyQXJyYXkodCk7Zm9yKGxldCBlPTA7ZTxpO2UrKyl7bGV0IHQsbCxJO3MubmV3ZXJUaGFuKCIxLjMiKT8odD1hLmdldFVpbnQzMihfK2Uqbi5ieXRlU2l6ZSswLCEwKSpmLGw9YS5nZXRVaW50MzIoXytlKm4uYnl0ZVNpemUrNCwhMCkqZixJPWEuZ2V0VWludDMyKF8rZSpuLmJ5dGVTaXplKzgsITApKmYpOih0PWEuZ2V0RmxvYXQzMihlKm4uYnl0ZVNpemUrMCwhMCkrQVswXSxsPWEuZ2V0RmxvYXQzMihlKm4uYnl0ZVNpemUrNCwhMCkrQVsxXSxJPWEuZ2V0RmxvYXQzMihlKm4uYnl0ZVNpemUrOCwhMCkrQVsyXSksclszKmUrMF09dCxyWzMqZSsxXT1sLHJbMyplKzJdPUksdVswXSs9dC9pLHVbMV0rPWwvaSx1WzJdKz1JL2ksVFswXT1NYXRoLm1pbihUWzBdLHQpLFRbMV09TWF0aC5taW4oVFsxXSxsKSxUWzJdPU1hdGgubWluKFRbMl0sSSksb1swXT1NYXRoLm1heChvWzBdLHQpLG9bMV09TWF0aC5tYXgob1sxXSxsKSxvWzJdPU1hdGgubWF4KG9bMl0sSSl9bFtlLm5hbWVdPXtidWZmZXI6dCxhdHRyaWJ1dGU6ZX19ZWxzZSBpZihlLm5hbWU9PT1OLkNPTE9SX1BBQ0tFRC5uYW1lKXtsZXQgdD1uZXcgQXJyYXlCdWZmZXIoNCppKSxyPW5ldyBVaW50OEFycmF5KHQpO2ZvcihsZXQgZT0wO2U8aTtlKyspcls0KmUrMF09YS5nZXRVaW50OChfK2Uqbi5ieXRlU2l6ZSswKSxyWzQqZSsxXT1hLmdldFVpbnQ4KF8rZSpuLmJ5dGVTaXplKzEpLHJbNCplKzJdPWEuZ2V0VWludDgoXytlKm4uYnl0ZVNpemUrMik7bFtlLm5hbWVdPXtidWZmZXI6dCxhdHRyaWJ1dGU6ZX19ZWxzZSBpZihlLm5hbWU9PT1OLklOVEVOU0lUWS5uYW1lKXtsZXQgdD1uZXcgQXJyYXlCdWZmZXIoNCppKSxyPW5ldyBGbG9hdDMyQXJyYXkodCk7Zm9yKGxldCBlPTA7ZTxpO2UrKyl7bGV0IHQ9YS5nZXRVaW50MTYoXytlKm4uYnl0ZVNpemUsITApO3JbZV09dH1sW2UubmFtZV09e2J1ZmZlcjp0LGF0dHJpYnV0ZTplfX1lbHNlIGlmKGUubmFtZT09PU4uQ0xBU1NJRklDQVRJT04ubmFtZSl7bGV0IHQ9bmV3IEFycmF5QnVmZmVyKGkpLHI9bmV3IFVpbnQ4QXJyYXkodCk7Zm9yKGxldCBlPTA7ZTxpO2UrKyl7bGV0IHQ9YS5nZXRVaW50OChfK2Uqbi5ieXRlU2l6ZSk7cltlXT10fWxbZS5uYW1lXT17YnVmZmVyOnQsYXR0cmlidXRlOmV9fWVsc2UgaWYoZS5uYW1lPT09Ti5SRVRVUk5fTlVNQkVSLm5hbWUpe2xldCB0PW5ldyBBcnJheUJ1ZmZlcihpKSxyPW5ldyBVaW50OEFycmF5KHQpO2ZvcihsZXQgZT0wO2U8aTtlKyspe2xldCB0PWEuZ2V0VWludDgoXytlKm4uYnl0ZVNpemUpO3JbZV09dH1sW2UubmFtZV09e2J1ZmZlcjp0LGF0dHJpYnV0ZTplfX1lbHNlIGlmKGUubmFtZT09PU4uTlVNQkVSX09GX1JFVFVSTlMubmFtZSl7bGV0IHQ9bmV3IEFycmF5QnVmZmVyKGkpLHI9bmV3IFVpbnQ4QXJyYXkodCk7Zm9yKGxldCBlPTA7ZTxpO2UrKyl7bGV0IHQ9YS5nZXRVaW50OChfK2Uqbi5ieXRlU2l6ZSk7cltlXT10fWxbZS5uYW1lXT17YnVmZmVyOnQsYXR0cmlidXRlOmV9fWVsc2UgaWYoZS5uYW1lPT09Ti5TT1VSQ0VfSUQubmFtZSl7bGV0IHQ9bmV3IEFycmF5QnVmZmVyKDIqaSkscj1uZXcgVWludDE2QXJyYXkodCk7Zm9yKGxldCBlPTA7ZTxpO2UrKyl7bGV0IHQ9YS5nZXRVaW50MTYoXytlKm4uYnl0ZVNpemUpO3JbZV09dH1sW2UubmFtZV09e2J1ZmZlcjp0LGF0dHJpYnV0ZTplfX1lbHNlIGlmKGUubmFtZT09PU4uTk9STUFMX1NQSEVSRU1BUFBFRC5uYW1lKXtsZXQgdD1uZXcgQXJyYXlCdWZmZXIoNCppKjMpLHI9bmV3IEZsb2F0MzJBcnJheSh0KTtmb3IobGV0IGU9MDtlPGk7ZSsrKXtsZXQgdD0yKihhLmdldFVpbnQ4KF8rZSpuLmJ5dGVTaXplKzApLzI1NSktMSxpPTIqKGEuZ2V0VWludDgoXytlKm4uYnl0ZVNpemUrMSkvMjU1KS0xLHM9MSxBPXQqLXQraSotaStzKi0gLTE7cz1BLHQqPU1hdGguc3FydChBKSxpKj1NYXRoLnNxcnQoQSksdCo9MixpKj0yLHM9MipzLTEsclszKmUrMF09dCxyWzMqZSsxXT1pLHJbMyplKzJdPXN9bFtlLm5hbWVdPXtidWZmZXI6dCxhdHRyaWJ1dGU6ZX19ZWxzZSBpZihlLm5hbWU9PT1OLk5PUk1BTF9PQ1QxNi5uYW1lKXtsZXQgdD1uZXcgQXJyYXlCdWZmZXIoNCppKjMpLHI9bmV3IEZsb2F0MzJBcnJheSh0KTtmb3IobGV0IGU9MDtlPGk7ZSsrKXtsZXQgdD1hLmdldFVpbnQ4KF8rZSpuLmJ5dGVTaXplKzApLzI1NSoyLTEsaT1hLmdldFVpbnQ4KF8rZSpuLmJ5dGVTaXplKzEpLzI1NSoyLTEscz0xLU1hdGguYWJzKHQpLU1hdGguYWJzKGkpLEE9MCxmPTA7cz49MD8oQT10LGY9aSk6KEE9LShpL01hdGguc2lnbihpKS0xKS9NYXRoLnNpZ24odCksZj0tKHQvTWF0aC5zaWduKHQpLTEpL01hdGguc2lnbihpKSk7bGV0IFQ9TWF0aC5zcXJ0KEEqQStmKmYrcypzKTtBLz1ULGYvPVQscy89VCxyWzMqZSswXT1BLHJbMyplKzFdPWYsclszKmUrMl09c31sW2UubmFtZV09e2J1ZmZlcjp0LGF0dHJpYnV0ZTplfX1lbHNlIGlmKGUubmFtZT09PU4uTk9STUFMLm5hbWUpe2xldCB0PW5ldyBBcnJheUJ1ZmZlcig0KmkqMykscj1uZXcgRmxvYXQzMkFycmF5KHQpO2ZvcihsZXQgZT0wO2U8aTtlKyspe2xldCB0PWEuZ2V0RmxvYXQzMihfK2Uqbi5ieXRlU2l6ZSswLCEwKSxpPWEuZ2V0RmxvYXQzMihfK2Uqbi5ieXRlU2l6ZSs0LCEwKSxzPWEuZ2V0RmxvYXQzMihfK2Uqbi5ieXRlU2l6ZSs4LCEwKTtyWzMqZSswXT10LHJbMyplKzFdPWksclszKmUrMl09c31sW2UubmFtZV09e2J1ZmZlcjp0LGF0dHJpYnV0ZTplfX1lbHNlIGlmKGUubmFtZT09PU4uR1BTX1RJTUUubmFtZSl7bGV0IHQ9bmV3IEFycmF5QnVmZmVyKDgqaSkscj1uZXcgRmxvYXQ2NEFycmF5KHQpO2ZvcihsZXQgZT0wO2U8aTtlKyspe2xldCB0PWEuZ2V0RmxvYXQ2NChfK2Uqbi5ieXRlU2l6ZSwhMCk7cltlXT10fWxbZS5uYW1lXT17YnVmZmVyOnQsYXR0cmlidXRlOmV9fV8rPWUuYnl0ZVNpemV9aWYobFtOLkdQU19USU1FLm5hbWVdKXtsZXQgZT1sW04uR1BTX1RJTUUubmFtZV0sdD1uZXcgRmxvYXQ2NEFycmF5KGUuYnVmZmVyKSxyPW5ldyBBcnJheUJ1ZmZlcig0KmkpLG49bmV3IEZsb2F0MzJBcnJheShyKSxhPTEvMCxzPS0xLzA7Zm9yKGxldCBlPTA7ZTxpO2UrKyl7bGV0IHI9dFtlXTthPU1hdGgubWluKGEscikscz1NYXRoLm1heChzLHIpfWZvcihsZXQgZT0wO2U8aTtlKyspe2xldCByPXRbZV07bltlXT1yLWF9bFtOLkdQU19USU1FLm5hbWVdPXtidWZmZXI6cixhdHRyaWJ1dGU6Ti5HUFNfVElNRSxvZmZzZXQ6YSxyYW5nZTpzLWF9fXtsZXQgZT1uZXcgQXJyYXlCdWZmZXIoNCppKSx0PW5ldyBVaW50MzJBcnJheShlKTtmb3IobGV0IGU9MDtlPGk7ZSsrKXRbZV09ZTtsW04uSU5ESUNFUy5uYW1lXT17YnVmZmVyOmUsYXR0cmlidXRlOk4uSU5ESUNFU319cGVyZm9ybWFuY2UubWFyaygiYmluYXJ5LWRlY29kZXItZW5kIikscGVyZm9ybWFuY2UuY2xlYXJNYXJrcygpLHBlcmZvcm1hbmNlLmNsZWFyTWVhc3VyZXMoKTtsZXQgST17YnVmZmVyOnIsbWVhbjp1LGF0dHJpYnV0ZUJ1ZmZlcnM6bCx0aWdodEJvdW5kaW5nQm94OnttaW46VCxtYXg6b319LGI9W107Zm9yKGxldCBlIGluIEkuYXR0cmlidXRlQnVmZmVycyliLnB1c2goSS5hdHRyaWJ1dGVCdWZmZXJzW2VdLmJ1ZmZlcik7Yi5wdXNoKHIpLHBvc3RNZXNzYWdlKEksYil9OwoK",T="data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmluYXJ5RGVjb2Rlcldvcmtlci5qcyIsInNvdXJjZXMiOlsic3JjL1ZlcnNpb24uanMiLCJzcmMvbG9hZGVyL1BvaW50QXR0cmlidXRlcy5qcyIsInNyYy93b3JrZXJzL0JpbmFyeURlY29kZXJXb3JrZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiXHJcbmV4cG9ydCBjbGFzcyBWZXJzaW9ue1xyXG5cclxuXHRjb25zdHJ1Y3Rvcih2ZXJzaW9uKXtcclxuXHRcdHRoaXMudmVyc2lvbiA9IHZlcnNpb247XHJcblx0XHRsZXQgdm1MZW5ndGggPSAodmVyc2lvbi5pbmRleE9mKCcuJykgPT09IC0xKSA/IHZlcnNpb24ubGVuZ3RoIDogdmVyc2lvbi5pbmRleE9mKCcuJyk7XHJcblx0XHR0aGlzLnZlcnNpb25NYWpvciA9IHBhcnNlSW50KHZlcnNpb24uc3Vic3RyKDAsIHZtTGVuZ3RoKSk7XHJcblx0XHR0aGlzLnZlcnNpb25NaW5vciA9IHBhcnNlSW50KHZlcnNpb24uc3Vic3RyKHZtTGVuZ3RoICsgMSkpO1xyXG5cdFx0aWYgKHRoaXMudmVyc2lvbk1pbm9yLmxlbmd0aCA9PT0gMCkge1xyXG5cdFx0XHR0aGlzLnZlcnNpb25NaW5vciA9IDA7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRuZXdlclRoYW4odmVyc2lvbil7XHJcblx0XHRsZXQgdiA9IG5ldyBWZXJzaW9uKHZlcnNpb24pO1xyXG5cclxuXHRcdGlmICh0aGlzLnZlcnNpb25NYWpvciA+IHYudmVyc2lvbk1ham9yKSB7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSBlbHNlIGlmICh0aGlzLnZlcnNpb25NYWpvciA9PT0gdi52ZXJzaW9uTWFqb3IgJiYgdGhpcy52ZXJzaW9uTWlub3IgPiB2LnZlcnNpb25NaW5vcikge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGVxdWFsT3JIaWdoZXIodmVyc2lvbil7XHJcblx0XHRsZXQgdiA9IG5ldyBWZXJzaW9uKHZlcnNpb24pO1xyXG5cclxuXHRcdGlmICh0aGlzLnZlcnNpb25NYWpvciA+IHYudmVyc2lvbk1ham9yKSB7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSBlbHNlIGlmICh0aGlzLnZlcnNpb25NYWpvciA9PT0gdi52ZXJzaW9uTWFqb3IgJiYgdGhpcy52ZXJzaW9uTWlub3IgPj0gdi52ZXJzaW9uTWlub3IpIHtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHR1cFRvKHZlcnNpb24pe1xyXG5cdFx0cmV0dXJuICF0aGlzLm5ld2VyVGhhbih2ZXJzaW9uKTtcclxuXHR9XHJcblxyXG59XHJcblxyXG5cclxuIiwiXHJcblxyXG5leHBvcnQgY29uc3QgUG9pbnRBdHRyaWJ1dGVOYW1lcyA9IHtcclxuXHRQT1NJVElPTl9DQVJURVNJQU46IDAsIC8vIGZsb2F0IHgsIHksIHo7XHJcblx0Q09MT1JfUEFDS0VEOiAxLCAvLyBieXRlIHIsIGcsIGIsIGE7IFx0STogWzAsMV1cclxuXHRDT0xPUl9GTE9BVFNfMTogMiwgLy8gZmxvYXQgciwgZywgYjsgXHRJOiBbMCwxXVxyXG5cdENPTE9SX0ZMT0FUU18yNTU6IDMsIC8vIGZsb2F0IHIsIGcsIGI7IFx0STogWzAsMjU1XVxyXG5cdE5PUk1BTF9GTE9BVFM6IDQsIC8vIGZsb2F0IHgsIHksIHo7XHJcblx0RklMTEVSOiA1LFxyXG5cdElOVEVOU0lUWTogNixcclxuXHRDTEFTU0lGSUNBVElPTjogNyxcclxuXHROT1JNQUxfU1BIRVJFTUFQUEVEOiA4LFxyXG5cdE5PUk1BTF9PQ1QxNjogOSxcclxuXHROT1JNQUw6IDEwLFxyXG5cdFJFVFVSTl9OVU1CRVI6IDExLFxyXG5cdE5VTUJFUl9PRl9SRVRVUk5TOiAxMixcclxuXHRTT1VSQ0VfSUQ6IDEzLFxyXG5cdElORElDRVM6IDE0LFxyXG5cdFNQQUNJTkc6IDE1LFxyXG5cdEdQU19USU1FOiAxNixcclxufTtcclxuXHJcblxyXG4vKipcclxuICogU29tZSB0eXBlcyBvZiBwb3NzaWJsZSBwb2ludCBhdHRyaWJ1dGUgZGF0YSBmb3JtYXRzXHJcbiAqXHJcbiAqIEBjbGFzc1xyXG4gKi9cclxuY29uc3QgUG9pbnRBdHRyaWJ1dGVUeXBlcyA9IHtcclxuXHREQVRBX1RZUEVfRE9VQkxFOiB7b3JkaW5hbDogMCwgc2l6ZTogOH0sXHJcblx0REFUQV9UWVBFX0ZMT0FUOiB7b3JkaW5hbDogMSwgc2l6ZTogNH0sXHJcblx0REFUQV9UWVBFX0lOVDg6IHtvcmRpbmFsOiAyLCBzaXplOiAxfSxcclxuXHREQVRBX1RZUEVfVUlOVDg6IHtvcmRpbmFsOiAzLCBzaXplOiAxfSxcclxuXHREQVRBX1RZUEVfSU5UMTY6IHtvcmRpbmFsOiA0LCBzaXplOiAyfSxcclxuXHREQVRBX1RZUEVfVUlOVDE2OiB7b3JkaW5hbDogNSwgc2l6ZTogMn0sXHJcblx0REFUQV9UWVBFX0lOVDMyOiB7b3JkaW5hbDogNiwgc2l6ZTogNH0sXHJcblx0REFUQV9UWVBFX1VJTlQzMjoge29yZGluYWw6IDcsIHNpemU6IDR9LFxyXG5cdERBVEFfVFlQRV9JTlQ2NDoge29yZGluYWw6IDgsIHNpemU6IDh9LFxyXG5cdERBVEFfVFlQRV9VSU5UNjQ6IHtvcmRpbmFsOiA5LCBzaXplOiA4fVxyXG59O1xyXG5cclxubGV0IGkgPSAwO1xyXG5mb3IgKGxldCBvYmogaW4gUG9pbnRBdHRyaWJ1dGVUeXBlcykge1xyXG5cdFBvaW50QXR0cmlidXRlVHlwZXNbaV0gPSBQb2ludEF0dHJpYnV0ZVR5cGVzW29ial07XHJcblx0aSsrO1xyXG59XHJcblxyXG5leHBvcnQge1BvaW50QXR0cmlidXRlVHlwZXN9O1xyXG5cclxuXHJcbmNsYXNzIFBvaW50QXR0cmlidXRle1xyXG5cdFxyXG5cdGNvbnN0cnVjdG9yKG5hbWUsIHR5cGUsIG51bUVsZW1lbnRzKXtcclxuXHRcdHRoaXMubmFtZSA9IG5hbWU7XHJcblx0XHR0aGlzLnR5cGUgPSB0eXBlO1xyXG5cdFx0dGhpcy5udW1FbGVtZW50cyA9IG51bUVsZW1lbnRzO1xyXG5cdFx0dGhpcy5ieXRlU2l6ZSA9IHRoaXMubnVtRWxlbWVudHMgKiB0aGlzLnR5cGUuc2l6ZTtcclxuXHR9XHJcblxyXG59O1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuUE9TSVRJT05fQ0FSVEVTSUFOID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuUE9TSVRJT05fQ0FSVEVTSUFOLFxyXG5cdFBvaW50QXR0cmlidXRlVHlwZXMuREFUQV9UWVBFX0ZMT0FULCAzKTtcclxuXHJcblBvaW50QXR0cmlidXRlLlJHQkFfUEFDS0VEID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuQ09MT1JfUEFDS0VELFxyXG5cdFBvaW50QXR0cmlidXRlVHlwZXMuREFUQV9UWVBFX0lOVDgsIDQpO1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuQ09MT1JfUEFDS0VEID0gUG9pbnRBdHRyaWJ1dGUuUkdCQV9QQUNLRUQ7XHJcblxyXG5Qb2ludEF0dHJpYnV0ZS5SR0JfUEFDS0VEID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuQ09MT1JfUEFDS0VELFxyXG5cdFBvaW50QXR0cmlidXRlVHlwZXMuREFUQV9UWVBFX0lOVDgsIDMpO1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuTk9STUFMX0ZMT0FUUyA9IG5ldyBQb2ludEF0dHJpYnV0ZShcclxuXHRQb2ludEF0dHJpYnV0ZU5hbWVzLk5PUk1BTF9GTE9BVFMsXHJcblx0UG9pbnRBdHRyaWJ1dGVUeXBlcy5EQVRBX1RZUEVfRkxPQVQsIDMpO1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuRklMTEVSXzFCID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuRklMTEVSLFxyXG5cdFBvaW50QXR0cmlidXRlVHlwZXMuREFUQV9UWVBFX1VJTlQ4LCAxKTtcclxuXHJcblBvaW50QXR0cmlidXRlLklOVEVOU0lUWSA9IG5ldyBQb2ludEF0dHJpYnV0ZShcclxuXHRQb2ludEF0dHJpYnV0ZU5hbWVzLklOVEVOU0lUWSxcclxuXHRQb2ludEF0dHJpYnV0ZVR5cGVzLkRBVEFfVFlQRV9VSU5UMTYsIDEpO1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuQ0xBU1NJRklDQVRJT04gPSBuZXcgUG9pbnRBdHRyaWJ1dGUoXHJcblx0UG9pbnRBdHRyaWJ1dGVOYW1lcy5DTEFTU0lGSUNBVElPTixcclxuXHRQb2ludEF0dHJpYnV0ZVR5cGVzLkRBVEFfVFlQRV9VSU5UOCwgMSk7XHJcblxyXG5Qb2ludEF0dHJpYnV0ZS5OT1JNQUxfU1BIRVJFTUFQUEVEID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuTk9STUFMX1NQSEVSRU1BUFBFRCxcclxuXHRQb2ludEF0dHJpYnV0ZVR5cGVzLkRBVEFfVFlQRV9VSU5UOCwgMik7XHJcblxyXG5Qb2ludEF0dHJpYnV0ZS5OT1JNQUxfT0NUMTYgPSBuZXcgUG9pbnRBdHRyaWJ1dGUoXHJcblx0UG9pbnRBdHRyaWJ1dGVOYW1lcy5OT1JNQUxfT0NUMTYsXHJcblx0UG9pbnRBdHRyaWJ1dGVUeXBlcy5EQVRBX1RZUEVfVUlOVDgsIDIpO1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuTk9STUFMID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuTk9STUFMLFxyXG5cdFBvaW50QXR0cmlidXRlVHlwZXMuREFUQV9UWVBFX0ZMT0FULCAzKTtcclxuXHRcclxuUG9pbnRBdHRyaWJ1dGUuUkVUVVJOX05VTUJFUiA9IG5ldyBQb2ludEF0dHJpYnV0ZShcclxuXHRQb2ludEF0dHJpYnV0ZU5hbWVzLlJFVFVSTl9OVU1CRVIsXHJcblx0UG9pbnRBdHRyaWJ1dGVUeXBlcy5EQVRBX1RZUEVfVUlOVDgsIDEpO1xyXG5cdFxyXG5Qb2ludEF0dHJpYnV0ZS5OVU1CRVJfT0ZfUkVUVVJOUyA9IG5ldyBQb2ludEF0dHJpYnV0ZShcclxuXHRQb2ludEF0dHJpYnV0ZU5hbWVzLk5VTUJFUl9PRl9SRVRVUk5TLFxyXG5cdFBvaW50QXR0cmlidXRlVHlwZXMuREFUQV9UWVBFX1VJTlQ4LCAxKTtcclxuXHRcclxuUG9pbnRBdHRyaWJ1dGUuU09VUkNFX0lEID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuU09VUkNFX0lELFxyXG5cdFBvaW50QXR0cmlidXRlVHlwZXMuREFUQV9UWVBFX1VJTlQxNiwgMSk7XHJcblxyXG5Qb2ludEF0dHJpYnV0ZS5JTkRJQ0VTID0gbmV3IFBvaW50QXR0cmlidXRlKFxyXG5cdFBvaW50QXR0cmlidXRlTmFtZXMuSU5ESUNFUyxcclxuXHRQb2ludEF0dHJpYnV0ZVR5cGVzLkRBVEFfVFlQRV9VSU5UMzIsIDEpO1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuU1BBQ0lORyA9IG5ldyBQb2ludEF0dHJpYnV0ZShcclxuXHRQb2ludEF0dHJpYnV0ZU5hbWVzLlNQQUNJTkcsXHJcblx0UG9pbnRBdHRyaWJ1dGVUeXBlcy5EQVRBX1RZUEVfRkxPQVQsIDEpO1xyXG5cclxuUG9pbnRBdHRyaWJ1dGUuR1BTX1RJTUUgPSBuZXcgUG9pbnRBdHRyaWJ1dGUoXHJcblx0UG9pbnRBdHRyaWJ1dGVOYW1lcy5HUFNfVElNRSxcclxuXHRQb2ludEF0dHJpYnV0ZVR5cGVzLkRBVEFfVFlQRV9ET1VCTEUsIDEpO1xyXG5cclxuZXhwb3J0IHtQb2ludEF0dHJpYnV0ZX07XHJcblxyXG5leHBvcnQgY2xhc3MgUG9pbnRBdHRyaWJ1dGVze1xyXG5cclxuXHRjb25zdHJ1Y3Rvcihwb2ludEF0dHJpYnV0ZXMpe1xyXG5cdFx0dGhpcy5hdHRyaWJ1dGVzID0gW107XHJcblx0XHR0aGlzLmJ5dGVTaXplID0gMDtcclxuXHRcdHRoaXMuc2l6ZSA9IDA7XHJcblxyXG5cdFx0aWYgKHBvaW50QXR0cmlidXRlcyAhPSBudWxsKSB7XHJcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRBdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdFx0bGV0IHBvaW50QXR0cmlidXRlTmFtZSA9IHBvaW50QXR0cmlidXRlc1tpXTtcclxuXHRcdFx0XHRsZXQgcG9pbnRBdHRyaWJ1dGUgPSBQb2ludEF0dHJpYnV0ZVtwb2ludEF0dHJpYnV0ZU5hbWVdO1xyXG5cdFx0XHRcdHRoaXMuYXR0cmlidXRlcy5wdXNoKHBvaW50QXR0cmlidXRlKTtcclxuXHRcdFx0XHR0aGlzLmJ5dGVTaXplICs9IHBvaW50QXR0cmlidXRlLmJ5dGVTaXplO1xyXG5cdFx0XHRcdHRoaXMuc2l6ZSsrO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHJcblx0YWRkKHBvaW50QXR0cmlidXRlKXtcclxuXHRcdHRoaXMuYXR0cmlidXRlcy5wdXNoKHBvaW50QXR0cmlidXRlKTtcclxuXHRcdHRoaXMuYnl0ZVNpemUgKz0gcG9pbnRBdHRyaWJ1dGUuYnl0ZVNpemU7XHJcblx0XHR0aGlzLnNpemUrKztcclxuXHR9O1xyXG5cclxuXHRoYXNDb2xvcnMoKXtcclxuXHRcdGZvciAobGV0IG5hbWUgaW4gdGhpcy5hdHRyaWJ1dGVzKSB7XHJcblx0XHRcdGxldCBwb2ludEF0dHJpYnV0ZSA9IHRoaXMuYXR0cmlidXRlc1tuYW1lXTtcclxuXHRcdFx0aWYgKHBvaW50QXR0cmlidXRlLm5hbWUgPT09IFBvaW50QXR0cmlidXRlTmFtZXMuQ09MT1JfUEFDS0VEKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fTtcclxuXHJcblx0aGFzTm9ybWFscygpe1xyXG5cdFx0Zm9yIChsZXQgbmFtZSBpbiB0aGlzLmF0dHJpYnV0ZXMpIHtcclxuXHRcdFx0bGV0IHBvaW50QXR0cmlidXRlID0gdGhpcy5hdHRyaWJ1dGVzW25hbWVdO1xyXG5cdFx0XHRpZiAoXHJcblx0XHRcdFx0cG9pbnRBdHRyaWJ1dGUgPT09IFBvaW50QXR0cmlidXRlLk5PUk1BTF9TUEhFUkVNQVBQRUQgfHxcclxuXHRcdFx0XHRwb2ludEF0dHJpYnV0ZSA9PT0gUG9pbnRBdHRyaWJ1dGUuTk9STUFMX0ZMT0FUUyB8fFxyXG5cdFx0XHRcdHBvaW50QXR0cmlidXRlID09PSBQb2ludEF0dHJpYnV0ZS5OT1JNQUwgfHxcclxuXHRcdFx0XHRwb2ludEF0dHJpYnV0ZSA9PT0gUG9pbnRBdHRyaWJ1dGUuTk9STUFMX09DVDE2KSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fTtcclxuXHJcbn1cclxuIiwiXHJcblxyXG5pbXBvcnQge1ZlcnNpb259IGZyb20gXCIuLi9WZXJzaW9uLmpzXCI7XHJcbmltcG9ydCB7UG9pbnRBdHRyaWJ1dGVzLCBQb2ludEF0dHJpYnV0ZX0gZnJvbSBcIi4uL2xvYWRlci9Qb2ludEF0dHJpYnV0ZXMuanNcIjtcclxuaW1wb3J0IHtJbnRlcmxlYXZlZEJ1ZmZlcn0gZnJvbSBcIi4uL0ludGVybGVhdmVkQnVmZmVyLmpzXCI7XHJcbmltcG9ydCB7dG9JbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZX0gZnJvbSBcIi4uL3V0aWxzL3RvSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUuanNcIjtcclxuXHJcblxyXG5cclxuLyogZ2xvYmFsIG9ubWVzc2FnZTp0cnVlIHBvc3RNZXNzYWdlOmZhbHNlICovXHJcbi8qIGV4cG9ydGVkIG9ubWVzc2FnZSAqL1xyXG4vLyBodHRwOi8vanNwZXJmLmNvbS91aW50OGFycmF5LXZzLWRhdGF2aWV3My8zXHJcbmZ1bmN0aW9uIEN1c3RvbVZpZXcgKGJ1ZmZlcikge1xyXG5cdHRoaXMuYnVmZmVyID0gYnVmZmVyO1xyXG5cdHRoaXMudTggPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xyXG5cclxuXHRsZXQgdG1wID0gbmV3IEFycmF5QnVmZmVyKDgpO1xyXG5cdGxldCB0bXBmID0gbmV3IEZsb2F0MzJBcnJheSh0bXApO1xyXG5cdGxldCB0bXBkID0gbmV3IEZsb2F0NjRBcnJheSh0bXApO1xyXG5cdGxldCB0bXB1OCA9IG5ldyBVaW50OEFycmF5KHRtcCk7XHJcblxyXG5cdHRoaXMuZ2V0VWludDMyID0gZnVuY3Rpb24gKGkpIHtcclxuXHRcdHJldHVybiAodGhpcy51OFtpICsgM10gPDwgMjQpIHwgKHRoaXMudThbaSArIDJdIDw8IDE2KSB8ICh0aGlzLnU4W2kgKyAxXSA8PCA4KSB8IHRoaXMudThbaV07XHJcblx0fTtcclxuXHJcblx0dGhpcy5nZXRVaW50MTYgPSBmdW5jdGlvbiAoaSkge1xyXG5cdFx0cmV0dXJuICh0aGlzLnU4W2kgKyAxXSA8PCA4KSB8IHRoaXMudThbaV07XHJcblx0fTtcclxuXHJcblx0dGhpcy5nZXRGbG9hdDMyID0gZnVuY3Rpb24gKGkpIHtcclxuXHRcdHRtcHU4WzBdID0gdGhpcy51OFtpICsgMF07XHJcblx0XHR0bXB1OFsxXSA9IHRoaXMudThbaSArIDFdO1xyXG5cdFx0dG1wdThbMl0gPSB0aGlzLnU4W2kgKyAyXTtcclxuXHRcdHRtcHU4WzNdID0gdGhpcy51OFtpICsgM107XHJcblxyXG5cdFx0cmV0dXJuIHRtcGZbMF07XHJcblx0fTtcclxuXHJcblx0dGhpcy5nZXRGbG9hdDY0ID0gZnVuY3Rpb24gKGkpIHtcclxuXHRcdHRtcHU4WzBdID0gdGhpcy51OFtpICsgMF07XHJcblx0XHR0bXB1OFsxXSA9IHRoaXMudThbaSArIDFdO1xyXG5cdFx0dG1wdThbMl0gPSB0aGlzLnU4W2kgKyAyXTtcclxuXHRcdHRtcHU4WzNdID0gdGhpcy51OFtpICsgM107XHJcblx0XHR0bXB1OFs0XSA9IHRoaXMudThbaSArIDRdO1xyXG5cdFx0dG1wdThbNV0gPSB0aGlzLnU4W2kgKyA1XTtcclxuXHRcdHRtcHU4WzZdID0gdGhpcy51OFtpICsgNl07XHJcblx0XHR0bXB1OFs3XSA9IHRoaXMudThbaSArIDddO1xyXG5cclxuXHRcdHJldHVybiB0bXBkWzBdO1xyXG5cdH07XHJcblxyXG5cdHRoaXMuZ2V0VWludDggPSBmdW5jdGlvbiAoaSkge1xyXG5cdFx0cmV0dXJuIHRoaXMudThbaV07XHJcblx0fTtcclxufVxyXG5cclxub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcblxyXG5cdHBlcmZvcm1hbmNlLm1hcmsoXCJiaW5hcnktZGVjb2Rlci1zdGFydFwiKTtcclxuXHRcclxuXHRsZXQgYnVmZmVyID0gZXZlbnQuZGF0YS5idWZmZXI7XHJcblx0bGV0IHBvaW50QXR0cmlidXRlcyA9IGV2ZW50LmRhdGEucG9pbnRBdHRyaWJ1dGVzO1xyXG5cdGxldCBudW1Qb2ludHMgPSBidWZmZXIuYnl0ZUxlbmd0aCAvIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZTtcclxuXHRsZXQgY3YgPSBuZXcgQ3VzdG9tVmlldyhidWZmZXIpO1xyXG5cdGxldCB2ZXJzaW9uID0gbmV3IFZlcnNpb24oZXZlbnQuZGF0YS52ZXJzaW9uKTtcclxuXHRsZXQgbm9kZU9mZnNldCA9IGV2ZW50LmRhdGEub2Zmc2V0O1xyXG5cdGxldCBzY2FsZSA9IGV2ZW50LmRhdGEuc2NhbGU7XHJcblx0bGV0IHNwYWNpbmcgPSBldmVudC5kYXRhLnNwYWNpbmc7XHJcblx0bGV0IGhhc0NoaWxkcmVuID0gZXZlbnQuZGF0YS5oYXNDaGlsZHJlbjtcclxuXHRsZXQgbmFtZSA9IGV2ZW50LmRhdGEubmFtZTtcclxuXHRcclxuXHRsZXQgdGlnaHRCb3hNaW4gPSBbIE51bWJlci5QT1NJVElWRV9JTkZJTklUWSwgTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLCBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgXTtcclxuXHRsZXQgdGlnaHRCb3hNYXggPSBbIE51bWJlci5ORUdBVElWRV9JTkZJTklUWSwgTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLCBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgXTtcclxuXHRsZXQgbWVhbiA9IFswLCAwLCAwXTtcclxuXHRcclxuXHJcblx0bGV0IGF0dHJpYnV0ZUJ1ZmZlcnMgPSB7fTtcclxuXHRsZXQgaW5PZmZzZXQgPSAwO1xyXG5cdGZvciAobGV0IHBvaW50QXR0cmlidXRlIG9mIHBvaW50QXR0cmlidXRlcy5hdHRyaWJ1dGVzKSB7XHJcblx0XHRcclxuXHRcdGlmIChwb2ludEF0dHJpYnV0ZS5uYW1lID09PSBQb2ludEF0dHJpYnV0ZS5QT1NJVElPTl9DQVJURVNJQU4ubmFtZSkge1xyXG5cdFx0XHRsZXQgYnVmZiA9IG5ldyBBcnJheUJ1ZmZlcihudW1Qb2ludHMgKiA0ICogMyk7XHJcblx0XHRcdGxldCBwb3NpdGlvbnMgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmYpO1xyXG5cdFx0XHJcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgbnVtUG9pbnRzOyBqKyspIHtcclxuXHRcdFx0XHRsZXQgeCwgeSwgejtcclxuXHJcblx0XHRcdFx0aWYgKHZlcnNpb24ubmV3ZXJUaGFuKCcxLjMnKSkge1xyXG5cdFx0XHRcdFx0eCA9IChjdi5nZXRVaW50MzIoaW5PZmZzZXQgKyBqICogcG9pbnRBdHRyaWJ1dGVzLmJ5dGVTaXplICsgMCwgdHJ1ZSkgKiBzY2FsZSk7XHJcblx0XHRcdFx0XHR5ID0gKGN2LmdldFVpbnQzMihpbk9mZnNldCArIGogKiBwb2ludEF0dHJpYnV0ZXMuYnl0ZVNpemUgKyA0LCB0cnVlKSAqIHNjYWxlKTtcclxuXHRcdFx0XHRcdHogPSAoY3YuZ2V0VWludDMyKGluT2Zmc2V0ICsgaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSArIDgsIHRydWUpICogc2NhbGUpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR4ID0gY3YuZ2V0RmxvYXQzMihqICogcG9pbnRBdHRyaWJ1dGVzLmJ5dGVTaXplICsgMCwgdHJ1ZSkgKyBub2RlT2Zmc2V0WzBdO1xyXG5cdFx0XHRcdFx0eSA9IGN2LmdldEZsb2F0MzIoaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSArIDQsIHRydWUpICsgbm9kZU9mZnNldFsxXTtcclxuXHRcdFx0XHRcdHogPSBjdi5nZXRGbG9hdDMyKGogKiBwb2ludEF0dHJpYnV0ZXMuYnl0ZVNpemUgKyA4LCB0cnVlKSArIG5vZGVPZmZzZXRbMl07XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRwb3NpdGlvbnNbMyAqIGogKyAwXSA9IHg7XHJcblx0XHRcdFx0cG9zaXRpb25zWzMgKiBqICsgMV0gPSB5O1xyXG5cdFx0XHRcdHBvc2l0aW9uc1szICogaiArIDJdID0gejtcclxuXHJcblx0XHRcdFx0bWVhblswXSArPSB4IC8gbnVtUG9pbnRzO1xyXG5cdFx0XHRcdG1lYW5bMV0gKz0geSAvIG51bVBvaW50cztcclxuXHRcdFx0XHRtZWFuWzJdICs9IHogLyBudW1Qb2ludHM7XHJcblxyXG5cdFx0XHRcdHRpZ2h0Qm94TWluWzBdID0gTWF0aC5taW4odGlnaHRCb3hNaW5bMF0sIHgpO1xyXG5cdFx0XHRcdHRpZ2h0Qm94TWluWzFdID0gTWF0aC5taW4odGlnaHRCb3hNaW5bMV0sIHkpO1xyXG5cdFx0XHRcdHRpZ2h0Qm94TWluWzJdID0gTWF0aC5taW4odGlnaHRCb3hNaW5bMl0sIHopO1xyXG5cclxuXHRcdFx0XHR0aWdodEJveE1heFswXSA9IE1hdGgubWF4KHRpZ2h0Qm94TWF4WzBdLCB4KTtcclxuXHRcdFx0XHR0aWdodEJveE1heFsxXSA9IE1hdGgubWF4KHRpZ2h0Qm94TWF4WzFdLCB5KTtcclxuXHRcdFx0XHR0aWdodEJveE1heFsyXSA9IE1hdGgubWF4KHRpZ2h0Qm94TWF4WzJdLCB6KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0YXR0cmlidXRlQnVmZmVyc1twb2ludEF0dHJpYnV0ZS5uYW1lXSA9IHsgYnVmZmVyOiBidWZmLCBhdHRyaWJ1dGU6IHBvaW50QXR0cmlidXRlIH07XHJcblx0XHR9IGVsc2UgaWYgKHBvaW50QXR0cmlidXRlLm5hbWUgPT09IFBvaW50QXR0cmlidXRlLkNPTE9SX1BBQ0tFRC5uYW1lKSB7XHJcblx0XHRcdGxldCBidWZmID0gbmV3IEFycmF5QnVmZmVyKG51bVBvaW50cyAqIDQpO1xyXG5cdFx0XHRsZXQgY29sb3JzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZik7XHJcblxyXG5cdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IG51bVBvaW50czsgaisrKSB7XHJcblx0XHRcdFx0Y29sb3JzWzQgKiBqICsgMF0gPSBjdi5nZXRVaW50OChpbk9mZnNldCArIGogKiBwb2ludEF0dHJpYnV0ZXMuYnl0ZVNpemUgKyAwKTtcclxuXHRcdFx0XHRjb2xvcnNbNCAqIGogKyAxXSA9IGN2LmdldFVpbnQ4KGluT2Zmc2V0ICsgaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSArIDEpO1xyXG5cdFx0XHRcdGNvbG9yc1s0ICogaiArIDJdID0gY3YuZ2V0VWludDgoaW5PZmZzZXQgKyBqICogcG9pbnRBdHRyaWJ1dGVzLmJ5dGVTaXplICsgMik7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGF0dHJpYnV0ZUJ1ZmZlcnNbcG9pbnRBdHRyaWJ1dGUubmFtZV0gPSB7IGJ1ZmZlcjogYnVmZiwgYXR0cmlidXRlOiBwb2ludEF0dHJpYnV0ZSB9O1xyXG5cdFx0fSBlbHNlIGlmIChwb2ludEF0dHJpYnV0ZS5uYW1lID09PSBQb2ludEF0dHJpYnV0ZS5JTlRFTlNJVFkubmFtZSkge1xyXG5cdFx0XHRsZXQgYnVmZiA9IG5ldyBBcnJheUJ1ZmZlcihudW1Qb2ludHMgKiA0KTtcclxuXHRcdFx0bGV0IGludGVuc2l0aWVzID0gbmV3IEZsb2F0MzJBcnJheShidWZmKTtcclxuXHJcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgbnVtUG9pbnRzOyBqKyspIHtcclxuXHRcdFx0XHRsZXQgaW50ZW5zaXR5ID0gY3YuZ2V0VWludDE2KGluT2Zmc2V0ICsgaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSwgdHJ1ZSk7XHJcblx0XHRcdFx0aW50ZW5zaXRpZXNbal0gPSBpbnRlbnNpdHk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGF0dHJpYnV0ZUJ1ZmZlcnNbcG9pbnRBdHRyaWJ1dGUubmFtZV0gPSB7IGJ1ZmZlcjogYnVmZiwgYXR0cmlidXRlOiBwb2ludEF0dHJpYnV0ZSB9O1xyXG5cdFx0fSBlbHNlIGlmIChwb2ludEF0dHJpYnV0ZS5uYW1lID09PSBQb2ludEF0dHJpYnV0ZS5DTEFTU0lGSUNBVElPTi5uYW1lKSB7XHJcblx0XHRcdGxldCBidWZmID0gbmV3IEFycmF5QnVmZmVyKG51bVBvaW50cyk7XHJcblx0XHRcdGxldCBjbGFzc2lmaWNhdGlvbnMgPSBuZXcgVWludDhBcnJheShidWZmKTtcclxuXHJcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgbnVtUG9pbnRzOyBqKyspIHtcclxuXHRcdFx0XHRsZXQgY2xhc3NpZmljYXRpb24gPSBjdi5nZXRVaW50OChpbk9mZnNldCArIGogKiBwb2ludEF0dHJpYnV0ZXMuYnl0ZVNpemUpO1xyXG5cdFx0XHRcdGNsYXNzaWZpY2F0aW9uc1tqXSA9IGNsYXNzaWZpY2F0aW9uO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRhdHRyaWJ1dGVCdWZmZXJzW3BvaW50QXR0cmlidXRlLm5hbWVdID0geyBidWZmZXI6IGJ1ZmYsIGF0dHJpYnV0ZTogcG9pbnRBdHRyaWJ1dGUgfTtcclxuXHRcdH0gZWxzZSBpZiAocG9pbnRBdHRyaWJ1dGUubmFtZSA9PT0gUG9pbnRBdHRyaWJ1dGUuUkVUVVJOX05VTUJFUi5uYW1lKSB7XHJcblx0XHRcdGxldCBidWZmID0gbmV3IEFycmF5QnVmZmVyKG51bVBvaW50cyk7XHJcblx0XHRcdGxldCByZXR1cm5OdW1iZXJzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZik7XHJcblxyXG5cdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IG51bVBvaW50czsgaisrKSB7XHJcblx0XHRcdFx0bGV0IHJldHVybk51bWJlciA9IGN2LmdldFVpbnQ4KGluT2Zmc2V0ICsgaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSk7XHJcblx0XHRcdFx0cmV0dXJuTnVtYmVyc1tqXSA9IHJldHVybk51bWJlcjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0YXR0cmlidXRlQnVmZmVyc1twb2ludEF0dHJpYnV0ZS5uYW1lXSA9IHsgYnVmZmVyOiBidWZmLCBhdHRyaWJ1dGU6IHBvaW50QXR0cmlidXRlIH07XHJcblx0XHR9IGVsc2UgaWYgKHBvaW50QXR0cmlidXRlLm5hbWUgPT09IFBvaW50QXR0cmlidXRlLk5VTUJFUl9PRl9SRVRVUk5TLm5hbWUpIHtcclxuXHRcdFx0bGV0IGJ1ZmYgPSBuZXcgQXJyYXlCdWZmZXIobnVtUG9pbnRzKTtcclxuXHRcdFx0bGV0IG51bWJlck9mUmV0dXJucyA9IG5ldyBVaW50OEFycmF5KGJ1ZmYpO1xyXG5cclxuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBudW1Qb2ludHM7IGorKykge1xyXG5cdFx0XHRcdGxldCBudW1iZXJPZlJldHVybiA9IGN2LmdldFVpbnQ4KGluT2Zmc2V0ICsgaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSk7XHJcblx0XHRcdFx0bnVtYmVyT2ZSZXR1cm5zW2pdID0gbnVtYmVyT2ZSZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGF0dHJpYnV0ZUJ1ZmZlcnNbcG9pbnRBdHRyaWJ1dGUubmFtZV0gPSB7IGJ1ZmZlcjogYnVmZiwgYXR0cmlidXRlOiBwb2ludEF0dHJpYnV0ZSB9O1xyXG5cdFx0fSBlbHNlIGlmIChwb2ludEF0dHJpYnV0ZS5uYW1lID09PSBQb2ludEF0dHJpYnV0ZS5TT1VSQ0VfSUQubmFtZSkge1xyXG5cdFx0XHRsZXQgYnVmZiA9IG5ldyBBcnJheUJ1ZmZlcihudW1Qb2ludHMgKiAyKTtcclxuXHRcdFx0bGV0IHNvdXJjZUlEcyA9IG5ldyBVaW50MTZBcnJheShidWZmKTtcclxuXHJcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgbnVtUG9pbnRzOyBqKyspIHtcclxuXHRcdFx0XHRsZXQgc291cmNlSUQgPSBjdi5nZXRVaW50MTYoaW5PZmZzZXQgKyBqICogcG9pbnRBdHRyaWJ1dGVzLmJ5dGVTaXplKTtcclxuXHRcdFx0XHRzb3VyY2VJRHNbal0gPSBzb3VyY2VJRDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0YXR0cmlidXRlQnVmZmVyc1twb2ludEF0dHJpYnV0ZS5uYW1lXSA9IHsgYnVmZmVyOiBidWZmLCBhdHRyaWJ1dGU6IHBvaW50QXR0cmlidXRlIH07XHJcblx0XHR9IGVsc2UgaWYgKHBvaW50QXR0cmlidXRlLm5hbWUgPT09IFBvaW50QXR0cmlidXRlLk5PUk1BTF9TUEhFUkVNQVBQRUQubmFtZSkge1xyXG5cdFx0XHRsZXQgYnVmZiA9IG5ldyBBcnJheUJ1ZmZlcihudW1Qb2ludHMgKiA0ICogMyk7XHJcblx0XHRcdGxldCBub3JtYWxzID0gbmV3IEZsb2F0MzJBcnJheShidWZmKTtcclxuXHJcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgbnVtUG9pbnRzOyBqKyspIHtcclxuXHRcdFx0XHRsZXQgYnggPSBjdi5nZXRVaW50OChpbk9mZnNldCArIGogKiBwb2ludEF0dHJpYnV0ZXMuYnl0ZVNpemUgKyAwKTtcclxuXHRcdFx0XHRsZXQgYnkgPSBjdi5nZXRVaW50OChpbk9mZnNldCArIGogKiBwb2ludEF0dHJpYnV0ZXMuYnl0ZVNpemUgKyAxKTtcclxuXHJcblx0XHRcdFx0bGV0IGV4ID0gYnggLyAyNTU7XHJcblx0XHRcdFx0bGV0IGV5ID0gYnkgLyAyNTU7XHJcblxyXG5cdFx0XHRcdGxldCBueCA9IGV4ICogMiAtIDE7XHJcblx0XHRcdFx0bGV0IG55ID0gZXkgKiAyIC0gMTtcclxuXHRcdFx0XHRsZXQgbnogPSAxO1xyXG5cdFx0XHRcdGxldCBudyA9IC0xO1xyXG5cclxuXHRcdFx0XHRsZXQgbCA9IChueCAqICgtbngpKSArIChueSAqICgtbnkpKSArIChueiAqICgtbncpKTtcclxuXHRcdFx0XHRueiA9IGw7XHJcblx0XHRcdFx0bnggPSBueCAqIE1hdGguc3FydChsKTtcclxuXHRcdFx0XHRueSA9IG55ICogTWF0aC5zcXJ0KGwpO1xyXG5cclxuXHRcdFx0XHRueCA9IG54ICogMjtcclxuXHRcdFx0XHRueSA9IG55ICogMjtcclxuXHRcdFx0XHRueiA9IG56ICogMiAtIDE7XHJcblxyXG5cdFx0XHRcdG5vcm1hbHNbMyAqIGogKyAwXSA9IG54O1xyXG5cdFx0XHRcdG5vcm1hbHNbMyAqIGogKyAxXSA9IG55O1xyXG5cdFx0XHRcdG5vcm1hbHNbMyAqIGogKyAyXSA9IG56O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRhdHRyaWJ1dGVCdWZmZXJzW3BvaW50QXR0cmlidXRlLm5hbWVdID0geyBidWZmZXI6IGJ1ZmYsIGF0dHJpYnV0ZTogcG9pbnRBdHRyaWJ1dGUgfTtcclxuXHRcdH0gZWxzZSBpZiAocG9pbnRBdHRyaWJ1dGUubmFtZSA9PT0gUG9pbnRBdHRyaWJ1dGUuTk9STUFMX09DVDE2Lm5hbWUpIHtcclxuXHRcdFx0bGV0IGJ1ZmYgPSBuZXcgQXJyYXlCdWZmZXIobnVtUG9pbnRzICogNCAqIDMpO1xyXG5cdFx0XHRsZXQgbm9ybWFscyA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZik7XHJcblxyXG5cdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IG51bVBvaW50czsgaisrKSB7XHJcblx0XHRcdFx0bGV0IGJ4ID0gY3YuZ2V0VWludDgoaW5PZmZzZXQgKyBqICogcG9pbnRBdHRyaWJ1dGVzLmJ5dGVTaXplICsgMCk7XHJcblx0XHRcdFx0bGV0IGJ5ID0gY3YuZ2V0VWludDgoaW5PZmZzZXQgKyBqICogcG9pbnRBdHRyaWJ1dGVzLmJ5dGVTaXplICsgMSk7XHJcblxyXG5cdFx0XHRcdGxldCB1ID0gKGJ4IC8gMjU1KSAqIDIgLSAxO1xyXG5cdFx0XHRcdGxldCB2ID0gKGJ5IC8gMjU1KSAqIDIgLSAxO1xyXG5cclxuXHRcdFx0XHRsZXQgeiA9IDEgLSBNYXRoLmFicyh1KSAtIE1hdGguYWJzKHYpO1xyXG5cclxuXHRcdFx0XHRsZXQgeCA9IDA7XHJcblx0XHRcdFx0bGV0IHkgPSAwO1xyXG5cdFx0XHRcdGlmICh6ID49IDApIHtcclxuXHRcdFx0XHRcdHggPSB1O1xyXG5cdFx0XHRcdFx0eSA9IHY7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHggPSAtKHYgLyBNYXRoLnNpZ24odikgLSAxKSAvIE1hdGguc2lnbih1KTtcclxuXHRcdFx0XHRcdHkgPSAtKHUgLyBNYXRoLnNpZ24odSkgLSAxKSAvIE1hdGguc2lnbih2KTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGxldCBsZW5ndGggPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSArIHogKiB6KTtcclxuXHRcdFx0XHR4ID0geCAvIGxlbmd0aDtcclxuXHRcdFx0XHR5ID0geSAvIGxlbmd0aDtcclxuXHRcdFx0XHR6ID0geiAvIGxlbmd0aDtcclxuXHRcdFx0XHRcclxuXHRcdFx0XHRub3JtYWxzWzMgKiBqICsgMF0gPSB4O1xyXG5cdFx0XHRcdG5vcm1hbHNbMyAqIGogKyAxXSA9IHk7XHJcblx0XHRcdFx0bm9ybWFsc1szICogaiArIDJdID0gejtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0YXR0cmlidXRlQnVmZmVyc1twb2ludEF0dHJpYnV0ZS5uYW1lXSA9IHsgYnVmZmVyOiBidWZmLCBhdHRyaWJ1dGU6IHBvaW50QXR0cmlidXRlIH07XHJcblx0XHR9IGVsc2UgaWYgKHBvaW50QXR0cmlidXRlLm5hbWUgPT09IFBvaW50QXR0cmlidXRlLk5PUk1BTC5uYW1lKSB7XHJcblx0XHRcdGxldCBidWZmID0gbmV3IEFycmF5QnVmZmVyKG51bVBvaW50cyAqIDQgKiAzKTtcclxuXHRcdFx0bGV0IG5vcm1hbHMgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmYpO1xyXG5cclxuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBudW1Qb2ludHM7IGorKykge1xyXG5cdFx0XHRcdGxldCB4ID0gY3YuZ2V0RmxvYXQzMihpbk9mZnNldCArIGogKiBwb2ludEF0dHJpYnV0ZXMuYnl0ZVNpemUgKyAwLCB0cnVlKTtcclxuXHRcdFx0XHRsZXQgeSA9IGN2LmdldEZsb2F0MzIoaW5PZmZzZXQgKyBqICogcG9pbnRBdHRyaWJ1dGVzLmJ5dGVTaXplICsgNCwgdHJ1ZSk7XHJcblx0XHRcdFx0bGV0IHogPSBjdi5nZXRGbG9hdDMyKGluT2Zmc2V0ICsgaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSArIDgsIHRydWUpO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdG5vcm1hbHNbMyAqIGogKyAwXSA9IHg7XHJcblx0XHRcdFx0bm9ybWFsc1szICogaiArIDFdID0geTtcclxuXHRcdFx0XHRub3JtYWxzWzMgKiBqICsgMl0gPSB6O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRhdHRyaWJ1dGVCdWZmZXJzW3BvaW50QXR0cmlidXRlLm5hbWVdID0geyBidWZmZXI6IGJ1ZmYsIGF0dHJpYnV0ZTogcG9pbnRBdHRyaWJ1dGUgfTtcclxuXHRcdH0gZWxzZSBpZiAocG9pbnRBdHRyaWJ1dGUubmFtZSA9PT0gUG9pbnRBdHRyaWJ1dGUuR1BTX1RJTUUubmFtZSkge1xyXG5cdFx0XHRsZXQgYnVmZiA9IG5ldyBBcnJheUJ1ZmZlcihudW1Qb2ludHMgKiA4KTtcclxuXHRcdFx0bGV0IGdwc3RpbWVzID0gbmV3IEZsb2F0NjRBcnJheShidWZmKTtcclxuXHJcblx0XHRcdGZvcihsZXQgaiA9IDA7IGogPCBudW1Qb2ludHM7IGorKyl7XHJcblx0XHRcdFx0bGV0IGdwc3RpbWUgPSBjdi5nZXRGbG9hdDY0KGluT2Zmc2V0ICsgaiAqIHBvaW50QXR0cmlidXRlcy5ieXRlU2l6ZSwgdHJ1ZSk7XHJcblx0XHRcdFx0Z3BzdGltZXNbal0gPSBncHN0aW1lO1xyXG5cdFx0XHR9XHJcblx0XHRcdGF0dHJpYnV0ZUJ1ZmZlcnNbcG9pbnRBdHRyaWJ1dGUubmFtZV0gPSB7IGJ1ZmZlcjogYnVmZiwgYXR0cmlidXRlOiBwb2ludEF0dHJpYnV0ZSB9O1xyXG5cdFx0fVxyXG5cclxuXHRcdGluT2Zmc2V0ICs9IHBvaW50QXR0cmlidXRlLmJ5dGVTaXplO1xyXG5cdH1cclxuXHJcblx0Ly8gQ29udmVydCBHUFMgdGltZSBmcm9tIGRvdWJsZSAodW5zdXBwb3J0ZWQgYnkgV2ViR0wpIHRvIG9yaWdpbi1hbGlnbmVkIGZsb2F0c1xyXG5cdGlmKGF0dHJpYnV0ZUJ1ZmZlcnNbUG9pbnRBdHRyaWJ1dGUuR1BTX1RJTUUubmFtZV0peyBcclxuXHRcdGxldCBhdHRyaWJ1dGUgPSBhdHRyaWJ1dGVCdWZmZXJzW1BvaW50QXR0cmlidXRlLkdQU19USU1FLm5hbWVdO1xyXG5cdFx0bGV0IHNvdXJjZUY2NCA9IG5ldyBGbG9hdDY0QXJyYXkoYXR0cmlidXRlLmJ1ZmZlcik7XHJcblx0XHRsZXQgdGFyZ2V0ID0gbmV3IEFycmF5QnVmZmVyKG51bVBvaW50cyAqIDQpO1xyXG5cdFx0bGV0IHRhcmdldEYzMiA9IG5ldyBGbG9hdDMyQXJyYXkodGFyZ2V0KTtcclxuXHJcblx0XHRsZXQgbWluID0gSW5maW5pdHk7XHJcblx0XHRsZXQgbWF4ID0gLUluZmluaXR5O1xyXG5cdFx0Zm9yKGxldCBpID0gMDsgaSA8IG51bVBvaW50czsgaSsrKXtcclxuXHRcdFx0bGV0IGdwc3RpbWUgPSBzb3VyY2VGNjRbaV07XHJcblxyXG5cdFx0XHRtaW4gPSBNYXRoLm1pbihtaW4sIGdwc3RpbWUpO1xyXG5cdFx0XHRtYXggPSBNYXRoLm1heChtYXgsIGdwc3RpbWUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvcihsZXQgaSA9IDA7IGkgPCBudW1Qb2ludHM7IGkrKyl7XHJcblx0XHRcdGxldCBncHN0aW1lID0gc291cmNlRjY0W2ldO1xyXG5cdFx0XHR0YXJnZXRGMzJbaV0gPSBncHN0aW1lIC0gbWluO1xyXG5cdFx0fVxyXG5cclxuXHRcdGF0dHJpYnV0ZUJ1ZmZlcnNbUG9pbnRBdHRyaWJ1dGUuR1BTX1RJTUUubmFtZV0gPSB7IFxyXG5cdFx0XHRidWZmZXI6IHRhcmdldCwgXHJcblx0XHRcdGF0dHJpYnV0ZTogUG9pbnRBdHRyaWJ1dGUuR1BTX1RJTUUsXHJcblx0XHRcdG9mZnNldDogbWluLFxyXG5cdFx0XHRyYW5nZTogbWF4IC0gbWlufTtcclxuXHR9XHJcblxyXG5cdC8vbGV0IGRlYnVnTm9kZXMgPSBbXCJyMDI2XCIsIFwicjAyMjZcIixcInIwMjI3NFwiXTtcclxuXHQvL2lmKGRlYnVnTm9kZXMuaW5jbHVkZXMobmFtZSkpe1xyXG5cdGlmKGZhbHNlKXtcclxuXHRcdGNvbnNvbGUubG9nKFwiZXN0aW1hdGUgc3BhY2luZyFcIik7XHJcblxyXG5cclxuXHRcdGxldCBzcGFyc2VHcmlkID0gbmV3IE1hcCgpO1xyXG5cdFx0bGV0IGdyaWRTaXplID0gMTY7XHJcblxyXG5cdFx0bGV0IHRpZ2h0Qm94U2l6ZSA9IHRpZ2h0Qm94TWF4Lm1hcCggKGEsIGkpID0+IGEgLSB0aWdodEJveE1pbltpXSk7XHJcblx0XHRsZXQgY3ViZUxlbmd0aCA9IE1hdGgubWF4KC4uLnRpZ2h0Qm94U2l6ZSk7XHJcblx0XHRsZXQgY3ViZSA9IHtcclxuXHRcdFx0bWluOiB0aWdodEJveE1pbixcclxuXHRcdFx0bWF4OiB0aWdodEJveE1pbi5tYXAodiA9PiB2ICsgY3ViZUxlbmd0aClcclxuXHRcdH07XHJcblxyXG5cdFx0bGV0IHBvc2l0aW9ucyA9IG5ldyBGbG9hdDMyQXJyYXkoYXR0cmlidXRlQnVmZmVyc1tQb2ludEF0dHJpYnV0ZS5QT1NJVElPTl9DQVJURVNJQU4ubmFtZV0uYnVmZmVyKTtcclxuXHRcdGZvcihsZXQgaSA9IDA7IGkgPCBudW1Qb2ludHM7IGkrKyl7XHJcblx0XHRcdGxldCB4ID0gcG9zaXRpb25zWzMgKiBpICsgMF07XHJcblx0XHRcdGxldCB5ID0gcG9zaXRpb25zWzMgKiBpICsgMV07XHJcblx0XHRcdGxldCB6ID0gcG9zaXRpb25zWzMgKiBpICsgMl07XHJcblxyXG5cdFx0XHRsZXQgaXggPSBNYXRoLm1heCgwLCBNYXRoLm1pbihncmlkU2l6ZSAqICh4IC0gY3ViZS5taW5bMF0pIC8gY3ViZUxlbmd0aCwgZ3JpZFNpemUgLSAxKSk7XHJcblx0XHRcdGxldCBpeSA9IE1hdGgubWF4KDAsIE1hdGgubWluKGdyaWRTaXplICogKHkgLSBjdWJlLm1pblsxXSkgLyBjdWJlTGVuZ3RoLCBncmlkU2l6ZSAtIDEpKTtcclxuXHRcdFx0bGV0IGl6ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oZ3JpZFNpemUgKiAoeiAtIGN1YmUubWluWzJdKSAvIGN1YmVMZW5ndGgsIGdyaWRTaXplIC0gMSkpO1xyXG5cclxuXHRcdFx0aXggPSBNYXRoLmZsb29yKGl4KTtcclxuXHRcdFx0aXkgPSBNYXRoLmZsb29yKGl5KTtcclxuXHRcdFx0aXogPSBNYXRoLmZsb29yKGl6KTtcclxuXHJcblx0XHRcdGxldCBjZWxsSW5kZXggPSBpeCB8IChpeSA8PCA4KSB8IChpeiA8PCAxNik7XHJcblx0XHRcdFxyXG5cdFx0XHRpZighc3BhcnNlR3JpZC5oYXMoY2VsbEluZGV4KSl7XHJcblx0XHRcdFx0c3BhcnNlR3JpZC5zZXQoY2VsbEluZGV4LCBbXSk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHNwYXJzZUdyaWQuZ2V0KGNlbGxJbmRleCkucHVzaChpKTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQga05lYXJlc3QgPSAocG9pbnRJbmRleCwgY2FuZGlkYXRlcywgbnVtTmVhcmVzdCkgPT4ge1xyXG5cdFx0XHRcclxuXHRcdFx0bGV0IHggPSBwb3NpdGlvbnNbMyAqIHBvaW50SW5kZXggKyAwXTtcclxuXHRcdFx0bGV0IHkgPSBwb3NpdGlvbnNbMyAqIHBvaW50SW5kZXggKyAxXTtcclxuXHRcdFx0bGV0IHogPSBwb3NpdGlvbnNbMyAqIHBvaW50SW5kZXggKyAyXTtcclxuXHJcblx0XHRcdGxldCBjYW5kaWRhdGVEaXN0YW5jZXMgPSBbXTtcclxuXHJcblx0XHRcdGZvcihsZXQgY2FuZGlkYXRlSW5kZXggb2YgY2FuZGlkYXRlcyl7XHJcblx0XHRcdFx0aWYoY2FuZGlkYXRlSW5kZXggPT09IHBvaW50SW5kZXgpe1xyXG5cdFx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRsZXQgY3ggPSBwb3NpdGlvbnNbMyAqIGNhbmRpZGF0ZUluZGV4ICsgMF07XHJcblx0XHRcdFx0bGV0IGN5ID0gcG9zaXRpb25zWzMgKiBjYW5kaWRhdGVJbmRleCArIDFdO1xyXG5cdFx0XHRcdGxldCBjeiA9IHBvc2l0aW9uc1szICogY2FuZGlkYXRlSW5kZXggKyAyXTtcclxuXHJcblx0XHRcdFx0bGV0IHNxdWFyZWREaXN0YW5jZSA9IChjeCAtIHgpICoqIDIgKyAoY3kgLSB5KSAqKiAyICsgKGN6IC0geikgKiogMjtcclxuXHJcblx0XHRcdFx0Y2FuZGlkYXRlRGlzdGFuY2VzLnB1c2goe2NhbmRpZGF0ZUluZGU6IGNhbmRpZGF0ZUluZGV4LCBzcXVhcmVkRGlzdGFuY2U6IHNxdWFyZWREaXN0YW5jZX0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjYW5kaWRhdGVEaXN0YW5jZXMuc29ydCg