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('slice2d', ALL_ENVS, () => {
|
21 | it('slicing a 1x1 from a 1x1 returns a 1x1', () => {
|
22 | const a = tf.tensor2d([0], [1, 1]);
|
23 | const b = tf.slice2d(a, [0, 0], [1, 1]);
|
24 | expect(b.shape).toEqual([1, 1]);
|
25 | });
|
26 | it('returns a tensor of slice size', () => {
|
27 | const a = tf.zeros([100, 100]);
|
28 | const b = tf.slice2d(a, [0, 0], [12, 34]);
|
29 | expect(b.shape).toEqual([12, 34]);
|
30 | });
|
31 | it('returns the upper-left submatrix when begin is [0, 0]', async () => {
|
32 | const a = tf.randomUniform([10, 10], -1, 1);
|
33 | const b = tf.slice2d(a, [0, 0], [2, 2]);
|
34 | const aValues = await a.data();
|
35 | expectArraysClose(await b.data(), [aValues[0], aValues[1], aValues[10], aValues[11]]);
|
36 | });
|
37 | it('returns the rectangle specified', async () => {
|
38 | const a = tf.tensor2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [4, 3]);
|
39 | const b = tf.slice2d(a, [1, 1], [3, 2]);
|
40 | expectArraysClose(await b.data(), [5, 6, 8, 9, 11, 12]);
|
41 | });
|
42 | it('throws when requesting out of bounds slice', () => {
|
43 | const a = tf.tensor2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [4, 3]);
|
44 | expect(() => tf.slice2d(a, [1, 1], [10, 10])).toThrowError();
|
45 | });
|
46 | it('grad', async () => {
|
47 | const a = tf.tensor2d([[1, 2, 3], [4, 5, 6]]);
|
48 | const dy = tf.tensor2d([[20], [50]]);
|
49 | const da = tf.grad((x) => tf.slice2d(a, [0, 1], [2, 1]))(a, dy);
|
50 | expect(da.shape).toEqual([2, 3]);
|
51 | expectArraysClose(await da.data(), [0, 20, 0, 0, 50, 0]);
|
52 | });
|
53 | it('accepts a tensor-like object', () => {
|
54 | const a = [[0]]; // 1x1
|
55 | const b = tf.slice2d(a, [0, 0], [1, 1]);
|
56 | expect(b.shape).toEqual([1, 1]);
|
57 | });
|
58 | it('slice an already sliced tensor, first was not continous', async () => {
|
59 | const a = [
|
60 | [1, 2, 3, 4],
|
61 | [5, 6, 7, 8],
|
62 | [9, 10, 11, 12],
|
63 | ]; // 3x4.
|
64 | const b = tf.slice(a, [0, 1]);
|
65 | const c = tf.slice(b, [1, 1], [1, 1]);
|
66 | expect(c.shape).toEqual([1, 1]);
|
67 | expectArraysClose(await c.data(), [7]);
|
68 | });
|
69 | it('slice an already sliced tensor, first was continous', async () => {
|
70 | const a = [
|
71 | [1, 2, 3, 4],
|
72 | [5, 6, 7, 8],
|
73 | [9, 10, 11, 12],
|
74 | ]; // 3x4.
|
75 | const b = tf.slice(a, [1, 0]);
|
76 | const c = tf.slice(b, [1, 0]);
|
77 | expect(c.shape).toEqual([1, 4]);
|
78 | expectArraysClose(await c.data(), [9, 10, 11, 12]);
|
79 | });
|
80 | it('slice an already sliced tensor and do async read', async () => {
|
81 | const a = [
|
82 | [1, 2, 3, 4],
|
83 | [5, 6, 7, 8],
|
84 | [9, 10, 11, 12],
|
85 | ]; // 3x4.
|
86 | const b = tf.slice(a, [0, 1]);
|
87 | const c = tf.slice(b, [1, 1], [1, 1]);
|
88 | expect(c.shape).toEqual([1, 1]);
|
89 | expectArraysClose(await c.data(), new Float32Array([7]));
|
90 | });
|
91 | it('square a sliced texture, followed by non-sliced texture of same shape', async () => {
|
92 | // Make a 2x3 tensor, upload to gpu and reshape to 3x2.
|
93 | const input = tf.tensor([[1, 2, 3], [4, 5, 6]]).abs().as2D(3, 2);
|
94 | const slicedInput = tf.slice(input, [0, 0], [3, 2]);
|
95 | // First square program takes the sliced input.
|
96 | const a = slicedInput.square();
|
97 | expectArraysClose(await a.data(), [1, 4, 9, 16, 25, 36]);
|
98 | // Second square program takes the non-sliced input.
|
99 | const b = tf.square(input);
|
100 | expectArraysClose(await b.data(), [1, 4, 9, 16, 25, 36]);
|
101 | });
|
102 | it('square a non-sliced texture, followed by a sliced texture of same shape', async () => {
|
103 | // Make a 2x3 tensor, upload to gpu and reshape to 3x2.
|
104 | const input = tf.tensor([[1, 2, 3], [4, 5, 6]]).abs().as2D(3, 2);
|
105 | // Make a sliced version of the same tensor with the same shape.
|
106 | const slicedInput = tf.slice(input, [0, 0], [3, 2]);
|
107 | // First square program takes the non-sliced input.
|
108 | const a = input.square();
|
109 | expectArraysClose(await a.data(), [1, 4, 9, 16, 25, 36]);
|
110 | // Second square program takes the sliced input.
|
111 | const b = tf.square(slicedInput);
|
112 | expectArraysClose(await b.data(), [1, 4, 9, 16, 25, 36]);
|
113 | });
|
114 | it('slice a tensor and do async read', async () => {
|
115 | const a = [
|
116 | [1, 2, 3, 4],
|
117 | [5, 6, 7, 8],
|
118 | [9, 10, 11, 12],
|
119 | ]; // 3x4.
|
120 | const b = tf.slice(a, [0, 1], [3, 2]);
|
121 | expect(b.shape).toEqual([3, 2]);
|
122 | const vals = await b.data();
|
123 | expectArraysClose(vals, new Float32Array([2, 3, 6, 7, 10, 11]));
|
124 | });
|
125 | it('flatten a sliced tensor that was continuous in memory', async () => {
|
126 | const a = [
|
127 | [1, 2, 3, 4],
|
128 | [5, 6, 7, 8],
|
129 | [9, 10, 11, 12],
|
130 | ]; // 3x4.
|
131 | const b = tf.slice(a, [1, 0]).flatten();
|
132 | expect(b.shape).toEqual([8]);
|
133 | expectArraysClose(await b.data(), [5, 6, 7, 8, 9, 10, 11, 12]);
|
134 | });
|
135 | it('slice a tensor that was not continuous in memory', async () => {
|
136 | const a = [
|
137 | [1, 2, 3, 4],
|
138 | [5, 6, 7, 8],
|
139 | [9, 10, 11, 12],
|
140 | ]; // 3x4.
|
141 | const b = tf.slice(a, [0, 1]);
|
142 | expect(b.shape).toEqual([3, 3]);
|
143 | expectArraysClose(await b.data(), [2, 3, 4, 6, 7, 8, 10, 11, 12]);
|
144 | });
|
145 | it('flatten a sliced tensor that was not continuous in memory', async () => {
|
146 | const a = [
|
147 | [1, 2, 3, 4],
|
148 | [5, 6, 7, 8],
|
149 | [9, 10, 11, 12],
|
150 | ]; // 3x4.
|
151 | const b = tf.slice(a, [0, 1]).flatten();
|
152 | expect(b.shape).toEqual([9]);
|
153 | expectArraysClose(await b.data(), [2, 3, 4, 6, 7, 8, 10, 11, 12]);
|
154 | });
|
155 | it('flatten a sliced tensor not continuous in memory and run program', async () => {
|
156 | const a = [
|
157 | [1, 2, 3, 4],
|
158 | [5, 6, 7, 8],
|
159 | [9, 10, 11, 12],
|
160 | ]; // 3x4.
|
161 | const b = tf.slice(a, [0, 1]).flatten();
|
162 | const c = tf.square(b);
|
163 | expectArraysClose(await c.data(), [4, 9, 16, 36, 49, 64, 100, 121, 144]);
|
164 | });
|
165 | it('reshape a sliced 1d into a 2d tensor', async () => {
|
166 | const a = [1, 2, 3, 4, 5];
|
167 | const b = tf.slice(a, 1).as2D(2, 2);
|
168 | expect(b.shape).toEqual([2, 2]);
|
169 | expectArraysClose(await b.data(), [2, 3, 4, 5]);
|
170 | });
|
171 | it('reshape a sliced 1d into a 2d tensor and run program', async () => {
|
172 | const a = [1, 2, 3, 4, 5];
|
173 | const b = tf.slice(a, 1).as2D(2, 2).square();
|
174 | expect(b.shape).toEqual([2, 2]);
|
175 | expectArraysClose(await b.data(), [4, 9, 16, 25]);
|
176 | });
|
177 | it('broadcast the original with the sliced tensor', async () => {
|
178 | const a = [[1, 2], [3, 4]];
|
179 | const b = tf.slice(a, [0, 1]);
|
180 | const c = tf.add(a, b);
|
181 | expect(c.shape).toEqual([2, 2]);
|
182 | expectArraysClose(await c.data(), [3, 4, 7, 8]);
|
183 | });
|
184 | it('zero-sized slice out of a non-zero sized tensor', async () => {
|
185 | const a = tf.zeros([4, 2]);
|
186 | const res = tf.slice(a, [0, 0], [0, 2]);
|
187 | expect(res.shape).toEqual([0, 2]);
|
188 | expectArraysClose(await res.data(), []);
|
189 | });
|
190 | it('zero-sized slice out of a zero-sized tensor', async () => {
|
191 | const a = tf.zeros([0, 4]);
|
192 | const res = tf.slice(a, [0, 1], [0, 3]);
|
193 | expect(res.shape).toEqual([0, 3]);
|
194 | expectArraysClose(await res.data(), []);
|
195 | });
|
196 | });
|
197 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpY2UyZF90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvc2xpY2UyZF90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFHL0MsaUJBQWlCLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDMUMsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRTtRQUNoRCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO1FBQ3hDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN4QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDckUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyRCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRS9CLGlCQUFpQixDQUNiLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMvQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFeEMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1FBQ3BELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMvRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sRUFBRSxHQUNKLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFjLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdEUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4QkFBOEIsRUFBRSxHQUFHLEVBQUU7UUFDdEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBRSxNQUFNO1FBQ3hCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx5REFBeUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2RSxNQUFNLENBQUMsR0FBRztZQUNSLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDWixDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztTQUNoQixDQUFDLENBQUUsT0FBTztRQUNYLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxxREFBcUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNuRSxNQUFNLENBQUMsR0FBRztZQUNSLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDWixDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztTQUNoQixDQUFDLENBQUUsT0FBTztRQUNYLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNyRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNoRSxNQUFNLENBQUMsR0FBRztZQUNSLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDWixDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztTQUNoQixDQUFDLENBQUUsT0FBTztRQUNYLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHVFQUF1RSxFQUN2RSxLQUFLLElBQUksRUFBRTtRQUNULHVEQUF1RDtRQUN2RCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqRSxNQUFNLFdBQVcsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BELCtDQUErQztRQUMvQyxNQUFNLENBQUMsR0FBRyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0IsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekQsb0RBQW9EO1FBQ3BELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFFTixFQUFFLENBQUMseUVBQXlFLEVBQ3pFLEtBQUssSUFBSSxFQUFFO1FBQ1QsdURBQXVEO1FBQ3ZELE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLGdFQUFnRTtRQUNoRSxNQUFNLFdBQVcsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BELG1EQUFtRDtRQUNuRCxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDekIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekQsZ0RBQWdEO1FBQ2hELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDakMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFFTixFQUFFLENBQUMsa0NBQWtDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDaEQsTUFBTSxDQUFDLEdBQUc7WUFDUixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNaLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1osQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7U0FDaEIsQ0FBQyxDQUFFLE9BQU87UUFDWCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUIsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDckUsTUFBTSxDQUFDLEdBQUc7WUFDUixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNaLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1osQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7U0FDaEIsQ0FBQyxDQUFFLE9BQU87UUFDWCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ2hFLE1BQU0sQ0FBQyxHQUFHO1lBQ1IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDWixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNaLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1NBQ2hCLENBQUMsQ0FBRSxPQUFPO1FBQ1gsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDJEQUEyRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3pFLE1BQU0sQ0FBQyxHQUFHO1lBQ1IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDWixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNaLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1NBQ2hCLENBQUMsQ0FBRSxPQUFPO1FBQ1gsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN4QyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0IsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsa0VBQWtFLEVBQ2xFLEtBQUssSUFBSSxFQUFFO1FBQ1QsTUFBTSxDQUFDLEdBQUc7WUFDUixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNaLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1osQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7U0FDaEIsQ0FBQyxDQUFFLE9BQU87UUFDWCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDM0UsQ0FBQyxDQUFDLENBQUM7SUFFTixFQUFFLENBQUMsc0NBQXNDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNwRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzdDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3BELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzdELE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlEQUFpRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQy9ELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEMsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNkNBQTZDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDM0QsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMxQyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4uL3Rlc3RfdXRpbCc7XG5pbXBvcnQge1Jhbmt9IGZyb20gJy4uL3R5cGVzJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ3NsaWNlMmQnLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnc2xpY2luZyBhIDF4MSBmcm9tIGEgMXgxIHJldHVybnMgYSAxeDEnLCAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFswXSwgWzEsIDFdKTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UyZChhLCBbMCwgMF0sIFsxLCAxXSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzEsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgYSB0ZW5zb3Igb2Ygc2xpY2Ugc2l6ZScsICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYuemVyb3M8UmFuay5SMj4oWzEwMCwgMTAwXSk7XG4gICAgY29uc3QgYiA9IHRmLnNsaWNlMmQoYSwgWzAsIDBdLCBbMTIsIDM0XSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzEyLCAzNF0pO1xuICB9KTtcblxuICBpdCgncmV0dXJucyB0aGUgdXBwZXItbGVmdCBzdWJtYXRyaXggd2hlbiBiZWdpbiBpcyBbMCwgMF0nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnJhbmRvbVVuaWZvcm08UmFuay5SMj4oWzEwLCAxMF0sIC0xLCAxKTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UyZChhLCBbMCwgMF0sIFsyLCAyXSk7XG4gICAgY29uc3QgYVZhbHVlcyA9IGF3YWl0IGEuZGF0YSgpO1xuXG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IGIuZGF0YSgpLCBbYVZhbHVlc1swXSwgYVZhbHVlc1sxXSwgYVZhbHVlc1sxMF0sIGFWYWx1ZXNbMTFdXSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIHRoZSByZWN0YW5nbGUgc3BlY2lmaWVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IyZChbMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMl0sIFs0LCAzXSk7XG4gICAgY29uc3QgYiA9IHRmLnNsaWNlMmQoYSwgWzEsIDFdLCBbMywgMl0pO1xuXG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFs1LCA2LCA4LCA5LCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIHJlcXVlc3Rpbmcgb3V0IG9mIGJvdW5kcyBzbGljZScsICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMmQoWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTJdLCBbNCwgM10pO1xuICAgIGV4cGVjdCgoKSA9PiB0Zi5zbGljZTJkKGEsIFsxLCAxXSwgWzEwLCAxMF0pKS50b1Rocm93RXJyb3IoKTtcbiAgfSk7XG5cbiAgaXQoJ2dyYWQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFtbMSwgMiwgM10sIFs0LCA1LCA2XV0pO1xuICAgIGNvbnN0IGR5ID0gdGYudGVuc29yMmQoW1syMF0sIFs1MF1dKTtcbiAgICBjb25zdCBkYSA9XG4gICAgICAgIHRmLmdyYWQoKHg6IHRmLlRlbnNvcjJEKSA9PiB0Zi5zbGljZTJkKGEsIFswLCAxXSwgWzIsIDFdKSkoYSwgZHkpO1xuICAgIGV4cGVjdChkYS5zaGFwZSkudG9FcXVhbChbMiwgM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRhLmRhdGEoKSwgWzAsIDIwLCAwLCAwLCA1MCwgMF0pO1xuICB9KTtcblxuICBpdCgnYWNjZXB0cyBhIHRlbnNvci1saWtlIG9iamVjdCcsICgpID0+IHtcbiAgICBjb25zdCBhID0gW1swXV07ICAvLyAxeDFcbiAgICBjb25zdCBiID0gdGYuc2xpY2UyZChhLCBbMCwgMF0sIFsxLCAxXSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzEsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGFuIGFscmVhZHkgc2xpY2VkIHRlbnNvciwgZmlyc3Qgd2FzIG5vdCBjb250aW5vdXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IFtcbiAgICAgIFsxLCAyLCAzLCA0XSxcbiAgICAgIFs1LCA2LCA3LCA4XSxcbiAgICAgIFs5LCAxMCwgMTEsIDEyXSxcbiAgICBdOyAgLy8gM3g0LlxuICAgIGNvbnN0IGIgPSB0Zi5zbGljZShhLCBbMCwgMV0pO1xuICAgIGNvbnN0IGMgPSB0Zi5zbGljZShiLCBbMSwgMV0sIFsxLCAxXSk7XG4gICAgZXhwZWN0KGMuc2hhcGUpLnRvRXF1YWwoWzEsIDFdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBjLmRhdGEoKSwgWzddKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGFuIGFscmVhZHkgc2xpY2VkIHRlbnNvciwgZmlyc3Qgd2FzIGNvbnRpbm91cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFsxLCAwXSk7XG4gICAgY29uc3QgYyA9IHRmLnNsaWNlKGIsIFsxLCAwXSk7XG4gICAgZXhwZWN0KGMuc2hhcGUpLnRvRXF1YWwoWzEsIDRdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBjLmRhdGEoKSwgWzksIDEwLCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGFuIGFscmVhZHkgc2xpY2VkIHRlbnNvciBhbmQgZG8gYXN5bmMgcmVhZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFswLCAxXSk7XG4gICAgY29uc3QgYyA9IHRmLnNsaWNlKGIsIFsxLCAxXSwgWzEsIDFdKTtcbiAgICBleHBlY3QoYy5zaGFwZSkudG9FcXVhbChbMSwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGMuZGF0YSgpLCBuZXcgRmxvYXQzMkFycmF5KFs3XSkpO1xuICB9KTtcblxuICBpdCgnc3F1YXJlIGEgc2xpY2VkIHRleHR1cmUsIGZvbGxvd2VkIGJ5IG5vbi1zbGljZWQgdGV4dHVyZSBvZiBzYW1lIHNoYXBlJyxcbiAgICAgYXN5bmMgKCkgPT4geyAgLy8gVGVzdHMgY29sbGlzaW9ucyBpbiB0aGUgc2hhZGVyIGNhY2hlLlxuICAgICAgIC8vIE1ha2UgYSAyeDMgdGVuc29yLCB1cGxvYWQgdG8gZ3B1IGFuZCByZXNoYXBlIHRvIDN4Mi5cbiAgICAgICBjb25zdCBpbnB1dCA9IHRmLnRlbnNvcihbWzEsIDIsIDNdLCBbNCwgNSwgNl1dKS5hYnMoKS5hczJEKDMsIDIpO1xuICAgICAgIGNvbnN0IHNsaWNlZElucHV0ID0gdGYuc2xpY2UoaW5wdXQsIFswLCAwXSwgWzMsIDJdKTtcbiAgICAgICAvLyBGaXJzdCBzcXVhcmUgcHJvZ3JhbSB0YWtlcyB0aGUgc2xpY2VkIGlucHV0LlxuICAgICAgIGNvbnN0IGEgPSBzbGljZWRJbnB1dC5zcXVhcmUoKTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBhLmRhdGEoKSwgWzEsIDQsIDksIDE2LCAyNSwgMzZdKTtcbiAgICAgICAvLyBTZWNvbmQgc3F1YXJlIHByb2dyYW0gdGFrZXMgdGhlIG5vbi1zbGljZWQgaW5wdXQuXG4gICAgICAgY29uc3QgYiA9IHRmLnNxdWFyZShpbnB1dCk7XG4gICAgICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFsxLCA0LCA5LCAxNiwgMjUsIDM2XSk7XG4gICAgIH0pO1xuXG4gIGl0KCdzcXVhcmUgYSBub24tc2xpY2VkIHRleHR1cmUsIGZvbGxvd2VkIGJ5IGEgc2xpY2VkIHRleHR1cmUgb2Ygc2FtZSBzaGFwZScsXG4gICAgIGFzeW5jICgpID0+IHsgIC8vIFRlc3RzIGNvbGxpc2lvbnMgaW4gdGhlIHNoYWRlciBjYWNoZS5cbiAgICAgICAvLyBNYWtlIGEgMngzIHRlbnNvciwgdXBsb2FkIHRvIGdwdSBhbmQgcmVzaGFwZSB0byAzeDIuXG4gICAgICAgY29uc3QgaW5wdXQgPSB0Zi50ZW5zb3IoW1sxLCAyLCAzXSwgWzQsIDUsIDZdXSkuYWJzKCkuYXMyRCgzLCAyKTtcbiAgICAgICAvLyBNYWtlIGEgc2xpY2VkIHZlcnNpb24gb2YgdGhlIHNhbWUgdGVuc29yIHdpdGggdGhlIHNhbWUgc2hhcGUuXG4gICAgICAgY29uc3Qgc2xpY2VkSW5wdXQgPSB0Zi5zbGljZShpbnB1dCwgWzAsIDBdLCBbMywgMl0pO1xuICAgICAgIC8vIEZpcnN0IHNxdWFyZSBwcm9ncmFtIHRha2VzIHRoZSBub24tc2xpY2VkIGlucHV0LlxuICAgICAgIGNvbnN0IGEgPSBpbnB1dC5zcXVhcmUoKTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBhLmRhdGEoKSwgWzEsIDQsIDksIDE2LCAyNSwgMzZdKTtcbiAgICAgICAvLyBTZWNvbmQgc3F1YXJlIHByb2dyYW0gdGFrZXMgdGhlIHNsaWNlZCBpbnB1dC5cbiAgICAgICBjb25zdCBiID0gdGYuc3F1YXJlKHNsaWNlZElucHV0KTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBiLmRhdGEoKSwgWzEsIDQsIDksIDE2LCAyNSwgMzZdKTtcbiAgICAgfSk7XG5cbiAgaXQoJ3NsaWNlIGEgdGVuc29yIGFuZCBkbyBhc3luYyByZWFkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBbXG4gICAgICBbMSwgMiwgMywgNF0sXG4gICAgICBbNSwgNiwgNywgOF0sXG4gICAgICBbOSwgMTAsIDExLCAxMl0sXG4gICAgXTsgIC8vIDN4NC5cbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzAsIDFdLCBbMywgMl0pO1xuICAgIGV4cGVjdChiLnNoYXBlKS50b0VxdWFsKFszLCAyXSk7XG4gICAgY29uc3QgdmFscyA9IGF3YWl0IGIuZGF0YSgpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKHZhbHMsIG5ldyBGbG9hdDMyQXJyYXkoWzIsIDMsIDYsIDcsIDEwLCAxMV0pKTtcbiAgfSk7XG5cbiAgaXQoJ2ZsYXR0ZW4gYSBzbGljZWQgdGVuc29yIHRoYXQgd2FzIGNvbnRpbnVvdXMgaW4gbWVtb3J5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBbXG4gICAgICBbMSwgMiwgMywgNF0sXG4gICAgICBbNSwgNiwgNywgOF0sXG4gICAgICBbOSwgMTAsIDExLCAxMl0sXG4gICAgXTsgIC8vIDN4NC5cbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzEsIDBdKS5mbGF0dGVuKCk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzhdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBiLmRhdGEoKSwgWzUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGEgdGVuc29yIHRoYXQgd2FzIG5vdCBjb250aW51b3VzIGluIG1lbW9yeScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFswLCAxXSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzMsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBiLmRhdGEoKSwgWzIsIDMsIDQsIDYsIDcsIDgsIDEwLCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ2ZsYXR0ZW4gYSBzbGljZWQgdGVuc29yIHRoYXQgd2FzIG5vdCBjb250aW51b3VzIGluIG1lbW9yeScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFswLCAxXSkuZmxhdHRlbigpO1xuICAgIGV4cGVjdChiLnNoYXBlKS50b0VxdWFsKFs5XSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFsyLCAzLCA0LCA2LCA3LCA4LCAxMCwgMTEsIDEyXSk7XG4gIH0pO1xuXG4gIGl0KCdmbGF0dGVuIGEgc2xpY2VkIHRlbnNvciBub3QgY29udGludW91cyBpbiBtZW1vcnkgYW5kIHJ1biBwcm9ncmFtJyxcbiAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgIGNvbnN0IGEgPSBbXG4gICAgICAgICBbMSwgMiwgMywgNF0sXG4gICAgICAgICBbNSwgNiwgNywgOF0sXG4gICAgICAgICBbOSwgMTAsIDExLCAxMl0sXG4gICAgICAgXTsgIC8vIDN4NC5cbiAgICAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzAsIDFdKS5mbGF0dGVuKCk7XG4gICAgICAgY29uc3QgYyA9IHRmLnNxdWFyZShiKTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBjLmRhdGEoKSwgWzQsIDksIDE2LCAzNiwgNDksIDY0LCAxMDAsIDEyMSwgMTQ0XSk7XG4gICAgIH0pO1xuXG4gIGl0KCdyZXNoYXBlIGEgc2xpY2VkIDFkIGludG8gYSAyZCB0ZW5zb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IFsxLCAyLCAzLCA0LCA1XTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgMSkuYXMyRCgyLCAyKTtcbiAgICBleHBlY3QoYi5zaGFwZSkudG9FcXVhbChbMiwgMl0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGIuZGF0YSgpLCBbMiwgMywgNCwgNV0pO1xuICB9KTtcblxuICBpdCgncmVzaGFwZSBhIHNsaWNlZCAxZCBpbnRvIGEgMmQgdGVuc29yIGFuZCBydW4gcHJvZ3JhbScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gWzEsIDIsIDMsIDQsIDVdO1xuICAgIGNvbnN0IGIgPSB0Zi5zbGljZShhLCAxKS5hczJEKDIsIDIpLnNxdWFyZSgpO1xuICAgIGV4cGVjdChiLnNoYXBlKS50b0VxdWFsKFsyLCAyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFs0LCA5LCAxNiwgMjVdKTtcbiAgfSk7XG5cbiAgaXQoJ2Jyb2FkY2FzdCB0aGUgb3JpZ2luYWwgd2l0aCB0aGUgc2xpY2VkIHRlbnNvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1sxLCAyXSwgWzMsIDRdXTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzAsIDFdKTtcbiAgICBjb25zdCBjID0gdGYuYWRkKGEsIGIpO1xuICAgIGV4cGVjdChjLnNoYXBlKS50b0VxdWFsKFsyLCAyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYy5kYXRhKCksIFszLCA0LCA3LCA4XSk7XG4gIH0pO1xuXG4gIGl0KCd6ZXJvLXNpemVkIHNsaWNlIG91dCBvZiBhIG5vbi16ZXJvIHNpemVkIHRlbnNvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYuemVyb3MoWzQsIDJdKTtcbiAgICBjb25zdCByZXMgPSB0Zi5zbGljZShhLCBbMCwgMF0sIFswLCAyXSk7XG4gICAgZXhwZWN0KHJlcy5zaGFwZSkudG9FcXVhbChbMCwgMl0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlcy5kYXRhKCksIFtdKTtcbiAgfSk7XG5cbiAgaXQoJ3plcm8tc2l6ZWQgc2xpY2Ugb3V0IG9mIGEgemVyby1zaXplZCB0ZW5zb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnplcm9zKFswLCA0XSk7XG4gICAgY29uc3QgcmVzID0gdGYuc2xpY2UoYSwgWzAsIDFdLCBbMCwgM10pO1xuICAgIGV4cGVjdChyZXMuc2hhcGUpLnRvRXF1YWwoWzAsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXMuZGF0YSgpLCBbXSk7XG4gIH0pO1xufSk7XG4iXX0= |
\ | No newline at end of file |