/**
|
* @license
|
* Copyright 2017 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 { Variable } from './tensor';
|
import { expectArraysClose } from './test_util';
|
describeWithFlags('variable', ALL_ENVS, () => {
|
it('simple assign', async () => {
|
const v = tf.variable(tf.tensor1d([1, 2, 3]));
|
expectArraysClose(await v.data(), [1, 2, 3]);
|
v.assign(tf.tensor1d([4, 5, 6]));
|
expectArraysClose(await v.data(), [4, 5, 6]);
|
});
|
it('simple chain assign', async () => {
|
const v = tf.tensor1d([1, 2, 3]).variable();
|
expectArraysClose(await v.data(), [1, 2, 3]);
|
v.assign(tf.tensor1d([4, 5, 6]));
|
expectArraysClose(await v.data(), [4, 5, 6]);
|
});
|
it('default names are unique', () => {
|
const v = tf.variable(tf.tensor1d([1, 2, 3]));
|
expect(v.name).not.toBeNull();
|
const v2 = tf.variable(tf.tensor1d([1, 2, 3]));
|
expect(v2.name).not.toBeNull();
|
expect(v.name).not.toBe(v2.name);
|
});
|
it('user provided name', () => {
|
const v = tf.variable(tf.tensor1d([1, 2, 3]), true, 'myName');
|
expect(v.name).toBe('myName');
|
});
|
it('if name already used, throw error', () => {
|
tf.variable(tf.tensor1d([1, 2, 3]), true, 'myName');
|
expect(() => tf.variable(tf.tensor1d([1, 2, 3]), true, 'myName'))
|
.toThrowError();
|
});
|
it('ops can take variables', async () => {
|
const value = tf.tensor1d([1, 2, 3]);
|
const v = tf.variable(value);
|
const res = tf.sum(v);
|
expectArraysClose(await res.data(), [6]);
|
});
|
it('chained variables works', async () => {
|
const v = tf.tensor1d([1, 2, 3]).variable();
|
const res = tf.sum(v);
|
expectArraysClose(await res.data(), [6]);
|
});
|
it('variables are not affected by tidy', async () => {
|
let v;
|
expect(tf.memory().numTensors).toBe(0);
|
tf.tidy(() => {
|
const value = tf.tensor1d([1, 2, 3], 'float32');
|
expect(tf.memory().numTensors).toBe(1);
|
v = tf.variable(value);
|
expect(tf.memory().numTensors).toBe(2);
|
});
|
expect(tf.memory().numTensors).toBe(1);
|
expectArraysClose(await v.data(), [1, 2, 3]);
|
v.dispose();
|
expect(tf.memory().numTensors).toBe(0);
|
});
|
it('disposing a named variable allows creating new named variable', () => {
|
const numTensors = tf.memory().numTensors;
|
const t = tf.scalar(1);
|
const varName = 'var';
|
const v = tf.variable(t, true, varName);
|
expect(tf.memory().numTensors).toBe(numTensors + 2);
|
v.dispose();
|
t.dispose();
|
expect(tf.memory().numTensors).toBe(numTensors);
|
// Create another variable with the same name.
|
const t2 = tf.scalar(1);
|
const v2 = tf.variable(t2, true, varName);
|
expect(tf.memory().numTensors).toBe(numTensors + 2);
|
t2.dispose();
|
v2.dispose();
|
expect(tf.memory().numTensors).toBe(numTensors);
|
});
|
it('double disposing a variable works', () => {
|
const numTensors = tf.memory().numTensors;
|
const t = tf.scalar(1);
|
const v = tf.variable(t);
|
expect(tf.memory().numTensors).toBe(numTensors + 2);
|
t.dispose();
|
v.dispose();
|
expect(tf.memory().numTensors).toBe(numTensors);
|
// Double dispose the variable.
|
v.dispose();
|
expect(tf.memory().numTensors).toBe(numTensors);
|
});
|
it('constructor does not dispose', async () => {
|
const a = tf.scalar(2);
|
const v = tf.variable(a);
|
expect(tf.memory().numTensors).toBe(2);
|
expect(tf.memory().numDataBuffers).toBe(1);
|
expectArraysClose(await v.data(), [2]);
|
expectArraysClose(await a.data(), [2]);
|
});
|
it('variables are assignable to tensors', () => {
|
// This test asserts compilation, not doing any run-time assertion.
|
const x0 = null;
|
const y0 = x0;
|
expect(y0).toBeNull();
|
const x1 = null;
|
const y1 = x1;
|
expect(y1).toBeNull();
|
const x2 = null;
|
const y2 = x2;
|
expect(y2).toBeNull();
|
const x3 = null;
|
const y3 = x3;
|
expect(y3).toBeNull();
|
const x4 = null;
|
const y4 = x4;
|
expect(y4).toBeNull();
|
const xh = null;
|
const yh = xh;
|
expect(yh).toBeNull();
|
});
|
it('assign does not dispose old data', async () => {
|
let v;
|
v = tf.variable(tf.tensor1d([1, 2, 3]));
|
expect(tf.memory().numTensors).toBe(2);
|
expect(tf.memory().numDataBuffers).toBe(1);
|
expectArraysClose(await v.data(), [1, 2, 3]);
|
const secondArray = tf.tensor1d([4, 5, 6]);
|
expect(tf.memory().numTensors).toBe(3);
|
expect(tf.memory().numDataBuffers).toBe(2);
|
v.assign(secondArray);
|
expectArraysClose(await v.data(), [4, 5, 6]);
|
// Assign doesn't dispose the 1st array.
|
expect(tf.memory().numTensors).toBe(3);
|
expect(tf.memory().numDataBuffers).toBe(2);
|
v.dispose();
|
// Disposing the variable disposes itself. The input to variable and
|
// secondArray are the only remaining tensors.
|
expect(tf.memory().numTensors).toBe(2);
|
expect(tf.memory().numDataBuffers).toBe(2);
|
});
|
it('shape must match', () => {
|
const v = tf.variable(tf.tensor1d([1, 2, 3]));
|
expect(() => v.assign(tf.tensor1d([1, 2]))).toThrowError();
|
// tslint:disable-next-line:no-any
|
expect(() => v.assign(tf.tensor2d([3, 4], [1, 2]))).toThrowError();
|
});
|
it('dtype must match', () => {
|
const v = tf.variable(tf.tensor1d([1, 2, 3]));
|
// tslint:disable-next-line:no-any
|
expect(() => v.assign(tf.tensor1d([1, 1, 1], 'int32')))
|
.toThrowError();
|
// tslint:disable-next-line:no-any
|
expect(() => v.assign(tf.tensor1d([true, false, true], 'bool')))
|
.toThrowError();
|
});
|
});
|
describeWithFlags('x instanceof Variable', ALL_ENVS, () => {
|
it('x: Variable', () => {
|
const t = tf.variable(tf.scalar(1));
|
expect(t instanceof Variable).toBe(true);
|
});
|
it('x: other object, fails', () => {
|
const t = { something: 'else' };
|
expect(t instanceof Variable).toBe(false);
|
});
|
it('x: Tensor, fails', () => {
|
const t = tf.scalar(1);
|
expect(t instanceof Variable).toBe(false);
|
});
|
});
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFyaWFibGVfdGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3RmanMtY29yZS9zcmMvdmFyaWFibGVfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0QsT0FBTyxFQUF5RCxRQUFRLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDMUYsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sYUFBYSxDQUFDO0FBRzlDLGlCQUFpQixDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFO0lBQzNDLEVBQUUsQ0FBQyxlQUFlLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDN0IsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFN0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMscUJBQXFCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbkMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM1QyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3QyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUU7UUFDbEMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFOUIsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0MsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDL0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxv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QyxNQUFNLENBQUMsR0FBRyxFQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUMsQ0FBQztRQUM5QixNQUFNLENBQUMsQ0FBQyxZQUFZLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxHQUFHLEVBQUU7UUFDMUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxZQUFZLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuL2luZGV4JztcbmltcG9ydCB7QUxMX0VOVlMsIGRlc2NyaWJlV2l0aEZsYWdzfSBmcm9tICcuL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge1NjYWxhciwgVGVuc29yLCBUZW5zb3IxRCwgVGVuc29yMkQsIFRlbnNvcjNELCBUZW5zb3I0RCwgVmFyaWFibGV9IGZyb20gJy4vdGVuc29yJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4vdGVzdF91dGlsJztcbmltcG9ydCB7UmFua30gZnJvbSAnLi90eXBlcyc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCd2YXJpYWJsZScsIEFMTF9FTlZTLCAoKSA9PiB7XG4gIGl0KCdzaW1wbGUgYXNzaWduJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHYgPSB0Zi52YXJpYWJsZSh0Zi50ZW5zb3IxZChbMSwgMiwgM10pKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB2LmRhdGEoKSwgWzEsIDIsIDNdKTtcblxuICAgIHYuYXNzaWduKHRmLnRlbnNvcjFkKFs0LCA1LCA2XSkpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHYuZGF0YSgpLCBbNCwgNSwgNl0pO1xuICB9KTtcblxuICBpdCgnc2ltcGxlIGNoYWluIGFzc2lnbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB2ID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKS52YXJpYWJsZSgpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHYuZGF0YSgpLCBbMSwgMiwgM10pO1xuXG4gICAgdi5hc3NpZ24odGYudGVuc29yMWQoWzQsIDUsIDZdKSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdi5kYXRhKCksIFs0LCA1LCA2XSk7XG4gIH0pO1xuXG4gIGl0KCdkZWZhdWx0IG5hbWVzIGFyZSB1bmlxdWUnLCAoKSA9PiB7XG4gICAgY29uc3QgdiA9IHRmLnZhcmlhYmxlKHRmLnRlbnNvcjFkKFsxLCAyLCAzXSkpO1xuICAgIGV4cGVjdCh2Lm5hbWUpLm5vdC50b0JlTnVsbCgpO1xuXG4gICAgY29uc3QgdjIgPSB0Zi52YXJpYWJsZSh0Zi50ZW5zb3IxZChbMSwgMiwgM10pKTtcbiAgICBleHBlY3QodjIubmFtZSkubm90LnRvQmVOdWxsKCk7XG4gICAgZXhwZWN0KHYubmFtZSkubm90LnRvQmUodjIubmFtZSk7XG4gIH0pO1xuXG4gIGl0KCd1c2VyIHByb3ZpZGVkIG5hbWUnLCAoKSA9PiB7XG4gICAgY29uc3QgdiA9IHRmLnZhcmlhYmxlKHRmLnRlbnNvcjFkKFsxLCAyLCAzXSksIHRydWUsICdteU5hbWUnKTtcbiAgICBleHBlY3Qodi5uYW1lKS50b0JlKCdteU5hbWUnKTtcbiAgfSk7XG5cbiAgaXQoJ2lmIG5hbWUgYWxyZWFkeSB1c2VkLCB0aHJvdyBlcnJvcicsICgpID0+IHtcbiAgICB0Zi52YXJpYWJsZSh0Zi50ZW5zb3IxZChbMSwgMiwgM10pLCB0cnVlLCAnbXlOYW1lJyk7XG4gICAgZXhwZWN0KCgpID0+IHRmLnZhcmlhYmxlKHRmLnRlbnNvcjFkKFsxLCAyLCAzXSksIHRydWUsICdteU5hbWUnKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgnb3BzIGNhbiB0YWtlIHZhcmlhYmxlcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzXSk7XG4gICAgY29uc3QgdiA9IHRmLnZhcmlhYmxlKHZhbHVlKTtcbiAgICBjb25zdCByZXMgPSB0Zi5zdW0odik7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzLmRhdGEoKSwgWzZdKTtcbiAgfSk7XG5cbiAgaXQoJ2NoYWluZWQgdmFyaWFibGVzIHdvcmtzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHYgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pLnZhcmlhYmxlKCk7XG4gICAgY29uc3QgcmVzID0gdGYuc3VtKHYpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlcy5kYXRhKCksIFs2XSk7XG4gIH0pO1xuXG4gIGl0KCd2YXJpYWJsZXMgYXJlIG5vdCBhZmZlY3RlZCBieSB0aWR5JywgYXN5bmMgKCkgPT4ge1xuICAgIGxldCB2OiBWYXJpYWJsZTxSYW5rLlIxPjtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgwKTtcblxuICAgIHRmLnRpZHkoKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10sICdmbG9hdDMyJyk7XG4gICAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgxKTtcblxuICAgICAgdiA9IHRmLnZhcmlhYmxlKHZhbHVlKTtcbiAgICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKDIpO1xuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdi5kYXRhKCksIFsxLCAyLCAzXSk7XG5cbiAgICB2LmRpc3Bvc2UoKTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgwKTtcbiAgfSk7XG5cbiAgaXQoJ2Rpc3Bvc2luZyBhIG5hbWVkIHZhcmlhYmxlIGFsbG93cyBjcmVhdGluZyBuZXcgbmFtZWQgdmFyaWFibGUnLCAoKSA9PiB7XG4gICAgY29uc3QgbnVtVGVuc29ycyA9IHRmLm1lbW9yeSgpLm51bVRlbnNvcnM7XG4gICAgY29uc3QgdCA9IHRmLnNjYWxhcigxKTtcbiAgICBjb25zdCB2YXJOYW1lID0gJ3Zhcic7XG4gICAgY29uc3QgdiA9IHRmLnZhcmlhYmxlKHQsIHRydWUsIHZhck5hbWUpO1xuXG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUobnVtVGVuc29ycyArIDIpO1xuXG4gICAgdi5kaXNwb3NlKCk7XG4gICAgdC5kaXNwb3NlKCk7XG5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZShudW1UZW5zb3JzKTtcblxuICAgIC8vIENyZWF0ZSBhbm90aGVyIHZhcmlhYmxlIHdpdGggdGhlIHNhbWUgbmFtZS5cbiAgICBjb25zdCB0MiA9IHRmLnNjYWxhcigxKTtcbiAgICBjb25zdCB2MiA9IHRmLnZhcmlhYmxlKHQyLCB0cnVlLCB2YXJOYW1lKTtcblxuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0JlKG51bVRlbnNvcnMgKyAyKTtcblxuICAgIHQyLmRpc3Bvc2UoKTtcbiAgICB2Mi5kaXNwb3NlKCk7XG5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZShudW1UZW5zb3JzKTtcbiAgfSk7XG5cbiAgaXQoJ2RvdWJsZSBkaXNwb3NpbmcgYSB2YXJpYWJsZSB3b3JrcycsICgpID0+IHtcbiAgICBjb25zdCBudW1UZW5zb3JzID0gdGYubWVtb3J5KCkubnVtVGVuc29ycztcblxuICAgIGNvbnN0IHQgPSB0Zi5zY2FsYXIoMSk7XG4gICAgY29uc3QgdiA9IHRmLnZhcmlhYmxlKHQpO1xuXG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUobnVtVGVuc29ycyArIDIpO1xuXG4gICAgdC5kaXNwb3NlKCk7XG4gICAgdi5kaXNwb3NlKCk7XG5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZShudW1UZW5zb3JzKTtcblxuICAgIC8vIERvdWJsZSBkaXNwb3NlIHRoZSB2YXJpYWJsZS5cbiAgICB2LmRpc3Bvc2UoKTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZShudW1UZW5zb3JzKTtcbiAgfSk7XG5cbiAgaXQoJ2NvbnN0cnVjdG9yIGRvZXMgbm90IGRpc3Bvc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnNjYWxhcigyKTtcbiAgICBjb25zdCB2ID0gdGYudmFyaWFibGUoYSk7XG5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgyKTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtRGF0YUJ1ZmZlcnMpLnRvQmUoMSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdi5kYXRhKCksIFsyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYS5kYXRhKCksIFsyXSk7XG4gIH0pO1xuXG4gIGl0KCd2YXJpYWJsZXMgYXJlIGFzc2lnbmFibGUgdG8gdGVuc29ycycsICgpID0+IHtcbiAgICAvLyBUaGlzIHRlc3QgYXNzZXJ0cyBjb21waWxhdGlvbiwgbm90IGRvaW5nIGFueSBydW4tdGltZSBhc3NlcnRpb24uXG4gICAgY29uc3QgeDA6IFZhcmlhYmxlPFJhbmsuUjA+ID0gbnVsbDtcbiAgICBjb25zdCB5MDogU2NhbGFyID0geDA7XG4gICAgZXhwZWN0KHkwKS50b0JlTnVsbCgpO1xuXG4gICAgY29uc3QgeDE6IFZhcmlhYmxlPFJhbmsuUjE+ID0gbnVsbDtcbiAgICBjb25zdCB5MTogVGVuc29yMUQgPSB4MTtcbiAgICBleHBlY3QoeTEpLnRvQmVOdWxsKCk7XG5cbiAgICBjb25zdCB4MjogVmFyaWFibGU8UmFuay5SMj4gPSBudWxsO1xuICAgIGNvbnN0IHkyOiBUZW5zb3IyRCA9IHgyO1xuICAgIGV4cGVjdCh5MikudG9CZU51bGwoKTtcblxuICAgIGNvbnN0IHgzOiBWYXJpYWJsZTxSYW5rLlIzPiA9IG51bGw7XG4gICAgY29uc3QgeTM6IFRlbnNvcjNEID0geDM7XG4gICAgZXhwZWN0KHkzKS50b0JlTnVsbCgpO1xuXG4gICAgY29uc3QgeDQ6IFZhcmlhYmxlPFJhbmsuUjQ+ID0gbnVsbDtcbiAgICBjb25zdCB5NDogVGVuc29yNEQgPSB4NDtcbiAgICBleHBlY3QoeTQpLnRvQmVOdWxsKCk7XG5cbiAgICBjb25zdCB4aDogVmFyaWFibGUgPSBudWxsO1xuICAgIGNvbnN0IHloOiBUZW5zb3IgPSB4aDtcbiAgICBleHBlY3QoeWgpLnRvQmVOdWxsKCk7XG4gIH0pO1xuXG4gIGl0KCdhc3NpZ24gZG9lcyBub3QgZGlzcG9zZSBvbGQgZGF0YScsIGFzeW5jICgpID0+IHtcbiAgICBsZXQgdjogVmFyaWFibGU8UmFuay5SMT47XG4gICAgdiA9IHRmLnZhcmlhYmxlKHRmLnRlbnNvcjFkKFsxLCAyLCAzXSkpO1xuXG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMik7XG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bURhdGFCdWZmZXJzKS50b0JlKDEpO1xuXG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdi5kYXRhKCksIFsxLCAyLCAzXSk7XG5cbiAgICBjb25zdCBzZWNvbmRBcnJheSA9IHRmLnRlbnNvcjFkKFs0LCA1LCA2XSk7XG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bVRlbnNvcnMpLnRvQmUoMyk7XG4gICAgZXhwZWN0KHRmLm1lbW9yeSgpLm51bURhdGFCdWZmZXJzKS50b0JlKDIpO1xuXG4gICAgdi5hc3NpZ24oc2Vjb25kQXJyYXkpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHYuZGF0YSgpLCBbNCwgNSwgNl0pO1xuICAgIC8vIEFzc2lnbiBkb2Vzbid0IGRpc3Bvc2UgdGhlIDFzdCBhcnJheS5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgzKTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtRGF0YUJ1ZmZlcnMpLnRvQmUoMik7XG5cbiAgICB2LmRpc3Bvc2UoKTtcbiAgICAvLyBEaXNwb3NpbmcgdGhlIHZhcmlhYmxlIGRpc3Bvc2VzIGl0c2VsZi4gVGhlIGlucHV0IHRvIHZhcmlhYmxlIGFuZFxuICAgIC8vIHNlY29uZEFycmF5IGFyZSB0aGUgb25seSByZW1haW5pbmcgdGVuc29ycy5cbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9CZSgyKTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtRGF0YUJ1ZmZlcnMpLnRvQmUoMik7XG4gIH0pO1xuXG4gIGl0KCdzaGFwZSBtdXN0IG1hdGNoJywgKCkgPT4ge1xuICAgIGNvbnN0IHYgPSB0Zi52YXJpYWJsZSh0Zi50ZW5zb3IxZChbMSwgMiwgM10pKTtcbiAgICBleHBlY3QoKCkgPT4gdi5hc3NpZ24odGYudGVuc29yMWQoWzEsIDJdKSkpLnRvVGhyb3dFcnJvcigpO1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICBleHBlY3QoKCkgPT4gdi5hc3NpZ24odGYudGVuc29yMmQoWzMsIDRdLCBbMSwgMl0pIGFzIGFueSkpLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgnZHR5cGUgbXVzdCBtYXRjaCcsICgpID0+IHtcbiAgICBjb25zdCB2ID0gdGYudmFyaWFibGUodGYudGVuc29yMWQoWzEsIDIsIDNdKSk7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIGV4cGVjdCgoKSA9PiB2LmFzc2lnbih0Zi50ZW5zb3IxZChbMSwgMSwgMV0sICdpbnQzMicpIGFzIGFueSkpXG4gICAgICAgIC50b1Rocm93RXJyb3IoKTtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgZXhwZWN0KCgpID0+IHYuYXNzaWduKHRmLnRlbnNvcjFkKFt0cnVlLCBmYWxzZSwgdHJ1ZV0sICdib29sJykgYXMgYW55KSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZVdpdGhGbGFncygneCBpbnN0YW5jZW9mIFZhcmlhYmxlJywgQUxMX0VOVlMsICgpID0+IHtcbiAgaXQoJ3g6IFZhcmlhYmxlJywgKCkgPT4ge1xuICAgIGNvbnN0IHQgPSB0Zi52YXJpYWJsZSh0Zi5zY2FsYXIoMSkpO1xuICAgIGV4cGVjdCh0IGluc3RhbmNlb2YgVmFyaWFibGUpLnRvQmUodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCd4OiBvdGhlciBvYmplY3QsIGZhaWxzJywgKCkgPT4ge1xuICAgIGNvbnN0IHQgPSB7c29tZXRoaW5nOiAnZWxzZSd9O1xuICAgIGV4cGVjdCh0IGluc3RhbmNlb2YgVmFyaWFibGUpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdCgneDogVGVuc29yLCBmYWlscycsICgpID0+IHtcbiAgICBjb25zdCB0ID0gdGYuc2NhbGFyKDEpO1xuICAgIGV4cGVjdCh0IGluc3RhbmNlb2YgVmFyaWFibGUpLnRvQmUoZmFsc2UpO1xuICB9KTtcbn0pO1xuIl19
|