diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7f5a2bc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto +/tests/__snapshots__/** text eol=lf +/testdata/** text eol=lf diff --git a/deno.jsonc b/deno.jsonc index 8070966..a594570 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -4,7 +4,8 @@ "exclude": [ "lib", "static", - "target" + "target", + "tests/__snapshots__" ] } }, @@ -13,12 +14,14 @@ "exclude": [ "lib", "static/*.js", - "target" + "target", + "tests/__snapshots__" ] } }, "tasks": { "test": "deno test --allow-read --allow-net --allow-env --allow-write", + "update-snapshots": "deno test --allow-read --allow-net --allow-env --allow-write -- --update", "build": "deno run -A --unstable https://deno.land/x/wasmbuild@0.8.3/main.ts" } } diff --git a/test.ts b/test.ts deleted file mode 100644 index d089ef5..0000000 --- a/test.ts +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -import { - assert, - assertEquals, - assertStringIncludes, -} from "https://deno.land/std@0.140.0/testing/asserts.ts"; -import { join } from "https://deno.land/std@0.140.0/path/mod.ts"; -import { bundle, emit } from "./mod.ts"; - -Deno.test({ - name: "bundle - remote", - async fn() { - const result = await bundle( - new URL("https://deno.land/std@0.140.0/examples/chat/server.ts"), - ); - console.log(result); - assert(result.code); - }, -}); - -Deno.test({ - name: "bundle - url", - async fn() { - const result = await bundle( - new URL( - "https://deno.land/std@0.140.0/examples/chat/server.ts", - ), - ); - console.log(result); - assert(result.code); - }, -}); - -Deno.test({ - name: "bundle - relative", - async fn() { - const result = await bundle( - "./testdata/mod.ts", - ); - console.log(result); - assert(result.code); - }, -}); - -Deno.test({ - name: "bundle - absolute", - async fn() { - const result = await bundle( - join(Deno.cwd(), "testdata", "mod.ts"), - ); - console.log(result); - assert(result.code); - }, -}); - -Deno.test({ - name: "bundle - source", - async fn() { - const result = await bundle(new URL("file:///src.ts"), { - async load(specifier) { - if (specifier !== "file:///src.ts") return undefined; - const content = await Deno.readTextFile( - join(Deno.cwd(), "testdata", "mod.ts"), - ); - return { kind: "module", specifier, content }; - }, - }); - console.log(result); - assert(result.code); - }, -}); - -Deno.test({ - name: "bundle - json escapes", - async fn() { - const result = await bundle("./testdata/escape.ts"); - const { code } = result; - assert(code); - const EOL = Deno?.build?.os === "windows" - ? String.raw`\r\n` - : String.raw`\n`; - // This is done on purpose, as `String.raw` still performs a string interpolation, - // and we want a literal value ${jsInterpolation" as is, without any modifications. - // We should not need to escape `$` nor `{` as they are both JSON-safe characters. - const jsInterpolation = "${jsInterpolation}"; - assertStringIncludes( - code, - String - .raw`const __default = JSON.parse("{${EOL} \"key\": \"a value with newline\\n, \\\"double quotes\\\", 'single quotes', and ${jsInterpolation}\"${EOL}}");`, - ); - }, -}); - -Deno.test({ - name: "transpile - remote", - async fn() { - const result = await emit( - new URL( - "https://deno.land/std@0.140.0/examples/chat/server.ts", - ), - ); - - console.log(result); - assertEquals(Object.keys(result).length, 18); - const code = - result["https://deno.land/std@0.140.0/examples/chat/server.ts"]; - assert(code); - }, -}); - -Deno.test({ - name: "transpile - url", - async fn() { - const result = await emit( - new URL( - "https://deno.land/std@0.140.0/examples/chat/server.ts", - ), - ); - - console.log(result); - assertEquals(Object.keys(result).length, 18); - const code = - result["https://deno.land/std@0.140.0/examples/chat/server.ts"]; - assert(code); - }, -}); - -Deno.test({ - name: "transpile - relative", - async fn() { - const result = await emit("./testdata/mod.ts"); - - console.log(result); - assertEquals(Object.keys(result).length, 1); - const code = result[Object.keys(result)[0]]; - assert(code); - assertStringIncludes(code, "export default function hello()"); - }, -}); - -Deno.test({ - name: "transpile - absolute", - async fn() { - const result = await emit(join(Deno.cwd(), "testdata", "mod.ts")); - - console.log(result); - assertEquals(Object.keys(result).length, 1); - const code = result[Object.keys(result)[0]]; - assert(code); - assertStringIncludes(code, "export default function hello()"); - }, -}); - -Deno.test({ - name: "transpile - source", - async fn() { - const result = await emit(new URL("file:///src.ts"), { - async load(specifier) { - if (specifier !== "file:///src.ts") return undefined; - const content = await Deno.readTextFile( - join(Deno.cwd(), "testdata", "mod.ts"), - ); - return { kind: "module", specifier, content }; - }, - }); - - console.log(result); - assertEquals(Object.keys(result).length, 1); - const code = result[Object.keys(result)[0]]; - assert(code); - assertStringIncludes(code, "export default function hello()"); - }, -}); diff --git a/tests/__snapshots__/bundle/absolute.js b/tests/__snapshots__/bundle/absolute.js new file mode 100644 index 0000000..2f81635 --- /dev/null +++ b/tests/__snapshots__/bundle/absolute.js @@ -0,0 +1,5 @@ +function hello() { + return "Hello there!"; +} +export { hello as default }; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vdGVzdGRhdGEvbW9kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGhlbGxvKCk6IHN0cmluZyB7XG4gIHJldHVybiBcIkhlbGxvIHRoZXJlIVwiO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFlLFNBQVMsUUFBZ0I7SUFDdEMsT0FBTztBQUNUO0FBRkEsNEJBRUMifQ== diff --git a/tests/__snapshots__/bundle/json_escapes.js b/tests/__snapshots__/bundle/json_escapes.js new file mode 100644 index 0000000..e53e9f7 --- /dev/null +++ b/tests/__snapshots__/bundle/json_escapes.js @@ -0,0 +1,6 @@ +const __default = JSON.parse("{\n \"key\": \"a value with newline\\n, \\\"double quotes\\\", 'single quotes', and ${jsInterpolation}\"\n}"); +function payload() { + return JSON.stringify(__default); +} +export { payload as default }; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vdGVzdGRhdGEvZXNjYXBlLmpzb24iLCJmaWxlOi8vL3Rlc3RkYXRhL2VzY2FwZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBKU09OLnBhcnNlKFwie1xcbiAgXFxcImtleVxcXCI6IFxcXCJhIHZhbHVlIHdpdGggbmV3bGluZVxcXFxuLCBcXFxcXFxcImRvdWJsZSBxdW90ZXNcXFxcXFxcIiwgJ3NpbmdsZSBxdW90ZXMnLCBhbmQgJHtqc0ludGVycG9sYXRpb259XFxcIlxcbn1cIik7IiwiaW1wb3J0IGogZnJvbSBcIi4vZXNjYXBlLmpzb25cIiBhc3NlcnQgeyB0eXBlOiBcImpzb25cIiB9O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwYXlsb2FkKCk6IHN0cmluZyB7XG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShqKTtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoia0JBQWUsS0FBSyxLQUFLLENBQUM7QUNFWCxTQUFTLFVBQWtCO0lBQ3hDLE9BQU8sS0FBSyxTQUFTO0FBQ3ZCO0FBRkEsOEJBRUMifQ== diff --git a/tests/__snapshots__/bundle/relative.js b/tests/__snapshots__/bundle/relative.js new file mode 100644 index 0000000..2f81635 --- /dev/null +++ b/tests/__snapshots__/bundle/relative.js @@ -0,0 +1,5 @@ +function hello() { + return "Hello there!"; +} +export { hello as default }; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vdGVzdGRhdGEvbW9kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGhlbGxvKCk6IHN0cmluZyB7XG4gIHJldHVybiBcIkhlbGxvIHRoZXJlIVwiO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFlLFNBQVMsUUFBZ0I7SUFDdEMsT0FBTztBQUNUO0FBRkEsNEJBRUMifQ== diff --git a/tests/__snapshots__/bundle/remote.js b/tests/__snapshots__/bundle/remote.js new file mode 100644 index 0000000..d0b5685 --- /dev/null +++ b/tests/__snapshots__/bundle/remote.js @@ -0,0 +1,1185 @@ +const osType = (()=>{ + const { Deno: Deno1 } = globalThis; + if (typeof Deno1?.build?.os === "string") { + return Deno1.build.os; + } + const { navigator } = globalThis; + if (navigator?.appVersion?.includes?.("Win")) { + return "windows"; + } + return "linux"; +})(); +const isWindows = osType === "windows"; +const CHAR_FORWARD_SLASH = 47; +function assertPath(path) { + if (typeof path !== "string") { + throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`); + } +} +function isPosixPathSeparator(code) { + return code === 47; +} +function isPathSeparator(code) { + return isPosixPathSeparator(code) || code === 92; +} +function isWindowsDeviceRoot(code) { + return code >= 97 && code <= 122 || code >= 65 && code <= 90; +} +function normalizeString(path, allowAboveRoot, separator, isPathSeparator) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let code; + for(let i = 0, len = path.length; i <= len; ++i){ + if (i < len) code = path.charCodeAt(i); + else if (isPathSeparator(code)) break; + else code = CHAR_FORWARD_SLASH; + if (isPathSeparator(code)) { + if (lastSlash === i - 1 || dots === 1) {} else if (lastSlash !== i - 1 && dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf(separator); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); + } + lastSlash = i; + dots = 0; + continue; + } else if (res.length === 2 || res.length === 1) { + res = ""; + lastSegmentLength = 0; + lastSlash = i; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + if (res.length > 0) res += `${separator}..`; + else res = ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) res += separator + path.slice(lastSlash + 1, i); + else res = path.slice(lastSlash + 1, i); + lastSegmentLength = i - lastSlash - 1; + } + lastSlash = i; + dots = 0; + } else if (code === 46 && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +function _format(sep, pathObject) { + const dir = pathObject.dir || pathObject.root; + const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); + if (!dir) return base; + if (dir === pathObject.root) return dir + base; + return dir + sep + base; +} +const WHITESPACE_ENCODINGS = { + "\u0009": "%09", + "\u000A": "%0A", + "\u000B": "%0B", + "\u000C": "%0C", + "\u000D": "%0D", + "\u0020": "%20" +}; +function encodeWhitespace(string) { + return string.replaceAll(/[\s]/g, (c)=>{ + return WHITESPACE_ENCODINGS[c] ?? c; + }); +} +class DenoStdInternalError extends Error { + constructor(message){ + super(message); + this.name = "DenoStdInternalError"; + } +} +function assert(expr, msg = "") { + if (!expr) { + throw new DenoStdInternalError(msg); + } +} +const sep = "\\"; +const delimiter = ";"; +function resolve(...pathSegments) { + let resolvedDevice = ""; + let resolvedTail = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1; i--){ + let path; + const { Deno: Deno1 } = globalThis; + if (i >= 0) { + path = pathSegments[i]; + } else if (!resolvedDevice) { + if (typeof Deno1?.cwd !== "function") { + throw new TypeError("Resolved a drive-letter-less path without a CWD."); + } + path = Deno1.cwd(); + } else { + if (typeof Deno1?.env?.get !== "function" || typeof Deno1?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno1.cwd(); + if (path === undefined || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) { + path = `${resolvedDevice}\\`; + } + } + assertPath(path); + const len = path.length; + if (len === 0) continue; + let rootEnd = 0; + let device = ""; + let isAbsolute = false; + const code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + device = `\\\\${firstPart}\\${path.slice(last)}`; + rootEnd = j; + } else if (j !== last) { + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + rootEnd = 1; + isAbsolute = true; + } + if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) { + continue; + } + if (resolvedDevice.length === 0 && device.length > 0) { + resolvedDevice = device; + } + if (!resolvedAbsolute) { + resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`; + resolvedAbsolute = isAbsolute; + } + if (resolvedAbsolute && resolvedDevice.length > 0) break; + } + resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator); + return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || "."; +} +function normalize(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = 0; + let device; + let isAbsolute = false; + const code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + return `\\\\${firstPart}\\${path.slice(last)}\\`; + } else if (j !== last) { + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + return "\\"; + } + let tail; + if (rootEnd < len) { + tail = normalizeString(path.slice(rootEnd), !isAbsolute, "\\", isPathSeparator); + } else { + tail = ""; + } + if (tail.length === 0 && !isAbsolute) tail = "."; + if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) { + tail += "\\"; + } + if (device === undefined) { + if (isAbsolute) { + if (tail.length > 0) return `\\${tail}`; + else return "\\"; + } else if (tail.length > 0) { + return tail; + } else { + return ""; + } + } else if (isAbsolute) { + if (tail.length > 0) return `${device}\\${tail}`; + else return `${device}\\`; + } else if (tail.length > 0) { + return device + tail; + } else { + return device; + } +} +function isAbsolute(path) { + assertPath(path); + const len = path.length; + if (len === 0) return false; + const code = path.charCodeAt(0); + if (isPathSeparator(code)) { + return true; + } else if (isWindowsDeviceRoot(code)) { + if (len > 2 && path.charCodeAt(1) === 58) { + if (isPathSeparator(path.charCodeAt(2))) return true; + } + } + return false; +} +function join(...paths) { + const pathsCount = paths.length; + if (pathsCount === 0) return "."; + let joined; + let firstPart = null; + for(let i = 0; i < pathsCount; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (joined === undefined) joined = firstPart = path; + else joined += `\\${path}`; + } + } + if (joined === undefined) return "."; + let needsReplace = true; + let slashCount = 0; + assert(firstPart != null); + if (isPathSeparator(firstPart.charCodeAt(0))) { + ++slashCount; + const firstLen = firstPart.length; + if (firstLen > 1) { + if (isPathSeparator(firstPart.charCodeAt(1))) { + ++slashCount; + if (firstLen > 2) { + if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount; + else { + needsReplace = false; + } + } + } + } + } + if (needsReplace) { + for(; slashCount < joined.length; ++slashCount){ + if (!isPathSeparator(joined.charCodeAt(slashCount))) break; + } + if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`; + } + return normalize(joined); +} +function relative(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + const fromOrig = resolve(from); + const toOrig = resolve(to); + if (fromOrig === toOrig) return ""; + from = fromOrig.toLowerCase(); + to = toOrig.toLowerCase(); + if (from === to) return ""; + let fromStart = 0; + let fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== 92) break; + } + for(; fromEnd - 1 > fromStart; --fromEnd){ + if (from.charCodeAt(fromEnd - 1) !== 92) break; + } + const fromLen = fromEnd - fromStart; + let toStart = 0; + let toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== 92) break; + } + for(; toEnd - 1 > toStart; --toEnd){ + if (to.charCodeAt(toEnd - 1) !== 92) break; + } + const toLen = toEnd - toStart; + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === 92) { + return toOrig.slice(toStart + i + 1); + } else if (i === 2) { + return toOrig.slice(toStart + i); + } + } + if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === 92) { + lastCommonSep = i; + } else if (i === 2) { + lastCommonSep = 3; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === 92) lastCommonSep = i; + } + if (i !== length && lastCommonSep === -1) { + return toOrig; + } + let out = ""; + if (lastCommonSep === -1) lastCommonSep = 0; + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === 92) { + if (out.length === 0) out += ".."; + else out += "\\.."; + } + } + if (out.length > 0) { + return out + toOrig.slice(toStart + lastCommonSep, toEnd); + } else { + toStart += lastCommonSep; + if (toOrig.charCodeAt(toStart) === 92) ++toStart; + return toOrig.slice(toStart, toEnd); + } +} +function toNamespacedPath(path) { + if (typeof path !== "string") return path; + if (path.length === 0) return ""; + const resolvedPath = resolve(path); + if (resolvedPath.length >= 3) { + if (resolvedPath.charCodeAt(0) === 92) { + if (resolvedPath.charCodeAt(1) === 92) { + const code = resolvedPath.charCodeAt(2); + if (code !== 63 && code !== 46) { + return `\\\\?\\UNC\\${resolvedPath.slice(2)}`; + } + } + } else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) { + if (resolvedPath.charCodeAt(1) === 58 && resolvedPath.charCodeAt(2) === 92) { + return `\\\\?\\${resolvedPath}`; + } + } + } + return path; +} +function dirname(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = -1; + let end = -1; + let matchedSlash = true; + let offset = 0; + const code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + rootEnd = offset = 1; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + return path; + } + if (j !== last) { + rootEnd = offset = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + rootEnd = offset = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3; + } + } + } + } else if (isPathSeparator(code)) { + return path; + } + for(let i = len - 1; i >= offset; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + if (!matchedSlash) { + end = i; + break; + } + } else { + matchedSlash = false; + } + } + if (end === -1) { + if (rootEnd === -1) return "."; + else end = rootEnd; + } + return path.slice(0, end); +} +function basename(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + if (path.length >= 2) { + const drive = path.charCodeAt(0); + if (isWindowsDeviceRoot(drive)) { + if (path.charCodeAt(1) === 58) start = 2; + } + } + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + end = i; + } + } else { + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= start; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +function extname(path) { + assertPath(path); + let start = 0; + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let preDotState = 0; + if (path.length >= 2 && path.charCodeAt(1) === 58 && isWindowsDeviceRoot(path.charCodeAt(0))) { + start = startPart = 2; + } + for(let i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +function format(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("\\", pathObject); +} +function parse(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + const len = path.length; + if (len === 0) return ret; + let rootEnd = 0; + let code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + rootEnd = 1; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + rootEnd = j; + } else if (j !== last) { + rootEnd = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + if (len === 3) { + ret.root = ret.dir = path; + return ret; + } + rootEnd = 3; + } + } else { + ret.root = ret.dir = path; + return ret; + } + } + } + } else if (isPathSeparator(code)) { + ret.root = ret.dir = path; + return ret; + } + if (rootEnd > 0) ret.root = path.slice(0, rootEnd); + let startDot = -1; + let startPart = rootEnd; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + let preDotState = 0; + for(; i >= rootEnd; --i){ + code = path.charCodeAt(i); + if (isPathSeparator(code)) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + ret.base = ret.name = path.slice(startPart, end); + } + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + ret.ext = path.slice(startDot, end); + } + if (startPart > 0 && startPart !== rootEnd) { + ret.dir = path.slice(0, startPart - 1); + } else ret.dir = ret.root; + return ret; +} +function fromFileUrl(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\"); + if (url.hostname != "") { + path = `\\\\${url.hostname}${path}`; + } + return path; +} +function toFileUrl(path) { + if (!isAbsolute(path)) { + throw new TypeError("Must be an absolute path."); + } + const [, hostname, pathname] = path.match(/^(?:[/\\]{2}([^/\\]+)(?=[/\\](?:[^/\\]|$)))?(.*)/); + const url = new URL("file:///"); + url.pathname = encodeWhitespace(pathname.replace(/%/g, "%25")); + if (hostname != null && hostname != "localhost") { + url.hostname = hostname; + if (!url.hostname) { + throw new TypeError("Invalid hostname."); + } + } + return url; +} +const mod = { + sep: sep, + delimiter: delimiter, + resolve: resolve, + normalize: normalize, + isAbsolute: isAbsolute, + join: join, + relative: relative, + toNamespacedPath: toNamespacedPath, + dirname: dirname, + basename: basename, + extname: extname, + format: format, + parse: parse, + fromFileUrl: fromFileUrl, + toFileUrl: toFileUrl +}; +const sep1 = "/"; +const delimiter1 = ":"; +function resolve1(...pathSegments) { + let resolvedPath = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--){ + let path; + if (i >= 0) path = pathSegments[i]; + else { + const { Deno: Deno1 } = globalThis; + if (typeof Deno1?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno1.cwd(); + } + assertPath(path); + if (path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator); + if (resolvedAbsolute) { + if (resolvedPath.length > 0) return `/${resolvedPath}`; + else return "/"; + } else if (resolvedPath.length > 0) return resolvedPath; + else return "."; +} +function normalize1(path) { + assertPath(path); + if (path.length === 0) return "."; + const isAbsolute = path.charCodeAt(0) === 47; + const trailingSeparator = path.charCodeAt(path.length - 1) === 47; + path = normalizeString(path, !isAbsolute, "/", isPosixPathSeparator); + if (path.length === 0 && !isAbsolute) path = "."; + if (path.length > 0 && trailingSeparator) path += "/"; + if (isAbsolute) return `/${path}`; + return path; +} +function isAbsolute1(path) { + assertPath(path); + return path.length > 0 && path.charCodeAt(0) === 47; +} +function join1(...paths) { + if (paths.length === 0) return "."; + let joined; + for(let i = 0, len = paths.length; i < len; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (!joined) joined = path; + else joined += `/${path}`; + } + } + if (!joined) return "."; + return normalize1(joined); +} +function relative1(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + from = resolve1(from); + to = resolve1(to); + if (from === to) return ""; + let fromStart = 1; + const fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== 47) break; + } + const fromLen = fromEnd - fromStart; + let toStart = 1; + const toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== 47) break; + } + const toLen = toEnd - toStart; + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === 47) { + return to.slice(toStart + i + 1); + } else if (i === 0) { + return to.slice(toStart + i); + } + } else if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === 47) { + lastCommonSep = i; + } else if (i === 0) { + lastCommonSep = 0; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === 47) lastCommonSep = i; + } + let out = ""; + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === 47) { + if (out.length === 0) out += ".."; + else out += "/.."; + } + } + if (out.length > 0) return out + to.slice(toStart + lastCommonSep); + else { + toStart += lastCommonSep; + if (to.charCodeAt(toStart) === 47) ++toStart; + return to.slice(toStart); + } +} +function toNamespacedPath1(path) { + return path; +} +function dirname1(path) { + assertPath(path); + if (path.length === 0) return "."; + const hasRoot = path.charCodeAt(0) === 47; + let end = -1; + let matchedSlash = true; + for(let i = path.length - 1; i >= 1; --i){ + if (path.charCodeAt(i) === 47) { + if (!matchedSlash) { + end = i; + break; + } + } else { + matchedSlash = false; + } + } + if (end === -1) return hasRoot ? "/" : "."; + if (hasRoot && end === 1) return "//"; + return path.slice(0, end); +} +function basename1(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + end = i; + } + } else { + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= 0; --i){ + if (path.charCodeAt(i) === 47) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +function extname1(path) { + assertPath(path); + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let preDotState = 0; + for(let i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +function format1(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("/", pathObject); +} +function parse1(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + if (path.length === 0) return ret; + const isAbsolute = path.charCodeAt(0) === 47; + let start; + if (isAbsolute) { + ret.root = "/"; + start = 1; + } else { + start = 0; + } + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + let preDotState = 0; + for(; i >= start; --i){ + const code = path.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + if (startPart === 0 && isAbsolute) { + ret.base = ret.name = path.slice(1, end); + } else { + ret.base = ret.name = path.slice(startPart, end); + } + } + } else { + if (startPart === 0 && isAbsolute) { + ret.name = path.slice(1, startDot); + ret.base = path.slice(1, end); + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + } + ret.ext = path.slice(startDot, end); + } + if (startPart > 0) ret.dir = path.slice(0, startPart - 1); + else if (isAbsolute) ret.dir = "/"; + return ret; +} +function fromFileUrl1(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25")); +} +function toFileUrl1(path) { + if (!isAbsolute1(path)) { + throw new TypeError("Must be an absolute path."); + } + const url = new URL("file:///"); + url.pathname = encodeWhitespace(path.replace(/%/g, "%25").replace(/\\/g, "%5C")); + return url; +} +const mod1 = { + sep: sep1, + delimiter: delimiter1, + resolve: resolve1, + normalize: normalize1, + isAbsolute: isAbsolute1, + join: join1, + relative: relative1, + toNamespacedPath: toNamespacedPath1, + dirname: dirname1, + basename: basename1, + extname: extname1, + format: format1, + parse: parse1, + fromFileUrl: fromFileUrl1, + toFileUrl: toFileUrl1 +}; +const path = isWindows ? mod : mod1; +const { join: join2 , normalize: normalize2 } = path; +const path1 = isWindows ? mod : mod1; +const { basename: basename2 , delimiter: delimiter2 , dirname: dirname2 , extname: extname2 , format: format2 , fromFileUrl: fromFileUrl2 , isAbsolute: isAbsolute2 , join: join3 , normalize: normalize3 , parse: parse2 , relative: relative2 , resolve: resolve2 , sep: sep2 , toFileUrl: toFileUrl2 , toNamespacedPath: toNamespacedPath2 } = path1; +function isCloser(value) { + return typeof value === "object" && value != null && "close" in value && typeof value["close"] === "function"; +} +function readableStreamFromReader(reader, options = {}) { + const { autoClose =true , chunkSize =16_640 , strategy } = options; + return new ReadableStream({ + async pull (controller) { + const chunk = new Uint8Array(chunkSize); + try { + const read = await reader.read(chunk); + if (read === null) { + if (isCloser(reader) && autoClose) { + reader.close(); + } + controller.close(); + return; + } + controller.enqueue(chunk.subarray(0, read)); + } catch (e) { + controller.error(e); + if (isCloser(reader)) { + reader.close(); + } + } + }, + cancel () { + if (isCloser(reader) && autoClose) { + reader.close(); + } + } + }, strategy); +} +const importMeta = { + url: "https://deno.land/std@0.140.0/examples/chat/server.ts", + main: import.meta.main +}; +const clients = new Map(); +let clientId = 0; +function dispatch(msg) { + for (const client of clients.values()){ + client.send(msg); + } +} +function wsHandler(ws) { + const id = ++clientId; + clients.set(id, ws); + ws.onopen = ()=>{ + dispatch(`Connected: [${id}]`); + }; + ws.onmessage = (e)=>{ + console.log(`msg:${id}`, e.data); + dispatch(`[${id}]: ${e.data}`); + }; + ws.onclose = ()=>{ + clients.delete(id); + dispatch(`Closed: [${id}]`); + }; +} +async function requestHandler(req) { + const pathname = new URL(req.request.url).pathname; + if (req.request.method === "GET" && pathname === "/") { + const u = new URL("./index.html", importMeta.url); + if (u.protocol.startsWith("http")) { + fetch(u.href).then(async (resp)=>{ + const body = new Uint8Array(await resp.arrayBuffer()); + req.respondWith(new Response(body, { + status: resp.status, + headers: { + "content-type": "text/html" + } + })); + }); + } else { + const file = await Deno.open(fromFileUrl2(u)); + req.respondWith(new Response(readableStreamFromReader(file), { + status: 200, + headers: { + "content-type": "text/html" + } + })); + } + } else if (req.request.method === "GET" && pathname === "/favicon.ico") { + req.respondWith(Response.redirect("https://deno.land/favicon.ico", 302)); + } else if (req.request.method === "GET" && pathname === "/ws") { + const { socket , response } = Deno.upgradeWebSocket(req.request); + wsHandler(socket); + req.respondWith(response); + } +} +const server = Deno.listen({ + port: 8080 +}); +console.log("chat server starting on :8080...."); +for await (const conn of server){ + (async ()=>{ + const httpConn = Deno.serveHttp(conn); + for await (const requestEvent of httpConn){ + requestHandler(requestEvent); + } + })(); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL29zLnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9fY29uc3RhbnRzLnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9fdXRpbC50cyIsImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL2Fzc2VydC50cyIsImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvd2luMzIudHMiLCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNDAuMC9wYXRoL3Bvc2l4LnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9nbG9iLnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9tb2QudHMiLCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNDAuMC9zdHJlYW1zL2NvbnZlcnNpb24udHMiLCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNDAuMC9leGFtcGxlcy9jaGF0L3NlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5leHBvcnQgdHlwZSBPU1R5cGUgPSBcIndpbmRvd3NcIiB8IFwibGludXhcIiB8IFwiZGFyd2luXCI7XG5cbmV4cG9ydCBjb25zdCBvc1R5cGU6IE9TVHlwZSA9ICgoKSA9PiB7XG4gIC8vIGRlbm8tbGludC1pZ25vcmUgbm8tZXhwbGljaXQtYW55XG4gIGNvbnN0IHsgRGVubyB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gIGlmICh0eXBlb2YgRGVubz8uYnVpbGQ/Lm9zID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIERlbm8uYnVpbGQub3M7XG4gIH1cblxuICAvLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueVxuICBjb25zdCB7IG5hdmlnYXRvciB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gIGlmIChuYXZpZ2F0b3I/LmFwcFZlcnNpb24/LmluY2x1ZGVzPy4oXCJXaW5cIikpIHtcbiAgICByZXR1cm4gXCJ3aW5kb3dzXCI7XG4gIH1cblxuICByZXR1cm4gXCJsaW51eFwiO1xufSkoKTtcblxuZXhwb3J0IGNvbnN0IGlzV2luZG93cyA9IG9zVHlwZSA9PT0gXCJ3aW5kb3dzXCI7XG5leHBvcnQgY29uc3QgaXNMaW51eCA9IG9zVHlwZSA9PT0gXCJsaW51eFwiO1xuIiwiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuLy8gQWxwaGFiZXQgY2hhcnMuXG5leHBvcnQgY29uc3QgQ0hBUl9VUFBFUkNBU0VfQSA9IDY1OyAvKiBBICovXG5leHBvcnQgY29uc3QgQ0hBUl9MT1dFUkNBU0VfQSA9IDk3OyAvKiBhICovXG5leHBvcnQgY29uc3QgQ0hBUl9VUFBFUkNBU0VfWiA9IDkwOyAvKiBaICovXG5leHBvcnQgY29uc3QgQ0hBUl9MT1dFUkNBU0VfWiA9IDEyMjsgLyogeiAqL1xuXG4vLyBOb24tYWxwaGFiZXRpYyBjaGFycy5cbmV4cG9ydCBjb25zdCBDSEFSX0RPVCA9IDQ2OyAvKiAuICovXG5leHBvcnQgY29uc3QgQ0hBUl9GT1JXQVJEX1NMQVNIID0gNDc7IC8qIC8gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0JBQ0tXQVJEX1NMQVNIID0gOTI7IC8qIFxcICovXG5leHBvcnQgY29uc3QgQ0hBUl9WRVJUSUNBTF9MSU5FID0gMTI0OyAvKiB8ICovXG5leHBvcnQgY29uc3QgQ0hBUl9DT0xPTiA9IDU4OyAvKiA6ICovXG5leHBvcnQgY29uc3QgQ0hBUl9RVUVTVElPTl9NQVJLID0gNjM7IC8qID8gKi9cbmV4cG9ydCBjb25zdCBDSEFSX1VOREVSU0NPUkUgPSA5NTsgLyogXyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTElORV9GRUVEID0gMTA7IC8qIFxcbiAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQ0FSUklBR0VfUkVUVVJOID0gMTM7IC8qIFxcciAqL1xuZXhwb3J0IGNvbnN0IENIQVJfVEFCID0gOTsgLyogXFx0ICovXG5leHBvcnQgY29uc3QgQ0hBUl9GT1JNX0ZFRUQgPSAxMjsgLyogXFxmICovXG5leHBvcnQgY29uc3QgQ0hBUl9FWENMQU1BVElPTl9NQVJLID0gMzM7IC8qICEgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0hBU0ggPSAzNTsgLyogIyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfU1BBQ0UgPSAzMjsgLyogICAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTk9fQlJFQUtfU1BBQ0UgPSAxNjA7IC8qIFxcdTAwQTAgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1pFUk9fV0lEVEhfTk9CUkVBS19TUEFDRSA9IDY1Mjc5OyAvKiBcXHVGRUZGICovXG5leHBvcnQgY29uc3QgQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUID0gOTE7IC8qIFsgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUID0gOTM7IC8qIF0gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xFRlRfQU5HTEVfQlJBQ0tFVCA9IDYwOyAvKiA8ICovXG5leHBvcnQgY29uc3QgQ0hBUl9SSUdIVF9BTkdMRV9CUkFDS0VUID0gNjI7IC8qID4gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVCA9IDEyMzsgLyogeyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVCA9IDEyNTsgLyogfSAqL1xuZXhwb3J0IGNvbnN0IENIQVJfSFlQSEVOX01JTlVTID0gNDU7IC8qIC0gKi9cbmV4cG9ydCBjb25zdCBDSEFSX1BMVVMgPSA0MzsgLyogKyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfRE9VQkxFX1FVT1RFID0gMzQ7IC8qIFwiICovXG5leHBvcnQgY29uc3QgQ0hBUl9TSU5HTEVfUVVPVEUgPSAzOTsgLyogJyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUEVSQ0VOVCA9IDM3OyAvKiAlICovXG5leHBvcnQgY29uc3QgQ0hBUl9TRU1JQ09MT04gPSA1OTsgLyogOyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQ0lSQ1VNRkxFWF9BQ0NFTlQgPSA5NDsgLyogXiAqL1xuZXhwb3J0IGNvbnN0IENIQVJfR1JBVkVfQUNDRU5UID0gOTY7IC8qIGAgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0FUID0gNjQ7IC8qIEAgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0FNUEVSU0FORCA9IDM4OyAvKiAmICovXG5leHBvcnQgY29uc3QgQ0hBUl9FUVVBTCA9IDYxOyAvKiA9ICovXG5cbi8vIERpZ2l0c1xuZXhwb3J0IGNvbnN0IENIQVJfMCA9IDQ4OyAvKiAwICovXG5leHBvcnQgY29uc3QgQ0hBUl85ID0gNTc7IC8qIDkgKi9cbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgdGhlIEJyb3dzZXJpZnkgYXV0aG9ycy4gTUlUIExpY2Vuc2UuXG4vLyBQb3J0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYnJvd3NlcmlmeS9wYXRoLWJyb3dzZXJpZnkvXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmltcG9ydCB0eXBlIHsgRm9ybWF0SW5wdXRQYXRoT2JqZWN0IH0gZnJvbSBcIi4vX2ludGVyZmFjZS50c1wiO1xuaW1wb3J0IHtcbiAgQ0hBUl9CQUNLV0FSRF9TTEFTSCxcbiAgQ0hBUl9ET1QsXG4gIENIQVJfRk9SV0FSRF9TTEFTSCxcbiAgQ0hBUl9MT1dFUkNBU0VfQSxcbiAgQ0hBUl9MT1dFUkNBU0VfWixcbiAgQ0hBUl9VUFBFUkNBU0VfQSxcbiAgQ0hBUl9VUFBFUkNBU0VfWixcbn0gZnJvbSBcIi4vX2NvbnN0YW50cy50c1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UGF0aChwYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKHR5cGVvZiBwYXRoICE9PSBcInN0cmluZ1wiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIGBQYXRoIG11c3QgYmUgYSBzdHJpbmcuIFJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkocGF0aCl9YCxcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1Bvc2l4UGF0aFNlcGFyYXRvcihjb2RlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGF0aFNlcGFyYXRvcihjb2RlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzUG9zaXhQYXRoU2VwYXJhdG9yKGNvZGUpIHx8IGNvZGUgPT09IENIQVJfQkFDS1dBUkRfU0xBU0g7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1dpbmRvd3NEZXZpY2VSb290KGNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIChjb2RlID49IENIQVJfTE9XRVJDQVNFX0EgJiYgY29kZSA8PSBDSEFSX0xPV0VSQ0FTRV9aKSB8fFxuICAgIChjb2RlID49IENIQVJfVVBQRVJDQVNFX0EgJiYgY29kZSA8PSBDSEFSX1VQUEVSQ0FTRV9aKVxuICApO1xufVxuXG4vLyBSZXNvbHZlcyAuIGFuZCAuLiBlbGVtZW50cyBpbiBhIHBhdGggd2l0aCBkaXJlY3RvcnkgbmFtZXNcbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVTdHJpbmcoXG4gIHBhdGg6IHN0cmluZyxcbiAgYWxsb3dBYm92ZVJvb3Q6IGJvb2xlYW4sXG4gIHNlcGFyYXRvcjogc3RyaW5nLFxuICBpc1BhdGhTZXBhcmF0b3I6IChjb2RlOiBudW1iZXIpID0+IGJvb2xlYW4sXG4pOiBzdHJpbmcge1xuICBsZXQgcmVzID0gXCJcIjtcbiAgbGV0IGxhc3RTZWdtZW50TGVuZ3RoID0gMDtcbiAgbGV0IGxhc3RTbGFzaCA9IC0xO1xuICBsZXQgZG90cyA9IDA7XG4gIGxldCBjb2RlOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBwYXRoLmxlbmd0aDsgaSA8PSBsZW47ICsraSkge1xuICAgIGlmIChpIDwgbGVuKSBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KGkpO1xuICAgIGVsc2UgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlISkpIGJyZWFrO1xuICAgIGVsc2UgY29kZSA9IENIQVJfRk9SV0FSRF9TTEFTSDtcblxuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSEpKSB7XG4gICAgICBpZiAobGFzdFNsYXNoID09PSBpIC0gMSB8fCBkb3RzID09PSAxKSB7XG4gICAgICAgIC8vIE5PT1BcbiAgICAgIH0gZWxzZSBpZiAobGFzdFNsYXNoICE9PSBpIC0gMSAmJiBkb3RzID09PSAyKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICByZXMubGVuZ3RoIDwgMiB8fFxuICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoICE9PSAyIHx8XG4gICAgICAgICAgcmVzLmNoYXJDb2RlQXQocmVzLmxlbmd0aCAtIDEpICE9PSBDSEFSX0RPVCB8fFxuICAgICAgICAgIHJlcy5jaGFyQ29kZUF0KHJlcy5sZW5ndGggLSAyKSAhPT0gQ0hBUl9ET1RcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHJlcy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBjb25zdCBsYXN0U2xhc2hJbmRleCA9IHJlcy5sYXN0SW5kZXhPZihzZXBhcmF0b3IpO1xuICAgICAgICAgICAgaWYgKGxhc3RTbGFzaEluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgICByZXMgPSBcIlwiO1xuICAgICAgICAgICAgICBsYXN0U2VnbWVudExlbmd0aCA9IDA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXMgPSByZXMuc2xpY2UoMCwgbGFzdFNsYXNoSW5kZXgpO1xuICAgICAgICAgICAgICBsYXN0U2VnbWVudExlbmd0aCA9IHJlcy5sZW5ndGggLSAxIC0gcmVzLmxhc3RJbmRleE9mKHNlcGFyYXRvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0U2xhc2ggPSBpO1xuICAgICAgICAgICAgZG90cyA9IDA7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlcy5sZW5ndGggPT09IDIgfHwgcmVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcmVzID0gXCJcIjtcbiAgICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gMDtcbiAgICAgICAgICAgIGxhc3RTbGFzaCA9IGk7XG4gICAgICAgICAgICBkb3RzID0gMDtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxsb3dBYm92ZVJvb3QpIHtcbiAgICAgICAgICBpZiAocmVzLmxlbmd0aCA+IDApIHJlcyArPSBgJHtzZXBhcmF0b3J9Li5gO1xuICAgICAgICAgIGVsc2UgcmVzID0gXCIuLlwiO1xuICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gMjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHJlcy5sZW5ndGggPiAwKSByZXMgKz0gc2VwYXJhdG9yICsgcGF0aC5zbGljZShsYXN0U2xhc2ggKyAxLCBpKTtcbiAgICAgICAgZWxzZSByZXMgPSBwYXRoLnNsaWNlKGxhc3RTbGFzaCArIDEsIGkpO1xuICAgICAgICBsYXN0U2VnbWVudExlbmd0aCA9IGkgLSBsYXN0U2xhc2ggLSAxO1xuICAgICAgfVxuICAgICAgbGFzdFNsYXNoID0gaTtcbiAgICAgIGRvdHMgPSAwO1xuICAgIH0gZWxzZSBpZiAoY29kZSA9PT0gQ0hBUl9ET1QgJiYgZG90cyAhPT0gLTEpIHtcbiAgICAgICsrZG90cztcbiAgICB9IGVsc2Uge1xuICAgICAgZG90cyA9IC0xO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX2Zvcm1hdChcbiAgc2VwOiBzdHJpbmcsXG4gIHBhdGhPYmplY3Q6IEZvcm1hdElucHV0UGF0aE9iamVjdCxcbik6IHN0cmluZyB7XG4gIGNvbnN0IGRpcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gcGF0aE9iamVjdC5kaXIgfHwgcGF0aE9iamVjdC5yb290O1xuICBjb25zdCBiYXNlOiBzdHJpbmcgPSBwYXRoT2JqZWN0LmJhc2UgfHxcbiAgICAocGF0aE9iamVjdC5uYW1lIHx8IFwiXCIpICsgKHBhdGhPYmplY3QuZXh0IHx8IFwiXCIpO1xuICBpZiAoIWRpcikgcmV0dXJuIGJhc2U7XG4gIGlmIChkaXIgPT09IHBhdGhPYmplY3Qucm9vdCkgcmV0dXJuIGRpciArIGJhc2U7XG4gIHJldHVybiBkaXIgKyBzZXAgKyBiYXNlO1xufVxuXG5jb25zdCBXSElURVNQQUNFX0VOQ09ESU5HUzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgXCJcXHUwMDA5XCI6IFwiJTA5XCIsXG4gIFwiXFx1MDAwQVwiOiBcIiUwQVwiLFxuICBcIlxcdTAwMEJcIjogXCIlMEJcIixcbiAgXCJcXHUwMDBDXCI6IFwiJTBDXCIsXG4gIFwiXFx1MDAwRFwiOiBcIiUwRFwiLFxuICBcIlxcdTAwMjBcIjogXCIlMjBcIixcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVXaGl0ZXNwYWNlKHN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlQWxsKC9bXFxzXS9nLCAoYykgPT4ge1xuICAgIHJldHVybiBXSElURVNQQUNFX0VOQ09ESU5HU1tjXSA/PyBjO1xuICB9KTtcbn1cbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmV4cG9ydCBjbGFzcyBEZW5vU3RkSW50ZXJuYWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gXCJEZW5vU3RkSW50ZXJuYWxFcnJvclwiO1xuICB9XG59XG5cbi8qKiBNYWtlIGFuIGFzc2VydGlvbiwgaWYgbm90IGB0cnVlYCwgdGhlbiB0aHJvdy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoZXhwcjogdW5rbm93biwgbXNnID0gXCJcIik6IGFzc2VydHMgZXhwciB7XG4gIGlmICghZXhwcikge1xuICAgIHRocm93IG5ldyBEZW5vU3RkSW50ZXJuYWxFcnJvcihtc2cpO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gQ29weXJpZ2h0IHRoZSBCcm93c2VyaWZ5IGF1dGhvcnMuIE1JVCBMaWNlbnNlLlxuLy8gUG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Jyb3dzZXJpZnkvcGF0aC1icm93c2VyaWZ5L1xuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5pbXBvcnQgdHlwZSB7IEZvcm1hdElucHV0UGF0aE9iamVjdCwgUGFyc2VkUGF0aCB9IGZyb20gXCIuL19pbnRlcmZhY2UudHNcIjtcbmltcG9ydCB7XG4gIENIQVJfQkFDS1dBUkRfU0xBU0gsXG4gIENIQVJfQ09MT04sXG4gIENIQVJfRE9ULFxuICBDSEFSX1FVRVNUSU9OX01BUkssXG59IGZyb20gXCIuL19jb25zdGFudHMudHNcIjtcblxuaW1wb3J0IHtcbiAgX2Zvcm1hdCxcbiAgYXNzZXJ0UGF0aCxcbiAgZW5jb2RlV2hpdGVzcGFjZSxcbiAgaXNQYXRoU2VwYXJhdG9yLFxuICBpc1dpbmRvd3NEZXZpY2VSb290LFxuICBub3JtYWxpemVTdHJpbmcsXG59IGZyb20gXCIuL191dGlsLnRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vX3V0aWwvYXNzZXJ0LnRzXCI7XG5cbmV4cG9ydCBjb25zdCBzZXAgPSBcIlxcXFxcIjtcbmV4cG9ydCBjb25zdCBkZWxpbWl0ZXIgPSBcIjtcIjtcblxuLyoqXG4gKiBSZXNvbHZlcyBwYXRoIHNlZ21lbnRzIGludG8gYSBgcGF0aGBcbiAqIEBwYXJhbSBwYXRoU2VnbWVudHMgdG8gcHJvY2VzcyB0byBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlKC4uLnBhdGhTZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICBsZXQgcmVzb2x2ZWREZXZpY2UgPSBcIlwiO1xuICBsZXQgcmVzb2x2ZWRUYWlsID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTE7IGktLSkge1xuICAgIGxldCBwYXRoOiBzdHJpbmc7XG4gICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCB7IERlbm8gfSA9IGdsb2JhbFRoaXMgYXMgYW55O1xuICAgIGlmIChpID49IDApIHtcbiAgICAgIHBhdGggPSBwYXRoU2VnbWVudHNbaV07XG4gICAgfSBlbHNlIGlmICghcmVzb2x2ZWREZXZpY2UpIHtcbiAgICAgIGlmICh0eXBlb2YgRGVubz8uY3dkICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlJlc29sdmVkIGEgZHJpdmUtbGV0dGVyLWxlc3MgcGF0aCB3aXRob3V0IGEgQ1dELlwiKTtcbiAgICAgIH1cbiAgICAgIHBhdGggPSBEZW5vLmN3ZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBEZW5vPy5lbnY/LmdldCAhPT0gXCJmdW5jdGlvblwiIHx8IHR5cGVvZiBEZW5vPy5jd2QgIT09IFwiZnVuY3Rpb25cIlxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIHJlbGF0aXZlIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcblxuICAgICAgLy8gVmVyaWZ5IHRoYXQgYSBjd2Qgd2FzIGZvdW5kIGFuZCB0aGF0IGl0IGFjdHVhbGx5IHBvaW50c1xuICAgICAgLy8gdG8gb3VyIGRyaXZlLiBJZiBub3QsIGRlZmF1bHQgdG8gdGhlIGRyaXZlJ3Mgcm9vdC5cbiAgICAgIGlmIChcbiAgICAgICAgcGF0aCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHBhdGguc2xpY2UoMCwgMykudG9Mb3dlckNhc2UoKSAhPT0gYCR7cmVzb2x2ZWREZXZpY2UudG9Mb3dlckNhc2UoKX1cXFxcYFxuICAgICAgKSB7XG4gICAgICAgIHBhdGggPSBgJHtyZXNvbHZlZERldmljZX1cXFxcYDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gICAgY29uc3QgbGVuID0gcGF0aC5sZW5ndGg7XG5cbiAgICAvLyBTa2lwIGVtcHR5IGVudHJpZXNcbiAgICBpZiAobGVuID09PSAwKSBjb250aW51ZTtcblxuICAgIGxldCByb290RW5kID0gMDtcbiAgICBsZXQgZGV2aWNlID0gXCJcIjtcbiAgICBsZXQgaXNBYnNvbHV0ZSA9IGZhbHNlO1xuICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgICAvLyBUcnkgdG8gbWF0Y2ggYSByb290XG4gICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgICAgLy8gUG9zc2libGUgVU5DIHJvb3RcblxuICAgICAgICAvLyBJZiB3ZSBzdGFydGVkIHdpdGggYSBzZXBhcmF0b3IsIHdlIGtub3cgd2UgYXQgbGVhc3QgaGF2ZSBhblxuICAgICAgICAvLyBhYnNvbHV0ZSBwYXRoIG9mIHNvbWUga2luZCAoVU5DIG9yIG90aGVyd2lzZSlcbiAgICAgICAgaXNBYnNvbHV0ZSA9IHRydWU7XG5cbiAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgICAgLy8gTWF0Y2hlZCBkb3VibGUgcGF0aCBzZXBhcmF0b3IgYXQgYmVnaW5uaW5nXG4gICAgICAgICAgbGV0IGogPSAyO1xuICAgICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0UGFydCA9IHBhdGguc2xpY2UobGFzdCwgaik7XG4gICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICAgIGlmICghaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGogPT09IGxlbikge1xuICAgICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCBvbmx5XG4gICAgICAgICAgICAgICAgZGV2aWNlID0gYFxcXFxcXFxcJHtmaXJzdFBhcnR9XFxcXCR7cGF0aC5zbGljZShsYXN0KX1gO1xuICAgICAgICAgICAgICAgIHJvb3RFbmQgPSBqO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgd2l0aCBsZWZ0b3ZlcnNcblxuICAgICAgICAgICAgICAgIGRldmljZSA9IGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCwgail9YDtcbiAgICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByb290RW5kID0gMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgICAgaWYgKHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikge1xuICAgICAgICAgIGRldmljZSA9IHBhdGguc2xpY2UoMCwgMik7XG4gICAgICAgICAgcm9vdEVuZCA9IDI7XG4gICAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDIpKSkge1xuICAgICAgICAgICAgICAvLyBUcmVhdCBzZXBhcmF0b3IgZm9sbG93aW5nIGRyaXZlIG5hbWUgYXMgYW4gYWJzb2x1dGUgcGF0aFxuICAgICAgICAgICAgICAvLyBpbmRpY2F0b3JcbiAgICAgICAgICAgICAgaXNBYnNvbHV0ZSA9IHRydWU7XG4gICAgICAgICAgICAgIHJvb3RFbmQgPSAzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yXG4gICAgICByb290RW5kID0gMTtcbiAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGRldmljZS5sZW5ndGggPiAwICYmXG4gICAgICByZXNvbHZlZERldmljZS5sZW5ndGggPiAwICYmXG4gICAgICBkZXZpY2UudG9Mb3dlckNhc2UoKSAhPT0gcmVzb2x2ZWREZXZpY2UudG9Mb3dlckNhc2UoKVxuICAgICkge1xuICAgICAgLy8gVGhpcyBwYXRoIHBvaW50cyB0byBhbm90aGVyIGRldmljZSBzbyBpdCBpcyBub3QgYXBwbGljYWJsZVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHJlc29sdmVkRGV2aWNlLmxlbmd0aCA9PT0gMCAmJiBkZXZpY2UubGVuZ3RoID4gMCkge1xuICAgICAgcmVzb2x2ZWREZXZpY2UgPSBkZXZpY2U7XG4gICAgfVxuICAgIGlmICghcmVzb2x2ZWRBYnNvbHV0ZSkge1xuICAgICAgcmVzb2x2ZWRUYWlsID0gYCR7cGF0aC5zbGljZShyb290RW5kKX1cXFxcJHtyZXNvbHZlZFRhaWx9YDtcbiAgICAgIHJlc29sdmVkQWJzb2x1dGUgPSBpc0Fic29sdXRlO1xuICAgIH1cblxuICAgIGlmIChyZXNvbHZlZEFic29sdXRlICYmIHJlc29sdmVkRGV2aWNlLmxlbmd0aCA+IDApIGJyZWFrO1xuICB9XG5cbiAgLy8gQXQgdGhpcyBwb2ludCB0aGUgcGF0aCBzaG91bGQgYmUgcmVzb2x2ZWQgdG8gYSBmdWxsIGFic29sdXRlIHBhdGgsXG4gIC8vIGJ1dCBoYW5kbGUgcmVsYXRpdmUgcGF0aHMgdG8gYmUgc2FmZSAobWlnaHQgaGFwcGVuIHdoZW4gcHJvY2Vzcy5jd2QoKVxuICAvLyBmYWlscylcblxuICAvLyBOb3JtYWxpemUgdGhlIHRhaWwgcGF0aFxuICByZXNvbHZlZFRhaWwgPSBub3JtYWxpemVTdHJpbmcoXG4gICAgcmVzb2x2ZWRUYWlsLFxuICAgICFyZXNvbHZlZEFic29sdXRlLFxuICAgIFwiXFxcXFwiLFxuICAgIGlzUGF0aFNlcGFyYXRvcixcbiAgKTtcblxuICByZXR1cm4gcmVzb2x2ZWREZXZpY2UgKyAocmVzb2x2ZWRBYnNvbHV0ZSA/IFwiXFxcXFwiIDogXCJcIikgKyByZXNvbHZlZFRhaWwgfHwgXCIuXCI7XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIGBwYXRoYFxuICogQHBhcmFtIHBhdGggdG8gbm9ybWFsaXplXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgY29uc3QgbGVuID0gcGF0aC5sZW5ndGg7XG4gIGlmIChsZW4gPT09IDApIHJldHVybiBcIi5cIjtcbiAgbGV0IHJvb3RFbmQgPSAwO1xuICBsZXQgZGV2aWNlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGxldCBpc0Fic29sdXRlID0gZmFsc2U7XG4gIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICBpZiAobGVuID4gMSkge1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgIC8vIElmIHdlIHN0YXJ0ZWQgd2l0aCBhIHNlcGFyYXRvciwgd2Uga25vdyB3ZSBhdCBsZWFzdCBoYXZlIGFuIGFic29sdXRlXG4gICAgICAvLyBwYXRoIG9mIHNvbWUga2luZCAoVU5DIG9yIG90aGVyd2lzZSlcbiAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuXG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgxKSkpIHtcbiAgICAgICAgLy8gTWF0Y2hlZCBkb3VibGUgcGF0aCBzZXBhcmF0b3IgYXQgYmVnaW5uaW5nXG4gICAgICAgIGxldCBqID0gMjtcbiAgICAgICAgbGV0IGxhc3QgPSBqO1xuICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgY29uc3QgZmlyc3RQYXJ0ID0gcGF0aC5zbGljZShsYXN0LCBqKTtcbiAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBwYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqID09PSBsZW4pIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IG9ubHlcbiAgICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIFVOQyByb290IHNpbmNlIHRoZXJlXG4gICAgICAgICAgICAgIC8vIGlzIG5vdGhpbmcgbGVmdCB0byBwcm9jZXNzXG5cbiAgICAgICAgICAgICAgcmV0dXJuIGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCl9XFxcXGA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IHdpdGggbGVmdG92ZXJzXG5cbiAgICAgICAgICAgICAgZGV2aWNlID0gYFxcXFxcXFxcJHtmaXJzdFBhcnR9XFxcXCR7cGF0aC5zbGljZShsYXN0LCBqKX1gO1xuICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJvb3RFbmQgPSAxO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChjb2RlKSkge1xuICAgICAgLy8gUG9zc2libGUgZGV2aWNlIHJvb3RcblxuICAgICAgaWYgKHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikge1xuICAgICAgICBkZXZpY2UgPSBwYXRoLnNsaWNlKDAsIDIpO1xuICAgICAgICByb290RW5kID0gMjtcbiAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgyKSkpIHtcbiAgICAgICAgICAgIC8vIFRyZWF0IHNlcGFyYXRvciBmb2xsb3dpbmcgZHJpdmUgbmFtZSBhcyBhbiBhYnNvbHV0ZSBwYXRoXG4gICAgICAgICAgICAvLyBpbmRpY2F0b3JcbiAgICAgICAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuICAgICAgICAgICAgcm9vdEVuZCA9IDM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgIC8vIGBwYXRoYCBjb250YWlucyBqdXN0IGEgcGF0aCBzZXBhcmF0b3IsIGV4aXQgZWFybHkgdG8gYXZvaWQgdW5uZWNlc3NhcnlcbiAgICAvLyB3b3JrXG4gICAgcmV0dXJuIFwiXFxcXFwiO1xuICB9XG5cbiAgbGV0IHRhaWw6IHN0cmluZztcbiAgaWYgKHJvb3RFbmQgPCBsZW4pIHtcbiAgICB0YWlsID0gbm9ybWFsaXplU3RyaW5nKFxuICAgICAgcGF0aC5zbGljZShyb290RW5kKSxcbiAgICAgICFpc0Fic29sdXRlLFxuICAgICAgXCJcXFxcXCIsXG4gICAgICBpc1BhdGhTZXBhcmF0b3IsXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICB0YWlsID0gXCJcIjtcbiAgfVxuICBpZiAodGFpbC5sZW5ndGggPT09IDAgJiYgIWlzQWJzb2x1dGUpIHRhaWwgPSBcIi5cIjtcbiAgaWYgKHRhaWwubGVuZ3RoID4gMCAmJiBpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGxlbiAtIDEpKSkge1xuICAgIHRhaWwgKz0gXCJcXFxcXCI7XG4gIH1cbiAgaWYgKGRldmljZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICAgIGlmICh0YWlsLmxlbmd0aCA+IDApIHJldHVybiBgXFxcXCR7dGFpbH1gO1xuICAgICAgZWxzZSByZXR1cm4gXCJcXFxcXCI7XG4gICAgfSBlbHNlIGlmICh0YWlsLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB0YWlsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNBYnNvbHV0ZSkge1xuICAgIGlmICh0YWlsLmxlbmd0aCA+IDApIHJldHVybiBgJHtkZXZpY2V9XFxcXCR7dGFpbH1gO1xuICAgIGVsc2UgcmV0dXJuIGAke2RldmljZX1cXFxcYDtcbiAgfSBlbHNlIGlmICh0YWlsLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gZGV2aWNlICsgdGFpbDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZGV2aWNlO1xuICB9XG59XG5cbi8qKlxuICogVmVyaWZpZXMgd2hldGhlciBwYXRoIGlzIGFic29sdXRlXG4gKiBAcGFyYW0gcGF0aCB0byB2ZXJpZnlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQWJzb2x1dGUocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdCgwKTtcbiAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgaWYgKGxlbiA+IDIgJiYgcGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OKSB7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgyKSkpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogSm9pbiBhbGwgZ2l2ZW4gYSBzZXF1ZW5jZSBvZiBgcGF0aHNgLHRoZW4gbm9ybWFsaXplcyB0aGUgcmVzdWx0aW5nIHBhdGguXG4gKiBAcGFyYW0gcGF0aHMgdG8gYmUgam9pbmVkIGFuZCBub3JtYWxpemVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqb2luKC4uLnBhdGhzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGNvbnN0IHBhdGhzQ291bnQgPSBwYXRocy5sZW5ndGg7XG4gIGlmIChwYXRoc0NvdW50ID09PSAwKSByZXR1cm4gXCIuXCI7XG5cbiAgbGV0IGpvaW5lZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBsZXQgZmlyc3RQYXJ0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRoc0NvdW50OyArK2kpIHtcbiAgICBjb25zdCBwYXRoID0gcGF0aHNbaV07XG4gICAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgICBpZiAocGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoam9pbmVkID09PSB1bmRlZmluZWQpIGpvaW5lZCA9IGZpcnN0UGFydCA9IHBhdGg7XG4gICAgICBlbHNlIGpvaW5lZCArPSBgXFxcXCR7cGF0aH1gO1xuICAgIH1cbiAgfVxuXG4gIGlmIChqb2luZWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIFwiLlwiO1xuXG4gIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBqb2luZWQgcGF0aCBkb2Vzbid0IHN0YXJ0IHdpdGggdHdvIHNsYXNoZXMsIGJlY2F1c2VcbiAgLy8gbm9ybWFsaXplKCkgd2lsbCBtaXN0YWtlIGl0IGZvciBhbiBVTkMgcGF0aCB0aGVuLlxuICAvL1xuICAvLyBUaGlzIHN0ZXAgaXMgc2tpcHBlZCB3aGVuIGl0IGlzIHZlcnkgY2xlYXIgdGhhdCB0aGUgdXNlciBhY3R1YWxseVxuICAvLyBpbnRlbmRlZCB0byBwb2ludCBhdCBhbiBVTkMgcGF0aC4gVGhpcyBpcyBhc3N1bWVkIHdoZW4gdGhlIGZpcnN0XG4gIC8vIG5vbi1lbXB0eSBzdHJpbmcgYXJndW1lbnRzIHN0YXJ0cyB3aXRoIGV4YWN0bHkgdHdvIHNsYXNoZXMgZm9sbG93ZWQgYnlcbiAgLy8gYXQgbGVhc3Qgb25lIG1vcmUgbm9uLXNsYXNoIGNoYXJhY3Rlci5cbiAgLy9cbiAgLy8gTm90ZSB0aGF0IGZvciBub3JtYWxpemUoKSB0byB0cmVhdCBhIHBhdGggYXMgYW4gVU5DIHBhdGggaXQgbmVlZHMgdG9cbiAgLy8gaGF2ZSBhdCBsZWFzdCAyIGNvbXBvbmVudHMsIHNvIHdlIGRvbid0IGZpbHRlciBmb3IgdGhhdCBoZXJlLlxuICAvLyBUaGlzIG1lYW5zIHRoYXQgdGhlIHVzZXIgY2FuIHVzZSBqb2luIHRvIGNvbnN0cnVjdCBVTkMgcGF0aHMgZnJvbVxuICAvLyBhIHNlcnZlciBuYW1lIGFuZCBhIHNoYXJlIG5hbWU7IGZvciBleGFtcGxlOlxuICAvLyAgIHBhdGguam9pbignLy9zZXJ2ZXInLCAnc2hhcmUnKSAtPiAnXFxcXFxcXFxzZXJ2ZXJcXFxcc2hhcmVcXFxcJylcbiAgbGV0IG5lZWRzUmVwbGFjZSA9IHRydWU7XG4gIGxldCBzbGFzaENvdW50ID0gMDtcbiAgYXNzZXJ0KGZpcnN0UGFydCAhPSBudWxsKTtcbiAgaWYgKGlzUGF0aFNlcGFyYXRvcihmaXJzdFBhcnQuY2hhckNvZGVBdCgwKSkpIHtcbiAgICArK3NsYXNoQ291bnQ7XG4gICAgY29uc3QgZmlyc3RMZW4gPSBmaXJzdFBhcnQubGVuZ3RoO1xuICAgIGlmIChmaXJzdExlbiA+IDEpIHtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoZmlyc3RQYXJ0LmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgICsrc2xhc2hDb3VudDtcbiAgICAgICAgaWYgKGZpcnN0TGVuID4gMikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoZmlyc3RQYXJ0LmNoYXJDb2RlQXQoMikpKSArK3NsYXNoQ291bnQ7XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHBhdGggaW4gdGhlIGZpcnN0IHBhcnRcbiAgICAgICAgICAgIG5lZWRzUmVwbGFjZSA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAobmVlZHNSZXBsYWNlKSB7XG4gICAgLy8gRmluZCBhbnkgbW9yZSBjb25zZWN1dGl2ZSBzbGFzaGVzIHdlIG5lZWQgdG8gcmVwbGFjZVxuICAgIGZvciAoOyBzbGFzaENvdW50IDwgam9pbmVkLmxlbmd0aDsgKytzbGFzaENvdW50KSB7XG4gICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihqb2luZWQuY2hhckNvZGVBdChzbGFzaENvdW50KSkpIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIFJlcGxhY2UgdGhlIHNsYXNoZXMgaWYgbmVlZGVkXG4gICAgaWYgKHNsYXNoQ291bnQgPj0gMikgam9pbmVkID0gYFxcXFwke2pvaW5lZC5zbGljZShzbGFzaENvdW50KX1gO1xuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZShqb2luZWQpO1xufVxuXG4vKipcbiAqIEl0IHdpbGwgc29sdmUgdGhlIHJlbGF0aXZlIHBhdGggZnJvbSBgZnJvbWAgdG8gYHRvYCwgZm9yIGluc3RhbmNlOlxuICogIGZyb20gPSAnQzpcXFxcb3JhbmRlYVxcXFx0ZXN0XFxcXGFhYSdcbiAqICB0byA9ICdDOlxcXFxvcmFuZGVhXFxcXGltcGxcXFxcYmJiJ1xuICogVGhlIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24gc2hvdWxkIGJlOiAnLi5cXFxcLi5cXFxcaW1wbFxcXFxiYmInXG4gKiBAcGFyYW0gZnJvbSByZWxhdGl2ZSBwYXRoXG4gKiBAcGFyYW0gdG8gcmVsYXRpdmUgcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpdmUoZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChmcm9tKTtcbiAgYXNzZXJ0UGF0aCh0byk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICBjb25zdCBmcm9tT3JpZyA9IHJlc29sdmUoZnJvbSk7XG4gIGNvbnN0IHRvT3JpZyA9IHJlc29sdmUodG8pO1xuXG4gIGlmIChmcm9tT3JpZyA9PT0gdG9PcmlnKSByZXR1cm4gXCJcIjtcblxuICBmcm9tID0gZnJvbU9yaWcudG9Mb3dlckNhc2UoKTtcbiAgdG8gPSB0b09yaWcudG9Mb3dlckNhc2UoKTtcblxuICBpZiAoZnJvbSA9PT0gdG8pIHJldHVybiBcIlwiO1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IGZyb21TdGFydCA9IDA7XG4gIGxldCBmcm9tRW5kID0gZnJvbS5sZW5ndGg7XG4gIGZvciAoOyBmcm9tU3RhcnQgPCBmcm9tRW5kOyArK2Zyb21TdGFydCkge1xuICAgIGlmIChmcm9tLmNoYXJDb2RlQXQoZnJvbVN0YXJ0KSAhPT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgLy8gVHJpbSB0cmFpbGluZyBiYWNrc2xhc2hlcyAoYXBwbGljYWJsZSB0byBVTkMgcGF0aHMgb25seSlcbiAgZm9yICg7IGZyb21FbmQgLSAxID4gZnJvbVN0YXJ0OyAtLWZyb21FbmQpIHtcbiAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21FbmQgLSAxKSAhPT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgZnJvbUxlbiA9IGZyb21FbmQgLSBmcm9tU3RhcnQ7XG5cbiAgLy8gVHJpbSBhbnkgbGVhZGluZyBiYWNrc2xhc2hlc1xuICBsZXQgdG9TdGFydCA9IDA7XG4gIGxldCB0b0VuZCA9IHRvLmxlbmd0aDtcbiAgZm9yICg7IHRvU3RhcnQgPCB0b0VuZDsgKyt0b1N0YXJ0KSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIC8vIFRyaW0gdHJhaWxpbmcgYmFja3NsYXNoZXMgKGFwcGxpY2FibGUgdG8gVU5DIHBhdGhzIG9ubHkpXG4gIGZvciAoOyB0b0VuZCAtIDEgPiB0b1N0YXJ0OyAtLXRvRW5kKSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9FbmQgLSAxKSAhPT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgdG9MZW4gPSB0b0VuZCAtIHRvU3RhcnQ7XG5cbiAgLy8gQ29tcGFyZSBwYXRocyB0byBmaW5kIHRoZSBsb25nZXN0IGNvbW1vbiBwYXRoIGZyb20gcm9vdFxuICBjb25zdCBsZW5ndGggPSBmcm9tTGVuIDwgdG9MZW4gPyBmcm9tTGVuIDogdG9MZW47XG4gIGxldCBsYXN0Q29tbW9uU2VwID0gLTE7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPD0gbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gbGVuZ3RoKSB7XG4gICAgICBpZiAodG9MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCArIGkpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYGZyb21gIGlzIHRoZSBleGFjdCBiYXNlIHBhdGggZm9yIGB0b2AuXG4gICAgICAgICAgLy8gRm9yIGV4YW1wbGU6IGZyb209J0M6XFxcXGZvb1xcXFxiYXInOyB0bz0nQzpcXFxcZm9vXFxcXGJhclxcXFxiYXonXG4gICAgICAgICAgcmV0dXJuIHRvT3JpZy5zbGljZSh0b1N0YXJ0ICsgaSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDIpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIGRldmljZSByb290LlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPSdDOlxcXFwnOyB0bz0nQzpcXFxcZm9vJ1xuICAgICAgICAgIHJldHVybiB0b09yaWcuc2xpY2UodG9TdGFydCArIGkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZnJvbUxlbiA+IGxlbmd0aCkge1xuICAgICAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCArIGkpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYHRvYCBpcyB0aGUgZXhhY3QgYmFzZSBwYXRoIGZvciBgZnJvbWAuXG4gICAgICAgICAgLy8gRm9yIGV4YW1wbGU6IGZyb209J0M6XFxcXGZvb1xcXFxiYXInOyB0bz0nQzpcXFxcZm9vJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDIpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSBkZXZpY2Ugcm9vdC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nQzpcXFxcZm9vXFxcXGJhcic7IHRvPSdDOlxcXFwnXG4gICAgICAgICAgbGFzdENvbW1vblNlcCA9IDM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ29kZSA9IGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKTtcbiAgICBjb25zdCB0b0NvZGUgPSB0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKTtcbiAgICBpZiAoZnJvbUNvZGUgIT09IHRvQ29kZSkgYnJlYWs7XG4gICAgZWxzZSBpZiAoZnJvbUNvZGUgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGxhc3RDb21tb25TZXAgPSBpO1xuICB9XG5cbiAgLy8gV2UgZm91bmQgYSBtaXNtYXRjaCBiZWZvcmUgdGhlIGZpcnN0IGNvbW1vbiBwYXRoIHNlcGFyYXRvciB3YXMgc2Vlbiwgc29cbiAgLy8gcmV0dXJuIHRoZSBvcmlnaW5hbCBgdG9gLlxuICBpZiAoaSAhPT0gbGVuZ3RoICYmIGxhc3RDb21tb25TZXAgPT09IC0xKSB7XG4gICAgcmV0dXJuIHRvT3JpZztcbiAgfVxuXG4gIGxldCBvdXQgPSBcIlwiO1xuICBpZiAobGFzdENvbW1vblNlcCA9PT0gLTEpIGxhc3RDb21tb25TZXAgPSAwO1xuICAvLyBHZW5lcmF0ZSB0aGUgcmVsYXRpdmUgcGF0aCBiYXNlZCBvbiB0aGUgcGF0aCBkaWZmZXJlbmNlIGJldHdlZW4gYHRvYCBhbmRcbiAgLy8gYGZyb21gXG4gIGZvciAoaSA9IGZyb21TdGFydCArIGxhc3RDb21tb25TZXAgKyAxOyBpIDw9IGZyb21FbmQ7ICsraSkge1xuICAgIGlmIChpID09PSBmcm9tRW5kIHx8IGZyb20uY2hhckNvZGVBdChpKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgaWYgKG91dC5sZW5ndGggPT09IDApIG91dCArPSBcIi4uXCI7XG4gICAgICBlbHNlIG91dCArPSBcIlxcXFwuLlwiO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSwgYXBwZW5kIHRoZSByZXN0IG9mIHRoZSBkZXN0aW5hdGlvbiAoYHRvYCkgcGF0aCB0aGF0IGNvbWVzIGFmdGVyXG4gIC8vIHRoZSBjb21tb24gcGF0aCBwYXJ0c1xuICBpZiAob3V0Lmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gb3V0ICsgdG9PcmlnLnNsaWNlKHRvU3RhcnQgKyBsYXN0Q29tbW9uU2VwLCB0b0VuZCk7XG4gIH0gZWxzZSB7XG4gICAgdG9TdGFydCArPSBsYXN0Q29tbW9uU2VwO1xuICAgIGlmICh0b09yaWcuY2hhckNvZGVBdCh0b1N0YXJ0KSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgKyt0b1N0YXJ0O1xuICAgIHJldHVybiB0b09yaWcuc2xpY2UodG9TdGFydCwgdG9FbmQpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCB0byBhIG5hbWVzcGFjZSBwYXRoXG4gKiBAcGFyYW0gcGF0aCB0byByZXNvbHZlIHRvIG5hbWVzcGFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9OYW1lc3BhY2VkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBOb3RlOiB0aGlzIHdpbGwgKnByb2JhYmx5KiB0aHJvdyBzb21ld2hlcmUuXG4gIGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIHBhdGg7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiXCI7XG5cbiAgY29uc3QgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZShwYXRoKTtcblxuICBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+PSAzKSB7XG4gICAgaWYgKHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDApID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICBpZiAocmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIHtcbiAgICAgICAgY29uc3QgY29kZSA9IHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDIpO1xuICAgICAgICBpZiAoY29kZSAhPT0gQ0hBUl9RVUVTVElPTl9NQVJLICYmIGNvZGUgIT09IENIQVJfRE9UKSB7XG4gICAgICAgICAgLy8gTWF0Y2hlZCBub24tbG9uZyBVTkMgcm9vdCwgY29udmVydCB0aGUgcGF0aCB0byBhIGxvbmcgVU5DIHBhdGhcbiAgICAgICAgICByZXR1cm4gYFxcXFxcXFxcP1xcXFxVTkNcXFxcJHtyZXNvbHZlZFBhdGguc2xpY2UoMil9YDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChyZXNvbHZlZFBhdGguY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChcbiAgICAgICAgcmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04gJiZcbiAgICAgICAgcmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMikgPT09IENIQVJfQkFDS1dBUkRfU0xBU0hcbiAgICAgICkge1xuICAgICAgICAvLyBNYXRjaGVkIGRldmljZSByb290LCBjb252ZXJ0IHRoZSBwYXRoIHRvIGEgbG9uZyBVTkMgcGF0aFxuICAgICAgICByZXR1cm4gYFxcXFxcXFxcP1xcXFwke3Jlc29sdmVkUGF0aH1gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXRoO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgZGlyZWN0b3J5IG5hbWUgb2YgYSBgcGF0aGAuXG4gKiBAcGFyYW0gcGF0aCB0byBkZXRlcm1pbmUgbmFtZSBmb3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpcm5hbWUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgY29uc3QgbGVuID0gcGF0aC5sZW5ndGg7XG4gIGlmIChsZW4gPT09IDApIHJldHVybiBcIi5cIjtcbiAgbGV0IHJvb3RFbmQgPSAtMTtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IG9mZnNldCA9IDA7XG4gIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICBpZiAobGVuID4gMSkge1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgIHJvb3RFbmQgPSBvZmZzZXQgPSAxO1xuXG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgxKSkpIHtcbiAgICAgICAgLy8gTWF0Y2hlZCBkb3VibGUgcGF0aCBzZXBhcmF0b3IgYXQgYmVnaW5uaW5nXG4gICAgICAgIGxldCBqID0gMjtcbiAgICAgICAgbGV0IGxhc3QgPSBqO1xuICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgaWYgKCFpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaiA9PT0gbGVuKSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCBvbmx5XG4gICAgICAgICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IHdpdGggbGVmdG92ZXJzXG5cbiAgICAgICAgICAgICAgLy8gT2Zmc2V0IGJ5IDEgdG8gaW5jbHVkZSB0aGUgc2VwYXJhdG9yIGFmdGVyIHRoZSBVTkMgcm9vdCB0b1xuICAgICAgICAgICAgICAvLyB0cmVhdCBpdCBhcyBhIFwibm9ybWFsIHJvb3RcIiBvbiB0b3Agb2YgYSAoVU5DKSByb290XG4gICAgICAgICAgICAgIHJvb3RFbmQgPSBvZmZzZXQgPSBqICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgcm9vdEVuZCA9IG9mZnNldCA9IDI7XG4gICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSByb290RW5kID0gb2Zmc2V0ID0gMztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yLCBleGl0IGVhcmx5IHRvIGF2b2lkXG4gICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgIHJldHVybiBwYXRoO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IGxlbiAtIDE7IGkgPj0gb2Zmc2V0OyAtLWkpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChpKSkpIHtcbiAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgIGVuZCA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvclxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICBpZiAocm9vdEVuZCA9PT0gLTEpIHJldHVybiBcIi5cIjtcbiAgICBlbHNlIGVuZCA9IHJvb3RFbmQ7XG4gIH1cbiAgcmV0dXJuIHBhdGguc2xpY2UoMCwgZW5kKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGxhc3QgcG9ydGlvbiBvZiBhIGBwYXRoYC4gVHJhaWxpbmcgZGlyZWN0b3J5IHNlcGFyYXRvcnMgYXJlIGlnbm9yZWQuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKiBAcGFyYW0gZXh0IG9mIHBhdGggZGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlbmFtZShwYXRoOiBzdHJpbmcsIGV4dCA9IFwiXCIpOiBzdHJpbmcge1xuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZXh0XCIgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZycpO1xuICB9XG5cbiAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICBsZXQgaTogbnVtYmVyO1xuXG4gIC8vIENoZWNrIGZvciBhIGRyaXZlIGxldHRlciBwcmVmaXggc28gYXMgbm90IHRvIG1pc3Rha2UgdGhlIGZvbGxvd2luZ1xuICAvLyBwYXRoIHNlcGFyYXRvciBhcyBhbiBleHRyYSBzZXBhcmF0b3IgYXQgdGhlIGVuZCBvZiB0aGUgcGF0aCB0aGF0IGNhbiBiZVxuICAvLyBkaXNyZWdhcmRlZFxuICBpZiAocGF0aC5sZW5ndGggPj0gMikge1xuICAgIGNvbnN0IGRyaXZlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuICAgIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGRyaXZlKSkge1xuICAgICAgaWYgKHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikgc3RhcnQgPSAyO1xuICAgIH1cbiAgfVxuXG4gIGlmIChleHQgIT09IHVuZGVmaW5lZCAmJiBleHQubGVuZ3RoID4gMCAmJiBleHQubGVuZ3RoIDw9IHBhdGgubGVuZ3RoKSB7XG4gICAgaWYgKGV4dC5sZW5ndGggPT09IHBhdGgubGVuZ3RoICYmIGV4dCA9PT0gcGF0aCkgcmV0dXJuIFwiXCI7XG4gICAgbGV0IGV4dElkeCA9IGV4dC5sZW5ndGggLSAxO1xuICAgIGxldCBmaXJzdE5vblNsYXNoRW5kID0gLTE7XG4gICAgZm9yIChpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IHN0YXJ0OyAtLWkpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaXJzdE5vblNsYXNoRW5kID09PSAtMSkge1xuICAgICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCByZW1lbWJlciB0aGlzIGluZGV4IGluIGNhc2VcbiAgICAgICAgICAvLyB3ZSBuZWVkIGl0IGlmIHRoZSBleHRlbnNpb24gZW5kcyB1cCBub3QgbWF0Y2hpbmdcbiAgICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgICBmaXJzdE5vblNsYXNoRW5kID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dElkeCA+PSAwKSB7XG4gICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIHRoZSBleHBsaWNpdCBleHRlbnNpb25cbiAgICAgICAgICBpZiAoY29kZSA9PT0gZXh0LmNoYXJDb2RlQXQoZXh0SWR4KSkge1xuICAgICAgICAgICAgaWYgKC0tZXh0SWR4ID09PSAtMSkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIHRoZSBleHRlbnNpb24sIHNvIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91ciBwYXRoXG4gICAgICAgICAgICAgIC8vIGNvbXBvbmVudFxuICAgICAgICAgICAgICBlbmQgPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBFeHRlbnNpb24gZG9lcyBub3QgbWF0Y2gsIHNvIG91ciByZXN1bHQgaXMgdGhlIGVudGlyZSBwYXRoXG4gICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgIGV4dElkeCA9IC0xO1xuICAgICAgICAgICAgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPT09IGVuZCkgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICBlbHNlIGlmIChlbmQgPT09IC0xKSBlbmQgPSBwYXRoLmxlbmd0aDtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gc3RhcnQ7IC0taSkge1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaSkpKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZW5kID09PSAtMSkge1xuICAgICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAgIC8vIHBhdGggY29tcG9uZW50XG4gICAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgICBlbmQgPSBpICsgMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW5kID09PSAtMSkgcmV0dXJuIFwiXCI7XG4gICAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnQsIGVuZCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGV4dGVuc2lvbiBvZiB0aGUgYHBhdGhgIHdpdGggbGVhZGluZyBwZXJpb2QuXG4gKiBAcGFyYW0gcGF0aCB3aXRoIGV4dGVuc2lvblxuICogQHJldHVybnMgZXh0ZW5zaW9uIChleC4gZm9yIGBmaWxlLnRzYCByZXR1cm5zIGAudHNgKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0bmFtZShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgc3RhcnREb3QgPSAtMTtcbiAgbGV0IHN0YXJ0UGFydCA9IDA7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIC8vIFRyYWNrIHRoZSBzdGF0ZSBvZiBjaGFyYWN0ZXJzIChpZiBhbnkpIHdlIHNlZSBiZWZvcmUgb3VyIGZpcnN0IGRvdCBhbmRcbiAgLy8gYWZ0ZXIgYW55IHBhdGggc2VwYXJhdG9yIHdlIGZpbmRcbiAgbGV0IHByZURvdFN0YXRlID0gMDtcblxuICAvLyBDaGVjayBmb3IgYSBkcml2ZSBsZXR0ZXIgcHJlZml4IHNvIGFzIG5vdCB0byBtaXN0YWtlIHRoZSBmb2xsb3dpbmdcbiAgLy8gcGF0aCBzZXBhcmF0b3IgYXMgYW4gZXh0cmEgc2VwYXJhdG9yIGF0IHRoZSBlbmQgb2YgdGhlIHBhdGggdGhhdCBjYW4gYmVcbiAgLy8gZGlzcmVnYXJkZWRcblxuICBpZiAoXG4gICAgcGF0aC5sZW5ndGggPj0gMiAmJlxuICAgIHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTiAmJlxuICAgIGlzV2luZG93c0RldmljZVJvb3QocGF0aC5jaGFyQ29kZUF0KDApKVxuICApIHtcbiAgICBzdGFydCA9IHN0YXJ0UGFydCA9IDI7XG4gIH1cblxuICBmb3IgKGxldCBpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IHN0YXJ0OyAtLWkpIHtcbiAgICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAvLyBzZXBhcmF0b3JzIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZywgc3RvcCBub3dcbiAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgIHN0YXJ0UGFydCA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoZW5kID09PSAtMSkge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3IsIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91clxuICAgICAgLy8gZXh0ZW5zaW9uXG4gICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgIGVuZCA9IGkgKyAxO1xuICAgIH1cbiAgICBpZiAoY29kZSA9PT0gQ0hBUl9ET1QpIHtcbiAgICAgIC8vIElmIHRoaXMgaXMgb3VyIGZpcnN0IGRvdCwgbWFyayBpdCBhcyB0aGUgc3RhcnQgb2Ygb3VyIGV4dGVuc2lvblxuICAgICAgaWYgKHN0YXJ0RG90ID09PSAtMSkgc3RhcnREb3QgPSBpO1xuICAgICAgZWxzZSBpZiAocHJlRG90U3RhdGUgIT09IDEpIHByZURvdFN0YXRlID0gMTtcbiAgICB9IGVsc2UgaWYgKHN0YXJ0RG90ICE9PSAtMSkge1xuICAgICAgLy8gV2Ugc2F3IGEgbm9uLWRvdCBhbmQgbm9uLXBhdGggc2VwYXJhdG9yIGJlZm9yZSBvdXIgZG90LCBzbyB3ZSBzaG91bGRcbiAgICAgIC8vIGhhdmUgYSBnb29kIGNoYW5jZSBhdCBoYXZpbmcgYSBub24tZW1wdHkgZXh0ZW5zaW9uXG4gICAgICBwcmVEb3RTdGF0ZSA9IC0xO1xuICAgIH1cbiAgfVxuXG4gIGlmIChcbiAgICBzdGFydERvdCA9PT0gLTEgfHxcbiAgICBlbmQgPT09IC0xIHx8XG4gICAgLy8gV2Ugc2F3IGEgbm9uLWRvdCBjaGFyYWN0ZXIgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBkb3RcbiAgICBwcmVEb3RTdGF0ZSA9PT0gMCB8fFxuICAgIC8vIFRoZSAocmlnaHQtbW9zdCkgdHJpbW1lZCBwYXRoIGNvbXBvbmVudCBpcyBleGFjdGx5ICcuLidcbiAgICAocHJlRG90U3RhdGUgPT09IDEgJiYgc3RhcnREb3QgPT09IGVuZCAtIDEgJiYgc3RhcnREb3QgPT09IHN0YXJ0UGFydCArIDEpXG4gICkge1xuICAgIHJldHVybiBcIlwiO1xuICB9XG4gIHJldHVybiBwYXRoLnNsaWNlKHN0YXJ0RG90LCBlbmQpO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgcGF0aCBmcm9tIGBGb3JtYXRJbnB1dFBhdGhPYmplY3RgIG9iamVjdC5cbiAqIEBwYXJhbSBwYXRoT2JqZWN0IHdpdGggcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0KHBhdGhPYmplY3Q6IEZvcm1hdElucHV0UGF0aE9iamVjdCk6IHN0cmluZyB7XG4gIGlmIChwYXRoT2JqZWN0ID09PSBudWxsIHx8IHR5cGVvZiBwYXRoT2JqZWN0ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIGBUaGUgXCJwYXRoT2JqZWN0XCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIE9iamVjdC4gUmVjZWl2ZWQgdHlwZSAke3R5cGVvZiBwYXRoT2JqZWN0fWAsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gX2Zvcm1hdChcIlxcXFxcIiwgcGF0aE9iamVjdCk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgYFBhcnNlZFBhdGhgIG9iamVjdCBvZiB0aGUgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gcHJvY2Vzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2UocGF0aDogc3RyaW5nKTogUGFyc2VkUGF0aCB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgY29uc3QgcmV0OiBQYXJzZWRQYXRoID0geyByb290OiBcIlwiLCBkaXI6IFwiXCIsIGJhc2U6IFwiXCIsIGV4dDogXCJcIiwgbmFtZTogXCJcIiB9O1xuXG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gcmV0O1xuXG4gIGxldCByb290RW5kID0gMDtcbiAgbGV0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICBpZiAobGVuID4gMSkge1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgIHJvb3RFbmQgPSAxO1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICBsZXQgaiA9IDI7XG4gICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIHBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgIGlmICghaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogPT09IGxlbikge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgb25seVxuXG4gICAgICAgICAgICAgIHJvb3RFbmQgPSBqO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCB3aXRoIGxlZnRvdmVyc1xuXG4gICAgICAgICAgICAgIHJvb3RFbmQgPSBqICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgcm9vdEVuZCA9IDI7XG4gICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSB7XG4gICAgICAgICAgICBpZiAobGVuID09PSAzKSB7XG4gICAgICAgICAgICAgIC8vIGBwYXRoYCBjb250YWlucyBqdXN0IGEgZHJpdmUgcm9vdCwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgICAgICAgICAgICAvLyB1bm5lY2Vzc2FyeSB3b3JrXG4gICAgICAgICAgICAgIHJldC5yb290ID0gcmV0LmRpciA9IHBhdGg7XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByb290RW5kID0gMztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBkcml2ZSByb290LCBleGl0IGVhcmx5IHRvIGF2b2lkXG4gICAgICAgICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgICAgICAgIHJldC5yb290ID0gcmV0LmRpciA9IHBhdGg7XG4gICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yLCBleGl0IGVhcmx5IHRvIGF2b2lkXG4gICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgIHJldC5yb290ID0gcmV0LmRpciA9IHBhdGg7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIGlmIChyb290RW5kID4gMCkgcmV0LnJvb3QgPSBwYXRoLnNsaWNlKDAsIHJvb3RFbmQpO1xuXG4gIGxldCBzdGFydERvdCA9IC0xO1xuICBsZXQgc3RhcnRQYXJ0ID0gcm9vdEVuZDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGkgPSBwYXRoLmxlbmd0aCAtIDE7XG5cbiAgLy8gVHJhY2sgdGhlIHN0YXRlIG9mIGNoYXJhY3RlcnMgKGlmIGFueSkgd2Ugc2VlIGJlZm9yZSBvdXIgZmlyc3QgZG90IGFuZFxuICAvLyBhZnRlciBhbnkgcGF0aCBzZXBhcmF0b3Igd2UgZmluZFxuICBsZXQgcHJlRG90U3RhdGUgPSAwO1xuXG4gIC8vIEdldCBub24tZGlyIGluZm9cbiAgZm9yICg7IGkgPj0gcm9vdEVuZDsgLS1pKSB7XG4gICAgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICBpZiAoZW5kICE9PSAtMSkge1xuICAgICAgcmV0LmJhc2UgPSByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBlbmQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBzdGFydERvdCk7XG4gICAgcmV0LmJhc2UgPSBwYXRoLnNsaWNlKHN0YXJ0UGFydCwgZW5kKTtcbiAgICByZXQuZXh0ID0gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbiAgfVxuXG4gIC8vIElmIHRoZSBkaXJlY3RvcnkgaXMgdGhlIHJvb3QsIHVzZSB0aGUgZW50aXJlIHJvb3QgYXMgdGhlIGBkaXJgIGluY2x1ZGluZ1xuICAvLyB0aGUgdHJhaWxpbmcgc2xhc2ggaWYgYW55IChgQzpcXGFiY2AgLT4gYEM6XFxgKS4gT3RoZXJ3aXNlLCBzdHJpcCBvdXQgdGhlXG4gIC8vIHRyYWlsaW5nIHNsYXNoIChgQzpcXGFiY1xcZGVmYCAtPiBgQzpcXGFiY2ApLlxuICBpZiAoc3RhcnRQYXJ0ID4gMCAmJiBzdGFydFBhcnQgIT09IHJvb3RFbmQpIHtcbiAgICByZXQuZGlyID0gcGF0aC5zbGljZSgwLCBzdGFydFBhcnQgLSAxKTtcbiAgfSBlbHNlIHJldC5kaXIgPSByZXQucm9vdDtcblxuICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgZmlsZSBVUkwgdG8gYSBwYXRoIHN0cmluZy5cbiAqXG4gKiBgYGB0c1xuICogICAgICBpbXBvcnQgeyBmcm9tRmlsZVVybCB9IGZyb20gXCIuL3dpbjMyLnRzXCI7XG4gKiAgICAgIGZyb21GaWxlVXJsKFwiZmlsZTovLy9ob21lL2Zvb1wiKTsgLy8gXCJcXFxcaG9tZVxcXFxmb29cIlxuICogICAgICBmcm9tRmlsZVVybChcImZpbGU6Ly8vQzovVXNlcnMvZm9vXCIpOyAvLyBcIkM6XFxcXFVzZXJzXFxcXGZvb1wiXG4gKiAgICAgIGZyb21GaWxlVXJsKFwiZmlsZTovL2xvY2FsaG9zdC9ob21lL2Zvb1wiKTsgLy8gXCJcXFxcXFxcXGxvY2FsaG9zdFxcXFxob21lXFxcXGZvb1wiXG4gKiBgYGBcbiAqIEBwYXJhbSB1cmwgb2YgYSBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUZpbGVVcmwodXJsOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICB1cmwgPSB1cmwgaW5zdGFuY2VvZiBVUkwgPyB1cmwgOiBuZXcgVVJMKHVybCk7XG4gIGlmICh1cmwucHJvdG9jb2wgIT0gXCJmaWxlOlwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYSBmaWxlIFVSTC5cIik7XG4gIH1cbiAgbGV0IHBhdGggPSBkZWNvZGVVUklDb21wb25lbnQoXG4gICAgdXJsLnBhdGhuYW1lLnJlcGxhY2UoL1xcLy9nLCBcIlxcXFxcIikucmVwbGFjZSgvJSg/IVswLTlBLUZhLWZdezJ9KS9nLCBcIiUyNVwiKSxcbiAgKS5yZXBsYWNlKC9eXFxcXCooW0EtWmEtel06KShcXFxcfCQpLywgXCIkMVxcXFxcIik7XG4gIGlmICh1cmwuaG9zdG5hbWUgIT0gXCJcIikge1xuICAgIC8vIE5vdGU6IFRoZSBgVVJMYCBpbXBsZW1lbnRhdGlvbiBndWFyYW50ZWVzIHRoYXQgdGhlIGRyaXZlIGxldHRlciBhbmRcbiAgICAvLyBob3N0bmFtZSBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiBPdGhlcndpc2UgaXQgd291bGQgbm90IGhhdmUgYmVlbiB2YWxpZFxuICAgIC8vIHRvIGFwcGVuZCB0aGUgaG9zdG5hbWUgYW5kIHBhdGggbGlrZSB0aGlzLlxuICAgIHBhdGggPSBgXFxcXFxcXFwke3VybC5ob3N0bmFtZX0ke3BhdGh9YDtcbiAgfVxuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHBhdGggc3RyaW5nIHRvIGEgZmlsZSBVUkwuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgdG9GaWxlVXJsIH0gZnJvbSBcIi4vd2luMzIudHNcIjtcbiAqICAgICAgdG9GaWxlVXJsKFwiXFxcXGhvbWVcXFxcZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9ob21lL2Zvb1wiKVxuICogICAgICB0b0ZpbGVVcmwoXCJDOlxcXFxVc2Vyc1xcXFxmb29cIik7IC8vIG5ldyBVUkwoXCJmaWxlOi8vL0M6L1VzZXJzL2Zvb1wiKVxuICogICAgICB0b0ZpbGVVcmwoXCJcXFxcXFxcXDEyNy4wLjAuMVxcXFxob21lXFxcXGZvb1wiKTsgLy8gbmV3IFVSTChcImZpbGU6Ly8xMjcuMC4wLjEvaG9tZS9mb29cIilcbiAqIGBgYFxuICogQHBhcmFtIHBhdGggdG8gY29udmVydCB0byBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9GaWxlVXJsKHBhdGg6IHN0cmluZyk6IFVSTCB7XG4gIGlmICghaXNBYnNvbHV0ZShwYXRoKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNdXN0IGJlIGFuIGFic29sdXRlIHBhdGguXCIpO1xuICB9XG4gIGNvbnN0IFssIGhvc3RuYW1lLCBwYXRobmFtZV0gPSBwYXRoLm1hdGNoKFxuICAgIC9eKD86Wy9cXFxcXXsyfShbXi9cXFxcXSspKD89Wy9cXFxcXSg/OlteL1xcXFxdfCQpKSk/KC4qKS8sXG4gICkhO1xuICBjb25zdCB1cmwgPSBuZXcgVVJMKFwiZmlsZTovLy9cIik7XG4gIHVybC5wYXRobmFtZSA9IGVuY29kZVdoaXRlc3BhY2UocGF0aG5hbWUucmVwbGFjZSgvJS9nLCBcIiUyNVwiKSk7XG4gIGlmIChob3N0bmFtZSAhPSBudWxsICYmIGhvc3RuYW1lICE9IFwibG9jYWxob3N0XCIpIHtcbiAgICB1cmwuaG9zdG5hbWUgPSBob3N0bmFtZTtcbiAgICBpZiAoIXVybC5ob3N0bmFtZSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgaG9zdG5hbWUuXCIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdXJsO1xufVxuIiwiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QsIFBhcnNlZFBhdGggfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQgeyBDSEFSX0RPVCwgQ0hBUl9GT1JXQVJEX1NMQVNIIH0gZnJvbSBcIi4vX2NvbnN0YW50cy50c1wiO1xuXG5pbXBvcnQge1xuICBfZm9ybWF0LFxuICBhc3NlcnRQYXRoLFxuICBlbmNvZGVXaGl0ZXNwYWNlLFxuICBpc1Bvc2l4UGF0aFNlcGFyYXRvcixcbiAgbm9ybWFsaXplU3RyaW5nLFxufSBmcm9tIFwiLi9fdXRpbC50c1wiO1xuXG5leHBvcnQgY29uc3Qgc2VwID0gXCIvXCI7XG5leHBvcnQgY29uc3QgZGVsaW1pdGVyID0gXCI6XCI7XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8qKlxuICogUmVzb2x2ZXMgYHBhdGhTZWdtZW50c2AgaW50byBhbiBhYnNvbHV0ZSBwYXRoLlxuICogQHBhcmFtIHBhdGhTZWdtZW50cyBhbiBhcnJheSBvZiBwYXRoIHNlZ21lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlKC4uLnBhdGhTZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICBsZXQgcmVzb2x2ZWRQYXRoID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTEgJiYgIXJlc29sdmVkQWJzb2x1dGU7IGktLSkge1xuICAgIGxldCBwYXRoOiBzdHJpbmc7XG5cbiAgICBpZiAoaSA+PSAwKSBwYXRoID0gcGF0aFNlZ21lbnRzW2ldO1xuICAgIGVsc2Uge1xuICAgICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICAgIGNvbnN0IHsgRGVubyB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gICAgICBpZiAodHlwZW9mIERlbm8/LmN3ZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIHJlbGF0aXZlIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcbiAgICB9XG5cbiAgICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBlbnRyaWVzXG4gICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXNvbHZlZFBhdGggPSBgJHtwYXRofS8ke3Jlc29sdmVkUGF0aH1gO1xuICAgIHJlc29sdmVkQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZVN0cmluZyhcbiAgICByZXNvbHZlZFBhdGgsXG4gICAgIXJlc29sdmVkQWJzb2x1dGUsXG4gICAgXCIvXCIsXG4gICAgaXNQb3NpeFBhdGhTZXBhcmF0b3IsXG4gICk7XG5cbiAgaWYgKHJlc29sdmVkQWJzb2x1dGUpIHtcbiAgICBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiBgLyR7cmVzb2x2ZWRQYXRofWA7XG4gICAgZWxzZSByZXR1cm4gXCIvXCI7XG4gIH0gZWxzZSBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiByZXNvbHZlZFBhdGg7XG4gIGVsc2UgcmV0dXJuIFwiLlwiO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSB0aGUgYHBhdGhgLCByZXNvbHZpbmcgYCcuLidgIGFuZCBgJy4nYCBzZWdtZW50cy5cbiAqIEBwYXJhbSBwYXRoIHRvIGJlIG5vcm1hbGl6ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuXG4gIGNvbnN0IGlzQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgY29uc3QgdHJhaWxpbmdTZXBhcmF0b3IgPVxuICAgIHBhdGguY2hhckNvZGVBdChwYXRoLmxlbmd0aCAtIDEpID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHBhdGggPSBub3JtYWxpemVTdHJpbmcocGF0aCwgIWlzQWJzb2x1dGUsIFwiL1wiLCBpc1Bvc2l4UGF0aFNlcGFyYXRvcik7XG5cbiAgaWYgKHBhdGgubGVuZ3RoID09PSAwICYmICFpc0Fic29sdXRlKSBwYXRoID0gXCIuXCI7XG4gIGlmIChwYXRoLmxlbmd0aCA+IDAgJiYgdHJhaWxpbmdTZXBhcmF0b3IpIHBhdGggKz0gXCIvXCI7XG5cbiAgaWYgKGlzQWJzb2x1dGUpIHJldHVybiBgLyR7cGF0aH1gO1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBWZXJpZmllcyB3aGV0aGVyIHByb3ZpZGVkIHBhdGggaXMgYWJzb2x1dGVcbiAqIEBwYXJhbSBwYXRoIHRvIGJlIHZlcmlmaWVkIGFzIGFic29sdXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Fic29sdXRlKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICByZXR1cm4gcGF0aC5sZW5ndGggPiAwICYmIHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xufVxuXG4vKipcbiAqIEpvaW4gYWxsIGdpdmVuIGEgc2VxdWVuY2Ugb2YgYHBhdGhzYCx0aGVuIG5vcm1hbGl6ZXMgdGhlIHJlc3VsdGluZyBwYXRoLlxuICogQHBhcmFtIHBhdGhzIHRvIGJlIGpvaW5lZCBhbmQgbm9ybWFsaXplZFxuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbiguLi5wYXRoczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAocGF0aHMubGVuZ3RoID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCBqb2luZWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBhdGhzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgIGFzc2VydFBhdGgocGF0aCk7XG4gICAgaWYgKHBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFqb2luZWQpIGpvaW5lZCA9IHBhdGg7XG4gICAgICBlbHNlIGpvaW5lZCArPSBgLyR7cGF0aH1gO1xuICAgIH1cbiAgfVxuICBpZiAoIWpvaW5lZCkgcmV0dXJuIFwiLlwiO1xuICByZXR1cm4gbm9ybWFsaXplKGpvaW5lZCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSByZWxhdGl2ZSBwYXRoIGZyb20gYGZyb21gIHRvIGB0b2AgYmFzZWQgb24gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSBmcm9tIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICogQHBhcmFtIHRvIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpdmUoZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChmcm9tKTtcbiAgYXNzZXJ0UGF0aCh0byk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICBmcm9tID0gcmVzb2x2ZShmcm9tKTtcbiAgdG8gPSByZXNvbHZlKHRvKTtcblxuICBpZiAoZnJvbSA9PT0gdG8pIHJldHVybiBcIlwiO1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IGZyb21TdGFydCA9IDE7XG4gIGNvbnN0IGZyb21FbmQgPSBmcm9tLmxlbmd0aDtcbiAgZm9yICg7IGZyb21TdGFydCA8IGZyb21FbmQ7ICsrZnJvbVN0YXJ0KSB7XG4gICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQpICE9PSBDSEFSX0ZPUldBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IGZyb21MZW4gPSBmcm9tRW5kIC0gZnJvbVN0YXJ0O1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IHRvU3RhcnQgPSAxO1xuICBjb25zdCB0b0VuZCA9IHRvLmxlbmd0aDtcbiAgZm9yICg7IHRvU3RhcnQgPCB0b0VuZDsgKyt0b1N0YXJ0KSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCkgIT09IENIQVJfRk9SV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgdG9MZW4gPSB0b0VuZCAtIHRvU3RhcnQ7XG5cbiAgLy8gQ29tcGFyZSBwYXRocyB0byBmaW5kIHRoZSBsb25nZXN0IGNvbW1vbiBwYXRoIGZyb20gcm9vdFxuICBjb25zdCBsZW5ndGggPSBmcm9tTGVuIDwgdG9MZW4gPyBmcm9tTGVuIDogdG9MZW47XG4gIGxldCBsYXN0Q29tbW9uU2VwID0gLTE7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPD0gbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gbGVuZ3RoKSB7XG4gICAgICBpZiAodG9MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIGV4YWN0IGJhc2UgcGF0aCBmb3IgYHRvYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXInOyB0bz0nL2Zvby9iYXIvYmF6J1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIHJvb3RcbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nLyc7IHRvPScvZm9vJ1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZnJvbUxlbiA+IGxlbmd0aCkge1xuICAgICAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSBleGFjdCBiYXNlIHBhdGggZm9yIGBmcm9tYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXIvYmF6JzsgdG89Jy9mb28vYmFyJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSByb290LlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPScvZm9vJzsgdG89Jy8nXG4gICAgICAgICAgbGFzdENvbW1vblNlcCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ29kZSA9IGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKTtcbiAgICBjb25zdCB0b0NvZGUgPSB0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKTtcbiAgICBpZiAoZnJvbUNvZGUgIT09IHRvQ29kZSkgYnJlYWs7XG4gICAgZWxzZSBpZiAoZnJvbUNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkgbGFzdENvbW1vblNlcCA9IGk7XG4gIH1cblxuICBsZXQgb3V0ID0gXCJcIjtcbiAgLy8gR2VuZXJhdGUgdGhlIHJlbGF0aXZlIHBhdGggYmFzZWQgb24gdGhlIHBhdGggZGlmZmVyZW5jZSBiZXR3ZWVuIGB0b2BcbiAgLy8gYW5kIGBmcm9tYFxuICBmb3IgKGkgPSBmcm9tU3RhcnQgKyBsYXN0Q29tbW9uU2VwICsgMTsgaSA8PSBmcm9tRW5kOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gZnJvbUVuZCB8fCBmcm9tLmNoYXJDb2RlQXQoaSkgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgaWYgKG91dC5sZW5ndGggPT09IDApIG91dCArPSBcIi4uXCI7XG4gICAgICBlbHNlIG91dCArPSBcIi8uLlwiO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSwgYXBwZW5kIHRoZSByZXN0IG9mIHRoZSBkZXN0aW5hdGlvbiAoYHRvYCkgcGF0aCB0aGF0IGNvbWVzIGFmdGVyXG4gIC8vIHRoZSBjb21tb24gcGF0aCBwYXJ0c1xuICBpZiAob3V0Lmxlbmd0aCA+IDApIHJldHVybiBvdXQgKyB0by5zbGljZSh0b1N0YXJ0ICsgbGFzdENvbW1vblNlcCk7XG4gIGVsc2Uge1xuICAgIHRvU3RhcnQgKz0gbGFzdENvbW1vblNlcDtcbiAgICBpZiAodG8uY2hhckNvZGVBdCh0b1N0YXJ0KSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSArK3RvU3RhcnQ7XG4gICAgcmV0dXJuIHRvLnNsaWNlKHRvU3RhcnQpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCB0byBhIG5hbWVzcGFjZSBwYXRoXG4gKiBAcGFyYW0gcGF0aCB0byByZXNvbHZlIHRvIG5hbWVzcGFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9OYW1lc3BhY2VkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBOb24tb3Agb24gcG9zaXggc3lzdGVtc1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGRpcmVjdG9yeSBuYW1lIG9mIGEgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gZGV0ZXJtaW5lIG5hbWUgZm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuICBjb25zdCBoYXNSb290ID0gcGF0aC5jaGFyQ29kZUF0KDApID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGZvciAobGV0IGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMTsgLS1pKSB7XG4gICAgaWYgKHBhdGguY2hhckNvZGVBdChpKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3JcbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbmQgPT09IC0xKSByZXR1cm4gaGFzUm9vdCA/IFwiL1wiIDogXCIuXCI7XG4gIGlmIChoYXNSb290ICYmIGVuZCA9PT0gMSkgcmV0dXJuIFwiLy9cIjtcbiAgcmV0dXJuIHBhdGguc2xpY2UoMCwgZW5kKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGxhc3QgcG9ydGlvbiBvZiBhIGBwYXRoYC4gVHJhaWxpbmcgZGlyZWN0b3J5IHNlcGFyYXRvcnMgYXJlIGlnbm9yZWQuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKiBAcGFyYW0gZXh0IG9mIHBhdGggZGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlbmFtZShwYXRoOiBzdHJpbmcsIGV4dCA9IFwiXCIpOiBzdHJpbmcge1xuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZXh0XCIgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZycpO1xuICB9XG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGk6IG51bWJlcjtcblxuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgZXh0Lmxlbmd0aCA+IDAgJiYgZXh0Lmxlbmd0aCA8PSBwYXRoLmxlbmd0aCkge1xuICAgIGlmIChleHQubGVuZ3RoID09PSBwYXRoLmxlbmd0aCAmJiBleHQgPT09IHBhdGgpIHJldHVybiBcIlwiO1xuICAgIGxldCBleHRJZHggPSBleHQubGVuZ3RoIC0gMTtcbiAgICBsZXQgZmlyc3ROb25TbGFzaEVuZCA9IC0xO1xuICAgIGZvciAoaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaXJzdE5vblNsYXNoRW5kID09PSAtMSkge1xuICAgICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCByZW1lbWJlciB0aGlzIGluZGV4IGluIGNhc2VcbiAgICAgICAgICAvLyB3ZSBuZWVkIGl0IGlmIHRoZSBleHRlbnNpb24gZW5kcyB1cCBub3QgbWF0Y2hpbmdcbiAgICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgICBmaXJzdE5vblNsYXNoRW5kID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dElkeCA+PSAwKSB7XG4gICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIHRoZSBleHBsaWNpdCBleHRlbnNpb25cbiAgICAgICAgICBpZiAoY29kZSA9PT0gZXh0LmNoYXJDb2RlQXQoZXh0SWR4KSkge1xuICAgICAgICAgICAgaWYgKC0tZXh0SWR4ID09PSAtMSkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIHRoZSBleHRlbnNpb24sIHNvIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91ciBwYXRoXG4gICAgICAgICAgICAgIC8vIGNvbXBvbmVudFxuICAgICAgICAgICAgICBlbmQgPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBFeHRlbnNpb24gZG9lcyBub3QgbWF0Y2gsIHNvIG91ciByZXN1bHQgaXMgdGhlIGVudGlyZSBwYXRoXG4gICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgIGV4dElkeCA9IC0xO1xuICAgICAgICAgICAgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPT09IGVuZCkgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICBlbHNlIGlmIChlbmQgPT09IC0xKSBlbmQgPSBwYXRoLmxlbmd0aDtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgICAgLy8gcGF0aCBjb21wb25lbnRcbiAgICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICAgIGVuZCA9IGkgKyAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbmQgPT09IC0xKSByZXR1cm4gXCJcIjtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgZXh0ZW5zaW9uIG9mIHRoZSBgcGF0aGAgd2l0aCBsZWFkaW5nIHBlcmlvZC5cbiAqIEBwYXJhbSBwYXRoIHdpdGggZXh0ZW5zaW9uXG4gKiBAcmV0dXJucyBleHRlbnNpb24gKGV4LiBmb3IgYGZpbGUudHNgIHJldHVybnMgYC50c2ApXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGxldCBzdGFydERvdCA9IC0xO1xuICBsZXQgc3RhcnRQYXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgLy8gVHJhY2sgdGhlIHN0YXRlIG9mIGNoYXJhY3RlcnMgKGlmIGFueSkgd2Ugc2VlIGJlZm9yZSBvdXIgZmlyc3QgZG90IGFuZFxuICAvLyBhZnRlciBhbnkgcGF0aCBzZXBhcmF0b3Igd2UgZmluZFxuICBsZXQgcHJlRG90U3RhdGUgPSAwO1xuICBmb3IgKGxldCBpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgc3RhcnRQYXJ0ID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25cbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgZW5kID0gaSArIDE7XG4gICAgfVxuICAgIGlmIChjb2RlID09PSBDSEFSX0RPVCkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBvdXIgZmlyc3QgZG90LCBtYXJrIGl0IGFzIHRoZSBzdGFydCBvZiBvdXIgZXh0ZW5zaW9uXG4gICAgICBpZiAoc3RhcnREb3QgPT09IC0xKSBzdGFydERvdCA9IGk7XG4gICAgICBlbHNlIGlmIChwcmVEb3RTdGF0ZSAhPT0gMSkgcHJlRG90U3RhdGUgPSAxO1xuICAgIH0gZWxzZSBpZiAoc3RhcnREb3QgIT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgYSBub24tZG90IGFuZCBub24tcGF0aCBzZXBhcmF0b3IgYmVmb3JlIG91ciBkb3QsIHNvIHdlIHNob3VsZFxuICAgICAgLy8gaGF2ZSBhIGdvb2QgY2hhbmNlIGF0IGhhdmluZyBhIG5vbi1lbXB0eSBleHRlbnNpb25cbiAgICAgIHByZURvdFN0YXRlID0gLTE7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIHN0YXJ0RG90ID09PSAtMSB8fFxuICAgIGVuZCA9PT0gLTEgfHxcbiAgICAvLyBXZSBzYXcgYSBub24tZG90IGNoYXJhY3RlciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGRvdFxuICAgIHByZURvdFN0YXRlID09PSAwIHx8XG4gICAgLy8gVGhlIChyaWdodC1tb3N0KSB0cmltbWVkIHBhdGggY29tcG9uZW50IGlzIGV4YWN0bHkgJy4uJ1xuICAgIChwcmVEb3RTdGF0ZSA9PT0gMSAmJiBzdGFydERvdCA9PT0gZW5kIC0gMSAmJiBzdGFydERvdCA9PT0gc3RhcnRQYXJ0ICsgMSlcbiAgKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbiAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnREb3QsIGVuZCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBwYXRoIGZyb20gYEZvcm1hdElucHV0UGF0aE9iamVjdGAgb2JqZWN0LlxuICogQHBhcmFtIHBhdGhPYmplY3Qgd2l0aCBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXQocGF0aE9iamVjdDogRm9ybWF0SW5wdXRQYXRoT2JqZWN0KTogc3RyaW5nIHtcbiAgaWYgKHBhdGhPYmplY3QgPT09IG51bGwgfHwgdHlwZW9mIHBhdGhPYmplY3QgIT09IFwib2JqZWN0XCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYFRoZSBcInBhdGhPYmplY3RcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICR7dHlwZW9mIHBhdGhPYmplY3R9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBfZm9ybWF0KFwiL1wiLCBwYXRoT2JqZWN0KTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBgUGFyc2VkUGF0aGAgb2JqZWN0IG9mIHRoZSBgcGF0aGAuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShwYXRoOiBzdHJpbmcpOiBQYXJzZWRQYXRoIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICBjb25zdCByZXQ6IFBhcnNlZFBhdGggPSB7IHJvb3Q6IFwiXCIsIGRpcjogXCJcIiwgYmFzZTogXCJcIiwgZXh0OiBcIlwiLCBuYW1lOiBcIlwiIH07XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJldDtcbiAgY29uc3QgaXNBYnNvbHV0ZSA9IHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xuICBsZXQgc3RhcnQ6IG51bWJlcjtcbiAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICByZXQucm9vdCA9IFwiL1wiO1xuICAgIHN0YXJ0ID0gMTtcbiAgfSBlbHNlIHtcbiAgICBzdGFydCA9IDA7XG4gIH1cbiAgbGV0IHN0YXJ0RG90ID0gLTE7XG4gIGxldCBzdGFydFBhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICBsZXQgaSA9IHBhdGgubGVuZ3RoIC0gMTtcblxuICAvLyBUcmFjayB0aGUgc3RhdGUgb2YgY2hhcmFjdGVycyAoaWYgYW55KSB3ZSBzZWUgYmVmb3JlIG91ciBmaXJzdCBkb3QgYW5kXG4gIC8vIGFmdGVyIGFueSBwYXRoIHNlcGFyYXRvciB3ZSBmaW5kXG4gIGxldCBwcmVEb3RTdGF0ZSA9IDA7XG5cbiAgLy8gR2V0IG5vbi1kaXIgaW5mb1xuICBmb3IgKDsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICBpZiAoZW5kICE9PSAtMSkge1xuICAgICAgaWYgKHN0YXJ0UGFydCA9PT0gMCAmJiBpc0Fic29sdXRlKSB7XG4gICAgICAgIHJldC5iYXNlID0gcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIGVuZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQuYmFzZSA9IHJldC5uYW1lID0gcGF0aC5zbGljZShzdGFydFBhcnQsIGVuZCk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChzdGFydFBhcnQgPT09IDAgJiYgaXNBYnNvbHV0ZSkge1xuICAgICAgcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIHN0YXJ0RG90KTtcbiAgICAgIHJldC5iYXNlID0gcGF0aC5zbGljZSgxLCBlbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBzdGFydERvdCk7XG4gICAgICByZXQuYmFzZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBlbmQpO1xuICAgIH1cbiAgICByZXQuZXh0ID0gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbiAgfVxuXG4gIGlmIChzdGFydFBhcnQgPiAwKSByZXQuZGlyID0gcGF0aC5zbGljZSgwLCBzdGFydFBhcnQgLSAxKTtcbiAgZWxzZSBpZiAoaXNBYnNvbHV0ZSkgcmV0LmRpciA9IFwiL1wiO1xuXG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBmaWxlIFVSTCB0byBhIHBhdGggc3RyaW5nLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IGZyb21GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgZnJvbUZpbGVVcmwoXCJmaWxlOi8vL2hvbWUvZm9vXCIpOyAvLyBcIi9ob21lL2Zvb1wiXG4gKiBgYGBcbiAqIEBwYXJhbSB1cmwgb2YgYSBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUZpbGVVcmwodXJsOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICB1cmwgPSB1cmwgaW5zdGFuY2VvZiBVUkwgPyB1cmwgOiBuZXcgVVJMKHVybCk7XG4gIGlmICh1cmwucHJvdG9jb2wgIT0gXCJmaWxlOlwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYSBmaWxlIFVSTC5cIik7XG4gIH1cbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChcbiAgICB1cmwucGF0aG5hbWUucmVwbGFjZSgvJSg/IVswLTlBLUZhLWZdezJ9KS9nLCBcIiUyNVwiKSxcbiAgKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHBhdGggc3RyaW5nIHRvIGEgZmlsZSBVUkwuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgdG9GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgdG9GaWxlVXJsKFwiL2hvbWUvZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9ob21lL2Zvb1wiKVxuICogYGBgXG4gKiBAcGFyYW0gcGF0aCB0byBjb252ZXJ0IHRvIGZpbGUgVVJMXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0ZpbGVVcmwocGF0aDogc3RyaW5nKTogVVJMIHtcbiAgaWYgKCFpc0Fic29sdXRlKHBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYW4gYWJzb2x1dGUgcGF0aC5cIik7XG4gIH1cbiAgY29uc3QgdXJsID0gbmV3IFVSTChcImZpbGU6Ly8vXCIpO1xuICB1cmwucGF0aG5hbWUgPSBlbmNvZGVXaGl0ZXNwYWNlKFxuICAgIHBhdGgucmVwbGFjZSgvJS9nLCBcIiUyNVwiKS5yZXBsYWNlKC9cXFxcL2csIFwiJTVDXCIpLFxuICApO1xuICByZXR1cm4gdXJsO1xufVxuIiwiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHsgaXNXaW5kb3dzLCBvc1R5cGUgfSBmcm9tIFwiLi4vX3V0aWwvb3MudHNcIjtcbmltcG9ydCB7IFNFUCwgU0VQX1BBVFRFUk4gfSBmcm9tIFwiLi9zZXBhcmF0b3IudHNcIjtcbmltcG9ydCAqIGFzIF93aW4zMiBmcm9tIFwiLi93aW4zMi50c1wiO1xuaW1wb3J0ICogYXMgX3Bvc2l4IGZyb20gXCIuL3Bvc2l4LnRzXCI7XG5pbXBvcnQgdHlwZSB7IE9TVHlwZSB9IGZyb20gXCIuLi9fdXRpbC9vcy50c1wiO1xuXG5jb25zdCBwYXRoID0gaXNXaW5kb3dzID8gX3dpbjMyIDogX3Bvc2l4O1xuY29uc3QgeyBqb2luLCBub3JtYWxpemUgfSA9IHBhdGg7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2xvYk9wdGlvbnMge1xuICAvKiogRXh0ZW5kZWQgZ2xvYiBzeW50YXguXG4gICAqIFNlZSBodHRwczovL3d3dy5saW51eGpvdXJuYWwuY29tL2NvbnRlbnQvYmFzaC1leHRlbmRlZC1nbG9iYmluZy4gRGVmYXVsdHNcbiAgICogdG8gdHJ1ZS4gKi9cbiAgZXh0ZW5kZWQ/OiBib29sZWFuO1xuICAvKiogR2xvYnN0YXIgc3ludGF4LlxuICAgKiBTZWUgaHR0cHM6Ly93d3cubGludXhqb3VybmFsLmNvbS9jb250ZW50L2dsb2JzdGFyLW5ldy1iYXNoLWdsb2JiaW5nLW9wdGlvbi5cbiAgICogSWYgZmFsc2UsIGAqKmAgaXMgdHJlYXRlZCBsaWtlIGAqYC4gRGVmYXVsdHMgdG8gdHJ1ZS4gKi9cbiAgZ2xvYnN0YXI/OiBib29sZWFuO1xuICAvKiogV2hldGhlciBnbG9ic3RhciBzaG91bGQgYmUgY2FzZSBpbnNlbnNpdGl2ZS4gKi9cbiAgY2FzZUluc2Vuc2l0aXZlPzogYm9vbGVhbjtcbiAgLyoqIE9wZXJhdGluZyBzeXN0ZW0uIERlZmF1bHRzIHRvIHRoZSBuYXRpdmUgT1MuICovXG4gIG9zPzogT1NUeXBlO1xufVxuXG5leHBvcnQgdHlwZSBHbG9iVG9SZWdFeHBPcHRpb25zID0gR2xvYk9wdGlvbnM7XG5cbmNvbnN0IHJlZ0V4cEVzY2FwZUNoYXJzID0gW1xuICBcIiFcIixcbiAgXCIkXCIsXG4gIFwiKFwiLFxuICBcIilcIixcbiAgXCIqXCIsXG4gIFwiK1wiLFxuICBcIi5cIixcbiAgXCI9XCIsXG4gIFwiP1wiLFxuICBcIltcIixcbiAgXCJcXFxcXCIsXG4gIFwiXlwiLFxuICBcIntcIixcbiAgXCJ8XCIsXG5dO1xuY29uc3QgcmFuZ2VFc2NhcGVDaGFycyA9IFtcIi1cIiwgXCJcXFxcXCIsIFwiXVwiXTtcblxuLyoqIENvbnZlcnQgYSBnbG9iIHN0cmluZyB0byBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAqXG4gKiBUcmllcyB0byBtYXRjaCBiYXNoIGdsb2IgZXhwYW5zaW9uIGFzIGNsb3NlbHkgYXMgcG9zc2libGUuXG4gKlxuICogQmFzaWMgZ2xvYiBzeW50YXg6XG4gKiAtIGAqYCAtIE1hdGNoZXMgZXZlcnl0aGluZyB3aXRob3V0IGxlYXZpbmcgdGhlIHBhdGggc2VnbWVudC5cbiAqIC0gYD9gIC0gTWF0Y2hlcyBhbnkgc2luZ2xlIGNoYXJhY3Rlci5cbiAqIC0gYHtmb28sYmFyfWAgLSBNYXRjaGVzIGBmb29gIG9yIGBiYXJgLlxuICogLSBgW2FiY2RdYCAtIE1hdGNoZXMgYGFgLCBgYmAsIGBjYCBvciBgZGAuXG4gKiAtIGBbYS1kXWAgLSBNYXRjaGVzIGBhYCwgYGJgLCBgY2Agb3IgYGRgLlxuICogLSBgWyFhYmNkXWAgLSBNYXRjaGVzIGFueSBzaW5nbGUgY2hhcmFjdGVyIGJlc2lkZXMgYGFgLCBgYmAsIGBjYCBvciBgZGAuXG4gKiAtIGBbWzo8Y2xhc3M+Ol1dYCAtIE1hdGNoZXMgYW55IGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gYDxjbGFzcz5gLlxuICogICAgIC0gYFtbOmFsbnVtOl1dYCAtIE1hdGNoZXMgYW55IGRpZ2l0IG9yIGxldHRlci5cbiAqICAgICAtIGBbWzpkaWdpdDpdYWJjXWAgLSBNYXRjaGVzIGFueSBkaWdpdCwgYGFgLCBgYmAgb3IgYGNgLlxuICogICAgIC0gU2VlIGh0dHBzOi8vZmFjZWxlc3N1c2VyLmdpdGh1Yi5pby93Y21hdGNoL2dsb2IvI3Bvc2l4LWNoYXJhY3Rlci1jbGFzc2VzXG4gKiAgICAgICBmb3IgYSBjb21wbGV0ZSBsaXN0IG9mIHN1cHBvcnRlZCBjaGFyYWN0ZXIgY2xhc3Nlcy5cbiAqIC0gYFxcYCAtIEVzY2FwZXMgdGhlIG5leHQgY2hhcmFjdGVyIGZvciBhbiBgb3NgIG90aGVyIHRoYW4gYFwid2luZG93c1wiYC5cbiAqIC0gXFxgIC0gRXNjYXBlcyB0aGUgbmV4dCBjaGFyYWN0ZXIgZm9yIGBvc2Agc2V0IHRvIGBcIndpbmRvd3NcImAuXG4gKiAtIGAvYCAtIFBhdGggc2VwYXJhdG9yLlxuICogLSBgXFxgIC0gQWRkaXRpb25hbCBwYXRoIHNlcGFyYXRvciBvbmx5IGZvciBgb3NgIHNldCB0byBgXCJ3aW5kb3dzXCJgLlxuICpcbiAqIEV4dGVuZGVkIHN5bnRheDpcbiAqIC0gUmVxdWlyZXMgYHsgZXh0ZW5kZWQ6IHRydWUgfWAuXG4gKiAtIGA/KGZvb3xiYXIpYCAtIE1hdGNoZXMgMCBvciAxIGluc3RhbmNlIG9mIGB7Zm9vLGJhcn1gLlxuICogLSBgQChmb298YmFyKWAgLSBNYXRjaGVzIDEgaW5zdGFuY2Ugb2YgYHtmb28sYmFyfWAuIFRoZXkgYmVoYXZlIHRoZSBzYW1lLlxuICogLSBgKihmb298YmFyKWAgLSBNYXRjaGVzIF9uXyBpbnN0YW5jZXMgb2YgYHtmb28sYmFyfWAuXG4gKiAtIGArKGZvb3xiYXIpYCAtIE1hdGNoZXMgX24gPiAwXyBpbnN0YW5jZXMgb2YgYHtmb28sYmFyfWAuXG4gKiAtIGAhKGZvb3xiYXIpYCAtIE1hdGNoZXMgYW55dGhpbmcgb3RoZXIgdGhhbiBge2ZvbyxiYXJ9YC5cbiAqIC0gU2VlIGh0dHBzOi8vd3d3LmxpbnV4am91cm5hbC5jb20vY29udGVudC9iYXNoLWV4dGVuZGVkLWdsb2JiaW5nLlxuICpcbiAqIEdsb2JzdGFyIHN5bnRheDpcbiAqIC0gUmVxdWlyZXMgYHsgZ2xvYnN0YXI6IHRydWUgfWAuXG4gKiAtIGAqKmAgLSBNYXRjaGVzIGFueSBudW1iZXIgb2YgYW55IHBhdGggc2VnbWVudHMuXG4gKiAgICAgLSBNdXN0IGNvbXByaXNlIGl0cyBlbnRpcmUgcGF0aCBzZWdtZW50IGluIHRoZSBwcm92aWRlZCBnbG9iLlxuICogLSBTZWUgaHR0cHM6Ly93d3cubGludXhqb3VybmFsLmNvbS9jb250ZW50L2dsb2JzdGFyLW5ldy1iYXNoLWdsb2JiaW5nLW9wdGlvbi5cbiAqXG4gKiBOb3RlIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqIC0gVGhlIGdlbmVyYXRlZCBgUmVnRXhwYCBpcyBhbmNob3JlZCBhdCBib3RoIHN0YXJ0IGFuZCBlbmQuXG4gKiAtIFJlcGVhdGluZyBhbmQgdHJhaWxpbmcgc2VwYXJhdG9ycyBhcmUgdG9sZXJhdGVkLiBUcmFpbGluZyBzZXBhcmF0b3JzIGluIHRoZVxuICogICBwcm92aWRlZCBnbG9iIGhhdmUgbm8gbWVhbmluZyBhbmQgYXJlIGRpc2NhcmRlZC5cbiAqIC0gQWJzb2x1dGUgZ2xvYnMgd2lsbCBvbmx5IG1hdGNoIGFic29sdXRlIHBhdGhzLCBldGMuXG4gKiAtIEVtcHR5IGdsb2JzIHdpbGwgbWF0Y2ggbm90aGluZy5cbiAqIC0gQW55IHNwZWNpYWwgZ2xvYiBzeW50YXggbXVzdCBiZSBjb250YWluZWQgdG8gb25lIHBhdGggc2VnbWVudC4gRm9yIGV4YW1wbGUsXG4gKiAgIGA/KGZvb3xiYXIvYmF6KWAgaXMgaW52YWxpZC4gVGhlIHNlcGFyYXRvciB3aWxsIHRha2UgcHJlY2VkZW5jZSBhbmQgdGhlXG4gKiAgIGZpcnN0IHNlZ21lbnQgZW5kcyB3aXRoIGFuIHVuY2xvc2VkIGdyb3VwLlxuICogLSBJZiBhIHBhdGggc2VnbWVudCBlbmRzIHdpdGggdW5jbG9zZWQgZ3JvdXBzIG9yIGEgZGFuZ2xpbmcgZXNjYXBlIHByZWZpeCwgYVxuICogICBwYXJzZSBlcnJvciBoYXMgb2NjdXJyZWQuIEV2ZXJ5IGNoYXJhY3RlciBmb3IgdGhhdCBzZWdtZW50IGlzIHRha2VuXG4gKiAgIGxpdGVyYWxseSBpbiB0aGlzIGV2ZW50LlxuICpcbiAqIExpbWl0YXRpb25zOlxuICogLSBBIG5lZ2F0aXZlIGdyb3VwIGxpa2UgYCEoZm9vfGJhcilgIHdpbGwgd3JvbmdseSBiZSBjb252ZXJ0ZWQgdG8gYSBuZWdhdGl2ZVxuICogICBsb29rLWFoZWFkIGZvbGxvd2VkIGJ5IGEgd2lsZGNhcmQuIFRoaXMgbWVhbnMgdGhhdCBgIShmb28pLmpzYCB3aWxsIHdyb25nbHlcbiAqICAgZmFpbCB0byBtYXRjaCBgZm9vYmFyLmpzYCwgZXZlbiB0aG91Z2ggYGZvb2JhcmAgaXMgbm90IGBmb29gLiBFZmZlY3RpdmVseSxcbiAqICAgYCEoZm9vfGJhcilgIGlzIHRyZWF0ZWQgbGlrZSBgIShAKGZvb3xiYXIpKilgLiBUaGlzIHdpbGwgd29yayBjb3JyZWN0bHkgaWZcbiAqICAgdGhlIGdyb3VwIG9jY3VycyBub3QgbmVzdGVkIGF0IHRoZSBlbmQgb2YgdGhlIHNlZ21lbnQuICovXG5leHBvcnQgZnVuY3Rpb24gZ2xvYlRvUmVnRXhwKFxuICBnbG9iOiBzdHJpbmcsXG4gIHtcbiAgICBleHRlbmRlZCA9IHRydWUsXG4gICAgZ2xvYnN0YXI6IGdsb2JzdGFyT3B0aW9uID0gdHJ1ZSxcbiAgICBvcyA9IG9zVHlwZSxcbiAgICBjYXNlSW5zZW5zaXRpdmUgPSBmYWxzZSxcbiAgfTogR2xvYlRvUmVnRXhwT3B0aW9ucyA9IHt9LFxuKTogUmVnRXhwIHtcbiAgaWYgKGdsb2IgPT0gXCJcIikge1xuICAgIHJldHVybiAvKD8hKS87XG4gIH1cblxuICBjb25zdCBzZXAgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiKD86XFxcXFxcXFx8LykrXCIgOiBcIi8rXCI7XG4gIGNvbnN0IHNlcE1heWJlID0gb3MgPT0gXCJ3aW5kb3dzXCIgPyBcIig/OlxcXFxcXFxcfC8pKlwiIDogXCIvKlwiO1xuICBjb25zdCBzZXBzID0gb3MgPT0gXCJ3aW5kb3dzXCIgPyBbXCJcXFxcXCIsIFwiL1wiXSA6IFtcIi9cIl07XG4gIGNvbnN0IGdsb2JzdGFyID0gb3MgPT0gXCJ3aW5kb3dzXCJcbiAgICA/IFwiKD86W15cXFxcXFxcXC9dKig/OlxcXFxcXFxcfC98JCkrKSpcIlxuICAgIDogXCIoPzpbXi9dKig/Oi98JCkrKSpcIjtcbiAgY29uc3Qgd2lsZGNhcmQgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiW15cXFxcXFxcXC9dKlwiIDogXCJbXi9dKlwiO1xuICBjb25zdCBlc2NhcGVQcmVmaXggPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiYFwiIDogXCJcXFxcXCI7XG5cbiAgLy8gUmVtb3ZlIHRyYWlsaW5nIHNlcGFyYXRvcnMuXG4gIGxldCBuZXdMZW5ndGggPSBnbG9iLmxlbmd0aDtcbiAgZm9yICg7IG5ld0xlbmd0aCA+IDEgJiYgc2Vwcy5pbmNsdWRlcyhnbG9iW25ld0xlbmd0aCAtIDFdKTsgbmV3TGVuZ3RoLS0pO1xuICBnbG9iID0gZ2xvYi5zbGljZSgwLCBuZXdMZW5ndGgpO1xuXG4gIGxldCByZWdFeHBTdHJpbmcgPSBcIlwiO1xuXG4gIC8vIFRlcm1pbmF0ZXMgY29ycmVjdGx5LiBUcnVzdCB0aGF0IGBqYCBpcyBpbmNyZW1lbnRlZCBldmVyeSBpdGVyYXRpb24uXG4gIGZvciAobGV0IGogPSAwOyBqIDwgZ2xvYi5sZW5ndGg7KSB7XG4gICAgbGV0IHNlZ21lbnQgPSBcIlwiO1xuICAgIGNvbnN0IGdyb3VwU3RhY2s6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IGluUmFuZ2UgPSBmYWxzZTtcbiAgICBsZXQgaW5Fc2NhcGUgPSBmYWxzZTtcbiAgICBsZXQgZW5kc1dpdGhTZXAgPSBmYWxzZTtcbiAgICBsZXQgaSA9IGo7XG5cbiAgICAvLyBUZXJtaW5hdGVzIHdpdGggYGlgIGF0IHRoZSBub24taW5jbHVzaXZlIGVuZCBvZiB0aGUgY3VycmVudCBzZWdtZW50LlxuICAgIGZvciAoOyBpIDwgZ2xvYi5sZW5ndGggJiYgIXNlcHMuaW5jbHVkZXMoZ2xvYltpXSk7IGkrKykge1xuICAgICAgaWYgKGluRXNjYXBlKSB7XG4gICAgICAgIGluRXNjYXBlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGVzY2FwZUNoYXJzID0gaW5SYW5nZSA/IHJhbmdlRXNjYXBlQ2hhcnMgOiByZWdFeHBFc2NhcGVDaGFycztcbiAgICAgICAgc2VnbWVudCArPSBlc2NhcGVDaGFycy5pbmNsdWRlcyhnbG9iW2ldKSA/IGBcXFxcJHtnbG9iW2ldfWAgOiBnbG9iW2ldO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gZXNjYXBlUHJlZml4KSB7XG4gICAgICAgIGluRXNjYXBlID0gdHJ1ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiW1wiKSB7XG4gICAgICAgIGlmICghaW5SYW5nZSkge1xuICAgICAgICAgIGluUmFuZ2UgPSB0cnVlO1xuICAgICAgICAgIHNlZ21lbnQgKz0gXCJbXCI7XG4gICAgICAgICAgaWYgKGdsb2JbaSArIDFdID09IFwiIVwiKSB7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgICBzZWdtZW50ICs9IFwiXlwiO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ2xvYltpICsgMV0gPT0gXCJeXCIpIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gXCJcXFxcXlwiO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIGlmIChnbG9iW2kgKyAxXSA9PSBcIjpcIikge1xuICAgICAgICAgIGxldCBrID0gaSArIDE7XG4gICAgICAgICAgbGV0IHZhbHVlID0gXCJcIjtcbiAgICAgICAgICB3aGlsZSAoZ2xvYltrICsgMV0gIT0gbnVsbCAmJiBnbG9iW2sgKyAxXSAhPSBcIjpcIikge1xuICAgICAgICAgICAgdmFsdWUgKz0gZ2xvYltrICsgMV07XG4gICAgICAgICAgICBrKys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChnbG9iW2sgKyAxXSA9PSBcIjpcIiAmJiBnbG9iW2sgKyAyXSA9PSBcIl1cIikge1xuICAgICAgICAgICAgaSA9IGsgKyAyO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiYWxudW1cIikgc2VnbWVudCArPSBcIlxcXFxkQS1aYS16XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImFscGhhXCIpIHNlZ21lbnQgKz0gXCJBLVphLXpcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiYXNjaWlcIikgc2VnbWVudCArPSBcIlxceDAwLVxceDdGXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImJsYW5rXCIpIHNlZ21lbnQgKz0gXCJcXHQgXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImNudHJsXCIpIHNlZ21lbnQgKz0gXCJcXHgwMC1cXHgxRlxceDdGXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImRpZ2l0XCIpIHNlZ21lbnQgKz0gXCJcXFxcZFwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJncmFwaFwiKSBzZWdtZW50ICs9IFwiXFx4MjEtXFx4N0VcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwibG93ZXJcIikgc2VnbWVudCArPSBcImEtelwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJwcmludFwiKSBzZWdtZW50ICs9IFwiXFx4MjAtXFx4N0VcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwicHVuY3RcIikge1xuICAgICAgICAgICAgICBzZWdtZW50ICs9IFwiIVxcXCIjJCUmJygpKissXFxcXC0uLzo7PD0+P0BbXFxcXFxcXFxcXFxcXV5f4oCYe3x9flwiO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSBcInNwYWNlXCIpIHNlZ21lbnQgKz0gXCJcXFxcc1xcdlwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJ1cHBlclwiKSBzZWdtZW50ICs9IFwiQS1aXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcIndvcmRcIikgc2VnbWVudCArPSBcIlxcXFx3XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcInhkaWdpdFwiKSBzZWdtZW50ICs9IFwiXFxcXGRBLUZhLWZcIjtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIl1cIiAmJiBpblJhbmdlKSB7XG4gICAgICAgIGluUmFuZ2UgPSBmYWxzZTtcbiAgICAgICAgc2VnbWVudCArPSBcIl1cIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpblJhbmdlKSB7XG4gICAgICAgIGlmIChnbG9iW2ldID09IFwiXFxcXFwiKSB7XG4gICAgICAgICAgc2VnbWVudCArPSBgXFxcXFxcXFxgO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlZ21lbnQgKz0gZ2xvYltpXTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBnbG9iW2ldID09IFwiKVwiICYmIGdyb3VwU3RhY2subGVuZ3RoID4gMCAmJlxuICAgICAgICBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gIT0gXCJCUkFDRVwiXG4gICAgICApIHtcbiAgICAgICAgc2VnbWVudCArPSBcIilcIjtcbiAgICAgICAgY29uc3QgdHlwZSA9IGdyb3VwU3RhY2sucG9wKCkhO1xuICAgICAgICBpZiAodHlwZSA9PSBcIiFcIikge1xuICAgICAgICAgIHNlZ21lbnQgKz0gd2lsZGNhcmQ7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSAhPSBcIkBcIikge1xuICAgICAgICAgIHNlZ21lbnQgKz0gdHlwZTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBnbG9iW2ldID09IFwifFwiICYmIGdyb3VwU3RhY2subGVuZ3RoID4gMCAmJlxuICAgICAgICBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gIT0gXCJCUkFDRVwiXG4gICAgICApIHtcbiAgICAgICAgc2VnbWVudCArPSBcInxcIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiK1wiICYmIGV4dGVuZGVkICYmIGdsb2JbaSArIDFdID09IFwiKFwiKSB7XG4gICAgICAgIGkrKztcbiAgICAgICAgZ3JvdXBTdGFjay5wdXNoKFwiK1wiKTtcbiAgICAgICAgc2VnbWVudCArPSBcIig/OlwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCJAXCIgJiYgZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCJAXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIj9cIikge1xuICAgICAgICBpZiAoZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgICAgZ3JvdXBTdGFjay5wdXNoKFwiP1wiKTtcbiAgICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VnbWVudCArPSBcIi5cIjtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIhXCIgJiYgZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCIhXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD8hXCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIntcIikge1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCJCUkFDRVwiKTtcbiAgICAgICAgc2VnbWVudCArPSBcIig/OlwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCJ9XCIgJiYgZ3JvdXBTdGFja1tncm91cFN0YWNrLmxlbmd0aCAtIDFdID09IFwiQlJBQ0VcIikge1xuICAgICAgICBncm91cFN0YWNrLnBvcCgpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKVwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIsXCIgJiYgZ3JvdXBTdGFja1tncm91cFN0YWNrLmxlbmd0aCAtIDFdID09IFwiQlJBQ0VcIikge1xuICAgICAgICBzZWdtZW50ICs9IFwifFwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIqXCIpIHtcbiAgICAgICAgaWYgKGV4dGVuZGVkICYmIGdsb2JbaSArIDFdID09IFwiKFwiKSB7XG4gICAgICAgICAgaSsrO1xuICAgICAgICAgIGdyb3VwU3RhY2sucHVzaChcIipcIik7XG4gICAgICAgICAgc2VnbWVudCArPSBcIig/OlwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHByZXZDaGFyID0gZ2xvYltpIC0gMV07XG4gICAgICAgICAgbGV0IG51bVN0YXJzID0gMTtcbiAgICAgICAgICB3aGlsZSAoZ2xvYltpICsgMV0gPT0gXCIqXCIpIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIG51bVN0YXJzKys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IG5leHRDaGFyID0gZ2xvYltpICsgMV07XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgZ2xvYnN0YXJPcHRpb24gJiYgbnVtU3RhcnMgPT0gMiAmJlxuICAgICAgICAgICAgWy4uLnNlcHMsIHVuZGVmaW5lZF0uaW5jbHVkZXMocHJldkNoYXIpICYmXG4gICAgICAgICAgICBbLi4uc2VwcywgdW5kZWZpbmVkXS5pbmNsdWRlcyhuZXh0Q2hhcilcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gZ2xvYnN0YXI7XG4gICAgICAgICAgICBlbmRzV2l0aFNlcCA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gd2lsZGNhcmQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBzZWdtZW50ICs9IHJlZ0V4cEVzY2FwZUNoYXJzLmluY2x1ZGVzKGdsb2JbaV0pID8gYFxcXFwke2dsb2JbaV19YCA6IGdsb2JbaV07XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIHVuY2xvc2VkIGdyb3VwcyBvciBhIGRhbmdsaW5nIGJhY2tzbGFzaC5cbiAgICBpZiAoZ3JvdXBTdGFjay5sZW5ndGggPiAwIHx8IGluUmFuZ2UgfHwgaW5Fc2NhcGUpIHtcbiAgICAgIC8vIFBhcnNlIGZhaWx1cmUuIFRha2UgYWxsIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHNlZ21lbnQgbGl0ZXJhbGx5LlxuICAgICAgc2VnbWVudCA9IFwiXCI7XG4gICAgICBmb3IgKGNvbnN0IGMgb2YgZ2xvYi5zbGljZShqLCBpKSkge1xuICAgICAgICBzZWdtZW50ICs9IHJlZ0V4cEVzY2FwZUNoYXJzLmluY2x1ZGVzKGMpID8gYFxcXFwke2N9YCA6IGM7XG4gICAgICAgIGVuZHNXaXRoU2VwID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVnRXhwU3RyaW5nICs9IHNlZ21lbnQ7XG4gICAgaWYgKCFlbmRzV2l0aFNlcCkge1xuICAgICAgcmVnRXhwU3RyaW5nICs9IGkgPCBnbG9iLmxlbmd0aCA/IHNlcCA6IHNlcE1heWJlO1xuICAgICAgZW5kc1dpdGhTZXAgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIFRlcm1pbmF0ZXMgd2l0aCBgaWAgYXQgdGhlIHN0YXJ0IG9mIHRoZSBuZXh0IHNlZ21lbnQuXG4gICAgd2hpbGUgKHNlcHMuaW5jbHVkZXMoZ2xvYltpXSkpIGkrKztcblxuICAgIC8vIENoZWNrIHRoYXQgdGhlIG5leHQgdmFsdWUgb2YgYGpgIGlzIGluZGVlZCBoaWdoZXIgdGhhbiB0aGUgY3VycmVudCB2YWx1ZS5cbiAgICBpZiAoIShpID4gaikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkFzc2VydGlvbiBmYWlsdXJlOiBpID4gaiAocG90ZW50aWFsIGluZmluaXRlIGxvb3ApXCIpO1xuICAgIH1cbiAgICBqID0gaTtcbiAgfVxuXG4gIHJlZ0V4cFN0cmluZyA9IGBeJHtyZWdFeHBTdHJpbmd9JGA7XG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ0V4cFN0cmluZywgY2FzZUluc2Vuc2l0aXZlID8gXCJpXCIgOiBcIlwiKTtcbn1cblxuLyoqIFRlc3Qgd2hldGhlciB0aGUgZ2l2ZW4gc3RyaW5nIGlzIGEgZ2xvYiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzR2xvYihzdHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBjaGFyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgXCJ7XCI6IFwifVwiLCBcIihcIjogXCIpXCIsIFwiW1wiOiBcIl1cIiB9O1xuICBjb25zdCByZWdleCA9XG4gICAgL1xcXFwoLil8KF4hfFxcKnxcXD98W1xcXS4rKV1cXD98XFxbW15cXFxcXFxdXStcXF18XFx7W15cXFxcfV0rXFx9fFxcKFxcP1s6IT1dW15cXFxcKV0rXFwpfFxcKFtefF0rXFx8W15cXFxcKV0rXFwpKS87XG5cbiAgaWYgKHN0ciA9PT0gXCJcIikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGxldCBtYXRjaDogUmVnRXhwRXhlY0FycmF5IHwgbnVsbDtcblxuICB3aGlsZSAoKG1hdGNoID0gcmVnZXguZXhlYyhzdHIpKSkge1xuICAgIGlmIChtYXRjaFsyXSkgcmV0dXJuIHRydWU7XG4gICAgbGV0IGlkeCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xuXG4gICAgLy8gaWYgYW4gb3BlbiBicmFja2V0L2JyYWNlL3BhcmVuIGlzIGVzY2FwZWQsXG4gICAgLy8gc2V0IHRoZSBpbmRleCB0byB0aGUgbmV4dCBjbG9zaW5nIGNoYXJhY3RlclxuICAgIGNvbnN0IG9wZW4gPSBtYXRjaFsxXTtcbiAgICBjb25zdCBjbG9zZSA9IG9wZW4gPyBjaGFyc1tvcGVuXSA6IG51bGw7XG4gICAgaWYgKG9wZW4gJiYgY2xvc2UpIHtcbiAgICAgIGNvbnN0IG4gPSBzdHIuaW5kZXhPZihjbG9zZSwgaWR4KTtcbiAgICAgIGlmIChuICE9PSAtMSkge1xuICAgICAgICBpZHggPSBuICsgMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdHIgPSBzdHIuc2xpY2UoaWR4KTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqIExpa2Ugbm9ybWFsaXplKCksIGJ1dCBkb2Vzbid0IGNvbGxhcHNlIFwiKipcXC8uLlwiIHdoZW4gYGdsb2JzdGFyYCBpcyB0cnVlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUdsb2IoXG4gIGdsb2I6IHN0cmluZyxcbiAgeyBnbG9ic3RhciA9IGZhbHNlIH06IEdsb2JPcHRpb25zID0ge30sXG4pOiBzdHJpbmcge1xuICBpZiAoZ2xvYi5tYXRjaCgvXFwwL2cpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBHbG9iIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyczogXCIke2dsb2J9XCJgKTtcbiAgfVxuICBpZiAoIWdsb2JzdGFyKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZShnbG9iKTtcbiAgfVxuICBjb25zdCBzID0gU0VQX1BBVFRFUk4uc291cmNlO1xuICBjb25zdCBiYWRQYXJlbnRQYXR0ZXJuID0gbmV3IFJlZ0V4cChcbiAgICBgKD88PSgke3N9fF4pXFxcXCpcXFxcKiR7c30pXFxcXC5cXFxcLig/PSR7c318JClgLFxuICAgIFwiZ1wiLFxuICApO1xuICByZXR1cm4gbm9ybWFsaXplKGdsb2IucmVwbGFjZShiYWRQYXJlbnRQYXR0ZXJuLCBcIlxcMFwiKSkucmVwbGFjZSgvXFwwL2csIFwiLi5cIik7XG59XG5cbi8qKiBMaWtlIGpvaW4oKSwgYnV0IGRvZXNuJ3QgY29sbGFwc2UgXCIqKlxcLy4uXCIgd2hlbiBgZ2xvYnN0YXJgIGlzIHRydWUuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbkdsb2JzKFxuICBnbG9iczogc3RyaW5nW10sXG4gIHsgZXh0ZW5kZWQgPSB0cnVlLCBnbG9ic3RhciA9IGZhbHNlIH06IEdsb2JPcHRpb25zID0ge30sXG4pOiBzdHJpbmcge1xuICBpZiAoIWdsb2JzdGFyIHx8IGdsb2JzLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIGpvaW4oLi4uZ2xvYnMpO1xuICB9XG4gIGlmIChnbG9icy5sZW5ndGggPT09IDApIHJldHVybiBcIi5cIjtcbiAgbGV0IGpvaW5lZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBmb3IgKGNvbnN0IGdsb2Igb2YgZ2xvYnMpIHtcbiAgICBjb25zdCBwYXRoID0gZ2xvYjtcbiAgICBpZiAocGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoIWpvaW5lZCkgam9pbmVkID0gcGF0aDtcbiAgICAgIGVsc2Ugam9pbmVkICs9IGAke1NFUH0ke3BhdGh9YDtcbiAgICB9XG4gIH1cbiAgaWYgKCFqb2luZWQpIHJldHVybiBcIi5cIjtcbiAgcmV0dXJuIG5vcm1hbGl6ZUdsb2Ioam9pbmVkLCB7IGV4dGVuZGVkLCBnbG9ic3RhciB9KTtcbn1cbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgdGhlIEJyb3dzZXJpZnkgYXV0aG9ycy4gTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogUG9ydGVkIG1vc3RseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbiAqIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBpc1dpbmRvd3MgfSBmcm9tIFwiLi4vX3V0aWwvb3MudHNcIjtcbmltcG9ydCAqIGFzIF93aW4zMiBmcm9tIFwiLi93aW4zMi50c1wiO1xuaW1wb3J0ICogYXMgX3Bvc2l4IGZyb20gXCIuL3Bvc2l4LnRzXCI7XG5cbmNvbnN0IHBhdGggPSBpc1dpbmRvd3MgPyBfd2luMzIgOiBfcG9zaXg7XG5cbmV4cG9ydCBjb25zdCB3aW4zMiA9IF93aW4zMjtcbmV4cG9ydCBjb25zdCBwb3NpeCA9IF9wb3NpeDtcbmV4cG9ydCBjb25zdCB7XG4gIGJhc2VuYW1lLFxuICBkZWxpbWl0ZXIsXG4gIGRpcm5hbWUsXG4gIGV4dG5hbWUsXG4gIGZvcm1hdCxcbiAgZnJvbUZpbGVVcmwsXG4gIGlzQWJzb2x1dGUsXG4gIGpvaW4sXG4gIG5vcm1hbGl6ZSxcbiAgcGFyc2UsXG4gIHJlbGF0aXZlLFxuICByZXNvbHZlLFxuICBzZXAsXG4gIHRvRmlsZVVybCxcbiAgdG9OYW1lc3BhY2VkUGF0aCxcbn0gPSBwYXRoO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jb21tb24udHNcIjtcbmV4cG9ydCB7IFNFUCwgU0VQX1BBVFRFUk4gfSBmcm9tIFwiLi9zZXBhcmF0b3IudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL19pbnRlcmZhY2UudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2dsb2IudHNcIjtcbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG5cbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCIuLi9pby9idWZmZXIudHNcIjtcblxuY29uc3QgREVGQVVMVF9DSFVOS19TSVpFID0gMTZfNjQwO1xuY29uc3QgREVGQVVMVF9CVUZGRVJfU0laRSA9IDMyICogMTAyNDtcblxuZnVuY3Rpb24gaXNDbG9zZXIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBEZW5vLkNsb3NlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT0gbnVsbCAmJiBcImNsb3NlXCIgaW4gdmFsdWUgJiZcbiAgICAvLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueVxuICAgIHR5cGVvZiAodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgYW55PilbXCJjbG9zZVwiXSA9PT0gXCJmdW5jdGlvblwiO1xufVxuXG4vKiogQ3JlYXRlIGEgYERlbm8uUmVhZGVyYCBmcm9tIGFuIGl0ZXJhYmxlIG9mIGBVaW50OEFycmF5YHMuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgcmVhZGVyRnJvbUl0ZXJhYmxlIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IERlbm8ub3BlbihcIm1ldHJpY3MudHh0XCIsIHsgd3JpdGU6IHRydWUgfSk7XG4gKiAgICAgIGNvbnN0IHJlYWRlciA9IHJlYWRlckZyb21JdGVyYWJsZSgoYXN5bmMgZnVuY3Rpb24qICgpIHtcbiAqICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICogICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpO1xuICogICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGBkYXRhOiAke0pTT04uc3RyaW5naWZ5KERlbm8ubWV0cmljcygpKX1cXG5cXG5gO1xuICogICAgICAgICAgeWllbGQgbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKG1lc3NhZ2UpO1xuICogICAgICAgIH1cbiAqICAgICAgfSkoKSk7XG4gKiAgICAgIGF3YWl0IERlbm8uY29weShyZWFkZXIsIGZpbGUpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkZXJGcm9tSXRlcmFibGUoXG4gIGl0ZXJhYmxlOiBJdGVyYWJsZTxVaW50OEFycmF5PiB8IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4sXG4pOiBEZW5vLlJlYWRlciB7XG4gIGNvbnN0IGl0ZXJhdG9yOiBJdGVyYXRvcjxVaW50OEFycmF5PiB8IEFzeW5jSXRlcmF0b3I8VWludDhBcnJheT4gPVxuICAgIChpdGVyYWJsZSBhcyBBc3luY0l0ZXJhYmxlPFVpbnQ4QXJyYXk+KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0/LigpID8/XG4gICAgICAoaXRlcmFibGUgYXMgSXRlcmFibGU8VWludDhBcnJheT4pW1N5bWJvbC5pdGVyYXRvcl0/LigpO1xuICBjb25zdCBidWZmZXIgPSBuZXcgQnVmZmVyKCk7XG4gIHJldHVybiB7XG4gICAgYXN5bmMgcmVhZChwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHJlc3VsdC52YWx1ZS5ieXRlTGVuZ3RoIDw9IHAuYnl0ZUxlbmd0aCkge1xuICAgICAgICAgICAgcC5zZXQocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudmFsdWUuYnl0ZUxlbmd0aDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcC5zZXQocmVzdWx0LnZhbHVlLnN1YmFycmF5KDAsIHAuYnl0ZUxlbmd0aCkpO1xuICAgICAgICAgIGF3YWl0IHdyaXRlQWxsKGJ1ZmZlciwgcmVzdWx0LnZhbHVlLnN1YmFycmF5KHAuYnl0ZUxlbmd0aCkpO1xuICAgICAgICAgIHJldHVybiBwLmJ5dGVMZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG4gPSBhd2FpdCBidWZmZXIucmVhZChwKTtcbiAgICAgICAgaWYgKG4gPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlYWQocCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG47XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIENyZWF0ZSBhIGBXcml0ZXJgIGZyb20gYSBgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZXJGcm9tU3RyZWFtV3JpdGVyKFxuICBzdHJlYW1Xcml0ZXI6IFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcjxVaW50OEFycmF5Pixcbik6IERlbm8uV3JpdGVyIHtcbiAgcmV0dXJuIHtcbiAgICBhc3luYyB3cml0ZShwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICAgIGF3YWl0IHN0cmVhbVdyaXRlci5yZWFkeTtcbiAgICAgIGF3YWl0IHN0cmVhbVdyaXRlci53cml0ZShwKTtcbiAgICAgIHJldHVybiBwLmxlbmd0aDtcbiAgICB9LFxuICB9O1xufVxuXG4vKiogQ3JlYXRlIGEgYFJlYWRlcmAgZnJvbSBhIGBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRlckZyb21TdHJlYW1SZWFkZXIoXG4gIHN0cmVhbVJlYWRlcjogUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyPFVpbnQ4QXJyYXk+LFxuKTogRGVuby5SZWFkZXIge1xuICBjb25zdCBidWZmZXIgPSBuZXcgQnVmZmVyKCk7XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyByZWFkKHA6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPG51bWJlciB8IG51bGw+IHtcbiAgICAgIGlmIChidWZmZXIuZW1wdHkoKSkge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBzdHJlYW1SZWFkZXIucmVhZCgpO1xuICAgICAgICBpZiAocmVzLmRvbmUpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gRU9GXG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB3cml0ZUFsbChidWZmZXIsIHJlcy52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBidWZmZXIucmVhZChwKTtcbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdyaXRhYmxlU3RyZWFtRnJvbVdyaXRlck9wdGlvbnMge1xuICAvKipcbiAgICogSWYgdGhlIGB3cml0ZXJgIGlzIGFsc28gYSBgRGVuby5DbG9zZXJgLCBhdXRvbWF0aWNhbGx5IGNsb3NlIHRoZSBgd3JpdGVyYFxuICAgKiB3aGVuIHRoZSBzdHJlYW0gaXMgY2xvc2VkLCBhYm9ydGVkLCBvciBhIHdyaXRlIGVycm9yIG9jY3Vycy5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gYHRydWVgLiAqL1xuICBhdXRvQ2xvc2U/OiBib29sZWFuO1xufVxuXG4vKiogQ3JlYXRlIGEgYFdyaXRhYmxlU3RyZWFtYCBmcm9tIGEgYFdyaXRlcmAuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGFibGVTdHJlYW1Gcm9tV3JpdGVyKFxuICB3cml0ZXI6IERlbm8uV3JpdGVyLFxuICBvcHRpb25zOiBXcml0YWJsZVN0cmVhbUZyb21Xcml0ZXJPcHRpb25zID0ge30sXG4pOiBXcml0YWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IHsgYXV0b0Nsb3NlID0gdHJ1ZSB9ID0gb3B0aW9ucztcblxuICByZXR1cm4gbmV3IFdyaXRhYmxlU3RyZWFtKHtcbiAgICBhc3luYyB3cml0ZShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd3JpdGVBbGwod3JpdGVyLCBjaHVuayk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZSk7XG4gICAgICAgIGlmIChpc0Nsb3Nlcih3cml0ZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICAgIHdyaXRlci5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBjbG9zZSgpIHtcbiAgICAgIGlmIChpc0Nsb3Nlcih3cml0ZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICB3cml0ZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFib3J0KCkge1xuICAgICAgaWYgKGlzQ2xvc2VyKHdyaXRlcikgJiYgYXV0b0Nsb3NlKSB7XG4gICAgICAgIHdyaXRlci5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKiogQ3JlYXRlIGEgYFJlYWRhYmxlU3RyZWFtYCBmcm9tIGFueSBraW5kIG9mIGl0ZXJhYmxlLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IHJlYWRhYmxlU3RyZWFtRnJvbUl0ZXJhYmxlIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqICAgICAgY29uc3QgcjEgPSByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZShbXCJmb28sIGJhciwgYmF6XCJdKTtcbiAqICAgICAgY29uc3QgcjIgPSByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZShhc3luYyBmdW5jdGlvbiogKCkge1xuICogICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKCgocikgPT4gc2V0VGltZW91dChyLCAxMDAwKSkpO1xuICogICAgICAgIHlpZWxkIFwiZm9vXCI7XG4gKiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEwMDApKSk7XG4gKiAgICAgICAgeWllbGQgXCJiYXJcIjtcbiAqICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpKTtcbiAqICAgICAgICB5aWVsZCBcImJhelwiO1xuICogICAgICB9KCkpO1xuICogYGBgXG4gKlxuICogSWYgdGhlIHByb2R1Y2VkIGl0ZXJhdG9yIChgaXRlcmFibGVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKClgIG9yXG4gKiBgaXRlcmFibGVbU3ltYm9sLml0ZXJhdG9yXSgpYCkgaXMgYSBnZW5lcmF0b3IsIG9yIG1vcmUgc3BlY2lmaWNhbGx5IGlzIGZvdW5kXG4gKiB0byBoYXZlIGEgYC50aHJvdygpYCBtZXRob2Qgb24gaXQsIHRoYXQgd2lsbCBiZSBjYWxsZWQgdXBvblxuICogYHJlYWRhYmxlU3RyZWFtLmNhbmNlbCgpYC4gVGhpcyBpcyB0aGUgY2FzZSBmb3IgdGhlIHNlY29uZCBpbnB1dCB0eXBlIGFib3ZlOlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZSB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiBjb25zdCByMyA9IHJlYWRhYmxlU3RyZWFtRnJvbUl0ZXJhYmxlKGFzeW5jIGZ1bmN0aW9uKiAoKSB7XG4gKiAgIHRyeSB7XG4gKiAgICAgeWllbGQgXCJmb29cIjtcbiAqICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmxvZyhlcnJvcik7IC8vIEVycm9yOiBDYW5jZWxsZWQgYnkgY29uc3VtZXIuXG4gKiAgIH1cbiAqIH0oKSk7XG4gKiBjb25zdCByZWFkZXIgPSByMy5nZXRSZWFkZXIoKTtcbiAqIGNvbnNvbGUubG9nKGF3YWl0IHJlYWRlci5yZWFkKCkpOyAvLyB7IHZhbHVlOiBcImZvb1wiLCBkb25lOiBmYWxzZSB9XG4gKiBhd2FpdCByZWFkZXIuY2FuY2VsKG5ldyBFcnJvcihcIkNhbmNlbGxlZCBieSBjb25zdW1lci5cIikpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZTxUPihcbiAgaXRlcmFibGU6IEl0ZXJhYmxlPFQ+IHwgQXN5bmNJdGVyYWJsZTxUPixcbik6IFJlYWRhYmxlU3RyZWFtPFQ+IHtcbiAgY29uc3QgaXRlcmF0b3I6IEl0ZXJhdG9yPFQ+IHwgQXN5bmNJdGVyYXRvcjxUPiA9XG4gICAgKGl0ZXJhYmxlIGFzIEFzeW5jSXRlcmFibGU8VD4pW1N5bWJvbC5hc3luY0l0ZXJhdG9yXT8uKCkgPz9cbiAgICAgIChpdGVyYWJsZSBhcyBJdGVyYWJsZTxUPilbU3ltYm9sLml0ZXJhdG9yXT8uKCk7XG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgIGFzeW5jIHB1bGwoY29udHJvbGxlcikge1xuICAgICAgY29uc3QgeyB2YWx1ZSwgZG9uZSB9ID0gYXdhaXQgaXRlcmF0b3IubmV4dCgpO1xuICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGNhbmNlbChyZWFzb24pIHtcbiAgICAgIGlmICh0eXBlb2YgaXRlcmF0b3IudGhyb3cgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgaXRlcmF0b3IudGhyb3cocmVhc29uKTtcbiAgICAgICAgfSBjYXRjaCB7IC8qIGBpdGVyYXRvci50aHJvdygpYCBhbHdheXMgdGhyb3dzIG9uIHNpdGUuIFdlIGNhdGNoIGl0LiAqLyB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyT3B0aW9ucyB7XG4gIC8qKiBJZiB0aGUgYHJlYWRlcmAgaXMgYWxzbyBhIGBEZW5vLkNsb3NlcmAsIGF1dG9tYXRpY2FsbHkgY2xvc2UgdGhlIGByZWFkZXJgXG4gICAqIHdoZW4gYEVPRmAgaXMgZW5jb3VudGVyZWQsIG9yIGEgcmVhZCBlcnJvciBvY2N1cnMuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIGB0cnVlYC4gKi9cbiAgYXV0b0Nsb3NlPzogYm9vbGVhbjtcblxuICAvKiogVGhlIHNpemUgb2YgY2h1bmtzIHRvIGFsbG9jYXRlIHRvIHJlYWQsIHRoZSBkZWZhdWx0IGlzIH4xNktpQiwgd2hpY2ggaXNcbiAgICogdGhlIG1heGltdW0gc2l6ZSB0aGF0IERlbm8gb3BlcmF0aW9ucyBjYW4gY3VycmVudGx5IHN1cHBvcnQuICovXG4gIGNodW5rU2l6ZT86IG51bWJlcjtcblxuICAvKiogVGhlIHF1ZXVpbmcgc3RyYXRlZ3kgdG8gY3JlYXRlIHRoZSBgUmVhZGFibGVTdHJlYW1gIHdpdGguICovXG4gIHN0cmF0ZWd5PzogeyBoaWdoV2F0ZXJNYXJrPzogbnVtYmVyIHwgdW5kZWZpbmVkOyBzaXplPzogdW5kZWZpbmVkIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgYFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+YCBmcm9tIGZyb20gYSBgRGVuby5SZWFkZXJgLlxuICpcbiAqIFdoZW4gdGhlIHB1bGwgYWxnb3JpdGhtIGlzIGNhbGxlZCBvbiB0aGUgc3RyZWFtLCBhIGNodW5rIGZyb20gdGhlIHJlYWRlclxuICogd2lsbCBiZSByZWFkLiAgV2hlbiBgbnVsbGAgaXMgcmV0dXJuZWQgZnJvbSB0aGUgcmVhZGVyLCB0aGUgc3RyZWFtIHdpbGwgYmVcbiAqIGNsb3NlZCBhbG9uZyB3aXRoIHRoZSByZWFkZXIgKGlmIGl0IGlzIGFsc28gYSBgRGVuby5DbG9zZXJgKS5cbiAqXG4gKiBBbiBleGFtcGxlIGNvbnZlcnRpbmcgYSBgRGVuby5Gc0ZpbGVgIGludG8gYSByZWFkYWJsZSBzdHJlYW06XG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlciB9IGZyb20gXCIuL21vZC50c1wiO1xuICpcbiAqIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oXCIuL2ZpbGUudHh0XCIsIHsgcmVhZDogdHJ1ZSB9KTtcbiAqIGNvbnN0IGZpbGVTdHJlYW0gPSByZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIoZmlsZSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlcihcbiAgcmVhZGVyOiBEZW5vLlJlYWRlciB8IChEZW5vLlJlYWRlciAmIERlbm8uQ2xvc2VyKSxcbiAgb3B0aW9uczogUmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyT3B0aW9ucyA9IHt9LFxuKTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICBjb25zdCB7XG4gICAgYXV0b0Nsb3NlID0gdHJ1ZSxcbiAgICBjaHVua1NpemUgPSBERUZBVUxUX0NIVU5LX1NJWkUsXG4gICAgc3RyYXRlZ3ksXG4gIH0gPSBvcHRpb25zO1xuXG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgIGFzeW5jIHB1bGwoY29udHJvbGxlcikge1xuICAgICAgY29uc3QgY2h1bmsgPSBuZXcgVWludDhBcnJheShjaHVua1NpemUpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVhZCA9IGF3YWl0IHJlYWRlci5yZWFkKGNodW5rKTtcbiAgICAgICAgaWYgKHJlYWQgPT09IG51bGwpIHtcbiAgICAgICAgICBpZiAoaXNDbG9zZXIocmVhZGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgICAgIHJlYWRlci5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuay5zdWJhcnJheSgwLCByZWFkKSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZSk7XG4gICAgICAgIGlmIChpc0Nsb3NlcihyZWFkZXIpKSB7XG4gICAgICAgICAgcmVhZGVyLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGNhbmNlbCgpIHtcbiAgICAgIGlmIChpc0Nsb3NlcihyZWFkZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICByZWFkZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuICB9LCBzdHJhdGVneSk7XG59XG5cbi8qKiBSZWFkIFJlYWRlciBgcmAgdW50aWwgRU9GIChgbnVsbGApIGFuZCByZXNvbHZlIHRvIHRoZSBjb250ZW50IGFzXG4gKiBVaW50OEFycmF5YC5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgcmVhZEFsbCB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiAvLyBFeGFtcGxlIGZyb20gc3RkaW5cbiAqIGNvbnN0IHN0ZGluQ29udGVudCA9IGF3YWl0IHJlYWRBbGwoRGVuby5zdGRpbik7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGZpbGVcbiAqIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oXCJteV9maWxlLnR4dFwiLCB7cmVhZDogdHJ1ZX0pO1xuICogY29uc3QgbXlGaWxlQ29udGVudCA9IGF3YWl0IHJlYWRBbGwoZmlsZSk7XG4gKiBEZW5vLmNsb3NlKGZpbGUucmlkKTtcbiAqXG4gKiAvLyBFeGFtcGxlIGZyb20gYnVmZmVyXG4gKiBjb25zdCBteURhdGEgPSBuZXcgVWludDhBcnJheSgxMDApO1xuICogLy8gLi4uIGZpbGwgbXlEYXRhIGFycmF5IHdpdGggZGF0YVxuICogY29uc3QgcmVhZGVyID0gbmV3IEJ1ZmZlcihteURhdGEuYnVmZmVyKTtcbiAqIGNvbnN0IGJ1ZmZlckNvbnRlbnQgPSBhd2FpdCByZWFkQWxsKHJlYWRlcik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRBbGwocjogRGVuby5SZWFkZXIpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgYnVmID0gbmV3IEJ1ZmZlcigpO1xuICBhd2FpdCBidWYucmVhZEZyb20ocik7XG4gIHJldHVybiBidWYuYnl0ZXMoKTtcbn1cblxuLyoqIFN5bmNocm9ub3VzbHkgcmVhZHMgUmVhZGVyIGByYCB1bnRpbCBFT0YgKGBudWxsYCkgYW5kIHJldHVybnMgdGhlIGNvbnRlbnRcbiAqIGFzIGBVaW50OEFycmF5YC5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgcmVhZEFsbFN5bmMgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIHN0ZGluXG4gKiBjb25zdCBzdGRpbkNvbnRlbnQgPSByZWFkQWxsU3luYyhEZW5vLnN0ZGluKTtcbiAqXG4gKiAvLyBFeGFtcGxlIGZyb20gZmlsZVxuICogY29uc3QgZmlsZSA9IERlbm8ub3BlblN5bmMoXCJteV9maWxlLnR4dFwiLCB7cmVhZDogdHJ1ZX0pO1xuICogY29uc3QgbXlGaWxlQ29udGVudCA9IHJlYWRBbGxTeW5jKGZpbGUpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGJ1ZmZlclxuICogY29uc3QgbXlEYXRhID0gbmV3IFVpbnQ4QXJyYXkoMTAwKTtcbiAqIC8vIC4uLiBmaWxsIG15RGF0YSBhcnJheSB3aXRoIGRhdGFcbiAqIGNvbnN0IHJlYWRlciA9IG5ldyBCdWZmZXIobXlEYXRhLmJ1ZmZlcik7XG4gKiBjb25zdCBidWZmZXJDb250ZW50ID0gcmVhZEFsbFN5bmMocmVhZGVyKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEFsbFN5bmMocjogRGVuby5SZWFkZXJTeW5jKTogVWludDhBcnJheSB7XG4gIGNvbnN0IGJ1ZiA9IG5ldyBCdWZmZXIoKTtcbiAgYnVmLnJlYWRGcm9tU3luYyhyKTtcbiAgcmV0dXJuIGJ1Zi5ieXRlcygpO1xufVxuXG4vKiogV3JpdGUgYWxsIHRoZSBjb250ZW50IG9mIHRoZSBhcnJheSBidWZmZXIgKGBhcnJgKSB0byB0aGUgd3JpdGVyIChgd2ApLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBCdWZmZXIgfSBmcm9tIFwiLi4vaW8vYnVmZmVyLnRzXCI7XG4gKiBpbXBvcnQgeyB3cml0ZUFsbCB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcblxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIHN0ZG91dFxuICogbGV0IGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogYXdhaXQgd3JpdGVBbGwoRGVuby5zdGRvdXQsIGNvbnRlbnRCeXRlcyk7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIGZpbGVcbiAqIGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogY29uc3QgZmlsZSA9IGF3YWl0IERlbm8ub3BlbigndGVzdC5maWxlJywge3dyaXRlOiB0cnVlfSk7XG4gKiBhd2FpdCB3cml0ZUFsbChmaWxlLCBjb250ZW50Qnl0ZXMpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIGJ1ZmZlclxuICogY29udGVudEJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFwiSGVsbG8gV29ybGRcIik7XG4gKiBjb25zdCB3cml0ZXIgPSBuZXcgQnVmZmVyKCk7XG4gKiBhd2FpdCB3cml0ZUFsbCh3cml0ZXIsIGNvbnRlbnRCeXRlcyk7XG4gKiBjb25zb2xlLmxvZyh3cml0ZXIuYnl0ZXMoKS5sZW5ndGgpOyAgLy8gMTFcbiAqIGBgYFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVBbGwodzogRGVuby5Xcml0ZXIsIGFycjogVWludDhBcnJheSkge1xuICBsZXQgbndyaXR0ZW4gPSAwO1xuICB3aGlsZSAobndyaXR0ZW4gPCBhcnIubGVuZ3RoKSB7XG4gICAgbndyaXR0ZW4gKz0gYXdhaXQgdy53cml0ZShhcnIuc3ViYXJyYXkobndyaXR0ZW4pKTtcbiAgfVxufVxuXG4vKiogU3luY2hyb25vdXNseSB3cml0ZSBhbGwgdGhlIGNvbnRlbnQgb2YgdGhlIGFycmF5IGJ1ZmZlciAoYGFycmApIHRvIHRoZVxuICogd3JpdGVyIChgd2ApLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBCdWZmZXIgfSBmcm9tIFwiLi4vaW8vYnVmZmVyLnRzXCI7XG4gKiBpbXBvcnQgeyB3cml0ZUFsbFN5bmMgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIHN0ZG91dFxuICogbGV0IGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogd3JpdGVBbGxTeW5jKERlbm8uc3Rkb3V0LCBjb250ZW50Qnl0ZXMpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBmaWxlXG4gKiBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIGNvbnN0IGZpbGUgPSBEZW5vLm9wZW5TeW5jKCd0ZXN0LmZpbGUnLCB7d3JpdGU6IHRydWV9KTtcbiAqIHdyaXRlQWxsU3luYyhmaWxlLCBjb250ZW50Qnl0ZXMpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIGJ1ZmZlclxuICogY29udGVudEJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFwiSGVsbG8gV29ybGRcIik7XG4gKiBjb25zdCB3cml0ZXIgPSBuZXcgQnVmZmVyKCk7XG4gKiB3cml0ZUFsbFN5bmMod3JpdGVyLCBjb250ZW50Qnl0ZXMpO1xuICogY29uc29sZS5sb2cod3JpdGVyLmJ5dGVzKCkubGVuZ3RoKTsgIC8vIDExXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlQWxsU3luYyh3OiBEZW5vLldyaXRlclN5bmMsIGFycjogVWludDhBcnJheSk6IHZvaWQge1xuICBsZXQgbndyaXR0ZW4gPSAwO1xuICB3aGlsZSAobndyaXR0ZW4gPCBhcnIubGVuZ3RoKSB7XG4gICAgbndyaXR0ZW4gKz0gdy53cml0ZVN5bmMoYXJyLnN1YmFycmF5KG53cml0dGVuKSk7XG4gIH1cbn1cblxuLyoqIFR1cm5zIGEgUmVhZGVyLCBgcmAsIGludG8gYW4gYXN5bmMgaXRlcmF0b3IuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGl0ZXJhdGVSZWFkZXIgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogbGV0IGYgPSBhd2FpdCBEZW5vLm9wZW4oXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgaXRlcmF0ZVJlYWRlcihmKSkge1xuICogICBjb25zb2xlLmxvZyhjaHVuayk7XG4gKiB9XG4gKiBmLmNsb3NlKCk7XG4gKiBgYGBcbiAqXG4gKiBTZWNvbmQgYXJndW1lbnQgY2FuIGJlIHVzZWQgdG8gdHVuZSBzaXplIG9mIGEgYnVmZmVyLlxuICogRGVmYXVsdCBzaXplIG9mIHRoZSBidWZmZXIgaXMgMzJrQi5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgaXRlcmF0ZVJlYWRlciB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiBsZXQgZiA9IGF3YWl0IERlbm8ub3BlbihcIi9ldGMvcGFzc3dkXCIpO1xuICogY29uc3QgaXQgPSBpdGVyYXRlUmVhZGVyKGYsIHtcbiAqICAgYnVmU2l6ZTogMTAyNCAqIDEwMjRcbiAqIH0pO1xuICogZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiBpdCkge1xuICogICBjb25zb2xlLmxvZyhjaHVuayk7XG4gKiB9XG4gKiBmLmNsb3NlKCk7XG4gKiBgYGBcbiAqXG4gKiBJdGVyYXRvciB1c2VzIGFuIGludGVybmFsIGJ1ZmZlciBvZiBmaXhlZCBzaXplIGZvciBlZmZpY2llbmN5OyBpdCByZXR1cm5zXG4gKiBhIHZpZXcgb24gdGhhdCBidWZmZXIgb24gZWFjaCBpdGVyYXRpb24uIEl0IGlzIHRoZXJlZm9yZSBjYWxsZXInc1xuICogcmVzcG9uc2liaWxpdHkgdG8gY29weSBjb250ZW50cyBvZiB0aGUgYnVmZmVyIGlmIG5lZWRlZDsgb3RoZXJ3aXNlIHRoZVxuICogbmV4dCBpdGVyYXRpb24gd2lsbCBvdmVyd3JpdGUgY29udGVudHMgb2YgcHJldmlvdXNseSByZXR1cm5lZCBjaHVuay5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uKiBpdGVyYXRlUmVhZGVyKFxuICByOiBEZW5vLlJlYWRlcixcbiAgb3B0aW9ucz86IHtcbiAgICBidWZTaXplPzogbnVtYmVyO1xuICB9LFxuKTogQXN5bmNJdGVyYWJsZUl0ZXJhdG9yPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgYnVmU2l6ZSA9IG9wdGlvbnM/LmJ1ZlNpemUgPz8gREVGQVVMVF9CVUZGRVJfU0laRTtcbiAgY29uc3QgYiA9IG5ldyBVaW50OEFycmF5KGJ1ZlNpemUpO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHIucmVhZChiKTtcbiAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB5aWVsZCBiLnN1YmFycmF5KDAsIHJlc3VsdCk7XG4gIH1cbn1cblxuLyoqIFR1cm5zIGEgUmVhZGVyU3luYywgYHJgLCBpbnRvIGFuIGl0ZXJhdG9yLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpdGVyYXRlUmVhZGVyU3luYyB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiBsZXQgZiA9IERlbm8ub3BlblN5bmMoXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGZvciAoY29uc3QgY2h1bmsgb2YgaXRlcmF0ZVJlYWRlclN5bmMoZikpIHtcbiAqICAgY29uc29sZS5sb2coY2h1bmspO1xuICogfVxuICogZi5jbG9zZSgpO1xuICogYGBgXG4gKlxuICogU2Vjb25kIGFyZ3VtZW50IGNhbiBiZSB1c2VkIHRvIHR1bmUgc2l6ZSBvZiBhIGJ1ZmZlci5cbiAqIERlZmF1bHQgc2l6ZSBvZiB0aGUgYnVmZmVyIGlzIDMya0IuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGl0ZXJhdGVSZWFkZXJTeW5jIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuXG4gKiBsZXQgZiA9IGF3YWl0IERlbm8ub3BlbihcIi9ldGMvcGFzc3dkXCIpO1xuICogY29uc3QgaXRlciA9IGl0ZXJhdGVSZWFkZXJTeW5jKGYsIHtcbiAqICAgYnVmU2l6ZTogMTAyNCAqIDEwMjRcbiAqIH0pO1xuICogZm9yIChjb25zdCBjaHVuayBvZiBpdGVyKSB7XG4gKiAgIGNvbnNvbGUubG9nKGNodW5rKTtcbiAqIH1cbiAqIGYuY2xvc2UoKTtcbiAqIGBgYFxuICpcbiAqIEl0ZXJhdG9yIHVzZXMgYW4gaW50ZXJuYWwgYnVmZmVyIG9mIGZpeGVkIHNpemUgZm9yIGVmZmljaWVuY3k7IGl0IHJldHVybnNcbiAqIGEgdmlldyBvbiB0aGF0IGJ1ZmZlciBvbiBlYWNoIGl0ZXJhdGlvbi4gSXQgaXMgdGhlcmVmb3JlIGNhbGxlcidzXG4gKiByZXNwb25zaWJpbGl0eSB0byBjb3B5IGNvbnRlbnRzIG9mIHRoZSBidWZmZXIgaWYgbmVlZGVkOyBvdGhlcndpc2UgdGhlXG4gKiBuZXh0IGl0ZXJhdGlvbiB3aWxsIG92ZXJ3cml0ZSBjb250ZW50cyBvZiBwcmV2aW91c2x5IHJldHVybmVkIGNodW5rLlxuICovXG5leHBvcnQgZnVuY3Rpb24qIGl0ZXJhdGVSZWFkZXJTeW5jKFxuICByOiBEZW5vLlJlYWRlclN5bmMsXG4gIG9wdGlvbnM/OiB7XG4gICAgYnVmU2l6ZT86IG51bWJlcjtcbiAgfSxcbik6IEl0ZXJhYmxlSXRlcmF0b3I8VWludDhBcnJheT4ge1xuICBjb25zdCBidWZTaXplID0gb3B0aW9ucz8uYnVmU2l6ZSA/PyBERUZBVUxUX0JVRkZFUl9TSVpFO1xuICBjb25zdCBiID0gbmV3IFVpbnQ4QXJyYXkoYnVmU2l6ZSk7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gci5yZWFkU3luYyhiKTtcbiAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB5aWVsZCBiLnN1YmFycmF5KDAsIHJlc3VsdCk7XG4gIH1cbn1cblxuLyoqIENvcGllcyBmcm9tIGBzcmNgIHRvIGBkc3RgIHVudGlsIGVpdGhlciBFT0YgKGBudWxsYCkgaXMgcmVhZCBmcm9tIGBzcmNgIG9yXG4gKiBhbiBlcnJvciBvY2N1cnMuIEl0IHJlc29sdmVzIHRvIHRoZSBudW1iZXIgb2YgYnl0ZXMgY29waWVkIG9yIHJlamVjdHMgd2l0aFxuICogdGhlIGZpcnN0IGVycm9yIGVuY291bnRlcmVkIHdoaWxlIGNvcHlpbmcuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGNvcHkgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogY29uc3Qgc291cmNlID0gYXdhaXQgRGVuby5vcGVuKFwibXlfZmlsZS50eHRcIik7XG4gKiBjb25zdCBieXRlc0NvcGllZDEgPSBhd2FpdCBjb3B5KHNvdXJjZSwgRGVuby5zdGRvdXQpO1xuICogY29uc3QgZGVzdGluYXRpb24gPSBhd2FpdCBEZW5vLmNyZWF0ZShcIm15X2ZpbGVfMi50eHRcIik7XG4gKiBjb25zdCBieXRlc0NvcGllZDIgPSBhd2FpdCBjb3B5KHNvdXJjZSwgZGVzdGluYXRpb24pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHNyYyBUaGUgc291cmNlIHRvIGNvcHkgZnJvbVxuICogQHBhcmFtIGRzdCBUaGUgZGVzdGluYXRpb24gdG8gY29weSB0b1xuICogQHBhcmFtIG9wdGlvbnMgQ2FuIGJlIHVzZWQgdG8gdHVuZSBzaXplIG9mIHRoZSBidWZmZXIuIERlZmF1bHQgc2l6ZSBpcyAzMmtCXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3B5KFxuICBzcmM6IERlbm8uUmVhZGVyLFxuICBkc3Q6IERlbm8uV3JpdGVyLFxuICBvcHRpb25zPzoge1xuICAgIGJ1ZlNpemU/OiBudW1iZXI7XG4gIH0sXG4pOiBQcm9taXNlPG51bWJlcj4ge1xuICBsZXQgbiA9IDA7XG4gIGNvbnN0IGJ1ZlNpemUgPSBvcHRpb25zPy5idWZTaXplID8/IERFRkFVTFRfQlVGRkVSX1NJWkU7XG4gIGNvbnN0IGIgPSBuZXcgVWludDhBcnJheShidWZTaXplKTtcbiAgbGV0IGdvdEVPRiA9IGZhbHNlO1xuICB3aGlsZSAoZ290RU9GID09PSBmYWxzZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNyYy5yZWFkKGIpO1xuICAgIGlmIChyZXN1bHQgPT09IG51bGwpIHtcbiAgICAgIGdvdEVPRiA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBud3JpdHRlbiA9IDA7XG4gICAgICB3aGlsZSAobndyaXR0ZW4gPCByZXN1bHQpIHtcbiAgICAgICAgbndyaXR0ZW4gKz0gYXdhaXQgZHN0LndyaXRlKGIuc3ViYXJyYXkobndyaXR0ZW4sIHJlc3VsdCkpO1xuICAgICAgfVxuICAgICAgbiArPSBud3JpdHRlbjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG47XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuaW1wb3J0IHsgZnJvbUZpbGVVcmwgfSBmcm9tIFwiLi4vLi4vcGF0aC9tb2QudHNcIjtcbmltcG9ydCB7IHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlciB9IGZyb20gXCIuLi8uLi9zdHJlYW1zL2NvbnZlcnNpb24udHNcIjtcblxuY29uc3QgY2xpZW50cyA9IG5ldyBNYXA8bnVtYmVyLCBXZWJTb2NrZXQ+KCk7XG5sZXQgY2xpZW50SWQgPSAwO1xuZnVuY3Rpb24gZGlzcGF0Y2gobXNnOiBzdHJpbmcpOiB2b2lkIHtcbiAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cy52YWx1ZXMoKSkge1xuICAgIGNsaWVudC5zZW5kKG1zZyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gd3NIYW5kbGVyKHdzOiBXZWJTb2NrZXQpIHtcbiAgY29uc3QgaWQgPSArK2NsaWVudElkO1xuICBjbGllbnRzLnNldChpZCwgd3MpO1xuICB3cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgZGlzcGF0Y2goYENvbm5lY3RlZDogWyR7aWR9XWApO1xuICB9O1xuICB3cy5vbm1lc3NhZ2UgPSAoZSkgPT4ge1xuICAgIGNvbnNvbGUubG9nKGBtc2c6JHtpZH1gLCBlLmRhdGEpO1xuICAgIGRpc3BhdGNoKGBbJHtpZH1dOiAke2UuZGF0YX1gKTtcbiAgfTtcbiAgd3Mub25jbG9zZSA9ICgpID0+IHtcbiAgICBjbGllbnRzLmRlbGV0ZShpZCk7XG4gICAgZGlzcGF0Y2goYENsb3NlZDogWyR7aWR9XWApO1xuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXF1ZXN0SGFuZGxlcihyZXE6IERlbm8uUmVxdWVzdEV2ZW50KSB7XG4gIGNvbnN0IHBhdGhuYW1lID0gbmV3IFVSTChyZXEucmVxdWVzdC51cmwpLnBhdGhuYW1lO1xuICBpZiAocmVxLnJlcXVlc3QubWV0aG9kID09PSBcIkdFVFwiICYmIHBhdGhuYW1lID09PSBcIi9cIikge1xuICAgIC8vU2VydmUgd2l0aCBoYWNrXG4gICAgY29uc3QgdSA9IG5ldyBVUkwoXCIuL2luZGV4Lmh0bWxcIiwgaW1wb3J0Lm1ldGEudXJsKTtcbiAgICBpZiAodS5wcm90b2NvbC5zdGFydHNXaXRoKFwiaHR0cFwiKSkge1xuICAgICAgLy8gc2VydmVyIGxhdW5jaGVkIGJ5IGRlbm8gcnVuIGh0dHAocyk6Ly8uLi4vc2VydmVyLnRzLFxuICAgICAgZmV0Y2godS5ocmVmKS50aGVuKGFzeW5jIChyZXNwKSA9PiB7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBuZXcgVWludDhBcnJheShhd2FpdCByZXNwLmFycmF5QnVmZmVyKCkpO1xuICAgICAgICByZXEucmVzcG9uZFdpdGgoXG4gICAgICAgICAgbmV3IFJlc3BvbnNlKGJvZHksIHtcbiAgICAgICAgICAgIHN0YXR1czogcmVzcC5zdGF0dXMsXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgIFwiY29udGVudC10eXBlXCI6IFwidGV4dC9odG1sXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHNlcnZlciBsYXVuY2hlZCBieSBkZW5vIHJ1biAuL3NlcnZlci50c1xuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IERlbm8ub3Blbihmcm9tRmlsZVVybCh1KSk7XG4gICAgICByZXEucmVzcG9uZFdpdGgoXG4gICAgICAgIG5ldyBSZXNwb25zZShyZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIoZmlsZSksIHtcbiAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICBcImNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoXG4gICAgcmVxLnJlcXVlc3QubWV0aG9kID09PSBcIkdFVFwiICYmIHBhdGhuYW1lID09PSBcIi9mYXZpY29uLmljb1wiXG4gICkge1xuICAgIHJlcS5yZXNwb25kV2l0aChSZXNwb25zZS5yZWRpcmVjdChcImh0dHBzOi8vZGVuby5sYW5kL2Zhdmljb24uaWNvXCIsIDMwMikpO1xuICB9IGVsc2UgaWYgKHJlcS5yZXF1ZXN0Lm1ldGhvZCA9PT0gXCJHRVRcIiAmJiBwYXRobmFtZSA9PT0gXCIvd3NcIikge1xuICAgIGNvbnN0IHsgc29ja2V0LCByZXNwb25zZSB9ID0gRGVuby51cGdyYWRlV2ViU29ja2V0KHJlcS5yZXF1ZXN0KTtcbiAgICB3c0hhbmRsZXIoc29ja2V0KTtcbiAgICByZXEucmVzcG9uZFdpdGgocmVzcG9uc2UpO1xuICB9XG59XG5cbmNvbnN0IHNlcnZlciA9IERlbm8ubGlzdGVuKHsgcG9ydDogODA4MCB9KTtcbmNvbnNvbGUubG9nKFwiY2hhdCBzZXJ2ZXIgc3RhcnRpbmcgb24gOjgwODAuLi4uXCIpO1xuXG5mb3IgYXdhaXQgKGNvbnN0IGNvbm4gb2Ygc2VydmVyKSB7XG4gIChhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaHR0cENvbm4gPSBEZW5vLnNlcnZlSHR0cChjb25uKTtcbiAgICBmb3IgYXdhaXQgKGNvbnN0IHJlcXVlc3RFdmVudCBvZiBodHRwQ29ubikge1xuICAgICAgcmVxdWVzdEhhbmRsZXIocmVxdWVzdEV2ZW50KTtcbiAgICB9XG4gIH0pKCk7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS08sTUFBTSxTQUFpQixBQUFDLENBQUEsSUFBTTtJQUVuQyxNQUFNLEVBQUUsTUFBQSxNQUFJLEVBQUUsR0FBRztJQUNqQixJ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 diff --git a/tests/__snapshots__/bundle/source.js b/tests/__snapshots__/bundle/source.js new file mode 100644 index 0000000..6bad4f6 --- /dev/null +++ b/tests/__snapshots__/bundle/source.js @@ -0,0 +1,5 @@ +function hello() { + return "Hello there!"; +} +export { hello as default }; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vc3JjLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGhlbGxvKCk6IHN0cmluZyB7XG4gIHJldHVybiBcIkhlbGxvIHRoZXJlIVwiO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFlLFNBQVMsUUFBZ0I7SUFDdEMsT0FBTztBQUNUO0FBRkEsNEJBRUMifQ== diff --git a/tests/__snapshots__/bundle/url.js b/tests/__snapshots__/bundle/url.js new file mode 100644 index 0000000..d0b5685 --- /dev/null +++ b/tests/__snapshots__/bundle/url.js @@ -0,0 +1,1185 @@ +const osType = (()=>{ + const { Deno: Deno1 } = globalThis; + if (typeof Deno1?.build?.os === "string") { + return Deno1.build.os; + } + const { navigator } = globalThis; + if (navigator?.appVersion?.includes?.("Win")) { + return "windows"; + } + return "linux"; +})(); +const isWindows = osType === "windows"; +const CHAR_FORWARD_SLASH = 47; +function assertPath(path) { + if (typeof path !== "string") { + throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`); + } +} +function isPosixPathSeparator(code) { + return code === 47; +} +function isPathSeparator(code) { + return isPosixPathSeparator(code) || code === 92; +} +function isWindowsDeviceRoot(code) { + return code >= 97 && code <= 122 || code >= 65 && code <= 90; +} +function normalizeString(path, allowAboveRoot, separator, isPathSeparator) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let code; + for(let i = 0, len = path.length; i <= len; ++i){ + if (i < len) code = path.charCodeAt(i); + else if (isPathSeparator(code)) break; + else code = CHAR_FORWARD_SLASH; + if (isPathSeparator(code)) { + if (lastSlash === i - 1 || dots === 1) {} else if (lastSlash !== i - 1 && dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf(separator); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); + } + lastSlash = i; + dots = 0; + continue; + } else if (res.length === 2 || res.length === 1) { + res = ""; + lastSegmentLength = 0; + lastSlash = i; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + if (res.length > 0) res += `${separator}..`; + else res = ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) res += separator + path.slice(lastSlash + 1, i); + else res = path.slice(lastSlash + 1, i); + lastSegmentLength = i - lastSlash - 1; + } + lastSlash = i; + dots = 0; + } else if (code === 46 && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +function _format(sep, pathObject) { + const dir = pathObject.dir || pathObject.root; + const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); + if (!dir) return base; + if (dir === pathObject.root) return dir + base; + return dir + sep + base; +} +const WHITESPACE_ENCODINGS = { + "\u0009": "%09", + "\u000A": "%0A", + "\u000B": "%0B", + "\u000C": "%0C", + "\u000D": "%0D", + "\u0020": "%20" +}; +function encodeWhitespace(string) { + return string.replaceAll(/[\s]/g, (c)=>{ + return WHITESPACE_ENCODINGS[c] ?? c; + }); +} +class DenoStdInternalError extends Error { + constructor(message){ + super(message); + this.name = "DenoStdInternalError"; + } +} +function assert(expr, msg = "") { + if (!expr) { + throw new DenoStdInternalError(msg); + } +} +const sep = "\\"; +const delimiter = ";"; +function resolve(...pathSegments) { + let resolvedDevice = ""; + let resolvedTail = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1; i--){ + let path; + const { Deno: Deno1 } = globalThis; + if (i >= 0) { + path = pathSegments[i]; + } else if (!resolvedDevice) { + if (typeof Deno1?.cwd !== "function") { + throw new TypeError("Resolved a drive-letter-less path without a CWD."); + } + path = Deno1.cwd(); + } else { + if (typeof Deno1?.env?.get !== "function" || typeof Deno1?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno1.cwd(); + if (path === undefined || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) { + path = `${resolvedDevice}\\`; + } + } + assertPath(path); + const len = path.length; + if (len === 0) continue; + let rootEnd = 0; + let device = ""; + let isAbsolute = false; + const code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + device = `\\\\${firstPart}\\${path.slice(last)}`; + rootEnd = j; + } else if (j !== last) { + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + rootEnd = 1; + isAbsolute = true; + } + if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) { + continue; + } + if (resolvedDevice.length === 0 && device.length > 0) { + resolvedDevice = device; + } + if (!resolvedAbsolute) { + resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`; + resolvedAbsolute = isAbsolute; + } + if (resolvedAbsolute && resolvedDevice.length > 0) break; + } + resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator); + return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || "."; +} +function normalize(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = 0; + let device; + let isAbsolute = false; + const code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + return `\\\\${firstPart}\\${path.slice(last)}\\`; + } else if (j !== last) { + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + return "\\"; + } + let tail; + if (rootEnd < len) { + tail = normalizeString(path.slice(rootEnd), !isAbsolute, "\\", isPathSeparator); + } else { + tail = ""; + } + if (tail.length === 0 && !isAbsolute) tail = "."; + if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) { + tail += "\\"; + } + if (device === undefined) { + if (isAbsolute) { + if (tail.length > 0) return `\\${tail}`; + else return "\\"; + } else if (tail.length > 0) { + return tail; + } else { + return ""; + } + } else if (isAbsolute) { + if (tail.length > 0) return `${device}\\${tail}`; + else return `${device}\\`; + } else if (tail.length > 0) { + return device + tail; + } else { + return device; + } +} +function isAbsolute(path) { + assertPath(path); + const len = path.length; + if (len === 0) return false; + const code = path.charCodeAt(0); + if (isPathSeparator(code)) { + return true; + } else if (isWindowsDeviceRoot(code)) { + if (len > 2 && path.charCodeAt(1) === 58) { + if (isPathSeparator(path.charCodeAt(2))) return true; + } + } + return false; +} +function join(...paths) { + const pathsCount = paths.length; + if (pathsCount === 0) return "."; + let joined; + let firstPart = null; + for(let i = 0; i < pathsCount; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (joined === undefined) joined = firstPart = path; + else joined += `\\${path}`; + } + } + if (joined === undefined) return "."; + let needsReplace = true; + let slashCount = 0; + assert(firstPart != null); + if (isPathSeparator(firstPart.charCodeAt(0))) { + ++slashCount; + const firstLen = firstPart.length; + if (firstLen > 1) { + if (isPathSeparator(firstPart.charCodeAt(1))) { + ++slashCount; + if (firstLen > 2) { + if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount; + else { + needsReplace = false; + } + } + } + } + } + if (needsReplace) { + for(; slashCount < joined.length; ++slashCount){ + if (!isPathSeparator(joined.charCodeAt(slashCount))) break; + } + if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`; + } + return normalize(joined); +} +function relative(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + const fromOrig = resolve(from); + const toOrig = resolve(to); + if (fromOrig === toOrig) return ""; + from = fromOrig.toLowerCase(); + to = toOrig.toLowerCase(); + if (from === to) return ""; + let fromStart = 0; + let fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== 92) break; + } + for(; fromEnd - 1 > fromStart; --fromEnd){ + if (from.charCodeAt(fromEnd - 1) !== 92) break; + } + const fromLen = fromEnd - fromStart; + let toStart = 0; + let toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== 92) break; + } + for(; toEnd - 1 > toStart; --toEnd){ + if (to.charCodeAt(toEnd - 1) !== 92) break; + } + const toLen = toEnd - toStart; + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === 92) { + return toOrig.slice(toStart + i + 1); + } else if (i === 2) { + return toOrig.slice(toStart + i); + } + } + if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === 92) { + lastCommonSep = i; + } else if (i === 2) { + lastCommonSep = 3; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === 92) lastCommonSep = i; + } + if (i !== length && lastCommonSep === -1) { + return toOrig; + } + let out = ""; + if (lastCommonSep === -1) lastCommonSep = 0; + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === 92) { + if (out.length === 0) out += ".."; + else out += "\\.."; + } + } + if (out.length > 0) { + return out + toOrig.slice(toStart + lastCommonSep, toEnd); + } else { + toStart += lastCommonSep; + if (toOrig.charCodeAt(toStart) === 92) ++toStart; + return toOrig.slice(toStart, toEnd); + } +} +function toNamespacedPath(path) { + if (typeof path !== "string") return path; + if (path.length === 0) return ""; + const resolvedPath = resolve(path); + if (resolvedPath.length >= 3) { + if (resolvedPath.charCodeAt(0) === 92) { + if (resolvedPath.charCodeAt(1) === 92) { + const code = resolvedPath.charCodeAt(2); + if (code !== 63 && code !== 46) { + return `\\\\?\\UNC\\${resolvedPath.slice(2)}`; + } + } + } else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) { + if (resolvedPath.charCodeAt(1) === 58 && resolvedPath.charCodeAt(2) === 92) { + return `\\\\?\\${resolvedPath}`; + } + } + } + return path; +} +function dirname(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = -1; + let end = -1; + let matchedSlash = true; + let offset = 0; + const code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + rootEnd = offset = 1; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + return path; + } + if (j !== last) { + rootEnd = offset = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + rootEnd = offset = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3; + } + } + } + } else if (isPathSeparator(code)) { + return path; + } + for(let i = len - 1; i >= offset; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + if (!matchedSlash) { + end = i; + break; + } + } else { + matchedSlash = false; + } + } + if (end === -1) { + if (rootEnd === -1) return "."; + else end = rootEnd; + } + return path.slice(0, end); +} +function basename(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + if (path.length >= 2) { + const drive = path.charCodeAt(0); + if (isWindowsDeviceRoot(drive)) { + if (path.charCodeAt(1) === 58) start = 2; + } + } + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + end = i; + } + } else { + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= start; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +function extname(path) { + assertPath(path); + let start = 0; + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let preDotState = 0; + if (path.length >= 2 && path.charCodeAt(1) === 58 && isWindowsDeviceRoot(path.charCodeAt(0))) { + start = startPart = 2; + } + for(let i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +function format(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("\\", pathObject); +} +function parse(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + const len = path.length; + if (len === 0) return ret; + let rootEnd = 0; + let code = path.charCodeAt(0); + if (len > 1) { + if (isPathSeparator(code)) { + rootEnd = 1; + if (isPathSeparator(path.charCodeAt(1))) { + let j = 2; + let last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + last = j; + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + rootEnd = j; + } else if (j !== last) { + rootEnd = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + if (path.charCodeAt(1) === 58) { + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + if (len === 3) { + ret.root = ret.dir = path; + return ret; + } + rootEnd = 3; + } + } else { + ret.root = ret.dir = path; + return ret; + } + } + } + } else if (isPathSeparator(code)) { + ret.root = ret.dir = path; + return ret; + } + if (rootEnd > 0) ret.root = path.slice(0, rootEnd); + let startDot = -1; + let startPart = rootEnd; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + let preDotState = 0; + for(; i >= rootEnd; --i){ + code = path.charCodeAt(i); + if (isPathSeparator(code)) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + ret.base = ret.name = path.slice(startPart, end); + } + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + ret.ext = path.slice(startDot, end); + } + if (startPart > 0 && startPart !== rootEnd) { + ret.dir = path.slice(0, startPart - 1); + } else ret.dir = ret.root; + return ret; +} +function fromFileUrl(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\"); + if (url.hostname != "") { + path = `\\\\${url.hostname}${path}`; + } + return path; +} +function toFileUrl(path) { + if (!isAbsolute(path)) { + throw new TypeError("Must be an absolute path."); + } + const [, hostname, pathname] = path.match(/^(?:[/\\]{2}([^/\\]+)(?=[/\\](?:[^/\\]|$)))?(.*)/); + const url = new URL("file:///"); + url.pathname = encodeWhitespace(pathname.replace(/%/g, "%25")); + if (hostname != null && hostname != "localhost") { + url.hostname = hostname; + if (!url.hostname) { + throw new TypeError("Invalid hostname."); + } + } + return url; +} +const mod = { + sep: sep, + delimiter: delimiter, + resolve: resolve, + normalize: normalize, + isAbsolute: isAbsolute, + join: join, + relative: relative, + toNamespacedPath: toNamespacedPath, + dirname: dirname, + basename: basename, + extname: extname, + format: format, + parse: parse, + fromFileUrl: fromFileUrl, + toFileUrl: toFileUrl +}; +const sep1 = "/"; +const delimiter1 = ":"; +function resolve1(...pathSegments) { + let resolvedPath = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--){ + let path; + if (i >= 0) path = pathSegments[i]; + else { + const { Deno: Deno1 } = globalThis; + if (typeof Deno1?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno1.cwd(); + } + assertPath(path); + if (path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + } + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator); + if (resolvedAbsolute) { + if (resolvedPath.length > 0) return `/${resolvedPath}`; + else return "/"; + } else if (resolvedPath.length > 0) return resolvedPath; + else return "."; +} +function normalize1(path) { + assertPath(path); + if (path.length === 0) return "."; + const isAbsolute = path.charCodeAt(0) === 47; + const trailingSeparator = path.charCodeAt(path.length - 1) === 47; + path = normalizeString(path, !isAbsolute, "/", isPosixPathSeparator); + if (path.length === 0 && !isAbsolute) path = "."; + if (path.length > 0 && trailingSeparator) path += "/"; + if (isAbsolute) return `/${path}`; + return path; +} +function isAbsolute1(path) { + assertPath(path); + return path.length > 0 && path.charCodeAt(0) === 47; +} +function join1(...paths) { + if (paths.length === 0) return "."; + let joined; + for(let i = 0, len = paths.length; i < len; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (!joined) joined = path; + else joined += `/${path}`; + } + } + if (!joined) return "."; + return normalize1(joined); +} +function relative1(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + from = resolve1(from); + to = resolve1(to); + if (from === to) return ""; + let fromStart = 1; + const fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== 47) break; + } + const fromLen = fromEnd - fromStart; + let toStart = 1; + const toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== 47) break; + } + const toLen = toEnd - toStart; + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === 47) { + return to.slice(toStart + i + 1); + } else if (i === 0) { + return to.slice(toStart + i); + } + } else if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === 47) { + lastCommonSep = i; + } else if (i === 0) { + lastCommonSep = 0; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === 47) lastCommonSep = i; + } + let out = ""; + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === 47) { + if (out.length === 0) out += ".."; + else out += "/.."; + } + } + if (out.length > 0) return out + to.slice(toStart + lastCommonSep); + else { + toStart += lastCommonSep; + if (to.charCodeAt(toStart) === 47) ++toStart; + return to.slice(toStart); + } +} +function toNamespacedPath1(path) { + return path; +} +function dirname1(path) { + assertPath(path); + if (path.length === 0) return "."; + const hasRoot = path.charCodeAt(0) === 47; + let end = -1; + let matchedSlash = true; + for(let i = path.length - 1; i >= 1; --i){ + if (path.charCodeAt(i) === 47) { + if (!matchedSlash) { + end = i; + break; + } + } else { + matchedSlash = false; + } + } + if (end === -1) return hasRoot ? "/" : "."; + if (hasRoot && end === 1) return "//"; + return path.slice(0, end); +} +function basename1(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + end = i; + } + } else { + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= 0; --i){ + if (path.charCodeAt(i) === 47) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +function extname1(path) { + assertPath(path); + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let preDotState = 0; + for(let i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +function format1(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("/", pathObject); +} +function parse1(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + if (path.length === 0) return ret; + const isAbsolute = path.charCodeAt(0) === 47; + let start; + if (isAbsolute) { + ret.root = "/"; + start = 1; + } else { + start = 0; + } + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + let preDotState = 0; + for(; i >= start; --i){ + const code = path.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + if (startPart === 0 && isAbsolute) { + ret.base = ret.name = path.slice(1, end); + } else { + ret.base = ret.name = path.slice(startPart, end); + } + } + } else { + if (startPart === 0 && isAbsolute) { + ret.name = path.slice(1, startDot); + ret.base = path.slice(1, end); + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + } + ret.ext = path.slice(startDot, end); + } + if (startPart > 0) ret.dir = path.slice(0, startPart - 1); + else if (isAbsolute) ret.dir = "/"; + return ret; +} +function fromFileUrl1(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25")); +} +function toFileUrl1(path) { + if (!isAbsolute1(path)) { + throw new TypeError("Must be an absolute path."); + } + const url = new URL("file:///"); + url.pathname = encodeWhitespace(path.replace(/%/g, "%25").replace(/\\/g, "%5C")); + return url; +} +const mod1 = { + sep: sep1, + delimiter: delimiter1, + resolve: resolve1, + normalize: normalize1, + isAbsolute: isAbsolute1, + join: join1, + relative: relative1, + toNamespacedPath: toNamespacedPath1, + dirname: dirname1, + basename: basename1, + extname: extname1, + format: format1, + parse: parse1, + fromFileUrl: fromFileUrl1, + toFileUrl: toFileUrl1 +}; +const path = isWindows ? mod : mod1; +const { join: join2 , normalize: normalize2 } = path; +const path1 = isWindows ? mod : mod1; +const { basename: basename2 , delimiter: delimiter2 , dirname: dirname2 , extname: extname2 , format: format2 , fromFileUrl: fromFileUrl2 , isAbsolute: isAbsolute2 , join: join3 , normalize: normalize3 , parse: parse2 , relative: relative2 , resolve: resolve2 , sep: sep2 , toFileUrl: toFileUrl2 , toNamespacedPath: toNamespacedPath2 } = path1; +function isCloser(value) { + return typeof value === "object" && value != null && "close" in value && typeof value["close"] === "function"; +} +function readableStreamFromReader(reader, options = {}) { + const { autoClose =true , chunkSize =16_640 , strategy } = options; + return new ReadableStream({ + async pull (controller) { + const chunk = new Uint8Array(chunkSize); + try { + const read = await reader.read(chunk); + if (read === null) { + if (isCloser(reader) && autoClose) { + reader.close(); + } + controller.close(); + return; + } + controller.enqueue(chunk.subarray(0, read)); + } catch (e) { + controller.error(e); + if (isCloser(reader)) { + reader.close(); + } + } + }, + cancel () { + if (isCloser(reader) && autoClose) { + reader.close(); + } + } + }, strategy); +} +const importMeta = { + url: "https://deno.land/std@0.140.0/examples/chat/server.ts", + main: import.meta.main +}; +const clients = new Map(); +let clientId = 0; +function dispatch(msg) { + for (const client of clients.values()){ + client.send(msg); + } +} +function wsHandler(ws) { + const id = ++clientId; + clients.set(id, ws); + ws.onopen = ()=>{ + dispatch(`Connected: [${id}]`); + }; + ws.onmessage = (e)=>{ + console.log(`msg:${id}`, e.data); + dispatch(`[${id}]: ${e.data}`); + }; + ws.onclose = ()=>{ + clients.delete(id); + dispatch(`Closed: [${id}]`); + }; +} +async function requestHandler(req) { + const pathname = new URL(req.request.url).pathname; + if (req.request.method === "GET" && pathname === "/") { + const u = new URL("./index.html", importMeta.url); + if (u.protocol.startsWith("http")) { + fetch(u.href).then(async (resp)=>{ + const body = new Uint8Array(await resp.arrayBuffer()); + req.respondWith(new Response(body, { + status: resp.status, + headers: { + "content-type": "text/html" + } + })); + }); + } else { + const file = await Deno.open(fromFileUrl2(u)); + req.respondWith(new Response(readableStreamFromReader(file), { + status: 200, + headers: { + "content-type": "text/html" + } + })); + } + } else if (req.request.method === "GET" && pathname === "/favicon.ico") { + req.respondWith(Response.redirect("https://deno.land/favicon.ico", 302)); + } else if (req.request.method === "GET" && pathname === "/ws") { + const { socket , response } = Deno.upgradeWebSocket(req.request); + wsHandler(socket); + req.respondWith(response); + } +} +const server = Deno.listen({ + port: 8080 +}); +console.log("chat server starting on :8080...."); +for await (const conn of server){ + (async ()=>{ + const httpConn = Deno.serveHttp(conn); + for await (const requestEvent of httpConn){ + requestHandler(requestEvent); + } + })(); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL29zLnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9fY29uc3RhbnRzLnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9fdXRpbC50cyIsImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL2Fzc2VydC50cyIsImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvd2luMzIudHMiLCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNDAuMC9wYXRoL3Bvc2l4LnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9nbG9iLnRzIiwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTQwLjAvcGF0aC9tb2QudHMiLCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNDAuMC9zdHJlYW1zL2NvbnZlcnNpb24udHMiLCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNDAuMC9leGFtcGxlcy9jaGF0L3NlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5leHBvcnQgdHlwZSBPU1R5cGUgPSBcIndpbmRvd3NcIiB8IFwibGludXhcIiB8IFwiZGFyd2luXCI7XG5cbmV4cG9ydCBjb25zdCBvc1R5cGU6IE9TVHlwZSA9ICgoKSA9PiB7XG4gIC8vIGRlbm8tbGludC1pZ25vcmUgbm8tZXhwbGljaXQtYW55XG4gIGNvbnN0IHsgRGVubyB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gIGlmICh0eXBlb2YgRGVubz8uYnVpbGQ/Lm9zID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIERlbm8uYnVpbGQub3M7XG4gIH1cblxuICAvLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueVxuICBjb25zdCB7IG5hdmlnYXRvciB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gIGlmIChuYXZpZ2F0b3I/LmFwcFZlcnNpb24/LmluY2x1ZGVzPy4oXCJXaW5cIikpIHtcbiAgICByZXR1cm4gXCJ3aW5kb3dzXCI7XG4gIH1cblxuICByZXR1cm4gXCJsaW51eFwiO1xufSkoKTtcblxuZXhwb3J0IGNvbnN0IGlzV2luZG93cyA9IG9zVHlwZSA9PT0gXCJ3aW5kb3dzXCI7XG5leHBvcnQgY29uc3QgaXNMaW51eCA9IG9zVHlwZSA9PT0gXCJsaW51eFwiO1xuIiwiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuLy8gQWxwaGFiZXQgY2hhcnMuXG5leHBvcnQgY29uc3QgQ0hBUl9VUFBFUkNBU0VfQSA9IDY1OyAvKiBBICovXG5leHBvcnQgY29uc3QgQ0hBUl9MT1dFUkNBU0VfQSA9IDk3OyAvKiBhICovXG5leHBvcnQgY29uc3QgQ0hBUl9VUFBFUkNBU0VfWiA9IDkwOyAvKiBaICovXG5leHBvcnQgY29uc3QgQ0hBUl9MT1dFUkNBU0VfWiA9IDEyMjsgLyogeiAqL1xuXG4vLyBOb24tYWxwaGFiZXRpYyBjaGFycy5cbmV4cG9ydCBjb25zdCBDSEFSX0RPVCA9IDQ2OyAvKiAuICovXG5leHBvcnQgY29uc3QgQ0hBUl9GT1JXQVJEX1NMQVNIID0gNDc7IC8qIC8gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0JBQ0tXQVJEX1NMQVNIID0gOTI7IC8qIFxcICovXG5leHBvcnQgY29uc3QgQ0hBUl9WRVJUSUNBTF9MSU5FID0gMTI0OyAvKiB8ICovXG5leHBvcnQgY29uc3QgQ0hBUl9DT0xPTiA9IDU4OyAvKiA6ICovXG5leHBvcnQgY29uc3QgQ0hBUl9RVUVTVElPTl9NQVJLID0gNjM7IC8qID8gKi9cbmV4cG9ydCBjb25zdCBDSEFSX1VOREVSU0NPUkUgPSA5NTsgLyogXyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTElORV9GRUVEID0gMTA7IC8qIFxcbiAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQ0FSUklBR0VfUkVUVVJOID0gMTM7IC8qIFxcciAqL1xuZXhwb3J0IGNvbnN0IENIQVJfVEFCID0gOTsgLyogXFx0ICovXG5leHBvcnQgY29uc3QgQ0hBUl9GT1JNX0ZFRUQgPSAxMjsgLyogXFxmICovXG5leHBvcnQgY29uc3QgQ0hBUl9FWENMQU1BVElPTl9NQVJLID0gMzM7IC8qICEgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0hBU0ggPSAzNTsgLyogIyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfU1BBQ0UgPSAzMjsgLyogICAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTk9fQlJFQUtfU1BBQ0UgPSAxNjA7IC8qIFxcdTAwQTAgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1pFUk9fV0lEVEhfTk9CUkVBS19TUEFDRSA9IDY1Mjc5OyAvKiBcXHVGRUZGICovXG5leHBvcnQgY29uc3QgQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUID0gOTE7IC8qIFsgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUID0gOTM7IC8qIF0gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xFRlRfQU5HTEVfQlJBQ0tFVCA9IDYwOyAvKiA8ICovXG5leHBvcnQgY29uc3QgQ0hBUl9SSUdIVF9BTkdMRV9CUkFDS0VUID0gNjI7IC8qID4gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVCA9IDEyMzsgLyogeyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVCA9IDEyNTsgLyogfSAqL1xuZXhwb3J0IGNvbnN0IENIQVJfSFlQSEVOX01JTlVTID0gNDU7IC8qIC0gKi9cbmV4cG9ydCBjb25zdCBDSEFSX1BMVVMgPSA0MzsgLyogKyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfRE9VQkxFX1FVT1RFID0gMzQ7IC8qIFwiICovXG5leHBvcnQgY29uc3QgQ0hBUl9TSU5HTEVfUVVPVEUgPSAzOTsgLyogJyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUEVSQ0VOVCA9IDM3OyAvKiAlICovXG5leHBvcnQgY29uc3QgQ0hBUl9TRU1JQ09MT04gPSA1OTsgLyogOyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQ0lSQ1VNRkxFWF9BQ0NFTlQgPSA5NDsgLyogXiAqL1xuZXhwb3J0IGNvbnN0IENIQVJfR1JBVkVfQUNDRU5UID0gOTY7IC8qIGAgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0FUID0gNjQ7IC8qIEAgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0FNUEVSU0FORCA9IDM4OyAvKiAmICovXG5leHBvcnQgY29uc3QgQ0hBUl9FUVVBTCA9IDYxOyAvKiA9ICovXG5cbi8vIERpZ2l0c1xuZXhwb3J0IGNvbnN0IENIQVJfMCA9IDQ4OyAvKiAwICovXG5leHBvcnQgY29uc3QgQ0hBUl85ID0gNTc7IC8qIDkgKi9cbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgdGhlIEJyb3dzZXJpZnkgYXV0aG9ycy4gTUlUIExpY2Vuc2UuXG4vLyBQb3J0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYnJvd3NlcmlmeS9wYXRoLWJyb3dzZXJpZnkvXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmltcG9ydCB0eXBlIHsgRm9ybWF0SW5wdXRQYXRoT2JqZWN0IH0gZnJvbSBcIi4vX2ludGVyZmFjZS50c1wiO1xuaW1wb3J0IHtcbiAgQ0hBUl9CQUNLV0FSRF9TTEFTSCxcbiAgQ0hBUl9ET1QsXG4gIENIQVJfRk9SV0FSRF9TTEFTSCxcbiAgQ0hBUl9MT1dFUkNBU0VfQSxcbiAgQ0hBUl9MT1dFUkNBU0VfWixcbiAgQ0hBUl9VUFBFUkNBU0VfQSxcbiAgQ0hBUl9VUFBFUkNBU0VfWixcbn0gZnJvbSBcIi4vX2NvbnN0YW50cy50c1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UGF0aChwYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKHR5cGVvZiBwYXRoICE9PSBcInN0cmluZ1wiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIGBQYXRoIG11c3QgYmUgYSBzdHJpbmcuIFJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkocGF0aCl9YCxcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1Bvc2l4UGF0aFNlcGFyYXRvcihjb2RlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGF0aFNlcGFyYXRvcihjb2RlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzUG9zaXhQYXRoU2VwYXJhdG9yKGNvZGUpIHx8IGNvZGUgPT09IENIQVJfQkFDS1dBUkRfU0xBU0g7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1dpbmRvd3NEZXZpY2VSb290KGNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIChjb2RlID49IENIQVJfTE9XRVJDQVNFX0EgJiYgY29kZSA8PSBDSEFSX0xPV0VSQ0FTRV9aKSB8fFxuICAgIChjb2RlID49IENIQVJfVVBQRVJDQVNFX0EgJiYgY29kZSA8PSBDSEFSX1VQUEVSQ0FTRV9aKVxuICApO1xufVxuXG4vLyBSZXNvbHZlcyAuIGFuZCAuLiBlbGVtZW50cyBpbiBhIHBhdGggd2l0aCBkaXJlY3RvcnkgbmFtZXNcbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVTdHJpbmcoXG4gIHBhdGg6IHN0cmluZyxcbiAgYWxsb3dBYm92ZVJvb3Q6IGJvb2xlYW4sXG4gIHNlcGFyYXRvcjogc3RyaW5nLFxuICBpc1BhdGhTZXBhcmF0b3I6IChjb2RlOiBudW1iZXIpID0+IGJvb2xlYW4sXG4pOiBzdHJpbmcge1xuICBsZXQgcmVzID0gXCJcIjtcbiAgbGV0IGxhc3RTZWdtZW50TGVuZ3RoID0gMDtcbiAgbGV0IGxhc3RTbGFzaCA9IC0xO1xuICBsZXQgZG90cyA9IDA7XG4gIGxldCBjb2RlOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBwYXRoLmxlbmd0aDsgaSA8PSBsZW47ICsraSkge1xuICAgIGlmIChpIDwgbGVuKSBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KGkpO1xuICAgIGVsc2UgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlISkpIGJyZWFrO1xuICAgIGVsc2UgY29kZSA9IENIQVJfRk9SV0FSRF9TTEFTSDtcblxuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSEpKSB7XG4gICAgICBpZiAobGFzdFNsYXNoID09PSBpIC0gMSB8fCBkb3RzID09PSAxKSB7XG4gICAgICAgIC8vIE5PT1BcbiAgICAgIH0gZWxzZSBpZiAobGFzdFNsYXNoICE9PSBpIC0gMSAmJiBkb3RzID09PSAyKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICByZXMubGVuZ3RoIDwgMiB8fFxuICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoICE9PSAyIHx8XG4gICAgICAgICAgcmVzLmNoYXJDb2RlQXQocmVzLmxlbmd0aCAtIDEpICE9PSBDSEFSX0RPVCB8fFxuICAgICAgICAgIHJlcy5jaGFyQ29kZUF0KHJlcy5sZW5ndGggLSAyKSAhPT0gQ0hBUl9ET1RcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHJlcy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBjb25zdCBsYXN0U2xhc2hJbmRleCA9IHJlcy5sYXN0SW5kZXhPZihzZXBhcmF0b3IpO1xuICAgICAgICAgICAgaWYgKGxhc3RTbGFzaEluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgICByZXMgPSBcIlwiO1xuICAgICAgICAgICAgICBsYXN0U2VnbWVudExlbmd0aCA9IDA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXMgPSByZXMuc2xpY2UoMCwgbGFzdFNsYXNoSW5kZXgpO1xuICAgICAgICAgICAgICBsYXN0U2VnbWVudExlbmd0aCA9IHJlcy5sZW5ndGggLSAxIC0gcmVzLmxhc3RJbmRleE9mKHNlcGFyYXRvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0U2xhc2ggPSBpO1xuICAgICAgICAgICAgZG90cyA9IDA7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlcy5sZW5ndGggPT09IDIgfHwgcmVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcmVzID0gXCJcIjtcbiAgICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gMDtcbiAgICAgICAgICAgIGxhc3RTbGFzaCA9IGk7XG4gICAgICAgICAgICBkb3RzID0gMDtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxsb3dBYm92ZVJvb3QpIHtcbiAgICAgICAgICBpZiAocmVzLmxlbmd0aCA+IDApIHJlcyArPSBgJHtzZXBhcmF0b3J9Li5gO1xuICAgICAgICAgIGVsc2UgcmVzID0gXCIuLlwiO1xuICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gMjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHJlcy5sZW5ndGggPiAwKSByZXMgKz0gc2VwYXJhdG9yICsgcGF0aC5zbGljZShsYXN0U2xhc2ggKyAxLCBpKTtcbiAgICAgICAgZWxzZSByZXMgPSBwYXRoLnNsaWNlKGxhc3RTbGFzaCArIDEsIGkpO1xuICAgICAgICBsYXN0U2VnbWVudExlbmd0aCA9IGkgLSBsYXN0U2xhc2ggLSAxO1xuICAgICAgfVxuICAgICAgbGFzdFNsYXNoID0gaTtcbiAgICAgIGRvdHMgPSAwO1xuICAgIH0gZWxzZSBpZiAoY29kZSA9PT0gQ0hBUl9ET1QgJiYgZG90cyAhPT0gLTEpIHtcbiAgICAgICsrZG90cztcbiAgICB9IGVsc2Uge1xuICAgICAgZG90cyA9IC0xO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX2Zvcm1hdChcbiAgc2VwOiBzdHJpbmcsXG4gIHBhdGhPYmplY3Q6IEZvcm1hdElucHV0UGF0aE9iamVjdCxcbik6IHN0cmluZyB7XG4gIGNvbnN0IGRpcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gcGF0aE9iamVjdC5kaXIgfHwgcGF0aE9iamVjdC5yb290O1xuICBjb25zdCBiYXNlOiBzdHJpbmcgPSBwYXRoT2JqZWN0LmJhc2UgfHxcbiAgICAocGF0aE9iamVjdC5uYW1lIHx8IFwiXCIpICsgKHBhdGhPYmplY3QuZXh0IHx8IFwiXCIpO1xuICBpZiAoIWRpcikgcmV0dXJuIGJhc2U7XG4gIGlmIChkaXIgPT09IHBhdGhPYmplY3Qucm9vdCkgcmV0dXJuIGRpciArIGJhc2U7XG4gIHJldHVybiBkaXIgKyBzZXAgKyBiYXNlO1xufVxuXG5jb25zdCBXSElURVNQQUNFX0VOQ09ESU5HUzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgXCJcXHUwMDA5XCI6IFwiJTA5XCIsXG4gIFwiXFx1MDAwQVwiOiBcIiUwQVwiLFxuICBcIlxcdTAwMEJcIjogXCIlMEJcIixcbiAgXCJcXHUwMDBDXCI6IFwiJTBDXCIsXG4gIFwiXFx1MDAwRFwiOiBcIiUwRFwiLFxuICBcIlxcdTAwMjBcIjogXCIlMjBcIixcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVXaGl0ZXNwYWNlKHN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlQWxsKC9bXFxzXS9nLCAoYykgPT4ge1xuICAgIHJldHVybiBXSElURVNQQUNFX0VOQ09ESU5HU1tjXSA/PyBjO1xuICB9KTtcbn1cbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmV4cG9ydCBjbGFzcyBEZW5vU3RkSW50ZXJuYWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gXCJEZW5vU3RkSW50ZXJuYWxFcnJvclwiO1xuICB9XG59XG5cbi8qKiBNYWtlIGFuIGFzc2VydGlvbiwgaWYgbm90IGB0cnVlYCwgdGhlbiB0aHJvdy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoZXhwcjogdW5rbm93biwgbXNnID0gXCJcIik6IGFzc2VydHMgZXhwciB7XG4gIGlmICghZXhwcikge1xuICAgIHRocm93IG5ldyBEZW5vU3RkSW50ZXJuYWxFcnJvcihtc2cpO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gQ29weXJpZ2h0IHRoZSBCcm93c2VyaWZ5IGF1dGhvcnMuIE1JVCBMaWNlbnNlLlxuLy8gUG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Jyb3dzZXJpZnkvcGF0aC1icm93c2VyaWZ5L1xuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5pbXBvcnQgdHlwZSB7IEZvcm1hdElucHV0UGF0aE9iamVjdCwgUGFyc2VkUGF0aCB9IGZyb20gXCIuL19pbnRlcmZhY2UudHNcIjtcbmltcG9ydCB7XG4gIENIQVJfQkFDS1dBUkRfU0xBU0gsXG4gIENIQVJfQ09MT04sXG4gIENIQVJfRE9ULFxuICBDSEFSX1FVRVNUSU9OX01BUkssXG59IGZyb20gXCIuL19jb25zdGFudHMudHNcIjtcblxuaW1wb3J0IHtcbiAgX2Zvcm1hdCxcbiAgYXNzZXJ0UGF0aCxcbiAgZW5jb2RlV2hpdGVzcGFjZSxcbiAgaXNQYXRoU2VwYXJhdG9yLFxuICBpc1dpbmRvd3NEZXZpY2VSb290LFxuICBub3JtYWxpemVTdHJpbmcsXG59IGZyb20gXCIuL191dGlsLnRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vX3V0aWwvYXNzZXJ0LnRzXCI7XG5cbmV4cG9ydCBjb25zdCBzZXAgPSBcIlxcXFxcIjtcbmV4cG9ydCBjb25zdCBkZWxpbWl0ZXIgPSBcIjtcIjtcblxuLyoqXG4gKiBSZXNvbHZlcyBwYXRoIHNlZ21lbnRzIGludG8gYSBgcGF0aGBcbiAqIEBwYXJhbSBwYXRoU2VnbWVudHMgdG8gcHJvY2VzcyB0byBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlKC4uLnBhdGhTZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICBsZXQgcmVzb2x2ZWREZXZpY2UgPSBcIlwiO1xuICBsZXQgcmVzb2x2ZWRUYWlsID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTE7IGktLSkge1xuICAgIGxldCBwYXRoOiBzdHJpbmc7XG4gICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCB7IERlbm8gfSA9IGdsb2JhbFRoaXMgYXMgYW55O1xuICAgIGlmIChpID49IDApIHtcbiAgICAgIHBhdGggPSBwYXRoU2VnbWVudHNbaV07XG4gICAgfSBlbHNlIGlmICghcmVzb2x2ZWREZXZpY2UpIHtcbiAgICAgIGlmICh0eXBlb2YgRGVubz8uY3dkICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlJlc29sdmVkIGEgZHJpdmUtbGV0dGVyLWxlc3MgcGF0aCB3aXRob3V0IGEgQ1dELlwiKTtcbiAgICAgIH1cbiAgICAgIHBhdGggPSBEZW5vLmN3ZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBEZW5vPy5lbnY/LmdldCAhPT0gXCJmdW5jdGlvblwiIHx8IHR5cGVvZiBEZW5vPy5jd2QgIT09IFwiZnVuY3Rpb25cIlxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIHJlbGF0aXZlIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcblxuICAgICAgLy8gVmVyaWZ5IHRoYXQgYSBjd2Qgd2FzIGZvdW5kIGFuZCB0aGF0IGl0IGFjdHVhbGx5IHBvaW50c1xuICAgICAgLy8gdG8gb3VyIGRyaXZlLiBJZiBub3QsIGRlZmF1bHQgdG8gdGhlIGRyaXZlJ3Mgcm9vdC5cbiAgICAgIGlmIChcbiAgICAgICAgcGF0aCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHBhdGguc2xpY2UoMCwgMykudG9Mb3dlckNhc2UoKSAhPT0gYCR7cmVzb2x2ZWREZXZpY2UudG9Mb3dlckNhc2UoKX1cXFxcYFxuICAgICAgKSB7XG4gICAgICAgIHBhdGggPSBgJHtyZXNvbHZlZERldmljZX1cXFxcYDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gICAgY29uc3QgbGVuID0gcGF0aC5sZW5ndGg7XG5cbiAgICAvLyBTa2lwIGVtcHR5IGVudHJpZXNcbiAgICBpZiAobGVuID09PSAwKSBjb250aW51ZTtcblxuICAgIGxldCByb290RW5kID0gMDtcbiAgICBsZXQgZGV2aWNlID0gXCJcIjtcbiAgICBsZXQgaXNBYnNvbHV0ZSA9IGZhbHNlO1xuICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgICAvLyBUcnkgdG8gbWF0Y2ggYSByb290XG4gICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgICAgLy8gUG9zc2libGUgVU5DIHJvb3RcblxuICAgICAgICAvLyBJZiB3ZSBzdGFydGVkIHdpdGggYSBzZXBhcmF0b3IsIHdlIGtub3cgd2UgYXQgbGVhc3QgaGF2ZSBhblxuICAgICAgICAvLyBhYnNvbHV0ZSBwYXRoIG9mIHNvbWUga2luZCAoVU5DIG9yIG90aGVyd2lzZSlcbiAgICAgICAgaXNBYnNvbHV0ZSA9IHRydWU7XG5cbiAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgICAgLy8gTWF0Y2hlZCBkb3VibGUgcGF0aCBzZXBhcmF0b3IgYXQgYmVnaW5uaW5nXG4gICAgICAgICAgbGV0IGogPSAyO1xuICAgICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0UGFydCA9IHBhdGguc2xpY2UobGFzdCwgaik7XG4gICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICAgIGlmICghaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGogPT09IGxlbikge1xuICAgICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCBvbmx5XG4gICAgICAgICAgICAgICAgZGV2aWNlID0gYFxcXFxcXFxcJHtmaXJzdFBhcnR9XFxcXCR7cGF0aC5zbGljZShsYXN0KX1gO1xuICAgICAgICAgICAgICAgIHJvb3RFbmQgPSBqO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgd2l0aCBsZWZ0b3ZlcnNcblxuICAgICAgICAgICAgICAgIGRldmljZSA9IGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCwgail9YDtcbiAgICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByb290RW5kID0gMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgICAgaWYgKHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikge1xuICAgICAgICAgIGRldmljZSA9IHBhdGguc2xpY2UoMCwgMik7XG4gICAgICAgICAgcm9vdEVuZCA9IDI7XG4gICAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDIpKSkge1xuICAgICAgICAgICAgICAvLyBUcmVhdCBzZXBhcmF0b3IgZm9sbG93aW5nIGRyaXZlIG5hbWUgYXMgYW4gYWJzb2x1dGUgcGF0aFxuICAgICAgICAgICAgICAvLyBpbmRpY2F0b3JcbiAgICAgICAgICAgICAgaXNBYnNvbHV0ZSA9IHRydWU7XG4gICAgICAgICAgICAgIHJvb3RFbmQgPSAzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yXG4gICAgICByb290RW5kID0gMTtcbiAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGRldmljZS5sZW5ndGggPiAwICYmXG4gICAgICByZXNvbHZlZERldmljZS5sZW5ndGggPiAwICYmXG4gICAgICBkZXZpY2UudG9Mb3dlckNhc2UoKSAhPT0gcmVzb2x2ZWREZXZpY2UudG9Mb3dlckNhc2UoKVxuICAgICkge1xuICAgICAgLy8gVGhpcyBwYXRoIHBvaW50cyB0byBhbm90aGVyIGRldmljZSBzbyBpdCBpcyBub3QgYXBwbGljYWJsZVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHJlc29sdmVkRGV2aWNlLmxlbmd0aCA9PT0gMCAmJiBkZXZpY2UubGVuZ3RoID4gMCkge1xuICAgICAgcmVzb2x2ZWREZXZpY2UgPSBkZXZpY2U7XG4gICAgfVxuICAgIGlmICghcmVzb2x2ZWRBYnNvbHV0ZSkge1xuICAgICAgcmVzb2x2ZWRUYWlsID0gYCR7cGF0aC5zbGljZShyb290RW5kKX1cXFxcJHtyZXNvbHZlZFRhaWx9YDtcbiAgICAgIHJlc29sdmVkQWJzb2x1dGUgPSBpc0Fic29sdXRlO1xuICAgIH1cblxuICAgIGlmIChyZXNvbHZlZEFic29sdXRlICYmIHJlc29sdmVkRGV2aWNlLmxlbmd0aCA+IDApIGJyZWFrO1xuICB9XG5cbiAgLy8gQXQgdGhpcyBwb2ludCB0aGUgcGF0aCBzaG91bGQgYmUgcmVzb2x2ZWQgdG8gYSBmdWxsIGFic29sdXRlIHBhdGgsXG4gIC8vIGJ1dCBoYW5kbGUgcmVsYXRpdmUgcGF0aHMgdG8gYmUgc2FmZSAobWlnaHQgaGFwcGVuIHdoZW4gcHJvY2Vzcy5jd2QoKVxuICAvLyBmYWlscylcblxuICAvLyBOb3JtYWxpemUgdGhlIHRhaWwgcGF0aFxuICByZXNvbHZlZFRhaWwgPSBub3JtYWxpemVTdHJpbmcoXG4gICAgcmVzb2x2ZWRUYWlsLFxuICAgICFyZXNvbHZlZEFic29sdXRlLFxuICAgIFwiXFxcXFwiLFxuICAgIGlzUGF0aFNlcGFyYXRvcixcbiAgKTtcblxuICByZXR1cm4gcmVzb2x2ZWREZXZpY2UgKyAocmVzb2x2ZWRBYnNvbHV0ZSA/IFwiXFxcXFwiIDogXCJcIikgKyByZXNvbHZlZFRhaWwgfHwgXCIuXCI7XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIGBwYXRoYFxuICogQHBhcmFtIHBhdGggdG8gbm9ybWFsaXplXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgY29uc3QgbGVuID0gcGF0aC5sZW5ndGg7XG4gIGlmIChsZW4gPT09IDApIHJldHVybiBcIi5cIjtcbiAgbGV0IHJvb3RFbmQgPSAwO1xuICBsZXQgZGV2aWNlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGxldCBpc0Fic29sdXRlID0gZmFsc2U7XG4gIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICBpZiAobGVuID4gMSkge1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgIC8vIElmIHdlIHN0YXJ0ZWQgd2l0aCBhIHNlcGFyYXRvciwgd2Uga25vdyB3ZSBhdCBsZWFzdCBoYXZlIGFuIGFic29sdXRlXG4gICAgICAvLyBwYXRoIG9mIHNvbWUga2luZCAoVU5DIG9yIG90aGVyd2lzZSlcbiAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuXG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgxKSkpIHtcbiAgICAgICAgLy8gTWF0Y2hlZCBkb3VibGUgcGF0aCBzZXBhcmF0b3IgYXQgYmVnaW5uaW5nXG4gICAgICAgIGxldCBqID0gMjtcbiAgICAgICAgbGV0IGxhc3QgPSBqO1xuICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgY29uc3QgZmlyc3RQYXJ0ID0gcGF0aC5zbGljZShsYXN0LCBqKTtcbiAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBwYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqID09PSBsZW4pIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IG9ubHlcbiAgICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIFVOQyByb290IHNpbmNlIHRoZXJlXG4gICAgICAgICAgICAgIC8vIGlzIG5vdGhpbmcgbGVmdCB0byBwcm9jZXNzXG5cbiAgICAgICAgICAgICAgcmV0dXJuIGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCl9XFxcXGA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IHdpdGggbGVmdG92ZXJzXG5cbiAgICAgICAgICAgICAgZGV2aWNlID0gYFxcXFxcXFxcJHtmaXJzdFBhcnR9XFxcXCR7cGF0aC5zbGljZShsYXN0LCBqKX1gO1xuICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJvb3RFbmQgPSAxO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChjb2RlKSkge1xuICAgICAgLy8gUG9zc2libGUgZGV2aWNlIHJvb3RcblxuICAgICAgaWYgKHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikge1xuICAgICAgICBkZXZpY2UgPSBwYXRoLnNsaWNlKDAsIDIpO1xuICAgICAgICByb290RW5kID0gMjtcbiAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgyKSkpIHtcbiAgICAgICAgICAgIC8vIFRyZWF0IHNlcGFyYXRvciBmb2xsb3dpbmcgZHJpdmUgbmFtZSBhcyBhbiBhYnNvbHV0ZSBwYXRoXG4gICAgICAgICAgICAvLyBpbmRpY2F0b3JcbiAgICAgICAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuICAgICAgICAgICAgcm9vdEVuZCA9IDM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgIC8vIGBwYXRoYCBjb250YWlucyBqdXN0IGEgcGF0aCBzZXBhcmF0b3IsIGV4aXQgZWFybHkgdG8gYXZvaWQgdW5uZWNlc3NhcnlcbiAgICAvLyB3b3JrXG4gICAgcmV0dXJuIFwiXFxcXFwiO1xuICB9XG5cbiAgbGV0IHRhaWw6IHN0cmluZztcbiAgaWYgKHJvb3RFbmQgPCBsZW4pIHtcbiAgICB0YWlsID0gbm9ybWFsaXplU3RyaW5nKFxuICAgICAgcGF0aC5zbGljZShyb290RW5kKSxcbiAgICAgICFpc0Fic29sdXRlLFxuICAgICAgXCJcXFxcXCIsXG4gICAgICBpc1BhdGhTZXBhcmF0b3IsXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICB0YWlsID0gXCJcIjtcbiAgfVxuICBpZiAodGFpbC5sZW5ndGggPT09IDAgJiYgIWlzQWJzb2x1dGUpIHRhaWwgPSBcIi5cIjtcbiAgaWYgKHRhaWwubGVuZ3RoID4gMCAmJiBpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGxlbiAtIDEpKSkge1xuICAgIHRhaWwgKz0gXCJcXFxcXCI7XG4gIH1cbiAgaWYgKGRldmljZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICAgIGlmICh0YWlsLmxlbmd0aCA+IDApIHJldHVybiBgXFxcXCR7dGFpbH1gO1xuICAgICAgZWxzZSByZXR1cm4gXCJcXFxcXCI7XG4gICAgfSBlbHNlIGlmICh0YWlsLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB0YWlsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNBYnNvbHV0ZSkge1xuICAgIGlmICh0YWlsLmxlbmd0aCA+IDApIHJldHVybiBgJHtkZXZpY2V9XFxcXCR7dGFpbH1gO1xuICAgIGVsc2UgcmV0dXJuIGAke2RldmljZX1cXFxcYDtcbiAgfSBlbHNlIGlmICh0YWlsLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gZGV2aWNlICsgdGFpbDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZGV2aWNlO1xuICB9XG59XG5cbi8qKlxuICogVmVyaWZpZXMgd2hldGhlciBwYXRoIGlzIGFic29sdXRlXG4gKiBAcGFyYW0gcGF0aCB0byB2ZXJpZnlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQWJzb2x1dGUocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdCgwKTtcbiAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgaWYgKGxlbiA+IDIgJiYgcGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OKSB7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgyKSkpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogSm9pbiBhbGwgZ2l2ZW4gYSBzZXF1ZW5jZSBvZiBgcGF0aHNgLHRoZW4gbm9ybWFsaXplcyB0aGUgcmVzdWx0aW5nIHBhdGguXG4gKiBAcGFyYW0gcGF0aHMgdG8gYmUgam9pbmVkIGFuZCBub3JtYWxpemVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqb2luKC4uLnBhdGhzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGNvbnN0IHBhdGhzQ291bnQgPSBwYXRocy5sZW5ndGg7XG4gIGlmIChwYXRoc0NvdW50ID09PSAwKSByZXR1cm4gXCIuXCI7XG5cbiAgbGV0IGpvaW5lZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBsZXQgZmlyc3RQYXJ0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRoc0NvdW50OyArK2kpIHtcbiAgICBjb25zdCBwYXRoID0gcGF0aHNbaV07XG4gICAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgICBpZiAocGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoam9pbmVkID09PSB1bmRlZmluZWQpIGpvaW5lZCA9IGZpcnN0UGFydCA9IHBhdGg7XG4gICAgICBlbHNlIGpvaW5lZCArPSBgXFxcXCR7cGF0aH1gO1xuICAgIH1cbiAgfVxuXG4gIGlmIChqb2luZWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIFwiLlwiO1xuXG4gIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBqb2luZWQgcGF0aCBkb2Vzbid0IHN0YXJ0IHdpdGggdHdvIHNsYXNoZXMsIGJlY2F1c2VcbiAgLy8gbm9ybWFsaXplKCkgd2lsbCBtaXN0YWtlIGl0IGZvciBhbiBVTkMgcGF0aCB0aGVuLlxuICAvL1xuICAvLyBUaGlzIHN0ZXAgaXMgc2tpcHBlZCB3aGVuIGl0IGlzIHZlcnkgY2xlYXIgdGhhdCB0aGUgdXNlciBhY3R1YWxseVxuICAvLyBpbnRlbmRlZCB0byBwb2ludCBhdCBhbiBVTkMgcGF0aC4gVGhpcyBpcyBhc3N1bWVkIHdoZW4gdGhlIGZpcnN0XG4gIC8vIG5vbi1lbXB0eSBzdHJpbmcgYXJndW1lbnRzIHN0YXJ0cyB3aXRoIGV4YWN0bHkgdHdvIHNsYXNoZXMgZm9sbG93ZWQgYnlcbiAgLy8gYXQgbGVhc3Qgb25lIG1vcmUgbm9uLXNsYXNoIGNoYXJhY3Rlci5cbiAgLy9cbiAgLy8gTm90ZSB0aGF0IGZvciBub3JtYWxpemUoKSB0byB0cmVhdCBhIHBhdGggYXMgYW4gVU5DIHBhdGggaXQgbmVlZHMgdG9cbiAgLy8gaGF2ZSBhdCBsZWFzdCAyIGNvbXBvbmVudHMsIHNvIHdlIGRvbid0IGZpbHRlciBmb3IgdGhhdCBoZXJlLlxuICAvLyBUaGlzIG1lYW5zIHRoYXQgdGhlIHVzZXIgY2FuIHVzZSBqb2luIHRvIGNvbnN0cnVjdCBVTkMgcGF0aHMgZnJvbVxuICAvLyBhIHNlcnZlciBuYW1lIGFuZCBhIHNoYXJlIG5hbWU7IGZvciBleGFtcGxlOlxuICAvLyAgIHBhdGguam9pbignLy9zZXJ2ZXInLCAnc2hhcmUnKSAtPiAnXFxcXFxcXFxzZXJ2ZXJcXFxcc2hhcmVcXFxcJylcbiAgbGV0IG5lZWRzUmVwbGFjZSA9IHRydWU7XG4gIGxldCBzbGFzaENvdW50ID0gMDtcbiAgYXNzZXJ0KGZpcnN0UGFydCAhPSBudWxsKTtcbiAgaWYgKGlzUGF0aFNlcGFyYXRvcihmaXJzdFBhcnQuY2hhckNvZGVBdCgwKSkpIHtcbiAgICArK3NsYXNoQ291bnQ7XG4gICAgY29uc3QgZmlyc3RMZW4gPSBmaXJzdFBhcnQubGVuZ3RoO1xuICAgIGlmIChmaXJzdExlbiA+IDEpIHtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoZmlyc3RQYXJ0LmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgICsrc2xhc2hDb3VudDtcbiAgICAgICAgaWYgKGZpcnN0TGVuID4gMikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoZmlyc3RQYXJ0LmNoYXJDb2RlQXQoMikpKSArK3NsYXNoQ291bnQ7XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHBhdGggaW4gdGhlIGZpcnN0IHBhcnRcbiAgICAgICAgICAgIG5lZWRzUmVwbGFjZSA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAobmVlZHNSZXBsYWNlKSB7XG4gICAgLy8gRmluZCBhbnkgbW9yZSBjb25zZWN1dGl2ZSBzbGFzaGVzIHdlIG5lZWQgdG8gcmVwbGFjZVxuICAgIGZvciAoOyBzbGFzaENvdW50IDwgam9pbmVkLmxlbmd0aDsgKytzbGFzaENvdW50KSB7XG4gICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihqb2luZWQuY2hhckNvZGVBdChzbGFzaENvdW50KSkpIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIFJlcGxhY2UgdGhlIHNsYXNoZXMgaWYgbmVlZGVkXG4gICAgaWYgKHNsYXNoQ291bnQgPj0gMikgam9pbmVkID0gYFxcXFwke2pvaW5lZC5zbGljZShzbGFzaENvdW50KX1gO1xuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZShqb2luZWQpO1xufVxuXG4vKipcbiAqIEl0IHdpbGwgc29sdmUgdGhlIHJlbGF0aXZlIHBhdGggZnJvbSBgZnJvbWAgdG8gYHRvYCwgZm9yIGluc3RhbmNlOlxuICogIGZyb20gPSAnQzpcXFxcb3JhbmRlYVxcXFx0ZXN0XFxcXGFhYSdcbiAqICB0byA9ICdDOlxcXFxvcmFuZGVhXFxcXGltcGxcXFxcYmJiJ1xuICogVGhlIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24gc2hvdWxkIGJlOiAnLi5cXFxcLi5cXFxcaW1wbFxcXFxiYmInXG4gKiBAcGFyYW0gZnJvbSByZWxhdGl2ZSBwYXRoXG4gKiBAcGFyYW0gdG8gcmVsYXRpdmUgcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpdmUoZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChmcm9tKTtcbiAgYXNzZXJ0UGF0aCh0byk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICBjb25zdCBmcm9tT3JpZyA9IHJlc29sdmUoZnJvbSk7XG4gIGNvbnN0IHRvT3JpZyA9IHJlc29sdmUodG8pO1xuXG4gIGlmIChmcm9tT3JpZyA9PT0gdG9PcmlnKSByZXR1cm4gXCJcIjtcblxuICBmcm9tID0gZnJvbU9yaWcudG9Mb3dlckNhc2UoKTtcbiAgdG8gPSB0b09yaWcudG9Mb3dlckNhc2UoKTtcblxuICBpZiAoZnJvbSA9PT0gdG8pIHJldHVybiBcIlwiO1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IGZyb21TdGFydCA9IDA7XG4gIGxldCBmcm9tRW5kID0gZnJvbS5sZW5ndGg7XG4gIGZvciAoOyBmcm9tU3RhcnQgPCBmcm9tRW5kOyArK2Zyb21TdGFydCkge1xuICAgIGlmIChmcm9tLmNoYXJDb2RlQXQoZnJvbVN0YXJ0KSAhPT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgLy8gVHJpbSB0cmFpbGluZyBiYWNrc2xhc2hlcyAoYXBwbGljYWJsZSB0byBVTkMgcGF0aHMgb25seSlcbiAgZm9yICg7IGZyb21FbmQgLSAxID4gZnJvbVN0YXJ0OyAtLWZyb21FbmQpIHtcbiAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21FbmQgLSAxKSAhPT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgZnJvbUxlbiA9IGZyb21FbmQgLSBmcm9tU3RhcnQ7XG5cbiAgLy8gVHJpbSBhbnkgbGVhZGluZyBiYWNrc2xhc2hlc1xuICBsZXQgdG9TdGFydCA9IDA7XG4gIGxldCB0b0VuZCA9IHRvLmxlbmd0aDtcbiAgZm9yICg7IHRvU3RhcnQgPCB0b0VuZDsgKyt0b1N0YXJ0KSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIC8vIFRyaW0gdHJhaWxpbmcgYmFja3NsYXNoZXMgKGFwcGxpY2FibGUgdG8gVU5DIHBhdGhzIG9ubHkpXG4gIGZvciAoOyB0b0VuZCAtIDEgPiB0b1N0YXJ0OyAtLXRvRW5kKSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9FbmQgLSAxKSAhPT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgdG9MZW4gPSB0b0VuZCAtIHRvU3RhcnQ7XG5cbiAgLy8gQ29tcGFyZSBwYXRocyB0byBmaW5kIHRoZSBsb25nZXN0IGNvbW1vbiBwYXRoIGZyb20gcm9vdFxuICBjb25zdCBsZW5ndGggPSBmcm9tTGVuIDwgdG9MZW4gPyBmcm9tTGVuIDogdG9MZW47XG4gIGxldCBsYXN0Q29tbW9uU2VwID0gLTE7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPD0gbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gbGVuZ3RoKSB7XG4gICAgICBpZiAodG9MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCArIGkpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYGZyb21gIGlzIHRoZSBleGFjdCBiYXNlIHBhdGggZm9yIGB0b2AuXG4gICAgICAgICAgLy8gRm9yIGV4YW1wbGU6IGZyb209J0M6XFxcXGZvb1xcXFxiYXInOyB0bz0nQzpcXFxcZm9vXFxcXGJhclxcXFxiYXonXG4gICAgICAgICAgcmV0dXJuIHRvT3JpZy5zbGljZSh0b1N0YXJ0ICsgaSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDIpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIGRldmljZSByb290LlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPSdDOlxcXFwnOyB0bz0nQzpcXFxcZm9vJ1xuICAgICAgICAgIHJldHVybiB0b09yaWcuc2xpY2UodG9TdGFydCArIGkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZnJvbUxlbiA+IGxlbmd0aCkge1xuICAgICAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCArIGkpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYHRvYCBpcyB0aGUgZXhhY3QgYmFzZSBwYXRoIGZvciBgZnJvbWAuXG4gICAgICAgICAgLy8gRm9yIGV4YW1wbGU6IGZyb209J0M6XFxcXGZvb1xcXFxiYXInOyB0bz0nQzpcXFxcZm9vJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDIpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSBkZXZpY2Ugcm9vdC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nQzpcXFxcZm9vXFxcXGJhcic7IHRvPSdDOlxcXFwnXG4gICAgICAgICAgbGFzdENvbW1vblNlcCA9IDM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ29kZSA9IGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKTtcbiAgICBjb25zdCB0b0NvZGUgPSB0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKTtcbiAgICBpZiAoZnJvbUNvZGUgIT09IHRvQ29kZSkgYnJlYWs7XG4gICAgZWxzZSBpZiAoZnJvbUNvZGUgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGxhc3RDb21tb25TZXAgPSBpO1xuICB9XG5cbiAgLy8gV2UgZm91bmQgYSBtaXNtYXRjaCBiZWZvcmUgdGhlIGZpcnN0IGNvbW1vbiBwYXRoIHNlcGFyYXRvciB3YXMgc2Vlbiwgc29cbiAgLy8gcmV0dXJuIHRoZSBvcmlnaW5hbCBgdG9gLlxuICBpZiAoaSAhPT0gbGVuZ3RoICYmIGxhc3RDb21tb25TZXAgPT09IC0xKSB7XG4gICAgcmV0dXJuIHRvT3JpZztcbiAgfVxuXG4gIGxldCBvdXQgPSBcIlwiO1xuICBpZiAobGFzdENvbW1vblNlcCA9PT0gLTEpIGxhc3RDb21tb25TZXAgPSAwO1xuICAvLyBHZW5lcmF0ZSB0aGUgcmVsYXRpdmUgcGF0aCBiYXNlZCBvbiB0aGUgcGF0aCBkaWZmZXJlbmNlIGJldHdlZW4gYHRvYCBhbmRcbiAgLy8gYGZyb21gXG4gIGZvciAoaSA9IGZyb21TdGFydCArIGxhc3RDb21tb25TZXAgKyAxOyBpIDw9IGZyb21FbmQ7ICsraSkge1xuICAgIGlmIChpID09PSBmcm9tRW5kIHx8IGZyb20uY2hhckNvZGVBdChpKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgaWYgKG91dC5sZW5ndGggPT09IDApIG91dCArPSBcIi4uXCI7XG4gICAgICBlbHNlIG91dCArPSBcIlxcXFwuLlwiO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSwgYXBwZW5kIHRoZSByZXN0IG9mIHRoZSBkZXN0aW5hdGlvbiAoYHRvYCkgcGF0aCB0aGF0IGNvbWVzIGFmdGVyXG4gIC8vIHRoZSBjb21tb24gcGF0aCBwYXJ0c1xuICBpZiAob3V0Lmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gb3V0ICsgdG9PcmlnLnNsaWNlKHRvU3RhcnQgKyBsYXN0Q29tbW9uU2VwLCB0b0VuZCk7XG4gIH0gZWxzZSB7XG4gICAgdG9TdGFydCArPSBsYXN0Q29tbW9uU2VwO1xuICAgIGlmICh0b09yaWcuY2hhckNvZGVBdCh0b1N0YXJ0KSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkgKyt0b1N0YXJ0O1xuICAgIHJldHVybiB0b09yaWcuc2xpY2UodG9TdGFydCwgdG9FbmQpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCB0byBhIG5hbWVzcGFjZSBwYXRoXG4gKiBAcGFyYW0gcGF0aCB0byByZXNvbHZlIHRvIG5hbWVzcGFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9OYW1lc3BhY2VkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBOb3RlOiB0aGlzIHdpbGwgKnByb2JhYmx5KiB0aHJvdyBzb21ld2hlcmUuXG4gIGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIHBhdGg7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiXCI7XG5cbiAgY29uc3QgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZShwYXRoKTtcblxuICBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+PSAzKSB7XG4gICAgaWYgKHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDApID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICBpZiAocmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIHtcbiAgICAgICAgY29uc3QgY29kZSA9IHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDIpO1xuICAgICAgICBpZiAoY29kZSAhPT0gQ0hBUl9RVUVTVElPTl9NQVJLICYmIGNvZGUgIT09IENIQVJfRE9UKSB7XG4gICAgICAgICAgLy8gTWF0Y2hlZCBub24tbG9uZyBVTkMgcm9vdCwgY29udmVydCB0aGUgcGF0aCB0byBhIGxvbmcgVU5DIHBhdGhcbiAgICAgICAgICByZXR1cm4gYFxcXFxcXFxcP1xcXFxVTkNcXFxcJHtyZXNvbHZlZFBhdGguc2xpY2UoMil9YDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChyZXNvbHZlZFBhdGguY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChcbiAgICAgICAgcmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04gJiZcbiAgICAgICAgcmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMikgPT09IENIQVJfQkFDS1dBUkRfU0xBU0hcbiAgICAgICkge1xuICAgICAgICAvLyBNYXRjaGVkIGRldmljZSByb290LCBjb252ZXJ0IHRoZSBwYXRoIHRvIGEgbG9uZyBVTkMgcGF0aFxuICAgICAgICByZXR1cm4gYFxcXFxcXFxcP1xcXFwke3Jlc29sdmVkUGF0aH1gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXRoO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgZGlyZWN0b3J5IG5hbWUgb2YgYSBgcGF0aGAuXG4gKiBAcGFyYW0gcGF0aCB0byBkZXRlcm1pbmUgbmFtZSBmb3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpcm5hbWUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgY29uc3QgbGVuID0gcGF0aC5sZW5ndGg7XG4gIGlmIChsZW4gPT09IDApIHJldHVybiBcIi5cIjtcbiAgbGV0IHJvb3RFbmQgPSAtMTtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IG9mZnNldCA9IDA7XG4gIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICBpZiAobGVuID4gMSkge1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgIHJvb3RFbmQgPSBvZmZzZXQgPSAxO1xuXG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgxKSkpIHtcbiAgICAgICAgLy8gTWF0Y2hlZCBkb3VibGUgcGF0aCBzZXBhcmF0b3IgYXQgYmVnaW5uaW5nXG4gICAgICAgIGxldCBqID0gMjtcbiAgICAgICAgbGV0IGxhc3QgPSBqO1xuICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgaWYgKCFpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaiA9PT0gbGVuKSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCBvbmx5XG4gICAgICAgICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IHdpdGggbGVmdG92ZXJzXG5cbiAgICAgICAgICAgICAgLy8gT2Zmc2V0IGJ5IDEgdG8gaW5jbHVkZSB0aGUgc2VwYXJhdG9yIGFmdGVyIHRoZSBVTkMgcm9vdCB0b1xuICAgICAgICAgICAgICAvLyB0cmVhdCBpdCBhcyBhIFwibm9ybWFsIHJvb3RcIiBvbiB0b3Agb2YgYSAoVU5DKSByb290XG4gICAgICAgICAgICAgIHJvb3RFbmQgPSBvZmZzZXQgPSBqICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgcm9vdEVuZCA9IG9mZnNldCA9IDI7XG4gICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSByb290RW5kID0gb2Zmc2V0ID0gMztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yLCBleGl0IGVhcmx5IHRvIGF2b2lkXG4gICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgIHJldHVybiBwYXRoO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IGxlbiAtIDE7IGkgPj0gb2Zmc2V0OyAtLWkpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChpKSkpIHtcbiAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgIGVuZCA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvclxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICBpZiAocm9vdEVuZCA9PT0gLTEpIHJldHVybiBcIi5cIjtcbiAgICBlbHNlIGVuZCA9IHJvb3RFbmQ7XG4gIH1cbiAgcmV0dXJuIHBhdGguc2xpY2UoMCwgZW5kKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGxhc3QgcG9ydGlvbiBvZiBhIGBwYXRoYC4gVHJhaWxpbmcgZGlyZWN0b3J5IHNlcGFyYXRvcnMgYXJlIGlnbm9yZWQuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKiBAcGFyYW0gZXh0IG9mIHBhdGggZGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlbmFtZShwYXRoOiBzdHJpbmcsIGV4dCA9IFwiXCIpOiBzdHJpbmcge1xuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZXh0XCIgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZycpO1xuICB9XG5cbiAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICBsZXQgaTogbnVtYmVyO1xuXG4gIC8vIENoZWNrIGZvciBhIGRyaXZlIGxldHRlciBwcmVmaXggc28gYXMgbm90IHRvIG1pc3Rha2UgdGhlIGZvbGxvd2luZ1xuICAvLyBwYXRoIHNlcGFyYXRvciBhcyBhbiBleHRyYSBzZXBhcmF0b3IgYXQgdGhlIGVuZCBvZiB0aGUgcGF0aCB0aGF0IGNhbiBiZVxuICAvLyBkaXNyZWdhcmRlZFxuICBpZiAocGF0aC5sZW5ndGggPj0gMikge1xuICAgIGNvbnN0IGRyaXZlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuICAgIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGRyaXZlKSkge1xuICAgICAgaWYgKHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikgc3RhcnQgPSAyO1xuICAgIH1cbiAgfVxuXG4gIGlmIChleHQgIT09IHVuZGVmaW5lZCAmJiBleHQubGVuZ3RoID4gMCAmJiBleHQubGVuZ3RoIDw9IHBhdGgubGVuZ3RoKSB7XG4gICAgaWYgKGV4dC5sZW5ndGggPT09IHBhdGgubGVuZ3RoICYmIGV4dCA9PT0gcGF0aCkgcmV0dXJuIFwiXCI7XG4gICAgbGV0IGV4dElkeCA9IGV4dC5sZW5ndGggLSAxO1xuICAgIGxldCBmaXJzdE5vblNsYXNoRW5kID0gLTE7XG4gICAgZm9yIChpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IHN0YXJ0OyAtLWkpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaXJzdE5vblNsYXNoRW5kID09PSAtMSkge1xuICAgICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCByZW1lbWJlciB0aGlzIGluZGV4IGluIGNhc2VcbiAgICAgICAgICAvLyB3ZSBuZWVkIGl0IGlmIHRoZSBleHRlbnNpb24gZW5kcyB1cCBub3QgbWF0Y2hpbmdcbiAgICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgICBmaXJzdE5vblNsYXNoRW5kID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dElkeCA+PSAwKSB7XG4gICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIHRoZSBleHBsaWNpdCBleHRlbnNpb25cbiAgICAgICAgICBpZiAoY29kZSA9PT0gZXh0LmNoYXJDb2RlQXQoZXh0SWR4KSkge1xuICAgICAgICAgICAgaWYgKC0tZXh0SWR4ID09PSAtMSkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIHRoZSBleHRlbnNpb24sIHNvIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91ciBwYXRoXG4gICAgICAgICAgICAgIC8vIGNvbXBvbmVudFxuICAgICAgICAgICAgICBlbmQgPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBFeHRlbnNpb24gZG9lcyBub3QgbWF0Y2gsIHNvIG91ciByZXN1bHQgaXMgdGhlIGVudGlyZSBwYXRoXG4gICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgIGV4dElkeCA9IC0xO1xuICAgICAgICAgICAgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPT09IGVuZCkgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICBlbHNlIGlmIChlbmQgPT09IC0xKSBlbmQgPSBwYXRoLmxlbmd0aDtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gc3RhcnQ7IC0taSkge1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaSkpKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZW5kID09PSAtMSkge1xuICAgICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAgIC8vIHBhdGggY29tcG9uZW50XG4gICAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgICBlbmQgPSBpICsgMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW5kID09PSAtMSkgcmV0dXJuIFwiXCI7XG4gICAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnQsIGVuZCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGV4dGVuc2lvbiBvZiB0aGUgYHBhdGhgIHdpdGggbGVhZGluZyBwZXJpb2QuXG4gKiBAcGFyYW0gcGF0aCB3aXRoIGV4dGVuc2lvblxuICogQHJldHVybnMgZXh0ZW5zaW9uIChleC4gZm9yIGBmaWxlLnRzYCByZXR1cm5zIGAudHNgKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0bmFtZShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgc3RhcnREb3QgPSAtMTtcbiAgbGV0IHN0YXJ0UGFydCA9IDA7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIC8vIFRyYWNrIHRoZSBzdGF0ZSBvZiBjaGFyYWN0ZXJzIChpZiBhbnkpIHdlIHNlZSBiZWZvcmUgb3VyIGZpcnN0IGRvdCBhbmRcbiAgLy8gYWZ0ZXIgYW55IHBhdGggc2VwYXJhdG9yIHdlIGZpbmRcbiAgbGV0IHByZURvdFN0YXRlID0gMDtcblxuICAvLyBDaGVjayBmb3IgYSBkcml2ZSBsZXR0ZXIgcHJlZml4IHNvIGFzIG5vdCB0byBtaXN0YWtlIHRoZSBmb2xsb3dpbmdcbiAgLy8gcGF0aCBzZXBhcmF0b3IgYXMgYW4gZXh0cmEgc2VwYXJhdG9yIGF0IHRoZSBlbmQgb2YgdGhlIHBhdGggdGhhdCBjYW4gYmVcbiAgLy8gZGlzcmVnYXJkZWRcblxuICBpZiAoXG4gICAgcGF0aC5sZW5ndGggPj0gMiAmJlxuICAgIHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTiAmJlxuICAgIGlzV2luZG93c0RldmljZVJvb3QocGF0aC5jaGFyQ29kZUF0KDApKVxuICApIHtcbiAgICBzdGFydCA9IHN0YXJ0UGFydCA9IDI7XG4gIH1cblxuICBmb3IgKGxldCBpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IHN0YXJ0OyAtLWkpIHtcbiAgICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAvLyBzZXBhcmF0b3JzIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZywgc3RvcCBub3dcbiAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgIHN0YXJ0UGFydCA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoZW5kID09PSAtMSkge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3IsIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91clxuICAgICAgLy8gZXh0ZW5zaW9uXG4gICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgIGVuZCA9IGkgKyAxO1xuICAgIH1cbiAgICBpZiAoY29kZSA9PT0gQ0hBUl9ET1QpIHtcbiAgICAgIC8vIElmIHRoaXMgaXMgb3VyIGZpcnN0IGRvdCwgbWFyayBpdCBhcyB0aGUgc3RhcnQgb2Ygb3VyIGV4dGVuc2lvblxuICAgICAgaWYgKHN0YXJ0RG90ID09PSAtMSkgc3RhcnREb3QgPSBpO1xuICAgICAgZWxzZSBpZiAocHJlRG90U3RhdGUgIT09IDEpIHByZURvdFN0YXRlID0gMTtcbiAgICB9IGVsc2UgaWYgKHN0YXJ0RG90ICE9PSAtMSkge1xuICAgICAgLy8gV2Ugc2F3IGEgbm9uLWRvdCBhbmQgbm9uLXBhdGggc2VwYXJhdG9yIGJlZm9yZSBvdXIgZG90LCBzbyB3ZSBzaG91bGRcbiAgICAgIC8vIGhhdmUgYSBnb29kIGNoYW5jZSBhdCBoYXZpbmcgYSBub24tZW1wdHkgZXh0ZW5zaW9uXG4gICAgICBwcmVEb3RTdGF0ZSA9IC0xO1xuICAgIH1cbiAgfVxuXG4gIGlmIChcbiAgICBzdGFydERvdCA9PT0gLTEgfHxcbiAgICBlbmQgPT09IC0xIHx8XG4gICAgLy8gV2Ugc2F3IGEgbm9uLWRvdCBjaGFyYWN0ZXIgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBkb3RcbiAgICBwcmVEb3RTdGF0ZSA9PT0gMCB8fFxuICAgIC8vIFRoZSAocmlnaHQtbW9zdCkgdHJpbW1lZCBwYXRoIGNvbXBvbmVudCBpcyBleGFjdGx5ICcuLidcbiAgICAocHJlRG90U3RhdGUgPT09IDEgJiYgc3RhcnREb3QgPT09IGVuZCAtIDEgJiYgc3RhcnREb3QgPT09IHN0YXJ0UGFydCArIDEpXG4gICkge1xuICAgIHJldHVybiBcIlwiO1xuICB9XG4gIHJldHVybiBwYXRoLnNsaWNlKHN0YXJ0RG90LCBlbmQpO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgcGF0aCBmcm9tIGBGb3JtYXRJbnB1dFBhdGhPYmplY3RgIG9iamVjdC5cbiAqIEBwYXJhbSBwYXRoT2JqZWN0IHdpdGggcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0KHBhdGhPYmplY3Q6IEZvcm1hdElucHV0UGF0aE9iamVjdCk6IHN0cmluZyB7XG4gIGlmIChwYXRoT2JqZWN0ID09PSBudWxsIHx8IHR5cGVvZiBwYXRoT2JqZWN0ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIGBUaGUgXCJwYXRoT2JqZWN0XCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIE9iamVjdC4gUmVjZWl2ZWQgdHlwZSAke3R5cGVvZiBwYXRoT2JqZWN0fWAsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gX2Zvcm1hdChcIlxcXFxcIiwgcGF0aE9iamVjdCk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgYFBhcnNlZFBhdGhgIG9iamVjdCBvZiB0aGUgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gcHJvY2Vzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2UocGF0aDogc3RyaW5nKTogUGFyc2VkUGF0aCB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgY29uc3QgcmV0OiBQYXJzZWRQYXRoID0geyByb290OiBcIlwiLCBkaXI6IFwiXCIsIGJhc2U6IFwiXCIsIGV4dDogXCJcIiwgbmFtZTogXCJcIiB9O1xuXG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gcmV0O1xuXG4gIGxldCByb290RW5kID0gMDtcbiAgbGV0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG5cbiAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICBpZiAobGVuID4gMSkge1xuICAgIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgIHJvb3RFbmQgPSAxO1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICBsZXQgaiA9IDI7XG4gICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIHBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgIGlmICghaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogPT09IGxlbikge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgb25seVxuXG4gICAgICAgICAgICAgIHJvb3RFbmQgPSBqO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCB3aXRoIGxlZnRvdmVyc1xuXG4gICAgICAgICAgICAgIHJvb3RFbmQgPSBqICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgcm9vdEVuZCA9IDI7XG4gICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSB7XG4gICAgICAgICAgICBpZiAobGVuID09PSAzKSB7XG4gICAgICAgICAgICAgIC8vIGBwYXRoYCBjb250YWlucyBqdXN0IGEgZHJpdmUgcm9vdCwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgICAgICAgICAgICAvLyB1bm5lY2Vzc2FyeSB3b3JrXG4gICAgICAgICAgICAgIHJldC5yb290ID0gcmV0LmRpciA9IHBhdGg7XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByb290RW5kID0gMztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBkcml2ZSByb290LCBleGl0IGVhcmx5IHRvIGF2b2lkXG4gICAgICAgICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgICAgICAgIHJldC5yb290ID0gcmV0LmRpciA9IHBhdGg7XG4gICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yLCBleGl0IGVhcmx5IHRvIGF2b2lkXG4gICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgIHJldC5yb290ID0gcmV0LmRpciA9IHBhdGg7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIGlmIChyb290RW5kID4gMCkgcmV0LnJvb3QgPSBwYXRoLnNsaWNlKDAsIHJvb3RFbmQpO1xuXG4gIGxldCBzdGFydERvdCA9IC0xO1xuICBsZXQgc3RhcnRQYXJ0ID0gcm9vdEVuZDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGkgPSBwYXRoLmxlbmd0aCAtIDE7XG5cbiAgLy8gVHJhY2sgdGhlIHN0YXRlIG9mIGNoYXJhY3RlcnMgKGlmIGFueSkgd2Ugc2VlIGJlZm9yZSBvdXIgZmlyc3QgZG90IGFuZFxuICAvLyBhZnRlciBhbnkgcGF0aCBzZXBhcmF0b3Igd2UgZmluZFxuICBsZXQgcHJlRG90U3RhdGUgPSAwO1xuXG4gIC8vIEdldCBub24tZGlyIGluZm9cbiAgZm9yICg7IGkgPj0gcm9vdEVuZDsgLS1pKSB7XG4gICAgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICBpZiAoZW5kICE9PSAtMSkge1xuICAgICAgcmV0LmJhc2UgPSByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBlbmQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBzdGFydERvdCk7XG4gICAgcmV0LmJhc2UgPSBwYXRoLnNsaWNlKHN0YXJ0UGFydCwgZW5kKTtcbiAgICByZXQuZXh0ID0gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbiAgfVxuXG4gIC8vIElmIHRoZSBkaXJlY3RvcnkgaXMgdGhlIHJvb3QsIHVzZSB0aGUgZW50aXJlIHJvb3QgYXMgdGhlIGBkaXJgIGluY2x1ZGluZ1xuICAvLyB0aGUgdHJhaWxpbmcgc2xhc2ggaWYgYW55IChgQzpcXGFiY2AgLT4gYEM6XFxgKS4gT3RoZXJ3aXNlLCBzdHJpcCBvdXQgdGhlXG4gIC8vIHRyYWlsaW5nIHNsYXNoIChgQzpcXGFiY1xcZGVmYCAtPiBgQzpcXGFiY2ApLlxuICBpZiAoc3RhcnRQYXJ0ID4gMCAmJiBzdGFydFBhcnQgIT09IHJvb3RFbmQpIHtcbiAgICByZXQuZGlyID0gcGF0aC5zbGljZSgwLCBzdGFydFBhcnQgLSAxKTtcbiAgfSBlbHNlIHJldC5kaXIgPSByZXQucm9vdDtcblxuICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgZmlsZSBVUkwgdG8gYSBwYXRoIHN0cmluZy5cbiAqXG4gKiBgYGB0c1xuICogICAgICBpbXBvcnQgeyBmcm9tRmlsZVVybCB9IGZyb20gXCIuL3dpbjMyLnRzXCI7XG4gKiAgICAgIGZyb21GaWxlVXJsKFwiZmlsZTovLy9ob21lL2Zvb1wiKTsgLy8gXCJcXFxcaG9tZVxcXFxmb29cIlxuICogICAgICBmcm9tRmlsZVVybChcImZpbGU6Ly8vQzovVXNlcnMvZm9vXCIpOyAvLyBcIkM6XFxcXFVzZXJzXFxcXGZvb1wiXG4gKiAgICAgIGZyb21GaWxlVXJsKFwiZmlsZTovL2xvY2FsaG9zdC9ob21lL2Zvb1wiKTsgLy8gXCJcXFxcXFxcXGxvY2FsaG9zdFxcXFxob21lXFxcXGZvb1wiXG4gKiBgYGBcbiAqIEBwYXJhbSB1cmwgb2YgYSBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUZpbGVVcmwodXJsOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICB1cmwgPSB1cmwgaW5zdGFuY2VvZiBVUkwgPyB1cmwgOiBuZXcgVVJMKHVybCk7XG4gIGlmICh1cmwucHJvdG9jb2wgIT0gXCJmaWxlOlwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYSBmaWxlIFVSTC5cIik7XG4gIH1cbiAgbGV0IHBhdGggPSBkZWNvZGVVUklDb21wb25lbnQoXG4gICAgdXJsLnBhdGhuYW1lLnJlcGxhY2UoL1xcLy9nLCBcIlxcXFxcIikucmVwbGFjZSgvJSg/IVswLTlBLUZhLWZdezJ9KS9nLCBcIiUyNVwiKSxcbiAgKS5yZXBsYWNlKC9eXFxcXCooW0EtWmEtel06KShcXFxcfCQpLywgXCIkMVxcXFxcIik7XG4gIGlmICh1cmwuaG9zdG5hbWUgIT0gXCJcIikge1xuICAgIC8vIE5vdGU6IFRoZSBgVVJMYCBpbXBsZW1lbnRhdGlvbiBndWFyYW50ZWVzIHRoYXQgdGhlIGRyaXZlIGxldHRlciBhbmRcbiAgICAvLyBob3N0bmFtZSBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiBPdGhlcndpc2UgaXQgd291bGQgbm90IGhhdmUgYmVlbiB2YWxpZFxuICAgIC8vIHRvIGFwcGVuZCB0aGUgaG9zdG5hbWUgYW5kIHBhdGggbGlrZSB0aGlzLlxuICAgIHBhdGggPSBgXFxcXFxcXFwke3VybC5ob3N0bmFtZX0ke3BhdGh9YDtcbiAgfVxuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHBhdGggc3RyaW5nIHRvIGEgZmlsZSBVUkwuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgdG9GaWxlVXJsIH0gZnJvbSBcIi4vd2luMzIudHNcIjtcbiAqICAgICAgdG9GaWxlVXJsKFwiXFxcXGhvbWVcXFxcZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9ob21lL2Zvb1wiKVxuICogICAgICB0b0ZpbGVVcmwoXCJDOlxcXFxVc2Vyc1xcXFxmb29cIik7IC8vIG5ldyBVUkwoXCJmaWxlOi8vL0M6L1VzZXJzL2Zvb1wiKVxuICogICAgICB0b0ZpbGVVcmwoXCJcXFxcXFxcXDEyNy4wLjAuMVxcXFxob21lXFxcXGZvb1wiKTsgLy8gbmV3IFVSTChcImZpbGU6Ly8xMjcuMC4wLjEvaG9tZS9mb29cIilcbiAqIGBgYFxuICogQHBhcmFtIHBhdGggdG8gY29udmVydCB0byBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9GaWxlVXJsKHBhdGg6IHN0cmluZyk6IFVSTCB7XG4gIGlmICghaXNBYnNvbHV0ZShwYXRoKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNdXN0IGJlIGFuIGFic29sdXRlIHBhdGguXCIpO1xuICB9XG4gIGNvbnN0IFssIGhvc3RuYW1lLCBwYXRobmFtZV0gPSBwYXRoLm1hdGNoKFxuICAgIC9eKD86Wy9cXFxcXXsyfShbXi9cXFxcXSspKD89Wy9cXFxcXSg/OlteL1xcXFxdfCQpKSk/KC4qKS8sXG4gICkhO1xuICBjb25zdCB1cmwgPSBuZXcgVVJMKFwiZmlsZTovLy9cIik7XG4gIHVybC5wYXRobmFtZSA9IGVuY29kZVdoaXRlc3BhY2UocGF0aG5hbWUucmVwbGFjZSgvJS9nLCBcIiUyNVwiKSk7XG4gIGlmIChob3N0bmFtZSAhPSBudWxsICYmIGhvc3RuYW1lICE9IFwibG9jYWxob3N0XCIpIHtcbiAgICB1cmwuaG9zdG5hbWUgPSBob3N0bmFtZTtcbiAgICBpZiAoIXVybC5ob3N0bmFtZSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgaG9zdG5hbWUuXCIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdXJsO1xufVxuIiwiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QsIFBhcnNlZFBhdGggfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQgeyBDSEFSX0RPVCwgQ0hBUl9GT1JXQVJEX1NMQVNIIH0gZnJvbSBcIi4vX2NvbnN0YW50cy50c1wiO1xuXG5pbXBvcnQge1xuICBfZm9ybWF0LFxuICBhc3NlcnRQYXRoLFxuICBlbmNvZGVXaGl0ZXNwYWNlLFxuICBpc1Bvc2l4UGF0aFNlcGFyYXRvcixcbiAgbm9ybWFsaXplU3RyaW5nLFxufSBmcm9tIFwiLi9fdXRpbC50c1wiO1xuXG5leHBvcnQgY29uc3Qgc2VwID0gXCIvXCI7XG5leHBvcnQgY29uc3QgZGVsaW1pdGVyID0gXCI6XCI7XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8qKlxuICogUmVzb2x2ZXMgYHBhdGhTZWdtZW50c2AgaW50byBhbiBhYnNvbHV0ZSBwYXRoLlxuICogQHBhcmFtIHBhdGhTZWdtZW50cyBhbiBhcnJheSBvZiBwYXRoIHNlZ21lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlKC4uLnBhdGhTZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICBsZXQgcmVzb2x2ZWRQYXRoID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTEgJiYgIXJlc29sdmVkQWJzb2x1dGU7IGktLSkge1xuICAgIGxldCBwYXRoOiBzdHJpbmc7XG5cbiAgICBpZiAoaSA+PSAwKSBwYXRoID0gcGF0aFNlZ21lbnRzW2ldO1xuICAgIGVsc2Uge1xuICAgICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICAgIGNvbnN0IHsgRGVubyB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gICAgICBpZiAodHlwZW9mIERlbm8/LmN3ZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIHJlbGF0aXZlIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcbiAgICB9XG5cbiAgICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBlbnRyaWVzXG4gICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXNvbHZlZFBhdGggPSBgJHtwYXRofS8ke3Jlc29sdmVkUGF0aH1gO1xuICAgIHJlc29sdmVkQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZVN0cmluZyhcbiAgICByZXNvbHZlZFBhdGgsXG4gICAgIXJlc29sdmVkQWJzb2x1dGUsXG4gICAgXCIvXCIsXG4gICAgaXNQb3NpeFBhdGhTZXBhcmF0b3IsXG4gICk7XG5cbiAgaWYgKHJlc29sdmVkQWJzb2x1dGUpIHtcbiAgICBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiBgLyR7cmVzb2x2ZWRQYXRofWA7XG4gICAgZWxzZSByZXR1cm4gXCIvXCI7XG4gIH0gZWxzZSBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiByZXNvbHZlZFBhdGg7XG4gIGVsc2UgcmV0dXJuIFwiLlwiO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSB0aGUgYHBhdGhgLCByZXNvbHZpbmcgYCcuLidgIGFuZCBgJy4nYCBzZWdtZW50cy5cbiAqIEBwYXJhbSBwYXRoIHRvIGJlIG5vcm1hbGl6ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuXG4gIGNvbnN0IGlzQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgY29uc3QgdHJhaWxpbmdTZXBhcmF0b3IgPVxuICAgIHBhdGguY2hhckNvZGVBdChwYXRoLmxlbmd0aCAtIDEpID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHBhdGggPSBub3JtYWxpemVTdHJpbmcocGF0aCwgIWlzQWJzb2x1dGUsIFwiL1wiLCBpc1Bvc2l4UGF0aFNlcGFyYXRvcik7XG5cbiAgaWYgKHBhdGgubGVuZ3RoID09PSAwICYmICFpc0Fic29sdXRlKSBwYXRoID0gXCIuXCI7XG4gIGlmIChwYXRoLmxlbmd0aCA+IDAgJiYgdHJhaWxpbmdTZXBhcmF0b3IpIHBhdGggKz0gXCIvXCI7XG5cbiAgaWYgKGlzQWJzb2x1dGUpIHJldHVybiBgLyR7cGF0aH1gO1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBWZXJpZmllcyB3aGV0aGVyIHByb3ZpZGVkIHBhdGggaXMgYWJzb2x1dGVcbiAqIEBwYXJhbSBwYXRoIHRvIGJlIHZlcmlmaWVkIGFzIGFic29sdXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Fic29sdXRlKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICByZXR1cm4gcGF0aC5sZW5ndGggPiAwICYmIHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xufVxuXG4vKipcbiAqIEpvaW4gYWxsIGdpdmVuIGEgc2VxdWVuY2Ugb2YgYHBhdGhzYCx0aGVuIG5vcm1hbGl6ZXMgdGhlIHJlc3VsdGluZyBwYXRoLlxuICogQHBhcmFtIHBhdGhzIHRvIGJlIGpvaW5lZCBhbmQgbm9ybWFsaXplZFxuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbiguLi5wYXRoczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAocGF0aHMubGVuZ3RoID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCBqb2luZWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBhdGhzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgIGFzc2VydFBhdGgocGF0aCk7XG4gICAgaWYgKHBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFqb2luZWQpIGpvaW5lZCA9IHBhdGg7XG4gICAgICBlbHNlIGpvaW5lZCArPSBgLyR7cGF0aH1gO1xuICAgIH1cbiAgfVxuICBpZiAoIWpvaW5lZCkgcmV0dXJuIFwiLlwiO1xuICByZXR1cm4gbm9ybWFsaXplKGpvaW5lZCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSByZWxhdGl2ZSBwYXRoIGZyb20gYGZyb21gIHRvIGB0b2AgYmFzZWQgb24gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSBmcm9tIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICogQHBhcmFtIHRvIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpdmUoZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChmcm9tKTtcbiAgYXNzZXJ0UGF0aCh0byk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICBmcm9tID0gcmVzb2x2ZShmcm9tKTtcbiAgdG8gPSByZXNvbHZlKHRvKTtcblxuICBpZiAoZnJvbSA9PT0gdG8pIHJldHVybiBcIlwiO1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IGZyb21TdGFydCA9IDE7XG4gIGNvbnN0IGZyb21FbmQgPSBmcm9tLmxlbmd0aDtcbiAgZm9yICg7IGZyb21TdGFydCA8IGZyb21FbmQ7ICsrZnJvbVN0YXJ0KSB7XG4gICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQpICE9PSBDSEFSX0ZPUldBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IGZyb21MZW4gPSBmcm9tRW5kIC0gZnJvbVN0YXJ0O1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IHRvU3RhcnQgPSAxO1xuICBjb25zdCB0b0VuZCA9IHRvLmxlbmd0aDtcbiAgZm9yICg7IHRvU3RhcnQgPCB0b0VuZDsgKyt0b1N0YXJ0KSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCkgIT09IENIQVJfRk9SV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgdG9MZW4gPSB0b0VuZCAtIHRvU3RhcnQ7XG5cbiAgLy8gQ29tcGFyZSBwYXRocyB0byBmaW5kIHRoZSBsb25nZXN0IGNvbW1vbiBwYXRoIGZyb20gcm9vdFxuICBjb25zdCBsZW5ndGggPSBmcm9tTGVuIDwgdG9MZW4gPyBmcm9tTGVuIDogdG9MZW47XG4gIGxldCBsYXN0Q29tbW9uU2VwID0gLTE7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPD0gbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gbGVuZ3RoKSB7XG4gICAgICBpZiAodG9MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIGV4YWN0IGJhc2UgcGF0aCBmb3IgYHRvYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXInOyB0bz0nL2Zvby9iYXIvYmF6J1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIHJvb3RcbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nLyc7IHRvPScvZm9vJ1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZnJvbUxlbiA+IGxlbmd0aCkge1xuICAgICAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSBleGFjdCBiYXNlIHBhdGggZm9yIGBmcm9tYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXIvYmF6JzsgdG89Jy9mb28vYmFyJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSByb290LlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPScvZm9vJzsgdG89Jy8nXG4gICAgICAgICAgbGFzdENvbW1vblNlcCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ29kZSA9IGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKTtcbiAgICBjb25zdCB0b0NvZGUgPSB0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKTtcbiAgICBpZiAoZnJvbUNvZGUgIT09IHRvQ29kZSkgYnJlYWs7XG4gICAgZWxzZSBpZiAoZnJvbUNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkgbGFzdENvbW1vblNlcCA9IGk7XG4gIH1cblxuICBsZXQgb3V0ID0gXCJcIjtcbiAgLy8gR2VuZXJhdGUgdGhlIHJlbGF0aXZlIHBhdGggYmFzZWQgb24gdGhlIHBhdGggZGlmZmVyZW5jZSBiZXR3ZWVuIGB0b2BcbiAgLy8gYW5kIGBmcm9tYFxuICBmb3IgKGkgPSBmcm9tU3RhcnQgKyBsYXN0Q29tbW9uU2VwICsgMTsgaSA8PSBmcm9tRW5kOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gZnJvbUVuZCB8fCBmcm9tLmNoYXJDb2RlQXQoaSkgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgaWYgKG91dC5sZW5ndGggPT09IDApIG91dCArPSBcIi4uXCI7XG4gICAgICBlbHNlIG91dCArPSBcIi8uLlwiO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSwgYXBwZW5kIHRoZSByZXN0IG9mIHRoZSBkZXN0aW5hdGlvbiAoYHRvYCkgcGF0aCB0aGF0IGNvbWVzIGFmdGVyXG4gIC8vIHRoZSBjb21tb24gcGF0aCBwYXJ0c1xuICBpZiAob3V0Lmxlbmd0aCA+IDApIHJldHVybiBvdXQgKyB0by5zbGljZSh0b1N0YXJ0ICsgbGFzdENvbW1vblNlcCk7XG4gIGVsc2Uge1xuICAgIHRvU3RhcnQgKz0gbGFzdENvbW1vblNlcDtcbiAgICBpZiAodG8uY2hhckNvZGVBdCh0b1N0YXJ0KSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSArK3RvU3RhcnQ7XG4gICAgcmV0dXJuIHRvLnNsaWNlKHRvU3RhcnQpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCB0byBhIG5hbWVzcGFjZSBwYXRoXG4gKiBAcGFyYW0gcGF0aCB0byByZXNvbHZlIHRvIG5hbWVzcGFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9OYW1lc3BhY2VkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBOb24tb3Agb24gcG9zaXggc3lzdGVtc1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGRpcmVjdG9yeSBuYW1lIG9mIGEgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gZGV0ZXJtaW5lIG5hbWUgZm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuICBjb25zdCBoYXNSb290ID0gcGF0aC5jaGFyQ29kZUF0KDApID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGZvciAobGV0IGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMTsgLS1pKSB7XG4gICAgaWYgKHBhdGguY2hhckNvZGVBdChpKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3JcbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbmQgPT09IC0xKSByZXR1cm4gaGFzUm9vdCA/IFwiL1wiIDogXCIuXCI7XG4gIGlmIChoYXNSb290ICYmIGVuZCA9PT0gMSkgcmV0dXJuIFwiLy9cIjtcbiAgcmV0dXJuIHBhdGguc2xpY2UoMCwgZW5kKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGxhc3QgcG9ydGlvbiBvZiBhIGBwYXRoYC4gVHJhaWxpbmcgZGlyZWN0b3J5IHNlcGFyYXRvcnMgYXJlIGlnbm9yZWQuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKiBAcGFyYW0gZXh0IG9mIHBhdGggZGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlbmFtZShwYXRoOiBzdHJpbmcsIGV4dCA9IFwiXCIpOiBzdHJpbmcge1xuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZXh0XCIgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZycpO1xuICB9XG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGk6IG51bWJlcjtcblxuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgZXh0Lmxlbmd0aCA+IDAgJiYgZXh0Lmxlbmd0aCA8PSBwYXRoLmxlbmd0aCkge1xuICAgIGlmIChleHQubGVuZ3RoID09PSBwYXRoLmxlbmd0aCAmJiBleHQgPT09IHBhdGgpIHJldHVybiBcIlwiO1xuICAgIGxldCBleHRJZHggPSBleHQubGVuZ3RoIC0gMTtcbiAgICBsZXQgZmlyc3ROb25TbGFzaEVuZCA9IC0xO1xuICAgIGZvciAoaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaXJzdE5vblNsYXNoRW5kID09PSAtMSkge1xuICAgICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCByZW1lbWJlciB0aGlzIGluZGV4IGluIGNhc2VcbiAgICAgICAgICAvLyB3ZSBuZWVkIGl0IGlmIHRoZSBleHRlbnNpb24gZW5kcyB1cCBub3QgbWF0Y2hpbmdcbiAgICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgICBmaXJzdE5vblNsYXNoRW5kID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dElkeCA+PSAwKSB7XG4gICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIHRoZSBleHBsaWNpdCBleHRlbnNpb25cbiAgICAgICAgICBpZiAoY29kZSA9PT0gZXh0LmNoYXJDb2RlQXQoZXh0SWR4KSkge1xuICAgICAgICAgICAgaWYgKC0tZXh0SWR4ID09PSAtMSkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIHRoZSBleHRlbnNpb24sIHNvIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91ciBwYXRoXG4gICAgICAgICAgICAgIC8vIGNvbXBvbmVudFxuICAgICAgICAgICAgICBlbmQgPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBFeHRlbnNpb24gZG9lcyBub3QgbWF0Y2gsIHNvIG91ciByZXN1bHQgaXMgdGhlIGVudGlyZSBwYXRoXG4gICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgIGV4dElkeCA9IC0xO1xuICAgICAgICAgICAgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPT09IGVuZCkgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICBlbHNlIGlmIChlbmQgPT09IC0xKSBlbmQgPSBwYXRoLmxlbmd0aDtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgICAgLy8gcGF0aCBjb21wb25lbnRcbiAgICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICAgIGVuZCA9IGkgKyAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbmQgPT09IC0xKSByZXR1cm4gXCJcIjtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgZXh0ZW5zaW9uIG9mIHRoZSBgcGF0aGAgd2l0aCBsZWFkaW5nIHBlcmlvZC5cbiAqIEBwYXJhbSBwYXRoIHdpdGggZXh0ZW5zaW9uXG4gKiBAcmV0dXJucyBleHRlbnNpb24gKGV4LiBmb3IgYGZpbGUudHNgIHJldHVybnMgYC50c2ApXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGxldCBzdGFydERvdCA9IC0xO1xuICBsZXQgc3RhcnRQYXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgLy8gVHJhY2sgdGhlIHN0YXRlIG9mIGNoYXJhY3RlcnMgKGlmIGFueSkgd2Ugc2VlIGJlZm9yZSBvdXIgZmlyc3QgZG90IGFuZFxuICAvLyBhZnRlciBhbnkgcGF0aCBzZXBhcmF0b3Igd2UgZmluZFxuICBsZXQgcHJlRG90U3RhdGUgPSAwO1xuICBmb3IgKGxldCBpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgc3RhcnRQYXJ0ID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25cbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgZW5kID0gaSArIDE7XG4gICAgfVxuICAgIGlmIChjb2RlID09PSBDSEFSX0RPVCkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBvdXIgZmlyc3QgZG90LCBtYXJrIGl0IGFzIHRoZSBzdGFydCBvZiBvdXIgZXh0ZW5zaW9uXG4gICAgICBpZiAoc3RhcnREb3QgPT09IC0xKSBzdGFydERvdCA9IGk7XG4gICAgICBlbHNlIGlmIChwcmVEb3RTdGF0ZSAhPT0gMSkgcHJlRG90U3RhdGUgPSAxO1xuICAgIH0gZWxzZSBpZiAoc3RhcnREb3QgIT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgYSBub24tZG90IGFuZCBub24tcGF0aCBzZXBhcmF0b3IgYmVmb3JlIG91ciBkb3QsIHNvIHdlIHNob3VsZFxuICAgICAgLy8gaGF2ZSBhIGdvb2QgY2hhbmNlIGF0IGhhdmluZyBhIG5vbi1lbXB0eSBleHRlbnNpb25cbiAgICAgIHByZURvdFN0YXRlID0gLTE7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIHN0YXJ0RG90ID09PSAtMSB8fFxuICAgIGVuZCA9PT0gLTEgfHxcbiAgICAvLyBXZSBzYXcgYSBub24tZG90IGNoYXJhY3RlciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGRvdFxuICAgIHByZURvdFN0YXRlID09PSAwIHx8XG4gICAgLy8gVGhlIChyaWdodC1tb3N0KSB0cmltbWVkIHBhdGggY29tcG9uZW50IGlzIGV4YWN0bHkgJy4uJ1xuICAgIChwcmVEb3RTdGF0ZSA9PT0gMSAmJiBzdGFydERvdCA9PT0gZW5kIC0gMSAmJiBzdGFydERvdCA9PT0gc3RhcnRQYXJ0ICsgMSlcbiAgKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbiAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnREb3QsIGVuZCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBwYXRoIGZyb20gYEZvcm1hdElucHV0UGF0aE9iamVjdGAgb2JqZWN0LlxuICogQHBhcmFtIHBhdGhPYmplY3Qgd2l0aCBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXQocGF0aE9iamVjdDogRm9ybWF0SW5wdXRQYXRoT2JqZWN0KTogc3RyaW5nIHtcbiAgaWYgKHBhdGhPYmplY3QgPT09IG51bGwgfHwgdHlwZW9mIHBhdGhPYmplY3QgIT09IFwib2JqZWN0XCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYFRoZSBcInBhdGhPYmplY3RcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICR7dHlwZW9mIHBhdGhPYmplY3R9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBfZm9ybWF0KFwiL1wiLCBwYXRoT2JqZWN0KTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBgUGFyc2VkUGF0aGAgb2JqZWN0IG9mIHRoZSBgcGF0aGAuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShwYXRoOiBzdHJpbmcpOiBQYXJzZWRQYXRoIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICBjb25zdCByZXQ6IFBhcnNlZFBhdGggPSB7IHJvb3Q6IFwiXCIsIGRpcjogXCJcIiwgYmFzZTogXCJcIiwgZXh0OiBcIlwiLCBuYW1lOiBcIlwiIH07XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJldDtcbiAgY29uc3QgaXNBYnNvbHV0ZSA9IHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xuICBsZXQgc3RhcnQ6IG51bWJlcjtcbiAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICByZXQucm9vdCA9IFwiL1wiO1xuICAgIHN0YXJ0ID0gMTtcbiAgfSBlbHNlIHtcbiAgICBzdGFydCA9IDA7XG4gIH1cbiAgbGV0IHN0YXJ0RG90ID0gLTE7XG4gIGxldCBzdGFydFBhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICBsZXQgaSA9IHBhdGgubGVuZ3RoIC0gMTtcblxuICAvLyBUcmFjayB0aGUgc3RhdGUgb2YgY2hhcmFjdGVycyAoaWYgYW55KSB3ZSBzZWUgYmVmb3JlIG91ciBmaXJzdCBkb3QgYW5kXG4gIC8vIGFmdGVyIGFueSBwYXRoIHNlcGFyYXRvciB3ZSBmaW5kXG4gIGxldCBwcmVEb3RTdGF0ZSA9IDA7XG5cbiAgLy8gR2V0IG5vbi1kaXIgaW5mb1xuICBmb3IgKDsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICBpZiAoZW5kICE9PSAtMSkge1xuICAgICAgaWYgKHN0YXJ0UGFydCA9PT0gMCAmJiBpc0Fic29sdXRlKSB7XG4gICAgICAgIHJldC5iYXNlID0gcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIGVuZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQuYmFzZSA9IHJldC5uYW1lID0gcGF0aC5zbGljZShzdGFydFBhcnQsIGVuZCk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChzdGFydFBhcnQgPT09IDAgJiYgaXNBYnNvbHV0ZSkge1xuICAgICAgcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIHN0YXJ0RG90KTtcbiAgICAgIHJldC5iYXNlID0gcGF0aC5zbGljZSgxLCBlbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBzdGFydERvdCk7XG4gICAgICByZXQuYmFzZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBlbmQpO1xuICAgIH1cbiAgICByZXQuZXh0ID0gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbiAgfVxuXG4gIGlmIChzdGFydFBhcnQgPiAwKSByZXQuZGlyID0gcGF0aC5zbGljZSgwLCBzdGFydFBhcnQgLSAxKTtcbiAgZWxzZSBpZiAoaXNBYnNvbHV0ZSkgcmV0LmRpciA9IFwiL1wiO1xuXG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBmaWxlIFVSTCB0byBhIHBhdGggc3RyaW5nLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IGZyb21GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgZnJvbUZpbGVVcmwoXCJmaWxlOi8vL2hvbWUvZm9vXCIpOyAvLyBcIi9ob21lL2Zvb1wiXG4gKiBgYGBcbiAqIEBwYXJhbSB1cmwgb2YgYSBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUZpbGVVcmwodXJsOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICB1cmwgPSB1cmwgaW5zdGFuY2VvZiBVUkwgPyB1cmwgOiBuZXcgVVJMKHVybCk7XG4gIGlmICh1cmwucHJvdG9jb2wgIT0gXCJmaWxlOlwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYSBmaWxlIFVSTC5cIik7XG4gIH1cbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChcbiAgICB1cmwucGF0aG5hbWUucmVwbGFjZSgvJSg/IVswLTlBLUZhLWZdezJ9KS9nLCBcIiUyNVwiKSxcbiAgKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHBhdGggc3RyaW5nIHRvIGEgZmlsZSBVUkwuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgdG9GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgdG9GaWxlVXJsKFwiL2hvbWUvZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9ob21lL2Zvb1wiKVxuICogYGBgXG4gKiBAcGFyYW0gcGF0aCB0byBjb252ZXJ0IHRvIGZpbGUgVVJMXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0ZpbGVVcmwocGF0aDogc3RyaW5nKTogVVJMIHtcbiAgaWYgKCFpc0Fic29sdXRlKHBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYW4gYWJzb2x1dGUgcGF0aC5cIik7XG4gIH1cbiAgY29uc3QgdXJsID0gbmV3IFVSTChcImZpbGU6Ly8vXCIpO1xuICB1cmwucGF0aG5hbWUgPSBlbmNvZGVXaGl0ZXNwYWNlKFxuICAgIHBhdGgucmVwbGFjZSgvJS9nLCBcIiUyNVwiKS5yZXBsYWNlKC9cXFxcL2csIFwiJTVDXCIpLFxuICApO1xuICByZXR1cm4gdXJsO1xufVxuIiwiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHsgaXNXaW5kb3dzLCBvc1R5cGUgfSBmcm9tIFwiLi4vX3V0aWwvb3MudHNcIjtcbmltcG9ydCB7IFNFUCwgU0VQX1BBVFRFUk4gfSBmcm9tIFwiLi9zZXBhcmF0b3IudHNcIjtcbmltcG9ydCAqIGFzIF93aW4zMiBmcm9tIFwiLi93aW4zMi50c1wiO1xuaW1wb3J0ICogYXMgX3Bvc2l4IGZyb20gXCIuL3Bvc2l4LnRzXCI7XG5pbXBvcnQgdHlwZSB7IE9TVHlwZSB9IGZyb20gXCIuLi9fdXRpbC9vcy50c1wiO1xuXG5jb25zdCBwYXRoID0gaXNXaW5kb3dzID8gX3dpbjMyIDogX3Bvc2l4O1xuY29uc3QgeyBqb2luLCBub3JtYWxpemUgfSA9IHBhdGg7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2xvYk9wdGlvbnMge1xuICAvKiogRXh0ZW5kZWQgZ2xvYiBzeW50YXguXG4gICAqIFNlZSBodHRwczovL3d3dy5saW51eGpvdXJuYWwuY29tL2NvbnRlbnQvYmFzaC1leHRlbmRlZC1nbG9iYmluZy4gRGVmYXVsdHNcbiAgICogdG8gdHJ1ZS4gKi9cbiAgZXh0ZW5kZWQ/OiBib29sZWFuO1xuICAvKiogR2xvYnN0YXIgc3ludGF4LlxuICAgKiBTZWUgaHR0cHM6Ly93d3cubGludXhqb3VybmFsLmNvbS9jb250ZW50L2dsb2JzdGFyLW5ldy1iYXNoLWdsb2JiaW5nLW9wdGlvbi5cbiAgICogSWYgZmFsc2UsIGAqKmAgaXMgdHJlYXRlZCBsaWtlIGAqYC4gRGVmYXVsdHMgdG8gdHJ1ZS4gKi9cbiAgZ2xvYnN0YXI/OiBib29sZWFuO1xuICAvKiogV2hldGhlciBnbG9ic3RhciBzaG91bGQgYmUgY2FzZSBpbnNlbnNpdGl2ZS4gKi9cbiAgY2FzZUluc2Vuc2l0aXZlPzogYm9vbGVhbjtcbiAgLyoqIE9wZXJhdGluZyBzeXN0ZW0uIERlZmF1bHRzIHRvIHRoZSBuYXRpdmUgT1MuICovXG4gIG9zPzogT1NUeXBlO1xufVxuXG5leHBvcnQgdHlwZSBHbG9iVG9SZWdFeHBPcHRpb25zID0gR2xvYk9wdGlvbnM7XG5cbmNvbnN0IHJlZ0V4cEVzY2FwZUNoYXJzID0gW1xuICBcIiFcIixcbiAgXCIkXCIsXG4gIFwiKFwiLFxuICBcIilcIixcbiAgXCIqXCIsXG4gIFwiK1wiLFxuICBcIi5cIixcbiAgXCI9XCIsXG4gIFwiP1wiLFxuICBcIltcIixcbiAgXCJcXFxcXCIsXG4gIFwiXlwiLFxuICBcIntcIixcbiAgXCJ8XCIsXG5dO1xuY29uc3QgcmFuZ2VFc2NhcGVDaGFycyA9IFtcIi1cIiwgXCJcXFxcXCIsIFwiXVwiXTtcblxuLyoqIENvbnZlcnQgYSBnbG9iIHN0cmluZyB0byBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAqXG4gKiBUcmllcyB0byBtYXRjaCBiYXNoIGdsb2IgZXhwYW5zaW9uIGFzIGNsb3NlbHkgYXMgcG9zc2libGUuXG4gKlxuICogQmFzaWMgZ2xvYiBzeW50YXg6XG4gKiAtIGAqYCAtIE1hdGNoZXMgZXZlcnl0aGluZyB3aXRob3V0IGxlYXZpbmcgdGhlIHBhdGggc2VnbWVudC5cbiAqIC0gYD9gIC0gTWF0Y2hlcyBhbnkgc2luZ2xlIGNoYXJhY3Rlci5cbiAqIC0gYHtmb28sYmFyfWAgLSBNYXRjaGVzIGBmb29gIG9yIGBiYXJgLlxuICogLSBgW2FiY2RdYCAtIE1hdGNoZXMgYGFgLCBgYmAsIGBjYCBvciBgZGAuXG4gKiAtIGBbYS1kXWAgLSBNYXRjaGVzIGBhYCwgYGJgLCBgY2Agb3IgYGRgLlxuICogLSBgWyFhYmNkXWAgLSBNYXRjaGVzIGFueSBzaW5nbGUgY2hhcmFjdGVyIGJlc2lkZXMgYGFgLCBgYmAsIGBjYCBvciBgZGAuXG4gKiAtIGBbWzo8Y2xhc3M+Ol1dYCAtIE1hdGNoZXMgYW55IGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gYDxjbGFzcz5gLlxuICogICAgIC0gYFtbOmFsbnVtOl1dYCAtIE1hdGNoZXMgYW55IGRpZ2l0IG9yIGxldHRlci5cbiAqICAgICAtIGBbWzpkaWdpdDpdYWJjXWAgLSBNYXRjaGVzIGFueSBkaWdpdCwgYGFgLCBgYmAgb3IgYGNgLlxuICogICAgIC0gU2VlIGh0dHBzOi8vZmFjZWxlc3N1c2VyLmdpdGh1Yi5pby93Y21hdGNoL2dsb2IvI3Bvc2l4LWNoYXJhY3Rlci1jbGFzc2VzXG4gKiAgICAgICBmb3IgYSBjb21wbGV0ZSBsaXN0IG9mIHN1cHBvcnRlZCBjaGFyYWN0ZXIgY2xhc3Nlcy5cbiAqIC0gYFxcYCAtIEVzY2FwZXMgdGhlIG5leHQgY2hhcmFjdGVyIGZvciBhbiBgb3NgIG90aGVyIHRoYW4gYFwid2luZG93c1wiYC5cbiAqIC0gXFxgIC0gRXNjYXBlcyB0aGUgbmV4dCBjaGFyYWN0ZXIgZm9yIGBvc2Agc2V0IHRvIGBcIndpbmRvd3NcImAuXG4gKiAtIGAvYCAtIFBhdGggc2VwYXJhdG9yLlxuICogLSBgXFxgIC0gQWRkaXRpb25hbCBwYXRoIHNlcGFyYXRvciBvbmx5IGZvciBgb3NgIHNldCB0byBgXCJ3aW5kb3dzXCJgLlxuICpcbiAqIEV4dGVuZGVkIHN5bnRheDpcbiAqIC0gUmVxdWlyZXMgYHsgZXh0ZW5kZWQ6IHRydWUgfWAuXG4gKiAtIGA/KGZvb3xiYXIpYCAtIE1hdGNoZXMgMCBvciAxIGluc3RhbmNlIG9mIGB7Zm9vLGJhcn1gLlxuICogLSBgQChmb298YmFyKWAgLSBNYXRjaGVzIDEgaW5zdGFuY2Ugb2YgYHtmb28sYmFyfWAuIFRoZXkgYmVoYXZlIHRoZSBzYW1lLlxuICogLSBgKihmb298YmFyKWAgLSBNYXRjaGVzIF9uXyBpbnN0YW5jZXMgb2YgYHtmb28sYmFyfWAuXG4gKiAtIGArKGZvb3xiYXIpYCAtIE1hdGNoZXMgX24gPiAwXyBpbnN0YW5jZXMgb2YgYHtmb28sYmFyfWAuXG4gKiAtIGAhKGZvb3xiYXIpYCAtIE1hdGNoZXMgYW55dGhpbmcgb3RoZXIgdGhhbiBge2ZvbyxiYXJ9YC5cbiAqIC0gU2VlIGh0dHBzOi8vd3d3LmxpbnV4am91cm5hbC5jb20vY29udGVudC9iYXNoLWV4dGVuZGVkLWdsb2JiaW5nLlxuICpcbiAqIEdsb2JzdGFyIHN5bnRheDpcbiAqIC0gUmVxdWlyZXMgYHsgZ2xvYnN0YXI6IHRydWUgfWAuXG4gKiAtIGAqKmAgLSBNYXRjaGVzIGFueSBudW1iZXIgb2YgYW55IHBhdGggc2VnbWVudHMuXG4gKiAgICAgLSBNdXN0IGNvbXByaXNlIGl0cyBlbnRpcmUgcGF0aCBzZWdtZW50IGluIHRoZSBwcm92aWRlZCBnbG9iLlxuICogLSBTZWUgaHR0cHM6Ly93d3cubGludXhqb3VybmFsLmNvbS9jb250ZW50L2dsb2JzdGFyLW5ldy1iYXNoLWdsb2JiaW5nLW9wdGlvbi5cbiAqXG4gKiBOb3RlIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqIC0gVGhlIGdlbmVyYXRlZCBgUmVnRXhwYCBpcyBhbmNob3JlZCBhdCBib3RoIHN0YXJ0IGFuZCBlbmQuXG4gKiAtIFJlcGVhdGluZyBhbmQgdHJhaWxpbmcgc2VwYXJhdG9ycyBhcmUgdG9sZXJhdGVkLiBUcmFpbGluZyBzZXBhcmF0b3JzIGluIHRoZVxuICogICBwcm92aWRlZCBnbG9iIGhhdmUgbm8gbWVhbmluZyBhbmQgYXJlIGRpc2NhcmRlZC5cbiAqIC0gQWJzb2x1dGUgZ2xvYnMgd2lsbCBvbmx5IG1hdGNoIGFic29sdXRlIHBhdGhzLCBldGMuXG4gKiAtIEVtcHR5IGdsb2JzIHdpbGwgbWF0Y2ggbm90aGluZy5cbiAqIC0gQW55IHNwZWNpYWwgZ2xvYiBzeW50YXggbXVzdCBiZSBjb250YWluZWQgdG8gb25lIHBhdGggc2VnbWVudC4gRm9yIGV4YW1wbGUsXG4gKiAgIGA/KGZvb3xiYXIvYmF6KWAgaXMgaW52YWxpZC4gVGhlIHNlcGFyYXRvciB3aWxsIHRha2UgcHJlY2VkZW5jZSBhbmQgdGhlXG4gKiAgIGZpcnN0IHNlZ21lbnQgZW5kcyB3aXRoIGFuIHVuY2xvc2VkIGdyb3VwLlxuICogLSBJZiBhIHBhdGggc2VnbWVudCBlbmRzIHdpdGggdW5jbG9zZWQgZ3JvdXBzIG9yIGEgZGFuZ2xpbmcgZXNjYXBlIHByZWZpeCwgYVxuICogICBwYXJzZSBlcnJvciBoYXMgb2NjdXJyZWQuIEV2ZXJ5IGNoYXJhY3RlciBmb3IgdGhhdCBzZWdtZW50IGlzIHRha2VuXG4gKiAgIGxpdGVyYWxseSBpbiB0aGlzIGV2ZW50LlxuICpcbiAqIExpbWl0YXRpb25zOlxuICogLSBBIG5lZ2F0aXZlIGdyb3VwIGxpa2UgYCEoZm9vfGJhcilgIHdpbGwgd3JvbmdseSBiZSBjb252ZXJ0ZWQgdG8gYSBuZWdhdGl2ZVxuICogICBsb29rLWFoZWFkIGZvbGxvd2VkIGJ5IGEgd2lsZGNhcmQuIFRoaXMgbWVhbnMgdGhhdCBgIShmb28pLmpzYCB3aWxsIHdyb25nbHlcbiAqICAgZmFpbCB0byBtYXRjaCBgZm9vYmFyLmpzYCwgZXZlbiB0aG91Z2ggYGZvb2JhcmAgaXMgbm90IGBmb29gLiBFZmZlY3RpdmVseSxcbiAqICAgYCEoZm9vfGJhcilgIGlzIHRyZWF0ZWQgbGlrZSBgIShAKGZvb3xiYXIpKilgLiBUaGlzIHdpbGwgd29yayBjb3JyZWN0bHkgaWZcbiAqICAgdGhlIGdyb3VwIG9jY3VycyBub3QgbmVzdGVkIGF0IHRoZSBlbmQgb2YgdGhlIHNlZ21lbnQuICovXG5leHBvcnQgZnVuY3Rpb24gZ2xvYlRvUmVnRXhwKFxuICBnbG9iOiBzdHJpbmcsXG4gIHtcbiAgICBleHRlbmRlZCA9IHRydWUsXG4gICAgZ2xvYnN0YXI6IGdsb2JzdGFyT3B0aW9uID0gdHJ1ZSxcbiAgICBvcyA9IG9zVHlwZSxcbiAgICBjYXNlSW5zZW5zaXRpdmUgPSBmYWxzZSxcbiAgfTogR2xvYlRvUmVnRXhwT3B0aW9ucyA9IHt9LFxuKTogUmVnRXhwIHtcbiAgaWYgKGdsb2IgPT0gXCJcIikge1xuICAgIHJldHVybiAvKD8hKS87XG4gIH1cblxuICBjb25zdCBzZXAgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiKD86XFxcXFxcXFx8LykrXCIgOiBcIi8rXCI7XG4gIGNvbnN0IHNlcE1heWJlID0gb3MgPT0gXCJ3aW5kb3dzXCIgPyBcIig/OlxcXFxcXFxcfC8pKlwiIDogXCIvKlwiO1xuICBjb25zdCBzZXBzID0gb3MgPT0gXCJ3aW5kb3dzXCIgPyBbXCJcXFxcXCIsIFwiL1wiXSA6IFtcIi9cIl07XG4gIGNvbnN0IGdsb2JzdGFyID0gb3MgPT0gXCJ3aW5kb3dzXCJcbiAgICA/IFwiKD86W15cXFxcXFxcXC9dKig/OlxcXFxcXFxcfC98JCkrKSpcIlxuICAgIDogXCIoPzpbXi9dKig/Oi98JCkrKSpcIjtcbiAgY29uc3Qgd2lsZGNhcmQgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiW15cXFxcXFxcXC9dKlwiIDogXCJbXi9dKlwiO1xuICBjb25zdCBlc2NhcGVQcmVmaXggPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiYFwiIDogXCJcXFxcXCI7XG5cbiAgLy8gUmVtb3ZlIHRyYWlsaW5nIHNlcGFyYXRvcnMuXG4gIGxldCBuZXdMZW5ndGggPSBnbG9iLmxlbmd0aDtcbiAgZm9yICg7IG5ld0xlbmd0aCA+IDEgJiYgc2Vwcy5pbmNsdWRlcyhnbG9iW25ld0xlbmd0aCAtIDFdKTsgbmV3TGVuZ3RoLS0pO1xuICBnbG9iID0gZ2xvYi5zbGljZSgwLCBuZXdMZW5ndGgpO1xuXG4gIGxldCByZWdFeHBTdHJpbmcgPSBcIlwiO1xuXG4gIC8vIFRlcm1pbmF0ZXMgY29ycmVjdGx5LiBUcnVzdCB0aGF0IGBqYCBpcyBpbmNyZW1lbnRlZCBldmVyeSBpdGVyYXRpb24uXG4gIGZvciAobGV0IGogPSAwOyBqIDwgZ2xvYi5sZW5ndGg7KSB7XG4gICAgbGV0IHNlZ21lbnQgPSBcIlwiO1xuICAgIGNvbnN0IGdyb3VwU3RhY2s6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IGluUmFuZ2UgPSBmYWxzZTtcbiAgICBsZXQgaW5Fc2NhcGUgPSBmYWxzZTtcbiAgICBsZXQgZW5kc1dpdGhTZXAgPSBmYWxzZTtcbiAgICBsZXQgaSA9IGo7XG5cbiAgICAvLyBUZXJtaW5hdGVzIHdpdGggYGlgIGF0IHRoZSBub24taW5jbHVzaXZlIGVuZCBvZiB0aGUgY3VycmVudCBzZWdtZW50LlxuICAgIGZvciAoOyBpIDwgZ2xvYi5sZW5ndGggJiYgIXNlcHMuaW5jbHVkZXMoZ2xvYltpXSk7IGkrKykge1xuICAgICAgaWYgKGluRXNjYXBlKSB7XG4gICAgICAgIGluRXNjYXBlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGVzY2FwZUNoYXJzID0gaW5SYW5nZSA/IHJhbmdlRXNjYXBlQ2hhcnMgOiByZWdFeHBFc2NhcGVDaGFycztcbiAgICAgICAgc2VnbWVudCArPSBlc2NhcGVDaGFycy5pbmNsdWRlcyhnbG9iW2ldKSA/IGBcXFxcJHtnbG9iW2ldfWAgOiBnbG9iW2ldO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gZXNjYXBlUHJlZml4KSB7XG4gICAgICAgIGluRXNjYXBlID0gdHJ1ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiW1wiKSB7XG4gICAgICAgIGlmICghaW5SYW5nZSkge1xuICAgICAgICAgIGluUmFuZ2UgPSB0cnVlO1xuICAgICAgICAgIHNlZ21lbnQgKz0gXCJbXCI7XG4gICAgICAgICAgaWYgKGdsb2JbaSArIDFdID09IFwiIVwiKSB7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgICBzZWdtZW50ICs9IFwiXlwiO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ2xvYltpICsgMV0gPT0gXCJeXCIpIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gXCJcXFxcXlwiO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIGlmIChnbG9iW2kgKyAxXSA9PSBcIjpcIikge1xuICAgICAgICAgIGxldCBrID0gaSArIDE7XG4gICAgICAgICAgbGV0IHZhbHVlID0gXCJcIjtcbiAgICAgICAgICB3aGlsZSAoZ2xvYltrICsgMV0gIT0gbnVsbCAmJiBnbG9iW2sgKyAxXSAhPSBcIjpcIikge1xuICAgICAgICAgICAgdmFsdWUgKz0gZ2xvYltrICsgMV07XG4gICAgICAgICAgICBrKys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChnbG9iW2sgKyAxXSA9PSBcIjpcIiAmJiBnbG9iW2sgKyAyXSA9PSBcIl1cIikge1xuICAgICAgICAgICAgaSA9IGsgKyAyO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiYWxudW1cIikgc2VnbWVudCArPSBcIlxcXFxkQS1aYS16XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImFscGhhXCIpIHNlZ21lbnQgKz0gXCJBLVphLXpcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiYXNjaWlcIikgc2VnbWVudCArPSBcIlxceDAwLVxceDdGXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImJsYW5rXCIpIHNlZ21lbnQgKz0gXCJcXHQgXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImNudHJsXCIpIHNlZ21lbnQgKz0gXCJcXHgwMC1cXHgxRlxceDdGXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImRpZ2l0XCIpIHNlZ21lbnQgKz0gXCJcXFxcZFwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJncmFwaFwiKSBzZWdtZW50ICs9IFwiXFx4MjEtXFx4N0VcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwibG93ZXJcIikgc2VnbWVudCArPSBcImEtelwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJwcmludFwiKSBzZWdtZW50ICs9IFwiXFx4MjAtXFx4N0VcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwicHVuY3RcIikge1xuICAgICAgICAgICAgICBzZWdtZW50ICs9IFwiIVxcXCIjJCUmJygpKissXFxcXC0uLzo7PD0+P0BbXFxcXFxcXFxcXFxcXV5f4oCYe3x9flwiO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSBcInNwYWNlXCIpIHNlZ21lbnQgKz0gXCJcXFxcc1xcdlwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJ1cHBlclwiKSBzZWdtZW50ICs9IFwiQS1aXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcIndvcmRcIikgc2VnbWVudCArPSBcIlxcXFx3XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcInhkaWdpdFwiKSBzZWdtZW50ICs9IFwiXFxcXGRBLUZhLWZcIjtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIl1cIiAmJiBpblJhbmdlKSB7XG4gICAgICAgIGluUmFuZ2UgPSBmYWxzZTtcbiAgICAgICAgc2VnbWVudCArPSBcIl1cIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpblJhbmdlKSB7XG4gICAgICAgIGlmIChnbG9iW2ldID09IFwiXFxcXFwiKSB7XG4gICAgICAgICAgc2VnbWVudCArPSBgXFxcXFxcXFxgO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlZ21lbnQgKz0gZ2xvYltpXTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBnbG9iW2ldID09IFwiKVwiICYmIGdyb3VwU3RhY2subGVuZ3RoID4gMCAmJlxuICAgICAgICBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gIT0gXCJCUkFDRVwiXG4gICAgICApIHtcbiAgICAgICAgc2VnbWVudCArPSBcIilcIjtcbiAgICAgICAgY29uc3QgdHlwZSA9IGdyb3VwU3RhY2sucG9wKCkhO1xuICAgICAgICBpZiAodHlwZSA9PSBcIiFcIikge1xuICAgICAgICAgIHNlZ21lbnQgKz0gd2lsZGNhcmQ7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSAhPSBcIkBcIikge1xuICAgICAgICAgIHNlZ21lbnQgKz0gdHlwZTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBnbG9iW2ldID09IFwifFwiICYmIGdyb3VwU3RhY2subGVuZ3RoID4gMCAmJlxuICAgICAgICBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gIT0gXCJCUkFDRVwiXG4gICAgICApIHtcbiAgICAgICAgc2VnbWVudCArPSBcInxcIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiK1wiICYmIGV4dGVuZGVkICYmIGdsb2JbaSArIDFdID09IFwiKFwiKSB7XG4gICAgICAgIGkrKztcbiAgICAgICAgZ3JvdXBTdGFjay5wdXNoKFwiK1wiKTtcbiAgICAgICAgc2VnbWVudCArPSBcIig/OlwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCJAXCIgJiYgZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCJAXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIj9cIikge1xuICAgICAgICBpZiAoZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgICAgZ3JvdXBTdGFjay5wdXNoKFwiP1wiKTtcbiAgICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VnbWVudCArPSBcIi5cIjtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIhXCIgJiYgZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCIhXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD8hXCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIntcIikge1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCJCUkFDRVwiKTtcbiAgICAgICAgc2VnbWVudCArPSBcIig/OlwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCJ9XCIgJiYgZ3JvdXBTdGFja1tncm91cFN0YWNrLmxlbmd0aCAtIDFdID09IFwiQlJBQ0VcIikge1xuICAgICAgICBncm91cFN0YWNrLnBvcCgpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKVwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIsXCIgJiYgZ3JvdXBTdGFja1tncm91cFN0YWNrLmxlbmd0aCAtIDFdID09IFwiQlJBQ0VcIikge1xuICAgICAgICBzZWdtZW50ICs9IFwifFwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIqXCIpIHtcbiAgICAgICAgaWYgKGV4dGVuZGVkICYmIGdsb2JbaSArIDFdID09IFwiKFwiKSB7XG4gICAgICAgICAgaSsrO1xuICAgICAgICAgIGdyb3VwU3RhY2sucHVzaChcIipcIik7XG4gICAgICAgICAgc2VnbWVudCArPSBcIig/OlwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHByZXZDaGFyID0gZ2xvYltpIC0gMV07XG4gICAgICAgICAgbGV0IG51bVN0YXJzID0gMTtcbiAgICAgICAgICB3aGlsZSAoZ2xvYltpICsgMV0gPT0gXCIqXCIpIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIG51bVN0YXJzKys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IG5leHRDaGFyID0gZ2xvYltpICsgMV07XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgZ2xvYnN0YXJPcHRpb24gJiYgbnVtU3RhcnMgPT0gMiAmJlxuICAgICAgICAgICAgWy4uLnNlcHMsIHVuZGVmaW5lZF0uaW5jbHVkZXMocHJldkNoYXIpICYmXG4gICAgICAgICAgICBbLi4uc2VwcywgdW5kZWZpbmVkXS5pbmNsdWRlcyhuZXh0Q2hhcilcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gZ2xvYnN0YXI7XG4gICAgICAgICAgICBlbmRzV2l0aFNlcCA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gd2lsZGNhcmQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBzZWdtZW50ICs9IHJlZ0V4cEVzY2FwZUNoYXJzLmluY2x1ZGVzKGdsb2JbaV0pID8gYFxcXFwke2dsb2JbaV19YCA6IGdsb2JbaV07XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIHVuY2xvc2VkIGdyb3VwcyBvciBhIGRhbmdsaW5nIGJhY2tzbGFzaC5cbiAgICBpZiAoZ3JvdXBTdGFjay5sZW5ndGggPiAwIHx8IGluUmFuZ2UgfHwgaW5Fc2NhcGUpIHtcbiAgICAgIC8vIFBhcnNlIGZhaWx1cmUuIFRha2UgYWxsIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHNlZ21lbnQgbGl0ZXJhbGx5LlxuICAgICAgc2VnbWVudCA9IFwiXCI7XG4gICAgICBmb3IgKGNvbnN0IGMgb2YgZ2xvYi5zbGljZShqLCBpKSkge1xuICAgICAgICBzZWdtZW50ICs9IHJlZ0V4cEVzY2FwZUNoYXJzLmluY2x1ZGVzKGMpID8gYFxcXFwke2N9YCA6IGM7XG4gICAgICAgIGVuZHNXaXRoU2VwID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVnRXhwU3RyaW5nICs9IHNlZ21lbnQ7XG4gICAgaWYgKCFlbmRzV2l0aFNlcCkge1xuICAgICAgcmVnRXhwU3RyaW5nICs9IGkgPCBnbG9iLmxlbmd0aCA/IHNlcCA6IHNlcE1heWJlO1xuICAgICAgZW5kc1dpdGhTZXAgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIFRlcm1pbmF0ZXMgd2l0aCBgaWAgYXQgdGhlIHN0YXJ0IG9mIHRoZSBuZXh0IHNlZ21lbnQuXG4gICAgd2hpbGUgKHNlcHMuaW5jbHVkZXMoZ2xvYltpXSkpIGkrKztcblxuICAgIC8vIENoZWNrIHRoYXQgdGhlIG5leHQgdmFsdWUgb2YgYGpgIGlzIGluZGVlZCBoaWdoZXIgdGhhbiB0aGUgY3VycmVudCB2YWx1ZS5cbiAgICBpZiAoIShpID4gaikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkFzc2VydGlvbiBmYWlsdXJlOiBpID4gaiAocG90ZW50aWFsIGluZmluaXRlIGxvb3ApXCIpO1xuICAgIH1cbiAgICBqID0gaTtcbiAgfVxuXG4gIHJlZ0V4cFN0cmluZyA9IGBeJHtyZWdFeHBTdHJpbmd9JGA7XG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ0V4cFN0cmluZywgY2FzZUluc2Vuc2l0aXZlID8gXCJpXCIgOiBcIlwiKTtcbn1cblxuLyoqIFRlc3Qgd2hldGhlciB0aGUgZ2l2ZW4gc3RyaW5nIGlzIGEgZ2xvYiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzR2xvYihzdHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBjaGFyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgXCJ7XCI6IFwifVwiLCBcIihcIjogXCIpXCIsIFwiW1wiOiBcIl1cIiB9O1xuICBjb25zdCByZWdleCA9XG4gICAgL1xcXFwoLil8KF4hfFxcKnxcXD98W1xcXS4rKV1cXD98XFxbW15cXFxcXFxdXStcXF18XFx7W15cXFxcfV0rXFx9fFxcKFxcP1s6IT1dW15cXFxcKV0rXFwpfFxcKFtefF0rXFx8W15cXFxcKV0rXFwpKS87XG5cbiAgaWYgKHN0ciA9PT0gXCJcIikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGxldCBtYXRjaDogUmVnRXhwRXhlY0FycmF5IHwgbnVsbDtcblxuICB3aGlsZSAoKG1hdGNoID0gcmVnZXguZXhlYyhzdHIpKSkge1xuICAgIGlmIChtYXRjaFsyXSkgcmV0dXJuIHRydWU7XG4gICAgbGV0IGlkeCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xuXG4gICAgLy8gaWYgYW4gb3BlbiBicmFja2V0L2JyYWNlL3BhcmVuIGlzIGVzY2FwZWQsXG4gICAgLy8gc2V0IHRoZSBpbmRleCB0byB0aGUgbmV4dCBjbG9zaW5nIGNoYXJhY3RlclxuICAgIGNvbnN0IG9wZW4gPSBtYXRjaFsxXTtcbiAgICBjb25zdCBjbG9zZSA9IG9wZW4gPyBjaGFyc1tvcGVuXSA6IG51bGw7XG4gICAgaWYgKG9wZW4gJiYgY2xvc2UpIHtcbiAgICAgIGNvbnN0IG4gPSBzdHIuaW5kZXhPZihjbG9zZSwgaWR4KTtcbiAgICAgIGlmIChuICE9PSAtMSkge1xuICAgICAgICBpZHggPSBuICsgMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdHIgPSBzdHIuc2xpY2UoaWR4KTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqIExpa2Ugbm9ybWFsaXplKCksIGJ1dCBkb2Vzbid0IGNvbGxhcHNlIFwiKipcXC8uLlwiIHdoZW4gYGdsb2JzdGFyYCBpcyB0cnVlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUdsb2IoXG4gIGdsb2I6IHN0cmluZyxcbiAgeyBnbG9ic3RhciA9IGZhbHNlIH06IEdsb2JPcHRpb25zID0ge30sXG4pOiBzdHJpbmcge1xuICBpZiAoZ2xvYi5tYXRjaCgvXFwwL2cpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBHbG9iIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyczogXCIke2dsb2J9XCJgKTtcbiAgfVxuICBpZiAoIWdsb2JzdGFyKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZShnbG9iKTtcbiAgfVxuICBjb25zdCBzID0gU0VQX1BBVFRFUk4uc291cmNlO1xuICBjb25zdCBiYWRQYXJlbnRQYXR0ZXJuID0gbmV3IFJlZ0V4cChcbiAgICBgKD88PSgke3N9fF4pXFxcXCpcXFxcKiR7c30pXFxcXC5cXFxcLig/PSR7c318JClgLFxuICAgIFwiZ1wiLFxuICApO1xuICByZXR1cm4gbm9ybWFsaXplKGdsb2IucmVwbGFjZShiYWRQYXJlbnRQYXR0ZXJuLCBcIlxcMFwiKSkucmVwbGFjZSgvXFwwL2csIFwiLi5cIik7XG59XG5cbi8qKiBMaWtlIGpvaW4oKSwgYnV0IGRvZXNuJ3QgY29sbGFwc2UgXCIqKlxcLy4uXCIgd2hlbiBgZ2xvYnN0YXJgIGlzIHRydWUuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbkdsb2JzKFxuICBnbG9iczogc3RyaW5nW10sXG4gIHsgZXh0ZW5kZWQgPSB0cnVlLCBnbG9ic3RhciA9IGZhbHNlIH06IEdsb2JPcHRpb25zID0ge30sXG4pOiBzdHJpbmcge1xuICBpZiAoIWdsb2JzdGFyIHx8IGdsb2JzLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIGpvaW4oLi4uZ2xvYnMpO1xuICB9XG4gIGlmIChnbG9icy5sZW5ndGggPT09IDApIHJldHVybiBcIi5cIjtcbiAgbGV0IGpvaW5lZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBmb3IgKGNvbnN0IGdsb2Igb2YgZ2xvYnMpIHtcbiAgICBjb25zdCBwYXRoID0gZ2xvYjtcbiAgICBpZiAocGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoIWpvaW5lZCkgam9pbmVkID0gcGF0aDtcbiAgICAgIGVsc2Ugam9pbmVkICs9IGAke1NFUH0ke3BhdGh9YDtcbiAgICB9XG4gIH1cbiAgaWYgKCFqb2luZWQpIHJldHVybiBcIi5cIjtcbiAgcmV0dXJuIG5vcm1hbGl6ZUdsb2Ioam9pbmVkLCB7IGV4dGVuZGVkLCBnbG9ic3RhciB9KTtcbn1cbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgdGhlIEJyb3dzZXJpZnkgYXV0aG9ycy4gTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogUG9ydGVkIG1vc3RseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbiAqIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBpc1dpbmRvd3MgfSBmcm9tIFwiLi4vX3V0aWwvb3MudHNcIjtcbmltcG9ydCAqIGFzIF93aW4zMiBmcm9tIFwiLi93aW4zMi50c1wiO1xuaW1wb3J0ICogYXMgX3Bvc2l4IGZyb20gXCIuL3Bvc2l4LnRzXCI7XG5cbmNvbnN0IHBhdGggPSBpc1dpbmRvd3MgPyBfd2luMzIgOiBfcG9zaXg7XG5cbmV4cG9ydCBjb25zdCB3aW4zMiA9IF93aW4zMjtcbmV4cG9ydCBjb25zdCBwb3NpeCA9IF9wb3NpeDtcbmV4cG9ydCBjb25zdCB7XG4gIGJhc2VuYW1lLFxuICBkZWxpbWl0ZXIsXG4gIGRpcm5hbWUsXG4gIGV4dG5hbWUsXG4gIGZvcm1hdCxcbiAgZnJvbUZpbGVVcmwsXG4gIGlzQWJzb2x1dGUsXG4gIGpvaW4sXG4gIG5vcm1hbGl6ZSxcbiAgcGFyc2UsXG4gIHJlbGF0aXZlLFxuICByZXNvbHZlLFxuICBzZXAsXG4gIHRvRmlsZVVybCxcbiAgdG9OYW1lc3BhY2VkUGF0aCxcbn0gPSBwYXRoO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jb21tb24udHNcIjtcbmV4cG9ydCB7IFNFUCwgU0VQX1BBVFRFUk4gfSBmcm9tIFwiLi9zZXBhcmF0b3IudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL19pbnRlcmZhY2UudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2dsb2IudHNcIjtcbiIsIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG5cbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCIuLi9pby9idWZmZXIudHNcIjtcblxuY29uc3QgREVGQVVMVF9DSFVOS19TSVpFID0gMTZfNjQwO1xuY29uc3QgREVGQVVMVF9CVUZGRVJfU0laRSA9IDMyICogMTAyNDtcblxuZnVuY3Rpb24gaXNDbG9zZXIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBEZW5vLkNsb3NlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT0gbnVsbCAmJiBcImNsb3NlXCIgaW4gdmFsdWUgJiZcbiAgICAvLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueVxuICAgIHR5cGVvZiAodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgYW55PilbXCJjbG9zZVwiXSA9PT0gXCJmdW5jdGlvblwiO1xufVxuXG4vKiogQ3JlYXRlIGEgYERlbm8uUmVhZGVyYCBmcm9tIGFuIGl0ZXJhYmxlIG9mIGBVaW50OEFycmF5YHMuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgcmVhZGVyRnJvbUl0ZXJhYmxlIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IERlbm8ub3BlbihcIm1ldHJpY3MudHh0XCIsIHsgd3JpdGU6IHRydWUgfSk7XG4gKiAgICAgIGNvbnN0IHJlYWRlciA9IHJlYWRlckZyb21JdGVyYWJsZSgoYXN5bmMgZnVuY3Rpb24qICgpIHtcbiAqICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICogICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpO1xuICogICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGBkYXRhOiAke0pTT04uc3RyaW5naWZ5KERlbm8ubWV0cmljcygpKX1cXG5cXG5gO1xuICogICAgICAgICAgeWllbGQgbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKG1lc3NhZ2UpO1xuICogICAgICAgIH1cbiAqICAgICAgfSkoKSk7XG4gKiAgICAgIGF3YWl0IERlbm8uY29weShyZWFkZXIsIGZpbGUpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkZXJGcm9tSXRlcmFibGUoXG4gIGl0ZXJhYmxlOiBJdGVyYWJsZTxVaW50OEFycmF5PiB8IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4sXG4pOiBEZW5vLlJlYWRlciB7XG4gIGNvbnN0IGl0ZXJhdG9yOiBJdGVyYXRvcjxVaW50OEFycmF5PiB8IEFzeW5jSXRlcmF0b3I8VWludDhBcnJheT4gPVxuICAgIChpdGVyYWJsZSBhcyBBc3luY0l0ZXJhYmxlPFVpbnQ4QXJyYXk+KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0/LigpID8/XG4gICAgICAoaXRlcmFibGUgYXMgSXRlcmFibGU8VWludDhBcnJheT4pW1N5bWJvbC5pdGVyYXRvcl0/LigpO1xuICBjb25zdCBidWZmZXIgPSBuZXcgQnVmZmVyKCk7XG4gIHJldHVybiB7XG4gICAgYXN5bmMgcmVhZChwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHJlc3VsdC52YWx1ZS5ieXRlTGVuZ3RoIDw9IHAuYnl0ZUxlbmd0aCkge1xuICAgICAgICAgICAgcC5zZXQocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudmFsdWUuYnl0ZUxlbmd0aDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcC5zZXQocmVzdWx0LnZhbHVlLnN1YmFycmF5KDAsIHAuYnl0ZUxlbmd0aCkpO1xuICAgICAgICAgIGF3YWl0IHdyaXRlQWxsKGJ1ZmZlciwgcmVzdWx0LnZhbHVlLnN1YmFycmF5KHAuYnl0ZUxlbmd0aCkpO1xuICAgICAgICAgIHJldHVybiBwLmJ5dGVMZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG4gPSBhd2FpdCBidWZmZXIucmVhZChwKTtcbiAgICAgICAgaWYgKG4gPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlYWQocCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG47XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIENyZWF0ZSBhIGBXcml0ZXJgIGZyb20gYSBgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZXJGcm9tU3RyZWFtV3JpdGVyKFxuICBzdHJlYW1Xcml0ZXI6IFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcjxVaW50OEFycmF5Pixcbik6IERlbm8uV3JpdGVyIHtcbiAgcmV0dXJuIHtcbiAgICBhc3luYyB3cml0ZShwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICAgIGF3YWl0IHN0cmVhbVdyaXRlci5yZWFkeTtcbiAgICAgIGF3YWl0IHN0cmVhbVdyaXRlci53cml0ZShwKTtcbiAgICAgIHJldHVybiBwLmxlbmd0aDtcbiAgICB9LFxuICB9O1xufVxuXG4vKiogQ3JlYXRlIGEgYFJlYWRlcmAgZnJvbSBhIGBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRlckZyb21TdHJlYW1SZWFkZXIoXG4gIHN0cmVhbVJlYWRlcjogUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyPFVpbnQ4QXJyYXk+LFxuKTogRGVuby5SZWFkZXIge1xuICBjb25zdCBidWZmZXIgPSBuZXcgQnVmZmVyKCk7XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyByZWFkKHA6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPG51bWJlciB8IG51bGw+IHtcbiAgICAgIGlmIChidWZmZXIuZW1wdHkoKSkge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBzdHJlYW1SZWFkZXIucmVhZCgpO1xuICAgICAgICBpZiAocmVzLmRvbmUpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gRU9GXG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB3cml0ZUFsbChidWZmZXIsIHJlcy52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBidWZmZXIucmVhZChwKTtcbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdyaXRhYmxlU3RyZWFtRnJvbVdyaXRlck9wdGlvbnMge1xuICAvKipcbiAgICogSWYgdGhlIGB3cml0ZXJgIGlzIGFsc28gYSBgRGVuby5DbG9zZXJgLCBhdXRvbWF0aWNhbGx5IGNsb3NlIHRoZSBgd3JpdGVyYFxuICAgKiB3aGVuIHRoZSBzdHJlYW0gaXMgY2xvc2VkLCBhYm9ydGVkLCBvciBhIHdyaXRlIGVycm9yIG9jY3Vycy5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gYHRydWVgLiAqL1xuICBhdXRvQ2xvc2U/OiBib29sZWFuO1xufVxuXG4vKiogQ3JlYXRlIGEgYFdyaXRhYmxlU3RyZWFtYCBmcm9tIGEgYFdyaXRlcmAuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGFibGVTdHJlYW1Gcm9tV3JpdGVyKFxuICB3cml0ZXI6IERlbm8uV3JpdGVyLFxuICBvcHRpb25zOiBXcml0YWJsZVN0cmVhbUZyb21Xcml0ZXJPcHRpb25zID0ge30sXG4pOiBXcml0YWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IHsgYXV0b0Nsb3NlID0gdHJ1ZSB9ID0gb3B0aW9ucztcblxuICByZXR1cm4gbmV3IFdyaXRhYmxlU3RyZWFtKHtcbiAgICBhc3luYyB3cml0ZShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd3JpdGVBbGwod3JpdGVyLCBjaHVuayk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZSk7XG4gICAgICAgIGlmIChpc0Nsb3Nlcih3cml0ZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICAgIHdyaXRlci5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBjbG9zZSgpIHtcbiAgICAgIGlmIChpc0Nsb3Nlcih3cml0ZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICB3cml0ZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFib3J0KCkge1xuICAgICAgaWYgKGlzQ2xvc2VyKHdyaXRlcikgJiYgYXV0b0Nsb3NlKSB7XG4gICAgICAgIHdyaXRlci5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKiogQ3JlYXRlIGEgYFJlYWRhYmxlU3RyZWFtYCBmcm9tIGFueSBraW5kIG9mIGl0ZXJhYmxlLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IHJlYWRhYmxlU3RyZWFtRnJvbUl0ZXJhYmxlIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqICAgICAgY29uc3QgcjEgPSByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZShbXCJmb28sIGJhciwgYmF6XCJdKTtcbiAqICAgICAgY29uc3QgcjIgPSByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZShhc3luYyBmdW5jdGlvbiogKCkge1xuICogICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKCgocikgPT4gc2V0VGltZW91dChyLCAxMDAwKSkpO1xuICogICAgICAgIHlpZWxkIFwiZm9vXCI7XG4gKiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEwMDApKSk7XG4gKiAgICAgICAgeWllbGQgXCJiYXJcIjtcbiAqICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpKTtcbiAqICAgICAgICB5aWVsZCBcImJhelwiO1xuICogICAgICB9KCkpO1xuICogYGBgXG4gKlxuICogSWYgdGhlIHByb2R1Y2VkIGl0ZXJhdG9yIChgaXRlcmFibGVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKClgIG9yXG4gKiBgaXRlcmFibGVbU3ltYm9sLml0ZXJhdG9yXSgpYCkgaXMgYSBnZW5lcmF0b3IsIG9yIG1vcmUgc3BlY2lmaWNhbGx5IGlzIGZvdW5kXG4gKiB0byBoYXZlIGEgYC50aHJvdygpYCBtZXRob2Qgb24gaXQsIHRoYXQgd2lsbCBiZSBjYWxsZWQgdXBvblxuICogYHJlYWRhYmxlU3RyZWFtLmNhbmNlbCgpYC4gVGhpcyBpcyB0aGUgY2FzZSBmb3IgdGhlIHNlY29uZCBpbnB1dCB0eXBlIGFib3ZlOlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZSB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiBjb25zdCByMyA9IHJlYWRhYmxlU3RyZWFtRnJvbUl0ZXJhYmxlKGFzeW5jIGZ1bmN0aW9uKiAoKSB7XG4gKiAgIHRyeSB7XG4gKiAgICAgeWllbGQgXCJmb29cIjtcbiAqICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmxvZyhlcnJvcik7IC8vIEVycm9yOiBDYW5jZWxsZWQgYnkgY29uc3VtZXIuXG4gKiAgIH1cbiAqIH0oKSk7XG4gKiBjb25zdCByZWFkZXIgPSByMy5nZXRSZWFkZXIoKTtcbiAqIGNvbnNvbGUubG9nKGF3YWl0IHJlYWRlci5yZWFkKCkpOyAvLyB7IHZhbHVlOiBcImZvb1wiLCBkb25lOiBmYWxzZSB9XG4gKiBhd2FpdCByZWFkZXIuY2FuY2VsKG5ldyBFcnJvcihcIkNhbmNlbGxlZCBieSBjb25zdW1lci5cIikpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZTxUPihcbiAgaXRlcmFibGU6IEl0ZXJhYmxlPFQ+IHwgQXN5bmNJdGVyYWJsZTxUPixcbik6IFJlYWRhYmxlU3RyZWFtPFQ+IHtcbiAgY29uc3QgaXRlcmF0b3I6IEl0ZXJhdG9yPFQ+IHwgQXN5bmNJdGVyYXRvcjxUPiA9XG4gICAgKGl0ZXJhYmxlIGFzIEFzeW5jSXRlcmFibGU8VD4pW1N5bWJvbC5hc3luY0l0ZXJhdG9yXT8uKCkgPz9cbiAgICAgIChpdGVyYWJsZSBhcyBJdGVyYWJsZTxUPilbU3ltYm9sLml0ZXJhdG9yXT8uKCk7XG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgIGFzeW5jIHB1bGwoY29udHJvbGxlcikge1xuICAgICAgY29uc3QgeyB2YWx1ZSwgZG9uZSB9ID0gYXdhaXQgaXRlcmF0b3IubmV4dCgpO1xuICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGNhbmNlbChyZWFzb24pIHtcbiAgICAgIGlmICh0eXBlb2YgaXRlcmF0b3IudGhyb3cgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgaXRlcmF0b3IudGhyb3cocmVhc29uKTtcbiAgICAgICAgfSBjYXRjaCB7IC8qIGBpdGVyYXRvci50aHJvdygpYCBhbHdheXMgdGhyb3dzIG9uIHNpdGUuIFdlIGNhdGNoIGl0LiAqLyB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyT3B0aW9ucyB7XG4gIC8qKiBJZiB0aGUgYHJlYWRlcmAgaXMgYWxzbyBhIGBEZW5vLkNsb3NlcmAsIGF1dG9tYXRpY2FsbHkgY2xvc2UgdGhlIGByZWFkZXJgXG4gICAqIHdoZW4gYEVPRmAgaXMgZW5jb3VudGVyZWQsIG9yIGEgcmVhZCBlcnJvciBvY2N1cnMuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIGB0cnVlYC4gKi9cbiAgYXV0b0Nsb3NlPzogYm9vbGVhbjtcblxuICAvKiogVGhlIHNpemUgb2YgY2h1bmtzIHRvIGFsbG9jYXRlIHRvIHJlYWQsIHRoZSBkZWZhdWx0IGlzIH4xNktpQiwgd2hpY2ggaXNcbiAgICogdGhlIG1heGltdW0gc2l6ZSB0aGF0IERlbm8gb3BlcmF0aW9ucyBjYW4gY3VycmVudGx5IHN1cHBvcnQuICovXG4gIGNodW5rU2l6ZT86IG51bWJlcjtcblxuICAvKiogVGhlIHF1ZXVpbmcgc3RyYXRlZ3kgdG8gY3JlYXRlIHRoZSBgUmVhZGFibGVTdHJlYW1gIHdpdGguICovXG4gIHN0cmF0ZWd5PzogeyBoaWdoV2F0ZXJNYXJrPzogbnVtYmVyIHwgdW5kZWZpbmVkOyBzaXplPzogdW5kZWZpbmVkIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgYFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+YCBmcm9tIGZyb20gYSBgRGVuby5SZWFkZXJgLlxuICpcbiAqIFdoZW4gdGhlIHB1bGwgYWxnb3JpdGhtIGlzIGNhbGxlZCBvbiB0aGUgc3RyZWFtLCBhIGNodW5rIGZyb20gdGhlIHJlYWRlclxuICogd2lsbCBiZSByZWFkLiAgV2hlbiBgbnVsbGAgaXMgcmV0dXJuZWQgZnJvbSB0aGUgcmVhZGVyLCB0aGUgc3RyZWFtIHdpbGwgYmVcbiAqIGNsb3NlZCBhbG9uZyB3aXRoIHRoZSByZWFkZXIgKGlmIGl0IGlzIGFsc28gYSBgRGVuby5DbG9zZXJgKS5cbiAqXG4gKiBBbiBleGFtcGxlIGNvbnZlcnRpbmcgYSBgRGVuby5Gc0ZpbGVgIGludG8gYSByZWFkYWJsZSBzdHJlYW06XG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlciB9IGZyb20gXCIuL21vZC50c1wiO1xuICpcbiAqIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oXCIuL2ZpbGUudHh0XCIsIHsgcmVhZDogdHJ1ZSB9KTtcbiAqIGNvbnN0IGZpbGVTdHJlYW0gPSByZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIoZmlsZSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlcihcbiAgcmVhZGVyOiBEZW5vLlJlYWRlciB8IChEZW5vLlJlYWRlciAmIERlbm8uQ2xvc2VyKSxcbiAgb3B0aW9uczogUmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyT3B0aW9ucyA9IHt9LFxuKTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICBjb25zdCB7XG4gICAgYXV0b0Nsb3NlID0gdHJ1ZSxcbiAgICBjaHVua1NpemUgPSBERUZBVUxUX0NIVU5LX1NJWkUsXG4gICAgc3RyYXRlZ3ksXG4gIH0gPSBvcHRpb25zO1xuXG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgIGFzeW5jIHB1bGwoY29udHJvbGxlcikge1xuICAgICAgY29uc3QgY2h1bmsgPSBuZXcgVWludDhBcnJheShjaHVua1NpemUpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVhZCA9IGF3YWl0IHJlYWRlci5yZWFkKGNodW5rKTtcbiAgICAgICAgaWYgKHJlYWQgPT09IG51bGwpIHtcbiAgICAgICAgICBpZiAoaXNDbG9zZXIocmVhZGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgICAgIHJlYWRlci5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuay5zdWJhcnJheSgwLCByZWFkKSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZSk7XG4gICAgICAgIGlmIChpc0Nsb3NlcihyZWFkZXIpKSB7XG4gICAgICAgICAgcmVhZGVyLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGNhbmNlbCgpIHtcbiAgICAgIGlmIChpc0Nsb3NlcihyZWFkZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICByZWFkZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuICB9LCBzdHJhdGVneSk7XG59XG5cbi8qKiBSZWFkIFJlYWRlciBgcmAgdW50aWwgRU9GIChgbnVsbGApIGFuZCByZXNvbHZlIHRvIHRoZSBjb250ZW50IGFzXG4gKiBVaW50OEFycmF5YC5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgcmVhZEFsbCB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiAvLyBFeGFtcGxlIGZyb20gc3RkaW5cbiAqIGNvbnN0IHN0ZGluQ29udGVudCA9IGF3YWl0IHJlYWRBbGwoRGVuby5zdGRpbik7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGZpbGVcbiAqIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oXCJteV9maWxlLnR4dFwiLCB7cmVhZDogdHJ1ZX0pO1xuICogY29uc3QgbXlGaWxlQ29udGVudCA9IGF3YWl0IHJlYWRBbGwoZmlsZSk7XG4gKiBEZW5vLmNsb3NlKGZpbGUucmlkKTtcbiAqXG4gKiAvLyBFeGFtcGxlIGZyb20gYnVmZmVyXG4gKiBjb25zdCBteURhdGEgPSBuZXcgVWludDhBcnJheSgxMDApO1xuICogLy8gLi4uIGZpbGwgbXlEYXRhIGFycmF5IHdpdGggZGF0YVxuICogY29uc3QgcmVhZGVyID0gbmV3IEJ1ZmZlcihteURhdGEuYnVmZmVyKTtcbiAqIGNvbnN0IGJ1ZmZlckNvbnRlbnQgPSBhd2FpdCByZWFkQWxsKHJlYWRlcik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRBbGwocjogRGVuby5SZWFkZXIpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgYnVmID0gbmV3IEJ1ZmZlcigpO1xuICBhd2FpdCBidWYucmVhZEZyb20ocik7XG4gIHJldHVybiBidWYuYnl0ZXMoKTtcbn1cblxuLyoqIFN5bmNocm9ub3VzbHkgcmVhZHMgUmVhZGVyIGByYCB1bnRpbCBFT0YgKGBudWxsYCkgYW5kIHJldHVybnMgdGhlIGNvbnRlbnRcbiAqIGFzIGBVaW50OEFycmF5YC5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgcmVhZEFsbFN5bmMgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIHN0ZGluXG4gKiBjb25zdCBzdGRpbkNvbnRlbnQgPSByZWFkQWxsU3luYyhEZW5vLnN0ZGluKTtcbiAqXG4gKiAvLyBFeGFtcGxlIGZyb20gZmlsZVxuICogY29uc3QgZmlsZSA9IERlbm8ub3BlblN5bmMoXCJteV9maWxlLnR4dFwiLCB7cmVhZDogdHJ1ZX0pO1xuICogY29uc3QgbXlGaWxlQ29udGVudCA9IHJlYWRBbGxTeW5jKGZpbGUpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGJ1ZmZlclxuICogY29uc3QgbXlEYXRhID0gbmV3IFVpbnQ4QXJyYXkoMTAwKTtcbiAqIC8vIC4uLiBmaWxsIG15RGF0YSBhcnJheSB3aXRoIGRhdGFcbiAqIGNvbnN0IHJlYWRlciA9IG5ldyBCdWZmZXIobXlEYXRhLmJ1ZmZlcik7XG4gKiBjb25zdCBidWZmZXJDb250ZW50ID0gcmVhZEFsbFN5bmMocmVhZGVyKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEFsbFN5bmMocjogRGVuby5SZWFkZXJTeW5jKTogVWludDhBcnJheSB7XG4gIGNvbnN0IGJ1ZiA9IG5ldyBCdWZmZXIoKTtcbiAgYnVmLnJlYWRGcm9tU3luYyhyKTtcbiAgcmV0dXJuIGJ1Zi5ieXRlcygpO1xufVxuXG4vKiogV3JpdGUgYWxsIHRoZSBjb250ZW50IG9mIHRoZSBhcnJheSBidWZmZXIgKGBhcnJgKSB0byB0aGUgd3JpdGVyIChgd2ApLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBCdWZmZXIgfSBmcm9tIFwiLi4vaW8vYnVmZmVyLnRzXCI7XG4gKiBpbXBvcnQgeyB3cml0ZUFsbCB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcblxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIHN0ZG91dFxuICogbGV0IGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogYXdhaXQgd3JpdGVBbGwoRGVuby5zdGRvdXQsIGNvbnRlbnRCeXRlcyk7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIGZpbGVcbiAqIGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogY29uc3QgZmlsZSA9IGF3YWl0IERlbm8ub3BlbigndGVzdC5maWxlJywge3dyaXRlOiB0cnVlfSk7XG4gKiBhd2FpdCB3cml0ZUFsbChmaWxlLCBjb250ZW50Qnl0ZXMpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIGJ1ZmZlclxuICogY29udGVudEJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFwiSGVsbG8gV29ybGRcIik7XG4gKiBjb25zdCB3cml0ZXIgPSBuZXcgQnVmZmVyKCk7XG4gKiBhd2FpdCB3cml0ZUFsbCh3cml0ZXIsIGNvbnRlbnRCeXRlcyk7XG4gKiBjb25zb2xlLmxvZyh3cml0ZXIuYnl0ZXMoKS5sZW5ndGgpOyAgLy8gMTFcbiAqIGBgYFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVBbGwodzogRGVuby5Xcml0ZXIsIGFycjogVWludDhBcnJheSkge1xuICBsZXQgbndyaXR0ZW4gPSAwO1xuICB3aGlsZSAobndyaXR0ZW4gPCBhcnIubGVuZ3RoKSB7XG4gICAgbndyaXR0ZW4gKz0gYXdhaXQgdy53cml0ZShhcnIuc3ViYXJyYXkobndyaXR0ZW4pKTtcbiAgfVxufVxuXG4vKiogU3luY2hyb25vdXNseSB3cml0ZSBhbGwgdGhlIGNvbnRlbnQgb2YgdGhlIGFycmF5IGJ1ZmZlciAoYGFycmApIHRvIHRoZVxuICogd3JpdGVyIChgd2ApLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBCdWZmZXIgfSBmcm9tIFwiLi4vaW8vYnVmZmVyLnRzXCI7XG4gKiBpbXBvcnQgeyB3cml0ZUFsbFN5bmMgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIHN0ZG91dFxuICogbGV0IGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogd3JpdGVBbGxTeW5jKERlbm8uc3Rkb3V0LCBjb250ZW50Qnl0ZXMpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBmaWxlXG4gKiBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIGNvbnN0IGZpbGUgPSBEZW5vLm9wZW5TeW5jKCd0ZXN0LmZpbGUnLCB7d3JpdGU6IHRydWV9KTtcbiAqIHdyaXRlQWxsU3luYyhmaWxlLCBjb250ZW50Qnl0ZXMpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSB3cml0aW5nIHRvIGJ1ZmZlclxuICogY29udGVudEJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFwiSGVsbG8gV29ybGRcIik7XG4gKiBjb25zdCB3cml0ZXIgPSBuZXcgQnVmZmVyKCk7XG4gKiB3cml0ZUFsbFN5bmMod3JpdGVyLCBjb250ZW50Qnl0ZXMpO1xuICogY29uc29sZS5sb2cod3JpdGVyLmJ5dGVzKCkubGVuZ3RoKTsgIC8vIDExXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlQWxsU3luYyh3OiBEZW5vLldyaXRlclN5bmMsIGFycjogVWludDhBcnJheSk6IHZvaWQge1xuICBsZXQgbndyaXR0ZW4gPSAwO1xuICB3aGlsZSAobndyaXR0ZW4gPCBhcnIubGVuZ3RoKSB7XG4gICAgbndyaXR0ZW4gKz0gdy53cml0ZVN5bmMoYXJyLnN1YmFycmF5KG53cml0dGVuKSk7XG4gIH1cbn1cblxuLyoqIFR1cm5zIGEgUmVhZGVyLCBgcmAsIGludG8gYW4gYXN5bmMgaXRlcmF0b3IuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGl0ZXJhdGVSZWFkZXIgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogbGV0IGYgPSBhd2FpdCBEZW5vLm9wZW4oXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgaXRlcmF0ZVJlYWRlcihmKSkge1xuICogICBjb25zb2xlLmxvZyhjaHVuayk7XG4gKiB9XG4gKiBmLmNsb3NlKCk7XG4gKiBgYGBcbiAqXG4gKiBTZWNvbmQgYXJndW1lbnQgY2FuIGJlIHVzZWQgdG8gdHVuZSBzaXplIG9mIGEgYnVmZmVyLlxuICogRGVmYXVsdCBzaXplIG9mIHRoZSBidWZmZXIgaXMgMzJrQi5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgaXRlcmF0ZVJlYWRlciB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiBsZXQgZiA9IGF3YWl0IERlbm8ub3BlbihcIi9ldGMvcGFzc3dkXCIpO1xuICogY29uc3QgaXQgPSBpdGVyYXRlUmVhZGVyKGYsIHtcbiAqICAgYnVmU2l6ZTogMTAyNCAqIDEwMjRcbiAqIH0pO1xuICogZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiBpdCkge1xuICogICBjb25zb2xlLmxvZyhjaHVuayk7XG4gKiB9XG4gKiBmLmNsb3NlKCk7XG4gKiBgYGBcbiAqXG4gKiBJdGVyYXRvciB1c2VzIGFuIGludGVybmFsIGJ1ZmZlciBvZiBmaXhlZCBzaXplIGZvciBlZmZpY2llbmN5OyBpdCByZXR1cm5zXG4gKiBhIHZpZXcgb24gdGhhdCBidWZmZXIgb24gZWFjaCBpdGVyYXRpb24uIEl0IGlzIHRoZXJlZm9yZSBjYWxsZXInc1xuICogcmVzcG9uc2liaWxpdHkgdG8gY29weSBjb250ZW50cyBvZiB0aGUgYnVmZmVyIGlmIG5lZWRlZDsgb3RoZXJ3aXNlIHRoZVxuICogbmV4dCBpdGVyYXRpb24gd2lsbCBvdmVyd3JpdGUgY29udGVudHMgb2YgcHJldmlvdXNseSByZXR1cm5lZCBjaHVuay5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uKiBpdGVyYXRlUmVhZGVyKFxuICByOiBEZW5vLlJlYWRlcixcbiAgb3B0aW9ucz86IHtcbiAgICBidWZTaXplPzogbnVtYmVyO1xuICB9LFxuKTogQXN5bmNJdGVyYWJsZUl0ZXJhdG9yPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgYnVmU2l6ZSA9IG9wdGlvbnM/LmJ1ZlNpemUgPz8gREVGQVVMVF9CVUZGRVJfU0laRTtcbiAgY29uc3QgYiA9IG5ldyBVaW50OEFycmF5KGJ1ZlNpemUpO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHIucmVhZChiKTtcbiAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB5aWVsZCBiLnN1YmFycmF5KDAsIHJlc3VsdCk7XG4gIH1cbn1cblxuLyoqIFR1cm5zIGEgUmVhZGVyU3luYywgYHJgLCBpbnRvIGFuIGl0ZXJhdG9yLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpdGVyYXRlUmVhZGVyU3luYyB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiBsZXQgZiA9IERlbm8ub3BlblN5bmMoXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGZvciAoY29uc3QgY2h1bmsgb2YgaXRlcmF0ZVJlYWRlclN5bmMoZikpIHtcbiAqICAgY29uc29sZS5sb2coY2h1bmspO1xuICogfVxuICogZi5jbG9zZSgpO1xuICogYGBgXG4gKlxuICogU2Vjb25kIGFyZ3VtZW50IGNhbiBiZSB1c2VkIHRvIHR1bmUgc2l6ZSBvZiBhIGJ1ZmZlci5cbiAqIERlZmF1bHQgc2l6ZSBvZiB0aGUgYnVmZmVyIGlzIDMya0IuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGl0ZXJhdGVSZWFkZXJTeW5jIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuXG4gKiBsZXQgZiA9IGF3YWl0IERlbm8ub3BlbihcIi9ldGMvcGFzc3dkXCIpO1xuICogY29uc3QgaXRlciA9IGl0ZXJhdGVSZWFkZXJTeW5jKGYsIHtcbiAqICAgYnVmU2l6ZTogMTAyNCAqIDEwMjRcbiAqIH0pO1xuICogZm9yIChjb25zdCBjaHVuayBvZiBpdGVyKSB7XG4gKiAgIGNvbnNvbGUubG9nKGNodW5rKTtcbiAqIH1cbiAqIGYuY2xvc2UoKTtcbiAqIGBgYFxuICpcbiAqIEl0ZXJhdG9yIHVzZXMgYW4gaW50ZXJuYWwgYnVmZmVyIG9mIGZpeGVkIHNpemUgZm9yIGVmZmljaWVuY3k7IGl0IHJldHVybnNcbiAqIGEgdmlldyBvbiB0aGF0IGJ1ZmZlciBvbiBlYWNoIGl0ZXJhdGlvbi4gSXQgaXMgdGhlcmVmb3JlIGNhbGxlcidzXG4gKiByZXNwb25zaWJpbGl0eSB0byBjb3B5IGNvbnRlbnRzIG9mIHRoZSBidWZmZXIgaWYgbmVlZGVkOyBvdGhlcndpc2UgdGhlXG4gKiBuZXh0IGl0ZXJhdGlvbiB3aWxsIG92ZXJ3cml0ZSBjb250ZW50cyBvZiBwcmV2aW91c2x5IHJldHVybmVkIGNodW5rLlxuICovXG5leHBvcnQgZnVuY3Rpb24qIGl0ZXJhdGVSZWFkZXJTeW5jKFxuICByOiBEZW5vLlJlYWRlclN5bmMsXG4gIG9wdGlvbnM/OiB7XG4gICAgYnVmU2l6ZT86IG51bWJlcjtcbiAgfSxcbik6IEl0ZXJhYmxlSXRlcmF0b3I8VWludDhBcnJheT4ge1xuICBjb25zdCBidWZTaXplID0gb3B0aW9ucz8uYnVmU2l6ZSA/PyBERUZBVUxUX0JVRkZFUl9TSVpFO1xuICBjb25zdCBiID0gbmV3IFVpbnQ4QXJyYXkoYnVmU2l6ZSk7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gci5yZWFkU3luYyhiKTtcbiAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB5aWVsZCBiLnN1YmFycmF5KDAsIHJlc3VsdCk7XG4gIH1cbn1cblxuLyoqIENvcGllcyBmcm9tIGBzcmNgIHRvIGBkc3RgIHVudGlsIGVpdGhlciBFT0YgKGBudWxsYCkgaXMgcmVhZCBmcm9tIGBzcmNgIG9yXG4gKiBhbiBlcnJvciBvY2N1cnMuIEl0IHJlc29sdmVzIHRvIHRoZSBudW1iZXIgb2YgYnl0ZXMgY29waWVkIG9yIHJlamVjdHMgd2l0aFxuICogdGhlIGZpcnN0IGVycm9yIGVuY291bnRlcmVkIHdoaWxlIGNvcHlpbmcuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGNvcHkgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogY29uc3Qgc291cmNlID0gYXdhaXQgRGVuby5vcGVuKFwibXlfZmlsZS50eHRcIik7XG4gKiBjb25zdCBieXRlc0NvcGllZDEgPSBhd2FpdCBjb3B5KHNvdXJjZSwgRGVuby5zdGRvdXQpO1xuICogY29uc3QgZGVzdGluYXRpb24gPSBhd2FpdCBEZW5vLmNyZWF0ZShcIm15X2ZpbGVfMi50eHRcIik7XG4gKiBjb25zdCBieXRlc0NvcGllZDIgPSBhd2FpdCBjb3B5KHNvdXJjZSwgZGVzdGluYXRpb24pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHNyYyBUaGUgc291cmNlIHRvIGNvcHkgZnJvbVxuICogQHBhcmFtIGRzdCBUaGUgZGVzdGluYXRpb24gdG8gY29weSB0b1xuICogQHBhcmFtIG9wdGlvbnMgQ2FuIGJlIHVzZWQgdG8gdHVuZSBzaXplIG9mIHRoZSBidWZmZXIuIERlZmF1bHQgc2l6ZSBpcyAzMmtCXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3B5KFxuICBzcmM6IERlbm8uUmVhZGVyLFxuICBkc3Q6IERlbm8uV3JpdGVyLFxuICBvcHRpb25zPzoge1xuICAgIGJ1ZlNpemU/OiBudW1iZXI7XG4gIH0sXG4pOiBQcm9taXNlPG51bWJlcj4ge1xuICBsZXQgbiA9IDA7XG4gIGNvbnN0IGJ1ZlNpemUgPSBvcHRpb25zPy5idWZTaXplID8/IERFRkFVTFRfQlVGRkVSX1NJWkU7XG4gIGNvbnN0IGIgPSBuZXcgVWludDhBcnJheShidWZTaXplKTtcbiAgbGV0IGdvdEVPRiA9IGZhbHNlO1xuICB3aGlsZSAoZ290RU9GID09PSBmYWxzZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNyYy5yZWFkKGIpO1xuICAgIGlmIChyZXN1bHQgPT09IG51bGwpIHtcbiAgICAgIGdvdEVPRiA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBud3JpdHRlbiA9IDA7XG4gICAgICB3aGlsZSAobndyaXR0ZW4gPCByZXN1bHQpIHtcbiAgICAgICAgbndyaXR0ZW4gKz0gYXdhaXQgZHN0LndyaXRlKGIuc3ViYXJyYXkobndyaXR0ZW4sIHJlc3VsdCkpO1xuICAgICAgfVxuICAgICAgbiArPSBud3JpdHRlbjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG47XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuaW1wb3J0IHsgZnJvbUZpbGVVcmwgfSBmcm9tIFwiLi4vLi4vcGF0aC9tb2QudHNcIjtcbmltcG9ydCB7IHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlciB9IGZyb20gXCIuLi8uLi9zdHJlYW1zL2NvbnZlcnNpb24udHNcIjtcblxuY29uc3QgY2xpZW50cyA9IG5ldyBNYXA8bnVtYmVyLCBXZWJTb2NrZXQ+KCk7XG5sZXQgY2xpZW50SWQgPSAwO1xuZnVuY3Rpb24gZGlzcGF0Y2gobXNnOiBzdHJpbmcpOiB2b2lkIHtcbiAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cy52YWx1ZXMoKSkge1xuICAgIGNsaWVudC5zZW5kKG1zZyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gd3NIYW5kbGVyKHdzOiBXZWJTb2NrZXQpIHtcbiAgY29uc3QgaWQgPSArK2NsaWVudElkO1xuICBjbGllbnRzLnNldChpZCwgd3MpO1xuICB3cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgZGlzcGF0Y2goYENvbm5lY3RlZDogWyR7aWR9XWApO1xuICB9O1xuICB3cy5vbm1lc3NhZ2UgPSAoZSkgPT4ge1xuICAgIGNvbnNvbGUubG9nKGBtc2c6JHtpZH1gLCBlLmRhdGEpO1xuICAgIGRpc3BhdGNoKGBbJHtpZH1dOiAke2UuZGF0YX1gKTtcbiAgfTtcbiAgd3Mub25jbG9zZSA9ICgpID0+IHtcbiAgICBjbGllbnRzLmRlbGV0ZShpZCk7XG4gICAgZGlzcGF0Y2goYENsb3NlZDogWyR7aWR9XWApO1xuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXF1ZXN0SGFuZGxlcihyZXE6IERlbm8uUmVxdWVzdEV2ZW50KSB7XG4gIGNvbnN0IHBhdGhuYW1lID0gbmV3IFVSTChyZXEucmVxdWVzdC51cmwpLnBhdGhuYW1lO1xuICBpZiAocmVxLnJlcXVlc3QubWV0aG9kID09PSBcIkdFVFwiICYmIHBhdGhuYW1lID09PSBcIi9cIikge1xuICAgIC8vU2VydmUgd2l0aCBoYWNrXG4gICAgY29uc3QgdSA9IG5ldyBVUkwoXCIuL2luZGV4Lmh0bWxcIiwgaW1wb3J0Lm1ldGEudXJsKTtcbiAgICBpZiAodS5wcm90b2NvbC5zdGFydHNXaXRoKFwiaHR0cFwiKSkge1xuICAgICAgLy8gc2VydmVyIGxhdW5jaGVkIGJ5IGRlbm8gcnVuIGh0dHAocyk6Ly8uLi4vc2VydmVyLnRzLFxuICAgICAgZmV0Y2godS5ocmVmKS50aGVuKGFzeW5jIChyZXNwKSA9PiB7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBuZXcgVWludDhBcnJheShhd2FpdCByZXNwLmFycmF5QnVmZmVyKCkpO1xuICAgICAgICByZXEucmVzcG9uZFdpdGgoXG4gICAgICAgICAgbmV3IFJlc3BvbnNlKGJvZHksIHtcbiAgICAgICAgICAgIHN0YXR1czogcmVzcC5zdGF0dXMsXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgIFwiY29udGVudC10eXBlXCI6IFwidGV4dC9odG1sXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHNlcnZlciBsYXVuY2hlZCBieSBkZW5vIHJ1biAuL3NlcnZlci50c1xuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IERlbm8ub3Blbihmcm9tRmlsZVVybCh1KSk7XG4gICAgICByZXEucmVzcG9uZFdpdGgoXG4gICAgICAgIG5ldyBSZXNwb25zZShyZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIoZmlsZSksIHtcbiAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICBcImNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoXG4gICAgcmVxLnJlcXVlc3QubWV0aG9kID09PSBcIkdFVFwiICYmIHBhdGhuYW1lID09PSBcIi9mYXZpY29uLmljb1wiXG4gICkge1xuICAgIHJlcS5yZXNwb25kV2l0aChSZXNwb25zZS5yZWRpcmVjdChcImh0dHBzOi8vZGVuby5sYW5kL2Zhdmljb24uaWNvXCIsIDMwMikpO1xuICB9IGVsc2UgaWYgKHJlcS5yZXF1ZXN0Lm1ldGhvZCA9PT0gXCJHRVRcIiAmJiBwYXRobmFtZSA9PT0gXCIvd3NcIikge1xuICAgIGNvbnN0IHsgc29ja2V0LCByZXNwb25zZSB9ID0gRGVuby51cGdyYWRlV2ViU29ja2V0KHJlcS5yZXF1ZXN0KTtcbiAgICB3c0hhbmRsZXIoc29ja2V0KTtcbiAgICByZXEucmVzcG9uZFdpdGgocmVzcG9uc2UpO1xuICB9XG59XG5cbmNvbnN0IHNlcnZlciA9IERlbm8ubGlzdGVuKHsgcG9ydDogODA4MCB9KTtcbmNvbnNvbGUubG9nKFwiY2hhdCBzZXJ2ZXIgc3RhcnRpbmcgb24gOjgwODAuLi4uXCIpO1xuXG5mb3IgYXdhaXQgKGNvbnN0IGNvbm4gb2Ygc2VydmVyKSB7XG4gIChhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaHR0cENvbm4gPSBEZW5vLnNlcnZlSHR0cChjb25uKTtcbiAgICBmb3IgYXdhaXQgKGNvbnN0IHJlcXVlc3RFdmVudCBvZiBodHRwQ29ubikge1xuICAgICAgcmVxdWVzdEhhbmRsZXIocmVxdWVzdEV2ZW50KTtcbiAgICB9XG4gIH0pKCk7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS08sTUFBTSxTQUFpQixBQUFDLENBQUEsSUFBTTtJQUVuQyxNQUFNLEVBQUUsTUFBQSxNQUFJLEVBQUUsR0FBRztJQUNqQixJ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 diff --git a/tests/__snapshots__/transpile/absolute/mapping.json b/tests/__snapshots__/transpile/absolute/mapping.json new file mode 100644 index 0000000..48d4dd4 --- /dev/null +++ b/tests/__snapshots__/transpile/absolute/mapping.json @@ -0,0 +1,3 @@ +{ + "file:///testdata/mod.ts": "0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js" +} diff --git a/tests/__snapshots__/transpile/absolute/modules/0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js b/tests/__snapshots__/transpile/absolute/modules/0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js new file mode 100644 index 0000000..e4c29b2 --- /dev/null +++ b/tests/__snapshots__/transpile/absolute/modules/0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js @@ -0,0 +1,4 @@ +export default function hello() { + return "Hello there!"; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vdGVzdGRhdGEvbW9kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGhlbGxvKCk6IHN0cmluZyB7XG4gIHJldHVybiBcIkhlbGxvIHRoZXJlIVwiO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGVBQWUsU0FBUyxRQUFnQjtJQUN0QyxPQUFPO0FBQ1QsQ0FBQyJ9 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/relative/mapping.json b/tests/__snapshots__/transpile/relative/mapping.json new file mode 100644 index 0000000..48d4dd4 --- /dev/null +++ b/tests/__snapshots__/transpile/relative/mapping.json @@ -0,0 +1,3 @@ +{ + "file:///testdata/mod.ts": "0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js" +} diff --git a/tests/__snapshots__/transpile/relative/modules/0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js b/tests/__snapshots__/transpile/relative/modules/0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js new file mode 100644 index 0000000..e4c29b2 --- /dev/null +++ b/tests/__snapshots__/transpile/relative/modules/0BJ1Cp_wwHSv6YnJzSlY2UlxpSc.js @@ -0,0 +1,4 @@ +export default function hello() { + return "Hello there!"; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vdGVzdGRhdGEvbW9kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGhlbGxvKCk6IHN0cmluZyB7XG4gIHJldHVybiBcIkhlbGxvIHRoZXJlIVwiO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGVBQWUsU0FBUyxRQUFnQjtJQUN0QyxPQUFPO0FBQ1QsQ0FBQyJ9 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/mapping.json b/tests/__snapshots__/transpile/remote/mapping.json new file mode 100644 index 0000000..02f1832 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/mapping.json @@ -0,0 +1,20 @@ +{ + "https://deno.land/std@0.140.0/_util/assert.ts": "nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js", + "https://deno.land/std@0.140.0/_util/os.ts": "ebsv4XtKEF8sxrDsnkLX8K9VdOA.js", + "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "p5wE1hCF6dGYMZ41YnIQs2go2is.js", + "https://deno.land/std@0.140.0/bytes/equals.ts": "jO4Cj24EIKVTiTvdPctAVhckzgg.js", + "https://deno.land/std@0.140.0/bytes/mod.ts": "WStdDhyHbKYy_C9CJ39RDks1VaY.js", + "https://deno.land/std@0.140.0/examples/chat/server.ts": "VR9N5EtRGYTL6BL2wtaFnqW-AuA.js", + "https://deno.land/std@0.140.0/io/buffer.ts": "npEsX-46oQUgZNw2Jkxv5i4eWDM.js", + "https://deno.land/std@0.140.0/io/types.d.ts": "7HctcYJMo9RPESb8_8SnGpYMx1U.js", + "https://deno.land/std@0.140.0/path/_constants.ts": "WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js", + "https://deno.land/std@0.140.0/path/_interface.ts": "wme9EIsCB7sfOz5qC_CSLRYajRk.js", + "https://deno.land/std@0.140.0/path/_util.ts": "7VWYTDioIHKQJaGRjtUtSbiHVG8.js", + "https://deno.land/std@0.140.0/path/common.ts": "WKh_-mE6UYta1pB11lfX_WOvFQ8.js", + "https://deno.land/std@0.140.0/path/glob.ts": "6asWNnLz5gIIvWCigeWDpbWva1Y.js", + "https://deno.land/std@0.140.0/path/mod.ts": "VUHr_YUyq8otV9YiIbexaSOfQCs.js", + "https://deno.land/std@0.140.0/path/posix.ts": "kWDlQkpYLFWxtJdAejga3vZCeeM.js", + "https://deno.land/std@0.140.0/path/separator.ts": "TPW77jtLW1NbcwGdiav4OHTJd6g.js", + "https://deno.land/std@0.140.0/path/win32.ts": "WPpXvFGuxwYeU5ay2bDrdG4fV_g.js", + "https://deno.land/std@0.140.0/streams/conversion.ts": "ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js" +} diff --git a/tests/__snapshots__/transpile/remote/modules/6asWNnLz5gIIvWCigeWDpbWva1Y.js b/tests/__snapshots__/transpile/remote/modules/6asWNnLz5gIIvWCigeWDpbWva1Y.js new file mode 100644 index 0000000..bcb9c67 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/6asWNnLz5gIIvWCigeWDpbWva1Y.js @@ -0,0 +1,346 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +import { isWindows, osType } from "../_util/os.ts"; +import { SEP, SEP_PATTERN } from "./separator.ts"; +import * as _win32 from "./win32.ts"; +import * as _posix from "./posix.ts"; +const path = isWindows ? _win32 : _posix; +const { join , normalize } = path; +const regExpEscapeChars = [ + "!", + "$", + "(", + ")", + "*", + "+", + ".", + "=", + "?", + "[", + "\\", + "^", + "{", + "|" +]; +const rangeEscapeChars = [ + "-", + "\\", + "]" +]; +/** Convert a glob string to a regular expression. + * + * Tries to match bash glob expansion as closely as possible. + * + * Basic glob syntax: + * - `*` - Matches everything without leaving the path segment. + * - `?` - Matches any single character. + * - `{foo,bar}` - Matches `foo` or `bar`. + * - `[abcd]` - Matches `a`, `b`, `c` or `d`. + * - `[a-d]` - Matches `a`, `b`, `c` or `d`. + * - `[!abcd]` - Matches any single character besides `a`, `b`, `c` or `d`. + * - `[[::]]` - Matches any character belonging to ``. + * - `[[:alnum:]]` - Matches any digit or letter. + * - `[[:digit:]abc]` - Matches any digit, `a`, `b` or `c`. + * - See https://facelessuser.github.io/wcmatch/glob/#posix-character-classes + * for a complete list of supported character classes. + * - `\` - Escapes the next character for an `os` other than `"windows"`. + * - \` - Escapes the next character for `os` set to `"windows"`. + * - `/` - Path separator. + * - `\` - Additional path separator only for `os` set to `"windows"`. + * + * Extended syntax: + * - Requires `{ extended: true }`. + * - `?(foo|bar)` - Matches 0 or 1 instance of `{foo,bar}`. + * - `@(foo|bar)` - Matches 1 instance of `{foo,bar}`. They behave the same. + * - `*(foo|bar)` - Matches _n_ instances of `{foo,bar}`. + * - `+(foo|bar)` - Matches _n > 0_ instances of `{foo,bar}`. + * - `!(foo|bar)` - Matches anything other than `{foo,bar}`. + * - See https://www.linuxjournal.com/content/bash-extended-globbing. + * + * Globstar syntax: + * - Requires `{ globstar: true }`. + * - `**` - Matches any number of any path segments. + * - Must comprise its entire path segment in the provided glob. + * - See https://www.linuxjournal.com/content/globstar-new-bash-globbing-option. + * + * Note the following properties: + * - The generated `RegExp` is anchored at both start and end. + * - Repeating and trailing separators are tolerated. Trailing separators in the + * provided glob have no meaning and are discarded. + * - Absolute globs will only match absolute paths, etc. + * - Empty globs will match nothing. + * - Any special glob syntax must be contained to one path segment. For example, + * `?(foo|bar/baz)` is invalid. The separator will take precedence and the + * first segment ends with an unclosed group. + * - If a path segment ends with unclosed groups or a dangling escape prefix, a + * parse error has occurred. Every character for that segment is taken + * literally in this event. + * + * Limitations: + * - A negative group like `!(foo|bar)` will wrongly be converted to a negative + * look-ahead followed by a wildcard. This means that `!(foo).js` will wrongly + * fail to match `foobar.js`, even though `foobar` is not `foo`. Effectively, + * `!(foo|bar)` is treated like `!(@(foo|bar)*)`. This will work correctly if + * the group occurs not nested at the end of the segment. */ export function globToRegExp(glob, { extended =true , globstar: globstarOption = true , os =osType , caseInsensitive =false } = {}) { + if (glob == "") { + return /(?!)/; + } + const sep = os == "windows" ? "(?:\\\\|/)+" : "/+"; + const sepMaybe = os == "windows" ? "(?:\\\\|/)*" : "/*"; + const seps = os == "windows" ? [ + "\\", + "/" + ] : [ + "/" + ]; + const globstar = os == "windows" ? "(?:[^\\\\/]*(?:\\\\|/|$)+)*" : "(?:[^/]*(?:/|$)+)*"; + const wildcard = os == "windows" ? "[^\\\\/]*" : "[^/]*"; + const escapePrefix = os == "windows" ? "`" : "\\"; + // Remove trailing separators. + let newLength = glob.length; + for(; newLength > 1 && seps.includes(glob[newLength - 1]); newLength--); + glob = glob.slice(0, newLength); + let regExpString = ""; + // Terminates correctly. Trust that `j` is incremented every iteration. + for(let j = 0; j < glob.length;){ + let segment = ""; + const groupStack = []; + let inRange = false; + let inEscape = false; + let endsWithSep = false; + let i = j; + // Terminates with `i` at the non-inclusive end of the current segment. + for(; i < glob.length && !seps.includes(glob[i]); i++){ + if (inEscape) { + inEscape = false; + const escapeChars = inRange ? rangeEscapeChars : regExpEscapeChars; + segment += escapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i]; + continue; + } + if (glob[i] == escapePrefix) { + inEscape = true; + continue; + } + if (glob[i] == "[") { + if (!inRange) { + inRange = true; + segment += "["; + if (glob[i + 1] == "!") { + i++; + segment += "^"; + } else if (glob[i + 1] == "^") { + i++; + segment += "\\^"; + } + continue; + } else if (glob[i + 1] == ":") { + let k = i + 1; + let value = ""; + while(glob[k + 1] != null && glob[k + 1] != ":"){ + value += glob[k + 1]; + k++; + } + if (glob[k + 1] == ":" && glob[k + 2] == "]") { + i = k + 2; + if (value == "alnum") segment += "\\dA-Za-z"; + else if (value == "alpha") segment += "A-Za-z"; + else if (value == "ascii") segment += "\x00-\x7F"; + else if (value == "blank") segment += "\t "; + else if (value == "cntrl") segment += "\x00-\x1F\x7F"; + else if (value == "digit") segment += "\\d"; + else if (value == "graph") segment += "\x21-\x7E"; + else if (value == "lower") segment += "a-z"; + else if (value == "print") segment += "\x20-\x7E"; + else if (value == "punct") { + segment += "!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_‘{|}~"; + } else if (value == "space") segment += "\\s\v"; + else if (value == "upper") segment += "A-Z"; + else if (value == "word") segment += "\\w"; + else if (value == "xdigit") segment += "\\dA-Fa-f"; + continue; + } + } + } + if (glob[i] == "]" && inRange) { + inRange = false; + segment += "]"; + continue; + } + if (inRange) { + if (glob[i] == "\\") { + segment += `\\\\`; + } else { + segment += glob[i]; + } + continue; + } + if (glob[i] == ")" && groupStack.length > 0 && groupStack[groupStack.length - 1] != "BRACE") { + segment += ")"; + const type = groupStack.pop(); + if (type == "!") { + segment += wildcard; + } else if (type != "@") { + segment += type; + } + continue; + } + if (glob[i] == "|" && groupStack.length > 0 && groupStack[groupStack.length - 1] != "BRACE") { + segment += "|"; + continue; + } + if (glob[i] == "+" && extended && glob[i + 1] == "(") { + i++; + groupStack.push("+"); + segment += "(?:"; + continue; + } + if (glob[i] == "@" && extended && glob[i + 1] == "(") { + i++; + groupStack.push("@"); + segment += "(?:"; + continue; + } + if (glob[i] == "?") { + if (extended && glob[i + 1] == "(") { + i++; + groupStack.push("?"); + segment += "(?:"; + } else { + segment += "."; + } + continue; + } + if (glob[i] == "!" && extended && glob[i + 1] == "(") { + i++; + groupStack.push("!"); + segment += "(?!"; + continue; + } + if (glob[i] == "{") { + groupStack.push("BRACE"); + segment += "(?:"; + continue; + } + if (glob[i] == "}" && groupStack[groupStack.length - 1] == "BRACE") { + groupStack.pop(); + segment += ")"; + continue; + } + if (glob[i] == "," && groupStack[groupStack.length - 1] == "BRACE") { + segment += "|"; + continue; + } + if (glob[i] == "*") { + if (extended && glob[i + 1] == "(") { + i++; + groupStack.push("*"); + segment += "(?:"; + } else { + const prevChar = glob[i - 1]; + let numStars = 1; + while(glob[i + 1] == "*"){ + i++; + numStars++; + } + const nextChar = glob[i + 1]; + if (globstarOption && numStars == 2 && [ + ...seps, + undefined + ].includes(prevChar) && [ + ...seps, + undefined + ].includes(nextChar)) { + segment += globstar; + endsWithSep = true; + } else { + segment += wildcard; + } + } + continue; + } + segment += regExpEscapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i]; + } + // Check for unclosed groups or a dangling backslash. + if (groupStack.length > 0 || inRange || inEscape) { + // Parse failure. Take all characters from this segment literally. + segment = ""; + for (const c of glob.slice(j, i)){ + segment += regExpEscapeChars.includes(c) ? `\\${c}` : c; + endsWithSep = false; + } + } + regExpString += segment; + if (!endsWithSep) { + regExpString += i < glob.length ? sep : sepMaybe; + endsWithSep = true; + } + // Terminates with `i` at the start of the next segment. + while(seps.includes(glob[i]))i++; + // Check that the next value of `j` is indeed higher than the current value. + if (!(i > j)) { + throw new Error("Assertion failure: i > j (potential infinite loop)"); + } + j = i; + } + regExpString = `^${regExpString}$`; + return new RegExp(regExpString, caseInsensitive ? "i" : ""); +} +/** Test whether the given string is a glob */ export function isGlob(str) { + const chars = { + "{": "}", + "(": ")", + "[": "]" + }; + const regex = /\\(.)|(^!|\*|\?|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; + if (str === "") { + return false; + } + let match; + while(match = regex.exec(str)){ + if (match[2]) return true; + let idx = match.index + match[0].length; + // if an open bracket/brace/paren is escaped, + // set the index to the next closing character + const open = match[1]; + const close = open ? chars[open] : null; + if (open && close) { + const n = str.indexOf(close, idx); + if (n !== -1) { + idx = n + 1; + } + } + str = str.slice(idx); + } + return false; +} +/** Like normalize(), but doesn't collapse "**\/.." when `globstar` is true. */ export function normalizeGlob(glob, { globstar =false } = {}) { + if (glob.match(/\0/g)) { + throw new Error(`Glob contains invalid characters: "${glob}"`); + } + if (!globstar) { + return normalize(glob); + } + const s = SEP_PATTERN.source; + const badParentPattern = new RegExp(`(?<=(${s}|^)\\*\\*${s})\\.\\.(?=${s}|$)`, "g"); + return normalize(glob.replace(badParentPattern, "\0")).replace(/\0/g, ".."); +} +/** Like join(), but doesn't collapse "**\/.." when `globstar` is true. */ export function joinGlobs(globs, { extended =true , globstar =false } = {}) { + if (!globstar || globs.length == 0) { + return join(...globs); + } + if (globs.length === 0) return "."; + let joined; + for (const glob of globs){ + const path = glob; + if (path.length > 0) { + if (!joined) joined = path; + else joined += `${SEP}${path}`; + } + } + if (!joined) return "."; + return normalizeGlob(joined, { + extended, + globstar + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvZ2xvYi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5pbXBvcnQgeyBpc1dpbmRvd3MsIG9zVHlwZSB9IGZyb20gXCIuLi9fdXRpbC9vcy50c1wiO1xuaW1wb3J0IHsgU0VQLCBTRVBfUEFUVEVSTiB9IGZyb20gXCIuL3NlcGFyYXRvci50c1wiO1xuaW1wb3J0ICogYXMgX3dpbjMyIGZyb20gXCIuL3dpbjMyLnRzXCI7XG5pbXBvcnQgKiBhcyBfcG9zaXggZnJvbSBcIi4vcG9zaXgudHNcIjtcbmltcG9ydCB0eXBlIHsgT1NUeXBlIH0gZnJvbSBcIi4uL191dGlsL29zLnRzXCI7XG5cbmNvbnN0IHBhdGggPSBpc1dpbmRvd3MgPyBfd2luMzIgOiBfcG9zaXg7XG5jb25zdCB7IGpvaW4sIG5vcm1hbGl6ZSB9ID0gcGF0aDtcblxuZXhwb3J0IGludGVyZmFjZSBHbG9iT3B0aW9ucyB7XG4gIC8qKiBFeHRlbmRlZCBnbG9iIHN5bnRheC5cbiAgICogU2VlIGh0dHBzOi8vd3d3LmxpbnV4am91cm5hbC5jb20vY29udGVudC9iYXNoLWV4dGVuZGVkLWdsb2JiaW5nLiBEZWZhdWx0c1xuICAgKiB0byB0cnVlLiAqL1xuICBleHRlbmRlZD86IGJvb2xlYW47XG4gIC8qKiBHbG9ic3RhciBzeW50YXguXG4gICAqIFNlZSBodHRwczovL3d3dy5saW51eGpvdXJuYWwuY29tL2NvbnRlbnQvZ2xvYnN0YXItbmV3LWJhc2gtZ2xvYmJpbmctb3B0aW9uLlxuICAgKiBJZiBmYWxzZSwgYCoqYCBpcyB0cmVhdGVkIGxpa2UgYCpgLiBEZWZhdWx0cyB0byB0cnVlLiAqL1xuICBnbG9ic3Rhcj86IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIGdsb2JzdGFyIHNob3VsZCBiZSBjYXNlIGluc2Vuc2l0aXZlLiAqL1xuICBjYXNlSW5zZW5zaXRpdmU/OiBib29sZWFuO1xuICAvKiogT3BlcmF0aW5nIHN5c3RlbS4gRGVmYXVsdHMgdG8gdGhlIG5hdGl2ZSBPUy4gKi9cbiAgb3M/OiBPU1R5cGU7XG59XG5cbmV4cG9ydCB0eXBlIEdsb2JUb1JlZ0V4cE9wdGlvbnMgPSBHbG9iT3B0aW9ucztcblxuY29uc3QgcmVnRXhwRXNjYXBlQ2hhcnMgPSBbXG4gIFwiIVwiLFxuICBcIiRcIixcbiAgXCIoXCIsXG4gIFwiKVwiLFxuICBcIipcIixcbiAgXCIrXCIsXG4gIFwiLlwiLFxuICBcIj1cIixcbiAgXCI/XCIsXG4gIFwiW1wiLFxuICBcIlxcXFxcIixcbiAgXCJeXCIsXG4gIFwie1wiLFxuICBcInxcIixcbl07XG5jb25zdCByYW5nZUVzY2FwZUNoYXJzID0gW1wiLVwiLCBcIlxcXFxcIiwgXCJdXCJdO1xuXG4vKiogQ29udmVydCBhIGdsb2Igc3RyaW5nIHRvIGEgcmVndWxhciBleHByZXNzaW9uLlxuICpcbiAqIFRyaWVzIHRvIG1hdGNoIGJhc2ggZ2xvYiBleHBhbnNpb24gYXMgY2xvc2VseSBhcyBwb3NzaWJsZS5cbiAqXG4gKiBCYXNpYyBnbG9iIHN5bnRheDpcbiAqIC0gYCpgIC0gTWF0Y2hlcyBldmVyeXRoaW5nIHdpdGhvdXQgbGVhdmluZyB0aGUgcGF0aCBzZWdtZW50LlxuICogLSBgP2AgLSBNYXRjaGVzIGFueSBzaW5nbGUgY2hhcmFjdGVyLlxuICogLSBge2ZvbyxiYXJ9YCAtIE1hdGNoZXMgYGZvb2Agb3IgYGJhcmAuXG4gKiAtIGBbYWJjZF1gIC0gTWF0Y2hlcyBgYWAsIGBiYCwgYGNgIG9yIGBkYC5cbiAqIC0gYFthLWRdYCAtIE1hdGNoZXMgYGFgLCBgYmAsIGBjYCBvciBgZGAuXG4gKiAtIGBbIWFiY2RdYCAtIE1hdGNoZXMgYW55IHNpbmdsZSBjaGFyYWN0ZXIgYmVzaWRlcyBgYWAsIGBiYCwgYGNgIG9yIGBkYC5cbiAqIC0gYFtbOjxjbGFzcz46XV1gIC0gTWF0Y2hlcyBhbnkgY2hhcmFjdGVyIGJlbG9uZ2luZyB0byBgPGNsYXNzPmAuXG4gKiAgICAgLSBgW1s6YWxudW06XV1gIC0gTWF0Y2hlcyBhbnkgZGlnaXQgb3IgbGV0dGVyLlxuICogICAgIC0gYFtbOmRpZ2l0Ol1hYmNdYCAtIE1hdGNoZXMgYW55IGRpZ2l0LCBgYWAsIGBiYCBvciBgY2AuXG4gKiAgICAgLSBTZWUgaHR0cHM6Ly9mYWNlbGVzc3VzZXIuZ2l0aHViLmlvL3djbWF0Y2gvZ2xvYi8jcG9zaXgtY2hhcmFjdGVyLWNsYXNzZXNcbiAqICAgICAgIGZvciBhIGNvbXBsZXRlIGxpc3Qgb2Ygc3VwcG9ydGVkIGNoYXJhY3RlciBjbGFzc2VzLlxuICogLSBgXFxgIC0gRXNjYXBlcyB0aGUgbmV4dCBjaGFyYWN0ZXIgZm9yIGFuIGBvc2Agb3RoZXIgdGhhbiBgXCJ3aW5kb3dzXCJgLlxuICogLSBcXGAgLSBFc2NhcGVzIHRoZSBuZXh0IGNoYXJhY3RlciBmb3IgYG9zYCBzZXQgdG8gYFwid2luZG93c1wiYC5cbiAqIC0gYC9gIC0gUGF0aCBzZXBhcmF0b3IuXG4gKiAtIGBcXGAgLSBBZGRpdGlvbmFsIHBhdGggc2VwYXJhdG9yIG9ubHkgZm9yIGBvc2Agc2V0IHRvIGBcIndpbmRvd3NcImAuXG4gKlxuICogRXh0ZW5kZWQgc3ludGF4OlxuICogLSBSZXF1aXJlcyBgeyBleHRlbmRlZDogdHJ1ZSB9YC5cbiAqIC0gYD8oZm9vfGJhcilgIC0gTWF0Y2hlcyAwIG9yIDEgaW5zdGFuY2Ugb2YgYHtmb28sYmFyfWAuXG4gKiAtIGBAKGZvb3xiYXIpYCAtIE1hdGNoZXMgMSBpbnN0YW5jZSBvZiBge2ZvbyxiYXJ9YC4gVGhleSBiZWhhdmUgdGhlIHNhbWUuXG4gKiAtIGAqKGZvb3xiYXIpYCAtIE1hdGNoZXMgX25fIGluc3RhbmNlcyBvZiBge2ZvbyxiYXJ9YC5cbiAqIC0gYCsoZm9vfGJhcilgIC0gTWF0Y2hlcyBfbiA+IDBfIGluc3RhbmNlcyBvZiBge2ZvbyxiYXJ9YC5cbiAqIC0gYCEoZm9vfGJhcilgIC0gTWF0Y2hlcyBhbnl0aGluZyBvdGhlciB0aGFuIGB7Zm9vLGJhcn1gLlxuICogLSBTZWUgaHR0cHM6Ly93d3cubGludXhqb3VybmFsLmNvbS9jb250ZW50L2Jhc2gtZXh0ZW5kZWQtZ2xvYmJpbmcuXG4gKlxuICogR2xvYnN0YXIgc3ludGF4OlxuICogLSBSZXF1aXJlcyBgeyBnbG9ic3RhcjogdHJ1ZSB9YC5cbiAqIC0gYCoqYCAtIE1hdGNoZXMgYW55IG51bWJlciBvZiBhbnkgcGF0aCBzZWdtZW50cy5cbiAqICAgICAtIE11c3QgY29tcHJpc2UgaXRzIGVudGlyZSBwYXRoIHNlZ21lbnQgaW4gdGhlIHByb3ZpZGVkIGdsb2IuXG4gKiAtIFNlZSBodHRwczovL3d3dy5saW51eGpvdXJuYWwuY29tL2NvbnRlbnQvZ2xvYnN0YXItbmV3LWJhc2gtZ2xvYmJpbmctb3B0aW9uLlxuICpcbiAqIE5vdGUgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBUaGUgZ2VuZXJhdGVkIGBSZWdFeHBgIGlzIGFuY2hvcmVkIGF0IGJvdGggc3RhcnQgYW5kIGVuZC5cbiAqIC0gUmVwZWF0aW5nIGFuZCB0cmFpbGluZyBzZXBhcmF0b3JzIGFyZSB0b2xlcmF0ZWQuIFRyYWlsaW5nIHNlcGFyYXRvcnMgaW4gdGhlXG4gKiAgIHByb3ZpZGVkIGdsb2IgaGF2ZSBubyBtZWFuaW5nIGFuZCBhcmUgZGlzY2FyZGVkLlxuICogLSBBYnNvbHV0ZSBnbG9icyB3aWxsIG9ubHkgbWF0Y2ggYWJzb2x1dGUgcGF0aHMsIGV0Yy5cbiAqIC0gRW1wdHkgZ2xvYnMgd2lsbCBtYXRjaCBub3RoaW5nLlxuICogLSBBbnkgc3BlY2lhbCBnbG9iIHN5bnRheCBtdXN0IGJlIGNvbnRhaW5lZCB0byBvbmUgcGF0aCBzZWdtZW50LiBGb3IgZXhhbXBsZSxcbiAqICAgYD8oZm9vfGJhci9iYXopYCBpcyBpbnZhbGlkLiBUaGUgc2VwYXJhdG9yIHdpbGwgdGFrZSBwcmVjZWRlbmNlIGFuZCB0aGVcbiAqICAgZmlyc3Qgc2VnbWVudCBlbmRzIHdpdGggYW4gdW5jbG9zZWQgZ3JvdXAuXG4gKiAtIElmIGEgcGF0aCBzZWdtZW50IGVuZHMgd2l0aCB1bmNsb3NlZCBncm91cHMgb3IgYSBkYW5nbGluZyBlc2NhcGUgcHJlZml4LCBhXG4gKiAgIHBhcnNlIGVycm9yIGhhcyBvY2N1cnJlZC4gRXZlcnkgY2hhcmFjdGVyIGZvciB0aGF0IHNlZ21lbnQgaXMgdGFrZW5cbiAqICAgbGl0ZXJhbGx5IGluIHRoaXMgZXZlbnQuXG4gKlxuICogTGltaXRhdGlvbnM6XG4gKiAtIEEgbmVnYXRpdmUgZ3JvdXAgbGlrZSBgIShmb298YmFyKWAgd2lsbCB3cm9uZ2x5IGJlIGNvbnZlcnRlZCB0byBhIG5lZ2F0aXZlXG4gKiAgIGxvb2stYWhlYWQgZm9sbG93ZWQgYnkgYSB3aWxkY2FyZC4gVGhpcyBtZWFucyB0aGF0IGAhKGZvbykuanNgIHdpbGwgd3JvbmdseVxuICogICBmYWlsIHRvIG1hdGNoIGBmb29iYXIuanNgLCBldmVuIHRob3VnaCBgZm9vYmFyYCBpcyBub3QgYGZvb2AuIEVmZmVjdGl2ZWx5LFxuICogICBgIShmb298YmFyKWAgaXMgdHJlYXRlZCBsaWtlIGAhKEAoZm9vfGJhcikqKWAuIFRoaXMgd2lsbCB3b3JrIGNvcnJlY3RseSBpZlxuICogICB0aGUgZ3JvdXAgb2NjdXJzIG5vdCBuZXN0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgc2VnbWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnbG9iVG9SZWdFeHAoXG4gIGdsb2I6IHN0cmluZyxcbiAge1xuICAgIGV4dGVuZGVkID0gdHJ1ZSxcbiAgICBnbG9ic3RhcjogZ2xvYnN0YXJPcHRpb24gPSB0cnVlLFxuICAgIG9zID0gb3NUeXBlLFxuICAgIGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlLFxuICB9OiBHbG9iVG9SZWdFeHBPcHRpb25zID0ge30sXG4pOiBSZWdFeHAge1xuICBpZiAoZ2xvYiA9PSBcIlwiKSB7XG4gICAgcmV0dXJuIC8oPyEpLztcbiAgfVxuXG4gIGNvbnN0IHNlcCA9IG9zID09IFwid2luZG93c1wiID8gXCIoPzpcXFxcXFxcXHwvKStcIiA6IFwiLytcIjtcbiAgY29uc3Qgc2VwTWF5YmUgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiKD86XFxcXFxcXFx8LykqXCIgOiBcIi8qXCI7XG4gIGNvbnN0IHNlcHMgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFtcIlxcXFxcIiwgXCIvXCJdIDogW1wiL1wiXTtcbiAgY29uc3QgZ2xvYnN0YXIgPSBvcyA9PSBcIndpbmRvd3NcIlxuICAgID8gXCIoPzpbXlxcXFxcXFxcL10qKD86XFxcXFxcXFx8L3wkKSspKlwiXG4gICAgOiBcIig/OlteL10qKD86L3wkKSspKlwiO1xuICBjb25zdCB3aWxkY2FyZCA9IG9zID09IFwid2luZG93c1wiID8gXCJbXlxcXFxcXFxcL10qXCIgOiBcIlteL10qXCI7XG4gIGNvbnN0IGVzY2FwZVByZWZpeCA9IG9zID09IFwid2luZG93c1wiID8gXCJgXCIgOiBcIlxcXFxcIjtcblxuICAvLyBSZW1vdmUgdHJhaWxpbmcgc2VwYXJhdG9ycy5cbiAgbGV0IG5ld0xlbmd0aCA9IGdsb2IubGVuZ3RoO1xuICBmb3IgKDsgbmV3TGVuZ3RoID4gMSAmJiBzZXBzLmluY2x1ZGVzKGdsb2JbbmV3TGVuZ3RoIC0gMV0pOyBuZXdMZW5ndGgtLSk7XG4gIGdsb2IgPSBnbG9iLnNsaWNlKDAsIG5ld0xlbmd0aCk7XG5cbiAgbGV0IHJlZ0V4cFN0cmluZyA9IFwiXCI7XG5cbiAgLy8gVGVybWluYXRlcyBjb3JyZWN0bHkuIFRydXN0IHRoYXQgYGpgIGlzIGluY3JlbWVudGVkIGV2ZXJ5IGl0ZXJhdGlvbi5cbiAgZm9yIChsZXQgaiA9IDA7IGogPCBnbG9iLmxlbmd0aDspIHtcbiAgICBsZXQgc2VnbWVudCA9IFwiXCI7XG4gICAgY29uc3QgZ3JvdXBTdGFjazogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgaW5SYW5nZSA9IGZhbHNlO1xuICAgIGxldCBpbkVzY2FwZSA9IGZhbHNlO1xuICAgIGxldCBlbmRzV2l0aFNlcCA9IGZhbHNlO1xuICAgIGxldCBpID0gajtcblxuICAgIC8vIFRlcm1pbmF0ZXMgd2l0aCBgaWAgYXQgdGhlIG5vbi1pbmNsdXNpdmUgZW5kIG9mIHRoZSBjdXJyZW50IHNlZ21lbnQuXG4gICAgZm9yICg7IGkgPCBnbG9iLmxlbmd0aCAmJiAhc2Vwcy5pbmNsdWRlcyhnbG9iW2ldKTsgaSsrKSB7XG4gICAgICBpZiAoaW5Fc2NhcGUpIHtcbiAgICAgICAgaW5Fc2NhcGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgZXNjYXBlQ2hhcnMgPSBpblJhbmdlID8gcmFuZ2VFc2NhcGVDaGFycyA6IHJlZ0V4cEVzY2FwZUNoYXJzO1xuICAgICAgICBzZWdtZW50ICs9IGVzY2FwZUNoYXJzLmluY2x1ZGVzKGdsb2JbaV0pID8gYFxcXFwke2dsb2JbaV19YCA6IGdsb2JbaV07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBlc2NhcGVQcmVmaXgpIHtcbiAgICAgICAgaW5Fc2NhcGUgPSB0cnVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCJbXCIpIHtcbiAgICAgICAgaWYgKCFpblJhbmdlKSB7XG4gICAgICAgICAgaW5SYW5nZSA9IHRydWU7XG4gICAgICAgICAgc2VnbWVudCArPSBcIltcIjtcbiAgICAgICAgICBpZiAoZ2xvYltpICsgMV0gPT0gXCIhXCIpIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gXCJeXCI7XG4gICAgICAgICAgfSBlbHNlIGlmIChnbG9iW2kgKyAxXSA9PSBcIl5cIikge1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgc2VnbWVudCArPSBcIlxcXFxeXCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGdsb2JbaSArIDFdID09IFwiOlwiKSB7XG4gICAgICAgICAgbGV0IGsgPSBpICsgMTtcbiAgICAgICAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgICAgICAgIHdoaWxlIChnbG9iW2sgKyAxXSAhPSBudWxsICYmIGdsb2JbayArIDFdICE9IFwiOlwiKSB7XG4gICAgICAgICAgICB2YWx1ZSArPSBnbG9iW2sgKyAxXTtcbiAgICAgICAgICAgIGsrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGdsb2JbayArIDFdID09IFwiOlwiICYmIGdsb2JbayArIDJdID09IFwiXVwiKSB7XG4gICAgICAgICAgICBpID0gayArIDI7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJhbG51bVwiKSBzZWdtZW50ICs9IFwiXFxcXGRBLVphLXpcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiYWxwaGFcIikgc2VnbWVudCArPSBcIkEtWmEtelwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJhc2NpaVwiKSBzZWdtZW50ICs9IFwiXFx4MDAtXFx4N0ZcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiYmxhbmtcIikgc2VnbWVudCArPSBcIlxcdCBcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiY250cmxcIikgc2VnbWVudCArPSBcIlxceDAwLVxceDFGXFx4N0ZcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiZGlnaXRcIikgc2VnbWVudCArPSBcIlxcXFxkXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImdyYXBoXCIpIHNlZ21lbnQgKz0gXCJcXHgyMS1cXHg3RVwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJsb3dlclwiKSBzZWdtZW50ICs9IFwiYS16XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcInByaW50XCIpIHNlZ21lbnQgKz0gXCJcXHgyMC1cXHg3RVwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJwdW5jdFwiKSB7XG4gICAgICAgICAgICAgIHNlZ21lbnQgKz0gXCIhXFxcIiMkJSYnKCkqKyxcXFxcLS4vOjs8PT4/QFtcXFxcXFxcXFxcXFxdXl/igJh7fH1+XCI7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IFwic3BhY2VcIikgc2VnbWVudCArPSBcIlxcXFxzXFx2XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcInVwcGVyXCIpIHNlZ21lbnQgKz0gXCJBLVpcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwid29yZFwiKSBzZWdtZW50ICs9IFwiXFxcXHdcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwieGRpZ2l0XCIpIHNlZ21lbnQgKz0gXCJcXFxcZEEtRmEtZlwiO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiXVwiICYmIGluUmFuZ2UpIHtcbiAgICAgICAgaW5SYW5nZSA9IGZhbHNlO1xuICAgICAgICBzZWdtZW50ICs9IFwiXVwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluUmFuZ2UpIHtcbiAgICAgICAgaWYgKGdsb2JbaV0gPT0gXCJcXFxcXCIpIHtcbiAgICAgICAgICBzZWdtZW50ICs9IGBcXFxcXFxcXGA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VnbWVudCArPSBnbG9iW2ldO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGdsb2JbaV0gPT0gXCIpXCIgJiYgZ3JvdXBTdGFjay5sZW5ndGggPiAwICYmXG4gICAgICAgIGdyb3VwU3RhY2tbZ3JvdXBTdGFjay5sZW5ndGggLSAxXSAhPSBcIkJSQUNFXCJcbiAgICAgICkge1xuICAgICAgICBzZWdtZW50ICs9IFwiKVwiO1xuICAgICAgICBjb25zdCB0eXBlID0gZ3JvdXBTdGFjay5wb3AoKSE7XG4gICAgICAgIGlmICh0eXBlID09IFwiIVwiKSB7XG4gICAgICAgICAgc2VnbWVudCArPSB3aWxkY2FyZDtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlICE9IFwiQFwiKSB7XG4gICAgICAgICAgc2VnbWVudCArPSB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGdsb2JbaV0gPT0gXCJ8XCIgJiYgZ3JvdXBTdGFjay5sZW5ndGggPiAwICYmXG4gICAgICAgIGdyb3VwU3RhY2tbZ3JvdXBTdGFjay5sZW5ndGggLSAxXSAhPSBcIkJSQUNFXCJcbiAgICAgICkge1xuICAgICAgICBzZWdtZW50ICs9IFwifFwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIrXCIgJiYgZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCIrXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIkBcIiAmJiBleHRlbmRlZCAmJiBnbG9iW2kgKyAxXSA9PSBcIihcIikge1xuICAgICAgICBpKys7XG4gICAgICAgIGdyb3VwU3RhY2sucHVzaChcIkBcIik7XG4gICAgICAgIHNlZ21lbnQgKz0gXCIoPzpcIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiP1wiKSB7XG4gICAgICAgIGlmIChleHRlbmRlZCAmJiBnbG9iW2kgKyAxXSA9PSBcIihcIikge1xuICAgICAgICAgIGkrKztcbiAgICAgICAgICBncm91cFN0YWNrLnB1c2goXCI/XCIpO1xuICAgICAgICAgIHNlZ21lbnQgKz0gXCIoPzpcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZWdtZW50ICs9IFwiLlwiO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIiFcIiAmJiBleHRlbmRlZCAmJiBnbG9iW2kgKyAxXSA9PSBcIihcIikge1xuICAgICAgICBpKys7XG4gICAgICAgIGdyb3VwU3RhY2sucHVzaChcIiFcIik7XG4gICAgICAgIHNlZ21lbnQgKz0gXCIoPyFcIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwie1wiKSB7XG4gICAgICAgIGdyb3VwU3RhY2sucHVzaChcIkJSQUNFXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIn1cIiAmJiBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gPT0gXCJCUkFDRVwiKSB7XG4gICAgICAgIGdyb3VwU3RhY2sucG9wKCk7XG4gICAgICAgIHNlZ21lbnQgKz0gXCIpXCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIixcIiAmJiBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gPT0gXCJCUkFDRVwiKSB7XG4gICAgICAgIHNlZ21lbnQgKz0gXCJ8XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIipcIikge1xuICAgICAgICBpZiAoZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgICAgZ3JvdXBTdGFjay5wdXNoKFwiKlwiKTtcbiAgICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgcHJldkNoYXIgPSBnbG9iW2kgLSAxXTtcbiAgICAgICAgICBsZXQgbnVtU3RhcnMgPSAxO1xuICAgICAgICAgIHdoaWxlIChnbG9iW2kgKyAxXSA9PSBcIipcIikge1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgbnVtU3RhcnMrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgbmV4dENoYXIgPSBnbG9iW2kgKyAxXTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBnbG9ic3Rhck9wdGlvbiAmJiBudW1TdGFycyA9PSAyICYmXG4gICAgICAgICAgICBbLi4uc2VwcywgdW5kZWZpbmVkXS5pbmNsdWRlcyhwcmV2Q2hhcikgJiZcbiAgICAgICAgICAgIFsuLi5zZXBzLCB1bmRlZmluZWRdLmluY2x1ZGVzKG5leHRDaGFyKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgc2VnbWVudCArPSBnbG9ic3RhcjtcbiAgICAgICAgICAgIGVuZHNXaXRoU2VwID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VnbWVudCArPSB3aWxkY2FyZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHNlZ21lbnQgKz0gcmVnRXhwRXNjYXBlQ2hhcnMuaW5jbHVkZXMoZ2xvYltpXSkgPyBgXFxcXCR7Z2xvYltpXX1gIDogZ2xvYltpXTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgdW5jbG9zZWQgZ3JvdXBzIG9yIGEgZGFuZ2xpbmcgYmFja3NsYXNoLlxuICAgIGlmIChncm91cFN0YWNrLmxlbmd0aCA+IDAgfHwgaW5SYW5nZSB8fCBpbkVzY2FwZSkge1xuICAgICAgLy8gUGFyc2UgZmFpbHVyZS4gVGFrZSBhbGwgY2hhcmFjdGVycyBmcm9tIHRoaXMgc2VnbWVudCBsaXRlcmFsbHkuXG4gICAgICBzZWdtZW50ID0gXCJcIjtcbiAgICAgIGZvciAoY29uc3QgYyBvZiBnbG9iLnNsaWNlKGosIGkpKSB7XG4gICAgICAgIHNlZ21lbnQgKz0gcmVnRXhwRXNjYXBlQ2hhcnMuaW5jbHVkZXMoYykgPyBgXFxcXCR7Y31gIDogYztcbiAgICAgICAgZW5kc1dpdGhTZXAgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZWdFeHBTdHJpbmcgKz0gc2VnbWVudDtcbiAgICBpZiAoIWVuZHNXaXRoU2VwKSB7XG4gICAgICByZWdFeHBTdHJpbmcgKz0gaSA8IGdsb2IubGVuZ3RoID8gc2VwIDogc2VwTWF5YmU7XG4gICAgICBlbmRzV2l0aFNlcCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gVGVybWluYXRlcyB3aXRoIGBpYCBhdCB0aGUgc3RhcnQgb2YgdGhlIG5leHQgc2VnbWVudC5cbiAgICB3aGlsZSAoc2Vwcy5pbmNsdWRlcyhnbG9iW2ldKSkgaSsrO1xuXG4gICAgLy8gQ2hlY2sgdGhhdCB0aGUgbmV4dCB2YWx1ZSBvZiBgamAgaXMgaW5kZWVkIGhpZ2hlciB0aGFuIHRoZSBjdXJyZW50IHZhbHVlLlxuICAgIGlmICghKGkgPiBqKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXNzZXJ0aW9uIGZhaWx1cmU6IGkgPiBqIChwb3RlbnRpYWwgaW5maW5pdGUgbG9vcClcIik7XG4gICAgfVxuICAgIGogPSBpO1xuICB9XG5cbiAgcmVnRXhwU3RyaW5nID0gYF4ke3JlZ0V4cFN0cmluZ30kYDtcbiAgcmV0dXJuIG5ldyBSZWdFeHAocmVnRXhwU3RyaW5nLCBjYXNlSW5zZW5zaXRpdmUgPyBcImlcIiA6IFwiXCIpO1xufVxuXG4vKiogVGVzdCB3aGV0aGVyIHRoZSBnaXZlbiBzdHJpbmcgaXMgYSBnbG9iICovXG5leHBvcnQgZnVuY3Rpb24gaXNHbG9iKHN0cjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IGNoYXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0geyBcIntcIjogXCJ9XCIsIFwiKFwiOiBcIilcIiwgXCJbXCI6IFwiXVwiIH07XG4gIGNvbnN0IHJlZ2V4ID1cbiAgICAvXFxcXCguKXwoXiF8XFwqfFxcP3xbXFxdLispXVxcP3xcXFtbXlxcXFxcXF1dK1xcXXxcXHtbXlxcXFx9XStcXH18XFwoXFw/WzohPV1bXlxcXFwpXStcXCl8XFwoW158XStcXHxbXlxcXFwpXStcXCkpLztcblxuICBpZiAoc3RyID09PSBcIlwiKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuXG4gIHdoaWxlICgobWF0Y2ggPSByZWdleC5leGVjKHN0cikpKSB7XG4gICAgaWYgKG1hdGNoWzJdKSByZXR1cm4gdHJ1ZTtcbiAgICBsZXQgaWR4ID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGg7XG5cbiAgICAvLyBpZiBhbiBvcGVuIGJyYWNrZXQvYnJhY2UvcGFyZW4gaXMgZXNjYXBlZCxcbiAgICAvLyBzZXQgdGhlIGluZGV4IHRvIHRoZSBuZXh0IGNsb3NpbmcgY2hhcmFjdGVyXG4gICAgY29uc3Qgb3BlbiA9IG1hdGNoWzFdO1xuICAgIGNvbnN0IGNsb3NlID0gb3BlbiA/IGNoYXJzW29wZW5dIDogbnVsbDtcbiAgICBpZiAob3BlbiAmJiBjbG9zZSkge1xuICAgICAgY29uc3QgbiA9IHN0ci5pbmRleE9mKGNsb3NlLCBpZHgpO1xuICAgICAgaWYgKG4gIT09IC0xKSB7XG4gICAgICAgIGlkeCA9IG4gKyAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIHN0ciA9IHN0ci5zbGljZShpZHgpO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogTGlrZSBub3JtYWxpemUoKSwgYnV0IGRvZXNuJ3QgY29sbGFwc2UgXCIqKlxcLy4uXCIgd2hlbiBgZ2xvYnN0YXJgIGlzIHRydWUuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplR2xvYihcbiAgZ2xvYjogc3RyaW5nLFxuICB7IGdsb2JzdGFyID0gZmFsc2UgfTogR2xvYk9wdGlvbnMgPSB7fSxcbik6IHN0cmluZyB7XG4gIGlmIChnbG9iLm1hdGNoKC9cXDAvZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEdsb2IgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzOiBcIiR7Z2xvYn1cImApO1xuICB9XG4gIGlmICghZ2xvYnN0YXIpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplKGdsb2IpO1xuICB9XG4gIGNvbnN0IHMgPSBTRVBfUEFUVEVSTi5zb3VyY2U7XG4gIGNvbnN0IGJhZFBhcmVudFBhdHRlcm4gPSBuZXcgUmVnRXhwKFxuICAgIGAoPzw9KCR7c318XilcXFxcKlxcXFwqJHtzfSlcXFxcLlxcXFwuKD89JHtzfXwkKWAsXG4gICAgXCJnXCIsXG4gICk7XG4gIHJldHVybiBub3JtYWxpemUoZ2xvYi5yZXBsYWNlKGJhZFBhcmVudFBhdHRlcm4sIFwiXFwwXCIpKS5yZXBsYWNlKC9cXDAvZywgXCIuLlwiKTtcbn1cblxuLyoqIExpa2Ugam9pbigpLCBidXQgZG9lc24ndCBjb2xsYXBzZSBcIioqXFwvLi5cIiB3aGVuIGBnbG9ic3RhcmAgaXMgdHJ1ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqb2luR2xvYnMoXG4gIGdsb2JzOiBzdHJpbmdbXSxcbiAgeyBleHRlbmRlZCA9IHRydWUsIGdsb2JzdGFyID0gZmFsc2UgfTogR2xvYk9wdGlvbnMgPSB7fSxcbik6IHN0cmluZyB7XG4gIGlmICghZ2xvYnN0YXIgfHwgZ2xvYnMubGVuZ3RoID09IDApIHtcbiAgICByZXR1cm4gam9pbiguLi5nbG9icyk7XG4gIH1cbiAgaWYgKGdsb2JzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuICBsZXQgam9pbmVkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgZ2xvYiBvZiBnbG9icykge1xuICAgIGNvbnN0IHBhdGggPSBnbG9iO1xuICAgIGlmIChwYXRoLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICgham9pbmVkKSBqb2luZWQgPSBwYXRoO1xuICAgICAgZWxzZSBqb2luZWQgKz0gYCR7U0VQfSR7cGF0aH1gO1xuICAgIH1cbiAgfVxuICBpZiAoIWpvaW5lZCkgcmV0dXJuIFwiLlwiO1xuICByZXR1cm4gbm9ybWFsaXplR2xvYihqb2luZWQsIHsgZXh0ZW5kZWQsIGdsb2JzdGFyIH0pO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxxQ0FBcUM7QUFFckMsU0FBUyxTQUFTLEVBQUUsTUFBTSxRQUFRLGlCQUFpQjtBQUNuRCxTQUFTLEdBQUcsRUFBRSxXQUFXLFFBQVEsaUJBQWlCO0FBQ2xELFlBQVksWUFBWSxhQUFhO0FBQ3JDLFlBQVksWUFBWSxhQUFhO0FBR3JDLE1BQU0sT0FBTyxZQUFZLFNBQVMsTUFBTTtBQUN4QyxNQUFNLEVBQUUsS0FBSSxFQUFFLFVBQVMsRUFBRSxHQUFHO0FBbUI1QixNQUFNLG9CQUFvQjtJQUN4QjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0NBQ0Q7QUFDRCxNQUFNLG1CQUFtQjtJQUFDO0lBQUs7SUFBTTtDQUFJO0FBRXpDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7NERBc0Q0RCxHQUM1RCxPQUFPLFNBQVMsYUFDZCxJQUFZLEVBQ1osRUFDRSxVQUFXLElBQUksQ0FBQSxFQUNmLFVBQVUsaUJBQWlCLElBQUksQ0FBQSxFQUMvQixJQUFLLE9BQU0sRUFDWCxpQkFBa0IsS0FBSyxDQUFBLEVBQ0gsR0FBRyxDQUFDLENBQUMsRUFDbkI7SUFDUixJQUFJLFFBQVEsSUFBSTtRQUNkLE9BQU87SUFDVCxDQUFDO0lBRUQsTUFBTSxNQUFNLE1BQU0sWUFBWSxnQkFBZ0IsSUFBSTtJQUNsRCxNQUFNLFdBQVcsTUFBTSxZQUFZLGdCQUFnQixJQUFJO0lBQ3ZELE1BQU0sT0FBTyxNQUFNLFlBQVk7UUFBQztRQUFNO0tBQUksR0FBRztRQUFDO0tBQUk7SUFDbEQsTUFBTSxXQUFXLE1BQU0sWUFDbkIsZ0NBQ0Esb0JBQW9CO0lBQ3hCLE1BQU0sV0FBVyxNQUFNLFlBQVksY0FBYyxPQUFPO0lBQ3hELE1BQU0sZUFBZSxNQUFNLFlBQVksTUFBTSxJQUFJO0lBRWpELDhCQUE4QjtJQUM5QixJQUFJLFlBQVksS0FBSyxNQUFNO0lBQzNCLE1BQU8sWUFBWSxLQUFLLEtBQUssUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsR0FBRztJQUM1RCxPQUFPLEtBQUssS0FBSyxDQUFDLEdBQUc7SUFFckIsSUFBSSxlQUFlO0lBRW5CLHVFQUF1RTtJQUN2RSxJQUFLLElBQUksSUFBSSxHQUFHLElBQUksS0FBSyxNQUFNLEVBQUc7UUFDaEMsSUFBSSxVQUFVO1FBQ2QsTUFBTSxhQUF1QixFQUFFO1FBQy9CLElBQUksVUFBVSxLQUFLO1FBQ25CLElBQUksV0FBVyxLQUFLO1FBQ3BCLElBQUksY0FBYyxLQUFLO1FBQ3ZCLElBQUksSUFBSTtRQUVSLHVFQUF1RTtRQUN2RSxNQUFPLElBQUksS0FBSyxNQUFNLElBQUksQ0FBQyxLQUFLLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUs7WUFDdEQsSUFBSSxVQUFVO2dCQUNaLFdBQVcsS0FBSztnQkFDaEIsTUFBTSxjQUFjLFVBQVUsbUJBQW1CLGlCQUFpQjtnQkFDbEUsV0FBVyxZQUFZLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFO2dCQUNuRSxRQUFTO1lBQ1gsQ0FBQztZQUVELElBQUksSUFBSSxDQUFDLEVBQUUsSUFBSSxjQUFjO2dCQUMzQixXQUFXLElBQUk7Z0JBQ2YsUUFBUztZQUNYLENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksS0FBSztnQkFDbEIsSUFBSSxDQUFDLFNBQVM7b0JBQ1osVUFBVSxJQUFJO29CQUNkLFdBQVc7b0JBQ1gsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksS0FBSzt3QkFDdEI7d0JBQ0EsV0FBVztvQkFDYixPQUFPLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLEtBQUs7d0JBQzdCO3dCQUNBLFdBQVc7b0JBQ2IsQ0FBQztvQkFDRCxRQUFTO2dCQUNYLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksS0FBSztvQkFDN0IsSUFBSSxJQUFJLElBQUk7b0JBQ1osSUFBSSxRQUFRO29CQUNaLE1BQU8sSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSzt3QkFDaEQsU0FBUyxJQUFJLENBQUMsSUFBSSxFQUFFO3dCQUNwQjtvQkFDRjtvQkFDQSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLO3dCQUM1QyxJQUFJLElBQUk7d0JBQ1IsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDNUIsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVMsV0FBVzs2QkFDakMsSUFBSSxTQUFTLFNBQVM7NEJBQ3pCLFdBQVc7d0JBQ2IsT0FBTyxJQUFJLFNBQVMsU0FBUyxXQUFXOzZCQUNuQyxJQUFJLFNBQVMsU0FBUyxXQUFXOzZCQUNqQyxJQUFJLFNBQVMsUUFBUSxXQUFXOzZCQUNoQyxJQUFJLFNBQVMsVUFBVSxXQUFXO3dCQUN2QyxRQUFTO29CQUNYLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksT0FBTyxTQUFTO2dCQUM3QixVQUFVLEtBQUs7Z0JBQ2YsV0FBVztnQkFDWCxRQUFTO1lBQ1gsQ0FBQztZQUVELElBQUksU0FBUztnQkFDWCxJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksTUFBTTtvQkFDbkIsV0FBVyxDQUFDLElBQUksQ0FBQztnQkFDbkIsT0FBTztvQkFDTCxXQUFXLElBQUksQ0FBQyxFQUFFO2dCQUNwQixDQUFDO2dCQUNELFFBQVM7WUFDWCxDQUFDO1lBRUQsSUFDRSxJQUFJLENBQUMsRUFBRSxJQUFJLE9BQU8sV0FBVyxNQUFNLEdBQUcsS0FDdEMsVUFBVSxDQUFDLFdBQVcsTUFBTSxHQUFHLEVBQUUsSUFBSSxTQUNyQztnQkFDQSxXQUFXO2dCQUNYLE1BQU0sT0FBTyxXQUFXLEdBQUc7Z0JBQzNCLElBQUksUUFBUSxLQUFLO29CQUNmLFdBQVc7Z0JBQ2IsT0FBTyxJQUFJLFFBQVEsS0FBSztvQkFDdEIsV0FBVztnQkFDYixDQUFDO2dCQUNELFFBQVM7WUFDWCxDQUFDO1lBRUQsSUFDRSxJQUFJLENBQUMsRUFBRSxJQUFJLE9BQU8sV0FBVyxNQUFNLEdBQUcsS0FDdEMsVUFBVSxDQUFDLFdBQVcsTUFBTSxHQUFHLEVBQUUsSUFBSSxTQUNyQztnQkFDQSxXQUFXO2dCQUNYLFFBQVM7WUFDWCxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLE9BQU8sWUFBWSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksS0FBSztnQkFDcEQ7Z0JBQ0EsV0FBVyxJQUFJLENBQUM7Z0JBQ2hCLFdBQVc7Z0JBQ1gsUUFBUztZQUNYLENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksT0FBTyxZQUFZLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLO2dCQUNwRDtnQkFDQSxXQUFXLElBQUksQ0FBQztnQkFDaEIsV0FBVztnQkFDWCxRQUFTO1lBQ1gsQ0FBQztZQUVELElBQUksSUFBSSxDQUFDLEVBQUUsSUFBSSxLQUFLO2dCQUNsQixJQUFJLFlBQVksSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLEtBQUs7b0JBQ2xDO29CQUNBLFdBQVcsSUFBSSxDQUFDO29CQUNoQixXQUFXO2dCQUNiLE9BQU87b0JBQ0wsV0FBVztnQkFDYixDQUFDO2dCQUNELFFBQVM7WUFDWCxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLE9BQU8sWUFBWSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksS0FBSztnQkFDcEQ7Z0JBQ0EsV0FBVyxJQUFJLENBQUM7Z0JBQ2hCLFdBQVc7Z0JBQ1gsUUFBUztZQUNYLENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksS0FBSztnQkFDbEIsV0FBVyxJQUFJLENBQUM7Z0JBQ2hCLFdBQVc7Z0JBQ1gsUUFBUztZQUNYLENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksT0FBTyxVQUFVLENBQUMsV0FBVyxNQUFNLEdBQUcsRUFBRSxJQUFJLFNBQVM7Z0JBQ2xFLFdBQVcsR0FBRztnQkFDZCxXQUFXO2dCQUNYLFFBQVM7WUFDWCxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLE9BQU8sVUFBVSxDQUFDLFdBQVcsTUFBTSxHQUFHLEVBQUUsSUFBSSxTQUFTO2dCQUNsRSxXQUFXO2dCQUNYLFFBQVM7WUFDWCxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLEtBQUs7Z0JBQ2xCLElBQUksWUFBWSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksS0FBSztvQkFDbEM7b0JBQ0EsV0FBVyxJQUFJLENBQUM7b0JBQ2hCLFdBQVc7Z0JBQ2IsT0FBTztvQkFDTCxNQUFNLFdBQVcsSUFBSSxDQUFDLElBQUksRUFBRTtvQkFDNUIsSUFBSSxXQUFXO29CQUNmLE1BQU8sSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLElBQUs7d0JBQ3pCO3dCQUNBO29CQUNGO29CQUNBLE1BQU0sV0FBVyxJQUFJLENBQUMsSUFBSSxFQUFFO29CQUM1QixJQUNFLGtCQUFrQixZQUFZLEtBQzlCOzJCQUFJO3dCQUFNO3FCQUFVLENBQUMsUUFBUSxDQUFDLGFBQzlCOzJCQUFJO3dCQUFNO3FCQUFVLENBQUMsUUFBUSxDQUFDLFdBQzlCO3dCQUNBLFdBQVc7d0JBQ1gsY0FBYyxJQUFJO29CQUNwQixPQUFPO3dCQUNMLFdBQVc7b0JBQ2IsQ0FBQztnQkFDSCxDQUFDO2dCQUNELFFBQVM7WUFDWCxDQUFDO1lBRUQsV0FBVyxrQkFBa0IsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUU7UUFDM0U7UUFFQSxxREFBcUQ7UUFDckQsSUFBSSxXQUFXLE1BQU0sR0FBRyxLQUFLLFdBQVcsVUFBVTtZQUNoRCxrRUFBa0U7WUFDbEUsVUFBVTtZQUNWLEtBQUssTUFBTSxLQUFLLEtBQUssS0FBSyxDQUFDLEdBQUcsR0FBSTtnQkFDaEMsV0FBVyxrQkFBa0IsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQztnQkFDdkQsY0FBYyxLQUFLO1lBQ3JCO1FBQ0YsQ0FBQztRQUVELGdCQUFnQjtRQUNoQixJQUFJLENBQUMsYUFBYTtZQUNoQixnQkFBZ0IsSUFBSSxLQUFLLE1BQU0sR0FBRyxNQUFNLFFBQVE7WUFDaEQsY0FBYyxJQUFJO1FBQ3BCLENBQUM7UUFFRCx3REFBd0Q7UUFDeEQsTUFBTyxLQUFLLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFHO1FBRS9CLDRFQUE0RTtRQUM1RSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRztZQUNaLE1BQU0sSUFBSSxNQUFNLHNEQUFzRDtRQUN4RSxDQUFDO1FBQ0QsSUFBSTtJQUNOO0lBRUEsZUFBZSxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUNsQyxPQUFPLElBQUksT0FBTyxjQUFjLGtCQUFrQixNQUFNLEVBQUU7QUFDNUQsQ0FBQztBQUVELDRDQUE0QyxHQUM1QyxPQUFPLFNBQVMsT0FBTyxHQUFXLEVBQVc7SUFDM0MsTUFBTSxRQUFnQztRQUFFLEtBQUs7UUFBSyxLQUFLO1FBQUssS0FBSztJQUFJO0lBQ3JFLE1BQU0sUUFDSjtJQUVGLElBQUksUUFBUSxJQUFJO1FBQ2QsT0FBTyxLQUFLO0lBQ2QsQ0FBQztJQUVELElBQUk7SUFFSixNQUFRLFFBQVEsTUFBTSxJQUFJLENBQUMsS0FBTztRQUNoQyxJQUFJLEtBQUssQ0FBQyxFQUFFLEVBQUUsT0FBTyxJQUFJO1FBQ3pCLElBQUksTUFBTSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU07UUFFdkMsNkNBQTZDO1FBQzdDLDhDQUE4QztRQUM5QyxNQUFNLE9BQU8sS0FBSyxDQUFDLEVBQUU7UUFDckIsTUFBTSxRQUFRLE9BQU8sS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJO1FBQ3ZDLElBQUksUUFBUSxPQUFPO1lBQ2pCLE1BQU0sSUFBSSxJQUFJLE9BQU8sQ0FBQyxPQUFPO1lBQzdCLElBQUksTUFBTSxDQUFDLEdBQUc7Z0JBQ1osTUFBTSxJQUFJO1lBQ1osQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLElBQUksS0FBSyxDQUFDO0lBQ2xCO0lBRUEsT0FBTyxLQUFLO0FBQ2QsQ0FBQztBQUVELDZFQUE2RSxHQUM3RSxPQUFPLFNBQVMsY0FDZCxJQUFZLEVBQ1osRUFBRSxVQUFXLEtBQUssQ0FBQSxFQUFlLEdBQUcsQ0FBQyxDQUFDLEVBQzlCO0lBQ1IsSUFBSSxLQUFLLEtBQUssQ0FBQyxRQUFRO1FBQ3JCLE1BQU0sSUFBSSxNQUFNLENBQUMsbUNBQW1DLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRTtJQUNqRSxDQUFDO0lBQ0QsSUFBSSxDQUFDLFVBQVU7UUFDYixPQUFPLFVBQVU7SUFDbkIsQ0FBQztJQUNELE1BQU0sSUFBSSxZQUFZLE1BQU07SUFDNUIsTUFBTSxtQkFBbUIsSUFBSSxPQUMzQixDQUFDLEtBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLFVBQVUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUN6QztJQUVGLE9BQU8sVUFBVSxLQUFLLE9BQU8sQ0FBQyxrQkFBa0IsT0FBTyxPQUFPLENBQUMsT0FBTztBQUN4RSxDQUFDO0FBRUQsd0VBQXdFLEdBQ3hFLE9BQU8sU0FBUyxVQUNkLEtBQWUsRUFDZixFQUFFLFVBQVcsSUFBSSxDQUFBLEVBQUUsVUFBVyxLQUFLLENBQUEsRUFBZSxHQUFHLENBQUMsQ0FBQyxFQUMvQztJQUNSLElBQUksQ0FBQyxZQUFZLE1BQU0sTUFBTSxJQUFJLEdBQUc7UUFDbEMsT0FBTyxRQUFRO0lBQ2pCLENBQUM7SUFDRCxJQUFJLE1BQU0sTUFBTSxLQUFLLEdBQUcsT0FBTztJQUMvQixJQUFJO0lBQ0osS0FBSyxNQUFNLFFBQVEsTUFBTztRQUN4QixNQUFNLE9BQU87UUFDYixJQUFJLEtBQUssTUFBTSxHQUFHLEdBQUc7WUFDbkIsSUFBSSxDQUFDLFFBQVEsU0FBUztpQkFDakIsVUFBVSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQztRQUNoQyxDQUFDO0lBQ0g7SUFDQSxJQUFJLENBQUMsUUFBUSxPQUFPO0lBQ3BCLE9BQU8sY0FBYyxRQUFRO1FBQUU7UUFBVTtJQUFTO0FBQ3BELENBQUMifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/7HctcYJMo9RPESb8_8SnGpYMx1U.js b/tests/__snapshots__/transpile/remote/modules/7HctcYJMo9RPESb8_8SnGpYMx1U.js new file mode 100644 index 0000000..b7663e5 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/7HctcYJMo9RPESb8_8SnGpYMx1U.js @@ -0,0 +1,2 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2lvL3R5cGVzLmQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cblxuZXhwb3J0IGludGVyZmFjZSBSZWFkZXIge1xuICAvKiogUmVhZHMgdXAgdG8gYHAuYnl0ZUxlbmd0aGAgYnl0ZXMgaW50byBgcGAuIEl0IHJlc29sdmVzIHRvIHRoZSBudW1iZXIgb2ZcbiAgICogYnl0ZXMgcmVhZCAoYDBgIDwgYG5gIDw9IGBwLmJ5dGVMZW5ndGhgKSBhbmQgcmVqZWN0cyBpZiBhbnkgZXJyb3JcbiAgICogZW5jb3VudGVyZWQuIEV2ZW4gaWYgYHJlYWQoKWAgcmVzb2x2ZXMgdG8gYG5gIDwgYHAuYnl0ZUxlbmd0aGAsIGl0IG1heVxuICAgKiB1c2UgYWxsIG9mIGBwYCBhcyBzY3JhdGNoIHNwYWNlIGR1cmluZyB0aGUgY2FsbC4gSWYgc29tZSBkYXRhIGlzXG4gICAqIGF2YWlsYWJsZSBidXQgbm90IGBwLmJ5dGVMZW5ndGhgIGJ5dGVzLCBgcmVhZCgpYCBjb252ZW50aW9uYWxseSByZXNvbHZlc1xuICAgKiB0byB3aGF0IGlzIGF2YWlsYWJsZSBpbnN0ZWFkIG9mIHdhaXRpbmcgZm9yIG1vcmUuXG4gICAqXG4gICAqIFdoZW4gYHJlYWQoKWAgZW5jb3VudGVycyBlbmQtb2YtZmlsZSBjb25kaXRpb24sIGl0IHJlc29sdmVzIHRvIEVPRlxuICAgKiAoYG51bGxgKS5cbiAgICpcbiAgICogV2hlbiBgcmVhZCgpYCBlbmNvdW50ZXJzIGFuIGVycm9yLCBpdCByZWplY3RzIHdpdGggYW4gZXJyb3IuXG4gICAqXG4gICAqIENhbGxlcnMgc2hvdWxkIGFsd2F5cyBwcm9jZXNzIHRoZSBgbmAgPiBgMGAgYnl0ZXMgcmV0dXJuZWQgYmVmb3JlXG4gICAqIGNvbnNpZGVyaW5nIHRoZSBFT0YgKGBudWxsYCkuIERvaW5nIHNvIGNvcnJlY3RseSBoYW5kbGVzIEkvTyBlcnJvcnMgdGhhdFxuICAgKiBoYXBwZW4gYWZ0ZXIgcmVhZGluZyBzb21lIGJ5dGVzIGFuZCBhbHNvIGJvdGggb2YgdGhlIGFsbG93ZWQgRU9GXG4gICAqIGJlaGF2aW9ycy5cbiAgICpcbiAgICogSW1wbGVtZW50YXRpb25zIHNob3VsZCBub3QgcmV0YWluIGEgcmVmZXJlbmNlIHRvIGBwYC5cbiAgICpcbiAgICogVXNlIGl0ZXIoKSBmcm9tIGh0dHBzOi8vZGVuby5sYW5kL3N0ZC9pby91dGlsLnRzIHRvIHR1cm4gYSBSZWFkZXIgaW50byBhblxuICAgKiBBc3luY0l0ZXJhdG9yLlxuICAgKi9cbiAgcmVhZChwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXIgfCBudWxsPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWFkZXJTeW5jIHtcbiAgLyoqIFJlYWRzIHVwIHRvIGBwLmJ5dGVMZW5ndGhgIGJ5dGVzIGludG8gYHBgLiBJdCByZXNvbHZlcyB0byB0aGUgbnVtYmVyXG4gICAqIG9mIGJ5dGVzIHJlYWQgKGAwYCA8IGBuYCA8PSBgcC5ieXRlTGVuZ3RoYCkgYW5kIHJlamVjdHMgaWYgYW55IGVycm9yXG4gICAqIGVuY291bnRlcmVkLiBFdmVuIGlmIGByZWFkKClgIHJldHVybnMgYG5gIDwgYHAuYnl0ZUxlbmd0aGAsIGl0IG1heSB1c2VcbiAgICogYWxsIG9mIGBwYCBhcyBzY3JhdGNoIHNwYWNlIGR1cmluZyB0aGUgY2FsbC4gSWYgc29tZSBkYXRhIGlzIGF2YWlsYWJsZVxuICAgKiBidXQgbm90IGBwLmJ5dGVMZW5ndGhgIGJ5dGVzLCBgcmVhZCgpYCBjb252ZW50aW9uYWxseSByZXR1cm5zIHdoYXQgaXNcbiAgICogYXZhaWxhYmxlIGluc3RlYWQgb2Ygd2FpdGluZyBmb3IgbW9yZS5cbiAgICpcbiAgICogV2hlbiBgcmVhZFN5bmMoKWAgZW5jb3VudGVycyBlbmQtb2YtZmlsZSBjb25kaXRpb24sIGl0IHJldHVybnMgRU9GXG4gICAqIChgbnVsbGApLlxuICAgKlxuICAgKiBXaGVuIGByZWFkU3luYygpYCBlbmNvdW50ZXJzIGFuIGVycm9yLCBpdCB0aHJvd3Mgd2l0aCBhbiBlcnJvci5cbiAgICpcbiAgICogQ2FsbGVycyBzaG91bGQgYWx3YXlzIHByb2Nlc3MgdGhlIGBuYCA+IGAwYCBieXRlcyByZXR1cm5lZCBiZWZvcmVcbiAgICogY29uc2lkZXJpbmcgdGhlIEVPRiAoYG51bGxgKS4gRG9pbmcgc28gY29ycmVjdGx5IGhhbmRsZXMgSS9PIGVycm9ycyB0aGF0IGhhcHBlblxuICAgKiBhZnRlciByZWFkaW5nIHNvbWUgYnl0ZXMgYW5kIGFsc28gYm90aCBvZiB0aGUgYWxsb3dlZCBFT0YgYmVoYXZpb3JzLlxuICAgKlxuICAgKiBJbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCByZXRhaW4gYSByZWZlcmVuY2UgdG8gYHBgLlxuICAgKlxuICAgKiBVc2UgaXRlclN5bmMoKSBmcm9tIGh0dHBzOi8vZGVuby5sYW5kL3N0ZC9pby91dGlsLnRzIHRvIHR1cm4gYSBSZWFkZXJTeW5jXG4gICAqIGludG8gYW4gSXRlcmF0b3IuXG4gICAqL1xuICByZWFkU3luYyhwOiBVaW50OEFycmF5KTogbnVtYmVyIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICAvKiogV3JpdGVzIGBwLmJ5dGVMZW5ndGhgIGJ5dGVzIGZyb20gYHBgIHRvIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RyZWFtLiBJdFxuICAgKiByZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gZnJvbSBgcGAgKGAwYCA8PSBgbmAgPD1cbiAgICogYHAuYnl0ZUxlbmd0aGApIG9yIHJlamVjdCB3aXRoIHRoZSBlcnJvciBlbmNvdW50ZXJlZCB0aGF0IGNhdXNlZCB0aGVcbiAgICogd3JpdGUgdG8gc3RvcCBlYXJseS4gYHdyaXRlKClgIG11c3QgcmVqZWN0IHdpdGggYSBub24tbnVsbCBlcnJvciBpZlxuICAgKiB3b3VsZCByZXNvbHZlIHRvIGBuYCA8IGBwLmJ5dGVMZW5ndGhgLiBgd3JpdGUoKWAgbXVzdCBub3QgbW9kaWZ5IHRoZVxuICAgKiBzbGljZSBkYXRhLCBldmVuIHRlbXBvcmFyaWx5LlxuICAgKlxuICAgKiBJbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCByZXRhaW4gYSByZWZlcmVuY2UgdG8gYHBgLlxuICAgKi9cbiAgd3JpdGUocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXJTeW5jIHtcbiAgLyoqIFdyaXRlcyBgcC5ieXRlTGVuZ3RoYCBieXRlcyBmcm9tIGBwYCB0byB0aGUgdW5kZXJseWluZyBkYXRhXG4gICAqIHN0cmVhbS4gSXQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gZnJvbSBgcGAgKGAwYCA8PSBgbmBcbiAgICogPD0gYHAuYnl0ZUxlbmd0aGApIGFuZCBhbnkgZXJyb3IgZW5jb3VudGVyZWQgdGhhdCBjYXVzZWQgdGhlIHdyaXRlIHRvXG4gICAqIHN0b3AgZWFybHkuIGB3cml0ZVN5bmMoKWAgbXVzdCB0aHJvdyBhIG5vbi1udWxsIGVycm9yIGlmIGl0IHJldHVybnMgYG5gIDxcbiAgICogYHAuYnl0ZUxlbmd0aGAuIGB3cml0ZVN5bmMoKWAgbXVzdCBub3QgbW9kaWZ5IHRoZSBzbGljZSBkYXRhLCBldmVuXG4gICAqIHRlbXBvcmFyaWx5LlxuICAgKlxuICAgKiBJbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCByZXRhaW4gYSByZWZlcmVuY2UgdG8gYHBgLlxuICAgKi9cbiAgd3JpdGVTeW5jKHA6IFVpbnQ4QXJyYXkpOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xvc2VyIHtcbiAgY2xvc2UoKTogdm9pZDtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEUifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/7VWYTDioIHKQJaGRjtUtSbiHVG8.js b/tests/__snapshots__/transpile/remote/modules/7VWYTDioIHKQJaGRjtUtSbiHVG8.js new file mode 100644 index 0000000..18b20d4 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/7VWYTDioIHKQJaGRjtUtSbiHVG8.js @@ -0,0 +1,96 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +import { CHAR_BACKWARD_SLASH, CHAR_DOT, CHAR_FORWARD_SLASH, CHAR_LOWERCASE_A, CHAR_LOWERCASE_Z, CHAR_UPPERCASE_A, CHAR_UPPERCASE_Z } from "./_constants.ts"; +export function assertPath(path) { + if (typeof path !== "string") { + throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`); + } +} +export function isPosixPathSeparator(code) { + return code === CHAR_FORWARD_SLASH; +} +export function isPathSeparator(code) { + return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH; +} +export function isWindowsDeviceRoot(code) { + return code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z || code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z; +} +// Resolves . and .. elements in a path with directory names +export function normalizeString(path, allowAboveRoot, separator, isPathSeparator) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let code; + for(let i = 0, len = path.length; i <= len; ++i){ + if (i < len) code = path.charCodeAt(i); + else if (isPathSeparator(code)) break; + else code = CHAR_FORWARD_SLASH; + if (isPathSeparator(code)) { + if (lastSlash === i - 1 || dots === 1) { + // NOOP + } else if (lastSlash !== i - 1 && dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== CHAR_DOT || res.charCodeAt(res.length - 2) !== CHAR_DOT) { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf(separator); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); + } + lastSlash = i; + dots = 0; + continue; + } else if (res.length === 2 || res.length === 1) { + res = ""; + lastSegmentLength = 0; + lastSlash = i; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + if (res.length > 0) res += `${separator}..`; + else res = ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) res += separator + path.slice(lastSlash + 1, i); + else res = path.slice(lastSlash + 1, i); + lastSegmentLength = i - lastSlash - 1; + } + lastSlash = i; + dots = 0; + } else if (code === CHAR_DOT && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +export function _format(sep, pathObject) { + const dir = pathObject.dir || pathObject.root; + const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); + if (!dir) return base; + if (dir === pathObject.root) return dir + base; + return dir + sep + base; +} +const WHITESPACE_ENCODINGS = { + "\u0009": "%09", + "\u000A": "%0A", + "\u000B": "%0B", + "\u000C": "%0C", + "\u000D": "%0D", + "\u0020": "%20" +}; +export function encodeWhitespace(string) { + return string.replaceAll(/[\s]/g, (c)=>{ + return WHITESPACE_ENCODINGS[c] ?? c; + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvX3V0aWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QgfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQge1xuICBDSEFSX0JBQ0tXQVJEX1NMQVNILFxuICBDSEFSX0RPVCxcbiAgQ0hBUl9GT1JXQVJEX1NMQVNILFxuICBDSEFSX0xPV0VSQ0FTRV9BLFxuICBDSEFSX0xPV0VSQ0FTRV9aLFxuICBDSEFSX1VQUEVSQ0FTRV9BLFxuICBDSEFSX1VQUEVSQ0FTRV9aLFxufSBmcm9tIFwiLi9fY29uc3RhbnRzLnRzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRQYXRoKHBhdGg6IHN0cmluZyk6IHZvaWQge1xuICBpZiAodHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYFBhdGggbXVzdCBiZSBhIHN0cmluZy4gUmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeShwYXRoKX1gLFxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUG9zaXhQYXRoU2VwYXJhdG9yKGNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYXRoU2VwYXJhdG9yKGNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNQb3NpeFBhdGhTZXBhcmF0b3IoY29kZSkgfHwgY29kZSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzV2luZG93c0RldmljZVJvb3QoY29kZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgKGNvZGUgPj0gQ0hBUl9MT1dFUkNBU0VfQSAmJiBjb2RlIDw9IENIQVJfTE9XRVJDQVNFX1opIHx8XG4gICAgKGNvZGUgPj0gQ0hBUl9VUFBFUkNBU0VfQSAmJiBjb2RlIDw9IENIQVJfVVBQRVJDQVNFX1opXG4gICk7XG59XG5cbi8vIFJlc29sdmVzIC4gYW5kIC4uIGVsZW1lbnRzIGluIGEgcGF0aCB3aXRoIGRpcmVjdG9yeSBuYW1lc1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZyhcbiAgcGF0aDogc3RyaW5nLFxuICBhbGxvd0Fib3ZlUm9vdDogYm9vbGVhbixcbiAgc2VwYXJhdG9yOiBzdHJpbmcsXG4gIGlzUGF0aFNlcGFyYXRvcjogKGNvZGU6IG51bWJlcikgPT4gYm9vbGVhbixcbik6IHN0cmluZyB7XG4gIGxldCByZXMgPSBcIlwiO1xuICBsZXQgbGFzdFNlZ21lbnRMZW5ndGggPSAwO1xuICBsZXQgbGFzdFNsYXNoID0gLTE7XG4gIGxldCBkb3RzID0gMDtcbiAgbGV0IGNvZGU6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBhdGgubGVuZ3RoOyBpIDw9IGxlbjsgKytpKSB7XG4gICAgaWYgKGkgPCBsZW4pIGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUhKSkgYnJlYWs7XG4gICAgZWxzZSBjb2RlID0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xuXG4gICAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlISkpIHtcbiAgICAgIGlmIChsYXN0U2xhc2ggPT09IGkgLSAxIHx8IGRvdHMgPT09IDEpIHtcbiAgICAgICAgLy8gTk9PUFxuICAgICAgfSBlbHNlIGlmIChsYXN0U2xhc2ggIT09IGkgLSAxICYmIGRvdHMgPT09IDIpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlcy5sZW5ndGggPCAyIHx8XG4gICAgICAgICAgbGFzdFNlZ21lbnRMZW5ndGggIT09IDIgfHxcbiAgICAgICAgICByZXMuY2hhckNvZGVBdChyZXMubGVuZ3RoIC0gMSkgIT09IENIQVJfRE9UIHx8XG4gICAgICAgICAgcmVzLmNoYXJDb2RlQXQocmVzLmxlbmd0aCAtIDIpICE9PSBDSEFSX0RPVFxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAocmVzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RTbGFzaEluZGV4ID0gcmVzLmxhc3RJbmRleE9mKHNlcGFyYXRvcik7XG4gICAgICAgICAgICBpZiAobGFzdFNsYXNoSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgIHJlcyA9IFwiXCI7XG4gICAgICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlcyA9IHJlcy5zbGljZSgwLCBsYXN0U2xhc2hJbmRleCk7XG4gICAgICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gcmVzLmxlbmd0aCAtIDEgLSByZXMubGFzdEluZGV4T2Yoc2VwYXJhdG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RTbGFzaCA9IGk7XG4gICAgICAgICAgICBkb3RzID0gMDtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzLmxlbmd0aCA9PT0gMiB8fCByZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICByZXMgPSBcIlwiO1xuICAgICAgICAgICAgbGFzdFNlZ21lbnRMZW5ndGggPSAwO1xuICAgICAgICAgICAgbGFzdFNsYXNoID0gaTtcbiAgICAgICAgICAgIGRvdHMgPSAwO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChhbGxvd0Fib3ZlUm9vdCkge1xuICAgICAgICAgIGlmIChyZXMubGVuZ3RoID4gMCkgcmVzICs9IGAke3NlcGFyYXRvcn0uLmA7XG4gICAgICAgICAgZWxzZSByZXMgPSBcIi4uXCI7XG4gICAgICAgICAgbGFzdFNlZ21lbnRMZW5ndGggPSAyO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocmVzLmxlbmd0aCA+IDApIHJlcyArPSBzZXBhcmF0b3IgKyBwYXRoLnNsaWNlKGxhc3RTbGFzaCArIDEsIGkpO1xuICAgICAgICBlbHNlIHJlcyA9IHBhdGguc2xpY2UobGFzdFNsYXNoICsgMSwgaSk7XG4gICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gaSAtIGxhc3RTbGFzaCAtIDE7XG4gICAgICB9XG4gICAgICBsYXN0U2xhc2ggPSBpO1xuICAgICAgZG90cyA9IDA7XG4gICAgfSBlbHNlIGlmIChjb2RlID09PSBDSEFSX0RPVCAmJiBkb3RzICE9PSAtMSkge1xuICAgICAgKytkb3RzO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb3RzID0gLTE7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfZm9ybWF0KFxuICBzZXA6IHN0cmluZyxcbiAgcGF0aE9iamVjdDogRm9ybWF0SW5wdXRQYXRoT2JqZWN0LFxuKTogc3RyaW5nIHtcbiAgY29uc3QgZGlyOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBwYXRoT2JqZWN0LmRpciB8fCBwYXRoT2JqZWN0LnJvb3Q7XG4gIGNvbnN0IGJhc2U6IHN0cmluZyA9IHBhdGhPYmplY3QuYmFzZSB8fFxuICAgIChwYXRoT2JqZWN0Lm5hbWUgfHwgXCJcIikgKyAocGF0aE9iamVjdC5leHQgfHwgXCJcIik7XG4gIGlmICghZGlyKSByZXR1cm4gYmFzZTtcbiAgaWYgKGRpciA9PT0gcGF0aE9iamVjdC5yb290KSByZXR1cm4gZGlyICsgYmFzZTtcbiAgcmV0dXJuIGRpciArIHNlcCArIGJhc2U7XG59XG5cbmNvbnN0IFdISVRFU1BBQ0VfRU5DT0RJTkdTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBcIlxcdTAwMDlcIjogXCIlMDlcIixcbiAgXCJcXHUwMDBBXCI6IFwiJTBBXCIsXG4gIFwiXFx1MDAwQlwiOiBcIiUwQlwiLFxuICBcIlxcdTAwMENcIjogXCIlMENcIixcbiAgXCJcXHUwMDBEXCI6IFwiJTBEXCIsXG4gIFwiXFx1MDAyMFwiOiBcIiUyMFwiLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZVdoaXRlc3BhY2Uoc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyaW5nLnJlcGxhY2VBbGwoL1tcXHNdL2csIChjKSA9PiB7XG4gICAgcmV0dXJuIFdISVRFU1BBQ0VfRU5DT0RJTkdTW2NdID8/IGM7XG4gIH0pO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxpREFBaUQ7QUFDakQsNkRBQTZEO0FBQzdELHFDQUFxQztBQUdyQyxTQUNFLG1CQUFtQixFQUNuQixRQUFRLEVBQ1Isa0JBQWtCLEVBQ2xCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixRQUNYLGtCQUFrQjtBQUV6QixPQUFPLFNBQVMsV0FBVyxJQUFZLEVBQVE7SUFDN0MsSUFBSSxPQUFPLFNBQVMsVUFBVTtRQUM1QixNQUFNLElBQUksVUFDUixDQUFDLGdDQUFnQyxFQUFFLEtBQUssU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUN6RDtJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsT0FBTyxTQUFTLHFCQUFxQixJQUFZLEVBQVc7SUFDMUQsT0FBTyxTQUFTO0FBQ2xCLENBQUM7QUFFRCxPQUFPLFNBQVMsZ0JBQWdCLElBQVksRUFBVztJQUNyRCxPQUFPLHFCQUFxQixTQUFTLFNBQVM7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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/TPW77jtLW1NbcwGdiav4OHTJd6g.js b/tests/__snapshots__/transpile/remote/modules/TPW77jtLW1NbcwGdiav4OHTJd6g.js new file mode 100644 index 0000000..f7ecf64 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/TPW77jtLW1NbcwGdiav4OHTJd6g.js @@ -0,0 +1,6 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +import { isWindows } from "../_util/os.ts"; +export const SEP = isWindows ? "\\" : "/"; +export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvc2VwYXJhdG9yLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmltcG9ydCB7IGlzV2luZG93cyB9IGZyb20gXCIuLi9fdXRpbC9vcy50c1wiO1xuXG5leHBvcnQgY29uc3QgU0VQID0gaXNXaW5kb3dzID8gXCJcXFxcXCIgOiBcIi9cIjtcbmV4cG9ydCBjb25zdCBTRVBfUEFUVEVSTiA9IGlzV2luZG93cyA/IC9bXFxcXC9dKy8gOiAvXFwvKy87XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEVBQTBFO0FBQzFFLHFDQUFxQztBQUVyQyxTQUFTLFNBQVMsUUFBUSxpQkFBaUI7QUFFM0MsT0FBTyxNQUFNLE1BQU0sWUFBWSxPQUFPLEdBQUcsQ0FBQztBQUMxQyxPQUFPLE1BQU0sY0FBYyxZQUFZLFdBQVcsS0FBSyxDQUFDIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/VR9N5EtRGYTL6BL2wtaFnqW-AuA.js b/tests/__snapshots__/transpile/remote/modules/VR9N5EtRGYTL6BL2wtaFnqW-AuA.js new file mode 100644 index 0000000..ef1880e --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/VR9N5EtRGYTL6BL2wtaFnqW-AuA.js @@ -0,0 +1,72 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { fromFileUrl } from "../../path/mod.ts"; +import { readableStreamFromReader } from "../../streams/conversion.ts"; +const clients = new Map(); +let clientId = 0; +function dispatch(msg) { + for (const client of clients.values()){ + client.send(msg); + } +} +function wsHandler(ws) { + const id = ++clientId; + clients.set(id, ws); + ws.onopen = ()=>{ + dispatch(`Connected: [${id}]`); + }; + ws.onmessage = (e)=>{ + console.log(`msg:${id}`, e.data); + dispatch(`[${id}]: ${e.data}`); + }; + ws.onclose = ()=>{ + clients.delete(id); + dispatch(`Closed: [${id}]`); + }; +} +async function requestHandler(req) { + const pathname = new URL(req.request.url).pathname; + if (req.request.method === "GET" && pathname === "/") { + //Serve with hack + const u = new URL("./index.html", import.meta.url); + if (u.protocol.startsWith("http")) { + // server launched by deno run http(s)://.../server.ts, + fetch(u.href).then(async (resp)=>{ + const body = new Uint8Array(await resp.arrayBuffer()); + req.respondWith(new Response(body, { + status: resp.status, + headers: { + "content-type": "text/html" + } + })); + }); + } else { + // server launched by deno run ./server.ts + const file = await Deno.open(fromFileUrl(u)); + req.respondWith(new Response(readableStreamFromReader(file), { + status: 200, + headers: { + "content-type": "text/html" + } + })); + } + } else if (req.request.method === "GET" && pathname === "/favicon.ico") { + req.respondWith(Response.redirect("https://deno.land/favicon.ico", 302)); + } else if (req.request.method === "GET" && pathname === "/ws") { + const { socket , response } = Deno.upgradeWebSocket(req.request); + wsHandler(socket); + req.respondWith(response); + } +} +const server = Deno.listen({ + port: 8080 +}); +console.log("chat server starting on :8080...."); +for await (const conn of server){ + (async ()=>{ + const httpConn = Deno.serveHttp(conn); + for await (const requestEvent of httpConn){ + requestHandler(requestEvent); + } + })(); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2V4YW1wbGVzL2NoYXQvc2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG5pbXBvcnQgeyBmcm9tRmlsZVVybCB9IGZyb20gXCIuLi8uLi9wYXRoL21vZC50c1wiO1xuaW1wb3J0IHsgcmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyIH0gZnJvbSBcIi4uLy4uL3N0cmVhbXMvY29udmVyc2lvbi50c1wiO1xuXG5jb25zdCBjbGllbnRzID0gbmV3IE1hcDxudW1iZXIsIFdlYlNvY2tldD4oKTtcbmxldCBjbGllbnRJZCA9IDA7XG5mdW5jdGlvbiBkaXNwYXRjaChtc2c6IHN0cmluZyk6IHZvaWQge1xuICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzLnZhbHVlcygpKSB7XG4gICAgY2xpZW50LnNlbmQobXNnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB3c0hhbmRsZXIod3M6IFdlYlNvY2tldCkge1xuICBjb25zdCBpZCA9ICsrY2xpZW50SWQ7XG4gIGNsaWVudHMuc2V0KGlkLCB3cyk7XG4gIHdzLm9ub3BlbiA9ICgpID0+IHtcbiAgICBkaXNwYXRjaChgQ29ubmVjdGVkOiBbJHtpZH1dYCk7XG4gIH07XG4gIHdzLm9ubWVzc2FnZSA9IChlKSA9PiB7XG4gICAgY29uc29sZS5sb2coYG1zZzoke2lkfWAsIGUuZGF0YSk7XG4gICAgZGlzcGF0Y2goYFske2lkfV06ICR7ZS5kYXRhfWApO1xuICB9O1xuICB3cy5vbmNsb3NlID0gKCkgPT4ge1xuICAgIGNsaWVudHMuZGVsZXRlKGlkKTtcbiAgICBkaXNwYXRjaChgQ2xvc2VkOiBbJHtpZH1dYCk7XG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlcXVlc3RIYW5kbGVyKHJlcTogRGVuby5SZXF1ZXN0RXZlbnQpIHtcbiAgY29uc3QgcGF0aG5hbWUgPSBuZXcgVVJMKHJlcS5yZXF1ZXN0LnVybCkucGF0aG5hbWU7XG4gIGlmIChyZXEucmVxdWVzdC5tZXRob2QgPT09IFwiR0VUXCIgJiYgcGF0aG5hbWUgPT09IFwiL1wiKSB7XG4gICAgLy9TZXJ2ZSB3aXRoIGhhY2tcbiAgICBjb25zdCB1ID0gbmV3IFVSTChcIi4vaW5kZXguaHRtbFwiLCBpbXBvcnQubWV0YS51cmwpO1xuICAgIGlmICh1LnByb3RvY29sLnN0YXJ0c1dpdGgoXCJodHRwXCIpKSB7XG4gICAgICAvLyBzZXJ2ZXIgbGF1bmNoZWQgYnkgZGVubyBydW4gaHR0cChzKTovLy4uLi9zZXJ2ZXIudHMsXG4gICAgICBmZXRjaCh1LmhyZWYpLnRoZW4oYXN5bmMgKHJlc3ApID0+IHtcbiAgICAgICAgY29uc3QgYm9keSA9IG5ldyBVaW50OEFycmF5KGF3YWl0IHJlc3AuYXJyYXlCdWZmZXIoKSk7XG4gICAgICAgIHJlcS5yZXNwb25kV2l0aChcbiAgICAgICAgICBuZXcgUmVzcG9uc2UoYm9keSwge1xuICAgICAgICAgICAgc3RhdHVzOiByZXNwLnN0YXR1cyxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgXCJjb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWxcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gc2VydmVyIGxhdW5jaGVkIGJ5IGRlbm8gcnVuIC4vc2VydmVyLnRzXG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKGZyb21GaWxlVXJsKHUpKTtcbiAgICAgIHJlcS5yZXNwb25kV2l0aChcbiAgICAgICAgbmV3IFJlc3BvbnNlKHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlcihmaWxlKSwge1xuICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIFwiY29udGVudC10eXBlXCI6IFwidGV4dC9odG1sXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIGlmIChcbiAgICByZXEucmVxdWVzdC5tZXRob2QgPT09IFwiR0VUXCIgJiYgcGF0aG5hbWUgPT09IFwiL2Zhdmljb24uaWNvXCJcbiAgKSB7XG4gICAgcmVxLnJlc3BvbmRXaXRoKFJlc3BvbnNlLnJlZGlyZWN0KFwiaHR0cHM6Ly9kZW5vLmxhbmQvZmF2aWNvbi5pY29cIiwgMzAyKSk7XG4gIH0gZWxzZSBpZiAocmVxLnJlcXVlc3QubWV0aG9kID09PSBcIkdFVFwiICYmIHBhdGhuYW1lID09PSBcIi93c1wiKSB7XG4gICAgY29uc3QgeyBzb2NrZXQsIHJlc3BvbnNlIH0gPSBEZW5vLnVwZ3JhZGVXZWJTb2NrZXQocmVxLnJlcXVlc3QpO1xuICAgIHdzSGFuZGxlcihzb2NrZXQpO1xuICAgIHJlcS5yZXNwb25kV2l0aChyZXNwb25zZSk7XG4gIH1cbn1cblxuY29uc3Qgc2VydmVyID0gRGVuby5saXN0ZW4oeyBwb3J0OiA4MDgwIH0pO1xuY29uc29sZS5sb2coXCJjaGF0IHNlcnZlciBzdGFydGluZyBvbiA6ODA4MC4uLi5cIik7XG5cbmZvciBhd2FpdCAoY29uc3QgY29ubiBvZiBzZXJ2ZXIpIHtcbiAgKGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBodHRwQ29ubiA9IERlbm8uc2VydmVIdHRwKGNvbm4pO1xuICAgIGZvciBhd2FpdCAoY29uc3QgcmVxdWVzdEV2ZW50IG9mIGh0dHBDb25uKSB7XG4gICAgICByZXF1ZXN0SGFuZGxlcihyZXF1ZXN0RXZlbnQpO1xuICAgIH1cbiAgfSkoKTtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsU0FBUyxXQUFXLFFBQVEsb0JBQW9CO0FBQ2hELFNBQVMsd0JBQXdCLFFBQVEsOEJBQThCO0FBRXZFLE1BQU0sVUFBVSxJQUFJO0FBQ3BCLElBQUksV0FBVztBQUNmLFNBQVMsU0FBUyxH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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/VUHr_YUyq8otV9YiIbexaSOfQCs.js b/tests/__snapshots__/transpile/remote/modules/VUHr_YUyq8otV9YiIbexaSOfQCs.js new file mode 100644 index 0000000..3ee16ef --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/VUHr_YUyq8otV9YiIbexaSOfQCs.js @@ -0,0 +1,18 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +/** + * Ported mostly from https://github.com/browserify/path-browserify/ + * This module is browser compatible. + * @module + */ import { isWindows } from "../_util/os.ts"; +import * as _win32 from "./win32.ts"; +import * as _posix from "./posix.ts"; +const path = isWindows ? _win32 : _posix; +export const win32 = _win32; +export const posix = _posix; +export const { basename , delimiter , dirname , extname , format , fromFileUrl , isAbsolute , join , normalize , parse , relative , resolve , sep , toFileUrl , toNamespacedPath } = path; +export * from "./common.ts"; +export { SEP, SEP_PATTERN } from "./separator.ts"; +export * from "./_interface.ts"; +export * from "./glob.ts"; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvbW9kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgdGhlIEJyb3dzZXJpZnkgYXV0aG9ycy4gTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogUG9ydGVkIG1vc3RseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbiAqIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBpc1dpbmRvd3MgfSBmcm9tIFwiLi4vX3V0aWwvb3MudHNcIjtcbmltcG9ydCAqIGFzIF93aW4zMiBmcm9tIFwiLi93aW4zMi50c1wiO1xuaW1wb3J0ICogYXMgX3Bvc2l4IGZyb20gXCIuL3Bvc2l4LnRzXCI7XG5cbmNvbnN0IHBhdGggPSBpc1dpbmRvd3MgPyBfd2luMzIgOiBfcG9zaXg7XG5cbmV4cG9ydCBjb25zdCB3aW4zMiA9IF93aW4zMjtcbmV4cG9ydCBjb25zdCBwb3NpeCA9IF9wb3NpeDtcbmV4cG9ydCBjb25zdCB7XG4gIGJhc2VuYW1lLFxuICBkZWxpbWl0ZXIsXG4gIGRpcm5hbWUsXG4gIGV4dG5hbWUsXG4gIGZvcm1hdCxcbiAgZnJvbUZpbGVVcmwsXG4gIGlzQWJzb2x1dGUsXG4gIGpvaW4sXG4gIG5vcm1hbGl6ZSxcbiAgcGFyc2UsXG4gIHJlbGF0aXZlLFxuICByZXNvbHZlLFxuICBzZXAsXG4gIHRvRmlsZVVybCxcbiAgdG9OYW1lc3BhY2VkUGF0aCxcbn0gPSBwYXRoO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jb21tb24udHNcIjtcbmV4cG9ydCB7IFNFUCwgU0VQX1BBVFRFUk4gfSBmcm9tIFwiLi9zZXBhcmF0b3IudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL19pbnRlcmZhY2UudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2dsb2IudHNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsaURBQWlEO0FBRWpEOzs7O0NBSUMsR0FFRCxTQUFTLFNBQVMsUUFBUSxpQkFBaUI7QUFDM0MsWUFBWSxZQUFZLGFBQWE7QUFDckMsWUFBWSxZQUFZLGFBQWE7QUFFckMsTUFBTSxPQUFPLFlBQVksU0FBUyxNQUFNO0FBRXhDLE9BQU8sTUFBTSxRQUFRLE9BQU87QUFDNUIsT0FBTyxNQUFNLFFBQVEsT0FBTztBQUM1QixPQUFPLE1BQU0sRUFDWCxTQUFRLEVBQ1IsVUFBUyxFQUNULFFBQU8sRUFDUCxRQUFPLEVBQ1AsT0FBTSxFQUNOLFlBQVcsRUFDWCxXQUFVLEVBQ1YsS0FBSSxFQUNKLFVBQVMsRUFDVCxNQUFLLEVBQ0wsU0FBUSxFQUNSLFFBQU8sRUFDUCxJQUFHLEVBQ0gsVUFBUyxFQUNULGlCQUFnQixFQUNqQixHQUFHLEtBQUs7QUFFVCxjQUFjLGNBQWM7QUFDNUIsU0FBUyxHQUFHLEVBQUUsV0FBVyxRQUFRLGlCQUFpQjtBQUNsRCxjQUFjLGtCQUFrQjtBQUNoQyxjQUFjLFlBQVkifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/WKh_-mE6UYta1pB11lfX_WOvFQ8.js b/tests/__snapshots__/transpile/remote/modules/WKh_-mE6UYta1pB11lfX_WOvFQ8.js new file mode 100644 index 0000000..a5d3b86 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/WKh_-mE6UYta1pB11lfX_WOvFQ8.js @@ -0,0 +1,36 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +import { SEP } from "./separator.ts"; +/** Determines the common path from a set of paths, using an optional separator, + * which defaults to the OS default separator. + * + * ```ts + * import { common } from "https://deno.land/std@$STD_VERSION/path/mod.ts"; + * const p = common([ + * "./deno/std/path/mod.ts", + * "./deno/std/fs/mod.ts", + * ]); + * console.log(p); // "./deno/std/" + * ``` + */ export function common(paths, sep = SEP) { + const [first = "", ...remaining] = paths; + if (first === "" || remaining.length === 0) { + return first.substring(0, first.lastIndexOf(sep) + 1); + } + const parts = first.split(sep); + let endOfPrefix = parts.length; + for (const path of remaining){ + const compare = path.split(sep); + for(let i = 0; i < endOfPrefix; i++){ + if (compare[i] !== parts[i]) { + endOfPrefix = i; + } + } + if (endOfPrefix === 0) { + return ""; + } + } + const prefix = parts.slice(0, endOfPrefix).join(sep); + return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvY29tbW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmltcG9ydCB7IFNFUCB9IGZyb20gXCIuL3NlcGFyYXRvci50c1wiO1xuXG4vKiogRGV0ZXJtaW5lcyB0aGUgY29tbW9uIHBhdGggZnJvbSBhIHNldCBvZiBwYXRocywgdXNpbmcgYW4gb3B0aW9uYWwgc2VwYXJhdG9yLFxuICogd2hpY2ggZGVmYXVsdHMgdG8gdGhlIE9TIGRlZmF1bHQgc2VwYXJhdG9yLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgICBpbXBvcnQgeyBjb21tb24gfSBmcm9tIFwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQCRTVERfVkVSU0lPTi9wYXRoL21vZC50c1wiO1xuICogICAgICAgY29uc3QgcCA9IGNvbW1vbihbXG4gKiAgICAgICAgIFwiLi9kZW5vL3N0ZC9wYXRoL21vZC50c1wiLFxuICogICAgICAgICBcIi4vZGVuby9zdGQvZnMvbW9kLnRzXCIsXG4gKiAgICAgICBdKTtcbiAqICAgICAgIGNvbnNvbGUubG9nKHApOyAvLyBcIi4vZGVuby9zdGQvXCJcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tbW9uKHBhdGhzOiBzdHJpbmdbXSwgc2VwID0gU0VQKTogc3RyaW5nIHtcbiAgY29uc3QgW2ZpcnN0ID0gXCJcIiwgLi4ucmVtYWluaW5nXSA9IHBhdGhzO1xuICBpZiAoZmlyc3QgPT09IFwiXCIgfHwgcmVtYWluaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmaXJzdC5zdWJzdHJpbmcoMCwgZmlyc3QubGFzdEluZGV4T2Yoc2VwKSArIDEpO1xuICB9XG4gIGNvbnN0IHBhcnRzID0gZmlyc3Quc3BsaXQoc2VwKTtcblxuICBsZXQgZW5kT2ZQcmVmaXggPSBwYXJ0cy5sZW5ndGg7XG4gIGZvciAoY29uc3QgcGF0aCBvZiByZW1haW5pbmcpIHtcbiAgICBjb25zdCBjb21wYXJlID0gcGF0aC5zcGxpdChzZXApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZW5kT2ZQcmVmaXg7IGkrKykge1xuICAgICAgaWYgKGNvbXBhcmVbaV0gIT09IHBhcnRzW2ldKSB7XG4gICAgICAgIGVuZE9mUHJlZml4ID0gaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW5kT2ZQcmVmaXggPT09IDApIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgfVxuICBjb25zdCBwcmVmaXggPSBwYXJ0cy5zbGljZSgwLCBlbmRPZlByZWZpeCkuam9pbihzZXApO1xuICByZXR1cm4gcHJlZml4LmVuZHNXaXRoKHNlcCkgPyBwcmVmaXggOiBgJHtwcmVmaXh9JHtzZXB9YDtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDLFNBQVMsR0FBRyxRQUFRLGlCQUFpQjtBQUVyQzs7Ozs7Ozs7Ozs7Q0FXQyxHQUNELE9BQU8sU0FBUyxPQUFPLEtBQWUsRUFBRSxNQUFNLEdBQUcsRUFBVTtJQUN6RCxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsR0FBRyxVQUFVLEdBQUc7SUFDbkMsSUFBSSxVQUFVLE1BQU0sVUFBVSxNQUFNLEtBQUssR0FBRztRQUMxQyxPQUFPLE1BQU0sU0FBUyxDQUFDLEdBQUcsTUFBTSxXQUFXLENBQUMsT0FBTztJQUNyRCxDQUFDO0lBQ0QsTUFBTSxRQUFRLE1BQU0sS0FBSyxDQUFDO0lBRTFCLElBQUksY0FBYyxNQUFNLE1BQU07SUFDOUIsS0FBSyxNQUFNLFFBQVEsVUFBVztRQUM1QixNQUFNLFVBQVUsS0FBSyxLQUFLLENBQUM7UUFDM0IsSUFBSyxJQUFJLElBQUksR0FBRyxJQUFJLGFBQWEsSUFBSztZQUNwQyxJQUFJLE9BQU8sQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLEVBQUUsRUFBRTtnQkFDM0IsY0FBYztZQUNoQixDQUFDO1FBQ0g7UUFFQSxJQUFJLGdCQUFnQixHQUFHO1lBQ3JCLE9BQU87UUFDVCxDQUFDO0lBQ0g7SUFDQSxNQUFNLFNBQVMsTUFBTSxLQUFLLENBQUMsR0FBRyxhQUFhLElBQUksQ0FBQztJQUNoRCxPQUFPLE9BQU8sUUFBUSxDQUFDLE9BQU8sU0FBUyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQztBQUMxRCxDQUFDIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/WPpXvFGuxwYeU5ay2bDrdG4fV_g.js b/tests/__snapshots__/transpile/remote/modules/WPpXvFGuxwYeU5ay2bDrdG4fV_g.js new file mode 100644 index 0000000..ca8ef1e --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/WPpXvFGuxwYeU5ay2bDrdG4fV_g.js @@ -0,0 +1,852 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +import { CHAR_BACKWARD_SLASH, CHAR_COLON, CHAR_DOT, CHAR_QUESTION_MARK } from "./_constants.ts"; +import { _format, assertPath, encodeWhitespace, isPathSeparator, isWindowsDeviceRoot, normalizeString } from "./_util.ts"; +import { assert } from "../_util/assert.ts"; +export const sep = "\\"; +export const delimiter = ";"; +/** + * Resolves path segments into a `path` + * @param pathSegments to process to path + */ export function resolve(...pathSegments) { + let resolvedDevice = ""; + let resolvedTail = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1; i--){ + let path; + // deno-lint-ignore no-explicit-any + const { Deno } = globalThis; + if (i >= 0) { + path = pathSegments[i]; + } else if (!resolvedDevice) { + if (typeof Deno?.cwd !== "function") { + throw new TypeError("Resolved a drive-letter-less path without a CWD."); + } + path = Deno.cwd(); + } else { + if (typeof Deno?.env?.get !== "function" || typeof Deno?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno.cwd(); + // Verify that a cwd was found and that it actually points + // to our drive. If not, default to the drive's root. + if (path === undefined || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) { + path = `${resolvedDevice}\\`; + } + } + assertPath(path); + const len = path.length; + // Skip empty entries + if (len === 0) continue; + let rootEnd = 0; + let device = ""; + let isAbsolute = false; + const code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + // If we started with a separator, we know we at least have an + // absolute path of some kind (UNC or otherwise) + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + device = `\\\\${firstPart}\\${path.slice(last)}`; + rootEnd = j; + } else if (j !== last) { + // We matched a UNC root with leftovers + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + // Treat separator following drive name as an absolute path + // indicator + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator + rootEnd = 1; + isAbsolute = true; + } + if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) { + continue; + } + if (resolvedDevice.length === 0 && device.length > 0) { + resolvedDevice = device; + } + if (!resolvedAbsolute) { + resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`; + resolvedAbsolute = isAbsolute; + } + if (resolvedAbsolute && resolvedDevice.length > 0) break; + } + // At this point the path should be resolved to a full absolute path, + // but handle relative paths to be safe (might happen when process.cwd() + // fails) + // Normalize the tail path + resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator); + return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || "."; +} +/** + * Normalizes a `path` + * @param path to normalize + */ export function normalize(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = 0; + let device; + let isAbsolute = false; + const code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + // If we started with a separator, we know we at least have an absolute + // path of some kind (UNC or otherwise) + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + // Return the normalized version of the UNC root since there + // is nothing left to process + return `\\\\${firstPart}\\${path.slice(last)}\\`; + } else if (j !== last) { + // We matched a UNC root with leftovers + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + // Treat separator following drive name as an absolute path + // indicator + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator, exit early to avoid unnecessary + // work + return "\\"; + } + let tail; + if (rootEnd < len) { + tail = normalizeString(path.slice(rootEnd), !isAbsolute, "\\", isPathSeparator); + } else { + tail = ""; + } + if (tail.length === 0 && !isAbsolute) tail = "."; + if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) { + tail += "\\"; + } + if (device === undefined) { + if (isAbsolute) { + if (tail.length > 0) return `\\${tail}`; + else return "\\"; + } else if (tail.length > 0) { + return tail; + } else { + return ""; + } + } else if (isAbsolute) { + if (tail.length > 0) return `${device}\\${tail}`; + else return `${device}\\`; + } else if (tail.length > 0) { + return device + tail; + } else { + return device; + } +} +/** + * Verifies whether path is absolute + * @param path to verify + */ export function isAbsolute(path) { + assertPath(path); + const len = path.length; + if (len === 0) return false; + const code = path.charCodeAt(0); + if (isPathSeparator(code)) { + return true; + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (len > 2 && path.charCodeAt(1) === CHAR_COLON) { + if (isPathSeparator(path.charCodeAt(2))) return true; + } + } + return false; +} +/** + * Join all given a sequence of `paths`,then normalizes the resulting path. + * @param paths to be joined and normalized + */ export function join(...paths) { + const pathsCount = paths.length; + if (pathsCount === 0) return "."; + let joined; + let firstPart = null; + for(let i = 0; i < pathsCount; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (joined === undefined) joined = firstPart = path; + else joined += `\\${path}`; + } + } + if (joined === undefined) return "."; + // Make sure that the joined path doesn't start with two slashes, because + // normalize() will mistake it for an UNC path then. + // + // This step is skipped when it is very clear that the user actually + // intended to point at an UNC path. This is assumed when the first + // non-empty string arguments starts with exactly two slashes followed by + // at least one more non-slash character. + // + // Note that for normalize() to treat a path as an UNC path it needs to + // have at least 2 components, so we don't filter for that here. + // This means that the user can use join to construct UNC paths from + // a server name and a share name; for example: + // path.join('//server', 'share') -> '\\\\server\\share\\') + let needsReplace = true; + let slashCount = 0; + assert(firstPart != null); + if (isPathSeparator(firstPart.charCodeAt(0))) { + ++slashCount; + const firstLen = firstPart.length; + if (firstLen > 1) { + if (isPathSeparator(firstPart.charCodeAt(1))) { + ++slashCount; + if (firstLen > 2) { + if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount; + else { + // We matched a UNC path in the first part + needsReplace = false; + } + } + } + } + } + if (needsReplace) { + // Find any more consecutive slashes we need to replace + for(; slashCount < joined.length; ++slashCount){ + if (!isPathSeparator(joined.charCodeAt(slashCount))) break; + } + // Replace the slashes if needed + if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`; + } + return normalize(joined); +} +/** + * It will solve the relative path from `from` to `to`, for instance: + * from = 'C:\\orandea\\test\\aaa' + * to = 'C:\\orandea\\impl\\bbb' + * The output of the function should be: '..\\..\\impl\\bbb' + * @param from relative path + * @param to relative path + */ export function relative(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + const fromOrig = resolve(from); + const toOrig = resolve(to); + if (fromOrig === toOrig) return ""; + from = fromOrig.toLowerCase(); + to = toOrig.toLowerCase(); + if (from === to) return ""; + // Trim any leading backslashes + let fromStart = 0; + let fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== CHAR_BACKWARD_SLASH) break; + } + // Trim trailing backslashes (applicable to UNC paths only) + for(; fromEnd - 1 > fromStart; --fromEnd){ + if (from.charCodeAt(fromEnd - 1) !== CHAR_BACKWARD_SLASH) break; + } + const fromLen = fromEnd - fromStart; + // Trim any leading backslashes + let toStart = 0; + let toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== CHAR_BACKWARD_SLASH) break; + } + // Trim trailing backslashes (applicable to UNC paths only) + for(; toEnd - 1 > toStart; --toEnd){ + if (to.charCodeAt(toEnd - 1) !== CHAR_BACKWARD_SLASH) break; + } + const toLen = toEnd - toStart; + // Compare paths to find the longest common path from root + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === CHAR_BACKWARD_SLASH) { + // We get here if `from` is the exact base path for `to`. + // For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz' + return toOrig.slice(toStart + i + 1); + } else if (i === 2) { + // We get here if `from` is the device root. + // For example: from='C:\\'; to='C:\\foo' + return toOrig.slice(toStart + i); + } + } + if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === CHAR_BACKWARD_SLASH) { + // We get here if `to` is the exact base path for `from`. + // For example: from='C:\\foo\\bar'; to='C:\\foo' + lastCommonSep = i; + } else if (i === 2) { + // We get here if `to` is the device root. + // For example: from='C:\\foo\\bar'; to='C:\\' + lastCommonSep = 3; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === CHAR_BACKWARD_SLASH) lastCommonSep = i; + } + // We found a mismatch before the first common path separator was seen, so + // return the original `to`. + if (i !== length && lastCommonSep === -1) { + return toOrig; + } + let out = ""; + if (lastCommonSep === -1) lastCommonSep = 0; + // Generate the relative path based on the path difference between `to` and + // `from` + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === CHAR_BACKWARD_SLASH) { + if (out.length === 0) out += ".."; + else out += "\\.."; + } + } + // Lastly, append the rest of the destination (`to`) path that comes after + // the common path parts + if (out.length > 0) { + return out + toOrig.slice(toStart + lastCommonSep, toEnd); + } else { + toStart += lastCommonSep; + if (toOrig.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) ++toStart; + return toOrig.slice(toStart, toEnd); + } +} +/** + * Resolves path to a namespace path + * @param path to resolve to namespace + */ export function toNamespacedPath(path) { + // Note: this will *probably* throw somewhere. + if (typeof path !== "string") return path; + if (path.length === 0) return ""; + const resolvedPath = resolve(path); + if (resolvedPath.length >= 3) { + if (resolvedPath.charCodeAt(0) === CHAR_BACKWARD_SLASH) { + // Possible UNC root + if (resolvedPath.charCodeAt(1) === CHAR_BACKWARD_SLASH) { + const code = resolvedPath.charCodeAt(2); + if (code !== CHAR_QUESTION_MARK && code !== CHAR_DOT) { + // Matched non-long UNC root, convert the path to a long UNC path + return `\\\\?\\UNC\\${resolvedPath.slice(2)}`; + } + } + } else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) { + // Possible device root + if (resolvedPath.charCodeAt(1) === CHAR_COLON && resolvedPath.charCodeAt(2) === CHAR_BACKWARD_SLASH) { + // Matched device root, convert the path to a long UNC path + return `\\\\?\\${resolvedPath}`; + } + } + } + return path; +} +/** + * Return the directory name of a `path`. + * @param path to determine name for + */ export function dirname(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = -1; + let end = -1; + let matchedSlash = true; + let offset = 0; + const code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + rootEnd = offset = 1; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + return path; + } + if (j !== last) { + // We matched a UNC root with leftovers + // Offset by 1 to include the separator after the UNC root to + // treat it as a "normal root" on top of a (UNC) root + rootEnd = offset = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + rootEnd = offset = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3; + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator, exit early to avoid + // unnecessary work + return path; + } + for(let i = len - 1; i >= offset; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + if (!matchedSlash) { + end = i; + break; + } + } else { + // We saw the first non-path separator + matchedSlash = false; + } + } + if (end === -1) { + if (rootEnd === -1) return "."; + else end = rootEnd; + } + return path.slice(0, end); +} +/** + * Return the last portion of a `path`. Trailing directory separators are ignored. + * @param path to process + * @param ext of path directory + */ export function basename(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + // Check for a drive letter prefix so as not to mistake the following + // path separator as an extra separator at the end of the path that can be + // disregarded + if (path.length >= 2) { + const drive = path.charCodeAt(0); + if (isWindowsDeviceRoot(drive)) { + if (path.charCodeAt(1) === CHAR_COLON) start = 2; + } + } + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + // We saw the first non-path separator, remember this index in case + // we need it if the extension ends up not matching + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + // Try to match the explicit extension + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + // We matched the extension, so mark this as the end of our path + // component + end = i; + } + } else { + // Extension does not match, so our result is the entire path + // component + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= start; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // path component + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +/** + * Return the extension of the `path` with leading period. + * @param path with extension + * @returns extension (ex. for `file.ts` returns `.ts`) + */ export function extname(path) { + assertPath(path); + let start = 0; + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + // Check for a drive letter prefix so as not to mistake the following + // path separator as an extra separator at the end of the path that can be + // disregarded + if (path.length >= 2 && path.charCodeAt(1) === CHAR_COLON && isWindowsDeviceRoot(path.charCodeAt(0))) { + start = startPart = 2; + } + for(let i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +/** + * Generate a path from `FormatInputPathObject` object. + * @param pathObject with path + */ export function format(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("\\", pathObject); +} +/** + * Return a `ParsedPath` object of the `path`. + * @param path to process + */ export function parse(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + const len = path.length; + if (len === 0) return ret; + let rootEnd = 0; + let code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + rootEnd = 1; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + rootEnd = j; + } else if (j !== last) { + // We matched a UNC root with leftovers + rootEnd = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + if (len === 3) { + // `path` contains just a drive root, exit early to avoid + // unnecessary work + ret.root = ret.dir = path; + return ret; + } + rootEnd = 3; + } + } else { + // `path` contains just a drive root, exit early to avoid + // unnecessary work + ret.root = ret.dir = path; + return ret; + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator, exit early to avoid + // unnecessary work + ret.root = ret.dir = path; + return ret; + } + if (rootEnd > 0) ret.root = path.slice(0, rootEnd); + let startDot = -1; + let startPart = rootEnd; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + // Get non-dir info + for(; i >= rootEnd; --i){ + code = path.charCodeAt(i); + if (isPathSeparator(code)) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + ret.base = ret.name = path.slice(startPart, end); + } + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + ret.ext = path.slice(startDot, end); + } + // If the directory is the root, use the entire root as the `dir` including + // the trailing slash if any (`C:\abc` -> `C:\`). Otherwise, strip out the + // trailing slash (`C:\abc\def` -> `C:\abc`). + if (startPart > 0 && startPart !== rootEnd) { + ret.dir = path.slice(0, startPart - 1); + } else ret.dir = ret.root; + return ret; +} +/** + * Converts a file URL to a path string. + * + * ```ts + * import { fromFileUrl } from "./win32.ts"; + * fromFileUrl("file:///home/foo"); // "\\home\\foo" + * fromFileUrl("file:///C:/Users/foo"); // "C:\\Users\\foo" + * fromFileUrl("file://localhost/home/foo"); // "\\\\localhost\\home\\foo" + * ``` + * @param url of a file URL + */ export function fromFileUrl(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\"); + if (url.hostname != "") { + // Note: The `URL` implementation guarantees that the drive letter and + // hostname are mutually exclusive. Otherwise it would not have been valid + // to append the hostname and path like this. + path = `\\\\${url.hostname}${path}`; + } + return path; +} +/** + * Converts a path string to a file URL. + * + * ```ts + * import { toFileUrl } from "./win32.ts"; + * toFileUrl("\\home\\foo"); // new URL("file:///home/foo") + * toFileUrl("C:\\Users\\foo"); // new URL("file:///C:/Users/foo") + * toFileUrl("\\\\127.0.0.1\\home\\foo"); // new URL("file://127.0.0.1/home/foo") + * ``` + * @param path to convert to file URL + */ export function toFileUrl(path) { + if (!isAbsolute(path)) { + throw new TypeError("Must be an absolute path."); + } + const [, hostname, pathname] = path.match(/^(?:[/\\]{2}([^/\\]+)(?=[/\\](?:[^/\\]|$)))?(.*)/); + const url = new URL("file:///"); + url.pathname = encodeWhitespace(pathname.replace(/%/g, "%25")); + if (hostname != null && hostname != "localhost") { + url.hostname = hostname; + if (!url.hostname) { + throw new TypeError("Invalid hostname."); + } + } + return url; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvd2luMzIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QsIFBhcnNlZFBhdGggfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQge1xuICBDSEFSX0JBQ0tXQVJEX1NMQVNILFxuICBDSEFSX0NPTE9OLFxuICBDSEFSX0RPVCxcbiAgQ0hBUl9RVUVTVElPTl9NQVJLLFxufSBmcm9tIFwiLi9fY29uc3RhbnRzLnRzXCI7XG5cbmltcG9ydCB7XG4gIF9mb3JtYXQsXG4gIGFzc2VydFBhdGgsXG4gIGVuY29kZVdoaXRlc3BhY2UsXG4gIGlzUGF0aFNlcGFyYXRvcixcbiAgaXNXaW5kb3dzRGV2aWNlUm9vdCxcbiAgbm9ybWFsaXplU3RyaW5nLFxufSBmcm9tIFwiLi9fdXRpbC50c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL191dGlsL2Fzc2VydC50c1wiO1xuXG5leHBvcnQgY29uc3Qgc2VwID0gXCJcXFxcXCI7XG5leHBvcnQgY29uc3QgZGVsaW1pdGVyID0gXCI7XCI7XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCBzZWdtZW50cyBpbnRvIGEgYHBhdGhgXG4gKiBAcGFyYW0gcGF0aFNlZ21lbnRzIHRvIHByb2Nlc3MgdG8gcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZSguLi5wYXRoU2VnbWVudHM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgbGV0IHJlc29sdmVkRGV2aWNlID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkVGFpbCA9IFwiXCI7XG4gIGxldCByZXNvbHZlZEFic29sdXRlID0gZmFsc2U7XG5cbiAgZm9yIChsZXQgaSA9IHBhdGhTZWdtZW50cy5sZW5ndGggLSAxOyBpID49IC0xOyBpLS0pIHtcbiAgICBsZXQgcGF0aDogc3RyaW5nO1xuICAgIC8vIGRlbm8tbGludC1pZ25vcmUgbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgeyBEZW5vIH0gPSBnbG9iYWxUaGlzIGFzIGFueTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICBwYXRoID0gcGF0aFNlZ21lbnRzW2ldO1xuICAgIH0gZWxzZSBpZiAoIXJlc29sdmVkRGV2aWNlKSB7XG4gICAgICBpZiAodHlwZW9mIERlbm8/LmN3ZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIGRyaXZlLWxldHRlci1sZXNzIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgRGVubz8uZW52Py5nZXQgIT09IFwiZnVuY3Rpb25cIiB8fCB0eXBlb2YgRGVubz8uY3dkICE9PSBcImZ1bmN0aW9uXCJcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUmVzb2x2ZWQgYSByZWxhdGl2ZSBwYXRoIHdpdGhvdXQgYSBDV0QuXCIpO1xuICAgICAgfVxuICAgICAgcGF0aCA9IERlbm8uY3dkKCk7XG5cbiAgICAgIC8vIFZlcmlmeSB0aGF0IGEgY3dkIHdhcyBmb3VuZCBhbmQgdGhhdCBpdCBhY3R1YWxseSBwb2ludHNcbiAgICAgIC8vIHRvIG91ciBkcml2ZS4gSWYgbm90LCBkZWZhdWx0IHRvIHRoZSBkcml2ZSdzIHJvb3QuXG4gICAgICBpZiAoXG4gICAgICAgIHBhdGggPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICBwYXRoLnNsaWNlKDAsIDMpLnRvTG93ZXJDYXNlKCkgIT09IGAke3Jlc29sdmVkRGV2aWNlLnRvTG93ZXJDYXNlKCl9XFxcXGBcbiAgICAgICkge1xuICAgICAgICBwYXRoID0gYCR7cmVzb2x2ZWREZXZpY2V9XFxcXGA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICAgIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBlbnRyaWVzXG4gICAgaWYgKGxlbiA9PT0gMCkgY29udGludWU7XG5cbiAgICBsZXQgcm9vdEVuZCA9IDA7XG4gICAgbGV0IGRldmljZSA9IFwiXCI7XG4gICAgbGV0IGlzQWJzb2x1dGUgPSBmYWxzZTtcbiAgICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gICAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgICAgLy8gSWYgd2Ugc3RhcnRlZCB3aXRoIGEgc2VwYXJhdG9yLCB3ZSBrbm93IHdlIGF0IGxlYXN0IGhhdmUgYW5cbiAgICAgICAgLy8gYWJzb2x1dGUgcGF0aCBvZiBzb21lIGtpbmQgKFVOQyBvciBvdGhlcndpc2UpXG4gICAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuXG4gICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDEpKSkge1xuICAgICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICAgIGxldCBqID0gMjtcbiAgICAgICAgICBsZXQgbGFzdCA9IGo7XG4gICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdFBhcnQgPSBwYXRoLnNsaWNlKGxhc3QsIGopO1xuICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIHBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChqID09PSBsZW4pIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgb25seVxuICAgICAgICAgICAgICAgIGRldmljZSA9IGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCl9YDtcbiAgICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IHdpdGggbGVmdG92ZXJzXG5cbiAgICAgICAgICAgICAgICBkZXZpY2UgPSBgXFxcXFxcXFwke2ZpcnN0UGFydH1cXFxcJHtwYXRoLnNsaWNlKGxhc3QsIGopfWA7XG4gICAgICAgICAgICAgICAgcm9vdEVuZCA9IGo7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcm9vdEVuZCA9IDE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChjb2RlKSkge1xuICAgICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgICBkZXZpY2UgPSBwYXRoLnNsaWNlKDAsIDIpO1xuICAgICAgICAgIHJvb3RFbmQgPSAyO1xuICAgICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgyKSkpIHtcbiAgICAgICAgICAgICAgLy8gVHJlYXQgc2VwYXJhdG9yIGZvbGxvd2luZyBkcml2ZSBuYW1lIGFzIGFuIGFic29sdXRlIHBhdGhcbiAgICAgICAgICAgICAgLy8gaW5kaWNhdG9yXG4gICAgICAgICAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuICAgICAgICAgICAgICByb290RW5kID0gMztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBwYXRoIHNlcGFyYXRvclxuICAgICAgcm9vdEVuZCA9IDE7XG4gICAgICBpc0Fic29sdXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBkZXZpY2UubGVuZ3RoID4gMCAmJlxuICAgICAgcmVzb2x2ZWREZXZpY2UubGVuZ3RoID4gMCAmJlxuICAgICAgZGV2aWNlLnRvTG93ZXJDYXNlKCkgIT09IHJlc29sdmVkRGV2aWNlLnRvTG93ZXJDYXNlKClcbiAgICApIHtcbiAgICAgIC8vIFRoaXMgcGF0aCBwb2ludHMgdG8gYW5vdGhlciBkZXZpY2Ugc28gaXQgaXMgbm90IGFwcGxpY2FibGVcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChyZXNvbHZlZERldmljZS5sZW5ndGggPT09IDAgJiYgZGV2aWNlLmxlbmd0aCA+IDApIHtcbiAgICAgIHJlc29sdmVkRGV2aWNlID0gZGV2aWNlO1xuICAgIH1cbiAgICBpZiAoIXJlc29sdmVkQWJzb2x1dGUpIHtcbiAgICAgIHJlc29sdmVkVGFpbCA9IGAke3BhdGguc2xpY2Uocm9vdEVuZCl9XFxcXCR7cmVzb2x2ZWRUYWlsfWA7XG4gICAgICByZXNvbHZlZEFic29sdXRlID0gaXNBYnNvbHV0ZTtcbiAgICB9XG5cbiAgICBpZiAocmVzb2x2ZWRBYnNvbHV0ZSAmJiByZXNvbHZlZERldmljZS5sZW5ndGggPiAwKSBicmVhaztcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLFxuICAvLyBidXQgaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKClcbiAgLy8gZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSB0YWlsIHBhdGhcbiAgcmVzb2x2ZWRUYWlsID0gbm9ybWFsaXplU3RyaW5nKFxuICAgIHJlc29sdmVkVGFpbCxcbiAgICAhcmVzb2x2ZWRBYnNvbHV0ZSxcbiAgICBcIlxcXFxcIixcbiAgICBpc1BhdGhTZXBhcmF0b3IsXG4gICk7XG5cbiAgcmV0dXJuIHJlc29sdmVkRGV2aWNlICsgKHJlc29sdmVkQWJzb2x1dGUgPyBcIlxcXFxcIiA6IFwiXCIpICsgcmVzb2x2ZWRUYWlsIHx8IFwiLlwiO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBgcGF0aGBcbiAqIEBwYXJhbSBwYXRoIHRvIG5vcm1hbGl6ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCByb290RW5kID0gMDtcbiAgbGV0IGRldmljZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBsZXQgaXNBYnNvbHV0ZSA9IGZhbHNlO1xuICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gIC8vIFRyeSB0byBtYXRjaCBhIHJvb3RcbiAgaWYgKGxlbiA+IDEpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICAvLyBJZiB3ZSBzdGFydGVkIHdpdGggYSBzZXBhcmF0b3IsIHdlIGtub3cgd2UgYXQgbGVhc3QgaGF2ZSBhbiBhYnNvbHV0ZVxuICAgICAgLy8gcGF0aCBvZiBzb21lIGtpbmQgKFVOQyBvciBvdGhlcndpc2UpXG4gICAgICBpc0Fic29sdXRlID0gdHJ1ZTtcblxuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICBsZXQgaiA9IDI7XG4gICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgIGNvbnN0IGZpcnN0UGFydCA9IHBhdGguc2xpY2UobGFzdCwgaik7XG4gICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgaWYgKCFpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaiA9PT0gbGVuKSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCBvbmx5XG4gICAgICAgICAgICAgIC8vIFJldHVybiB0aGUgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBVTkMgcm9vdCBzaW5jZSB0aGVyZVxuICAgICAgICAgICAgICAvLyBpcyBub3RoaW5nIGxlZnQgdG8gcHJvY2Vzc1xuXG4gICAgICAgICAgICAgIHJldHVybiBgXFxcXFxcXFwke2ZpcnN0UGFydH1cXFxcJHtwYXRoLnNsaWNlKGxhc3QpfVxcXFxgO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCB3aXRoIGxlZnRvdmVyc1xuXG4gICAgICAgICAgICAgIGRldmljZSA9IGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCwgail9YDtcbiAgICAgICAgICAgICAgcm9vdEVuZCA9IGo7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByb290RW5kID0gMTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgZGV2aWNlID0gcGF0aC5zbGljZSgwLCAyKTtcbiAgICAgICAgcm9vdEVuZCA9IDI7XG4gICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSB7XG4gICAgICAgICAgICAvLyBUcmVhdCBzZXBhcmF0b3IgZm9sbG93aW5nIGRyaXZlIG5hbWUgYXMgYW4gYWJzb2x1dGUgcGF0aFxuICAgICAgICAgICAgLy8gaW5kaWNhdG9yXG4gICAgICAgICAgICBpc0Fic29sdXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIHJvb3RFbmQgPSAzO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yLCBleGl0IGVhcmx5IHRvIGF2b2lkIHVubmVjZXNzYXJ5XG4gICAgLy8gd29ya1xuICAgIHJldHVybiBcIlxcXFxcIjtcbiAgfVxuXG4gIGxldCB0YWlsOiBzdHJpbmc7XG4gIGlmIChyb290RW5kIDwgbGVuKSB7XG4gICAgdGFpbCA9IG5vcm1hbGl6ZVN0cmluZyhcbiAgICAgIHBhdGguc2xpY2Uocm9vdEVuZCksXG4gICAgICAhaXNBYnNvbHV0ZSxcbiAgICAgIFwiXFxcXFwiLFxuICAgICAgaXNQYXRoU2VwYXJhdG9yLFxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgdGFpbCA9IFwiXCI7XG4gIH1cbiAgaWYgKHRhaWwubGVuZ3RoID09PSAwICYmICFpc0Fic29sdXRlKSB0YWlsID0gXCIuXCI7XG4gIGlmICh0YWlsLmxlbmd0aCA+IDAgJiYgaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChsZW4gLSAxKSkpIHtcbiAgICB0YWlsICs9IFwiXFxcXFwiO1xuICB9XG4gIGlmIChkZXZpY2UgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChpc0Fic29sdXRlKSB7XG4gICAgICBpZiAodGFpbC5sZW5ndGggPiAwKSByZXR1cm4gYFxcXFwke3RhaWx9YDtcbiAgICAgIGVsc2UgcmV0dXJuIFwiXFxcXFwiO1xuICAgIH0gZWxzZSBpZiAodGFpbC5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdGFpbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICBpZiAodGFpbC5sZW5ndGggPiAwKSByZXR1cm4gYCR7ZGV2aWNlfVxcXFwke3RhaWx9YDtcbiAgICBlbHNlIHJldHVybiBgJHtkZXZpY2V9XFxcXGA7XG4gIH0gZWxzZSBpZiAodGFpbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGRldmljZSArIHRhaWw7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRldmljZTtcbiAgfVxufVxuXG4vKipcbiAqIFZlcmlmaWVzIHdoZXRoZXIgcGF0aCBpcyBhYnNvbHV0ZVxuICogQHBhcmFtIHBhdGggdG8gdmVyaWZ5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Fic29sdXRlKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICBjb25zdCBsZW4gPSBwYXRoLmxlbmd0aDtcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG4gIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgLy8gUG9zc2libGUgZGV2aWNlIHJvb3RcblxuICAgIGlmIChsZW4gPiAyICYmIHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikge1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEpvaW4gYWxsIGdpdmVuIGEgc2VxdWVuY2Ugb2YgYHBhdGhzYCx0aGVuIG5vcm1hbGl6ZXMgdGhlIHJlc3VsdGluZyBwYXRoLlxuICogQHBhcmFtIHBhdGhzIHRvIGJlIGpvaW5lZCBhbmQgbm9ybWFsaXplZFxuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbiguLi5wYXRoczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCBwYXRoc0NvdW50ID0gcGF0aHMubGVuZ3RoO1xuICBpZiAocGF0aHNDb3VudCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuXG4gIGxldCBqb2luZWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbGV0IGZpcnN0UGFydDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0aHNDb3VudDsgKytpKSB7XG4gICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgIGFzc2VydFBhdGgocGF0aCk7XG4gICAgaWYgKHBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGpvaW5lZCA9PT0gdW5kZWZpbmVkKSBqb2luZWQgPSBmaXJzdFBhcnQgPSBwYXRoO1xuICAgICAgZWxzZSBqb2luZWQgKz0gYFxcXFwke3BhdGh9YDtcbiAgICB9XG4gIH1cblxuICBpZiAoam9pbmVkID09PSB1bmRlZmluZWQpIHJldHVybiBcIi5cIjtcblxuICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgam9pbmVkIHBhdGggZG9lc24ndCBzdGFydCB3aXRoIHR3byBzbGFzaGVzLCBiZWNhdXNlXG4gIC8vIG5vcm1hbGl6ZSgpIHdpbGwgbWlzdGFrZSBpdCBmb3IgYW4gVU5DIHBhdGggdGhlbi5cbiAgLy9cbiAgLy8gVGhpcyBzdGVwIGlzIHNraXBwZWQgd2hlbiBpdCBpcyB2ZXJ5IGNsZWFyIHRoYXQgdGhlIHVzZXIgYWN0dWFsbHlcbiAgLy8gaW50ZW5kZWQgdG8gcG9pbnQgYXQgYW4gVU5DIHBhdGguIFRoaXMgaXMgYXNzdW1lZCB3aGVuIHRoZSBmaXJzdFxuICAvLyBub24tZW1wdHkgc3RyaW5nIGFyZ3VtZW50cyBzdGFydHMgd2l0aCBleGFjdGx5IHR3byBzbGFzaGVzIGZvbGxvd2VkIGJ5XG4gIC8vIGF0IGxlYXN0IG9uZSBtb3JlIG5vbi1zbGFzaCBjaGFyYWN0ZXIuXG4gIC8vXG4gIC8vIE5vdGUgdGhhdCBmb3Igbm9ybWFsaXplKCkgdG8gdHJlYXQgYSBwYXRoIGFzIGFuIFVOQyBwYXRoIGl0IG5lZWRzIHRvXG4gIC8vIGhhdmUgYXQgbGVhc3QgMiBjb21wb25lbnRzLCBzbyB3ZSBkb24ndCBmaWx0ZXIgZm9yIHRoYXQgaGVyZS5cbiAgLy8gVGhpcyBtZWFucyB0aGF0IHRoZSB1c2VyIGNhbiB1c2Ugam9pbiB0byBjb25zdHJ1Y3QgVU5DIHBhdGhzIGZyb21cbiAgLy8gYSBzZXJ2ZXIgbmFtZSBhbmQgYSBzaGFyZSBuYW1lOyBmb3IgZXhhbXBsZTpcbiAgLy8gICBwYXRoLmpvaW4oJy8vc2VydmVyJywgJ3NoYXJlJykgLT4gJ1xcXFxcXFxcc2VydmVyXFxcXHNoYXJlXFxcXCcpXG4gIGxldCBuZWVkc1JlcGxhY2UgPSB0cnVlO1xuICBsZXQgc2xhc2hDb3VudCA9IDA7XG4gIGFzc2VydChmaXJzdFBhcnQgIT0gbnVsbCk7XG4gIGlmIChpc1BhdGhTZXBhcmF0b3IoZmlyc3RQYXJ0LmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgKytzbGFzaENvdW50O1xuICAgIGNvbnN0IGZpcnN0TGVuID0gZmlyc3RQYXJ0Lmxlbmd0aDtcbiAgICBpZiAoZmlyc3RMZW4gPiAxKSB7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGZpcnN0UGFydC5jaGFyQ29kZUF0KDEpKSkge1xuICAgICAgICArK3NsYXNoQ291bnQ7XG4gICAgICAgIGlmIChmaXJzdExlbiA+IDIpIHtcbiAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGZpcnN0UGFydC5jaGFyQ29kZUF0KDIpKSkgKytzbGFzaENvdW50O1xuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyBwYXRoIGluIHRoZSBmaXJzdCBwYXJ0XG4gICAgICAgICAgICBuZWVkc1JlcGxhY2UgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKG5lZWRzUmVwbGFjZSkge1xuICAgIC8vIEZpbmQgYW55IG1vcmUgY29uc2VjdXRpdmUgc2xhc2hlcyB3ZSBuZWVkIHRvIHJlcGxhY2VcbiAgICBmb3IgKDsgc2xhc2hDb3VudCA8IGpvaW5lZC5sZW5ndGg7ICsrc2xhc2hDb3VudCkge1xuICAgICAgaWYgKCFpc1BhdGhTZXBhcmF0b3Ioam9pbmVkLmNoYXJDb2RlQXQoc2xhc2hDb3VudCkpKSBicmVhaztcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBzbGFzaGVzIGlmIG5lZWRlZFxuICAgIGlmIChzbGFzaENvdW50ID49IDIpIGpvaW5lZCA9IGBcXFxcJHtqb2luZWQuc2xpY2Uoc2xhc2hDb3VudCl9YDtcbiAgfVxuXG4gIHJldHVybiBub3JtYWxpemUoam9pbmVkKTtcbn1cblxuLyoqXG4gKiBJdCB3aWxsIHNvbHZlIHRoZSByZWxhdGl2ZSBwYXRoIGZyb20gYGZyb21gIHRvIGB0b2AsIGZvciBpbnN0YW5jZTpcbiAqICBmcm9tID0gJ0M6XFxcXG9yYW5kZWFcXFxcdGVzdFxcXFxhYWEnXG4gKiAgdG8gPSAnQzpcXFxcb3JhbmRlYVxcXFxpbXBsXFxcXGJiYidcbiAqIFRoZSBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uIHNob3VsZCBiZTogJy4uXFxcXC4uXFxcXGltcGxcXFxcYmJiJ1xuICogQHBhcmFtIGZyb20gcmVsYXRpdmUgcGF0aFxuICogQHBhcmFtIHRvIHJlbGF0aXZlIHBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbGF0aXZlKGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgoZnJvbSk7XG4gIGFzc2VydFBhdGgodG8pO1xuXG4gIGlmIChmcm9tID09PSB0bykgcmV0dXJuIFwiXCI7XG5cbiAgY29uc3QgZnJvbU9yaWcgPSByZXNvbHZlKGZyb20pO1xuICBjb25zdCB0b09yaWcgPSByZXNvbHZlKHRvKTtcblxuICBpZiAoZnJvbU9yaWcgPT09IHRvT3JpZykgcmV0dXJuIFwiXCI7XG5cbiAgZnJvbSA9IGZyb21PcmlnLnRvTG93ZXJDYXNlKCk7XG4gIHRvID0gdG9PcmlnLnRvTG93ZXJDYXNlKCk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICAvLyBUcmltIGFueSBsZWFkaW5nIGJhY2tzbGFzaGVzXG4gIGxldCBmcm9tU3RhcnQgPSAwO1xuICBsZXQgZnJvbUVuZCA9IGZyb20ubGVuZ3RoO1xuICBmb3IgKDsgZnJvbVN0YXJ0IDwgZnJvbUVuZDsgKytmcm9tU3RhcnQpIHtcbiAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIC8vIFRyaW0gdHJhaWxpbmcgYmFja3NsYXNoZXMgKGFwcGxpY2FibGUgdG8gVU5DIHBhdGhzIG9ubHkpXG4gIGZvciAoOyBmcm9tRW5kIC0gMSA+IGZyb21TdGFydDsgLS1mcm9tRW5kKSB7XG4gICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tRW5kIC0gMSkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IGZyb21MZW4gPSBmcm9tRW5kIC0gZnJvbVN0YXJ0O1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IHRvU3RhcnQgPSAwO1xuICBsZXQgdG9FbmQgPSB0by5sZW5ndGg7XG4gIGZvciAoOyB0b1N0YXJ0IDwgdG9FbmQ7ICsrdG9TdGFydCkge1xuICAgIGlmICh0by5jaGFyQ29kZUF0KHRvU3RhcnQpICE9PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSBicmVhaztcbiAgfVxuICAvLyBUcmltIHRyYWlsaW5nIGJhY2tzbGFzaGVzIChhcHBsaWNhYmxlIHRvIFVOQyBwYXRocyBvbmx5KVxuICBmb3IgKDsgdG9FbmQgLSAxID4gdG9TdGFydDsgLS10b0VuZCkge1xuICAgIGlmICh0by5jaGFyQ29kZUF0KHRvRW5kIC0gMSkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IHRvTGVuID0gdG9FbmQgLSB0b1N0YXJ0O1xuXG4gIC8vIENvbXBhcmUgcGF0aHMgdG8gZmluZCB0aGUgbG9uZ2VzdCBjb21tb24gcGF0aCBmcm9tIHJvb3RcbiAgY29uc3QgbGVuZ3RoID0gZnJvbUxlbiA8IHRvTGVuID8gZnJvbUxlbiA6IHRvTGVuO1xuICBsZXQgbGFzdENvbW1vblNlcCA9IC0xO1xuICBsZXQgaSA9IDA7XG4gIGZvciAoOyBpIDw9IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGkgPT09IGxlbmd0aCkge1xuICAgICAgaWYgKHRvTGVuID4gbGVuZ3RoKSB7XG4gICAgICAgIGlmICh0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgICAgIC8vIFdlIGdldCBoZXJlIGlmIGBmcm9tYCBpcyB0aGUgZXhhY3QgYmFzZSBwYXRoIGZvciBgdG9gLlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPSdDOlxcXFxmb29cXFxcYmFyJzsgdG89J0M6XFxcXGZvb1xcXFxiYXJcXFxcYmF6J1xuICAgICAgICAgIHJldHVybiB0b09yaWcuc2xpY2UodG9TdGFydCArIGkgKyAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChpID09PSAyKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYGZyb21gIGlzIHRoZSBkZXZpY2Ugcm9vdC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nQzpcXFxcJzsgdG89J0M6XFxcXGZvbydcbiAgICAgICAgICByZXR1cm4gdG9PcmlnLnNsaWNlKHRvU3RhcnQgKyBpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZyb21MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgICAgIC8vIFdlIGdldCBoZXJlIGlmIGB0b2AgaXMgdGhlIGV4YWN0IGJhc2UgcGF0aCBmb3IgYGZyb21gLlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPSdDOlxcXFxmb29cXFxcYmFyJzsgdG89J0M6XFxcXGZvbydcbiAgICAgICAgICBsYXN0Q29tbW9uU2VwID0gaTtcbiAgICAgICAgfSBlbHNlIGlmIChpID09PSAyKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYHRvYCBpcyB0aGUgZGV2aWNlIHJvb3QuXG4gICAgICAgICAgLy8gRm9yIGV4YW1wbGU6IGZyb209J0M6XFxcXGZvb1xcXFxiYXInOyB0bz0nQzpcXFxcJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSAzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY29uc3QgZnJvbUNvZGUgPSBmcm9tLmNoYXJDb2RlQXQoZnJvbVN0YXJ0ICsgaSk7XG4gICAgY29uc3QgdG9Db2RlID0gdG8uY2hhckNvZGVBdCh0b1N0YXJ0ICsgaSk7XG4gICAgaWYgKGZyb21Db2RlICE9PSB0b0NvZGUpIGJyZWFrO1xuICAgIGVsc2UgaWYgKGZyb21Db2RlID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSBsYXN0Q29tbW9uU2VwID0gaTtcbiAgfVxuXG4gIC8vIFdlIGZvdW5kIGEgbWlzbWF0Y2ggYmVmb3JlIHRoZSBmaXJzdCBjb21tb24gcGF0aCBzZXBhcmF0b3Igd2FzIHNlZW4sIHNvXG4gIC8vIHJldHVybiB0aGUgb3JpZ2luYWwgYHRvYC5cbiAgaWYgKGkgIT09IGxlbmd0aCAmJiBsYXN0Q29tbW9uU2VwID09PSAtMSkge1xuICAgIHJldHVybiB0b09yaWc7XG4gIH1cblxuICBsZXQgb3V0ID0gXCJcIjtcbiAgaWYgKGxhc3RDb21tb25TZXAgPT09IC0xKSBsYXN0Q29tbW9uU2VwID0gMDtcbiAgLy8gR2VuZXJhdGUgdGhlIHJlbGF0aXZlIHBhdGggYmFzZWQgb24gdGhlIHBhdGggZGlmZmVyZW5jZSBiZXR3ZWVuIGB0b2AgYW5kXG4gIC8vIGBmcm9tYFxuICBmb3IgKGkgPSBmcm9tU3RhcnQgKyBsYXN0Q29tbW9uU2VwICsgMTsgaSA8PSBmcm9tRW5kOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gZnJvbUVuZCB8fCBmcm9tLmNoYXJDb2RlQXQoaSkgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIHtcbiAgICAgIGlmIChvdXQubGVuZ3RoID09PSAwKSBvdXQgKz0gXCIuLlwiO1xuICAgICAgZWxzZSBvdXQgKz0gXCJcXFxcLi5cIjtcbiAgICB9XG4gIH1cblxuICAvLyBMYXN0bHksIGFwcGVuZCB0aGUgcmVzdCBvZiB0aGUgZGVzdGluYXRpb24gKGB0b2ApIHBhdGggdGhhdCBjb21lcyBhZnRlclxuICAvLyB0aGUgY29tbW9uIHBhdGggcGFydHNcbiAgaWYgKG91dC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIG91dCArIHRvT3JpZy5zbGljZSh0b1N0YXJ0ICsgbGFzdENvbW1vblNlcCwgdG9FbmQpO1xuICB9IGVsc2Uge1xuICAgIHRvU3RhcnQgKz0gbGFzdENvbW1vblNlcDtcbiAgICBpZiAodG9PcmlnLmNoYXJDb2RlQXQodG9TdGFydCkgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpICsrdG9TdGFydDtcbiAgICByZXR1cm4gdG9PcmlnLnNsaWNlKHRvU3RhcnQsIHRvRW5kKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHBhdGggdG8gYSBuYW1lc3BhY2UgcGF0aFxuICogQHBhcmFtIHBhdGggdG8gcmVzb2x2ZSB0byBuYW1lc3BhY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvTmFtZXNwYWNlZFBhdGgocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gTm90ZTogdGhpcyB3aWxsICpwcm9iYWJseSogdGhyb3cgc29tZXdoZXJlLlxuICBpZiAodHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHJldHVybiBwYXRoO1xuICBpZiAocGF0aC5sZW5ndGggPT09IDApIHJldHVybiBcIlwiO1xuXG4gIGNvbnN0IHJlc29sdmVkUGF0aCA9IHJlc29sdmUocGF0aCk7XG5cbiAgaWYgKHJlc29sdmVkUGF0aC5sZW5ndGggPj0gMykge1xuICAgIGlmIChyZXNvbHZlZFBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgLy8gUG9zc2libGUgVU5DIHJvb3RcblxuICAgICAgaWYgKHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAgIGNvbnN0IGNvZGUgPSByZXNvbHZlZFBhdGguY2hhckNvZGVBdCgyKTtcbiAgICAgICAgaWYgKGNvZGUgIT09IENIQVJfUVVFU1RJT05fTUFSSyAmJiBjb2RlICE9PSBDSEFSX0RPVCkge1xuICAgICAgICAgIC8vIE1hdGNoZWQgbm9uLWxvbmcgVU5DIHJvb3QsIGNvbnZlcnQgdGhlIHBhdGggdG8gYSBsb25nIFVOQyBwYXRoXG4gICAgICAgICAgcmV0dXJuIGBcXFxcXFxcXD9cXFxcVU5DXFxcXCR7cmVzb2x2ZWRQYXRoLnNsaWNlKDIpfWA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QocmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICBpZiAoXG4gICAgICAgIHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OICYmXG4gICAgICAgIHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDIpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIXG4gICAgICApIHtcbiAgICAgICAgLy8gTWF0Y2hlZCBkZXZpY2Ugcm9vdCwgY29udmVydCB0aGUgcGF0aCB0byBhIGxvbmcgVU5DIHBhdGhcbiAgICAgICAgcmV0dXJuIGBcXFxcXFxcXD9cXFxcJHtyZXNvbHZlZFBhdGh9YDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGRpcmVjdG9yeSBuYW1lIG9mIGEgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gZGV0ZXJtaW5lIG5hbWUgZm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCByb290RW5kID0gLTE7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gIC8vIFRyeSB0byBtYXRjaCBhIHJvb3RcbiAgaWYgKGxlbiA+IDEpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICByb290RW5kID0gb2Zmc2V0ID0gMTtcblxuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICBsZXQgaiA9IDI7XG4gICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIHBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgIGlmICghaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogPT09IGxlbikge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgb25seVxuICAgICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCB3aXRoIGxlZnRvdmVyc1xuXG4gICAgICAgICAgICAgIC8vIE9mZnNldCBieSAxIHRvIGluY2x1ZGUgdGhlIHNlcGFyYXRvciBhZnRlciB0aGUgVU5DIHJvb3QgdG9cbiAgICAgICAgICAgICAgLy8gdHJlYXQgaXQgYXMgYSBcIm5vcm1hbCByb290XCIgb24gdG9wIG9mIGEgKFVOQykgcm9vdFxuICAgICAgICAgICAgICByb290RW5kID0gb2Zmc2V0ID0gaiArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OKSB7XG4gICAgICAgIHJvb3RFbmQgPSBvZmZzZXQgPSAyO1xuICAgICAgICBpZiAobGVuID4gMikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDIpKSkgcm9vdEVuZCA9IG9mZnNldCA9IDM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBwYXRoIHNlcGFyYXRvciwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgIC8vIHVubmVjZXNzYXJ5IHdvcmtcbiAgICByZXR1cm4gcGF0aDtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSBsZW4gLSAxOyBpID49IG9mZnNldDsgLS1pKSB7XG4gICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaSkpKSB7XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3JcbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbmQgPT09IC0xKSB7XG4gICAgaWYgKHJvb3RFbmQgPT09IC0xKSByZXR1cm4gXCIuXCI7XG4gICAgZWxzZSBlbmQgPSByb290RW5kO1xuICB9XG4gIHJldHVybiBwYXRoLnNsaWNlKDAsIGVuZCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBsYXN0IHBvcnRpb24gb2YgYSBgcGF0aGAuIFRyYWlsaW5nIGRpcmVjdG9yeSBzZXBhcmF0b3JzIGFyZSBpZ25vcmVkLlxuICogQHBhcmFtIHBhdGggdG8gcHJvY2Vzc1xuICogQHBhcmFtIGV4dCBvZiBwYXRoIGRpcmVjdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmFzZW5hbWUocGF0aDogc3RyaW5nLCBleHQgPSBcIlwiKTogc3RyaW5nIHtcbiAgaWYgKGV4dCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBleHQgIT09IFwic3RyaW5nXCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImV4dFwiIGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgfVxuXG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGk6IG51bWJlcjtcblxuICAvLyBDaGVjayBmb3IgYSBkcml2ZSBsZXR0ZXIgcHJlZml4IHNvIGFzIG5vdCB0byBtaXN0YWtlIHRoZSBmb2xsb3dpbmdcbiAgLy8gcGF0aCBzZXBhcmF0b3IgYXMgYW4gZXh0cmEgc2VwYXJhdG9yIGF0IHRoZSBlbmQgb2YgdGhlIHBhdGggdGhhdCBjYW4gYmVcbiAgLy8gZGlzcmVnYXJkZWRcbiAgaWYgKHBhdGgubGVuZ3RoID49IDIpIHtcbiAgICBjb25zdCBkcml2ZSA9IHBhdGguY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChkcml2ZSkpIHtcbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHN0YXJ0ID0gMjtcbiAgICB9XG4gIH1cblxuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgZXh0Lmxlbmd0aCA+IDAgJiYgZXh0Lmxlbmd0aCA8PSBwYXRoLmxlbmd0aCkge1xuICAgIGlmIChleHQubGVuZ3RoID09PSBwYXRoLmxlbmd0aCAmJiBleHQgPT09IHBhdGgpIHJldHVybiBcIlwiO1xuICAgIGxldCBleHRJZHggPSBleHQubGVuZ3RoIC0gMTtcbiAgICBsZXQgZmlyc3ROb25TbGFzaEVuZCA9IC0xO1xuICAgIGZvciAoaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgICAvLyBzZXBhcmF0b3JzIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZywgc3RvcCBub3dcbiAgICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgICBzdGFydCA9IGkgKyAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmlyc3ROb25TbGFzaEVuZCA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgcmVtZW1iZXIgdGhpcyBpbmRleCBpbiBjYXNlXG4gICAgICAgICAgLy8gd2UgbmVlZCBpdCBpZiB0aGUgZXh0ZW5zaW9uIGVuZHMgdXAgbm90IG1hdGNoaW5nXG4gICAgICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICAgICAgZmlyc3ROb25TbGFzaEVuZCA9IGkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChleHRJZHggPj0gMCkge1xuICAgICAgICAgIC8vIFRyeSB0byBtYXRjaCB0aGUgZXhwbGljaXQgZXh0ZW5zaW9uXG4gICAgICAgICAgaWYgKGNvZGUgPT09IGV4dC5jaGFyQ29kZUF0KGV4dElkeCkpIHtcbiAgICAgICAgICAgIGlmICgtLWV4dElkeCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCB0aGUgZXh0ZW5zaW9uLCBzbyBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXIgcGF0aFxuICAgICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgICAgZW5kID0gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gRXh0ZW5zaW9uIGRvZXMgbm90IG1hdGNoLCBzbyBvdXIgcmVzdWx0IGlzIHRoZSBlbnRpcmUgcGF0aFxuICAgICAgICAgICAgLy8gY29tcG9uZW50XG4gICAgICAgICAgICBleHRJZHggPSAtMTtcbiAgICAgICAgICAgIGVuZCA9IGZpcnN0Tm9uU2xhc2hFbmQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ID09PSBlbmQpIGVuZCA9IGZpcnN0Tm9uU2xhc2hFbmQ7XG4gICAgZWxzZSBpZiAoZW5kID09PSAtMSkgZW5kID0gcGF0aC5sZW5ndGg7XG4gICAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnQsIGVuZCk7XG4gIH0gZWxzZSB7XG4gICAgZm9yIChpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IHN0YXJ0OyAtLWkpIHtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGkpKSkge1xuICAgICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgICAvLyBzZXBhcmF0b3JzIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZywgc3RvcCBub3dcbiAgICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgICBzdGFydCA9IGkgKyAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3IsIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91clxuICAgICAgICAvLyBwYXRoIGNvbXBvbmVudFxuICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgZW5kID0gaSArIDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVuZCA9PT0gLTEpIHJldHVybiBcIlwiO1xuICAgIHJldHVybiBwYXRoLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBleHRlbnNpb24gb2YgdGhlIGBwYXRoYCB3aXRoIGxlYWRpbmcgcGVyaW9kLlxuICogQHBhcmFtIHBhdGggd2l0aCBleHRlbnNpb25cbiAqIEByZXR1cm5zIGV4dGVuc2lvbiAoZXguIGZvciBgZmlsZS50c2AgcmV0dXJucyBgLnRzYClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dG5hbWUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IHN0YXJ0RG90ID0gLTE7XG4gIGxldCBzdGFydFBhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICAvLyBUcmFjayB0aGUgc3RhdGUgb2YgY2hhcmFjdGVycyAoaWYgYW55KSB3ZSBzZWUgYmVmb3JlIG91ciBmaXJzdCBkb3QgYW5kXG4gIC8vIGFmdGVyIGFueSBwYXRoIHNlcGFyYXRvciB3ZSBmaW5kXG4gIGxldCBwcmVEb3RTdGF0ZSA9IDA7XG5cbiAgLy8gQ2hlY2sgZm9yIGEgZHJpdmUgbGV0dGVyIHByZWZpeCBzbyBhcyBub3QgdG8gbWlzdGFrZSB0aGUgZm9sbG93aW5nXG4gIC8vIHBhdGggc2VwYXJhdG9yIGFzIGFuIGV4dHJhIHNlcGFyYXRvciBhdCB0aGUgZW5kIG9mIHRoZSBwYXRoIHRoYXQgY2FuIGJlXG4gIC8vIGRpc3JlZ2FyZGVkXG5cbiAgaWYgKFxuICAgIHBhdGgubGVuZ3RoID49IDIgJiZcbiAgICBwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04gJiZcbiAgICBpc1dpbmRvd3NEZXZpY2VSb290KHBhdGguY2hhckNvZGVBdCgwKSlcbiAgKSB7XG4gICAgc3RhcnQgPSBzdGFydFBhcnQgPSAyO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICByZXR1cm4gXCJcIjtcbiAgfVxuICByZXR1cm4gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHBhdGggZnJvbSBgRm9ybWF0SW5wdXRQYXRoT2JqZWN0YCBvYmplY3QuXG4gKiBAcGFyYW0gcGF0aE9iamVjdCB3aXRoIHBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdChwYXRoT2JqZWN0OiBGb3JtYXRJbnB1dFBhdGhPYmplY3QpOiBzdHJpbmcge1xuICBpZiAocGF0aE9iamVjdCA9PT0gbnVsbCB8fCB0eXBlb2YgcGF0aE9iamVjdCAhPT0gXCJvYmplY3RcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICBgVGhlIFwicGF0aE9iamVjdFwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBPYmplY3QuIFJlY2VpdmVkIHR5cGUgJHt0eXBlb2YgcGF0aE9iamVjdH1gLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIF9mb3JtYXQoXCJcXFxcXCIsIHBhdGhPYmplY3QpO1xufVxuXG4vKipcbiAqIFJldHVybiBhIGBQYXJzZWRQYXRoYCBvYmplY3Qgb2YgdGhlIGBwYXRoYC5cbiAqIEBwYXJhbSBwYXRoIHRvIHByb2Nlc3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlKHBhdGg6IHN0cmluZyk6IFBhcnNlZFBhdGgge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gIGNvbnN0IHJldDogUGFyc2VkUGF0aCA9IHsgcm9vdDogXCJcIiwgZGlyOiBcIlwiLCBiYXNlOiBcIlwiLCBleHQ6IFwiXCIsIG5hbWU6IFwiXCIgfTtcblxuICBjb25zdCBsZW4gPSBwYXRoLmxlbmd0aDtcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIHJldDtcblxuICBsZXQgcm9vdEVuZCA9IDA7XG4gIGxldCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gIC8vIFRyeSB0byBtYXRjaCBhIHJvb3RcbiAgaWYgKGxlbiA+IDEpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICByb290RW5kID0gMTtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDEpKSkge1xuICAgICAgICAvLyBNYXRjaGVkIGRvdWJsZSBwYXRoIHNlcGFyYXRvciBhdCBiZWdpbm5pbmdcbiAgICAgICAgbGV0IGogPSAyO1xuICAgICAgICBsZXQgbGFzdCA9IGo7XG4gICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBwYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqID09PSBsZW4pIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IG9ubHlcblxuICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgd2l0aCBsZWZ0b3ZlcnNcblxuICAgICAgICAgICAgICByb290RW5kID0gaiArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OKSB7XG4gICAgICAgIHJvb3RFbmQgPSAyO1xuICAgICAgICBpZiAobGVuID4gMikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDIpKSkge1xuICAgICAgICAgICAgaWYgKGxlbiA9PT0gMykge1xuICAgICAgICAgICAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIGRyaXZlIHJvb3QsIGV4aXQgZWFybHkgdG8gYXZvaWRcbiAgICAgICAgICAgICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgICAgICAgICAgICByZXQucm9vdCA9IHJldC5kaXIgPSBwYXRoO1xuICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcm9vdEVuZCA9IDM7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGBwYXRoYCBjb250YWlucyBqdXN0IGEgZHJpdmUgcm9vdCwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgICAgICAgIC8vIHVubmVjZXNzYXJ5IHdvcmtcbiAgICAgICAgICByZXQucm9vdCA9IHJldC5kaXIgPSBwYXRoO1xuICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBwYXRoIHNlcGFyYXRvciwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgIC8vIHVubmVjZXNzYXJ5IHdvcmtcbiAgICByZXQucm9vdCA9IHJldC5kaXIgPSBwYXRoO1xuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICBpZiAocm9vdEVuZCA+IDApIHJldC5yb290ID0gcGF0aC5zbGljZSgwLCByb290RW5kKTtcblxuICBsZXQgc3RhcnREb3QgPSAtMTtcbiAgbGV0IHN0YXJ0UGFydCA9IHJvb3RFbmQ7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGxldCBpID0gcGF0aC5sZW5ndGggLSAxO1xuXG4gIC8vIFRyYWNrIHRoZSBzdGF0ZSBvZiBjaGFyYWN0ZXJzIChpZiBhbnkpIHdlIHNlZSBiZWZvcmUgb3VyIGZpcnN0IGRvdCBhbmRcbiAgLy8gYWZ0ZXIgYW55IHBhdGggc2VwYXJhdG9yIHdlIGZpbmRcbiAgbGV0IHByZURvdFN0YXRlID0gMDtcblxuICAvLyBHZXQgbm9uLWRpciBpbmZvXG4gIGZvciAoOyBpID49IHJvb3RFbmQ7IC0taSkge1xuICAgIGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgc3RhcnRQYXJ0ID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25cbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgZW5kID0gaSArIDE7XG4gICAgfVxuICAgIGlmIChjb2RlID09PSBDSEFSX0RPVCkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBvdXIgZmlyc3QgZG90LCBtYXJrIGl0IGFzIHRoZSBzdGFydCBvZiBvdXIgZXh0ZW5zaW9uXG4gICAgICBpZiAoc3RhcnREb3QgPT09IC0xKSBzdGFydERvdCA9IGk7XG4gICAgICBlbHNlIGlmIChwcmVEb3RTdGF0ZSAhPT0gMSkgcHJlRG90U3RhdGUgPSAxO1xuICAgIH0gZWxzZSBpZiAoc3RhcnREb3QgIT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgYSBub24tZG90IGFuZCBub24tcGF0aCBzZXBhcmF0b3IgYmVmb3JlIG91ciBkb3QsIHNvIHdlIHNob3VsZFxuICAgICAgLy8gaGF2ZSBhIGdvb2QgY2hhbmNlIGF0IGhhdmluZyBhIG5vbi1lbXB0eSBleHRlbnNpb25cbiAgICAgIHByZURvdFN0YXRlID0gLTE7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIHN0YXJ0RG90ID09PSAtMSB8fFxuICAgIGVuZCA9PT0gLTEgfHxcbiAgICAvLyBXZSBzYXcgYSBub24tZG90IGNoYXJhY3RlciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGRvdFxuICAgIHByZURvdFN0YXRlID09PSAwIHx8XG4gICAgLy8gVGhlIChyaWdodC1tb3N0KSB0cmltbWVkIHBhdGggY29tcG9uZW50IGlzIGV4YWN0bHkgJy4uJ1xuICAgIChwcmVEb3RTdGF0ZSA9PT0gMSAmJiBzdGFydERvdCA9PT0gZW5kIC0gMSAmJiBzdGFydERvdCA9PT0gc3RhcnRQYXJ0ICsgMSlcbiAgKSB7XG4gICAgaWYgKGVuZCAhPT0gLTEpIHtcbiAgICAgIHJldC5iYXNlID0gcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKHN0YXJ0UGFydCwgZW5kKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKHN0YXJ0UGFydCwgc3RhcnREb3QpO1xuICAgIHJldC5iYXNlID0gcGF0aC5zbGljZShzdGFydFBhcnQsIGVuZCk7XG4gICAgcmV0LmV4dCA9IHBhdGguc2xpY2Uoc3RhcnREb3QsIGVuZCk7XG4gIH1cblxuICAvLyBJZiB0aGUgZGlyZWN0b3J5IGlzIHRoZSByb290LCB1c2UgdGhlIGVudGlyZSByb290IGFzIHRoZSBgZGlyYCBpbmNsdWRpbmdcbiAgLy8gdGhlIHRyYWlsaW5nIHNsYXNoIGlmIGFueSAoYEM6XFxhYmNgIC0+IGBDOlxcYCkuIE90aGVyd2lzZSwgc3RyaXAgb3V0IHRoZVxuICAvLyB0cmFpbGluZyBzbGFzaCAoYEM6XFxhYmNcXGRlZmAgLT4gYEM6XFxhYmNgKS5cbiAgaWYgKHN0YXJ0UGFydCA+IDAgJiYgc3RhcnRQYXJ0ICE9PSByb290RW5kKSB7XG4gICAgcmV0LmRpciA9IHBhdGguc2xpY2UoMCwgc3RhcnRQYXJ0IC0gMSk7XG4gIH0gZWxzZSByZXQuZGlyID0gcmV0LnJvb3Q7XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIGZpbGUgVVJMIHRvIGEgcGF0aCBzdHJpbmcuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgZnJvbUZpbGVVcmwgfSBmcm9tIFwiLi93aW4zMi50c1wiO1xuICogICAgICBmcm9tRmlsZVVybChcImZpbGU6Ly8vaG9tZS9mb29cIik7IC8vIFwiXFxcXGhvbWVcXFxcZm9vXCJcbiAqICAgICAgZnJvbUZpbGVVcmwoXCJmaWxlOi8vL0M6L1VzZXJzL2Zvb1wiKTsgLy8gXCJDOlxcXFxVc2Vyc1xcXFxmb29cIlxuICogICAgICBmcm9tRmlsZVVybChcImZpbGU6Ly9sb2NhbGhvc3QvaG9tZS9mb29cIik7IC8vIFwiXFxcXFxcXFxsb2NhbGhvc3RcXFxcaG9tZVxcXFxmb29cIlxuICogYGBgXG4gKiBAcGFyYW0gdXJsIG9mIGEgZmlsZSBVUkxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyb21GaWxlVXJsKHVybDogc3RyaW5nIHwgVVJMKTogc3RyaW5nIHtcbiAgdXJsID0gdXJsIGluc3RhbmNlb2YgVVJMID8gdXJsIDogbmV3IFVSTCh1cmwpO1xuICBpZiAodXJsLnByb3RvY29sICE9IFwiZmlsZTpcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNdXN0IGJlIGEgZmlsZSBVUkwuXCIpO1xuICB9XG4gIGxldCBwYXRoID0gZGVjb2RlVVJJQ29tcG9uZW50KFxuICAgIHVybC5wYXRobmFtZS5yZXBsYWNlKC9cXC8vZywgXCJcXFxcXCIpLnJlcGxhY2UoLyUoPyFbMC05QS1GYS1mXXsyfSkvZywgXCIlMjVcIiksXG4gICkucmVwbGFjZSgvXlxcXFwqKFtBLVphLXpdOikoXFxcXHwkKS8sIFwiJDFcXFxcXCIpO1xuICBpZiAodXJsLmhvc3RuYW1lICE9IFwiXCIpIHtcbiAgICAvLyBOb3RlOiBUaGUgYFVSTGAgaW1wbGVtZW50YXRpb24gZ3VhcmFudGVlcyB0aGF0IHRoZSBkcml2ZSBsZXR0ZXIgYW5kXG4gICAgLy8gaG9zdG5hbWUgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS4gT3RoZXJ3aXNlIGl0IHdvdWxkIG5vdCBoYXZlIGJlZW4gdmFsaWRcbiAgICAvLyB0byBhcHBlbmQgdGhlIGhvc3RuYW1lIGFuZCBwYXRoIGxpa2UgdGhpcy5cbiAgICBwYXRoID0gYFxcXFxcXFxcJHt1cmwuaG9zdG5hbWV9JHtwYXRofWA7XG4gIH1cbiAgcmV0dXJuIHBhdGg7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBwYXRoIHN0cmluZyB0byBhIGZpbGUgVVJMLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IHRvRmlsZVVybCB9IGZyb20gXCIuL3dpbjMyLnRzXCI7XG4gKiAgICAgIHRvRmlsZVVybChcIlxcXFxob21lXFxcXGZvb1wiKTsgLy8gbmV3IFVSTChcImZpbGU6Ly8vaG9tZS9mb29cIilcbiAqICAgICAgdG9GaWxlVXJsKFwiQzpcXFxcVXNlcnNcXFxcZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9DOi9Vc2Vycy9mb29cIilcbiAqICAgICAgdG9GaWxlVXJsKFwiXFxcXFxcXFwxMjcuMC4wLjFcXFxcaG9tZVxcXFxmb29cIik7IC8vIG5ldyBVUkwoXCJmaWxlOi8vMTI3LjAuMC4xL2hvbWUvZm9vXCIpXG4gKiBgYGBcbiAqIEBwYXJhbSBwYXRoIHRvIGNvbnZlcnQgdG8gZmlsZSBVUkxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRmlsZVVybChwYXRoOiBzdHJpbmcpOiBVUkwge1xuICBpZiAoIWlzQWJzb2x1dGUocGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTXVzdCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlwiKTtcbiAgfVxuICBjb25zdCBbLCBob3N0bmFtZSwgcGF0aG5hbWVdID0gcGF0aC5tYXRjaChcbiAgICAvXig/OlsvXFxcXF17Mn0oW14vXFxcXF0rKSg/PVsvXFxcXF0oPzpbXi9cXFxcXXwkKSkpPyguKikvLFxuICApITtcbiAgY29uc3QgdXJsID0gbmV3IFVSTChcImZpbGU6Ly8vXCIpO1xuICB1cmwucGF0aG5hbWUgPSBlbmNvZGVXaGl0ZXNwYWNlKHBhdGhuYW1lLnJlcGxhY2UoLyUvZywgXCIlMjVcIikpO1xuICBpZiAoaG9zdG5hbWUgIT0gbnVsbCAmJiBob3N0bmFtZSAhPSBcImxvY2FsaG9zdFwiKSB7XG4gICAgdXJsLmhvc3RuYW1lID0gaG9zdG5hbWU7XG4gICAgaWYgKCF1cmwuaG9zdG5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGhvc3RuYW1lLlwiKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVybDtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsaURBQWlEO0FBQ2pELDZEQUE2RDtBQUM3RCxxQ0FBcUM7QUFHckMsU0FDRSxtQkFBbUIsRUFDbkIsVUFBVSxFQUNWLFFBQVEsRUFDUixrQkFBa0IsUUFDYixrQkFBa0I7QUFFekIsU0FDRSxPQUFPLEVBQ1AsVUFBVSxFQUNWLGdCQUFnQixFQUNoQixl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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/WStdDhyHbKYy_C9CJ39RDks1VaY.js b/tests/__snapshots__/transpile/remote/modules/WStdDhyHbKYy_C9CJ39RDks1VaY.js new file mode 100644 index 0000000..bd10af7 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/WStdDhyHbKYy_C9CJ39RDks1VaY.js @@ -0,0 +1,228 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** + * Provides helper functions to manipulate `Uint8Array` byte slices that are not + * included on the `Uint8Array` prototype. + * + * @module + */ /** Returns the index of the first occurrence of the needle array in the source + * array, or -1 if it is not present. + * + * A start index can be specified as the third argument that begins the search + * at that given index. The start index defaults to the start of the array. + * + * The complexity of this function is O(source.lenth * needle.length). + * + * ```ts + * import { indexOfNeedle } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const needle = new Uint8Array([1, 2]); + * console.log(indexOfNeedle(source, needle)); // 1 + * console.log(indexOfNeedle(source, needle, 2)); // 3 + * ``` + */ export function indexOfNeedle(source, needle, start = 0) { + if (start >= source.length) { + return -1; + } + if (start < 0) { + start = Math.max(0, source.length + start); + } + const s = needle[0]; + for(let i = start; i < source.length; i++){ + if (source[i] !== s) continue; + const pin = i; + let matched = 1; + let j = i; + while(matched < needle.length){ + j++; + if (source[j] !== needle[j - pin]) { + break; + } + matched++; + } + if (matched === needle.length) { + return pin; + } + } + return -1; +} +/** Returns the index of the last occurrence of the needle array in the source + * array, or -1 if it is not present. + * + * A start index can be specified as the third argument that begins the search + * at that given index. The start index defaults to the end of the array. + * + * The complexity of this function is O(source.lenth * needle.length). + * + * ```ts + * import { lastIndexOfNeedle } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const needle = new Uint8Array([1, 2]); + * console.log(lastIndexOfNeedle(source, needle)); // 5 + * console.log(lastIndexOfNeedle(source, needle, 4)); // 3 + * ``` + */ export function lastIndexOfNeedle(source, needle, start = source.length - 1) { + if (start < 0) { + return -1; + } + if (start >= source.length) { + start = source.length - 1; + } + const e = needle[needle.length - 1]; + for(let i = start; i >= 0; i--){ + if (source[i] !== e) continue; + const pin = i; + let matched = 1; + let j = i; + while(matched < needle.length){ + j--; + if (source[j] !== needle[needle.length - 1 - (pin - j)]) { + break; + } + matched++; + } + if (matched === needle.length) { + return pin - needle.length + 1; + } + } + return -1; +} +/** Returns true if the prefix array appears at the start of the source array, + * false otherwise. + * + * The complexity of this function is O(prefix.length). + * + * ```ts + * import { startsWith } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const prefix = new Uint8Array([0, 1, 2]); + * console.log(startsWith(source, prefix)); // true + * ``` + */ export function startsWith(source, prefix) { + for(let i = 0, max = prefix.length; i < max; i++){ + if (source[i] !== prefix[i]) return false; + } + return true; +} +/** Returns true if the suffix array appears at the end of the source array, + * false otherwise. + * + * The complexity of this function is O(suffix.length). + * + * ```ts + * import { endsWith } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const suffix = new Uint8Array([1, 2, 3]); + * console.log(endsWith(source, suffix)); // true + * ``` + */ export function endsWith(source, suffix) { + for(let srci = source.length - 1, sfxi = suffix.length - 1; sfxi >= 0; srci--, sfxi--){ + if (source[srci] !== suffix[sfxi]) return false; + } + return true; +} +/** Returns a new Uint8Array composed of `count` repetitions of the `source` + * array. + * + * If `count` is negative, a `RangeError` is thrown. + * + * ```ts + * import { repeat } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2]); + * console.log(repeat(source, 3)); // [0, 1, 2, 0, 1, 2, 0, 1, 2] + * console.log(repeat(source, 0)); // [] + * console.log(repeat(source, -1)); // RangeError + * ``` + */ export function repeat(source, count) { + if (count === 0) { + return new Uint8Array(); + } + if (count < 0) { + throw new RangeError("bytes: negative repeat count"); + } else if (source.length * count / count !== source.length) { + throw new Error("bytes: repeat count causes overflow"); + } + const int = Math.floor(count); + if (int !== count) { + throw new Error("bytes: repeat count must be an integer"); + } + const nb = new Uint8Array(source.length * count); + let bp = copy(source, nb); + for(; bp < nb.length; bp *= 2){ + copy(nb.slice(0, bp), nb, bp); + } + return nb; +} +/** Concatenate the given arrays into a new Uint8Array. + * + * ```ts + * import { concat } from "./mod.ts"; + * const a = new Uint8Array([0, 1, 2]); + * const b = new Uint8Array([3, 4, 5]); + * console.log(concat(a, b)); // [0, 1, 2, 3, 4, 5] + */ export function concat(...buf) { + let length = 0; + for (const b of buf){ + length += b.length; + } + const output = new Uint8Array(length); + let index = 0; + for (const b of buf){ + output.set(b, index); + index += b.length; + } + return output; +} +/** Returns true if the source array contains the needle array, false otherwise. + * + * A start index can be specified as the third argument that begins the search + * at that given index. The start index defaults to the beginning of the array. + * + * The complexity of this function is O(source.length * needle.length). + * + * ```ts + * import { includesNeedle } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const needle = new Uint8Array([1, 2]); + * console.log(includesNeedle(source, needle)); // true + * console.log(includesNeedle(source, needle, 6)); // false + * ``` + */ export function includesNeedle(source, needle, start = 0) { + return indexOfNeedle(source, needle, start) !== -1; +} +/** Copy bytes from the `src` array to the `dst` array. Returns the number of + * bytes copied. + * + * If the `src` array is larger than what the `dst` array can hold, only the + * amount of bytes that fit in the `dst` array are copied. + * + * An offset can be specified as the third argument that begins the copy at + * that given index in the `dst` array. The offset defaults to the beginning of + * the array. + * + * ```ts + * import { copy } from "./mod.ts"; + * const src = new Uint8Array([9, 8, 7]); + * const dst = new Uint8Array([0, 1, 2, 3, 4, 5]); + * console.log(copy(src, dst)); // 3 + * console.log(dst); // [9, 8, 7, 3, 4, 5] + * ``` + * + * ```ts + * import { copy } from "./mod.ts"; + * const src = new Uint8Array([1, 1, 1, 1]); + * const dst = new Uint8Array([0, 0, 0, 0]); + * console.log(copy(src, dst, 1)); // 3 + * console.log(dst); // [0, 1, 1, 1] + * ``` + */ export function copy(src, dst, off = 0) { + off = Math.max(0, Math.min(off, dst.byteLength)); + const dstBytesAvailable = dst.byteLength - off; + if (src.byteLength > dstBytesAvailable) { + src = src.subarray(0, dstBytesAvailable); + } + dst.set(src, off); + return src.byteLength; +} +export { equals } from "./equals.ts"; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2J5dGVzL21vZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vKipcbiAqIFByb3ZpZGVzIGhlbHBlciBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSBgVWludDhBcnJheWAgYnl0ZSBzbGljZXMgdGhhdCBhcmUgbm90XG4gKiBpbmNsdWRlZCBvbiB0aGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuLyoqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBuZWVkbGUgYXJyYXkgaW4gdGhlIHNvdXJjZVxuICogYXJyYXksIG9yIC0xIGlmIGl0IGlzIG5vdCBwcmVzZW50LlxuICpcbiAqIEEgc3RhcnQgaW5kZXggY2FuIGJlIHNwZWNpZmllZCBhcyB0aGUgdGhpcmQgYXJndW1lbnQgdGhhdCBiZWdpbnMgdGhlIHNlYXJjaFxuICogYXQgdGhhdCBnaXZlbiBpbmRleC4gVGhlIHN0YXJ0IGluZGV4IGRlZmF1bHRzIHRvIHRoZSBzdGFydCBvZiB0aGUgYXJyYXkuXG4gKlxuICogVGhlIGNvbXBsZXhpdHkgb2YgdGhpcyBmdW5jdGlvbiBpcyBPKHNvdXJjZS5sZW50aCAqIG5lZWRsZS5sZW5ndGgpLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpbmRleE9mTmVlZGxlIH0gZnJvbSBcIi4vbW9kLnRzXCI7XG4gKiBjb25zdCBzb3VyY2UgPSBuZXcgVWludDhBcnJheShbMCwgMSwgMiwgMSwgMiwgMSwgMiwgM10pO1xuICogY29uc3QgbmVlZGxlID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDJdKTtcbiAqIGNvbnNvbGUubG9nKGluZGV4T2ZOZWVkbGUoc291cmNlLCBuZWVkbGUpKTsgLy8gMVxuICogY29uc29sZS5sb2coaW5kZXhPZk5lZWRsZShzb3VyY2UsIG5lZWRsZSwgMikpOyAvLyAzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZGV4T2ZOZWVkbGUoXG4gIHNvdXJjZTogVWludDhBcnJheSxcbiAgbmVlZGxlOiBVaW50OEFycmF5LFxuICBzdGFydCA9IDAsXG4pOiBudW1iZXIge1xuICBpZiAoc3RhcnQgPj0gc291cmNlLmxlbmd0aCkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSBNYXRoLm1heCgwLCBzb3VyY2UubGVuZ3RoICsgc3RhcnQpO1xuICB9XG4gIGNvbnN0IHMgPSBuZWVkbGVbMF07XG4gIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IHNvdXJjZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzb3VyY2VbaV0gIT09IHMpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHBpbiA9IGk7XG4gICAgbGV0IG1hdGNoZWQgPSAxO1xuICAgIGxldCBqID0gaTtcbiAgICB3aGlsZSAobWF0Y2hlZCA8IG5lZWRsZS5sZW5ndGgpIHtcbiAgICAgIGorKztcbiAgICAgIGlmIChzb3VyY2Vbal0gIT09IG5lZWRsZVtqIC0gcGluXSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIG1hdGNoZWQrKztcbiAgICB9XG4gICAgaWYgKG1hdGNoZWQgPT09IG5lZWRsZS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBwaW47XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxuLyoqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIG5lZWRsZSBhcnJheSBpbiB0aGUgc291cmNlXG4gKiBhcnJheSwgb3IgLTEgaWYgaXQgaXMgbm90IHByZXNlbnQuXG4gKlxuICogQSBzdGFydCBpbmRleCBjYW4gYmUgc3BlY2lmaWVkIGFzIHRoZSB0aGlyZCBhcmd1bWVudCB0aGF0IGJlZ2lucyB0aGUgc2VhcmNoXG4gKiBhdCB0aGF0IGdpdmVuIGluZGV4LiBUaGUgc3RhcnQgaW5kZXggZGVmYXVsdHMgdG8gdGhlIGVuZCBvZiB0aGUgYXJyYXkuXG4gKlxuICogVGhlIGNvbXBsZXhpdHkgb2YgdGhpcyBmdW5jdGlvbiBpcyBPKHNvdXJjZS5sZW50aCAqIG5lZWRsZS5sZW5ndGgpLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBsYXN0SW5kZXhPZk5lZWRsZSB9IGZyb20gXCIuL21vZC50c1wiO1xuICogY29uc3Qgc291cmNlID0gbmV3IFVpbnQ4QXJyYXkoWzAsIDEsIDIsIDEsIDIsIDEsIDIsIDNdKTtcbiAqIGNvbnN0IG5lZWRsZSA9IG5ldyBVaW50OEFycmF5KFsxLCAyXSk7XG4gKiBjb25zb2xlLmxvZyhsYXN0SW5kZXhPZk5lZWRsZShzb3VyY2UsIG5lZWRsZSkpOyAvLyA1XG4gKiBjb25zb2xlLmxvZyhsYXN0SW5kZXhPZk5lZWRsZShzb3VyY2UsIG5lZWRsZSwgNCkpOyAvLyAzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhc3RJbmRleE9mTmVlZGxlKFxuICBzb3VyY2U6IFVpbnQ4QXJyYXksXG4gIG5lZWRsZTogVWludDhBcnJheSxcbiAgc3RhcnQgPSBzb3VyY2UubGVuZ3RoIC0gMSxcbik6IG51bWJlciB7XG4gIGlmIChzdGFydCA8IDApIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHN0YXJ0ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICBzdGFydCA9IHNvdXJjZS5sZW5ndGggLSAxO1xuICB9XG4gIGNvbnN0IGUgPSBuZWVkbGVbbmVlZGxlLmxlbmd0aCAtIDFdO1xuICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKHNvdXJjZVtpXSAhPT0gZSkgY29udGludWU7XG4gICAgY29uc3QgcGluID0gaTtcbiAgICBsZXQgbWF0Y2hlZCA9IDE7XG4gICAgbGV0IGogPSBpO1xuICAgIHdoaWxlIChtYXRjaGVkIDwgbmVlZGxlLmxlbmd0aCkge1xuICAgICAgai0tO1xuICAgICAgaWYgKHNvdXJjZVtqXSAhPT0gbmVlZGxlW25lZWRsZS5sZW5ndGggLSAxIC0gKHBpbiAtIGopXSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIG1hdGNoZWQrKztcbiAgICB9XG4gICAgaWYgKG1hdGNoZWQgPT09IG5lZWRsZS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBwaW4gLSBuZWVkbGUubGVuZ3RoICsgMTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG4vKiogUmV0dXJucyB0cnVlIGlmIHRoZSBwcmVmaXggYXJyYXkgYXBwZWFycyBhdCB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZSBhcnJheSxcbiAqIGZhbHNlIG90aGVyd2lzZS5cbiAqXG4gKiBUaGUgY29tcGxleGl0eSBvZiB0aGlzIGZ1bmN0aW9uIGlzIE8ocHJlZml4Lmxlbmd0aCkuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IHN0YXJ0c1dpdGggfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqIGNvbnN0IHNvdXJjZSA9IG5ldyBVaW50OEFycmF5KFswLCAxLCAyLCAxLCAyLCAxLCAyLCAzXSk7XG4gKiBjb25zdCBwcmVmaXggPSBuZXcgVWludDhBcnJheShbMCwgMSwgMl0pO1xuICogY29uc29sZS5sb2coc3RhcnRzV2l0aChzb3VyY2UsIHByZWZpeCkpOyAvLyB0cnVlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0c1dpdGgoc291cmNlOiBVaW50OEFycmF5LCBwcmVmaXg6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgZm9yIChsZXQgaSA9IDAsIG1heCA9IHByZWZpeC5sZW5ndGg7IGkgPCBtYXg7IGkrKykge1xuICAgIGlmIChzb3VyY2VbaV0gIT09IHByZWZpeFtpXSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogUmV0dXJucyB0cnVlIGlmIHRoZSBzdWZmaXggYXJyYXkgYXBwZWFycyBhdCB0aGUgZW5kIG9mIHRoZSBzb3VyY2UgYXJyYXksXG4gKiBmYWxzZSBvdGhlcndpc2UuXG4gKlxuICogVGhlIGNvbXBsZXhpdHkgb2YgdGhpcyBmdW5jdGlvbiBpcyBPKHN1ZmZpeC5sZW5ndGgpLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBlbmRzV2l0aCB9IGZyb20gXCIuL21vZC50c1wiO1xuICogY29uc3Qgc291cmNlID0gbmV3IFVpbnQ4QXJyYXkoWzAsIDEsIDIsIDEsIDIsIDEsIDIsIDNdKTtcbiAqIGNvbnN0IHN1ZmZpeCA9IG5ldyBVaW50OEFycmF5KFsxLCAyLCAzXSk7XG4gKiBjb25zb2xlLmxvZyhlbmRzV2l0aChzb3VyY2UsIHN1ZmZpeCkpOyAvLyB0cnVlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuZHNXaXRoKHNvdXJjZTogVWludDhBcnJheSwgc3VmZml4OiBVaW50OEFycmF5KTogYm9vbGVhbiB7XG4gIGZvciAoXG4gICAgbGV0IHNyY2kgPSBzb3VyY2UubGVuZ3RoIC0gMSwgc2Z4aSA9IHN1ZmZpeC5sZW5ndGggLSAxO1xuICAgIHNmeGkgPj0gMDtcbiAgICBzcmNpLS0sIHNmeGktLVxuICApIHtcbiAgICBpZiAoc291cmNlW3NyY2ldICE9PSBzdWZmaXhbc2Z4aV0pIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqIFJldHVybnMgYSBuZXcgVWludDhBcnJheSBjb21wb3NlZCBvZiBgY291bnRgIHJlcGV0aXRpb25zIG9mIHRoZSBgc291cmNlYFxuICogYXJyYXkuXG4gKlxuICogSWYgYGNvdW50YCBpcyBuZWdhdGl2ZSwgYSBgUmFuZ2VFcnJvcmAgaXMgdGhyb3duLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyByZXBlYXQgfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqIGNvbnN0IHNvdXJjZSA9IG5ldyBVaW50OEFycmF5KFswLCAxLCAyXSk7XG4gKiBjb25zb2xlLmxvZyhyZXBlYXQoc291cmNlLCAzKSk7IC8vIFswLCAxLCAyLCAwLCAxLCAyLCAwLCAxLCAyXVxuICogY29uc29sZS5sb2cocmVwZWF0KHNvdXJjZSwgMCkpOyAvLyBbXVxuICogY29uc29sZS5sb2cocmVwZWF0KHNvdXJjZSwgLTEpKTsgLy8gUmFuZ2VFcnJvclxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBlYXQoc291cmNlOiBVaW50OEFycmF5LCBjb3VudDogbnVtYmVyKTogVWludDhBcnJheSB7XG4gIGlmIChjb3VudCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheSgpO1xuICB9XG5cbiAgaWYgKGNvdW50IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiYnl0ZXM6IG5lZ2F0aXZlIHJlcGVhdCBjb3VudFwiKTtcbiAgfSBlbHNlIGlmICgoc291cmNlLmxlbmd0aCAqIGNvdW50KSAvIGNvdW50ICE9PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYnl0ZXM6IHJlcGVhdCBjb3VudCBjYXVzZXMgb3ZlcmZsb3dcIik7XG4gIH1cblxuICBjb25zdCBpbnQgPSBNYXRoLmZsb29yKGNvdW50KTtcblxuICBpZiAoaW50ICE9PSBjb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImJ5dGVzOiByZXBlYXQgY291bnQgbXVzdCBiZSBhbiBpbnRlZ2VyXCIpO1xuICB9XG5cbiAgY29uc3QgbmIgPSBuZXcgVWludDhBcnJheShzb3VyY2UubGVuZ3RoICogY291bnQpO1xuXG4gIGxldCBicCA9IGNvcHkoc291cmNlLCBuYik7XG5cbiAgZm9yICg7IGJwIDwgbmIubGVuZ3RoOyBicCAqPSAyKSB7XG4gICAgY29weShuYi5zbGljZSgwLCBicCksIG5iLCBicCk7XG4gIH1cblxuICByZXR1cm4gbmI7XG59XG5cbi8qKiBDb25jYXRlbmF0ZSB0aGUgZ2l2ZW4gYXJyYXlzIGludG8gYSBuZXcgVWludDhBcnJheS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgY29uY2F0IH0gZnJvbSBcIi4vbW9kLnRzXCI7XG4gKiBjb25zdCBhID0gbmV3IFVpbnQ4QXJyYXkoWzAsIDEsIDJdKTtcbiAqIGNvbnN0IGIgPSBuZXcgVWludDhBcnJheShbMywgNCwgNV0pO1xuICogY29uc29sZS5sb2coY29uY2F0KGEsIGIpKTsgLy8gWzAsIDEsIDIsIDMsIDQsIDVdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25jYXQoLi4uYnVmOiBVaW50OEFycmF5W10pOiBVaW50OEFycmF5IHtcbiAgbGV0IGxlbmd0aCA9IDA7XG4gIGZvciAoY29uc3QgYiBvZiBidWYpIHtcbiAgICBsZW5ndGggKz0gYi5sZW5ndGg7XG4gIH1cblxuICBjb25zdCBvdXRwdXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICBsZXQgaW5kZXggPSAwO1xuICBmb3IgKGNvbnN0IGIgb2YgYnVmKSB7XG4gICAgb3V0cHV0LnNldChiLCBpbmRleCk7XG4gICAgaW5kZXggKz0gYi5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKiogUmV0dXJucyB0cnVlIGlmIHRoZSBzb3VyY2UgYXJyYXkgY29udGFpbnMgdGhlIG5lZWRsZSBhcnJheSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEEgc3RhcnQgaW5kZXggY2FuIGJlIHNwZWNpZmllZCBhcyB0aGUgdGhpcmQgYXJndW1lbnQgdGhhdCBiZWdpbnMgdGhlIHNlYXJjaFxuICogYXQgdGhhdCBnaXZlbiBpbmRleC4gVGhlIHN0YXJ0IGluZGV4IGRlZmF1bHRzIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFycmF5LlxuICpcbiAqIFRoZSBjb21wbGV4aXR5IG9mIHRoaXMgZnVuY3Rpb24gaXMgTyhzb3VyY2UubGVuZ3RoICogbmVlZGxlLmxlbmd0aCkuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGluY2x1ZGVzTmVlZGxlIH0gZnJvbSBcIi4vbW9kLnRzXCI7XG4gKiBjb25zdCBzb3VyY2UgPSBuZXcgVWludDhBcnJheShbMCwgMSwgMiwgMSwgMiwgMSwgMiwgM10pO1xuICogY29uc3QgbmVlZGxlID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDJdKTtcbiAqIGNvbnNvbGUubG9nKGluY2x1ZGVzTmVlZGxlKHNvdXJjZSwgbmVlZGxlKSk7IC8vIHRydWVcbiAqIGNvbnNvbGUubG9nKGluY2x1ZGVzTmVlZGxlKHNvdXJjZSwgbmVlZGxlLCA2KSk7IC8vIGZhbHNlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluY2x1ZGVzTmVlZGxlKFxuICBzb3VyY2U6IFVpbnQ4QXJyYXksXG4gIG5lZWRsZTogVWludDhBcnJheSxcbiAgc3RhcnQgPSAwLFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiBpbmRleE9mTmVlZGxlKHNvdXJjZSwgbmVlZGxlLCBzdGFydCkgIT09IC0xO1xufVxuXG4vKiogQ29weSBieXRlcyBmcm9tIHRoZSBgc3JjYCBhcnJheSB0byB0aGUgYGRzdGAgYXJyYXkuIFJldHVybnMgdGhlIG51bWJlciBvZlxuICogYnl0ZXMgY29waWVkLlxuICpcbiAqIElmIHRoZSBgc3JjYCBhcnJheSBpcyBsYXJnZXIgdGhhbiB3aGF0IHRoZSBgZHN0YCBhcnJheSBjYW4gaG9sZCwgb25seSB0aGVcbiAqIGFtb3VudCBvZiBieXRlcyB0aGF0IGZpdCBpbiB0aGUgYGRzdGAgYXJyYXkgYXJlIGNvcGllZC5cbiAqXG4gKiBBbiBvZmZzZXQgY2FuIGJlIHNwZWNpZmllZCBhcyB0aGUgdGhpcmQgYXJndW1lbnQgdGhhdCBiZWdpbnMgdGhlIGNvcHkgYXRcbiAqIHRoYXQgZ2l2ZW4gaW5kZXggaW4gdGhlIGBkc3RgIGFycmF5LiBUaGUgb2Zmc2V0IGRlZmF1bHRzIHRvIHRoZSBiZWdpbm5pbmcgb2ZcbiAqIHRoZSBhcnJheS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgY29weSB9IGZyb20gXCIuL21vZC50c1wiO1xuICogY29uc3Qgc3JjID0gbmV3IFVpbnQ4QXJyYXkoWzksIDgsIDddKTtcbiAqIGNvbnN0IGRzdCA9IG5ldyBVaW50OEFycmF5KFswLCAxLCAyLCAzLCA0LCA1XSk7XG4gKiBjb25zb2xlLmxvZyhjb3B5KHNyYywgZHN0KSk7IC8vIDNcbiAqIGNvbnNvbGUubG9nKGRzdCk7IC8vIFs5LCA4LCA3LCAzLCA0LCA1XVxuICogYGBgXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGNvcHkgfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqIGNvbnN0IHNyYyA9IG5ldyBVaW50OEFycmF5KFsxLCAxLCAxLCAxXSk7XG4gKiBjb25zdCBkc3QgPSBuZXcgVWludDhBcnJheShbMCwgMCwgMCwgMF0pO1xuICogY29uc29sZS5sb2coY29weShzcmMsIGRzdCwgMSkpOyAvLyAzXG4gKiBjb25zb2xlLmxvZyhkc3QpOyAvLyBbMCwgMSwgMSwgMV1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY29weShzcmM6IFVpbnQ4QXJyYXksIGRzdDogVWludDhBcnJheSwgb2ZmID0gMCk6IG51bWJlciB7XG4gIG9mZiA9IE1hdGgubWF4KDAsIE1hdGgubWluKG9mZiwgZHN0LmJ5dGVMZW5ndGgpKTtcbiAgY29uc3QgZHN0Qnl0ZXNBdmFpbGFibGUgPSBkc3QuYnl0ZUxlbmd0aCAtIG9mZjtcbiAgaWYgKHNyYy5ieXRlTGVuZ3RoID4gZHN0Qnl0ZXNBdmFpbGFibGUpIHtcbiAgICBzcmMgPSBzcmMuc3ViYXJyYXkoMCwgZHN0Qnl0ZXNBdmFpbGFibGUpO1xuICB9XG4gIGRzdC5zZXQoc3JjLCBvZmYpO1xuICByZXR1cm4gc3JjLmJ5dGVMZW5ndGg7XG59XG5cbmV4cG9ydCB7IGVxdWFscyB9IGZyb20gXCIuL2VxdWFscy50c1wiO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxxQ0FBcUM7QUFFckM7Ozs7O0NBS0MsR0FFRDs7Ozs7Ozs7Ozs7Ozs7O0NBZUMsR0FDRCxPQUFPLFNBQVMsY0FDZCxNQUFrQixFQUNsQixNQUFrQixFQUNsQixRQUFRLENBQUMsRUFDRDtJQUNSLElBQUksU0FBUyxPQUFP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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js b/tests/__snapshots__/transpile/remote/modules/WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js new file mode 100644 index 0000000..3767f70 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js @@ -0,0 +1,47 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +// Alphabet chars. +export const CHAR_UPPERCASE_A = 65; /* A */ +export const CHAR_LOWERCASE_A = 97; /* a */ +export const CHAR_UPPERCASE_Z = 90; /* Z */ +export const CHAR_LOWERCASE_Z = 122; /* z */ +// Non-alphabetic chars. +export const CHAR_DOT = 46; /* . */ +export const CHAR_FORWARD_SLASH = 47; /* / */ +export const CHAR_BACKWARD_SLASH = 92; /* \ */ +export const CHAR_VERTICAL_LINE = 124; /* | */ +export const CHAR_COLON = 58; /* : */ +export const CHAR_QUESTION_MARK = 63; /* ? */ +export const CHAR_UNDERSCORE = 95; /* _ */ +export const CHAR_LINE_FEED = 10; /* \n */ +export const CHAR_CARRIAGE_RETURN = 13; /* \r */ +export const CHAR_TAB = 9; /* \t */ +export const CHAR_FORM_FEED = 12; /* \f */ +export const CHAR_EXCLAMATION_MARK = 33; /* ! */ +export const CHAR_HASH = 35; /* # */ +export const CHAR_SPACE = 32; /* */ +export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */ +export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */ +export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */ +export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */ +export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */ +export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */ +export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */ +export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */ +export const CHAR_HYPHEN_MINUS = 45; /* - */ +export const CHAR_PLUS = 43; /* + */ +export const CHAR_DOUBLE_QUOTE = 34; /* " */ +export const CHAR_SINGLE_QUOTE = 39; /* ' */ +export const CHAR_PERCENT = 37; /* % */ +export const CHAR_SEMICOLON = 59; /* ; */ +export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */ +export const CHAR_GRAVE_ACCENT = 96; /* ` */ +export const CHAR_AT = 64; /* @ */ +export const CHAR_AMPERSAND = 38; /* & */ +export const CHAR_EQUAL = 61; /* = */ +// Digits +export const CHAR_0 = 48; /* 0 */ +export const CHAR_9 = 57; /* 9 */ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvX2NvbnN0YW50cy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gQ29weXJpZ2h0IHRoZSBCcm93c2VyaWZ5IGF1dGhvcnMuIE1JVCBMaWNlbnNlLlxuLy8gUG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Jyb3dzZXJpZnkvcGF0aC1icm93c2VyaWZ5L1xuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vLyBBbHBoYWJldCBjaGFycy5cbmV4cG9ydCBjb25zdCBDSEFSX1VQUEVSQ0FTRV9BID0gNjU7IC8qIEEgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xPV0VSQ0FTRV9BID0gOTc7IC8qIGEgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1VQUEVSQ0FTRV9aID0gOTA7IC8qIFogKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xPV0VSQ0FTRV9aID0gMTIyOyAvKiB6ICovXG5cbi8vIE5vbi1hbHBoYWJldGljIGNoYXJzLlxuZXhwb3J0IGNvbnN0IENIQVJfRE9UID0gNDY7IC8qIC4gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0ZPUldBUkRfU0xBU0ggPSA0NzsgLyogLyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQkFDS1dBUkRfU0xBU0ggPSA5MjsgLyogXFwgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1ZFUlRJQ0FMX0xJTkUgPSAxMjQ7IC8qIHwgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0NPTE9OID0gNTg7IC8qIDogKi9cbmV4cG9ydCBjb25zdCBDSEFSX1FVRVNUSU9OX01BUksgPSA2MzsgLyogPyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfVU5ERVJTQ09SRSA9IDk1OyAvKiBfICovXG5leHBvcnQgY29uc3QgQ0hBUl9MSU5FX0ZFRUQgPSAxMDsgLyogXFxuICovXG5leHBvcnQgY29uc3QgQ0hBUl9DQVJSSUFHRV9SRVRVUk4gPSAxMzsgLyogXFxyICovXG5leHBvcnQgY29uc3QgQ0hBUl9UQUIgPSA5OyAvKiBcXHQgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0ZPUk1fRkVFRCA9IDEyOyAvKiBcXGYgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0VYQ0xBTUFUSU9OX01BUksgPSAzMzsgLyogISAqL1xuZXhwb3J0IGNvbnN0IENIQVJfSEFTSCA9IDM1OyAvKiAjICovXG5leHBvcnQgY29uc3QgQ0hBUl9TUEFDRSA9IDMyOyAvKiAgICovXG5leHBvcnQgY29uc3QgQ0hBUl9OT19CUkVBS19TUEFDRSA9IDE2MDsgLyogXFx1MDBBMCAqL1xuZXhwb3J0IGNvbnN0IENIQVJfWkVST19XSURUSF9OT0JSRUFLX1NQQUNFID0gNjUyNzk7IC8qIFxcdUZFRkYgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xFRlRfU1FVQVJFX0JSQUNLRVQgPSA5MTsgLyogWyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUklHSFRfU1FVQVJFX0JSQUNLRVQgPSA5MzsgLyogXSAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTEVGVF9BTkdMRV9CUkFDS0VUID0gNjA7IC8qIDwgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1JJR0hUX0FOR0xFX0JSQUNLRVQgPSA2MjsgLyogPiAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUID0gMTIzOyAvKiB7ICovXG5leHBvcnQgY29uc3QgQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUID0gMTI1OyAvKiB9ICovXG5leHBvcnQgY29uc3QgQ0hBUl9IWVBIRU5fTUlOVVMgPSA0NTsgLyogLSAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUExVUyA9IDQzOyAvKiArICovXG5leHBvcnQgY29uc3QgQ0hBUl9ET1VCTEVfUVVPVEUgPSAzNDsgLyogXCIgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1NJTkdMRV9RVU9URSA9IDM5OyAvKiAnICovXG5leHBvcnQgY29uc3QgQ0hBUl9QRVJDRU5UID0gMzc7IC8qICUgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1NFTUlDT0xPTiA9IDU5OyAvKiA7ICovXG5leHBvcnQgY29uc3QgQ0hBUl9DSVJDVU1GTEVYX0FDQ0VOVCA9IDk0OyAvKiBeICovXG5leHBvcnQgY29uc3QgQ0hBUl9HUkFWRV9BQ0NFTlQgPSA5NjsgLyogYCAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQVQgPSA2NDsgLyogQCAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQU1QRVJTQU5EID0gMzg7IC8qICYgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0VRVUFMID0gNjE7IC8qID0gKi9cblxuLy8gRGlnaXRzXG5leHBvcnQgY29uc3QgQ0hBUl8wID0gNDg7IC8qIDAgKi9cbmV4cG9ydCBjb25zdCBDSEFSXzkgPSA1NzsgLyogOSAqL1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxpREFBaUQ7QUFDakQsNkRBQTZEO0FBQzdELHFDQUFxQztBQUVyQyxrQkFBa0I7QUFDbEIsT0FBTyxNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBSztBQUN6QyxPQUFPLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxLQUFLO0FBQ3pDLE9BQU8sTUFBTSxtQkFBbUIsR0FBRyxDQUFDLEtBQUs7QUFDekMsT0FBTyxNQUFNLG1CQUFtQixJQUFJLENBQUMsS0FBSztBQUUxQyx3QkFBd0I7QUFDeEIsT0FBTyxNQUFNLFdBQVcsR0FBRyxDQUFDLEtBQUs7QUFDakMsT0FBTyxNQUFNLHFCQUFxQixHQUFHLENBQUMsS0FBSztBQUMzQyxPQUFPLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxLQUFLO0FBQzVDLE9BQU8sTUFBTSxxQkFBcUIsSUFBSSxDQUFDLEtBQUs7QUFDNUMsT0FBTyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUs7QUFDbkMsT0FBTyxNQUFNLHFCQUFxQixHQUFHLENBQUMsS0FBSztBQUMzQyxPQUFPLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxLQUFLO0FBQ3hDLE9BQU8sTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE1BQU07QUFDeEMsT0FBTyxNQUFNLHVCQUF1QixHQUFHLENBQUMsTUFBTTtBQUM5QyxPQUFPLE1BQU0sV0FBVyxFQUFFLENBQUMsTUFBTTtBQUNqQyxPQUFPLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxNQUFNO0FBQ3hDLE9BQU8sTUFBTSx3QkFBd0IsR0FBRyxDQUFDLEtBQUs7QUFDOUMsT0FBTyxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQUs7QUFDbEMsT0FBTyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUs7QUFDbkMsT0FBTyxNQUFNLHNCQUFzQixJQUFJLENBQUMsVUFBVTtBQUNsRCxPQUFPLE1BQU0sZ0NBQWdDLE1BQU0sQ0FBQyxVQUFVO0FBQzlELE9BQU8sTUFBTSwyQkFBMkIsR0FBRyxDQUFDLEtBQUs7QUFDakQsT0FBTyxNQUFNLDRCQUE0QixHQUFHLENBQUMsS0FBSztBQUNsRCxPQUFPLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxLQUFLO0FBQ2hELE9BQU8sTUFBTSwyQkFBMkIsR0FBRyxDQUFDLEtBQUs7QUFDakQsT0FBTyxNQUFNLDBCQUEwQixJQUFJLENBQUMsS0FBSztBQUNqRCxPQUFPLE1BQU0sMkJBQTJCLElBQUksQ0FBQyxLQUFLO0FBQ2xELE9BQU8sTUFBTSxvQkFBb0IsR0FBRyxDQUFDLEtBQUs7QUFDMUMsT0FBTyxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQUs7QUFDbEMsT0FBTyxNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBSztBQUMxQyxPQUFPLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxLQUFLO0FBQzFDLE9BQU8sTUFBTSxlQUFlLEdBQUcsQ0FBQyxLQUFLO0FBQ3JDLE9BQU8sTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEtBQUs7QUFDdkMsT0FBTyxNQUFNLHlCQUF5QixHQUFHLENBQUMsS0FBSztBQUMvQyxPQUFPLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxLQUFLO0FBQzFDLE9BQU8sTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFLO0FBQ2hDLE9BQU8sTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEtBQUs7QUFDdkMsT0FBTyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUs7QUFFbkMsU0FBUztBQUNULE9BQU8sTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUFLO0FBQy9CLE9BQU8sTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUFLIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js b/tests/__snapshots__/transpile/remote/modules/ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js new file mode 100644 index 0000000..0fdef86 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js @@ -0,0 +1,430 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { Buffer } from "../io/buffer.ts"; +const DEFAULT_CHUNK_SIZE = 16_640; +const DEFAULT_BUFFER_SIZE = 32 * 1024; +function isCloser(value) { + return typeof value === "object" && value != null && "close" in value && // deno-lint-ignore no-explicit-any + typeof value["close"] === "function"; +} +/** Create a `Deno.Reader` from an iterable of `Uint8Array`s. + * + * ```ts + * import { readerFromIterable } from "./conversion.ts"; + * + * const file = await Deno.open("metrics.txt", { write: true }); + * const reader = readerFromIterable((async function* () { + * while (true) { + * await new Promise((r) => setTimeout(r, 1000)); + * const message = `data: ${JSON.stringify(Deno.metrics())}\n\n`; + * yield new TextEncoder().encode(message); + * } + * })()); + * await Deno.copy(reader, file); + * ``` + */ export function readerFromIterable(iterable) { + const iterator = iterable[Symbol.asyncIterator]?.() ?? iterable[Symbol.iterator]?.(); + const buffer = new Buffer(); + return { + async read (p) { + if (buffer.length == 0) { + const result = await iterator.next(); + if (result.done) { + return null; + } else { + if (result.value.byteLength <= p.byteLength) { + p.set(result.value); + return result.value.byteLength; + } + p.set(result.value.subarray(0, p.byteLength)); + await writeAll(buffer, result.value.subarray(p.byteLength)); + return p.byteLength; + } + } else { + const n = await buffer.read(p); + if (n == null) { + return this.read(p); + } + return n; + } + } + }; +} +/** Create a `Writer` from a `WritableStreamDefaultWriter`. */ export function writerFromStreamWriter(streamWriter) { + return { + async write (p) { + await streamWriter.ready; + await streamWriter.write(p); + return p.length; + } + }; +} +/** Create a `Reader` from a `ReadableStreamDefaultReader`. */ export function readerFromStreamReader(streamReader) { + const buffer = new Buffer(); + return { + async read (p) { + if (buffer.empty()) { + const res = await streamReader.read(); + if (res.done) { + return null; // EOF + } + await writeAll(buffer, res.value); + } + return buffer.read(p); + } + }; +} +/** Create a `WritableStream` from a `Writer`. */ export function writableStreamFromWriter(writer, options = {}) { + const { autoClose =true } = options; + return new WritableStream({ + async write (chunk, controller) { + try { + await writeAll(writer, chunk); + } catch (e) { + controller.error(e); + if (isCloser(writer) && autoClose) { + writer.close(); + } + } + }, + close () { + if (isCloser(writer) && autoClose) { + writer.close(); + } + }, + abort () { + if (isCloser(writer) && autoClose) { + writer.close(); + } + } + }); +} +/** Create a `ReadableStream` from any kind of iterable. + * + * ```ts + * import { readableStreamFromIterable } from "./conversion.ts"; + * + * const r1 = readableStreamFromIterable(["foo, bar, baz"]); + * const r2 = readableStreamFromIterable(async function* () { + * await new Promise(((r) => setTimeout(r, 1000))); + * yield "foo"; + * await new Promise(((r) => setTimeout(r, 1000))); + * yield "bar"; + * await new Promise(((r) => setTimeout(r, 1000))); + * yield "baz"; + * }()); + * ``` + * + * If the produced iterator (`iterable[Symbol.asyncIterator]()` or + * `iterable[Symbol.iterator]()`) is a generator, or more specifically is found + * to have a `.throw()` method on it, that will be called upon + * `readableStream.cancel()`. This is the case for the second input type above: + * + * ```ts + * import { readableStreamFromIterable } from "./conversion.ts"; + * + * const r3 = readableStreamFromIterable(async function* () { + * try { + * yield "foo"; + * } catch (error) { + * console.log(error); // Error: Cancelled by consumer. + * } + * }()); + * const reader = r3.getReader(); + * console.log(await reader.read()); // { value: "foo", done: false } + * await reader.cancel(new Error("Cancelled by consumer.")); + * ``` + */ export function readableStreamFromIterable(iterable) { + const iterator = iterable[Symbol.asyncIterator]?.() ?? iterable[Symbol.iterator]?.(); + return new ReadableStream({ + async pull (controller) { + const { value , done } = await iterator.next(); + if (done) { + controller.close(); + } else { + controller.enqueue(value); + } + }, + async cancel (reason) { + if (typeof iterator.throw == "function") { + try { + await iterator.throw(reason); + } catch {} + } + } + }); +} +/** + * Create a `ReadableStream` from from a `Deno.Reader`. + * + * When the pull algorithm is called on the stream, a chunk from the reader + * will be read. When `null` is returned from the reader, the stream will be + * closed along with the reader (if it is also a `Deno.Closer`). + * + * An example converting a `Deno.FsFile` into a readable stream: + * + * ```ts + * import { readableStreamFromReader } from "./mod.ts"; + * + * const file = await Deno.open("./file.txt", { read: true }); + * const fileStream = readableStreamFromReader(file); + * ``` + */ export function readableStreamFromReader(reader, options = {}) { + const { autoClose =true , chunkSize =DEFAULT_CHUNK_SIZE , strategy } = options; + return new ReadableStream({ + async pull (controller) { + const chunk = new Uint8Array(chunkSize); + try { + const read = await reader.read(chunk); + if (read === null) { + if (isCloser(reader) && autoClose) { + reader.close(); + } + controller.close(); + return; + } + controller.enqueue(chunk.subarray(0, read)); + } catch (e) { + controller.error(e); + if (isCloser(reader)) { + reader.close(); + } + } + }, + cancel () { + if (isCloser(reader) && autoClose) { + reader.close(); + } + } + }, strategy); +} +/** Read Reader `r` until EOF (`null`) and resolve to the content as + * Uint8Array`. + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { readAll } from "./conversion.ts"; + * + * // Example from stdin + * const stdinContent = await readAll(Deno.stdin); + * + * // Example from file + * const file = await Deno.open("my_file.txt", {read: true}); + * const myFileContent = await readAll(file); + * Deno.close(file.rid); + * + * // Example from buffer + * const myData = new Uint8Array(100); + * // ... fill myData array with data + * const reader = new Buffer(myData.buffer); + * const bufferContent = await readAll(reader); + * ``` + */ export async function readAll(r) { + const buf = new Buffer(); + await buf.readFrom(r); + return buf.bytes(); +} +/** Synchronously reads Reader `r` until EOF (`null`) and returns the content + * as `Uint8Array`. + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { readAllSync } from "./conversion.ts"; + * + * // Example from stdin + * const stdinContent = readAllSync(Deno.stdin); + * + * // Example from file + * const file = Deno.openSync("my_file.txt", {read: true}); + * const myFileContent = readAllSync(file); + * Deno.close(file.rid); + * + * // Example from buffer + * const myData = new Uint8Array(100); + * // ... fill myData array with data + * const reader = new Buffer(myData.buffer); + * const bufferContent = readAllSync(reader); + * ``` + */ export function readAllSync(r) { + const buf = new Buffer(); + buf.readFromSync(r); + return buf.bytes(); +} +/** Write all the content of the array buffer (`arr`) to the writer (`w`). + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { writeAll } from "./conversion.ts"; + + * // Example writing to stdout + * let contentBytes = new TextEncoder().encode("Hello World"); + * await writeAll(Deno.stdout, contentBytes); + * + * // Example writing to file + * contentBytes = new TextEncoder().encode("Hello World"); + * const file = await Deno.open('test.file', {write: true}); + * await writeAll(file, contentBytes); + * Deno.close(file.rid); + * + * // Example writing to buffer + * contentBytes = new TextEncoder().encode("Hello World"); + * const writer = new Buffer(); + * await writeAll(writer, contentBytes); + * console.log(writer.bytes().length); // 11 + * ``` + */ export async function writeAll(w, arr) { + let nwritten = 0; + while(nwritten < arr.length){ + nwritten += await w.write(arr.subarray(nwritten)); + } +} +/** Synchronously write all the content of the array buffer (`arr`) to the + * writer (`w`). + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { writeAllSync } from "./conversion.ts"; + * + * // Example writing to stdout + * let contentBytes = new TextEncoder().encode("Hello World"); + * writeAllSync(Deno.stdout, contentBytes); + * + * // Example writing to file + * contentBytes = new TextEncoder().encode("Hello World"); + * const file = Deno.openSync('test.file', {write: true}); + * writeAllSync(file, contentBytes); + * Deno.close(file.rid); + * + * // Example writing to buffer + * contentBytes = new TextEncoder().encode("Hello World"); + * const writer = new Buffer(); + * writeAllSync(writer, contentBytes); + * console.log(writer.bytes().length); // 11 + * ``` + */ export function writeAllSync(w, arr) { + let nwritten = 0; + while(nwritten < arr.length){ + nwritten += w.writeSync(arr.subarray(nwritten)); + } +} +/** Turns a Reader, `r`, into an async iterator. + * + * ```ts + * import { iterateReader } from "./conversion.ts"; + * + * let f = await Deno.open("/etc/passwd"); + * for await (const chunk of iterateReader(f)) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Second argument can be used to tune size of a buffer. + * Default size of the buffer is 32kB. + * + * ```ts + * import { iterateReader } from "./conversion.ts"; + * + * let f = await Deno.open("/etc/passwd"); + * const it = iterateReader(f, { + * bufSize: 1024 * 1024 + * }); + * for await (const chunk of it) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Iterator uses an internal buffer of fixed size for efficiency; it returns + * a view on that buffer on each iteration. It is therefore caller's + * responsibility to copy contents of the buffer if needed; otherwise the + * next iteration will overwrite contents of previously returned chunk. + */ export async function* iterateReader(r, options) { + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + while(true){ + const result = await r.read(b); + if (result === null) { + break; + } + yield b.subarray(0, result); + } +} +/** Turns a ReaderSync, `r`, into an iterator. + * + * ```ts + * import { iterateReaderSync } from "./conversion.ts"; + * + * let f = Deno.openSync("/etc/passwd"); + * for (const chunk of iterateReaderSync(f)) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Second argument can be used to tune size of a buffer. + * Default size of the buffer is 32kB. + * + * ```ts + * import { iterateReaderSync } from "./conversion.ts"; + + * let f = await Deno.open("/etc/passwd"); + * const iter = iterateReaderSync(f, { + * bufSize: 1024 * 1024 + * }); + * for (const chunk of iter) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Iterator uses an internal buffer of fixed size for efficiency; it returns + * a view on that buffer on each iteration. It is therefore caller's + * responsibility to copy contents of the buffer if needed; otherwise the + * next iteration will overwrite contents of previously returned chunk. + */ export function* iterateReaderSync(r, options) { + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + while(true){ + const result = r.readSync(b); + if (result === null) { + break; + } + yield b.subarray(0, result); + } +} +/** Copies from `src` to `dst` until either EOF (`null`) is read from `src` or + * an error occurs. It resolves to the number of bytes copied or rejects with + * the first error encountered while copying. + * + * ```ts + * import { copy } from "./conversion.ts"; + * + * const source = await Deno.open("my_file.txt"); + * const bytesCopied1 = await copy(source, Deno.stdout); + * const destination = await Deno.create("my_file_2.txt"); + * const bytesCopied2 = await copy(source, destination); + * ``` + * + * @param src The source to copy from + * @param dst The destination to copy to + * @param options Can be used to tune size of the buffer. Default size is 32kB + */ export async function copy(src, dst, options) { + let n = 0; + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + let gotEOF = false; + while(gotEOF === false){ + const result = await src.read(b); + if (result === null) { + gotEOF = true; + } else { + let nwritten = 0; + while(nwritten < result){ + nwritten += await dst.write(b.subarray(nwritten, result)); + } + n += nwritten; + } + } + return n; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3N0cmVhbXMvY29udmVyc2lvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuXG5pbXBvcnQgeyBCdWZmZXIgfSBmcm9tIFwiLi4vaW8vYnVmZmVyLnRzXCI7XG5cbmNvbnN0IERFRkFVTFRfQ0hVTktfU0laRSA9IDE2XzY0MDtcbmNvbnN0IERFRkFVTFRfQlVGRkVSX1NJWkUgPSAzMiAqIDEwMjQ7XG5cbmZ1bmN0aW9uIGlzQ2xvc2VyKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgRGVuby5DbG9zZXIge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9IG51bGwgJiYgXCJjbG9zZVwiIGluIHZhbHVlICYmXG4gICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICB0eXBlb2YgKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW1wiY2xvc2VcIl0gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqIENyZWF0ZSBhIGBEZW5vLlJlYWRlcmAgZnJvbSBhbiBpdGVyYWJsZSBvZiBgVWludDhBcnJheWBzLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IHJlYWRlckZyb21JdGVyYWJsZSB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oXCJtZXRyaWNzLnR4dFwiLCB7IHdyaXRlOiB0cnVlIH0pO1xuICogICAgICBjb25zdCByZWFkZXIgPSByZWFkZXJGcm9tSXRlcmFibGUoKGFzeW5jIGZ1bmN0aW9uKiAoKSB7XG4gKiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAqICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEwMDApKTtcbiAqICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBgZGF0YTogJHtKU09OLnN0cmluZ2lmeShEZW5vLm1ldHJpY3MoKSl9XFxuXFxuYDtcbiAqICAgICAgICAgIHlpZWxkIG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShtZXNzYWdlKTtcbiAqICAgICAgICB9XG4gKiAgICAgIH0pKCkpO1xuICogICAgICBhd2FpdCBEZW5vLmNvcHkocmVhZGVyLCBmaWxlKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZGVyRnJvbUl0ZXJhYmxlKFxuICBpdGVyYWJsZTogSXRlcmFibGU8VWludDhBcnJheT4gfCBBc3luY0l0ZXJhYmxlPFVpbnQ4QXJyYXk+LFxuKTogRGVuby5SZWFkZXIge1xuICBjb25zdCBpdGVyYXRvcjogSXRlcmF0b3I8VWludDhBcnJheT4gfCBBc3luY0l0ZXJhdG9yPFVpbnQ4QXJyYXk+ID1cbiAgICAoaXRlcmFibGUgYXMgQXN5bmNJdGVyYWJsZTxVaW50OEFycmF5PilbU3ltYm9sLmFzeW5jSXRlcmF0b3JdPy4oKSA/P1xuICAgICAgKGl0ZXJhYmxlIGFzIEl0ZXJhYmxlPFVpbnQ4QXJyYXk+KVtTeW1ib2wuaXRlcmF0b3JdPy4oKTtcbiAgY29uc3QgYnVmZmVyID0gbmV3IEJ1ZmZlcigpO1xuICByZXR1cm4ge1xuICAgIGFzeW5jIHJlYWQocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPT0gMCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIGlmIChyZXN1bHQuZG9uZSkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChyZXN1bHQudmFsdWUuYnl0ZUxlbmd0aCA8PSBwLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgIHAuc2V0KHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LnZhbHVlLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgfVxuICAgICAgICAgIHAuc2V0KHJlc3VsdC52YWx1ZS5zdWJhcnJheSgwLCBwLmJ5dGVMZW5ndGgpKTtcbiAgICAgICAgICBhd2FpdCB3cml0ZUFsbChidWZmZXIsIHJlc3VsdC52YWx1ZS5zdWJhcnJheShwLmJ5dGVMZW5ndGgpKTtcbiAgICAgICAgICByZXR1cm4gcC5ieXRlTGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuID0gYXdhaXQgYnVmZmVyLnJlYWQocCk7XG4gICAgICAgIGlmIChuID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWFkKHApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbi8qKiBDcmVhdGUgYSBgV3JpdGVyYCBmcm9tIGEgYFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcmAuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVyRnJvbVN0cmVhbVdyaXRlcihcbiAgc3RyZWFtV3JpdGVyOiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXI8VWludDhBcnJheT4sXG4pOiBEZW5vLldyaXRlciB7XG4gIHJldHVybiB7XG4gICAgYXN5bmMgd3JpdGUocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICBhd2FpdCBzdHJlYW1Xcml0ZXIucmVhZHk7XG4gICAgICBhd2FpdCBzdHJlYW1Xcml0ZXIud3JpdGUocCk7XG4gICAgICByZXR1cm4gcC5sZW5ndGg7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIENyZWF0ZSBhIGBSZWFkZXJgIGZyb20gYSBgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkZXJGcm9tU3RyZWFtUmVhZGVyKFxuICBzdHJlYW1SZWFkZXI6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjxVaW50OEFycmF5Pixcbik6IERlbm8uUmVhZGVyIHtcbiAgY29uc3QgYnVmZmVyID0gbmV3IEJ1ZmZlcigpO1xuXG4gIHJldHVybiB7XG4gICAgYXN5bmMgcmVhZChwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gICAgICBpZiAoYnVmZmVyLmVtcHR5KCkpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgc3RyZWFtUmVhZGVyLnJlYWQoKTtcbiAgICAgICAgaWYgKHJlcy5kb25lKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7IC8vIEVPRlxuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgd3JpdGVBbGwoYnVmZmVyLCByZXMudmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmZmVyLnJlYWQocCk7XG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXcml0YWJsZVN0cmVhbUZyb21Xcml0ZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIElmIHRoZSBgd3JpdGVyYCBpcyBhbHNvIGEgYERlbm8uQ2xvc2VyYCwgYXV0b21hdGljYWxseSBjbG9zZSB0aGUgYHdyaXRlcmBcbiAgICogd2hlbiB0aGUgc3RyZWFtIGlzIGNsb3NlZCwgYWJvcnRlZCwgb3IgYSB3cml0ZSBlcnJvciBvY2N1cnMuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIGB0cnVlYC4gKi9cbiAgYXV0b0Nsb3NlPzogYm9vbGVhbjtcbn1cblxuLyoqIENyZWF0ZSBhIGBXcml0YWJsZVN0cmVhbWAgZnJvbSBhIGBXcml0ZXJgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRhYmxlU3RyZWFtRnJvbVdyaXRlcihcbiAgd3JpdGVyOiBEZW5vLldyaXRlcixcbiAgb3B0aW9uczogV3JpdGFibGVTdHJlYW1Gcm9tV3JpdGVyT3B0aW9ucyA9IHt9LFxuKTogV3JpdGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICBjb25zdCB7IGF1dG9DbG9zZSA9IHRydWUgfSA9IG9wdGlvbnM7XG5cbiAgcmV0dXJuIG5ldyBXcml0YWJsZVN0cmVhbSh7XG4gICAgYXN5bmMgd3JpdGUoY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdyaXRlQWxsKHdyaXRlciwgY2h1bmspO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKGUpO1xuICAgICAgICBpZiAoaXNDbG9zZXIod3JpdGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgICB3cml0ZXIuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgY2xvc2UoKSB7XG4gICAgICBpZiAoaXNDbG9zZXIod3JpdGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgd3JpdGVyLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBhYm9ydCgpIHtcbiAgICAgIGlmIChpc0Nsb3Nlcih3cml0ZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICB3cml0ZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIENyZWF0ZSBhIGBSZWFkYWJsZVN0cmVhbWAgZnJvbSBhbnkga2luZCBvZiBpdGVyYWJsZS5cbiAqXG4gKiBgYGB0c1xuICogICAgICBpbXBvcnQgeyByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZSB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiAgICAgIGNvbnN0IHIxID0gcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGUoW1wiZm9vLCBiYXIsIGJhelwiXSk7XG4gKiAgICAgIGNvbnN0IHIyID0gcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGUoYXN5bmMgZnVuY3Rpb24qICgpIHtcbiAqICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpKTtcbiAqICAgICAgICB5aWVsZCBcImZvb1wiO1xuICogICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKCgocikgPT4gc2V0VGltZW91dChyLCAxMDAwKSkpO1xuICogICAgICAgIHlpZWxkIFwiYmFyXCI7XG4gKiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEwMDApKSk7XG4gKiAgICAgICAgeWllbGQgXCJiYXpcIjtcbiAqICAgICAgfSgpKTtcbiAqIGBgYFxuICpcbiAqIElmIHRoZSBwcm9kdWNlZCBpdGVyYXRvciAoYGl0ZXJhYmxlW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSgpYCBvclxuICogYGl0ZXJhYmxlW1N5bWJvbC5pdGVyYXRvcl0oKWApIGlzIGEgZ2VuZXJhdG9yLCBvciBtb3JlIHNwZWNpZmljYWxseSBpcyBmb3VuZFxuICogdG8gaGF2ZSBhIGAudGhyb3coKWAgbWV0aG9kIG9uIGl0LCB0aGF0IHdpbGwgYmUgY2FsbGVkIHVwb25cbiAqIGByZWFkYWJsZVN0cmVhbS5jYW5jZWwoKWAuIFRoaXMgaXMgdGhlIGNhc2UgZm9yIHRoZSBzZWNvbmQgaW5wdXQgdHlwZSBhYm92ZTpcbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGUgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogY29uc3QgcjMgPSByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZShhc3luYyBmdW5jdGlvbiogKCkge1xuICogICB0cnkge1xuICogICAgIHlpZWxkIFwiZm9vXCI7XG4gKiAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyb3IpOyAvLyBFcnJvcjogQ2FuY2VsbGVkIGJ5IGNvbnN1bWVyLlxuICogICB9XG4gKiB9KCkpO1xuICogY29uc3QgcmVhZGVyID0gcjMuZ2V0UmVhZGVyKCk7XG4gKiBjb25zb2xlLmxvZyhhd2FpdCByZWFkZXIucmVhZCgpKTsgLy8geyB2YWx1ZTogXCJmb29cIiwgZG9uZTogZmFsc2UgfVxuICogYXdhaXQgcmVhZGVyLmNhbmNlbChuZXcgRXJyb3IoXCJDYW5jZWxsZWQgYnkgY29uc3VtZXIuXCIpKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGU8VD4oXG4gIGl0ZXJhYmxlOiBJdGVyYWJsZTxUPiB8IEFzeW5jSXRlcmFibGU8VD4sXG4pOiBSZWFkYWJsZVN0cmVhbTxUPiB7XG4gIGNvbnN0IGl0ZXJhdG9yOiBJdGVyYXRvcjxUPiB8IEFzeW5jSXRlcmF0b3I8VD4gPVxuICAgIChpdGVyYWJsZSBhcyBBc3luY0l0ZXJhYmxlPFQ+KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0/LigpID8/XG4gICAgICAoaXRlcmFibGUgYXMgSXRlcmFibGU8VD4pW1N5bWJvbC5pdGVyYXRvcl0/LigpO1xuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtKHtcbiAgICBhc3luYyBwdWxsKGNvbnRyb2xsZXIpIHtcbiAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgIGlmIChkb25lKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBhc3luYyBjYW5jZWwocmVhc29uKSB7XG4gICAgICBpZiAodHlwZW9mIGl0ZXJhdG9yLnRocm93ID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGl0ZXJhdG9yLnRocm93KHJlYXNvbik7XG4gICAgICAgIH0gY2F0Y2ggeyAvKiBgaXRlcmF0b3IudGhyb3coKWAgYWx3YXlzIHRocm93cyBvbiBzaXRlLiBXZSBjYXRjaCBpdC4gKi8gfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlck9wdGlvbnMge1xuICAvKiogSWYgdGhlIGByZWFkZXJgIGlzIGFsc28gYSBgRGVuby5DbG9zZXJgLCBhdXRvbWF0aWNhbGx5IGNsb3NlIHRoZSBgcmVhZGVyYFxuICAgKiB3aGVuIGBFT0ZgIGlzIGVuY291bnRlcmVkLCBvciBhIHJlYWQgZXJyb3Igb2NjdXJzLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBgdHJ1ZWAuICovXG4gIGF1dG9DbG9zZT86IGJvb2xlYW47XG5cbiAgLyoqIFRoZSBzaXplIG9mIGNodW5rcyB0byBhbGxvY2F0ZSB0byByZWFkLCB0aGUgZGVmYXVsdCBpcyB+MTZLaUIsIHdoaWNoIGlzXG4gICAqIHRoZSBtYXhpbXVtIHNpemUgdGhhdCBEZW5vIG9wZXJhdGlvbnMgY2FuIGN1cnJlbnRseSBzdXBwb3J0LiAqL1xuICBjaHVua1NpemU/OiBudW1iZXI7XG5cbiAgLyoqIFRoZSBxdWV1aW5nIHN0cmF0ZWd5IHRvIGNyZWF0ZSB0aGUgYFJlYWRhYmxlU3RyZWFtYCB3aXRoLiAqL1xuICBzdHJhdGVneT86IHsgaGlnaFdhdGVyTWFyaz86IG51bWJlciB8IHVuZGVmaW5lZDsgc2l6ZT86IHVuZGVmaW5lZCB9O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PmAgZnJvbSBmcm9tIGEgYERlbm8uUmVhZGVyYC5cbiAqXG4gKiBXaGVuIHRoZSBwdWxsIGFsZ29yaXRobSBpcyBjYWxsZWQgb24gdGhlIHN0cmVhbSwgYSBjaHVuayBmcm9tIHRoZSByZWFkZXJcbiAqIHdpbGwgYmUgcmVhZC4gIFdoZW4gYG51bGxgIGlzIHJldHVybmVkIGZyb20gdGhlIHJlYWRlciwgdGhlIHN0cmVhbSB3aWxsIGJlXG4gKiBjbG9zZWQgYWxvbmcgd2l0aCB0aGUgcmVhZGVyIChpZiBpdCBpcyBhbHNvIGEgYERlbm8uQ2xvc2VyYCkuXG4gKlxuICogQW4gZXhhbXBsZSBjb252ZXJ0aW5nIGEgYERlbm8uRnNGaWxlYCBpbnRvIGEgcmVhZGFibGUgc3RyZWFtOlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyByZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIgfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqXG4gKiBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKFwiLi9maWxlLnR4dFwiLCB7IHJlYWQ6IHRydWUgfSk7XG4gKiBjb25zdCBmaWxlU3RyZWFtID0gcmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyKGZpbGUpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIoXG4gIHJlYWRlcjogRGVuby5SZWFkZXIgfCAoRGVuby5SZWFkZXIgJiBEZW5vLkNsb3NlciksXG4gIG9wdGlvbnM6IFJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlck9wdGlvbnMgPSB7fSxcbik6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3Qge1xuICAgIGF1dG9DbG9zZSA9IHRydWUsXG4gICAgY2h1bmtTaXplID0gREVGQVVMVF9DSFVOS19TSVpFLFxuICAgIHN0cmF0ZWd5LFxuICB9ID0gb3B0aW9ucztcblxuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtKHtcbiAgICBhc3luYyBwdWxsKGNvbnRyb2xsZXIpIHtcbiAgICAgIGNvbnN0IGNodW5rID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmtTaXplKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlYWQgPSBhd2FpdCByZWFkZXIucmVhZChjaHVuayk7XG4gICAgICAgIGlmIChyZWFkID09PSBudWxsKSB7XG4gICAgICAgICAgaWYgKGlzQ2xvc2VyKHJlYWRlcikgJiYgYXV0b0Nsb3NlKSB7XG4gICAgICAgICAgICByZWFkZXIuY2xvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmsuc3ViYXJyYXkoMCwgcmVhZCkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKGUpO1xuICAgICAgICBpZiAoaXNDbG9zZXIocmVhZGVyKSkge1xuICAgICAgICAgIHJlYWRlci5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBjYW5jZWwoKSB7XG4gICAgICBpZiAoaXNDbG9zZXIocmVhZGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgcmVhZGVyLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSxcbiAgfSwgc3RyYXRlZ3kpO1xufVxuXG4vKiogUmVhZCBSZWFkZXIgYHJgIHVudGlsIEVPRiAoYG51bGxgKSBhbmQgcmVzb2x2ZSB0byB0aGUgY29udGVudCBhc1xuICogVWludDhBcnJheWAuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCIuLi9pby9idWZmZXIudHNcIjtcbiAqIGltcG9ydCB7IHJlYWRBbGwgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIHN0ZGluXG4gKiBjb25zdCBzdGRpbkNvbnRlbnQgPSBhd2FpdCByZWFkQWxsKERlbm8uc3RkaW4pO1xuICpcbiAqIC8vIEV4YW1wbGUgZnJvbSBmaWxlXG4gKiBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKFwibXlfZmlsZS50eHRcIiwge3JlYWQ6IHRydWV9KTtcbiAqIGNvbnN0IG15RmlsZUNvbnRlbnQgPSBhd2FpdCByZWFkQWxsKGZpbGUpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGJ1ZmZlclxuICogY29uc3QgbXlEYXRhID0gbmV3IFVpbnQ4QXJyYXkoMTAwKTtcbiAqIC8vIC4uLiBmaWxsIG15RGF0YSBhcnJheSB3aXRoIGRhdGFcbiAqIGNvbnN0IHJlYWRlciA9IG5ldyBCdWZmZXIobXlEYXRhLmJ1ZmZlcik7XG4gKiBjb25zdCBidWZmZXJDb250ZW50ID0gYXdhaXQgcmVhZEFsbChyZWFkZXIpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkQWxsKHI6IERlbm8uUmVhZGVyKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGJ1ZiA9IG5ldyBCdWZmZXIoKTtcbiAgYXdhaXQgYnVmLnJlYWRGcm9tKHIpO1xuICByZXR1cm4gYnVmLmJ5dGVzKCk7XG59XG5cbi8qKiBTeW5jaHJvbm91c2x5IHJlYWRzIFJlYWRlciBgcmAgdW50aWwgRU9GIChgbnVsbGApIGFuZCByZXR1cm5zIHRoZSBjb250ZW50XG4gKiBhcyBgVWludDhBcnJheWAuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCIuLi9pby9idWZmZXIudHNcIjtcbiAqIGltcG9ydCB7IHJlYWRBbGxTeW5jIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIC8vIEV4YW1wbGUgZnJvbSBzdGRpblxuICogY29uc3Qgc3RkaW5Db250ZW50ID0gcmVhZEFsbFN5bmMoRGVuby5zdGRpbik7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGZpbGVcbiAqIGNvbnN0IGZpbGUgPSBEZW5vLm9wZW5TeW5jKFwibXlfZmlsZS50eHRcIiwge3JlYWQ6IHRydWV9KTtcbiAqIGNvbnN0IG15RmlsZUNvbnRlbnQgPSByZWFkQWxsU3luYyhmaWxlKTtcbiAqIERlbm8uY2xvc2UoZmlsZS5yaWQpO1xuICpcbiAqIC8vIEV4YW1wbGUgZnJvbSBidWZmZXJcbiAqIGNvbnN0IG15RGF0YSA9IG5ldyBVaW50OEFycmF5KDEwMCk7XG4gKiAvLyAuLi4gZmlsbCBteURhdGEgYXJyYXkgd2l0aCBkYXRhXG4gKiBjb25zdCByZWFkZXIgPSBuZXcgQnVmZmVyKG15RGF0YS5idWZmZXIpO1xuICogY29uc3QgYnVmZmVyQ29udGVudCA9IHJlYWRBbGxTeW5jKHJlYWRlcik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRBbGxTeW5jKHI6IERlbm8uUmVhZGVyU3luYyk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBidWYgPSBuZXcgQnVmZmVyKCk7XG4gIGJ1Zi5yZWFkRnJvbVN5bmMocik7XG4gIHJldHVybiBidWYuYnl0ZXMoKTtcbn1cblxuLyoqIFdyaXRlIGFsbCB0aGUgY29udGVudCBvZiB0aGUgYXJyYXkgYnVmZmVyIChgYXJyYCkgdG8gdGhlIHdyaXRlciAoYHdgKS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgd3JpdGVBbGwgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG5cbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBzdGRvdXRcbiAqIGxldCBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIGF3YWl0IHdyaXRlQWxsKERlbm8uc3Rkb3V0LCBjb250ZW50Qnl0ZXMpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBmaWxlXG4gKiBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oJ3Rlc3QuZmlsZScsIHt3cml0ZTogdHJ1ZX0pO1xuICogYXdhaXQgd3JpdGVBbGwoZmlsZSwgY29udGVudEJ5dGVzKTtcbiAqIERlbm8uY2xvc2UoZmlsZS5yaWQpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBidWZmZXJcbiAqIGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogY29uc3Qgd3JpdGVyID0gbmV3IEJ1ZmZlcigpO1xuICogYXdhaXQgd3JpdGVBbGwod3JpdGVyLCBjb250ZW50Qnl0ZXMpO1xuICogY29uc29sZS5sb2cod3JpdGVyLmJ5dGVzKCkubGVuZ3RoKTsgIC8vIDExXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlQWxsKHc6IERlbm8uV3JpdGVyLCBhcnI6IFVpbnQ4QXJyYXkpIHtcbiAgbGV0IG53cml0dGVuID0gMDtcbiAgd2hpbGUgKG53cml0dGVuIDwgYXJyLmxlbmd0aCkge1xuICAgIG53cml0dGVuICs9IGF3YWl0IHcud3JpdGUoYXJyLnN1YmFycmF5KG53cml0dGVuKSk7XG4gIH1cbn1cblxuLyoqIFN5bmNocm9ub3VzbHkgd3JpdGUgYWxsIHRoZSBjb250ZW50IG9mIHRoZSBhcnJheSBidWZmZXIgKGBhcnJgKSB0byB0aGVcbiAqIHdyaXRlciAoYHdgKS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgd3JpdGVBbGxTeW5jIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBzdGRvdXRcbiAqIGxldCBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIHdyaXRlQWxsU3luYyhEZW5vLnN0ZG91dCwgY29udGVudEJ5dGVzKTtcbiAqXG4gKiAvLyBFeGFtcGxlIHdyaXRpbmcgdG8gZmlsZVxuICogY29udGVudEJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFwiSGVsbG8gV29ybGRcIik7XG4gKiBjb25zdCBmaWxlID0gRGVuby5vcGVuU3luYygndGVzdC5maWxlJywge3dyaXRlOiB0cnVlfSk7XG4gKiB3cml0ZUFsbFN5bmMoZmlsZSwgY29udGVudEJ5dGVzKTtcbiAqIERlbm8uY2xvc2UoZmlsZS5yaWQpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBidWZmZXJcbiAqIGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogY29uc3Qgd3JpdGVyID0gbmV3IEJ1ZmZlcigpO1xuICogd3JpdGVBbGxTeW5jKHdyaXRlciwgY29udGVudEJ5dGVzKTtcbiAqIGNvbnNvbGUubG9nKHdyaXRlci5ieXRlcygpLmxlbmd0aCk7ICAvLyAxMVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZUFsbFN5bmModzogRGVuby5Xcml0ZXJTeW5jLCBhcnI6IFVpbnQ4QXJyYXkpOiB2b2lkIHtcbiAgbGV0IG53cml0dGVuID0gMDtcbiAgd2hpbGUgKG53cml0dGVuIDwgYXJyLmxlbmd0aCkge1xuICAgIG53cml0dGVuICs9IHcud3JpdGVTeW5jKGFyci5zdWJhcnJheShud3JpdHRlbikpO1xuICB9XG59XG5cbi8qKiBUdXJucyBhIFJlYWRlciwgYHJgLCBpbnRvIGFuIGFzeW5jIGl0ZXJhdG9yLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpdGVyYXRlUmVhZGVyIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIGxldCBmID0gYXdhaXQgRGVuby5vcGVuKFwiL2V0Yy9wYXNzd2RcIik7XG4gKiBmb3IgYXdhaXQgKGNvbnN0IGNodW5rIG9mIGl0ZXJhdGVSZWFkZXIoZikpIHtcbiAqICAgY29uc29sZS5sb2coY2h1bmspO1xuICogfVxuICogZi5jbG9zZSgpO1xuICogYGBgXG4gKlxuICogU2Vjb25kIGFyZ3VtZW50IGNhbiBiZSB1c2VkIHRvIHR1bmUgc2l6ZSBvZiBhIGJ1ZmZlci5cbiAqIERlZmF1bHQgc2l6ZSBvZiB0aGUgYnVmZmVyIGlzIDMya0IuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGl0ZXJhdGVSZWFkZXIgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogbGV0IGYgPSBhd2FpdCBEZW5vLm9wZW4oXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGNvbnN0IGl0ID0gaXRlcmF0ZVJlYWRlcihmLCB7XG4gKiAgIGJ1ZlNpemU6IDEwMjQgKiAxMDI0XG4gKiB9KTtcbiAqIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgaXQpIHtcbiAqICAgY29uc29sZS5sb2coY2h1bmspO1xuICogfVxuICogZi5jbG9zZSgpO1xuICogYGBgXG4gKlxuICogSXRlcmF0b3IgdXNlcyBhbiBpbnRlcm5hbCBidWZmZXIgb2YgZml4ZWQgc2l6ZSBmb3IgZWZmaWNpZW5jeTsgaXQgcmV0dXJuc1xuICogYSB2aWV3IG9uIHRoYXQgYnVmZmVyIG9uIGVhY2ggaXRlcmF0aW9uLiBJdCBpcyB0aGVyZWZvcmUgY2FsbGVyJ3NcbiAqIHJlc3BvbnNpYmlsaXR5IHRvIGNvcHkgY29udGVudHMgb2YgdGhlIGJ1ZmZlciBpZiBuZWVkZWQ7IG90aGVyd2lzZSB0aGVcbiAqIG5leHQgaXRlcmF0aW9uIHdpbGwgb3ZlcndyaXRlIGNvbnRlbnRzIG9mIHByZXZpb3VzbHkgcmV0dXJuZWQgY2h1bmsuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogaXRlcmF0ZVJlYWRlcihcbiAgcjogRGVuby5SZWFkZXIsXG4gIG9wdGlvbnM/OiB7XG4gICAgYnVmU2l6ZT86IG51bWJlcjtcbiAgfSxcbik6IEFzeW5jSXRlcmFibGVJdGVyYXRvcjxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGJ1ZlNpemUgPSBvcHRpb25zPy5idWZTaXplID8/IERFRkFVTFRfQlVGRkVSX1NJWkU7XG4gIGNvbnN0IGIgPSBuZXcgVWludDhBcnJheShidWZTaXplKTtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByLnJlYWQoYik7XG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgeWllbGQgYi5zdWJhcnJheSgwLCByZXN1bHQpO1xuICB9XG59XG5cbi8qKiBUdXJucyBhIFJlYWRlclN5bmMsIGByYCwgaW50byBhbiBpdGVyYXRvci5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgaXRlcmF0ZVJlYWRlclN5bmMgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogbGV0IGYgPSBEZW5vLm9wZW5TeW5jKFwiL2V0Yy9wYXNzd2RcIik7XG4gKiBmb3IgKGNvbnN0IGNodW5rIG9mIGl0ZXJhdGVSZWFkZXJTeW5jKGYpKSB7XG4gKiAgIGNvbnNvbGUubG9nKGNodW5rKTtcbiAqIH1cbiAqIGYuY2xvc2UoKTtcbiAqIGBgYFxuICpcbiAqIFNlY29uZCBhcmd1bWVudCBjYW4gYmUgdXNlZCB0byB0dW5lIHNpemUgb2YgYSBidWZmZXIuXG4gKiBEZWZhdWx0IHNpemUgb2YgdGhlIGJ1ZmZlciBpcyAzMmtCLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpdGVyYXRlUmVhZGVyU3luYyB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcblxuICogbGV0IGYgPSBhd2FpdCBEZW5vLm9wZW4oXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGNvbnN0IGl0ZXIgPSBpdGVyYXRlUmVhZGVyU3luYyhmLCB7XG4gKiAgIGJ1ZlNpemU6IDEwMjQgKiAxMDI0XG4gKiB9KTtcbiAqIGZvciAoY29uc3QgY2h1bmsgb2YgaXRlcikge1xuICogICBjb25zb2xlLmxvZyhjaHVuayk7XG4gKiB9XG4gKiBmLmNsb3NlKCk7XG4gKiBgYGBcbiAqXG4gKiBJdGVyYXRvciB1c2VzIGFuIGludGVybmFsIGJ1ZmZlciBvZiBmaXhlZCBzaXplIGZvciBlZmZpY2llbmN5OyBpdCByZXR1cm5zXG4gKiBhIHZpZXcgb24gdGhhdCBidWZmZXIgb24gZWFjaCBpdGVyYXRpb24uIEl0IGlzIHRoZXJlZm9yZSBjYWxsZXInc1xuICogcmVzcG9uc2liaWxpdHkgdG8gY29weSBjb250ZW50cyBvZiB0aGUgYnVmZmVyIGlmIG5lZWRlZDsgb3RoZXJ3aXNlIHRoZVxuICogbmV4dCBpdGVyYXRpb24gd2lsbCBvdmVyd3JpdGUgY29udGVudHMgb2YgcHJldmlvdXNseSByZXR1cm5lZCBjaHVuay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uKiBpdGVyYXRlUmVhZGVyU3luYyhcbiAgcjogRGVuby5SZWFkZXJTeW5jLFxuICBvcHRpb25zPzoge1xuICAgIGJ1ZlNpemU/OiBudW1iZXI7XG4gIH0sXG4pOiBJdGVyYWJsZUl0ZXJhdG9yPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgYnVmU2l6ZSA9IG9wdGlvbnM/LmJ1ZlNpemUgPz8gREVGQVVMVF9CVUZGRVJfU0laRTtcbiAgY29uc3QgYiA9IG5ldyBVaW50OEFycmF5KGJ1ZlNpemUpO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IHIucmVhZFN5bmMoYik7XG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgeWllbGQgYi5zdWJhcnJheSgwLCByZXN1bHQpO1xuICB9XG59XG5cbi8qKiBDb3BpZXMgZnJvbSBgc3JjYCB0byBgZHN0YCB1bnRpbCBlaXRoZXIgRU9GIChgbnVsbGApIGlzIHJlYWQgZnJvbSBgc3JjYCBvclxuICogYW4gZXJyb3Igb2NjdXJzLiBJdCByZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIGNvcGllZCBvciByZWplY3RzIHdpdGhcbiAqIHRoZSBmaXJzdCBlcnJvciBlbmNvdW50ZXJlZCB3aGlsZSBjb3B5aW5nLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBjb3B5IH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIGNvbnN0IHNvdXJjZSA9IGF3YWl0IERlbm8ub3BlbihcIm15X2ZpbGUudHh0XCIpO1xuICogY29uc3QgYnl0ZXNDb3BpZWQxID0gYXdhaXQgY29weShzb3VyY2UsIERlbm8uc3Rkb3V0KTtcbiAqIGNvbnN0IGRlc3RpbmF0aW9uID0gYXdhaXQgRGVuby5jcmVhdGUoXCJteV9maWxlXzIudHh0XCIpO1xuICogY29uc3QgYnl0ZXNDb3BpZWQyID0gYXdhaXQgY29weShzb3VyY2UsIGRlc3RpbmF0aW9uKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBzcmMgVGhlIHNvdXJjZSB0byBjb3B5IGZyb21cbiAqIEBwYXJhbSBkc3QgVGhlIGRlc3RpbmF0aW9uIHRvIGNvcHkgdG9cbiAqIEBwYXJhbSBvcHRpb25zIENhbiBiZSB1c2VkIHRvIHR1bmUgc2l6ZSBvZiB0aGUgYnVmZmVyLiBEZWZhdWx0IHNpemUgaXMgMzJrQlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29weShcbiAgc3JjOiBEZW5vLlJlYWRlcixcbiAgZHN0OiBEZW5vLldyaXRlcixcbiAgb3B0aW9ucz86IHtcbiAgICBidWZTaXplPzogbnVtYmVyO1xuICB9LFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgbGV0IG4gPSAwO1xuICBjb25zdCBidWZTaXplID0gb3B0aW9ucz8uYnVmU2l6ZSA/PyBERUZBVUxUX0JVRkZFUl9TSVpFO1xuICBjb25zdCBiID0gbmV3IFVpbnQ4QXJyYXkoYnVmU2l6ZSk7XG4gIGxldCBnb3RFT0YgPSBmYWxzZTtcbiAgd2hpbGUgKGdvdEVPRiA9PT0gZmFsc2UpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzcmMucmVhZChiKTtcbiAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICBnb3RFT0YgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbndyaXR0ZW4gPSAwO1xuICAgICAgd2hpbGUgKG53cml0dGVuIDwgcmVzdWx0KSB7XG4gICAgICAgIG53cml0dGVuICs9IGF3YWl0IGRzdC53cml0ZShiLnN1YmFycmF5KG53cml0dGVuLCByZXN1bHQpKTtcbiAgICAgIH1cbiAgICAgIG4gKz0gbndyaXR0ZW47XG4gICAgfVxuICB9XG4gIHJldHVybiBuO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUUxRSxTQUFTLE1BQU0sUUFBUSxrQkFBa0I7QUFFekMsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSxzQkFBc0IsS0FBSztBQUVqQyxTQUFTLFNBQVMsS0FBYyxFQUF3QjtJQUN0RCxPQUFPLE9BQU8sVUFBVSxZQUFZLFNBQVMsSUFBSSxJQUFJLFdBQVcsU0FDOUQsbUNBQW1DO0lBQ25DLE9BQU8sQUFBQyxLQUE2QixDQUFDLFFBQVEsS0FBSztBQUN2RDtBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Q0FlQyxHQUNELE9BQU8sU0FBUyxtQkFDZCxRQUEwRCxFQUM3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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/ebsv4XtKEF8sxrDsnkLX8K9VdOA.js b/tests/__snapshots__/transpile/remote/modules/ebsv4XtKEF8sxrDsnkLX8K9VdOA.js new file mode 100644 index 0000000..30e11f0 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/ebsv4XtKEF8sxrDsnkLX8K9VdOA.js @@ -0,0 +1,18 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +export const osType = (()=>{ + // deno-lint-ignore no-explicit-any + const { Deno } = globalThis; + if (typeof Deno?.build?.os === "string") { + return Deno.build.os; + } + // deno-lint-ignore no-explicit-any + const { navigator } = globalThis; + if (navigator?.appVersion?.includes?.("Win")) { + return "windows"; + } + return "linux"; +})(); +export const isWindows = osType === "windows"; +export const isLinux = osType === "linux"; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL29zLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmV4cG9ydCB0eXBlIE9TVHlwZSA9IFwid2luZG93c1wiIHwgXCJsaW51eFwiIHwgXCJkYXJ3aW5cIjtcblxuZXhwb3J0IGNvbnN0IG9zVHlwZTogT1NUeXBlID0gKCgpID0+IHtcbiAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgY29uc3QgeyBEZW5vIH0gPSBnbG9iYWxUaGlzIGFzIGFueTtcbiAgaWYgKHR5cGVvZiBEZW5vPy5idWlsZD8ub3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gRGVuby5idWlsZC5vcztcbiAgfVxuXG4gIC8vIGRlbm8tbGludC1pZ25vcmUgbm8tZXhwbGljaXQtYW55XG4gIGNvbnN0IHsgbmF2aWdhdG9yIH0gPSBnbG9iYWxUaGlzIGFzIGFueTtcbiAgaWYgKG5hdmlnYXRvcj8uYXBwVmVyc2lvbj8uaW5jbHVkZXM/LihcIldpblwiKSkge1xuICAgIHJldHVybiBcIndpbmRvd3NcIjtcbiAgfVxuXG4gIHJldHVybiBcImxpbnV4XCI7XG59KSgpO1xuXG5leHBvcnQgY29uc3QgaXNXaW5kb3dzID0gb3NUeXBlID09PSBcIndpbmRvd3NcIjtcbmV4cG9ydCBjb25zdCBpc0xpbnV4ID0gb3NUeXBlID09PSBcImxpbnV4XCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEVBQTBFO0FBQzFFLHFDQUFxQztBQUlyQyxPQUFPLE1BQU0sU0FBaUIsQUFBQyxDQUFBLElBQU07SUFDbkMsbUNBQW1DO0lBQ25DLE1BQU0sRUFBRSxLQUFJLEVBQUUsR0FBRztJQUNqQixJQUFJLE9BQU8sTUFBTSxPQUFPLE9BQU8sVUFBVTtRQUN2QyxPQUFPLEtBQUssS0FBSyxDQUFDLEVBQUU7SUFDdEIsQ0FBQztJQUVELG1DQUFtQztJQUNuQyxNQUFNLEVBQUUsVUFBUyxFQUFFLEdBQUc7SUFDdEIsSUFBSSxXQUFXLFlBQVksV0FBVyxRQUFRO1FBQzVDLE9BQU87SUFDVCxDQUFDO0lBRUQsT0FBTztBQUNULENBQUEsSUFBSztBQUVMLE9BQU8sTUFBTSxZQUFZLFdBQVcsVUFBVTtBQUM5QyxPQUFPLE1BQU0sVUFBVSxXQUFXLFFBQVEifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/jO4Cj24EIKVTiTvdPctAVhckzgg.js b/tests/__snapshots__/transpile/remote/modules/jO4Cj24EIKVTiTvdPctAVhckzgg.js new file mode 100644 index 0000000..121d0d0 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/jO4Cj24EIKVTiTvdPctAVhckzgg.js @@ -0,0 +1,39 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** Check whether binary arrays are equal to each other using 8-bit comparisons. + * @private + * @param a first array to check equality + * @param b second array to check equality + */ export function equalsNaive(a, b) { + if (a.length !== b.length) return false; + for(let i = 0; i < b.length; i++){ + if (a[i] !== b[i]) return false; + } + return true; +} +/** Check whether binary arrays are equal to each other using 32-bit comparisons. + * @private + * @param a first array to check equality + * @param b second array to check equality + */ export function equalsSimd(a, b) { + if (a.length !== b.length) return false; + const len = a.length; + const compressable = Math.floor(len / 4); + const compressedA = new Uint32Array(a.buffer, 0, compressable); + const compressedB = new Uint32Array(b.buffer, 0, compressable); + for(let i = compressable * 4; i < len; i++){ + if (a[i] !== b[i]) return false; + } + for(let i = 0; i < compressedA.length; i++){ + if (compressedA[i] !== compressedB[i]) return false; + } + return true; +} +/** Check whether binary arrays are equal to each other. + * @param a first array to check equality + * @param b second array to check equality + */ export function equals(a, b) { + if (a.length < 1000) return equalsNaive(a, b); + return equalsSimd(a, b); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2J5dGVzL2VxdWFscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vKiogQ2hlY2sgd2hldGhlciBiaW5hcnkgYXJyYXlzIGFyZSBlcXVhbCB0byBlYWNoIG90aGVyIHVzaW5nIDgtYml0IGNvbXBhcmlzb25zLlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBhIGZpcnN0IGFycmF5IHRvIGNoZWNrIGVxdWFsaXR5XG4gKiBAcGFyYW0gYiBzZWNvbmQgYXJyYXkgdG8gY2hlY2sgZXF1YWxpdHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVxdWFsc05haXZlKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogQ2hlY2sgd2hldGhlciBiaW5hcnkgYXJyYXlzIGFyZSBlcXVhbCB0byBlYWNoIG90aGVyIHVzaW5nIDMyLWJpdCBjb21wYXJpc29ucy5cbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gYSBmaXJzdCBhcnJheSB0byBjaGVjayBlcXVhbGl0eVxuICogQHBhcmFtIGIgc2Vjb25kIGFycmF5IHRvIGNoZWNrIGVxdWFsaXR5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbHNTaW1kKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBsZW4gPSBhLmxlbmd0aDtcbiAgY29uc3QgY29tcHJlc3NhYmxlID0gTWF0aC5mbG9vcihsZW4gLyA0KTtcbiAgY29uc3QgY29tcHJlc3NlZEEgPSBuZXcgVWludDMyQXJyYXkoYS5idWZmZXIsIDAsIGNvbXByZXNzYWJsZSk7XG4gIGNvbnN0IGNvbXByZXNzZWRCID0gbmV3IFVpbnQzMkFycmF5KGIuYnVmZmVyLCAwLCBjb21wcmVzc2FibGUpO1xuICBmb3IgKGxldCBpID0gY29tcHJlc3NhYmxlICogNDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbXByZXNzZWRBLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGNvbXByZXNzZWRBW2ldICE9PSBjb21wcmVzc2VkQltpXSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogQ2hlY2sgd2hldGhlciBiaW5hcnkgYXJyYXlzIGFyZSBlcXVhbCB0byBlYWNoIG90aGVyLlxuICogQHBhcmFtIGEgZmlyc3QgYXJyYXkgdG8gY2hlY2sgZXF1YWxpdHlcbiAqIEBwYXJhbSBiIHNlY29uZCBhcnJheSB0byBjaGVjayBlcXVhbGl0eVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoIDwgMTAwMCkgcmV0dXJuIGVxdWFsc05haXZlKGEsIGIpO1xuICByZXR1cm4gZXF1YWxzU2ltZChhLCBiKTtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDOzs7O0NBSUMsR0FDRCxPQUFPLFNBQVMsWUFBWSxDQUFhLEVBQUUsQ0FBYSxFQUFXO0lBQ2pFLElBQUksRUFBRSxNQUFNLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxLQUFLO0lBQ3ZDLElBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFLO1FBQ2pDLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sS0FBSztJQUNqQztJQUNBLE9BQU8sSUFBSTtBQUNiLENBQUM7QUFFRDs7OztDQUlDLEdBQ0QsT0FBTyxTQUFTLFdBQVcsQ0FBYSxFQUFFLENBQWEsRUFBVztJQUNoRSxJQUFJLEVBQUUsTUFBTSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sS0FBSztJQUN2QyxNQUFNLE1BQU0sRUFBRSxNQUFNO0lBQ3BCLE1BQU0sZUFBZSxLQUFLLEtBQUssQ0FBQyxNQUFNO0lBQ3RDLE1BQU0sY0FBYyxJQUFJLFlBQVksRUFBRSxNQUFNLEVBQUUsR0FBRztJQUNqRCxNQUFNLGNBQWMsSUFBSSxZQUFZLEVBQUUsTUFBTSxFQUFFLEdBQUc7SUFDakQsSUFBSyxJQUFJLElBQUksZUFBZSxHQUFHLElBQUksS0FBSyxJQUFLO1FBQzNDLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sS0FBSztJQUNqQztJQUNBLElBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxZQUFZLE1BQU0sRUFBRSxJQUFLO1FBQzNDLElBQUksV0FBVyxDQUFDLEVBQUUsS0FBSyxXQUFXLENBQUMsRUFBRSxFQUFFLE9BQU8sS0FBSztJQUNyRDtJQUNBLE9BQU8sSUFBSTtBQUNiLENBQUM7QUFFRDs7O0NBR0MsR0FDRCxPQUFPLFNBQVMsT0FBTyxDQUFhLEVBQUUsQ0FBYSxFQUFXO0lBQzVELElBQUksRUFBRSxNQUFNLEdBQUcsTUFBTSxPQUFPLFlBQVksR0FBRztJQUMzQyxPQUFPLFdBQVcsR0FBRztBQUN2QixDQUFDIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/kWDlQkpYLFWxtJdAejga3vZCeeM.js b/tests/__snapshots__/transpile/remote/modules/kWDlQkpYLFWxtJdAejga3vZCeeM.js new file mode 100644 index 0000000..c838ff9 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/kWDlQkpYLFWxtJdAejga3vZCeeM.js @@ -0,0 +1,433 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +import { CHAR_DOT, CHAR_FORWARD_SLASH } from "./_constants.ts"; +import { _format, assertPath, encodeWhitespace, isPosixPathSeparator, normalizeString } from "./_util.ts"; +export const sep = "/"; +export const delimiter = ":"; +// path.resolve([from ...], to) +/** + * Resolves `pathSegments` into an absolute path. + * @param pathSegments an array of path segments + */ export function resolve(...pathSegments) { + let resolvedPath = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--){ + let path; + if (i >= 0) path = pathSegments[i]; + else { + // deno-lint-ignore no-explicit-any + const { Deno } = globalThis; + if (typeof Deno?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno.cwd(); + } + assertPath(path); + // Skip empty entries + if (path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + } + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + // Normalize the path + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator); + if (resolvedAbsolute) { + if (resolvedPath.length > 0) return `/${resolvedPath}`; + else return "/"; + } else if (resolvedPath.length > 0) return resolvedPath; + else return "."; +} +/** + * Normalize the `path`, resolving `'..'` and `'.'` segments. + * @param path to be normalized + */ export function normalize(path) { + assertPath(path); + if (path.length === 0) return "."; + const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + const trailingSeparator = path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH; + // Normalize the path + path = normalizeString(path, !isAbsolute, "/", isPosixPathSeparator); + if (path.length === 0 && !isAbsolute) path = "."; + if (path.length > 0 && trailingSeparator) path += "/"; + if (isAbsolute) return `/${path}`; + return path; +} +/** + * Verifies whether provided path is absolute + * @param path to be verified as absolute + */ export function isAbsolute(path) { + assertPath(path); + return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH; +} +/** + * Join all given a sequence of `paths`,then normalizes the resulting path. + * @param paths to be joined and normalized + */ export function join(...paths) { + if (paths.length === 0) return "."; + let joined; + for(let i = 0, len = paths.length; i < len; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (!joined) joined = path; + else joined += `/${path}`; + } + } + if (!joined) return "."; + return normalize(joined); +} +/** + * Return the relative path from `from` to `to` based on current working directory. + * @param from path in current working directory + * @param to path in current working directory + */ export function relative(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + from = resolve(from); + to = resolve(to); + if (from === to) return ""; + // Trim any leading backslashes + let fromStart = 1; + const fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== CHAR_FORWARD_SLASH) break; + } + const fromLen = fromEnd - fromStart; + // Trim any leading backslashes + let toStart = 1; + const toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== CHAR_FORWARD_SLASH) break; + } + const toLen = toEnd - toStart; + // Compare paths to find the longest common path from root + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) { + // We get here if `from` is the exact base path for `to`. + // For example: from='/foo/bar'; to='/foo/bar/baz' + return to.slice(toStart + i + 1); + } else if (i === 0) { + // We get here if `from` is the root + // For example: from='/'; to='/foo' + return to.slice(toStart + i); + } + } else if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) { + // We get here if `to` is the exact base path for `from`. + // For example: from='/foo/bar/baz'; to='/foo/bar' + lastCommonSep = i; + } else if (i === 0) { + // We get here if `to` is the root. + // For example: from='/foo'; to='/' + lastCommonSep = 0; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === CHAR_FORWARD_SLASH) lastCommonSep = i; + } + let out = ""; + // Generate the relative path based on the path difference between `to` + // and `from` + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === CHAR_FORWARD_SLASH) { + if (out.length === 0) out += ".."; + else out += "/.."; + } + } + // Lastly, append the rest of the destination (`to`) path that comes after + // the common path parts + if (out.length > 0) return out + to.slice(toStart + lastCommonSep); + else { + toStart += lastCommonSep; + if (to.charCodeAt(toStart) === CHAR_FORWARD_SLASH) ++toStart; + return to.slice(toStart); + } +} +/** + * Resolves path to a namespace path + * @param path to resolve to namespace + */ export function toNamespacedPath(path) { + // Non-op on posix systems + return path; +} +/** + * Return the directory name of a `path`. + * @param path to determine name for + */ export function dirname(path) { + assertPath(path); + if (path.length === 0) return "."; + const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + let end = -1; + let matchedSlash = true; + for(let i = path.length - 1; i >= 1; --i){ + if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { + if (!matchedSlash) { + end = i; + break; + } + } else { + // We saw the first non-path separator + matchedSlash = false; + } + } + if (end === -1) return hasRoot ? "/" : "."; + if (hasRoot && end === 1) return "//"; + return path.slice(0, end); +} +/** + * Return the last portion of a `path`. Trailing directory separators are ignored. + * @param path to process + * @param ext of path directory + */ export function basename(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + // We saw the first non-path separator, remember this index in case + // we need it if the extension ends up not matching + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + // Try to match the explicit extension + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + // We matched the extension, so mark this as the end of our path + // component + end = i; + } + } else { + // Extension does not match, so our result is the entire path + // component + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= 0; --i){ + if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // path component + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +/** + * Return the extension of the `path` with leading period. + * @param path with extension + * @returns extension (ex. for `file.ts` returns `.ts`) + */ export function extname(path) { + assertPath(path); + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + for(let i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +/** + * Generate a path from `FormatInputPathObject` object. + * @param pathObject with path + */ export function format(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("/", pathObject); +} +/** + * Return a `ParsedPath` object of the `path`. + * @param path to process + */ export function parse(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + if (path.length === 0) return ret; + const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + let start; + if (isAbsolute) { + ret.root = "/"; + start = 1; + } else { + start = 0; + } + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + // Get non-dir info + for(; i >= start; --i){ + const code = path.charCodeAt(i); + if (code === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + if (startPart === 0 && isAbsolute) { + ret.base = ret.name = path.slice(1, end); + } else { + ret.base = ret.name = path.slice(startPart, end); + } + } + } else { + if (startPart === 0 && isAbsolute) { + ret.name = path.slice(1, startDot); + ret.base = path.slice(1, end); + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + } + ret.ext = path.slice(startDot, end); + } + if (startPart > 0) ret.dir = path.slice(0, startPart - 1); + else if (isAbsolute) ret.dir = "/"; + return ret; +} +/** + * Converts a file URL to a path string. + * + * ```ts + * import { fromFileUrl } from "./posix.ts"; + * fromFileUrl("file:///home/foo"); // "/home/foo" + * ``` + * @param url of a file URL + */ export function fromFileUrl(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25")); +} +/** + * Converts a path string to a file URL. + * + * ```ts + * import { toFileUrl } from "./posix.ts"; + * toFileUrl("/home/foo"); // new URL("file:///home/foo") + * ``` + * @param path to convert to file URL + */ export function toFileUrl(path) { + if (!isAbsolute(path)) { + throw new TypeError("Must be an absolute path."); + } + const url = new URL("file:///"); + url.pathname = encodeWhitespace(path.replace(/%/g, "%25").replace(/\\/g, "%5C")); + return url; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvcG9zaXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QsIFBhcnNlZFBhdGggfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQgeyBDSEFSX0RPVCwgQ0hBUl9GT1JXQVJEX1NMQVNIIH0gZnJvbSBcIi4vX2NvbnN0YW50cy50c1wiO1xuXG5pbXBvcnQge1xuICBfZm9ybWF0LFxuICBhc3NlcnRQYXRoLFxuICBlbmNvZGVXaGl0ZXNwYWNlLFxuICBpc1Bvc2l4UGF0aFNlcGFyYXRvcixcbiAgbm9ybWFsaXplU3RyaW5nLFxufSBmcm9tIFwiLi9fdXRpbC50c1wiO1xuXG5leHBvcnQgY29uc3Qgc2VwID0gXCIvXCI7XG5leHBvcnQgY29uc3QgZGVsaW1pdGVyID0gXCI6XCI7XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8qKlxuICogUmVzb2x2ZXMgYHBhdGhTZWdtZW50c2AgaW50byBhbiBhYnNvbHV0ZSBwYXRoLlxuICogQHBhcmFtIHBhdGhTZWdtZW50cyBhbiBhcnJheSBvZiBwYXRoIHNlZ21lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlKC4uLnBhdGhTZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICBsZXQgcmVzb2x2ZWRQYXRoID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTEgJiYgIXJlc29sdmVkQWJzb2x1dGU7IGktLSkge1xuICAgIGxldCBwYXRoOiBzdHJpbmc7XG5cbiAgICBpZiAoaSA+PSAwKSBwYXRoID0gcGF0aFNlZ21lbnRzW2ldO1xuICAgIGVsc2Uge1xuICAgICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICAgIGNvbnN0IHsgRGVubyB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gICAgICBpZiAodHlwZW9mIERlbm8/LmN3ZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIHJlbGF0aXZlIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcbiAgICB9XG5cbiAgICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBlbnRyaWVzXG4gICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXNvbHZlZFBhdGggPSBgJHtwYXRofS8ke3Jlc29sdmVkUGF0aH1gO1xuICAgIHJlc29sdmVkQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZVN0cmluZyhcbiAgICByZXNvbHZlZFBhdGgsXG4gICAgIXJlc29sdmVkQWJzb2x1dGUsXG4gICAgXCIvXCIsXG4gICAgaXNQb3NpeFBhdGhTZXBhcmF0b3IsXG4gICk7XG5cbiAgaWYgKHJlc29sdmVkQWJzb2x1dGUpIHtcbiAgICBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiBgLyR7cmVzb2x2ZWRQYXRofWA7XG4gICAgZWxzZSByZXR1cm4gXCIvXCI7XG4gIH0gZWxzZSBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiByZXNvbHZlZFBhdGg7XG4gIGVsc2UgcmV0dXJuIFwiLlwiO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSB0aGUgYHBhdGhgLCByZXNvbHZpbmcgYCcuLidgIGFuZCBgJy4nYCBzZWdtZW50cy5cbiAqIEBwYXJhbSBwYXRoIHRvIGJlIG5vcm1hbGl6ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuXG4gIGNvbnN0IGlzQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgY29uc3QgdHJhaWxpbmdTZXBhcmF0b3IgPVxuICAgIHBhdGguY2hhckNvZGVBdChwYXRoLmxlbmd0aCAtIDEpID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHBhdGggPSBub3JtYWxpemVTdHJpbmcocGF0aCwgIWlzQWJzb2x1dGUsIFwiL1wiLCBpc1Bvc2l4UGF0aFNlcGFyYXRvcik7XG5cbiAgaWYgKHBhdGgubGVuZ3RoID09PSAwICYmICFpc0Fic29sdXRlKSBwYXRoID0gXCIuXCI7XG4gIGlmIChwYXRoLmxlbmd0aCA+IDAgJiYgdHJhaWxpbmdTZXBhcmF0b3IpIHBhdGggKz0gXCIvXCI7XG5cbiAgaWYgKGlzQWJzb2x1dGUpIHJldHVybiBgLyR7cGF0aH1gO1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBWZXJpZmllcyB3aGV0aGVyIHByb3ZpZGVkIHBhdGggaXMgYWJzb2x1dGVcbiAqIEBwYXJhbSBwYXRoIHRvIGJlIHZlcmlmaWVkIGFzIGFic29sdXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Fic29sdXRlKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICByZXR1cm4gcGF0aC5sZW5ndGggPiAwICYmIHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xufVxuXG4vKipcbiAqIEpvaW4gYWxsIGdpdmVuIGEgc2VxdWVuY2Ugb2YgYHBhdGhzYCx0aGVuIG5vcm1hbGl6ZXMgdGhlIHJlc3VsdGluZyBwYXRoLlxuICogQHBhcmFtIHBhdGhzIHRvIGJlIGpvaW5lZCBhbmQgbm9ybWFsaXplZFxuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbiguLi5wYXRoczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAocGF0aHMubGVuZ3RoID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCBqb2luZWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBhdGhzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgIGFzc2VydFBhdGgocGF0aCk7XG4gICAgaWYgKHBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFqb2luZWQpIGpvaW5lZCA9IHBhdGg7XG4gICAgICBlbHNlIGpvaW5lZCArPSBgLyR7cGF0aH1gO1xuICAgIH1cbiAgfVxuICBpZiAoIWpvaW5lZCkgcmV0dXJuIFwiLlwiO1xuICByZXR1cm4gbm9ybWFsaXplKGpvaW5lZCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSByZWxhdGl2ZSBwYXRoIGZyb20gYGZyb21gIHRvIGB0b2AgYmFzZWQgb24gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSBmcm9tIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICogQHBhcmFtIHRvIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpdmUoZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChmcm9tKTtcbiAgYXNzZXJ0UGF0aCh0byk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICBmcm9tID0gcmVzb2x2ZShmcm9tKTtcbiAgdG8gPSByZXNvbHZlKHRvKTtcblxuICBpZiAoZnJvbSA9PT0gdG8pIHJldHVybiBcIlwiO1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IGZyb21TdGFydCA9IDE7XG4gIGNvbnN0IGZyb21FbmQgPSBmcm9tLmxlbmd0aDtcbiAgZm9yICg7IGZyb21TdGFydCA8IGZyb21FbmQ7ICsrZnJvbVN0YXJ0KSB7XG4gICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQpICE9PSBDSEFSX0ZPUldBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IGZyb21MZW4gPSBmcm9tRW5kIC0gZnJvbVN0YXJ0O1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IHRvU3RhcnQgPSAxO1xuICBjb25zdCB0b0VuZCA9IHRvLmxlbmd0aDtcbiAgZm9yICg7IHRvU3RhcnQgPCB0b0VuZDsgKyt0b1N0YXJ0KSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCkgIT09IENIQVJfRk9SV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgdG9MZW4gPSB0b0VuZCAtIHRvU3RhcnQ7XG5cbiAgLy8gQ29tcGFyZSBwYXRocyB0byBmaW5kIHRoZSBsb25nZXN0IGNvbW1vbiBwYXRoIGZyb20gcm9vdFxuICBjb25zdCBsZW5ndGggPSBmcm9tTGVuIDwgdG9MZW4gPyBmcm9tTGVuIDogdG9MZW47XG4gIGxldCBsYXN0Q29tbW9uU2VwID0gLTE7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPD0gbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gbGVuZ3RoKSB7XG4gICAgICBpZiAodG9MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIGV4YWN0IGJhc2UgcGF0aCBmb3IgYHRvYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXInOyB0bz0nL2Zvby9iYXIvYmF6J1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIHJvb3RcbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nLyc7IHRvPScvZm9vJ1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZnJvbUxlbiA+IGxlbmd0aCkge1xuICAgICAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSBleGFjdCBiYXNlIHBhdGggZm9yIGBmcm9tYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXIvYmF6JzsgdG89Jy9mb28vYmFyJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSByb290LlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPScvZm9vJzsgdG89Jy8nXG4gICAgICAgICAgbGFzdENvbW1vblNlcCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ29kZSA9IGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKTtcbiAgICBjb25zdCB0b0NvZGUgPSB0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKTtcbiAgICBpZiAoZnJvbUNvZGUgIT09IHRvQ29kZSkgYnJlYWs7XG4gICAgZWxzZSBpZiAoZnJvbUNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkgbGFzdENvbW1vblNlcCA9IGk7XG4gIH1cblxuICBsZXQgb3V0ID0gXCJcIjtcbiAgLy8gR2VuZXJhdGUgdGhlIHJlbGF0aXZlIHBhdGggYmFzZWQgb24gdGhlIHBhdGggZGlmZmVyZW5jZSBiZXR3ZWVuIGB0b2BcbiAgLy8gYW5kIGBmcm9tYFxuICBmb3IgKGkgPSBmcm9tU3RhcnQgKyBsYXN0Q29tbW9uU2VwICsgMTsgaSA8PSBmcm9tRW5kOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gZnJvbUVuZCB8fCBmcm9tLmNoYXJDb2RlQXQoaSkgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgaWYgKG91dC5sZW5ndGggPT09IDApIG91dCArPSBcIi4uXCI7XG4gICAgICBlbHNlIG91dCArPSBcIi8uLlwiO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSwgYXBwZW5kIHRoZSByZXN0IG9mIHRoZSBkZXN0aW5hdGlvbiAoYHRvYCkgcGF0aCB0aGF0IGNvbWVzIGFmdGVyXG4gIC8vIHRoZSBjb21tb24gcGF0aCBwYXJ0c1xuICBpZiAob3V0Lmxlbmd0aCA+IDApIHJldHVybiBvdXQgKyB0by5zbGljZSh0b1N0YXJ0ICsgbGFzdENvbW1vblNlcCk7XG4gIGVsc2Uge1xuICAgIHRvU3RhcnQgKz0gbGFzdENvbW1vblNlcDtcbiAgICBpZiAodG8uY2hhckNvZGVBdCh0b1N0YXJ0KSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSArK3RvU3RhcnQ7XG4gICAgcmV0dXJuIHRvLnNsaWNlKHRvU3RhcnQpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCB0byBhIG5hbWVzcGFjZSBwYXRoXG4gKiBAcGFyYW0gcGF0aCB0byByZXNvbHZlIHRvIG5hbWVzcGFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9OYW1lc3BhY2VkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBOb24tb3Agb24gcG9zaXggc3lzdGVtc1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGRpcmVjdG9yeSBuYW1lIG9mIGEgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gZGV0ZXJtaW5lIG5hbWUgZm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuICBjb25zdCBoYXNSb290ID0gcGF0aC5jaGFyQ29kZUF0KDApID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGZvciAobGV0IGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMTsgLS1pKSB7XG4gICAgaWYgKHBhdGguY2hhckNvZGVBdChpKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3JcbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbmQgPT09IC0xKSByZXR1cm4gaGFzUm9vdCA/IFwiL1wiIDogXCIuXCI7XG4gIGlmIChoYXNSb290ICYmIGVuZCA9PT0gMSkgcmV0dXJuIFwiLy9cIjtcbiAgcmV0dXJuIHBhdGguc2xpY2UoMCwgZW5kKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGxhc3QgcG9ydGlvbiBvZiBhIGBwYXRoYC4gVHJhaWxpbmcgZGlyZWN0b3J5IHNlcGFyYXRvcnMgYXJlIGlnbm9yZWQuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKiBAcGFyYW0gZXh0IG9mIHBhdGggZGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlbmFtZShwYXRoOiBzdHJpbmcsIGV4dCA9IFwiXCIpOiBzdHJpbmcge1xuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZXh0XCIgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZycpO1xuICB9XG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGk6IG51bWJlcjtcblxuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgZXh0Lmxlbmd0aCA+IDAgJiYgZXh0Lmxlbmd0aCA8PSBwYXRoLmxlbmd0aCkge1xuICAgIGlmIChleHQubGVuZ3RoID09PSBwYXRoLmxlbmd0aCAmJiBleHQgPT09IHBhdGgpIHJldHVybiBcIlwiO1xuICAgIGxldCBleHRJZHggPSBleHQubGVuZ3RoIC0gMTtcbiAgICBsZXQgZmlyc3ROb25TbGFzaEVuZCA9IC0xO1xuICAgIGZvciAoaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaXJzdE5vblNsYXNoRW5kID09PSAtMSkge1xuICAgICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCByZW1lbWJlciB0aGlzIGluZGV4IGluIGNhc2VcbiAgICAgICAgICAvLyB3ZSBuZWVkIGl0IGlmIHRoZSBleHRlbnNpb24gZW5kcyB1cCBub3QgbWF0Y2hpbmdcbiAgICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgICBmaXJzdE5vblNsYXNoRW5kID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dElkeCA+PSAwKSB7XG4gICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIHRoZSBleHBsaWNpdCBleHRlbnNpb25cbiAgICAgICAgICBpZiAoY29kZSA9PT0gZXh0LmNoYXJDb2RlQXQoZXh0SWR4KSkge1xuICAgICAgICAgICAgaWYgKC0tZXh0SWR4ID09PSAtMSkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIHRoZSBleHRlbnNpb24sIHNvIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91ciBwYXRoXG4gICAgICAgICAgICAgIC8vIGNvbXBvbmVudFxuICAgICAgICAgICAgICBlbmQgPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBFeHRlbnNpb24gZG9lcyBub3QgbWF0Y2gsIHNvIG91ciByZXN1bHQgaXMgdGhlIGVudGlyZSBwYXRoXG4gICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgIGV4dElkeCA9IC0xO1xuICAgICAgICAgICAgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPT09IGVuZCkgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICBlbHNlIGlmIChlbmQgPT09IC0xKSBlbmQgPSBwYXRoLmxlbmd0aDtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgICAgLy8gcGF0aCBjb21wb25lbnRcbiAgICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICAgIGVuZCA9IGkgKyAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbmQgPT09IC0xKSByZXR1cm4gXCJcIjtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgZXh0ZW5zaW9uIG9mIHRoZSBgcGF0aGAgd2l0aCBsZWFkaW5nIHBlcmlvZC5cbiAqIEBwYXJhbSBwYXRoIHdpdGggZXh0ZW5zaW9uXG4gKiBAcmV0dXJucyBleHRlbnNpb24gKGV4LiBmb3IgYGZpbGUudHNgIHJldHVybnMgYC50c2ApXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGxldCBzdGFydERvdCA9IC0xO1xuICBsZXQgc3RhcnRQYXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgLy8gVHJhY2sgdGhlIHN0YXRlIG9mIGNoYXJhY3RlcnMgKGlmIGFueSkgd2Ugc2VlIGJlZm9yZSBvdXIgZmlyc3QgZG90IGFuZFxuICAvLyBhZnRlciBhbnkgcGF0aCBzZXBhcmF0b3Igd2UgZmluZFxuICBsZXQgcHJlRG90U3RhdGUgPSAwO1xuICBmb3IgKGxldCBpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgc3RhcnRQYXJ0ID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25cbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgZW5kID0gaSArIDE7XG4gICAgfVxuICAgIGlmIChjb2RlID09PSBDSEFSX0RPVCkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBvdXIgZmlyc3QgZG90LCBtYXJrIGl0IGFzIHRoZSBzdGFydCBvZiBvdXIgZXh0ZW5zaW9uXG4gICAgICBpZiAoc3RhcnREb3QgPT09IC0xKSBzdGFydERvdCA9IGk7XG4gICAgICBlbHNlIGlmIChwcmVEb3RTdGF0ZSAhPT0gMSkgcHJlRG90U3RhdGUgPSAxO1xuICAgIH0gZWxzZSBpZiAoc3RhcnREb3QgIT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgYSBub24tZG90IGFuZCBub24tcGF0aCBzZXBhcmF0b3IgYmVmb3JlIG91ciBkb3QsIHNvIHdlIHNob3VsZFxuICAgICAgLy8gaGF2ZSBhIGdvb2QgY2hhbmNlIGF0IGhhdmluZyBhIG5vbi1lbXB0eSBleHRlbnNpb25cbiAgICAgIHByZURvdFN0YXRlID0gLTE7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIHN0YXJ0RG90ID09PSAtMSB8fFxuICAgIGVuZCA9PT0gLTEgfHxcbiAgICAvLyBXZSBzYXcgYSBub24tZG90IGNoYXJhY3RlciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGRvdFxuICAgIHByZURvdFN0YXRlID09PSAwIHx8XG4gICAgLy8gVGhlIChyaWdodC1tb3N0KSB0cmltbWVkIHBhdGggY29tcG9uZW50IGlzIGV4YWN0bHkgJy4uJ1xuICAgIChwcmVEb3RTdGF0ZSA9PT0gMSAmJiBzdGFydERvdCA9PT0gZW5kIC0gMSAmJiBzdGFydERvdCA9PT0gc3RhcnRQYXJ0ICsgMSlcbiAgKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbiAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnREb3QsIGVuZCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBwYXRoIGZyb20gYEZvcm1hdElucHV0UGF0aE9iamVjdGAgb2JqZWN0LlxuICogQHBhcmFtIHBhdGhPYmplY3Qgd2l0aCBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXQocGF0aE9iamVjdDogRm9ybWF0SW5wdXRQYXRoT2JqZWN0KTogc3RyaW5nIHtcbiAgaWYgKHBhdGhPYmplY3QgPT09IG51bGwgfHwgdHlwZW9mIHBhdGhPYmplY3QgIT09IFwib2JqZWN0XCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYFRoZSBcInBhdGhPYmplY3RcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICR7dHlwZW9mIHBhdGhPYmplY3R9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBfZm9ybWF0KFwiL1wiLCBwYXRoT2JqZWN0KTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBgUGFyc2VkUGF0aGAgb2JqZWN0IG9mIHRoZSBgcGF0aGAuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShwYXRoOiBzdHJpbmcpOiBQYXJzZWRQYXRoIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICBjb25zdCByZXQ6IFBhcnNlZFBhdGggPSB7IHJvb3Q6IFwiXCIsIGRpcjogXCJcIiwgYmFzZTogXCJcIiwgZXh0OiBcIlwiLCBuYW1lOiBcIlwiIH07XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJldDtcbiAgY29uc3QgaXNBYnNvbHV0ZSA9IHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xuICBsZXQgc3RhcnQ6IG51bWJlcjtcbiAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICByZXQucm9vdCA9IFwiL1wiO1xuICAgIHN0YXJ0ID0gMTtcbiAgfSBlbHNlIHtcbiAgICBzdGFydCA9IDA7XG4gIH1cbiAgbGV0IHN0YXJ0RG90ID0gLTE7XG4gIGxldCBzdGFydFBhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICBsZXQgaSA9IHBhdGgubGVuZ3RoIC0gMTtcblxuICAvLyBUcmFjayB0aGUgc3RhdGUgb2YgY2hhcmFjdGVycyAoaWYgYW55KSB3ZSBzZWUgYmVmb3JlIG91ciBmaXJzdCBkb3QgYW5kXG4gIC8vIGFmdGVyIGFueSBwYXRoIHNlcGFyYXRvciB3ZSBmaW5kXG4gIGxldCBwcmVEb3RTdGF0ZSA9IDA7XG5cbiAgLy8gR2V0IG5vbi1kaXIgaW5mb1xuICBmb3IgKDsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICBpZiAoZW5kICE9PSAtMSkge1xuICAgICAgaWYgKHN0YXJ0UGFydCA9PT0gMCAmJiBpc0Fic29sdXRlKSB7XG4gICAgICAgIHJldC5iYXNlID0gcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIGVuZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQuYmFzZSA9IHJldC5uYW1lID0gcGF0aC5zbGljZShzdGFydFBhcnQsIGVuZCk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChzdGFydFBhcnQgPT09IDAgJiYgaXNBYnNvbHV0ZSkge1xuICAgICAgcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIHN0YXJ0RG90KTtcbiAgICAgIHJldC5iYXNlID0gcGF0aC5zbGljZSgxLCBlbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBzdGFydERvdCk7XG4gICAgICByZXQuYmFzZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBlbmQpO1xuICAgIH1cbiAgICByZXQuZXh0ID0gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbiAgfVxuXG4gIGlmIChzdGFydFBhcnQgPiAwKSByZXQuZGlyID0gcGF0aC5zbGljZSgwLCBzdGFydFBhcnQgLSAxKTtcbiAgZWxzZSBpZiAoaXNBYnNvbHV0ZSkgcmV0LmRpciA9IFwiL1wiO1xuXG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBmaWxlIFVSTCB0byBhIHBhdGggc3RyaW5nLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IGZyb21GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgZnJvbUZpbGVVcmwoXCJmaWxlOi8vL2hvbWUvZm9vXCIpOyAvLyBcIi9ob21lL2Zvb1wiXG4gKiBgYGBcbiAqIEBwYXJhbSB1cmwgb2YgYSBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUZpbGVVcmwodXJsOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICB1cmwgPSB1cmwgaW5zdGFuY2VvZiBVUkwgPyB1cmwgOiBuZXcgVVJMKHVybCk7XG4gIGlmICh1cmwucHJvdG9jb2wgIT0gXCJmaWxlOlwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYSBmaWxlIFVSTC5cIik7XG4gIH1cbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChcbiAgICB1cmwucGF0aG5hbWUucmVwbGFjZSgvJSg/IVswLTlBLUZhLWZdezJ9KS9nLCBcIiUyNVwiKSxcbiAgKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHBhdGggc3RyaW5nIHRvIGEgZmlsZSBVUkwuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgdG9GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgdG9GaWxlVXJsKFwiL2hvbWUvZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9ob21lL2Zvb1wiKVxuICogYGBgXG4gKiBAcGFyYW0gcGF0aCB0byBjb252ZXJ0IHRvIGZpbGUgVVJMXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0ZpbGVVcmwocGF0aDogc3RyaW5nKTogVVJMIHtcbiAgaWYgKCFpc0Fic29sdXRlKHBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYW4gYWJzb2x1dGUgcGF0aC5cIik7XG4gIH1cbiAgY29uc3QgdXJsID0gbmV3IFVSTChcImZpbGU6Ly8vXCIpO1xuICB1cmwucGF0aG5hbWUgPSBlbmNvZGVXaGl0ZXNwYWNlKFxuICAgIHBhdGgucmVwbGFjZSgvJS9nLCBcIiUyNVwiKS5yZXBsYWNlKC9cXFxcL2csIFwiJTVDXCIpLFxuICApO1xuICByZXR1cm4gdXJsO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxpREFBaUQ7QUFDakQsNkRBQTZEO0FBQzdELHFDQUFxQztBQUdyQyxTQUFTLFFBQVEsRUFBRSxrQkFBa0IsUUFBUSxrQkFBa0I7QUFFL0QsU0FDRSxPQUFPLEVBQ1AsVUFBVSxFQUNWLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsZUFBZSxRQUNWLGFBQWE7QUFFcEIsT0FBTyxNQUFNLE1BQU0sSUFBSTtBQUN2QixPQUFPLE1BQU0sWUFBWSxJQUFJO0FBRTdCLCtCQUErQjtBQUMvQjs7O0NBR0MsR0FDRCxPQUFPLFNBQVMsUUFBUSxHQUFHLFlBQXNCLEVBQVU7SUFDekQsSUFBSSxlQUFlO0lBQ25CLElBQUksbUJBQW1CLEtBQUs7SUFFNUIsSUFBSyxJQUFJLElBQUksYUFBYSxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLGtCQUFrQixJQUFLO1FBQ3ZFLElBQUk7UUFFSixJQUFJLEtBQUssR0FBRyxPQUFPLFlBQVksQ0FBQyxFQUFFO2FBQzdCO1lBQ0gsbUNBQW1DO1lBQ25D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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js b/tests/__snapshots__/transpile/remote/modules/nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js new file mode 100644 index 0000000..fc8cdf6 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js @@ -0,0 +1,14 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +export class DenoStdInternalError extends Error { + constructor(message){ + super(message); + this.name = "DenoStdInternalError"; + } +} +/** Make an assertion, if not `true`, then throw. */ export function assert(expr, msg = "") { + if (!expr) { + throw new DenoStdInternalError(msg); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL2Fzc2VydC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5leHBvcnQgY2xhc3MgRGVub1N0ZEludGVybmFsRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiRGVub1N0ZEludGVybmFsRXJyb3JcIjtcbiAgfVxufVxuXG4vKiogTWFrZSBhbiBhc3NlcnRpb24sIGlmIG5vdCBgdHJ1ZWAsIHRoZW4gdGhyb3cuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0KGV4cHI6IHVua25vd24sIG1zZyA9IFwiXCIpOiBhc3NlcnRzIGV4cHIge1xuICBpZiAoIWV4cHIpIHtcbiAgICB0aHJvdyBuZXcgRGVub1N0ZEludGVybmFsRXJyb3IobXNnKTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxxQ0FBcUM7QUFFckMsT0FBTyxNQUFNLDZCQUE2QjtJQUN4QyxZQUFZLE9BQWUsQ0FBRTtRQUMzQixLQUFLLENBQUM7UUFDTixJQUFJLENBQUMsSUFBSSxHQUFHO0lBQ2Q7QUFDRixDQUFDO0FBRUQsa0RBQWtELEdBQ2xELE9BQU8sU0FBUyxPQUFPLElBQWEsRUFBRSxNQUFNLEVBQUUsRUFBZ0I7SUFDNUQsSUFBSSxDQUFDLE1BQU07UUFDVCxNQUFNLElBQUkscUJBQXFCLEtBQUs7SUFDdEMsQ0FBQztBQUNILENBQUMifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/npEsX-46oQUgZNw2Jkxv5i4eWDM.js b/tests/__snapshots__/transpile/remote/modules/npEsX-46oQUgZNw2Jkxv5i4eWDM.js new file mode 100644 index 0000000..04be5a3 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/npEsX-46oQUgZNw2Jkxv5i4eWDM.js @@ -0,0 +1,851 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { assert } from "../_util/assert.ts"; +import { BytesList } from "../bytes/bytes_list.ts"; +import { concat, copy } from "../bytes/mod.ts"; +// MIN_READ is the minimum ArrayBuffer size passed to a read call by +// buffer.ReadFrom. As long as the Buffer has at least MIN_READ bytes beyond +// what is required to hold the contents of r, readFrom() will not grow the +// underlying buffer. +const MIN_READ = 32 * 1024; +const MAX_SIZE = 2 ** 32 - 2; +/** A variable-sized buffer of bytes with `read()` and `write()` methods. + * + * Buffer is almost always used with some I/O like files and sockets. It allows + * one to buffer up a download from a socket. Buffer grows and shrinks as + * necessary. + * + * Buffer is NOT the same thing as Node's Buffer. Node's Buffer was created in + * 2009 before JavaScript had the concept of ArrayBuffers. It's simply a + * non-standard ArrayBuffer. + * + * ArrayBuffer is a fixed memory allocation. Buffer is implemented on top of + * ArrayBuffer. + * + * Based on [Go Buffer](https://golang.org/pkg/bytes/#Buffer). */ export class Buffer { + #buf; + #off = 0; + constructor(ab){ + this.#buf = ab === undefined ? new Uint8Array(0) : new Uint8Array(ab); + } + /** Returns a slice holding the unread portion of the buffer. + * + * The slice is valid for use only until the next buffer modification (that + * is, only until the next call to a method like `read()`, `write()`, + * `reset()`, or `truncate()`). If `options.copy` is false the slice aliases the buffer content at + * least until the next buffer modification, so immediate changes to the + * slice will affect the result of future reads. + * @param options Defaults to `{ copy: true }` + */ bytes(options = { + copy: true + }) { + if (options.copy === false) return this.#buf.subarray(this.#off); + return this.#buf.slice(this.#off); + } + /** Returns whether the unread portion of the buffer is empty. */ empty() { + return this.#buf.byteLength <= this.#off; + } + /** A read only number of bytes of the unread portion of the buffer. */ get length() { + return this.#buf.byteLength - this.#off; + } + /** The read only capacity of the buffer's underlying byte slice, that is, + * the total space allocated for the buffer's data. */ get capacity() { + return this.#buf.buffer.byteLength; + } + /** Discards all but the first `n` unread bytes from the buffer but + * continues to use the same allocated storage. It throws if `n` is + * negative or greater than the length of the buffer. */ truncate(n) { + if (n === 0) { + this.reset(); + return; + } + if (n < 0 || n > this.length) { + throw Error("bytes.Buffer: truncation out of range"); + } + this.#reslice(this.#off + n); + } + reset() { + this.#reslice(0); + this.#off = 0; + } + #tryGrowByReslice(n) { + const l = this.#buf.byteLength; + if (n <= this.capacity - l) { + this.#reslice(l + n); + return l; + } + return -1; + } + #reslice(len) { + assert(len <= this.#buf.buffer.byteLength); + this.#buf = new Uint8Array(this.#buf.buffer, 0, len); + } + /** Reads the next `p.length` bytes from the buffer or until the buffer is + * drained. Returns the number of bytes read. If the buffer has no data to + * return, the return is EOF (`null`). */ readSync(p) { + if (this.empty()) { + // Buffer is empty, reset to recover space. + this.reset(); + if (p.byteLength === 0) { + // this edge case is tested in 'bufferReadEmptyAtEOF' test + return 0; + } + return null; + } + const nread = copy(this.#buf.subarray(this.#off), p); + this.#off += nread; + return nread; + } + /** Reads the next `p.length` bytes from the buffer or until the buffer is + * drained. Resolves to the number of bytes read. If the buffer has no + * data to return, resolves to EOF (`null`). + * + * NOTE: This methods reads bytes synchronously; it's provided for + * compatibility with `Reader` interfaces. + */ read(p) { + const rr = this.readSync(p); + return Promise.resolve(rr); + } + writeSync(p) { + const m = this.#grow(p.byteLength); + return copy(p, this.#buf, m); + } + /** NOTE: This methods writes bytes synchronously; it's provided for + * compatibility with `Writer` interface. */ write(p) { + const n = this.writeSync(p); + return Promise.resolve(n); + } + #grow(n) { + const m = this.length; + // If buffer is empty, reset to recover space. + if (m === 0 && this.#off !== 0) { + this.reset(); + } + // Fast: Try to grow by means of a reslice. + const i = this.#tryGrowByReslice(n); + if (i >= 0) { + return i; + } + const c = this.capacity; + if (n <= Math.floor(c / 2) - m) { + // We can slide things down instead of allocating a new + // ArrayBuffer. We only need m+n <= c to slide, but + // we instead let capacity get twice as large so we + // don't spend all our time copying. + copy(this.#buf.subarray(this.#off), this.#buf); + } else if (c + n > MAX_SIZE) { + throw new Error("The buffer cannot be grown beyond the maximum size."); + } else { + // Not enough space anywhere, we need to allocate. + const buf = new Uint8Array(Math.min(2 * c + n, MAX_SIZE)); + copy(this.#buf.subarray(this.#off), buf); + this.#buf = buf; + } + // Restore this.#off and len(this.#buf). + this.#off = 0; + this.#reslice(Math.min(m + n, MAX_SIZE)); + return m; + } + /** Grows the buffer's capacity, if necessary, to guarantee space for + * another `n` bytes. After `.grow(n)`, at least `n` bytes can be written to + * the buffer without another allocation. If `n` is negative, `.grow()` will + * throw. If the buffer can't grow it will throw an error. + * + * Based on Go Lang's + * [Buffer.Grow](https://golang.org/pkg/bytes/#Buffer.Grow). */ grow(n) { + if (n < 0) { + throw Error("Buffer.grow: negative count"); + } + const m = this.#grow(n); + this.#reslice(m); + } + /** Reads data from `r` until EOF (`null`) and appends it to the buffer, + * growing the buffer as needed. It resolves to the number of bytes read. + * If the buffer becomes too large, `.readFrom()` will reject with an error. + * + * Based on Go Lang's + * [Buffer.ReadFrom](https://golang.org/pkg/bytes/#Buffer.ReadFrom). */ async readFrom(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while(true){ + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow ? tmp : new Uint8Array(this.#buf.buffer, this.length); + const nread = await r.read(buf); + if (nread === null) { + return n; + } + // write will grow if needed + if (shouldGrow) this.writeSync(buf.subarray(0, nread)); + else this.#reslice(this.length + nread); + n += nread; + } + } + /** Reads data from `r` until EOF (`null`) and appends it to the buffer, + * growing the buffer as needed. It returns the number of bytes read. If the + * buffer becomes too large, `.readFromSync()` will throw an error. + * + * Based on Go Lang's + * [Buffer.ReadFrom](https://golang.org/pkg/bytes/#Buffer.ReadFrom). */ readFromSync(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while(true){ + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow ? tmp : new Uint8Array(this.#buf.buffer, this.length); + const nread = r.readSync(buf); + if (nread === null) { + return n; + } + // write will grow if needed + if (shouldGrow) this.writeSync(buf.subarray(0, nread)); + else this.#reslice(this.length + nread); + n += nread; + } + } +} +const DEFAULT_BUF_SIZE = 4096; +const MIN_BUF_SIZE = 16; +const MAX_CONSECUTIVE_EMPTY_READS = 100; +const CR = "\r".charCodeAt(0); +const LF = "\n".charCodeAt(0); +export class BufferFullError extends Error { + partial; + name; + constructor(partial){ + super("Buffer full"); + this.partial = partial; + this.name = "BufferFullError"; + } +} +export class PartialReadError extends Error { + name = "PartialReadError"; + partial; + constructor(){ + super("Encountered UnexpectedEof, data only partially read"); + } +} +/** BufReader implements buffering for a Reader object. */ export class BufReader { + #buf; + #rd; + #r = 0; + #w = 0; + #eof = false; + // private lastByte: number; + // private lastCharSize: number; + /** return new BufReader unless r is BufReader */ static create(r, size = DEFAULT_BUF_SIZE) { + return r instanceof BufReader ? r : new BufReader(r, size); + } + constructor(rd, size = DEFAULT_BUF_SIZE){ + if (size < MIN_BUF_SIZE) { + size = MIN_BUF_SIZE; + } + this.#reset(new Uint8Array(size), rd); + } + /** Returns the size of the underlying buffer in bytes. */ size() { + return this.#buf.byteLength; + } + buffered() { + return this.#w - this.#r; + } + // Reads a new chunk into the buffer. + #fill = async ()=>{ + // Slide existing data to beginning. + if (this.#r > 0) { + this.#buf.copyWithin(0, this.#r, this.#w); + this.#w -= this.#r; + this.#r = 0; + } + if (this.#w >= this.#buf.byteLength) { + throw Error("bufio: tried to fill full buffer"); + } + // Read new data: try a limited number of times. + for(let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--){ + const rr = await this.#rd.read(this.#buf.subarray(this.#w)); + if (rr === null) { + this.#eof = true; + return; + } + assert(rr >= 0, "negative read"); + this.#w += rr; + if (rr > 0) { + return; + } + } + throw new Error(`No progress after ${MAX_CONSECUTIVE_EMPTY_READS} read() calls`); + }; + /** Discards any buffered data, resets all state, and switches + * the buffered reader to read from r. + */ reset(r) { + this.#reset(this.#buf, r); + } + #reset = (buf, rd)=>{ + this.#buf = buf; + this.#rd = rd; + this.#eof = false; + // this.lastByte = -1; + // this.lastCharSize = -1; + }; + /** reads data into p. + * It returns the number of bytes read into p. + * The bytes are taken from at most one Read on the underlying Reader, + * hence n may be less than len(p). + * To read exactly len(p) bytes, use io.ReadFull(b, p). + */ async read(p) { + let rr = p.byteLength; + if (p.byteLength === 0) return rr; + if (this.#r === this.#w) { + if (p.byteLength >= this.#buf.byteLength) { + // Large read, empty buffer. + // Read directly into p to avoid copy. + const rr = await this.#rd.read(p); + const nread = rr ?? 0; + assert(nread >= 0, "negative read"); + // if (rr.nread > 0) { + // this.lastByte = p[rr.nread - 1]; + // this.lastCharSize = -1; + // } + return rr; + } + // One read. + // Do not use this.fill, which will loop. + this.#r = 0; + this.#w = 0; + rr = await this.#rd.read(this.#buf); + if (rr === 0 || rr === null) return rr; + assert(rr >= 0, "negative read"); + this.#w += rr; + } + // copy as much as we can + const copied = copy(this.#buf.subarray(this.#r, this.#w), p, 0); + this.#r += copied; + // this.lastByte = this.buf[this.r - 1]; + // this.lastCharSize = -1; + return copied; + } + /** reads exactly `p.length` bytes into `p`. + * + * If successful, `p` is returned. + * + * If the end of the underlying stream has been reached, and there are no more + * bytes available in the buffer, `readFull()` returns `null` instead. + * + * An error is thrown if some bytes could be read, but not enough to fill `p` + * entirely before the underlying stream reported an error or EOF. Any error + * thrown will have a `partial` property that indicates the slice of the + * buffer that has been successfully filled with data. + * + * Ported from https://golang.org/pkg/io/#ReadFull + */ async readFull(p) { + let bytesRead = 0; + while(bytesRead < p.length){ + try { + const rr = await this.read(p.subarray(bytesRead)); + if (rr === null) { + if (bytesRead === 0) { + return null; + } else { + throw new PartialReadError(); + } + } + bytesRead += rr; + } catch (err) { + if (err instanceof PartialReadError) { + err.partial = p.subarray(0, bytesRead); + } else if (err instanceof Error) { + const e = new PartialReadError(); + e.partial = p.subarray(0, bytesRead); + e.stack = err.stack; + e.message = err.message; + e.cause = err.cause; + throw err; + } + throw err; + } + } + return p; + } + /** Returns the next byte [0, 255] or `null`. */ async readByte() { + while(this.#r === this.#w){ + if (this.#eof) return null; + await this.#fill(); // buffer is empty. + } + const c = this.#buf[this.#r]; + this.#r++; + // this.lastByte = c; + return c; + } + /** readString() reads until the first occurrence of delim in the input, + * returning a string containing the data up to and including the delimiter. + * If ReadString encounters an error before finding a delimiter, + * it returns the data read before the error and the error itself + * (often `null`). + * ReadString returns err != nil if and only if the returned data does not end + * in delim. + * For simple uses, a Scanner may be more convenient. + */ async readString(delim) { + if (delim.length !== 1) { + throw new Error("Delimiter should be a single character"); + } + const buffer = await this.readSlice(delim.charCodeAt(0)); + if (buffer === null) return null; + return new TextDecoder().decode(buffer); + } + /** `readLine()` is a low-level line-reading primitive. Most callers should + * use `readString('\n')` instead or use a Scanner. + * + * `readLine()` tries to return a single line, not including the end-of-line + * bytes. If the line was too long for the buffer then `more` is set and the + * beginning of the line is returned. The rest of the line will be returned + * from future calls. `more` will be false when returning the last fragment + * of the line. The returned buffer is only valid until the next call to + * `readLine()`. + * + * The text returned from ReadLine does not include the line end ("\r\n" or + * "\n"). + * + * When the end of the underlying stream is reached, the final bytes in the + * stream are returned. No indication or error is given if the input ends + * without a final line end. When there are no more trailing bytes to read, + * `readLine()` returns `null`. + * + * Calling `unreadByte()` after `readLine()` will always unread the last byte + * read (possibly a character belonging to the line end) even if that byte is + * not part of the line returned by `readLine()`. + */ async readLine() { + let line = null; + try { + line = await this.readSlice(LF); + } catch (err) { + if (err instanceof Deno.errors.BadResource) { + throw err; + } + let partial; + if (err instanceof PartialReadError) { + partial = err.partial; + assert(partial instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property"); + } + // Don't throw if `readSlice()` failed with `BufferFullError`, instead we + // just return whatever is available and set the `more` flag. + if (!(err instanceof BufferFullError)) { + throw err; + } + partial = err.partial; + // Handle the case where "\r\n" straddles the buffer. + if (!this.#eof && partial && partial.byteLength > 0 && partial[partial.byteLength - 1] === CR) { + // Put the '\r' back on buf and drop it from line. + // Let the next call to ReadLine check for "\r\n". + assert(this.#r > 0, "bufio: tried to rewind past start of buffer"); + this.#r--; + partial = partial.subarray(0, partial.byteLength - 1); + } + if (partial) { + return { + line: partial, + more: !this.#eof + }; + } + } + if (line === null) { + return null; + } + if (line.byteLength === 0) { + return { + line, + more: false + }; + } + if (line[line.byteLength - 1] == LF) { + let drop = 1; + if (line.byteLength > 1 && line[line.byteLength - 2] === CR) { + drop = 2; + } + line = line.subarray(0, line.byteLength - drop); + } + return { + line, + more: false + }; + } + /** `readSlice()` reads until the first occurrence of `delim` in the input, + * returning a slice pointing at the bytes in the buffer. The bytes stop + * being valid at the next read. + * + * If `readSlice()` encounters an error before finding a delimiter, or the + * buffer fills without finding a delimiter, it throws an error with a + * `partial` property that contains the entire buffer. + * + * If `readSlice()` encounters the end of the underlying stream and there are + * any bytes left in the buffer, the rest of the buffer is returned. In other + * words, EOF is always treated as a delimiter. Once the buffer is empty, + * it returns `null`. + * + * Because the data returned from `readSlice()` will be overwritten by the + * next I/O operation, most clients should use `readString()` instead. + */ async readSlice(delim) { + let s = 0; // search start index + let slice; + while(true){ + // Search buffer. + let i = this.#buf.subarray(this.#r + s, this.#w).indexOf(delim); + if (i >= 0) { + i += s; + slice = this.#buf.subarray(this.#r, this.#r + i + 1); + this.#r += i + 1; + break; + } + // EOF? + if (this.#eof) { + if (this.#r === this.#w) { + return null; + } + slice = this.#buf.subarray(this.#r, this.#w); + this.#r = this.#w; + break; + } + // Buffer full? + if (this.buffered() >= this.#buf.byteLength) { + this.#r = this.#w; + // #4521 The internal buffer should not be reused across reads because it causes corruption of data. + const oldbuf = this.#buf; + const newbuf = this.#buf.slice(0); + this.#buf = newbuf; + throw new BufferFullError(oldbuf); + } + s = this.#w - this.#r; // do not rescan area we scanned before + // Buffer is not full. + try { + await this.#fill(); + } catch (err) { + if (err instanceof PartialReadError) { + err.partial = slice; + } else if (err instanceof Error) { + const e = new PartialReadError(); + e.partial = slice; + e.stack = err.stack; + e.message = err.message; + e.cause = err.cause; + throw err; + } + throw err; + } + } + // Handle last byte, if any. + // const i = slice.byteLength - 1; + // if (i >= 0) { + // this.lastByte = slice[i]; + // this.lastCharSize = -1 + // } + return slice; + } + /** `peek()` returns the next `n` bytes without advancing the reader. The + * bytes stop being valid at the next read call. + * + * When the end of the underlying stream is reached, but there are unread + * bytes left in the buffer, those bytes are returned. If there are no bytes + * left in the buffer, it returns `null`. + * + * If an error is encountered before `n` bytes are available, `peek()` throws + * an error with the `partial` property set to a slice of the buffer that + * contains the bytes that were available before the error occurred. + */ async peek(n) { + if (n < 0) { + throw Error("negative count"); + } + let avail = this.#w - this.#r; + while(avail < n && avail < this.#buf.byteLength && !this.#eof){ + try { + await this.#fill(); + } catch (err) { + if (err instanceof PartialReadError) { + err.partial = this.#buf.subarray(this.#r, this.#w); + } else if (err instanceof Error) { + const e = new PartialReadError(); + e.partial = this.#buf.subarray(this.#r, this.#w); + e.stack = err.stack; + e.message = err.message; + e.cause = err.cause; + throw err; + } + throw err; + } + avail = this.#w - this.#r; + } + if (avail === 0 && this.#eof) { + return null; + } else if (avail < n && this.#eof) { + return this.#buf.subarray(this.#r, this.#r + avail); + } else if (avail < n) { + throw new BufferFullError(this.#buf.subarray(this.#r, this.#w)); + } + return this.#buf.subarray(this.#r, this.#r + n); + } +} +class AbstractBufBase { + buf; + usedBufferBytes = 0; + err = null; + constructor(buf){ + this.buf = buf; + } + /** Size returns the size of the underlying buffer in bytes. */ size() { + return this.buf.byteLength; + } + /** Returns how many bytes are unused in the buffer. */ available() { + return this.buf.byteLength - this.usedBufferBytes; + } + /** buffered returns the number of bytes that have been written into the + * current buffer. + */ buffered() { + return this.usedBufferBytes; + } +} +/** BufWriter implements buffering for an deno.Writer object. + * If an error occurs writing to a Writer, no more data will be + * accepted and all subsequent writes, and flush(), will return the error. + * After all data has been written, the client should call the + * flush() method to guarantee all data has been forwarded to + * the underlying deno.Writer. + */ export class BufWriter extends AbstractBufBase { + #writer; + /** return new BufWriter unless writer is BufWriter */ static create(writer, size = DEFAULT_BUF_SIZE) { + return writer instanceof BufWriter ? writer : new BufWriter(writer, size); + } + constructor(writer, size = DEFAULT_BUF_SIZE){ + super(new Uint8Array(size <= 0 ? DEFAULT_BUF_SIZE : size)); + this.#writer = writer; + } + /** Discards any unflushed buffered data, clears any error, and + * resets buffer to write its output to w. + */ reset(w) { + this.err = null; + this.usedBufferBytes = 0; + this.#writer = w; + } + /** Flush writes any buffered data to the underlying io.Writer. */ async flush() { + if (this.err !== null) throw this.err; + if (this.usedBufferBytes === 0) return; + try { + const p = this.buf.subarray(0, this.usedBufferBytes); + let nwritten = 0; + while(nwritten < p.length){ + nwritten += await this.#writer.write(p.subarray(nwritten)); + } + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + this.buf = new Uint8Array(this.buf.length); + this.usedBufferBytes = 0; + } + /** Writes the contents of `data` into the buffer. If the contents won't fully + * fit into the buffer, those bytes that can are copied into the buffer, the + * buffer is the flushed to the writer and the remaining bytes are copied into + * the now empty buffer. + * + * @return the number of bytes written to the buffer. + */ async write(data) { + if (this.err !== null) throw this.err; + if (data.length === 0) return 0; + let totalBytesWritten = 0; + let numBytesWritten = 0; + while(data.byteLength > this.available()){ + if (this.buffered() === 0) { + // Large write, empty buffer. + // Write directly from data to avoid copy. + try { + numBytesWritten = await this.#writer.write(data); + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + } else { + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + await this.flush(); + } + totalBytesWritten += numBytesWritten; + data = data.subarray(numBytesWritten); + } + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + totalBytesWritten += numBytesWritten; + return totalBytesWritten; + } +} +/** BufWriterSync implements buffering for a deno.WriterSync object. + * If an error occurs writing to a WriterSync, no more data will be + * accepted and all subsequent writes, and flush(), will return the error. + * After all data has been written, the client should call the + * flush() method to guarantee all data has been forwarded to + * the underlying deno.WriterSync. + */ export class BufWriterSync extends AbstractBufBase { + #writer; + /** return new BufWriterSync unless writer is BufWriterSync */ static create(writer, size = DEFAULT_BUF_SIZE) { + return writer instanceof BufWriterSync ? writer : new BufWriterSync(writer, size); + } + constructor(writer, size = DEFAULT_BUF_SIZE){ + super(new Uint8Array(size <= 0 ? DEFAULT_BUF_SIZE : size)); + this.#writer = writer; + } + /** Discards any unflushed buffered data, clears any error, and + * resets buffer to write its output to w. + */ reset(w) { + this.err = null; + this.usedBufferBytes = 0; + this.#writer = w; + } + /** Flush writes any buffered data to the underlying io.WriterSync. */ flush() { + if (this.err !== null) throw this.err; + if (this.usedBufferBytes === 0) return; + try { + const p = this.buf.subarray(0, this.usedBufferBytes); + let nwritten = 0; + while(nwritten < p.length){ + nwritten += this.#writer.writeSync(p.subarray(nwritten)); + } + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + this.buf = new Uint8Array(this.buf.length); + this.usedBufferBytes = 0; + } + /** Writes the contents of `data` into the buffer. If the contents won't fully + * fit into the buffer, those bytes that can are copied into the buffer, the + * buffer is the flushed to the writer and the remaining bytes are copied into + * the now empty buffer. + * + * @return the number of bytes written to the buffer. + */ writeSync(data) { + if (this.err !== null) throw this.err; + if (data.length === 0) return 0; + let totalBytesWritten = 0; + let numBytesWritten = 0; + while(data.byteLength > this.available()){ + if (this.buffered() === 0) { + // Large write, empty buffer. + // Write directly from data to avoid copy. + try { + numBytesWritten = this.#writer.writeSync(data); + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + } else { + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + this.flush(); + } + totalBytesWritten += numBytesWritten; + data = data.subarray(numBytesWritten); + } + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + totalBytesWritten += numBytesWritten; + return totalBytesWritten; + } +} +/** Generate longest proper prefix which is also suffix array. */ function createLPS(pat) { + const lps = new Uint8Array(pat.length); + lps[0] = 0; + let prefixEnd = 0; + let i = 1; + while(i < lps.length){ + if (pat[i] == pat[prefixEnd]) { + prefixEnd++; + lps[i] = prefixEnd; + i++; + } else if (prefixEnd === 0) { + lps[i] = 0; + i++; + } else { + prefixEnd = lps[prefixEnd - 1]; + } + } + return lps; +} +/** Read delimited bytes from a Reader. */ export async function* readDelim(reader, delim) { + // Avoid unicode problems + const delimLen = delim.length; + const delimLPS = createLPS(delim); + const chunks = new BytesList(); + const bufSize = Math.max(1024, delimLen + 1); + // Modified KMP + let inspectIndex = 0; + let matchIndex = 0; + while(true){ + const inspectArr = new Uint8Array(bufSize); + const result = await reader.read(inspectArr); + if (result === null) { + // Yield last chunk. + yield chunks.concat(); + return; + } else if (result < 0) { + // Discard all remaining and silently fail. + return; + } + chunks.add(inspectArr, 0, result); + let localIndex = 0; + while(inspectIndex < chunks.size()){ + if (inspectArr[localIndex] === delim[matchIndex]) { + inspectIndex++; + localIndex++; + matchIndex++; + if (matchIndex === delimLen) { + // Full match + const matchEnd = inspectIndex - delimLen; + const readyBytes = chunks.slice(0, matchEnd); + yield readyBytes; + // Reset match, different from KMP. + chunks.shift(inspectIndex); + inspectIndex = 0; + matchIndex = 0; + } + } else { + if (matchIndex === 0) { + inspectIndex++; + localIndex++; + } else { + matchIndex = delimLPS[matchIndex - 1]; + } + } + } + } +} +/** Read delimited strings from a Reader. */ export async function* readStringDelim(reader, delim, decoderOpts) { + const encoder = new TextEncoder(); + const decoder = new TextDecoder(decoderOpts?.encoding, decoderOpts); + for await (const chunk of readDelim(reader, encoder.encode(delim))){ + yield decoder.decode(chunk); + } +} +/** Read strings line-by-line from a Reader. */ export async function* readLines(reader, decoderOpts) { + const bufReader = new BufReader(reader); + let chunks = []; + const decoder = new TextDecoder(decoderOpts?.encoding, decoderOpts); + while(true){ + const res = await bufReader.readLine(); + if (!res) { + if (chunks.length > 0) { + yield decoder.decode(concat(...chunks)); + } + break; + } + chunks.push(res.line); + if (!res.more) { + yield decoder.decode(concat(...chunks)); + chunks = []; + } + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2lvL2J1ZmZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL191dGlsL2Fzc2VydC50c1wiO1xuaW1wb3J0IHsgQnl0ZXNMaXN0IH0gZnJvbSBcIi4uL2J5dGVzL2J5dGVzX2xpc3QudHNcIjtcbmltcG9ydCB7IGNvbmNhdCwgY29weSB9IGZyb20gXCIuLi9ieXRlcy9tb2QudHNcIjtcbmltcG9ydCB0eXBlIHsgUmVhZGVyLCBSZWFkZXJTeW5jLCBXcml0ZXIsIFdyaXRlclN5bmMgfSBmcm9tIFwiLi90eXBlcy5kLnRzXCI7XG5cbi8vIE1JTl9SRUFEIGlzIHRoZSBtaW5pbXVtIEFycmF5QnVmZmVyIHNpemUgcGFzc2VkIHRvIGEgcmVhZCBjYWxsIGJ5XG4vLyBidWZmZXIuUmVhZEZyb20uIEFzIGxvbmcgYXMgdGhlIEJ1ZmZlciBoYXMgYXQgbGVhc3QgTUlOX1JFQUQgYnl0ZXMgYmV5b25kXG4vLyB3aGF0IGlzIHJlcXVpcmVkIHRvIGhvbGQgdGhlIGNvbnRlbnRzIG9mIHIsIHJlYWRGcm9tKCkgd2lsbCBub3QgZ3JvdyB0aGVcbi8vIHVuZGVybHlpbmcgYnVmZmVyLlxuY29uc3QgTUlOX1JFQUQgPSAzMiAqIDEwMjQ7XG5jb25zdCBNQVhfU0laRSA9IDIgKiogMzIgLSAyO1xuXG4vKiogQSB2YXJpYWJsZS1zaXplZCBidWZmZXIgb2YgYnl0ZXMgd2l0aCBgcmVhZCgpYCBhbmQgYHdyaXRlKClgIG1ldGhvZHMuXG4gKlxuICogQnVmZmVyIGlzIGFsbW9zdCBhbHdheXMgdXNlZCB3aXRoIHNvbWUgSS9PIGxpa2UgZmlsZXMgYW5kIHNvY2tldHMuIEl0IGFsbG93c1xuICogb25lIHRvIGJ1ZmZlciB1cCBhIGRvd25sb2FkIGZyb20gYSBzb2NrZXQuIEJ1ZmZlciBncm93cyBhbmQgc2hyaW5rcyBhc1xuICogbmVjZXNzYXJ5LlxuICpcbiAqIEJ1ZmZlciBpcyBOT1QgdGhlIHNhbWUgdGhpbmcgYXMgTm9kZSdzIEJ1ZmZlci4gTm9kZSdzIEJ1ZmZlciB3YXMgY3JlYXRlZCBpblxuICogMjAwOSBiZWZvcmUgSmF2YVNjcmlwdCBoYWQgdGhlIGNvbmNlcHQgb2YgQXJyYXlCdWZmZXJzLiBJdCdzIHNpbXBseSBhXG4gKiBub24tc3RhbmRhcmQgQXJyYXlCdWZmZXIuXG4gKlxuICogQXJyYXlCdWZmZXIgaXMgYSBmaXhlZCBtZW1vcnkgYWxsb2NhdGlvbi4gQnVmZmVyIGlzIGltcGxlbWVudGVkIG9uIHRvcCBvZlxuICogQXJyYXlCdWZmZXIuXG4gKlxuICogQmFzZWQgb24gW0dvIEJ1ZmZlcl0oaHR0cHM6Ly9nb2xhbmcub3JnL3BrZy9ieXRlcy8jQnVmZmVyKS4gKi9cblxuZXhwb3J0IGNsYXNzIEJ1ZmZlciB7XG4gICNidWY6IFVpbnQ4QXJyYXk7IC8vIGNvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYnVmW29mZiA6IGxlbihidWYpXVxuICAjb2ZmID0gMDsgLy8gcmVhZCBhdCBidWZbb2ZmXSwgd3JpdGUgYXQgYnVmW2J1Zi5ieXRlTGVuZ3RoXVxuXG4gIGNvbnN0cnVjdG9yKGFiPzogQXJyYXlCdWZmZXJMaWtlIHwgQXJyYXlMaWtlPG51bWJlcj4pIHtcbiAgICB0aGlzLiNidWYgPSBhYiA9PT0gdW5kZWZpbmVkID8gbmV3IFVpbnQ4QXJyYXkoMCkgOiBuZXcgVWludDhBcnJheShhYik7XG4gIH1cblxuICAvKiogUmV0dXJucyBhIHNsaWNlIGhvbGRpbmcgdGhlIHVucmVhZCBwb3J0aW9uIG9mIHRoZSBidWZmZXIuXG4gICAqXG4gICAqIFRoZSBzbGljZSBpcyB2YWxpZCBmb3IgdXNlIG9ubHkgdW50aWwgdGhlIG5leHQgYnVmZmVyIG1vZGlmaWNhdGlvbiAodGhhdFxuICAgKiBpcywgb25seSB1bnRpbCB0aGUgbmV4dCBjYWxsIHRvIGEgbWV0aG9kIGxpa2UgYHJlYWQoKWAsIGB3cml0ZSgpYCxcbiAgICogYHJlc2V0KClgLCBvciBgdHJ1bmNhdGUoKWApLiBJZiBgb3B0aW9ucy5jb3B5YCBpcyBmYWxzZSB0aGUgc2xpY2UgYWxpYXNlcyB0aGUgYnVmZmVyIGNvbnRlbnQgYXRcbiAgICogbGVhc3QgdW50aWwgdGhlIG5leHQgYnVmZmVyIG1vZGlmaWNhdGlvbiwgc28gaW1tZWRpYXRlIGNoYW5nZXMgdG8gdGhlXG4gICAqIHNsaWNlIHdpbGwgYWZmZWN0IHRoZSByZXN1bHQgb2YgZnV0dXJlIHJlYWRzLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBEZWZhdWx0cyB0byBgeyBjb3B5OiB0cnVlIH1gXG4gICAqL1xuICBieXRlcyhvcHRpb25zID0geyBjb3B5OiB0cnVlIH0pOiBVaW50OEFycmF5IHtcbiAgICBpZiAob3B0aW9ucy5jb3B5ID09PSBmYWxzZSkgcmV0dXJuIHRoaXMuI2J1Zi5zdWJhcnJheSh0aGlzLiNvZmYpO1xuICAgIHJldHVybiB0aGlzLiNidWYuc2xpY2UodGhpcy4jb2ZmKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHVucmVhZCBwb3J0aW9uIG9mIHRoZSBidWZmZXIgaXMgZW1wdHkuICovXG4gIGVtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLiNidWYuYnl0ZUxlbmd0aCA8PSB0aGlzLiNvZmY7XG4gIH1cblxuICAvKiogQSByZWFkIG9ubHkgbnVtYmVyIG9mIGJ5dGVzIG9mIHRoZSB1bnJlYWQgcG9ydGlvbiBvZiB0aGUgYnVmZmVyLiAqL1xuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuI2J1Zi5ieXRlTGVuZ3RoIC0gdGhpcy4jb2ZmO1xuICB9XG5cbiAgLyoqIFRoZSByZWFkIG9ubHkgY2FwYWNpdHkgb2YgdGhlIGJ1ZmZlcidzIHVuZGVybHlpbmcgYnl0ZSBzbGljZSwgdGhhdCBpcyxcbiAgICogdGhlIHRvdGFsIHNwYWNlIGFsbG9jYXRlZCBmb3IgdGhlIGJ1ZmZlcidzIGRhdGEuICovXG4gIGdldCBjYXBhY2l0eSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLiNidWYuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gIH1cblxuICAvKiogRGlzY2FyZHMgYWxsIGJ1dCB0aGUgZmlyc3QgYG5gIHVucmVhZCBieXRlcyBmcm9tIHRoZSBidWZmZXIgYnV0XG4gICAqIGNvbnRpbnVlcyB0byB1c2UgdGhlIHNhbWUgYWxsb2NhdGVkIHN0b3JhZ2UuIEl0IHRocm93cyBpZiBgbmAgaXNcbiAgICogbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlci4gKi9cbiAgdHJ1bmNhdGUobjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG4gPCAwIHx8IG4gPiB0aGlzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgRXJyb3IoXCJieXRlcy5CdWZmZXI6IHRydW5jYXRpb24gb3V0IG9mIHJhbmdlXCIpO1xuICAgIH1cbiAgICB0aGlzLiNyZXNsaWNlKHRoaXMuI29mZiArIG4pO1xuICB9XG5cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy4jcmVzbGljZSgwKTtcbiAgICB0aGlzLiNvZmYgPSAwO1xuICB9XG5cbiAgI3RyeUdyb3dCeVJlc2xpY2UobjogbnVtYmVyKSB7XG4gICAgY29uc3QgbCA9IHRoaXMuI2J1Zi5ieXRlTGVuZ3RoO1xuICAgIGlmIChuIDw9IHRoaXMuY2FwYWNpdHkgLSBsKSB7XG4gICAgICB0aGlzLiNyZXNsaWNlKGwgKyBuKTtcbiAgICAgIHJldHVybiBsO1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAjcmVzbGljZShsZW46IG51bWJlcikge1xuICAgIGFzc2VydChsZW4gPD0gdGhpcy4jYnVmLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICB0aGlzLiNidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLiNidWYuYnVmZmVyLCAwLCBsZW4pO1xuICB9XG5cbiAgLyoqIFJlYWRzIHRoZSBuZXh0IGBwLmxlbmd0aGAgYnl0ZXMgZnJvbSB0aGUgYnVmZmVyIG9yIHVudGlsIHRoZSBidWZmZXIgaXNcbiAgICogZHJhaW5lZC4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuIElmIHRoZSBidWZmZXIgaGFzIG5vIGRhdGEgdG9cbiAgICogcmV0dXJuLCB0aGUgcmV0dXJuIGlzIEVPRiAoYG51bGxgKS4gKi9cbiAgcmVhZFN5bmMocDogVWludDhBcnJheSk6IG51bWJlciB8IG51bGwge1xuICAgIGlmICh0aGlzLmVtcHR5KCkpIHtcbiAgICAgIC8vIEJ1ZmZlciBpcyBlbXB0eSwgcmVzZXQgdG8gcmVjb3ZlciBzcGFjZS5cbiAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgIGlmIChwLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gdGhpcyBlZGdlIGNhc2UgaXMgdGVzdGVkIGluICdidWZmZXJSZWFkRW1wdHlBdEVPRicgdGVzdFxuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBucmVhZCA9IGNvcHkodGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI29mZiksIHApO1xuICAgIHRoaXMuI29mZiArPSBucmVhZDtcbiAgICByZXR1cm4gbnJlYWQ7XG4gIH1cblxuICAvKiogUmVhZHMgdGhlIG5leHQgYHAubGVuZ3RoYCBieXRlcyBmcm9tIHRoZSBidWZmZXIgb3IgdW50aWwgdGhlIGJ1ZmZlciBpc1xuICAgKiBkcmFpbmVkLiBSZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuIElmIHRoZSBidWZmZXIgaGFzIG5vXG4gICAqIGRhdGEgdG8gcmV0dXJuLCByZXNvbHZlcyB0byBFT0YgKGBudWxsYCkuXG4gICAqXG4gICAqIE5PVEU6IFRoaXMgbWV0aG9kcyByZWFkcyBieXRlcyBzeW5jaHJvbm91c2x5OyBpdCdzIHByb3ZpZGVkIGZvclxuICAgKiBjb21wYXRpYmlsaXR5IHdpdGggYFJlYWRlcmAgaW50ZXJmYWNlcy5cbiAgICovXG4gIHJlYWQocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgIGNvbnN0IHJyID0gdGhpcy5yZWFkU3luYyhwKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJyKTtcbiAgfVxuXG4gIHdyaXRlU3luYyhwOiBVaW50OEFycmF5KTogbnVtYmVyIHtcbiAgICBjb25zdCBtID0gdGhpcy4jZ3JvdyhwLmJ5dGVMZW5ndGgpO1xuICAgIHJldHVybiBjb3B5KHAsIHRoaXMuI2J1ZiwgbSk7XG4gIH1cblxuICAvKiogTk9URTogVGhpcyBtZXRob2RzIHdyaXRlcyBieXRlcyBzeW5jaHJvbm91c2x5OyBpdCdzIHByb3ZpZGVkIGZvclxuICAgKiBjb21wYXRpYmlsaXR5IHdpdGggYFdyaXRlcmAgaW50ZXJmYWNlLiAqL1xuICB3cml0ZShwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBuID0gdGhpcy53cml0ZVN5bmMocCk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuKTtcbiAgfVxuXG4gICNncm93KG46IG51bWJlcikge1xuICAgIGNvbnN0IG0gPSB0aGlzLmxlbmd0aDtcbiAgICAvLyBJZiBidWZmZXIgaXMgZW1wdHksIHJlc2V0IHRvIHJlY292ZXIgc3BhY2UuXG4gICAgaWYgKG0gPT09IDAgJiYgdGhpcy4jb2ZmICE9PSAwKSB7XG4gICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuICAgIC8vIEZhc3Q6IFRyeSB0byBncm93IGJ5IG1lYW5zIG9mIGEgcmVzbGljZS5cbiAgICBjb25zdCBpID0gdGhpcy4jdHJ5R3Jvd0J5UmVzbGljZShuKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gICAgY29uc3QgYyA9IHRoaXMuY2FwYWNpdHk7XG4gICAgaWYgKG4gPD0gTWF0aC5mbG9vcihjIC8gMikgLSBtKSB7XG4gICAgICAvLyBXZSBjYW4gc2xpZGUgdGhpbmdzIGRvd24gaW5zdGVhZCBvZiBhbGxvY2F0aW5nIGEgbmV3XG4gICAgICAvLyBBcnJheUJ1ZmZlci4gV2Ugb25seSBuZWVkIG0rbiA8PSBjIHRvIHNsaWRlLCBidXRcbiAgICAgIC8vIHdlIGluc3RlYWQgbGV0IGNhcGFjaXR5IGdldCB0d2ljZSBhcyBsYXJnZSBzbyB3ZVxuICAgICAgLy8gZG9uJ3Qgc3BlbmQgYWxsIG91ciB0aW1lIGNvcHlpbmcuXG4gICAgICBjb3B5KHRoaXMuI2J1Zi5zdWJhcnJheSh0aGlzLiNvZmYpLCB0aGlzLiNidWYpO1xuICAgIH0gZWxzZSBpZiAoYyArIG4gPiBNQVhfU0laRSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIGJ1ZmZlciBjYW5ub3QgYmUgZ3Jvd24gYmV5b25kIHRoZSBtYXhpbXVtIHNpemUuXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBOb3QgZW5vdWdoIHNwYWNlIGFueXdoZXJlLCB3ZSBuZWVkIHRvIGFsbG9jYXRlLlxuICAgICAgY29uc3QgYnVmID0gbmV3IFVpbnQ4QXJyYXkoTWF0aC5taW4oMiAqIGMgKyBuLCBNQVhfU0laRSkpO1xuICAgICAgY29weSh0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jb2ZmKSwgYnVmKTtcbiAgICAgIHRoaXMuI2J1ZiA9IGJ1ZjtcbiAgICB9XG4gICAgLy8gUmVzdG9yZSB0aGlzLiNvZmYgYW5kIGxlbih0aGlzLiNidWYpLlxuICAgIHRoaXMuI29mZiA9IDA7XG4gICAgdGhpcy4jcmVzbGljZShNYXRoLm1pbihtICsgbiwgTUFYX1NJWkUpKTtcbiAgICByZXR1cm4gbTtcbiAgfVxuXG4gIC8qKiBHcm93cyB0aGUgYnVmZmVyJ3MgY2FwYWNpdHksIGlmIG5lY2Vzc2FyeSwgdG8gZ3VhcmFudGVlIHNwYWNlIGZvclxuICAgKiBhbm90aGVyIGBuYCBieXRlcy4gQWZ0ZXIgYC5ncm93KG4pYCwgYXQgbGVhc3QgYG5gIGJ5dGVzIGNhbiBiZSB3cml0dGVuIHRvXG4gICAqIHRoZSBidWZmZXIgd2l0aG91dCBhbm90aGVyIGFsbG9jYXRpb24uIElmIGBuYCBpcyBuZWdhdGl2ZSwgYC5ncm93KClgIHdpbGxcbiAgICogdGhyb3cuIElmIHRoZSBidWZmZXIgY2FuJ3QgZ3JvdyBpdCB3aWxsIHRocm93IGFuIGVycm9yLlxuICAgKlxuICAgKiBCYXNlZCBvbiBHbyBMYW5nJ3NcbiAgICogW0J1ZmZlci5Hcm93XShodHRwczovL2dvbGFuZy5vcmcvcGtnL2J5dGVzLyNCdWZmZXIuR3JvdykuICovXG4gIGdyb3cobjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKG4gPCAwKSB7XG4gICAgICB0aHJvdyBFcnJvcihcIkJ1ZmZlci5ncm93OiBuZWdhdGl2ZSBjb3VudFwiKTtcbiAgICB9XG4gICAgY29uc3QgbSA9IHRoaXMuI2dyb3cobik7XG4gICAgdGhpcy4jcmVzbGljZShtKTtcbiAgfVxuXG4gIC8qKiBSZWFkcyBkYXRhIGZyb20gYHJgIHVudGlsIEVPRiAoYG51bGxgKSBhbmQgYXBwZW5kcyBpdCB0byB0aGUgYnVmZmVyLFxuICAgKiBncm93aW5nIHRoZSBidWZmZXIgYXMgbmVlZGVkLiBJdCByZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXG4gICAqIElmIHRoZSBidWZmZXIgYmVjb21lcyB0b28gbGFyZ2UsIGAucmVhZEZyb20oKWAgd2lsbCByZWplY3Qgd2l0aCBhbiBlcnJvci5cbiAgICpcbiAgICogQmFzZWQgb24gR28gTGFuZydzXG4gICAqIFtCdWZmZXIuUmVhZEZyb21dKGh0dHBzOi8vZ29sYW5nLm9yZy9wa2cvYnl0ZXMvI0J1ZmZlci5SZWFkRnJvbSkuICovXG4gIGFzeW5jIHJlYWRGcm9tKHI6IFJlYWRlcik6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgbGV0IG4gPSAwO1xuICAgIGNvbnN0IHRtcCA9IG5ldyBVaW50OEFycmF5KE1JTl9SRUFEKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3Qgc2hvdWxkR3JvdyA9IHRoaXMuY2FwYWNpdHkgLSB0aGlzLmxlbmd0aCA8IE1JTl9SRUFEO1xuICAgICAgLy8gcmVhZCBpbnRvIHRtcCBidWZmZXIgaWYgdGhlcmUncyBub3QgZW5vdWdoIHJvb21cbiAgICAgIC8vIG90aGVyd2lzZSByZWFkIGRpcmVjdGx5IGludG8gdGhlIGludGVybmFsIGJ1ZmZlclxuICAgICAgY29uc3QgYnVmID0gc2hvdWxkR3Jvd1xuICAgICAgICA/IHRtcFxuICAgICAgICA6IG5ldyBVaW50OEFycmF5KHRoaXMuI2J1Zi5idWZmZXIsIHRoaXMubGVuZ3RoKTtcblxuICAgICAgY29uc3QgbnJlYWQgPSBhd2FpdCByLnJlYWQoYnVmKTtcbiAgICAgIGlmIChucmVhZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbjtcbiAgICAgIH1cblxuICAgICAgLy8gd3JpdGUgd2lsbCBncm93IGlmIG5lZWRlZFxuICAgICAgaWYgKHNob3VsZEdyb3cpIHRoaXMud3JpdGVTeW5jKGJ1Zi5zdWJhcnJheSgwLCBucmVhZCkpO1xuICAgICAgZWxzZSB0aGlzLiNyZXNsaWNlKHRoaXMubGVuZ3RoICsgbnJlYWQpO1xuXG4gICAgICBuICs9IG5yZWFkO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZWFkcyBkYXRhIGZyb20gYHJgIHVudGlsIEVPRiAoYG51bGxgKSBhbmQgYXBwZW5kcyBpdCB0byB0aGUgYnVmZmVyLFxuICAgKiBncm93aW5nIHRoZSBidWZmZXIgYXMgbmVlZGVkLiBJdCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZC4gSWYgdGhlXG4gICAqIGJ1ZmZlciBiZWNvbWVzIHRvbyBsYXJnZSwgYC5yZWFkRnJvbVN5bmMoKWAgd2lsbCB0aHJvdyBhbiBlcnJvci5cbiAgICpcbiAgICogQmFzZWQgb24gR28gTGFuZydzXG4gICAqIFtCdWZmZXIuUmVhZEZyb21dKGh0dHBzOi8vZ29sYW5nLm9yZy9wa2cvYnl0ZXMvI0J1ZmZlci5SZWFkRnJvbSkuICovXG4gIHJlYWRGcm9tU3luYyhyOiBSZWFkZXJTeW5jKTogbnVtYmVyIHtcbiAgICBsZXQgbiA9IDA7XG4gICAgY29uc3QgdG1wID0gbmV3IFVpbnQ4QXJyYXkoTUlOX1JFQUQpO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCBzaG91bGRHcm93ID0gdGhpcy5jYXBhY2l0eSAtIHRoaXMubGVuZ3RoIDwgTUlOX1JFQUQ7XG4gICAgICAvLyByZWFkIGludG8gdG1wIGJ1ZmZlciBpZiB0aGVyZSdzIG5vdCBlbm91Z2ggcm9vbVxuICAgICAgLy8gb3RoZXJ3aXNlIHJlYWQgZGlyZWN0bHkgaW50byB0aGUgaW50ZXJuYWwgYnVmZmVyXG4gICAgICBjb25zdCBidWYgPSBzaG91bGRHcm93XG4gICAgICAgID8gdG1wXG4gICAgICAgIDogbmV3IFVpbnQ4QXJyYXkodGhpcy4jYnVmLmJ1ZmZlciwgdGhpcy5sZW5ndGgpO1xuXG4gICAgICBjb25zdCBucmVhZCA9IHIucmVhZFN5bmMoYnVmKTtcbiAgICAgIGlmIChucmVhZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbjtcbiAgICAgIH1cblxuICAgICAgLy8gd3JpdGUgd2lsbCBncm93IGlmIG5lZWRlZFxuICAgICAgaWYgKHNob3VsZEdyb3cpIHRoaXMud3JpdGVTeW5jKGJ1Zi5zdWJhcnJheSgwLCBucmVhZCkpO1xuICAgICAgZWxzZSB0aGlzLiNyZXNsaWNlKHRoaXMubGVuZ3RoICsgbnJlYWQpO1xuXG4gICAgICBuICs9IG5yZWFkO1xuICAgIH1cbiAgfVxufVxuXG5jb25zdCBERUZBVUxUX0JVRl9TSVpFID0gNDA5NjtcbmNvbnN0IE1JTl9CVUZfU0laRSA9IDE2O1xuY29uc3QgTUFYX0NPTlNFQ1VUSVZFX0VNUFRZX1JFQURTID0gMTAwO1xuY29uc3QgQ1IgPSBcIlxcclwiLmNoYXJDb2RlQXQoMCk7XG5jb25zdCBMRiA9IFwiXFxuXCIuY2hhckNvZGVBdCgwKTtcblxuZXhwb3J0IGNsYXNzIEJ1ZmZlckZ1bGxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgbmFtZSA9IFwiQnVmZmVyRnVsbEVycm9yXCI7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXJ0aWFsOiBVaW50OEFycmF5KSB7XG4gICAgc3VwZXIoXCJCdWZmZXIgZnVsbFwiKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFydGlhbFJlYWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgbmFtZSA9IFwiUGFydGlhbFJlYWRFcnJvclwiO1xuICBwYXJ0aWFsPzogVWludDhBcnJheTtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoXCJFbmNvdW50ZXJlZCBVbmV4cGVjdGVkRW9mLCBkYXRhIG9ubHkgcGFydGlhbGx5IHJlYWRcIik7XG4gIH1cbn1cblxuLyoqIFJlc3VsdCB0eXBlIHJldHVybmVkIGJ5IG9mIEJ1ZlJlYWRlci5yZWFkTGluZSgpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWFkTGluZVJlc3VsdCB7XG4gIGxpbmU6IFVpbnQ4QXJyYXk7XG4gIG1vcmU6IGJvb2xlYW47XG59XG5cbi8qKiBCdWZSZWFkZXIgaW1wbGVtZW50cyBidWZmZXJpbmcgZm9yIGEgUmVhZGVyIG9iamVjdC4gKi9cbmV4cG9ydCBjbGFzcyBCdWZSZWFkZXIgaW1wbGVtZW50cyBSZWFkZXIge1xuICAjYnVmITogVWludDhBcnJheTtcbiAgI3JkITogUmVhZGVyOyAvLyBSZWFkZXIgcHJvdmlkZWQgYnkgY2FsbGVyLlxuICAjciA9IDA7IC8vIGJ1ZiByZWFkIHBvc2l0aW9uLlxuICAjdyA9IDA7IC8vIGJ1ZiB3cml0ZSBwb3NpdGlvbi5cbiAgI2VvZiA9IGZhbHNlO1xuICAvLyBwcml2YXRlIGxhc3RCeXRlOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbGFzdENoYXJTaXplOiBudW1iZXI7XG5cbiAgLyoqIHJldHVybiBuZXcgQnVmUmVhZGVyIHVubGVzcyByIGlzIEJ1ZlJlYWRlciAqL1xuICBzdGF0aWMgY3JlYXRlKHI6IFJlYWRlciwgc2l6ZTogbnVtYmVyID0gREVGQVVMVF9CVUZfU0laRSk6IEJ1ZlJlYWRlciB7XG4gICAgcmV0dXJuIHIgaW5zdGFuY2VvZiBCdWZSZWFkZXIgPyByIDogbmV3IEJ1ZlJlYWRlcihyLCBzaXplKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHJkOiBSZWFkZXIsIHNpemU6IG51bWJlciA9IERFRkFVTFRfQlVGX1NJWkUpIHtcbiAgICBpZiAoc2l6ZSA8IE1JTl9CVUZfU0laRSkge1xuICAgICAgc2l6ZSA9IE1JTl9CVUZfU0laRTtcbiAgICB9XG4gICAgdGhpcy4jcmVzZXQobmV3IFVpbnQ4QXJyYXkoc2l6ZSksIHJkKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlciBpbiBieXRlcy4gKi9cbiAgc2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLiNidWYuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIGJ1ZmZlcmVkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuI3cgLSB0aGlzLiNyO1xuICB9XG5cbiAgLy8gUmVhZHMgYSBuZXcgY2h1bmsgaW50byB0aGUgYnVmZmVyLlxuICAjZmlsbCA9IGFzeW5jICgpID0+IHtcbiAgICAvLyBTbGlkZSBleGlzdGluZyBkYXRhIHRvIGJlZ2lubmluZy5cbiAgICBpZiAodGhpcy4jciA+IDApIHtcbiAgICAgIHRoaXMuI2J1Zi5jb3B5V2l0aGluKDAsIHRoaXMuI3IsIHRoaXMuI3cpO1xuICAgICAgdGhpcy4jdyAtPSB0aGlzLiNyO1xuICAgICAgdGhpcy4jciA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuI3cgPj0gdGhpcy4jYnVmLmJ5dGVMZW5ndGgpIHtcbiAgICAgIHRocm93IEVycm9yKFwiYnVmaW86IHRyaWVkIHRvIGZpbGwgZnVsbCBidWZmZXJcIik7XG4gICAgfVxuXG4gICAgLy8gUmVhZCBuZXcgZGF0YTogdHJ5IGEgbGltaXRlZCBudW1iZXIgb2YgdGltZXMuXG4gICAgZm9yIChsZXQgaSA9IE1BWF9DT05TRUNVVElWRV9FTVBUWV9SRUFEUzsgaSA+IDA7IGktLSkge1xuICAgICAgY29uc3QgcnIgPSBhd2FpdCB0aGlzLiNyZC5yZWFkKHRoaXMuI2J1Zi5zdWJhcnJheSh0aGlzLiN3KSk7XG4gICAgICBpZiAocnIgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy4jZW9mID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXNzZXJ0KHJyID49IDAsIFwibmVnYXRpdmUgcmVhZFwiKTtcbiAgICAgIHRoaXMuI3cgKz0gcnI7XG4gICAgICBpZiAocnIgPiAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTm8gcHJvZ3Jlc3MgYWZ0ZXIgJHtNQVhfQ09OU0VDVVRJVkVfRU1QVFlfUkVBRFN9IHJlYWQoKSBjYWxsc2AsXG4gICAgKTtcbiAgfTtcblxuICAvKiogRGlzY2FyZHMgYW55IGJ1ZmZlcmVkIGRhdGEsIHJlc2V0cyBhbGwgc3RhdGUsIGFuZCBzd2l0Y2hlc1xuICAgKiB0aGUgYnVmZmVyZWQgcmVhZGVyIHRvIHJlYWQgZnJvbSByLlxuICAgKi9cbiAgcmVzZXQocjogUmVhZGVyKTogdm9pZCB7XG4gICAgdGhpcy4jcmVzZXQodGhpcy4jYnVmLCByKTtcbiAgfVxuXG4gICNyZXNldCA9IChidWY6IFVpbnQ4QXJyYXksIHJkOiBSZWFkZXIpOiB2b2lkID0+IHtcbiAgICB0aGlzLiNidWYgPSBidWY7XG4gICAgdGhpcy4jcmQgPSByZDtcbiAgICB0aGlzLiNlb2YgPSBmYWxzZTtcbiAgICAvLyB0aGlzLmxhc3RCeXRlID0gLTE7XG4gICAgLy8gdGhpcy5sYXN0Q2hhclNpemUgPSAtMTtcbiAgfTtcblxuICAvKiogcmVhZHMgZGF0YSBpbnRvIHAuXG4gICAqIEl0IHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZWFkIGludG8gcC5cbiAgICogVGhlIGJ5dGVzIGFyZSB0YWtlbiBmcm9tIGF0IG1vc3Qgb25lIFJlYWQgb24gdGhlIHVuZGVybHlpbmcgUmVhZGVyLFxuICAgKiBoZW5jZSBuIG1heSBiZSBsZXNzIHRoYW4gbGVuKHApLlxuICAgKiBUbyByZWFkIGV4YWN0bHkgbGVuKHApIGJ5dGVzLCB1c2UgaW8uUmVhZEZ1bGwoYiwgcCkuXG4gICAqL1xuICBhc3luYyByZWFkKHA6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPG51bWJlciB8IG51bGw+IHtcbiAgICBsZXQgcnI6IG51bWJlciB8IG51bGwgPSBwLmJ5dGVMZW5ndGg7XG4gICAgaWYgKHAuYnl0ZUxlbmd0aCA9PT0gMCkgcmV0dXJuIHJyO1xuXG4gICAgaWYgKHRoaXMuI3IgPT09IHRoaXMuI3cpIHtcbiAgICAgIGlmIChwLmJ5dGVMZW5ndGggPj0gdGhpcy4jYnVmLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgLy8gTGFyZ2UgcmVhZCwgZW1wdHkgYnVmZmVyLlxuICAgICAgICAvLyBSZWFkIGRpcmVjdGx5IGludG8gcCB0byBhdm9pZCBjb3B5LlxuICAgICAgICBjb25zdCByciA9IGF3YWl0IHRoaXMuI3JkLnJlYWQocCk7XG4gICAgICAgIGNvbnN0IG5yZWFkID0gcnIgPz8gMDtcbiAgICAgICAgYXNzZXJ0KG5yZWFkID49IDAsIFwibmVnYXRpdmUgcmVhZFwiKTtcbiAgICAgICAgLy8gaWYgKHJyLm5yZWFkID4gMCkge1xuICAgICAgICAvLyAgIHRoaXMubGFzdEJ5dGUgPSBwW3JyLm5yZWFkIC0gMV07XG4gICAgICAgIC8vICAgdGhpcy5sYXN0Q2hhclNpemUgPSAtMTtcbiAgICAgICAgLy8gfVxuICAgICAgICByZXR1cm4gcnI7XG4gICAgICB9XG5cbiAgICAgIC8vIE9uZSByZWFkLlxuICAgICAgLy8gRG8gbm90IHVzZSB0aGlzLmZpbGwsIHdoaWNoIHdpbGwgbG9vcC5cbiAgICAgIHRoaXMuI3IgPSAwO1xuICAgICAgdGhpcy4jdyA9IDA7XG4gICAgICByciA9IGF3YWl0IHRoaXMuI3JkLnJlYWQodGhpcy4jYnVmKTtcbiAgICAgIGlmIChyciA9PT0gMCB8fCByciA9PT0gbnVsbCkgcmV0dXJuIHJyO1xuICAgICAgYXNzZXJ0KHJyID49IDAsIFwibmVnYXRpdmUgcmVhZFwiKTtcbiAgICAgIHRoaXMuI3cgKz0gcnI7XG4gICAgfVxuXG4gICAgLy8gY29weSBhcyBtdWNoIGFzIHdlIGNhblxuICAgIGNvbnN0IGNvcGllZCA9IGNvcHkodGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3cpLCBwLCAwKTtcbiAgICB0aGlzLiNyICs9IGNvcGllZDtcbiAgICAvLyB0aGlzLmxhc3RCeXRlID0gdGhpcy5idWZbdGhpcy5yIC0gMV07XG4gICAgLy8gdGhpcy5sYXN0Q2hhclNpemUgPSAtMTtcbiAgICByZXR1cm4gY29waWVkO1xuICB9XG5cbiAgLyoqIHJlYWRzIGV4YWN0bHkgYHAubGVuZ3RoYCBieXRlcyBpbnRvIGBwYC5cbiAgICpcbiAgICogSWYgc3VjY2Vzc2Z1bCwgYHBgIGlzIHJldHVybmVkLlxuICAgKlxuICAgKiBJZiB0aGUgZW5kIG9mIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLCBhbmQgdGhlcmUgYXJlIG5vIG1vcmVcbiAgICogYnl0ZXMgYXZhaWxhYmxlIGluIHRoZSBidWZmZXIsIGByZWFkRnVsbCgpYCByZXR1cm5zIGBudWxsYCBpbnN0ZWFkLlxuICAgKlxuICAgKiBBbiBlcnJvciBpcyB0aHJvd24gaWYgc29tZSBieXRlcyBjb3VsZCBiZSByZWFkLCBidXQgbm90IGVub3VnaCB0byBmaWxsIGBwYFxuICAgKiBlbnRpcmVseSBiZWZvcmUgdGhlIHVuZGVybHlpbmcgc3RyZWFtIHJlcG9ydGVkIGFuIGVycm9yIG9yIEVPRi4gQW55IGVycm9yXG4gICAqIHRocm93biB3aWxsIGhhdmUgYSBgcGFydGlhbGAgcHJvcGVydHkgdGhhdCBpbmRpY2F0ZXMgdGhlIHNsaWNlIG9mIHRoZVxuICAgKiBidWZmZXIgdGhhdCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZmlsbGVkIHdpdGggZGF0YS5cbiAgICpcbiAgICogUG9ydGVkIGZyb20gaHR0cHM6Ly9nb2xhbmcub3JnL3BrZy9pby8jUmVhZEZ1bGxcbiAgICovXG4gIGFzeW5jIHJlYWRGdWxsKHA6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCBudWxsPiB7XG4gICAgbGV0IGJ5dGVzUmVhZCA9IDA7XG4gICAgd2hpbGUgKGJ5dGVzUmVhZCA8IHAubGVuZ3RoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByciA9IGF3YWl0IHRoaXMucmVhZChwLnN1YmFycmF5KGJ5dGVzUmVhZCkpO1xuICAgICAgICBpZiAocnIgPT09IG51bGwpIHtcbiAgICAgICAgICBpZiAoYnl0ZXNSZWFkID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnRpYWxSZWFkRXJyb3IoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnl0ZXNSZWFkICs9IHJyO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJ0aWFsUmVhZEVycm9yKSB7XG4gICAgICAgICAgZXJyLnBhcnRpYWwgPSBwLnN1YmFycmF5KDAsIGJ5dGVzUmVhZCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBlID0gbmV3IFBhcnRpYWxSZWFkRXJyb3IoKTtcbiAgICAgICAgICBlLnBhcnRpYWwgPSBwLnN1YmFycmF5KDAsIGJ5dGVzUmVhZCk7XG4gICAgICAgICAgZS5zdGFjayA9IGVyci5zdGFjaztcbiAgICAgICAgICBlLm1lc3NhZ2UgPSBlcnIubWVzc2FnZTtcbiAgICAgICAgICBlLmNhdXNlID0gZXJyLmNhdXNlO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwO1xuICB9XG5cbiAgLyoqIFJldHVybnMgdGhlIG5leHQgYnl0ZSBbMCwgMjU1XSBvciBgbnVsbGAuICovXG4gIGFzeW5jIHJlYWRCeXRlKCk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgIHdoaWxlICh0aGlzLiNyID09PSB0aGlzLiN3KSB7XG4gICAgICBpZiAodGhpcy4jZW9mKSByZXR1cm4gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMuI2ZpbGwoKTsgLy8gYnVmZmVyIGlzIGVtcHR5LlxuICAgIH1cbiAgICBjb25zdCBjID0gdGhpcy4jYnVmW3RoaXMuI3JdO1xuICAgIHRoaXMuI3IrKztcbiAgICAvLyB0aGlzLmxhc3RCeXRlID0gYztcbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIC8qKiByZWFkU3RyaW5nKCkgcmVhZHMgdW50aWwgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgZGVsaW0gaW4gdGhlIGlucHV0LFxuICAgKiByZXR1cm5pbmcgYSBzdHJpbmcgY29udGFpbmluZyB0aGUgZGF0YSB1cCB0byBhbmQgaW5jbHVkaW5nIHRoZSBkZWxpbWl0ZXIuXG4gICAqIElmIFJlYWRTdHJpbmcgZW5jb3VudGVycyBhbiBlcnJvciBiZWZvcmUgZmluZGluZyBhIGRlbGltaXRlcixcbiAgICogaXQgcmV0dXJucyB0aGUgZGF0YSByZWFkIGJlZm9yZSB0aGUgZXJyb3IgYW5kIHRoZSBlcnJvciBpdHNlbGZcbiAgICogKG9mdGVuIGBudWxsYCkuXG4gICAqIFJlYWRTdHJpbmcgcmV0dXJucyBlcnIgIT0gbmlsIGlmIGFuZCBvbmx5IGlmIHRoZSByZXR1cm5lZCBkYXRhIGRvZXMgbm90IGVuZFxuICAgKiBpbiBkZWxpbS5cbiAgICogRm9yIHNpbXBsZSB1c2VzLCBhIFNjYW5uZXIgbWF5IGJlIG1vcmUgY29udmVuaWVudC5cbiAgICovXG4gIGFzeW5jIHJlYWRTdHJpbmcoZGVsaW06IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGlmIChkZWxpbS5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkRlbGltaXRlciBzaG91bGQgYmUgYSBzaW5nbGUgY2hhcmFjdGVyXCIpO1xuICAgIH1cbiAgICBjb25zdCBidWZmZXIgPSBhd2FpdCB0aGlzLnJlYWRTbGljZShkZWxpbS5jaGFyQ29kZUF0KDApKTtcbiAgICBpZiAoYnVmZmVyID09PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJ1ZmZlcik7XG4gIH1cblxuICAvKiogYHJlYWRMaW5lKClgIGlzIGEgbG93LWxldmVsIGxpbmUtcmVhZGluZyBwcmltaXRpdmUuIE1vc3QgY2FsbGVycyBzaG91bGRcbiAgICogdXNlIGByZWFkU3RyaW5nKCdcXG4nKWAgaW5zdGVhZCBvciB1c2UgYSBTY2FubmVyLlxuICAgKlxuICAgKiBgcmVhZExpbmUoKWAgdHJpZXMgdG8gcmV0dXJuIGEgc2luZ2xlIGxpbmUsIG5vdCBpbmNsdWRpbmcgdGhlIGVuZC1vZi1saW5lXG4gICAqIGJ5dGVzLiBJZiB0aGUgbGluZSB3YXMgdG9vIGxvbmcgZm9yIHRoZSBidWZmZXIgdGhlbiBgbW9yZWAgaXMgc2V0IGFuZCB0aGVcbiAgICogYmVnaW5uaW5nIG9mIHRoZSBsaW5lIGlzIHJldHVybmVkLiBUaGUgcmVzdCBvZiB0aGUgbGluZSB3aWxsIGJlIHJldHVybmVkXG4gICAqIGZyb20gZnV0dXJlIGNhbGxzLiBgbW9yZWAgd2lsbCBiZSBmYWxzZSB3aGVuIHJldHVybmluZyB0aGUgbGFzdCBmcmFnbWVudFxuICAgKiBvZiB0aGUgbGluZS4gVGhlIHJldHVybmVkIGJ1ZmZlciBpcyBvbmx5IHZhbGlkIHVudGlsIHRoZSBuZXh0IGNhbGwgdG9cbiAgICogYHJlYWRMaW5lKClgLlxuICAgKlxuICAgKiBUaGUgdGV4dCByZXR1cm5lZCBmcm9tIFJlYWRMaW5lIGRvZXMgbm90IGluY2x1ZGUgdGhlIGxpbmUgZW5kIChcIlxcclxcblwiIG9yXG4gICAqIFwiXFxuXCIpLlxuICAgKlxuICAgKiBXaGVuIHRoZSBlbmQgb2YgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGlzIHJlYWNoZWQsIHRoZSBmaW5hbCBieXRlcyBpbiB0aGVcbiAgICogc3RyZWFtIGFyZSByZXR1cm5lZC4gTm8gaW5kaWNhdGlvbiBvciBlcnJvciBpcyBnaXZlbiBpZiB0aGUgaW5wdXQgZW5kc1xuICAgKiB3aXRob3V0IGEgZmluYWwgbGluZSBlbmQuIFdoZW4gdGhlcmUgYXJlIG5vIG1vcmUgdHJhaWxpbmcgYnl0ZXMgdG8gcmVhZCxcbiAgICogYHJlYWRMaW5lKClgIHJldHVybnMgYG51bGxgLlxuICAgKlxuICAgKiBDYWxsaW5nIGB1bnJlYWRCeXRlKClgIGFmdGVyIGByZWFkTGluZSgpYCB3aWxsIGFsd2F5cyB1bnJlYWQgdGhlIGxhc3QgYnl0ZVxuICAgKiByZWFkIChwb3NzaWJseSBhIGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gdGhlIGxpbmUgZW5kKSBldmVuIGlmIHRoYXQgYnl0ZSBpc1xuICAgKiBub3QgcGFydCBvZiB0aGUgbGluZSByZXR1cm5lZCBieSBgcmVhZExpbmUoKWAuXG4gICAqL1xuICBhc3luYyByZWFkTGluZSgpOiBQcm9taXNlPFJlYWRMaW5lUmVzdWx0IHwgbnVsbD4ge1xuICAgIGxldCBsaW5lOiBVaW50OEFycmF5IHwgbnVsbCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgbGluZSA9IGF3YWl0IHRoaXMucmVhZFNsaWNlKExGKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBEZW5vLmVycm9ycy5CYWRSZXNvdXJjZSkge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgICBsZXQgcGFydGlhbDtcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJ0aWFsUmVhZEVycm9yKSB7XG4gICAgICAgIHBhcnRpYWwgPSBlcnIucGFydGlhbDtcbiAgICAgICAgYXNzZXJ0KFxuICAgICAgICAgIHBhcnRpYWwgaW5zdGFuY2VvZiBVaW50OEFycmF5LFxuICAgICAgICAgIFwiYnVmaW86IGNhdWdodCBlcnJvciBmcm9tIGByZWFkU2xpY2UoKWAgd2l0aG91dCBgcGFydGlhbGAgcHJvcGVydHlcIixcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gRG9uJ3QgdGhyb3cgaWYgYHJlYWRTbGljZSgpYCBmYWlsZWQgd2l0aCBgQnVmZmVyRnVsbEVycm9yYCwgaW5zdGVhZCB3ZVxuICAgICAgLy8ganVzdCByZXR1cm4gd2hhdGV2ZXIgaXMgYXZhaWxhYmxlIGFuZCBzZXQgdGhlIGBtb3JlYCBmbGFnLlxuICAgICAgaWYgKCEoZXJyIGluc3RhbmNlb2YgQnVmZmVyRnVsbEVycm9yKSkge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG5cbiAgICAgIHBhcnRpYWwgPSBlcnIucGFydGlhbDtcblxuICAgICAgLy8gSGFuZGxlIHRoZSBjYXNlIHdoZXJlIFwiXFxyXFxuXCIgc3RyYWRkbGVzIHRoZSBidWZmZXIuXG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLiNlb2YgJiYgcGFydGlhbCAmJlxuICAgICAgICBwYXJ0aWFsLmJ5dGVMZW5ndGggPiAwICYmXG4gICAgICAgIHBhcnRpYWxbcGFydGlhbC5ieXRlTGVuZ3RoIC0gMV0gPT09IENSXG4gICAgICApIHtcbiAgICAgICAgLy8gUHV0IHRoZSAnXFxyJyBiYWNrIG9uIGJ1ZiBhbmQgZHJvcCBpdCBmcm9tIGxpbmUuXG4gICAgICAgIC8vIExldCB0aGUgbmV4dCBjYWxsIHRvIFJlYWRMaW5lIGNoZWNrIGZvciBcIlxcclxcblwiLlxuICAgICAgICBhc3NlcnQodGhpcy4jciA+IDAsIFwiYnVmaW86IHRyaWVkIHRvIHJld2luZCBwYXN0IHN0YXJ0IG9mIGJ1ZmZlclwiKTtcbiAgICAgICAgdGhpcy4jci0tO1xuICAgICAgICBwYXJ0aWFsID0gcGFydGlhbC5zdWJhcnJheSgwLCBwYXJ0aWFsLmJ5dGVMZW5ndGggLSAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcnRpYWwpIHtcbiAgICAgICAgcmV0dXJuIHsgbGluZTogcGFydGlhbCwgbW9yZTogIXRoaXMuI2VvZiB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChsaW5lID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAobGluZS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4geyBsaW5lLCBtb3JlOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIGlmIChsaW5lW2xpbmUuYnl0ZUxlbmd0aCAtIDFdID09IExGKSB7XG4gICAgICBsZXQgZHJvcCA9IDE7XG4gICAgICBpZiAobGluZS5ieXRlTGVuZ3RoID4gMSAmJiBsaW5lW2xpbmUuYnl0ZUxlbmd0aCAtIDJdID09PSBDUikge1xuICAgICAgICBkcm9wID0gMjtcbiAgICAgIH1cbiAgICAgIGxpbmUgPSBsaW5lLnN1YmFycmF5KDAsIGxpbmUuYnl0ZUxlbmd0aCAtIGRyb3ApO1xuICAgIH1cbiAgICByZXR1cm4geyBsaW5lLCBtb3JlOiBmYWxzZSB9O1xuICB9XG5cbiAgLyoqIGByZWFkU2xpY2UoKWAgcmVhZHMgdW50aWwgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYGRlbGltYCBpbiB0aGUgaW5wdXQsXG4gICAqIHJldHVybmluZyBhIHNsaWNlIHBvaW50aW5nIGF0IHRoZSBieXRlcyBpbiB0aGUgYnVmZmVyLiBUaGUgYnl0ZXMgc3RvcFxuICAgKiBiZWluZyB2YWxpZCBhdCB0aGUgbmV4dCByZWFkLlxuICAgKlxuICAgKiBJZiBgcmVhZFNsaWNlKClgIGVuY291bnRlcnMgYW4gZXJyb3IgYmVmb3JlIGZpbmRpbmcgYSBkZWxpbWl0ZXIsIG9yIHRoZVxuICAgKiBidWZmZXIgZmlsbHMgd2l0aG91dCBmaW5kaW5nIGEgZGVsaW1pdGVyLCBpdCB0aHJvd3MgYW4gZXJyb3Igd2l0aCBhXG4gICAqIGBwYXJ0aWFsYCBwcm9wZXJ0eSB0aGF0IGNvbnRhaW5zIHRoZSBlbnRpcmUgYnVmZmVyLlxuICAgKlxuICAgKiBJZiBgcmVhZFNsaWNlKClgIGVuY291bnRlcnMgdGhlIGVuZCBvZiB0aGUgdW5kZXJseWluZyBzdHJlYW0gYW5kIHRoZXJlIGFyZVxuICAgKiBhbnkgYnl0ZXMgbGVmdCBpbiB0aGUgYnVmZmVyLCB0aGUgcmVzdCBvZiB0aGUgYnVmZmVyIGlzIHJldHVybmVkLiBJbiBvdGhlclxuICAgKiB3b3JkcywgRU9GIGlzIGFsd2F5cyB0cmVhdGVkIGFzIGEgZGVsaW1pdGVyLiBPbmNlIHRoZSBidWZmZXIgaXMgZW1wdHksXG4gICAqIGl0IHJldHVybnMgYG51bGxgLlxuICAgKlxuICAgKiBCZWNhdXNlIHRoZSBkYXRhIHJldHVybmVkIGZyb20gYHJlYWRTbGljZSgpYCB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IHRoZVxuICAgKiBuZXh0IEkvTyBvcGVyYXRpb24sIG1vc3QgY2xpZW50cyBzaG91bGQgdXNlIGByZWFkU3RyaW5nKClgIGluc3RlYWQuXG4gICAqL1xuICBhc3luYyByZWFkU2xpY2UoZGVsaW06IG51bWJlcik6IFByb21pc2U8VWludDhBcnJheSB8IG51bGw+IHtcbiAgICBsZXQgcyA9IDA7IC8vIHNlYXJjaCBzdGFydCBpbmRleFxuICAgIGxldCBzbGljZTogVWludDhBcnJheSB8IHVuZGVmaW5lZDtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAvLyBTZWFyY2ggYnVmZmVyLlxuICAgICAgbGV0IGkgPSB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciArIHMsIHRoaXMuI3cpLmluZGV4T2YoZGVsaW0pO1xuICAgICAgaWYgKGkgPj0gMCkge1xuICAgICAgICBpICs9IHM7XG4gICAgICAgIHNsaWNlID0gdGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3IgKyBpICsgMSk7XG4gICAgICAgIHRoaXMuI3IgKz0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBFT0Y/XG4gICAgICBpZiAodGhpcy4jZW9mKSB7XG4gICAgICAgIGlmICh0aGlzLiNyID09PSB0aGlzLiN3KSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgc2xpY2UgPSB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jdyk7XG4gICAgICAgIHRoaXMuI3IgPSB0aGlzLiN3O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gQnVmZmVyIGZ1bGw/XG4gICAgICBpZiAodGhpcy5idWZmZXJlZCgpID49IHRoaXMuI2J1Zi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuI3IgPSB0aGlzLiN3O1xuICAgICAgICAvLyAjNDUyMSBUaGUgaW50ZXJuYWwgYnVmZmVyIHNob3VsZCBub3QgYmUgcmV1c2VkIGFjcm9zcyByZWFkcyBiZWNhdXNlIGl0IGNhdXNlcyBjb3JydXB0aW9uIG9mIGRhdGEuXG4gICAgICAgIGNvbnN0IG9sZGJ1ZiA9IHRoaXMuI2J1ZjtcbiAgICAgICAgY29uc3QgbmV3YnVmID0gdGhpcy4jYnVmLnNsaWNlKDApO1xuICAgICAgICB0aGlzLiNidWYgPSBuZXdidWY7XG4gICAgICAgIHRocm93IG5ldyBCdWZmZXJGdWxsRXJyb3Iob2xkYnVmKTtcbiAgICAgIH1cblxuICAgICAgcyA9IHRoaXMuI3cgLSB0aGlzLiNyOyAvLyBkbyBub3QgcmVzY2FuIGFyZWEgd2Ugc2Nhbm5lZCBiZWZvcmVcblxuICAgICAgLy8gQnVmZmVyIGlzIG5vdCBmdWxsLlxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy4jZmlsbCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJ0aWFsUmVhZEVycm9yKSB7XG4gICAgICAgICAgZXJyLnBhcnRpYWwgPSBzbGljZTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIGNvbnN0IGUgPSBuZXcgUGFydGlhbFJlYWRFcnJvcigpO1xuICAgICAgICAgIGUucGFydGlhbCA9IHNsaWNlO1xuICAgICAgICAgIGUuc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgICAgICAgZS5tZXNzYWdlID0gZXJyLm1lc3NhZ2U7XG4gICAgICAgICAgZS5jYXVzZSA9IGVyci5jYXVzZTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBsYXN0IGJ5dGUsIGlmIGFueS5cbiAgICAvLyBjb25zdCBpID0gc2xpY2UuYnl0ZUxlbmd0aCAtIDE7XG4gICAgLy8gaWYgKGkgPj0gMCkge1xuICAgIC8vICAgdGhpcy5sYXN0Qnl0ZSA9IHNsaWNlW2ldO1xuICAgIC8vICAgdGhpcy5sYXN0Q2hhclNpemUgPSAtMVxuICAgIC8vIH1cblxuICAgIHJldHVybiBzbGljZTtcbiAgfVxuXG4gIC8qKiBgcGVlaygpYCByZXR1cm5zIHRoZSBuZXh0IGBuYCBieXRlcyB3aXRob3V0IGFkdmFuY2luZyB0aGUgcmVhZGVyLiBUaGVcbiAgICogYnl0ZXMgc3RvcCBiZWluZyB2YWxpZCBhdCB0aGUgbmV4dCByZWFkIGNhbGwuXG4gICAqXG4gICAqIFdoZW4gdGhlIGVuZCBvZiB0aGUgdW5kZXJseWluZyBzdHJlYW0gaXMgcmVhY2hlZCwgYnV0IHRoZXJlIGFyZSB1bnJlYWRcbiAgICogYnl0ZXMgbGVmdCBpbiB0aGUgYnVmZmVyLCB0aG9zZSBieXRlcyBhcmUgcmV0dXJuZWQuIElmIHRoZXJlIGFyZSBubyBieXRlc1xuICAgKiBsZWZ0IGluIHRoZSBidWZmZXIsIGl0IHJldHVybnMgYG51bGxgLlxuICAgKlxuICAgKiBJZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZCBiZWZvcmUgYG5gIGJ5dGVzIGFyZSBhdmFpbGFibGUsIGBwZWVrKClgIHRocm93c1xuICAgKiBhbiBlcnJvciB3aXRoIHRoZSBgcGFydGlhbGAgcHJvcGVydHkgc2V0IHRvIGEgc2xpY2Ugb2YgdGhlIGJ1ZmZlciB0aGF0XG4gICAqIGNvbnRhaW5zIHRoZSBieXRlcyB0aGF0IHdlcmUgYXZhaWxhYmxlIGJlZm9yZSB0aGUgZXJyb3Igb2NjdXJyZWQuXG4gICAqL1xuICBhc3luYyBwZWVrKG46IG51bWJlcik6IFByb21pc2U8VWludDhBcnJheSB8IG51bGw+IHtcbiAgICBpZiAobiA8IDApIHtcbiAgICAgIHRocm93IEVycm9yKFwibmVnYXRpdmUgY291bnRcIik7XG4gICAgfVxuXG4gICAgbGV0IGF2YWlsID0gdGhpcy4jdyAtIHRoaXMuI3I7XG4gICAgd2hpbGUgKGF2YWlsIDwgbiAmJiBhdmFpbCA8IHRoaXMuI2J1Zi5ieXRlTGVuZ3RoICYmICF0aGlzLiNlb2YpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuI2ZpbGwoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgUGFydGlhbFJlYWRFcnJvcikge1xuICAgICAgICAgIGVyci5wYXJ0aWFsID0gdGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3cpO1xuICAgICAgICB9IGVsc2UgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgY29uc3QgZSA9IG5ldyBQYXJ0aWFsUmVhZEVycm9yKCk7XG4gICAgICAgICAgZS5wYXJ0aWFsID0gdGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3cpO1xuICAgICAgICAgIGUuc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgICAgICAgZS5tZXNzYWdlID0gZXJyLm1lc3NhZ2U7XG4gICAgICAgICAgZS5jYXVzZSA9IGVyci5jYXVzZTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgICAgYXZhaWwgPSB0aGlzLiN3IC0gdGhpcy4jcjtcbiAgICB9XG5cbiAgICBpZiAoYXZhaWwgPT09IDAgJiYgdGhpcy4jZW9mKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2UgaWYgKGF2YWlsIDwgbiAmJiB0aGlzLiNlb2YpIHtcbiAgICAgIHJldHVybiB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jciArIGF2YWlsKTtcbiAgICB9IGVsc2UgaWYgKGF2YWlsIDwgbikge1xuICAgICAgdGhyb3cgbmV3IEJ1ZmZlckZ1bGxFcnJvcih0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jdykpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jciArIG4pO1xuICB9XG59XG5cbmFic3RyYWN0IGNsYXNzIEFic3RyYWN0QnVmQmFzZSB7XG4gIGJ1ZjogVWludDhBcnJheTtcbiAgdXNlZEJ1ZmZlckJ5dGVzID0gMDtcbiAgZXJyOiBFcnJvciB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKGJ1ZjogVWludDhBcnJheSkge1xuICAgIHRoaXMuYnVmID0gYnVmO1xuICB9XG5cbiAgLyoqIFNpemUgcmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgdW5kZXJseWluZyBidWZmZXIgaW4gYnl0ZXMuICovXG4gIHNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5idWYuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIGhvdyBtYW55IGJ5dGVzIGFyZSB1bnVzZWQgaW4gdGhlIGJ1ZmZlci4gKi9cbiAgYXZhaWxhYmxlKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYnVmLmJ5dGVMZW5ndGggLSB0aGlzLnVzZWRCdWZmZXJCeXRlcztcbiAgfVxuXG4gIC8qKiBidWZmZXJlZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gd3JpdHRlbiBpbnRvIHRoZVxuICAgKiBjdXJyZW50IGJ1ZmZlci5cbiAgICovXG4gIGJ1ZmZlcmVkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudXNlZEJ1ZmZlckJ5dGVzO1xuICB9XG59XG5cbi8qKiBCdWZXcml0ZXIgaW1wbGVtZW50cyBidWZmZXJpbmcgZm9yIGFuIGRlbm8uV3JpdGVyIG9iamVjdC5cbiAqIElmIGFuIGVycm9yIG9jY3VycyB3cml0aW5nIHRvIGEgV3JpdGVyLCBubyBtb3JlIGRhdGEgd2lsbCBiZVxuICogYWNjZXB0ZWQgYW5kIGFsbCBzdWJzZXF1ZW50IHdyaXRlcywgYW5kIGZsdXNoKCksIHdpbGwgcmV0dXJuIHRoZSBlcnJvci5cbiAqIEFmdGVyIGFsbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4sIHRoZSBjbGllbnQgc2hvdWxkIGNhbGwgdGhlXG4gKiBmbHVzaCgpIG1ldGhvZCB0byBndWFyYW50ZWUgYWxsIGRhdGEgaGFzIGJlZW4gZm9yd2FyZGVkIHRvXG4gKiB0aGUgdW5kZXJseWluZyBkZW5vLldyaXRlci5cbiAqL1xuZXhwb3J0IGNsYXNzIEJ1ZldyaXRlciBleHRlbmRzIEFic3RyYWN0QnVmQmFzZSBpbXBsZW1lbnRzIFdyaXRlciB7XG4gICN3cml0ZXI6IFdyaXRlcjtcblxuICAvKiogcmV0dXJuIG5ldyBCdWZXcml0ZXIgdW5sZXNzIHdyaXRlciBpcyBCdWZXcml0ZXIgKi9cbiAgc3RhdGljIGNyZWF0ZSh3cml0ZXI6IFdyaXRlciwgc2l6ZTogbnVtYmVyID0gREVGQVVMVF9CVUZfU0laRSk6IEJ1ZldyaXRlciB7XG4gICAgcmV0dXJuIHdyaXRlciBpbnN0YW5jZW9mIEJ1ZldyaXRlciA/IHdyaXRlciA6IG5ldyBCdWZXcml0ZXIod3JpdGVyLCBzaXplKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHdyaXRlcjogV3JpdGVyLCBzaXplOiBudW1iZXIgPSBERUZBVUxUX0JVRl9TSVpFKSB7XG4gICAgc3VwZXIobmV3IFVpbnQ4QXJyYXkoc2l6ZSA8PSAwID8gREVGQVVMVF9CVUZfU0laRSA6IHNpemUpKTtcbiAgICB0aGlzLiN3cml0ZXIgPSB3cml0ZXI7XG4gIH1cblxuICAvKiogRGlzY2FyZHMgYW55IHVuZmx1c2hlZCBidWZmZXJlZCBkYXRhLCBjbGVhcnMgYW55IGVycm9yLCBhbmRcbiAgICogcmVzZXRzIGJ1ZmZlciB0byB3cml0ZSBpdHMgb3V0cHV0IHRvIHcuXG4gICAqL1xuICByZXNldCh3OiBXcml0ZXIpOiB2b2lkIHtcbiAgICB0aGlzLmVyciA9IG51bGw7XG4gICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgPSAwO1xuICAgIHRoaXMuI3dyaXRlciA9IHc7XG4gIH1cblxuICAvKiogRmx1c2ggd3JpdGVzIGFueSBidWZmZXJlZCBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIGlvLldyaXRlci4gKi9cbiAgYXN5bmMgZmx1c2goKSB7XG4gICAgaWYgKHRoaXMuZXJyICE9PSBudWxsKSB0aHJvdyB0aGlzLmVycjtcbiAgICBpZiAodGhpcy51c2VkQnVmZmVyQnl0ZXMgPT09IDApIHJldHVybjtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwID0gdGhpcy5idWYuc3ViYXJyYXkoMCwgdGhpcy51c2VkQnVmZmVyQnl0ZXMpO1xuICAgICAgbGV0IG53cml0dGVuID0gMDtcbiAgICAgIHdoaWxlIChud3JpdHRlbiA8IHAubGVuZ3RoKSB7XG4gICAgICAgIG53cml0dGVuICs9IGF3YWl0IHRoaXMuI3dyaXRlci53cml0ZShwLnN1YmFycmF5KG53cml0dGVuKSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aGlzLmVyciA9IGU7XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIHRoaXMuYnVmID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5idWYubGVuZ3RoKTtcbiAgICB0aGlzLnVzZWRCdWZmZXJCeXRlcyA9IDA7XG4gIH1cblxuICAvKiogV3JpdGVzIHRoZSBjb250ZW50cyBvZiBgZGF0YWAgaW50byB0aGUgYnVmZmVyLiAgSWYgdGhlIGNvbnRlbnRzIHdvbid0IGZ1bGx5XG4gICAqIGZpdCBpbnRvIHRoZSBidWZmZXIsIHRob3NlIGJ5dGVzIHRoYXQgY2FuIGFyZSBjb3BpZWQgaW50byB0aGUgYnVmZmVyLCB0aGVcbiAgICogYnVmZmVyIGlzIHRoZSBmbHVzaGVkIHRvIHRoZSB3cml0ZXIgYW5kIHRoZSByZW1haW5pbmcgYnl0ZXMgYXJlIGNvcGllZCBpbnRvXG4gICAqIHRoZSBub3cgZW1wdHkgYnVmZmVyLlxuICAgKlxuICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUgYnVmZmVyLlxuICAgKi9cbiAgYXN5bmMgd3JpdGUoZGF0YTogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgaWYgKHRoaXMuZXJyICE9PSBudWxsKSB0aHJvdyB0aGlzLmVycjtcbiAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiAwO1xuXG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICBsZXQgbnVtQnl0ZXNXcml0dGVuID0gMDtcbiAgICB3aGlsZSAoZGF0YS5ieXRlTGVuZ3RoID4gdGhpcy5hdmFpbGFibGUoKSkge1xuICAgICAgaWYgKHRoaXMuYnVmZmVyZWQoKSA9PT0gMCkge1xuICAgICAgICAvLyBMYXJnZSB3cml0ZSwgZW1wdHkgYnVmZmVyLlxuICAgICAgICAvLyBXcml0ZSBkaXJlY3RseSBmcm9tIGRhdGEgdG8gYXZvaWQgY29weS5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBudW1CeXRlc1dyaXR0ZW4gPSBhd2FpdCB0aGlzLiN3cml0ZXIud3JpdGUoZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVyciA9IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG51bUJ5dGVzV3JpdHRlbiA9IGNvcHkoZGF0YSwgdGhpcy5idWYsIHRoaXMudXNlZEJ1ZmZlckJ5dGVzKTtcbiAgICAgICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgICAgICBhd2FpdCB0aGlzLmZsdXNoKCk7XG4gICAgICB9XG4gICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBudW1CeXRlc1dyaXR0ZW47XG4gICAgICBkYXRhID0gZGF0YS5zdWJhcnJheShudW1CeXRlc1dyaXR0ZW4pO1xuICAgIH1cblxuICAgIG51bUJ5dGVzV3JpdHRlbiA9IGNvcHkoZGF0YSwgdGhpcy5idWYsIHRoaXMudXNlZEJ1ZmZlckJ5dGVzKTtcbiAgICB0aGlzLnVzZWRCdWZmZXJCeXRlcyArPSBudW1CeXRlc1dyaXR0ZW47XG4gICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgIHJldHVybiB0b3RhbEJ5dGVzV3JpdHRlbjtcbiAgfVxufVxuXG4vKiogQnVmV3JpdGVyU3luYyBpbXBsZW1lbnRzIGJ1ZmZlcmluZyBmb3IgYSBkZW5vLldyaXRlclN5bmMgb2JqZWN0LlxuICogSWYgYW4gZXJyb3Igb2NjdXJzIHdyaXRpbmcgdG8gYSBXcml0ZXJTeW5jLCBubyBtb3JlIGRhdGEgd2lsbCBiZVxuICogYWNjZXB0ZWQgYW5kIGFsbCBzdWJzZXF1ZW50IHdyaXRlcywgYW5kIGZsdXNoKCksIHdpbGwgcmV0dXJuIHRoZSBlcnJvci5cbiAqIEFmdGVyIGFsbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4sIHRoZSBjbGllbnQgc2hvdWxkIGNhbGwgdGhlXG4gKiBmbHVzaCgpIG1ldGhvZCB0byBndWFyYW50ZWUgYWxsIGRhdGEgaGFzIGJlZW4gZm9yd2FyZGVkIHRvXG4gKiB0aGUgdW5kZXJseWluZyBkZW5vLldyaXRlclN5bmMuXG4gKi9cbmV4cG9ydCBjbGFzcyBCdWZXcml0ZXJTeW5jIGV4dGVuZHMgQWJzdHJhY3RCdWZCYXNlIGltcGxlbWVudHMgV3JpdGVyU3luYyB7XG4gICN3cml0ZXI6IFdyaXRlclN5bmM7XG5cbiAgLyoqIHJldHVybiBuZXcgQnVmV3JpdGVyU3luYyB1bmxlc3Mgd3JpdGVyIGlzIEJ1ZldyaXRlclN5bmMgKi9cbiAgc3RhdGljIGNyZWF0ZShcbiAgICB3cml0ZXI6IFdyaXRlclN5bmMsXG4gICAgc2l6ZTogbnVtYmVyID0gREVGQVVMVF9CVUZfU0laRSxcbiAgKTogQnVmV3JpdGVyU3luYyB7XG4gICAgcmV0dXJuIHdyaXRlciBpbnN0YW5jZW9mIEJ1ZldyaXRlclN5bmNcbiAgICAgID8gd3JpdGVyXG4gICAgICA6IG5ldyBCdWZXcml0ZXJTeW5jKHdyaXRlciwgc2l6ZSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcih3cml0ZXI6IFdyaXRlclN5bmMsIHNpemU6IG51bWJlciA9IERFRkFVTFRfQlVGX1NJWkUpIHtcbiAgICBzdXBlcihuZXcgVWludDhBcnJheShzaXplIDw9IDAgPyBERUZBVUxUX0JVRl9TSVpFIDogc2l6ZSkpO1xuICAgIHRoaXMuI3dyaXRlciA9IHdyaXRlcjtcbiAgfVxuXG4gIC8qKiBEaXNjYXJkcyBhbnkgdW5mbHVzaGVkIGJ1ZmZlcmVkIGRhdGEsIGNsZWFycyBhbnkgZXJyb3IsIGFuZFxuICAgKiByZXNldHMgYnVmZmVyIHRvIHdyaXRlIGl0cyBvdXRwdXQgdG8gdy5cbiAgICovXG4gIHJlc2V0KHc6IFdyaXRlclN5bmMpOiB2b2lkIHtcbiAgICB0aGlzLmVyciA9IG51bGw7XG4gICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgPSAwO1xuICAgIHRoaXMuI3dyaXRlciA9IHc7XG4gIH1cblxuICAvKiogRmx1c2ggd3JpdGVzIGFueSBidWZmZXJlZCBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIGlvLldyaXRlclN5bmMuICovXG4gIGZsdXNoKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVyciAhPT0gbnVsbCkgdGhyb3cgdGhpcy5lcnI7XG4gICAgaWYgKHRoaXMudXNlZEJ1ZmZlckJ5dGVzID09PSAwKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcCA9IHRoaXMuYnVmLnN1YmFycmF5KDAsIHRoaXMudXNlZEJ1ZmZlckJ5dGVzKTtcbiAgICAgIGxldCBud3JpdHRlbiA9IDA7XG4gICAgICB3aGlsZSAobndyaXR0ZW4gPCBwLmxlbmd0aCkge1xuICAgICAgICBud3JpdHRlbiArPSB0aGlzLiN3cml0ZXIud3JpdGVTeW5jKHAuc3ViYXJyYXkobndyaXR0ZW4pKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRoaXMuZXJyID0gZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgdGhpcy5idWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1Zi5sZW5ndGgpO1xuICAgIHRoaXMudXNlZEJ1ZmZlckJ5dGVzID0gMDtcbiAgfVxuXG4gIC8qKiBXcml0ZXMgdGhlIGNvbnRlbnRzIG9mIGBkYXRhYCBpbnRvIHRoZSBidWZmZXIuICBJZiB0aGUgY29udGVudHMgd29uJ3QgZnVsbHlcbiAgICogZml0IGludG8gdGhlIGJ1ZmZlciwgdGhvc2UgYnl0ZXMgdGhhdCBjYW4gYXJlIGNvcGllZCBpbnRvIHRoZSBidWZmZXIsIHRoZVxuICAgKiBidWZmZXIgaXMgdGhlIGZsdXNoZWQgdG8gdGhlIHdyaXRlciBhbmQgdGhlIHJlbWFpbmluZyBieXRlcyBhcmUgY29waWVkIGludG9cbiAgICogdGhlIG5vdyBlbXB0eSBidWZmZXIuXG4gICAqXG4gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHRoZSBidWZmZXIuXG4gICAqL1xuICB3cml0ZVN5bmMoZGF0YTogVWludDhBcnJheSk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZXJyICE9PSBudWxsKSB0aHJvdyB0aGlzLmVycjtcbiAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiAwO1xuXG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICBsZXQgbnVtQnl0ZXNXcml0dGVuID0gMDtcbiAgICB3aGlsZSAoZGF0YS5ieXRlTGVuZ3RoID4gdGhpcy5hdmFpbGFibGUoKSkge1xuICAgICAgaWYgKHRoaXMuYnVmZmVyZWQoKSA9PT0gMCkge1xuICAgICAgICAvLyBMYXJnZSB3cml0ZSwgZW1wdHkgYnVmZmVyLlxuICAgICAgICAvLyBXcml0ZSBkaXJlY3RseSBmcm9tIGRhdGEgdG8gYXZvaWQgY29weS5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBudW1CeXRlc1dyaXR0ZW4gPSB0aGlzLiN3cml0ZXIud3JpdGVTeW5jKGRhdGEpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgdGhpcy5lcnIgPSBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBudW1CeXRlc1dyaXR0ZW4gPSBjb3B5KGRhdGEsIHRoaXMuYnVmLCB0aGlzLnVzZWRCdWZmZXJCeXRlcyk7XG4gICAgICAgIHRoaXMudXNlZEJ1ZmZlckJ5dGVzICs9IG51bUJ5dGVzV3JpdHRlbjtcbiAgICAgICAgdGhpcy5mbHVzaCgpO1xuICAgICAgfVxuICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgICAgZGF0YSA9IGRhdGEuc3ViYXJyYXkobnVtQnl0ZXNXcml0dGVuKTtcbiAgICB9XG5cbiAgICBudW1CeXRlc1dyaXR0ZW4gPSBjb3B5KGRhdGEsIHRoaXMuYnVmLCB0aGlzLnVzZWRCdWZmZXJCeXRlcyk7XG4gICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IG51bUJ5dGVzV3JpdHRlbjtcbiAgICByZXR1cm4gdG90YWxCeXRlc1dyaXR0ZW47XG4gIH1cbn1cblxuLyoqIEdlbmVyYXRlIGxvbmdlc3QgcHJvcGVyIHByZWZpeCB3aGljaCBpcyBhbHNvIHN1ZmZpeCBhcnJheS4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUxQUyhwYXQ6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5IHtcbiAgY29uc3QgbHBzID0gbmV3IFVpbnQ4QXJyYXkocGF0Lmxlbmd0aCk7XG4gIGxwc1swXSA9IDA7XG4gIGxldCBwcmVmaXhFbmQgPSAwO1xuICBsZXQgaSA9IDE7XG4gIHdoaWxlIChpIDwgbHBzLmxlbmd0aCkge1xuICAgIGlmIChwYXRbaV0gPT0gcGF0W3ByZWZpeEVuZF0pIHtcbiAgICAgIHByZWZpeEVuZCsrO1xuICAgICAgbHBzW2ldID0gcHJlZml4RW5kO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSBpZiAocHJlZml4RW5kID09PSAwKSB7XG4gICAgICBscHNbaV0gPSAwO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcmVmaXhFbmQgPSBscHNbcHJlZml4RW5kIC0gMV07XG4gICAgfVxuICB9XG4gIHJldHVybiBscHM7XG59XG5cbi8qKiBSZWFkIGRlbGltaXRlZCBieXRlcyBmcm9tIGEgUmVhZGVyLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uKiByZWFkRGVsaW0oXG4gIHJlYWRlcjogUmVhZGVyLFxuICBkZWxpbTogVWludDhBcnJheSxcbik6IEFzeW5jSXRlcmFibGVJdGVyYXRvcjxVaW50OEFycmF5PiB7XG4gIC8vIEF2b2lkIHVuaWNvZGUgcHJvYmxlbXNcbiAgY29uc3QgZGVsaW1MZW4gPSBkZWxpbS5sZW5ndGg7XG4gIGNvbnN0IGRlbGltTFBTID0gY3JlYXRlTFBTKGRlbGltKTtcbiAgY29uc3QgY2h1bmtzID0gbmV3IEJ5dGVzTGlzdCgpO1xuICBjb25zdCBidWZTaXplID0gTWF0aC5tYXgoMTAyNCwgZGVsaW1MZW4gKyAxKTtcblxuICAvLyBNb2RpZmllZCBLTVBcbiAgbGV0IGluc3BlY3RJbmRleCA9IDA7XG4gIGxldCBtYXRjaEluZGV4ID0gMDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBpbnNwZWN0QXJyID0gbmV3IFVpbnQ4QXJyYXkoYnVmU2l6ZSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZGVyLnJlYWQoaW5zcGVjdEFycik7XG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgLy8gWWllbGQgbGFzdCBjaHVuay5cbiAgICAgIHlpZWxkIGNodW5rcy5jb25jYXQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKHJlc3VsdCA8IDApIHtcbiAgICAgIC8vIERpc2NhcmQgYWxsIHJlbWFpbmluZyBhbmQgc2lsZW50bHkgZmFpbC5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY2h1bmtzLmFkZChpbnNwZWN0QXJyLCAwLCByZXN1bHQpO1xuICAgIGxldCBsb2NhbEluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5zcGVjdEluZGV4IDwgY2h1bmtzLnNpemUoKSkge1xuICAgICAgaWYgKGluc3BlY3RBcnJbbG9jYWxJbmRleF0gPT09IGRlbGltW21hdGNoSW5kZXhdKSB7XG4gICAgICAgIGluc3BlY3RJbmRleCsrO1xuICAgICAgICBsb2NhbEluZGV4Kys7XG4gICAgICAgIG1hdGNoSW5kZXgrKztcbiAgICAgICAgaWYgKG1hdGNoSW5kZXggPT09IGRlbGltTGVuKSB7XG4gICAgICAgICAgLy8gRnVsbCBtYXRjaFxuICAgICAgICAgIGNvbnN0IG1hdGNoRW5kID0gaW5zcGVjdEluZGV4IC0gZGVsaW1MZW47XG4gICAgICAgICAgY29uc3QgcmVhZHlCeXRlcyA9IGNodW5rcy5zbGljZSgwLCBtYXRjaEVuZCk7XG4gICAgICAgICAgeWllbGQgcmVhZHlCeXRlcztcbiAgICAgICAgICAvLyBSZXNldCBtYXRjaCwgZGlmZmVyZW50IGZyb20gS01QLlxuICAgICAgICAgIGNodW5rcy5zaGlmdChpbnNwZWN0SW5kZXgpO1xuICAgICAgICAgIGluc3BlY3RJbmRleCA9IDA7XG4gICAgICAgICAgbWF0Y2hJbmRleCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChtYXRjaEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgaW5zcGVjdEluZGV4Kys7XG4gICAgICAgICAgbG9jYWxJbmRleCsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1hdGNoSW5kZXggPSBkZWxpbUxQU1ttYXRjaEluZGV4IC0gMV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqIFJlYWQgZGVsaW1pdGVkIHN0cmluZ3MgZnJvbSBhIFJlYWRlci4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogcmVhZFN0cmluZ0RlbGltKFxuICByZWFkZXI6IFJlYWRlcixcbiAgZGVsaW06IHN0cmluZyxcbiAgZGVjb2Rlck9wdHM/OiB7XG4gICAgZW5jb2Rpbmc/OiBzdHJpbmc7XG4gICAgZmF0YWw/OiBib29sZWFuO1xuICAgIGlnbm9yZUJPTT86IGJvb2xlYW47XG4gIH0sXG4pOiBBc3luY0l0ZXJhYmxlSXRlcmF0b3I8c3RyaW5nPiB7XG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihkZWNvZGVyT3B0cz8uZW5jb2RpbmcsIGRlY29kZXJPcHRzKTtcbiAgZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiByZWFkRGVsaW0ocmVhZGVyLCBlbmNvZGVyLmVuY29kZShkZWxpbSkpKSB7XG4gICAgeWllbGQgZGVjb2Rlci5kZWNvZGUoY2h1bmspO1xuICB9XG59XG5cbi8qKiBSZWFkIHN0cmluZ3MgbGluZS1ieS1saW5lIGZyb20gYSBSZWFkZXIuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24qIHJlYWRMaW5lcyhcbiAgcmVhZGVyOiBSZWFkZXIsXG4gIGRlY29kZXJPcHRzPzoge1xuICAgIGVuY29kaW5nPzogc3RyaW5nO1xuICAgIGZhdGFsPzogYm9vbGVhbjtcbiAgICBpZ25vcmVCT00/OiBib29sZWFuO1xuICB9LFxuKTogQXN5bmNJdGVyYWJsZUl0ZXJhdG9yPHN0cmluZz4ge1xuICBjb25zdCBidWZSZWFkZXIgPSBuZXcgQnVmUmVhZGVyKHJlYWRlcik7XG4gIGxldCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKGRlY29kZXJPcHRzPy5lbmNvZGluZywgZGVjb2Rlck9wdHMpO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJ1ZlJlYWRlci5yZWFkTGluZSgpO1xuICAgIGlmICghcmVzKSB7XG4gICAgICBpZiAoY2h1bmtzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgeWllbGQgZGVjb2Rlci5kZWNvZGUoY29uY2F0KC4uLmNodW5rcykpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNodW5rcy5wdXNoKHJlcy5saW5lKTtcbiAgICBpZiAoIXJlcy5tb3JlKSB7XG4gICAgICB5aWVsZCBkZWNvZGVyLmRlY29kZShjb25jYXQoLi4uY2h1bmtzKSk7XG4gICAgICBjaHVua3MgPSBbXTtcbiAgICB9XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsU0FBUyxNQUFNLFFBQVEscUJBQXFCO0FBQzVDLFNBQVMsU0FBUyxRQUFRLHlCQUF5QjtBQUNuRCxTQUFTLE1BQU0sRUFBRSxJQUFJLFFBQVEsa0JBQWtCO0FBRy9DLG9FQUFvRTtBQUNwRSw0RUFBNEU7QUFDNUUsMkVBQTJFO0FBQzNFLHFCQUFxQjtBQUNyQixNQUFNLFdBQVcsS0FBSztBQUN0QixNQUFNLFdBQVcsS0FBSyxLQUFLO0FBRTNCOzs7Ozs7Ozs7Ozs7OytEQWErRCxHQUUvRCxPQUFPLE1BQU07SUFDWCxDQUFDLEdBQUcsQ0FBYTtJQUNqQixDQUFDLEdBQUcsR0FBRyxFQUFFO0lBRVQsWUFBWSxFQUF3QyxDQUFFO1FBQ3BELElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxPQUFPLFlBQVksSUFBSSxXQUFXLEtBQUssSUFBSSxXQUFXLEdBQUc7SUFDdkU7SUFFQTs7Ozs7Ozs7R0FRQyxHQUNELE1BQU0sVUFBVTtRQUFFLE1BQU0sSUFBSTtJQUFDLENBQUMsRUFBYztRQUMxQyxJQUFJLFFBQVEsSUFBSSxLQUFLLEtBQUssRUFBRSxPQUFPLElB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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/p5wE1hCF6dGYMZ41YnIQs2go2is.js b/tests/__snapshots__/transpile/remote/modules/p5wE1hCF6dGYMZ41YnIQs2go2is.js new file mode 100644 index 0000000..d414e93 --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/p5wE1hCF6dGYMZ41YnIQs2go2is.js @@ -0,0 +1,140 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** + * An abstraction of multiple Uint8Arrays + */ export class BytesList { + len = 0; + chunks = []; + constructor(){} + /** + * Total size of bytes + */ size() { + return this.len; + } + /** + * Push bytes with given offset infos + */ add(value, start = 0, end = value.byteLength) { + if (value.byteLength === 0 || end - start === 0) { + return; + } + checkRange(start, end, value.byteLength); + this.chunks.push({ + value, + end, + start, + offset: this.len + }); + this.len += end - start; + } + /** + * Drop head `n` bytes. + */ shift(n) { + if (n === 0) { + return; + } + if (this.len <= n) { + this.chunks = []; + this.len = 0; + return; + } + const idx = this.getChunkIndex(n); + this.chunks.splice(0, idx); + const [chunk] = this.chunks; + if (chunk) { + const diff = n - chunk.offset; + chunk.start += diff; + } + let offset = 0; + for (const chunk of this.chunks){ + chunk.offset = offset; + offset += chunk.end - chunk.start; + } + this.len = offset; + } + /** + * Find chunk index in which `pos` locates by binary-search + * returns -1 if out of range + */ getChunkIndex(pos) { + let max = this.chunks.length; + let min = 0; + while(true){ + const i = min + Math.floor((max - min) / 2); + if (i < 0 || this.chunks.length <= i) { + return -1; + } + const { offset , start , end } = this.chunks[i]; + const len = end - start; + if (offset <= pos && pos < offset + len) { + return i; + } else if (offset + len <= pos) { + min = i + 1; + } else { + max = i - 1; + } + } + } + /** + * Get indexed byte from chunks + */ get(i) { + if (i < 0 || this.len <= i) { + throw new Error("out of range"); + } + const idx = this.getChunkIndex(i); + const { value , offset , start } = this.chunks[idx]; + return value[start + i - offset]; + } + /** + * Iterator of bytes from given position + */ *iterator(start = 0) { + const startIdx = this.getChunkIndex(start); + if (startIdx < 0) return; + const first = this.chunks[startIdx]; + let firstOffset = start - first.offset; + for(let i = startIdx; i < this.chunks.length; i++){ + const chunk = this.chunks[i]; + for(let j = chunk.start + firstOffset; j < chunk.end; j++){ + yield chunk.value[j]; + } + firstOffset = 0; + } + } + /** + * Returns subset of bytes copied + */ slice(start, end = this.len) { + if (end === start) { + return new Uint8Array(); + } + checkRange(start, end, this.len); + const result = new Uint8Array(end - start); + const startIdx = this.getChunkIndex(start); + const endIdx = this.getChunkIndex(end - 1); + let written = 0; + for(let i = startIdx; i < endIdx; i++){ + const chunk = this.chunks[i]; + const len = chunk.end - chunk.start; + result.set(chunk.value.subarray(chunk.start, chunk.end), written); + written += len; + } + const last = this.chunks[endIdx]; + const rest = end - start - written; + result.set(last.value.subarray(last.start, last.start + rest), written); + return result; + } + /** + * Concatenate chunks into single Uint8Array copied. + */ concat() { + const result = new Uint8Array(this.len); + let sum = 0; + for (const { value , start , end } of this.chunks){ + result.set(value.subarray(start, end), sum); + sum += end - start; + } + return result; + } +} +function checkRange(start, end, len) { + if (start < 0 || len < start || end < 0 || len < end || end < start) { + throw new Error("invalid range"); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2J5dGVzL2J5dGVzX2xpc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuLyoqXG4gKiBBbiBhYnN0cmFjdGlvbiBvZiBtdWx0aXBsZSBVaW50OEFycmF5c1xuICovXG5leHBvcnQgY2xhc3MgQnl0ZXNMaXN0IHtcbiAgcHJpdmF0ZSBsZW4gPSAwO1xuICBwcml2YXRlIGNodW5rczoge1xuICAgIHZhbHVlOiBVaW50OEFycmF5O1xuICAgIHN0YXJ0OiBudW1iZXI7IC8vIHN0YXJ0IG9mZnNldCBmcm9tIGhlYWQgb2YgY2h1bmtcbiAgICBlbmQ6IG51bWJlcjsgLy8gZW5kIG9mZnNldCBmcm9tIGhlYWQgb2YgY2h1bmtcbiAgICBvZmZzZXQ6IG51bWJlcjsgLy8gb2Zmc2V0IG9mIGhlYWQgaW4gYWxsIGJ5dGVzXG4gIH1bXSA9IFtdO1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIFRvdGFsIHNpemUgb2YgYnl0ZXNcbiAgICovXG4gIHNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMubGVuO1xuICB9XG4gIC8qKlxuICAgKiBQdXNoIGJ5dGVzIHdpdGggZ2l2ZW4gb2Zmc2V0IGluZm9zXG4gICAqL1xuICBhZGQodmFsdWU6IFVpbnQ4QXJyYXksIHN0YXJ0ID0gMCwgZW5kID0gdmFsdWUuYnl0ZUxlbmd0aCkge1xuICAgIGlmICh2YWx1ZS5ieXRlTGVuZ3RoID09PSAwIHx8IGVuZCAtIHN0YXJ0ID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNoZWNrUmFuZ2Uoc3RhcnQsIGVuZCwgdmFsdWUuYnl0ZUxlbmd0aCk7XG4gICAgdGhpcy5jaHVua3MucHVzaCh7XG4gICAgICB2YWx1ZSxcbiAgICAgIGVuZCxcbiAgICAgIHN0YXJ0LFxuICAgICAgb2Zmc2V0OiB0aGlzLmxlbixcbiAgICB9KTtcbiAgICB0aGlzLmxlbiArPSBlbmQgLSBzdGFydDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcm9wIGhlYWQgYG5gIGJ5dGVzLlxuICAgKi9cbiAgc2hpZnQobjogbnVtYmVyKSB7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubGVuIDw9IG4pIHtcbiAgICAgIHRoaXMuY2h1bmtzID0gW107XG4gICAgICB0aGlzLmxlbiA9IDA7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGlkeCA9IHRoaXMuZ2V0Q2h1bmtJbmRleChuKTtcbiAgICB0aGlzLmNodW5rcy5zcGxpY2UoMCwgaWR4KTtcbiAgICBjb25zdCBbY2h1bmtdID0gdGhpcy5jaHVua3M7XG4gICAgaWYgKGNodW5rKSB7XG4gICAgICBjb25zdCBkaWZmID0gbiAtIGNodW5rLm9mZnNldDtcbiAgICAgIGNodW5rLnN0YXJ0ICs9IGRpZmY7XG4gICAgfVxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGZvciAoY29uc3QgY2h1bmsgb2YgdGhpcy5jaHVua3MpIHtcbiAgICAgIGNodW5rLm9mZnNldCA9IG9mZnNldDtcbiAgICAgIG9mZnNldCArPSBjaHVuay5lbmQgLSBjaHVuay5zdGFydDtcbiAgICB9XG4gICAgdGhpcy5sZW4gPSBvZmZzZXQ7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBjaHVuayBpbmRleCBpbiB3aGljaCBgcG9zYCBsb2NhdGVzIGJ5IGJpbmFyeS1zZWFyY2hcbiAgICogcmV0dXJucyAtMSBpZiBvdXQgb2YgcmFuZ2VcbiAgICovXG4gIGdldENodW5rSW5kZXgocG9zOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBtYXggPSB0aGlzLmNodW5rcy5sZW5ndGg7XG4gICAgbGV0IG1pbiA9IDA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IGkgPSBtaW4gKyBNYXRoLmZsb29yKChtYXggLSBtaW4pIC8gMik7XG4gICAgICBpZiAoaSA8IDAgfHwgdGhpcy5jaHVua3MubGVuZ3RoIDw9IGkpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBvZmZzZXQsIHN0YXJ0LCBlbmQgfSA9IHRoaXMuY2h1bmtzW2ldO1xuICAgICAgY29uc3QgbGVuID0gZW5kIC0gc3RhcnQ7XG4gICAgICBpZiAob2Zmc2V0IDw9IHBvcyAmJiBwb3MgPCBvZmZzZXQgKyBsZW4pIHtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgICB9IGVsc2UgaWYgKG9mZnNldCArIGxlbiA8PSBwb3MpIHtcbiAgICAgICAgbWluID0gaSArIDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXggPSBpIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGluZGV4ZWQgYnl0ZSBmcm9tIGNodW5rc1xuICAgKi9cbiAgZ2V0KGk6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGkgPCAwIHx8IHRoaXMubGVuIDw9IGkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm91dCBvZiByYW5nZVwiKTtcbiAgICB9XG4gICAgY29uc3QgaWR4ID0gdGhpcy5nZXRDaHVua0luZGV4KGkpO1xuICAgIGNvbnN0IHsgdmFsdWUsIG9mZnNldCwgc3RhcnQgfSA9IHRoaXMuY2h1bmtzW2lkeF07XG4gICAgcmV0dXJuIHZhbHVlW3N0YXJ0ICsgaSAtIG9mZnNldF07XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0b3Igb2YgYnl0ZXMgZnJvbSBnaXZlbiBwb3NpdGlvblxuICAgKi9cbiAgKml0ZXJhdG9yKHN0YXJ0ID0gMCk6IEl0ZXJhYmxlSXRlcmF0b3I8bnVtYmVyPiB7XG4gICAgY29uc3Qgc3RhcnRJZHggPSB0aGlzLmdldENodW5rSW5kZXgoc3RhcnQpO1xuICAgIGlmIChzdGFydElkeCA8IDApIHJldHVybjtcbiAgICBjb25zdCBmaXJzdCA9IHRoaXMuY2h1bmtzW3N0YXJ0SWR4XTtcbiAgICBsZXQgZmlyc3RPZmZzZXQgPSBzdGFydCAtIGZpcnN0Lm9mZnNldDtcbiAgICBmb3IgKGxldCBpID0gc3RhcnRJZHg7IGkgPCB0aGlzLmNodW5rcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLmNodW5rc1tpXTtcbiAgICAgIGZvciAobGV0IGogPSBjaHVuay5zdGFydCArIGZpcnN0T2Zmc2V0OyBqIDwgY2h1bmsuZW5kOyBqKyspIHtcbiAgICAgICAgeWllbGQgY2h1bmsudmFsdWVbal07XG4gICAgICB9XG4gICAgICBmaXJzdE9mZnNldCA9IDA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgc3Vic2V0IG9mIGJ5dGVzIGNvcGllZFxuICAgKi9cbiAgc2xpY2Uoc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIgPSB0aGlzLmxlbik6IFVpbnQ4QXJyYXkge1xuICAgIGlmIChlbmQgPT09IHN0YXJ0KSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoKTtcbiAgICB9XG4gICAgY2hlY2tSYW5nZShzdGFydCwgZW5kLCB0aGlzLmxlbik7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkoZW5kIC0gc3RhcnQpO1xuICAgIGNvbnN0IHN0YXJ0SWR4ID0gdGhpcy5nZXRDaHVua0luZGV4KHN0YXJ0KTtcbiAgICBjb25zdCBlbmRJZHggPSB0aGlzLmdldENodW5rSW5kZXgoZW5kIC0gMSk7XG4gICAgbGV0IHdyaXR0ZW4gPSAwO1xuICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IGVuZElkeDsgaSsrKSB7XG4gICAgICBjb25zdCBjaHVuayA9IHRoaXMuY2h1bmtzW2ldO1xuICAgICAgY29uc3QgbGVuID0gY2h1bmsuZW5kIC0gY2h1bmsuc3RhcnQ7XG4gICAgICByZXN1bHQuc2V0KGNodW5rLnZhbHVlLnN1YmFycmF5KGNodW5rLnN0YXJ0LCBjaHVuay5lbmQpLCB3cml0dGVuKTtcbiAgICAgIHdyaXR0ZW4gKz0gbGVuO1xuICAgIH1cbiAgICBjb25zdCBsYXN0ID0gdGhpcy5jaHVua3NbZW5kSWR4XTtcbiAgICBjb25zdCByZXN0ID0gZW5kIC0gc3RhcnQgLSB3cml0dGVuO1xuICAgIHJlc3VsdC5zZXQobGFzdC52YWx1ZS5zdWJhcnJheShsYXN0LnN0YXJ0LCBsYXN0LnN0YXJ0ICsgcmVzdCksIHdyaXR0ZW4pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLyoqXG4gICAqIENvbmNhdGVuYXRlIGNodW5rcyBpbnRvIHNpbmdsZSBVaW50OEFycmF5IGNvcGllZC5cbiAgICovXG4gIGNvbmNhdCgpOiBVaW50OEFycmF5IHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbik7XG4gICAgbGV0IHN1bSA9IDA7XG4gICAgZm9yIChjb25zdCB7IHZhbHVlLCBzdGFydCwgZW5kIH0gb2YgdGhpcy5jaHVua3MpIHtcbiAgICAgIHJlc3VsdC5zZXQodmFsdWUuc3ViYXJyYXkoc3RhcnQsIGVuZCksIHN1bSk7XG4gICAgICBzdW0gKz0gZW5kIC0gc3RhcnQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tSYW5nZShzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgbGVuOiBudW1iZXIpIHtcbiAgaWYgKHN0YXJ0IDwgMCB8fCBsZW4gPCBzdGFydCB8fCBlbmQgPCAwIHx8IGxlbiA8IGVuZCB8fCBlbmQgPCBzdGFydCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgcmFuZ2VcIik7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDOztDQUVDLEdBQ0QsT0FBTyxNQUFNO0lBQ0gsTUFBTSxFQUFFO0lBQ1IsU0FLRixFQUFFLENBQUM7SUFDVCxhQUFjLENBQUM7SUFFZjs7R0FFQyxHQUNELE9BQU87UUFD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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/remote/modules/wme9EIsCB7sfOz5qC_CSLRYajRk.js b/tests/__snapshots__/transpile/remote/modules/wme9EIsCB7sfOz5qC_CSLRYajRk.js new file mode 100644 index 0000000..e057dad --- /dev/null +++ b/tests/__snapshots__/transpile/remote/modules/wme9EIsCB7sfOz5qC_CSLRYajRk.js @@ -0,0 +1,5 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvX2ludGVyZmFjZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vKipcbiAqIEEgcGFyc2VkIHBhdGggb2JqZWN0IGdlbmVyYXRlZCBieSBwYXRoLnBhcnNlKCkgb3IgY29uc3VtZWQgYnkgcGF0aC5mb3JtYXQoKS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJzZWRQYXRoIHtcbiAgLyoqXG4gICAqIFRoZSByb290IG9mIHRoZSBwYXRoIHN1Y2ggYXMgJy8nIG9yICdjOlxcJ1xuICAgKi9cbiAgcm9vdDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGZ1bGwgZGlyZWN0b3J5IHBhdGggc3VjaCBhcyAnL2hvbWUvdXNlci9kaXInIG9yICdjOlxccGF0aFxcZGlyJ1xuICAgKi9cbiAgZGlyOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZmlsZSBuYW1lIGluY2x1ZGluZyBleHRlbnNpb24gKGlmIGFueSkgc3VjaCBhcyAnaW5kZXguaHRtbCdcbiAgICovXG4gIGJhc2U6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBmaWxlIGV4dGVuc2lvbiAoaWYgYW55KSBzdWNoIGFzICcuaHRtbCdcbiAgICovXG4gIGV4dDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGZpbGUgbmFtZSB3aXRob3V0IGV4dGVuc2lvbiAoaWYgYW55KSBzdWNoIGFzICdpbmRleCdcbiAgICovXG4gIG5hbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgRm9ybWF0SW5wdXRQYXRoT2JqZWN0ID0gUGFydGlhbDxQYXJzZWRQYXRoPjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDOztDQUVDLEdBQ0QifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/source/mapping.json b/tests/__snapshots__/transpile/source/mapping.json new file mode 100644 index 0000000..b81962b --- /dev/null +++ b/tests/__snapshots__/transpile/source/mapping.json @@ -0,0 +1,3 @@ +{ + "file:///src.ts": "FX-W_GgTo-jcLMQCWKy5udxEtG0.js" +} diff --git a/tests/__snapshots__/transpile/source/modules/FX-W_GgTo-jcLMQCWKy5udxEtG0.js b/tests/__snapshots__/transpile/source/modules/FX-W_GgTo-jcLMQCWKy5udxEtG0.js new file mode 100644 index 0000000..af83a0f --- /dev/null +++ b/tests/__snapshots__/transpile/source/modules/FX-W_GgTo-jcLMQCWKy5udxEtG0.js @@ -0,0 +1,4 @@ +export default function hello() { + return "Hello there!"; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vc3JjLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGhlbGxvKCk6IHN0cmluZyB7XG4gIHJldHVybiBcIkhlbGxvIHRoZXJlIVwiO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGVBQWUsU0FBUyxRQUFnQjtJQUN0QyxPQUFPO0FBQ1QsQ0FBQyJ9 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/mapping.json b/tests/__snapshots__/transpile/url/mapping.json new file mode 100644 index 0000000..02f1832 --- /dev/null +++ b/tests/__snapshots__/transpile/url/mapping.json @@ -0,0 +1,20 @@ +{ + "https://deno.land/std@0.140.0/_util/assert.ts": "nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js", + "https://deno.land/std@0.140.0/_util/os.ts": "ebsv4XtKEF8sxrDsnkLX8K9VdOA.js", + "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "p5wE1hCF6dGYMZ41YnIQs2go2is.js", + "https://deno.land/std@0.140.0/bytes/equals.ts": "jO4Cj24EIKVTiTvdPctAVhckzgg.js", + "https://deno.land/std@0.140.0/bytes/mod.ts": "WStdDhyHbKYy_C9CJ39RDks1VaY.js", + "https://deno.land/std@0.140.0/examples/chat/server.ts": "VR9N5EtRGYTL6BL2wtaFnqW-AuA.js", + "https://deno.land/std@0.140.0/io/buffer.ts": "npEsX-46oQUgZNw2Jkxv5i4eWDM.js", + "https://deno.land/std@0.140.0/io/types.d.ts": "7HctcYJMo9RPESb8_8SnGpYMx1U.js", + "https://deno.land/std@0.140.0/path/_constants.ts": "WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js", + "https://deno.land/std@0.140.0/path/_interface.ts": "wme9EIsCB7sfOz5qC_CSLRYajRk.js", + "https://deno.land/std@0.140.0/path/_util.ts": "7VWYTDioIHKQJaGRjtUtSbiHVG8.js", + "https://deno.land/std@0.140.0/path/common.ts": "WKh_-mE6UYta1pB11lfX_WOvFQ8.js", + "https://deno.land/std@0.140.0/path/glob.ts": "6asWNnLz5gIIvWCigeWDpbWva1Y.js", + "https://deno.land/std@0.140.0/path/mod.ts": "VUHr_YUyq8otV9YiIbexaSOfQCs.js", + "https://deno.land/std@0.140.0/path/posix.ts": "kWDlQkpYLFWxtJdAejga3vZCeeM.js", + "https://deno.land/std@0.140.0/path/separator.ts": "TPW77jtLW1NbcwGdiav4OHTJd6g.js", + "https://deno.land/std@0.140.0/path/win32.ts": "WPpXvFGuxwYeU5ay2bDrdG4fV_g.js", + "https://deno.land/std@0.140.0/streams/conversion.ts": "ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js" +} diff --git a/tests/__snapshots__/transpile/url/modules/6asWNnLz5gIIvWCigeWDpbWva1Y.js b/tests/__snapshots__/transpile/url/modules/6asWNnLz5gIIvWCigeWDpbWva1Y.js new file mode 100644 index 0000000..bcb9c67 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/6asWNnLz5gIIvWCigeWDpbWva1Y.js @@ -0,0 +1,346 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +import { isWindows, osType } from "../_util/os.ts"; +import { SEP, SEP_PATTERN } from "./separator.ts"; +import * as _win32 from "./win32.ts"; +import * as _posix from "./posix.ts"; +const path = isWindows ? _win32 : _posix; +const { join , normalize } = path; +const regExpEscapeChars = [ + "!", + "$", + "(", + ")", + "*", + "+", + ".", + "=", + "?", + "[", + "\\", + "^", + "{", + "|" +]; +const rangeEscapeChars = [ + "-", + "\\", + "]" +]; +/** Convert a glob string to a regular expression. + * + * Tries to match bash glob expansion as closely as possible. + * + * Basic glob syntax: + * - `*` - Matches everything without leaving the path segment. + * - `?` - Matches any single character. + * - `{foo,bar}` - Matches `foo` or `bar`. + * - `[abcd]` - Matches `a`, `b`, `c` or `d`. + * - `[a-d]` - Matches `a`, `b`, `c` or `d`. + * - `[!abcd]` - Matches any single character besides `a`, `b`, `c` or `d`. + * - `[[::]]` - Matches any character belonging to ``. + * - `[[:alnum:]]` - Matches any digit or letter. + * - `[[:digit:]abc]` - Matches any digit, `a`, `b` or `c`. + * - See https://facelessuser.github.io/wcmatch/glob/#posix-character-classes + * for a complete list of supported character classes. + * - `\` - Escapes the next character for an `os` other than `"windows"`. + * - \` - Escapes the next character for `os` set to `"windows"`. + * - `/` - Path separator. + * - `\` - Additional path separator only for `os` set to `"windows"`. + * + * Extended syntax: + * - Requires `{ extended: true }`. + * - `?(foo|bar)` - Matches 0 or 1 instance of `{foo,bar}`. + * - `@(foo|bar)` - Matches 1 instance of `{foo,bar}`. They behave the same. + * - `*(foo|bar)` - Matches _n_ instances of `{foo,bar}`. + * - `+(foo|bar)` - Matches _n > 0_ instances of `{foo,bar}`. + * - `!(foo|bar)` - Matches anything other than `{foo,bar}`. + * - See https://www.linuxjournal.com/content/bash-extended-globbing. + * + * Globstar syntax: + * - Requires `{ globstar: true }`. + * - `**` - Matches any number of any path segments. + * - Must comprise its entire path segment in the provided glob. + * - See https://www.linuxjournal.com/content/globstar-new-bash-globbing-option. + * + * Note the following properties: + * - The generated `RegExp` is anchored at both start and end. + * - Repeating and trailing separators are tolerated. Trailing separators in the + * provided glob have no meaning and are discarded. + * - Absolute globs will only match absolute paths, etc. + * - Empty globs will match nothing. + * - Any special glob syntax must be contained to one path segment. For example, + * `?(foo|bar/baz)` is invalid. The separator will take precedence and the + * first segment ends with an unclosed group. + * - If a path segment ends with unclosed groups or a dangling escape prefix, a + * parse error has occurred. Every character for that segment is taken + * literally in this event. + * + * Limitations: + * - A negative group like `!(foo|bar)` will wrongly be converted to a negative + * look-ahead followed by a wildcard. This means that `!(foo).js` will wrongly + * fail to match `foobar.js`, even though `foobar` is not `foo`. Effectively, + * `!(foo|bar)` is treated like `!(@(foo|bar)*)`. This will work correctly if + * the group occurs not nested at the end of the segment. */ export function globToRegExp(glob, { extended =true , globstar: globstarOption = true , os =osType , caseInsensitive =false } = {}) { + if (glob == "") { + return /(?!)/; + } + const sep = os == "windows" ? "(?:\\\\|/)+" : "/+"; + const sepMaybe = os == "windows" ? "(?:\\\\|/)*" : "/*"; + const seps = os == "windows" ? [ + "\\", + "/" + ] : [ + "/" + ]; + const globstar = os == "windows" ? "(?:[^\\\\/]*(?:\\\\|/|$)+)*" : "(?:[^/]*(?:/|$)+)*"; + const wildcard = os == "windows" ? "[^\\\\/]*" : "[^/]*"; + const escapePrefix = os == "windows" ? "`" : "\\"; + // Remove trailing separators. + let newLength = glob.length; + for(; newLength > 1 && seps.includes(glob[newLength - 1]); newLength--); + glob = glob.slice(0, newLength); + let regExpString = ""; + // Terminates correctly. Trust that `j` is incremented every iteration. + for(let j = 0; j < glob.length;){ + let segment = ""; + const groupStack = []; + let inRange = false; + let inEscape = false; + let endsWithSep = false; + let i = j; + // Terminates with `i` at the non-inclusive end of the current segment. + for(; i < glob.length && !seps.includes(glob[i]); i++){ + if (inEscape) { + inEscape = false; + const escapeChars = inRange ? rangeEscapeChars : regExpEscapeChars; + segment += escapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i]; + continue; + } + if (glob[i] == escapePrefix) { + inEscape = true; + continue; + } + if (glob[i] == "[") { + if (!inRange) { + inRange = true; + segment += "["; + if (glob[i + 1] == "!") { + i++; + segment += "^"; + } else if (glob[i + 1] == "^") { + i++; + segment += "\\^"; + } + continue; + } else if (glob[i + 1] == ":") { + let k = i + 1; + let value = ""; + while(glob[k + 1] != null && glob[k + 1] != ":"){ + value += glob[k + 1]; + k++; + } + if (glob[k + 1] == ":" && glob[k + 2] == "]") { + i = k + 2; + if (value == "alnum") segment += "\\dA-Za-z"; + else if (value == "alpha") segment += "A-Za-z"; + else if (value == "ascii") segment += "\x00-\x7F"; + else if (value == "blank") segment += "\t "; + else if (value == "cntrl") segment += "\x00-\x1F\x7F"; + else if (value == "digit") segment += "\\d"; + else if (value == "graph") segment += "\x21-\x7E"; + else if (value == "lower") segment += "a-z"; + else if (value == "print") segment += "\x20-\x7E"; + else if (value == "punct") { + segment += "!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_‘{|}~"; + } else if (value == "space") segment += "\\s\v"; + else if (value == "upper") segment += "A-Z"; + else if (value == "word") segment += "\\w"; + else if (value == "xdigit") segment += "\\dA-Fa-f"; + continue; + } + } + } + if (glob[i] == "]" && inRange) { + inRange = false; + segment += "]"; + continue; + } + if (inRange) { + if (glob[i] == "\\") { + segment += `\\\\`; + } else { + segment += glob[i]; + } + continue; + } + if (glob[i] == ")" && groupStack.length > 0 && groupStack[groupStack.length - 1] != "BRACE") { + segment += ")"; + const type = groupStack.pop(); + if (type == "!") { + segment += wildcard; + } else if (type != "@") { + segment += type; + } + continue; + } + if (glob[i] == "|" && groupStack.length > 0 && groupStack[groupStack.length - 1] != "BRACE") { + segment += "|"; + continue; + } + if (glob[i] == "+" && extended && glob[i + 1] == "(") { + i++; + groupStack.push("+"); + segment += "(?:"; + continue; + } + if (glob[i] == "@" && extended && glob[i + 1] == "(") { + i++; + groupStack.push("@"); + segment += "(?:"; + continue; + } + if (glob[i] == "?") { + if (extended && glob[i + 1] == "(") { + i++; + groupStack.push("?"); + segment += "(?:"; + } else { + segment += "."; + } + continue; + } + if (glob[i] == "!" && extended && glob[i + 1] == "(") { + i++; + groupStack.push("!"); + segment += "(?!"; + continue; + } + if (glob[i] == "{") { + groupStack.push("BRACE"); + segment += "(?:"; + continue; + } + if (glob[i] == "}" && groupStack[groupStack.length - 1] == "BRACE") { + groupStack.pop(); + segment += ")"; + continue; + } + if (glob[i] == "," && groupStack[groupStack.length - 1] == "BRACE") { + segment += "|"; + continue; + } + if (glob[i] == "*") { + if (extended && glob[i + 1] == "(") { + i++; + groupStack.push("*"); + segment += "(?:"; + } else { + const prevChar = glob[i - 1]; + let numStars = 1; + while(glob[i + 1] == "*"){ + i++; + numStars++; + } + const nextChar = glob[i + 1]; + if (globstarOption && numStars == 2 && [ + ...seps, + undefined + ].includes(prevChar) && [ + ...seps, + undefined + ].includes(nextChar)) { + segment += globstar; + endsWithSep = true; + } else { + segment += wildcard; + } + } + continue; + } + segment += regExpEscapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i]; + } + // Check for unclosed groups or a dangling backslash. + if (groupStack.length > 0 || inRange || inEscape) { + // Parse failure. Take all characters from this segment literally. + segment = ""; + for (const c of glob.slice(j, i)){ + segment += regExpEscapeChars.includes(c) ? `\\${c}` : c; + endsWithSep = false; + } + } + regExpString += segment; + if (!endsWithSep) { + regExpString += i < glob.length ? sep : sepMaybe; + endsWithSep = true; + } + // Terminates with `i` at the start of the next segment. + while(seps.includes(glob[i]))i++; + // Check that the next value of `j` is indeed higher than the current value. + if (!(i > j)) { + throw new Error("Assertion failure: i > j (potential infinite loop)"); + } + j = i; + } + regExpString = `^${regExpString}$`; + return new RegExp(regExpString, caseInsensitive ? "i" : ""); +} +/** Test whether the given string is a glob */ export function isGlob(str) { + const chars = { + "{": "}", + "(": ")", + "[": "]" + }; + const regex = /\\(.)|(^!|\*|\?|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; + if (str === "") { + return false; + } + let match; + while(match = regex.exec(str)){ + if (match[2]) return true; + let idx = match.index + match[0].length; + // if an open bracket/brace/paren is escaped, + // set the index to the next closing character + const open = match[1]; + const close = open ? chars[open] : null; + if (open && close) { + const n = str.indexOf(close, idx); + if (n !== -1) { + idx = n + 1; + } + } + str = str.slice(idx); + } + return false; +} +/** Like normalize(), but doesn't collapse "**\/.." when `globstar` is true. */ export function normalizeGlob(glob, { globstar =false } = {}) { + if (glob.match(/\0/g)) { + throw new Error(`Glob contains invalid characters: "${glob}"`); + } + if (!globstar) { + return normalize(glob); + } + const s = SEP_PATTERN.source; + const badParentPattern = new RegExp(`(?<=(${s}|^)\\*\\*${s})\\.\\.(?=${s}|$)`, "g"); + return normalize(glob.replace(badParentPattern, "\0")).replace(/\0/g, ".."); +} +/** Like join(), but doesn't collapse "**\/.." when `globstar` is true. */ export function joinGlobs(globs, { extended =true , globstar =false } = {}) { + if (!globstar || globs.length == 0) { + return join(...globs); + } + if (globs.length === 0) return "."; + let joined; + for (const glob of globs){ + const path = glob; + if (path.length > 0) { + if (!joined) joined = path; + else joined += `${SEP}${path}`; + } + } + if (!joined) return "."; + return normalizeGlob(joined, { + extended, + globstar + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvZ2xvYi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5pbXBvcnQgeyBpc1dpbmRvd3MsIG9zVHlwZSB9IGZyb20gXCIuLi9fdXRpbC9vcy50c1wiO1xuaW1wb3J0IHsgU0VQLCBTRVBfUEFUVEVSTiB9IGZyb20gXCIuL3NlcGFyYXRvci50c1wiO1xuaW1wb3J0ICogYXMgX3dpbjMyIGZyb20gXCIuL3dpbjMyLnRzXCI7XG5pbXBvcnQgKiBhcyBfcG9zaXggZnJvbSBcIi4vcG9zaXgudHNcIjtcbmltcG9ydCB0eXBlIHsgT1NUeXBlIH0gZnJvbSBcIi4uL191dGlsL29zLnRzXCI7XG5cbmNvbnN0IHBhdGggPSBpc1dpbmRvd3MgPyBfd2luMzIgOiBfcG9zaXg7XG5jb25zdCB7IGpvaW4sIG5vcm1hbGl6ZSB9ID0gcGF0aDtcblxuZXhwb3J0IGludGVyZmFjZSBHbG9iT3B0aW9ucyB7XG4gIC8qKiBFeHRlbmRlZCBnbG9iIHN5bnRheC5cbiAgICogU2VlIGh0dHBzOi8vd3d3LmxpbnV4am91cm5hbC5jb20vY29udGVudC9iYXNoLWV4dGVuZGVkLWdsb2JiaW5nLiBEZWZhdWx0c1xuICAgKiB0byB0cnVlLiAqL1xuICBleHRlbmRlZD86IGJvb2xlYW47XG4gIC8qKiBHbG9ic3RhciBzeW50YXguXG4gICAqIFNlZSBodHRwczovL3d3dy5saW51eGpvdXJuYWwuY29tL2NvbnRlbnQvZ2xvYnN0YXItbmV3LWJhc2gtZ2xvYmJpbmctb3B0aW9uLlxuICAgKiBJZiBmYWxzZSwgYCoqYCBpcyB0cmVhdGVkIGxpa2UgYCpgLiBEZWZhdWx0cyB0byB0cnVlLiAqL1xuICBnbG9ic3Rhcj86IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIGdsb2JzdGFyIHNob3VsZCBiZSBjYXNlIGluc2Vuc2l0aXZlLiAqL1xuICBjYXNlSW5zZW5zaXRpdmU/OiBib29sZWFuO1xuICAvKiogT3BlcmF0aW5nIHN5c3RlbS4gRGVmYXVsdHMgdG8gdGhlIG5hdGl2ZSBPUy4gKi9cbiAgb3M/OiBPU1R5cGU7XG59XG5cbmV4cG9ydCB0eXBlIEdsb2JUb1JlZ0V4cE9wdGlvbnMgPSBHbG9iT3B0aW9ucztcblxuY29uc3QgcmVnRXhwRXNjYXBlQ2hhcnMgPSBbXG4gIFwiIVwiLFxuICBcIiRcIixcbiAgXCIoXCIsXG4gIFwiKVwiLFxuICBcIipcIixcbiAgXCIrXCIsXG4gIFwiLlwiLFxuICBcIj1cIixcbiAgXCI/XCIsXG4gIFwiW1wiLFxuICBcIlxcXFxcIixcbiAgXCJeXCIsXG4gIFwie1wiLFxuICBcInxcIixcbl07XG5jb25zdCByYW5nZUVzY2FwZUNoYXJzID0gW1wiLVwiLCBcIlxcXFxcIiwgXCJdXCJdO1xuXG4vKiogQ29udmVydCBhIGdsb2Igc3RyaW5nIHRvIGEgcmVndWxhciBleHByZXNzaW9uLlxuICpcbiAqIFRyaWVzIHRvIG1hdGNoIGJhc2ggZ2xvYiBleHBhbnNpb24gYXMgY2xvc2VseSBhcyBwb3NzaWJsZS5cbiAqXG4gKiBCYXNpYyBnbG9iIHN5bnRheDpcbiAqIC0gYCpgIC0gTWF0Y2hlcyBldmVyeXRoaW5nIHdpdGhvdXQgbGVhdmluZyB0aGUgcGF0aCBzZWdtZW50LlxuICogLSBgP2AgLSBNYXRjaGVzIGFueSBzaW5nbGUgY2hhcmFjdGVyLlxuICogLSBge2ZvbyxiYXJ9YCAtIE1hdGNoZXMgYGZvb2Agb3IgYGJhcmAuXG4gKiAtIGBbYWJjZF1gIC0gTWF0Y2hlcyBgYWAsIGBiYCwgYGNgIG9yIGBkYC5cbiAqIC0gYFthLWRdYCAtIE1hdGNoZXMgYGFgLCBgYmAsIGBjYCBvciBgZGAuXG4gKiAtIGBbIWFiY2RdYCAtIE1hdGNoZXMgYW55IHNpbmdsZSBjaGFyYWN0ZXIgYmVzaWRlcyBgYWAsIGBiYCwgYGNgIG9yIGBkYC5cbiAqIC0gYFtbOjxjbGFzcz46XV1gIC0gTWF0Y2hlcyBhbnkgY2hhcmFjdGVyIGJlbG9uZ2luZyB0byBgPGNsYXNzPmAuXG4gKiAgICAgLSBgW1s6YWxudW06XV1gIC0gTWF0Y2hlcyBhbnkgZGlnaXQgb3IgbGV0dGVyLlxuICogICAgIC0gYFtbOmRpZ2l0Ol1hYmNdYCAtIE1hdGNoZXMgYW55IGRpZ2l0LCBgYWAsIGBiYCBvciBgY2AuXG4gKiAgICAgLSBTZWUgaHR0cHM6Ly9mYWNlbGVzc3VzZXIuZ2l0aHViLmlvL3djbWF0Y2gvZ2xvYi8jcG9zaXgtY2hhcmFjdGVyLWNsYXNzZXNcbiAqICAgICAgIGZvciBhIGNvbXBsZXRlIGxpc3Qgb2Ygc3VwcG9ydGVkIGNoYXJhY3RlciBjbGFzc2VzLlxuICogLSBgXFxgIC0gRXNjYXBlcyB0aGUgbmV4dCBjaGFyYWN0ZXIgZm9yIGFuIGBvc2Agb3RoZXIgdGhhbiBgXCJ3aW5kb3dzXCJgLlxuICogLSBcXGAgLSBFc2NhcGVzIHRoZSBuZXh0IGNoYXJhY3RlciBmb3IgYG9zYCBzZXQgdG8gYFwid2luZG93c1wiYC5cbiAqIC0gYC9gIC0gUGF0aCBzZXBhcmF0b3IuXG4gKiAtIGBcXGAgLSBBZGRpdGlvbmFsIHBhdGggc2VwYXJhdG9yIG9ubHkgZm9yIGBvc2Agc2V0IHRvIGBcIndpbmRvd3NcImAuXG4gKlxuICogRXh0ZW5kZWQgc3ludGF4OlxuICogLSBSZXF1aXJlcyBgeyBleHRlbmRlZDogdHJ1ZSB9YC5cbiAqIC0gYD8oZm9vfGJhcilgIC0gTWF0Y2hlcyAwIG9yIDEgaW5zdGFuY2Ugb2YgYHtmb28sYmFyfWAuXG4gKiAtIGBAKGZvb3xiYXIpYCAtIE1hdGNoZXMgMSBpbnN0YW5jZSBvZiBge2ZvbyxiYXJ9YC4gVGhleSBiZWhhdmUgdGhlIHNhbWUuXG4gKiAtIGAqKGZvb3xiYXIpYCAtIE1hdGNoZXMgX25fIGluc3RhbmNlcyBvZiBge2ZvbyxiYXJ9YC5cbiAqIC0gYCsoZm9vfGJhcilgIC0gTWF0Y2hlcyBfbiA+IDBfIGluc3RhbmNlcyBvZiBge2ZvbyxiYXJ9YC5cbiAqIC0gYCEoZm9vfGJhcilgIC0gTWF0Y2hlcyBhbnl0aGluZyBvdGhlciB0aGFuIGB7Zm9vLGJhcn1gLlxuICogLSBTZWUgaHR0cHM6Ly93d3cubGludXhqb3VybmFsLmNvbS9jb250ZW50L2Jhc2gtZXh0ZW5kZWQtZ2xvYmJpbmcuXG4gKlxuICogR2xvYnN0YXIgc3ludGF4OlxuICogLSBSZXF1aXJlcyBgeyBnbG9ic3RhcjogdHJ1ZSB9YC5cbiAqIC0gYCoqYCAtIE1hdGNoZXMgYW55IG51bWJlciBvZiBhbnkgcGF0aCBzZWdtZW50cy5cbiAqICAgICAtIE11c3QgY29tcHJpc2UgaXRzIGVudGlyZSBwYXRoIHNlZ21lbnQgaW4gdGhlIHByb3ZpZGVkIGdsb2IuXG4gKiAtIFNlZSBodHRwczovL3d3dy5saW51eGpvdXJuYWwuY29tL2NvbnRlbnQvZ2xvYnN0YXItbmV3LWJhc2gtZ2xvYmJpbmctb3B0aW9uLlxuICpcbiAqIE5vdGUgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBUaGUgZ2VuZXJhdGVkIGBSZWdFeHBgIGlzIGFuY2hvcmVkIGF0IGJvdGggc3RhcnQgYW5kIGVuZC5cbiAqIC0gUmVwZWF0aW5nIGFuZCB0cmFpbGluZyBzZXBhcmF0b3JzIGFyZSB0b2xlcmF0ZWQuIFRyYWlsaW5nIHNlcGFyYXRvcnMgaW4gdGhlXG4gKiAgIHByb3ZpZGVkIGdsb2IgaGF2ZSBubyBtZWFuaW5nIGFuZCBhcmUgZGlzY2FyZGVkLlxuICogLSBBYnNvbHV0ZSBnbG9icyB3aWxsIG9ubHkgbWF0Y2ggYWJzb2x1dGUgcGF0aHMsIGV0Yy5cbiAqIC0gRW1wdHkgZ2xvYnMgd2lsbCBtYXRjaCBub3RoaW5nLlxuICogLSBBbnkgc3BlY2lhbCBnbG9iIHN5bnRheCBtdXN0IGJlIGNvbnRhaW5lZCB0byBvbmUgcGF0aCBzZWdtZW50LiBGb3IgZXhhbXBsZSxcbiAqICAgYD8oZm9vfGJhci9iYXopYCBpcyBpbnZhbGlkLiBUaGUgc2VwYXJhdG9yIHdpbGwgdGFrZSBwcmVjZWRlbmNlIGFuZCB0aGVcbiAqICAgZmlyc3Qgc2VnbWVudCBlbmRzIHdpdGggYW4gdW5jbG9zZWQgZ3JvdXAuXG4gKiAtIElmIGEgcGF0aCBzZWdtZW50IGVuZHMgd2l0aCB1bmNsb3NlZCBncm91cHMgb3IgYSBkYW5nbGluZyBlc2NhcGUgcHJlZml4LCBhXG4gKiAgIHBhcnNlIGVycm9yIGhhcyBvY2N1cnJlZC4gRXZlcnkgY2hhcmFjdGVyIGZvciB0aGF0IHNlZ21lbnQgaXMgdGFrZW5cbiAqICAgbGl0ZXJhbGx5IGluIHRoaXMgZXZlbnQuXG4gKlxuICogTGltaXRhdGlvbnM6XG4gKiAtIEEgbmVnYXRpdmUgZ3JvdXAgbGlrZSBgIShmb298YmFyKWAgd2lsbCB3cm9uZ2x5IGJlIGNvbnZlcnRlZCB0byBhIG5lZ2F0aXZlXG4gKiAgIGxvb2stYWhlYWQgZm9sbG93ZWQgYnkgYSB3aWxkY2FyZC4gVGhpcyBtZWFucyB0aGF0IGAhKGZvbykuanNgIHdpbGwgd3JvbmdseVxuICogICBmYWlsIHRvIG1hdGNoIGBmb29iYXIuanNgLCBldmVuIHRob3VnaCBgZm9vYmFyYCBpcyBub3QgYGZvb2AuIEVmZmVjdGl2ZWx5LFxuICogICBgIShmb298YmFyKWAgaXMgdHJlYXRlZCBsaWtlIGAhKEAoZm9vfGJhcikqKWAuIFRoaXMgd2lsbCB3b3JrIGNvcnJlY3RseSBpZlxuICogICB0aGUgZ3JvdXAgb2NjdXJzIG5vdCBuZXN0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgc2VnbWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnbG9iVG9SZWdFeHAoXG4gIGdsb2I6IHN0cmluZyxcbiAge1xuICAgIGV4dGVuZGVkID0gdHJ1ZSxcbiAgICBnbG9ic3RhcjogZ2xvYnN0YXJPcHRpb24gPSB0cnVlLFxuICAgIG9zID0gb3NUeXBlLFxuICAgIGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlLFxuICB9OiBHbG9iVG9SZWdFeHBPcHRpb25zID0ge30sXG4pOiBSZWdFeHAge1xuICBpZiAoZ2xvYiA9PSBcIlwiKSB7XG4gICAgcmV0dXJuIC8oPyEpLztcbiAgfVxuXG4gIGNvbnN0IHNlcCA9IG9zID09IFwid2luZG93c1wiID8gXCIoPzpcXFxcXFxcXHwvKStcIiA6IFwiLytcIjtcbiAgY29uc3Qgc2VwTWF5YmUgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFwiKD86XFxcXFxcXFx8LykqXCIgOiBcIi8qXCI7XG4gIGNvbnN0IHNlcHMgPSBvcyA9PSBcIndpbmRvd3NcIiA/IFtcIlxcXFxcIiwgXCIvXCJdIDogW1wiL1wiXTtcbiAgY29uc3QgZ2xvYnN0YXIgPSBvcyA9PSBcIndpbmRvd3NcIlxuICAgID8gXCIoPzpbXlxcXFxcXFxcL10qKD86XFxcXFxcXFx8L3wkKSspKlwiXG4gICAgOiBcIig/OlteL10qKD86L3wkKSspKlwiO1xuICBjb25zdCB3aWxkY2FyZCA9IG9zID09IFwid2luZG93c1wiID8gXCJbXlxcXFxcXFxcL10qXCIgOiBcIlteL10qXCI7XG4gIGNvbnN0IGVzY2FwZVByZWZpeCA9IG9zID09IFwid2luZG93c1wiID8gXCJgXCIgOiBcIlxcXFxcIjtcblxuICAvLyBSZW1vdmUgdHJhaWxpbmcgc2VwYXJhdG9ycy5cbiAgbGV0IG5ld0xlbmd0aCA9IGdsb2IubGVuZ3RoO1xuICBmb3IgKDsgbmV3TGVuZ3RoID4gMSAmJiBzZXBzLmluY2x1ZGVzKGdsb2JbbmV3TGVuZ3RoIC0gMV0pOyBuZXdMZW5ndGgtLSk7XG4gIGdsb2IgPSBnbG9iLnNsaWNlKDAsIG5ld0xlbmd0aCk7XG5cbiAgbGV0IHJlZ0V4cFN0cmluZyA9IFwiXCI7XG5cbiAgLy8gVGVybWluYXRlcyBjb3JyZWN0bHkuIFRydXN0IHRoYXQgYGpgIGlzIGluY3JlbWVudGVkIGV2ZXJ5IGl0ZXJhdGlvbi5cbiAgZm9yIChsZXQgaiA9IDA7IGogPCBnbG9iLmxlbmd0aDspIHtcbiAgICBsZXQgc2VnbWVudCA9IFwiXCI7XG4gICAgY29uc3QgZ3JvdXBTdGFjazogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgaW5SYW5nZSA9IGZhbHNlO1xuICAgIGxldCBpbkVzY2FwZSA9IGZhbHNlO1xuICAgIGxldCBlbmRzV2l0aFNlcCA9IGZhbHNlO1xuICAgIGxldCBpID0gajtcblxuICAgIC8vIFRlcm1pbmF0ZXMgd2l0aCBgaWAgYXQgdGhlIG5vbi1pbmNsdXNpdmUgZW5kIG9mIHRoZSBjdXJyZW50IHNlZ21lbnQuXG4gICAgZm9yICg7IGkgPCBnbG9iLmxlbmd0aCAmJiAhc2Vwcy5pbmNsdWRlcyhnbG9iW2ldKTsgaSsrKSB7XG4gICAgICBpZiAoaW5Fc2NhcGUpIHtcbiAgICAgICAgaW5Fc2NhcGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgZXNjYXBlQ2hhcnMgPSBpblJhbmdlID8gcmFuZ2VFc2NhcGVDaGFycyA6IHJlZ0V4cEVzY2FwZUNoYXJzO1xuICAgICAgICBzZWdtZW50ICs9IGVzY2FwZUNoYXJzLmluY2x1ZGVzKGdsb2JbaV0pID8gYFxcXFwke2dsb2JbaV19YCA6IGdsb2JbaV07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBlc2NhcGVQcmVmaXgpIHtcbiAgICAgICAgaW5Fc2NhcGUgPSB0cnVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCJbXCIpIHtcbiAgICAgICAgaWYgKCFpblJhbmdlKSB7XG4gICAgICAgICAgaW5SYW5nZSA9IHRydWU7XG4gICAgICAgICAgc2VnbWVudCArPSBcIltcIjtcbiAgICAgICAgICBpZiAoZ2xvYltpICsgMV0gPT0gXCIhXCIpIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIHNlZ21lbnQgKz0gXCJeXCI7XG4gICAgICAgICAgfSBlbHNlIGlmIChnbG9iW2kgKyAxXSA9PSBcIl5cIikge1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgc2VnbWVudCArPSBcIlxcXFxeXCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGdsb2JbaSArIDFdID09IFwiOlwiKSB7XG4gICAgICAgICAgbGV0IGsgPSBpICsgMTtcbiAgICAgICAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgICAgICAgIHdoaWxlIChnbG9iW2sgKyAxXSAhPSBudWxsICYmIGdsb2JbayArIDFdICE9IFwiOlwiKSB7XG4gICAgICAgICAgICB2YWx1ZSArPSBnbG9iW2sgKyAxXTtcbiAgICAgICAgICAgIGsrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGdsb2JbayArIDFdID09IFwiOlwiICYmIGdsb2JbayArIDJdID09IFwiXVwiKSB7XG4gICAgICAgICAgICBpID0gayArIDI7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJhbG51bVwiKSBzZWdtZW50ICs9IFwiXFxcXGRBLVphLXpcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiYWxwaGFcIikgc2VnbWVudCArPSBcIkEtWmEtelwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJhc2NpaVwiKSBzZWdtZW50ICs9IFwiXFx4MDAtXFx4N0ZcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiYmxhbmtcIikgc2VnbWVudCArPSBcIlxcdCBcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiY250cmxcIikgc2VnbWVudCArPSBcIlxceDAwLVxceDFGXFx4N0ZcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwiZGlnaXRcIikgc2VnbWVudCArPSBcIlxcXFxkXCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcImdyYXBoXCIpIHNlZ21lbnQgKz0gXCJcXHgyMS1cXHg3RVwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJsb3dlclwiKSBzZWdtZW50ICs9IFwiYS16XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcInByaW50XCIpIHNlZ21lbnQgKz0gXCJcXHgyMC1cXHg3RVwiO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gXCJwdW5jdFwiKSB7XG4gICAgICAgICAgICAgIHNlZ21lbnQgKz0gXCIhXFxcIiMkJSYnKCkqKyxcXFxcLS4vOjs8PT4/QFtcXFxcXFxcXFxcXFxdXl/igJh7fH1+XCI7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IFwic3BhY2VcIikgc2VnbWVudCArPSBcIlxcXFxzXFx2XCI7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSBcInVwcGVyXCIpIHNlZ21lbnQgKz0gXCJBLVpcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwid29yZFwiKSBzZWdtZW50ICs9IFwiXFxcXHdcIjtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwieGRpZ2l0XCIpIHNlZ21lbnQgKz0gXCJcXFxcZEEtRmEtZlwiO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiXVwiICYmIGluUmFuZ2UpIHtcbiAgICAgICAgaW5SYW5nZSA9IGZhbHNlO1xuICAgICAgICBzZWdtZW50ICs9IFwiXVwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluUmFuZ2UpIHtcbiAgICAgICAgaWYgKGdsb2JbaV0gPT0gXCJcXFxcXCIpIHtcbiAgICAgICAgICBzZWdtZW50ICs9IGBcXFxcXFxcXGA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VnbWVudCArPSBnbG9iW2ldO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGdsb2JbaV0gPT0gXCIpXCIgJiYgZ3JvdXBTdGFjay5sZW5ndGggPiAwICYmXG4gICAgICAgIGdyb3VwU3RhY2tbZ3JvdXBTdGFjay5sZW5ndGggLSAxXSAhPSBcIkJSQUNFXCJcbiAgICAgICkge1xuICAgICAgICBzZWdtZW50ICs9IFwiKVwiO1xuICAgICAgICBjb25zdCB0eXBlID0gZ3JvdXBTdGFjay5wb3AoKSE7XG4gICAgICAgIGlmICh0eXBlID09IFwiIVwiKSB7XG4gICAgICAgICAgc2VnbWVudCArPSB3aWxkY2FyZDtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlICE9IFwiQFwiKSB7XG4gICAgICAgICAgc2VnbWVudCArPSB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGdsb2JbaV0gPT0gXCJ8XCIgJiYgZ3JvdXBTdGFjay5sZW5ndGggPiAwICYmXG4gICAgICAgIGdyb3VwU3RhY2tbZ3JvdXBTdGFjay5sZW5ndGggLSAxXSAhPSBcIkJSQUNFXCJcbiAgICAgICkge1xuICAgICAgICBzZWdtZW50ICs9IFwifFwiO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JbaV0gPT0gXCIrXCIgJiYgZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBncm91cFN0YWNrLnB1c2goXCIrXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIkBcIiAmJiBleHRlbmRlZCAmJiBnbG9iW2kgKyAxXSA9PSBcIihcIikge1xuICAgICAgICBpKys7XG4gICAgICAgIGdyb3VwU3RhY2sucHVzaChcIkBcIik7XG4gICAgICAgIHNlZ21lbnQgKz0gXCIoPzpcIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwiP1wiKSB7XG4gICAgICAgIGlmIChleHRlbmRlZCAmJiBnbG9iW2kgKyAxXSA9PSBcIihcIikge1xuICAgICAgICAgIGkrKztcbiAgICAgICAgICBncm91cFN0YWNrLnB1c2goXCI/XCIpO1xuICAgICAgICAgIHNlZ21lbnQgKz0gXCIoPzpcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZWdtZW50ICs9IFwiLlwiO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIiFcIiAmJiBleHRlbmRlZCAmJiBnbG9iW2kgKyAxXSA9PSBcIihcIikge1xuICAgICAgICBpKys7XG4gICAgICAgIGdyb3VwU3RhY2sucHVzaChcIiFcIik7XG4gICAgICAgIHNlZ21lbnQgKz0gXCIoPyFcIjtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbG9iW2ldID09IFwie1wiKSB7XG4gICAgICAgIGdyb3VwU3RhY2sucHVzaChcIkJSQUNFXCIpO1xuICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIn1cIiAmJiBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gPT0gXCJCUkFDRVwiKSB7XG4gICAgICAgIGdyb3VwU3RhY2sucG9wKCk7XG4gICAgICAgIHNlZ21lbnQgKz0gXCIpXCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIixcIiAmJiBncm91cFN0YWNrW2dyb3VwU3RhY2subGVuZ3RoIC0gMV0gPT0gXCJCUkFDRVwiKSB7XG4gICAgICAgIHNlZ21lbnQgKz0gXCJ8XCI7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2xvYltpXSA9PSBcIipcIikge1xuICAgICAgICBpZiAoZXh0ZW5kZWQgJiYgZ2xvYltpICsgMV0gPT0gXCIoXCIpIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgICAgZ3JvdXBTdGFjay5wdXNoKFwiKlwiKTtcbiAgICAgICAgICBzZWdtZW50ICs9IFwiKD86XCI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgcHJldkNoYXIgPSBnbG9iW2kgLSAxXTtcbiAgICAgICAgICBsZXQgbnVtU3RhcnMgPSAxO1xuICAgICAgICAgIHdoaWxlIChnbG9iW2kgKyAxXSA9PSBcIipcIikge1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgbnVtU3RhcnMrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgbmV4dENoYXIgPSBnbG9iW2kgKyAxXTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBnbG9ic3Rhck9wdGlvbiAmJiBudW1TdGFycyA9PSAyICYmXG4gICAgICAgICAgICBbLi4uc2VwcywgdW5kZWZpbmVkXS5pbmNsdWRlcyhwcmV2Q2hhcikgJiZcbiAgICAgICAgICAgIFsuLi5zZXBzLCB1bmRlZmluZWRdLmluY2x1ZGVzKG5leHRDaGFyKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgc2VnbWVudCArPSBnbG9ic3RhcjtcbiAgICAgICAgICAgIGVuZHNXaXRoU2VwID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VnbWVudCArPSB3aWxkY2FyZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHNlZ21lbnQgKz0gcmVnRXhwRXNjYXBlQ2hhcnMuaW5jbHVkZXMoZ2xvYltpXSkgPyBgXFxcXCR7Z2xvYltpXX1gIDogZ2xvYltpXTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgdW5jbG9zZWQgZ3JvdXBzIG9yIGEgZGFuZ2xpbmcgYmFja3NsYXNoLlxuICAgIGlmIChncm91cFN0YWNrLmxlbmd0aCA+IDAgfHwgaW5SYW5nZSB8fCBpbkVzY2FwZSkge1xuICAgICAgLy8gUGFyc2UgZmFpbHVyZS4gVGFrZSBhbGwgY2hhcmFjdGVycyBmcm9tIHRoaXMgc2VnbWVudCBsaXRlcmFsbHkuXG4gICAgICBzZWdtZW50ID0gXCJcIjtcbiAgICAgIGZvciAoY29uc3QgYyBvZiBnbG9iLnNsaWNlKGosIGkpKSB7XG4gICAgICAgIHNlZ21lbnQgKz0gcmVnRXhwRXNjYXBlQ2hhcnMuaW5jbHVkZXMoYykgPyBgXFxcXCR7Y31gIDogYztcbiAgICAgICAgZW5kc1dpdGhTZXAgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZWdFeHBTdHJpbmcgKz0gc2VnbWVudDtcbiAgICBpZiAoIWVuZHNXaXRoU2VwKSB7XG4gICAgICByZWdFeHBTdHJpbmcgKz0gaSA8IGdsb2IubGVuZ3RoID8gc2VwIDogc2VwTWF5YmU7XG4gICAgICBlbmRzV2l0aFNlcCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gVGVybWluYXRlcyB3aXRoIGBpYCBhdCB0aGUgc3RhcnQgb2YgdGhlIG5leHQgc2VnbWVudC5cbiAgICB3aGlsZSAoc2Vwcy5pbmNsdWRlcyhnbG9iW2ldKSkgaSsrO1xuXG4gICAgLy8gQ2hlY2sgdGhhdCB0aGUgbmV4dCB2YWx1ZSBvZiBgamAgaXMgaW5kZWVkIGhpZ2hlciB0aGFuIHRoZSBjdXJyZW50IHZhbHVlLlxuICAgIGlmICghKGkgPiBqKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXNzZXJ0aW9uIGZhaWx1cmU6IGkgPiBqIChwb3RlbnRpYWwgaW5maW5pdGUgbG9vcClcIik7XG4gICAgfVxuICAgIGogPSBpO1xuICB9XG5cbiAgcmVnRXhwU3RyaW5nID0gYF4ke3JlZ0V4cFN0cmluZ30kYDtcbiAgcmV0dXJuIG5ldyBSZWdFeHAocmVnRXhwU3RyaW5nLCBjYXNlSW5zZW5zaXRpdmUgPyBcImlcIiA6IFwiXCIpO1xufVxuXG4vKiogVGVzdCB3aGV0aGVyIHRoZSBnaXZlbiBzdHJpbmcgaXMgYSBnbG9iICovXG5leHBvcnQgZnVuY3Rpb24gaXNHbG9iKHN0cjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IGNoYXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0geyBcIntcIjogXCJ9XCIsIFwiKFwiOiBcIilcIiwgXCJbXCI6IFwiXVwiIH07XG4gIGNvbnN0IHJlZ2V4ID1cbiAgICAvXFxcXCguKXwoXiF8XFwqfFxcP3xbXFxdLispXVxcP3xcXFtbXlxcXFxcXF1dK1xcXXxcXHtbXlxcXFx9XStcXH18XFwoXFw/WzohPV1bXlxcXFwpXStcXCl8XFwoW158XStcXHxbXlxcXFwpXStcXCkpLztcblxuICBpZiAoc3RyID09PSBcIlwiKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuXG4gIHdoaWxlICgobWF0Y2ggPSByZWdleC5leGVjKHN0cikpKSB7XG4gICAgaWYgKG1hdGNoWzJdKSByZXR1cm4gdHJ1ZTtcbiAgICBsZXQgaWR4ID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGg7XG5cbiAgICAvLyBpZiBhbiBvcGVuIGJyYWNrZXQvYnJhY2UvcGFyZW4gaXMgZXNjYXBlZCxcbiAgICAvLyBzZXQgdGhlIGluZGV4IHRvIHRoZSBuZXh0IGNsb3NpbmcgY2hhcmFjdGVyXG4gICAgY29uc3Qgb3BlbiA9IG1hdGNoWzFdO1xuICAgIGNvbnN0IGNsb3NlID0gb3BlbiA/IGNoYXJzW29wZW5dIDogbnVsbDtcbiAgICBpZiAob3BlbiAmJiBjbG9zZSkge1xuICAgICAgY29uc3QgbiA9IHN0ci5pbmRleE9mKGNsb3NlLCBpZHgpO1xuICAgICAgaWYgKG4gIT09IC0xKSB7XG4gICAgICAgIGlkeCA9IG4gKyAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIHN0ciA9IHN0ci5zbGljZShpZHgpO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogTGlrZSBub3JtYWxpemUoKSwgYnV0IGRvZXNuJ3QgY29sbGFwc2UgXCIqKlxcLy4uXCIgd2hlbiBgZ2xvYnN0YXJgIGlzIHRydWUuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplR2xvYihcbiAgZ2xvYjogc3RyaW5nLFxuICB7IGdsb2JzdGFyID0gZmFsc2UgfTogR2xvYk9wdGlvbnMgPSB7fSxcbik6IHN0cmluZyB7XG4gIGlmIChnbG9iLm1hdGNoKC9cXDAvZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEdsb2IgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzOiBcIiR7Z2xvYn1cImApO1xuICB9XG4gIGlmICghZ2xvYnN0YXIpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplKGdsb2IpO1xuICB9XG4gIGNvbnN0IHMgPSBTRVBfUEFUVEVSTi5zb3VyY2U7XG4gIGNvbnN0IGJhZFBhcmVudFBhdHRlcm4gPSBuZXcgUmVnRXhwKFxuICAgIGAoPzw9KCR7c318XilcXFxcKlxcXFwqJHtzfSlcXFxcLlxcXFwuKD89JHtzfXwkKWAsXG4gICAgXCJnXCIsXG4gICk7XG4gIHJldHVybiBub3JtYWxpemUoZ2xvYi5yZXBsYWNlKGJhZFBhcmVudFBhdHRlcm4sIFwiXFwwXCIpKS5yZXBsYWNlKC9cXDAvZywgXCIuLlwiKTtcbn1cblxuLyoqIExpa2Ugam9pbigpLCBidXQgZG9lc24ndCBjb2xsYXBzZSBcIioqXFwvLi5cIiB3aGVuIGBnbG9ic3RhcmAgaXMgdHJ1ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqb2luR2xvYnMoXG4gIGdsb2JzOiBzdHJpbmdbXSxcbiAgeyBleHRlbmRlZCA9IHRydWUsIGdsb2JzdGFyID0gZmFsc2UgfTogR2xvYk9wdGlvbnMgPSB7fSxcbik6IHN0cmluZyB7XG4gIGlmICghZ2xvYnN0YXIgfHwgZ2xvYnMubGVuZ3RoID09IDApIHtcbiAgICByZXR1cm4gam9pbiguLi5nbG9icyk7XG4gIH1cbiAgaWYgKGdsb2JzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuICBsZXQgam9pbmVkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgZ2xvYiBvZiBnbG9icykge1xuICAgIGNvbnN0IHBhdGggPSBnbG9iO1xuICAgIGlmIChwYXRoLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICgham9pbmVkKSBqb2luZWQgPSBwYXRoO1xuICAgICAgZWxzZSBqb2luZWQgKz0gYCR7U0VQfSR7cGF0aH1gO1xuICAgIH1cbiAgfVxuICBpZiAoIWpvaW5lZCkgcmV0dXJuIFwiLlwiO1xuICByZXR1cm4gbm9ybWFsaXplR2xvYihqb2luZWQsIHsgZXh0ZW5kZWQsIGdsb2JzdGFyIH0pO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxxQ0FBcUM7QUFFckMsU0FBUyxTQUFTLEVBQUUsTUFBTSxRQUFRLGlCQUFpQjtBQUNuRCxTQUFTLEdBQUcsRUFBRSxXQUFXLFFBQVEsaUJBQWlCO0FBQ2xELFlBQVksWUFBWSxhQUFhO0FBQ3JDLFlBQVksWUFBWSxhQUFhO0FBR3JDLE1BQU0sT0FBTyxZQUFZLFNBQVMsTUFBTTtBQUN4QyxNQUFNLEVBQUUsS0FBSSxFQUFFLFVBQVMsRUFBRSxHQUFHO0FBbUI1QixNQUFNLG9CQUFvQjtJQUN4QjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0NBQ0Q7QUFDRCxNQUFNLG1CQUFtQjtJQUFDO0lBQUs7SUFBTTtDQUFJO0FBRXpDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7NERBc0Q0RCxHQUM1RCxPQUFPLFNBQVMsYUFDZCxJQUFZLEVBQ1osRUFDRSxVQUFXLElBQUksQ0FBQSxFQUNmLFVBQVUsaUJBQWlCLElBQUksQ0FBQSxFQUMvQixJQUFLLE9BQU0sRUFDWCxpQkFBa0IsS0FBSyxDQUFBLEVBQ0gsR0FBRyxDQUFDLENBQUMsRUFDbkI7SUFDUixJQUFJLFFBQVEsSUFBSTtRQUNkLE9BQU87SUFDVCxDQUFDO0lBRUQsTUFBTSxNQUFNLE1BQU0sWUFBWSxnQkFBZ0IsSUFBSTtJQUNsRCxNQUFNLFdBQVcsTUFBTSxZQUFZLGdCQUFnQixJQUFJO0lBQ3ZELE1BQU0sT0FBTyxNQUFNLFlBQVk7UUFBQztRQUFNO0tBQUksR0FBRztRQUFDO0tBQUk7SUFDbEQsTUFBTSxXQUFXLE1BQU0sWUFDbkIsZ0NBQ0Esb0JBQW9CO0lBQ3hCLE1BQU0sV0FBVyxNQUFNLFlBQVks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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/7HctcYJMo9RPESb8_8SnGpYMx1U.js b/tests/__snapshots__/transpile/url/modules/7HctcYJMo9RPESb8_8SnGpYMx1U.js new file mode 100644 index 0000000..b7663e5 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/7HctcYJMo9RPESb8_8SnGpYMx1U.js @@ -0,0 +1,2 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2lvL3R5cGVzLmQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cblxuZXhwb3J0IGludGVyZmFjZSBSZWFkZXIge1xuICAvKiogUmVhZHMgdXAgdG8gYHAuYnl0ZUxlbmd0aGAgYnl0ZXMgaW50byBgcGAuIEl0IHJlc29sdmVzIHRvIHRoZSBudW1iZXIgb2ZcbiAgICogYnl0ZXMgcmVhZCAoYDBgIDwgYG5gIDw9IGBwLmJ5dGVMZW5ndGhgKSBhbmQgcmVqZWN0cyBpZiBhbnkgZXJyb3JcbiAgICogZW5jb3VudGVyZWQuIEV2ZW4gaWYgYHJlYWQoKWAgcmVzb2x2ZXMgdG8gYG5gIDwgYHAuYnl0ZUxlbmd0aGAsIGl0IG1heVxuICAgKiB1c2UgYWxsIG9mIGBwYCBhcyBzY3JhdGNoIHNwYWNlIGR1cmluZyB0aGUgY2FsbC4gSWYgc29tZSBkYXRhIGlzXG4gICAqIGF2YWlsYWJsZSBidXQgbm90IGBwLmJ5dGVMZW5ndGhgIGJ5dGVzLCBgcmVhZCgpYCBjb252ZW50aW9uYWxseSByZXNvbHZlc1xuICAgKiB0byB3aGF0IGlzIGF2YWlsYWJsZSBpbnN0ZWFkIG9mIHdhaXRpbmcgZm9yIG1vcmUuXG4gICAqXG4gICAqIFdoZW4gYHJlYWQoKWAgZW5jb3VudGVycyBlbmQtb2YtZmlsZSBjb25kaXRpb24sIGl0IHJlc29sdmVzIHRvIEVPRlxuICAgKiAoYG51bGxgKS5cbiAgICpcbiAgICogV2hlbiBgcmVhZCgpYCBlbmNvdW50ZXJzIGFuIGVycm9yLCBpdCByZWplY3RzIHdpdGggYW4gZXJyb3IuXG4gICAqXG4gICAqIENhbGxlcnMgc2hvdWxkIGFsd2F5cyBwcm9jZXNzIHRoZSBgbmAgPiBgMGAgYnl0ZXMgcmV0dXJuZWQgYmVmb3JlXG4gICAqIGNvbnNpZGVyaW5nIHRoZSBFT0YgKGBudWxsYCkuIERvaW5nIHNvIGNvcnJlY3RseSBoYW5kbGVzIEkvTyBlcnJvcnMgdGhhdFxuICAgKiBoYXBwZW4gYWZ0ZXIgcmVhZGluZyBzb21lIGJ5dGVzIGFuZCBhbHNvIGJvdGggb2YgdGhlIGFsbG93ZWQgRU9GXG4gICAqIGJlaGF2aW9ycy5cbiAgICpcbiAgICogSW1wbGVtZW50YXRpb25zIHNob3VsZCBub3QgcmV0YWluIGEgcmVmZXJlbmNlIHRvIGBwYC5cbiAgICpcbiAgICogVXNlIGl0ZXIoKSBmcm9tIGh0dHBzOi8vZGVuby5sYW5kL3N0ZC9pby91dGlsLnRzIHRvIHR1cm4gYSBSZWFkZXIgaW50byBhblxuICAgKiBBc3luY0l0ZXJhdG9yLlxuICAgKi9cbiAgcmVhZChwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXIgfCBudWxsPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWFkZXJTeW5jIHtcbiAgLyoqIFJlYWRzIHVwIHRvIGBwLmJ5dGVMZW5ndGhgIGJ5dGVzIGludG8gYHBgLiBJdCByZXNvbHZlcyB0byB0aGUgbnVtYmVyXG4gICAqIG9mIGJ5dGVzIHJlYWQgKGAwYCA8IGBuYCA8PSBgcC5ieXRlTGVuZ3RoYCkgYW5kIHJlamVjdHMgaWYgYW55IGVycm9yXG4gICAqIGVuY291bnRlcmVkLiBFdmVuIGlmIGByZWFkKClgIHJldHVybnMgYG5gIDwgYHAuYnl0ZUxlbmd0aGAsIGl0IG1heSB1c2VcbiAgICogYWxsIG9mIGBwYCBhcyBzY3JhdGNoIHNwYWNlIGR1cmluZyB0aGUgY2FsbC4gSWYgc29tZSBkYXRhIGlzIGF2YWlsYWJsZVxuICAgKiBidXQgbm90IGBwLmJ5dGVMZW5ndGhgIGJ5dGVzLCBgcmVhZCgpYCBjb252ZW50aW9uYWxseSByZXR1cm5zIHdoYXQgaXNcbiAgICogYXZhaWxhYmxlIGluc3RlYWQgb2Ygd2FpdGluZyBmb3IgbW9yZS5cbiAgICpcbiAgICogV2hlbiBgcmVhZFN5bmMoKWAgZW5jb3VudGVycyBlbmQtb2YtZmlsZSBjb25kaXRpb24sIGl0IHJldHVybnMgRU9GXG4gICAqIChgbnVsbGApLlxuICAgKlxuICAgKiBXaGVuIGByZWFkU3luYygpYCBlbmNvdW50ZXJzIGFuIGVycm9yLCBpdCB0aHJvd3Mgd2l0aCBhbiBlcnJvci5cbiAgICpcbiAgICogQ2FsbGVycyBzaG91bGQgYWx3YXlzIHByb2Nlc3MgdGhlIGBuYCA+IGAwYCBieXRlcyByZXR1cm5lZCBiZWZvcmVcbiAgICogY29uc2lkZXJpbmcgdGhlIEVPRiAoYG51bGxgKS4gRG9pbmcgc28gY29ycmVjdGx5IGhhbmRsZXMgSS9PIGVycm9ycyB0aGF0IGhhcHBlblxuICAgKiBhZnRlciByZWFkaW5nIHNvbWUgYnl0ZXMgYW5kIGFsc28gYm90aCBvZiB0aGUgYWxsb3dlZCBFT0YgYmVoYXZpb3JzLlxuICAgKlxuICAgKiBJbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCByZXRhaW4gYSByZWZlcmVuY2UgdG8gYHBgLlxuICAgKlxuICAgKiBVc2UgaXRlclN5bmMoKSBmcm9tIGh0dHBzOi8vZGVuby5sYW5kL3N0ZC9pby91dGlsLnRzIHRvIHR1cm4gYSBSZWFkZXJTeW5jXG4gICAqIGludG8gYW4gSXRlcmF0b3IuXG4gICAqL1xuICByZWFkU3luYyhwOiBVaW50OEFycmF5KTogbnVtYmVyIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICAvKiogV3JpdGVzIGBwLmJ5dGVMZW5ndGhgIGJ5dGVzIGZyb20gYHBgIHRvIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RyZWFtLiBJdFxuICAgKiByZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gZnJvbSBgcGAgKGAwYCA8PSBgbmAgPD1cbiAgICogYHAuYnl0ZUxlbmd0aGApIG9yIHJlamVjdCB3aXRoIHRoZSBlcnJvciBlbmNvdW50ZXJlZCB0aGF0IGNhdXNlZCB0aGVcbiAgICogd3JpdGUgdG8gc3RvcCBlYXJseS4gYHdyaXRlKClgIG11c3QgcmVqZWN0IHdpdGggYSBub24tbnVsbCBlcnJvciBpZlxuICAgKiB3b3VsZCByZXNvbHZlIHRvIGBuYCA8IGBwLmJ5dGVMZW5ndGhgLiBgd3JpdGUoKWAgbXVzdCBub3QgbW9kaWZ5IHRoZVxuICAgKiBzbGljZSBkYXRhLCBldmVuIHRlbXBvcmFyaWx5LlxuICAgKlxuICAgKiBJbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCByZXRhaW4gYSByZWZlcmVuY2UgdG8gYHBgLlxuICAgKi9cbiAgd3JpdGUocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXJTeW5jIHtcbiAgLyoqIFdyaXRlcyBgcC5ieXRlTGVuZ3RoYCBieXRlcyBmcm9tIGBwYCB0byB0aGUgdW5kZXJseWluZyBkYXRhXG4gICAqIHN0cmVhbS4gSXQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gZnJvbSBgcGAgKGAwYCA8PSBgbmBcbiAgICogPD0gYHAuYnl0ZUxlbmd0aGApIGFuZCBhbnkgZXJyb3IgZW5jb3VudGVyZWQgdGhhdCBjYXVzZWQgdGhlIHdyaXRlIHRvXG4gICAqIHN0b3AgZWFybHkuIGB3cml0ZVN5bmMoKWAgbXVzdCB0aHJvdyBhIG5vbi1udWxsIGVycm9yIGlmIGl0IHJldHVybnMgYG5gIDxcbiAgICogYHAuYnl0ZUxlbmd0aGAuIGB3cml0ZVN5bmMoKWAgbXVzdCBub3QgbW9kaWZ5IHRoZSBzbGljZSBkYXRhLCBldmVuXG4gICAqIHRlbXBvcmFyaWx5LlxuICAgKlxuICAgKiBJbXBsZW1lbnRhdGlvbnMgc2hvdWxkIG5vdCByZXRhaW4gYSByZWZlcmVuY2UgdG8gYHBgLlxuICAgKi9cbiAgd3JpdGVTeW5jKHA6IFVpbnQ4QXJyYXkpOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xvc2VyIHtcbiAgY2xvc2UoKTogdm9pZDtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEUifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/7VWYTDioIHKQJaGRjtUtSbiHVG8.js b/tests/__snapshots__/transpile/url/modules/7VWYTDioIHKQJaGRjtUtSbiHVG8.js new file mode 100644 index 0000000..18b20d4 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/7VWYTDioIHKQJaGRjtUtSbiHVG8.js @@ -0,0 +1,96 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +import { CHAR_BACKWARD_SLASH, CHAR_DOT, CHAR_FORWARD_SLASH, CHAR_LOWERCASE_A, CHAR_LOWERCASE_Z, CHAR_UPPERCASE_A, CHAR_UPPERCASE_Z } from "./_constants.ts"; +export function assertPath(path) { + if (typeof path !== "string") { + throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`); + } +} +export function isPosixPathSeparator(code) { + return code === CHAR_FORWARD_SLASH; +} +export function isPathSeparator(code) { + return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH; +} +export function isWindowsDeviceRoot(code) { + return code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z || code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z; +} +// Resolves . and .. elements in a path with directory names +export function normalizeString(path, allowAboveRoot, separator, isPathSeparator) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let code; + for(let i = 0, len = path.length; i <= len; ++i){ + if (i < len) code = path.charCodeAt(i); + else if (isPathSeparator(code)) break; + else code = CHAR_FORWARD_SLASH; + if (isPathSeparator(code)) { + if (lastSlash === i - 1 || dots === 1) { + // NOOP + } else if (lastSlash !== i - 1 && dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== CHAR_DOT || res.charCodeAt(res.length - 2) !== CHAR_DOT) { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf(separator); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); + } + lastSlash = i; + dots = 0; + continue; + } else if (res.length === 2 || res.length === 1) { + res = ""; + lastSegmentLength = 0; + lastSlash = i; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + if (res.length > 0) res += `${separator}..`; + else res = ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) res += separator + path.slice(lastSlash + 1, i); + else res = path.slice(lastSlash + 1, i); + lastSegmentLength = i - lastSlash - 1; + } + lastSlash = i; + dots = 0; + } else if (code === CHAR_DOT && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +export function _format(sep, pathObject) { + const dir = pathObject.dir || pathObject.root; + const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); + if (!dir) return base; + if (dir === pathObject.root) return dir + base; + return dir + sep + base; +} +const WHITESPACE_ENCODINGS = { + "\u0009": "%09", + "\u000A": "%0A", + "\u000B": "%0B", + "\u000C": "%0C", + "\u000D": "%0D", + "\u0020": "%20" +}; +export function encodeWhitespace(string) { + return string.replaceAll(/[\s]/g, (c)=>{ + return WHITESPACE_ENCODINGS[c] ?? c; + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvX3V0aWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QgfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQge1xuICBDSEFSX0JBQ0tXQVJEX1NMQVNILFxuICBDSEFSX0RPVCxcbiAgQ0hBUl9GT1JXQVJEX1NMQVNILFxuICBDSEFSX0xPV0VSQ0FTRV9BLFxuICBDSEFSX0xPV0VSQ0FTRV9aLFxuICBDSEFSX1VQUEVSQ0FTRV9BLFxuICBDSEFSX1VQUEVSQ0FTRV9aLFxufSBmcm9tIFwiLi9fY29uc3RhbnRzLnRzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRQYXRoKHBhdGg6IHN0cmluZyk6IHZvaWQge1xuICBpZiAodHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYFBhdGggbXVzdCBiZSBhIHN0cmluZy4gUmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeShwYXRoKX1gLFxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUG9zaXhQYXRoU2VwYXJhdG9yKGNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYXRoU2VwYXJhdG9yKGNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNQb3NpeFBhdGhTZXBhcmF0b3IoY29kZSkgfHwgY29kZSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzV2luZG93c0RldmljZVJvb3QoY29kZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgKGNvZGUgPj0gQ0hBUl9MT1dFUkNBU0VfQSAmJiBjb2RlIDw9IENIQVJfTE9XRVJDQVNFX1opIHx8XG4gICAgKGNvZGUgPj0gQ0hBUl9VUFBFUkNBU0VfQSAmJiBjb2RlIDw9IENIQVJfVVBQRVJDQVNFX1opXG4gICk7XG59XG5cbi8vIFJlc29sdmVzIC4gYW5kIC4uIGVsZW1lbnRzIGluIGEgcGF0aCB3aXRoIGRpcmVjdG9yeSBuYW1lc1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZyhcbiAgcGF0aDogc3RyaW5nLFxuICBhbGxvd0Fib3ZlUm9vdDogYm9vbGVhbixcbiAgc2VwYXJhdG9yOiBzdHJpbmcsXG4gIGlzUGF0aFNlcGFyYXRvcjogKGNvZGU6IG51bWJlcikgPT4gYm9vbGVhbixcbik6IHN0cmluZyB7XG4gIGxldCByZXMgPSBcIlwiO1xuICBsZXQgbGFzdFNlZ21lbnRMZW5ndGggPSAwO1xuICBsZXQgbGFzdFNsYXNoID0gLTE7XG4gIGxldCBkb3RzID0gMDtcbiAgbGV0IGNvZGU6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBhdGgubGVuZ3RoOyBpIDw9IGxlbjsgKytpKSB7XG4gICAgaWYgKGkgPCBsZW4pIGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUhKSkgYnJlYWs7XG4gICAgZWxzZSBjb2RlID0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xuXG4gICAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlISkpIHtcbiAgICAgIGlmIChsYXN0U2xhc2ggPT09IGkgLSAxIHx8IGRvdHMgPT09IDEpIHtcbiAgICAgICAgLy8gTk9PUFxuICAgICAgfSBlbHNlIGlmIChsYXN0U2xhc2ggIT09IGkgLSAxICYmIGRvdHMgPT09IDIpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlcy5sZW5ndGggPCAyIHx8XG4gICAgICAgICAgbGFzdFNlZ21lbnRMZW5ndGggIT09IDIgfHxcbiAgICAgICAgICByZXMuY2hhckNvZGVBdChyZXMubGVuZ3RoIC0gMSkgIT09IENIQVJfRE9UIHx8XG4gICAgICAgICAgcmVzLmNoYXJDb2RlQXQocmVzLmxlbmd0aCAtIDIpICE9PSBDSEFSX0RPVFxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAocmVzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RTbGFzaEluZGV4ID0gcmVzLmxhc3RJbmRleE9mKHNlcGFyYXRvcik7XG4gICAgICAgICAgICBpZiAobGFzdFNsYXNoSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgIHJlcyA9IFwiXCI7XG4gICAgICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlcyA9IHJlcy5zbGljZSgwLCBsYXN0U2xhc2hJbmRleCk7XG4gICAgICAgICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gcmVzLmxlbmd0aCAtIDEgLSByZXMubGFzdEluZGV4T2Yoc2VwYXJhdG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RTbGFzaCA9IGk7XG4gICAgICAgICAgICBkb3RzID0gMDtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzLmxlbmd0aCA9PT0gMiB8fCByZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICByZXMgPSBcIlwiO1xuICAgICAgICAgICAgbGFzdFNlZ21lbnRMZW5ndGggPSAwO1xuICAgICAgICAgICAgbGFzdFNsYXNoID0gaTtcbiAgICAgICAgICAgIGRvdHMgPSAwO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChhbGxvd0Fib3ZlUm9vdCkge1xuICAgICAgICAgIGlmIChyZXMubGVuZ3RoID4gMCkgcmVzICs9IGAke3NlcGFyYXRvcn0uLmA7XG4gICAgICAgICAgZWxzZSByZXMgPSBcIi4uXCI7XG4gICAgICAgICAgbGFzdFNlZ21lbnRMZW5ndGggPSAyO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocmVzLmxlbmd0aCA+IDApIHJlcyArPSBzZXBhcmF0b3IgKyBwYXRoLnNsaWNlKGxhc3RTbGFzaCArIDEsIGkpO1xuICAgICAgICBlbHNlIHJlcyA9IHBhdGguc2xpY2UobGFzdFNsYXNoICsgMSwgaSk7XG4gICAgICAgIGxhc3RTZWdtZW50TGVuZ3RoID0gaSAtIGxhc3RTbGFzaCAtIDE7XG4gICAgICB9XG4gICAgICBsYXN0U2xhc2ggPSBpO1xuICAgICAgZG90cyA9IDA7XG4gICAgfSBlbHNlIGlmIChjb2RlID09PSBDSEFSX0RPVCAmJiBkb3RzICE9PSAtMSkge1xuICAgICAgKytkb3RzO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb3RzID0gLTE7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfZm9ybWF0KFxuICBzZXA6IHN0cmluZyxcbiAgcGF0aE9iamVjdDogRm9ybWF0SW5wdXRQYXRoT2JqZWN0LFxuKTogc3RyaW5nIHtcbiAgY29uc3QgZGlyOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBwYXRoT2JqZWN0LmRpciB8fCBwYXRoT2JqZWN0LnJvb3Q7XG4gIGNvbnN0IGJhc2U6IHN0cmluZyA9IHBhdGhPYmplY3QuYmFzZSB8fFxuICAgIChwYXRoT2JqZWN0Lm5hbWUgfHwgXCJcIikgKyAocGF0aE9iamVjdC5leHQgfHwgXCJcIik7XG4gIGlmICghZGlyKSByZXR1cm4gYmFzZTtcbiAgaWYgKGRpciA9PT0gcGF0aE9iamVjdC5yb290KSByZXR1cm4gZGlyICsgYmFzZTtcbiAgcmV0dXJuIGRpciArIHNlcCArIGJhc2U7XG59XG5cbmNvbnN0IFdISVRFU1BBQ0VfRU5DT0RJTkdTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBcIlxcdTAwMDlcIjogXCIlMDlcIixcbiAgXCJcXHUwMDBBXCI6IFwiJTBBXCIsXG4gIFwiXFx1MDAwQlwiOiBcIiUwQlwiLFxuICBcIlxcdTAwMENcIjogXCIlMENcIixcbiAgXCJcXHUwMDBEXCI6IFwiJTBEXCIsXG4gIFwiXFx1MDAyMFwiOiBcIiUyMFwiLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZVdoaXRlc3BhY2Uoc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyaW5nLnJlcGxhY2VBbGwoL1tcXHNdL2csIChjKSA9PiB7XG4gICAgcmV0dXJuIFdISVRFU1BBQ0VfRU5DT0RJTkdTW2NdID8/IGM7XG4gIH0pO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxpREFBaUQ7QUFDakQsNkRBQTZEO0FBQzdELHFDQUFxQztBQUdyQyxTQUNFLG1CQUFtQixFQUNuQixRQUFRLEVBQ1Isa0JBQWtCLEVBQ2xCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixRQUNYLGtCQUFrQjtBQUV6QixPQUFPLFNBQVMsV0FBVyxJQUFZLEVBQVE7SUFDN0MsSUFBSSxPQUFPLFNBQVMsVUFBVTtRQUM1QixNQUFNLElBQUksVUFDUixDQUFDLGdDQUFnQyxFQUFFLEtBQUssU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUN6RDtJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsT0FBTyxTQUFTLHFCQUFxQixJQUFZLEVBQVc7SUFDMUQsT0FBTyxTQUFTO0FBQ2xCLENBQUM7QUFFRCxPQUFPLFNBQVMsZ0JBQWdCLElBQVksRUFBVztJQUNyRCxPQUFPLHFCQUFxQixTQUFTLFNBQVM7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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/TPW77jtLW1NbcwGdiav4OHTJd6g.js b/tests/__snapshots__/transpile/url/modules/TPW77jtLW1NbcwGdiav4OHTJd6g.js new file mode 100644 index 0000000..f7ecf64 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/TPW77jtLW1NbcwGdiav4OHTJd6g.js @@ -0,0 +1,6 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +import { isWindows } from "../_util/os.ts"; +export const SEP = isWindows ? "\\" : "/"; +export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvc2VwYXJhdG9yLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmltcG9ydCB7IGlzV2luZG93cyB9IGZyb20gXCIuLi9fdXRpbC9vcy50c1wiO1xuXG5leHBvcnQgY29uc3QgU0VQID0gaXNXaW5kb3dzID8gXCJcXFxcXCIgOiBcIi9cIjtcbmV4cG9ydCBjb25zdCBTRVBfUEFUVEVSTiA9IGlzV2luZG93cyA/IC9bXFxcXC9dKy8gOiAvXFwvKy87XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEVBQTBFO0FBQzFFLHFDQUFxQztBQUVyQyxTQUFTLFNBQVMsUUFBUSxpQkFBaUI7QUFFM0MsT0FBTyxNQUFNLE1BQU0sWUFBWSxPQUFPLEdBQUcsQ0FBQztBQUMxQyxPQUFPLE1BQU0sY0FBYyxZQUFZLFdBQVcsS0FBSyxDQUFDIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/VR9N5EtRGYTL6BL2wtaFnqW-AuA.js b/tests/__snapshots__/transpile/url/modules/VR9N5EtRGYTL6BL2wtaFnqW-AuA.js new file mode 100644 index 0000000..ef1880e --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/VR9N5EtRGYTL6BL2wtaFnqW-AuA.js @@ -0,0 +1,72 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { fromFileUrl } from "../../path/mod.ts"; +import { readableStreamFromReader } from "../../streams/conversion.ts"; +const clients = new Map(); +let clientId = 0; +function dispatch(msg) { + for (const client of clients.values()){ + client.send(msg); + } +} +function wsHandler(ws) { + const id = ++clientId; + clients.set(id, ws); + ws.onopen = ()=>{ + dispatch(`Connected: [${id}]`); + }; + ws.onmessage = (e)=>{ + console.log(`msg:${id}`, e.data); + dispatch(`[${id}]: ${e.data}`); + }; + ws.onclose = ()=>{ + clients.delete(id); + dispatch(`Closed: [${id}]`); + }; +} +async function requestHandler(req) { + const pathname = new URL(req.request.url).pathname; + if (req.request.method === "GET" && pathname === "/") { + //Serve with hack + const u = new URL("./index.html", import.meta.url); + if (u.protocol.startsWith("http")) { + // server launched by deno run http(s)://.../server.ts, + fetch(u.href).then(async (resp)=>{ + const body = new Uint8Array(await resp.arrayBuffer()); + req.respondWith(new Response(body, { + status: resp.status, + headers: { + "content-type": "text/html" + } + })); + }); + } else { + // server launched by deno run ./server.ts + const file = await Deno.open(fromFileUrl(u)); + req.respondWith(new Response(readableStreamFromReader(file), { + status: 200, + headers: { + "content-type": "text/html" + } + })); + } + } else if (req.request.method === "GET" && pathname === "/favicon.ico") { + req.respondWith(Response.redirect("https://deno.land/favicon.ico", 302)); + } else if (req.request.method === "GET" && pathname === "/ws") { + const { socket , response } = Deno.upgradeWebSocket(req.request); + wsHandler(socket); + req.respondWith(response); + } +} +const server = Deno.listen({ + port: 8080 +}); +console.log("chat server starting on :8080...."); +for await (const conn of server){ + (async ()=>{ + const httpConn = Deno.serveHttp(conn); + for await (const requestEvent of httpConn){ + requestHandler(requestEvent); + } + })(); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2V4YW1wbGVzL2NoYXQvc2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG5pbXBvcnQgeyBmcm9tRmlsZVVybCB9IGZyb20gXCIuLi8uLi9wYXRoL21vZC50c1wiO1xuaW1wb3J0IHsgcmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyIH0gZnJvbSBcIi4uLy4uL3N0cmVhbXMvY29udmVyc2lvbi50c1wiO1xuXG5jb25zdCBjbGllbnRzID0gbmV3IE1hcDxudW1iZXIsIFdlYlNvY2tldD4oKTtcbmxldCBjbGllbnRJZCA9IDA7XG5mdW5jdGlvbiBkaXNwYXRjaChtc2c6IHN0cmluZyk6IHZvaWQge1xuICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzLnZhbHVlcygpKSB7XG4gICAgY2xpZW50LnNlbmQobXNnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB3c0hhbmRsZXIod3M6IFdlYlNvY2tldCkge1xuICBjb25zdCBpZCA9ICsrY2xpZW50SWQ7XG4gIGNsaWVudHMuc2V0KGlkLCB3cyk7XG4gIHdzLm9ub3BlbiA9ICgpID0+IHtcbiAgICBkaXNwYXRjaChgQ29ubmVjdGVkOiBbJHtpZH1dYCk7XG4gIH07XG4gIHdzLm9ubWVzc2FnZSA9IChlKSA9PiB7XG4gICAgY29uc29sZS5sb2coYG1zZzoke2lkfWAsIGUuZGF0YSk7XG4gICAgZGlzcGF0Y2goYFske2lkfV06ICR7ZS5kYXRhfWApO1xuICB9O1xuICB3cy5vbmNsb3NlID0gKCkgPT4ge1xuICAgIGNsaWVudHMuZGVsZXRlKGlkKTtcbiAgICBkaXNwYXRjaChgQ2xvc2VkOiBbJHtpZH1dYCk7XG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlcXVlc3RIYW5kbGVyKHJlcTogRGVuby5SZXF1ZXN0RXZlbnQpIHtcbiAgY29uc3QgcGF0aG5hbWUgPSBuZXcgVVJMKHJlcS5yZXF1ZXN0LnVybCkucGF0aG5hbWU7XG4gIGlmIChyZXEucmVxdWVzdC5tZXRob2QgPT09IFwiR0VUXCIgJiYgcGF0aG5hbWUgPT09IFwiL1wiKSB7XG4gICAgLy9TZXJ2ZSB3aXRoIGhhY2tcbiAgICBjb25zdCB1ID0gbmV3IFVSTChcIi4vaW5kZXguaHRtbFwiLCBpbXBvcnQubWV0YS51cmwpO1xuICAgIGlmICh1LnByb3RvY29sLnN0YXJ0c1dpdGgoXCJodHRwXCIpKSB7XG4gICAgICAvLyBzZXJ2ZXIgbGF1bmNoZWQgYnkgZGVubyBydW4gaHR0cChzKTovLy4uLi9zZXJ2ZXIudHMsXG4gICAgICBmZXRjaCh1LmhyZWYpLnRoZW4oYXN5bmMgKHJlc3ApID0+IHtcbiAgICAgICAgY29uc3QgYm9keSA9IG5ldyBVaW50OEFycmF5KGF3YWl0IHJlc3AuYXJyYXlCdWZmZXIoKSk7XG4gICAgICAgIHJlcS5yZXNwb25kV2l0aChcbiAgICAgICAgICBuZXcgUmVzcG9uc2UoYm9keSwge1xuICAgICAgICAgICAgc3RhdHVzOiByZXNwLnN0YXR1cyxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgXCJjb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWxcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gc2VydmVyIGxhdW5jaGVkIGJ5IGRlbm8gcnVuIC4vc2VydmVyLnRzXG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKGZyb21GaWxlVXJsKHUpKTtcbiAgICAgIHJlcS5yZXNwb25kV2l0aChcbiAgICAgICAgbmV3IFJlc3BvbnNlKHJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlcihmaWxlKSwge1xuICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIFwiY29udGVudC10eXBlXCI6IFwidGV4dC9odG1sXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIGlmIChcbiAgICByZXEucmVxdWVzdC5tZXRob2QgPT09IFwiR0VUXCIgJiYgcGF0aG5hbWUgPT09IFwiL2Zhdmljb24uaWNvXCJcbiAgKSB7XG4gICAgcmVxLnJlc3BvbmRXaXRoKFJlc3BvbnNlLnJlZGlyZWN0KFwiaHR0cHM6Ly9kZW5vLmxhbmQvZmF2aWNvbi5pY29cIiwgMzAyKSk7XG4gIH0gZWxzZSBpZiAocmVxLnJlcXVlc3QubWV0aG9kID09PSBcIkdFVFwiICYmIHBhdGhuYW1lID09PSBcIi93c1wiKSB7XG4gICAgY29uc3QgeyBzb2NrZXQsIHJlc3BvbnNlIH0gPSBEZW5vLnVwZ3JhZGVXZWJTb2NrZXQocmVxLnJlcXVlc3QpO1xuICAgIHdzSGFuZGxlcihzb2NrZXQpO1xuICAgIHJlcS5yZXNwb25kV2l0aChyZXNwb25zZSk7XG4gIH1cbn1cblxuY29uc3Qgc2VydmVyID0gRGVuby5saXN0ZW4oeyBwb3J0OiA4MDgwIH0pO1xuY29uc29sZS5sb2coXCJjaGF0IHNlcnZlciBzdGFydGluZyBvbiA6ODA4MC4uLi5cIik7XG5cbmZvciBhd2FpdCAoY29uc3QgY29ubiBvZiBzZXJ2ZXIpIHtcbiAgKGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBodHRwQ29ubiA9IERlbm8uc2VydmVIdHRwKGNvbm4pO1xuICAgIGZvciBhd2FpdCAoY29uc3QgcmVxdWVzdEV2ZW50IG9mIGh0dHBDb25uKSB7XG4gICAgICByZXF1ZXN0SGFuZGxlcihyZXF1ZXN0RXZlbnQpO1xuICAgIH1cbiAgfSkoKTtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsU0FBUyxXQUFXLFFBQVEsb0JBQW9CO0FBQ2hELFNBQVMsd0JBQXdCLFFBQVEsOEJBQThCO0FBRXZFLE1BQU0sVUFBVSxJQUFJO0FBQ3BCLElBQUksV0FBVztBQUNmLFNBQVMsU0FBUyxH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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/VUHr_YUyq8otV9YiIbexaSOfQCs.js b/tests/__snapshots__/transpile/url/modules/VUHr_YUyq8otV9YiIbexaSOfQCs.js new file mode 100644 index 0000000..3ee16ef --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/VUHr_YUyq8otV9YiIbexaSOfQCs.js @@ -0,0 +1,18 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +/** + * Ported mostly from https://github.com/browserify/path-browserify/ + * This module is browser compatible. + * @module + */ import { isWindows } from "../_util/os.ts"; +import * as _win32 from "./win32.ts"; +import * as _posix from "./posix.ts"; +const path = isWindows ? _win32 : _posix; +export const win32 = _win32; +export const posix = _posix; +export const { basename , delimiter , dirname , extname , format , fromFileUrl , isAbsolute , join , normalize , parse , relative , resolve , sep , toFileUrl , toNamespacedPath } = path; +export * from "./common.ts"; +export { SEP, SEP_PATTERN } from "./separator.ts"; +export * from "./_interface.ts"; +export * from "./glob.ts"; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvbW9kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgdGhlIEJyb3dzZXJpZnkgYXV0aG9ycy4gTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogUG9ydGVkIG1vc3RseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbiAqIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBpc1dpbmRvd3MgfSBmcm9tIFwiLi4vX3V0aWwvb3MudHNcIjtcbmltcG9ydCAqIGFzIF93aW4zMiBmcm9tIFwiLi93aW4zMi50c1wiO1xuaW1wb3J0ICogYXMgX3Bvc2l4IGZyb20gXCIuL3Bvc2l4LnRzXCI7XG5cbmNvbnN0IHBhdGggPSBpc1dpbmRvd3MgPyBfd2luMzIgOiBfcG9zaXg7XG5cbmV4cG9ydCBjb25zdCB3aW4zMiA9IF93aW4zMjtcbmV4cG9ydCBjb25zdCBwb3NpeCA9IF9wb3NpeDtcbmV4cG9ydCBjb25zdCB7XG4gIGJhc2VuYW1lLFxuICBkZWxpbWl0ZXIsXG4gIGRpcm5hbWUsXG4gIGV4dG5hbWUsXG4gIGZvcm1hdCxcbiAgZnJvbUZpbGVVcmwsXG4gIGlzQWJzb2x1dGUsXG4gIGpvaW4sXG4gIG5vcm1hbGl6ZSxcbiAgcGFyc2UsXG4gIHJlbGF0aXZlLFxuICByZXNvbHZlLFxuICBzZXAsXG4gIHRvRmlsZVVybCxcbiAgdG9OYW1lc3BhY2VkUGF0aCxcbn0gPSBwYXRoO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jb21tb24udHNcIjtcbmV4cG9ydCB7IFNFUCwgU0VQX1BBVFRFUk4gfSBmcm9tIFwiLi9zZXBhcmF0b3IudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL19pbnRlcmZhY2UudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2dsb2IudHNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsaURBQWlEO0FBRWpEOzs7O0NBSUMsR0FFRCxTQUFTLFNBQVMsUUFBUSxpQkFBaUI7QUFDM0MsWUFBWSxZQUFZLGFBQWE7QUFDckMsWUFBWSxZQUFZLGFBQWE7QUFFckMsTUFBTSxPQUFPLFlBQVksU0FBUyxNQUFNO0FBRXhDLE9BQU8sTUFBTSxRQUFRLE9BQU87QUFDNUIsT0FBTyxNQUFNLFFBQVEsT0FBTztBQUM1QixPQUFPLE1BQU0sRUFDWCxTQUFRLEVBQ1IsVUFBUyxFQUNULFFBQU8sRUFDUCxRQUFPLEVBQ1AsT0FBTSxFQUNOLFlBQVcsRUFDWCxXQUFVLEVBQ1YsS0FBSSxFQUNKLFVBQVMsRUFDVCxNQUFLLEVBQ0wsU0FBUSxFQUNSLFFBQU8sRUFDUCxJQUFHLEVBQ0gsVUFBUyxFQUNULGlCQUFnQixFQUNqQixHQUFHLEtBQUs7QUFFVCxjQUFjLGNBQWM7QUFDNUIsU0FBUyxHQUFHLEVBQUUsV0FBVyxRQUFRLGlCQUFpQjtBQUNsRCxjQUFjLGtCQUFrQjtBQUNoQyxjQUFjLFlBQVkifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/WKh_-mE6UYta1pB11lfX_WOvFQ8.js b/tests/__snapshots__/transpile/url/modules/WKh_-mE6UYta1pB11lfX_WOvFQ8.js new file mode 100644 index 0000000..a5d3b86 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/WKh_-mE6UYta1pB11lfX_WOvFQ8.js @@ -0,0 +1,36 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +import { SEP } from "./separator.ts"; +/** Determines the common path from a set of paths, using an optional separator, + * which defaults to the OS default separator. + * + * ```ts + * import { common } from "https://deno.land/std@$STD_VERSION/path/mod.ts"; + * const p = common([ + * "./deno/std/path/mod.ts", + * "./deno/std/fs/mod.ts", + * ]); + * console.log(p); // "./deno/std/" + * ``` + */ export function common(paths, sep = SEP) { + const [first = "", ...remaining] = paths; + if (first === "" || remaining.length === 0) { + return first.substring(0, first.lastIndexOf(sep) + 1); + } + const parts = first.split(sep); + let endOfPrefix = parts.length; + for (const path of remaining){ + const compare = path.split(sep); + for(let i = 0; i < endOfPrefix; i++){ + if (compare[i] !== parts[i]) { + endOfPrefix = i; + } + } + if (endOfPrefix === 0) { + return ""; + } + } + const prefix = parts.slice(0, endOfPrefix).join(sep); + return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvY29tbW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmltcG9ydCB7IFNFUCB9IGZyb20gXCIuL3NlcGFyYXRvci50c1wiO1xuXG4vKiogRGV0ZXJtaW5lcyB0aGUgY29tbW9uIHBhdGggZnJvbSBhIHNldCBvZiBwYXRocywgdXNpbmcgYW4gb3B0aW9uYWwgc2VwYXJhdG9yLFxuICogd2hpY2ggZGVmYXVsdHMgdG8gdGhlIE9TIGRlZmF1bHQgc2VwYXJhdG9yLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgICBpbXBvcnQgeyBjb21tb24gfSBmcm9tIFwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQCRTVERfVkVSU0lPTi9wYXRoL21vZC50c1wiO1xuICogICAgICAgY29uc3QgcCA9IGNvbW1vbihbXG4gKiAgICAgICAgIFwiLi9kZW5vL3N0ZC9wYXRoL21vZC50c1wiLFxuICogICAgICAgICBcIi4vZGVuby9zdGQvZnMvbW9kLnRzXCIsXG4gKiAgICAgICBdKTtcbiAqICAgICAgIGNvbnNvbGUubG9nKHApOyAvLyBcIi4vZGVuby9zdGQvXCJcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tbW9uKHBhdGhzOiBzdHJpbmdbXSwgc2VwID0gU0VQKTogc3RyaW5nIHtcbiAgY29uc3QgW2ZpcnN0ID0gXCJcIiwgLi4ucmVtYWluaW5nXSA9IHBhdGhzO1xuICBpZiAoZmlyc3QgPT09IFwiXCIgfHwgcmVtYWluaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmaXJzdC5zdWJzdHJpbmcoMCwgZmlyc3QubGFzdEluZGV4T2Yoc2VwKSArIDEpO1xuICB9XG4gIGNvbnN0IHBhcnRzID0gZmlyc3Quc3BsaXQoc2VwKTtcblxuICBsZXQgZW5kT2ZQcmVmaXggPSBwYXJ0cy5sZW5ndGg7XG4gIGZvciAoY29uc3QgcGF0aCBvZiByZW1haW5pbmcpIHtcbiAgICBjb25zdCBjb21wYXJlID0gcGF0aC5zcGxpdChzZXApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZW5kT2ZQcmVmaXg7IGkrKykge1xuICAgICAgaWYgKGNvbXBhcmVbaV0gIT09IHBhcnRzW2ldKSB7XG4gICAgICAgIGVuZE9mUHJlZml4ID0gaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW5kT2ZQcmVmaXggPT09IDApIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgfVxuICBjb25zdCBwcmVmaXggPSBwYXJ0cy5zbGljZSgwLCBlbmRPZlByZWZpeCkuam9pbihzZXApO1xuICByZXR1cm4gcHJlZml4LmVuZHNXaXRoKHNlcCkgPyBwcmVmaXggOiBgJHtwcmVmaXh9JHtzZXB9YDtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDLFNBQVMsR0FBRyxRQUFRLGlCQUFpQjtBQUVyQzs7Ozs7Ozs7Ozs7Q0FXQyxHQUNELE9BQU8sU0FBUyxPQUFPLEtBQWUsRUFBRSxNQUFNLEdBQUcsRUFBVTtJQUN6RCxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsR0FBRyxVQUFVLEdBQUc7SUFDbkMsSUFBSSxVQUFVLE1BQU0sVUFBVSxNQUFNLEtBQUssR0FBRztRQUMxQyxPQUFPLE1BQU0sU0FBUyxDQUFDLEdBQUcsTUFBTSxXQUFXLENBQUMsT0FBTztJQUNyRCxDQUFDO0lBQ0QsTUFBTSxRQUFRLE1BQU0sS0FBSyxDQUFDO0lBRTFCLElBQUksY0FBYyxNQUFNLE1BQU07SUFDOUIsS0FBSyxNQUFNLFFBQVEsVUFBVztRQUM1QixNQUFNLFVBQVUsS0FBSyxLQUFLLENBQUM7UUFDM0IsSUFBSyxJQUFJLElBQUksR0FBRyxJQUFJLGFBQWEsSUFBSztZQUNwQyxJQUFJLE9BQU8sQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLEVBQUUsRUFBRTtnQkFDM0IsY0FBYztZQUNoQixDQUFDO1FBQ0g7UUFFQSxJQUFJLGdCQUFnQixHQUFHO1lBQ3JCLE9BQU87UUFDVCxDQUFDO0lBQ0g7SUFDQSxNQUFNLFNBQVMsTUFBTSxLQUFLLENBQUMsR0FBRyxhQUFhLElBQUksQ0FBQztJQUNoRCxPQUFPLE9BQU8sUUFBUSxDQUFDLE9BQU8sU0FBUyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQztBQUMxRCxDQUFDIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/WPpXvFGuxwYeU5ay2bDrdG4fV_g.js b/tests/__snapshots__/transpile/url/modules/WPpXvFGuxwYeU5ay2bDrdG4fV_g.js new file mode 100644 index 0000000..ca8ef1e --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/WPpXvFGuxwYeU5ay2bDrdG4fV_g.js @@ -0,0 +1,852 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +import { CHAR_BACKWARD_SLASH, CHAR_COLON, CHAR_DOT, CHAR_QUESTION_MARK } from "./_constants.ts"; +import { _format, assertPath, encodeWhitespace, isPathSeparator, isWindowsDeviceRoot, normalizeString } from "./_util.ts"; +import { assert } from "../_util/assert.ts"; +export const sep = "\\"; +export const delimiter = ";"; +/** + * Resolves path segments into a `path` + * @param pathSegments to process to path + */ export function resolve(...pathSegments) { + let resolvedDevice = ""; + let resolvedTail = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1; i--){ + let path; + // deno-lint-ignore no-explicit-any + const { Deno } = globalThis; + if (i >= 0) { + path = pathSegments[i]; + } else if (!resolvedDevice) { + if (typeof Deno?.cwd !== "function") { + throw new TypeError("Resolved a drive-letter-less path without a CWD."); + } + path = Deno.cwd(); + } else { + if (typeof Deno?.env?.get !== "function" || typeof Deno?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno.cwd(); + // Verify that a cwd was found and that it actually points + // to our drive. If not, default to the drive's root. + if (path === undefined || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) { + path = `${resolvedDevice}\\`; + } + } + assertPath(path); + const len = path.length; + // Skip empty entries + if (len === 0) continue; + let rootEnd = 0; + let device = ""; + let isAbsolute = false; + const code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + // If we started with a separator, we know we at least have an + // absolute path of some kind (UNC or otherwise) + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + device = `\\\\${firstPart}\\${path.slice(last)}`; + rootEnd = j; + } else if (j !== last) { + // We matched a UNC root with leftovers + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + // Treat separator following drive name as an absolute path + // indicator + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator + rootEnd = 1; + isAbsolute = true; + } + if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) { + continue; + } + if (resolvedDevice.length === 0 && device.length > 0) { + resolvedDevice = device; + } + if (!resolvedAbsolute) { + resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`; + resolvedAbsolute = isAbsolute; + } + if (resolvedAbsolute && resolvedDevice.length > 0) break; + } + // At this point the path should be resolved to a full absolute path, + // but handle relative paths to be safe (might happen when process.cwd() + // fails) + // Normalize the tail path + resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator); + return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || "."; +} +/** + * Normalizes a `path` + * @param path to normalize + */ export function normalize(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = 0; + let device; + let isAbsolute = false; + const code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + // If we started with a separator, we know we at least have an absolute + // path of some kind (UNC or otherwise) + isAbsolute = true; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + const firstPart = path.slice(last, j); + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + // Return the normalized version of the UNC root since there + // is nothing left to process + return `\\\\${firstPart}\\${path.slice(last)}\\`; + } else if (j !== last) { + // We matched a UNC root with leftovers + device = `\\\\${firstPart}\\${path.slice(last, j)}`; + rootEnd = j; + } + } + } + } else { + rootEnd = 1; + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + device = path.slice(0, 2); + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + // Treat separator following drive name as an absolute path + // indicator + isAbsolute = true; + rootEnd = 3; + } + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator, exit early to avoid unnecessary + // work + return "\\"; + } + let tail; + if (rootEnd < len) { + tail = normalizeString(path.slice(rootEnd), !isAbsolute, "\\", isPathSeparator); + } else { + tail = ""; + } + if (tail.length === 0 && !isAbsolute) tail = "."; + if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) { + tail += "\\"; + } + if (device === undefined) { + if (isAbsolute) { + if (tail.length > 0) return `\\${tail}`; + else return "\\"; + } else if (tail.length > 0) { + return tail; + } else { + return ""; + } + } else if (isAbsolute) { + if (tail.length > 0) return `${device}\\${tail}`; + else return `${device}\\`; + } else if (tail.length > 0) { + return device + tail; + } else { + return device; + } +} +/** + * Verifies whether path is absolute + * @param path to verify + */ export function isAbsolute(path) { + assertPath(path); + const len = path.length; + if (len === 0) return false; + const code = path.charCodeAt(0); + if (isPathSeparator(code)) { + return true; + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (len > 2 && path.charCodeAt(1) === CHAR_COLON) { + if (isPathSeparator(path.charCodeAt(2))) return true; + } + } + return false; +} +/** + * Join all given a sequence of `paths`,then normalizes the resulting path. + * @param paths to be joined and normalized + */ export function join(...paths) { + const pathsCount = paths.length; + if (pathsCount === 0) return "."; + let joined; + let firstPart = null; + for(let i = 0; i < pathsCount; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (joined === undefined) joined = firstPart = path; + else joined += `\\${path}`; + } + } + if (joined === undefined) return "."; + // Make sure that the joined path doesn't start with two slashes, because + // normalize() will mistake it for an UNC path then. + // + // This step is skipped when it is very clear that the user actually + // intended to point at an UNC path. This is assumed when the first + // non-empty string arguments starts with exactly two slashes followed by + // at least one more non-slash character. + // + // Note that for normalize() to treat a path as an UNC path it needs to + // have at least 2 components, so we don't filter for that here. + // This means that the user can use join to construct UNC paths from + // a server name and a share name; for example: + // path.join('//server', 'share') -> '\\\\server\\share\\') + let needsReplace = true; + let slashCount = 0; + assert(firstPart != null); + if (isPathSeparator(firstPart.charCodeAt(0))) { + ++slashCount; + const firstLen = firstPart.length; + if (firstLen > 1) { + if (isPathSeparator(firstPart.charCodeAt(1))) { + ++slashCount; + if (firstLen > 2) { + if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount; + else { + // We matched a UNC path in the first part + needsReplace = false; + } + } + } + } + } + if (needsReplace) { + // Find any more consecutive slashes we need to replace + for(; slashCount < joined.length; ++slashCount){ + if (!isPathSeparator(joined.charCodeAt(slashCount))) break; + } + // Replace the slashes if needed + if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`; + } + return normalize(joined); +} +/** + * It will solve the relative path from `from` to `to`, for instance: + * from = 'C:\\orandea\\test\\aaa' + * to = 'C:\\orandea\\impl\\bbb' + * The output of the function should be: '..\\..\\impl\\bbb' + * @param from relative path + * @param to relative path + */ export function relative(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + const fromOrig = resolve(from); + const toOrig = resolve(to); + if (fromOrig === toOrig) return ""; + from = fromOrig.toLowerCase(); + to = toOrig.toLowerCase(); + if (from === to) return ""; + // Trim any leading backslashes + let fromStart = 0; + let fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== CHAR_BACKWARD_SLASH) break; + } + // Trim trailing backslashes (applicable to UNC paths only) + for(; fromEnd - 1 > fromStart; --fromEnd){ + if (from.charCodeAt(fromEnd - 1) !== CHAR_BACKWARD_SLASH) break; + } + const fromLen = fromEnd - fromStart; + // Trim any leading backslashes + let toStart = 0; + let toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== CHAR_BACKWARD_SLASH) break; + } + // Trim trailing backslashes (applicable to UNC paths only) + for(; toEnd - 1 > toStart; --toEnd){ + if (to.charCodeAt(toEnd - 1) !== CHAR_BACKWARD_SLASH) break; + } + const toLen = toEnd - toStart; + // Compare paths to find the longest common path from root + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === CHAR_BACKWARD_SLASH) { + // We get here if `from` is the exact base path for `to`. + // For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz' + return toOrig.slice(toStart + i + 1); + } else if (i === 2) { + // We get here if `from` is the device root. + // For example: from='C:\\'; to='C:\\foo' + return toOrig.slice(toStart + i); + } + } + if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === CHAR_BACKWARD_SLASH) { + // We get here if `to` is the exact base path for `from`. + // For example: from='C:\\foo\\bar'; to='C:\\foo' + lastCommonSep = i; + } else if (i === 2) { + // We get here if `to` is the device root. + // For example: from='C:\\foo\\bar'; to='C:\\' + lastCommonSep = 3; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === CHAR_BACKWARD_SLASH) lastCommonSep = i; + } + // We found a mismatch before the first common path separator was seen, so + // return the original `to`. + if (i !== length && lastCommonSep === -1) { + return toOrig; + } + let out = ""; + if (lastCommonSep === -1) lastCommonSep = 0; + // Generate the relative path based on the path difference between `to` and + // `from` + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === CHAR_BACKWARD_SLASH) { + if (out.length === 0) out += ".."; + else out += "\\.."; + } + } + // Lastly, append the rest of the destination (`to`) path that comes after + // the common path parts + if (out.length > 0) { + return out + toOrig.slice(toStart + lastCommonSep, toEnd); + } else { + toStart += lastCommonSep; + if (toOrig.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) ++toStart; + return toOrig.slice(toStart, toEnd); + } +} +/** + * Resolves path to a namespace path + * @param path to resolve to namespace + */ export function toNamespacedPath(path) { + // Note: this will *probably* throw somewhere. + if (typeof path !== "string") return path; + if (path.length === 0) return ""; + const resolvedPath = resolve(path); + if (resolvedPath.length >= 3) { + if (resolvedPath.charCodeAt(0) === CHAR_BACKWARD_SLASH) { + // Possible UNC root + if (resolvedPath.charCodeAt(1) === CHAR_BACKWARD_SLASH) { + const code = resolvedPath.charCodeAt(2); + if (code !== CHAR_QUESTION_MARK && code !== CHAR_DOT) { + // Matched non-long UNC root, convert the path to a long UNC path + return `\\\\?\\UNC\\${resolvedPath.slice(2)}`; + } + } + } else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) { + // Possible device root + if (resolvedPath.charCodeAt(1) === CHAR_COLON && resolvedPath.charCodeAt(2) === CHAR_BACKWARD_SLASH) { + // Matched device root, convert the path to a long UNC path + return `\\\\?\\${resolvedPath}`; + } + } + } + return path; +} +/** + * Return the directory name of a `path`. + * @param path to determine name for + */ export function dirname(path) { + assertPath(path); + const len = path.length; + if (len === 0) return "."; + let rootEnd = -1; + let end = -1; + let matchedSlash = true; + let offset = 0; + const code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + rootEnd = offset = 1; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + return path; + } + if (j !== last) { + // We matched a UNC root with leftovers + // Offset by 1 to include the separator after the UNC root to + // treat it as a "normal root" on top of a (UNC) root + rootEnd = offset = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + rootEnd = offset = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3; + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator, exit early to avoid + // unnecessary work + return path; + } + for(let i = len - 1; i >= offset; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + if (!matchedSlash) { + end = i; + break; + } + } else { + // We saw the first non-path separator + matchedSlash = false; + } + } + if (end === -1) { + if (rootEnd === -1) return "."; + else end = rootEnd; + } + return path.slice(0, end); +} +/** + * Return the last portion of a `path`. Trailing directory separators are ignored. + * @param path to process + * @param ext of path directory + */ export function basename(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + // Check for a drive letter prefix so as not to mistake the following + // path separator as an extra separator at the end of the path that can be + // disregarded + if (path.length >= 2) { + const drive = path.charCodeAt(0); + if (isWindowsDeviceRoot(drive)) { + if (path.charCodeAt(1) === CHAR_COLON) start = 2; + } + } + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + // We saw the first non-path separator, remember this index in case + // we need it if the extension ends up not matching + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + // Try to match the explicit extension + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + // We matched the extension, so mark this as the end of our path + // component + end = i; + } + } else { + // Extension does not match, so our result is the entire path + // component + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= start; --i){ + if (isPathSeparator(path.charCodeAt(i))) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // path component + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +/** + * Return the extension of the `path` with leading period. + * @param path with extension + * @returns extension (ex. for `file.ts` returns `.ts`) + */ export function extname(path) { + assertPath(path); + let start = 0; + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + // Check for a drive letter prefix so as not to mistake the following + // path separator as an extra separator at the end of the path that can be + // disregarded + if (path.length >= 2 && path.charCodeAt(1) === CHAR_COLON && isWindowsDeviceRoot(path.charCodeAt(0))) { + start = startPart = 2; + } + for(let i = path.length - 1; i >= start; --i){ + const code = path.charCodeAt(i); + if (isPathSeparator(code)) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +/** + * Generate a path from `FormatInputPathObject` object. + * @param pathObject with path + */ export function format(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("\\", pathObject); +} +/** + * Return a `ParsedPath` object of the `path`. + * @param path to process + */ export function parse(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + const len = path.length; + if (len === 0) return ret; + let rootEnd = 0; + let code = path.charCodeAt(0); + // Try to match a root + if (len > 1) { + if (isPathSeparator(code)) { + // Possible UNC root + rootEnd = 1; + if (isPathSeparator(path.charCodeAt(1))) { + // Matched double path separator at beginning + let j = 2; + let last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more path separators + for(; j < len; ++j){ + if (!isPathSeparator(path.charCodeAt(j))) break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for(; j < len; ++j){ + if (isPathSeparator(path.charCodeAt(j))) break; + } + if (j === len) { + // We matched a UNC root only + rootEnd = j; + } else if (j !== last) { + // We matched a UNC root with leftovers + rootEnd = j + 1; + } + } + } + } + } else if (isWindowsDeviceRoot(code)) { + // Possible device root + if (path.charCodeAt(1) === CHAR_COLON) { + rootEnd = 2; + if (len > 2) { + if (isPathSeparator(path.charCodeAt(2))) { + if (len === 3) { + // `path` contains just a drive root, exit early to avoid + // unnecessary work + ret.root = ret.dir = path; + return ret; + } + rootEnd = 3; + } + } else { + // `path` contains just a drive root, exit early to avoid + // unnecessary work + ret.root = ret.dir = path; + return ret; + } + } + } + } else if (isPathSeparator(code)) { + // `path` contains just a path separator, exit early to avoid + // unnecessary work + ret.root = ret.dir = path; + return ret; + } + if (rootEnd > 0) ret.root = path.slice(0, rootEnd); + let startDot = -1; + let startPart = rootEnd; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + // Get non-dir info + for(; i >= rootEnd; --i){ + code = path.charCodeAt(i); + if (isPathSeparator(code)) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + ret.base = ret.name = path.slice(startPart, end); + } + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + ret.ext = path.slice(startDot, end); + } + // If the directory is the root, use the entire root as the `dir` including + // the trailing slash if any (`C:\abc` -> `C:\`). Otherwise, strip out the + // trailing slash (`C:\abc\def` -> `C:\abc`). + if (startPart > 0 && startPart !== rootEnd) { + ret.dir = path.slice(0, startPart - 1); + } else ret.dir = ret.root; + return ret; +} +/** + * Converts a file URL to a path string. + * + * ```ts + * import { fromFileUrl } from "./win32.ts"; + * fromFileUrl("file:///home/foo"); // "\\home\\foo" + * fromFileUrl("file:///C:/Users/foo"); // "C:\\Users\\foo" + * fromFileUrl("file://localhost/home/foo"); // "\\\\localhost\\home\\foo" + * ``` + * @param url of a file URL + */ export function fromFileUrl(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\"); + if (url.hostname != "") { + // Note: The `URL` implementation guarantees that the drive letter and + // hostname are mutually exclusive. Otherwise it would not have been valid + // to append the hostname and path like this. + path = `\\\\${url.hostname}${path}`; + } + return path; +} +/** + * Converts a path string to a file URL. + * + * ```ts + * import { toFileUrl } from "./win32.ts"; + * toFileUrl("\\home\\foo"); // new URL("file:///home/foo") + * toFileUrl("C:\\Users\\foo"); // new URL("file:///C:/Users/foo") + * toFileUrl("\\\\127.0.0.1\\home\\foo"); // new URL("file://127.0.0.1/home/foo") + * ``` + * @param path to convert to file URL + */ export function toFileUrl(path) { + if (!isAbsolute(path)) { + throw new TypeError("Must be an absolute path."); + } + const [, hostname, pathname] = path.match(/^(?:[/\\]{2}([^/\\]+)(?=[/\\](?:[^/\\]|$)))?(.*)/); + const url = new URL("file:///"); + url.pathname = encodeWhitespace(pathname.replace(/%/g, "%25")); + if (hostname != null && hostname != "localhost") { + url.hostname = hostname; + if (!url.hostname) { + throw new TypeError("Invalid hostname."); + } + } + return url; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvd2luMzIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QsIFBhcnNlZFBhdGggfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQge1xuICBDSEFSX0JBQ0tXQVJEX1NMQVNILFxuICBDSEFSX0NPTE9OLFxuICBDSEFSX0RPVCxcbiAgQ0hBUl9RVUVTVElPTl9NQVJLLFxufSBmcm9tIFwiLi9fY29uc3RhbnRzLnRzXCI7XG5cbmltcG9ydCB7XG4gIF9mb3JtYXQsXG4gIGFzc2VydFBhdGgsXG4gIGVuY29kZVdoaXRlc3BhY2UsXG4gIGlzUGF0aFNlcGFyYXRvcixcbiAgaXNXaW5kb3dzRGV2aWNlUm9vdCxcbiAgbm9ybWFsaXplU3RyaW5nLFxufSBmcm9tIFwiLi9fdXRpbC50c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL191dGlsL2Fzc2VydC50c1wiO1xuXG5leHBvcnQgY29uc3Qgc2VwID0gXCJcXFxcXCI7XG5leHBvcnQgY29uc3QgZGVsaW1pdGVyID0gXCI7XCI7XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCBzZWdtZW50cyBpbnRvIGEgYHBhdGhgXG4gKiBAcGFyYW0gcGF0aFNlZ21lbnRzIHRvIHByb2Nlc3MgdG8gcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZSguLi5wYXRoU2VnbWVudHM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgbGV0IHJlc29sdmVkRGV2aWNlID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkVGFpbCA9IFwiXCI7XG4gIGxldCByZXNvbHZlZEFic29sdXRlID0gZmFsc2U7XG5cbiAgZm9yIChsZXQgaSA9IHBhdGhTZWdtZW50cy5sZW5ndGggLSAxOyBpID49IC0xOyBpLS0pIHtcbiAgICBsZXQgcGF0aDogc3RyaW5nO1xuICAgIC8vIGRlbm8tbGludC1pZ25vcmUgbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgeyBEZW5vIH0gPSBnbG9iYWxUaGlzIGFzIGFueTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICBwYXRoID0gcGF0aFNlZ21lbnRzW2ldO1xuICAgIH0gZWxzZSBpZiAoIXJlc29sdmVkRGV2aWNlKSB7XG4gICAgICBpZiAodHlwZW9mIERlbm8/LmN3ZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIGRyaXZlLWxldHRlci1sZXNzIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgRGVubz8uZW52Py5nZXQgIT09IFwiZnVuY3Rpb25cIiB8fCB0eXBlb2YgRGVubz8uY3dkICE9PSBcImZ1bmN0aW9uXCJcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUmVzb2x2ZWQgYSByZWxhdGl2ZSBwYXRoIHdpdGhvdXQgYSBDV0QuXCIpO1xuICAgICAgfVxuICAgICAgcGF0aCA9IERlbm8uY3dkKCk7XG5cbiAgICAgIC8vIFZlcmlmeSB0aGF0IGEgY3dkIHdhcyBmb3VuZCBhbmQgdGhhdCBpdCBhY3R1YWxseSBwb2ludHNcbiAgICAgIC8vIHRvIG91ciBkcml2ZS4gSWYgbm90LCBkZWZhdWx0IHRvIHRoZSBkcml2ZSdzIHJvb3QuXG4gICAgICBpZiAoXG4gICAgICAgIHBhdGggPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICBwYXRoLnNsaWNlKDAsIDMpLnRvTG93ZXJDYXNlKCkgIT09IGAke3Jlc29sdmVkRGV2aWNlLnRvTG93ZXJDYXNlKCl9XFxcXGBcbiAgICAgICkge1xuICAgICAgICBwYXRoID0gYCR7cmVzb2x2ZWREZXZpY2V9XFxcXGA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICAgIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBlbnRyaWVzXG4gICAgaWYgKGxlbiA9PT0gMCkgY29udGludWU7XG5cbiAgICBsZXQgcm9vdEVuZCA9IDA7XG4gICAgbGV0IGRldmljZSA9IFwiXCI7XG4gICAgbGV0IGlzQWJzb2x1dGUgPSBmYWxzZTtcbiAgICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gICAgLy8gVHJ5IHRvIG1hdGNoIGEgcm9vdFxuICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAgIC8vIFBvc3NpYmxlIFVOQyByb290XG5cbiAgICAgICAgLy8gSWYgd2Ugc3RhcnRlZCB3aXRoIGEgc2VwYXJhdG9yLCB3ZSBrbm93IHdlIGF0IGxlYXN0IGhhdmUgYW5cbiAgICAgICAgLy8gYWJzb2x1dGUgcGF0aCBvZiBzb21lIGtpbmQgKFVOQyBvciBvdGhlcndpc2UpXG4gICAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuXG4gICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDEpKSkge1xuICAgICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICAgIGxldCBqID0gMjtcbiAgICAgICAgICBsZXQgbGFzdCA9IGo7XG4gICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdFBhcnQgPSBwYXRoLnNsaWNlKGxhc3QsIGopO1xuICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIHBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChqID09PSBsZW4pIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgb25seVxuICAgICAgICAgICAgICAgIGRldmljZSA9IGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCl9YDtcbiAgICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IHdpdGggbGVmdG92ZXJzXG5cbiAgICAgICAgICAgICAgICBkZXZpY2UgPSBgXFxcXFxcXFwke2ZpcnN0UGFydH1cXFxcJHtwYXRoLnNsaWNlKGxhc3QsIGopfWA7XG4gICAgICAgICAgICAgICAgcm9vdEVuZCA9IGo7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcm9vdEVuZCA9IDE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChjb2RlKSkge1xuICAgICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgICBkZXZpY2UgPSBwYXRoLnNsaWNlKDAsIDIpO1xuICAgICAgICAgIHJvb3RFbmQgPSAyO1xuICAgICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdCgyKSkpIHtcbiAgICAgICAgICAgICAgLy8gVHJlYXQgc2VwYXJhdG9yIGZvbGxvd2luZyBkcml2ZSBuYW1lIGFzIGFuIGFic29sdXRlIHBhdGhcbiAgICAgICAgICAgICAgLy8gaW5kaWNhdG9yXG4gICAgICAgICAgICAgIGlzQWJzb2x1dGUgPSB0cnVlO1xuICAgICAgICAgICAgICByb290RW5kID0gMztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBwYXRoIHNlcGFyYXRvclxuICAgICAgcm9vdEVuZCA9IDE7XG4gICAgICBpc0Fic29sdXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBkZXZpY2UubGVuZ3RoID4gMCAmJlxuICAgICAgcmVzb2x2ZWREZXZpY2UubGVuZ3RoID4gMCAmJlxuICAgICAgZGV2aWNlLnRvTG93ZXJDYXNlKCkgIT09IHJlc29sdmVkRGV2aWNlLnRvTG93ZXJDYXNlKClcbiAgICApIHtcbiAgICAgIC8vIFRoaXMgcGF0aCBwb2ludHMgdG8gYW5vdGhlciBkZXZpY2Ugc28gaXQgaXMgbm90IGFwcGxpY2FibGVcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChyZXNvbHZlZERldmljZS5sZW5ndGggPT09IDAgJiYgZGV2aWNlLmxlbmd0aCA+IDApIHtcbiAgICAgIHJlc29sdmVkRGV2aWNlID0gZGV2aWNlO1xuICAgIH1cbiAgICBpZiAoIXJlc29sdmVkQWJzb2x1dGUpIHtcbiAgICAgIHJlc29sdmVkVGFpbCA9IGAke3BhdGguc2xpY2Uocm9vdEVuZCl9XFxcXCR7cmVzb2x2ZWRUYWlsfWA7XG4gICAgICByZXNvbHZlZEFic29sdXRlID0gaXNBYnNvbHV0ZTtcbiAgICB9XG5cbiAgICBpZiAocmVzb2x2ZWRBYnNvbHV0ZSAmJiByZXNvbHZlZERldmljZS5sZW5ndGggPiAwKSBicmVhaztcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLFxuICAvLyBidXQgaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKClcbiAgLy8gZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSB0YWlsIHBhdGhcbiAgcmVzb2x2ZWRUYWlsID0gbm9ybWFsaXplU3RyaW5nKFxuICAgIHJlc29sdmVkVGFpbCxcbiAgICAhcmVzb2x2ZWRBYnNvbHV0ZSxcbiAgICBcIlxcXFxcIixcbiAgICBpc1BhdGhTZXBhcmF0b3IsXG4gICk7XG5cbiAgcmV0dXJuIHJlc29sdmVkRGV2aWNlICsgKHJlc29sdmVkQWJzb2x1dGUgPyBcIlxcXFxcIiA6IFwiXCIpICsgcmVzb2x2ZWRUYWlsIHx8IFwiLlwiO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBgcGF0aGBcbiAqIEBwYXJhbSBwYXRoIHRvIG5vcm1hbGl6ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCByb290RW5kID0gMDtcbiAgbGV0IGRldmljZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBsZXQgaXNBYnNvbHV0ZSA9IGZhbHNlO1xuICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gIC8vIFRyeSB0byBtYXRjaCBhIHJvb3RcbiAgaWYgKGxlbiA+IDEpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICAvLyBJZiB3ZSBzdGFydGVkIHdpdGggYSBzZXBhcmF0b3IsIHdlIGtub3cgd2UgYXQgbGVhc3QgaGF2ZSBhbiBhYnNvbHV0ZVxuICAgICAgLy8gcGF0aCBvZiBzb21lIGtpbmQgKFVOQyBvciBvdGhlcndpc2UpXG4gICAgICBpc0Fic29sdXRlID0gdHJ1ZTtcblxuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICBsZXQgaiA9IDI7XG4gICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgIGNvbnN0IGZpcnN0UGFydCA9IHBhdGguc2xpY2UobGFzdCwgaik7XG4gICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgaWYgKCFpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgICBsYXN0ID0gajtcbiAgICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaiA9PT0gbGVuKSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCBvbmx5XG4gICAgICAgICAgICAgIC8vIFJldHVybiB0aGUgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBVTkMgcm9vdCBzaW5jZSB0aGVyZVxuICAgICAgICAgICAgICAvLyBpcyBub3RoaW5nIGxlZnQgdG8gcHJvY2Vzc1xuXG4gICAgICAgICAgICAgIHJldHVybiBgXFxcXFxcXFwke2ZpcnN0UGFydH1cXFxcJHtwYXRoLnNsaWNlKGxhc3QpfVxcXFxgO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCB3aXRoIGxlZnRvdmVyc1xuXG4gICAgICAgICAgICAgIGRldmljZSA9IGBcXFxcXFxcXCR7Zmlyc3RQYXJ0fVxcXFwke3BhdGguc2xpY2UobGFzdCwgail9YDtcbiAgICAgICAgICAgICAgcm9vdEVuZCA9IGo7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByb290RW5kID0gMTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QoY29kZSkpIHtcbiAgICAgIC8vIFBvc3NpYmxlIGRldmljZSByb290XG5cbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHtcbiAgICAgICAgZGV2aWNlID0gcGF0aC5zbGljZSgwLCAyKTtcbiAgICAgICAgcm9vdEVuZCA9IDI7XG4gICAgICAgIGlmIChsZW4gPiAyKSB7XG4gICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSB7XG4gICAgICAgICAgICAvLyBUcmVhdCBzZXBhcmF0b3IgZm9sbG93aW5nIGRyaXZlIG5hbWUgYXMgYW4gYWJzb2x1dGUgcGF0aFxuICAgICAgICAgICAgLy8gaW5kaWNhdG9yXG4gICAgICAgICAgICBpc0Fic29sdXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIHJvb3RFbmQgPSAzO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIHBhdGggc2VwYXJhdG9yLCBleGl0IGVhcmx5IHRvIGF2b2lkIHVubmVjZXNzYXJ5XG4gICAgLy8gd29ya1xuICAgIHJldHVybiBcIlxcXFxcIjtcbiAgfVxuXG4gIGxldCB0YWlsOiBzdHJpbmc7XG4gIGlmIChyb290RW5kIDwgbGVuKSB7XG4gICAgdGFpbCA9IG5vcm1hbGl6ZVN0cmluZyhcbiAgICAgIHBhdGguc2xpY2Uocm9vdEVuZCksXG4gICAgICAhaXNBYnNvbHV0ZSxcbiAgICAgIFwiXFxcXFwiLFxuICAgICAgaXNQYXRoU2VwYXJhdG9yLFxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgdGFpbCA9IFwiXCI7XG4gIH1cbiAgaWYgKHRhaWwubGVuZ3RoID09PSAwICYmICFpc0Fic29sdXRlKSB0YWlsID0gXCIuXCI7XG4gIGlmICh0YWlsLmxlbmd0aCA+IDAgJiYgaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChsZW4gLSAxKSkpIHtcbiAgICB0YWlsICs9IFwiXFxcXFwiO1xuICB9XG4gIGlmIChkZXZpY2UgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChpc0Fic29sdXRlKSB7XG4gICAgICBpZiAodGFpbC5sZW5ndGggPiAwKSByZXR1cm4gYFxcXFwke3RhaWx9YDtcbiAgICAgIGVsc2UgcmV0dXJuIFwiXFxcXFwiO1xuICAgIH0gZWxzZSBpZiAodGFpbC5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdGFpbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICBpZiAodGFpbC5sZW5ndGggPiAwKSByZXR1cm4gYCR7ZGV2aWNlfVxcXFwke3RhaWx9YDtcbiAgICBlbHNlIHJldHVybiBgJHtkZXZpY2V9XFxcXGA7XG4gIH0gZWxzZSBpZiAodGFpbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGRldmljZSArIHRhaWw7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRldmljZTtcbiAgfVxufVxuXG4vKipcbiAqIFZlcmlmaWVzIHdoZXRoZXIgcGF0aCBpcyBhYnNvbHV0ZVxuICogQHBhcmFtIHBhdGggdG8gdmVyaWZ5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Fic29sdXRlKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICBjb25zdCBsZW4gPSBwYXRoLmxlbmd0aDtcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoMCk7XG4gIGlmIChpc1BhdGhTZXBhcmF0b3IoY29kZSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgLy8gUG9zc2libGUgZGV2aWNlIHJvb3RcblxuICAgIGlmIChsZW4gPiAyICYmIHBhdGguY2hhckNvZGVBdCgxKSA9PT0gQ0hBUl9DT0xPTikge1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMikpKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEpvaW4gYWxsIGdpdmVuIGEgc2VxdWVuY2Ugb2YgYHBhdGhzYCx0aGVuIG5vcm1hbGl6ZXMgdGhlIHJlc3VsdGluZyBwYXRoLlxuICogQHBhcmFtIHBhdGhzIHRvIGJlIGpvaW5lZCBhbmQgbm9ybWFsaXplZFxuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbiguLi5wYXRoczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCBwYXRoc0NvdW50ID0gcGF0aHMubGVuZ3RoO1xuICBpZiAocGF0aHNDb3VudCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuXG4gIGxldCBqb2luZWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbGV0IGZpcnN0UGFydDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0aHNDb3VudDsgKytpKSB7XG4gICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgIGFzc2VydFBhdGgocGF0aCk7XG4gICAgaWYgKHBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGpvaW5lZCA9PT0gdW5kZWZpbmVkKSBqb2luZWQgPSBmaXJzdFBhcnQgPSBwYXRoO1xuICAgICAgZWxzZSBqb2luZWQgKz0gYFxcXFwke3BhdGh9YDtcbiAgICB9XG4gIH1cblxuICBpZiAoam9pbmVkID09PSB1bmRlZmluZWQpIHJldHVybiBcIi5cIjtcblxuICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgam9pbmVkIHBhdGggZG9lc24ndCBzdGFydCB3aXRoIHR3byBzbGFzaGVzLCBiZWNhdXNlXG4gIC8vIG5vcm1hbGl6ZSgpIHdpbGwgbWlzdGFrZSBpdCBmb3IgYW4gVU5DIHBhdGggdGhlbi5cbiAgLy9cbiAgLy8gVGhpcyBzdGVwIGlzIHNraXBwZWQgd2hlbiBpdCBpcyB2ZXJ5IGNsZWFyIHRoYXQgdGhlIHVzZXIgYWN0dWFsbHlcbiAgLy8gaW50ZW5kZWQgdG8gcG9pbnQgYXQgYW4gVU5DIHBhdGguIFRoaXMgaXMgYXNzdW1lZCB3aGVuIHRoZSBmaXJzdFxuICAvLyBub24tZW1wdHkgc3RyaW5nIGFyZ3VtZW50cyBzdGFydHMgd2l0aCBleGFjdGx5IHR3byBzbGFzaGVzIGZvbGxvd2VkIGJ5XG4gIC8vIGF0IGxlYXN0IG9uZSBtb3JlIG5vbi1zbGFzaCBjaGFyYWN0ZXIuXG4gIC8vXG4gIC8vIE5vdGUgdGhhdCBmb3Igbm9ybWFsaXplKCkgdG8gdHJlYXQgYSBwYXRoIGFzIGFuIFVOQyBwYXRoIGl0IG5lZWRzIHRvXG4gIC8vIGhhdmUgYXQgbGVhc3QgMiBjb21wb25lbnRzLCBzbyB3ZSBkb24ndCBmaWx0ZXIgZm9yIHRoYXQgaGVyZS5cbiAgLy8gVGhpcyBtZWFucyB0aGF0IHRoZSB1c2VyIGNhbiB1c2Ugam9pbiB0byBjb25zdHJ1Y3QgVU5DIHBhdGhzIGZyb21cbiAgLy8gYSBzZXJ2ZXIgbmFtZSBhbmQgYSBzaGFyZSBuYW1lOyBmb3IgZXhhbXBsZTpcbiAgLy8gICBwYXRoLmpvaW4oJy8vc2VydmVyJywgJ3NoYXJlJykgLT4gJ1xcXFxcXFxcc2VydmVyXFxcXHNoYXJlXFxcXCcpXG4gIGxldCBuZWVkc1JlcGxhY2UgPSB0cnVlO1xuICBsZXQgc2xhc2hDb3VudCA9IDA7XG4gIGFzc2VydChmaXJzdFBhcnQgIT0gbnVsbCk7XG4gIGlmIChpc1BhdGhTZXBhcmF0b3IoZmlyc3RQYXJ0LmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgKytzbGFzaENvdW50O1xuICAgIGNvbnN0IGZpcnN0TGVuID0gZmlyc3RQYXJ0Lmxlbmd0aDtcbiAgICBpZiAoZmlyc3RMZW4gPiAxKSB7XG4gICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGZpcnN0UGFydC5jaGFyQ29kZUF0KDEpKSkge1xuICAgICAgICArK3NsYXNoQ291bnQ7XG4gICAgICAgIGlmIChmaXJzdExlbiA+IDIpIHtcbiAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGZpcnN0UGFydC5jaGFyQ29kZUF0KDIpKSkgKytzbGFzaENvdW50O1xuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyBwYXRoIGluIHRoZSBmaXJzdCBwYXJ0XG4gICAgICAgICAgICBuZWVkc1JlcGxhY2UgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKG5lZWRzUmVwbGFjZSkge1xuICAgIC8vIEZpbmQgYW55IG1vcmUgY29uc2VjdXRpdmUgc2xhc2hlcyB3ZSBuZWVkIHRvIHJlcGxhY2VcbiAgICBmb3IgKDsgc2xhc2hDb3VudCA8IGpvaW5lZC5sZW5ndGg7ICsrc2xhc2hDb3VudCkge1xuICAgICAgaWYgKCFpc1BhdGhTZXBhcmF0b3Ioam9pbmVkLmNoYXJDb2RlQXQoc2xhc2hDb3VudCkpKSBicmVhaztcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBzbGFzaGVzIGlmIG5lZWRlZFxuICAgIGlmIChzbGFzaENvdW50ID49IDIpIGpvaW5lZCA9IGBcXFxcJHtqb2luZWQuc2xpY2Uoc2xhc2hDb3VudCl9YDtcbiAgfVxuXG4gIHJldHVybiBub3JtYWxpemUoam9pbmVkKTtcbn1cblxuLyoqXG4gKiBJdCB3aWxsIHNvbHZlIHRoZSByZWxhdGl2ZSBwYXRoIGZyb20gYGZyb21gIHRvIGB0b2AsIGZvciBpbnN0YW5jZTpcbiAqICBmcm9tID0gJ0M6XFxcXG9yYW5kZWFcXFxcdGVzdFxcXFxhYWEnXG4gKiAgdG8gPSAnQzpcXFxcb3JhbmRlYVxcXFxpbXBsXFxcXGJiYidcbiAqIFRoZSBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uIHNob3VsZCBiZTogJy4uXFxcXC4uXFxcXGltcGxcXFxcYmJiJ1xuICogQHBhcmFtIGZyb20gcmVsYXRpdmUgcGF0aFxuICogQHBhcmFtIHRvIHJlbGF0aXZlIHBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbGF0aXZlKGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgoZnJvbSk7XG4gIGFzc2VydFBhdGgodG8pO1xuXG4gIGlmIChmcm9tID09PSB0bykgcmV0dXJuIFwiXCI7XG5cbiAgY29uc3QgZnJvbU9yaWcgPSByZXNvbHZlKGZyb20pO1xuICBjb25zdCB0b09yaWcgPSByZXNvbHZlKHRvKTtcblxuICBpZiAoZnJvbU9yaWcgPT09IHRvT3JpZykgcmV0dXJuIFwiXCI7XG5cbiAgZnJvbSA9IGZyb21PcmlnLnRvTG93ZXJDYXNlKCk7XG4gIHRvID0gdG9PcmlnLnRvTG93ZXJDYXNlKCk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICAvLyBUcmltIGFueSBsZWFkaW5nIGJhY2tzbGFzaGVzXG4gIGxldCBmcm9tU3RhcnQgPSAwO1xuICBsZXQgZnJvbUVuZCA9IGZyb20ubGVuZ3RoO1xuICBmb3IgKDsgZnJvbVN0YXJ0IDwgZnJvbUVuZDsgKytmcm9tU3RhcnQpIHtcbiAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIC8vIFRyaW0gdHJhaWxpbmcgYmFja3NsYXNoZXMgKGFwcGxpY2FibGUgdG8gVU5DIHBhdGhzIG9ubHkpXG4gIGZvciAoOyBmcm9tRW5kIC0gMSA+IGZyb21TdGFydDsgLS1mcm9tRW5kKSB7XG4gICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tRW5kIC0gMSkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IGZyb21MZW4gPSBmcm9tRW5kIC0gZnJvbVN0YXJ0O1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IHRvU3RhcnQgPSAwO1xuICBsZXQgdG9FbmQgPSB0by5sZW5ndGg7XG4gIGZvciAoOyB0b1N0YXJ0IDwgdG9FbmQ7ICsrdG9TdGFydCkge1xuICAgIGlmICh0by5jaGFyQ29kZUF0KHRvU3RhcnQpICE9PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSBicmVhaztcbiAgfVxuICAvLyBUcmltIHRyYWlsaW5nIGJhY2tzbGFzaGVzIChhcHBsaWNhYmxlIHRvIFVOQyBwYXRocyBvbmx5KVxuICBmb3IgKDsgdG9FbmQgLSAxID4gdG9TdGFydDsgLS10b0VuZCkge1xuICAgIGlmICh0by5jaGFyQ29kZUF0KHRvRW5kIC0gMSkgIT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IHRvTGVuID0gdG9FbmQgLSB0b1N0YXJ0O1xuXG4gIC8vIENvbXBhcmUgcGF0aHMgdG8gZmluZCB0aGUgbG9uZ2VzdCBjb21tb24gcGF0aCBmcm9tIHJvb3RcbiAgY29uc3QgbGVuZ3RoID0gZnJvbUxlbiA8IHRvTGVuID8gZnJvbUxlbiA6IHRvTGVuO1xuICBsZXQgbGFzdENvbW1vblNlcCA9IC0xO1xuICBsZXQgaSA9IDA7XG4gIGZvciAoOyBpIDw9IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGkgPT09IGxlbmd0aCkge1xuICAgICAgaWYgKHRvTGVuID4gbGVuZ3RoKSB7XG4gICAgICAgIGlmICh0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgICAgIC8vIFdlIGdldCBoZXJlIGlmIGBmcm9tYCBpcyB0aGUgZXhhY3QgYmFzZSBwYXRoIGZvciBgdG9gLlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPSdDOlxcXFxmb29cXFxcYmFyJzsgdG89J0M6XFxcXGZvb1xcXFxiYXJcXFxcYmF6J1xuICAgICAgICAgIHJldHVybiB0b09yaWcuc2xpY2UodG9TdGFydCArIGkgKyAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChpID09PSAyKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYGZyb21gIGlzIHRoZSBkZXZpY2Ugcm9vdC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nQzpcXFxcJzsgdG89J0M6XFxcXGZvbydcbiAgICAgICAgICByZXR1cm4gdG9PcmlnLnNsaWNlKHRvU3RhcnQgKyBpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZyb21MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgICAgIC8vIFdlIGdldCBoZXJlIGlmIGB0b2AgaXMgdGhlIGV4YWN0IGJhc2UgcGF0aCBmb3IgYGZyb21gLlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPSdDOlxcXFxmb29cXFxcYmFyJzsgdG89J0M6XFxcXGZvbydcbiAgICAgICAgICBsYXN0Q29tbW9uU2VwID0gaTtcbiAgICAgICAgfSBlbHNlIGlmIChpID09PSAyKSB7XG4gICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgaWYgYHRvYCBpcyB0aGUgZGV2aWNlIHJvb3QuXG4gICAgICAgICAgLy8gRm9yIGV4YW1wbGU6IGZyb209J0M6XFxcXGZvb1xcXFxiYXInOyB0bz0nQzpcXFxcJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSAzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY29uc3QgZnJvbUNvZGUgPSBmcm9tLmNoYXJDb2RlQXQoZnJvbVN0YXJ0ICsgaSk7XG4gICAgY29uc3QgdG9Db2RlID0gdG8uY2hhckNvZGVBdCh0b1N0YXJ0ICsgaSk7XG4gICAgaWYgKGZyb21Db2RlICE9PSB0b0NvZGUpIGJyZWFrO1xuICAgIGVsc2UgaWYgKGZyb21Db2RlID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSBsYXN0Q29tbW9uU2VwID0gaTtcbiAgfVxuXG4gIC8vIFdlIGZvdW5kIGEgbWlzbWF0Y2ggYmVmb3JlIHRoZSBmaXJzdCBjb21tb24gcGF0aCBzZXBhcmF0b3Igd2FzIHNlZW4sIHNvXG4gIC8vIHJldHVybiB0aGUgb3JpZ2luYWwgYHRvYC5cbiAgaWYgKGkgIT09IGxlbmd0aCAmJiBsYXN0Q29tbW9uU2VwID09PSAtMSkge1xuICAgIHJldHVybiB0b09yaWc7XG4gIH1cblxuICBsZXQgb3V0ID0gXCJcIjtcbiAgaWYgKGxhc3RDb21tb25TZXAgPT09IC0xKSBsYXN0Q29tbW9uU2VwID0gMDtcbiAgLy8gR2VuZXJhdGUgdGhlIHJlbGF0aXZlIHBhdGggYmFzZWQgb24gdGhlIHBhdGggZGlmZmVyZW5jZSBiZXR3ZWVuIGB0b2AgYW5kXG4gIC8vIGBmcm9tYFxuICBmb3IgKGkgPSBmcm9tU3RhcnQgKyBsYXN0Q29tbW9uU2VwICsgMTsgaSA8PSBmcm9tRW5kOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gZnJvbUVuZCB8fCBmcm9tLmNoYXJDb2RlQXQoaSkgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpIHtcbiAgICAgIGlmIChvdXQubGVuZ3RoID09PSAwKSBvdXQgKz0gXCIuLlwiO1xuICAgICAgZWxzZSBvdXQgKz0gXCJcXFxcLi5cIjtcbiAgICB9XG4gIH1cblxuICAvLyBMYXN0bHksIGFwcGVuZCB0aGUgcmVzdCBvZiB0aGUgZGVzdGluYXRpb24gKGB0b2ApIHBhdGggdGhhdCBjb21lcyBhZnRlclxuICAvLyB0aGUgY29tbW9uIHBhdGggcGFydHNcbiAgaWYgKG91dC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIG91dCArIHRvT3JpZy5zbGljZSh0b1N0YXJ0ICsgbGFzdENvbW1vblNlcCwgdG9FbmQpO1xuICB9IGVsc2Uge1xuICAgIHRvU3RhcnQgKz0gbGFzdENvbW1vblNlcDtcbiAgICBpZiAodG9PcmlnLmNoYXJDb2RlQXQodG9TdGFydCkgPT09IENIQVJfQkFDS1dBUkRfU0xBU0gpICsrdG9TdGFydDtcbiAgICByZXR1cm4gdG9PcmlnLnNsaWNlKHRvU3RhcnQsIHRvRW5kKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHBhdGggdG8gYSBuYW1lc3BhY2UgcGF0aFxuICogQHBhcmFtIHBhdGggdG8gcmVzb2x2ZSB0byBuYW1lc3BhY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvTmFtZXNwYWNlZFBhdGgocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gTm90ZTogdGhpcyB3aWxsICpwcm9iYWJseSogdGhyb3cgc29tZXdoZXJlLlxuICBpZiAodHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHJldHVybiBwYXRoO1xuICBpZiAocGF0aC5sZW5ndGggPT09IDApIHJldHVybiBcIlwiO1xuXG4gIGNvbnN0IHJlc29sdmVkUGF0aCA9IHJlc29sdmUocGF0aCk7XG5cbiAgaWYgKHJlc29sdmVkUGF0aC5sZW5ndGggPj0gMykge1xuICAgIGlmIChyZXNvbHZlZFBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9CQUNLV0FSRF9TTEFTSCkge1xuICAgICAgLy8gUG9zc2libGUgVU5DIHJvb3RcblxuICAgICAgaWYgKHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIKSB7XG4gICAgICAgIGNvbnN0IGNvZGUgPSByZXNvbHZlZFBhdGguY2hhckNvZGVBdCgyKTtcbiAgICAgICAgaWYgKGNvZGUgIT09IENIQVJfUVVFU1RJT05fTUFSSyAmJiBjb2RlICE9PSBDSEFSX0RPVCkge1xuICAgICAgICAgIC8vIE1hdGNoZWQgbm9uLWxvbmcgVU5DIHJvb3QsIGNvbnZlcnQgdGhlIHBhdGggdG8gYSBsb25nIFVOQyBwYXRoXG4gICAgICAgICAgcmV0dXJuIGBcXFxcXFxcXD9cXFxcVU5DXFxcXCR7cmVzb2x2ZWRQYXRoLnNsaWNlKDIpfWA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzV2luZG93c0RldmljZVJvb3QocmVzb2x2ZWRQYXRoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICBpZiAoXG4gICAgICAgIHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OICYmXG4gICAgICAgIHJlc29sdmVkUGF0aC5jaGFyQ29kZUF0KDIpID09PSBDSEFSX0JBQ0tXQVJEX1NMQVNIXG4gICAgICApIHtcbiAgICAgICAgLy8gTWF0Y2hlZCBkZXZpY2Ugcm9vdCwgY29udmVydCB0aGUgcGF0aCB0byBhIGxvbmcgVU5DIHBhdGhcbiAgICAgICAgcmV0dXJuIGBcXFxcXFxcXD9cXFxcJHtyZXNvbHZlZFBhdGh9YDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGRpcmVjdG9yeSBuYW1lIG9mIGEgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gZGV0ZXJtaW5lIG5hbWUgZm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGNvbnN0IGxlbiA9IHBhdGgubGVuZ3RoO1xuICBpZiAobGVuID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCByb290RW5kID0gLTE7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gIC8vIFRyeSB0byBtYXRjaCBhIHJvb3RcbiAgaWYgKGxlbiA+IDEpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICByb290RW5kID0gb2Zmc2V0ID0gMTtcblxuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoMSkpKSB7XG4gICAgICAgIC8vIE1hdGNoZWQgZG91YmxlIHBhdGggc2VwYXJhdG9yIGF0IGJlZ2lubmluZ1xuICAgICAgICBsZXQgaiA9IDI7XG4gICAgICAgIGxldCBsYXN0ID0gajtcbiAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGopKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgIC8vIE1hdGNoZWQhXG4gICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIHBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgIGlmICghaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IGxlbiAmJiBqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgICAgbGFzdCA9IGo7XG4gICAgICAgICAgICAvLyBNYXRjaCAxIG9yIG1vcmUgbm9uLXBhdGggc2VwYXJhdG9yc1xuICAgICAgICAgICAgZm9yICg7IGogPCBsZW47ICsraikge1xuICAgICAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGogPT09IGxlbikge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgb25seVxuICAgICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqICE9PSBsYXN0KSB7XG4gICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgYSBVTkMgcm9vdCB3aXRoIGxlZnRvdmVyc1xuXG4gICAgICAgICAgICAgIC8vIE9mZnNldCBieSAxIHRvIGluY2x1ZGUgdGhlIHNlcGFyYXRvciBhZnRlciB0aGUgVU5DIHJvb3QgdG9cbiAgICAgICAgICAgICAgLy8gdHJlYXQgaXQgYXMgYSBcIm5vcm1hbCByb290XCIgb24gdG9wIG9mIGEgKFVOQykgcm9vdFxuICAgICAgICAgICAgICByb290RW5kID0gb2Zmc2V0ID0gaiArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OKSB7XG4gICAgICAgIHJvb3RFbmQgPSBvZmZzZXQgPSAyO1xuICAgICAgICBpZiAobGVuID4gMikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDIpKSkgcm9vdEVuZCA9IG9mZnNldCA9IDM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBwYXRoIHNlcGFyYXRvciwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgIC8vIHVubmVjZXNzYXJ5IHdvcmtcbiAgICByZXR1cm4gcGF0aDtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSBsZW4gLSAxOyBpID49IG9mZnNldDsgLS1pKSB7XG4gICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaSkpKSB7XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3JcbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbmQgPT09IC0xKSB7XG4gICAgaWYgKHJvb3RFbmQgPT09IC0xKSByZXR1cm4gXCIuXCI7XG4gICAgZWxzZSBlbmQgPSByb290RW5kO1xuICB9XG4gIHJldHVybiBwYXRoLnNsaWNlKDAsIGVuZCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBsYXN0IHBvcnRpb24gb2YgYSBgcGF0aGAuIFRyYWlsaW5nIGRpcmVjdG9yeSBzZXBhcmF0b3JzIGFyZSBpZ25vcmVkLlxuICogQHBhcmFtIHBhdGggdG8gcHJvY2Vzc1xuICogQHBhcmFtIGV4dCBvZiBwYXRoIGRpcmVjdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmFzZW5hbWUocGF0aDogc3RyaW5nLCBleHQgPSBcIlwiKTogc3RyaW5nIHtcbiAgaWYgKGV4dCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBleHQgIT09IFwic3RyaW5nXCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImV4dFwiIGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgfVxuXG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGk6IG51bWJlcjtcblxuICAvLyBDaGVjayBmb3IgYSBkcml2ZSBsZXR0ZXIgcHJlZml4IHNvIGFzIG5vdCB0byBtaXN0YWtlIHRoZSBmb2xsb3dpbmdcbiAgLy8gcGF0aCBzZXBhcmF0b3IgYXMgYW4gZXh0cmEgc2VwYXJhdG9yIGF0IHRoZSBlbmQgb2YgdGhlIHBhdGggdGhhdCBjYW4gYmVcbiAgLy8gZGlzcmVnYXJkZWRcbiAgaWYgKHBhdGgubGVuZ3RoID49IDIpIHtcbiAgICBjb25zdCBkcml2ZSA9IHBhdGguY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoaXNXaW5kb3dzRGV2aWNlUm9vdChkcml2ZSkpIHtcbiAgICAgIGlmIChwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04pIHN0YXJ0ID0gMjtcbiAgICB9XG4gIH1cblxuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgZXh0Lmxlbmd0aCA+IDAgJiYgZXh0Lmxlbmd0aCA8PSBwYXRoLmxlbmd0aCkge1xuICAgIGlmIChleHQubGVuZ3RoID09PSBwYXRoLmxlbmd0aCAmJiBleHQgPT09IHBhdGgpIHJldHVybiBcIlwiO1xuICAgIGxldCBleHRJZHggPSBleHQubGVuZ3RoIC0gMTtcbiAgICBsZXQgZmlyc3ROb25TbGFzaEVuZCA9IC0xO1xuICAgIGZvciAoaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgICBjb25zdCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgICAvLyBzZXBhcmF0b3JzIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZywgc3RvcCBub3dcbiAgICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgICBzdGFydCA9IGkgKyAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmlyc3ROb25TbGFzaEVuZCA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgcmVtZW1iZXIgdGhpcyBpbmRleCBpbiBjYXNlXG4gICAgICAgICAgLy8gd2UgbmVlZCBpdCBpZiB0aGUgZXh0ZW5zaW9uIGVuZHMgdXAgbm90IG1hdGNoaW5nXG4gICAgICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICAgICAgZmlyc3ROb25TbGFzaEVuZCA9IGkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChleHRJZHggPj0gMCkge1xuICAgICAgICAgIC8vIFRyeSB0byBtYXRjaCB0aGUgZXhwbGljaXQgZXh0ZW5zaW9uXG4gICAgICAgICAgaWYgKGNvZGUgPT09IGV4dC5jaGFyQ29kZUF0KGV4dElkeCkpIHtcbiAgICAgICAgICAgIGlmICgtLWV4dElkeCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCB0aGUgZXh0ZW5zaW9uLCBzbyBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXIgcGF0aFxuICAgICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgICAgZW5kID0gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gRXh0ZW5zaW9uIGRvZXMgbm90IG1hdGNoLCBzbyBvdXIgcmVzdWx0IGlzIHRoZSBlbnRpcmUgcGF0aFxuICAgICAgICAgICAgLy8gY29tcG9uZW50XG4gICAgICAgICAgICBleHRJZHggPSAtMTtcbiAgICAgICAgICAgIGVuZCA9IGZpcnN0Tm9uU2xhc2hFbmQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ID09PSBlbmQpIGVuZCA9IGZpcnN0Tm9uU2xhc2hFbmQ7XG4gICAgZWxzZSBpZiAoZW5kID09PSAtMSkgZW5kID0gcGF0aC5sZW5ndGg7XG4gICAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnQsIGVuZCk7XG4gIH0gZWxzZSB7XG4gICAgZm9yIChpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IHN0YXJ0OyAtLWkpIHtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KGkpKSkge1xuICAgICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgICAvLyBzZXBhcmF0b3JzIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZywgc3RvcCBub3dcbiAgICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgICBzdGFydCA9IGkgKyAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3IsIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91clxuICAgICAgICAvLyBwYXRoIGNvbXBvbmVudFxuICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgZW5kID0gaSArIDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVuZCA9PT0gLTEpIHJldHVybiBcIlwiO1xuICAgIHJldHVybiBwYXRoLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBleHRlbnNpb24gb2YgdGhlIGBwYXRoYCB3aXRoIGxlYWRpbmcgcGVyaW9kLlxuICogQHBhcmFtIHBhdGggd2l0aCBleHRlbnNpb25cbiAqIEByZXR1cm5zIGV4dGVuc2lvbiAoZXguIGZvciBgZmlsZS50c2AgcmV0dXJucyBgLnRzYClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dG5hbWUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IHN0YXJ0RG90ID0gLTE7XG4gIGxldCBzdGFydFBhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICAvLyBUcmFjayB0aGUgc3RhdGUgb2YgY2hhcmFjdGVycyAoaWYgYW55KSB3ZSBzZWUgYmVmb3JlIG91ciBmaXJzdCBkb3QgYW5kXG4gIC8vIGFmdGVyIGFueSBwYXRoIHNlcGFyYXRvciB3ZSBmaW5kXG4gIGxldCBwcmVEb3RTdGF0ZSA9IDA7XG5cbiAgLy8gQ2hlY2sgZm9yIGEgZHJpdmUgbGV0dGVyIHByZWZpeCBzbyBhcyBub3QgdG8gbWlzdGFrZSB0aGUgZm9sbG93aW5nXG4gIC8vIHBhdGggc2VwYXJhdG9yIGFzIGFuIGV4dHJhIHNlcGFyYXRvciBhdCB0aGUgZW5kIG9mIHRoZSBwYXRoIHRoYXQgY2FuIGJlXG4gIC8vIGRpc3JlZ2FyZGVkXG5cbiAgaWYgKFxuICAgIHBhdGgubGVuZ3RoID49IDIgJiZcbiAgICBwYXRoLmNoYXJDb2RlQXQoMSkgPT09IENIQVJfQ09MT04gJiZcbiAgICBpc1dpbmRvd3NEZXZpY2VSb290KHBhdGguY2hhckNvZGVBdCgwKSlcbiAgKSB7XG4gICAgc3RhcnQgPSBzdGFydFBhcnQgPSAyO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICByZXR1cm4gXCJcIjtcbiAgfVxuICByZXR1cm4gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHBhdGggZnJvbSBgRm9ybWF0SW5wdXRQYXRoT2JqZWN0YCBvYmplY3QuXG4gKiBAcGFyYW0gcGF0aE9iamVjdCB3aXRoIHBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdChwYXRoT2JqZWN0OiBGb3JtYXRJbnB1dFBhdGhPYmplY3QpOiBzdHJpbmcge1xuICBpZiAocGF0aE9iamVjdCA9PT0gbnVsbCB8fCB0eXBlb2YgcGF0aE9iamVjdCAhPT0gXCJvYmplY3RcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICBgVGhlIFwicGF0aE9iamVjdFwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBPYmplY3QuIFJlY2VpdmVkIHR5cGUgJHt0eXBlb2YgcGF0aE9iamVjdH1gLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIF9mb3JtYXQoXCJcXFxcXCIsIHBhdGhPYmplY3QpO1xufVxuXG4vKipcbiAqIFJldHVybiBhIGBQYXJzZWRQYXRoYCBvYmplY3Qgb2YgdGhlIGBwYXRoYC5cbiAqIEBwYXJhbSBwYXRoIHRvIHByb2Nlc3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlKHBhdGg6IHN0cmluZyk6IFBhcnNlZFBhdGgge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gIGNvbnN0IHJldDogUGFyc2VkUGF0aCA9IHsgcm9vdDogXCJcIiwgZGlyOiBcIlwiLCBiYXNlOiBcIlwiLCBleHQ6IFwiXCIsIG5hbWU6IFwiXCIgfTtcblxuICBjb25zdCBsZW4gPSBwYXRoLmxlbmd0aDtcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIHJldDtcblxuICBsZXQgcm9vdEVuZCA9IDA7XG4gIGxldCBjb2RlID0gcGF0aC5jaGFyQ29kZUF0KDApO1xuXG4gIC8vIFRyeSB0byBtYXRjaCBhIHJvb3RcbiAgaWYgKGxlbiA+IDEpIHtcbiAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBVTkMgcm9vdFxuXG4gICAgICByb290RW5kID0gMTtcbiAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDEpKSkge1xuICAgICAgICAvLyBNYXRjaGVkIGRvdWJsZSBwYXRoIHNlcGFyYXRvciBhdCBiZWdpbm5pbmdcbiAgICAgICAgbGV0IGogPSAyO1xuICAgICAgICBsZXQgbGFzdCA9IGo7XG4gICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBub24tcGF0aCBzZXBhcmF0b3JzXG4gICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICBpZiAoaXNQYXRoU2VwYXJhdG9yKHBhdGguY2hhckNvZGVBdChqKSkpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqIDwgbGVuICYmIGogIT09IGxhc3QpIHtcbiAgICAgICAgICAvLyBNYXRjaGVkIVxuICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgIC8vIE1hdGNoIDEgb3IgbW9yZSBwYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICBmb3IgKDsgaiA8IGxlbjsgKytqKSB7XG4gICAgICAgICAgICBpZiAoIWlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGogPCBsZW4gJiYgaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgLy8gTWF0Y2hlZCFcbiAgICAgICAgICAgIGxhc3QgPSBqO1xuICAgICAgICAgICAgLy8gTWF0Y2ggMSBvciBtb3JlIG5vbi1wYXRoIHNlcGFyYXRvcnNcbiAgICAgICAgICAgIGZvciAoOyBqIDwgbGVuOyArK2opIHtcbiAgICAgICAgICAgICAgaWYgKGlzUGF0aFNlcGFyYXRvcihwYXRoLmNoYXJDb2RlQXQoaikpKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqID09PSBsZW4pIHtcbiAgICAgICAgICAgICAgLy8gV2UgbWF0Y2hlZCBhIFVOQyByb290IG9ubHlcblxuICAgICAgICAgICAgICByb290RW5kID0gajtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaiAhPT0gbGFzdCkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIGEgVU5DIHJvb3Qgd2l0aCBsZWZ0b3ZlcnNcblxuICAgICAgICAgICAgICByb290RW5kID0gaiArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1dpbmRvd3NEZXZpY2VSb290KGNvZGUpKSB7XG4gICAgICAvLyBQb3NzaWJsZSBkZXZpY2Ugcm9vdFxuXG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KDEpID09PSBDSEFSX0NPTE9OKSB7XG4gICAgICAgIHJvb3RFbmQgPSAyO1xuICAgICAgICBpZiAobGVuID4gMikge1xuICAgICAgICAgIGlmIChpc1BhdGhTZXBhcmF0b3IocGF0aC5jaGFyQ29kZUF0KDIpKSkge1xuICAgICAgICAgICAgaWYgKGxlbiA9PT0gMykge1xuICAgICAgICAgICAgICAvLyBgcGF0aGAgY29udGFpbnMganVzdCBhIGRyaXZlIHJvb3QsIGV4aXQgZWFybHkgdG8gYXZvaWRcbiAgICAgICAgICAgICAgLy8gdW5uZWNlc3Nhcnkgd29ya1xuICAgICAgICAgICAgICByZXQucm9vdCA9IHJldC5kaXIgPSBwYXRoO1xuICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcm9vdEVuZCA9IDM7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGBwYXRoYCBjb250YWlucyBqdXN0IGEgZHJpdmUgcm9vdCwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgICAgICAgIC8vIHVubmVjZXNzYXJ5IHdvcmtcbiAgICAgICAgICByZXQucm9vdCA9IHJldC5kaXIgPSBwYXRoO1xuICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNQYXRoU2VwYXJhdG9yKGNvZGUpKSB7XG4gICAgLy8gYHBhdGhgIGNvbnRhaW5zIGp1c3QgYSBwYXRoIHNlcGFyYXRvciwgZXhpdCBlYXJseSB0byBhdm9pZFxuICAgIC8vIHVubmVjZXNzYXJ5IHdvcmtcbiAgICByZXQucm9vdCA9IHJldC5kaXIgPSBwYXRoO1xuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICBpZiAocm9vdEVuZCA+IDApIHJldC5yb290ID0gcGF0aC5zbGljZSgwLCByb290RW5kKTtcblxuICBsZXQgc3RhcnREb3QgPSAtMTtcbiAgbGV0IHN0YXJ0UGFydCA9IHJvb3RFbmQ7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGxldCBpID0gcGF0aC5sZW5ndGggLSAxO1xuXG4gIC8vIFRyYWNrIHRoZSBzdGF0ZSBvZiBjaGFyYWN0ZXJzIChpZiBhbnkpIHdlIHNlZSBiZWZvcmUgb3VyIGZpcnN0IGRvdCBhbmRcbiAgLy8gYWZ0ZXIgYW55IHBhdGggc2VwYXJhdG9yIHdlIGZpbmRcbiAgbGV0IHByZURvdFN0YXRlID0gMDtcblxuICAvLyBHZXQgbm9uLWRpciBpbmZvXG4gIGZvciAoOyBpID49IHJvb3RFbmQ7IC0taSkge1xuICAgIGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGlzUGF0aFNlcGFyYXRvcihjb2RlKSkge1xuICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgc3RhcnRQYXJ0ID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25cbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgZW5kID0gaSArIDE7XG4gICAgfVxuICAgIGlmIChjb2RlID09PSBDSEFSX0RPVCkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBvdXIgZmlyc3QgZG90LCBtYXJrIGl0IGFzIHRoZSBzdGFydCBvZiBvdXIgZXh0ZW5zaW9uXG4gICAgICBpZiAoc3RhcnREb3QgPT09IC0xKSBzdGFydERvdCA9IGk7XG4gICAgICBlbHNlIGlmIChwcmVEb3RTdGF0ZSAhPT0gMSkgcHJlRG90U3RhdGUgPSAxO1xuICAgIH0gZWxzZSBpZiAoc3RhcnREb3QgIT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgYSBub24tZG90IGFuZCBub24tcGF0aCBzZXBhcmF0b3IgYmVmb3JlIG91ciBkb3QsIHNvIHdlIHNob3VsZFxuICAgICAgLy8gaGF2ZSBhIGdvb2QgY2hhbmNlIGF0IGhhdmluZyBhIG5vbi1lbXB0eSBleHRlbnNpb25cbiAgICAgIHByZURvdFN0YXRlID0gLTE7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIHN0YXJ0RG90ID09PSAtMSB8fFxuICAgIGVuZCA9PT0gLTEgfHxcbiAgICAvLyBXZSBzYXcgYSBub24tZG90IGNoYXJhY3RlciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGRvdFxuICAgIHByZURvdFN0YXRlID09PSAwIHx8XG4gICAgLy8gVGhlIChyaWdodC1tb3N0KSB0cmltbWVkIHBhdGggY29tcG9uZW50IGlzIGV4YWN0bHkgJy4uJ1xuICAgIChwcmVEb3RTdGF0ZSA9PT0gMSAmJiBzdGFydERvdCA9PT0gZW5kIC0gMSAmJiBzdGFydERvdCA9PT0gc3RhcnRQYXJ0ICsgMSlcbiAgKSB7XG4gICAgaWYgKGVuZCAhPT0gLTEpIHtcbiAgICAgIHJldC5iYXNlID0gcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKHN0YXJ0UGFydCwgZW5kKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKHN0YXJ0UGFydCwgc3RhcnREb3QpO1xuICAgIHJldC5iYXNlID0gcGF0aC5zbGljZShzdGFydFBhcnQsIGVuZCk7XG4gICAgcmV0LmV4dCA9IHBhdGguc2xpY2Uoc3RhcnREb3QsIGVuZCk7XG4gIH1cblxuICAvLyBJZiB0aGUgZGlyZWN0b3J5IGlzIHRoZSByb290LCB1c2UgdGhlIGVudGlyZSByb290IGFzIHRoZSBgZGlyYCBpbmNsdWRpbmdcbiAgLy8gdGhlIHRyYWlsaW5nIHNsYXNoIGlmIGFueSAoYEM6XFxhYmNgIC0+IGBDOlxcYCkuIE90aGVyd2lzZSwgc3RyaXAgb3V0IHRoZVxuICAvLyB0cmFpbGluZyBzbGFzaCAoYEM6XFxhYmNcXGRlZmAgLT4gYEM6XFxhYmNgKS5cbiAgaWYgKHN0YXJ0UGFydCA+IDAgJiYgc3RhcnRQYXJ0ICE9PSByb290RW5kKSB7XG4gICAgcmV0LmRpciA9IHBhdGguc2xpY2UoMCwgc3RhcnRQYXJ0IC0gMSk7XG4gIH0gZWxzZSByZXQuZGlyID0gcmV0LnJvb3Q7XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIGZpbGUgVVJMIHRvIGEgcGF0aCBzdHJpbmcuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgZnJvbUZpbGVVcmwgfSBmcm9tIFwiLi93aW4zMi50c1wiO1xuICogICAgICBmcm9tRmlsZVVybChcImZpbGU6Ly8vaG9tZS9mb29cIik7IC8vIFwiXFxcXGhvbWVcXFxcZm9vXCJcbiAqICAgICAgZnJvbUZpbGVVcmwoXCJmaWxlOi8vL0M6L1VzZXJzL2Zvb1wiKTsgLy8gXCJDOlxcXFxVc2Vyc1xcXFxmb29cIlxuICogICAgICBmcm9tRmlsZVVybChcImZpbGU6Ly9sb2NhbGhvc3QvaG9tZS9mb29cIik7IC8vIFwiXFxcXFxcXFxsb2NhbGhvc3RcXFxcaG9tZVxcXFxmb29cIlxuICogYGBgXG4gKiBAcGFyYW0gdXJsIG9mIGEgZmlsZSBVUkxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyb21GaWxlVXJsKHVybDogc3RyaW5nIHwgVVJMKTogc3RyaW5nIHtcbiAgdXJsID0gdXJsIGluc3RhbmNlb2YgVVJMID8gdXJsIDogbmV3IFVSTCh1cmwpO1xuICBpZiAodXJsLnByb3RvY29sICE9IFwiZmlsZTpcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNdXN0IGJlIGEgZmlsZSBVUkwuXCIpO1xuICB9XG4gIGxldCBwYXRoID0gZGVjb2RlVVJJQ29tcG9uZW50KFxuICAgIHVybC5wYXRobmFtZS5yZXBsYWNlKC9cXC8vZywgXCJcXFxcXCIpLnJlcGxhY2UoLyUoPyFbMC05QS1GYS1mXXsyfSkvZywgXCIlMjVcIiksXG4gICkucmVwbGFjZSgvXlxcXFwqKFtBLVphLXpdOikoXFxcXHwkKS8sIFwiJDFcXFxcXCIpO1xuICBpZiAodXJsLmhvc3RuYW1lICE9IFwiXCIpIHtcbiAgICAvLyBOb3RlOiBUaGUgYFVSTGAgaW1wbGVtZW50YXRpb24gZ3VhcmFudGVlcyB0aGF0IHRoZSBkcml2ZSBsZXR0ZXIgYW5kXG4gICAgLy8gaG9zdG5hbWUgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS4gT3RoZXJ3aXNlIGl0IHdvdWxkIG5vdCBoYXZlIGJlZW4gdmFsaWRcbiAgICAvLyB0byBhcHBlbmQgdGhlIGhvc3RuYW1lIGFuZCBwYXRoIGxpa2UgdGhpcy5cbiAgICBwYXRoID0gYFxcXFxcXFxcJHt1cmwuaG9zdG5hbWV9JHtwYXRofWA7XG4gIH1cbiAgcmV0dXJuIHBhdGg7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBwYXRoIHN0cmluZyB0byBhIGZpbGUgVVJMLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IHRvRmlsZVVybCB9IGZyb20gXCIuL3dpbjMyLnRzXCI7XG4gKiAgICAgIHRvRmlsZVVybChcIlxcXFxob21lXFxcXGZvb1wiKTsgLy8gbmV3IFVSTChcImZpbGU6Ly8vaG9tZS9mb29cIilcbiAqICAgICAgdG9GaWxlVXJsKFwiQzpcXFxcVXNlcnNcXFxcZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9DOi9Vc2Vycy9mb29cIilcbiAqICAgICAgdG9GaWxlVXJsKFwiXFxcXFxcXFwxMjcuMC4wLjFcXFxcaG9tZVxcXFxmb29cIik7IC8vIG5ldyBVUkwoXCJmaWxlOi8vMTI3LjAuMC4xL2hvbWUvZm9vXCIpXG4gKiBgYGBcbiAqIEBwYXJhbSBwYXRoIHRvIGNvbnZlcnQgdG8gZmlsZSBVUkxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRmlsZVVybChwYXRoOiBzdHJpbmcpOiBVUkwge1xuICBpZiAoIWlzQWJzb2x1dGUocGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTXVzdCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlwiKTtcbiAgfVxuICBjb25zdCBbLCBob3N0bmFtZSwgcGF0aG5hbWVdID0gcGF0aC5tYXRjaChcbiAgICAvXig/OlsvXFxcXF17Mn0oW14vXFxcXF0rKSg/PVsvXFxcXF0oPzpbXi9cXFxcXXwkKSkpPyguKikvLFxuICApITtcbiAgY29uc3QgdXJsID0gbmV3IFVSTChcImZpbGU6Ly8vXCIpO1xuICB1cmwucGF0aG5hbWUgPSBlbmNvZGVXaGl0ZXNwYWNlKHBhdGhuYW1lLnJlcGxhY2UoLyUvZywgXCIlMjVcIikpO1xuICBpZiAoaG9zdG5hbWUgIT0gbnVsbCAmJiBob3N0bmFtZSAhPSBcImxvY2FsaG9zdFwiKSB7XG4gICAgdXJsLmhvc3RuYW1lID0gaG9zdG5hbWU7XG4gICAgaWYgKCF1cmwuaG9zdG5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGhvc3RuYW1lLlwiKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVybDtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsaURBQWlEO0FBQ2pELDZEQUE2RDtBQUM3RCxxQ0FBcUM7QUFHckMsU0FDRSxtQkFBbUIsRUFDbkIsVUFBVSxFQUNWLFFBQVEsRUFDUixrQkFBa0IsUUFDYixrQkFBa0I7QUFFekIsU0FDRSxPQUFPLEVBQ1AsVUFBVSxFQUNWLGdCQUFnQixFQUNoQixl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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/WStdDhyHbKYy_C9CJ39RDks1VaY.js b/tests/__snapshots__/transpile/url/modules/WStdDhyHbKYy_C9CJ39RDks1VaY.js new file mode 100644 index 0000000..bd10af7 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/WStdDhyHbKYy_C9CJ39RDks1VaY.js @@ -0,0 +1,228 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** + * Provides helper functions to manipulate `Uint8Array` byte slices that are not + * included on the `Uint8Array` prototype. + * + * @module + */ /** Returns the index of the first occurrence of the needle array in the source + * array, or -1 if it is not present. + * + * A start index can be specified as the third argument that begins the search + * at that given index. The start index defaults to the start of the array. + * + * The complexity of this function is O(source.lenth * needle.length). + * + * ```ts + * import { indexOfNeedle } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const needle = new Uint8Array([1, 2]); + * console.log(indexOfNeedle(source, needle)); // 1 + * console.log(indexOfNeedle(source, needle, 2)); // 3 + * ``` + */ export function indexOfNeedle(source, needle, start = 0) { + if (start >= source.length) { + return -1; + } + if (start < 0) { + start = Math.max(0, source.length + start); + } + const s = needle[0]; + for(let i = start; i < source.length; i++){ + if (source[i] !== s) continue; + const pin = i; + let matched = 1; + let j = i; + while(matched < needle.length){ + j++; + if (source[j] !== needle[j - pin]) { + break; + } + matched++; + } + if (matched === needle.length) { + return pin; + } + } + return -1; +} +/** Returns the index of the last occurrence of the needle array in the source + * array, or -1 if it is not present. + * + * A start index can be specified as the third argument that begins the search + * at that given index. The start index defaults to the end of the array. + * + * The complexity of this function is O(source.lenth * needle.length). + * + * ```ts + * import { lastIndexOfNeedle } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const needle = new Uint8Array([1, 2]); + * console.log(lastIndexOfNeedle(source, needle)); // 5 + * console.log(lastIndexOfNeedle(source, needle, 4)); // 3 + * ``` + */ export function lastIndexOfNeedle(source, needle, start = source.length - 1) { + if (start < 0) { + return -1; + } + if (start >= source.length) { + start = source.length - 1; + } + const e = needle[needle.length - 1]; + for(let i = start; i >= 0; i--){ + if (source[i] !== e) continue; + const pin = i; + let matched = 1; + let j = i; + while(matched < needle.length){ + j--; + if (source[j] !== needle[needle.length - 1 - (pin - j)]) { + break; + } + matched++; + } + if (matched === needle.length) { + return pin - needle.length + 1; + } + } + return -1; +} +/** Returns true if the prefix array appears at the start of the source array, + * false otherwise. + * + * The complexity of this function is O(prefix.length). + * + * ```ts + * import { startsWith } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const prefix = new Uint8Array([0, 1, 2]); + * console.log(startsWith(source, prefix)); // true + * ``` + */ export function startsWith(source, prefix) { + for(let i = 0, max = prefix.length; i < max; i++){ + if (source[i] !== prefix[i]) return false; + } + return true; +} +/** Returns true if the suffix array appears at the end of the source array, + * false otherwise. + * + * The complexity of this function is O(suffix.length). + * + * ```ts + * import { endsWith } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const suffix = new Uint8Array([1, 2, 3]); + * console.log(endsWith(source, suffix)); // true + * ``` + */ export function endsWith(source, suffix) { + for(let srci = source.length - 1, sfxi = suffix.length - 1; sfxi >= 0; srci--, sfxi--){ + if (source[srci] !== suffix[sfxi]) return false; + } + return true; +} +/** Returns a new Uint8Array composed of `count` repetitions of the `source` + * array. + * + * If `count` is negative, a `RangeError` is thrown. + * + * ```ts + * import { repeat } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2]); + * console.log(repeat(source, 3)); // [0, 1, 2, 0, 1, 2, 0, 1, 2] + * console.log(repeat(source, 0)); // [] + * console.log(repeat(source, -1)); // RangeError + * ``` + */ export function repeat(source, count) { + if (count === 0) { + return new Uint8Array(); + } + if (count < 0) { + throw new RangeError("bytes: negative repeat count"); + } else if (source.length * count / count !== source.length) { + throw new Error("bytes: repeat count causes overflow"); + } + const int = Math.floor(count); + if (int !== count) { + throw new Error("bytes: repeat count must be an integer"); + } + const nb = new Uint8Array(source.length * count); + let bp = copy(source, nb); + for(; bp < nb.length; bp *= 2){ + copy(nb.slice(0, bp), nb, bp); + } + return nb; +} +/** Concatenate the given arrays into a new Uint8Array. + * + * ```ts + * import { concat } from "./mod.ts"; + * const a = new Uint8Array([0, 1, 2]); + * const b = new Uint8Array([3, 4, 5]); + * console.log(concat(a, b)); // [0, 1, 2, 3, 4, 5] + */ export function concat(...buf) { + let length = 0; + for (const b of buf){ + length += b.length; + } + const output = new Uint8Array(length); + let index = 0; + for (const b of buf){ + output.set(b, index); + index += b.length; + } + return output; +} +/** Returns true if the source array contains the needle array, false otherwise. + * + * A start index can be specified as the third argument that begins the search + * at that given index. The start index defaults to the beginning of the array. + * + * The complexity of this function is O(source.length * needle.length). + * + * ```ts + * import { includesNeedle } from "./mod.ts"; + * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); + * const needle = new Uint8Array([1, 2]); + * console.log(includesNeedle(source, needle)); // true + * console.log(includesNeedle(source, needle, 6)); // false + * ``` + */ export function includesNeedle(source, needle, start = 0) { + return indexOfNeedle(source, needle, start) !== -1; +} +/** Copy bytes from the `src` array to the `dst` array. Returns the number of + * bytes copied. + * + * If the `src` array is larger than what the `dst` array can hold, only the + * amount of bytes that fit in the `dst` array are copied. + * + * An offset can be specified as the third argument that begins the copy at + * that given index in the `dst` array. The offset defaults to the beginning of + * the array. + * + * ```ts + * import { copy } from "./mod.ts"; + * const src = new Uint8Array([9, 8, 7]); + * const dst = new Uint8Array([0, 1, 2, 3, 4, 5]); + * console.log(copy(src, dst)); // 3 + * console.log(dst); // [9, 8, 7, 3, 4, 5] + * ``` + * + * ```ts + * import { copy } from "./mod.ts"; + * const src = new Uint8Array([1, 1, 1, 1]); + * const dst = new Uint8Array([0, 0, 0, 0]); + * console.log(copy(src, dst, 1)); // 3 + * console.log(dst); // [0, 1, 1, 1] + * ``` + */ export function copy(src, dst, off = 0) { + off = Math.max(0, Math.min(off, dst.byteLength)); + const dstBytesAvailable = dst.byteLength - off; + if (src.byteLength > dstBytesAvailable) { + src = src.subarray(0, dstBytesAvailable); + } + dst.set(src, off); + return src.byteLength; +} +export { equals } from "./equals.ts"; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2J5dGVzL21vZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vKipcbiAqIFByb3ZpZGVzIGhlbHBlciBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSBgVWludDhBcnJheWAgYnl0ZSBzbGljZXMgdGhhdCBhcmUgbm90XG4gKiBpbmNsdWRlZCBvbiB0aGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuLyoqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBuZWVkbGUgYXJyYXkgaW4gdGhlIHNvdXJjZVxuICogYXJyYXksIG9yIC0xIGlmIGl0IGlzIG5vdCBwcmVzZW50LlxuICpcbiAqIEEgc3RhcnQgaW5kZXggY2FuIGJlIHNwZWNpZmllZCBhcyB0aGUgdGhpcmQgYXJndW1lbnQgdGhhdCBiZWdpbnMgdGhlIHNlYXJjaFxuICogYXQgdGhhdCBnaXZlbiBpbmRleC4gVGhlIHN0YXJ0IGluZGV4IGRlZmF1bHRzIHRvIHRoZSBzdGFydCBvZiB0aGUgYXJyYXkuXG4gKlxuICogVGhlIGNvbXBsZXhpdHkgb2YgdGhpcyBmdW5jdGlvbiBpcyBPKHNvdXJjZS5sZW50aCAqIG5lZWRsZS5sZW5ndGgpLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpbmRleE9mTmVlZGxlIH0gZnJvbSBcIi4vbW9kLnRzXCI7XG4gKiBjb25zdCBzb3VyY2UgPSBuZXcgVWludDhBcnJheShbMCwgMSwgMiwgMSwgMiwgMSwgMiwgM10pO1xuICogY29uc3QgbmVlZGxlID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDJdKTtcbiAqIGNvbnNvbGUubG9nKGluZGV4T2ZOZWVkbGUoc291cmNlLCBuZWVkbGUpKTsgLy8gMVxuICogY29uc29sZS5sb2coaW5kZXhPZk5lZWRsZShzb3VyY2UsIG5lZWRsZSwgMikpOyAvLyAzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZGV4T2ZOZWVkbGUoXG4gIHNvdXJjZTogVWludDhBcnJheSxcbiAgbmVlZGxlOiBVaW50OEFycmF5LFxuICBzdGFydCA9IDAsXG4pOiBudW1iZXIge1xuICBpZiAoc3RhcnQgPj0gc291cmNlLmxlbmd0aCkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSBNYXRoLm1heCgwLCBzb3VyY2UubGVuZ3RoICsgc3RhcnQpO1xuICB9XG4gIGNvbnN0IHMgPSBuZWVkbGVbMF07XG4gIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IHNvdXJjZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzb3VyY2VbaV0gIT09IHMpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHBpbiA9IGk7XG4gICAgbGV0IG1hdGNoZWQgPSAxO1xuICAgIGxldCBqID0gaTtcbiAgICB3aGlsZSAobWF0Y2hlZCA8IG5lZWRsZS5sZW5ndGgpIHtcbiAgICAgIGorKztcbiAgICAgIGlmIChzb3VyY2Vbal0gIT09IG5lZWRsZVtqIC0gcGluXSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIG1hdGNoZWQrKztcbiAgICB9XG4gICAgaWYgKG1hdGNoZWQgPT09IG5lZWRsZS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBwaW47XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxuLyoqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIG5lZWRsZSBhcnJheSBpbiB0aGUgc291cmNlXG4gKiBhcnJheSwgb3IgLTEgaWYgaXQgaXMgbm90IHByZXNlbnQuXG4gKlxuICogQSBzdGFydCBpbmRleCBjYW4gYmUgc3BlY2lmaWVkIGFzIHRoZSB0aGlyZCBhcmd1bWVudCB0aGF0IGJlZ2lucyB0aGUgc2VhcmNoXG4gKiBhdCB0aGF0IGdpdmVuIGluZGV4LiBUaGUgc3RhcnQgaW5kZXggZGVmYXVsdHMgdG8gdGhlIGVuZCBvZiB0aGUgYXJyYXkuXG4gKlxuICogVGhlIGNvbXBsZXhpdHkgb2YgdGhpcyBmdW5jdGlvbiBpcyBPKHNvdXJjZS5sZW50aCAqIG5lZWRsZS5sZW5ndGgpLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBsYXN0SW5kZXhPZk5lZWRsZSB9IGZyb20gXCIuL21vZC50c1wiO1xuICogY29uc3Qgc291cmNlID0gbmV3IFVpbnQ4QXJyYXkoWzAsIDEsIDIsIDEsIDIsIDEsIDIsIDNdKTtcbiAqIGNvbnN0IG5lZWRsZSA9IG5ldyBVaW50OEFycmF5KFsxLCAyXSk7XG4gKiBjb25zb2xlLmxvZyhsYXN0SW5kZXhPZk5lZWRsZShzb3VyY2UsIG5lZWRsZSkpOyAvLyA1XG4gKiBjb25zb2xlLmxvZyhsYXN0SW5kZXhPZk5lZWRsZShzb3VyY2UsIG5lZWRsZSwgNCkpOyAvLyAzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhc3RJbmRleE9mTmVlZGxlKFxuICBzb3VyY2U6IFVpbnQ4QXJyYXksXG4gIG5lZWRsZTogVWludDhBcnJheSxcbiAgc3RhcnQgPSBzb3VyY2UubGVuZ3RoIC0gMSxcbik6IG51bWJlciB7XG4gIGlmIChzdGFydCA8IDApIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHN0YXJ0ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICBzdGFydCA9IHNvdXJjZS5sZW5ndGggLSAxO1xuICB9XG4gIGNvbnN0IGUgPSBuZWVkbGVbbmVlZGxlLmxlbmd0aCAtIDFdO1xuICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKHNvdXJjZVtpXSAhPT0gZSkgY29udGludWU7XG4gICAgY29uc3QgcGluID0gaTtcbiAgICBsZXQgbWF0Y2hlZCA9IDE7XG4gICAgbGV0IGogPSBpO1xuICAgIHdoaWxlIChtYXRjaGVkIDwgbmVlZGxlLmxlbmd0aCkge1xuICAgICAgai0tO1xuICAgICAgaWYgKHNvdXJjZVtqXSAhPT0gbmVlZGxlW25lZWRsZS5sZW5ndGggLSAxIC0gKHBpbiAtIGopXSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIG1hdGNoZWQrKztcbiAgICB9XG4gICAgaWYgKG1hdGNoZWQgPT09IG5lZWRsZS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBwaW4gLSBuZWVkbGUubGVuZ3RoICsgMTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG4vKiogUmV0dXJucyB0cnVlIGlmIHRoZSBwcmVmaXggYXJyYXkgYXBwZWFycyBhdCB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZSBhcnJheSxcbiAqIGZhbHNlIG90aGVyd2lzZS5cbiAqXG4gKiBUaGUgY29tcGxleGl0eSBvZiB0aGlzIGZ1bmN0aW9uIGlzIE8ocHJlZml4Lmxlbmd0aCkuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IHN0YXJ0c1dpdGggfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqIGNvbnN0IHNvdXJjZSA9IG5ldyBVaW50OEFycmF5KFswLCAxLCAyLCAxLCAyLCAxLCAyLCAzXSk7XG4gKiBjb25zdCBwcmVmaXggPSBuZXcgVWludDhBcnJheShbMCwgMSwgMl0pO1xuICogY29uc29sZS5sb2coc3RhcnRzV2l0aChzb3VyY2UsIHByZWZpeCkpOyAvLyB0cnVlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0c1dpdGgoc291cmNlOiBVaW50OEFycmF5LCBwcmVmaXg6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgZm9yIChsZXQgaSA9IDAsIG1heCA9IHByZWZpeC5sZW5ndGg7IGkgPCBtYXg7IGkrKykge1xuICAgIGlmIChzb3VyY2VbaV0gIT09IHByZWZpeFtpXSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogUmV0dXJucyB0cnVlIGlmIHRoZSBzdWZmaXggYXJyYXkgYXBwZWFycyBhdCB0aGUgZW5kIG9mIHRoZSBzb3VyY2UgYXJyYXksXG4gKiBmYWxzZSBvdGhlcndpc2UuXG4gKlxuICogVGhlIGNvbXBsZXhpdHkgb2YgdGhpcyBmdW5jdGlvbiBpcyBPKHN1ZmZpeC5sZW5ndGgpLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBlbmRzV2l0aCB9IGZyb20gXCIuL21vZC50c1wiO1xuICogY29uc3Qgc291cmNlID0gbmV3IFVpbnQ4QXJyYXkoWzAsIDEsIDIsIDEsIDIsIDEsIDIsIDNdKTtcbiAqIGNvbnN0IHN1ZmZpeCA9IG5ldyBVaW50OEFycmF5KFsxLCAyLCAzXSk7XG4gKiBjb25zb2xlLmxvZyhlbmRzV2l0aChzb3VyY2UsIHN1ZmZpeCkpOyAvLyB0cnVlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuZHNXaXRoKHNvdXJjZTogVWludDhBcnJheSwgc3VmZml4OiBVaW50OEFycmF5KTogYm9vbGVhbiB7XG4gIGZvciAoXG4gICAgbGV0IHNyY2kgPSBzb3VyY2UubGVuZ3RoIC0gMSwgc2Z4aSA9IHN1ZmZpeC5sZW5ndGggLSAxO1xuICAgIHNmeGkgPj0gMDtcbiAgICBzcmNpLS0sIHNmeGktLVxuICApIHtcbiAgICBpZiAoc291cmNlW3NyY2ldICE9PSBzdWZmaXhbc2Z4aV0pIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqIFJldHVybnMgYSBuZXcgVWludDhBcnJheSBjb21wb3NlZCBvZiBgY291bnRgIHJlcGV0aXRpb25zIG9mIHRoZSBgc291cmNlYFxuICogYXJyYXkuXG4gKlxuICogSWYgYGNvdW50YCBpcyBuZWdhdGl2ZSwgYSBgUmFuZ2VFcnJvcmAgaXMgdGhyb3duLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyByZXBlYXQgfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqIGNvbnN0IHNvdXJjZSA9IG5ldyBVaW50OEFycmF5KFswLCAxLCAyXSk7XG4gKiBjb25zb2xlLmxvZyhyZXBlYXQoc291cmNlLCAzKSk7IC8vIFswLCAxLCAyLCAwLCAxLCAyLCAwLCAxLCAyXVxuICogY29uc29sZS5sb2cocmVwZWF0KHNvdXJjZSwgMCkpOyAvLyBbXVxuICogY29uc29sZS5sb2cocmVwZWF0KHNvdXJjZSwgLTEpKTsgLy8gUmFuZ2VFcnJvclxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBlYXQoc291cmNlOiBVaW50OEFycmF5LCBjb3VudDogbnVtYmVyKTogVWludDhBcnJheSB7XG4gIGlmIChjb3VudCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheSgpO1xuICB9XG5cbiAgaWYgKGNvdW50IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiYnl0ZXM6IG5lZ2F0aXZlIHJlcGVhdCBjb3VudFwiKTtcbiAgfSBlbHNlIGlmICgoc291cmNlLmxlbmd0aCAqIGNvdW50KSAvIGNvdW50ICE9PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYnl0ZXM6IHJlcGVhdCBjb3VudCBjYXVzZXMgb3ZlcmZsb3dcIik7XG4gIH1cblxuICBjb25zdCBpbnQgPSBNYXRoLmZsb29yKGNvdW50KTtcblxuICBpZiAoaW50ICE9PSBjb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImJ5dGVzOiByZXBlYXQgY291bnQgbXVzdCBiZSBhbiBpbnRlZ2VyXCIpO1xuICB9XG5cbiAgY29uc3QgbmIgPSBuZXcgVWludDhBcnJheShzb3VyY2UubGVuZ3RoICogY291bnQpO1xuXG4gIGxldCBicCA9IGNvcHkoc291cmNlLCBuYik7XG5cbiAgZm9yICg7IGJwIDwgbmIubGVuZ3RoOyBicCAqPSAyKSB7XG4gICAgY29weShuYi5zbGljZSgwLCBicCksIG5iLCBicCk7XG4gIH1cblxuICByZXR1cm4gbmI7XG59XG5cbi8qKiBDb25jYXRlbmF0ZSB0aGUgZ2l2ZW4gYXJyYXlzIGludG8gYSBuZXcgVWludDhBcnJheS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgY29uY2F0IH0gZnJvbSBcIi4vbW9kLnRzXCI7XG4gKiBjb25zdCBhID0gbmV3IFVpbnQ4QXJyYXkoWzAsIDEsIDJdKTtcbiAqIGNvbnN0IGIgPSBuZXcgVWludDhBcnJheShbMywgNCwgNV0pO1xuICogY29uc29sZS5sb2coY29uY2F0KGEsIGIpKTsgLy8gWzAsIDEsIDIsIDMsIDQsIDVdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25jYXQoLi4uYnVmOiBVaW50OEFycmF5W10pOiBVaW50OEFycmF5IHtcbiAgbGV0IGxlbmd0aCA9IDA7XG4gIGZvciAoY29uc3QgYiBvZiBidWYpIHtcbiAgICBsZW5ndGggKz0gYi5sZW5ndGg7XG4gIH1cblxuICBjb25zdCBvdXRwdXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICBsZXQgaW5kZXggPSAwO1xuICBmb3IgKGNvbnN0IGIgb2YgYnVmKSB7XG4gICAgb3V0cHV0LnNldChiLCBpbmRleCk7XG4gICAgaW5kZXggKz0gYi5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKiogUmV0dXJucyB0cnVlIGlmIHRoZSBzb3VyY2UgYXJyYXkgY29udGFpbnMgdGhlIG5lZWRsZSBhcnJheSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEEgc3RhcnQgaW5kZXggY2FuIGJlIHNwZWNpZmllZCBhcyB0aGUgdGhpcmQgYXJndW1lbnQgdGhhdCBiZWdpbnMgdGhlIHNlYXJjaFxuICogYXQgdGhhdCBnaXZlbiBpbmRleC4gVGhlIHN0YXJ0IGluZGV4IGRlZmF1bHRzIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFycmF5LlxuICpcbiAqIFRoZSBjb21wbGV4aXR5IG9mIHRoaXMgZnVuY3Rpb24gaXMgTyhzb3VyY2UubGVuZ3RoICogbmVlZGxlLmxlbmd0aCkuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGluY2x1ZGVzTmVlZGxlIH0gZnJvbSBcIi4vbW9kLnRzXCI7XG4gKiBjb25zdCBzb3VyY2UgPSBuZXcgVWludDhBcnJheShbMCwgMSwgMiwgMSwgMiwgMSwgMiwgM10pO1xuICogY29uc3QgbmVlZGxlID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDJdKTtcbiAqIGNvbnNvbGUubG9nKGluY2x1ZGVzTmVlZGxlKHNvdXJjZSwgbmVlZGxlKSk7IC8vIHRydWVcbiAqIGNvbnNvbGUubG9nKGluY2x1ZGVzTmVlZGxlKHNvdXJjZSwgbmVlZGxlLCA2KSk7IC8vIGZhbHNlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluY2x1ZGVzTmVlZGxlKFxuICBzb3VyY2U6IFVpbnQ4QXJyYXksXG4gIG5lZWRsZTogVWludDhBcnJheSxcbiAgc3RhcnQgPSAwLFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiBpbmRleE9mTmVlZGxlKHNvdXJjZSwgbmVlZGxlLCBzdGFydCkgIT09IC0xO1xufVxuXG4vKiogQ29weSBieXRlcyBmcm9tIHRoZSBgc3JjYCBhcnJheSB0byB0aGUgYGRzdGAgYXJyYXkuIFJldHVybnMgdGhlIG51bWJlciBvZlxuICogYnl0ZXMgY29waWVkLlxuICpcbiAqIElmIHRoZSBgc3JjYCBhcnJheSBpcyBsYXJnZXIgdGhhbiB3aGF0IHRoZSBgZHN0YCBhcnJheSBjYW4gaG9sZCwgb25seSB0aGVcbiAqIGFtb3VudCBvZiBieXRlcyB0aGF0IGZpdCBpbiB0aGUgYGRzdGAgYXJyYXkgYXJlIGNvcGllZC5cbiAqXG4gKiBBbiBvZmZzZXQgY2FuIGJlIHNwZWNpZmllZCBhcyB0aGUgdGhpcmQgYXJndW1lbnQgdGhhdCBiZWdpbnMgdGhlIGNvcHkgYXRcbiAqIHRoYXQgZ2l2ZW4gaW5kZXggaW4gdGhlIGBkc3RgIGFycmF5LiBUaGUgb2Zmc2V0IGRlZmF1bHRzIHRvIHRoZSBiZWdpbm5pbmcgb2ZcbiAqIHRoZSBhcnJheS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgY29weSB9IGZyb20gXCIuL21vZC50c1wiO1xuICogY29uc3Qgc3JjID0gbmV3IFVpbnQ4QXJyYXkoWzksIDgsIDddKTtcbiAqIGNvbnN0IGRzdCA9IG5ldyBVaW50OEFycmF5KFswLCAxLCAyLCAzLCA0LCA1XSk7XG4gKiBjb25zb2xlLmxvZyhjb3B5KHNyYywgZHN0KSk7IC8vIDNcbiAqIGNvbnNvbGUubG9nKGRzdCk7IC8vIFs5LCA4LCA3LCAzLCA0LCA1XVxuICogYGBgXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGNvcHkgfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqIGNvbnN0IHNyYyA9IG5ldyBVaW50OEFycmF5KFsxLCAxLCAxLCAxXSk7XG4gKiBjb25zdCBkc3QgPSBuZXcgVWludDhBcnJheShbMCwgMCwgMCwgMF0pO1xuICogY29uc29sZS5sb2coY29weShzcmMsIGRzdCwgMSkpOyAvLyAzXG4gKiBjb25zb2xlLmxvZyhkc3QpOyAvLyBbMCwgMSwgMSwgMV1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY29weShzcmM6IFVpbnQ4QXJyYXksIGRzdDogVWludDhBcnJheSwgb2ZmID0gMCk6IG51bWJlciB7XG4gIG9mZiA9IE1hdGgubWF4KDAsIE1hdGgubWluKG9mZiwgZHN0LmJ5dGVMZW5ndGgpKTtcbiAgY29uc3QgZHN0Qnl0ZXNBdmFpbGFibGUgPSBkc3QuYnl0ZUxlbmd0aCAtIG9mZjtcbiAgaWYgKHNyYy5ieXRlTGVuZ3RoID4gZHN0Qnl0ZXNBdmFpbGFibGUpIHtcbiAgICBzcmMgPSBzcmMuc3ViYXJyYXkoMCwgZHN0Qnl0ZXNBdmFpbGFibGUpO1xuICB9XG4gIGRzdC5zZXQoc3JjLCBvZmYpO1xuICByZXR1cm4gc3JjLmJ5dGVMZW5ndGg7XG59XG5cbmV4cG9ydCB7IGVxdWFscyB9IGZyb20gXCIuL2VxdWFscy50c1wiO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxxQ0FBcUM7QUFFckM7Ozs7O0NBS0MsR0FFRDs7Ozs7Ozs7Ozs7Ozs7O0NBZUMsR0FDRCxPQUFPLFNBQVMsY0FDZCxNQUFrQixFQUNsQixNQUFrQixFQUNsQixRQUFRLENBQUMsRUFDRDtJQUNSLElBQUksU0FBUyxPQUFP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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js b/tests/__snapshots__/transpile/url/modules/WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js new file mode 100644 index 0000000..3767f70 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/WzxVr2Q8XtUlLvHc6jsTVQR8Mnc.js @@ -0,0 +1,47 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +// Alphabet chars. +export const CHAR_UPPERCASE_A = 65; /* A */ +export const CHAR_LOWERCASE_A = 97; /* a */ +export const CHAR_UPPERCASE_Z = 90; /* Z */ +export const CHAR_LOWERCASE_Z = 122; /* z */ +// Non-alphabetic chars. +export const CHAR_DOT = 46; /* . */ +export const CHAR_FORWARD_SLASH = 47; /* / */ +export const CHAR_BACKWARD_SLASH = 92; /* \ */ +export const CHAR_VERTICAL_LINE = 124; /* | */ +export const CHAR_COLON = 58; /* : */ +export const CHAR_QUESTION_MARK = 63; /* ? */ +export const CHAR_UNDERSCORE = 95; /* _ */ +export const CHAR_LINE_FEED = 10; /* \n */ +export const CHAR_CARRIAGE_RETURN = 13; /* \r */ +export const CHAR_TAB = 9; /* \t */ +export const CHAR_FORM_FEED = 12; /* \f */ +export const CHAR_EXCLAMATION_MARK = 33; /* ! */ +export const CHAR_HASH = 35; /* # */ +export const CHAR_SPACE = 32; /* */ +export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */ +export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */ +export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */ +export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */ +export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */ +export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */ +export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */ +export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */ +export const CHAR_HYPHEN_MINUS = 45; /* - */ +export const CHAR_PLUS = 43; /* + */ +export const CHAR_DOUBLE_QUOTE = 34; /* " */ +export const CHAR_SINGLE_QUOTE = 39; /* ' */ +export const CHAR_PERCENT = 37; /* % */ +export const CHAR_SEMICOLON = 59; /* ; */ +export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */ +export const CHAR_GRAVE_ACCENT = 96; /* ` */ +export const CHAR_AT = 64; /* @ */ +export const CHAR_AMPERSAND = 38; /* & */ +export const CHAR_EQUAL = 61; /* = */ +// Digits +export const CHAR_0 = 48; /* 0 */ +export const CHAR_9 = 57; /* 9 */ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvX2NvbnN0YW50cy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gQ29weXJpZ2h0IHRoZSBCcm93c2VyaWZ5IGF1dGhvcnMuIE1JVCBMaWNlbnNlLlxuLy8gUG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Jyb3dzZXJpZnkvcGF0aC1icm93c2VyaWZ5L1xuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vLyBBbHBoYWJldCBjaGFycy5cbmV4cG9ydCBjb25zdCBDSEFSX1VQUEVSQ0FTRV9BID0gNjU7IC8qIEEgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xPV0VSQ0FTRV9BID0gOTc7IC8qIGEgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1VQUEVSQ0FTRV9aID0gOTA7IC8qIFogKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xPV0VSQ0FTRV9aID0gMTIyOyAvKiB6ICovXG5cbi8vIE5vbi1hbHBoYWJldGljIGNoYXJzLlxuZXhwb3J0IGNvbnN0IENIQVJfRE9UID0gNDY7IC8qIC4gKi9cbmV4cG9ydCBjb25zdCBDSEFSX0ZPUldBUkRfU0xBU0ggPSA0NzsgLyogLyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQkFDS1dBUkRfU0xBU0ggPSA5MjsgLyogXFwgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1ZFUlRJQ0FMX0xJTkUgPSAxMjQ7IC8qIHwgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0NPTE9OID0gNTg7IC8qIDogKi9cbmV4cG9ydCBjb25zdCBDSEFSX1FVRVNUSU9OX01BUksgPSA2MzsgLyogPyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfVU5ERVJTQ09SRSA9IDk1OyAvKiBfICovXG5leHBvcnQgY29uc3QgQ0hBUl9MSU5FX0ZFRUQgPSAxMDsgLyogXFxuICovXG5leHBvcnQgY29uc3QgQ0hBUl9DQVJSSUFHRV9SRVRVUk4gPSAxMzsgLyogXFxyICovXG5leHBvcnQgY29uc3QgQ0hBUl9UQUIgPSA5OyAvKiBcXHQgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0ZPUk1fRkVFRCA9IDEyOyAvKiBcXGYgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0VYQ0xBTUFUSU9OX01BUksgPSAzMzsgLyogISAqL1xuZXhwb3J0IGNvbnN0IENIQVJfSEFTSCA9IDM1OyAvKiAjICovXG5leHBvcnQgY29uc3QgQ0hBUl9TUEFDRSA9IDMyOyAvKiAgICovXG5leHBvcnQgY29uc3QgQ0hBUl9OT19CUkVBS19TUEFDRSA9IDE2MDsgLyogXFx1MDBBMCAqL1xuZXhwb3J0IGNvbnN0IENIQVJfWkVST19XSURUSF9OT0JSRUFLX1NQQUNFID0gNjUyNzk7IC8qIFxcdUZFRkYgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0xFRlRfU1FVQVJFX0JSQUNLRVQgPSA5MTsgLyogWyAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUklHSFRfU1FVQVJFX0JSQUNLRVQgPSA5MzsgLyogXSAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTEVGVF9BTkdMRV9CUkFDS0VUID0gNjA7IC8qIDwgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1JJR0hUX0FOR0xFX0JSQUNLRVQgPSA2MjsgLyogPiAqL1xuZXhwb3J0IGNvbnN0IENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUID0gMTIzOyAvKiB7ICovXG5leHBvcnQgY29uc3QgQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUID0gMTI1OyAvKiB9ICovXG5leHBvcnQgY29uc3QgQ0hBUl9IWVBIRU5fTUlOVVMgPSA0NTsgLyogLSAqL1xuZXhwb3J0IGNvbnN0IENIQVJfUExVUyA9IDQzOyAvKiArICovXG5leHBvcnQgY29uc3QgQ0hBUl9ET1VCTEVfUVVPVEUgPSAzNDsgLyogXCIgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1NJTkdMRV9RVU9URSA9IDM5OyAvKiAnICovXG5leHBvcnQgY29uc3QgQ0hBUl9QRVJDRU5UID0gMzc7IC8qICUgKi9cbmV4cG9ydCBjb25zdCBDSEFSX1NFTUlDT0xPTiA9IDU5OyAvKiA7ICovXG5leHBvcnQgY29uc3QgQ0hBUl9DSVJDVU1GTEVYX0FDQ0VOVCA9IDk0OyAvKiBeICovXG5leHBvcnQgY29uc3QgQ0hBUl9HUkFWRV9BQ0NFTlQgPSA5NjsgLyogYCAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQVQgPSA2NDsgLyogQCAqL1xuZXhwb3J0IGNvbnN0IENIQVJfQU1QRVJTQU5EID0gMzg7IC8qICYgKi9cbmV4cG9ydCBjb25zdCBDSEFSX0VRVUFMID0gNjE7IC8qID0gKi9cblxuLy8gRGlnaXRzXG5leHBvcnQgY29uc3QgQ0hBUl8wID0gNDg7IC8qIDAgKi9cbmV4cG9ydCBjb25zdCBDSEFSXzkgPSA1NzsgLyogOSAqL1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxpREFBaUQ7QUFDakQsNkRBQTZEO0FBQzdELHFDQUFxQztBQUVyQyxrQkFBa0I7QUFDbEIsT0FBTyxNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBSztBQUN6QyxPQUFPLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxLQUFLO0FBQ3pDLE9BQU8sTUFBTSxtQkFBbUIsR0FBRyxDQUFDLEtBQUs7QUFDekMsT0FBTyxNQUFNLG1CQUFtQixJQUFJLENBQUMsS0FBSztBQUUxQyx3QkFBd0I7QUFDeEIsT0FBTyxNQUFNLFdBQVcsR0FBRyxDQUFDLEtBQUs7QUFDakMsT0FBTyxNQUFNLHFCQUFxQixHQUFHLENBQUMsS0FBSztBQUMzQyxPQUFPLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxLQUFLO0FBQzVDLE9BQU8sTUFBTSxxQkFBcUIsSUFBSSxDQUFDLEtBQUs7QUFDNUMsT0FBTyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUs7QUFDbkMsT0FBTyxNQUFNLHFCQUFxQixHQUFHLENBQUMsS0FBSztBQUMzQyxPQUFPLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxLQUFLO0FBQ3hDLE9BQU8sTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE1BQU07QUFDeEMsT0FBTyxNQUFNLHVCQUF1QixHQUFHLENBQUMsTUFBTTtBQUM5QyxPQUFPLE1BQU0sV0FBVyxFQUFFLENBQUMsTUFBTTtBQUNqQyxPQUFPLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxNQUFNO0FBQ3hDLE9BQU8sTUFBTSx3QkFBd0IsR0FBRyxDQUFDLEtBQUs7QUFDOUMsT0FBTyxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQUs7QUFDbEMsT0FBTyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUs7QUFDbkMsT0FBTyxNQUFNLHNCQUFzQixJQUFJLENBQUMsVUFBVTtBQUNsRCxPQUFPLE1BQU0sZ0NBQWdDLE1BQU0sQ0FBQyxVQUFVO0FBQzlELE9BQU8sTUFBTSwyQkFBMkIsR0FBRyxDQUFDLEtBQUs7QUFDakQsT0FBTyxNQUFNLDRCQUE0QixHQUFHLENBQUMsS0FBSztBQUNsRCxPQUFPLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxLQUFLO0FBQ2hELE9BQU8sTUFBTSwyQkFBMkIsR0FBRyxDQUFDLEtBQUs7QUFDakQsT0FBTyxNQUFNLDBCQUEwQixJQUFJLENBQUMsS0FBSztBQUNqRCxPQUFPLE1BQU0sMkJBQTJCLElBQUksQ0FBQyxLQUFLO0FBQ2xELE9BQU8sTUFBTSxvQkFBb0IsR0FBRyxDQUFDLEtBQUs7QUFDMUMsT0FBTyxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQUs7QUFDbEMsT0FBTyxNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBSztBQUMxQyxPQUFPLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxLQUFLO0FBQzFDLE9BQU8sTUFBTSxlQUFlLEdBQUcsQ0FBQyxLQUFLO0FBQ3JDLE9BQU8sTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEtBQUs7QUFDdkMsT0FBTyxNQUFNLHlCQUF5QixHQUFHLENBQUMsS0FBSztBQUMvQyxPQUFPLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxLQUFLO0FBQzFDLE9BQU8sTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFLO0FBQ2hDLE9BQU8sTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEtBQUs7QUFDdkMsT0FBTyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUs7QUFFbkMsU0FBUztBQUNULE9BQU8sTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUFLO0FBQy9CLE9BQU8sTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUFLIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js b/tests/__snapshots__/transpile/url/modules/ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js new file mode 100644 index 0000000..0fdef86 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/ZD3DgFZlCOXbEC8b6k6GmMtkN3g.js @@ -0,0 +1,430 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { Buffer } from "../io/buffer.ts"; +const DEFAULT_CHUNK_SIZE = 16_640; +const DEFAULT_BUFFER_SIZE = 32 * 1024; +function isCloser(value) { + return typeof value === "object" && value != null && "close" in value && // deno-lint-ignore no-explicit-any + typeof value["close"] === "function"; +} +/** Create a `Deno.Reader` from an iterable of `Uint8Array`s. + * + * ```ts + * import { readerFromIterable } from "./conversion.ts"; + * + * const file = await Deno.open("metrics.txt", { write: true }); + * const reader = readerFromIterable((async function* () { + * while (true) { + * await new Promise((r) => setTimeout(r, 1000)); + * const message = `data: ${JSON.stringify(Deno.metrics())}\n\n`; + * yield new TextEncoder().encode(message); + * } + * })()); + * await Deno.copy(reader, file); + * ``` + */ export function readerFromIterable(iterable) { + const iterator = iterable[Symbol.asyncIterator]?.() ?? iterable[Symbol.iterator]?.(); + const buffer = new Buffer(); + return { + async read (p) { + if (buffer.length == 0) { + const result = await iterator.next(); + if (result.done) { + return null; + } else { + if (result.value.byteLength <= p.byteLength) { + p.set(result.value); + return result.value.byteLength; + } + p.set(result.value.subarray(0, p.byteLength)); + await writeAll(buffer, result.value.subarray(p.byteLength)); + return p.byteLength; + } + } else { + const n = await buffer.read(p); + if (n == null) { + return this.read(p); + } + return n; + } + } + }; +} +/** Create a `Writer` from a `WritableStreamDefaultWriter`. */ export function writerFromStreamWriter(streamWriter) { + return { + async write (p) { + await streamWriter.ready; + await streamWriter.write(p); + return p.length; + } + }; +} +/** Create a `Reader` from a `ReadableStreamDefaultReader`. */ export function readerFromStreamReader(streamReader) { + const buffer = new Buffer(); + return { + async read (p) { + if (buffer.empty()) { + const res = await streamReader.read(); + if (res.done) { + return null; // EOF + } + await writeAll(buffer, res.value); + } + return buffer.read(p); + } + }; +} +/** Create a `WritableStream` from a `Writer`. */ export function writableStreamFromWriter(writer, options = {}) { + const { autoClose =true } = options; + return new WritableStream({ + async write (chunk, controller) { + try { + await writeAll(writer, chunk); + } catch (e) { + controller.error(e); + if (isCloser(writer) && autoClose) { + writer.close(); + } + } + }, + close () { + if (isCloser(writer) && autoClose) { + writer.close(); + } + }, + abort () { + if (isCloser(writer) && autoClose) { + writer.close(); + } + } + }); +} +/** Create a `ReadableStream` from any kind of iterable. + * + * ```ts + * import { readableStreamFromIterable } from "./conversion.ts"; + * + * const r1 = readableStreamFromIterable(["foo, bar, baz"]); + * const r2 = readableStreamFromIterable(async function* () { + * await new Promise(((r) => setTimeout(r, 1000))); + * yield "foo"; + * await new Promise(((r) => setTimeout(r, 1000))); + * yield "bar"; + * await new Promise(((r) => setTimeout(r, 1000))); + * yield "baz"; + * }()); + * ``` + * + * If the produced iterator (`iterable[Symbol.asyncIterator]()` or + * `iterable[Symbol.iterator]()`) is a generator, or more specifically is found + * to have a `.throw()` method on it, that will be called upon + * `readableStream.cancel()`. This is the case for the second input type above: + * + * ```ts + * import { readableStreamFromIterable } from "./conversion.ts"; + * + * const r3 = readableStreamFromIterable(async function* () { + * try { + * yield "foo"; + * } catch (error) { + * console.log(error); // Error: Cancelled by consumer. + * } + * }()); + * const reader = r3.getReader(); + * console.log(await reader.read()); // { value: "foo", done: false } + * await reader.cancel(new Error("Cancelled by consumer.")); + * ``` + */ export function readableStreamFromIterable(iterable) { + const iterator = iterable[Symbol.asyncIterator]?.() ?? iterable[Symbol.iterator]?.(); + return new ReadableStream({ + async pull (controller) { + const { value , done } = await iterator.next(); + if (done) { + controller.close(); + } else { + controller.enqueue(value); + } + }, + async cancel (reason) { + if (typeof iterator.throw == "function") { + try { + await iterator.throw(reason); + } catch {} + } + } + }); +} +/** + * Create a `ReadableStream` from from a `Deno.Reader`. + * + * When the pull algorithm is called on the stream, a chunk from the reader + * will be read. When `null` is returned from the reader, the stream will be + * closed along with the reader (if it is also a `Deno.Closer`). + * + * An example converting a `Deno.FsFile` into a readable stream: + * + * ```ts + * import { readableStreamFromReader } from "./mod.ts"; + * + * const file = await Deno.open("./file.txt", { read: true }); + * const fileStream = readableStreamFromReader(file); + * ``` + */ export function readableStreamFromReader(reader, options = {}) { + const { autoClose =true , chunkSize =DEFAULT_CHUNK_SIZE , strategy } = options; + return new ReadableStream({ + async pull (controller) { + const chunk = new Uint8Array(chunkSize); + try { + const read = await reader.read(chunk); + if (read === null) { + if (isCloser(reader) && autoClose) { + reader.close(); + } + controller.close(); + return; + } + controller.enqueue(chunk.subarray(0, read)); + } catch (e) { + controller.error(e); + if (isCloser(reader)) { + reader.close(); + } + } + }, + cancel () { + if (isCloser(reader) && autoClose) { + reader.close(); + } + } + }, strategy); +} +/** Read Reader `r` until EOF (`null`) and resolve to the content as + * Uint8Array`. + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { readAll } from "./conversion.ts"; + * + * // Example from stdin + * const stdinContent = await readAll(Deno.stdin); + * + * // Example from file + * const file = await Deno.open("my_file.txt", {read: true}); + * const myFileContent = await readAll(file); + * Deno.close(file.rid); + * + * // Example from buffer + * const myData = new Uint8Array(100); + * // ... fill myData array with data + * const reader = new Buffer(myData.buffer); + * const bufferContent = await readAll(reader); + * ``` + */ export async function readAll(r) { + const buf = new Buffer(); + await buf.readFrom(r); + return buf.bytes(); +} +/** Synchronously reads Reader `r` until EOF (`null`) and returns the content + * as `Uint8Array`. + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { readAllSync } from "./conversion.ts"; + * + * // Example from stdin + * const stdinContent = readAllSync(Deno.stdin); + * + * // Example from file + * const file = Deno.openSync("my_file.txt", {read: true}); + * const myFileContent = readAllSync(file); + * Deno.close(file.rid); + * + * // Example from buffer + * const myData = new Uint8Array(100); + * // ... fill myData array with data + * const reader = new Buffer(myData.buffer); + * const bufferContent = readAllSync(reader); + * ``` + */ export function readAllSync(r) { + const buf = new Buffer(); + buf.readFromSync(r); + return buf.bytes(); +} +/** Write all the content of the array buffer (`arr`) to the writer (`w`). + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { writeAll } from "./conversion.ts"; + + * // Example writing to stdout + * let contentBytes = new TextEncoder().encode("Hello World"); + * await writeAll(Deno.stdout, contentBytes); + * + * // Example writing to file + * contentBytes = new TextEncoder().encode("Hello World"); + * const file = await Deno.open('test.file', {write: true}); + * await writeAll(file, contentBytes); + * Deno.close(file.rid); + * + * // Example writing to buffer + * contentBytes = new TextEncoder().encode("Hello World"); + * const writer = new Buffer(); + * await writeAll(writer, contentBytes); + * console.log(writer.bytes().length); // 11 + * ``` + */ export async function writeAll(w, arr) { + let nwritten = 0; + while(nwritten < arr.length){ + nwritten += await w.write(arr.subarray(nwritten)); + } +} +/** Synchronously write all the content of the array buffer (`arr`) to the + * writer (`w`). + * + * ```ts + * import { Buffer } from "../io/buffer.ts"; + * import { writeAllSync } from "./conversion.ts"; + * + * // Example writing to stdout + * let contentBytes = new TextEncoder().encode("Hello World"); + * writeAllSync(Deno.stdout, contentBytes); + * + * // Example writing to file + * contentBytes = new TextEncoder().encode("Hello World"); + * const file = Deno.openSync('test.file', {write: true}); + * writeAllSync(file, contentBytes); + * Deno.close(file.rid); + * + * // Example writing to buffer + * contentBytes = new TextEncoder().encode("Hello World"); + * const writer = new Buffer(); + * writeAllSync(writer, contentBytes); + * console.log(writer.bytes().length); // 11 + * ``` + */ export function writeAllSync(w, arr) { + let nwritten = 0; + while(nwritten < arr.length){ + nwritten += w.writeSync(arr.subarray(nwritten)); + } +} +/** Turns a Reader, `r`, into an async iterator. + * + * ```ts + * import { iterateReader } from "./conversion.ts"; + * + * let f = await Deno.open("/etc/passwd"); + * for await (const chunk of iterateReader(f)) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Second argument can be used to tune size of a buffer. + * Default size of the buffer is 32kB. + * + * ```ts + * import { iterateReader } from "./conversion.ts"; + * + * let f = await Deno.open("/etc/passwd"); + * const it = iterateReader(f, { + * bufSize: 1024 * 1024 + * }); + * for await (const chunk of it) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Iterator uses an internal buffer of fixed size for efficiency; it returns + * a view on that buffer on each iteration. It is therefore caller's + * responsibility to copy contents of the buffer if needed; otherwise the + * next iteration will overwrite contents of previously returned chunk. + */ export async function* iterateReader(r, options) { + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + while(true){ + const result = await r.read(b); + if (result === null) { + break; + } + yield b.subarray(0, result); + } +} +/** Turns a ReaderSync, `r`, into an iterator. + * + * ```ts + * import { iterateReaderSync } from "./conversion.ts"; + * + * let f = Deno.openSync("/etc/passwd"); + * for (const chunk of iterateReaderSync(f)) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Second argument can be used to tune size of a buffer. + * Default size of the buffer is 32kB. + * + * ```ts + * import { iterateReaderSync } from "./conversion.ts"; + + * let f = await Deno.open("/etc/passwd"); + * const iter = iterateReaderSync(f, { + * bufSize: 1024 * 1024 + * }); + * for (const chunk of iter) { + * console.log(chunk); + * } + * f.close(); + * ``` + * + * Iterator uses an internal buffer of fixed size for efficiency; it returns + * a view on that buffer on each iteration. It is therefore caller's + * responsibility to copy contents of the buffer if needed; otherwise the + * next iteration will overwrite contents of previously returned chunk. + */ export function* iterateReaderSync(r, options) { + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + while(true){ + const result = r.readSync(b); + if (result === null) { + break; + } + yield b.subarray(0, result); + } +} +/** Copies from `src` to `dst` until either EOF (`null`) is read from `src` or + * an error occurs. It resolves to the number of bytes copied or rejects with + * the first error encountered while copying. + * + * ```ts + * import { copy } from "./conversion.ts"; + * + * const source = await Deno.open("my_file.txt"); + * const bytesCopied1 = await copy(source, Deno.stdout); + * const destination = await Deno.create("my_file_2.txt"); + * const bytesCopied2 = await copy(source, destination); + * ``` + * + * @param src The source to copy from + * @param dst The destination to copy to + * @param options Can be used to tune size of the buffer. Default size is 32kB + */ export async function copy(src, dst, options) { + let n = 0; + const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; + const b = new Uint8Array(bufSize); + let gotEOF = false; + while(gotEOF === false){ + const result = await src.read(b); + if (result === null) { + gotEOF = true; + } else { + let nwritten = 0; + while(nwritten < result){ + nwritten += await dst.write(b.subarray(nwritten, result)); + } + n += nwritten; + } + } + return n; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3N0cmVhbXMvY29udmVyc2lvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuXG5pbXBvcnQgeyBCdWZmZXIgfSBmcm9tIFwiLi4vaW8vYnVmZmVyLnRzXCI7XG5cbmNvbnN0IERFRkFVTFRfQ0hVTktfU0laRSA9IDE2XzY0MDtcbmNvbnN0IERFRkFVTFRfQlVGRkVSX1NJWkUgPSAzMiAqIDEwMjQ7XG5cbmZ1bmN0aW9uIGlzQ2xvc2VyKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgRGVuby5DbG9zZXIge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9IG51bGwgJiYgXCJjbG9zZVwiIGluIHZhbHVlICYmXG4gICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICB0eXBlb2YgKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW1wiY2xvc2VcIl0gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqIENyZWF0ZSBhIGBEZW5vLlJlYWRlcmAgZnJvbSBhbiBpdGVyYWJsZSBvZiBgVWludDhBcnJheWBzLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IHJlYWRlckZyb21JdGVyYWJsZSB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oXCJtZXRyaWNzLnR4dFwiLCB7IHdyaXRlOiB0cnVlIH0pO1xuICogICAgICBjb25zdCByZWFkZXIgPSByZWFkZXJGcm9tSXRlcmFibGUoKGFzeW5jIGZ1bmN0aW9uKiAoKSB7XG4gKiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAqICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEwMDApKTtcbiAqICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBgZGF0YTogJHtKU09OLnN0cmluZ2lmeShEZW5vLm1ldHJpY3MoKSl9XFxuXFxuYDtcbiAqICAgICAgICAgIHlpZWxkIG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShtZXNzYWdlKTtcbiAqICAgICAgICB9XG4gKiAgICAgIH0pKCkpO1xuICogICAgICBhd2FpdCBEZW5vLmNvcHkocmVhZGVyLCBmaWxlKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZGVyRnJvbUl0ZXJhYmxlKFxuICBpdGVyYWJsZTogSXRlcmFibGU8VWludDhBcnJheT4gfCBBc3luY0l0ZXJhYmxlPFVpbnQ4QXJyYXk+LFxuKTogRGVuby5SZWFkZXIge1xuICBjb25zdCBpdGVyYXRvcjogSXRlcmF0b3I8VWludDhBcnJheT4gfCBBc3luY0l0ZXJhdG9yPFVpbnQ4QXJyYXk+ID1cbiAgICAoaXRlcmFibGUgYXMgQXN5bmNJdGVyYWJsZTxVaW50OEFycmF5PilbU3ltYm9sLmFzeW5jSXRlcmF0b3JdPy4oKSA/P1xuICAgICAgKGl0ZXJhYmxlIGFzIEl0ZXJhYmxlPFVpbnQ4QXJyYXk+KVtTeW1ib2wuaXRlcmF0b3JdPy4oKTtcbiAgY29uc3QgYnVmZmVyID0gbmV3IEJ1ZmZlcigpO1xuICByZXR1cm4ge1xuICAgIGFzeW5jIHJlYWQocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPT0gMCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIGlmIChyZXN1bHQuZG9uZSkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChyZXN1bHQudmFsdWUuYnl0ZUxlbmd0aCA8PSBwLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgIHAuc2V0KHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LnZhbHVlLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgfVxuICAgICAgICAgIHAuc2V0KHJlc3VsdC52YWx1ZS5zdWJhcnJheSgwLCBwLmJ5dGVMZW5ndGgpKTtcbiAgICAgICAgICBhd2FpdCB3cml0ZUFsbChidWZmZXIsIHJlc3VsdC52YWx1ZS5zdWJhcnJheShwLmJ5dGVMZW5ndGgpKTtcbiAgICAgICAgICByZXR1cm4gcC5ieXRlTGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuID0gYXdhaXQgYnVmZmVyLnJlYWQocCk7XG4gICAgICAgIGlmIChuID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWFkKHApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbi8qKiBDcmVhdGUgYSBgV3JpdGVyYCBmcm9tIGEgYFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcmAuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVyRnJvbVN0cmVhbVdyaXRlcihcbiAgc3RyZWFtV3JpdGVyOiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXI8VWludDhBcnJheT4sXG4pOiBEZW5vLldyaXRlciB7XG4gIHJldHVybiB7XG4gICAgYXN5bmMgd3JpdGUocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICBhd2FpdCBzdHJlYW1Xcml0ZXIucmVhZHk7XG4gICAgICBhd2FpdCBzdHJlYW1Xcml0ZXIud3JpdGUocCk7XG4gICAgICByZXR1cm4gcC5sZW5ndGg7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIENyZWF0ZSBhIGBSZWFkZXJgIGZyb20gYSBgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkZXJGcm9tU3RyZWFtUmVhZGVyKFxuICBzdHJlYW1SZWFkZXI6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjxVaW50OEFycmF5Pixcbik6IERlbm8uUmVhZGVyIHtcbiAgY29uc3QgYnVmZmVyID0gbmV3IEJ1ZmZlcigpO1xuXG4gIHJldHVybiB7XG4gICAgYXN5bmMgcmVhZChwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gICAgICBpZiAoYnVmZmVyLmVtcHR5KCkpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgc3RyZWFtUmVhZGVyLnJlYWQoKTtcbiAgICAgICAgaWYgKHJlcy5kb25lKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7IC8vIEVPRlxuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgd3JpdGVBbGwoYnVmZmVyLCByZXMudmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmZmVyLnJlYWQocCk7XG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXcml0YWJsZVN0cmVhbUZyb21Xcml0ZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIElmIHRoZSBgd3JpdGVyYCBpcyBhbHNvIGEgYERlbm8uQ2xvc2VyYCwgYXV0b21hdGljYWxseSBjbG9zZSB0aGUgYHdyaXRlcmBcbiAgICogd2hlbiB0aGUgc3RyZWFtIGlzIGNsb3NlZCwgYWJvcnRlZCwgb3IgYSB3cml0ZSBlcnJvciBvY2N1cnMuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIGB0cnVlYC4gKi9cbiAgYXV0b0Nsb3NlPzogYm9vbGVhbjtcbn1cblxuLyoqIENyZWF0ZSBhIGBXcml0YWJsZVN0cmVhbWAgZnJvbSBhIGBXcml0ZXJgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRhYmxlU3RyZWFtRnJvbVdyaXRlcihcbiAgd3JpdGVyOiBEZW5vLldyaXRlcixcbiAgb3B0aW9uczogV3JpdGFibGVTdHJlYW1Gcm9tV3JpdGVyT3B0aW9ucyA9IHt9LFxuKTogV3JpdGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICBjb25zdCB7IGF1dG9DbG9zZSA9IHRydWUgfSA9IG9wdGlvbnM7XG5cbiAgcmV0dXJuIG5ldyBXcml0YWJsZVN0cmVhbSh7XG4gICAgYXN5bmMgd3JpdGUoY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdyaXRlQWxsKHdyaXRlciwgY2h1bmspO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKGUpO1xuICAgICAgICBpZiAoaXNDbG9zZXIod3JpdGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgICB3cml0ZXIuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgY2xvc2UoKSB7XG4gICAgICBpZiAoaXNDbG9zZXIod3JpdGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgd3JpdGVyLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBhYm9ydCgpIHtcbiAgICAgIGlmIChpc0Nsb3Nlcih3cml0ZXIpICYmIGF1dG9DbG9zZSkge1xuICAgICAgICB3cml0ZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIENyZWF0ZSBhIGBSZWFkYWJsZVN0cmVhbWAgZnJvbSBhbnkga2luZCBvZiBpdGVyYWJsZS5cbiAqXG4gKiBgYGB0c1xuICogICAgICBpbXBvcnQgeyByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZSB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcbiAqXG4gKiAgICAgIGNvbnN0IHIxID0gcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGUoW1wiZm9vLCBiYXIsIGJhelwiXSk7XG4gKiAgICAgIGNvbnN0IHIyID0gcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGUoYXN5bmMgZnVuY3Rpb24qICgpIHtcbiAqICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpKTtcbiAqICAgICAgICB5aWVsZCBcImZvb1wiO1xuICogICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKCgocikgPT4gc2V0VGltZW91dChyLCAxMDAwKSkpO1xuICogICAgICAgIHlpZWxkIFwiYmFyXCI7XG4gKiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEwMDApKSk7XG4gKiAgICAgICAgeWllbGQgXCJiYXpcIjtcbiAqICAgICAgfSgpKTtcbiAqIGBgYFxuICpcbiAqIElmIHRoZSBwcm9kdWNlZCBpdGVyYXRvciAoYGl0ZXJhYmxlW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSgpYCBvclxuICogYGl0ZXJhYmxlW1N5bWJvbC5pdGVyYXRvcl0oKWApIGlzIGEgZ2VuZXJhdG9yLCBvciBtb3JlIHNwZWNpZmljYWxseSBpcyBmb3VuZFxuICogdG8gaGF2ZSBhIGAudGhyb3coKWAgbWV0aG9kIG9uIGl0LCB0aGF0IHdpbGwgYmUgY2FsbGVkIHVwb25cbiAqIGByZWFkYWJsZVN0cmVhbS5jYW5jZWwoKWAuIFRoaXMgaXMgdGhlIGNhc2UgZm9yIHRoZSBzZWNvbmQgaW5wdXQgdHlwZSBhYm92ZTpcbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGUgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogY29uc3QgcjMgPSByZWFkYWJsZVN0cmVhbUZyb21JdGVyYWJsZShhc3luYyBmdW5jdGlvbiogKCkge1xuICogICB0cnkge1xuICogICAgIHlpZWxkIFwiZm9vXCI7XG4gKiAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyb3IpOyAvLyBFcnJvcjogQ2FuY2VsbGVkIGJ5IGNvbnN1bWVyLlxuICogICB9XG4gKiB9KCkpO1xuICogY29uc3QgcmVhZGVyID0gcjMuZ2V0UmVhZGVyKCk7XG4gKiBjb25zb2xlLmxvZyhhd2FpdCByZWFkZXIucmVhZCgpKTsgLy8geyB2YWx1ZTogXCJmb29cIiwgZG9uZTogZmFsc2UgfVxuICogYXdhaXQgcmVhZGVyLmNhbmNlbChuZXcgRXJyb3IoXCJDYW5jZWxsZWQgYnkgY29uc3VtZXIuXCIpKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZGFibGVTdHJlYW1Gcm9tSXRlcmFibGU8VD4oXG4gIGl0ZXJhYmxlOiBJdGVyYWJsZTxUPiB8IEFzeW5jSXRlcmFibGU8VD4sXG4pOiBSZWFkYWJsZVN0cmVhbTxUPiB7XG4gIGNvbnN0IGl0ZXJhdG9yOiBJdGVyYXRvcjxUPiB8IEFzeW5jSXRlcmF0b3I8VD4gPVxuICAgIChpdGVyYWJsZSBhcyBBc3luY0l0ZXJhYmxlPFQ+KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0/LigpID8/XG4gICAgICAoaXRlcmFibGUgYXMgSXRlcmFibGU8VD4pW1N5bWJvbC5pdGVyYXRvcl0/LigpO1xuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtKHtcbiAgICBhc3luYyBwdWxsKGNvbnRyb2xsZXIpIHtcbiAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgIGlmIChkb25lKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBhc3luYyBjYW5jZWwocmVhc29uKSB7XG4gICAgICBpZiAodHlwZW9mIGl0ZXJhdG9yLnRocm93ID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGl0ZXJhdG9yLnRocm93KHJlYXNvbik7XG4gICAgICAgIH0gY2F0Y2ggeyAvKiBgaXRlcmF0b3IudGhyb3coKWAgYWx3YXlzIHRocm93cyBvbiBzaXRlLiBXZSBjYXRjaCBpdC4gKi8gfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlck9wdGlvbnMge1xuICAvKiogSWYgdGhlIGByZWFkZXJgIGlzIGFsc28gYSBgRGVuby5DbG9zZXJgLCBhdXRvbWF0aWNhbGx5IGNsb3NlIHRoZSBgcmVhZGVyYFxuICAgKiB3aGVuIGBFT0ZgIGlzIGVuY291bnRlcmVkLCBvciBhIHJlYWQgZXJyb3Igb2NjdXJzLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBgdHJ1ZWAuICovXG4gIGF1dG9DbG9zZT86IGJvb2xlYW47XG5cbiAgLyoqIFRoZSBzaXplIG9mIGNodW5rcyB0byBhbGxvY2F0ZSB0byByZWFkLCB0aGUgZGVmYXVsdCBpcyB+MTZLaUIsIHdoaWNoIGlzXG4gICAqIHRoZSBtYXhpbXVtIHNpemUgdGhhdCBEZW5vIG9wZXJhdGlvbnMgY2FuIGN1cnJlbnRseSBzdXBwb3J0LiAqL1xuICBjaHVua1NpemU/OiBudW1iZXI7XG5cbiAgLyoqIFRoZSBxdWV1aW5nIHN0cmF0ZWd5IHRvIGNyZWF0ZSB0aGUgYFJlYWRhYmxlU3RyZWFtYCB3aXRoLiAqL1xuICBzdHJhdGVneT86IHsgaGlnaFdhdGVyTWFyaz86IG51bWJlciB8IHVuZGVmaW5lZDsgc2l6ZT86IHVuZGVmaW5lZCB9O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PmAgZnJvbSBmcm9tIGEgYERlbm8uUmVhZGVyYC5cbiAqXG4gKiBXaGVuIHRoZSBwdWxsIGFsZ29yaXRobSBpcyBjYWxsZWQgb24gdGhlIHN0cmVhbSwgYSBjaHVuayBmcm9tIHRoZSByZWFkZXJcbiAqIHdpbGwgYmUgcmVhZC4gIFdoZW4gYG51bGxgIGlzIHJldHVybmVkIGZyb20gdGhlIHJlYWRlciwgdGhlIHN0cmVhbSB3aWxsIGJlXG4gKiBjbG9zZWQgYWxvbmcgd2l0aCB0aGUgcmVhZGVyIChpZiBpdCBpcyBhbHNvIGEgYERlbm8uQ2xvc2VyYCkuXG4gKlxuICogQW4gZXhhbXBsZSBjb252ZXJ0aW5nIGEgYERlbm8uRnNGaWxlYCBpbnRvIGEgcmVhZGFibGUgc3RyZWFtOlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyByZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIgfSBmcm9tIFwiLi9tb2QudHNcIjtcbiAqXG4gKiBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKFwiLi9maWxlLnR4dFwiLCB7IHJlYWQ6IHRydWUgfSk7XG4gKiBjb25zdCBmaWxlU3RyZWFtID0gcmVhZGFibGVTdHJlYW1Gcm9tUmVhZGVyKGZpbGUpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkYWJsZVN0cmVhbUZyb21SZWFkZXIoXG4gIHJlYWRlcjogRGVuby5SZWFkZXIgfCAoRGVuby5SZWFkZXIgJiBEZW5vLkNsb3NlciksXG4gIG9wdGlvbnM6IFJlYWRhYmxlU3RyZWFtRnJvbVJlYWRlck9wdGlvbnMgPSB7fSxcbik6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3Qge1xuICAgIGF1dG9DbG9zZSA9IHRydWUsXG4gICAgY2h1bmtTaXplID0gREVGQVVMVF9DSFVOS19TSVpFLFxuICAgIHN0cmF0ZWd5LFxuICB9ID0gb3B0aW9ucztcblxuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtKHtcbiAgICBhc3luYyBwdWxsKGNvbnRyb2xsZXIpIHtcbiAgICAgIGNvbnN0IGNodW5rID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmtTaXplKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlYWQgPSBhd2FpdCByZWFkZXIucmVhZChjaHVuayk7XG4gICAgICAgIGlmIChyZWFkID09PSBudWxsKSB7XG4gICAgICAgICAgaWYgKGlzQ2xvc2VyKHJlYWRlcikgJiYgYXV0b0Nsb3NlKSB7XG4gICAgICAgICAgICByZWFkZXIuY2xvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmsuc3ViYXJyYXkoMCwgcmVhZCkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKGUpO1xuICAgICAgICBpZiAoaXNDbG9zZXIocmVhZGVyKSkge1xuICAgICAgICAgIHJlYWRlci5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBjYW5jZWwoKSB7XG4gICAgICBpZiAoaXNDbG9zZXIocmVhZGVyKSAmJiBhdXRvQ2xvc2UpIHtcbiAgICAgICAgcmVhZGVyLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSxcbiAgfSwgc3RyYXRlZ3kpO1xufVxuXG4vKiogUmVhZCBSZWFkZXIgYHJgIHVudGlsIEVPRiAoYG51bGxgKSBhbmQgcmVzb2x2ZSB0byB0aGUgY29udGVudCBhc1xuICogVWludDhBcnJheWAuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCIuLi9pby9idWZmZXIudHNcIjtcbiAqIGltcG9ydCB7IHJlYWRBbGwgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIHN0ZGluXG4gKiBjb25zdCBzdGRpbkNvbnRlbnQgPSBhd2FpdCByZWFkQWxsKERlbm8uc3RkaW4pO1xuICpcbiAqIC8vIEV4YW1wbGUgZnJvbSBmaWxlXG4gKiBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKFwibXlfZmlsZS50eHRcIiwge3JlYWQ6IHRydWV9KTtcbiAqIGNvbnN0IG15RmlsZUNvbnRlbnQgPSBhd2FpdCByZWFkQWxsKGZpbGUpO1xuICogRGVuby5jbG9zZShmaWxlLnJpZCk7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGJ1ZmZlclxuICogY29uc3QgbXlEYXRhID0gbmV3IFVpbnQ4QXJyYXkoMTAwKTtcbiAqIC8vIC4uLiBmaWxsIG15RGF0YSBhcnJheSB3aXRoIGRhdGFcbiAqIGNvbnN0IHJlYWRlciA9IG5ldyBCdWZmZXIobXlEYXRhLmJ1ZmZlcik7XG4gKiBjb25zdCBidWZmZXJDb250ZW50ID0gYXdhaXQgcmVhZEFsbChyZWFkZXIpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkQWxsKHI6IERlbm8uUmVhZGVyKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGJ1ZiA9IG5ldyBCdWZmZXIoKTtcbiAgYXdhaXQgYnVmLnJlYWRGcm9tKHIpO1xuICByZXR1cm4gYnVmLmJ5dGVzKCk7XG59XG5cbi8qKiBTeW5jaHJvbm91c2x5IHJlYWRzIFJlYWRlciBgcmAgdW50aWwgRU9GIChgbnVsbGApIGFuZCByZXR1cm5zIHRoZSBjb250ZW50XG4gKiBhcyBgVWludDhBcnJheWAuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCIuLi9pby9idWZmZXIudHNcIjtcbiAqIGltcG9ydCB7IHJlYWRBbGxTeW5jIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIC8vIEV4YW1wbGUgZnJvbSBzdGRpblxuICogY29uc3Qgc3RkaW5Db250ZW50ID0gcmVhZEFsbFN5bmMoRGVuby5zdGRpbik7XG4gKlxuICogLy8gRXhhbXBsZSBmcm9tIGZpbGVcbiAqIGNvbnN0IGZpbGUgPSBEZW5vLm9wZW5TeW5jKFwibXlfZmlsZS50eHRcIiwge3JlYWQ6IHRydWV9KTtcbiAqIGNvbnN0IG15RmlsZUNvbnRlbnQgPSByZWFkQWxsU3luYyhmaWxlKTtcbiAqIERlbm8uY2xvc2UoZmlsZS5yaWQpO1xuICpcbiAqIC8vIEV4YW1wbGUgZnJvbSBidWZmZXJcbiAqIGNvbnN0IG15RGF0YSA9IG5ldyBVaW50OEFycmF5KDEwMCk7XG4gKiAvLyAuLi4gZmlsbCBteURhdGEgYXJyYXkgd2l0aCBkYXRhXG4gKiBjb25zdCByZWFkZXIgPSBuZXcgQnVmZmVyKG15RGF0YS5idWZmZXIpO1xuICogY29uc3QgYnVmZmVyQ29udGVudCA9IHJlYWRBbGxTeW5jKHJlYWRlcik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRBbGxTeW5jKHI6IERlbm8uUmVhZGVyU3luYyk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBidWYgPSBuZXcgQnVmZmVyKCk7XG4gIGJ1Zi5yZWFkRnJvbVN5bmMocik7XG4gIHJldHVybiBidWYuYnl0ZXMoKTtcbn1cblxuLyoqIFdyaXRlIGFsbCB0aGUgY29udGVudCBvZiB0aGUgYXJyYXkgYnVmZmVyIChgYXJyYCkgdG8gdGhlIHdyaXRlciAoYHdgKS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgd3JpdGVBbGwgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG5cbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBzdGRvdXRcbiAqIGxldCBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIGF3YWl0IHdyaXRlQWxsKERlbm8uc3Rkb3V0LCBjb250ZW50Qnl0ZXMpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBmaWxlXG4gKiBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIGNvbnN0IGZpbGUgPSBhd2FpdCBEZW5vLm9wZW4oJ3Rlc3QuZmlsZScsIHt3cml0ZTogdHJ1ZX0pO1xuICogYXdhaXQgd3JpdGVBbGwoZmlsZSwgY29udGVudEJ5dGVzKTtcbiAqIERlbm8uY2xvc2UoZmlsZS5yaWQpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBidWZmZXJcbiAqIGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogY29uc3Qgd3JpdGVyID0gbmV3IEJ1ZmZlcigpO1xuICogYXdhaXQgd3JpdGVBbGwod3JpdGVyLCBjb250ZW50Qnl0ZXMpO1xuICogY29uc29sZS5sb2cod3JpdGVyLmJ5dGVzKCkubGVuZ3RoKTsgIC8vIDExXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlQWxsKHc6IERlbm8uV3JpdGVyLCBhcnI6IFVpbnQ4QXJyYXkpIHtcbiAgbGV0IG53cml0dGVuID0gMDtcbiAgd2hpbGUgKG53cml0dGVuIDwgYXJyLmxlbmd0aCkge1xuICAgIG53cml0dGVuICs9IGF3YWl0IHcud3JpdGUoYXJyLnN1YmFycmF5KG53cml0dGVuKSk7XG4gIH1cbn1cblxuLyoqIFN5bmNocm9ub3VzbHkgd3JpdGUgYWxsIHRoZSBjb250ZW50IG9mIHRoZSBhcnJheSBidWZmZXIgKGBhcnJgKSB0byB0aGVcbiAqIHdyaXRlciAoYHdgKS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcIi4uL2lvL2J1ZmZlci50c1wiO1xuICogaW1wb3J0IHsgd3JpdGVBbGxTeW5jIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBzdGRvdXRcbiAqIGxldCBjb250ZW50Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJIZWxsbyBXb3JsZFwiKTtcbiAqIHdyaXRlQWxsU3luYyhEZW5vLnN0ZG91dCwgY29udGVudEJ5dGVzKTtcbiAqXG4gKiAvLyBFeGFtcGxlIHdyaXRpbmcgdG8gZmlsZVxuICogY29udGVudEJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFwiSGVsbG8gV29ybGRcIik7XG4gKiBjb25zdCBmaWxlID0gRGVuby5vcGVuU3luYygndGVzdC5maWxlJywge3dyaXRlOiB0cnVlfSk7XG4gKiB3cml0ZUFsbFN5bmMoZmlsZSwgY29udGVudEJ5dGVzKTtcbiAqIERlbm8uY2xvc2UoZmlsZS5yaWQpO1xuICpcbiAqIC8vIEV4YW1wbGUgd3JpdGluZyB0byBidWZmZXJcbiAqIGNvbnRlbnRCeXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkhlbGxvIFdvcmxkXCIpO1xuICogY29uc3Qgd3JpdGVyID0gbmV3IEJ1ZmZlcigpO1xuICogd3JpdGVBbGxTeW5jKHdyaXRlciwgY29udGVudEJ5dGVzKTtcbiAqIGNvbnNvbGUubG9nKHdyaXRlci5ieXRlcygpLmxlbmd0aCk7ICAvLyAxMVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZUFsbFN5bmModzogRGVuby5Xcml0ZXJTeW5jLCBhcnI6IFVpbnQ4QXJyYXkpOiB2b2lkIHtcbiAgbGV0IG53cml0dGVuID0gMDtcbiAgd2hpbGUgKG53cml0dGVuIDwgYXJyLmxlbmd0aCkge1xuICAgIG53cml0dGVuICs9IHcud3JpdGVTeW5jKGFyci5zdWJhcnJheShud3JpdHRlbikpO1xuICB9XG59XG5cbi8qKiBUdXJucyBhIFJlYWRlciwgYHJgLCBpbnRvIGFuIGFzeW5jIGl0ZXJhdG9yLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpdGVyYXRlUmVhZGVyIH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIGxldCBmID0gYXdhaXQgRGVuby5vcGVuKFwiL2V0Yy9wYXNzd2RcIik7XG4gKiBmb3IgYXdhaXQgKGNvbnN0IGNodW5rIG9mIGl0ZXJhdGVSZWFkZXIoZikpIHtcbiAqICAgY29uc29sZS5sb2coY2h1bmspO1xuICogfVxuICogZi5jbG9zZSgpO1xuICogYGBgXG4gKlxuICogU2Vjb25kIGFyZ3VtZW50IGNhbiBiZSB1c2VkIHRvIHR1bmUgc2l6ZSBvZiBhIGJ1ZmZlci5cbiAqIERlZmF1bHQgc2l6ZSBvZiB0aGUgYnVmZmVyIGlzIDMya0IuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGl0ZXJhdGVSZWFkZXIgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogbGV0IGYgPSBhd2FpdCBEZW5vLm9wZW4oXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGNvbnN0IGl0ID0gaXRlcmF0ZVJlYWRlcihmLCB7XG4gKiAgIGJ1ZlNpemU6IDEwMjQgKiAxMDI0XG4gKiB9KTtcbiAqIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgaXQpIHtcbiAqICAgY29uc29sZS5sb2coY2h1bmspO1xuICogfVxuICogZi5jbG9zZSgpO1xuICogYGBgXG4gKlxuICogSXRlcmF0b3IgdXNlcyBhbiBpbnRlcm5hbCBidWZmZXIgb2YgZml4ZWQgc2l6ZSBmb3IgZWZmaWNpZW5jeTsgaXQgcmV0dXJuc1xuICogYSB2aWV3IG9uIHRoYXQgYnVmZmVyIG9uIGVhY2ggaXRlcmF0aW9uLiBJdCBpcyB0aGVyZWZvcmUgY2FsbGVyJ3NcbiAqIHJlc3BvbnNpYmlsaXR5IHRvIGNvcHkgY29udGVudHMgb2YgdGhlIGJ1ZmZlciBpZiBuZWVkZWQ7IG90aGVyd2lzZSB0aGVcbiAqIG5leHQgaXRlcmF0aW9uIHdpbGwgb3ZlcndyaXRlIGNvbnRlbnRzIG9mIHByZXZpb3VzbHkgcmV0dXJuZWQgY2h1bmsuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogaXRlcmF0ZVJlYWRlcihcbiAgcjogRGVuby5SZWFkZXIsXG4gIG9wdGlvbnM/OiB7XG4gICAgYnVmU2l6ZT86IG51bWJlcjtcbiAgfSxcbik6IEFzeW5jSXRlcmFibGVJdGVyYXRvcjxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGJ1ZlNpemUgPSBvcHRpb25zPy5idWZTaXplID8/IERFRkFVTFRfQlVGRkVSX1NJWkU7XG4gIGNvbnN0IGIgPSBuZXcgVWludDhBcnJheShidWZTaXplKTtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByLnJlYWQoYik7XG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgeWllbGQgYi5zdWJhcnJheSgwLCByZXN1bHQpO1xuICB9XG59XG5cbi8qKiBUdXJucyBhIFJlYWRlclN5bmMsIGByYCwgaW50byBhbiBpdGVyYXRvci5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgaXRlcmF0ZVJlYWRlclN5bmMgfSBmcm9tIFwiLi9jb252ZXJzaW9uLnRzXCI7XG4gKlxuICogbGV0IGYgPSBEZW5vLm9wZW5TeW5jKFwiL2V0Yy9wYXNzd2RcIik7XG4gKiBmb3IgKGNvbnN0IGNodW5rIG9mIGl0ZXJhdGVSZWFkZXJTeW5jKGYpKSB7XG4gKiAgIGNvbnNvbGUubG9nKGNodW5rKTtcbiAqIH1cbiAqIGYuY2xvc2UoKTtcbiAqIGBgYFxuICpcbiAqIFNlY29uZCBhcmd1bWVudCBjYW4gYmUgdXNlZCB0byB0dW5lIHNpemUgb2YgYSBidWZmZXIuXG4gKiBEZWZhdWx0IHNpemUgb2YgdGhlIGJ1ZmZlciBpcyAzMmtCLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBpdGVyYXRlUmVhZGVyU3luYyB9IGZyb20gXCIuL2NvbnZlcnNpb24udHNcIjtcblxuICogbGV0IGYgPSBhd2FpdCBEZW5vLm9wZW4oXCIvZXRjL3Bhc3N3ZFwiKTtcbiAqIGNvbnN0IGl0ZXIgPSBpdGVyYXRlUmVhZGVyU3luYyhmLCB7XG4gKiAgIGJ1ZlNpemU6IDEwMjQgKiAxMDI0XG4gKiB9KTtcbiAqIGZvciAoY29uc3QgY2h1bmsgb2YgaXRlcikge1xuICogICBjb25zb2xlLmxvZyhjaHVuayk7XG4gKiB9XG4gKiBmLmNsb3NlKCk7XG4gKiBgYGBcbiAqXG4gKiBJdGVyYXRvciB1c2VzIGFuIGludGVybmFsIGJ1ZmZlciBvZiBmaXhlZCBzaXplIGZvciBlZmZpY2llbmN5OyBpdCByZXR1cm5zXG4gKiBhIHZpZXcgb24gdGhhdCBidWZmZXIgb24gZWFjaCBpdGVyYXRpb24uIEl0IGlzIHRoZXJlZm9yZSBjYWxsZXInc1xuICogcmVzcG9uc2liaWxpdHkgdG8gY29weSBjb250ZW50cyBvZiB0aGUgYnVmZmVyIGlmIG5lZWRlZDsgb3RoZXJ3aXNlIHRoZVxuICogbmV4dCBpdGVyYXRpb24gd2lsbCBvdmVyd3JpdGUgY29udGVudHMgb2YgcHJldmlvdXNseSByZXR1cm5lZCBjaHVuay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uKiBpdGVyYXRlUmVhZGVyU3luYyhcbiAgcjogRGVuby5SZWFkZXJTeW5jLFxuICBvcHRpb25zPzoge1xuICAgIGJ1ZlNpemU/OiBudW1iZXI7XG4gIH0sXG4pOiBJdGVyYWJsZUl0ZXJhdG9yPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgYnVmU2l6ZSA9IG9wdGlvbnM/LmJ1ZlNpemUgPz8gREVGQVVMVF9CVUZGRVJfU0laRTtcbiAgY29uc3QgYiA9IG5ldyBVaW50OEFycmF5KGJ1ZlNpemUpO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IHIucmVhZFN5bmMoYik7XG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgeWllbGQgYi5zdWJhcnJheSgwLCByZXN1bHQpO1xuICB9XG59XG5cbi8qKiBDb3BpZXMgZnJvbSBgc3JjYCB0byBgZHN0YCB1bnRpbCBlaXRoZXIgRU9GIChgbnVsbGApIGlzIHJlYWQgZnJvbSBgc3JjYCBvclxuICogYW4gZXJyb3Igb2NjdXJzLiBJdCByZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIGNvcGllZCBvciByZWplY3RzIHdpdGhcbiAqIHRoZSBmaXJzdCBlcnJvciBlbmNvdW50ZXJlZCB3aGlsZSBjb3B5aW5nLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBjb3B5IH0gZnJvbSBcIi4vY29udmVyc2lvbi50c1wiO1xuICpcbiAqIGNvbnN0IHNvdXJjZSA9IGF3YWl0IERlbm8ub3BlbihcIm15X2ZpbGUudHh0XCIpO1xuICogY29uc3QgYnl0ZXNDb3BpZWQxID0gYXdhaXQgY29weShzb3VyY2UsIERlbm8uc3Rkb3V0KTtcbiAqIGNvbnN0IGRlc3RpbmF0aW9uID0gYXdhaXQgRGVuby5jcmVhdGUoXCJteV9maWxlXzIudHh0XCIpO1xuICogY29uc3QgYnl0ZXNDb3BpZWQyID0gYXdhaXQgY29weShzb3VyY2UsIGRlc3RpbmF0aW9uKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBzcmMgVGhlIHNvdXJjZSB0byBjb3B5IGZyb21cbiAqIEBwYXJhbSBkc3QgVGhlIGRlc3RpbmF0aW9uIHRvIGNvcHkgdG9cbiAqIEBwYXJhbSBvcHRpb25zIENhbiBiZSB1c2VkIHRvIHR1bmUgc2l6ZSBvZiB0aGUgYnVmZmVyLiBEZWZhdWx0IHNpemUgaXMgMzJrQlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29weShcbiAgc3JjOiBEZW5vLlJlYWRlcixcbiAgZHN0OiBEZW5vLldyaXRlcixcbiAgb3B0aW9ucz86IHtcbiAgICBidWZTaXplPzogbnVtYmVyO1xuICB9LFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgbGV0IG4gPSAwO1xuICBjb25zdCBidWZTaXplID0gb3B0aW9ucz8uYnVmU2l6ZSA/PyBERUZBVUxUX0JVRkZFUl9TSVpFO1xuICBjb25zdCBiID0gbmV3IFVpbnQ4QXJyYXkoYnVmU2l6ZSk7XG4gIGxldCBnb3RFT0YgPSBmYWxzZTtcbiAgd2hpbGUgKGdvdEVPRiA9PT0gZmFsc2UpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzcmMucmVhZChiKTtcbiAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICBnb3RFT0YgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbndyaXR0ZW4gPSAwO1xuICAgICAgd2hpbGUgKG53cml0dGVuIDwgcmVzdWx0KSB7XG4gICAgICAgIG53cml0dGVuICs9IGF3YWl0IGRzdC53cml0ZShiLnN1YmFycmF5KG53cml0dGVuLCByZXN1bHQpKTtcbiAgICAgIH1cbiAgICAgIG4gKz0gbndyaXR0ZW47XG4gICAgfVxuICB9XG4gIHJldHVybiBuO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUUxRSxTQUFTLE1BQU0sUUFBUSxrQkFBa0I7QUFFekMsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSxzQkFBc0IsS0FBSztBQUVqQyxTQUFTLFNBQVMsS0FBYyxFQUF3QjtJQUN0RCxPQUFPLE9BQU8sVUFBVSxZQUFZLFNBQVMsSUFBSSxJQUFJLFdBQVcsU0FDOUQsbUNBQW1DO0lBQ25DLE9BQU8sQUFBQyxLQUE2QixDQUFDLFFBQVEsS0FBSztBQUN2RDtBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Q0FlQyxHQUNELE9BQU8sU0FBUyxtQkFDZCxRQUEwRCxFQUM3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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/ebsv4XtKEF8sxrDsnkLX8K9VdOA.js b/tests/__snapshots__/transpile/url/modules/ebsv4XtKEF8sxrDsnkLX8K9VdOA.js new file mode 100644 index 0000000..30e11f0 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/ebsv4XtKEF8sxrDsnkLX8K9VdOA.js @@ -0,0 +1,18 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +export const osType = (()=>{ + // deno-lint-ignore no-explicit-any + const { Deno } = globalThis; + if (typeof Deno?.build?.os === "string") { + return Deno.build.os; + } + // deno-lint-ignore no-explicit-any + const { navigator } = globalThis; + if (navigator?.appVersion?.includes?.("Win")) { + return "windows"; + } + return "linux"; +})(); +export const isWindows = osType === "windows"; +export const isLinux = osType === "linux"; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL29zLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDE4LTIwMjIgdGhlIERlbm8gYXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gTUlUIGxpY2Vuc2UuXG4vLyBUaGlzIG1vZHVsZSBpcyBicm93c2VyIGNvbXBhdGlibGUuXG5cbmV4cG9ydCB0eXBlIE9TVHlwZSA9IFwid2luZG93c1wiIHwgXCJsaW51eFwiIHwgXCJkYXJ3aW5cIjtcblxuZXhwb3J0IGNvbnN0IG9zVHlwZTogT1NUeXBlID0gKCgpID0+IHtcbiAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgY29uc3QgeyBEZW5vIH0gPSBnbG9iYWxUaGlzIGFzIGFueTtcbiAgaWYgKHR5cGVvZiBEZW5vPy5idWlsZD8ub3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gRGVuby5idWlsZC5vcztcbiAgfVxuXG4gIC8vIGRlbm8tbGludC1pZ25vcmUgbm8tZXhwbGljaXQtYW55XG4gIGNvbnN0IHsgbmF2aWdhdG9yIH0gPSBnbG9iYWxUaGlzIGFzIGFueTtcbiAgaWYgKG5hdmlnYXRvcj8uYXBwVmVyc2lvbj8uaW5jbHVkZXM/LihcIldpblwiKSkge1xuICAgIHJldHVybiBcIndpbmRvd3NcIjtcbiAgfVxuXG4gIHJldHVybiBcImxpbnV4XCI7XG59KSgpO1xuXG5leHBvcnQgY29uc3QgaXNXaW5kb3dzID0gb3NUeXBlID09PSBcIndpbmRvd3NcIjtcbmV4cG9ydCBjb25zdCBpc0xpbnV4ID0gb3NUeXBlID09PSBcImxpbnV4XCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEVBQTBFO0FBQzFFLHFDQUFxQztBQUlyQyxPQUFPLE1BQU0sU0FBaUIsQUFBQyxDQUFBLElBQU07SUFDbkMsbUNBQW1DO0lBQ25DLE1BQU0sRUFBRSxLQUFJLEVBQUUsR0FBRztJQUNqQixJQUFJLE9BQU8sTUFBTSxPQUFPLE9BQU8sVUFBVTtRQUN2QyxPQUFPLEtBQUssS0FBSyxDQUFDLEVBQUU7SUFDdEIsQ0FBQztJQUVELG1DQUFtQztJQUNuQyxNQUFNLEVBQUUsVUFBUyxFQUFFLEdBQUc7SUFDdEIsSUFBSSxXQUFXLFlBQVksV0FBVyxRQUFRO1FBQzVDLE9BQU87SUFDVCxDQUFDO0lBRUQsT0FBTztBQUNULENBQUEsSUFBSztBQUVMLE9BQU8sTUFBTSxZQUFZLFdBQVcsVUFBVTtBQUM5QyxPQUFPLE1BQU0sVUFBVSxXQUFXLFFBQVEifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/jO4Cj24EIKVTiTvdPctAVhckzgg.js b/tests/__snapshots__/transpile/url/modules/jO4Cj24EIKVTiTvdPctAVhckzgg.js new file mode 100644 index 0000000..121d0d0 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/jO4Cj24EIKVTiTvdPctAVhckzgg.js @@ -0,0 +1,39 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** Check whether binary arrays are equal to each other using 8-bit comparisons. + * @private + * @param a first array to check equality + * @param b second array to check equality + */ export function equalsNaive(a, b) { + if (a.length !== b.length) return false; + for(let i = 0; i < b.length; i++){ + if (a[i] !== b[i]) return false; + } + return true; +} +/** Check whether binary arrays are equal to each other using 32-bit comparisons. + * @private + * @param a first array to check equality + * @param b second array to check equality + */ export function equalsSimd(a, b) { + if (a.length !== b.length) return false; + const len = a.length; + const compressable = Math.floor(len / 4); + const compressedA = new Uint32Array(a.buffer, 0, compressable); + const compressedB = new Uint32Array(b.buffer, 0, compressable); + for(let i = compressable * 4; i < len; i++){ + if (a[i] !== b[i]) return false; + } + for(let i = 0; i < compressedA.length; i++){ + if (compressedA[i] !== compressedB[i]) return false; + } + return true; +} +/** Check whether binary arrays are equal to each other. + * @param a first array to check equality + * @param b second array to check equality + */ export function equals(a, b) { + if (a.length < 1000) return equalsNaive(a, b); + return equalsSimd(a, b); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2J5dGVzL2VxdWFscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vKiogQ2hlY2sgd2hldGhlciBiaW5hcnkgYXJyYXlzIGFyZSBlcXVhbCB0byBlYWNoIG90aGVyIHVzaW5nIDgtYml0IGNvbXBhcmlzb25zLlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBhIGZpcnN0IGFycmF5IHRvIGNoZWNrIGVxdWFsaXR5XG4gKiBAcGFyYW0gYiBzZWNvbmQgYXJyYXkgdG8gY2hlY2sgZXF1YWxpdHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVxdWFsc05haXZlKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogQ2hlY2sgd2hldGhlciBiaW5hcnkgYXJyYXlzIGFyZSBlcXVhbCB0byBlYWNoIG90aGVyIHVzaW5nIDMyLWJpdCBjb21wYXJpc29ucy5cbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gYSBmaXJzdCBhcnJheSB0byBjaGVjayBlcXVhbGl0eVxuICogQHBhcmFtIGIgc2Vjb25kIGFycmF5IHRvIGNoZWNrIGVxdWFsaXR5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbHNTaW1kKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBsZW4gPSBhLmxlbmd0aDtcbiAgY29uc3QgY29tcHJlc3NhYmxlID0gTWF0aC5mbG9vcihsZW4gLyA0KTtcbiAgY29uc3QgY29tcHJlc3NlZEEgPSBuZXcgVWludDMyQXJyYXkoYS5idWZmZXIsIDAsIGNvbXByZXNzYWJsZSk7XG4gIGNvbnN0IGNvbXByZXNzZWRCID0gbmV3IFVpbnQzMkFycmF5KGIuYnVmZmVyLCAwLCBjb21wcmVzc2FibGUpO1xuICBmb3IgKGxldCBpID0gY29tcHJlc3NhYmxlICogNDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbXByZXNzZWRBLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGNvbXByZXNzZWRBW2ldICE9PSBjb21wcmVzc2VkQltpXSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogQ2hlY2sgd2hldGhlciBiaW5hcnkgYXJyYXlzIGFyZSBlcXVhbCB0byBlYWNoIG90aGVyLlxuICogQHBhcmFtIGEgZmlyc3QgYXJyYXkgdG8gY2hlY2sgZXF1YWxpdHlcbiAqIEBwYXJhbSBiIHNlY29uZCBhcnJheSB0byBjaGVjayBlcXVhbGl0eVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoIDwgMTAwMCkgcmV0dXJuIGVxdWFsc05haXZlKGEsIGIpO1xuICByZXR1cm4gZXF1YWxzU2ltZChhLCBiKTtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDOzs7O0NBSUMsR0FDRCxPQUFPLFNBQVMsWUFBWSxDQUFhLEVBQUUsQ0FBYSxFQUFXO0lBQ2pFLElBQUksRUFBRSxNQUFNLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxLQUFLO0lBQ3ZDLElBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFLO1FBQ2pDLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sS0FBSztJQUNqQztJQUNBLE9BQU8sSUFBSTtBQUNiLENBQUM7QUFFRDs7OztDQUlDLEdBQ0QsT0FBTyxTQUFTLFdBQVcsQ0FBYSxFQUFFLENBQWEsRUFBVztJQUNoRSxJQUFJLEVBQUUsTUFBTSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sS0FBSztJQUN2QyxNQUFNLE1BQU0sRUFBRSxNQUFNO0lBQ3BCLE1BQU0sZUFBZSxLQUFLLEtBQUssQ0FBQyxNQUFNO0lBQ3RDLE1BQU0sY0FBYyxJQUFJLFlBQVksRUFBRSxNQUFNLEVBQUUsR0FBRztJQUNqRCxNQUFNLGNBQWMsSUFBSSxZQUFZLEVBQUUsTUFBTSxFQUFFLEdBQUc7SUFDakQsSUFBSyxJQUFJLElBQUksZUFBZSxHQUFHLElBQUksS0FBSyxJQUFLO1FBQzNDLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sS0FBSztJQUNqQztJQUNBLElBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxZQUFZLE1BQU0sRUFBRSxJQUFLO1FBQzNDLElBQUksV0FBVyxDQUFDLEVBQUUsS0FBSyxXQUFXLENBQUMsRUFBRSxFQUFFLE9BQU8sS0FBSztJQUNyRDtJQUNBLE9BQU8sSUFBSTtBQUNiLENBQUM7QUFFRDs7O0NBR0MsR0FDRCxPQUFPLFNBQVMsT0FBTyxDQUFhLEVBQUUsQ0FBYSxFQUFXO0lBQzVELElBQUksRUFBRSxNQUFNLEdBQUcsTUFBTSxPQUFPLFlBQVksR0FBRztJQUMzQyxPQUFPLFdBQVcsR0FBRztBQUN2QixDQUFDIn0= \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/kWDlQkpYLFWxtJdAejga3vZCeeM.js b/tests/__snapshots__/transpile/url/modules/kWDlQkpYLFWxtJdAejga3vZCeeM.js new file mode 100644 index 0000000..c838ff9 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/kWDlQkpYLFWxtJdAejga3vZCeeM.js @@ -0,0 +1,433 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// Copyright the Browserify authors. MIT License. +// Ported from https://github.com/browserify/path-browserify/ +// This module is browser compatible. +import { CHAR_DOT, CHAR_FORWARD_SLASH } from "./_constants.ts"; +import { _format, assertPath, encodeWhitespace, isPosixPathSeparator, normalizeString } from "./_util.ts"; +export const sep = "/"; +export const delimiter = ":"; +// path.resolve([from ...], to) +/** + * Resolves `pathSegments` into an absolute path. + * @param pathSegments an array of path segments + */ export function resolve(...pathSegments) { + let resolvedPath = ""; + let resolvedAbsolute = false; + for(let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--){ + let path; + if (i >= 0) path = pathSegments[i]; + else { + // deno-lint-ignore no-explicit-any + const { Deno } = globalThis; + if (typeof Deno?.cwd !== "function") { + throw new TypeError("Resolved a relative path without a CWD."); + } + path = Deno.cwd(); + } + assertPath(path); + // Skip empty entries + if (path.length === 0) { + continue; + } + resolvedPath = `${path}/${resolvedPath}`; + resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + } + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + // Normalize the path + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator); + if (resolvedAbsolute) { + if (resolvedPath.length > 0) return `/${resolvedPath}`; + else return "/"; + } else if (resolvedPath.length > 0) return resolvedPath; + else return "."; +} +/** + * Normalize the `path`, resolving `'..'` and `'.'` segments. + * @param path to be normalized + */ export function normalize(path) { + assertPath(path); + if (path.length === 0) return "."; + const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + const trailingSeparator = path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH; + // Normalize the path + path = normalizeString(path, !isAbsolute, "/", isPosixPathSeparator); + if (path.length === 0 && !isAbsolute) path = "."; + if (path.length > 0 && trailingSeparator) path += "/"; + if (isAbsolute) return `/${path}`; + return path; +} +/** + * Verifies whether provided path is absolute + * @param path to be verified as absolute + */ export function isAbsolute(path) { + assertPath(path); + return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH; +} +/** + * Join all given a sequence of `paths`,then normalizes the resulting path. + * @param paths to be joined and normalized + */ export function join(...paths) { + if (paths.length === 0) return "."; + let joined; + for(let i = 0, len = paths.length; i < len; ++i){ + const path = paths[i]; + assertPath(path); + if (path.length > 0) { + if (!joined) joined = path; + else joined += `/${path}`; + } + } + if (!joined) return "."; + return normalize(joined); +} +/** + * Return the relative path from `from` to `to` based on current working directory. + * @param from path in current working directory + * @param to path in current working directory + */ export function relative(from, to) { + assertPath(from); + assertPath(to); + if (from === to) return ""; + from = resolve(from); + to = resolve(to); + if (from === to) return ""; + // Trim any leading backslashes + let fromStart = 1; + const fromEnd = from.length; + for(; fromStart < fromEnd; ++fromStart){ + if (from.charCodeAt(fromStart) !== CHAR_FORWARD_SLASH) break; + } + const fromLen = fromEnd - fromStart; + // Trim any leading backslashes + let toStart = 1; + const toEnd = to.length; + for(; toStart < toEnd; ++toStart){ + if (to.charCodeAt(toStart) !== CHAR_FORWARD_SLASH) break; + } + const toLen = toEnd - toStart; + // Compare paths to find the longest common path from root + const length = fromLen < toLen ? fromLen : toLen; + let lastCommonSep = -1; + let i = 0; + for(; i <= length; ++i){ + if (i === length) { + if (toLen > length) { + if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) { + // We get here if `from` is the exact base path for `to`. + // For example: from='/foo/bar'; to='/foo/bar/baz' + return to.slice(toStart + i + 1); + } else if (i === 0) { + // We get here if `from` is the root + // For example: from='/'; to='/foo' + return to.slice(toStart + i); + } + } else if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) { + // We get here if `to` is the exact base path for `from`. + // For example: from='/foo/bar/baz'; to='/foo/bar' + lastCommonSep = i; + } else if (i === 0) { + // We get here if `to` is the root. + // For example: from='/foo'; to='/' + lastCommonSep = 0; + } + } + break; + } + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); + if (fromCode !== toCode) break; + else if (fromCode === CHAR_FORWARD_SLASH) lastCommonSep = i; + } + let out = ""; + // Generate the relative path based on the path difference between `to` + // and `from` + for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){ + if (i === fromEnd || from.charCodeAt(i) === CHAR_FORWARD_SLASH) { + if (out.length === 0) out += ".."; + else out += "/.."; + } + } + // Lastly, append the rest of the destination (`to`) path that comes after + // the common path parts + if (out.length > 0) return out + to.slice(toStart + lastCommonSep); + else { + toStart += lastCommonSep; + if (to.charCodeAt(toStart) === CHAR_FORWARD_SLASH) ++toStart; + return to.slice(toStart); + } +} +/** + * Resolves path to a namespace path + * @param path to resolve to namespace + */ export function toNamespacedPath(path) { + // Non-op on posix systems + return path; +} +/** + * Return the directory name of a `path`. + * @param path to determine name for + */ export function dirname(path) { + assertPath(path); + if (path.length === 0) return "."; + const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + let end = -1; + let matchedSlash = true; + for(let i = path.length - 1; i >= 1; --i){ + if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { + if (!matchedSlash) { + end = i; + break; + } + } else { + // We saw the first non-path separator + matchedSlash = false; + } + } + if (end === -1) return hasRoot ? "/" : "."; + if (hasRoot && end === 1) return "//"; + return path.slice(0, end); +} +/** + * Return the last portion of a `path`. Trailing directory separators are ignored. + * @param path to process + * @param ext of path directory + */ export function basename(path, ext = "") { + if (ext !== undefined && typeof ext !== "string") { + throw new TypeError('"ext" argument must be a string'); + } + assertPath(path); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { + if (ext.length === path.length && ext === path) return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for(i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + // We saw the first non-path separator, remember this index in case + // we need it if the extension ends up not matching + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + // Try to match the explicit extension + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + // We matched the extension, so mark this as the end of our path + // component + end = i; + } + } else { + // Extension does not match, so our result is the entire path + // component + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; + return path.slice(start, end); + } else { + for(i = path.length - 1; i >= 0; --i){ + if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // path component + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) return ""; + return path.slice(start, end); + } +} +/** + * Return the extension of the `path` with leading period. + * @param path with extension + * @returns extension (ex. for `file.ts` returns `.ts`) + */ export function extname(path) { + assertPath(path); + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + for(let i = path.length - 1; i >= 0; --i){ + const code = path.charCodeAt(i); + if (code === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path.slice(startDot, end); +} +/** + * Generate a path from `FormatInputPathObject` object. + * @param pathObject with path + */ export function format(pathObject) { + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`); + } + return _format("/", pathObject); +} +/** + * Return a `ParsedPath` object of the `path`. + * @param path to process + */ export function parse(path) { + assertPath(path); + const ret = { + root: "", + dir: "", + base: "", + ext: "", + name: "" + }; + if (path.length === 0) return ret; + const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + let start; + if (isAbsolute) { + ret.root = "/"; + start = 1; + } else { + start = 0; + } + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; + // Track the state of characters (if any) we see before our first dot and + // after any path separator we find + let preDotState = 0; + // Get non-dir info + for(; i >= start; --i){ + const code = path.charCodeAt(i); + if (code === CHAR_FORWARD_SLASH) { + // If we reached a path separator that was not part of a set of path + // separators at the end of the string, stop now + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + // We saw the first non-path separator, mark this as the end of our + // extension + matchedSlash = false; + end = i + 1; + } + if (code === CHAR_DOT) { + // If this is our first dot, mark it as the start of our extension + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; + } else if (startDot !== -1) { + // We saw a non-dot and non-path separator before our dot, so we should + // have a good chance at having a non-empty extension + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot + preDotState === 0 || // The (right-most) trimmed path component is exactly '..' + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + if (startPart === 0 && isAbsolute) { + ret.base = ret.name = path.slice(1, end); + } else { + ret.base = ret.name = path.slice(startPart, end); + } + } + } else { + if (startPart === 0 && isAbsolute) { + ret.name = path.slice(1, startDot); + ret.base = path.slice(1, end); + } else { + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); + } + ret.ext = path.slice(startDot, end); + } + if (startPart > 0) ret.dir = path.slice(0, startPart - 1); + else if (isAbsolute) ret.dir = "/"; + return ret; +} +/** + * Converts a file URL to a path string. + * + * ```ts + * import { fromFileUrl } from "./posix.ts"; + * fromFileUrl("file:///home/foo"); // "/home/foo" + * ``` + * @param url of a file URL + */ export function fromFileUrl(url) { + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25")); +} +/** + * Converts a path string to a file URL. + * + * ```ts + * import { toFileUrl } from "./posix.ts"; + * toFileUrl("/home/foo"); // new URL("file:///home/foo") + * ``` + * @param path to convert to file URL + */ export function toFileUrl(path) { + if (!isAbsolute(path)) { + throw new TypeError("Must be an absolute path."); + } + const url = new URL("file:///"); + url.pathname = encodeWhitespace(path.replace(/%/g, "%25").replace(/\\/g, "%5C")); + return url; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvcG9zaXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCB0aGUgQnJvd3NlcmlmeSBhdXRob3JzLiBNSVQgTGljZW5zZS5cbi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm93c2VyaWZ5L3BhdGgtYnJvd3NlcmlmeS9cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuaW1wb3J0IHR5cGUgeyBGb3JtYXRJbnB1dFBhdGhPYmplY3QsIFBhcnNlZFBhdGggfSBmcm9tIFwiLi9faW50ZXJmYWNlLnRzXCI7XG5pbXBvcnQgeyBDSEFSX0RPVCwgQ0hBUl9GT1JXQVJEX1NMQVNIIH0gZnJvbSBcIi4vX2NvbnN0YW50cy50c1wiO1xuXG5pbXBvcnQge1xuICBfZm9ybWF0LFxuICBhc3NlcnRQYXRoLFxuICBlbmNvZGVXaGl0ZXNwYWNlLFxuICBpc1Bvc2l4UGF0aFNlcGFyYXRvcixcbiAgbm9ybWFsaXplU3RyaW5nLFxufSBmcm9tIFwiLi9fdXRpbC50c1wiO1xuXG5leHBvcnQgY29uc3Qgc2VwID0gXCIvXCI7XG5leHBvcnQgY29uc3QgZGVsaW1pdGVyID0gXCI6XCI7XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8qKlxuICogUmVzb2x2ZXMgYHBhdGhTZWdtZW50c2AgaW50byBhbiBhYnNvbHV0ZSBwYXRoLlxuICogQHBhcmFtIHBhdGhTZWdtZW50cyBhbiBhcnJheSBvZiBwYXRoIHNlZ21lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlKC4uLnBhdGhTZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICBsZXQgcmVzb2x2ZWRQYXRoID0gXCJcIjtcbiAgbGV0IHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTEgJiYgIXJlc29sdmVkQWJzb2x1dGU7IGktLSkge1xuICAgIGxldCBwYXRoOiBzdHJpbmc7XG5cbiAgICBpZiAoaSA+PSAwKSBwYXRoID0gcGF0aFNlZ21lbnRzW2ldO1xuICAgIGVsc2Uge1xuICAgICAgLy8gZGVuby1saW50LWlnbm9yZSBuby1leHBsaWNpdC1hbnlcbiAgICAgIGNvbnN0IHsgRGVubyB9ID0gZ2xvYmFsVGhpcyBhcyBhbnk7XG4gICAgICBpZiAodHlwZW9mIERlbm8/LmN3ZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJSZXNvbHZlZCBhIHJlbGF0aXZlIHBhdGggd2l0aG91dCBhIENXRC5cIik7XG4gICAgICB9XG4gICAgICBwYXRoID0gRGVuby5jd2QoKTtcbiAgICB9XG5cbiAgICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBlbnRyaWVzXG4gICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXNvbHZlZFBhdGggPSBgJHtwYXRofS8ke3Jlc29sdmVkUGF0aH1gO1xuICAgIHJlc29sdmVkQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZVN0cmluZyhcbiAgICByZXNvbHZlZFBhdGgsXG4gICAgIXJlc29sdmVkQWJzb2x1dGUsXG4gICAgXCIvXCIsXG4gICAgaXNQb3NpeFBhdGhTZXBhcmF0b3IsXG4gICk7XG5cbiAgaWYgKHJlc29sdmVkQWJzb2x1dGUpIHtcbiAgICBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiBgLyR7cmVzb2x2ZWRQYXRofWA7XG4gICAgZWxzZSByZXR1cm4gXCIvXCI7XG4gIH0gZWxzZSBpZiAocmVzb2x2ZWRQYXRoLmxlbmd0aCA+IDApIHJldHVybiByZXNvbHZlZFBhdGg7XG4gIGVsc2UgcmV0dXJuIFwiLlwiO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSB0aGUgYHBhdGhgLCByZXNvbHZpbmcgYCcuLidgIGFuZCBgJy4nYCBzZWdtZW50cy5cbiAqIEBwYXJhbSBwYXRoIHRvIGJlIG5vcm1hbGl6ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuXG4gIGNvbnN0IGlzQWJzb2x1dGUgPSBwYXRoLmNoYXJDb2RlQXQoMCkgPT09IENIQVJfRk9SV0FSRF9TTEFTSDtcbiAgY29uc3QgdHJhaWxpbmdTZXBhcmF0b3IgPVxuICAgIHBhdGguY2hhckNvZGVBdChwYXRoLmxlbmd0aCAtIDEpID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHBhdGggPSBub3JtYWxpemVTdHJpbmcocGF0aCwgIWlzQWJzb2x1dGUsIFwiL1wiLCBpc1Bvc2l4UGF0aFNlcGFyYXRvcik7XG5cbiAgaWYgKHBhdGgubGVuZ3RoID09PSAwICYmICFpc0Fic29sdXRlKSBwYXRoID0gXCIuXCI7XG4gIGlmIChwYXRoLmxlbmd0aCA+IDAgJiYgdHJhaWxpbmdTZXBhcmF0b3IpIHBhdGggKz0gXCIvXCI7XG5cbiAgaWYgKGlzQWJzb2x1dGUpIHJldHVybiBgLyR7cGF0aH1gO1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBWZXJpZmllcyB3aGV0aGVyIHByb3ZpZGVkIHBhdGggaXMgYWJzb2x1dGVcbiAqIEBwYXJhbSBwYXRoIHRvIGJlIHZlcmlmaWVkIGFzIGFic29sdXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Fic29sdXRlKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBhc3NlcnRQYXRoKHBhdGgpO1xuICByZXR1cm4gcGF0aC5sZW5ndGggPiAwICYmIHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xufVxuXG4vKipcbiAqIEpvaW4gYWxsIGdpdmVuIGEgc2VxdWVuY2Ugb2YgYHBhdGhzYCx0aGVuIG5vcm1hbGl6ZXMgdGhlIHJlc3VsdGluZyBwYXRoLlxuICogQHBhcmFtIHBhdGhzIHRvIGJlIGpvaW5lZCBhbmQgbm9ybWFsaXplZFxuICovXG5leHBvcnQgZnVuY3Rpb24gam9pbiguLi5wYXRoczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAocGF0aHMubGVuZ3RoID09PSAwKSByZXR1cm4gXCIuXCI7XG4gIGxldCBqb2luZWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBhdGhzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgIGFzc2VydFBhdGgocGF0aCk7XG4gICAgaWYgKHBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFqb2luZWQpIGpvaW5lZCA9IHBhdGg7XG4gICAgICBlbHNlIGpvaW5lZCArPSBgLyR7cGF0aH1gO1xuICAgIH1cbiAgfVxuICBpZiAoIWpvaW5lZCkgcmV0dXJuIFwiLlwiO1xuICByZXR1cm4gbm9ybWFsaXplKGpvaW5lZCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSByZWxhdGl2ZSBwYXRoIGZyb20gYGZyb21gIHRvIGB0b2AgYmFzZWQgb24gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSBmcm9tIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICogQHBhcmFtIHRvIHBhdGggaW4gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpdmUoZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0UGF0aChmcm9tKTtcbiAgYXNzZXJ0UGF0aCh0byk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSByZXR1cm4gXCJcIjtcblxuICBmcm9tID0gcmVzb2x2ZShmcm9tKTtcbiAgdG8gPSByZXNvbHZlKHRvKTtcblxuICBpZiAoZnJvbSA9PT0gdG8pIHJldHVybiBcIlwiO1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IGZyb21TdGFydCA9IDE7XG4gIGNvbnN0IGZyb21FbmQgPSBmcm9tLmxlbmd0aDtcbiAgZm9yICg7IGZyb21TdGFydCA8IGZyb21FbmQ7ICsrZnJvbVN0YXJ0KSB7XG4gICAgaWYgKGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQpICE9PSBDSEFSX0ZPUldBUkRfU0xBU0gpIGJyZWFrO1xuICB9XG4gIGNvbnN0IGZyb21MZW4gPSBmcm9tRW5kIC0gZnJvbVN0YXJ0O1xuXG4gIC8vIFRyaW0gYW55IGxlYWRpbmcgYmFja3NsYXNoZXNcbiAgbGV0IHRvU3RhcnQgPSAxO1xuICBjb25zdCB0b0VuZCA9IHRvLmxlbmd0aDtcbiAgZm9yICg7IHRvU3RhcnQgPCB0b0VuZDsgKyt0b1N0YXJ0KSB7XG4gICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCkgIT09IENIQVJfRk9SV0FSRF9TTEFTSCkgYnJlYWs7XG4gIH1cbiAgY29uc3QgdG9MZW4gPSB0b0VuZCAtIHRvU3RhcnQ7XG5cbiAgLy8gQ29tcGFyZSBwYXRocyB0byBmaW5kIHRoZSBsb25nZXN0IGNvbW1vbiBwYXRoIGZyb20gcm9vdFxuICBjb25zdCBsZW5ndGggPSBmcm9tTGVuIDwgdG9MZW4gPyBmcm9tTGVuIDogdG9MZW47XG4gIGxldCBsYXN0Q29tbW9uU2VwID0gLTE7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPD0gbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gbGVuZ3RoKSB7XG4gICAgICBpZiAodG9MZW4gPiBsZW5ndGgpIHtcbiAgICAgICAgaWYgKHRvLmNoYXJDb2RlQXQodG9TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIGV4YWN0IGJhc2UgcGF0aCBmb3IgYHRvYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXInOyB0bz0nL2Zvby9iYXIvYmF6J1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgZnJvbWAgaXMgdGhlIHJvb3RcbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nLyc7IHRvPScvZm9vJ1xuICAgICAgICAgIHJldHVybiB0by5zbGljZSh0b1N0YXJ0ICsgaSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZnJvbUxlbiA+IGxlbmd0aCkge1xuICAgICAgICBpZiAoZnJvbS5jaGFyQ29kZUF0KGZyb21TdGFydCArIGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSBleGFjdCBiYXNlIHBhdGggZm9yIGBmcm9tYC5cbiAgICAgICAgICAvLyBGb3IgZXhhbXBsZTogZnJvbT0nL2Zvby9iYXIvYmF6JzsgdG89Jy9mb28vYmFyJ1xuICAgICAgICAgIGxhc3RDb21tb25TZXAgPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBgdG9gIGlzIHRoZSByb290LlxuICAgICAgICAgIC8vIEZvciBleGFtcGxlOiBmcm9tPScvZm9vJzsgdG89Jy8nXG4gICAgICAgICAgbGFzdENvbW1vblNlcCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ29kZSA9IGZyb20uY2hhckNvZGVBdChmcm9tU3RhcnQgKyBpKTtcbiAgICBjb25zdCB0b0NvZGUgPSB0by5jaGFyQ29kZUF0KHRvU3RhcnQgKyBpKTtcbiAgICBpZiAoZnJvbUNvZGUgIT09IHRvQ29kZSkgYnJlYWs7XG4gICAgZWxzZSBpZiAoZnJvbUNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkgbGFzdENvbW1vblNlcCA9IGk7XG4gIH1cblxuICBsZXQgb3V0ID0gXCJcIjtcbiAgLy8gR2VuZXJhdGUgdGhlIHJlbGF0aXZlIHBhdGggYmFzZWQgb24gdGhlIHBhdGggZGlmZmVyZW5jZSBiZXR3ZWVuIGB0b2BcbiAgLy8gYW5kIGBmcm9tYFxuICBmb3IgKGkgPSBmcm9tU3RhcnQgKyBsYXN0Q29tbW9uU2VwICsgMTsgaSA8PSBmcm9tRW5kOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gZnJvbUVuZCB8fCBmcm9tLmNoYXJDb2RlQXQoaSkgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgaWYgKG91dC5sZW5ndGggPT09IDApIG91dCArPSBcIi4uXCI7XG4gICAgICBlbHNlIG91dCArPSBcIi8uLlwiO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSwgYXBwZW5kIHRoZSByZXN0IG9mIHRoZSBkZXN0aW5hdGlvbiAoYHRvYCkgcGF0aCB0aGF0IGNvbWVzIGFmdGVyXG4gIC8vIHRoZSBjb21tb24gcGF0aCBwYXJ0c1xuICBpZiAob3V0Lmxlbmd0aCA+IDApIHJldHVybiBvdXQgKyB0by5zbGljZSh0b1N0YXJ0ICsgbGFzdENvbW1vblNlcCk7XG4gIGVsc2Uge1xuICAgIHRvU3RhcnQgKz0gbGFzdENvbW1vblNlcDtcbiAgICBpZiAodG8uY2hhckNvZGVBdCh0b1N0YXJ0KSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSArK3RvU3RhcnQ7XG4gICAgcmV0dXJuIHRvLnNsaWNlKHRvU3RhcnQpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgcGF0aCB0byBhIG5hbWVzcGFjZSBwYXRoXG4gKiBAcGFyYW0gcGF0aCB0byByZXNvbHZlIHRvIG5hbWVzcGFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9OYW1lc3BhY2VkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBOb24tb3Agb24gcG9zaXggc3lzdGVtc1xuICByZXR1cm4gcGF0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGRpcmVjdG9yeSBuYW1lIG9mIGEgYHBhdGhgLlxuICogQHBhcmFtIHBhdGggdG8gZGV0ZXJtaW5lIG5hbWUgZm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiLlwiO1xuICBjb25zdCBoYXNSb290ID0gcGF0aC5jaGFyQ29kZUF0KDApID09PSBDSEFSX0ZPUldBUkRfU0xBU0g7XG4gIGxldCBlbmQgPSAtMTtcbiAgbGV0IG1hdGNoZWRTbGFzaCA9IHRydWU7XG4gIGZvciAobGV0IGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMTsgLS1pKSB7XG4gICAgaWYgKHBhdGguY2hhckNvZGVBdChpKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2Ugc2F3IHRoZSBmaXJzdCBub24tcGF0aCBzZXBhcmF0b3JcbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbmQgPT09IC0xKSByZXR1cm4gaGFzUm9vdCA/IFwiL1wiIDogXCIuXCI7XG4gIGlmIChoYXNSb290ICYmIGVuZCA9PT0gMSkgcmV0dXJuIFwiLy9cIjtcbiAgcmV0dXJuIHBhdGguc2xpY2UoMCwgZW5kKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGxhc3QgcG9ydGlvbiBvZiBhIGBwYXRoYC4gVHJhaWxpbmcgZGlyZWN0b3J5IHNlcGFyYXRvcnMgYXJlIGlnbm9yZWQuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKiBAcGFyYW0gZXh0IG9mIHBhdGggZGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlbmFtZShwYXRoOiBzdHJpbmcsIGV4dCA9IFwiXCIpOiBzdHJpbmcge1xuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZXh0XCIgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZycpO1xuICB9XG4gIGFzc2VydFBhdGgocGF0aCk7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgbGV0IGk6IG51bWJlcjtcblxuICBpZiAoZXh0ICE9PSB1bmRlZmluZWQgJiYgZXh0Lmxlbmd0aCA+IDAgJiYgZXh0Lmxlbmd0aCA8PSBwYXRoLmxlbmd0aCkge1xuICAgIGlmIChleHQubGVuZ3RoID09PSBwYXRoLmxlbmd0aCAmJiBleHQgPT09IHBhdGgpIHJldHVybiBcIlwiO1xuICAgIGxldCBleHRJZHggPSBleHQubGVuZ3RoIC0gMTtcbiAgICBsZXQgZmlyc3ROb25TbGFzaEVuZCA9IC0xO1xuICAgIGZvciAoaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYSBwYXRoIHNlcGFyYXRvciB0aGF0IHdhcyBub3QgcGFydCBvZiBhIHNldCBvZiBwYXRoXG4gICAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICAgIHN0YXJ0ID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaXJzdE5vblNsYXNoRW5kID09PSAtMSkge1xuICAgICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCByZW1lbWJlciB0aGlzIGluZGV4IGluIGNhc2VcbiAgICAgICAgICAvLyB3ZSBuZWVkIGl0IGlmIHRoZSBleHRlbnNpb24gZW5kcyB1cCBub3QgbWF0Y2hpbmdcbiAgICAgICAgICBtYXRjaGVkU2xhc2ggPSBmYWxzZTtcbiAgICAgICAgICBmaXJzdE5vblNsYXNoRW5kID0gaSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dElkeCA+PSAwKSB7XG4gICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIHRoZSBleHBsaWNpdCBleHRlbnNpb25cbiAgICAgICAgICBpZiAoY29kZSA9PT0gZXh0LmNoYXJDb2RlQXQoZXh0SWR4KSkge1xuICAgICAgICAgICAgaWYgKC0tZXh0SWR4ID09PSAtMSkge1xuICAgICAgICAgICAgICAvLyBXZSBtYXRjaGVkIHRoZSBleHRlbnNpb24sIHNvIG1hcmsgdGhpcyBhcyB0aGUgZW5kIG9mIG91ciBwYXRoXG4gICAgICAgICAgICAgIC8vIGNvbXBvbmVudFxuICAgICAgICAgICAgICBlbmQgPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBFeHRlbnNpb24gZG9lcyBub3QgbWF0Y2gsIHNvIG91ciByZXN1bHQgaXMgdGhlIGVudGlyZSBwYXRoXG4gICAgICAgICAgICAvLyBjb21wb25lbnRcbiAgICAgICAgICAgIGV4dElkeCA9IC0xO1xuICAgICAgICAgICAgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPT09IGVuZCkgZW5kID0gZmlyc3ROb25TbGFzaEVuZDtcbiAgICBlbHNlIGlmIChlbmQgPT09IC0xKSBlbmQgPSBwYXRoLmxlbmd0aDtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSBwYXRoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBpZiAocGF0aC5jaGFyQ29kZUF0KGkpID09PSBDSEFSX0ZPUldBUkRfU0xBU0gpIHtcbiAgICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICAgIGlmICghbWF0Y2hlZFNsYXNoKSB7XG4gICAgICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgICAgLy8gcGF0aCBjb21wb25lbnRcbiAgICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICAgIGVuZCA9IGkgKyAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbmQgPT09IC0xKSByZXR1cm4gXCJcIjtcbiAgICByZXR1cm4gcGF0aC5zbGljZShzdGFydCwgZW5kKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgZXh0ZW5zaW9uIG9mIHRoZSBgcGF0aGAgd2l0aCBsZWFkaW5nIHBlcmlvZC5cbiAqIEBwYXJhbSBwYXRoIHdpdGggZXh0ZW5zaW9uXG4gKiBAcmV0dXJucyBleHRlbnNpb24gKGV4LiBmb3IgYGZpbGUudHNgIHJldHVybnMgYC50c2ApXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydFBhdGgocGF0aCk7XG4gIGxldCBzdGFydERvdCA9IC0xO1xuICBsZXQgc3RhcnRQYXJ0ID0gMDtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgbWF0Y2hlZFNsYXNoID0gdHJ1ZTtcbiAgLy8gVHJhY2sgdGhlIHN0YXRlIG9mIGNoYXJhY3RlcnMgKGlmIGFueSkgd2Ugc2VlIGJlZm9yZSBvdXIgZmlyc3QgZG90IGFuZFxuICAvLyBhZnRlciBhbnkgcGF0aCBzZXBhcmF0b3Igd2UgZmluZFxuICBsZXQgcHJlRG90U3RhdGUgPSAwO1xuICBmb3IgKGxldCBpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgIGNvbnN0IGNvZGUgPSBwYXRoLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRk9SV0FSRF9TTEFTSCkge1xuICAgICAgLy8gSWYgd2UgcmVhY2hlZCBhIHBhdGggc2VwYXJhdG9yIHRoYXQgd2FzIG5vdCBwYXJ0IG9mIGEgc2V0IG9mIHBhdGhcbiAgICAgIC8vIHNlcGFyYXRvcnMgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCBzdG9wIG5vd1xuICAgICAgaWYgKCFtYXRjaGVkU2xhc2gpIHtcbiAgICAgICAgc3RhcnRQYXJ0ID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChlbmQgPT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgdGhlIGZpcnN0IG5vbi1wYXRoIHNlcGFyYXRvciwgbWFyayB0aGlzIGFzIHRoZSBlbmQgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25cbiAgICAgIG1hdGNoZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgZW5kID0gaSArIDE7XG4gICAgfVxuICAgIGlmIChjb2RlID09PSBDSEFSX0RPVCkge1xuICAgICAgLy8gSWYgdGhpcyBpcyBvdXIgZmlyc3QgZG90LCBtYXJrIGl0IGFzIHRoZSBzdGFydCBvZiBvdXIgZXh0ZW5zaW9uXG4gICAgICBpZiAoc3RhcnREb3QgPT09IC0xKSBzdGFydERvdCA9IGk7XG4gICAgICBlbHNlIGlmIChwcmVEb3RTdGF0ZSAhPT0gMSkgcHJlRG90U3RhdGUgPSAxO1xuICAgIH0gZWxzZSBpZiAoc3RhcnREb3QgIT09IC0xKSB7XG4gICAgICAvLyBXZSBzYXcgYSBub24tZG90IGFuZCBub24tcGF0aCBzZXBhcmF0b3IgYmVmb3JlIG91ciBkb3QsIHNvIHdlIHNob3VsZFxuICAgICAgLy8gaGF2ZSBhIGdvb2QgY2hhbmNlIGF0IGhhdmluZyBhIG5vbi1lbXB0eSBleHRlbnNpb25cbiAgICAgIHByZURvdFN0YXRlID0gLTE7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIHN0YXJ0RG90ID09PSAtMSB8fFxuICAgIGVuZCA9PT0gLTEgfHxcbiAgICAvLyBXZSBzYXcgYSBub24tZG90IGNoYXJhY3RlciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGRvdFxuICAgIHByZURvdFN0YXRlID09PSAwIHx8XG4gICAgLy8gVGhlIChyaWdodC1tb3N0KSB0cmltbWVkIHBhdGggY29tcG9uZW50IGlzIGV4YWN0bHkgJy4uJ1xuICAgIChwcmVEb3RTdGF0ZSA9PT0gMSAmJiBzdGFydERvdCA9PT0gZW5kIC0gMSAmJiBzdGFydERvdCA9PT0gc3RhcnRQYXJ0ICsgMSlcbiAgKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbiAgcmV0dXJuIHBhdGguc2xpY2Uoc3RhcnREb3QsIGVuZCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBwYXRoIGZyb20gYEZvcm1hdElucHV0UGF0aE9iamVjdGAgb2JqZWN0LlxuICogQHBhcmFtIHBhdGhPYmplY3Qgd2l0aCBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXQocGF0aE9iamVjdDogRm9ybWF0SW5wdXRQYXRoT2JqZWN0KTogc3RyaW5nIHtcbiAgaWYgKHBhdGhPYmplY3QgPT09IG51bGwgfHwgdHlwZW9mIHBhdGhPYmplY3QgIT09IFwib2JqZWN0XCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYFRoZSBcInBhdGhPYmplY3RcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICR7dHlwZW9mIHBhdGhPYmplY3R9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBfZm9ybWF0KFwiL1wiLCBwYXRoT2JqZWN0KTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBgUGFyc2VkUGF0aGAgb2JqZWN0IG9mIHRoZSBgcGF0aGAuXG4gKiBAcGFyYW0gcGF0aCB0byBwcm9jZXNzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShwYXRoOiBzdHJpbmcpOiBQYXJzZWRQYXRoIHtcbiAgYXNzZXJ0UGF0aChwYXRoKTtcblxuICBjb25zdCByZXQ6IFBhcnNlZFBhdGggPSB7IHJvb3Q6IFwiXCIsIGRpcjogXCJcIiwgYmFzZTogXCJcIiwgZXh0OiBcIlwiLCBuYW1lOiBcIlwiIH07XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJldDtcbiAgY29uc3QgaXNBYnNvbHV0ZSA9IHBhdGguY2hhckNvZGVBdCgwKSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIO1xuICBsZXQgc3RhcnQ6IG51bWJlcjtcbiAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICByZXQucm9vdCA9IFwiL1wiO1xuICAgIHN0YXJ0ID0gMTtcbiAgfSBlbHNlIHtcbiAgICBzdGFydCA9IDA7XG4gIH1cbiAgbGV0IHN0YXJ0RG90ID0gLTE7XG4gIGxldCBzdGFydFBhcnQgPSAwO1xuICBsZXQgZW5kID0gLTE7XG4gIGxldCBtYXRjaGVkU2xhc2ggPSB0cnVlO1xuICBsZXQgaSA9IHBhdGgubGVuZ3RoIC0gMTtcblxuICAvLyBUcmFjayB0aGUgc3RhdGUgb2YgY2hhcmFjdGVycyAoaWYgYW55KSB3ZSBzZWUgYmVmb3JlIG91ciBmaXJzdCBkb3QgYW5kXG4gIC8vIGFmdGVyIGFueSBwYXRoIHNlcGFyYXRvciB3ZSBmaW5kXG4gIGxldCBwcmVEb3RTdGF0ZSA9IDA7XG5cbiAgLy8gR2V0IG5vbi1kaXIgaW5mb1xuICBmb3IgKDsgaSA+PSBzdGFydDsgLS1pKSB7XG4gICAgY29uc3QgY29kZSA9IHBhdGguY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gQ0hBUl9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAvLyBJZiB3ZSByZWFjaGVkIGEgcGF0aCBzZXBhcmF0b3IgdGhhdCB3YXMgbm90IHBhcnQgb2YgYSBzZXQgb2YgcGF0aFxuICAgICAgLy8gc2VwYXJhdG9ycyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIHN0b3Agbm93XG4gICAgICBpZiAoIW1hdGNoZWRTbGFzaCkge1xuICAgICAgICBzdGFydFBhcnQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyB0aGUgZmlyc3Qgbm9uLXBhdGggc2VwYXJhdG9yLCBtYXJrIHRoaXMgYXMgdGhlIGVuZCBvZiBvdXJcbiAgICAgIC8vIGV4dGVuc2lvblxuICAgICAgbWF0Y2hlZFNsYXNoID0gZmFsc2U7XG4gICAgICBlbmQgPSBpICsgMTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENIQVJfRE9UKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBkb3QsIG1hcmsgaXQgYXMgdGhlIHN0YXJ0IG9mIG91ciBleHRlbnNpb25cbiAgICAgIGlmIChzdGFydERvdCA9PT0gLTEpIHN0YXJ0RG90ID0gaTtcbiAgICAgIGVsc2UgaWYgKHByZURvdFN0YXRlICE9PSAxKSBwcmVEb3RTdGF0ZSA9IDE7XG4gICAgfSBlbHNlIGlmIChzdGFydERvdCAhPT0gLTEpIHtcbiAgICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgYW5kIG5vbi1wYXRoIHNlcGFyYXRvciBiZWZvcmUgb3VyIGRvdCwgc28gd2Ugc2hvdWxkXG4gICAgICAvLyBoYXZlIGEgZ29vZCBjaGFuY2UgYXQgaGF2aW5nIGEgbm9uLWVtcHR5IGV4dGVuc2lvblxuICAgICAgcHJlRG90U3RhdGUgPSAtMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgc3RhcnREb3QgPT09IC0xIHx8XG4gICAgZW5kID09PSAtMSB8fFxuICAgIC8vIFdlIHNhdyBhIG5vbi1kb3QgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZG90XG4gICAgcHJlRG90U3RhdGUgPT09IDAgfHxcbiAgICAvLyBUaGUgKHJpZ2h0LW1vc3QpIHRyaW1tZWQgcGF0aCBjb21wb25lbnQgaXMgZXhhY3RseSAnLi4nXG4gICAgKHByZURvdFN0YXRlID09PSAxICYmIHN0YXJ0RG90ID09PSBlbmQgLSAxICYmIHN0YXJ0RG90ID09PSBzdGFydFBhcnQgKyAxKVxuICApIHtcbiAgICBpZiAoZW5kICE9PSAtMSkge1xuICAgICAgaWYgKHN0YXJ0UGFydCA9PT0gMCAmJiBpc0Fic29sdXRlKSB7XG4gICAgICAgIHJldC5iYXNlID0gcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIGVuZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQuYmFzZSA9IHJldC5uYW1lID0gcGF0aC5zbGljZShzdGFydFBhcnQsIGVuZCk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChzdGFydFBhcnQgPT09IDAgJiYgaXNBYnNvbHV0ZSkge1xuICAgICAgcmV0Lm5hbWUgPSBwYXRoLnNsaWNlKDEsIHN0YXJ0RG90KTtcbiAgICAgIHJldC5iYXNlID0gcGF0aC5zbGljZSgxLCBlbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXQubmFtZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBzdGFydERvdCk7XG4gICAgICByZXQuYmFzZSA9IHBhdGguc2xpY2Uoc3RhcnRQYXJ0LCBlbmQpO1xuICAgIH1cbiAgICByZXQuZXh0ID0gcGF0aC5zbGljZShzdGFydERvdCwgZW5kKTtcbiAgfVxuXG4gIGlmIChzdGFydFBhcnQgPiAwKSByZXQuZGlyID0gcGF0aC5zbGljZSgwLCBzdGFydFBhcnQgLSAxKTtcbiAgZWxzZSBpZiAoaXNBYnNvbHV0ZSkgcmV0LmRpciA9IFwiL1wiO1xuXG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBmaWxlIFVSTCB0byBhIHBhdGggc3RyaW5nLlxuICpcbiAqIGBgYHRzXG4gKiAgICAgIGltcG9ydCB7IGZyb21GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgZnJvbUZpbGVVcmwoXCJmaWxlOi8vL2hvbWUvZm9vXCIpOyAvLyBcIi9ob21lL2Zvb1wiXG4gKiBgYGBcbiAqIEBwYXJhbSB1cmwgb2YgYSBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUZpbGVVcmwodXJsOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICB1cmwgPSB1cmwgaW5zdGFuY2VvZiBVUkwgPyB1cmwgOiBuZXcgVVJMKHVybCk7XG4gIGlmICh1cmwucHJvdG9jb2wgIT0gXCJmaWxlOlwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYSBmaWxlIFVSTC5cIik7XG4gIH1cbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChcbiAgICB1cmwucGF0aG5hbWUucmVwbGFjZSgvJSg/IVswLTlBLUZhLWZdezJ9KS9nLCBcIiUyNVwiKSxcbiAgKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHBhdGggc3RyaW5nIHRvIGEgZmlsZSBVUkwuXG4gKlxuICogYGBgdHNcbiAqICAgICAgaW1wb3J0IHsgdG9GaWxlVXJsIH0gZnJvbSBcIi4vcG9zaXgudHNcIjtcbiAqICAgICAgdG9GaWxlVXJsKFwiL2hvbWUvZm9vXCIpOyAvLyBuZXcgVVJMKFwiZmlsZTovLy9ob21lL2Zvb1wiKVxuICogYGBgXG4gKiBAcGFyYW0gcGF0aCB0byBjb252ZXJ0IHRvIGZpbGUgVVJMXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0ZpbGVVcmwocGF0aDogc3RyaW5nKTogVVJMIHtcbiAgaWYgKCFpc0Fic29sdXRlKHBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYW4gYWJzb2x1dGUgcGF0aC5cIik7XG4gIH1cbiAgY29uc3QgdXJsID0gbmV3IFVSTChcImZpbGU6Ly8vXCIpO1xuICB1cmwucGF0aG5hbWUgPSBlbmNvZGVXaGl0ZXNwYWNlKFxuICAgIHBhdGgucmVwbGFjZSgvJS9nLCBcIiUyNVwiKS5yZXBsYWNlKC9cXFxcL2csIFwiJTVDXCIpLFxuICApO1xuICByZXR1cm4gdXJsO1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxpREFBaUQ7QUFDakQsNkRBQTZEO0FBQzdELHFDQUFxQztBQUdyQyxTQUFTLFFBQVEsRUFBRSxrQkFBa0IsUUFBUSxrQkFBa0I7QUFFL0QsU0FDRSxPQUFPLEVBQ1AsVUFBVSxFQUNWLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsZUFBZSxRQUNWLGFBQWE7QUFFcEIsT0FBTyxNQUFNLE1BQU0sSUFBSTtBQUN2QixPQUFPLE1BQU0sWUFBWSxJQUFJO0FBRTdCLCtCQUErQjtBQUMvQjs7O0NBR0MsR0FDRCxPQUFPLFNBQVMsUUFBUSxHQUFHLFlBQXNCLEVBQVU7SUFDekQsSUFBSSxlQUFlO0lBQ25CLElBQUksbUJBQW1CLEtBQUs7SUFFNUIsSUFBSyxJQUFJLElBQUksYUFBYSxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLGtCQUFrQixJQUFLO1FBQ3ZFLElBQUk7UUFFSixJQUFJLEtBQUssR0FBRyxPQUFPLFlBQVksQ0FBQyxFQUFFO2FBQzdCO1lBQ0gsbUNBQW1DO1lBQ25D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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js b/tests/__snapshots__/transpile/url/modules/nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js new file mode 100644 index 0000000..fc8cdf6 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/nhMTTXGO1bgNtQ_bGZFJE0b7hWs.js @@ -0,0 +1,14 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +export class DenoStdInternalError extends Error { + constructor(message){ + super(message); + this.name = "DenoStdInternalError"; + } +} +/** Make an assertion, if not `true`, then throw. */ export function assert(expr, msg = "") { + if (!expr) { + throw new DenoStdInternalError(msg); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL191dGlsL2Fzc2VydC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG5leHBvcnQgY2xhc3MgRGVub1N0ZEludGVybmFsRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiRGVub1N0ZEludGVybmFsRXJyb3JcIjtcbiAgfVxufVxuXG4vKiogTWFrZSBhbiBhc3NlcnRpb24sIGlmIG5vdCBgdHJ1ZWAsIHRoZW4gdGhyb3cuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0KGV4cHI6IHVua25vd24sIG1zZyA9IFwiXCIpOiBhc3NlcnRzIGV4cHIge1xuICBpZiAoIWV4cHIpIHtcbiAgICB0aHJvdyBuZXcgRGVub1N0ZEludGVybmFsRXJyb3IobXNnKTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBFQUEwRTtBQUMxRSxxQ0FBcUM7QUFFckMsT0FBTyxNQUFNLDZCQUE2QjtJQUN4QyxZQUFZLE9BQWUsQ0FBRTtRQUMzQixLQUFLLENBQUM7UUFDTixJQUFJLENBQUMsSUFBSSxHQUFHO0lBQ2Q7QUFDRixDQUFDO0FBRUQsa0RBQWtELEdBQ2xELE9BQU8sU0FBUyxPQUFPLElBQWEsRUFBRSxNQUFNLEVBQUUsRUFBZ0I7SUFDNUQsSUFBSSxDQUFDLE1BQU07UUFDVCxNQUFNLElBQUkscUJBQXFCLEtBQUs7SUFDdEMsQ0FBQztBQUNILENBQUMifQ== \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/npEsX-46oQUgZNw2Jkxv5i4eWDM.js b/tests/__snapshots__/transpile/url/modules/npEsX-46oQUgZNw2Jkxv5i4eWDM.js new file mode 100644 index 0000000..04be5a3 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/npEsX-46oQUgZNw2Jkxv5i4eWDM.js @@ -0,0 +1,851 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { assert } from "../_util/assert.ts"; +import { BytesList } from "../bytes/bytes_list.ts"; +import { concat, copy } from "../bytes/mod.ts"; +// MIN_READ is the minimum ArrayBuffer size passed to a read call by +// buffer.ReadFrom. As long as the Buffer has at least MIN_READ bytes beyond +// what is required to hold the contents of r, readFrom() will not grow the +// underlying buffer. +const MIN_READ = 32 * 1024; +const MAX_SIZE = 2 ** 32 - 2; +/** A variable-sized buffer of bytes with `read()` and `write()` methods. + * + * Buffer is almost always used with some I/O like files and sockets. It allows + * one to buffer up a download from a socket. Buffer grows and shrinks as + * necessary. + * + * Buffer is NOT the same thing as Node's Buffer. Node's Buffer was created in + * 2009 before JavaScript had the concept of ArrayBuffers. It's simply a + * non-standard ArrayBuffer. + * + * ArrayBuffer is a fixed memory allocation. Buffer is implemented on top of + * ArrayBuffer. + * + * Based on [Go Buffer](https://golang.org/pkg/bytes/#Buffer). */ export class Buffer { + #buf; + #off = 0; + constructor(ab){ + this.#buf = ab === undefined ? new Uint8Array(0) : new Uint8Array(ab); + } + /** Returns a slice holding the unread portion of the buffer. + * + * The slice is valid for use only until the next buffer modification (that + * is, only until the next call to a method like `read()`, `write()`, + * `reset()`, or `truncate()`). If `options.copy` is false the slice aliases the buffer content at + * least until the next buffer modification, so immediate changes to the + * slice will affect the result of future reads. + * @param options Defaults to `{ copy: true }` + */ bytes(options = { + copy: true + }) { + if (options.copy === false) return this.#buf.subarray(this.#off); + return this.#buf.slice(this.#off); + } + /** Returns whether the unread portion of the buffer is empty. */ empty() { + return this.#buf.byteLength <= this.#off; + } + /** A read only number of bytes of the unread portion of the buffer. */ get length() { + return this.#buf.byteLength - this.#off; + } + /** The read only capacity of the buffer's underlying byte slice, that is, + * the total space allocated for the buffer's data. */ get capacity() { + return this.#buf.buffer.byteLength; + } + /** Discards all but the first `n` unread bytes from the buffer but + * continues to use the same allocated storage. It throws if `n` is + * negative or greater than the length of the buffer. */ truncate(n) { + if (n === 0) { + this.reset(); + return; + } + if (n < 0 || n > this.length) { + throw Error("bytes.Buffer: truncation out of range"); + } + this.#reslice(this.#off + n); + } + reset() { + this.#reslice(0); + this.#off = 0; + } + #tryGrowByReslice(n) { + const l = this.#buf.byteLength; + if (n <= this.capacity - l) { + this.#reslice(l + n); + return l; + } + return -1; + } + #reslice(len) { + assert(len <= this.#buf.buffer.byteLength); + this.#buf = new Uint8Array(this.#buf.buffer, 0, len); + } + /** Reads the next `p.length` bytes from the buffer or until the buffer is + * drained. Returns the number of bytes read. If the buffer has no data to + * return, the return is EOF (`null`). */ readSync(p) { + if (this.empty()) { + // Buffer is empty, reset to recover space. + this.reset(); + if (p.byteLength === 0) { + // this edge case is tested in 'bufferReadEmptyAtEOF' test + return 0; + } + return null; + } + const nread = copy(this.#buf.subarray(this.#off), p); + this.#off += nread; + return nread; + } + /** Reads the next `p.length` bytes from the buffer or until the buffer is + * drained. Resolves to the number of bytes read. If the buffer has no + * data to return, resolves to EOF (`null`). + * + * NOTE: This methods reads bytes synchronously; it's provided for + * compatibility with `Reader` interfaces. + */ read(p) { + const rr = this.readSync(p); + return Promise.resolve(rr); + } + writeSync(p) { + const m = this.#grow(p.byteLength); + return copy(p, this.#buf, m); + } + /** NOTE: This methods writes bytes synchronously; it's provided for + * compatibility with `Writer` interface. */ write(p) { + const n = this.writeSync(p); + return Promise.resolve(n); + } + #grow(n) { + const m = this.length; + // If buffer is empty, reset to recover space. + if (m === 0 && this.#off !== 0) { + this.reset(); + } + // Fast: Try to grow by means of a reslice. + const i = this.#tryGrowByReslice(n); + if (i >= 0) { + return i; + } + const c = this.capacity; + if (n <= Math.floor(c / 2) - m) { + // We can slide things down instead of allocating a new + // ArrayBuffer. We only need m+n <= c to slide, but + // we instead let capacity get twice as large so we + // don't spend all our time copying. + copy(this.#buf.subarray(this.#off), this.#buf); + } else if (c + n > MAX_SIZE) { + throw new Error("The buffer cannot be grown beyond the maximum size."); + } else { + // Not enough space anywhere, we need to allocate. + const buf = new Uint8Array(Math.min(2 * c + n, MAX_SIZE)); + copy(this.#buf.subarray(this.#off), buf); + this.#buf = buf; + } + // Restore this.#off and len(this.#buf). + this.#off = 0; + this.#reslice(Math.min(m + n, MAX_SIZE)); + return m; + } + /** Grows the buffer's capacity, if necessary, to guarantee space for + * another `n` bytes. After `.grow(n)`, at least `n` bytes can be written to + * the buffer without another allocation. If `n` is negative, `.grow()` will + * throw. If the buffer can't grow it will throw an error. + * + * Based on Go Lang's + * [Buffer.Grow](https://golang.org/pkg/bytes/#Buffer.Grow). */ grow(n) { + if (n < 0) { + throw Error("Buffer.grow: negative count"); + } + const m = this.#grow(n); + this.#reslice(m); + } + /** Reads data from `r` until EOF (`null`) and appends it to the buffer, + * growing the buffer as needed. It resolves to the number of bytes read. + * If the buffer becomes too large, `.readFrom()` will reject with an error. + * + * Based on Go Lang's + * [Buffer.ReadFrom](https://golang.org/pkg/bytes/#Buffer.ReadFrom). */ async readFrom(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while(true){ + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow ? tmp : new Uint8Array(this.#buf.buffer, this.length); + const nread = await r.read(buf); + if (nread === null) { + return n; + } + // write will grow if needed + if (shouldGrow) this.writeSync(buf.subarray(0, nread)); + else this.#reslice(this.length + nread); + n += nread; + } + } + /** Reads data from `r` until EOF (`null`) and appends it to the buffer, + * growing the buffer as needed. It returns the number of bytes read. If the + * buffer becomes too large, `.readFromSync()` will throw an error. + * + * Based on Go Lang's + * [Buffer.ReadFrom](https://golang.org/pkg/bytes/#Buffer.ReadFrom). */ readFromSync(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while(true){ + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow ? tmp : new Uint8Array(this.#buf.buffer, this.length); + const nread = r.readSync(buf); + if (nread === null) { + return n; + } + // write will grow if needed + if (shouldGrow) this.writeSync(buf.subarray(0, nread)); + else this.#reslice(this.length + nread); + n += nread; + } + } +} +const DEFAULT_BUF_SIZE = 4096; +const MIN_BUF_SIZE = 16; +const MAX_CONSECUTIVE_EMPTY_READS = 100; +const CR = "\r".charCodeAt(0); +const LF = "\n".charCodeAt(0); +export class BufferFullError extends Error { + partial; + name; + constructor(partial){ + super("Buffer full"); + this.partial = partial; + this.name = "BufferFullError"; + } +} +export class PartialReadError extends Error { + name = "PartialReadError"; + partial; + constructor(){ + super("Encountered UnexpectedEof, data only partially read"); + } +} +/** BufReader implements buffering for a Reader object. */ export class BufReader { + #buf; + #rd; + #r = 0; + #w = 0; + #eof = false; + // private lastByte: number; + // private lastCharSize: number; + /** return new BufReader unless r is BufReader */ static create(r, size = DEFAULT_BUF_SIZE) { + return r instanceof BufReader ? r : new BufReader(r, size); + } + constructor(rd, size = DEFAULT_BUF_SIZE){ + if (size < MIN_BUF_SIZE) { + size = MIN_BUF_SIZE; + } + this.#reset(new Uint8Array(size), rd); + } + /** Returns the size of the underlying buffer in bytes. */ size() { + return this.#buf.byteLength; + } + buffered() { + return this.#w - this.#r; + } + // Reads a new chunk into the buffer. + #fill = async ()=>{ + // Slide existing data to beginning. + if (this.#r > 0) { + this.#buf.copyWithin(0, this.#r, this.#w); + this.#w -= this.#r; + this.#r = 0; + } + if (this.#w >= this.#buf.byteLength) { + throw Error("bufio: tried to fill full buffer"); + } + // Read new data: try a limited number of times. + for(let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--){ + const rr = await this.#rd.read(this.#buf.subarray(this.#w)); + if (rr === null) { + this.#eof = true; + return; + } + assert(rr >= 0, "negative read"); + this.#w += rr; + if (rr > 0) { + return; + } + } + throw new Error(`No progress after ${MAX_CONSECUTIVE_EMPTY_READS} read() calls`); + }; + /** Discards any buffered data, resets all state, and switches + * the buffered reader to read from r. + */ reset(r) { + this.#reset(this.#buf, r); + } + #reset = (buf, rd)=>{ + this.#buf = buf; + this.#rd = rd; + this.#eof = false; + // this.lastByte = -1; + // this.lastCharSize = -1; + }; + /** reads data into p. + * It returns the number of bytes read into p. + * The bytes are taken from at most one Read on the underlying Reader, + * hence n may be less than len(p). + * To read exactly len(p) bytes, use io.ReadFull(b, p). + */ async read(p) { + let rr = p.byteLength; + if (p.byteLength === 0) return rr; + if (this.#r === this.#w) { + if (p.byteLength >= this.#buf.byteLength) { + // Large read, empty buffer. + // Read directly into p to avoid copy. + const rr = await this.#rd.read(p); + const nread = rr ?? 0; + assert(nread >= 0, "negative read"); + // if (rr.nread > 0) { + // this.lastByte = p[rr.nread - 1]; + // this.lastCharSize = -1; + // } + return rr; + } + // One read. + // Do not use this.fill, which will loop. + this.#r = 0; + this.#w = 0; + rr = await this.#rd.read(this.#buf); + if (rr === 0 || rr === null) return rr; + assert(rr >= 0, "negative read"); + this.#w += rr; + } + // copy as much as we can + const copied = copy(this.#buf.subarray(this.#r, this.#w), p, 0); + this.#r += copied; + // this.lastByte = this.buf[this.r - 1]; + // this.lastCharSize = -1; + return copied; + } + /** reads exactly `p.length` bytes into `p`. + * + * If successful, `p` is returned. + * + * If the end of the underlying stream has been reached, and there are no more + * bytes available in the buffer, `readFull()` returns `null` instead. + * + * An error is thrown if some bytes could be read, but not enough to fill `p` + * entirely before the underlying stream reported an error or EOF. Any error + * thrown will have a `partial` property that indicates the slice of the + * buffer that has been successfully filled with data. + * + * Ported from https://golang.org/pkg/io/#ReadFull + */ async readFull(p) { + let bytesRead = 0; + while(bytesRead < p.length){ + try { + const rr = await this.read(p.subarray(bytesRead)); + if (rr === null) { + if (bytesRead === 0) { + return null; + } else { + throw new PartialReadError(); + } + } + bytesRead += rr; + } catch (err) { + if (err instanceof PartialReadError) { + err.partial = p.subarray(0, bytesRead); + } else if (err instanceof Error) { + const e = new PartialReadError(); + e.partial = p.subarray(0, bytesRead); + e.stack = err.stack; + e.message = err.message; + e.cause = err.cause; + throw err; + } + throw err; + } + } + return p; + } + /** Returns the next byte [0, 255] or `null`. */ async readByte() { + while(this.#r === this.#w){ + if (this.#eof) return null; + await this.#fill(); // buffer is empty. + } + const c = this.#buf[this.#r]; + this.#r++; + // this.lastByte = c; + return c; + } + /** readString() reads until the first occurrence of delim in the input, + * returning a string containing the data up to and including the delimiter. + * If ReadString encounters an error before finding a delimiter, + * it returns the data read before the error and the error itself + * (often `null`). + * ReadString returns err != nil if and only if the returned data does not end + * in delim. + * For simple uses, a Scanner may be more convenient. + */ async readString(delim) { + if (delim.length !== 1) { + throw new Error("Delimiter should be a single character"); + } + const buffer = await this.readSlice(delim.charCodeAt(0)); + if (buffer === null) return null; + return new TextDecoder().decode(buffer); + } + /** `readLine()` is a low-level line-reading primitive. Most callers should + * use `readString('\n')` instead or use a Scanner. + * + * `readLine()` tries to return a single line, not including the end-of-line + * bytes. If the line was too long for the buffer then `more` is set and the + * beginning of the line is returned. The rest of the line will be returned + * from future calls. `more` will be false when returning the last fragment + * of the line. The returned buffer is only valid until the next call to + * `readLine()`. + * + * The text returned from ReadLine does not include the line end ("\r\n" or + * "\n"). + * + * When the end of the underlying stream is reached, the final bytes in the + * stream are returned. No indication or error is given if the input ends + * without a final line end. When there are no more trailing bytes to read, + * `readLine()` returns `null`. + * + * Calling `unreadByte()` after `readLine()` will always unread the last byte + * read (possibly a character belonging to the line end) even if that byte is + * not part of the line returned by `readLine()`. + */ async readLine() { + let line = null; + try { + line = await this.readSlice(LF); + } catch (err) { + if (err instanceof Deno.errors.BadResource) { + throw err; + } + let partial; + if (err instanceof PartialReadError) { + partial = err.partial; + assert(partial instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property"); + } + // Don't throw if `readSlice()` failed with `BufferFullError`, instead we + // just return whatever is available and set the `more` flag. + if (!(err instanceof BufferFullError)) { + throw err; + } + partial = err.partial; + // Handle the case where "\r\n" straddles the buffer. + if (!this.#eof && partial && partial.byteLength > 0 && partial[partial.byteLength - 1] === CR) { + // Put the '\r' back on buf and drop it from line. + // Let the next call to ReadLine check for "\r\n". + assert(this.#r > 0, "bufio: tried to rewind past start of buffer"); + this.#r--; + partial = partial.subarray(0, partial.byteLength - 1); + } + if (partial) { + return { + line: partial, + more: !this.#eof + }; + } + } + if (line === null) { + return null; + } + if (line.byteLength === 0) { + return { + line, + more: false + }; + } + if (line[line.byteLength - 1] == LF) { + let drop = 1; + if (line.byteLength > 1 && line[line.byteLength - 2] === CR) { + drop = 2; + } + line = line.subarray(0, line.byteLength - drop); + } + return { + line, + more: false + }; + } + /** `readSlice()` reads until the first occurrence of `delim` in the input, + * returning a slice pointing at the bytes in the buffer. The bytes stop + * being valid at the next read. + * + * If `readSlice()` encounters an error before finding a delimiter, or the + * buffer fills without finding a delimiter, it throws an error with a + * `partial` property that contains the entire buffer. + * + * If `readSlice()` encounters the end of the underlying stream and there are + * any bytes left in the buffer, the rest of the buffer is returned. In other + * words, EOF is always treated as a delimiter. Once the buffer is empty, + * it returns `null`. + * + * Because the data returned from `readSlice()` will be overwritten by the + * next I/O operation, most clients should use `readString()` instead. + */ async readSlice(delim) { + let s = 0; // search start index + let slice; + while(true){ + // Search buffer. + let i = this.#buf.subarray(this.#r + s, this.#w).indexOf(delim); + if (i >= 0) { + i += s; + slice = this.#buf.subarray(this.#r, this.#r + i + 1); + this.#r += i + 1; + break; + } + // EOF? + if (this.#eof) { + if (this.#r === this.#w) { + return null; + } + slice = this.#buf.subarray(this.#r, this.#w); + this.#r = this.#w; + break; + } + // Buffer full? + if (this.buffered() >= this.#buf.byteLength) { + this.#r = this.#w; + // #4521 The internal buffer should not be reused across reads because it causes corruption of data. + const oldbuf = this.#buf; + const newbuf = this.#buf.slice(0); + this.#buf = newbuf; + throw new BufferFullError(oldbuf); + } + s = this.#w - this.#r; // do not rescan area we scanned before + // Buffer is not full. + try { + await this.#fill(); + } catch (err) { + if (err instanceof PartialReadError) { + err.partial = slice; + } else if (err instanceof Error) { + const e = new PartialReadError(); + e.partial = slice; + e.stack = err.stack; + e.message = err.message; + e.cause = err.cause; + throw err; + } + throw err; + } + } + // Handle last byte, if any. + // const i = slice.byteLength - 1; + // if (i >= 0) { + // this.lastByte = slice[i]; + // this.lastCharSize = -1 + // } + return slice; + } + /** `peek()` returns the next `n` bytes without advancing the reader. The + * bytes stop being valid at the next read call. + * + * When the end of the underlying stream is reached, but there are unread + * bytes left in the buffer, those bytes are returned. If there are no bytes + * left in the buffer, it returns `null`. + * + * If an error is encountered before `n` bytes are available, `peek()` throws + * an error with the `partial` property set to a slice of the buffer that + * contains the bytes that were available before the error occurred. + */ async peek(n) { + if (n < 0) { + throw Error("negative count"); + } + let avail = this.#w - this.#r; + while(avail < n && avail < this.#buf.byteLength && !this.#eof){ + try { + await this.#fill(); + } catch (err) { + if (err instanceof PartialReadError) { + err.partial = this.#buf.subarray(this.#r, this.#w); + } else if (err instanceof Error) { + const e = new PartialReadError(); + e.partial = this.#buf.subarray(this.#r, this.#w); + e.stack = err.stack; + e.message = err.message; + e.cause = err.cause; + throw err; + } + throw err; + } + avail = this.#w - this.#r; + } + if (avail === 0 && this.#eof) { + return null; + } else if (avail < n && this.#eof) { + return this.#buf.subarray(this.#r, this.#r + avail); + } else if (avail < n) { + throw new BufferFullError(this.#buf.subarray(this.#r, this.#w)); + } + return this.#buf.subarray(this.#r, this.#r + n); + } +} +class AbstractBufBase { + buf; + usedBufferBytes = 0; + err = null; + constructor(buf){ + this.buf = buf; + } + /** Size returns the size of the underlying buffer in bytes. */ size() { + return this.buf.byteLength; + } + /** Returns how many bytes are unused in the buffer. */ available() { + return this.buf.byteLength - this.usedBufferBytes; + } + /** buffered returns the number of bytes that have been written into the + * current buffer. + */ buffered() { + return this.usedBufferBytes; + } +} +/** BufWriter implements buffering for an deno.Writer object. + * If an error occurs writing to a Writer, no more data will be + * accepted and all subsequent writes, and flush(), will return the error. + * After all data has been written, the client should call the + * flush() method to guarantee all data has been forwarded to + * the underlying deno.Writer. + */ export class BufWriter extends AbstractBufBase { + #writer; + /** return new BufWriter unless writer is BufWriter */ static create(writer, size = DEFAULT_BUF_SIZE) { + return writer instanceof BufWriter ? writer : new BufWriter(writer, size); + } + constructor(writer, size = DEFAULT_BUF_SIZE){ + super(new Uint8Array(size <= 0 ? DEFAULT_BUF_SIZE : size)); + this.#writer = writer; + } + /** Discards any unflushed buffered data, clears any error, and + * resets buffer to write its output to w. + */ reset(w) { + this.err = null; + this.usedBufferBytes = 0; + this.#writer = w; + } + /** Flush writes any buffered data to the underlying io.Writer. */ async flush() { + if (this.err !== null) throw this.err; + if (this.usedBufferBytes === 0) return; + try { + const p = this.buf.subarray(0, this.usedBufferBytes); + let nwritten = 0; + while(nwritten < p.length){ + nwritten += await this.#writer.write(p.subarray(nwritten)); + } + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + this.buf = new Uint8Array(this.buf.length); + this.usedBufferBytes = 0; + } + /** Writes the contents of `data` into the buffer. If the contents won't fully + * fit into the buffer, those bytes that can are copied into the buffer, the + * buffer is the flushed to the writer and the remaining bytes are copied into + * the now empty buffer. + * + * @return the number of bytes written to the buffer. + */ async write(data) { + if (this.err !== null) throw this.err; + if (data.length === 0) return 0; + let totalBytesWritten = 0; + let numBytesWritten = 0; + while(data.byteLength > this.available()){ + if (this.buffered() === 0) { + // Large write, empty buffer. + // Write directly from data to avoid copy. + try { + numBytesWritten = await this.#writer.write(data); + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + } else { + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + await this.flush(); + } + totalBytesWritten += numBytesWritten; + data = data.subarray(numBytesWritten); + } + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + totalBytesWritten += numBytesWritten; + return totalBytesWritten; + } +} +/** BufWriterSync implements buffering for a deno.WriterSync object. + * If an error occurs writing to a WriterSync, no more data will be + * accepted and all subsequent writes, and flush(), will return the error. + * After all data has been written, the client should call the + * flush() method to guarantee all data has been forwarded to + * the underlying deno.WriterSync. + */ export class BufWriterSync extends AbstractBufBase { + #writer; + /** return new BufWriterSync unless writer is BufWriterSync */ static create(writer, size = DEFAULT_BUF_SIZE) { + return writer instanceof BufWriterSync ? writer : new BufWriterSync(writer, size); + } + constructor(writer, size = DEFAULT_BUF_SIZE){ + super(new Uint8Array(size <= 0 ? DEFAULT_BUF_SIZE : size)); + this.#writer = writer; + } + /** Discards any unflushed buffered data, clears any error, and + * resets buffer to write its output to w. + */ reset(w) { + this.err = null; + this.usedBufferBytes = 0; + this.#writer = w; + } + /** Flush writes any buffered data to the underlying io.WriterSync. */ flush() { + if (this.err !== null) throw this.err; + if (this.usedBufferBytes === 0) return; + try { + const p = this.buf.subarray(0, this.usedBufferBytes); + let nwritten = 0; + while(nwritten < p.length){ + nwritten += this.#writer.writeSync(p.subarray(nwritten)); + } + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + this.buf = new Uint8Array(this.buf.length); + this.usedBufferBytes = 0; + } + /** Writes the contents of `data` into the buffer. If the contents won't fully + * fit into the buffer, those bytes that can are copied into the buffer, the + * buffer is the flushed to the writer and the remaining bytes are copied into + * the now empty buffer. + * + * @return the number of bytes written to the buffer. + */ writeSync(data) { + if (this.err !== null) throw this.err; + if (data.length === 0) return 0; + let totalBytesWritten = 0; + let numBytesWritten = 0; + while(data.byteLength > this.available()){ + if (this.buffered() === 0) { + // Large write, empty buffer. + // Write directly from data to avoid copy. + try { + numBytesWritten = this.#writer.writeSync(data); + } catch (e) { + if (e instanceof Error) { + this.err = e; + } + throw e; + } + } else { + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + this.flush(); + } + totalBytesWritten += numBytesWritten; + data = data.subarray(numBytesWritten); + } + numBytesWritten = copy(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + totalBytesWritten += numBytesWritten; + return totalBytesWritten; + } +} +/** Generate longest proper prefix which is also suffix array. */ function createLPS(pat) { + const lps = new Uint8Array(pat.length); + lps[0] = 0; + let prefixEnd = 0; + let i = 1; + while(i < lps.length){ + if (pat[i] == pat[prefixEnd]) { + prefixEnd++; + lps[i] = prefixEnd; + i++; + } else if (prefixEnd === 0) { + lps[i] = 0; + i++; + } else { + prefixEnd = lps[prefixEnd - 1]; + } + } + return lps; +} +/** Read delimited bytes from a Reader. */ export async function* readDelim(reader, delim) { + // Avoid unicode problems + const delimLen = delim.length; + const delimLPS = createLPS(delim); + const chunks = new BytesList(); + const bufSize = Math.max(1024, delimLen + 1); + // Modified KMP + let inspectIndex = 0; + let matchIndex = 0; + while(true){ + const inspectArr = new Uint8Array(bufSize); + const result = await reader.read(inspectArr); + if (result === null) { + // Yield last chunk. + yield chunks.concat(); + return; + } else if (result < 0) { + // Discard all remaining and silently fail. + return; + } + chunks.add(inspectArr, 0, result); + let localIndex = 0; + while(inspectIndex < chunks.size()){ + if (inspectArr[localIndex] === delim[matchIndex]) { + inspectIndex++; + localIndex++; + matchIndex++; + if (matchIndex === delimLen) { + // Full match + const matchEnd = inspectIndex - delimLen; + const readyBytes = chunks.slice(0, matchEnd); + yield readyBytes; + // Reset match, different from KMP. + chunks.shift(inspectIndex); + inspectIndex = 0; + matchIndex = 0; + } + } else { + if (matchIndex === 0) { + inspectIndex++; + localIndex++; + } else { + matchIndex = delimLPS[matchIndex - 1]; + } + } + } + } +} +/** Read delimited strings from a Reader. */ export async function* readStringDelim(reader, delim, decoderOpts) { + const encoder = new TextEncoder(); + const decoder = new TextDecoder(decoderOpts?.encoding, decoderOpts); + for await (const chunk of readDelim(reader, encoder.encode(delim))){ + yield decoder.decode(chunk); + } +} +/** Read strings line-by-line from a Reader. */ export async function* readLines(reader, decoderOpts) { + const bufReader = new BufReader(reader); + let chunks = []; + const decoder = new TextDecoder(decoderOpts?.encoding, decoderOpts); + while(true){ + const res = await bufReader.readLine(); + if (!res) { + if (chunks.length > 0) { + yield decoder.decode(concat(...chunks)); + } + break; + } + chunks.push(res.line); + if (!res.more) { + yield decoder.decode(concat(...chunks)); + chunks = []; + } + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2lvL2J1ZmZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL191dGlsL2Fzc2VydC50c1wiO1xuaW1wb3J0IHsgQnl0ZXNMaXN0IH0gZnJvbSBcIi4uL2J5dGVzL2J5dGVzX2xpc3QudHNcIjtcbmltcG9ydCB7IGNvbmNhdCwgY29weSB9IGZyb20gXCIuLi9ieXRlcy9tb2QudHNcIjtcbmltcG9ydCB0eXBlIHsgUmVhZGVyLCBSZWFkZXJTeW5jLCBXcml0ZXIsIFdyaXRlclN5bmMgfSBmcm9tIFwiLi90eXBlcy5kLnRzXCI7XG5cbi8vIE1JTl9SRUFEIGlzIHRoZSBtaW5pbXVtIEFycmF5QnVmZmVyIHNpemUgcGFzc2VkIHRvIGEgcmVhZCBjYWxsIGJ5XG4vLyBidWZmZXIuUmVhZEZyb20uIEFzIGxvbmcgYXMgdGhlIEJ1ZmZlciBoYXMgYXQgbGVhc3QgTUlOX1JFQUQgYnl0ZXMgYmV5b25kXG4vLyB3aGF0IGlzIHJlcXVpcmVkIHRvIGhvbGQgdGhlIGNvbnRlbnRzIG9mIHIsIHJlYWRGcm9tKCkgd2lsbCBub3QgZ3JvdyB0aGVcbi8vIHVuZGVybHlpbmcgYnVmZmVyLlxuY29uc3QgTUlOX1JFQUQgPSAzMiAqIDEwMjQ7XG5jb25zdCBNQVhfU0laRSA9IDIgKiogMzIgLSAyO1xuXG4vKiogQSB2YXJpYWJsZS1zaXplZCBidWZmZXIgb2YgYnl0ZXMgd2l0aCBgcmVhZCgpYCBhbmQgYHdyaXRlKClgIG1ldGhvZHMuXG4gKlxuICogQnVmZmVyIGlzIGFsbW9zdCBhbHdheXMgdXNlZCB3aXRoIHNvbWUgSS9PIGxpa2UgZmlsZXMgYW5kIHNvY2tldHMuIEl0IGFsbG93c1xuICogb25lIHRvIGJ1ZmZlciB1cCBhIGRvd25sb2FkIGZyb20gYSBzb2NrZXQuIEJ1ZmZlciBncm93cyBhbmQgc2hyaW5rcyBhc1xuICogbmVjZXNzYXJ5LlxuICpcbiAqIEJ1ZmZlciBpcyBOT1QgdGhlIHNhbWUgdGhpbmcgYXMgTm9kZSdzIEJ1ZmZlci4gTm9kZSdzIEJ1ZmZlciB3YXMgY3JlYXRlZCBpblxuICogMjAwOSBiZWZvcmUgSmF2YVNjcmlwdCBoYWQgdGhlIGNvbmNlcHQgb2YgQXJyYXlCdWZmZXJzLiBJdCdzIHNpbXBseSBhXG4gKiBub24tc3RhbmRhcmQgQXJyYXlCdWZmZXIuXG4gKlxuICogQXJyYXlCdWZmZXIgaXMgYSBmaXhlZCBtZW1vcnkgYWxsb2NhdGlvbi4gQnVmZmVyIGlzIGltcGxlbWVudGVkIG9uIHRvcCBvZlxuICogQXJyYXlCdWZmZXIuXG4gKlxuICogQmFzZWQgb24gW0dvIEJ1ZmZlcl0oaHR0cHM6Ly9nb2xhbmcub3JnL3BrZy9ieXRlcy8jQnVmZmVyKS4gKi9cblxuZXhwb3J0IGNsYXNzIEJ1ZmZlciB7XG4gICNidWY6IFVpbnQ4QXJyYXk7IC8vIGNvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYnVmW29mZiA6IGxlbihidWYpXVxuICAjb2ZmID0gMDsgLy8gcmVhZCBhdCBidWZbb2ZmXSwgd3JpdGUgYXQgYnVmW2J1Zi5ieXRlTGVuZ3RoXVxuXG4gIGNvbnN0cnVjdG9yKGFiPzogQXJyYXlCdWZmZXJMaWtlIHwgQXJyYXlMaWtlPG51bWJlcj4pIHtcbiAgICB0aGlzLiNidWYgPSBhYiA9PT0gdW5kZWZpbmVkID8gbmV3IFVpbnQ4QXJyYXkoMCkgOiBuZXcgVWludDhBcnJheShhYik7XG4gIH1cblxuICAvKiogUmV0dXJucyBhIHNsaWNlIGhvbGRpbmcgdGhlIHVucmVhZCBwb3J0aW9uIG9mIHRoZSBidWZmZXIuXG4gICAqXG4gICAqIFRoZSBzbGljZSBpcyB2YWxpZCBmb3IgdXNlIG9ubHkgdW50aWwgdGhlIG5leHQgYnVmZmVyIG1vZGlmaWNhdGlvbiAodGhhdFxuICAgKiBpcywgb25seSB1bnRpbCB0aGUgbmV4dCBjYWxsIHRvIGEgbWV0aG9kIGxpa2UgYHJlYWQoKWAsIGB3cml0ZSgpYCxcbiAgICogYHJlc2V0KClgLCBvciBgdHJ1bmNhdGUoKWApLiBJZiBgb3B0aW9ucy5jb3B5YCBpcyBmYWxzZSB0aGUgc2xpY2UgYWxpYXNlcyB0aGUgYnVmZmVyIGNvbnRlbnQgYXRcbiAgICogbGVhc3QgdW50aWwgdGhlIG5leHQgYnVmZmVyIG1vZGlmaWNhdGlvbiwgc28gaW1tZWRpYXRlIGNoYW5nZXMgdG8gdGhlXG4gICAqIHNsaWNlIHdpbGwgYWZmZWN0IHRoZSByZXN1bHQgb2YgZnV0dXJlIHJlYWRzLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBEZWZhdWx0cyB0byBgeyBjb3B5OiB0cnVlIH1gXG4gICAqL1xuICBieXRlcyhvcHRpb25zID0geyBjb3B5OiB0cnVlIH0pOiBVaW50OEFycmF5IHtcbiAgICBpZiAob3B0aW9ucy5jb3B5ID09PSBmYWxzZSkgcmV0dXJuIHRoaXMuI2J1Zi5zdWJhcnJheSh0aGlzLiNvZmYpO1xuICAgIHJldHVybiB0aGlzLiNidWYuc2xpY2UodGhpcy4jb2ZmKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHVucmVhZCBwb3J0aW9uIG9mIHRoZSBidWZmZXIgaXMgZW1wdHkuICovXG4gIGVtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLiNidWYuYnl0ZUxlbmd0aCA8PSB0aGlzLiNvZmY7XG4gIH1cblxuICAvKiogQSByZWFkIG9ubHkgbnVtYmVyIG9mIGJ5dGVzIG9mIHRoZSB1bnJlYWQgcG9ydGlvbiBvZiB0aGUgYnVmZmVyLiAqL1xuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuI2J1Zi5ieXRlTGVuZ3RoIC0gdGhpcy4jb2ZmO1xuICB9XG5cbiAgLyoqIFRoZSByZWFkIG9ubHkgY2FwYWNpdHkgb2YgdGhlIGJ1ZmZlcidzIHVuZGVybHlpbmcgYnl0ZSBzbGljZSwgdGhhdCBpcyxcbiAgICogdGhlIHRvdGFsIHNwYWNlIGFsbG9jYXRlZCBmb3IgdGhlIGJ1ZmZlcidzIGRhdGEuICovXG4gIGdldCBjYXBhY2l0eSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLiNidWYuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gIH1cblxuICAvKiogRGlzY2FyZHMgYWxsIGJ1dCB0aGUgZmlyc3QgYG5gIHVucmVhZCBieXRlcyBmcm9tIHRoZSBidWZmZXIgYnV0XG4gICAqIGNvbnRpbnVlcyB0byB1c2UgdGhlIHNhbWUgYWxsb2NhdGVkIHN0b3JhZ2UuIEl0IHRocm93cyBpZiBgbmAgaXNcbiAgICogbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlci4gKi9cbiAgdHJ1bmNhdGUobjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG4gPCAwIHx8IG4gPiB0aGlzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgRXJyb3IoXCJieXRlcy5CdWZmZXI6IHRydW5jYXRpb24gb3V0IG9mIHJhbmdlXCIpO1xuICAgIH1cbiAgICB0aGlzLiNyZXNsaWNlKHRoaXMuI29mZiArIG4pO1xuICB9XG5cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy4jcmVzbGljZSgwKTtcbiAgICB0aGlzLiNvZmYgPSAwO1xuICB9XG5cbiAgI3RyeUdyb3dCeVJlc2xpY2UobjogbnVtYmVyKSB7XG4gICAgY29uc3QgbCA9IHRoaXMuI2J1Zi5ieXRlTGVuZ3RoO1xuICAgIGlmIChuIDw9IHRoaXMuY2FwYWNpdHkgLSBsKSB7XG4gICAgICB0aGlzLiNyZXNsaWNlKGwgKyBuKTtcbiAgICAgIHJldHVybiBsO1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAjcmVzbGljZShsZW46IG51bWJlcikge1xuICAgIGFzc2VydChsZW4gPD0gdGhpcy4jYnVmLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICB0aGlzLiNidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLiNidWYuYnVmZmVyLCAwLCBsZW4pO1xuICB9XG5cbiAgLyoqIFJlYWRzIHRoZSBuZXh0IGBwLmxlbmd0aGAgYnl0ZXMgZnJvbSB0aGUgYnVmZmVyIG9yIHVudGlsIHRoZSBidWZmZXIgaXNcbiAgICogZHJhaW5lZC4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuIElmIHRoZSBidWZmZXIgaGFzIG5vIGRhdGEgdG9cbiAgICogcmV0dXJuLCB0aGUgcmV0dXJuIGlzIEVPRiAoYG51bGxgKS4gKi9cbiAgcmVhZFN5bmMocDogVWludDhBcnJheSk6IG51bWJlciB8IG51bGwge1xuICAgIGlmICh0aGlzLmVtcHR5KCkpIHtcbiAgICAgIC8vIEJ1ZmZlciBpcyBlbXB0eSwgcmVzZXQgdG8gcmVjb3ZlciBzcGFjZS5cbiAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgIGlmIChwLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gdGhpcyBlZGdlIGNhc2UgaXMgdGVzdGVkIGluICdidWZmZXJSZWFkRW1wdHlBdEVPRicgdGVzdFxuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBucmVhZCA9IGNvcHkodGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI29mZiksIHApO1xuICAgIHRoaXMuI29mZiArPSBucmVhZDtcbiAgICByZXR1cm4gbnJlYWQ7XG4gIH1cblxuICAvKiogUmVhZHMgdGhlIG5leHQgYHAubGVuZ3RoYCBieXRlcyBmcm9tIHRoZSBidWZmZXIgb3IgdW50aWwgdGhlIGJ1ZmZlciBpc1xuICAgKiBkcmFpbmVkLiBSZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuIElmIHRoZSBidWZmZXIgaGFzIG5vXG4gICAqIGRhdGEgdG8gcmV0dXJuLCByZXNvbHZlcyB0byBFT0YgKGBudWxsYCkuXG4gICAqXG4gICAqIE5PVEU6IFRoaXMgbWV0aG9kcyByZWFkcyBieXRlcyBzeW5jaHJvbm91c2x5OyBpdCdzIHByb3ZpZGVkIGZvclxuICAgKiBjb21wYXRpYmlsaXR5IHdpdGggYFJlYWRlcmAgaW50ZXJmYWNlcy5cbiAgICovXG4gIHJlYWQocDogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgIGNvbnN0IHJyID0gdGhpcy5yZWFkU3luYyhwKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJyKTtcbiAgfVxuXG4gIHdyaXRlU3luYyhwOiBVaW50OEFycmF5KTogbnVtYmVyIHtcbiAgICBjb25zdCBtID0gdGhpcy4jZ3JvdyhwLmJ5dGVMZW5ndGgpO1xuICAgIHJldHVybiBjb3B5KHAsIHRoaXMuI2J1ZiwgbSk7XG4gIH1cblxuICAvKiogTk9URTogVGhpcyBtZXRob2RzIHdyaXRlcyBieXRlcyBzeW5jaHJvbm91c2x5OyBpdCdzIHByb3ZpZGVkIGZvclxuICAgKiBjb21wYXRpYmlsaXR5IHdpdGggYFdyaXRlcmAgaW50ZXJmYWNlLiAqL1xuICB3cml0ZShwOiBVaW50OEFycmF5KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBuID0gdGhpcy53cml0ZVN5bmMocCk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuKTtcbiAgfVxuXG4gICNncm93KG46IG51bWJlcikge1xuICAgIGNvbnN0IG0gPSB0aGlzLmxlbmd0aDtcbiAgICAvLyBJZiBidWZmZXIgaXMgZW1wdHksIHJlc2V0IHRvIHJlY292ZXIgc3BhY2UuXG4gICAgaWYgKG0gPT09IDAgJiYgdGhpcy4jb2ZmICE9PSAwKSB7XG4gICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuICAgIC8vIEZhc3Q6IFRyeSB0byBncm93IGJ5IG1lYW5zIG9mIGEgcmVzbGljZS5cbiAgICBjb25zdCBpID0gdGhpcy4jdHJ5R3Jvd0J5UmVzbGljZShuKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gICAgY29uc3QgYyA9IHRoaXMuY2FwYWNpdHk7XG4gICAgaWYgKG4gPD0gTWF0aC5mbG9vcihjIC8gMikgLSBtKSB7XG4gICAgICAvLyBXZSBjYW4gc2xpZGUgdGhpbmdzIGRvd24gaW5zdGVhZCBvZiBhbGxvY2F0aW5nIGEgbmV3XG4gICAgICAvLyBBcnJheUJ1ZmZlci4gV2Ugb25seSBuZWVkIG0rbiA8PSBjIHRvIHNsaWRlLCBidXRcbiAgICAgIC8vIHdlIGluc3RlYWQgbGV0IGNhcGFjaXR5IGdldCB0d2ljZSBhcyBsYXJnZSBzbyB3ZVxuICAgICAgLy8gZG9uJ3Qgc3BlbmQgYWxsIG91ciB0aW1lIGNvcHlpbmcuXG4gICAgICBjb3B5KHRoaXMuI2J1Zi5zdWJhcnJheSh0aGlzLiNvZmYpLCB0aGlzLiNidWYpO1xuICAgIH0gZWxzZSBpZiAoYyArIG4gPiBNQVhfU0laRSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIGJ1ZmZlciBjYW5ub3QgYmUgZ3Jvd24gYmV5b25kIHRoZSBtYXhpbXVtIHNpemUuXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBOb3QgZW5vdWdoIHNwYWNlIGFueXdoZXJlLCB3ZSBuZWVkIHRvIGFsbG9jYXRlLlxuICAgICAgY29uc3QgYnVmID0gbmV3IFVpbnQ4QXJyYXkoTWF0aC5taW4oMiAqIGMgKyBuLCBNQVhfU0laRSkpO1xuICAgICAgY29weSh0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jb2ZmKSwgYnVmKTtcbiAgICAgIHRoaXMuI2J1ZiA9IGJ1ZjtcbiAgICB9XG4gICAgLy8gUmVzdG9yZSB0aGlzLiNvZmYgYW5kIGxlbih0aGlzLiNidWYpLlxuICAgIHRoaXMuI29mZiA9IDA7XG4gICAgdGhpcy4jcmVzbGljZShNYXRoLm1pbihtICsgbiwgTUFYX1NJWkUpKTtcbiAgICByZXR1cm4gbTtcbiAgfVxuXG4gIC8qKiBHcm93cyB0aGUgYnVmZmVyJ3MgY2FwYWNpdHksIGlmIG5lY2Vzc2FyeSwgdG8gZ3VhcmFudGVlIHNwYWNlIGZvclxuICAgKiBhbm90aGVyIGBuYCBieXRlcy4gQWZ0ZXIgYC5ncm93KG4pYCwgYXQgbGVhc3QgYG5gIGJ5dGVzIGNhbiBiZSB3cml0dGVuIHRvXG4gICAqIHRoZSBidWZmZXIgd2l0aG91dCBhbm90aGVyIGFsbG9jYXRpb24uIElmIGBuYCBpcyBuZWdhdGl2ZSwgYC5ncm93KClgIHdpbGxcbiAgICogdGhyb3cuIElmIHRoZSBidWZmZXIgY2FuJ3QgZ3JvdyBpdCB3aWxsIHRocm93IGFuIGVycm9yLlxuICAgKlxuICAgKiBCYXNlZCBvbiBHbyBMYW5nJ3NcbiAgICogW0J1ZmZlci5Hcm93XShodHRwczovL2dvbGFuZy5vcmcvcGtnL2J5dGVzLyNCdWZmZXIuR3JvdykuICovXG4gIGdyb3cobjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKG4gPCAwKSB7XG4gICAgICB0aHJvdyBFcnJvcihcIkJ1ZmZlci5ncm93OiBuZWdhdGl2ZSBjb3VudFwiKTtcbiAgICB9XG4gICAgY29uc3QgbSA9IHRoaXMuI2dyb3cobik7XG4gICAgdGhpcy4jcmVzbGljZShtKTtcbiAgfVxuXG4gIC8qKiBSZWFkcyBkYXRhIGZyb20gYHJgIHVudGlsIEVPRiAoYG51bGxgKSBhbmQgYXBwZW5kcyBpdCB0byB0aGUgYnVmZmVyLFxuICAgKiBncm93aW5nIHRoZSBidWZmZXIgYXMgbmVlZGVkLiBJdCByZXNvbHZlcyB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXG4gICAqIElmIHRoZSBidWZmZXIgYmVjb21lcyB0b28gbGFyZ2UsIGAucmVhZEZyb20oKWAgd2lsbCByZWplY3Qgd2l0aCBhbiBlcnJvci5cbiAgICpcbiAgICogQmFzZWQgb24gR28gTGFuZydzXG4gICAqIFtCdWZmZXIuUmVhZEZyb21dKGh0dHBzOi8vZ29sYW5nLm9yZy9wa2cvYnl0ZXMvI0J1ZmZlci5SZWFkRnJvbSkuICovXG4gIGFzeW5jIHJlYWRGcm9tKHI6IFJlYWRlcik6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgbGV0IG4gPSAwO1xuICAgIGNvbnN0IHRtcCA9IG5ldyBVaW50OEFycmF5KE1JTl9SRUFEKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3Qgc2hvdWxkR3JvdyA9IHRoaXMuY2FwYWNpdHkgLSB0aGlzLmxlbmd0aCA8IE1JTl9SRUFEO1xuICAgICAgLy8gcmVhZCBpbnRvIHRtcCBidWZmZXIgaWYgdGhlcmUncyBub3QgZW5vdWdoIHJvb21cbiAgICAgIC8vIG90aGVyd2lzZSByZWFkIGRpcmVjdGx5IGludG8gdGhlIGludGVybmFsIGJ1ZmZlclxuICAgICAgY29uc3QgYnVmID0gc2hvdWxkR3Jvd1xuICAgICAgICA/IHRtcFxuICAgICAgICA6IG5ldyBVaW50OEFycmF5KHRoaXMuI2J1Zi5idWZmZXIsIHRoaXMubGVuZ3RoKTtcblxuICAgICAgY29uc3QgbnJlYWQgPSBhd2FpdCByLnJlYWQoYnVmKTtcbiAgICAgIGlmIChucmVhZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbjtcbiAgICAgIH1cblxuICAgICAgLy8gd3JpdGUgd2lsbCBncm93IGlmIG5lZWRlZFxuICAgICAgaWYgKHNob3VsZEdyb3cpIHRoaXMud3JpdGVTeW5jKGJ1Zi5zdWJhcnJheSgwLCBucmVhZCkpO1xuICAgICAgZWxzZSB0aGlzLiNyZXNsaWNlKHRoaXMubGVuZ3RoICsgbnJlYWQpO1xuXG4gICAgICBuICs9IG5yZWFkO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZWFkcyBkYXRhIGZyb20gYHJgIHVudGlsIEVPRiAoYG51bGxgKSBhbmQgYXBwZW5kcyBpdCB0byB0aGUgYnVmZmVyLFxuICAgKiBncm93aW5nIHRoZSBidWZmZXIgYXMgbmVlZGVkLiBJdCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZC4gSWYgdGhlXG4gICAqIGJ1ZmZlciBiZWNvbWVzIHRvbyBsYXJnZSwgYC5yZWFkRnJvbVN5bmMoKWAgd2lsbCB0aHJvdyBhbiBlcnJvci5cbiAgICpcbiAgICogQmFzZWQgb24gR28gTGFuZydzXG4gICAqIFtCdWZmZXIuUmVhZEZyb21dKGh0dHBzOi8vZ29sYW5nLm9yZy9wa2cvYnl0ZXMvI0J1ZmZlci5SZWFkRnJvbSkuICovXG4gIHJlYWRGcm9tU3luYyhyOiBSZWFkZXJTeW5jKTogbnVtYmVyIHtcbiAgICBsZXQgbiA9IDA7XG4gICAgY29uc3QgdG1wID0gbmV3IFVpbnQ4QXJyYXkoTUlOX1JFQUQpO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCBzaG91bGRHcm93ID0gdGhpcy5jYXBhY2l0eSAtIHRoaXMubGVuZ3RoIDwgTUlOX1JFQUQ7XG4gICAgICAvLyByZWFkIGludG8gdG1wIGJ1ZmZlciBpZiB0aGVyZSdzIG5vdCBlbm91Z2ggcm9vbVxuICAgICAgLy8gb3RoZXJ3aXNlIHJlYWQgZGlyZWN0bHkgaW50byB0aGUgaW50ZXJuYWwgYnVmZmVyXG4gICAgICBjb25zdCBidWYgPSBzaG91bGRHcm93XG4gICAgICAgID8gdG1wXG4gICAgICAgIDogbmV3IFVpbnQ4QXJyYXkodGhpcy4jYnVmLmJ1ZmZlciwgdGhpcy5sZW5ndGgpO1xuXG4gICAgICBjb25zdCBucmVhZCA9IHIucmVhZFN5bmMoYnVmKTtcbiAgICAgIGlmIChucmVhZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbjtcbiAgICAgIH1cblxuICAgICAgLy8gd3JpdGUgd2lsbCBncm93IGlmIG5lZWRlZFxuICAgICAgaWYgKHNob3VsZEdyb3cpIHRoaXMud3JpdGVTeW5jKGJ1Zi5zdWJhcnJheSgwLCBucmVhZCkpO1xuICAgICAgZWxzZSB0aGlzLiNyZXNsaWNlKHRoaXMubGVuZ3RoICsgbnJlYWQpO1xuXG4gICAgICBuICs9IG5yZWFkO1xuICAgIH1cbiAgfVxufVxuXG5jb25zdCBERUZBVUxUX0JVRl9TSVpFID0gNDA5NjtcbmNvbnN0IE1JTl9CVUZfU0laRSA9IDE2O1xuY29uc3QgTUFYX0NPTlNFQ1VUSVZFX0VNUFRZX1JFQURTID0gMTAwO1xuY29uc3QgQ1IgPSBcIlxcclwiLmNoYXJDb2RlQXQoMCk7XG5jb25zdCBMRiA9IFwiXFxuXCIuY2hhckNvZGVBdCgwKTtcblxuZXhwb3J0IGNsYXNzIEJ1ZmZlckZ1bGxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgbmFtZSA9IFwiQnVmZmVyRnVsbEVycm9yXCI7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXJ0aWFsOiBVaW50OEFycmF5KSB7XG4gICAgc3VwZXIoXCJCdWZmZXIgZnVsbFwiKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFydGlhbFJlYWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgbmFtZSA9IFwiUGFydGlhbFJlYWRFcnJvclwiO1xuICBwYXJ0aWFsPzogVWludDhBcnJheTtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoXCJFbmNvdW50ZXJlZCBVbmV4cGVjdGVkRW9mLCBkYXRhIG9ubHkgcGFydGlhbGx5IHJlYWRcIik7XG4gIH1cbn1cblxuLyoqIFJlc3VsdCB0eXBlIHJldHVybmVkIGJ5IG9mIEJ1ZlJlYWRlci5yZWFkTGluZSgpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWFkTGluZVJlc3VsdCB7XG4gIGxpbmU6IFVpbnQ4QXJyYXk7XG4gIG1vcmU6IGJvb2xlYW47XG59XG5cbi8qKiBCdWZSZWFkZXIgaW1wbGVtZW50cyBidWZmZXJpbmcgZm9yIGEgUmVhZGVyIG9iamVjdC4gKi9cbmV4cG9ydCBjbGFzcyBCdWZSZWFkZXIgaW1wbGVtZW50cyBSZWFkZXIge1xuICAjYnVmITogVWludDhBcnJheTtcbiAgI3JkITogUmVhZGVyOyAvLyBSZWFkZXIgcHJvdmlkZWQgYnkgY2FsbGVyLlxuICAjciA9IDA7IC8vIGJ1ZiByZWFkIHBvc2l0aW9uLlxuICAjdyA9IDA7IC8vIGJ1ZiB3cml0ZSBwb3NpdGlvbi5cbiAgI2VvZiA9IGZhbHNlO1xuICAvLyBwcml2YXRlIGxhc3RCeXRlOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbGFzdENoYXJTaXplOiBudW1iZXI7XG5cbiAgLyoqIHJldHVybiBuZXcgQnVmUmVhZGVyIHVubGVzcyByIGlzIEJ1ZlJlYWRlciAqL1xuICBzdGF0aWMgY3JlYXRlKHI6IFJlYWRlciwgc2l6ZTogbnVtYmVyID0gREVGQVVMVF9CVUZfU0laRSk6IEJ1ZlJlYWRlciB7XG4gICAgcmV0dXJuIHIgaW5zdGFuY2VvZiBCdWZSZWFkZXIgPyByIDogbmV3IEJ1ZlJlYWRlcihyLCBzaXplKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHJkOiBSZWFkZXIsIHNpemU6IG51bWJlciA9IERFRkFVTFRfQlVGX1NJWkUpIHtcbiAgICBpZiAoc2l6ZSA8IE1JTl9CVUZfU0laRSkge1xuICAgICAgc2l6ZSA9IE1JTl9CVUZfU0laRTtcbiAgICB9XG4gICAgdGhpcy4jcmVzZXQobmV3IFVpbnQ4QXJyYXkoc2l6ZSksIHJkKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlciBpbiBieXRlcy4gKi9cbiAgc2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLiNidWYuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIGJ1ZmZlcmVkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuI3cgLSB0aGlzLiNyO1xuICB9XG5cbiAgLy8gUmVhZHMgYSBuZXcgY2h1bmsgaW50byB0aGUgYnVmZmVyLlxuICAjZmlsbCA9IGFzeW5jICgpID0+IHtcbiAgICAvLyBTbGlkZSBleGlzdGluZyBkYXRhIHRvIGJlZ2lubmluZy5cbiAgICBpZiAodGhpcy4jciA+IDApIHtcbiAgICAgIHRoaXMuI2J1Zi5jb3B5V2l0aGluKDAsIHRoaXMuI3IsIHRoaXMuI3cpO1xuICAgICAgdGhpcy4jdyAtPSB0aGlzLiNyO1xuICAgICAgdGhpcy4jciA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuI3cgPj0gdGhpcy4jYnVmLmJ5dGVMZW5ndGgpIHtcbiAgICAgIHRocm93IEVycm9yKFwiYnVmaW86IHRyaWVkIHRvIGZpbGwgZnVsbCBidWZmZXJcIik7XG4gICAgfVxuXG4gICAgLy8gUmVhZCBuZXcgZGF0YTogdHJ5IGEgbGltaXRlZCBudW1iZXIgb2YgdGltZXMuXG4gICAgZm9yIChsZXQgaSA9IE1BWF9DT05TRUNVVElWRV9FTVBUWV9SRUFEUzsgaSA+IDA7IGktLSkge1xuICAgICAgY29uc3QgcnIgPSBhd2FpdCB0aGlzLiNyZC5yZWFkKHRoaXMuI2J1Zi5zdWJhcnJheSh0aGlzLiN3KSk7XG4gICAgICBpZiAocnIgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy4jZW9mID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXNzZXJ0KHJyID49IDAsIFwibmVnYXRpdmUgcmVhZFwiKTtcbiAgICAgIHRoaXMuI3cgKz0gcnI7XG4gICAgICBpZiAocnIgPiAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTm8gcHJvZ3Jlc3MgYWZ0ZXIgJHtNQVhfQ09OU0VDVVRJVkVfRU1QVFlfUkVBRFN9IHJlYWQoKSBjYWxsc2AsXG4gICAgKTtcbiAgfTtcblxuICAvKiogRGlzY2FyZHMgYW55IGJ1ZmZlcmVkIGRhdGEsIHJlc2V0cyBhbGwgc3RhdGUsIGFuZCBzd2l0Y2hlc1xuICAgKiB0aGUgYnVmZmVyZWQgcmVhZGVyIHRvIHJlYWQgZnJvbSByLlxuICAgKi9cbiAgcmVzZXQocjogUmVhZGVyKTogdm9pZCB7XG4gICAgdGhpcy4jcmVzZXQodGhpcy4jYnVmLCByKTtcbiAgfVxuXG4gICNyZXNldCA9IChidWY6IFVpbnQ4QXJyYXksIHJkOiBSZWFkZXIpOiB2b2lkID0+IHtcbiAgICB0aGlzLiNidWYgPSBidWY7XG4gICAgdGhpcy4jcmQgPSByZDtcbiAgICB0aGlzLiNlb2YgPSBmYWxzZTtcbiAgICAvLyB0aGlzLmxhc3RCeXRlID0gLTE7XG4gICAgLy8gdGhpcy5sYXN0Q2hhclNpemUgPSAtMTtcbiAgfTtcblxuICAvKiogcmVhZHMgZGF0YSBpbnRvIHAuXG4gICAqIEl0IHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZWFkIGludG8gcC5cbiAgICogVGhlIGJ5dGVzIGFyZSB0YWtlbiBmcm9tIGF0IG1vc3Qgb25lIFJlYWQgb24gdGhlIHVuZGVybHlpbmcgUmVhZGVyLFxuICAgKiBoZW5jZSBuIG1heSBiZSBsZXNzIHRoYW4gbGVuKHApLlxuICAgKiBUbyByZWFkIGV4YWN0bHkgbGVuKHApIGJ5dGVzLCB1c2UgaW8uUmVhZEZ1bGwoYiwgcCkuXG4gICAqL1xuICBhc3luYyByZWFkKHA6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPG51bWJlciB8IG51bGw+IHtcbiAgICBsZXQgcnI6IG51bWJlciB8IG51bGwgPSBwLmJ5dGVMZW5ndGg7XG4gICAgaWYgKHAuYnl0ZUxlbmd0aCA9PT0gMCkgcmV0dXJuIHJyO1xuXG4gICAgaWYgKHRoaXMuI3IgPT09IHRoaXMuI3cpIHtcbiAgICAgIGlmIChwLmJ5dGVMZW5ndGggPj0gdGhpcy4jYnVmLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgLy8gTGFyZ2UgcmVhZCwgZW1wdHkgYnVmZmVyLlxuICAgICAgICAvLyBSZWFkIGRpcmVjdGx5IGludG8gcCB0byBhdm9pZCBjb3B5LlxuICAgICAgICBjb25zdCByciA9IGF3YWl0IHRoaXMuI3JkLnJlYWQocCk7XG4gICAgICAgIGNvbnN0IG5yZWFkID0gcnIgPz8gMDtcbiAgICAgICAgYXNzZXJ0KG5yZWFkID49IDAsIFwibmVnYXRpdmUgcmVhZFwiKTtcbiAgICAgICAgLy8gaWYgKHJyLm5yZWFkID4gMCkge1xuICAgICAgICAvLyAgIHRoaXMubGFzdEJ5dGUgPSBwW3JyLm5yZWFkIC0gMV07XG4gICAgICAgIC8vICAgdGhpcy5sYXN0Q2hhclNpemUgPSAtMTtcbiAgICAgICAgLy8gfVxuICAgICAgICByZXR1cm4gcnI7XG4gICAgICB9XG5cbiAgICAgIC8vIE9uZSByZWFkLlxuICAgICAgLy8gRG8gbm90IHVzZSB0aGlzLmZpbGwsIHdoaWNoIHdpbGwgbG9vcC5cbiAgICAgIHRoaXMuI3IgPSAwO1xuICAgICAgdGhpcy4jdyA9IDA7XG4gICAgICByciA9IGF3YWl0IHRoaXMuI3JkLnJlYWQodGhpcy4jYnVmKTtcbiAgICAgIGlmIChyciA9PT0gMCB8fCByciA9PT0gbnVsbCkgcmV0dXJuIHJyO1xuICAgICAgYXNzZXJ0KHJyID49IDAsIFwibmVnYXRpdmUgcmVhZFwiKTtcbiAgICAgIHRoaXMuI3cgKz0gcnI7XG4gICAgfVxuXG4gICAgLy8gY29weSBhcyBtdWNoIGFzIHdlIGNhblxuICAgIGNvbnN0IGNvcGllZCA9IGNvcHkodGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3cpLCBwLCAwKTtcbiAgICB0aGlzLiNyICs9IGNvcGllZDtcbiAgICAvLyB0aGlzLmxhc3RCeXRlID0gdGhpcy5idWZbdGhpcy5yIC0gMV07XG4gICAgLy8gdGhpcy5sYXN0Q2hhclNpemUgPSAtMTtcbiAgICByZXR1cm4gY29waWVkO1xuICB9XG5cbiAgLyoqIHJlYWRzIGV4YWN0bHkgYHAubGVuZ3RoYCBieXRlcyBpbnRvIGBwYC5cbiAgICpcbiAgICogSWYgc3VjY2Vzc2Z1bCwgYHBgIGlzIHJldHVybmVkLlxuICAgKlxuICAgKiBJZiB0aGUgZW5kIG9mIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLCBhbmQgdGhlcmUgYXJlIG5vIG1vcmVcbiAgICogYnl0ZXMgYXZhaWxhYmxlIGluIHRoZSBidWZmZXIsIGByZWFkRnVsbCgpYCByZXR1cm5zIGBudWxsYCBpbnN0ZWFkLlxuICAgKlxuICAgKiBBbiBlcnJvciBpcyB0aHJvd24gaWYgc29tZSBieXRlcyBjb3VsZCBiZSByZWFkLCBidXQgbm90IGVub3VnaCB0byBmaWxsIGBwYFxuICAgKiBlbnRpcmVseSBiZWZvcmUgdGhlIHVuZGVybHlpbmcgc3RyZWFtIHJlcG9ydGVkIGFuIGVycm9yIG9yIEVPRi4gQW55IGVycm9yXG4gICAqIHRocm93biB3aWxsIGhhdmUgYSBgcGFydGlhbGAgcHJvcGVydHkgdGhhdCBpbmRpY2F0ZXMgdGhlIHNsaWNlIG9mIHRoZVxuICAgKiBidWZmZXIgdGhhdCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgZmlsbGVkIHdpdGggZGF0YS5cbiAgICpcbiAgICogUG9ydGVkIGZyb20gaHR0cHM6Ly9nb2xhbmcub3JnL3BrZy9pby8jUmVhZEZ1bGxcbiAgICovXG4gIGFzeW5jIHJlYWRGdWxsKHA6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCBudWxsPiB7XG4gICAgbGV0IGJ5dGVzUmVhZCA9IDA7XG4gICAgd2hpbGUgKGJ5dGVzUmVhZCA8IHAubGVuZ3RoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByciA9IGF3YWl0IHRoaXMucmVhZChwLnN1YmFycmF5KGJ5dGVzUmVhZCkpO1xuICAgICAgICBpZiAocnIgPT09IG51bGwpIHtcbiAgICAgICAgICBpZiAoYnl0ZXNSZWFkID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnRpYWxSZWFkRXJyb3IoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnl0ZXNSZWFkICs9IHJyO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJ0aWFsUmVhZEVycm9yKSB7XG4gICAgICAgICAgZXJyLnBhcnRpYWwgPSBwLnN1YmFycmF5KDAsIGJ5dGVzUmVhZCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBlID0gbmV3IFBhcnRpYWxSZWFkRXJyb3IoKTtcbiAgICAgICAgICBlLnBhcnRpYWwgPSBwLnN1YmFycmF5KDAsIGJ5dGVzUmVhZCk7XG4gICAgICAgICAgZS5zdGFjayA9IGVyci5zdGFjaztcbiAgICAgICAgICBlLm1lc3NhZ2UgPSBlcnIubWVzc2FnZTtcbiAgICAgICAgICBlLmNhdXNlID0gZXJyLmNhdXNlO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwO1xuICB9XG5cbiAgLyoqIFJldHVybnMgdGhlIG5leHQgYnl0ZSBbMCwgMjU1XSBvciBgbnVsbGAuICovXG4gIGFzeW5jIHJlYWRCeXRlKCk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgIHdoaWxlICh0aGlzLiNyID09PSB0aGlzLiN3KSB7XG4gICAgICBpZiAodGhpcy4jZW9mKSByZXR1cm4gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMuI2ZpbGwoKTsgLy8gYnVmZmVyIGlzIGVtcHR5LlxuICAgIH1cbiAgICBjb25zdCBjID0gdGhpcy4jYnVmW3RoaXMuI3JdO1xuICAgIHRoaXMuI3IrKztcbiAgICAvLyB0aGlzLmxhc3RCeXRlID0gYztcbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIC8qKiByZWFkU3RyaW5nKCkgcmVhZHMgdW50aWwgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgZGVsaW0gaW4gdGhlIGlucHV0LFxuICAgKiByZXR1cm5pbmcgYSBzdHJpbmcgY29udGFpbmluZyB0aGUgZGF0YSB1cCB0byBhbmQgaW5jbHVkaW5nIHRoZSBkZWxpbWl0ZXIuXG4gICAqIElmIFJlYWRTdHJpbmcgZW5jb3VudGVycyBhbiBlcnJvciBiZWZvcmUgZmluZGluZyBhIGRlbGltaXRlcixcbiAgICogaXQgcmV0dXJucyB0aGUgZGF0YSByZWFkIGJlZm9yZSB0aGUgZXJyb3IgYW5kIHRoZSBlcnJvciBpdHNlbGZcbiAgICogKG9mdGVuIGBudWxsYCkuXG4gICAqIFJlYWRTdHJpbmcgcmV0dXJucyBlcnIgIT0gbmlsIGlmIGFuZCBvbmx5IGlmIHRoZSByZXR1cm5lZCBkYXRhIGRvZXMgbm90IGVuZFxuICAgKiBpbiBkZWxpbS5cbiAgICogRm9yIHNpbXBsZSB1c2VzLCBhIFNjYW5uZXIgbWF5IGJlIG1vcmUgY29udmVuaWVudC5cbiAgICovXG4gIGFzeW5jIHJlYWRTdHJpbmcoZGVsaW06IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGlmIChkZWxpbS5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkRlbGltaXRlciBzaG91bGQgYmUgYSBzaW5nbGUgY2hhcmFjdGVyXCIpO1xuICAgIH1cbiAgICBjb25zdCBidWZmZXIgPSBhd2FpdCB0aGlzLnJlYWRTbGljZShkZWxpbS5jaGFyQ29kZUF0KDApKTtcbiAgICBpZiAoYnVmZmVyID09PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJ1ZmZlcik7XG4gIH1cblxuICAvKiogYHJlYWRMaW5lKClgIGlzIGEgbG93LWxldmVsIGxpbmUtcmVhZGluZyBwcmltaXRpdmUuIE1vc3QgY2FsbGVycyBzaG91bGRcbiAgICogdXNlIGByZWFkU3RyaW5nKCdcXG4nKWAgaW5zdGVhZCBvciB1c2UgYSBTY2FubmVyLlxuICAgKlxuICAgKiBgcmVhZExpbmUoKWAgdHJpZXMgdG8gcmV0dXJuIGEgc2luZ2xlIGxpbmUsIG5vdCBpbmNsdWRpbmcgdGhlIGVuZC1vZi1saW5lXG4gICAqIGJ5dGVzLiBJZiB0aGUgbGluZSB3YXMgdG9vIGxvbmcgZm9yIHRoZSBidWZmZXIgdGhlbiBgbW9yZWAgaXMgc2V0IGFuZCB0aGVcbiAgICogYmVnaW5uaW5nIG9mIHRoZSBsaW5lIGlzIHJldHVybmVkLiBUaGUgcmVzdCBvZiB0aGUgbGluZSB3aWxsIGJlIHJldHVybmVkXG4gICAqIGZyb20gZnV0dXJlIGNhbGxzLiBgbW9yZWAgd2lsbCBiZSBmYWxzZSB3aGVuIHJldHVybmluZyB0aGUgbGFzdCBmcmFnbWVudFxuICAgKiBvZiB0aGUgbGluZS4gVGhlIHJldHVybmVkIGJ1ZmZlciBpcyBvbmx5IHZhbGlkIHVudGlsIHRoZSBuZXh0IGNhbGwgdG9cbiAgICogYHJlYWRMaW5lKClgLlxuICAgKlxuICAgKiBUaGUgdGV4dCByZXR1cm5lZCBmcm9tIFJlYWRMaW5lIGRvZXMgbm90IGluY2x1ZGUgdGhlIGxpbmUgZW5kIChcIlxcclxcblwiIG9yXG4gICAqIFwiXFxuXCIpLlxuICAgKlxuICAgKiBXaGVuIHRoZSBlbmQgb2YgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGlzIHJlYWNoZWQsIHRoZSBmaW5hbCBieXRlcyBpbiB0aGVcbiAgICogc3RyZWFtIGFyZSByZXR1cm5lZC4gTm8gaW5kaWNhdGlvbiBvciBlcnJvciBpcyBnaXZlbiBpZiB0aGUgaW5wdXQgZW5kc1xuICAgKiB3aXRob3V0IGEgZmluYWwgbGluZSBlbmQuIFdoZW4gdGhlcmUgYXJlIG5vIG1vcmUgdHJhaWxpbmcgYnl0ZXMgdG8gcmVhZCxcbiAgICogYHJlYWRMaW5lKClgIHJldHVybnMgYG51bGxgLlxuICAgKlxuICAgKiBDYWxsaW5nIGB1bnJlYWRCeXRlKClgIGFmdGVyIGByZWFkTGluZSgpYCB3aWxsIGFsd2F5cyB1bnJlYWQgdGhlIGxhc3QgYnl0ZVxuICAgKiByZWFkIChwb3NzaWJseSBhIGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gdGhlIGxpbmUgZW5kKSBldmVuIGlmIHRoYXQgYnl0ZSBpc1xuICAgKiBub3QgcGFydCBvZiB0aGUgbGluZSByZXR1cm5lZCBieSBgcmVhZExpbmUoKWAuXG4gICAqL1xuICBhc3luYyByZWFkTGluZSgpOiBQcm9taXNlPFJlYWRMaW5lUmVzdWx0IHwgbnVsbD4ge1xuICAgIGxldCBsaW5lOiBVaW50OEFycmF5IHwgbnVsbCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgbGluZSA9IGF3YWl0IHRoaXMucmVhZFNsaWNlKExGKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBEZW5vLmVycm9ycy5CYWRSZXNvdXJjZSkge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgICBsZXQgcGFydGlhbDtcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJ0aWFsUmVhZEVycm9yKSB7XG4gICAgICAgIHBhcnRpYWwgPSBlcnIucGFydGlhbDtcbiAgICAgICAgYXNzZXJ0KFxuICAgICAgICAgIHBhcnRpYWwgaW5zdGFuY2VvZiBVaW50OEFycmF5LFxuICAgICAgICAgIFwiYnVmaW86IGNhdWdodCBlcnJvciBmcm9tIGByZWFkU2xpY2UoKWAgd2l0aG91dCBgcGFydGlhbGAgcHJvcGVydHlcIixcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gRG9uJ3QgdGhyb3cgaWYgYHJlYWRTbGljZSgpYCBmYWlsZWQgd2l0aCBgQnVmZmVyRnVsbEVycm9yYCwgaW5zdGVhZCB3ZVxuICAgICAgLy8ganVzdCByZXR1cm4gd2hhdGV2ZXIgaXMgYXZhaWxhYmxlIGFuZCBzZXQgdGhlIGBtb3JlYCBmbGFnLlxuICAgICAgaWYgKCEoZXJyIGluc3RhbmNlb2YgQnVmZmVyRnVsbEVycm9yKSkge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG5cbiAgICAgIHBhcnRpYWwgPSBlcnIucGFydGlhbDtcblxuICAgICAgLy8gSGFuZGxlIHRoZSBjYXNlIHdoZXJlIFwiXFxyXFxuXCIgc3RyYWRkbGVzIHRoZSBidWZmZXIuXG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLiNlb2YgJiYgcGFydGlhbCAmJlxuICAgICAgICBwYXJ0aWFsLmJ5dGVMZW5ndGggPiAwICYmXG4gICAgICAgIHBhcnRpYWxbcGFydGlhbC5ieXRlTGVuZ3RoIC0gMV0gPT09IENSXG4gICAgICApIHtcbiAgICAgICAgLy8gUHV0IHRoZSAnXFxyJyBiYWNrIG9uIGJ1ZiBhbmQgZHJvcCBpdCBmcm9tIGxpbmUuXG4gICAgICAgIC8vIExldCB0aGUgbmV4dCBjYWxsIHRvIFJlYWRMaW5lIGNoZWNrIGZvciBcIlxcclxcblwiLlxuICAgICAgICBhc3NlcnQodGhpcy4jciA+IDAsIFwiYnVmaW86IHRyaWVkIHRvIHJld2luZCBwYXN0IHN0YXJ0IG9mIGJ1ZmZlclwiKTtcbiAgICAgICAgdGhpcy4jci0tO1xuICAgICAgICBwYXJ0aWFsID0gcGFydGlhbC5zdWJhcnJheSgwLCBwYXJ0aWFsLmJ5dGVMZW5ndGggLSAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcnRpYWwpIHtcbiAgICAgICAgcmV0dXJuIHsgbGluZTogcGFydGlhbCwgbW9yZTogIXRoaXMuI2VvZiB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChsaW5lID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAobGluZS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4geyBsaW5lLCBtb3JlOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIGlmIChsaW5lW2xpbmUuYnl0ZUxlbmd0aCAtIDFdID09IExGKSB7XG4gICAgICBsZXQgZHJvcCA9IDE7XG4gICAgICBpZiAobGluZS5ieXRlTGVuZ3RoID4gMSAmJiBsaW5lW2xpbmUuYnl0ZUxlbmd0aCAtIDJdID09PSBDUikge1xuICAgICAgICBkcm9wID0gMjtcbiAgICAgIH1cbiAgICAgIGxpbmUgPSBsaW5lLnN1YmFycmF5KDAsIGxpbmUuYnl0ZUxlbmd0aCAtIGRyb3ApO1xuICAgIH1cbiAgICByZXR1cm4geyBsaW5lLCBtb3JlOiBmYWxzZSB9O1xuICB9XG5cbiAgLyoqIGByZWFkU2xpY2UoKWAgcmVhZHMgdW50aWwgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYGRlbGltYCBpbiB0aGUgaW5wdXQsXG4gICAqIHJldHVybmluZyBhIHNsaWNlIHBvaW50aW5nIGF0IHRoZSBieXRlcyBpbiB0aGUgYnVmZmVyLiBUaGUgYnl0ZXMgc3RvcFxuICAgKiBiZWluZyB2YWxpZCBhdCB0aGUgbmV4dCByZWFkLlxuICAgKlxuICAgKiBJZiBgcmVhZFNsaWNlKClgIGVuY291bnRlcnMgYW4gZXJyb3IgYmVmb3JlIGZpbmRpbmcgYSBkZWxpbWl0ZXIsIG9yIHRoZVxuICAgKiBidWZmZXIgZmlsbHMgd2l0aG91dCBmaW5kaW5nIGEgZGVsaW1pdGVyLCBpdCB0aHJvd3MgYW4gZXJyb3Igd2l0aCBhXG4gICAqIGBwYXJ0aWFsYCBwcm9wZXJ0eSB0aGF0IGNvbnRhaW5zIHRoZSBlbnRpcmUgYnVmZmVyLlxuICAgKlxuICAgKiBJZiBgcmVhZFNsaWNlKClgIGVuY291bnRlcnMgdGhlIGVuZCBvZiB0aGUgdW5kZXJseWluZyBzdHJlYW0gYW5kIHRoZXJlIGFyZVxuICAgKiBhbnkgYnl0ZXMgbGVmdCBpbiB0aGUgYnVmZmVyLCB0aGUgcmVzdCBvZiB0aGUgYnVmZmVyIGlzIHJldHVybmVkLiBJbiBvdGhlclxuICAgKiB3b3JkcywgRU9GIGlzIGFsd2F5cyB0cmVhdGVkIGFzIGEgZGVsaW1pdGVyLiBPbmNlIHRoZSBidWZmZXIgaXMgZW1wdHksXG4gICAqIGl0IHJldHVybnMgYG51bGxgLlxuICAgKlxuICAgKiBCZWNhdXNlIHRoZSBkYXRhIHJldHVybmVkIGZyb20gYHJlYWRTbGljZSgpYCB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IHRoZVxuICAgKiBuZXh0IEkvTyBvcGVyYXRpb24sIG1vc3QgY2xpZW50cyBzaG91bGQgdXNlIGByZWFkU3RyaW5nKClgIGluc3RlYWQuXG4gICAqL1xuICBhc3luYyByZWFkU2xpY2UoZGVsaW06IG51bWJlcik6IFByb21pc2U8VWludDhBcnJheSB8IG51bGw+IHtcbiAgICBsZXQgcyA9IDA7IC8vIHNlYXJjaCBzdGFydCBpbmRleFxuICAgIGxldCBzbGljZTogVWludDhBcnJheSB8IHVuZGVmaW5lZDtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAvLyBTZWFyY2ggYnVmZmVyLlxuICAgICAgbGV0IGkgPSB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciArIHMsIHRoaXMuI3cpLmluZGV4T2YoZGVsaW0pO1xuICAgICAgaWYgKGkgPj0gMCkge1xuICAgICAgICBpICs9IHM7XG4gICAgICAgIHNsaWNlID0gdGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3IgKyBpICsgMSk7XG4gICAgICAgIHRoaXMuI3IgKz0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBFT0Y/XG4gICAgICBpZiAodGhpcy4jZW9mKSB7XG4gICAgICAgIGlmICh0aGlzLiNyID09PSB0aGlzLiN3KSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgc2xpY2UgPSB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jdyk7XG4gICAgICAgIHRoaXMuI3IgPSB0aGlzLiN3O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gQnVmZmVyIGZ1bGw/XG4gICAgICBpZiAodGhpcy5idWZmZXJlZCgpID49IHRoaXMuI2J1Zi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuI3IgPSB0aGlzLiN3O1xuICAgICAgICAvLyAjNDUyMSBUaGUgaW50ZXJuYWwgYnVmZmVyIHNob3VsZCBub3QgYmUgcmV1c2VkIGFjcm9zcyByZWFkcyBiZWNhdXNlIGl0IGNhdXNlcyBjb3JydXB0aW9uIG9mIGRhdGEuXG4gICAgICAgIGNvbnN0IG9sZGJ1ZiA9IHRoaXMuI2J1ZjtcbiAgICAgICAgY29uc3QgbmV3YnVmID0gdGhpcy4jYnVmLnNsaWNlKDApO1xuICAgICAgICB0aGlzLiNidWYgPSBuZXdidWY7XG4gICAgICAgIHRocm93IG5ldyBCdWZmZXJGdWxsRXJyb3Iob2xkYnVmKTtcbiAgICAgIH1cblxuICAgICAgcyA9IHRoaXMuI3cgLSB0aGlzLiNyOyAvLyBkbyBub3QgcmVzY2FuIGFyZWEgd2Ugc2Nhbm5lZCBiZWZvcmVcblxuICAgICAgLy8gQnVmZmVyIGlzIG5vdCBmdWxsLlxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy4jZmlsbCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJ0aWFsUmVhZEVycm9yKSB7XG4gICAgICAgICAgZXJyLnBhcnRpYWwgPSBzbGljZTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIGNvbnN0IGUgPSBuZXcgUGFydGlhbFJlYWRFcnJvcigpO1xuICAgICAgICAgIGUucGFydGlhbCA9IHNsaWNlO1xuICAgICAgICAgIGUuc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgICAgICAgZS5tZXNzYWdlID0gZXJyLm1lc3NhZ2U7XG4gICAgICAgICAgZS5jYXVzZSA9IGVyci5jYXVzZTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBsYXN0IGJ5dGUsIGlmIGFueS5cbiAgICAvLyBjb25zdCBpID0gc2xpY2UuYnl0ZUxlbmd0aCAtIDE7XG4gICAgLy8gaWYgKGkgPj0gMCkge1xuICAgIC8vICAgdGhpcy5sYXN0Qnl0ZSA9IHNsaWNlW2ldO1xuICAgIC8vICAgdGhpcy5sYXN0Q2hhclNpemUgPSAtMVxuICAgIC8vIH1cblxuICAgIHJldHVybiBzbGljZTtcbiAgfVxuXG4gIC8qKiBgcGVlaygpYCByZXR1cm5zIHRoZSBuZXh0IGBuYCBieXRlcyB3aXRob3V0IGFkdmFuY2luZyB0aGUgcmVhZGVyLiBUaGVcbiAgICogYnl0ZXMgc3RvcCBiZWluZyB2YWxpZCBhdCB0aGUgbmV4dCByZWFkIGNhbGwuXG4gICAqXG4gICAqIFdoZW4gdGhlIGVuZCBvZiB0aGUgdW5kZXJseWluZyBzdHJlYW0gaXMgcmVhY2hlZCwgYnV0IHRoZXJlIGFyZSB1bnJlYWRcbiAgICogYnl0ZXMgbGVmdCBpbiB0aGUgYnVmZmVyLCB0aG9zZSBieXRlcyBhcmUgcmV0dXJuZWQuIElmIHRoZXJlIGFyZSBubyBieXRlc1xuICAgKiBsZWZ0IGluIHRoZSBidWZmZXIsIGl0IHJldHVybnMgYG51bGxgLlxuICAgKlxuICAgKiBJZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZCBiZWZvcmUgYG5gIGJ5dGVzIGFyZSBhdmFpbGFibGUsIGBwZWVrKClgIHRocm93c1xuICAgKiBhbiBlcnJvciB3aXRoIHRoZSBgcGFydGlhbGAgcHJvcGVydHkgc2V0IHRvIGEgc2xpY2Ugb2YgdGhlIGJ1ZmZlciB0aGF0XG4gICAqIGNvbnRhaW5zIHRoZSBieXRlcyB0aGF0IHdlcmUgYXZhaWxhYmxlIGJlZm9yZSB0aGUgZXJyb3Igb2NjdXJyZWQuXG4gICAqL1xuICBhc3luYyBwZWVrKG46IG51bWJlcik6IFByb21pc2U8VWludDhBcnJheSB8IG51bGw+IHtcbiAgICBpZiAobiA8IDApIHtcbiAgICAgIHRocm93IEVycm9yKFwibmVnYXRpdmUgY291bnRcIik7XG4gICAgfVxuXG4gICAgbGV0IGF2YWlsID0gdGhpcy4jdyAtIHRoaXMuI3I7XG4gICAgd2hpbGUgKGF2YWlsIDwgbiAmJiBhdmFpbCA8IHRoaXMuI2J1Zi5ieXRlTGVuZ3RoICYmICF0aGlzLiNlb2YpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuI2ZpbGwoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgUGFydGlhbFJlYWRFcnJvcikge1xuICAgICAgICAgIGVyci5wYXJ0aWFsID0gdGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3cpO1xuICAgICAgICB9IGVsc2UgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgY29uc3QgZSA9IG5ldyBQYXJ0aWFsUmVhZEVycm9yKCk7XG4gICAgICAgICAgZS5wYXJ0aWFsID0gdGhpcy4jYnVmLnN1YmFycmF5KHRoaXMuI3IsIHRoaXMuI3cpO1xuICAgICAgICAgIGUuc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgICAgICAgZS5tZXNzYWdlID0gZXJyLm1lc3NhZ2U7XG4gICAgICAgICAgZS5jYXVzZSA9IGVyci5jYXVzZTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgICAgYXZhaWwgPSB0aGlzLiN3IC0gdGhpcy4jcjtcbiAgICB9XG5cbiAgICBpZiAoYXZhaWwgPT09IDAgJiYgdGhpcy4jZW9mKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2UgaWYgKGF2YWlsIDwgbiAmJiB0aGlzLiNlb2YpIHtcbiAgICAgIHJldHVybiB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jciArIGF2YWlsKTtcbiAgICB9IGVsc2UgaWYgKGF2YWlsIDwgbikge1xuICAgICAgdGhyb3cgbmV3IEJ1ZmZlckZ1bGxFcnJvcih0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jdykpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLiNidWYuc3ViYXJyYXkodGhpcy4jciwgdGhpcy4jciArIG4pO1xuICB9XG59XG5cbmFic3RyYWN0IGNsYXNzIEFic3RyYWN0QnVmQmFzZSB7XG4gIGJ1ZjogVWludDhBcnJheTtcbiAgdXNlZEJ1ZmZlckJ5dGVzID0gMDtcbiAgZXJyOiBFcnJvciB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKGJ1ZjogVWludDhBcnJheSkge1xuICAgIHRoaXMuYnVmID0gYnVmO1xuICB9XG5cbiAgLyoqIFNpemUgcmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgdW5kZXJseWluZyBidWZmZXIgaW4gYnl0ZXMuICovXG4gIHNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5idWYuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIGhvdyBtYW55IGJ5dGVzIGFyZSB1bnVzZWQgaW4gdGhlIGJ1ZmZlci4gKi9cbiAgYXZhaWxhYmxlKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYnVmLmJ5dGVMZW5ndGggLSB0aGlzLnVzZWRCdWZmZXJCeXRlcztcbiAgfVxuXG4gIC8qKiBidWZmZXJlZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gd3JpdHRlbiBpbnRvIHRoZVxuICAgKiBjdXJyZW50IGJ1ZmZlci5cbiAgICovXG4gIGJ1ZmZlcmVkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudXNlZEJ1ZmZlckJ5dGVzO1xuICB9XG59XG5cbi8qKiBCdWZXcml0ZXIgaW1wbGVtZW50cyBidWZmZXJpbmcgZm9yIGFuIGRlbm8uV3JpdGVyIG9iamVjdC5cbiAqIElmIGFuIGVycm9yIG9jY3VycyB3cml0aW5nIHRvIGEgV3JpdGVyLCBubyBtb3JlIGRhdGEgd2lsbCBiZVxuICogYWNjZXB0ZWQgYW5kIGFsbCBzdWJzZXF1ZW50IHdyaXRlcywgYW5kIGZsdXNoKCksIHdpbGwgcmV0dXJuIHRoZSBlcnJvci5cbiAqIEFmdGVyIGFsbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4sIHRoZSBjbGllbnQgc2hvdWxkIGNhbGwgdGhlXG4gKiBmbHVzaCgpIG1ldGhvZCB0byBndWFyYW50ZWUgYWxsIGRhdGEgaGFzIGJlZW4gZm9yd2FyZGVkIHRvXG4gKiB0aGUgdW5kZXJseWluZyBkZW5vLldyaXRlci5cbiAqL1xuZXhwb3J0IGNsYXNzIEJ1ZldyaXRlciBleHRlbmRzIEFic3RyYWN0QnVmQmFzZSBpbXBsZW1lbnRzIFdyaXRlciB7XG4gICN3cml0ZXI6IFdyaXRlcjtcblxuICAvKiogcmV0dXJuIG5ldyBCdWZXcml0ZXIgdW5sZXNzIHdyaXRlciBpcyBCdWZXcml0ZXIgKi9cbiAgc3RhdGljIGNyZWF0ZSh3cml0ZXI6IFdyaXRlciwgc2l6ZTogbnVtYmVyID0gREVGQVVMVF9CVUZfU0laRSk6IEJ1ZldyaXRlciB7XG4gICAgcmV0dXJuIHdyaXRlciBpbnN0YW5jZW9mIEJ1ZldyaXRlciA/IHdyaXRlciA6IG5ldyBCdWZXcml0ZXIod3JpdGVyLCBzaXplKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHdyaXRlcjogV3JpdGVyLCBzaXplOiBudW1iZXIgPSBERUZBVUxUX0JVRl9TSVpFKSB7XG4gICAgc3VwZXIobmV3IFVpbnQ4QXJyYXkoc2l6ZSA8PSAwID8gREVGQVVMVF9CVUZfU0laRSA6IHNpemUpKTtcbiAgICB0aGlzLiN3cml0ZXIgPSB3cml0ZXI7XG4gIH1cblxuICAvKiogRGlzY2FyZHMgYW55IHVuZmx1c2hlZCBidWZmZXJlZCBkYXRhLCBjbGVhcnMgYW55IGVycm9yLCBhbmRcbiAgICogcmVzZXRzIGJ1ZmZlciB0byB3cml0ZSBpdHMgb3V0cHV0IHRvIHcuXG4gICAqL1xuICByZXNldCh3OiBXcml0ZXIpOiB2b2lkIHtcbiAgICB0aGlzLmVyciA9IG51bGw7XG4gICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgPSAwO1xuICAgIHRoaXMuI3dyaXRlciA9IHc7XG4gIH1cblxuICAvKiogRmx1c2ggd3JpdGVzIGFueSBidWZmZXJlZCBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIGlvLldyaXRlci4gKi9cbiAgYXN5bmMgZmx1c2goKSB7XG4gICAgaWYgKHRoaXMuZXJyICE9PSBudWxsKSB0aHJvdyB0aGlzLmVycjtcbiAgICBpZiAodGhpcy51c2VkQnVmZmVyQnl0ZXMgPT09IDApIHJldHVybjtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwID0gdGhpcy5idWYuc3ViYXJyYXkoMCwgdGhpcy51c2VkQnVmZmVyQnl0ZXMpO1xuICAgICAgbGV0IG53cml0dGVuID0gMDtcbiAgICAgIHdoaWxlIChud3JpdHRlbiA8IHAubGVuZ3RoKSB7XG4gICAgICAgIG53cml0dGVuICs9IGF3YWl0IHRoaXMuI3dyaXRlci53cml0ZShwLnN1YmFycmF5KG53cml0dGVuKSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aGlzLmVyciA9IGU7XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIHRoaXMuYnVmID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5idWYubGVuZ3RoKTtcbiAgICB0aGlzLnVzZWRCdWZmZXJCeXRlcyA9IDA7XG4gIH1cblxuICAvKiogV3JpdGVzIHRoZSBjb250ZW50cyBvZiBgZGF0YWAgaW50byB0aGUgYnVmZmVyLiAgSWYgdGhlIGNvbnRlbnRzIHdvbid0IGZ1bGx5XG4gICAqIGZpdCBpbnRvIHRoZSBidWZmZXIsIHRob3NlIGJ5dGVzIHRoYXQgY2FuIGFyZSBjb3BpZWQgaW50byB0aGUgYnVmZmVyLCB0aGVcbiAgICogYnVmZmVyIGlzIHRoZSBmbHVzaGVkIHRvIHRoZSB3cml0ZXIgYW5kIHRoZSByZW1haW5pbmcgYnl0ZXMgYXJlIGNvcGllZCBpbnRvXG4gICAqIHRoZSBub3cgZW1wdHkgYnVmZmVyLlxuICAgKlxuICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUgYnVmZmVyLlxuICAgKi9cbiAgYXN5bmMgd3JpdGUoZGF0YTogVWludDhBcnJheSk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgaWYgKHRoaXMuZXJyICE9PSBudWxsKSB0aHJvdyB0aGlzLmVycjtcbiAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiAwO1xuXG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICBsZXQgbnVtQnl0ZXNXcml0dGVuID0gMDtcbiAgICB3aGlsZSAoZGF0YS5ieXRlTGVuZ3RoID4gdGhpcy5hdmFpbGFibGUoKSkge1xuICAgICAgaWYgKHRoaXMuYnVmZmVyZWQoKSA9PT0gMCkge1xuICAgICAgICAvLyBMYXJnZSB3cml0ZSwgZW1wdHkgYnVmZmVyLlxuICAgICAgICAvLyBXcml0ZSBkaXJlY3RseSBmcm9tIGRhdGEgdG8gYXZvaWQgY29weS5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBudW1CeXRlc1dyaXR0ZW4gPSBhd2FpdCB0aGlzLiN3cml0ZXIud3JpdGUoZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVyciA9IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG51bUJ5dGVzV3JpdHRlbiA9IGNvcHkoZGF0YSwgdGhpcy5idWYsIHRoaXMudXNlZEJ1ZmZlckJ5dGVzKTtcbiAgICAgICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgICAgICBhd2FpdCB0aGlzLmZsdXNoKCk7XG4gICAgICB9XG4gICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBudW1CeXRlc1dyaXR0ZW47XG4gICAgICBkYXRhID0gZGF0YS5zdWJhcnJheShudW1CeXRlc1dyaXR0ZW4pO1xuICAgIH1cblxuICAgIG51bUJ5dGVzV3JpdHRlbiA9IGNvcHkoZGF0YSwgdGhpcy5idWYsIHRoaXMudXNlZEJ1ZmZlckJ5dGVzKTtcbiAgICB0aGlzLnVzZWRCdWZmZXJCeXRlcyArPSBudW1CeXRlc1dyaXR0ZW47XG4gICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgIHJldHVybiB0b3RhbEJ5dGVzV3JpdHRlbjtcbiAgfVxufVxuXG4vKiogQnVmV3JpdGVyU3luYyBpbXBsZW1lbnRzIGJ1ZmZlcmluZyBmb3IgYSBkZW5vLldyaXRlclN5bmMgb2JqZWN0LlxuICogSWYgYW4gZXJyb3Igb2NjdXJzIHdyaXRpbmcgdG8gYSBXcml0ZXJTeW5jLCBubyBtb3JlIGRhdGEgd2lsbCBiZVxuICogYWNjZXB0ZWQgYW5kIGFsbCBzdWJzZXF1ZW50IHdyaXRlcywgYW5kIGZsdXNoKCksIHdpbGwgcmV0dXJuIHRoZSBlcnJvci5cbiAqIEFmdGVyIGFsbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4sIHRoZSBjbGllbnQgc2hvdWxkIGNhbGwgdGhlXG4gKiBmbHVzaCgpIG1ldGhvZCB0byBndWFyYW50ZWUgYWxsIGRhdGEgaGFzIGJlZW4gZm9yd2FyZGVkIHRvXG4gKiB0aGUgdW5kZXJseWluZyBkZW5vLldyaXRlclN5bmMuXG4gKi9cbmV4cG9ydCBjbGFzcyBCdWZXcml0ZXJTeW5jIGV4dGVuZHMgQWJzdHJhY3RCdWZCYXNlIGltcGxlbWVudHMgV3JpdGVyU3luYyB7XG4gICN3cml0ZXI6IFdyaXRlclN5bmM7XG5cbiAgLyoqIHJldHVybiBuZXcgQnVmV3JpdGVyU3luYyB1bmxlc3Mgd3JpdGVyIGlzIEJ1ZldyaXRlclN5bmMgKi9cbiAgc3RhdGljIGNyZWF0ZShcbiAgICB3cml0ZXI6IFdyaXRlclN5bmMsXG4gICAgc2l6ZTogbnVtYmVyID0gREVGQVVMVF9CVUZfU0laRSxcbiAgKTogQnVmV3JpdGVyU3luYyB7XG4gICAgcmV0dXJuIHdyaXRlciBpbnN0YW5jZW9mIEJ1ZldyaXRlclN5bmNcbiAgICAgID8gd3JpdGVyXG4gICAgICA6IG5ldyBCdWZXcml0ZXJTeW5jKHdyaXRlciwgc2l6ZSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcih3cml0ZXI6IFdyaXRlclN5bmMsIHNpemU6IG51bWJlciA9IERFRkFVTFRfQlVGX1NJWkUpIHtcbiAgICBzdXBlcihuZXcgVWludDhBcnJheShzaXplIDw9IDAgPyBERUZBVUxUX0JVRl9TSVpFIDogc2l6ZSkpO1xuICAgIHRoaXMuI3dyaXRlciA9IHdyaXRlcjtcbiAgfVxuXG4gIC8qKiBEaXNjYXJkcyBhbnkgdW5mbHVzaGVkIGJ1ZmZlcmVkIGRhdGEsIGNsZWFycyBhbnkgZXJyb3IsIGFuZFxuICAgKiByZXNldHMgYnVmZmVyIHRvIHdyaXRlIGl0cyBvdXRwdXQgdG8gdy5cbiAgICovXG4gIHJlc2V0KHc6IFdyaXRlclN5bmMpOiB2b2lkIHtcbiAgICB0aGlzLmVyciA9IG51bGw7XG4gICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgPSAwO1xuICAgIHRoaXMuI3dyaXRlciA9IHc7XG4gIH1cblxuICAvKiogRmx1c2ggd3JpdGVzIGFueSBidWZmZXJlZCBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIGlvLldyaXRlclN5bmMuICovXG4gIGZsdXNoKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVyciAhPT0gbnVsbCkgdGhyb3cgdGhpcy5lcnI7XG4gICAgaWYgKHRoaXMudXNlZEJ1ZmZlckJ5dGVzID09PSAwKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcCA9IHRoaXMuYnVmLnN1YmFycmF5KDAsIHRoaXMudXNlZEJ1ZmZlckJ5dGVzKTtcbiAgICAgIGxldCBud3JpdHRlbiA9IDA7XG4gICAgICB3aGlsZSAobndyaXR0ZW4gPCBwLmxlbmd0aCkge1xuICAgICAgICBud3JpdHRlbiArPSB0aGlzLiN3cml0ZXIud3JpdGVTeW5jKHAuc3ViYXJyYXkobndyaXR0ZW4pKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRoaXMuZXJyID0gZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgdGhpcy5idWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1Zi5sZW5ndGgpO1xuICAgIHRoaXMudXNlZEJ1ZmZlckJ5dGVzID0gMDtcbiAgfVxuXG4gIC8qKiBXcml0ZXMgdGhlIGNvbnRlbnRzIG9mIGBkYXRhYCBpbnRvIHRoZSBidWZmZXIuICBJZiB0aGUgY29udGVudHMgd29uJ3QgZnVsbHlcbiAgICogZml0IGludG8gdGhlIGJ1ZmZlciwgdGhvc2UgYnl0ZXMgdGhhdCBjYW4gYXJlIGNvcGllZCBpbnRvIHRoZSBidWZmZXIsIHRoZVxuICAgKiBidWZmZXIgaXMgdGhlIGZsdXNoZWQgdG8gdGhlIHdyaXRlciBhbmQgdGhlIHJlbWFpbmluZyBieXRlcyBhcmUgY29waWVkIGludG9cbiAgICogdGhlIG5vdyBlbXB0eSBidWZmZXIuXG4gICAqXG4gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHRoZSBidWZmZXIuXG4gICAqL1xuICB3cml0ZVN5bmMoZGF0YTogVWludDhBcnJheSk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZXJyICE9PSBudWxsKSB0aHJvdyB0aGlzLmVycjtcbiAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiAwO1xuXG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICBsZXQgbnVtQnl0ZXNXcml0dGVuID0gMDtcbiAgICB3aGlsZSAoZGF0YS5ieXRlTGVuZ3RoID4gdGhpcy5hdmFpbGFibGUoKSkge1xuICAgICAgaWYgKHRoaXMuYnVmZmVyZWQoKSA9PT0gMCkge1xuICAgICAgICAvLyBMYXJnZSB3cml0ZSwgZW1wdHkgYnVmZmVyLlxuICAgICAgICAvLyBXcml0ZSBkaXJlY3RseSBmcm9tIGRhdGEgdG8gYXZvaWQgY29weS5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBudW1CeXRlc1dyaXR0ZW4gPSB0aGlzLiN3cml0ZXIud3JpdGVTeW5jKGRhdGEpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgdGhpcy5lcnIgPSBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBudW1CeXRlc1dyaXR0ZW4gPSBjb3B5KGRhdGEsIHRoaXMuYnVmLCB0aGlzLnVzZWRCdWZmZXJCeXRlcyk7XG4gICAgICAgIHRoaXMudXNlZEJ1ZmZlckJ5dGVzICs9IG51bUJ5dGVzV3JpdHRlbjtcbiAgICAgICAgdGhpcy5mbHVzaCgpO1xuICAgICAgfVxuICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgICAgZGF0YSA9IGRhdGEuc3ViYXJyYXkobnVtQnl0ZXNXcml0dGVuKTtcbiAgICB9XG5cbiAgICBudW1CeXRlc1dyaXR0ZW4gPSBjb3B5KGRhdGEsIHRoaXMuYnVmLCB0aGlzLnVzZWRCdWZmZXJCeXRlcyk7XG4gICAgdGhpcy51c2VkQnVmZmVyQnl0ZXMgKz0gbnVtQnl0ZXNXcml0dGVuO1xuICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IG51bUJ5dGVzV3JpdHRlbjtcbiAgICByZXR1cm4gdG90YWxCeXRlc1dyaXR0ZW47XG4gIH1cbn1cblxuLyoqIEdlbmVyYXRlIGxvbmdlc3QgcHJvcGVyIHByZWZpeCB3aGljaCBpcyBhbHNvIHN1ZmZpeCBhcnJheS4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUxQUyhwYXQ6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5IHtcbiAgY29uc3QgbHBzID0gbmV3IFVpbnQ4QXJyYXkocGF0Lmxlbmd0aCk7XG4gIGxwc1swXSA9IDA7XG4gIGxldCBwcmVmaXhFbmQgPSAwO1xuICBsZXQgaSA9IDE7XG4gIHdoaWxlIChpIDwgbHBzLmxlbmd0aCkge1xuICAgIGlmIChwYXRbaV0gPT0gcGF0W3ByZWZpeEVuZF0pIHtcbiAgICAgIHByZWZpeEVuZCsrO1xuICAgICAgbHBzW2ldID0gcHJlZml4RW5kO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSBpZiAocHJlZml4RW5kID09PSAwKSB7XG4gICAgICBscHNbaV0gPSAwO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcmVmaXhFbmQgPSBscHNbcHJlZml4RW5kIC0gMV07XG4gICAgfVxuICB9XG4gIHJldHVybiBscHM7XG59XG5cbi8qKiBSZWFkIGRlbGltaXRlZCBieXRlcyBmcm9tIGEgUmVhZGVyLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uKiByZWFkRGVsaW0oXG4gIHJlYWRlcjogUmVhZGVyLFxuICBkZWxpbTogVWludDhBcnJheSxcbik6IEFzeW5jSXRlcmFibGVJdGVyYXRvcjxVaW50OEFycmF5PiB7XG4gIC8vIEF2b2lkIHVuaWNvZGUgcHJvYmxlbXNcbiAgY29uc3QgZGVsaW1MZW4gPSBkZWxpbS5sZW5ndGg7XG4gIGNvbnN0IGRlbGltTFBTID0gY3JlYXRlTFBTKGRlbGltKTtcbiAgY29uc3QgY2h1bmtzID0gbmV3IEJ5dGVzTGlzdCgpO1xuICBjb25zdCBidWZTaXplID0gTWF0aC5tYXgoMTAyNCwgZGVsaW1MZW4gKyAxKTtcblxuICAvLyBNb2RpZmllZCBLTVBcbiAgbGV0IGluc3BlY3RJbmRleCA9IDA7XG4gIGxldCBtYXRjaEluZGV4ID0gMDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBpbnNwZWN0QXJyID0gbmV3IFVpbnQ4QXJyYXkoYnVmU2l6ZSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZGVyLnJlYWQoaW5zcGVjdEFycik7XG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgLy8gWWllbGQgbGFzdCBjaHVuay5cbiAgICAgIHlpZWxkIGNodW5rcy5jb25jYXQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKHJlc3VsdCA8IDApIHtcbiAgICAgIC8vIERpc2NhcmQgYWxsIHJlbWFpbmluZyBhbmQgc2lsZW50bHkgZmFpbC5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY2h1bmtzLmFkZChpbnNwZWN0QXJyLCAwLCByZXN1bHQpO1xuICAgIGxldCBsb2NhbEluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5zcGVjdEluZGV4IDwgY2h1bmtzLnNpemUoKSkge1xuICAgICAgaWYgKGluc3BlY3RBcnJbbG9jYWxJbmRleF0gPT09IGRlbGltW21hdGNoSW5kZXhdKSB7XG4gICAgICAgIGluc3BlY3RJbmRleCsrO1xuICAgICAgICBsb2NhbEluZGV4Kys7XG4gICAgICAgIG1hdGNoSW5kZXgrKztcbiAgICAgICAgaWYgKG1hdGNoSW5kZXggPT09IGRlbGltTGVuKSB7XG4gICAgICAgICAgLy8gRnVsbCBtYXRjaFxuICAgICAgICAgIGNvbnN0IG1hdGNoRW5kID0gaW5zcGVjdEluZGV4IC0gZGVsaW1MZW47XG4gICAgICAgICAgY29uc3QgcmVhZHlCeXRlcyA9IGNodW5rcy5zbGljZSgwLCBtYXRjaEVuZCk7XG4gICAgICAgICAgeWllbGQgcmVhZHlCeXRlcztcbiAgICAgICAgICAvLyBSZXNldCBtYXRjaCwgZGlmZmVyZW50IGZyb20gS01QLlxuICAgICAgICAgIGNodW5rcy5zaGlmdChpbnNwZWN0SW5kZXgpO1xuICAgICAgICAgIGluc3BlY3RJbmRleCA9IDA7XG4gICAgICAgICAgbWF0Y2hJbmRleCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChtYXRjaEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgaW5zcGVjdEluZGV4Kys7XG4gICAgICAgICAgbG9jYWxJbmRleCsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1hdGNoSW5kZXggPSBkZWxpbUxQU1ttYXRjaEluZGV4IC0gMV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqIFJlYWQgZGVsaW1pdGVkIHN0cmluZ3MgZnJvbSBhIFJlYWRlci4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogcmVhZFN0cmluZ0RlbGltKFxuICByZWFkZXI6IFJlYWRlcixcbiAgZGVsaW06IHN0cmluZyxcbiAgZGVjb2Rlck9wdHM/OiB7XG4gICAgZW5jb2Rpbmc/OiBzdHJpbmc7XG4gICAgZmF0YWw/OiBib29sZWFuO1xuICAgIGlnbm9yZUJPTT86IGJvb2xlYW47XG4gIH0sXG4pOiBBc3luY0l0ZXJhYmxlSXRlcmF0b3I8c3RyaW5nPiB7XG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihkZWNvZGVyT3B0cz8uZW5jb2RpbmcsIGRlY29kZXJPcHRzKTtcbiAgZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiByZWFkRGVsaW0ocmVhZGVyLCBlbmNvZGVyLmVuY29kZShkZWxpbSkpKSB7XG4gICAgeWllbGQgZGVjb2Rlci5kZWNvZGUoY2h1bmspO1xuICB9XG59XG5cbi8qKiBSZWFkIHN0cmluZ3MgbGluZS1ieS1saW5lIGZyb20gYSBSZWFkZXIuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24qIHJlYWRMaW5lcyhcbiAgcmVhZGVyOiBSZWFkZXIsXG4gIGRlY29kZXJPcHRzPzoge1xuICAgIGVuY29kaW5nPzogc3RyaW5nO1xuICAgIGZhdGFsPzogYm9vbGVhbjtcbiAgICBpZ25vcmVCT00/OiBib29sZWFuO1xuICB9LFxuKTogQXN5bmNJdGVyYWJsZUl0ZXJhdG9yPHN0cmluZz4ge1xuICBjb25zdCBidWZSZWFkZXIgPSBuZXcgQnVmUmVhZGVyKHJlYWRlcik7XG4gIGxldCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKGRlY29kZXJPcHRzPy5lbmNvZGluZywgZGVjb2Rlck9wdHMpO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJ1ZlJlYWRlci5yZWFkTGluZSgpO1xuICAgIGlmICghcmVzKSB7XG4gICAgICBpZiAoY2h1bmtzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgeWllbGQgZGVjb2Rlci5kZWNvZGUoY29uY2F0KC4uLmNodW5rcykpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNodW5rcy5wdXNoKHJlcy5saW5lKTtcbiAgICBpZiAoIXJlcy5tb3JlKSB7XG4gICAgICB5aWVsZCBkZWNvZGVyLmRlY29kZShjb25jYXQoLi4uY2h1bmtzKSk7XG4gICAgICBjaHVua3MgPSBbXTtcbiAgICB9XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUsU0FBUyxNQUFNLFFBQVEscUJBQXFCO0FBQzVDLFNBQVMsU0FBUyxRQUFRLHlCQUF5QjtBQUNuRCxTQUFTLE1BQU0sRUFBRSxJQUFJLFFBQVEsa0JBQWtCO0FBRy9DLG9FQUFvRTtBQUNwRSw0RUFBNEU7QUFDNUUsMkVBQTJFO0FBQzNFLHFCQUFxQjtBQUNyQixNQUFNLFdBQVcsS0FBSztBQUN0QixNQUFNLFdBQVcsS0FBSyxLQUFLO0FBRTNCOzs7Ozs7Ozs7Ozs7OytEQWErRCxHQUUvRCxPQUFPLE1BQU07SUFDWCxDQUFDLEdBQUcsQ0FBYTtJQUNqQixDQUFDLEdBQUcsR0FBRyxFQUFFO0lBRVQsWUFBWSxFQUF3QyxDQUFFO1FBQ3BELElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxPQUFPLFlBQVksSUFBSSxXQUFXLEtBQUssSUFBSSxXQUFXLEdBQUc7SUFDdkU7SUFFQTs7Ozs7Ozs7R0FRQyxHQUNELE1BQU0sVUFBVTtRQUFFLE1BQU0sSUFBSTtJQUFDLENBQUMsRUFBYztRQUMxQyxJQUFJLFFBQVEsSUFBSSxLQUFLLEtBQUssRUFBRSxPQUFPLElB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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/p5wE1hCF6dGYMZ41YnIQs2go2is.js b/tests/__snapshots__/transpile/url/modules/p5wE1hCF6dGYMZ41YnIQs2go2is.js new file mode 100644 index 0000000..d414e93 --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/p5wE1hCF6dGYMZ41YnIQs2go2is.js @@ -0,0 +1,140 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** + * An abstraction of multiple Uint8Arrays + */ export class BytesList { + len = 0; + chunks = []; + constructor(){} + /** + * Total size of bytes + */ size() { + return this.len; + } + /** + * Push bytes with given offset infos + */ add(value, start = 0, end = value.byteLength) { + if (value.byteLength === 0 || end - start === 0) { + return; + } + checkRange(start, end, value.byteLength); + this.chunks.push({ + value, + end, + start, + offset: this.len + }); + this.len += end - start; + } + /** + * Drop head `n` bytes. + */ shift(n) { + if (n === 0) { + return; + } + if (this.len <= n) { + this.chunks = []; + this.len = 0; + return; + } + const idx = this.getChunkIndex(n); + this.chunks.splice(0, idx); + const [chunk] = this.chunks; + if (chunk) { + const diff = n - chunk.offset; + chunk.start += diff; + } + let offset = 0; + for (const chunk of this.chunks){ + chunk.offset = offset; + offset += chunk.end - chunk.start; + } + this.len = offset; + } + /** + * Find chunk index in which `pos` locates by binary-search + * returns -1 if out of range + */ getChunkIndex(pos) { + let max = this.chunks.length; + let min = 0; + while(true){ + const i = min + Math.floor((max - min) / 2); + if (i < 0 || this.chunks.length <= i) { + return -1; + } + const { offset , start , end } = this.chunks[i]; + const len = end - start; + if (offset <= pos && pos < offset + len) { + return i; + } else if (offset + len <= pos) { + min = i + 1; + } else { + max = i - 1; + } + } + } + /** + * Get indexed byte from chunks + */ get(i) { + if (i < 0 || this.len <= i) { + throw new Error("out of range"); + } + const idx = this.getChunkIndex(i); + const { value , offset , start } = this.chunks[idx]; + return value[start + i - offset]; + } + /** + * Iterator of bytes from given position + */ *iterator(start = 0) { + const startIdx = this.getChunkIndex(start); + if (startIdx < 0) return; + const first = this.chunks[startIdx]; + let firstOffset = start - first.offset; + for(let i = startIdx; i < this.chunks.length; i++){ + const chunk = this.chunks[i]; + for(let j = chunk.start + firstOffset; j < chunk.end; j++){ + yield chunk.value[j]; + } + firstOffset = 0; + } + } + /** + * Returns subset of bytes copied + */ slice(start, end = this.len) { + if (end === start) { + return new Uint8Array(); + } + checkRange(start, end, this.len); + const result = new Uint8Array(end - start); + const startIdx = this.getChunkIndex(start); + const endIdx = this.getChunkIndex(end - 1); + let written = 0; + for(let i = startIdx; i < endIdx; i++){ + const chunk = this.chunks[i]; + const len = chunk.end - chunk.start; + result.set(chunk.value.subarray(chunk.start, chunk.end), written); + written += len; + } + const last = this.chunks[endIdx]; + const rest = end - start - written; + result.set(last.value.subarray(last.start, last.start + rest), written); + return result; + } + /** + * Concatenate chunks into single Uint8Array copied. + */ concat() { + const result = new Uint8Array(this.len); + let sum = 0; + for (const { value , start , end } of this.chunks){ + result.set(value.subarray(start, end), sum); + sum += end - start; + } + return result; + } +} +function checkRange(start, end, len) { + if (start < 0 || len < start || end < 0 || len < end || end < start) { + throw new Error("invalid range"); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL2J5dGVzL2J5dGVzX2xpc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMTgtMjAyMiB0aGUgRGVubyBhdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBNSVQgbGljZW5zZS5cbi8vIFRoaXMgbW9kdWxlIGlzIGJyb3dzZXIgY29tcGF0aWJsZS5cblxuLyoqXG4gKiBBbiBhYnN0cmFjdGlvbiBvZiBtdWx0aXBsZSBVaW50OEFycmF5c1xuICovXG5leHBvcnQgY2xhc3MgQnl0ZXNMaXN0IHtcbiAgcHJpdmF0ZSBsZW4gPSAwO1xuICBwcml2YXRlIGNodW5rczoge1xuICAgIHZhbHVlOiBVaW50OEFycmF5O1xuICAgIHN0YXJ0OiBudW1iZXI7IC8vIHN0YXJ0IG9mZnNldCBmcm9tIGhlYWQgb2YgY2h1bmtcbiAgICBlbmQ6IG51bWJlcjsgLy8gZW5kIG9mZnNldCBmcm9tIGhlYWQgb2YgY2h1bmtcbiAgICBvZmZzZXQ6IG51bWJlcjsgLy8gb2Zmc2V0IG9mIGhlYWQgaW4gYWxsIGJ5dGVzXG4gIH1bXSA9IFtdO1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIFRvdGFsIHNpemUgb2YgYnl0ZXNcbiAgICovXG4gIHNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMubGVuO1xuICB9XG4gIC8qKlxuICAgKiBQdXNoIGJ5dGVzIHdpdGggZ2l2ZW4gb2Zmc2V0IGluZm9zXG4gICAqL1xuICBhZGQodmFsdWU6IFVpbnQ4QXJyYXksIHN0YXJ0ID0gMCwgZW5kID0gdmFsdWUuYnl0ZUxlbmd0aCkge1xuICAgIGlmICh2YWx1ZS5ieXRlTGVuZ3RoID09PSAwIHx8IGVuZCAtIHN0YXJ0ID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNoZWNrUmFuZ2Uoc3RhcnQsIGVuZCwgdmFsdWUuYnl0ZUxlbmd0aCk7XG4gICAgdGhpcy5jaHVua3MucHVzaCh7XG4gICAgICB2YWx1ZSxcbiAgICAgIGVuZCxcbiAgICAgIHN0YXJ0LFxuICAgICAgb2Zmc2V0OiB0aGlzLmxlbixcbiAgICB9KTtcbiAgICB0aGlzLmxlbiArPSBlbmQgLSBzdGFydDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcm9wIGhlYWQgYG5gIGJ5dGVzLlxuICAgKi9cbiAgc2hpZnQobjogbnVtYmVyKSB7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubGVuIDw9IG4pIHtcbiAgICAgIHRoaXMuY2h1bmtzID0gW107XG4gICAgICB0aGlzLmxlbiA9IDA7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGlkeCA9IHRoaXMuZ2V0Q2h1bmtJbmRleChuKTtcbiAgICB0aGlzLmNodW5rcy5zcGxpY2UoMCwgaWR4KTtcbiAgICBjb25zdCBbY2h1bmtdID0gdGhpcy5jaHVua3M7XG4gICAgaWYgKGNodW5rKSB7XG4gICAgICBjb25zdCBkaWZmID0gbiAtIGNodW5rLm9mZnNldDtcbiAgICAgIGNodW5rLnN0YXJ0ICs9IGRpZmY7XG4gICAgfVxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGZvciAoY29uc3QgY2h1bmsgb2YgdGhpcy5jaHVua3MpIHtcbiAgICAgIGNodW5rLm9mZnNldCA9IG9mZnNldDtcbiAgICAgIG9mZnNldCArPSBjaHVuay5lbmQgLSBjaHVuay5zdGFydDtcbiAgICB9XG4gICAgdGhpcy5sZW4gPSBvZmZzZXQ7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBjaHVuayBpbmRleCBpbiB3aGljaCBgcG9zYCBsb2NhdGVzIGJ5IGJpbmFyeS1zZWFyY2hcbiAgICogcmV0dXJucyAtMSBpZiBvdXQgb2YgcmFuZ2VcbiAgICovXG4gIGdldENodW5rSW5kZXgocG9zOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBtYXggPSB0aGlzLmNodW5rcy5sZW5ndGg7XG4gICAgbGV0IG1pbiA9IDA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IGkgPSBtaW4gKyBNYXRoLmZsb29yKChtYXggLSBtaW4pIC8gMik7XG4gICAgICBpZiAoaSA8IDAgfHwgdGhpcy5jaHVua3MubGVuZ3RoIDw9IGkpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBvZmZzZXQsIHN0YXJ0LCBlbmQgfSA9IHRoaXMuY2h1bmtzW2ldO1xuICAgICAgY29uc3QgbGVuID0gZW5kIC0gc3RhcnQ7XG4gICAgICBpZiAob2Zmc2V0IDw9IHBvcyAmJiBwb3MgPCBvZmZzZXQgKyBsZW4pIHtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgICB9IGVsc2UgaWYgKG9mZnNldCArIGxlbiA8PSBwb3MpIHtcbiAgICAgICAgbWluID0gaSArIDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXggPSBpIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGluZGV4ZWQgYnl0ZSBmcm9tIGNodW5rc1xuICAgKi9cbiAgZ2V0KGk6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGkgPCAwIHx8IHRoaXMubGVuIDw9IGkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm91dCBvZiByYW5nZVwiKTtcbiAgICB9XG4gICAgY29uc3QgaWR4ID0gdGhpcy5nZXRDaHVua0luZGV4KGkpO1xuICAgIGNvbnN0IHsgdmFsdWUsIG9mZnNldCwgc3RhcnQgfSA9IHRoaXMuY2h1bmtzW2lkeF07XG4gICAgcmV0dXJuIHZhbHVlW3N0YXJ0ICsgaSAtIG9mZnNldF07XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0b3Igb2YgYnl0ZXMgZnJvbSBnaXZlbiBwb3NpdGlvblxuICAgKi9cbiAgKml0ZXJhdG9yKHN0YXJ0ID0gMCk6IEl0ZXJhYmxlSXRlcmF0b3I8bnVtYmVyPiB7XG4gICAgY29uc3Qgc3RhcnRJZHggPSB0aGlzLmdldENodW5rSW5kZXgoc3RhcnQpO1xuICAgIGlmIChzdGFydElkeCA8IDApIHJldHVybjtcbiAgICBjb25zdCBmaXJzdCA9IHRoaXMuY2h1bmtzW3N0YXJ0SWR4XTtcbiAgICBsZXQgZmlyc3RPZmZzZXQgPSBzdGFydCAtIGZpcnN0Lm9mZnNldDtcbiAgICBmb3IgKGxldCBpID0gc3RhcnRJZHg7IGkgPCB0aGlzLmNodW5rcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLmNodW5rc1tpXTtcbiAgICAgIGZvciAobGV0IGogPSBjaHVuay5zdGFydCArIGZpcnN0T2Zmc2V0OyBqIDwgY2h1bmsuZW5kOyBqKyspIHtcbiAgICAgICAgeWllbGQgY2h1bmsudmFsdWVbal07XG4gICAgICB9XG4gICAgICBmaXJzdE9mZnNldCA9IDA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgc3Vic2V0IG9mIGJ5dGVzIGNvcGllZFxuICAgKi9cbiAgc2xpY2Uoc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIgPSB0aGlzLmxlbik6IFVpbnQ4QXJyYXkge1xuICAgIGlmIChlbmQgPT09IHN0YXJ0KSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoKTtcbiAgICB9XG4gICAgY2hlY2tSYW5nZShzdGFydCwgZW5kLCB0aGlzLmxlbik7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkoZW5kIC0gc3RhcnQpO1xuICAgIGNvbnN0IHN0YXJ0SWR4ID0gdGhpcy5nZXRDaHVua0luZGV4KHN0YXJ0KTtcbiAgICBjb25zdCBlbmRJZHggPSB0aGlzLmdldENodW5rSW5kZXgoZW5kIC0gMSk7XG4gICAgbGV0IHdyaXR0ZW4gPSAwO1xuICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IGVuZElkeDsgaSsrKSB7XG4gICAgICBjb25zdCBjaHVuayA9IHRoaXMuY2h1bmtzW2ldO1xuICAgICAgY29uc3QgbGVuID0gY2h1bmsuZW5kIC0gY2h1bmsuc3RhcnQ7XG4gICAgICByZXN1bHQuc2V0KGNodW5rLnZhbHVlLnN1YmFycmF5KGNodW5rLnN0YXJ0LCBjaHVuay5lbmQpLCB3cml0dGVuKTtcbiAgICAgIHdyaXR0ZW4gKz0gbGVuO1xuICAgIH1cbiAgICBjb25zdCBsYXN0ID0gdGhpcy5jaHVua3NbZW5kSWR4XTtcbiAgICBjb25zdCByZXN0ID0gZW5kIC0gc3RhcnQgLSB3cml0dGVuO1xuICAgIHJlc3VsdC5zZXQobGFzdC52YWx1ZS5zdWJhcnJheShsYXN0LnN0YXJ0LCBsYXN0LnN0YXJ0ICsgcmVzdCksIHdyaXR0ZW4pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLyoqXG4gICAqIENvbmNhdGVuYXRlIGNodW5rcyBpbnRvIHNpbmdsZSBVaW50OEFycmF5IGNvcGllZC5cbiAgICovXG4gIGNvbmNhdCgpOiBVaW50OEFycmF5IHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbik7XG4gICAgbGV0IHN1bSA9IDA7XG4gICAgZm9yIChjb25zdCB7IHZhbHVlLCBzdGFydCwgZW5kIH0gb2YgdGhpcy5jaHVua3MpIHtcbiAgICAgIHJlc3VsdC5zZXQodmFsdWUuc3ViYXJyYXkoc3RhcnQsIGVuZCksIHN1bSk7XG4gICAgICBzdW0gKz0gZW5kIC0gc3RhcnQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tSYW5nZShzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgbGVuOiBudW1iZXIpIHtcbiAgaWYgKHN0YXJ0IDwgMCB8fCBsZW4gPCBzdGFydCB8fCBlbmQgPCAwIHx8IGxlbiA8IGVuZCB8fCBlbmQgPCBzdGFydCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgcmFuZ2VcIik7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDOztDQUVDLEdBQ0QsT0FBTyxNQUFNO0lBQ0gsTUFBTSxFQUFFO0lBQ1IsU0FLRixFQUFFLENBQUM7SUFDVCxhQUFjLENBQUM7SUFFZjs7R0FFQyxHQUNELE9BQU87UUFD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 \ No newline at end of file diff --git a/tests/__snapshots__/transpile/url/modules/wme9EIsCB7sfOz5qC_CSLRYajRk.js b/tests/__snapshots__/transpile/url/modules/wme9EIsCB7sfOz5qC_CSLRYajRk.js new file mode 100644 index 0000000..e057dad --- /dev/null +++ b/tests/__snapshots__/transpile/url/modules/wme9EIsCB7sfOz5qC_CSLRYajRk.js @@ -0,0 +1,5 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +// This module is browser compatible. +/** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE0MC4wL3BhdGgvX2ludGVyZmFjZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAxOC0yMDIyIHRoZSBEZW5vIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIE1JVCBsaWNlbnNlLlxuLy8gVGhpcyBtb2R1bGUgaXMgYnJvd3NlciBjb21wYXRpYmxlLlxuXG4vKipcbiAqIEEgcGFyc2VkIHBhdGggb2JqZWN0IGdlbmVyYXRlZCBieSBwYXRoLnBhcnNlKCkgb3IgY29uc3VtZWQgYnkgcGF0aC5mb3JtYXQoKS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJzZWRQYXRoIHtcbiAgLyoqXG4gICAqIFRoZSByb290IG9mIHRoZSBwYXRoIHN1Y2ggYXMgJy8nIG9yICdjOlxcJ1xuICAgKi9cbiAgcm9vdDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGZ1bGwgZGlyZWN0b3J5IHBhdGggc3VjaCBhcyAnL2hvbWUvdXNlci9kaXInIG9yICdjOlxccGF0aFxcZGlyJ1xuICAgKi9cbiAgZGlyOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZmlsZSBuYW1lIGluY2x1ZGluZyBleHRlbnNpb24gKGlmIGFueSkgc3VjaCBhcyAnaW5kZXguaHRtbCdcbiAgICovXG4gIGJhc2U6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBmaWxlIGV4dGVuc2lvbiAoaWYgYW55KSBzdWNoIGFzICcuaHRtbCdcbiAgICovXG4gIGV4dDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGZpbGUgbmFtZSB3aXRob3V0IGV4dGVuc2lvbiAoaWYgYW55KSBzdWNoIGFzICdpbmRleCdcbiAgICovXG4gIG5hbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgRm9ybWF0SW5wdXRQYXRoT2JqZWN0ID0gUGFydGlhbDxQYXJzZWRQYXRoPjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwRUFBMEU7QUFDMUUscUNBQXFDO0FBRXJDOztDQUVDLEdBQ0QifQ== \ No newline at end of file diff --git a/tests/bundle_test.ts b/tests/bundle_test.ts new file mode 100644 index 0000000..00b2c38 --- /dev/null +++ b/tests/bundle_test.ts @@ -0,0 +1,55 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { assertStringIncludes } from "https://deno.land/std@0.182.0/testing/asserts.ts"; +import { resolveFixture, testBundle } from "./utils.ts"; + +// FIXME: This repeats the test below. Consider supporting URLs without wrapping +// in a URL object. +Deno.test({ + name: "remote", + fn: testBundle( + new URL("https://deno.land/std@0.140.0/examples/chat/server.ts"), + ), +}); + +Deno.test({ + name: "url", + fn: testBundle( + new URL("https://deno.land/std@0.140.0/examples/chat/server.ts"), + ), +}); + +Deno.test({ + name: "relative", + fn: testBundle("./testdata/mod.ts"), +}); + +Deno.test({ + name: "absolute", + fn: testBundle(resolveFixture("mod.ts")), +}); + +Deno.test({ + name: "source", + fn: testBundle(new URL("file:///src.ts"), { + async load(specifier) { + if (specifier !== "file:///src.ts") return undefined; + const content = await Deno.readTextFile(resolveFixture("mod.ts")); + return { kind: "module", specifier, content }; + }, + }), +}); + +Deno.test({ + name: "json escapes", + fn: testBundle(resolveFixture("escape.ts"), undefined, ({ result }) => { + // This is done on purpose, as `String.raw` still performs a string interpolation, + // and we want a literal value ${jsInterpolation" as is, without any modifications. + // We should not need to escape `$` nor `{` as they are both JSON-safe characters. + const jsInterpolation = "${jsInterpolation}"; + assertStringIncludes( + result.code, + String + .raw`const __default = JSON.parse("{\n \"key\": \"a value with newline\\n, \\\"double quotes\\\", 'single quotes', and ${jsInterpolation}\"\n}");`, + ); + }), +}); diff --git a/tests/transpile_test.ts b/tests/transpile_test.ts new file mode 100644 index 0000000..7a59ab4 --- /dev/null +++ b/tests/transpile_test.ts @@ -0,0 +1,39 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { resolveFixture, testTranspile } from "./utils.ts"; + +// FIXME: This repeats the test below. Consider supporting URLs without wrapping +// in a URL object. +Deno.test({ + name: "remote", + fn: testTranspile( + new URL("https://deno.land/std@0.140.0/examples/chat/server.ts"), + ), +}); + +Deno.test({ + name: "url", + fn: testTranspile( + new URL("https://deno.land/std@0.140.0/examples/chat/server.ts"), + ), +}); + +Deno.test({ + name: "relative", + fn: testTranspile("./testdata/mod.ts"), +}); + +Deno.test({ + name: "absolute", + fn: testTranspile(resolveFixture("mod.ts")), +}); + +Deno.test({ + name: "source", + fn: testTranspile(new URL("file:///src.ts"), { + async load(specifier) { + if (specifier !== "file:///src.ts") return undefined; + const content = await Deno.readTextFile(resolveFixture("mod.ts")); + return { kind: "module", specifier, content }; + }, + }), +}); diff --git a/tests/utils.ts b/tests/utils.ts new file mode 100644 index 0000000..2162390 --- /dev/null +++ b/tests/utils.ts @@ -0,0 +1,379 @@ +import { + fromFileUrl, + parse, + relative, + resolve, + SEP, + toFileUrl, +} from "https://deno.land/std@0.182.0/path/mod.ts"; +import { + ensureFile, + existsSync, +} from "https://deno.land/std@0.182.0/fs/mod.ts"; +import { AssertionError } from "https://deno.land/std@0.182.0/testing/asserts.ts"; +import { + buildMessage, + diffstr, +} from "https://deno.land/std@0.182.0/testing/_diff.ts"; +import { bundle, type BundleOptions, emit, type EmitOptions } from "../mod.ts"; +import * as base64Url from "https://deno.land/std@0.182.0/encoding/base64url.ts"; +import * as base64 from "https://deno.land/std@0.182.0/encoding/base64.ts"; + +const textEncoder = new TextEncoder(); +const textDecoder = new TextDecoder(); + +const inlineSourceMapRegex = + /^\/\/# sourceMappingURL=data:application\/json;base64,([a-zA-Z0-9+/=]+)$/; + +// Tracks which snapshots are involved in order to identify conflicts. +const tracker: Set = new Set(); + +type TranspileResult = Awaited>; +interface TestTranspileOutput { + result: TranspileResult; + modulesPaths: Record; +} + +type BundleResult = Awaited>; +interface TestBundleOutput { + result: BundleResult; + bundlePath: string; + sourceMapPath?: string; +} + +/** + * Calls `emit` with the provided parameters and checks that the output is + * consistent with the snapshots. + * Each module in the record returned by `emit` is stored as its own file. + * In order to avoid special characters, the file name is a hash of the module's + * URL. The mapping between the hashes and the URLs is stored alongside the + * modules. + * + * @param root The root module specifier to use for the emitted modules. + * @param options Options to use when emitting. + * @param more An optional function to perform more assertions. + * @returns A function to pass to the test runner + */ +export function testTranspile( + root: string | URL, + options?: EmitOptions, + more?: ( + output: TestTranspileOutput, + t: Deno.TestContext, + ) => void | Promise, +) { + return async function (t: Deno.TestContext): Promise { + const result = fixTranspileResult(await emit(root, options)); + + const testDir = resolve(getSnapshotDir(t), getTestName(t)); + + const modules = await Promise.all( + Object.entries(result).map(async ([url, source]) => { + const hash = await hashShortSha1(url); + const fileName = `${hash}.js`; + return { fileName, url, source }; + }), + ); + const modulesSnapshotEntries: [string, string][] = modules.map(( + { fileName, source }, + ) => [fileName, source]); + // The keys need to be sorted in order to have consistency between runs. + const mapping: Record = Object.fromEntries( + modules.map(({ fileName, url }) => { + return [url, fileName]; + }).sort((a, b) => { + if (a[0] > b[0]) return 1; + if (a[0] < b[0]) return -1; + return 0; + }), + ); + + const snapshotMode = + existsSync(testDir, { isReadable: true, isDirectory: true }) + ? getMode() + : "update"; + + await assertSnapshot( + resolve(testDir, "mapping.json"), + JSON.stringify(mapping, null, 2) + "\n", + snapshotMode, + ); + await assertSnapshots( + resolve(testDir, "modules"), + modulesSnapshotEntries, + snapshotMode, + ); + + if (more) { + const output: TestTranspileOutput = { + result, + modulesPaths: Object.fromEntries( + Object.entries(mapping).map(([url, filename]) => { + const filepath = resolve(testDir, "modules", filename); + return [url, filepath]; + }), + ), + }; + await more(output, t); + } + }; +} + +/** + * Calls `bundle` with the provided parameters and checks that the output is + * consistent with the snapshots of the code, stored as a JavaScript file, + * and the snapshot of the sourcemap, when it exists. + * + * @param root The root module specifier to use for the bundle. + * @param options Options to use when bundling. + * @param more An optional function to perform more assertions. + * @returns A function to pass to the test runner + */ +export function testBundle( + root: string | URL, + options?: BundleOptions, + more?: ( + output: TestBundleOutput, + t: Deno.TestContext, + ) => void | Promise, +) { + return async function (t: Deno.TestContext): Promise { + const result = fixBundleResult(await bundle(root, options)); + + const testName = getTestName(t); + const snapshotDir = getSnapshotDir(t); + + const bundlePath = resolve(snapshotDir, `${testName}.js`); + const sourceMapPath = resolve(snapshotDir, `${testName}.js.map`); + + const snapshotMode = + existsSync(snapshotDir, { isReadable: true, isDirectory: true }) + ? getMode() + : "update"; + await assertSnapshot( + bundlePath, + result.code, + snapshotMode, + ); + await assertSnapshot( + sourceMapPath, + result.map, + snapshotMode, + ); + + if (more) { + const output: TestBundleOutput = { + result, + bundlePath, + sourceMapPath: result.map ? sourceMapPath : undefined, + }; + await more(output, t); + } + }; +} + +/** + * Provides the full path of a fixture file stored in "testdata". + * + * @param parts Path relative to the folder with the fixtures. + * @returns the full path of the fixture. + */ +export function resolveFixture(...parts: string[]): string { + return resolve(Deno.cwd(), "testdata", ...parts); +} + +async function assertSnapshot( + path: string, + actual: string | undefined, + mode: SnapshotMode, +): Promise { + let snapshot: string | undefined; + try { + snapshot = await Deno.readTextFile(path); + } catch (e: unknown) { + if (!(e instanceof Deno.errors.NotFound)) { + throw e; + } + } + + if (actual === snapshot) { + return; + } + + const relativePath = relative(Deno.cwd(), path); + + if (mode === "update") { + if (tracker.has(path)) { + throw new Error(`Snapshot already defined at ${relativePath}`); + } + await applyUpdate(path, actual); + } else { + const diffResult = diffstr( + actual ?? "", + snapshot ?? "", + ); + const diffMsg = buildMessage(diffResult); + throw new AssertionError( + `Snapshot at ${relativePath} does not match:\n${diffMsg}`, + ); + } +} + +async function assertSnapshots( + path: string, + files: Iterable<[fileName: string, actual: string | undefined]>, + mode: SnapshotMode, +): Promise { + const remainingFiles: Set = new Set(); + const dir = Deno.readDir(path); + try { + for await (const entry of dir) { + if (entry.isFile) { + remainingFiles.add(resolve(path, entry.name)); + } + } + } catch (e: unknown) { + if (!(e instanceof Deno.errors.NotFound)) { + throw e; + } + } + for (const [fileName, actual] of files) { + const filePath = resolve(path, fileName); + await assertSnapshot(filePath, actual, mode); + remainingFiles.delete(filePath); + } + for (const filePath of remainingFiles) { + await assertSnapshot(filePath, undefined, mode); + } +} + +type SnapshotMode = "assert" | "update"; + +let _mode: SnapshotMode; + +function getMode(): SnapshotMode { + if (_mode) { + return _mode; + } else { + _mode = Deno.args.some((arg) => arg === "--update" || arg === "-u") + ? "update" + : "assert"; + return _mode; + } +} + +// Note that there can be conflicts; different tests can output the same test +// name. It is not ideal but it shouldn't happen in normal circumstances, and +// assertSnapshot will throw if it ever causes snapshots to clash. +function getTestName( + context: Deno.TestContext, +): string { + // Avoiding special characters other than dash and underscore + let name = slugify(context.name); + if (context.parent) { + name = `${getTestName(context.parent)}__${name}`; + } + return name; +} + +function slugify(name: string): string { + return name + .replace(/\s/g, "_") + .replace(/[^a-zA-Z0-9_]/g, "") + .toLowerCase(); +} + +function getSnapshotDir(context: Deno.TestContext): string { + const { dir, name } = parse(fromFileUrl(context.origin)); + const snapshotDir = resolve( + dir, + "__snapshots__", + name.endsWith("_test") + ? name.substring(0, name.length - "_test".length) + : name, + ); + return snapshotDir; +} + +async function applyUpdate( + path: string, + actual: string | undefined, +): Promise { + if (actual === undefined) { + await Deno.remove(path); + return; + } + await ensureFile(path); + await Deno.writeTextFile(path, actual); +} + +// We don't want to litter the snapshots with absolute file paths, which +// depend on where the repository is located on the device. +function normalizeIfFileUrl(urlString: string): string { + const url = new URL(urlString); + if (url.protocol === "file:") { + const path = fromFileUrl(url); + // We prepend with the separator instead of using `resolve()` because, on + // Windows, this adds the device prefix (e.g. `C:`), which we don't want. + const normalizedPath = SEP + relative(Deno.cwd(), path); + return toFileUrl(normalizedPath).toString(); + } + return url.toString(); +} + +// We need to normalize the source map URLs because they are absolute paths. + +function fixTranspileResult(result: TranspileResult): TranspileResult { + return Object.fromEntries( + Object.entries(result).map(( + [url, source], + ) => { + source = fixInlineSourceMap(source); + url = normalizeIfFileUrl(url); + return [url, source]; + }), + ); +} + +function fixBundleResult(result: BundleResult): BundleResult { + const code = fixInlineSourceMap(result.code); + const map = result.map !== undefined ? fixSourceMap(result.map) : undefined; + return { code, map }; +} + +function fixSourceMap(sourceMapJsonString: string): string { + const sourceMap = JSON.parse(sourceMapJsonString); + sourceMap.sources = sourceMap.sources.map(normalizeIfFileUrl); + return JSON.stringify(sourceMap); +} + +function fixInlineSourceMap(code: string): string { + const lines = code.split("\n"); + + const indexOfLastLine = lines.findLastIndex((line) => line !== ""); + const match = lines[indexOfLastLine]?.match(inlineSourceMapRegex); + if (match == null) { + return code; + } + + const sourceMapBase64 = match[1]; + const sourceMap = textDecoder.decode(base64.decode(sourceMapBase64)); + const newSourceMap = fixSourceMap(sourceMap); + const newSourceMapBase64 = base64.encode(textEncoder.encode(newSourceMap)); + + lines[indexOfLastLine] = + `//# sourceMappingURL=data:application/json;base64,${newSourceMapBase64}`; + + return lines.join("\n"); +} + +async function hashShortSha1(input: string): Promise { + // Base64 makes the hash shorted; the URL variants avoids special characters + // other than dash and underscore. + return base64Url.encode( + await crypto.subtle.digest( + "SHA-1", + textEncoder.encode(input), + ), + ); +}