{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/@fingerprintjs/fingerprintjs/dist/fp.cjs.js","node_modules/@microsoft/signalr/dist/cjs/AbortController.js","node_modules/@microsoft/signalr/dist/cjs/DefaultHttpClient.js","node_modules/@microsoft/signalr/dist/cjs/DefaultReconnectPolicy.js","node_modules/@microsoft/signalr/dist/cjs/Errors.js","node_modules/@microsoft/signalr/dist/cjs/FetchHttpClient.js","node_modules/@microsoft/signalr/dist/cjs/HandshakeProtocol.js","node_modules/@microsoft/signalr/dist/cjs/HttpClient.js","node_modules/@microsoft/signalr/dist/cjs/HttpConnection.js","node_modules/@microsoft/signalr/dist/cjs/HubConnection.js","node_modules/@microsoft/signalr/dist/cjs/HubConnectionBuilder.js","node_modules/@microsoft/signalr/dist/cjs/IHubProtocol.js","node_modules/@microsoft/signalr/dist/cjs/ILogger.js","node_modules/@microsoft/signalr/dist/cjs/ITransport.js","node_modules/@microsoft/signalr/dist/cjs/JsonHubProtocol.js","node_modules/@microsoft/signalr/dist/cjs/Loggers.js","node_modules/@microsoft/signalr/dist/cjs/LongPollingTransport.js","node_modules/@microsoft/signalr/dist/cjs/ServerSentEventsTransport.js","node_modules/@microsoft/signalr/dist/cjs/Subject.js","node_modules/@microsoft/signalr/dist/cjs/TextMessageFormat.js","node_modules/@microsoft/signalr/dist/cjs/Utils.js","node_modules/@microsoft/signalr/dist/cjs/WebSocketTransport.js","node_modules/@microsoft/signalr/dist/cjs/XhrHttpClient.js","node_modules/@microsoft/signalr/dist/cjs/index.js","node_modules/base64-js/index.js","node_modules/buffer/index.js","node_modules/ieee754/index.js","node_modules/process/browser.js","node_modules/tslib/tslib.js","src/js/app/main.ts","src/js/app/toaster.ts"],"names":[],"mappings":"AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7nFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACv7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AClTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACtJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACjvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACraA,iBA4GC;;;;AA3GD,kEAA8C;AAC9C,kFAA6D;AAC7D,qCAAqC;AACxB,QAAA,UAAU,GAAG,IAAI,OAAO,CAAC,oBAAoB,EAAE;KACzD,OAAO,CAAC,aAAa,CAAC;KACtB,sBAAsB,EAAE;IACzB,4CAA4C;KAC3C,KAAK,EAAE,CAAC;AACX,qCAAoC;AAKpC,CAAC,CAAC;IACA,kBAAU,CAAC,EAAE,CAAC,OAAO,EACnB,UAAC,IAAY,EAAE,OAAe;QAC5B,iBAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEL,kBAAU,CAAC,EAAE,CAAC,sBAAsB,EAClC;QACE,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACnD,CAAC,CAAC,CAAC;IAEL,kBAAU,CAAC,EAAE,CAAC,MAAM,EAClB,UAAC,OAAe;QACd,iBAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEL,kBAAU,CAAC,EAAE,CAAC,mBAAmB,EAC/B,UAAC,UAAuB,EAAE,QAAgB,EAAE,IAAY;QACtD,0BAA0B;IAC5B,CAAC,CAAC,CAAC;IAEL,IAAI,kBAAU,CAAC,KAAK,KAAK,cAAc,EAAE,EAAE,wCAAwC;QACjF,kBAAU,CAAC,KAAK,EAAE;aACf,IAAI,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,YAAY,EAAE,CAAC;YACf,qBAAqB,EAAE,CAAC;QAC1B,CAAC,CAAC;aACD,KAAK,CAAC,UAAC,KAAK;YACX,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChC,iBAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;KACN;IAED,kBAAU,CAAC,OAAO,CAAC,UAAC,KAAa;QAC/B,IAAI,KAAK,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;SACjD;aAAM;YACL,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;SACxC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAgB,YAAY;IAC1B,IAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,aAAa,CAAE,CAAC,CAAA,CAAC,mEAAmE;IAC3H,SAAS;SACN,IAAI,CAAC,UAAA,EAAE,IAAI,OAAA,EAAE,CAAC,GAAG,EAAE,EAAR,CAAQ,CAAC;SACpB,IAAI,CAAC,UAAA,MAAM;QACV,OAAA,kBAAU;aACP,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC;aACxC,KAAK,CAAC,UAAC,KAAK,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAA/B,CAA+B,CAAC;IAFpD,CAEoD,CAAC,CAAC;AAC5D,CAAC;AARD,oCAQC;AAED,SAAgB,qBAAqB;IACnC,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE;QACpC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAEtC,SAAS,CAAC,IAAI,CAAC;YACb,SAAS,CAAC,SAAS,CAAC,UAAU,QAAgB;gBAC5C,kBAAU,CAAC,MAAM,CAAC,6BAA6B,EAAE,QAAQ,CAAC;qBACvD,KAAK,CAAC,UAAC,KAAK,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAA/B,CAA+B,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,IAAI,CAAC;YACb,SAAS,CAAC,UAAU,CAAC,UAAU,QAAgB;gBAC7C,kBAAU,CAAC,MAAM,CAAC,2BAA2B,EAAE,QAAQ,CAAC;qBACrD,KAAK,CAAC,UAAC,KAAK,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAA/B,CAA+B,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,IAAI,CAAC;YACb,SAAS,CAAC,QAAQ,CAAC,UAAU,QAAgB;gBAC3C,kBAAU,CAAC,MAAM,CAAC,yBAAyB,EAAE,QAAQ,CAAC;qBACnD,KAAK,CAAC,UAAC,KAAK,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAA/B,CAA+B,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,UAAU,aAAa;gBAC7D,kBAAU,CAAC,MAAM,CAAC,4BAA4B,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;qBAC3E,KAAK,CAAC,UAAC,KAAK,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAA/B,CAA+B,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;SACJ;KACF;AACH,CAAC;AAhCD,sDAgCC;AAEM,IAAM,QAAQ,GAAG,UAAC,EAAE,EAAE,KAAW;IAAX,sBAAA,EAAA,WAAW;IACtC,IAAI,OAAsC,CAAC;IAC3C,IAAM,YAAY,GAAG,KAAI,CAAC;IAC1B,OAAO;QAAU,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,yBAAO;;QACtB,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC,IAAI,OAAP,EAAE,yBAAM,YAAY,GAAK,IAAI,WAAG,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAA;AACH,CAAC,CAAA;AAPY,QAAA,QAAQ,YAOpB;;;;;AC1GD;IAAA;IA6DA,CAAC;IA5DiB,YAAI,GAAlB,UAAmB,IAAY,EAAE,OAAgB;QAC7C,CAAC,CAAC,KAAK,CAAC;YACJ,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,aAAa;YACvB,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,KAAK;YACtB,kBAAkB,EAAE,OAAO;YAC3B,kBAAkB;SACrB,CAAC,CAAC;IACP,CAAC;IAEa,aAAK,GAAnB,UAAoB,IAAY;QAC5B,CAAC,CAAC,KAAK,CAAC;YACJ,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,aAAa;YACvB,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,KAAK;YACtB,kBAAkB,EAAE,OAAO;SAC9B,CAAC,CAAC;IACP,CAAC;IAEa,oBAAY,GAA1B,UAA2B,OAAe,EAAE,IAAY;QACpD,CAAC,CAAC,KAAK,CAAC;YACJ,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,aAAa;YACvB,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,KAAK;YACtB,kBAAkB,EAAE,OAAO;SAC9B,CAAC,CAAC;IACP,CAAC;IAEa,iBAAS,GAAvB,UAAwB,OAAe,EAAE,IAAY;QACjD,CAAC,CAAC,KAAK,CAAC;YACJ,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,aAAa;YACvB,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,KAAK;YACtB,kBAAkB,EAAE,OAAO;SAC9B,CAAC,CAAC;IACP,CAAC;IAEa,kBAAU,GAAxB,UAAyB,IAAY;QACjC,CAAC,CAAC,KAAK,CAAC;YACJ,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,aAAa;YACvB,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,KAAK;YACtB,kBAAkB,EAAE,OAAO;SAC9B,CAAC,CAAC;IACP,CAAC;IACL,cAAC;AAAD,CA7DA,AA6DC,IAAA;AA7DY,0BAAO","file":"bundle.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i= lastLoopReleaseTime + loopReleaseInterval)) return [3 /*break*/, 3];\n lastLoopReleaseTime = now;\n // Allows asynchronous actions and microtasks to happen\n return [4 /*yield*/, wait(0)];\n case 2:\n // Allows asynchronous actions and microtasks to happen\n _a.sent();\n _a.label = 3;\n case 3:\n ++i;\n return [3 /*break*/, 1];\n case 4: return [2 /*return*/];\n }\n });\n });\n}\n/**\n * Makes the given promise never emit an unhandled promise rejection console warning.\n * The promise will still pass errors to the next promises.\n *\n * Otherwise, promise emits a console warning unless it has a `catch` listener.\n */\nfunction suppressUnhandledRejectionWarning(promise) {\n promise.then(undefined, function () { return undefined; });\n}\n\n/*\n * Taken from https://github.com/karanlyons/murmurHash3.js/blob/a33d0723127e2e5415056c455f8aed2451ace208/murmurHash3.js\n */\n//\n// Given two 64bit ints (as an array of two 32bit ints) returns the two\n// added together as a 64bit int (as an array of two 32bit ints).\n//\nfunction x64Add(m, n) {\n m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];\n n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];\n var o = [0, 0, 0, 0];\n o[3] += m[3] + n[3];\n o[2] += o[3] >>> 16;\n o[3] &= 0xffff;\n o[2] += m[2] + n[2];\n o[1] += o[2] >>> 16;\n o[2] &= 0xffff;\n o[1] += m[1] + n[1];\n o[0] += o[1] >>> 16;\n o[1] &= 0xffff;\n o[0] += m[0] + n[0];\n o[0] &= 0xffff;\n return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];\n}\n//\n// Given two 64bit ints (as an array of two 32bit ints) returns the two\n// multiplied together as a 64bit int (as an array of two 32bit ints).\n//\nfunction x64Multiply(m, n) {\n m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];\n n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];\n var o = [0, 0, 0, 0];\n o[3] += m[3] * n[3];\n o[2] += o[3] >>> 16;\n o[3] &= 0xffff;\n o[2] += m[2] * n[3];\n o[1] += o[2] >>> 16;\n o[2] &= 0xffff;\n o[2] += m[3] * n[2];\n o[1] += o[2] >>> 16;\n o[2] &= 0xffff;\n o[1] += m[1] * n[3];\n o[0] += o[1] >>> 16;\n o[1] &= 0xffff;\n o[1] += m[2] * n[2];\n o[0] += o[1] >>> 16;\n o[1] &= 0xffff;\n o[1] += m[3] * n[1];\n o[0] += o[1] >>> 16;\n o[1] &= 0xffff;\n o[0] += m[0] * n[3] + m[1] * n[2] + m[2] * n[1] + m[3] * n[0];\n o[0] &= 0xffff;\n return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];\n}\n//\n// Given a 64bit int (as an array of two 32bit ints) and an int\n// representing a number of bit positions, returns the 64bit int (as an\n// array of two 32bit ints) rotated left by that number of positions.\n//\nfunction x64Rotl(m, n) {\n n %= 64;\n if (n === 32) {\n return [m[1], m[0]];\n }\n else if (n < 32) {\n return [(m[0] << n) | (m[1] >>> (32 - n)), (m[1] << n) | (m[0] >>> (32 - n))];\n }\n else {\n n -= 32;\n return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))];\n }\n}\n//\n// Given a 64bit int (as an array of two 32bit ints) and an int\n// representing a number of bit positions, returns the 64bit int (as an\n// array of two 32bit ints) shifted left by that number of positions.\n//\nfunction x64LeftShift(m, n) {\n n %= 64;\n if (n === 0) {\n return m;\n }\n else if (n < 32) {\n return [(m[0] << n) | (m[1] >>> (32 - n)), m[1] << n];\n }\n else {\n return [m[1] << (n - 32), 0];\n }\n}\n//\n// Given two 64bit ints (as an array of two 32bit ints) returns the two\n// xored together as a 64bit int (as an array of two 32bit ints).\n//\nfunction x64Xor(m, n) {\n return [m[0] ^ n[0], m[1] ^ n[1]];\n}\n//\n// Given a block, returns murmurHash3's final x64 mix of that block.\n// (`[0, h[0] >>> 1]` is a 33 bit unsigned right shift. This is the\n// only place where we need to right shift 64bit ints.)\n//\nfunction x64Fmix(h) {\n h = x64Xor(h, [0, h[0] >>> 1]);\n h = x64Multiply(h, [0xff51afd7, 0xed558ccd]);\n h = x64Xor(h, [0, h[0] >>> 1]);\n h = x64Multiply(h, [0xc4ceb9fe, 0x1a85ec53]);\n h = x64Xor(h, [0, h[0] >>> 1]);\n return h;\n}\n//\n// Given a string and an optional seed as an int, returns a 128 bit\n// hash using the x64 flavor of MurmurHash3, as an unsigned hex.\n//\nfunction x64hash128(key, seed) {\n key = key || '';\n seed = seed || 0;\n var remainder = key.length % 16;\n var bytes = key.length - remainder;\n var h1 = [0, seed];\n var h2 = [0, seed];\n var k1 = [0, 0];\n var k2 = [0, 0];\n var c1 = [0x87c37b91, 0x114253d5];\n var c2 = [0x4cf5ad43, 0x2745937f];\n var i;\n for (i = 0; i < bytes; i = i + 16) {\n k1 = [\n (key.charCodeAt(i + 4) & 0xff) |\n ((key.charCodeAt(i + 5) & 0xff) << 8) |\n ((key.charCodeAt(i + 6) & 0xff) << 16) |\n ((key.charCodeAt(i + 7) & 0xff) << 24),\n (key.charCodeAt(i) & 0xff) |\n ((key.charCodeAt(i + 1) & 0xff) << 8) |\n ((key.charCodeAt(i + 2) & 0xff) << 16) |\n ((key.charCodeAt(i + 3) & 0xff) << 24),\n ];\n k2 = [\n (key.charCodeAt(i + 12) & 0xff) |\n ((key.charCodeAt(i + 13) & 0xff) << 8) |\n ((key.charCodeAt(i + 14) & 0xff) << 16) |\n ((key.charCodeAt(i + 15) & 0xff) << 24),\n (key.charCodeAt(i + 8) & 0xff) |\n ((key.charCodeAt(i + 9) & 0xff) << 8) |\n ((key.charCodeAt(i + 10) & 0xff) << 16) |\n ((key.charCodeAt(i + 11) & 0xff) << 24),\n ];\n k1 = x64Multiply(k1, c1);\n k1 = x64Rotl(k1, 31);\n k1 = x64Multiply(k1, c2);\n h1 = x64Xor(h1, k1);\n h1 = x64Rotl(h1, 27);\n h1 = x64Add(h1, h2);\n h1 = x64Add(x64Multiply(h1, [0, 5]), [0, 0x52dce729]);\n k2 = x64Multiply(k2, c2);\n k2 = x64Rotl(k2, 33);\n k2 = x64Multiply(k2, c1);\n h2 = x64Xor(h2, k2);\n h2 = x64Rotl(h2, 31);\n h2 = x64Add(h2, h1);\n h2 = x64Add(x64Multiply(h2, [0, 5]), [0, 0x38495ab5]);\n }\n k1 = [0, 0];\n k2 = [0, 0];\n switch (remainder) {\n case 15:\n k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 14)], 48));\n // fallthrough\n case 14:\n k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 13)], 40));\n // fallthrough\n case 13:\n k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 12)], 32));\n // fallthrough\n case 12:\n k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 11)], 24));\n // fallthrough\n case 11:\n k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 10)], 16));\n // fallthrough\n case 10:\n k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 9)], 8));\n // fallthrough\n case 9:\n k2 = x64Xor(k2, [0, key.charCodeAt(i + 8)]);\n k2 = x64Multiply(k2, c2);\n k2 = x64Rotl(k2, 33);\n k2 = x64Multiply(k2, c1);\n h2 = x64Xor(h2, k2);\n // fallthrough\n case 8:\n k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 7)], 56));\n // fallthrough\n case 7:\n k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 6)], 48));\n // fallthrough\n case 6:\n k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 5)], 40));\n // fallthrough\n case 5:\n k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 4)], 32));\n // fallthrough\n case 4:\n k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 3)], 24));\n // fallthrough\n case 3:\n k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 2)], 16));\n // fallthrough\n case 2:\n k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 1)], 8));\n // fallthrough\n case 1:\n k1 = x64Xor(k1, [0, key.charCodeAt(i)]);\n k1 = x64Multiply(k1, c1);\n k1 = x64Rotl(k1, 31);\n k1 = x64Multiply(k1, c2);\n h1 = x64Xor(h1, k1);\n // fallthrough\n }\n h1 = x64Xor(h1, [0, key.length]);\n h2 = x64Xor(h2, [0, key.length]);\n h1 = x64Add(h1, h2);\n h2 = x64Add(h2, h1);\n h1 = x64Fmix(h1);\n h2 = x64Fmix(h2);\n h1 = x64Add(h1, h2);\n h2 = x64Add(h2, h1);\n return (('00000000' + (h1[0] >>> 0).toString(16)).slice(-8) +\n ('00000000' + (h1[1] >>> 0).toString(16)).slice(-8) +\n ('00000000' + (h2[0] >>> 0).toString(16)).slice(-8) +\n ('00000000' + (h2[1] >>> 0).toString(16)).slice(-8));\n}\n\n/**\n * Converts an error object to a plain object that can be used with `JSON.stringify`.\n * If you just run `JSON.stringify(error)`, you'll get `'{}'`.\n */\nfunction errorToObject(error) {\n var _a;\n return tslib.__assign({ name: error.name, message: error.message, stack: (_a = error.stack) === null || _a === void 0 ? void 0 : _a.split('\\n') }, error);\n}\n\n/*\n * This file contains functions to work with pure data only (no browser features, DOM, side effects, etc).\n */\n/**\n * Does the same as Array.prototype.includes but has better typing\n */\nfunction includes(haystack, needle) {\n for (var i = 0, l = haystack.length; i < l; ++i) {\n if (haystack[i] === needle) {\n return true;\n }\n }\n return false;\n}\n/**\n * Like `!includes()` but with proper typing\n */\nfunction excludes(haystack, needle) {\n return !includes(haystack, needle);\n}\n/**\n * Be careful, NaN can return\n */\nfunction toInt(value) {\n return parseInt(value);\n}\n/**\n * Be careful, NaN can return\n */\nfunction toFloat(value) {\n return parseFloat(value);\n}\nfunction replaceNaN(value, replacement) {\n return typeof value === 'number' && isNaN(value) ? replacement : value;\n}\nfunction countTruthy(values) {\n return values.reduce(function (sum, value) { return sum + (value ? 1 : 0); }, 0);\n}\nfunction round(value, base) {\n if (base === void 0) { base = 1; }\n if (Math.abs(base) >= 1) {\n return Math.round(value / base) * base;\n }\n else {\n // Sometimes when a number is multiplied by a small number, precision is lost,\n // for example 1234 * 0.0001 === 0.12340000000000001, and it's more precise divide: 1234 / (1 / 0.0001) === 0.1234.\n var counterBase = 1 / base;\n return Math.round(value * counterBase) / counterBase;\n }\n}\n/**\n * Parses a CSS selector into tag name with HTML attributes.\n * Only single element selector are supported (without operators like space, +, >, etc).\n *\n * Multiple values can be returned for each attribute. You decide how to handle them.\n */\nfunction parseSimpleCssSelector(selector) {\n var _a, _b;\n var errorMessage = \"Unexpected syntax '\" + selector + \"'\";\n var tagMatch = /^\\s*([a-z-]*)(.*)$/i.exec(selector);\n var tag = tagMatch[1] || undefined;\n var attributes = {};\n var partsRegex = /([.:#][\\w-]+|\\[.+?\\])/gi;\n var addAttribute = function (name, value) {\n attributes[name] = attributes[name] || [];\n attributes[name].push(value);\n };\n for (;;) {\n var match = partsRegex.exec(tagMatch[2]);\n if (!match) {\n break;\n }\n var part = match[0];\n switch (part[0]) {\n case '.':\n addAttribute('class', part.slice(1));\n break;\n case '#':\n addAttribute('id', part.slice(1));\n break;\n case '[': {\n var attributeMatch = /^\\[([\\w-]+)([~|^$*]?=(\"(.*?)\"|([\\w-]+)))?(\\s+[is])?\\]$/.exec(part);\n if (attributeMatch) {\n addAttribute(attributeMatch[1], (_b = (_a = attributeMatch[4]) !== null && _a !== void 0 ? _a : attributeMatch[5]) !== null && _b !== void 0 ? _b : '');\n }\n else {\n throw new Error(errorMessage);\n }\n break;\n }\n default:\n throw new Error(errorMessage);\n }\n }\n return [tag, attributes];\n}\n\nfunction ensureErrorWithMessage(error) {\n return error && typeof error === 'object' && 'message' in error ? error : { message: error };\n}\nfunction isFinalResultLoaded(loadResult) {\n return typeof loadResult !== 'function';\n}\n/**\n * Loads the given entropy source. Returns a function that gets an entropy component from the source.\n *\n * The result is returned synchronously to prevent `loadSources` from\n * waiting for one source to load before getting the components from the other sources.\n */\nfunction loadSource(source, sourceOptions) {\n var sourceLoadPromise = new Promise(function (resolveLoad) {\n var loadStartTime = Date.now();\n // `awaitIfAsync` is used instead of just `await` in order to measure the duration of synchronous sources\n // correctly (other microtasks won't affect the duration).\n awaitIfAsync(source.bind(null, sourceOptions), function () {\n var loadArgs = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n loadArgs[_i] = arguments[_i];\n }\n var loadDuration = Date.now() - loadStartTime;\n // Source loading failed\n if (!loadArgs[0]) {\n return resolveLoad(function () { return ({ error: ensureErrorWithMessage(loadArgs[1]), duration: loadDuration }); });\n }\n var loadResult = loadArgs[1];\n // Source loaded with the final result\n if (isFinalResultLoaded(loadResult)) {\n return resolveLoad(function () { return ({ value: loadResult, duration: loadDuration }); });\n }\n // Source loaded with \"get\" stage\n resolveLoad(function () {\n return new Promise(function (resolveGet) {\n var getStartTime = Date.now();\n awaitIfAsync(loadResult, function () {\n var getArgs = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n getArgs[_i] = arguments[_i];\n }\n var duration = loadDuration + Date.now() - getStartTime;\n // Source getting failed\n if (!getArgs[0]) {\n return resolveGet({ error: ensureErrorWithMessage(getArgs[1]), duration: duration });\n }\n // Source getting succeeded\n resolveGet({ value: getArgs[1], duration: duration });\n });\n });\n });\n });\n });\n suppressUnhandledRejectionWarning(sourceLoadPromise);\n return function getComponent() {\n return sourceLoadPromise.then(function (finalizeSource) { return finalizeSource(); });\n };\n}\n/**\n * Loads the given entropy sources. Returns a function that collects the entropy components.\n *\n * The result is returned synchronously in order to allow start getting the components\n * before the sources are loaded completely.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction loadSources(sources, sourceOptions, excludeSources) {\n var includedSources = Object.keys(sources).filter(function (sourceKey) { return excludes(excludeSources, sourceKey); });\n var sourceGetters = Array(includedSources.length);\n // Using `forEachWithBreaks` allows asynchronous sources to complete between synchronous sources\n // and measure the duration correctly\n forEachWithBreaks(includedSources, function (sourceKey, index) {\n sourceGetters[index] = loadSource(sources[sourceKey], sourceOptions);\n });\n return function getComponents() {\n return tslib.__awaiter(this, void 0, void 0, function () {\n var components, _i, includedSources_1, sourceKey, componentPromises, _loop_1, state_1;\n return tslib.__generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n components = {};\n for (_i = 0, includedSources_1 = includedSources; _i < includedSources_1.length; _i++) {\n sourceKey = includedSources_1[_i];\n components[sourceKey] = undefined;\n }\n componentPromises = Array(includedSources.length);\n _loop_1 = function () {\n var hasAllComponentPromises;\n return tslib.__generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n hasAllComponentPromises = true;\n return [4 /*yield*/, forEachWithBreaks(includedSources, function (sourceKey, index) {\n if (!componentPromises[index]) {\n // `sourceGetters` may be incomplete at this point of execution because `forEachWithBreaks` is asynchronous\n if (sourceGetters[index]) {\n var componentPromise = sourceGetters[index]().then(function (component) { return (components[sourceKey] = component); });\n suppressUnhandledRejectionWarning(componentPromise);\n componentPromises[index] = componentPromise;\n }\n else {\n hasAllComponentPromises = false;\n }\n }\n })];\n case 1:\n _a.sent();\n if (hasAllComponentPromises) {\n return [2 /*return*/, \"break\"];\n }\n return [4 /*yield*/, wait(1)]; // Lets the source load loop continue\n case 2:\n _a.sent(); // Lets the source load loop continue\n return [2 /*return*/];\n }\n });\n };\n _a.label = 1;\n case 1: return [5 /*yield**/, _loop_1()];\n case 2:\n state_1 = _a.sent();\n if (state_1 === \"break\")\n return [3 /*break*/, 4];\n _a.label = 3;\n case 3: return [3 /*break*/, 1];\n case 4: return [4 /*yield*/, Promise.all(componentPromises)];\n case 5:\n _a.sent();\n return [2 /*return*/, components];\n }\n });\n });\n };\n}\n/**\n * Modifies an entropy source by transforming its returned value with the given function.\n * Keeps the source properties: sync/async, 1/2 stages.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction transformSource(source, transformValue) {\n var transformLoadResult = function (loadResult) {\n if (isFinalResultLoaded(loadResult)) {\n return transformValue(loadResult);\n }\n return function () {\n var getResult = loadResult();\n if (isPromise(getResult)) {\n return getResult.then(transformValue);\n }\n return transformValue(getResult);\n };\n };\n return function (options) {\n var loadResult = source(options);\n if (isPromise(loadResult)) {\n return loadResult.then(transformLoadResult);\n }\n return transformLoadResult(loadResult);\n };\n}\n\n/*\n * Functions to help with features that vary through browsers\n */\n/**\n * Checks whether the browser is based on Trident (the Internet Explorer engine) without using user-agent.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction isTrident() {\n var w = window;\n var n = navigator;\n // The properties are checked to be in IE 10, IE 11 and not to be in other browsers in October 2020\n return (countTruthy([\n 'MSCSSMatrix' in w,\n 'msSetImmediate' in w,\n 'msIndexedDB' in w,\n 'msMaxTouchPoints' in n,\n 'msPointerEnabled' in n,\n ]) >= 4);\n}\n/**\n * Checks whether the browser is based on EdgeHTML (the pre-Chromium Edge engine) without using user-agent.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction isEdgeHTML() {\n // Based on research in October 2020\n var w = window;\n var n = navigator;\n return (countTruthy(['msWriteProfilerMark' in w, 'MSStream' in w, 'msLaunchUri' in n, 'msSaveBlob' in n]) >= 3 &&\n !isTrident());\n}\n/**\n * Checks whether the browser is based on Chromium without using user-agent.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction isChromium() {\n // Based on research in October 2020. Tested to detect Chromium 42-86.\n var w = window;\n var n = navigator;\n return (countTruthy([\n 'webkitPersistentStorage' in n,\n 'webkitTemporaryStorage' in n,\n n.vendor.indexOf('Google') === 0,\n 'webkitResolveLocalFileSystemURL' in w,\n 'BatteryManager' in w,\n 'webkitMediaStream' in w,\n 'webkitSpeechGrammar' in w,\n ]) >= 5);\n}\n/**\n * Checks whether the browser is based on mobile or desktop Safari without using user-agent.\n * All iOS browsers use WebKit (the Safari engine).\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction isWebKit() {\n // Based on research in September 2020\n var w = window;\n var n = navigator;\n return (countTruthy([\n 'ApplePayError' in w,\n 'CSSPrimitiveValue' in w,\n 'Counter' in w,\n n.vendor.indexOf('Apple') === 0,\n 'getStorageUpdates' in n,\n 'WebKitMediaKeys' in w,\n ]) >= 4);\n}\n/**\n * Checks whether the WebKit browser is a desktop Safari.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction isDesktopSafari() {\n var w = window;\n return (countTruthy([\n 'safari' in w,\n !('DeviceMotionEvent' in w),\n !('ongestureend' in w),\n !('standalone' in navigator),\n ]) >= 3);\n}\n/**\n * Checks whether the browser is based on Gecko (Firefox engine) without using user-agent.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction isGecko() {\n var _a, _b;\n var w = window;\n // Based on research in September 2020\n return (countTruthy([\n 'buildID' in navigator,\n 'MozAppearance' in ((_b = (_a = document.documentElement) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : {}),\n 'onmozfullscreenchange' in w,\n 'mozInnerScreenX' in w,\n 'CSSMozDocumentRule' in w,\n 'CanvasCaptureMediaStream' in w,\n ]) >= 4);\n}\n/**\n * Checks whether the browser is based on Chromium version ≥86 without using user-agent.\n * It doesn't check that the browser is based on Chromium, there is a separate function for this.\n */\nfunction isChromium86OrNewer() {\n // Checked in Chrome 85 vs Chrome 86 both on desktop and Android\n var w = window;\n return (countTruthy([\n !('MediaSettingsRange' in w),\n 'RTCEncodedAudioFrame' in w,\n '' + w.Intl === '[object Intl]',\n '' + w.Reflect === '[object Reflect]',\n ]) >= 3);\n}\n/**\n * Checks whether the browser is based on WebKit version ≥606 (Safari ≥12) without using user-agent.\n * It doesn't check that the browser is based on WebKit, there is a separate function for this.\n *\n * @link https://en.wikipedia.org/wiki/Safari_version_history#Release_history Safari-WebKit versions map\n */\nfunction isWebKit606OrNewer() {\n // Checked in Safari 9–14\n var w = window;\n return (countTruthy([\n 'DOMRectList' in w,\n 'RTCPeerConnectionIceEvent' in w,\n 'SVGGeometryElement' in w,\n 'ontransitioncancel' in w,\n ]) >= 3);\n}\n/**\n * Checks whether the device is an iPad.\n * It doesn't check that the engine is WebKit and that the WebKit isn't desktop.\n */\nfunction isIPad() {\n // Checked on:\n // Safari on iPadOS (both mobile and desktop modes): 8, 11, 12, 13, 14\n // Chrome on iPadOS (both mobile and desktop modes): 11, 12, 13, 14\n // Safari on iOS (both mobile and desktop modes): 9, 10, 11, 12, 13, 14\n // Chrome on iOS (both mobile and desktop modes): 9, 10, 11, 12, 13, 14\n // Before iOS 13. Safari tampers the value in \"request desktop site\" mode since iOS 13.\n if (navigator.platform === 'iPad') {\n return true;\n }\n var s = screen;\n var screenRatio = s.width / s.height;\n return (countTruthy([\n 'MediaSource' in window,\n !!Element.prototype.webkitRequestFullscreen,\n // iPhone 4S that runs iOS 9 matches this. But it won't match the criteria above, so it won't be detected as iPad.\n screenRatio > 0.65 && screenRatio < 1.53,\n ]) >= 2);\n}\n/**\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction getFullscreenElement() {\n var d = document;\n return d.fullscreenElement || d.msFullscreenElement || d.mozFullScreenElement || d.webkitFullscreenElement || null;\n}\nfunction exitFullscreen() {\n var d = document;\n // `call` is required because the function throws an error without a proper \"this\" context\n return (d.exitFullscreen || d.msExitFullscreen || d.mozCancelFullScreen || d.webkitExitFullscreen).call(d);\n}\n/**\n * Checks whether the device runs on Android without using user-agent.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction isAndroid() {\n var isItChromium = isChromium();\n var isItGecko = isGecko();\n // Only 2 browser engines are presented on Android.\n // Actually, there is also Android 4.1 browser, but it's not worth detecting it at the moment.\n if (!isItChromium && !isItGecko) {\n return false;\n }\n var w = window;\n // Chrome removes all words \"Android\" from `navigator` when desktop version is requested\n // Firefox keeps \"Android\" in `navigator.appVersion` when desktop version is requested\n return (countTruthy([\n 'onorientationchange' in w,\n 'orientation' in w,\n isItChromium && !('SharedWorker' in w),\n isItGecko && /android/i.test(navigator.appVersion),\n ]) >= 2);\n}\n\n/**\n * A deep description: https://fingerprint.com/blog/audio-fingerprinting/\n * Inspired by and based on https://github.com/cozylife/audio-fingerprint\n */\nfunction getAudioFingerprint() {\n var w = window;\n var AudioContext = w.OfflineAudioContext || w.webkitOfflineAudioContext;\n if (!AudioContext) {\n return -2 /* NotSupported */;\n }\n // In some browsers, audio context always stays suspended unless the context is started in response to a user action\n // (e.g. a click or a tap). It prevents audio fingerprint from being taken at an arbitrary moment of time.\n // Such browsers are old and unpopular, so the audio fingerprinting is just skipped in them.\n // See a similar case explanation at https://stackoverflow.com/questions/46363048/onaudioprocess-not-called-on-ios11#46534088\n if (doesCurrentBrowserSuspendAudioContext()) {\n return -1 /* KnownToSuspend */;\n }\n var hashFromIndex = 4500;\n var hashToIndex = 5000;\n var context = new AudioContext(1, hashToIndex, 44100);\n var oscillator = context.createOscillator();\n oscillator.type = 'triangle';\n oscillator.frequency.value = 10000;\n var compressor = context.createDynamicsCompressor();\n compressor.threshold.value = -50;\n compressor.knee.value = 40;\n compressor.ratio.value = 12;\n compressor.attack.value = 0;\n compressor.release.value = 0.25;\n oscillator.connect(compressor);\n compressor.connect(context.destination);\n oscillator.start(0);\n var _a = startRenderingAudio(context), renderPromise = _a[0], finishRendering = _a[1];\n var fingerprintPromise = renderPromise.then(function (buffer) { return getHash(buffer.getChannelData(0).subarray(hashFromIndex)); }, function (error) {\n if (error.name === \"timeout\" /* Timeout */ || error.name === \"suspended\" /* Suspended */) {\n return -3 /* Timeout */;\n }\n throw error;\n });\n // Suppresses the console error message in case when the fingerprint fails before requested\n suppressUnhandledRejectionWarning(fingerprintPromise);\n return function () {\n finishRendering();\n return fingerprintPromise;\n };\n}\n/**\n * Checks if the current browser is known to always suspend audio context\n */\nfunction doesCurrentBrowserSuspendAudioContext() {\n return isWebKit() && !isDesktopSafari() && !isWebKit606OrNewer();\n}\n/**\n * Starts rendering the audio context.\n * When the returned function is called, the render process starts finishing.\n */\nfunction startRenderingAudio(context) {\n var renderTryMaxCount = 3;\n var renderRetryDelay = 500;\n var runningMaxAwaitTime = 500;\n var runningSufficientTime = 5000;\n var finalize = function () { return undefined; };\n var resultPromise = new Promise(function (resolve, reject) {\n var isFinalized = false;\n var renderTryCount = 0;\n var startedRunningAt = 0;\n context.oncomplete = function (event) { return resolve(event.renderedBuffer); };\n var startRunningTimeout = function () {\n setTimeout(function () { return reject(makeInnerError(\"timeout\" /* Timeout */)); }, Math.min(runningMaxAwaitTime, startedRunningAt + runningSufficientTime - Date.now()));\n };\n var tryRender = function () {\n try {\n context.startRendering();\n switch (context.state) {\n case 'running':\n startedRunningAt = Date.now();\n if (isFinalized) {\n startRunningTimeout();\n }\n break;\n // Sometimes the audio context doesn't start after calling `startRendering` (in addition to the cases where\n // audio context doesn't start at all). A known case is starting an audio context when the browser tab is in\n // background on iPhone. Retries usually help in this case.\n case 'suspended':\n // The audio context can reject starting until the tab is in foreground. Long fingerprint duration\n // in background isn't a problem, therefore the retry attempts don't count in background. It can lead to\n // a situation when a fingerprint takes very long time and finishes successfully. FYI, the audio context\n // can be suspended when `document.hidden === false` and start running after a retry.\n if (!document.hidden) {\n renderTryCount++;\n }\n if (isFinalized && renderTryCount >= renderTryMaxCount) {\n reject(makeInnerError(\"suspended\" /* Suspended */));\n }\n else {\n setTimeout(tryRender, renderRetryDelay);\n }\n break;\n }\n }\n catch (error) {\n reject(error);\n }\n };\n tryRender();\n finalize = function () {\n if (!isFinalized) {\n isFinalized = true;\n if (startedRunningAt > 0) {\n startRunningTimeout();\n }\n }\n };\n });\n return [resultPromise, finalize];\n}\nfunction getHash(signal) {\n var hash = 0;\n for (var i = 0; i < signal.length; ++i) {\n hash += Math.abs(signal[i]);\n }\n return hash;\n}\nfunction makeInnerError(name) {\n var error = new Error(name);\n error.name = name;\n return error;\n}\n\n/**\n * Creates and keeps an invisible iframe while the given function runs.\n * The given function is called when the iframe is loaded and has a body.\n * The iframe allows to measure DOM sizes inside itself.\n *\n * Notice: passing an initial HTML code doesn't work in IE.\n *\n * Warning for package users:\n * This function is out of Semantic Versioning, i.e. can change unexpectedly. Usage is at your own risk.\n */\nfunction withIframe(action, initialHtml, domPollInterval) {\n var _a, _b, _c;\n if (domPollInterval === void 0) { domPollInterval = 50; }\n return tslib.__awaiter(this, void 0, void 0, function () {\n var d, iframe;\n return tslib.__generator(this, function (_d) {\n switch (_d.label) {\n case 0:\n d = document;\n _d.label = 1;\n case 1:\n if (!!d.body) return [3 /*break*/, 3];\n return [4 /*yield*/, wait(domPollInterval)];\n case 2:\n _d.sent();\n return [3 /*break*/, 1];\n case 3:\n iframe = d.createElement('iframe');\n _d.label = 4;\n case 4:\n _d.trys.push([4, , 10, 11]);\n return [4 /*yield*/, new Promise(function (_resolve, _reject) {\n var isComplete = false;\n var resolve = function () {\n isComplete = true;\n _resolve();\n };\n var reject = function (error) {\n isComplete = true;\n _reject(error);\n };\n iframe.onload = resolve;\n iframe.onerror = reject;\n var style = iframe.style;\n style.setProperty('display', 'block', 'important'); // Required for browsers to calculate the layout\n style.position = 'absolute';\n style.top = '0';\n style.left = '0';\n style.visibility = 'hidden';\n if (initialHtml && 'srcdoc' in iframe) {\n iframe.srcdoc = initialHtml;\n }\n else {\n iframe.src = 'about:blank';\n }\n d.body.appendChild(iframe);\n // WebKit in WeChat doesn't fire the iframe's `onload` for some reason.\n // This code checks for the loading state manually.\n // See https://github.com/fingerprintjs/fingerprintjs/issues/645\n var checkReadyState = function () {\n var _a, _b;\n // The ready state may never become 'complete' in Firefox despite the 'load' event being fired.\n // So an infinite setTimeout loop can happen without this check.\n // See https://github.com/fingerprintjs/fingerprintjs/pull/716#issuecomment-986898796\n if (isComplete) {\n return;\n }\n // Make sure iframe.contentWindow and iframe.contentWindow.document are both loaded\n // The contentWindow.document can miss in JSDOM (https://github.com/jsdom/jsdom).\n if (((_b = (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document) === null || _b === void 0 ? void 0 : _b.readyState) === 'complete') {\n resolve();\n }\n else {\n setTimeout(checkReadyState, 10);\n }\n };\n checkReadyState();\n })];\n case 5:\n _d.sent();\n _d.label = 6;\n case 6:\n if (!!((_b = (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document) === null || _b === void 0 ? void 0 : _b.body)) return [3 /*break*/, 8];\n return [4 /*yield*/, wait(domPollInterval)];\n case 7:\n _d.sent();\n return [3 /*break*/, 6];\n case 8: return [4 /*yield*/, action(iframe, iframe.contentWindow)];\n case 9: return [2 /*return*/, _d.sent()];\n case 10:\n (_c = iframe.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(iframe);\n return [7 /*endfinally*/];\n case 11: return [2 /*return*/];\n }\n });\n });\n}\n/**\n * Creates a DOM element that matches the given selector.\n * Only single element selector are supported (without operators like space, +, >, etc).\n */\nfunction selectorToElement(selector) {\n var _a = parseSimpleCssSelector(selector), tag = _a[0], attributes = _a[1];\n var element = document.createElement(tag !== null && tag !== void 0 ? tag : 'div');\n for (var _i = 0, _b = Object.keys(attributes); _i < _b.length; _i++) {\n var name_1 = _b[_i];\n var value = attributes[name_1].join(' ');\n // Changing the `style` attribute can cause a CSP error, therefore we change the `style.cssText` property.\n // https://github.com/fingerprintjs/fingerprintjs/issues/733\n if (name_1 === 'style') {\n addStyleString(element.style, value);\n }\n else {\n element.setAttribute(name_1, value);\n }\n }\n return element;\n}\n/**\n * Adds CSS styles from a string in such a way that doesn't trigger a CSP warning (unsafe-inline or unsafe-eval)\n */\nfunction addStyleString(style, source) {\n // We don't use `style.cssText` because browsers must block it when no `unsafe-eval` CSP is presented: https://csplite.com/csp145/#w3c_note\n // Even though the browsers ignore this standard, we don't use `cssText` just in case.\n for (var _i = 0, _a = source.split(';'); _i < _a.length; _i++) {\n var property = _a[_i];\n var match = /^\\s*([\\w-]+)\\s*:\\s*(.+?)(\\s*!([\\w-]+))?\\s*$/.exec(property);\n if (match) {\n var name_2 = match[1], value = match[2], priority = match[4];\n style.setProperty(name_2, value, priority || ''); // The last argument can't be undefined in IE11\n }\n }\n}\n\n// We use m or w because these two characters take up the maximum width.\n// And we use a LLi so that the same matching fonts can get separated.\nvar testString = 'mmMwWLliI0O&1';\n// We test using 48px font size, we may use any size. I guess larger the better.\nvar textSize = '48px';\n// A font will be compared against all the three default fonts.\n// And if for any default fonts it doesn't match, then that font is available.\nvar baseFonts = ['monospace', 'sans-serif', 'serif'];\nvar fontList = [\n // This is android-specific font from \"Roboto\" family\n 'sans-serif-thin',\n 'ARNO PRO',\n 'Agency FB',\n 'Arabic Typesetting',\n 'Arial Unicode MS',\n 'AvantGarde Bk BT',\n 'BankGothic Md BT',\n 'Batang',\n 'Bitstream Vera Sans Mono',\n 'Calibri',\n 'Century',\n 'Century Gothic',\n 'Clarendon',\n 'EUROSTILE',\n 'Franklin Gothic',\n 'Futura Bk BT',\n 'Futura Md BT',\n 'GOTHAM',\n 'Gill Sans',\n 'HELV',\n 'Haettenschweiler',\n 'Helvetica Neue',\n 'Humanst521 BT',\n 'Leelawadee',\n 'Letter Gothic',\n 'Levenim MT',\n 'Lucida Bright',\n 'Lucida Sans',\n 'Menlo',\n 'MS Mincho',\n 'MS Outlook',\n 'MS Reference Specialty',\n 'MS UI Gothic',\n 'MT Extra',\n 'MYRIAD PRO',\n 'Marlett',\n 'Meiryo UI',\n 'Microsoft Uighur',\n 'Minion Pro',\n 'Monotype Corsiva',\n 'PMingLiU',\n 'Pristina',\n 'SCRIPTINA',\n 'Segoe UI Light',\n 'Serifa',\n 'SimHei',\n 'Small Fonts',\n 'Staccato222 BT',\n 'TRAJAN PRO',\n 'Univers CE 55 Medium',\n 'Vrinda',\n 'ZWAdobeF',\n];\n// kudos to http://www.lalit.org/lab/javascript-css-font-detect/\nfunction getFonts() {\n // Running the script in an iframe makes it not affect the page look and not be affected by the page CSS. See:\n // https://github.com/fingerprintjs/fingerprintjs/issues/592\n // https://github.com/fingerprintjs/fingerprintjs/issues/628\n return withIframe(function (_, _a) {\n var document = _a.document;\n var holder = document.body;\n holder.style.fontSize = textSize;\n // div to load spans for the default fonts and the fonts to detect\n var spansContainer = document.createElement('div');\n var defaultWidth = {};\n var defaultHeight = {};\n // creates a span where the fonts will be loaded\n var createSpan = function (fontFamily) {\n var span = document.createElement('span');\n var style = span.style;\n style.position = 'absolute';\n style.top = '0';\n style.left = '0';\n style.fontFamily = fontFamily;\n span.textContent = testString;\n spansContainer.appendChild(span);\n return span;\n };\n // creates a span and load the font to detect and a base font for fallback\n var createSpanWithFonts = function (fontToDetect, baseFont) {\n return createSpan(\"'\" + fontToDetect + \"',\" + baseFont);\n };\n // creates spans for the base fonts and adds them to baseFontsDiv\n var initializeBaseFontsSpans = function () {\n return baseFonts.map(createSpan);\n };\n // creates spans for the fonts to detect and adds them to fontsDiv\n var initializeFontsSpans = function () {\n // Stores {fontName : [spans for that font]}\n var spans = {};\n var _loop_1 = function (font) {\n spans[font] = baseFonts.map(function (baseFont) { return createSpanWithFonts(font, baseFont); });\n };\n for (var _i = 0, fontList_1 = fontList; _i < fontList_1.length; _i++) {\n var font = fontList_1[_i];\n _loop_1(font);\n }\n return spans;\n };\n // checks if a font is available\n var isFontAvailable = function (fontSpans) {\n return baseFonts.some(function (baseFont, baseFontIndex) {\n return fontSpans[baseFontIndex].offsetWidth !== defaultWidth[baseFont] ||\n fontSpans[baseFontIndex].offsetHeight !== defaultHeight[baseFont];\n });\n };\n // create spans for base fonts\n var baseFontsSpans = initializeBaseFontsSpans();\n // create spans for fonts to detect\n var fontsSpans = initializeFontsSpans();\n // add all the spans to the DOM\n holder.appendChild(spansContainer);\n // get the default width for the three base fonts\n for (var index = 0; index < baseFonts.length; index++) {\n defaultWidth[baseFonts[index]] = baseFontsSpans[index].offsetWidth; // width for the default font\n defaultHeight[baseFonts[index]] = baseFontsSpans[index].offsetHeight; // height for the default font\n }\n // check available fonts\n return fontList.filter(function (font) { return isFontAvailable(fontsSpans[font]); });\n });\n}\n\nfunction getPlugins() {\n var rawPlugins = navigator.plugins;\n if (!rawPlugins) {\n return undefined;\n }\n var plugins = [];\n // Safari 10 doesn't support iterating navigator.plugins with for...of\n for (var i = 0; i < rawPlugins.length; ++i) {\n var plugin = rawPlugins[i];\n if (!plugin) {\n continue;\n }\n var mimeTypes = [];\n for (var j = 0; j < plugin.length; ++j) {\n var mimeType = plugin[j];\n mimeTypes.push({\n type: mimeType.type,\n suffixes: mimeType.suffixes,\n });\n }\n plugins.push({\n name: plugin.name,\n description: plugin.description,\n mimeTypes: mimeTypes,\n });\n }\n return plugins;\n}\n\n// https://www.browserleaks.com/canvas#how-does-it-work\nfunction getCanvasFingerprint() {\n var winding = false;\n var geometry;\n var text;\n var _a = makeCanvasContext(), canvas = _a[0], context = _a[1];\n if (!isSupported(canvas, context)) {\n geometry = text = ''; // The value will be 'unsupported' in v3.4\n }\n else {\n winding = doesSupportWinding(context);\n renderTextImage(canvas, context);\n var textImage1 = canvasToString(canvas);\n var textImage2 = canvasToString(canvas); // It's slightly faster to double-encode the text image\n // Some browsers add a noise to the canvas: https://github.com/fingerprintjs/fingerprintjs/issues/791\n // The canvas is excluded from the fingerprint in this case\n if (textImage1 !== textImage2) {\n geometry = text = 'unstable';\n }\n else {\n text = textImage1;\n // Text is unstable:\n // https://github.com/fingerprintjs/fingerprintjs/issues/583\n // https://github.com/fingerprintjs/fingerprintjs/issues/103\n // Therefore it's extracted into a separate image.\n renderGeometryImage(canvas, context);\n geometry = canvasToString(canvas);\n }\n }\n return { winding: winding, geometry: geometry, text: text };\n}\nfunction makeCanvasContext() {\n var canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n return [canvas, canvas.getContext('2d')];\n}\nfunction isSupported(canvas, context) {\n return !!(context && canvas.toDataURL);\n}\nfunction doesSupportWinding(context) {\n // https://web.archive.org/web/20170825024655/http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/\n // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/canvas/winding.js\n context.rect(0, 0, 10, 10);\n context.rect(2, 2, 6, 6);\n return !context.isPointInPath(5, 5, 'evenodd');\n}\nfunction renderTextImage(canvas, context) {\n // Resizing the canvas cleans it\n canvas.width = 240;\n canvas.height = 60;\n context.textBaseline = 'alphabetic';\n context.fillStyle = '#f60';\n context.fillRect(100, 1, 62, 20);\n context.fillStyle = '#069';\n // It's important to use explicit built-in fonts in order to exclude the affect of font preferences\n // (there is a separate entropy source for them).\n context.font = '11pt \"Times New Roman\"';\n // The choice of emojis has a gigantic impact on rendering performance (especially in FF).\n // Some newer emojis cause it to slow down 50-200 times.\n // There must be no text to the right of the emoji, see https://github.com/fingerprintjs/fingerprintjs/issues/574\n // A bare emoji shouldn't be used because the canvas will change depending on the script encoding:\n // https://github.com/fingerprintjs/fingerprintjs/issues/66\n // Escape sequence shouldn't be used too because Terser will turn it into a bare unicode.\n var printedText = \"Cwm fjordbank gly \" + String.fromCharCode(55357, 56835) /* 😃 */;\n context.fillText(printedText, 2, 15);\n context.fillStyle = 'rgba(102, 204, 0, 0.2)';\n context.font = '18pt Arial';\n context.fillText(printedText, 4, 45);\n}\nfunction renderGeometryImage(canvas, context) {\n // Resizing the canvas cleans it\n canvas.width = 122;\n canvas.height = 110;\n // Canvas blending\n // https://web.archive.org/web/20170826194121/http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\n // http://jsfiddle.net/NDYV8/16/\n context.globalCompositeOperation = 'multiply';\n for (var _i = 0, _a = [\n ['#f2f', 40, 40],\n ['#2ff', 80, 40],\n ['#ff2', 60, 80],\n ]; _i < _a.length; _i++) {\n var _b = _a[_i], color = _b[0], x = _b[1], y = _b[2];\n context.fillStyle = color;\n context.beginPath();\n context.arc(x, y, 40, 0, Math.PI * 2, true);\n context.closePath();\n context.fill();\n }\n // Canvas winding\n // https://web.archive.org/web/20130913061632/http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/\n // http://jsfiddle.net/NDYV8/19/\n context.fillStyle = '#f9c';\n context.arc(60, 60, 60, 0, Math.PI * 2, true);\n context.arc(60, 60, 20, 0, Math.PI * 2, true);\n context.fill('evenodd');\n}\nfunction canvasToString(canvas) {\n return canvas.toDataURL();\n}\n\n/**\n * This is a crude and primitive touch screen detection. It's not possible to currently reliably detect the availability\n * of a touch screen with a JS, without actually subscribing to a touch event.\n *\n * @see http://www.stucox.com/blog/you-cant-detect-a-touchscreen/\n * @see https://github.com/Modernizr/Modernizr/issues/548\n */\nfunction getTouchSupport() {\n var n = navigator;\n var maxTouchPoints = 0;\n var touchEvent;\n if (n.maxTouchPoints !== undefined) {\n maxTouchPoints = toInt(n.maxTouchPoints);\n }\n else if (n.msMaxTouchPoints !== undefined) {\n maxTouchPoints = n.msMaxTouchPoints;\n }\n try {\n document.createEvent('TouchEvent');\n touchEvent = true;\n }\n catch (_a) {\n touchEvent = false;\n }\n var touchStart = 'ontouchstart' in window;\n return {\n maxTouchPoints: maxTouchPoints,\n touchEvent: touchEvent,\n touchStart: touchStart,\n };\n}\n\nfunction getOsCpu() {\n return navigator.oscpu;\n}\n\nfunction getLanguages() {\n var n = navigator;\n var result = [];\n var language = n.language || n.userLanguage || n.browserLanguage || n.systemLanguage;\n if (language !== undefined) {\n result.push([language]);\n }\n if (Array.isArray(n.languages)) {\n // Starting from Chromium 86, there is only a single value in `navigator.language` in Incognito mode:\n // the value of `navigator.language`. Therefore the value is ignored in this browser.\n if (!(isChromium() && isChromium86OrNewer())) {\n result.push(n.languages);\n }\n }\n else if (typeof n.languages === 'string') {\n var languages = n.languages;\n if (languages) {\n result.push(languages.split(','));\n }\n }\n return result;\n}\n\nfunction getColorDepth() {\n return window.screen.colorDepth;\n}\n\nfunction getDeviceMemory() {\n // `navigator.deviceMemory` is a string containing a number in some unidentified cases\n return replaceNaN(toFloat(navigator.deviceMemory), undefined);\n}\n\nfunction getScreenResolution() {\n var s = screen;\n // Some browsers return screen resolution as strings, e.g. \"1200\", instead of a number, e.g. 1200.\n // I suspect it's done by certain plugins that randomize browser properties to prevent fingerprinting.\n // Some browsers even return screen resolution as not numbers.\n var parseDimension = function (value) { return replaceNaN(toInt(value), null); };\n var dimensions = [parseDimension(s.width), parseDimension(s.height)];\n dimensions.sort().reverse();\n return dimensions;\n}\n\nvar screenFrameCheckInterval = 2500;\nvar roundingPrecision = 10;\n// The type is readonly to protect from unwanted mutations\nvar screenFrameBackup;\nvar screenFrameSizeTimeoutId;\n/**\n * Starts watching the screen frame size. When a non-zero size appears, the size is saved and the watch is stopped.\n * Later, when `getScreenFrame` runs, it will return the saved non-zero size if the current size is null.\n *\n * This trick is required to mitigate the fact that the screen frame turns null in some cases.\n * See more on this at https://github.com/fingerprintjs/fingerprintjs/issues/568\n */\nfunction watchScreenFrame() {\n if (screenFrameSizeTimeoutId !== undefined) {\n return;\n }\n var checkScreenFrame = function () {\n var frameSize = getCurrentScreenFrame();\n if (isFrameSizeNull(frameSize)) {\n screenFrameSizeTimeoutId = setTimeout(checkScreenFrame, screenFrameCheckInterval);\n }\n else {\n screenFrameBackup = frameSize;\n screenFrameSizeTimeoutId = undefined;\n }\n };\n checkScreenFrame();\n}\nfunction getScreenFrame() {\n var _this = this;\n watchScreenFrame();\n return function () { return tslib.__awaiter(_this, void 0, void 0, function () {\n var frameSize;\n return tslib.__generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n frameSize = getCurrentScreenFrame();\n if (!isFrameSizeNull(frameSize)) return [3 /*break*/, 2];\n if (screenFrameBackup) {\n return [2 /*return*/, tslib.__spreadArrays(screenFrameBackup)];\n }\n if (!getFullscreenElement()) return [3 /*break*/, 2];\n // Some browsers set the screen frame to zero when programmatic fullscreen is on.\n // There is a chance of getting a non-zero frame after exiting the fullscreen.\n // See more on this at https://github.com/fingerprintjs/fingerprintjs/issues/568\n return [4 /*yield*/, exitFullscreen()];\n case 1:\n // Some browsers set the screen frame to zero when programmatic fullscreen is on.\n // There is a chance of getting a non-zero frame after exiting the fullscreen.\n // See more on this at https://github.com/fingerprintjs/fingerprintjs/issues/568\n _a.sent();\n frameSize = getCurrentScreenFrame();\n _a.label = 2;\n case 2:\n if (!isFrameSizeNull(frameSize)) {\n screenFrameBackup = frameSize;\n }\n return [2 /*return*/, frameSize];\n }\n });\n }); };\n}\n/**\n * Sometimes the available screen resolution changes a bit, e.g. 1900x1440 → 1900x1439. A possible reason: macOS Dock\n * shrinks to fit more icons when there is too little space. The rounding is used to mitigate the difference.\n */\nfunction getRoundedScreenFrame() {\n var _this = this;\n var screenFrameGetter = getScreenFrame();\n return function () { return tslib.__awaiter(_this, void 0, void 0, function () {\n var frameSize, processSize;\n return tslib.__generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, screenFrameGetter()];\n case 1:\n frameSize = _a.sent();\n processSize = function (sideSize) { return (sideSize === null ? null : round(sideSize, roundingPrecision)); };\n // It might look like I don't know about `for` and `map`.\n // In fact, such code is used to avoid TypeScript issues without using `as`.\n return [2 /*return*/, [processSize(frameSize[0]), processSize(frameSize[1]), processSize(frameSize[2]), processSize(frameSize[3])]];\n }\n });\n }); };\n}\nfunction getCurrentScreenFrame() {\n var s = screen;\n // Some browsers return screen resolution as strings, e.g. \"1200\", instead of a number, e.g. 1200.\n // I suspect it's done by certain plugins that randomize browser properties to prevent fingerprinting.\n //\n // Some browsers (IE, Edge ≤18) don't provide `screen.availLeft` and `screen.availTop`. The property values are\n // replaced with 0 in such cases to not lose the entropy from `screen.availWidth` and `screen.availHeight`.\n return [\n replaceNaN(toFloat(s.availTop), null),\n replaceNaN(toFloat(s.width) - toFloat(s.availWidth) - replaceNaN(toFloat(s.availLeft), 0), null),\n replaceNaN(toFloat(s.height) - toFloat(s.availHeight) - replaceNaN(toFloat(s.availTop), 0), null),\n replaceNaN(toFloat(s.availLeft), null),\n ];\n}\nfunction isFrameSizeNull(frameSize) {\n for (var i = 0; i < 4; ++i) {\n if (frameSize[i]) {\n return false;\n }\n }\n return true;\n}\n\nfunction getHardwareConcurrency() {\n // sometimes hardware concurrency is a string\n return replaceNaN(toInt(navigator.hardwareConcurrency), undefined);\n}\n\nfunction getTimezone() {\n var _a;\n var DateTimeFormat = (_a = window.Intl) === null || _a === void 0 ? void 0 : _a.DateTimeFormat;\n if (DateTimeFormat) {\n var timezone = new DateTimeFormat().resolvedOptions().timeZone;\n if (timezone) {\n return timezone;\n }\n }\n // For browsers that don't support timezone names\n // The minus is intentional because the JS offset is opposite to the real offset\n var offset = -getTimezoneOffset();\n return \"UTC\" + (offset >= 0 ? '+' : '') + Math.abs(offset);\n}\nfunction getTimezoneOffset() {\n var currentYear = new Date().getFullYear();\n // The timezone offset may change over time due to daylight saving time (DST) shifts.\n // The non-DST timezone offset is used as the result timezone offset.\n // Since the DST season differs in the northern and the southern hemispheres,\n // both January and July timezones offsets are considered.\n return Math.max(\n // `getTimezoneOffset` returns a number as a string in some unidentified cases\n toFloat(new Date(currentYear, 0, 1).getTimezoneOffset()), toFloat(new Date(currentYear, 6, 1).getTimezoneOffset()));\n}\n\nfunction getSessionStorage() {\n try {\n return !!window.sessionStorage;\n }\n catch (error) {\n /* SecurityError when referencing it means it exists */\n return true;\n }\n}\n\n// https://bugzilla.mozilla.org/show_bug.cgi?id=781447\nfunction getLocalStorage() {\n try {\n return !!window.localStorage;\n }\n catch (e) {\n /* SecurityError when referencing it means it exists */\n return true;\n }\n}\n\nfunction getIndexedDB() {\n // IE and Edge don't allow accessing indexedDB in private mode, therefore IE and Edge will have different\n // visitor identifier in normal and private modes.\n if (isTrident() || isEdgeHTML()) {\n return undefined;\n }\n try {\n return !!window.indexedDB;\n }\n catch (e) {\n /* SecurityError when referencing it means it exists */\n return true;\n }\n}\n\nfunction getOpenDatabase() {\n return !!window.openDatabase;\n}\n\nfunction getCpuClass() {\n return navigator.cpuClass;\n}\n\nfunction getPlatform() {\n // Android Chrome 86 and 87 and Android Firefox 80 and 84 don't mock the platform value when desktop mode is requested\n var platform = navigator.platform;\n // iOS mocks the platform value when desktop version is requested: https://github.com/fingerprintjs/fingerprintjs/issues/514\n // iPad uses desktop mode by default since iOS 13\n // The value is 'MacIntel' on M1 Macs\n // The value is 'iPhone' on iPod Touch\n if (platform === 'MacIntel') {\n if (isWebKit() && !isDesktopSafari()) {\n return isIPad() ? 'iPad' : 'iPhone';\n }\n }\n return platform;\n}\n\nfunction getVendor() {\n return navigator.vendor || '';\n}\n\n/**\n * Checks for browser-specific (not engine specific) global variables to tell browsers with the same engine apart.\n * Only somewhat popular browsers are considered.\n */\nfunction getVendorFlavors() {\n var flavors = [];\n for (var _i = 0, _a = [\n // Blink and some browsers on iOS\n 'chrome',\n // Safari on macOS\n 'safari',\n // Chrome on iOS (checked in 85 on 13 and 87 on 14)\n '__crWeb',\n '__gCrWeb',\n // Yandex Browser on iOS, macOS and Android (checked in 21.2 on iOS 14, macOS and Android)\n 'yandex',\n // Yandex Browser on iOS (checked in 21.2 on 14)\n '__yb',\n '__ybro',\n // Firefox on iOS (checked in 32 on 14)\n '__firefox__',\n // Edge on iOS (checked in 46 on 14)\n '__edgeTrackingPreventionStatistics',\n 'webkit',\n // Opera Touch on iOS (checked in 2.6 on 14)\n 'oprt',\n // Samsung Internet on Android (checked in 11.1)\n 'samsungAr',\n // UC Browser on Android (checked in 12.10 and 13.0)\n 'ucweb',\n 'UCShellJava',\n // Puffin on Android (checked in 9.0)\n 'puffinDevice',\n ]; _i < _a.length; _i++) {\n var key = _a[_i];\n var value = window[key];\n if (value && typeof value === 'object') {\n flavors.push(key);\n }\n }\n return flavors.sort();\n}\n\n/**\n * navigator.cookieEnabled cannot detect custom or nuanced cookie blocking configurations. For example, when blocking\n * cookies via the Advanced Privacy Settings in IE9, it always returns true. And there have been issues in the past with\n * site-specific exceptions. Don't rely on it.\n *\n * @see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cookies.js Taken from here\n */\nfunction areCookiesEnabled() {\n var d = document;\n // Taken from here: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cookies.js\n // navigator.cookieEnabled cannot detect custom or nuanced cookie blocking configurations. For example, when blocking\n // cookies via the Advanced Privacy Settings in IE9, it always returns true. And there have been issues in the past\n // with site-specific exceptions. Don't rely on it.\n // try..catch because some in situations `document.cookie` is exposed but throws a\n // SecurityError if you try to access it; e.g. documents created from data URIs\n // or in sandboxed iframes (depending on flags/context)\n try {\n // Create cookie\n d.cookie = 'cookietest=1; SameSite=Strict;';\n var result = d.cookie.indexOf('cookietest=') !== -1;\n // Delete cookie\n d.cookie = 'cookietest=1; SameSite=Strict; expires=Thu, 01-Jan-1970 00:00:01 GMT';\n return result;\n }\n catch (e) {\n return false;\n }\n}\n\n/**\n * Only single element selector are supported (no operators like space, +, >, etc).\n * `embed` and `position: fixed;` will be considered as blocked anyway because it always has no offsetParent.\n * Avoid `iframe` and anything with `[src=]` because they produce excess HTTP requests.\n *\n * The \"inappropriate\" selectors are obfuscated. See https://github.com/fingerprintjs/fingerprintjs/issues/734.\n * A function is used instead of a plain object to help tree-shaking.\n *\n * The function code is generated automatically. See docs/content_blockers.md to learn how to make the list.\n */\nfunction getFilters() {\n var fromB64 = atob; // Just for better minification\n return {\n abpIndo: [\n '#Iklan-Melayang',\n '#Kolom-Iklan-728',\n '#SidebarIklan-wrapper',\n fromB64('YVt0aXRsZT0iN25hZ2EgcG9rZXIiIGld'),\n '[title=\"ALIENBOLA\" i]',\n ],\n abpvn: [\n '#quangcaomb',\n fromB64('Lmlvc0Fkc2lvc0Fkcy1sYXlvdXQ='),\n '.quangcao',\n fromB64('W2hyZWZePSJodHRwczovL3I4OC52bi8iXQ=='),\n fromB64('W2hyZWZePSJodHRwczovL3piZXQudm4vIl0='),\n ],\n adBlockFinland: [\n '.mainostila',\n fromB64('LnNwb25zb3JpdA=='),\n '.ylamainos',\n fromB64('YVtocmVmKj0iL2NsaWNrdGhyZ2guYXNwPyJd'),\n fromB64('YVtocmVmXj0iaHR0cHM6Ly9hcHAucmVhZHBlYWsuY29tL2FkcyJd'),\n ],\n adBlockPersian: ['#navbar_notice_50', '.kadr', 'TABLE[width=\"140px\"]', '#divAgahi', fromB64('I2FkMl9pbmxpbmU=')],\n adBlockWarningRemoval: [\n '#adblock-honeypot',\n '.adblocker-root',\n '.wp_adblock_detect',\n fromB64('LmhlYWRlci1ibG9ja2VkLWFk'),\n fromB64('I2FkX2Jsb2NrZXI='),\n ],\n adGuardAnnoyances: [\n 'amp-embed[type=\"zen\"]',\n '.hs-sosyal',\n '#cookieconsentdiv',\n 'div[class^=\"app_gdpr\"]',\n '.as-oil',\n ],\n adGuardBase: [\n '.BetterJsPopOverlay',\n fromB64('I2FkXzMwMFgyNTA='),\n fromB64('I2Jhbm5lcmZsb2F0MjI='),\n fromB64('I2FkLWJhbm5lcg=='),\n fromB64('I2NhbXBhaWduLWJhbm5lcg=='),\n ],\n adGuardChinese: [\n fromB64('LlppX2FkX2FfSA=='),\n fromB64('YVtocmVmKj0iL29kMDA1LmNvbSJd'),\n fromB64('YVtocmVmKj0iLmh0aGJldDM0LmNvbSJd'),\n '.qq_nr_lad',\n '#widget-quan',\n ],\n adGuardFrench: [\n fromB64('I2Jsb2NrLXZpZXdzLWFkcy1zaWRlYmFyLWJsb2NrLWJsb2Nr'),\n '#pavePub',\n fromB64('LmFkLWRlc2t0b3AtcmVjdGFuZ2xl'),\n '.mobile_adhesion',\n '.widgetadv',\n ],\n adGuardGerman: [\n fromB64('LmJhbm5lcml0ZW13ZXJidW5nX2hlYWRfMQ=='),\n fromB64('LmJveHN0YXJ0d2VyYnVuZw=='),\n fromB64('LndlcmJ1bmcz'),\n fromB64('YVtocmVmXj0iaHR0cDovL3d3dy5laXMuZGUvaW5kZXgucGh0bWw/cmVmaWQ9Il0='),\n fromB64('YVtocmVmXj0iaHR0cHM6Ly93d3cudGlwaWNvLmNvbS8/YWZmaWxpYXRlSWQ9Il0='),\n ],\n adGuardJapanese: [\n '#kauli_yad_1',\n fromB64('YVtocmVmXj0iaHR0cDovL2FkMi50cmFmZmljZ2F0ZS5uZXQvIl0='),\n fromB64('Ll9wb3BJbl9pbmZpbml0ZV9hZA=='),\n fromB64('LmFkZ29vZ2xl'),\n fromB64('LmFkX3JlZ3VsYXIz'),\n ],\n adGuardMobile: [\n fromB64('YW1wLWF1dG8tYWRz'),\n fromB64('LmFtcF9hZA=='),\n 'amp-embed[type=\"24smi\"]',\n '#mgid_iframe1',\n fromB64('I2FkX2ludmlld19hcmVh'),\n ],\n adGuardRussian: [\n fromB64('YVtocmVmXj0iaHR0cHM6Ly9hZC5sZXRtZWFkcy5jb20vIl0='),\n fromB64('LnJlY2xhbWE='),\n 'div[id^=\"smi2adblock\"]',\n fromB64('ZGl2W2lkXj0iQWRGb3hfYmFubmVyXyJd'),\n fromB64('I2FkX3NxdWFyZQ=='),\n ],\n adGuardSocial: [\n fromB64('YVtocmVmXj0iLy93d3cuc3R1bWJsZXVwb24uY29tL3N1Ym1pdD91cmw9Il0='),\n fromB64('YVtocmVmXj0iLy90ZWxlZ3JhbS5tZS9zaGFyZS91cmw/Il0='),\n '.etsy-tweet',\n '#inlineShare',\n '.popup-social',\n ],\n adGuardSpanishPortuguese: [\n '#barraPublicidade',\n '#Publicidade',\n '#publiEspecial',\n '#queTooltip',\n fromB64('W2hyZWZePSJodHRwOi8vYWRzLmdsaXNwYS5jb20vIl0='),\n ],\n adGuardTrackingProtection: [\n '#qoo-counter',\n fromB64('YVtocmVmXj0iaHR0cDovL2NsaWNrLmhvdGxvZy5ydS8iXQ=='),\n fromB64('YVtocmVmXj0iaHR0cDovL2hpdGNvdW50ZXIucnUvdG9wL3N0YXQucGhwIl0='),\n fromB64('YVtocmVmXj0iaHR0cDovL3RvcC5tYWlsLnJ1L2p1bXAiXQ=='),\n '#top100counter',\n ],\n adGuardTurkish: [\n '#backkapat',\n fromB64('I3Jla2xhbWk='),\n fromB64('YVtocmVmXj0iaHR0cDovL2Fkc2Vydi5vbnRlay5jb20udHIvIl0='),\n fromB64('YVtocmVmXj0iaHR0cDovL2l6bGVuemkuY29tL2NhbXBhaWduLyJd'),\n fromB64('YVtocmVmXj0iaHR0cDovL3d3dy5pbnN0YWxsYWRzLm5ldC8iXQ=='),\n ],\n bulgarian: [\n fromB64('dGQjZnJlZW5ldF90YWJsZV9hZHM='),\n '#ea_intext_div',\n '.lapni-pop-over',\n '#xenium_hot_offers',\n fromB64('I25ld0Fk'),\n ],\n easyList: [\n fromB64('I0FEX0NPTlRST0xfMjg='),\n fromB64('LnNlY29uZC1wb3N0LWFkcy13cmFwcGVy'),\n '.universalboxADVBOX03',\n fromB64('LmFkdmVydGlzZW1lbnQtNzI4eDkw'),\n fromB64('LnNxdWFyZV9hZHM='),\n ],\n easyListChina: [\n fromB64('YVtocmVmKj0iLndlbnNpeHVldGFuZy5jb20vIl0='),\n fromB64('LmFwcGd1aWRlLXdyYXBbb25jbGljayo9ImJjZWJvcy5jb20iXQ=='),\n fromB64('LmZyb250cGFnZUFkdk0='),\n '#taotaole',\n '#aafoot.top_box',\n ],\n easyListCookie: [\n '#AdaCompliance.app-notice',\n '.text-center.rgpd',\n '.panel--cookie',\n '.js-cookies-andromeda',\n '.elxtr-consent',\n ],\n easyListCzechSlovak: [\n '#onlajny-stickers',\n fromB64('I3Jla2xhbW5pLWJveA=='),\n fromB64('LnJla2xhbWEtbWVnYWJvYXJk'),\n '.sklik',\n fromB64('W2lkXj0ic2tsaWtSZWtsYW1hIl0='),\n ],\n easyListDutch: [\n fromB64('I2FkdmVydGVudGll'),\n fromB64('I3ZpcEFkbWFya3RCYW5uZXJCbG9jaw=='),\n '.adstekst',\n fromB64('YVtocmVmXj0iaHR0cHM6Ly94bHR1YmUubmwvY2xpY2svIl0='),\n '#semilo-lrectangle',\n ],\n easyListGermany: [\n fromB64('I0FkX1dpbjJkYXk='),\n fromB64('I3dlcmJ1bmdzYm94MzAw'),\n fromB64('YVtocmVmXj0iaHR0cDovL3d3dy5yb3RsaWNodGthcnRlaS5jb20vP3NjPSJd'),\n fromB64('I3dlcmJ1bmdfd2lkZXNreXNjcmFwZXJfc2NyZWVu'),\n fromB64('YVtocmVmXj0iaHR0cDovL2xhbmRpbmcucGFya3BsYXR6a2FydGVpLmNvbS8/YWc9Il0='),\n ],\n easyListItaly: [\n fromB64('LmJveF9hZHZfYW5udW5jaQ=='),\n '.sb-box-pubbliredazionale',\n fromB64('YVtocmVmXj0iaHR0cDovL2FmZmlsaWF6aW9uaWFkcy5zbmFpLml0LyJd'),\n fromB64('YVtocmVmXj0iaHR0cHM6Ly9hZHNlcnZlci5odG1sLml0LyJd'),\n fromB64('YVtocmVmXj0iaHR0cHM6Ly9hZmZpbGlhemlvbmlhZHMuc25haS5pdC8iXQ=='),\n ],\n easyListLithuania: [\n fromB64('LnJla2xhbW9zX3RhcnBhcw=='),\n fromB64('LnJla2xhbW9zX251b3JvZG9z'),\n fromB64('aW1nW2FsdD0iUmVrbGFtaW5pcyBza3lkZWxpcyJd'),\n fromB64('aW1nW2FsdD0iRGVkaWt1b3RpLmx0IHNlcnZlcmlhaSJd'),\n fromB64('aW1nW2FsdD0iSG9zdGluZ2FzIFNlcnZlcmlhaS5sdCJd'),\n ],\n estonian: [fromB64('QVtocmVmKj0iaHR0cDovL3BheTRyZXN1bHRzMjQuZXUiXQ==')],\n fanboyAnnoyances: [\n '#feedback-tab',\n '#taboola-below-article',\n '.feedburnerFeedBlock',\n '.widget-feedburner-counter',\n '[title=\"Subscribe to our blog\"]',\n ],\n fanboyAntiFacebook: ['.util-bar-module-firefly-visible'],\n fanboyEnhancedTrackers: [\n '.open.pushModal',\n '#issuem-leaky-paywall-articles-zero-remaining-nag',\n '#sovrn_container',\n 'div[class$=\"-hide\"][zoompage-fontsize][style=\"display: block;\"]',\n '.BlockNag__Card',\n ],\n fanboySocial: [\n '.td-tags-and-social-wrapper-box',\n '.twitterContainer',\n '.youtube-social',\n 'a[title^=\"Like us on Facebook\"]',\n 'img[alt^=\"Share on Digg\"]',\n ],\n frellwitSwedish: [\n fromB64('YVtocmVmKj0iY2FzaW5vcHJvLnNlIl1bdGFyZ2V0PSJfYmxhbmsiXQ=='),\n fromB64('YVtocmVmKj0iZG9rdG9yLXNlLm9uZWxpbmsubWUiXQ=='),\n 'article.category-samarbete',\n fromB64('ZGl2LmhvbGlkQWRz'),\n 'ul.adsmodern',\n ],\n greekAdBlock: [\n fromB64('QVtocmVmKj0iYWRtYW4ub3RlbmV0LmdyL2NsaWNrPyJd'),\n fromB64('QVtocmVmKj0iaHR0cDovL2F4aWFiYW5uZXJzLmV4b2R1cy5nci8iXQ=='),\n fromB64('QVtocmVmKj0iaHR0cDovL2ludGVyYWN0aXZlLmZvcnRobmV0LmdyL2NsaWNrPyJd'),\n 'DIV.agores300',\n 'TABLE.advright',\n ],\n hungarian: [\n '#cemp_doboz',\n '.optimonk-iframe-container',\n fromB64('LmFkX19tYWlu'),\n fromB64('W2NsYXNzKj0iR29vZ2xlQWRzIl0='),\n '#hirdetesek_box',\n ],\n iDontCareAboutCookies: [\n '.alert-info[data-block-track*=\"CookieNotice\"]',\n '.ModuleTemplateCookieIndicator',\n '.o--cookies--container',\n '.cookie-msg-info-container',\n '#cookies-policy-sticky',\n ],\n icelandicAbp: [fromB64('QVtocmVmXj0iL2ZyYW1ld29yay9yZXNvdXJjZXMvZm9ybXMvYWRzLmFzcHgiXQ==')],\n latvian: [\n fromB64('YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiAxMjBweDsgaGVpZ2h0O' +\n 'iA0MHB4OyBvdmVyZmxvdzogaGlkZGVuOyBwb3NpdGlvbjogcmVsYXRpdmU7Il0='),\n fromB64('YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiA4OHB4OyBoZWlnaHQ6I' +\n 'DMxcHg7IG92ZXJmbG93OiBoaWRkZW47IHBvc2l0aW9uOiByZWxhdGl2ZTsiXQ=='),\n ],\n listKr: [\n fromB64('YVtocmVmKj0iLy9hZC5wbGFuYnBsdXMuY28ua3IvIl0='),\n fromB64('I2xpdmVyZUFkV3JhcHBlcg=='),\n fromB64('YVtocmVmKj0iLy9hZHYuaW1hZHJlcC5jby5rci8iXQ=='),\n fromB64('aW5zLmZhc3R2aWV3LWFk'),\n '.revenue_unit_item.dable',\n ],\n listeAr: [\n fromB64('LmdlbWluaUxCMUFk'),\n '.right-and-left-sponsers',\n fromB64('YVtocmVmKj0iLmFmbGFtLmluZm8iXQ=='),\n fromB64('YVtocmVmKj0iYm9vcmFxLm9yZyJd'),\n fromB64('YVtocmVmKj0iZHViaXp6bGUuY29tL2FyLz91dG1fc291cmNlPSJd'),\n ],\n listeFr: [\n fromB64('YVtocmVmXj0iaHR0cDovL3Byb21vLnZhZG9yLmNvbS8iXQ=='),\n fromB64('I2FkY29udGFpbmVyX3JlY2hlcmNoZQ=='),\n fromB64('YVtocmVmKj0id2Vib3JhbWEuZnIvZmNnaS1iaW4vIl0='),\n '.site-pub-interstitiel',\n 'div[id^=\"crt-\"][data-criteo-id]',\n ],\n officialPolish: [\n '#ceneo-placeholder-ceneo-12',\n fromB64('W2hyZWZePSJodHRwczovL2FmZi5zZW5kaHViLnBsLyJd'),\n fromB64('YVtocmVmXj0iaHR0cDovL2Fkdm1hbmFnZXIudGVjaGZ1bi5wbC9yZWRpcmVjdC8iXQ=='),\n fromB64('YVtocmVmXj0iaHR0cDovL3d3dy50cml6ZXIucGwvP3V0bV9zb3VyY2UiXQ=='),\n fromB64('ZGl2I3NrYXBpZWNfYWQ='),\n ],\n ro: [\n fromB64('YVtocmVmXj0iLy9hZmZ0cmsuYWx0ZXgucm8vQ291bnRlci9DbGljayJd'),\n 'a[href^=\"/magazin/\"]',\n fromB64('YVtocmVmXj0iaHR0cHM6Ly9ibGFja2ZyaWRheXNhbGVzLnJvL3Ryay9zaG9wLyJd'),\n fromB64('YVtocmVmXj0iaHR0cHM6Ly9ldmVudC4ycGVyZm9ybWFudC5jb20vZXZlbnRzL2NsaWNrIl0='),\n fromB64('YVtocmVmXj0iaHR0cHM6Ly9sLnByb2ZpdHNoYXJlLnJvLyJd'),\n ],\n ruAd: [\n fromB64('YVtocmVmKj0iLy9mZWJyYXJlLnJ1LyJd'),\n fromB64('YVtocmVmKj0iLy91dGltZy5ydS8iXQ=='),\n fromB64('YVtocmVmKj0iOi8vY2hpa2lkaWtpLnJ1Il0='),\n '#pgeldiz',\n '.yandex-rtb-block',\n ],\n thaiAds: [\n 'a[href*=macau-uta-popup]',\n fromB64('I2Fkcy1nb29nbGUtbWlkZGxlX3JlY3RhbmdsZS1ncm91cA=='),\n fromB64('LmFkczMwMHM='),\n '.bumq',\n '.img-kosana',\n ],\n webAnnoyancesUltralist: [\n '#mod-social-share-2',\n '#social-tools',\n fromB64('LmN0cGwtZnVsbGJhbm5lcg=='),\n '.zergnet-recommend',\n '.yt.btn-link.btn-md.btn',\n ],\n };\n}\n/**\n * The order of the returned array means nothing (it's always sorted alphabetically).\n *\n * Notice that the source is slightly unstable.\n * Safari provides a 2-taps way to disable all content blockers on a page temporarily.\n * Also content blockers can be disabled permanently for a domain, but it requires 4 taps.\n * So empty array shouldn't be treated as \"no blockers\", it should be treated as \"no signal\".\n * If you are a website owner, don't make your visitors want to disable content blockers.\n */\nfunction getDomBlockers(_a) {\n var debug = (_a === void 0 ? {} : _a).debug;\n return tslib.__awaiter(this, void 0, void 0, function () {\n var filters, filterNames, allSelectors, blockedSelectors, activeBlockers;\n var _b;\n return tslib.__generator(this, function (_c) {\n switch (_c.label) {\n case 0:\n if (!isApplicable()) {\n return [2 /*return*/, undefined];\n }\n filters = getFilters();\n filterNames = Object.keys(filters);\n allSelectors = (_b = []).concat.apply(_b, filterNames.map(function (filterName) { return filters[filterName]; }));\n return [4 /*yield*/, getBlockedSelectors(allSelectors)];\n case 1:\n blockedSelectors = _c.sent();\n if (debug) {\n printDebug(filters, blockedSelectors);\n }\n activeBlockers = filterNames.filter(function (filterName) {\n var selectors = filters[filterName];\n var blockedCount = countTruthy(selectors.map(function (selector) { return blockedSelectors[selector]; }));\n return blockedCount > selectors.length * 0.6;\n });\n activeBlockers.sort();\n return [2 /*return*/, activeBlockers];\n }\n });\n });\n}\nfunction isApplicable() {\n // Safari (desktop and mobile) and all Android browsers keep content blockers in both regular and private mode\n return isWebKit() || isAndroid();\n}\nfunction getBlockedSelectors(selectors) {\n var _a;\n return tslib.__awaiter(this, void 0, void 0, function () {\n var d, root, elements, blockedSelectors, i, element, holder, i;\n return tslib.__generator(this, function (_b) {\n switch (_b.label) {\n case 0:\n d = document;\n root = d.createElement('div');\n elements = new Array(selectors.length);\n blockedSelectors = {} // Set() isn't used just in case somebody need older browser support\n ;\n forceShow(root);\n // First create all elements that can be blocked. If the DOM steps below are done in a single cycle,\n // browser will alternate tree modification and layout reading, that is very slow.\n for (i = 0; i < selectors.length; ++i) {\n element = selectorToElement(selectors[i]);\n holder = d.createElement('div') // Protects from unwanted effects of `+` and `~` selectors of filters\n ;\n forceShow(holder);\n holder.appendChild(element);\n root.appendChild(holder);\n elements[i] = element;\n }\n _b.label = 1;\n case 1:\n if (!!d.body) return [3 /*break*/, 3];\n return [4 /*yield*/, wait(50)];\n case 2:\n _b.sent();\n return [3 /*break*/, 1];\n case 3:\n d.body.appendChild(root);\n try {\n // Then check which of the elements are blocked\n for (i = 0; i < selectors.length; ++i) {\n if (!elements[i].offsetParent) {\n blockedSelectors[selectors[i]] = true;\n }\n }\n }\n finally {\n // Then remove the elements\n (_a = root.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(root);\n }\n return [2 /*return*/, blockedSelectors];\n }\n });\n });\n}\nfunction forceShow(element) {\n element.style.setProperty('display', 'block', 'important');\n}\nfunction printDebug(filters, blockedSelectors) {\n var message = 'DOM blockers debug:\\n```';\n for (var _i = 0, _a = Object.keys(filters); _i < _a.length; _i++) {\n var filterName = _a[_i];\n message += \"\\n\" + filterName + \":\";\n for (var _b = 0, _c = filters[filterName]; _b < _c.length; _b++) {\n var selector = _c[_b];\n message += \"\\n \" + (blockedSelectors[selector] ? '🚫' : '➡️') + \" \" + selector;\n }\n }\n // console.log is ok here because it's under a debug clause\n // eslint-disable-next-line no-console\n console.log(message + \"\\n```\");\n}\n\n/**\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/color-gamut\n */\nfunction getColorGamut() {\n // rec2020 includes p3 and p3 includes srgb\n for (var _i = 0, _a = ['rec2020', 'p3', 'srgb']; _i < _a.length; _i++) {\n var gamut = _a[_i];\n if (matchMedia(\"(color-gamut: \" + gamut + \")\").matches) {\n return gamut;\n }\n }\n return undefined;\n}\n\n/**\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/inverted-colors\n */\nfunction areColorsInverted() {\n if (doesMatch$4('inverted')) {\n return true;\n }\n if (doesMatch$4('none')) {\n return false;\n }\n return undefined;\n}\nfunction doesMatch$4(value) {\n return matchMedia(\"(inverted-colors: \" + value + \")\").matches;\n}\n\n/**\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors\n */\nfunction areColorsForced() {\n if (doesMatch$3('active')) {\n return true;\n }\n if (doesMatch$3('none')) {\n return false;\n }\n return undefined;\n}\nfunction doesMatch$3(value) {\n return matchMedia(\"(forced-colors: \" + value + \")\").matches;\n}\n\nvar maxValueToCheck = 100;\n/**\n * If the display is monochrome (e.g. black&white), the value will be ≥0 and will mean the number of bits per pixel.\n * If the display is not monochrome, the returned value will be 0.\n * If the browser doesn't support this feature, the returned value will be undefined.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/monochrome\n */\nfunction getMonochromeDepth() {\n if (!matchMedia('(min-monochrome: 0)').matches) {\n // The media feature isn't supported by the browser\n return undefined;\n }\n // A variation of binary search algorithm can be used here.\n // But since expected values are very small (≤10), there is no sense in adding the complexity.\n for (var i = 0; i <= maxValueToCheck; ++i) {\n if (matchMedia(\"(max-monochrome: \" + i + \")\").matches) {\n return i;\n }\n }\n throw new Error('Too high value');\n}\n\n/**\n * @see https://www.w3.org/TR/mediaqueries-5/#prefers-contrast\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast\n */\nfunction getContrastPreference() {\n if (doesMatch$2('no-preference')) {\n return 0 /* None */;\n }\n // The sources contradict on the keywords. Probably 'high' and 'low' will never be implemented.\n // Need to check it when all browsers implement the feature.\n if (doesMatch$2('high') || doesMatch$2('more')) {\n return 1 /* More */;\n }\n if (doesMatch$2('low') || doesMatch$2('less')) {\n return -1 /* Less */;\n }\n if (doesMatch$2('forced')) {\n return 10 /* ForcedColors */;\n }\n return undefined;\n}\nfunction doesMatch$2(value) {\n return matchMedia(\"(prefers-contrast: \" + value + \")\").matches;\n}\n\n/**\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion\n */\nfunction isMotionReduced() {\n if (doesMatch$1('reduce')) {\n return true;\n }\n if (doesMatch$1('no-preference')) {\n return false;\n }\n return undefined;\n}\nfunction doesMatch$1(value) {\n return matchMedia(\"(prefers-reduced-motion: \" + value + \")\").matches;\n}\n\n/**\n * @see https://www.w3.org/TR/mediaqueries-5/#dynamic-range\n */\nfunction isHDR() {\n if (doesMatch('high')) {\n return true;\n }\n if (doesMatch('standard')) {\n return false;\n }\n return undefined;\n}\nfunction doesMatch(value) {\n return matchMedia(\"(dynamic-range: \" + value + \")\").matches;\n}\n\nvar M = Math; // To reduce the minified code size\nvar fallbackFn = function () { return 0; };\n/**\n * @see https://gitlab.torproject.org/legacy/trac/-/issues/13018\n * @see https://bugzilla.mozilla.org/show_bug.cgi?id=531915\n */\nfunction getMathFingerprint() {\n // Native operations\n var acos = M.acos || fallbackFn;\n var acosh = M.acosh || fallbackFn;\n var asin = M.asin || fallbackFn;\n var asinh = M.asinh || fallbackFn;\n var atanh = M.atanh || fallbackFn;\n var atan = M.atan || fallbackFn;\n var sin = M.sin || fallbackFn;\n var sinh = M.sinh || fallbackFn;\n var cos = M.cos || fallbackFn;\n var cosh = M.cosh || fallbackFn;\n var tan = M.tan || fallbackFn;\n var tanh = M.tanh || fallbackFn;\n var exp = M.exp || fallbackFn;\n var expm1 = M.expm1 || fallbackFn;\n var log1p = M.log1p || fallbackFn;\n // Operation polyfills\n var powPI = function (value) { return M.pow(M.PI, value); };\n var acoshPf = function (value) { return M.log(value + M.sqrt(value * value - 1)); };\n var asinhPf = function (value) { return M.log(value + M.sqrt(value * value + 1)); };\n var atanhPf = function (value) { return M.log((1 + value) / (1 - value)) / 2; };\n var sinhPf = function (value) { return M.exp(value) - 1 / M.exp(value) / 2; };\n var coshPf = function (value) { return (M.exp(value) + 1 / M.exp(value)) / 2; };\n var expm1Pf = function (value) { return M.exp(value) - 1; };\n var tanhPf = function (value) { return (M.exp(2 * value) - 1) / (M.exp(2 * value) + 1); };\n var log1pPf = function (value) { return M.log(1 + value); };\n // Note: constant values are empirical\n return {\n acos: acos(0.123124234234234242),\n acosh: acosh(1e308),\n acoshPf: acoshPf(1e154),\n asin: asin(0.123124234234234242),\n asinh: asinh(1),\n asinhPf: asinhPf(1),\n atanh: atanh(0.5),\n atanhPf: atanhPf(0.5),\n atan: atan(0.5),\n sin: sin(-1e300),\n sinh: sinh(1),\n sinhPf: sinhPf(1),\n cos: cos(10.000000000123),\n cosh: cosh(1),\n coshPf: coshPf(1),\n tan: tan(-1e300),\n tanh: tanh(1),\n tanhPf: tanhPf(1),\n exp: exp(1),\n expm1: expm1(1),\n expm1Pf: expm1Pf(1),\n log1p: log1p(10),\n log1pPf: log1pPf(10),\n powPI: powPI(-100),\n };\n}\n\n/**\n * We use m or w because these two characters take up the maximum width.\n * Also there are a couple of ligatures.\n */\nvar defaultText = 'mmMwWLliI0fiflO&1';\n/**\n * Settings of text blocks to measure. The keys are random but persistent words.\n */\nvar presets = {\n /**\n * The default font. User can change it in desktop Chrome, desktop Firefox, IE 11,\n * Android Chrome (but only when the size is ≥ than the default) and Android Firefox.\n */\n default: [],\n /** OS font on macOS. User can change its size and weight. Applies after Safari restart. */\n apple: [{ font: '-apple-system-body' }],\n /** User can change it in desktop Chrome and desktop Firefox. */\n serif: [{ fontFamily: 'serif' }],\n /** User can change it in desktop Chrome and desktop Firefox. */\n sans: [{ fontFamily: 'sans-serif' }],\n /** User can change it in desktop Chrome and desktop Firefox. */\n mono: [{ fontFamily: 'monospace' }],\n /**\n * Check the smallest allowed font size. User can change it in desktop Chrome, desktop Firefox and desktop Safari.\n * The height can be 0 in Chrome on a retina display.\n */\n min: [{ fontSize: '1px' }],\n /** Tells one OS from another in desktop Chrome. */\n system: [{ fontFamily: 'system-ui' }],\n};\n/**\n * The result is a dictionary of the width of the text samples.\n * Heights aren't included because they give no extra entropy and are unstable.\n *\n * The result is very stable in IE 11, Edge 18 and Safari 14.\n * The result changes when the OS pixel density changes in Chromium 87. The real pixel density is required to solve,\n * but seems like it's impossible: https://stackoverflow.com/q/1713771/1118709.\n * The \"min\" and the \"mono\" (only on Windows) value may change when the page is zoomed in Firefox 87.\n */\nfunction getFontPreferences() {\n return withNaturalFonts(function (document, container) {\n var elements = {};\n var sizes = {};\n // First create all elements to measure. If the DOM steps below are done in a single cycle,\n // browser will alternate tree modification and layout reading, that is very slow.\n for (var _i = 0, _a = Object.keys(presets); _i < _a.length; _i++) {\n var key = _a[_i];\n var _b = presets[key], _c = _b[0], style = _c === void 0 ? {} : _c, _d = _b[1], text = _d === void 0 ? defaultText : _d;\n var element = document.createElement('span');\n element.textContent = text;\n element.style.whiteSpace = 'nowrap';\n for (var _e = 0, _f = Object.keys(style); _e < _f.length; _e++) {\n var name_1 = _f[_e];\n var value = style[name_1];\n if (value !== undefined) {\n element.style[name_1] = value;\n }\n }\n elements[key] = element;\n container.appendChild(document.createElement('br'));\n container.appendChild(element);\n }\n // Then measure the created elements\n for (var _g = 0, _h = Object.keys(presets); _g < _h.length; _g++) {\n var key = _h[_g];\n sizes[key] = elements[key].getBoundingClientRect().width;\n }\n return sizes;\n });\n}\n/**\n * Creates a DOM environment that provides the most natural font available, including Android OS font.\n * Measurements of the elements are zoom-independent.\n * Don't put a content to measure inside an absolutely positioned element.\n */\nfunction withNaturalFonts(action, containerWidthPx) {\n if (containerWidthPx === void 0) { containerWidthPx = 4000; }\n /*\n * Requirements for Android Chrome to apply the system font size to a text inside an iframe:\n * - The iframe mustn't have a `display: none;` style;\n * - The text mustn't be positioned absolutely;\n * - The text block must be wide enough.\n * 2560px on some devices in portrait orientation for the biggest font size option (32px);\n * - There must be much enough text to form a few lines (I don't know the exact numbers);\n * - The text must have the `text-size-adjust: none` style. Otherwise the text will scale in \"Desktop site\" mode;\n *\n * Requirements for Android Firefox to apply the system font size to a text inside an iframe:\n * - The iframe document must have a header: ``.\n * The only way to set it is to use the `srcdoc` attribute of the iframe;\n * - The iframe content must get loaded before adding extra content with JavaScript;\n *\n * https://example.com as the iframe target always inherits Android font settings so it can be used as a reference.\n *\n * Observations on how page zoom affects the measurements:\n * - macOS Safari 11.1, 12.1, 13.1, 14.0: zoom reset + offsetWidth = 100% reliable;\n * - macOS Safari 11.1, 12.1, 13.1, 14.0: zoom reset + getBoundingClientRect = 100% reliable;\n * - macOS Safari 14.0: offsetWidth = 5% fluctuation;\n * - macOS Safari 14.0: getBoundingClientRect = 5% fluctuation;\n * - iOS Safari 9, 10, 11.0, 12.0: haven't found a way to zoom a page (pinch doesn't change layout);\n * - iOS Safari 13.1, 14.0: zoom reset + offsetWidth = 100% reliable;\n * - iOS Safari 13.1, 14.0: zoom reset + getBoundingClientRect = 100% reliable;\n * - iOS Safari 14.0: offsetWidth = 100% reliable;\n * - iOS Safari 14.0: getBoundingClientRect = 100% reliable;\n * - Chrome 42, 65, 80, 87: zoom 1/devicePixelRatio + offsetWidth = 1px fluctuation;\n * - Chrome 42, 65, 80, 87: zoom 1/devicePixelRatio + getBoundingClientRect = 100% reliable;\n * - Chrome 87: offsetWidth = 1px fluctuation;\n * - Chrome 87: getBoundingClientRect = 0.7px fluctuation;\n * - Firefox 48, 51: offsetWidth = 10% fluctuation;\n * - Firefox 48, 51: getBoundingClientRect = 10% fluctuation;\n * - Firefox 52, 53, 57, 62, 66, 67, 68, 71, 75, 80, 84: offsetWidth = width 100% reliable, height 10% fluctuation;\n * - Firefox 52, 53, 57, 62, 66, 67, 68, 71, 75, 80, 84: getBoundingClientRect = width 100% reliable, height 10%\n * fluctuation;\n * - Android Chrome 86: haven't found a way to zoom a page (pinch doesn't change layout);\n * - Android Firefox 84: font size in accessibility settings changes all the CSS sizes, but offsetWidth and\n * getBoundingClientRect keep measuring with regular units, so the size reflects the font size setting and doesn't\n * fluctuate;\n * - IE 11, Edge 18: zoom 1/devicePixelRatio + offsetWidth = 100% reliable;\n * - IE 11, Edge 18: zoom 1/devicePixelRatio + getBoundingClientRect = reflects the zoom level;\n * - IE 11, Edge 18: offsetWidth = 100% reliable;\n * - IE 11, Edge 18: getBoundingClientRect = 100% reliable;\n */\n return withIframe(function (_, iframeWindow) {\n var iframeDocument = iframeWindow.document;\n var iframeBody = iframeDocument.body;\n var bodyStyle = iframeBody.style;\n bodyStyle.width = containerWidthPx + \"px\";\n bodyStyle.webkitTextSizeAdjust = bodyStyle.textSizeAdjust = 'none';\n // See the big comment above\n if (isChromium()) {\n iframeBody.style.zoom = \"\" + 1 / iframeWindow.devicePixelRatio;\n }\n else if (isWebKit()) {\n iframeBody.style.zoom = 'reset';\n }\n // See the big comment above\n var linesOfText = iframeDocument.createElement('div');\n linesOfText.textContent = tslib.__spreadArrays(Array((containerWidthPx / 20) << 0)).map(function () { return 'word'; }).join(' ');\n iframeBody.appendChild(linesOfText);\n return action(iframeDocument, iframeBody);\n }, '');\n}\n\n/**\n * The list of entropy sources used to make visitor identifiers.\n *\n * This value isn't restricted by Semantic Versioning, i.e. it may be changed without bumping minor or major version of\n * this package.\n *\n * Note: Rollup and Webpack are smart enough to remove unused properties of this object during tree-shaking, so there is\n * no need to export the sources individually.\n */\nvar sources = {\n // READ FIRST:\n // See https://github.com/fingerprintjs/fingerprintjs/blob/master/contributing.md#how-to-make-an-entropy-source\n // to learn how entropy source works and how to make your own.\n // The sources run in this exact order.\n // The asynchronous sources are at the start to run in parallel with other sources.\n fonts: getFonts,\n domBlockers: getDomBlockers,\n fontPreferences: getFontPreferences,\n audio: getAudioFingerprint,\n screenFrame: getRoundedScreenFrame,\n osCpu: getOsCpu,\n languages: getLanguages,\n colorDepth: getColorDepth,\n deviceMemory: getDeviceMemory,\n screenResolution: getScreenResolution,\n hardwareConcurrency: getHardwareConcurrency,\n timezone: getTimezone,\n sessionStorage: getSessionStorage,\n localStorage: getLocalStorage,\n indexedDB: getIndexedDB,\n openDatabase: getOpenDatabase,\n cpuClass: getCpuClass,\n platform: getPlatform,\n plugins: getPlugins,\n canvas: getCanvasFingerprint,\n touchSupport: getTouchSupport,\n vendor: getVendor,\n vendorFlavors: getVendorFlavors,\n cookiesEnabled: areCookiesEnabled,\n colorGamut: getColorGamut,\n invertedColors: areColorsInverted,\n forcedColors: areColorsForced,\n monochrome: getMonochromeDepth,\n contrast: getContrastPreference,\n reducedMotion: isMotionReduced,\n hdr: isHDR,\n math: getMathFingerprint,\n};\n/**\n * Loads the built-in entropy sources.\n * Returns a function that collects the entropy components to make the visitor identifier.\n */\nfunction loadBuiltinSources(options) {\n return loadSources(sources, options, []);\n}\n\nvar commentTemplate = '$ if upgrade to Pro: https://fpjs.dev/pro';\nfunction getConfidence(components) {\n var openConfidenceScore = getOpenConfidenceScore(components);\n var proConfidenceScore = deriveProConfidenceScore(openConfidenceScore);\n return { score: openConfidenceScore, comment: commentTemplate.replace(/\\$/g, \"\" + proConfidenceScore) };\n}\nfunction getOpenConfidenceScore(components) {\n // In order to calculate the true probability of the visitor identifier being correct, we need to know the number of\n // website visitors (the higher the number, the less the probability because the fingerprint entropy is limited).\n // JS agent doesn't know the number of visitors, so we can only do an approximate assessment.\n if (isAndroid()) {\n return 0.4;\n }\n // Safari (mobile and desktop)\n if (isWebKit()) {\n return isDesktopSafari() ? 0.5 : 0.3;\n }\n var platform = components.platform.value || '';\n // Windows\n if (/^Win/.test(platform)) {\n // The score is greater than on macOS because of the higher variety of devices running Windows.\n // Chrome provides more entropy than Firefox according too\n // https://netmarketshare.com/browser-market-share.aspx?options=%7B%22filter%22%3A%7B%22%24and%22%3A%5B%7B%22platform%22%3A%7B%22%24in%22%3A%5B%22Windows%22%5D%7D%7D%5D%7D%2C%22dateLabel%22%3A%22Trend%22%2C%22attributes%22%3A%22share%22%2C%22group%22%3A%22browser%22%2C%22sort%22%3A%7B%22share%22%3A-1%7D%2C%22id%22%3A%22browsersDesktop%22%2C%22dateInterval%22%3A%22Monthly%22%2C%22dateStart%22%3A%222019-11%22%2C%22dateEnd%22%3A%222020-10%22%2C%22segments%22%3A%22-1000%22%7D\n // So we assign the same score to them.\n return 0.6;\n }\n // macOS\n if (/^Mac/.test(platform)) {\n // Chrome provides more entropy than Safari and Safari provides more entropy than Firefox.\n // Chrome is more popular than Safari and Safari is more popular than Firefox according to\n // https://netmarketshare.com/browser-market-share.aspx?options=%7B%22filter%22%3A%7B%22%24and%22%3A%5B%7B%22platform%22%3A%7B%22%24in%22%3A%5B%22Mac%20OS%22%5D%7D%7D%5D%7D%2C%22dateLabel%22%3A%22Trend%22%2C%22attributes%22%3A%22share%22%2C%22group%22%3A%22browser%22%2C%22sort%22%3A%7B%22share%22%3A-1%7D%2C%22id%22%3A%22browsersDesktop%22%2C%22dateInterval%22%3A%22Monthly%22%2C%22dateStart%22%3A%222019-11%22%2C%22dateEnd%22%3A%222020-10%22%2C%22segments%22%3A%22-1000%22%7D\n // So we assign the same score to them.\n return 0.5;\n }\n // Another platform, e.g. a desktop Linux. It's rare, so it should be pretty unique.\n return 0.7;\n}\nfunction deriveProConfidenceScore(openConfidenceScore) {\n return round(0.99 + 0.01 * openConfidenceScore, 0.0001);\n}\n\nfunction componentsToCanonicalString(components) {\n var result = '';\n for (var _i = 0, _a = Object.keys(components).sort(); _i < _a.length; _i++) {\n var componentKey = _a[_i];\n var component = components[componentKey];\n var value = component.error ? 'error' : JSON.stringify(component.value);\n result += \"\" + (result ? '|' : '') + componentKey.replace(/([:|\\\\])/g, '\\\\$1') + \":\" + value;\n }\n return result;\n}\nfunction componentsToDebugString(components) {\n return JSON.stringify(components, function (_key, value) {\n if (value instanceof Error) {\n return errorToObject(value);\n }\n return value;\n }, 2);\n}\nfunction hashComponents(components) {\n return x64hash128(componentsToCanonicalString(components));\n}\n/**\n * Makes a GetResult implementation that calculates the visitor id hash on demand.\n * Designed for optimisation.\n */\nfunction makeLazyGetResult(components) {\n var visitorIdCache;\n // This function runs very fast, so there is no need to make it lazy\n var confidence = getConfidence(components);\n // A plain class isn't used because its getters and setters aren't enumerable.\n return {\n get visitorId() {\n if (visitorIdCache === undefined) {\n visitorIdCache = hashComponents(this.components);\n }\n return visitorIdCache;\n },\n set visitorId(visitorId) {\n visitorIdCache = visitorId;\n },\n confidence: confidence,\n components: components,\n version: version,\n };\n}\n/**\n * A delay is required to ensure consistent entropy components.\n * See https://github.com/fingerprintjs/fingerprintjs/issues/254\n * and https://github.com/fingerprintjs/fingerprintjs/issues/307\n * and https://github.com/fingerprintjs/fingerprintjs/commit/945633e7c5f67ae38eb0fea37349712f0e669b18\n */\nfunction prepareForSources(delayFallback) {\n if (delayFallback === void 0) { delayFallback = 50; }\n // A proper deadline is unknown. Let it be twice the fallback timeout so that both cases have the same average time.\n return requestIdleCallbackIfAvailable(delayFallback, delayFallback * 2);\n}\n/**\n * The function isn't exported from the index file to not allow to call it without `load()`.\n * The hiding gives more freedom for future non-breaking updates.\n *\n * A factory function is used instead of a class to shorten the attribute names in the minified code.\n * Native private class fields could've been used, but TypeScript doesn't allow them with `\"target\": \"es5\"`.\n */\nfunction makeAgent(getComponents, debug) {\n var creationTime = Date.now();\n return {\n get: function (options) {\n return tslib.__awaiter(this, void 0, void 0, function () {\n var startTime, components, result;\n return tslib.__generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n startTime = Date.now();\n return [4 /*yield*/, getComponents()];\n case 1:\n components = _a.sent();\n result = makeLazyGetResult(components);\n if (debug || (options === null || options === void 0 ? void 0 : options.debug)) {\n // console.log is ok here because it's under a debug clause\n // eslint-disable-next-line no-console\n console.log(\"Copy the text below to get the debug data:\\n\\n```\\nversion: \" + result.version + \"\\nuserAgent: \" + navigator.userAgent + \"\\ntimeBetweenLoadAndGet: \" + (startTime - creationTime) + \"\\nvisitorId: \" + result.visitorId + \"\\ncomponents: \" + componentsToDebugString(components) + \"\\n```\");\n }\n return [2 /*return*/, result];\n }\n });\n });\n },\n };\n}\n/**\n * Sends an unpersonalized AJAX request to collect installation statistics\n */\nfunction monitor() {\n // The FingerprintJS CDN (https://github.com/fingerprintjs/cdn) replaces `window.__fpjs_d_m` with `true`\n if (window.__fpjs_d_m || Math.random() >= 0.001) {\n return;\n }\n try {\n var request = new XMLHttpRequest();\n request.open('get', \"https://m1.openfpcdn.io/fingerprintjs/v\" + version + \"/npm-monitoring\", true);\n request.send();\n }\n catch (error) {\n // console.error is ok here because it's an unexpected error handler\n // eslint-disable-next-line no-console\n console.error(error);\n }\n}\n/**\n * Builds an instance of Agent and waits a delay required for a proper operation.\n */\nfunction load(_a) {\n var _b = _a === void 0 ? {} : _a, delayFallback = _b.delayFallback, debug = _b.debug, _c = _b.monitoring, monitoring = _c === void 0 ? true : _c;\n return tslib.__awaiter(this, void 0, void 0, function () {\n var getComponents;\n return tslib.__generator(this, function (_d) {\n switch (_d.label) {\n case 0:\n if (monitoring) {\n monitor();\n }\n return [4 /*yield*/, prepareForSources(delayFallback)];\n case 1:\n _d.sent();\n getComponents = loadBuiltinSources({ debug: debug });\n return [2 /*return*/, makeAgent(getComponents, debug)];\n }\n });\n });\n}\n\n// The default export is a syntax sugar (`import * as FP from '...' → import FP from '...'`).\n// It should contain all the public exported values.\nvar index = { load: load, hashComponents: hashComponents, componentsToDebugString: componentsToDebugString };\n// The exports below are for private usage. They may change unexpectedly. Use them at your own risk.\n/** Not documented, out of Semantic Versioning, usage is at your own risk */\nvar murmurX64Hash128 = x64hash128;\n\nexports.componentsToDebugString = componentsToDebugString;\nexports[\"default\"] = index;\nexports.getFullscreenElement = getFullscreenElement;\nexports.getScreenFrame = getScreenFrame;\nexports.hashComponents = hashComponents;\nexports.isAndroid = isAndroid;\nexports.isChromium = isChromium;\nexports.isDesktopSafari = isDesktopSafari;\nexports.isEdgeHTML = isEdgeHTML;\nexports.isGecko = isGecko;\nexports.isTrident = isTrident;\nexports.isWebKit = isWebKit;\nexports.load = load;\nexports.loadSources = loadSources;\nexports.murmurX64Hash128 = murmurX64Hash128;\nexports.prepareForSources = prepareForSources;\nexports.sources = sources;\nexports.transformSource = transformSource;\n","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n// Rough polyfill of https://developer.mozilla.org/en-US/docs/Web/API/AbortController\r\n// We don't actually ever use the API being polyfilled, we always use the polyfill because\r\n// it's a very new API right now.\r\n// Not exported from index.\r\n/** @private */\r\nvar AbortController = /** @class */ (function () {\r\n function AbortController() {\r\n this.isAborted = false;\r\n this.onabort = null;\r\n }\r\n AbortController.prototype.abort = function () {\r\n if (!this.isAborted) {\r\n this.isAborted = true;\r\n if (this.onabort) {\r\n this.onabort();\r\n }\r\n }\r\n };\r\n Object.defineProperty(AbortController.prototype, \"signal\", {\r\n get: function () {\r\n return this;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(AbortController.prototype, \"aborted\", {\r\n get: function () {\r\n return this.isAborted;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n return AbortController;\r\n}());\r\nexports.AbortController = AbortController;\r\n//# sourceMappingURL=AbortController.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __extends = (this && this.__extends) || (function () {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return function (d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n})();\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar Errors_1 = require(\"./Errors\");\r\nvar FetchHttpClient_1 = require(\"./FetchHttpClient\");\r\nvar HttpClient_1 = require(\"./HttpClient\");\r\nvar Utils_1 = require(\"./Utils\");\r\nvar XhrHttpClient_1 = require(\"./XhrHttpClient\");\r\n/** Default implementation of {@link @microsoft/signalr.HttpClient}. */\r\nvar DefaultHttpClient = /** @class */ (function (_super) {\r\n __extends(DefaultHttpClient, _super);\r\n /** Creates a new instance of the {@link @microsoft/signalr.DefaultHttpClient}, using the provided {@link @microsoft/signalr.ILogger} to log messages. */\r\n function DefaultHttpClient(logger) {\r\n var _this = _super.call(this) || this;\r\n if (typeof fetch !== \"undefined\" || Utils_1.Platform.isNode) {\r\n _this.httpClient = new FetchHttpClient_1.FetchHttpClient(logger);\r\n }\r\n else if (typeof XMLHttpRequest !== \"undefined\") {\r\n _this.httpClient = new XhrHttpClient_1.XhrHttpClient(logger);\r\n }\r\n else {\r\n throw new Error(\"No usable HttpClient found.\");\r\n }\r\n return _this;\r\n }\r\n /** @inheritDoc */\r\n DefaultHttpClient.prototype.send = function (request) {\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n return Promise.reject(new Errors_1.AbortError());\r\n }\r\n if (!request.method) {\r\n return Promise.reject(new Error(\"No method defined.\"));\r\n }\r\n if (!request.url) {\r\n return Promise.reject(new Error(\"No url defined.\"));\r\n }\r\n return this.httpClient.send(request);\r\n };\r\n DefaultHttpClient.prototype.getCookieString = function (url) {\r\n return this.httpClient.getCookieString(url);\r\n };\r\n return DefaultHttpClient;\r\n}(HttpClient_1.HttpClient));\r\nexports.DefaultHttpClient = DefaultHttpClient;\r\n//# sourceMappingURL=DefaultHttpClient.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n// 0, 2, 10, 30 second delays before reconnect attempts.\r\nvar DEFAULT_RETRY_DELAYS_IN_MILLISECONDS = [0, 2000, 10000, 30000, null];\r\n/** @private */\r\nvar DefaultReconnectPolicy = /** @class */ (function () {\r\n function DefaultReconnectPolicy(retryDelays) {\r\n this.retryDelays = retryDelays !== undefined ? retryDelays.concat([null]) : DEFAULT_RETRY_DELAYS_IN_MILLISECONDS;\r\n }\r\n DefaultReconnectPolicy.prototype.nextRetryDelayInMilliseconds = function (retryContext) {\r\n return this.retryDelays[retryContext.previousRetryCount];\r\n };\r\n return DefaultReconnectPolicy;\r\n}());\r\nexports.DefaultReconnectPolicy = DefaultReconnectPolicy;\r\n//# sourceMappingURL=DefaultReconnectPolicy.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __extends = (this && this.__extends) || (function () {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return function (d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n})();\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n/** Error thrown when an HTTP request fails. */\r\nvar HttpError = /** @class */ (function (_super) {\r\n __extends(HttpError, _super);\r\n /** Constructs a new instance of {@link @microsoft/signalr.HttpError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n * @param {number} statusCode The HTTP status code represented by this error.\r\n */\r\n function HttpError(errorMessage, statusCode) {\r\n var _newTarget = this.constructor;\r\n var _this = this;\r\n var trueProto = _newTarget.prototype;\r\n _this = _super.call(this, errorMessage) || this;\r\n _this.statusCode = statusCode;\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n _this.__proto__ = trueProto;\r\n return _this;\r\n }\r\n return HttpError;\r\n}(Error));\r\nexports.HttpError = HttpError;\r\n/** Error thrown when a timeout elapses. */\r\nvar TimeoutError = /** @class */ (function (_super) {\r\n __extends(TimeoutError, _super);\r\n /** Constructs a new instance of {@link @microsoft/signalr.TimeoutError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n */\r\n function TimeoutError(errorMessage) {\r\n var _newTarget = this.constructor;\r\n if (errorMessage === void 0) { errorMessage = \"A timeout occurred.\"; }\r\n var _this = this;\r\n var trueProto = _newTarget.prototype;\r\n _this = _super.call(this, errorMessage) || this;\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n _this.__proto__ = trueProto;\r\n return _this;\r\n }\r\n return TimeoutError;\r\n}(Error));\r\nexports.TimeoutError = TimeoutError;\r\n/** Error thrown when an action is aborted. */\r\nvar AbortError = /** @class */ (function (_super) {\r\n __extends(AbortError, _super);\r\n /** Constructs a new instance of {@link AbortError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n */\r\n function AbortError(errorMessage) {\r\n var _newTarget = this.constructor;\r\n if (errorMessage === void 0) { errorMessage = \"An abort occurred.\"; }\r\n var _this = this;\r\n var trueProto = _newTarget.prototype;\r\n _this = _super.call(this, errorMessage) || this;\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n _this.__proto__ = trueProto;\r\n return _this;\r\n }\r\n return AbortError;\r\n}(Error));\r\nexports.AbortError = AbortError;\r\n//# sourceMappingURL=Errors.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __extends = (this && this.__extends) || (function () {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return function (d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n})();\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __generator = (this && this.__generator) || function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar Errors_1 = require(\"./Errors\");\r\nvar HttpClient_1 = require(\"./HttpClient\");\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar Utils_1 = require(\"./Utils\");\r\nvar FetchHttpClient = /** @class */ (function (_super) {\r\n __extends(FetchHttpClient, _super);\r\n function FetchHttpClient(logger) {\r\n var _this = _super.call(this) || this;\r\n _this.logger = logger;\r\n if (typeof fetch === \"undefined\") {\r\n // In order to ignore the dynamic require in webpack builds we need to do this magic\r\n // @ts-ignore: TS doesn't know about these names\r\n var requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\r\n // Cookies aren't automatically handled in Node so we need to add a CookieJar to preserve cookies across requests\r\n _this.jar = new (requireFunc(\"tough-cookie\")).CookieJar();\r\n _this.fetchType = requireFunc(\"node-fetch\");\r\n // node-fetch doesn't have a nice API for getting and setting cookies\r\n // fetch-cookie will wrap a fetch implementation with a default CookieJar or a provided one\r\n _this.fetchType = requireFunc(\"fetch-cookie\")(_this.fetchType, _this.jar);\r\n // Node needs EventListener methods on AbortController which our custom polyfill doesn't provide\r\n _this.abortControllerType = requireFunc(\"abort-controller\");\r\n }\r\n else {\r\n _this.fetchType = fetch.bind(self);\r\n _this.abortControllerType = AbortController;\r\n }\r\n return _this;\r\n }\r\n /** @inheritDoc */\r\n FetchHttpClient.prototype.send = function (request) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var abortController, error, timeoutId, msTimeout, response, e_1, content, payload;\r\n var _this = this;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n throw new Errors_1.AbortError();\r\n }\r\n if (!request.method) {\r\n throw new Error(\"No method defined.\");\r\n }\r\n if (!request.url) {\r\n throw new Error(\"No url defined.\");\r\n }\r\n abortController = new this.abortControllerType();\r\n // Hook our abortSignal into the abort controller\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = function () {\r\n abortController.abort();\r\n error = new Errors_1.AbortError();\r\n };\r\n }\r\n timeoutId = null;\r\n if (request.timeout) {\r\n msTimeout = request.timeout;\r\n timeoutId = setTimeout(function () {\r\n abortController.abort();\r\n _this.logger.log(ILogger_1.LogLevel.Warning, \"Timeout from HTTP request.\");\r\n error = new Errors_1.TimeoutError();\r\n }, msTimeout);\r\n }\r\n _a.label = 1;\r\n case 1:\r\n _a.trys.push([1, 3, 4, 5]);\r\n return [4 /*yield*/, this.fetchType(request.url, {\r\n body: request.content,\r\n cache: \"no-cache\",\r\n credentials: request.withCredentials === true ? \"include\" : \"same-origin\",\r\n headers: __assign({ \"Content-Type\": \"text/plain;charset=UTF-8\", \"X-Requested-With\": \"XMLHttpRequest\" }, request.headers),\r\n method: request.method,\r\n mode: \"cors\",\r\n redirect: \"manual\",\r\n signal: abortController.signal,\r\n })];\r\n case 2:\r\n response = _a.sent();\r\n return [3 /*break*/, 5];\r\n case 3:\r\n e_1 = _a.sent();\r\n if (error) {\r\n throw error;\r\n }\r\n this.logger.log(ILogger_1.LogLevel.Warning, \"Error from HTTP request. \" + e_1 + \".\");\r\n throw e_1;\r\n case 4:\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = null;\r\n }\r\n return [7 /*endfinally*/];\r\n case 5:\r\n if (!response.ok) {\r\n throw new Errors_1.HttpError(response.statusText, response.status);\r\n }\r\n content = deserializeContent(response, request.responseType);\r\n return [4 /*yield*/, content];\r\n case 6:\r\n payload = _a.sent();\r\n return [2 /*return*/, new HttpClient_1.HttpResponse(response.status, response.statusText, payload)];\r\n }\r\n });\r\n });\r\n };\r\n FetchHttpClient.prototype.getCookieString = function (url) {\r\n var cookies = \"\";\r\n if (Utils_1.Platform.isNode && this.jar) {\r\n // @ts-ignore: unused variable\r\n this.jar.getCookies(url, function (e, c) { return cookies = c.join(\"; \"); });\r\n }\r\n return cookies;\r\n };\r\n return FetchHttpClient;\r\n}(HttpClient_1.HttpClient));\r\nexports.FetchHttpClient = FetchHttpClient;\r\nfunction deserializeContent(response, responseType) {\r\n var content;\r\n switch (responseType) {\r\n case \"arraybuffer\":\r\n content = response.arrayBuffer();\r\n break;\r\n case \"text\":\r\n content = response.text();\r\n break;\r\n case \"blob\":\r\n case \"document\":\r\n case \"json\":\r\n throw new Error(responseType + \" is not supported.\");\r\n default:\r\n content = response.text();\r\n break;\r\n }\r\n return content;\r\n}\r\n//# sourceMappingURL=FetchHttpClient.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar TextMessageFormat_1 = require(\"./TextMessageFormat\");\r\nvar Utils_1 = require(\"./Utils\");\r\n/** @private */\r\nvar HandshakeProtocol = /** @class */ (function () {\r\n function HandshakeProtocol() {\r\n }\r\n // Handshake request is always JSON\r\n HandshakeProtocol.prototype.writeHandshakeRequest = function (handshakeRequest) {\r\n return TextMessageFormat_1.TextMessageFormat.write(JSON.stringify(handshakeRequest));\r\n };\r\n HandshakeProtocol.prototype.parseHandshakeResponse = function (data) {\r\n var responseMessage;\r\n var messageData;\r\n var remainingData;\r\n if (Utils_1.isArrayBuffer(data) || (typeof Buffer !== \"undefined\" && data instanceof Buffer)) {\r\n // Format is binary but still need to read JSON text from handshake response\r\n var binaryData = new Uint8Array(data);\r\n var separatorIndex = binaryData.indexOf(TextMessageFormat_1.TextMessageFormat.RecordSeparatorCode);\r\n if (separatorIndex === -1) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n // content before separator is handshake response\r\n // optional content after is additional messages\r\n var responseLength = separatorIndex + 1;\r\n messageData = String.fromCharCode.apply(null, binaryData.slice(0, responseLength));\r\n remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;\r\n }\r\n else {\r\n var textData = data;\r\n var separatorIndex = textData.indexOf(TextMessageFormat_1.TextMessageFormat.RecordSeparator);\r\n if (separatorIndex === -1) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n // content before separator is handshake response\r\n // optional content after is additional messages\r\n var responseLength = separatorIndex + 1;\r\n messageData = textData.substring(0, responseLength);\r\n remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null;\r\n }\r\n // At this point we should have just the single handshake message\r\n var messages = TextMessageFormat_1.TextMessageFormat.parse(messageData);\r\n var response = JSON.parse(messages[0]);\r\n if (response.type) {\r\n throw new Error(\"Expected a handshake response from the server.\");\r\n }\r\n responseMessage = response;\r\n // multiple messages could have arrived with handshake\r\n // return additional data to be parsed as usual, or null if all parsed\r\n return [remainingData, responseMessage];\r\n };\r\n return HandshakeProtocol;\r\n}());\r\nexports.HandshakeProtocol = HandshakeProtocol;\r\n//# sourceMappingURL=HandshakeProtocol.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n/** Represents an HTTP response. */\r\nvar HttpResponse = /** @class */ (function () {\r\n function HttpResponse(statusCode, statusText, content) {\r\n this.statusCode = statusCode;\r\n this.statusText = statusText;\r\n this.content = content;\r\n }\r\n return HttpResponse;\r\n}());\r\nexports.HttpResponse = HttpResponse;\r\n/** Abstraction over an HTTP client.\r\n *\r\n * This class provides an abstraction over an HTTP client so that a different implementation can be provided on different platforms.\r\n */\r\nvar HttpClient = /** @class */ (function () {\r\n function HttpClient() {\r\n }\r\n HttpClient.prototype.get = function (url, options) {\r\n return this.send(__assign({}, options, { method: \"GET\", url: url }));\r\n };\r\n HttpClient.prototype.post = function (url, options) {\r\n return this.send(__assign({}, options, { method: \"POST\", url: url }));\r\n };\r\n HttpClient.prototype.delete = function (url, options) {\r\n return this.send(__assign({}, options, { method: \"DELETE\", url: url }));\r\n };\r\n /** Gets all cookies that apply to the specified URL.\r\n *\r\n * @param url The URL that the cookies are valid for.\r\n * @returns {string} A string containing all the key-value cookie pairs for the specified URL.\r\n */\r\n // @ts-ignore\r\n HttpClient.prototype.getCookieString = function (url) {\r\n return \"\";\r\n };\r\n return HttpClient;\r\n}());\r\nexports.HttpClient = HttpClient;\r\n//# sourceMappingURL=HttpClient.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __generator = (this && this.__generator) || function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar DefaultHttpClient_1 = require(\"./DefaultHttpClient\");\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar ITransport_1 = require(\"./ITransport\");\r\nvar LongPollingTransport_1 = require(\"./LongPollingTransport\");\r\nvar ServerSentEventsTransport_1 = require(\"./ServerSentEventsTransport\");\r\nvar Utils_1 = require(\"./Utils\");\r\nvar WebSocketTransport_1 = require(\"./WebSocketTransport\");\r\nvar MAX_REDIRECTS = 100;\r\n/** @private */\r\nvar HttpConnection = /** @class */ (function () {\r\n function HttpConnection(url, options) {\r\n if (options === void 0) { options = {}; }\r\n this.features = {};\r\n this.negotiateVersion = 1;\r\n Utils_1.Arg.isRequired(url, \"url\");\r\n this.logger = Utils_1.createLogger(options.logger);\r\n this.baseUrl = this.resolveUrl(url);\r\n options = options || {};\r\n options.logMessageContent = options.logMessageContent === undefined ? false : options.logMessageContent;\r\n if (typeof options.withCredentials === \"boolean\" || options.withCredentials === undefined) {\r\n options.withCredentials = options.withCredentials === undefined ? true : options.withCredentials;\r\n }\r\n else {\r\n throw new Error(\"withCredentials option was not a 'boolean' or 'undefined' value\");\r\n }\r\n var webSocketModule = null;\r\n var eventSourceModule = null;\r\n if (Utils_1.Platform.isNode && typeof require !== \"undefined\") {\r\n // In order to ignore the dynamic require in webpack builds we need to do this magic\r\n // @ts-ignore: TS doesn't know about these names\r\n var requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\r\n webSocketModule = requireFunc(\"ws\");\r\n eventSourceModule = requireFunc(\"eventsource\");\r\n }\r\n if (!Utils_1.Platform.isNode && typeof WebSocket !== \"undefined\" && !options.WebSocket) {\r\n options.WebSocket = WebSocket;\r\n }\r\n else if (Utils_1.Platform.isNode && !options.WebSocket) {\r\n if (webSocketModule) {\r\n options.WebSocket = webSocketModule;\r\n }\r\n }\r\n if (!Utils_1.Platform.isNode && typeof EventSource !== \"undefined\" && !options.EventSource) {\r\n options.EventSource = EventSource;\r\n }\r\n else if (Utils_1.Platform.isNode && !options.EventSource) {\r\n if (typeof eventSourceModule !== \"undefined\") {\r\n options.EventSource = eventSourceModule;\r\n }\r\n }\r\n this.httpClient = options.httpClient || new DefaultHttpClient_1.DefaultHttpClient(this.logger);\r\n this.connectionState = \"Disconnected\" /* Disconnected */;\r\n this.connectionStarted = false;\r\n this.options = options;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n HttpConnection.prototype.start = function (transferFormat) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var message, message;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n transferFormat = transferFormat || ITransport_1.TransferFormat.Binary;\r\n Utils_1.Arg.isIn(transferFormat, ITransport_1.TransferFormat, \"transferFormat\");\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Starting connection with transfer format '\" + ITransport_1.TransferFormat[transferFormat] + \"'.\");\r\n if (this.connectionState !== \"Disconnected\" /* Disconnected */) {\r\n return [2 /*return*/, Promise.reject(new Error(\"Cannot start an HttpConnection that is not in the 'Disconnected' state.\"))];\r\n }\r\n this.connectionState = \"Connecting\" /* Connecting */;\r\n this.startInternalPromise = this.startInternal(transferFormat);\r\n return [4 /*yield*/, this.startInternalPromise];\r\n case 1:\r\n _a.sent();\r\n if (!(this.connectionState === \"Disconnecting\" /* Disconnecting */)) return [3 /*break*/, 3];\r\n message = \"Failed to start the HttpConnection before stop() was called.\";\r\n this.logger.log(ILogger_1.LogLevel.Error, message);\r\n // We cannot await stopPromise inside startInternal since stopInternal awaits the startInternalPromise.\r\n return [4 /*yield*/, this.stopPromise];\r\n case 2:\r\n // We cannot await stopPromise inside startInternal since stopInternal awaits the startInternalPromise.\r\n _a.sent();\r\n return [2 /*return*/, Promise.reject(new Error(message))];\r\n case 3:\r\n if (this.connectionState !== \"Connected\" /* Connected */) {\r\n message = \"HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!\";\r\n this.logger.log(ILogger_1.LogLevel.Error, message);\r\n return [2 /*return*/, Promise.reject(new Error(message))];\r\n }\r\n _a.label = 4;\r\n case 4:\r\n this.connectionStarted = true;\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HttpConnection.prototype.send = function (data) {\r\n if (this.connectionState !== \"Connected\" /* Connected */) {\r\n return Promise.reject(new Error(\"Cannot send data if the connection is not in the 'Connected' State.\"));\r\n }\r\n if (!this.sendQueue) {\r\n this.sendQueue = new TransportSendQueue(this.transport);\r\n }\r\n // Transport will not be null if state is connected\r\n return this.sendQueue.send(data);\r\n };\r\n HttpConnection.prototype.stop = function (error) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var _this = this;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (this.connectionState === \"Disconnected\" /* Disconnected */) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Call to HttpConnection.stop(\" + error + \") ignored because the connection is already in the disconnected state.\");\r\n return [2 /*return*/, Promise.resolve()];\r\n }\r\n if (this.connectionState === \"Disconnecting\" /* Disconnecting */) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Call to HttpConnection.stop(\" + error + \") ignored because the connection is already in the disconnecting state.\");\r\n return [2 /*return*/, this.stopPromise];\r\n }\r\n this.connectionState = \"Disconnecting\" /* Disconnecting */;\r\n this.stopPromise = new Promise(function (resolve) {\r\n // Don't complete stop() until stopConnection() completes.\r\n _this.stopPromiseResolver = resolve;\r\n });\r\n // stopInternal should never throw so just observe it.\r\n return [4 /*yield*/, this.stopInternal(error)];\r\n case 1:\r\n // stopInternal should never throw so just observe it.\r\n _a.sent();\r\n return [4 /*yield*/, this.stopPromise];\r\n case 2:\r\n _a.sent();\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HttpConnection.prototype.stopInternal = function (error) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var e_1, e_2;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n // Set error as soon as possible otherwise there is a race between\r\n // the transport closing and providing an error and the error from a close message\r\n // We would prefer the close message error.\r\n this.stopError = error;\r\n _a.label = 1;\r\n case 1:\r\n _a.trys.push([1, 3, , 4]);\r\n return [4 /*yield*/, this.startInternalPromise];\r\n case 2:\r\n _a.sent();\r\n return [3 /*break*/, 4];\r\n case 3:\r\n e_1 = _a.sent();\r\n return [3 /*break*/, 4];\r\n case 4:\r\n if (!this.transport) return [3 /*break*/, 9];\r\n _a.label = 5;\r\n case 5:\r\n _a.trys.push([5, 7, , 8]);\r\n return [4 /*yield*/, this.transport.stop()];\r\n case 6:\r\n _a.sent();\r\n return [3 /*break*/, 8];\r\n case 7:\r\n e_2 = _a.sent();\r\n this.logger.log(ILogger_1.LogLevel.Error, \"HttpConnection.transport.stop() threw error '\" + e_2 + \"'.\");\r\n this.stopConnection();\r\n return [3 /*break*/, 8];\r\n case 8:\r\n this.transport = undefined;\r\n return [3 /*break*/, 10];\r\n case 9:\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.\");\r\n this.stopConnection();\r\n _a.label = 10;\r\n case 10: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HttpConnection.prototype.startInternal = function (transferFormat) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var url, negotiateResponse, redirects, _loop_1, this_1, e_3;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n url = this.baseUrl;\r\n this.accessTokenFactory = this.options.accessTokenFactory;\r\n _a.label = 1;\r\n case 1:\r\n _a.trys.push([1, 12, , 13]);\r\n if (!this.options.skipNegotiation) return [3 /*break*/, 5];\r\n if (!(this.options.transport === ITransport_1.HttpTransportType.WebSockets)) return [3 /*break*/, 3];\r\n // No need to add a connection ID in this case\r\n this.transport = this.constructTransport(ITransport_1.HttpTransportType.WebSockets);\r\n // We should just call connect directly in this case.\r\n // No fallback or negotiate in this case.\r\n return [4 /*yield*/, this.startTransport(url, transferFormat)];\r\n case 2:\r\n // We should just call connect directly in this case.\r\n // No fallback or negotiate in this case.\r\n _a.sent();\r\n return [3 /*break*/, 4];\r\n case 3: throw new Error(\"Negotiation can only be skipped when using the WebSocket transport directly.\");\r\n case 4: return [3 /*break*/, 11];\r\n case 5:\r\n negotiateResponse = null;\r\n redirects = 0;\r\n _loop_1 = function () {\r\n var accessToken_1;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, this_1.getNegotiationResponse(url)];\r\n case 1:\r\n negotiateResponse = _a.sent();\r\n // the user tries to stop the connection when it is being started\r\n if (this_1.connectionState === \"Disconnecting\" /* Disconnecting */ || this_1.connectionState === \"Disconnected\" /* Disconnected */) {\r\n throw new Error(\"The connection was stopped during negotiation.\");\r\n }\r\n if (negotiateResponse.error) {\r\n throw new Error(negotiateResponse.error);\r\n }\r\n if (negotiateResponse.ProtocolVersion) {\r\n throw new Error(\"Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.\");\r\n }\r\n if (negotiateResponse.url) {\r\n url = negotiateResponse.url;\r\n }\r\n if (negotiateResponse.accessToken) {\r\n accessToken_1 = negotiateResponse.accessToken;\r\n this_1.accessTokenFactory = function () { return accessToken_1; };\r\n }\r\n redirects++;\r\n return [2 /*return*/];\r\n }\r\n });\r\n };\r\n this_1 = this;\r\n _a.label = 6;\r\n case 6: return [5 /*yield**/, _loop_1()];\r\n case 7:\r\n _a.sent();\r\n _a.label = 8;\r\n case 8:\r\n if (negotiateResponse.url && redirects < MAX_REDIRECTS) return [3 /*break*/, 6];\r\n _a.label = 9;\r\n case 9:\r\n if (redirects === MAX_REDIRECTS && negotiateResponse.url) {\r\n throw new Error(\"Negotiate redirection limit exceeded.\");\r\n }\r\n return [4 /*yield*/, this.createTransport(url, this.options.transport, negotiateResponse, transferFormat)];\r\n case 10:\r\n _a.sent();\r\n _a.label = 11;\r\n case 11:\r\n if (this.transport instanceof LongPollingTransport_1.LongPollingTransport) {\r\n this.features.inherentKeepAlive = true;\r\n }\r\n if (this.connectionState === \"Connecting\" /* Connecting */) {\r\n // Ensure the connection transitions to the connected state prior to completing this.startInternalPromise.\r\n // start() will handle the case when stop was called and startInternal exits still in the disconnecting state.\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"The HttpConnection connected successfully.\");\r\n this.connectionState = \"Connected\" /* Connected */;\r\n }\r\n return [3 /*break*/, 13];\r\n case 12:\r\n e_3 = _a.sent();\r\n this.logger.log(ILogger_1.LogLevel.Error, \"Failed to start the connection: \" + e_3);\r\n this.connectionState = \"Disconnected\" /* Disconnected */;\r\n this.transport = undefined;\r\n return [2 /*return*/, Promise.reject(e_3)];\r\n case 13: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HttpConnection.prototype.getNegotiationResponse = function (url) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var headers, token, _a, name, value, negotiateUrl, response, negotiateResponse, e_4;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0:\r\n headers = {};\r\n if (!this.accessTokenFactory) return [3 /*break*/, 2];\r\n return [4 /*yield*/, this.accessTokenFactory()];\r\n case 1:\r\n token = _b.sent();\r\n if (token) {\r\n headers[\"Authorization\"] = \"Bearer \" + token;\r\n }\r\n _b.label = 2;\r\n case 2:\r\n _a = Utils_1.getUserAgentHeader(), name = _a[0], value = _a[1];\r\n headers[name] = value;\r\n negotiateUrl = this.resolveNegotiateUrl(url);\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Sending negotiation request: \" + negotiateUrl + \".\");\r\n _b.label = 3;\r\n case 3:\r\n _b.trys.push([3, 5, , 6]);\r\n return [4 /*yield*/, this.httpClient.post(negotiateUrl, {\r\n content: \"\",\r\n headers: __assign({}, headers, this.options.headers),\r\n withCredentials: this.options.withCredentials,\r\n })];\r\n case 4:\r\n response = _b.sent();\r\n if (response.statusCode !== 200) {\r\n return [2 /*return*/, Promise.reject(new Error(\"Unexpected status code returned from negotiate '\" + response.statusCode + \"'\"))];\r\n }\r\n negotiateResponse = JSON.parse(response.content);\r\n if (!negotiateResponse.negotiateVersion || negotiateResponse.negotiateVersion < 1) {\r\n // Negotiate version 0 doesn't use connectionToken\r\n // So we set it equal to connectionId so all our logic can use connectionToken without being aware of the negotiate version\r\n negotiateResponse.connectionToken = negotiateResponse.connectionId;\r\n }\r\n return [2 /*return*/, negotiateResponse];\r\n case 5:\r\n e_4 = _b.sent();\r\n this.logger.log(ILogger_1.LogLevel.Error, \"Failed to complete negotiation with the server: \" + e_4);\r\n return [2 /*return*/, Promise.reject(e_4)];\r\n case 6: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HttpConnection.prototype.createConnectUrl = function (url, connectionToken) {\r\n if (!connectionToken) {\r\n return url;\r\n }\r\n return url + (url.indexOf(\"?\") === -1 ? \"?\" : \"&\") + (\"id=\" + connectionToken);\r\n };\r\n HttpConnection.prototype.createTransport = function (url, requestedTransport, negotiateResponse, requestedTransferFormat) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var connectUrl, transportExceptions, transports, negotiate, _i, transports_1, endpoint, transportOrError, ex_1, ex_2, message;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n connectUrl = this.createConnectUrl(url, negotiateResponse.connectionToken);\r\n if (!this.isITransport(requestedTransport)) return [3 /*break*/, 2];\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Connection was provided an instance of ITransport, using that directly.\");\r\n this.transport = requestedTransport;\r\n return [4 /*yield*/, this.startTransport(connectUrl, requestedTransferFormat)];\r\n case 1:\r\n _a.sent();\r\n this.connectionId = negotiateResponse.connectionId;\r\n return [2 /*return*/];\r\n case 2:\r\n transportExceptions = [];\r\n transports = negotiateResponse.availableTransports || [];\r\n negotiate = negotiateResponse;\r\n _i = 0, transports_1 = transports;\r\n _a.label = 3;\r\n case 3:\r\n if (!(_i < transports_1.length)) return [3 /*break*/, 13];\r\n endpoint = transports_1[_i];\r\n transportOrError = this.resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat);\r\n if (!(transportOrError instanceof Error)) return [3 /*break*/, 4];\r\n // Store the error and continue, we don't want to cause a re-negotiate in these cases\r\n transportExceptions.push(endpoint.transport + \" failed: \" + transportOrError);\r\n return [3 /*break*/, 12];\r\n case 4:\r\n if (!this.isITransport(transportOrError)) return [3 /*break*/, 12];\r\n this.transport = transportOrError;\r\n if (!!negotiate) return [3 /*break*/, 9];\r\n _a.label = 5;\r\n case 5:\r\n _a.trys.push([5, 7, , 8]);\r\n return [4 /*yield*/, this.getNegotiationResponse(url)];\r\n case 6:\r\n negotiate = _a.sent();\r\n return [3 /*break*/, 8];\r\n case 7:\r\n ex_1 = _a.sent();\r\n return [2 /*return*/, Promise.reject(ex_1)];\r\n case 8:\r\n connectUrl = this.createConnectUrl(url, negotiate.connectionToken);\r\n _a.label = 9;\r\n case 9:\r\n _a.trys.push([9, 11, , 12]);\r\n return [4 /*yield*/, this.startTransport(connectUrl, requestedTransferFormat)];\r\n case 10:\r\n _a.sent();\r\n this.connectionId = negotiate.connectionId;\r\n return [2 /*return*/];\r\n case 11:\r\n ex_2 = _a.sent();\r\n this.logger.log(ILogger_1.LogLevel.Error, \"Failed to start the transport '\" + endpoint.transport + \"': \" + ex_2);\r\n negotiate = undefined;\r\n transportExceptions.push(endpoint.transport + \" failed: \" + ex_2);\r\n if (this.connectionState !== \"Connecting\" /* Connecting */) {\r\n message = \"Failed to select transport before stop() was called.\";\r\n this.logger.log(ILogger_1.LogLevel.Debug, message);\r\n return [2 /*return*/, Promise.reject(new Error(message))];\r\n }\r\n return [3 /*break*/, 12];\r\n case 12:\r\n _i++;\r\n return [3 /*break*/, 3];\r\n case 13:\r\n if (transportExceptions.length > 0) {\r\n return [2 /*return*/, Promise.reject(new Error(\"Unable to connect to the server with any of the available transports. \" + transportExceptions.join(\" \")))];\r\n }\r\n return [2 /*return*/, Promise.reject(new Error(\"None of the transports supported by the client are supported by the server.\"))];\r\n }\r\n });\r\n });\r\n };\r\n HttpConnection.prototype.constructTransport = function (transport) {\r\n switch (transport) {\r\n case ITransport_1.HttpTransportType.WebSockets:\r\n if (!this.options.WebSocket) {\r\n throw new Error(\"'WebSocket' is not supported in your environment.\");\r\n }\r\n return new WebSocketTransport_1.WebSocketTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.WebSocket, this.options.headers || {});\r\n case ITransport_1.HttpTransportType.ServerSentEvents:\r\n if (!this.options.EventSource) {\r\n throw new Error(\"'EventSource' is not supported in your environment.\");\r\n }\r\n return new ServerSentEventsTransport_1.ServerSentEventsTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.EventSource, this.options.withCredentials, this.options.headers || {});\r\n case ITransport_1.HttpTransportType.LongPolling:\r\n return new LongPollingTransport_1.LongPollingTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.withCredentials, this.options.headers || {});\r\n default:\r\n throw new Error(\"Unknown transport: \" + transport + \".\");\r\n }\r\n };\r\n HttpConnection.prototype.startTransport = function (url, transferFormat) {\r\n var _this = this;\r\n this.transport.onreceive = this.onreceive;\r\n this.transport.onclose = function (e) { return _this.stopConnection(e); };\r\n return this.transport.connect(url, transferFormat);\r\n };\r\n HttpConnection.prototype.resolveTransportOrError = function (endpoint, requestedTransport, requestedTransferFormat) {\r\n var transport = ITransport_1.HttpTransportType[endpoint.transport];\r\n if (transport === null || transport === undefined) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Skipping transport '\" + endpoint.transport + \"' because it is not supported by this client.\");\r\n return new Error(\"Skipping transport '\" + endpoint.transport + \"' because it is not supported by this client.\");\r\n }\r\n else {\r\n if (transportMatches(requestedTransport, transport)) {\r\n var transferFormats = endpoint.transferFormats.map(function (s) { return ITransport_1.TransferFormat[s]; });\r\n if (transferFormats.indexOf(requestedTransferFormat) >= 0) {\r\n if ((transport === ITransport_1.HttpTransportType.WebSockets && !this.options.WebSocket) ||\r\n (transport === ITransport_1.HttpTransportType.ServerSentEvents && !this.options.EventSource)) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Skipping transport '\" + ITransport_1.HttpTransportType[transport] + \"' because it is not supported in your environment.'\");\r\n return new Error(\"'\" + ITransport_1.HttpTransportType[transport] + \"' is not supported in your environment.\");\r\n }\r\n else {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Selecting transport '\" + ITransport_1.HttpTransportType[transport] + \"'.\");\r\n try {\r\n return this.constructTransport(transport);\r\n }\r\n catch (ex) {\r\n return ex;\r\n }\r\n }\r\n }\r\n else {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Skipping transport '\" + ITransport_1.HttpTransportType[transport] + \"' because it does not support the requested transfer format '\" + ITransport_1.TransferFormat[requestedTransferFormat] + \"'.\");\r\n return new Error(\"'\" + ITransport_1.HttpTransportType[transport] + \"' does not support \" + ITransport_1.TransferFormat[requestedTransferFormat] + \".\");\r\n }\r\n }\r\n else {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Skipping transport '\" + ITransport_1.HttpTransportType[transport] + \"' because it was disabled by the client.\");\r\n return new Error(\"'\" + ITransport_1.HttpTransportType[transport] + \"' is disabled by the client.\");\r\n }\r\n }\r\n };\r\n HttpConnection.prototype.isITransport = function (transport) {\r\n return transport && typeof (transport) === \"object\" && \"connect\" in transport;\r\n };\r\n HttpConnection.prototype.stopConnection = function (error) {\r\n var _this = this;\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"HttpConnection.stopConnection(\" + error + \") called while in state \" + this.connectionState + \".\");\r\n this.transport = undefined;\r\n // If we have a stopError, it takes precedence over the error from the transport\r\n error = this.stopError || error;\r\n this.stopError = undefined;\r\n if (this.connectionState === \"Disconnected\" /* Disconnected */) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Call to HttpConnection.stopConnection(\" + error + \") was ignored because the connection is already in the disconnected state.\");\r\n return;\r\n }\r\n if (this.connectionState === \"Connecting\" /* Connecting */) {\r\n this.logger.log(ILogger_1.LogLevel.Warning, \"Call to HttpConnection.stopConnection(\" + error + \") was ignored because the connection is still in the connecting state.\");\r\n throw new Error(\"HttpConnection.stopConnection(\" + error + \") was called while the connection is still in the connecting state.\");\r\n }\r\n if (this.connectionState === \"Disconnecting\" /* Disconnecting */) {\r\n // A call to stop() induced this call to stopConnection and needs to be completed.\r\n // Any stop() awaiters will be scheduled to continue after the onclose callback fires.\r\n this.stopPromiseResolver();\r\n }\r\n if (error) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"Connection disconnected with error '\" + error + \"'.\");\r\n }\r\n else {\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Connection disconnected.\");\r\n }\r\n if (this.sendQueue) {\r\n this.sendQueue.stop().catch(function (e) {\r\n _this.logger.log(ILogger_1.LogLevel.Error, \"TransportSendQueue.stop() threw error '\" + e + \"'.\");\r\n });\r\n this.sendQueue = undefined;\r\n }\r\n this.connectionId = undefined;\r\n this.connectionState = \"Disconnected\" /* Disconnected */;\r\n if (this.connectionStarted) {\r\n this.connectionStarted = false;\r\n try {\r\n if (this.onclose) {\r\n this.onclose(error);\r\n }\r\n }\r\n catch (e) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"HttpConnection.onclose(\" + error + \") threw error '\" + e + \"'.\");\r\n }\r\n }\r\n };\r\n HttpConnection.prototype.resolveUrl = function (url) {\r\n // startsWith is not supported in IE\r\n if (url.lastIndexOf(\"https://\", 0) === 0 || url.lastIndexOf(\"http://\", 0) === 0) {\r\n return url;\r\n }\r\n if (!Utils_1.Platform.isBrowser || !window.document) {\r\n throw new Error(\"Cannot resolve '\" + url + \"'.\");\r\n }\r\n // Setting the url to the href propery of an anchor tag handles normalization\r\n // for us. There are 3 main cases.\r\n // 1. Relative path normalization e.g \"b\" -> \"http://localhost:5000/a/b\"\r\n // 2. Absolute path normalization e.g \"/a/b\" -> \"http://localhost:5000/a/b\"\r\n // 3. Networkpath reference normalization e.g \"//localhost:5000/a/b\" -> \"http://localhost:5000/a/b\"\r\n var aTag = window.document.createElement(\"a\");\r\n aTag.href = url;\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Normalizing '\" + url + \"' to '\" + aTag.href + \"'.\");\r\n return aTag.href;\r\n };\r\n HttpConnection.prototype.resolveNegotiateUrl = function (url) {\r\n var index = url.indexOf(\"?\");\r\n var negotiateUrl = url.substring(0, index === -1 ? url.length : index);\r\n if (negotiateUrl[negotiateUrl.length - 1] !== \"/\") {\r\n negotiateUrl += \"/\";\r\n }\r\n negotiateUrl += \"negotiate\";\r\n negotiateUrl += index === -1 ? \"\" : url.substring(index);\r\n if (negotiateUrl.indexOf(\"negotiateVersion\") === -1) {\r\n negotiateUrl += index === -1 ? \"?\" : \"&\";\r\n negotiateUrl += \"negotiateVersion=\" + this.negotiateVersion;\r\n }\r\n return negotiateUrl;\r\n };\r\n return HttpConnection;\r\n}());\r\nexports.HttpConnection = HttpConnection;\r\nfunction transportMatches(requestedTransport, actualTransport) {\r\n return !requestedTransport || ((actualTransport & requestedTransport) !== 0);\r\n}\r\n/** @private */\r\nvar TransportSendQueue = /** @class */ (function () {\r\n function TransportSendQueue(transport) {\r\n this.transport = transport;\r\n this.buffer = [];\r\n this.executing = true;\r\n this.sendBufferedData = new PromiseSource();\r\n this.transportResult = new PromiseSource();\r\n this.sendLoopPromise = this.sendLoop();\r\n }\r\n TransportSendQueue.prototype.send = function (data) {\r\n this.bufferData(data);\r\n if (!this.transportResult) {\r\n this.transportResult = new PromiseSource();\r\n }\r\n return this.transportResult.promise;\r\n };\r\n TransportSendQueue.prototype.stop = function () {\r\n this.executing = false;\r\n this.sendBufferedData.resolve();\r\n return this.sendLoopPromise;\r\n };\r\n TransportSendQueue.prototype.bufferData = function (data) {\r\n if (this.buffer.length && typeof (this.buffer[0]) !== typeof (data)) {\r\n throw new Error(\"Expected data to be of type \" + typeof (this.buffer) + \" but was of type \" + typeof (data));\r\n }\r\n this.buffer.push(data);\r\n this.sendBufferedData.resolve();\r\n };\r\n TransportSendQueue.prototype.sendLoop = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var transportResult, data, error_1;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (!true) return [3 /*break*/, 6];\r\n return [4 /*yield*/, this.sendBufferedData.promise];\r\n case 1:\r\n _a.sent();\r\n if (!this.executing) {\r\n if (this.transportResult) {\r\n this.transportResult.reject(\"Connection stopped.\");\r\n }\r\n return [3 /*break*/, 6];\r\n }\r\n this.sendBufferedData = new PromiseSource();\r\n transportResult = this.transportResult;\r\n this.transportResult = undefined;\r\n data = typeof (this.buffer[0]) === \"string\" ?\r\n this.buffer.join(\"\") :\r\n TransportSendQueue.concatBuffers(this.buffer);\r\n this.buffer.length = 0;\r\n _a.label = 2;\r\n case 2:\r\n _a.trys.push([2, 4, , 5]);\r\n return [4 /*yield*/, this.transport.send(data)];\r\n case 3:\r\n _a.sent();\r\n transportResult.resolve();\r\n return [3 /*break*/, 5];\r\n case 4:\r\n error_1 = _a.sent();\r\n transportResult.reject(error_1);\r\n return [3 /*break*/, 5];\r\n case 5: return [3 /*break*/, 0];\r\n case 6: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n TransportSendQueue.concatBuffers = function (arrayBuffers) {\r\n var totalLength = arrayBuffers.map(function (b) { return b.byteLength; }).reduce(function (a, b) { return a + b; });\r\n var result = new Uint8Array(totalLength);\r\n var offset = 0;\r\n for (var _i = 0, arrayBuffers_1 = arrayBuffers; _i < arrayBuffers_1.length; _i++) {\r\n var item = arrayBuffers_1[_i];\r\n result.set(new Uint8Array(item), offset);\r\n offset += item.byteLength;\r\n }\r\n return result.buffer;\r\n };\r\n return TransportSendQueue;\r\n}());\r\nexports.TransportSendQueue = TransportSendQueue;\r\nvar PromiseSource = /** @class */ (function () {\r\n function PromiseSource() {\r\n var _this = this;\r\n this.promise = new Promise(function (resolve, reject) {\r\n var _a;\r\n return _a = [resolve, reject], _this.resolver = _a[0], _this.rejecter = _a[1], _a;\r\n });\r\n }\r\n PromiseSource.prototype.resolve = function () {\r\n this.resolver();\r\n };\r\n PromiseSource.prototype.reject = function (reason) {\r\n this.rejecter(reason);\r\n };\r\n return PromiseSource;\r\n}());\r\n//# sourceMappingURL=HttpConnection.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __generator = (this && this.__generator) || function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar HandshakeProtocol_1 = require(\"./HandshakeProtocol\");\r\nvar IHubProtocol_1 = require(\"./IHubProtocol\");\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar Subject_1 = require(\"./Subject\");\r\nvar Utils_1 = require(\"./Utils\");\r\nvar DEFAULT_TIMEOUT_IN_MS = 30 * 1000;\r\nvar DEFAULT_PING_INTERVAL_IN_MS = 15 * 1000;\r\n/** Describes the current state of the {@link HubConnection} to the server. */\r\nvar HubConnectionState;\r\n(function (HubConnectionState) {\r\n /** The hub connection is disconnected. */\r\n HubConnectionState[\"Disconnected\"] = \"Disconnected\";\r\n /** The hub connection is connecting. */\r\n HubConnectionState[\"Connecting\"] = \"Connecting\";\r\n /** The hub connection is connected. */\r\n HubConnectionState[\"Connected\"] = \"Connected\";\r\n /** The hub connection is disconnecting. */\r\n HubConnectionState[\"Disconnecting\"] = \"Disconnecting\";\r\n /** The hub connection is reconnecting. */\r\n HubConnectionState[\"Reconnecting\"] = \"Reconnecting\";\r\n})(HubConnectionState = exports.HubConnectionState || (exports.HubConnectionState = {}));\r\n/** Represents a connection to a SignalR Hub. */\r\nvar HubConnection = /** @class */ (function () {\r\n function HubConnection(connection, logger, protocol, reconnectPolicy) {\r\n var _this = this;\r\n Utils_1.Arg.isRequired(connection, \"connection\");\r\n Utils_1.Arg.isRequired(logger, \"logger\");\r\n Utils_1.Arg.isRequired(protocol, \"protocol\");\r\n this.serverTimeoutInMilliseconds = DEFAULT_TIMEOUT_IN_MS;\r\n this.keepAliveIntervalInMilliseconds = DEFAULT_PING_INTERVAL_IN_MS;\r\n this.logger = logger;\r\n this.protocol = protocol;\r\n this.connection = connection;\r\n this.reconnectPolicy = reconnectPolicy;\r\n this.handshakeProtocol = new HandshakeProtocol_1.HandshakeProtocol();\r\n this.connection.onreceive = function (data) { return _this.processIncomingData(data); };\r\n this.connection.onclose = function (error) { return _this.connectionClosed(error); };\r\n this.callbacks = {};\r\n this.methods = {};\r\n this.closedCallbacks = [];\r\n this.reconnectingCallbacks = [];\r\n this.reconnectedCallbacks = [];\r\n this.invocationId = 0;\r\n this.receivedHandshakeResponse = false;\r\n this.connectionState = HubConnectionState.Disconnected;\r\n this.connectionStarted = false;\r\n this.cachedPingMessage = this.protocol.writeMessage({ type: IHubProtocol_1.MessageType.Ping });\r\n }\r\n /** @internal */\r\n // Using a public static factory method means we can have a private constructor and an _internal_\r\n // create method that can be used by HubConnectionBuilder. An \"internal\" constructor would just\r\n // be stripped away and the '.d.ts' file would have no constructor, which is interpreted as a\r\n // public parameter-less constructor.\r\n HubConnection.create = function (connection, logger, protocol, reconnectPolicy) {\r\n return new HubConnection(connection, logger, protocol, reconnectPolicy);\r\n };\r\n Object.defineProperty(HubConnection.prototype, \"state\", {\r\n /** Indicates the state of the {@link HubConnection} to the server. */\r\n get: function () {\r\n return this.connectionState;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(HubConnection.prototype, \"connectionId\", {\r\n /** Represents the connection id of the {@link HubConnection} on the server. The connection id will be null when the connection is either\r\n * in the disconnected state or if the negotiation step was skipped.\r\n */\r\n get: function () {\r\n return this.connection ? (this.connection.connectionId || null) : null;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(HubConnection.prototype, \"baseUrl\", {\r\n /** Indicates the url of the {@link HubConnection} to the server. */\r\n get: function () {\r\n return this.connection.baseUrl || \"\";\r\n },\r\n /**\r\n * Sets a new url for the HubConnection. Note that the url can only be changed when the connection is in either the Disconnected or\r\n * Reconnecting states.\r\n * @param {string} url The url to connect to.\r\n */\r\n set: function (url) {\r\n if (this.connectionState !== HubConnectionState.Disconnected && this.connectionState !== HubConnectionState.Reconnecting) {\r\n throw new Error(\"The HubConnection must be in the Disconnected or Reconnecting state to change the url.\");\r\n }\r\n if (!url) {\r\n throw new Error(\"The HubConnection url must be a valid url.\");\r\n }\r\n this.connection.baseUrl = url;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /** Starts the connection.\r\n *\r\n * @returns {Promise} A Promise that resolves when the connection has been successfully established, or rejects with an error.\r\n */\r\n HubConnection.prototype.start = function () {\r\n this.startPromise = this.startWithStateTransitions();\r\n return this.startPromise;\r\n };\r\n HubConnection.prototype.startWithStateTransitions = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var e_1;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (this.connectionState !== HubConnectionState.Disconnected) {\r\n return [2 /*return*/, Promise.reject(new Error(\"Cannot start a HubConnection that is not in the 'Disconnected' state.\"))];\r\n }\r\n this.connectionState = HubConnectionState.Connecting;\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Starting HubConnection.\");\r\n _a.label = 1;\r\n case 1:\r\n _a.trys.push([1, 3, , 4]);\r\n return [4 /*yield*/, this.startInternal()];\r\n case 2:\r\n _a.sent();\r\n this.connectionState = HubConnectionState.Connected;\r\n this.connectionStarted = true;\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"HubConnection connected successfully.\");\r\n return [3 /*break*/, 4];\r\n case 3:\r\n e_1 = _a.sent();\r\n this.connectionState = HubConnectionState.Disconnected;\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"HubConnection failed to start successfully because of error '\" + e_1 + \"'.\");\r\n return [2 /*return*/, Promise.reject(e_1)];\r\n case 4: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HubConnection.prototype.startInternal = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var handshakePromise, handshakeRequest, e_2;\r\n var _this = this;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n this.stopDuringStartError = undefined;\r\n this.receivedHandshakeResponse = false;\r\n handshakePromise = new Promise(function (resolve, reject) {\r\n _this.handshakeResolver = resolve;\r\n _this.handshakeRejecter = reject;\r\n });\r\n return [4 /*yield*/, this.connection.start(this.protocol.transferFormat)];\r\n case 1:\r\n _a.sent();\r\n _a.label = 2;\r\n case 2:\r\n _a.trys.push([2, 5, , 7]);\r\n handshakeRequest = {\r\n protocol: this.protocol.name,\r\n version: this.protocol.version,\r\n };\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Sending handshake request.\");\r\n return [4 /*yield*/, this.sendMessage(this.handshakeProtocol.writeHandshakeRequest(handshakeRequest))];\r\n case 3:\r\n _a.sent();\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Using HubProtocol '\" + this.protocol.name + \"'.\");\r\n // defensively cleanup timeout in case we receive a message from the server before we finish start\r\n this.cleanupTimeout();\r\n this.resetTimeoutPeriod();\r\n this.resetKeepAliveInterval();\r\n return [4 /*yield*/, handshakePromise];\r\n case 4:\r\n _a.sent();\r\n // It's important to check the stopDuringStartError instead of just relying on the handshakePromise\r\n // being rejected on close, because this continuation can run after both the handshake completed successfully\r\n // and the connection was closed.\r\n if (this.stopDuringStartError) {\r\n // It's important to throw instead of returning a rejected promise, because we don't want to allow any state\r\n // transitions to occur between now and the calling code observing the exceptions. Returning a rejected promise\r\n // will cause the calling continuation to get scheduled to run later.\r\n throw this.stopDuringStartError;\r\n }\r\n return [3 /*break*/, 7];\r\n case 5:\r\n e_2 = _a.sent();\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Hub handshake failed with error '\" + e_2 + \"' during start(). Stopping HubConnection.\");\r\n this.cleanupTimeout();\r\n this.cleanupPingTimer();\r\n // HttpConnection.stop() should not complete until after the onclose callback is invoked.\r\n // This will transition the HubConnection to the disconnected state before HttpConnection.stop() completes.\r\n return [4 /*yield*/, this.connection.stop(e_2)];\r\n case 6:\r\n // HttpConnection.stop() should not complete until after the onclose callback is invoked.\r\n // This will transition the HubConnection to the disconnected state before HttpConnection.stop() completes.\r\n _a.sent();\r\n throw e_2;\r\n case 7: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n /** Stops the connection.\r\n *\r\n * @returns {Promise} A Promise that resolves when the connection has been successfully terminated, or rejects with an error.\r\n */\r\n HubConnection.prototype.stop = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var startPromise, e_3;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n startPromise = this.startPromise;\r\n this.stopPromise = this.stopInternal();\r\n return [4 /*yield*/, this.stopPromise];\r\n case 1:\r\n _a.sent();\r\n _a.label = 2;\r\n case 2:\r\n _a.trys.push([2, 4, , 5]);\r\n // Awaiting undefined continues immediately\r\n return [4 /*yield*/, startPromise];\r\n case 3:\r\n // Awaiting undefined continues immediately\r\n _a.sent();\r\n return [3 /*break*/, 5];\r\n case 4:\r\n e_3 = _a.sent();\r\n return [3 /*break*/, 5];\r\n case 5: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HubConnection.prototype.stopInternal = function (error) {\r\n if (this.connectionState === HubConnectionState.Disconnected) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Call to HubConnection.stop(\" + error + \") ignored because it is already in the disconnected state.\");\r\n return Promise.resolve();\r\n }\r\n if (this.connectionState === HubConnectionState.Disconnecting) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Call to HttpConnection.stop(\" + error + \") ignored because the connection is already in the disconnecting state.\");\r\n return this.stopPromise;\r\n }\r\n this.connectionState = HubConnectionState.Disconnecting;\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Stopping HubConnection.\");\r\n if (this.reconnectDelayHandle) {\r\n // We're in a reconnect delay which means the underlying connection is currently already stopped.\r\n // Just clear the handle to stop the reconnect loop (which no one is waiting on thankfully) and\r\n // fire the onclose callbacks.\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Connection stopped during reconnect delay. Done reconnecting.\");\r\n clearTimeout(this.reconnectDelayHandle);\r\n this.reconnectDelayHandle = undefined;\r\n this.completeClose();\r\n return Promise.resolve();\r\n }\r\n this.cleanupTimeout();\r\n this.cleanupPingTimer();\r\n this.stopDuringStartError = error || new Error(\"The connection was stopped before the hub handshake could complete.\");\r\n // HttpConnection.stop() should not complete until after either HttpConnection.start() fails\r\n // or the onclose callback is invoked. The onclose callback will transition the HubConnection\r\n // to the disconnected state if need be before HttpConnection.stop() completes.\r\n return this.connection.stop(error);\r\n };\r\n /** Invokes a streaming hub method on the server using the specified name and arguments.\r\n *\r\n * @typeparam T The type of the items returned by the server.\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {IStreamResult} An object that yields results from the server as they are received.\r\n */\r\n HubConnection.prototype.stream = function (methodName) {\r\n var _this = this;\r\n var args = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n args[_i - 1] = arguments[_i];\r\n }\r\n var _a = this.replaceStreamingParams(args), streams = _a[0], streamIds = _a[1];\r\n var invocationDescriptor = this.createStreamInvocation(methodName, args, streamIds);\r\n var promiseQueue;\r\n var subject = new Subject_1.Subject();\r\n subject.cancelCallback = function () {\r\n var cancelInvocation = _this.createCancelInvocation(invocationDescriptor.invocationId);\r\n delete _this.callbacks[invocationDescriptor.invocationId];\r\n return promiseQueue.then(function () {\r\n return _this.sendWithProtocol(cancelInvocation);\r\n });\r\n };\r\n this.callbacks[invocationDescriptor.invocationId] = function (invocationEvent, error) {\r\n if (error) {\r\n subject.error(error);\r\n return;\r\n }\r\n else if (invocationEvent) {\r\n // invocationEvent will not be null when an error is not passed to the callback\r\n if (invocationEvent.type === IHubProtocol_1.MessageType.Completion) {\r\n if (invocationEvent.error) {\r\n subject.error(new Error(invocationEvent.error));\r\n }\r\n else {\r\n subject.complete();\r\n }\r\n }\r\n else {\r\n subject.next((invocationEvent.item));\r\n }\r\n }\r\n };\r\n promiseQueue = this.sendWithProtocol(invocationDescriptor)\r\n .catch(function (e) {\r\n subject.error(e);\r\n delete _this.callbacks[invocationDescriptor.invocationId];\r\n });\r\n this.launchStreams(streams, promiseQueue);\r\n return subject;\r\n };\r\n HubConnection.prototype.sendMessage = function (message) {\r\n this.resetKeepAliveInterval();\r\n return this.connection.send(message);\r\n };\r\n /**\r\n * Sends a js object to the server.\r\n * @param message The js object to serialize and send.\r\n */\r\n HubConnection.prototype.sendWithProtocol = function (message) {\r\n return this.sendMessage(this.protocol.writeMessage(message));\r\n };\r\n /** Invokes a hub method on the server using the specified name and arguments. Does not wait for a response from the receiver.\r\n *\r\n * The Promise returned by this method resolves when the client has sent the invocation to the server. The server may still\r\n * be processing the invocation.\r\n *\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {Promise} A Promise that resolves when the invocation has been successfully sent, or rejects with an error.\r\n */\r\n HubConnection.prototype.send = function (methodName) {\r\n var args = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n args[_i - 1] = arguments[_i];\r\n }\r\n var _a = this.replaceStreamingParams(args), streams = _a[0], streamIds = _a[1];\r\n var sendPromise = this.sendWithProtocol(this.createInvocation(methodName, args, true, streamIds));\r\n this.launchStreams(streams, sendPromise);\r\n return sendPromise;\r\n };\r\n /** Invokes a hub method on the server using the specified name and arguments.\r\n *\r\n * The Promise returned by this method resolves when the server indicates it has finished invoking the method. When the promise\r\n * resolves, the server has finished invoking the method. If the server method returns a result, it is produced as the result of\r\n * resolving the Promise.\r\n *\r\n * @typeparam T The expected return type.\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {Promise} A Promise that resolves with the result of the server method (if any), or rejects with an error.\r\n */\r\n HubConnection.prototype.invoke = function (methodName) {\r\n var _this = this;\r\n var args = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n args[_i - 1] = arguments[_i];\r\n }\r\n var _a = this.replaceStreamingParams(args), streams = _a[0], streamIds = _a[1];\r\n var invocationDescriptor = this.createInvocation(methodName, args, false, streamIds);\r\n var p = new Promise(function (resolve, reject) {\r\n // invocationId will always have a value for a non-blocking invocation\r\n _this.callbacks[invocationDescriptor.invocationId] = function (invocationEvent, error) {\r\n if (error) {\r\n reject(error);\r\n return;\r\n }\r\n else if (invocationEvent) {\r\n // invocationEvent will not be null when an error is not passed to the callback\r\n if (invocationEvent.type === IHubProtocol_1.MessageType.Completion) {\r\n if (invocationEvent.error) {\r\n reject(new Error(invocationEvent.error));\r\n }\r\n else {\r\n resolve(invocationEvent.result);\r\n }\r\n }\r\n else {\r\n reject(new Error(\"Unexpected message type: \" + invocationEvent.type));\r\n }\r\n }\r\n };\r\n var promiseQueue = _this.sendWithProtocol(invocationDescriptor)\r\n .catch(function (e) {\r\n reject(e);\r\n // invocationId will always have a value for a non-blocking invocation\r\n delete _this.callbacks[invocationDescriptor.invocationId];\r\n });\r\n _this.launchStreams(streams, promiseQueue);\r\n });\r\n return p;\r\n };\r\n /** Registers a handler that will be invoked when the hub method with the specified method name is invoked.\r\n *\r\n * @param {string} methodName The name of the hub method to define.\r\n * @param {Function} newMethod The handler that will be raised when the hub method is invoked.\r\n */\r\n HubConnection.prototype.on = function (methodName, newMethod) {\r\n if (!methodName || !newMethod) {\r\n return;\r\n }\r\n methodName = methodName.toLowerCase();\r\n if (!this.methods[methodName]) {\r\n this.methods[methodName] = [];\r\n }\r\n // Preventing adding the same handler multiple times.\r\n if (this.methods[methodName].indexOf(newMethod) !== -1) {\r\n return;\r\n }\r\n this.methods[methodName].push(newMethod);\r\n };\r\n HubConnection.prototype.off = function (methodName, method) {\r\n if (!methodName) {\r\n return;\r\n }\r\n methodName = methodName.toLowerCase();\r\n var handlers = this.methods[methodName];\r\n if (!handlers) {\r\n return;\r\n }\r\n if (method) {\r\n var removeIdx = handlers.indexOf(method);\r\n if (removeIdx !== -1) {\r\n handlers.splice(removeIdx, 1);\r\n if (handlers.length === 0) {\r\n delete this.methods[methodName];\r\n }\r\n }\r\n }\r\n else {\r\n delete this.methods[methodName];\r\n }\r\n };\r\n /** Registers a handler that will be invoked when the connection is closed.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection is closed. Optionally receives a single argument containing the error that caused the connection to close (if any).\r\n */\r\n HubConnection.prototype.onclose = function (callback) {\r\n if (callback) {\r\n this.closedCallbacks.push(callback);\r\n }\r\n };\r\n /** Registers a handler that will be invoked when the connection starts reconnecting.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection starts reconnecting. Optionally receives a single argument containing the error that caused the connection to start reconnecting (if any).\r\n */\r\n HubConnection.prototype.onreconnecting = function (callback) {\r\n if (callback) {\r\n this.reconnectingCallbacks.push(callback);\r\n }\r\n };\r\n /** Registers a handler that will be invoked when the connection successfully reconnects.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection successfully reconnects.\r\n */\r\n HubConnection.prototype.onreconnected = function (callback) {\r\n if (callback) {\r\n this.reconnectedCallbacks.push(callback);\r\n }\r\n };\r\n HubConnection.prototype.processIncomingData = function (data) {\r\n this.cleanupTimeout();\r\n if (!this.receivedHandshakeResponse) {\r\n data = this.processHandshakeResponse(data);\r\n this.receivedHandshakeResponse = true;\r\n }\r\n // Data may have all been read when processing handshake response\r\n if (data) {\r\n // Parse the messages\r\n var messages = this.protocol.parseMessages(data, this.logger);\r\n for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) {\r\n var message = messages_1[_i];\r\n switch (message.type) {\r\n case IHubProtocol_1.MessageType.Invocation:\r\n this.invokeClientMethod(message);\r\n break;\r\n case IHubProtocol_1.MessageType.StreamItem:\r\n case IHubProtocol_1.MessageType.Completion:\r\n var callback = this.callbacks[message.invocationId];\r\n if (callback) {\r\n if (message.type === IHubProtocol_1.MessageType.Completion) {\r\n delete this.callbacks[message.invocationId];\r\n }\r\n callback(message);\r\n }\r\n break;\r\n case IHubProtocol_1.MessageType.Ping:\r\n // Don't care about pings\r\n break;\r\n case IHubProtocol_1.MessageType.Close:\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Close message received from server.\");\r\n var error = message.error ? new Error(\"Server returned an error on close: \" + message.error) : undefined;\r\n if (message.allowReconnect === true) {\r\n // It feels wrong not to await connection.stop() here, but processIncomingData is called as part of an onreceive callback which is not async,\r\n // this is already the behavior for serverTimeout(), and HttpConnection.Stop() should catch and log all possible exceptions.\r\n // tslint:disable-next-line:no-floating-promises\r\n this.connection.stop(error);\r\n }\r\n else {\r\n // We cannot await stopInternal() here, but subsequent calls to stop() will await this if stopInternal() is still ongoing.\r\n this.stopPromise = this.stopInternal(error);\r\n }\r\n break;\r\n default:\r\n this.logger.log(ILogger_1.LogLevel.Warning, \"Invalid message type: \" + message.type + \".\");\r\n break;\r\n }\r\n }\r\n }\r\n this.resetTimeoutPeriod();\r\n };\r\n HubConnection.prototype.processHandshakeResponse = function (data) {\r\n var _a;\r\n var responseMessage;\r\n var remainingData;\r\n try {\r\n _a = this.handshakeProtocol.parseHandshakeResponse(data), remainingData = _a[0], responseMessage = _a[1];\r\n }\r\n catch (e) {\r\n var message = \"Error parsing handshake response: \" + e;\r\n this.logger.log(ILogger_1.LogLevel.Error, message);\r\n var error = new Error(message);\r\n this.handshakeRejecter(error);\r\n throw error;\r\n }\r\n if (responseMessage.error) {\r\n var message = \"Server returned handshake error: \" + responseMessage.error;\r\n this.logger.log(ILogger_1.LogLevel.Error, message);\r\n var error = new Error(message);\r\n this.handshakeRejecter(error);\r\n throw error;\r\n }\r\n else {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Server handshake complete.\");\r\n }\r\n this.handshakeResolver();\r\n return remainingData;\r\n };\r\n HubConnection.prototype.resetKeepAliveInterval = function () {\r\n var _this = this;\r\n if (this.connection.features.inherentKeepAlive) {\r\n return;\r\n }\r\n this.cleanupPingTimer();\r\n this.pingServerHandle = setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {\r\n var _a;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0:\r\n if (!(this.connectionState === HubConnectionState.Connected)) return [3 /*break*/, 4];\r\n _b.label = 1;\r\n case 1:\r\n _b.trys.push([1, 3, , 4]);\r\n return [4 /*yield*/, this.sendMessage(this.cachedPingMessage)];\r\n case 2:\r\n _b.sent();\r\n return [3 /*break*/, 4];\r\n case 3:\r\n _a = _b.sent();\r\n // We don't care about the error. It should be seen elsewhere in the client.\r\n // The connection is probably in a bad or closed state now, cleanup the timer so it stops triggering\r\n this.cleanupPingTimer();\r\n return [3 /*break*/, 4];\r\n case 4: return [2 /*return*/];\r\n }\r\n });\r\n }); }, this.keepAliveIntervalInMilliseconds);\r\n };\r\n HubConnection.prototype.resetTimeoutPeriod = function () {\r\n var _this = this;\r\n if (!this.connection.features || !this.connection.features.inherentKeepAlive) {\r\n // Set the timeout timer\r\n this.timeoutHandle = setTimeout(function () { return _this.serverTimeout(); }, this.serverTimeoutInMilliseconds);\r\n }\r\n };\r\n HubConnection.prototype.serverTimeout = function () {\r\n // The server hasn't talked to us in a while. It doesn't like us anymore ... :(\r\n // Terminate the connection, but we don't need to wait on the promise. This could trigger reconnecting.\r\n // tslint:disable-next-line:no-floating-promises\r\n this.connection.stop(new Error(\"Server timeout elapsed without receiving a message from the server.\"));\r\n };\r\n HubConnection.prototype.invokeClientMethod = function (invocationMessage) {\r\n var _this = this;\r\n var methods = this.methods[invocationMessage.target.toLowerCase()];\r\n if (methods) {\r\n try {\r\n methods.forEach(function (m) { return m.apply(_this, invocationMessage.arguments); });\r\n }\r\n catch (e) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"A callback for the method \" + invocationMessage.target.toLowerCase() + \" threw error '\" + e + \"'.\");\r\n }\r\n if (invocationMessage.invocationId) {\r\n // This is not supported in v1. So we return an error to avoid blocking the server waiting for the response.\r\n var message = \"Server requested a response, which is not supported in this version of the client.\";\r\n this.logger.log(ILogger_1.LogLevel.Error, message);\r\n // We don't want to wait on the stop itself.\r\n this.stopPromise = this.stopInternal(new Error(message));\r\n }\r\n }\r\n else {\r\n this.logger.log(ILogger_1.LogLevel.Warning, \"No client method with the name '\" + invocationMessage.target + \"' found.\");\r\n }\r\n };\r\n HubConnection.prototype.connectionClosed = function (error) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"HubConnection.connectionClosed(\" + error + \") called while in state \" + this.connectionState + \".\");\r\n // Triggering this.handshakeRejecter is insufficient because it could already be resolved without the continuation having run yet.\r\n this.stopDuringStartError = this.stopDuringStartError || error || new Error(\"The underlying connection was closed before the hub handshake could complete.\");\r\n // If the handshake is in progress, start will be waiting for the handshake promise, so we complete it.\r\n // If it has already completed, this should just noop.\r\n if (this.handshakeResolver) {\r\n this.handshakeResolver();\r\n }\r\n this.cancelCallbacksWithError(error || new Error(\"Invocation canceled due to the underlying connection being closed.\"));\r\n this.cleanupTimeout();\r\n this.cleanupPingTimer();\r\n if (this.connectionState === HubConnectionState.Disconnecting) {\r\n this.completeClose(error);\r\n }\r\n else if (this.connectionState === HubConnectionState.Connected && this.reconnectPolicy) {\r\n // tslint:disable-next-line:no-floating-promises\r\n this.reconnect(error);\r\n }\r\n else if (this.connectionState === HubConnectionState.Connected) {\r\n this.completeClose(error);\r\n }\r\n // If none of the above if conditions were true were called the HubConnection must be in either:\r\n // 1. The Connecting state in which case the handshakeResolver will complete it and stopDuringStartError will fail it.\r\n // 2. The Reconnecting state in which case the handshakeResolver will complete it and stopDuringStartError will fail the current reconnect attempt\r\n // and potentially continue the reconnect() loop.\r\n // 3. The Disconnected state in which case we're already done.\r\n };\r\n HubConnection.prototype.completeClose = function (error) {\r\n var _this = this;\r\n if (this.connectionStarted) {\r\n this.connectionState = HubConnectionState.Disconnected;\r\n this.connectionStarted = false;\r\n try {\r\n this.closedCallbacks.forEach(function (c) { return c.apply(_this, [error]); });\r\n }\r\n catch (e) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"An onclose callback called with error '\" + error + \"' threw error '\" + e + \"'.\");\r\n }\r\n }\r\n };\r\n HubConnection.prototype.reconnect = function (error) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var reconnectStartTime, previousReconnectAttempts, retryError, nextRetryDelay, e_4;\r\n var _this = this;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n reconnectStartTime = Date.now();\r\n previousReconnectAttempts = 0;\r\n retryError = error !== undefined ? error : new Error(\"Attempting to reconnect due to a unknown error.\");\r\n nextRetryDelay = this.getNextRetryDelay(previousReconnectAttempts++, 0, retryError);\r\n if (nextRetryDelay === null) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt.\");\r\n this.completeClose(error);\r\n return [2 /*return*/];\r\n }\r\n this.connectionState = HubConnectionState.Reconnecting;\r\n if (error) {\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Connection reconnecting because of error '\" + error + \"'.\");\r\n }\r\n else {\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Connection reconnecting.\");\r\n }\r\n if (this.onreconnecting) {\r\n try {\r\n this.reconnectingCallbacks.forEach(function (c) { return c.apply(_this, [error]); });\r\n }\r\n catch (e) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"An onreconnecting callback called with error '\" + error + \"' threw error '\" + e + \"'.\");\r\n }\r\n // Exit early if an onreconnecting callback called connection.stop().\r\n if (this.connectionState !== HubConnectionState.Reconnecting) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Connection left the reconnecting state in onreconnecting callback. Done reconnecting.\");\r\n return [2 /*return*/];\r\n }\r\n }\r\n _a.label = 1;\r\n case 1:\r\n if (!(nextRetryDelay !== null)) return [3 /*break*/, 7];\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Reconnect attempt number \" + previousReconnectAttempts + \" will start in \" + nextRetryDelay + \" ms.\");\r\n return [4 /*yield*/, new Promise(function (resolve) {\r\n _this.reconnectDelayHandle = setTimeout(resolve, nextRetryDelay);\r\n })];\r\n case 2:\r\n _a.sent();\r\n this.reconnectDelayHandle = undefined;\r\n if (this.connectionState !== HubConnectionState.Reconnecting) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Connection left the reconnecting state during reconnect delay. Done reconnecting.\");\r\n return [2 /*return*/];\r\n }\r\n _a.label = 3;\r\n case 3:\r\n _a.trys.push([3, 5, , 6]);\r\n return [4 /*yield*/, this.startInternal()];\r\n case 4:\r\n _a.sent();\r\n this.connectionState = HubConnectionState.Connected;\r\n this.logger.log(ILogger_1.LogLevel.Information, \"HubConnection reconnected successfully.\");\r\n if (this.onreconnected) {\r\n try {\r\n this.reconnectedCallbacks.forEach(function (c) { return c.apply(_this, [_this.connection.connectionId]); });\r\n }\r\n catch (e) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"An onreconnected callback called with connectionId '\" + this.connection.connectionId + \"; threw error '\" + e + \"'.\");\r\n }\r\n }\r\n return [2 /*return*/];\r\n case 5:\r\n e_4 = _a.sent();\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Reconnect attempt failed because of error '\" + e_4 + \"'.\");\r\n if (this.connectionState !== HubConnectionState.Reconnecting) {\r\n this.logger.log(ILogger_1.LogLevel.Debug, \"Connection left the reconnecting state during reconnect attempt. Done reconnecting.\");\r\n return [2 /*return*/];\r\n }\r\n retryError = e_4 instanceof Error ? e_4 : new Error(e_4.toString());\r\n nextRetryDelay = this.getNextRetryDelay(previousReconnectAttempts++, Date.now() - reconnectStartTime, retryError);\r\n return [3 /*break*/, 6];\r\n case 6: return [3 /*break*/, 1];\r\n case 7:\r\n this.logger.log(ILogger_1.LogLevel.Information, \"Reconnect retries have been exhausted after \" + (Date.now() - reconnectStartTime) + \" ms and \" + previousReconnectAttempts + \" failed attempts. Connection disconnecting.\");\r\n this.completeClose();\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n HubConnection.prototype.getNextRetryDelay = function (previousRetryCount, elapsedMilliseconds, retryReason) {\r\n try {\r\n return this.reconnectPolicy.nextRetryDelayInMilliseconds({\r\n elapsedMilliseconds: elapsedMilliseconds,\r\n previousRetryCount: previousRetryCount,\r\n retryReason: retryReason,\r\n });\r\n }\r\n catch (e) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"IRetryPolicy.nextRetryDelayInMilliseconds(\" + previousRetryCount + \", \" + elapsedMilliseconds + \") threw error '\" + e + \"'.\");\r\n return null;\r\n }\r\n };\r\n HubConnection.prototype.cancelCallbacksWithError = function (error) {\r\n var callbacks = this.callbacks;\r\n this.callbacks = {};\r\n Object.keys(callbacks)\r\n .forEach(function (key) {\r\n var callback = callbacks[key];\r\n callback(null, error);\r\n });\r\n };\r\n HubConnection.prototype.cleanupPingTimer = function () {\r\n if (this.pingServerHandle) {\r\n clearTimeout(this.pingServerHandle);\r\n }\r\n };\r\n HubConnection.prototype.cleanupTimeout = function () {\r\n if (this.timeoutHandle) {\r\n clearTimeout(this.timeoutHandle);\r\n }\r\n };\r\n HubConnection.prototype.createInvocation = function (methodName, args, nonblocking, streamIds) {\r\n if (nonblocking) {\r\n if (streamIds.length !== 0) {\r\n return {\r\n arguments: args,\r\n streamIds: streamIds,\r\n target: methodName,\r\n type: IHubProtocol_1.MessageType.Invocation,\r\n };\r\n }\r\n else {\r\n return {\r\n arguments: args,\r\n target: methodName,\r\n type: IHubProtocol_1.MessageType.Invocation,\r\n };\r\n }\r\n }\r\n else {\r\n var invocationId = this.invocationId;\r\n this.invocationId++;\r\n if (streamIds.length !== 0) {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n streamIds: streamIds,\r\n target: methodName,\r\n type: IHubProtocol_1.MessageType.Invocation,\r\n };\r\n }\r\n else {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n target: methodName,\r\n type: IHubProtocol_1.MessageType.Invocation,\r\n };\r\n }\r\n }\r\n };\r\n HubConnection.prototype.launchStreams = function (streams, promiseQueue) {\r\n var _this = this;\r\n if (streams.length === 0) {\r\n return;\r\n }\r\n // Synchronize stream data so they arrive in-order on the server\r\n if (!promiseQueue) {\r\n promiseQueue = Promise.resolve();\r\n }\r\n var _loop_1 = function (streamId) {\r\n streams[streamId].subscribe({\r\n complete: function () {\r\n promiseQueue = promiseQueue.then(function () { return _this.sendWithProtocol(_this.createCompletionMessage(streamId)); });\r\n },\r\n error: function (err) {\r\n var message;\r\n if (err instanceof Error) {\r\n message = err.message;\r\n }\r\n else if (err && err.toString) {\r\n message = err.toString();\r\n }\r\n else {\r\n message = \"Unknown error\";\r\n }\r\n promiseQueue = promiseQueue.then(function () { return _this.sendWithProtocol(_this.createCompletionMessage(streamId, message)); });\r\n },\r\n next: function (item) {\r\n promiseQueue = promiseQueue.then(function () { return _this.sendWithProtocol(_this.createStreamItemMessage(streamId, item)); });\r\n },\r\n });\r\n };\r\n // We want to iterate over the keys, since the keys are the stream ids\r\n // tslint:disable-next-line:forin\r\n for (var streamId in streams) {\r\n _loop_1(streamId);\r\n }\r\n };\r\n HubConnection.prototype.replaceStreamingParams = function (args) {\r\n var streams = [];\r\n var streamIds = [];\r\n for (var i = 0; i < args.length; i++) {\r\n var argument = args[i];\r\n if (this.isObservable(argument)) {\r\n var streamId = this.invocationId;\r\n this.invocationId++;\r\n // Store the stream for later use\r\n streams[streamId] = argument;\r\n streamIds.push(streamId.toString());\r\n // remove stream from args\r\n args.splice(i, 1);\r\n }\r\n }\r\n return [streams, streamIds];\r\n };\r\n HubConnection.prototype.isObservable = function (arg) {\r\n // This allows other stream implementations to just work (like rxjs)\r\n return arg && arg.subscribe && typeof arg.subscribe === \"function\";\r\n };\r\n HubConnection.prototype.createStreamInvocation = function (methodName, args, streamIds) {\r\n var invocationId = this.invocationId;\r\n this.invocationId++;\r\n if (streamIds.length !== 0) {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n streamIds: streamIds,\r\n target: methodName,\r\n type: IHubProtocol_1.MessageType.StreamInvocation,\r\n };\r\n }\r\n else {\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n target: methodName,\r\n type: IHubProtocol_1.MessageType.StreamInvocation,\r\n };\r\n }\r\n };\r\n HubConnection.prototype.createCancelInvocation = function (id) {\r\n return {\r\n invocationId: id,\r\n type: IHubProtocol_1.MessageType.CancelInvocation,\r\n };\r\n };\r\n HubConnection.prototype.createStreamItemMessage = function (id, item) {\r\n return {\r\n invocationId: id,\r\n item: item,\r\n type: IHubProtocol_1.MessageType.StreamItem,\r\n };\r\n };\r\n HubConnection.prototype.createCompletionMessage = function (id, error, result) {\r\n if (error) {\r\n return {\r\n error: error,\r\n invocationId: id,\r\n type: IHubProtocol_1.MessageType.Completion,\r\n };\r\n }\r\n return {\r\n invocationId: id,\r\n result: result,\r\n type: IHubProtocol_1.MessageType.Completion,\r\n };\r\n };\r\n return HubConnection;\r\n}());\r\nexports.HubConnection = HubConnection;\r\n//# sourceMappingURL=HubConnection.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar DefaultReconnectPolicy_1 = require(\"./DefaultReconnectPolicy\");\r\nvar HttpConnection_1 = require(\"./HttpConnection\");\r\nvar HubConnection_1 = require(\"./HubConnection\");\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar JsonHubProtocol_1 = require(\"./JsonHubProtocol\");\r\nvar Loggers_1 = require(\"./Loggers\");\r\nvar Utils_1 = require(\"./Utils\");\r\n// tslint:disable:object-literal-sort-keys\r\nvar LogLevelNameMapping = {\r\n trace: ILogger_1.LogLevel.Trace,\r\n debug: ILogger_1.LogLevel.Debug,\r\n info: ILogger_1.LogLevel.Information,\r\n information: ILogger_1.LogLevel.Information,\r\n warn: ILogger_1.LogLevel.Warning,\r\n warning: ILogger_1.LogLevel.Warning,\r\n error: ILogger_1.LogLevel.Error,\r\n critical: ILogger_1.LogLevel.Critical,\r\n none: ILogger_1.LogLevel.None,\r\n};\r\nfunction parseLogLevel(name) {\r\n // Case-insensitive matching via lower-casing\r\n // Yes, I know case-folding is a complicated problem in Unicode, but we only support\r\n // the ASCII strings defined in LogLevelNameMapping anyway, so it's fine -anurse.\r\n var mapping = LogLevelNameMapping[name.toLowerCase()];\r\n if (typeof mapping !== \"undefined\") {\r\n return mapping;\r\n }\r\n else {\r\n throw new Error(\"Unknown log level: \" + name);\r\n }\r\n}\r\n/** A builder for configuring {@link @microsoft/signalr.HubConnection} instances. */\r\nvar HubConnectionBuilder = /** @class */ (function () {\r\n function HubConnectionBuilder() {\r\n }\r\n HubConnectionBuilder.prototype.configureLogging = function (logging) {\r\n Utils_1.Arg.isRequired(logging, \"logging\");\r\n if (isLogger(logging)) {\r\n this.logger = logging;\r\n }\r\n else if (typeof logging === \"string\") {\r\n var logLevel = parseLogLevel(logging);\r\n this.logger = new Utils_1.ConsoleLogger(logLevel);\r\n }\r\n else {\r\n this.logger = new Utils_1.ConsoleLogger(logging);\r\n }\r\n return this;\r\n };\r\n HubConnectionBuilder.prototype.withUrl = function (url, transportTypeOrOptions) {\r\n Utils_1.Arg.isRequired(url, \"url\");\r\n Utils_1.Arg.isNotEmpty(url, \"url\");\r\n this.url = url;\r\n // Flow-typing knows where it's at. Since HttpTransportType is a number and IHttpConnectionOptions is guaranteed\r\n // to be an object, we know (as does TypeScript) this comparison is all we need to figure out which overload was called.\r\n if (typeof transportTypeOrOptions === \"object\") {\r\n this.httpConnectionOptions = __assign({}, this.httpConnectionOptions, transportTypeOrOptions);\r\n }\r\n else {\r\n this.httpConnectionOptions = __assign({}, this.httpConnectionOptions, { transport: transportTypeOrOptions });\r\n }\r\n return this;\r\n };\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to use the specified Hub Protocol.\r\n *\r\n * @param {IHubProtocol} protocol The {@link @microsoft/signalr.IHubProtocol} implementation to use.\r\n */\r\n HubConnectionBuilder.prototype.withHubProtocol = function (protocol) {\r\n Utils_1.Arg.isRequired(protocol, \"protocol\");\r\n this.protocol = protocol;\r\n return this;\r\n };\r\n HubConnectionBuilder.prototype.withAutomaticReconnect = function (retryDelaysOrReconnectPolicy) {\r\n if (this.reconnectPolicy) {\r\n throw new Error(\"A reconnectPolicy has already been set.\");\r\n }\r\n if (!retryDelaysOrReconnectPolicy) {\r\n this.reconnectPolicy = new DefaultReconnectPolicy_1.DefaultReconnectPolicy();\r\n }\r\n else if (Array.isArray(retryDelaysOrReconnectPolicy)) {\r\n this.reconnectPolicy = new DefaultReconnectPolicy_1.DefaultReconnectPolicy(retryDelaysOrReconnectPolicy);\r\n }\r\n else {\r\n this.reconnectPolicy = retryDelaysOrReconnectPolicy;\r\n }\r\n return this;\r\n };\r\n /** Creates a {@link @microsoft/signalr.HubConnection} from the configuration options specified in this builder.\r\n *\r\n * @returns {HubConnection} The configured {@link @microsoft/signalr.HubConnection}.\r\n */\r\n HubConnectionBuilder.prototype.build = function () {\r\n // If httpConnectionOptions has a logger, use it. Otherwise, override it with the one\r\n // provided to configureLogger\r\n var httpConnectionOptions = this.httpConnectionOptions || {};\r\n // If it's 'null', the user **explicitly** asked for null, don't mess with it.\r\n if (httpConnectionOptions.logger === undefined) {\r\n // If our logger is undefined or null, that's OK, the HttpConnection constructor will handle it.\r\n httpConnectionOptions.logger = this.logger;\r\n }\r\n // Now create the connection\r\n if (!this.url) {\r\n throw new Error(\"The 'HubConnectionBuilder.withUrl' method must be called before building the connection.\");\r\n }\r\n var connection = new HttpConnection_1.HttpConnection(this.url, httpConnectionOptions);\r\n return HubConnection_1.HubConnection.create(connection, this.logger || Loggers_1.NullLogger.instance, this.protocol || new JsonHubProtocol_1.JsonHubProtocol(), this.reconnectPolicy);\r\n };\r\n return HubConnectionBuilder;\r\n}());\r\nexports.HubConnectionBuilder = HubConnectionBuilder;\r\nfunction isLogger(logger) {\r\n return logger.log !== undefined;\r\n}\r\n//# sourceMappingURL=HubConnectionBuilder.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n/** Defines the type of a Hub Message. */\r\nvar MessageType;\r\n(function (MessageType) {\r\n /** Indicates the message is an Invocation message and implements the {@link @microsoft/signalr.InvocationMessage} interface. */\r\n MessageType[MessageType[\"Invocation\"] = 1] = \"Invocation\";\r\n /** Indicates the message is a StreamItem message and implements the {@link @microsoft/signalr.StreamItemMessage} interface. */\r\n MessageType[MessageType[\"StreamItem\"] = 2] = \"StreamItem\";\r\n /** Indicates the message is a Completion message and implements the {@link @microsoft/signalr.CompletionMessage} interface. */\r\n MessageType[MessageType[\"Completion\"] = 3] = \"Completion\";\r\n /** Indicates the message is a Stream Invocation message and implements the {@link @microsoft/signalr.StreamInvocationMessage} interface. */\r\n MessageType[MessageType[\"StreamInvocation\"] = 4] = \"StreamInvocation\";\r\n /** Indicates the message is a Cancel Invocation message and implements the {@link @microsoft/signalr.CancelInvocationMessage} interface. */\r\n MessageType[MessageType[\"CancelInvocation\"] = 5] = \"CancelInvocation\";\r\n /** Indicates the message is a Ping message and implements the {@link @microsoft/signalr.PingMessage} interface. */\r\n MessageType[MessageType[\"Ping\"] = 6] = \"Ping\";\r\n /** Indicates the message is a Close message and implements the {@link @microsoft/signalr.CloseMessage} interface. */\r\n MessageType[MessageType[\"Close\"] = 7] = \"Close\";\r\n})(MessageType = exports.MessageType || (exports.MessageType = {}));\r\n//# sourceMappingURL=IHubProtocol.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n// These values are designed to match the ASP.NET Log Levels since that's the pattern we're emulating here.\r\n/** Indicates the severity of a log message.\r\n *\r\n * Log Levels are ordered in increasing severity. So `Debug` is more severe than `Trace`, etc.\r\n */\r\nvar LogLevel;\r\n(function (LogLevel) {\r\n /** Log level for very low severity diagnostic messages. */\r\n LogLevel[LogLevel[\"Trace\"] = 0] = \"Trace\";\r\n /** Log level for low severity diagnostic messages. */\r\n LogLevel[LogLevel[\"Debug\"] = 1] = \"Debug\";\r\n /** Log level for informational diagnostic messages. */\r\n LogLevel[LogLevel[\"Information\"] = 2] = \"Information\";\r\n /** Log level for diagnostic messages that indicate a non-fatal problem. */\r\n LogLevel[LogLevel[\"Warning\"] = 3] = \"Warning\";\r\n /** Log level for diagnostic messages that indicate a failure in the current operation. */\r\n LogLevel[LogLevel[\"Error\"] = 4] = \"Error\";\r\n /** Log level for diagnostic messages that indicate a failure that will terminate the entire application. */\r\n LogLevel[LogLevel[\"Critical\"] = 5] = \"Critical\";\r\n /** The highest possible log level. Used when configuring logging to indicate that no log messages should be emitted. */\r\n LogLevel[LogLevel[\"None\"] = 6] = \"None\";\r\n})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));\r\n//# sourceMappingURL=ILogger.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n// This will be treated as a bit flag in the future, so we keep it using power-of-two values.\r\n/** Specifies a specific HTTP transport type. */\r\nvar HttpTransportType;\r\n(function (HttpTransportType) {\r\n /** Specifies no transport preference. */\r\n HttpTransportType[HttpTransportType[\"None\"] = 0] = \"None\";\r\n /** Specifies the WebSockets transport. */\r\n HttpTransportType[HttpTransportType[\"WebSockets\"] = 1] = \"WebSockets\";\r\n /** Specifies the Server-Sent Events transport. */\r\n HttpTransportType[HttpTransportType[\"ServerSentEvents\"] = 2] = \"ServerSentEvents\";\r\n /** Specifies the Long Polling transport. */\r\n HttpTransportType[HttpTransportType[\"LongPolling\"] = 4] = \"LongPolling\";\r\n})(HttpTransportType = exports.HttpTransportType || (exports.HttpTransportType = {}));\r\n/** Specifies the transfer format for a connection. */\r\nvar TransferFormat;\r\n(function (TransferFormat) {\r\n /** Specifies that only text data will be transmitted over the connection. */\r\n TransferFormat[TransferFormat[\"Text\"] = 1] = \"Text\";\r\n /** Specifies that binary data will be transmitted over the connection. */\r\n TransferFormat[TransferFormat[\"Binary\"] = 2] = \"Binary\";\r\n})(TransferFormat = exports.TransferFormat || (exports.TransferFormat = {}));\r\n//# sourceMappingURL=ITransport.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar IHubProtocol_1 = require(\"./IHubProtocol\");\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar ITransport_1 = require(\"./ITransport\");\r\nvar Loggers_1 = require(\"./Loggers\");\r\nvar TextMessageFormat_1 = require(\"./TextMessageFormat\");\r\nvar JSON_HUB_PROTOCOL_NAME = \"json\";\r\n/** Implements the JSON Hub Protocol. */\r\nvar JsonHubProtocol = /** @class */ (function () {\r\n function JsonHubProtocol() {\r\n /** @inheritDoc */\r\n this.name = JSON_HUB_PROTOCOL_NAME;\r\n /** @inheritDoc */\r\n this.version = 1;\r\n /** @inheritDoc */\r\n this.transferFormat = ITransport_1.TransferFormat.Text;\r\n }\r\n /** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.\r\n *\r\n * @param {string} input A string containing the serialized representation.\r\n * @param {ILogger} logger A logger that will be used to log messages that occur during parsing.\r\n */\r\n JsonHubProtocol.prototype.parseMessages = function (input, logger) {\r\n // The interface does allow \"ArrayBuffer\" to be passed in, but this implementation does not. So let's throw a useful error.\r\n if (typeof input !== \"string\") {\r\n throw new Error(\"Invalid input for JSON hub protocol. Expected a string.\");\r\n }\r\n if (!input) {\r\n return [];\r\n }\r\n if (logger === null) {\r\n logger = Loggers_1.NullLogger.instance;\r\n }\r\n // Parse the messages\r\n var messages = TextMessageFormat_1.TextMessageFormat.parse(input);\r\n var hubMessages = [];\r\n for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) {\r\n var message = messages_1[_i];\r\n var parsedMessage = JSON.parse(message);\r\n if (typeof parsedMessage.type !== \"number\") {\r\n throw new Error(\"Invalid payload.\");\r\n }\r\n switch (parsedMessage.type) {\r\n case IHubProtocol_1.MessageType.Invocation:\r\n this.isInvocationMessage(parsedMessage);\r\n break;\r\n case IHubProtocol_1.MessageType.StreamItem:\r\n this.isStreamItemMessage(parsedMessage);\r\n break;\r\n case IHubProtocol_1.MessageType.Completion:\r\n this.isCompletionMessage(parsedMessage);\r\n break;\r\n case IHubProtocol_1.MessageType.Ping:\r\n // Single value, no need to validate\r\n break;\r\n case IHubProtocol_1.MessageType.Close:\r\n // All optional values, no need to validate\r\n break;\r\n default:\r\n // Future protocol changes can add message types, old clients can ignore them\r\n logger.log(ILogger_1.LogLevel.Information, \"Unknown message type '\" + parsedMessage.type + \"' ignored.\");\r\n continue;\r\n }\r\n hubMessages.push(parsedMessage);\r\n }\r\n return hubMessages;\r\n };\r\n /** Writes the specified {@link @microsoft/signalr.HubMessage} to a string and returns it.\r\n *\r\n * @param {HubMessage} message The message to write.\r\n * @returns {string} A string containing the serialized representation of the message.\r\n */\r\n JsonHubProtocol.prototype.writeMessage = function (message) {\r\n return TextMessageFormat_1.TextMessageFormat.write(JSON.stringify(message));\r\n };\r\n JsonHubProtocol.prototype.isInvocationMessage = function (message) {\r\n this.assertNotEmptyString(message.target, \"Invalid payload for Invocation message.\");\r\n if (message.invocationId !== undefined) {\r\n this.assertNotEmptyString(message.invocationId, \"Invalid payload for Invocation message.\");\r\n }\r\n };\r\n JsonHubProtocol.prototype.isStreamItemMessage = function (message) {\r\n this.assertNotEmptyString(message.invocationId, \"Invalid payload for StreamItem message.\");\r\n if (message.item === undefined) {\r\n throw new Error(\"Invalid payload for StreamItem message.\");\r\n }\r\n };\r\n JsonHubProtocol.prototype.isCompletionMessage = function (message) {\r\n if (message.result && message.error) {\r\n throw new Error(\"Invalid payload for Completion message.\");\r\n }\r\n if (!message.result && message.error) {\r\n this.assertNotEmptyString(message.error, \"Invalid payload for Completion message.\");\r\n }\r\n this.assertNotEmptyString(message.invocationId, \"Invalid payload for Completion message.\");\r\n };\r\n JsonHubProtocol.prototype.assertNotEmptyString = function (value, errorMessage) {\r\n if (typeof value !== \"string\" || value === \"\") {\r\n throw new Error(errorMessage);\r\n }\r\n };\r\n return JsonHubProtocol;\r\n}());\r\nexports.JsonHubProtocol = JsonHubProtocol;\r\n//# sourceMappingURL=JsonHubProtocol.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n/** A logger that does nothing when log messages are sent to it. */\r\nvar NullLogger = /** @class */ (function () {\r\n function NullLogger() {\r\n }\r\n /** @inheritDoc */\r\n // tslint:disable-next-line\r\n NullLogger.prototype.log = function (_logLevel, _message) {\r\n };\r\n /** The singleton instance of the {@link @microsoft/signalr.NullLogger}. */\r\n NullLogger.instance = new NullLogger();\r\n return NullLogger;\r\n}());\r\nexports.NullLogger = NullLogger;\r\n//# sourceMappingURL=Loggers.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __generator = (this && this.__generator) || function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar AbortController_1 = require(\"./AbortController\");\r\nvar Errors_1 = require(\"./Errors\");\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar ITransport_1 = require(\"./ITransport\");\r\nvar Utils_1 = require(\"./Utils\");\r\n// Not exported from 'index', this type is internal.\r\n/** @private */\r\nvar LongPollingTransport = /** @class */ (function () {\r\n function LongPollingTransport(httpClient, accessTokenFactory, logger, logMessageContent, withCredentials, headers) {\r\n this.httpClient = httpClient;\r\n this.accessTokenFactory = accessTokenFactory;\r\n this.logger = logger;\r\n this.pollAbort = new AbortController_1.AbortController();\r\n this.logMessageContent = logMessageContent;\r\n this.withCredentials = withCredentials;\r\n this.headers = headers;\r\n this.running = false;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n Object.defineProperty(LongPollingTransport.prototype, \"pollAborted\", {\r\n // This is an internal type, not exported from 'index' so this is really just internal.\r\n get: function () {\r\n return this.pollAbort.aborted;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n LongPollingTransport.prototype.connect = function (url, transferFormat) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var _a, _b, name, value, headers, pollOptions, token, pollUrl, response;\r\n return __generator(this, function (_c) {\r\n switch (_c.label) {\r\n case 0:\r\n Utils_1.Arg.isRequired(url, \"url\");\r\n Utils_1.Arg.isRequired(transferFormat, \"transferFormat\");\r\n Utils_1.Arg.isIn(transferFormat, ITransport_1.TransferFormat, \"transferFormat\");\r\n this.url = url;\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) Connecting.\");\r\n // Allow binary format on Node and Browsers that support binary content (indicated by the presence of responseType property)\r\n if (transferFormat === ITransport_1.TransferFormat.Binary &&\r\n (typeof XMLHttpRequest !== \"undefined\" && typeof new XMLHttpRequest().responseType !== \"string\")) {\r\n throw new Error(\"Binary protocols over XmlHttpRequest not implementing advanced features are not supported.\");\r\n }\r\n _b = Utils_1.getUserAgentHeader(), name = _b[0], value = _b[1];\r\n headers = __assign((_a = {}, _a[name] = value, _a), this.headers);\r\n pollOptions = {\r\n abortSignal: this.pollAbort.signal,\r\n headers: headers,\r\n timeout: 100000,\r\n withCredentials: this.withCredentials,\r\n };\r\n if (transferFormat === ITransport_1.TransferFormat.Binary) {\r\n pollOptions.responseType = \"arraybuffer\";\r\n }\r\n return [4 /*yield*/, this.getAccessToken()];\r\n case 1:\r\n token = _c.sent();\r\n this.updateHeaderToken(pollOptions, token);\r\n pollUrl = url + \"&_=\" + Date.now();\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) polling: \" + pollUrl + \".\");\r\n return [4 /*yield*/, this.httpClient.get(pollUrl, pollOptions)];\r\n case 2:\r\n response = _c.sent();\r\n if (response.statusCode !== 200) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"(LongPolling transport) Unexpected response code: \" + response.statusCode + \".\");\r\n // Mark running as false so that the poll immediately ends and runs the close logic\r\n this.closeError = new Errors_1.HttpError(response.statusText || \"\", response.statusCode);\r\n this.running = false;\r\n }\r\n else {\r\n this.running = true;\r\n }\r\n this.receiving = this.poll(this.url, pollOptions);\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n LongPollingTransport.prototype.getAccessToken = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (!this.accessTokenFactory) return [3 /*break*/, 2];\r\n return [4 /*yield*/, this.accessTokenFactory()];\r\n case 1: return [2 /*return*/, _a.sent()];\r\n case 2: return [2 /*return*/, null];\r\n }\r\n });\r\n });\r\n };\r\n LongPollingTransport.prototype.updateHeaderToken = function (request, token) {\r\n if (!request.headers) {\r\n request.headers = {};\r\n }\r\n if (token) {\r\n // tslint:disable-next-line:no-string-literal\r\n request.headers[\"Authorization\"] = \"Bearer \" + token;\r\n return;\r\n }\r\n // tslint:disable-next-line:no-string-literal\r\n if (request.headers[\"Authorization\"]) {\r\n // tslint:disable-next-line:no-string-literal\r\n delete request.headers[\"Authorization\"];\r\n }\r\n };\r\n LongPollingTransport.prototype.poll = function (url, pollOptions) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var token, pollUrl, response, e_1;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n _a.trys.push([0, , 8, 9]);\r\n _a.label = 1;\r\n case 1:\r\n if (!this.running) return [3 /*break*/, 7];\r\n return [4 /*yield*/, this.getAccessToken()];\r\n case 2:\r\n token = _a.sent();\r\n this.updateHeaderToken(pollOptions, token);\r\n _a.label = 3;\r\n case 3:\r\n _a.trys.push([3, 5, , 6]);\r\n pollUrl = url + \"&_=\" + Date.now();\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) polling: \" + pollUrl + \".\");\r\n return [4 /*yield*/, this.httpClient.get(pollUrl, pollOptions)];\r\n case 4:\r\n response = _a.sent();\r\n if (response.statusCode === 204) {\r\n this.logger.log(ILogger_1.LogLevel.Information, \"(LongPolling transport) Poll terminated by server.\");\r\n this.running = false;\r\n }\r\n else if (response.statusCode !== 200) {\r\n this.logger.log(ILogger_1.LogLevel.Error, \"(LongPolling transport) Unexpected response code: \" + response.statusCode + \".\");\r\n // Unexpected status code\r\n this.closeError = new Errors_1.HttpError(response.statusText || \"\", response.statusCode);\r\n this.running = false;\r\n }\r\n else {\r\n // Process the response\r\n if (response.content) {\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) data received. \" + Utils_1.getDataDetail(response.content, this.logMessageContent) + \".\");\r\n if (this.onreceive) {\r\n this.onreceive(response.content);\r\n }\r\n }\r\n else {\r\n // This is another way timeout manifest.\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) Poll timed out, reissuing.\");\r\n }\r\n }\r\n return [3 /*break*/, 6];\r\n case 5:\r\n e_1 = _a.sent();\r\n if (!this.running) {\r\n // Log but disregard errors that occur after stopping\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) Poll errored after shutdown: \" + e_1.message);\r\n }\r\n else {\r\n if (e_1 instanceof Errors_1.TimeoutError) {\r\n // Ignore timeouts and reissue the poll.\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) Poll timed out, reissuing.\");\r\n }\r\n else {\r\n // Close the connection with the error as the result.\r\n this.closeError = e_1;\r\n this.running = false;\r\n }\r\n }\r\n return [3 /*break*/, 6];\r\n case 6: return [3 /*break*/, 1];\r\n case 7: return [3 /*break*/, 9];\r\n case 8:\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) Polling complete.\");\r\n // We will reach here with pollAborted==false when the server returned a response causing the transport to stop.\r\n // If pollAborted==true then client initiated the stop and the stop method will raise the close event after DELETE is sent.\r\n if (!this.pollAborted) {\r\n this.raiseOnClose();\r\n }\r\n return [7 /*endfinally*/];\r\n case 9: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n LongPollingTransport.prototype.send = function (data) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n if (!this.running) {\r\n return [2 /*return*/, Promise.reject(new Error(\"Cannot send until the transport is connected\"))];\r\n }\r\n return [2 /*return*/, Utils_1.sendMessage(this.logger, \"LongPolling\", this.httpClient, this.url, this.accessTokenFactory, data, this.logMessageContent, this.withCredentials, this.headers)];\r\n });\r\n });\r\n };\r\n LongPollingTransport.prototype.stop = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var headers, _a, name_1, value, deleteOptions, token;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0:\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) Stopping polling.\");\r\n // Tell receiving loop to stop, abort any current request, and then wait for it to finish\r\n this.running = false;\r\n this.pollAbort.abort();\r\n _b.label = 1;\r\n case 1:\r\n _b.trys.push([1, , 5, 6]);\r\n return [4 /*yield*/, this.receiving];\r\n case 2:\r\n _b.sent();\r\n // Send DELETE to clean up long polling on the server\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) sending DELETE request to \" + this.url + \".\");\r\n headers = {};\r\n _a = Utils_1.getUserAgentHeader(), name_1 = _a[0], value = _a[1];\r\n headers[name_1] = value;\r\n deleteOptions = {\r\n headers: __assign({}, headers, this.headers),\r\n withCredentials: this.withCredentials,\r\n };\r\n return [4 /*yield*/, this.getAccessToken()];\r\n case 3:\r\n token = _b.sent();\r\n this.updateHeaderToken(deleteOptions, token);\r\n return [4 /*yield*/, this.httpClient.delete(this.url, deleteOptions)];\r\n case 4:\r\n _b.sent();\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) DELETE request sent.\");\r\n return [3 /*break*/, 6];\r\n case 5:\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(LongPolling transport) Stop finished.\");\r\n // Raise close event here instead of in polling\r\n // It needs to happen after the DELETE request is sent\r\n this.raiseOnClose();\r\n return [7 /*endfinally*/];\r\n case 6: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n LongPollingTransport.prototype.raiseOnClose = function () {\r\n if (this.onclose) {\r\n var logMessage = \"(LongPolling transport) Firing onclose event.\";\r\n if (this.closeError) {\r\n logMessage += \" Error: \" + this.closeError;\r\n }\r\n this.logger.log(ILogger_1.LogLevel.Trace, logMessage);\r\n this.onclose(this.closeError);\r\n }\r\n };\r\n return LongPollingTransport;\r\n}());\r\nexports.LongPollingTransport = LongPollingTransport;\r\n//# sourceMappingURL=LongPollingTransport.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __generator = (this && this.__generator) || function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar ITransport_1 = require(\"./ITransport\");\r\nvar Utils_1 = require(\"./Utils\");\r\n/** @private */\r\nvar ServerSentEventsTransport = /** @class */ (function () {\r\n function ServerSentEventsTransport(httpClient, accessTokenFactory, logger, logMessageContent, eventSourceConstructor, withCredentials, headers) {\r\n this.httpClient = httpClient;\r\n this.accessTokenFactory = accessTokenFactory;\r\n this.logger = logger;\r\n this.logMessageContent = logMessageContent;\r\n this.withCredentials = withCredentials;\r\n this.eventSourceConstructor = eventSourceConstructor;\r\n this.headers = headers;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n ServerSentEventsTransport.prototype.connect = function (url, transferFormat) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var token;\r\n var _this = this;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n Utils_1.Arg.isRequired(url, \"url\");\r\n Utils_1.Arg.isRequired(transferFormat, \"transferFormat\");\r\n Utils_1.Arg.isIn(transferFormat, ITransport_1.TransferFormat, \"transferFormat\");\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(SSE transport) Connecting.\");\r\n // set url before accessTokenFactory because this.url is only for send and we set the auth header instead of the query string for send\r\n this.url = url;\r\n if (!this.accessTokenFactory) return [3 /*break*/, 2];\r\n return [4 /*yield*/, this.accessTokenFactory()];\r\n case 1:\r\n token = _a.sent();\r\n if (token) {\r\n url += (url.indexOf(\"?\") < 0 ? \"?\" : \"&\") + (\"access_token=\" + encodeURIComponent(token));\r\n }\r\n _a.label = 2;\r\n case 2: return [2 /*return*/, new Promise(function (resolve, reject) {\r\n var opened = false;\r\n if (transferFormat !== ITransport_1.TransferFormat.Text) {\r\n reject(new Error(\"The Server-Sent Events transport only supports the 'Text' transfer format\"));\r\n return;\r\n }\r\n var eventSource;\r\n if (Utils_1.Platform.isBrowser || Utils_1.Platform.isWebWorker) {\r\n eventSource = new _this.eventSourceConstructor(url, { withCredentials: _this.withCredentials });\r\n }\r\n else {\r\n // Non-browser passes cookies via the dictionary\r\n var cookies = _this.httpClient.getCookieString(url);\r\n var headers = {};\r\n headers.Cookie = cookies;\r\n var _a = Utils_1.getUserAgentHeader(), name_1 = _a[0], value = _a[1];\r\n headers[name_1] = value;\r\n eventSource = new _this.eventSourceConstructor(url, { withCredentials: _this.withCredentials, headers: __assign({}, headers, _this.headers) });\r\n }\r\n try {\r\n eventSource.onmessage = function (e) {\r\n if (_this.onreceive) {\r\n try {\r\n _this.logger.log(ILogger_1.LogLevel.Trace, \"(SSE transport) data received. \" + Utils_1.getDataDetail(e.data, _this.logMessageContent) + \".\");\r\n _this.onreceive(e.data);\r\n }\r\n catch (error) {\r\n _this.close(error);\r\n return;\r\n }\r\n }\r\n };\r\n eventSource.onerror = function (e) {\r\n var error = new Error(e.data || \"Error occurred\");\r\n if (opened) {\r\n _this.close(error);\r\n }\r\n else {\r\n reject(error);\r\n }\r\n };\r\n eventSource.onopen = function () {\r\n _this.logger.log(ILogger_1.LogLevel.Information, \"SSE connected to \" + _this.url);\r\n _this.eventSource = eventSource;\r\n opened = true;\r\n resolve();\r\n };\r\n }\r\n catch (e) {\r\n reject(e);\r\n return;\r\n }\r\n })];\r\n }\r\n });\r\n });\r\n };\r\n ServerSentEventsTransport.prototype.send = function (data) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n if (!this.eventSource) {\r\n return [2 /*return*/, Promise.reject(new Error(\"Cannot send until the transport is connected\"))];\r\n }\r\n return [2 /*return*/, Utils_1.sendMessage(this.logger, \"SSE\", this.httpClient, this.url, this.accessTokenFactory, data, this.logMessageContent, this.withCredentials, this.headers)];\r\n });\r\n });\r\n };\r\n ServerSentEventsTransport.prototype.stop = function () {\r\n this.close();\r\n return Promise.resolve();\r\n };\r\n ServerSentEventsTransport.prototype.close = function (e) {\r\n if (this.eventSource) {\r\n this.eventSource.close();\r\n this.eventSource = undefined;\r\n if (this.onclose) {\r\n this.onclose(e);\r\n }\r\n }\r\n };\r\n return ServerSentEventsTransport;\r\n}());\r\nexports.ServerSentEventsTransport = ServerSentEventsTransport;\r\n//# sourceMappingURL=ServerSentEventsTransport.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar Utils_1 = require(\"./Utils\");\r\n/** Stream implementation to stream items to the server. */\r\nvar Subject = /** @class */ (function () {\r\n function Subject() {\r\n this.observers = [];\r\n }\r\n Subject.prototype.next = function (item) {\r\n for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {\r\n var observer = _a[_i];\r\n observer.next(item);\r\n }\r\n };\r\n Subject.prototype.error = function (err) {\r\n for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {\r\n var observer = _a[_i];\r\n if (observer.error) {\r\n observer.error(err);\r\n }\r\n }\r\n };\r\n Subject.prototype.complete = function () {\r\n for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {\r\n var observer = _a[_i];\r\n if (observer.complete) {\r\n observer.complete();\r\n }\r\n }\r\n };\r\n Subject.prototype.subscribe = function (observer) {\r\n this.observers.push(observer);\r\n return new Utils_1.SubjectSubscription(this, observer);\r\n };\r\n return Subject;\r\n}());\r\nexports.Subject = Subject;\r\n//# sourceMappingURL=Subject.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\n// Not exported from index\r\n/** @private */\r\nvar TextMessageFormat = /** @class */ (function () {\r\n function TextMessageFormat() {\r\n }\r\n TextMessageFormat.write = function (output) {\r\n return \"\" + output + TextMessageFormat.RecordSeparator;\r\n };\r\n TextMessageFormat.parse = function (input) {\r\n if (input[input.length - 1] !== TextMessageFormat.RecordSeparator) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n var messages = input.split(TextMessageFormat.RecordSeparator);\r\n messages.pop();\r\n return messages;\r\n };\r\n TextMessageFormat.RecordSeparatorCode = 0x1e;\r\n TextMessageFormat.RecordSeparator = String.fromCharCode(TextMessageFormat.RecordSeparatorCode);\r\n return TextMessageFormat;\r\n}());\r\nexports.TextMessageFormat = TextMessageFormat;\r\n//# sourceMappingURL=TextMessageFormat.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __generator = (this && this.__generator) || function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar Loggers_1 = require(\"./Loggers\");\r\n// Version token that will be replaced by the prepack command\r\n/** The version of the SignalR client. */\r\nexports.VERSION = \"5.0.4\";\r\n/** @private */\r\nvar Arg = /** @class */ (function () {\r\n function Arg() {\r\n }\r\n Arg.isRequired = function (val, name) {\r\n if (val === null || val === undefined) {\r\n throw new Error(\"The '\" + name + \"' argument is required.\");\r\n }\r\n };\r\n Arg.isNotEmpty = function (val, name) {\r\n if (!val || val.match(/^\\s*$/)) {\r\n throw new Error(\"The '\" + name + \"' argument should not be empty.\");\r\n }\r\n };\r\n Arg.isIn = function (val, values, name) {\r\n // TypeScript enums have keys for **both** the name and the value of each enum member on the type itself.\r\n if (!(val in values)) {\r\n throw new Error(\"Unknown \" + name + \" value: \" + val + \".\");\r\n }\r\n };\r\n return Arg;\r\n}());\r\nexports.Arg = Arg;\r\n/** @private */\r\nvar Platform = /** @class */ (function () {\r\n function Platform() {\r\n }\r\n Object.defineProperty(Platform, \"isBrowser\", {\r\n get: function () {\r\n return typeof window === \"object\";\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(Platform, \"isWebWorker\", {\r\n get: function () {\r\n return typeof self === \"object\" && \"importScripts\" in self;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(Platform, \"isNode\", {\r\n get: function () {\r\n return !this.isBrowser && !this.isWebWorker;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n return Platform;\r\n}());\r\nexports.Platform = Platform;\r\n/** @private */\r\nfunction getDataDetail(data, includeContent) {\r\n var detail = \"\";\r\n if (isArrayBuffer(data)) {\r\n detail = \"Binary data of length \" + data.byteLength;\r\n if (includeContent) {\r\n detail += \". Content: '\" + formatArrayBuffer(data) + \"'\";\r\n }\r\n }\r\n else if (typeof data === \"string\") {\r\n detail = \"String data of length \" + data.length;\r\n if (includeContent) {\r\n detail += \". Content: '\" + data + \"'\";\r\n }\r\n }\r\n return detail;\r\n}\r\nexports.getDataDetail = getDataDetail;\r\n/** @private */\r\nfunction formatArrayBuffer(data) {\r\n var view = new Uint8Array(data);\r\n // Uint8Array.map only supports returning another Uint8Array?\r\n var str = \"\";\r\n view.forEach(function (num) {\r\n var pad = num < 16 ? \"0\" : \"\";\r\n str += \"0x\" + pad + num.toString(16) + \" \";\r\n });\r\n // Trim of trailing space.\r\n return str.substr(0, str.length - 1);\r\n}\r\nexports.formatArrayBuffer = formatArrayBuffer;\r\n// Also in signalr-protocol-msgpack/Utils.ts\r\n/** @private */\r\nfunction isArrayBuffer(val) {\r\n return val && typeof ArrayBuffer !== \"undefined\" &&\r\n (val instanceof ArrayBuffer ||\r\n // Sometimes we get an ArrayBuffer that doesn't satisfy instanceof\r\n (val.constructor && val.constructor.name === \"ArrayBuffer\"));\r\n}\r\nexports.isArrayBuffer = isArrayBuffer;\r\n/** @private */\r\nfunction sendMessage(logger, transportName, httpClient, url, accessTokenFactory, content, logMessageContent, withCredentials, defaultHeaders) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var _a, headers, token, _b, name, value, responseType, response;\r\n return __generator(this, function (_c) {\r\n switch (_c.label) {\r\n case 0:\r\n headers = {};\r\n if (!accessTokenFactory) return [3 /*break*/, 2];\r\n return [4 /*yield*/, accessTokenFactory()];\r\n case 1:\r\n token = _c.sent();\r\n if (token) {\r\n headers = (_a = {},\r\n _a[\"Authorization\"] = \"Bearer \" + token,\r\n _a);\r\n }\r\n _c.label = 2;\r\n case 2:\r\n _b = getUserAgentHeader(), name = _b[0], value = _b[1];\r\n headers[name] = value;\r\n logger.log(ILogger_1.LogLevel.Trace, \"(\" + transportName + \" transport) sending data. \" + getDataDetail(content, logMessageContent) + \".\");\r\n responseType = isArrayBuffer(content) ? \"arraybuffer\" : \"text\";\r\n return [4 /*yield*/, httpClient.post(url, {\r\n content: content,\r\n headers: __assign({}, headers, defaultHeaders),\r\n responseType: responseType,\r\n withCredentials: withCredentials,\r\n })];\r\n case 3:\r\n response = _c.sent();\r\n logger.log(ILogger_1.LogLevel.Trace, \"(\" + transportName + \" transport) request complete. Response status: \" + response.statusCode + \".\");\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\nexports.sendMessage = sendMessage;\r\n/** @private */\r\nfunction createLogger(logger) {\r\n if (logger === undefined) {\r\n return new ConsoleLogger(ILogger_1.LogLevel.Information);\r\n }\r\n if (logger === null) {\r\n return Loggers_1.NullLogger.instance;\r\n }\r\n if (logger.log) {\r\n return logger;\r\n }\r\n return new ConsoleLogger(logger);\r\n}\r\nexports.createLogger = createLogger;\r\n/** @private */\r\nvar SubjectSubscription = /** @class */ (function () {\r\n function SubjectSubscription(subject, observer) {\r\n this.subject = subject;\r\n this.observer = observer;\r\n }\r\n SubjectSubscription.prototype.dispose = function () {\r\n var index = this.subject.observers.indexOf(this.observer);\r\n if (index > -1) {\r\n this.subject.observers.splice(index, 1);\r\n }\r\n if (this.subject.observers.length === 0 && this.subject.cancelCallback) {\r\n this.subject.cancelCallback().catch(function (_) { });\r\n }\r\n };\r\n return SubjectSubscription;\r\n}());\r\nexports.SubjectSubscription = SubjectSubscription;\r\n/** @private */\r\nvar ConsoleLogger = /** @class */ (function () {\r\n function ConsoleLogger(minimumLogLevel) {\r\n this.minimumLogLevel = minimumLogLevel;\r\n this.outputConsole = console;\r\n }\r\n ConsoleLogger.prototype.log = function (logLevel, message) {\r\n if (logLevel >= this.minimumLogLevel) {\r\n switch (logLevel) {\r\n case ILogger_1.LogLevel.Critical:\r\n case ILogger_1.LogLevel.Error:\r\n this.outputConsole.error(\"[\" + new Date().toISOString() + \"] \" + ILogger_1.LogLevel[logLevel] + \": \" + message);\r\n break;\r\n case ILogger_1.LogLevel.Warning:\r\n this.outputConsole.warn(\"[\" + new Date().toISOString() + \"] \" + ILogger_1.LogLevel[logLevel] + \": \" + message);\r\n break;\r\n case ILogger_1.LogLevel.Information:\r\n this.outputConsole.info(\"[\" + new Date().toISOString() + \"] \" + ILogger_1.LogLevel[logLevel] + \": \" + message);\r\n break;\r\n default:\r\n // console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug\r\n this.outputConsole.log(\"[\" + new Date().toISOString() + \"] \" + ILogger_1.LogLevel[logLevel] + \": \" + message);\r\n break;\r\n }\r\n }\r\n };\r\n return ConsoleLogger;\r\n}());\r\nexports.ConsoleLogger = ConsoleLogger;\r\n/** @private */\r\nfunction getUserAgentHeader() {\r\n var userAgentHeaderName = \"X-SignalR-User-Agent\";\r\n if (Platform.isNode) {\r\n userAgentHeaderName = \"User-Agent\";\r\n }\r\n return [userAgentHeaderName, constructUserAgent(exports.VERSION, getOsName(), getRuntime(), getRuntimeVersion())];\r\n}\r\nexports.getUserAgentHeader = getUserAgentHeader;\r\n/** @private */\r\nfunction constructUserAgent(version, os, runtime, runtimeVersion) {\r\n // Microsoft SignalR/[Version] ([Detailed Version]; [Operating System]; [Runtime]; [Runtime Version])\r\n var userAgent = \"Microsoft SignalR/\";\r\n var majorAndMinor = version.split(\".\");\r\n userAgent += majorAndMinor[0] + \".\" + majorAndMinor[1];\r\n userAgent += \" (\" + version + \"; \";\r\n if (os && os !== \"\") {\r\n userAgent += os + \"; \";\r\n }\r\n else {\r\n userAgent += \"Unknown OS; \";\r\n }\r\n userAgent += \"\" + runtime;\r\n if (runtimeVersion) {\r\n userAgent += \"; \" + runtimeVersion;\r\n }\r\n else {\r\n userAgent += \"; Unknown Runtime Version\";\r\n }\r\n userAgent += \")\";\r\n return userAgent;\r\n}\r\nexports.constructUserAgent = constructUserAgent;\r\nfunction getOsName() {\r\n if (Platform.isNode) {\r\n switch (process.platform) {\r\n case \"win32\":\r\n return \"Windows NT\";\r\n case \"darwin\":\r\n return \"macOS\";\r\n case \"linux\":\r\n return \"Linux\";\r\n default:\r\n return process.platform;\r\n }\r\n }\r\n else {\r\n return \"\";\r\n }\r\n}\r\nfunction getRuntimeVersion() {\r\n if (Platform.isNode) {\r\n return process.versions.node;\r\n }\r\n return undefined;\r\n}\r\nfunction getRuntime() {\r\n if (Platform.isNode) {\r\n return \"NodeJS\";\r\n }\r\n else {\r\n return \"Browser\";\r\n }\r\n}\r\n//# sourceMappingURL=Utils.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __assign = (this && this.__assign) || Object.assign || function(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\r\n t[p] = s[p];\r\n }\r\n return t;\r\n};\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __generator = (this && this.__generator) || function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar ITransport_1 = require(\"./ITransport\");\r\nvar Utils_1 = require(\"./Utils\");\r\n/** @private */\r\nvar WebSocketTransport = /** @class */ (function () {\r\n function WebSocketTransport(httpClient, accessTokenFactory, logger, logMessageContent, webSocketConstructor, headers) {\r\n this.logger = logger;\r\n this.accessTokenFactory = accessTokenFactory;\r\n this.logMessageContent = logMessageContent;\r\n this.webSocketConstructor = webSocketConstructor;\r\n this.httpClient = httpClient;\r\n this.onreceive = null;\r\n this.onclose = null;\r\n this.headers = headers;\r\n }\r\n WebSocketTransport.prototype.connect = function (url, transferFormat) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var token;\r\n var _this = this;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n Utils_1.Arg.isRequired(url, \"url\");\r\n Utils_1.Arg.isRequired(transferFormat, \"transferFormat\");\r\n Utils_1.Arg.isIn(transferFormat, ITransport_1.TransferFormat, \"transferFormat\");\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(WebSockets transport) Connecting.\");\r\n if (!this.accessTokenFactory) return [3 /*break*/, 2];\r\n return [4 /*yield*/, this.accessTokenFactory()];\r\n case 1:\r\n token = _a.sent();\r\n if (token) {\r\n url += (url.indexOf(\"?\") < 0 ? \"?\" : \"&\") + (\"access_token=\" + encodeURIComponent(token));\r\n }\r\n _a.label = 2;\r\n case 2: return [2 /*return*/, new Promise(function (resolve, reject) {\r\n url = url.replace(/^http/, \"ws\");\r\n var webSocket;\r\n var cookies = _this.httpClient.getCookieString(url);\r\n var opened = false;\r\n if (Utils_1.Platform.isNode) {\r\n var headers = {};\r\n var _a = Utils_1.getUserAgentHeader(), name_1 = _a[0], value = _a[1];\r\n headers[name_1] = value;\r\n if (cookies) {\r\n headers[\"Cookie\"] = \"\" + cookies;\r\n }\r\n // Only pass headers when in non-browser environments\r\n webSocket = new _this.webSocketConstructor(url, undefined, {\r\n headers: __assign({}, headers, _this.headers),\r\n });\r\n }\r\n if (!webSocket) {\r\n // Chrome is not happy with passing 'undefined' as protocol\r\n webSocket = new _this.webSocketConstructor(url);\r\n }\r\n if (transferFormat === ITransport_1.TransferFormat.Binary) {\r\n webSocket.binaryType = \"arraybuffer\";\r\n }\r\n // tslint:disable-next-line:variable-name\r\n webSocket.onopen = function (_event) {\r\n _this.logger.log(ILogger_1.LogLevel.Information, \"WebSocket connected to \" + url + \".\");\r\n _this.webSocket = webSocket;\r\n opened = true;\r\n resolve();\r\n };\r\n webSocket.onerror = function (event) {\r\n var error = null;\r\n // ErrorEvent is a browser only type we need to check if the type exists before using it\r\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent) {\r\n error = event.error;\r\n }\r\n else {\r\n error = new Error(\"There was an error with the transport.\");\r\n }\r\n reject(error);\r\n };\r\n webSocket.onmessage = function (message) {\r\n _this.logger.log(ILogger_1.LogLevel.Trace, \"(WebSockets transport) data received. \" + Utils_1.getDataDetail(message.data, _this.logMessageContent) + \".\");\r\n if (_this.onreceive) {\r\n try {\r\n _this.onreceive(message.data);\r\n }\r\n catch (error) {\r\n _this.close(error);\r\n return;\r\n }\r\n }\r\n };\r\n webSocket.onclose = function (event) {\r\n // Don't call close handler if connection was never established\r\n // We'll reject the connect call instead\r\n if (opened) {\r\n _this.close(event);\r\n }\r\n else {\r\n var error = null;\r\n // ErrorEvent is a browser only type we need to check if the type exists before using it\r\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent) {\r\n error = event.error;\r\n }\r\n else {\r\n error = new Error(\"There was an error with the transport.\");\r\n }\r\n reject(error);\r\n }\r\n };\r\n })];\r\n }\r\n });\r\n });\r\n };\r\n WebSocketTransport.prototype.send = function (data) {\r\n if (this.webSocket && this.webSocket.readyState === this.webSocketConstructor.OPEN) {\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(WebSockets transport) sending data. \" + Utils_1.getDataDetail(data, this.logMessageContent) + \".\");\r\n this.webSocket.send(data);\r\n return Promise.resolve();\r\n }\r\n return Promise.reject(\"WebSocket is not in the OPEN state\");\r\n };\r\n WebSocketTransport.prototype.stop = function () {\r\n if (this.webSocket) {\r\n // Manually invoke onclose callback inline so we know the HttpConnection was closed properly before returning\r\n // This also solves an issue where websocket.onclose could take 18+ seconds to trigger during network disconnects\r\n this.close(undefined);\r\n }\r\n return Promise.resolve();\r\n };\r\n WebSocketTransport.prototype.close = function (event) {\r\n // webSocket will be null if the transport did not start successfully\r\n if (this.webSocket) {\r\n // Clear websocket handlers because we are considering the socket closed now\r\n this.webSocket.onclose = function () { };\r\n this.webSocket.onmessage = function () { };\r\n this.webSocket.onerror = function () { };\r\n this.webSocket.close();\r\n this.webSocket = undefined;\r\n }\r\n this.logger.log(ILogger_1.LogLevel.Trace, \"(WebSockets transport) socket closed.\");\r\n if (this.onclose) {\r\n if (this.isCloseEvent(event) && (event.wasClean === false || event.code !== 1000)) {\r\n this.onclose(new Error(\"WebSocket closed with status code: \" + event.code + \" (\" + event.reason + \").\"));\r\n }\r\n else if (event instanceof Error) {\r\n this.onclose(event);\r\n }\r\n else {\r\n this.onclose();\r\n }\r\n }\r\n };\r\n WebSocketTransport.prototype.isCloseEvent = function (event) {\r\n return event && typeof event.wasClean === \"boolean\" && typeof event.code === \"number\";\r\n };\r\n return WebSocketTransport;\r\n}());\r\nexports.WebSocketTransport = WebSocketTransport;\r\n//# sourceMappingURL=WebSocketTransport.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nvar __extends = (this && this.__extends) || (function () {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return function (d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n})();\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar Errors_1 = require(\"./Errors\");\r\nvar HttpClient_1 = require(\"./HttpClient\");\r\nvar ILogger_1 = require(\"./ILogger\");\r\nvar XhrHttpClient = /** @class */ (function (_super) {\r\n __extends(XhrHttpClient, _super);\r\n function XhrHttpClient(logger) {\r\n var _this = _super.call(this) || this;\r\n _this.logger = logger;\r\n return _this;\r\n }\r\n /** @inheritDoc */\r\n XhrHttpClient.prototype.send = function (request) {\r\n var _this = this;\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n return Promise.reject(new Errors_1.AbortError());\r\n }\r\n if (!request.method) {\r\n return Promise.reject(new Error(\"No method defined.\"));\r\n }\r\n if (!request.url) {\r\n return Promise.reject(new Error(\"No url defined.\"));\r\n }\r\n return new Promise(function (resolve, reject) {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open(request.method, request.url, true);\r\n xhr.withCredentials = request.withCredentials === undefined ? true : request.withCredentials;\r\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\r\n // Explicitly setting the Content-Type header for React Native on Android platform.\r\n xhr.setRequestHeader(\"Content-Type\", \"text/plain;charset=UTF-8\");\r\n var headers = request.headers;\r\n if (headers) {\r\n Object.keys(headers)\r\n .forEach(function (header) {\r\n xhr.setRequestHeader(header, headers[header]);\r\n });\r\n }\r\n if (request.responseType) {\r\n xhr.responseType = request.responseType;\r\n }\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = function () {\r\n xhr.abort();\r\n reject(new Errors_1.AbortError());\r\n };\r\n }\r\n if (request.timeout) {\r\n xhr.timeout = request.timeout;\r\n }\r\n xhr.onload = function () {\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = null;\r\n }\r\n if (xhr.status >= 200 && xhr.status < 300) {\r\n resolve(new HttpClient_1.HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText));\r\n }\r\n else {\r\n reject(new Errors_1.HttpError(xhr.statusText, xhr.status));\r\n }\r\n };\r\n xhr.onerror = function () {\r\n _this.logger.log(ILogger_1.LogLevel.Warning, \"Error from HTTP request. \" + xhr.status + \": \" + xhr.statusText + \".\");\r\n reject(new Errors_1.HttpError(xhr.statusText, xhr.status));\r\n };\r\n xhr.ontimeout = function () {\r\n _this.logger.log(ILogger_1.LogLevel.Warning, \"Timeout from HTTP request.\");\r\n reject(new Errors_1.TimeoutError());\r\n };\r\n xhr.send(request.content || \"\");\r\n });\r\n };\r\n return XhrHttpClient;\r\n}(HttpClient_1.HttpClient));\r\nexports.XhrHttpClient = XhrHttpClient;\r\n//# sourceMappingURL=XhrHttpClient.js.map","\"use strict\";\r\n// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar Errors_1 = require(\"./Errors\");\r\nexports.AbortError = Errors_1.AbortError;\r\nexports.HttpError = Errors_1.HttpError;\r\nexports.TimeoutError = Errors_1.TimeoutError;\r\nvar HttpClient_1 = require(\"./HttpClient\");\r\nexports.HttpClient = HttpClient_1.HttpClient;\r\nexports.HttpResponse = HttpClient_1.HttpResponse;\r\nvar DefaultHttpClient_1 = require(\"./DefaultHttpClient\");\r\nexports.DefaultHttpClient = DefaultHttpClient_1.DefaultHttpClient;\r\nvar HubConnection_1 = require(\"./HubConnection\");\r\nexports.HubConnection = HubConnection_1.HubConnection;\r\nexports.HubConnectionState = HubConnection_1.HubConnectionState;\r\nvar HubConnectionBuilder_1 = require(\"./HubConnectionBuilder\");\r\nexports.HubConnectionBuilder = HubConnectionBuilder_1.HubConnectionBuilder;\r\nvar IHubProtocol_1 = require(\"./IHubProtocol\");\r\nexports.MessageType = IHubProtocol_1.MessageType;\r\nvar ILogger_1 = require(\"./ILogger\");\r\nexports.LogLevel = ILogger_1.LogLevel;\r\nvar ITransport_1 = require(\"./ITransport\");\r\nexports.HttpTransportType = ITransport_1.HttpTransportType;\r\nexports.TransferFormat = ITransport_1.TransferFormat;\r\nvar Loggers_1 = require(\"./Loggers\");\r\nexports.NullLogger = Loggers_1.NullLogger;\r\nvar JsonHubProtocol_1 = require(\"./JsonHubProtocol\");\r\nexports.JsonHubProtocol = JsonHubProtocol_1.JsonHubProtocol;\r\nvar Subject_1 = require(\"./Subject\");\r\nexports.Subject = Subject_1.Subject;\r\nvar Utils_1 = require(\"./Utils\");\r\nexports.VERSION = Utils_1.VERSION;\r\n//# sourceMappingURL=index.js.map","'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\nvar K_MAX_LENGTH = 0x7fffffff\nexports.kMaxLength = K_MAX_LENGTH\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Print warning and recommend using `buffer` v4.x which has an Object\n * implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * We report that the browser does not support typed arrays if the are not subclassable\n * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`\n * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support\n * for __proto__ and has a buggy typed array implementation.\n */\nBuffer.TYPED_ARRAY_SUPPORT = typedArraySupport()\n\nif (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&\n typeof console.error === 'function') {\n console.error(\n 'This browser lacks typed array (Uint8Array) support which is required by ' +\n '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'\n )\n}\n\nfunction typedArraySupport () {\n // Can typed array instances can be augmented?\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }\n return arr.foo() === 42\n } catch (e) {\n return false\n }\n}\n\nObject.defineProperty(Buffer.prototype, 'parent', {\n enumerable: true,\n get: function () {\n if (!Buffer.isBuffer(this)) return undefined\n return this.buffer\n }\n})\n\nObject.defineProperty(Buffer.prototype, 'offset', {\n enumerable: true,\n get: function () {\n if (!Buffer.isBuffer(this)) return undefined\n return this.byteOffset\n }\n})\n\nfunction createBuffer (length) {\n if (length > K_MAX_LENGTH) {\n throw new RangeError('The value \"' + length + '\" is invalid for option \"size\"')\n }\n // Return an augmented `Uint8Array` instance\n var buf = new Uint8Array(length)\n buf.__proto__ = Buffer.prototype\n return buf\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new TypeError(\n 'The \"string\" argument must be of type string. Received type number'\n )\n }\n return allocUnsafe(arg)\n }\n return from(arg, encodingOrOffset, length)\n}\n\n// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\nif (typeof Symbol !== 'undefined' && Symbol.species != null &&\n Buffer[Symbol.species] === Buffer) {\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true,\n enumerable: false,\n writable: false\n })\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\nfunction from (value, encodingOrOffset, length) {\n if (typeof value === 'string') {\n return fromString(value, encodingOrOffset)\n }\n\n if (ArrayBuffer.isView(value)) {\n return fromArrayLike(value)\n }\n\n if (value == null) {\n throw TypeError(\n 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +\n 'or Array-like Object. Received type ' + (typeof value)\n )\n }\n\n if (isInstance(value, ArrayBuffer) ||\n (value && isInstance(value.buffer, ArrayBuffer))) {\n return fromArrayBuffer(value, encodingOrOffset, length)\n }\n\n if (typeof value === 'number') {\n throw new TypeError(\n 'The \"value\" argument must not be of type number. Received type number'\n )\n }\n\n var valueOf = value.valueOf && value.valueOf()\n if (valueOf != null && valueOf !== value) {\n return Buffer.from(valueOf, encodingOrOffset, length)\n }\n\n var b = fromObject(value)\n if (b) return b\n\n if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&\n typeof value[Symbol.toPrimitive] === 'function') {\n return Buffer.from(\n value[Symbol.toPrimitive]('string'), encodingOrOffset, length\n )\n }\n\n throw new TypeError(\n 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +\n 'or Array-like Object. Received type ' + (typeof value)\n )\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(value, encodingOrOffset, length)\n}\n\n// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:\n// https://github.com/feross/buffer/pull/148\nBuffer.prototype.__proto__ = Uint8Array.prototype\nBuffer.__proto__ = Uint8Array\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be of type number')\n } else if (size < 0) {\n throw new RangeError('The value \"' + size + '\" is invalid for option \"size\"')\n }\n}\n\nfunction alloc (size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(size).fill(fill, encoding)\n : createBuffer(size).fill(fill)\n }\n return createBuffer(size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(size, fill, encoding)\n}\n\nfunction allocUnsafe (size) {\n assertSize(size)\n return createBuffer(size < 0 ? 0 : checked(size) | 0)\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(size)\n}\n\nfunction fromString (string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n\n var length = byteLength(string, encoding) | 0\n var buf = createBuffer(length)\n\n var actual = buf.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n buf = buf.slice(0, actual)\n }\n\n return buf\n}\n\nfunction fromArrayLike (array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n var buf = createBuffer(length)\n for (var i = 0; i < length; i += 1) {\n buf[i] = array[i] & 255\n }\n return buf\n}\n\nfunction fromArrayBuffer (array, byteOffset, length) {\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\"offset\" is outside of buffer bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\"length\" is outside of buffer bounds')\n }\n\n var buf\n if (byteOffset === undefined && length === undefined) {\n buf = new Uint8Array(array)\n } else if (length === undefined) {\n buf = new Uint8Array(array, byteOffset)\n } else {\n buf = new Uint8Array(array, byteOffset, length)\n }\n\n // Return an augmented `Uint8Array` instance\n buf.__proto__ = Buffer.prototype\n return buf\n}\n\nfunction fromObject (obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n var buf = createBuffer(len)\n\n if (buf.length === 0) {\n return buf\n }\n\n obj.copy(buf, 0, 0, len)\n return buf\n }\n\n if (obj.length !== undefined) {\n if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {\n return createBuffer(0)\n }\n return fromArrayLike(obj)\n }\n\n if (obj.type === 'Buffer' && Array.isArray(obj.data)) {\n return fromArrayLike(obj.data)\n }\n}\n\nfunction checked (length) {\n // Note: cannot use `length < K_MAX_LENGTH` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= K_MAX_LENGTH) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return b != null && b._isBuffer === true &&\n b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false\n}\n\nBuffer.compare = function compare (a, b) {\n if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)\n if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError(\n 'The \"buf1\", \"buf2\" arguments must be one of type Buffer or Uint8Array'\n )\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!Array.isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (isInstance(buf, Uint8Array)) {\n buf = Buffer.from(buf)\n }\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n throw new TypeError(\n 'The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. ' +\n 'Received type ' + typeof string\n )\n }\n\n var len = string.length\n var mustMatch = (arguments.length > 2 && arguments[2] === true)\n if (!mustMatch && len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) {\n return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8\n }\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)\n// to detect a Buffer instance. It's not possible to use `instanceof Buffer`\n// reliably in a browserify context because there could be multiple different\n// copies of the 'buffer' package in use. This method works even for Buffer\n// instances that were created from another copy of the `buffer` package.\n// See: https://github.com/feross/buffer/issues/154\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.toLocaleString = Buffer.prototype.toString\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()\n if (this.length > max) str += ' ... '\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (isInstance(target, Uint8Array)) {\n target = Buffer.from(target, target.offset, target.byteLength)\n }\n if (!Buffer.isBuffer(target)) {\n throw new TypeError(\n 'The \"target\" argument must be one of type Buffer or Uint8Array. ' +\n 'Received type ' + (typeof target)\n )\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (numberIsNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n var strLen = string.length\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (numberIsNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset >>> 0\n if (isFinite(length)) {\n length = length >>> 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf = this.subarray(start, end)\n // Return an augmented `Uint8Array` instance\n newBuf.__proto__ = Buffer.prototype\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset >>> 0\n byteLength = byteLength >>> 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset >>> 0\n byteLength = byteLength >>> 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset >>> 0\n byteLength = byteLength >>> 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset >>> 0\n byteLength = byteLength >>> 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n offset = offset >>> 0\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset >>> 0\n byteLength = byteLength >>> 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset >>> 0\n byteLength = byteLength >>> 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n return offset + 2\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) {\n var limit = Math.pow(2, (8 * byteLength) - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) {\n var limit = Math.pow(2, (8 * byteLength) - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n value = +value\n offset = offset >>> 0\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('Index out of range')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n\n if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {\n // Use built-in when available, missing from IE11\n this.copyWithin(targetStart, start, end)\n } else if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (var i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, end),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if ((encoding === 'utf8' && code < 128) ||\n encoding === 'latin1') {\n // Fast path: If `val` fits into a single byte, use that numeric value.\n val = code\n }\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : Buffer.from(val, encoding)\n var len = bytes.length\n if (len === 0) {\n throw new TypeError('The value \"' + val +\n '\" is invalid for argument \"value\"')\n }\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node takes equal signs as end of the Base64 encoding\n str = str.split('=')[0]\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = str.trim().replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\n// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass\n// the `instanceof` check but they should be treated as of that type.\n// See: https://github.com/feross/buffer/issues/166\nfunction isInstance (obj, type) {\n return obj instanceof type ||\n (obj != null && obj.constructor != null && obj.constructor.name != null &&\n obj.constructor.name === type.name)\n}\nfunction numberIsNaN (obj) {\n // For IE11 support\n return obj !== obj // eslint-disable-line no-self-compare\n}\n","/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global global, define, Symbol, Reflect, Promise, SuppressedError */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __esDecorate;\r\nvar __runInitializers;\r\nvar __propKey;\r\nvar __setFunctionName;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __spreadArrays;\r\nvar __spreadArray;\r\nvar __await;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\nvar __makeTemplateObject;\r\nvar __importStar;\r\nvar __importDefault;\r\nvar __classPrivateFieldGet;\r\nvar __classPrivateFieldSet;\r\nvar __classPrivateFieldIn;\r\nvar __createBinding;\r\nvar __addDisposableResource;\r\nvar __disposeResources;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n if (exports !== root) {\r\n if (typeof Object.create === \"function\") {\r\n Object.defineProperty(exports, \"__esModule\", { value: true });\r\n }\r\n else {\r\n exports.__esModule = true;\r\n }\r\n }\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __esDecorate = function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n };\r\n\r\n __runInitializers = function (thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n };\r\n\r\n __propKey = function (x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n };\r\n\r\n __setFunctionName = function (f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n };\r\n\r\n __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n }) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n });\r\n\r\n __values = function (o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spreadArrays = function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n };\r\n\r\n __spreadArray = function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n };\r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n };\r\n\r\n __makeTemplateObject = function (cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n };\r\n\r\n var __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n }) : function(o, v) {\r\n o[\"default\"] = v;\r\n };\r\n\r\n __importStar = function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n };\r\n\r\n __importDefault = function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n };\r\n\r\n __classPrivateFieldGet = function (receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n };\r\n\r\n __classPrivateFieldSet = function (receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n };\r\n\r\n __classPrivateFieldIn = function (state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n };\r\n\r\n __addDisposableResource = function (env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n };\r\n\r\n var _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n };\r\n\r\n __disposeResources = function (env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n function next() {\r\n while (env.stack.length) {\r\n var rec = env.stack.pop();\r\n try {\r\n var result = rec.dispose && rec.dispose.call(rec.value);\r\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__esDecorate\", __esDecorate);\r\n exporter(\"__runInitializers\", __runInitializers);\r\n exporter(\"__propKey\", __propKey);\r\n exporter(\"__setFunctionName\", __setFunctionName);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__createBinding\", __createBinding);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__spreadArrays\", __spreadArrays);\r\n exporter(\"__spreadArray\", __spreadArray);\r\n exporter(\"__await\", __await);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n exporter(\"__makeTemplateObject\", __makeTemplateObject);\r\n exporter(\"__importStar\", __importStar);\r\n exporter(\"__importDefault\", __importDefault);\r\n exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\r\n exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\r\n exporter(\"__classPrivateFieldIn\", __classPrivateFieldIn);\r\n exporter(\"__addDisposableResource\", __addDisposableResource);\r\n exporter(\"__disposeResources\", __disposeResources);\r\n});\r\n","import { ActionTypes } from './actions';\r\nimport * as signalR from \"@microsoft/signalr\";\r\nimport * as FingerprintJS from \"@fingerprintjs/fingerprintjs\"\r\n// single signalR connection-per-page\r\nexport const connection = new signalR.HubConnectionBuilder()\r\n .withUrl(\"/defaultHub\")\r\n .withAutomaticReconnect()\r\n // .configureLogging(signalR.LogLevel.Debug)\r\n .build();\r\nimport { Toaster } from \"./toaster\";\r\ndeclare var OneSignal: any;\r\ndeclare var gonative: any;\r\nimport { HubConnection, HubConnectionState } from '@microsoft/signalr';\r\n\r\n$(() => {\r\n connection.on(\"Error\",\r\n (code: number, message: string) => {\r\n Toaster.error(message);\r\n });\r\n\r\n connection.on(\"ConnectionNotAllowed\",\r\n () => {\r\n window.location.href = '/connection-not-allowed';\r\n });\r\n\r\n connection.on(\"Info\",\r\n (message: string) => {\r\n Toaster.info(message);\r\n });\r\n\r\n connection.on(\"OnActionCompleted\",\r\n (actionType: ActionTypes, actionId: string, text: string) => {\r\n // handle Action Completed\r\n });\r\n\r\n if (connection.state === 'Disconnected') { // connection can be opened by component\r\n connection.start()\r\n .then(() => {\r\n console.log(\"connection started\");\r\n setVisitorId();\r\n setOneSignalPlayerIds();\r\n })\r\n .catch((error) => {\r\n console.error(error.toString());\r\n Toaster.error(\"Failed to connect to server\");\r\n });\r\n }\r\n\r\n connection.onclose((error?: Error) => {\r\n if (error) {\r\n console.error('connection was closed: ', error);\r\n } else {\r\n console.error('connection was closed');\r\n }\r\n });\r\n});\r\n\r\nexport function setVisitorId() {\r\n const fpPromise = FingerprintJS.load({ /* options */ }) // https://dev.fingerprintjs.com/docs/js-agent#agent-initialization\r\n fpPromise\r\n .then(fp => fp.get())\r\n .then(result =>\r\n connection\r\n .invoke(\"SetVisitorId\", result.visitorId)\r\n .catch((error) => console.error(error.toString())));\r\n}\r\n\r\nexport function setOneSignalPlayerIds() {\r\n if (typeof OneSignal !== \"undefined\") {\r\n console.log('updating OneSignal IDs');\r\n\r\n OneSignal.push(function () {\r\n OneSignal.getUserId(function (playerId: string) {\r\n connection.invoke(\"SetOneSignalWebPushPlayerId\", playerId)\r\n .catch((error) => console.error(error.toString()));\r\n });\r\n });\r\n\r\n OneSignal.push(function () {\r\n OneSignal.getEmailId(function (playerId: string) {\r\n connection.invoke(\"SetOneSignalEmailPlayerId\", playerId)\r\n .catch((error) => console.error(error.toString()));\r\n });\r\n });\r\n\r\n OneSignal.push(function () {\r\n OneSignal.getSMSId(function (playerId: string) {\r\n connection.invoke(\"SetOneSignalSMSPlayerId\", playerId)\r\n .catch((error) => console.error(error.toString()));\r\n });\r\n });\r\n\r\n if (typeof gonative !== \"undefined\") {\r\n gonative.onesignal.onesignalInfo().then(function (oneSignalInfo) {\r\n connection.invoke(\"SetOneSignalMobilePlayerId\", JSON.stringify(oneSignalInfo))\r\n .catch((error) => console.error(error.toString()));\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport const debounce = (fn, delay = 500) => {\r\n let timeout: ReturnType;\r\n const currentScope = this;\r\n return function (...args) {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(fn.bind(currentScope, ...args), delay);\r\n }\r\n}","export { };\r\n\r\nexport class Toaster {\r\n public static info(text: string, heading?: string) {\r\n $.toast({\r\n heading: heading,\r\n text: text,\r\n position: \"bottom-left\",\r\n loader: false,\r\n hideAfter: 2000,\r\n allowToastClose: false,\r\n showHideTransition: \"slide\"\r\n // icon: \"success\"\r\n });\r\n }\r\n\r\n public static error(text: string) {\r\n $.toast({\r\n heading: \"Error\",\r\n text: text,\r\n position: \"bottom-left\",\r\n loader: false,\r\n hideAfter: 2000,\r\n allowToastClose: false,\r\n showHideTransition: \"slide\"\r\n });\r\n }\r\n\r\n public static tradeSuccess(heading: string, text: string) {\r\n $.toast({\r\n heading: heading,\r\n text: text,\r\n position: \"bottom-left\",\r\n loaderBg: \"#5ba035\",\r\n hideAfter: 2000,\r\n allowToastClose: false,\r\n showHideTransition: \"slide\"\r\n });\r\n }\r\n\r\n public static tradeInfo(heading: string, text: string) {\r\n $.toast({\r\n heading: heading,\r\n text: text,\r\n position: \"bottom-left\",\r\n loaderBg: \"#5ba035\",\r\n hideAfter: 2000,\r\n allowToastClose: false,\r\n showHideTransition: \"slide\"\r\n });\r\n }\r\n\r\n public static tradeError(text: string) {\r\n $.toast({\r\n heading: \"Error\",\r\n text: text,\r\n position: \"bottom-left\",\r\n loaderBg: \"#bf441d\",\r\n hideAfter: 2000,\r\n allowToastClose: false,\r\n showHideTransition: \"slide\"\r\n });\r\n }\r\n}\r\n"],"preExistingComment":"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvQGZpbmdlcnByaW50anMvZmluZ2VycHJpbnRqcy9kaXN0L2ZwLmNqcy5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvQWJvcnRDb250cm9sbGVyLmpzIiwibm9kZV9tb2R1bGVzL0BtaWNyb3NvZnQvc2lnbmFsci9kaXN0L2Nqcy9EZWZhdWx0SHR0cENsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvRGVmYXVsdFJlY29ubmVjdFBvbGljeS5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvRXJyb3JzLmpzIiwibm9kZV9tb2R1bGVzL0BtaWNyb3NvZnQvc2lnbmFsci9kaXN0L2Nqcy9GZXRjaEh0dHBDbGllbnQuanMiLCJub2RlX21vZHVsZXMvQG1pY3Jvc29mdC9zaWduYWxyL2Rpc3QvY2pzL0hhbmRzaGFrZVByb3RvY29sLmpzIiwibm9kZV9tb2R1bGVzL0BtaWNyb3NvZnQvc2lnbmFsci9kaXN0L2Nqcy9IdHRwQ2xpZW50LmpzIiwibm9kZV9tb2R1bGVzL0BtaWNyb3NvZnQvc2lnbmFsci9kaXN0L2Nqcy9IdHRwQ29ubmVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvSHViQ29ubmVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvSHViQ29ubmVjdGlvbkJ1aWxkZXIuanMiLCJub2RlX21vZHVsZXMvQG1pY3Jvc29mdC9zaWduYWxyL2Rpc3QvY2pzL0lIdWJQcm90b2NvbC5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvSUxvZ2dlci5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvSVRyYW5zcG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvSnNvbkh1YlByb3RvY29sLmpzIiwibm9kZV9tb2R1bGVzL0BtaWNyb3NvZnQvc2lnbmFsci9kaXN0L2Nqcy9Mb2dnZXJzLmpzIiwibm9kZV9tb2R1bGVzL0BtaWNyb3NvZnQvc2lnbmFsci9kaXN0L2Nqcy9Mb25nUG9sbGluZ1RyYW5zcG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvU2VydmVyU2VudEV2ZW50c1RyYW5zcG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvU3ViamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AbWljcm9zb2Z0L3NpZ25hbHIvZGlzdC9janMvVGV4dE1lc3NhZ2VGb3JtYXQuanMiLCJub2RlX21vZHVsZXMvQG1pY3Jvc29mdC9zaWduYWxyL2Rpc3QvY2pzL1V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL0BtaWNyb3NvZnQvc2lnbmFsci9kaXN0L2Nqcy9XZWJTb2NrZXRUcmFuc3BvcnQuanMiLCJub2RlX21vZHVsZXMvQG1pY3Jvc29mdC9zaWduYWxyL2Rpc3QvY2pzL1hockh0dHBDbGllbnQuanMiLCJub2RlX21vZHVsZXMvQG1pY3Jvc29mdC9zaWduYWxyL2Rpc3QvY2pzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuanMiLCJzcmMvanMvYXBwL21haW4udHMiLCJzcmMvanMvYXBwL3RvYXN0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3bkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsc0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3Y3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNyYUEsaUJBNEdDOzs7O0FBM0dELGtFQUE4QztBQUM5QyxrRkFBNkQ7QUFDN0QscUNBQXFDO0FBQ3hCLFFBQUEsVUFBVSxHQUFHLElBQUksT0FBTyxDQUFDLG9CQUFvQixFQUFFO0tBQ3pELE9BQU8sQ0FBQyxhQUFhLENBQUM7S0FDdEIsc0JBQXNCLEVBQUU7SUFDekIsNENBQTRDO0tBQzNDLEtBQUssRUFBRSxDQUFDO0FBQ1gscUNBQW9DO0FBS3BDLENBQUMsQ0FBQztJQUNBLGtCQUFVLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFDbkIsVUFBQyxJQUFZLEVBQUUsT0FBZTtRQUM1QixpQkFBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN6QixDQUFDLENBQUMsQ0FBQztJQUVMLGtCQUFVLENBQUMsRUFBRSxDQUFDLHNCQUFzQixFQUNsQztRQUNFLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLHlCQUF5QixDQUFDO0lBQ25ELENBQUMsQ0FBQyxDQUFDO0lBRUwsa0JBQVUsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUNsQixVQUFDLE9BQWU7UUFDZCxpQkFBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN4QixDQUFDLENBQUMsQ0FBQztJQUVMLGtCQUFVLENBQUMsRUFBRSxDQUFDLG1CQUFtQixFQUMvQixVQUFDLFVBQXVCLEVBQUUsUUFBZ0IsRUFBRSxJQUFZO1FBQ3RELDBCQUEwQjtJQUM1QixDQUFDLENBQUMsQ0FBQztJQUVMLElBQUksa0JBQVUsQ0FBQyxLQUFLLEtBQUssY0FBYyxFQUFFLEVBQUUsd0NBQXdDO1FBQ2pGLGtCQUFVLENBQUMsS0FBSyxFQUFFO2FBQ2YsSUFBSSxDQUFDO1lBQ0osT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ2xDLFlBQVksRUFBRSxDQUFDO1lBQ2YscUJBQXFCLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUM7YUFDRCxLQUFLLENBQUMsVUFBQyxLQUFLO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUNoQyxpQkFBTyxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO0tBQ047SUFFRCxrQkFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQWE7UUFDL0IsSUFBSSxLQUFLLEVBQUU7WUFDVCxPQUFPLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ2pEO2FBQU07WUFDTCxPQUFPLENBQUMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7U0FDeEM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsU0FBZ0IsWUFBWTtJQUMxQixJQUFNLFNBQVMsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsYUFBYSxDQUFFLENBQUMsQ0FBQSxDQUFDLG1FQUFtRTtJQUMzSCxTQUFTO1NBQ04sSUFBSSxDQUFDLFVBQUEsRUFBRSxJQUFJLE9BQUEsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFSLENBQVEsQ0FBQztTQUNwQixJQUFJLENBQUMsVUFBQSxNQUFNO1FBQ1YsT0FBQSxrQkFBVTthQUNQLE1BQU0sQ0FBQyxjQUFjLEVBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQzthQUN4QyxLQUFLLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUEvQixDQUErQixDQUFDO0lBRnBELENBRW9ELENBQUMsQ0FBQztBQUM1RCxDQUFDO0FBUkQsb0NBUUM7QUFFRCxTQUFnQixxQkFBcUI7SUFDbkMsSUFBSSxPQUFPLFNBQVMsS0FBSyxXQUFXLEVBQUU7UUFDcEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBRXRDLFNBQVMsQ0FBQyxJQUFJLENBQUM7WUFDYixTQUFTLENBQUMsU0FBUyxDQUFDLFVBQVUsUUFBZ0I7Z0JBQzVDLGtCQUFVLENBQUMsTUFBTSxDQUFDLDZCQUE2QixFQUFFLFFBQVEsQ0FBQztxQkFDdkQsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBL0IsQ0FBK0IsQ0FBQyxDQUFDO1lBQ3ZELENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2IsU0FBUyxDQUFDLFVBQVUsQ0FBQyxVQUFVLFFBQWdCO2dCQUM3QyxrQkFBVSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsRUFBRSxRQUFRLENBQUM7cUJBQ3JELEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQS9CLENBQStCLENBQUMsQ0FBQztZQUN2RCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsU0FBUyxDQUFDLElBQUksQ0FBQztZQUNiLFNBQVMsQ0FBQyxRQUFRLENBQUMsVUFBVSxRQUFnQjtnQkFDM0Msa0JBQVUsQ0FBQyxNQUFNLENBQUMseUJBQXlCLEVBQUUsUUFBUSxDQUFDO3FCQUNuRCxLQUFLLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUEvQixDQUErQixDQUFDLENBQUM7WUFDdkQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFO1lBQ25DLFFBQVEsQ0FBQyxTQUFTLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsYUFBYTtnQkFDN0Qsa0JBQVUsQ0FBQyxNQUFNLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztxQkFDM0UsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBL0IsQ0FBK0IsQ0FBQyxDQUFDO1lBQ3ZELENBQUMsQ0FBQyxDQUFDO1NBQ0o7S0FDRjtBQUNILENBQUM7QUFoQ0Qsc0RBZ0NDO0FBRU0sSUFBTSxRQUFRLEdBQUcsVUFBQyxFQUFFLEVBQUUsS0FBVztJQUFYLHNCQUFBLEVBQUEsV0FBVztJQUN0QyxJQUFJLE9BQXNDLENBQUM7SUFDM0MsSUFBTSxZQUFZLEdBQUcsS0FBSSxDQUFDO0lBQzFCLE9BQU87UUFBVSxjQUFPO2FBQVAsVUFBTyxFQUFQLHFCQUFPLEVBQVAsSUFBTztZQUFQLHlCQUFPOztRQUN0QixZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdEIsT0FBTyxHQUFHLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxPQUFQLEVBQUUseUJBQU0sWUFBWSxHQUFLLElBQUksV0FBRyxLQUFLLENBQUMsQ0FBQztJQUM5RCxDQUFDLENBQUE7QUFDSCxDQUFDLENBQUE7QUFQWSxRQUFBLFFBQVEsWUFPcEI7Ozs7O0FDMUdEO0lBQUE7SUE2REEsQ0FBQztJQTVEaUIsWUFBSSxHQUFsQixVQUFtQixJQUFZLEVBQUUsT0FBZ0I7UUFDN0MsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUNKLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLElBQUksRUFBRSxJQUFJO1lBQ1YsUUFBUSxFQUFFLGFBQWE7WUFDdkIsTUFBTSxFQUFFLEtBQUs7WUFDYixTQUFTLEVBQUUsSUFBSTtZQUNmLGVBQWUsRUFBRSxLQUFLO1lBQ3RCLGtCQUFrQixFQUFFLE9BQU87WUFDM0Isa0JBQWtCO1NBQ3JCLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFYSxhQUFLLEdBQW5CLFVBQW9CLElBQVk7UUFDNUIsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUNKLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLElBQUksRUFBRSxJQUFJO1lBQ1YsUUFBUSxFQUFFLGFBQWE7WUFDdkIsTUFBTSxFQUFFLEtBQUs7WUFDYixTQUFTLEVBQUUsSUFBSTtZQUNmLGVBQWUsRUFBRSxLQUFLO1lBQ3RCLGtCQUFrQixFQUFFLE9BQU87U0FDOUIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVhLG9CQUFZLEdBQTFCLFVBQTJCLE9BQWUsRUFBRSxJQUFZO1FBQ3BELENBQUMsQ0FBQyxLQUFLLENBQUM7WUFDSixPQUFPLEVBQUUsT0FBTztZQUNoQixJQUFJLEVBQUUsSUFBSTtZQUNWLFFBQVEsRUFBRSxhQUFhO1lBQ3ZCLFFBQVEsRUFBRSxTQUFTO1lBQ25CLFNBQVMsRUFBRSxJQUFJO1lBQ2YsZUFBZSxFQUFFLEtBQUs7WUFDdEIsa0JBQWtCLEVBQUUsT0FBTztTQUM5QixDQUFDLENBQUM7SUFDUCxDQUFDO0lBRWEsaUJBQVMsR0FBdkIsVUFBd0IsT0FBZSxFQUFFLElBQVk7UUFDakQsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUNKLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLElBQUksRUFBRSxJQUFJO1lBQ1YsUUFBUSxFQUFFLGFBQWE7WUFDdkIsUUFBUSxFQUFFLFNBQVM7WUFDbkIsU0FBUyxFQUFFLElBQUk7WUFDZixlQUFlLEVBQUUsS0FBSztZQUN0QixrQkFBa0IsRUFBRSxPQUFPO1NBQzlCLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFYSxrQkFBVSxHQUF4QixVQUF5QixJQUFZO1FBQ2pDLENBQUMsQ0FBQyxLQUFLLENBQUM7WUFDSixPQUFPLEVBQUUsT0FBTztZQUNoQixJQUFJLEVBQUUsSUFBSTtZQUNWLFFBQVEsRUFBRSxhQUFhO1lBQ3ZCLFFBQVEsRUFBRSxTQUFTO1lBQ25CLFNBQVMsRUFBRSxJQUFJO1lBQ2YsZUFBZSxFQUFFLEtBQUs7WUFDdEIsa0JBQWtCLEVBQUUsT0FBTztTQUM5QixDQUFDLENBQUM7SUFDUCxDQUFDO0lBQ0wsY0FBQztBQUFELENBN0RBLEFBNkRDLElBQUE7QUE3RFksMEJBQU8iLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvKipcbiAqIEZpbmdlcnByaW50SlMgdjMuMy42IC0gQ29weXJpZ2h0IChjKSBGaW5nZXJwcmludEpTLCBJbmMsIDIwMjIgKGh0dHBzOi8vZmluZ2VycHJpbnQuY29tKVxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCAoaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHApIGxpY2Vuc2UuXG4gKlxuICogVGhpcyBzb2Z0d2FyZSBjb250YWlucyBjb2RlIGZyb20gb3Blbi1zb3VyY2UgcHJvamVjdHM6XG4gKiBNdXJtdXJIYXNoMyBieSBLYXJhbiBMeW9ucyAoaHR0cHM6Ly9naXRodWIuY29tL2thcmFubHlvbnMvbXVybXVySGFzaDMuanMpXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgdHNsaWIgPSByZXF1aXJlKCd0c2xpYicpO1xuXG52YXIgdmVyc2lvbiA9IFwiMy4zLjZcIjtcblxuZnVuY3Rpb24gd2FpdChkdXJhdGlvbk1zLCByZXNvbHZlV2l0aCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXR1cm4gc2V0VGltZW91dChyZXNvbHZlLCBkdXJhdGlvbk1zLCByZXNvbHZlV2l0aCk7IH0pO1xufVxuZnVuY3Rpb24gcmVxdWVzdElkbGVDYWxsYmFja0lmQXZhaWxhYmxlKGZhbGxiYWNrVGltZW91dCwgZGVhZGxpbmVUaW1lb3V0KSB7XG4gICAgaWYgKGRlYWRsaW5lVGltZW91dCA9PT0gdm9pZCAwKSB7IGRlYWRsaW5lVGltZW91dCA9IEluZmluaXR5OyB9XG4gICAgdmFyIHJlcXVlc3RJZGxlQ2FsbGJhY2sgPSB3aW5kb3cucmVxdWVzdElkbGVDYWxsYmFjaztcbiAgICBpZiAocmVxdWVzdElkbGVDYWxsYmFjaykge1xuICAgICAgICAvLyBUaGUgZnVuY3Rpb24gYHJlcXVlc3RJZGxlQ2FsbGJhY2tgIGxvc2VzIHRoZSBiaW5kaW5nIHRvIGB3aW5kb3dgIGhlcmUuXG4gICAgICAgIC8vIGBnbG9iYWxUaGlzYCBpc24ndCBhbHdheXMgZXF1YWwgYHdpbmRvd2AgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9maW5nZXJwcmludGpzL2lzc3Vlcy82ODMpLlxuICAgICAgICAvLyBUaGVyZWZvcmUsIGFuIGVycm9yIGNhbiBvY2N1ci4gYGNhbGwod2luZG93LGAgcHJldmVudHMgdGhlIGVycm9yLlxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmV0dXJuIHJlcXVlc3RJZGxlQ2FsbGJhY2suY2FsbCh3aW5kb3csIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJlc29sdmUoKTsgfSwgeyB0aW1lb3V0OiBkZWFkbGluZVRpbWVvdXQgfSk7IH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHdhaXQoTWF0aC5taW4oZmFsbGJhY2tUaW1lb3V0LCBkZWFkbGluZVRpbWVvdXQpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBpc1Byb21pc2UodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbic7XG59XG4vKipcbiAqIENhbGxzIGEgbWF5YmUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uIHdpdGhvdXQgY3JlYXRpbmcgbWljcm90YXNrcyB3aGVuIHRoZSBmdW5jdGlvbiBpcyBzeW5jaHJvbm91cy5cbiAqIENhdGNoZXMgZXJyb3JzIGluIGJvdGggY2FzZXMuXG4gKlxuICogSWYganVzdCB5b3UgcnVuIGEgY29kZSBsaWtlIHRoaXM6XG4gKiBgYGBcbiAqIGNvbnNvbGUudGltZSgnQWN0aW9uIGR1cmF0aW9uJylcbiAqIGF3YWl0IGFjdGlvbigpXG4gKiBjb25zb2xlLnRpbWVFbmQoJ0FjdGlvbiBkdXJhdGlvbicpXG4gKiBgYGBcbiAqIFRoZSBzeW5jaHJvbm91cyBmdW5jdGlvbiB0aW1lIGNhbiBiZSBtZWFzdXJlZCBpbmNvcnJlY3RseSBiZWNhdXNlIGFub3RoZXIgbWljcm90YXNrIG1heSBydW4gYmVmb3JlIHRoZSBgYXdhaXRgXG4gKiByZXR1cm5zIHRoZSBjb250cm9sIGJhY2sgdG8gdGhlIGNvZGUuXG4gKi9cbmZ1bmN0aW9uIGF3YWl0SWZBc3luYyhhY3Rpb24sIGNhbGxiYWNrKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgdmFyIHJldHVybmVkVmFsdWUgPSBhY3Rpb24oKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShyZXR1cm5lZFZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuZWRWYWx1ZS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHsgcmV0dXJuIGNhbGxiYWNrKHRydWUsIHJlc3VsdCk7IH0sIGZ1bmN0aW9uIChlcnJvcikgeyByZXR1cm4gY2FsbGJhY2soZmFsc2UsIGVycm9yKTsgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjYWxsYmFjayh0cnVlLCByZXR1cm5lZFZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY2FsbGJhY2soZmFsc2UsIGVycm9yKTtcbiAgICB9XG59XG4vKipcbiAqIElmIHlvdSBydW4gbWFueSBzeW5jaHJvbm91cyB0YXNrcyB3aXRob3V0IHVzaW5nIHRoaXMgZnVuY3Rpb24sIHRoZSBKUyBtYWluIGxvb3Agd2lsbCBiZSBidXN5IGFuZCBhc3luY2hyb25vdXMgdGFza3NcbiAqIChlLmcuIGNvbXBsZXRpbmcgYSBuZXR3b3JrIHJlcXVlc3QsIHJlbmRlcmluZyB0aGUgcGFnZSkgd29uJ3QgYmUgYWJsZSB0byBoYXBwZW4uXG4gKiBUaGlzIGZ1bmN0aW9uIGFsbG93cyBydW5uaW5nIG1hbnkgc3luY2hyb25vdXMgdGFza3Mgc3VjaCB3YXkgdGhhdCBhc3luY2hyb25vdXMgdGFza3MgY2FuIHJ1biB0b28gaW4gYmFja2dyb3VuZC5cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaFdpdGhCcmVha3MoaXRlbXMsIGNhbGxiYWNrLCBsb29wUmVsZWFzZUludGVydmFsKSB7XG4gICAgaWYgKGxvb3BSZWxlYXNlSW50ZXJ2YWwgPT09IHZvaWQgMCkgeyBsb29wUmVsZWFzZUludGVydmFsID0gMTY7IH1cbiAgICByZXR1cm4gdHNsaWIuX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYXN0TG9vcFJlbGVhc2VUaW1lLCBpLCBub3c7XG4gICAgICAgIHJldHVybiB0c2xpYi5fX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgIGxhc3RMb29wUmVsZWFzZVRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgICAgICBpID0gMDtcbiAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAxO1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoaSA8IGl0ZW1zLmxlbmd0aCkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDRdO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhpdGVtc1tpXSwgaSk7XG4gICAgICAgICAgICAgICAgICAgIG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG5vdyA+PSBsYXN0TG9vcFJlbGVhc2VUaW1lICsgbG9vcFJlbGVhc2VJbnRlcnZhbCkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDNdO1xuICAgICAgICAgICAgICAgICAgICBsYXN0TG9vcFJlbGVhc2VUaW1lID0gbm93O1xuICAgICAgICAgICAgICAgICAgICAvLyBBbGxvd3MgYXN5bmNocm9ub3VzIGFjdGlvbnMgYW5kIG1pY3JvdGFza3MgdG8gaGFwcGVuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHdhaXQoMCldO1xuICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgLy8gQWxsb3dzIGFzeW5jaHJvbm91cyBhY3Rpb25zIGFuZCBtaWNyb3Rhc2tzIHRvIGhhcHBlblxuICAgICAgICAgICAgICAgICAgICBfYS5zZW50KCk7XG4gICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMztcbiAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgICsraTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFszIC8qYnJlYWsqLywgMV07XG4gICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gWzIgLypyZXR1cm4qL107XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuLyoqXG4gKiBNYWtlcyB0aGUgZ2l2ZW4gcHJvbWlzZSBuZXZlciBlbWl0IGFuIHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbiBjb25zb2xlIHdhcm5pbmcuXG4gKiBUaGUgcHJvbWlzZSB3aWxsIHN0aWxsIHBhc3MgZXJyb3JzIHRvIHRoZSBuZXh0IHByb21pc2VzLlxuICpcbiAqIE90aGVyd2lzZSwgcHJvbWlzZSBlbWl0cyBhIGNvbnNvbGUgd2FybmluZyB1bmxlc3MgaXQgaGFzIGEgYGNhdGNoYCBsaXN0ZW5lci5cbiAqL1xuZnVuY3Rpb24gc3VwcHJlc3NVbmhhbmRsZWRSZWplY3Rpb25XYXJuaW5nKHByb21pc2UpIHtcbiAgICBwcm9taXNlLnRoZW4odW5kZWZpbmVkLCBmdW5jdGlvbiAoKSB7IHJldHVybiB1bmRlZmluZWQ7IH0pO1xufVxuXG4vKlxuICogVGFrZW4gZnJvbSBodHRwczovL2dpdGh1Yi5jb20va2FyYW5seW9ucy9tdXJtdXJIYXNoMy5qcy9ibG9iL2EzM2QwNzIzMTI3ZTJlNTQxNTA1NmM0NTVmOGFlZDI0NTFhY2UyMDgvbXVybXVySGFzaDMuanNcbiAqL1xuLy9cbi8vIEdpdmVuIHR3byA2NGJpdCBpbnRzIChhcyBhbiBhcnJheSBvZiB0d28gMzJiaXQgaW50cykgcmV0dXJucyB0aGUgdHdvXG4vLyBhZGRlZCB0b2dldGhlciBhcyBhIDY0Yml0IGludCAoYXMgYW4gYXJyYXkgb2YgdHdvIDMyYml0IGludHMpLlxuLy9cbmZ1bmN0aW9uIHg2NEFkZChtLCBuKSB7XG4gICAgbSA9IFttWzBdID4+PiAxNiwgbVswXSAmIDB4ZmZmZiwgbVsxXSA+Pj4gMTYsIG1bMV0gJiAweGZmZmZdO1xuICAgIG4gPSBbblswXSA+Pj4gMTYsIG5bMF0gJiAweGZmZmYsIG5bMV0gPj4+IDE2LCBuWzFdICYgMHhmZmZmXTtcbiAgICB2YXIgbyA9IFswLCAwLCAwLCAwXTtcbiAgICBvWzNdICs9IG1bM10gKyBuWzNdO1xuICAgIG9bMl0gKz0gb1szXSA+Pj4gMTY7XG4gICAgb1szXSAmPSAweGZmZmY7XG4gICAgb1syXSArPSBtWzJdICsgblsyXTtcbiAgICBvWzFdICs9IG9bMl0gPj4+IDE2O1xuICAgIG9bMl0gJj0gMHhmZmZmO1xuICAgIG9bMV0gKz0gbVsxXSArIG5bMV07XG4gICAgb1swXSArPSBvWzFdID4+PiAxNjtcbiAgICBvWzFdICY9IDB4ZmZmZjtcbiAgICBvWzBdICs9IG1bMF0gKyBuWzBdO1xuICAgIG9bMF0gJj0gMHhmZmZmO1xuICAgIHJldHVybiBbKG9bMF0gPDwgMTYpIHwgb1sxXSwgKG9bMl0gPDwgMTYpIHwgb1szXV07XG59XG4vL1xuLy8gR2l2ZW4gdHdvIDY0Yml0IGludHMgKGFzIGFuIGFycmF5IG9mIHR3byAzMmJpdCBpbnRzKSByZXR1cm5zIHRoZSB0d29cbi8vIG11bHRpcGxpZWQgdG9nZXRoZXIgYXMgYSA2NGJpdCBpbnQgKGFzIGFuIGFycmF5IG9mIHR3byAzMmJpdCBpbnRzKS5cbi8vXG5mdW5jdGlvbiB4NjRNdWx0aXBseShtLCBuKSB7XG4gICAgbSA9IFttWzBdID4+PiAxNiwgbVswXSAmIDB4ZmZmZiwgbVsxXSA+Pj4gMTYsIG1bMV0gJiAweGZmZmZdO1xuICAgIG4gPSBbblswXSA+Pj4gMTYsIG5bMF0gJiAweGZmZmYsIG5bMV0gPj4+IDE2LCBuWzFdICYgMHhmZmZmXTtcbiAgICB2YXIgbyA9IFswLCAwLCAwLCAwXTtcbiAgICBvWzNdICs9IG1bM10gKiBuWzNdO1xuICAgIG9bMl0gKz0gb1szXSA+Pj4gMTY7XG4gICAgb1szXSAmPSAweGZmZmY7XG4gICAgb1syXSArPSBtWzJdICogblszXTtcbiAgICBvWzFdICs9IG9bMl0gPj4+IDE2O1xuICAgIG9bMl0gJj0gMHhmZmZmO1xuICAgIG9bMl0gKz0gbVszXSAqIG5bMl07XG4gICAgb1sxXSArPSBvWzJdID4+PiAxNjtcbiAgICBvWzJdICY9IDB4ZmZmZjtcbiAgICBvWzFdICs9IG1bMV0gKiBuWzNdO1xuICAgIG9bMF0gKz0gb1sxXSA+Pj4gMTY7XG4gICAgb1sxXSAmPSAweGZmZmY7XG4gICAgb1sxXSArPSBtWzJdICogblsyXTtcbiAgICBvWzBdICs9IG9bMV0gPj4+IDE2O1xuICAgIG9bMV0gJj0gMHhmZmZmO1xuICAgIG9bMV0gKz0gbVszXSAqIG5bMV07XG4gICAgb1swXSArPSBvWzFdID4+PiAxNjtcbiAgICBvWzFdICY9IDB4ZmZmZjtcbiAgICBvWzBdICs9IG1bMF0gKiBuWzNdICsgbVsxXSAqIG5bMl0gKyBtWzJdICogblsxXSArIG1bM10gKiBuWzBdO1xuICAgIG9bMF0gJj0gMHhmZmZmO1xuICAgIHJldHVybiBbKG9bMF0gPDwgMTYpIHwgb1sxXSwgKG9bMl0gPDwgMTYpIHwgb1szXV07XG59XG4vL1xuLy8gR2l2ZW4gYSA2NGJpdCBpbnQgKGFzIGFuIGFycmF5IG9mIHR3byAzMmJpdCBpbnRzKSBhbmQgYW4gaW50XG4vLyByZXByZXNlbnRpbmcgYSBudW1iZXIgb2YgYml0IHBvc2l0aW9ucywgcmV0dXJucyB0aGUgNjRiaXQgaW50IChhcyBhblxuLy8gYXJyYXkgb2YgdHdvIDMyYml0IGludHMpIHJvdGF0ZWQgbGVmdCBieSB0aGF0IG51bWJlciBvZiBwb3NpdGlvbnMuXG4vL1xuZnVuY3Rpb24geDY0Um90bChtLCBuKSB7XG4gICAgbiAlPSA2NDtcbiAgICBpZiAobiA9PT0gMzIpIHtcbiAgICAgICAgcmV0dXJuIFttWzFdLCBtWzBdXTtcbiAgICB9XG4gICAgZWxzZSBpZiAobiA8IDMyKSB7XG4gICAgICAgIHJldHVybiBbKG1bMF0gPDwgbikgfCAobVsxXSA+Pj4gKDMyIC0gbikpLCAobVsxXSA8PCBuKSB8IChtWzBdID4+PiAoMzIgLSBuKSldO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbiAtPSAzMjtcbiAgICAgICAgcmV0dXJuIFsobVsxXSA8PCBuKSB8IChtWzBdID4+PiAoMzIgLSBuKSksIChtWzBdIDw8IG4pIHwgKG1bMV0gPj4+ICgzMiAtIG4pKV07XG4gICAgfVxufVxuLy9cbi8vIEdpdmVuIGEgNjRiaXQgaW50IChhcyBhbiBhcnJheSBvZiB0d28gMzJiaXQgaW50cykgYW5kIGFuIGludFxuLy8gcmVwcmVzZW50aW5nIGEgbnVtYmVyIG9mIGJpdCBwb3NpdGlvbnMsIHJldHVybnMgdGhlIDY0Yml0IGludCAoYXMgYW5cbi8vIGFycmF5IG9mIHR3byAzMmJpdCBpbnRzKSBzaGlmdGVkIGxlZnQgYnkgdGhhdCBudW1iZXIgb2YgcG9zaXRpb25zLlxuLy9cbmZ1bmN0aW9uIHg2NExlZnRTaGlmdChtLCBuKSB7XG4gICAgbiAlPSA2NDtcbiAgICBpZiAobiA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbTtcbiAgICB9XG4gICAgZWxzZSBpZiAobiA8IDMyKSB7XG4gICAgICAgIHJldHVybiBbKG1bMF0gPDwgbikgfCAobVsxXSA+Pj4gKDMyIC0gbikpLCBtWzFdIDw8IG5dO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFttWzFdIDw8IChuIC0gMzIpLCAwXTtcbiAgICB9XG59XG4vL1xuLy8gR2l2ZW4gdHdvIDY0Yml0IGludHMgKGFzIGFuIGFycmF5IG9mIHR3byAzMmJpdCBpbnRzKSByZXR1cm5zIHRoZSB0d29cbi8vIHhvcmVkIHRvZ2V0aGVyIGFzIGEgNjRiaXQgaW50IChhcyBhbiBhcnJheSBvZiB0d28gMzJiaXQgaW50cykuXG4vL1xuZnVuY3Rpb24geDY0WG9yKG0sIG4pIHtcbiAgICByZXR1cm4gW21bMF0gXiBuWzBdLCBtWzFdIF4gblsxXV07XG59XG4vL1xuLy8gR2l2ZW4gYSBibG9jaywgcmV0dXJucyBtdXJtdXJIYXNoMydzIGZpbmFsIHg2NCBtaXggb2YgdGhhdCBibG9jay5cbi8vIChgWzAsIGhbMF0gPj4+IDFdYCBpcyBhIDMzIGJpdCB1bnNpZ25lZCByaWdodCBzaGlmdC4gVGhpcyBpcyB0aGVcbi8vIG9ubHkgcGxhY2Ugd2hlcmUgd2UgbmVlZCB0byByaWdodCBzaGlmdCA2NGJpdCBpbnRzLilcbi8vXG5mdW5jdGlvbiB4NjRGbWl4KGgpIHtcbiAgICBoID0geDY0WG9yKGgsIFswLCBoWzBdID4+PiAxXSk7XG4gICAgaCA9IHg2NE11bHRpcGx5KGgsIFsweGZmNTFhZmQ3LCAweGVkNTU4Y2NkXSk7XG4gICAgaCA9IHg2NFhvcihoLCBbMCwgaFswXSA+Pj4gMV0pO1xuICAgIGggPSB4NjRNdWx0aXBseShoLCBbMHhjNGNlYjlmZSwgMHgxYTg1ZWM1M10pO1xuICAgIGggPSB4NjRYb3IoaCwgWzAsIGhbMF0gPj4+IDFdKTtcbiAgICByZXR1cm4gaDtcbn1cbi8vXG4vLyBHaXZlbiBhIHN0cmluZyBhbmQgYW4gb3B0aW9uYWwgc2VlZCBhcyBhbiBpbnQsIHJldHVybnMgYSAxMjggYml0XG4vLyBoYXNoIHVzaW5nIHRoZSB4NjQgZmxhdm9yIG9mIE11cm11ckhhc2gzLCBhcyBhbiB1bnNpZ25lZCBoZXguXG4vL1xuZnVuY3Rpb24geDY0aGFzaDEyOChrZXksIHNlZWQpIHtcbiAgICBrZXkgPSBrZXkgfHwgJyc7XG4gICAgc2VlZCA9IHNlZWQgfHwgMDtcbiAgICB2YXIgcmVtYWluZGVyID0ga2V5Lmxlbmd0aCAlIDE2O1xuICAgIHZhciBieXRlcyA9IGtleS5sZW5ndGggLSByZW1haW5kZXI7XG4gICAgdmFyIGgxID0gWzAsIHNlZWRdO1xuICAgIHZhciBoMiA9IFswLCBzZWVkXTtcbiAgICB2YXIgazEgPSBbMCwgMF07XG4gICAgdmFyIGsyID0gWzAsIDBdO1xuICAgIHZhciBjMSA9IFsweDg3YzM3YjkxLCAweDExNDI1M2Q1XTtcbiAgICB2YXIgYzIgPSBbMHg0Y2Y1YWQ0MywgMHgyNzQ1OTM3Zl07XG4gICAgdmFyIGk7XG4gICAgZm9yIChpID0gMDsgaSA8IGJ5dGVzOyBpID0gaSArIDE2KSB7XG4gICAgICAgIGsxID0gW1xuICAgICAgICAgICAgKGtleS5jaGFyQ29kZUF0KGkgKyA0KSAmIDB4ZmYpIHxcbiAgICAgICAgICAgICAgICAoKGtleS5jaGFyQ29kZUF0KGkgKyA1KSAmIDB4ZmYpIDw8IDgpIHxcbiAgICAgICAgICAgICAgICAoKGtleS5jaGFyQ29kZUF0KGkgKyA2KSAmIDB4ZmYpIDw8IDE2KSB8XG4gICAgICAgICAgICAgICAgKChrZXkuY2hhckNvZGVBdChpICsgNykgJiAweGZmKSA8PCAyNCksXG4gICAgICAgICAgICAoa2V5LmNoYXJDb2RlQXQoaSkgJiAweGZmKSB8XG4gICAgICAgICAgICAgICAgKChrZXkuY2hhckNvZGVBdChpICsgMSkgJiAweGZmKSA8PCA4KSB8XG4gICAgICAgICAgICAgICAgKChrZXkuY2hhckNvZGVBdChpICsgMikgJiAweGZmKSA8PCAxNikgfFxuICAgICAgICAgICAgICAgICgoa2V5LmNoYXJDb2RlQXQoaSArIDMpICYgMHhmZikgPDwgMjQpLFxuICAgICAgICBdO1xuICAgICAgICBrMiA9IFtcbiAgICAgICAgICAgIChrZXkuY2hhckNvZGVBdChpICsgMTIpICYgMHhmZikgfFxuICAgICAgICAgICAgICAgICgoa2V5LmNoYXJDb2RlQXQoaSArIDEzKSAmIDB4ZmYpIDw8IDgpIHxcbiAgICAgICAgICAgICAgICAoKGtleS5jaGFyQ29kZUF0KGkgKyAxNCkgJiAweGZmKSA8PCAxNikgfFxuICAgICAgICAgICAgICAgICgoa2V5LmNoYXJDb2RlQXQoaSArIDE1KSAmIDB4ZmYpIDw8IDI0KSxcbiAgICAgICAgICAgIChrZXkuY2hhckNvZGVBdChpICsgOCkgJiAweGZmKSB8XG4gICAgICAgICAgICAgICAgKChrZXkuY2hhckNvZGVBdChpICsgOSkgJiAweGZmKSA8PCA4KSB8XG4gICAgICAgICAgICAgICAgKChrZXkuY2hhckNvZGVBdChpICsgMTApICYgMHhmZikgPDwgMTYpIHxcbiAgICAgICAgICAgICAgICAoKGtleS5jaGFyQ29kZUF0KGkgKyAxMSkgJiAweGZmKSA8PCAyNCksXG4gICAgICAgIF07XG4gICAgICAgIGsxID0geDY0TXVsdGlwbHkoazEsIGMxKTtcbiAgICAgICAgazEgPSB4NjRSb3RsKGsxLCAzMSk7XG4gICAgICAgIGsxID0geDY0TXVsdGlwbHkoazEsIGMyKTtcbiAgICAgICAgaDEgPSB4NjRYb3IoaDEsIGsxKTtcbiAgICAgICAgaDEgPSB4NjRSb3RsKGgxLCAyNyk7XG4gICAgICAgIGgxID0geDY0QWRkKGgxLCBoMik7XG4gICAgICAgIGgxID0geDY0QWRkKHg2NE11bHRpcGx5KGgxLCBbMCwgNV0pLCBbMCwgMHg1MmRjZTcyOV0pO1xuICAgICAgICBrMiA9IHg2NE11bHRpcGx5KGsyLCBjMik7XG4gICAgICAgIGsyID0geDY0Um90bChrMiwgMzMpO1xuICAgICAgICBrMiA9IHg2NE11bHRpcGx5KGsyLCBjMSk7XG4gICAgICAgIGgyID0geDY0WG9yKGgyLCBrMik7XG4gICAgICAgIGgyID0geDY0Um90bChoMiwgMzEpO1xuICAgICAgICBoMiA9IHg2NEFkZChoMiwgaDEpO1xuICAgICAgICBoMiA9IHg2NEFkZCh4NjRNdWx0aXBseShoMiwgWzAsIDVdKSwgWzAsIDB4Mzg0OTVhYjVdKTtcbiAgICB9XG4gICAgazEgPSBbMCwgMF07XG4gICAgazIgPSBbMCwgMF07XG4gICAgc3dpdGNoIChyZW1haW5kZXIpIHtcbiAgICAgICAgY2FzZSAxNTpcbiAgICAgICAgICAgIGsyID0geDY0WG9yKGsyLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyAxNCldLCA0OCkpO1xuICAgICAgICAvLyBmYWxsdGhyb3VnaFxuICAgICAgICBjYXNlIDE0OlxuICAgICAgICAgICAgazIgPSB4NjRYb3IoazIsIHg2NExlZnRTaGlmdChbMCwga2V5LmNoYXJDb2RlQXQoaSArIDEzKV0sIDQwKSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgMTM6XG4gICAgICAgICAgICBrMiA9IHg2NFhvcihrMiwgeDY0TGVmdFNoaWZ0KFswLCBrZXkuY2hhckNvZGVBdChpICsgMTIpXSwgMzIpKTtcbiAgICAgICAgLy8gZmFsbHRocm91Z2hcbiAgICAgICAgY2FzZSAxMjpcbiAgICAgICAgICAgIGsyID0geDY0WG9yKGsyLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyAxMSldLCAyNCkpO1xuICAgICAgICAvLyBmYWxsdGhyb3VnaFxuICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgazIgPSB4NjRYb3IoazIsIHg2NExlZnRTaGlmdChbMCwga2V5LmNoYXJDb2RlQXQoaSArIDEwKV0sIDE2KSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICBrMiA9IHg2NFhvcihrMiwgeDY0TGVmdFNoaWZ0KFswLCBrZXkuY2hhckNvZGVBdChpICsgOSldLCA4KSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgOTpcbiAgICAgICAgICAgIGsyID0geDY0WG9yKGsyLCBbMCwga2V5LmNoYXJDb2RlQXQoaSArIDgpXSk7XG4gICAgICAgICAgICBrMiA9IHg2NE11bHRpcGx5KGsyLCBjMik7XG4gICAgICAgICAgICBrMiA9IHg2NFJvdGwoazIsIDMzKTtcbiAgICAgICAgICAgIGsyID0geDY0TXVsdGlwbHkoazIsIGMxKTtcbiAgICAgICAgICAgIGgyID0geDY0WG9yKGgyLCBrMik7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgIGsxID0geDY0WG9yKGsxLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyA3KV0sIDU2KSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgIGsxID0geDY0WG9yKGsxLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyA2KV0sIDQ4KSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgIGsxID0geDY0WG9yKGsxLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyA1KV0sIDQwKSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgIGsxID0geDY0WG9yKGsxLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyA0KV0sIDMyKSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgIGsxID0geDY0WG9yKGsxLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyAzKV0sIDI0KSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgIGsxID0geDY0WG9yKGsxLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyAyKV0sIDE2KSk7XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIGsxID0geDY0WG9yKGsxLCB4NjRMZWZ0U2hpZnQoWzAsIGtleS5jaGFyQ29kZUF0KGkgKyAxKV0sIDgpKTtcbiAgICAgICAgLy8gZmFsbHRocm91Z2hcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgazEgPSB4NjRYb3IoazEsIFswLCBrZXkuY2hhckNvZGVBdChpKV0pO1xuICAgICAgICAgICAgazEgPSB4NjRNdWx0aXBseShrMSwgYzEpO1xuICAgICAgICAgICAgazEgPSB4NjRSb3RsKGsxLCAzMSk7XG4gICAgICAgICAgICBrMSA9IHg2NE11bHRpcGx5KGsxLCBjMik7XG4gICAgICAgICAgICBoMSA9IHg2NFhvcihoMSwgazEpO1xuICAgICAgICAvLyBmYWxsdGhyb3VnaFxuICAgIH1cbiAgICBoMSA9IHg2NFhvcihoMSwgWzAsIGtleS5sZW5ndGhdKTtcbiAgICBoMiA9IHg2NFhvcihoMiwgWzAsIGtleS5sZW5ndGhdKTtcbiAgICBoMSA9IHg2NEFkZChoMSwgaDIpO1xuICAgIGgyID0geDY0QWRkKGgyLCBoMSk7XG4gICAgaDEgPSB4NjRGbWl4KGgxKTtcbiAgICBoMiA9IHg2NEZtaXgoaDIpO1xuICAgIGgxID0geDY0QWRkKGgxLCBoMik7XG4gICAgaDIgPSB4NjRBZGQoaDIsIGgxKTtcbiAgICByZXR1cm4gKCgnMDAwMDAwMDAnICsgKGgxWzBdID4+PiAwKS50b1N0cmluZygxNikpLnNsaWNlKC04KSArXG4gICAgICAgICgnMDAwMDAwMDAnICsgKGgxWzFdID4+PiAwKS50b1N0cmluZygxNikpLnNsaWNlKC04KSArXG4gICAgICAgICgnMDAwMDAwMDAnICsgKGgyWzBdID4+PiAwKS50b1N0cmluZygxNikpLnNsaWNlKC04KSArXG4gICAgICAgICgnMDAwMDAwMDAnICsgKGgyWzFdID4+PiAwKS50b1N0cmluZygxNikpLnNsaWNlKC04KSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYW4gZXJyb3Igb2JqZWN0IHRvIGEgcGxhaW4gb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgd2l0aCBgSlNPTi5zdHJpbmdpZnlgLlxuICogSWYgeW91IGp1c3QgcnVuIGBKU09OLnN0cmluZ2lmeShlcnJvcilgLCB5b3UnbGwgZ2V0IGAne30nYC5cbiAqL1xuZnVuY3Rpb24gZXJyb3JUb09iamVjdChlcnJvcikge1xuICAgIHZhciBfYTtcbiAgICByZXR1cm4gdHNsaWIuX19hc3NpZ24oeyBuYW1lOiBlcnJvci5uYW1lLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLCBzdGFjazogKF9hID0gZXJyb3Iuc3RhY2spID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5zcGxpdCgnXFxuJykgfSwgZXJyb3IpO1xufVxuXG4vKlxuICogVGhpcyBmaWxlIGNvbnRhaW5zIGZ1bmN0aW9ucyB0byB3b3JrIHdpdGggcHVyZSBkYXRhIG9ubHkgKG5vIGJyb3dzZXIgZmVhdHVyZXMsIERPTSwgc2lkZSBlZmZlY3RzLCBldGMpLlxuICovXG4vKipcbiAqIERvZXMgdGhlIHNhbWUgYXMgQXJyYXkucHJvdG90eXBlLmluY2x1ZGVzIGJ1dCBoYXMgYmV0dGVyIHR5cGluZ1xuICovXG5mdW5jdGlvbiBpbmNsdWRlcyhoYXlzdGFjaywgbmVlZGxlKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBoYXlzdGFjay5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgaWYgKGhheXN0YWNrW2ldID09PSBuZWVkbGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8qKlxuICogTGlrZSBgIWluY2x1ZGVzKClgIGJ1dCB3aXRoIHByb3BlciB0eXBpbmdcbiAqL1xuZnVuY3Rpb24gZXhjbHVkZXMoaGF5c3RhY2ssIG5lZWRsZSkge1xuICAgIHJldHVybiAhaW5jbHVkZXMoaGF5c3RhY2ssIG5lZWRsZSk7XG59XG4vKipcbiAqIEJlIGNhcmVmdWwsIE5hTiBjYW4gcmV0dXJuXG4gKi9cbmZ1bmN0aW9uIHRvSW50KHZhbHVlKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlKTtcbn1cbi8qKlxuICogQmUgY2FyZWZ1bCwgTmFOIGNhbiByZXR1cm5cbiAqL1xuZnVuY3Rpb24gdG9GbG9hdCh2YWx1ZSkge1xuICAgIHJldHVybiBwYXJzZUZsb2F0KHZhbHVlKTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VOYU4odmFsdWUsIHJlcGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgaXNOYU4odmFsdWUpID8gcmVwbGFjZW1lbnQgOiB2YWx1ZTtcbn1cbmZ1bmN0aW9uIGNvdW50VHJ1dGh5KHZhbHVlcykge1xuICAgIHJldHVybiB2YWx1ZXMucmVkdWNlKGZ1bmN0aW9uIChzdW0sIHZhbHVlKSB7IHJldHVybiBzdW0gKyAodmFsdWUgPyAxIDogMCk7IH0sIDApO1xufVxuZnVuY3Rpb24gcm91bmQodmFsdWUsIGJhc2UpIHtcbiAgICBpZiAoYmFzZSA9PT0gdm9pZCAwKSB7IGJhc2UgPSAxOyB9XG4gICAgaWYgKE1hdGguYWJzKGJhc2UpID49IDEpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQodmFsdWUgLyBiYXNlKSAqIGJhc2U7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyBTb21ldGltZXMgd2hlbiBhIG51bWJlciBpcyBtdWx0aXBsaWVkIGJ5IGEgc21hbGwgbnVtYmVyLCBwcmVjaXNpb24gaXMgbG9zdCxcbiAgICAgICAgLy8gZm9yIGV4YW1wbGUgMTIzNCAqIDAuMDAwMSA9PT0gMC4xMjM0MDAwMDAwMDAwMDAwMSwgYW5kIGl0J3MgbW9yZSBwcmVjaXNlIGRpdmlkZTogMTIzNCAvICgxIC8gMC4wMDAxKSA9PT0gMC4xMjM0LlxuICAgICAgICB2YXIgY291bnRlckJhc2UgPSAxIC8gYmFzZTtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQodmFsdWUgKiBjb3VudGVyQmFzZSkgLyBjb3VudGVyQmFzZTtcbiAgICB9XG59XG4vKipcbiAqIFBhcnNlcyBhIENTUyBzZWxlY3RvciBpbnRvIHRhZyBuYW1lIHdpdGggSFRNTCBhdHRyaWJ1dGVzLlxuICogT25seSBzaW5nbGUgZWxlbWVudCBzZWxlY3RvciBhcmUgc3VwcG9ydGVkICh3aXRob3V0IG9wZXJhdG9ycyBsaWtlIHNwYWNlLCArLCA+LCBldGMpLlxuICpcbiAqIE11bHRpcGxlIHZhbHVlcyBjYW4gYmUgcmV0dXJuZWQgZm9yIGVhY2ggYXR0cmlidXRlLiBZb3UgZGVjaWRlIGhvdyB0byBoYW5kbGUgdGhlbS5cbiAqL1xuZnVuY3Rpb24gcGFyc2VTaW1wbGVDc3NTZWxlY3RvcihzZWxlY3Rvcikge1xuICAgIHZhciBfYSwgX2I7XG4gICAgdmFyIGVycm9yTWVzc2FnZSA9IFwiVW5leHBlY3RlZCBzeW50YXggJ1wiICsgc2VsZWN0b3IgKyBcIidcIjtcbiAgICB2YXIgdGFnTWF0Y2ggPSAvXlxccyooW2Etei1dKikoLiopJC9pLmV4ZWMoc2VsZWN0b3IpO1xuICAgIHZhciB0YWcgPSB0YWdNYXRjaFsxXSB8fCB1bmRlZmluZWQ7XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSB7fTtcbiAgICB2YXIgcGFydHNSZWdleCA9IC8oWy46I11bXFx3LV0rfFxcWy4rP1xcXSkvZ2k7XG4gICAgdmFyIGFkZEF0dHJpYnV0ZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgICAgICBhdHRyaWJ1dGVzW25hbWVdID0gYXR0cmlidXRlc1tuYW1lXSB8fCBbXTtcbiAgICAgICAgYXR0cmlidXRlc1tuYW1lXS5wdXNoKHZhbHVlKTtcbiAgICB9O1xuICAgIGZvciAoOzspIHtcbiAgICAgICAgdmFyIG1hdGNoID0gcGFydHNSZWdleC5leGVjKHRhZ01hdGNoWzJdKTtcbiAgICAgICAgaWYgKCFtYXRjaCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHBhcnQgPSBtYXRjaFswXTtcbiAgICAgICAgc3dpdGNoIChwYXJ0WzBdKSB7XG4gICAgICAgICAgICBjYXNlICcuJzpcbiAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoJ2NsYXNzJywgcGFydC5zbGljZSgxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICcjJzpcbiAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoJ2lkJywgcGFydC5zbGljZSgxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdbJzoge1xuICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVNYXRjaCA9IC9eXFxbKFtcXHctXSspKFt+fF4kKl0/PShcIiguKj8pXCJ8KFtcXHctXSspKSk/KFxccytbaXNdKT9cXF0kLy5leGVjKHBhcnQpO1xuICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVNYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoYXR0cmlidXRlTWF0Y2hbMV0sIChfYiA9IChfYSA9IGF0dHJpYnV0ZU1hdGNoWzRdKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBhdHRyaWJ1dGVNYXRjaFs1XSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogJycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW3RhZywgYXR0cmlidXRlc107XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUVycm9yV2l0aE1lc3NhZ2UoZXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJiAnbWVzc2FnZScgaW4gZXJyb3IgPyBlcnJvciA6IHsgbWVzc2FnZTogZXJyb3IgfTtcbn1cbmZ1bmN0aW9uIGlzRmluYWxSZXN1bHRMb2FkZWQobG9hZFJlc3VsdCkge1xuICAgIHJldHVybiB0eXBlb2YgbG9hZFJlc3VsdCAhPT0gJ2Z1bmN0aW9uJztcbn1cbi8qKlxuICogTG9hZHMgdGhlIGdpdmVuIGVudHJvcHkgc291cmNlLiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBnZXRzIGFuIGVudHJvcHkgY29tcG9uZW50IGZyb20gdGhlIHNvdXJjZS5cbiAqXG4gKiBUaGUgcmVzdWx0IGlzIHJldHVybmVkIHN5bmNocm9ub3VzbHkgdG8gcHJldmVudCBgbG9hZFNvdXJjZXNgIGZyb21cbiAqIHdhaXRpbmcgZm9yIG9uZSBzb3VyY2UgdG8gbG9hZCBiZWZvcmUgZ2V0dGluZyB0aGUgY29tcG9uZW50cyBmcm9tIHRoZSBvdGhlciBzb3VyY2VzLlxuICovXG5mdW5jdGlvbiBsb2FkU291cmNlKHNvdXJjZSwgc291cmNlT3B0aW9ucykge1xuICAgIHZhciBzb3VyY2VMb2FkUHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlTG9hZCkge1xuICAgICAgICB2YXIgbG9hZFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIC8vIGBhd2FpdElmQXN5bmNgIGlzIHVzZWQgaW5zdGVhZCBvZiBqdXN0IGBhd2FpdGAgaW4gb3JkZXIgdG8gbWVhc3VyZSB0aGUgZHVyYXRpb24gb2Ygc3luY2hyb25vdXMgc291cmNlc1xuICAgICAgICAvLyBjb3JyZWN0bHkgKG90aGVyIG1pY3JvdGFza3Mgd29uJ3QgYWZmZWN0IHRoZSBkdXJhdGlvbikuXG4gICAgICAgIGF3YWl0SWZBc3luYyhzb3VyY2UuYmluZChudWxsLCBzb3VyY2VPcHRpb25zKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGxvYWRBcmdzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIGxvYWRBcmdzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbG9hZER1cmF0aW9uID0gRGF0ZS5ub3coKSAtIGxvYWRTdGFydFRpbWU7XG4gICAgICAgICAgICAvLyBTb3VyY2UgbG9hZGluZyBmYWlsZWRcbiAgICAgICAgICAgIGlmICghbG9hZEFyZ3NbMF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUxvYWQoZnVuY3Rpb24gKCkgeyByZXR1cm4gKHsgZXJyb3I6IGVuc3VyZUVycm9yV2l0aE1lc3NhZ2UobG9hZEFyZ3NbMV0pLCBkdXJhdGlvbjogbG9hZER1cmF0aW9uIH0pOyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBsb2FkUmVzdWx0ID0gbG9hZEFyZ3NbMV07XG4gICAgICAgICAgICAvLyBTb3VyY2UgbG9hZGVkIHdpdGggdGhlIGZpbmFsIHJlc3VsdFxuICAgICAgICAgICAgaWYgKGlzRmluYWxSZXN1bHRMb2FkZWQobG9hZFJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUxvYWQoZnVuY3Rpb24gKCkgeyByZXR1cm4gKHsgdmFsdWU6IGxvYWRSZXN1bHQsIGR1cmF0aW9uOiBsb2FkRHVyYXRpb24gfSk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU291cmNlIGxvYWRlZCB3aXRoIFwiZ2V0XCIgc3RhZ2VcbiAgICAgICAgICAgIHJlc29sdmVMb2FkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmVHZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0SWZBc3luYyhsb2FkUmVzdWx0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZ2V0QXJncyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRBcmdzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHVyYXRpb24gPSBsb2FkRHVyYXRpb24gKyBEYXRlLm5vdygpIC0gZ2V0U3RhcnRUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU291cmNlIGdldHRpbmcgZmFpbGVkXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWdldEFyZ3NbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUdldCh7IGVycm9yOiBlbnN1cmVFcnJvcldpdGhNZXNzYWdlKGdldEFyZ3NbMV0pLCBkdXJhdGlvbjogZHVyYXRpb24gfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTb3VyY2UgZ2V0dGluZyBzdWNjZWVkZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVHZXQoeyB2YWx1ZTogZ2V0QXJnc1sxXSwgZHVyYXRpb246IGR1cmF0aW9uIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBzdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbldhcm5pbmcoc291cmNlTG9hZFByb21pc2UpO1xuICAgIHJldHVybiBmdW5jdGlvbiBnZXRDb21wb25lbnQoKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2VMb2FkUHJvbWlzZS50aGVuKGZ1bmN0aW9uIChmaW5hbGl6ZVNvdXJjZSkgeyByZXR1cm4gZmluYWxpemVTb3VyY2UoKTsgfSk7XG4gICAgfTtcbn1cbi8qKlxuICogTG9hZHMgdGhlIGdpdmVuIGVudHJvcHkgc291cmNlcy4gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgY29sbGVjdHMgdGhlIGVudHJvcHkgY29tcG9uZW50cy5cbiAqXG4gKiBUaGUgcmVzdWx0IGlzIHJldHVybmVkIHN5bmNocm9ub3VzbHkgaW4gb3JkZXIgdG8gYWxsb3cgc3RhcnQgZ2V0dGluZyB0aGUgY29tcG9uZW50c1xuICogYmVmb3JlIHRoZSBzb3VyY2VzIGFyZSBsb2FkZWQgY29tcGxldGVseS5cbiAqXG4gKiBXYXJuaW5nIGZvciBwYWNrYWdlIHVzZXJzOlxuICogVGhpcyBmdW5jdGlvbiBpcyBvdXQgb2YgU2VtYW50aWMgVmVyc2lvbmluZywgaS5lLiBjYW4gY2hhbmdlIHVuZXhwZWN0ZWRseS4gVXNhZ2UgaXMgYXQgeW91ciBvd24gcmlzay5cbiAqL1xuZnVuY3Rpb24gbG9hZFNvdXJjZXMoc291cmNlcywgc291cmNlT3B0aW9ucywgZXhjbHVkZVNvdXJjZXMpIHtcbiAgICB2YXIgaW5jbHVkZWRTb3VyY2VzID0gT2JqZWN0LmtleXMoc291cmNlcykuZmlsdGVyKGZ1bmN0aW9uIChzb3VyY2VLZXkpIHsgcmV0dXJuIGV4Y2x1ZGVzKGV4Y2x1ZGVTb3VyY2VzLCBzb3VyY2VLZXkpOyB9KTtcbiAgICB2YXIgc291cmNlR2V0dGVycyA9IEFycmF5KGluY2x1ZGVkU291cmNlcy5sZW5ndGgpO1xuICAgIC8vIFVzaW5nIGBmb3JFYWNoV2l0aEJyZWFrc2AgYWxsb3dzIGFzeW5jaHJvbm91cyBzb3VyY2VzIHRvIGNvbXBsZXRlIGJldHdlZW4gc3luY2hyb25vdXMgc291cmNlc1xuICAgIC8vIGFuZCBtZWFzdXJlIHRoZSBkdXJhdGlvbiBjb3JyZWN0bHlcbiAgICBmb3JFYWNoV2l0aEJyZWFrcyhpbmNsdWRlZFNvdXJjZXMsIGZ1bmN0aW9uIChzb3VyY2VLZXksIGluZGV4KSB7XG4gICAgICAgIHNvdXJjZUdldHRlcnNbaW5kZXhdID0gbG9hZFNvdXJjZShzb3VyY2VzW3NvdXJjZUtleV0sIHNvdXJjZU9wdGlvbnMpO1xuICAgIH0pO1xuICAgIHJldHVybiBmdW5jdGlvbiBnZXRDb21wb25lbnRzKCkge1xuICAgICAgICByZXR1cm4gdHNsaWIuX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgY29tcG9uZW50cywgX2ksIGluY2x1ZGVkU291cmNlc18xLCBzb3VyY2VLZXksIGNvbXBvbmVudFByb21pc2VzLCBfbG9vcF8xLCBzdGF0ZV8xO1xuICAgICAgICAgICAgcmV0dXJuIHRzbGliLl9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50cyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChfaSA9IDAsIGluY2x1ZGVkU291cmNlc18xID0gaW5jbHVkZWRTb3VyY2VzOyBfaSA8IGluY2x1ZGVkU291cmNlc18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZUtleSA9IGluY2x1ZGVkU291cmNlc18xW19pXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRzW3NvdXJjZUtleV0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRQcm9taXNlcyA9IEFycmF5KGluY2x1ZGVkU291cmNlcy5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BfMSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFzQWxsQ29tcG9uZW50UHJvbWlzZXM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRzbGliLl9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzQWxsQ29tcG9uZW50UHJvbWlzZXMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIGZvckVhY2hXaXRoQnJlYWtzKGluY2x1ZGVkU291cmNlcywgZnVuY3Rpb24gKHNvdXJjZUtleSwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29tcG9uZW50UHJvbWlzZXNbaW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYHNvdXJjZUdldHRlcnNgIG1heSBiZSBpbmNvbXBsZXRlIGF0IHRoaXMgcG9pbnQgb2YgZXhlY3V0aW9uIGJlY2F1c2UgYGZvckVhY2hXaXRoQnJlYWtzYCBpcyBhc3luY2hyb25vdXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlR2V0dGVyc1tpbmRleF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbXBvbmVudFByb21pc2UgPSBzb3VyY2VHZXR0ZXJzW2luZGV4XSgpLnRoZW4oZnVuY3Rpb24gKGNvbXBvbmVudCkgeyByZXR1cm4gKGNvbXBvbmVudHNbc291cmNlS2V5XSA9IGNvbXBvbmVudCk7IH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbldhcm5pbmcoY29tcG9uZW50UHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFByb21pc2VzW2luZGV4XSA9IGNvbXBvbmVudFByb21pc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNBbGxDb21wb25lbnRQcm9taXNlcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hLnNlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQWxsQ29tcG9uZW50UHJvbWlzZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFwiYnJlYWtcIl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHdhaXQoMSldOyAvLyBMZXRzIHRoZSBzb3VyY2UgbG9hZCBsb29wIGNvbnRpbnVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpOyAvLyBMZXRzIHRoZSBzb3VyY2UgbG9hZCBsb29wIGNvbnRpbnVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAxO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHJldHVybiBbNSAvKnlpZWxkKiovLCBfbG9vcF8xKCldO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZV8xID0gX2Euc2VudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlXzEgPT09IFwiYnJlYWtcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA0XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOiByZXR1cm4gWzMgLypicmVhayovLCAxXTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gWzQgLyp5aWVsZCovLCBQcm9taXNlLmFsbChjb21wb25lbnRQcm9taXNlcyldO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5zZW50KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgY29tcG9uZW50c107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG59XG4vKipcbiAqIE1vZGlmaWVzIGFuIGVudHJvcHkgc291cmNlIGJ5IHRyYW5zZm9ybWluZyBpdHMgcmV0dXJuZWQgdmFsdWUgd2l0aCB0aGUgZ2l2ZW4gZnVuY3Rpb24uXG4gKiBLZWVwcyB0aGUgc291cmNlIHByb3BlcnRpZXM6IHN5bmMvYXN5bmMsIDEvMiBzdGFnZXMuXG4gKlxuICogV2FybmluZyBmb3IgcGFja2FnZSB1c2VyczpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgb3V0IG9mIFNlbWFudGljIFZlcnNpb25pbmcsIGkuZS4gY2FuIGNoYW5nZSB1bmV4cGVjdGVkbHkuIFVzYWdlIGlzIGF0IHlvdXIgb3duIHJpc2suXG4gKi9cbmZ1bmN0aW9uIHRyYW5zZm9ybVNvdXJjZShzb3VyY2UsIHRyYW5zZm9ybVZhbHVlKSB7XG4gICAgdmFyIHRyYW5zZm9ybUxvYWRSZXN1bHQgPSBmdW5jdGlvbiAobG9hZFJlc3VsdCkge1xuICAgICAgICBpZiAoaXNGaW5hbFJlc3VsdExvYWRlZChsb2FkUmVzdWx0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVZhbHVlKGxvYWRSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZ2V0UmVzdWx0ID0gbG9hZFJlc3VsdCgpO1xuICAgICAgICAgICAgaWYgKGlzUHJvbWlzZShnZXRSZXN1bHQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldFJlc3VsdC50aGVuKHRyYW5zZm9ybVZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1WYWx1ZShnZXRSZXN1bHQpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHZhciBsb2FkUmVzdWx0ID0gc291cmNlKG9wdGlvbnMpO1xuICAgICAgICBpZiAoaXNQcm9taXNlKGxvYWRSZXN1bHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9hZFJlc3VsdC50aGVuKHRyYW5zZm9ybUxvYWRSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm1Mb2FkUmVzdWx0KGxvYWRSZXN1bHQpO1xuICAgIH07XG59XG5cbi8qXG4gKiBGdW5jdGlvbnMgdG8gaGVscCB3aXRoIGZlYXR1cmVzIHRoYXQgdmFyeSB0aHJvdWdoIGJyb3dzZXJzXG4gKi9cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgYmFzZWQgb24gVHJpZGVudCAodGhlIEludGVybmV0IEV4cGxvcmVyIGVuZ2luZSkgd2l0aG91dCB1c2luZyB1c2VyLWFnZW50LlxuICpcbiAqIFdhcm5pbmcgZm9yIHBhY2thZ2UgdXNlcnM6XG4gKiBUaGlzIGZ1bmN0aW9uIGlzIG91dCBvZiBTZW1hbnRpYyBWZXJzaW9uaW5nLCBpLmUuIGNhbiBjaGFuZ2UgdW5leHBlY3RlZGx5LiBVc2FnZSBpcyBhdCB5b3VyIG93biByaXNrLlxuICovXG5mdW5jdGlvbiBpc1RyaWRlbnQoKSB7XG4gICAgdmFyIHcgPSB3aW5kb3c7XG4gICAgdmFyIG4gPSBuYXZpZ2F0b3I7XG4gICAgLy8gVGhlIHByb3BlcnRpZXMgYXJlIGNoZWNrZWQgdG8gYmUgaW4gSUUgMTAsIElFIDExIGFuZCBub3QgdG8gYmUgaW4gb3RoZXIgYnJvd3NlcnMgaW4gT2N0b2JlciAyMDIwXG4gICAgcmV0dXJuIChjb3VudFRydXRoeShbXG4gICAgICAgICdNU0NTU01hdHJpeCcgaW4gdyxcbiAgICAgICAgJ21zU2V0SW1tZWRpYXRlJyBpbiB3LFxuICAgICAgICAnbXNJbmRleGVkREInIGluIHcsXG4gICAgICAgICdtc01heFRvdWNoUG9pbnRzJyBpbiBuLFxuICAgICAgICAnbXNQb2ludGVyRW5hYmxlZCcgaW4gbixcbiAgICBdKSA+PSA0KTtcbn1cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgYmFzZWQgb24gRWRnZUhUTUwgKHRoZSBwcmUtQ2hyb21pdW0gRWRnZSBlbmdpbmUpIHdpdGhvdXQgdXNpbmcgdXNlci1hZ2VudC5cbiAqXG4gKiBXYXJuaW5nIGZvciBwYWNrYWdlIHVzZXJzOlxuICogVGhpcyBmdW5jdGlvbiBpcyBvdXQgb2YgU2VtYW50aWMgVmVyc2lvbmluZywgaS5lLiBjYW4gY2hhbmdlIHVuZXhwZWN0ZWRseS4gVXNhZ2UgaXMgYXQgeW91ciBvd24gcmlzay5cbiAqL1xuZnVuY3Rpb24gaXNFZGdlSFRNTCgpIHtcbiAgICAvLyBCYXNlZCBvbiByZXNlYXJjaCBpbiBPY3RvYmVyIDIwMjBcbiAgICB2YXIgdyA9IHdpbmRvdztcbiAgICB2YXIgbiA9IG5hdmlnYXRvcjtcbiAgICByZXR1cm4gKGNvdW50VHJ1dGh5KFsnbXNXcml0ZVByb2ZpbGVyTWFyaycgaW4gdywgJ01TU3RyZWFtJyBpbiB3LCAnbXNMYXVuY2hVcmknIGluIG4sICdtc1NhdmVCbG9iJyBpbiBuXSkgPj0gMyAmJlxuICAgICAgICAhaXNUcmlkZW50KCkpO1xufVxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYnJvd3NlciBpcyBiYXNlZCBvbiBDaHJvbWl1bSB3aXRob3V0IHVzaW5nIHVzZXItYWdlbnQuXG4gKlxuICogV2FybmluZyBmb3IgcGFja2FnZSB1c2VyczpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgb3V0IG9mIFNlbWFudGljIFZlcnNpb25pbmcsIGkuZS4gY2FuIGNoYW5nZSB1bmV4cGVjdGVkbHkuIFVzYWdlIGlzIGF0IHlvdXIgb3duIHJpc2suXG4gKi9cbmZ1bmN0aW9uIGlzQ2hyb21pdW0oKSB7XG4gICAgLy8gQmFzZWQgb24gcmVzZWFyY2ggaW4gT2N0b2JlciAyMDIwLiBUZXN0ZWQgdG8gZGV0ZWN0IENocm9taXVtIDQyLTg2LlxuICAgIHZhciB3ID0gd2luZG93O1xuICAgIHZhciBuID0gbmF2aWdhdG9yO1xuICAgIHJldHVybiAoY291bnRUcnV0aHkoW1xuICAgICAgICAnd2Via2l0UGVyc2lzdGVudFN0b3JhZ2UnIGluIG4sXG4gICAgICAgICd3ZWJraXRUZW1wb3JhcnlTdG9yYWdlJyBpbiBuLFxuICAgICAgICBuLnZlbmRvci5pbmRleE9mKCdHb29nbGUnKSA9PT0gMCxcbiAgICAgICAgJ3dlYmtpdFJlc29sdmVMb2NhbEZpbGVTeXN0ZW1VUkwnIGluIHcsXG4gICAgICAgICdCYXR0ZXJ5TWFuYWdlcicgaW4gdyxcbiAgICAgICAgJ3dlYmtpdE1lZGlhU3RyZWFtJyBpbiB3LFxuICAgICAgICAnd2Via2l0U3BlZWNoR3JhbW1hcicgaW4gdyxcbiAgICBdKSA+PSA1KTtcbn1cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgYmFzZWQgb24gbW9iaWxlIG9yIGRlc2t0b3AgU2FmYXJpIHdpdGhvdXQgdXNpbmcgdXNlci1hZ2VudC5cbiAqIEFsbCBpT1MgYnJvd3NlcnMgdXNlIFdlYktpdCAodGhlIFNhZmFyaSBlbmdpbmUpLlxuICpcbiAqIFdhcm5pbmcgZm9yIHBhY2thZ2UgdXNlcnM6XG4gKiBUaGlzIGZ1bmN0aW9uIGlzIG91dCBvZiBTZW1hbnRpYyBWZXJzaW9uaW5nLCBpLmUuIGNhbiBjaGFuZ2UgdW5leHBlY3RlZGx5LiBVc2FnZSBpcyBhdCB5b3VyIG93biByaXNrLlxuICovXG5mdW5jdGlvbiBpc1dlYktpdCgpIHtcbiAgICAvLyBCYXNlZCBvbiByZXNlYXJjaCBpbiBTZXB0ZW1iZXIgMjAyMFxuICAgIHZhciB3ID0gd2luZG93O1xuICAgIHZhciBuID0gbmF2aWdhdG9yO1xuICAgIHJldHVybiAoY291bnRUcnV0aHkoW1xuICAgICAgICAnQXBwbGVQYXlFcnJvcicgaW4gdyxcbiAgICAgICAgJ0NTU1ByaW1pdGl2ZVZhbHVlJyBpbiB3LFxuICAgICAgICAnQ291bnRlcicgaW4gdyxcbiAgICAgICAgbi52ZW5kb3IuaW5kZXhPZignQXBwbGUnKSA9PT0gMCxcbiAgICAgICAgJ2dldFN0b3JhZ2VVcGRhdGVzJyBpbiBuLFxuICAgICAgICAnV2ViS2l0TWVkaWFLZXlzJyBpbiB3LFxuICAgIF0pID49IDQpO1xufVxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgV2ViS2l0IGJyb3dzZXIgaXMgYSBkZXNrdG9wIFNhZmFyaS5cbiAqXG4gKiBXYXJuaW5nIGZvciBwYWNrYWdlIHVzZXJzOlxuICogVGhpcyBmdW5jdGlvbiBpcyBvdXQgb2YgU2VtYW50aWMgVmVyc2lvbmluZywgaS5lLiBjYW4gY2hhbmdlIHVuZXhwZWN0ZWRseS4gVXNhZ2UgaXMgYXQgeW91ciBvd24gcmlzay5cbiAqL1xuZnVuY3Rpb24gaXNEZXNrdG9wU2FmYXJpKCkge1xuICAgIHZhciB3ID0gd2luZG93O1xuICAgIHJldHVybiAoY291bnRUcnV0aHkoW1xuICAgICAgICAnc2FmYXJpJyBpbiB3LFxuICAgICAgICAhKCdEZXZpY2VNb3Rpb25FdmVudCcgaW4gdyksXG4gICAgICAgICEoJ29uZ2VzdHVyZWVuZCcgaW4gdyksXG4gICAgICAgICEoJ3N0YW5kYWxvbmUnIGluIG5hdmlnYXRvciksXG4gICAgXSkgPj0gMyk7XG59XG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBicm93c2VyIGlzIGJhc2VkIG9uIEdlY2tvIChGaXJlZm94IGVuZ2luZSkgd2l0aG91dCB1c2luZyB1c2VyLWFnZW50LlxuICpcbiAqIFdhcm5pbmcgZm9yIHBhY2thZ2UgdXNlcnM6XG4gKiBUaGlzIGZ1bmN0aW9uIGlzIG91dCBvZiBTZW1hbnRpYyBWZXJzaW9uaW5nLCBpLmUuIGNhbiBjaGFuZ2UgdW5leHBlY3RlZGx5LiBVc2FnZSBpcyBhdCB5b3VyIG93biByaXNrLlxuICovXG5mdW5jdGlvbiBpc0dlY2tvKCkge1xuICAgIHZhciBfYSwgX2I7XG4gICAgdmFyIHcgPSB3aW5kb3c7XG4gICAgLy8gQmFzZWQgb24gcmVzZWFyY2ggaW4gU2VwdGVtYmVyIDIwMjBcbiAgICByZXR1cm4gKGNvdW50VHJ1dGh5KFtcbiAgICAgICAgJ2J1aWxkSUQnIGluIG5hdmlnYXRvcixcbiAgICAgICAgJ01vekFwcGVhcmFuY2UnIGluICgoX2IgPSAoX2EgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5zdHlsZSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDoge30pLFxuICAgICAgICAnb25tb3pmdWxsc2NyZWVuY2hhbmdlJyBpbiB3LFxuICAgICAgICAnbW96SW5uZXJTY3JlZW5YJyBpbiB3LFxuICAgICAgICAnQ1NTTW96RG9jdW1lbnRSdWxlJyBpbiB3LFxuICAgICAgICAnQ2FudmFzQ2FwdHVyZU1lZGlhU3RyZWFtJyBpbiB3LFxuICAgIF0pID49IDQpO1xufVxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYnJvd3NlciBpcyBiYXNlZCBvbiBDaHJvbWl1bSB2ZXJzaW9uIOKJpTg2IHdpdGhvdXQgdXNpbmcgdXNlci1hZ2VudC5cbiAqIEl0IGRvZXNuJ3QgY2hlY2sgdGhhdCB0aGUgYnJvd3NlciBpcyBiYXNlZCBvbiBDaHJvbWl1bSwgdGhlcmUgaXMgYSBzZXBhcmF0ZSBmdW5jdGlvbiBmb3IgdGhpcy5cbiAqL1xuZnVuY3Rpb24gaXNDaHJvbWl1bTg2T3JOZXdlcigpIHtcbiAgICAvLyBDaGVja2VkIGluIENocm9tZSA4NSB2cyBDaHJvbWUgODYgYm90aCBvbiBkZXNrdG9wIGFuZCBBbmRyb2lkXG4gICAgdmFyIHcgPSB3aW5kb3c7XG4gICAgcmV0dXJuIChjb3VudFRydXRoeShbXG4gICAgICAgICEoJ01lZGlhU2V0dGluZ3NSYW5nZScgaW4gdyksXG4gICAgICAgICdSVENFbmNvZGVkQXVkaW9GcmFtZScgaW4gdyxcbiAgICAgICAgJycgKyB3LkludGwgPT09ICdbb2JqZWN0IEludGxdJyxcbiAgICAgICAgJycgKyB3LlJlZmxlY3QgPT09ICdbb2JqZWN0IFJlZmxlY3RdJyxcbiAgICBdKSA+PSAzKTtcbn1cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgYmFzZWQgb24gV2ViS2l0IHZlcnNpb24g4omlNjA2IChTYWZhcmkg4omlMTIpIHdpdGhvdXQgdXNpbmcgdXNlci1hZ2VudC5cbiAqIEl0IGRvZXNuJ3QgY2hlY2sgdGhhdCB0aGUgYnJvd3NlciBpcyBiYXNlZCBvbiBXZWJLaXQsIHRoZXJlIGlzIGEgc2VwYXJhdGUgZnVuY3Rpb24gZm9yIHRoaXMuXG4gKlxuICogQGxpbmsgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU2FmYXJpX3ZlcnNpb25faGlzdG9yeSNSZWxlYXNlX2hpc3RvcnkgU2FmYXJpLVdlYktpdCB2ZXJzaW9ucyBtYXBcbiAqL1xuZnVuY3Rpb24gaXNXZWJLaXQ2MDZPck5ld2VyKCkge1xuICAgIC8vIENoZWNrZWQgaW4gU2FmYXJpIDnigJMxNFxuICAgIHZhciB3ID0gd2luZG93O1xuICAgIHJldHVybiAoY291bnRUcnV0aHkoW1xuICAgICAgICAnRE9NUmVjdExpc3QnIGluIHcsXG4gICAgICAgICdSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50JyBpbiB3LFxuICAgICAgICAnU1ZHR2VvbWV0cnlFbGVtZW50JyBpbiB3LFxuICAgICAgICAnb250cmFuc2l0aW9uY2FuY2VsJyBpbiB3LFxuICAgIF0pID49IDMpO1xufVxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgZGV2aWNlIGlzIGFuIGlQYWQuXG4gKiBJdCBkb2Vzbid0IGNoZWNrIHRoYXQgdGhlIGVuZ2luZSBpcyBXZWJLaXQgYW5kIHRoYXQgdGhlIFdlYktpdCBpc24ndCBkZXNrdG9wLlxuICovXG5mdW5jdGlvbiBpc0lQYWQoKSB7XG4gICAgLy8gQ2hlY2tlZCBvbjpcbiAgICAvLyBTYWZhcmkgb24gaVBhZE9TIChib3RoIG1vYmlsZSBhbmQgZGVza3RvcCBtb2Rlcyk6IDgsIDExLCAxMiwgMTMsIDE0XG4gICAgLy8gQ2hyb21lIG9uIGlQYWRPUyAoYm90aCBtb2JpbGUgYW5kIGRlc2t0b3AgbW9kZXMpOiAxMSwgMTIsIDEzLCAxNFxuICAgIC8vIFNhZmFyaSBvbiBpT1MgKGJvdGggbW9iaWxlIGFuZCBkZXNrdG9wIG1vZGVzKTogOSwgMTAsIDExLCAxMiwgMTMsIDE0XG4gICAgLy8gQ2hyb21lIG9uIGlPUyAoYm90aCBtb2JpbGUgYW5kIGRlc2t0b3AgbW9kZXMpOiA5LCAxMCwgMTEsIDEyLCAxMywgMTRcbiAgICAvLyBCZWZvcmUgaU9TIDEzLiBTYWZhcmkgdGFtcGVycyB0aGUgdmFsdWUgaW4gXCJyZXF1ZXN0IGRlc2t0b3Agc2l0ZVwiIG1vZGUgc2luY2UgaU9TIDEzLlxuICAgIGlmIChuYXZpZ2F0b3IucGxhdGZvcm0gPT09ICdpUGFkJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgdmFyIHMgPSBzY3JlZW47XG4gICAgdmFyIHNjcmVlblJhdGlvID0gcy53aWR0aCAvIHMuaGVpZ2h0O1xuICAgIHJldHVybiAoY291bnRUcnV0aHkoW1xuICAgICAgICAnTWVkaWFTb3VyY2UnIGluIHdpbmRvdyxcbiAgICAgICAgISFFbGVtZW50LnByb3RvdHlwZS53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbixcbiAgICAgICAgLy8gaVBob25lIDRTIHRoYXQgcnVucyBpT1MgOSBtYXRjaGVzIHRoaXMuIEJ1dCBpdCB3b24ndCBtYXRjaCB0aGUgY3JpdGVyaWEgYWJvdmUsIHNvIGl0IHdvbid0IGJlIGRldGVjdGVkIGFzIGlQYWQuXG4gICAgICAgIHNjcmVlblJhdGlvID4gMC42NSAmJiBzY3JlZW5SYXRpbyA8IDEuNTMsXG4gICAgXSkgPj0gMik7XG59XG4vKipcbiAqIFdhcm5pbmcgZm9yIHBhY2thZ2UgdXNlcnM6XG4gKiBUaGlzIGZ1bmN0aW9uIGlzIG91dCBvZiBTZW1hbnRpYyBWZXJzaW9uaW5nLCBpLmUuIGNhbiBjaGFuZ2UgdW5leHBlY3RlZGx5LiBVc2FnZSBpcyBhdCB5b3VyIG93biByaXNrLlxuICovXG5mdW5jdGlvbiBnZXRGdWxsc2NyZWVuRWxlbWVudCgpIHtcbiAgICB2YXIgZCA9IGRvY3VtZW50O1xuICAgIHJldHVybiBkLmZ1bGxzY3JlZW5FbGVtZW50IHx8IGQubXNGdWxsc2NyZWVuRWxlbWVudCB8fCBkLm1vekZ1bGxTY3JlZW5FbGVtZW50IHx8IGQud2Via2l0RnVsbHNjcmVlbkVsZW1lbnQgfHwgbnVsbDtcbn1cbmZ1bmN0aW9uIGV4aXRGdWxsc2NyZWVuKCkge1xuICAgIHZhciBkID0gZG9jdW1lbnQ7XG4gICAgLy8gYGNhbGxgIGlzIHJlcXVpcmVkIGJlY2F1c2UgdGhlIGZ1bmN0aW9uIHRocm93cyBhbiBlcnJvciB3aXRob3V0IGEgcHJvcGVyIFwidGhpc1wiIGNvbnRleHRcbiAgICByZXR1cm4gKGQuZXhpdEZ1bGxzY3JlZW4gfHwgZC5tc0V4aXRGdWxsc2NyZWVuIHx8IGQubW96Q2FuY2VsRnVsbFNjcmVlbiB8fCBkLndlYmtpdEV4aXRGdWxsc2NyZWVuKS5jYWxsKGQpO1xufVxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgZGV2aWNlIHJ1bnMgb24gQW5kcm9pZCB3aXRob3V0IHVzaW5nIHVzZXItYWdlbnQuXG4gKlxuICogV2FybmluZyBmb3IgcGFja2FnZSB1c2VyczpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgb3V0IG9mIFNlbWFudGljIFZlcnNpb25pbmcsIGkuZS4gY2FuIGNoYW5nZSB1bmV4cGVjdGVkbHkuIFVzYWdlIGlzIGF0IHlvdXIgb3duIHJpc2suXG4gKi9cbmZ1bmN0aW9uIGlzQW5kcm9pZCgpIHtcbiAgICB2YXIgaXNJdENocm9taXVtID0gaXNDaHJvbWl1bSgpO1xuICAgIHZhciBpc0l0R2Vja28gPSBpc0dlY2tvKCk7XG4gICAgLy8gT25seSAyIGJyb3dzZXIgZW5naW5lcyBhcmUgcHJlc2VudGVkIG9uIEFuZHJvaWQuXG4gICAgLy8gQWN0dWFsbHksIHRoZXJlIGlzIGFsc28gQW5kcm9pZCA0LjEgYnJvd3NlciwgYnV0IGl0J3Mgbm90IHdvcnRoIGRldGVjdGluZyBpdCBhdCB0aGUgbW9tZW50LlxuICAgIGlmICghaXNJdENocm9taXVtICYmICFpc0l0R2Vja28pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgdyA9IHdpbmRvdztcbiAgICAvLyBDaHJvbWUgcmVtb3ZlcyBhbGwgd29yZHMgXCJBbmRyb2lkXCIgZnJvbSBgbmF2aWdhdG9yYCB3aGVuIGRlc2t0b3AgdmVyc2lvbiBpcyByZXF1ZXN0ZWRcbiAgICAvLyBGaXJlZm94IGtlZXBzIFwiQW5kcm9pZFwiIGluIGBuYXZpZ2F0b3IuYXBwVmVyc2lvbmAgd2hlbiBkZXNrdG9wIHZlcnNpb24gaXMgcmVxdWVzdGVkXG4gICAgcmV0dXJuIChjb3VudFRydXRoeShbXG4gICAgICAgICdvbm9yaWVudGF0aW9uY2hhbmdlJyBpbiB3LFxuICAgICAgICAnb3JpZW50YXRpb24nIGluIHcsXG4gICAgICAgIGlzSXRDaHJvbWl1bSAmJiAhKCdTaGFyZWRXb3JrZXInIGluIHcpLFxuICAgICAgICBpc0l0R2Vja28gJiYgL2FuZHJvaWQvaS50ZXN0KG5hdmlnYXRvci5hcHBWZXJzaW9uKSxcbiAgICBdKSA+PSAyKTtcbn1cblxuLyoqXG4gKiBBIGRlZXAgZGVzY3JpcHRpb246IGh0dHBzOi8vZmluZ2VycHJpbnQuY29tL2Jsb2cvYXVkaW8tZmluZ2VycHJpbnRpbmcvXG4gKiBJbnNwaXJlZCBieSBhbmQgYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2NvenlsaWZlL2F1ZGlvLWZpbmdlcnByaW50XG4gKi9cbmZ1bmN0aW9uIGdldEF1ZGlvRmluZ2VycHJpbnQoKSB7XG4gICAgdmFyIHcgPSB3aW5kb3c7XG4gICAgdmFyIEF1ZGlvQ29udGV4dCA9IHcuT2ZmbGluZUF1ZGlvQ29udGV4dCB8fCB3LndlYmtpdE9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgaWYgKCFBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIC0yIC8qIE5vdFN1cHBvcnRlZCAqLztcbiAgICB9XG4gICAgLy8gSW4gc29tZSBicm93c2VycywgYXVkaW8gY29udGV4dCBhbHdheXMgc3RheXMgc3VzcGVuZGVkIHVubGVzcyB0aGUgY29udGV4dCBpcyBzdGFydGVkIGluIHJlc3BvbnNlIHRvIGEgdXNlciBhY3Rpb25cbiAgICAvLyAoZS5nLiBhIGNsaWNrIG9yIGEgdGFwKS4gSXQgcHJldmVudHMgYXVkaW8gZmluZ2VycHJpbnQgZnJvbSBiZWluZyB0YWtlbiBhdCBhbiBhcmJpdHJhcnkgbW9tZW50IG9mIHRpbWUuXG4gICAgLy8gU3VjaCBicm93c2VycyBhcmUgb2xkIGFuZCB1bnBvcHVsYXIsIHNvIHRoZSBhdWRpbyBmaW5nZXJwcmludGluZyBpcyBqdXN0IHNraXBwZWQgaW4gdGhlbS5cbiAgICAvLyBTZWUgYSBzaW1pbGFyIGNhc2UgZXhwbGFuYXRpb24gYXQgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDYzNjMwNDgvb25hdWRpb3Byb2Nlc3Mtbm90LWNhbGxlZC1vbi1pb3MxMSM0NjUzNDA4OFxuICAgIGlmIChkb2VzQ3VycmVudEJyb3dzZXJTdXNwZW5kQXVkaW9Db250ZXh0KCkpIHtcbiAgICAgICAgcmV0dXJuIC0xIC8qIEtub3duVG9TdXNwZW5kICovO1xuICAgIH1cbiAgICB2YXIgaGFzaEZyb21JbmRleCA9IDQ1MDA7XG4gICAgdmFyIGhhc2hUb0luZGV4ID0gNTAwMDtcbiAgICB2YXIgY29udGV4dCA9IG5ldyBBdWRpb0NvbnRleHQoMSwgaGFzaFRvSW5kZXgsIDQ0MTAwKTtcbiAgICB2YXIgb3NjaWxsYXRvciA9IGNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgIG9zY2lsbGF0b3IudHlwZSA9ICd0cmlhbmdsZSc7XG4gICAgb3NjaWxsYXRvci5mcmVxdWVuY3kudmFsdWUgPSAxMDAwMDtcbiAgICB2YXIgY29tcHJlc3NvciA9IGNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgY29tcHJlc3Nvci50aHJlc2hvbGQudmFsdWUgPSAtNTA7XG4gICAgY29tcHJlc3Nvci5rbmVlLnZhbHVlID0gNDA7XG4gICAgY29tcHJlc3Nvci5yYXRpby52YWx1ZSA9IDEyO1xuICAgIGNvbXByZXNzb3IuYXR0YWNrLnZhbHVlID0gMDtcbiAgICBjb21wcmVzc29yLnJlbGVhc2UudmFsdWUgPSAwLjI1O1xuICAgIG9zY2lsbGF0b3IuY29ubmVjdChjb21wcmVzc29yKTtcbiAgICBjb21wcmVzc29yLmNvbm5lY3QoY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgb3NjaWxsYXRvci5zdGFydCgwKTtcbiAgICB2YXIgX2EgPSBzdGFydFJlbmRlcmluZ0F1ZGlvKGNvbnRleHQpLCByZW5kZXJQcm9taXNlID0gX2FbMF0sIGZpbmlzaFJlbmRlcmluZyA9IF9hWzFdO1xuICAgIHZhciBmaW5nZXJwcmludFByb21pc2UgPSByZW5kZXJQcm9taXNlLnRoZW4oZnVuY3Rpb24gKGJ1ZmZlcikgeyByZXR1cm4gZ2V0SGFzaChidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCkuc3ViYXJyYXkoaGFzaEZyb21JbmRleCkpOyB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09IFwidGltZW91dFwiIC8qIFRpbWVvdXQgKi8gfHwgZXJyb3IubmFtZSA9PT0gXCJzdXNwZW5kZWRcIiAvKiBTdXNwZW5kZWQgKi8pIHtcbiAgICAgICAgICAgIHJldHVybiAtMyAvKiBUaW1lb3V0ICovO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xuICAgIC8vIFN1cHByZXNzZXMgdGhlIGNvbnNvbGUgZXJyb3IgbWVzc2FnZSBpbiBjYXNlIHdoZW4gdGhlIGZpbmdlcnByaW50IGZhaWxzIGJlZm9yZSByZXF1ZXN0ZWRcbiAgICBzdXBwcmVzc1VuaGFuZGxlZFJlamVjdGlvbldhcm5pbmcoZmluZ2VycHJpbnRQcm9taXNlKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBmaW5pc2hSZW5kZXJpbmcoKTtcbiAgICAgICAgcmV0dXJuIGZpbmdlcnByaW50UHJvbWlzZTtcbiAgICB9O1xufVxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgYnJvd3NlciBpcyBrbm93biB0byBhbHdheXMgc3VzcGVuZCBhdWRpbyBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIGRvZXNDdXJyZW50QnJvd3NlclN1c3BlbmRBdWRpb0NvbnRleHQoKSB7XG4gICAgcmV0dXJuIGlzV2ViS2l0KCkgJiYgIWlzRGVza3RvcFNhZmFyaSgpICYmICFpc1dlYktpdDYwNk9yTmV3ZXIoKTtcbn1cbi8qKlxuICogU3RhcnRzIHJlbmRlcmluZyB0aGUgYXVkaW8gY29udGV4dC5cbiAqIFdoZW4gdGhlIHJldHVybmVkIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhlIHJlbmRlciBwcm9jZXNzIHN0YXJ0cyBmaW5pc2hpbmcuXG4gKi9cbmZ1bmN0aW9uIHN0YXJ0UmVuZGVyaW5nQXVkaW8oY29udGV4dCkge1xuICAgIHZhciByZW5kZXJUcnlNYXhDb3VudCA9IDM7XG4gICAgdmFyIHJlbmRlclJldHJ5RGVsYXkgPSA1MDA7XG4gICAgdmFyIHJ1bm5pbmdNYXhBd2FpdFRpbWUgPSA1MDA7XG4gICAgdmFyIHJ1bm5pbmdTdWZmaWNpZW50VGltZSA9IDUwMDA7XG4gICAgdmFyIGZpbmFsaXplID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9O1xuICAgIHZhciByZXN1bHRQcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICB2YXIgaXNGaW5hbGl6ZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIHJlbmRlclRyeUNvdW50ID0gMDtcbiAgICAgICAgdmFyIHN0YXJ0ZWRSdW5uaW5nQXQgPSAwO1xuICAgICAgICBjb250ZXh0Lm9uY29tcGxldGUgPSBmdW5jdGlvbiAoZXZlbnQpIHsgcmV0dXJuIHJlc29sdmUoZXZlbnQucmVuZGVyZWRCdWZmZXIpOyB9O1xuICAgICAgICB2YXIgc3RhcnRSdW5uaW5nVGltZW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVqZWN0KG1ha2VJbm5lckVycm9yKFwidGltZW91dFwiIC8qIFRpbWVvdXQgKi8pKTsgfSwgTWF0aC5taW4ocnVubmluZ01heEF3YWl0VGltZSwgc3RhcnRlZFJ1bm5pbmdBdCArIHJ1bm5pbmdTdWZmaWNpZW50VGltZSAtIERhdGUubm93KCkpKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHRyeVJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoY29udGV4dC5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdydW5uaW5nJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWRSdW5uaW5nQXQgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRmluYWxpemVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRSdW5uaW5nVGltZW91dCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNvbWV0aW1lcyB0aGUgYXVkaW8gY29udGV4dCBkb2Vzbid0IHN0YXJ0IGFmdGVyIGNhbGxpbmcgYHN0YXJ0UmVuZGVyaW5nYCAoaW4gYWRkaXRpb24gdG8gdGhlIGNhc2VzIHdoZXJlXG4gICAgICAgICAgICAgICAgICAgIC8vIGF1ZGlvIGNvbnRleHQgZG9lc24ndCBzdGFydCBhdCBhbGwpLiBBIGtub3duIGNhc2UgaXMgc3RhcnRpbmcgYW4gYXVkaW8gY29udGV4dCB3aGVuIHRoZSBicm93c2VyIHRhYiBpcyBpblxuICAgICAgICAgICAgICAgICAgICAvLyBiYWNrZ3JvdW5kIG9uIGlQaG9uZS4gUmV0cmllcyB1c3VhbGx5IGhlbHAgaW4gdGhpcyBjYXNlLlxuICAgICAgICAgICAgICAgICAgICBjYXNlICdzdXNwZW5kZWQnOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGF1ZGlvIGNvbnRleHQgY2FuIHJlamVjdCBzdGFydGluZyB1bnRpbCB0aGUgdGFiIGlzIGluIGZvcmVncm91bmQuIExvbmcgZmluZ2VycHJpbnQgZHVyYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIGJhY2tncm91bmQgaXNuJ3QgYSBwcm9ibGVtLCB0aGVyZWZvcmUgdGhlIHJldHJ5IGF0dGVtcHRzIGRvbid0IGNvdW50IGluIGJhY2tncm91bmQuIEl0IGNhbiBsZWFkIHRvXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhIHNpdHVhdGlvbiB3aGVuIGEgZmluZ2VycHJpbnQgdGFrZXMgdmVyeSBsb25nIHRpbWUgYW5kIGZpbmlzaGVzIHN1Y2Nlc3NmdWxseS4gRllJLCB0aGUgYXVkaW8gY29udGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuIGJlIHN1c3BlbmRlZCB3aGVuIGBkb2N1bWVudC5oaWRkZW4gPT09IGZhbHNlYCBhbmQgc3RhcnQgcnVubmluZyBhZnRlciBhIHJldHJ5LlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkb2N1bWVudC5oaWRkZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJUcnlDb3VudCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRmluYWxpemVkICYmIHJlbmRlclRyeUNvdW50ID49IHJlbmRlclRyeU1heENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG1ha2VJbm5lckVycm9yKFwic3VzcGVuZGVkXCIgLyogU3VzcGVuZGVkICovKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KHRyeVJlbmRlciwgcmVuZGVyUmV0cnlEZWxheSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0cnlSZW5kZXIoKTtcbiAgICAgICAgZmluYWxpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIWlzRmluYWxpemVkKSB7XG4gICAgICAgICAgICAgICAgaXNGaW5hbGl6ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydGVkUnVubmluZ0F0ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBzdGFydFJ1bm5pbmdUaW1lb3V0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuICAgIHJldHVybiBbcmVzdWx0UHJvbWlzZSwgZmluYWxpemVdO1xufVxuZnVuY3Rpb24gZ2V0SGFzaChzaWduYWwpIHtcbiAgICB2YXIgaGFzaCA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWduYWwubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaGFzaCArPSBNYXRoLmFicyhzaWduYWxbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaDtcbn1cbmZ1bmN0aW9uIG1ha2VJbm5lckVycm9yKG5hbWUpIHtcbiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobmFtZSk7XG4gICAgZXJyb3IubmFtZSA9IG5hbWU7XG4gICAgcmV0dXJuIGVycm9yO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW5kIGtlZXBzIGFuIGludmlzaWJsZSBpZnJhbWUgd2hpbGUgdGhlIGdpdmVuIGZ1bmN0aW9uIHJ1bnMuXG4gKiBUaGUgZ2l2ZW4gZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gdGhlIGlmcmFtZSBpcyBsb2FkZWQgYW5kIGhhcyBhIGJvZHkuXG4gKiBUaGUgaWZyYW1lIGFsbG93cyB0byBtZWFzdXJlIERPTSBzaXplcyBpbnNpZGUgaXRzZWxmLlxuICpcbiAqIE5vdGljZTogcGFzc2luZyBhbiBpbml0aWFsIEhUTUwgY29kZSBkb2Vzbid0IHdvcmsgaW4gSUUuXG4gKlxuICogV2FybmluZyBmb3IgcGFja2FnZSB1c2VyczpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgb3V0IG9mIFNlbWFudGljIFZlcnNpb25pbmcsIGkuZS4gY2FuIGNoYW5nZSB1bmV4cGVjdGVkbHkuIFVzYWdlIGlzIGF0IHlvdXIgb3duIHJpc2suXG4gKi9cbmZ1bmN0aW9uIHdpdGhJZnJhbWUoYWN0aW9uLCBpbml0aWFsSHRtbCwgZG9tUG9sbEludGVydmFsKSB7XG4gICAgdmFyIF9hLCBfYiwgX2M7XG4gICAgaWYgKGRvbVBvbGxJbnRlcnZhbCA9PT0gdm9pZCAwKSB7IGRvbVBvbGxJbnRlcnZhbCA9IDUwOyB9XG4gICAgcmV0dXJuIHRzbGliLl9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZCwgaWZyYW1lO1xuICAgICAgICByZXR1cm4gdHNsaWIuX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9kKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9kLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICBkID0gZG9jdW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIF9kLmxhYmVsID0gMTtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWQuYm9keSkgcmV0dXJuIFszIC8qYnJlYWsqLywgM107XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHdhaXQoZG9tUG9sbEludGVydmFsKV07XG4gICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICBfZC5zZW50KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDFdO1xuICAgICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICAgICAgaWZyYW1lID0gZC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgX2QubGFiZWwgPSA0O1xuICAgICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICAgICAgX2QudHJ5cy5wdXNoKFs0LCAsIDEwLCAxMV0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCBuZXcgUHJvbWlzZShmdW5jdGlvbiAoX3Jlc29sdmUsIF9yZWplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNDb21wbGV0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNvbHZlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Jlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWplY3QgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDb21wbGV0ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9yZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZyYW1lLm9ubG9hZCA9IHJlc29sdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZyYW1lLm9uZXJyb3IgPSByZWplY3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gaWZyYW1lLnN0eWxlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ2Jsb2NrJywgJ2ltcG9ydGFudCcpOyAvLyBSZXF1aXJlZCBmb3IgYnJvd3NlcnMgdG8gY2FsY3VsYXRlIHRoZSBsYXlvdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUudG9wID0gJzAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlLmxlZnQgPSAnMCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbml0aWFsSHRtbCAmJiAnc3JjZG9jJyBpbiBpZnJhbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZyYW1lLnNyY2RvYyA9IGluaXRpYWxIdG1sO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZyYW1lLnNyYyA9ICdhYm91dDpibGFuayc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlYktpdCBpbiBXZUNoYXQgZG9lc24ndCBmaXJlIHRoZSBpZnJhbWUncyBgb25sb2FkYCBmb3Igc29tZSByZWFzb24uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBjb2RlIGNoZWNrcyBmb3IgdGhlIGxvYWRpbmcgc3RhdGUgbWFudWFsbHkuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvaXNzdWVzLzY0NVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1JlYWR5U3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSByZWFkeSBzdGF0ZSBtYXkgbmV2ZXIgYmVjb21lICdjb21wbGV0ZScgaW4gRmlyZWZveCBkZXNwaXRlIHRoZSAnbG9hZCcgZXZlbnQgYmVpbmcgZmlyZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvIGFuIGluZmluaXRlIHNldFRpbWVvdXQgbG9vcCBjYW4gaGFwcGVuIHdpdGhvdXQgdGhpcyBjaGVjay5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvcHVsbC83MTYjaXNzdWVjb21tZW50LTk4Njg5ODc5NlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNDb21wbGV0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBpZnJhbWUuY29udGVudFdpbmRvdyBhbmQgaWZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQgYXJlIGJvdGggbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjb250ZW50V2luZG93LmRvY3VtZW50IGNhbiBtaXNzIGluIEpTRE9NIChodHRwczovL2dpdGh1Yi5jb20vanNkb20vanNkb20pLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChfYiA9IChfYSA9IGlmcmFtZS5jb250ZW50V2luZG93KSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZG9jdW1lbnQpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5yZWFkeVN0YXRlKSA9PT0gJ2NvbXBsZXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChjaGVja1JlYWR5U3RhdGUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tSZWFkeVN0YXRlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KV07XG4gICAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgICAgICBfZC5zZW50KCk7XG4gICAgICAgICAgICAgICAgICAgIF9kLmxhYmVsID0gNjtcbiAgICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgICAgIGlmICghISgoX2IgPSAoX2EgPSBpZnJhbWUuY29udGVudFdpbmRvdykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmRvY3VtZW50KSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuYm9keSkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDhdO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB3YWl0KGRvbVBvbGxJbnRlcnZhbCldO1xuICAgICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgICAgICAgX2Quc2VudCgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA2XTtcbiAgICAgICAgICAgICAgICBjYXNlIDg6IHJldHVybiBbNCAvKnlpZWxkKi8sIGFjdGlvbihpZnJhbWUsIGlmcmFtZS5jb250ZW50V2luZG93KV07XG4gICAgICAgICAgICAgICAgY2FzZSA5OiByZXR1cm4gWzIgLypyZXR1cm4qLywgX2Quc2VudCgpXTtcbiAgICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICAgICAgICAoX2MgPSBpZnJhbWUucGFyZW50Tm9kZSkgPT09IG51bGwgfHwgX2MgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jLnJlbW92ZUNoaWxkKGlmcmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbNyAvKmVuZGZpbmFsbHkqL107XG4gICAgICAgICAgICAgICAgY2FzZSAxMTogcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9KTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIERPTSBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gc2VsZWN0b3IuXG4gKiBPbmx5IHNpbmdsZSBlbGVtZW50IHNlbGVjdG9yIGFyZSBzdXBwb3J0ZWQgKHdpdGhvdXQgb3BlcmF0b3JzIGxpa2Ugc3BhY2UsICssID4sIGV0YykuXG4gKi9cbmZ1bmN0aW9uIHNlbGVjdG9yVG9FbGVtZW50KHNlbGVjdG9yKSB7XG4gICAgdmFyIF9hID0gcGFyc2VTaW1wbGVDc3NTZWxlY3RvcihzZWxlY3RvciksIHRhZyA9IF9hWzBdLCBhdHRyaWJ1dGVzID0gX2FbMV07XG4gICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZyAhPT0gbnVsbCAmJiB0YWcgIT09IHZvaWQgMCA/IHRhZyA6ICdkaXYnKTtcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9iID0gT2JqZWN0LmtleXMoYXR0cmlidXRlcyk7IF9pIDwgX2IubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBuYW1lXzEgPSBfYltfaV07XG4gICAgICAgIHZhciB2YWx1ZSA9IGF0dHJpYnV0ZXNbbmFtZV8xXS5qb2luKCcgJyk7XG4gICAgICAgIC8vIENoYW5naW5nIHRoZSBgc3R5bGVgIGF0dHJpYnV0ZSBjYW4gY2F1c2UgYSBDU1AgZXJyb3IsIHRoZXJlZm9yZSB3ZSBjaGFuZ2UgdGhlIGBzdHlsZS5jc3NUZXh0YCBwcm9wZXJ0eS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZpbmdlcnByaW50anMvZmluZ2VycHJpbnRqcy9pc3N1ZXMvNzMzXG4gICAgICAgIGlmIChuYW1lXzEgPT09ICdzdHlsZScpIHtcbiAgICAgICAgICAgIGFkZFN0eWxlU3RyaW5nKGVsZW1lbnQuc3R5bGUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWVfMSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50O1xufVxuLyoqXG4gKiBBZGRzIENTUyBzdHlsZXMgZnJvbSBhIHN0cmluZyBpbiBzdWNoIGEgd2F5IHRoYXQgZG9lc24ndCB0cmlnZ2VyIGEgQ1NQIHdhcm5pbmcgKHVuc2FmZS1pbmxpbmUgb3IgdW5zYWZlLWV2YWwpXG4gKi9cbmZ1bmN0aW9uIGFkZFN0eWxlU3RyaW5nKHN0eWxlLCBzb3VyY2UpIHtcbiAgICAvLyBXZSBkb24ndCB1c2UgYHN0eWxlLmNzc1RleHRgIGJlY2F1c2UgYnJvd3NlcnMgbXVzdCBibG9jayBpdCB3aGVuIG5vIGB1bnNhZmUtZXZhbGAgQ1NQIGlzIHByZXNlbnRlZDogaHR0cHM6Ly9jc3BsaXRlLmNvbS9jc3AxNDUvI3czY19ub3RlXG4gICAgLy8gRXZlbiB0aG91Z2ggdGhlIGJyb3dzZXJzIGlnbm9yZSB0aGlzIHN0YW5kYXJkLCB3ZSBkb24ndCB1c2UgYGNzc1RleHRgIGp1c3QgaW4gY2FzZS5cbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gc291cmNlLnNwbGl0KCc7Jyk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBwcm9wZXJ0eSA9IF9hW19pXTtcbiAgICAgICAgdmFyIG1hdGNoID0gL15cXHMqKFtcXHctXSspXFxzKjpcXHMqKC4rPykoXFxzKiEoW1xcdy1dKykpP1xccyokLy5leGVjKHByb3BlcnR5KTtcbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICB2YXIgbmFtZV8yID0gbWF0Y2hbMV0sIHZhbHVlID0gbWF0Y2hbMl0sIHByaW9yaXR5ID0gbWF0Y2hbNF07XG4gICAgICAgICAgICBzdHlsZS5zZXRQcm9wZXJ0eShuYW1lXzIsIHZhbHVlLCBwcmlvcml0eSB8fCAnJyk7IC8vIFRoZSBsYXN0IGFyZ3VtZW50IGNhbid0IGJlIHVuZGVmaW5lZCBpbiBJRTExXG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIFdlIHVzZSBtIG9yIHcgYmVjYXVzZSB0aGVzZSB0d28gY2hhcmFjdGVycyB0YWtlIHVwIHRoZSBtYXhpbXVtIHdpZHRoLlxuLy8gQW5kIHdlIHVzZSBhIExMaSBzbyB0aGF0IHRoZSBzYW1lIG1hdGNoaW5nIGZvbnRzIGNhbiBnZXQgc2VwYXJhdGVkLlxudmFyIHRlc3RTdHJpbmcgPSAnbW1Nd1dMbGlJME8mMSc7XG4vLyBXZSB0ZXN0IHVzaW5nIDQ4cHggZm9udCBzaXplLCB3ZSBtYXkgdXNlIGFueSBzaXplLiBJIGd1ZXNzIGxhcmdlciB0aGUgYmV0dGVyLlxudmFyIHRleHRTaXplID0gJzQ4cHgnO1xuLy8gQSBmb250IHdpbGwgYmUgY29tcGFyZWQgYWdhaW5zdCBhbGwgdGhlIHRocmVlIGRlZmF1bHQgZm9udHMuXG4vLyBBbmQgaWYgZm9yIGFueSBkZWZhdWx0IGZvbnRzIGl0IGRvZXNuJ3QgbWF0Y2gsIHRoZW4gdGhhdCBmb250IGlzIGF2YWlsYWJsZS5cbnZhciBiYXNlRm9udHMgPSBbJ21vbm9zcGFjZScsICdzYW5zLXNlcmlmJywgJ3NlcmlmJ107XG52YXIgZm9udExpc3QgPSBbXG4gICAgLy8gVGhpcyBpcyBhbmRyb2lkLXNwZWNpZmljIGZvbnQgZnJvbSBcIlJvYm90b1wiIGZhbWlseVxuICAgICdzYW5zLXNlcmlmLXRoaW4nLFxuICAgICdBUk5PIFBSTycsXG4gICAgJ0FnZW5jeSBGQicsXG4gICAgJ0FyYWJpYyBUeXBlc2V0dGluZycsXG4gICAgJ0FyaWFsIFVuaWNvZGUgTVMnLFxuICAgICdBdmFudEdhcmRlIEJrIEJUJyxcbiAgICAnQmFua0dvdGhpYyBNZCBCVCcsXG4gICAgJ0JhdGFuZycsXG4gICAgJ0JpdHN0cmVhbSBWZXJhIFNhbnMgTW9ubycsXG4gICAgJ0NhbGlicmknLFxuICAgICdDZW50dXJ5JyxcbiAgICAnQ2VudHVyeSBHb3RoaWMnLFxuICAgICdDbGFyZW5kb24nLFxuICAgICdFVVJPU1RJTEUnLFxuICAgICdGcmFua2xpbiBHb3RoaWMnLFxuICAgICdGdXR1cmEgQmsgQlQnLFxuICAgICdGdXR1cmEgTWQgQlQnLFxuICAgICdHT1RIQU0nLFxuICAgICdHaWxsIFNhbnMnLFxuICAgICdIRUxWJyxcbiAgICAnSGFldHRlbnNjaHdlaWxlcicsXG4gICAgJ0hlbHZldGljYSBOZXVlJyxcbiAgICAnSHVtYW5zdDUyMSBCVCcsXG4gICAgJ0xlZWxhd2FkZWUnLFxuICAgICdMZXR0ZXIgR290aGljJyxcbiAgICAnTGV2ZW5pbSBNVCcsXG4gICAgJ0x1Y2lkYSBCcmlnaHQnLFxuICAgICdMdWNpZGEgU2FucycsXG4gICAgJ01lbmxvJyxcbiAgICAnTVMgTWluY2hvJyxcbiAgICAnTVMgT3V0bG9vaycsXG4gICAgJ01TIFJlZmVyZW5jZSBTcGVjaWFsdHknLFxuICAgICdNUyBVSSBHb3RoaWMnLFxuICAgICdNVCBFeHRyYScsXG4gICAgJ01ZUklBRCBQUk8nLFxuICAgICdNYXJsZXR0JyxcbiAgICAnTWVpcnlvIFVJJyxcbiAgICAnTWljcm9zb2Z0IFVpZ2h1cicsXG4gICAgJ01pbmlvbiBQcm8nLFxuICAgICdNb25vdHlwZSBDb3JzaXZhJyxcbiAgICAnUE1pbmdMaVUnLFxuICAgICdQcmlzdGluYScsXG4gICAgJ1NDUklQVElOQScsXG4gICAgJ1NlZ29lIFVJIExpZ2h0JyxcbiAgICAnU2VyaWZhJyxcbiAgICAnU2ltSGVpJyxcbiAgICAnU21hbGwgRm9udHMnLFxuICAgICdTdGFjY2F0bzIyMiBCVCcsXG4gICAgJ1RSQUpBTiBQUk8nLFxuICAgICdVbml2ZXJzIENFIDU1IE1lZGl1bScsXG4gICAgJ1ZyaW5kYScsXG4gICAgJ1pXQWRvYmVGJyxcbl07XG4vLyBrdWRvcyB0byBodHRwOi8vd3d3LmxhbGl0Lm9yZy9sYWIvamF2YXNjcmlwdC1jc3MtZm9udC1kZXRlY3QvXG5mdW5jdGlvbiBnZXRGb250cygpIHtcbiAgICAvLyBSdW5uaW5nIHRoZSBzY3JpcHQgaW4gYW4gaWZyYW1lIG1ha2VzIGl0IG5vdCBhZmZlY3QgdGhlIHBhZ2UgbG9vayBhbmQgbm90IGJlIGFmZmVjdGVkIGJ5IHRoZSBwYWdlIENTUy4gU2VlOlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvaXNzdWVzLzU5MlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvaXNzdWVzLzYyOFxuICAgIHJldHVybiB3aXRoSWZyYW1lKGZ1bmN0aW9uIChfLCBfYSkge1xuICAgICAgICB2YXIgZG9jdW1lbnQgPSBfYS5kb2N1bWVudDtcbiAgICAgICAgdmFyIGhvbGRlciA9IGRvY3VtZW50LmJvZHk7XG4gICAgICAgIGhvbGRlci5zdHlsZS5mb250U2l6ZSA9IHRleHRTaXplO1xuICAgICAgICAvLyBkaXYgdG8gbG9hZCBzcGFucyBmb3IgdGhlIGRlZmF1bHQgZm9udHMgYW5kIHRoZSBmb250cyB0byBkZXRlY3RcbiAgICAgICAgdmFyIHNwYW5zQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHZhciBkZWZhdWx0V2lkdGggPSB7fTtcbiAgICAgICAgdmFyIGRlZmF1bHRIZWlnaHQgPSB7fTtcbiAgICAgICAgLy8gY3JlYXRlcyBhIHNwYW4gd2hlcmUgdGhlIGZvbnRzIHdpbGwgYmUgbG9hZGVkXG4gICAgICAgIHZhciBjcmVhdGVTcGFuID0gZnVuY3Rpb24gKGZvbnRGYW1pbHkpIHtcbiAgICAgICAgICAgIHZhciBzcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgdmFyIHN0eWxlID0gc3Bhbi5zdHlsZTtcbiAgICAgICAgICAgIHN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgICAgIHN0eWxlLnRvcCA9ICcwJztcbiAgICAgICAgICAgIHN0eWxlLmxlZnQgPSAnMCc7XG4gICAgICAgICAgICBzdHlsZS5mb250RmFtaWx5ID0gZm9udEZhbWlseTtcbiAgICAgICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSB0ZXN0U3RyaW5nO1xuICAgICAgICAgICAgc3BhbnNDb250YWluZXIuYXBwZW5kQ2hpbGQoc3Bhbik7XG4gICAgICAgICAgICByZXR1cm4gc3BhbjtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY3JlYXRlcyBhIHNwYW4gYW5kIGxvYWQgdGhlIGZvbnQgdG8gZGV0ZWN0IGFuZCBhIGJhc2UgZm9udCBmb3IgZmFsbGJhY2tcbiAgICAgICAgdmFyIGNyZWF0ZVNwYW5XaXRoRm9udHMgPSBmdW5jdGlvbiAoZm9udFRvRGV0ZWN0LCBiYXNlRm9udCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVNwYW4oXCInXCIgKyBmb250VG9EZXRlY3QgKyBcIicsXCIgKyBiYXNlRm9udCk7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGNyZWF0ZXMgc3BhbnMgZm9yIHRoZSBiYXNlIGZvbnRzIGFuZCBhZGRzIHRoZW0gdG8gYmFzZUZvbnRzRGl2XG4gICAgICAgIHZhciBpbml0aWFsaXplQmFzZUZvbnRzU3BhbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gYmFzZUZvbnRzLm1hcChjcmVhdGVTcGFuKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY3JlYXRlcyBzcGFucyBmb3IgdGhlIGZvbnRzIHRvIGRldGVjdCBhbmQgYWRkcyB0aGVtIHRvIGZvbnRzRGl2XG4gICAgICAgIHZhciBpbml0aWFsaXplRm9udHNTcGFucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIFN0b3JlcyB7Zm9udE5hbWUgOiBbc3BhbnMgZm9yIHRoYXQgZm9udF19XG4gICAgICAgICAgICB2YXIgc3BhbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKGZvbnQpIHtcbiAgICAgICAgICAgICAgICBzcGFuc1tmb250XSA9IGJhc2VGb250cy5tYXAoZnVuY3Rpb24gKGJhc2VGb250KSB7IHJldHVybiBjcmVhdGVTcGFuV2l0aEZvbnRzKGZvbnQsIGJhc2VGb250KTsgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBmb250TGlzdF8xID0gZm9udExpc3Q7IF9pIDwgZm9udExpc3RfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgZm9udCA9IGZvbnRMaXN0XzFbX2ldO1xuICAgICAgICAgICAgICAgIF9sb29wXzEoZm9udCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3BhbnM7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGNoZWNrcyBpZiBhIGZvbnQgaXMgYXZhaWxhYmxlXG4gICAgICAgIHZhciBpc0ZvbnRBdmFpbGFibGUgPSBmdW5jdGlvbiAoZm9udFNwYW5zKSB7XG4gICAgICAgICAgICByZXR1cm4gYmFzZUZvbnRzLnNvbWUoZnVuY3Rpb24gKGJhc2VGb250LCBiYXNlRm9udEluZGV4KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvbnRTcGFuc1tiYXNlRm9udEluZGV4XS5vZmZzZXRXaWR0aCAhPT0gZGVmYXVsdFdpZHRoW2Jhc2VGb250XSB8fFxuICAgICAgICAgICAgICAgICAgICBmb250U3BhbnNbYmFzZUZvbnRJbmRleF0ub2Zmc2V0SGVpZ2h0ICE9PSBkZWZhdWx0SGVpZ2h0W2Jhc2VGb250XTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICAvLyBjcmVhdGUgc3BhbnMgZm9yIGJhc2UgZm9udHNcbiAgICAgICAgdmFyIGJhc2VGb250c1NwYW5zID0gaW5pdGlhbGl6ZUJhc2VGb250c1NwYW5zKCk7XG4gICAgICAgIC8vIGNyZWF0ZSBzcGFucyBmb3IgZm9udHMgdG8gZGV0ZWN0XG4gICAgICAgIHZhciBmb250c1NwYW5zID0gaW5pdGlhbGl6ZUZvbnRzU3BhbnMoKTtcbiAgICAgICAgLy8gYWRkIGFsbCB0aGUgc3BhbnMgdG8gdGhlIERPTVxuICAgICAgICBob2xkZXIuYXBwZW5kQ2hpbGQoc3BhbnNDb250YWluZXIpO1xuICAgICAgICAvLyBnZXQgdGhlIGRlZmF1bHQgd2lkdGggZm9yIHRoZSB0aHJlZSBiYXNlIGZvbnRzXG4gICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBiYXNlRm9udHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICBkZWZhdWx0V2lkdGhbYmFzZUZvbnRzW2luZGV4XV0gPSBiYXNlRm9udHNTcGFuc1tpbmRleF0ub2Zmc2V0V2lkdGg7IC8vIHdpZHRoIGZvciB0aGUgZGVmYXVsdCBmb250XG4gICAgICAgICAgICBkZWZhdWx0SGVpZ2h0W2Jhc2VGb250c1tpbmRleF1dID0gYmFzZUZvbnRzU3BhbnNbaW5kZXhdLm9mZnNldEhlaWdodDsgLy8gaGVpZ2h0IGZvciB0aGUgZGVmYXVsdCBmb250XG4gICAgICAgIH1cbiAgICAgICAgLy8gY2hlY2sgYXZhaWxhYmxlIGZvbnRzXG4gICAgICAgIHJldHVybiBmb250TGlzdC5maWx0ZXIoZnVuY3Rpb24gKGZvbnQpIHsgcmV0dXJuIGlzRm9udEF2YWlsYWJsZShmb250c1NwYW5zW2ZvbnRdKTsgfSk7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFBsdWdpbnMoKSB7XG4gICAgdmFyIHJhd1BsdWdpbnMgPSBuYXZpZ2F0b3IucGx1Z2lucztcbiAgICBpZiAoIXJhd1BsdWdpbnMpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdmFyIHBsdWdpbnMgPSBbXTtcbiAgICAvLyBTYWZhcmkgMTAgZG9lc24ndCBzdXBwb3J0IGl0ZXJhdGluZyBuYXZpZ2F0b3IucGx1Z2lucyB3aXRoIGZvci4uLm9mXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYXdQbHVnaW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBwbHVnaW4gPSByYXdQbHVnaW5zW2ldO1xuICAgICAgICBpZiAoIXBsdWdpbikge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG1pbWVUeXBlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHBsdWdpbi5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgdmFyIG1pbWVUeXBlID0gcGx1Z2luW2pdO1xuICAgICAgICAgICAgbWltZVR5cGVzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IG1pbWVUeXBlLnR5cGUsXG4gICAgICAgICAgICAgICAgc3VmZml4ZXM6IG1pbWVUeXBlLnN1ZmZpeGVzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcGx1Z2lucy5wdXNoKHtcbiAgICAgICAgICAgIG5hbWU6IHBsdWdpbi5uYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHBsdWdpbi5kZXNjcmlwdGlvbixcbiAgICAgICAgICAgIG1pbWVUeXBlczogbWltZVR5cGVzLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBsdWdpbnM7XG59XG5cbi8vIGh0dHBzOi8vd3d3LmJyb3dzZXJsZWFrcy5jb20vY2FudmFzI2hvdy1kb2VzLWl0LXdvcmtcbmZ1bmN0aW9uIGdldENhbnZhc0ZpbmdlcnByaW50KCkge1xuICAgIHZhciB3aW5kaW5nID0gZmFsc2U7XG4gICAgdmFyIGdlb21ldHJ5O1xuICAgIHZhciB0ZXh0O1xuICAgIHZhciBfYSA9IG1ha2VDYW52YXNDb250ZXh0KCksIGNhbnZhcyA9IF9hWzBdLCBjb250ZXh0ID0gX2FbMV07XG4gICAgaWYgKCFpc1N1cHBvcnRlZChjYW52YXMsIGNvbnRleHQpKSB7XG4gICAgICAgIGdlb21ldHJ5ID0gdGV4dCA9ICcnOyAvLyBUaGUgdmFsdWUgd2lsbCBiZSAndW5zdXBwb3J0ZWQnIGluIHYzLjRcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHdpbmRpbmcgPSBkb2VzU3VwcG9ydFdpbmRpbmcoY29udGV4dCk7XG4gICAgICAgIHJlbmRlclRleHRJbWFnZShjYW52YXMsIGNvbnRleHQpO1xuICAgICAgICB2YXIgdGV4dEltYWdlMSA9IGNhbnZhc1RvU3RyaW5nKGNhbnZhcyk7XG4gICAgICAgIHZhciB0ZXh0SW1hZ2UyID0gY2FudmFzVG9TdHJpbmcoY2FudmFzKTsgLy8gSXQncyBzbGlnaHRseSBmYXN0ZXIgdG8gZG91YmxlLWVuY29kZSB0aGUgdGV4dCBpbWFnZVxuICAgICAgICAvLyBTb21lIGJyb3dzZXJzIGFkZCBhIG5vaXNlIHRvIHRoZSBjYW52YXM6IGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvaXNzdWVzLzc5MVxuICAgICAgICAvLyBUaGUgY2FudmFzIGlzIGV4Y2x1ZGVkIGZyb20gdGhlIGZpbmdlcnByaW50IGluIHRoaXMgY2FzZVxuICAgICAgICBpZiAodGV4dEltYWdlMSAhPT0gdGV4dEltYWdlMikge1xuICAgICAgICAgICAgZ2VvbWV0cnkgPSB0ZXh0ID0gJ3Vuc3RhYmxlJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRleHQgPSB0ZXh0SW1hZ2UxO1xuICAgICAgICAgICAgLy8gVGV4dCBpcyB1bnN0YWJsZTpcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvaXNzdWVzLzU4M1xuICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZpbmdlcnByaW50anMvZmluZ2VycHJpbnRqcy9pc3N1ZXMvMTAzXG4gICAgICAgICAgICAvLyBUaGVyZWZvcmUgaXQncyBleHRyYWN0ZWQgaW50byBhIHNlcGFyYXRlIGltYWdlLlxuICAgICAgICAgICAgcmVuZGVyR2VvbWV0cnlJbWFnZShjYW52YXMsIGNvbnRleHQpO1xuICAgICAgICAgICAgZ2VvbWV0cnkgPSBjYW52YXNUb1N0cmluZyhjYW52YXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHdpbmRpbmc6IHdpbmRpbmcsIGdlb21ldHJ5OiBnZW9tZXRyeSwgdGV4dDogdGV4dCB9O1xufVxuZnVuY3Rpb24gbWFrZUNhbnZhc0NvbnRleHQoKSB7XG4gICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IDE7XG4gICAgY2FudmFzLmhlaWdodCA9IDE7XG4gICAgcmV0dXJuIFtjYW52YXMsIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpXTtcbn1cbmZ1bmN0aW9uIGlzU3VwcG9ydGVkKGNhbnZhcywgY29udGV4dCkge1xuICAgIHJldHVybiAhIShjb250ZXh0ICYmIGNhbnZhcy50b0RhdGFVUkwpO1xufVxuZnVuY3Rpb24gZG9lc1N1cHBvcnRXaW5kaW5nKGNvbnRleHQpIHtcbiAgICAvLyBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNzA4MjUwMjQ2NTUvaHR0cDovL2Jsb2dzLmFkb2JlLmNvbS93ZWJwbGF0Zm9ybS8yMDEzLzAxLzMwL3dpbmRpbmctcnVsZXMtaW4tY2FudmFzL1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9Nb2Rlcm5penIvTW9kZXJuaXpyL2Jsb2IvbWFzdGVyL2ZlYXR1cmUtZGV0ZWN0cy9jYW52YXMvd2luZGluZy5qc1xuICAgIGNvbnRleHQucmVjdCgwLCAwLCAxMCwgMTApO1xuICAgIGNvbnRleHQucmVjdCgyLCAyLCA2LCA2KTtcbiAgICByZXR1cm4gIWNvbnRleHQuaXNQb2ludEluUGF0aCg1LCA1LCAnZXZlbm9kZCcpO1xufVxuZnVuY3Rpb24gcmVuZGVyVGV4dEltYWdlKGNhbnZhcywgY29udGV4dCkge1xuICAgIC8vIFJlc2l6aW5nIHRoZSBjYW52YXMgY2xlYW5zIGl0XG4gICAgY2FudmFzLndpZHRoID0gMjQwO1xuICAgIGNhbnZhcy5oZWlnaHQgPSA2MDtcbiAgICBjb250ZXh0LnRleHRCYXNlbGluZSA9ICdhbHBoYWJldGljJztcbiAgICBjb250ZXh0LmZpbGxTdHlsZSA9ICcjZjYwJztcbiAgICBjb250ZXh0LmZpbGxSZWN0KDEwMCwgMSwgNjIsIDIwKTtcbiAgICBjb250ZXh0LmZpbGxTdHlsZSA9ICcjMDY5JztcbiAgICAvLyBJdCdzIGltcG9ydGFudCB0byB1c2UgZXhwbGljaXQgYnVpbHQtaW4gZm9udHMgaW4gb3JkZXIgdG8gZXhjbHVkZSB0aGUgYWZmZWN0IG9mIGZvbnQgcHJlZmVyZW5jZXNcbiAgICAvLyAodGhlcmUgaXMgYSBzZXBhcmF0ZSBlbnRyb3B5IHNvdXJjZSBmb3IgdGhlbSkuXG4gICAgY29udGV4dC5mb250ID0gJzExcHQgXCJUaW1lcyBOZXcgUm9tYW5cIic7XG4gICAgLy8gVGhlIGNob2ljZSBvZiBlbW9qaXMgaGFzIGEgZ2lnYW50aWMgaW1wYWN0IG9uIHJlbmRlcmluZyBwZXJmb3JtYW5jZSAoZXNwZWNpYWxseSBpbiBGRikuXG4gICAgLy8gU29tZSBuZXdlciBlbW9qaXMgY2F1c2UgaXQgdG8gc2xvdyBkb3duIDUwLTIwMCB0aW1lcy5cbiAgICAvLyBUaGVyZSBtdXN0IGJlIG5vIHRleHQgdG8gdGhlIHJpZ2h0IG9mIHRoZSBlbW9qaSwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvaXNzdWVzLzU3NFxuICAgIC8vIEEgYmFyZSBlbW9qaSBzaG91bGRuJ3QgYmUgdXNlZCBiZWNhdXNlIHRoZSBjYW52YXMgd2lsbCBjaGFuZ2UgZGVwZW5kaW5nIG9uIHRoZSBzY3JpcHQgZW5jb2Rpbmc6XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZpbmdlcnByaW50anMvZmluZ2VycHJpbnRqcy9pc3N1ZXMvNjZcbiAgICAvLyBFc2NhcGUgc2VxdWVuY2Ugc2hvdWxkbid0IGJlIHVzZWQgdG9vIGJlY2F1c2UgVGVyc2VyIHdpbGwgdHVybiBpdCBpbnRvIGEgYmFyZSB1bmljb2RlLlxuICAgIHZhciBwcmludGVkVGV4dCA9IFwiQ3dtIGZqb3JkYmFuayBnbHkgXCIgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDU1MzU3LCA1NjgzNSkgLyog8J+YgyAqLztcbiAgICBjb250ZXh0LmZpbGxUZXh0KHByaW50ZWRUZXh0LCAyLCAxNSk7XG4gICAgY29udGV4dC5maWxsU3R5bGUgPSAncmdiYSgxMDIsIDIwNCwgMCwgMC4yKSc7XG4gICAgY29udGV4dC5mb250ID0gJzE4cHQgQXJpYWwnO1xuICAgIGNvbnRleHQuZmlsbFRleHQocHJpbnRlZFRleHQsIDQsIDQ1KTtcbn1cbmZ1bmN0aW9uIHJlbmRlckdlb21ldHJ5SW1hZ2UoY2FudmFzLCBjb250ZXh0KSB7XG4gICAgLy8gUmVzaXppbmcgdGhlIGNhbnZhcyBjbGVhbnMgaXRcbiAgICBjYW52YXMud2lkdGggPSAxMjI7XG4gICAgY2FudmFzLmhlaWdodCA9IDExMDtcbiAgICAvLyBDYW52YXMgYmxlbmRpbmdcbiAgICAvLyBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNzA4MjYxOTQxMjEvaHR0cDovL2Jsb2dzLmFkb2JlLmNvbS93ZWJwbGF0Zm9ybS8yMDEzLzAxLzI4L2JsZW5kaW5nLWZlYXR1cmVzLWluLWNhbnZhcy9cbiAgICAvLyBodHRwOi8vanNmaWRkbGUubmV0L05EWVY4LzE2L1xuICAgIGNvbnRleHQuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ211bHRpcGx5JztcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gW1xuICAgICAgICBbJyNmMmYnLCA0MCwgNDBdLFxuICAgICAgICBbJyMyZmYnLCA4MCwgNDBdLFxuICAgICAgICBbJyNmZjInLCA2MCwgODBdLFxuICAgIF07IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBfYiA9IF9hW19pXSwgY29sb3IgPSBfYlswXSwgeCA9IF9iWzFdLCB5ID0gX2JbMl07XG4gICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gY29sb3I7XG4gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICAgIGNvbnRleHQuYXJjKHgsIHksIDQwLCAwLCBNYXRoLlBJICogMiwgdHJ1ZSk7XG4gICAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGNvbnRleHQuZmlsbCgpO1xuICAgIH1cbiAgICAvLyBDYW52YXMgd2luZGluZ1xuICAgIC8vIGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDEzMDkxMzA2MTYzMi9odHRwOi8vYmxvZ3MuYWRvYmUuY29tL3dlYnBsYXRmb3JtLzIwMTMvMDEvMzAvd2luZGluZy1ydWxlcy1pbi1jYW52YXMvXG4gICAgLy8gaHR0cDovL2pzZmlkZGxlLm5ldC9ORFlWOC8xOS9cbiAgICBjb250ZXh0LmZpbGxTdHlsZSA9ICcjZjljJztcbiAgICBjb250ZXh0LmFyYyg2MCwgNjAsIDYwLCAwLCBNYXRoLlBJICogMiwgdHJ1ZSk7XG4gICAgY29udGV4dC5hcmMoNjAsIDYwLCAyMCwgMCwgTWF0aC5QSSAqIDIsIHRydWUpO1xuICAgIGNvbnRleHQuZmlsbCgnZXZlbm9kZCcpO1xufVxuZnVuY3Rpb24gY2FudmFzVG9TdHJpbmcoY2FudmFzKSB7XG4gICAgcmV0dXJuIGNhbnZhcy50b0RhdGFVUkwoKTtcbn1cblxuLyoqXG4gKiBUaGlzIGlzIGEgY3J1ZGUgYW5kIHByaW1pdGl2ZSB0b3VjaCBzY3JlZW4gZGV0ZWN0aW9uLiBJdCdzIG5vdCBwb3NzaWJsZSB0byBjdXJyZW50bHkgcmVsaWFibHkgZGV0ZWN0IHRoZSBhdmFpbGFiaWxpdHlcbiAqIG9mIGEgdG91Y2ggc2NyZWVuIHdpdGggYSBKUywgd2l0aG91dCBhY3R1YWxseSBzdWJzY3JpYmluZyB0byBhIHRvdWNoIGV2ZW50LlxuICpcbiAqIEBzZWUgaHR0cDovL3d3dy5zdHVjb3guY29tL2Jsb2cveW91LWNhbnQtZGV0ZWN0LWEtdG91Y2hzY3JlZW4vXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9Nb2Rlcm5penIvTW9kZXJuaXpyL2lzc3Vlcy81NDhcbiAqL1xuZnVuY3Rpb24gZ2V0VG91Y2hTdXBwb3J0KCkge1xuICAgIHZhciBuID0gbmF2aWdhdG9yO1xuICAgIHZhciBtYXhUb3VjaFBvaW50cyA9IDA7XG4gICAgdmFyIHRvdWNoRXZlbnQ7XG4gICAgaWYgKG4ubWF4VG91Y2hQb2ludHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtYXhUb3VjaFBvaW50cyA9IHRvSW50KG4ubWF4VG91Y2hQb2ludHMpO1xuICAgIH1cbiAgICBlbHNlIGlmIChuLm1zTWF4VG91Y2hQb2ludHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtYXhUb3VjaFBvaW50cyA9IG4ubXNNYXhUb3VjaFBvaW50cztcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ1RvdWNoRXZlbnQnKTtcbiAgICAgICAgdG91Y2hFdmVudCA9IHRydWU7XG4gICAgfVxuICAgIGNhdGNoIChfYSkge1xuICAgICAgICB0b3VjaEV2ZW50ID0gZmFsc2U7XG4gICAgfVxuICAgIHZhciB0b3VjaFN0YXJ0ID0gJ29udG91Y2hzdGFydCcgaW4gd2luZG93O1xuICAgIHJldHVybiB7XG4gICAgICAgIG1heFRvdWNoUG9pbnRzOiBtYXhUb3VjaFBvaW50cyxcbiAgICAgICAgdG91Y2hFdmVudDogdG91Y2hFdmVudCxcbiAgICAgICAgdG91Y2hTdGFydDogdG91Y2hTdGFydCxcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRPc0NwdSgpIHtcbiAgICByZXR1cm4gbmF2aWdhdG9yLm9zY3B1O1xufVxuXG5mdW5jdGlvbiBnZXRMYW5ndWFnZXMoKSB7XG4gICAgdmFyIG4gPSBuYXZpZ2F0b3I7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHZhciBsYW5ndWFnZSA9IG4ubGFuZ3VhZ2UgfHwgbi51c2VyTGFuZ3VhZ2UgfHwgbi5icm93c2VyTGFuZ3VhZ2UgfHwgbi5zeXN0ZW1MYW5ndWFnZTtcbiAgICBpZiAobGFuZ3VhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXN1bHQucHVzaChbbGFuZ3VhZ2VdKTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkobi5sYW5ndWFnZXMpKSB7XG4gICAgICAgIC8vIFN0YXJ0aW5nIGZyb20gQ2hyb21pdW0gODYsIHRoZXJlIGlzIG9ubHkgYSBzaW5nbGUgdmFsdWUgaW4gYG5hdmlnYXRvci5sYW5ndWFnZWAgaW4gSW5jb2duaXRvIG1vZGU6XG4gICAgICAgIC8vIHRoZSB2YWx1ZSBvZiBgbmF2aWdhdG9yLmxhbmd1YWdlYC4gVGhlcmVmb3JlIHRoZSB2YWx1ZSBpcyBpZ25vcmVkIGluIHRoaXMgYnJvd3Nlci5cbiAgICAgICAgaWYgKCEoaXNDaHJvbWl1bSgpICYmIGlzQ2hyb21pdW04Nk9yTmV3ZXIoKSkpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKG4ubGFuZ3VhZ2VzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2Ygbi5sYW5ndWFnZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciBsYW5ndWFnZXMgPSBuLmxhbmd1YWdlcztcbiAgICAgICAgaWYgKGxhbmd1YWdlcykge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobGFuZ3VhZ2VzLnNwbGl0KCcsJykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGdldENvbG9yRGVwdGgoKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5zY3JlZW4uY29sb3JEZXB0aDtcbn1cblxuZnVuY3Rpb24gZ2V0RGV2aWNlTWVtb3J5KCkge1xuICAgIC8vIGBuYXZpZ2F0b3IuZGV2aWNlTWVtb3J5YCBpcyBhIHN0cmluZyBjb250YWluaW5nIGEgbnVtYmVyIGluIHNvbWUgdW5pZGVudGlmaWVkIGNhc2VzXG4gICAgcmV0dXJuIHJlcGxhY2VOYU4odG9GbG9hdChuYXZpZ2F0b3IuZGV2aWNlTWVtb3J5KSwgdW5kZWZpbmVkKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyZWVuUmVzb2x1dGlvbigpIHtcbiAgICB2YXIgcyA9IHNjcmVlbjtcbiAgICAvLyBTb21lIGJyb3dzZXJzIHJldHVybiBzY3JlZW4gcmVzb2x1dGlvbiBhcyBzdHJpbmdzLCBlLmcuIFwiMTIwMFwiLCBpbnN0ZWFkIG9mIGEgbnVtYmVyLCBlLmcuIDEyMDAuXG4gICAgLy8gSSBzdXNwZWN0IGl0J3MgZG9uZSBieSBjZXJ0YWluIHBsdWdpbnMgdGhhdCByYW5kb21pemUgYnJvd3NlciBwcm9wZXJ0aWVzIHRvIHByZXZlbnQgZmluZ2VycHJpbnRpbmcuXG4gICAgLy8gU29tZSBicm93c2VycyBldmVuIHJldHVybiAgc2NyZWVuIHJlc29sdXRpb24gYXMgbm90IG51bWJlcnMuXG4gICAgdmFyIHBhcnNlRGltZW5zaW9uID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiByZXBsYWNlTmFOKHRvSW50KHZhbHVlKSwgbnVsbCk7IH07XG4gICAgdmFyIGRpbWVuc2lvbnMgPSBbcGFyc2VEaW1lbnNpb24ocy53aWR0aCksIHBhcnNlRGltZW5zaW9uKHMuaGVpZ2h0KV07XG4gICAgZGltZW5zaW9ucy5zb3J0KCkucmV2ZXJzZSgpO1xuICAgIHJldHVybiBkaW1lbnNpb25zO1xufVxuXG52YXIgc2NyZWVuRnJhbWVDaGVja0ludGVydmFsID0gMjUwMDtcbnZhciByb3VuZGluZ1ByZWNpc2lvbiA9IDEwO1xuLy8gVGhlIHR5cGUgaXMgcmVhZG9ubHkgdG8gcHJvdGVjdCBmcm9tIHVud2FudGVkIG11dGF0aW9uc1xudmFyIHNjcmVlbkZyYW1lQmFja3VwO1xudmFyIHNjcmVlbkZyYW1lU2l6ZVRpbWVvdXRJZDtcbi8qKlxuICogU3RhcnRzIHdhdGNoaW5nIHRoZSBzY3JlZW4gZnJhbWUgc2l6ZS4gV2hlbiBhIG5vbi16ZXJvIHNpemUgYXBwZWFycywgdGhlIHNpemUgaXMgc2F2ZWQgYW5kIHRoZSB3YXRjaCBpcyBzdG9wcGVkLlxuICogTGF0ZXIsIHdoZW4gYGdldFNjcmVlbkZyYW1lYCBydW5zLCBpdCB3aWxsIHJldHVybiB0aGUgc2F2ZWQgbm9uLXplcm8gc2l6ZSBpZiB0aGUgY3VycmVudCBzaXplIGlzIG51bGwuXG4gKlxuICogVGhpcyB0cmljayBpcyByZXF1aXJlZCB0byBtaXRpZ2F0ZSB0aGUgZmFjdCB0aGF0IHRoZSBzY3JlZW4gZnJhbWUgdHVybnMgbnVsbCBpbiBzb21lIGNhc2VzLlxuICogU2VlIG1vcmUgb24gdGhpcyBhdCBodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9maW5nZXJwcmludGpzL2lzc3Vlcy81NjhcbiAqL1xuZnVuY3Rpb24gd2F0Y2hTY3JlZW5GcmFtZSgpIHtcbiAgICBpZiAoc2NyZWVuRnJhbWVTaXplVGltZW91dElkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgY2hlY2tTY3JlZW5GcmFtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZyYW1lU2l6ZSA9IGdldEN1cnJlbnRTY3JlZW5GcmFtZSgpO1xuICAgICAgICBpZiAoaXNGcmFtZVNpemVOdWxsKGZyYW1lU2l6ZSkpIHtcbiAgICAgICAgICAgIHNjcmVlbkZyYW1lU2l6ZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoY2hlY2tTY3JlZW5GcmFtZSwgc2NyZWVuRnJhbWVDaGVja0ludGVydmFsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNjcmVlbkZyYW1lQmFja3VwID0gZnJhbWVTaXplO1xuICAgICAgICAgICAgc2NyZWVuRnJhbWVTaXplVGltZW91dElkID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBjaGVja1NjcmVlbkZyYW1lKCk7XG59XG5mdW5jdGlvbiBnZXRTY3JlZW5GcmFtZSgpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgIHdhdGNoU2NyZWVuRnJhbWUoKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkgeyByZXR1cm4gdHNsaWIuX19hd2FpdGVyKF90aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZnJhbWVTaXplO1xuICAgICAgICByZXR1cm4gdHNsaWIuX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9hKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICBmcmFtZVNpemUgPSBnZXRDdXJyZW50U2NyZWVuRnJhbWUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0ZyYW1lU2l6ZU51bGwoZnJhbWVTaXplKSkgcmV0dXJuIFszIC8qYnJlYWsqLywgMl07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzY3JlZW5GcmFtZUJhY2t1cCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIHRzbGliLl9fc3ByZWFkQXJyYXlzKHNjcmVlbkZyYW1lQmFja3VwKV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFnZXRGdWxsc2NyZWVuRWxlbWVudCgpKSByZXR1cm4gWzMgLypicmVhayovLCAyXTtcbiAgICAgICAgICAgICAgICAgICAgLy8gU29tZSBicm93c2VycyBzZXQgdGhlIHNjcmVlbiBmcmFtZSB0byB6ZXJvIHdoZW4gcHJvZ3JhbW1hdGljIGZ1bGxzY3JlZW4gaXMgb24uXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZXJlIGlzIGEgY2hhbmNlIG9mIGdldHRpbmcgYSBub24temVybyBmcmFtZSBhZnRlciBleGl0aW5nIHRoZSBmdWxsc2NyZWVuLlxuICAgICAgICAgICAgICAgICAgICAvLyBTZWUgbW9yZSBvbiB0aGlzIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9maW5nZXJwcmludGpzL2ZpbmdlcnByaW50anMvaXNzdWVzLzU2OFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCBleGl0RnVsbHNjcmVlbigpXTtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIC8vIFNvbWUgYnJvd3NlcnMgc2V0IHRoZSBzY3JlZW4gZnJhbWUgdG8gemVybyB3aGVuIHByb2dyYW1tYXRpYyBmdWxsc2NyZWVuIGlzIG9uLlxuICAgICAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBhIGNoYW5jZSBvZiBnZXR0aW5nIGEgbm9uLXplcm8gZnJhbWUgYWZ0ZXIgZXhpdGluZyB0aGUgZnVsbHNjcmVlbi5cbiAgICAgICAgICAgICAgICAgICAgLy8gU2VlIG1vcmUgb24gdGhpcyBhdCBodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9maW5nZXJwcmludGpzL2lzc3Vlcy81NjhcbiAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xuICAgICAgICAgICAgICAgICAgICBmcmFtZVNpemUgPSBnZXRDdXJyZW50U2NyZWVuRnJhbWUoKTtcbiAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAyO1xuICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0ZyYW1lU2l6ZU51bGwoZnJhbWVTaXplKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuRnJhbWVCYWNrdXAgPSBmcmFtZVNpemU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIGZyYW1lU2l6ZV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pOyB9O1xufVxuLyoqXG4gKiBTb21ldGltZXMgdGhlIGF2YWlsYWJsZSBzY3JlZW4gcmVzb2x1dGlvbiBjaGFuZ2VzIGEgYml0LCBlLmcuIDE5MDB4MTQ0MCDihpIgMTkwMHgxNDM5LiBBIHBvc3NpYmxlIHJlYXNvbjogbWFjT1MgRG9ja1xuICogc2hyaW5rcyB0byBmaXQgbW9yZSBpY29ucyB3aGVuIHRoZXJlIGlzIHRvbyBsaXR0bGUgc3BhY2UuIFRoZSByb3VuZGluZyBpcyB1c2VkIHRvIG1pdGlnYXRlIHRoZSBkaWZmZXJlbmNlLlxuICovXG5mdW5jdGlvbiBnZXRSb3VuZGVkU2NyZWVuRnJhbWUoKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcbiAgICB2YXIgc2NyZWVuRnJhbWVHZXR0ZXIgPSBnZXRTY3JlZW5GcmFtZSgpO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IHJldHVybiB0c2xpYi5fX2F3YWl0ZXIoX3RoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmcmFtZVNpemUsIHByb2Nlc3NTaXplO1xuICAgICAgICByZXR1cm4gdHNsaWIuX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9hKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwOiByZXR1cm4gWzQgLyp5aWVsZCovLCBzY3JlZW5GcmFtZUdldHRlcigpXTtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIGZyYW1lU2l6ZSA9IF9hLnNlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc1NpemUgPSBmdW5jdGlvbiAoc2lkZVNpemUpIHsgcmV0dXJuIChzaWRlU2l6ZSA9PT0gbnVsbCA/IG51bGwgOiByb3VuZChzaWRlU2l6ZSwgcm91bmRpbmdQcmVjaXNpb24pKTsgfTtcbiAgICAgICAgICAgICAgICAgICAgLy8gSXQgbWlnaHQgbG9vayBsaWtlIEkgZG9uJ3Qga25vdyBhYm91dCBgZm9yYCBhbmQgYG1hcGAuXG4gICAgICAgICAgICAgICAgICAgIC8vIEluIGZhY3QsIHN1Y2ggY29kZSBpcyB1c2VkIHRvIGF2b2lkIFR5cGVTY3JpcHQgaXNzdWVzIHdpdGhvdXQgdXNpbmcgYGFzYC5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFtwcm9jZXNzU2l6ZShmcmFtZVNpemVbMF0pLCBwcm9jZXNzU2l6ZShmcmFtZVNpemVbMV0pLCBwcm9jZXNzU2l6ZShmcmFtZVNpemVbMl0pLCBwcm9jZXNzU2l6ZShmcmFtZVNpemVbM10pXV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pOyB9O1xufVxuZnVuY3Rpb24gZ2V0Q3VycmVudFNjcmVlbkZyYW1lKCkge1xuICAgIHZhciBzID0gc2NyZWVuO1xuICAgIC8vIFNvbWUgYnJvd3NlcnMgcmV0dXJuIHNjcmVlbiByZXNvbHV0aW9uIGFzIHN0cmluZ3MsIGUuZy4gXCIxMjAwXCIsIGluc3RlYWQgb2YgYSBudW1iZXIsIGUuZy4gMTIwMC5cbiAgICAvLyBJIHN1c3BlY3QgaXQncyBkb25lIGJ5IGNlcnRhaW4gcGx1Z2lucyB0aGF0IHJhbmRvbWl6ZSBicm93c2VyIHByb3BlcnRpZXMgdG8gcHJldmVudCBmaW5nZXJwcmludGluZy5cbiAgICAvL1xuICAgIC8vIFNvbWUgYnJvd3NlcnMgKElFLCBFZGdlIOKJpDE4KSBkb24ndCBwcm92aWRlIGBzY3JlZW4uYXZhaWxMZWZ0YCBhbmQgYHNjcmVlbi5hdmFpbFRvcGAuIFRoZSBwcm9wZXJ0eSB2YWx1ZXMgYXJlXG4gICAgLy8gcmVwbGFjZWQgd2l0aCAwIGluIHN1Y2ggY2FzZXMgdG8gbm90IGxvc2UgdGhlIGVudHJvcHkgZnJvbSBgc2NyZWVuLmF2YWlsV2lkdGhgIGFuZCBgc2NyZWVuLmF2YWlsSGVpZ2h0YC5cbiAgICByZXR1cm4gW1xuICAgICAgICByZXBsYWNlTmFOKHRvRmxvYXQocy5hdmFpbFRvcCksIG51bGwpLFxuICAgICAgICByZXBsYWNlTmFOKHRvRmxvYXQocy53aWR0aCkgLSB0b0Zsb2F0KHMuYXZhaWxXaWR0aCkgLSByZXBsYWNlTmFOKHRvRmxvYXQocy5hdmFpbExlZnQpLCAwKSwgbnVsbCksXG4gICAgICAgIHJlcGxhY2VOYU4odG9GbG9hdChzLmhlaWdodCkgLSB0b0Zsb2F0KHMuYXZhaWxIZWlnaHQpIC0gcmVwbGFjZU5hTih0b0Zsb2F0KHMuYXZhaWxUb3ApLCAwKSwgbnVsbCksXG4gICAgICAgIHJlcGxhY2VOYU4odG9GbG9hdChzLmF2YWlsTGVmdCksIG51bGwpLFxuICAgIF07XG59XG5mdW5jdGlvbiBpc0ZyYW1lU2l6ZU51bGwoZnJhbWVTaXplKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyArK2kpIHtcbiAgICAgICAgaWYgKGZyYW1lU2l6ZVtpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBnZXRIYXJkd2FyZUNvbmN1cnJlbmN5KCkge1xuICAgIC8vIHNvbWV0aW1lcyBoYXJkd2FyZSBjb25jdXJyZW5jeSBpcyBhIHN0cmluZ1xuICAgIHJldHVybiByZXBsYWNlTmFOKHRvSW50KG5hdmlnYXRvci5oYXJkd2FyZUNvbmN1cnJlbmN5KSwgdW5kZWZpbmVkKTtcbn1cblxuZnVuY3Rpb24gZ2V0VGltZXpvbmUoKSB7XG4gICAgdmFyIF9hO1xuICAgIHZhciBEYXRlVGltZUZvcm1hdCA9IChfYSA9IHdpbmRvdy5JbnRsKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuRGF0ZVRpbWVGb3JtYXQ7XG4gICAgaWYgKERhdGVUaW1lRm9ybWF0KSB7XG4gICAgICAgIHZhciB0aW1lem9uZSA9IG5ldyBEYXRlVGltZUZvcm1hdCgpLnJlc29sdmVkT3B0aW9ucygpLnRpbWVab25lO1xuICAgICAgICBpZiAodGltZXpvbmUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aW1lem9uZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBGb3IgYnJvd3NlcnMgdGhhdCBkb24ndCBzdXBwb3J0IHRpbWV6b25lIG5hbWVzXG4gICAgLy8gVGhlIG1pbnVzIGlzIGludGVudGlvbmFsIGJlY2F1c2UgdGhlIEpTIG9mZnNldCBpcyBvcHBvc2l0ZSB0byB0aGUgcmVhbCBvZmZzZXRcbiAgICB2YXIgb2Zmc2V0ID0gLWdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgcmV0dXJuIFwiVVRDXCIgKyAob2Zmc2V0ID49IDAgPyAnKycgOiAnJykgKyBNYXRoLmFicyhvZmZzZXQpO1xufVxuZnVuY3Rpb24gZ2V0VGltZXpvbmVPZmZzZXQoKSB7XG4gICAgdmFyIGN1cnJlbnRZZWFyID0gbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpO1xuICAgIC8vIFRoZSB0aW1lem9uZSBvZmZzZXQgbWF5IGNoYW5nZSBvdmVyIHRpbWUgZHVlIHRvIGRheWxpZ2h0IHNhdmluZyB0aW1lIChEU1QpIHNoaWZ0cy5cbiAgICAvLyBUaGUgbm9uLURTVCB0aW1lem9uZSBvZmZzZXQgaXMgdXNlZCBhcyB0aGUgcmVzdWx0IHRpbWV6b25lIG9mZnNldC5cbiAgICAvLyBTaW5jZSB0aGUgRFNUIHNlYXNvbiBkaWZmZXJzIGluIHRoZSBub3J0aGVybiBhbmQgdGhlIHNvdXRoZXJuIGhlbWlzcGhlcmVzLFxuICAgIC8vIGJvdGggSmFudWFyeSBhbmQgSnVseSB0aW1lem9uZXMgb2Zmc2V0cyBhcmUgY29uc2lkZXJlZC5cbiAgICByZXR1cm4gTWF0aC5tYXgoXG4gICAgLy8gYGdldFRpbWV6b25lT2Zmc2V0YCByZXR1cm5zIGEgbnVtYmVyIGFzIGEgc3RyaW5nIGluIHNvbWUgdW5pZGVudGlmaWVkIGNhc2VzXG4gICAgdG9GbG9hdChuZXcgRGF0ZShjdXJyZW50WWVhciwgMCwgMSkuZ2V0VGltZXpvbmVPZmZzZXQoKSksIHRvRmxvYXQobmV3IERhdGUoY3VycmVudFllYXIsIDYsIDEpLmdldFRpbWV6b25lT2Zmc2V0KCkpKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2Vzc2lvblN0b3JhZ2UoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuICEhd2luZG93LnNlc3Npb25TdG9yYWdlO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLyogU2VjdXJpdHlFcnJvciB3aGVuIHJlZmVyZW5jaW5nIGl0IG1lYW5zIGl0IGV4aXN0cyAqL1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5cbi8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTc4MTQ0N1xuZnVuY3Rpb24gZ2V0TG9jYWxTdG9yYWdlKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiAhIXdpbmRvdy5sb2NhbFN0b3JhZ2U7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIC8qIFNlY3VyaXR5RXJyb3Igd2hlbiByZWZlcmVuY2luZyBpdCBtZWFucyBpdCBleGlzdHMgKi9cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRJbmRleGVkREIoKSB7XG4gICAgLy8gSUUgYW5kIEVkZ2UgZG9uJ3QgYWxsb3cgYWNjZXNzaW5nIGluZGV4ZWREQiBpbiBwcml2YXRlIG1vZGUsIHRoZXJlZm9yZSBJRSBhbmQgRWRnZSB3aWxsIGhhdmUgZGlmZmVyZW50XG4gICAgLy8gdmlzaXRvciBpZGVudGlmaWVyIGluIG5vcm1hbCBhbmQgcHJpdmF0ZSBtb2Rlcy5cbiAgICBpZiAoaXNUcmlkZW50KCkgfHwgaXNFZGdlSFRNTCgpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiAhIXdpbmRvdy5pbmRleGVkREI7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIC8qIFNlY3VyaXR5RXJyb3Igd2hlbiByZWZlcmVuY2luZyBpdCBtZWFucyBpdCBleGlzdHMgKi9cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRPcGVuRGF0YWJhc2UoKSB7XG4gICAgcmV0dXJuICEhd2luZG93Lm9wZW5EYXRhYmFzZTtcbn1cblxuZnVuY3Rpb24gZ2V0Q3B1Q2xhc3MoKSB7XG4gICAgcmV0dXJuIG5hdmlnYXRvci5jcHVDbGFzcztcbn1cblxuZnVuY3Rpb24gZ2V0UGxhdGZvcm0oKSB7XG4gICAgLy8gQW5kcm9pZCBDaHJvbWUgODYgYW5kIDg3IGFuZCBBbmRyb2lkIEZpcmVmb3ggODAgYW5kIDg0IGRvbid0IG1vY2sgdGhlIHBsYXRmb3JtIHZhbHVlIHdoZW4gZGVza3RvcCBtb2RlIGlzIHJlcXVlc3RlZFxuICAgIHZhciBwbGF0Zm9ybSA9IG5hdmlnYXRvci5wbGF0Zm9ybTtcbiAgICAvLyBpT1MgbW9ja3MgdGhlIHBsYXRmb3JtIHZhbHVlIHdoZW4gZGVza3RvcCB2ZXJzaW9uIGlzIHJlcXVlc3RlZDogaHR0cHM6Ly9naXRodWIuY29tL2ZpbmdlcnByaW50anMvZmluZ2VycHJpbnRqcy9pc3N1ZXMvNTE0XG4gICAgLy8gaVBhZCB1c2VzIGRlc2t0b3AgbW9kZSBieSBkZWZhdWx0IHNpbmNlIGlPUyAxM1xuICAgIC8vIFRoZSB2YWx1ZSBpcyAnTWFjSW50ZWwnIG9uIE0xIE1hY3NcbiAgICAvLyBUaGUgdmFsdWUgaXMgJ2lQaG9uZScgb24gaVBvZCBUb3VjaFxuICAgIGlmIChwbGF0Zm9ybSA9PT0gJ01hY0ludGVsJykge1xuICAgICAgICBpZiAoaXNXZWJLaXQoKSAmJiAhaXNEZXNrdG9wU2FmYXJpKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBpc0lQYWQoKSA/ICdpUGFkJyA6ICdpUGhvbmUnO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwbGF0Zm9ybTtcbn1cblxuZnVuY3Rpb24gZ2V0VmVuZG9yKCkge1xuICAgIHJldHVybiBuYXZpZ2F0b3IudmVuZG9yIHx8ICcnO1xufVxuXG4vKipcbiAqIENoZWNrcyBmb3IgYnJvd3Nlci1zcGVjaWZpYyAobm90IGVuZ2luZSBzcGVjaWZpYykgZ2xvYmFsIHZhcmlhYmxlcyB0byB0ZWxsIGJyb3dzZXJzIHdpdGggdGhlIHNhbWUgZW5naW5lIGFwYXJ0LlxuICogT25seSBzb21ld2hhdCBwb3B1bGFyIGJyb3dzZXJzIGFyZSBjb25zaWRlcmVkLlxuICovXG5mdW5jdGlvbiBnZXRWZW5kb3JGbGF2b3JzKCkge1xuICAgIHZhciBmbGF2b3JzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IFtcbiAgICAgICAgLy8gQmxpbmsgYW5kIHNvbWUgYnJvd3NlcnMgb24gaU9TXG4gICAgICAgICdjaHJvbWUnLFxuICAgICAgICAvLyBTYWZhcmkgb24gbWFjT1NcbiAgICAgICAgJ3NhZmFyaScsXG4gICAgICAgIC8vIENocm9tZSBvbiBpT1MgKGNoZWNrZWQgaW4gODUgb24gMTMgYW5kIDg3IG9uIDE0KVxuICAgICAgICAnX19jcldlYicsXG4gICAgICAgICdfX2dDcldlYicsXG4gICAgICAgIC8vIFlhbmRleCBCcm93c2VyIG9uIGlPUywgbWFjT1MgYW5kIEFuZHJvaWQgKGNoZWNrZWQgaW4gMjEuMiBvbiBpT1MgMTQsIG1hY09TIGFuZCBBbmRyb2lkKVxuICAgICAgICAneWFuZGV4JyxcbiAgICAgICAgLy8gWWFuZGV4IEJyb3dzZXIgb24gaU9TIChjaGVja2VkIGluIDIxLjIgb24gMTQpXG4gICAgICAgICdfX3liJyxcbiAgICAgICAgJ19feWJybycsXG4gICAgICAgIC8vIEZpcmVmb3ggb24gaU9TIChjaGVja2VkIGluIDMyIG9uIDE0KVxuICAgICAgICAnX19maXJlZm94X18nLFxuICAgICAgICAvLyBFZGdlIG9uIGlPUyAoY2hlY2tlZCBpbiA0NiBvbiAxNClcbiAgICAgICAgJ19fZWRnZVRyYWNraW5nUHJldmVudGlvblN0YXRpc3RpY3MnLFxuICAgICAgICAnd2Via2l0JyxcbiAgICAgICAgLy8gT3BlcmEgVG91Y2ggb24gaU9TIChjaGVja2VkIGluIDIuNiBvbiAxNClcbiAgICAgICAgJ29wcnQnLFxuICAgICAgICAvLyBTYW1zdW5nIEludGVybmV0IG9uIEFuZHJvaWQgKGNoZWNrZWQgaW4gMTEuMSlcbiAgICAgICAgJ3NhbXN1bmdBcicsXG4gICAgICAgIC8vIFVDIEJyb3dzZXIgb24gQW5kcm9pZCAoY2hlY2tlZCBpbiAxMi4xMCBhbmQgMTMuMClcbiAgICAgICAgJ3Vjd2ViJyxcbiAgICAgICAgJ1VDU2hlbGxKYXZhJyxcbiAgICAgICAgLy8gUHVmZmluIG9uIEFuZHJvaWQgKGNoZWNrZWQgaW4gOS4wKVxuICAgICAgICAncHVmZmluRGV2aWNlJyxcbiAgICBdOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIga2V5ID0gX2FbX2ldO1xuICAgICAgICB2YXIgdmFsdWUgPSB3aW5kb3dba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGZsYXZvcnMucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmbGF2b3JzLnNvcnQoKTtcbn1cblxuLyoqXG4gKiBuYXZpZ2F0b3IuY29va2llRW5hYmxlZCBjYW5ub3QgZGV0ZWN0IGN1c3RvbSBvciBudWFuY2VkIGNvb2tpZSBibG9ja2luZyBjb25maWd1cmF0aW9ucy4gRm9yIGV4YW1wbGUsIHdoZW4gYmxvY2tpbmdcbiAqIGNvb2tpZXMgdmlhIHRoZSBBZHZhbmNlZCBQcml2YWN5IFNldHRpbmdzIGluIElFOSwgaXQgYWx3YXlzIHJldHVybnMgdHJ1ZS4gQW5kIHRoZXJlIGhhdmUgYmVlbiBpc3N1ZXMgaW4gdGhlIHBhc3Qgd2l0aFxuICogc2l0ZS1zcGVjaWZpYyBleGNlcHRpb25zLiBEb24ndCByZWx5IG9uIGl0LlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2Nvb2tpZXMuanMgVGFrZW4gZnJvbSBoZXJlXG4gKi9cbmZ1bmN0aW9uIGFyZUNvb2tpZXNFbmFibGVkKCkge1xuICAgIHZhciBkID0gZG9jdW1lbnQ7XG4gICAgLy8gVGFrZW4gZnJvbSBoZXJlOiBodHRwczovL2dpdGh1Yi5jb20vTW9kZXJuaXpyL01vZGVybml6ci9ibG9iL21hc3Rlci9mZWF0dXJlLWRldGVjdHMvY29va2llcy5qc1xuICAgIC8vIG5hdmlnYXRvci5jb29raWVFbmFibGVkIGNhbm5vdCBkZXRlY3QgY3VzdG9tIG9yIG51YW5jZWQgY29va2llIGJsb2NraW5nIGNvbmZpZ3VyYXRpb25zLiBGb3IgZXhhbXBsZSwgd2hlbiBibG9ja2luZ1xuICAgIC8vIGNvb2tpZXMgdmlhIHRoZSBBZHZhbmNlZCBQcml2YWN5IFNldHRpbmdzIGluIElFOSwgaXQgYWx3YXlzIHJldHVybnMgdHJ1ZS4gQW5kIHRoZXJlIGhhdmUgYmVlbiBpc3N1ZXMgaW4gdGhlIHBhc3RcbiAgICAvLyB3aXRoIHNpdGUtc3BlY2lmaWMgZXhjZXB0aW9ucy4gRG9uJ3QgcmVseSBvbiBpdC5cbiAgICAvLyB0cnkuLmNhdGNoIGJlY2F1c2Ugc29tZSBpbiBzaXR1YXRpb25zIGBkb2N1bWVudC5jb29raWVgIGlzIGV4cG9zZWQgYnV0IHRocm93cyBhXG4gICAgLy8gU2VjdXJpdHlFcnJvciBpZiB5b3UgdHJ5IHRvIGFjY2VzcyBpdDsgZS5nLiBkb2N1bWVudHMgY3JlYXRlZCBmcm9tIGRhdGEgVVJJc1xuICAgIC8vIG9yIGluIHNhbmRib3hlZCBpZnJhbWVzIChkZXBlbmRpbmcgb24gZmxhZ3MvY29udGV4dClcbiAgICB0cnkge1xuICAgICAgICAvLyBDcmVhdGUgY29va2llXG4gICAgICAgIGQuY29va2llID0gJ2Nvb2tpZXRlc3Q9MTsgU2FtZVNpdGU9U3RyaWN0Oyc7XG4gICAgICAgIHZhciByZXN1bHQgPSBkLmNvb2tpZS5pbmRleE9mKCdjb29raWV0ZXN0PScpICE9PSAtMTtcbiAgICAgICAgLy8gRGVsZXRlIGNvb2tpZVxuICAgICAgICBkLmNvb2tpZSA9ICdjb29raWV0ZXN0PTE7IFNhbWVTaXRlPVN0cmljdDsgZXhwaXJlcz1UaHUsIDAxLUphbi0xOTcwIDAwOjAwOjAxIEdNVCc7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbi8qKlxuICogT25seSBzaW5nbGUgZWxlbWVudCBzZWxlY3RvciBhcmUgc3VwcG9ydGVkIChubyBvcGVyYXRvcnMgbGlrZSBzcGFjZSwgKywgPiwgZXRjKS5cbiAqIGBlbWJlZGAgYW5kIGBwb3NpdGlvbjogZml4ZWQ7YCB3aWxsIGJlIGNvbnNpZGVyZWQgYXMgYmxvY2tlZCBhbnl3YXkgYmVjYXVzZSBpdCBhbHdheXMgaGFzIG5vIG9mZnNldFBhcmVudC5cbiAqIEF2b2lkIGBpZnJhbWVgIGFuZCBhbnl0aGluZyB3aXRoIGBbc3JjPV1gIGJlY2F1c2UgdGhleSBwcm9kdWNlIGV4Y2VzcyBIVFRQIHJlcXVlc3RzLlxuICpcbiAqIFRoZSBcImluYXBwcm9wcmlhdGVcIiBzZWxlY3RvcnMgYXJlIG9iZnVzY2F0ZWQuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9maW5nZXJwcmludGpzL2lzc3Vlcy83MzQuXG4gKiBBIGZ1bmN0aW9uIGlzIHVzZWQgaW5zdGVhZCBvZiBhIHBsYWluIG9iamVjdCB0byBoZWxwIHRyZWUtc2hha2luZy5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gY29kZSBpcyBnZW5lcmF0ZWQgYXV0b21hdGljYWxseS4gU2VlIGRvY3MvY29udGVudF9ibG9ja2Vycy5tZCB0byBsZWFybiBob3cgdG8gbWFrZSB0aGUgbGlzdC5cbiAqL1xuZnVuY3Rpb24gZ2V0RmlsdGVycygpIHtcbiAgICB2YXIgZnJvbUI2NCA9IGF0b2I7IC8vIEp1c3QgZm9yIGJldHRlciBtaW5pZmljYXRpb25cbiAgICByZXR1cm4ge1xuICAgICAgICBhYnBJbmRvOiBbXG4gICAgICAgICAgICAnI0lrbGFuLU1lbGF5YW5nJyxcbiAgICAgICAgICAgICcjS29sb20tSWtsYW4tNzI4JyxcbiAgICAgICAgICAgICcjU2lkZWJhcklrbGFuLXdyYXBwZXInLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0MGFYUnNaVDBpTjI1aFoyRWdjRzlyWlhJaUlHbGQnKSxcbiAgICAgICAgICAgICdbdGl0bGU9XCJBTElFTkJPTEFcIiBpXScsXG4gICAgICAgIF0sXG4gICAgICAgIGFicHZuOiBbXG4gICAgICAgICAgICAnI3F1YW5nY2FvbWInLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG1sdmMwRmtjMmx2YzBGa2N5MXNZWGx2ZFhRPScpLFxuICAgICAgICAgICAgJy5xdWFuZ2NhbycsXG4gICAgICAgICAgICBmcm9tQjY0KCdXMmh5WldaZVBTSm9kSFJ3Y3pvdkwzSTRPQzUyYmk4aVhRPT0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1cyaHlaV1plUFNKb2RIUndjem92TDNwaVpYUXVkbTR2SWwwPScpLFxuICAgICAgICBdLFxuICAgICAgICBhZEJsb2NrRmlubGFuZDogW1xuICAgICAgICAgICAgJy5tYWlub3N0aWxhJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ0xuTndiMjV6YjNKcGRBPT0nKSxcbiAgICAgICAgICAgICcueWxhbWFpbm9zJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtS2owaUwyTnNhV05yZEdoeVoyZ3VZWE53UHlKZCcpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNITTZMeTloY0hBdWNtVmhaSEJsWVdzdVkyOXRMMkZrY3lKZCcpLFxuICAgICAgICBdLFxuICAgICAgICBhZEJsb2NrUGVyc2lhbjogWycjbmF2YmFyX25vdGljZV81MCcsICcua2FkcicsICdUQUJMRVt3aWR0aD1cIjE0MHB4XCJdJywgJyNkaXZBZ2FoaScsIGZyb21CNjQoJ0kyRmtNbDlwYm14cGJtVT0nKV0sXG4gICAgICAgIGFkQmxvY2tXYXJuaW5nUmVtb3ZhbDogW1xuICAgICAgICAgICAgJyNhZGJsb2NrLWhvbmV5cG90JyxcbiAgICAgICAgICAgICcuYWRibG9ja2VyLXJvb3QnLFxuICAgICAgICAgICAgJy53cF9hZGJsb2NrX2RldGVjdCcsXG4gICAgICAgICAgICBmcm9tQjY0KCdMbWhsWVdSbGNpMWliRzlqYTJWa0xXRmsnKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0kyRmtYMkpzYjJOclpYST0nKSxcbiAgICAgICAgXSxcbiAgICAgICAgYWRHdWFyZEFubm95YW5jZXM6IFtcbiAgICAgICAgICAgICdhbXAtZW1iZWRbdHlwZT1cInplblwiXScsXG4gICAgICAgICAgICAnLmhzLXNvc3lhbCcsXG4gICAgICAgICAgICAnI2Nvb2tpZWNvbnNlbnRkaXYnLFxuICAgICAgICAgICAgJ2RpdltjbGFzc149XCJhcHBfZ2RwclwiXScsXG4gICAgICAgICAgICAnLmFzLW9pbCcsXG4gICAgICAgIF0sXG4gICAgICAgIGFkR3VhcmRCYXNlOiBbXG4gICAgICAgICAgICAnLkJldHRlckpzUG9wT3ZlcmxheScsXG4gICAgICAgICAgICBmcm9tQjY0KCdJMkZrWHpNd01GZ3lOVEE9JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdJMkpoYm01bGNtWnNiMkYwTWpJPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnSTJGa0xXSmhibTVsY2c9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnSTJOaGJYQmhhV2R1TFdKaGJtNWxjZz09JyksXG4gICAgICAgIF0sXG4gICAgICAgIGFkR3VhcmRDaGluZXNlOiBbXG4gICAgICAgICAgICBmcm9tQjY0KCdMbHBwWDJGa1gyRmZTQT09JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbUtqMGlMMjlrTURBMUxtTnZiU0pkJyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbUtqMGlMbWgwYUdKbGRETTBMbU52YlNKZCcpLFxuICAgICAgICAgICAgJy5xcV9ucl9sYWQnLFxuICAgICAgICAgICAgJyN3aWRnZXQtcXVhbicsXG4gICAgICAgIF0sXG4gICAgICAgIGFkR3VhcmRGcmVuY2g6IFtcbiAgICAgICAgICAgIGZyb21CNjQoJ0kySnNiMk5yTFhacFpYZHpMV0ZrY3kxemFXUmxZbUZ5TFdKc2IyTnJMV0pzYjJOcicpLFxuICAgICAgICAgICAgJyNwYXZlUHViJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ0xtRmtMV1JsYzJ0MGIzQXRjbVZqZEdGdVoyeGwnKSxcbiAgICAgICAgICAgICcubW9iaWxlX2FkaGVzaW9uJyxcbiAgICAgICAgICAgICcud2lkZ2V0YWR2JyxcbiAgICAgICAgXSxcbiAgICAgICAgYWRHdWFyZEdlcm1hbjogW1xuICAgICAgICAgICAgZnJvbUI2NCgnTG1KaGJtNWxjbWwwWlcxM1pYSmlkVzVuWDJobFlXUmZNUT09JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdMbUp2ZUhOMFlYSjBkMlZ5WW5WdVp3PT0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0xuZGxjbUoxYm1jeicpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNEb3ZMM2QzZHk1bGFYTXVaR1V2YVc1a1pYZ3VjR2gwYld3L2NtVm1hV1E5SWwwPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNITTZMeTkzZDNjdWRHbHdhV052TG1OdmJTOC9ZV1ptYVd4cFlYUmxTV1E5SWwwPScpLFxuICAgICAgICBdLFxuICAgICAgICBhZEd1YXJkSmFwYW5lc2U6IFtcbiAgICAgICAgICAgICcja2F1bGlfeWFkXzEnLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNEb3ZMMkZrTWk1MGNtRm1abWxqWjJGMFpTNXVaWFF2SWwwPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnTGw5d2IzQkpibDlwYm1acGJtbDBaVjloWkE9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG1Ga1oyOXZaMnhsJyksXG4gICAgICAgICAgICBmcm9tQjY0KCdMbUZrWDNKbFozVnNZWEl6JyksXG4gICAgICAgIF0sXG4gICAgICAgIGFkR3VhcmRNb2JpbGU6IFtcbiAgICAgICAgICAgIGZyb21CNjQoJ1lXMXdMV0YxZEc4dFlXUnonKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0xtRnRjRjloWkE9PScpLFxuICAgICAgICAgICAgJ2FtcC1lbWJlZFt0eXBlPVwiMjRzbWlcIl0nLFxuICAgICAgICAgICAgJyNtZ2lkX2lmcmFtZTEnLFxuICAgICAgICAgICAgZnJvbUI2NCgnSTJGa1gybHVkbWxsZDE5aGNtVmgnKSxcbiAgICAgICAgXSxcbiAgICAgICAgYWRHdWFyZFJ1c3NpYW46IFtcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjSE02THk5aFpDNXNaWFJ0WldGa2N5NWpiMjB2SWwwPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG5KbFkyeGhiV0U9JyksXG4gICAgICAgICAgICAnZGl2W2lkXj1cInNtaTJhZGJsb2NrXCJdJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ1pHbDJXMmxrWGowaVFXUkdiM2hmWW1GdWJtVnlYeUpkJyksXG4gICAgICAgICAgICBmcm9tQjY0KCdJMkZrWDNOeGRXRnlaUT09JyksXG4gICAgICAgIF0sXG4gICAgICAgIGFkR3VhcmRTb2NpYWw6IFtcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaUx5OTNkM2N1YzNSMWJXSnNaWFZ3YjI0dVkyOXRMM04xWW0xcGREOTFjbXc5SWwwPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpTHk5MFpXeGxaM0poYlM1dFpTOXphR0Z5WlM5MWNtdy9JbDA9JyksXG4gICAgICAgICAgICAnLmV0c3ktdHdlZXQnLFxuICAgICAgICAgICAgJyNpbmxpbmVTaGFyZScsXG4gICAgICAgICAgICAnLnBvcHVwLXNvY2lhbCcsXG4gICAgICAgIF0sXG4gICAgICAgIGFkR3VhcmRTcGFuaXNoUG9ydHVndWVzZTogW1xuICAgICAgICAgICAgJyNiYXJyYVB1YmxpY2lkYWRlJyxcbiAgICAgICAgICAgICcjUHVibGljaWRhZGUnLFxuICAgICAgICAgICAgJyNwdWJsaUVzcGVjaWFsJyxcbiAgICAgICAgICAgICcjcXVlVG9vbHRpcCcsXG4gICAgICAgICAgICBmcm9tQjY0KCdXMmh5WldaZVBTSm9kSFJ3T2k4dllXUnpMbWRzYVhOd1lTNWpiMjB2SWwwPScpLFxuICAgICAgICBdLFxuICAgICAgICBhZEd1YXJkVHJhY2tpbmdQcm90ZWN0aW9uOiBbXG4gICAgICAgICAgICAnI3Fvby1jb3VudGVyJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjRG92TDJOc2FXTnJMbWh2ZEd4dlp5NXlkUzhpWFE9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNEb3ZMMmhwZEdOdmRXNTBaWEl1Y25VdmRHOXdMM04wWVhRdWNHaHdJbDA9JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbVhqMGlhSFIwY0RvdkwzUnZjQzV0WVdsc0xuSjFMMnAxYlhBaVhRPT0nKSxcbiAgICAgICAgICAgICcjdG9wMTAwY291bnRlcicsXG4gICAgICAgIF0sXG4gICAgICAgIGFkR3VhcmRUdXJraXNoOiBbXG4gICAgICAgICAgICAnI2JhY2trYXBhdCcsXG4gICAgICAgICAgICBmcm9tQjY0KCdJM0psYTJ4aGJXaz0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjRG92TDJGa2MyVnlkaTV2Ym5SbGF5NWpiMjB1ZEhJdklsMD0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjRG92TDJsNmJHVnVlbWt1WTI5dEwyTmhiWEJoYVdkdUx5SmQnKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjRG92TDNkM2R5NXBibk4wWVd4c1lXUnpMbTVsZEM4aVhRPT0nKSxcbiAgICAgICAgXSxcbiAgICAgICAgYnVsZ2FyaWFuOiBbXG4gICAgICAgICAgICBmcm9tQjY0KCdkR1FqWm5KbFpXNWxkRjkwWVdKc1pWOWhaSE09JyksXG4gICAgICAgICAgICAnI2VhX2ludGV4dF9kaXYnLFxuICAgICAgICAgICAgJy5sYXBuaS1wb3Atb3ZlcicsXG4gICAgICAgICAgICAnI3hlbml1bV9ob3Rfb2ZmZXJzJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ0kyNWxkMEZrJyksXG4gICAgICAgIF0sXG4gICAgICAgIGVhc3lMaXN0OiBbXG4gICAgICAgICAgICBmcm9tQjY0KCdJMEZFWDBOUFRsUlNUMHhmTWpnPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG5ObFkyOXVaQzF3YjNOMExXRmtjeTEzY21Gd2NHVnknKSxcbiAgICAgICAgICAgICcudW5pdmVyc2FsYm94QURWQk9YMDMnLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG1Ga2RtVnlkR2x6WlcxbGJuUXROekk0ZURrdycpLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG5OeGRXRnlaVjloWkhNPScpLFxuICAgICAgICBdLFxuICAgICAgICBlYXN5TGlzdENoaW5hOiBbXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbUtqMGlMbmRsYm5OcGVIVmxkR0Z1Wnk1amIyMHZJbDA9JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdMbUZ3Y0dkMWFXUmxMWGR5WVhCYmIyNWpiR2xqYXlvOUltSmpaV0p2Y3k1amIyMGlYUT09JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdMbVp5YjI1MGNHRm5aVUZrZGswPScpLFxuICAgICAgICAgICAgJyN0YW90YW9sZScsXG4gICAgICAgICAgICAnI2FhZm9vdC50b3BfYm94JyxcbiAgICAgICAgXSxcbiAgICAgICAgZWFzeUxpc3RDb29raWU6IFtcbiAgICAgICAgICAgICcjQWRhQ29tcGxpYW5jZS5hcHAtbm90aWNlJyxcbiAgICAgICAgICAgICcudGV4dC1jZW50ZXIucmdwZCcsXG4gICAgICAgICAgICAnLnBhbmVsLS1jb29raWUnLFxuICAgICAgICAgICAgJy5qcy1jb29raWVzLWFuZHJvbWVkYScsXG4gICAgICAgICAgICAnLmVseHRyLWNvbnNlbnQnLFxuICAgICAgICBdLFxuICAgICAgICBlYXN5TGlzdEN6ZWNoU2xvdmFrOiBbXG4gICAgICAgICAgICAnI29ubGFqbnktc3RpY2tlcnMnLFxuICAgICAgICAgICAgZnJvbUI2NCgnSTNKbGEyeGhiVzVwTFdKdmVBPT0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0xuSmxhMnhoYldFdGJXVm5ZV0p2WVhKaycpLFxuICAgICAgICAgICAgJy5za2xpaycsXG4gICAgICAgICAgICBmcm9tQjY0KCdXMmxrWGowaWMydHNhV3RTWld0c1lXMWhJbDA9JyksXG4gICAgICAgIF0sXG4gICAgICAgIGVhc3lMaXN0RHV0Y2g6IFtcbiAgICAgICAgICAgIGZyb21CNjQoJ0kyRmtkbVZ5ZEdWdWRHbGwnKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0kzWnBjRUZrYldGeWEzUkNZVzV1WlhKQ2JHOWphdz09JyksXG4gICAgICAgICAgICAnLmFkc3Rla3N0JyxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjSE02THk5NGJIUjFZbVV1Ym13dlkyeHBZMnN2SWwwPScpLFxuICAgICAgICAgICAgJyNzZW1pbG8tbHJlY3RhbmdsZScsXG4gICAgICAgIF0sXG4gICAgICAgIGVhc3lMaXN0R2VybWFueTogW1xuICAgICAgICAgICAgZnJvbUI2NCgnSTBGa1gxZHBiakprWVhrPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnSTNkbGNtSjFibWR6WW05NE16QXcnKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjRG92TDNkM2R5NXliM1JzYVdOb2RHdGhjblJsYVM1amIyMHZQM05qUFNKZCcpLFxuICAgICAgICAgICAgZnJvbUI2NCgnSTNkbGNtSjFibWRmZDJsa1pYTnJlWE5qY21Gd1pYSmZjMk55WldWdScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNEb3ZMMnhoYm1ScGJtY3VjR0Z5YTNCc1lYUjZhMkZ5ZEdWcExtTnZiUzgvWVdjOUlsMD0nKSxcbiAgICAgICAgXSxcbiAgICAgICAgZWFzeUxpc3RJdGFseTogW1xuICAgICAgICAgICAgZnJvbUI2NCgnTG1KdmVGOWhaSFpmWVc1dWRXNWphUT09JyksXG4gICAgICAgICAgICAnLnNiLWJveC1wdWJibGlyZWRhemlvbmFsZScsXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbVhqMGlhSFIwY0RvdkwyRm1abWxzYVdGNmFXOXVhV0ZrY3k1emJtRnBMbWwwTHlKZCcpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNITTZMeTloWkhObGNuWmxjaTVvZEcxc0xtbDBMeUpkJyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbVhqMGlhSFIwY0hNNkx5OWhabVpwYkdsaGVtbHZibWxoWkhNdWMyNWhhUzVwZEM4aVhRPT0nKSxcbiAgICAgICAgXSxcbiAgICAgICAgZWFzeUxpc3RMaXRodWFuaWE6IFtcbiAgICAgICAgICAgIGZyb21CNjQoJ0xuSmxhMnhoYlc5elgzUmhjbkJoY3c9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG5KbGEyeGhiVzl6WDI1MWIzSnZaRzl6JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdhVzFuVzJGc2REMGlVbVZyYkdGdGFXNXBjeUJ6YTNsa1pXeHBjeUpkJyksXG4gICAgICAgICAgICBmcm9tQjY0KCdhVzFuVzJGc2REMGlSR1ZrYVd0MWIzUnBMbXgwSUhObGNuWmxjbWxoYVNKZCcpLFxuICAgICAgICAgICAgZnJvbUI2NCgnYVcxblcyRnNkRDBpU0c5emRHbHVaMkZ6SUZObGNuWmxjbWxoYVM1c2RDSmQnKSxcbiAgICAgICAgXSxcbiAgICAgICAgZXN0b25pYW46IFtmcm9tQjY0KCdRVnRvY21WbUtqMGlhSFIwY0RvdkwzQmhlVFJ5WlhOMWJIUnpNalF1WlhVaVhRPT0nKV0sXG4gICAgICAgIGZhbmJveUFubm95YW5jZXM6IFtcbiAgICAgICAgICAgICcjZmVlZGJhY2stdGFiJyxcbiAgICAgICAgICAgICcjdGFib29sYS1iZWxvdy1hcnRpY2xlJyxcbiAgICAgICAgICAgICcuZmVlZGJ1cm5lckZlZWRCbG9jaycsXG4gICAgICAgICAgICAnLndpZGdldC1mZWVkYnVybmVyLWNvdW50ZXInLFxuICAgICAgICAgICAgJ1t0aXRsZT1cIlN1YnNjcmliZSB0byBvdXIgYmxvZ1wiXScsXG4gICAgICAgIF0sXG4gICAgICAgIGZhbmJveUFudGlGYWNlYm9vazogWycudXRpbC1iYXItbW9kdWxlLWZpcmVmbHktdmlzaWJsZSddLFxuICAgICAgICBmYW5ib3lFbmhhbmNlZFRyYWNrZXJzOiBbXG4gICAgICAgICAgICAnLm9wZW4ucHVzaE1vZGFsJyxcbiAgICAgICAgICAgICcjaXNzdWVtLWxlYWt5LXBheXdhbGwtYXJ0aWNsZXMtemVyby1yZW1haW5pbmctbmFnJyxcbiAgICAgICAgICAgICcjc292cm5fY29udGFpbmVyJyxcbiAgICAgICAgICAgICdkaXZbY2xhc3MkPVwiLWhpZGVcIl1bem9vbXBhZ2UtZm9udHNpemVdW3N0eWxlPVwiZGlzcGxheTogYmxvY2s7XCJdJyxcbiAgICAgICAgICAgICcuQmxvY2tOYWdfX0NhcmQnLFxuICAgICAgICBdLFxuICAgICAgICBmYW5ib3lTb2NpYWw6IFtcbiAgICAgICAgICAgICcudGQtdGFncy1hbmQtc29jaWFsLXdyYXBwZXItYm94JyxcbiAgICAgICAgICAgICcudHdpdHRlckNvbnRhaW5lcicsXG4gICAgICAgICAgICAnLnlvdXR1YmUtc29jaWFsJyxcbiAgICAgICAgICAgICdhW3RpdGxlXj1cIkxpa2UgdXMgb24gRmFjZWJvb2tcIl0nLFxuICAgICAgICAgICAgJ2ltZ1thbHRePVwiU2hhcmUgb24gRGlnZ1wiXScsXG4gICAgICAgIF0sXG4gICAgICAgIGZyZWxsd2l0U3dlZGlzaDogW1xuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1LajBpWTJGemFXNXZjSEp2TG5ObElsMWJkR0Z5WjJWMFBTSmZZbXhoYm1zaVhRPT0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtS2owaVpHOXJkRzl5TFhObExtOXVaV3hwYm1zdWJXVWlYUT09JyksXG4gICAgICAgICAgICAnYXJ0aWNsZS5jYXRlZ29yeS1zYW1hcmJldGUnLFxuICAgICAgICAgICAgZnJvbUI2NCgnWkdsMkxtaHZiR2xrUVdSeicpLFxuICAgICAgICAgICAgJ3VsLmFkc21vZGVybicsXG4gICAgICAgIF0sXG4gICAgICAgIGdyZWVrQWRCbG9jazogW1xuICAgICAgICAgICAgZnJvbUI2NCgnUVZ0b2NtVm1LajBpWVdSdFlXNHViM1JsYm1WMExtZHlMMk5zYVdOclB5SmQnKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1FWdG9jbVZtS2owaWFIUjBjRG92TDJGNGFXRmlZVzV1WlhKekxtVjRiMlIxY3k1bmNpOGlYUT09JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdRVnRvY21WbUtqMGlhSFIwY0RvdkwybHVkR1Z5WVdOMGFYWmxMbVp2Y25Sb2JtVjBMbWR5TDJOc2FXTnJQeUpkJyksXG4gICAgICAgICAgICAnRElWLmFnb3JlczMwMCcsXG4gICAgICAgICAgICAnVEFCTEUuYWR2cmlnaHQnLFxuICAgICAgICBdLFxuICAgICAgICBodW5nYXJpYW46IFtcbiAgICAgICAgICAgICcjY2VtcF9kb2JveicsXG4gICAgICAgICAgICAnLm9wdGltb25rLWlmcmFtZS1jb250YWluZXInLFxuICAgICAgICAgICAgZnJvbUI2NCgnTG1Ga1gxOXRZV2x1JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdXMk5zWVhOektqMGlSMjl2WjJ4bFFXUnpJbDA9JyksXG4gICAgICAgICAgICAnI2hpcmRldGVzZWtfYm94JyxcbiAgICAgICAgXSxcbiAgICAgICAgaURvbnRDYXJlQWJvdXRDb29raWVzOiBbXG4gICAgICAgICAgICAnLmFsZXJ0LWluZm9bZGF0YS1ibG9jay10cmFjayo9XCJDb29raWVOb3RpY2VcIl0nLFxuICAgICAgICAgICAgJy5Nb2R1bGVUZW1wbGF0ZUNvb2tpZUluZGljYXRvcicsXG4gICAgICAgICAgICAnLm8tLWNvb2tpZXMtLWNvbnRhaW5lcicsXG4gICAgICAgICAgICAnLmNvb2tpZS1tc2ctaW5mby1jb250YWluZXInLFxuICAgICAgICAgICAgJyNjb29raWVzLXBvbGljeS1zdGlja3knLFxuICAgICAgICBdLFxuICAgICAgICBpY2VsYW5kaWNBYnA6IFtmcm9tQjY0KCdRVnRvY21WbVhqMGlMMlp5WVcxbGQyOXlheTl5WlhOdmRYSmpaWE12Wm05eWJYTXZZV1J6TG1GemNIZ2lYUT09JyldLFxuICAgICAgICBsYXR2aWFuOiBbXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbVBTSm9kSFJ3T2k4dmQzZDNMbk5oYkdsa2VtbHVhUzVzZGk4aVhWdHpkSGxzWlQwaVpHbHpjR3hoZVRvZ1lteHZZMnM3SUhkcFpIUm9PaUF4TWpCd2VEc2dhR1ZwWjJoME8nICtcbiAgICAgICAgICAgICAgICAnaUEwTUhCNE95QnZkbVZ5Wm14dmR6b2dhR2xrWkdWdU95QndiM05wZEdsdmJqb2djbVZzWVhScGRtVTdJbDA9JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbVBTSm9kSFJ3T2k4dmQzZDNMbk5oYkdsa2VtbHVhUzVzZGk4aVhWdHpkSGxzWlQwaVpHbHpjR3hoZVRvZ1lteHZZMnM3SUhkcFpIUm9PaUE0T0hCNE95Qm9aV2xuYUhRNkknICtcbiAgICAgICAgICAgICAgICAnRE14Y0hnN0lHOTJaWEptYkc5M09pQm9hV1JrWlc0N0lIQnZjMmwwYVc5dU9pQnlaV3hoZEdsMlpUc2lYUT09JyksXG4gICAgICAgIF0sXG4gICAgICAgIGxpc3RLcjogW1xuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1LajBpTHk5aFpDNXdiR0Z1WW5Cc2RYTXVZMjh1YTNJdklsMD0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0kyeHBkbVZ5WlVGa1YzSmhjSEJsY2c9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1LajBpTHk5aFpIWXVhVzFoWkhKbGNDNWpieTVyY2k4aVhRPT0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ2FXNXpMbVpoYzNSMmFXVjNMV0ZrJyksXG4gICAgICAgICAgICAnLnJldmVudWVfdW5pdF9pdGVtLmRhYmxlJyxcbiAgICAgICAgXSxcbiAgICAgICAgbGlzdGVBcjogW1xuICAgICAgICAgICAgZnJvbUI2NCgnTG1kbGJXbHVhVXhDTVVGaycpLFxuICAgICAgICAgICAgJy5yaWdodC1hbmQtbGVmdC1zcG9uc2VycycsXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbUtqMGlMbUZtYkdGdExtbHVabThpWFE9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1LajBpWW05dmNtRnhMbTl5WnlKZCcpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1LajBpWkhWaWFYcDZiR1V1WTI5dEwyRnlMejkxZEcxZmMyOTFjbU5sUFNKZCcpLFxuICAgICAgICBdLFxuICAgICAgICBsaXN0ZUZyOiBbXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbVhqMGlhSFIwY0RvdkwzQnliMjF2TG5aaFpHOXlMbU52YlM4aVhRPT0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0kyRmtZMjl1ZEdGcGJtVnlYM0psWTJobGNtTm9aUT09JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbUtqMGlkMlZpYjNKaGJXRXVabkl2Wm1ObmFTMWlhVzR2SWwwPScpLFxuICAgICAgICAgICAgJy5zaXRlLXB1Yi1pbnRlcnN0aXRpZWwnLFxuICAgICAgICAgICAgJ2RpdltpZF49XCJjcnQtXCJdW2RhdGEtY3JpdGVvLWlkXScsXG4gICAgICAgIF0sXG4gICAgICAgIG9mZmljaWFsUG9saXNoOiBbXG4gICAgICAgICAgICAnI2NlbmVvLXBsYWNlaG9sZGVyLWNlbmVvLTEyJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ1cyaHlaV1plUFNKb2RIUndjem92TDJGbVppNXpaVzVrYUhWaUxuQnNMeUpkJyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbVhqMGlhSFIwY0RvdkwyRmtkbTFoYm1GblpYSXVkR1ZqYUdaMWJpNXdiQzl5WldScGNtVmpkQzhpWFE9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNEb3ZMM2QzZHk1MGNtbDZaWEl1Y0d3dlAzVjBiVjl6YjNWeVkyVWlYUT09JyksXG4gICAgICAgICAgICBmcm9tQjY0KCdaR2wySTNOcllYQnBaV05mWVdRPScpLFxuICAgICAgICBdLFxuICAgICAgICBybzogW1xuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpTHk5aFptWjBjbXN1WVd4MFpYZ3VjbTh2UTI5MWJuUmxjaTlEYkdsamF5SmQnKSxcbiAgICAgICAgICAgICdhW2hyZWZePVwiL21hZ2F6aW4vXCJdJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjSE02THk5aWJHRmphMlp5YVdSaGVYTmhiR1Z6TG5KdkwzUnlheTl6YUc5d0x5SmQnKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtWGowaWFIUjBjSE02THk5bGRtVnVkQzR5Y0dWeVptOXliV0Z1ZEM1amIyMHZaWFpsYm5SekwyTnNhV05ySWwwPScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1YajBpYUhSMGNITTZMeTlzTG5CeWIyWnBkSE5vWVhKbExuSnZMeUpkJyksXG4gICAgICAgIF0sXG4gICAgICAgIHJ1QWQ6IFtcbiAgICAgICAgICAgIGZyb21CNjQoJ1lWdG9jbVZtS2owaUx5OW1aV0p5WVhKbExuSjFMeUpkJyksXG4gICAgICAgICAgICBmcm9tQjY0KCdZVnRvY21WbUtqMGlMeTkxZEdsdFp5NXlkUzhpWFE9PScpLFxuICAgICAgICAgICAgZnJvbUI2NCgnWVZ0b2NtVm1LajBpT2k4dlkyaHBhMmxrYVd0cExuSjFJbDA9JyksXG4gICAgICAgICAgICAnI3BnZWxkaXonLFxuICAgICAgICAgICAgJy55YW5kZXgtcnRiLWJsb2NrJyxcbiAgICAgICAgXSxcbiAgICAgICAgdGhhaUFkczogW1xuICAgICAgICAgICAgJ2FbaHJlZio9bWFjYXUtdXRhLXBvcHVwXScsXG4gICAgICAgICAgICBmcm9tQjY0KCdJMkZrY3kxbmIyOW5iR1V0Yldsa1pHeGxYM0psWTNSaGJtZHNaUzFuY205MWNBPT0nKSxcbiAgICAgICAgICAgIGZyb21CNjQoJ0xtRmtjek13TUhNPScpLFxuICAgICAgICAgICAgJy5idW1xJyxcbiAgICAgICAgICAgICcuaW1nLWtvc2FuYScsXG4gICAgICAgIF0sXG4gICAgICAgIHdlYkFubm95YW5jZXNVbHRyYWxpc3Q6IFtcbiAgICAgICAgICAgICcjbW9kLXNvY2lhbC1zaGFyZS0yJyxcbiAgICAgICAgICAgICcjc29jaWFsLXRvb2xzJyxcbiAgICAgICAgICAgIGZyb21CNjQoJ0xtTjBjR3d0Wm5Wc2JHSmhibTVsY2c9PScpLFxuICAgICAgICAgICAgJy56ZXJnbmV0LXJlY29tbWVuZCcsXG4gICAgICAgICAgICAnLnl0LmJ0bi1saW5rLmJ0bi1tZC5idG4nLFxuICAgICAgICBdLFxuICAgIH07XG59XG4vKipcbiAqIFRoZSBvcmRlciBvZiB0aGUgcmV0dXJuZWQgYXJyYXkgbWVhbnMgbm90aGluZyAoaXQncyBhbHdheXMgc29ydGVkIGFscGhhYmV0aWNhbGx5KS5cbiAqXG4gKiBOb3RpY2UgdGhhdCB0aGUgc291cmNlIGlzIHNsaWdodGx5IHVuc3RhYmxlLlxuICogU2FmYXJpIHByb3ZpZGVzIGEgMi10YXBzIHdheSB0byBkaXNhYmxlIGFsbCBjb250ZW50IGJsb2NrZXJzIG9uIGEgcGFnZSB0ZW1wb3JhcmlseS5cbiAqIEFsc28gY29udGVudCBibG9ja2VycyBjYW4gYmUgZGlzYWJsZWQgcGVybWFuZW50bHkgZm9yIGEgZG9tYWluLCBidXQgaXQgcmVxdWlyZXMgNCB0YXBzLlxuICogU28gZW1wdHkgYXJyYXkgc2hvdWxkbid0IGJlIHRyZWF0ZWQgYXMgXCJubyBibG9ja2Vyc1wiLCBpdCBzaG91bGQgYmUgdHJlYXRlZCBhcyBcIm5vIHNpZ25hbFwiLlxuICogSWYgeW91IGFyZSBhIHdlYnNpdGUgb3duZXIsIGRvbid0IG1ha2UgeW91ciB2aXNpdG9ycyB3YW50IHRvIGRpc2FibGUgY29udGVudCBibG9ja2Vycy5cbiAqL1xuZnVuY3Rpb24gZ2V0RG9tQmxvY2tlcnMoX2EpIHtcbiAgICB2YXIgZGVidWcgPSAoX2EgPT09IHZvaWQgMCA/IHt9IDogX2EpLmRlYnVnO1xuICAgIHJldHVybiB0c2xpYi5fX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZpbHRlcnMsIGZpbHRlck5hbWVzLCBhbGxTZWxlY3RvcnMsIGJsb2NrZWRTZWxlY3RvcnMsIGFjdGl2ZUJsb2NrZXJzO1xuICAgICAgICB2YXIgX2I7XG4gICAgICAgIHJldHVybiB0c2xpYi5fX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2MpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2MubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNBcHBsaWNhYmxlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCB1bmRlZmluZWRdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcnMgPSBnZXRGaWx0ZXJzKCk7XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlck5hbWVzID0gT2JqZWN0LmtleXMoZmlsdGVycyk7XG4gICAgICAgICAgICAgICAgICAgIGFsbFNlbGVjdG9ycyA9IChfYiA9IFtdKS5jb25jYXQuYXBwbHkoX2IsIGZpbHRlck5hbWVzLm1hcChmdW5jdGlvbiAoZmlsdGVyTmFtZSkgeyByZXR1cm4gZmlsdGVyc1tmaWx0ZXJOYW1lXTsgfSkpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCBnZXRCbG9ja2VkU2VsZWN0b3JzKGFsbFNlbGVjdG9ycyldO1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgYmxvY2tlZFNlbGVjdG9ycyA9IF9jLnNlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlYnVnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmludERlYnVnKGZpbHRlcnMsIGJsb2NrZWRTZWxlY3RvcnMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUJsb2NrZXJzID0gZmlsdGVyTmFtZXMuZmlsdGVyKGZ1bmN0aW9uIChmaWx0ZXJOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0b3JzID0gZmlsdGVyc1tmaWx0ZXJOYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja2VkQ291bnQgPSBjb3VudFRydXRoeShzZWxlY3RvcnMubWFwKGZ1bmN0aW9uIChzZWxlY3RvcikgeyByZXR1cm4gYmxvY2tlZFNlbGVjdG9yc1tzZWxlY3Rvcl07IH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBibG9ja2VkQ291bnQgPiBzZWxlY3RvcnMubGVuZ3RoICogMC42O1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlQmxvY2tlcnMuc29ydCgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgYWN0aXZlQmxvY2tlcnNdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGlzQXBwbGljYWJsZSgpIHtcbiAgICAvLyBTYWZhcmkgKGRlc2t0b3AgYW5kIG1vYmlsZSkgYW5kIGFsbCBBbmRyb2lkIGJyb3dzZXJzIGtlZXAgY29udGVudCBibG9ja2VycyBpbiBib3RoIHJlZ3VsYXIgYW5kIHByaXZhdGUgbW9kZVxuICAgIHJldHVybiBpc1dlYktpdCgpIHx8IGlzQW5kcm9pZCgpO1xufVxuZnVuY3Rpb24gZ2V0QmxvY2tlZFNlbGVjdG9ycyhzZWxlY3RvcnMpIHtcbiAgICB2YXIgX2E7XG4gICAgcmV0dXJuIHRzbGliLl9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZCwgcm9vdCwgZWxlbWVudHMsIGJsb2NrZWRTZWxlY3RvcnMsIGksIGVsZW1lbnQsIGhvbGRlciwgaTtcbiAgICAgICAgcmV0dXJuIHRzbGliLl9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYikge1xuICAgICAgICAgICAgc3dpdGNoIChfYi5sYWJlbCkge1xuICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICAgICAgZCA9IGRvY3VtZW50O1xuICAgICAgICAgICAgICAgICAgICByb290ID0gZC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgPSBuZXcgQXJyYXkoc2VsZWN0b3JzLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgIGJsb2NrZWRTZWxlY3RvcnMgPSB7fSAvLyBTZXQoKSBpc24ndCB1c2VkIGp1c3QgaW4gY2FzZSBzb21lYm9keSBuZWVkIG9sZGVyIGJyb3dzZXIgc3VwcG9ydFxuICAgICAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICAgICAgICAgIGZvcmNlU2hvdyhyb290KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gRmlyc3QgY3JlYXRlIGFsbCBlbGVtZW50cyB0aGF0IGNhbiBiZSBibG9ja2VkLiBJZiB0aGUgRE9NIHN0ZXBzIGJlbG93IGFyZSBkb25lIGluIGEgc2luZ2xlIGN5Y2xlLFxuICAgICAgICAgICAgICAgICAgICAvLyBicm93c2VyIHdpbGwgYWx0ZXJuYXRlIHRyZWUgbW9kaWZpY2F0aW9uIGFuZCBsYXlvdXQgcmVhZGluZywgdGhhdCBpcyB2ZXJ5IHNsb3cuXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzZWxlY3RvcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBzZWxlY3RvclRvRWxlbWVudChzZWxlY3RvcnNbaV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaG9sZGVyID0gZC5jcmVhdGVFbGVtZW50KCdkaXYnKSAvLyBQcm90ZWN0cyBmcm9tIHVud2FudGVkIGVmZmVjdHMgb2YgYCtgIGFuZCBgfmAgc2VsZWN0b3JzIG9mIGZpbHRlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlU2hvdyhob2xkZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaG9sZGVyLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChob2xkZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHNbaV0gPSBlbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMTtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWQuYm9keSkgcmV0dXJuIFszIC8qYnJlYWsqLywgM107XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHdhaXQoNTApXTtcbiAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgIF9iLnNlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFszIC8qYnJlYWsqLywgMV07XG4gICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICBkLmJvZHkuYXBwZW5kQ2hpbGQocm9vdCk7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGVuIGNoZWNrIHdoaWNoIG9mIHRoZSBlbGVtZW50cyBhcmUgYmxvY2tlZFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHNlbGVjdG9ycy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZWxlbWVudHNbaV0ub2Zmc2V0UGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrZWRTZWxlY3RvcnNbc2VsZWN0b3JzW2ldXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlbiByZW1vdmUgdGhlIGVsZW1lbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAoX2EgPSByb290LnBhcmVudE5vZGUpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5yZW1vdmVDaGlsZChyb290KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgYmxvY2tlZFNlbGVjdG9yc107XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZm9yY2VTaG93KGVsZW1lbnQpIHtcbiAgICBlbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ2Jsb2NrJywgJ2ltcG9ydGFudCcpO1xufVxuZnVuY3Rpb24gcHJpbnREZWJ1ZyhmaWx0ZXJzLCBibG9ja2VkU2VsZWN0b3JzKSB7XG4gICAgdmFyIG1lc3NhZ2UgPSAnRE9NIGJsb2NrZXJzIGRlYnVnOlxcbmBgYCc7XG4gICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IE9iamVjdC5rZXlzKGZpbHRlcnMpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIgZmlsdGVyTmFtZSA9IF9hW19pXTtcbiAgICAgICAgbWVzc2FnZSArPSBcIlxcblwiICsgZmlsdGVyTmFtZSArIFwiOlwiO1xuICAgICAgICBmb3IgKHZhciBfYiA9IDAsIF9jID0gZmlsdGVyc1tmaWx0ZXJOYW1lXTsgX2IgPCBfYy5sZW5ndGg7IF9iKyspIHtcbiAgICAgICAgICAgIHZhciBzZWxlY3RvciA9IF9jW19iXTtcbiAgICAgICAgICAgIG1lc3NhZ2UgKz0gXCJcXG4gIFwiICsgKGJsb2NrZWRTZWxlY3RvcnNbc2VsZWN0b3JdID8gJ/CfmqsnIDogJ+Keoe+4jycpICsgXCIgXCIgKyBzZWxlY3RvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBjb25zb2xlLmxvZyBpcyBvayBoZXJlIGJlY2F1c2UgaXQncyB1bmRlciBhIGRlYnVnIGNsYXVzZVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2cobWVzc2FnZSArIFwiXFxuYGBgXCIpO1xufVxuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0BtZWRpYS9jb2xvci1nYW11dFxuICovXG5mdW5jdGlvbiBnZXRDb2xvckdhbXV0KCkge1xuICAgIC8vIHJlYzIwMjAgaW5jbHVkZXMgcDMgYW5kIHAzIGluY2x1ZGVzIHNyZ2JcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gWydyZWMyMDIwJywgJ3AzJywgJ3NyZ2InXTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIGdhbXV0ID0gX2FbX2ldO1xuICAgICAgICBpZiAobWF0Y2hNZWRpYShcIihjb2xvci1nYW11dDogXCIgKyBnYW11dCArIFwiKVwiKS5tYXRjaGVzKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2FtdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9AbWVkaWEvaW52ZXJ0ZWQtY29sb3JzXG4gKi9cbmZ1bmN0aW9uIGFyZUNvbG9yc0ludmVydGVkKCkge1xuICAgIGlmIChkb2VzTWF0Y2gkNCgnaW52ZXJ0ZWQnKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGRvZXNNYXRjaCQ0KCdub25lJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gZG9lc01hdGNoJDQodmFsdWUpIHtcbiAgICByZXR1cm4gbWF0Y2hNZWRpYShcIihpbnZlcnRlZC1jb2xvcnM6IFwiICsgdmFsdWUgKyBcIilcIikubWF0Y2hlcztcbn1cblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9AbWVkaWEvZm9yY2VkLWNvbG9yc1xuICovXG5mdW5jdGlvbiBhcmVDb2xvcnNGb3JjZWQoKSB7XG4gICAgaWYgKGRvZXNNYXRjaCQzKCdhY3RpdmUnKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGRvZXNNYXRjaCQzKCdub25lJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gZG9lc01hdGNoJDModmFsdWUpIHtcbiAgICByZXR1cm4gbWF0Y2hNZWRpYShcIihmb3JjZWQtY29sb3JzOiBcIiArIHZhbHVlICsgXCIpXCIpLm1hdGNoZXM7XG59XG5cbnZhciBtYXhWYWx1ZVRvQ2hlY2sgPSAxMDA7XG4vKipcbiAqIElmIHRoZSBkaXNwbGF5IGlzIG1vbm9jaHJvbWUgKGUuZy4gYmxhY2smd2hpdGUpLCB0aGUgdmFsdWUgd2lsbCBiZSDiiaUwIGFuZCB3aWxsIG1lYW4gdGhlIG51bWJlciBvZiBiaXRzIHBlciBwaXhlbC5cbiAqIElmIHRoZSBkaXNwbGF5IGlzIG5vdCBtb25vY2hyb21lLCB0aGUgcmV0dXJuZWQgdmFsdWUgd2lsbCBiZSAwLlxuICogSWYgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IHRoaXMgZmVhdHVyZSwgdGhlIHJldHVybmVkIHZhbHVlIHdpbGwgYmUgdW5kZWZpbmVkLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0BtZWRpYS9tb25vY2hyb21lXG4gKi9cbmZ1bmN0aW9uIGdldE1vbm9jaHJvbWVEZXB0aCgpIHtcbiAgICBpZiAoIW1hdGNoTWVkaWEoJyhtaW4tbW9ub2Nocm9tZTogMCknKS5tYXRjaGVzKSB7XG4gICAgICAgIC8vIFRoZSBtZWRpYSBmZWF0dXJlIGlzbid0IHN1cHBvcnRlZCBieSB0aGUgYnJvd3NlclxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICAvLyBBIHZhcmlhdGlvbiBvZiBiaW5hcnkgc2VhcmNoIGFsZ29yaXRobSBjYW4gYmUgdXNlZCBoZXJlLlxuICAgIC8vIEJ1dCBzaW5jZSBleHBlY3RlZCB2YWx1ZXMgYXJlIHZlcnkgc21hbGwgKOKJpDEwKSwgdGhlcmUgaXMgbm8gc2Vuc2UgaW4gYWRkaW5nIHRoZSBjb21wbGV4aXR5LlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IG1heFZhbHVlVG9DaGVjazsgKytpKSB7XG4gICAgICAgIGlmIChtYXRjaE1lZGlhKFwiKG1heC1tb25vY2hyb21lOiBcIiArIGkgKyBcIilcIikubWF0Y2hlcykge1xuICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUb28gaGlnaCB2YWx1ZScpO1xufVxuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL21lZGlhcXVlcmllcy01LyNwcmVmZXJzLWNvbnRyYXN0XG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9AbWVkaWEvcHJlZmVycy1jb250cmFzdFxuICovXG5mdW5jdGlvbiBnZXRDb250cmFzdFByZWZlcmVuY2UoKSB7XG4gICAgaWYgKGRvZXNNYXRjaCQyKCduby1wcmVmZXJlbmNlJykpIHtcbiAgICAgICAgcmV0dXJuIDAgLyogTm9uZSAqLztcbiAgICB9XG4gICAgLy8gVGhlIHNvdXJjZXMgY29udHJhZGljdCBvbiB0aGUga2V5d29yZHMuIFByb2JhYmx5ICdoaWdoJyBhbmQgJ2xvdycgd2lsbCBuZXZlciBiZSBpbXBsZW1lbnRlZC5cbiAgICAvLyBOZWVkIHRvIGNoZWNrIGl0IHdoZW4gYWxsIGJyb3dzZXJzIGltcGxlbWVudCB0aGUgZmVhdHVyZS5cbiAgICBpZiAoZG9lc01hdGNoJDIoJ2hpZ2gnKSB8fCBkb2VzTWF0Y2gkMignbW9yZScpKSB7XG4gICAgICAgIHJldHVybiAxIC8qIE1vcmUgKi87XG4gICAgfVxuICAgIGlmIChkb2VzTWF0Y2gkMignbG93JykgfHwgZG9lc01hdGNoJDIoJ2xlc3MnKSkge1xuICAgICAgICByZXR1cm4gLTEgLyogTGVzcyAqLztcbiAgICB9XG4gICAgaWYgKGRvZXNNYXRjaCQyKCdmb3JjZWQnKSkge1xuICAgICAgICByZXR1cm4gMTAgLyogRm9yY2VkQ29sb3JzICovO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gZG9lc01hdGNoJDIodmFsdWUpIHtcbiAgICByZXR1cm4gbWF0Y2hNZWRpYShcIihwcmVmZXJzLWNvbnRyYXN0OiBcIiArIHZhbHVlICsgXCIpXCIpLm1hdGNoZXM7XG59XG5cbi8qKlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQG1lZGlhL3ByZWZlcnMtcmVkdWNlZC1tb3Rpb25cbiAqL1xuZnVuY3Rpb24gaXNNb3Rpb25SZWR1Y2VkKCkge1xuICAgIGlmIChkb2VzTWF0Y2gkMSgncmVkdWNlJykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChkb2VzTWF0Y2gkMSgnbm8tcHJlZmVyZW5jZScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGRvZXNNYXRjaCQxKHZhbHVlKSB7XG4gICAgcmV0dXJuIG1hdGNoTWVkaWEoXCIocHJlZmVycy1yZWR1Y2VkLW1vdGlvbjogXCIgKyB2YWx1ZSArIFwiKVwiKS5tYXRjaGVzO1xufVxuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL21lZGlhcXVlcmllcy01LyNkeW5hbWljLXJhbmdlXG4gKi9cbmZ1bmN0aW9uIGlzSERSKCkge1xuICAgIGlmIChkb2VzTWF0Y2goJ2hpZ2gnKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGRvZXNNYXRjaCgnc3RhbmRhcmQnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBkb2VzTWF0Y2godmFsdWUpIHtcbiAgICByZXR1cm4gbWF0Y2hNZWRpYShcIihkeW5hbWljLXJhbmdlOiBcIiArIHZhbHVlICsgXCIpXCIpLm1hdGNoZXM7XG59XG5cbnZhciBNID0gTWF0aDsgLy8gVG8gcmVkdWNlIHRoZSBtaW5pZmllZCBjb2RlIHNpemVcbnZhciBmYWxsYmFja0ZuID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gMDsgfTtcbi8qKlxuICogQHNlZSBodHRwczovL2dpdGxhYi50b3Jwcm9qZWN0Lm9yZy9sZWdhY3kvdHJhYy8tL2lzc3Vlcy8xMzAxOFxuICogQHNlZSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD01MzE5MTVcbiAqL1xuZnVuY3Rpb24gZ2V0TWF0aEZpbmdlcnByaW50KCkge1xuICAgIC8vIE5hdGl2ZSBvcGVyYXRpb25zXG4gICAgdmFyIGFjb3MgPSBNLmFjb3MgfHwgZmFsbGJhY2tGbjtcbiAgICB2YXIgYWNvc2ggPSBNLmFjb3NoIHx8IGZhbGxiYWNrRm47XG4gICAgdmFyIGFzaW4gPSBNLmFzaW4gfHwgZmFsbGJhY2tGbjtcbiAgICB2YXIgYXNpbmggPSBNLmFzaW5oIHx8IGZhbGxiYWNrRm47XG4gICAgdmFyIGF0YW5oID0gTS5hdGFuaCB8fCBmYWxsYmFja0ZuO1xuICAgIHZhciBhdGFuID0gTS5hdGFuIHx8IGZhbGxiYWNrRm47XG4gICAgdmFyIHNpbiA9IE0uc2luIHx8IGZhbGxiYWNrRm47XG4gICAgdmFyIHNpbmggPSBNLnNpbmggfHwgZmFsbGJhY2tGbjtcbiAgICB2YXIgY29zID0gTS5jb3MgfHwgZmFsbGJhY2tGbjtcbiAgICB2YXIgY29zaCA9IE0uY29zaCB8fCBmYWxsYmFja0ZuO1xuICAgIHZhciB0YW4gPSBNLnRhbiB8fCBmYWxsYmFja0ZuO1xuICAgIHZhciB0YW5oID0gTS50YW5oIHx8IGZhbGxiYWNrRm47XG4gICAgdmFyIGV4cCA9IE0uZXhwIHx8IGZhbGxiYWNrRm47XG4gICAgdmFyIGV4cG0xID0gTS5leHBtMSB8fCBmYWxsYmFja0ZuO1xuICAgIHZhciBsb2cxcCA9IE0ubG9nMXAgfHwgZmFsbGJhY2tGbjtcbiAgICAvLyBPcGVyYXRpb24gcG9seWZpbGxzXG4gICAgdmFyIHBvd1BJID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBNLnBvdyhNLlBJLCB2YWx1ZSk7IH07XG4gICAgdmFyIGFjb3NoUGYgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIE0ubG9nKHZhbHVlICsgTS5zcXJ0KHZhbHVlICogdmFsdWUgLSAxKSk7IH07XG4gICAgdmFyIGFzaW5oUGYgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIE0ubG9nKHZhbHVlICsgTS5zcXJ0KHZhbHVlICogdmFsdWUgKyAxKSk7IH07XG4gICAgdmFyIGF0YW5oUGYgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIE0ubG9nKCgxICsgdmFsdWUpIC8gKDEgLSB2YWx1ZSkpIC8gMjsgfTtcbiAgICB2YXIgc2luaFBmID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBNLmV4cCh2YWx1ZSkgLSAxIC8gTS5leHAodmFsdWUpIC8gMjsgfTtcbiAgICB2YXIgY29zaFBmID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiAoTS5leHAodmFsdWUpICsgMSAvIE0uZXhwKHZhbHVlKSkgLyAyOyB9O1xuICAgIHZhciBleHBtMVBmID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBNLmV4cCh2YWx1ZSkgLSAxOyB9O1xuICAgIHZhciB0YW5oUGYgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIChNLmV4cCgyICogdmFsdWUpIC0gMSkgLyAoTS5leHAoMiAqIHZhbHVlKSArIDEpOyB9O1xuICAgIHZhciBsb2cxcFBmID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBNLmxvZygxICsgdmFsdWUpOyB9O1xuICAgIC8vIE5vdGU6IGNvbnN0YW50IHZhbHVlcyBhcmUgZW1waXJpY2FsXG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWNvczogYWNvcygwLjEyMzEyNDIzNDIzNDIzNDI0MiksXG4gICAgICAgIGFjb3NoOiBhY29zaCgxZTMwOCksXG4gICAgICAgIGFjb3NoUGY6IGFjb3NoUGYoMWUxNTQpLFxuICAgICAgICBhc2luOiBhc2luKDAuMTIzMTI0MjM0MjM0MjM0MjQyKSxcbiAgICAgICAgYXNpbmg6IGFzaW5oKDEpLFxuICAgICAgICBhc2luaFBmOiBhc2luaFBmKDEpLFxuICAgICAgICBhdGFuaDogYXRhbmgoMC41KSxcbiAgICAgICAgYXRhbmhQZjogYXRhbmhQZigwLjUpLFxuICAgICAgICBhdGFuOiBhdGFuKDAuNSksXG4gICAgICAgIHNpbjogc2luKC0xZTMwMCksXG4gICAgICAgIHNpbmg6IHNpbmgoMSksXG4gICAgICAgIHNpbmhQZjogc2luaFBmKDEpLFxuICAgICAgICBjb3M6IGNvcygxMC4wMDAwMDAwMDAxMjMpLFxuICAgICAgICBjb3NoOiBjb3NoKDEpLFxuICAgICAgICBjb3NoUGY6IGNvc2hQZigxKSxcbiAgICAgICAgdGFuOiB0YW4oLTFlMzAwKSxcbiAgICAgICAgdGFuaDogdGFuaCgxKSxcbiAgICAgICAgdGFuaFBmOiB0YW5oUGYoMSksXG4gICAgICAgIGV4cDogZXhwKDEpLFxuICAgICAgICBleHBtMTogZXhwbTEoMSksXG4gICAgICAgIGV4cG0xUGY6IGV4cG0xUGYoMSksXG4gICAgICAgIGxvZzFwOiBsb2cxcCgxMCksXG4gICAgICAgIGxvZzFwUGY6IGxvZzFwUGYoMTApLFxuICAgICAgICBwb3dQSTogcG93UEkoLTEwMCksXG4gICAgfTtcbn1cblxuLyoqXG4gKiBXZSB1c2UgbSBvciB3IGJlY2F1c2UgdGhlc2UgdHdvIGNoYXJhY3RlcnMgdGFrZSB1cCB0aGUgbWF4aW11bSB3aWR0aC5cbiAqIEFsc28gdGhlcmUgYXJlIGEgY291cGxlIG9mIGxpZ2F0dXJlcy5cbiAqL1xudmFyIGRlZmF1bHRUZXh0ID0gJ21tTXdXTGxpSTBmaWZsTyYxJztcbi8qKlxuICogU2V0dGluZ3Mgb2YgdGV4dCBibG9ja3MgdG8gbWVhc3VyZS4gVGhlIGtleXMgYXJlIHJhbmRvbSBidXQgcGVyc2lzdGVudCB3b3Jkcy5cbiAqL1xudmFyIHByZXNldHMgPSB7XG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgZm9udC4gVXNlciBjYW4gY2hhbmdlIGl0IGluIGRlc2t0b3AgQ2hyb21lLCBkZXNrdG9wIEZpcmVmb3gsIElFIDExLFxuICAgICAqIEFuZHJvaWQgQ2hyb21lIChidXQgb25seSB3aGVuIHRoZSBzaXplIGlzIOKJpSB0aGFuIHRoZSBkZWZhdWx0KSBhbmQgQW5kcm9pZCBGaXJlZm94LlxuICAgICAqL1xuICAgIGRlZmF1bHQ6IFtdLFxuICAgIC8qKiBPUyBmb250IG9uIG1hY09TLiBVc2VyIGNhbiBjaGFuZ2UgaXRzIHNpemUgYW5kIHdlaWdodC4gQXBwbGllcyBhZnRlciBTYWZhcmkgcmVzdGFydC4gKi9cbiAgICBhcHBsZTogW3sgZm9udDogJy1hcHBsZS1zeXN0ZW0tYm9keScgfV0sXG4gICAgLyoqIFVzZXIgY2FuIGNoYW5nZSBpdCBpbiBkZXNrdG9wIENocm9tZSBhbmQgZGVza3RvcCBGaXJlZm94LiAqL1xuICAgIHNlcmlmOiBbeyBmb250RmFtaWx5OiAnc2VyaWYnIH1dLFxuICAgIC8qKiBVc2VyIGNhbiBjaGFuZ2UgaXQgaW4gZGVza3RvcCBDaHJvbWUgYW5kIGRlc2t0b3AgRmlyZWZveC4gKi9cbiAgICBzYW5zOiBbeyBmb250RmFtaWx5OiAnc2Fucy1zZXJpZicgfV0sXG4gICAgLyoqIFVzZXIgY2FuIGNoYW5nZSBpdCBpbiBkZXNrdG9wIENocm9tZSBhbmQgZGVza3RvcCBGaXJlZm94LiAqL1xuICAgIG1vbm86IFt7IGZvbnRGYW1pbHk6ICdtb25vc3BhY2UnIH1dLFxuICAgIC8qKlxuICAgICAqIENoZWNrIHRoZSBzbWFsbGVzdCBhbGxvd2VkIGZvbnQgc2l6ZS4gVXNlciBjYW4gY2hhbmdlIGl0IGluIGRlc2t0b3AgQ2hyb21lLCBkZXNrdG9wIEZpcmVmb3ggYW5kIGRlc2t0b3AgU2FmYXJpLlxuICAgICAqIFRoZSBoZWlnaHQgY2FuIGJlIDAgaW4gQ2hyb21lIG9uIGEgcmV0aW5hIGRpc3BsYXkuXG4gICAgICovXG4gICAgbWluOiBbeyBmb250U2l6ZTogJzFweCcgfV0sXG4gICAgLyoqIFRlbGxzIG9uZSBPUyBmcm9tIGFub3RoZXIgaW4gZGVza3RvcCBDaHJvbWUuICovXG4gICAgc3lzdGVtOiBbeyBmb250RmFtaWx5OiAnc3lzdGVtLXVpJyB9XSxcbn07XG4vKipcbiAqIFRoZSByZXN1bHQgaXMgYSBkaWN0aW9uYXJ5IG9mIHRoZSB3aWR0aCBvZiB0aGUgdGV4dCBzYW1wbGVzLlxuICogSGVpZ2h0cyBhcmVuJ3QgaW5jbHVkZWQgYmVjYXVzZSB0aGV5IGdpdmUgbm8gZXh0cmEgZW50cm9weSBhbmQgYXJlIHVuc3RhYmxlLlxuICpcbiAqIFRoZSByZXN1bHQgaXMgdmVyeSBzdGFibGUgaW4gSUUgMTEsIEVkZ2UgMTggYW5kIFNhZmFyaSAxNC5cbiAqIFRoZSByZXN1bHQgY2hhbmdlcyB3aGVuIHRoZSBPUyBwaXhlbCBkZW5zaXR5IGNoYW5nZXMgaW4gQ2hyb21pdW0gODcuIFRoZSByZWFsIHBpeGVsIGRlbnNpdHkgaXMgcmVxdWlyZWQgdG8gc29sdmUsXG4gKiBidXQgc2VlbXMgbGlrZSBpdCdzIGltcG9zc2libGU6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcS8xNzEzNzcxLzExMTg3MDkuXG4gKiBUaGUgXCJtaW5cIiBhbmQgdGhlIFwibW9ub1wiIChvbmx5IG9uIFdpbmRvd3MpIHZhbHVlIG1heSBjaGFuZ2Ugd2hlbiB0aGUgcGFnZSBpcyB6b29tZWQgaW4gRmlyZWZveCA4Ny5cbiAqL1xuZnVuY3Rpb24gZ2V0Rm9udFByZWZlcmVuY2VzKCkge1xuICAgIHJldHVybiB3aXRoTmF0dXJhbEZvbnRzKGZ1bmN0aW9uIChkb2N1bWVudCwgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHt9O1xuICAgICAgICB2YXIgc2l6ZXMgPSB7fTtcbiAgICAgICAgLy8gRmlyc3QgY3JlYXRlIGFsbCBlbGVtZW50cyB0byBtZWFzdXJlLiBJZiB0aGUgRE9NIHN0ZXBzIGJlbG93IGFyZSBkb25lIGluIGEgc2luZ2xlIGN5Y2xlLFxuICAgICAgICAvLyBicm93c2VyIHdpbGwgYWx0ZXJuYXRlIHRyZWUgbW9kaWZpY2F0aW9uIGFuZCBsYXlvdXQgcmVhZGluZywgdGhhdCBpcyB2ZXJ5IHNsb3cuXG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBPYmplY3Qua2V5cyhwcmVzZXRzKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBfYVtfaV07XG4gICAgICAgICAgICB2YXIgX2IgPSBwcmVzZXRzW2tleV0sIF9jID0gX2JbMF0sIHN0eWxlID0gX2MgPT09IHZvaWQgMCA/IHt9IDogX2MsIF9kID0gX2JbMV0sIHRleHQgPSBfZCA9PT0gdm9pZCAwID8gZGVmYXVsdFRleHQgOiBfZDtcbiAgICAgICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgZWxlbWVudC50ZXh0Q29udGVudCA9IHRleHQ7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLndoaXRlU3BhY2UgPSAnbm93cmFwJztcbiAgICAgICAgICAgIGZvciAodmFyIF9lID0gMCwgX2YgPSBPYmplY3Qua2V5cyhzdHlsZSk7IF9lIDwgX2YubGVuZ3RoOyBfZSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5hbWVfMSA9IF9mW19lXTtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBzdHlsZVtuYW1lXzFdO1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVbbmFtZV8xXSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsZW1lbnRzW2tleV0gPSBlbGVtZW50O1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJykpO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZW4gbWVhc3VyZSB0aGUgY3JlYXRlZCBlbGVtZW50c1xuICAgICAgICBmb3IgKHZhciBfZyA9IDAsIF9oID0gT2JqZWN0LmtleXMocHJlc2V0cyk7IF9nIDwgX2gubGVuZ3RoOyBfZysrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gX2hbX2ddO1xuICAgICAgICAgICAgc2l6ZXNba2V5XSA9IGVsZW1lbnRzW2tleV0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNpemVzO1xuICAgIH0pO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgRE9NIGVudmlyb25tZW50IHRoYXQgcHJvdmlkZXMgdGhlIG1vc3QgbmF0dXJhbCBmb250IGF2YWlsYWJsZSwgaW5jbHVkaW5nIEFuZHJvaWQgT1MgZm9udC5cbiAqIE1lYXN1cmVtZW50cyBvZiB0aGUgZWxlbWVudHMgYXJlIHpvb20taW5kZXBlbmRlbnQuXG4gKiBEb24ndCBwdXQgYSBjb250ZW50IHRvIG1lYXN1cmUgaW5zaWRlIGFuIGFic29sdXRlbHkgcG9zaXRpb25lZCBlbGVtZW50LlxuICovXG5mdW5jdGlvbiB3aXRoTmF0dXJhbEZvbnRzKGFjdGlvbiwgY29udGFpbmVyV2lkdGhQeCkge1xuICAgIGlmIChjb250YWluZXJXaWR0aFB4ID09PSB2b2lkIDApIHsgY29udGFpbmVyV2lkdGhQeCA9IDQwMDA7IH1cbiAgICAvKlxuICAgICAqIFJlcXVpcmVtZW50cyBmb3IgQW5kcm9pZCBDaHJvbWUgdG8gYXBwbHkgdGhlIHN5c3RlbSBmb250IHNpemUgdG8gYSB0ZXh0IGluc2lkZSBhbiBpZnJhbWU6XG4gICAgICogLSBUaGUgaWZyYW1lIG11c3RuJ3QgaGF2ZSBhIGBkaXNwbGF5OiBub25lO2Agc3R5bGU7XG4gICAgICogLSBUaGUgdGV4dCBtdXN0bid0IGJlIHBvc2l0aW9uZWQgYWJzb2x1dGVseTtcbiAgICAgKiAtIFRoZSB0ZXh0IGJsb2NrIG11c3QgYmUgd2lkZSBlbm91Z2guXG4gICAgICogICAyNTYwcHggb24gc29tZSBkZXZpY2VzIGluIHBvcnRyYWl0IG9yaWVudGF0aW9uIGZvciB0aGUgYmlnZ2VzdCBmb250IHNpemUgb3B0aW9uICgzMnB4KTtcbiAgICAgKiAtIFRoZXJlIG11c3QgYmUgbXVjaCBlbm91Z2ggdGV4dCB0byBmb3JtIGEgZmV3IGxpbmVzIChJIGRvbid0IGtub3cgdGhlIGV4YWN0IG51bWJlcnMpO1xuICAgICAqIC0gVGhlIHRleHQgbXVzdCBoYXZlIHRoZSBgdGV4dC1zaXplLWFkanVzdDogbm9uZWAgc3R5bGUuIE90aGVyd2lzZSB0aGUgdGV4dCB3aWxsIHNjYWxlIGluIFwiRGVza3RvcCBzaXRlXCIgbW9kZTtcbiAgICAgKlxuICAgICAqIFJlcXVpcmVtZW50cyBmb3IgQW5kcm9pZCBGaXJlZm94IHRvIGFwcGx5IHRoZSBzeXN0ZW0gZm9udCBzaXplIHRvIGEgdGV4dCBpbnNpZGUgYW4gaWZyYW1lOlxuICAgICAqIC0gVGhlIGlmcmFtZSBkb2N1bWVudCBtdXN0IGhhdmUgYSBoZWFkZXI6IGA8bWV0YSBuYW1lPVwidmlld3BvcnRcIiBjb250ZW50PVwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTFcIiAvPmAuXG4gICAgICogICBUaGUgb25seSB3YXkgdG8gc2V0IGl0IGlzIHRvIHVzZSB0aGUgYHNyY2RvY2AgYXR0cmlidXRlIG9mIHRoZSBpZnJhbWU7XG4gICAgICogLSBUaGUgaWZyYW1lIGNvbnRlbnQgbXVzdCBnZXQgbG9hZGVkIGJlZm9yZSBhZGRpbmcgZXh0cmEgY29udGVudCB3aXRoIEphdmFTY3JpcHQ7XG4gICAgICpcbiAgICAgKiBodHRwczovL2V4YW1wbGUuY29tIGFzIHRoZSBpZnJhbWUgdGFyZ2V0IGFsd2F5cyBpbmhlcml0cyBBbmRyb2lkIGZvbnQgc2V0dGluZ3Mgc28gaXQgY2FuIGJlIHVzZWQgYXMgYSByZWZlcmVuY2UuXG4gICAgICpcbiAgICAgKiBPYnNlcnZhdGlvbnMgb24gaG93IHBhZ2Ugem9vbSBhZmZlY3RzIHRoZSBtZWFzdXJlbWVudHM6XG4gICAgICogLSBtYWNPUyBTYWZhcmkgMTEuMSwgMTIuMSwgMTMuMSwgMTQuMDogem9vbSByZXNldCArIG9mZnNldFdpZHRoID0gMTAwJSByZWxpYWJsZTtcbiAgICAgKiAtIG1hY09TIFNhZmFyaSAxMS4xLCAxMi4xLCAxMy4xLCAxNC4wOiB6b29tIHJlc2V0ICsgZ2V0Qm91bmRpbmdDbGllbnRSZWN0ID0gMTAwJSByZWxpYWJsZTtcbiAgICAgKiAtIG1hY09TIFNhZmFyaSAxNC4wOiBvZmZzZXRXaWR0aCA9IDUlIGZsdWN0dWF0aW9uO1xuICAgICAqIC0gbWFjT1MgU2FmYXJpIDE0LjA6IGdldEJvdW5kaW5nQ2xpZW50UmVjdCA9IDUlIGZsdWN0dWF0aW9uO1xuICAgICAqIC0gaU9TIFNhZmFyaSA5LCAxMCwgMTEuMCwgMTIuMDogaGF2ZW4ndCBmb3VuZCBhIHdheSB0byB6b29tIGEgcGFnZSAocGluY2ggZG9lc24ndCBjaGFuZ2UgbGF5b3V0KTtcbiAgICAgKiAtIGlPUyBTYWZhcmkgMTMuMSwgMTQuMDogem9vbSByZXNldCArIG9mZnNldFdpZHRoID0gMTAwJSByZWxpYWJsZTtcbiAgICAgKiAtIGlPUyBTYWZhcmkgMTMuMSwgMTQuMDogem9vbSByZXNldCArIGdldEJvdW5kaW5nQ2xpZW50UmVjdCA9IDEwMCUgcmVsaWFibGU7XG4gICAgICogLSBpT1MgU2FmYXJpIDE0LjA6IG9mZnNldFdpZHRoID0gMTAwJSByZWxpYWJsZTtcbiAgICAgKiAtIGlPUyBTYWZhcmkgMTQuMDogZ2V0Qm91bmRpbmdDbGllbnRSZWN0ID0gMTAwJSByZWxpYWJsZTtcbiAgICAgKiAtIENocm9tZSA0MiwgNjUsIDgwLCA4Nzogem9vbSAxL2RldmljZVBpeGVsUmF0aW8gKyBvZmZzZXRXaWR0aCA9IDFweCBmbHVjdHVhdGlvbjtcbiAgICAgKiAtIENocm9tZSA0MiwgNjUsIDgwLCA4Nzogem9vbSAxL2RldmljZVBpeGVsUmF0aW8gKyBnZXRCb3VuZGluZ0NsaWVudFJlY3QgPSAxMDAlIHJlbGlhYmxlO1xuICAgICAqIC0gQ2hyb21lIDg3OiBvZmZzZXRXaWR0aCA9IDFweCBmbHVjdHVhdGlvbjtcbiAgICAgKiAtIENocm9tZSA4NzogZ2V0Qm91bmRpbmdDbGllbnRSZWN0ID0gMC43cHggZmx1Y3R1YXRpb247XG4gICAgICogLSBGaXJlZm94IDQ4LCA1MTogb2Zmc2V0V2lkdGggPSAxMCUgZmx1Y3R1YXRpb247XG4gICAgICogLSBGaXJlZm94IDQ4LCA1MTogZ2V0Qm91bmRpbmdDbGllbnRSZWN0ID0gMTAlIGZsdWN0dWF0aW9uO1xuICAgICAqIC0gRmlyZWZveCA1MiwgNTMsIDU3LCA2MiwgNjYsIDY3LCA2OCwgNzEsIDc1LCA4MCwgODQ6IG9mZnNldFdpZHRoID0gd2lkdGggMTAwJSByZWxpYWJsZSwgaGVpZ2h0IDEwJSBmbHVjdHVhdGlvbjtcbiAgICAgKiAtIEZpcmVmb3ggNTIsIDUzLCA1NywgNjIsIDY2LCA2NywgNjgsIDcxLCA3NSwgODAsIDg0OiBnZXRCb3VuZGluZ0NsaWVudFJlY3QgPSB3aWR0aCAxMDAlIHJlbGlhYmxlLCBoZWlnaHQgMTAlXG4gICAgICogICBmbHVjdHVhdGlvbjtcbiAgICAgKiAtIEFuZHJvaWQgQ2hyb21lIDg2OiBoYXZlbid0IGZvdW5kIGEgd2F5IHRvIHpvb20gYSBwYWdlIChwaW5jaCBkb2Vzbid0IGNoYW5nZSBsYXlvdXQpO1xuICAgICAqIC0gQW5kcm9pZCBGaXJlZm94IDg0OiBmb250IHNpemUgaW4gYWNjZXNzaWJpbGl0eSBzZXR0aW5ncyBjaGFuZ2VzIGFsbCB0aGUgQ1NTIHNpemVzLCBidXQgb2Zmc2V0V2lkdGggYW5kXG4gICAgICogICBnZXRCb3VuZGluZ0NsaWVudFJlY3Qga2VlcCBtZWFzdXJpbmcgd2l0aCByZWd1bGFyIHVuaXRzLCBzbyB0aGUgc2l6ZSByZWZsZWN0cyB0aGUgZm9udCBzaXplIHNldHRpbmcgYW5kIGRvZXNuJ3RcbiAgICAgKiAgIGZsdWN0dWF0ZTtcbiAgICAgKiAtIElFIDExLCBFZGdlIDE4OiB6b29tIDEvZGV2aWNlUGl4ZWxSYXRpbyArIG9mZnNldFdpZHRoID0gMTAwJSByZWxpYWJsZTtcbiAgICAgKiAtIElFIDExLCBFZGdlIDE4OiB6b29tIDEvZGV2aWNlUGl4ZWxSYXRpbyArIGdldEJvdW5kaW5nQ2xpZW50UmVjdCA9IHJlZmxlY3RzIHRoZSB6b29tIGxldmVsO1xuICAgICAqIC0gSUUgMTEsIEVkZ2UgMTg6IG9mZnNldFdpZHRoID0gMTAwJSByZWxpYWJsZTtcbiAgICAgKiAtIElFIDExLCBFZGdlIDE4OiBnZXRCb3VuZGluZ0NsaWVudFJlY3QgPSAxMDAlIHJlbGlhYmxlO1xuICAgICAqL1xuICAgIHJldHVybiB3aXRoSWZyYW1lKGZ1bmN0aW9uIChfLCBpZnJhbWVXaW5kb3cpIHtcbiAgICAgICAgdmFyIGlmcmFtZURvY3VtZW50ID0gaWZyYW1lV2luZG93LmRvY3VtZW50O1xuICAgICAgICB2YXIgaWZyYW1lQm9keSA9IGlmcmFtZURvY3VtZW50LmJvZHk7XG4gICAgICAgIHZhciBib2R5U3R5bGUgPSBpZnJhbWVCb2R5LnN0eWxlO1xuICAgICAgICBib2R5U3R5bGUud2lkdGggPSBjb250YWluZXJXaWR0aFB4ICsgXCJweFwiO1xuICAgICAgICBib2R5U3R5bGUud2Via2l0VGV4dFNpemVBZGp1c3QgPSBib2R5U3R5bGUudGV4dFNpemVBZGp1c3QgPSAnbm9uZSc7XG4gICAgICAgIC8vIFNlZSB0aGUgYmlnIGNvbW1lbnQgYWJvdmVcbiAgICAgICAgaWYgKGlzQ2hyb21pdW0oKSkge1xuICAgICAgICAgICAgaWZyYW1lQm9keS5zdHlsZS56b29tID0gXCJcIiArIDEgLyBpZnJhbWVXaW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1dlYktpdCgpKSB7XG4gICAgICAgICAgICBpZnJhbWVCb2R5LnN0eWxlLnpvb20gPSAncmVzZXQnO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNlZSB0aGUgYmlnIGNvbW1lbnQgYWJvdmVcbiAgICAgICAgdmFyIGxpbmVzT2ZUZXh0ID0gaWZyYW1lRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGxpbmVzT2ZUZXh0LnRleHRDb250ZW50ID0gdHNsaWIuX19zcHJlYWRBcnJheXMoQXJyYXkoKGNvbnRhaW5lcldpZHRoUHggLyAyMCkgPDwgMCkpLm1hcChmdW5jdGlvbiAoKSB7IHJldHVybiAnd29yZCc7IH0pLmpvaW4oJyAnKTtcbiAgICAgICAgaWZyYW1lQm9keS5hcHBlbmRDaGlsZChsaW5lc09mVGV4dCk7XG4gICAgICAgIHJldHVybiBhY3Rpb24oaWZyYW1lRG9jdW1lbnQsIGlmcmFtZUJvZHkpO1xuICAgIH0sICc8IWRvY3R5cGUgaHRtbD48aHRtbD48aGVhZD48bWV0YSBuYW1lPVwidmlld3BvcnRcIiBjb250ZW50PVwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTFcIj4nKTtcbn1cblxuLyoqXG4gKiBUaGUgbGlzdCBvZiBlbnRyb3B5IHNvdXJjZXMgdXNlZCB0byBtYWtlIHZpc2l0b3IgaWRlbnRpZmllcnMuXG4gKlxuICogVGhpcyB2YWx1ZSBpc24ndCByZXN0cmljdGVkIGJ5IFNlbWFudGljIFZlcnNpb25pbmcsIGkuZS4gaXQgbWF5IGJlIGNoYW5nZWQgd2l0aG91dCBidW1waW5nIG1pbm9yIG9yIG1ham9yIHZlcnNpb24gb2ZcbiAqIHRoaXMgcGFja2FnZS5cbiAqXG4gKiBOb3RlOiBSb2xsdXAgYW5kIFdlYnBhY2sgYXJlIHNtYXJ0IGVub3VnaCB0byByZW1vdmUgdW51c2VkIHByb3BlcnRpZXMgb2YgdGhpcyBvYmplY3QgZHVyaW5nIHRyZWUtc2hha2luZywgc28gdGhlcmUgaXNcbiAqIG5vIG5lZWQgdG8gZXhwb3J0IHRoZSBzb3VyY2VzIGluZGl2aWR1YWxseS5cbiAqL1xudmFyIHNvdXJjZXMgPSB7XG4gICAgLy8gUkVBRCBGSVJTVDpcbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZpbmdlcnByaW50anMvZmluZ2VycHJpbnRqcy9ibG9iL21hc3Rlci9jb250cmlidXRpbmcubWQjaG93LXRvLW1ha2UtYW4tZW50cm9weS1zb3VyY2VcbiAgICAvLyB0byBsZWFybiBob3cgZW50cm9weSBzb3VyY2Ugd29ya3MgYW5kIGhvdyB0byBtYWtlIHlvdXIgb3duLlxuICAgIC8vIFRoZSBzb3VyY2VzIHJ1biBpbiB0aGlzIGV4YWN0IG9yZGVyLlxuICAgIC8vIFRoZSBhc3luY2hyb25vdXMgc291cmNlcyBhcmUgYXQgdGhlIHN0YXJ0IHRvIHJ1biBpbiBwYXJhbGxlbCB3aXRoIG90aGVyIHNvdXJjZXMuXG4gICAgZm9udHM6IGdldEZvbnRzLFxuICAgIGRvbUJsb2NrZXJzOiBnZXREb21CbG9ja2VycyxcbiAgICBmb250UHJlZmVyZW5jZXM6IGdldEZvbnRQcmVmZXJlbmNlcyxcbiAgICBhdWRpbzogZ2V0QXVkaW9GaW5nZXJwcmludCxcbiAgICBzY3JlZW5GcmFtZTogZ2V0Um91bmRlZFNjcmVlbkZyYW1lLFxuICAgIG9zQ3B1OiBnZXRPc0NwdSxcbiAgICBsYW5ndWFnZXM6IGdldExhbmd1YWdlcyxcbiAgICBjb2xvckRlcHRoOiBnZXRDb2xvckRlcHRoLFxuICAgIGRldmljZU1lbW9yeTogZ2V0RGV2aWNlTWVtb3J5LFxuICAgIHNjcmVlblJlc29sdXRpb246IGdldFNjcmVlblJlc29sdXRpb24sXG4gICAgaGFyZHdhcmVDb25jdXJyZW5jeTogZ2V0SGFyZHdhcmVDb25jdXJyZW5jeSxcbiAgICB0aW1lem9uZTogZ2V0VGltZXpvbmUsXG4gICAgc2Vzc2lvblN0b3JhZ2U6IGdldFNlc3Npb25TdG9yYWdlLFxuICAgIGxvY2FsU3RvcmFnZTogZ2V0TG9jYWxTdG9yYWdlLFxuICAgIGluZGV4ZWREQjogZ2V0SW5kZXhlZERCLFxuICAgIG9wZW5EYXRhYmFzZTogZ2V0T3BlbkRhdGFiYXNlLFxuICAgIGNwdUNsYXNzOiBnZXRDcHVDbGFzcyxcbiAgICBwbGF0Zm9ybTogZ2V0UGxhdGZvcm0sXG4gICAgcGx1Z2luczogZ2V0UGx1Z2lucyxcbiAgICBjYW52YXM6IGdldENhbnZhc0ZpbmdlcnByaW50LFxuICAgIHRvdWNoU3VwcG9ydDogZ2V0VG91Y2hTdXBwb3J0LFxuICAgIHZlbmRvcjogZ2V0VmVuZG9yLFxuICAgIHZlbmRvckZsYXZvcnM6IGdldFZlbmRvckZsYXZvcnMsXG4gICAgY29va2llc0VuYWJsZWQ6IGFyZUNvb2tpZXNFbmFibGVkLFxuICAgIGNvbG9yR2FtdXQ6IGdldENvbG9yR2FtdXQsXG4gICAgaW52ZXJ0ZWRDb2xvcnM6IGFyZUNvbG9yc0ludmVydGVkLFxuICAgIGZvcmNlZENvbG9yczogYXJlQ29sb3JzRm9yY2VkLFxuICAgIG1vbm9jaHJvbWU6IGdldE1vbm9jaHJvbWVEZXB0aCxcbiAgICBjb250cmFzdDogZ2V0Q29udHJhc3RQcmVmZXJlbmNlLFxuICAgIHJlZHVjZWRNb3Rpb246IGlzTW90aW9uUmVkdWNlZCxcbiAgICBoZHI6IGlzSERSLFxuICAgIG1hdGg6IGdldE1hdGhGaW5nZXJwcmludCxcbn07XG4vKipcbiAqIExvYWRzIHRoZSBidWlsdC1pbiBlbnRyb3B5IHNvdXJjZXMuXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBjb2xsZWN0cyB0aGUgZW50cm9weSBjb21wb25lbnRzIHRvIG1ha2UgdGhlIHZpc2l0b3IgaWRlbnRpZmllci5cbiAqL1xuZnVuY3Rpb24gbG9hZEJ1aWx0aW5Tb3VyY2VzKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbG9hZFNvdXJjZXMoc291cmNlcywgb3B0aW9ucywgW10pO1xufVxuXG52YXIgY29tbWVudFRlbXBsYXRlID0gJyQgaWYgdXBncmFkZSB0byBQcm86IGh0dHBzOi8vZnBqcy5kZXYvcHJvJztcbmZ1bmN0aW9uIGdldENvbmZpZGVuY2UoY29tcG9uZW50cykge1xuICAgIHZhciBvcGVuQ29uZmlkZW5jZVNjb3JlID0gZ2V0T3BlbkNvbmZpZGVuY2VTY29yZShjb21wb25lbnRzKTtcbiAgICB2YXIgcHJvQ29uZmlkZW5jZVNjb3JlID0gZGVyaXZlUHJvQ29uZmlkZW5jZVNjb3JlKG9wZW5Db25maWRlbmNlU2NvcmUpO1xuICAgIHJldHVybiB7IHNjb3JlOiBvcGVuQ29uZmlkZW5jZVNjb3JlLCBjb21tZW50OiBjb21tZW50VGVtcGxhdGUucmVwbGFjZSgvXFwkL2csIFwiXCIgKyBwcm9Db25maWRlbmNlU2NvcmUpIH07XG59XG5mdW5jdGlvbiBnZXRPcGVuQ29uZmlkZW5jZVNjb3JlKGNvbXBvbmVudHMpIHtcbiAgICAvLyBJbiBvcmRlciB0byBjYWxjdWxhdGUgdGhlIHRydWUgcHJvYmFiaWxpdHkgb2YgdGhlIHZpc2l0b3IgaWRlbnRpZmllciBiZWluZyBjb3JyZWN0LCB3ZSBuZWVkIHRvIGtub3cgdGhlIG51bWJlciBvZlxuICAgIC8vIHdlYnNpdGUgdmlzaXRvcnMgKHRoZSBoaWdoZXIgdGhlIG51bWJlciwgdGhlIGxlc3MgdGhlIHByb2JhYmlsaXR5IGJlY2F1c2UgdGhlIGZpbmdlcnByaW50IGVudHJvcHkgaXMgbGltaXRlZCkuXG4gICAgLy8gSlMgYWdlbnQgZG9lc24ndCBrbm93IHRoZSBudW1iZXIgb2YgdmlzaXRvcnMsIHNvIHdlIGNhbiBvbmx5IGRvIGFuIGFwcHJveGltYXRlIGFzc2Vzc21lbnQuXG4gICAgaWYgKGlzQW5kcm9pZCgpKSB7XG4gICAgICAgIHJldHVybiAwLjQ7XG4gICAgfVxuICAgIC8vIFNhZmFyaSAobW9iaWxlIGFuZCBkZXNrdG9wKVxuICAgIGlmIChpc1dlYktpdCgpKSB7XG4gICAgICAgIHJldHVybiBpc0Rlc2t0b3BTYWZhcmkoKSA/IDAuNSA6IDAuMztcbiAgICB9XG4gICAgdmFyIHBsYXRmb3JtID0gY29tcG9uZW50cy5wbGF0Zm9ybS52YWx1ZSB8fCAnJztcbiAgICAvLyBXaW5kb3dzXG4gICAgaWYgKC9eV2luLy50ZXN0KHBsYXRmb3JtKSkge1xuICAgICAgICAvLyBUaGUgc2NvcmUgaXMgZ3JlYXRlciB0aGFuIG9uIG1hY09TIGJlY2F1c2Ugb2YgdGhlIGhpZ2hlciB2YXJpZXR5IG9mIGRldmljZXMgcnVubmluZyBXaW5kb3dzLlxuICAgICAgICAvLyBDaHJvbWUgcHJvdmlkZXMgbW9yZSBlbnRyb3B5IHRoYW4gRmlyZWZveCBhY2NvcmRpbmcgdG9vXG4gICAgICAgIC8vIGh0dHBzOi8vbmV0bWFya2V0c2hhcmUuY29tL2Jyb3dzZXItbWFya2V0LXNoYXJlLmFzcHg/b3B0aW9ucz0lN0IlMjJmaWx0ZXIlMjIlM0ElN0IlMjIlMjRhbmQlMjIlM0ElNUIlN0IlMjJwbGF0Zm9ybSUyMiUzQSU3QiUyMiUyNGluJTIyJTNBJTVCJTIyV2luZG93cyUyMiU1RCU3RCU3RCU1RCU3RCUyQyUyMmRhdGVMYWJlbCUyMiUzQSUyMlRyZW5kJTIyJTJDJTIyYXR0cmlidXRlcyUyMiUzQSUyMnNoYXJlJTIyJTJDJTIyZ3JvdXAlMjIlM0ElMjJicm93c2VyJTIyJTJDJTIyc29ydCUyMiUzQSU3QiUyMnNoYXJlJTIyJTNBLTElN0QlMkMlMjJpZCUyMiUzQSUyMmJyb3dzZXJzRGVza3RvcCUyMiUyQyUyMmRhdGVJbnRlcnZhbCUyMiUzQSUyMk1vbnRobHklMjIlMkMlMjJkYXRlU3RhcnQlMjIlM0ElMjIyMDE5LTExJTIyJTJDJTIyZGF0ZUVuZCUyMiUzQSUyMjIwMjAtMTAlMjIlMkMlMjJzZWdtZW50cyUyMiUzQSUyMi0xMDAwJTIyJTdEXG4gICAgICAgIC8vIFNvIHdlIGFzc2lnbiB0aGUgc2FtZSBzY29yZSB0byB0aGVtLlxuICAgICAgICByZXR1cm4gMC42O1xuICAgIH1cbiAgICAvLyBtYWNPU1xuICAgIGlmICgvXk1hYy8udGVzdChwbGF0Zm9ybSkpIHtcbiAgICAgICAgLy8gQ2hyb21lIHByb3ZpZGVzIG1vcmUgZW50cm9weSB0aGFuIFNhZmFyaSBhbmQgU2FmYXJpIHByb3ZpZGVzIG1vcmUgZW50cm9weSB0aGFuIEZpcmVmb3guXG4gICAgICAgIC8vIENocm9tZSBpcyBtb3JlIHBvcHVsYXIgdGhhbiBTYWZhcmkgYW5kIFNhZmFyaSBpcyBtb3JlIHBvcHVsYXIgdGhhbiBGaXJlZm94IGFjY29yZGluZyB0b1xuICAgICAgICAvLyBodHRwczovL25ldG1hcmtldHNoYXJlLmNvbS9icm93c2VyLW1hcmtldC1zaGFyZS5hc3B4P29wdGlvbnM9JTdCJTIyZmlsdGVyJTIyJTNBJTdCJTIyJTI0YW5kJTIyJTNBJTVCJTdCJTIycGxhdGZvcm0lMjIlM0ElN0IlMjIlMjRpbiUyMiUzQSU1QiUyMk1hYyUyME9TJTIyJTVEJTdEJTdEJTVEJTdEJTJDJTIyZGF0ZUxhYmVsJTIyJTNBJTIyVHJlbmQlMjIlMkMlMjJhdHRyaWJ1dGVzJTIyJTNBJTIyc2hhcmUlMjIlMkMlMjJncm91cCUyMiUzQSUyMmJyb3dzZXIlMjIlMkMlMjJzb3J0JTIyJTNBJTdCJTIyc2hhcmUlMjIlM0EtMSU3RCUyQyUyMmlkJTIyJTNBJTIyYnJvd3NlcnNEZXNrdG9wJTIyJTJDJTIyZGF0ZUludGVydmFsJTIyJTNBJTIyTW9udGhseSUyMiUyQyUyMmRhdGVTdGFydCUyMiUzQSUyMjIwMTktMTElMjIlMkMlMjJkYXRlRW5kJTIyJTNBJTIyMjAyMC0xMCUyMiUyQyUyMnNlZ21lbnRzJTIyJTNBJTIyLTEwMDAlMjIlN0RcbiAgICAgICAgLy8gU28gd2UgYXNzaWduIHRoZSBzYW1lIHNjb3JlIHRvIHRoZW0uXG4gICAgICAgIHJldHVybiAwLjU7XG4gICAgfVxuICAgIC8vIEFub3RoZXIgcGxhdGZvcm0sIGUuZy4gYSBkZXNrdG9wIExpbnV4LiBJdCdzIHJhcmUsIHNvIGl0IHNob3VsZCBiZSBwcmV0dHkgdW5pcXVlLlxuICAgIHJldHVybiAwLjc7XG59XG5mdW5jdGlvbiBkZXJpdmVQcm9Db25maWRlbmNlU2NvcmUob3BlbkNvbmZpZGVuY2VTY29yZSkge1xuICAgIHJldHVybiByb3VuZCgwLjk5ICsgMC4wMSAqIG9wZW5Db25maWRlbmNlU2NvcmUsIDAuMDAwMSk7XG59XG5cbmZ1bmN0aW9uIGNvbXBvbmVudHNUb0Nhbm9uaWNhbFN0cmluZyhjb21wb25lbnRzKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBPYmplY3Qua2V5cyhjb21wb25lbnRzKS5zb3J0KCk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBjb21wb25lbnRLZXkgPSBfYVtfaV07XG4gICAgICAgIHZhciBjb21wb25lbnQgPSBjb21wb25lbnRzW2NvbXBvbmVudEtleV07XG4gICAgICAgIHZhciB2YWx1ZSA9IGNvbXBvbmVudC5lcnJvciA/ICdlcnJvcicgOiBKU09OLnN0cmluZ2lmeShjb21wb25lbnQudmFsdWUpO1xuICAgICAgICByZXN1bHQgKz0gXCJcIiArIChyZXN1bHQgPyAnfCcgOiAnJykgKyBjb21wb25lbnRLZXkucmVwbGFjZSgvKFs6fFxcXFxdKS9nLCAnXFxcXCQxJykgKyBcIjpcIiArIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gY29tcG9uZW50c1RvRGVidWdTdHJpbmcoY29tcG9uZW50cykge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShjb21wb25lbnRzLCBmdW5jdGlvbiAoX2tleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBlcnJvclRvT2JqZWN0KHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSwgMik7XG59XG5mdW5jdGlvbiBoYXNoQ29tcG9uZW50cyhjb21wb25lbnRzKSB7XG4gICAgcmV0dXJuIHg2NGhhc2gxMjgoY29tcG9uZW50c1RvQ2Fub25pY2FsU3RyaW5nKGNvbXBvbmVudHMpKTtcbn1cbi8qKlxuICogTWFrZXMgYSBHZXRSZXN1bHQgaW1wbGVtZW50YXRpb24gdGhhdCBjYWxjdWxhdGVzIHRoZSB2aXNpdG9yIGlkIGhhc2ggb24gZGVtYW5kLlxuICogRGVzaWduZWQgZm9yIG9wdGltaXNhdGlvbi5cbiAqL1xuZnVuY3Rpb24gbWFrZUxhenlHZXRSZXN1bHQoY29tcG9uZW50cykge1xuICAgIHZhciB2aXNpdG9ySWRDYWNoZTtcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHJ1bnMgdmVyeSBmYXN0LCBzbyB0aGVyZSBpcyBubyBuZWVkIHRvIG1ha2UgaXQgbGF6eVxuICAgIHZhciBjb25maWRlbmNlID0gZ2V0Q29uZmlkZW5jZShjb21wb25lbnRzKTtcbiAgICAvLyBBIHBsYWluIGNsYXNzIGlzbid0IHVzZWQgYmVjYXVzZSBpdHMgZ2V0dGVycyBhbmQgc2V0dGVycyBhcmVuJ3QgZW51bWVyYWJsZS5cbiAgICByZXR1cm4ge1xuICAgICAgICBnZXQgdmlzaXRvcklkKCkge1xuICAgICAgICAgICAgaWYgKHZpc2l0b3JJZENhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2aXNpdG9ySWRDYWNoZSA9IGhhc2hDb21wb25lbnRzKHRoaXMuY29tcG9uZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdmlzaXRvcklkQ2FjaGU7XG4gICAgICAgIH0sXG4gICAgICAgIHNldCB2aXNpdG9ySWQodmlzaXRvcklkKSB7XG4gICAgICAgICAgICB2aXNpdG9ySWRDYWNoZSA9IHZpc2l0b3JJZDtcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlkZW5jZTogY29uZmlkZW5jZSxcbiAgICAgICAgY29tcG9uZW50czogY29tcG9uZW50cyxcbiAgICAgICAgdmVyc2lvbjogdmVyc2lvbixcbiAgICB9O1xufVxuLyoqXG4gKiBBIGRlbGF5IGlzIHJlcXVpcmVkIHRvIGVuc3VyZSBjb25zaXN0ZW50IGVudHJvcHkgY29tcG9uZW50cy5cbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9maW5nZXJwcmludGpzL2lzc3Vlcy8yNTRcbiAqIGFuZCBodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9maW5nZXJwcmludGpzL2lzc3Vlcy8zMDdcbiAqIGFuZCBodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9maW5nZXJwcmludGpzL2NvbW1pdC85NDU2MzNlN2M1ZjY3YWUzOGViMGZlYTM3MzQ5NzEyZjBlNjY5YjE4XG4gKi9cbmZ1bmN0aW9uIHByZXBhcmVGb3JTb3VyY2VzKGRlbGF5RmFsbGJhY2spIHtcbiAgICBpZiAoZGVsYXlGYWxsYmFjayA9PT0gdm9pZCAwKSB7IGRlbGF5RmFsbGJhY2sgPSA1MDsgfVxuICAgIC8vIEEgcHJvcGVyIGRlYWRsaW5lIGlzIHVua25vd24uIExldCBpdCBiZSB0d2ljZSB0aGUgZmFsbGJhY2sgdGltZW91dCBzbyB0aGF0IGJvdGggY2FzZXMgaGF2ZSB0aGUgc2FtZSBhdmVyYWdlIHRpbWUuXG4gICAgcmV0dXJuIHJlcXVlc3RJZGxlQ2FsbGJhY2tJZkF2YWlsYWJsZShkZWxheUZhbGxiYWNrLCBkZWxheUZhbGxiYWNrICogMik7XG59XG4vKipcbiAqIFRoZSBmdW5jdGlvbiBpc24ndCBleHBvcnRlZCBmcm9tIHRoZSBpbmRleCBmaWxlIHRvIG5vdCBhbGxvdyB0byBjYWxsIGl0IHdpdGhvdXQgYGxvYWQoKWAuXG4gKiBUaGUgaGlkaW5nIGdpdmVzIG1vcmUgZnJlZWRvbSBmb3IgZnV0dXJlIG5vbi1icmVha2luZyB1cGRhdGVzLlxuICpcbiAqIEEgZmFjdG9yeSBmdW5jdGlvbiBpcyB1c2VkIGluc3RlYWQgb2YgYSBjbGFzcyB0byBzaG9ydGVuIHRoZSBhdHRyaWJ1dGUgbmFtZXMgaW4gdGhlIG1pbmlmaWVkIGNvZGUuXG4gKiBOYXRpdmUgcHJpdmF0ZSBjbGFzcyBmaWVsZHMgY291bGQndmUgYmVlbiB1c2VkLCBidXQgVHlwZVNjcmlwdCBkb2Vzbid0IGFsbG93IHRoZW0gd2l0aCBgXCJ0YXJnZXRcIjogXCJlczVcImAuXG4gKi9cbmZ1bmN0aW9uIG1ha2VBZ2VudChnZXRDb21wb25lbnRzLCBkZWJ1Zykge1xuICAgIHZhciBjcmVhdGlvblRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiB0c2xpYi5fX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RhcnRUaW1lLCBjb21wb25lbnRzLCByZXN1bHQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRzbGliLl9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCBnZXRDb21wb25lbnRzKCldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHMgPSBfYS5zZW50KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbWFrZUxhenlHZXRSZXN1bHQoY29tcG9uZW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlYnVnIHx8IChvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMuZGVidWcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nIGlzIG9rIGhlcmUgYmVjYXVzZSBpdCdzIHVuZGVyIGEgZGVidWcgY2xhdXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ29weSB0aGUgdGV4dCBiZWxvdyB0byBnZXQgdGhlIGRlYnVnIGRhdGE6XFxuXFxuYGBgXFxudmVyc2lvbjogXCIgKyByZXN1bHQudmVyc2lvbiArIFwiXFxudXNlckFnZW50OiBcIiArIG5hdmlnYXRvci51c2VyQWdlbnQgKyBcIlxcbnRpbWVCZXR3ZWVuTG9hZEFuZEdldDogXCIgKyAoc3RhcnRUaW1lIC0gY3JlYXRpb25UaW1lKSArIFwiXFxudmlzaXRvcklkOiBcIiArIHJlc3VsdC52aXNpdG9ySWQgKyBcIlxcbmNvbXBvbmVudHM6IFwiICsgY29tcG9uZW50c1RvRGVidWdTdHJpbmcoY29tcG9uZW50cykgKyBcIlxcbmBgYFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIHJlc3VsdF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgIH07XG59XG4vKipcbiAqIFNlbmRzIGFuIHVucGVyc29uYWxpemVkIEFKQVggcmVxdWVzdCB0byBjb2xsZWN0IGluc3RhbGxhdGlvbiBzdGF0aXN0aWNzXG4gKi9cbmZ1bmN0aW9uIG1vbml0b3IoKSB7XG4gICAgLy8gVGhlIEZpbmdlcnByaW50SlMgQ0ROIChodHRwczovL2dpdGh1Yi5jb20vZmluZ2VycHJpbnRqcy9jZG4pIHJlcGxhY2VzIGB3aW5kb3cuX19mcGpzX2RfbWAgd2l0aCBgdHJ1ZWBcbiAgICBpZiAod2luZG93Ll9fZnBqc19kX20gfHwgTWF0aC5yYW5kb20oKSA+PSAwLjAwMSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgIHJlcXVlc3Qub3BlbignZ2V0JywgXCJodHRwczovL20xLm9wZW5mcGNkbi5pby9maW5nZXJwcmludGpzL3ZcIiArIHZlcnNpb24gKyBcIi9ucG0tbW9uaXRvcmluZ1wiLCB0cnVlKTtcbiAgICAgICAgcmVxdWVzdC5zZW5kKCk7XG4gICAgfVxuICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBjb25zb2xlLmVycm9yIGlzIG9rIGhlcmUgYmVjYXVzZSBpdCdzIGFuIHVuZXhwZWN0ZWQgZXJyb3IgaGFuZGxlclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB9XG59XG4vKipcbiAqIEJ1aWxkcyBhbiBpbnN0YW5jZSBvZiBBZ2VudCBhbmQgd2FpdHMgYSBkZWxheSByZXF1aXJlZCBmb3IgYSBwcm9wZXIgb3BlcmF0aW9uLlxuICovXG5mdW5jdGlvbiBsb2FkKF9hKSB7XG4gICAgdmFyIF9iID0gX2EgPT09IHZvaWQgMCA/IHt9IDogX2EsIGRlbGF5RmFsbGJhY2sgPSBfYi5kZWxheUZhbGxiYWNrLCBkZWJ1ZyA9IF9iLmRlYnVnLCBfYyA9IF9iLm1vbml0b3JpbmcsIG1vbml0b3JpbmcgPSBfYyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9jO1xuICAgIHJldHVybiB0c2xpYi5fX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGdldENvbXBvbmVudHM7XG4gICAgICAgIHJldHVybiB0c2xpYi5fX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2QpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2QubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgIGlmIChtb25pdG9yaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb25pdG9yKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgcHJlcGFyZUZvclNvdXJjZXMoZGVsYXlGYWxsYmFjayldO1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgX2Quc2VudCgpO1xuICAgICAgICAgICAgICAgICAgICBnZXRDb21wb25lbnRzID0gbG9hZEJ1aWx0aW5Tb3VyY2VzKHsgZGVidWc6IGRlYnVnIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgbWFrZUFnZW50KGdldENvbXBvbmVudHMsIGRlYnVnKV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG4vLyBUaGUgZGVmYXVsdCBleHBvcnQgaXMgYSBzeW50YXggc3VnYXIgKGBpbXBvcnQgKiBhcyBGUCBmcm9tICcuLi4nIOKGkiBpbXBvcnQgRlAgZnJvbSAnLi4uJ2ApLlxuLy8gSXQgc2hvdWxkIGNvbnRhaW4gYWxsIHRoZSBwdWJsaWMgZXhwb3J0ZWQgdmFsdWVzLlxudmFyIGluZGV4ID0geyBsb2FkOiBsb2FkLCBoYXNoQ29tcG9uZW50czogaGFzaENvbXBvbmVudHMsIGNvbXBvbmVudHNUb0RlYnVnU3RyaW5nOiBjb21wb25lbnRzVG9EZWJ1Z1N0cmluZyB9O1xuLy8gVGhlIGV4cG9ydHMgYmVsb3cgYXJlIGZvciBwcml2YXRlIHVzYWdlLiBUaGV5IG1heSBjaGFuZ2UgdW5leHBlY3RlZGx5LiBVc2UgdGhlbSBhdCB5b3VyIG93biByaXNrLlxuLyoqIE5vdCBkb2N1bWVudGVkLCBvdXQgb2YgU2VtYW50aWMgVmVyc2lvbmluZywgdXNhZ2UgaXMgYXQgeW91ciBvd24gcmlzayAqL1xudmFyIG11cm11clg2NEhhc2gxMjggPSB4NjRoYXNoMTI4O1xuXG5leHBvcnRzLmNvbXBvbmVudHNUb0RlYnVnU3RyaW5nID0gY29tcG9uZW50c1RvRGVidWdTdHJpbmc7XG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IGluZGV4O1xuZXhwb3J0cy5nZXRGdWxsc2NyZWVuRWxlbWVudCA9IGdldEZ1bGxzY3JlZW5FbGVtZW50O1xuZXhwb3J0cy5nZXRTY3JlZW5GcmFtZSA9IGdldFNjcmVlbkZyYW1lO1xuZXhwb3J0cy5oYXNoQ29tcG9uZW50cyA9IGhhc2hDb21wb25lbnRzO1xuZXhwb3J0cy5pc0FuZHJvaWQgPSBpc0FuZHJvaWQ7XG5leHBvcnRzLmlzQ2hyb21pdW0gPSBpc0Nocm9taXVtO1xuZXhwb3J0cy5pc0Rlc2t0b3BTYWZhcmkgPSBpc0Rlc2t0b3BTYWZhcmk7XG5leHBvcnRzLmlzRWRnZUhUTUwgPSBpc0VkZ2VIVE1MO1xuZXhwb3J0cy5pc0dlY2tvID0gaXNHZWNrbztcbmV4cG9ydHMuaXNUcmlkZW50ID0gaXNUcmlkZW50O1xuZXhwb3J0cy5pc1dlYktpdCA9IGlzV2ViS2l0O1xuZXhwb3J0cy5sb2FkID0gbG9hZDtcbmV4cG9ydHMubG9hZFNvdXJjZXMgPSBsb2FkU291cmNlcztcbmV4cG9ydHMubXVybXVyWDY0SGFzaDEyOCA9IG11cm11clg2NEhhc2gxMjg7XG5leHBvcnRzLnByZXBhcmVGb3JTb3VyY2VzID0gcHJlcGFyZUZvclNvdXJjZXM7XG5leHBvcnRzLnNvdXJjZXMgPSBzb3VyY2VzO1xuZXhwb3J0cy50cmFuc2Zvcm1Tb3VyY2UgPSB0cmFuc2Zvcm1Tb3VyY2U7XG4iLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbi8vIFJvdWdoIHBvbHlmaWxsIG9mIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9BYm9ydENvbnRyb2xsZXJcclxuLy8gV2UgZG9uJ3QgYWN0dWFsbHkgZXZlciB1c2UgdGhlIEFQSSBiZWluZyBwb2x5ZmlsbGVkLCB3ZSBhbHdheXMgdXNlIHRoZSBwb2x5ZmlsbCBiZWNhdXNlXHJcbi8vIGl0J3MgYSB2ZXJ5IG5ldyBBUEkgcmlnaHQgbm93LlxyXG4vLyBOb3QgZXhwb3J0ZWQgZnJvbSBpbmRleC5cclxuLyoqIEBwcml2YXRlICovXHJcbnZhciBBYm9ydENvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBBYm9ydENvbnRyb2xsZXIoKSB7XHJcbiAgICAgICAgdGhpcy5pc0Fib3J0ZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLm9uYWJvcnQgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNBYm9ydGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNBYm9ydGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMub25hYm9ydCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbmFib3J0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFib3J0Q29udHJvbGxlci5wcm90b3R5cGUsIFwic2lnbmFsXCIsIHtcclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZSwgXCJhYm9ydGVkXCIsIHtcclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNBYm9ydGVkO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIEFib3J0Q29udHJvbGxlcjtcclxufSgpKTtcclxuZXhwb3J0cy5BYm9ydENvbnRyb2xsZXIgPSBBYm9ydENvbnRyb2xsZXI7XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFib3J0Q29udHJvbGxlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgRXJyb3JzXzEgPSByZXF1aXJlKFwiLi9FcnJvcnNcIik7XHJcbnZhciBGZXRjaEh0dHBDbGllbnRfMSA9IHJlcXVpcmUoXCIuL0ZldGNoSHR0cENsaWVudFwiKTtcclxudmFyIEh0dHBDbGllbnRfMSA9IHJlcXVpcmUoXCIuL0h0dHBDbGllbnRcIik7XHJcbnZhciBVdGlsc18xID0gcmVxdWlyZShcIi4vVXRpbHNcIik7XHJcbnZhciBYaHJIdHRwQ2xpZW50XzEgPSByZXF1aXJlKFwiLi9YaHJIdHRwQ2xpZW50XCIpO1xyXG4vKiogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgQG1pY3Jvc29mdC9zaWduYWxyLkh0dHBDbGllbnR9LiAqL1xyXG52YXIgRGVmYXVsdEh0dHBDbGllbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoRGVmYXVsdEh0dHBDbGllbnQsIF9zdXBlcik7XHJcbiAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUge0BsaW5rIEBtaWNyb3NvZnQvc2lnbmFsci5EZWZhdWx0SHR0cENsaWVudH0sIHVzaW5nIHRoZSBwcm92aWRlZCB7QGxpbmsgQG1pY3Jvc29mdC9zaWduYWxyLklMb2dnZXJ9IHRvIGxvZyBtZXNzYWdlcy4gKi9cclxuICAgIGZ1bmN0aW9uIERlZmF1bHRIdHRwQ2xpZW50KGxvZ2dlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBmZXRjaCAhPT0gXCJ1bmRlZmluZWRcIiB8fCBVdGlsc18xLlBsYXRmb3JtLmlzTm9kZSkge1xyXG4gICAgICAgICAgICBfdGhpcy5odHRwQ2xpZW50ID0gbmV3IEZldGNoSHR0cENsaWVudF8xLkZldGNoSHR0cENsaWVudChsb2dnZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgWE1MSHR0cFJlcXVlc3QgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgICAgICAgX3RoaXMuaHR0cENsaWVudCA9IG5ldyBYaHJIdHRwQ2xpZW50XzEuWGhySHR0cENsaWVudChsb2dnZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gdXNhYmxlIEh0dHBDbGllbnQgZm91bmQuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICAvKiogQGluaGVyaXREb2MgKi9cclxuICAgIERlZmF1bHRIdHRwQ2xpZW50LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcclxuICAgICAgICAvLyBDaGVjayB0aGF0IGFib3J0IHdhcyBub3Qgc2lnbmFsZWQgYmVmb3JlIGNhbGxpbmcgc2VuZFxyXG4gICAgICAgIGlmIChyZXF1ZXN0LmFib3J0U2lnbmFsICYmIHJlcXVlc3QuYWJvcnRTaWduYWwuYWJvcnRlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yc18xLkFib3J0RXJyb3IoKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghcmVxdWVzdC5tZXRob2QpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIG1ldGhvZCBkZWZpbmVkLlwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghcmVxdWVzdC51cmwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHVybCBkZWZpbmVkLlwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuc2VuZChyZXF1ZXN0KTtcclxuICAgIH07XHJcbiAgICBEZWZhdWx0SHR0cENsaWVudC5wcm90b3R5cGUuZ2V0Q29va2llU3RyaW5nID0gZnVuY3Rpb24gKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuZ2V0Q29va2llU3RyaW5nKHVybCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIERlZmF1bHRIdHRwQ2xpZW50O1xyXG59KEh0dHBDbGllbnRfMS5IdHRwQ2xpZW50KSk7XHJcbmV4cG9ydHMuRGVmYXVsdEh0dHBDbGllbnQgPSBEZWZhdWx0SHR0cENsaWVudDtcclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVmYXVsdEh0dHBDbGllbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vLyAwLCAyLCAxMCwgMzAgc2Vjb25kIGRlbGF5cyBiZWZvcmUgcmVjb25uZWN0IGF0dGVtcHRzLlxyXG52YXIgREVGQVVMVF9SRVRSWV9ERUxBWVNfSU5fTUlMTElTRUNPTkRTID0gWzAsIDIwMDAsIDEwMDAwLCAzMDAwMCwgbnVsbF07XHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG52YXIgRGVmYXVsdFJlY29ubmVjdFBvbGljeSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIERlZmF1bHRSZWNvbm5lY3RQb2xpY3kocmV0cnlEZWxheXMpIHtcclxuICAgICAgICB0aGlzLnJldHJ5RGVsYXlzID0gcmV0cnlEZWxheXMgIT09IHVuZGVmaW5lZCA/IHJldHJ5RGVsYXlzLmNvbmNhdChbbnVsbF0pIDogREVGQVVMVF9SRVRSWV9ERUxBWVNfSU5fTUlMTElTRUNPTkRTO1xyXG4gICAgfVxyXG4gICAgRGVmYXVsdFJlY29ubmVjdFBvbGljeS5wcm90b3R5cGUubmV4dFJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kcyA9IGZ1bmN0aW9uIChyZXRyeUNvbnRleHQpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXRyeURlbGF5c1tyZXRyeUNvbnRleHQucHJldmlvdXNSZXRyeUNvdW50XTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gRGVmYXVsdFJlY29ubmVjdFBvbGljeTtcclxufSgpKTtcclxuZXhwb3J0cy5EZWZhdWx0UmVjb25uZWN0UG9saWN5ID0gRGVmYXVsdFJlY29ubmVjdFBvbGljeTtcclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVmYXVsdFJlY29ubmVjdFBvbGljeS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vKiogRXJyb3IgdGhyb3duIHdoZW4gYW4gSFRUUCByZXF1ZXN0IGZhaWxzLiAqL1xyXG52YXIgSHR0cEVycm9yID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEh0dHBFcnJvciwgX3N1cGVyKTtcclxuICAgIC8qKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAbGluayBAbWljcm9zb2Z0L3NpZ25hbHIuSHR0cEVycm9yfS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3JNZXNzYWdlIEEgZGVzY3JpcHRpdmUgZXJyb3IgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGF0dXNDb2RlIFRoZSBIVFRQIHN0YXR1cyBjb2RlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZXJyb3IuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIEh0dHBFcnJvcihlcnJvck1lc3NhZ2UsIHN0YXR1c0NvZGUpIHtcclxuICAgICAgICB2YXIgX25ld1RhcmdldCA9IHRoaXMuY29uc3RydWN0b3I7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgdHJ1ZVByb3RvID0gX25ld1RhcmdldC5wcm90b3R5cGU7XHJcbiAgICAgICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBlcnJvck1lc3NhZ2UpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGU7XHJcbiAgICAgICAgLy8gV29ya2Fyb3VuZCBpc3N1ZSBpbiBUeXBlc2NyaXB0IGNvbXBpbGVyXHJcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL01pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8xMzk2NSNpc3N1ZWNvbW1lbnQtMjc4NTcwMjAwXHJcbiAgICAgICAgX3RoaXMuX19wcm90b19fID0gdHJ1ZVByb3RvO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIHJldHVybiBIdHRwRXJyb3I7XHJcbn0oRXJyb3IpKTtcclxuZXhwb3J0cy5IdHRwRXJyb3IgPSBIdHRwRXJyb3I7XHJcbi8qKiBFcnJvciB0aHJvd24gd2hlbiBhIHRpbWVvdXQgZWxhcHNlcy4gKi9cclxudmFyIFRpbWVvdXRFcnJvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhUaW1lb3V0RXJyb3IsIF9zdXBlcik7XHJcbiAgICAvKiogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGxpbmsgQG1pY3Jvc29mdC9zaWduYWxyLlRpbWVvdXRFcnJvcn0uXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVycm9yTWVzc2FnZSBBIGRlc2NyaXB0aXZlIGVycm9yIG1lc3NhZ2UuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIFRpbWVvdXRFcnJvcihlcnJvck1lc3NhZ2UpIHtcclxuICAgICAgICB2YXIgX25ld1RhcmdldCA9IHRoaXMuY29uc3RydWN0b3I7XHJcbiAgICAgICAgaWYgKGVycm9yTWVzc2FnZSA9PT0gdm9pZCAwKSB7IGVycm9yTWVzc2FnZSA9IFwiQSB0aW1lb3V0IG9jY3VycmVkLlwiOyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgdHJ1ZVByb3RvID0gX25ld1RhcmdldC5wcm90b3R5cGU7XHJcbiAgICAgICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBlcnJvck1lc3NhZ2UpIHx8IHRoaXM7XHJcbiAgICAgICAgLy8gV29ya2Fyb3VuZCBpc3N1ZSBpbiBUeXBlc2NyaXB0IGNvbXBpbGVyXHJcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL01pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8xMzk2NSNpc3N1ZWNvbW1lbnQtMjc4NTcwMjAwXHJcbiAgICAgICAgX3RoaXMuX19wcm90b19fID0gdHJ1ZVByb3RvO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIHJldHVybiBUaW1lb3V0RXJyb3I7XHJcbn0oRXJyb3IpKTtcclxuZXhwb3J0cy5UaW1lb3V0RXJyb3IgPSBUaW1lb3V0RXJyb3I7XHJcbi8qKiBFcnJvciB0aHJvd24gd2hlbiBhbiBhY3Rpb24gaXMgYWJvcnRlZC4gKi9cclxudmFyIEFib3J0RXJyb3IgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoQWJvcnRFcnJvciwgX3N1cGVyKTtcclxuICAgIC8qKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAbGluayBBYm9ydEVycm9yfS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3JNZXNzYWdlIEEgZGVzY3JpcHRpdmUgZXJyb3IgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gQWJvcnRFcnJvcihlcnJvck1lc3NhZ2UpIHtcclxuICAgICAgICB2YXIgX25ld1RhcmdldCA9IHRoaXMuY29uc3RydWN0b3I7XHJcbiAgICAgICAgaWYgKGVycm9yTWVzc2FnZSA9PT0gdm9pZCAwKSB7IGVycm9yTWVzc2FnZSA9IFwiQW4gYWJvcnQgb2NjdXJyZWQuXCI7IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciB0cnVlUHJvdG8gPSBfbmV3VGFyZ2V0LnByb3RvdHlwZTtcclxuICAgICAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGVycm9yTWVzc2FnZSkgfHwgdGhpcztcclxuICAgICAgICAvLyBXb3JrYXJvdW5kIGlzc3VlIGluIFR5cGVzY3JpcHQgY29tcGlsZXJcclxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vTWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzEzOTY1I2lzc3VlY29tbWVudC0yNzg1NzAyMDBcclxuICAgICAgICBfdGhpcy5fX3Byb3RvX18gPSB0cnVlUHJvdG87XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIEFib3J0RXJyb3I7XHJcbn0oRXJyb3IpKTtcclxuZXhwb3J0cy5BYm9ydEVycm9yID0gQWJvcnRFcnJvcjtcclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RXJyb3JzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIC5ORVQgRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG52YXIgX19hc3NpZ24gPSAodGhpcyAmJiB0aGlzLl9fYXNzaWduKSB8fCBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uKHQpIHtcclxuICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKVxyXG4gICAgICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59O1xyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG52YXIgX19nZW5lcmF0b3IgPSAodGhpcyAmJiB0aGlzLl9fZ2VuZXJhdG9yKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIEVycm9yc18xID0gcmVxdWlyZShcIi4vRXJyb3JzXCIpO1xyXG52YXIgSHR0cENsaWVudF8xID0gcmVxdWlyZShcIi4vSHR0cENsaWVudFwiKTtcclxudmFyIElMb2dnZXJfMSA9IHJlcXVpcmUoXCIuL0lMb2dnZXJcIik7XHJcbnZhciBVdGlsc18xID0gcmVxdWlyZShcIi4vVXRpbHNcIik7XHJcbnZhciBGZXRjaEh0dHBDbGllbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoRmV0Y2hIdHRwQ2xpZW50LCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gRmV0Y2hIdHRwQ2xpZW50KGxvZ2dlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMubG9nZ2VyID0gbG9nZ2VyO1xyXG4gICAgICAgIGlmICh0eXBlb2YgZmV0Y2ggPT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgICAgICAgLy8gSW4gb3JkZXIgdG8gaWdub3JlIHRoZSBkeW5hbWljIHJlcXVpcmUgaW4gd2VicGFjayBidWlsZHMgd2UgbmVlZCB0byBkbyB0aGlzIG1hZ2ljXHJcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmU6IFRTIGRvZXNuJ3Qga25vdyBhYm91dCB0aGVzZSBuYW1lc1xyXG4gICAgICAgICAgICB2YXIgcmVxdWlyZUZ1bmMgPSB0eXBlb2YgX193ZWJwYWNrX3JlcXVpcmVfXyA9PT0gXCJmdW5jdGlvblwiID8gX19ub25fd2VicGFja19yZXF1aXJlX18gOiByZXF1aXJlO1xyXG4gICAgICAgICAgICAvLyBDb29raWVzIGFyZW4ndCBhdXRvbWF0aWNhbGx5IGhhbmRsZWQgaW4gTm9kZSBzbyB3ZSBuZWVkIHRvIGFkZCBhIENvb2tpZUphciB0byBwcmVzZXJ2ZSBjb29raWVzIGFjcm9zcyByZXF1ZXN0c1xyXG4gICAgICAgICAgICBfdGhpcy5qYXIgPSBuZXcgKHJlcXVpcmVGdW5jKFwidG91Z2gtY29va2llXCIpKS5Db29raWVKYXIoKTtcclxuICAgICAgICAgICAgX3RoaXMuZmV0Y2hUeXBlID0gcmVxdWlyZUZ1bmMoXCJub2RlLWZldGNoXCIpO1xyXG4gICAgICAgICAgICAvLyBub2RlLWZldGNoIGRvZXNuJ3QgaGF2ZSBhIG5pY2UgQVBJIGZvciBnZXR0aW5nIGFuZCBzZXR0aW5nIGNvb2tpZXNcclxuICAgICAgICAgICAgLy8gZmV0Y2gtY29va2llIHdpbGwgd3JhcCBhIGZldGNoIGltcGxlbWVudGF0aW9uIHdpdGggYSBkZWZhdWx0IENvb2tpZUphciBvciBhIHByb3ZpZGVkIG9uZVxyXG4gICAgICAgICAgICBfdGhpcy5mZXRjaFR5cGUgPSByZXF1aXJlRnVuYyhcImZldGNoLWNvb2tpZVwiKShfdGhpcy5mZXRjaFR5cGUsIF90aGlzLmphcik7XHJcbiAgICAgICAgICAgIC8vIE5vZGUgbmVlZHMgRXZlbnRMaXN0ZW5lciBtZXRob2RzIG9uIEFib3J0Q29udHJvbGxlciB3aGljaCBvdXIgY3VzdG9tIHBvbHlmaWxsIGRvZXNuJ3QgcHJvdmlkZVxyXG4gICAgICAgICAgICBfdGhpcy5hYm9ydENvbnRyb2xsZXJUeXBlID0gcmVxdWlyZUZ1bmMoXCJhYm9ydC1jb250cm9sbGVyXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgX3RoaXMuZmV0Y2hUeXBlID0gZmV0Y2guYmluZChzZWxmKTtcclxuICAgICAgICAgICAgX3RoaXMuYWJvcnRDb250cm9sbGVyVHlwZSA9IEFib3J0Q29udHJvbGxlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgLyoqIEBpbmhlcml0RG9jICovXHJcbiAgICBGZXRjaEh0dHBDbGllbnQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGFib3J0Q29udHJvbGxlciwgZXJyb3IsIHRpbWVvdXRJZCwgbXNUaW1lb3V0LCByZXNwb25zZSwgZV8xLCBjb250ZW50LCBwYXlsb2FkO1xyXG4gICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9hKSB7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGF0IGFib3J0IHdhcyBub3Qgc2lnbmFsZWQgYmVmb3JlIGNhbGxpbmcgc2VuZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVxdWVzdC5hYm9ydFNpZ25hbCAmJiByZXF1ZXN0LmFib3J0U2lnbmFsLmFib3J0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcnNfMS5BYm9ydEVycm9yKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXF1ZXN0Lm1ldGhvZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWV0aG9kIGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVxdWVzdC51cmwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHVybCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhYm9ydENvbnRyb2xsZXIgPSBuZXcgdGhpcy5hYm9ydENvbnRyb2xsZXJUeXBlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhvb2sgb3VyIGFib3J0U2lnbmFsIGludG8gdGhlIGFib3J0IGNvbnRyb2xsZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXVlc3QuYWJvcnRTaWduYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QuYWJvcnRTaWduYWwub25hYm9ydCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcnNfMS5BYm9ydEVycm9yKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVvdXRJZCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LnRpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zVGltZW91dCA9IHJlcXVlc3QudGltZW91dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0Q29udHJvbGxlci5hYm9ydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLldhcm5pbmcsIFwiVGltZW91dCBmcm9tIEhUVFAgcmVxdWVzdC5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3JzXzEuVGltZW91dEVycm9yKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBtc1RpbWVvdXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnRyeXMucHVzaChbMSwgMywgNCwgNV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLmZldGNoVHlwZShyZXF1ZXN0LnVybCwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk6IHJlcXVlc3QuY29udGVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZTogXCJuby1jYWNoZVwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWRlbnRpYWxzOiByZXF1ZXN0LndpdGhDcmVkZW50aWFscyA9PT0gdHJ1ZSA/IFwiaW5jbHVkZVwiIDogXCJzYW1lLW9yaWdpblwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IF9fYXNzaWduKHsgXCJDb250ZW50LVR5cGVcIjogXCJ0ZXh0L3BsYWluO2NoYXJzZXQ9VVRGLThcIiwgXCJYLVJlcXVlc3RlZC1XaXRoXCI6IFwiWE1MSHR0cFJlcXVlc3RcIiB9LCByZXF1ZXN0LmhlYWRlcnMpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZTogXCJjb3JzXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3Q6IFwibWFudWFsXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbmFsOiBhYm9ydENvbnRyb2xsZXIuc2lnbmFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDVdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZV8xID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuV2FybmluZywgXCJFcnJvciBmcm9tIEhUVFAgcmVxdWVzdC4gXCIgKyBlXzEgKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVfMTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aW1lb3V0SWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LmFib3J0U2lnbmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LmFib3J0U2lnbmFsLm9uYWJvcnQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNyAvKmVuZGZpbmFsbHkqL107XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3JzXzEuSHR0cEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQsIHJlc3BvbnNlLnN0YXR1cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGRlc2VyaWFsaXplQ29udGVudChyZXNwb25zZSwgcmVxdWVzdC5yZXNwb25zZVR5cGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCBjb250ZW50XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDY6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQgPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCBuZXcgSHR0cENsaWVudF8xLkh0dHBSZXNwb25zZShyZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLnN0YXR1c1RleHQsIHBheWxvYWQpXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgRmV0Y2hIdHRwQ2xpZW50LnByb3RvdHlwZS5nZXRDb29raWVTdHJpbmcgPSBmdW5jdGlvbiAodXJsKSB7XHJcbiAgICAgICAgdmFyIGNvb2tpZXMgPSBcIlwiO1xyXG4gICAgICAgIGlmIChVdGlsc18xLlBsYXRmb3JtLmlzTm9kZSAmJiB0aGlzLmphcikge1xyXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlOiB1bnVzZWQgdmFyaWFibGVcclxuICAgICAgICAgICAgdGhpcy5qYXIuZ2V0Q29va2llcyh1cmwsIGZ1bmN0aW9uIChlLCBjKSB7IHJldHVybiBjb29raWVzID0gYy5qb2luKFwiOyBcIik7IH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29va2llcztcclxuICAgIH07XHJcbiAgICByZXR1cm4gRmV0Y2hIdHRwQ2xpZW50O1xyXG59KEh0dHBDbGllbnRfMS5IdHRwQ2xpZW50KSk7XHJcbmV4cG9ydHMuRmV0Y2hIdHRwQ2xpZW50ID0gRmV0Y2hIdHRwQ2xpZW50O1xyXG5mdW5jdGlvbiBkZXNlcmlhbGl6ZUNvbnRlbnQocmVzcG9uc2UsIHJlc3BvbnNlVHlwZSkge1xyXG4gICAgdmFyIGNvbnRlbnQ7XHJcbiAgICBzd2l0Y2ggKHJlc3BvbnNlVHlwZSkge1xyXG4gICAgICAgIGNhc2UgXCJhcnJheWJ1ZmZlclwiOlxyXG4gICAgICAgICAgICBjb250ZW50ID0gcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcInRleHRcIjpcclxuICAgICAgICAgICAgY29udGVudCA9IHJlc3BvbnNlLnRleHQoKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcImJsb2JcIjpcclxuICAgICAgICBjYXNlIFwiZG9jdW1lbnRcIjpcclxuICAgICAgICBjYXNlIFwianNvblwiOlxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVzcG9uc2VUeXBlICsgXCIgaXMgbm90IHN1cHBvcnRlZC5cIik7XHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgY29udGVudCA9IHJlc3BvbnNlLnRleHQoKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29udGVudDtcclxufVxyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZXRjaEh0dHBDbGllbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgVGV4dE1lc3NhZ2VGb3JtYXRfMSA9IHJlcXVpcmUoXCIuL1RleHRNZXNzYWdlRm9ybWF0XCIpO1xyXG52YXIgVXRpbHNfMSA9IHJlcXVpcmUoXCIuL1V0aWxzXCIpO1xyXG4vKiogQHByaXZhdGUgKi9cclxudmFyIEhhbmRzaGFrZVByb3RvY29sID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gSGFuZHNoYWtlUHJvdG9jb2woKSB7XHJcbiAgICB9XHJcbiAgICAvLyBIYW5kc2hha2UgcmVxdWVzdCBpcyBhbHdheXMgSlNPTlxyXG4gICAgSGFuZHNoYWtlUHJvdG9jb2wucHJvdG90eXBlLndyaXRlSGFuZHNoYWtlUmVxdWVzdCA9IGZ1bmN0aW9uIChoYW5kc2hha2VSZXF1ZXN0KSB7XHJcbiAgICAgICAgcmV0dXJuIFRleHRNZXNzYWdlRm9ybWF0XzEuVGV4dE1lc3NhZ2VGb3JtYXQud3JpdGUoSlNPTi5zdHJpbmdpZnkoaGFuZHNoYWtlUmVxdWVzdCkpO1xyXG4gICAgfTtcclxuICAgIEhhbmRzaGFrZVByb3RvY29sLnByb3RvdHlwZS5wYXJzZUhhbmRzaGFrZVJlc3BvbnNlID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICB2YXIgcmVzcG9uc2VNZXNzYWdlO1xyXG4gICAgICAgIHZhciBtZXNzYWdlRGF0YTtcclxuICAgICAgICB2YXIgcmVtYWluaW5nRGF0YTtcclxuICAgICAgICBpZiAoVXRpbHNfMS5pc0FycmF5QnVmZmVyKGRhdGEpIHx8ICh0eXBlb2YgQnVmZmVyICE9PSBcInVuZGVmaW5lZFwiICYmIGRhdGEgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XHJcbiAgICAgICAgICAgIC8vIEZvcm1hdCBpcyBiaW5hcnkgYnV0IHN0aWxsIG5lZWQgdG8gcmVhZCBKU09OIHRleHQgZnJvbSBoYW5kc2hha2UgcmVzcG9uc2VcclxuICAgICAgICAgICAgdmFyIGJpbmFyeURhdGEgPSBuZXcgVWludDhBcnJheShkYXRhKTtcclxuICAgICAgICAgICAgdmFyIHNlcGFyYXRvckluZGV4ID0gYmluYXJ5RGF0YS5pbmRleE9mKFRleHRNZXNzYWdlRm9ybWF0XzEuVGV4dE1lc3NhZ2VGb3JtYXQuUmVjb3JkU2VwYXJhdG9yQ29kZSk7XHJcbiAgICAgICAgICAgIGlmIChzZXBhcmF0b3JJbmRleCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1lc3NhZ2UgaXMgaW5jb21wbGV0ZS5cIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gY29udGVudCBiZWZvcmUgc2VwYXJhdG9yIGlzIGhhbmRzaGFrZSByZXNwb25zZVxyXG4gICAgICAgICAgICAvLyBvcHRpb25hbCBjb250ZW50IGFmdGVyIGlzIGFkZGl0aW9uYWwgbWVzc2FnZXNcclxuICAgICAgICAgICAgdmFyIHJlc3BvbnNlTGVuZ3RoID0gc2VwYXJhdG9ySW5kZXggKyAxO1xyXG4gICAgICAgICAgICBtZXNzYWdlRGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYmluYXJ5RGF0YS5zbGljZSgwLCByZXNwb25zZUxlbmd0aCkpO1xyXG4gICAgICAgICAgICByZW1haW5pbmdEYXRhID0gKGJpbmFyeURhdGEuYnl0ZUxlbmd0aCA+IHJlc3BvbnNlTGVuZ3RoKSA/IGJpbmFyeURhdGEuc2xpY2UocmVzcG9uc2VMZW5ndGgpLmJ1ZmZlciA6IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgdGV4dERhdGEgPSBkYXRhO1xyXG4gICAgICAgICAgICB2YXIgc2VwYXJhdG9ySW5kZXggPSB0ZXh0RGF0YS5pbmRleE9mKFRleHRNZXNzYWdlRm9ybWF0XzEuVGV4dE1lc3NhZ2VGb3JtYXQuUmVjb3JkU2VwYXJhdG9yKTtcclxuICAgICAgICAgICAgaWYgKHNlcGFyYXRvckluZGV4ID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWVzc2FnZSBpcyBpbmNvbXBsZXRlLlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBjb250ZW50IGJlZm9yZSBzZXBhcmF0b3IgaXMgaGFuZHNoYWtlIHJlc3BvbnNlXHJcbiAgICAgICAgICAgIC8vIG9wdGlvbmFsIGNvbnRlbnQgYWZ0ZXIgaXMgYWRkaXRpb25hbCBtZXNzYWdlc1xyXG4gICAgICAgICAgICB2YXIgcmVzcG9uc2VMZW5ndGggPSBzZXBhcmF0b3JJbmRleCArIDE7XHJcbiAgICAgICAgICAgIG1lc3NhZ2VEYXRhID0gdGV4dERhdGEuc3Vic3RyaW5nKDAsIHJlc3BvbnNlTGVuZ3RoKTtcclxuICAgICAgICAgICAgcmVtYWluaW5nRGF0YSA9ICh0ZXh0RGF0YS5sZW5ndGggPiByZXNwb25zZUxlbmd0aCkgPyB0ZXh0RGF0YS5zdWJzdHJpbmcocmVzcG9uc2VMZW5ndGgpIDogbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCB3ZSBzaG91bGQgaGF2ZSBqdXN0IHRoZSBzaW5nbGUgaGFuZHNoYWtlIG1lc3NhZ2VcclxuICAgICAgICB2YXIgbWVzc2FnZXMgPSBUZXh0TWVzc2FnZUZvcm1hdF8xLlRleHRNZXNzYWdlRm9ybWF0LnBhcnNlKG1lc3NhZ2VEYXRhKTtcclxuICAgICAgICB2YXIgcmVzcG9uc2UgPSBKU09OLnBhcnNlKG1lc3NhZ2VzWzBdKTtcclxuICAgICAgICBpZiAocmVzcG9uc2UudHlwZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBhIGhhbmRzaGFrZSByZXNwb25zZSBmcm9tIHRoZSBzZXJ2ZXIuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXNwb25zZU1lc3NhZ2UgPSByZXNwb25zZTtcclxuICAgICAgICAvLyBtdWx0aXBsZSBtZXNzYWdlcyBjb3VsZCBoYXZlIGFycml2ZWQgd2l0aCBoYW5kc2hha2VcclxuICAgICAgICAvLyByZXR1cm4gYWRkaXRpb25hbCBkYXRhIHRvIGJlIHBhcnNlZCBhcyB1c3VhbCwgb3IgbnVsbCBpZiBhbGwgcGFyc2VkXHJcbiAgICAgICAgcmV0dXJuIFtyZW1haW5pbmdEYXRhLCByZXNwb25zZU1lc3NhZ2VdO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBIYW5kc2hha2VQcm90b2NvbDtcclxufSgpKTtcclxuZXhwb3J0cy5IYW5kc2hha2VQcm90b2NvbCA9IEhhbmRzaGFrZVByb3RvY29sO1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1IYW5kc2hha2VQcm90b2NvbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hc3NpZ24gPSAodGhpcyAmJiB0aGlzLl9fYXNzaWduKSB8fCBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uKHQpIHtcclxuICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKVxyXG4gICAgICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbi8qKiBSZXByZXNlbnRzIGFuIEhUVFAgcmVzcG9uc2UuICovXHJcbnZhciBIdHRwUmVzcG9uc2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBIdHRwUmVzcG9uc2Uoc3RhdHVzQ29kZSwgc3RhdHVzVGV4dCwgY29udGVudCkge1xyXG4gICAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGU7XHJcbiAgICAgICAgdGhpcy5zdGF0dXNUZXh0ID0gc3RhdHVzVGV4dDtcclxuICAgICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIEh0dHBSZXNwb25zZTtcclxufSgpKTtcclxuZXhwb3J0cy5IdHRwUmVzcG9uc2UgPSBIdHRwUmVzcG9uc2U7XHJcbi8qKiBBYnN0cmFjdGlvbiBvdmVyIGFuIEhUVFAgY2xpZW50LlxyXG4gKlxyXG4gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFuIGFic3RyYWN0aW9uIG92ZXIgYW4gSFRUUCBjbGllbnQgc28gdGhhdCBhIGRpZmZlcmVudCBpbXBsZW1lbnRhdGlvbiBjYW4gYmUgcHJvdmlkZWQgb24gZGlmZmVyZW50IHBsYXRmb3Jtcy5cclxuICovXHJcbnZhciBIdHRwQ2xpZW50ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gSHR0cENsaWVudCgpIHtcclxuICAgIH1cclxuICAgIEh0dHBDbGllbnQucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZW5kKF9fYXNzaWduKHt9LCBvcHRpb25zLCB7IG1ldGhvZDogXCJHRVRcIiwgdXJsOiB1cmwgfSkpO1xyXG4gICAgfTtcclxuICAgIEh0dHBDbGllbnQucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZChfX2Fzc2lnbih7fSwgb3B0aW9ucywgeyBtZXRob2Q6IFwiUE9TVFwiLCB1cmw6IHVybCB9KSk7XHJcbiAgICB9O1xyXG4gICAgSHR0cENsaWVudC5wcm90b3R5cGUuZGVsZXRlID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNlbmQoX19hc3NpZ24oe30sIG9wdGlvbnMsIHsgbWV0aG9kOiBcIkRFTEVURVwiLCB1cmw6IHVybCB9KSk7XHJcbiAgICB9O1xyXG4gICAgLyoqIEdldHMgYWxsIGNvb2tpZXMgdGhhdCBhcHBseSB0byB0aGUgc3BlY2lmaWVkIFVSTC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gdXJsIFRoZSBVUkwgdGhhdCB0aGUgY29va2llcyBhcmUgdmFsaWQgZm9yLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQSBzdHJpbmcgY29udGFpbmluZyBhbGwgdGhlIGtleS12YWx1ZSBjb29raWUgcGFpcnMgZm9yIHRoZSBzcGVjaWZpZWQgVVJMLlxyXG4gICAgICovXHJcbiAgICAvLyBAdHMtaWdub3JlXHJcbiAgICBIdHRwQ2xpZW50LnByb3RvdHlwZS5nZXRDb29raWVTdHJpbmcgPSBmdW5jdGlvbiAodXJsKSB7XHJcbiAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEh0dHBDbGllbnQ7XHJcbn0oKSk7XHJcbmV4cG9ydHMuSHR0cENsaWVudCA9IEh0dHBDbGllbnQ7XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUh0dHBDbGllbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxudmFyIF9fYXNzaWduID0gKHRoaXMgJiYgdGhpcy5fX2Fzc2lnbikgfHwgT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbih0KSB7XHJcbiAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSlcclxuICAgICAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufTtcclxudmFyIF9fYXdhaXRlciA9ICh0aGlzICYmIHRoaXMuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufTtcclxudmFyIF9fZ2VuZXJhdG9yID0gKHRoaXMgJiYgdGhpcy5fX2dlbmVyYXRvcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBEZWZhdWx0SHR0cENsaWVudF8xID0gcmVxdWlyZShcIi4vRGVmYXVsdEh0dHBDbGllbnRcIik7XHJcbnZhciBJTG9nZ2VyXzEgPSByZXF1aXJlKFwiLi9JTG9nZ2VyXCIpO1xyXG52YXIgSVRyYW5zcG9ydF8xID0gcmVxdWlyZShcIi4vSVRyYW5zcG9ydFwiKTtcclxudmFyIExvbmdQb2xsaW5nVHJhbnNwb3J0XzEgPSByZXF1aXJlKFwiLi9Mb25nUG9sbGluZ1RyYW5zcG9ydFwiKTtcclxudmFyIFNlcnZlclNlbnRFdmVudHNUcmFuc3BvcnRfMSA9IHJlcXVpcmUoXCIuL1NlcnZlclNlbnRFdmVudHNUcmFuc3BvcnRcIik7XHJcbnZhciBVdGlsc18xID0gcmVxdWlyZShcIi4vVXRpbHNcIik7XHJcbnZhciBXZWJTb2NrZXRUcmFuc3BvcnRfMSA9IHJlcXVpcmUoXCIuL1dlYlNvY2tldFRyYW5zcG9ydFwiKTtcclxudmFyIE1BWF9SRURJUkVDVFMgPSAxMDA7XHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG52YXIgSHR0cENvbm5lY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBIdHRwQ29ubmVjdGlvbih1cmwsIG9wdGlvbnMpIHtcclxuICAgICAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7IG9wdGlvbnMgPSB7fTsgfVxyXG4gICAgICAgIHRoaXMuZmVhdHVyZXMgPSB7fTtcclxuICAgICAgICB0aGlzLm5lZ290aWF0ZVZlcnNpb24gPSAxO1xyXG4gICAgICAgIFV0aWxzXzEuQXJnLmlzUmVxdWlyZWQodXJsLCBcInVybFwiKTtcclxuICAgICAgICB0aGlzLmxvZ2dlciA9IFV0aWxzXzEuY3JlYXRlTG9nZ2VyKG9wdGlvbnMubG9nZ2VyKTtcclxuICAgICAgICB0aGlzLmJhc2VVcmwgPSB0aGlzLnJlc29sdmVVcmwodXJsKTtcclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICBvcHRpb25zLmxvZ01lc3NhZ2VDb250ZW50ID0gb3B0aW9ucy5sb2dNZXNzYWdlQ29udGVudCA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBvcHRpb25zLmxvZ01lc3NhZ2VDb250ZW50O1xyXG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53aXRoQ3JlZGVudGlhbHMgPT09IFwiYm9vbGVhblwiIHx8IG9wdGlvbnMud2l0aENyZWRlbnRpYWxzID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgb3B0aW9ucy53aXRoQ3JlZGVudGlhbHMgPSBvcHRpb25zLndpdGhDcmVkZW50aWFscyA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IG9wdGlvbnMud2l0aENyZWRlbnRpYWxzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwid2l0aENyZWRlbnRpYWxzIG9wdGlvbiB3YXMgbm90IGEgJ2Jvb2xlYW4nIG9yICd1bmRlZmluZWQnIHZhbHVlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgd2ViU29ja2V0TW9kdWxlID0gbnVsbDtcclxuICAgICAgICB2YXIgZXZlbnRTb3VyY2VNb2R1bGUgPSBudWxsO1xyXG4gICAgICAgIGlmIChVdGlsc18xLlBsYXRmb3JtLmlzTm9kZSAmJiB0eXBlb2YgcmVxdWlyZSAhPT0gXCJ1bmRlZmluZWRcIikge1xyXG4gICAgICAgICAgICAvLyBJbiBvcmRlciB0byBpZ25vcmUgdGhlIGR5bmFtaWMgcmVxdWlyZSBpbiB3ZWJwYWNrIGJ1aWxkcyB3ZSBuZWVkIHRvIGRvIHRoaXMgbWFnaWNcclxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogVFMgZG9lc24ndCBrbm93IGFib3V0IHRoZXNlIG5hbWVzXHJcbiAgICAgICAgICAgIHZhciByZXF1aXJlRnVuYyA9IHR5cGVvZiBfX3dlYnBhY2tfcmVxdWlyZV9fID09PSBcImZ1bmN0aW9uXCIgPyBfX25vbl93ZWJwYWNrX3JlcXVpcmVfXyA6IHJlcXVpcmU7XHJcbiAgICAgICAgICAgIHdlYlNvY2tldE1vZHVsZSA9IHJlcXVpcmVGdW5jKFwid3NcIik7XHJcbiAgICAgICAgICAgIGV2ZW50U291cmNlTW9kdWxlID0gcmVxdWlyZUZ1bmMoXCJldmVudHNvdXJjZVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFVdGlsc18xLlBsYXRmb3JtLmlzTm9kZSAmJiB0eXBlb2YgV2ViU29ja2V0ICE9PSBcInVuZGVmaW5lZFwiICYmICFvcHRpb25zLldlYlNvY2tldCkge1xyXG4gICAgICAgICAgICBvcHRpb25zLldlYlNvY2tldCA9IFdlYlNvY2tldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoVXRpbHNfMS5QbGF0Zm9ybS5pc05vZGUgJiYgIW9wdGlvbnMuV2ViU29ja2V0KSB7XHJcbiAgICAgICAgICAgIGlmICh3ZWJTb2NrZXRNb2R1bGUpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMuV2ViU29ja2V0ID0gd2ViU29ja2V0TW9kdWxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghVXRpbHNfMS5QbGF0Zm9ybS5pc05vZGUgJiYgdHlwZW9mIEV2ZW50U291cmNlICE9PSBcInVuZGVmaW5lZFwiICYmICFvcHRpb25zLkV2ZW50U291cmNlKSB7XHJcbiAgICAgICAgICAgIG9wdGlvbnMuRXZlbnRTb3VyY2UgPSBFdmVudFNvdXJjZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoVXRpbHNfMS5QbGF0Zm9ybS5pc05vZGUgJiYgIW9wdGlvbnMuRXZlbnRTb3VyY2UpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBldmVudFNvdXJjZU1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIikge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5FdmVudFNvdXJjZSA9IGV2ZW50U291cmNlTW9kdWxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuaHR0cENsaWVudCA9IG9wdGlvbnMuaHR0cENsaWVudCB8fCBuZXcgRGVmYXVsdEh0dHBDbGllbnRfMS5EZWZhdWx0SHR0cENsaWVudCh0aGlzLmxvZ2dlcik7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUgPSBcIkRpc2Nvbm5lY3RlZFwiIC8qIERpc2Nvbm5lY3RlZCAqLztcclxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGFydGVkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcclxuICAgICAgICB0aGlzLm9ucmVjZWl2ZSA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5vbmNsb3NlID0gbnVsbDtcclxuICAgIH1cclxuICAgIEh0dHBDb25uZWN0aW9uLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICh0cmFuc2ZlckZvcm1hdCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIG1lc3NhZ2UsIG1lc3NhZ2U7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZmVyRm9ybWF0ID0gdHJhbnNmZXJGb3JtYXQgfHwgSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0LkJpbmFyeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgVXRpbHNfMS5BcmcuaXNJbih0cmFuc2ZlckZvcm1hdCwgSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0LCBcInRyYW5zZmVyRm9ybWF0XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIlN0YXJ0aW5nIGNvbm5lY3Rpb24gd2l0aCB0cmFuc2ZlciBmb3JtYXQgJ1wiICsgSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0W3RyYW5zZmVyRm9ybWF0XSArIFwiJy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZSAhPT0gXCJEaXNjb25uZWN0ZWRcIiAvKiBEaXNjb25uZWN0ZWQgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJDYW5ub3Qgc3RhcnQgYW4gSHR0cENvbm5lY3Rpb24gdGhhdCBpcyBub3QgaW4gdGhlICdEaXNjb25uZWN0ZWQnIHN0YXRlLlwiKSldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlID0gXCJDb25uZWN0aW5nXCIgLyogQ29ubmVjdGluZyAqLztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydEludGVybmFsUHJvbWlzZSA9IHRoaXMuc3RhcnRJbnRlcm5hbCh0cmFuc2ZlckZvcm1hdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuc3RhcnRJbnRlcm5hbFByb21pc2VdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISh0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9PT0gXCJEaXNjb25uZWN0aW5nXCIgLyogRGlzY29ubmVjdGluZyAqLykpIHJldHVybiBbMyAvKmJyZWFrKi8sIDNdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gXCJGYWlsZWQgdG8gc3RhcnQgdGhlIEh0dHBDb25uZWN0aW9uIGJlZm9yZSBzdG9wKCkgd2FzIGNhbGxlZC5cIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGNhbm5vdCBhd2FpdCBzdG9wUHJvbWlzZSBpbnNpZGUgc3RhcnRJbnRlcm5hbCBzaW5jZSBzdG9wSW50ZXJuYWwgYXdhaXRzIHRoZSBzdGFydEludGVybmFsUHJvbWlzZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5zdG9wUHJvbWlzZV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBjYW5ub3QgYXdhaXQgc3RvcFByb21pc2UgaW5zaWRlIHN0YXJ0SW50ZXJuYWwgc2luY2Ugc3RvcEludGVybmFsIGF3YWl0cyB0aGUgc3RhcnRJbnRlcm5hbFByb21pc2UuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihtZXNzYWdlKSldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlICE9PSBcIkNvbm5lY3RlZFwiIC8qIENvbm5lY3RlZCAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IFwiSHR0cENvbm5lY3Rpb24uc3RhcnRJbnRlcm5hbCBjb21wbGV0ZWQgZ3JhY2VmdWxseSBidXQgZGlkbid0IGVudGVyIHRoZSBjb25uZWN0aW9uIGludG8gdGhlIGNvbm5lY3RlZCBzdGF0ZSFcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihtZXNzYWdlKSldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gNDtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXJ0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIEh0dHBDb25uZWN0aW9uLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgIT09IFwiQ29ubmVjdGVkXCIgLyogQ29ubmVjdGVkICovKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJDYW5ub3Qgc2VuZCBkYXRhIGlmIHRoZSBjb25uZWN0aW9uIGlzIG5vdCBpbiB0aGUgJ0Nvbm5lY3RlZCcgU3RhdGUuXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlbmRRdWV1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRRdWV1ZSA9IG5ldyBUcmFuc3BvcnRTZW5kUXVldWUodGhpcy50cmFuc3BvcnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBUcmFuc3BvcnQgd2lsbCBub3QgYmUgbnVsbCBpZiBzdGF0ZSBpcyBjb25uZWN0ZWRcclxuICAgICAgICByZXR1cm4gdGhpcy5zZW5kUXVldWUuc2VuZChkYXRhKTtcclxuICAgIH07XHJcbiAgICBIdHRwQ29ubmVjdGlvbi5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uIChlcnJvcikge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAgICAgcmV0dXJuIF9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYS5sYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlID09PSBcIkRpc2Nvbm5lY3RlZFwiIC8qIERpc2Nvbm5lY3RlZCAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJDYWxsIHRvIEh0dHBDb25uZWN0aW9uLnN0b3AoXCIgKyBlcnJvciArIFwiKSBpZ25vcmVkIGJlY2F1c2UgdGhlIGNvbm5lY3Rpb24gaXMgYWxyZWFkeSBpbiB0aGUgZGlzY29ubmVjdGVkIHN0YXRlLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCBQcm9taXNlLnJlc29sdmUoKV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlID09PSBcIkRpc2Nvbm5lY3RpbmdcIiAvKiBEaXNjb25uZWN0aW5nICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIkNhbGwgdG8gSHR0cENvbm5lY3Rpb24uc3RvcChcIiArIGVycm9yICsgXCIpIGlnbm9yZWQgYmVjYXVzZSB0aGUgY29ubmVjdGlvbiBpcyBhbHJlYWR5IGluIHRoZSBkaXNjb25uZWN0aW5nIHN0YXRlLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCB0aGlzLnN0b3BQcm9taXNlXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9IFwiRGlzY29ubmVjdGluZ1wiIC8qIERpc2Nvbm5lY3RpbmcgKi87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcFByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgY29tcGxldGUgc3RvcCgpIHVudGlsIHN0b3BDb25uZWN0aW9uKCkgY29tcGxldGVzLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc3RvcFByb21pc2VSZXNvbHZlciA9IHJlc29sdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdG9wSW50ZXJuYWwgc2hvdWxkIG5ldmVyIHRocm93IHNvIGp1c3Qgb2JzZXJ2ZSBpdC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5zdG9wSW50ZXJuYWwoZXJyb3IpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3BJbnRlcm5hbCBzaG91bGQgbmV2ZXIgdGhyb3cgc28ganVzdCBvYnNlcnZlIGl0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuc3RvcFByb21pc2VdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIEh0dHBDb25uZWN0aW9uLnByb3RvdHlwZS5zdG9wSW50ZXJuYWwgPSBmdW5jdGlvbiAoZXJyb3IpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBlXzEsIGVfMjtcclxuICAgICAgICAgICAgcmV0dXJuIF9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYS5sYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IGVycm9yIGFzIHNvb24gYXMgcG9zc2libGUgb3RoZXJ3aXNlIHRoZXJlIGlzIGEgcmFjZSBiZXR3ZWVuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSB0cmFuc3BvcnQgY2xvc2luZyBhbmQgcHJvdmlkaW5nIGFuIGVycm9yIGFuZCB0aGUgZXJyb3IgZnJvbSBhIGNsb3NlIG1lc3NhZ2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2Ugd291bGQgcHJlZmVyIHRoZSBjbG9zZSBtZXNzYWdlIGVycm9yLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3BFcnJvciA9IGVycm9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5sYWJlbCA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS50cnlzLnB1c2goWzEsIDMsICwgNF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLnN0YXJ0SW50ZXJuYWxQcm9taXNlXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFszIC8qYnJlYWsqLywgNF07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlXzEgPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDRdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnRyYW5zcG9ydCkgcmV0dXJuIFszIC8qYnJlYWsqLywgOV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gNTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnRyeXMucHVzaChbNSwgNywgLCA4XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMudHJhbnNwb3J0LnN0b3AoKV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDhdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZV8yID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkVycm9yLCBcIkh0dHBDb25uZWN0aW9uLnRyYW5zcG9ydC5zdG9wKCkgdGhyZXcgZXJyb3IgJ1wiICsgZV8yICsgXCInLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9wQ29ubmVjdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA4XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDg6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCAxMF07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA5OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIkh0dHBDb25uZWN0aW9uLnRyYW5zcG9ydCBpcyB1bmRlZmluZWQgaW4gSHR0cENvbm5lY3Rpb24uc3RvcCgpIGJlY2F1c2Ugc3RhcnQoKSBmYWlsZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3BDb25uZWN0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMTA7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBIdHRwQ29ubmVjdGlvbi5wcm90b3R5cGUuc3RhcnRJbnRlcm5hbCA9IGZ1bmN0aW9uICh0cmFuc2ZlckZvcm1hdCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHVybCwgbmVnb3RpYXRlUmVzcG9uc2UsIHJlZGlyZWN0cywgX2xvb3BfMSwgdGhpc18xLCBlXzM7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IHRoaXMuYmFzZVVybDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NUb2tlbkZhY3RvcnkgPSB0aGlzLm9wdGlvbnMuYWNjZXNzVG9rZW5GYWN0b3J5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5sYWJlbCA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS50cnlzLnB1c2goWzEsIDEyLCAsIDEzXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLnNraXBOZWdvdGlhdGlvbikgcmV0dXJuIFszIC8qYnJlYWsqLywgNV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHRoaXMub3B0aW9ucy50cmFuc3BvcnQgPT09IElUcmFuc3BvcnRfMS5IdHRwVHJhbnNwb3J0VHlwZS5XZWJTb2NrZXRzKSkgcmV0dXJuIFszIC8qYnJlYWsqLywgM107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgdG8gYWRkIGEgY29ubmVjdGlvbiBJRCBpbiB0aGlzIGNhc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB0aGlzLmNvbnN0cnVjdFRyYW5zcG9ydChJVHJhbnNwb3J0XzEuSHR0cFRyYW5zcG9ydFR5cGUuV2ViU29ja2V0cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIHNob3VsZCBqdXN0IGNhbGwgY29ubmVjdCBkaXJlY3RseSBpbiB0aGlzIGNhc2UuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIGZhbGxiYWNrIG9yIG5lZ290aWF0ZSBpbiB0aGlzIGNhc2UuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuc3RhcnRUcmFuc3BvcnQodXJsLCB0cmFuc2ZlckZvcm1hdCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2Ugc2hvdWxkIGp1c3QgY2FsbCBjb25uZWN0IGRpcmVjdGx5IGluIHRoaXMgY2FzZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm8gZmFsbGJhY2sgb3IgbmVnb3RpYXRlIGluIHRoaXMgY2FzZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA0XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHRocm93IG5ldyBFcnJvcihcIk5lZ290aWF0aW9uIGNhbiBvbmx5IGJlIHNraXBwZWQgd2hlbiB1c2luZyB0aGUgV2ViU29ja2V0IHRyYW5zcG9ydCBkaXJlY3RseS5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gWzMgLypicmVhayovLCAxMV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZWdvdGlhdGVSZXNwb25zZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0cyA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wXzEgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWNjZXNzVG9rZW5fMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpc18xLmdldE5lZ290aWF0aW9uUmVzcG9uc2UodXJsKV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZ290aWF0ZVJlc3BvbnNlID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHVzZXIgdHJpZXMgdG8gc3RvcCB0aGUgY29ubmVjdGlvbiB3aGVuIGl0IGlzIGJlaW5nIHN0YXJ0ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzXzEuY29ubmVjdGlvblN0YXRlID09PSBcIkRpc2Nvbm5lY3RpbmdcIiAvKiBEaXNjb25uZWN0aW5nICovIHx8IHRoaXNfMS5jb25uZWN0aW9uU3RhdGUgPT09IFwiRGlzY29ubmVjdGVkXCIgLyogRGlzY29ubmVjdGVkICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIGNvbm5lY3Rpb24gd2FzIHN0b3BwZWQgZHVyaW5nIG5lZ290aWF0aW9uLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZWdvdGlhdGVSZXNwb25zZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihuZWdvdGlhdGVSZXNwb25zZS5lcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmVnb3RpYXRlUmVzcG9uc2UuUHJvdG9jb2xWZXJzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGV0ZWN0ZWQgYSBjb25uZWN0aW9uIGF0dGVtcHQgdG8gYW4gQVNQLk5FVCBTaWduYWxSIFNlcnZlci4gVGhpcyBjbGllbnQgb25seSBzdXBwb3J0cyBjb25uZWN0aW5nIHRvIGFuIEFTUC5ORVQgQ29yZSBTaWduYWxSIFNlcnZlci4gU2VlIGh0dHBzOi8vYWthLm1zL3NpZ25hbHItY29yZS1kaWZmZXJlbmNlcyBmb3IgZGV0YWlscy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmVnb3RpYXRlUmVzcG9uc2UudXJsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsID0gbmVnb3RpYXRlUmVzcG9uc2UudXJsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5lZ290aWF0ZVJlc3BvbnNlLmFjY2Vzc1Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzVG9rZW5fMSA9IG5lZ290aWF0ZVJlc3BvbnNlLmFjY2Vzc1Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfMS5hY2Nlc3NUb2tlbkZhY3RvcnkgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBhY2Nlc3NUb2tlbl8xOyB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3RzKys7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfMSA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gNjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDY6IHJldHVybiBbNSAvKnlpZWxkKiovLCBfbG9vcF8xKCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5sYWJlbCA9IDg7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA4OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmVnb3RpYXRlUmVzcG9uc2UudXJsICYmIHJlZGlyZWN0cyA8IE1BWF9SRURJUkVDVFMpIHJldHVybiBbMyAvKmJyZWFrKi8sIDZdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5sYWJlbCA9IDk7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA5OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVkaXJlY3RzID09PSBNQVhfUkVESVJFQ1RTICYmIG5lZ290aWF0ZVJlc3BvbnNlLnVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTmVnb3RpYXRlIHJlZGlyZWN0aW9uIGxpbWl0IGV4Y2VlZGVkLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLmNyZWF0ZVRyYW5zcG9ydCh1cmwsIHRoaXMub3B0aW9ucy50cmFuc3BvcnQsIG5lZ290aWF0ZVJlc3BvbnNlLCB0cmFuc2ZlckZvcm1hdCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAxMTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDExOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50cmFuc3BvcnQgaW5zdGFuY2VvZiBMb25nUG9sbGluZ1RyYW5zcG9ydF8xLkxvbmdQb2xsaW5nVHJhbnNwb3J0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZlYXR1cmVzLmluaGVyZW50S2VlcEFsaXZlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgPT09IFwiQ29ubmVjdGluZ1wiIC8qIENvbm5lY3RpbmcgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVuc3VyZSB0aGUgY29ubmVjdGlvbiB0cmFuc2l0aW9ucyB0byB0aGUgY29ubmVjdGVkIHN0YXRlIHByaW9yIHRvIGNvbXBsZXRpbmcgdGhpcy5zdGFydEludGVybmFsUHJvbWlzZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0YXJ0KCkgd2lsbCBoYW5kbGUgdGhlIGNhc2Ugd2hlbiBzdG9wIHdhcyBjYWxsZWQgYW5kIHN0YXJ0SW50ZXJuYWwgZXhpdHMgc3RpbGwgaW4gdGhlIGRpc2Nvbm5lY3Rpbmcgc3RhdGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIlRoZSBIdHRwQ29ubmVjdGlvbiBjb25uZWN0ZWQgc3VjY2Vzc2Z1bGx5LlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlID0gXCJDb25uZWN0ZWRcIiAvKiBDb25uZWN0ZWQgKi87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFszIC8qYnJlYWsqLywgMTNdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVfMyA9IF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgXCJGYWlsZWQgdG8gc3RhcnQgdGhlIGNvbm5lY3Rpb246IFwiICsgZV8zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUgPSBcIkRpc2Nvbm5lY3RlZFwiIC8qIERpc2Nvbm5lY3RlZCAqLztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCBQcm9taXNlLnJlamVjdChlXzMpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDEzOiByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIEh0dHBDb25uZWN0aW9uLnByb3RvdHlwZS5nZXROZWdvdGlhdGlvblJlc3BvbnNlID0gZnVuY3Rpb24gKHVybCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGhlYWRlcnMsIHRva2VuLCBfYSwgbmFtZSwgdmFsdWUsIG5lZ290aWF0ZVVybCwgcmVzcG9uc2UsIG5lZ290aWF0ZVJlc3BvbnNlLCBlXzQ7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2IpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2IubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSkgcmV0dXJuIFszIC8qYnJlYWsqLywgMl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuYWNjZXNzVG9rZW5GYWN0b3J5KCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSBfYi5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyc1tcIkF1dGhvcml6YXRpb25cIl0gPSBcIkJlYXJlciBcIiArIHRva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hID0gVXRpbHNfMS5nZXRVc2VyQWdlbnRIZWFkZXIoKSwgbmFtZSA9IF9hWzBdLCB2YWx1ZSA9IF9hWzFdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW25hbWVdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5lZ290aWF0ZVVybCA9IHRoaXMucmVzb2x2ZU5lZ290aWF0ZVVybCh1cmwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIlNlbmRpbmcgbmVnb3RpYXRpb24gcmVxdWVzdDogXCIgKyBuZWdvdGlhdGVVcmwgKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLnRyeXMucHVzaChbMywgNSwgLCA2XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuaHR0cENsaWVudC5wb3N0KG5lZ290aWF0ZVVybCwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFwiXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogX19hc3NpZ24oe30sIGhlYWRlcnMsIHRoaXMub3B0aW9ucy5oZWFkZXJzKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoQ3JlZGVudGlhbHM6IHRoaXMub3B0aW9ucy53aXRoQ3JlZGVudGlhbHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IF9iLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlVuZXhwZWN0ZWQgc3RhdHVzIGNvZGUgcmV0dXJuZWQgZnJvbSBuZWdvdGlhdGUgJ1wiICsgcmVzcG9uc2Uuc3RhdHVzQ29kZSArIFwiJ1wiKSldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5lZ290aWF0ZVJlc3BvbnNlID0gSlNPTi5wYXJzZShyZXNwb25zZS5jb250ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFuZWdvdGlhdGVSZXNwb25zZS5uZWdvdGlhdGVWZXJzaW9uIHx8IG5lZ290aWF0ZVJlc3BvbnNlLm5lZ290aWF0ZVZlcnNpb24gPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZWdvdGlhdGUgdmVyc2lvbiAwIGRvZXNuJ3QgdXNlIGNvbm5lY3Rpb25Ub2tlblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU28gd2Ugc2V0IGl0IGVxdWFsIHRvIGNvbm5lY3Rpb25JZCBzbyBhbGwgb3VyIGxvZ2ljIGNhbiB1c2UgY29ubmVjdGlvblRva2VuIHdpdGhvdXQgYmVpbmcgYXdhcmUgb2YgdGhlIG5lZ290aWF0ZSB2ZXJzaW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWdvdGlhdGVSZXNwb25zZS5jb25uZWN0aW9uVG9rZW4gPSBuZWdvdGlhdGVSZXNwb25zZS5jb25uZWN0aW9uSWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIG5lZ290aWF0ZVJlc3BvbnNlXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVfNCA9IF9iLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgXCJGYWlsZWQgdG8gY29tcGxldGUgbmVnb3RpYXRpb24gd2l0aCB0aGUgc2VydmVyOiBcIiArIGVfNCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCBQcm9taXNlLnJlamVjdChlXzQpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDY6IHJldHVybiBbMiAvKnJldHVybiovXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgSHR0cENvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZUNvbm5lY3RVcmwgPSBmdW5jdGlvbiAodXJsLCBjb25uZWN0aW9uVG9rZW4pIHtcclxuICAgICAgICBpZiAoIWNvbm5lY3Rpb25Ub2tlbikge1xyXG4gICAgICAgICAgICByZXR1cm4gdXJsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdXJsICsgKHVybC5pbmRleE9mKFwiP1wiKSA9PT0gLTEgPyBcIj9cIiA6IFwiJlwiKSArIChcImlkPVwiICsgY29ubmVjdGlvblRva2VuKTtcclxuICAgIH07XHJcbiAgICBIdHRwQ29ubmVjdGlvbi5wcm90b3R5cGUuY3JlYXRlVHJhbnNwb3J0ID0gZnVuY3Rpb24gKHVybCwgcmVxdWVzdGVkVHJhbnNwb3J0LCBuZWdvdGlhdGVSZXNwb25zZSwgcmVxdWVzdGVkVHJhbnNmZXJGb3JtYXQpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBjb25uZWN0VXJsLCB0cmFuc3BvcnRFeGNlcHRpb25zLCB0cmFuc3BvcnRzLCBuZWdvdGlhdGUsIF9pLCB0cmFuc3BvcnRzXzEsIGVuZHBvaW50LCB0cmFuc3BvcnRPckVycm9yLCBleF8xLCBleF8yLCBtZXNzYWdlO1xyXG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9hKSB7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0VXJsID0gdGhpcy5jcmVhdGVDb25uZWN0VXJsKHVybCwgbmVnb3RpYXRlUmVzcG9uc2UuY29ubmVjdGlvblRva2VuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzSVRyYW5zcG9ydChyZXF1ZXN0ZWRUcmFuc3BvcnQpKSByZXR1cm4gWzMgLypicmVhayovLCAyXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJDb25uZWN0aW9uIHdhcyBwcm92aWRlZCBhbiBpbnN0YW5jZSBvZiBJVHJhbnNwb3J0LCB1c2luZyB0aGF0IGRpcmVjdGx5LlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQgPSByZXF1ZXN0ZWRUcmFuc3BvcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuc3RhcnRUcmFuc3BvcnQoY29ubmVjdFVybCwgcmVxdWVzdGVkVHJhbnNmZXJGb3JtYXQpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQgPSBuZWdvdGlhdGVSZXNwb25zZS5jb25uZWN0aW9uSWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydEV4Y2VwdGlvbnMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0cyA9IG5lZ290aWF0ZVJlc3BvbnNlLmF2YWlsYWJsZVRyYW5zcG9ydHMgfHwgW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5lZ290aWF0ZSA9IG5lZ290aWF0ZVJlc3BvbnNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaSA9IDAsIHRyYW5zcG9ydHNfMSA9IHRyYW5zcG9ydHM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKF9pIDwgdHJhbnNwb3J0c18xLmxlbmd0aCkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDEzXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW5kcG9pbnQgPSB0cmFuc3BvcnRzXzFbX2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnRPckVycm9yID0gdGhpcy5yZXNvbHZlVHJhbnNwb3J0T3JFcnJvcihlbmRwb2ludCwgcmVxdWVzdGVkVHJhbnNwb3J0LCByZXF1ZXN0ZWRUcmFuc2ZlckZvcm1hdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHRyYW5zcG9ydE9yRXJyb3IgaW5zdGFuY2VvZiBFcnJvcikpIHJldHVybiBbMyAvKmJyZWFrKi8sIDRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTdG9yZSB0aGUgZXJyb3IgYW5kIGNvbnRpbnVlLCB3ZSBkb24ndCB3YW50IHRvIGNhdXNlIGEgcmUtbmVnb3RpYXRlIGluIHRoZXNlIGNhc2VzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydEV4Y2VwdGlvbnMucHVzaChlbmRwb2ludC50cmFuc3BvcnQgKyBcIiBmYWlsZWQ6IFwiICsgdHJhbnNwb3J0T3JFcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDEyXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0lUcmFuc3BvcnQodHJhbnNwb3J0T3JFcnJvcikpIHJldHVybiBbMyAvKmJyZWFrKi8sIDEyXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnRPckVycm9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFuZWdvdGlhdGUpIHJldHVybiBbMyAvKmJyZWFrKi8sIDldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5sYWJlbCA9IDU7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS50cnlzLnB1c2goWzUsIDcsICwgOF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLmdldE5lZ290aWF0aW9uUmVzcG9uc2UodXJsKV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZWdvdGlhdGUgPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDhdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhfMSA9IF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFByb21pc2UucmVqZWN0KGV4XzEpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDg6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RVcmwgPSB0aGlzLmNyZWF0ZUNvbm5lY3RVcmwodXJsLCBuZWdvdGlhdGUuY29ubmVjdGlvblRva2VuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSA5O1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgOTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EudHJ5cy5wdXNoKFs5LCAxMSwgLCAxMl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLnN0YXJ0VHJhbnNwb3J0KGNvbm5lY3RVcmwsIHJlcXVlc3RlZFRyYW5zZmVyRm9ybWF0KV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9IG5lZ290aWF0ZS5jb25uZWN0aW9uSWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDExOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleF8yID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkVycm9yLCBcIkZhaWxlZCB0byBzdGFydCB0aGUgdHJhbnNwb3J0ICdcIiArIGVuZHBvaW50LnRyYW5zcG9ydCArIFwiJzogXCIgKyBleF8yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmVnb3RpYXRlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnRFeGNlcHRpb25zLnB1c2goZW5kcG9pbnQudHJhbnNwb3J0ICsgXCIgZmFpbGVkOiBcIiArIGV4XzIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgIT09IFwiQ29ubmVjdGluZ1wiIC8qIENvbm5lY3RpbmcgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBcIkZhaWxlZCB0byBzZWxlY3QgdHJhbnNwb3J0IGJlZm9yZSBzdG9wKCkgd2FzIGNhbGxlZC5cIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihtZXNzYWdlKSldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDEyXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDEyOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaSsrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCAzXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDEzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNwb3J0RXhjZXB0aW9ucy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5hYmxlIHRvIGNvbm5lY3QgdG8gdGhlIHNlcnZlciB3aXRoIGFueSBvZiB0aGUgYXZhaWxhYmxlIHRyYW5zcG9ydHMuIFwiICsgdHJhbnNwb3J0RXhjZXB0aW9ucy5qb2luKFwiIFwiKSkpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm9uZSBvZiB0aGUgdHJhbnNwb3J0cyBzdXBwb3J0ZWQgYnkgdGhlIGNsaWVudCBhcmUgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIuXCIpKV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIEh0dHBDb25uZWN0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RUcmFuc3BvcnQgPSBmdW5jdGlvbiAodHJhbnNwb3J0KSB7XHJcbiAgICAgICAgc3dpdGNoICh0cmFuc3BvcnQpIHtcclxuICAgICAgICAgICAgY2FzZSBJVHJhbnNwb3J0XzEuSHR0cFRyYW5zcG9ydFR5cGUuV2ViU29ja2V0czpcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLldlYlNvY2tldCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIidXZWJTb2NrZXQnIGlzIG5vdCBzdXBwb3J0ZWQgaW4geW91ciBlbnZpcm9ubWVudC5cIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdlYlNvY2tldFRyYW5zcG9ydF8xLldlYlNvY2tldFRyYW5zcG9ydCh0aGlzLmh0dHBDbGllbnQsIHRoaXMuYWNjZXNzVG9rZW5GYWN0b3J5LCB0aGlzLmxvZ2dlciwgdGhpcy5vcHRpb25zLmxvZ01lc3NhZ2VDb250ZW50IHx8IGZhbHNlLCB0aGlzLm9wdGlvbnMuV2ViU29ja2V0LCB0aGlzLm9wdGlvbnMuaGVhZGVycyB8fCB7fSk7XHJcbiAgICAgICAgICAgIGNhc2UgSVRyYW5zcG9ydF8xLkh0dHBUcmFuc3BvcnRUeXBlLlNlcnZlclNlbnRFdmVudHM6XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5FdmVudFNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIidFdmVudFNvdXJjZScgaXMgbm90IHN1cHBvcnRlZCBpbiB5b3VyIGVudmlyb25tZW50LlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2VydmVyU2VudEV2ZW50c1RyYW5zcG9ydF8xLlNlcnZlclNlbnRFdmVudHNUcmFuc3BvcnQodGhpcy5odHRwQ2xpZW50LCB0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSwgdGhpcy5sb2dnZXIsIHRoaXMub3B0aW9ucy5sb2dNZXNzYWdlQ29udGVudCB8fCBmYWxzZSwgdGhpcy5vcHRpb25zLkV2ZW50U291cmNlLCB0aGlzLm9wdGlvbnMud2l0aENyZWRlbnRpYWxzLCB0aGlzLm9wdGlvbnMuaGVhZGVycyB8fCB7fSk7XHJcbiAgICAgICAgICAgIGNhc2UgSVRyYW5zcG9ydF8xLkh0dHBUcmFuc3BvcnRUeXBlLkxvbmdQb2xsaW5nOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBMb25nUG9sbGluZ1RyYW5zcG9ydF8xLkxvbmdQb2xsaW5nVHJhbnNwb3J0KHRoaXMuaHR0cENsaWVudCwgdGhpcy5hY2Nlc3NUb2tlbkZhY3RvcnksIHRoaXMubG9nZ2VyLCB0aGlzLm9wdGlvbnMubG9nTWVzc2FnZUNvbnRlbnQgfHwgZmFsc2UsIHRoaXMub3B0aW9ucy53aXRoQ3JlZGVudGlhbHMsIHRoaXMub3B0aW9ucy5oZWFkZXJzIHx8IHt9KTtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gdHJhbnNwb3J0OiBcIiArIHRyYW5zcG9ydCArIFwiLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgSHR0cENvbm5lY3Rpb24ucHJvdG90eXBlLnN0YXJ0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHVybCwgdHJhbnNmZXJGb3JtYXQpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9ucmVjZWl2ZSA9IHRoaXMub25yZWNlaXZlO1xyXG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9uY2xvc2UgPSBmdW5jdGlvbiAoZSkgeyByZXR1cm4gX3RoaXMuc3RvcENvbm5lY3Rpb24oZSk7IH07XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNwb3J0LmNvbm5lY3QodXJsLCB0cmFuc2ZlckZvcm1hdCk7XHJcbiAgICB9O1xyXG4gICAgSHR0cENvbm5lY3Rpb24ucHJvdG90eXBlLnJlc29sdmVUcmFuc3BvcnRPckVycm9yID0gZnVuY3Rpb24gKGVuZHBvaW50LCByZXF1ZXN0ZWRUcmFuc3BvcnQsIHJlcXVlc3RlZFRyYW5zZmVyRm9ybWF0KSB7XHJcbiAgICAgICAgdmFyIHRyYW5zcG9ydCA9IElUcmFuc3BvcnRfMS5IdHRwVHJhbnNwb3J0VHlwZVtlbmRwb2ludC50cmFuc3BvcnRdO1xyXG4gICAgICAgIGlmICh0cmFuc3BvcnQgPT09IG51bGwgfHwgdHJhbnNwb3J0ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJTa2lwcGluZyB0cmFuc3BvcnQgJ1wiICsgZW5kcG9pbnQudHJhbnNwb3J0ICsgXCInIGJlY2F1c2UgaXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNsaWVudC5cIik7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJTa2lwcGluZyB0cmFuc3BvcnQgJ1wiICsgZW5kcG9pbnQudHJhbnNwb3J0ICsgXCInIGJlY2F1c2UgaXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNsaWVudC5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0TWF0Y2hlcyhyZXF1ZXN0ZWRUcmFuc3BvcnQsIHRyYW5zcG9ydCkpIHtcclxuICAgICAgICAgICAgICAgIHZhciB0cmFuc2ZlckZvcm1hdHMgPSBlbmRwb2ludC50cmFuc2ZlckZvcm1hdHMubWFwKGZ1bmN0aW9uIChzKSB7IHJldHVybiBJVHJhbnNwb3J0XzEuVHJhbnNmZXJGb3JtYXRbc107IH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zZmVyRm9ybWF0cy5pbmRleE9mKHJlcXVlc3RlZFRyYW5zZmVyRm9ybWF0KSA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0cmFuc3BvcnQgPT09IElUcmFuc3BvcnRfMS5IdHRwVHJhbnNwb3J0VHlwZS5XZWJTb2NrZXRzICYmICF0aGlzLm9wdGlvbnMuV2ViU29ja2V0KSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAodHJhbnNwb3J0ID09PSBJVHJhbnNwb3J0XzEuSHR0cFRyYW5zcG9ydFR5cGUuU2VydmVyU2VudEV2ZW50cyAmJiAhdGhpcy5vcHRpb25zLkV2ZW50U291cmNlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIlNraXBwaW5nIHRyYW5zcG9ydCAnXCIgKyBJVHJhbnNwb3J0XzEuSHR0cFRyYW5zcG9ydFR5cGVbdHJhbnNwb3J0XSArIFwiJyBiZWNhdXNlIGl0IGlzIG5vdCBzdXBwb3J0ZWQgaW4geW91ciBlbnZpcm9ubWVudC4nXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKFwiJ1wiICsgSVRyYW5zcG9ydF8xLkh0dHBUcmFuc3BvcnRUeXBlW3RyYW5zcG9ydF0gKyBcIicgaXMgbm90IHN1cHBvcnRlZCBpbiB5b3VyIGVudmlyb25tZW50LlwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiU2VsZWN0aW5nIHRyYW5zcG9ydCAnXCIgKyBJVHJhbnNwb3J0XzEuSHR0cFRyYW5zcG9ydFR5cGVbdHJhbnNwb3J0XSArIFwiJy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3RUcmFuc3BvcnQodHJhbnNwb3J0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBleDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiU2tpcHBpbmcgdHJhbnNwb3J0ICdcIiArIElUcmFuc3BvcnRfMS5IdHRwVHJhbnNwb3J0VHlwZVt0cmFuc3BvcnRdICsgXCInIGJlY2F1c2UgaXQgZG9lcyBub3Qgc3VwcG9ydCB0aGUgcmVxdWVzdGVkIHRyYW5zZmVyIGZvcm1hdCAnXCIgKyBJVHJhbnNwb3J0XzEuVHJhbnNmZXJGb3JtYXRbcmVxdWVzdGVkVHJhbnNmZXJGb3JtYXRdICsgXCInLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKFwiJ1wiICsgSVRyYW5zcG9ydF8xLkh0dHBUcmFuc3BvcnRUeXBlW3RyYW5zcG9ydF0gKyBcIicgZG9lcyBub3Qgc3VwcG9ydCBcIiArIElUcmFuc3BvcnRfMS5UcmFuc2ZlckZvcm1hdFtyZXF1ZXN0ZWRUcmFuc2ZlckZvcm1hdF0gKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIlNraXBwaW5nIHRyYW5zcG9ydCAnXCIgKyBJVHJhbnNwb3J0XzEuSHR0cFRyYW5zcG9ydFR5cGVbdHJhbnNwb3J0XSArIFwiJyBiZWNhdXNlIGl0IHdhcyBkaXNhYmxlZCBieSB0aGUgY2xpZW50LlwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IoXCInXCIgKyBJVHJhbnNwb3J0XzEuSHR0cFRyYW5zcG9ydFR5cGVbdHJhbnNwb3J0XSArIFwiJyBpcyBkaXNhYmxlZCBieSB0aGUgY2xpZW50LlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBIdHRwQ29ubmVjdGlvbi5wcm90b3R5cGUuaXNJVHJhbnNwb3J0ID0gZnVuY3Rpb24gKHRyYW5zcG9ydCkge1xyXG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQgJiYgdHlwZW9mICh0cmFuc3BvcnQpID09PSBcIm9iamVjdFwiICYmIFwiY29ubmVjdFwiIGluIHRyYW5zcG9ydDtcclxuICAgIH07XHJcbiAgICBIdHRwQ29ubmVjdGlvbi5wcm90b3R5cGUuc3RvcENvbm5lY3Rpb24gPSBmdW5jdGlvbiAoZXJyb3IpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiSHR0cENvbm5lY3Rpb24uc3RvcENvbm5lY3Rpb24oXCIgKyBlcnJvciArIFwiKSBjYWxsZWQgd2hpbGUgaW4gc3RhdGUgXCIgKyB0aGlzLmNvbm5lY3Rpb25TdGF0ZSArIFwiLlwiKTtcclxuICAgICAgICB0aGlzLnRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAvLyBJZiB3ZSBoYXZlIGEgc3RvcEVycm9yLCBpdCB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgdGhlIGVycm9yIGZyb20gdGhlIHRyYW5zcG9ydFxyXG4gICAgICAgIGVycm9yID0gdGhpcy5zdG9wRXJyb3IgfHwgZXJyb3I7XHJcbiAgICAgICAgdGhpcy5zdG9wRXJyb3IgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlID09PSBcIkRpc2Nvbm5lY3RlZFwiIC8qIERpc2Nvbm5lY3RlZCAqLykge1xyXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIkNhbGwgdG8gSHR0cENvbm5lY3Rpb24uc3RvcENvbm5lY3Rpb24oXCIgKyBlcnJvciArIFwiKSB3YXMgaWdub3JlZCBiZWNhdXNlIHRoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgaW4gdGhlIGRpc2Nvbm5lY3RlZCBzdGF0ZS5cIik7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlID09PSBcIkNvbm5lY3RpbmdcIiAvKiBDb25uZWN0aW5nICovKSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuV2FybmluZywgXCJDYWxsIHRvIEh0dHBDb25uZWN0aW9uLnN0b3BDb25uZWN0aW9uKFwiICsgZXJyb3IgKyBcIikgd2FzIGlnbm9yZWQgYmVjYXVzZSB0aGUgY29ubmVjdGlvbiBpcyBzdGlsbCBpbiB0aGUgY29ubmVjdGluZyBzdGF0ZS5cIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkh0dHBDb25uZWN0aW9uLnN0b3BDb25uZWN0aW9uKFwiICsgZXJyb3IgKyBcIikgd2FzIGNhbGxlZCB3aGlsZSB0aGUgY29ubmVjdGlvbiBpcyBzdGlsbCBpbiB0aGUgY29ubmVjdGluZyBzdGF0ZS5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9PT0gXCJEaXNjb25uZWN0aW5nXCIgLyogRGlzY29ubmVjdGluZyAqLykge1xyXG4gICAgICAgICAgICAvLyBBIGNhbGwgdG8gc3RvcCgpIGluZHVjZWQgdGhpcyBjYWxsIHRvIHN0b3BDb25uZWN0aW9uIGFuZCBuZWVkcyB0byBiZSBjb21wbGV0ZWQuXHJcbiAgICAgICAgICAgIC8vIEFueSBzdG9wKCkgYXdhaXRlcnMgd2lsbCBiZSBzY2hlZHVsZWQgdG8gY29udGludWUgYWZ0ZXIgdGhlIG9uY2xvc2UgY2FsbGJhY2sgZmlyZXMuXHJcbiAgICAgICAgICAgIHRoaXMuc3RvcFByb21pc2VSZXNvbHZlcigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgXCJDb25uZWN0aW9uIGRpc2Nvbm5lY3RlZCB3aXRoIGVycm9yICdcIiArIGVycm9yICsgXCInLlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sIFwiQ29ubmVjdGlvbiBkaXNjb25uZWN0ZWQuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5zZW5kUXVldWUpIHtcclxuICAgICAgICAgICAgdGhpcy5zZW5kUXVldWUuc3RvcCgpLmNhdGNoKGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgXCJUcmFuc3BvcnRTZW5kUXVldWUuc3RvcCgpIHRocmV3IGVycm9yICdcIiArIGUgKyBcIicuXCIpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5zZW5kUXVldWUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY29ubmVjdGlvbklkID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlID0gXCJEaXNjb25uZWN0ZWRcIiAvKiBEaXNjb25uZWN0ZWQgKi87XHJcbiAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXJ0ZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhcnRlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub25jbG9zZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25jbG9zZShlcnJvcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsIFwiSHR0cENvbm5lY3Rpb24ub25jbG9zZShcIiArIGVycm9yICsgXCIpIHRocmV3IGVycm9yICdcIiArIGUgKyBcIicuXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEh0dHBDb25uZWN0aW9uLnByb3RvdHlwZS5yZXNvbHZlVXJsID0gZnVuY3Rpb24gKHVybCkge1xyXG4gICAgICAgIC8vIHN0YXJ0c1dpdGggaXMgbm90IHN1cHBvcnRlZCBpbiBJRVxyXG4gICAgICAgIGlmICh1cmwubGFzdEluZGV4T2YoXCJodHRwczovL1wiLCAwKSA9PT0gMCB8fCB1cmwubGFzdEluZGV4T2YoXCJodHRwOi8vXCIsIDApID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB1cmw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghVXRpbHNfMS5QbGF0Zm9ybS5pc0Jyb3dzZXIgfHwgIXdpbmRvdy5kb2N1bWVudCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgcmVzb2x2ZSAnXCIgKyB1cmwgKyBcIicuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTZXR0aW5nIHRoZSB1cmwgdG8gdGhlIGhyZWYgcHJvcGVyeSBvZiBhbiBhbmNob3IgdGFnIGhhbmRsZXMgbm9ybWFsaXphdGlvblxyXG4gICAgICAgIC8vIGZvciB1cy4gVGhlcmUgYXJlIDMgbWFpbiBjYXNlcy5cclxuICAgICAgICAvLyAxLiBSZWxhdGl2ZSBwYXRoIG5vcm1hbGl6YXRpb24gZS5nIFwiYlwiIC0+IFwiaHR0cDovL2xvY2FsaG9zdDo1MDAwL2EvYlwiXHJcbiAgICAgICAgLy8gMi4gQWJzb2x1dGUgcGF0aCBub3JtYWxpemF0aW9uIGUuZyBcIi9hL2JcIiAtPiBcImh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC9hL2JcIlxyXG4gICAgICAgIC8vIDMuIE5ldHdvcmtwYXRoIHJlZmVyZW5jZSBub3JtYWxpemF0aW9uIGUuZyBcIi8vbG9jYWxob3N0OjUwMDAvYS9iXCIgLT4gXCJodHRwOi8vbG9jYWxob3N0OjUwMDAvYS9iXCJcclxuICAgICAgICB2YXIgYVRhZyA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcclxuICAgICAgICBhVGFnLmhyZWYgPSB1cmw7XHJcbiAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5JbmZvcm1hdGlvbiwgXCJOb3JtYWxpemluZyAnXCIgKyB1cmwgKyBcIicgdG8gJ1wiICsgYVRhZy5ocmVmICsgXCInLlwiKTtcclxuICAgICAgICByZXR1cm4gYVRhZy5ocmVmO1xyXG4gICAgfTtcclxuICAgIEh0dHBDb25uZWN0aW9uLnByb3RvdHlwZS5yZXNvbHZlTmVnb3RpYXRlVXJsID0gZnVuY3Rpb24gKHVybCkge1xyXG4gICAgICAgIHZhciBpbmRleCA9IHVybC5pbmRleE9mKFwiP1wiKTtcclxuICAgICAgICB2YXIgbmVnb3RpYXRlVXJsID0gdXJsLnN1YnN0cmluZygwLCBpbmRleCA9PT0gLTEgPyB1cmwubGVuZ3RoIDogaW5kZXgpO1xyXG4gICAgICAgIGlmIChuZWdvdGlhdGVVcmxbbmVnb3RpYXRlVXJsLmxlbmd0aCAtIDFdICE9PSBcIi9cIikge1xyXG4gICAgICAgICAgICBuZWdvdGlhdGVVcmwgKz0gXCIvXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG5lZ290aWF0ZVVybCArPSBcIm5lZ290aWF0ZVwiO1xyXG4gICAgICAgIG5lZ290aWF0ZVVybCArPSBpbmRleCA9PT0gLTEgPyBcIlwiIDogdXJsLnN1YnN0cmluZyhpbmRleCk7XHJcbiAgICAgICAgaWYgKG5lZ290aWF0ZVVybC5pbmRleE9mKFwibmVnb3RpYXRlVmVyc2lvblwiKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgbmVnb3RpYXRlVXJsICs9IGluZGV4ID09PSAtMSA/IFwiP1wiIDogXCImXCI7XHJcbiAgICAgICAgICAgIG5lZ290aWF0ZVVybCArPSBcIm5lZ290aWF0ZVZlcnNpb249XCIgKyB0aGlzLm5lZ290aWF0ZVZlcnNpb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBuZWdvdGlhdGVVcmw7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEh0dHBDb25uZWN0aW9uO1xyXG59KCkpO1xyXG5leHBvcnRzLkh0dHBDb25uZWN0aW9uID0gSHR0cENvbm5lY3Rpb247XHJcbmZ1bmN0aW9uIHRyYW5zcG9ydE1hdGNoZXMocmVxdWVzdGVkVHJhbnNwb3J0LCBhY3R1YWxUcmFuc3BvcnQpIHtcclxuICAgIHJldHVybiAhcmVxdWVzdGVkVHJhbnNwb3J0IHx8ICgoYWN0dWFsVHJhbnNwb3J0ICYgcmVxdWVzdGVkVHJhbnNwb3J0KSAhPT0gMCk7XHJcbn1cclxuLyoqIEBwcml2YXRlICovXHJcbnZhciBUcmFuc3BvcnRTZW5kUXVldWUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBUcmFuc3BvcnRTZW5kUXVldWUodHJhbnNwb3J0KSB7XHJcbiAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XHJcbiAgICAgICAgdGhpcy5idWZmZXIgPSBbXTtcclxuICAgICAgICB0aGlzLmV4ZWN1dGluZyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5zZW5kQnVmZmVyZWREYXRhID0gbmV3IFByb21pc2VTb3VyY2UoKTtcclxuICAgICAgICB0aGlzLnRyYW5zcG9ydFJlc3VsdCA9IG5ldyBQcm9taXNlU291cmNlKCk7XHJcbiAgICAgICAgdGhpcy5zZW5kTG9vcFByb21pc2UgPSB0aGlzLnNlbmRMb29wKCk7XHJcbiAgICB9XHJcbiAgICBUcmFuc3BvcnRTZW5kUXVldWUucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIHRoaXMuYnVmZmVyRGF0YShkYXRhKTtcclxuICAgICAgICBpZiAoIXRoaXMudHJhbnNwb3J0UmVzdWx0KSB7XHJcbiAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0UmVzdWx0ID0gbmV3IFByb21pc2VTb3VyY2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNwb3J0UmVzdWx0LnByb21pc2U7XHJcbiAgICB9O1xyXG4gICAgVHJhbnNwb3J0U2VuZFF1ZXVlLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuZXhlY3V0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5zZW5kQnVmZmVyZWREYXRhLnJlc29sdmUoKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZW5kTG9vcFByb21pc2U7XHJcbiAgICB9O1xyXG4gICAgVHJhbnNwb3J0U2VuZFF1ZXVlLnByb3RvdHlwZS5idWZmZXJEYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoICYmIHR5cGVvZiAodGhpcy5idWZmZXJbMF0pICE9PSB0eXBlb2YgKGRhdGEpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIGRhdGEgdG8gYmUgb2YgdHlwZSBcIiArIHR5cGVvZiAodGhpcy5idWZmZXIpICsgXCIgYnV0IHdhcyBvZiB0eXBlIFwiICsgdHlwZW9mIChkYXRhKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuYnVmZmVyLnB1c2goZGF0YSk7XHJcbiAgICAgICAgdGhpcy5zZW5kQnVmZmVyZWREYXRhLnJlc29sdmUoKTtcclxuICAgIH07XHJcbiAgICBUcmFuc3BvcnRTZW5kUXVldWUucHJvdG90eXBlLnNlbmRMb29wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHRyYW5zcG9ydFJlc3VsdCwgZGF0YSwgZXJyb3JfMTtcclxuICAgICAgICAgICAgcmV0dXJuIF9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYS5sYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0cnVlKSByZXR1cm4gWzMgLypicmVhayovLCA2XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5zZW5kQnVmZmVyZWREYXRhLnByb21pc2VdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZXhlY3V0aW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50cmFuc3BvcnRSZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zcG9ydFJlc3VsdC5yZWplY3QoXCJDb25uZWN0aW9uIHN0b3BwZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFszIC8qYnJlYWsqLywgNl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZW5kQnVmZmVyZWREYXRhID0gbmV3IFByb21pc2VTb3VyY2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0UmVzdWx0ID0gdGhpcy50cmFuc3BvcnRSZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0UmVzdWx0ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gdHlwZW9mICh0aGlzLmJ1ZmZlclswXSkgPT09IFwic3RyaW5nXCIgP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWZmZXIuam9pbihcIlwiKSA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc3BvcnRTZW5kUXVldWUuY29uY2F0QnVmZmVycyh0aGlzLmJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVmZmVyLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnRyeXMucHVzaChbMiwgNCwgLCA1XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMudHJhbnNwb3J0LnNlbmQoZGF0YSldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnRSZXN1bHQucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA1XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yXzEgPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydFJlc3VsdC5yZWplY3QoZXJyb3JfMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDVdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNTogcmV0dXJuIFszIC8qYnJlYWsqLywgMF07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2OiByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIFRyYW5zcG9ydFNlbmRRdWV1ZS5jb25jYXRCdWZmZXJzID0gZnVuY3Rpb24gKGFycmF5QnVmZmVycykge1xyXG4gICAgICAgIHZhciB0b3RhbExlbmd0aCA9IGFycmF5QnVmZmVycy5tYXAoZnVuY3Rpb24gKGIpIHsgcmV0dXJuIGIuYnl0ZUxlbmd0aDsgfSkucmVkdWNlKGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhICsgYjsgfSk7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KHRvdGFsTGVuZ3RoKTtcclxuICAgICAgICB2YXIgb2Zmc2V0ID0gMDtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGFycmF5QnVmZmVyc18xID0gYXJyYXlCdWZmZXJzOyBfaSA8IGFycmF5QnVmZmVyc18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgaXRlbSA9IGFycmF5QnVmZmVyc18xW19pXTtcclxuICAgICAgICAgICAgcmVzdWx0LnNldChuZXcgVWludDhBcnJheShpdGVtKSwgb2Zmc2V0KTtcclxuICAgICAgICAgICAgb2Zmc2V0ICs9IGl0ZW0uYnl0ZUxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdC5idWZmZXI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFRyYW5zcG9ydFNlbmRRdWV1ZTtcclxufSgpKTtcclxuZXhwb3J0cy5UcmFuc3BvcnRTZW5kUXVldWUgPSBUcmFuc3BvcnRTZW5kUXVldWU7XHJcbnZhciBQcm9taXNlU291cmNlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gUHJvbWlzZVNvdXJjZSgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMucHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgdmFyIF9hO1xyXG4gICAgICAgICAgICByZXR1cm4gX2EgPSBbcmVzb2x2ZSwgcmVqZWN0XSwgX3RoaXMucmVzb2x2ZXIgPSBfYVswXSwgX3RoaXMucmVqZWN0ZXIgPSBfYVsxXSwgX2E7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBQcm9taXNlU291cmNlLnByb3RvdHlwZS5yZXNvbHZlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMucmVzb2x2ZXIoKTtcclxuICAgIH07XHJcbiAgICBQcm9taXNlU291cmNlLnByb3RvdHlwZS5yZWplY3QgPSBmdW5jdGlvbiAocmVhc29uKSB7XHJcbiAgICAgICAgdGhpcy5yZWplY3RlcihyZWFzb24pO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBQcm9taXNlU291cmNlO1xyXG59KCkpO1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1IdHRwQ29ubmVjdGlvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG52YXIgX19nZW5lcmF0b3IgPSAodGhpcyAmJiB0aGlzLl9fZ2VuZXJhdG9yKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIEhhbmRzaGFrZVByb3RvY29sXzEgPSByZXF1aXJlKFwiLi9IYW5kc2hha2VQcm90b2NvbFwiKTtcclxudmFyIElIdWJQcm90b2NvbF8xID0gcmVxdWlyZShcIi4vSUh1YlByb3RvY29sXCIpO1xyXG52YXIgSUxvZ2dlcl8xID0gcmVxdWlyZShcIi4vSUxvZ2dlclwiKTtcclxudmFyIFN1YmplY3RfMSA9IHJlcXVpcmUoXCIuL1N1YmplY3RcIik7XHJcbnZhciBVdGlsc18xID0gcmVxdWlyZShcIi4vVXRpbHNcIik7XHJcbnZhciBERUZBVUxUX1RJTUVPVVRfSU5fTVMgPSAzMCAqIDEwMDA7XHJcbnZhciBERUZBVUxUX1BJTkdfSU5URVJWQUxfSU5fTVMgPSAxNSAqIDEwMDA7XHJcbi8qKiBEZXNjcmliZXMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHtAbGluayBIdWJDb25uZWN0aW9ufSB0byB0aGUgc2VydmVyLiAqL1xyXG52YXIgSHViQ29ubmVjdGlvblN0YXRlO1xyXG4oZnVuY3Rpb24gKEh1YkNvbm5lY3Rpb25TdGF0ZSkge1xyXG4gICAgLyoqIFRoZSBodWIgY29ubmVjdGlvbiBpcyBkaXNjb25uZWN0ZWQuICovXHJcbiAgICBIdWJDb25uZWN0aW9uU3RhdGVbXCJEaXNjb25uZWN0ZWRcIl0gPSBcIkRpc2Nvbm5lY3RlZFwiO1xyXG4gICAgLyoqIFRoZSBodWIgY29ubmVjdGlvbiBpcyBjb25uZWN0aW5nLiAqL1xyXG4gICAgSHViQ29ubmVjdGlvblN0YXRlW1wiQ29ubmVjdGluZ1wiXSA9IFwiQ29ubmVjdGluZ1wiO1xyXG4gICAgLyoqIFRoZSBodWIgY29ubmVjdGlvbiBpcyBjb25uZWN0ZWQuICovXHJcbiAgICBIdWJDb25uZWN0aW9uU3RhdGVbXCJDb25uZWN0ZWRcIl0gPSBcIkNvbm5lY3RlZFwiO1xyXG4gICAgLyoqIFRoZSBodWIgY29ubmVjdGlvbiBpcyBkaXNjb25uZWN0aW5nLiAqL1xyXG4gICAgSHViQ29ubmVjdGlvblN0YXRlW1wiRGlzY29ubmVjdGluZ1wiXSA9IFwiRGlzY29ubmVjdGluZ1wiO1xyXG4gICAgLyoqIFRoZSBodWIgY29ubmVjdGlvbiBpcyByZWNvbm5lY3RpbmcuICovXHJcbiAgICBIdWJDb25uZWN0aW9uU3RhdGVbXCJSZWNvbm5lY3RpbmdcIl0gPSBcIlJlY29ubmVjdGluZ1wiO1xyXG59KShIdWJDb25uZWN0aW9uU3RhdGUgPSBleHBvcnRzLkh1YkNvbm5lY3Rpb25TdGF0ZSB8fCAoZXhwb3J0cy5IdWJDb25uZWN0aW9uU3RhdGUgPSB7fSkpO1xyXG4vKiogUmVwcmVzZW50cyBhIGNvbm5lY3Rpb24gdG8gYSBTaWduYWxSIEh1Yi4gKi9cclxudmFyIEh1YkNvbm5lY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBIdWJDb25uZWN0aW9uKGNvbm5lY3Rpb24sIGxvZ2dlciwgcHJvdG9jb2wsIHJlY29ubmVjdFBvbGljeSkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgVXRpbHNfMS5BcmcuaXNSZXF1aXJlZChjb25uZWN0aW9uLCBcImNvbm5lY3Rpb25cIik7XHJcbiAgICAgICAgVXRpbHNfMS5BcmcuaXNSZXF1aXJlZChsb2dnZXIsIFwibG9nZ2VyXCIpO1xyXG4gICAgICAgIFV0aWxzXzEuQXJnLmlzUmVxdWlyZWQocHJvdG9jb2wsIFwicHJvdG9jb2xcIik7XHJcbiAgICAgICAgdGhpcy5zZXJ2ZXJUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBERUZBVUxUX1RJTUVPVVRfSU5fTVM7XHJcbiAgICAgICAgdGhpcy5rZWVwQWxpdmVJbnRlcnZhbEluTWlsbGlzZWNvbmRzID0gREVGQVVMVF9QSU5HX0lOVEVSVkFMX0lOX01TO1xyXG4gICAgICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyO1xyXG4gICAgICAgIHRoaXMucHJvdG9jb2wgPSBwcm90b2NvbDtcclxuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xyXG4gICAgICAgIHRoaXMucmVjb25uZWN0UG9saWN5ID0gcmVjb25uZWN0UG9saWN5O1xyXG4gICAgICAgIHRoaXMuaGFuZHNoYWtlUHJvdG9jb2wgPSBuZXcgSGFuZHNoYWtlUHJvdG9jb2xfMS5IYW5kc2hha2VQcm90b2NvbCgpO1xyXG4gICAgICAgIHRoaXMuY29ubmVjdGlvbi5vbnJlY2VpdmUgPSBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gX3RoaXMucHJvY2Vzc0luY29taW5nRGF0YShkYXRhKTsgfTtcclxuICAgICAgICB0aGlzLmNvbm5lY3Rpb24ub25jbG9zZSA9IGZ1bmN0aW9uIChlcnJvcikgeyByZXR1cm4gX3RoaXMuY29ubmVjdGlvbkNsb3NlZChlcnJvcik7IH07XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB7fTtcclxuICAgICAgICB0aGlzLm1ldGhvZHMgPSB7fTtcclxuICAgICAgICB0aGlzLmNsb3NlZENhbGxiYWNrcyA9IFtdO1xyXG4gICAgICAgIHRoaXMucmVjb25uZWN0aW5nQ2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgdGhpcy5yZWNvbm5lY3RlZENhbGxiYWNrcyA9IFtdO1xyXG4gICAgICAgIHRoaXMuaW52b2NhdGlvbklkID0gMDtcclxuICAgICAgICB0aGlzLnJlY2VpdmVkSGFuZHNoYWtlUmVzcG9uc2UgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9IEh1YkNvbm5lY3Rpb25TdGF0ZS5EaXNjb25uZWN0ZWQ7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhcnRlZCA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuY2FjaGVkUGluZ01lc3NhZ2UgPSB0aGlzLnByb3RvY29sLndyaXRlTWVzc2FnZSh7IHR5cGU6IElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLlBpbmcgfSk7XHJcbiAgICB9XHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICAvLyBVc2luZyBhIHB1YmxpYyBzdGF0aWMgZmFjdG9yeSBtZXRob2QgbWVhbnMgd2UgY2FuIGhhdmUgYSBwcml2YXRlIGNvbnN0cnVjdG9yIGFuZCBhbiBfaW50ZXJuYWxfXHJcbiAgICAvLyBjcmVhdGUgbWV0aG9kIHRoYXQgY2FuIGJlIHVzZWQgYnkgSHViQ29ubmVjdGlvbkJ1aWxkZXIuIEFuIFwiaW50ZXJuYWxcIiBjb25zdHJ1Y3RvciB3b3VsZCBqdXN0XHJcbiAgICAvLyBiZSBzdHJpcHBlZCBhd2F5IGFuZCB0aGUgJy5kLnRzJyBmaWxlIHdvdWxkIGhhdmUgbm8gY29uc3RydWN0b3IsIHdoaWNoIGlzIGludGVycHJldGVkIGFzIGFcclxuICAgIC8vIHB1YmxpYyBwYXJhbWV0ZXItbGVzcyBjb25zdHJ1Y3Rvci5cclxuICAgIEh1YkNvbm5lY3Rpb24uY3JlYXRlID0gZnVuY3Rpb24gKGNvbm5lY3Rpb24sIGxvZ2dlciwgcHJvdG9jb2wsIHJlY29ubmVjdFBvbGljeSkge1xyXG4gICAgICAgIHJldHVybiBuZXcgSHViQ29ubmVjdGlvbihjb25uZWN0aW9uLCBsb2dnZXIsIHByb3RvY29sLCByZWNvbm5lY3RQb2xpY3kpO1xyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShIdWJDb25uZWN0aW9uLnByb3RvdHlwZSwgXCJzdGF0ZVwiLCB7XHJcbiAgICAgICAgLyoqIEluZGljYXRlcyB0aGUgc3RhdGUgb2YgdGhlIHtAbGluayBIdWJDb25uZWN0aW9ufSB0byB0aGUgc2VydmVyLiAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uU3RhdGU7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoSHViQ29ubmVjdGlvbi5wcm90b3R5cGUsIFwiY29ubmVjdGlvbklkXCIsIHtcclxuICAgICAgICAvKiogUmVwcmVzZW50cyB0aGUgY29ubmVjdGlvbiBpZCBvZiB0aGUge0BsaW5rIEh1YkNvbm5lY3Rpb259IG9uIHRoZSBzZXJ2ZXIuIFRoZSBjb25uZWN0aW9uIGlkIHdpbGwgYmUgbnVsbCB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGVpdGhlclxyXG4gICAgICAgICAqICBpbiB0aGUgZGlzY29ubmVjdGVkIHN0YXRlIG9yIGlmIHRoZSBuZWdvdGlhdGlvbiBzdGVwIHdhcyBza2lwcGVkLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uID8gKHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgfHwgbnVsbCkgOiBudWxsO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLCBcImJhc2VVcmxcIiwge1xyXG4gICAgICAgIC8qKiBJbmRpY2F0ZXMgdGhlIHVybCBvZiB0aGUge0BsaW5rIEh1YkNvbm5lY3Rpb259IHRvIHRoZSBzZXJ2ZXIuICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24uYmFzZVVybCB8fCBcIlwiO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2V0cyBhIG5ldyB1cmwgZm9yIHRoZSBIdWJDb25uZWN0aW9uLiBOb3RlIHRoYXQgdGhlIHVybCBjYW4gb25seSBiZSBjaGFuZ2VkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgaW4gZWl0aGVyIHRoZSBEaXNjb25uZWN0ZWQgb3JcclxuICAgICAgICAgKiBSZWNvbm5lY3Rpbmcgc3RhdGVzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIHVybCB0byBjb25uZWN0IHRvLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHNldDogZnVuY3Rpb24gKHVybCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgIT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5EaXNjb25uZWN0ZWQgJiYgdGhpcy5jb25uZWN0aW9uU3RhdGUgIT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5SZWNvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBIdWJDb25uZWN0aW9uIG11c3QgYmUgaW4gdGhlIERpc2Nvbm5lY3RlZCBvciBSZWNvbm5lY3Rpbmcgc3RhdGUgdG8gY2hhbmdlIHRoZSB1cmwuXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghdXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgSHViQ29ubmVjdGlvbiB1cmwgbXVzdCBiZSBhIHZhbGlkIHVybC5cIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmJhc2VVcmwgPSB1cmw7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICAvKiogU3RhcnRzIHRoZSBjb25uZWN0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjb25uZWN0aW9uIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBlc3RhYmxpc2hlZCwgb3IgcmVqZWN0cyB3aXRoIGFuIGVycm9yLlxyXG4gICAgICovXHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnN0YXJ0UHJvbWlzZSA9IHRoaXMuc3RhcnRXaXRoU3RhdGVUcmFuc2l0aW9ucygpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0UHJvbWlzZTtcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zdGFydFdpdGhTdGF0ZVRyYW5zaXRpb25zID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGVfMTtcclxuICAgICAgICAgICAgcmV0dXJuIF9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYS5sYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlICE9PSBIdWJDb25uZWN0aW9uU3RhdGUuRGlzY29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQ2Fubm90IHN0YXJ0IGEgSHViQ29ubmVjdGlvbiB0aGF0IGlzIG5vdCBpbiB0aGUgJ0Rpc2Nvbm5lY3RlZCcgc3RhdGUuXCIpKV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUgPSBIdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJTdGFydGluZyBIdWJDb25uZWN0aW9uLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EudHJ5cy5wdXNoKFsxLCAzLCAsIDRdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5zdGFydEludGVybmFsKCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9IEh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXJ0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIkh1YkNvbm5lY3Rpb24gY29ubmVjdGVkIHN1Y2Nlc3NmdWxseS5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDRdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZV8xID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9IEh1YkNvbm5lY3Rpb25TdGF0ZS5EaXNjb25uZWN0ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiSHViQ29ubmVjdGlvbiBmYWlsZWQgdG8gc3RhcnQgc3VjY2Vzc2Z1bGx5IGJlY2F1c2Ugb2YgZXJyb3IgJ1wiICsgZV8xICsgXCInLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFByb21pc2UucmVqZWN0KGVfMSldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDogcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zdGFydEludGVybmFsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGhhbmRzaGFrZVByb21pc2UsIGhhbmRzaGFrZVJlcXVlc3QsIGVfMjtcclxuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAgICAgcmV0dXJuIF9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYS5sYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9wRHVyaW5nU3RhcnRFcnJvciA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWNlaXZlZEhhbmRzaGFrZVJlc3BvbnNlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRzaGFrZVByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5oYW5kc2hha2VSZXNvbHZlciA9IHJlc29sdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5oYW5kc2hha2VSZWplY3RlciA9IHJlamVjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuY29ubmVjdGlvbi5zdGFydCh0aGlzLnByb3RvY29sLnRyYW5zZmVyRm9ybWF0KV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnRyeXMucHVzaChbMiwgNSwgLCA3XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRzaGFrZVJlcXVlc3QgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2NvbDogdGhpcy5wcm90b2NvbC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbjogdGhpcy5wcm90b2NvbC52ZXJzaW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIlNlbmRpbmcgaGFuZHNoYWtlIHJlcXVlc3QuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLnNlbmRNZXNzYWdlKHRoaXMuaGFuZHNoYWtlUHJvdG9jb2wud3JpdGVIYW5kc2hha2VSZXF1ZXN0KGhhbmRzaGFrZVJlcXVlc3QpKV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sIFwiVXNpbmcgSHViUHJvdG9jb2wgJ1wiICsgdGhpcy5wcm90b2NvbC5uYW1lICsgXCInLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmZW5zaXZlbHkgY2xlYW51cCB0aW1lb3V0IGluIGNhc2Ugd2UgcmVjZWl2ZSBhIG1lc3NhZ2UgZnJvbSB0aGUgc2VydmVyIGJlZm9yZSB3ZSBmaW5pc2ggc3RhcnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhbnVwVGltZW91dCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0VGltZW91dFBlcmlvZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0S2VlcEFsaXZlSW50ZXJ2YWwoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgaGFuZHNoYWtlUHJvbWlzZV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEl0J3MgaW1wb3J0YW50IHRvIGNoZWNrIHRoZSBzdG9wRHVyaW5nU3RhcnRFcnJvciBpbnN0ZWFkIG9mIGp1c3QgcmVseWluZyBvbiB0aGUgaGFuZHNoYWtlUHJvbWlzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWluZyByZWplY3RlZCBvbiBjbG9zZSwgYmVjYXVzZSB0aGlzIGNvbnRpbnVhdGlvbiBjYW4gcnVuIGFmdGVyIGJvdGggdGhlIGhhbmRzaGFrZSBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgY29ubmVjdGlvbiB3YXMgY2xvc2VkLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdG9wRHVyaW5nU3RhcnRFcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXQncyBpbXBvcnRhbnQgdG8gdGhyb3cgaW5zdGVhZCBvZiByZXR1cm5pbmcgYSByZWplY3RlZCBwcm9taXNlLCBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gYWxsb3cgYW55IHN0YXRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cmFuc2l0aW9ucyB0byBvY2N1ciBiZXR3ZWVuIG5vdyBhbmQgdGhlIGNhbGxpbmcgY29kZSBvYnNlcnZpbmcgdGhlIGV4Y2VwdGlvbnMuIFJldHVybmluZyBhIHJlamVjdGVkIHByb21pc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgY2F1c2UgdGhlIGNhbGxpbmcgY29udGludWF0aW9uIHRvIGdldCBzY2hlZHVsZWQgdG8gcnVuIGxhdGVyLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgdGhpcy5zdG9wRHVyaW5nU3RhcnRFcnJvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA3XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVfMiA9IF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJIdWIgaGFuZHNoYWtlIGZhaWxlZCB3aXRoIGVycm9yICdcIiArIGVfMiArIFwiJyBkdXJpbmcgc3RhcnQoKS4gU3RvcHBpbmcgSHViQ29ubmVjdGlvbi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYW51cFRpbWVvdXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhbnVwUGluZ1RpbWVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEh0dHBDb25uZWN0aW9uLnN0b3AoKSBzaG91bGQgbm90IGNvbXBsZXRlIHVudGlsIGFmdGVyIHRoZSBvbmNsb3NlIGNhbGxiYWNrIGlzIGludm9rZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgd2lsbCB0cmFuc2l0aW9uIHRoZSBIdWJDb25uZWN0aW9uIHRvIHRoZSBkaXNjb25uZWN0ZWQgc3RhdGUgYmVmb3JlIEh0dHBDb25uZWN0aW9uLnN0b3AoKSBjb21wbGV0ZXMuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuY29ubmVjdGlvbi5zdG9wKGVfMildO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSHR0cENvbm5lY3Rpb24uc3RvcCgpIHNob3VsZCBub3QgY29tcGxldGUgdW50aWwgYWZ0ZXIgdGhlIG9uY2xvc2UgY2FsbGJhY2sgaXMgaW52b2tlZC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB3aWxsIHRyYW5zaXRpb24gdGhlIEh1YkNvbm5lY3Rpb24gdG8gdGhlIGRpc2Nvbm5lY3RlZCBzdGF0ZSBiZWZvcmUgSHR0cENvbm5lY3Rpb24uc3RvcCgpIGNvbXBsZXRlcy5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlXzI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIC8qKiBTdG9wcyB0aGUgY29ubmVjdGlvbi5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgdGVybWluYXRlZCwgb3IgcmVqZWN0cyB3aXRoIGFuIGVycm9yLlxyXG4gICAgICovXHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHN0YXJ0UHJvbWlzZSwgZV8zO1xyXG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9hKSB7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKF9hLmxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydFByb21pc2UgPSB0aGlzLnN0YXJ0UHJvbWlzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9wUHJvbWlzZSA9IHRoaXMuc3RvcEludGVybmFsKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuc3RvcFByb21pc2VdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5sYWJlbCA9IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS50cnlzLnB1c2goWzIsIDQsICwgNV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBd2FpdGluZyB1bmRlZmluZWQgY29udGludWVzIGltbWVkaWF0ZWx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHN0YXJ0UHJvbWlzZV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBd2FpdGluZyB1bmRlZmluZWQgY29udGludWVzIGltbWVkaWF0ZWx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFszIC8qYnJlYWsqLywgNV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlXzMgPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDVdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNTogcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zdG9wSW50ZXJuYWwgPSBmdW5jdGlvbiAoZXJyb3IpIHtcclxuICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgPT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5EaXNjb25uZWN0ZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJDYWxsIHRvIEh1YkNvbm5lY3Rpb24uc3RvcChcIiArIGVycm9yICsgXCIpIGlnbm9yZWQgYmVjYXVzZSBpdCBpcyBhbHJlYWR5IGluIHRoZSBkaXNjb25uZWN0ZWQgc3RhdGUuXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9PT0gSHViQ29ubmVjdGlvblN0YXRlLkRpc2Nvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJDYWxsIHRvIEh0dHBDb25uZWN0aW9uLnN0b3AoXCIgKyBlcnJvciArIFwiKSBpZ25vcmVkIGJlY2F1c2UgdGhlIGNvbm5lY3Rpb24gaXMgYWxyZWFkeSBpbiB0aGUgZGlzY29ubmVjdGluZyBzdGF0ZS5cIik7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0b3BQcm9taXNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9IEh1YkNvbm5lY3Rpb25TdGF0ZS5EaXNjb25uZWN0aW5nO1xyXG4gICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiU3RvcHBpbmcgSHViQ29ubmVjdGlvbi5cIik7XHJcbiAgICAgICAgaWYgKHRoaXMucmVjb25uZWN0RGVsYXlIYW5kbGUpIHtcclxuICAgICAgICAgICAgLy8gV2UncmUgaW4gYSByZWNvbm5lY3QgZGVsYXkgd2hpY2ggbWVhbnMgdGhlIHVuZGVybHlpbmcgY29ubmVjdGlvbiBpcyBjdXJyZW50bHkgYWxyZWFkeSBzdG9wcGVkLlxyXG4gICAgICAgICAgICAvLyBKdXN0IGNsZWFyIHRoZSBoYW5kbGUgdG8gc3RvcCB0aGUgcmVjb25uZWN0IGxvb3AgKHdoaWNoIG5vIG9uZSBpcyB3YWl0aW5nIG9uIHRoYW5rZnVsbHkpIGFuZFxyXG4gICAgICAgICAgICAvLyBmaXJlIHRoZSBvbmNsb3NlIGNhbGxiYWNrcy5cclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5EZWJ1ZywgXCJDb25uZWN0aW9uIHN0b3BwZWQgZHVyaW5nIHJlY29ubmVjdCBkZWxheS4gRG9uZSByZWNvbm5lY3RpbmcuXCIpO1xyXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5yZWNvbm5lY3REZWxheUhhbmRsZSk7XHJcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0RGVsYXlIYW5kbGUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcGxldGVDbG9zZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY2xlYW51cFRpbWVvdXQoKTtcclxuICAgICAgICB0aGlzLmNsZWFudXBQaW5nVGltZXIoKTtcclxuICAgICAgICB0aGlzLnN0b3BEdXJpbmdTdGFydEVycm9yID0gZXJyb3IgfHwgbmV3IEVycm9yKFwiVGhlIGNvbm5lY3Rpb24gd2FzIHN0b3BwZWQgYmVmb3JlIHRoZSBodWIgaGFuZHNoYWtlIGNvdWxkIGNvbXBsZXRlLlwiKTtcclxuICAgICAgICAvLyBIdHRwQ29ubmVjdGlvbi5zdG9wKCkgc2hvdWxkIG5vdCBjb21wbGV0ZSB1bnRpbCBhZnRlciBlaXRoZXIgSHR0cENvbm5lY3Rpb24uc3RhcnQoKSBmYWlsc1xyXG4gICAgICAgIC8vIG9yIHRoZSBvbmNsb3NlIGNhbGxiYWNrIGlzIGludm9rZWQuIFRoZSBvbmNsb3NlIGNhbGxiYWNrIHdpbGwgdHJhbnNpdGlvbiB0aGUgSHViQ29ubmVjdGlvblxyXG4gICAgICAgIC8vIHRvIHRoZSBkaXNjb25uZWN0ZWQgc3RhdGUgaWYgbmVlZCBiZSBiZWZvcmUgSHR0cENvbm5lY3Rpb24uc3RvcCgpIGNvbXBsZXRlcy5cclxuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uLnN0b3AoZXJyb3IpO1xyXG4gICAgfTtcclxuICAgIC8qKiBJbnZva2VzIGEgc3RyZWFtaW5nIGh1YiBtZXRob2Qgb24gdGhlIHNlcnZlciB1c2luZyB0aGUgc3BlY2lmaWVkIG5hbWUgYW5kIGFyZ3VtZW50cy5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZXBhcmFtIFQgVGhlIHR5cGUgb2YgdGhlIGl0ZW1zIHJldHVybmVkIGJ5IHRoZSBzZXJ2ZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgc2VydmVyIG1ldGhvZCB0byBpbnZva2UuXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIFRoZSBhcmd1bWVudHMgdXNlZCB0byBpbnZva2UgdGhlIHNlcnZlciBtZXRob2QuXHJcbiAgICAgKiBAcmV0dXJucyB7SVN0cmVhbVJlc3VsdDxUPn0gQW4gb2JqZWN0IHRoYXQgeWllbGRzIHJlc3VsdHMgZnJvbSB0aGUgc2VydmVyIGFzIHRoZXkgYXJlIHJlY2VpdmVkLlxyXG4gICAgICovXHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zdHJlYW0gPSBmdW5jdGlvbiAobWV0aG9kTmFtZSkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICBhcmdzW19pIC0gMV0gPSBhcmd1bWVudHNbX2ldO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgX2EgPSB0aGlzLnJlcGxhY2VTdHJlYW1pbmdQYXJhbXMoYXJncyksIHN0cmVhbXMgPSBfYVswXSwgc3RyZWFtSWRzID0gX2FbMV07XHJcbiAgICAgICAgdmFyIGludm9jYXRpb25EZXNjcmlwdG9yID0gdGhpcy5jcmVhdGVTdHJlYW1JbnZvY2F0aW9uKG1ldGhvZE5hbWUsIGFyZ3MsIHN0cmVhbUlkcyk7XHJcbiAgICAgICAgdmFyIHByb21pc2VRdWV1ZTtcclxuICAgICAgICB2YXIgc3ViamVjdCA9IG5ldyBTdWJqZWN0XzEuU3ViamVjdCgpO1xyXG4gICAgICAgIHN1YmplY3QuY2FuY2VsQ2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBjYW5jZWxJbnZvY2F0aW9uID0gX3RoaXMuY3JlYXRlQ2FuY2VsSW52b2NhdGlvbihpbnZvY2F0aW9uRGVzY3JpcHRvci5pbnZvY2F0aW9uSWQpO1xyXG4gICAgICAgICAgICBkZWxldGUgX3RoaXMuY2FsbGJhY2tzW2ludm9jYXRpb25EZXNjcmlwdG9yLmludm9jYXRpb25JZF07XHJcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUXVldWUudGhlbihmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuc2VuZFdpdGhQcm90b2NvbChjYW5jZWxJbnZvY2F0aW9uKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrc1tpbnZvY2F0aW9uRGVzY3JpcHRvci5pbnZvY2F0aW9uSWRdID0gZnVuY3Rpb24gKGludm9jYXRpb25FdmVudCwgZXJyb3IpIHtcclxuICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBzdWJqZWN0LmVycm9yKGVycm9yKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChpbnZvY2F0aW9uRXZlbnQpIHtcclxuICAgICAgICAgICAgICAgIC8vIGludm9jYXRpb25FdmVudCB3aWxsIG5vdCBiZSBudWxsIHdoZW4gYW4gZXJyb3IgaXMgbm90IHBhc3NlZCB0byB0aGUgY2FsbGJhY2tcclxuICAgICAgICAgICAgICAgIGlmIChpbnZvY2F0aW9uRXZlbnQudHlwZSA9PT0gSUh1YlByb3RvY29sXzEuTWVzc2FnZVR5cGUuQ29tcGxldGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnZvY2F0aW9uRXZlbnQuZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3ViamVjdC5lcnJvcihuZXcgRXJyb3IoaW52b2NhdGlvbkV2ZW50LmVycm9yKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWJqZWN0LmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3ViamVjdC5uZXh0KChpbnZvY2F0aW9uRXZlbnQuaXRlbSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwcm9taXNlUXVldWUgPSB0aGlzLnNlbmRXaXRoUHJvdG9jb2woaW52b2NhdGlvbkRlc2NyaXB0b3IpXHJcbiAgICAgICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBzdWJqZWN0LmVycm9yKGUpO1xyXG4gICAgICAgICAgICBkZWxldGUgX3RoaXMuY2FsbGJhY2tzW2ludm9jYXRpb25EZXNjcmlwdG9yLmludm9jYXRpb25JZF07XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5sYXVuY2hTdHJlYW1zKHN0cmVhbXMsIHByb21pc2VRdWV1ZSk7XHJcbiAgICAgICAgcmV0dXJuIHN1YmplY3Q7XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuc2VuZE1lc3NhZ2UgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMucmVzZXRLZWVwQWxpdmVJbnRlcnZhbCgpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24uc2VuZChtZXNzYWdlKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNlbmRzIGEganMgb2JqZWN0IHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUganMgb2JqZWN0IHRvIHNlcmlhbGl6ZSBhbmQgc2VuZC5cclxuICAgICAqL1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuc2VuZFdpdGhQcm90b2NvbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZE1lc3NhZ2UodGhpcy5wcm90b2NvbC53cml0ZU1lc3NhZ2UobWVzc2FnZSkpO1xyXG4gICAgfTtcclxuICAgIC8qKiBJbnZva2VzIGEgaHViIG1ldGhvZCBvbiB0aGUgc2VydmVyIHVzaW5nIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQgYXJndW1lbnRzLiBEb2VzIG5vdCB3YWl0IGZvciBhIHJlc3BvbnNlIGZyb20gdGhlIHJlY2VpdmVyLlxyXG4gICAgICpcclxuICAgICAqIFRoZSBQcm9taXNlIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIHJlc29sdmVzIHdoZW4gdGhlIGNsaWVudCBoYXMgc2VudCB0aGUgaW52b2NhdGlvbiB0byB0aGUgc2VydmVyLiBUaGUgc2VydmVyIG1heSBzdGlsbFxyXG4gICAgICogYmUgcHJvY2Vzc2luZyB0aGUgaW52b2NhdGlvbi5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgc2VydmVyIG1ldGhvZCB0byBpbnZva2UuXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIFRoZSBhcmd1bWVudHMgdXNlZCB0byBpbnZva2UgdGhlIHNlcnZlciBtZXRob2QuXHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgaW52b2NhdGlvbiBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgc2VudCwgb3IgcmVqZWN0cyB3aXRoIGFuIGVycm9yLlxyXG4gICAgICovXHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcclxuICAgICAgICB2YXIgYXJncyA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIF9pID0gMTsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIGFyZ3NbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBfYSA9IHRoaXMucmVwbGFjZVN0cmVhbWluZ1BhcmFtcyhhcmdzKSwgc3RyZWFtcyA9IF9hWzBdLCBzdHJlYW1JZHMgPSBfYVsxXTtcclxuICAgICAgICB2YXIgc2VuZFByb21pc2UgPSB0aGlzLnNlbmRXaXRoUHJvdG9jb2wodGhpcy5jcmVhdGVJbnZvY2F0aW9uKG1ldGhvZE5hbWUsIGFyZ3MsIHRydWUsIHN0cmVhbUlkcykpO1xyXG4gICAgICAgIHRoaXMubGF1bmNoU3RyZWFtcyhzdHJlYW1zLCBzZW5kUHJvbWlzZSk7XHJcbiAgICAgICAgcmV0dXJuIHNlbmRQcm9taXNlO1xyXG4gICAgfTtcclxuICAgIC8qKiBJbnZva2VzIGEgaHViIG1ldGhvZCBvbiB0aGUgc2VydmVyIHVzaW5nIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQgYXJndW1lbnRzLlxyXG4gICAgICpcclxuICAgICAqIFRoZSBQcm9taXNlIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIHJlc29sdmVzIHdoZW4gdGhlIHNlcnZlciBpbmRpY2F0ZXMgaXQgaGFzIGZpbmlzaGVkIGludm9raW5nIHRoZSBtZXRob2QuIFdoZW4gdGhlIHByb21pc2VcclxuICAgICAqIHJlc29sdmVzLCB0aGUgc2VydmVyIGhhcyBmaW5pc2hlZCBpbnZva2luZyB0aGUgbWV0aG9kLiBJZiB0aGUgc2VydmVyIG1ldGhvZCByZXR1cm5zIGEgcmVzdWx0LCBpdCBpcyBwcm9kdWNlZCBhcyB0aGUgcmVzdWx0IG9mXHJcbiAgICAgKiByZXNvbHZpbmcgdGhlIFByb21pc2UuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGVwYXJhbSBUIFRoZSBleHBlY3RlZCByZXR1cm4gdHlwZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2ROYW1lIFRoZSBuYW1lIG9mIHRoZSBzZXJ2ZXIgbWV0aG9kIHRvIGludm9rZS5cclxuICAgICAqIEBwYXJhbSB7YW55W119IGFyZ3MgVGhlIGFyZ3VtZW50cyB1c2VkIHRvIGludm9rZSB0aGUgc2VydmVyIG1ldGhvZC5cclxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSByZXN1bHQgb2YgdGhlIHNlcnZlciBtZXRob2QgKGlmIGFueSksIG9yIHJlamVjdHMgd2l0aCBhbiBlcnJvci5cclxuICAgICAqL1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuaW52b2tlID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBhcmdzID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAxOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgYXJnc1tfaSAtIDFdID0gYXJndW1lbnRzW19pXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIF9hID0gdGhpcy5yZXBsYWNlU3RyZWFtaW5nUGFyYW1zKGFyZ3MpLCBzdHJlYW1zID0gX2FbMF0sIHN0cmVhbUlkcyA9IF9hWzFdO1xyXG4gICAgICAgIHZhciBpbnZvY2F0aW9uRGVzY3JpcHRvciA9IHRoaXMuY3JlYXRlSW52b2NhdGlvbihtZXRob2ROYW1lLCBhcmdzLCBmYWxzZSwgc3RyZWFtSWRzKTtcclxuICAgICAgICB2YXIgcCA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgLy8gaW52b2NhdGlvbklkIHdpbGwgYWx3YXlzIGhhdmUgYSB2YWx1ZSBmb3IgYSBub24tYmxvY2tpbmcgaW52b2NhdGlvblxyXG4gICAgICAgICAgICBfdGhpcy5jYWxsYmFja3NbaW52b2NhdGlvbkRlc2NyaXB0b3IuaW52b2NhdGlvbklkXSA9IGZ1bmN0aW9uIChpbnZvY2F0aW9uRXZlbnQsIGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGludm9jYXRpb25FdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGludm9jYXRpb25FdmVudCB3aWxsIG5vdCBiZSBudWxsIHdoZW4gYW4gZXJyb3IgaXMgbm90IHBhc3NlZCB0byB0aGUgY2FsbGJhY2tcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW52b2NhdGlvbkV2ZW50LnR5cGUgPT09IElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLkNvbXBsZXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludm9jYXRpb25FdmVudC5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihpbnZvY2F0aW9uRXZlbnQuZXJyb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoaW52b2NhdGlvbkV2ZW50LnJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIG1lc3NhZ2UgdHlwZTogXCIgKyBpbnZvY2F0aW9uRXZlbnQudHlwZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdmFyIHByb21pc2VRdWV1ZSA9IF90aGlzLnNlbmRXaXRoUHJvdG9jb2woaW52b2NhdGlvbkRlc2NyaXB0b3IpXHJcbiAgICAgICAgICAgICAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgICAgIC8vIGludm9jYXRpb25JZCB3aWxsIGFsd2F5cyBoYXZlIGEgdmFsdWUgZm9yIGEgbm9uLWJsb2NraW5nIGludm9jYXRpb25cclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBfdGhpcy5jYWxsYmFja3NbaW52b2NhdGlvbkRlc2NyaXB0b3IuaW52b2NhdGlvbklkXTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIF90aGlzLmxhdW5jaFN0cmVhbXMoc3RyZWFtcywgcHJvbWlzZVF1ZXVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gcDtcclxuICAgIH07XHJcbiAgICAvKiogUmVnaXN0ZXJzIGEgaGFuZGxlciB0aGF0IHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSBodWIgbWV0aG9kIHdpdGggdGhlIHNwZWNpZmllZCBtZXRob2QgbmFtZSBpcyBpbnZva2VkLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2ROYW1lIFRoZSBuYW1lIG9mIHRoZSBodWIgbWV0aG9kIHRvIGRlZmluZS5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG5ld01ldGhvZCBUaGUgaGFuZGxlciB0aGF0IHdpbGwgYmUgcmFpc2VkIHdoZW4gdGhlIGh1YiBtZXRob2QgaXMgaW52b2tlZC5cclxuICAgICAqL1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAobWV0aG9kTmFtZSwgbmV3TWV0aG9kKSB7XHJcbiAgICAgICAgaWYgKCFtZXRob2ROYW1lIHx8ICFuZXdNZXRob2QpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBtZXRob2ROYW1lID0gbWV0aG9kTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIGlmICghdGhpcy5tZXRob2RzW21ldGhvZE5hbWVdKSB7XHJcbiAgICAgICAgICAgIHRoaXMubWV0aG9kc1ttZXRob2ROYW1lXSA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBQcmV2ZW50aW5nIGFkZGluZyB0aGUgc2FtZSBoYW5kbGVyIG11bHRpcGxlIHRpbWVzLlxyXG4gICAgICAgIGlmICh0aGlzLm1ldGhvZHNbbWV0aG9kTmFtZV0uaW5kZXhPZihuZXdNZXRob2QpICE9PSAtMSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubWV0aG9kc1ttZXRob2ROYW1lXS5wdXNoKG5ld01ldGhvZCk7XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUsIG1ldGhvZCkge1xyXG4gICAgICAgIGlmICghbWV0aG9kTmFtZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG1ldGhvZE5hbWUgPSBtZXRob2ROYW1lLnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgICAgdmFyIGhhbmRsZXJzID0gdGhpcy5tZXRob2RzW21ldGhvZE5hbWVdO1xyXG4gICAgICAgIGlmICghaGFuZGxlcnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobWV0aG9kKSB7XHJcbiAgICAgICAgICAgIHZhciByZW1vdmVJZHggPSBoYW5kbGVycy5pbmRleE9mKG1ldGhvZCk7XHJcbiAgICAgICAgICAgIGlmIChyZW1vdmVJZHggIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UocmVtb3ZlSWR4LCAxKTtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVycy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5tZXRob2RzW21ldGhvZE5hbWVdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5tZXRob2RzW21ldGhvZE5hbWVdO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKiogUmVnaXN0ZXJzIGEgaGFuZGxlciB0aGF0IHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGNsb3NlZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgaGFuZGxlciB0aGF0IHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGNsb3NlZC4gT3B0aW9uYWxseSByZWNlaXZlcyBhIHNpbmdsZSBhcmd1bWVudCBjb250YWluaW5nIHRoZSBlcnJvciB0aGF0IGNhdXNlZCB0aGUgY29ubmVjdGlvbiB0byBjbG9zZSAoaWYgYW55KS5cclxuICAgICAqL1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUub25jbG9zZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xyXG4gICAgICAgIGlmIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICB0aGlzLmNsb3NlZENhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqIFJlZ2lzdGVycyBhIGhhbmRsZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBzdGFydHMgcmVjb25uZWN0aW5nLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBoYW5kbGVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIHdoZW4gdGhlIGNvbm5lY3Rpb24gc3RhcnRzIHJlY29ubmVjdGluZy4gT3B0aW9uYWxseSByZWNlaXZlcyBhIHNpbmdsZSBhcmd1bWVudCBjb250YWluaW5nIHRoZSBlcnJvciB0aGF0IGNhdXNlZCB0aGUgY29ubmVjdGlvbiB0byBzdGFydCByZWNvbm5lY3RpbmcgKGlmIGFueSkuXHJcbiAgICAgKi9cclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLm9ucmVjb25uZWN0aW5nID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW5nQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKiogUmVnaXN0ZXJzIGEgaGFuZGxlciB0aGF0IHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSBjb25uZWN0aW9uIHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBoYW5kbGVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIHdoZW4gdGhlIGNvbm5lY3Rpb24gc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMuXHJcbiAgICAgKi9cclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLm9ucmVjb25uZWN0ZWQgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcclxuICAgICAgICBpZiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3RlZENhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUucHJvY2Vzc0luY29taW5nRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgdGhpcy5jbGVhbnVwVGltZW91dCgpO1xyXG4gICAgICAgIGlmICghdGhpcy5yZWNlaXZlZEhhbmRzaGFrZVJlc3BvbnNlKSB7XHJcbiAgICAgICAgICAgIGRhdGEgPSB0aGlzLnByb2Nlc3NIYW5kc2hha2VSZXNwb25zZShkYXRhKTtcclxuICAgICAgICAgICAgdGhpcy5yZWNlaXZlZEhhbmRzaGFrZVJlc3BvbnNlID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gRGF0YSBtYXkgaGF2ZSBhbGwgYmVlbiByZWFkIHdoZW4gcHJvY2Vzc2luZyBoYW5kc2hha2UgcmVzcG9uc2VcclxuICAgICAgICBpZiAoZGF0YSkge1xyXG4gICAgICAgICAgICAvLyBQYXJzZSB0aGUgbWVzc2FnZXNcclxuICAgICAgICAgICAgdmFyIG1lc3NhZ2VzID0gdGhpcy5wcm90b2NvbC5wYXJzZU1lc3NhZ2VzKGRhdGEsIHRoaXMubG9nZ2VyKTtcclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBtZXNzYWdlc18xID0gbWVzc2FnZXM7IF9pIDwgbWVzc2FnZXNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbWVzc2FnZXNfMVtfaV07XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKG1lc3NhZ2UudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgSUh1YlByb3RvY29sXzEuTWVzc2FnZVR5cGUuSW52b2NhdGlvbjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnZva2VDbGllbnRNZXRob2QobWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgSUh1YlByb3RvY29sXzEuTWVzc2FnZVR5cGUuU3RyZWFtSXRlbTpcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLkNvbXBsZXRpb246XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IHRoaXMuY2FsbGJhY2tzW21lc3NhZ2UuaW52b2NhdGlvbklkXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS50eXBlID09PSBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5Db21wbGV0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW21lc3NhZ2UuaW52b2NhdGlvbklkXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgSUh1YlByb3RvY29sXzEuTWVzc2FnZVR5cGUuUGluZzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgY2FyZSBhYm91dCBwaW5nc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLkNsb3NlOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkluZm9ybWF0aW9uLCBcIkNsb3NlIG1lc3NhZ2UgcmVjZWl2ZWQgZnJvbSBzZXJ2ZXIuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBtZXNzYWdlLmVycm9yID8gbmV3IEVycm9yKFwiU2VydmVyIHJldHVybmVkIGFuIGVycm9yIG9uIGNsb3NlOiBcIiArIG1lc3NhZ2UuZXJyb3IpIDogdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5hbGxvd1JlY29ubmVjdCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXQgZmVlbHMgd3Jvbmcgbm90IHRvIGF3YWl0IGNvbm5lY3Rpb24uc3RvcCgpIGhlcmUsIGJ1dCBwcm9jZXNzSW5jb21pbmdEYXRhIGlzIGNhbGxlZCBhcyBwYXJ0IG9mIGFuIG9ucmVjZWl2ZSBjYWxsYmFjayB3aGljaCBpcyBub3QgYXN5bmMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGFscmVhZHkgdGhlIGJlaGF2aW9yIGZvciBzZXJ2ZXJUaW1lb3V0KCksIGFuZCBIdHRwQ29ubmVjdGlvbi5TdG9wKCkgc2hvdWxkIGNhdGNoIGFuZCBsb2cgYWxsIHBvc3NpYmxlIGV4Y2VwdGlvbnMuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZmxvYXRpbmctcHJvbWlzZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdG9wKGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGNhbm5vdCBhd2FpdCBzdG9wSW50ZXJuYWwoKSBoZXJlLCBidXQgc3Vic2VxdWVudCBjYWxscyB0byBzdG9wKCkgd2lsbCBhd2FpdCB0aGlzIGlmIHN0b3BJbnRlcm5hbCgpIGlzIHN0aWxsIG9uZ29pbmcuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3BQcm9taXNlID0gdGhpcy5zdG9wSW50ZXJuYWwoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuV2FybmluZywgXCJJbnZhbGlkIG1lc3NhZ2UgdHlwZTogXCIgKyBtZXNzYWdlLnR5cGUgKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucmVzZXRUaW1lb3V0UGVyaW9kKCk7XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUucHJvY2Vzc0hhbmRzaGFrZVJlc3BvbnNlID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICB2YXIgX2E7XHJcbiAgICAgICAgdmFyIHJlc3BvbnNlTWVzc2FnZTtcclxuICAgICAgICB2YXIgcmVtYWluaW5nRGF0YTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBfYSA9IHRoaXMuaGFuZHNoYWtlUHJvdG9jb2wucGFyc2VIYW5kc2hha2VSZXNwb25zZShkYXRhKSwgcmVtYWluaW5nRGF0YSA9IF9hWzBdLCByZXNwb25zZU1lc3NhZ2UgPSBfYVsxXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBcIkVycm9yIHBhcnNpbmcgaGFuZHNoYWtlIHJlc3BvbnNlOiBcIiArIGU7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZHNoYWtlUmVqZWN0ZXIoZXJyb3IpO1xyXG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlc3BvbnNlTWVzc2FnZS5lcnJvcikge1xyXG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IFwiU2VydmVyIHJldHVybmVkIGhhbmRzaGFrZSBlcnJvcjogXCIgKyByZXNwb25zZU1lc3NhZ2UuZXJyb3I7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZHNoYWtlUmVqZWN0ZXIoZXJyb3IpO1xyXG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiU2VydmVyIGhhbmRzaGFrZSBjb21wbGV0ZS5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuaGFuZHNoYWtlUmVzb2x2ZXIoKTtcclxuICAgICAgICByZXR1cm4gcmVtYWluaW5nRGF0YTtcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5yZXNldEtlZXBBbGl2ZUludGVydmFsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbi5mZWF0dXJlcy5pbmhlcmVudEtlZXBBbGl2ZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY2xlYW51cFBpbmdUaW1lcigpO1xyXG4gICAgICAgIHRoaXMucGluZ1NlcnZlckhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyByZXR1cm4gX19hd2FpdGVyKF90aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgX2E7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2IpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2IubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHRoaXMuY29ubmVjdGlvblN0YXRlID09PSBIdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkKSkgcmV0dXJuIFszIC8qYnJlYWsqLywgNF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLnRyeXMucHVzaChbMSwgMywgLCA0XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuc2VuZE1lc3NhZ2UodGhpcy5jYWNoZWRQaW5nTWVzc2FnZSldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Iuc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA0XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hID0gX2Iuc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCBjYXJlIGFib3V0IHRoZSBlcnJvci4gSXQgc2hvdWxkIGJlIHNlZW4gZWxzZXdoZXJlIGluIHRoZSBjbGllbnQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjb25uZWN0aW9uIGlzIHByb2JhYmx5IGluIGEgYmFkIG9yIGNsb3NlZCBzdGF0ZSBub3csIGNsZWFudXAgdGhlIHRpbWVyIHNvIGl0IHN0b3BzIHRyaWdnZXJpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhbnVwUGluZ1RpbWVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDRdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDogcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTsgfSwgdGhpcy5rZWVwQWxpdmVJbnRlcnZhbEluTWlsbGlzZWNvbmRzKTtcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5yZXNldFRpbWVvdXRQZXJpb2QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAoIXRoaXMuY29ubmVjdGlvbi5mZWF0dXJlcyB8fCAhdGhpcy5jb25uZWN0aW9uLmZlYXR1cmVzLmluaGVyZW50S2VlcEFsaXZlKSB7XHJcbiAgICAgICAgICAgIC8vIFNldCB0aGUgdGltZW91dCB0aW1lclxyXG4gICAgICAgICAgICB0aGlzLnRpbWVvdXRIYW5kbGUgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgcmV0dXJuIF90aGlzLnNlcnZlclRpbWVvdXQoKTsgfSwgdGhpcy5zZXJ2ZXJUaW1lb3V0SW5NaWxsaXNlY29uZHMpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5zZXJ2ZXJUaW1lb3V0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIFRoZSBzZXJ2ZXIgaGFzbid0IHRhbGtlZCB0byB1cyBpbiBhIHdoaWxlLiBJdCBkb2Vzbid0IGxpa2UgdXMgYW55bW9yZSAuLi4gOihcclxuICAgICAgICAvLyBUZXJtaW5hdGUgdGhlIGNvbm5lY3Rpb24sIGJ1dCB3ZSBkb24ndCBuZWVkIHRvIHdhaXQgb24gdGhlIHByb21pc2UuIFRoaXMgY291bGQgdHJpZ2dlciByZWNvbm5lY3RpbmcuXHJcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWZsb2F0aW5nLXByb21pc2VzXHJcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uLnN0b3AobmV3IEVycm9yKFwiU2VydmVyIHRpbWVvdXQgZWxhcHNlZCB3aXRob3V0IHJlY2VpdmluZyBhIG1lc3NhZ2UgZnJvbSB0aGUgc2VydmVyLlwiKSk7XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuaW52b2tlQ2xpZW50TWV0aG9kID0gZnVuY3Rpb24gKGludm9jYXRpb25NZXNzYWdlKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgbWV0aG9kcyA9IHRoaXMubWV0aG9kc1tpbnZvY2F0aW9uTWVzc2FnZS50YXJnZXQudG9Mb3dlckNhc2UoKV07XHJcbiAgICAgICAgaWYgKG1ldGhvZHMpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIG1ldGhvZHMuZm9yRWFjaChmdW5jdGlvbiAobSkgeyByZXR1cm4gbS5hcHBseShfdGhpcywgaW52b2NhdGlvbk1lc3NhZ2UuYXJndW1lbnRzKTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsIFwiQSBjYWxsYmFjayBmb3IgdGhlIG1ldGhvZCBcIiArIGludm9jYXRpb25NZXNzYWdlLnRhcmdldC50b0xvd2VyQ2FzZSgpICsgXCIgdGhyZXcgZXJyb3IgJ1wiICsgZSArIFwiJy5cIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGludm9jYXRpb25NZXNzYWdlLmludm9jYXRpb25JZCkge1xyXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBub3Qgc3VwcG9ydGVkIGluIHYxLiBTbyB3ZSByZXR1cm4gYW4gZXJyb3IgdG8gYXZvaWQgYmxvY2tpbmcgdGhlIHNlcnZlciB3YWl0aW5nIGZvciB0aGUgcmVzcG9uc2UuXHJcbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZSA9IFwiU2VydmVyIHJlcXVlc3RlZCBhIHJlc3BvbnNlLCB3aGljaCBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgdmVyc2lvbiBvZiB0aGUgY2xpZW50LlwiO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCB3YW50IHRvIHdhaXQgb24gdGhlIHN0b3AgaXRzZWxmLlxyXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9wUHJvbWlzZSA9IHRoaXMuc3RvcEludGVybmFsKG5ldyBFcnJvcihtZXNzYWdlKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuV2FybmluZywgXCJObyBjbGllbnQgbWV0aG9kIHdpdGggdGhlIG5hbWUgJ1wiICsgaW52b2NhdGlvbk1lc3NhZ2UudGFyZ2V0ICsgXCInIGZvdW5kLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuY29ubmVjdGlvbkNsb3NlZCA9IGZ1bmN0aW9uIChlcnJvcikge1xyXG4gICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiSHViQ29ubmVjdGlvbi5jb25uZWN0aW9uQ2xvc2VkKFwiICsgZXJyb3IgKyBcIikgY2FsbGVkIHdoaWxlIGluIHN0YXRlIFwiICsgdGhpcy5jb25uZWN0aW9uU3RhdGUgKyBcIi5cIik7XHJcbiAgICAgICAgLy8gVHJpZ2dlcmluZyB0aGlzLmhhbmRzaGFrZVJlamVjdGVyIGlzIGluc3VmZmljaWVudCBiZWNhdXNlIGl0IGNvdWxkIGFscmVhZHkgYmUgcmVzb2x2ZWQgd2l0aG91dCB0aGUgY29udGludWF0aW9uIGhhdmluZyBydW4geWV0LlxyXG4gICAgICAgIHRoaXMuc3RvcER1cmluZ1N0YXJ0RXJyb3IgPSB0aGlzLnN0b3BEdXJpbmdTdGFydEVycm9yIHx8IGVycm9yIHx8IG5ldyBFcnJvcihcIlRoZSB1bmRlcmx5aW5nIGNvbm5lY3Rpb24gd2FzIGNsb3NlZCBiZWZvcmUgdGhlIGh1YiBoYW5kc2hha2UgY291bGQgY29tcGxldGUuXCIpO1xyXG4gICAgICAgIC8vIElmIHRoZSBoYW5kc2hha2UgaXMgaW4gcHJvZ3Jlc3MsIHN0YXJ0IHdpbGwgYmUgd2FpdGluZyBmb3IgdGhlIGhhbmRzaGFrZSBwcm9taXNlLCBzbyB3ZSBjb21wbGV0ZSBpdC5cclxuICAgICAgICAvLyBJZiBpdCBoYXMgYWxyZWFkeSBjb21wbGV0ZWQsIHRoaXMgc2hvdWxkIGp1c3Qgbm9vcC5cclxuICAgICAgICBpZiAodGhpcy5oYW5kc2hha2VSZXNvbHZlcikge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRzaGFrZVJlc29sdmVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY2FuY2VsQ2FsbGJhY2tzV2l0aEVycm9yKGVycm9yIHx8IG5ldyBFcnJvcihcIkludm9jYXRpb24gY2FuY2VsZWQgZHVlIHRvIHRoZSB1bmRlcmx5aW5nIGNvbm5lY3Rpb24gYmVpbmcgY2xvc2VkLlwiKSk7XHJcbiAgICAgICAgdGhpcy5jbGVhbnVwVGltZW91dCgpO1xyXG4gICAgICAgIHRoaXMuY2xlYW51cFBpbmdUaW1lcigpO1xyXG4gICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZSA9PT0gSHViQ29ubmVjdGlvblN0YXRlLkRpc2Nvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5jb21wbGV0ZUNsb3NlKGVycm9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgPT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQgJiYgdGhpcy5yZWNvbm5lY3RQb2xpY3kpIHtcclxuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWZsb2F0aW5nLXByb21pc2VzXHJcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0KGVycm9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgPT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5jb21wbGV0ZUNsb3NlKGVycm9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gSWYgbm9uZSBvZiB0aGUgYWJvdmUgaWYgY29uZGl0aW9ucyB3ZXJlIHRydWUgd2VyZSBjYWxsZWQgdGhlIEh1YkNvbm5lY3Rpb24gbXVzdCBiZSBpbiBlaXRoZXI6XHJcbiAgICAgICAgLy8gMS4gVGhlIENvbm5lY3Rpbmcgc3RhdGUgaW4gd2hpY2ggY2FzZSB0aGUgaGFuZHNoYWtlUmVzb2x2ZXIgd2lsbCBjb21wbGV0ZSBpdCBhbmQgc3RvcER1cmluZ1N0YXJ0RXJyb3Igd2lsbCBmYWlsIGl0LlxyXG4gICAgICAgIC8vIDIuIFRoZSBSZWNvbm5lY3Rpbmcgc3RhdGUgaW4gd2hpY2ggY2FzZSB0aGUgaGFuZHNoYWtlUmVzb2x2ZXIgd2lsbCBjb21wbGV0ZSBpdCBhbmQgc3RvcER1cmluZ1N0YXJ0RXJyb3Igd2lsbCBmYWlsIHRoZSBjdXJyZW50IHJlY29ubmVjdCBhdHRlbXB0XHJcbiAgICAgICAgLy8gICAgYW5kIHBvdGVudGlhbGx5IGNvbnRpbnVlIHRoZSByZWNvbm5lY3QoKSBsb29wLlxyXG4gICAgICAgIC8vIDMuIFRoZSBEaXNjb25uZWN0ZWQgc3RhdGUgaW4gd2hpY2ggY2FzZSB3ZSdyZSBhbHJlYWR5IGRvbmUuXHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuY29tcGxldGVDbG9zZSA9IGZ1bmN0aW9uIChlcnJvcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXJ0ZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUgPSBIdWJDb25uZWN0aW9uU3RhdGUuRGlzY29ubmVjdGVkO1xyXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGFydGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlZENhbGxiYWNrcy5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7IHJldHVybiBjLmFwcGx5KF90aGlzLCBbZXJyb3JdKTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsIFwiQW4gb25jbG9zZSBjYWxsYmFjayBjYWxsZWQgd2l0aCBlcnJvciAnXCIgKyBlcnJvciArIFwiJyB0aHJldyBlcnJvciAnXCIgKyBlICsgXCInLlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoZXJyb3IpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciByZWNvbm5lY3RTdGFydFRpbWUsIHByZXZpb3VzUmVjb25uZWN0QXR0ZW1wdHMsIHJldHJ5RXJyb3IsIG5leHRSZXRyeURlbGF5LCBlXzQ7XHJcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdFN0YXJ0VGltZSA9IERhdGUubm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzUmVjb25uZWN0QXR0ZW1wdHMgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXRyeUVycm9yID0gZXJyb3IgIT09IHVuZGVmaW5lZCA/IGVycm9yIDogbmV3IEVycm9yKFwiQXR0ZW1wdGluZyB0byByZWNvbm5lY3QgZHVlIHRvIGEgdW5rbm93biBlcnJvci5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRSZXRyeURlbGF5ID0gdGhpcy5nZXROZXh0UmV0cnlEZWxheShwcmV2aW91c1JlY29ubmVjdEF0dGVtcHRzKyssIDAsIHJldHJ5RXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFJldHJ5RGVsYXkgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiQ29ubmVjdGlvbiBub3QgcmVjb25uZWN0aW5nIGJlY2F1c2UgdGhlIElSZXRyeVBvbGljeSByZXR1cm5lZCBudWxsIG9uIHRoZSBmaXJzdCByZWNvbm5lY3QgYXR0ZW1wdC5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBsZXRlQ2xvc2UoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlID0gSHViQ29ubmVjdGlvblN0YXRlLlJlY29ubmVjdGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkluZm9ybWF0aW9uLCBcIkNvbm5lY3Rpb24gcmVjb25uZWN0aW5nIGJlY2F1c2Ugb2YgZXJyb3IgJ1wiICsgZXJyb3IgKyBcIicuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5JbmZvcm1hdGlvbiwgXCJDb25uZWN0aW9uIHJlY29ubmVjdGluZy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25yZWNvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3RpbmdDYWxsYmFja3MuZm9yRWFjaChmdW5jdGlvbiAoYykgeyByZXR1cm4gYy5hcHBseShfdGhpcywgW2Vycm9yXSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkVycm9yLCBcIkFuIG9ucmVjb25uZWN0aW5nIGNhbGxiYWNrIGNhbGxlZCB3aXRoIGVycm9yICdcIiArIGVycm9yICsgXCInIHRocmV3IGVycm9yICdcIiArIGUgKyBcIicuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXhpdCBlYXJseSBpZiBhbiBvbnJlY29ubmVjdGluZyBjYWxsYmFjayBjYWxsZWQgY29ubmVjdGlvbi5zdG9wKCkuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgIT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5SZWNvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkRlYnVnLCBcIkNvbm5lY3Rpb24gbGVmdCB0aGUgcmVjb25uZWN0aW5nIHN0YXRlIGluIG9ucmVjb25uZWN0aW5nIGNhbGxiYWNrLiBEb25lIHJlY29ubmVjdGluZy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG5leHRSZXRyeURlbGF5ICE9PSBudWxsKSkgcmV0dXJuIFszIC8qYnJlYWsqLywgN107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sIFwiUmVjb25uZWN0IGF0dGVtcHQgbnVtYmVyIFwiICsgcHJldmlvdXNSZWNvbm5lY3RBdHRlbXB0cyArIFwiIHdpbGwgc3RhcnQgaW4gXCIgKyBuZXh0UmV0cnlEZWxheSArIFwiIG1zLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5yZWNvbm5lY3REZWxheUhhbmRsZSA9IHNldFRpbWVvdXQocmVzb2x2ZSwgbmV4dFJldHJ5RGVsYXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdERlbGF5SGFuZGxlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgIT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5SZWNvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiQ29ubmVjdGlvbiBsZWZ0IHRoZSByZWNvbm5lY3Rpbmcgc3RhdGUgZHVyaW5nIHJlY29ubmVjdCBkZWxheS4gRG9uZSByZWNvbm5lY3RpbmcuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLmxhYmVsID0gMztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnRyeXMucHVzaChbMywgNSwgLCA2XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuc3RhcnRJbnRlcm5hbCgpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUgPSBIdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkluZm9ybWF0aW9uLCBcIkh1YkNvbm5lY3Rpb24gcmVjb25uZWN0ZWQgc3VjY2Vzc2Z1bGx5LlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25yZWNvbm5lY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdGVkQ2FsbGJhY2tzLmZvckVhY2goZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGMuYXBwbHkoX3RoaXMsIFtfdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZF0pOyB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgXCJBbiBvbnJlY29ubmVjdGVkIGNhbGxiYWNrIGNhbGxlZCB3aXRoIGNvbm5lY3Rpb25JZCAnXCIgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgXCI7IHRocmV3IGVycm9yICdcIiArIGUgKyBcIicuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVfNCA9IF9hLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5JbmZvcm1hdGlvbiwgXCJSZWNvbm5lY3QgYXR0ZW1wdCBmYWlsZWQgYmVjYXVzZSBvZiBlcnJvciAnXCIgKyBlXzQgKyBcIicuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUgIT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5SZWNvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsIFwiQ29ubmVjdGlvbiBsZWZ0IHRoZSByZWNvbm5lY3Rpbmcgc3RhdGUgZHVyaW5nIHJlY29ubmVjdCBhdHRlbXB0LiBEb25lIHJlY29ubmVjdGluZy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0cnlFcnJvciA9IGVfNCBpbnN0YW5jZW9mIEVycm9yID8gZV80IDogbmV3IEVycm9yKGVfNC50b1N0cmluZygpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFJldHJ5RGVsYXkgPSB0aGlzLmdldE5leHRSZXRyeURlbGF5KHByZXZpb3VzUmVjb25uZWN0QXR0ZW1wdHMrKywgRGF0ZS5ub3coKSAtIHJlY29ubmVjdFN0YXJ0VGltZSwgcmV0cnlFcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDZdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFszIC8qYnJlYWsqLywgMV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkluZm9ybWF0aW9uLCBcIlJlY29ubmVjdCByZXRyaWVzIGhhdmUgYmVlbiBleGhhdXN0ZWQgYWZ0ZXIgXCIgKyAoRGF0ZS5ub3coKSAtIHJlY29ubmVjdFN0YXJ0VGltZSkgKyBcIiBtcyBhbmQgXCIgKyBwcmV2aW91c1JlY29ubmVjdEF0dGVtcHRzICsgXCIgZmFpbGVkIGF0dGVtcHRzLiBDb25uZWN0aW9uIGRpc2Nvbm5lY3RpbmcuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBsZXRlQ2xvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXROZXh0UmV0cnlEZWxheSA9IGZ1bmN0aW9uIChwcmV2aW91c1JldHJ5Q291bnQsIGVsYXBzZWRNaWxsaXNlY29uZHMsIHJldHJ5UmVhc29uKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVjb25uZWN0UG9saWN5Lm5leHRSZXRyeURlbGF5SW5NaWxsaXNlY29uZHMoe1xyXG4gICAgICAgICAgICAgICAgZWxhcHNlZE1pbGxpc2Vjb25kczogZWxhcHNlZE1pbGxpc2Vjb25kcyxcclxuICAgICAgICAgICAgICAgIHByZXZpb3VzUmV0cnlDb3VudDogcHJldmlvdXNSZXRyeUNvdW50LFxyXG4gICAgICAgICAgICAgICAgcmV0cnlSZWFzb246IHJldHJ5UmVhc29uLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvciwgXCJJUmV0cnlQb2xpY3kubmV4dFJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kcyhcIiArIHByZXZpb3VzUmV0cnlDb3VudCArIFwiLCBcIiArIGVsYXBzZWRNaWxsaXNlY29uZHMgKyBcIikgdGhyZXcgZXJyb3IgJ1wiICsgZSArIFwiJy5cIik7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5jYW5jZWxDYWxsYmFja3NXaXRoRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcclxuICAgICAgICB2YXIgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3M7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB7fTtcclxuICAgICAgICBPYmplY3Qua2V5cyhjYWxsYmFja3MpXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gY2FsbGJhY2tzW2tleV07XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGVycm9yKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5jbGVhbnVwUGluZ1RpbWVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnBpbmdTZXJ2ZXJIYW5kbGUpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ1NlcnZlckhhbmRsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLmNsZWFudXBUaW1lb3V0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnRpbWVvdXRIYW5kbGUpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dEhhbmRsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZUludm9jYXRpb24gPSBmdW5jdGlvbiAobWV0aG9kTmFtZSwgYXJncywgbm9uYmxvY2tpbmcsIHN0cmVhbUlkcykge1xyXG4gICAgICAgIGlmIChub25ibG9ja2luZykge1xyXG4gICAgICAgICAgICBpZiAoc3RyZWFtSWRzLmxlbmd0aCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHM6IGFyZ3MsXHJcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWRzOiBzdHJlYW1JZHMsXHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBtZXRob2ROYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLkludm9jYXRpb24sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHM6IGFyZ3MsXHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBtZXRob2ROYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLkludm9jYXRpb24sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgaW52b2NhdGlvbklkID0gdGhpcy5pbnZvY2F0aW9uSWQ7XHJcbiAgICAgICAgICAgIHRoaXMuaW52b2NhdGlvbklkKys7XHJcbiAgICAgICAgICAgIGlmIChzdHJlYW1JZHMubGVuZ3RoICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50czogYXJncyxcclxuICAgICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uSWQ6IGludm9jYXRpb25JZC50b1N0cmluZygpLFxyXG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkczogc3RyZWFtSWRzLFxyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldDogbWV0aG9kTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5JbnZvY2F0aW9uLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzOiBhcmdzLFxyXG4gICAgICAgICAgICAgICAgICAgIGludm9jYXRpb25JZDogaW52b2NhdGlvbklkLnRvU3RyaW5nKCksXHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBtZXRob2ROYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLkludm9jYXRpb24sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLmxhdW5jaFN0cmVhbXMgPSBmdW5jdGlvbiAoc3RyZWFtcywgcHJvbWlzZVF1ZXVlKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAoc3RyZWFtcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTeW5jaHJvbml6ZSBzdHJlYW0gZGF0YSBzbyB0aGV5IGFycml2ZSBpbi1vcmRlciBvbiB0aGUgc2VydmVyXHJcbiAgICAgICAgaWYgKCFwcm9taXNlUXVldWUpIHtcclxuICAgICAgICAgICAgcHJvbWlzZVF1ZXVlID0gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKHN0cmVhbUlkKSB7XHJcbiAgICAgICAgICAgIHN0cmVhbXNbc3RyZWFtSWRdLnN1YnNjcmliZSh7XHJcbiAgICAgICAgICAgICAgICBjb21wbGV0ZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VRdWV1ZSA9IHByb21pc2VRdWV1ZS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF90aGlzLnNlbmRXaXRoUHJvdG9jb2woX3RoaXMuY3JlYXRlQ29tcGxldGlvbk1lc3NhZ2Uoc3RyZWFtSWQpKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGVyci5tZXNzYWdlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlcnIgJiYgZXJyLnRvU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnIudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBcIlVua25vd24gZXJyb3JcIjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZVF1ZXVlID0gcHJvbWlzZVF1ZXVlLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gX3RoaXMuc2VuZFdpdGhQcm90b2NvbChfdGhpcy5jcmVhdGVDb21wbGV0aW9uTWVzc2FnZShzdHJlYW1JZCwgbWVzc2FnZSkpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBuZXh0OiBmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VRdWV1ZSA9IHByb21pc2VRdWV1ZS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF90aGlzLnNlbmRXaXRoUHJvdG9jb2woX3RoaXMuY3JlYXRlU3RyZWFtSXRlbU1lc3NhZ2Uoc3RyZWFtSWQsIGl0ZW0pKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFdlIHdhbnQgdG8gaXRlcmF0ZSBvdmVyIHRoZSBrZXlzLCBzaW5jZSB0aGUga2V5cyBhcmUgdGhlIHN0cmVhbSBpZHNcclxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Zm9yaW5cclxuICAgICAgICBmb3IgKHZhciBzdHJlYW1JZCBpbiBzdHJlYW1zKSB7XHJcbiAgICAgICAgICAgIF9sb29wXzEoc3RyZWFtSWQpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uLnByb3RvdHlwZS5yZXBsYWNlU3RyZWFtaW5nUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcclxuICAgICAgICB2YXIgc3RyZWFtcyA9IFtdO1xyXG4gICAgICAgIHZhciBzdHJlYW1JZHMgPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdmFyIGFyZ3VtZW50ID0gYXJnc1tpXTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNPYnNlcnZhYmxlKGFyZ3VtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0cmVhbUlkID0gdGhpcy5pbnZvY2F0aW9uSWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmludm9jYXRpb25JZCsrO1xyXG4gICAgICAgICAgICAgICAgLy8gU3RvcmUgdGhlIHN0cmVhbSBmb3IgbGF0ZXIgdXNlXHJcbiAgICAgICAgICAgICAgICBzdHJlYW1zW3N0cmVhbUlkXSA9IGFyZ3VtZW50O1xyXG4gICAgICAgICAgICAgICAgc3RyZWFtSWRzLnB1c2goc3RyZWFtSWQudG9TdHJpbmcoKSk7XHJcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgc3RyZWFtIGZyb20gYXJnc1xyXG4gICAgICAgICAgICAgICAgYXJncy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFtzdHJlYW1zLCBzdHJlYW1JZHNdO1xyXG4gICAgfTtcclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLmlzT2JzZXJ2YWJsZSA9IGZ1bmN0aW9uIChhcmcpIHtcclxuICAgICAgICAvLyBUaGlzIGFsbG93cyBvdGhlciBzdHJlYW0gaW1wbGVtZW50YXRpb25zIHRvIGp1c3Qgd29yayAobGlrZSByeGpzKVxyXG4gICAgICAgIHJldHVybiBhcmcgJiYgYXJnLnN1YnNjcmliZSAmJiB0eXBlb2YgYXJnLnN1YnNjcmliZSA9PT0gXCJmdW5jdGlvblwiO1xyXG4gICAgfTtcclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZVN0cmVhbUludm9jYXRpb24gPSBmdW5jdGlvbiAobWV0aG9kTmFtZSwgYXJncywgc3RyZWFtSWRzKSB7XHJcbiAgICAgICAgdmFyIGludm9jYXRpb25JZCA9IHRoaXMuaW52b2NhdGlvbklkO1xyXG4gICAgICAgIHRoaXMuaW52b2NhdGlvbklkKys7XHJcbiAgICAgICAgaWYgKHN0cmVhbUlkcy5sZW5ndGggIT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGFyZ3VtZW50czogYXJncyxcclxuICAgICAgICAgICAgICAgIGludm9jYXRpb25JZDogaW52b2NhdGlvbklkLnRvU3RyaW5nKCksXHJcbiAgICAgICAgICAgICAgICBzdHJlYW1JZHM6IHN0cmVhbUlkcyxcclxuICAgICAgICAgICAgICAgIHRhcmdldDogbWV0aG9kTmFtZSxcclxuICAgICAgICAgICAgICAgIHR5cGU6IElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLlN0cmVhbUludm9jYXRpb24sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgYXJndW1lbnRzOiBhcmdzLFxyXG4gICAgICAgICAgICAgICAgaW52b2NhdGlvbklkOiBpbnZvY2F0aW9uSWQudG9TdHJpbmcoKSxcclxuICAgICAgICAgICAgICAgIHRhcmdldDogbWV0aG9kTmFtZSxcclxuICAgICAgICAgICAgICAgIHR5cGU6IElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLlN0cmVhbUludm9jYXRpb24sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEh1YkNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZUNhbmNlbEludm9jYXRpb24gPSBmdW5jdGlvbiAoaWQpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBpbnZvY2F0aW9uSWQ6IGlkLFxyXG4gICAgICAgICAgICB0eXBlOiBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5DYW5jZWxJbnZvY2F0aW9uLFxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuY3JlYXRlU3RyZWFtSXRlbU1lc3NhZ2UgPSBmdW5jdGlvbiAoaWQsIGl0ZW0pIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBpbnZvY2F0aW9uSWQ6IGlkLFxyXG4gICAgICAgICAgICBpdGVtOiBpdGVtLFxyXG4gICAgICAgICAgICB0eXBlOiBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5TdHJlYW1JdGVtLFxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbi5wcm90b3R5cGUuY3JlYXRlQ29tcGxldGlvbk1lc3NhZ2UgPSBmdW5jdGlvbiAoaWQsIGVycm9yLCByZXN1bHQpIHtcclxuICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvcixcclxuICAgICAgICAgICAgICAgIGludm9jYXRpb25JZDogaWQsXHJcbiAgICAgICAgICAgICAgICB0eXBlOiBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5Db21wbGV0aW9uLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBpbnZvY2F0aW9uSWQ6IGlkLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJlc3VsdCxcclxuICAgICAgICAgICAgdHlwZTogSUh1YlByb3RvY29sXzEuTWVzc2FnZVR5cGUuQ29tcGxldGlvbixcclxuICAgICAgICB9O1xyXG4gICAgfTtcclxuICAgIHJldHVybiBIdWJDb25uZWN0aW9uO1xyXG59KCkpO1xyXG5leHBvcnRzLkh1YkNvbm5lY3Rpb24gPSBIdWJDb25uZWN0aW9uO1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1IdWJDb25uZWN0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIC5ORVQgRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbnZhciBfX2Fzc2lnbiA9ICh0aGlzICYmIHRoaXMuX19hc3NpZ24pIHx8IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24odCkge1xyXG4gICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpXHJcbiAgICAgICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIERlZmF1bHRSZWNvbm5lY3RQb2xpY3lfMSA9IHJlcXVpcmUoXCIuL0RlZmF1bHRSZWNvbm5lY3RQb2xpY3lcIik7XHJcbnZhciBIdHRwQ29ubmVjdGlvbl8xID0gcmVxdWlyZShcIi4vSHR0cENvbm5lY3Rpb25cIik7XHJcbnZhciBIdWJDb25uZWN0aW9uXzEgPSByZXF1aXJlKFwiLi9IdWJDb25uZWN0aW9uXCIpO1xyXG52YXIgSUxvZ2dlcl8xID0gcmVxdWlyZShcIi4vSUxvZ2dlclwiKTtcclxudmFyIEpzb25IdWJQcm90b2NvbF8xID0gcmVxdWlyZShcIi4vSnNvbkh1YlByb3RvY29sXCIpO1xyXG52YXIgTG9nZ2Vyc18xID0gcmVxdWlyZShcIi4vTG9nZ2Vyc1wiKTtcclxudmFyIFV0aWxzXzEgPSByZXF1aXJlKFwiLi9VdGlsc1wiKTtcclxuLy8gdHNsaW50OmRpc2FibGU6b2JqZWN0LWxpdGVyYWwtc29ydC1rZXlzXHJcbnZhciBMb2dMZXZlbE5hbWVNYXBwaW5nID0ge1xyXG4gICAgdHJhY2U6IElMb2dnZXJfMS5Mb2dMZXZlbC5UcmFjZSxcclxuICAgIGRlYnVnOiBJTG9nZ2VyXzEuTG9nTGV2ZWwuRGVidWcsXHJcbiAgICBpbmZvOiBJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sXHJcbiAgICBpbmZvcm1hdGlvbjogSUxvZ2dlcl8xLkxvZ0xldmVsLkluZm9ybWF0aW9uLFxyXG4gICAgd2FybjogSUxvZ2dlcl8xLkxvZ0xldmVsLldhcm5pbmcsXHJcbiAgICB3YXJuaW5nOiBJTG9nZ2VyXzEuTG9nTGV2ZWwuV2FybmluZyxcclxuICAgIGVycm9yOiBJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsXHJcbiAgICBjcml0aWNhbDogSUxvZ2dlcl8xLkxvZ0xldmVsLkNyaXRpY2FsLFxyXG4gICAgbm9uZTogSUxvZ2dlcl8xLkxvZ0xldmVsLk5vbmUsXHJcbn07XHJcbmZ1bmN0aW9uIHBhcnNlTG9nTGV2ZWwobmFtZSkge1xyXG4gICAgLy8gQ2FzZS1pbnNlbnNpdGl2ZSBtYXRjaGluZyB2aWEgbG93ZXItY2FzaW5nXHJcbiAgICAvLyBZZXMsIEkga25vdyBjYXNlLWZvbGRpbmcgaXMgYSBjb21wbGljYXRlZCBwcm9ibGVtIGluIFVuaWNvZGUsIGJ1dCB3ZSBvbmx5IHN1cHBvcnRcclxuICAgIC8vIHRoZSBBU0NJSSBzdHJpbmdzIGRlZmluZWQgaW4gTG9nTGV2ZWxOYW1lTWFwcGluZyBhbnl3YXksIHNvIGl0J3MgZmluZSAtYW51cnNlLlxyXG4gICAgdmFyIG1hcHBpbmcgPSBMb2dMZXZlbE5hbWVNYXBwaW5nW25hbWUudG9Mb3dlckNhc2UoKV07XHJcbiAgICBpZiAodHlwZW9mIG1hcHBpbmcgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgICByZXR1cm4gbWFwcGluZztcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gbG9nIGxldmVsOiBcIiArIG5hbWUpO1xyXG4gICAgfVxyXG59XHJcbi8qKiBBIGJ1aWxkZXIgZm9yIGNvbmZpZ3VyaW5nIHtAbGluayBAbWljcm9zb2Z0L3NpZ25hbHIuSHViQ29ubmVjdGlvbn0gaW5zdGFuY2VzLiAqL1xyXG52YXIgSHViQ29ubmVjdGlvbkJ1aWxkZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBIdWJDb25uZWN0aW9uQnVpbGRlcigpIHtcclxuICAgIH1cclxuICAgIEh1YkNvbm5lY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5jb25maWd1cmVMb2dnaW5nID0gZnVuY3Rpb24gKGxvZ2dpbmcpIHtcclxuICAgICAgICBVdGlsc18xLkFyZy5pc1JlcXVpcmVkKGxvZ2dpbmcsIFwibG9nZ2luZ1wiKTtcclxuICAgICAgICBpZiAoaXNMb2dnZXIobG9nZ2luZykpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIgPSBsb2dnaW5nO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgbG9nZ2luZyA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgICB2YXIgbG9nTGV2ZWwgPSBwYXJzZUxvZ0xldmVsKGxvZ2dpbmcpO1xyXG4gICAgICAgICAgICB0aGlzLmxvZ2dlciA9IG5ldyBVdGlsc18xLkNvbnNvbGVMb2dnZXIobG9nTGV2ZWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIgPSBuZXcgVXRpbHNfMS5Db25zb2xlTG9nZ2VyKGxvZ2dpbmcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBIdWJDb25uZWN0aW9uQnVpbGRlci5wcm90b3R5cGUud2l0aFVybCA9IGZ1bmN0aW9uICh1cmwsIHRyYW5zcG9ydFR5cGVPck9wdGlvbnMpIHtcclxuICAgICAgICBVdGlsc18xLkFyZy5pc1JlcXVpcmVkKHVybCwgXCJ1cmxcIik7XHJcbiAgICAgICAgVXRpbHNfMS5BcmcuaXNOb3RFbXB0eSh1cmwsIFwidXJsXCIpO1xyXG4gICAgICAgIHRoaXMudXJsID0gdXJsO1xyXG4gICAgICAgIC8vIEZsb3ctdHlwaW5nIGtub3dzIHdoZXJlIGl0J3MgYXQuIFNpbmNlIEh0dHBUcmFuc3BvcnRUeXBlIGlzIGEgbnVtYmVyIGFuZCBJSHR0cENvbm5lY3Rpb25PcHRpb25zIGlzIGd1YXJhbnRlZWRcclxuICAgICAgICAvLyB0byBiZSBhbiBvYmplY3QsIHdlIGtub3cgKGFzIGRvZXMgVHlwZVNjcmlwdCkgdGhpcyBjb21wYXJpc29uIGlzIGFsbCB3ZSBuZWVkIHRvIGZpZ3VyZSBvdXQgd2hpY2ggb3ZlcmxvYWQgd2FzIGNhbGxlZC5cclxuICAgICAgICBpZiAodHlwZW9mIHRyYW5zcG9ydFR5cGVPck9wdGlvbnMgPT09IFwib2JqZWN0XCIpIHtcclxuICAgICAgICAgICAgdGhpcy5odHRwQ29ubmVjdGlvbk9wdGlvbnMgPSBfX2Fzc2lnbih7fSwgdGhpcy5odHRwQ29ubmVjdGlvbk9wdGlvbnMsIHRyYW5zcG9ydFR5cGVPck9wdGlvbnMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5odHRwQ29ubmVjdGlvbk9wdGlvbnMgPSBfX2Fzc2lnbih7fSwgdGhpcy5odHRwQ29ubmVjdGlvbk9wdGlvbnMsIHsgdHJhbnNwb3J0OiB0cmFuc3BvcnRUeXBlT3JPcHRpb25zIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKiogQ29uZmlndXJlcyB0aGUge0BsaW5rIEBtaWNyb3NvZnQvc2lnbmFsci5IdWJDb25uZWN0aW9ufSB0byB1c2UgdGhlIHNwZWNpZmllZCBIdWIgUHJvdG9jb2wuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtJSHViUHJvdG9jb2x9IHByb3RvY29sIFRoZSB7QGxpbmsgQG1pY3Jvc29mdC9zaWduYWxyLklIdWJQcm90b2NvbH0gaW1wbGVtZW50YXRpb24gdG8gdXNlLlxyXG4gICAgICovXHJcbiAgICBIdWJDb25uZWN0aW9uQnVpbGRlci5wcm90b3R5cGUud2l0aEh1YlByb3RvY29sID0gZnVuY3Rpb24gKHByb3RvY29sKSB7XHJcbiAgICAgICAgVXRpbHNfMS5BcmcuaXNSZXF1aXJlZChwcm90b2NvbCwgXCJwcm90b2NvbFwiKTtcclxuICAgICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2w7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgSHViQ29ubmVjdGlvbkJ1aWxkZXIucHJvdG90eXBlLndpdGhBdXRvbWF0aWNSZWNvbm5lY3QgPSBmdW5jdGlvbiAocmV0cnlEZWxheXNPclJlY29ubmVjdFBvbGljeSkge1xyXG4gICAgICAgIGlmICh0aGlzLnJlY29ubmVjdFBvbGljeSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHJlY29ubmVjdFBvbGljeSBoYXMgYWxyZWFkeSBiZWVuIHNldC5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghcmV0cnlEZWxheXNPclJlY29ubmVjdFBvbGljeSkge1xyXG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdFBvbGljeSA9IG5ldyBEZWZhdWx0UmVjb25uZWN0UG9saWN5XzEuRGVmYXVsdFJlY29ubmVjdFBvbGljeSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJldHJ5RGVsYXlzT3JSZWNvbm5lY3RQb2xpY3kpKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0UG9saWN5ID0gbmV3IERlZmF1bHRSZWNvbm5lY3RQb2xpY3lfMS5EZWZhdWx0UmVjb25uZWN0UG9saWN5KHJldHJ5RGVsYXlzT3JSZWNvbm5lY3RQb2xpY3kpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3RQb2xpY3kgPSByZXRyeURlbGF5c09yUmVjb25uZWN0UG9saWN5O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKiogQ3JlYXRlcyBhIHtAbGluayBAbWljcm9zb2Z0L3NpZ25hbHIuSHViQ29ubmVjdGlvbn0gZnJvbSB0aGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHNwZWNpZmllZCBpbiB0aGlzIGJ1aWxkZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0h1YkNvbm5lY3Rpb259IFRoZSBjb25maWd1cmVkIHtAbGluayBAbWljcm9zb2Z0L3NpZ25hbHIuSHViQ29ubmVjdGlvbn0uXHJcbiAgICAgKi9cclxuICAgIEh1YkNvbm5lY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5idWlsZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBJZiBodHRwQ29ubmVjdGlvbk9wdGlvbnMgaGFzIGEgbG9nZ2VyLCB1c2UgaXQuIE90aGVyd2lzZSwgb3ZlcnJpZGUgaXQgd2l0aCB0aGUgb25lXHJcbiAgICAgICAgLy8gcHJvdmlkZWQgdG8gY29uZmlndXJlTG9nZ2VyXHJcbiAgICAgICAgdmFyIGh0dHBDb25uZWN0aW9uT3B0aW9ucyA9IHRoaXMuaHR0cENvbm5lY3Rpb25PcHRpb25zIHx8IHt9O1xyXG4gICAgICAgIC8vIElmIGl0J3MgJ251bGwnLCB0aGUgdXNlciAqKmV4cGxpY2l0bHkqKiBhc2tlZCBmb3IgbnVsbCwgZG9uJ3QgbWVzcyB3aXRoIGl0LlxyXG4gICAgICAgIGlmIChodHRwQ29ubmVjdGlvbk9wdGlvbnMubG9nZ2VyID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgLy8gSWYgb3VyIGxvZ2dlciBpcyB1bmRlZmluZWQgb3IgbnVsbCwgdGhhdCdzIE9LLCB0aGUgSHR0cENvbm5lY3Rpb24gY29uc3RydWN0b3Igd2lsbCBoYW5kbGUgaXQuXHJcbiAgICAgICAgICAgIGh0dHBDb25uZWN0aW9uT3B0aW9ucy5sb2dnZXIgPSB0aGlzLmxvZ2dlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gTm93IGNyZWF0ZSB0aGUgY29ubmVjdGlvblxyXG4gICAgICAgIGlmICghdGhpcy51cmwpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlICdIdWJDb25uZWN0aW9uQnVpbGRlci53aXRoVXJsJyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIGJ1aWxkaW5nIHRoZSBjb25uZWN0aW9uLlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNvbm5lY3Rpb24gPSBuZXcgSHR0cENvbm5lY3Rpb25fMS5IdHRwQ29ubmVjdGlvbih0aGlzLnVybCwgaHR0cENvbm5lY3Rpb25PcHRpb25zKTtcclxuICAgICAgICByZXR1cm4gSHViQ29ubmVjdGlvbl8xLkh1YkNvbm5lY3Rpb24uY3JlYXRlKGNvbm5lY3Rpb24sIHRoaXMubG9nZ2VyIHx8IExvZ2dlcnNfMS5OdWxsTG9nZ2VyLmluc3RhbmNlLCB0aGlzLnByb3RvY29sIHx8IG5ldyBKc29uSHViUHJvdG9jb2xfMS5Kc29uSHViUHJvdG9jb2woKSwgdGhpcy5yZWNvbm5lY3RQb2xpY3kpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBIdWJDb25uZWN0aW9uQnVpbGRlcjtcclxufSgpKTtcclxuZXhwb3J0cy5IdWJDb25uZWN0aW9uQnVpbGRlciA9IEh1YkNvbm5lY3Rpb25CdWlsZGVyO1xyXG5mdW5jdGlvbiBpc0xvZ2dlcihsb2dnZXIpIHtcclxuICAgIHJldHVybiBsb2dnZXIubG9nICE9PSB1bmRlZmluZWQ7XHJcbn1cclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SHViQ29ubmVjdGlvbkJ1aWxkZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vKiogRGVmaW5lcyB0aGUgdHlwZSBvZiBhIEh1YiBNZXNzYWdlLiAqL1xyXG52YXIgTWVzc2FnZVR5cGU7XHJcbihmdW5jdGlvbiAoTWVzc2FnZVR5cGUpIHtcclxuICAgIC8qKiBJbmRpY2F0ZXMgdGhlIG1lc3NhZ2UgaXMgYW4gSW52b2NhdGlvbiBtZXNzYWdlIGFuZCBpbXBsZW1lbnRzIHRoZSB7QGxpbmsgQG1pY3Jvc29mdC9zaWduYWxyLkludm9jYXRpb25NZXNzYWdlfSBpbnRlcmZhY2UuICovXHJcbiAgICBNZXNzYWdlVHlwZVtNZXNzYWdlVHlwZVtcIkludm9jYXRpb25cIl0gPSAxXSA9IFwiSW52b2NhdGlvblwiO1xyXG4gICAgLyoqIEluZGljYXRlcyB0aGUgbWVzc2FnZSBpcyBhIFN0cmVhbUl0ZW0gbWVzc2FnZSBhbmQgaW1wbGVtZW50cyB0aGUge0BsaW5rIEBtaWNyb3NvZnQvc2lnbmFsci5TdHJlYW1JdGVtTWVzc2FnZX0gaW50ZXJmYWNlLiAqL1xyXG4gICAgTWVzc2FnZVR5cGVbTWVzc2FnZVR5cGVbXCJTdHJlYW1JdGVtXCJdID0gMl0gPSBcIlN0cmVhbUl0ZW1cIjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgdGhlIG1lc3NhZ2UgaXMgYSBDb21wbGV0aW9uIG1lc3NhZ2UgYW5kIGltcGxlbWVudHMgdGhlIHtAbGluayBAbWljcm9zb2Z0L3NpZ25hbHIuQ29tcGxldGlvbk1lc3NhZ2V9IGludGVyZmFjZS4gKi9cclxuICAgIE1lc3NhZ2VUeXBlW01lc3NhZ2VUeXBlW1wiQ29tcGxldGlvblwiXSA9IDNdID0gXCJDb21wbGV0aW9uXCI7XHJcbiAgICAvKiogSW5kaWNhdGVzIHRoZSBtZXNzYWdlIGlzIGEgU3RyZWFtIEludm9jYXRpb24gbWVzc2FnZSBhbmQgaW1wbGVtZW50cyB0aGUge0BsaW5rIEBtaWNyb3NvZnQvc2lnbmFsci5TdHJlYW1JbnZvY2F0aW9uTWVzc2FnZX0gaW50ZXJmYWNlLiAqL1xyXG4gICAgTWVzc2FnZVR5cGVbTWVzc2FnZVR5cGVbXCJTdHJlYW1JbnZvY2F0aW9uXCJdID0gNF0gPSBcIlN0cmVhbUludm9jYXRpb25cIjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgdGhlIG1lc3NhZ2UgaXMgYSBDYW5jZWwgSW52b2NhdGlvbiBtZXNzYWdlIGFuZCBpbXBsZW1lbnRzIHRoZSB7QGxpbmsgQG1pY3Jvc29mdC9zaWduYWxyLkNhbmNlbEludm9jYXRpb25NZXNzYWdlfSBpbnRlcmZhY2UuICovXHJcbiAgICBNZXNzYWdlVHlwZVtNZXNzYWdlVHlwZVtcIkNhbmNlbEludm9jYXRpb25cIl0gPSA1XSA9IFwiQ2FuY2VsSW52b2NhdGlvblwiO1xyXG4gICAgLyoqIEluZGljYXRlcyB0aGUgbWVzc2FnZSBpcyBhIFBpbmcgbWVzc2FnZSBhbmQgaW1wbGVtZW50cyB0aGUge0BsaW5rIEBtaWNyb3NvZnQvc2lnbmFsci5QaW5nTWVzc2FnZX0gaW50ZXJmYWNlLiAqL1xyXG4gICAgTWVzc2FnZVR5cGVbTWVzc2FnZVR5cGVbXCJQaW5nXCJdID0gNl0gPSBcIlBpbmdcIjtcclxuICAgIC8qKiBJbmRpY2F0ZXMgdGhlIG1lc3NhZ2UgaXMgYSBDbG9zZSBtZXNzYWdlIGFuZCBpbXBsZW1lbnRzIHRoZSB7QGxpbmsgQG1pY3Jvc29mdC9zaWduYWxyLkNsb3NlTWVzc2FnZX0gaW50ZXJmYWNlLiAqL1xyXG4gICAgTWVzc2FnZVR5cGVbTWVzc2FnZVR5cGVbXCJDbG9zZVwiXSA9IDddID0gXCJDbG9zZVwiO1xyXG59KShNZXNzYWdlVHlwZSA9IGV4cG9ydHMuTWVzc2FnZVR5cGUgfHwgKGV4cG9ydHMuTWVzc2FnZVR5cGUgPSB7fSkpO1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1JSHViUHJvdG9jb2wuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vLyBUaGVzZSB2YWx1ZXMgYXJlIGRlc2lnbmVkIHRvIG1hdGNoIHRoZSBBU1AuTkVUIExvZyBMZXZlbHMgc2luY2UgdGhhdCdzIHRoZSBwYXR0ZXJuIHdlJ3JlIGVtdWxhdGluZyBoZXJlLlxyXG4vKiogSW5kaWNhdGVzIHRoZSBzZXZlcml0eSBvZiBhIGxvZyBtZXNzYWdlLlxyXG4gKlxyXG4gKiBMb2cgTGV2ZWxzIGFyZSBvcmRlcmVkIGluIGluY3JlYXNpbmcgc2V2ZXJpdHkuIFNvIGBEZWJ1Z2AgaXMgbW9yZSBzZXZlcmUgdGhhbiBgVHJhY2VgLCBldGMuXHJcbiAqL1xyXG52YXIgTG9nTGV2ZWw7XHJcbihmdW5jdGlvbiAoTG9nTGV2ZWwpIHtcclxuICAgIC8qKiBMb2cgbGV2ZWwgZm9yIHZlcnkgbG93IHNldmVyaXR5IGRpYWdub3N0aWMgbWVzc2FnZXMuICovXHJcbiAgICBMb2dMZXZlbFtMb2dMZXZlbFtcIlRyYWNlXCJdID0gMF0gPSBcIlRyYWNlXCI7XHJcbiAgICAvKiogTG9nIGxldmVsIGZvciBsb3cgc2V2ZXJpdHkgZGlhZ25vc3RpYyBtZXNzYWdlcy4gKi9cclxuICAgIExvZ0xldmVsW0xvZ0xldmVsW1wiRGVidWdcIl0gPSAxXSA9IFwiRGVidWdcIjtcclxuICAgIC8qKiBMb2cgbGV2ZWwgZm9yIGluZm9ybWF0aW9uYWwgZGlhZ25vc3RpYyBtZXNzYWdlcy4gKi9cclxuICAgIExvZ0xldmVsW0xvZ0xldmVsW1wiSW5mb3JtYXRpb25cIl0gPSAyXSA9IFwiSW5mb3JtYXRpb25cIjtcclxuICAgIC8qKiBMb2cgbGV2ZWwgZm9yIGRpYWdub3N0aWMgbWVzc2FnZXMgdGhhdCBpbmRpY2F0ZSBhIG5vbi1mYXRhbCBwcm9ibGVtLiAqL1xyXG4gICAgTG9nTGV2ZWxbTG9nTGV2ZWxbXCJXYXJuaW5nXCJdID0gM10gPSBcIldhcm5pbmdcIjtcclxuICAgIC8qKiBMb2cgbGV2ZWwgZm9yIGRpYWdub3N0aWMgbWVzc2FnZXMgdGhhdCBpbmRpY2F0ZSBhIGZhaWx1cmUgaW4gdGhlIGN1cnJlbnQgb3BlcmF0aW9uLiAqL1xyXG4gICAgTG9nTGV2ZWxbTG9nTGV2ZWxbXCJFcnJvclwiXSA9IDRdID0gXCJFcnJvclwiO1xyXG4gICAgLyoqIExvZyBsZXZlbCBmb3IgZGlhZ25vc3RpYyBtZXNzYWdlcyB0aGF0IGluZGljYXRlIGEgZmFpbHVyZSB0aGF0IHdpbGwgdGVybWluYXRlIHRoZSBlbnRpcmUgYXBwbGljYXRpb24uICovXHJcbiAgICBMb2dMZXZlbFtMb2dMZXZlbFtcIkNyaXRpY2FsXCJdID0gNV0gPSBcIkNyaXRpY2FsXCI7XHJcbiAgICAvKiogVGhlIGhpZ2hlc3QgcG9zc2libGUgbG9nIGxldmVsLiBVc2VkIHdoZW4gY29uZmlndXJpbmcgbG9nZ2luZyB0byBpbmRpY2F0ZSB0aGF0IG5vIGxvZyBtZXNzYWdlcyBzaG91bGQgYmUgZW1pdHRlZC4gKi9cclxuICAgIExvZ0xldmVsW0xvZ0xldmVsW1wiTm9uZVwiXSA9IDZdID0gXCJOb25lXCI7XHJcbn0pKExvZ0xldmVsID0gZXhwb3J0cy5Mb2dMZXZlbCB8fCAoZXhwb3J0cy5Mb2dMZXZlbCA9IHt9KSk7XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUlMb2dnZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vLyBUaGlzIHdpbGwgYmUgdHJlYXRlZCBhcyBhIGJpdCBmbGFnIGluIHRoZSBmdXR1cmUsIHNvIHdlIGtlZXAgaXQgdXNpbmcgcG93ZXItb2YtdHdvIHZhbHVlcy5cclxuLyoqIFNwZWNpZmllcyBhIHNwZWNpZmljIEhUVFAgdHJhbnNwb3J0IHR5cGUuICovXHJcbnZhciBIdHRwVHJhbnNwb3J0VHlwZTtcclxuKGZ1bmN0aW9uIChIdHRwVHJhbnNwb3J0VHlwZSkge1xyXG4gICAgLyoqIFNwZWNpZmllcyBubyB0cmFuc3BvcnQgcHJlZmVyZW5jZS4gKi9cclxuICAgIEh0dHBUcmFuc3BvcnRUeXBlW0h0dHBUcmFuc3BvcnRUeXBlW1wiTm9uZVwiXSA9IDBdID0gXCJOb25lXCI7XHJcbiAgICAvKiogU3BlY2lmaWVzIHRoZSBXZWJTb2NrZXRzIHRyYW5zcG9ydC4gKi9cclxuICAgIEh0dHBUcmFuc3BvcnRUeXBlW0h0dHBUcmFuc3BvcnRUeXBlW1wiV2ViU29ja2V0c1wiXSA9IDFdID0gXCJXZWJTb2NrZXRzXCI7XHJcbiAgICAvKiogU3BlY2lmaWVzIHRoZSBTZXJ2ZXItU2VudCBFdmVudHMgdHJhbnNwb3J0LiAqL1xyXG4gICAgSHR0cFRyYW5zcG9ydFR5cGVbSHR0cFRyYW5zcG9ydFR5cGVbXCJTZXJ2ZXJTZW50RXZlbnRzXCJdID0gMl0gPSBcIlNlcnZlclNlbnRFdmVudHNcIjtcclxuICAgIC8qKiBTcGVjaWZpZXMgdGhlIExvbmcgUG9sbGluZyB0cmFuc3BvcnQuICovXHJcbiAgICBIdHRwVHJhbnNwb3J0VHlwZVtIdHRwVHJhbnNwb3J0VHlwZVtcIkxvbmdQb2xsaW5nXCJdID0gNF0gPSBcIkxvbmdQb2xsaW5nXCI7XHJcbn0pKEh0dHBUcmFuc3BvcnRUeXBlID0gZXhwb3J0cy5IdHRwVHJhbnNwb3J0VHlwZSB8fCAoZXhwb3J0cy5IdHRwVHJhbnNwb3J0VHlwZSA9IHt9KSk7XHJcbi8qKiBTcGVjaWZpZXMgdGhlIHRyYW5zZmVyIGZvcm1hdCBmb3IgYSBjb25uZWN0aW9uLiAqL1xyXG52YXIgVHJhbnNmZXJGb3JtYXQ7XHJcbihmdW5jdGlvbiAoVHJhbnNmZXJGb3JtYXQpIHtcclxuICAgIC8qKiBTcGVjaWZpZXMgdGhhdCBvbmx5IHRleHQgZGF0YSB3aWxsIGJlIHRyYW5zbWl0dGVkIG92ZXIgdGhlIGNvbm5lY3Rpb24uICovXHJcbiAgICBUcmFuc2ZlckZvcm1hdFtUcmFuc2ZlckZvcm1hdFtcIlRleHRcIl0gPSAxXSA9IFwiVGV4dFwiO1xyXG4gICAgLyoqIFNwZWNpZmllcyB0aGF0IGJpbmFyeSBkYXRhIHdpbGwgYmUgdHJhbnNtaXR0ZWQgb3ZlciB0aGUgY29ubmVjdGlvbi4gKi9cclxuICAgIFRyYW5zZmVyRm9ybWF0W1RyYW5zZmVyRm9ybWF0W1wiQmluYXJ5XCJdID0gMl0gPSBcIkJpbmFyeVwiO1xyXG59KShUcmFuc2ZlckZvcm1hdCA9IGV4cG9ydHMuVHJhbnNmZXJGb3JtYXQgfHwgKGV4cG9ydHMuVHJhbnNmZXJGb3JtYXQgPSB7fSkpO1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1JVHJhbnNwb3J0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIC5ORVQgRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIElIdWJQcm90b2NvbF8xID0gcmVxdWlyZShcIi4vSUh1YlByb3RvY29sXCIpO1xyXG52YXIgSUxvZ2dlcl8xID0gcmVxdWlyZShcIi4vSUxvZ2dlclwiKTtcclxudmFyIElUcmFuc3BvcnRfMSA9IHJlcXVpcmUoXCIuL0lUcmFuc3BvcnRcIik7XHJcbnZhciBMb2dnZXJzXzEgPSByZXF1aXJlKFwiLi9Mb2dnZXJzXCIpO1xyXG52YXIgVGV4dE1lc3NhZ2VGb3JtYXRfMSA9IHJlcXVpcmUoXCIuL1RleHRNZXNzYWdlRm9ybWF0XCIpO1xyXG52YXIgSlNPTl9IVUJfUFJPVE9DT0xfTkFNRSA9IFwianNvblwiO1xyXG4vKiogSW1wbGVtZW50cyB0aGUgSlNPTiBIdWIgUHJvdG9jb2wuICovXHJcbnZhciBKc29uSHViUHJvdG9jb2wgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBKc29uSHViUHJvdG9jb2woKSB7XHJcbiAgICAgICAgLyoqIEBpbmhlcml0RG9jICovXHJcbiAgICAgICAgdGhpcy5uYW1lID0gSlNPTl9IVUJfUFJPVE9DT0xfTkFNRTtcclxuICAgICAgICAvKiogQGluaGVyaXREb2MgKi9cclxuICAgICAgICB0aGlzLnZlcnNpb24gPSAxO1xyXG4gICAgICAgIC8qKiBAaW5oZXJpdERvYyAqL1xyXG4gICAgICAgIHRoaXMudHJhbnNmZXJGb3JtYXQgPSBJVHJhbnNwb3J0XzEuVHJhbnNmZXJGb3JtYXQuVGV4dDtcclxuICAgIH1cclxuICAgIC8qKiBDcmVhdGVzIGFuIGFycmF5IG9mIHtAbGluayBAbWljcm9zb2Z0L3NpZ25hbHIuSHViTWVzc2FnZX0gb2JqZWN0cyBmcm9tIHRoZSBzcGVjaWZpZWQgc2VyaWFsaXplZCByZXByZXNlbnRhdGlvbi5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCByZXByZXNlbnRhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7SUxvZ2dlcn0gbG9nZ2VyIEEgbG9nZ2VyIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGxvZyBtZXNzYWdlcyB0aGF0IG9jY3VyIGR1cmluZyBwYXJzaW5nLlxyXG4gICAgICovXHJcbiAgICBKc29uSHViUHJvdG9jb2wucHJvdG90eXBlLnBhcnNlTWVzc2FnZXMgPSBmdW5jdGlvbiAoaW5wdXQsIGxvZ2dlcikge1xyXG4gICAgICAgIC8vIFRoZSBpbnRlcmZhY2UgZG9lcyBhbGxvdyBcIkFycmF5QnVmZmVyXCIgdG8gYmUgcGFzc2VkIGluLCBidXQgdGhpcyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdC4gU28gbGV0J3MgdGhyb3cgYSB1c2VmdWwgZXJyb3IuXHJcbiAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBKU09OIGh1YiBwcm90b2NvbC4gRXhwZWN0ZWQgYSBzdHJpbmcuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWlucHV0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxvZ2dlciA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICBsb2dnZXIgPSBMb2dnZXJzXzEuTnVsbExvZ2dlci5pbnN0YW5jZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gUGFyc2UgdGhlIG1lc3NhZ2VzXHJcbiAgICAgICAgdmFyIG1lc3NhZ2VzID0gVGV4dE1lc3NhZ2VGb3JtYXRfMS5UZXh0TWVzc2FnZUZvcm1hdC5wYXJzZShpbnB1dCk7XHJcbiAgICAgICAgdmFyIGh1Yk1lc3NhZ2VzID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBtZXNzYWdlc18xID0gbWVzc2FnZXM7IF9pIDwgbWVzc2FnZXNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBtZXNzYWdlc18xW19pXTtcclxuICAgICAgICAgICAgdmFyIHBhcnNlZE1lc3NhZ2UgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHBhcnNlZE1lc3NhZ2UudHlwZSAhPT0gXCJudW1iZXJcIikge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBwYXlsb2FkLlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzd2l0Y2ggKHBhcnNlZE1lc3NhZ2UudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5JbnZvY2F0aW9uOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNJbnZvY2F0aW9uTWVzc2FnZShwYXJzZWRNZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgSUh1YlByb3RvY29sXzEuTWVzc2FnZVR5cGUuU3RyZWFtSXRlbTpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzU3RyZWFtSXRlbU1lc3NhZ2UocGFyc2VkTWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIElIdWJQcm90b2NvbF8xLk1lc3NhZ2VUeXBlLkNvbXBsZXRpb246XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0NvbXBsZXRpb25NZXNzYWdlKHBhcnNlZE1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5QaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNpbmdsZSB2YWx1ZSwgbm8gbmVlZCB0byB2YWxpZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZS5DbG9zZTpcclxuICAgICAgICAgICAgICAgICAgICAvLyBBbGwgb3B0aW9uYWwgdmFsdWVzLCBubyBuZWVkIHRvIHZhbGlkYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEZ1dHVyZSBwcm90b2NvbCBjaGFuZ2VzIGNhbiBhZGQgbWVzc2FnZSB0eXBlcywgb2xkIGNsaWVudHMgY2FuIGlnbm9yZSB0aGVtXHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sIFwiVW5rbm93biBtZXNzYWdlIHR5cGUgJ1wiICsgcGFyc2VkTWVzc2FnZS50eXBlICsgXCInIGlnbm9yZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGh1Yk1lc3NhZ2VzLnB1c2gocGFyc2VkTWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBodWJNZXNzYWdlcztcclxuICAgIH07XHJcbiAgICAvKiogV3JpdGVzIHRoZSBzcGVjaWZpZWQge0BsaW5rIEBtaWNyb3NvZnQvc2lnbmFsci5IdWJNZXNzYWdlfSB0byBhIHN0cmluZyBhbmQgcmV0dXJucyBpdC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0h1Yk1lc3NhZ2V9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gd3JpdGUuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHN0cmluZyBjb250YWluaW5nIHRoZSBzZXJpYWxpemVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXNzYWdlLlxyXG4gICAgICovXHJcbiAgICBKc29uSHViUHJvdG9jb2wucHJvdG90eXBlLndyaXRlTWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XHJcbiAgICAgICAgcmV0dXJuIFRleHRNZXNzYWdlRm9ybWF0XzEuVGV4dE1lc3NhZ2VGb3JtYXQud3JpdGUoSlNPTi5zdHJpbmdpZnkobWVzc2FnZSkpO1xyXG4gICAgfTtcclxuICAgIEpzb25IdWJQcm90b2NvbC5wcm90b3R5cGUuaXNJbnZvY2F0aW9uTWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5hc3NlcnROb3RFbXB0eVN0cmluZyhtZXNzYWdlLnRhcmdldCwgXCJJbnZhbGlkIHBheWxvYWQgZm9yIEludm9jYXRpb24gbWVzc2FnZS5cIik7XHJcbiAgICAgICAgaWYgKG1lc3NhZ2UuaW52b2NhdGlvbklkICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5hc3NlcnROb3RFbXB0eVN0cmluZyhtZXNzYWdlLmludm9jYXRpb25JZCwgXCJJbnZhbGlkIHBheWxvYWQgZm9yIEludm9jYXRpb24gbWVzc2FnZS5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEpzb25IdWJQcm90b2NvbC5wcm90b3R5cGUuaXNTdHJlYW1JdGVtTWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5hc3NlcnROb3RFbXB0eVN0cmluZyhtZXNzYWdlLmludm9jYXRpb25JZCwgXCJJbnZhbGlkIHBheWxvYWQgZm9yIFN0cmVhbUl0ZW0gbWVzc2FnZS5cIik7XHJcbiAgICAgICAgaWYgKG1lc3NhZ2UuaXRlbSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcGF5bG9hZCBmb3IgU3RyZWFtSXRlbSBtZXNzYWdlLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgSnNvbkh1YlByb3RvY29sLnByb3RvdHlwZS5pc0NvbXBsZXRpb25NZXNzYWdlID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcclxuICAgICAgICBpZiAobWVzc2FnZS5yZXN1bHQgJiYgbWVzc2FnZS5lcnJvcikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHBheWxvYWQgZm9yIENvbXBsZXRpb24gbWVzc2FnZS5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghbWVzc2FnZS5yZXN1bHQgJiYgbWVzc2FnZS5lcnJvcikge1xyXG4gICAgICAgICAgICB0aGlzLmFzc2VydE5vdEVtcHR5U3RyaW5nKG1lc3NhZ2UuZXJyb3IsIFwiSW52YWxpZCBwYXlsb2FkIGZvciBDb21wbGV0aW9uIG1lc3NhZ2UuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmFzc2VydE5vdEVtcHR5U3RyaW5nKG1lc3NhZ2UuaW52b2NhdGlvbklkLCBcIkludmFsaWQgcGF5bG9hZCBmb3IgQ29tcGxldGlvbiBtZXNzYWdlLlwiKTtcclxuICAgIH07XHJcbiAgICBKc29uSHViUHJvdG9jb2wucHJvdG90eXBlLmFzc2VydE5vdEVtcHR5U3RyaW5nID0gZnVuY3Rpb24gKHZhbHVlLCBlcnJvck1lc3NhZ2UpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiIHx8IHZhbHVlID09PSBcIlwiKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gSnNvbkh1YlByb3RvY29sO1xyXG59KCkpO1xyXG5leHBvcnRzLkpzb25IdWJQcm90b2NvbCA9IEpzb25IdWJQcm90b2NvbDtcclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SnNvbkh1YlByb3RvY29sLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIC5ORVQgRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuLyoqIEEgbG9nZ2VyIHRoYXQgZG9lcyBub3RoaW5nIHdoZW4gbG9nIG1lc3NhZ2VzIGFyZSBzZW50IHRvIGl0LiAqL1xyXG52YXIgTnVsbExvZ2dlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIE51bGxMb2dnZXIoKSB7XHJcbiAgICB9XHJcbiAgICAvKiogQGluaGVyaXREb2MgKi9cclxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZVxyXG4gICAgTnVsbExvZ2dlci5wcm90b3R5cGUubG9nID0gZnVuY3Rpb24gKF9sb2dMZXZlbCwgX21lc3NhZ2UpIHtcclxuICAgIH07XHJcbiAgICAvKiogVGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUge0BsaW5rIEBtaWNyb3NvZnQvc2lnbmFsci5OdWxsTG9nZ2VyfS4gKi9cclxuICAgIE51bGxMb2dnZXIuaW5zdGFuY2UgPSBuZXcgTnVsbExvZ2dlcigpO1xyXG4gICAgcmV0dXJuIE51bGxMb2dnZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuTnVsbExvZ2dlciA9IE51bGxMb2dnZXI7XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxvZ2dlcnMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxudmFyIF9fYXNzaWduID0gKHRoaXMgJiYgdGhpcy5fX2Fzc2lnbikgfHwgT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbih0KSB7XHJcbiAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSlcclxuICAgICAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufTtcclxudmFyIF9fYXdhaXRlciA9ICh0aGlzICYmIHRoaXMuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufTtcclxudmFyIF9fZ2VuZXJhdG9yID0gKHRoaXMgJiYgdGhpcy5fX2dlbmVyYXRvcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBBYm9ydENvbnRyb2xsZXJfMSA9IHJlcXVpcmUoXCIuL0Fib3J0Q29udHJvbGxlclwiKTtcclxudmFyIEVycm9yc18xID0gcmVxdWlyZShcIi4vRXJyb3JzXCIpO1xyXG52YXIgSUxvZ2dlcl8xID0gcmVxdWlyZShcIi4vSUxvZ2dlclwiKTtcclxudmFyIElUcmFuc3BvcnRfMSA9IHJlcXVpcmUoXCIuL0lUcmFuc3BvcnRcIik7XHJcbnZhciBVdGlsc18xID0gcmVxdWlyZShcIi4vVXRpbHNcIik7XHJcbi8vIE5vdCBleHBvcnRlZCBmcm9tICdpbmRleCcsIHRoaXMgdHlwZSBpcyBpbnRlcm5hbC5cclxuLyoqIEBwcml2YXRlICovXHJcbnZhciBMb25nUG9sbGluZ1RyYW5zcG9ydCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIExvbmdQb2xsaW5nVHJhbnNwb3J0KGh0dHBDbGllbnQsIGFjY2Vzc1Rva2VuRmFjdG9yeSwgbG9nZ2VyLCBsb2dNZXNzYWdlQ29udGVudCwgd2l0aENyZWRlbnRpYWxzLCBoZWFkZXJzKSB7XHJcbiAgICAgICAgdGhpcy5odHRwQ2xpZW50ID0gaHR0cENsaWVudDtcclxuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSA9IGFjY2Vzc1Rva2VuRmFjdG9yeTtcclxuICAgICAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlcjtcclxuICAgICAgICB0aGlzLnBvbGxBYm9ydCA9IG5ldyBBYm9ydENvbnRyb2xsZXJfMS5BYm9ydENvbnRyb2xsZXIoKTtcclxuICAgICAgICB0aGlzLmxvZ01lc3NhZ2VDb250ZW50ID0gbG9nTWVzc2FnZUNvbnRlbnQ7XHJcbiAgICAgICAgdGhpcy53aXRoQ3JlZGVudGlhbHMgPSB3aXRoQ3JlZGVudGlhbHM7XHJcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gaGVhZGVycztcclxuICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLm9ucmVjZWl2ZSA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5vbmNsb3NlID0gbnVsbDtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShMb25nUG9sbGluZ1RyYW5zcG9ydC5wcm90b3R5cGUsIFwicG9sbEFib3J0ZWRcIiwge1xyXG4gICAgICAgIC8vIFRoaXMgaXMgYW4gaW50ZXJuYWwgdHlwZSwgbm90IGV4cG9ydGVkIGZyb20gJ2luZGV4JyBzbyB0aGlzIGlzIHJlYWxseSBqdXN0IGludGVybmFsLlxyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wb2xsQWJvcnQuYWJvcnRlZDtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIExvbmdQb2xsaW5nVHJhbnNwb3J0LnByb3RvdHlwZS5jb25uZWN0ID0gZnVuY3Rpb24gKHVybCwgdHJhbnNmZXJGb3JtYXQpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBfYSwgX2IsIG5hbWUsIHZhbHVlLCBoZWFkZXJzLCBwb2xsT3B0aW9ucywgdG9rZW4sIHBvbGxVcmwsIHJlc3BvbnNlO1xyXG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9jKSB7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKF9jLmxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBVdGlsc18xLkFyZy5pc1JlcXVpcmVkKHVybCwgXCJ1cmxcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxzXzEuQXJnLmlzUmVxdWlyZWQodHJhbnNmZXJGb3JtYXQsIFwidHJhbnNmZXJGb3JtYXRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxzXzEuQXJnLmlzSW4odHJhbnNmZXJGb3JtYXQsIElUcmFuc3BvcnRfMS5UcmFuc2ZlckZvcm1hdCwgXCJ0cmFuc2ZlckZvcm1hdFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuVHJhY2UsIFwiKExvbmdQb2xsaW5nIHRyYW5zcG9ydCkgQ29ubmVjdGluZy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFsbG93IGJpbmFyeSBmb3JtYXQgb24gTm9kZSBhbmQgQnJvd3NlcnMgdGhhdCBzdXBwb3J0IGJpbmFyeSBjb250ZW50IChpbmRpY2F0ZWQgYnkgdGhlIHByZXNlbmNlIG9mIHJlc3BvbnNlVHlwZSBwcm9wZXJ0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zZmVyRm9ybWF0ID09PSBJVHJhbnNwb3J0XzEuVHJhbnNmZXJGb3JtYXQuQmluYXJ5ICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICE9PSBcInVuZGVmaW5lZFwiICYmIHR5cGVvZiBuZXcgWE1MSHR0cFJlcXVlc3QoKS5yZXNwb25zZVR5cGUgIT09IFwic3RyaW5nXCIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCaW5hcnkgcHJvdG9jb2xzIG92ZXIgWG1sSHR0cFJlcXVlc3Qgbm90IGltcGxlbWVudGluZyBhZHZhbmNlZCBmZWF0dXJlcyBhcmUgbm90IHN1cHBvcnRlZC5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2IgPSBVdGlsc18xLmdldFVzZXJBZ2VudEhlYWRlcigpLCBuYW1lID0gX2JbMF0sIHZhbHVlID0gX2JbMV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBfX2Fzc2lnbigoX2EgPSB7fSwgX2FbbmFtZV0gPSB2YWx1ZSwgX2EpLCB0aGlzLmhlYWRlcnMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2xsT3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0U2lnbmFsOiB0aGlzLnBvbGxBYm9ydC5zaWduYWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dDogMTAwMDAwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aENyZWRlbnRpYWxzOiB0aGlzLndpdGhDcmVkZW50aWFscyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zZmVyRm9ybWF0ID09PSBJVHJhbnNwb3J0XzEuVHJhbnNmZXJGb3JtYXQuQmluYXJ5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2xsT3B0aW9ucy5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5nZXRBY2Nlc3NUb2tlbigpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuID0gX2Muc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlYWRlclRva2VuKHBvbGxPcHRpb25zLCB0b2tlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvbGxVcmwgPSB1cmwgKyBcIiZfPVwiICsgRGF0ZS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5UcmFjZSwgXCIoTG9uZ1BvbGxpbmcgdHJhbnNwb3J0KSBwb2xsaW5nOiBcIiArIHBvbGxVcmwgKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIHRoaXMuaHR0cENsaWVudC5nZXQocG9sbFVybCwgcG9sbE9wdGlvbnMpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gX2Muc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLkVycm9yLCBcIihMb25nUG9sbGluZyB0cmFuc3BvcnQpIFVuZXhwZWN0ZWQgcmVzcG9uc2UgY29kZTogXCIgKyByZXNwb25zZS5zdGF0dXNDb2RlICsgXCIuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFyayBydW5uaW5nIGFzIGZhbHNlIHNvIHRoYXQgdGhlIHBvbGwgaW1tZWRpYXRlbHkgZW5kcyBhbmQgcnVucyB0aGUgY2xvc2UgbG9naWNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VFcnJvciA9IG5ldyBFcnJvcnNfMS5IdHRwRXJyb3IocmVzcG9uc2Uuc3RhdHVzVGV4dCB8fCBcIlwiLCByZXNwb25zZS5zdGF0dXNDb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlY2VpdmluZyA9IHRoaXMucG9sbCh0aGlzLnVybCwgcG9sbE9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIExvbmdQb2xsaW5nVHJhbnNwb3J0LnByb3RvdHlwZS5nZXRBY2Nlc3NUb2tlbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hY2Nlc3NUb2tlbkZhY3RvcnkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDJdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSgpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHJldHVybiBbMiAvKnJldHVybiovLCBfYS5zZW50KCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIFsyIC8qcmV0dXJuKi8sIG51bGxdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBMb25nUG9sbGluZ1RyYW5zcG9ydC5wcm90b3R5cGUudXBkYXRlSGVhZGVyVG9rZW4gPSBmdW5jdGlvbiAocmVxdWVzdCwgdG9rZW4pIHtcclxuICAgICAgICBpZiAoIXJlcXVlc3QuaGVhZGVycykge1xyXG4gICAgICAgICAgICByZXF1ZXN0LmhlYWRlcnMgPSB7fTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRva2VuKSB7XHJcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1zdHJpbmctbGl0ZXJhbFxyXG4gICAgICAgICAgICByZXF1ZXN0LmhlYWRlcnNbXCJBdXRob3JpemF0aW9uXCJdID0gXCJCZWFyZXIgXCIgKyB0b2tlbjtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tc3RyaW5nLWxpdGVyYWxcclxuICAgICAgICBpZiAocmVxdWVzdC5oZWFkZXJzW1wiQXV0aG9yaXphdGlvblwiXSkge1xyXG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tc3RyaW5nLWxpdGVyYWxcclxuICAgICAgICAgICAgZGVsZXRlIHJlcXVlc3QuaGVhZGVyc1tcIkF1dGhvcml6YXRpb25cIl07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIExvbmdQb2xsaW5nVHJhbnNwb3J0LnByb3RvdHlwZS5wb2xsID0gZnVuY3Rpb24gKHVybCwgcG9sbE9wdGlvbnMpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciB0b2tlbiwgcG9sbFVybCwgcmVzcG9uc2UsIGVfMTtcclxuICAgICAgICAgICAgcmV0dXJuIF9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYS5sYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EudHJ5cy5wdXNoKFswLCAsIDgsIDldKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnJ1bm5pbmcpIHJldHVybiBbMyAvKmJyZWFrKi8sIDddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLmdldEFjY2Vzc1Rva2VuKCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVhZGVyVG9rZW4ocG9sbE9wdGlvbnMsIHRva2VuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAzO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EudHJ5cy5wdXNoKFszLCA1LCAsIDZdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcG9sbFVybCA9IHVybCArIFwiJl89XCIgKyBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihMb25nUG9sbGluZyB0cmFuc3BvcnQpIHBvbGxpbmc6IFwiICsgcG9sbFVybCArIFwiLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5odHRwQ2xpZW50LmdldChwb2xsVXJsLCBwb2xsT3B0aW9ucyldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBfYS5zZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSAyMDQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sIFwiKExvbmdQb2xsaW5nIHRyYW5zcG9ydCkgUG9sbCB0ZXJtaW5hdGVkIGJ5IHNlcnZlci5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuRXJyb3IsIFwiKExvbmdQb2xsaW5nIHRyYW5zcG9ydCkgVW5leHBlY3RlZCByZXNwb25zZSBjb2RlOiBcIiArIHJlc3BvbnNlLnN0YXR1c0NvZGUgKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHN0YXR1cyBjb2RlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb3NlRXJyb3IgPSBuZXcgRXJyb3JzXzEuSHR0cEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQgfHwgXCJcIiwgcmVzcG9uc2Uuc3RhdHVzQ29kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgdGhlIHJlc3BvbnNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuY29udGVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuVHJhY2UsIFwiKExvbmdQb2xsaW5nIHRyYW5zcG9ydCkgZGF0YSByZWNlaXZlZC4gXCIgKyBVdGlsc18xLmdldERhdGFEZXRhaWwocmVzcG9uc2UuY29udGVudCwgdGhpcy5sb2dNZXNzYWdlQ29udGVudCkgKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25yZWNlaXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25yZWNlaXZlKHJlc3BvbnNlLmNvbnRlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYW5vdGhlciB3YXkgdGltZW91dCBtYW5pZmVzdC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihMb25nUG9sbGluZyB0cmFuc3BvcnQpIFBvbGwgdGltZWQgb3V0LCByZWlzc3VpbmcuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDZdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZV8xID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMucnVubmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTG9nIGJ1dCBkaXNyZWdhcmQgZXJyb3JzIHRoYXQgb2NjdXIgYWZ0ZXIgc3RvcHBpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuVHJhY2UsIFwiKExvbmdQb2xsaW5nIHRyYW5zcG9ydCkgUG9sbCBlcnJvcmVkIGFmdGVyIHNodXRkb3duOiBcIiArIGVfMS5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlXzEgaW5zdGFuY2VvZiBFcnJvcnNfMS5UaW1lb3V0RXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgdGltZW91dHMgYW5kIHJlaXNzdWUgdGhlIHBvbGwuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5UcmFjZSwgXCIoTG9uZ1BvbGxpbmcgdHJhbnNwb3J0KSBQb2xsIHRpbWVkIG91dCwgcmVpc3N1aW5nLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENsb3NlIHRoZSBjb25uZWN0aW9uIHdpdGggdGhlIGVycm9yIGFzIHRoZSByZXN1bHQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9zZUVycm9yID0gZV8xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMyAvKmJyZWFrKi8sIDZdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFszIC8qYnJlYWsqLywgMV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiByZXR1cm4gWzMgLypicmVhayovLCA5XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDg6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuVHJhY2UsIFwiKExvbmdQb2xsaW5nIHRyYW5zcG9ydCkgUG9sbGluZyBjb21wbGV0ZS5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIHdpbGwgcmVhY2ggaGVyZSB3aXRoIHBvbGxBYm9ydGVkPT1mYWxzZSB3aGVuIHRoZSBzZXJ2ZXIgcmV0dXJuZWQgYSByZXNwb25zZSBjYXVzaW5nIHRoZSB0cmFuc3BvcnQgdG8gc3RvcC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgcG9sbEFib3J0ZWQ9PXRydWUgdGhlbiBjbGllbnQgaW5pdGlhdGVkIHRoZSBzdG9wIGFuZCB0aGUgc3RvcCBtZXRob2Qgd2lsbCByYWlzZSB0aGUgY2xvc2UgZXZlbnQgYWZ0ZXIgREVMRVRFIGlzIHNlbnQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5wb2xsQWJvcnRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yYWlzZU9uQ2xvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzcgLyplbmRmaW5hbGx5Ki9dO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgOTogcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBMb25nUG9sbGluZ1RyYW5zcG9ydC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9hKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucnVubmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbMiAvKnJldHVybiovLCBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJDYW5ub3Qgc2VuZCB1bnRpbCB0aGUgdHJhbnNwb3J0IGlzIGNvbm5lY3RlZFwiKSldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFV0aWxzXzEuc2VuZE1lc3NhZ2UodGhpcy5sb2dnZXIsIFwiTG9uZ1BvbGxpbmdcIiwgdGhpcy5odHRwQ2xpZW50LCB0aGlzLnVybCwgdGhpcy5hY2Nlc3NUb2tlbkZhY3RvcnksIGRhdGEsIHRoaXMubG9nTWVzc2FnZUNvbnRlbnQsIHRoaXMud2l0aENyZWRlbnRpYWxzLCB0aGlzLmhlYWRlcnMpXTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgTG9uZ1BvbGxpbmdUcmFuc3BvcnQucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgaGVhZGVycywgX2EsIG5hbWVfMSwgdmFsdWUsIGRlbGV0ZU9wdGlvbnMsIHRva2VuO1xyXG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9iKSB7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKF9iLmxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihMb25nUG9sbGluZyB0cmFuc3BvcnQpIFN0b3BwaW5nIHBvbGxpbmcuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBUZWxsIHJlY2VpdmluZyBsb29wIHRvIHN0b3AsIGFib3J0IGFueSBjdXJyZW50IHJlcXVlc3QsIGFuZCB0aGVuIHdhaXQgZm9yIGl0IHRvIGZpbmlzaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wb2xsQWJvcnQuYWJvcnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2IubGFiZWwgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2IudHJ5cy5wdXNoKFsxLCAsIDUsIDZdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5yZWNlaXZpbmddO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Iuc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTZW5kIERFTEVURSB0byBjbGVhbiB1cCBsb25nIHBvbGxpbmcgb24gdGhlIHNlcnZlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihMb25nUG9sbGluZyB0cmFuc3BvcnQpIHNlbmRpbmcgREVMRVRFIHJlcXVlc3QgdG8gXCIgKyB0aGlzLnVybCArIFwiLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVycyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYSA9IFV0aWxzXzEuZ2V0VXNlckFnZW50SGVhZGVyKCksIG5hbWVfMSA9IF9hWzBdLCB2YWx1ZSA9IF9hWzFdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW25hbWVfMV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlT3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IF9fYXNzaWduKHt9LCBoZWFkZXJzLCB0aGlzLmhlYWRlcnMpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aENyZWRlbnRpYWxzOiB0aGlzLndpdGhDcmVkZW50aWFscyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5nZXRBY2Nlc3NUb2tlbigpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuID0gX2Iuc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlYWRlclRva2VuKGRlbGV0ZU9wdGlvbnMsIHRva2VuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFs0IC8qeWllbGQqLywgdGhpcy5odHRwQ2xpZW50LmRlbGV0ZSh0aGlzLnVybCwgZGVsZXRlT3B0aW9ucyldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Iuc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihMb25nUG9sbGluZyB0cmFuc3BvcnQpIERFTEVURSByZXF1ZXN0IHNlbnQuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzMgLypicmVhayovLCA2XTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuVHJhY2UsIFwiKExvbmdQb2xsaW5nIHRyYW5zcG9ydCkgU3RvcCBmaW5pc2hlZC5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJhaXNlIGNsb3NlIGV2ZW50IGhlcmUgaW5zdGVhZCBvZiBpbiBwb2xsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEl0IG5lZWRzIHRvIGhhcHBlbiBhZnRlciB0aGUgREVMRVRFIHJlcXVlc3QgaXMgc2VudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhaXNlT25DbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzcgLyplbmRmaW5hbGx5Ki9dO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFsyIC8qcmV0dXJuKi9dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBMb25nUG9sbGluZ1RyYW5zcG9ydC5wcm90b3R5cGUucmFpc2VPbkNsb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm9uY2xvc2UpIHtcclxuICAgICAgICAgICAgdmFyIGxvZ01lc3NhZ2UgPSBcIihMb25nUG9sbGluZyB0cmFuc3BvcnQpIEZpcmluZyBvbmNsb3NlIGV2ZW50LlwiO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jbG9zZUVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBsb2dNZXNzYWdlICs9IFwiIEVycm9yOiBcIiArIHRoaXMuY2xvc2VFcnJvcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBsb2dNZXNzYWdlKTtcclxuICAgICAgICAgICAgdGhpcy5vbmNsb3NlKHRoaXMuY2xvc2VFcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBMb25nUG9sbGluZ1RyYW5zcG9ydDtcclxufSgpKTtcclxuZXhwb3J0cy5Mb25nUG9sbGluZ1RyYW5zcG9ydCA9IExvbmdQb2xsaW5nVHJhbnNwb3J0O1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1Mb25nUG9sbGluZ1RyYW5zcG9ydC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hc3NpZ24gPSAodGhpcyAmJiB0aGlzLl9fYXNzaWduKSB8fCBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uKHQpIHtcclxuICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKVxyXG4gICAgICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59O1xyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG52YXIgX19nZW5lcmF0b3IgPSAodGhpcyAmJiB0aGlzLl9fZ2VuZXJhdG9yKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIElMb2dnZXJfMSA9IHJlcXVpcmUoXCIuL0lMb2dnZXJcIik7XHJcbnZhciBJVHJhbnNwb3J0XzEgPSByZXF1aXJlKFwiLi9JVHJhbnNwb3J0XCIpO1xyXG52YXIgVXRpbHNfMSA9IHJlcXVpcmUoXCIuL1V0aWxzXCIpO1xyXG4vKiogQHByaXZhdGUgKi9cclxudmFyIFNlcnZlclNlbnRFdmVudHNUcmFuc3BvcnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBTZXJ2ZXJTZW50RXZlbnRzVHJhbnNwb3J0KGh0dHBDbGllbnQsIGFjY2Vzc1Rva2VuRmFjdG9yeSwgbG9nZ2VyLCBsb2dNZXNzYWdlQ29udGVudCwgZXZlbnRTb3VyY2VDb25zdHJ1Y3Rvciwgd2l0aENyZWRlbnRpYWxzLCBoZWFkZXJzKSB7XHJcbiAgICAgICAgdGhpcy5odHRwQ2xpZW50ID0gaHR0cENsaWVudDtcclxuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSA9IGFjY2Vzc1Rva2VuRmFjdG9yeTtcclxuICAgICAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlcjtcclxuICAgICAgICB0aGlzLmxvZ01lc3NhZ2VDb250ZW50ID0gbG9nTWVzc2FnZUNvbnRlbnQ7XHJcbiAgICAgICAgdGhpcy53aXRoQ3JlZGVudGlhbHMgPSB3aXRoQ3JlZGVudGlhbHM7XHJcbiAgICAgICAgdGhpcy5ldmVudFNvdXJjZUNvbnN0cnVjdG9yID0gZXZlbnRTb3VyY2VDb25zdHJ1Y3RvcjtcclxuICAgICAgICB0aGlzLmhlYWRlcnMgPSBoZWFkZXJzO1xyXG4gICAgICAgIHRoaXMub25yZWNlaXZlID0gbnVsbDtcclxuICAgICAgICB0aGlzLm9uY2xvc2UgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgU2VydmVyU2VudEV2ZW50c1RyYW5zcG9ydC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICh1cmwsIHRyYW5zZmVyRm9ybWF0KSB7XHJcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgdG9rZW47XHJcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxzXzEuQXJnLmlzUmVxdWlyZWQodXJsLCBcInVybFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgVXRpbHNfMS5BcmcuaXNSZXF1aXJlZCh0cmFuc2ZlckZvcm1hdCwgXCJ0cmFuc2ZlckZvcm1hdFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgVXRpbHNfMS5BcmcuaXNJbih0cmFuc2ZlckZvcm1hdCwgSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0LCBcInRyYW5zZmVyRm9ybWF0XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihTU0UgdHJhbnNwb3J0KSBDb25uZWN0aW5nLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHVybCBiZWZvcmUgYWNjZXNzVG9rZW5GYWN0b3J5IGJlY2F1c2UgdGhpcy51cmwgaXMgb25seSBmb3Igc2VuZCBhbmQgd2Ugc2V0IHRoZSBhdXRoIGhlYWRlciBpbnN0ZWFkIG9mIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHNlbmRcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hY2Nlc3NUb2tlbkZhY3RvcnkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDJdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSgpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybCArPSAodXJsLmluZGV4T2YoXCI/XCIpIDwgMCA/IFwiP1wiIDogXCImXCIpICsgKFwiYWNjZXNzX3Rva2VuPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KHRva2VuKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAyO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIFsyIC8qcmV0dXJuKi8sIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcGVuZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFuc2ZlckZvcm1hdCAhPT0gSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0LlRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiVGhlIFNlcnZlci1TZW50IEV2ZW50cyB0cmFuc3BvcnQgb25seSBzdXBwb3J0cyB0aGUgJ1RleHQnIHRyYW5zZmVyIGZvcm1hdFwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50U291cmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFV0aWxzXzEuUGxhdGZvcm0uaXNCcm93c2VyIHx8IFV0aWxzXzEuUGxhdGZvcm0uaXNXZWJXb3JrZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFNvdXJjZSA9IG5ldyBfdGhpcy5ldmVudFNvdXJjZUNvbnN0cnVjdG9yKHVybCwgeyB3aXRoQ3JlZGVudGlhbHM6IF90aGlzLndpdGhDcmVkZW50aWFscyB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vbi1icm93c2VyIHBhc3NlcyBjb29raWVzIHZpYSB0aGUgZGljdGlvbmFyeVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb29raWVzID0gX3RoaXMuaHR0cENsaWVudC5nZXRDb29raWVTdHJpbmcodXJsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGVhZGVycyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMuQ29va2llID0gY29va2llcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgX2EgPSBVdGlsc18xLmdldFVzZXJBZ2VudEhlYWRlcigpLCBuYW1lXzEgPSBfYVswXSwgdmFsdWUgPSBfYVsxXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW25hbWVfMV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFNvdXJjZSA9IG5ldyBfdGhpcy5ldmVudFNvdXJjZUNvbnN0cnVjdG9yKHVybCwgeyB3aXRoQ3JlZGVudGlhbHM6IF90aGlzLndpdGhDcmVkZW50aWFscywgaGVhZGVyczogX19hc3NpZ24oe30sIGhlYWRlcnMsIF90aGlzLmhlYWRlcnMpIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFNvdXJjZS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMub25yZWNlaXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihTU0UgdHJhbnNwb3J0KSBkYXRhIHJlY2VpdmVkLiBcIiArIFV0aWxzXzEuZ2V0RGF0YURldGFpbChlLmRhdGEsIF90aGlzLmxvZ01lc3NhZ2VDb250ZW50KSArIFwiLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5vbnJlY2VpdmUoZS5kYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmNsb3NlKGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U291cmNlLm9uZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoZS5kYXRhIHx8IFwiRXJyb3Igb2NjdXJyZWRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcGVuZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmNsb3NlKGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U291cmNlLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sIFwiU1NFIGNvbm5lY3RlZCB0byBcIiArIF90aGlzLnVybCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmV2ZW50U291cmNlID0gZXZlbnRTb3VyY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZW5lZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIFNlcnZlclNlbnRFdmVudHNUcmFuc3BvcnQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF9fZ2VuZXJhdG9yKHRoaXMsIGZ1bmN0aW9uIChfYSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmV2ZW50U291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsyIC8qcmV0dXJuKi8sIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkNhbm5vdCBzZW5kIHVudGlsIHRoZSB0cmFuc3BvcnQgaXMgY29ubmVjdGVkXCIpKV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qLywgVXRpbHNfMS5zZW5kTWVzc2FnZSh0aGlzLmxvZ2dlciwgXCJTU0VcIiwgdGhpcy5odHRwQ2xpZW50LCB0aGlzLnVybCwgdGhpcy5hY2Nlc3NUb2tlbkZhY3RvcnksIGRhdGEsIHRoaXMubG9nTWVzc2FnZUNvbnRlbnQsIHRoaXMud2l0aENyZWRlbnRpYWxzLCB0aGlzLmhlYWRlcnMpXTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgU2VydmVyU2VudEV2ZW50c1RyYW5zcG9ydC5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfTtcclxuICAgIFNlcnZlclNlbnRFdmVudHNUcmFuc3BvcnQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSkge1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50U291cmNlLmNsb3NlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRTb3VyY2UgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm9uY2xvc2UpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25jbG9zZShlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gU2VydmVyU2VudEV2ZW50c1RyYW5zcG9ydDtcclxufSgpKTtcclxuZXhwb3J0cy5TZXJ2ZXJTZW50RXZlbnRzVHJhbnNwb3J0ID0gU2VydmVyU2VudEV2ZW50c1RyYW5zcG9ydDtcclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2VydmVyU2VudEV2ZW50c1RyYW5zcG9ydC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBVdGlsc18xID0gcmVxdWlyZShcIi4vVXRpbHNcIik7XHJcbi8qKiBTdHJlYW0gaW1wbGVtZW50YXRpb24gdG8gc3RyZWFtIGl0ZW1zIHRvIHRoZSBzZXJ2ZXIuICovXHJcbnZhciBTdWJqZWN0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gU3ViamVjdCgpIHtcclxuICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgfVxyXG4gICAgU3ViamVjdC5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMub2JzZXJ2ZXJzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgb2JzZXJ2ZXIgPSBfYVtfaV07XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm5leHQoaXRlbSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFN1YmplY3QucHJvdG90eXBlLmVycm9yID0gZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLm9ic2VydmVyczsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIG9ic2VydmVyID0gX2FbX2ldO1xyXG4gICAgICAgICAgICBpZiAob2JzZXJ2ZXIuZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgU3ViamVjdC5wcm90b3R5cGUuY29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMub2JzZXJ2ZXJzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgb2JzZXJ2ZXIgPSBfYVtfaV07XHJcbiAgICAgICAgICAgIGlmIChvYnNlcnZlci5jb21wbGV0ZSkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBTdWJqZWN0LnByb3RvdHlwZS5zdWJzY3JpYmUgPSBmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICB0aGlzLm9ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcclxuICAgICAgICByZXR1cm4gbmV3IFV0aWxzXzEuU3ViamVjdFN1YnNjcmlwdGlvbih0aGlzLCBvYnNlcnZlcik7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFN1YmplY3Q7XHJcbn0oKSk7XHJcbmV4cG9ydHMuU3ViamVjdCA9IFN1YmplY3Q7XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN1YmplY3QuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgLk5FVCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vLyBOb3QgZXhwb3J0ZWQgZnJvbSBpbmRleFxyXG4vKiogQHByaXZhdGUgKi9cclxudmFyIFRleHRNZXNzYWdlRm9ybWF0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gVGV4dE1lc3NhZ2VGb3JtYXQoKSB7XHJcbiAgICB9XHJcbiAgICBUZXh0TWVzc2FnZUZvcm1hdC53cml0ZSA9IGZ1bmN0aW9uIChvdXRwdXQpIHtcclxuICAgICAgICByZXR1cm4gXCJcIiArIG91dHB1dCArIFRleHRNZXNzYWdlRm9ybWF0LlJlY29yZFNlcGFyYXRvcjtcclxuICAgIH07XHJcbiAgICBUZXh0TWVzc2FnZUZvcm1hdC5wYXJzZSA9IGZ1bmN0aW9uIChpbnB1dCkge1xyXG4gICAgICAgIGlmIChpbnB1dFtpbnB1dC5sZW5ndGggLSAxXSAhPT0gVGV4dE1lc3NhZ2VGb3JtYXQuUmVjb3JkU2VwYXJhdG9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1lc3NhZ2UgaXMgaW5jb21wbGV0ZS5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBtZXNzYWdlcyA9IGlucHV0LnNwbGl0KFRleHRNZXNzYWdlRm9ybWF0LlJlY29yZFNlcGFyYXRvcik7XHJcbiAgICAgICAgbWVzc2FnZXMucG9wKCk7XHJcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VzO1xyXG4gICAgfTtcclxuICAgIFRleHRNZXNzYWdlRm9ybWF0LlJlY29yZFNlcGFyYXRvckNvZGUgPSAweDFlO1xyXG4gICAgVGV4dE1lc3NhZ2VGb3JtYXQuUmVjb3JkU2VwYXJhdG9yID0gU3RyaW5nLmZyb21DaGFyQ29kZShUZXh0TWVzc2FnZUZvcm1hdC5SZWNvcmRTZXBhcmF0b3JDb2RlKTtcclxuICAgIHJldHVybiBUZXh0TWVzc2FnZUZvcm1hdDtcclxufSgpKTtcclxuZXhwb3J0cy5UZXh0TWVzc2FnZUZvcm1hdCA9IFRleHRNZXNzYWdlRm9ybWF0O1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1UZXh0TWVzc2FnZUZvcm1hdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hc3NpZ24gPSAodGhpcyAmJiB0aGlzLl9fYXNzaWduKSB8fCBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uKHQpIHtcclxuICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKVxyXG4gICAgICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59O1xyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG52YXIgX19nZW5lcmF0b3IgPSAodGhpcyAmJiB0aGlzLl9fZ2VuZXJhdG9yKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIElMb2dnZXJfMSA9IHJlcXVpcmUoXCIuL0lMb2dnZXJcIik7XHJcbnZhciBMb2dnZXJzXzEgPSByZXF1aXJlKFwiLi9Mb2dnZXJzXCIpO1xyXG4vLyBWZXJzaW9uIHRva2VuIHRoYXQgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgcHJlcGFjayBjb21tYW5kXHJcbi8qKiBUaGUgdmVyc2lvbiBvZiB0aGUgU2lnbmFsUiBjbGllbnQuICovXHJcbmV4cG9ydHMuVkVSU0lPTiA9IFwiNS4wLjRcIjtcclxuLyoqIEBwcml2YXRlICovXHJcbnZhciBBcmcgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBBcmcoKSB7XHJcbiAgICB9XHJcbiAgICBBcmcuaXNSZXF1aXJlZCA9IGZ1bmN0aW9uICh2YWwsIG5hbWUpIHtcclxuICAgICAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSAnXCIgKyBuYW1lICsgXCInIGFyZ3VtZW50IGlzIHJlcXVpcmVkLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgQXJnLmlzTm90RW1wdHkgPSBmdW5jdGlvbiAodmFsLCBuYW1lKSB7XHJcbiAgICAgICAgaWYgKCF2YWwgfHwgdmFsLm1hdGNoKC9eXFxzKiQvKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgJ1wiICsgbmFtZSArIFwiJyBhcmd1bWVudCBzaG91bGQgbm90IGJlIGVtcHR5LlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgQXJnLmlzSW4gPSBmdW5jdGlvbiAodmFsLCB2YWx1ZXMsIG5hbWUpIHtcclxuICAgICAgICAvLyBUeXBlU2NyaXB0IGVudW1zIGhhdmUga2V5cyBmb3IgKipib3RoKiogdGhlIG5hbWUgYW5kIHRoZSB2YWx1ZSBvZiBlYWNoIGVudW0gbWVtYmVyIG9uIHRoZSB0eXBlIGl0c2VsZi5cclxuICAgICAgICBpZiAoISh2YWwgaW4gdmFsdWVzKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIFwiICsgbmFtZSArIFwiIHZhbHVlOiBcIiArIHZhbCArIFwiLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEFyZztcclxufSgpKTtcclxuZXhwb3J0cy5BcmcgPSBBcmc7XHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG52YXIgUGxhdGZvcm0gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBQbGF0Zm9ybSgpIHtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShQbGF0Zm9ybSwgXCJpc0Jyb3dzZXJcIiwge1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIjtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShQbGF0Zm9ybSwgXCJpc1dlYldvcmtlclwiLCB7XHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiAmJiBcImltcG9ydFNjcmlwdHNcIiBpbiBzZWxmO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFBsYXRmb3JtLCBcImlzTm9kZVwiLCB7XHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAhdGhpcy5pc0Jyb3dzZXIgJiYgIXRoaXMuaXNXZWJXb3JrZXI7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gUGxhdGZvcm07XHJcbn0oKSk7XHJcbmV4cG9ydHMuUGxhdGZvcm0gPSBQbGF0Zm9ybTtcclxuLyoqIEBwcml2YXRlICovXHJcbmZ1bmN0aW9uIGdldERhdGFEZXRhaWwoZGF0YSwgaW5jbHVkZUNvbnRlbnQpIHtcclxuICAgIHZhciBkZXRhaWwgPSBcIlwiO1xyXG4gICAgaWYgKGlzQXJyYXlCdWZmZXIoZGF0YSkpIHtcclxuICAgICAgICBkZXRhaWwgPSBcIkJpbmFyeSBkYXRhIG9mIGxlbmd0aCBcIiArIGRhdGEuYnl0ZUxlbmd0aDtcclxuICAgICAgICBpZiAoaW5jbHVkZUNvbnRlbnQpIHtcclxuICAgICAgICAgICAgZGV0YWlsICs9IFwiLiBDb250ZW50OiAnXCIgKyBmb3JtYXRBcnJheUJ1ZmZlcihkYXRhKSArIFwiJ1wiO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgZGV0YWlsID0gXCJTdHJpbmcgZGF0YSBvZiBsZW5ndGggXCIgKyBkYXRhLmxlbmd0aDtcclxuICAgICAgICBpZiAoaW5jbHVkZUNvbnRlbnQpIHtcclxuICAgICAgICAgICAgZGV0YWlsICs9IFwiLiBDb250ZW50OiAnXCIgKyBkYXRhICsgXCInXCI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGRldGFpbDtcclxufVxyXG5leHBvcnRzLmdldERhdGFEZXRhaWwgPSBnZXREYXRhRGV0YWlsO1xyXG4vKiogQHByaXZhdGUgKi9cclxuZnVuY3Rpb24gZm9ybWF0QXJyYXlCdWZmZXIoZGF0YSkge1xyXG4gICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShkYXRhKTtcclxuICAgIC8vIFVpbnQ4QXJyYXkubWFwIG9ubHkgc3VwcG9ydHMgcmV0dXJuaW5nIGFub3RoZXIgVWludDhBcnJheT9cclxuICAgIHZhciBzdHIgPSBcIlwiO1xyXG4gICAgdmlldy5mb3JFYWNoKGZ1bmN0aW9uIChudW0pIHtcclxuICAgICAgICB2YXIgcGFkID0gbnVtIDwgMTYgPyBcIjBcIiA6IFwiXCI7XHJcbiAgICAgICAgc3RyICs9IFwiMHhcIiArIHBhZCArIG51bS50b1N0cmluZygxNikgKyBcIiBcIjtcclxuICAgIH0pO1xyXG4gICAgLy8gVHJpbSBvZiB0cmFpbGluZyBzcGFjZS5cclxuICAgIHJldHVybiBzdHIuc3Vic3RyKDAsIHN0ci5sZW5ndGggLSAxKTtcclxufVxyXG5leHBvcnRzLmZvcm1hdEFycmF5QnVmZmVyID0gZm9ybWF0QXJyYXlCdWZmZXI7XHJcbi8vIEFsc28gaW4gc2lnbmFsci1wcm90b2NvbC1tc2dwYWNrL1V0aWxzLnRzXHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG5mdW5jdGlvbiBpc0FycmF5QnVmZmVyKHZhbCkge1xyXG4gICAgcmV0dXJuIHZhbCAmJiB0eXBlb2YgQXJyYXlCdWZmZXIgIT09IFwidW5kZWZpbmVkXCIgJiZcclxuICAgICAgICAodmFsIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHxcclxuICAgICAgICAgICAgLy8gU29tZXRpbWVzIHdlIGdldCBhbiBBcnJheUJ1ZmZlciB0aGF0IGRvZXNuJ3Qgc2F0aXNmeSBpbnN0YW5jZW9mXHJcbiAgICAgICAgICAgICh2YWwuY29uc3RydWN0b3IgJiYgdmFsLmNvbnN0cnVjdG9yLm5hbWUgPT09IFwiQXJyYXlCdWZmZXJcIikpO1xyXG59XHJcbmV4cG9ydHMuaXNBcnJheUJ1ZmZlciA9IGlzQXJyYXlCdWZmZXI7XHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG5mdW5jdGlvbiBzZW5kTWVzc2FnZShsb2dnZXIsIHRyYW5zcG9ydE5hbWUsIGh0dHBDbGllbnQsIHVybCwgYWNjZXNzVG9rZW5GYWN0b3J5LCBjb250ZW50LCBsb2dNZXNzYWdlQ29udGVudCwgd2l0aENyZWRlbnRpYWxzLCBkZWZhdWx0SGVhZGVycykge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfYSwgaGVhZGVycywgdG9rZW4sIF9iLCBuYW1lLCB2YWx1ZSwgcmVzcG9uc2VUeXBlLCByZXNwb25zZTtcclxuICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9jKSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoX2MubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhY2Nlc3NUb2tlbkZhY3RvcnkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDJdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCAvKnlpZWxkKi8sIGFjY2Vzc1Rva2VuRmFjdG9yeSgpXTtcclxuICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICB0b2tlbiA9IF9jLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVycyA9IChfYSA9IHt9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FbXCJBdXRob3JpemF0aW9uXCJdID0gXCJCZWFyZXIgXCIgKyB0b2tlbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgX2MubGFiZWwgPSAyO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgICAgIF9iID0gZ2V0VXNlckFnZW50SGVhZGVyKCksIG5hbWUgPSBfYlswXSwgdmFsdWUgPSBfYlsxXTtcclxuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW25hbWVdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuVHJhY2UsIFwiKFwiICsgdHJhbnNwb3J0TmFtZSArIFwiIHRyYW5zcG9ydCkgc2VuZGluZyBkYXRhLiBcIiArIGdldERhdGFEZXRhaWwoY29udGVudCwgbG9nTWVzc2FnZUNvbnRlbnQpICsgXCIuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlVHlwZSA9IGlzQXJyYXlCdWZmZXIoY29udGVudCkgPyBcImFycmF5YnVmZmVyXCIgOiBcInRleHRcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCBodHRwQ2xpZW50LnBvc3QodXJsLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBjb250ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogX19hc3NpZ24oe30sIGhlYWRlcnMsIGRlZmF1bHRIZWFkZXJzKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlVHlwZTogcmVzcG9uc2VUeXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aENyZWRlbnRpYWxzOiB3aXRoQ3JlZGVudGlhbHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXTtcclxuICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IF9jLnNlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5UcmFjZSwgXCIoXCIgKyB0cmFuc3BvcnROYW1lICsgXCIgdHJhbnNwb3J0KSByZXF1ZXN0IGNvbXBsZXRlLiBSZXNwb25zZSBzdGF0dXM6IFwiICsgcmVzcG9uc2Uuc3RhdHVzQ29kZSArIFwiLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzIgLypyZXR1cm4qL107XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuc2VuZE1lc3NhZ2UgPSBzZW5kTWVzc2FnZTtcclxuLyoqIEBwcml2YXRlICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihsb2dnZXIpIHtcclxuICAgIGlmIChsb2dnZXIgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQ29uc29sZUxvZ2dlcihJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24pO1xyXG4gICAgfVxyXG4gICAgaWYgKGxvZ2dlciA9PT0gbnVsbCkge1xyXG4gICAgICAgIHJldHVybiBMb2dnZXJzXzEuTnVsbExvZ2dlci5pbnN0YW5jZTtcclxuICAgIH1cclxuICAgIGlmIChsb2dnZXIubG9nKSB7XHJcbiAgICAgICAgcmV0dXJuIGxvZ2dlcjtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgQ29uc29sZUxvZ2dlcihsb2dnZXIpO1xyXG59XHJcbmV4cG9ydHMuY3JlYXRlTG9nZ2VyID0gY3JlYXRlTG9nZ2VyO1xyXG4vKiogQHByaXZhdGUgKi9cclxudmFyIFN1YmplY3RTdWJzY3JpcHRpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBTdWJqZWN0U3Vic2NyaXB0aW9uKHN1YmplY3QsIG9ic2VydmVyKSB7XHJcbiAgICAgICAgdGhpcy5zdWJqZWN0ID0gc3ViamVjdDtcclxuICAgICAgICB0aGlzLm9ic2VydmVyID0gb2JzZXJ2ZXI7XHJcbiAgICB9XHJcbiAgICBTdWJqZWN0U3Vic2NyaXB0aW9uLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMuc3ViamVjdC5vYnNlcnZlcnMuaW5kZXhPZih0aGlzLm9ic2VydmVyKTtcclxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLnN1YmplY3Qub2JzZXJ2ZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnN1YmplY3Qub2JzZXJ2ZXJzLmxlbmd0aCA9PT0gMCAmJiB0aGlzLnN1YmplY3QuY2FuY2VsQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdGhpcy5zdWJqZWN0LmNhbmNlbENhbGxiYWNrKCkuY2F0Y2goZnVuY3Rpb24gKF8pIHsgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBTdWJqZWN0U3Vic2NyaXB0aW9uO1xyXG59KCkpO1xyXG5leHBvcnRzLlN1YmplY3RTdWJzY3JpcHRpb24gPSBTdWJqZWN0U3Vic2NyaXB0aW9uO1xyXG4vKiogQHByaXZhdGUgKi9cclxudmFyIENvbnNvbGVMb2dnZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBDb25zb2xlTG9nZ2VyKG1pbmltdW1Mb2dMZXZlbCkge1xyXG4gICAgICAgIHRoaXMubWluaW11bUxvZ0xldmVsID0gbWluaW11bUxvZ0xldmVsO1xyXG4gICAgICAgIHRoaXMub3V0cHV0Q29uc29sZSA9IGNvbnNvbGU7XHJcbiAgICB9XHJcbiAgICBDb25zb2xlTG9nZ2VyLnByb3RvdHlwZS5sb2cgPSBmdW5jdGlvbiAobG9nTGV2ZWwsIG1lc3NhZ2UpIHtcclxuICAgICAgICBpZiAobG9nTGV2ZWwgPj0gdGhpcy5taW5pbXVtTG9nTGV2ZWwpIHtcclxuICAgICAgICAgICAgc3dpdGNoIChsb2dMZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBJTG9nZ2VyXzEuTG9nTGV2ZWwuQ3JpdGljYWw6XHJcbiAgICAgICAgICAgICAgICBjYXNlIElMb2dnZXJfMS5Mb2dMZXZlbC5FcnJvcjpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dHB1dENvbnNvbGUuZXJyb3IoXCJbXCIgKyBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgKyBcIl0gXCIgKyBJTG9nZ2VyXzEuTG9nTGV2ZWxbbG9nTGV2ZWxdICsgXCI6IFwiICsgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIElMb2dnZXJfMS5Mb2dMZXZlbC5XYXJuaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0Q29uc29sZS53YXJuKFwiW1wiICsgbmV3IERhdGUoKS50b0lTT1N0cmluZygpICsgXCJdIFwiICsgSUxvZ2dlcl8xLkxvZ0xldmVsW2xvZ0xldmVsXSArIFwiOiBcIiArIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb246XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRDb25zb2xlLmluZm8oXCJbXCIgKyBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgKyBcIl0gXCIgKyBJTG9nZ2VyXzEuTG9nTGV2ZWxbbG9nTGV2ZWxdICsgXCI6IFwiICsgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUuZGVidWcgb25seSBnb2VzIHRvIGF0dGFjaGVkIGRlYnVnZ2VycyBpbiBOb2RlLCBzbyB3ZSB1c2UgY29uc29sZS5sb2cgZm9yIFRyYWNlIGFuZCBEZWJ1Z1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0Q29uc29sZS5sb2coXCJbXCIgKyBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgKyBcIl0gXCIgKyBJTG9nZ2VyXzEuTG9nTGV2ZWxbbG9nTGV2ZWxdICsgXCI6IFwiICsgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENvbnNvbGVMb2dnZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuQ29uc29sZUxvZ2dlciA9IENvbnNvbGVMb2dnZXI7XHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG5mdW5jdGlvbiBnZXRVc2VyQWdlbnRIZWFkZXIoKSB7XHJcbiAgICB2YXIgdXNlckFnZW50SGVhZGVyTmFtZSA9IFwiWC1TaWduYWxSLVVzZXItQWdlbnRcIjtcclxuICAgIGlmIChQbGF0Zm9ybS5pc05vZGUpIHtcclxuICAgICAgICB1c2VyQWdlbnRIZWFkZXJOYW1lID0gXCJVc2VyLUFnZW50XCI7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gW3VzZXJBZ2VudEhlYWRlck5hbWUsIGNvbnN0cnVjdFVzZXJBZ2VudChleHBvcnRzLlZFUlNJT04sIGdldE9zTmFtZSgpLCBnZXRSdW50aW1lKCksIGdldFJ1bnRpbWVWZXJzaW9uKCkpXTtcclxufVxyXG5leHBvcnRzLmdldFVzZXJBZ2VudEhlYWRlciA9IGdldFVzZXJBZ2VudEhlYWRlcjtcclxuLyoqIEBwcml2YXRlICovXHJcbmZ1bmN0aW9uIGNvbnN0cnVjdFVzZXJBZ2VudCh2ZXJzaW9uLCBvcywgcnVudGltZSwgcnVudGltZVZlcnNpb24pIHtcclxuICAgIC8vIE1pY3Jvc29mdCBTaWduYWxSL1tWZXJzaW9uXSAoW0RldGFpbGVkIFZlcnNpb25dOyBbT3BlcmF0aW5nIFN5c3RlbV07IFtSdW50aW1lXTsgW1J1bnRpbWUgVmVyc2lvbl0pXHJcbiAgICB2YXIgdXNlckFnZW50ID0gXCJNaWNyb3NvZnQgU2lnbmFsUi9cIjtcclxuICAgIHZhciBtYWpvckFuZE1pbm9yID0gdmVyc2lvbi5zcGxpdChcIi5cIik7XHJcbiAgICB1c2VyQWdlbnQgKz0gbWFqb3JBbmRNaW5vclswXSArIFwiLlwiICsgbWFqb3JBbmRNaW5vclsxXTtcclxuICAgIHVzZXJBZ2VudCArPSBcIiAoXCIgKyB2ZXJzaW9uICsgXCI7IFwiO1xyXG4gICAgaWYgKG9zICYmIG9zICE9PSBcIlwiKSB7XHJcbiAgICAgICAgdXNlckFnZW50ICs9IG9zICsgXCI7IFwiO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdXNlckFnZW50ICs9IFwiVW5rbm93biBPUzsgXCI7XHJcbiAgICB9XHJcbiAgICB1c2VyQWdlbnQgKz0gXCJcIiArIHJ1bnRpbWU7XHJcbiAgICBpZiAocnVudGltZVZlcnNpb24pIHtcclxuICAgICAgICB1c2VyQWdlbnQgKz0gXCI7IFwiICsgcnVudGltZVZlcnNpb247XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICB1c2VyQWdlbnQgKz0gXCI7IFVua25vd24gUnVudGltZSBWZXJzaW9uXCI7XHJcbiAgICB9XHJcbiAgICB1c2VyQWdlbnQgKz0gXCIpXCI7XHJcbiAgICByZXR1cm4gdXNlckFnZW50O1xyXG59XHJcbmV4cG9ydHMuY29uc3RydWN0VXNlckFnZW50ID0gY29uc3RydWN0VXNlckFnZW50O1xyXG5mdW5jdGlvbiBnZXRPc05hbWUoKSB7XHJcbiAgICBpZiAoUGxhdGZvcm0uaXNOb2RlKSB7XHJcbiAgICAgICAgc3dpdGNoIChwcm9jZXNzLnBsYXRmb3JtKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJ3aW4zMlwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiV2luZG93cyBOVFwiO1xyXG4gICAgICAgICAgICBjYXNlIFwiZGFyd2luXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJtYWNPU1wiO1xyXG4gICAgICAgICAgICBjYXNlIFwibGludXhcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBcIkxpbnV4XCI7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvY2Vzcy5wbGF0Zm9ybTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gXCJcIjtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBnZXRSdW50aW1lVmVyc2lvbigpIHtcclxuICAgIGlmIChQbGF0Zm9ybS5pc05vZGUpIHtcclxuICAgICAgICByZXR1cm4gcHJvY2Vzcy52ZXJzaW9ucy5ub2RlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcclxufVxyXG5mdW5jdGlvbiBnZXRSdW50aW1lKCkge1xyXG4gICAgaWYgKFBsYXRmb3JtLmlzTm9kZSkge1xyXG4gICAgICAgIHJldHVybiBcIk5vZGVKU1wiO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIFwiQnJvd3NlclwiO1xyXG4gICAgfVxyXG59XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVV0aWxzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIC5ORVQgRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbnZhciBfX2Fzc2lnbiA9ICh0aGlzICYmIHRoaXMuX19hc3NpZ24pIHx8IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24odCkge1xyXG4gICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpXHJcbiAgICAgICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn07XHJcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZShyZXN1bHQudmFsdWUpOyB9KS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn07XHJcbnZhciBfX2dlbmVyYXRvciA9ICh0aGlzICYmIHRoaXMuX19nZW5lcmF0b3IpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgSUxvZ2dlcl8xID0gcmVxdWlyZShcIi4vSUxvZ2dlclwiKTtcclxudmFyIElUcmFuc3BvcnRfMSA9IHJlcXVpcmUoXCIuL0lUcmFuc3BvcnRcIik7XHJcbnZhciBVdGlsc18xID0gcmVxdWlyZShcIi4vVXRpbHNcIik7XHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG52YXIgV2ViU29ja2V0VHJhbnNwb3J0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gV2ViU29ja2V0VHJhbnNwb3J0KGh0dHBDbGllbnQsIGFjY2Vzc1Rva2VuRmFjdG9yeSwgbG9nZ2VyLCBsb2dNZXNzYWdlQ29udGVudCwgd2ViU29ja2V0Q29uc3RydWN0b3IsIGhlYWRlcnMpIHtcclxuICAgICAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlcjtcclxuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSA9IGFjY2Vzc1Rva2VuRmFjdG9yeTtcclxuICAgICAgICB0aGlzLmxvZ01lc3NhZ2VDb250ZW50ID0gbG9nTWVzc2FnZUNvbnRlbnQ7XHJcbiAgICAgICAgdGhpcy53ZWJTb2NrZXRDb25zdHJ1Y3RvciA9IHdlYlNvY2tldENvbnN0cnVjdG9yO1xyXG4gICAgICAgIHRoaXMuaHR0cENsaWVudCA9IGh0dHBDbGllbnQ7XHJcbiAgICAgICAgdGhpcy5vbnJlY2VpdmUgPSBudWxsO1xyXG4gICAgICAgIHRoaXMub25jbG9zZSA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gaGVhZGVycztcclxuICAgIH1cclxuICAgIFdlYlNvY2tldFRyYW5zcG9ydC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICh1cmwsIHRyYW5zZmVyRm9ybWF0KSB7XHJcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgdG9rZW47XHJcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoX2EubGFiZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxzXzEuQXJnLmlzUmVxdWlyZWQodXJsLCBcInVybFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgVXRpbHNfMS5BcmcuaXNSZXF1aXJlZCh0cmFuc2ZlckZvcm1hdCwgXCJ0cmFuc2ZlckZvcm1hdFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgVXRpbHNfMS5BcmcuaXNJbih0cmFuc2ZlckZvcm1hdCwgSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0LCBcInRyYW5zZmVyRm9ybWF0XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihXZWJTb2NrZXRzIHRyYW5zcG9ydCkgQ29ubmVjdGluZy5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hY2Nlc3NUb2tlbkZhY3RvcnkpIHJldHVybiBbMyAvKmJyZWFrKi8sIDJdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQgLyp5aWVsZCovLCB0aGlzLmFjY2Vzc1Rva2VuRmFjdG9yeSgpXTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuID0gX2Euc2VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybCArPSAodXJsLmluZGV4T2YoXCI/XCIpIDwgMCA/IFwiP1wiIDogXCImXCIpICsgKFwiYWNjZXNzX3Rva2VuPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KHRva2VuKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubGFiZWwgPSAyO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIFsyIC8qcmV0dXJuKi8sIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IHVybC5yZXBsYWNlKC9eaHR0cC8sIFwid3NcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2ViU29ja2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvb2tpZXMgPSBfdGhpcy5odHRwQ2xpZW50LmdldENvb2tpZVN0cmluZyh1cmwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9wZW5lZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFV0aWxzXzEuUGxhdGZvcm0uaXNOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgX2EgPSBVdGlsc18xLmdldFVzZXJBZ2VudEhlYWRlcigpLCBuYW1lXzEgPSBfYVswXSwgdmFsdWUgPSBfYVsxXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW25hbWVfMV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW1wiQ29va2llXCJdID0gXCJcIiArIGNvb2tpZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgcGFzcyBoZWFkZXJzIHdoZW4gaW4gbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2ViU29ja2V0ID0gbmV3IF90aGlzLndlYlNvY2tldENvbnN0cnVjdG9yKHVybCwgdW5kZWZpbmVkLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IF9fYXNzaWduKHt9LCBoZWFkZXJzLCBfdGhpcy5oZWFkZXJzKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghd2ViU29ja2V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hyb21lIGlzIG5vdCBoYXBweSB3aXRoIHBhc3NpbmcgJ3VuZGVmaW5lZCcgYXMgcHJvdG9jb2xcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWJTb2NrZXQgPSBuZXcgX3RoaXMud2ViU29ja2V0Q29uc3RydWN0b3IodXJsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFuc2ZlckZvcm1hdCA9PT0gSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0LkJpbmFyeSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlYlNvY2tldC5iaW5hcnlUeXBlID0gXCJhcnJheWJ1ZmZlclwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlYlNvY2tldC5vbm9wZW4gPSBmdW5jdGlvbiAoX2V2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuSW5mb3JtYXRpb24sIFwiV2ViU29ja2V0IGNvbm5lY3RlZCB0byBcIiArIHVybCArIFwiLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy53ZWJTb2NrZXQgPSB3ZWJTb2NrZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlbmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2ViU29ja2V0Lm9uZXJyb3IgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVycm9yRXZlbnQgaXMgYSBicm93c2VyIG9ubHkgdHlwZSB3ZSBuZWVkIHRvIGNoZWNrIGlmIHRoZSB0eXBlIGV4aXN0cyBiZWZvcmUgdXNpbmcgaXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIEVycm9yRXZlbnQgIT09IFwidW5kZWZpbmVkXCIgJiYgZXZlbnQgaW5zdGFuY2VvZiBFcnJvckV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXZlbnQuZXJyb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihcIlRoZXJlIHdhcyBhbiBlcnJvciB3aXRoIHRoZSB0cmFuc3BvcnQuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlYlNvY2tldC5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmxvZ2dlci5sb2coSUxvZ2dlcl8xLkxvZ0xldmVsLlRyYWNlLCBcIihXZWJTb2NrZXRzIHRyYW5zcG9ydCkgZGF0YSByZWNlaXZlZC4gXCIgKyBVdGlsc18xLmdldERhdGFEZXRhaWwobWVzc2FnZS5kYXRhLCBfdGhpcy5sb2dNZXNzYWdlQ29udGVudCkgKyBcIi5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLm9ucmVjZWl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMub25yZWNlaXZlKG1lc3NhZ2UuZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5jbG9zZShlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2ViU29ja2V0Lm9uY2xvc2UgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEb24ndCBjYWxsIGNsb3NlIGhhbmRsZXIgaWYgY29ubmVjdGlvbiB3YXMgbmV2ZXIgZXN0YWJsaXNoZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSdsbCByZWplY3QgdGhlIGNvbm5lY3QgY2FsbCBpbnN0ZWFkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5jbG9zZShldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFcnJvckV2ZW50IGlzIGEgYnJvd3NlciBvbmx5IHR5cGUgd2UgbmVlZCB0byBjaGVjayBpZiB0aGUgdHlwZSBleGlzdHMgYmVmb3JlIHVzaW5nIGl0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgRXJyb3JFdmVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBldmVudCBpbnN0YW5jZW9mIEVycm9yRXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXZlbnQuZXJyb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihcIlRoZXJlIHdhcyBhbiBlcnJvciB3aXRoIHRoZSB0cmFuc3BvcnQuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBXZWJTb2NrZXRUcmFuc3BvcnQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIGlmICh0aGlzLndlYlNvY2tldCAmJiB0aGlzLndlYlNvY2tldC5yZWFkeVN0YXRlID09PSB0aGlzLndlYlNvY2tldENvbnN0cnVjdG9yLk9QRU4pIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5UcmFjZSwgXCIoV2ViU29ja2V0cyB0cmFuc3BvcnQpIHNlbmRpbmcgZGF0YS4gXCIgKyBVdGlsc18xLmdldERhdGFEZXRhaWwoZGF0YSwgdGhpcy5sb2dNZXNzYWdlQ29udGVudCkgKyBcIi5cIik7XHJcbiAgICAgICAgICAgIHRoaXMud2ViU29ja2V0LnNlbmQoZGF0YSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFwiV2ViU29ja2V0IGlzIG5vdCBpbiB0aGUgT1BFTiBzdGF0ZVwiKTtcclxuICAgIH07XHJcbiAgICBXZWJTb2NrZXRUcmFuc3BvcnQucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMud2ViU29ja2V0KSB7XHJcbiAgICAgICAgICAgIC8vIE1hbnVhbGx5IGludm9rZSBvbmNsb3NlIGNhbGxiYWNrIGlubGluZSBzbyB3ZSBrbm93IHRoZSBIdHRwQ29ubmVjdGlvbiB3YXMgY2xvc2VkIHByb3Blcmx5IGJlZm9yZSByZXR1cm5pbmdcclxuICAgICAgICAgICAgLy8gVGhpcyBhbHNvIHNvbHZlcyBhbiBpc3N1ZSB3aGVyZSB3ZWJzb2NrZXQub25jbG9zZSBjb3VsZCB0YWtlIDE4KyBzZWNvbmRzIHRvIHRyaWdnZXIgZHVyaW5nIG5ldHdvcmsgZGlzY29ubmVjdHNcclxuICAgICAgICAgICAgdGhpcy5jbG9zZSh1bmRlZmluZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICB9O1xyXG4gICAgV2ViU29ja2V0VHJhbnNwb3J0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIC8vIHdlYlNvY2tldCB3aWxsIGJlIG51bGwgaWYgdGhlIHRyYW5zcG9ydCBkaWQgbm90IHN0YXJ0IHN1Y2Nlc3NmdWxseVxyXG4gICAgICAgIGlmICh0aGlzLndlYlNvY2tldCkge1xyXG4gICAgICAgICAgICAvLyBDbGVhciB3ZWJzb2NrZXQgaGFuZGxlcnMgYmVjYXVzZSB3ZSBhcmUgY29uc2lkZXJpbmcgdGhlIHNvY2tldCBjbG9zZWQgbm93XHJcbiAgICAgICAgICAgIHRoaXMud2ViU29ja2V0Lm9uY2xvc2UgPSBmdW5jdGlvbiAoKSB7IH07XHJcbiAgICAgICAgICAgIHRoaXMud2ViU29ja2V0Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHsgfTtcclxuICAgICAgICAgICAgdGhpcy53ZWJTb2NrZXQub25lcnJvciA9IGZ1bmN0aW9uICgpIHsgfTtcclxuICAgICAgICAgICAgdGhpcy53ZWJTb2NrZXQuY2xvc2UoKTtcclxuICAgICAgICAgICAgdGhpcy53ZWJTb2NrZXQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubG9nZ2VyLmxvZyhJTG9nZ2VyXzEuTG9nTGV2ZWwuVHJhY2UsIFwiKFdlYlNvY2tldHMgdHJhbnNwb3J0KSBzb2NrZXQgY2xvc2VkLlwiKTtcclxuICAgICAgICBpZiAodGhpcy5vbmNsb3NlKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQ2xvc2VFdmVudChldmVudCkgJiYgKGV2ZW50Lndhc0NsZWFuID09PSBmYWxzZSB8fCBldmVudC5jb2RlICE9PSAxMDAwKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbmNsb3NlKG5ldyBFcnJvcihcIldlYlNvY2tldCBjbG9zZWQgd2l0aCBzdGF0dXMgY29kZTogXCIgKyBldmVudC5jb2RlICsgXCIgKFwiICsgZXZlbnQucmVhc29uICsgXCIpLlwiKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnQgaW5zdGFuY2VvZiBFcnJvcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbmNsb3NlKGV2ZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25jbG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFdlYlNvY2tldFRyYW5zcG9ydC5wcm90b3R5cGUuaXNDbG9zZUV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGV2ZW50ICYmIHR5cGVvZiBldmVudC53YXNDbGVhbiA9PT0gXCJib29sZWFuXCIgJiYgdHlwZW9mIGV2ZW50LmNvZGUgPT09IFwibnVtYmVyXCI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFdlYlNvY2tldFRyYW5zcG9ydDtcclxufSgpKTtcclxuZXhwb3J0cy5XZWJTb2NrZXRUcmFuc3BvcnQgPSBXZWJTb2NrZXRUcmFuc3BvcnQ7XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVdlYlNvY2tldFRyYW5zcG9ydC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSAuTkVUIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgRXJyb3JzXzEgPSByZXF1aXJlKFwiLi9FcnJvcnNcIik7XHJcbnZhciBIdHRwQ2xpZW50XzEgPSByZXF1aXJlKFwiLi9IdHRwQ2xpZW50XCIpO1xyXG52YXIgSUxvZ2dlcl8xID0gcmVxdWlyZShcIi4vSUxvZ2dlclwiKTtcclxudmFyIFhockh0dHBDbGllbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoWGhySHR0cENsaWVudCwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFhockh0dHBDbGllbnQobG9nZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5sb2dnZXIgPSBsb2dnZXI7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgLyoqIEBpbmhlcml0RG9jICovXHJcbiAgICBYaHJIdHRwQ2xpZW50LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIC8vIENoZWNrIHRoYXQgYWJvcnQgd2FzIG5vdCBzaWduYWxlZCBiZWZvcmUgY2FsbGluZyBzZW5kXHJcbiAgICAgICAgaWYgKHJlcXVlc3QuYWJvcnRTaWduYWwgJiYgcmVxdWVzdC5hYm9ydFNpZ25hbC5hYm9ydGVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3JzXzEuQWJvcnRFcnJvcigpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFyZXF1ZXN0Lm1ldGhvZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gbWV0aG9kIGRlZmluZWQuXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFyZXF1ZXN0LnVybCkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gdXJsIGRlZmluZWQuXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG4gICAgICAgICAgICB4aHIub3BlbihyZXF1ZXN0Lm1ldGhvZCwgcmVxdWVzdC51cmwsIHRydWUpO1xyXG4gICAgICAgICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gcmVxdWVzdC53aXRoQ3JlZGVudGlhbHMgPT09IHVuZGVmaW5lZCA/IHRydWUgOiByZXF1ZXN0LndpdGhDcmVkZW50aWFscztcclxuICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJYLVJlcXVlc3RlZC1XaXRoXCIsIFwiWE1MSHR0cFJlcXVlc3RcIik7XHJcbiAgICAgICAgICAgIC8vIEV4cGxpY2l0bHkgc2V0dGluZyB0aGUgQ29udGVudC1UeXBlIGhlYWRlciBmb3IgUmVhY3QgTmF0aXZlIG9uIEFuZHJvaWQgcGxhdGZvcm0uXHJcbiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsIFwidGV4dC9wbGFpbjtjaGFyc2V0PVVURi04XCIpO1xyXG4gICAgICAgICAgICB2YXIgaGVhZGVycyA9IHJlcXVlc3QuaGVhZGVycztcclxuICAgICAgICAgICAgaWYgKGhlYWRlcnMpIHtcclxuICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGhlYWRlcnMpXHJcbiAgICAgICAgICAgICAgICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGhlYWRlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGhlYWRlciwgaGVhZGVyc1toZWFkZXJdKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0LnJlc3BvbnNlVHlwZSkge1xyXG4gICAgICAgICAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9IHJlcXVlc3QucmVzcG9uc2VUeXBlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0LmFib3J0U2lnbmFsKSB7XHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0LmFib3J0U2lnbmFsLm9uYWJvcnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeGhyLmFib3J0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcnNfMS5BYm9ydEVycm9yKCkpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdC50aW1lb3V0KSB7XHJcbiAgICAgICAgICAgICAgICB4aHIudGltZW91dCA9IHJlcXVlc3QudGltZW91dDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB4aHIub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlcXVlc3QuYWJvcnRTaWduYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LmFib3J0U2lnbmFsLm9uYWJvcnQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPj0gMjAwICYmIHhoci5zdGF0dXMgPCAzMDApIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBIdHRwQ2xpZW50XzEuSHR0cFJlc3BvbnNlKHhoci5zdGF0dXMsIHhoci5zdGF0dXNUZXh0LCB4aHIucmVzcG9uc2UgfHwgeGhyLnJlc3BvbnNlVGV4dCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcnNfMS5IdHRwRXJyb3IoeGhyLnN0YXR1c1RleHQsIHhoci5zdGF0dXMpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5XYXJuaW5nLCBcIkVycm9yIGZyb20gSFRUUCByZXF1ZXN0LiBcIiArIHhoci5zdGF0dXMgKyBcIjogXCIgKyB4aHIuc3RhdHVzVGV4dCArIFwiLlwiKTtcclxuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3JzXzEuSHR0cEVycm9yKHhoci5zdGF0dXNUZXh0LCB4aHIuc3RhdHVzKSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHhoci5vbnRpbWVvdXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5sb2dnZXIubG9nKElMb2dnZXJfMS5Mb2dMZXZlbC5XYXJuaW5nLCBcIlRpbWVvdXQgZnJvbSBIVFRQIHJlcXVlc3QuXCIpO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcnNfMS5UaW1lb3V0RXJyb3IoKSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHhoci5zZW5kKHJlcXVlc3QuY29udGVudCB8fCBcIlwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gWGhySHR0cENsaWVudDtcclxufShIdHRwQ2xpZW50XzEuSHR0cENsaWVudCkpO1xyXG5leHBvcnRzLlhockh0dHBDbGllbnQgPSBYaHJIdHRwQ2xpZW50O1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1YaHJIdHRwQ2xpZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIC5ORVQgRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIEVycm9yc18xID0gcmVxdWlyZShcIi4vRXJyb3JzXCIpO1xyXG5leHBvcnRzLkFib3J0RXJyb3IgPSBFcnJvcnNfMS5BYm9ydEVycm9yO1xyXG5leHBvcnRzLkh0dHBFcnJvciA9IEVycm9yc18xLkh0dHBFcnJvcjtcclxuZXhwb3J0cy5UaW1lb3V0RXJyb3IgPSBFcnJvcnNfMS5UaW1lb3V0RXJyb3I7XHJcbnZhciBIdHRwQ2xpZW50XzEgPSByZXF1aXJlKFwiLi9IdHRwQ2xpZW50XCIpO1xyXG5leHBvcnRzLkh0dHBDbGllbnQgPSBIdHRwQ2xpZW50XzEuSHR0cENsaWVudDtcclxuZXhwb3J0cy5IdHRwUmVzcG9uc2UgPSBIdHRwQ2xpZW50XzEuSHR0cFJlc3BvbnNlO1xyXG52YXIgRGVmYXVsdEh0dHBDbGllbnRfMSA9IHJlcXVpcmUoXCIuL0RlZmF1bHRIdHRwQ2xpZW50XCIpO1xyXG5leHBvcnRzLkRlZmF1bHRIdHRwQ2xpZW50ID0gRGVmYXVsdEh0dHBDbGllbnRfMS5EZWZhdWx0SHR0cENsaWVudDtcclxudmFyIEh1YkNvbm5lY3Rpb25fMSA9IHJlcXVpcmUoXCIuL0h1YkNvbm5lY3Rpb25cIik7XHJcbmV4cG9ydHMuSHViQ29ubmVjdGlvbiA9IEh1YkNvbm5lY3Rpb25fMS5IdWJDb25uZWN0aW9uO1xyXG5leHBvcnRzLkh1YkNvbm5lY3Rpb25TdGF0ZSA9IEh1YkNvbm5lY3Rpb25fMS5IdWJDb25uZWN0aW9uU3RhdGU7XHJcbnZhciBIdWJDb25uZWN0aW9uQnVpbGRlcl8xID0gcmVxdWlyZShcIi4vSHViQ29ubmVjdGlvbkJ1aWxkZXJcIik7XHJcbmV4cG9ydHMuSHViQ29ubmVjdGlvbkJ1aWxkZXIgPSBIdWJDb25uZWN0aW9uQnVpbGRlcl8xLkh1YkNvbm5lY3Rpb25CdWlsZGVyO1xyXG52YXIgSUh1YlByb3RvY29sXzEgPSByZXF1aXJlKFwiLi9JSHViUHJvdG9jb2xcIik7XHJcbmV4cG9ydHMuTWVzc2FnZVR5cGUgPSBJSHViUHJvdG9jb2xfMS5NZXNzYWdlVHlwZTtcclxudmFyIElMb2dnZXJfMSA9IHJlcXVpcmUoXCIuL0lMb2dnZXJcIik7XHJcbmV4cG9ydHMuTG9nTGV2ZWwgPSBJTG9nZ2VyXzEuTG9nTGV2ZWw7XHJcbnZhciBJVHJhbnNwb3J0XzEgPSByZXF1aXJlKFwiLi9JVHJhbnNwb3J0XCIpO1xyXG5leHBvcnRzLkh0dHBUcmFuc3BvcnRUeXBlID0gSVRyYW5zcG9ydF8xLkh0dHBUcmFuc3BvcnRUeXBlO1xyXG5leHBvcnRzLlRyYW5zZmVyRm9ybWF0ID0gSVRyYW5zcG9ydF8xLlRyYW5zZmVyRm9ybWF0O1xyXG52YXIgTG9nZ2Vyc18xID0gcmVxdWlyZShcIi4vTG9nZ2Vyc1wiKTtcclxuZXhwb3J0cy5OdWxsTG9nZ2VyID0gTG9nZ2Vyc18xLk51bGxMb2dnZXI7XHJcbnZhciBKc29uSHViUHJvdG9jb2xfMSA9IHJlcXVpcmUoXCIuL0pzb25IdWJQcm90b2NvbFwiKTtcclxuZXhwb3J0cy5Kc29uSHViUHJvdG9jb2wgPSBKc29uSHViUHJvdG9jb2xfMS5Kc29uSHViUHJvdG9jb2w7XHJcbnZhciBTdWJqZWN0XzEgPSByZXF1aXJlKFwiLi9TdWJqZWN0XCIpO1xyXG5leHBvcnRzLlN1YmplY3QgPSBTdWJqZWN0XzEuU3ViamVjdDtcclxudmFyIFV0aWxzXzEgPSByZXF1aXJlKFwiLi9VdGlsc1wiKTtcclxuZXhwb3J0cy5WRVJTSU9OID0gVXRpbHNfMS5WRVJTSU9OO1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICB2YXIgaVxuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsodWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKSkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG52YXIgS19NQVhfTEVOR1RIID0gMHg3ZmZmZmZmZlxuZXhwb3J0cy5rTWF4TGVuZ3RoID0gS19NQVhfTEVOR1RIXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFByaW50IHdhcm5pbmcgYW5kIHJlY29tbWVuZCB1c2luZyBgYnVmZmVyYCB2NC54IHdoaWNoIGhhcyBhbiBPYmplY3RcbiAqICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIFdlIHJlcG9ydCB0aGF0IHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGlmIHRoZSBhcmUgbm90IHN1YmNsYXNzYWJsZVxuICogdXNpbmcgX19wcm90b19fLiBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YFxuICogKFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4KS4gSUUgMTAgbGFja3Mgc3VwcG9ydFxuICogZm9yIF9fcHJvdG9fXyBhbmQgaGFzIGEgYnVnZ3kgdHlwZWQgYXJyYXkgaW1wbGVtZW50YXRpb24uXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gdHlwZWRBcnJheVN1cHBvcnQoKVxuXG5pZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJlxuICAgIHR5cGVvZiBjb25zb2xlLmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gIGNvbnNvbGUuZXJyb3IoXG4gICAgJ1RoaXMgYnJvd3NlciBsYWNrcyB0eXBlZCBhcnJheSAoVWludDhBcnJheSkgc3VwcG9ydCB3aGljaCBpcyByZXF1aXJlZCBieSAnICtcbiAgICAnYGJ1ZmZlcmAgdjUueC4gVXNlIGBidWZmZXJgIHY0LnggaWYgeW91IHJlcXVpcmUgb2xkIGJyb3dzZXIgc3VwcG9ydC4nXG4gIClcbn1cblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICAvLyBDYW4gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWQ/XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHsgX19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9IH1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MlxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlci5wcm90b3R5cGUsICdwYXJlbnQnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHRoaXMpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgcmV0dXJuIHRoaXMuYnVmZmVyXG4gIH1cbn0pXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIucHJvdG90eXBlLCAnb2Zmc2V0Jywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0aGlzKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIHJldHVybiB0aGlzLmJ5dGVPZmZzZXRcbiAgfVxufSlcblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKGxlbmd0aCA+IEtfTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgXCInICsgbGVuZ3RoICsgJ1wiIGlzIGludmFsaWQgZm9yIG9wdGlvbiBcInNpemVcIicpXG4gIH1cbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgYnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGJ1ZlxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICdUaGUgXCJzdHJpbmdcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLiBSZWNlaXZlZCB0eXBlIG51bWJlcidcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGFsbG9jVW5zYWZlKGFyZylcbiAgfVxuICByZXR1cm4gZnJvbShhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbmlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAhPSBudWxsICYmXG4gICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgdmFsdWU6IG51bGwsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuZnVuY3Rpb24gZnJvbSAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh2YWx1ZSlcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksICcgK1xuICAgICAgJ29yIEFycmF5LWxpa2UgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICcgKyAodHlwZW9mIHZhbHVlKVxuICAgIClcbiAgfVxuXG4gIGlmIChpc0luc3RhbmNlKHZhbHVlLCBBcnJheUJ1ZmZlcikgfHxcbiAgICAgICh2YWx1ZSAmJiBpc0luc3RhbmNlKHZhbHVlLmJ1ZmZlciwgQXJyYXlCdWZmZXIpKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG9mIHR5cGUgbnVtYmVyLiBSZWNlaXZlZCB0eXBlIG51bWJlcidcbiAgICApXG4gIH1cblxuICB2YXIgdmFsdWVPZiA9IHZhbHVlLnZhbHVlT2YgJiYgdmFsdWUudmFsdWVPZigpXG4gIGlmICh2YWx1ZU9mICE9IG51bGwgJiYgdmFsdWVPZiAhPT0gdmFsdWUpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20odmFsdWVPZiwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgdmFyIGIgPSBmcm9tT2JqZWN0KHZhbHVlKVxuICBpZiAoYikgcmV0dXJuIGJcblxuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvUHJpbWl0aXZlICE9IG51bGwgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZVtTeW1ib2wudG9QcmltaXRpdmVdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKFxuICAgICAgdmFsdWVbU3ltYm9sLnRvUHJpbWl0aXZlXSgnc3RyaW5nJyksIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aFxuICAgIClcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksICcgK1xuICAgICdvciBBcnJheS1saWtlIE9iamVjdC4gUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB2YWx1ZSlcbiAgKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIE5vdGU6IENoYW5nZSBwcm90b3R5cGUgKmFmdGVyKiBCdWZmZXIuZnJvbSBpcyBkZWZpbmVkIHRvIHdvcmthcm91bmQgQ2hyb21lIGJ1Zzpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvMTQ4XG5CdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG5CdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgbnVtYmVyJylcbiAgfSBlbHNlIGlmIChzaXplIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgXCInICsgc2l6ZSArICdcIiBpcyBpbnZhbGlkIGZvciBvcHRpb24gXCJzaXplXCInKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIoc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSBidWYud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIGJ1ZiA9IGJ1Zi5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICBidWZbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyIChhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcIm9mZnNldFwiIGlzIG91dHNpZGUgb2YgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wibGVuZ3RoXCIgaXMgb3V0c2lkZSBvZiBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIHZhciBidWZcbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIGJ1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAob2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuKVxuXG4gICAgaWYgKGJ1Zi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBidWZcbiAgICB9XG5cbiAgICBvYmouY29weShidWYsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gYnVmXG4gIH1cblxuICBpZiAob2JqLmxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBudW1iZXJJc05hTihvYmoubGVuZ3RoKSkge1xuICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcigwKVxuICAgIH1cbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZShvYmopXG4gIH1cblxuICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIEFycmF5LmlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUxpa2Uob2JqLmRhdGEpXG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IEtfTUFYX0xFTkdUSGAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBLX01BWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsgS19NQVhfTEVOR1RILnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyID09PSB0cnVlICYmXG4gICAgYiAhPT0gQnVmZmVyLnByb3RvdHlwZSAvLyBzbyBCdWZmZXIuaXNCdWZmZXIoQnVmZmVyLnByb3RvdHlwZSkgd2lsbCBiZSBmYWxzZVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKGlzSW5zdGFuY2UoYSwgVWludDhBcnJheSkpIGEgPSBCdWZmZXIuZnJvbShhLCBhLm9mZnNldCwgYS5ieXRlTGVuZ3RoKVxuICBpZiAoaXNJbnN0YW5jZShiLCBVaW50OEFycmF5KSkgYiA9IEJ1ZmZlci5mcm9tKGIsIGIub2Zmc2V0LCBiLmJ5dGVMZW5ndGgpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcImJ1ZjFcIiwgXCJidWYyXCIgYXJndW1lbnRzIG11c3QgYmUgb25lIG9mIHR5cGUgQnVmZmVyIG9yIFVpbnQ4QXJyYXknXG4gICAgKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKGlzSW5zdGFuY2UoYnVmLCBVaW50OEFycmF5KSkge1xuICAgICAgYnVmID0gQnVmZmVyLmZyb20oYnVmKVxuICAgIH1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBpc0luc3RhbmNlKHN0cmluZywgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJzdHJpbmdcIiBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBvciBBcnJheUJ1ZmZlci4gJyArXG4gICAgICAnUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIHN0cmluZ1xuICAgIClcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBtdXN0TWF0Y2ggPSAoYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdID09PSB0cnVlKVxuICBpZiAoIW11c3RNYXRjaCAmJiBsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHtcbiAgICAgICAgICByZXR1cm4gbXVzdE1hdGNoID8gLTEgOiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICB9XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhpcyBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIChhbmQgdGhlIGBpcy1idWZmZXJgIG5wbSBwYWNrYWdlKVxuLy8gdG8gZGV0ZWN0IGEgQnVmZmVyIGluc3RhbmNlLiBJdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgYGluc3RhbmNlb2YgQnVmZmVyYFxuLy8gcmVsaWFibHkgaW4gYSBicm93c2VyaWZ5IGNvbnRleHQgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBtdWx0aXBsZSBkaWZmZXJlbnRcbi8vIGNvcGllcyBvZiB0aGUgJ2J1ZmZlcicgcGFja2FnZSBpbiB1c2UuIFRoaXMgbWV0aG9kIHdvcmtzIGV2ZW4gZm9yIEJ1ZmZlclxuLy8gaW5zdGFuY2VzIHRoYXQgd2VyZSBjcmVhdGVkIGZyb20gYW5vdGhlciBjb3B5IG9mIHRoZSBgYnVmZmVyYCBwYWNrYWdlLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9pc3N1ZXMvMTU0XG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvTG9jYWxlU3RyaW5nID0gQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZ1xuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLnJlcGxhY2UoLyguezJ9KS9nLCAnJDEgJykudHJpbSgpXG4gIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKGlzSW5zdGFuY2UodGFyZ2V0LCBVaW50OEFycmF5KSkge1xuICAgIHRhcmdldCA9IEJ1ZmZlci5mcm9tKHRhcmdldCwgdGFyZ2V0Lm9mZnNldCwgdGFyZ2V0LmJ5dGVMZW5ndGgpXG4gIH1cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwidGFyZ2V0XCIgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBCdWZmZXIgb3IgVWludDhBcnJheS4gJyArXG4gICAgICAnUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB0YXJnZXQpXG4gICAgKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAobnVtYmVySXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmICh0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAobnVtYmVySXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggPj4+IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCdcbiAgICApXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGxhdGluMVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyAoYnl0ZXNbaSArIDFdICogMjU2KSlcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsICg4ICogYnl0ZUxlbmd0aCkgLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCAoOCAqIGJ5dGVMZW5ndGgpIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignYXJndW1lbnQgc2hvdWxkIGJlIGEgQnVmZmVyJylcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBVc2UgYnVpbHQtaW4gd2hlbiBhdmFpbGFibGUsIG1pc3NpbmcgZnJvbSBJRTExXG4gICAgdGhpcy5jb3B5V2l0aGluKHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKVxuICB9IGVsc2UgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yICh2YXIgaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoKGVuY29kaW5nID09PSAndXRmOCcgJiYgY29kZSA8IDEyOCkgfHxcbiAgICAgICAgICBlbmNvZGluZyA9PT0gJ2xhdGluMScpIHtcbiAgICAgICAgLy8gRmFzdCBwYXRoOiBJZiBgdmFsYCBmaXRzIGludG8gYSBzaW5nbGUgYnl0ZSwgdXNlIHRoYXQgbnVtZXJpYyB2YWx1ZS5cbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGlmIChsZW4gPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyB2YWwgK1xuICAgICAgICAnXCIgaXMgaW52YWxpZCBmb3IgYXJndW1lbnQgXCJ2YWx1ZVwiJylcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSB0YWtlcyBlcXVhbCBzaWducyBhcyBlbmQgb2YgdGhlIEJhc2U2NCBlbmNvZGluZ1xuICBzdHIgPSBzdHIuc3BsaXQoJz0nKVswXVxuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyLnRyaW0oKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbi8vIEFycmF5QnVmZmVyIG9yIFVpbnQ4QXJyYXkgb2JqZWN0cyBmcm9tIG90aGVyIGNvbnRleHRzIChpLmUuIGlmcmFtZXMpIGRvIG5vdCBwYXNzXG4vLyB0aGUgYGluc3RhbmNlb2ZgIGNoZWNrIGJ1dCB0aGV5IHNob3VsZCBiZSB0cmVhdGVkIGFzIG9mIHRoYXQgdHlwZS5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvaXNzdWVzLzE2NlxuZnVuY3Rpb24gaXNJbnN0YW5jZSAob2JqLCB0eXBlKSB7XG4gIHJldHVybiBvYmogaW5zdGFuY2VvZiB0eXBlIHx8XG4gICAgKG9iaiAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3RvciAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3Rvci5uYW1lICE9IG51bGwgJiZcbiAgICAgIG9iai5jb25zdHJ1Y3Rvci5uYW1lID09PSB0eXBlLm5hbWUpXG59XG5mdW5jdGlvbiBudW1iZXJJc05hTiAob2JqKSB7XG4gIC8vIEZvciBJRTExIHN1cHBvcnRcbiAgcmV0dXJuIG9iaiAhPT0gb2JqIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG4iLCIvKiEgaWVlZTc1NC4gQlNELTMtQ2xhdXNlIExpY2Vuc2UuIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZy9vcGVuc291cmNlPiAqL1xuZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgZ2xvYmFsLCBkZWZpbmUsIFN5bWJvbCwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yICovXHJcbnZhciBfX2V4dGVuZHM7XHJcbnZhciBfX2Fzc2lnbjtcclxudmFyIF9fcmVzdDtcclxudmFyIF9fZGVjb3JhdGU7XHJcbnZhciBfX3BhcmFtO1xyXG52YXIgX19lc0RlY29yYXRlO1xyXG52YXIgX19ydW5Jbml0aWFsaXplcnM7XHJcbnZhciBfX3Byb3BLZXk7XHJcbnZhciBfX3NldEZ1bmN0aW9uTmFtZTtcclxudmFyIF9fbWV0YWRhdGE7XHJcbnZhciBfX2F3YWl0ZXI7XHJcbnZhciBfX2dlbmVyYXRvcjtcclxudmFyIF9fZXhwb3J0U3RhcjtcclxudmFyIF9fdmFsdWVzO1xyXG52YXIgX19yZWFkO1xyXG52YXIgX19zcHJlYWQ7XHJcbnZhciBfX3NwcmVhZEFycmF5cztcclxudmFyIF9fc3ByZWFkQXJyYXk7XHJcbnZhciBfX2F3YWl0O1xyXG52YXIgX19hc3luY0dlbmVyYXRvcjtcclxudmFyIF9fYXN5bmNEZWxlZ2F0b3I7XHJcbnZhciBfX2FzeW5jVmFsdWVzO1xyXG52YXIgX19tYWtlVGVtcGxhdGVPYmplY3Q7XHJcbnZhciBfX2ltcG9ydFN0YXI7XHJcbnZhciBfX2ltcG9ydERlZmF1bHQ7XHJcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0O1xyXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldDtcclxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRJbjtcclxudmFyIF9fY3JlYXRlQmluZGluZztcclxudmFyIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlO1xyXG52YXIgX19kaXNwb3NlUmVzb3VyY2VzO1xyXG4oZnVuY3Rpb24gKGZhY3RvcnkpIHtcclxuICAgIHZhciByb290ID0gdHlwZW9mIGdsb2JhbCA9PT0gXCJvYmplY3RcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IHR5cGVvZiB0aGlzID09PSBcIm9iamVjdFwiID8gdGhpcyA6IHt9O1xyXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XHJcbiAgICAgICAgZGVmaW5lKFwidHNsaWJcIiwgW1wiZXhwb3J0c1wiXSwgZnVuY3Rpb24gKGV4cG9ydHMpIHsgZmFjdG9yeShjcmVhdGVFeHBvcnRlcihyb290LCBjcmVhdGVFeHBvcnRlcihleHBvcnRzKSkpOyB9KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgICAgZmFjdG9yeShjcmVhdGVFeHBvcnRlcihyb290LCBjcmVhdGVFeHBvcnRlcihtb2R1bGUuZXhwb3J0cykpKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGZhY3RvcnkoY3JlYXRlRXhwb3J0ZXIocm9vdCkpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gY3JlYXRlRXhwb3J0ZXIoZXhwb3J0cywgcHJldmlvdXMpIHtcclxuICAgICAgICBpZiAoZXhwb3J0cyAhPT0gcm9vdCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGlkLCB2KSB7IHJldHVybiBleHBvcnRzW2lkXSA9IHByZXZpb3VzID8gcHJldmlvdXMoaWQsIHYpIDogdjsgfTtcclxuICAgIH1cclxufSlcclxuKGZ1bmN0aW9uIChleHBvcnRlcikge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuXHJcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcblxyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3Jlc3QgPSBmdW5jdGlvbiAocywgZSkge1xyXG4gICAgICAgIHZhciB0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fZGVjb3JhdGUgPSBmdW5jdGlvbiAoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgICAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICAgICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgICAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3BhcmFtID0gZnVuY3Rpb24gKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG4gICAgfTtcclxuXHJcbiAgICBfX2VzRGVjb3JhdGUgPSBmdW5jdGlvbiAoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgICAgICBmdW5jdGlvbiBhY2NlcHQoZikgeyBpZiAoZiAhPT0gdm9pZCAwICYmIHR5cGVvZiBmICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGdW5jdGlvbiBleHBlY3RlZFwiKTsgcmV0dXJuIGY7IH1cclxuICAgICAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgICAgIHZhciBkZXNjcmlwdG9yID0gZGVzY3JpcHRvckluIHx8ICh0YXJnZXQgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgY29udGV4dEluLm5hbWUpIDoge30pO1xyXG4gICAgICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSB7fTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgICAgICBjb250ZXh0LmFkZEluaXRpYWxpemVyID0gZnVuY3Rpb24gKGYpIHsgaWYgKGRvbmUpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgYWRkIGluaXRpYWxpemVycyBhZnRlciBkZWNvcmF0aW9uIGhhcyBjb21wbGV0ZWRcIik7IGV4dHJhSW5pdGlhbGl6ZXJzLnB1c2goYWNjZXB0KGYgfHwgbnVsbCkpOyB9O1xyXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuc2V0KSkgZGVzY3JpcHRvci5zZXQgPSBfO1xyXG4gICAgICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChfID0gYWNjZXB0KHJlc3VsdCkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgICAgICBkb25lID0gdHJ1ZTtcclxuICAgIH07XHJcblxyXG4gICAgX19ydW5Jbml0aWFsaXplcnMgPSBmdW5jdGlvbiAodGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5pdGlhbGl6ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVzZVZhbHVlID8gdmFsdWUgOiB2b2lkIDA7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fcHJvcEtleSA9IGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3NldEZ1bmN0aW9uTmFtZSA9IGZ1bmN0aW9uIChmLCBuYW1lLCBwcmVmaXgpIHtcclxuICAgICAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fbWV0YWRhdGEgPSBmdW5jdGlvbiAobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgICAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2F3YWl0ZXIgPSBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICAgICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICAgICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgX19nZW5lcmF0b3IgPSBmdW5jdGlvbiAodGhpc0FyZywgYm9keSkge1xyXG4gICAgICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICAgICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICAgICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fZXhwb3J0U3RhciA9IGZ1bmN0aW9uKG0sIG8pIHtcclxuICAgICAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgICAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcclxuICAgICAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG4gICAgfSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgICAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgICAgIG9bazJdID0gbVtrXTtcclxuICAgIH0pO1xyXG5cclxuICAgIF9fdmFsdWVzID0gZnVuY3Rpb24gKG8pIHtcclxuICAgICAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3JlYWQgPSBmdW5jdGlvbiAobywgbikge1xyXG4gICAgICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgICAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgICAgICBmaW5hbGx5IHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKiBAZGVwcmVjYXRlZCAqL1xyXG4gICAgX19zcHJlYWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKiBAZGVwcmVjYXRlZCAqL1xyXG4gICAgX19zcHJlYWRBcnJheXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICAgICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgICAgIHJldHVybiByO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3NwcmVhZEFycmF5ID0gZnVuY3Rpb24gKHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICAgICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxuICAgIH07XHJcblxyXG4gICAgX19hd2FpdCA9IGZ1bmN0aW9uICh2KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXN5bmNHZW5lcmF0b3IgPSBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICAgICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgICAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgICAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICAgICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG4gICAgfTtcclxuXHJcbiAgICBfX2FzeW5jRGVsZWdhdG9yID0gZnVuY3Rpb24gKG8pIHtcclxuICAgICAgICB2YXIgaSwgcDtcclxuICAgICAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXN5bmNWYWx1ZXMgPSBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICAgICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgICAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICAgICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxuICAgIH07XHJcblxyXG4gICAgX19tYWtlVGVtcGxhdGVPYmplY3QgPSBmdW5jdGlvbiAoY29va2VkLCByYXcpIHtcclxuICAgICAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgICAgIHJldHVybiBjb29rZWQ7XHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbiAgICB9KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgICAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbiAgICB9O1xyXG5cclxuICAgIF9faW1wb3J0U3RhciA9IGZ1bmN0aW9uIChtb2QpIHtcclxuICAgICAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgICAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICAgICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2ltcG9ydERlZmF1bHQgPSBmdW5jdGlvbiAobW9kKSB7XHJcbiAgICAgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XHJcbiAgICB9O1xyXG5cclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQgPSBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQgPSBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgICAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEluID0gZnVuY3Rpb24gKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgICAgIGlmIChyZWNlaXZlciA9PT0gbnVsbCB8fCAodHlwZW9mIHJlY2VpdmVyICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZWNlaXZlciAhPT0gXCJmdW5jdGlvblwiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB1c2UgJ2luJyBvcGVyYXRvciBvbiBub24tb2JqZWN0XCIpO1xyXG4gICAgICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlID0gZnVuY3Rpb24gKGVudiwgdmFsdWUsIGFzeW5jKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZC5cIik7XHJcbiAgICAgICAgICAgIHZhciBkaXNwb3NlO1xyXG4gICAgICAgICAgICBpZiAoYXN5bmMpIHtcclxuICAgICAgICAgICAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5hc3luY0Rpc3Bvc2VdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgICAgIGlmICghU3ltYm9sLmRpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuZGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICAgICAgICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmRpc3Bvc2VdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG5vdCBkaXNwb3NhYmxlLlwiKTtcclxuICAgICAgICAgICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYXN5bmMpIHtcclxuICAgICAgICAgICAgZW52LnN0YWNrLnB1c2goeyBhc3luYzogdHJ1ZSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgX1N1cHByZXNzZWRFcnJvciA9IHR5cGVvZiBTdXBwcmVzc2VkRXJyb3IgPT09IFwiZnVuY3Rpb25cIiA/IFN1cHByZXNzZWRFcnJvciA6IGZ1bmN0aW9uIChlcnJvciwgc3VwcHJlc3NlZCwgbWVzc2FnZSkge1xyXG4gICAgICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHJldHVybiBlLm5hbWUgPSBcIlN1cHByZXNzZWRFcnJvclwiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fZGlzcG9zZVJlc291cmNlcyA9IGZ1bmN0aW9uIChlbnYpIHtcclxuICAgICAgICBmdW5jdGlvbiBmYWlsKGUpIHtcclxuICAgICAgICAgICAgZW52LmVycm9yID0gZW52Lmhhc0Vycm9yID8gbmV3IF9TdXBwcmVzc2VkRXJyb3IoZSwgZW52LmVycm9yLCBcIkFuIGVycm9yIHdhcyBzdXBwcmVzc2VkIGR1cmluZyBkaXNwb3NhbC5cIikgOiBlO1xyXG4gICAgICAgICAgICBlbnYuaGFzRXJyb3IgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBuZXh0KCkge1xyXG4gICAgICAgICAgICB3aGlsZSAoZW52LnN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlYyA9IGVudi5zdGFjay5wb3AoKTtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHJlYy5kaXNwb3NlICYmIHJlYy5kaXNwb3NlLmNhbGwocmVjLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVjLmFzeW5jKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBmYWlsKGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG5leHQoKTtcclxuICAgIH07XHJcblxyXG4gICAgZXhwb3J0ZXIoXCJfX2V4dGVuZHNcIiwgX19leHRlbmRzKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3NpZ25cIiwgX19hc3NpZ24pO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3Jlc3RcIiwgX19yZXN0KTtcclxuICAgIGV4cG9ydGVyKFwiX19kZWNvcmF0ZVwiLCBfX2RlY29yYXRlKTtcclxuICAgIGV4cG9ydGVyKFwiX19wYXJhbVwiLCBfX3BhcmFtKTtcclxuICAgIGV4cG9ydGVyKFwiX19lc0RlY29yYXRlXCIsIF9fZXNEZWNvcmF0ZSk7XHJcbiAgICBleHBvcnRlcihcIl9fcnVuSW5pdGlhbGl6ZXJzXCIsIF9fcnVuSW5pdGlhbGl6ZXJzKTtcclxuICAgIGV4cG9ydGVyKFwiX19wcm9wS2V5XCIsIF9fcHJvcEtleSk7XHJcbiAgICBleHBvcnRlcihcIl9fc2V0RnVuY3Rpb25OYW1lXCIsIF9fc2V0RnVuY3Rpb25OYW1lKTtcclxuICAgIGV4cG9ydGVyKFwiX19tZXRhZGF0YVwiLCBfX21ldGFkYXRhKTtcclxuICAgIGV4cG9ydGVyKFwiX19hd2FpdGVyXCIsIF9fYXdhaXRlcik7XHJcbiAgICBleHBvcnRlcihcIl9fZ2VuZXJhdG9yXCIsIF9fZ2VuZXJhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19leHBvcnRTdGFyXCIsIF9fZXhwb3J0U3Rhcik7XHJcbiAgICBleHBvcnRlcihcIl9fY3JlYXRlQmluZGluZ1wiLCBfX2NyZWF0ZUJpbmRpbmcpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3ZhbHVlc1wiLCBfX3ZhbHVlcyk7XHJcbiAgICBleHBvcnRlcihcIl9fcmVhZFwiLCBfX3JlYWQpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3NwcmVhZFwiLCBfX3NwcmVhZCk7XHJcbiAgICBleHBvcnRlcihcIl9fc3ByZWFkQXJyYXlzXCIsIF9fc3ByZWFkQXJyYXlzKTtcclxuICAgIGV4cG9ydGVyKFwiX19zcHJlYWRBcnJheVwiLCBfX3NwcmVhZEFycmF5KTtcclxuICAgIGV4cG9ydGVyKFwiX19hd2FpdFwiLCBfX2F3YWl0KTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY0dlbmVyYXRvclwiLCBfX2FzeW5jR2VuZXJhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY0RlbGVnYXRvclwiLCBfX2FzeW5jRGVsZWdhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY1ZhbHVlc1wiLCBfX2FzeW5jVmFsdWVzKTtcclxuICAgIGV4cG9ydGVyKFwiX19tYWtlVGVtcGxhdGVPYmplY3RcIiwgX19tYWtlVGVtcGxhdGVPYmplY3QpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2ltcG9ydFN0YXJcIiwgX19pbXBvcnRTdGFyKTtcclxuICAgIGV4cG9ydGVyKFwiX19pbXBvcnREZWZhdWx0XCIsIF9faW1wb3J0RGVmYXVsdCk7XHJcbiAgICBleHBvcnRlcihcIl9fY2xhc3NQcml2YXRlRmllbGRHZXRcIiwgX19jbGFzc1ByaXZhdGVGaWVsZEdldCk7XHJcbiAgICBleHBvcnRlcihcIl9fY2xhc3NQcml2YXRlRmllbGRTZXRcIiwgX19jbGFzc1ByaXZhdGVGaWVsZFNldCk7XHJcbiAgICBleHBvcnRlcihcIl9fY2xhc3NQcml2YXRlRmllbGRJblwiLCBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4pO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2FkZERpc3Bvc2FibGVSZXNvdXJjZVwiLCBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZSk7XHJcbiAgICBleHBvcnRlcihcIl9fZGlzcG9zZVJlc291cmNlc1wiLCBfX2Rpc3Bvc2VSZXNvdXJjZXMpO1xyXG59KTtcclxuIiwiaW1wb3J0IHsgQWN0aW9uVHlwZXMgfSBmcm9tICcuL2FjdGlvbnMnO1xyXG5pbXBvcnQgKiBhcyBzaWduYWxSIGZyb20gXCJAbWljcm9zb2Z0L3NpZ25hbHJcIjtcclxuaW1wb3J0ICogYXMgRmluZ2VycHJpbnRKUyBmcm9tIFwiQGZpbmdlcnByaW50anMvZmluZ2VycHJpbnRqc1wiXHJcbi8vIHNpbmdsZSBzaWduYWxSIGNvbm5lY3Rpb24tcGVyLXBhZ2VcclxuZXhwb3J0IGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgc2lnbmFsUi5IdWJDb25uZWN0aW9uQnVpbGRlcigpXHJcbiAgLndpdGhVcmwoXCIvZGVmYXVsdEh1YlwiKVxyXG4gIC53aXRoQXV0b21hdGljUmVjb25uZWN0KClcclxuICAvLyAuY29uZmlndXJlTG9nZ2luZyhzaWduYWxSLkxvZ0xldmVsLkRlYnVnKVxyXG4gIC5idWlsZCgpO1xyXG5pbXBvcnQgeyBUb2FzdGVyIH0gZnJvbSBcIi4vdG9hc3RlclwiO1xyXG5kZWNsYXJlIHZhciBPbmVTaWduYWw6IGFueTtcclxuZGVjbGFyZSB2YXIgZ29uYXRpdmU6IGFueTtcclxuaW1wb3J0IHsgSHViQ29ubmVjdGlvbiwgSHViQ29ubmVjdGlvblN0YXRlIH0gZnJvbSAnQG1pY3Jvc29mdC9zaWduYWxyJztcclxuXHJcbiQoKCkgPT4ge1xyXG4gIGNvbm5lY3Rpb24ub24oXCJFcnJvclwiLFxyXG4gICAgKGNvZGU6IG51bWJlciwgbWVzc2FnZTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIFRvYXN0ZXIuZXJyb3IobWVzc2FnZSk7XHJcbiAgICB9KTtcclxuXHJcbiAgY29ubmVjdGlvbi5vbihcIkNvbm5lY3Rpb25Ob3RBbGxvd2VkXCIsXHJcbiAgICAoKSA9PiB7XHJcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gJy9jb25uZWN0aW9uLW5vdC1hbGxvd2VkJztcclxuICAgIH0pO1xyXG5cclxuICBjb25uZWN0aW9uLm9uKFwiSW5mb1wiLFxyXG4gICAgKG1lc3NhZ2U6IHN0cmluZykgPT4ge1xyXG4gICAgICBUb2FzdGVyLmluZm8obWVzc2FnZSk7XHJcbiAgICB9KTtcclxuXHJcbiAgY29ubmVjdGlvbi5vbihcIk9uQWN0aW9uQ29tcGxldGVkXCIsXHJcbiAgICAoYWN0aW9uVHlwZTogQWN0aW9uVHlwZXMsIGFjdGlvbklkOiBzdHJpbmcsIHRleHQ6IHN0cmluZykgPT4ge1xyXG4gICAgICAvLyBoYW5kbGUgQWN0aW9uIENvbXBsZXRlZFxyXG4gICAgfSk7XHJcblxyXG4gIGlmIChjb25uZWN0aW9uLnN0YXRlID09PSAnRGlzY29ubmVjdGVkJykgeyAvLyBjb25uZWN0aW9uIGNhbiBiZSBvcGVuZWQgYnkgY29tcG9uZW50XHJcbiAgICBjb25uZWN0aW9uLnN0YXJ0KClcclxuICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKFwiY29ubmVjdGlvbiBzdGFydGVkXCIpO1xyXG4gICAgICAgIHNldFZpc2l0b3JJZCgpO1xyXG4gICAgICAgIHNldE9uZVNpZ25hbFBsYXllcklkcygpO1xyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci50b1N0cmluZygpKTtcclxuICAgICAgICBUb2FzdGVyLmVycm9yKFwiRmFpbGVkIHRvIGNvbm5lY3QgdG8gc2VydmVyXCIpO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIGNvbm5lY3Rpb24ub25jbG9zZSgoZXJyb3I/OiBFcnJvcikgPT4ge1xyXG4gICAgaWYgKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ2Nvbm5lY3Rpb24gd2FzIGNsb3NlZDogJywgZXJyb3IpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc29sZS5lcnJvcignY29ubmVjdGlvbiB3YXMgY2xvc2VkJyk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNldFZpc2l0b3JJZCgpIHtcclxuICBjb25zdCBmcFByb21pc2UgPSBGaW5nZXJwcmludEpTLmxvYWQoeyAvKiBvcHRpb25zICovIH0pIC8vIGh0dHBzOi8vZGV2LmZpbmdlcnByaW50anMuY29tL2RvY3MvanMtYWdlbnQjYWdlbnQtaW5pdGlhbGl6YXRpb25cclxuICBmcFByb21pc2VcclxuICAgIC50aGVuKGZwID0+IGZwLmdldCgpKVxyXG4gICAgLnRoZW4ocmVzdWx0ID0+XHJcbiAgICAgIGNvbm5lY3Rpb25cclxuICAgICAgICAuaW52b2tlKFwiU2V0VmlzaXRvcklkXCIsIHJlc3VsdC52aXNpdG9ySWQpXHJcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gY29uc29sZS5lcnJvcihlcnJvci50b1N0cmluZygpKSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0T25lU2lnbmFsUGxheWVySWRzKCkge1xyXG4gIGlmICh0eXBlb2YgT25lU2lnbmFsICE9PSBcInVuZGVmaW5lZFwiKSB7XHJcbiAgICBjb25zb2xlLmxvZygndXBkYXRpbmcgT25lU2lnbmFsIElEcycpO1xyXG5cclxuICAgIE9uZVNpZ25hbC5wdXNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgT25lU2lnbmFsLmdldFVzZXJJZChmdW5jdGlvbiAocGxheWVySWQ6IHN0cmluZykge1xyXG4gICAgICAgIGNvbm5lY3Rpb24uaW52b2tlKFwiU2V0T25lU2lnbmFsV2ViUHVzaFBsYXllcklkXCIsIHBsYXllcklkKVxyXG4gICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gY29uc29sZS5lcnJvcihlcnJvci50b1N0cmluZygpKSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgT25lU2lnbmFsLnB1c2goZnVuY3Rpb24gKCkge1xyXG4gICAgICBPbmVTaWduYWwuZ2V0RW1haWxJZChmdW5jdGlvbiAocGxheWVySWQ6IHN0cmluZykge1xyXG4gICAgICAgIGNvbm5lY3Rpb24uaW52b2tlKFwiU2V0T25lU2lnbmFsRW1haWxQbGF5ZXJJZFwiLCBwbGF5ZXJJZClcclxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoZXJyb3IudG9TdHJpbmcoKSkpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIE9uZVNpZ25hbC5wdXNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgT25lU2lnbmFsLmdldFNNU0lkKGZ1bmN0aW9uIChwbGF5ZXJJZDogc3RyaW5nKSB7XHJcbiAgICAgICAgY29ubmVjdGlvbi5pbnZva2UoXCJTZXRPbmVTaWduYWxTTVNQbGF5ZXJJZFwiLCBwbGF5ZXJJZClcclxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoZXJyb3IudG9TdHJpbmcoKSkpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICh0eXBlb2YgZ29uYXRpdmUgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgZ29uYXRpdmUub25lc2lnbmFsLm9uZXNpZ25hbEluZm8oKS50aGVuKGZ1bmN0aW9uIChvbmVTaWduYWxJbmZvKSB7XHJcbiAgICAgICAgY29ubmVjdGlvbi5pbnZva2UoXCJTZXRPbmVTaWduYWxNb2JpbGVQbGF5ZXJJZFwiLCBKU09OLnN0cmluZ2lmeShvbmVTaWduYWxJbmZvKSlcclxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoZXJyb3IudG9TdHJpbmcoKSkpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBkZWJvdW5jZSA9IChmbiwgZGVsYXkgPSA1MDApID0+IHtcclxuICBsZXQgdGltZW91dDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XHJcbiAgY29uc3QgY3VycmVudFNjb3BlID0gdGhpcztcclxuICByZXR1cm4gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcclxuICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZuLmJpbmQoY3VycmVudFNjb3BlLCAuLi5hcmdzKSwgZGVsYXkpO1xyXG4gIH1cclxufSIsImV4cG9ydCB7IH07XHJcblxyXG5leHBvcnQgY2xhc3MgVG9hc3RlciB7XHJcbiAgICBwdWJsaWMgc3RhdGljIGluZm8odGV4dDogc3RyaW5nLCBoZWFkaW5nPzogc3RyaW5nKSB7XHJcbiAgICAgICAgJC50b2FzdCh7XHJcbiAgICAgICAgICAgIGhlYWRpbmc6IGhlYWRpbmcsXHJcbiAgICAgICAgICAgIHRleHQ6IHRleHQsXHJcbiAgICAgICAgICAgIHBvc2l0aW9uOiBcImJvdHRvbS1sZWZ0XCIsXHJcbiAgICAgICAgICAgIGxvYWRlcjogZmFsc2UsXHJcbiAgICAgICAgICAgIGhpZGVBZnRlcjogMjAwMCxcclxuICAgICAgICAgICAgYWxsb3dUb2FzdENsb3NlOiBmYWxzZSxcclxuICAgICAgICAgICAgc2hvd0hpZGVUcmFuc2l0aW9uOiBcInNsaWRlXCJcclxuICAgICAgICAgICAgLy8gaWNvbjogXCJzdWNjZXNzXCJcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIGVycm9yKHRleHQ6IHN0cmluZykge1xyXG4gICAgICAgICQudG9hc3Qoe1xyXG4gICAgICAgICAgICBoZWFkaW5nOiBcIkVycm9yXCIsXHJcbiAgICAgICAgICAgIHRleHQ6IHRleHQsXHJcbiAgICAgICAgICAgIHBvc2l0aW9uOiBcImJvdHRvbS1sZWZ0XCIsXHJcbiAgICAgICAgICAgIGxvYWRlcjogZmFsc2UsXHJcbiAgICAgICAgICAgIGhpZGVBZnRlcjogMjAwMCxcclxuICAgICAgICAgICAgYWxsb3dUb2FzdENsb3NlOiBmYWxzZSxcclxuICAgICAgICAgICAgc2hvd0hpZGVUcmFuc2l0aW9uOiBcInNsaWRlXCJcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIHRyYWRlU3VjY2VzcyhoZWFkaW5nOiBzdHJpbmcsIHRleHQ6IHN0cmluZykge1xyXG4gICAgICAgICQudG9hc3Qoe1xyXG4gICAgICAgICAgICBoZWFkaW5nOiBoZWFkaW5nLFxyXG4gICAgICAgICAgICB0ZXh0OiB0ZXh0LFxyXG4gICAgICAgICAgICBwb3NpdGlvbjogXCJib3R0b20tbGVmdFwiLFxyXG4gICAgICAgICAgICBsb2FkZXJCZzogXCIjNWJhMDM1XCIsXHJcbiAgICAgICAgICAgIGhpZGVBZnRlcjogMjAwMCxcclxuICAgICAgICAgICAgYWxsb3dUb2FzdENsb3NlOiBmYWxzZSxcclxuICAgICAgICAgICAgc2hvd0hpZGVUcmFuc2l0aW9uOiBcInNsaWRlXCJcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIHRyYWRlSW5mbyhoZWFkaW5nOiBzdHJpbmcsIHRleHQ6IHN0cmluZykge1xyXG4gICAgICAgICQudG9hc3Qoe1xyXG4gICAgICAgICAgICBoZWFkaW5nOiBoZWFkaW5nLFxyXG4gICAgICAgICAgICB0ZXh0OiB0ZXh0LFxyXG4gICAgICAgICAgICBwb3NpdGlvbjogXCJib3R0b20tbGVmdFwiLFxyXG4gICAgICAgICAgICBsb2FkZXJCZzogXCIjNWJhMDM1XCIsXHJcbiAgICAgICAgICAgIGhpZGVBZnRlcjogMjAwMCxcclxuICAgICAgICAgICAgYWxsb3dUb2FzdENsb3NlOiBmYWxzZSxcclxuICAgICAgICAgICAgc2hvd0hpZGVUcmFuc2l0aW9uOiBcInNsaWRlXCJcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIHRyYWRlRXJyb3IodGV4dDogc3RyaW5nKSB7XHJcbiAgICAgICAgJC50b2FzdCh7XHJcbiAgICAgICAgICAgIGhlYWRpbmc6IFwiRXJyb3JcIixcclxuICAgICAgICAgICAgdGV4dDogdGV4dCxcclxuICAgICAgICAgICAgcG9zaXRpb246IFwiYm90dG9tLWxlZnRcIixcclxuICAgICAgICAgICAgbG9hZGVyQmc6IFwiI2JmNDQxZFwiLFxyXG4gICAgICAgICAgICBoaWRlQWZ0ZXI6IDIwMDAsXHJcbiAgICAgICAgICAgIGFsbG93VG9hc3RDbG9zZTogZmFsc2UsXHJcbiAgICAgICAgICAgIHNob3dIaWRlVHJhbnNpdGlvbjogXCJzbGlkZVwiXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIl19"}