gx
chenyc
2025-02-12 ea42ff3ebee1eeb3fb29423aa848a249441db81c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/**
 * @license
 * Copyright 2021 Google LLC. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =============================================================================
 */
import * as tf from '../index';
import { ALL_ENVS, describeWithFlags } from '../jasmine_util';
import { expectArraysClose } from '../test_util';
import { tensor1d, tensor2d, tensor3d } from './ops';
describeWithFlags('einsum', ALL_ENVS, () => {
    it('two scalars', async () => {
        const x = tf.scalar(2);
        const y = tf.scalar(3);
        const out = tf.einsum(',->', x, y);
        expectArraysClose(await out.data(), 6);
    });
    it('1D tensor and scalars: reduce', async () => {
        const x = tensor1d([2, 3]);
        const y = tf.scalar(4);
        const out = tf.einsum('i,->', x, y);
        expectArraysClose(await out.data(), 20);
    });
    it('1D tensor and scalars: multiply', async () => {
        const x = tensor1d([2, 3]);
        const y = tf.scalar(4);
        const out = tf.einsum('i,->i', x, y);
        expectArraysClose(await out.data(), [8, 12]);
    });
    it('1d reduce sum', async () => {
        const x = tensor1d([2, 4, 6]);
        const out = tf.einsum('i->', x);
        expectArraysClose(await out.data(), 12);
    });
    it('2d matrix reduce sum', async () => {
        const x = tensor2d([[1, 2], [3, 4]]);
        const out = tf.einsum('ij->', x);
        expectArraysClose(await out.data(), 10);
    });
    it('2d matrices multiply and reduce summing', async () => {
        const x = tensor2d([[1, 2], [3, 4]]);
        const y = tensor2d([[4, 3], [2, 1]]);
        const out = tf.einsum('ij,ji->', x, y);
        expectArraysClose(await out.data(), 21);
    });
    it('2d matrix times scalar and reduce summing', async () => {
        const x = tensor2d([[1, 2], [3, 4]]);
        const y = tf.scalar(5);
        const out = tf.einsum('ij,->', x, y);
        expectArraysClose(await out.data(), 50);
    });
    it('two 1d tensors dot', async () => {
        const x = tensor1d([1, 3, 5]);
        const y = tensor1d([2, 4, 6]);
        const out = tf.einsum('i,i->', x, y);
        expectArraysClose(await out.data(), 44);
    });
    it('two 1d tensors outer', async () => {
        const x = tensor1d([1, 3, 5]);
        const y = tensor1d([2, 4, 6]);
        const out = tf.einsum('i,j->ij', x, y);
        expectArraysClose(await out.data(), [[2, 4, 6], [6, 12, 18], [10, 20, 30]]);
    });
    it('2d matrix calculate trace: duplicate axes not implemented yet', () => {
        const x = tensor2d([[1, 2], [3, 4]]);
        expect(() => tf.einsum('ii->', x)).toThrowError(/not implemented yet/);
    });
    it('2d and 1d matrix & vector multiply', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor1d([2, 4, 6]);
        const out = tf.einsum('ij,j->i', x, y);
        expectArraysClose(await out.data(), [28, 64]);
    });
    it('2d matrix sum along columns', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const out = tf.einsum('ij->j', x);
        expectArraysClose(await out.data(), [5, 7, 9]);
    });
    it('2d matrix sum along rows', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const out = tf.einsum('ij->i', x);
        expectArraysClose(await out.data(), [6, 15]);
    });
    it('2d matrix transposing', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const out = tf.einsum('ij->ji', x);
        expectArraysClose(await out.data(), [[1, 4], [2, 5], [3, 6]]);
    });
    it('2d matrix multiply', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor2d([[0, 1], [2, 3], [4, 5]]);
        const out = tf.einsum('ij,jk->ik', x, y);
        expectArraysClose(await out.data(), [[16, 22], [34, 49]]);
    });
    it('2d matrix multiply and transposing', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor2d([[0, 1], [2, 3], [4, 5]]);
        const out = tf.einsum('ij,jk->ki', x, y);
        expectArraysClose(await out.data(), [[16, 34], [22, 49]]);
    });
    it('two 2d matrices batch dot', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor2d([[0, 1, 2], [3, 4, 5]]);
        const out = tf.einsum('bi,bi->b', x, y);
        expectArraysClose(await out.data(), [8, 62]);
    });
    it('two 2d matrices batch outer', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor2d([[0, 1, 2], [3, 4, 5]]);
        const out = tf.einsum('bi,bj->bij', x, y);
        expectArraysClose(await out.data(), [
            [[0, 1, 2], [0, 2, 4], [0, 3, 6]],
            [[12, 16, 20], [15, 20, 25], [18, 24, 30]]
        ]);
    });
    it('two 3d tensors batch matmul', async () => {
        const x = tf.reshape(tf.range(1, 13), [2, 2, 3]);
        const y = tf.reshape(tf.range(1, 19), [2, 3, 3]);
        const out = tf.einsum('bij,bjk->bik', x, y);
        expectArraysClose(await out.data(), [[[30, 36, 42], [66, 81, 96]], [[318, 342, 366], [435, 468, 501]]]);
    });
    it('two 3d tensors A', async () => {
        const x = tf.reshape(tf.range(1, 9), [2, 2, 2]);
        const y = tf.reshape(tf.range(1, 13), [2, 3, 2]);
        const out = tf.einsum('adc,abc->abd', x, y);
        expectArraysClose(await out.data(), [[[5, 11], [11, 25], [17, 39]], [[83, 113], [105, 143], [127, 173]]]);
    });
    it('two 3d tensors B', async () => {
        const x = tf.reshape(tf.range(1, 9), [2, 2, 2]);
        const y = tf.reshape(tf.range(1, 13), [2, 3, 2]);
        const out = tf.einsum('adc,abc->adb', x, y);
        expectArraysClose(await out.data(), [[[5, 11, 17], [11, 25, 39]], [[83, 105, 127], [113, 143, 173]]]);
    });
    it('one 3d tensor: batch matrix transposing', async () => {
        const x = tensor3d([[[1, 2], [3, 4]], [[-1, -2], [-3, -4]]]);
        const out = tf.einsum('bij->bji', x);
        expectArraysClose(await out.data(), [[[1, 3], [2, 4]], [[-1, -3], [-2, -4]]]);
    });
    it('4d tensor and 3d tensor, contracting two dimensions', async () => {
        const x = tf.reshape(tf.range(1, 33), [2, 4, 2, 2]);
        const y = tf.reshape(tf.range(1, 9), [2, 2, 2]);
        const out = tf.einsum('abcd,cde->abe', x, y);
        expectArraysClose(await out.data(), [
            [[50, 60], [114, 140], [178, 220], [242, 300]],
            [[306, 380], [370, 460], [434, 540], [498, 620]]
        ]);
    });
    it('two 4d tensors, contracting one dimension', async () => {
        const x = tf.reshape(tf.range(1, 33), [2, 4, 2, 2]);
        const y = tf.reshape(tf.range(1, 25), [2, 3, 2, 2]);
        const out = tf.einsum('aecd,abcd->acbe', x, y);
        expectArraysClose(await out.data(), [
            [
                [[5, 17, 29, 41], [17, 61, 105, 149], [29, 105, 181, 257]],
                [[25, 53, 81, 109], [53, 113, 173, 233], [81, 173, 265, 357]]
            ],
            [
                [[473, 581, 689, 797], [613, 753, 893, 1033], [753, 925, 1097, 1269]],
                [[605, 729, 853, 977], [761, 917, 1073, 1229], [917, 1105, 1293, 1481]]
            ]
        ]);
    });
    it('two 4d tensors, contracting two dimensions', async () => {
        const x = tf.reshape(tf.range(1, 33), [2, 4, 2, 2]);
        const y = tf.reshape(tf.range(1, 25), [2, 3, 2, 2]);
        const out = tf.einsum('aecd,abcd->abe', x, y);
        expectArraysClose(await out.data(), [
            [[30, 70, 110, 150], [70, 174, 278, 382], [110, 278, 446, 614]],
            [
                [1078, 1310, 1542, 1774], [1374, 1670, 1966, 2262],
                [1670, 2030, 2390, 2750]
            ]
        ]);
    });
    it('mismatched dimensions throws error', () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor2d([[0, 1], [2, 3]]);
        expect(() => tf.einsum('ij,jk->ik', x, y))
            .toThrowError(/dimension 3 at axis 0 of (the )?input shaped \[2,2\]/);
    });
    it('incorrect equation throws error', () => {
        const x = tensor2d([[1, 2], [3, 4]]);
        const y = tensor2d([[0, 1], [2, 3]]);
        expect(() => tf.einsum('', x, y))
            .toThrowError(/Equations without an arrow|Expecting exactly one/);
        expect(() => tf.einsum('ij,jk>ik', x, y))
            .toThrowError(/Equations without an arrow|Expecting exactly one/);
    });
    it('incorrect number of tensors throws error', () => {
        const x = tensor2d([[1, 2], [3, 4]]);
        const y = tensor2d([[0, 1], [2, 3]]);
        expect(() => tf.einsum('ij->ji', x, y))
            .toThrowError(/Expected 1 inputs? (tensors, received)?(but got:)? 2/);
    });
    it('more than two input tensors throws error', async () => {
        const x = tensor2d([[1, 2], [3, 4]]);
        const y = tensor2d([[0, 1], [2, 3]]);
        const z = tensor2d([[-1, 0], [1, 2]]);
        expect(() => tf.einsum('ij,jk,kl->il', x, y, z))
            .toThrowError(/(more than 2 input tensors)|(Expecting 1 or 2 input)/);
    });
    it('nonexistent dimension throws error', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor2d([[0, 1], [2, 3], [4, 5]]);
        expect(() => tf.einsum('ij,jk->in', x, y))
            .toThrowError('Output subscripts contain the label n not present in ' +
            'the input subscripts.');
    });
    it('two arrows in equation throws error', async () => {
        const x = tensor2d([[1, 2, 3], [4, 5, 6]]);
        const y = tensor2d([[0, 1], [2, 3], [4, 5]]);
        expect(() => tf.einsum('ij,jk->ik->i', x, y)).toThrowError(/exactly one/);
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWluc3VtX3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL29wcy9laW5zdW1fdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sY0FBYyxDQUFDO0FBRS9DLE9BQU8sRUFBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQyxNQUFNLE9BQU8sQ0FBQztBQUVuRCxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRTtJQUN6QyxFQUFFLENBQUMsYUFBYSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzNCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbkMsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsK0JBQStCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDN0MsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLEdBQUcs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LENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMEJBQTBCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDeEMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEMsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMvQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNyQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuQyxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNsQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ2xELE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekMsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMkJBQTJCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDekMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDM0MsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0s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QUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHFEQUFxRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ25FLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEQsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzdDLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDOUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztT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LENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUMzQyxZQUFZLENBQUMsc0RBQXNELENBQUMsQ0FBQztJQUM1RSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNsRCxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUNyQyxZQUFZLENBQ1QsdURBQXVEO1lBQ3ZELHVCQUF1QixDQUFDLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMscUNBQXFDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbkQsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDNUUsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3N9IGZyb20gJy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlfSBmcm9tICcuLi90ZXN0X3V0aWwnO1xuXG5pbXBvcnQge3RlbnNvcjFkLCB0ZW5zb3IyZCwgdGVuc29yM2R9IGZyb20gJy4vb3BzJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ2VpbnN1bScsIEFMTF9FTlZTLCAoKSA9PiB7XG4gIGl0KCd0d28gc2NhbGFycycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGYuc2NhbGFyKDIpO1xuICAgIGNvbnN0IHkgPSB0Zi5zY2FsYXIoMyk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCcsLT4nLCB4LCB5KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXQuZGF0YSgpLCA2KTtcbiAgfSk7XG5cbiAgaXQoJzFEIHRlbnNvciBhbmQgc2NhbGFyczogcmVkdWNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0ZW5zb3IxZChbMiwgM10pO1xuICAgIGNvbnN0IHkgPSB0Zi5zY2FsYXIoNCk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpLC0+JywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgMjApO1xuICB9KTtcblxuICBpdCgnMUQgdGVuc29yIGFuZCBzY2FsYXJzOiBtdWx0aXBseScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMWQoWzIsIDNdKTtcbiAgICBjb25zdCB5ID0gdGYuc2NhbGFyKDQpO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnaSwtPmknLCB4LCB5KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXQuZGF0YSgpLCBbOCwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJzFkIHJlZHVjZSBzdW0nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjFkKFsyLCA0LCA2XSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpLT4nLCB4KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXQuZGF0YSgpLCAxMik7XG4gIH0pO1xuXG4gIGl0KCcyZCBtYXRyaXggcmVkdWNlIHN1bScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyXSwgWzMsIDRdXSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpai0+JywgeCk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgMTApO1xuICB9KTtcblxuICBpdCgnMmQgbWF0cmljZXMgbXVsdGlwbHkgYW5kIHJlZHVjZSBzdW1taW5nJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0ZW5zb3IyZChbWzEsIDJdLCBbMywgNF1dKTtcbiAgICBjb25zdCB5ID0gdGVuc29yMmQoW1s0LCAzXSwgWzIsIDFdXSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpaixqaS0+JywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgMjEpO1xuICB9KTtcblxuICBpdCgnMmQgbWF0cml4IHRpbWVzIHNjYWxhciBhbmQgcmVkdWNlIHN1bW1pbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjJkKFtbMSwgMl0sIFszLCA0XV0pO1xuICAgIGNvbnN0IHkgPSB0Zi5zY2FsYXIoNSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpaiwtPicsIHgsIHkpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IG91dC5kYXRhKCksIDUwKTtcbiAgfSk7XG5cbiAgaXQoJ3R3byAxZCB0ZW5zb3JzIGRvdCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMWQoWzEsIDMsIDVdKTtcbiAgICBjb25zdCB5ID0gdGVuc29yMWQoWzIsIDQsIDZdKTtcbiAgICBjb25zdCBvdXQgPSB0Zi5laW5zdW0oJ2ksaS0+JywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgNDQpO1xuICB9KTtcblxuICBpdCgndHdvIDFkIHRlbnNvcnMgb3V0ZXInLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjFkKFsxLCAzLCA1XSk7XG4gICAgY29uc3QgeSA9IHRlbnNvcjFkKFsyLCA0LCA2XSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpLGotPmlqJywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgW1syLCA0LCA2XSwgWzYsIDEyLCAxOF0sIFsxMCwgMjAsIDMwXV0pO1xuICB9KTtcblxuICBpdCgnMmQgbWF0cml4IGNhbGN1bGF0ZSB0cmFjZTogZHVwbGljYXRlIGF4ZXMgbm90IGltcGxlbWVudGVkIHlldCcsICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyXSwgWzMsIDRdXSk7XG4gICAgZXhwZWN0KCgpID0+IHRmLmVpbnN1bSgnaWktPicsIHgpKS50b1Rocm93RXJyb3IoL25vdCBpbXBsZW1lbnRlZCB5ZXQvKTtcbiAgfSk7XG5cbiAgaXQoJzJkIGFuZCAxZCBtYXRyaXggJiB2ZWN0b3IgbXVsdGlwbHknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjJkKFtbMSwgMiwgM10sIFs0LCA1LCA2XV0pO1xuICAgIGNvbnN0IHkgPSB0ZW5zb3IxZChbMiwgNCwgNl0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnaWosai0+aScsIHgsIHkpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IG91dC5kYXRhKCksIFsyOCwgNjRdKTtcbiAgfSk7XG5cbiAgaXQoJzJkIG1hdHJpeCBzdW0gYWxvbmcgY29sdW1ucycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyLCAzXSwgWzQsIDUsIDZdXSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpai0+aicsIHgpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IG91dC5kYXRhKCksIFs1LCA3LCA5XSk7XG4gIH0pO1xuXG4gIGl0KCcyZCBtYXRyaXggc3VtIGFsb25nIHJvd3MnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjJkKFtbMSwgMiwgM10sIFs0LCA1LCA2XV0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnaWotPmknLCB4KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXQuZGF0YSgpLCBbNiwgMTVdKTtcbiAgfSk7XG5cbiAgaXQoJzJkIG1hdHJpeCB0cmFuc3Bvc2luZycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyLCAzXSwgWzQsIDUsIDZdXSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdpai0+amknLCB4KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXQuZGF0YSgpLCBbWzEsIDRdLCBbMiwgNV0sIFszLCA2XV0pO1xuICB9KTtcblxuICBpdCgnMmQgbWF0cml4IG11bHRpcGx5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0ZW5zb3IyZChbWzEsIDIsIDNdLCBbNCwgNSwgNl1dKTtcbiAgICBjb25zdCB5ID0gdGVuc29yMmQoW1swLCAxXSwgWzIsIDNdLCBbNCwgNV1dKTtcbiAgICBjb25zdCBvdXQgPSB0Zi5laW5zdW0oJ2lqLGprLT5paycsIHgsIHkpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IG91dC5kYXRhKCksIFtbMTYsIDIyXSwgWzM0LCA0OV1dKTtcbiAgfSk7XG5cbiAgaXQoJzJkIG1hdHJpeCBtdWx0aXBseSBhbmQgdHJhbnNwb3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjJkKFtbMSwgMiwgM10sIFs0LCA1LCA2XV0pO1xuICAgIGNvbnN0IHkgPSB0ZW5zb3IyZChbWzAsIDFdLCBbMiwgM10sIFs0LCA1XV0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnaWosamstPmtpJywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgW1sxNiwgMzRdLCBbMjIsIDQ5XV0pO1xuICB9KTtcblxuICBpdCgndHdvIDJkIG1hdHJpY2VzIGJhdGNoIGRvdCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyLCAzXSwgWzQsIDUsIDZdXSk7XG4gICAgY29uc3QgeSA9IHRlbnNvcjJkKFtbMCwgMSwgMl0sIFszLCA0LCA1XV0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnYmksYmktPmInLCB4LCB5KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXQuZGF0YSgpLCBbOCwgNjJdKTtcbiAgfSk7XG5cbiAgaXQoJ3R3byAyZCBtYXRyaWNlcyBiYXRjaCBvdXRlcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyLCAzXSwgWzQsIDUsIDZdXSk7XG4gICAgY29uc3QgeSA9IHRlbnNvcjJkKFtbMCwgMSwgMl0sIFszLCA0LCA1XV0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnYmksYmotPmJpaicsIHgsIHkpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IG91dC5kYXRhKCksIFtcbiAgICAgIFtbMCwgMSwgMl0sIFswLCAyLCA0XSwgWzAsIDMsIDZdXSxcbiAgICAgIFtbMTIsIDE2LCAyMF0sIFsxNSwgMjAsIDI1XSwgWzE4LCAyNCwgMzBdXVxuICAgIF0pO1xuICB9KTtcblxuICBpdCgndHdvIDNkIHRlbnNvcnMgYmF0Y2ggbWF0bXVsJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0Zi5yZXNoYXBlKHRmLnJhbmdlKDEsIDEzKSwgWzIsIDIsIDNdKTtcbiAgICBjb25zdCB5ID0gdGYucmVzaGFwZSh0Zi5yYW5nZSgxLCAxOSksIFsyLCAzLCAzXSk7XG4gICAgY29uc3Qgb3V0ID0gdGYuZWluc3VtKCdiaWosYmprLT5iaWsnLCB4LCB5KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShcbiAgICAgICAgYXdhaXQgb3V0LmRhdGEoKSxcbiAgICAgICAgW1tbMzAsIDM2LCA0Ml0sIFs2NiwgODEsIDk2XV0sIFtbMzE4LCAzNDIsIDM2Nl0sIFs0MzUsIDQ2OCwgNTAxXV1dKTtcbiAgfSk7XG5cbiAgaXQoJ3R3byAzZCB0ZW5zb3JzIEEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnJlc2hhcGUodGYucmFuZ2UoMSwgOSksIFsyLCAyLCAyXSk7XG4gICAgY29uc3QgeSA9IHRmLnJlc2hhcGUodGYucmFuZ2UoMSwgMTMpLCBbMiwgMywgMl0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnYWRjLGFiYy0+YWJkJywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IG91dC5kYXRhKCksXG4gICAgICAgIFtbWzUsIDExXSwgWzExLCAyNV0sIFsxNywgMzldXSwgW1s4MywgMTEzXSwgWzEwNSwgMTQzXSwgWzEyNywgMTczXV1dKTtcbiAgfSk7XG5cbiAgaXQoJ3R3byAzZCB0ZW5zb3JzIEInLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnJlc2hhcGUodGYucmFuZ2UoMSwgOSksIFsyLCAyLCAyXSk7XG4gICAgY29uc3QgeSA9IHRmLnJlc2hhcGUodGYucmFuZ2UoMSwgMTMpLCBbMiwgMywgMl0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnYWRjLGFiYy0+YWRiJywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IG91dC5kYXRhKCksXG4gICAgICAgIFtbWzUsIDExLCAxN10sIFsxMSwgMjUsIDM5XV0sIFtbODMsIDEwNSwgMTI3XSwgWzExMywgMTQzLCAxNzNdXV0pO1xuICB9KTtcblxuICBpdCgnb25lIDNkIHRlbnNvcjogYmF0Y2ggbWF0cml4IHRyYW5zcG9zaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0ZW5zb3IzZChbW1sxLCAyXSwgWzMsIDRdXSwgW1stMSwgLTJdLCBbLTMsIC00XV1dKTtcbiAgICBjb25zdCBvdXQgPSB0Zi5laW5zdW0oJ2Jpai0+YmppJywgeCk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IG91dC5kYXRhKCksIFtbWzEsIDNdLCBbMiwgNF1dLCBbWy0xLCAtM10sIFstMiwgLTRdXV0pO1xuICB9KTtcblxuICBpdCgnNGQgdGVuc29yIGFuZCAzZCB0ZW5zb3IsIGNvbnRyYWN0aW5nIHR3byBkaW1lbnNpb25zJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0Zi5yZXNoYXBlKHRmLnJhbmdlKDEsIDMzKSwgWzIsIDQsIDIsIDJdKTtcbiAgICBjb25zdCB5ID0gdGYucmVzaGFwZSh0Zi5yYW5nZSgxLCA5KSwgWzIsIDIsIDJdKTtcbiAgICBjb25zdCBvdXQgPSB0Zi5laW5zdW0oJ2FiY2QsY2RlLT5hYmUnLCB4LCB5KTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXQuZGF0YSgpLCBbXG4gICAgICBbWzUwLCA2MF0sIFsxMTQsIDE0MF0sIFsxNzgsIDIyMF0sIFsyNDIsIDMwMF1dLFxuICAgICAgW1szMDYsIDM4MF0sIFszNzAsIDQ2MF0sIFs0MzQsIDU0MF0sIFs0OTgsIDYyMF1dXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCd0d28gNGQgdGVuc29ycywgY29udHJhY3Rpbmcgb25lIGRpbWVuc2lvbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGYucmVzaGFwZSh0Zi5yYW5nZSgxLCAzMyksIFsyLCA0LCAyLCAyXSk7XG4gICAgY29uc3QgeSA9IHRmLnJlc2hhcGUodGYucmFuZ2UoMSwgMjUpLCBbMiwgMywgMiwgMl0pO1xuICAgIGNvbnN0IG91dCA9IHRmLmVpbnN1bSgnYWVjZCxhYmNkLT5hY2JlJywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgW1xuICAgICAgW1xuICAgICAgICBbWzUsIDE3LCAyOSwgNDFdLCBbMTcsIDYxLCAxMDUsIDE0OV0sIFsyOSwgMTA1LCAxODEsIDI1N11dLFxuICAgICAgICBbWzI1LCA1MywgODEsIDEwOV0sIFs1MywgMTEzLCAxNzMsIDIzM10sIFs4MSwgMTczLCAyNjUsIDM1N11dXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICBbWzQ3MywgNTgxLCA2ODksIDc5N10sIFs2MTMsIDc1MywgODkzLCAxMDMzXSwgWzc1MywgOTI1LCAxMDk3LCAxMjY5XV0sXG4gICAgICAgIFtbNjA1LCA3MjksIDg1MywgOTc3XSwgWzc2MSwgOTE3LCAxMDczLCAxMjI5XSwgWzkxNywgMTEwNSwgMTI5MywgMTQ4MV1dXG4gICAgICBdXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCd0d28gNGQgdGVuc29ycywgY29udHJhY3RpbmcgdHdvIGRpbWVuc2lvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnJlc2hhcGUodGYucmFuZ2UoMSwgMzMpLCBbMiwgNCwgMiwgMl0pO1xuICAgIGNvbnN0IHkgPSB0Zi5yZXNoYXBlKHRmLnJhbmdlKDEsIDI1KSwgWzIsIDMsIDIsIDJdKTtcbiAgICBjb25zdCBvdXQgPSB0Zi5laW5zdW0oJ2FlY2QsYWJjZC0+YWJlJywgeCwgeSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0LmRhdGEoKSwgW1xuICAgICAgW1szMCwgNzAsIDExMCwgMTUwXSwgWzcwLCAxNzQsIDI3OCwgMzgyXSwgWzExMCwgMjc4LCA0NDYsIDYxNF1dLFxuICAgICAgW1xuICAgICAgICBbMTA3OCwgMTMxMCwgMTU0MiwgMTc3NF0sIFsxMzc0LCAxNjcwLCAxOTY2LCAyMjYyXSxcbiAgICAgICAgWzE2NzAsIDIwMzAsIDIzOTAsIDI3NTBdXG4gICAgICBdXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCdtaXNtYXRjaGVkIGRpbWVuc2lvbnMgdGhyb3dzIGVycm9yJywgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0ZW5zb3IyZChbWzEsIDIsIDNdLCBbNCwgNSwgNl1dKTtcbiAgICBjb25zdCB5ID0gdGVuc29yMmQoW1swLCAxXSwgWzIsIDNdXSk7XG4gICAgZXhwZWN0KCgpID0+IHRmLmVpbnN1bSgnaWosamstPmlrJywgeCwgeSkpXG4gICAgICAgIC50b1Rocm93RXJyb3IoL2RpbWVuc2lvbiAzIGF0IGF4aXMgMCBvZiAodGhlICk/aW5wdXQgc2hhcGVkIFxcWzIsMlxcXS8pO1xuICB9KTtcblxuICBpdCgnaW5jb3JyZWN0IGVxdWF0aW9uIHRocm93cyBlcnJvcicsICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyXSwgWzMsIDRdXSk7XG4gICAgY29uc3QgeSA9IHRlbnNvcjJkKFtbMCwgMV0sIFsyLCAzXV0pO1xuICAgIGV4cGVjdCgoKSA9PiB0Zi5laW5zdW0oJycsIHgsIHkpKVxuICAgICAgICAudG9UaHJvd0Vycm9yKC9FcXVhdGlvbnMgd2l0aG91dCBhbiBhcnJvd3xFeHBlY3RpbmcgZXhhY3RseSBvbmUvKTtcbiAgICBleHBlY3QoKCkgPT4gdGYuZWluc3VtKCdpaixqaz5paycsIHgsIHkpKVxuICAgICAgICAudG9UaHJvd0Vycm9yKC9FcXVhdGlvbnMgd2l0aG91dCBhbiBhcnJvd3xFeHBlY3RpbmcgZXhhY3RseSBvbmUvKTtcbiAgfSk7XG5cbiAgaXQoJ2luY29ycmVjdCBudW1iZXIgb2YgdGVuc29ycyB0aHJvd3MgZXJyb3InLCAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjJkKFtbMSwgMl0sIFszLCA0XV0pO1xuICAgIGNvbnN0IHkgPSB0ZW5zb3IyZChbWzAsIDFdLCBbMiwgM11dKTtcbiAgICBleHBlY3QoKCkgPT4gdGYuZWluc3VtKCdpai0+amknLCB4LCB5KSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigvRXhwZWN0ZWQgMSBpbnB1dHM/ICh0ZW5zb3JzLCByZWNlaXZlZCk/KGJ1dCBnb3Q6KT8gMi8pO1xuICB9KTtcblxuICBpdCgnbW9yZSB0aGFuIHR3byBpbnB1dCB0ZW5zb3JzIHRocm93cyBlcnJvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyXSwgWzMsIDRdXSk7XG4gICAgY29uc3QgeSA9IHRlbnNvcjJkKFtbMCwgMV0sIFsyLCAzXV0pO1xuICAgIGNvbnN0IHogPSB0ZW5zb3IyZChbWy0xLCAwXSwgWzEsIDJdXSk7XG4gICAgZXhwZWN0KCgpID0+IHRmLmVpbnN1bSgnaWosamssa2wtPmlsJywgeCwgeSwgeikpXG4gICAgICAgIC50b1Rocm93RXJyb3IoLyhtb3JlIHRoYW4gMiBpbnB1dCB0ZW5zb3JzKXwoRXhwZWN0aW5nIDEgb3IgMiBpbnB1dCkvKTtcbiAgfSk7XG5cbiAgaXQoJ25vbmV4aXN0ZW50IGRpbWVuc2lvbiB0aHJvd3MgZXJyb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRlbnNvcjJkKFtbMSwgMiwgM10sIFs0LCA1LCA2XV0pO1xuICAgIGNvbnN0IHkgPSB0ZW5zb3IyZChbWzAsIDFdLCBbMiwgM10sIFs0LCA1XV0pO1xuICAgIGV4cGVjdCgoKSA9PiB0Zi5laW5zdW0oJ2lqLGprLT5pbicsIHgsIHkpKVxuICAgICAgICAudG9UaHJvd0Vycm9yKFxuICAgICAgICAgICAgJ091dHB1dCBzdWJzY3JpcHRzIGNvbnRhaW4gdGhlIGxhYmVsIG4gbm90IHByZXNlbnQgaW4gJyArXG4gICAgICAgICAgICAndGhlIGlucHV0IHN1YnNjcmlwdHMuJyk7XG4gIH0pO1xuXG4gIGl0KCd0d28gYXJyb3dzIGluIGVxdWF0aW9uIHRocm93cyBlcnJvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGVuc29yMmQoW1sxLCAyLCAzXSwgWzQsIDUsIDZdXSk7XG4gICAgY29uc3QgeSA9IHRlbnNvcjJkKFtbMCwgMV0sIFsyLCAzXSwgWzQsIDVdXSk7XG4gICAgZXhwZWN0KCgpID0+IHRmLmVpbnN1bSgnaWosamstPmlrLT5pJywgeCwgeSkpLnRvVGhyb3dFcnJvcigvZXhhY3RseSBvbmUvKTtcbiAgfSk7XG59KTtcbiJdfQ==