import { deprecate } from '@glimmer/util'; import visitorKeys from '../v1/visitor-keys'; import { cannotRemoveNode, cannotReplaceNode, cannotReplaceOrRemoveInKeyHandlerYet } from './errors'; import WalkerPath from './path'; function getEnterFunction(handler) { if (typeof handler === 'function') { return handler; } else { return handler.enter; } } function getExitFunction(handler) { if (typeof handler === 'function') { return undefined; } else { return handler.exit; } } function getKeyHandler(handler, key) { let keyVisitor = typeof handler !== 'function' ? handler.keys : undefined; if (keyVisitor === undefined) return; let keyHandler = keyVisitor[key]; if (keyHandler !== undefined) { return keyHandler; } return keyVisitor.All; } function getNodeHandler(visitor, nodeType) { if (nodeType === 'Template' || nodeType === 'Block') { if (visitor.Program) { if (false /* LOCAL_DEBUG */ ) { (false && !(false) && deprecate(`The 'Program' visitor node is deprecated. Use 'Template' or 'Block' instead (node was '${nodeType}') `)); } return visitor.Program; } } let handler = visitor[nodeType]; if (handler !== undefined) { return handler; } return visitor.All; } function visitNode(visitor, path) { let { node, parent, parentKey } = path; let handler = getNodeHandler(visitor, node.type); let enter; let exit; if (handler !== undefined) { enter = getEnterFunction(handler); exit = getExitFunction(handler); } let result; if (enter !== undefined) { result = enter(node, path); } if (result !== undefined && result !== null) { if (JSON.stringify(node) === JSON.stringify(result)) { result = undefined; } else if (Array.isArray(result)) { visitArray(visitor, result, parent, parentKey); return result; } else { let path = new WalkerPath(result, parent, parentKey); return visitNode(visitor, path) || result; } } if (result === undefined) { let keys = visitorKeys[node.type]; for (let i = 0; i < keys.length; i++) { let key = keys[i]; // we know if it has child keys we can widen to a ParentNode visitKey(visitor, handler, path, key); } if (exit !== undefined) { result = exit(node, path); } } return result; } function get(node, key) { return node[key]; } function set(node, key, value) { node[key] = value; } function visitKey(visitor, handler, path, key) { let { node } = path; let value = get(node, key); if (!value) { return; } let keyEnter; let keyExit; if (handler !== undefined) { let keyHandler = getKeyHandler(handler, key); if (keyHandler !== undefined) { keyEnter = getEnterFunction(keyHandler); keyExit = getExitFunction(keyHandler); } } if (keyEnter !== undefined) { if (keyEnter(node, key) !== undefined) { throw cannotReplaceOrRemoveInKeyHandlerYet(node, key); } } if (Array.isArray(value)) { visitArray(visitor, value, path, key); } else { let keyPath = new WalkerPath(value, path, key); let result = visitNode(visitor, keyPath); if (result !== undefined) { // TODO: dynamically check the results by having a table of // expected node types in value space, not just type space // eslint-disable-next-line @typescript-eslint/no-explicit-any assignKey(node, key, value, result); } } if (keyExit !== undefined) { if (keyExit(node, key) !== undefined) { throw cannotReplaceOrRemoveInKeyHandlerYet(node, key); } } } function visitArray(visitor, array, parent, parentKey) { for (let i = 0; i < array.length; i++) { let node = array[i]; let path = new WalkerPath(node, parent, parentKey); let result = visitNode(visitor, path); if (result !== undefined) { i += spliceArray(array, i, result) - 1; } } } function assignKey(node, key, value, result) { if (result === null) { throw cannotRemoveNode(value, node, key); } else if (Array.isArray(result)) { if (result.length === 1) { set(node, key, result[0]); } else { if (result.length === 0) { throw cannotRemoveNode(value, node, key); } else { throw cannotReplaceNode(value, node, key); } } } else { set(node, key, result); } } function spliceArray(array, index, result) { if (result === null) { array.splice(index, 1); return 0; } else if (Array.isArray(result)) { array.splice(index, 1, ...result); return result.length; } else { array.splice(index, 1, result); return 1; } } export default function traverse(node, visitor) { let path = new WalkerPath(node); visitNode(visitor, path); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvdHJhdmVyc2FsL3RyYXZlcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLFNBQVMsU0FBVCxRQUEwQixlQUExQjtBQUdBLE9BQU8sV0FBUCxNQUFxRCxvQkFBckQ7QUFDQSxTQUNFLGdCQURGLEVBRUUsaUJBRkYsRUFHRSxvQ0FIRixRQUlPLFVBSlA7QUFLQSxPQUFPLFVBQVAsTUFBdUIsUUFBdkI7O0FBU0EsU0FBUyxnQkFBVCxDQUNFLE9BREYsRUFDZ0Q7QUFFOUMsTUFBSSxPQUFPLE9BQVAsS0FBbUIsVUFBdkIsRUFBbUM7QUFDakMsV0FBTyxPQUFQO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsV0FBTyxPQUFPLENBQUMsS0FBZjtBQUNEO0FBQ0Y7O0FBUUQsU0FBUyxlQUFULENBQ0UsT0FERixFQUNnRDtBQUU5QyxNQUFJLE9BQU8sT0FBUCxLQUFtQixVQUF2QixFQUFtQztBQUNqQyxXQUFPLFNBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxXQUFPLE9BQU8sQ0FBQyxJQUFmO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTLGFBQVQsQ0FDRSxPQURGLEVBRUUsR0FGRixFQUVRO0FBRU4sTUFBSSxVQUFVLEdBQUcsT0FBTyxPQUFQLEtBQW1CLFVBQW5CLEdBQWdDLE9BQU8sQ0FBQyxJQUF4QyxHQUErQyxTQUFoRTtBQUNBLE1BQUksVUFBVSxLQUFLLFNBQW5CLEVBQThCO0FBRTlCLE1BQUksVUFBVSxHQUFHLFVBQVUsQ0FBQyxHQUFELENBQTNCOztBQUNBLE1BQUksVUFBVSxLQUFLLFNBQW5CLEVBQThCO0FBQzVCLFdBQU8sVUFBUDtBQUNEOztBQUNELFNBQU8sVUFBVSxDQUFDLEdBQWxCO0FBQ0Q7O0FBT0QsU0FBUyxjQUFULENBQ0UsT0FERixFQUVFLFFBRkYsRUFFcUI7QUFFbkIsTUFBSSxRQUFRLEtBQUssVUFBYixJQUEyQixRQUFRLEtBQUssT0FBNUMsRUFBcUQ7QUFDbkQs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QUFrQixDQUF0QixFQUF5QjtBQUN2QixjQUFNLGdCQUFnQixDQUFDLEtBQUQsRUFBUSxJQUFSLEVBQWMsR0FBZCxDQUF0QjtBQUNELE9BRkQsTUFFTztBQUNMLGNBQU0saUJBQWlCLENBQUMsS0FBRCxFQUFRLElBQVIsRUFBYyxHQUFkLENBQXZCO0FBQ0Q7QUFDRjtBQUNGLEdBVk0sTUFVQTtBQUNMLElBQUEsR0FBRyxDQUFDLElBQUQsRUFBTyxHQUFQLEVBQVksTUFBWixDQUFIO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTLFdBQVQsQ0FBcUIsS0FBckIsRUFBMEMsS0FBMUMsRUFBeUQsTUFBekQsRUFBaUc7QUFDL0YsTUFBSSxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixJQUFBLEtBQUssQ0FBQyxNQUFOLENBQWEsS0FBYixFQUFvQixDQUFwQjtBQUNBLFdBQU8sQ0FBUDtBQUNELEdBSEQsTUFHTyxJQUFJLEtBQUssQ0FBQyxPQUFOLENBQWMsTUFBZCxDQUFKLEVBQTJCO0FBQ2hDLElBQUEsS0FBSyxDQUFDLE1BQU4sQ0FBYSxLQUFiLEVBQW9CLENBQXBCLEVBQXVCLEdBQUcsTUFBMUI7QUFDQSxXQUFPLE1BQU0sQ0FBQyxNQUFkO0FBQ0QsR0FITSxNQUdBO0FBQ0wsSUFBQSxLQUFLLENBQUMsTUFBTixDQUFhLEtBQWIsRUFBb0IsQ0FBcEIsRUFBdUIsTUFBdkI7QUFDQSxXQUFPLENBQVA7QUFDRDtBQUNGOztBQUVELGVBQWMsU0FBVSxRQUFWLENBQW1CLElBQW5CLEVBQXFDLE9BQXJDLEVBQXlEO0FBQ3JFLE1BQUksSUFBSSxHQUFHLElBQUksVUFBSixDQUFlLElBQWYsQ0FBWDtBQUNBLEVBQUEsU0FBUyxDQUFDLE9BQUQsRUFBVSxJQUFWLENBQVQ7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExPQ0FMX0RFQlVHIH0gZnJvbSAnQGdsaW1tZXIvbG9jYWwtZGVidWctZmxhZ3MnO1xuaW1wb3J0IHsgZGVwcmVjYXRlIH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5cbmltcG9ydCAqIGFzIEFTVHYxIGZyb20gJy4uL3YxL2FwaSc7XG5pbXBvcnQgdmlzaXRvcktleXMsIHsgVmlzaXRvcktleSwgVmlzaXRvcktleXMgfSBmcm9tICcuLi92MS92aXNpdG9yLWtleXMnO1xuaW1wb3J0IHtcbiAgY2Fubm90UmVtb3ZlTm9kZSxcbiAgY2Fubm90UmVwbGFjZU5vZGUsXG4gIGNhbm5vdFJlcGxhY2VPclJlbW92ZUluS2V5SGFuZGxlcllldCxcbn0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IFdhbGtlclBhdGggZnJvbSAnLi9wYXRoJztcbmltcG9ydCB7IEtleUhhbmRsZXIsIEtleVRyYXZlcnNhbCwgTm9kZUhhbmRsZXIsIE5vZGVUcmF2ZXJzYWwsIE5vZGVWaXNpdG9yIH0gZnJvbSAnLi92aXNpdG9yJztcblxuZnVuY3Rpb24gZ2V0RW50ZXJGdW5jdGlvbjxOIGV4dGVuZHMgQVNUdjEuTm9kZT4oXG4gIGhhbmRsZXI6IE5vZGVUcmF2ZXJzYWw8Tj5cbik6IE5vZGVIYW5kbGVyPE4+IHwgdW5kZWZpbmVkO1xuZnVuY3Rpb24gZ2V0RW50ZXJGdW5jdGlvbjxOIGV4dGVuZHMgQVNUdjEuTm9kZSwgSyBleHRlbmRzIFZpc2l0b3JLZXk8Tj4+KFxuICBoYW5kbGVyOiBLZXlUcmF2ZXJzYWw8TiwgSz5cbik6IEtleUhhbmRsZXI8TiwgSz4gfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiBnZXRFbnRlckZ1bmN0aW9uPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlLCBLIGV4dGVuZHMgVmlzaXRvcktleTxOPj4oXG4gIGhhbmRsZXI6IE5vZGVUcmF2ZXJzYWw8Tj4gfCBLZXlUcmF2ZXJzYWw8TiwgSz5cbik6IE5vZGVIYW5kbGVyPE4+IHwgS2V5SGFuZGxlcjxOLCBLPiB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBoYW5kbGVyO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBoYW5kbGVyLmVudGVyIGFzIE5vZGVIYW5kbGVyPE4+IHwgS2V5SGFuZGxlcjxOLCBLPjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRFeGl0RnVuY3Rpb248TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+XG4pOiBOb2RlSGFuZGxlcjxOPiB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIGdldEV4aXRGdW5jdGlvbjxOIGV4dGVuZHMgQVNUdjEuTm9kZSwgSyBleHRlbmRzIFZpc2l0b3JLZXk8Tj4+KFxuICBoYW5kbGVyOiBLZXlUcmF2ZXJzYWw8TiwgSz5cbik6IEtleUhhbmRsZXI8TiwgSz4gfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiBnZXRFeGl0RnVuY3Rpb248TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBWaXNpdG9yS2V5PE4+PihcbiAgaGFuZGxlcjogTm9kZVRyYXZlcnNhbDxOPiB8IEtleVRyYXZlcnNhbDxOLCBLPlxuKTogTm9kZUhhbmRsZXI8Tj4gfCBLZXlIYW5kbGVyPE4sIEs+IHwgdW5kZWZpbmVkIHtcbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gaGFuZGxlci5leGl0IGFzIE5vZGVIYW5kbGVyPE4+IHwgS2V5SGFuZGxlcjxOLCBLPjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRLZXlIYW5kbGVyPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlLCBLIGV4dGVuZHMgVmlzaXRvcktleTxOPj4oXG4gIGhhbmRsZXI6IE5vZGVUcmF2ZXJzYWw8Tj4sXG4gIGtleTogS1xuKTogS2V5VHJhdmVyc2FsPE4sIEs+IHwgS2V5VHJhdmVyc2FsPE4sIFZpc2l0b3JLZXk8Tj4+IHwgdW5kZWZpbmVkIHtcbiAgbGV0IGtleVZpc2l0b3IgPSB0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJyA/IGhhbmRsZXIua2V5cyA6IHVuZGVmaW5lZDtcbiAgaWYgKGtleVZpc2l0b3IgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gIGxldCBrZXlIYW5kbGVyID0ga2V5VmlzaXRvcltrZXldO1xuICBpZiAoa2V5SGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGtleUhhbmRsZXIgYXMgS2V5VHJhdmVyc2FsPE4sIEs+O1xuICB9XG4gIHJldHVybiBrZXlWaXNpdG9yLkFsbDtcbn1cblxuZnVuY3Rpb24gZ2V0Tm9kZUhhbmRsZXI8TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICB2aXNpdG9yOiBOb2RlVmlzaXRvcixcbiAgbm9kZVR5cGU6IE5bJ3R5cGUnXVxuKTogTm9kZVRyYXZlcnNhbDxOPjtcbmZ1bmN0aW9uIGdldE5vZGVIYW5kbGVyKHZpc2l0b3I6IE5vZGVWaXNpdG9yLCBub2RlVHlwZTogJ0FsbCcpOiBOb2RlVHJhdmVyc2FsPEFTVHYxLk5vZGU+O1xuZnVuY3Rpb24gZ2V0Tm9kZUhhbmRsZXI8TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICB2aXNpdG9yOiBOb2RlVmlzaXRvcixcbiAgbm9kZVR5cGU6IE5bJ3R5cGUnXVxuKTogTm9kZVRyYXZlcnNhbDxBU1R2MS5Ob2RlPiB8IHVuZGVmaW5lZCB7XG4gIGlmIChub2RlVHlwZSA9PT0gJ1RlbXBsYXRlJyB8fCBub2RlVHlwZSA9PT0gJ0Jsb2NrJykge1xuICAgIGlmICh2aXNpdG9yLlByb2dyYW0pIHtcbiAgICAgIGlmIChMT0NBTF9ERUJVRykge1xuICAgICAgICBkZXByZWNhdGUoXG4gICAgICAgICAgYFRoZSAnUHJvZ3JhbScgdmlzaXRvciBub2RlIGlzIGRlcHJlY2F0ZWQuIFVzZSAnVGVtcGxhdGUnIG9yICdCbG9jaycgaW5zdGVhZCAobm9kZSB3YXMgJyR7bm9kZVR5cGV9JykgYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmlzaXRvci5Qcm9ncmFtIGFzIE5vZGVUcmF2ZXJzYWw8QVNUdjEuTm9kZT47XG4gICAgfVxuICB9XG5cbiAgbGV0IGhhbmRsZXIgPSB2aXNpdG9yW25vZGVUeXBlXTtcbiAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiAoaGFuZGxlciBhcyB1bmtub3duKSBhcyBOb2RlVHJhdmVyc2FsPEFTVHYxLk5vZGU+O1xuICB9XG4gIHJldHVybiB2aXNpdG9yLkFsbDtcbn1cblxuZnVuY3Rpb24gdmlzaXROb2RlPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlPihcbiAgdmlzaXRvcjogTm9kZVZpc2l0b3IsXG4gIHBhdGg6IFdhbGtlclBhdGg8Tj5cbik6IEFTVHYxLk5vZGUgfCBBU1R2MS5Ob2RlW10gfCB1bmRlZmluZWQgfCBudWxsIHwgdm9pZCB7XG4gIGxldCB7IG5vZGUsIHBhcmVudCwgcGFyZW50S2V5IH0gPSBwYXRoO1xuXG4gIGxldCBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+ID0gZ2V0Tm9kZUhhbmRsZXIodmlzaXRvciwgbm9kZS50eXBlKTtcbiAgbGV0IGVudGVyO1xuICBsZXQgZXhpdDtcblxuICBpZiAoaGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW50ZXIgPSBnZXRFbnRlckZ1bmN0aW9uKGhhbmRsZXIpO1xuICAgIGV4aXQgPSBnZXRFeGl0RnVuY3Rpb24oaGFuZGxlcik7XG4gIH1cblxuICBsZXQgcmVzdWx0OiBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdIHwgdW5kZWZpbmVkIHwgbnVsbCB8IHZvaWQ7XG4gIGlmIChlbnRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0ID0gZW50ZXIobm9kZSwgcGF0aCk7XG4gIH1cblxuICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQgJiYgcmVzdWx0ICE9PSBudWxsKSB7XG4gICAgaWYgKEpTT04uc3RyaW5naWZ5KG5vZGUpID09PSBKU09OLnN0cmluZ2lmeShyZXN1bHQpKSB7XG4gICAgICByZXN1bHQgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgIHZpc2l0QXJyYXkodmlzaXRvciwgcmVzdWx0LCBwYXJlbnQsIHBhcmVudEtleSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcGF0aCA9IG5ldyBXYWxrZXJQYXRoKHJlc3VsdCwgcGFyZW50LCBwYXJlbnRLZXkpO1xuICAgICAgcmV0dXJuIHZpc2l0Tm9kZSh2aXNpdG9yLCBwYXRoKSB8fCByZXN1bHQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGV0IGtleXMgPSB2aXNpdG9yS2V5c1tub2RlLnR5cGVdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQga2V5ID0ga2V5c1tpXSBhcyBWaXNpdG9yS2V5c1tOWyd0eXBlJ11dICYga2V5b2YgTjtcbiAgICAgIC8vIHdlIGtub3cgaWYgaXQgaGFzIGNoaWxkIGtleXMgd2UgY2FuIHdpZGVuIHRvIGEgUGFyZW50Tm9kZVxuICAgICAgdmlzaXRLZXkodmlzaXRvciwgaGFuZGxlciwgcGF0aCwga2V5KTtcbiAgICB9XG5cbiAgICBpZiAoZXhpdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHQgPSBleGl0KG5vZGUsIHBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGdldDxOIGV4dGVuZHMgQVNUdjEuTm9kZT4oXG4gIG5vZGU6IE4sXG4gIGtleTogVmlzaXRvcktleXNbTlsndHlwZSddXSAmIGtleW9mIE5cbik6IEFTVHYxLk5vZGUgfCBBU1R2MS5Ob2RlW10ge1xuICByZXR1cm4gKG5vZGVba2V5XSBhcyB1bmtub3duKSBhcyBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdO1xufVxuXG5mdW5jdGlvbiBzZXQ8TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBrZXlvZiBOPihub2RlOiBOLCBrZXk6IEssIHZhbHVlOiBOW0tdKTogdm9pZCB7XG4gIG5vZGVba2V5XSA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiB2aXNpdEtleTxOIGV4dGVuZHMgQVNUdjEuTm9kZT4oXG4gIHZpc2l0b3I6IE5vZGVWaXNpdG9yLFxuICBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+LFxuICBwYXRoOiBXYWxrZXJQYXRoPE4+LFxuICBrZXk6IFZpc2l0b3JLZXlzW05bJ3R5cGUnXV0gJiBrZXlvZiBOXG4pIHtcbiAgbGV0IHsgbm9kZSB9ID0gcGF0aDtcblxuICBsZXQgdmFsdWUgPSBnZXQobm9kZSwga2V5KTtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBrZXlFbnRlcjtcbiAgbGV0IGtleUV4aXQ7XG5cbiAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIGxldCBrZXlIYW5kbGVyID0gZ2V0S2V5SGFuZGxlcihoYW5kbGVyLCBrZXkpO1xuICAgIGlmIChrZXlIYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGtleUVudGVyID0gZ2V0RW50ZXJGdW5jdGlvbihrZXlIYW5kbGVyKTtcbiAgICAgIGtleUV4aXQgPSBnZXRFeGl0RnVuY3Rpb24oa2V5SGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgaWYgKGtleUVudGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoa2V5RW50ZXIobm9kZSwga2V5KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBjYW5ub3RSZXBsYWNlT3JSZW1vdmVJbktleUhhbmRsZXJZZXQobm9kZSwga2V5KTtcbiAgICB9XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICB2aXNpdEFycmF5KHZpc2l0b3IsIHZhbHVlLCBwYXRoLCBrZXkpO1xuICB9IGVsc2Uge1xuICAgIGxldCBrZXlQYXRoID0gbmV3IFdhbGtlclBhdGgodmFsdWUsIHBhdGgsIGtleSk7XG4gICAgbGV0IHJlc3VsdCA9IHZpc2l0Tm9kZSh2aXNpdG9yLCBrZXlQYXRoKTtcbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFRPRE86IGR5bmFtaWNhbGx5IGNoZWNrIHRoZSByZXN1bHRzIGJ5IGhhdmluZyBhIHRhYmxlIG9mXG4gICAgICAvLyBleHBlY3RlZCBub2RlIHR5cGVzIGluIHZhbHVlIHNwYWNlLCBub3QganVzdCB0eXBlIHNwYWNlXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgYXNzaWduS2V5KG5vZGUsIGtleSwgdmFsdWUsIHJlc3VsdCBhcyBhbnkpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChrZXlFeGl0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoa2V5RXhpdChub2RlLCBrZXkpICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IGNhbm5vdFJlcGxhY2VPclJlbW92ZUluS2V5SGFuZGxlcllldChub2RlLCBrZXkpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB2aXNpdEFycmF5KFxuICB2aXNpdG9yOiBOb2RlVmlzaXRvcixcbiAgYXJyYXk6IEFTVHYxLk5vZGVbXSxcbiAgcGFyZW50OiBXYWxrZXJQYXRoPEFTVHYxLk5vZGU+IHwgbnVsbCxcbiAgcGFyZW50S2V5OiBzdHJpbmcgfCBudWxsXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgIGxldCBub2RlID0gYXJyYXlbaV07XG4gICAgbGV0IHBhdGggPSBuZXcgV2Fsa2VyUGF0aChub2RlLCBwYXJlbnQsIHBhcmVudEtleSk7XG4gICAgbGV0IHJlc3VsdCA9IHZpc2l0Tm9kZSh2aXNpdG9yLCBwYXRoKTtcbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGkgKz0gc3BsaWNlQXJyYXkoYXJyYXksIGksIHJlc3VsdCkgLSAxO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NpZ25LZXk8TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBWaXNpdG9yS2V5PE4+PihcbiAgbm9kZTogTixcbiAga2V5OiBLLFxuICB2YWx1ZTogQVNUdjEuTm9kZSxcbiAgcmVzdWx0OiBOW0tdIHwgW05bS11dIHwgbnVsbFxuKSB7XG4gIGlmIChyZXN1bHQgPT09IG51bGwpIHtcbiAgICB0aHJvdyBjYW5ub3RSZW1vdmVOb2RlKHZhbHVlLCBub2RlLCBrZXkpO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocmVzdWx0KSkge1xuICAgIGlmIChyZXN1bHQubGVuZ3RoID09PSAxKSB7XG4gICAgICBzZXQobm9kZSwga2V5LCByZXN1bHRbMF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocmVzdWx0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBjYW5ub3RSZW1vdmVOb2RlKHZhbHVlLCBub2RlLCBrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgY2Fubm90UmVwbGFjZU5vZGUodmFsdWUsIG5vZGUsIGtleSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHNldChub2RlLCBrZXksIHJlc3VsdCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc3BsaWNlQXJyYXkoYXJyYXk6IEFTVHYxLk5vZGVbXSwgaW5kZXg6IG51bWJlciwgcmVzdWx0OiBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdIHwgbnVsbCkge1xuICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgYXJyYXkuc3BsaWNlKGluZGV4LCAxKTtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICBhcnJheS5zcGxpY2UoaW5kZXgsIDEsIC4uLnJlc3VsdCk7XG4gICAgcmV0dXJuIHJlc3VsdC5sZW5ndGg7XG4gIH0gZWxzZSB7XG4gICAgYXJyYXkuc3BsaWNlKGluZGV4LCAxLCByZXN1bHQpO1xuICAgIHJldHVybiAxO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyYXZlcnNlKG5vZGU6IEFTVHYxLk5vZGUsIHZpc2l0b3I6IE5vZGVWaXNpdG9yKTogdm9pZCB7XG4gIGxldCBwYXRoID0gbmV3IFdhbGtlclBhdGgobm9kZSk7XG4gIHZpc2l0Tm9kZSh2aXNpdG9yLCBwYXRoKTtcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=