1 | /**
|
2 | * @license
|
3 | * Copyright 2019 Google LLC. All Rights Reserved.
|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | * you may not use this file except in compliance with the License.
|
6 | * You may obtain a copy of the License at
|
7 | *
|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
9 | *
|
10 | * Unless required by applicable law or agreed to in writing, software
|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | * See the License for the specific language governing permissions and
|
14 | * limitations under the License.
|
15 | * =============================================================================
|
16 | */
|
17 | import * as tf from './index';
|
18 | import { ALL_ENVS, describeWithFlags, NODE_ENVS } from './jasmine_util';
|
19 | import { expectArraysClose } from './test_util';
|
20 | describe('deprecation warnings', () => {
|
21 | beforeEach(() => {
|
22 | spyOn(console, 'warn').and.callFake((msg) => null);
|
23 | });
|
24 | it('deprecationWarn warns', () => {
|
25 | // flags_test.ts verifies deprecation warnings are on by default.
|
26 | const deprecationVal = tf.env().get('DEPRECATION_WARNINGS_ENABLED');
|
27 | tf.env().set('DEPRECATION_WARNINGS_ENABLED', true);
|
28 | tf.deprecationWarn('xyz is deprecated.');
|
29 | tf.env().set('DEPRECATION_WARNINGS_ENABLED', deprecationVal);
|
30 | expect(console.warn).toHaveBeenCalledTimes(1);
|
31 | expect(console.warn)
|
32 | .toHaveBeenCalledWith('xyz is deprecated. You can disable deprecation warnings with ' +
|
33 | 'tf.disableDeprecationWarnings().');
|
34 | });
|
35 | it('disableDeprecationWarnings called, deprecationWarn doesnt warn', () => {
|
36 | tf.disableDeprecationWarnings();
|
37 | expect(console.warn).toHaveBeenCalledTimes(1);
|
38 | expect(console.warn)
|
39 | .toHaveBeenCalledWith('TensorFlow.js deprecation warnings have been disabled.');
|
40 | // deprecationWarn no longer warns.
|
41 | tf.deprecationWarn('xyz is deprecated.');
|
42 | expect(console.warn).toHaveBeenCalledTimes(1);
|
43 | });
|
44 | });
|
45 | describe('Flag flipping methods', () => {
|
46 | beforeEach(() => {
|
47 | tf.env().reset();
|
48 | });
|
49 | afterEach(() => {
|
50 | tf.env().reset();
|
51 | });
|
52 | it('tf.enableProdMode', () => {
|
53 | tf.enableProdMode();
|
54 | expect(tf.env().getBool('PROD')).toBe(true);
|
55 | });
|
56 | it('tf.enableDebugMode', () => {
|
57 | // Silence debug warnings.
|
58 | spyOn(console, 'warn');
|
59 | tf.enableDebugMode();
|
60 | expect(tf.env().getBool('DEBUG')).toBe(true);
|
61 | });
|
62 | });
|
63 | describeWithFlags('time cpu', NODE_ENVS, () => {
|
64 | it('simple upload', async () => {
|
65 | const a = tf.zeros([10, 10]);
|
66 | const time = await tf.time(() => a.square());
|
67 | expect(time.kernelMs > 0);
|
68 | expect(time.wallMs >= time.kernelMs);
|
69 | });
|
70 | });
|
71 | describeWithFlags('tidy', ALL_ENVS, () => {
|
72 | it('returns Tensor', async () => {
|
73 | tf.tidy(() => {
|
74 | const a = tf.tensor1d([1, 2, 3]);
|
75 | let b = tf.tensor1d([0, 0, 0]);
|
76 | expect(tf.memory().numTensors).toBe(2);
|
77 | tf.tidy(() => {
|
78 | const result = tf.tidy(() => {
|
79 | b = tf.add(a, b);
|
80 | b = tf.add(a, b);
|
81 | b = tf.add(a, b);
|
82 | return tf.add(a, b);
|
83 | });
|
84 | // result is new. All intermediates should be disposed.
|
85 | expect(tf.memory().numTensors).toBe(2 + 1);
|
86 | expect(result.shape).toEqual([3]);
|
87 | expect(result.isDisposed).toBe(false);
|
88 | });
|
89 | // a, b are still here, result should be disposed.
|
90 | expect(tf.memory().numTensors).toBe(2);
|
91 | });
|
92 | expect(tf.memory().numTensors).toBe(0);
|
93 | });
|
94 | it('multiple disposes does not affect num arrays', () => {
|
95 | expect(tf.memory().numTensors).toBe(0);
|
96 | const a = tf.tensor1d([1, 2, 3]);
|
97 | const b = tf.tensor1d([1, 2, 3]);
|
98 | expect(tf.memory().numTensors).toBe(2);
|
99 | a.dispose();
|
100 | a.dispose();
|
101 | expect(tf.memory().numTensors).toBe(1);
|
102 | b.dispose();
|
103 | expect(tf.memory().numTensors).toBe(0);
|
104 | });
|
105 | it('allows primitive types', () => {
|
106 | const a = tf.tidy(() => 5);
|
107 | expect(a).toBe(5);
|
108 | const b = tf.tidy(() => 'hello');
|
109 | expect(b).toBe('hello');
|
110 | });
|
111 | it('allows complex types', async () => {
|
112 | const res = tf.tidy(() => {
|
113 | return { a: tf.scalar(1), b: 'hello', c: [tf.scalar(2), 'world'] };
|
114 | });
|
115 | expectArraysClose(await res.a.data(), [1]);
|
116 | expectArraysClose(await res.c[0].data(), [2]);
|
117 | });
|
118 | it('returns Tensor[]', async () => {
|
119 | const a = tf.tensor1d([1, 2, 3]);
|
120 | const b = tf.tensor1d([0, -1, 1]);
|
121 | expect(tf.memory().numTensors).toBe(2);
|
122 | tf.tidy(() => {
|
123 | const result = tf.tidy(() => {
|
124 | tf.add(a, b);
|
125 | return [tf.add(a, b), tf.sub(a, b)];
|
126 | });
|
127 | // the 2 results are new. All intermediates should be disposed.
|
128 | expect(tf.memory().numTensors).toBe(4);
|
129 | expect(result[0].isDisposed).toBe(false);
|
130 | expect(result[0].shape).toEqual([3]);
|
131 | expect(result[1].isDisposed).toBe(false);
|
132 | expect(result[1].shape).toEqual([3]);
|
133 | expect(tf.memory().numTensors).toBe(4);
|
134 | });
|
135 | // the 2 results should be disposed.
|
136 | expect(tf.memory().numTensors).toBe(2);
|
137 | a.dispose();
|
138 | b.dispose();
|
139 | expect(tf.memory().numTensors).toBe(0);
|
140 | });
|
141 | it('basic usage without return', () => {
|
142 | const a = tf.tensor1d([1, 2, 3]);
|
143 | let b = tf.tensor1d([0, 0, 0]);
|
144 | expect(tf.memory().numTensors).toBe(2);
|
145 | tf.tidy(() => {
|
146 | b = tf.add(a, b);
|
147 | b = tf.add(a, b);
|
148 | b = tf.add(a, b);
|
149 | tf.add(a, b);
|
150 | });
|
151 | // all intermediates should be disposed.
|
152 | expect(tf.memory().numTensors).toBe(2);
|
153 | });
|
154 | it('nested usage', async () => {
|
155 | const a = tf.tensor1d([1, 2, 3]);
|
156 | let b = tf.tensor1d([0, 0, 0]);
|
157 | expect(tf.memory().numTensors).toBe(2);
|
158 | tf.tidy(() => {
|
159 | const result = tf.tidy(() => {
|
160 | b = tf.add(a, b);
|
161 | b = tf.tidy(() => {
|
162 | b = tf.tidy(() => {
|
163 | return tf.add(a, b);
|
164 | });
|
165 | // original a, b, and two intermediates.
|
166 | expect(tf.memory().numTensors).toBe(4);
|
167 | tf.tidy(() => {
|
168 | tf.add(a, b);
|
169 | });
|
170 | // All the intermediates should be cleaned up.
|
171 | expect(tf.memory().numTensors).toBe(4);
|
172 | return tf.add(a, b);
|
173 | });
|
174 | expect(tf.memory().numTensors).toBe(4);
|
175 | return tf.add(a, b);
|
176 | });
|
177 | expect(tf.memory().numTensors).toBe(3);
|
178 | expect(result.isDisposed).toBe(false);
|
179 | expect(result.shape).toEqual([3]);
|
180 | });
|
181 | expect(tf.memory().numTensors).toBe(2);
|
182 | });
|
183 | it('nested usage returns tensor created from outside scope', () => {
|
184 | const x = tf.scalar(1);
|
185 | tf.tidy(() => {
|
186 | tf.tidy(() => {
|
187 | return x;
|
188 | });
|
189 | });
|
190 | expect(x.isDisposed).toBe(false);
|
191 | });
|
192 | it('nested usage with keep works', () => {
|
193 | let b;
|
194 | tf.tidy(() => {
|
195 | const a = tf.scalar(1);
|
196 | tf.tidy(() => {
|
197 | b = tf.keep(a);
|
198 | });
|
199 | });
|
200 | expect(b.isDisposed).toBe(false);
|
201 | b.dispose();
|
202 | });
|
203 | it('single argument', () => {
|
204 | let hasRan = false;
|
205 | tf.tidy(() => {
|
206 | hasRan = true;
|
207 | });
|
208 | expect(hasRan).toBe(true);
|
209 | });
|
210 | it('single argument, but not a function throws error', () => {
|
211 | expect(() => {
|
212 | tf.tidy('asdf');
|
213 | }).toThrowError();
|
214 | });
|
215 | it('2 arguments, first is string', () => {
|
216 | let hasRan = false;
|
217 | tf.tidy('name', () => {
|
218 | hasRan = true;
|
219 | });
|
220 | expect(hasRan).toBe(true);
|
221 | });
|
222 | it('2 arguments, but first is not string throws error', () => {
|
223 | expect(() => {
|
224 | // tslint:disable-next-line:no-any
|
225 | tf.tidy(4, () => { });
|
226 | }).toThrowError();
|
227 | });
|
228 | it('2 arguments, but second is not a function throws error', () => {
|
229 | expect(() => {
|
230 | // tslint:disable-next-line:no-any
|
231 | tf.tidy('name', 'another name');
|
232 | }).toThrowError();
|
233 | });
|
234 | it('works with arbitrary depth of result', async () => {
|
235 | tf.tidy(() => {
|
236 | const res = tf.tidy(() => {
|
237 | return [tf.scalar(1), [[tf.scalar(2)]], { list: [tf.scalar(3)] }];
|
238 | });
|
239 | expect(res[0].isDisposed).toBe(false);
|
240 | // tslint:disable-next-line:no-any
|
241 | expect(res[1][0][0].isDisposed).toBe(false);
|
242 | // tslint:disable-next-line:no-any
|
243 | expect(res[2].list[0].isDisposed).toBe(false);
|
244 | expect(tf.memory().numTensors).toBe(3);
|
245 | return res[0];
|
246 | });
|
247 | // Everything but scalar(1) got disposed.
|
248 | expect(tf.memory().numTensors).toBe(1);
|
249 | });
|
250 | });
|
251 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2xvYmFsc190ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9nbG9iYWxzX3Rlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RSxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFFOUMsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtJQUNwQyxVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsS0FBSyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBVyxFQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7UUFDL0IsaUVBQWlFO1FBQ2pFLE1BQU0sY0FBYyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNwRSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLDhCQUE4QixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ25ELEVBQUUsQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUN6QyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLDhCQUE4QixFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzdELE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7YUFDZixv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Q0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxrQ0FBa0M7WUFDbEMsTUFBTSxDQUFFLEdBQUcsQ0FBQyxDQUFDLENBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO1FBQ0gseUNBQXlDO1FBQ3pDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCAqIGFzIHRmIGZyb20gJy4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3MsIE5PREVfRU5WU30gZnJvbSAnLi9qYXNtaW5lX3V0aWwnO1xuaW1wb3J0IHtleHBlY3RBcnJheXNDbG9zZX0gZnJvbSAnLi90ZXN0X3V0aWwnO1xuXG5kZXNjcmliZSgnZGVwcmVjYXRpb24gd2FybmluZ3MnLCAoKSA9PiB7XG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIHNweU9uKGNvbnNvbGUsICd3YXJuJykuYW5kLmNhbGxGYWtlKChtc2c6IHN0cmluZyk6IHZvaWQgPT4gbnVsbCk7XG4gIH0pO1xuXG4gIGl0KCdkZXByZWNhdGlvbldhcm4gd2FybnMnLCAoKSA9PiB7XG4gICAgLy8gZmxhZ3NfdGVzdC50cyB2ZXJpZmllcyBkZXByZWNhdGlvbiB3YXJuaW5ncyBhcmUgb24gYnkgZGVmYXVsdC5cbiAgICBjb25zdCBkZXByZWNhdGlvblZhbCA9IHRmLmVudigpLmdldCgnREVQUkVDQVRJT05fV0FSTklOR1NfRU5BQkxFRCcpO1xuICAgIHRmLmVudigpLnNldCgnREVQUkVDQVRJT05fV0FSTklOR1NfRU5BQkxFRCcsIHRydWUpO1xuICAgIHRmLmRlcHJlY2F0aW9uV2FybigneHl6IGlzIGRlcHJlY2F0ZWQuJyk7XG4gICAgdGYuZW52KCkuc2V0KCdERVBSRUNBVElPTl9XQVJOSU5HU19FTkFCTEVEJywgZGVwcmVjYXRpb25WYWwpO1xuICAgIGV4cGVjdChjb25zb2xlLndhcm4pLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygxKTtcbiAgICBleHBlY3QoY29uc29sZS53YXJuKVxuICAgICAgICAudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgICAgICAneHl6IGlzIGRlcHJlY2F0ZWQuIFlvdSBjYW4gZGlzYWJsZSBkZXByZWNhdGlvbiB3YXJuaW5ncyB3aXRoICcgK1xuICAgICAgICAgICAgJ3RmLmRpc2FibGVEZXByZWNhdGlvbldhcm5pbmdzKCkuJyk7XG4gIH0pO1xuXG4gIGl0KCdkaXNhYmxlRGVwcmVjYXRpb25XYXJuaW5ncyBjYWxsZWQsIGRlcHJlY2F0aW9uV2FybiBkb2VzbnQgd2FybicsICgpID0+IHtcbiAgICB0Zi5kaXNhYmxlRGVwcmVjYXRpb25XYXJuaW5ncygpO1xuICAgIGV4cGVjdChjb25zb2xlLndhcm4pLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygxKTtcbiAgICBleHBlY3QoY29uc29sZS53YXJuKVxuICAgICAgICAudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgICAgICAnVGVuc29yRmxvdy5qcyBkZXByZWNhdGlvbiB3YXJuaW5ncyBoYXZlIGJlZW4gZGlzYWJsZWQuJyk7XG5cbiAgICAvLyBkZXByZWNhdGlvbldhcm4gbm8gbG9uZ2VyIHdhcm5zLlxuICAgIHRmLmRlcHJlY2F0aW9uV2FybigneHl6IGlzIGRlcHJlY2F0ZWQuJyk7XG4gICAgZXhwZWN0KGNvbnNvbGUud2FybikudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRmxhZyBmbGlwcGluZyBtZXRob2RzJywgKCkgPT4ge1xuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICB0Zi5lbnYoKS5yZXNldCgpO1xuICB9KTtcblxuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIHRmLmVudigpLnJlc2V0KCk7XG4gIH0pO1xuXG4gIGl0KCd0Zi5lbmFibGVQcm9kTW9kZScsICgpID0+IHtcbiAgICB0Zi5lbmFibGVQcm9kTW9kZSgpO1xuICAgIGV4cGVjdCh0Zi5lbnYoKS5nZXRCb29sKCdQUk9EJykpLnRvQmUodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCd0Zi5lbmFibGVEZWJ1Z01vZGUnLCAoKSA9PiB7XG4gICAgLy8gU2lsZW5jZSBkZWJ1ZyB3YXJuaW5ncy5cbiAgICBzcHlPbihjb25zb2xlLCAnd2FybicpO1xuICAgIHRmLmVuYWJsZURlYnVnTW9kZSgpO1xuICAgIGV4cGVjdCh0Zi5lbnYoKS5nZXRCb29sKCdERUJVRycpKS50b0JlKHRydWUpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZVdpdGhGbGFncygndGltZSBjcHUnLCBOT0RFX0VOVlMsICgpID0+IHtcbiAgaXQoJ3NpbXBsZSB1cGxvYWQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnplcm9zKFsxMCwgMTBdKTtcbiAgICBjb25zdCB0aW1lID0gYXdhaXQgdGYudGltZSgoKSA9PiBhLnNxdWFyZSgpKTtcbiAgICBleHBlY3QodGltZS5rZXJuZWxNcyA+IDApO1xuICAgIGV4cGVjdCh0aW1lLndhbGxNcyA+PSB0aW1lLmtlcm5lbE1zKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ3RpZHknLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgncmV0dXJucyBUZW5zb3InLCBhc3luYyAoKSA9PiB7XG4gICAgdGYudGlkeSgoKSA9PiB7XG4gICAgICBjb25zdCBhID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcbiAgICAgIGxldCBiID0gdGYudGVuc29yMWQoWzAsIDAsIDBdKTtcblxuICAgICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMik7XG4gICAgICB0Zi50aWR5KCgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGYudGlkeSgoKSA9PiB7XG4gICAgICAgICAgYiA9IHRmLmFkZChhLCBiKTtcbiAgICAgICAgICBiID0gdGYuYWRkKGEsIGIpO1xuICAgICAgICAgIGIgPSB0Zi5hZGQoYSwgYik7XG4gICAgICAgICAgcmV0dXJuIHRmLmFkZChhLCBiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcmVzdWx0IGlzIG5ldy4gQWxsIGludGVybWVkaWF0ZXMgc2hvdWxkIGJlIGRpc3Bvc2VkLlxuICAgICAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgyICsgMSk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzNdKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5pc0Rpc3Bvc2VkKS50b0JlKGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBhLCBiIGFyZSBzdGlsbCBoZXJlLCByZXN1bHQgc2hvdWxkIGJlIGRpc3Bvc2VkLlxuICAgICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMik7XG4gICAgfSk7XG5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgwKTtcbiAgfSk7XG5cbiAgaXQoJ211bHRpcGxlIGRpc3Bvc2VzIGRvZXMgbm90IGFmZmVjdCBudW0gYXJyYXlzJywgKCkgPT4ge1xuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDApO1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAgIGNvbnN0IGIgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDIpO1xuICAgIGEuZGlzcG9zZSgpO1xuICAgIGEuZGlzcG9zZSgpO1xuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDEpO1xuICAgIGIuZGlzcG9zZSgpO1xuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDApO1xuICB9KTtcblxuICBpdCgnYWxsb3dzIHByaW1pdGl2ZSB0eXBlcycsICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGlkeSgoKSA9PiA1KTtcbiAgICBleHBlY3QoYSkudG9CZSg1KTtcblxuICAgIGNvbnN0IGIgPSB0Zi50aWR5KCgpID0+ICdoZWxsbycpO1xuICAgIGV4cGVjdChiKS50b0JlKCdoZWxsbycpO1xuICB9KTtcblxuICBpdCgnYWxsb3dzIGNvbXBsZXggdHlwZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gdGYudGlkeSgoKSA9PiB7XG4gICAgICByZXR1cm4ge2E6IHRmLnNjYWxhcigxKSwgYjogJ2hlbGxvJywgYzogW3RmLnNjYWxhcigyKSwgJ3dvcmxkJ119O1xuICAgIH0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlcy5hLmRhdGEoKSwgWzFdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCAocmVzLmNbMF0gYXMgdGYuVGVuc29yKS5kYXRhKCksIFsyXSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIFRlbnNvcltdJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAgIGNvbnN0IGIgPSB0Zi50ZW5zb3IxZChbMCwgLTEsIDFdKTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgyKTtcblxuICAgIHRmLnRpZHkoKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGYudGlkeSgoKSA9PiB7XG4gICAgICAgIHRmLmFkZChhLCBiKTtcbiAgICAgICAgcmV0dXJuIFt0Zi5hZGQoYSwgYiksIHRmLnN1YihhLCBiKV07XG4gICAgICB9KTtcblxuICAgICAgLy8gdGhlIDIgcmVzdWx0cyBhcmUgbmV3LiBBbGwgaW50ZXJtZWRpYXRlcyBzaG91bGQgYmUgZGlzcG9zZWQuXG4gICAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSg0KTtcbiAgICAgIGV4cGVjdChyZXN1bHRbMF0uaXNEaXNwb3NlZCkudG9CZShmYWxzZSk7XG4gICAgICBleHBlY3QocmVzdWx0WzBdLnNoYXBlKS50b0VxdWFsKFszXSk7XG4gICAgICBleHBlY3QocmVzdWx0WzFdLmlzRGlzcG9zZWQpLnRvQmUoZmFsc2UpO1xuICAgICAgZXhwZWN0KHJlc3VsdFsxXS5zaGFwZSkudG9FcXVhbChbM10pO1xuICAgICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoNCk7XG4gICAgfSk7XG5cbiAgICAvLyB0aGUgMiByZXN1bHRzIHNob3VsZCBiZSBkaXNwb3NlZC5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgyKTtcbiAgICBhLmRpc3Bvc2UoKTtcbiAgICBiLmRpc3Bvc2UoKTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgwKTtcbiAgfSk7XG5cbiAgaXQoJ2Jhc2ljIHVzYWdlIHdpdGhvdXQgcmV0dXJuJywgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAgIGxldCBiID0gdGYudGVuc29yMWQoWzAsIDAsIDBdKTtcblxuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDIpO1xuXG4gICAgdGYudGlkeSgoKSA9PiB7XG4gICAgICBiID0gdGYuYWRkKGEsIGIpO1xuICAgICAgYiA9IHRmLmFkZChhLCBiKTtcbiAgICAgIGIgPSB0Zi5hZGQoYSwgYik7XG4gICAgICB0Zi5hZGQoYSwgYik7XG4gICAgfSk7XG5cbiAgICAvLyBhbGwgaW50ZXJtZWRpYXRlcyBzaG91bGQgYmUgZGlzcG9zZWQuXG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMik7XG4gIH0pO1xuXG4gIGl0KCduZXN0ZWQgdXNhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzXSk7XG4gICAgbGV0IGIgPSB0Zi50ZW5zb3IxZChbMCwgMCwgMF0pO1xuXG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMik7XG5cbiAgICB0Zi50aWR5KCgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRmLnRpZHkoKCkgPT4ge1xuICAgICAgICBiID0gdGYuYWRkKGEsIGIpO1xuICAgICAgICBiID0gdGYudGlkeSgoKSA9PiB7XG4gICAgICAgICAgYiA9IHRmLnRpZHkoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRmLmFkZChhLCBiKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBvcmlnaW5hbCBhLCBiLCBhbmQgdHdvIGludGVybWVkaWF0ZXMuXG4gICAgICAgICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoNCk7XG5cbiAgICAgICAgICB0Zi50aWR5KCgpID0+IHtcbiAgICAgICAgICAgIHRmLmFkZChhLCBiKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBBbGwgdGhlIGludGVybWVkaWF0ZXMgc2hvdWxkIGJlIGNsZWFuZWQgdXAuXG4gICAgICAgICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoNCk7XG5cbiAgICAgICAgICByZXR1cm4gdGYuYWRkKGEsIGIpO1xuICAgICAgICB9KTtcbiAgICAgICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoNCk7XG5cbiAgICAgICAgcmV0dXJuIHRmLmFkZChhLCBiKTtcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgzKTtcbiAgICAgIGV4cGVjdChyZXN1bHQuaXNEaXNwb3NlZCkudG9CZShmYWxzZSk7XG4gICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFszXSk7XG4gICAgfSk7XG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMik7XG4gIH0pO1xuXG4gIGl0KCduZXN0ZWQgdXNhZ2UgcmV0dXJucyB0ZW5zb3IgY3JlYXRlZCBmcm9tIG91dHNpZGUgc2NvcGUnLCAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnNjYWxhcigxKTtcblxuICAgIHRmLnRpZHkoKCkgPT4ge1xuICAgICAgdGYudGlkeSgoKSA9PiB7XG4gICAgICAgIHJldHVybiB4O1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBleHBlY3QoeC5pc0Rpc3Bvc2VkKS50b0JlKGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ25lc3RlZCB1c2FnZSB3aXRoIGtlZXAgd29ya3MnLCAoKSA9PiB7XG4gICAgbGV0IGI6IHRmLlRlbnNvcjtcbiAgICB0Zi50aWR5KCgpID0+IHtcbiAgICAgIGNvbnN0IGEgPSB0Zi5zY2FsYXIoMSk7XG4gICAgICB0Zi50aWR5KCgpID0+IHtcbiAgICAgICAgYiA9IHRmLmtlZXAoYSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGV4cGVjdChiLmlzRGlzcG9zZWQpLnRvQmUoZmFsc2UpO1xuICAgIGIuZGlzcG9zZSgpO1xuICB9KTtcblxuICBpdCgnc2luZ2xlIGFyZ3VtZW50JywgKCkgPT4ge1xuICAgIGxldCBoYXNSYW4gPSBmYWxzZTtcbiAgICB0Zi50aWR5KCgpID0+IHtcbiAgICAgIGhhc1JhbiA9IHRydWU7XG4gICAgfSk7XG4gICAgZXhwZWN0KGhhc1JhbikudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3NpbmdsZSBhcmd1bWVudCwgYnV0IG5vdCBhIGZ1bmN0aW9uIHRocm93cyBlcnJvcicsICgpID0+IHtcbiAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgdGYudGlkeSgnYXNkZicpO1xuICAgIH0pLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgnMiBhcmd1bWVudHMsIGZpcnN0IGlzIHN0cmluZycsICgpID0+IHtcbiAgICBsZXQgaGFzUmFuID0gZmFsc2U7XG4gICAgdGYudGlkeSgnbmFtZScsICgpID0+IHtcbiAgICAgIGhhc1JhbiA9IHRydWU7XG4gICAgfSk7XG4gICAgZXhwZWN0KGhhc1JhbikudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJzIgYXJndW1lbnRzLCBidXQgZmlyc3QgaXMgbm90IHN0cmluZyB0aHJvd3MgZXJyb3InLCAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgIHRmLnRpZHkoNCBhcyBhbnksICgpID0+IHt9KTtcbiAgICB9KS50b1Rocm93RXJyb3IoKTtcbiAgfSk7XG5cbiAgaXQoJzIgYXJndW1lbnRzLCBidXQgc2Vjb25kIGlzIG5vdCBhIGZ1bmN0aW9uIHRocm93cyBlcnJvcicsICgpID0+IHtcbiAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgICAgdGYudGlkeSgnbmFtZScsICdhbm90aGVyIG5hbWUnIGFzIGFueSk7XG4gICAgfSkudG9UaHJvd0Vycm9yKCk7XG4gIH0pO1xuXG4gIGl0KCd3b3JrcyB3aXRoIGFyYml0cmFyeSBkZXB0aCBvZiByZXN1bHQnLCBhc3luYyAoKSA9PiB7XG4gICAgdGYudGlkeSgoKSA9PiB7XG4gICAgICBjb25zdCByZXMgPSB0Zi50aWR5KCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFt0Zi5zY2FsYXIoMSksIFtbdGYuc2NhbGFyKDIpXV0sIHtsaXN0OiBbdGYuc2NhbGFyKDMpXX1dO1xuICAgICAgfSk7XG4gICAgICBleHBlY3QoKHJlc1swXSBhcyB0Zi5UZW5zb3IpLmlzRGlzcG9zZWQpLnRvQmUoZmFsc2UpO1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgICAgZXhwZWN0KChyZXNbMV0gYXMgYW55KVswXVswXS5pc0Rpc3Bvc2VkKS50b0JlKGZhbHNlKTtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgIGV4cGVjdCgocmVzWzJdIGFzIGFueSkubGlzdFswXS5pc0Rpc3Bvc2VkKS50b0JlKGZhbHNlKTtcbiAgICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDMpO1xuICAgICAgcmV0dXJuIHJlc1swXTtcbiAgICB9KTtcbiAgICAvLyBFdmVyeXRoaW5nIGJ1dCBzY2FsYXIoMSkgZ290IGRpc3Bvc2VkLlxuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDEpO1xuICB9KTtcbn0pO1xuIl19 |
\ | No newline at end of file |