1 | /**
|
2 | * @license
|
3 | * Copyright 2017 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 | import * as axis_util from './axis_util';
|
21 | describe('axis_util combineLocations', () => {
|
22 | it('rank 4, reduce last 2 dims', () => {
|
23 | const loc = axis_util.combineLocations([4, 1], [3, 7], [2, 3]);
|
24 | expect(loc).toEqual([4, 1, 3, 7]);
|
25 | });
|
26 | it('rank 4, reduce first two dims', () => {
|
27 | const loc = axis_util.combineLocations([4, 1], [3, 7], [0, 1]);
|
28 | expect(loc).toEqual([3, 7, 4, 1]);
|
29 | });
|
30 | it('rank 4, reduce 1st and 3rd dims', () => {
|
31 | const loc = axis_util.combineLocations([4, 1], [3, 7], [0, 2]);
|
32 | expect(loc).toEqual([3, 4, 7, 1]);
|
33 | });
|
34 | it('rank 4, reduce 1st and 4th dims', () => {
|
35 | const loc = axis_util.combineLocations([4, 1], [3, 7], [0, 3]);
|
36 | expect(loc).toEqual([3, 4, 1, 7]);
|
37 | });
|
38 | it('rank 3, reduce all dims', () => {
|
39 | const loc = axis_util.combineLocations([], [3, 7, 1], [0, 1, 2]);
|
40 | expect(loc).toEqual([3, 7, 1]);
|
41 | });
|
42 | it('rank 2, reduce last dim', () => {
|
43 | const loc = axis_util.combineLocations([3], [5], [1]);
|
44 | expect(loc).toEqual([3, 5]);
|
45 | });
|
46 | it('rank 2, reduce first dim', () => {
|
47 | const loc = axis_util.combineLocations([3], [5], [0]);
|
48 | expect(loc).toEqual([5, 3]);
|
49 | });
|
50 | });
|
51 | describe('axis_util computeOutAndReduceShapes', () => {
|
52 | it('rank 4, reduce all dims', () => {
|
53 | const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [0, 1, 2, 3]);
|
54 | expect(out).toEqual([]);
|
55 | expect(red).toEqual([3, 7, 2, 4]);
|
56 | });
|
57 | it('rank 4, reduce last 2 dims', () => {
|
58 | const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [2, 3]);
|
59 | expect(out).toEqual([3, 7]);
|
60 | expect(red).toEqual([2, 4]);
|
61 | });
|
62 | it('rank 4, reduce first 2 dims', () => {
|
63 | const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [0, 1]);
|
64 | expect(out).toEqual([2, 4]);
|
65 | expect(red).toEqual([3, 7]);
|
66 | });
|
67 | it('rank 4, reduce last 3 dims', () => {
|
68 | const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [1, 2, 3]);
|
69 | expect(out).toEqual([3]);
|
70 | expect(red).toEqual([7, 2, 4]);
|
71 | });
|
72 | it('rank 4, reduce 1st and 3rd dims', () => {
|
73 | const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [0, 2]);
|
74 | expect(out).toEqual([7, 4]);
|
75 | expect(red).toEqual([3, 2]);
|
76 | });
|
77 | it('rank 3, reduce all dims', () => {
|
78 | const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2], [0, 1, 2]);
|
79 | expect(out).toEqual([]);
|
80 | expect(red).toEqual([3, 7, 2]);
|
81 | });
|
82 | });
|
83 | describe('axis_util axesAreInnerMostDims', () => {
|
84 | it('rank 4, reduce last dim', () => {
|
85 | const res = axis_util.axesAreInnerMostDims([3], 4);
|
86 | expect(res).toBe(true);
|
87 | });
|
88 | it('rank 4, reduce last 2 dims', () => {
|
89 | const res = axis_util.axesAreInnerMostDims([2, 3], 4);
|
90 | expect(res).toBe(true);
|
91 | });
|
92 | it('rank 4, reduce last 3 dims', () => {
|
93 | const res = axis_util.axesAreInnerMostDims([1, 2, 3], 4);
|
94 | expect(res).toBe(true);
|
95 | });
|
96 | it('rank 4, reduce all dims', () => {
|
97 | const res = axis_util.axesAreInnerMostDims([0, 1, 2, 3], 4);
|
98 | expect(res).toBe(true);
|
99 | });
|
100 | it('rank 4, reduce all but 2nd', () => {
|
101 | const res = axis_util.axesAreInnerMostDims([0, 2, 3], 4);
|
102 | expect(res).toBe(false);
|
103 | });
|
104 | it('rank 4, reduce all but 3rd', () => {
|
105 | const res = axis_util.axesAreInnerMostDims([0, 1, 3], 4);
|
106 | expect(res).toBe(false);
|
107 | });
|
108 | it('rank 4, reduce all but last', () => {
|
109 | const res = axis_util.axesAreInnerMostDims([0, 1, 2], 4);
|
110 | expect(res).toBe(false);
|
111 | });
|
112 | });
|
113 | describe('axis_util expandShapeToKeepDim', () => {
|
114 | it('2d -> 1d axis=0', () => {
|
115 | const shape = axis_util.expandShapeToKeepDim([2], [0]);
|
116 | expect(shape).toEqual([1, 2]);
|
117 | });
|
118 | it('2d -> 1d axis=1', () => {
|
119 | const shape = axis_util.expandShapeToKeepDim([4], [1]);
|
120 | expect(shape).toEqual([4, 1]);
|
121 | });
|
122 | it('3d -> 1d axis=1,2', () => {
|
123 | const shape = axis_util.expandShapeToKeepDim([7], [1, 2]);
|
124 | expect(shape).toEqual([7, 1, 1]);
|
125 | });
|
126 | it('3d -> 2d axis=1', () => {
|
127 | const shape = axis_util.expandShapeToKeepDim([7, 3], [1]);
|
128 | expect(shape).toEqual([7, 1, 3]);
|
129 | });
|
130 | });
|
131 | describe('axis_util getPermAxes', () => {
|
132 | it('all axes, no perm is needed', () => {
|
133 | const perm = axis_util.getAxesPermutation([0, 1, 2], 3);
|
134 | expect(perm).toBeNull();
|
135 | });
|
136 | it('no axes, no perm is needed', () => {
|
137 | const perm = axis_util.getAxesPermutation([], 3);
|
138 | expect(perm).toBeNull();
|
139 | });
|
140 | it('inner most 2 axes, no perm is needed', () => {
|
141 | const perm = axis_util.getAxesPermutation([2, 3], 4);
|
142 | expect(perm).toBeNull();
|
143 | });
|
144 | it('outer most axis, perm is needed', () => {
|
145 | const perm = axis_util.getAxesPermutation([0], 4);
|
146 | expect(perm).toEqual([1, 2, 3, 0]);
|
147 | });
|
148 | it('2 outer most axes, perm is needed', () => {
|
149 | const perm = axis_util.getAxesPermutation([0, 1], 4);
|
150 | expect(perm).toEqual([2, 3, 0, 1]);
|
151 | });
|
152 | });
|
153 | describeWithFlags('axis_util getUndoAxesPermutation', ALL_ENVS, () => {
|
154 | it('4d axes', () => {
|
155 | const axes = [2, 0, 1, 3];
|
156 | expect(axis_util.getUndoAxesPermutation(axes)).toEqual([1, 2, 0, 3]);
|
157 | });
|
158 | it('3d axes, no perm', () => {
|
159 | const axes = [0, 1, 2];
|
160 | expect(axis_util.getUndoAxesPermutation(axes)).toEqual([0, 1, 2]);
|
161 | });
|
162 | it('3d axes, complete flip', () => {
|
163 | const axes = [2, 1, 0];
|
164 | expect(axis_util.getUndoAxesPermutation(axes)).toEqual([2, 1, 0]);
|
165 | });
|
166 | it('4d array with values', async () => {
|
167 | const axes = [2, 0, 1, 3];
|
168 | const undoPermutation = axis_util.getUndoAxesPermutation(axes);
|
169 | const a = tf.randomNormal([2, 3, 4, 5]);
|
170 | const aT = tf.transpose(a, axes);
|
171 | const aTT = tf.transpose(aT, undoPermutation);
|
172 | expectArraysClose(await a.data(), await aTT.data());
|
173 | });
|
174 | });
|
175 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXhpc191dGlsX3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL29wcy9heGlzX3V0aWxfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sY0FBYyxDQUFDO0FBRS9DLE9BQU8sS0FBSyxTQUFTLE1BQU0sYUFBYSxDQUFDO0FBRXpDLFFBQVEsQ0FBQyw0QkFBNEIsRUFBRSxHQUFHLEVBQUU7SUFDMUMsRUFBRSxDQUFDLDRCQUE0QixFQUFFLEdBQUcsRUFBRTtRQUNwQyxNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7UUFDdkMsTUFBTSxHQUFHLEdBQUcsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFB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QyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRS9ELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBQzlDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3N9IGZyb20gJy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlfSBmcm9tICcuLi90ZXN0X3V0aWwnO1xuXG5pbXBvcnQgKiBhcyBheGlzX3V0aWwgZnJvbSAnLi9heGlzX3V0aWwnO1xuXG5kZXNjcmliZSgnYXhpc191dGlsIGNvbWJpbmVMb2NhdGlvbnMnLCAoKSA9PiB7XG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBsYXN0IDIgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBsb2MgPSBheGlzX3V0aWwuY29tYmluZUxvY2F0aW9ucyhbNCwgMV0sIFszLCA3XSwgWzIsIDNdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFs0LCAxLCAzLCA3XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBmaXJzdCB0d28gZGltcycsICgpID0+IHtcbiAgICBjb25zdCBsb2MgPSBheGlzX3V0aWwuY29tYmluZUxvY2F0aW9ucyhbNCwgMV0sIFszLCA3XSwgWzAsIDFdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFszLCA3LCA0LCAxXSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSAxc3QgYW5kIDNyZCBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IGxvYyA9IGF4aXNfdXRpbC5jb21iaW5lTG9jYXRpb25zKFs0LCAxXSwgWzMsIDddLCBbMCwgMl0pO1xuICAgIGV4cGVjdChsb2MpLnRvRXF1YWwoWzMsIDQsIDcsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIDFzdCBhbmQgNHRoIGRpbXMnLCAoKSA9PiB7XG4gICAgY29uc3QgbG9jID0gYXhpc191dGlsLmNvbWJpbmVMb2NhdGlvbnMoWzQsIDFdLCBbMywgN10sIFswLCAzXSk7XG4gICAgZXhwZWN0KGxvYykudG9FcXVhbChbMywgNCwgMSwgN10pO1xuICB9KTtcblxuICBpdCgncmFuayAzLCByZWR1Y2UgYWxsIGRpbXMnLCAoKSA9PiB7XG4gICAgY29uc3QgbG9jID0gYXhpc191dGlsLmNvbWJpbmVMb2NhdGlvbnMoW10sIFszLCA3LCAxXSwgWzAsIDEsIDJdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFszLCA3LCAxXSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDIsIHJlZHVjZSBsYXN0IGRpbScsICgpID0+IHtcbiAgICBjb25zdCBsb2MgPSBheGlzX3V0aWwuY29tYmluZUxvY2F0aW9ucyhbM10sIFs1XSwgWzFdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFszLCA1XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDIsIHJlZHVjZSBmaXJzdCBkaW0nLCAoKSA9PiB7XG4gICAgY29uc3QgbG9jID0gYXhpc191dGlsLmNvbWJpbmVMb2NhdGlvbnMoWzNdLCBbNV0sIFswXSk7XG4gICAgZXhwZWN0KGxvYykudG9FcXVhbChbNSwgM10pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXhpc191dGlsIGNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMnLCAoKSA9PiB7XG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBhbGwgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBbb3V0LCByZWRdID1cbiAgICAgICAgYXhpc191dGlsLmNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoWzMsIDcsIDIsIDRdLCBbMCwgMSwgMiwgM10pO1xuICAgIGV4cGVjdChvdXQpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdChyZWQpLnRvRXF1YWwoWzMsIDcsIDIsIDRdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGxhc3QgMiBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IFtvdXQsIHJlZF0gPVxuICAgICAgICBheGlzX3V0aWwuY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhbMywgNywgMiwgNF0sIFsyLCAzXSk7XG4gICAgZXhwZWN0KG91dCkudG9FcXVhbChbMywgN10pO1xuICAgIGV4cGVjdChyZWQpLnRvRXF1YWwoWzIsIDRdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGZpcnN0IDIgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBbb3V0LCByZWRdID1cbiAgICAgICAgYXhpc191dGlsLmNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoWzMsIDcsIDIsIDRdLCBbMCwgMV0pO1xuICAgIGV4cGVjdChvdXQpLnRvRXF1YWwoWzIsIDRdKTtcbiAgICBleHBlY3QocmVkKS50b0VxdWFsKFszLCA3XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBsYXN0IDMgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBbb3V0LCByZWRdID1cbiAgICAgICAgYXhpc191dGlsLmNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoWzMsIDcsIDIsIDRdLCBbMSwgMiwgM10pO1xuICAgIGV4cGVjdChvdXQpLnRvRXF1YWwoWzNdKTtcbiAgICBleHBlY3QocmVkKS50b0VxdWFsKFs3LCAyLCA0XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSAxc3QgYW5kIDNyZCBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IFtvdXQsIHJlZF0gPVxuICAgICAgICBheGlzX3V0aWwuY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhbMywgNywgMiwgNF0sIFswLCAyXSk7XG4gICAgZXhwZWN0KG91dCkudG9FcXVhbChbNywgNF0pO1xuICAgIGV4cGVjdChyZWQpLnRvRXF1YWwoWzMsIDJdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgMywgcmVkdWNlIGFsbCBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IFtvdXQsIHJlZF0gPVxuICAgICAgICBheGlzX3V0aWwuY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhbMywgNywgMl0sIFswLCAxLCAyXSk7XG4gICAgZXhwZWN0KG91dCkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0KHJlZCkudG9FcXVhbChbMywgNywgMl0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXhpc191dGlsIGF4ZXNBcmVJbm5lck1vc3REaW1zJywgKCkgPT4ge1xuICBpdCgncmFuayA0LCByZWR1Y2UgbGFzdCBkaW0nLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFszXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGxhc3QgMiBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF4aXNfdXRpbC5heGVzQXJlSW5uZXJNb3N0RGltcyhbMiwgM10sIDQpO1xuICAgIGV4cGVjdChyZXMpLnRvQmUodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBsYXN0IDMgZGltcycsICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBheGlzX3V0aWwuYXhlc0FyZUlubmVyTW9zdERpbXMoWzEsIDIsIDNdLCA0KTtcbiAgICBleHBlY3QocmVzKS50b0JlKHRydWUpO1xuICB9KTtcblxuICBpdCgncmFuayA0LCByZWR1Y2UgYWxsIGRpbXMnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFswLCAxLCAyLCAzXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGFsbCBidXQgMm5kJywgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF4aXNfdXRpbC5heGVzQXJlSW5uZXJNb3N0RGltcyhbMCwgMiwgM10sIDQpO1xuICAgIGV4cGVjdChyZXMpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdCgncmFuayA0LCByZWR1Y2UgYWxsIGJ1dCAzcmQnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFswLCAxLCAzXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZShmYWxzZSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBhbGwgYnV0IGxhc3QnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFswLCAxLCAyXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZShmYWxzZSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdheGlzX3V0aWwgZXhwYW5kU2hhcGVUb0tlZXBEaW0nLCAoKSA9PiB7XG4gIGl0KCcyZCAtPiAxZCBheGlzPTAnLCAoKSA9PiB7XG4gICAgY29uc3Qgc2hhcGUgPSBheGlzX3V0aWwuZXhwYW5kU2hhcGVUb0tlZXBEaW0oWzJdLCBbMF0pO1xuICAgIGV4cGVjdChzaGFwZSkudG9FcXVhbChbMSwgMl0pO1xuICB9KTtcblxuICBpdCgnMmQgLT4gMWQgYXhpcz0xJywgKCkgPT4ge1xuICAgIGNvbnN0IHNoYXBlID0gYXhpc191dGlsLmV4cGFuZFNoYXBlVG9LZWVwRGltKFs0XSwgWzFdKTtcbiAgICBleHBlY3Qoc2hhcGUpLnRvRXF1YWwoWzQsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJzNkIC0+IDFkIGF4aXM9MSwyJywgKCkgPT4ge1xuICAgIGNvbnN0IHNoYXBlID0gYXhpc191dGlsLmV4cGFuZFNoYXBlVG9LZWVwRGltKFs3XSwgWzEsIDJdKTtcbiAgICBleHBlY3Qoc2hhcGUpLnRvRXF1YWwoWzcsIDEsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJzNkIC0+IDJkIGF4aXM9MScsICgpID0+IHtcbiAgICBjb25zdCBzaGFwZSA9IGF4aXNfdXRpbC5leHBhbmRTaGFwZVRvS2VlcERpbShbNywgM10sIFsxXSk7XG4gICAgZXhwZWN0KHNoYXBlKS50b0VxdWFsKFs3LCAxLCAzXSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdheGlzX3V0aWwgZ2V0UGVybUF4ZXMnLCAoKSA9PiB7XG4gIGl0KCdhbGwgYXhlcywgbm8gcGVybSBpcyBuZWVkZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgcGVybSA9IGF4aXNfdXRpbC5nZXRBeGVzUGVybXV0YXRpb24oWzAsIDEsIDJdLCAzKTtcbiAgICBleHBlY3QocGVybSkudG9CZU51bGwoKTtcbiAgfSk7XG5cbiAgaXQoJ25vIGF4ZXMsIG5vIHBlcm0gaXMgbmVlZGVkJywgKCkgPT4ge1xuICAgIGNvbnN0IHBlcm0gPSBheGlzX3V0aWwuZ2V0QXhlc1Blcm11dGF0aW9uKFtdLCAzKTtcbiAgICBleHBlY3QocGVybSkudG9CZU51bGwoKTtcbiAgfSk7XG5cbiAgaXQoJ2lubmVyIG1vc3QgMiBheGVzLCBubyBwZXJtIGlzIG5lZWRlZCcsICgpID0+IHtcbiAgICBjb25zdCBwZXJtID0gYXhpc191dGlsLmdldEF4ZXNQZXJtdXRhdGlvbihbMiwgM10sIDQpO1xuICAgIGV4cGVjdChwZXJtKS50b0JlTnVsbCgpO1xuICB9KTtcblxuICBpdCgnb3V0ZXIgbW9zdCBheGlzLCBwZXJtIGlzIG5lZWRlZCcsICgpID0+IHtcbiAgICBjb25zdCBwZXJtID0gYXhpc191dGlsLmdldEF4ZXNQZXJtdXRhdGlvbihbMF0sIDQpO1xuICAgIGV4cGVjdChwZXJtKS50b0VxdWFsKFsxLCAyLCAzLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCcyIG91dGVyIG1vc3QgYXhlcywgcGVybSBpcyBuZWVkZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgcGVybSA9IGF4aXNfdXRpbC5nZXRBeGVzUGVybXV0YXRpb24oWzAsIDFdLCA0KTtcbiAgICBleHBlY3QocGVybSkudG9FcXVhbChbMiwgMywgMCwgMV0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZVdpdGhGbGFncygnYXhpc191dGlsIGdldFVuZG9BeGVzUGVybXV0YXRpb24nLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnNGQgYXhlcycsICgpID0+IHtcbiAgICBjb25zdCBheGVzID0gWzIsIDAsIDEsIDNdO1xuICAgIGV4cGVjdChheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKSkudG9FcXVhbChbMSwgMiwgMCwgM10pO1xuICB9KTtcblxuICBpdCgnM2QgYXhlcywgbm8gcGVybScsICgpID0+IHtcbiAgICBjb25zdCBheGVzID0gWzAsIDEsIDJdO1xuICAgIGV4cGVjdChheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKSkudG9FcXVhbChbMCwgMSwgMl0pO1xuICB9KTtcblxuICBpdCgnM2QgYXhlcywgY29tcGxldGUgZmxpcCcsICgpID0+IHtcbiAgICBjb25zdCBheGVzID0gWzIsIDEsIDBdO1xuICAgIGV4cGVjdChheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKSkudG9FcXVhbChbMiwgMSwgMF0pO1xuICB9KTtcblxuICBpdCgnNGQgYXJyYXkgd2l0aCB2YWx1ZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYXhlcyA9IFsyLCAwLCAxLCAzXTtcbiAgICBjb25zdCB1bmRvUGVybXV0YXRpb24gPSBheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKTtcblxuICAgIGNvbnN0IGEgPSB0Zi5yYW5kb21Ob3JtYWwoWzIsIDMsIDQsIDVdKTtcbiAgICBjb25zdCBhVCA9IHRmLnRyYW5zcG9zZShhLCBheGVzKTtcbiAgICBjb25zdCBhVFQgPSB0Zi50cmFuc3Bvc2UoYVQsIHVuZG9QZXJtdXRhdGlvbik7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYS5kYXRhKCksIGF3YWl0IGFUVC5kYXRhKCkpO1xuICB9KTtcbn0pO1xuIl19 |
\ | No newline at end of file |