@tensorflow/tfjs-core
Version:
Hardware-accelerated JavaScript library for machine intelligence
103 lines • 17.4 kB
JavaScript
/**
* @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';
describeWithFlags('booleanMaskAsync', ALL_ENVS, () => {
it('1d array, 1d mask, default axis', async () => {
const array = tf.tensor1d([1, 2, 3]);
const mask = tf.tensor1d([1, 0, 1], 'bool');
const result = await tf.booleanMaskAsync(array, mask);
expect(result.shape).toEqual([2]);
expect(result.dtype).toBe('float32');
expectArraysClose(await result.data(), [1, 3]);
});
it('2d array, 1d mask, default axis', async () => {
const array = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
const mask = tf.tensor1d([1, 0, 1], 'bool');
const result = await tf.booleanMaskAsync(array, mask);
expect(result.shape).toEqual([2, 2]);
expect(result.dtype).toBe('float32');
expectArraysClose(await result.data(), [1, 2, 5, 6]);
});
it('2d array, 2d mask, default axis', async () => {
const array = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
const mask = tf.tensor2d([1, 0, 1, 0, 1, 0], [3, 2], 'bool');
const result = await tf.booleanMaskAsync(array, mask);
expect(result.shape).toEqual([3]);
expect(result.dtype).toBe('float32');
expectArraysClose(await result.data(), [1, 3, 5]);
});
it('2d array, 1d mask, axis=1', async () => {
const array = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
const mask = tf.tensor1d([0, 1], 'bool');
const axis = 1;
const result = await tf.booleanMaskAsync(array, mask, axis);
expect(result.shape).toEqual([3, 1]);
expect(result.dtype).toBe('float32');
expectArraysClose(await result.data(), [2, 4, 6]);
});
it('accepts tensor-like object as array or mask', async () => {
const array = [[1, 2], [3, 4], [5, 6]];
const mask = [1, 0, 1];
const result = await tf.booleanMaskAsync(array, mask);
expect(result.shape).toEqual([2, 2]);
expect(result.dtype).toBe('float32');
expectArraysClose(await result.data(), [1, 2, 5, 6]);
});
it('ensure no memory leak', async () => {
const numTensorsBefore = tf.memory().numTensors;
const array = tf.tensor1d([1, 2, 3]);
const mask = tf.tensor1d([1, 0, 1], 'bool');
const result = await tf.booleanMaskAsync(array, mask);
expect(result.shape).toEqual([2]);
expect(result.dtype).toBe('float32');
expectArraysClose(await result.data(), [1, 3]);
array.dispose();
mask.dispose();
result.dispose();
const numTensorsAfter = tf.memory().numTensors;
expect(numTensorsAfter).toBe(numTensorsBefore);
});
it('should throw if mask is scalar', async () => {
const array = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
const mask = tf.scalar(1, 'bool');
let errorMessage = 'No error thrown.';
try {
await tf.booleanMaskAsync(array, mask);
}
catch (error) {
errorMessage = error.message;
}
expect(errorMessage).toBe('mask cannot be scalar');
});
it('should throw if array and mask shape miss match', async () => {
const array = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
const mask = tf.tensor2d([1, 0], [1, 2], 'bool');
let errorMessage = 'No error thrown.';
try {
await tf.booleanMaskAsync(array, mask);
}
catch (error) {
errorMessage = error.message;
}
expect(errorMessage)
.toBe(`mask's shape must match the first K ` +
`dimensions of tensor's shape, Shapes 3,2 and 1,2 must match`);
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vbGVhbl9tYXNrX3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL29wcy9ib29sZWFuX21hc2tfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sY0FBYyxDQUFDO0FBRS9DLGlCQUFpQixDQUFDLGtCQUFrQixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDbkQsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQy9DLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDNUMsTUFBTSxNQUFNLEdBQUcsTUFBTSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3RELE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQy9DLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEQsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDNUMsTUFBTSxNQUFNLEdBQUcsTUFBTSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3RELE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsaUJBQWlCLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQy9DLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEQsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFF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bEMsSUFBSSxZQUFZLEdBQUcsa0JBQWtCLENBQUM7UUFDdEMsSUFBSTtZQUNGLE1BQU0sRUFBRSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztTQUN4QztRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsWUFBWSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7U0FDOUI7UUFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDL0QsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RCxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELElBQUksWUFBWSxHQUFHLGtCQUFrQixDQUFDO1FBQ3RDLElBQUk7WUFDRixNQUFNLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDeEM7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLFlBQVksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1NBQzlCO1FBQ0QsTUFBTSxDQUFDLFlBQVksQ0FBQzthQUNmLElBQUksQ0FDRCxzQ0FBc0M7WUFDdEMsNkRBQTZELENBQUMsQ0FBQztJQUN6RSxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4uL3Rlc3RfdXRpbCc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdib29sZWFuTWFza0FzeW5jJywgQUxMX0VOVlMsICgpID0+IHtcbiAgaXQoJzFkIGFycmF5LCAxZCBtYXNrLCBkZWZhdWx0IGF4aXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYXJyYXkgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAgIGNvbnN0IG1hc2sgPSB0Zi50ZW5zb3IxZChbMSwgMCwgMV0sICdib29sJyk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGYuYm9vbGVhbk1hc2tBc3luYyhhcnJheSwgbWFzayk7XG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMl0pO1xuICAgIGV4cGVjdChyZXN1bHQuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbMSwgM10pO1xuICB9KTtcblxuICBpdCgnMmQgYXJyYXksIDFkIG1hc2ssIGRlZmF1bHQgYXhpcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhcnJheSA9IHRmLnRlbnNvcjJkKFsxLCAyLCAzLCA0LCA1LCA2XSwgWzMsIDJdKTtcbiAgICBjb25zdCBtYXNrID0gdGYudGVuc29yMWQoWzEsIDAsIDFdLCAnYm9vbCcpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRmLmJvb2xlYW5NYXNrQXN5bmMoYXJyYXksIG1hc2spO1xuICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzIsIDJdKTtcbiAgICBleHBlY3QocmVzdWx0LmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWzEsIDIsIDUsIDZdKTtcbiAgfSk7XG5cbiAgaXQoJzJkIGFycmF5LCAyZCBtYXNrLCBkZWZhdWx0IGF4aXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYXJyYXkgPSB0Zi50ZW5zb3IyZChbMSwgMiwgMywgNCwgNSwgNl0sIFszLCAyXSk7XG4gICAgY29uc3QgbWFzayA9IHRmLnRlbnNvcjJkKFsxLCAwLCAxLCAwLCAxLCAwXSwgWzMsIDJdLCAnYm9vbCcpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRmLmJvb2xlYW5NYXNrQXN5bmMoYXJyYXksIG1hc2spO1xuICAgIGV4cGVjdChyZXN1bHQuc2hhcGUpLnRvRXF1YWwoWzNdKTtcbiAgICBleHBlY3QocmVzdWx0LmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWzEsIDMsIDVdKTtcbiAgfSk7XG5cbiAgaXQoJzJkIGFycmF5LCAxZCBtYXNrLCBheGlzPTEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYXJyYXkgPSB0Zi50ZW5zb3IyZChbMSwgMiwgMywgNCwgNSwgNl0sIFszLCAyXSk7XG4gICAgY29uc3QgbWFzayA9IHRmLnRlbnNvcjFkKFswLCAxXSwgJ2Jvb2wnKTtcbiAgICBjb25zdCBheGlzID0gMTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0Zi5ib29sZWFuTWFza0FzeW5jKGFycmF5LCBtYXNrLCBheGlzKTtcbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFszLCAxXSk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsyLCA0LCA2XSk7XG4gIH0pO1xuXG4gIGl0KCdhY2NlcHRzIHRlbnNvci1saWtlIG9iamVjdCBhcyBhcnJheSBvciBtYXNrJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGFycmF5ID0gW1sxLCAyXSwgWzMsIDRdLCBbNSwgNl1dO1xuICAgIGNvbnN0IG1hc2sgPSBbMSwgMCwgMV07XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGYuYm9vbGVhbk1hc2tBc3luYyhhcnJheSwgbWFzayk7XG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMiwgMl0pO1xuICAgIGV4cGVjdChyZXN1bHQuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXN1bHQuZGF0YSgpLCBbMSwgMiwgNSwgNl0pO1xuICB9KTtcblxuICBpdCgnZW5zdXJlIG5vIG1lbW9yeSBsZWFrJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG51bVRlbnNvcnNCZWZvcmUgPSB0Zi5tZW1vcnkoKS5udW1UZW5zb3JzO1xuXG4gICAgY29uc3QgYXJyYXkgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAgIGNvbnN0IG1hc2sgPSB0Zi50ZW5zb3IxZChbMSwgMCwgMV0sICdib29sJyk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0Zi5ib29sZWFuTWFza0FzeW5jKGFycmF5LCBtYXNrKTtcbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsyXSk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsxLCAzXSk7XG4gICAgYXJyYXkuZGlzcG9zZSgpO1xuICAgIG1hc2suZGlzcG9zZSgpO1xuICAgIHJlc3VsdC5kaXNwb3NlKCk7XG5cbiAgICBjb25zdCBudW1UZW5zb3JzQWZ0ZXIgPSB0Zi5tZW1vcnkoKS5udW1UZW5zb3JzO1xuICAgIGV4cGVjdChudW1UZW5zb3JzQWZ0ZXIpLnRvQmUobnVtVGVuc29yc0JlZm9yZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdGhyb3cgaWYgbWFzayBpcyBzY2FsYXInLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYXJyYXkgPSB0Zi50ZW5zb3IyZChbMSwgMiwgMywgNCwgNSwgNl0sIFszLCAyXSk7XG4gICAgY29uc3QgbWFzayA9IHRmLnNjYWxhcigxLCAnYm9vbCcpO1xuICAgIGxldCBlcnJvck1lc3NhZ2UgPSAnTm8gZXJyb3IgdGhyb3duLic7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRmLmJvb2xlYW5NYXNrQXN5bmMoYXJyYXksIG1hc2spO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgIH1cbiAgICBleHBlY3QoZXJyb3JNZXNzYWdlKS50b0JlKCdtYXNrIGNhbm5vdCBiZSBzY2FsYXInKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBhcnJheSBhbmQgbWFzayBzaGFwZSBtaXNzIG1hdGNoJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGFycmF5ID0gdGYudGVuc29yMmQoWzEsIDIsIDMsIDQsIDUsIDZdLCBbMywgMl0pO1xuICAgIGNvbnN0IG1hc2sgPSB0Zi50ZW5zb3IyZChbMSwgMF0sIFsxLCAyXSwgJ2Jvb2wnKTtcbiAgICBsZXQgZXJyb3JNZXNzYWdlID0gJ05vIGVycm9yIHRocm93bi4nO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0Zi5ib29sZWFuTWFza0FzeW5jKGFycmF5LCBtYXNrKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IubWVzc2FnZTtcbiAgICB9XG4gICAgZXhwZWN0KGVycm9yTWVzc2FnZSlcbiAgICAgICAgLnRvQmUoXG4gICAgICAgICAgICBgbWFzaydzIHNoYXBlIG11c3QgbWF0Y2ggdGhlIGZpcnN0IEsgYCArXG4gICAgICAgICAgICBgZGltZW5zaW9ucyBvZiB0ZW5zb3IncyBzaGFwZSwgU2hhcGVzIDMsMiBhbmQgMSwyIG11c3QgbWF0Y2hgKTtcbiAgfSk7XG59KTtcbiJdfQ==