@tensorflow/tfjs-converter
Version:
Tensorflow model converter for javascript
138 lines • 27 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 { tidy, util } from '@tensorflow/tfjs-core';
// tslint:disable-next-line: no-imports-from-dist
import * as tfOps from '@tensorflow/tfjs-core/dist/ops/ops_for_converter';
import { getParamValue } from './utils';
export const executeOp = (node, tensorMap, context) => {
switch (node.op) {
case 'ConcatV2':
case 'Concat': {
const n = getParamValue('n', node, tensorMap, context);
const axis = getParamValue('axis', node, tensorMap, context);
let inputs = getParamValue('tensors', node, tensorMap, context);
inputs = inputs.slice(0, n);
return [tfOps.concat(inputs, axis)];
}
case 'Gather': {
const input = getParamValue('x', node, tensorMap, context);
const indices = getParamValue('indices', node, tensorMap, context);
return [tfOps.gather(input, tfOps.cast(indices, 'int32'), 0)];
}
case 'GatherV2': {
const axis = getParamValue('axis', node, tensorMap, context);
const batchDims = getParamValue('batchDims', node, tensorMap, context);
const input = getParamValue('x', node, tensorMap, context);
const indices = getParamValue('indices', node, tensorMap, context);
return [tfOps.gather(input, tfOps.cast(indices, 'int32'), axis, batchDims)];
}
case 'Reverse': {
const dims = getParamValue('dims', node, tensorMap, context);
const axis = [];
for (let i = 0; i < dims.length; i++) {
if (dims[i]) {
axis.push(i);
}
}
const input = getParamValue('x', node, tensorMap, context);
return [tfOps.reverse(input, axis)];
}
case 'ReverseV2': {
const axis = getParamValue('axis', node, tensorMap, context);
const input = getParamValue('x', node, tensorMap, context);
return [tfOps.reverse(input, axis)];
}
case 'Slice': {
// tslint:disable-next-line:no-any
const begin = getParamValue('begin', node, tensorMap, context);
// tslint:disable-next-line:no-any
const size = getParamValue('size', node, tensorMap, context);
return [tfOps.slice(getParamValue('x', node, tensorMap, context), begin, size)];
}
case 'StridedSlice': {
const begin = getParamValue('begin', node, tensorMap, context);
const end = getParamValue('end', node, tensorMap, context);
const strides = getParamValue('strides', node, tensorMap, context);
const beginMask = getParamValue('beginMask', node, tensorMap, context);
const endMask = getParamValue('endMask', node, tensorMap, context);
const ellipsisMask = getParamValue('ellipsisMask', node, tensorMap, context);
const newAxisMask = getParamValue('newAxisMask', node, tensorMap, context);
const shrinkAxisMask = getParamValue('shrinkAxisMask', node, tensorMap, context);
const tensor = getParamValue('x', node, tensorMap, context);
return [tfOps.stridedSlice(tensor, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask)];
}
case 'Pack': {
return tidy(() => {
const axis = getParamValue('axis', node, tensorMap, context);
const tensors = getParamValue('tensors', node, tensorMap, context);
// Reshape the tensors to the first tensor's shape if they don't
// match.
const shape = tensors[0].shape;
const squeezedShape = tfOps.squeeze(tensors[0]).shape;
const mapped = tensors.map(tensor => {
const sameShape = util.arraysEqual(tensor.shape, shape);
if (!sameShape &&
!util.arraysEqual(tfOps.squeeze(tensor).shape, squeezedShape)) {
throw new Error('the input tensors shape does not match');
}
return sameShape ? tensor : tfOps.reshape(tensor, shape);
});
return [tfOps.stack(mapped, axis)];
});
}
case 'Unpack': {
const axis = getParamValue('axis', node, tensorMap, context);
const tensor = getParamValue('tensor', node, tensorMap, context);
return tfOps.unstack(tensor, axis);
}
case 'Tile': {
const reps = getParamValue('reps', node, tensorMap, context);
return [tfOps.tile(getParamValue('x', node, tensorMap, context), reps)];
}
case 'Split':
case 'SplitV': {
const axis = getParamValue('axis', node, tensorMap, context);
const numOrSizeSplits = getParamValue('numOrSizeSplits', node, tensorMap, context);
const tensor = getParamValue('x', node, tensorMap, context);
return tfOps.split(tensor, numOrSizeSplits, axis);
}
case 'ScatterNd': {
const indices = getParamValue('indices', node, tensorMap, context);
const values = getParamValue('values', node, tensorMap, context);
const shape = getParamValue('shape', node, tensorMap, context);
return [tfOps.scatterND(indices, values, shape)];
}
case 'GatherNd': {
const x = getParamValue('x', node, tensorMap, context);
const indices = getParamValue('indices', node, tensorMap, context);
return [tfOps.gatherND(x, indices)];
}
case 'SparseToDense': {
const indices = getParamValue('sparseIndices', node, tensorMap, context);
const shape = getParamValue('outputShape', node, tensorMap, context);
const sparseValues = getParamValue('sparseValues', node, tensorMap, context);
const defaultValue = getParamValue('defaultValue', node, tensorMap, context);
return [tfOps.sparseToDense(indices, sparseValues, shape, sparseValues.dtype === defaultValue.dtype ?
defaultValue :
tfOps.cast(defaultValue, sparseValues.dtype))];
}
default:
throw TypeError(`Node type ${node.op} is not implemented`);
}
};
export const CATEGORY = 'slice_join';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpY2Vfam9pbl9leGVjdXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3RmanMtY29udmVydGVyL3NyYy9vcGVyYXRpb25zL2V4ZWN1dG9ycy9zbGljZV9qb2luX2V4ZWN1dG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sRUFBMkIsSUFBSSxFQUFFLElBQUksRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQzNFLGlEQUFpRDtBQUNqRCxPQUFPLEtBQUssS0FBSyxNQUFNLGtEQUFrRCxDQUFDO0FBTTFFLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFFdEMsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUNsQixDQUFDLElBQVUsRUFBRSxTQUEwQixFQUN0QyxPQUF5QixFQUFZLEVBQUU7SUFDdEMsUUFBUSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2YsS0FBSyxVQUFVLENBQUM7UUFDaEIsS0FBSyxRQUFRLENBQUMsQ0FBQztZQUNiLE1BQU0sQ0FBQyxHQUFHLGFBQWEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQVcsQ0FBQztZQUNqRSxNQUFNLElBQUksR0FDTixhQUFhLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFXLENBQUM7WUFDOUQsSUFBSSxNQUFNLEdBQ04sYUFBYSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBYSxDQUFDO1lBQ25FLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUNyQztRQUNELEtBQUssUUFBUSxDQUFDLENBQUM7WUFDYixNQUFNLEtB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UUFDRDtZQUNFLE1BQU0sU0FBUyxDQUFDLGFBQWEsSUFBSSxDQUFDLEVBQUUscUJBQXFCLENBQUMsQ0FBQztLQUM5RDtBQUNILENBQUMsQ0FBQztBQUVOLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxZQUFZLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCB7U2NhbGFyLCBUZW5zb3IsIFRlbnNvcjFELCB0aWR5LCB1dGlsfSBmcm9tICdAdGVuc29yZmxvdy90ZmpzLWNvcmUnO1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1pbXBvcnRzLWZyb20tZGlzdFxuaW1wb3J0ICogYXMgdGZPcHMgZnJvbSAnQHRlbnNvcmZsb3cvdGZqcy1jb3JlL2Rpc3Qvb3BzL29wc19mb3JfY29udmVydGVyJztcblxuaW1wb3J0IHtOYW1lZFRlbnNvcnNNYXB9IGZyb20gJy4uLy4uL2RhdGEvdHlwZXMnO1xuaW1wb3J0IHtFeGVjdXRpb25Db250ZXh0fSBmcm9tICcuLi8uLi9leGVjdXRvci9leGVjdXRpb25fY29udGV4dCc7XG5pbXBvcnQge0ludGVybmFsT3BFeGVjdXRvciwgTm9kZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge2dldFBhcmFtVmFsdWV9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgY29uc3QgZXhlY3V0ZU9wOiBJbnRlcm5hbE9wRXhlY3V0b3IgPVxuICAgIChub2RlOiBOb2RlLCB0ZW5zb3JNYXA6IE5hbWVkVGVuc29yc01hcCxcbiAgICAgY29udGV4dDogRXhlY3V0aW9uQ29udGV4dCk6IFRlbnNvcltdID0+IHtcbiAgICAgIHN3aXRjaCAobm9kZS5vcCkge1xuICAgICAgICBjYXNlICdDb25jYXRWMic6XG4gICAgICAgIGNhc2UgJ0NvbmNhdCc6IHtcbiAgICAgICAgICBjb25zdCBuID0gZ2V0UGFyYW1WYWx1ZSgnbicsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgbnVtYmVyO1xuICAgICAgICAgIGNvbnN0IGF4aXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdheGlzJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXI7XG4gICAgICAgICAgbGV0IGlucHV0cyA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ3RlbnNvcnMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcltdO1xuICAgICAgICAgIGlucHV0cyA9IGlucHV0cy5zbGljZSgwLCBuKTtcbiAgICAgICAgICByZXR1cm4gW3RmT3BzLmNvbmNhdChpbnB1dHMsIGF4aXMpXTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdHYXRoZXInOiB7XG4gICAgICAgICAgY29uc3QgaW5wdXQgPSBnZXRQYXJhbVZhbHVlKCd4Jywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBUZW5zb3I7XG4gICAgICAgICAgY29uc3QgaW5kaWNlcyA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ2luZGljZXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjFEO1xuICAgICAgICAgIHJldHVybiBbdGZPcHMuZ2F0aGVyKGlucHV0LCB0Zk9wcy5jYXN0KGluZGljZXMsICdpbnQzMicpLCAwKV07XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnR2F0aGVyVjInOiB7XG4gICAgICAgICAgY29uc3QgYXhpcyA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ2F4aXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIG51bWJlcjtcbiAgICAgICAgICBjb25zdCBiYXRjaERpbXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdiYXRjaERpbXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIG51bWJlcjtcbiAgICAgICAgICBjb25zdCBpbnB1dCA9IGdldFBhcmFtVmFsdWUoJ3gnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjtcbiAgICAgICAgICBjb25zdCBpbmRpY2VzID1cbiAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgnaW5kaWNlcycsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgVGVuc29yMUQ7XG4gICAgICAgICAgcmV0dXJuIFt0Zk9wcy5nYXRoZXIoXG4gICAgICAgICAgICAgIGlucHV0LCB0Zk9wcy5jYXN0KGluZGljZXMsICdpbnQzMicpLCBheGlzLCBiYXRjaERpbXMpXTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdSZXZlcnNlJzoge1xuICAgICAgICAgIGNvbnN0IGRpbXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdkaW1zJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBib29sZWFuW107XG4gICAgICAgICAgY29uc3QgYXhpcyA9IFtdO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGRpbXNbaV0pIHtcbiAgICAgICAgICAgICAgYXhpcy5wdXNoKGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBpbnB1dCA9IGdldFBhcmFtVmFsdWUoJ3gnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjtcbiAgICAgICAgICByZXR1cm4gW3RmT3BzLnJldmVyc2UoaW5wdXQsIGF4aXMpXTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdSZXZlcnNlVjInOiB7XG4gICAgICAgICAgY29uc3QgYXhpcyA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ2F4aXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIG51bWJlcltdO1xuICAgICAgICAgIGNvbnN0IGlucHV0ID0gZ2V0UGFyYW1WYWx1ZSgneCcsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgVGVuc29yO1xuICAgICAgICAgIHJldHVybiBbdGZPcHMucmV2ZXJzZShpbnB1dCwgYXhpcyldO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ1NsaWNlJzoge1xuICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgICAgICBjb25zdCBiZWdpbiA9IGdldFBhcmFtVmFsdWUoJ2JlZ2luJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBhbnk7XG4gICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgICAgICAgIGNvbnN0IHNpemUgPSBnZXRQYXJhbVZhbHVlKCdzaXplJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBhbnk7XG4gICAgICAgICAgcmV0dXJuIFt0Zk9wcy5zbGljZShcbiAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgneCcsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgVGVuc29yLCBiZWdpbixcbiAgICAgICAgICAgICAgc2l6ZSldO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ1N0cmlkZWRTbGljZSc6IHtcbiAgICAgICAgICBjb25zdCBiZWdpbiA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ2JlZ2luJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXJbXTtcbiAgICAgICAgICBjb25zdCBlbmQgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdlbmQnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIG51bWJlcltdO1xuICAgICAgICAgIGNvbnN0IHN0cmlkZXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdzdHJpZGVzJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXJbXTtcbiAgICAgICAgICBjb25zdCBiZWdpbk1hc2sgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdiZWdpbk1hc2snLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIG51bWJlcjtcbiAgICAgICAgICBjb25zdCBlbmRNYXNrID1cbiAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgnZW5kTWFzaycsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgbnVtYmVyO1xuICAgICAgICAgIGNvbnN0IGVsbGlwc2lzTWFzayA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ2VsbGlwc2lzTWFzaycsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgbnVtYmVyO1xuICAgICAgICAgIGNvbnN0IG5ld0F4aXNNYXNrID1cbiAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgnbmV3QXhpc01hc2snLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIG51bWJlcjtcbiAgICAgICAgICBjb25zdCBzaHJpbmtBeGlzTWFzayA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ3Nocmlua0F4aXNNYXNrJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhc1xuICAgICAgICAgICAgICBudW1iZXI7XG4gICAgICAgICAgY29uc3QgdGVuc29yID0gZ2V0UGFyYW1WYWx1ZSgneCcsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgVGVuc29yO1xuXG4gICAgICAgICAgcmV0dXJuIFt0Zk9wcy5zdHJpZGVkU2xpY2UoXG4gICAgICAgICAgICAgIHRlbnNvciwgYmVnaW4sIGVuZCwgc3RyaWRlcywgYmVnaW5NYXNrLCBlbmRNYXNrLCBlbGxpcHNpc01hc2ssXG4gICAgICAgICAgICAgIG5ld0F4aXNNYXNrLCBzaHJpbmtBeGlzTWFzayldO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ1BhY2snOiB7XG4gICAgICAgICAgcmV0dXJuIHRpZHkoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXhpcyA9XG4gICAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgnYXhpcycsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgbnVtYmVyO1xuICAgICAgICAgICAgY29uc3QgdGVuc29ycyA9XG4gICAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgndGVuc29ycycsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgVGVuc29yW107XG4gICAgICAgICAgICAvLyBSZXNoYXBlIHRoZSB0ZW5zb3JzIHRvIHRoZSBmaXJzdCB0ZW5zb3IncyBzaGFwZSBpZiB0aGV5IGRvbid0XG4gICAgICAgICAgICAvLyBtYXRjaC5cbiAgICAgICAgICAgIGNvbnN0IHNoYXBlID0gdGVuc29yc1swXS5zaGFwZTtcbiAgICAgICAgICAgIGNvbnN0IHNxdWVlemVkU2hhcGUgPSB0Zk9wcy5zcXVlZXplKHRlbnNvcnNbMF0pLnNoYXBlO1xuICAgICAgICAgICAgY29uc3QgbWFwcGVkID0gdGVuc29ycy5tYXAodGVuc29yID0+IHtcbiAgICAgICAgICAgICAgY29uc3Qgc2FtZVNoYXBlID0gdXRpbC5hcnJheXNFcXVhbCh0ZW5zb3Iuc2hhcGUsIHNoYXBlKTtcbiAgICAgICAgICAgICAgaWYgKCFzYW1lU2hhcGUgJiZcbiAgICAgICAgICAgICAgICAgICF1dGlsLmFycmF5c0VxdWFsKFxuICAgICAgICAgICAgICAgICAgICAgIHRmT3BzLnNxdWVlemUodGVuc29yKS5zaGFwZSwgc3F1ZWV6ZWRTaGFwZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBpbnB1dCB0ZW5zb3JzIHNoYXBlIGRvZXMgbm90IG1hdGNoJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHNhbWVTaGFwZSA/IHRlbnNvciA6IHRmT3BzLnJlc2hhcGUodGVuc29yLCBzaGFwZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBbdGZPcHMuc3RhY2sobWFwcGVkLCBheGlzKV07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnVW5wYWNrJzoge1xuICAgICAgICAgIGNvbnN0IGF4aXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdheGlzJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXI7XG4gICAgICAgICAgY29uc3QgdGVuc29yID1cbiAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgndGVuc29yJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBUZW5zb3I7XG4gICAgICAgICAgcmV0dXJuIHRmT3BzLnVuc3RhY2sodGVuc29yLCBheGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdUaWxlJzoge1xuICAgICAgICAgIGNvbnN0IHJlcHMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdyZXBzJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXJbXTtcbiAgICAgICAgICByZXR1cm4gW3RmT3BzLnRpbGUoXG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ3gnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvciwgcmVwcyldO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ1NwbGl0JzpcbiAgICAgICAgY2FzZSAnU3BsaXRWJzoge1xuICAgICAgICAgIGNvbnN0IGF4aXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdheGlzJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXI7XG4gICAgICAgICAgY29uc3QgbnVtT3JTaXplU3BsaXRzID1cbiAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgnbnVtT3JTaXplU3BsaXRzJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhc1xuICAgICAgICAgICAgICAgICAgbnVtYmVyIHxcbiAgICAgICAgICAgICAgbnVtYmVyW107XG4gICAgICAgICAgY29uc3QgdGVuc29yID0gZ2V0UGFyYW1WYWx1ZSgneCcsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgVGVuc29yO1xuXG4gICAgICAgICAgcmV0dXJuIHRmT3BzLnNwbGl0KHRlbnNvciwgbnVtT3JTaXplU3BsaXRzLCBheGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdTY2F0dGVyTmQnOiB7XG4gICAgICAgICAgY29uc3QgaW5kaWNlcyA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ2luZGljZXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjtcbiAgICAgICAgICBjb25zdCB2YWx1ZXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCd2YWx1ZXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjtcbiAgICAgICAgICBjb25zdCBzaGFwZSA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ3NoYXBlJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXJbXTtcbiAgICAgICAgICByZXR1cm4gW3RmT3BzLnNjYXR0ZXJORChpbmRpY2VzLCB2YWx1ZXMsIHNoYXBlKV07XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnR2F0aGVyTmQnOiB7XG4gICAgICAgICAgY29uc3QgeCA9IGdldFBhcmFtVmFsdWUoJ3gnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjtcbiAgICAgICAgICBjb25zdCBpbmRpY2VzID1cbiAgICAgICAgICAgICAgZ2V0UGFyYW1WYWx1ZSgnaW5kaWNlcycsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgVGVuc29yO1xuICAgICAgICAgIHJldHVybiBbdGZPcHMuZ2F0aGVyTkQoeCwgaW5kaWNlcyldO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ1NwYXJzZVRvRGVuc2UnOiB7XG4gICAgICAgICAgY29uc3QgaW5kaWNlcyA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ3NwYXJzZUluZGljZXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzXG4gICAgICAgICAgICAgIFRlbnNvcjtcbiAgICAgICAgICBjb25zdCBzaGFwZSA9XG4gICAgICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ291dHB1dFNoYXBlJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhc1xuICAgICAgICAgICAgICBudW1iZXJbXTtcbiAgICAgICAgICBjb25zdCBzcGFyc2VWYWx1ZXMgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdzcGFyc2VWYWx1ZXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjtcbiAgICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPVxuICAgICAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdkZWZhdWx0VmFsdWUnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFNjYWxhcjtcbiAgICAgICAgICByZXR1cm4gW3RmT3BzLnNwYXJzZVRvRGVuc2UoXG4gICAgICAgICAgICAgIGluZGljZXMsIHNwYXJzZVZhbHVlcywgc2hhcGUsXG4gICAgICAgICAgICAgIHNwYXJzZVZhbHVlcy5kdHlwZSA9PT0gZGVmYXVsdFZhbHVlLmR0eXBlID9cbiAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA6XG4gICAgICAgICAgICAgICAgICB0Zk9wcy5jYXN0KGRlZmF1bHRWYWx1ZSwgc3BhcnNlVmFsdWVzLmR0eXBlKSldO1xuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKGBOb2RlIHR5cGUgJHtub2RlLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKTtcbiAgICAgIH1cbiAgICB9O1xuXG5leHBvcnQgY29uc3QgQ0FURUdPUlkgPSAnc2xpY2Vfam9pbic7XG4iXX0=