UNPKG

travels

Version:

A fast, framework-agnostic undo/redo core library powered by Mutative JSON Patch

554 lines 79.4 kB
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