travels
Version:
A fast, framework-agnostic undo/redo core library powered by Mutative JSON Patch
554 lines • 79.4 kB
JavaScript
import { __rest } from "tslib";
import { apply, create, rawReturn, } from 'mutative';
import { isObjectLike, isPlainObject } from './utils';
const cloneTravelPatches = (base) => ({
patches: base ? base.patches.map((patch) => [...patch]) : [],
inversePatches: base ? base.inversePatches.map((patch) => [...patch]) : [],
});
const deepCloneValue = (value) => {
if (value === null || typeof value !== 'object') {
return value;
}
if (Array.isArray(value)) {
return value.map(deepCloneValue);
}
const cloned = {};
for (const key in value) {
if (Object.prototype.hasOwnProperty.call(value, key)) {
cloned[key] = deepCloneValue(value[key]);
}
}
return cloned;
};
const deepClone = (source, target) => {
if (target && source && typeof source === 'object') {
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = deepCloneValue(source[key]);
}
}
return target;
}
return deepCloneValue(source);
};
const hasOnlyArrayIndices = (value) => {
if (!Array.isArray(value)) {
return false;
}
return Reflect.ownKeys(value).every((key) => {
if (key === 'length') {
return true;
}
if (typeof key === 'symbol') {
return false;
}
const index = Number(key);
return Number.isInteger(index) && index >= 0 && String(index) === key;
});
};
// Align mutable value updates with immutable replacements by syncing objects
const overwriteDraftWith = (draft, value) => {
const draftIsArray = Array.isArray(draft);
const valueIsArray = Array.isArray(value);
const draftKeys = Reflect.ownKeys(draft);
for (const key of draftKeys) {
if (draftIsArray && key === 'length') {
continue;
}
if (!Object.prototype.hasOwnProperty.call(value, key)) {
delete draft[key];
}
}
if (draftIsArray && valueIsArray) {
draft.length = value.length;
}
Object.assign(draft, value);
};
/**
* Core Travels class for managing undo/redo history
*/
export class Travels {
constructor(initialState, options = {}) {
this.listeners = new Set();
this.pendingState = null;
this.historyCache = null;
this.historyVersion = 0;
this.mutableFallbackWarned = false;
/**
* Subscribe to state changes
* @returns Unsubscribe function
*/
this.subscribe = (listener) => {
this.listeners.add(listener);
return () => {
this.listeners.delete(listener);
};
};
/**
* Get the current state
*/
this.getState = () => this.state;
const { maxHistory = 10, initialPatches, initialPosition = 0, autoArchive = true, mutable = false, patchesOptions } = options, mutativeOptions = __rest(options, ["maxHistory", "initialPatches", "initialPosition", "autoArchive", "mutable", "patchesOptions"]);
// Validate and enforce maxHistory constraints
if (maxHistory < 0) {
throw new Error(`Travels: maxHistory must be non-negative, but got ${maxHistory}`);
}
if (maxHistory === 0 && process.env.NODE_ENV !== 'production') {
console.warn('Travels: maxHistory is 0, which disables undo/redo history. This is rarely intended.');
}
// Validate options in development mode
if (process.env.NODE_ENV !== 'production') {
if (initialPatches) {
if (!Array.isArray(initialPatches.patches) ||
!Array.isArray(initialPatches.inversePatches)) {
console.error(`Travels: initialPatches must have 'patches' and 'inversePatches' arrays`);
}
else if (initialPatches.patches.length !== initialPatches.inversePatches.length) {
console.error(`Travels: initialPatches.patches and initialPatches.inversePatches must have the same length`);
}
}
}
this.state = initialState;
// For mutable mode, deep clone initialState to prevent mutations
this.initialState = mutable ? deepClone(initialState) : initialState;
this.maxHistory = maxHistory;
this.autoArchive = autoArchive;
this.mutable = mutable;
this.options = Object.assign(Object.assign({}, mutativeOptions), { enablePatches: patchesOptions !== null && patchesOptions !== void 0 ? patchesOptions : true });
const { patches: normalizedPatches, position: normalizedPosition } = this.normalizeInitialHistory(initialPatches, initialPosition);
this.allPatches = normalizedPatches;
this.initialPatches = initialPatches
? cloneTravelPatches(normalizedPatches)
: undefined;
this.position = normalizedPosition;
this.initialPosition = normalizedPosition;
this.tempPatches = cloneTravelPatches();
}
normalizeInitialHistory(initialPatches, initialPosition) {
const cloned = cloneTravelPatches(initialPatches);
const total = cloned.patches.length;
const historyLimit = this.maxHistory > 0 ? this.maxHistory : 0;
const invalidInitialPosition = typeof initialPosition !== 'number' || !Number.isFinite(initialPosition);
let position = invalidInitialPosition ? 0 : initialPosition;
const clampedPosition = Math.max(0, Math.min(position, total));
if (process.env.NODE_ENV !== 'production' &&
(invalidInitialPosition || clampedPosition !== position)) {
console.warn(`Travels: initialPosition (${initialPosition}) is invalid for available patches (${total}). ` +
`Using ${clampedPosition} instead.`);
}
position = clampedPosition;
if (total === 0) {
return { patches: cloned, position: 0 };
}
if (historyLimit === 0) {
if (process.env.NODE_ENV !== 'production') {
console.warn(`Travels: maxHistory (${this.maxHistory}) discards persisted history.`);
}
return { patches: cloneTravelPatches(), position: 0 };
}
if (historyLimit >= total) {
return { patches: cloned, position };
}
const trim = total - historyLimit;
const trimmedBase = {
patches: cloned.patches.slice(-historyLimit),
inversePatches: cloned.inversePatches.slice(-historyLimit),
};
const trimmed = cloneTravelPatches(trimmedBase);
const adjustedPosition = Math.max(0, Math.min(historyLimit, position - trim));
if (process.env.NODE_ENV !== 'production') {
console.warn(`Travels: initialPatches length (${total}) exceeds maxHistory (${historyLimit}). ` +
`Trimmed to last ${historyLimit} steps. Position adjusted to ${adjustedPosition}.`);
}
return {
patches: trimmed,
position: adjustedPosition,
};
}
invalidateHistoryCache() {
this.historyVersion += 1;
this.historyCache = null;
}
/**
* Notify all listeners of state changes
*/
notify() {
this.listeners.forEach((listener) => listener(this.state, this.getPatches(), this.position));
}
/**
* Check if patches contain root-level replacement operations
* Root replacement cannot be done mutably as it changes the type/value of the entire state
*/
hasRootReplacement(patches) {
return patches.some((patch) => Array.isArray(patch.path) &&
patch.path.length === 0 &&
patch.op === 'replace');
}
/**
* Update the state
*/
setState(updater) {
let patches;
let inversePatches;
const canUseMutableRoot = this.mutable && isObjectLike(this.state);
const isFunctionUpdater = typeof updater === 'function';
const stateIsArray = Array.isArray(this.state);
const updaterIsArray = Array.isArray(updater);
const canMutatePlainObjects = !stateIsArray &&
!updaterIsArray &&
isPlainObject(this.state) &&
isPlainObject(updater);
const canMutateArrays = stateIsArray &&
updaterIsArray &&
hasOnlyArrayIndices(this.state) &&
hasOnlyArrayIndices(updater);
const canMutateWithValue = canUseMutableRoot &&
!isFunctionUpdater &&
(canMutateArrays || canMutatePlainObjects);
const useMutable = (isFunctionUpdater && canUseMutableRoot) || canMutateWithValue;
if (this.mutable && !canUseMutableRoot && !this.mutableFallbackWarned) {
this.mutableFallbackWarned = true;
if (process.env.NODE_ENV !== 'production') {
console.warn('Travels: mutable mode requires the state root to be an object. Falling back to immutable updates.');
}
}
if (useMutable) {
// For observable state: generate patches then apply mutably
[, patches, inversePatches] = create(this.state, isFunctionUpdater
? updater
: (draft) => {
overwriteDraftWith(draft, updater);
}, this.options);
// Apply patches to mutate the existing state object
apply(this.state, patches, { mutable: true });
// Keep the same reference
this.pendingState = this.state;
}
else {
// For immutable state: create new object
const [nextState, p, ip] = (typeof updater === 'function'
? create(this.state, updater, this.options)
: create(this.state, () => isObjectLike(updater)
? rawReturn(updater)
: updater, this.options));
patches = p;
inversePatches = ip;
this.state = nextState;
this.pendingState = nextState;
}
// Reset pendingState asynchronously
Promise.resolve().then(() => {
this.pendingState = null;
});
const hasNoChanges = patches.length === 0 && inversePatches.length === 0;
if (hasNoChanges) {
return;
}
if (this.autoArchive) {
const notLast = this.position < this.allPatches.patches.length;
// Remove all patches after the current position
if (notLast) {
this.allPatches.patches.splice(this.position, this.allPatches.patches.length - this.position);
this.allPatches.inversePatches.splice(this.position, this.allPatches.inversePatches.length - this.position);
}
this.allPatches.patches.push(patches);
this.allPatches.inversePatches.push(inversePatches);
this.position =
this.maxHistory < this.allPatches.patches.length
? this.maxHistory
: this.position + 1;
if (this.maxHistory < this.allPatches.patches.length) {
// Handle maxHistory = 0 case: clear all patches
if (this.maxHistory === 0) {
this.allPatches.patches = [];
this.allPatches.inversePatches = [];
}
else {
this.allPatches.patches = this.allPatches.patches.slice(-this.maxHistory);
this.allPatches.inversePatches = this.allPatches.inversePatches.slice(-this.maxHistory);
}
}
}
else {
const notLast = this.position <
this.allPatches.patches.length +
Number(!!this.tempPatches.patches.length);
// Remove all patches after the current position
if (notLast) {
this.allPatches.patches.splice(this.position, this.allPatches.patches.length - this.position);
this.allPatches.inversePatches.splice(this.position, this.allPatches.inversePatches.length - this.position);
}
if (!this.tempPatches.patches.length || notLast) {
this.position =
this.maxHistory < this.allPatches.patches.length + 1
? this.maxHistory
: this.position + 1;
}
if (notLast) {
this.tempPatches.patches.length = 0;
this.tempPatches.inversePatches.length = 0;
}
this.tempPatches.patches.push(patches);
this.tempPatches.inversePatches.push(inversePatches);
}
this.invalidateHistoryCache();
this.notify();
}
/**
* Archive the current state (only for manual archive mode)
*/
archive() {
var _a;
if (this.autoArchive) {
console.warn('Auto archive is enabled, no need to archive manually');
return;
}
if (!this.tempPatches.patches.length)
return;
// Use pendingState if available, otherwise use current state
const stateToUse = ((_a = this.pendingState) !== null && _a !== void 0 ? _a : this.state);
// Merge temp patches
const [, patches, inversePatches] = create(stateToUse, (draft) => apply(draft, this.tempPatches.inversePatches.flat().reverse()), this.options);
this.allPatches.patches.push(inversePatches);
this.allPatches.inversePatches.push(patches);
// Respect maxHistory limit
if (this.maxHistory < this.allPatches.patches.length) {
// Handle maxHistory = 0 case: clear all patches
if (this.maxHistory === 0) {
this.allPatches.patches = [];
this.allPatches.inversePatches = [];
}
else {
this.allPatches.patches = this.allPatches.patches.slice(-this.maxHistory);
this.allPatches.inversePatches = this.allPatches.inversePatches.slice(-this.maxHistory);
}
}
// Clear temporary patches after archiving
this.tempPatches.patches.length = 0;
this.tempPatches.inversePatches.length = 0;
this.invalidateHistoryCache();
this.notify();
}
/**
* Get all patches including temporary patches
*/
getAllPatches() {
const shouldArchive = !this.autoArchive && !!this.tempPatches.patches.length;
if (shouldArchive) {
return {
patches: this.allPatches.patches.concat([
this.tempPatches.patches.flat(),
]),
inversePatches: this.allPatches.inversePatches.concat([
this.tempPatches.inversePatches.flat().reverse(),
]),
};
}
return this.allPatches;
}
/**
* Get the complete history of states
*
* @returns The history array. Reference equality indicates cache hit.
*
* @remarks
* **IMPORTANT**: Do not modify the returned array. It is cached internally.
* - In development mode, the array is frozen
* - In production mode, modifications will corrupt the cache
*/
getHistory() {
if (this.historyCache &&
this.historyCache.version === this.historyVersion) {
return this.historyCache.history;
}
const history = [this.state];
let currentState = this.state;
const _allPatches = this.getAllPatches();
const patches = !this.autoArchive && _allPatches.patches.length > this.maxHistory
? _allPatches.patches.slice(_allPatches.patches.length - this.maxHistory)
: _allPatches.patches;
const inversePatches = !this.autoArchive && _allPatches.inversePatches.length > this.maxHistory
? _allPatches.inversePatches.slice(_allPatches.inversePatches.length - this.maxHistory)
: _allPatches.inversePatches;
// Build future history
for (let i = this.position; i < patches.length; i++) {
currentState = apply(currentState, patches[i]);
history.push(currentState);
}
// Build past history
currentState = this.state;
for (let i = this.position - 1; i > -1; i--) {
currentState = apply(currentState, inversePatches[i]);
history.unshift(currentState);
}
this.historyCache = {
version: this.historyVersion,
history,
};
// In development mode, freeze the history array to prevent accidental mutations
if (process.env.NODE_ENV !== 'production') {
Object.freeze(history);
}
return history;
}
/**
* Go to a specific position in the history
*/
go(nextPosition) {
const shouldArchive = !this.autoArchive && !!this.tempPatches.patches.length;
if (shouldArchive) {
this.archive();
}
const _allPatches = this.getAllPatches();
const back = nextPosition < this.position;
if (nextPosition > _allPatches.patches.length) {
console.warn(`Can't go forward to position ${nextPosition}`);
nextPosition = _allPatches.patches.length;
}
if (nextPosition < 0) {
console.warn(`Can't go back to position ${nextPosition}`);
nextPosition = 0;
}
if (nextPosition === this.position)
return;
if (shouldArchive) {
const lastInversePatch = _allPatches.inversePatches.slice(-1)[0];
_allPatches.inversePatches[_allPatches.inversePatches.length - 1] = [
...lastInversePatch,
].reverse();
}
const patchesToApply = back
? _allPatches.inversePatches
.slice(-this.maxHistory)
.slice(nextPosition, this.position)
.flat()
.reverse()
: _allPatches.patches
.slice(-this.maxHistory)
.slice(this.position, nextPosition)
.flat();
// Can only use mutable mode if:
// 1. mutable mode is enabled
// 2. current state is an object
// 3. patches don't contain root-level replacements (which change the entire state)
const canGoMutably = this.mutable &&
isObjectLike(this.state) &&
!this.hasRootReplacement(patchesToApply);
if (canGoMutably) {
// For observable state: mutate in place
apply(this.state, patchesToApply, { mutable: true });
}
else {
// For immutable state or primitive types: create new state
this.state = apply(this.state, patchesToApply);
}
this.position = nextPosition;
this.invalidateHistoryCache();
this.notify();
}
/**
* Go back in the history
*/
back(amount = 1) {
this.go(this.position - amount);
}
/**
* Go forward in the history
*/
forward(amount = 1) {
this.go(this.position + amount);
}
/**
* Reset to the initial state
*/
reset() {
const canResetMutably = this.mutable &&
isObjectLike(this.state) &&
isObjectLike(this.initialState);
if (canResetMutably) {
// For observable state: use patch system to reset to initial state
// Generate patches from current state to initial state
const [, patches] = create(this.state, (draft) => {
// Clear all properties
for (const key of Object.keys(draft)) {
delete draft[key];
}
// Deep copy all properties from initialState
deepClone(this.initialState, draft);
}, this.options);
apply(this.state, patches, { mutable: true });
}
else {
// For immutable state: reassign reference
this.state = this.initialState;
}
this.position = this.initialPosition;
this.allPatches = cloneTravelPatches(this.initialPatches);
this.tempPatches = cloneTravelPatches();
this.invalidateHistoryCache();
this.notify();
}
/**
* Check if it's possible to go back
*/
canBack() {
return this.position > 0;
}
/**
* Check if it's possible to go forward
*/
canForward() {
const shouldArchive = !this.autoArchive && !!this.tempPatches.patches.length;
const _allPatches = this.getAllPatches();
// Temporary patches represent the current state, not a future state
return shouldArchive
? this.position < _allPatches.patches.length - 1
: this.position < _allPatches.patches.length;
}
/**
* Check if it's possible to archive the current state
*/
canArchive() {
return !this.autoArchive && !!this.tempPatches.patches.length;
}
/**
* Get the current position in the history
*/
getPosition() {
return this.position;
}
/**
* Get the patches history
*/
getPatches() {
const shouldArchive = !this.autoArchive && !!this.tempPatches.patches.length;
return shouldArchive ? this.getAllPatches() : this.allPatches;
}
/**
* Get the controls object
*/
getControls() {
const self = this;
const controls = {
get position() {
return self.getPosition();
},
getHistory: () => self.getHistory(),
get patches() {
return self.getPatches();
},
back: (amount) => self.back(amount),
forward: (amount) => self.forward(amount),
reset: () => self.reset(),
go: (position) => self.go(position),
canBack: () => self.canBack(),
canForward: () => self.canForward(),
};
if (!this.autoArchive) {
controls.archive = () => self.archive();
controls.canArchive = () => self.canArchive();
}
return controls;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhdmVscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90cmF2ZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBSUwsS0FBSyxFQUNMLE1BQU0sRUFDTixTQUFTLEdBQ1YsTUFBTSxVQUFVLENBQUM7QUFVbEIsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFXdEQsTUFBTSxrQkFBa0IsR0FBRyxDQUN6QixJQUF1QixFQUNMLEVBQUUsQ0FBQyxDQUFDO0lBQ3RCLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtJQUM1RCxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Q0FDM0UsQ0FBQyxDQUFDO0FBRUgsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFVLEVBQU8sRUFBRTtJQUN6QyxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDaEQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBd0IsRUFBRSxDQUFDO0lBQ3ZDLEtBQUssTUFBTSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7UUFDeEIsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFD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QUFDLE9BQU8sR0FBRyxHQUFTLEVBQUUsQ0FDaEUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2hCLFFBQTJDLENBQUMsVUFBVSxHQUFHLEdBQVksRUFBRSxDQUN0RSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDdEIsQ0FBQztRQUVELE9BQU8sUUFFMkIsQ0FBQztJQUNyQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICB0eXBlIE9wdGlvbnMgYXMgTXV0YXRpdmVPcHRpb25zLFxuICB0eXBlIFBhdGNoZXMsXG4gIHR5cGUgRHJhZnQsXG4gIGFwcGx5LFxuICBjcmVhdGUsXG4gIHJhd1JldHVybixcbn0gZnJvbSAnbXV0YXRpdmUnO1xuaW1wb3J0IHR5cGUge1xuICBNYW51YWxUcmF2ZWxzQ29udHJvbHMsXG4gIFBhdGNoZXNPcHRpb24sXG4gIFRyYXZlbFBhdGNoZXMsXG4gIFRyYXZlbHNDb250cm9scyxcbiAgVHJhdmVsc09wdGlvbnMsXG4gIFVwZGF0ZXIsXG4gIFZhbHVlLFxufSBmcm9tICcuL3R5cGUnO1xuaW1wb3J0IHsgaXNPYmplY3RMaWtlLCBpc1BsYWluT2JqZWN0IH0gZnJvbSAnLi91dGlscyc7XG5cbi8qKlxuICogTGlzdGVuZXIgY2FsbGJhY2sgZm9yIHN0YXRlIGNoYW5nZXNcbiAqL1xudHlwZSBMaXN0ZW5lcjxTLCBQIGV4dGVuZHMgUGF0Y2hlc09wdGlvbiA9IHt9PiA9IChcbiAgc3RhdGU6IFMsXG4gIHBhdGNoZXM6IFRyYXZlbFBhdGNoZXM8UD4sXG4gIHBvc2l0aW9uOiBudW1iZXJcbikgPT4gdm9pZDtcblxuY29uc3QgY2xvbmVUcmF2ZWxQYXRjaGVzID0gPFAgZXh0ZW5kcyBQYXRjaGVzT3B0aW9uID0ge30+KFxuICBiYXNlPzogVHJhdmVsUGF0Y2hlczxQPlxuKTogVHJhdmVsUGF0Y2hlczxQPiA9PiAoe1xuICBwYXRjaGVzOiBiYXNlID8gYmFzZS5wYXRjaGVzLm1hcCgocGF0Y2gpID0+IFsuLi5wYXRjaF0pIDogW10sXG4gIGludmVyc2VQYXRjaGVzOiBiYXNlID8gYmFzZS5pbnZlcnNlUGF0Y2hlcy5tYXAoKHBhdGNoKSA9PiBbLi4ucGF0Y2hdKSA6IFtdLFxufSk7XG5cbmNvbnN0IGRlZXBDbG9uZVZhbHVlID0gKHZhbHVlOiBhbnkpOiBhbnkgPT4ge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5tYXAoZGVlcENsb25lVmFsdWUpO1xuICB9XG5cbiAgY29uc3QgY2xvbmVkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkge1xuICAgICAgY2xvbmVkW2tleV0gPSBkZWVwQ2xvbmVWYWx1ZSh2YWx1ZVtrZXldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2xvbmVkO1xufTtcblxuY29uc3QgZGVlcENsb25lID0gPFQ+KHNvdXJjZTogVCwgdGFyZ2V0PzogYW55KTogVCA9PiB7XG4gIGlmICh0YXJnZXQgJiYgc291cmNlICYmIHR5cGVvZiBzb3VyY2UgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gc291cmNlIGFzIGFueSkge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSBkZWVwQ2xvbmVWYWx1ZSgoc291cmNlIGFzIGFueSlba2V5XSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cblxuICByZXR1cm4gZGVlcENsb25lVmFsdWUoc291cmNlKTtcbn07XG5cbmNvbnN0IGhhc09ubHlBcnJheUluZGljZXMgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBhbnlbXSA9PiB7XG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZ