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
| /**
| * @license
| * Copyright 2020 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';
| describeWithFlags('softmaxCrossEntropy', ALL_ENVS, () => {
| it('All wrong', async () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const y = tf.losses.softmaxCrossEntropy(label, predictions);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 20);
| });
| it('All right', async () => {
| const label = tf.tensor2d([[1, 0, 0], [0, 1, 0], [0, 0, 1]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const y = tf.losses.softmaxCrossEntropy(label, predictions);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 0);
| });
| it('Weighted - Reduction.SUM_BY_NONZERO_WEIGHTS', async () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const weights = tf.tensor2d([[0.1, 0.2, 0.3], [0.1, 0.2, 0.3], [0.1, 0.2, 0.3]]);
| const y = tf.losses.softmaxCrossEntropy(label, predictions, weights);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 4);
| });
| it('Weighted - Reduction.NONE', async () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const weights = tf.tensor1d([0.1, 0.2, 0.3]);
| const y = tf.losses.softmaxCrossEntropy(label, predictions, weights, undefined, tf.Reduction.NONE);
| expect(y.shape).toEqual([3]);
| expectArraysClose(await y.data(), [2, 4, 6]);
| });
| it('Reduction.MEAN', async () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const y = tf.losses.softmaxCrossEntropy(label, predictions, undefined, undefined, tf.Reduction.MEAN);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 20);
| });
| it('Weighted - Reduction.MEAN', async () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const weights = tf.tensor1d([0.1, 0.2, 0.3]);
| const y = tf.losses.softmaxCrossEntropy(label, predictions, weights, undefined, tf.Reduction.MEAN);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 20);
| });
| it('Label Smoothing - Weighted - Reduction.MEAN', async () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const weights = tf.tensor2d([[0.1, 0.2, 0.3]]);
| const labelSmoothing = 0.3;
| const y = tf.losses.softmaxCrossEntropy(label, predictions, weights, labelSmoothing, tf.Reduction.MEAN);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 18);
| });
| it('throws when multiClassLabels and logits are of different shapes', () => {
| const multiClassLabels = tf.tensor2d([10, 10, 10, 10, 10, 10, 10, 10, 10], [3, 3]);
| const logits = tf.tensor2d([10, 10, 10, 10, 10, 10], [2, 3]);
| const e = new RegExp('Error in softmaxCrossEntropy: Shapes 3,3 and 2,3 must match');
| expect(() => tf.losses.softmaxCrossEntropy(multiClassLabels, logits))
| .toThrowError(e);
| });
| it('throws when passed multiClassLabels as a non-tensor', () => {
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const weights = tf.tensor2d([[0.1, 0.2, 0.3]]);
| const e = new RegExp('Argument \'onehotLabels\' passed to \'softmaxCrossEntropy\' ' +
| 'must be a Tensor');
| expect(() => tf.losses.softmaxCrossEntropy({}, predictions, weights, tf.Reduction.MEAN))
| .toThrowError(e);
| });
| it('throws when passed logits as a non-tensor', () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const weights = tf.tensor2d([[0.1, 0.2, 0.3]]);
| const e = new RegExp('Argument \'logits\' passed to \'softmaxCrossEntropy\' ' +
| 'must be a Tensor');
| expect(() => tf.losses.softmaxCrossEntropy(label, {}, weights, tf.Reduction.MEAN))
| .toThrowError(e);
| });
| it('throws when passed weights as a non-tensor', () => {
| const label = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
| const predictions = tf.tensor2d([[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]], [3, 3]);
| const e = /Argument 'weights' passed to 'softmaxCrossEntropy' must be a Tensor/;
| expect(() => tf.losses.softmaxCrossEntropy(label, predictions, {}, tf.Reduction.MEAN))
| .toThrowError(e);
| });
| it('accepts a tensor-like object', async () => {
| const label = [[0, 0, 1], [1, 0, 0], [0, 1, 0]];
| const predictions = [[10.0, -10.0, -10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, 10.0]];
| const y = tf.losses.softmaxCrossEntropy(label, predictions);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 20);
| });
| });
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29mdG1heF9jcm9zc19lbnRyb3B5X3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL29wcy9sb3NzZXMvc29mdG1heF9jcm9zc19lbnRyb3B5X3Rlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxFQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQy9ELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBRWxELGlCQUFpQixDQUFDLHFCQUFxQixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDdEQsRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6QixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQzNCLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFDbEUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVaLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRTVELE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3hDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6QixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQzNCLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFDbEUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVaLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRTVELE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENB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V0FBVyxDQUFDLENBQUM7UUFFNUQsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDNUIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDeEMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vLi4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3N9IGZyb20gJy4uLy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlfSBmcm9tICcuLi8uLi90ZXN0X3V0aWwnO1xuXG5kZXNjcmliZVdpdGhGbGFncygnc29mdG1heENyb3NzRW50cm9weScsIEFMTF9FTlZTLCAoKSA9PiB7XG4gIGl0KCdBbGwgd3JvbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWwgPSB0Zi50ZW5zb3IyZChbWzAsIDAsIDFdLCBbMSwgMCwgMF0sIFswLCAxLCAwXV0sIFszLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IyZChcbiAgICAgICAgW1sxMC4wLCAtMTAuMCwgLTEwLjBdLCBbLTEwLjAsIDEwLjAsIC0xMC4wXSwgWy0xMC4wLCAtMTAuMCwgMTAuMF1dLFxuICAgICAgICBbMywgM10pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5zb2Z0bWF4Q3Jvc3NFbnRyb3B5KGxhYmVsLCBwcmVkaWN0aW9ucyk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIDIwKTtcbiAgfSk7XG5cbiAgaXQoJ0FsbCByaWdodCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsYWJlbCA9IHRmLnRlbnNvcjJkKFtbMSwgMCwgMF0sIFswLCAxLCAwXSwgWzAsIDAsIDFdXSwgWzMsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjJkKFxuICAgICAgICBbWzEwLjAsIC0xMC4wLCAtMTAuMF0sIFstMTAuMCwgMTAuMCwgLTEwLjBdLCBbLTEwLjAsIC0xMC4wLCAxMC4wXV0sXG4gICAgICAgIFszLCAzXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLnNvZnRtYXhDcm9zc0VudHJvcHkobGFiZWwsIHByZWRpY3Rpb25zKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMCk7XG4gIH0pO1xuXG4gIGl0KCdXZWlnaHRlZCAtIFJlZHVjdGlvbi5TVU1fQllfTk9OWkVST19XRUlHSFRTJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVsID0gdGYudGVuc29yMmQoW1swLCAwLCAxXSwgWzEsIDAsIDBdLCBbMCwgMSwgMF1dLCBbMywgM10pO1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gdGYudGVuc29yMmQoXG4gICAgICAgIFtbMTAuMCwgLTEwLjAsIC0xMC4wXSwgWy0xMC4wLCAxMC4wLCAtMTAuMF0sIFstMTAuMCwgLTEwLjAsIDEwLjBdXSxcbiAgICAgICAgWzMsIDNdKTtcblxuICAgIGNvbnN0IHdlaWdodHMgPVxuICAgICAgICB0Zi50ZW5zb3IyZChbWzAuMSwgMC4yLCAwLjNdLCBbMC4xLCAwLjIsIDAuM10sIFswLjEsIDAuMiwgMC4zXV0pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5zb2Z0bWF4Q3Jvc3NFbnRyb3B5KGxhYmVsLCBwcmVkaWN0aW9ucywgd2VpZ2h0cyk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIDQpO1xuICB9KTtcblxuICBpdCgnV2VpZ2h0ZWQgLSBSZWR1Y3Rpb24uTk9ORScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsYWJlbCA9IHRmLnRlbnNvcjJkKFtbMCwgMCwgMV0sIFsxLCAwLCAwXSwgWzAsIDEsIDBdXSwgWzMsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjJkKFxuICAgICAgICBbWzEwLjAsIC0xMC4wLCAtMTAuMF0sIFstMTAuMCwgMTAuMCwgLTEwLjBdLCBbLTEwLjAsIC0xMC4wLCAxMC4wXV0sXG4gICAgICAgIFszLCAzXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjFkKFswLjEsIDAuMiwgMC4zXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLnNvZnRtYXhDcm9zc0VudHJvcHkoXG4gICAgICAgIGxhYmVsLCBwcmVkaWN0aW9ucywgd2VpZ2h0cywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTk9ORSk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCBbMiwgNCwgNl0pO1xuICB9KTtcblxuICBpdCgnUmVkdWN0aW9uLk1FQU4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWwgPSB0Zi50ZW5zb3IyZChbWzAsIDAsIDFdLCBbMSwgMCwgMF0sIFswLCAxLCAwXV0sIFszLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IyZChcbiAgICAgICAgW1sxMC4wLCAtMTAuMCwgLTEwLjBdLCBbLTEwLjAsIDEwLjAsIC0xMC4wXSwgWy0xMC4wLCAtMTAuMCwgMTAuMF1dLFxuICAgICAgICBbMywgM10pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5zb2Z0bWF4Q3Jvc3NFbnRyb3B5KFxuICAgICAgICBsYWJlbCwgcHJlZGljdGlvbnMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTUVBTik7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIDIwKTtcbiAgfSk7XG5cbiAgaXQoJ1dlaWdodGVkIC0gUmVkdWN0aW9uLk1FQU4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWwgPSB0Zi50ZW5zb3IyZChbWzAsIDAsIDFdLCBbMSwgMCwgMF0sIFswLCAxLCAwXV0sIFszLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IyZChcbiAgICAgICAgW1sxMC4wLCAtMTAuMCwgLTEwLjBdLCBbLTEwLjAsIDEwLjAsIC0xMC4wXSwgWy0xMC4wLCAtMTAuMCwgMTAuMF1dLFxuICAgICAgICBbMywgM10pO1xuICAgIGNvbnN0IHdlaWdodHMgPSB0Zi50ZW5zb3IxZChbMC4xLCAwLjIsIDAuM10pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5zb2Z0bWF4Q3Jvc3NFbnRyb3B5KFxuICAgICAgICBsYWJlbCwgcHJlZGljdGlvbnMsIHdlaWdodHMsIHVuZGVmaW5lZCwgdGYuUmVkdWN0aW9uLk1FQU4pO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCB5LmRhdGEoKSxcbiAgICAgICAgMjAsXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ0xhYmVsIFNtb290aGluZyAtIFdlaWdodGVkIC0gUmVkdWN0aW9uLk1FQU4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWwgPSB0Zi50ZW5zb3IyZChbWzAsIDAsIDFdLCBbMSwgMCwgMF0sIFswLCAxLCAwXV0sIFszLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IyZChcbiAgICAgICAgW1sxMC4wLCAtMTAuMCwgLTEwLjBdLCBbLTEwLjAsIDEwLjAsIC0xMC4wXSwgWy0xMC4wLCAtMTAuMCwgMTAuMF1dLFxuICAgICAgICBbMywgM10pO1xuICAgIGNvbnN0IHdlaWdodHMgPSB0Zi50ZW5zb3IyZChbWzAuMSwgMC4yLCAwLjNdXSk7XG4gICAgY29uc3QgbGFiZWxTbW9vdGhpbmcgPSAwLjM7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLnNvZnRtYXhDcm9zc0VudHJvcHkoXG4gICAgICAgIGxhYmVsLCBwcmVkaWN0aW9ucywgd2VpZ2h0cywgbGFiZWxTbW9vdGhpbmcsIHRmLlJlZHVjdGlvbi5NRUFOKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMTgpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gbXVsdGlDbGFzc0xhYmVscyBhbmQgbG9naXRzIGFyZSBvZiBkaWZmZXJlbnQgc2hhcGVzJywgKCkgPT4ge1xuICAgIGNvbnN0IG11bHRpQ2xhc3NMYWJlbHMgPVxuICAgICAgICB0Zi50ZW5zb3IyZChbMTAsIDEwLCAxMCwgMTAsIDEwLCAxMCwgMTAsIDEwLCAxMF0sIFszLCAzXSk7XG4gICAgY29uc3QgbG9naXRzID0gdGYudGVuc29yMmQoWzEwLCAxMCwgMTAsIDEwLCAxMCwgMTBdLCBbMiwgM10pO1xuXG4gICAgY29uc3QgZSA9IG5ldyBSZWdFeHAoXG4gICAgICAgICdFcnJvciBpbiBzb2Z0bWF4Q3Jvc3NFbnRyb3B5OiAgU2hhcGVzIDMsMyBhbmQgMiwzIG11c3QgbWF0Y2gnKTtcbiAgICBleHBlY3QoKCkgPT4gdGYubG9zc2VzLnNvZnRtYXhDcm9zc0VudHJvcHkobXVsdGlDbGFzc0xhYmVscywgbG9naXRzKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcihlKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIHBhc3NlZCBtdWx0aUNsYXNzTGFiZWxzIGFzIGEgbm9uLXRlbnNvcicsICgpID0+IHtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjJkKFxuICAgICAgICBbWzEwLjAsIC0xMC4wLCAtMTAuMF0sIFstMTAuMCwgMTAuMCwgLTEwLjBdLCBbLTEwLjAsIC0xMC4wLCAxMC4wXV0sXG4gICAgICAgIFszLCAzXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjJkKFtbMC4xLCAwLjIsIDAuM11dKTtcblxuICAgIGNvbnN0IGUgPSBuZXcgUmVnRXhwKFxuICAgICAgICAnQXJndW1lbnQgXFwnb25laG90TGFiZWxzXFwnIHBhc3NlZCB0byBcXCdzb2Z0bWF4Q3Jvc3NFbnRyb3B5XFwnICcgK1xuICAgICAgICAnbXVzdCBiZSBhIFRlbnNvcicpO1xuXG4gICAgZXhwZWN0KFxuICAgICAgICAoKSA9PiB0Zi5sb3NzZXMuc29mdG1heENyb3NzRW50cm9weShcbiAgICAgICAgICAgIHt9IGFzIHRmLlRlbnNvciwgcHJlZGljdGlvbnMsIHdlaWdodHMsIHRmLlJlZHVjdGlvbi5NRUFOKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcihlKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIHBhc3NlZCBsb2dpdHMgYXMgYSBub24tdGVuc29yJywgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVsID0gdGYudGVuc29yMmQoW1swLCAwLCAxXSwgWzEsIDAsIDBdLCBbMCwgMSwgMF1dLCBbMywgM10pO1xuICAgIGNvbnN0IHdlaWdodHMgPSB0Zi50ZW5zb3IyZChbWzAuMSwgMC4yLCAwLjNdXSk7XG5cbiAgICBjb25zdCBlID0gbmV3IFJlZ0V4cChcbiAgICAgICAgJ0FyZ3VtZW50IFxcJ2xvZ2l0c1xcJyBwYXNzZWQgdG8gXFwnc29mdG1heENyb3NzRW50cm9weVxcJyAnICtcbiAgICAgICAgJ211c3QgYmUgYSBUZW5zb3InKTtcbiAgICBleHBlY3QoXG4gICAgICAgICgpID0+IHRmLmxvc3Nlcy5zb2Z0bWF4Q3Jvc3NFbnRyb3B5KFxuICAgICAgICAgICAgbGFiZWwsIHt9IGFzIHRmLlRlbnNvciwgd2VpZ2h0cywgdGYuUmVkdWN0aW9uLk1FQU4pKVxuICAgICAgICAudG9UaHJvd0Vycm9yKGUpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gcGFzc2VkIHdlaWdodHMgYXMgYSBub24tdGVuc29yJywgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVsID0gdGYudGVuc29yMmQoW1swLCAwLCAxXSwgWzEsIDAsIDBdLCBbMCwgMSwgMF1dLCBbMywgM10pO1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gdGYudGVuc29yMmQoXG4gICAgICAgIFtbMTAuMCwgLTEwLjAsIC0xMC4wXSwgWy0xMC4wLCAxMC4wLCAtMTAuMF0sIFstMTAuMCwgLTEwLjAsIDEwLjBdXSxcbiAgICAgICAgWzMsIDNdKTtcblxuICAgIGNvbnN0IGUgPVxuICAgICAgICAvQXJndW1lbnQgJ3dlaWdodHMnIHBhc3NlZCB0byAnc29mdG1heENyb3NzRW50cm9weScgbXVzdCBiZSBhIFRlbnNvci87XG4gICAgZXhwZWN0KFxuICAgICAgICAoKSA9PiB0Zi5sb3NzZXMuc29mdG1heENyb3NzRW50cm9weShcbiAgICAgICAgICAgIGxhYmVsLCBwcmVkaWN0aW9ucywge30gYXMgdGYuVGVuc29yLCB0Zi5SZWR1Y3Rpb24uTUVBTikpXG4gICAgICAgIC50b1Rocm93RXJyb3IoZSk7XG4gIH0pO1xuXG4gIGl0KCdhY2NlcHRzIGEgdGVuc29yLWxpa2Ugb2JqZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVsID0gW1swLCAwLCAxXSwgWzEsIDAsIDBdLCBbMCwgMSwgMF1dO1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID1cbiAgICAgICAgW1sxMC4wLCAtMTAuMCwgLTEwLjBdLCBbLTEwLjAsIDEwLjAsIC0xMC4wXSwgWy0xMC4wLCAtMTAuMCwgMTAuMF1dO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5zb2Z0bWF4Q3Jvc3NFbnRyb3B5KGxhYmVsLCBwcmVkaWN0aW9ucyk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIDIwKTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|