@react-three/p2
Version:
2D physics based hooks for react-three-fiber
107 lines (94 loc) • 1.06 MB
JavaScript
import { createContext, useEffect, useState, useRef, useCallback, useLayoutEffect, useMemo, useContext, Suspense } from 'react';
import { useThree, useFrame } from '@react-three/fiber';
import { Vector3, Quaternion, Matrix4, InstancedMesh, Box3, InstancedBufferGeometry, Float32BufferAttribute, InstancedInterleavedBuffer, InterleavedBufferAttribute, WireframeGeometry, Sphere, UniformsLib, Vector2, ShaderLib, UniformsUtils, ShaderMaterial, Vector4, Line3, Mesh, MathUtils, Scene, Euler, Object3D, DynamicDrawUsage } from 'three';
import EventEmitter$4 from 'events';
import { jsx, jsxs } from 'react/jsx-runtime';
const atomicNames = ['allowSleep', 'angle', 'angularDamping', 'angularVelocity', 'collisionFilterGroup', 'collisionFilterMask', 'collisionResponse', 'fixedRotation', 'isTrigger', 'linearDamping', 'mass', 'material', 'sleepSpeedLimit', 'sleepTimeLimit', 'userData'];
const vectorNames = ['position', 'velocity'];
const subscriptionNames = [...atomicNames, ...vectorNames, 'collisions', 'raysData'];
const context = /*#__PURE__*/createContext({});
const debugContext = /*#__PURE__*/createContext(null);
function useUpdateWorldPropsEffect(_ref) {
let {
axisIndex,
broadphase,
gravity,
iterations,
tolerance,
worker
} = _ref;
useEffect(() => {
worker.axisIndex = axisIndex;
}, [axisIndex]);
useEffect(() => {
worker.broadphase = broadphase;
}, [broadphase]);
useEffect(() => {
worker.gravity = gravity;
}, [gravity]);
useEffect(() => {
worker.iterations = iterations;
}, [iterations]);
useEffect(() => {
worker.tolerance = tolerance;
}, [tolerance]);
}
var WorkerClass = null;
try {
var WorkerThreads =
typeof module !== 'undefined' && typeof module.require === 'function' && module.require('worker_threads') ||
typeof __non_webpack_require__ === 'function' && __non_webpack_require__('worker_threads') ||
typeof require === 'function' && require('worker_threads');
WorkerClass = WorkerThreads.Worker;
} catch(e) {} // eslint-disable-line
function decodeBase64$1(base64, enableUnicode) {
return Buffer.from(base64, 'base64').toString(enableUnicode ? 'utf16' : 'utf8');
}
function createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg) {
var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
var source = decodeBase64$1(base64, enableUnicode);
var start = source.indexOf('\n', 10) + 1;
var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
return function WorkerFactory(options) {
return new WorkerClass(body, Object.assign({}, options, { eval: true }));
};
}
function decodeBase64(base64, enableUnicode) {
var binaryString = atob(base64);
if (enableUnicode) {
var binaryView = new Uint8Array(binaryString.length);
for (var i = 0, n = binaryString.length; i < n; ++i) {
binaryView[i] = binaryString.charCodeAt(i);
}
return String.fromCharCode.apply(null, new Uint16Array(binaryView.buffer));
}
return binaryString;
}
function createURL(base64, sourcemapArg, enableUnicodeArg) {
var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
var source = decodeBase64(base64, enableUnicode);
var start = source.indexOf('\n', 10) + 1;
var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
var blob = new Blob([body], { type: 'application/javascript' });
return URL.createObjectURL(blob);
}
function createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg) {
var url;
return function WorkerFactory(options) {
url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
return new Worker(url, options);
};
}
var kIsNodeJS = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
function isNodeJS() {
return kIsNodeJS;
}
function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
if (isNodeJS()) {
return createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg);
}
return createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg);
}
var WorkerFactory = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIHZhciBwMiA9IHtleHBvcnRzOiB7fX07CgogICAgdmFyIHZlYzIkcSA9IHtleHBvcnRzOiB7fX07CgogICAgLyogZ2xvYmFsIFAyX0FSUkFZX1RZUEUgKi8KCiAgICB2YXIgVXRpbHNfMSA9IFV0aWxzJDc7CiAgICAvKioKICAgICAqIE1pc2MgdXRpbGl0eSBmdW5jdGlvbnMKICAgICAqIEBjbGFzcyBVdGlscwogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KCiAgICBmdW5jdGlvbiBVdGlscyQ3KCkge30KICAgIC8qKgogICAgICogQXBwZW5kIHRoZSB2YWx1ZXMgaW4gYXJyYXkgYiB0byB0aGUgYXJyYXkgYS4gU2VlIDxhIGhyZWY9Imh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTM3NDEyNi9ob3ctdG8tYXBwZW5kLWFuLWFycmF5LXRvLWFuLWV4aXN0aW5nLWphdmFzY3JpcHQtYXJyYXkvMTM3NDEzMSMxMzc0MTMxIj50aGlzPC9hPiBmb3IgYW4gZXhwbGFuYXRpb24uCiAgICAgKiBAbWV0aG9kIGFwcGVuZEFycmF5CiAgICAgKiBAc3RhdGljCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gYQogICAgICogQHBhcmFtICB7QXJyYXl9IGIKICAgICAqLwoKCiAgICBVdGlscyQ3LmFwcGVuZEFycmF5ID0gZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgaWYgKGIubGVuZ3RoIDwgMTUwMDAwKSB7CiAgICAgICAgYS5wdXNoLmFwcGx5KGEsIGIpOwogICAgICB9IGVsc2UgewogICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBiLmxlbmd0aDsgaSAhPT0gbGVuOyArK2kpIHsKICAgICAgICAgIGEucHVzaChiW2ldKTsKICAgICAgICB9CiAgICAgIH0KICAgIH07CiAgICAvKioKICAgICAqIEdhcmJhZ2UgZnJlZSBBcnJheS5zcGxpY2UoKS4gRG9lcyBub3QgYWxsb2NhdGUgYSBuZXcgYXJyYXkuCiAgICAgKiBAbWV0aG9kIHNwbGljZQogICAgICogQHN0YXRpYwogICAgICogQHBhcmFtICB7QXJyYXl9IGFycmF5CiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGluZGV4CiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGhvd21hbnkKICAgICAqLwoKCiAgICBVdGlscyQ3LnNwbGljZSA9IGZ1bmN0aW9uIChhcnJheSwgaW5kZXgsIGhvd21hbnkpIHsKICAgICAgaG93bWFueSA9IGhvd21hbnkgfHwgMTsKCiAgICAgIGZvciAodmFyIGkgPSBpbmRleCwgbGVuID0gYXJyYXkubGVuZ3RoIC0gaG93bWFueTsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgYXJyYXlbaV0gPSBhcnJheVtpICsgaG93bWFueV07CiAgICAgIH0KCiAgICAgIGFycmF5Lmxlbmd0aCA9IGxlbjsKICAgIH07CiAgICAvKioKICAgICAqIFJlbW92ZSBhbiBlbGVtZW50IGZyb20gYW4gYXJyYXksIGlmIHRoZSBhcnJheSBjb250YWlucyB0aGUgZWxlbWVudC4KICAgICAqIEBtZXRob2QgYXJyYXlSZW1vdmUKICAgICAqIEBzdGF0aWMKICAgICAqIEBwYXJhbSAge0FycmF5fSBhcnJheQogICAgICogQHBhcmFtICB7TnVtYmVyfSBlbGVtZW50CiAgICAgKi8KCgogICAgVXRpbHMkNy5hcnJheVJlbW92ZSA9IGZ1bmN0aW9uIChhcnJheSwgZWxlbWVudCkgewogICAgICB2YXIgaWR4ID0gYXJyYXkuaW5kZXhPZihlbGVtZW50KTsKCiAgICAgIGlmIChpZHggIT09IC0xKSB7CiAgICAgICAgVXRpbHMkNy5zcGxpY2UoYXJyYXksIGlkeCwgMSk7CiAgICAgIH0KICAgIH07CiAgICAvKioKICAgICAqIFRoZSBhcnJheSB0eXBlIHRvIHVzZSBmb3IgaW50ZXJuYWwgbnVtZXJpYyBjb21wdXRhdGlvbnMgdGhyb3VnaG91dCB0aGUgbGlicmFyeS4gRmxvYXQzMkFycmF5IGlzIHVzZWQgaWYgaXQgaXMgYXZhaWxhYmxlLCBidXQgZmFsbHMgYmFjayBvbiBBcnJheS4gSWYgeW91IHdhbnQgdG8gc2V0IGFycmF5IHR5cGUgbWFudWFsbHksIGluamVjdCBpdCB2aWEgdGhlIGdsb2JhbCB2YXJpYWJsZSBQMl9BUlJBWV9UWVBFLiBTZWUgZXhhbXBsZSBiZWxvdy4KICAgICAqIEBzdGF0aWMKICAgICAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IEFSUkFZX1RZUEUKICAgICAqIEBleGFtcGxlCiAgICAgKiAgICAgPHNjcmlwdD4KICAgICAqICAgICAgICAgPCEtLSBJbmplY3QgeW91ciBwcmVmZXJyZWQgYXJyYXkgdHlwZSBiZWZvcmUgbG9hZGluZyBwMi5qcyAtLT4KICAgICAqICAgICAgICAgUDJfQVJSQVlfVFlQRSA9IEFycmF5OwogICAgICogICAgIDwvc2NyaXB0PgogICAgICogICAgIDxzY3JpcHQgc3JjPSJwMi5qcyI+PC9zY3JpcHQ+CiAgICAgKi8KCgogICAgaWYgKHR5cGVvZiBQMl9BUlJBWV9UWVBFICE9PSAndW5kZWZpbmVkJykgewogICAgICBVdGlscyQ3LkFSUkFZX1RZUEUgPSBQMl9BUlJBWV9UWVBFOwogICAgfSBlbHNlIGlmICh0eXBlb2YgRmxvYXQzMkFycmF5ICE9PSAndW5kZWZpbmVkJykgewogICAgICBVdGlscyQ3LkFSUkFZX1RZUEUgPSBGbG9hdDMyQXJyYXk7CiAgICB9IGVsc2UgewogICAgICBVdGlscyQ3LkFSUkFZX1RZUEUgPSBBcnJheTsKICAgIH0KICAgIC8qKgogICAgICogRXh0ZW5kIGFuIG9iamVjdCB3aXRoIHRoZSBwcm9wZXJ0aWVzIG9mIGFub3RoZXIKICAgICAqIEBzdGF0aWMKICAgICAqIEBtZXRob2QgZXh0ZW5kCiAgICAgKiBAcGFyYW0gIHtvYmplY3R9IGEKICAgICAqIEBwYXJhbSAge29iamVjdH0gYgogICAgICovCgoKICAgIFV0aWxzJDcuZXh0ZW5kID0gZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgZm9yICh2YXIga2V5IGluIGIpIHsKICAgICAgICBhW2tleV0gPSBiW2tleV07CiAgICAgIH0KICAgIH07CiAgICAvKioKICAgICAqIFNoYWxsb3cgY2xvbmUgYW4gb2JqZWN0LiBSZXR1cm5zIGEgbmV3IG9iamVjdCBpbnN0YW5jZSB3aXRoIHRoZSBzYW1lIHByb3BlcnRpZXMgYXMgdGhlIGlucHV0IGluc3RhbmNlLgogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBzaGFsbG93Q2xvbmUKICAgICAqIEBwYXJhbSAge29iamVjdH0gb2JqCiAgICAgKi8KCgogICAgVXRpbHMkNy5zaGFsbG93Q2xvbmUgPSBmdW5jdGlvbiAob2JqKSB7CiAgICAgIHZhciBuZXdPYmogPSB7fTsKICAgICAgVXRpbHMkNy5leHRlbmQobmV3T2JqLCBvYmopOwogICAgICByZXR1cm4gbmV3T2JqOwogICAgfTsKICAgIC8qKgogICAgICogRXh0ZW5kIGFuIG9wdGlvbnMgb2JqZWN0IHdpdGggZGVmYXVsdCB2YWx1ZXMuCiAgICAgKiBAZGVwcmVjYXRlZCBOb3QgdXNlZCBpbnRlcm5hbGx5LCB3aWxsIGJlIHJlbW92ZWQuCiAgICAgKiBAc3RhdGljCiAgICAgKiBAbWV0aG9kIGRlZmF1bHRzCiAgICAgKiBAcGFyYW0gIHtvYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgb2JqZWN0LiBNYXkgYmUgZmFsc3k6IGluIHRoaXMgY2FzZSwgYSBuZXcgb2JqZWN0IGlzIGNyZWF0ZWQgYW5kIHJldHVybmVkLgogICAgICogQHBhcmFtICB7b2JqZWN0fSBkZWZhdWx0cyBBbiBvYmplY3QgY29udGFpbmluZyBkZWZhdWx0IHZhbHVlcy4KICAgICAqIEByZXR1cm4ge29iamVjdH0gVGhlIG1vZGlmaWVkIG9wdGlvbnMgb2JqZWN0LgogICAgICovCgoKICAgIFV0aWxzJDcuZGVmYXVsdHMgPSBmdW5jdGlvbiAob3B0aW9ucywgZGVmYXVsdHMpIHsKICAgICAgY29uc29sZS53YXJuKCdVdGlscy5kZWZhdWx0cyBpcyBkZXByZWNhdGVkLicpOwogICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgICAgIGZvciAodmFyIGtleSBpbiBkZWZhdWx0cykgewogICAgICAgIGlmICghKGtleSBpbiBvcHRpb25zKSkgewogICAgICAgICAgb3B0aW9uc1trZXldID0gZGVmYXVsdHNba2V5XTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHJldHVybiBvcHRpb25zOwogICAgfTsKCiAgICAvKiBDb3B5cmlnaHQgKGMpIDIwMTMsIEJyYW5kb24gSm9uZXMsIENvbGluIE1hY0tlbnppZSBJVi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLAogICAgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgoKICAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMKICAgICAgICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCiAgICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbgogICAgICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgoKICAgIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgIkFTIElTIiBBTkQKICAgIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVECiAgICBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAgICBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUgogICAgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCiAgICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CiAgICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04KICAgIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAgICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUwogICAgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuICovCgogICAgLyoqCiAgICAgKiBUaGUgdmVjMiBvYmplY3QgZnJvbSBnbE1hdHJpeCwgd2l0aCBzb21lIGV4dGVuc2lvbnMgYW5kIHNvbWUgcmVtb3ZlZCBtZXRob2RzLiBTZWUgaHR0cDovL2dsbWF0cml4Lm5ldC4KICAgICAqIEBjbGFzcyB2ZWMyCiAgICAgKi8KICAgIHZhciB2ZWMyJHAgPSB2ZWMyJHEuZXhwb3J0cyA9IHt9OwoKICAgIHZhciBVdGlscyQ2ID0gVXRpbHNfMTsKICAgIC8qKgogICAgICogTWFrZSBhIGNyb3NzIHByb2R1Y3QgYW5kIG9ubHkgcmV0dXJuIHRoZSB6IGNvbXBvbmVudAogICAgICogQG1ldGhvZCBjcm9zc0xlbmd0aAogICAgICogQHN0YXRpYwogICAgICogQHBhcmFtICB7QXJyYXl9IGEKICAgICAqIEBwYXJhbSAge0FycmF5fSBiCiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9CiAgICAgKi8KCgogICAgdmVjMiRwLmNyb3NzTGVuZ3RoID0gZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgcmV0dXJuIGFbMF0gKiBiWzFdIC0gYVsxXSAqIGJbMF07CiAgICB9OwogICAgLyoqCiAgICAgKiBDcm9zcyBwcm9kdWN0IGJldHdlZW4gYSB2ZWN0b3IgYW5kIHRoZSBaIGNvbXBvbmVudCBvZiBhIHZlY3RvcgogICAgICogQG1ldGhvZCBjcm9zc1ZaCiAgICAgKiBAc3RhdGljCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gb3V0CiAgICAgKiBAcGFyYW0gIHtBcnJheX0gdmVjCiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IHpjb21wCiAgICAgKiBAcmV0dXJuIHtBcnJheX0KICAgICAqLwoKCiAgICB2ZWMyJHAuY3Jvc3NWWiA9IGZ1bmN0aW9uIChvdXQsIHZlYywgemNvbXApIHsKICAgICAgdmVjMiRwLnJvdGF0ZShvdXQsIHZlYywgLU1hdGguUEkgLyAyKTsgLy8gUm90YXRlIGFjY29yZGluZyB0byB0aGUgcmlnaHQgaGFuZCBydWxlCgogICAgICB2ZWMyJHAuc2NhbGUob3V0LCBvdXQsIHpjb21wKTsgLy8gU2NhbGUgd2l0aCB6CgogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogQ3Jvc3MgcHJvZHVjdCBiZXR3ZWVuIGEgdmVjdG9yIGFuZCB0aGUgWiBjb21wb25lbnQgb2YgYSB2ZWN0b3IKICAgICAqIEBtZXRob2QgY3Jvc3NaVgogICAgICogQHN0YXRpYwogICAgICogQHBhcmFtICB7QXJyYXl9IG91dAogICAgICogQHBhcmFtICB7TnVtYmVyfSB6Y29tcAogICAgICogQHBhcmFtICB7QXJyYXl9IHZlYwogICAgICogQHJldHVybiB7QXJyYXl9CiAgICAgKi8KCgogICAgdmVjMiRwLmNyb3NzWlYgPSBmdW5jdGlvbiAob3V0LCB6Y29tcCwgdmVjKSB7CiAgICAgIHZlYzIkcC5yb3RhdGUob3V0LCB2ZWMsIE1hdGguUEkgLyAyKTsgLy8gUm90YXRlIGFjY29yZGluZyB0byB0aGUgcmlnaHQgaGFuZCBydWxlCgogICAgICB2ZWMyJHAuc2NhbGUob3V0LCBvdXQsIHpjb21wKTsgLy8gU2NhbGUgd2l0aCB6CgogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogUm90YXRlIGEgdmVjdG9yIGJ5IGFuIGFuZ2xlCiAgICAgKiBAbWV0aG9kIHJvdGF0ZQogICAgICogQHN0YXRpYwogICAgICogQHBhcmFtICB7QXJyYXl9IG91dAogICAgICogQHBhcmFtICB7QXJyYXl9IGEKICAgICAqIEBwYXJhbSAge051bWJlcn0gYW5nbGUKICAgICAqIEByZXR1cm4ge0FycmF5fQogICAgICovCgoKICAgIHZlYzIkcC5yb3RhdGUgPSBmdW5jdGlvbiAob3V0LCBhLCBhbmdsZSkgewogICAgICBpZiAoYW5nbGUgIT09IDApIHsKICAgICAgICB2YXIgYyA9IE1hdGguY29zKGFuZ2xlKSwKICAgICAgICAgICAgcyA9IE1hdGguc2luKGFuZ2xlKSwKICAgICAgICAgICAgeCA9IGFbMF0sCiAgICAgICAgICAgIHkgPSBhWzFdOwogICAgICAgIG91dFswXSA9IGMgKiB4IC0gcyAqIHk7CiAgICAgICAgb3V0WzFdID0gcyAqIHggKyBjICogeTsKICAgICAgfSBlbHNlIHsKICAgICAgICBvdXRbMF0gPSBhWzBdOwogICAgICAgIG91dFsxXSA9IGFbMV07CiAgICAgIH0KCiAgICAgIHJldHVybiBvdXQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBSb3RhdGUgYSB2ZWN0b3IgOTAgZGVncmVlcyBjbG9ja3dpc2UKICAgICAqIEBtZXRob2Qgcm90YXRlOTBjdwogICAgICogQHN0YXRpYwogICAgICogQHBhcmFtICB7QXJyYXl9IG91dAogICAgICogQHBhcmFtICB7QXJyYXl9IGEKICAgICAqIEBwYXJhbSAge051bWJlcn0gYW5nbGUKICAgICAqIEByZXR1cm4ge0FycmF5fQogICAgICovCgoKICAgIHZlYzIkcC5yb3RhdGU5MGN3ID0gZnVuY3Rpb24gKG91dCwgYSkgewogICAgICB2YXIgeCA9IGFbMF07CiAgICAgIHZhciB5ID0gYVsxXTsKICAgICAgb3V0WzBdID0geTsKICAgICAgb3V0WzFdID0gLXg7CiAgICAgIHJldHVybiBvdXQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBUcmFuc2Zvcm0gYSBwb2ludCBwb3NpdGlvbiB0byBsb2NhbCBmcmFtZS4KICAgICAqIEBtZXRob2QgdG9Mb2NhbEZyYW1lCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gb3V0CiAgICAgKiBAcGFyYW0gIHtBcnJheX0gd29ybGRQb2ludAogICAgICogQHBhcmFtICB7QXJyYXl9IGZyYW1lUG9zaXRpb24KICAgICAqIEBwYXJhbSAge051bWJlcn0gZnJhbWVBbmdsZQogICAgICogQHJldHVybiB7QXJyYXl9CiAgICAgKi8KCgogICAgdmVjMiRwLnRvTG9jYWxGcmFtZSA9IGZ1bmN0aW9uIChvdXQsIHdvcmxkUG9pbnQsIGZyYW1lUG9zaXRpb24sIGZyYW1lQW5nbGUpIHsKICAgICAgdmFyIGMgPSBNYXRoLmNvcygtZnJhbWVBbmdsZSksCiAgICAgICAgICBzID0gTWF0aC5zaW4oLWZyYW1lQW5nbGUpLAogICAgICAgICAgeCA9IHdvcmxkUG9pbnRbMF0gLSBmcmFtZVBvc2l0aW9uWzBdLAogICAgICAgICAgeSA9IHdvcmxkUG9pbnRbMV0gLSBmcmFtZVBvc2l0aW9uWzFdOwogICAgICBvdXRbMF0gPSBjICogeCAtIHMgKiB5OwogICAgICBvdXRbMV0gPSBzICogeCArIGMgKiB5OwogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogVHJhbnNmb3JtIGEgcG9pbnQgcG9zaXRpb24gdG8gZ2xvYmFsIGZyYW1lLgogICAgICogQG1ldGhvZCB0b0dsb2JhbEZyYW1lCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gb3V0CiAgICAgKiBAcGFyYW0gIHtBcnJheX0gbG9jYWxQb2ludAogICAgICogQHBhcmFtICB7QXJyYXl9IGZyYW1lUG9zaXRpb24KICAgICAqIEBwYXJhbSAge051bWJlcn0gZnJhbWVBbmdsZQogICAgICovCgoKICAgIHZlYzIkcC50b0dsb2JhbEZyYW1lID0gZnVuY3Rpb24gKG91dCwgbG9jYWxQb2ludCwgZnJhbWVQb3NpdGlvbiwgZnJhbWVBbmdsZSkgewogICAgICB2YXIgYyA9IE1hdGguY29zKGZyYW1lQW5nbGUpLAogICAgICAgICAgcyA9IE1hdGguc2luKGZyYW1lQW5nbGUpLAogICAgICAgICAgeCA9IGxvY2FsUG9pbnRbMF0sCiAgICAgICAgICB5ID0gbG9jYWxQb2ludFsxXSwKICAgICAgICAgIGFkZFggPSBmcmFtZVBvc2l0aW9uWzBdLAogICAgICAgICAgYWRkWSA9IGZyYW1lUG9zaXRpb25bMV07CiAgICAgIG91dFswXSA9IGMgKiB4IC0gcyAqIHkgKyBhZGRYOwogICAgICBvdXRbMV0gPSBzICogeCArIGMgKiB5ICsgYWRkWTsKICAgIH07CiAgICAvKioKICAgICAqIFRyYW5zZm9ybSBhIHZlY3RvciB0byBsb2NhbCBmcmFtZS4KICAgICAqIEBtZXRob2QgdmVjdG9yVG9Mb2NhbEZyYW1lCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gb3V0CiAgICAgKiBAcGFyYW0gIHtBcnJheX0gd29ybGRWZWN0b3IKICAgICAqIEBwYXJhbSAge051bWJlcn0gZnJhbWVBbmdsZQogICAgICogQHJldHVybiB7QXJyYXl9CiAgICAgKi8KCgogICAgdmVjMiRwLnZlY3RvclRvTG9jYWxGcmFtZSA9IGZ1bmN0aW9uIChvdXQsIHdvcmxkVmVjdG9yLCBmcmFtZUFuZ2xlKSB7CiAgICAgIHZhciBjID0gTWF0aC5jb3MoLWZyYW1lQW5nbGUpLAogICAgICAgICAgcyA9IE1hdGguc2luKC1mcmFtZUFuZ2xlKSwKICAgICAgICAgIHggPSB3b3JsZFZlY3RvclswXSwKICAgICAgICAgIHkgPSB3b3JsZFZlY3RvclsxXTsKICAgICAgb3V0WzBdID0gYyAqIHggLSBzICogeTsKICAgICAgb3V0WzFdID0gcyAqIHggKyBjICogeTsKICAgICAgcmV0dXJuIG91dDsKICAgIH07CiAgICAvKioKICAgICAqIFRyYW5zZm9ybSBhIHZlY3RvciB0byBnbG9iYWwgZnJhbWUuCiAgICAgKiBAbWV0aG9kIHZlY3RvclRvR2xvYmFsRnJhbWUKICAgICAqIEBwYXJhbSAge0FycmF5fSBvdXQKICAgICAqIEBwYXJhbSAge0FycmF5fSBsb2NhbFZlY3RvcgogICAgICogQHBhcmFtICB7TnVtYmVyfSBmcmFtZUFuZ2xlCiAgICAgKi8KCgogICAgdmVjMiRwLnZlY3RvclRvR2xvYmFsRnJhbWUgPSB2ZWMyJHAucm90YXRlOwogICAgLyoqCiAgICAgKiBDb21wdXRlIGNlbnRyb2lkIG9mIGEgdHJpYW5nbGUgc3Bhbm5lZCBieSB2ZWN0b3JzIGEsYixjLiBTZWUgaHR0cDovL2Vhc3ljYWxjdWxhdGlvbi5jb20vYW5hbHl0aWNhbC9sZWFybi1jZW50cm9pZC5waHAKICAgICAqIEBtZXRob2QgY2VudHJvaWQKICAgICAqIEBzdGF0aWMKICAgICAqIEBwYXJhbSAge0FycmF5fSBvdXQKICAgICAqIEBwYXJhbSAge0FycmF5fSBhCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gYgogICAgICogQHBhcmFtICB7QXJyYXl9IGMKICAgICAqIEByZXR1cm4gIHtBcnJheX0gVGhlICJvdXQiIHZlY3Rvci4KICAgICAqLwoKICAgIHZlYzIkcC5jZW50cm9pZCA9IGZ1bmN0aW9uIChvdXQsIGEsIGIsIGMpIHsKICAgICAgdmVjMiRwLmFkZChvdXQsIGEsIGIpOwogICAgICB2ZWMyJHAuYWRkKG91dCwgb3V0LCBjKTsKICAgICAgdmVjMiRwLnNjYWxlKG91dCwgb3V0LCAxIC8gMyk7CiAgICAgIHJldHVybiBvdXQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB2ZWMyCiAgICAgKiBAc3RhdGljCiAgICAgKiBAbWV0aG9kIGNyZWF0ZQogICAgICogQHJldHVybiB7QXJyYXl9IGEgbmV3IDJEIHZlY3RvcgogICAgICovCgoKICAgIHZlYzIkcC5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgIHZhciBvdXQgPSBuZXcgVXRpbHMkNi5BUlJBWV9UWVBFKDIpOwogICAgICBvdXRbMF0gPSAwOwogICAgICBvdXRbMV0gPSAwOwogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyB2ZWMyIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgdmVjdG9yCiAgICAgKiBAc3RhdGljCiAgICAgKiBAbWV0aG9kIGNsb25lCiAgICAgKiBAcGFyYW0ge0FycmF5fSBhIHZlY3RvciB0byBjbG9uZQogICAgICogQHJldHVybiB7QXJyYXl9IGEgbmV3IDJEIHZlY3RvcgogICAgICovCgoKICAgIHZlYzIkcC5jbG9uZSA9IGZ1bmN0aW9uIChhKSB7CiAgICAgIHZhciBvdXQgPSBuZXcgVXRpbHMkNi5BUlJBWV9UWVBFKDIpOwogICAgICBvdXRbMF0gPSBhWzBdOwogICAgICBvdXRbMV0gPSBhWzFdOwogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyB2ZWMyIGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHZhbHVlcwogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBmcm9tVmFsdWVzCiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudAogICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnQKICAgICAqIEByZXR1cm4ge0FycmF5fSBhIG5ldyAyRCB2ZWN0b3IKICAgICAqLwoKCiAgICB2ZWMyJHAuZnJvbVZhbHVlcyA9IGZ1bmN0aW9uICh4LCB5KSB7CiAgICAgIHZhciBvdXQgPSBuZXcgVXRpbHMkNi5BUlJBWV9UWVBFKDIpOwogICAgICBvdXRbMF0gPSB4OwogICAgICBvdXRbMV0gPSB5OwogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIHZlYzIgdG8gYW5vdGhlcgogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBjb3B5CiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3IKICAgICAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIHNvdXJjZSB2ZWN0b3IKICAgICAqIEByZXR1cm4ge0FycmF5fSBvdXQKICAgICAqLwoKCiAgICB2ZWMyJHAuY29weSA9IGZ1bmN0aW9uIChvdXQsIGEpIHsKICAgICAgb3V0WzBdID0gYVswXTsKICAgICAgb3V0WzFdID0gYVsxXTsKICAgICAgcmV0dXJuIG91dDsKICAgIH07CiAgICAvKioKICAgICAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzIgdG8gdGhlIGdpdmVuIHZhbHVlcwogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBzZXQKICAgICAqIEBwYXJhbSB7QXJyYXl9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvcgogICAgICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnQKICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50CiAgICAgKiBAcmV0dXJuIHtBcnJheX0gb3V0CiAgICAgKi8KCgogICAgdmVjMiRwLnNldCA9IGZ1bmN0aW9uIChvdXQsIHgsIHkpIHsKICAgICAgb3V0WzBdID0geDsKICAgICAgb3V0WzFdID0geTsKICAgICAgcmV0dXJuIG91dDsKICAgIH07CiAgICAvKioKICAgICAqIEFkZHMgdHdvIHZlYzIncwogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBhZGQKICAgICAqIEBwYXJhbSB7QXJyYXl9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvcgogICAgICogQHBhcmFtIHtBcnJheX0gYSB0aGUgZmlyc3Qgb3BlcmFuZAogICAgICogQHBhcmFtIHtBcnJheX0gYiB0aGUgc2Vjb25kIG9wZXJhbmQKICAgICAqIEByZXR1cm4ge0FycmF5fSBvdXQKICAgICAqLwoKCiAgICB2ZWMyJHAuYWRkID0gZnVuY3Rpb24gKG91dCwgYSwgYikgewogICAgICBvdXRbMF0gPSBhWzBdICsgYlswXTsKICAgICAgb3V0WzFdID0gYVsxXSArIGJbMV07CiAgICAgIHJldHVybiBvdXQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBTdWJ0cmFjdHMgdHdvIHZlYzIncwogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBzdWJ0cmFjdAogICAgICogQHBhcmFtIHtBcnJheX0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yCiAgICAgKiBAcGFyYW0ge0FycmF5fSBhIHRoZSBmaXJzdCBvcGVyYW5kCiAgICAgKiBAcGFyYW0ge0FycmF5fSBiIHRoZSBzZWNvbmQgb3BlcmFuZAogICAgICogQHJldHVybiB7QXJyYXl9IG91dAogICAgICovCgoKICAgIHZlYzIkcC5zdWJ0cmFjdCA9IGZ1bmN0aW9uIChvdXQsIGEsIGIpIHsKICAgICAgb3V0WzBdID0gYVswXSAtIGJbMF07CiAgICAgIG91dFsxXSA9IGFbMV0gLSBiWzFdOwogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogTXVsdGlwbGllcyB0d28gdmVjMidzCiAgICAgKiBAc3RhdGljCiAgICAgKiBAbWV0aG9kIG11bHRpcGx5CiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3IKICAgICAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIGZpcnN0IG9wZXJhbmQKICAgICAqIEBwYXJhbSB7QXJyYXl9IGIgdGhlIHNlY29uZCBvcGVyYW5kCiAgICAgKiBAcmV0dXJuIHtBcnJheX0gb3V0CiAgICAgKi8KCgogICAgdmVjMiRwLm11bHRpcGx5ID0gZnVuY3Rpb24gKG91dCwgYSwgYikgewogICAgICBvdXRbMF0gPSBhWzBdICogYlswXTsKICAgICAgb3V0WzFdID0gYVsxXSAqIGJbMV07CiAgICAgIHJldHVybiBvdXQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBEaXZpZGVzIHR3byB2ZWMyJ3MKICAgICAqIEBzdGF0aWMKICAgICAqIEBtZXRob2QgZGl2aWRlCiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3IKICAgICAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIGZpcnN0IG9wZXJhbmQKICAgICAqIEBwYXJhbSB7QXJyYXl9IGIgdGhlIHNlY29uZCBvcGVyYW5kCiAgICAgKiBAcmV0dXJuIHtBcnJheX0gb3V0CiAgICAgKi8KCgogICAgdmVjMiRwLmRpdmlkZSA9IGZ1bmN0aW9uIChvdXQsIGEsIGIpIHsKICAgICAgb3V0WzBdID0gYVswXSAvIGJbMF07CiAgICAgIG91dFsxXSA9IGFbMV0gLyBiWzFdOwogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogU2NhbGVzIGEgdmVjMiBieSBhIHNjYWxhciBudW1iZXIKICAgICAqIEBzdGF0aWMKICAgICAqIEBtZXRob2Qgc2NhbGUKICAgICAqIEBwYXJhbSB7QXJyYXl9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvcgogICAgICogQHBhcmFtIHtBcnJheX0gYSB0aGUgdmVjdG9yIHRvIHNjYWxlCiAgICAgKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHZlY3RvciBieQogICAgICogQHJldHVybiB7QXJyYXl9IG91dAogICAgICovCgoKICAgIHZlYzIkcC5zY2FsZSA9IGZ1bmN0aW9uIChvdXQsIGEsIGIpIHsKICAgICAgb3V0WzBdID0gYVswXSAqIGI7CiAgICAgIG91dFsxXSA9IGFbMV0gKiBiOwogICAgICByZXR1cm4gb3V0OwogICAgfTsKICAgIC8qKgogICAgICogQ2FsY3VsYXRlcyB0aGUgZXVjbGlkaWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlYzIncwogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBkaXN0YW5jZQogICAgICogQHBhcmFtIHtBcnJheX0gYSB0aGUgZmlyc3Qgb3BlcmFuZAogICAgICogQHBhcmFtIHtBcnJheX0gYiB0aGUgc2Vjb25kIG9wZXJhbmQKICAgICAqIEByZXR1cm4ge051bWJlcn0gZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiCiAgICAgKi8KCgogICAgdmVjMiRwLmRpc3RhbmNlID0gZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgdmFyIHggPSBiWzBdIC0gYVswXSwKICAgICAgICAgIHkgPSBiWzFdIC0gYVsxXTsKICAgICAgcmV0dXJuIE1hdGguc3FydCh4ICogeCArIHkgKiB5KTsKICAgIH07CiAgICAvKioKICAgICAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgZXVjbGlkaWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlYzIncwogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBzcXVhcmVkRGlzdGFuY2UKICAgICAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIGZpcnN0IG9wZXJhbmQKICAgICAqIEBwYXJhbSB7QXJyYXl9IGIgdGhlIHNlY29uZCBvcGVyYW5kCiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IHNxdWFyZWQgZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiCiAgICAgKi8KCgogICAgdmVjMiRwLnNxdWFyZWREaXN0YW5jZSA9IGZ1bmN0aW9uIChhLCBiKSB7CiAgICAgIHZhciB4ID0gYlswXSAtIGFbMF0sCiAgICAgICAgICB5ID0gYlsxXSAtIGFbMV07CiAgICAgIHJldHVybiB4ICogeCArIHkgKiB5OwogICAgfTsKICAgIC8qKgogICAgICogQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIGEgdmVjMgogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBsZW5ndGgKICAgICAqIEBwYXJhbSB7QXJyYXl9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2YKICAgICAqIEByZXR1cm4ge051bWJlcn0gbGVuZ3RoIG9mIGEKICAgICAqLwoKCiAgICB2ZWMyJHAubGVuZ3RoID0gZnVuY3Rpb24gKGEpIHsKICAgICAgdmFyIHggPSBhWzBdLAogICAgICAgICAgeSA9IGFbMV07CiAgICAgIHJldHVybiBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7CiAgICB9OwogICAgLyoqCiAgICAgKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGxlbmd0aCBvZiBhIHZlYzIKICAgICAqIEBzdGF0aWMKICAgICAqIEBtZXRob2Qgc3F1YXJlZExlbmd0aAogICAgICogQHBhcmFtIHtBcnJheX0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIHNxdWFyZWQgbGVuZ3RoIG9mCiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IHNxdWFyZWQgbGVuZ3RoIG9mIGEKICAgICAqLwoKCiAgICB2ZWMyJHAuc3F1YXJlZExlbmd0aCA9IGZ1bmN0aW9uIChhKSB7CiAgICAgIHZhciB4ID0gYVswXSwKICAgICAgICAgIHkgPSBhWzFdOwogICAgICByZXR1cm4geCAqIHggKyB5ICogeTsKICAgIH07CiAgICAvKioKICAgICAqIE5lZ2F0ZXMgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMyCiAgICAgKiBAc3RhdGljCiAgICAgKiBAbWV0aG9kIG5lZ2F0ZQogICAgICogQHBhcmFtIHtBcnJheX0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yCiAgICAgKiBAcGFyYW0ge0FycmF5fSBhIHZlY3RvciB0byBuZWdhdGUKICAgICAqIEByZXR1cm4ge0FycmF5fSBvdXQKICAgICAqLwoKCiAgICB2ZWMyJHAubmVnYXRlID0gZnVuY3Rpb24gKG91dCwgYSkgewogICAgICBvdXRbMF0gPSAtYVswXTsKICAgICAgb3V0WzFdID0gLWFbMV07CiAgICAgIHJldHVybiBvdXQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBOb3JtYWxpemUgYSB2ZWMyCiAgICAgKiBAc3RhdGljCiAgICAgKiBAbWV0aG9kIG5vcm1hbGl6ZQogICAgICogQHBhcmFtIHtBcnJheX0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yCiAgICAgKiBAcGFyYW0ge0FycmF5fSBhIHZlY3RvciB0byBub3JtYWxpemUKICAgICAqIEByZXR1cm4ge0FycmF5fSBvdXQKICAgICAqLwoKCiAgICB2ZWMyJHAubm9ybWFsaXplID0gZnVuY3Rpb24gKG91dCwgYSkgewogICAgICB2YXIgeCA9IGFbMF0sCiAgICAgICAgICB5ID0gYVsxXTsKICAgICAgdmFyIGxlbiA9IHggKiB4ICsgeSAqIHk7CgogICAgICBpZiAobGVuID4gMCkgewogICAgICAgIC8vVE9ETzogZXZhbHVhdGUgdXNlIG9mIGdsbV9pbnZzcXJ0IGhlcmU/CiAgICAgICAgbGVuID0gMSAvIE1hdGguc3FydChsZW4pOwogICAgICAgIG91dFswXSA9IGFbMF0gKiBsZW47CiAgICAgICAgb3V0WzFdID0gYVsxXSAqIGxlbjsKICAgICAgfQoKICAgICAgcmV0dXJuIG91dDsKICAgIH07CiAgICAvKioKICAgICAqIENhbGN1bGF0ZXMgdGhlIGRvdCBwcm9kdWN0IG9mIHR3byB2ZWMyJ3MKICAgICAqIEBzdGF0aWMKICAgICAqIEBtZXRob2QgZG90CiAgICAgKiBAcGFyYW0ge0FycmF5fSBhIHRoZSBmaXJzdCBvcGVyYW5kCiAgICAgKiBAcGFyYW0ge0FycmF5fSBiIHRoZSBzZWNvbmQgb3BlcmFuZAogICAgICogQHJldHVybiB7TnVtYmVyfSBkb3QgcHJvZHVjdCBvZiBhIGFuZCBiCiAgICAgKi8KCgogICAgdmVjMiRwLmRvdCA9IGZ1bmN0aW9uIChhLCBiKSB7CiAgICAgIHJldHVybiBhWzBdICogYlswXSArIGFbMV0gKiBiWzFdOwogICAgfTsKICAgIC8qKgogICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHZlY3RvcgogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBzdHIKICAgICAqIEBwYXJhbSB7QXJyYXl9IHZlYyB2ZWN0b3IgdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nCiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmVjdG9yCiAgICAgKi8KCgogICAgdmVjMiRwLnN0ciA9IGZ1bmN0aW9uIChhKSB7CiAgICAgIHJldHVybiAndmVjMignICsgYVswXSArICcsICcgKyBhWzFdICsgJyknOwogICAgfTsKICAgIC8qKgogICAgICogTGluZWFybHkgaW50ZXJwb2xhdGUvbWl4IHR3byB2ZWN0b3JzLgogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBsZXJwCiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdXQKICAgICAqIEBwYXJhbSB7QXJyYXl9IGEgRmlyc3QgdmVjdG9yCiAgICAgKiBAcGFyYW0ge0FycmF5fSBiIFNlY29uZCB2ZWN0b3IKICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0IExlcnAgZmFjdG9yCiAgICAgKi8KCgogICAgdmVjMiRwLmxlcnAgPSBmdW5jdGlvbiAob3V0LCBhLCBiLCB0KSB7CiAgICAgIHZhciBheCA9IGFbMF0sCiAgICAgICAgICBheSA9IGFbMV07CiAgICAgIG91dFswXSA9IGF4ICsgdCAqIChiWzBdIC0gYXgpOwogICAgICBvdXRbMV0gPSBheSArIHQgKiAoYlsxXSAtIGF5KTsKICAgICAgcmV0dXJuIG91dDsKICAgIH07CiAgICAvKioKICAgICAqIFJlZmxlY3QgYSB2ZWN0b3IgYWxvbmcgYSBub3JtYWwuCiAgICAgKiBAc3RhdGljCiAgICAgKiBAbWV0aG9kIHJlZmxlY3QKICAgICAqIEBwYXJhbSB7QXJyYXl9IG91dAogICAgICogQHBhcmFtIHtBcnJheX0gdmVjdG9yCiAgICAgKiBAcGFyYW0ge0FycmF5fSBub3JtYWwKICAgICAqLwoKCiAgICB2ZWMyJHAucmVmbGVjdCA9IGZ1bmN0aW9uIChvdXQsIHZlY3Rvciwgbm9ybWFsKSB7CiAgICAgIHZhciBkb3QgPSB2ZWN0b3JbMF0gKiBub3JtYWxbMF0gKyB2ZWN0b3JbMV0gKiBub3JtYWxbMV07CiAgICAgIG91dFswXSA9IHZlY3RvclswXSAtIDIgKiBub3JtYWxbMF0gKiBkb3Q7CiAgICAgIG91dFsxXSA9IHZlY3RvclsxXSAtIDIgKiBub3JtYWxbMV0gKiBkb3Q7CiAgICB9OwogICAgLyoqCiAgICAgKiBHZXQgdGhlIGludGVyc2VjdGlvbiBwb2ludCBiZXR3ZWVuIHR3byBsaW5lIHNlZ21lbnRzLgogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBnZXRMaW5lU2VnbWVudHNJbnRlcnNlY3Rpb24KICAgICAqIEBwYXJhbSAge0FycmF5fSBvdXQKICAgICAqIEBwYXJhbSAge0FycmF5fSBwMAogICAgICogQHBhcmFtICB7QXJyYXl9IHAxCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gcDIKICAgICAqIEBwYXJhbSAge0FycmF5fSBwMwogICAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGVyZSB3YXMgYW4gaW50ZXJzZWN0aW9uLCBvdGhlcndpc2UgZmFsc2UuCiAgICAgKi8KCgogICAgdmVjMiRwLmdldExpbmVTZWdtZW50c0ludGVyc2VjdGlvbiA9IGZ1bmN0aW9uIChvdXQsIHAwLCBwMSwgcDIsIHAzKSB7CiAgICAgIHZhciB0ID0gdmVjMiRwLmdldExpbmVTZWdtZW50c0ludGVyc2VjdGlvbkZyYWN0aW9uKHAwLCBwMSwgcDIsIHAzKTsKCiAgICAgIGlmICh0IDwgMCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBvdXRbMF0gPSBwMFswXSArIHQgKiAocDFbMF0gLSBwMFswXSk7CiAgICAgICAgb3V0WzFdID0gcDBbMV0gKyB0ICogKHAxWzFdIC0gcDBbMV0pOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9OwogICAgLyoqCiAgICAgKiBHZXQgdGhlIGludGVyc2VjdGlvbiBmcmFjdGlvbiBiZXR3ZWVuIHR3byBsaW5lIHNlZ21lbnRzLiBJZiBzdWNjZXNzZnVsLCB0aGUgaW50ZXJzZWN0aW9uIGlzIGF0IHAwICsgdCAqIChwMSAtIHAwKQogICAgICogQHN0YXRpYwogICAgICogQG1ldGhvZCBnZXRMaW5lU2VnbWVudHNJbnRlcnNlY3Rpb25GcmFjdGlvbgogICAgICogQHBhcmFtICB7QXJyYXl9IHAwCiAgICAgKiBAcGFyYW0gIHtBcnJheX0gcDEKICAgICAqIEBwYXJhbSAge0FycmF5fSBwMgogICAgICogQHBhcmFtICB7QXJyYXl9IHAzCiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IEEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSBpZiB0aGVyZSB3YXMgYW4gaW50ZXJzZWN0aW9uLCBvdGhlcndpc2UgLTEuCiAgICAgKi8KCgogICAgdmVjMiRwLmdldExpbmVTZWdtZW50c0ludGVyc2VjdGlvbkZyYWN0aW9uID0gZnVuY3Rpb24gKHAwLCBwMSwgcDIsIHAzKSB7CiAgICAgIHZhciBzMV94ID0gcDFbMF0gLSBwMFswXTsKICAgICAgdmFyIHMxX3kgPSBwMVsxXSAtIHAwWzFdOwogICAgICB2YXIgczJfeCA9IHAzWzBdIC0gcDJbMF07CiAgICAgIHZhciBzMl95ID0gcDNbMV0gLSBwMlsxXTsKICAgICAgdmFyIHMsIHQ7CiAgICAgIHMgPSAoLXMxX3kgKiAocDBbMF0gLSBwMlswXSkgKyBzMV94ICogKHAwWzFdIC0gcDJbMV0pKSAvICgtczJfeCAqIHMxX3kgKyBzMV94ICogczJfeSk7CiAgICAgIHQgPSAoczJfeCAqIChwMFsxXSAtIHAyWzFdKSAtIHMyX3kgKiAocDBbMF0gLSBwMlswXSkpIC8gKC1zMl94ICogczFfeSArIHMxX3ggKiBzMl95KTsKCiAgICAgIGlmIChzID49IDAgJiYgcyA8PSAxICYmIHQgPj0gMCAmJiB0IDw9IDEpIHsKICAgICAgICAvLyBDb2xsaXNpb24gZGV0ZWN0ZWQKICAgICAgICByZXR1cm4gdDsKICAgICAgfQoKICAgICAgcmV0dXJuIC0xOyAvLyBObyBjb2xsaXNpb24KICAgIH07CgogICAgdmFyIHZlYzIkbyA9IHZlYzIkcS5leHBvcnRzOwoKICAgIHZhciBBQUJCXzEgPSBBQUJCJDI7CiAgICAvKioKICAgICAqIEF4aXMgYWxpZ25lZCBib3VuZGluZyBib3ggY2xhc3MuCiAgICAgKiBAY2xhc3MgQUFCQgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge09iamVjdH0gIFtvcHRpb25zXQogICAgICogQHBhcmFtIHtBcnJheX0gICBbb3B0aW9ucy51cHBlckJvdW5kXQogICAgICogQHBhcmFtIHtBcnJheX0gICBbb3B0aW9ucy5sb3dlckJvdW5kXQogICAgICogQGV4YW1wbGUKICAgICAqICAgICB2YXIgYWFiYiA9IG5ldyBBQUJCKHsKICAgICAqICAgICAgICAgdXBwZXJCb3VuZDogWzEsIDFdLAogICAgICogICAgICAgICBsb3dlckJvdW5kOiBbLTEsIC0xXQogICAgICogICAgIH0pOwogICAgICovCgogICAgZnVuY3Rpb24gQUFCQiQyKG9wdGlvbnMpIHsKICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgICAgIC8qKgogICAgICAgKiBUaGUgbG93ZXIgYm91bmQgb2YgdGhlIGJvdW5kaW5nIGJveC4KICAgICAgICogQHByb3BlcnR5IGxvd2VyQm91bmQKICAgICAgICogQHR5cGUge0FycmF5fQogICAgICAgKi8KCiAgICAgIHRoaXMubG93ZXJCb3VuZCA9IG9wdGlvbnMubG93ZXJCb3VuZCA/IHZlYzIkby5jbG9uZShvcHRpb25zLmxvd2VyQm91bmQpIDogdmVjMiRvLmNyZWF0ZSgpOwogICAgICAvKioKICAgICAgICogVGhlIHVwcGVyIGJvdW5kIG9mIHRoZSBib3VuZGluZyBib3guCiAgICAgICAqIEBwcm9wZXJ0eSB1cHBlckJvdW5kCiAgICAgICAqIEB0eXBlIHtBcnJheX0KICAgICAgICovCgogICAgICB0aGlzLnVwcGVyQm91bmQgPSBvcHRpb25zLnVwcGVyQm91bmQgPyB2ZWMyJG8uY2xvbmUob3B0aW9ucy51cHBlckJvdW5kKSA6IHZlYzIkby5jcmVhdGUoKTsKICAgIH0KCiAgICB2YXIgdG1wJDIgPSB2ZWMyJG8uY3JlYXRlKCk7CiAgICAvKioKICAgICAqIFNldCB0aGUgQUFCQiBib3VuZHMgZnJvbSBhIHNldCBvZiBwb2ludHMsIHRyYW5zZm9ybWVkIGJ5IHRoZSBnaXZlbiBwb3NpdGlvbiBhbmQgYW5nbGUuCiAgICAgKiBAbWV0aG9kIHNldEZyb21Qb2ludHMKICAgICAqIEBwYXJhbSB7QXJyYXl9IHBvaW50cyBBbiBhcnJheSBvZiB2ZWMyJ3MuCiAgICAgKiBAcGFyYW0ge0FycmF5fSBwb3NpdGlvbgogICAgICogQHBhcmFtIHtudW1iZXJ9IFthbmdsZT0wXQogICAgICogQHBhcmFtIHtudW1iZXJ9IFtza2luU2l6ZT0wXSBTb21lIG1hcmdpbiB0byBiZSBhZGRlZCB0byB0aGUgQUFCQi4KICAgICAqLwoKICAgIEFBQkIkMi5wcm90b3R5cGUuc2V0RnJvbVBvaW50cyA9IGZ1bmN0aW9uIChwb2ludHMsIHBvc2l0aW9uLCBhbmdsZSwgc2tpblNpemUpIHsKICAgICAgdmFyIGwgPSB0aGlzLmxvd2VyQm91bmQsCiAgICAgICAgICB1ID0gdGhpcy51cHBlckJvdW5kOwogICAgICBhbmdsZSA9IGFuZ2xlIHx8IDA7IC8vIFNldCB0byB0aGUgZmlyc3QgcG9pbnQKCiAgICAgIGlmIChhbmdsZSAhPT0gMCkgewogICAgICAgIHZlYzIkby5yb3RhdGUobCwgcG9pbnRzWzBdLCBhbmdsZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmVjMiRvLmNvcHkobCwgcG9pbnRzWzBdKTsKICAgICAgfQoKICAgICAgdmVjMiRvLmNvcHkodSwgbCk7IC8vIENvbXB1dGUgY29zaW5lcyBhbmQgc2luZXMganVzdCBvbmNlCgogICAgICB2YXIgY29zQW5nbGUgPSBNYXRoLmNvcyhhbmdsZSksCiAgICAgICAgICBzaW5BbmdsZSA9IE1hdGguc2luKGFuZ2xlKTsKCiAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIHAgPSBwb2ludHNbaV07CgogICAgICAgIGlmIChhbmdsZSAhPT0gMCkgewogICAgICAgICAgdmFyIHggPSBwWzBdLAogICAgICAgICAgICAgIHkgPSBwWzFdOwogICAgICAgICAgdG1wJDJbMF0gPSBjb3NBbmdsZSAqIHggLSBzaW5BbmdsZSAqIHk7CiAgICAgICAgICB0bXAkMlsxXSA9IHNpbkFuZ2xlICogeCArIGNvc0FuZ2xlICogeTsKICAgICAgICAgIHAgPSB0bXAkMjsKICAgICAgICB9CgogICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgMjsgaisrKSB7CiAgICAgICAgICBpZiAocFtqXSA+IHVbal0pIHsKICAgICAgICAgICAgdVtqXSA9IHBbal07CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKHBbal0gPCBsW2pdKSB7CiAgICAgICAgICAgIGxbal0gPSBwW2pdOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSAvLyBBZGQgb2Zmc2V0CgoKICAgICAgaWYgKHBvc2l0aW9uKSB7CiAgICAgICAgdmVjMiRvLmFkZChsLCBsLCBwb3NpdGlvbik7CiAgICAgICAgdmVjMiRvLmFkZCh1LCB1LCBwb3NpdGlvbik7CiAgICAgIH0KCiAgICAgIGlmIChza2luU2l6ZSkgewogICAgICAgIGxbMF0gLT0gc2tpblNpemU7CiAgICAgICAgbFsxXSAtPSBza2luU2l6ZTsKICAgICAgICB1WzBdICs9IHNraW5TaXplOwogICAgICAgIHVbMV0gKz0gc2tpblNpemU7CiAgICAgIH0KICAgIH07CiAgICAvKioKICAgICAqIENvcHkgYm91bmRzIGZyb20gYW4gQUFCQiB0byB0aGlzIEFBQkIKICAgICAqIEBtZXRob2QgY29weQogICAgICogQHBhcmFtICB7QUFCQn0gYWFiYgogICAgICovCgoKICAgIEFBQkIkMi5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIChhYWJiKSB7CiAgICAgIHZlYzIkby5jb3B5KHRoaXMubG93ZXJCb3VuZCwgYWFiYi5sb3dlckJvdW5kKTsKICAgICAgdmVjMiRvLmNvcHkodGhpcy51cHBlckJvdW5kLCBhYWJiLnVwcGVyQm91bmQpOwogICAgfTsKICAgIC8qKgogICAgICogRXh0ZW5kIHRoaXMgQUFCQiBzbyB0aGF0IGl0IGNvdmVycyB0aGUgZ2l2ZW4gQUFCQiB0b28uCiAgICAgKiBAbWV0aG9kIGV4dGVuZAogICAgICogQHBhcmFtICB7QUFCQn0gYWFiYgogICAgICovCgoKICAgIEFBQkIkMi5wcm90b3R5cGUuZXh0ZW5kID0gZnVuY3Rpb24gKGFhYmIpIHsKICAgICAgdmFyIGxvd2VyID0gdGhpcy5sb3dlckJvdW5kLAogICAgICAgICAgdXBwZXIgPSB0aGlzLnVwcGVyQm91bmQ7IC8vIExvb3Agb3ZlciB4IGFuZCB5CgogICAgICB2YXIgaSA9IDI7CgogICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgLy8gRXh0ZW5kIGxvd2VyIGJvdW5kCiAgICAgICAgdmFyIGwgPSBhYWJiLmxvd2VyQm91bmRbaV07CgogICAgICAgIGlmIChsb3dlcltpXSA+IGwpIHsKICAgICAgICAgIGxvd2VyW2ldID0gbDsKICAgICAgICB9IC8vIFVwcGVyCgoKICAgICAgICB2YXIgdSA9IGFhYmIudXBwZXJCb3VuZFtpXTsKCiAgICAgICAgaWYgKHVwcGVyW2ldIDwgdSkgewogICAgICAgICAgdXBwZXJbaV0gPSB1OwogICAgICAgIH0KICAgICAgfQogICAgfTsKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBBQUJCIG92ZXJsYXBzIHRoaXMgQUFCQi4KICAgICAqIEBtZXRob2Qgb3ZlcmxhcHMKICAgICAqIEBwYXJhbSAge0FBQkJ9IGFhYmIKICAgICAqIEByZXR1cm4ge0Jvb2xlYW59CiAgICAgKi8KCgogICAgQUFCQiQyLnByb3RvdHlwZS5vdmVybGFwcyA9IGZ1bmN0aW9uIChhYWJiKSB7CiAgICAgIHZhciBsMSA9IHRoaXMubG93ZXJCb3VuZCwKICAgICAgICAgIHUxID0gdGhpcy51cHBlckJvdW5kLAogICAgICAgICAgbDIgPSBhYWJiLmxvd2VyQm91bmQsCiAgICAgICAgICB1MiA9IGFhYmIudXBwZXJCb3VuZDsgLy8gICAgICBsMiAgICAgICAgdTIKICAgICAgLy8gICAgICB8LS0tLS0tLS0tfAogICAgICAvLyB8LS0tLS0tLS18CiAgICAgIC8vIGwxICAgICAgIHUxCgogICAgICByZXR1cm4gKGwyWzBdIDw9IHUxWzBdICYmIHUxWzBdIDw9IHUyWzBdIHx8IGwxWzBdIDw9IHUyWzBdICYmIHUyWzBdIDw9IHUxWzBdKSAmJiAobDJbMV0gPD0gdTFbMV0gJiYgdTFbMV0gPD0gdTJbMV0gfHwgbDFbMV0gPD0gdTJbMV0gJiYgdTJbMV0gPD0gdTFbMV0pOwogICAgfTsKICAgIC8qKgogICAgICogQG1ldGhvZCBjb250YWluc1BvaW50CiAgICAgKiBAcGFyYW0gIHtBcnJheX0gcG9pbnQKICAgICAqIEByZXR1cm4ge2Jvb2xlYW59CiAgICAgKi8KCgogICAgQUFCQiQyLnByb3RvdHlwZS5jb250YWluc1BvaW50ID0gZnVuY3Rpb24gKHBvaW50KSB7CiAgICAgIHZhciBsID0gdGhpcy5sb3dlckJvdW5kLAogICAgICAgICAgdSA9IHRoaXMudXBwZXJCb3VuZDsKICAgICAgcmV0dXJuIGxbMF0gPD0gcG9pbnRbMF0gJiYgcG9pbnRbMF0gPD0gdVswXSAmJiBsWzFdIDw9IHBvaW50WzFdICYmIHBvaW50WzFdIDw9IHVbMV07CiAgICB9OwogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGUgQUFCQiBpcyBoaXQgYnkgYSByYXkuCiAgICAgKiBAbWV0aG9kIG92ZXJsYXBzUmF5CiAgICAgKiBAcGFyYW0gIHtSYXl9IHJheQogICAgICogQHJldHVybiB7bnVtYmVyfSAtMSBpZiBubyBoaXQsIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSBpZiBoaXQsIGluZGljYXRpbmcgdGhlIHBvc2l0aW9uIGJldHdlZW4gdGhlICJmcm9tIiBhbmQgInRvIiBwb2ludHMuCiAgICAgKiBAZXhhbXBsZQogICAgICogICAgIHZhciBhYWJiID0gbmV3IEFBQkIoewogICAgICogICAgICAgICB1cHBlckJvdW5kOiBbMSwgMV0sCiAgICAgKiAgICAgICAgIGxvd2VyQm91bmQ6IFstMSwgLTFdCiAgICAgKiAgICAgfSk7CiAgICAgKiAgICAgdmFyIHJheSA9IG5ldyBSYXkoewogICAgICogICAgICAgICBmcm9tOiBbLTIsIDBdLAogICAgICogICAgICAgICB0bzogWzAsIDBdCiAgICAgKiAgICAgfSk7CiAgICAgKiAgICAgdmFyIGZyYWN0aW9uID0gYWFiYi5vdmVybGFwc1JheShyYXkpOyAvLyBmcmFjdGlvbiA9PSAwLjUKICAgICAqLwoKCiAgICBBQUJCJDIucHJvdG90eXBlLm92ZXJsYXBzUmF5ID0gZnVuY3Rpb24gKHJheSkgewogICAgICAvLyByYXkuZGlyZWN0aW9uIGlzIHVuaXQgZGlyZWN0aW9uIHZlY3RvciBvZiByYXkKICAgICAgdmFyIGRpckZyYWNYID0gMSAvIHJheS5kaXJlY3Rpb25bMF07CiAgICAgIHZhciBkaXJGcmFjWSA9IDEgLyByYXkuZGlyZWN0aW9uWzFdOyAvLyB0aGlzLmxvd2VyQm91bmQgaXMgdGhlIGNvcm5lciBvZiBBQUJCIHdpdGggbWluaW1hbCBjb29yZGluYXRlcyAtIGxlZnQgYm90dG9tLCBydCBpcyBtYXhpbWFsIGNvcm5lcgoKICAgICAgdmFyIGZyb20gPSByYXkuZnJvbTsKICAgICAgdmFyIGxvd2VyQm91bmQgPSB0aGlzLmxvd2VyQm91bmQ7CiAgICAgIHZhciB1cHBlckJvdW5kID0gdGhpcy51cHBlckJvdW5kOwogICAgICB2YXIgdDEgPSAobG93ZXJCb3VuZFswXSAtIGZyb21bMF0pICogZGlyRnJhY1g7CiAgICAgIHZhciB0MiA9ICh1cHBlckJvdW5kWzBdIC0gZnJvbVswXSkgKiBkaXJGcmFjWDsKICAgICAgdmFyIHQzID0gKGxvd2VyQm91bmRbMV0gLSBmcm9tWzFdKSAqIGRpckZyYWNZOwogICAgICB2YXIgdDQgPSAodXBwZXJCb3VuZFsxXSAtIGZyb21bMV0pICogZGlyRnJhY1k7CiAgICAgIHZhciB0bWluID0gTWF0aC5tYXgoTWF0aC5tYXgoTWF0aC5taW4odDEsIHQyKSwgTWF0aC5taW4odDMsIHQ0KSkpOwogICAgICB2YXIgdG1heCA9IE1hdGgubWluKE1hdGgubWluKE1hdGgubWF4KHQxLCB0MiksIE1hdGgubWF4KHQzLCB0NCkpKTsgLy8gaWYgdG1heCA8IDAsIHJheSAobGluZSkgaXMgaW50ZXJzZWN0aW5nIEFBQkIsIGJ1dCB3aG9sZSBBQUJCIGlzIGJlaGluZyB1cwoKICAgICAgaWYgKHRtYXggPCAwKSB7CiAgICAgICAgLy90ID0gdG1heDsKICAgICAgICByZXR1cm4gLTE7CiAgICAgIH0gLy8gaWYgdG1pbiA+IHRtYXgsIHJheSBkb2Vzbid0IGludGVyc2VjdCBBQUJCCgoKICAgICAgaWYgKHRtaW4gPiB0bWF4KSB7CiAgICAgICAgLy90ID0gdG1heDsKICAgICAgICByZXR1cm4gLTE7CiAgICAgIH0KCiAgICAgIHJldHVybiB0bWluIC8gcmF5Lmxlbmd0aDsKICAgIH07CgogICAgdmFyIEVxdWF0aW9uXzEgPSBFcXVhdGlvbiRhOwoKICAgIHZhciB2ZWMyJG4gPSB2ZWMyJHEuZXhwb3J0cywKICAgICAgICBzY2FsZSQxID0gdmVjMiRuLnNjYWxlLAogICAgICAgIG11bHRpcGx5ID0gdmVjMiRuLm11bHRpcGx5LAogICAgICAgIGNyZWF0ZVZlYzIkMSA9IHZlYzIkbi5jcmVhdGUsCiAgICAgICAgVXRpbHMkNSA9IFV0aWxzXzE7CiAgICAvKioKICAgICAqIEJhc2UgY2xhc3MgZm9yIGNvbnN0cmFpbnQgZXF1YXRpb25zLgogICAgICogQGNsYXNzIEVxdWF0aW9uCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7Qm9keX0gYm9keUEgRmlyc3QgYm9keSBwYXJ0aWNpcGF0aW5nIGluIHRoZSBlcXVhdGlvbgogICAgICogQHBhcmFtIHtCb2R5fSBib2R5QiBTZWNvbmQgYm9keSBwYXJ0aWNpcGF0aW5nIGluIHRoZSBlcXVhdGlvbgogICAgICogQHBhcmFtIHtudW1iZXJ9IG1pbkZvcmNlIE1pbmltdW0gZm9yY2UgdG8gYXBwbHkuIERlZmF1bHQ6IC1OdW1iZXIuTUFYX1ZBTFVFCiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4Rm9yY2UgTWF4aW11bSBmb3JjZSB0byBhcHBseS4gRGVmYXVsdDogTnVtYmVyLk1BWF9WQUxVRQogICAgICovCgoKICAgIGZ1bmN0aW9uIEVxdWF0aW9uJGEoYm9keUEsIGJvZHlCLCBtaW5Gb3JjZSwgbWF4Rm9yY2UpIHsKICAgICAgLyoqCiAgICAgICAqIE1pbmltdW0gZm9yY2UgdG8gYXBwbHkgd2hlbiBzb2x2aW5nLgogICAgICAgKiBAcHJvcGVydHkgbWluRm9yY2UKICAgICAgICogQHR5cGUge051bWJlcn0KICAgICAgICovCiAgICAgIHRoaXMubWluRm9yY2UgPSBtaW5Gb3JjZSA9PT0gdW5kZWZpbmVkID8gLU51bWJlci5NQVhfVkFMVUUgOiBtaW5Gb3JjZTsKICAgICAgLyoqCiAgICAgICAqIE1heCBmb3JjZSB0byBhcHBseSB3aGVuIHNvbHZpbmcuCiAgICAgICAqIEBwcm9wZXJ0eSBtYXhGb3JjZQogICAgICAgKiBAdHlwZSB7TnVtYmVyfQogICAgICAgKi8KCiAgICAgIHRoaXMubWF4Rm9yY2UgPSBtYXhGb3JjZSA9PT0gdW5kZWZpbmVkID8gTnVtYmVyLk1BWF9WQUxVRSA6IG1heEZvcmNlOwogICAgICAvKioKICAgICAgICogQ2FwIHRoZSBjb25zdHJhaW50IHZpb2xhdGlvbiAoRypxKSB0byB0aGlzIHZhbHVlLgogICAgICAgKiBAcHJvcGVydHkgbWF4QmlhcwogICAgICAgKiBAdHlwZSB7TnVtYmVyfQogICAgICAgKi8KCiAgICAgIHRoaXMubWF4QmlhcyA9IE51bWJlci5NQVhfVkFMVUU7CiAgICAgIC8qKgogICAgICAgKiBGaXJzdCBib2R5IHBhcnRpY2lwYXRpbmcgaW4gdGhlIGNvbnN0cmFpbnQKICAgICAgICogQHByb3BlcnR5IGJvZHlBCiAgICAgICAqIEB0eXBlIHtCb2R5fQogICAgICAgKi8KCiAgICAgIHRoaXMuYm9keUEgPSBib2R5QTsKICAgICAgLyoqCiAgICAgICAqIFNlY29uZCBib2R5IHBhcnRpY2lwYXRpbmcgaW4gdGhlIGNvbnN0cmFpbnQKICAgICAgICogQHByb3BlcnR5IGJvZHlCCiAgICAgICAqIEB0eXBlIHtCb2R5fQogICAgICAgKi8KCiAgICAgIHRoaXMuYm9keUIgPSBib2R5QjsKICAgICAgLyoqCiAgICAgICAqIFRoZSBzdGlmZm5lc3Mgb2YgdGhpcyBlcXVhdGlvbi4gVHlwaWNhbGx5IGNob3NlbiB0byBhIGxhcmdlIG51bWJlciAofjFlNyksIGJ1dCBjYW4gYmUgY2hvc2VuIHNvbWV3aGF0IGZyZWVseSB0byBnZXQgYSBzdGFibGUgc2ltdWxhdGlvbi4KICAgICAgICogQHByb3BlcnR5IHN0aWZmbmVzcwogICAgICAgKiBAdHlwZSB7TnVtYmVyfQogICAgICAgKi8KCiAgICAgIHRoaXMuc3RpZmZuZXNzID0gRXF1YXRpb24kYS5ERUZBVUxUX1NUSUZGTkVTUzsKICAgICAgLyoqCiAgICAgICAqIFRoZSBudW1iZXIgb2YgdGltZSBzdGVwcyBuZWVkZWQgdG8gc3RhYmlsaXplIHRoZSBjb25zdHJhaW50IGVxdWF0aW9uLiBUeXBpY2FsbHkgYmV0d2VlbiAzIGFuZCA1IHRpbWUgc3RlcHMuCiAgICAgICAqIEBwcm9wZXJ0eSByZWxheGF0aW9uCiAgICAgICAqIEB0eXBlIHtOdW1iZXJ9CiAgICAgICAqLwoKICAgICAgdGhpcy5yZWxheGF0aW9uID0gRXF1YXRpb24kYS5ERUZBVUxUX1JFTEFYQVRJT047CiAgICAgIC8qKgogICAgICAgKiBUaGUgSmFjb2JpYW4gZW50cnkgb2YgdGhpcyBlcXVhdGlvbi4gNiBudW1iZXJzLCAzIHBlciBib2R5ICh4LHksYW5nbGUpLgogICAgICAgKiBAcHJvcGVydHkgRwogICAgICAgKiBAdHlwZSB7QXJyYXl9CiAgICAgICAqLwoKICAgICAgdGhpcy5HID0gbmV3IFV0aWxzJDUuQVJSQVlfVFlQRSg2KTsKCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNjsgaSsrKSB7CiAgICAgICAgdGhpcy5HW2ldID0gMDsKICAgICAgfQoKICAgICAgdGhpcy5vZmZzZXQgPSAwOwogICAgICB0aGlzLmEgPSAwOwogICAgICB0aGlzLmIgPSAwOwogICAgICB0aGlzLmVwc2lsb24gPSAwOwogICAgICB0aGlzLnRpbWVTdGVwID0gMSAvIDYwOwogICAgICAvKioKICAgICAgICogSW5kaWNhdGVzIGlmIHN0aWZmbmVzcyBvciByZWxheGF0aW9uIHdhcyBjaGFuZ2VkLgogICAgICAgKiBAcHJvcGVydHkge0Jvb2xlYW59IG5lZWRzVXBkYXRlCiAgICAgICAqLwoKICAgICAgdGhpcy5uZWVkc1VwZGF0ZSA9IHRydWU7CiAgICAgIC8qKgogICAgICAgKiBUaGUgcmVzdWx0aW5nIGNvbnN0cmFpbnQgbXVsdGlwbGllciBmcm9tIHRoZSBsYXN0IHNvbHZlLiBUaGlzIGlzIG1vc3RseSBlcXVpdmFsZW50IHRvIHRoZSBmb3JjZSBwcm9kdWNlZCBieSB0aGUgY29uc3RyYWludC4KICAgICAgICogQHByb3BlcnR5IG11bHRpcGxpZXIKICAgICAgICogQHR5cGUge051bWJlcn0KICAgICAgICovCgogICAgICB0aGlzLm11bHRpcGxpZXIgPSAwOwogICAgICAvKioKICAgICAgICogUmVsYXRpdmUgdmVsb2NpdHkuCiAgICAgICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSByZWxhdGl2ZVZlbG9jaXR5CiAgICAgICAqLwoKICAgICAgdGhpcy5yZWxhdGl2ZVZlbG9jaXR5ID0gMDsKICAgICAgLyoqCiAgICAgICAqIFdoZXRoZXIgdGhpcyBlcXVhdGlvbiBpcyBlbmFibGVkIG9yIG5vdC4gSWYgdHJ1ZSwgaXQgd2lsbCBiZSBhZGRlZCB0byB0aGUgc29sdmVyLgogICAgICAgKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZWQKICAgICAgICovCgogICAgICB0aGlzLmVuYWJsZWQgPSB0cnVlOyAvLyBUZW1wIHN0dWZmCgogICAgICB0aGlzLmxhbWJkYSA9IHRoaXMuQiA9IHRoaXMuaW52QyA9IHRoaXMubWluRm9yY2VEdCA9IHRoaXMubWF4Rm9yY2VEdCA9IDA7CiAgICAgIHRoaXMuaW5kZXggPSAtMTsKICAgIH0KICAgIC8qKgogICAgICogVGhlIGRlZmF1bHQgc3RpZmZuZXNzIHdoZW4gY3JlYXRpbmcgYSBuZXcgRXF1YXRpb24uCiAgICAgKiBAc3RhdGljCiAgICAgKiBAcHJvcGVydHkge051bWJlcn0gREVGQVVMVF9TVElGRk5FU1MKICAgICAqIEBkZWZhdWx0IDFlNgogICAgICovCgoKICAgIEVxdWF0aW9uJGEuREVGQVVMVF9TVElGRk5FU1MgPSAxZTY7CiAgICAvKioKICAgICAqIFRoZSBkZWZhdWx0IHJlbGF4YXRpb24gd2hlbiBjcmVhdGluZyBhIG5ldyBFcXVhdGlvbi4KICAgICAqIEBzdGF0aWMKICAgICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBERUZBVUxUX1JFTEFYQVRJT04KICAgICAqIEBkZWZhdWx0IDQKICAgICAqLwoKICAgIEVxdWF0aW9uJGEuREVGQVVMVF9SRUxBWEFUSU9OID0gNDsKICAgIHZhciBxaSA9IGNyZWF0ZVZlYzIkMSgpLAogICAgICAgIHFqID0gY3JlYXRlVmVjMiQxKCksCiAgICAgICAgaU1maSA9IGNyZWF0ZVZlYzIkMSgpLAogICAgICAgIGlNZmogPSBjcmVhdGVWZWMyJDEoKTsKICAgIEVxdWF0aW9uJGEucHJvdG90eXBlID0gewogICAgICAvKioKICAgICAgICogQ29tcHV0ZSBTUE9PSyBwYXJhbWV0ZXJzIC5hLCAuYiBhbmQgLmVwc2lsb24gYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50IHBhcmFtZXRlcnMuIFNlZSBlcXVhdGlvbnMgOSwgMTAgYW5kIDExIGluIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3OC5jcy51bXUuc2Uva3Vyc2VyLzVEVjA1OC9WVDA5L2xlY3R1cmVzL3Nwb29rbm90ZXMucGRmIj5TUE9PSyBub3RlczwvYT4uCiAgICAgICAqIEBtZXRob2QgdXBkYXRlCiAgICAgICAqLwogICAgICB1cGRhdGU6IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgayA9IHRoaXMuc3RpZmZuZXNzLAogICAgICAgICAgICBkID0gdGhpcy5yZWxheGF0aW9uLAogICAgICAgICAgICBoID0gdGhpcy50aW1lU3RlcDsKICAgICAgICB0aGlzLmEgPSA0IC8gKGggKiAoMSArIDQgKiBkKSk7CiAgICAgICAgdGhpcy5iID0gNCAqIGQgLyAoMSArIDQgKiBkKTsKICAgICAgICB0aGlzLmVwc2lsb24gPSA0IC8gKGggKiBoICogayAqICgxICsgNCAqIGQpKTsKICAgICAgICB0aGlzLm5lZWRzVXBkYXRlID0gZmFsc2U7CiAgICAgIH0sCgogICAgICAvKioKICAgICAgICogTXVsdGlwbHkgYSBqYWNvYmlhbiBlbnRyeSB3aXRoIGNvcnJlc3BvbmRpbmcgcG9zaXRpb25zIG9yIHZlbG9jaXRpZXMKICAgICAgICogQG1ldGhvZCBnbXVsdAogICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9CiAgICAgICAqLwogICAgICBnbXVsdDogZnVuY3Rpb24gKEcsIHZpLCB3aSwgdmosIHdqKSB7CiAgICAgICAgcmV0dXJuIEdbMF0gKiB2aVswXSArIEdbMV0gKiB2aVsxXSArIEdbMl0gKiB3aSArIEdbM10gKiB2alswXSArIEdbNF0gKiB2alsxXSArIEdbNV0gKiB3ajsKICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKiBDb21wdXRlcyB0aGUgUkhTIG9mIHRoZSBTUE9PSyBlcXVhdGlvbgogICAgICAgKiBAbWV0aG9kIGNvbXB1dGVCCiAgICAgICAqIEByZXR1cm4ge051bWJlcn0KICAgICAgICovCiAgICAgIGNvbXB1dGVCOiBmdW5jdGlvbiAoYSwgYiwgaCkgewogICAgICAgIHZhciBHVyA9IHRoaXMuY29tcHV0ZUdXKCk7CiAgICAgICAgdmFyIEdxID0gdGhpcy5jb21wdXRlR3EoKTsKICAgICAgICB2YXIgbWF4QmlhcyA9IHRoaXMubWF4QmlhczsKCiAgICAgICAgaWYgKE1hdGguYWJzKEdxKSA+IG1heEJpYXMpIHsKICAgICAgICAgIEdxID0gR3EgPiAwID8gbWF4QmlhcyA6IC1tYXhCaWFzOwogICAgICAgIH0KCiAgICAgICAgdmFyIEdpTWYgPSB0aGlzLmNvbXB1dGVHaU1mKCk7CiAgICAgICAgdmFyIEIgPSAtR3EgKiBhIC0gR1cgKiBiIC0gR2lNZiAqIGg7CiAgICAgICAgcmV0dXJuIEI7CiAgICAgIH0sCgogICAgICAvKioKICAgICAgICogQ29tcHV0ZXMgR1wqcSwgd2hlcmUgcSBhcmUgdGhlIGdlbmVyYWxpemVkIGJvZHkgY29vcmRpbmF0ZXMKICAgICAgICogQG1ldGhvZCBjb21wdXRlR3EKICAgICAgICogQHJldHVybiB7TnVtYmVyfQogICAgICAgKi8KICAgICAgY29tcHV0ZUdxOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIEcgPSB0aGlzLkcsCiAgICAgICAgICAgIGJpID0gdGhpcy5ib2R5QSwKICAgICAgICAgICAgYmogPSB0aGlzLmJvZHlCLAogICAgICAgICAgICBhaSA9IGJpLmFuZ2xlLAogICAgICAgICAgICBhaiA9IGJqLmFuZ2xlOwogICAgICAgIHJldHVybiB0aGlzLmdtdWx0KEcsIHFpLCBhaSwgcWosIGFqKSArIHRoaXMub2Zmc2V0OwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIENvbXB1dGVzIEdcKlcsIHdoZXJlIFcgYXJlIHRoZSBib2R5IHZlbG9jaXRpZXMKICAgICAgICogQG1ldGhvZCBjb21wdXRlR1cKICAgICAgICogQHJldHVybiB7TnVtYmVyfQogICAgICAgKi8KICAgICAgY29tcHV0ZUdXOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIEcgPSB0aGlzLkcsCiAgICAgICAgICAgIGJpID0gdGhpcy5ib2R5QSwKICAgICAgICAgICAgYmogPSB0aGlzLmJvZHlCLAogICAgICAgICAgICB2aSA9IGJpLnZlbG9jaXR5LAogICAgICAgICAgICB2aiA9IGJqLnZlbG9jaXR5LAogICAgICAgICAgICB3aSA9IGJpLmFuZ3VsYXJWZWxvY2l0eSwKICAgICAgICAgICAgd2ogPSBiai5hbmd1bGFyVmVsb2NpdHk7CiAgICAgICAgcmV0dXJuIHRoaXMuZ211bHQoRywgdmksIHdpLCB2aiwgd2opICsgdGhpcy5yZWxhdGl2ZVZlbG9jaXR5OwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIENvbXB1dGVzIEdcKldsYW1iZGEsIHdoZXJlIFcgYXJlIHRoZSBib2R5IHZlbG9jaXRpZXMKICAgICAgICogQG1ldGhvZCBjb21wdXRlR1dsYW1iZGEKICAgICAgICogQHJldHVybiB7TnVtYmVyfQogICAgICAgKi8KICAgICAgY29tcHV0ZUdXbGFtYmRhOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIEcgPSB0aGlzLkcsCiAgICAgICAgICAgIGJpID0gdGhpcy5ib2R5QSwKICAgICAgICAgICAgYmogPSB0aGlzLmJvZHlCLAogICAgICAgICAgICB2aSA9IGJpLnZsYW1iZGEsCiAgICAgICAgICAgIHZqID0gYmoudmxhbWJkYSwKICAgICAgICAgICAgd2kgPSBiaS53bGFtYmRhLAogICAgICAgICAgICB3aiA9IGJqLndsYW1iZGE7CiAgICAgICAgcmV0dXJuIHRoaXMuZ211bHQoRywgdmksIHdpLCB2aiwgd2opOwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIENvbXB1dGVzIEdcKmludihNKVwqZiwgd2hlcmUgTSBpcyB0aGUgbWFzcyBtYXRyaXggd2l0aCBkaWFnb25hbCBibG9ja3MgZm9yIGVhY2ggYm9keSwgYW5kIGYgYXJlIHRoZSBmb3JjZXMgb24gdGhlIGJvZGllcy4KICAgICAgICogQG1ldGhvZCBjb21wdXRlR2lNZgogICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9CiAgICAgICAqLwogICAgICBjb21wdXRlR2lNZjogZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBiaSA9IHRoaXMuYm9keUEsCiAgICAgICAgICAgIGJqID0gdGhpcy5ib2R5QiwKICAgICAgICAgICAgZmkgPSBiaS5mb3JjZSwKICAgICAgICAgICAgdGkgPSBiaS5hbmd1bGFyRm9yY2UsCiAgICAgICAgICAgIGZqID0gYmouZm9yY2UsCiAgICAgICAgICAgIHRqID0gYmouYW5ndWxhckZvcmNlLAogICAgICAgICAgICBpbnZNYXNzaSA9IGJpLmludk1hc3NTb2x2ZSwKICAgICAgICAgICAgaW52TWFzc2ogPSBiai5pbnZNYXNzU29sdmUsCiAgICAgICAgICAgIGludklpID0gYmkuaW52SW5lcnRpYVNvbHZlLAogICAgICAgICAgICBpbnZJaiA9IGJqLmludkluZXJ0aWFTb2x2ZSwKICAgICAgICAgICAgRyA9IHRoaXMuRzsKICAgICAgICBzY2FsZSQxKGlNZmksIGZpLCBpbnZNYXNzaSk7CiAgICAgICAgbXVsdGlwbHkoaU1maSwgYmkubWFzc011bHRpcGxpZXIsIGlNZmkpOwogICAgICAgIHNjYWxlJDEoaU1maiwgZmosIGludk1hc3NqKTsKICAgICAgICBtdWx0aXBseShpTWZqLCBiai5tYXNzTXVsdGlwbGllciwgaU1maik7CiAgICAgICAgcmV0dXJuIHRoaXMuZ211bHQoRywgaU1maSwgdGkgKiBpbnZJaSwgaU1maiwgdGogKiBpbnZJaik7CiAgICAgIH0sCgogICAgICAvKioKICAgICAgICogQ29tcHV0ZXMgR1wqaW52KE0pXCpHJwogICAgICAgKiBAbWV0aG9kIGNvbXB1dGVHaU1HdAogICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9CiAgICAgICAqLwogICAgICBjb21wdXRlR2lNR3Q6IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgYmkgPSB0aGlzLmJvZHlBLAogICAgICAgICAgICBiaiA9IHRoaXMuYm9keUIsCiAgICAgICAgICAgIGludk1hc3NpID0gYmkuaW52TWFzc1NvbHZlLAogICAgICAgICAgICBpbnZNYXNzaiA9IGJqLmludk1hc3NTb2x2ZSwKICAgICAgICAgICAgaW52SWkgPSBiaS5pbnZJbmVydGlhU29sdmUsCiAgICAgICAgICAgIGludklqID0gYmouaW52SW5lcnRpYVNvbHZlLAogICAgICAgICAgICBHID0gdGhpcy5HOwogICAgICAgIHJldHVybiBHWzBdICogR1swXSAqIGludk1hc3NpICogYmkubWFzc011bHRpcGxpZXJbMF0gKyBHWzFdICogR1sxXSAqIGludk1hc3NpICogYmkubWFzc011bHRpcGxpZXJbMV0gKyBHWzJdICogR1syXSAqIGludklpICsgR1szXSAqIEdbM10gKiBpbnZNYXNzaiAqIGJqLm1hc3NNdWx0aXBsaWVyWzBdICsgR1s0XSAqIEdbNF0gKiBpbnZNYXNzaiAqIGJqLm1hc3NNdWx0aXBsaWVyWzFdICsgR1s1XSAqIEdbNV0gKiBpbnZJajsKICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKiBBZGQgY29uc3RyYWludCB2ZWxvY2l0eSB0byB0aGUgYm9kaWVzLgogICAgICAgKiBAbWV0aG9kIGFkZFRvV2xhbWJkYQogICAgICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFsYW1iZGEKICAgICAgICovCiAgICAgIGFkZFRvV2xhbWJkYTogZnVuY3Rpb24gKGRlbHRhbGFtYmRhKSB7CiAgICAgICAgdmFyIGJpID0gdGhpcy5ib2R5QSwKICAgICAgICAgICAgYmogPSB0aGlzLmJvZHlCLAogICAgICAgICAgICBpbnZNYXNzaSA9IGJpLmludk1hc3NTb2x2ZSwKICAgICAgICAgICAgaW52TWFzc2ogPSBiai5pbnZNYXNzU29sdmUsCiAgICAgICAgICAgIGludklpID0gYmkuaW52SW5lcnRpYVNvbHZlLAogICAgICAgICAgICBpbnZJaiA9IGJqLmludkluZXJ0aWFTb2x2ZSwKICAgICAgICAgICAgRyA9IHRoaXMuRzsgLy8gdl9sYW1iZGEgPSBHICogaW52KE0pICogZGVsdGFfbGFtYmRhCgogICAgICAgIGFkZFRvVkxhbWJkYShiaS52bGFtYmRhLCBHWzBdLCBHWzFdLCBpbnZNYXNzaSwgZGVsdGFsYW1iZGEsIGJpLm1hc3NNdWx0aXBsaWVyKTsKICAgICAgICBiaS53bGFtYmRhICs9IGludklpICogR1syXSAqIGRlbHRhbGFtYmRhOwogICAgICAgIGFkZFRvVkxhbWJkYShiai52bGFtYmRhLCBHWzNdLCBHWzRdLCBpbnZNYXNzaiwgZGVsdGFsYW1iZGEsIGJqLm1hc3NNdWx0aXBsaWVyKTsKICAgICAgICBiai53bGFtYmRhICs9IGludklqICogR1s1XSAqIGRlbHRhbGFtYmRhOwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIENvbXB1dGUgdGhlIGRlbm9taW5hdG9yIHBhcnQgb2YgdGhlIFNQT09LIGVxdWF0aW9uOiBDID0gR1wqaW52KE0pXCpHJyArIGVwcwogICAgICAgKiBAbWV0aG9kIGNvbXB1dGVJbnZDCiAgICAgICAqIEBwYXJhbSAge051bWJlcn0gZXBzCiAgICAgICAqIEByZXR1cm4ge051bWJlcn0KICAgICAgICovCiAgICAgIGNvbXB1dGVJbnZDOiBmdW5jdGlvbiAoZXBzKSB7CiAgICAgICAgdmFyIGludkMgPSAxIC8gKHRoaXMuY29tcHV0ZUdpTUd0KCkgKyBlcHMpOwogICAgICAgIHJldHVybiBpbnZDOwogICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIGFkZFRvVkxhbWJkYSh2bGFtYmRhLCBHeCwgR3ksIGludk1hc3MsIGRlbHRhbGFtYmRhLCBtYXNzTXVsdGlwbGllcikgewogICAgICB2bGFtYmRhWzBdICs9IEd4ICogaW52TWFzcyAqIGRlbHRhbGFtYmRhICogbWFzc011bHRpcGxpZXJbMF07CiAgICAgIHZsYW1iZGFbMV0gKz0gR3kgKiBpbnZNYXNzICogZGVsdGFsYW1iZGEgKiBtYXNzTXVsdGlwbGllclsxXTsKICAgIH0KCiAgICB2YXIgRXF1YXRpb24kOSA9IEVxdWF0aW9uXzE7CgogICAgdmFyIEFuZ2xlTG9ja0VxdWF0aW9uXzEgPSBBbmdsZUxvY2tFcXVhdGlvbiQxOwogICAgLyoqCiAgICAgKiBMb2NrcyB0aGUgcmVsYXRpdmUgYW5nbGUgYmV0d2VlbiB0d28gYm9kaWVzLiBUaGUgY29uc3RyYWludCB0cmllcyB0byBrZWVwIHRoZSBkb3QgcHJvZHVjdCBiZXR3ZWVuIHR3byB2ZWN0b3JzLCBsb2NhbCBpbiBlYWNoIGJvZHksIHRvIHplcm8uIFRoZSBsb2NhbCBhbmdsZSBpbiBib2R5IGkgaXMgYSBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQGNsYXNzIEFuZ2xlTG9ja0VxdWF0aW9uCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBleHRlbmRzIEVxdWF0aW9uCiAgICAgKiBAcGFyYW0ge0JvZHl9IGJvZHlBCiAgICAgKiBAcGFyYW0ge0JvZHl9IGJvZHlCCiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdCiAgICAg