1 | /**
|
2 | * @license
|
3 | * Copyright 2020 Google Inc. 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 } from '../jasmine_util';
|
19 | import { expectArraysClose, expectArraysEqual } from '../test_util';
|
20 | import * as reduce_util from './reduce_util';
|
21 | describeWithFlags('argmin', ALL_ENVS, () => {
|
22 | it('Tensor1D', async () => {
|
23 | const a = tf.tensor1d([1, 0, 3, 2]);
|
24 | const result = tf.argMin(a);
|
25 | expectArraysEqual(await result.data(), 1);
|
26 | });
|
27 | it('one value', async () => {
|
28 | const a = tf.tensor1d([10]);
|
29 | const result = tf.argMin(a);
|
30 | expectArraysEqual(await result.data(), 0);
|
31 | });
|
32 | it('N > than parallelization threshold', async () => {
|
33 | const n = reduce_util.PARALLELIZE_THRESHOLD * 2;
|
34 | const values = new Float32Array(n);
|
35 | for (let i = 0; i < n; i++) {
|
36 | values[i] = n - i;
|
37 | }
|
38 | const a = tf.tensor1d(values);
|
39 | const result = tf.argMin(a);
|
40 | expect(result.dtype).toBe('int32');
|
41 | expectArraysEqual(await result.data(), n - 1);
|
42 | });
|
43 | it('4D, N > than parallelization threshold', async () => {
|
44 | const n = reduce_util.PARALLELIZE_THRESHOLD * 2;
|
45 | const values = new Float32Array(n);
|
46 | for (let i = 0; i < n; i++) {
|
47 | values[i] = n - i;
|
48 | }
|
49 | const a = tf.tensor4d(values, [1, 1, 1, n]);
|
50 | const result = tf.argMin(a, -1);
|
51 | expect(result.dtype).toBe('int32');
|
52 | expectArraysEqual(await result.data(), n - 1);
|
53 | });
|
54 | it('min index corresponds to start of a non-initial window', async () => {
|
55 | const n = reduce_util.PARALLELIZE_THRESHOLD * 2;
|
56 | const windowSize = reduce_util.computeOptimalWindowSize(n);
|
57 | const values = new Float32Array(n);
|
58 | const index = windowSize * 2;
|
59 | values[index] = -1;
|
60 | const a = tf.tensor1d(values);
|
61 | const result = tf.argMin(a);
|
62 | expect(result.dtype).toBe('int32');
|
63 | expectArraysEqual(await result.data(), index);
|
64 | });
|
65 | it('ignores NaNs', async () => {
|
66 | const a = tf.tensor1d([5, 0, NaN, -1, 3]);
|
67 | const res = tf.argMin(a);
|
68 | expectArraysEqual(await res.data(), 3);
|
69 | });
|
70 | it('3D, ignores NaNs', async () => {
|
71 | const a = tf.tensor3d([5, 0, NaN, -1, 3], [1, 1, 5]);
|
72 | const res = tf.argMin(a, -1);
|
73 | expectArraysEqual(await res.data(), 3);
|
74 | });
|
75 | it('2D, no axis specified', async () => {
|
76 | const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
|
77 | expectArraysEqual(await tf.argMin(a).data(), [0, 1, 0]);
|
78 | });
|
79 | it('2D, axis=0', async () => {
|
80 | const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
|
81 | const r = tf.argMin(a, 0);
|
82 | expect(r.shape).toEqual([3]);
|
83 | expect(r.dtype).toBe('int32');
|
84 | expectArraysEqual(await r.data(), [0, 1, 0]);
|
85 | });
|
86 | it('2D, axis=1', async () => {
|
87 | const a = tf.tensor2d([3, 2, 5, 100, -7, -8], [2, 3]);
|
88 | const r = tf.argMin(a, 1);
|
89 | expectArraysEqual(await r.data(), [1, 2]);
|
90 | });
|
91 | it('2D, axis = -1', async () => {
|
92 | const a = tf.tensor2d([3, 2, 5, 100, -7, -8], [2, 3]);
|
93 | const r = tf.argMin(a, -1);
|
94 | expectArraysEqual(await r.data(), [1, 2]);
|
95 | });
|
96 | it('throws when passed a non-tensor', () => {
|
97 | expect(() => tf.argMin({}))
|
98 | .toThrowError(/Argument 'x' passed to 'argMin' must be a Tensor/);
|
99 | });
|
100 | it('accepts a tensor-like object', async () => {
|
101 | const result = tf.argMin([1, 0, 3, 2]);
|
102 | expectArraysEqual(await result.data(), 1);
|
103 | });
|
104 | it('accepts tensor with bool values', async () => {
|
105 | const t = tf.tensor1d([0, 1], 'bool');
|
106 | const result = tf.argMin(t);
|
107 | expect(result.dtype).toBe('int32');
|
108 | expectArraysEqual(await result.data(), 0);
|
109 | });
|
110 | it('has gradient', async () => {
|
111 | const a = tf.tensor2d([3, 2, 5, 100, -7, 2], [2, 3]);
|
112 | const dy = tf.ones([3], 'float32');
|
113 | const da = tf.grad((x) => tf.argMin(x))(a, dy);
|
114 | expect(da.dtype).toBe('float32');
|
115 | expect(da.shape).toEqual([2, 3]);
|
116 | expectArraysClose(await da.data(), [0, 0, 0, 0, 0, 0]);
|
117 | });
|
118 | it('gradient with clones', async () => {
|
119 | const a = tf.tensor2d([3, 2, 5, 100, -7, 2], [2, 3]);
|
120 | const dy = tf.ones([3], 'float32');
|
121 | const da = tf.grad((x) => tf.argMin(x.clone()).clone())(a, dy);
|
122 | expect(da.dtype).toBe('float32');
|
123 | expect(da.shape).toEqual([2, 3]);
|
124 | expectArraysClose(await da.data(), [0, 0, 0, 0, 0, 0]);
|
125 | });
|
126 | it('throws error for string tensor', () => {
|
127 | expect(() => tf.argMin(['a']))
|
128 | .toThrowError(/Argument 'x' passed to 'argMin' must be numeric tensor/);
|
129 | });
|
130 | });
|
131 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJnX21pbl90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvYXJnX21pbl90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFFbEUsT0FBTyxLQUFLLFdBQVcsTUFBTSxlQUFlLENBQUM7QUFFN0MsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDekMsRUFBRSxDQUFDLFVBQVUsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN4QixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6QixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lB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QVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QixpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNoQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckQsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNyQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RCxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsWUFBWSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzFCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTFCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxZQUFZLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDMUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FB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KlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3N9IGZyb20gJy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlLCBleHBlY3RBcnJheXNFcXVhbH0gZnJvbSAnLi4vdGVzdF91dGlsJztcblxuaW1wb3J0ICogYXMgcmVkdWNlX3V0aWwgZnJvbSAnLi9yZWR1Y2VfdXRpbCc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdhcmdtaW4nLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnVGVuc29yMUQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjFkKFsxLCAwLCAzLCAyXSk7XG4gICAgY29uc3QgcmVzdWx0ID0gdGYuYXJnTWluKGEpO1xuICAgIGV4cGVjdEFycmF5c0VxdWFsKGF3YWl0IHJlc3VsdC5kYXRhKCksIDEpO1xuICB9KTtcblxuICBpdCgnb25lIHZhbHVlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IxZChbMTBdKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgcmVzdWx0LmRhdGEoKSwgMCk7XG4gIH0pO1xuXG4gIGl0KCdOID4gdGhhbiBwYXJhbGxlbGl6YXRpb24gdGhyZXNob2xkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG4gPSByZWR1Y2VfdXRpbC5QQVJBTExFTElaRV9USFJFU0hPTEQgKiAyO1xuICAgIGNvbnN0IHZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgIHZhbHVlc1tpXSA9IG4gLSBpO1xuICAgIH1cbiAgICBjb25zdCBhID0gdGYudGVuc29yMWQodmFsdWVzKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCBuIC0gMSk7XG4gIH0pO1xuXG4gIGl0KCc0RCwgTiA+IHRoYW4gcGFyYWxsZWxpemF0aW9uIHRocmVzaG9sZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBuID0gcmVkdWNlX3V0aWwuUEFSQUxMRUxJWkVfVEhSRVNIT0xEICogMjtcbiAgICBjb25zdCB2YWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KG4pO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICB2YWx1ZXNbaV0gPSBuIC0gaTtcbiAgICB9XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjRkKHZhbHVlcywgWzEsIDEsIDEsIG5dKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSwgLTEpO1xuICAgIGV4cGVjdChyZXN1bHQuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgcmVzdWx0LmRhdGEoKSwgbiAtIDEpO1xuICB9KTtcblxuICBpdCgnbWluIGluZGV4IGNvcnJlc3BvbmRzIHRvIHN0YXJ0IG9mIGEgbm9uLWluaXRpYWwgd2luZG93JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG4gPSByZWR1Y2VfdXRpbC5QQVJBTExFTElaRV9USFJFU0hPTEQgKiAyO1xuICAgIGNvbnN0IHdpbmRvd1NpemUgPSByZWR1Y2VfdXRpbC5jb21wdXRlT3B0aW1hbFdpbmRvd1NpemUobik7XG4gICAgY29uc3QgdmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShuKTtcbiAgICBjb25zdCBpbmRleCA9IHdpbmRvd1NpemUgKiAyO1xuICAgIHZhbHVlc1tpbmRleF0gPSAtMTtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMWQodmFsdWVzKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCBpbmRleCk7XG4gIH0pO1xuXG4gIGl0KCdpZ25vcmVzIE5hTnMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjFkKFs1LCAwLCBOYU4sIC0xLCAzXSk7XG4gICAgY29uc3QgcmVzID0gdGYuYXJnTWluKGEpO1xuICAgIGV4cGVjdEFycmF5c0VxdWFsKGF3YWl0IHJlcy5kYXRhKCksIDMpO1xuICB9KTtcblxuICBpdCgnM0QsIGlnbm9yZXMgTmFOcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yM2QoWzUsIDAsIE5hTiwgLTEsIDNdLCBbMSwgMSwgNV0pO1xuICAgIGNvbnN0IHJlcyA9IHRmLmFyZ01pbihhLCAtMSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgcmVzLmRhdGEoKSwgMyk7XG4gIH0pO1xuXG4gIGl0KCcyRCwgbm8gYXhpcyBzcGVjaWZpZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFszLCAtMSwgMCwgMTAwLCAtNywgMl0sIFsyLCAzXSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgdGYuYXJnTWluKGEpLmRhdGEoKSwgWzAsIDEsIDBdKTtcbiAgfSk7XG5cbiAgaXQoJzJELCBheGlzPTAnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFszLCAtMSwgMCwgMTAwLCAtNywgMl0sIFsyLCAzXSk7XG4gICAgY29uc3QgciA9IHRmLmFyZ01pbihhLCAwKTtcblxuICAgIGV4cGVjdChyLnNoYXBlKS50b0VxdWFsKFszXSk7XG4gICAgZXhwZWN0KHIuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgci5kYXRhKCksIFswLCAxLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCcyRCwgYXhpcz0xJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IyZChbMywgMiwgNSwgMTAwLCAtNywgLThdLCBbMiwgM10pO1xuICAgIGNvbnN0IHIgPSB0Zi5hcmdNaW4oYSwgMSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgci5kYXRhKCksIFsxLCAyXSk7XG4gIH0pO1xuXG4gIGl0KCcyRCwgYXhpcyA9IC0xJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IyZChbMywgMiwgNSwgMTAwLCAtNywgLThdLCBbMiwgM10pO1xuICAgIGNvbnN0IHIgPSB0Zi5hcmdNaW4oYSwgLTEpO1xuICAgIGV4cGVjdEFycmF5c0VxdWFsKGF3YWl0IHIuZGF0YSgpLCBbMSwgMl0pO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gcGFzc2VkIGEgbm9uLXRlbnNvcicsICgpID0+IHtcbiAgICBleHBlY3QoKCkgPT4gdGYuYXJnTWluKHt9IGFzIHRmLlRlbnNvcikpXG4gICAgICAgIC50b1Rocm93RXJyb3IoL0FyZ3VtZW50ICd4JyBwYXNzZWQgdG8gJ2FyZ01pbicgbXVzdCBiZSBhIFRlbnNvci8pO1xuICB9KTtcblxuICBpdCgnYWNjZXB0cyBhIHRlbnNvci1saWtlIG9iamVjdCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oWzEsIDAsIDMsIDJdKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCAxKTtcbiAgfSk7XG5cbiAgaXQoJ2FjY2VwdHMgdGVuc29yIHdpdGggYm9vbCB2YWx1ZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdCA9IHRmLnRlbnNvcjFkKFswLCAxXSwgJ2Jvb2wnKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4odCk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCAwKTtcbiAgfSk7XG5cbiAgaXQoJ2hhcyBncmFkaWVudCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMmQoWzMsIDIsIDUsIDEwMCwgLTcsIDJdLCBbMiwgM10pO1xuICAgIGNvbnN0IGR5ID0gdGYub25lcyhbM10sICdmbG9hdDMyJyk7XG4gICAgY29uc3QgZGEgPSB0Zi5ncmFkKCh4OiB0Zi5UZW5zb3IyRCkgPT4gdGYuYXJnTWluKHgpKShhLCBkeSk7XG5cbiAgICBleHBlY3QoZGEuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3QoZGEuc2hhcGUpLnRvRXF1YWwoWzIsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBkYS5kYXRhKCksIFswLCAwLCAwLCAwLCAwLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCdncmFkaWVudCB3aXRoIGNsb25lcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMmQoWzMsIDIsIDUsIDEwMCwgLTcsIDJdLCBbMiwgM10pO1xuICAgIGNvbnN0IGR5ID0gdGYub25lcyhbM10sICdmbG9hdDMyJyk7XG4gICAgY29uc3QgZGEgPSB0Zi5ncmFkKCh4OiB0Zi5UZW5zb3IyRCkgPT4gdGYuYXJnTWluKHguY2xvbmUoKSkuY2xvbmUoKSkoYSwgZHkpO1xuXG4gICAgZXhwZWN0KGRhLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0KGRhLnNoYXBlKS50b0VxdWFsKFsyLCAzXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZGEuZGF0YSgpLCBbMCwgMCwgMCwgMCwgMCwgMF0pO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGVycm9yIGZvciBzdHJpbmcgdGVuc29yJywgKCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PiB0Zi5hcmdNaW4oWydhJ10pKVxuICAgICAgICAudG9UaHJvd0Vycm9yKC9Bcmd1bWVudCAneCcgcGFzc2VkIHRvICdhcmdNaW4nIG11c3QgYmUgbnVtZXJpYyB0ZW5zb3IvKTtcbiAgfSk7XG59KTtcbiJdfQ== |
\ | No newline at end of file |