@antv/layout 1.0.0-alpha.0 → 1.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +0,0 @@
1
- (()=>{"use strict";var e={d:(t,r)=>{for(var a in r)e.o(r,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:r[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{calculateLayout:()=>f});class r{nodeMap=new Map;edgeMap=new Map;inEdgesMap=new Map;outEdgesMap=new Map;treeIndices=new Map;changes=[];batchCount=0;onChanged=()=>{};constructor(e){e&&(e.nodes&&this.addNodes(e.nodes),e.edges&&this.addEdges(e.edges),e.tree&&this.addTree(e.tree),e.onChanged&&(this.onChanged=e.onChanged))}batch=e=>{this.batchCount+=1,e(),this.batchCount-=1,this.batchCount||this.commit()};commit(){const e=this.changes;this.changes=[],this.onChanged({graph:this,changes:e})}reduceChanges(e){let t=[];return e.forEach((e=>{switch(e.type){case"NodeRemoved":{let r=!1;t=t.filter((t=>{if("NodeAdded"===t.type){const a=t.value.id===e.value.id;return a&&(r=!0),!a}return"NodeDataUpdated"===t.type?t.id!==e.value.id:"TreeStructureChanged"!==t.type||t.nodeId!==e.value.id})),r||t.push(e);break}case"EdgeRemoved":{let r=!1;t=t.filter((t=>{if("EdgeAdded"===t.type){const a=t.value.id===e.value.id;return a&&(r=!0),!a}return"EdgeDataUpdated"!==t.type&&"EdgeUpdated"!==t.type||t.id!==e.value.id})),r||t.push(e);break}case"NodeDataUpdated":case"EdgeDataUpdated":case"EdgeUpdated":{const r=t.find((t=>t.type===e.type&&t.id===e.id&&t.propertyName===e.propertyName));r?r.newValue=e.newValue:t.push(e);break}case"TreeStructureDetached":t=t.filter((t=>"TreeStructureAttached"===t.type?t.treeKey!==e.treeKey:"TreeStructureChanged"!==t.type||t.treeKey!==e.treeKey)),t.push(e);break;case"TreeStructureChanged":{const r=t.find((t=>"TreeStructureChanged"===t.type&&t.treeKey===e.treeKey&&t.nodeId===e.nodeId));r?r.newParentId=e.newParentId:t.push(e);break}default:t.push(e)}})),t}checkNodeExistence(e){if(!this.hasNode(e))throw new Error("Node not found for id: "+e)}hasNode(e){return this.nodeMap.has(e)}areNeighbors(e,t){return this.checkNodeExistence(e),this.getNeighbors(t).some((t=>t.id===e))}getNode(e){return this.checkNodeExistence(e),this.nodeMap.get(e)}getRelatedEdges(e,t){this.checkNodeExistence(e);const r=this.inEdgesMap.get(e),a=this.outEdgesMap.get(e);if("in"===t)return Array.from(r);if("out"===t)return Array.from(a);const d=new Set([...r,...a]);return Array.from(d)}getDegree(e,t){return this.getRelatedEdges(e,t).length}getSuccessors(e){const t=this.getRelatedEdges(e,"out").map((e=>e.target));return Array.from(new Set(t)).map((e=>this.getNode(e)))}getPredecessors(e){const t=this.getRelatedEdges(e,"in").map((e=>e.source));return Array.from(new Set(t)).map((e=>this.getNode(e)))}getNeighbors(e){const t=this.getPredecessors(e),r=this.getSuccessors(e);return Array.from(new Set([...t,...r]))}doAddNode(e){if(this.hasNode(e.id))throw new Error("Node already exists: "+e.id);this.nodeMap.set(e.id,e),this.inEdgesMap.set(e.id,new Set),this.outEdgesMap.set(e.id,new Set),this.treeIndices.forEach((t=>{t.childrenMap.set(e.id,new Set)})),this.changes.push({type:"NodeAdded",value:e})}addNodes(e){this.batch((()=>{for(const t of e)this.doAddNode(t)}))}addNode(e){this.addNodes([e])}doRemoveNode(e){const t=this.getNode(e),r=this.inEdgesMap.get(e),a=this.outEdgesMap.get(e);r?.forEach((e=>this.doRemoveEdge(e.id))),a?.forEach((e=>this.doRemoveEdge(e.id))),this.nodeMap.delete(e),this.treeIndices.forEach((t=>{t.childrenMap.get(e)?.forEach((e=>{t.parentMap.delete(e.id)})),t.parentMap.delete(e),t.childrenMap.delete(e)})),this.changes.push({type:"NodeRemoved",value:t})}removeNodes(e){this.batch((()=>{e.forEach((e=>this.doRemoveNode(e)))}))}removeNode(e){this.removeNodes([e])}updateNodeData(e,t,r){const a=this.getNode(e);this.batch((()=>{const d=a.data[t],s=r;a.data[t]=s,this.changes.push({type:"NodeDataUpdated",id:e,propertyName:t,oldValue:d,newValue:s})}))}mergeNodeData(e,t){this.batch((()=>{Object.entries(t).forEach((([t,r])=>{this.updateNodeData(e,t,r)}))}))}checkEdgeExistence(e){if(!this.hasEdge(e))throw new Error("Edge not found for id: "+e)}hasEdge(e){return this.edgeMap.has(e)}getEdge(e){return this.checkEdgeExistence(e),this.edgeMap.get(e)}getEdgeDetail(e){const t=this.getEdge(e);return{edge:t,source:this.getNode(t.source),target:this.getNode(t.target)}}doAddEdge(e){if(this.hasEdge(e.id))throw new Error("Edge already exists: "+e.id);this.checkNodeExistence(e.source),this.checkNodeExistence(e.target),this.edgeMap.set(e.id,e);const t=this.inEdgesMap.get(e.target),r=this.outEdgesMap.get(e.source);t.add(e),r.add(e),this.changes.push({type:"EdgeAdded",value:e})}addEdges(e){this.batch((()=>{for(const t of e)this.doAddEdge(t)}))}addEdge(e){this.addEdges([e])}doRemoveEdge(e){const t=this.getEdge(e),r=this.outEdgesMap.get(t.source),a=this.inEdgesMap.get(t.target);r.delete(t),a.delete(t),this.edgeMap.delete(e),this.changes.push({type:"EdgeRemoved",value:t})}removeEdges(e){this.batch((()=>{e.forEach((e=>this.doRemoveEdge(e)))}))}removeEdge(e){this.removeEdges([e])}updateEdgeSource(e,t){const r=this.getEdge(e);this.checkNodeExistence(t);const a=r.source,d=t;this.outEdgesMap.get(a).delete(r),this.outEdgesMap.get(d).add(r),r.source=t,this.batch((()=>{this.changes.push({type:"EdgeUpdated",id:e,propertyName:"source",oldValue:a,newValue:d})}))}updateEdgeTarget(e,t){const r=this.getEdge(e);this.checkNodeExistence(t);const a=r.target,d=t;this.inEdgesMap.get(a).delete(r),this.inEdgesMap.get(d).add(r),r.target=t,this.batch((()=>{this.changes.push({type:"EdgeUpdated",id:e,propertyName:"target",oldValue:a,newValue:d})}))}updateEdgeData(e,t,r){const a=this.getEdge(e);this.batch((()=>{const d=a.data[t],s=r;a.data[t]=s,this.changes.push({type:"EdgeDataUpdated",id:e,propertyName:t,oldValue:d,newValue:s})}))}mergeEdgeData(e,t){this.batch((()=>{Object.entries(t).forEach((([t,r])=>{this.updateEdgeData(e,t,r)}))}))}checkTreeExistence(e){if(!this.treeIndices.has(e))throw new Error("Tree structure not found for treeKey: "+e)}attachTreeStructure(e){this.treeIndices.has(e)||(this.treeIndices.set(e,{parentMap:new Map,childrenMap:new Map}),this.batch((()=>{this.changes.push({type:"TreeStructureAttached",treeKey:e})})))}detachTreeStructure(e){this.checkTreeExistence(e),this.treeIndices.delete(e),this.batch((()=>{this.changes.push({type:"TreeStructureDetached",treeKey:e})}))}addTree(e,t){this.batch((()=>{this.attachTreeStructure(t);const r=[],a=Array.isArray(e)?e:[e];for(;a.length;){const e=a.shift();r.push(e),e.children&&a.push(...e.children)}this.addNodes(r),r.forEach((e=>{e.children?.forEach((r=>{this.setParent(r.id,e.id,t)}))}))}))}getRoots(e){return this.checkTreeExistence(e),this.getAllNodes().filter((t=>!this.getParent(t.id,e)))}getChildren(e,t){this.checkNodeExistence(e),this.checkTreeExistence(t);const r=this.treeIndices.get(t).childrenMap.get(e);return Array.from(r||[])}getParent(e,t){return this.checkNodeExistence(e),this.checkTreeExistence(t),this.treeIndices.get(t).parentMap.get(e)||null}setParent(e,t,r){this.checkTreeExistence(r);const a=this.treeIndices.get(r),d=this.getNode(e),s=a.parentMap.get(e),n=this.getNode(t);a.parentMap.set(e,n),s&&a.childrenMap.get(s.id)?.delete(d);let i=a.childrenMap.get(n.id);i||(i=new Set,a.childrenMap.set(n.id,i)),i.add(d),this.batch((()=>{this.changes.push({type:"TreeStructureChanged",treeKey:r,nodeId:e,oldParentId:s?.id,newParentId:n.id})}))}getAllNodes(){return Array.from(this.nodeMap.values())}getAllEdges(){return Array.from(this.edgeMap.values())}doBFS(e,t,r){for(;e.length;){const a=e.shift();r(a),t.add(a.id),this.getSuccessors(a.id).forEach((r=>{t.has(r.id)||(t.add(r.id),e.push(r))}))}}bfs(e,t){this.doBFS([this.getNode(e)],new Set,t)}doDFS(e,t,r){r(e),t.add(e.id),this.getSuccessors(e.id).forEach((e=>{t.has(e.id)||this.doDFS(e,t,r)}))}dfs(e,t){this.doDFS(this.getNode(e),new Set,t)}clone(){const e=this.getAllNodes().map((e=>({...e,data:{...e.data}}))),t=this.getAllEdges().map((e=>({...e,data:{...e.data}}))),a=new r({nodes:e,edges:t});return this.treeIndices.forEach((({parentMap:e,childrenMap:t},r)=>{const d=new Map;e.forEach(((e,t)=>{d.set(t,a.getNode(e.id))}));const s=new Map;t.forEach(((e,t)=>{s.set(t,new Set(Array.from(e).map((e=>a.getNode(e.id)))))})),a.treeIndices.set(r,{parentMap:d,childrenMap:s})})),a}toJSON(){return JSON.stringify({nodes:this.getAllNodes(),edges:this.getAllEdges()})}}var a=function(){return a=Object.assign||function(e){for(var t,r=1,a=arguments.length;r<a;r++)for(var d in t=arguments[r])Object.prototype.hasOwnProperty.call(t,d)&&(e[d]=t[d]);return e},a.apply(this,arguments)};function d(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var a,d,s=r.call(e),n=[];try{for(;(void 0===t||t-- >0)&&!(a=s.next()).done;)n.push(a.value)}catch(e){d={error:e}}finally{try{a&&!a.done&&(r=s.return)&&r.call(s)}finally{if(d)throw d.error}}return n}Object.create,Object.create;var s=/-(\w)/g,n=(function(e){return e.replace(s,(function(e,t){return t?t.toUpperCase():""}))},Object.create(null),Array.isArray),i=function(e){return null!==e&&"object"==typeof e},o=function(e){if(null===e)return e;if(e instanceof Date)return new Date(e.getTime());if(e instanceof Array){var t=[];return e.forEach((function(e){t.push(e)})),t.map((function(e){return o(e)}))}if("object"==typeof e&&Object.keys(e).length){var r=a({},e);return Object.keys(r).forEach((function(e){r[e]=o(r[e])})),r}return e},h=function(e,t){var r=e[t];return i(r)?r.cell:r},c=function(e,t,r){return void 0===r&&(r=!0),t||0===t?"function"==typeof t?t:"number"==typeof t?function(){return t}:n(t)?function(){if(r){var a=Math.max.apply(Math,function(e,t,r){if(r||2===arguments.length)for(var a,d=0,s=t.length;d<s;d++)!a&&d in t||(a||(a=Array.prototype.slice.call(t,0,d)),a[d]=t[d]);return e.concat(a||Array.prototype.slice.call(t))}([],d(t),!1));return isNaN(a)?e:a}return t}:i(t)?function(){if(r){var a=Math.max(t.width,t.height);return isNaN(a)?e:a}return[t.width,t.height]}:function(){return e}:function(t){return t.size?n(t.size)?t.size[0]>t.size[1]?t.size[0]:t.size[1]:i(t.size)?t.size.width>t.size.height?t.size.width:t.size.height:t.size:e}},u={radius:null,startRadius:null,endRadius:null,startAngle:0,endAngle:2*Math.PI,clockwise:!0,divisions:1,ordering:null,angleRatio:1};function g(e,t){var r=e.degree,a=t.degree;return r<a?-1:r>a?1:0}function p(e,t,r,a,d){void 0===d&&(d=!1);var s=o(t),n=[s[0]],i=[t[0]],c=[],u=t.length;c[0]=!0,function(e,t,r,a){e.forEach((function(t,r){e[r].children=[],e[r].parent=[]})),a?t.forEach((function(t){var a=h(t,"source"),d=h(t,"target"),s=0;a&&(s=r[a]);var n=0;d&&(n=r[d]);var i=e[s].children,o=e[n].parent;i.push(e[n].id),o.push(e[s].id)})):t.forEach((function(t){var a=h(t,"source"),d=h(t,"target"),s=0;a&&(s=r[a]);var n=0;d&&(n=r[d]);var i=e[s].children,o=e[n].children;i.push(e[n].id),o.push(e[s].id)}))}(s,r,a,d);var g=0;return s.forEach((function(d,o){if(0!==o)if(o!==u-1&&e[o].all===e[o+1].all&&!function(e,t,r){for(var a=r.length,d=0;d<a;d++){var s=h(r[d],"source"),n=h(r[d],"target");if(e.id===s&&t.id===n||t.id===s&&e.id===n)return!0}return!1}(n[g],d,r)||c[o]){for(var p=n[g].children,l=!1,f=0;f<p.length;f++){var E=a[p[f]];if(e[E].all===e[o].all&&!c[E]){n.push(s[E]),i.push(t[a[s[E].id]]),c[E]=!0,l=!0;break}}for(var y=0;!l&&(c[y]||(n.push(s[y]),i.push(t[a[s[y].id]]),c[y]=!0,l=!0),++y!==u););}else n.push(d),i.push(t[a[d.id]]),c[o]=!0,g++})),i}var l={circular:function(){function e(e){void 0===e&&(e={}),this.options=e,this.id="circular",Object.assign(this.options,u,e)}return e.prototype.execute=function(e,t){return this.genericCircularLayout(!1,e,t)},e.prototype.assign=function(e,t){var r=this;e.batch((function(){r.genericCircularLayout(!0,e,t)}))},e.prototype.genericCircularLayout=function(e,t,r){var s=a(a({},this.options),r),n=s.width,i=s.height,o=s.center,u=s.divisions,l=s.startAngle,f=void 0===l?0:l,E=s.endAngle,y=void 0===E?2*Math.PI:E,v=s.angleRatio,N=s.ordering,M=s.clockwise,w=s.nodeSpacing,m=s.nodeSize,b=s.onLayoutEnd,A=t.getAllNodes(),S=t.getAllEdges(),k=A.length;if(0===k)return b&&b(),{nodes:[],edges:[]};var x=d(function(e,t,r){var a=e,d=t,s=r;return a||"undefined"==typeof window||(a=window.innerWidth),d||"undefined"==typeof window||(d=window.innerHeight),s||(s=[a/2,d/2]),[a,d,s]}(n,i,o),3),I=x[0],R=x[1],C=x[2];if(1===k)return e&&(t.updateNodeData(A[0].id,"x",C[0]),t.updateNodeData(A[0].id,"y",C[1])),b&&b(),{nodes:[{id:"".concat(A[0].id),x:C[0],y:C[1]}],edges:[]};var D=(y-f)/k,P={};A.forEach((function(e,t){P[e.id]=t}));var T=function(e,t,r){for(var a=[],d=0;d<e;d++)a[d]={in:0,out:0,all:0};return r?(r.forEach((function(e){var r=h(e,"source"),d=h(e,"target");r&&a[t[r]]&&(a[t[r]].out+=1,a[t[r]].all+=1),d&&a[t[d]]&&(a[t[d]].in+=1,a[t[d]].all+=1)})),a):a}(A.length,P,S),O=s.radius,j=s.startRadius,z=s.endRadius;if(w){var U=c(10,w),K=c(10,m),V=-1/0;A.forEach((function(e){var t=K(e);V<t&&(V=t)}));var L=0;A.forEach((function(e,t){L+=0===t?V||10:(U(e)||0)+(V||10)})),O=L/(2*Math.PI)}else O||j||z?!j&&z?j=z:j&&!z&&(z=j):O=R>I?I/2:R/2;var F=D*v,B=[],J=A.map((function(e){return e.data}));B="topology"===N?p(T,J,S,P):"topology-directed"===N?p(T,J,S,P,!0):"degree"===N?function(e,t){var r=[];return t.forEach((function(t,a){t.degree=e[a].all,r.push(t)})),r.sort(g),r}(T,J):A;for(var H=Math.ceil(k/u),W=0;W<k;++W){var q=O;q||null===j||null===z||(q=j+W*(z-j)/(k-1)),q||(q=10+100*W/(k-1));var G=f+W%H*F+2*Math.PI/u*Math.floor(W/H);M||(G=y-W%H*F-2*Math.PI/u*Math.floor(W/H)),B[W].x=C[0]+Math.cos(G)*q,B[W].y=C[1]+Math.sin(G)*q,B[W].weight=T[W].all}return e&&B.forEach((function(e){t.mergeNodeData(e.id,{x:e.x,y:e.y,weight:e.weight})})),b&&b(),{nodes:B,edges:S}},e}()};function f(e,t){var a=e.layout,d=a.id,s=a.options,n=e.nodes,i=e.edges,o=new r({nodes:n,edges:i}),h=l[d];if(!h)throw new Error("Unknown layout id: "+d);return[new h(s).execute(o),t]}addEventListener("message",(function(e){var r,a=e.data,d=a.type,s=a.method,n=a.id,i=a.params;"RPC"===d&&s&&((r=t[s])?Promise.resolve().then((function(){return r.apply(t,i)})):Promise.reject("No such method")).then((function(e){postMessage({type:"RPC",id:n,result:e})})).catch((function(e){var t={message:e};e.stack&&(t.message=e.message,t.stack=e.stack,t.name=e.name),postMessage({type:"RPC",id:n,error:t})}))})),postMessage({type:"RPC",method:"ready"})})();
2
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFLZ0YsSUFBSUYsR0FBU3pHLEVBQzNEa0csRUFBWTFHLEdBQUdtRyxFQUFJTixFQUFpQixHQUFLMUQsS0FBS2lGLElBQUlILEdBQVN6RyxFQUMzRGtHLEVBQVkxRyxHQUFHcUgsT0FBU3JELEVBQVFoRSxHQUFHNEUsRyxDQWlCckMsT0FkSS9FLEdBQ0Y2RyxFQUFZdE8sU0FBUSxTQUFDaUQsR0FDbkJwRCxFQUFNbUUsY0FBY2YsRUFBS3pDLEdBQUksQ0FDM0JzTixFQUFHN0ssRUFBSzZLLEVBQ1JDLEVBQUc5SyxFQUFLOEssRUFDUmtCLE9BQVFoTSxFQUFLZ00sUUFFakIsSUFHRTNCLEdBQ0ZBLElBR0ssQ0FDTG5PLE1BQU9tUCxFQUNQaFAsTUFBSyxFQUVULEVBQ0YsRUE3SkEsSUV4Qk8sU0FBUzRQLEVBQWdCQyxFQUFrQkMsR0FDeEMsTUFBMENELEVBQU8sT0FBdkMzTyxFQUFFLEtBQUV0QixFQUFPLFVBQUlDLEVBQWlCZ1EsRUFBTyxNQUFqQjdQLEVBQVU2UCxFQUFPLE1BTW5EdFAsRUFBUSxJQUFJdEIsRUFBTSxDQUN0QlksTUFBT0EsRUFDUEcsTUFBT0EsSUFRSCtQLEVBQWF2QyxFQUFTdE0sR0FDNUIsSUFBSTZPLEVBR0YsTUFBTSxJQUFJbE8sTUFBTSxzQkFBd0JYLEdBTTFDLE1BQU8sQ0FSSSxJQUFJNk8sRUFBV25RLEdBTVA4TixRQUFRbk4sR0FFUnVQLEVBQ3JCLEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9MYXlvdXQvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vTGF5b3V0L3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9MYXlvdXQvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9MYXlvdXQvLi4vLi4vbm9kZV9tb2R1bGVzL0BhbnR2L2dyYXBobGliL2VzbS9HcmFwaC5qcyIsIndlYnBhY2s6Ly9MYXlvdXQvLi4vLi4vbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIndlYnBhY2s6Ly9MYXlvdXQvLi9zcmMvdXRpbC9zdHJpbmcudHMiLCJ3ZWJwYWNrOi8vTGF5b3V0Ly4vc3JjL3V0aWwvYXJyYXkudHMiLCJ3ZWJwYWNrOi8vTGF5b3V0Ly4vc3JjL3V0aWwvb2JqZWN0LnRzIiwid2VicGFjazovL0xheW91dC8uL3NyYy91dGlsL21hdGgudHMiLCJ3ZWJwYWNrOi8vTGF5b3V0Ly4vc3JjL3V0aWwvZnVuY3Rpb24udHMiLCJ3ZWJwYWNrOi8vTGF5b3V0Ly4vc3JjL3V0aWwvbnVtYmVyLnRzIiwid2VicGFjazovL0xheW91dC8uL3NyYy9jaXJjdWxhci50cyIsIndlYnBhY2s6Ly9MYXlvdXQvLi9zcmMvcmVnaXN0cnkudHMiLCJ3ZWJwYWNrOi8vTGF5b3V0Ly4vc3JjL3dvcmtlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgcmVxdWlyZSBzY29wZVxudmFyIF9fd2VicGFja19yZXF1aXJlX18gPSB7fTtcblxuIiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsImV4cG9ydCBjbGFzcyBHcmFwaCB7XG4gICAgbm9kZU1hcCA9IG5ldyBNYXAoKTtcbiAgICBlZGdlTWFwID0gbmV3IE1hcCgpO1xuICAgIGluRWRnZXNNYXAgPSBuZXcgTWFwKCk7XG4gICAgb3V0RWRnZXNNYXAgPSBuZXcgTWFwKCk7XG4gICAgdHJlZUluZGljZXMgPSBuZXcgTWFwKCk7XG4gICAgY2hhbmdlcyA9IFtdO1xuICAgIGJhdGNoQ291bnQgPSAwO1xuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggYSB7QGxpbmsgR3JhcGhDaGFuZ2VkRXZlbnR9IGVhY2ggdGltZSBhIGdyYXBoIGNoYW5nZSBoYXBwZW5lZC5cbiAgICAgKlxuICAgICAqIGBldmVudC5jaGFuZ2VzYCBjb250YWlucyBhbGwgdGhlIGdyYXBoIGNoYW5nZXMgaW4gb3JkZXIgc2luY2UgbGFzdCBgb25DaGFuZ2VkYC5cbiAgICAgKi9cbiAgICBvbkNoYW5nZWQgPSAoKSA9PiB7XG4gICAgICAgIC8vIERvIG5vdGhpbmcuXG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgR3JhcGggaW5zdGFuY2UuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3B0aW9ucyB0byBpbml0aWFsaXplIGEgZ3JhcGguIFNlZSB7QGxpbmsgR3JhcGhPcHRpb25zfS5cbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogY29uc3QgZ3JhcGggPSBuZXcgR3JhcGgoe1xuICAgICAqICAgLy8gT3B0aW9uYWwsIGluaXRpYWwgbm9kZXMuXG4gICAgICogICBub2RlczogW1xuICAgICAqICAgICAvLyBFYWNoIG5vZGUgaGFzIGEgdW5pcXVlIElELlxuICAgICAqICAgICB7IGlkOiAnQScsIGZvbzogMSB9LFxuICAgICAqICAgICB7IGlkOiAnQicsIGZvbzogMSB9LFxuICAgICAqICAgXSxcbiAgICAgKiAgIC8vIE9wdGlvbmFsLCBpbml0aWFsIGVkZ2VzLlxuICAgICAqICAgZWRnZXM6IFtcbiAgICAgKiAgICAgeyBpZDogJ0MnLCBzb3VyY2U6ICdCJywgdGFyZ2V0OiAnQicsIHdlaWdodDogMSB9LFxuICAgICAqICAgXSxcbiAgICAgKiAgIC8vIE9wdGlvbmFsLCBjYWxsZWQgd2l0aCBhIEdyYXBoQ2hhbmdlZEV2ZW50LlxuICAgICAqICAgb25DaGFuZ2VkOiAoZXZlbnQpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXZlbnQpO1xuICAgICAqICAgfVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAob3B0aW9ucy5ub2RlcylcbiAgICAgICAgICAgIHRoaXMuYWRkTm9kZXMob3B0aW9ucy5ub2Rlcyk7XG4gICAgICAgIGlmIChvcHRpb25zLmVkZ2VzKVxuICAgICAgICAgICAgdGhpcy5hZGRFZGdlcyhvcHRpb25zLmVkZ2VzKTtcbiAgICAgICAgaWYgKG9wdGlvbnMudHJlZSlcbiAgICAgICAgICAgIHRoaXMuYWRkVHJlZShvcHRpb25zLnRyZWUpO1xuICAgICAgICBpZiAob3B0aW9ucy5vbkNoYW5nZWQpXG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlZCA9IG9wdGlvbnMub25DaGFuZ2VkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCYXRjaCBzZXZlcmFsIGdyYXBoIGNoYW5nZXMgaW50byBvbmUuXG4gICAgICpcbiAgICAgKiBNYWtlIHNldmVyYWwgY2hhbmdlcywgYnV0IGRpc3BhdGNoIG9ubHkgb25lIENoYW5nZWRFdmVudCBhdCB0aGUgZW5kIG9mIGJhdGNoOlxuICAgICAqIGBgYHRzXG4gICAgICogZ3JhcGguYmF0Y2goKCkgPT4ge1xuICAgICAqICAgZ3JhcGguYWRkTm9kZXMoW10pO1xuICAgICAqICAgZ3JhcGguYWRkRWRnZXMoW10pO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQmF0Y2hlcyBjYW4gYmUgbmVzdGVkLiBPbmx5IHRoZSBvdXRlcm1vc3QgYmF0Y2ggd2lsbCBkaXNwYXRjaCBhIENoYW5nZWRFdmVudDpcbiAgICAgKiBgYGB0c1xuICAgICAqIGdyYXBoLmJhdGNoKCgpID0+IHtcbiAgICAgKiAgIGdyYXBoLmFkZE5vZGVzKFtdKTtcbiAgICAgKiAgIGdyYXBoLmJhdGNoKCgpID0+IHtcbiAgICAgKiAgICAgZ3JhcGguYWRkRWRnZXMoW10pO1xuICAgICAqICAgfSk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYmF0Y2ggPSAoZm4pID0+IHtcbiAgICAgICAgdGhpcy5iYXRjaENvdW50ICs9IDE7XG4gICAgICAgIGZuKCk7XG4gICAgICAgIHRoaXMuYmF0Y2hDb3VudCAtPSAxO1xuICAgICAgICBpZiAoIXRoaXMuYmF0Y2hDb3VudCkge1xuICAgICAgICAgICAgdGhpcy5jb21taXQoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICogUmVzZXQgY2hhbmdlcyBhbmQgZGlzcGF0Y2ggYSBDaGFuZ2VkRXZlbnQuXG4gICAgICovXG4gICAgY29tbWl0KCkge1xuICAgICAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5jaGFuZ2VzO1xuICAgICAgICB0aGlzLmNoYW5nZXMgPSBbXTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZWQoe1xuICAgICAgICAgICAgZ3JhcGg6IHRoaXMsXG4gICAgICAgICAgICBjaGFuZ2VzLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVkdWNlIHRoZSBudW1iZXIgb2Ygb3JkZXJlZCBncmFwaCBjaGFuZ2VzIGJ5IGRyb3BwaW5nIG9yIG1lcmdpbmcgdW5uZWNlc3NhcnkgY2hhbmdlcy5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlLCBpZiB3ZSB1cGRhdGUgYSBub2RlIGFuZCByZW1vdmUgaXQgaW4gYSBiYXRjaDpcbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogZ3JhcGguYmF0Y2goKCkgPT4ge1xuICAgICAqICAgZ3JhcGgudXBkYXRlTm9kZURhdGEoJ0EnLCAnZm9vJywgMik7XG4gICAgICogICBncmFwaC5yZW1vdmVOb2RlKCdBJyk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXZSBnZXQgMiBhdG9taWMgZ3JhcGggY2hhbmdlcyBsaWtlXG4gICAgICpcbiAgICAgKiBgYGB0c1xuICAgICAqIFtcbiAgICAgKiAgIHsgdHlwZTogJ05vZGVEYXRhVXBkYXRlZCcsIGlkOiAnQScsIHByb3BlcnR5TmFtZTogJ2ZvbycsIG9sZFZhbHVlOiAxLCBuZXdWYWx1ZTogMiB9LFxuICAgICAqICAgeyB0eXBlOiAnTm9kZVJlbW92ZWQnLCB2YWx1ZTogeyBpZDogJ0EnLCBkYXRhOiB7IGZvbzogMiB9IH0sXG4gICAgICogXVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogU2luY2Ugbm9kZSAnQScgaGFzIGJlZW4gcmVtb3ZlZCwgd2UgYWN0dWFsbHkgaGF2ZSBubyBuZWVkIHRvIGhhbmRsZSB3aXRoIE5vZGVEYXRhVXBkYXRlZCBjaGFuZ2UuXG4gICAgICpcbiAgICAgKiBgcmVkdWNlQ2hhbmdlcygpYCBoZXJlIGhlbHBzIHVzIHJlbW92ZSBzdWNoIGNoYW5nZXMuXG4gICAgICovXG4gICAgcmVkdWNlQ2hhbmdlcyhjaGFuZ2VzKSB7XG4gICAgICAgIGxldCBtZXJnZWRDaGFuZ2VzID0gW107XG4gICAgICAgIGNoYW5nZXMuZm9yRWFjaCgoY2hhbmdlKSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNoYW5nZS50eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnTm9kZVJlbW92ZWQnOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE5vZGVBZGRlZDogQSBhZGRlZC5cbiAgICAgICAgICAgICAgICAgICAgLy8gTm9kZURhdGFVcGRhdGVkOiBBIGNoYW5nZWQuXG4gICAgICAgICAgICAgICAgICAgIC8vIFRyZWVTdHJ1Y3R1cmVDaGFuZ2VkOiBBJ3MgcGFyZW50IGNoYW5nZWQuXG4gICAgICAgICAgICAgICAgICAgIC8vIE5vZGVSZW1vdmVkOiBBIHJlbW92ZWQuIPCfkYjwn4+7IFNpbmNlIEEgd2FzIHJlbW92ZWQsIGFib3ZlIHRocmVlIGNoYW5nZXMgbWF5IGJlIGlnbm9yZWQuXG4gICAgICAgICAgICAgICAgICAgIGxldCBpc05ld2x5QWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgbWVyZ2VkQ2hhbmdlcyA9IG1lcmdlZENoYW5nZXMuZmlsdGVyKChwYXN0Q2hhbmdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFzdENoYW5nZS50eXBlID09PSAnTm9kZUFkZGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNhbWVJZCA9IHBhc3RDaGFuZ2UudmFsdWUuaWQgPT09IGNoYW5nZS52YWx1ZS5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2FtZUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzTmV3bHlBZGRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhc2FtZUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocGFzdENoYW5nZS50eXBlID09PSAnTm9kZURhdGFVcGRhdGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXN0Q2hhbmdlLmlkICE9PSBjaGFuZ2UudmFsdWUuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwYXN0Q2hhbmdlLnR5cGUgPT09ICdUcmVlU3RydWN0dXJlQ2hhbmdlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFzdENoYW5nZS5ub2RlSWQgIT09IGNoYW5nZS52YWx1ZS5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc05ld2x5QWRkZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlZENoYW5nZXMucHVzaChjaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlICdFZGdlUmVtb3ZlZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRWRnZUFkZGVkOiBBIGFkZGVkLlxuICAgICAgICAgICAgICAgICAgICAvLyBFZGdlRGF0YVVwZGF0ZWQ6IEEgY2hhbmdlZC5cbiAgICAgICAgICAgICAgICAgICAgLy8gRWRnZURhdGFVcGRhdGVkOiBBJ3Mgc291cmNlL3RhcmdldCBjaGFuZ2VkLlxuICAgICAgICAgICAgICAgICAgICAvLyBFZGdlUmVtb3ZlZDogQSByZW1vdmVkLiDwn5GI8J+PuyBTaW5jZSBBIHdhcyByZW1vdmVkLCBhYm92ZSB0aHJlZSBjaGFuZ2VzIG1heSBiZSBpZ25vcmVkLlxuICAgICAgICAgICAgICAgICAgICBsZXQgaXNOZXdseUFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlZENoYW5nZXMgPSBtZXJnZWRDaGFuZ2VzLmZpbHRlcigocGFzdENoYW5nZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhc3RDaGFuZ2UudHlwZSA9PT0gJ0VkZ2VBZGRlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzYW1lSWQgPSBwYXN0Q2hhbmdlLnZhbHVlLmlkID09PSBjaGFuZ2UudmFsdWUuaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNhbWVJZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc05ld2x5QWRkZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIXNhbWVJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBhc3RDaGFuZ2UudHlwZSA9PT0gJ0VkZ2VEYXRhVXBkYXRlZCcgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0Q2hhbmdlLnR5cGUgPT09ICdFZGdlVXBkYXRlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFzdENoYW5nZS5pZCAhPT0gY2hhbmdlLnZhbHVlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzTmV3bHlBZGRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VkQ2hhbmdlcy5wdXNoKGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgJ05vZGVEYXRhVXBkYXRlZCc6XG4gICAgICAgICAgICAgICAgY2FzZSAnRWRnZURhdGFVcGRhdGVkJzpcbiAgICAgICAgICAgICAgICBjYXNlICdFZGdlVXBkYXRlZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm9kZURhdGFVcGRhdGVkOiB7IGlkOiBBLCBwcm9wZXJ0eU5hbWU6ICdmb28nLCBvbGRWYWx1ZTogMSwgbmV3VmFsdWU6IDIgfS5cbiAgICAgICAgICAgICAgICAgICAgLy8gTm9kZURhdGFVcGRhdGVkOiB7IGlkOiBBLCBwcm9wZXJ0eU5hbWU6ICdmb28nLCBvbGRWYWx1ZTogMiwgbmV3VmFsdWU6IDMgfS5cbiAgICAgICAgICAgICAgICAgICAgLy8g8J+RhiBDb3VsZCBiZSBtZXJnZWQgYXMgeyBpZDogQSwgcHJvcGVydHlOYW1lOiAnZm9vJywgb2xkVmFsdWU6IDEsIG5ld1ZhbHVlOiAzIH0uXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nQ2hhbmdlID0gbWVyZ2VkQ2hhbmdlcy5maW5kKChwYXN0Q2hhbmdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHBhc3RDaGFuZ2UudHlwZSA9PT0gY2hhbmdlLnR5cGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0Q2hhbmdlLmlkID09PSBjaGFuZ2UuaWQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0Q2hhbmdlLnByb3BlcnR5TmFtZSA9PT0gY2hhbmdlLnByb3BlcnR5TmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdDaGFuZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nQ2hhbmdlLm5ld1ZhbHVlID0gY2hhbmdlLm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VkQ2hhbmdlcy5wdXNoKGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgJ1RyZWVTdHJ1Y3R1cmVEZXRhY2hlZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVHJlZVN0cnVjdHVyZUF0dGFjaGVkXG4gICAgICAgICAgICAgICAgICAgIC8vIFRyZWVTdHJ1Y3R1cmVDaGFuZ2VkXG4gICAgICAgICAgICAgICAgICAgIC8vIFRyZWVTdHJ1Y3R1cmVEZXRhY2hlZCDwn5GI8J+PuyBTaW5jZSB0aGUgdHJlZSBzdHJ1Y3Qgd2FzIGRldGFjaGVkLCBhYm92ZSAyIGNoYW5nZXMgbWF5IGJlIGlnbm9yZWQuXG4gICAgICAgICAgICAgICAgICAgIG1lcmdlZENoYW5nZXMgPSBtZXJnZWRDaGFuZ2VzLmZpbHRlcigocGFzdENoYW5nZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhc3RDaGFuZ2UudHlwZSA9PT0gJ1RyZWVTdHJ1Y3R1cmVBdHRhY2hlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFzdENoYW5nZS50cmVlS2V5ICE9PSBjaGFuZ2UudHJlZUtleTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBhc3RDaGFuZ2UudHlwZSA9PT0gJ1RyZWVTdHJ1Y3R1cmVDaGFuZ2VkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXN0Q2hhbmdlLnRyZWVLZXkgIT09IGNoYW5nZS50cmVlS2V5O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBtZXJnZWRDaGFuZ2VzLnB1c2goY2hhbmdlKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgJ1RyZWVTdHJ1Y3R1cmVDaGFuZ2VkJzoge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ0NoYW5nZSA9IG1lcmdlZENoYW5nZXMuZmluZCgocGFzdENoYW5nZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChwYXN0Q2hhbmdlLnR5cGUgPT09ICdUcmVlU3RydWN0dXJlQ2hhbmdlZCcgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0Q2hhbmdlLnRyZWVLZXkgPT09IGNoYW5nZS50cmVlS2V5ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdENoYW5nZS5ub2RlSWQgPT09IGNoYW5nZS5ub2RlSWQpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nQ2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0NoYW5nZS5uZXdQYXJlbnRJZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlLm5ld1BhcmVudElkO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VkQ2hhbmdlcy5wdXNoKGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlZENoYW5nZXMucHVzaChjaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtZXJnZWRDaGFuZ2VzO1xuICAgIH1cbiAgICAvLyA9PT09PT09PT09PT09PT09PSBOb2RlID09PT09PT09PT09PT09PT09XG4gICAgY2hlY2tOb2RlRXhpc3RlbmNlKGlkKSB7XG4gICAgICAgIGlmICghdGhpcy5oYXNOb2RlKGlkKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb2RlIG5vdCBmb3VuZCBmb3IgaWQ6ICcgKyBpZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYSBub2RlIGV4aXN0cyBpbiB0aGUgZ3JhcGguXG4gICAgICogQGdyb3VwIE5vZGVNZXRob2RzXG4gICAgICovXG4gICAgaGFzTm9kZShpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub2RlTWFwLmhhcyhpZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlbGwgaWYgdHdvIG5vZGVzIGFyZSBuZWlnaGJvcnMuXG4gICAgICogQGdyb3VwIE5vZGVNZXRob2RzXG4gICAgICovXG4gICAgYXJlTmVpZ2hib3JzKGZpcnN0Tm9kZUlkLCBzZWNvbmROb2RlSWQpIHtcbiAgICAgICAgdGhpcy5jaGVja05vZGVFeGlzdGVuY2UoZmlyc3ROb2RlSWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXROZWlnaGJvcnMoc2Vjb25kTm9kZUlkKS5zb21lKChuZWlnaGJvcikgPT4gbmVpZ2hib3IuaWQgPT09IGZpcnN0Tm9kZUlkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBub2RlIGRhdGEgd2l0aCBnaXZlbiBJRC5cbiAgICAgKiBAZ3JvdXAgTm9kZU1ldGhvZHNcbiAgICAgKi9cbiAgICBnZXROb2RlKGlkKSB7XG4gICAgICAgIHRoaXMuY2hlY2tOb2RlRXhpc3RlbmNlKGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZU1hcC5nZXQoaWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIG5vZGUgSUQsIGZpbmQgYWxsIGVkZ2VzIG9mIHRoZSBub2RlLlxuICAgICAqIEBwYXJhbSBpZCAtIElEIG9mIHRoZSBub2RlXG4gICAgICogQHBhcmFtIGRpcmVjdGlvbiAtIEVkZ2UgZGlyZWN0aW9uLCBkZWZhdWx0cyB0byAnYm90aCcuXG4gICAgICogQGdyb3VwIE5vZGVNZXRob2RzXG4gICAgICovXG4gICAgZ2V0UmVsYXRlZEVkZ2VzKGlkLCBkaXJlY3Rpb24pIHtcbiAgICAgICAgdGhpcy5jaGVja05vZGVFeGlzdGVuY2UoaWQpO1xuICAgICAgICBjb25zdCBpbkVkZ2VzID0gdGhpcy5pbkVkZ2VzTWFwLmdldChpZCk7XG4gICAgICAgIGNvbnN0IG91dEVkZ2VzID0gdGhpcy5vdXRFZGdlc01hcC5nZXQoaWQpO1xuICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAnaW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShpbkVkZ2VzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkaXJlY3Rpb24gPT09ICdvdXQnKSB7XG4gICAgICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShvdXRFZGdlcyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm90aEVkZ2VzID0gbmV3IFNldChbLi4uaW5FZGdlcywgLi4ub3V0RWRnZXNdKTtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20oYm90aEVkZ2VzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBkZWdyZWUgb2YgdGhlIGdpdmVuIG5vZGUuXG4gICAgICogQGdyb3VwIE5vZGVNZXRob2RzXG4gICAgICovXG4gICAgZ2V0RGVncmVlKGlkLCBkaXJlY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UmVsYXRlZEVkZ2VzKGlkLCBkaXJlY3Rpb24pLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFsbCBzdWNjZXNzb3JzIG9mIHRoZSBnaXZlbiBub2RlLlxuICAgICAqL1xuICAgIGdldFN1Y2Nlc3NvcnMoaWQpIHtcbiAgICAgICAgY29uc3Qgb3V0RWRnZXMgPSB0aGlzLmdldFJlbGF0ZWRFZGdlcyhpZCwgJ291dCcpO1xuICAgICAgICBjb25zdCB0YXJnZXRzID0gb3V0RWRnZXMubWFwKChlZGdlKSA9PiBlZGdlLnRhcmdldCk7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodGFyZ2V0cykpLm1hcCgoaWQpID0+IHRoaXMuZ2V0Tm9kZShpZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIHByZWRlY2Vzc29ycyBvZiB0aGUgZ2l2ZW4gbm9kZS5cbiAgICAgKi9cbiAgICBnZXRQcmVkZWNlc3NvcnMoaWQpIHtcbiAgICAgICAgY29uc3QgaW5FZGdlcyA9IHRoaXMuZ2V0UmVsYXRlZEVkZ2VzKGlkLCAnaW4nKTtcbiAgICAgICAgY29uc3Qgc291cmNlcyA9IGluRWRnZXMubWFwKChlZGdlKSA9PiBlZGdlLnNvdXJjZSk7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoc291cmNlcykpLm1hcCgoaWQpID0+IHRoaXMuZ2V0Tm9kZShpZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIG5vZGUgSUQsIGZpbmQgaXRzIG5laWdoYm9ycy5cbiAgICAgKiBAcGFyYW0gaWQgLSBJRCBvZiB0aGUgbm9kZVxuICAgICAqIEBncm91cCBOb2RlTWV0aG9kc1xuICAgICAqL1xuICAgIGdldE5laWdoYm9ycyhpZCkge1xuICAgICAgICBjb25zdCBwcmVkZWNlc3NvcnMgPSB0aGlzLmdldFByZWRlY2Vzc29ycyhpZCk7XG4gICAgICAgIGNvbnN0IHN1Y2Nlc3NvcnMgPSB0aGlzLmdldFN1Y2Nlc3NvcnMoaWQpO1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KFsuLi5wcmVkZWNlc3NvcnMsIC4uLnN1Y2Nlc3NvcnNdKSk7XG4gICAgfVxuICAgIGRvQWRkTm9kZShub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc05vZGUobm9kZS5pZCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm9kZSBhbHJlYWR5IGV4aXN0czogJyArIG5vZGUuaWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9kZU1hcC5zZXQobm9kZS5pZCwgbm9kZSk7XG4gICAgICAgIHRoaXMuaW5FZGdlc01hcC5zZXQobm9kZS5pZCwgbmV3IFNldCgpKTtcbiAgICAgICAgdGhpcy5vdXRFZGdlc01hcC5zZXQobm9kZS5pZCwgbmV3IFNldCgpKTtcbiAgICAgICAgdGhpcy50cmVlSW5kaWNlcy5mb3JFYWNoKCh0cmVlKSA9PiB7XG4gICAgICAgICAgICB0cmVlLmNoaWxkcmVuTWFwLnNldChub2RlLmlkLCBuZXcgU2V0KCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jaGFuZ2VzLnB1c2goeyB0eXBlOiAnTm9kZUFkZGVkJywgdmFsdWU6IG5vZGUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbGwgbm9kZXMgb2YgdGhlIGdpdmVuIGFycmF5LCBvciBpdGVyYWJsZSwgaW50byB0aGUgZ3JhcGguXG4gICAgICogQGdyb3VwIE5vZGVNZXRob2RzXG4gICAgICovXG4gICAgYWRkTm9kZXMobm9kZXMpIHtcbiAgICAgICAgdGhpcy5iYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvQWRkTm9kZShub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIHNpbmdsZSBub2RlIGludG8gdGhlIGdyYXBoLlxuICAgICAqIEBncm91cCBOb2RlTWV0aG9kc1xuICAgICAqL1xuICAgIGFkZE5vZGUobm9kZSkge1xuICAgICAgICB0aGlzLmFkZE5vZGVzKFtub2RlXSk7XG4gICAgfVxuICAgIGRvUmVtb3ZlTm9kZShpZCkge1xuICAgICAgICBjb25zdCBub2RlID0gdGhpcy5nZXROb2RlKGlkKTtcbiAgICAgICAgY29uc3QgaW5FZGdlcyA9IHRoaXMuaW5FZGdlc01hcC5nZXQoaWQpO1xuICAgICAgICBjb25zdCBvdXRFZGdlcyA9IHRoaXMub3V0RWRnZXNNYXAuZ2V0KGlkKTtcbiAgICAgICAgaW5FZGdlcz8uZm9yRWFjaCgoZWRnZSkgPT4gdGhpcy5kb1JlbW92ZUVkZ2UoZWRnZS5pZCkpO1xuICAgICAgICBvdXRFZGdlcz8uZm9yRWFjaCgoZWRnZSkgPT4gdGhpcy5kb1JlbW92ZUVkZ2UoZWRnZS5pZCkpO1xuICAgICAgICB0aGlzLm5vZGVNYXAuZGVsZXRlKGlkKTtcbiAgICAgICAgdGhpcy50cmVlSW5kaWNlcy5mb3JFYWNoKCh0cmVlKSA9PiB7XG4gICAgICAgICAgICB0cmVlLmNoaWxkcmVuTWFwLmdldChpZCk/LmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJlZS5wYXJlbnRNYXAuZGVsZXRlKGNoaWxkLmlkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdHJlZS5wYXJlbnRNYXAuZGVsZXRlKGlkKTtcbiAgICAgICAgICAgIHRyZWUuY2hpbGRyZW5NYXAuZGVsZXRlKGlkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2hhbmdlcy5wdXNoKHsgdHlwZTogJ05vZGVSZW1vdmVkJywgdmFsdWU6IG5vZGUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBub2RlcyBhbmQgdGhlaXIgYXR0YWNoZWQgZWRnZXMgZnJvbSB0aGUgZ3JhcGguXG4gICAgICogQGdyb3VwIE5vZGVNZXRob2RzXG4gICAgICovXG4gICAgcmVtb3ZlTm9kZXMoaWRMaXN0KSB7XG4gICAgICAgIHRoaXMuYmF0Y2goKCkgPT4ge1xuICAgICAgICAgICAgaWRMaXN0LmZvckVhY2goKGlkKSA9PiB0aGlzLmRvUmVtb3ZlTm9kZShpZCkpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgc2luZ2xlIG5vZGUgYW5kIGl0cyBhdHRhY2hlZCBlZGdlcyBmcm9tIHRoZSBncmFwaC5cbiAgICAgKiBAZ3JvdXAgTm9kZU1ldGhvZHNcbiAgICAgKi9cbiAgICByZW1vdmVOb2RlKGlkKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlTm9kZXMoW2lkXSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBub2RlIGRhdGEuXG4gICAgICogQGdyb3VwIE5vZGVNZXRob2RzXG4gICAgICovXG4gICAgdXBkYXRlTm9kZURhdGEoaWQsIHByb3BlcnR5TmFtZSwgdmFsdWUpIHtcbiAgICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuZ2V0Tm9kZShpZCk7XG4gICAgICAgIHRoaXMuYmF0Y2goKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSBub2RlLmRhdGFbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICBub2RlLmRhdGFbcHJvcGVydHlOYW1lXSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdOb2RlRGF0YVVwZGF0ZWQnLFxuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIHByb3BlcnR5TmFtZSxcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZSxcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGlrZSBPYmplY3QuYXNzaWduLCBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiBgcGF0aGAgdG8gdGhlIG5vZGUgZGF0YS5cbiAgICAgKiBAcGFyYW0gaWQgTm9kZSBJRC5cbiAgICAgKiBAcGFyYW0gcGF0Y2ggQSBkYXRhIG9iamVjdCB0byBtZXJnZS5cbiAgICAgKi9cbiAgICBtZXJnZU5vZGVEYXRhKGlkLCBwYXRjaCkge1xuICAgICAgICB0aGlzLmJhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHBhdGNoKS5mb3JFYWNoKChbcHJvcGVydHlOYW1lLCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZU5vZGVEYXRhKGlkLCBwcm9wZXJ0eU5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8gPT09PT09PT09PT09PT09PT0gRWRnZSA9PT09PT09PT09PT09PT09PVxuICAgIGNoZWNrRWRnZUV4aXN0ZW5jZShpZCkge1xuICAgICAgICBpZiAoIXRoaXMuaGFzRWRnZShpZCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWRnZSBub3QgZm91bmQgZm9yIGlkOiAnICsgaWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGFuIGVkZ2UgZXhpc3RzIGluIHRoZSBncmFwaC5cbiAgICAgKiBAZ3JvdXAgTm9kZU1ldGhvZHNcbiAgICAgKi9cbiAgICBoYXNFZGdlKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVkZ2VNYXAuaGFzKGlkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBlZGdlIGRhdGEgd2l0aCBnaXZlbiBJRC5cbiAgICAgKiBAZ3JvdXAgRWRnZU1ldGhvZHNcbiAgICAgKi9cbiAgICBnZXRFZGdlKGlkKSB7XG4gICAgICAgIHRoaXMuY2hlY2tFZGdlRXhpc3RlbmNlKGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWRnZU1hcC5nZXQoaWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGVkZ2UsIHRoZSBzb3VyY2Ugbm9kZSwgYW5kIHRoZSB0YXJnZXQgbm9kZSBieSBhbiBlZGdlIElELlxuICAgICAqIEBncm91cCBFZGdlTWV0aG9kc1xuICAgICAqL1xuICAgIGdldEVkZ2VEZXRhaWwoaWQpIHtcbiAgICAgICAgY29uc3QgZWRnZSA9IHRoaXMuZ2V0RWRnZShpZCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBlZGdlLFxuICAgICAgICAgICAgc291cmNlOiB0aGlzLmdldE5vZGUoZWRnZS5zb3VyY2UpLFxuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmdldE5vZGUoZWRnZS50YXJnZXQpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBkb0FkZEVkZ2UoZWRnZSkge1xuICAgICAgICBpZiAodGhpcy5oYXNFZGdlKGVkZ2UuaWQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VkZ2UgYWxyZWFkeSBleGlzdHM6ICcgKyBlZGdlLmlkKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrTm9kZUV4aXN0ZW5jZShlZGdlLnNvdXJjZSk7XG4gICAgICAgIHRoaXMuY2hlY2tOb2RlRXhpc3RlbmNlKGVkZ2UudGFyZ2V0KTtcbiAgICAgICAgdGhpcy5lZGdlTWFwLnNldChlZGdlLmlkLCBlZGdlKTtcbiAgICAgICAgY29uc3QgaW5FZGdlcyA9IHRoaXMuaW5FZGdlc01hcC5nZXQoZWRnZS50YXJnZXQpO1xuICAgICAgICBjb25zdCBvdXRFZGdlcyA9IHRoaXMub3V0RWRnZXNNYXAuZ2V0KGVkZ2Uuc291cmNlKTtcbiAgICAgICAgaW5FZGdlcy5hZGQoZWRnZSk7XG4gICAgICAgIG91dEVkZ2VzLmFkZChlZGdlKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VzLnB1c2goeyB0eXBlOiAnRWRnZUFkZGVkJywgdmFsdWU6IGVkZ2UgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbGwgZWRnZXMgb2YgdGhlIGdpdmVuIGl0ZXJhYmxlKGFuIGFycmF5LCBhIHNldCwgZXRjLikgaW50byB0aGUgZ3JhcGguXG4gICAgICogQGdyb3VwIEVkZ2VNZXRob2RzXG4gICAgICovXG4gICAgYWRkRWRnZXMoZWRnZXMpIHtcbiAgICAgICAgdGhpcy5iYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVkZ2Ugb2YgZWRnZXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvQWRkRWRnZShlZGdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIHNpbmdsZSBlZGdlIHBvaW50aW5nIGZyb20gYHNvdXJjZWAgdG8gYHRhcmdldGAgaW50byB0aGUgZ3JhcGguXG4gICAgICpcbiAgICAgKiBgYGB0c1xuICAgICAqIGdyYXBoLmFkZE5vZGUoeyBpZDogJ05vZGVBJyB9KTtcbiAgICAgKiBncmFwaC5hZGROb2RlKHsgaWQ6ICdOb2RlQicgfSk7XG4gICAgICogZ3JhcGguYWRkRWRnZSh7IGlkOiAnRWRnZUEnLCBzb3VyY2U6ICdOb2RlQScsIHRhcmdldDogJ05vZGVCJyB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIElmIGBzb3VyY2VgIG9yIGB0YXJnZXRgIHdlcmUgbm90IGZvdW5kIGluIHRoZSBjdXJyZW50IGdyYXBoLCBpdCB0aHJvd3MgYW4gRXJyb3IuXG4gICAgICogQGdyb3VwIEVkZ2VNZXRob2RzXG4gICAgICovXG4gICAgYWRkRWRnZShlZGdlKSB7XG4gICAgICAgIHRoaXMuYWRkRWRnZXMoW2VkZ2VdKTtcbiAgICB9XG4gICAgZG9SZW1vdmVFZGdlKGlkKSB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSB0aGlzLmdldEVkZ2UoaWQpO1xuICAgICAgICBjb25zdCBvdXRFZGdlcyA9IHRoaXMub3V0RWRnZXNNYXAuZ2V0KGVkZ2Uuc291cmNlKTtcbiAgICAgICAgY29uc3QgaW5FZGdlcyA9IHRoaXMuaW5FZGdlc01hcC5nZXQoZWRnZS50YXJnZXQpO1xuICAgICAgICBvdXRFZGdlcy5kZWxldGUoZWRnZSk7XG4gICAgICAgIGluRWRnZXMuZGVsZXRlKGVkZ2UpO1xuICAgICAgICB0aGlzLmVkZ2VNYXAuZGVsZXRlKGlkKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VzLnB1c2goeyB0eXBlOiAnRWRnZVJlbW92ZWQnLCB2YWx1ZTogZWRnZSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGVkZ2VzIHdob3NlIGlkIHdhcyBpbmNsdWRlZCBpbiB0aGUgZ2l2ZW4gaWQgbGlzdC5cbiAgICAgKiBAZ3JvdXAgRWRnZU1ldGhvZHNcbiAgICAgKi9cbiAgICByZW1vdmVFZGdlcyhpZExpc3QpIHtcbiAgICAgICAgdGhpcy5iYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICBpZExpc3QuZm9yRWFjaCgoaWQpID0+IHRoaXMuZG9SZW1vdmVFZGdlKGlkKSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBzaW5nbGUgZWRnZSBvZiB0aGUgZ2l2ZW4gaWQuXG4gICAgICogQGdyb3VwIEVkZ2VNZXRob2RzXG4gICAgICovXG4gICAgcmVtb3ZlRWRnZShpZCkge1xuICAgICAgICB0aGlzLnJlbW92ZUVkZ2VzKFtpZF0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDaGFuZ2UgdGhlIHNvdXJjZSBvZiBhbiBlZGdlLiBUaGUgc291cmNlIG11c3QgYmUgZm91bmQgaW4gY3VycmVudCBncmFwaC5cbiAgICAgKiBAZ3JvdXAgRWRnZU1ldGhvZHNcbiAgICAgKi9cbiAgICB1cGRhdGVFZGdlU291cmNlKGlkLCBzb3VyY2UpIHtcbiAgICAgICAgY29uc3QgZWRnZSA9IHRoaXMuZ2V0RWRnZShpZCk7XG4gICAgICAgIHRoaXMuY2hlY2tOb2RlRXhpc3RlbmNlKHNvdXJjZSk7XG4gICAgICAgIGNvbnN0IG9sZFNvdXJjZSA9IGVkZ2Uuc291cmNlO1xuICAgICAgICBjb25zdCBuZXdTb3VyY2UgPSBzb3VyY2U7XG4gICAgICAgIHRoaXMub3V0RWRnZXNNYXAuZ2V0KG9sZFNvdXJjZSkuZGVsZXRlKGVkZ2UpO1xuICAgICAgICB0aGlzLm91dEVkZ2VzTWFwLmdldChuZXdTb3VyY2UpLmFkZChlZGdlKTtcbiAgICAgICAgZWRnZS5zb3VyY2UgPSBzb3VyY2U7XG4gICAgICAgIHRoaXMuYmF0Y2goKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdFZGdlVXBkYXRlZCcsXG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgcHJvcGVydHlOYW1lOiAnc291cmNlJyxcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZTogb2xkU291cmNlLFxuICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBuZXdTb3VyY2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoYW5nZSB0aGUgdGFyZ2V0IG9mIGFuIGVkZ2UuIFRoZSB0YXJnZXQgbXVzdCBiZSBmb3VuZCBpbiBjdXJyZW50IGdyYXBoLlxuICAgICAqIEBncm91cCBFZGdlTWV0aG9kc1xuICAgICAqL1xuICAgIHVwZGF0ZUVkZ2VUYXJnZXQoaWQsIHRhcmdldCkge1xuICAgICAgICBjb25zdCBlZGdlID0gdGhpcy5nZXRFZGdlKGlkKTtcbiAgICAgICAgdGhpcy5jaGVja05vZGVFeGlzdGVuY2UodGFyZ2V0KTtcbiAgICAgICAgY29uc3Qgb2xkVGFyZ2V0ID0gZWRnZS50YXJnZXQ7XG4gICAgICAgIGNvbnN0IG5ld1RhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy5pbkVkZ2VzTWFwLmdldChvbGRUYXJnZXQpLmRlbGV0ZShlZGdlKTtcbiAgICAgICAgdGhpcy5pbkVkZ2VzTWFwLmdldChuZXdUYXJnZXQpLmFkZChlZGdlKTtcbiAgICAgICAgZWRnZS50YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgIHRoaXMuYmF0Y2goKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdFZGdlVXBkYXRlZCcsXG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgcHJvcGVydHlOYW1lOiAndGFyZ2V0JyxcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZTogb2xkVGFyZ2V0LFxuICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBuZXdUYXJnZXQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBlZGdlIGRhdGEuXG4gICAgICogQGdyb3VwIEVkZ2VNZXRob2RzXG4gICAgICovXG4gICAgdXBkYXRlRWRnZURhdGEoaWQsIHByb3BlcnR5TmFtZSwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgZWRnZSA9IHRoaXMuZ2V0RWRnZShpZCk7XG4gICAgICAgIHRoaXMuYmF0Y2goKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSBlZGdlLmRhdGFbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICBlZGdlLmRhdGFbcHJvcGVydHlOYW1lXSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdFZGdlRGF0YVVwZGF0ZWQnLFxuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIHByb3BlcnR5TmFtZSxcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZSxcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQGdyb3VwIEVkZ2VNZXRob2RzXG4gICAgICovXG4gICAgbWVyZ2VFZGdlRGF0YShpZCwgcGF0Y2gpIHtcbiAgICAgICAgdGhpcy5iYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyhwYXRjaCkuZm9yRWFjaCgoW3Byb3BlcnR5TmFtZSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVFZGdlRGF0YShpZCwgcHJvcGVydHlOYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vID09PT09PT09PT09PT09PT09IFRyZWUgPT09PT09PT09PT09PT09PT1cbiAgICBjaGVja1RyZWVFeGlzdGVuY2UodHJlZUtleSkge1xuICAgICAgICBpZiAoIXRoaXMudHJlZUluZGljZXMuaGFzKHRyZWVLZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyZWUgc3RydWN0dXJlIG5vdCBmb3VuZCBmb3IgdHJlZUtleTogJyArIHRyZWVLZXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEF0dGFjaCBhIG5ldyB0cmVlIHN0cnVjdHVyZSByZXByZXNlbnRpbmcgdGhlIGhpZXJhcmNoeSBvZiBhbGwgbm9kZXMgaW4gdGhlIGdyYXBoLlxuICAgICAqIEBwYXJhbSB0cmVlS2V5IEEgdW5pcXVlIGtleSBvZiB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFlvdSBjYW4gYXR0YWNoIG11bHRpcGxlIHRyZWUgc3RydWN0dXJlcyB3aXRoIGRpZmZlcmVudCBrZXlzLlxuICAgICAqXG4gICAgICogYGBgdHNcbiAgICAgKiBjb25zdCBncmFwaCA9IG5ldyBHcmFwaCh7XG4gICAgICogICBub2RlczogW3sgaWQ6IDEgfSwgeyBpZDogMiB9LCB7IGlkOiAzIH1dLFxuICAgICAqIH0pO1xuICAgICAqIGdyYXBoLmF0dGFjaFRyZWVTdHJ1Y3R1cmUoJ0luaGVyaXRhbmNlJyk7XG4gICAgICogZ3JhcGguc2V0UGFyZW50KDIsIDEsICdJbmhlcml0YW5jZScpO1xuICAgICAqIGdyYXBoLnNldFBhcmVudCgzLCAxLCAnSW5oZXJpdGFuY2UnKTtcbiAgICAgKiBncmFwaC5nZXRSb290cygnSW5oZXJpdGFuY2UnKTsgLy8gWzFdXG4gICAgICogZ3JhcGguZ2V0Q2hpbGRyZW4oMSwgJ0luaGVyaXRhbmNlJyk7IC8vIFsyLDNdXG4gICAgICogYGBgXG4gICAgICogQGdyb3VwIFRyZWVNZXRob2RzXG4gICAgICovXG4gICAgYXR0YWNoVHJlZVN0cnVjdHVyZSh0cmVlS2V5KSB7XG4gICAgICAgIGlmICh0aGlzLnRyZWVJbmRpY2VzLmhhcyh0cmVlS2V5KSkge1xuICAgICAgICAgICAgLy8gQWxyZWFkeSBhdHRhY2hlZC5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyZWVJbmRpY2VzLnNldCh0cmVlS2V5LCB7XG4gICAgICAgICAgICBwYXJlbnRNYXA6IG5ldyBNYXAoKSxcbiAgICAgICAgICAgIGNoaWxkcmVuTWFwOiBuZXcgTWFwKCksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmJhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnVHJlZVN0cnVjdHVyZUF0dGFjaGVkJyxcbiAgICAgICAgICAgICAgICB0cmVlS2V5LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXRhY2ggdGhlIHRyZWUgc3RydWN0dXJlIG9mIHRoZSBnaXZlbiB0cmVlIGtleSBmcm9tIHRoZSBncmFwaC5cbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogZ3JhcGguZGV0YWNoVHJlZVN0cnVjdHVyZSgnSW5oZXJpdGFuY2UnKTtcbiAgICAgKiBncmFwaC5nZXRSb290cygnSW5oZXJpdGFuY2UnKTsgLy8gRXJyb3IhXG4gICAgICogYGBgXG4gICAgICogQGdyb3VwIFRyZWVNZXRob2RzXG4gICAgICovXG4gICAgZGV0YWNoVHJlZVN0cnVjdHVyZSh0cmVlS2V5KSB7XG4gICAgICAgIHRoaXMuY2hlY2tUcmVlRXhpc3RlbmNlKHRyZWVLZXkpO1xuICAgICAgICB0aGlzLnRyZWVJbmRpY2VzLmRlbGV0ZSh0cmVlS2V5KTtcbiAgICAgICAgdGhpcy5iYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ1RyZWVTdHJ1Y3R1cmVEZXRhY2hlZCcsXG4gICAgICAgICAgICAgICAgdHJlZUtleSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJhdmVyc2UgdGhlIGdpdmVuIHRyZWUgZGF0YSwgYWRkIGVhY2ggbm9kZSBpbnRvIHRoZSBncmFwaCwgdGhlbiBhdHRhY2ggdGhlIHRyZWUgc3RydWN0dXJlLlxuICAgICAqXG4gICAgICogYGBgdHNcbiAgICAgKiBncmFwaC5hZGRUcmVlKHtcbiAgICAgKiAgIGlkOiAxLFxuICAgICAqICAgY2hpbGRyZW46IFtcbiAgICAgKiAgICAgeyBpZDogMiB9LFxuICAgICAqICAgICB7IGlkOiAzIH0sXG4gICAgICogICBdLFxuICAgICAqIH0sICdJbmhlcml0YW5jZScpO1xuICAgICAqIGdyYXBoLmdldFJvb3RzKCdJbmhlcml0YW5jZScpOyAvLyBbMV1cbiAgICAgKiBncmFwaC5nZXRDaGlsZHJlbigxLCAnSW5oZXJpdGFuY2UnKTsgLy8gWzIsIDNdXG4gICAgICogZ3JhcGguZ2V0QWxsTm9kZXMoKTsgLy8gWzEsIDIsIDNdXG4gICAgICogZ3JhcGguZ2V0QWxsRWRnZXMoKTsgLy8gW11cbiAgICAgKiBgYGBcbiAgICAgKiBAZ3JvdXAgVHJlZU1ldGhvZHNcbiAgICAgKi9cbiAgICBhZGRUcmVlKHRyZWUsIHRyZWVLZXkpIHtcbiAgICAgICAgdGhpcy5iYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmF0dGFjaFRyZWVTdHJ1Y3R1cmUodHJlZUtleSk7XG4gICAgICAgICAgICAvLyBBZGQgTm9kZXNcbiAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gW107XG4gICAgICAgICAgICBjb25zdCBzdGFjayA9IEFycmF5LmlzQXJyYXkodHJlZSkgPyB0cmVlIDogW3RyZWVdO1xuICAgICAgICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBzdGFjay5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIG5vZGVzLnB1c2gobm9kZSk7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhY2sucHVzaCguLi5ub2RlLmNoaWxkcmVuKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmFkZE5vZGVzKG5vZGVzKTtcbiAgICAgICAgICAgIC8vIFNldCBwYXJlbnQgZm9yIGVhY2ggY2hpbGQgbm9kZS5cbiAgICAgICAgICAgIG5vZGVzLmZvckVhY2goKHBhcmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIHBhcmVudC5jaGlsZHJlbj8uZm9yRWFjaCgoY2hpbGQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQYXJlbnQoY2hpbGQuaWQsIHBhcmVudC5pZCwgdHJlZUtleSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcm9vdCBub2RlcyBvZiBhbiBhdHRhY2hlZCB0cmVlIHN0cnVjdHVyZS5cbiAgICAgKlxuICAgICAqIENvbnNpZGVyIGEgZ3JhcGggd2l0aCB0aGUgZm9sbG93aW5nIHRyZWUgc3RydWN0dXJlIGF0dGFjaGVkOlxuICAgICAqIGBgYFxuICAgICAqIFRyZWUgc3RydWN0dXJlOlxuICAgICAqICAgIE8gICAgIDNcbiAgICAgKiAgIC8gXFwgICAgfFxuICAgICAqICAxICAgMiAgIDRcbiAgICAgKiBgYGBcbiAgICAgKiBgZ3JhcGguZ2V0Um9vdHMoKWAgdGFrZXMgYWxsIG5vZGVzIHdpdGhvdXQgYSBwYXJlbnQsIHRoZXJlZm9yZSBbMCwgM10gd2FzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogTmV3bHkgYWRkZWQgbm9kZXMgYXJlIGFsc28gdW5wYXJlbnRlZC4gU28gdGhleSBhcmUgY291bnRlZCBhcyByb290cy5cbiAgICAgKiBgYGB0c1xuICAgICAqIGdyYXBoLmFkZE5vZGUoeyBpZDogNSB9KTtcbiAgICAgKiBncmFwaC5nZXRSb290cygpOyAvLyBbMCwgMywgNV1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEhlcmUgaXMgaG93IHRoZSB0cmVlIHN0cnVjdHVyZSBsb29rcyBsaWtlOlxuICAgICAqIGBgYFxuICAgICAqIFRyZWUgc3RydWN0dXJlOlxuICAgICAqICAgIE8gICAgIDMgIDVcbiAgICAgKiAgIC8gXFwgICAgfFxuICAgICAqICAxICAgMiAgIDRcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEJ5IHNldHRpbmcgYSBwYXJlbnQsIGEgcm9vdCBub2RlIG5vIG1vcmUgYmUgYSByb290LlxuICAgICAqIGBgYHRzXG4gICAgICogZ3JhcGguc2V0UGFyZW50KDUsIDIpO1xuICAgICAqIGdyYXBoLmdldFJvb3RzKCk7IC8vIFswLCAzXVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogVGhlIHRyZWUgc3RydWN0dXJlIG5vdyBiZWNvbWVzOlxuICAgICAqIGBgYFxuICAgICAqIFRyZWUgc3RydWN0dXJlOlxuICAgICAqICAgIE8gICAgIDNcbiAgICAgKiAgIC8gXFwgICAgfFxuICAgICAqICAxICAgMiAgIDRcbiAgICAgKiAgICAgIHxcbiAgICAgKiAgICAgIDVcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFJlbW92aW5nIGEgbm9kZSBmb3JjZXMgaXRzIGNoaWxkcmVuIHRvIGJlIHVucGFyZW50ZWQsIG9yIHJvb3RzLlxuICAgICAqIGBgYHRzXG4gICAgICogZ3JhcGgucmVtb3ZlTm9kZSgwKTtcbiAgICAgKiBncmFwaC5nZXRSb290cygpOyAvLyBbMSwgMiwgM11cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFlvdSBtaWdodCBkcmF3IHRoZSB0aGUgc3RydWN0dXJlIGFzIGZvbGxvdzpcbiAgICAgKiBgYGBcbiAgICAgKiBUcmVlIHN0cnVjdHVyZTpcbiAgICAgKiAgMSAgIDIgIDNcbiAgICAgKiAgICAgIHwgIHxcbiAgICAgKiAgICAgIDUgIDRcbiAgICAgKiBgYGBcbiAgICAgKiBAZ3JvdXAgVHJlZU1ldGhvZHNcbiAgICAgKi9cbiAgICBnZXRSb290cyh0cmVlS2V5KSB7XG4gICAgICAgIHRoaXMuY2hlY2tUcmVlRXhpc3RlbmNlKHRyZWVLZXkpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBbGxOb2RlcygpLmZpbHRlcigobm9kZSkgPT4gIXRoaXMuZ2V0UGFyZW50KG5vZGUuaWQsIHRyZWVLZXkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBub2RlIElEIGFuZCBhbiBvcHRpb25hbCB0cmVlIGtleSwgZ2V0IHRoZSBjaGlsZHJlbiBvZiB0aGUgbm9kZSBpbiB0aGUgc3BlY2lmaWVkIHRyZWUgc3RydWN0dXJlLlxuICAgICAqIEBncm91cCBUcmVlTWV0aG9kc1xuICAgICAqL1xuICAgIGdldENoaWxkcmVuKGlkLCB0cmVlS2V5KSB7XG4gICAgICAgIHRoaXMuY2hlY2tOb2RlRXhpc3RlbmNlKGlkKTtcbiAgICAgICAgdGhpcy5jaGVja1RyZWVFeGlzdGVuY2UodHJlZUtleSk7XG4gICAgICAgIGNvbnN0IHRyZWUgPSB0aGlzLnRyZWVJbmRpY2VzLmdldCh0cmVlS2V5KTtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSB0cmVlLmNoaWxkcmVuTWFwLmdldChpZCk7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKGNoaWxkcmVuIHx8IFtdKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBub2RlIElEIGFuZCBhbiBvcHRpb25hbCB0cmVlIGtleSwgZ2V0IHRoZSBwYXJlbnQgb2YgdGhlIG5vZGUgaW4gdGhlIHNwZWNpZmllZCB0cmVlIHN0cnVjdHVyZS5cbiAgICAgKiBJZiB0aGUgZ2l2ZW4gbm9kZSBpcyBvbmUgb2YgdGhlIHRyZWUgcm9vdHMsIHRoaXMgcmV0dXJucyBudWxsLlxuICAgICAqIEBncm91cCBUcmVlTWV0aG9kc1xuICAgICAqL1xuICAgIGdldFBhcmVudChpZCwgdHJlZUtleSkge1xuICAgICAgICB0aGlzLmNoZWNrTm9kZUV4aXN0ZW5jZShpZCk7XG4gICAgICAgIHRoaXMuY2hlY2tUcmVlRXhpc3RlbmNlKHRyZWVLZXkpO1xuICAgICAgICBjb25zdCB0cmVlID0gdGhpcy50cmVlSW5kaWNlcy5nZXQodHJlZUtleSk7XG4gICAgICAgIHJldHVybiB0cmVlLnBhcmVudE1hcC5nZXQoaWQpIHx8IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCBub2RlIHBhcmVudC4gSWYgdGhpcyBvcGVyYXRpb24gY2F1c2VzIGEgY2lyY2xlLCBpdCBmYWlscyB3aXRoIGFuIGVycm9yLlxuICAgICAqIEBwYXJhbSBpZCAtIElEIG9mIHRoZSBjaGlsZCBub2RlLlxuICAgICAqIEBwYXJhbSBwYXJlbnQgLSBJRCBvZiB0aGUgcGFyZW50IG5vZGUuXG4gICAgICogQHBhcmFtIHRyZWVLZXkgLSBXaGljaCB0cmVlIHN0cnVjdHVyZSB0aGUgcmVsYXRpb24gaXMgYXBwbGllZCB0by5cbiAgICAgKiBAZ3JvdXAgVHJlZU1ldGhvZHNcbiAgICAgKi9cbiAgICBzZXRQYXJlbnQoaWQsIHBhcmVudCwgdHJlZUtleSkge1xuICAgICAgICB0aGlzLmNoZWNrVHJlZUV4aXN0ZW5jZSh0cmVlS2V5KTtcbiAgICAgICAgY29uc3QgdHJlZSA9IHRoaXMudHJlZUluZGljZXMuZ2V0KHRyZWVLZXkpO1xuICAgICAgICBjb25zdCBub2RlID0gdGhpcy5nZXROb2RlKGlkKTtcbiAgICAgICAgY29uc3Qgb2xkUGFyZW50ID0gdHJlZS5wYXJlbnRNYXAuZ2V0KGlkKTtcbiAgICAgICAgY29uc3QgbmV3UGFyZW50ID0gdGhpcy5nZXROb2RlKHBhcmVudCk7XG4gICAgICAgIC8vIFNldCBwYXJlbnRcbiAgICAgICAgdHJlZS5wYXJlbnRNYXAuc2V0KGlkLCBuZXdQYXJlbnQpO1xuICAgICAgICAvLyBTZXQgY2hpbGRyZW5cbiAgICAgICAgaWYgKG9sZFBhcmVudCkge1xuICAgICAgICAgICAgdHJlZS5jaGlsZHJlbk1hcC5nZXQob2xkUGFyZW50LmlkKT8uZGVsZXRlKG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjaGlsZHJlbiA9IHRyZWUuY2hpbGRyZW5NYXAuZ2V0KG5ld1BhcmVudC5pZCk7XG4gICAgICAgIGlmICghY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGNoaWxkcmVuID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgdHJlZS5jaGlsZHJlbk1hcC5zZXQobmV3UGFyZW50LmlkLCBjaGlsZHJlbik7XG4gICAgICAgIH1cbiAgICAgICAgY2hpbGRyZW4uYWRkKG5vZGUpO1xuICAgICAgICB0aGlzLmJhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnVHJlZVN0cnVjdHVyZUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgIHRyZWVLZXksXG4gICAgICAgICAgICAgICAgbm9kZUlkOiBpZCxcbiAgICAgICAgICAgICAgICBvbGRQYXJlbnRJZDogb2xkUGFyZW50Py5pZCxcbiAgICAgICAgICAgICAgICBuZXdQYXJlbnRJZDogbmV3UGFyZW50LmlkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyA9PT09PT09PT09PT09PT09PSBHcmFwaCA9PT09PT09PT09PT09PT09PVxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgbm9kZXMgaW4gdGhlIGdyYXBoIGFzIGFuIGFycmF5LlxuICAgICAqL1xuICAgIGdldEFsbE5vZGVzKCkge1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLm5vZGVNYXAudmFsdWVzKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIGVkZ2VzIGluIHRoZSBncmFwaCBhcyBhbiBhcnJheS5cbiAgICAgKi9cbiAgICBnZXRBbGxFZGdlcygpIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5lZGdlTWFwLnZhbHVlcygpKTtcbiAgICB9XG4gICAgZG9CRlMocXVldWUsIHZpc2l0ZWQsIGZuKSB7XG4gICAgICAgIHdoaWxlIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgZm4obm9kZSk7XG4gICAgICAgICAgICB2aXNpdGVkLmFkZChub2RlLmlkKTtcbiAgICAgICAgICAgIHRoaXMuZ2V0U3VjY2Vzc29ycyhub2RlLmlkKS5mb3JFYWNoKChuKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCF2aXNpdGVkLmhhcyhuLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICB2aXNpdGVkLmFkZChuLmlkKTtcbiAgICAgICAgICAgICAgICAgICAgcXVldWUucHVzaChuKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBiZnMoaWQsIGZuKSB7XG4gICAgICAgIHRoaXMuZG9CRlMoW3RoaXMuZ2V0Tm9kZShpZCldLCBuZXcgU2V0KCksIGZuKTtcbiAgICB9XG4gICAgZG9ERlMobm9kZSwgdmlzaXRlZCwgZm4pIHtcbiAgICAgICAgZm4obm9kZSk7XG4gICAgICAgIHZpc2l0ZWQuYWRkKG5vZGUuaWQpO1xuICAgICAgICB0aGlzLmdldFN1Y2Nlc3NvcnMobm9kZS5pZCkuZm9yRWFjaCgobikgPT4ge1xuICAgICAgICAgICAgaWYgKCF2aXNpdGVkLmhhcyhuLmlkKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZG9ERlMobiwgdmlzaXRlZCwgZm4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGZzKGlkLCBmbikge1xuICAgICAgICB0aGlzLmRvREZTKHRoaXMuZ2V0Tm9kZShpZCksIG5ldyBTZXQoKSwgZm4pO1xuICAgIH1cbiAgICBjbG9uZSgpIHtcbiAgICAgICAgLy8gTWFrZSBhIHNoYWxsb3cgY29weSBvZiBub2RlcyBhbmQgZWRnZXMuXG4gICAgICAgIGNvbnN0IG5ld05vZGVzID0gdGhpcy5nZXRBbGxOb2RlcygpLm1hcCgob2xkTm9kZSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4ub2xkTm9kZSwgZGF0YTogeyAuLi5vbGROb2RlLmRhdGEgfSB9O1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbmV3RWRnZXMgPSB0aGlzLmdldEFsbEVkZ2VzKCkubWFwKChvbGRFZGdlKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyAuLi5vbGRFZGdlLCBkYXRhOiB7IC4uLm9sZEVkZ2UuZGF0YSB9IH07XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBDcmVhdGUgYSBuZXcgZ3JhcGggd2l0aCBzaGFsbG93IGNvcGllZCBub2RlcyBhbmQgZWRnZXMuXG4gICAgICAgIGNvbnN0IG5ld0dyYXBoID0gbmV3IEdyYXBoKHtcbiAgICAgICAgICAgIG5vZGVzOiBuZXdOb2RlcyxcbiAgICAgICAgICAgIGVkZ2VzOiBuZXdFZGdlcyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEFkZCB0cmVlIGluZGljZXMuXG4gICAgICAgIHRoaXMudHJlZUluZGljZXMuZm9yRWFjaCgoeyBwYXJlbnRNYXA6IG9sZFBhcmVudE1hcCwgY2hpbGRyZW5NYXA6IG9sZENoaWxkcmVuTWFwIH0sIHRyZWVLZXkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIG9sZFBhcmVudE1hcC5mb3JFYWNoKChwYXJlbnQsIGtleSkgPT4ge1xuICAgICAgICAgICAgICAgIHBhcmVudE1hcC5zZXQoa2V5LCBuZXdHcmFwaC5nZXROb2RlKHBhcmVudC5pZCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbk1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIG9sZENoaWxkcmVuTWFwLmZvckVhY2goKGNoaWxkcmVuLCBrZXkpID0+IHtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbk1hcC5zZXQoa2V5LCBuZXcgU2V0KEFycmF5LmZyb20oY2hpbGRyZW4pLm1hcCgobikgPT4gbmV3R3JhcGguZ2V0Tm9kZShuLmlkKSkpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbmV3R3JhcGgudHJlZUluZGljZXMuc2V0KHRyZWVLZXksIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRNYXA6IHBhcmVudE1hcCxcbiAgICAgICAgICAgICAgICBjaGlsZHJlbk1hcDogY2hpbGRyZW5NYXAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXdHcmFwaDtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgbm9kZXM6IHRoaXMuZ2V0QWxsTm9kZXMoKSxcbiAgICAgICAgICAgIGVkZ2VzOiB0aGlzLmdldEFsbEVkZ2VzKCksXG4gICAgICAgICAgICAvLyBGSVhNRTogQW5kIHRyZWUgc3RydWN0dXJlcz9cbiAgICAgICAgfSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R3JhcGguanMubWFwIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoZyAmJiAoZyA9IDAsIG9wWzBdICYmIChfID0gMCkpLCBfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcclxuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XHJcbiAgICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbn0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuIiwiZXhwb3J0IGNvbnN0IGlzU3RyaW5nID0gKHZhbDogdW5rbm93bik6IHZhbCBpcyBzdHJpbmcgPT5cbiAgdHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIjtcblxuY29uc3QgY2FjaGVTdHJpbmdGdW5jdGlvbiA9IDxUIGV4dGVuZHMgKHN0cjogc3RyaW5nKSA9PiBzdHJpbmc+KGZuOiBUKTogVCA9PiB7XG4gIGNvbnN0IGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgcmV0dXJuICgoc3RyOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBoaXQgPSBjYWNoZVtzdHJdO1xuICAgIHJldHVybiBoaXQgfHwgKGNhY2hlW3N0cl0gPSBmbihzdHIpKTtcbiAgfSkgYXMgYW55O1xufTtcblxuY29uc3QgY2FtZWxpemVSRSA9IC8tKFxcdykvZztcbmV4cG9ydCBjb25zdCBjYW1lbGl6ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oKHN0cjogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKGNhbWVsaXplUkUsIChfLCBjKSA9PiAoYyA/IGMudG9VcHBlckNhc2UoKSA6IFwiXCIpKTtcbn0pO1xuXG4vLyBleHBvcnQgY29uc3QgY2FwaXRhbGl6ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oXG4vLyAgIChzdHI6IHN0cmluZykgPT4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpLFxuLy8gKVxuIiwiZXhwb3J0IGNvbnN0IGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuIiwiZXhwb3J0IGNvbnN0IGlzT2JqZWN0ID0gKHZhbDogdW5rbm93bik6IHZhbCBpcyBSZWNvcmQ8YW55LCBhbnk+ID0+XG4gIHZhbCAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiO1xuXG5leHBvcnQgY29uc3QgY2xvbmUgPSA8VD4odGFyZ2V0OiBUKTogVCA9PiB7XG4gIGlmICh0YXJnZXQgPT09IG51bGwpIHtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG4gIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHRhcmdldC5nZXRUaW1lKCkpIGFzIGFueTtcbiAgfVxuICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBjb25zdCBjcCA9IFtdIGFzIGFueVtdO1xuICAgICh0YXJnZXQgYXMgYW55W10pLmZvckVhY2goKHYpID0+IHtcbiAgICAgIGNwLnB1c2godik7XG4gICAgfSk7XG4gICAgcmV0dXJuIGNwLm1hcCgobjogYW55KSA9PiBjbG9uZTxhbnk+KG4pKSBhcyBhbnk7XG4gIH1cbiAgaWYgKHR5cGVvZiB0YXJnZXQgPT09IFwib2JqZWN0XCIgJiYgT2JqZWN0LmtleXModGFyZ2V0KS5sZW5ndGgpIHtcbiAgICBjb25zdCBjcCA9IHsgLi4uKHRhcmdldCBhcyB7IFtrZXk6IHN0cmluZ106IGFueSB9KSB9IGFzIHtcbiAgICAgIFtrZXk6IHN0cmluZ106IGFueTtcbiAgICB9O1xuICAgIE9iamVjdC5rZXlzKGNwKS5mb3JFYWNoKChrKSA9PiB7XG4gICAgICBjcFtrXSA9IGNsb25lPGFueT4oY3Bba10pO1xuICAgIH0pO1xuICAgIHJldHVybiBjcCBhcyBUO1xuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59O1xuIiwiaW1wb3J0IHtcbiAgTWF0cml4LFxuICBNb2RlbCxcbiAgSW5kZXhNYXAsXG4gIEVkZ2UsXG4gIE5vZGUsXG4gIE91dE5vZGUsXG4gIERlZ3JlZSxcbiAgTm9kZU1hcCxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBpc0FycmF5IH0gZnJvbSBcIi4vYXJyYXlcIjtcbmltcG9ydCB7IGlzTnVtYmVyIH0gZnJvbSBcIi4vbnVtYmVyXCI7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuL29iamVjdFwiO1xuXG5leHBvcnQgY29uc3QgZ2V0RWRnZVRlcm1pbmFsID0gKGVkZ2U6IEVkZ2UsIHR5cGU6IFwic291cmNlXCIgfCBcInRhcmdldFwiKSA9PiB7XG4gIGNvbnN0IHRlcm1pbmFsID0gZWRnZVt0eXBlXTtcbiAgaWYgKGlzT2JqZWN0KHRlcm1pbmFsKSkge1xuICAgIHJldHVybiB0ZXJtaW5hbC5jZWxsO1xuICB9XG4gIHJldHVybiB0ZXJtaW5hbDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXREZWdyZWUgPSAoXG4gIG46IG51bWJlcixcbiAgbm9kZUlkeE1hcDogSW5kZXhNYXAsXG4gIGVkZ2VzOiBFZGdlW10gfCBudWxsXG4pID0+IHtcbiAgY29uc3QgZGVncmVlczogRGVncmVlW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICBkZWdyZWVzW2ldID0ge1xuICAgICAgaW46IDAsXG4gICAgICBvdXQ6IDAsXG4gICAgICBhbGw6IDAsXG4gICAgfTtcbiAgfVxuICBpZiAoIWVkZ2VzKSByZXR1cm4gZGVncmVlcztcbiAgZWRnZXMuZm9yRWFjaCgoZSkgPT4ge1xuICAgIGNvbnN0IHNvdXJjZSA9IGdldEVkZ2VUZXJtaW5hbChlLCBcInNvdXJjZVwiKTtcbiAgICBjb25zdCB0YXJnZXQgPSBnZXRFZGdlVGVybWluYWwoZSwgXCJ0YXJnZXRcIik7XG4gICAgaWYgKHNvdXJjZSAmJiBkZWdyZWVzW25vZGVJZHhNYXBbc291cmNlXV0pIHtcbiAgICAgIGRlZ3JlZXNbbm9kZUlkeE1hcFtzb3VyY2VdXS5vdXQgKz0gMTtcbiAgICAgIGRlZ3JlZXNbbm9kZUlkeE1hcFtzb3VyY2VdXS5hbGwgKz0gMTtcbiAgICB9XG4gICAgaWYgKHRhcmdldCAmJiBkZWdyZWVzW25vZGVJZHhNYXBbdGFyZ2V0XV0pIHtcbiAgICAgIGRlZ3JlZXNbbm9kZUlkeE1hcFt0YXJnZXRdXS5pbiArPSAxO1xuICAgICAgZGVncmVlc1tub2RlSWR4TWFwW3RhcmdldF1dLmFsbCArPSAxO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBkZWdyZWVzO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldERlZ3JlZU1hcCA9IChub2RlczogTm9kZVtdLCBlZGdlczogRWRnZVtdIHwgbnVsbCkgPT4ge1xuICBjb25zdCBkZWdyZWVzTWFwOiB7IFtpZDogc3RyaW5nXTogRGVncmVlIH0gPSB7fTtcbiAgbm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgIGRlZ3JlZXNNYXBbbm9kZS5pZF0gPSB7XG4gICAgICBpbjogMCxcbiAgICAgIG91dDogMCxcbiAgICAgIGFsbDogMCxcbiAgICB9O1xuICB9KTtcblxuICBpZiAoIWVkZ2VzKSByZXR1cm4gZGVncmVlc01hcDtcbiAgZWRnZXMuZm9yRWFjaCgoZSkgPT4ge1xuICAgIGNvbnN0IHNvdXJjZSA9IGdldEVkZ2VUZXJtaW5hbChlLCBcInNvdXJjZVwiKTtcbiAgICBjb25zdCB0YXJnZXQgPSBnZXRFZGdlVGVybWluYWwoZSwgXCJ0YXJnZXRcIik7XG4gICAgaWYgKHNvdXJjZSkge1xuICAgICAgZGVncmVlc01hcFtzb3VyY2VdLm91dCArPSAxO1xuICAgICAgZGVncmVlc01hcFtzb3VyY2VdLmFsbCArPSAxO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0KSB7XG4gICAgICBkZWdyZWVzTWFwW3RhcmdldF0uaW4gKz0gMTtcbiAgICAgIGRlZ3JlZXNNYXBbdGFyZ2V0XS5hbGwgKz0gMTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gZGVncmVlc01hcDtcbn07XG5cbmV4cG9ydCBjb25zdCBmbG95ZFdhcnNoYWxsID0gKGFkak1hdHJpeDogTWF0cml4W10pOiBNYXRyaXhbXSA9PiB7XG4gIC8vIGluaXRpYWxpemVcbiAgY29uc3QgZGlzdDogTWF0cml4W10gPSBbXTtcbiAgY29uc3Qgc2l6ZSA9IGFkak1hdHJpeC5sZW5ndGg7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSArPSAxKSB7XG4gICAgZGlzdFtpXSA9IFtdO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgc2l6ZTsgaiArPSAxKSB7XG4gICAgICBpZiAoaSA9PT0gaikge1xuICAgICAgICBkaXN0W2ldW2pdID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoYWRqTWF0cml4W2ldW2pdID09PSAwIHx8ICFhZGpNYXRyaXhbaV1bal0pIHtcbiAgICAgICAgZGlzdFtpXVtqXSA9IEluZmluaXR5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlzdFtpXVtqXSA9IGFkak1hdHJpeFtpXVtqXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLy8gZmxveWRcbiAgZm9yIChsZXQgayA9IDA7IGsgPCBzaXplOyBrICs9IDEpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkgKz0gMSkge1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzaXplOyBqICs9IDEpIHtcbiAgICAgICAgaWYgKGRpc3RbaV1bal0gPiBkaXN0W2ldW2tdICsgZGlzdFtrXVtqXSkge1xuICAgICAgICAgIGRpc3RbaV1bal0gPSBkaXN0W2ldW2tdICsgZGlzdFtrXVtqXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZGlzdDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRBZGpNYXRyaXggPSAoZGF0YTogTW9kZWwsIGRpcmVjdGVkOiBib29sZWFuKTogTWF0cml4W10gPT4ge1xuICBjb25zdCB7IG5vZGVzLCBlZGdlcyB9ID0gZGF0YTtcbiAgY29uc3QgbWF0cml4OiBNYXRyaXhbXSA9IFtdO1xuICAvLyBtYXAgbm9kZSB3aXRoIGluZGV4IGluIGRhdGEubm9kZXNcbiAgY29uc3Qgbm9kZU1hcDoge1xuICAgIFtrZXk6IHN0cmluZ106IG51bWJlcjtcbiAgfSA9IHt9O1xuXG4gIGlmICghbm9kZXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIG5vZGVzIGRhdGEhXCIpO1xuICB9XG4gIGlmIChub2Rlcykge1xuICAgIG5vZGVzLmZvckVhY2goKG5vZGUsIGkpID0+IHtcbiAgICAgIG5vZGVNYXBbbm9kZS5pZF0gPSBpO1xuICAgICAgY29uc3Qgcm93OiBudW1iZXJbXSA9IFtdO1xuICAgICAgbWF0cml4LnB1c2gocm93KTtcbiAgICB9KTtcbiAgfVxuXG4gIGVkZ2VzPy5mb3JFYWNoKChlKSA9PiB7XG4gICAgY29uc3Qgc291cmNlID0gZ2V0RWRnZVRlcm1pbmFsKGUsIFwic291cmNlXCIpO1xuICAgIGNvbnN0IHRhcmdldCA9IGdldEVkZ2VUZXJtaW5hbChlLCBcInRhcmdldFwiKTtcbiAgICBjb25zdCBzSW5kZXggPSBub2RlTWFwW3NvdXJjZSBhcyBzdHJpbmddO1xuICAgIGNvbnN0IHRJbmRleCA9IG5vZGVNYXBbdGFyZ2V0IGFzIHN0cmluZ107XG4gICAgaWYgKHNJbmRleCA9PT0gdW5kZWZpbmVkIHx8IHRJbmRleCA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgbWF0cml4W3NJbmRleF1bdEluZGV4XSA9IDE7XG4gICAgaWYgKCFkaXJlY3RlZCkge1xuICAgICAgbWF0cml4W3RJbmRleF1bc0luZGV4XSA9IDE7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG1hdHJpeDtcbn07XG5cbi8qKlxuICogc2NhbGUgbWF0cml4XG4gKiBAcGFyYW0gbWF0cml4IFsgW10sIFtdLCBbXSBdXG4gKiBAcGFyYW0gcmF0aW9cbiAqL1xuZXhwb3J0IGNvbnN0IHNjYWxlTWF0cml4ID0gKG1hdHJpeDogTWF0cml4W10sIHJhdGlvOiBudW1iZXIpID0+IHtcbiAgY29uc3QgcmVzdWx0OiBNYXRyaXhbXSA9IFtdO1xuICBtYXRyaXguZm9yRWFjaCgocm93KSA9PiB7XG4gICAgY29uc3QgbmV3Um93OiBudW1iZXJbXSA9IFtdO1xuICAgIHJvdy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICBuZXdSb3cucHVzaCh2ICogcmF0aW8pO1xuICAgIH0pO1xuICAgIHJlc3VsdC5wdXNoKG5ld1Jvdyk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyoqXG4gKiBkZXB0aCBmaXJzdCB0cmF2ZXJzZSwgZnJvbSBsZWF2ZXMgdG8gcm9vdCwgY2hpbGRyZW4gaW4gaW52ZXJzZSBvcmRlclxuICogIGlmIHRoZSBmbiByZXR1cm5zIGZhbHNlLCB0ZXJtaW5hdGUgdGhlIHRyYXZlcnNlXG4gKi9cbmNvbnN0IHRyYXZlcnNlVXAgPSA8VCBleHRlbmRzIHsgY2hpbGRyZW4/OiBUW10gfT4oXG4gIGRhdGE6IFQsXG4gIGZuOiAocGFyYW06IFQpID0+IGJvb2xlYW5cbikgPT4ge1xuICBpZiAoZGF0YSAmJiBkYXRhLmNoaWxkcmVuKSB7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGlmICghdHJhdmVyc2VVcChkYXRhLmNoaWxkcmVuW2ldLCBmbikpIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAoIWZuKGRhdGEpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBkZXB0aCBmaXJzdCB0cmF2ZXJzZSwgZnJvbSBsZWF2ZXMgdG8gcm9vdCwgY2hpbGRyZW4gaW4gaW52ZXJzZSBvcmRlclxuICogaWYgdGhlIGZuIHJldHVybnMgZmFsc2UsIHRlcm1pbmF0ZSB0aGUgdHJhdmVyc2VcbiAqL1xuZXhwb3J0IGNvbnN0IHRyYXZlcnNlVHJlZVVwID0gPFQgZXh0ZW5kcyB7IGNoaWxkcmVuPzogVFtdIH0+KFxuICBkYXRhOiBULFxuICBmbjogKHBhcmFtOiBUKSA9PiBib29sZWFuXG4pID0+IHtcbiAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRyYXZlcnNlVXAoZGF0YSwgZm4pO1xufTtcblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIGJvdW5kaW5nIGJveCBmb3IgdGhlIG5vZGVzIGFjY29yZGluZyB0byB0aGVpciB4LCB5LCBhbmQgc2l6ZVxuICogQHBhcmFtIG5vZGVzIG5vZGVzIGluIHRoZSBsYXlvdXRcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRMYXlvdXRCQm94ID0gKG5vZGVzOiBPdXROb2RlW10pID0+IHtcbiAgbGV0IG1pblggPSBJbmZpbml0eTtcbiAgbGV0IG1pblkgPSBJbmZpbml0eTtcbiAgbGV0IG1heFggPSAtSW5maW5pdHk7XG4gIGxldCBtYXhZID0gLUluZmluaXR5O1xuICBub2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgbGV0IHNpemUgPSBub2RlLnNpemU7XG4gICAgaWYgKGlzQXJyYXkoc2l6ZSkpIHtcbiAgICAgIGlmIChzaXplLmxlbmd0aCA9PT0gMSkgc2l6ZSA9IFtzaXplWzBdLCBzaXplWzBdXTtcbiAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKHNpemUpKSB7XG4gICAgICBzaXplID0gW3NpemUsIHNpemVdO1xuICAgIH0gZWxzZSBpZiAoc2l6ZSA9PT0gdW5kZWZpbmVkIHx8IGlzTmFOKHNpemUgYXMgYW55KSkge1xuICAgICAgc2l6ZSA9IFszMCwgMzBdO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbGZTaXplID0gW3NpemVbMF0gLyAyLCBzaXplWzFdIC8gMl07XG4gICAgY29uc3QgbGVmdCA9IG5vZGUueCAtIGhhbGZTaXplWzBdO1xuICAgIGNvbnN0IHJpZ2h0ID0gbm9kZS54ICsgaGFsZlNpemVbMF07XG4gICAgY29uc3QgdG9wID0gbm9kZS55IC0gaGFsZlNpemVbMV07XG4gICAgY29uc3QgYm90dG9tID0gbm9kZS55ICsgaGFsZlNpemVbMV07XG5cbiAgICBpZiAobWluWCA+IGxlZnQpIG1pblggPSBsZWZ0O1xuICAgIGlmIChtaW5ZID4gdG9wKSBtaW5ZID0gdG9wO1xuICAgIGlmIChtYXhYIDwgcmlnaHQpIG1heFggPSByaWdodDtcbiAgICBpZiAobWF4WSA8IGJvdHRvbSkgbWF4WSA9IGJvdHRvbTtcbiAgfSk7XG4gIHJldHVybiB7IG1pblgsIG1pblksIG1heFgsIG1heFkgfTtcbn07XG5cbi8qKlxuICog6I635Y+W6IqC54K56ZuG5ZCI55qE5bmz5Z2H5L2N572u5L+h5oGvXG4gKiBAcGFyYW0gbm9kZXMg6IqC54K56ZuG5ZCIXG4gKiBAcmV0dXJucyDlubPlsYDlhoXnva5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEF2Z05vZGVQb3NpdGlvbiA9IChub2RlczogT3V0Tm9kZVtdKSA9PiB7XG4gIGNvbnN0IHRvdGFsTm9kZXMgPSB7IHg6IDAsIHk6IDAgfTtcbiAgbm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgIHRvdGFsTm9kZXMueCArPSBub2RlLnggfHwgMDtcbiAgICB0b3RhbE5vZGVzLnkgKz0gbm9kZS55IHx8IDA7XG4gIH0pO1xuICAvLyDojrflj5blnYflgLzlkJHph49cbiAgY29uc3QgbGVuZ3RoID0gbm9kZXMubGVuZ3RoIHx8IDE7XG4gIHJldHVybiB7XG4gICAgeDogdG90YWxOb2Rlcy54IC8gbGVuZ3RoLFxuICAgIHk6IHRvdGFsTm9kZXMueSAvIGxlbmd0aCxcbiAgfTtcbn07XG5cbi8vIOaJvuWHuuaMh+WumuiKgueCueWFs+iBlOeahOi+ueeahOi1t+eCueaIlue7iOeCuVxuY29uc3QgZ2V0Q29yZU5vZGUgPSAodHlwZTogXCJzb3VyY2VcIiB8IFwidGFyZ2V0XCIsIG5vZGU6IE5vZGUsIGVkZ2VzOiBFZGdlW10pID0+IHtcbiAgaWYgKHR5cGUgPT09IFwic291cmNlXCIpIHtcbiAgICByZXR1cm4gKGVkZ2VzPy5maW5kKChlZGdlKSA9PiBlZGdlLnRhcmdldCA9PT0gbm9kZS5pZCk/LnNvdXJjZSB8fFxuICAgICAge30pIGFzIE5vZGU7XG4gIH1cbiAgcmV0dXJuIChlZGdlcz8uZmluZCgoZWRnZSkgPT4gZWRnZS5zb3VyY2UgPT09IG5vZGUuaWQpPy50YXJnZXQgfHwge30pIGFzIE5vZGU7XG59O1xuXG4vLyDmib7lh7rmjIflrproioLngrnkuLrotbfngrnmiJbnu4jngrnnmoTmiYDmnInkuIDluqblj7blrZDoioLngrlcbmNvbnN0IGdldFJlbGF0aXZlTm9kZUlkcyA9IChcbiAgdHlwZTogXCJzb3VyY2VcIiB8IFwidGFyZ2V0XCIgfCBcImJvdGhcIixcbiAgY29yZU5vZGU6IE5vZGUsXG4gIGVkZ2VzOiBFZGdlW11cbikgPT4ge1xuICBsZXQgcmVsYXRpdmVOb2Rlczogc3RyaW5nW10gPSBbXTtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBcInNvdXJjZVwiOlxuICAgICAgcmVsYXRpdmVOb2RlcyA9IGVkZ2VzXG4gICAgICAgID8uZmlsdGVyKChlZGdlKSA9PiBlZGdlLnNvdXJjZSA9PT0gY29yZU5vZGUuaWQpXG4gICAgICAgIC5tYXAoKGVkZ2UpID0+IGVkZ2UudGFyZ2V0KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJ0YXJnZXRcIjpcbiAgICAgIHJlbGF0aXZlTm9kZXMgPSBlZGdlc1xuICAgICAgICA/LmZpbHRlcigoZWRnZSkgPT4gZWRnZS50YXJnZXQgPT09IGNvcmVOb2RlLmlkKVxuICAgICAgICAubWFwKChlZGdlKSA9PiBlZGdlLnNvdXJjZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFwiYm90aFwiOlxuICAgICAgcmVsYXRpdmVOb2RlcyA9IGVkZ2VzXG4gICAgICAgID8uZmlsdGVyKChlZGdlKSA9PiBlZGdlLnNvdXJjZSA9PT0gY29yZU5vZGUuaWQpXG4gICAgICAgIC5tYXAoKGVkZ2UpID0+IGVkZ2UudGFyZ2V0KVxuICAgICAgICAuY29uY2F0KFxuICAgICAgICAgIGVkZ2VzXG4gICAgICAgICAgICA/LmZpbHRlcigoZWRnZSkgPT4gZWRnZS50YXJnZXQgPT09IGNvcmVOb2RlLmlkKVxuICAgICAgICAgICAgLm1hcCgoZWRnZSkgPT4gZWRnZS5zb3VyY2UpXG4gICAgICAgICk7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgYnJlYWs7XG4gIH1cbiAgLy8g5Y676YeNXG4gIGNvbnN0IHNldCA9IG5ldyBTZXQocmVsYXRpdmVOb2Rlcyk7XG4gIHJldHVybiBBcnJheS5mcm9tKHNldCk7XG59O1xuLy8g5om+5Ye65ZCM57G75Z6L55qE6IqC54K5XG5jb25zdCBnZXRTYW1lVHlwZU5vZGVzID0gKFxuICB0eXBlOiBcImxlYWZcIiB8IFwiYWxsXCIsXG4gIG5vZGVDbHVzdGVyQnk6IHN0cmluZyxcbiAgbm9kZTogTm9kZSxcbiAgcmVsYXRpdmVOb2RlczogTm9kZVtdLFxuICBkZWdyZWVzTWFwOiB7IFtpZDogc3RyaW5nXTogRGVncmVlIH1cbikgPT4ge1xuICAvLyBAdHMtaWdub3JlXG4gIGNvbnN0IHR5cGVOYW1lID0gbm9kZVtub2RlQ2x1c3RlckJ5XSB8fCBcIlwiO1xuICAvLyBAdHMtaWdub3JlXG4gIGxldCBzYW1lVHlwZU5vZGVzID1cbiAgICByZWxhdGl2ZU5vZGVzPy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW1bbm9kZUNsdXN0ZXJCeV0gPT09IHR5cGVOYW1lKSB8fCBbXTtcbiAgaWYgKHR5cGUgPT09IFwibGVhZlwiKSB7XG4gICAgc2FtZVR5cGVOb2RlcyA9IHNhbWVUeXBlTm9kZXMuZmlsdGVyKFxuICAgICAgKG5vZGUpID0+IGRlZ3JlZXNNYXBbbm9kZS5pZF0/LmluID09PSAwIHx8IGRlZ3JlZXNNYXBbbm9kZS5pZF0/Lm91dCA9PT0gMFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHNhbWVUeXBlTm9kZXM7XG59O1xuXG4vLyDmib7lh7rkuI7mjIflrproioLngrnlhbPogZTnmoTovrnnmoTotbfngrnmiJbnu4jngrnlh7rlj5HnmoTmiYDmnInkuIDluqblj7blrZDoioLngrlcbmV4cG9ydCBjb25zdCBnZXRDb3JlTm9kZUFuZFJlbGF0aXZlTGVhZk5vZGVzID0gKFxuICB0eXBlOiBcImxlYWZcIiB8IFwiYWxsXCIsXG4gIG5vZGU6IE5vZGUsXG4gIGVkZ2VzOiBFZGdlW10sXG4gIG5vZGVDbHVzdGVyQnk6IHN0cmluZyxcbiAgZGVncmVlc01hcDogeyBbaWQ6IHN0cmluZ106IERlZ3JlZSB9LFxuICBub2RlTWFwOiBOb2RlTWFwXG4pID0+IHtcbiAgY29uc3QgeyBpbjogaW5EZWdyZWUsIG91dDogb3V0RGVncmVlIH0gPSBkZWdyZWVzTWFwW25vZGUuaWRdO1xuICBsZXQgY29yZU5vZGU6IE5vZGUgPSBub2RlO1xuICBsZXQgcmVsYXRpdmVMZWFmTm9kZXM6IE5vZGVbXSA9IFtdO1xuICBpZiAoaW5EZWdyZWUgPT09IDApIHtcbiAgICAvLyDlpoLmnpzkuLrmsqHmnInlh7rovrnnmoTlj7blrZDoioLngrnvvIzliJnmib7lh7rkuI7lroPlhbPogZTnmoTovrnnmoTotbfngrnlh7rlj5HnmoTmiYDmnInkuIDluqboioLngrlcbiAgICBjb3JlTm9kZSA9IGdldENvcmVOb2RlKFwic291cmNlXCIsIG5vZGUsIGVkZ2VzKTtcbiAgICByZWxhdGl2ZUxlYWZOb2RlcyA9IGdldFJlbGF0aXZlTm9kZUlkcyhcImJvdGhcIiwgY29yZU5vZGUsIGVkZ2VzKS5tYXAoXG4gICAgICAobm9kZUlkKSA9PiBub2RlTWFwW25vZGVJZF1cbiAgICApO1xuICB9IGVsc2UgaWYgKG91dERlZ3JlZSA9PT0gMCkge1xuICAgIC8vIOWmguaenOS4uuayoeacieWFpei+uei+ueeahOWPtuWtkOiKgueCue+8jOWImeaJvuWHuuS4juWug+WFs+iBlOeahOi+ueeahOi1t+eCueWHuuWPkeeahOaJgOacieS4gOW6puiKgueCuVxuICAgIGNvcmVOb2RlID0gZ2V0Q29yZU5vZGUoXCJ0YXJnZXRcIiwgbm9kZSwgZWRnZXMpO1xuICAgIHJlbGF0aXZlTGVhZk5vZGVzID0gZ2V0UmVsYXRpdmVOb2RlSWRzKFwiYm90aFwiLCBjb3JlTm9kZSwgZWRnZXMpLm1hcChcbiAgICAgIChub2RlSWQpID0+IG5vZGVNYXBbbm9kZUlkXVxuICAgICk7XG4gIH1cbiAgcmVsYXRpdmVMZWFmTm9kZXMgPSByZWxhdGl2ZUxlYWZOb2Rlcy5maWx0ZXIoXG4gICAgKG5vZGUpID0+XG4gICAgICBkZWdyZWVzTWFwW25vZGUuaWRdICYmXG4gICAgICAoZGVncmVlc01hcFtub2RlLmlkXS5pbiA9PT0gMCB8fCBkZWdyZWVzTWFwW25vZGUuaWRdLm91dCA9PT0gMClcbiAgKTtcbiAgY29uc3Qgc2FtZVR5cGVMZWFmTm9kZXMgPSBnZXRTYW1lVHlwZU5vZGVzKFxuICAgIHR5cGUsXG4gICAgbm9kZUNsdXN0ZXJCeSxcbiAgICBub2RlLFxuICAgIHJlbGF0aXZlTGVhZk5vZGVzLFxuICAgIGRlZ3JlZXNNYXBcbiAgKTtcbiAgcmV0dXJuIHsgY29yZU5vZGUsIHJlbGF0aXZlTGVhZk5vZGVzLCBzYW1lVHlwZUxlYWZOb2RlcyB9O1xufTtcbiIsImltcG9ydCB7IGlzQXJyYXksIGlzT2JqZWN0IH0gZnJvbSBcIi5cIjtcbmltcG9ydCB7IGlzTnVtYmVyIH0gZnJvbSBcIi4vbnVtYmVyXCI7XG5cbmV4cG9ydCBjb25zdCBpc0Z1bmN0aW9uID0gKHZhbDogdW5rbm93bik6IHZhbCBpcyBGdW5jdGlvbiA9PlxuICB0eXBlb2YgdmFsID09PSBcImZ1bmN0aW9uXCI7XG5cbmV4cG9ydCBjb25zdCBnZXRGdW5jID0gKFxuICB2YWx1ZTogbnVtYmVyLFxuICBkZWZhdWx0VmFsdWU6IG51bWJlcixcbiAgZnVuYz86ICgoZD86IGFueSkgPT4gbnVtYmVyKSB8IHVuZGVmaW5lZFxuKTogRnVuY3Rpb24gPT4ge1xuICBsZXQgcmVzdWx0RnVuYztcbiAgaWYgKGZ1bmMpIHtcbiAgICByZXN1bHRGdW5jID0gZnVuYztcbiAgfSBlbHNlIGlmIChpc051bWJlcih2YWx1ZSkpIHtcbiAgICByZXN1bHRGdW5jID0gKCkgPT4gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0RnVuYyA9ICgpID0+IGRlZmF1bHRWYWx1ZTtcbiAgfVxuICByZXR1cm4gcmVzdWx0RnVuYztcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRGdW5jQnlVbmtub3duVHlwZSA9IChcbiAgZGVmYXVsdFZhbHVlOiBudW1iZXIsXG4gIHZhbHVlPzpcbiAgICB8IG51bWJlclxuICAgIHwgbnVtYmVyW11cbiAgICB8IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfVxuICAgIHwgKChkPzogYW55KSA9PiBudW1iZXIpXG4gICAgfCB1bmRlZmluZWQsXG4gIHJlc3VsdElzTnVtYmVyOiBib29sZWFuID0gdHJ1ZVxuKTogKChkPzogYW55KSA9PiBudW1iZXIgfCBudW1iZXJbXSkgPT4ge1xuICBpZiAoIXZhbHVlICYmIHZhbHVlICE9PSAwKSB7XG4gICAgcmV0dXJuIChkKSA9PiB7XG4gICAgICBpZiAoZC5zaXplKSB7XG4gICAgICAgIGlmIChpc0FycmF5KGQuc2l6ZSkpXG4gICAgICAgICAgcmV0dXJuIGQuc2l6ZVswXSA+IGQuc2l6ZVsxXSA/IGQuc2l6ZVswXSA6IGQuc2l6ZVsxXTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KGQuc2l6ZSkpXG4gICAgICAgICAgcmV0dXJuIGQuc2l6ZS53aWR0aCA+IGQuc2l6ZS5oZWlnaHQgPyBkLnNpemUud2lkdGggOiBkLnNpemUuaGVpZ2h0O1xuICAgICAgICByZXR1cm4gZC5zaXplO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9O1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgcmV0dXJuICgpID0+IHZhbHVlO1xuICB9XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAocmVzdWx0SXNOdW1iZXIpIHtcbiAgICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoLi4uKHZhbHVlIGFzIG51bWJlcltdKSk7XG4gICAgICAgIHJldHVybiBpc05hTihtYXgpID8gZGVmYXVsdFZhbHVlIDogbWF4O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH1cbiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAocmVzdWx0SXNOdW1iZXIpIHtcbiAgICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgodmFsdWUud2lkdGgsIHZhbHVlLmhlaWdodCk7XG4gICAgICAgIHJldHVybiBpc05hTihtYXgpID8gZGVmYXVsdFZhbHVlIDogbWF4O1xuICAgICAgfVxuICAgICAgcmV0dXJuIFt2YWx1ZS53aWR0aCwgdmFsdWUuaGVpZ2h0XTtcbiAgICB9O1xuICB9XG4gIHJldHVybiAoKSA9PiBkZWZhdWx0VmFsdWU7XG59O1xuIiwiZXhwb3J0IGNvbnN0IGlzTnVtYmVyID0gKHZhbDogdW5rbm93bik6IHZhbCBpcyBOdW1iZXIgPT5cbiAgdHlwZW9mIHZhbCA9PT0gXCJudW1iZXJcIjtcblxuZXhwb3J0IGNvbnN0IGlzTmFOID0gKG51bTogdW5rbm93bikgPT4gTnVtYmVyLmlzTmFOKE51bWJlcihudW0pKTtcblxuZXhwb3J0IGNvbnN0IHRvTnVtYmVyID0gKHZhbDogYW55KTogYW55ID0+IHtcbiAgY29uc3QgbiA9IHBhcnNlRmxvYXQodmFsKTtcbiAgcmV0dXJuIGlzTmFOKG4pID8gdmFsIDogbjtcbn07XG4iLCJpbXBvcnQgdHlwZSB7IEdyYXBoIH0gZnJvbSBcIkBhbnR2L2dyYXBobGliXCI7XG5pbXBvcnQgdHlwZSB7IENpcmN1bGFyTGF5b3V0T3B0aW9ucywgU3luY0xheW91dCwgTGF5b3V0TWFwcGluZywgUG9pbnRUdXBsZSwgSW5kZXhNYXAsIE91dE5vZGUsIEVkZ2UsIERlZ3JlZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXREZWdyZWUsIGdldEVkZ2VUZXJtaW5hbCwgZ2V0RnVuY0J5VW5rbm93blR5cGUsIGNsb25lIH0gZnJvbSBcIi4vdXRpbFwiO1xuXG50eXBlIElOb2RlRGF0YSA9IE91dE5vZGUgJiB7XG4gIGRlZ3JlZTogbnVtYmVyO1xuICBzaXplOiBudW1iZXIgfCBQb2ludFR1cGxlO1xuICB3ZWlnaHQ6IG51bWJlcjtcbiAgY2hpbGRyZW46IHN0cmluZ1tdO1xuICBwYXJlbnQ6IHN0cmluZ1tdO1xufTtcblxudHlwZSBJRWRnZURhdGEgPSB7fTtcblxuY29uc3QgREVGQVVMVFNfTEFZT1VUX09QVElPTlM6IFBhcnRpYWw8Q2lyY3VsYXJMYXlvdXRPcHRpb25zPiA9IHtcbiAgcmFkaXVzOiBudWxsLFxuICBzdGFydFJhZGl1czogbnVsbCxcbiAgZW5kUmFkaXVzOiBudWxsLFxuICBzdGFydEFuZ2xlOiAwLFxuICBlbmRBbmdsZTogMiAqIE1hdGguUEksXG4gIGNsb2Nrd2lzZTogdHJ1ZSxcbiAgZGl2aXNpb25zOiAxLFxuICBvcmRlcmluZzogbnVsbCxcbiAgYW5nbGVSYXRpbzogMVxufVxuXG4vKipcbiAqIExheW91dCBhcnJhbmdpbmcgdGhlIG5vZGVzIGluIGEgY2lyY2xlLlxuICogXG4gKiBAZXhhbXBsZVxuICogLy8gQXNzaWduIGxheW91dCBvcHRpb25zIHdoZW4gaW5pdGlhbGl6YXRpb24uXG4gKiBjb25zdCBsYXlvdXQgPSBuZXcgQ2lyY3VsYXJMYXlvdXQoeyByYWRpdXM6IDEwIH0pO1xuICogY29uc3QgcG9zaXRpb25zID0gbGF5b3V0LmV4ZWN1dGUoZ3JhcGgpOyAvLyB7IG5vZGVzOiBbXSwgZWRnZXM6IFtdIH1cbiAqIFxuICogLy8gT3IgdXNlIGRpZmZlcmVudCBvcHRpb25zIGxhdGVyLlxuICogY29uc3QgbGF5b3V0ID0gbmV3IENpcmN1bGFyTGF5b3V0KHsgcmFkaXVzOiAxMCB9KTtcbiAqIGNvbnN0IHBvc2l0aW9ucyA9IGxheW91dC5leGVjdXRlKGdyYXBoLCB7IHJhZGl1czogMjAgfSk7IC8vIHsgbm9kZXM6IFtdLCBlZGdlczogW10gfVxuICogXG4gKiAvLyBJZiB5b3Ugd2FudCB0byBhc3NpZ24gdGhlIHBvc2l0aW9ucyBkaXJlY3RseSB0byB0aGUgbm9kZXMsIHVzZSBhc3NpZ24gbWV0aG9kLlxuICogbGF5b3V0LmFzc2lnbihncmFwaCwgeyByYWRpdXM6IDIwIH0pO1xuICovXG5leHBvcnQgY2xhc3MgQ2lyY3VsYXJMYXlvdXQgaW1wbGVtZW50cyBTeW5jTGF5b3V0PENpcmN1bGFyTGF5b3V0T3B0aW9ucz4ge1xuICBpZCA9ICdjaXJjdWxhcic7XG5cbiAgY29uc3RydWN0b3IocHVibGljIG9wdGlvbnM6IENpcmN1bGFyTGF5b3V0T3B0aW9ucyA9IHt9IGFzIENpcmN1bGFyTGF5b3V0T3B0aW9ucykge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5vcHRpb25zLCBERUZBVUxUU19MQVlPVVRfT1BUSU9OUywgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBwb3NpdGlvbnMgb2Ygbm9kZXMgYW5kIGVkZ2VzKGlmIG5lZWRlZCkuXG4gICAqL1xuICBleGVjdXRlKGdyYXBoOiBHcmFwaDxJTm9kZURhdGEsIElFZGdlRGF0YT4sIG9wdGlvbnM/OiBDaXJjdWxhckxheW91dE9wdGlvbnMpOiBMYXlvdXRNYXBwaW5nIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcmljQ2lyY3VsYXJMYXlvdXQoZmFsc2UsIGdyYXBoLCBvcHRpb25zKSBhcyBMYXlvdXRNYXBwaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvIGRpcmVjdGx5IGFzc2lnbiB0aGUgcG9zaXRpb25zIHRvIHRoZSBub2Rlcy5cbiAgICovXG4gIGFzc2lnbihncmFwaDogR3JhcGg8SU5vZGVEYXRhLCBJRWRnZURhdGE+LCBvcHRpb25zPzogQ2lyY3VsYXJMYXlvdXRPcHRpb25zKSB7XG4gICAgZ3JhcGguYmF0Y2goKCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmljQ2lyY3VsYXJMYXlvdXQodHJ1ZSwgZ3JhcGgsIG9wdGlvbnMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZW5lcmljQ2lyY3VsYXJMYXlvdXQoYXNzaWduOiBib29sZWFuLCBncmFwaDogR3JhcGg8SU5vZGVEYXRhLCBJRWRnZURhdGE+LCBvcHRpb25zPzogQ2lyY3VsYXJMYXlvdXRPcHRpb25zKTogTGF5b3V0TWFwcGluZyB8IHZvaWQge1xuICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLnRoaXMub3B0aW9ucywgLi4ub3B0aW9ucyB9O1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCwgY2VudGVyLCBkaXZpc2lvbnMsIHN0YXJ0QW5nbGUgPSAwLCBlbmRBbmdsZSA9IDIgKiBNYXRoLlBJLCBhbmdsZVJhdGlvLCBvcmRlcmluZywgY2xvY2t3aXNlLCBub2RlU3BhY2luZzogcGFyYW1Ob2RlU3BhY2luZywgbm9kZVNpemU6IHBhcmFtTm9kZVNpemUsIG9uTGF5b3V0RW5kIH0gPSBtZXJnZWRPcHRpb25zO1xuXG4gICAgY29uc3Qgbm9kZXMgPSBncmFwaC5nZXRBbGxOb2RlcygpO1xuICAgIGNvbnN0IGVkZ2VzID0gZ3JhcGguZ2V0QWxsRWRnZXMoKSBhcyBFZGdlW107XG4gICAgY29uc3QgbiA9IG5vZGVzLmxlbmd0aDtcblxuICAgIC8vIE5lZWQgbm8gbGF5b3V0IGlmIHRoZXJlIGlzIG5vIG5vZGUuXG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChvbkxheW91dEVuZCkge1xuICAgICAgICBvbkxheW91dEVuZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbm9kZXM6IFtdLFxuICAgICAgICBlZGdlczogW10sXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIENhbGN1bGF0ZSBjZW50ZXIgYWNjb3JkaW5nIHRvIGB3aW5kb3dgIGlmIG5vdCBwcm92aWRlZC5cbiAgICBjb25zdCBbY2FsY3VsYXRlZFdpZHRoLCBjYWxjdWxhdGVkSGVpZ2h0LCBjYWxjdWxhdGVkQ2VudGVyXSA9IGNhbGN1bGF0ZUNlbnRlcih3aWR0aCwgaGVpZ2h0LCBjZW50ZXIpO1xuXG4gICAgLy8gTGF5b3V0IGVhc2lseSBpZiB0aGVyZSBpcyBvbmx5IG9uZSBub2RlLlxuICAgIGlmIChuID09PSAxKSB7XG4gICAgICBpZiAoYXNzaWduKSB7XG4gICAgICAgIGdyYXBoLnVwZGF0ZU5vZGVEYXRhKG5vZGVzWzBdLmlkLCBcInhcIiwgY2FsY3VsYXRlZENlbnRlclswXSk7XG4gICAgICAgIGdyYXBoLnVwZGF0ZU5vZGVEYXRhKG5vZGVzWzBdLmlkLCBcInlcIiwgY2FsY3VsYXRlZENlbnRlclsxXSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGlmIChvbkxheW91dEVuZCkge1xuICAgICAgICBvbkxheW91dEVuZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbm9kZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogYCR7bm9kZXNbMF0uaWR9YCxcbiAgICAgICAgICAgIHg6IGNhbGN1bGF0ZWRDZW50ZXJbMF0sXG4gICAgICAgICAgICB5OiBjYWxjdWxhdGVkQ2VudGVyWzFdLFxuICAgICAgICAgIH1cbiAgICAgICAgXSxcbiAgICAgICAgZWRnZXM6IFtdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBhbmdsZVN0ZXAgPSAoZW5kQW5nbGUgLSBzdGFydEFuZ2xlKSAvIG47XG4gICAgY29uc3Qgbm9kZU1hcDogSW5kZXhNYXAgPSB7fTtcbiAgICBub2Rlcy5mb3JFYWNoKChub2RlLCBpKSA9PiB7XG4gICAgICBub2RlTWFwW25vZGUuaWRdID0gaTtcbiAgICB9KTtcbiAgICBjb25zdCBkZWdyZWVzID0gZ2V0RGVncmVlKG5vZGVzLmxlbmd0aCwgbm9kZU1hcCwgZWRnZXMgYXMgRWRnZVtdKTtcblxuICAgIGxldCB7IHJhZGl1cywgc3RhcnRSYWRpdXMsIGVuZFJhZGl1cyB9ID0gbWVyZ2VkT3B0aW9ucztcbiAgICBpZiAocGFyYW1Ob2RlU3BhY2luZykge1xuICAgICAgY29uc3Qgbm9kZVNwYWNpbmc6IEZ1bmN0aW9uID0gZ2V0RnVuY0J5VW5rbm93blR5cGUoMTAsIHBhcmFtTm9kZVNwYWNpbmcpO1xuICAgICAgY29uc3Qgbm9kZVNpemU6IEZ1bmN0aW9uID0gZ2V0RnVuY0J5VW5rbm93blR5cGUoMTAsIHBhcmFtTm9kZVNpemUpO1xuICAgICAgbGV0IG1heE5vZGVTaXplID0gLUluZmluaXR5O1xuICAgICAgbm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBuU2l6ZSA9IG5vZGVTaXplKG5vZGUpO1xuICAgICAgICBpZiAobWF4Tm9kZVNpemUgPCBuU2l6ZSkgbWF4Tm9kZVNpemUgPSBuU2l6ZTtcbiAgICAgIH0pO1xuICAgICAgbGV0IGxlbmd0aCA9IDA7XG4gICAgICBub2Rlcy5mb3JFYWNoKChub2RlLCBpKSA9PiB7XG4gICAgICAgIGlmIChpID09PSAwKSBsZW5ndGggKz0gKG1heE5vZGVTaXplIHx8IDEwKTtcbiAgICAgICAgZWxzZSBsZW5ndGggKz0gKG5vZGVTcGFjaW5nKG5vZGUpIHx8IDApICsgKG1heE5vZGVTaXplIHx8IDEwKTtcbiAgICAgIH0pO1xuICAgICAgcmFkaXVzID0gbGVuZ3RoIC8gKDIgKiBNYXRoLlBJKTtcbiAgICB9IGVsc2UgaWYgKCFyYWRpdXMgJiYgIXN0YXJ0UmFkaXVzICYmICFlbmRSYWRpdXMpIHtcbiAgICAgIHJhZGl1cyA9IGNhbGN1bGF0ZWRIZWlnaHQgPiBjYWxjdWxhdGVkV2lkdGggPyBjYWxjdWxhdGVkV2lkdGggLyAyIDogY2FsY3VsYXRlZEhlaWdodCAvIDI7XG4gICAgfSBlbHNlIGlmICghc3RhcnRSYWRpdXMgJiYgZW5kUmFkaXVzKSB7XG4gICAgICBzdGFydFJhZGl1cyA9IGVuZFJhZGl1cztcbiAgICB9IGVsc2UgaWYgKHN0YXJ0UmFkaXVzICYmICFlbmRSYWRpdXMpIHtcbiAgICAgIGVuZFJhZGl1cyA9IHN0YXJ0UmFkaXVzO1xuICAgIH1cbiAgICBjb25zdCBhc3RlcCA9IGFuZ2xlU3RlcCAqIGFuZ2xlUmF0aW8hO1xuXG4gICAgbGV0IGxheW91dE5vZGVzOiBhbnlbXSA9IFtdO1xuICAgIGxldCBub2Rlc0RhdGEgPSBub2Rlcy5tYXAoKG5vZGUpID0+IG5vZGUuZGF0YSk7XG4gICAgaWYgKG9yZGVyaW5nID09PSBcInRvcG9sb2d5XCIpIHtcbiAgICAgIC8vIGxheW91dCBhY2NvcmRpbmcgdG8gdGhlIHRvcG9sb2d5XG4gICAgICBsYXlvdXROb2RlcyA9IHRvcG9sb2d5T3JkZXJpbmcoZGVncmVlcywgbm9kZXNEYXRhLCBlZGdlcywgbm9kZU1hcCk7XG4gICAgfSBlbHNlIGlmIChvcmRlcmluZyA9PT0gXCJ0b3BvbG9neS1kaXJlY3RlZFwiKSB7XG4gICAgICAvLyBsYXlvdXQgYWNjb3JkaW5nIHRvIHRoZSB0b3BvbG9neVxuICAgICAgbGF5b3V0Tm9kZXMgPSB0b3BvbG9neU9yZGVyaW5nKGRlZ3JlZXMsIG5vZGVzRGF0YSwgZWRnZXMsIG5vZGVNYXAsIHRydWUpO1xuICAgIH0gZWxzZSBpZiAob3JkZXJpbmcgPT09IFwiZGVncmVlXCIpIHtcbiAgICAgIC8vIGxheW91dCBhY2NvcmRpbmcgdG8gdGhlIGRlc2NlbnQgb3JkZXIgb2YgZGVncmVlc1xuICAgICAgbGF5b3V0Tm9kZXMgPSBkZWdyZWVPcmRlcmluZyhkZWdyZWVzLCBub2Rlc0RhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBsYXlvdXQgYWNjb3JkaW5nIHRvIHRoZSBvcmlnaW5hbCBvcmRlciBpbiB0aGUgZGF0YS5ub2Rlc1xuICAgICAgbGF5b3V0Tm9kZXMgPSBub2RlcztcbiAgICB9XG5cbiAgICBjb25zdCBkaXZOID0gTWF0aC5jZWlsKG4gLyBkaXZpc2lvbnMhKTsgLy8gbm9kZSBudW1iZXIgaW4gZWFjaCBkaXZpc2lvblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBsZXQgciA9IHJhZGl1cztcbiAgICAgIGlmICghciAmJiBzdGFydFJhZGl1cyAhPT0gbnVsbCAmJiBlbmRSYWRpdXMgIT09IG51bGwpIHtcbiAgICAgICAgciA9IHN0YXJ0UmFkaXVzISArIChpICogKGVuZFJhZGl1cyEgLSBzdGFydFJhZGl1cyEpKSAvIChuIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoIXIpIHtcbiAgICAgICAgciA9IDEwICsgKGkgKiAxMDApIC8gKG4gLSAxKTtcbiAgICAgIH1cbiAgICAgIGxldCBhbmdsZSA9XG4gICAgICAgIHN0YXJ0QW5nbGUgK1xuICAgICAgICAoaSAlIGRpdk4pICogYXN0ZXAgK1xuICAgICAgICAoKDIgKiBNYXRoLlBJKSAvIGRpdmlzaW9ucyEpICogTWF0aC5mbG9vcihpIC8gZGl2Tik7XG4gICAgICBpZiAoIWNsb2Nrd2lzZSkge1xuICAgICAgICBhbmdsZSA9XG4gICAgICAgICAgZW5kQW5nbGUgLVxuICAgICAgICAgIChpICUgZGl2TikgKiBhc3RlcCAtXG4gICAgICAgICAgKCgyICogTWF0aC5QSSkgLyBkaXZpc2lvbnMhKSAqIE1hdGguZmxvb3IoaSAvIGRpdk4pO1xuICAgICAgfVxuICAgICAgbGF5b3V0Tm9kZXNbaV0ueCA9IGNhbGN1bGF0ZWRDZW50ZXJbMF0gKyBNYXRoLmNvcyhhbmdsZSkgKiByO1xuICAgICAgbGF5b3V0Tm9kZXNbaV0ueSA9IGNhbGN1bGF0ZWRDZW50ZXJbMV0gKyBNYXRoLnNpbihhbmdsZSkgKiByO1xuICAgICAgbGF5b3V0Tm9kZXNbaV0ud2VpZ2h0ID0gZGVncmVlc1tpXS5hbGw7XG4gICAgfVxuXG4gICAgaWYgKGFzc2lnbikge1xuICAgICAgbGF5b3V0Tm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgICBncmFwaC5tZXJnZU5vZGVEYXRhKG5vZGUuaWQsIHtcbiAgICAgICAgICB4OiBub2RlLngsXG4gICAgICAgICAgeTogbm9kZS55LFxuICAgICAgICAgIHdlaWdodDogbm9kZS53ZWlnaHQsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKG9uTGF5b3V0RW5kKSB7XG4gICAgICBvbkxheW91dEVuZCgpO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgbm9kZXM6IGxheW91dE5vZGVzLFxuICAgICAgZWRnZXNcbiAgICB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRIaWVyYXJjaHkoXG4gIG5vZGVzOiBJTm9kZURhdGFbXSxcbiAgZWRnZXM6IEVkZ2VbXSxcbiAgbm9kZU1hcDogSW5kZXhNYXAsXG4gIGRpcmVjdGVkOiBib29sZWFuXG4pIHtcbiAgbm9kZXMuZm9yRWFjaCgoXywgaTogbnVtYmVyKSA9PiB7XG4gICAgbm9kZXNbaV0uY2hpbGRyZW4gPSBbXTtcbiAgICBub2Rlc1tpXS5wYXJlbnQgPSBbXTtcbiAgfSk7XG4gIGlmIChkaXJlY3RlZCkge1xuICAgIGVkZ2VzLmZvckVhY2goKGUpID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGdldEVkZ2VUZXJtaW5hbChlLCAnc291cmNlJyk7XG4gICAgICBjb25zdCB0YXJnZXQgPSBnZXRFZGdlVGVybWluYWwoZSwgJ3RhcmdldCcpO1xuICAgICAgbGV0IHNvdXJjZUlkeCA9IDA7XG4gICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgIHNvdXJjZUlkeCA9IG5vZGVNYXBbc291cmNlXTtcbiAgICAgIH1cbiAgICAgIGxldCB0YXJnZXRJZHggPSAwO1xuICAgICAgaWYgKHRhcmdldCkge1xuICAgICAgICB0YXJnZXRJZHggPSBub2RlTWFwW3RhcmdldF07XG4gICAgICB9XG4gICAgICBjb25zdCBjaGlsZCA9IG5vZGVzW3NvdXJjZUlkeF0uY2hpbGRyZW4hO1xuICAgICAgY29uc3QgcGFyZW50ID0gbm9kZXNbdGFyZ2V0SWR4XS5wYXJlbnQhO1xuICAgICAgY2hpbGQucHVzaChub2Rlc1t0YXJnZXRJZHhdLmlkKTtcbiAgICAgIHBhcmVudC5wdXNoKG5vZGVzW3NvdXJjZUlkeF0uaWQpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGVkZ2VzLmZvckVhY2goKGUpID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGdldEVkZ2VUZXJtaW5hbChlLCAnc291cmNlJyk7XG4gICAgICBjb25zdCB0YXJnZXQgPSBnZXRFZGdlVGVybWluYWwoZSwgJ3RhcmdldCcpO1xuICAgICAgbGV0IHNvdXJjZUlkeCA9IDA7XG4gICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgIHNvdXJjZUlkeCA9IG5vZGVNYXBbc291cmNlXTtcbiAgICAgIH1cbiAgICAgIGxldCB0YXJnZXRJZHggPSAwO1xuICAgICAgaWYgKHRhcmdldCkge1xuICAgICAgICB0YXJnZXRJZHggPSBub2RlTWFwW3RhcmdldF07XG4gICAgICB9XG4gICAgICBjb25zdCBzb3VyY2VDaGlsZHJlbiA9IG5vZGVzW3NvdXJjZUlkeF0uY2hpbGRyZW4hO1xuICAgICAgY29uc3QgdGFyZ2V0Q2hpbGRyZW4gPSBub2Rlc1t0YXJnZXRJZHhdLmNoaWxkcmVuITtcbiAgICAgIHNvdXJjZUNoaWxkcmVuLnB1c2gobm9kZXNbdGFyZ2V0SWR4XS5pZCk7XG4gICAgICB0YXJnZXRDaGlsZHJlbi5wdXNoKG5vZGVzW3NvdXJjZUlkeF0uaWQpO1xuICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbm5lY3QoYTogSU5vZGVEYXRhLCBiOiBJTm9kZURhdGEsIGVkZ2VzOiBFZGdlW10pIHtcbiAgY29uc3QgbSA9IGVkZ2VzLmxlbmd0aDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIHtcbiAgICBjb25zdCBzb3VyY2UgPSBnZXRFZGdlVGVybWluYWwoZWRnZXNbaV0sICdzb3VyY2UnKTtcbiAgICBjb25zdCB0YXJnZXQgPSBnZXRFZGdlVGVybWluYWwoZWRnZXNbaV0sICd0YXJnZXQnKTtcbiAgICBpZiAoXG4gICAgICAoYS5pZCA9PT0gc291cmNlICYmIGIuaWQgPT09IHRhcmdldCkgfHxcbiAgICAgIChiLmlkID09PSBzb3VyY2UgJiYgYS5pZCA9PT0gdGFyZ2V0KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29tcGFyZURlZ3JlZShhOiBJTm9kZURhdGEsIGI6IElOb2RlRGF0YSkge1xuICBjb25zdCBhRGVncmVlID0gYS5kZWdyZWUhO1xuICBjb25zdCBiRGVncmVlID0gYi5kZWdyZWUhO1xuICBpZiAoYURlZ3JlZSA8IGJEZWdyZWUpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKGFEZWdyZWUgPiBiRGVncmVlKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIHRvcG9sb2d5T3JkZXJpbmcoXG4gIGRlZ3JlZXM6IERlZ3JlZVtdLFxuICBub2RlczogSU5vZGVEYXRhW10sXG4gIGVkZ2VzOiBFZGdlW10sXG4gIG5vZGVNYXA6IEluZGV4TWFwLCBcbiAgZGlyZWN0ZWQ6IGJvb2xlYW4gPSBmYWxzZVxuKSB7XG4gIGNvbnN0IGNub2RlcyA9IGNsb25lKG5vZGVzKTtcbiAgY29uc3Qgb3JkZXJlZENOb2RlcyA9IFtjbm9kZXNbMF1dO1xuICBjb25zdCByZXNOb2RlcyA9IFtub2Rlc1swXV07XG4gIGNvbnN0IHBpY2tGbGFnczogYm9vbGVhbltdID0gW107XG4gIGNvbnN0IG4gPSBub2Rlcy5sZW5ndGg7XG4gIHBpY2tGbGFnc1swXSA9IHRydWU7XG4gIGluaXRIaWVyYXJjaHkoY25vZGVzLCBlZGdlcywgbm9kZU1hcCwgZGlyZWN0ZWQpO1xuICBsZXQgayA9IDA7XG4gIGNub2Rlcy5mb3JFYWNoKChjbm9kZSwgaSkgPT4ge1xuICAgIGlmIChpICE9PSAwKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChpID09PSBuIC0gMSB8fFxuICAgICAgICAgIGRlZ3JlZXNbaV0uYWxsICE9PSBkZWdyZWVzW2kgKyAxXS5hbGwgfHxcbiAgICAgICAgICBjb25uZWN0KFxuICAgICAgICAgICAgb3JkZXJlZENOb2Rlc1trXSxcbiAgICAgICAgICAgIGNub2RlLFxuICAgICAgICAgICAgZWRnZXNcbiAgICAgICAgICApKSAmJlxuICAgICAgICAhcGlja0ZsYWdzW2ldXG4gICAgICApIHtcbiAgICAgICAgb3JkZXJlZENOb2Rlcy5wdXNoKGNub2RlKTtcbiAgICAgICAgcmVzTm9kZXMucHVzaChub2Rlc1tub2RlTWFwW2Nub2RlLmlkXV0pO1xuICAgICAgICBwaWNrRmxhZ3NbaV0gPSB0cnVlO1xuICAgICAgICBrKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBjaGlsZHJlbiA9IG9yZGVyZWRDTm9kZXNba10uY2hpbGRyZW4hO1xuICAgICAgICBsZXQgZm91bmRDaGlsZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNoaWxkcmVuLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY29uc3QgY2hpbGRJZHggPSBub2RlTWFwW2NoaWxkcmVuW2pdXTtcbiAgICAgICAgICBpZiAoZGVncmVlc1tjaGlsZElkeF0uYWxsID09PSBkZWdyZWVzW2ldLmFsbCAmJiAhcGlja0ZsYWdzW2NoaWxkSWR4XSkge1xuICAgICAgICAgICAgb3JkZXJlZENOb2Rlcy5wdXNoKGNub2Rlc1tjaGlsZElkeF0pO1xuICAgICAgICAgICAgcmVzTm9kZXMucHVzaChub2Rlc1tub2RlTWFwW2Nub2Rlc1tjaGlsZElkeF0uaWRdXSk7XG4gICAgICAgICAgICBwaWNrRmxhZ3NbY2hpbGRJZHhdID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvdW5kQ2hpbGQgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBpaSA9IDA7XG4gICAgICAgIHdoaWxlICghZm91bmRDaGlsZCkge1xuICAgICAgICAgIGlmICghcGlja0ZsYWdzW2lpXSkge1xuICAgICAgICAgICAgb3JkZXJlZENOb2Rlcy5wdXNoKGNub2Rlc1tpaV0pO1xuICAgICAgICAgICAgcmVzTm9kZXMucHVzaChub2Rlc1tub2RlTWFwW2Nub2Rlc1tpaV0uaWRdXSk7XG4gICAgICAgICAgICBwaWNrRmxhZ3NbaWldID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvdW5kQ2hpbGQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpaSsrO1xuICAgICAgICAgIGlmIChpaSA9PT0gbikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc05vZGVzO1xufVxuXG5mdW5jdGlvbiBkZWdyZWVPcmRlcmluZyhcbiAgZGVncmVlczogRGVncmVlW10sXG4gIG5vZGVzOiBJTm9kZURhdGFbXSxcbik6IElOb2RlRGF0YVtdIHtcbiAgY29uc3Qgb3JkZXJlZE5vZGVzOiBJTm9kZURhdGFbXSA9IFtdO1xuICBub2Rlcy5mb3JFYWNoKChub2RlLCBpKSA9PiB7XG4gICAgbm9kZS5kZWdyZWUgPSBkZWdyZWVzW2ldLmFsbDtcbiAgICBvcmRlcmVkTm9kZXMucHVzaChub2RlKTtcbiAgfSk7XG4gIG9yZGVyZWROb2Rlcy5zb3J0KGNvbXBhcmVEZWdyZWUpO1xuICByZXR1cm4gb3JkZXJlZE5vZGVzO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVDZW50ZXIod2lkdGg6IG51bWJlciB8IHVuZGVmaW5lZCwgaGVpZ2h0OiBudW1iZXIgfCB1bmRlZmluZWQsIGNlbnRlcjogUG9pbnRUdXBsZSB8IHVuZGVmaW5lZCk6IFtudW1iZXIsIG51bWJlciwgUG9pbnRUdXBsZV0ge1xuICBsZXQgY2FsY3VsYXRlZFdpZHRoID0gd2lkdGg7XG4gIGxldCBjYWxjdWxhdGVkSGVpZ2h0ID0gaGVpZ2h0O1xuICBsZXQgY2FsY3VsYXRlZENlbnRlciA9IGNlbnRlcjtcbiAgaWYgKCFjYWxjdWxhdGVkV2lkdGggJiYgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIGNhbGN1bGF0ZWRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICB9XG4gIGlmICghY2FsY3VsYXRlZEhlaWdodCAmJiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgY2FsY3VsYXRlZEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgfVxuICBpZiAoIWNhbGN1bGF0ZWRDZW50ZXIpIHtcbiAgICBjYWxjdWxhdGVkQ2VudGVyID0gW2NhbGN1bGF0ZWRXaWR0aCEgLyAyLCBjYWxjdWxhdGVkSGVpZ2h0ISAvIDJdO1xuICB9XG4gIHJldHVybiBbY2FsY3VsYXRlZFdpZHRoISwgY2FsY3VsYXRlZEhlaWdodCEsIGNhbGN1bGF0ZWRDZW50ZXJdO1xufSIsImltcG9ydCB7IENpcmN1bGFyTGF5b3V0IH0gZnJvbSBcIi4vY2lyY3VsYXJcIjtcbmltcG9ydCB0eXBlIHsgU3luY0xheW91dENvbnN0cnVjdG9yIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IHJlZ2lzdHJ5OiBSZWNvcmQ8c3RyaW5nLCBTeW5jTGF5b3V0Q29uc3RydWN0b3I8YW55Pj4gPSB7XG4gIGNpcmN1bGFyOiBDaXJjdWxhckxheW91dCxcbn07XG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJMYXlvdXQoaWQ6IHN0cmluZywgbGF5b3V0OiBTeW5jTGF5b3V0Q29uc3RydWN0b3I8YW55Pikge1xuICByZWdpc3RyeVtpZF0gPSBsYXlvdXQ7XG59XG4iLCJpbXBvcnQgeyBHcmFwaCB9IGZyb20gXCJAYW50di9ncmFwaGxpYlwiO1xuLy8gaW1wb3J0IHsgc2V0dXBUcmFuc2ZlcmFibGVNZXRob2RzT25Xb3JrZXIgfSBmcm9tIFwiQG5hb2FrL3dvcmtlcml6ZS10cmFuc2ZlcmFibGVcIjtcbmltcG9ydCB7IHJlZ2lzdHJ5IH0gZnJvbSBcIi4vcmVnaXN0cnlcIjtcbmltcG9ydCB0eXBlIHsgUGF5bG9hZCB9IGZyb20gXCIuL3N1cGVydmlzb3JcIjtcbmltcG9ydCB0eXBlIHsgTGF5b3V0TWFwcGluZywgU3luY0xheW91dCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8vIEBzZWUgaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvQG5hb2FrL3dvcmtlcml6ZS10cmFuc2ZlcmFibGVcbi8vIHNldHVwVHJhbnNmZXJhYmxlTWV0aG9kc09uV29ya2VyKHtcbi8vICAgLy8gVGhlIG5hbWUgb2YgZnVuY3Rpb24gd2hpY2ggdXNlIHNvbWUgdHJhbnNmZXJhYmxlcy5cbi8vICAgY2FsY3VsYXRlTGF5b3V0OiB7XG4vLyAgICAgLy8gU3BlY2lmeSBhbiBpbnN0YW5jZSBvZiB0aGUgZnVuY3Rpb25cbi8vICAgICBmbjogY2FsY3VsYXRlTGF5b3V0LFxuLy8gICAgIC8vIFBpY2sgYSB0cmFuc2ZlcmFibGUgb2JqZWN0IGZyb20gdGhlIHJlc3VsdCB3aGljaCBpcyBhbiBpbnN0YW5jZSBvZiBGbG9hdDMyQXJyYXlcbi8vICAgICBwaWNrVHJhbnNmZXJhYmxlc0Zyb21SZXN1bHQ6IChyZXN1bHQpID0+IFtyZXN1bHRbMV0uYnVmZmVyXSxcbi8vICAgfSxcbi8vIH0pO1xuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlTGF5b3V0KHBheWxvYWQ6IFBheWxvYWQsIHRyYW5zZmVyYWJsZXM6IEZsb2F0MzJBcnJheVtdKSB7XG4gIGNvbnN0IHsgbGF5b3V0OiB7IGlkLCBvcHRpb25zIH0sIG5vZGVzLCBlZGdlcyB9ID0gcGF5bG9hZDtcblxuICAvLyBTeW5jIGdyYXBoIG9uIHRoZSB3b3JrZXIgc2lkZS5cbiAgLy8gVE9ETzogVXNlIHRyYW5zZmVyYWJsZSBvYmplY3RzIGxpa2UgQXJyYXlCdWZmZXIgZm9yIG5vZGVzICYgZWRnZXMsIFxuICAvLyBpbiB3aGljaCBjYXNlIHdlIGRvbid0IG5lZWQgdGhlIHdob2xlIGdyYXBoLlxuICAvLyBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ncmFwaG9sb2d5L2dyYXBob2xvZ3kvYmxvYi9tYXN0ZXIvc3JjL2xheW91dC1ub3ZlcmxhcC93ZWJ3b3JrZXIudHBsLmpzI0wzMlxuICBjb25zdCBncmFwaCA9IG5ldyBHcmFwaCh7XG4gICAgbm9kZXM6IG5vZGVzLFxuICAgIGVkZ2VzOiBlZGdlcyxcbiAgfSk7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBsYXlvdXQgaW5zdGFuY2Ugb24gdGhlIHdvcmtlciBzaWRlLlxuICAgKi9cbiAgbGV0IGxheW91dDogU3luY0xheW91dDxhbnk+O1xuICBsZXQgcG9zaXRpb25zOiBMYXlvdXRNYXBwaW5nO1xuICBjb25zdCBsYXlvdXRDdG9yID0gcmVnaXN0cnlbaWRdO1xuICBpZiAobGF5b3V0Q3Rvcikge1xuICAgIGxheW91dCA9IG5ldyBsYXlvdXRDdG9yKG9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBsYXlvdXQgaWQ6ICcgKyBpZCk7XG4gIH1cblxuICAvLyBEbyBjYWxjdWxhdGlvbi5cbiAgcG9zaXRpb25zID0gbGF5b3V0LmV4ZWN1dGUoZ3JhcGgpO1xuICBcbiAgcmV0dXJuIFtwb3NpdGlvbnMsIHRyYW5zZmVyYWJsZXNdO1xufVxuIl0sIm5hbWVzIjpbIl9fd2VicGFja19yZXF1aXJlX18iLCJleHBvcnRzIiwiZGVmaW5pdGlvbiIsImtleSIsIm8iLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImVudW1lcmFibGUiLCJnZXQiLCJvYmoiLCJwcm9wIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiR3JhcGgiLCJub2RlTWFwIiwiTWFwIiwiZWRnZU1hcCIsImluRWRnZXNNYXAiLCJvdXRFZGdlc01hcCIsInRyZWVJbmRpY2VzIiwiY2hhbmdlcyIsImJhdGNoQ291bnQiLCJvbkNoYW5nZWQiLCJjb25zdHJ1Y3RvciIsIm9wdGlvbnMiLCJub2RlcyIsInRoaXMiLCJhZGROb2RlcyIsImVkZ2VzIiwiYWRkRWRnZXMiLCJ0cmVlIiwiYWRkVHJlZSIsImJhdGNoIiwiZm4iLCJjb21taXQiLCJncmFwaCIsInJlZHVjZUNoYW5nZXMiLCJtZXJnZWRDaGFuZ2VzIiwiZm9yRWFjaCIsImNoYW5nZSIsInR5cGUiLCJpc05ld2x5QWRkZWQiLCJmaWx0ZXIiLCJwYXN0Q2hhbmdlIiwic2FtZUlkIiwidmFsdWUiLCJpZCIsIm5vZGVJZCIsInB1c2giLCJleGlzdGluZ0NoYW5nZSIsImZpbmQiLCJwcm9wZXJ0eU5hbWUiLCJuZXdWYWx1ZSIsInRyZWVLZXkiLCJuZXdQYXJlbnRJZCIsImNoZWNrTm9kZUV4aXN0ZW5jZSIsImhhc05vZGUiLCJFcnJvciIsImhhcyIsImFyZU5laWdoYm9ycyIsImZpcnN0Tm9kZUlkIiwic2Vjb25kTm9kZUlkIiwiZ2V0TmVpZ2hib3JzIiwic29tZSIsIm5laWdoYm9yIiwiZ2V0Tm9kZSIsImdldFJlbGF0ZWRFZGdlcyIsImRpcmVjdGlvbiIsImluRWRnZXMiLCJvdXRFZGdlcyIsIkFycmF5IiwiZnJvbSIsImJvdGhFZGdlcyIsIlNldCIsImdldERlZ3JlZSIsImxlbmd0aCIsImdldFN1Y2Nlc3NvcnMiLCJ0YXJnZXRzIiwibWFwIiwiZWRnZSIsInRhcmdldCIsImdldFByZWRlY2Vzc29ycyIsInNvdXJjZXMiLCJzb3VyY2UiLCJwcmVkZWNlc3NvcnMiLCJzdWNjZXNzb3JzIiwiZG9BZGROb2RlIiwibm9kZSIsInNldCIsImNoaWxkcmVuTWFwIiwiYWRkTm9kZSIsImRvUmVtb3ZlTm9kZSIsImRvUmVtb3ZlRWRnZSIsImRlbGV0ZSIsImNoaWxkIiwicGFyZW50TWFwIiwicmVtb3ZlTm9kZXMiLCJpZExpc3QiLCJyZW1vdmVOb2RlIiwidXBkYXRlTm9kZURhdGEiLCJvbGRWYWx1ZSIsImRhdGEiLCJtZXJnZU5vZGVEYXRhIiwicGF0Y2giLCJlbnRyaWVzIiwiY2hlY2tFZGdlRXhpc3RlbmNlIiwiaGFzRWRnZSIsImdldEVkZ2UiLCJnZXRFZGdlRGV0YWlsIiwiZG9BZGRFZGdlIiwiYWRkIiwiYWRkRWRnZSIsInJlbW92ZUVkZ2VzIiwicmVtb3ZlRWRnZSIsInVwZGF0ZUVkZ2VTb3VyY2UiLCJvbGRTb3VyY2UiLCJuZXdTb3VyY2UiLCJ1cGRhdGVFZGdlVGFyZ2V0Iiwib2xkVGFyZ2V0IiwibmV3VGFyZ2V0IiwidXBkYXRlRWRnZURhdGEiLCJtZXJnZUVkZ2VEYXRhIiwiY2hlY2tUcmVlRXhpc3RlbmNlIiwiYXR0YWNoVHJlZVN0cnVjdHVyZSIsImRldGFjaFRyZWVTdHJ1Y3R1cmUiLCJzdGFjayIsImlzQXJyYXkiLCJzaGlmdCIsImNoaWxkcmVuIiwicGFyZW50Iiwic2V0UGFyZW50IiwiZ2V0Um9vdHMiLCJnZXRBbGxOb2RlcyIsImdldFBhcmVudCIsImdldENoaWxkcmVuIiwib2xkUGFyZW50IiwibmV3UGFyZW50Iiwib2xkUGFyZW50SWQiLCJ2YWx1ZXMiLCJnZXRBbGxFZGdlcyIsImRvQkZTIiwicXVldWUiLCJ2aXNpdGVkIiwibiIsImJmcyIsImRvREZTIiwiZGZzIiwiY2xvbmUiLCJuZXdOb2RlcyIsIm9sZE5vZGUiLCJuZXdFZGdlcyIsIm9sZEVkZ2UiLCJuZXdHcmFwaCIsIm9sZFBhcmVudE1hcCIsIm9sZENoaWxkcmVuTWFwIiwidG9KU09OIiwiSlNPTiIsInN0cmluZ2lmeSIsIl9fYXNzaWduIiwiYXNzaWduIiwidCIsInMiLCJpIiwiYXJndW1lbnRzIiwicCIsImFwcGx5IiwiX19yZWFkIiwibSIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiciIsImUiLCJhciIsIm5leHQiLCJkb25lIiwiZXJyb3IiLCJjcmVhdGUiLCJjYW1lbGl6ZVJFIiwic3RyIiwicmVwbGFjZSIsIl8iLCJjIiwidG9VcHBlckNhc2UiLCJpc09iamVjdCIsInZhbCIsIkRhdGUiLCJnZXRUaW1lIiwidiIsImtleXMiLCJrIiwiZ2V0RWRnZVRlcm1pbmFsIiwidGVybWluYWwiLCJjZWxsIiwiZ2V0RnVuY0J5VW5rbm93blR5cGUiLCJkZWZhdWx0VmFsdWUiLCJyZXN1bHRJc051bWJlciIsIm1heCIsIk1hdGgiLCJ0byIsInBhY2siLCJsIiwic2xpY2UiLCJjb25jYXQiLCJpc05hTiIsIndpZHRoIiwiaGVpZ2h0IiwiZCIsInNpemUiLCJERUZBVUxUU19MQVlPVVRfT1BUSU9OUyIsInJhZGl1cyIsInN0YXJ0UmFkaXVzIiwiZW5kUmFkaXVzIiwic3RhcnRBbmdsZSIsImVuZEFuZ2xlIiwiUEkiLCJjbG9ja3dpc2UiLCJkaXZpc2lvbnMiLCJvcmRlcmluZyIsImFuZ2xlUmF0aW8iLCJjb21wYXJlRGVncmVlIiwiYSIsImIiLCJhRGVncmVlIiwiZGVncmVlIiwiYkRlZ3JlZSIsInRvcG9sb2d5T3JkZXJpbmciLCJkZWdyZWVzIiwiZGlyZWN0ZWQiLCJjbm9kZXMiLCJvcmRlcmVkQ05vZGVzIiwicmVzTm9kZXMiLCJwaWNrRmxhZ3MiLCJzb3VyY2VJZHgiLCJ0YXJnZXRJZHgiLCJzb3VyY2VDaGlsZHJlbiIsInRhcmdldENoaWxkcmVuIiwiaW5pdEhpZXJhcmNoeSIsImNub2RlIiwiYWxsIiwiY29ubmVjdCIsImZvdW5kQ2hpbGQiLCJqIiwiY2hpbGRJZHgiLCJpaSIsInJlZ2lzdHJ5IiwiY2lyY3VsYXIiLCJleGVjdXRlIiwiZ2VuZXJpY0NpcmN1bGFyTGF5b3V0IiwibWVyZ2VkT3B0aW9ucyIsImNlbnRlciIsInBhcmFtTm9kZVNwYWNpbmciLCJwYXJhbU5vZGVTaXplIiwib25MYXlvdXRFbmQiLCJjYWxjdWxhdGVkV2lkdGgiLCJjYWxjdWxhdGVkSGVpZ2h0IiwiY2FsY3VsYXRlZENlbnRlciIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJpbm5lckhlaWdodCIsImNhbGN1bGF0ZUNlbnRlciIsIngiLCJ5IiwiYW5nbGVTdGVwIiwibm9kZUlkeE1hcCIsImluIiwib3V0IiwiblNpemUiLCJhc3RlcCIsImxheW91dE5vZGVzIiwibm9kZXNEYXRhIiwib3JkZXJlZE5vZGVzIiwic29ydCIsImRlZ3JlZU9yZGVyaW5nIiwiZGl2TiIsImNlaWwiLCJhbmdsZSIsImZsb29yIiwiY29zIiwic2luIiwid2VpZ2h0IiwiY2FsY3VsYXRlTGF5b3V0IiwicGF5bG9hZCIsInRyYW5zZmVyYWJsZXMiLCJsYXlvdXRDdG9yIl0sInNvdXJjZVJvb3QiOiIifQ==
@@ -1 +0,0 @@
1
- {"version":3,"file":"3a54d760230d1933f953.worker.js","mappings":"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","sources":["webpack://Layout/webpack/bootstrap","webpack://Layout/webpack/runtime/define property getters","webpack://Layout/webpack/runtime/hasOwnProperty shorthand","webpack://Layout/../../node_modules/@antv/graphlib/esm/Graph.js","webpack://Layout/../../node_modules/tslib/tslib.es6.js","webpack://Layout/./src/util/string.ts","webpack://Layout/./src/util/array.ts","webpack://Layout/./src/util/object.ts","webpack://Layout/./src/util/math.ts","webpack://Layout/./src/util/function.ts","webpack://Layout/./src/util/number.ts","webpack://Layout/./src/circular.ts","webpack://Layout/./src/registry.ts","webpack://Layout/./src/worker.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","export class Graph {\n nodeMap = new Map();\n edgeMap = new Map();\n inEdgesMap = new Map();\n outEdgesMap = new Map();\n treeIndices = new Map();\n changes = [];\n batchCount = 0;\n /**\n * This function is called with a {@link GraphChangedEvent} each time a graph change happened.\n *\n * `event.changes` contains all the graph changes in order since last `onChanged`.\n */\n onChanged = () => {\n // Do nothing.\n };\n /**\n * Create a new Graph instance.\n * @param options - The options to initialize a graph. See {@link GraphOptions}.\n *\n * ```ts\n * const graph = new Graph({\n * // Optional, initial nodes.\n * nodes: [\n * // Each node has a unique ID.\n * { id: 'A', foo: 1 },\n * { id: 'B', foo: 1 },\n * ],\n * // Optional, initial edges.\n * edges: [\n * { id: 'C', source: 'B', target: 'B', weight: 1 },\n * ],\n * // Optional, called with a GraphChangedEvent.\n * onChanged: (event) => {\n * console.log(event);\n * }\n * });\n * ```\n */\n constructor(options) {\n if (!options)\n return;\n if (options.nodes)\n this.addNodes(options.nodes);\n if (options.edges)\n this.addEdges(options.edges);\n if (options.tree)\n this.addTree(options.tree);\n if (options.onChanged)\n this.onChanged = options.onChanged;\n }\n /**\n * Batch several graph changes into one.\n *\n * Make several changes, but dispatch only one ChangedEvent at the end of batch:\n * ```ts\n * graph.batch(() => {\n * graph.addNodes([]);\n * graph.addEdges([]);\n * });\n * ```\n *\n * Batches can be nested. Only the outermost batch will dispatch a ChangedEvent:\n * ```ts\n * graph.batch(() => {\n * graph.addNodes([]);\n * graph.batch(() => {\n * graph.addEdges([]);\n * });\n * });\n * ```\n */\n batch = (fn) => {\n this.batchCount += 1;\n fn();\n this.batchCount -= 1;\n if (!this.batchCount) {\n this.commit();\n }\n };\n /**\n * Reset changes and dispatch a ChangedEvent.\n */\n commit() {\n const changes = this.changes;\n this.changes = [];\n this.onChanged({\n graph: this,\n changes,\n });\n }\n /**\n * Reduce the number of ordered graph changes by dropping or merging unnecessary changes.\n *\n * For example, if we update a node and remove it in a batch:\n *\n * ```ts\n * graph.batch(() => {\n * graph.updateNodeData('A', 'foo', 2);\n * graph.removeNode('A');\n * });\n * ```\n *\n * We get 2 atomic graph changes like\n *\n * ```ts\n * [\n * { type: 'NodeDataUpdated', id: 'A', propertyName: 'foo', oldValue: 1, newValue: 2 },\n * { type: 'NodeRemoved', value: { id: 'A', data: { foo: 2 } },\n * ]\n * ```\n *\n * Since node 'A' has been removed, we actually have no need to handle with NodeDataUpdated change.\n *\n * `reduceChanges()` here helps us remove such changes.\n */\n reduceChanges(changes) {\n let mergedChanges = [];\n changes.forEach((change) => {\n switch (change.type) {\n case 'NodeRemoved': {\n // NodeAdded: A added.\n // NodeDataUpdated: A changed.\n // TreeStructureChanged: A's parent changed.\n // NodeRemoved: A removed. 👈🏻 Since A was removed, above three changes may be ignored.\n let isNewlyAdded = false;\n mergedChanges = mergedChanges.filter((pastChange) => {\n if (pastChange.type === 'NodeAdded') {\n const sameId = pastChange.value.id === change.value.id;\n if (sameId) {\n isNewlyAdded = true;\n }\n return !sameId;\n }\n else if (pastChange.type === 'NodeDataUpdated') {\n return pastChange.id !== change.value.id;\n }\n else if (pastChange.type === 'TreeStructureChanged') {\n return pastChange.nodeId !== change.value.id;\n }\n return true;\n });\n if (!isNewlyAdded) {\n mergedChanges.push(change);\n }\n break;\n }\n case 'EdgeRemoved': {\n // EdgeAdded: A added.\n // EdgeDataUpdated: A changed.\n // EdgeDataUpdated: A's source/target changed.\n // EdgeRemoved: A removed. 👈🏻 Since A was removed, above three changes may be ignored.\n let isNewlyAdded = false;\n mergedChanges = mergedChanges.filter((pastChange) => {\n if (pastChange.type === 'EdgeAdded') {\n const sameId = pastChange.value.id === change.value.id;\n if (sameId) {\n isNewlyAdded = true;\n }\n return !sameId;\n }\n else if (pastChange.type === 'EdgeDataUpdated' ||\n pastChange.type === 'EdgeUpdated') {\n return pastChange.id !== change.value.id;\n }\n return true;\n });\n if (!isNewlyAdded) {\n mergedChanges.push(change);\n }\n break;\n }\n case 'NodeDataUpdated':\n case 'EdgeDataUpdated':\n case 'EdgeUpdated': {\n // NodeDataUpdated: { id: A, propertyName: 'foo', oldValue: 1, newValue: 2 }.\n // NodeDataUpdated: { id: A, propertyName: 'foo', oldValue: 2, newValue: 3 }.\n // 👆 Could be merged as { id: A, propertyName: 'foo', oldValue: 1, newValue: 3 }.\n const existingChange = mergedChanges.find((pastChange) => {\n return (pastChange.type === change.type &&\n pastChange.id === change.id &&\n pastChange.propertyName === change.propertyName);\n });\n if (existingChange) {\n existingChange.newValue = change.newValue;\n }\n else {\n mergedChanges.push(change);\n }\n break;\n }\n case 'TreeStructureDetached': {\n // TreeStructureAttached\n // TreeStructureChanged\n // TreeStructureDetached 👈🏻 Since the tree struct was detached, above 2 changes may be ignored.\n mergedChanges = mergedChanges.filter((pastChange) => {\n if (pastChange.type === 'TreeStructureAttached') {\n return pastChange.treeKey !== change.treeKey;\n }\n else if (pastChange.type === 'TreeStructureChanged') {\n return pastChange.treeKey !== change.treeKey;\n }\n return true;\n });\n mergedChanges.push(change);\n break;\n }\n case 'TreeStructureChanged': {\n const existingChange = mergedChanges.find((pastChange) => {\n return (pastChange.type === 'TreeStructureChanged' &&\n pastChange.treeKey === change.treeKey &&\n pastChange.nodeId === change.nodeId);\n });\n if (existingChange) {\n existingChange.newParentId =\n change.newParentId;\n }\n else {\n mergedChanges.push(change);\n }\n break;\n }\n default:\n mergedChanges.push(change);\n break;\n }\n });\n return mergedChanges;\n }\n // ================= Node =================\n checkNodeExistence(id) {\n if (!this.hasNode(id)) {\n throw new Error('Node not found for id: ' + id);\n }\n }\n /**\n * Check if a node exists in the graph.\n * @group NodeMethods\n */\n hasNode(id) {\n return this.nodeMap.has(id);\n }\n /**\n * Tell if two nodes are neighbors.\n * @group NodeMethods\n */\n areNeighbors(firstNodeId, secondNodeId) {\n this.checkNodeExistence(firstNodeId);\n return this.getNeighbors(secondNodeId).some((neighbor) => neighbor.id === firstNodeId);\n }\n /**\n * Get the node data with given ID.\n * @group NodeMethods\n */\n getNode(id) {\n this.checkNodeExistence(id);\n return this.nodeMap.get(id);\n }\n /**\n * Given a node ID, find all edges of the node.\n * @param id - ID of the node\n * @param direction - Edge direction, defaults to 'both'.\n * @group NodeMethods\n */\n getRelatedEdges(id, direction) {\n this.checkNodeExistence(id);\n const inEdges = this.inEdgesMap.get(id);\n const outEdges = this.outEdgesMap.get(id);\n if (direction === 'in') {\n return Array.from(inEdges);\n }\n else if (direction === 'out') {\n return Array.from(outEdges);\n }\n const bothEdges = new Set([...inEdges, ...outEdges]);\n return Array.from(bothEdges);\n }\n /**\n * Get the degree of the given node.\n * @group NodeMethods\n */\n getDegree(id, direction) {\n return this.getRelatedEdges(id, direction).length;\n }\n /**\n * Get all successors of the given node.\n */\n getSuccessors(id) {\n const outEdges = this.getRelatedEdges(id, 'out');\n const targets = outEdges.map((edge) => edge.target);\n return Array.from(new Set(targets)).map((id) => this.getNode(id));\n }\n /**\n * Get all predecessors of the given node.\n */\n getPredecessors(id) {\n const inEdges = this.getRelatedEdges(id, 'in');\n const sources = inEdges.map((edge) => edge.source);\n return Array.from(new Set(sources)).map((id) => this.getNode(id));\n }\n /**\n * Given a node ID, find its neighbors.\n * @param id - ID of the node\n * @group NodeMethods\n */\n getNeighbors(id) {\n const predecessors = this.getPredecessors(id);\n const successors = this.getSuccessors(id);\n return Array.from(new Set([...predecessors, ...successors]));\n }\n doAddNode(node) {\n if (this.hasNode(node.id)) {\n throw new Error('Node already exists: ' + node.id);\n }\n this.nodeMap.set(node.id, node);\n this.inEdgesMap.set(node.id, new Set());\n this.outEdgesMap.set(node.id, new Set());\n this.treeIndices.forEach((tree) => {\n tree.childrenMap.set(node.id, new Set());\n });\n this.changes.push({ type: 'NodeAdded', value: node });\n }\n /**\n * Add all nodes of the given array, or iterable, into the graph.\n * @group NodeMethods\n */\n addNodes(nodes) {\n this.batch(() => {\n for (const node of nodes) {\n this.doAddNode(node);\n }\n });\n }\n /**\n * Add a single node into the graph.\n * @group NodeMethods\n */\n addNode(node) {\n this.addNodes([node]);\n }\n doRemoveNode(id) {\n const node = this.getNode(id);\n const inEdges = this.inEdgesMap.get(id);\n const outEdges = this.outEdgesMap.get(id);\n inEdges?.forEach((edge) => this.doRemoveEdge(edge.id));\n outEdges?.forEach((edge) => this.doRemoveEdge(edge.id));\n this.nodeMap.delete(id);\n this.treeIndices.forEach((tree) => {\n tree.childrenMap.get(id)?.forEach((child) => {\n tree.parentMap.delete(child.id);\n });\n tree.parentMap.delete(id);\n tree.childrenMap.delete(id);\n });\n this.changes.push({ type: 'NodeRemoved', value: node });\n }\n /**\n * Remove nodes and their attached edges from the graph.\n * @group NodeMethods\n */\n removeNodes(idList) {\n this.batch(() => {\n idList.forEach((id) => this.doRemoveNode(id));\n });\n }\n /**\n * Remove a single node and its attached edges from the graph.\n * @group NodeMethods\n */\n removeNode(id) {\n this.removeNodes([id]);\n }\n /**\n * Update node data.\n * @group NodeMethods\n */\n updateNodeData(id, propertyName, value) {\n const node = this.getNode(id);\n this.batch(() => {\n const oldValue = node.data[propertyName];\n const newValue = value;\n node.data[propertyName] = newValue;\n this.changes.push({\n type: 'NodeDataUpdated',\n id,\n propertyName,\n oldValue,\n newValue,\n });\n });\n }\n /**\n * Like Object.assign, merge all properties of `path` to the node data.\n * @param id Node ID.\n * @param patch A data object to merge.\n */\n mergeNodeData(id, patch) {\n this.batch(() => {\n Object.entries(patch).forEach(([propertyName, value]) => {\n this.updateNodeData(id, propertyName, value);\n });\n });\n }\n // ================= Edge =================\n checkEdgeExistence(id) {\n if (!this.hasEdge(id)) {\n throw new Error('Edge not found for id: ' + id);\n }\n }\n /**\n * Check if an edge exists in the graph.\n * @group NodeMethods\n */\n hasEdge(id) {\n return this.edgeMap.has(id);\n }\n /**\n * Get the edge data with given ID.\n * @group EdgeMethods\n */\n getEdge(id) {\n this.checkEdgeExistence(id);\n return this.edgeMap.get(id);\n }\n /**\n * Get the edge, the source node, and the target node by an edge ID.\n * @group EdgeMethods\n */\n getEdgeDetail(id) {\n const edge = this.getEdge(id);\n return {\n edge,\n source: this.getNode(edge.source),\n target: this.getNode(edge.target),\n };\n }\n doAddEdge(edge) {\n if (this.hasEdge(edge.id)) {\n throw new Error('Edge already exists: ' + edge.id);\n }\n this.checkNodeExistence(edge.source);\n this.checkNodeExistence(edge.target);\n this.edgeMap.set(edge.id, edge);\n const inEdges = this.inEdgesMap.get(edge.target);\n const outEdges = this.outEdgesMap.get(edge.source);\n inEdges.add(edge);\n outEdges.add(edge);\n this.changes.push({ type: 'EdgeAdded', value: edge });\n }\n /**\n * Add all edges of the given iterable(an array, a set, etc.) into the graph.\n * @group EdgeMethods\n */\n addEdges(edges) {\n this.batch(() => {\n for (const edge of edges) {\n this.doAddEdge(edge);\n }\n });\n }\n /**\n * Add a single edge pointing from `source` to `target` into the graph.\n *\n * ```ts\n * graph.addNode({ id: 'NodeA' });\n * graph.addNode({ id: 'NodeB' });\n * graph.addEdge({ id: 'EdgeA', source: 'NodeA', target: 'NodeB' });\n * ```\n *\n * If `source` or `target` were not found in the current graph, it throws an Error.\n * @group EdgeMethods\n */\n addEdge(edge) {\n this.addEdges([edge]);\n }\n doRemoveEdge(id) {\n const edge = this.getEdge(id);\n const outEdges = this.outEdgesMap.get(edge.source);\n const inEdges = this.inEdgesMap.get(edge.target);\n outEdges.delete(edge);\n inEdges.delete(edge);\n this.edgeMap.delete(id);\n this.changes.push({ type: 'EdgeRemoved', value: edge });\n }\n /**\n * Remove edges whose id was included in the given id list.\n * @group EdgeMethods\n */\n removeEdges(idList) {\n this.batch(() => {\n idList.forEach((id) => this.doRemoveEdge(id));\n });\n }\n /**\n * Remove a single edge of the given id.\n * @group EdgeMethods\n */\n removeEdge(id) {\n this.removeEdges([id]);\n }\n /**\n * Change the source of an edge. The source must be found in current graph.\n * @group EdgeMethods\n */\n updateEdgeSource(id, source) {\n const edge = this.getEdge(id);\n this.checkNodeExistence(source);\n const oldSource = edge.source;\n const newSource = source;\n this.outEdgesMap.get(oldSource).delete(edge);\n this.outEdgesMap.get(newSource).add(edge);\n edge.source = source;\n this.batch(() => {\n this.changes.push({\n type: 'EdgeUpdated',\n id,\n propertyName: 'source',\n oldValue: oldSource,\n newValue: newSource,\n });\n });\n }\n /**\n * Change the target of an edge. The target must be found in current graph.\n * @group EdgeMethods\n */\n updateEdgeTarget(id, target) {\n const edge = this.getEdge(id);\n this.checkNodeExistence(target);\n const oldTarget = edge.target;\n const newTarget = target;\n this.inEdgesMap.get(oldTarget).delete(edge);\n this.inEdgesMap.get(newTarget).add(edge);\n edge.target = target;\n this.batch(() => {\n this.changes.push({\n type: 'EdgeUpdated',\n id,\n propertyName: 'target',\n oldValue: oldTarget,\n newValue: newTarget,\n });\n });\n }\n /**\n * Update edge data.\n * @group EdgeMethods\n */\n updateEdgeData(id, propertyName, value) {\n const edge = this.getEdge(id);\n this.batch(() => {\n const oldValue = edge.data[propertyName];\n const newValue = value;\n edge.data[propertyName] = newValue;\n this.changes.push({\n type: 'EdgeDataUpdated',\n id,\n propertyName,\n oldValue,\n newValue,\n });\n });\n }\n /**\n * @group EdgeMethods\n */\n mergeEdgeData(id, patch) {\n this.batch(() => {\n Object.entries(patch).forEach(([propertyName, value]) => {\n this.updateEdgeData(id, propertyName, value);\n });\n });\n }\n // ================= Tree =================\n checkTreeExistence(treeKey) {\n if (!this.treeIndices.has(treeKey)) {\n throw new Error('Tree structure not found for treeKey: ' + treeKey);\n }\n }\n /**\n * Attach a new tree structure representing the hierarchy of all nodes in the graph.\n * @param treeKey A unique key of the tree structure. You can attach multiple tree structures with different keys.\n *\n * ```ts\n * const graph = new Graph({\n * nodes: [{ id: 1 }, { id: 2 }, { id: 3 }],\n * });\n * graph.attachTreeStructure('Inheritance');\n * graph.setParent(2, 1, 'Inheritance');\n * graph.setParent(3, 1, 'Inheritance');\n * graph.getRoots('Inheritance'); // [1]\n * graph.getChildren(1, 'Inheritance'); // [2,3]\n * ```\n * @group TreeMethods\n */\n attachTreeStructure(treeKey) {\n if (this.treeIndices.has(treeKey)) {\n // Already attached.\n return;\n }\n this.treeIndices.set(treeKey, {\n parentMap: new Map(),\n childrenMap: new Map(),\n });\n this.batch(() => {\n this.changes.push({\n type: 'TreeStructureAttached',\n treeKey,\n });\n });\n }\n /**\n * Detach the tree structure of the given tree key from the graph.\n *\n * ```ts\n * graph.detachTreeStructure('Inheritance');\n * graph.getRoots('Inheritance'); // Error!\n * ```\n * @group TreeMethods\n */\n detachTreeStructure(treeKey) {\n this.checkTreeExistence(treeKey);\n this.treeIndices.delete(treeKey);\n this.batch(() => {\n this.changes.push({\n type: 'TreeStructureDetached',\n treeKey,\n });\n });\n }\n /**\n * Traverse the given tree data, add each node into the graph, then attach the tree structure.\n *\n * ```ts\n * graph.addTree({\n * id: 1,\n * children: [\n * { id: 2 },\n * { id: 3 },\n * ],\n * }, 'Inheritance');\n * graph.getRoots('Inheritance'); // [1]\n * graph.getChildren(1, 'Inheritance'); // [2, 3]\n * graph.getAllNodes(); // [1, 2, 3]\n * graph.getAllEdges(); // []\n * ```\n * @group TreeMethods\n */\n addTree(tree, treeKey) {\n this.batch(() => {\n this.attachTreeStructure(treeKey);\n // Add Nodes\n const nodes = [];\n const stack = Array.isArray(tree) ? tree : [tree];\n while (stack.length) {\n const node = stack.shift();\n nodes.push(node);\n if (node.children) {\n stack.push(...node.children);\n }\n }\n this.addNodes(nodes);\n // Set parent for each child node.\n nodes.forEach((parent) => {\n parent.children?.forEach((child) => {\n this.setParent(child.id, parent.id, treeKey);\n });\n });\n });\n }\n /**\n * Get the root nodes of an attached tree structure.\n *\n * Consider a graph with the following tree structure attached:\n * ```\n * Tree structure:\n * O 3\n * / \\ |\n * 1 2 4\n * ```\n * `graph.getRoots()` takes all nodes without a parent, therefore [0, 3] was returned.\n *\n * Newly added nodes are also unparented. So they are counted as roots.\n * ```ts\n * graph.addNode({ id: 5 });\n * graph.getRoots(); // [0, 3, 5]\n * ```\n *\n * Here is how the tree structure looks like:\n * ```\n * Tree structure:\n * O 3 5\n * / \\ |\n * 1 2 4\n * ```\n *\n * By setting a parent, a root node no more be a root.\n * ```ts\n * graph.setParent(5, 2);\n * graph.getRoots(); // [0, 3]\n * ```\n *\n * The tree structure now becomes:\n * ```\n * Tree structure:\n * O 3\n * / \\ |\n * 1 2 4\n * |\n * 5\n * ```\n *\n * Removing a node forces its children to be unparented, or roots.\n * ```ts\n * graph.removeNode(0);\n * graph.getRoots(); // [1, 2, 3]\n * ```\n *\n * You might draw the the structure as follow:\n * ```\n * Tree structure:\n * 1 2 3\n * | |\n * 5 4\n * ```\n * @group TreeMethods\n */\n getRoots(treeKey) {\n this.checkTreeExistence(treeKey);\n return this.getAllNodes().filter((node) => !this.getParent(node.id, treeKey));\n }\n /**\n * Given a node ID and an optional tree key, get the children of the node in the specified tree structure.\n * @group TreeMethods\n */\n getChildren(id, treeKey) {\n this.checkNodeExistence(id);\n this.checkTreeExistence(treeKey);\n const tree = this.treeIndices.get(treeKey);\n const children = tree.childrenMap.get(id);\n return Array.from(children || []);\n }\n /**\n * Given a node ID and an optional tree key, get the parent of the node in the specified tree structure.\n * If the given node is one of the tree roots, this returns null.\n * @group TreeMethods\n */\n getParent(id, treeKey) {\n this.checkNodeExistence(id);\n this.checkTreeExistence(treeKey);\n const tree = this.treeIndices.get(treeKey);\n return tree.parentMap.get(id) || null;\n }\n /**\n * Set node parent. If this operation causes a circle, it fails with an error.\n * @param id - ID of the child node.\n * @param parent - ID of the parent node.\n * @param treeKey - Which tree structure the relation is applied to.\n * @group TreeMethods\n */\n setParent(id, parent, treeKey) {\n this.checkTreeExistence(treeKey);\n const tree = this.treeIndices.get(treeKey);\n const node = this.getNode(id);\n const oldParent = tree.parentMap.get(id);\n const newParent = this.getNode(parent);\n // Set parent\n tree.parentMap.set(id, newParent);\n // Set children\n if (oldParent) {\n tree.childrenMap.get(oldParent.id)?.delete(node);\n }\n let children = tree.childrenMap.get(newParent.id);\n if (!children) {\n children = new Set();\n tree.childrenMap.set(newParent.id, children);\n }\n children.add(node);\n this.batch(() => {\n this.changes.push({\n type: 'TreeStructureChanged',\n treeKey,\n nodeId: id,\n oldParentId: oldParent?.id,\n newParentId: newParent.id,\n });\n });\n }\n // ================= Graph =================\n /**\n * Get all nodes in the graph as an array.\n */\n getAllNodes() {\n return Array.from(this.nodeMap.values());\n }\n /**\n * Get all edges in the graph as an array.\n */\n getAllEdges() {\n return Array.from(this.edgeMap.values());\n }\n doBFS(queue, visited, fn) {\n while (queue.length) {\n const node = queue.shift();\n fn(node);\n visited.add(node.id);\n this.getSuccessors(node.id).forEach((n) => {\n if (!visited.has(n.id)) {\n visited.add(n.id);\n queue.push(n);\n }\n });\n }\n }\n bfs(id, fn) {\n this.doBFS([this.getNode(id)], new Set(), fn);\n }\n doDFS(node, visited, fn) {\n fn(node);\n visited.add(node.id);\n this.getSuccessors(node.id).forEach((n) => {\n if (!visited.has(n.id)) {\n this.doDFS(n, visited, fn);\n }\n });\n }\n dfs(id, fn) {\n this.doDFS(this.getNode(id), new Set(), fn);\n }\n clone() {\n // Make a shallow copy of nodes and edges.\n const newNodes = this.getAllNodes().map((oldNode) => {\n return { ...oldNode, data: { ...oldNode.data } };\n });\n const newEdges = this.getAllEdges().map((oldEdge) => {\n return { ...oldEdge, data: { ...oldEdge.data } };\n });\n // Create a new graph with shallow copied nodes and edges.\n const newGraph = new Graph({\n nodes: newNodes,\n edges: newEdges,\n });\n // Add tree indices.\n this.treeIndices.forEach(({ parentMap: oldParentMap, childrenMap: oldChildrenMap }, treeKey) => {\n const parentMap = new Map();\n oldParentMap.forEach((parent, key) => {\n parentMap.set(key, newGraph.getNode(parent.id));\n });\n const childrenMap = new Map();\n oldChildrenMap.forEach((children, key) => {\n childrenMap.set(key, new Set(Array.from(children).map((n) => newGraph.getNode(n.id))));\n });\n newGraph.treeIndices.set(treeKey, {\n parentMap: parentMap,\n childrenMap: childrenMap,\n });\n });\n return newGraph;\n }\n toJSON() {\n return JSON.stringify({\n nodes: this.getAllNodes(),\n edges: this.getAllEdges(),\n // FIXME: And tree structures?\n });\n }\n}\n//# sourceMappingURL=Graph.js.map","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","export const isString = (val: unknown): val is string =>\n typeof val === \"string\";\n\nconst cacheStringFunction = <T extends (str: string) => string>(fn: T): T => {\n const cache: Record<string, string> = Object.create(null);\n return ((str: string) => {\n const hit = cache[str];\n return hit || (cache[str] = fn(str));\n }) as any;\n};\n\nconst camelizeRE = /-(\\w)/g;\nexport const camelize = cacheStringFunction((str: string): string => {\n return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : \"\"));\n});\n\n// export const capitalize = cacheStringFunction(\n// (str: string) => str.charAt(0).toUpperCase() + str.slice(1),\n// )\n","export const isArray = Array.isArray;\n","export const isObject = (val: unknown): val is Record<any, any> =>\n val !== null && typeof val === \"object\";\n\nexport const clone = <T>(target: T): T => {\n if (target === null) {\n return target;\n }\n if (target instanceof Date) {\n return new Date(target.getTime()) as any;\n }\n if (target instanceof Array) {\n const cp = [] as any[];\n (target as any[]).forEach((v) => {\n cp.push(v);\n });\n return cp.map((n: any) => clone<any>(n)) as any;\n }\n if (typeof target === \"object\" && Object.keys(target).length) {\n const cp = { ...(target as { [key: string]: any }) } as {\n [key: string]: any;\n };\n Object.keys(cp).forEach((k) => {\n cp[k] = clone<any>(cp[k]);\n });\n return cp as T;\n }\n return target;\n};\n","import {\n Matrix,\n Model,\n IndexMap,\n Edge,\n Node,\n OutNode,\n Degree,\n NodeMap,\n} from \"../types\";\nimport { isArray } from \"./array\";\nimport { isNumber } from \"./number\";\nimport { isObject } from \"./object\";\n\nexport const getEdgeTerminal = (edge: Edge, type: \"source\" | \"target\") => {\n const terminal = edge[type];\n if (isObject(terminal)) {\n return terminal.cell;\n }\n return terminal;\n};\n\nexport const getDegree = (\n n: number,\n nodeIdxMap: IndexMap,\n edges: Edge[] | null\n) => {\n const degrees: Degree[] = [];\n for (let i = 0; i < n; i++) {\n degrees[i] = {\n in: 0,\n out: 0,\n all: 0,\n };\n }\n if (!edges) return degrees;\n edges.forEach((e) => {\n const source = getEdgeTerminal(e, \"source\");\n const target = getEdgeTerminal(e, \"target\");\n if (source && degrees[nodeIdxMap[source]]) {\n degrees[nodeIdxMap[source]].out += 1;\n degrees[nodeIdxMap[source]].all += 1;\n }\n if (target && degrees[nodeIdxMap[target]]) {\n degrees[nodeIdxMap[target]].in += 1;\n degrees[nodeIdxMap[target]].all += 1;\n }\n });\n return degrees;\n};\n\nexport const getDegreeMap = (nodes: Node[], edges: Edge[] | null) => {\n const degreesMap: { [id: string]: Degree } = {};\n nodes.forEach((node) => {\n degreesMap[node.id] = {\n in: 0,\n out: 0,\n all: 0,\n };\n });\n\n if (!edges) return degreesMap;\n edges.forEach((e) => {\n const source = getEdgeTerminal(e, \"source\");\n const target = getEdgeTerminal(e, \"target\");\n if (source) {\n degreesMap[source].out += 1;\n degreesMap[source].all += 1;\n }\n if (target) {\n degreesMap[target].in += 1;\n degreesMap[target].all += 1;\n }\n });\n return degreesMap;\n};\n\nexport const floydWarshall = (adjMatrix: Matrix[]): Matrix[] => {\n // initialize\n const dist: Matrix[] = [];\n const size = adjMatrix.length;\n for (let i = 0; i < size; i += 1) {\n dist[i] = [];\n for (let j = 0; j < size; j += 1) {\n if (i === j) {\n dist[i][j] = 0;\n } else if (adjMatrix[i][j] === 0 || !adjMatrix[i][j]) {\n dist[i][j] = Infinity;\n } else {\n dist[i][j] = adjMatrix[i][j];\n }\n }\n }\n // floyd\n for (let k = 0; k < size; k += 1) {\n for (let i = 0; i < size; i += 1) {\n for (let j = 0; j < size; j += 1) {\n if (dist[i][j] > dist[i][k] + dist[k][j]) {\n dist[i][j] = dist[i][k] + dist[k][j];\n }\n }\n }\n }\n return dist;\n};\n\nexport const getAdjMatrix = (data: Model, directed: boolean): Matrix[] => {\n const { nodes, edges } = data;\n const matrix: Matrix[] = [];\n // map node with index in data.nodes\n const nodeMap: {\n [key: string]: number;\n } = {};\n\n if (!nodes) {\n throw new Error(\"invalid nodes data!\");\n }\n if (nodes) {\n nodes.forEach((node, i) => {\n nodeMap[node.id] = i;\n const row: number[] = [];\n matrix.push(row);\n });\n }\n\n edges?.forEach((e) => {\n const source = getEdgeTerminal(e, \"source\");\n const target = getEdgeTerminal(e, \"target\");\n const sIndex = nodeMap[source as string];\n const tIndex = nodeMap[target as string];\n if (sIndex === undefined || tIndex === undefined) return;\n matrix[sIndex][tIndex] = 1;\n if (!directed) {\n matrix[tIndex][sIndex] = 1;\n }\n });\n return matrix;\n};\n\n/**\n * scale matrix\n * @param matrix [ [], [], [] ]\n * @param ratio\n */\nexport const scaleMatrix = (matrix: Matrix[], ratio: number) => {\n const result: Matrix[] = [];\n matrix.forEach((row) => {\n const newRow: number[] = [];\n row.forEach((v) => {\n newRow.push(v * ratio);\n });\n result.push(newRow);\n });\n return result;\n};\n\n/**\n * depth first traverse, from leaves to root, children in inverse order\n * if the fn returns false, terminate the traverse\n */\nconst traverseUp = <T extends { children?: T[] }>(\n data: T,\n fn: (param: T) => boolean\n) => {\n if (data && data.children) {\n for (let i = data.children.length - 1; i >= 0; i--) {\n if (!traverseUp(data.children[i], fn)) return;\n }\n }\n\n if (!fn(data)) {\n return false;\n }\n return true;\n};\n\n/**\n * depth first traverse, from leaves to root, children in inverse order\n * if the fn returns false, terminate the traverse\n */\nexport const traverseTreeUp = <T extends { children?: T[] }>(\n data: T,\n fn: (param: T) => boolean\n) => {\n if (typeof fn !== \"function\") {\n return;\n }\n traverseUp(data, fn);\n};\n\n/**\n * calculate the bounding box for the nodes according to their x, y, and size\n * @param nodes nodes in the layout\n * @returns\n */\nexport const getLayoutBBox = (nodes: OutNode[]) => {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n nodes.forEach((node) => {\n let size = node.size;\n if (isArray(size)) {\n if (size.length === 1) size = [size[0], size[0]];\n } else if (isNumber(size)) {\n size = [size, size];\n } else if (size === undefined || isNaN(size as any)) {\n size = [30, 30];\n }\n\n const halfSize = [size[0] / 2, size[1] / 2];\n const left = node.x - halfSize[0];\n const right = node.x + halfSize[0];\n const top = node.y - halfSize[1];\n const bottom = node.y + halfSize[1];\n\n if (minX > left) minX = left;\n if (minY > top) minY = top;\n if (maxX < right) maxX = right;\n if (maxY < bottom) maxY = bottom;\n });\n return { minX, minY, maxX, maxY };\n};\n\n/**\n * 获取节点集合的平均位置信息\n * @param nodes 节点集合\n * @returns 平局内置\n */\nexport const getAvgNodePosition = (nodes: OutNode[]) => {\n const totalNodes = { x: 0, y: 0 };\n nodes.forEach((node) => {\n totalNodes.x += node.x || 0;\n totalNodes.y += node.y || 0;\n });\n // 获取均值向量\n const length = nodes.length || 1;\n return {\n x: totalNodes.x / length,\n y: totalNodes.y / length,\n };\n};\n\n// 找出指定节点关联的边的起点或终点\nconst getCoreNode = (type: \"source\" | \"target\", node: Node, edges: Edge[]) => {\n if (type === \"source\") {\n return (edges?.find((edge) => edge.target === node.id)?.source ||\n {}) as Node;\n }\n return (edges?.find((edge) => edge.source === node.id)?.target || {}) as Node;\n};\n\n// 找出指定节点为起点或终点的所有一度叶子节点\nconst getRelativeNodeIds = (\n type: \"source\" | \"target\" | \"both\",\n coreNode: Node,\n edges: Edge[]\n) => {\n let relativeNodes: string[] = [];\n switch (type) {\n case \"source\":\n relativeNodes = edges\n ?.filter((edge) => edge.source === coreNode.id)\n .map((edge) => edge.target);\n break;\n case \"target\":\n relativeNodes = edges\n ?.filter((edge) => edge.target === coreNode.id)\n .map((edge) => edge.source);\n break;\n case \"both\":\n relativeNodes = edges\n ?.filter((edge) => edge.source === coreNode.id)\n .map((edge) => edge.target)\n .concat(\n edges\n ?.filter((edge) => edge.target === coreNode.id)\n .map((edge) => edge.source)\n );\n break;\n default:\n break;\n }\n // 去重\n const set = new Set(relativeNodes);\n return Array.from(set);\n};\n// 找出同类型的节点\nconst getSameTypeNodes = (\n type: \"leaf\" | \"all\",\n nodeClusterBy: string,\n node: Node,\n relativeNodes: Node[],\n degreesMap: { [id: string]: Degree }\n) => {\n // @ts-ignore\n const typeName = node[nodeClusterBy] || \"\";\n // @ts-ignore\n let sameTypeNodes =\n relativeNodes?.filter((item) => item[nodeClusterBy] === typeName) || [];\n if (type === \"leaf\") {\n sameTypeNodes = sameTypeNodes.filter(\n (node) => degreesMap[node.id]?.in === 0 || degreesMap[node.id]?.out === 0\n );\n }\n return sameTypeNodes;\n};\n\n// 找出与指定节点关联的边的起点或终点出发的所有一度叶子节点\nexport const getCoreNodeAndRelativeLeafNodes = (\n type: \"leaf\" | \"all\",\n node: Node,\n edges: Edge[],\n nodeClusterBy: string,\n degreesMap: { [id: string]: Degree },\n nodeMap: NodeMap\n) => {\n const { in: inDegree, out: outDegree } = degreesMap[node.id];\n let coreNode: Node = node;\n let relativeLeafNodes: Node[] = [];\n if (inDegree === 0) {\n // 如果为没有出边的叶子节点,则找出与它关联的边的起点出发的所有一度节点\n coreNode = getCoreNode(\"source\", node, edges);\n relativeLeafNodes = getRelativeNodeIds(\"both\", coreNode, edges).map(\n (nodeId) => nodeMap[nodeId]\n );\n } else if (outDegree === 0) {\n // 如果为没有入边边的叶子节点,则找出与它关联的边的起点出发的所有一度节点\n coreNode = getCoreNode(\"target\", node, edges);\n relativeLeafNodes = getRelativeNodeIds(\"both\", coreNode, edges).map(\n (nodeId) => nodeMap[nodeId]\n );\n }\n relativeLeafNodes = relativeLeafNodes.filter(\n (node) =>\n degreesMap[node.id] &&\n (degreesMap[node.id].in === 0 || degreesMap[node.id].out === 0)\n );\n const sameTypeLeafNodes = getSameTypeNodes(\n type,\n nodeClusterBy,\n node,\n relativeLeafNodes,\n degreesMap\n );\n return { coreNode, relativeLeafNodes, sameTypeLeafNodes };\n};\n","import { isArray, isObject } from \".\";\nimport { isNumber } from \"./number\";\n\nexport const isFunction = (val: unknown): val is Function =>\n typeof val === \"function\";\n\nexport const getFunc = (\n value: number,\n defaultValue: number,\n func?: ((d?: any) => number) | undefined\n): Function => {\n let resultFunc;\n if (func) {\n resultFunc = func;\n } else if (isNumber(value)) {\n resultFunc = () => value;\n } else {\n resultFunc = () => defaultValue;\n }\n return resultFunc;\n};\n\nexport const getFuncByUnknownType = (\n defaultValue: number,\n value?:\n | number\n | number[]\n | { width: number; height: number }\n | ((d?: any) => number)\n | undefined,\n resultIsNumber: boolean = true\n): ((d?: any) => number | number[]) => {\n if (!value && value !== 0) {\n return (d) => {\n if (d.size) {\n if (isArray(d.size))\n return d.size[0] > d.size[1] ? d.size[0] : d.size[1];\n if (isObject(d.size))\n return d.size.width > d.size.height ? d.size.width : d.size.height;\n return d.size;\n }\n return defaultValue;\n };\n }\n if (isFunction(value)) {\n return value;\n }\n if (isNumber(value)) {\n return () => value;\n }\n if (isArray(value)) {\n return () => {\n if (resultIsNumber) {\n const max = Math.max(...(value as number[]));\n return isNaN(max) ? defaultValue : max;\n }\n return value;\n };\n }\n if (isObject(value)) {\n return () => {\n if (resultIsNumber) {\n const max = Math.max(value.width, value.height);\n return isNaN(max) ? defaultValue : max;\n }\n return [value.width, value.height];\n };\n }\n return () => defaultValue;\n};\n","export const isNumber = (val: unknown): val is Number =>\n typeof val === \"number\";\n\nexport const isNaN = (num: unknown) => Number.isNaN(Number(num));\n\nexport const toNumber = (val: any): any => {\n const n = parseFloat(val);\n return isNaN(n) ? val : n;\n};\n","import type { Graph } from \"@antv/graphlib\";\nimport type { CircularLayoutOptions, SyncLayout, LayoutMapping, PointTuple, IndexMap, OutNode, Edge, Degree } from \"./types\";\nimport { getDegree, getEdgeTerminal, getFuncByUnknownType, clone } from \"./util\";\n\ntype INodeData = OutNode & {\n degree: number;\n size: number | PointTuple;\n weight: number;\n children: string[];\n parent: string[];\n};\n\ntype IEdgeData = {};\n\nconst DEFAULTS_LAYOUT_OPTIONS: Partial<CircularLayoutOptions> = {\n radius: null,\n startRadius: null,\n endRadius: null,\n startAngle: 0,\n endAngle: 2 * Math.PI,\n clockwise: true,\n divisions: 1,\n ordering: null,\n angleRatio: 1\n}\n\n/**\n * Layout arranging the nodes in a circle.\n * \n * @example\n * // Assign layout options when initialization.\n * const layout = new CircularLayout({ radius: 10 });\n * const positions = layout.execute(graph); // { nodes: [], edges: [] }\n * \n * // Or use different options later.\n * const layout = new CircularLayout({ radius: 10 });\n * const positions = layout.execute(graph, { radius: 20 }); // { nodes: [], edges: [] }\n * \n * // If you want to assign the positions directly to the nodes, use assign method.\n * layout.assign(graph, { radius: 20 });\n */\nexport class CircularLayout implements SyncLayout<CircularLayoutOptions> {\n id = 'circular';\n\n constructor(public options: CircularLayoutOptions = {} as CircularLayoutOptions) {\n Object.assign(this.options, DEFAULTS_LAYOUT_OPTIONS, options);\n }\n\n /**\n * Return the positions of nodes and edges(if needed).\n */\n execute(graph: Graph<INodeData, IEdgeData>, options?: CircularLayoutOptions): LayoutMapping {\n return this.genericCircularLayout(false, graph, options) as LayoutMapping;\n }\n\n /**\n * To directly assign the positions to the nodes.\n */\n assign(graph: Graph<INodeData, IEdgeData>, options?: CircularLayoutOptions) {\n graph.batch(() => {\n this.genericCircularLayout(true, graph, options);\n });\n }\n\n private genericCircularLayout(assign: boolean, graph: Graph<INodeData, IEdgeData>, options?: CircularLayoutOptions): LayoutMapping | void {\n const mergedOptions = { ...this.options, ...options };\n const { width, height, center, divisions, startAngle = 0, endAngle = 2 * Math.PI, angleRatio, ordering, clockwise, nodeSpacing: paramNodeSpacing, nodeSize: paramNodeSize, onLayoutEnd } = mergedOptions;\n\n const nodes = graph.getAllNodes();\n const edges = graph.getAllEdges() as Edge[];\n const n = nodes.length;\n\n // Need no layout if there is no node.\n if (n === 0) {\n if (onLayoutEnd) {\n onLayoutEnd();\n }\n return {\n nodes: [],\n edges: [],\n };\n }\n\n // Calculate center according to `window` if not provided.\n const [calculatedWidth, calculatedHeight, calculatedCenter] = calculateCenter(width, height, center);\n\n // Layout easily if there is only one node.\n if (n === 1) {\n if (assign) {\n graph.updateNodeData(nodes[0].id, \"x\", calculatedCenter[0]);\n graph.updateNodeData(nodes[0].id, \"y\", calculatedCenter[1]);\n }\n \n if (onLayoutEnd) {\n onLayoutEnd();\n }\n return {\n nodes: [\n {\n id: `${nodes[0].id}`,\n x: calculatedCenter[0],\n y: calculatedCenter[1],\n }\n ],\n edges: [],\n };\n }\n\n const angleStep = (endAngle - startAngle) / n;\n const nodeMap: IndexMap = {};\n nodes.forEach((node, i) => {\n nodeMap[node.id] = i;\n });\n const degrees = getDegree(nodes.length, nodeMap, edges as Edge[]);\n\n let { radius, startRadius, endRadius } = mergedOptions;\n if (paramNodeSpacing) {\n const nodeSpacing: Function = getFuncByUnknownType(10, paramNodeSpacing);\n const nodeSize: Function = getFuncByUnknownType(10, paramNodeSize);\n let maxNodeSize = -Infinity;\n nodes.forEach((node) => {\n const nSize = nodeSize(node);\n if (maxNodeSize < nSize) maxNodeSize = nSize;\n });\n let length = 0;\n nodes.forEach((node, i) => {\n if (i === 0) length += (maxNodeSize || 10);\n else length += (nodeSpacing(node) || 0) + (maxNodeSize || 10);\n });\n radius = length / (2 * Math.PI);\n } else if (!radius && !startRadius && !endRadius) {\n radius = calculatedHeight > calculatedWidth ? calculatedWidth / 2 : calculatedHeight / 2;\n } else if (!startRadius && endRadius) {\n startRadius = endRadius;\n } else if (startRadius && !endRadius) {\n endRadius = startRadius;\n }\n const astep = angleStep * angleRatio!;\n\n let layoutNodes: any[] = [];\n let nodesData = nodes.map((node) => node.data);\n if (ordering === \"topology\") {\n // layout according to the topology\n layoutNodes = topologyOrdering(degrees, nodesData, edges, nodeMap);\n } else if (ordering === \"topology-directed\") {\n // layout according to the topology\n layoutNodes = topologyOrdering(degrees, nodesData, edges, nodeMap, true);\n } else if (ordering === \"degree\") {\n // layout according to the descent order of degrees\n layoutNodes = degreeOrdering(degrees, nodesData);\n } else {\n // layout according to the original order in the data.nodes\n layoutNodes = nodes;\n }\n\n const divN = Math.ceil(n / divisions!); // node number in each division\n for (let i = 0; i < n; ++i) {\n let r = radius;\n if (!r && startRadius !== null && endRadius !== null) {\n r = startRadius! + (i * (endRadius! - startRadius!)) / (n - 1);\n }\n if (!r) {\n r = 10 + (i * 100) / (n - 1);\n }\n let angle =\n startAngle +\n (i % divN) * astep +\n ((2 * Math.PI) / divisions!) * Math.floor(i / divN);\n if (!clockwise) {\n angle =\n endAngle -\n (i % divN) * astep -\n ((2 * Math.PI) / divisions!) * Math.floor(i / divN);\n }\n layoutNodes[i].x = calculatedCenter[0] + Math.cos(angle) * r;\n layoutNodes[i].y = calculatedCenter[1] + Math.sin(angle) * r;\n layoutNodes[i].weight = degrees[i].all;\n }\n\n if (assign) {\n layoutNodes.forEach((node) => {\n graph.mergeNodeData(node.id, {\n x: node.x,\n y: node.y,\n weight: node.weight,\n });\n });\n }\n\n if (onLayoutEnd) {\n onLayoutEnd();\n };\n\n return {\n nodes: layoutNodes,\n edges\n };\n }\n}\n\nfunction initHierarchy(\n nodes: INodeData[],\n edges: Edge[],\n nodeMap: IndexMap,\n directed: boolean\n) {\n nodes.forEach((_, i: number) => {\n nodes[i].children = [];\n nodes[i].parent = [];\n });\n if (directed) {\n edges.forEach((e) => {\n const source = getEdgeTerminal(e, 'source');\n const target = getEdgeTerminal(e, 'target');\n let sourceIdx = 0;\n if (source) {\n sourceIdx = nodeMap[source];\n }\n let targetIdx = 0;\n if (target) {\n targetIdx = nodeMap[target];\n }\n const child = nodes[sourceIdx].children!;\n const parent = nodes[targetIdx].parent!;\n child.push(nodes[targetIdx].id);\n parent.push(nodes[sourceIdx].id);\n });\n } else {\n edges.forEach((e) => {\n const source = getEdgeTerminal(e, 'source');\n const target = getEdgeTerminal(e, 'target');\n let sourceIdx = 0;\n if (source) {\n sourceIdx = nodeMap[source];\n }\n let targetIdx = 0;\n if (target) {\n targetIdx = nodeMap[target];\n }\n const sourceChildren = nodes[sourceIdx].children!;\n const targetChildren = nodes[targetIdx].children!;\n sourceChildren.push(nodes[targetIdx].id);\n targetChildren.push(nodes[sourceIdx].id);\n });\n }\n}\n\nfunction connect(a: INodeData, b: INodeData, edges: Edge[]) {\n const m = edges.length;\n for (let i = 0; i < m; i++) {\n const source = getEdgeTerminal(edges[i], 'source');\n const target = getEdgeTerminal(edges[i], 'target');\n if (\n (a.id === source && b.id === target) ||\n (b.id === source && a.id === target)\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction compareDegree(a: INodeData, b: INodeData) {\n const aDegree = a.degree!;\n const bDegree = b.degree!;\n if (aDegree < bDegree) {\n return -1;\n }\n if (aDegree > bDegree) {\n return 1;\n }\n return 0;\n}\n\nfunction topologyOrdering(\n degrees: Degree[],\n nodes: INodeData[],\n edges: Edge[],\n nodeMap: IndexMap, \n directed: boolean = false\n) {\n const cnodes = clone(nodes);\n const orderedCNodes = [cnodes[0]];\n const resNodes = [nodes[0]];\n const pickFlags: boolean[] = [];\n const n = nodes.length;\n pickFlags[0] = true;\n initHierarchy(cnodes, edges, nodeMap, directed);\n let k = 0;\n cnodes.forEach((cnode, i) => {\n if (i !== 0) {\n if (\n (i === n - 1 ||\n degrees[i].all !== degrees[i + 1].all ||\n connect(\n orderedCNodes[k],\n cnode,\n edges\n )) &&\n !pickFlags[i]\n ) {\n orderedCNodes.push(cnode);\n resNodes.push(nodes[nodeMap[cnode.id]]);\n pickFlags[i] = true;\n k++;\n } else {\n const children = orderedCNodes[k].children!;\n let foundChild = false;\n for (let j = 0; j < children.length; j++) {\n const childIdx = nodeMap[children[j]];\n if (degrees[childIdx].all === degrees[i].all && !pickFlags[childIdx]) {\n orderedCNodes.push(cnodes[childIdx]);\n resNodes.push(nodes[nodeMap[cnodes[childIdx].id]]);\n pickFlags[childIdx] = true;\n foundChild = true;\n break;\n }\n }\n let ii = 0;\n while (!foundChild) {\n if (!pickFlags[ii]) {\n orderedCNodes.push(cnodes[ii]);\n resNodes.push(nodes[nodeMap[cnodes[ii].id]]);\n pickFlags[ii] = true;\n foundChild = true;\n }\n ii++;\n if (ii === n) {\n break;\n }\n }\n }\n }\n });\n return resNodes;\n}\n\nfunction degreeOrdering(\n degrees: Degree[],\n nodes: INodeData[],\n): INodeData[] {\n const orderedNodes: INodeData[] = [];\n nodes.forEach((node, i) => {\n node.degree = degrees[i].all;\n orderedNodes.push(node);\n });\n orderedNodes.sort(compareDegree);\n return orderedNodes;\n}\n\nfunction calculateCenter(width: number | undefined, height: number | undefined, center: PointTuple | undefined): [number, number, PointTuple] {\n let calculatedWidth = width;\n let calculatedHeight = height;\n let calculatedCenter = center;\n if (!calculatedWidth && typeof window !== \"undefined\") {\n calculatedWidth = window.innerWidth;\n }\n if (!calculatedHeight && typeof window !== \"undefined\") {\n calculatedHeight = window.innerHeight;\n }\n if (!calculatedCenter) {\n calculatedCenter = [calculatedWidth! / 2, calculatedHeight! / 2];\n }\n return [calculatedWidth!, calculatedHeight!, calculatedCenter];\n}","import { CircularLayout } from \"./circular\";\nimport type { SyncLayoutConstructor } from \"./types\";\n\nexport const registry: Record<string, SyncLayoutConstructor<any>> = {\n circular: CircularLayout,\n};\nexport function registerLayout(id: string, layout: SyncLayoutConstructor<any>) {\n registry[id] = layout;\n}\n","import { Graph } from \"@antv/graphlib\";\n// import { setupTransferableMethodsOnWorker } from \"@naoak/workerize-transferable\";\nimport { registry } from \"./registry\";\nimport type { Payload } from \"./supervisor\";\nimport type { LayoutMapping, SyncLayout } from \"./types\";\n\n// @see https://www.npmjs.com/package/@naoak/workerize-transferable\n// setupTransferableMethodsOnWorker({\n// // The name of function which use some transferables.\n// calculateLayout: {\n// // Specify an instance of the function\n// fn: calculateLayout,\n// // Pick a transferable object from the result which is an instance of Float32Array\n// pickTransferablesFromResult: (result) => [result[1].buffer],\n// },\n// });\n\nexport function calculateLayout(payload: Payload, transferables: Float32Array[]) {\n const { layout: { id, options }, nodes, edges } = payload;\n\n // Sync graph on the worker side.\n // TODO: Use transferable objects like ArrayBuffer for nodes & edges, \n // in which case we don't need the whole graph.\n // @see https://github.com/graphology/graphology/blob/master/src/layout-noverlap/webworker.tpl.js#L32\n const graph = new Graph({\n nodes: nodes,\n edges: edges,\n });\n\n /**\n * Create layout instance on the worker side.\n */\n let layout: SyncLayout<any>;\n let positions: LayoutMapping;\n const layoutCtor = registry[id];\n if (layoutCtor) {\n layout = new layoutCtor(options);\n } else {\n throw new Error('Unknown layout id: ' + id);\n }\n\n // Do calculation.\n positions = layout.execute(graph);\n \n return [positions, transferables];\n}\n"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Graph","nodeMap","Map","edgeMap","inEdgesMap","outEdgesMap","treeIndices","changes","batchCount","onChanged","constructor","options","nodes","this","addNodes","edges","addEdges","tree","addTree","batch","fn","commit","graph","reduceChanges","mergedChanges","forEach","change","type","isNewlyAdded","filter","pastChange","sameId","value","id","nodeId","push","existingChange","find","propertyName","newValue","treeKey","newParentId","checkNodeExistence","hasNode","Error","has","areNeighbors","firstNodeId","secondNodeId","getNeighbors","some","neighbor","getNode","getRelatedEdges","direction","inEdges","outEdges","Array","from","bothEdges","Set","getDegree","length","getSuccessors","targets","map","edge","target","getPredecessors","sources","source","predecessors","successors","doAddNode","node","set","childrenMap","addNode","doRemoveNode","doRemoveEdge","delete","child","parentMap","removeNodes","idList","removeNode","updateNodeData","oldValue","data","mergeNodeData","patch","entries","checkEdgeExistence","hasEdge","getEdge","getEdgeDetail","doAddEdge","add","addEdge","removeEdges","removeEdge","updateEdgeSource","oldSource","newSource","updateEdgeTarget","oldTarget","newTarget","updateEdgeData","mergeEdgeData","checkTreeExistence","attachTreeStructure","detachTreeStructure","stack","isArray","shift","children","parent","setParent","getRoots","getAllNodes","getParent","getChildren","oldParent","newParent","oldParentId","values","getAllEdges","doBFS","queue","visited","n","bfs","doDFS","dfs","clone","newNodes","oldNode","newEdges","oldEdge","newGraph","oldParentMap","oldChildrenMap","toJSON","JSON","stringify","__assign","assign","t","s","i","arguments","p","apply","__read","m","Symbol","iterator","r","e","ar","next","done","error","create","camelizeRE","str","replace","_","c","toUpperCase","isObject","val","Date","getTime","v","keys","k","getEdgeTerminal","terminal","cell","getFuncByUnknownType","defaultValue","resultIsNumber","max","Math","to","pack","l","slice","concat","isNaN","width","height","d","size","DEFAULTS_LAYOUT_OPTIONS","radius","startRadius","endRadius","startAngle","endAngle","PI","clockwise","divisions","ordering","angleRatio","compareDegree","a","b","aDegree","degree","bDegree","topologyOrdering","degrees","directed","cnodes","orderedCNodes","resNodes","pickFlags","sourceIdx","targetIdx","sourceChildren","targetChildren","initHierarchy","cnode","all","connect","foundChild","j","childIdx","ii","registry","circular","execute","genericCircularLayout","mergedOptions","center","paramNodeSpacing","paramNodeSize","onLayoutEnd","calculatedWidth","calculatedHeight","calculatedCenter","window","innerWidth","innerHeight","calculateCenter","x","y","angleStep","nodeIdxMap","in","out","nSize","astep","layoutNodes","nodesData","orderedNodes","sort","degreeOrdering","divN","ceil","angle","floor","cos","sin","weight","calculateLayout","payload","transferables","layoutCtor"],"sourceRoot":""}