UNPKG

17.9 kBJavaScriptView Raw
1/**
2 * ExecutionContext captures the runtime environment of the node. It keeps
3 * track of the current frame and iteration for the control flow ops.
4 *
5 * For example, typical Dynamic RNN model may contain loops, for which
6 * TensorFlow will generate graphs with Enter/Exit nodes to control the
7 * current execution frame, and NextIteration Nodes for iteration id increment.
8 * For model with branch logic, TensorFLow will generate Switch/Merge ops.
9 */
10export class ExecutionContext {
11 constructor(weightMap = {}, tensorArrayMap = {}, tensorListMap = {}, functionMap = {}) {
12 this.weightMap = weightMap;
13 this.tensorArrayMap = tensorArrayMap;
14 this.tensorListMap = tensorListMap;
15 this.functionMap = functionMap;
16 this.rootContext = { id: 0, frameName: '', iterationId: 0 };
17 this.contexts = [this.rootContext];
18 this.lastId = 0;
19 this.generateCurrentContextIds();
20 }
21 newFrame(id, frameName) {
22 return { id, frameName, iterationId: 0 };
23 }
24 /**
25 * Set the current context
26 * @param contexts: ExecutionContextInfo[] the current path of execution
27 * frames
28 */
29 set currentContext(contexts) {
30 if (this.contexts !== contexts) {
31 this.contexts = contexts;
32 this.generateCurrentContextIds();
33 }
34 }
35 get currentContext() {
36 return this.contexts;
37 }
38 /**
39 * Returns the current context in string format.
40 */
41 get currentContextId() {
42 return this._currentContextIds[0];
43 }
44 /**
45 * Returns the current context and all parent contexts in string format.
46 * This allow access to the nodes in the current and parent frames.
47 */
48 get currentContextIds() {
49 return this._currentContextIds;
50 }
51 generateCurrentContextIds() {
52 const names = [];
53 for (let i = 0; i < this.contexts.length - 1; i++) {
54 const contexts = this.contexts.slice(0, this.contexts.length - i);
55 names.push(this.contextIdforContexts(contexts));
56 }
57 names.push('');
58 this._currentContextIds = names;
59 }
60 contextIdforContexts(contexts) {
61 return contexts ?
62 contexts
63 .map(context => (context.id === 0 && context.iterationId === 0) ?
64 '' :
65 `${context.frameName}-${context.iterationId}`)
66 .join('/') :
67 '';
68 }
69 /**
70 * Enter a new frame, a new context is pushed on the current context list.
71 * @param frameId new frame id
72 */
73 enterFrame(frameId) {
74 if (this.contexts) {
75 this.lastId++;
76 this.contexts = this.contexts.slice();
77 this.contexts.push(this.newFrame(this.lastId, frameId));
78 this._currentContextIds.unshift(this.contextIdforContexts(this.contexts));
79 }
80 }
81 /**
82 * Exit the current frame, the last context is removed from the current
83 * context list.
84 */
85 exitFrame() {
86 if (this.contexts && this.contexts.length > 1) {
87 this.contexts = this.contexts.slice();
88 this.contexts.splice(-1);
89 this.currentContextIds.shift();
90 }
91 else {
92 throw new Error('Cannot exit frame, the context is empty');
93 }
94 }
95 /**
96 * Enter the next iteration of a loop, the iteration id of last context is
97 * increased.
98 */
99 nextIteration() {
100 if (this.contexts && this.contexts.length > 0) {
101 this.contexts = this.contexts.slice();
102 this.lastId++;
103 const context = Object.assign({}, this.contexts[this.contexts.length - 1]);
104 context.iterationId += 1;
105 context.id = this.lastId;
106 this.contexts.splice(-1, 1, context);
107 this._currentContextIds.splice(0, 1, this.contextIdforContexts(this.contexts));
108 }
109 else {
110 throw new Error('Cannot increase frame iteration, the context is empty');
111 }
112 }
113 getWeight(name) {
114 return this.weightMap[name];
115 }
116 addTensorArray(tensorArray) {
117 this.tensorArrayMap[tensorArray.id] = tensorArray;
118 }
119 getTensorArray(id) {
120 return this.tensorArrayMap[id];
121 }
122 addTensorList(tensorList) {
123 this.tensorListMap[tensorList.id] = tensorList;
124 }
125 getTensorList(id) {
126 return this.tensorListMap[id];
127 }
128 dispose(keepIds) {
129 for (const key in this.tensorArrayMap) {
130 this.tensorArrayMap[key].clearAndClose(keepIds);
131 }
132 for (const key in this.tensorListMap) {
133 this.tensorListMap[key].clearAndClose(keepIds);
134 }
135 }
136}
137//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhlY3V0aW9uX2NvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvbnZlcnRlci9zcmMvZXhlY3V0b3IvZXhlY3V0aW9uX2NvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBK0JBOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQU0zQixZQUNhLFlBQTZCLEVBQUUsRUFDL0IsaUJBQWlDLEVBQUUsRUFDbkMsZ0JBQStCLEVBQUUsRUFDakMsY0FBaUQsRUFBRTtRQUhuRCxjQUFTLEdBQVQsU0FBUyxDQUFzQjtRQUMvQixtQkFBYyxHQUFkLGNBQWMsQ0FBcUI7UUFDbkMsa0JBQWEsR0FBYixhQUFhLENBQW9CO1FBQ2pDLGdCQUFXLEdBQVgsV0FBVyxDQUF3QztRQVR4RCxnQkFBVyxHQUFHLEVBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUMsQ0FBQztRQUNyRCxhQUFRLEdBQTJCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3RELFdBQU0sR0FBRyxDQUFDLENBQUM7UUFRakIsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVPLFFBQVEsQ0FBQyxFQUFVLEVBQUUsU0FBaUI7UUFDNUMsT0FBTyxFQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBSSxjQUFjLENBQUMsUUFBZ0M7UUFDakQsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRTtZQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztZQUN6QixJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztTQUNsQztJQUNILENBQUM7SUFFRCxJQUFJLGNBQWM7UUFDaEIsT0FBTyxJQUFJLENBQUMsUUFB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QUFFO1lBQ3JDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ2pEO1FBRUQsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3BDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ2hEO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJ0B0ZW5zb3JmbG93L3RmanMtY29yZSc7XG5cbmltcG9ydCB7TmFtZWRUZW5zb3JzTWFwLCBUZW5zb3JBcnJheU1hcCwgVGVuc29yTGlzdE1hcH0gZnJvbSAnLi4vZGF0YS90eXBlcyc7XG5cbmltcG9ydCB7VGVuc29yQXJyYXl9IGZyb20gJy4vdGVuc29yX2FycmF5JztcbmltcG9ydCB7VGVuc29yTGlzdH0gZnJvbSAnLi90ZW5zb3JfbGlzdCc7XG5pbXBvcnQge0Z1bmN0aW9uRXhlY3V0b3J9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEV4ZWN1dGlvbkNvbnRleHRJbmZvIHtcbiAgaWQ6IG51bWJlcjsgICAgICAgICAgIC8vIHRoZSB1bmlxdWUgaWQgb2YgdGhlIGNvbnRleHQgaW5mb1xuICBmcmFtZU5hbWU6IHN0cmluZzsgICAgLy8gVGhlIGZyYW1lIG5hbWUgb2YgdGhlIGxvb3AsIHRoaXMgY29tZXMgZnJvbVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIFRlbnNvckZsb3cgTm9kZURlZi5cbiAgaXRlcmF0aW9uSWQ6IG51bWJlcjsgIC8vIFRoZSBpdGVyYXRpb24gaWQgb2YgdGhlIGxvb3Bcbn1cblxuLyoqXG4gKiBFeGVjdXRpb25Db250ZXh0IGNhcHR1cmVzIHRoZSBydW50aW1lIGVudmlyb25tZW50IG9mIHRoZSBub2RlLiBJdCBrZWVwc1xuICogdHJhY2sgb2YgdGhlIGN1cnJlbnQgZnJhbWUgYW5kIGl0ZXJhdGlvbiBmb3IgdGhlIGNvbnRyb2wgZmxvdyBvcHMuXG4gKlxuICogRm9yIGV4YW1wbGUsIHR5cGljYWwgRHluYW1pYyBSTk4gbW9kZWwgbWF5IGNvbnRhaW4gbG9vcHMsIGZvciB3aGljaFxuICogVGVuc29yRmxvdyB3aWxsIGdlbmVyYXRlIGdyYXBocyB3aXRoIEVudGVyL0V4aXQgbm9kZXMgdG8gY29udHJvbCB0aGVcbiAqIGN1cnJlbnQgZXhlY3V0aW9uIGZyYW1lLCBhbmQgTmV4dEl0ZXJhdGlvbiBOb2RlcyBmb3IgaXRlcmF0aW9uIGlkIGluY3JlbWVudC5cbiAqIEZvciBtb2RlbCB3aXRoIGJyYW5jaCBsb2dpYywgVGVuc29yRkxvdyB3aWxsIGdlbmVyYXRlIFN3aXRjaC9NZXJnZSBvcHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBFeGVjdXRpb25Db250ZXh0IHtcbiAgcHJpdmF0ZSByb290Q29udGV4dCA9IHtpZDogMCwgZnJhbWVOYW1lOiAnJywgaXRlcmF0aW9uSWQ6IDB9O1xuICBwcml2YXRlIGNvbnRleHRzOiBFeGVjdXRpb25Db250ZXh0SW5mb1tdID0gW3RoaXMucm9vdENvbnRleHRdO1xuICBwcml2YXRlIGxhc3RJZCA9IDA7XG4gIHByaXZhdGUgX2N1cnJlbnRDb250ZXh0SWRzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHJlYWRvbmx5IHdlaWdodE1hcDogTmFtZWRUZW5zb3JzTWFwID0ge30sXG4gICAgICByZWFkb25seSB0ZW5zb3JBcnJheU1hcDogVGVuc29yQXJyYXlNYXAgPSB7fSxcbiAgICAgIHJlYWRvbmx5IHRlbnNvckxpc3RNYXA6IFRlbnNvckxpc3RNYXAgPSB7fSxcbiAgICAgIHJlYWRvbmx5IGZ1bmN0aW9uTWFwOiB7W2tleTogc3RyaW5nXTogRnVuY3Rpb25FeGVjdXRvcn0gPSB7fSkge1xuICAgIHRoaXMuZ2VuZXJhdGVDdXJyZW50Q29udGV4dElkcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBuZXdGcmFtZShpZDogbnVtYmVyLCBmcmFtZU5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB7aWQsIGZyYW1lTmFtZSwgaXRlcmF0aW9uSWQ6IDB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqIEBwYXJhbSBjb250ZXh0czogRXhlY3V0aW9uQ29udGV4dEluZm9bXSB0aGUgY3VycmVudCBwYXRoIG9mIGV4ZWN1dGlvblxuICAgKiBmcmFtZXNcbiAgICovXG4gIHNldCBjdXJyZW50Q29udGV4dChjb250ZXh0czogRXhlY3V0aW9uQ29udGV4dEluZm9bXSkge1xuICAgIGlmICh0aGlzLmNvbnRleHRzICE9PSBjb250ZXh0cykge1xuICAgICAgdGhpcy5jb250ZXh0cyA9IGNvbnRleHRzO1xuICAgICAgdGhpcy5nZW5lcmF0ZUN1cnJlbnRDb250ZXh0SWRzKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGN1cnJlbnRDb250ZXh0KCk6IEV4ZWN1dGlvbkNvbnRleHRJbmZvW10ge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgY29udGV4dCBpbiBzdHJpbmcgZm9ybWF0LlxuICAgKi9cbiAgZ2V0IGN1cnJlbnRDb250ZXh0SWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudENvbnRleHRJZHNbMF07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCBjb250ZXh0IGFuZCBhbGwgcGFyZW50IGNvbnRleHRzIGluIHN0cmluZyBmb3JtYXQuXG4gICAqIFRoaXMgYWxsb3cgYWNjZXNzIHRvIHRoZSBub2RlcyBpbiB0aGUgY3VycmVudCBhbmQgcGFyZW50IGZyYW1lcy5cbiAgICovXG4gIGdldCBjdXJyZW50Q29udGV4dElkcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRDb250ZXh0SWRzO1xuICB9XG5cbiAgcHJpdmF0ZSBnZW5lcmF0ZUN1cnJlbnRDb250ZXh0SWRzKCkge1xuICAgIGNvbnN0IG5hbWVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvbnRleHRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgY29uc3QgY29udGV4dHMgPSB0aGlzLmNvbnRleHRzLnNsaWNlKDAsIHRoaXMuY29udGV4dHMubGVuZ3RoIC0gaSk7XG4gICAgICBuYW1lcy5wdXNoKHRoaXMuY29udGV4dElkZm9yQ29udGV4dHMoY29udGV4dHMpKTtcbiAgICB9XG4gICAgbmFtZXMucHVzaCgnJyk7XG4gICAgdGhpcy5fY3VycmVudENvbnRleHRJZHMgPSBuYW1lcztcbiAgfVxuXG4gIHByaXZhdGUgY29udGV4dElkZm9yQ29udGV4dHMoY29udGV4dHM6IEV4ZWN1dGlvbkNvbnRleHRJbmZvW10pIHtcbiAgICByZXR1cm4gY29udGV4dHMgP1xuICAgICAgICBjb250ZXh0c1xuICAgICAgICAgICAgLm1hcChcbiAgICAgICAgICAgICAgICBjb250ZXh0ID0+IChjb250ZXh0LmlkID09PSAwICYmIGNvbnRleHQuaXRlcmF0aW9uSWQgPT09IDApID9cbiAgICAgICAgICAgICAgICAgICAgJycgOlxuICAgICAgICAgICAgICAgICAgICBgJHtjb250ZXh0LmZyYW1lTmFtZX0tJHtjb250ZXh0Lml0ZXJhdGlvbklkfWApXG4gICAgICAgICAgICAuam9pbignLycpIDpcbiAgICAgICAgJyc7XG4gIH1cblxuICAvKipcbiAgICogRW50ZXIgYSBuZXcgZnJhbWUsIGEgbmV3IGNvbnRleHQgaXMgcHVzaGVkIG9uIHRoZSBjdXJyZW50IGNvbnRleHQgbGlzdC5cbiAgICogQHBhcmFtIGZyYW1lSWQgbmV3IGZyYW1lIGlkXG4gICAqL1xuICBlbnRlckZyYW1lKGZyYW1lSWQ6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmNvbnRleHRzKSB7XG4gICAgICB0aGlzLmxhc3RJZCsrO1xuICAgICAgdGhpcy5jb250ZXh0cyA9IHRoaXMuY29udGV4dHMuc2xpY2UoKTtcbiAgICAgIHRoaXMuY29udGV4dHMucHVzaCh0aGlzLm5ld0ZyYW1lKHRoaXMubGFzdElkLCBmcmFtZUlkKSk7XG4gICAgICB0aGlzLl9jdXJyZW50Q29udGV4dElkcy51bnNoaWZ0KHRoaXMuY29udGV4dElkZm9yQ29udGV4dHModGhpcy5jb250ZXh0cykpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFeGl0IHRoZSBjdXJyZW50IGZyYW1lLCB0aGUgbGFzdCBjb250ZXh0IGlzIHJlbW92ZWQgZnJvbSB0aGUgY3VycmVudFxuICAgKiBjb250ZXh0IGxpc3QuXG4gICAqL1xuICBleGl0RnJhbWUoKSB7XG4gICAgaWYgKHRoaXMuY29udGV4dHMgJiYgdGhpcy5jb250ZXh0cy5sZW5ndGggPiAxKSB7XG4gICAgICB0aGlzLmNvbnRleHRzID0gdGhpcy5jb250ZXh0cy5zbGljZSgpO1xuICAgICAgdGhpcy5jb250ZXh0cy5zcGxpY2UoLTEpO1xuICAgICAgdGhpcy5jdXJyZW50Q29udGV4dElkcy5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBleGl0IGZyYW1lLCB0aGUgY29udGV4dCBpcyBlbXB0eScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFbnRlciB0aGUgbmV4dCBpdGVyYXRpb24gb2YgYSBsb29wLCB0aGUgaXRlcmF0aW9uIGlkIG9mIGxhc3QgY29udGV4dCBpc1xuICAgKiBpbmNyZWFzZWQuXG4gICAqL1xuICBuZXh0SXRlcmF0aW9uKCkge1xuICAgIGlmICh0aGlzLmNvbnRleHRzICYmIHRoaXMuY29udGV4dHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5jb250ZXh0cyA9IHRoaXMuY29udGV4dHMuc2xpY2UoKTtcbiAgICAgIHRoaXMubGFzdElkKys7XG4gICAgICBjb25zdCBjb250ZXh0ID1cbiAgICAgICAgICBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmNvbnRleHRzW3RoaXMuY29udGV4dHMubGVuZ3RoIC0gMV0pO1xuICAgICAgY29udGV4dC5pdGVyYXRpb25JZCArPSAxO1xuICAgICAgY29udGV4dC5pZCA9IHRoaXMubGFzdElkO1xuICAgICAgdGhpcy5jb250ZXh0cy5zcGxpY2UoLTEsIDEsIGNvbnRleHQpO1xuICAgICAgdGhpcy5fY3VycmVudENvbnRleHRJZHMuc3BsaWNlKFxuICAgICAgICAgIDAsIDEsIHRoaXMuY29udGV4dElkZm9yQ29udGV4dHModGhpcy5jb250ZXh0cykpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBpbmNyZWFzZSBmcmFtZSBpdGVyYXRpb24sIHRoZSBjb250ZXh0IGlzIGVtcHR5Jyk7XG4gICAgfVxuICB9XG5cbiAgZ2V0V2VpZ2h0KG5hbWU6IHN0cmluZyk6IFRlbnNvcltdIHtcbiAgICByZXR1cm4gdGhpcy53ZWlnaHRNYXBbbmFtZV07XG4gIH1cblxuICBhZGRUZW5zb3JBcnJheSh0ZW5zb3JBcnJheTogVGVuc29yQXJyYXkpIHtcbiAgICB0aGlzLnRlbnNvckFycmF5TWFwW3RlbnNvckFycmF5LmlkXSA9IHRlbnNvckFycmF5O1xuICB9XG5cbiAgZ2V0VGVuc29yQXJyYXkoaWQ6IG51bWJlcik6IFRlbnNvckFycmF5IHtcbiAgICByZXR1cm4gdGhpcy50ZW5zb3JBcnJheU1hcFtpZF07XG4gIH1cblxuICBhZGRUZW5zb3JMaXN0KHRlbnNvckxpc3Q6IFRlbnNvckxpc3QpIHtcbiAgICB0aGlzLnRlbnNvckxpc3RNYXBbdGVuc29yTGlzdC5pZF0gPSB0ZW5zb3JMaXN0O1xuICB9XG5cbiAgZ2V0VGVuc29yTGlzdChpZDogbnVtYmVyKTogVGVuc29yTGlzdCB7XG4gICAgcmV0dXJuIHRoaXMudGVuc29yTGlzdE1hcFtpZF07XG4gIH1cblxuICBkaXNwb3NlKGtlZXBJZHM6IFNldDxudW1iZXI+KSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy50ZW5zb3JBcnJheU1hcCkge1xuICAgICAgdGhpcy50ZW5zb3JBcnJheU1hcFtrZXldLmNsZWFyQW5kQ2xvc2Uoa2VlcElkcyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy50ZW5zb3JMaXN0TWFwKSB7XG4gICAgICB0aGlzLnRlbnNvckxpc3RNYXBba2V5XS5jbGVhckFuZENsb3NlKGtlZXBJZHMpO1xuICAgIH1cbiAgfVxufVxuIl19
\No newline at end of file