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
/**
 * @license
 * Copyright 2018 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('inTopKAsync', ALL_ENVS, async () => {
    it('predictions 2d array, targets 1d array, with default k', async () => {
        const predictions = tensor2d([[20, 10, 40, 30], [30, 50, -20, 10]]);
        const targets = tensor1d([2, 0]);
        const precision = await tf.inTopKAsync(predictions, targets);
        expect(precision.shape).toEqual([2]);
        expect(precision.dtype).toBe('bool');
        expectArraysClose(await precision.data(), [1, 0]);
    });
    it('predictions 2d array, targets 1d array, with k=2', async () => {
        const predictions = tensor2d([[20, 10, 40, 30], [30, 50, -20, 10]]);
        const targets = tensor1d([2, 0]);
        const k = 2;
        const precision = await tf.inTopKAsync(predictions, targets, k);
        expect(precision.shape).toEqual([2]);
        expect(precision.dtype).toBe('bool');
        expectArraysClose(await precision.data(), [1, 1]);
    });
    it('predictions 3d array, targets 2d array, with default k', async () => {
        const predictions = tensor3d([[[1, 5, 2], [4, 3, 6]], [[3, 2, 1], [1, 2, 3]]]);
        const targets = tensor2d([[1, 2], [0, 1]]);
        const precision = await tf.inTopKAsync(predictions, targets);
        expect(precision.shape).toEqual([2, 2]);
        expect(precision.dtype).toBe('bool');
        expectArraysClose(await precision.data(), [1, 1, 1, 0]);
    });
    it('predictions 3d array, targets 2d array, with k=2', async () => {
        const predictions = tensor3d([[[1, 5, 2], [4, 3, 6]], [[3, 2, 1], [1, 2, 3]]]);
        const targets = tensor2d([[1, 2], [0, 1]]);
        const k = 2;
        const precision = await tf.inTopKAsync(predictions, targets, k);
        expect(precision.shape).toEqual([2, 2]);
        expect(precision.dtype).toBe('bool');
        expectArraysClose(await precision.data(), [1, 1, 1, 1]);
    });
    it('lower-index element count first, with default k', async () => {
        const predictions = tensor2d([[1, 2, 2, 1]]);
        const targets1 = tensor1d([1]);
        const precision1 = await tf.inTopKAsync(predictions, targets1);
        expect(precision1.shape).toEqual([1]);
        expect(precision1.dtype).toBe('bool');
        expectArraysClose(await precision1.data(), [1]);
        const targets2 = tensor1d([2]);
        const precision2 = await tf.inTopKAsync(predictions, targets2);
        expect(precision2.shape).toEqual([1]);
        expect(precision2.dtype).toBe('bool');
        expectArraysClose(await precision2.data(), [0]);
    });
    it('accept tensor-like object, with default k', async () => {
        const predictions = [[20, 10, 40, 30], [30, 50, -20, 10]];
        const targets = [2, 0];
        const precision = await tf.inTopKAsync(predictions, targets);
        expect(precision.shape).toEqual([2]);
        expect(precision.dtype).toBe('bool');
        expectArraysClose(await precision.data(), [1, 0]);
    });
    it('doesnt leak tensors with tensor-like objects', async () => {
        const numTensors = tf.memory().numTensors;
        const predictions = [[20, 10, 40, 30], [30, 50, -20, 10]];
        const targets = [2, 0];
        const precision = await tf.inTopKAsync(predictions, targets);
        precision.dispose();
        expect(tf.memory().numTensors).toBe(numTensors);
    });
    it('throws when predictions_rank <2', async () => {
        const predictions = tensor1d([20, 10, 40, 30]);
        const targets = [2];
        // expect(...).toThrowError() does not support async functions.
        // See https://github.com/jasmine/jasmine/issues/1410
        try {
            await tf.inTopKAsync(predictions, targets);
            throw new Error('The line above should have thrown an error');
        }
        catch (ex) {
            expect(ex.message)
                .toEqual('inTopK() expects the predictions to ' +
                'be of rank 2 or higher, but got 1');
        }
    });
    it('throws when prediction.rank != targets.rank + 1', async () => {
        const predictions = tensor2d([[20, 10, 40, 30], [30, 50, -20, 10]]);
        const targets = tensor2d([[0], [0]]);
        // expect(...).toThrowError() does not support async functions.
        // See https://github.com/jasmine/jasmine/issues/1410
        try {
            await tf.inTopKAsync(predictions, targets);
            throw new Error('The line above should have thrown an error');
        }
        catch (ex) {
            expect(ex.message)
                .toEqual('predictions rank should be 1 larger than targets rank,' +
                ' but got predictions rank 2 and targets rank 2');
        }
    });
    it('throws when k > size of last dimension of predictions', async () => {
        const predictions = tensor2d([[20, 10, 40, 30], [30, 50, -20, 10]]);
        const targets = tensor1d([2, 0]);
        const k = 5;
        // expect(...).toThrowError() does not support async functions.
        // See https://github.com/jasmine/jasmine/issues/1410
        try {
            await tf.inTopKAsync(predictions, targets, k);
            throw new Error('The line above should have thrown an error');
        }
        catch (ex) {
            expect(ex.message)
                .toEqual('\'k\' passed to inTopK() must be > 0 && <= the predictions ' +
                'last dimension (4), but got 5');
        }
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5fdG9wX2tfdGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3RmanMtY29yZS9zcmMvb3BzL2luX3RvcF9rX3Rlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDL0IsT0FBTyxFQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzVELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUUvQyxPQUFPLEVBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUMsTUFBTSxPQUFPLENBQUM7QUFFbkQsaUJBQWlCLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNwRCxFQUFFLENBQUMsd0RBQXdELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdEUsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sU0FBUyxHQUFHLE1BQU0sRUFBRSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDN0QsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JDLGlCQUFpQixDQUFDLE1BQU0sU0FBUyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsa0RBQWtELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDaEUsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNaLE1BQU0sU0FBUyxHQUFHLE1BQU0sRUFBRSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNyQyxpQkFBaUIsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHdEQUF3RCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3RFLE1BQU0sV0FBVyxHQUNiLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FB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LFdBQVcsQ0FBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQztTQUMvRDtRQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ1gsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUM7aUJBQ2IsT0FBTyxDQUNKLDZEQUE2RDtnQkFDN0QsK0JBQStCLENBQUMsQ0FBQztTQUMxQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCAqIGFzIHRmIGZyb20gJy4uL2luZGV4JztcbmltcG9ydCB7QUxMX0VOVlMsIGRlc2NyaWJlV2l0aEZsYWdzfSBmcm9tICcuLi9qYXNtaW5lX3V0aWwnO1xuaW1wb3J0IHtleHBlY3RBcnJheXNDbG9zZX0gZnJvbSAnLi4vdGVzdF91dGlsJztcblxuaW1wb3J0IHt0ZW5zb3IxZCwgdGVuc29yMmQsIHRlbnNvcjNkfSBmcm9tICcuL29wcyc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdpblRvcEtBc3luYycsIEFMTF9FTlZTLCBhc3luYyAoKSA9PiB7XG4gIGl0KCdwcmVkaWN0aW9ucyAyZCBhcnJheSwgdGFyZ2V0cyAxZCBhcnJheSwgd2l0aCBkZWZhdWx0IGsnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0ZW5zb3IyZChbWzIwLCAxMCwgNDAsIDMwXSwgWzMwLCA1MCwgLTIwLCAxMF1dKTtcbiAgICBjb25zdCB0YXJnZXRzID0gdGVuc29yMWQoWzIsIDBdKTtcbiAgICBjb25zdCBwcmVjaXNpb24gPSBhd2FpdCB0Zi5pblRvcEtBc3luYyhwcmVkaWN0aW9ucywgdGFyZ2V0cyk7XG4gICAgZXhwZWN0KHByZWNpc2lvbi5zaGFwZSkudG9FcXVhbChbMl0pO1xuICAgIGV4cGVjdChwcmVjaXNpb24uZHR5cGUpLnRvQmUoJ2Jvb2wnKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBwcmVjaXNpb24uZGF0YSgpLCBbMSwgMF0pO1xuICB9KTtcblxuICBpdCgncHJlZGljdGlvbnMgMmQgYXJyYXksIHRhcmdldHMgMWQgYXJyYXksIHdpdGggaz0yJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gdGVuc29yMmQoW1syMCwgMTAsIDQwLCAzMF0sIFszMCwgNTAsIC0yMCwgMTBdXSk7XG4gICAgY29uc3QgdGFyZ2V0cyA9IHRlbnNvcjFkKFsyLCAwXSk7XG4gICAgY29uc3QgayA9IDI7XG4gICAgY29uc3QgcHJlY2lzaW9uID0gYXdhaXQgdGYuaW5Ub3BLQXN5bmMocHJlZGljdGlvbnMsIHRhcmdldHMsIGspO1xuICAgIGV4cGVjdChwcmVjaXNpb24uc2hhcGUpLnRvRXF1YWwoWzJdKTtcbiAgICBleHBlY3QocHJlY2lzaW9uLmR0eXBlKS50b0JlKCdib29sJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcHJlY2lzaW9uLmRhdGEoKSwgWzEsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJ3ByZWRpY3Rpb25zIDNkIGFycmF5LCB0YXJnZXRzIDJkIGFycmF5LCB3aXRoIGRlZmF1bHQgaycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9XG4gICAgICAgIHRlbnNvcjNkKFtbWzEsIDUsIDJdLCBbNCwgMywgNl1dLCBbWzMsIDIsIDFdLCBbMSwgMiwgM11dXSk7XG4gICAgY29uc3QgdGFyZ2V0cyA9IHRlbnNvcjJkKFtbMSwgMl0sIFswLCAxXV0pO1xuICAgIGNvbnN0IHByZWNpc2lvbiA9IGF3YWl0IHRmLmluVG9wS0FzeW5jKHByZWRpY3Rpb25zLCB0YXJnZXRzKTtcbiAgICBleHBlY3QocHJlY2lzaW9uLnNoYXBlKS50b0VxdWFsKFsyLCAyXSk7XG4gICAgZXhwZWN0KHByZWNpc2lvbi5kdHlwZSkudG9CZSgnYm9vbCcpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHByZWNpc2lvbi5kYXRhKCksIFsxLCAxLCAxLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCdwcmVkaWN0aW9ucyAzZCBhcnJheSwgdGFyZ2V0cyAyZCBhcnJheSwgd2l0aCBrPTInLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPVxuICAgICAgICB0ZW5zb3IzZChbW1sxLCA1LCAyXSwgWzQsIDMsIDZdXSwgW1szLCAyLCAxXSwgWzEsIDIsIDNdXV0pO1xuICAgIGNvbnN0IHRhcmdldHMgPSB0ZW5zb3IyZChbWzEsIDJdLCBbMCwgMV1dKTtcbiAgICBjb25zdCBrID0gMjtcbiAgICBjb25zdCBwcmVjaXNpb24gPSBhd2FpdCB0Zi5pblRvcEtBc3luYyhwcmVkaWN0aW9ucywgdGFyZ2V0cywgayk7XG4gICAgZXhwZWN0KHByZWNpc2lvbi5zaGFwZSkudG9FcXVhbChbMiwgMl0pO1xuICAgIGV4cGVjdChwcmVjaXNpb24uZHR5cGUpLnRvQmUoJ2Jvb2wnKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBwcmVjaXNpb24uZGF0YSgpLCBbMSwgMSwgMSwgMV0pO1xuICB9KTtcblxuICBpdCgnbG93ZXItaW5kZXggZWxlbWVudCBjb3VudCBmaXJzdCwgd2l0aCBkZWZhdWx0IGsnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0ZW5zb3IyZChbWzEsIDIsIDIsIDFdXSk7XG5cbiAgICBjb25zdCB0YXJnZXRzMSA9IHRlbnNvcjFkKFsxXSk7XG4gICAgY29uc3QgcHJlY2lzaW9uMSA9IGF3YWl0IHRmLmluVG9wS0FzeW5jKHByZWRpY3Rpb25zLCB0YXJnZXRzMSk7XG4gICAgZXhwZWN0KHByZWNpc2lvbjEuc2hhcGUpLnRvRXF1YWwoWzFdKTtcbiAgICBleHBlY3QocHJlY2lzaW9uMS5kdHlwZSkudG9CZSgnYm9vbCcpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHByZWNpc2lvbjEuZGF0YSgpLCBbMV0pO1xuXG4gICAgY29uc3QgdGFyZ2V0czIgPSB0ZW5zb3IxZChbMl0pO1xuICAgIGNvbnN0IHByZWNpc2lvbjIgPSBhd2FpdCB0Zi5pblRvcEtBc3luYyhwcmVkaWN0aW9ucywgdGFyZ2V0czIpO1xuICAgIGV4cGVjdChwcmVjaXNpb24yLnNoYXBlKS50b0VxdWFsKFsxXSk7XG4gICAgZXhwZWN0KHByZWNpc2lvbjIuZHR5cGUpLnRvQmUoJ2Jvb2wnKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBwcmVjaXNpb24yLmRhdGEoKSwgWzBdKTtcbiAgfSk7XG5cbiAgaXQoJ2FjY2VwdCB0ZW5zb3ItbGlrZSBvYmplY3QsIHdpdGggZGVmYXVsdCBrJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gW1syMCwgMTAsIDQwLCAzMF0sIFszMCwgNTAsIC0yMCwgMTBdXTtcbiAgICBjb25zdCB0YXJnZXRzID0gWzIsIDBdO1xuICAgIGNvbnN0IHByZWNpc2lvbiA9IGF3YWl0IHRmLmluVG9wS0FzeW5jKHByZWRpY3Rpb25zLCB0YXJnZXRzKTtcbiAgICBleHBlY3QocHJlY2lzaW9uLnNoYXBlKS50b0VxdWFsKFsyXSk7XG4gICAgZXhwZWN0KHByZWNpc2lvbi5kdHlwZSkudG9CZSgnYm9vbCcpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHByZWNpc2lvbi5kYXRhKCksIFsxLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCdkb2VzbnQgbGVhayB0ZW5zb3JzIHdpdGggdGVuc29yLWxpa2Ugb2JqZWN0cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBudW1UZW5zb3JzID0gdGYubWVtb3J5KCkubnVtVGVuc29ycztcblxuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gW1syMCwgMTAsIDQwLCAzMF0sIFszMCwgNTAsIC0yMCwgMTBdXTtcbiAgICBjb25zdCB0YXJnZXRzID0gWzIsIDBdO1xuICAgIGNvbnN0IHByZWNpc2lvbiA9IGF3YWl0IHRmLmluVG9wS0FzeW5jKHByZWRpY3Rpb25zLCB0YXJnZXRzKTtcbiAgICBwcmVjaXNpb24uZGlzcG9zZSgpO1xuXG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUobnVtVGVuc29ycyk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBwcmVkaWN0aW9uc19yYW5rIDwyJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gdGVuc29yMWQoWzIwLCAxMCwgNDAsIDMwXSk7XG4gICAgY29uc3QgdGFyZ2V0cyA9IFsyXTtcblxuICAgIC8vIGV4cGVjdCguLi4pLnRvVGhyb3dFcnJvcigpIGRvZXMgbm90IHN1cHBvcnQgYXN5bmMgZnVuY3Rpb25zLlxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vamFzbWluZS9qYXNtaW5lL2lzc3Vlcy8xNDEwXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRmLmluVG9wS0FzeW5jKHByZWRpY3Rpb25zLCB0YXJnZXRzKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGxpbmUgYWJvdmUgc2hvdWxkIGhhdmUgdGhyb3duIGFuIGVycm9yJyk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIGV4cGVjdChleC5tZXNzYWdlKVxuICAgICAgICAgIC50b0VxdWFsKFxuICAgICAgICAgICAgICAnaW5Ub3BLKCkgZXhwZWN0cyB0aGUgcHJlZGljdGlvbnMgdG8gJyArXG4gICAgICAgICAgICAgICdiZSBvZiByYW5rIDIgb3IgaGlnaGVyLCBidXQgZ290IDEnKTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBwcmVkaWN0aW9uLnJhbmsgIT0gdGFyZ2V0cy5yYW5rICsgMScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRlbnNvcjJkKFtbMjAsIDEwLCA0MCwgMzBdLCBbMzAsIDUwLCAtMjAsIDEwXV0pO1xuICAgIGNvbnN0IHRhcmdldHMgPSB0ZW5zb3IyZChbWzBdLCBbMF1dKTtcblxuICAgIC8vIGV4cGVjdCguLi4pLnRvVGhyb3dFcnJvcigpIGRvZXMgbm90IHN1cHBvcnQgYXN5bmMgZnVuY3Rpb25zLlxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vamFzbWluZS9qYXNtaW5lL2lzc3Vlcy8xNDEwXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRmLmluVG9wS0FzeW5jKHByZWRpY3Rpb25zLCB0YXJnZXRzKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGxpbmUgYWJvdmUgc2hvdWxkIGhhdmUgdGhyb3duIGFuIGVycm9yJyk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIGV4cGVjdChleC5tZXNzYWdlKVxuICAgICAgICAgIC50b0VxdWFsKFxuICAgICAgICAgICAgICAncHJlZGljdGlvbnMgcmFuayBzaG91bGQgYmUgMSBsYXJnZXIgdGhhbiB0YXJnZXRzIHJhbmssJyArXG4gICAgICAgICAgICAgICcgYnV0IGdvdCBwcmVkaWN0aW9ucyByYW5rIDIgYW5kIHRhcmdldHMgcmFuayAyJyk7XG4gICAgfVxuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gayA+IHNpemUgb2YgbGFzdCBkaW1lbnNpb24gb2YgcHJlZGljdGlvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0ZW5zb3IyZChbWzIwLCAxMCwgNDAsIDMwXSwgWzMwLCA1MCwgLTIwLCAxMF1dKTtcbiAgICBjb25zdCB0YXJnZXRzID0gdGVuc29yMWQoWzIsIDBdKTtcbiAgICBjb25zdCBrID0gNTtcblxuICAgIC8vIGV4cGVjdCguLi4pLnRvVGhyb3dFcnJvcigpIGRvZXMgbm90IHN1cHBvcnQgYXN5bmMgZnVuY3Rpb25zLlxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vamFzbWluZS9qYXNtaW5lL2lzc3Vlcy8xNDEwXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRmLmluVG9wS0FzeW5jKHByZWRpY3Rpb25zLCB0YXJnZXRzLCBrKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGxpbmUgYWJvdmUgc2hvdWxkIGhhdmUgdGhyb3duIGFuIGVycm9yJyk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIGV4cGVjdChleC5tZXNzYWdlKVxuICAgICAgICAgIC50b0VxdWFsKFxuICAgICAgICAgICAgICAnXFwna1xcJyBwYXNzZWQgdG8gaW5Ub3BLKCkgbXVzdCBiZSA+IDAgJiYgPD0gdGhlIHByZWRpY3Rpb25zICcgK1xuICAgICAgICAgICAgICAnbGFzdCBkaW1lbnNpb24gKDQpLCBidXQgZ290IDUnKTtcbiAgICB9XG4gIH0pO1xufSk7XG4iXX0=