1 | /**
|
2 | * @license
|
3 | * Copyright 2020 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 } from '../jasmine_util';
|
19 | import { expectArraysClose } from '../test_util';
|
20 | describeWithFlags('dilation2d', ALL_ENVS, () => {
|
21 | it('valid padding.', async () => {
|
22 | const inputShape = [1, 2, 2, 1];
|
23 | const filterShape = [2, 2, 1];
|
24 | const x = tf.tensor4d([.1, .2, .3, .4], inputShape);
|
25 | const filter = tf.tensor3d([.4, .3, .1, .0], filterShape);
|
26 | const result = tf.dilation2d(x, filter, 1 /* strides */, 'valid');
|
27 | expect(result.shape).toEqual([1, 1, 1, 1]);
|
28 | expectArraysClose(await result.data(), [.5]);
|
29 | });
|
30 | it('same padding.', async () => {
|
31 | const inputShape = [1, 2, 2, 1];
|
32 | const filterShape = [2, 2, 1];
|
33 | const x = tf.tensor4d([.1, .2, .3, .4], inputShape);
|
34 | const filter = tf.tensor3d([.4, .3, .1, .0], filterShape);
|
35 | const result = tf.dilation2d(x, filter, 1 /* strides */, 'same');
|
36 | expect(result.shape).toEqual([1, 2, 2, 1]);
|
37 | expectArraysClose(await result.data(), [.5, .6, .7, .8]);
|
38 | });
|
39 | it('same padding depth 3.', async () => {
|
40 | const inputShape = [1, 2, 2, 3];
|
41 | const filterShape = [2, 2, 3];
|
42 | const x = tf.tensor4d([.1, .2, .0, .2, .3, .1, .3, .4, .2, .4, .5, .3], inputShape);
|
43 | const filter = tf.tensor3d([.4, .5, .3, .3, .4, .2, .1, .2, .0, .0, .1, -.1], filterShape);
|
44 | const result = tf.dilation2d(x, filter, 1 /* strides */, 'same');
|
45 | expect(result.shape).toEqual([1, 2, 2, 3]);
|
46 | expectArraysClose(await result.data(), [.5, .7, .3, .6, .8, .4, .7, .9, .5, .8, 1., .6]);
|
47 | });
|
48 | it('same padding batch 2.', async () => {
|
49 | const inputShape = [2, 2, 2, 1];
|
50 | const filterShape = [2, 2, 1];
|
51 | const x = tf.tensor4d([.1, .2, .3, .4, .2, .3, .4, .5], inputShape);
|
52 | const filter = tf.tensor3d([.4, .3, .1, .0], filterShape);
|
53 | const result = tf.dilation2d(x, filter, 1 /* strides */, 'same');
|
54 | expect(result.shape).toEqual([2, 2, 2, 1]);
|
55 | expectArraysClose(await result.data(), [.5, .6, .7, .8, .6, .7, .8, .9]);
|
56 | });
|
57 | it('same padding filter 2.', async () => {
|
58 | const inputShape = [1, 3, 3, 1];
|
59 | const filterShape = [2, 2, 1];
|
60 | const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape);
|
61 | const filter = tf.tensor3d([.4, .3, .1, .2], filterShape);
|
62 | const result = tf.dilation2d(x, filter, 1 /* strides */, 'same');
|
63 | expect(result.shape).toEqual([1, 3, 3, 1]);
|
64 | expectArraysClose(await result.data(), [.7, .8, .7, 1, 1.1, 1, 1.1, 1.2, 1.3]);
|
65 | });
|
66 | it('valid padding non-square-window.', async () => {
|
67 | const inputShape = [1, 2, 2, 1];
|
68 | const filterShape = [1, 2, 1];
|
69 | const x = tf.tensor4d([.1, .2, .3, .4], inputShape);
|
70 | const filter = tf.tensor3d([.4, .3], filterShape);
|
71 | const result = tf.dilation2d(x, filter, 1 /* strides */, 'valid');
|
72 | expect(result.shape).toEqual([1, 2, 1, 1]);
|
73 | expectArraysClose(await result.data(), [.5, .7]);
|
74 | });
|
75 | it('same padding dilations 2.', async () => {
|
76 | const inputShape = [1, 3, 3, 1];
|
77 | const filterShape = [2, 2, 1];
|
78 | const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape);
|
79 | const filter = tf.tensor3d([.4, .3, .1, .2], filterShape);
|
80 | const result = tf.dilation2d(x, filter, 1 /* strides */, 'same', 2);
|
81 | // Because dilations = 2, the effective filter is [3, 3, 1]:
|
82 | // filter_eff = [[[.4], [.0], [.3]],
|
83 | // [[.0], [.0], [.0]],
|
84 | // [[.1], [.0], [.2]]]
|
85 | expect(result.shape).toEqual([1, 3, 3, 1]);
|
86 | expectArraysClose(await result.data(), [.7, .8, .6, 1., 1.1, .9, .8, .9, .9]);
|
87 | });
|
88 | it('valid padding uneven stride.', async () => {
|
89 | const inputShape = [1, 3, 4, 1];
|
90 | const filterShape = [2, 2, 1];
|
91 | const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9, 1., 1.1, 1.2], inputShape);
|
92 | const filter = tf.tensor3d([.4, .3, .1, .2], filterShape);
|
93 | const result = tf.dilation2d(x, filter, [1, 2] /* strides */, 'valid');
|
94 | expect(result.shape).toEqual([1, 2, 2, 1]);
|
95 | expectArraysClose(await result.data(), [.8, 1., 1.2, 1.4]);
|
96 | });
|
97 | it('throws when input rank is not 3 or 4.', async () => {
|
98 | const filterShape = [1, 1, 1];
|
99 | // tslint:disable-next-line:no-any
|
100 | const x = tf.tensor1d([.5]);
|
101 | const filter = tf.tensor3d([.4], filterShape);
|
102 | expect(() => tf.dilation2d(x, filter, 1, 'valid')).toThrowError();
|
103 | });
|
104 | it('thorws when filter is not rank 3.', async () => {
|
105 | const inputShape = [1, 2, 2, 1];
|
106 | const filterShape = [2, 2];
|
107 | const x = tf.tensor4d([.1, .2, .3, .4], inputShape);
|
108 | // tslint:disable-next-line:no-any
|
109 | const filter = tf.tensor2d([.4, .3, .1, .0], filterShape);
|
110 | expect(() => tf.dilation2d(x, filter, 1, 'valid')).toThrowError();
|
111 | });
|
112 | it('throws when data format is not NHWC.', async () => {
|
113 | const inputShape = [1, 2, 2, 1];
|
114 | const filterShape = [2, 2, 1];
|
115 | const x = tf.tensor4d([.1, .2, .3, .4], inputShape);
|
116 | const filter = tf.tensor3d([.4, .3, .1, .0], filterShape);
|
117 | // tslint:disable-next-line:no-any
|
118 | const dataFormat = 'NCHW';
|
119 | expect(() => tf.dilation2d(x, filter, 1 /* strides */, 'valid', 1, dataFormat))
|
120 | .toThrowError();
|
121 | });
|
122 | it('dilation gradient valid padding.', async () => {
|
123 | const inputShape = [1, 3, 3, 1];
|
124 | const filterShape = [1, 1, 1];
|
125 | const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape);
|
126 | const filter = tf.tensor3d([.5], filterShape);
|
127 | const dy = tf.tensor4d([.2, .3, .4, .2, .1, 1., .2, .3, .4], inputShape);
|
128 | const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'valid'));
|
129 | const [dx, dfilter] = grads([x, filter], dy);
|
130 | expect(dx.shape).toEqual(x.shape);
|
131 | expectArraysClose(await dx.data(), [.2, .3, .4, .2, .1, 1., .2, .3, .4]);
|
132 | expect(dfilter.shape).toEqual(filterShape);
|
133 | expectArraysClose(await dfilter.data(), [3.1]);
|
134 | });
|
135 | it('dilation gradient same padding.', async () => {
|
136 | const inputShape = [1, 3, 3, 1];
|
137 | const filterShape = [1, 1, 1];
|
138 | const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape);
|
139 | const filter = tf.tensor3d([.5], filterShape);
|
140 | const dy = tf.tensor4d([.2, .3, .4, .2, .1, 1., .2, .3, .4], inputShape);
|
141 | const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'same'));
|
142 | const [dx, dfilter] = grads([x, filter], dy);
|
143 | expect(dx.shape).toEqual(x.shape);
|
144 | expectArraysClose(await dx.data(), [.2, .3, .4, .2, .1, 1., .2, .3, .4]);
|
145 | expect(dfilter.shape).toEqual(filterShape);
|
146 | expectArraysClose(await dfilter.data(), [3.1]);
|
147 | });
|
148 | it('dilation gradient same padding depth 2.', async () => {
|
149 | const inputShape = [1, 2, 2, 3];
|
150 | const filterShape = [1, 1, 3];
|
151 | const x = tf.tensor4d([.1, .2, .0, .2, .3, .1, .3, .4, .2, .4, .5, .3], inputShape);
|
152 | const filter = tf.tensor3d([.4, .5, .6], filterShape);
|
153 | const dy = tf.tensor4d([.2, .3, .4, .2, .1, 1., .2, .3, .4, .8, -.1, .1], inputShape);
|
154 | const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'same'));
|
155 | const [dx, dfilter] = grads([x, filter], dy);
|
156 | expect(dx.shape).toEqual(x.shape);
|
157 | expectArraysClose(await dx.data(), [.2, .3, .4, .2, .1, 1., .2, .3, .4, .8, -.1, .1]);
|
158 | expect(dfilter.shape).toEqual(filterShape);
|
159 | expectArraysClose(await dfilter.data(), [1.4, .6, 1.9]);
|
160 | });
|
161 | it('dilation gradient valid padding filter 2.', async () => {
|
162 | const inputShape = [1, 3, 3, 1];
|
163 | const filterShape = [2, 2, 1];
|
164 | const dyShape = [1, 2, 2, 1];
|
165 | const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape);
|
166 | const filter = tf.tensor3d([.4, .3, .1, .2], filterShape);
|
167 | const dy = tf.tensor4d([.2, .3, .4, .2], dyShape);
|
168 | const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'valid'));
|
169 | const [dx, dfilter] = grads([x, filter], dy);
|
170 | expect(dx.shape).toEqual(x.shape);
|
171 | expectArraysClose(await dx.data(), [0, 0, 0, 0, .2, .3, 0, .4, .2]);
|
172 | expect(dfilter.shape).toEqual(filterShape);
|
173 | expectArraysClose(await dfilter.data(), [0, 0, 0, 1.1]);
|
174 | });
|
175 | it('dilation gradient same padding filter 2 depth 3.', async () => {
|
176 | const inputShape = [1, 3, 3, 3];
|
177 | const filterShape = [2, 2, 3];
|
178 | const x = tf.tensor4d([
|
179 | .1, .2, .3, .4, .5, .6, .7, .8, .9, .3, .2, .3, .4, .5,
|
180 | .1, .9, .6, .3, .4, .5, .6, .2, .3, .5, .1, .2, .3
|
181 | ], inputShape);
|
182 | const filter = tf.tensor3d([.4, .3, .1, .2, .2, .1, .7, .3, .8, .4, .9, .1], filterShape);
|
183 | const dy = tf.tensor4d([
|
184 | .2, .3, .4, .2, .1, .5, 0, .8, .7, .1, .2, .1, .2, .3,
|
185 | .4, .5, .6, .6, .6, .7, .8, .3, .2, .1, .2, .4, .2
|
186 | ], inputShape);
|
187 | const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'same'));
|
188 | const [dx, dfilter] = grads([x, filter], dy);
|
189 | expect(dx.shape).toEqual(x.shape);
|
190 | expectArraysClose(await dx.data(), [
|
191 | 0, 0, 0, 0, 0, 0, 0, .8, .5, .2, 0, .4, 0, .3,
|
192 | 0, .9, .7, .7, .7, .7, .9, .3, .4, .5, .2, .7, .8
|
193 | ]);
|
194 | expect(dfilter.shape).toEqual(filterShape);
|
195 | expectArraysClose(await dfilter.data(), [1.6, 2.7, 1.1, .2, 0, .5, .3, 0, 2.2, .2, .9, 0]);
|
196 | });
|
197 | });
|
198 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlsYXRpb24yZF90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvZGlsYXRpb24yZF90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFFL0MsaUJBQWlCLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDN0MsRUFBRSxDQUFDLGdCQUFnQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzlCLE1BQU0sVUFBVSxHQUFxQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sV0FBVyxHQUE2QixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDeEQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUUxRCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUVsRSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMs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LEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRTdDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNqQyxDQUFDLEVBQUUsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNwRCxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO1NBQ2xELENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzNDLGlCQUFpQixDQUNiLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxFQUNwQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6RCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4uL3Rlc3RfdXRpbCc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdkaWxhdGlvbjJkJywgQUxMX0VOVlMsICgpID0+IHtcbiAgaXQoJ3ZhbGlkIHBhZGRpbmcuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMF0sIGZpbHRlclNoYXBlKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCAxIC8qIHN0cmlkZXMgKi8sICd2YWxpZCcpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMSwgMSwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNV0pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAyLCAyLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjRdLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zLCAuMSwgLjBdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMiwgMiwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNSwgLjYsIC43LCAuOF0pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nIGRlcHRoIDMuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDNdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgM107XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFxuICAgICAgICBbLjEsIC4yLCAuMCwgLjIsIC4zLCAuMSwgLjMsIC40LCAuMiwgLjQsIC41LCAuM10sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFxuICAgICAgICBbLjQsIC41LCAuMywgLjMsIC40LCAuMiwgLjEsIC4yLCAuMCwgLjAsIC4xLCAtLjFdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMiwgMiwgM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCByZXN1bHQuZGF0YSgpLCBbLjUsIC43LCAuMywgLjYsIC44LCAuNCwgLjcsIC45LCAuNSwgLjgsIDEuLCAuNl0pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nIGJhdGNoIDIuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDIsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNCwgLjIsIC4zLCAuNCwgLjVdLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zLCAuMSwgLjBdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMiwgMiwgMiwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNSwgLjYsIC43LCAuOCwgLjYsIC43LCAuOCwgLjldKTtcbiAgfSk7XG5cbiAgaXQoJ3NhbWUgcGFkZGluZyBmaWx0ZXIgMi4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMywgMywgMV07XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsyLCAyLCAxXTtcbiAgICBjb25zdCB4ID0gdGYudGVuc29yNGQoWy4xLCAuMiwgLjMsIC40LCAuNSwgLjYsIC43LCAuOCwgLjldLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zLCAuMSwgLjJdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMywgMywgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCByZXN1bHQuZGF0YSgpLCBbLjcsIC44LCAuNywgMSwgMS4xLCAxLCAxLjEsIDEuMiwgMS4zXSk7XG4gIH0pO1xuXG4gIGl0KCd2YWxpZCBwYWRkaW5nIG5vbi1zcXVhcmUtd2luZG93LicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAyLCAyLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjRdLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zXSwgZmlsdGVyU2hhcGUpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gdGYuZGlsYXRpb24yZCh4LCBmaWx0ZXIsIDEgLyogc3RyaWRlcyAqLywgJ3ZhbGlkJyk7XG5cbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAyLCAxLCAxXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWy41LCAuN10pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nIGRpbGF0aW9ucyAyLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAzLCAzLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjQsIC41LCAuNiwgLjcsIC44LCAuOV0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMl0sIGZpbHRlclNoYXBlKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCAxIC8qIHN0cmlkZXMgKi8sICdzYW1lJywgMik7XG5cbiAgICAvLyBCZWNhdXNlIGRpbGF0aW9ucyA9IDIsIHRoZSBlZmZlY3RpdmUgZmlsdGVyIGlzIFszLCAzLCAxXTpcbiAgICAvLyBmaWx0ZXJfZWZmID0gW1tbLjRdLCBbLjBdLCBbLjNdXSxcbiAgICAvLyAgICAgICAgICAgICAgIFtbLjBdLCBbLjBdLCBbLjBdXSxcbiAgICAvLyAgICAgICAgICAgICAgIFtbLjFdLCBbLjBdLCBbLjJdXV1cbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAzLCAzLCAxXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNywgLjgsIC42LCAxLiwgMS4xLCAuOSwgLjgsIC45LCAuOV0pO1xuICB9KTtcblxuICBpdCgndmFsaWQgcGFkZGluZyB1bmV2ZW4gc3RyaWRlLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAzLCA0LCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChcbiAgICAgICAgWy4xLCAuMiwgLjMsIC40LCAuNSwgLjYsIC43LCAuOCwgLjksIDEuLCAxLjEsIDEuMl0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMl0sIGZpbHRlclNoYXBlKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCBbMSwgMl0gLyogc3RyaWRlcyAqLywgJ3ZhbGlkJyk7XG5cbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAyLCAyLCAxXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWy44LCAxLiwgMS4yLCAxLjRdKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIGlucHV0IHJhbmsgaXMgbm90IDMgb3IgNC4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAxLCAxXTtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgY29uc3QgeDogYW55ID0gdGYudGVuc29yMWQoWy41XSk7XG4gICAgY29uc3QgZmlsdGVyID0gdGYudGVuc29yM2QoWy40XSwgZmlsdGVyU2hhcGUpO1xuXG4gICAgZXhwZWN0KCgpID0+IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCAxLCAndmFsaWQnKSkudG9UaHJvd0Vycm9yKCk7XG4gIH0pO1xuXG4gIGl0KCd0aG9yd3Mgd2hlbiBmaWx0ZXIgaXMgbm90IHJhbmsgMy4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMiwgMiwgMV07XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlcl0gPSBbMiwgMl07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICBjb25zdCBmaWx0ZXI6IGFueSA9IHRmLnRlbnNvcjJkKFsuNCwgLjMsIC4xLCAuMF0sIGZpbHRlclNoYXBlKTtcblxuICAgIGV4cGVjdCgoKSA9PiB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSwgJ3ZhbGlkJykpLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gZGF0YSBmb3JtYXQgaXMgbm90IE5IV0MuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMF0sIGZpbHRlclNoYXBlKTtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgY29uc3QgZGF0YUZvcm1hdDogYW55ID0gJ05DSFcnO1xuXG4gICAgZXhwZWN0KFxuICAgICAgICAoKSA9PiB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAndmFsaWQnLCAxLCBkYXRhRm9ybWF0KSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgnZGlsYXRpb24gZ3JhZGllbnQgdmFsaWQgcGFkZGluZy4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMywgMywgMV07XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAxLCAxXTtcbiAgICBjb25zdCB4ID0gdGYudGVuc29yNGQoWy4xLCAuMiwgLjMsIC40LCAuNSwgLjYsIC43LCAuOCwgLjldLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjVdLCBmaWx0ZXJTaGFwZSk7XG4gICAgY29uc3QgZHkgPSB0Zi50ZW5zb3I0ZChbLjIsIC4zLCAuNCwgLjIsIC4xLCAxLiwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuXG4gICAgY29uc3QgZ3JhZHMgPSB0Zi5ncmFkcyhcbiAgICAgICAgKHg6IHRmLlRlbnNvcjRELCBmaWx0ZXI6IHRmLlRlbnNvcjNEKSA9PlxuICAgICAgICAgICAgeC5kaWxhdGlvbjJkKGZpbHRlciwgMSwgJ3ZhbGlkJykpO1xuXG4gICAgY29uc3QgW2R4LCBkZmlsdGVyXSA9IGdyYWRzKFt4LCBmaWx0ZXJdLCBkeSk7XG5cbiAgICBleHBlY3QoZHguc2hhcGUpLnRvRXF1YWwoeC5zaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZHguZGF0YSgpLCBbLjIsIC4zLCAuNCwgLjIsIC4xLCAxLiwgLjIsIC4zLCAuNF0pO1xuXG4gICAgZXhwZWN0KGRmaWx0ZXIuc2hhcGUpLnRvRXF1YWwoZmlsdGVyU2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRmaWx0ZXIuZGF0YSgpLCBbMy4xXSk7XG4gIH0pO1xuXG4gIGl0KCdkaWxhdGlvbiBncmFkaWVudCBzYW1lIHBhZGRpbmcuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDMsIDMsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMSwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNCwgLjUsIC42LCAuNywgLjgsIC45XSwgaW5wdXRTaGFwZSk7XG4gICAgY29uc3QgZmlsdGVyID0gdGYudGVuc29yM2QoWy41XSwgZmlsdGVyU2hhcGUpO1xuICAgIGNvbnN0IGR5ID0gdGYudGVuc29yNGQoWy4yLCAuMywgLjQsIC4yLCAuMSwgMS4sIC4yLCAuMywgLjRdLCBpbnB1dFNoYXBlKTtcblxuICAgIGNvbnN0IGdyYWRzID0gdGYuZ3JhZHMoXG4gICAgICAgICh4OiB0Zi5UZW5zb3I0RCwgZmlsdGVyOiB0Zi5UZW5zb3IzRCkgPT5cbiAgICAgICAgICAgIHguZGlsYXRpb24yZChmaWx0ZXIsIDEsICdzYW1lJykpO1xuXG4gICAgY29uc3QgW2R4LCBkZmlsdGVyXSA9IGdyYWRzKFt4LCBmaWx0ZXJdLCBkeSk7XG5cbiAgICBleHBlY3QoZHguc2hhcGUpLnRvRXF1YWwoeC5zaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZHguZGF0YSgpLCBbLjIsIC4zLCAuNCwgLjIsIC4xLCAxLiwgLjIsIC4zLCAuNF0pO1xuXG4gICAgZXhwZWN0KGRmaWx0ZXIuc2hhcGUpLnRvRXF1YWwoZmlsdGVyU2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRmaWx0ZXIuZGF0YSgpLCBbMy4xXSk7XG4gIH0pO1xuXG4gIGl0KCdkaWxhdGlvbiBncmFkaWVudCBzYW1lIHBhZGRpbmcgZGVwdGggMi4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMiwgMiwgM107XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAxLCAzXTtcbiAgICBjb25zdCB4ID0gdGYudGVuc29yNGQoXG4gICAgICAgIFsuMSwgLjIsIC4wLCAuMiwgLjMsIC4xLCAuMywgLjQsIC4yLCAuNCwgLjUsIC4zXSwgaW5wdXRTaGFwZSk7XG4gICAgY29uc3QgZmlsdGVyID0gdGYudGVuc29yM2QoWy40LCAuNSwgLjZdLCBmaWx0ZXJTaGFwZSk7XG4gICAgY29uc3QgZHkgPSB0Zi50ZW5zb3I0ZChcbiAgICAgICAgWy4yLCAuMywgLjQsIC4yLCAuMSwgMS4sIC4yLCAuMywgLjQsIC44LCAtLjEsIC4xXSwgaW5wdXRTaGFwZSk7XG5cbiAgICBjb25zdCBncmFkcyA9IHRmLmdyYWRzKFxuICAgICAgICAoeDogdGYuVGVuc29yNEQsIGZpbHRlcjogdGYuVGVuc29yM0QpID0+XG4gICAgICAgICAgICB4LmRpbGF0aW9uMmQoZmlsdGVyLCAxLCAnc2FtZScpKTtcblxuICAgIGNvbnN0IFtkeCwgZGZpbHRlcl0gPSBncmFkcyhbeCwgZmlsdGVyXSwgZHkpO1xuXG4gICAgZXhwZWN0KGR4LnNoYXBlKS50b0VxdWFsKHguc2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCBkeC5kYXRhKCksIFsuMiwgLjMsIC40LCAuMiwgLjEsIDEuLCAuMiwgLjMsIC40LCAuOCwgLS4xLCAuMV0pO1xuXG4gICAgZXhwZWN0KGRmaWx0ZXIuc2hhcGUpLnRvRXF1YWwoZmlsdGVyU2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRmaWx0ZXIuZGF0YSgpLCBbMS40LCAuNiwgMS45XSk7XG4gIH0pO1xuXG4gIGl0KCdkaWxhdGlvbiBncmFkaWVudCB2YWxpZCBwYWRkaW5nIGZpbHRlciAyLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAzLCAzLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IGR5U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjQsIC41LCAuNiwgLjcsIC44LCAuOV0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMl0sIGZpbHRlclNoYXBlKTtcbiAgICBjb25zdCBkeSA9IHRmLnRlbnNvcjRkKFsuMiwgLjMsIC40LCAuMl0sIGR5U2hhcGUpO1xuXG4gICAgY29uc3QgZ3JhZHMgPSB0Zi5ncmFkcyhcbiAgICAgICAgKHg6IHRmLlRlbnNvcjRELCBmaWx0ZXI6IHRmLlRlbnNvcjNEKSA9PlxuICAgICAgICAgICAgeC5kaWxhdGlvbjJkKGZpbHRlciwgMSwgJ3ZhbGlkJykpO1xuXG4gICAgY29uc3QgW2R4LCBkZmlsdGVyXSA9IGdyYWRzKFt4LCBmaWx0ZXJdLCBkeSk7XG5cbiAgICBleHBlY3QoZHguc2hhcGUpLnRvRXF1YWwoeC5zaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZHguZGF0YSgpLCBbMCwgMCwgMCwgMCwgLjIsIC4zLCAwLCAuNCwgLjJdKTtcblxuICAgIGV4cGVjdChkZmlsdGVyLnNoYXBlKS50b0VxdWFsKGZpbHRlclNoYXBlKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBkZmlsdGVyLmRhdGEoKSwgWzAsIDAsIDAsIDEuMV0pO1xuICB9KTtcblxuICBpdCgnZGlsYXRpb24gZ3JhZGllbnQgc2FtZSBwYWRkaW5nIGZpbHRlciAyIGRlcHRoIDMuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDMsIDMsIDNdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgM107XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFxuICAgICAgICBbXG4gICAgICAgICAgLjEsIC4yLCAuMywgLjQsIC41LCAuNiwgLjcsIC44LCAuOSwgLjMsIC4yLCAuMywgLjQsIC41LFxuICAgICAgICAgIC4xLCAuOSwgLjYsIC4zLCAuNCwgLjUsIC42LCAuMiwgLjMsIC41LCAuMSwgLjIsIC4zXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFxuICAgICAgICBbLjQsIC4zLCAuMSwgLjIsIC4yLCAuMSwgLjcsIC4zLCAuOCwgLjQsIC45LCAuMV0sIGZpbHRlclNoYXBlKTtcbiAgICBjb25zdCBkeSA9IHRmLnRlbnNvcjRkKFxuICAgICAgICBbXG4gICAgICAgICAgLjIsIC4zLCAuNCwgLjIsIC4xLCAuNSwgMCwgIC44LCAuNywgLjEsIC4yLCAuMSwgLjIsIC4zLFxuICAgICAgICAgIC40LCAuNSwgLjYsIC42LCAuNiwgLjcsIC44LCAuMywgLjIsIC4xLCAuMiwgLjQsIC4yXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0U2hhcGUpO1xuXG4gICAgY29uc3QgZ3JhZHMgPSB0Zi5ncmFkcyhcbiAgICAgICAgKHg6IHRmLlRlbnNvcjRELCBmaWx0ZXI6IHRmLlRlbnNvcjNEKSA9PlxuICAgICAgICAgICAgeC5kaWxhdGlvbjJkKGZpbHRlciwgMSwgJ3NhbWUnKSk7XG5cbiAgICBjb25zdCBbZHgsIGRmaWx0ZXJdID0gZ3JhZHMoW3gsIGZpbHRlcl0sIGR5KTtcblxuICAgIGV4cGVjdChkeC5zaGFwZSkudG9FcXVhbCh4LnNoYXBlKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBkeC5kYXRhKCksIFtcbiAgICAgIDAsIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIC44LCAuNSwgLjIsIDAsICAuNCwgMCwgLjMsXG4gICAgICAwLCAuOSwgLjcsIC43LCAuNywgLjcsIC45LCAuMywgLjQsIC41LCAuMiwgLjcsIC44XG4gICAgXSk7XG5cbiAgICBleHBlY3QoZGZpbHRlci5zaGFwZSkudG9FcXVhbChmaWx0ZXJTaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IGRmaWx0ZXIuZGF0YSgpLFxuICAgICAgICBbMS42LCAyLjcsIDEuMSwgLjIsIDAsIC41LCAuMywgMCwgMi4yLCAuMiwgLjksIDBdKTtcbiAgfSk7XG59KTtcbiJdfQ== |
\ | No newline at end of file |