/**
|
* @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 { getTensorsInContainer, isTensorInList } from './tensor_util';
|
import { convertToTensor } from './tensor_util_env';
|
import { expectArraysClose, expectArraysEqual } from './test_util';
|
describeWithFlags('tensor_util.isTensorInList', ALL_ENVS, () => {
|
it('not in list', () => {
|
const a = tf.scalar(1);
|
const list = [tf.scalar(1), tf.tensor1d([1, 2, 3])];
|
expect(isTensorInList(a, list)).toBe(false);
|
});
|
it('in list', () => {
|
const a = tf.scalar(1);
|
const list = [tf.scalar(2), tf.tensor1d([1, 2, 3]), a];
|
expect(isTensorInList(a, list)).toBe(true);
|
});
|
});
|
describeWithFlags('getTensorsInContainer', ALL_ENVS, () => {
|
it('null input returns empty tensor', () => {
|
const results = getTensorsInContainer(null);
|
expect(results).toEqual([]);
|
});
|
it('tensor input returns one element tensor', () => {
|
const x = tf.scalar(1);
|
const results = getTensorsInContainer(x);
|
expect(results).toEqual([x]);
|
});
|
it('name tensor map returns flattened tensor', () => {
|
const x1 = tf.scalar(1);
|
const x2 = tf.scalar(3);
|
const x3 = tf.scalar(4);
|
const results = getTensorsInContainer({ x1, x2, x3 });
|
expect(results).toEqual([x1, x2, x3]);
|
});
|
it('can extract from arbitrary depth', () => {
|
const container = [
|
{ x: tf.scalar(1), y: tf.scalar(2) }, [[[tf.scalar(3)]], { z: tf.scalar(4) }]
|
];
|
const results = getTensorsInContainer(container);
|
expect(results.length).toBe(4);
|
});
|
it('works with loops in container', () => {
|
const container = [tf.scalar(1), tf.scalar(2), [tf.scalar(3)]];
|
const innerContainer = [container];
|
// tslint:disable-next-line:no-any
|
container.push(innerContainer);
|
const results = getTensorsInContainer(container);
|
expect(results.length).toBe(3);
|
});
|
});
|
describeWithFlags('convertToTensor', ALL_ENVS, () => {
|
it('primitive integer, NaN converts to zero, no error thrown', async () => {
|
const a = () => convertToTensor(NaN, 'a', 'test', 'int32');
|
expect(a).not.toThrowError();
|
const b = convertToTensor(NaN, 'b', 'test', 'int32');
|
expect(b.rank).toBe(0);
|
expect(b.dtype).toBe('int32');
|
expectArraysClose(await b.data(), 0);
|
});
|
it('primitive number', async () => {
|
const a = convertToTensor(3, 'a', 'test');
|
expect(a.rank).toBe(0);
|
expect(a.dtype).toBe('float32');
|
expectArraysClose(await a.data(), 3);
|
});
|
it('primitive integer, NaN converts to zero', async () => {
|
const a = convertToTensor(NaN, 'a', 'test', 'int32');
|
expect(a.rank).toBe(0);
|
expect(a.dtype).toBe('int32');
|
expectArraysClose(await a.data(), 0);
|
});
|
it('primitive boolean, parsed as bool tensor', async () => {
|
const a = convertToTensor(true, 'a', 'test');
|
expect(a.rank).toBe(0);
|
expect(a.dtype).toBe('bool');
|
expectArraysClose(await a.data(), 1);
|
});
|
it('primitive boolean, forced to be parsed as bool tensor', async () => {
|
const a = convertToTensor(true, 'a', 'test', 'bool');
|
expect(a.rank).toBe(0);
|
expect(a.dtype).toBe('bool');
|
expectArraysEqual(await a.data(), 1);
|
});
|
it('array1d', async () => {
|
const a = convertToTensor([1, 2, 3], 'a', 'test');
|
expect(a.rank).toBe(1);
|
expect(a.dtype).toBe('float32');
|
expect(a.shape).toEqual([3]);
|
expectArraysClose(await a.data(), [1, 2, 3]);
|
});
|
it('array2d', async () => {
|
const a = convertToTensor([[1], [2], [3]], 'a', 'test');
|
expect(a.rank).toBe(2);
|
expect(a.shape).toEqual([3, 1]);
|
expect(a.dtype).toBe('float32');
|
expectArraysClose(await a.data(), [1, 2, 3]);
|
});
|
it('array3d', async () => {
|
const a = convertToTensor([[[1], [2]], [[3], [4]]], 'a', 'test');
|
expect(a.rank).toBe(3);
|
expect(a.shape).toEqual([2, 2, 1]);
|
expect(a.dtype).toBe('float32');
|
expectArraysClose(await a.data(), [1, 2, 3, 4]);
|
});
|
it('array4d', async () => {
|
const a = convertToTensor([[[[1]], [[2]]], [[[3]], [[4]]]], 'a', 'test');
|
expect(a.rank).toBe(4);
|
expect(a.shape).toEqual([2, 2, 1, 1]);
|
expect(a.dtype).toBe('float32');
|
expectArraysClose(await a.data(), [1, 2, 3, 4]);
|
});
|
it('passing a tensor returns the tensor itself', () => {
|
const s = tf.scalar(3);
|
const res = convertToTensor(s, 'a', 'test');
|
expect(res === s).toBe(true);
|
});
|
it('passing a tensor with wrong type errors', () => {
|
const s = tf.scalar(3);
|
expect(() => convertToTensor(s, 'p', 'f', 'bool'))
|
.toThrowError(/Argument 'p' passed to 'f' must be bool tensor, but got float32/);
|
});
|
it('fails when passed a string and force numeric is true', () => {
|
const expectedDtype = 'numeric';
|
expect(() => convertToTensor('hello', 'p', 'test', expectedDtype))
|
.toThrowError();
|
});
|
it('force numeric is true by default', () => {
|
// Should fail to parse a string tensor since force numeric is true.
|
expect(() => convertToTensor('hello', 'p', 'test')).toThrowError();
|
});
|
it('primitive string, do not force numeric', () => {
|
const t = convertToTensor('hello', 'p', 'test', 'string_or_numeric');
|
expect(t.dtype).toBe('string');
|
expect(t.shape).toEqual([]);
|
});
|
it('string[], do not force numeric', () => {
|
const t = convertToTensor(['a', 'b', 'c'], 'p', 'test', 'string_or_numeric');
|
expect(t.dtype).toBe('string');
|
expect(t.shape).toEqual([3]);
|
});
|
it('string, explicitly parse as bool', () => {
|
expect(() => convertToTensor('a', 'argName', 'func', 'bool'))
|
.toThrowError('Argument \'argName\' passed to \'func\' must be bool tensor' +
|
', but got string tensor');
|
});
|
it('string, throw error if pass null.', () => {
|
expect(() => convertToTensor('a', 'argName', 'func', null))
|
.toThrowError('Expected dtype cannot be null.');
|
});
|
it('fails to convert a dict to tensor', () => {
|
expect(() => convertToTensor({}, 'a', 'test'))
|
.toThrowError('Argument \'a\' passed to \'test\' must be a Tensor ' +
|
'or TensorLike, but got \'Object\'');
|
});
|
it('fails to convert a string to tensor', () => {
|
expect(() => convertToTensor('asdf', 'a', 'test'))
|
.toThrowError('Argument \'a\' passed to \'test\' must be numeric tensor, ' +
|
'but got string tensor');
|
});
|
});
|
describeWithFlags('convertToTensor debug mode', ALL_ENVS, () => {
|
beforeAll(() => {
|
// Silence debug warnings.
|
spyOn(console, 'warn');
|
tf.enableDebugMode();
|
});
|
it('fails to convert a non-valid shape array to tensor', () => {
|
const a = [[1, 2], [3], [4, 5, 6]]; // 2nd element has only 1 entry.
|
expect(() => convertToTensor(a, 'a', 'test'))
|
.toThrowError('Element arr[1] should have 2 elements, but has 1 elements');
|
});
|
});
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuc29yX3V0aWxfdGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3RmanMtY29yZS9zcmMvdGVuc29yX3V0aWxfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0QsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGNBQWMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNwRSxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDbEQsT0FBTyxFQUFDLGlCQUFpQixFQUFFLGlCQUFpQixFQUFDLE1BQU0sYUFBYSxDQUFDO0FBRWpFLGlCQUFpQixDQUFDLDRCQUE0QixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDN0QsRUFBRSxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUU7UUFDckIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBYSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTlELE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDakIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBYSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVqRSxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsaUJBQWlCLENBQUMsdUJBQXVCLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRTtJQUN4RCxFQUFFLENBQUMsaUNBQWlDLEVBQUUsR0FBRyxFQUFFO1FBQ3pDLE1BQU0sT0FBTyxHQUFHLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTVDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO1FBQ2pELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxPQUFPLEdBQUcscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1FBQ2xELE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEIsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QixNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLE1BQU0sT0FBTyxHQUFHLHFCQUFxQixDQUFDLEVBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUMsQ0FBQyxDQUFDO1FBRXBELE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO1FBQzFDLE1BQU0sU0FBUyxHQUFHO1lBQ2hCLEVBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUM7U0FDMUUsQ0FBQztRQUNGLE1BQU0sT0FBTyxHQUFHLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLCtCQUErQixFQUFFLEdBQUcsRUFBRTtRQUN2QyxNQUFNLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sY0FBYyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkMsa0NBQWtDO1FBQ2xDLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBcUIsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sT0FBTyxHQUFHLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFSCxpQkFBaUIsQ0FBQyxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFO0lBQ2xELEVBQUUsQ0FBQywwREFBMEQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN4RSxNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDM0QsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUU3QixNQUFNLENBQUMsR0FBRyxlQUFlLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDckQsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDaEMsTUFBTSxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDMUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdkQsTUFBTSxDQUFDLEdBQUcsZUFBZSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3JELE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3hELE1BQU0sQ0FBQyxHQUFHLGVBQWUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzdDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHVEQUF1RCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3JFLE1BQU0sQ0FBQyxHQUFHLGVBQWUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNyRCxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN2QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdkIsTUFBTSxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbEQsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9DLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFNBQVMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2QixNQUFNLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN4RCxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9DLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFNBQVMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2QixNQUFNLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFNBQVMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2QixNQUFNLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3pFLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1FBQ3BELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxHQUFHLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDNUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO1FBQ2pELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQzthQUM3QyxZQUFZLENBQ1QsaUVBQWlFLENBQUMsQ0FBQztJQUM3RSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRSxHQUFHLEVBQUU7UUFDOUQsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUM7YUFDN0QsWUFBWSxFQUFFLENBQUM7SUFDdEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO1FBQzFDLG9FQUFvRTtRQUNwRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNyRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsTUFBTSxDQUFDLEdBQUcsZUFBZSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixDQUFDLENBQUM7UUFDckUsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO1FBQ3hDLE1BQU0sQ0FBQyxHQUNILGVBQWUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7UUFDMUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQzthQUN4RCxZQUFZLENBQ1QsNkRBQTZEO1lBQzdELHlCQUF5QixDQUFDLENBQUM7SUFDckMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDdEQsWUFBWSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7SUFDdEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsRUFBWSxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQzthQUNuRCxZQUFZLENBQ1QscURBQXFEO1lBQ3JELG1DQUFtQyxDQUFDLENBQUM7SUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMscUNBQXFDLEVBQUUsR0FBRyxFQUFFO1FBQzdDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQzthQUM3QyxZQUFZLENBQ1QsNERBQTREO1lBQzVELHVCQUF1QixDQUFDLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILGlCQUFpQixDQUFDLDRCQUE0QixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDN0QsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNiLDBCQUEwQjtRQUMxQixLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZCLEVBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN2QixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxvREFBb0QsRUFBRSxHQUFHLEVBQUU7UUFDNUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUUsZ0NBQWdDO1FBQ3JFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQzthQUN4QyxZQUFZLENBQ1QsMkRBQTJELENBQUMsQ0FBQztJQUN2RSxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuL2luZGV4JztcbmltcG9ydCB7QUxMX0VOVlMsIGRlc2NyaWJlV2l0aEZsYWdzfSBmcm9tICcuL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRUZW5zb3JzSW5Db250YWluZXIsIGlzVGVuc29ySW5MaXN0fSBmcm9tICcuL3RlbnNvcl91dGlsJztcbmltcG9ydCB7Y29udmVydFRvVGVuc29yfSBmcm9tICcuL3RlbnNvcl91dGlsX2Vudic7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlLCBleHBlY3RBcnJheXNFcXVhbH0gZnJvbSAnLi90ZXN0X3V0aWwnO1xuXG5kZXNjcmliZVdpdGhGbGFncygndGVuc29yX3V0aWwuaXNUZW5zb3JJbkxpc3QnLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnbm90IGluIGxpc3QnLCAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnNjYWxhcigxKTtcbiAgICBjb25zdCBsaXN0OiBUZW5zb3JbXSA9IFt0Zi5zY2FsYXIoMSksIHRmLnRlbnNvcjFkKFsxLCAyLCAzXSldO1xuXG4gICAgZXhwZWN0KGlzVGVuc29ySW5MaXN0KGEsIGxpc3QpKS50b0JlKGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ2luIGxpc3QnLCAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnNjYWxhcigxKTtcbiAgICBjb25zdCBsaXN0OiBUZW5zb3JbXSA9IFt0Zi5zY2FsYXIoMiksIHRmLnRlbnNvcjFkKFsxLCAyLCAzXSksIGFdO1xuXG4gICAgZXhwZWN0KGlzVGVuc29ySW5MaXN0KGEsIGxpc3QpKS50b0JlKHRydWUpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZVdpdGhGbGFncygnZ2V0VGVuc29yc0luQ29udGFpbmVyJywgQUxMX0VOVlMsICgpID0+IHtcbiAgaXQoJ251bGwgaW5wdXQgcmV0dXJucyBlbXB0eSB0ZW5zb3InLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGdldFRlbnNvcnNJbkNvbnRhaW5lcihudWxsKTtcblxuICAgIGV4cGVjdChyZXN1bHRzKS50b0VxdWFsKFtdKTtcbiAgfSk7XG5cbiAgaXQoJ3RlbnNvciBpbnB1dCByZXR1cm5zIG9uZSBlbGVtZW50IHRlbnNvcicsICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGYuc2NhbGFyKDEpO1xuICAgIGNvbnN0IHJlc3VsdHMgPSBnZXRUZW5zb3JzSW5Db250YWluZXIoeCk7XG5cbiAgICBleHBlY3QocmVzdWx0cykudG9FcXVhbChbeF0pO1xuICB9KTtcblxuICBpdCgnbmFtZSB0ZW5zb3IgbWFwIHJldHVybnMgZmxhdHRlbmVkIHRlbnNvcicsICgpID0+IHtcbiAgICBjb25zdCB4MSA9IHRmLnNjYWxhcigxKTtcbiAgICBjb25zdCB4MiA9IHRmLnNjYWxhcigzKTtcbiAgICBjb25zdCB4MyA9IHRmLnNjYWxhcig0KTtcbiAgICBjb25zdCByZXN1bHRzID0gZ2V0VGVuc29yc0luQ29udGFpbmVyKHt4MSwgeDIsIHgzfSk7XG5cbiAgICBleHBlY3QocmVzdWx0cykudG9FcXVhbChbeDEsIHgyLCB4M10pO1xuICB9KTtcblxuICBpdCgnY2FuIGV4dHJhY3QgZnJvbSBhcmJpdHJhcnkgZGVwdGgnLCAoKSA9PiB7XG4gICAgY29uc3QgY29udGFpbmVyID0gW1xuICAgICAge3g6IHRmLnNjYWxhcigxKSwgeTogdGYuc2NhbGFyKDIpfSwgW1tbdGYuc2NhbGFyKDMpXV0sIHt6OiB0Zi5zY2FsYXIoNCl9XVxuICAgIF07XG4gICAgY29uc3QgcmVzdWx0cyA9IGdldFRlbnNvcnNJbkNvbnRhaW5lcihjb250YWluZXIpO1xuICAgIGV4cGVjdChyZXN1bHRzLmxlbmd0aCkudG9CZSg0KTtcbiAgfSk7XG5cbiAgaXQoJ3dvcmtzIHdpdGggbG9vcHMgaW4gY29udGFpbmVyJywgKCkgPT4ge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IFt0Zi5zY2FsYXIoMSksIHRmLnNjYWxhcigyKSwgW3RmLnNjYWxhcigzKV1dO1xuICAgIGNvbnN0IGlubmVyQ29udGFpbmVyID0gW2NvbnRhaW5lcl07XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIGNvbnRhaW5lci5wdXNoKGlubmVyQ29udGFpbmVyIGFzIGFueSk7XG4gICAgY29uc3QgcmVzdWx0cyA9IGdldFRlbnNvcnNJbkNvbnRhaW5lcihjb250YWluZXIpO1xuICAgIGV4cGVjdChyZXN1bHRzLmxlbmd0aCkudG9CZSgzKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ2NvbnZlcnRUb1RlbnNvcicsIEFMTF9FTlZTLCAoKSA9PiB7XG4gIGl0KCdwcmltaXRpdmUgaW50ZWdlciwgTmFOIGNvbnZlcnRzIHRvIHplcm8sIG5vIGVycm9yIHRocm93bicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gKCkgPT4gY29udmVydFRvVGVuc29yKE5hTiwgJ2EnLCAndGVzdCcsICdpbnQzMicpO1xuICAgIGV4cGVjdChhKS5ub3QudG9UaHJvd0Vycm9yKCk7XG5cbiAgICBjb25zdCBiID0gY29udmVydFRvVGVuc29yKE5hTiwgJ2InLCAndGVzdCcsICdpbnQzMicpO1xuICAgIGV4cGVjdChiLnJhbmspLnRvQmUoMCk7XG4gICAgZXhwZWN0KGIuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIDApO1xuICB9KTtcblxuICBpdCgncHJpbWl0aXZlIG51bWJlcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gY29udmVydFRvVGVuc29yKDMsICdhJywgJ3Rlc3QnKTtcbiAgICBleHBlY3QoYS5yYW5rKS50b0JlKDApO1xuICAgIGV4cGVjdChhLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYS5kYXRhKCksIDMpO1xuICB9KTtcblxuICBpdCgncHJpbWl0aXZlIGludGVnZXIsIE5hTiBjb252ZXJ0cyB0byB6ZXJvJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBjb252ZXJ0VG9UZW5zb3IoTmFOLCAnYScsICd0ZXN0JywgJ2ludDMyJyk7XG4gICAgZXhwZWN0KGEucmFuaykudG9CZSgwKTtcbiAgICBleHBlY3QoYS5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBhLmRhdGEoKSwgMCk7XG4gIH0pO1xuXG4gIGl0KCdwcmltaXRpdmUgYm9vbGVhbiwgcGFyc2VkIGFzIGJvb2wgdGVuc29yJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBjb252ZXJ0VG9UZW5zb3IodHJ1ZSwgJ2EnLCAndGVzdCcpO1xuICAgIGV4cGVjdChhLnJhbmspLnRvQmUoMCk7XG4gICAgZXhwZWN0KGEuZHR5cGUpLnRvQmUoJ2Jvb2wnKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBhLmRhdGEoKSwgMSk7XG4gIH0pO1xuXG4gIGl0KCdwcmltaXRpdmUgYm9vbGVhbiwgZm9yY2VkIHRvIGJlIHBhcnNlZCBhcyBib29sIHRlbnNvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gY29udmVydFRvVGVuc29yKHRydWUsICdhJywgJ3Rlc3QnLCAnYm9vbCcpO1xuICAgIGV4cGVjdChhLnJhbmspLnRvQmUoMCk7XG4gICAgZXhwZWN0KGEuZHR5cGUpLnRvQmUoJ2Jvb2wnKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCBhLmRhdGEoKSwgMSk7XG4gIH0pO1xuXG4gIGl0KCdhcnJheTFkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBjb252ZXJ0VG9UZW5zb3IoWzEsIDIsIDNdLCAnYScsICd0ZXN0Jyk7XG4gICAgZXhwZWN0KGEucmFuaykudG9CZSgxKTtcbiAgICBleHBlY3QoYS5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdChhLnNoYXBlKS50b0VxdWFsKFszXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYS5kYXRhKCksIFsxLCAyLCAzXSk7XG4gIH0pO1xuXG4gIGl0KCdhcnJheTJkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBjb252ZXJ0VG9UZW5zb3IoW1sxXSwgWzJdLCBbM11dLCAnYScsICd0ZXN0Jyk7XG4gICAgZXhwZWN0KGEucmFuaykudG9CZSgyKTtcbiAgICBleHBlY3QoYS5zaGFwZSkudG9FcXVhbChbMywgMV0pO1xuICAgIGV4cGVjdChhLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYS5kYXRhKCksIFsxLCAyLCAzXSk7XG4gIH0pO1xuXG4gIGl0KCdhcnJheTNkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBjb252ZXJ0VG9UZW5zb3IoW1tbMV0sIFsyXV0sIFtbM10sIFs0XV1dLCAnYScsICd0ZXN0Jyk7XG4gICAgZXhwZWN0KGEucmFuaykudG9CZSgzKTtcbiAgICBleHBlY3QoYS5zaGFwZSkudG9FcXVhbChbMiwgMiwgMV0pO1xuICAgIGV4cGVjdChhLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYS5kYXRhKCksIFsxLCAyLCAzLCA0XSk7XG4gIH0pO1xuXG4gIGl0KCdhcnJheTRkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBjb252ZXJ0VG9UZW5zb3IoW1tbWzFdXSwgW1syXV1dLCBbW1szXV0sIFtbNF1dXV0sICdhJywgJ3Rlc3QnKTtcbiAgICBleHBlY3QoYS5yYW5rKS50b0JlKDQpO1xuICAgIGV4cGVjdChhLnNoYXBlKS50b0VxdWFsKFsyLCAyLCAxLCAxXSk7XG4gICAgZXhwZWN0KGEuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBhLmRhdGEoKSwgWzEsIDIsIDMsIDRdKTtcbiAgfSk7XG5cbiAgaXQoJ3Bhc3NpbmcgYSB0ZW5zb3IgcmV0dXJucyB0aGUgdGVuc29yIGl0c2VsZicsICgpID0+IHtcbiAgICBjb25zdCBzID0gdGYuc2NhbGFyKDMpO1xuICAgIGNvbnN0IHJlcyA9IGNvbnZlcnRUb1RlbnNvcihzLCAnYScsICd0ZXN0Jyk7XG4gICAgZXhwZWN0KHJlcyA9PT0gcykudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3Bhc3NpbmcgYSB0ZW5zb3Igd2l0aCB3cm9uZyB0eXBlIGVycm9ycycsICgpID0+IHtcbiAgICBjb25zdCBzID0gdGYuc2NhbGFyKDMpO1xuICAgIGV4cGVjdCgoKSA9PiBjb252ZXJ0VG9UZW5zb3IocywgJ3AnLCAnZicsICdib29sJykpXG4gICAgICAgIC50b1Rocm93RXJyb3IoXG4gICAgICAgICAgICAvQXJndW1lbnQgJ3AnIHBhc3NlZCB0byAnZicgbXVzdCBiZSBib29sIHRlbnNvciwgYnV0IGdvdCBmbG9hdDMyLyk7XG4gIH0pO1xuXG4gIGl0KCdmYWlscyB3aGVuIHBhc3NlZCBhIHN0cmluZyBhbmQgZm9yY2UgbnVtZXJpYyBpcyB0cnVlJywgKCkgPT4ge1xuICAgIGNvbnN0IGV4cGVjdGVkRHR5cGUgPSAnbnVtZXJpYyc7XG4gICAgZXhwZWN0KCgpID0+IGNvbnZlcnRUb1RlbnNvcignaGVsbG8nLCAncCcsICd0ZXN0JywgZXhwZWN0ZWREdHlwZSkpXG4gICAgICAgIC50b1Rocm93RXJyb3IoKTtcbiAgfSk7XG5cbiAgaXQoJ2ZvcmNlIG51bWVyaWMgaXMgdHJ1ZSBieSBkZWZhdWx0JywgKCkgPT4ge1xuICAgIC8vIFNob3VsZCBmYWlsIHRvIHBhcnNlIGEgc3RyaW5nIHRlbnNvciBzaW5jZSBmb3JjZSBudW1lcmljIGlzIHRydWUuXG4gICAgZXhwZWN0KCgpID0+IGNvbnZlcnRUb1RlbnNvcignaGVsbG8nLCAncCcsICd0ZXN0JykpLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgncHJpbWl0aXZlIHN0cmluZywgZG8gbm90IGZvcmNlIG51bWVyaWMnLCAoKSA9PiB7XG4gICAgY29uc3QgdCA9IGNvbnZlcnRUb1RlbnNvcignaGVsbG8nLCAncCcsICd0ZXN0JywgJ3N0cmluZ19vcl9udW1lcmljJyk7XG4gICAgZXhwZWN0KHQuZHR5cGUpLnRvQmUoJ3N0cmluZycpO1xuICAgIGV4cGVjdCh0LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgfSk7XG5cbiAgaXQoJ3N0cmluZ1tdLCBkbyBub3QgZm9yY2UgbnVtZXJpYycsICgpID0+IHtcbiAgICBjb25zdCB0ID1cbiAgICAgICAgY29udmVydFRvVGVuc29yKFsnYScsICdiJywgJ2MnXSwgJ3AnLCAndGVzdCcsICdzdHJpbmdfb3JfbnVtZXJpYycpO1xuICAgIGV4cGVjdCh0LmR0eXBlKS50b0JlKCdzdHJpbmcnKTtcbiAgICBleHBlY3QodC5zaGFwZSkudG9FcXVhbChbM10pO1xuICB9KTtcblxuICBpdCgnc3RyaW5nLCBleHBsaWNpdGx5IHBhcnNlIGFzIGJvb2wnLCAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IGNvbnZlcnRUb1RlbnNvcignYScsICdhcmdOYW1lJywgJ2Z1bmMnLCAnYm9vbCcpKVxuICAgICAgICAudG9UaHJvd0Vycm9yKFxuICAgICAgICAgICAgJ0FyZ3VtZW50IFxcJ2FyZ05hbWVcXCcgcGFzc2VkIHRvIFxcJ2Z1bmNcXCcgbXVzdCBiZSBib29sIHRlbnNvcicgK1xuICAgICAgICAgICAgJywgYnV0IGdvdCBzdHJpbmcgdGVuc29yJyk7XG4gIH0pO1xuXG4gIGl0KCdzdHJpbmcsIHRocm93IGVycm9yIGlmIHBhc3MgbnVsbC4nLCAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IGNvbnZlcnRUb1RlbnNvcignYScsICdhcmdOYW1lJywgJ2Z1bmMnLCBudWxsKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcignRXhwZWN0ZWQgZHR5cGUgY2Fubm90IGJlIG51bGwuJyk7XG4gIH0pO1xuXG4gIGl0KCdmYWlscyB0byBjb252ZXJ0IGEgZGljdCB0byB0ZW5zb3InLCAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IGNvbnZlcnRUb1RlbnNvcih7fSBhcyBudW1iZXIsICdhJywgJ3Rlc3QnKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcihcbiAgICAgICAgICAgICdBcmd1bWVudCBcXCdhXFwnIHBhc3NlZCB0byBcXCd0ZXN0XFwnIG11c3QgYmUgYSBUZW5zb3IgJyArXG4gICAgICAgICAgICAnb3IgVGVuc29yTGlrZSwgYnV0IGdvdCBcXCdPYmplY3RcXCcnKTtcbiAgfSk7XG5cbiAgaXQoJ2ZhaWxzIHRvIGNvbnZlcnQgYSBzdHJpbmcgdG8gdGVuc29yJywgKCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PiBjb252ZXJ0VG9UZW5zb3IoJ2FzZGYnLCAnYScsICd0ZXN0JykpXG4gICAgICAgIC50b1Rocm93RXJyb3IoXG4gICAgICAgICAgICAnQXJndW1lbnQgXFwnYVxcJyBwYXNzZWQgdG8gXFwndGVzdFxcJyBtdXN0IGJlIG51bWVyaWMgdGVuc29yLCAnICtcbiAgICAgICAgICAgICdidXQgZ290IHN0cmluZyB0ZW5zb3InKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ2NvbnZlcnRUb1RlbnNvciBkZWJ1ZyBtb2RlJywgQUxMX0VOVlMsICgpID0+IHtcbiAgYmVmb3JlQWxsKCgpID0+IHtcbiAgICAvLyBTaWxlbmNlIGRlYnVnIHdhcm5pbmdzLlxuICAgIHNweU9uKGNvbnNvbGUsICd3YXJuJyk7XG4gICAgdGYuZW5hYmxlRGVidWdNb2RlKCk7XG4gIH0pO1xuXG4gIGl0KCdmYWlscyB0byBjb252ZXJ0IGEgbm9uLXZhbGlkIHNoYXBlIGFycmF5IHRvIHRlbnNvcicsICgpID0+IHtcbiAgICBjb25zdCBhID0gW1sxLCAyXSwgWzNdLCBbNCwgNSwgNl1dOyAgLy8gMm5kIGVsZW1lbnQgaGFzIG9ubHkgMSBlbnRyeS5cbiAgICBleHBlY3QoKCkgPT4gY29udmVydFRvVGVuc29yKGEsICdhJywgJ3Rlc3QnKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcihcbiAgICAgICAgICAgICdFbGVtZW50IGFyclsxXSBzaG91bGQgaGF2ZSAyIGVsZW1lbnRzLCBidXQgaGFzIDEgZWxlbWVudHMnKTtcbiAgfSk7XG59KTtcbiJdfQ==
|