UNPKG

45 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2018 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 */
17import * as tf from '../index';
18import { ALL_ENVS, describeWithFlags, SYNC_BACKEND_ENVS } from '../jasmine_util';
19import { encodeStrings, expectArraysClose } from '../test_util';
20describeWithFlags('slice ', ALL_ENVS, () => {
21 describeWithFlags('ergonomics', ALL_ENVS, () => {
22 it('slices 2x2x2 array into 2x1x1 no size', async () => {
23 const a = tf.tensor3d([1, 2, 3, 4, 5, 6, 7, 8], [2, 2, 2]);
24 const result = a.slice([0, 1, 1]);
25 expect(result.shape).toEqual([2, 1, 1]);
26 expectArraysClose(await result.data(), [4, 8]);
27 });
28 it('slices 2x2x2 array into 1x2x2 with scalar begin no size', async () => {
29 const a = tf.tensor3d([1, 2, 3, 4, 5, 6, 7, 8], [2, 2, 2]);
30 const result = a.slice(1);
31 expect(result.shape).toEqual([1, 2, 2]);
32 expectArraysClose(await result.data(), [5, 6, 7, 8]);
33 });
34 it('slices 2x2x2 array using 2d size and 2d size', async () => {
35 const a = tf.tensor3d([1, 2, 3, 4, 5, 6, 7, 8], [2, 2, 2]);
36 const result = a.slice([0, 1]);
37 expect(result.shape).toEqual([2, 1, 2]);
38 expectArraysClose(await result.data(), [3, 4, 7, 8]);
39 });
40 it('slices 2x2x2 array using negative size', async () => {
41 const a = tf.tensor3d([1, 2, 3, 4, 5, 6, 7, 8], [2, 2, 2]);
42 const result = a.slice([0, 1], [-1, 1]);
43 expect(result.shape).toEqual([2, 1, 2]);
44 expectArraysClose(await result.data(), [3, 4, 7, 8]);
45 });
46 it('slices 2x2x2 array using 1d size', async () => {
47 const a = tf.tensor3d([1, 2, 3, 4, 5, 6, 7, 8], [2, 2, 2]);
48 const result = a.slice(0, 1);
49 expect(result.shape).toEqual([1, 2, 2]);
50 expectArraysClose(await result.data(), [1, 2, 3, 4]);
51 });
52 it('throws when passed a non-tensor', () => {
53 expect(() => tf.slice({}, 0, 0))
54 .toThrowError(/Argument 'x' passed to 'slice' must be a Tensor/);
55 });
56 it('accepts a tensor-like object', async () => {
57 const a = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]; // 2x2x2
58 const result = tf.slice(a, [0, 1, 1]);
59 expect(result.shape).toEqual([2, 1, 1]);
60 expectArraysClose(await result.data(), [4, 8]);
61 });
62 it('should match source tensor dtype', () => {
63 const a = tf.tensor1d([1, 2, 3, 4, 5], 'int32');
64 const b = a.asType('float32');
65 expect(tf.slice(b, 0).dtype).toEqual('float32');
66 });
67 it('throws when begin is negative', async () => {
68 const a = [[1, 2], [3, 4]]; // 2x2
69 expect(() => tf.slice(a, [-1, 1], [
70 1, 1
71 ])).toThrowError(/slice\(\) does not support negative begin indexing./);
72 });
73 });
74 describeWithFlags('shallow slicing', ALL_ENVS, () => {
75 it('shallow slice an input that was cast', async () => {
76 const a = tf.tensor([[1, 2], [3, 4]], [2, 2], 'int32');
77 const b = a.toFloat();
78 const c = b.slice(1, 1);
79 expect(c.dtype).toBe('float32');
80 expect(c.shape).toEqual([1, 2]);
81 expectArraysClose(await c.data(), [3, 4]);
82 });
83 it('delayed async read of sliced tensor has no mem leak', async () => {
84 const a = tf.zeros([10]);
85 const b = tf.slice(a, 0, 1);
86 const nBefore = tf.memory().numTensors;
87 expect(nBefore).toBe(2);
88 await b.data();
89 const nAfter = tf.memory().numTensors;
90 expect(nAfter).toBe(2);
91 tf.dispose([a, b]);
92 expect(tf.memory().numTensors).toBe(0);
93 });
94 });
95 describeWithFlags('shallow slicing', SYNC_BACKEND_ENVS, () => {
96 it('delayed sync read of sliced tensor has no mem leak', () => {
97 const a = tf.zeros([10]);
98 const b = tf.slice(a, 0, 1);
99 const nBefore = tf.memory().numTensors;
100 expect(nBefore).toBe(2);
101 b.dataSync();
102 const nAfter = tf.memory().numTensors;
103 expect(nAfter).toBe(2);
104 tf.dispose([a, b]);
105 expect(tf.memory().numTensors).toBe(0);
106 });
107 });
108 describeWithFlags('slice5d', ALL_ENVS, () => {
109 it('slices 1x1x1x1x1 into shape 1x1x1x1x1 (effectively a copy)', async () => {
110 const a = tf.tensor5d([[[[[5]]]]], [1, 1, 1, 1, 1]);
111 const result = tf.slice(a, [0, 0, 0, 0, 0], [1, 1, 1, 1, 1]);
112 expect(result.shape).toEqual([1, 1, 1, 1, 1]);
113 expectArraysClose(await result.data(), [5]);
114 });
115 it('slices 2x2x2x2x2 array into 1x2x2x2x2 starting at [1,0,0,0,0]', async () => {
116 const a = tf.tensor5d([
117 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
118 12, 13, 14, 15, 16, 11, 22, 33, 44, 55, 66,
119 77, 88, 111, 222, 333, 444, 555, 666, 777, 888
120 ], [2, 2, 2, 2, 2]);
121 const result = tf.slice(a, [1, 0, 0, 0, 0], [1, 2, 2, 2, 2]);
122 expect(result.shape).toEqual([1, 2, 2, 2, 2]);
123 expectArraysClose(await result.data(), [
124 11, 22, 33, 44, 55, 66, 77, 88, 111, 222, 333, 444, 555, 666, 777,
125 888
126 ]);
127 });
128 it('slices 2x2x2x2x2 array into 2x1x1x1x1 starting at [0,1,1,1,1]', async () => {
129 const a = tf.tensor5d([
130 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
131 12, 13, 14, 15, 16, 11, 22, 33, 44, 55, 66,
132 77, 88, 111, 222, 333, 444, 555, 666, 777, 888
133 ], [2, 2, 2, 2, 2]);
134 const result = tf.slice(a, [0, 1, 1, 1, 1], [2, 1, 1, 1, 1]);
135 expect(result.shape).toEqual([2, 1, 1, 1, 1]);
136 expectArraysClose(await result.data(), [16, 888]);
137 });
138 it('accepts a tensor-like object', async () => {
139 const a = [[[[[5]]]]]; // 1x1x1x1x1
140 const result = tf.slice(a, [0, 0, 0, 0, 0], [1, 1, 1, 1, 1]);
141 expect(result.shape).toEqual([1, 1, 1, 1, 1]);
142 expectArraysClose(await result.data(), [5]);
143 });
144 });
145 describeWithFlags('slice6d', ALL_ENVS, () => {
146 it('slices 1x1x1x1x1x1 into shape 1x1x1x1x1x1 (effectively a copy)', async () => {
147 const a = tf.tensor6d([[[[[[5]]]]]], [1, 1, 1, 1, 1, 1]);
148 const result = tf.slice(a, [0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1]);
149 expect(result.shape).toEqual([1, 1, 1, 1, 1, 1]);
150 expectArraysClose(await result.data(), [5]);
151 });
152 it('slices 2x2x2x2x2x2 array into 1x2x2x2x2x2 starting at [1,0,0,0,0,0]', async () => {
153 const a = tf.tensor6d([
154 31, 32, 33, 34, 35, 36, 37, 38, 39, 310, 311,
155 312, 313, 314, 315, 316, 311, 322, 333, 344, 355, 366,
156 377, 388, 3111, 3222, 3333, 3444, 3555, 3666, 3777, 3888,
157 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
158 12, 13, 14, 15, 16, 11, 22, 33, 44, 55, 66,
159 77, 88, 111, 222, 333, 444, 555, 666, 777, 888
160 ], [2, 2, 2, 2, 2, 2]);
161 const result = tf.slice(a, [1, 0, 0, 0, 0, 0], [1, 2, 2, 2, 2, 2]);
162 expect(result.shape).toEqual([1, 2, 2, 2, 2, 2]);
163 expectArraysClose(await result.data(), [
164 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
165 12, 13, 14, 15, 16, 11, 22, 33, 44, 55, 66,
166 77, 88, 111, 222, 333, 444, 555, 666, 777, 888
167 ]);
168 });
169 it('slices 2x2x2x2x2x2 array into 2x1x1x1x1x1 starting at [0,1,1,1,1,1]', async () => {
170 const a = tf.tensor6d([
171 31, 32, 33, 34, 35, 36, 37, 38, 39, 310, 311,
172 312, 313, 314, 315, 316, 311, 322, 333, 344, 355, 366,
173 377, 388, 3111, 3222, 3333, 3444, 3555, 3666, 3777, 3888,
174 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
175 12, 13, 14, 15, 16, 11, 22, 33, 44, 55, 66,
176 77, 88, 111, 222, 333, 444, 555, 666, 777, 888
177 ], [2, 2, 2, 2, 2, 2]);
178 const result = tf.slice(a, [0, 1, 1, 1, 1, 1], [2, 1, 1, 1, 1, 1]);
179 expect(result.shape).toEqual([2, 1, 1, 1, 1, 1]);
180 expectArraysClose(await result.data(), [3888, 888]);
181 });
182 it('accepts a tensor-like object', async () => {
183 const a = [[[[[[5]]]]]]; // 1x1x1x1x1x1
184 const result = tf.slice(a, [0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1]);
185 expect(result.shape).toEqual([1, 1, 1, 1, 1, 1]);
186 expectArraysClose(await result.data(), [5]);
187 });
188 });
189 describeWithFlags('accepts string', ALL_ENVS, () => {
190 it('slices 2x2x2 array into 2x1x1 no size.', async () => {
191 const a = tf.tensor3d(['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'], [2, 2, 2], 'string');
192 const result = a.slice([0, 1, 1]);
193 expect(result.shape).toEqual([2, 1, 1]);
194 expectArraysClose(await result.data(), ['four', 'eight']);
195 });
196 it('slices 2x2x2 array into 1x2x2 with scalar begin no size.', async () => {
197 const a = tf.tensor3d(['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'], [2, 2, 2]);
198 const result = a.slice(1);
199 expect(result.shape).toEqual([1, 2, 2]);
200 expectArraysClose(await result.data(), ['five', 'six', 'seven', 'eight']);
201 });
202 it('slice encoded string.', async () => {
203 const bytes = encodeStrings([
204 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'
205 ]);
206 const a = tf.tensor3d(bytes, [2, 2, 2], 'string');
207 const result = a.slice([0, 1, 1]);
208 expect(result.shape).toEqual([2, 1, 1]);
209 expectArraysClose(await result.data(), ['four', 'eight']);
210 });
211 });
212});
213//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpY2VfdGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3RmanMtY29yZS9zcmMvb3BzL3NsaWNlX3Rlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDL0IsT0FBTyxFQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQy9FLE9BQU8sRUFBQyxhQUFhLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFHOUQsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDekMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7UUFDN0MsRUFBRSxDQUFDLHVDQUF1QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3JELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0QsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3ZFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0QsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxQixNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOENBQThDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDNUQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzRCxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsaUJBQWlCLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3RELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0QsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsaUJBQWlCLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtDQUFrQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2hELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0Qs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QUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFN0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILGlCQUFpQixDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFO1FBQzFDLEVBQUUsQ0FBQyxnRUFBZ0UsRUFDaEUsS0FBSyxJQUFJLEVBQUU7WUFDVCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6RCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFbkUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakQsaUJBQWlCLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBRU4sRUFBRSxDQUFDLHFFQUFxRSxFQUNyRSxLQUFLLElBQUksRUFBRTtZQUNULE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQ2pCO2dCQUNFLEVBQUUsRUFBRyxFQUFFLEVBQUcsRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksRUFBRSxFQUFJLEdBQUcsRUFBRyxHQUFHO2dCQUM3RCxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRztnQkFDN0QsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSTtnQkFFeEQsQ0FBQyxFQUFJLENBQUMsRUFBSSxDQUFDLEVBQUssQ0FBQyxFQUFLLENBQUMsRUFBSyxDQUFDLEVBQUssQ0FBQyxFQUFLLENBQUMsRUFBSyxDQUFDLEVBQUssRUFBRSxFQUFJLEVBQUU7Z0JBQzVELEVBQUUsRUFBRyxFQUFFLEVBQUcsRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFO2dCQUM1RCxFQUFFLEVBQUcsRUFBRSxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHO2FBQ3hELEVBQ0QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEIsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRW5FLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pELGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNyQyxDQUFDLEVBQUcsQ0FBQyxFQUFHLENBQUMsRUFBSSxDQUFDLEVBQUksQ0FBQyxFQUFJLENBQUMsRUFBSSxDQUFDLEVBQUksQ0FBQyxFQUFJLENBQUMsRUFBSSxFQUFFLEVBQUUsRUFBRTtnQkFDakQsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUcsRUFBRSxFQUFHLEVBQUUsRUFBRyxFQUFFLEVBQUcsRUFBRSxFQUFHLEVBQUUsRUFBRyxFQUFFLEVBQUcsRUFBRSxFQUFFLEVBQUU7Z0JBQ2pELEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUc7YUFDL0MsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFTixFQUFFLENBQUMscUVBQXFFLEVBQ3JFLEtBQUssSUFBSSxFQUFFO1lBQ1QsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FDakI7Z0JBQ0UsRUFBRSxFQUFHLEVBQUUsRUFBRyxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksR0FBRyxFQUFHLEdBQUc7Z0JBQzdELEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHO2dCQUM3RCxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJO2dCQUV4RCxDQUFDLEVBQUksQ0FBQyxFQUFJLENBQUMsRUFBSyxDQUFDLEVBQUssQ0FBQyxFQUFLLENBQUMsRUFBSyxDQUFDLEVBQUssQ0FBQyxFQUFLLENBQUMsRUFBSyxFQUFFLEVBQUksRUFBRTtnQkFDNUQsRUFBRSxFQUFHLEVBQUUsRUFBRyxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUUsRUFBSSxFQUFFLEVBQUksRUFBRSxFQUFJLEVBQUU7Z0JBQzVELEVBQUUsRUFBRyxFQUFFLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUcsRUFBRyxHQUFHLEVBQUcsR0FBRyxFQUFHLEdBQUc7YUFDeEQsRUFDRCxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMs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QUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVCQUF1QixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3JDLE1BQU0sS0FBSyxHQUNQLGFBQWEsQ0FBQztnQkFDWixLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTzthQUMvRCxDQUFpQixDQUFDO1lBQ3ZCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUNsRCxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFncywgU1lOQ19CQUNLRU5EX0VOVlN9IGZyb20gJy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2VuY29kZVN0cmluZ3MsIGV4cGVjdEFycmF5c0Nsb3NlfSBmcm9tICcuLi90ZXN0X3V0aWwnO1xuaW1wb3J0IHtUZW5zb3JMaWtlMUR9IGZyb20gJy4uL3R5cGVzJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ3NsaWNlICcsIEFMTF9FTlZTLCAoKSA9PiB7XG4gIGRlc2NyaWJlV2l0aEZsYWdzKCdlcmdvbm9taWNzJywgQUxMX0VOVlMsICgpID0+IHtcbiAgICBpdCgnc2xpY2VzIDJ4MngyIGFycmF5IGludG8gMngxeDEgbm8gc2l6ZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IzZChbMSwgMiwgMywgNCwgNSwgNiwgNywgOF0sIFsyLCAyLCAyXSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhLnNsaWNlKFswLCAxLCAxXSk7XG4gICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsyLCAxLCAxXSk7XG4gICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbNCwgOF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NsaWNlcyAyeDJ4MiBhcnJheSBpbnRvIDF4MngyIHdpdGggc2NhbGFyIGJlZ2luIG5vIHNpemUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBhID0gdGYudGVuc29yM2QoWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDhdLCBbMiwgMiwgMl0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYS5zbGljZSgxKTtcbiAgICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzEsIDIsIDJdKTtcbiAgICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFs1LCA2LCA3LCA4XSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2xpY2VzIDJ4MngyIGFycmF5IHVzaW5nIDJkIHNpemUgYW5kIDJkIHNpemUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBhID0gdGYudGVuc29yM2QoWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDhdLCBbMiwgMiwgMl0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYS5zbGljZShbMCwgMV0pO1xuICAgICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMiwgMSwgMl0pO1xuICAgICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWzMsIDQsIDcsIDhdKTtcbiAgICB9KTtcblxuICAgIGl0KCdzbGljZXMgMngyeDIgYXJyYXkgdXNpbmcgbmVnYXRpdmUgc2l6ZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IzZChbMSwgMiwgMywgNCwgNSwgNiwgNywgOF0sIFsyLCAyLCAyXSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhLnNsaWNlKFswLCAxXSwgWy0xLCAxXSk7XG4gICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsyLCAxLCAyXSk7XG4gICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbMywgNCwgNywgOF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NsaWNlcyAyeDJ4MiBhcnJheSB1c2luZyAxZCBzaXplJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjNkKFsxLCAyLCAzLCA0LCA1LCA2LCA3LCA4XSwgWzIsIDIsIDJdKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGEuc2xpY2UoMCwgMSk7XG4gICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAyLCAyXSk7XG4gICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbMSwgMiwgMywgNF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIHBhc3NlZCBhIG5vbi10ZW5zb3InLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4gdGYuc2xpY2Uoe30gYXMgdGYuVGVuc29yLCAwLCAwKSlcbiAgICAgICAgICAudG9UaHJvd0Vycm9yKC9Bcmd1bWVudCAneCcgcGFzc2VkIHRvICdzbGljZScgbXVzdCBiZSBhIFRlbnNvci8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FjY2VwdHMgYSB0ZW5zb3ItbGlrZSBvYmplY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBhID0gW1tbMSwgMl0sIFszLCA0XV0sIFtbNSwgNl0sIFs3LCA4XV1dOyAgLy8gMngyeDJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRmLnNsaWNlKGEsIFswLCAxLCAxXSk7XG4gICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsyLCAxLCAxXSk7XG4gICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbNCwgOF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBtYXRjaCBzb3VyY2UgdGVuc29yIGR0eXBlJywgKCkgPT4ge1xuICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzLCA0LCA1XSwgJ2ludDMyJyk7XG4gICAgICBjb25zdCBiID0gYS5hc1R5cGUoJ2Zsb2F0MzInKTtcblxuICAgICAgZXhwZWN0KHRmLnNsaWNlKGIsIDApLmR0eXBlKS50b0VxdWFsKCdmbG9hdDMyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgndGhyb3dzIHdoZW4gYmVnaW4gaXMgbmVnYXRpdmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBhID0gW1sxLCAyXSwgWzMsIDRdXTsgIC8vIDJ4MlxuICAgICAgZXhwZWN0KCgpID0+IHRmLnNsaWNlKGEsIFstMSwgMV0sIFtcbiAgICAgICAgMSwgMVxuICAgICAgXSkpLnRvVGhyb3dFcnJvcigvc2xpY2VcXChcXCkgZG9lcyBub3Qgc3VwcG9ydCBuZWdhdGl2ZSBiZWdpbiBpbmRleGluZy4vKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmVXaXRoRmxhZ3MoJ3NoYWxsb3cgc2xpY2luZycsIEFMTF9FTlZTLCAoKSA9PiB7XG4gICAgaXQoJ3NoYWxsb3cgc2xpY2UgYW4gaW5wdXQgdGhhdCB3YXMgY2FzdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IoW1sxLCAyXSwgWzMsIDRdXSwgWzIsIDJdLCAnaW50MzInKTtcbiAgICAgIGNvbnN0IGIgPSBhLnRvRmxvYXQoKTtcbiAgICAgIGNvbnN0IGMgPSBiLnNsaWNlKDEsIDEpO1xuICAgICAgZXhwZWN0KGMuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICAgIGV4cGVjdChjLnNoYXBlKS50b0VxdWFsKFsxLCAyXSk7XG4gICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBjLmRhdGEoKSwgWzMsIDRdKTtcbiAgICB9KTtcblxuICAgIGl0KCdkZWxheWVkIGFzeW5jIHJlYWQgb2Ygc2xpY2VkIHRlbnNvciBoYXMgbm8gbWVtIGxlYWsnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBhID0gdGYuemVyb3MoWzEwXSk7XG4gICAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgMCwgMSk7XG4gICAgICBjb25zdCBuQmVmb3JlID0gdGYubWVtb3J5KCkubnVtVGVuc29ycztcbiAgICAgIGV4cGVjdChuQmVmb3JlKS50b0JlKDIpO1xuICAgICAgYXdhaXQgYi5kYXRhKCk7XG4gICAgICBjb25zdCBuQWZ0ZXIgPSB0Zi5tZW1vcnkoKS5udW1UZW5zb3JzO1xuICAgICAgZXhwZWN0KG5BZnRlcikudG9CZSgyKTtcbiAgICAgIHRmLmRpc3Bvc2UoW2EsIGJdKTtcbiAgICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZVdpdGhGbGFncygnc2hhbGxvdyBzbGljaW5nJywgU1lOQ19CQUNLRU5EX0VOVlMsICgpID0+IHtcbiAgICBpdCgnZGVsYXllZCBzeW5jIHJlYWQgb2Ygc2xpY2VkIHRlbnNvciBoYXMgbm8gbWVtIGxlYWsnLCAoKSA9PiB7XG4gICAgICBjb25zdCBhID0gdGYuemVyb3MoWzEwXSk7XG4gICAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgMCwgMSk7XG4gICAgICBjb25zdCBuQmVmb3JlID0gdGYubWVtb3J5KCkubnVtVGVuc29ycztcbiAgICAgIGV4cGVjdChuQmVmb3JlKS50b0JlKDIpO1xuICAgICAgYi5kYXRhU3luYygpO1xuICAgICAgY29uc3QgbkFmdGVyID0gdGYubWVtb3J5KCkubnVtVGVuc29ycztcbiAgICAgIGV4cGVjdChuQWZ0ZXIpLnRvQmUoMik7XG4gICAgICB0Zi5kaXNwb3NlKFthLCBiXSk7XG4gICAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgwKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmVXaXRoRmxhZ3MoJ3NsaWNlNWQnLCBBTExfRU5WUywgKCkgPT4ge1xuICAgIGl0KCdzbGljZXMgMXgxeDF4MXgxIGludG8gc2hhcGUgMXgxeDF4MXgxIChlZmZlY3RpdmVseSBhIGNvcHkpJyxcbiAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICBjb25zdCBhID0gdGYudGVuc29yNWQoW1tbW1s1XV1dXV0sIFsxLCAxLCAxLCAxLCAxXSk7XG4gICAgICAgICBjb25zdCByZXN1bHQgPSB0Zi5zbGljZShhLCBbMCwgMCwgMCwgMCwgMF0sIFsxLCAxLCAxLCAxLCAxXSk7XG5cbiAgICAgICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzEsIDEsIDEsIDEsIDFdKTtcbiAgICAgICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFs1XSk7XG4gICAgICAgfSk7XG5cbiAgICBpdCgnc2xpY2VzIDJ4MngyeDJ4MiBhcnJheSBpbnRvIDF4MngyeDJ4MiBzdGFydGluZyBhdCBbMSwwLDAsMCwwXScsXG4gICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjVkKFxuICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgIDEsICAyLCAgMywgICA0LCAgIDUsICAgNiwgICA3LCAgIDgsICAgOSwgICAxMCwgMTEsXG4gICAgICAgICAgICAgICAxMiwgMTMsIDE0LCAgMTUsICAxNiwgIDExLCAgMjIsICAzMywgIDQ0LCAgNTUsIDY2LFxuICAgICAgICAgICAgICAgNzcsIDg4LCAxMTEsIDIyMiwgMzMzLCA0NDQsIDU1NSwgNjY2LCA3NzcsIDg4OFxuICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgWzIsIDIsIDIsIDIsIDJdKTtcbiAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRmLnNsaWNlKGEsIFsxLCAwLCAwLCAwLCAwXSwgWzEsIDIsIDIsIDIsIDJdKTtcblxuICAgICAgICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMiwgMiwgMiwgMl0pO1xuICAgICAgICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgW1xuICAgICAgICAgICAxMSwgMjIsIDMzLCA0NCwgNTUsIDY2LCA3NywgODgsIDExMSwgMjIyLCAzMzMsIDQ0NCwgNTU1LCA2NjYsIDc3NyxcbiAgICAgICAgICAgODg4XG4gICAgICAgICBdKTtcbiAgICAgICB9KTtcblxuICAgIGl0KCdzbGljZXMgMngyeDJ4MngyIGFycmF5IGludG8gMngxeDF4MXgxIHN0YXJ0aW5nIGF0IFswLDEsMSwxLDFdJyxcbiAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICBjb25zdCBhID0gdGYudGVuc29yNWQoXG4gICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgMSwgIDIsICAzLCAgIDQsICAgNSwgICA2LCAgIDcsICAgOCwgICA5LCAgIDEwLCAxMSxcbiAgICAgICAgICAgICAgIDEyLCAxMywgMTQsICAxNSwgIDE2LCAgMTEsICAyMiwgIDMzLCAgNDQsICA1NSwgNjYsXG4gICAgICAgICAgICAgICA3NywgODgsIDExMSwgMjIyLCAzMzMsIDQ0NCwgNTU1LCA2NjYsIDc3NywgODg4XG4gICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICBbMiwgMiwgMiwgMiwgMl0pO1xuICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGYuc2xpY2UoYSwgWzAsIDEsIDEsIDEsIDFdLCBbMiwgMSwgMSwgMSwgMV0pO1xuXG4gICAgICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsyLCAxLCAxLCAxLCAxXSk7XG4gICAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbMTYsIDg4OF0pO1xuICAgICAgIH0pO1xuXG4gICAgaXQoJ2FjY2VwdHMgYSB0ZW5zb3ItbGlrZSBvYmplY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBhID0gW1tbW1s1XV1dXV07ICAvLyAxeDF4MXgxeDFcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRmLnNsaWNlKGEsIFswLCAwLCAwLCAwLCAwXSwgWzEsIDEsIDEsIDEsIDFdKTtcblxuICAgICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMSwgMSwgMSwgMV0pO1xuICAgICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWzVdKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmVXaXRoRmxhZ3MoJ3NsaWNlNmQnLCBBTExfRU5WUywgKCkgPT4ge1xuICAgIGl0KCdzbGljZXMgMXgxeDF4MXgxeDEgaW50byBzaGFwZSAxeDF4MXgxeDF4MSAoZWZmZWN0aXZlbHkgYSBjb3B5KScsXG4gICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjZkKFtbW1tbWzVdXV1dXV0sIFsxLCAxLCAxLCAxLCAxLCAxXSk7XG4gICAgICAgICBjb25zdCByZXN1bHQgPSB0Zi5zbGljZShhLCBbMCwgMCwgMCwgMCwgMCwgMF0sIFsxLCAxLCAxLCAxLCAxLCAxXSk7XG5cbiAgICAgICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzEsIDEsIDEsIDEsIDEsIDFdKTtcbiAgICAgICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFs1XSk7XG4gICAgICAgfSk7XG5cbiAgICBpdCgnc2xpY2VzIDJ4MngyeDJ4MngyIGFycmF5IGludG8gMXgyeDJ4MngyeDIgc3RhcnRpbmcgYXQgWzEsMCwwLDAsMCwwXScsXG4gICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjZkKFxuICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgIDMxLCAgMzIsICAzMywgICAzNCwgICAzNSwgICAzNiwgICAzNywgICAzOCwgICAzOSwgICAzMTAsICAzMTEsXG4gICAgICAgICAgICAgICAzMTIsIDMxMywgMzE0LCAgMzE1LCAgMzE2LCAgMzExLCAgMzIyLCAgMzMzLCAgMzQ0LCAgMzU1LCAgMzY2LFxuICAgICAgICAgICAgICAgMzc3LCAzODgsIDMxMTEsIDMyMjIsIDMzMzMsIDM0NDQsIDM1NTUsIDM2NjYsIDM3NzcsIDM4ODgsXG5cbiAgICAgICAgICAgICAgIDEsICAgMiwgICAzLCAgICA0LCAgICA1LCAgICA2LCAgICA3LCAgICA4LCAgICA5LCAgICAxMCwgICAxMSxcbiAgICAgICAgICAgICAgIDEyLCAgMTMsICAxNCwgICAxNSwgICAxNiwgICAxMSwgICAyMiwgICAzMywgICA0NCwgICA1NSwgICA2NixcbiAgICAgICAgICAgICAgIDc3LCAgODgsICAxMTEsICAyMjIsICAzMzMsICA0NDQsICA1NTUsICA2NjYsICA3NzcsICA4ODhcbiAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgIFsyLCAyLCAyLCAyLCAyLCAyXSk7XG4gICAgICAgICBjb25zdCByZXN1bHQgPSB0Zi5zbGljZShhLCBbMSwgMCwgMCwgMCwgMCwgMF0sIFsxLCAyLCAyLCAyLCAyLCAyXSk7XG5cbiAgICAgICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzEsIDIsIDIsIDIsIDIsIDJdKTtcbiAgICAgICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFtcbiAgICAgICAgICAgMSwgIDIsICAzLCAgIDQsICAgNSwgICA2LCAgIDcsICAgOCwgICA5LCAgIDEwLCAxMSxcbiAgICAgICAgICAgMTIsIDEzLCAxNCwgIDE1LCAgMTYsICAxMSwgIDIyLCAgMzMsICA0NCwgIDU1LCA2NixcbiAgICAgICAgICAgNzcsIDg4LCAxMTEsIDIyMiwgMzMzLCA0NDQsIDU1NSwgNjY2LCA3NzcsIDg4OFxuICAgICAgICAgXSk7XG4gICAgICAgfSk7XG5cbiAgICBpdCgnc2xpY2VzIDJ4MngyeDJ4MngyIGFycmF5IGludG8gMngxeDF4MXgxeDEgc3RhcnRpbmcgYXQgWzAsMSwxLDEsMSwxXScsXG4gICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjZkKFxuICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgIDMxLCAgMzIsICAzMywgICAzNCwgICAzNSwgICAzNiwgICAzNywgICAzOCwgICAzOSwgICAzMTAsICAzMTEsXG4gICAgICAgICAgICAgICAzMTIsIDMxMywgMzE0LCAgMzE1LCAgMzE2LCAgMzExLCAgMzIyLCAgMzMzLCAgMzQ0LCAgMzU1LCAgMzY2LFxuICAgICAgICAgICAgICAgMzc3LCAzODgsIDMxMTEsIDMyMjIsIDMzMzMsIDM0NDQsIDM1NTUsIDM2NjYsIDM3NzcsIDM4ODgsXG5cbiAgICAgICAgICAgICAgIDEsICAgMiwgICAzLCAgICA0LCAgICA1LCAgICA2LCAgICA3LCAgICA4LCAgICA5LCAgICAxMCwgICAxMSxcbiAgICAgICAgICAgICAgIDEyLCAgMTMsICAxNCwgICAxNSwgICAxNiwgICAxMSwgICAyMiwgICAzMywgICA0NCwgICA1NSwgICA2NixcbiAgICAgICAgICAgICAgIDc3LCAgODgsICAxMTEsICAyMjIsICAzMzMsICA0NDQsICA1NTUsICA2NjYsICA3NzcsICA4ODhcbiAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgIFsyLCAyLCAyLCAyLCAyLCAyXSk7XG4gICAgICAgICBjb25zdCByZXN1bHQgPSB0Zi5zbGljZShhLCBbMCwgMSwgMSwgMSwgMSwgMV0sIFsyLCAxLCAxLCAxLCAxLCAxXSk7XG5cbiAgICAgICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzIsIDEsIDEsIDEsIDEsIDFdKTtcbiAgICAgICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFszODg4LCA4ODhdKTtcbiAgICAgICB9KTtcblxuICAgIGl0KCdhY2NlcHRzIGEgdGVuc29yLWxpa2Ugb2JqZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYSA9IFtbW1tbWzVdXV1dXV07ICAvLyAxeDF4MXgxeDF4MVxuICAgICAgY29uc3QgcmVzdWx0ID0gdGYuc2xpY2UoYSwgWzAsIDAsIDAsIDAsIDAsIDBdLCBbMSwgMSwgMSwgMSwgMSwgMV0pO1xuXG4gICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAxLCAxLCAxLCAxLCAxXSk7XG4gICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbNV0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZVdpdGhGbGFncygnYWNjZXB0cyBzdHJpbmcnLCBBTExfRU5WUywgKCkgPT4ge1xuICAgIGl0KCdzbGljZXMgMngyeDIgYXJyYXkgaW50byAyeDF4MSBubyBzaXplLicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IzZChcbiAgICAgICAgICBbJ29uZScsICd0d28nLCAndGhyZWUnLCAnZm91cicsICdmaXZlJywgJ3NpeCcsICdzZXZlbicsICdlaWdodCddLFxuICAgICAgICAgIFsyLCAyLCAyXSwgJ3N0cmluZycpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYS5zbGljZShbMCwgMSwgMV0pO1xuICAgICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMiwgMSwgMV0pO1xuICAgICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWydmb3VyJywgJ2VpZ2h0J10pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NsaWNlcyAyeDJ4MiBhcnJheSBpbnRvIDF4MngyIHdpdGggc2NhbGFyIGJlZ2luIG5vIHNpemUuJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjNkKFxuICAgICAgICAgIFsnb25lJywgJ3R3bycsICd0aHJlZScsICdmb3VyJywgJ2ZpdmUnLCAnc2l4JywgJ3NldmVuJywgJ2VpZ2h0J10sXG4gICAgICAgICAgWzIsIDIsIDJdKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGEuc2xpY2UoMSk7XG4gICAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAyLCAyXSk7XG4gICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbJ2ZpdmUnLCAnc2l4JywgJ3NldmVuJywgJ2VpZ2h0J10pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NsaWNlIGVuY29kZWQgc3RyaW5nLicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ5dGVzID1cbiAgICAgICAgICBlbmNvZGVTdHJpbmdzKFtcbiAgICAgICAgICAgICdvbmUnLCAndHdvJywgJ3RocmVlJywgJ2ZvdXInLCAnZml2ZScsICdzaXgnLCAnc2V2ZW4nLCAnZWlnaHQnXG4gICAgICAgICAgXSkgYXMgVGVuc29yTGlrZTFEO1xuICAgICAgY29uc3QgYSA9IHRmLnRlbnNvcjNkKGJ5dGVzLCBbMiwgMiwgMl0sICdzdHJpbmcnKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGEuc2xpY2UoWzAsIDEsIDFdKTtcbiAgICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzIsIDEsIDFdKTtcbiAgICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsnZm91cicsICdlaWdodCddKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
\No newline at end of file