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 | */
|
10 | export 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 |