mimo-reasonix 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/package.json +1 -1
- package/node_modules/@alcalzone/ansi-tokenize/LICENSE +21 -0
- package/node_modules/@alcalzone/ansi-tokenize/README.md +278 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/ansiCodes.d.ts +7 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/ansiCodes.js +57 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/ansiCodes.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/consts.d.ts +17 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/consts.js +28 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/consts.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/diff.d.ts +6 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/diff.js +26 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/diff.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/index.d.ts +6 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/index.js +7 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/index.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/reduce.d.ts +5 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/reduce.js +37 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/reduce.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/styledChars.d.ts +6 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/styledChars.js +38 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/styledChars.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/tokenize.d.ts +16 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/tokenize.js +194 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/tokenize.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/undo.d.ts +3 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/undo.js +11 -0
- package/node_modules/@alcalzone/ansi-tokenize/build/undo.js.map +1 -0
- package/node_modules/@alcalzone/ansi-tokenize/package.json +55 -0
- package/node_modules/ansi-regex/index.d.ts +33 -0
- package/node_modules/ansi-regex/index.js +14 -0
- package/node_modules/ansi-regex/license +9 -0
- package/node_modules/ansi-regex/package.json +61 -0
- package/node_modules/ansi-regex/readme.md +66 -0
- package/node_modules/ansi-styles/index.d.ts +236 -0
- package/node_modules/ansi-styles/index.js +223 -0
- package/node_modules/ansi-styles/license +9 -0
- package/node_modules/ansi-styles/package.json +54 -0
- package/node_modules/ansi-styles/readme.md +173 -0
- package/node_modules/auto-bind/index.d.ts +50 -0
- package/node_modules/auto-bind/index.js +41 -0
- package/node_modules/auto-bind/license +9 -0
- package/node_modules/auto-bind/package.json +51 -0
- package/node_modules/auto-bind/react.d.ts +26 -0
- package/node_modules/auto-bind/react.js +28 -0
- package/node_modules/auto-bind/readme.md +92 -0
- package/node_modules/bidi-js/LICENSE.txt +22 -0
- package/node_modules/bidi-js/README.md +133 -0
- package/node_modules/bidi-js/dist/bidi.js +1010 -0
- package/node_modules/bidi-js/dist/bidi.min.js +1 -0
- package/node_modules/bidi-js/dist/bidi.min.mjs +1 -0
- package/node_modules/bidi-js/dist/bidi.mjs +1002 -0
- package/node_modules/bidi-js/package.json +39 -0
- package/node_modules/bidi-js/src/brackets.js +30 -0
- package/node_modules/bidi-js/src/charTypes.js +66 -0
- package/node_modules/bidi-js/src/data/bidiBrackets.data.js +5 -0
- package/node_modules/bidi-js/src/data/bidiCharTypes.data.js +25 -0
- package/node_modules/bidi-js/src/data/bidiMirroring.data.js +2 -0
- package/node_modules/bidi-js/src/embeddingLevels.js +690 -0
- package/node_modules/bidi-js/src/index.js +5 -0
- package/node_modules/bidi-js/src/mirroring.js +48 -0
- package/node_modules/bidi-js/src/reordering.js +99 -0
- package/node_modules/bidi-js/src/util/parseCharacterMap.js +30 -0
- package/node_modules/chalk/license +9 -0
- package/node_modules/chalk/package.json +83 -0
- package/node_modules/chalk/readme.md +297 -0
- package/node_modules/chalk/source/index.d.ts +325 -0
- package/node_modules/chalk/source/index.js +225 -0
- package/node_modules/chalk/source/utilities.js +33 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/node_modules/cli-boxes/boxes.json +82 -0
- package/node_modules/cli-boxes/index.d.ts +122 -0
- package/node_modules/cli-boxes/index.js +3 -0
- package/node_modules/cli-boxes/license +9 -0
- package/node_modules/cli-boxes/package.json +49 -0
- package/node_modules/cli-boxes/readme.md +103 -0
- package/node_modules/code-excerpt/dist/index.d.ts +9 -0
- package/node_modules/code-excerpt/dist/index.js +27 -0
- package/node_modules/code-excerpt/license +21 -0
- package/node_modules/code-excerpt/package.json +43 -0
- package/node_modules/code-excerpt/readme.md +65 -0
- package/node_modules/convert-to-spaces/dist/index.d.ts +2 -0
- package/node_modules/convert-to-spaces/dist/index.js +4 -0
- package/node_modules/convert-to-spaces/license +21 -0
- package/node_modules/convert-to-spaces/package.json +40 -0
- package/node_modules/convert-to-spaces/readme.md +39 -0
- package/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
- package/node_modules/emoji-regex/README.md +107 -0
- package/node_modules/emoji-regex/index.d.ts +3 -0
- package/node_modules/emoji-regex/index.js +4 -0
- package/node_modules/emoji-regex/index.mjs +4 -0
- package/node_modules/emoji-regex/package.json +45 -0
- package/node_modules/escape-string-regexp/index.d.ts +18 -0
- package/node_modules/escape-string-regexp/index.js +11 -0
- package/node_modules/escape-string-regexp/license +9 -0
- package/node_modules/escape-string-regexp/package.json +43 -0
- package/node_modules/escape-string-regexp/readme.md +29 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +18 -0
- package/node_modules/get-east-asian-width/lookup.js +135 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/indent-string/index.d.ts +38 -0
- package/node_modules/indent-string/index.js +38 -0
- package/node_modules/indent-string/license +9 -0
- package/node_modules/indent-string/package.json +40 -0
- package/node_modules/indent-string/readme.md +73 -0
- package/node_modules/ink/LICENSE +30 -0
- package/node_modules/ink/package.json +53 -0
- package/node_modules/ink/src/Ansi.tsx +254 -0
- package/node_modules/ink/src/_internal/debug.ts +27 -0
- package/node_modules/ink/src/_internal/earlyInput.ts +7 -0
- package/node_modules/ink/src/_internal/env.ts +38 -0
- package/node_modules/ink/src/_internal/envUtils.ts +13 -0
- package/node_modules/ink/src/_internal/execFileNoThrow.ts +58 -0
- package/node_modules/ink/src/_internal/fullscreen.ts +9 -0
- package/node_modules/ink/src/_internal/intl.ts +13 -0
- package/node_modules/ink/src/_internal/iter-lines.ts +14 -0
- package/node_modules/ink/src/_internal/log.ts +15 -0
- package/node_modules/ink/src/_internal/semver.ts +12 -0
- package/node_modules/ink/src/_internal/sliceAnsi.ts +6 -0
- package/node_modules/ink/src/_internal/state.ts +22 -0
- package/node_modules/ink/src/_internal/yoga-layout.ts +23 -0
- package/node_modules/ink/src/ambient.d.ts +47 -0
- package/node_modules/ink/src/bidi.ts +110 -0
- package/node_modules/ink/src/clearTerminal.ts +53 -0
- package/node_modules/ink/src/colorize.ts +129 -0
- package/node_modules/ink/src/components/AlternateScreen.tsx +49 -0
- package/node_modules/ink/src/components/App.tsx +700 -0
- package/node_modules/ink/src/components/AppContext.ts +17 -0
- package/node_modules/ink/src/components/Box.tsx +105 -0
- package/node_modules/ink/src/components/Button.tsx +96 -0
- package/node_modules/ink/src/components/ClockContext.tsx +94 -0
- package/node_modules/ink/src/components/CursorDeclarationContext.ts +23 -0
- package/node_modules/ink/src/components/ErrorOverview.tsx +116 -0
- package/node_modules/ink/src/components/Link.tsx +27 -0
- package/node_modules/ink/src/components/Newline.tsx +11 -0
- package/node_modules/ink/src/components/NoSelect.tsx +16 -0
- package/node_modules/ink/src/components/RawAnsi.tsx +18 -0
- package/node_modules/ink/src/components/ScrollBox.tsx +209 -0
- package/node_modules/ink/src/components/Spacer.tsx +6 -0
- package/node_modules/ink/src/components/StdinContext.ts +35 -0
- package/node_modules/ink/src/components/TerminalFocusContext.tsx +37 -0
- package/node_modules/ink/src/components/TerminalSizeContext.tsx +9 -0
- package/node_modules/ink/src/components/Text.tsx +85 -0
- package/node_modules/ink/src/components/TextInput.tsx +140 -0
- package/node_modules/ink/src/constants.ts +2 -0
- package/node_modules/ink/src/cursor.ts +6 -0
- package/node_modules/ink/src/devtools.ts +2 -0
- package/node_modules/ink/src/dom.ts +451 -0
- package/node_modules/ink/src/events/click-event.ts +19 -0
- package/node_modules/ink/src/events/dispatcher.ts +185 -0
- package/node_modules/ink/src/events/emitter.ts +37 -0
- package/node_modules/ink/src/events/event-handlers.ts +60 -0
- package/node_modules/ink/src/events/event.ts +12 -0
- package/node_modules/ink/src/events/focus-event.ts +13 -0
- package/node_modules/ink/src/events/input-event.ts +212 -0
- package/node_modules/ink/src/events/keyboard-event.ts +41 -0
- package/node_modules/ink/src/events/paste-event.ts +11 -0
- package/node_modules/ink/src/events/resize-event.ts +13 -0
- package/node_modules/ink/src/events/terminal-event.ts +99 -0
- package/node_modules/ink/src/events/terminal-focus-event.ts +13 -0
- package/node_modules/ink/src/focus.ts +159 -0
- package/node_modules/ink/src/frame.ts +105 -0
- package/node_modules/ink/src/get-max-width.ts +10 -0
- package/node_modules/ink/src/hit-test.ts +107 -0
- package/node_modules/ink/src/hooks/use-animation-frame.ts +33 -0
- package/node_modules/ink/src/hooks/use-app.ts +6 -0
- package/node_modules/ink/src/hooks/use-declared-cursor.ts +59 -0
- package/node_modules/ink/src/hooks/use-input.ts +57 -0
- package/node_modules/ink/src/hooks/use-interval.ts +53 -0
- package/node_modules/ink/src/hooks/use-search-highlight.ts +41 -0
- package/node_modules/ink/src/hooks/use-selection.ts +86 -0
- package/node_modules/ink/src/hooks/use-stdin.ts +6 -0
- package/node_modules/ink/src/hooks/use-tab-status.ts +68 -0
- package/node_modules/ink/src/hooks/use-terminal-focus.ts +8 -0
- package/node_modules/ink/src/hooks/use-terminal-title.ts +21 -0
- package/node_modules/ink/src/hooks/use-terminal-viewport.ts +77 -0
- package/node_modules/ink/src/index.ts +150 -0
- package/node_modules/ink/src/ink.tsx +1499 -0
- package/node_modules/ink/src/instances.ts +5 -0
- package/node_modules/ink/src/layout/engine.ts +10 -0
- package/node_modules/ink/src/layout/geometry.ts +116 -0
- package/node_modules/ink/src/layout/node.ts +178 -0
- package/node_modules/ink/src/layout/yoga.ts +316 -0
- package/node_modules/ink/src/line-width-cache.ts +19 -0
- package/node_modules/ink/src/log-update.ts +777 -0
- package/node_modules/ink/src/measure-element.ts +14 -0
- package/node_modules/ink/src/measure-text.ts +29 -0
- package/node_modules/ink/src/node-cache.ts +58 -0
- package/node_modules/ink/src/optimizer.ts +65 -0
- package/node_modules/ink/src/output.ts +730 -0
- package/node_modules/ink/src/parse-keypress.ts +751 -0
- package/node_modules/ink/src/react-jsx-aug.d.ts +14 -0
- package/node_modules/ink/src/reconciler.ts +508 -0
- package/node_modules/ink/src/render-border.ts +230 -0
- package/node_modules/ink/src/render-node-to-output.ts +1477 -0
- package/node_modules/ink/src/render-to-screen.ts +201 -0
- package/node_modules/ink/src/renderer.ts +183 -0
- package/node_modules/ink/src/root.ts +148 -0
- package/node_modules/ink/src/screen.ts +1301 -0
- package/node_modules/ink/src/searchHighlight.ts +68 -0
- package/node_modules/ink/src/selection.ts +742 -0
- package/node_modules/ink/src/squash-text-nodes.ts +70 -0
- package/node_modules/ink/src/stringWidth.ts +222 -0
- package/node_modules/ink/src/styles.ts +603 -0
- package/node_modules/ink/src/supports-hyperlinks.ts +41 -0
- package/node_modules/ink/src/tabstops.ts +39 -0
- package/node_modules/ink/src/terminal-focus-state.ts +46 -0
- package/node_modules/ink/src/terminal-querier.ts +143 -0
- package/node_modules/ink/src/terminal.ts +220 -0
- package/node_modules/ink/src/termio/ansi.ts +66 -0
- package/node_modules/ink/src/termio/csi.ts +290 -0
- package/node_modules/ink/src/termio/dec.ts +52 -0
- package/node_modules/ink/src/termio/esc.ts +63 -0
- package/node_modules/ink/src/termio/osc.ts +364 -0
- package/node_modules/ink/src/termio/parser.ts +383 -0
- package/node_modules/ink/src/termio/sgr.ts +331 -0
- package/node_modules/ink/src/termio/tokenize.ts +311 -0
- package/node_modules/ink/src/termio/types.ts +225 -0
- package/node_modules/ink/src/termio.ts +20 -0
- package/node_modules/ink/src/useTerminalNotification.ts +124 -0
- package/node_modules/ink/src/warn.ts +10 -0
- package/node_modules/ink/src/widest-line.ts +12 -0
- package/node_modules/ink/src/wrap-text.ts +55 -0
- package/node_modules/ink/src/wrapAnsi.ts +15 -0
- package/node_modules/ink/tsconfig.json +26 -0
- package/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
- package/node_modules/is-fullwidth-code-point/index.js +12 -0
- package/node_modules/is-fullwidth-code-point/license +9 -0
- package/node_modules/is-fullwidth-code-point/package.json +53 -0
- package/node_modules/is-fullwidth-code-point/readme.md +31 -0
- package/node_modules/lodash-es/LICENSE +47 -0
- package/node_modules/lodash-es/README.md +10 -0
- package/node_modules/lodash-es/_DataView.js +7 -0
- package/node_modules/lodash-es/_Hash.js +32 -0
- package/node_modules/lodash-es/_LazyWrapper.js +28 -0
- package/node_modules/lodash-es/_ListCache.js +32 -0
- package/node_modules/lodash-es/_LodashWrapper.js +22 -0
- package/node_modules/lodash-es/_Map.js +7 -0
- package/node_modules/lodash-es/_MapCache.js +32 -0
- package/node_modules/lodash-es/_Promise.js +7 -0
- package/node_modules/lodash-es/_Set.js +7 -0
- package/node_modules/lodash-es/_SetCache.js +27 -0
- package/node_modules/lodash-es/_Stack.js +27 -0
- package/node_modules/lodash-es/_Symbol.js +6 -0
- package/node_modules/lodash-es/_Uint8Array.js +6 -0
- package/node_modules/lodash-es/_WeakMap.js +7 -0
- package/node_modules/lodash-es/_addMapEntry.js +15 -0
- package/node_modules/lodash-es/_addSetEntry.js +15 -0
- package/node_modules/lodash-es/_apply.js +21 -0
- package/node_modules/lodash-es/_arrayAggregator.js +22 -0
- package/node_modules/lodash-es/_arrayEach.js +22 -0
- package/node_modules/lodash-es/_arrayEachRight.js +21 -0
- package/node_modules/lodash-es/_arrayEvery.js +23 -0
- package/node_modules/lodash-es/_arrayFilter.js +25 -0
- package/node_modules/lodash-es/_arrayIncludes.js +17 -0
- package/node_modules/lodash-es/_arrayIncludesWith.js +22 -0
- package/node_modules/lodash-es/_arrayLikeKeys.js +49 -0
- package/node_modules/lodash-es/_arrayMap.js +21 -0
- package/node_modules/lodash-es/_arrayPush.js +20 -0
- package/node_modules/lodash-es/_arrayReduce.js +26 -0
- package/node_modules/lodash-es/_arrayReduceRight.js +24 -0
- package/node_modules/lodash-es/_arraySample.js +15 -0
- package/node_modules/lodash-es/_arraySampleSize.js +17 -0
- package/node_modules/lodash-es/_arrayShuffle.js +15 -0
- package/node_modules/lodash-es/_arraySome.js +23 -0
- package/node_modules/lodash-es/_asciiSize.js +12 -0
- package/node_modules/lodash-es/_asciiToArray.js +12 -0
- package/node_modules/lodash-es/_asciiWords.js +15 -0
- package/node_modules/lodash-es/_assignMergeValue.js +20 -0
- package/node_modules/lodash-es/_assignValue.js +28 -0
- package/node_modules/lodash-es/_assocIndexOf.js +21 -0
- package/node_modules/lodash-es/_baseAggregator.js +21 -0
- package/node_modules/lodash-es/_baseAssign.js +17 -0
- package/node_modules/lodash-es/_baseAssignIn.js +17 -0
- package/node_modules/lodash-es/_baseAssignValue.js +25 -0
- package/node_modules/lodash-es/_baseAt.js +23 -0
- package/node_modules/lodash-es/_baseClamp.js +22 -0
- package/node_modules/lodash-es/_baseClone.js +166 -0
- package/node_modules/lodash-es/_baseConforms.js +18 -0
- package/node_modules/lodash-es/_baseConformsTo.js +27 -0
- package/node_modules/lodash-es/_baseCreate.js +30 -0
- package/node_modules/lodash-es/_baseDelay.js +21 -0
- package/node_modules/lodash-es/_baseDifference.js +67 -0
- package/node_modules/lodash-es/_baseEach.js +14 -0
- package/node_modules/lodash-es/_baseEachRight.js +14 -0
- package/node_modules/lodash-es/_baseEvery.js +21 -0
- package/node_modules/lodash-es/_baseExtremum.js +32 -0
- package/node_modules/lodash-es/_baseFill.js +32 -0
- package/node_modules/lodash-es/_baseFilter.js +21 -0
- package/node_modules/lodash-es/_baseFindIndex.js +24 -0
- package/node_modules/lodash-es/_baseFindKey.js +23 -0
- package/node_modules/lodash-es/_baseFlatten.js +38 -0
- package/node_modules/lodash-es/_baseFor.js +16 -0
- package/node_modules/lodash-es/_baseForOwn.js +16 -0
- package/node_modules/lodash-es/_baseForOwnRight.js +16 -0
- package/node_modules/lodash-es/_baseForRight.js +15 -0
- package/node_modules/lodash-es/_baseFunctions.js +19 -0
- package/node_modules/lodash-es/_baseGet.js +24 -0
- package/node_modules/lodash-es/_baseGetAllKeys.js +20 -0
- package/node_modules/lodash-es/_baseGetTag.js +28 -0
- package/node_modules/lodash-es/_baseGt.js +14 -0
- package/node_modules/lodash-es/_baseHas.js +19 -0
- package/node_modules/lodash-es/_baseHasIn.js +13 -0
- package/node_modules/lodash-es/_baseInRange.js +18 -0
- package/node_modules/lodash-es/_baseIndexOf.js +20 -0
- package/node_modules/lodash-es/_baseIndexOfWith.js +23 -0
- package/node_modules/lodash-es/_baseIntersection.js +74 -0
- package/node_modules/lodash-es/_baseInverter.js +21 -0
- package/node_modules/lodash-es/_baseInvoke.js +24 -0
- package/node_modules/lodash-es/_baseIsArguments.js +18 -0
- package/node_modules/lodash-es/_baseIsArrayBuffer.js +17 -0
- package/node_modules/lodash-es/_baseIsDate.js +18 -0
- package/node_modules/lodash-es/_baseIsEqual.js +28 -0
- package/node_modules/lodash-es/_baseIsEqualDeep.js +83 -0
- package/node_modules/lodash-es/_baseIsMap.js +18 -0
- package/node_modules/lodash-es/_baseIsMatch.js +62 -0
- package/node_modules/lodash-es/_baseIsNaN.js +12 -0
- package/node_modules/lodash-es/_baseIsNative.js +47 -0
- package/node_modules/lodash-es/_baseIsRegExp.js +18 -0
- package/node_modules/lodash-es/_baseIsSet.js +18 -0
- package/node_modules/lodash-es/_baseIsTypedArray.js +60 -0
- package/node_modules/lodash-es/_baseIteratee.js +31 -0
- package/node_modules/lodash-es/_baseKeys.js +30 -0
- package/node_modules/lodash-es/_baseKeysIn.js +33 -0
- package/node_modules/lodash-es/_baseLodash.js +10 -0
- package/node_modules/lodash-es/_baseLt.js +14 -0
- package/node_modules/lodash-es/_baseMap.js +22 -0
- package/node_modules/lodash-es/_baseMatches.js +22 -0
- package/node_modules/lodash-es/_baseMatchesProperty.js +33 -0
- package/node_modules/lodash-es/_baseMean.js +20 -0
- package/node_modules/lodash-es/_baseMerge.js +42 -0
- package/node_modules/lodash-es/_baseMergeDeep.js +94 -0
- package/node_modules/lodash-es/_baseNth.js +20 -0
- package/node_modules/lodash-es/_baseOrderBy.js +49 -0
- package/node_modules/lodash-es/_basePick.js +19 -0
- package/node_modules/lodash-es/_basePickBy.js +30 -0
- package/node_modules/lodash-es/_baseProperty.js +14 -0
- package/node_modules/lodash-es/_basePropertyDeep.js +16 -0
- package/node_modules/lodash-es/_basePropertyOf.js +14 -0
- package/node_modules/lodash-es/_basePullAll.js +51 -0
- package/node_modules/lodash-es/_basePullAt.js +37 -0
- package/node_modules/lodash-es/_baseRandom.js +18 -0
- package/node_modules/lodash-es/_baseRange.js +28 -0
- package/node_modules/lodash-es/_baseReduce.js +23 -0
- package/node_modules/lodash-es/_baseRepeat.js +35 -0
- package/node_modules/lodash-es/_baseRest.js +17 -0
- package/node_modules/lodash-es/_baseSample.js +15 -0
- package/node_modules/lodash-es/_baseSampleSize.js +18 -0
- package/node_modules/lodash-es/_baseSet.js +51 -0
- package/node_modules/lodash-es/_baseSetData.js +17 -0
- package/node_modules/lodash-es/_baseSetToString.js +22 -0
- package/node_modules/lodash-es/_baseShuffle.js +15 -0
- package/node_modules/lodash-es/_baseSlice.js +31 -0
- package/node_modules/lodash-es/_baseSome.js +22 -0
- package/node_modules/lodash-es/_baseSortBy.js +21 -0
- package/node_modules/lodash-es/_baseSortedIndex.js +42 -0
- package/node_modules/lodash-es/_baseSortedIndexBy.js +67 -0
- package/node_modules/lodash-es/_baseSortedUniq.js +30 -0
- package/node_modules/lodash-es/_baseSum.js +24 -0
- package/node_modules/lodash-es/_baseTimes.js +20 -0
- package/node_modules/lodash-es/_baseToNumber.js +24 -0
- package/node_modules/lodash-es/_baseToPairs.js +18 -0
- package/node_modules/lodash-es/_baseToString.js +37 -0
- package/node_modules/lodash-es/_baseTrim.js +19 -0
- package/node_modules/lodash-es/_baseUnary.js +14 -0
- package/node_modules/lodash-es/_baseUniq.js +72 -0
- package/node_modules/lodash-es/_baseUnset.js +52 -0
- package/node_modules/lodash-es/_baseUpdate.js +18 -0
- package/node_modules/lodash-es/_baseValues.js +19 -0
- package/node_modules/lodash-es/_baseWhile.js +26 -0
- package/node_modules/lodash-es/_baseWrapperValue.js +25 -0
- package/node_modules/lodash-es/_baseXor.js +36 -0
- package/node_modules/lodash-es/_baseZipObject.js +23 -0
- package/node_modules/lodash-es/_cacheHas.js +13 -0
- package/node_modules/lodash-es/_castArrayLikeObject.js +14 -0
- package/node_modules/lodash-es/_castFunction.js +14 -0
- package/node_modules/lodash-es/_castPath.js +21 -0
- package/node_modules/lodash-es/_castRest.js +14 -0
- package/node_modules/lodash-es/_castSlice.js +18 -0
- package/node_modules/lodash-es/_charsEndIndex.js +19 -0
- package/node_modules/lodash-es/_charsStartIndex.js +20 -0
- package/node_modules/lodash-es/_cloneArrayBuffer.js +16 -0
- package/node_modules/lodash-es/_cloneBuffer.js +35 -0
- package/node_modules/lodash-es/_cloneDataView.js +16 -0
- package/node_modules/lodash-es/_cloneMap.js +22 -0
- package/node_modules/lodash-es/_cloneRegExp.js +17 -0
- package/node_modules/lodash-es/_cloneSet.js +22 -0
- package/node_modules/lodash-es/_cloneSymbol.js +18 -0
- package/node_modules/lodash-es/_cloneTypedArray.js +16 -0
- package/node_modules/lodash-es/_compareAscending.js +41 -0
- package/node_modules/lodash-es/_compareMultiple.js +44 -0
- package/node_modules/lodash-es/_composeArgs.js +39 -0
- package/node_modules/lodash-es/_composeArgsRight.js +41 -0
- package/node_modules/lodash-es/_copyArray.js +20 -0
- package/node_modules/lodash-es/_copyObject.js +40 -0
- package/node_modules/lodash-es/_copySymbols.js +16 -0
- package/node_modules/lodash-es/_copySymbolsIn.js +16 -0
- package/node_modules/lodash-es/_coreJsData.js +6 -0
- package/node_modules/lodash-es/_countHolders.js +21 -0
- package/node_modules/lodash-es/_createAggregator.js +23 -0
- package/node_modules/lodash-es/_createAssigner.js +37 -0
- package/node_modules/lodash-es/_createBaseEach.js +32 -0
- package/node_modules/lodash-es/_createBaseFor.js +25 -0
- package/node_modules/lodash-es/_createBind.js +28 -0
- package/node_modules/lodash-es/_createCaseFirst.js +33 -0
- package/node_modules/lodash-es/_createCompounder.js +24 -0
- package/node_modules/lodash-es/_createCtor.js +37 -0
- package/node_modules/lodash-es/_createCurry.js +46 -0
- package/node_modules/lodash-es/_createFind.js +25 -0
- package/node_modules/lodash-es/_createFlow.js +78 -0
- package/node_modules/lodash-es/_createHybrid.js +92 -0
- package/node_modules/lodash-es/_createInverter.js +17 -0
- package/node_modules/lodash-es/_createMathOperation.js +38 -0
- package/node_modules/lodash-es/_createOver.js +27 -0
- package/node_modules/lodash-es/_createPadding.js +33 -0
- package/node_modules/lodash-es/_createPartial.js +43 -0
- package/node_modules/lodash-es/_createRange.js +30 -0
- package/node_modules/lodash-es/_createRecurry.js +56 -0
- package/node_modules/lodash-es/_createRelationalOperation.js +20 -0
- package/node_modules/lodash-es/_createRound.js +35 -0
- package/node_modules/lodash-es/_createSet.js +19 -0
- package/node_modules/lodash-es/_createToPairs.js +30 -0
- package/node_modules/lodash-es/_createWrap.js +106 -0
- package/node_modules/lodash-es/_customDefaultsAssignIn.js +29 -0
- package/node_modules/lodash-es/_customDefaultsMerge.js +28 -0
- package/node_modules/lodash-es/_customOmitClone.js +16 -0
- package/node_modules/lodash-es/_deburrLetter.js +71 -0
- package/node_modules/lodash-es/_defineProperty.js +11 -0
- package/node_modules/lodash-es/_equalArrays.js +84 -0
- package/node_modules/lodash-es/_equalByTag.js +112 -0
- package/node_modules/lodash-es/_equalObjects.js +90 -0
- package/node_modules/lodash-es/_escapeHtmlChar.js +21 -0
- package/node_modules/lodash-es/_escapeStringChar.js +22 -0
- package/node_modules/lodash-es/_flatRest.js +16 -0
- package/node_modules/lodash-es/_freeGlobal.js +4 -0
- package/node_modules/lodash-es/_getAllKeys.js +16 -0
- package/node_modules/lodash-es/_getAllKeysIn.js +17 -0
- package/node_modules/lodash-es/_getData.js +15 -0
- package/node_modules/lodash-es/_getFuncName.js +31 -0
- package/node_modules/lodash-es/_getHolder.js +13 -0
- package/node_modules/lodash-es/_getMapData.js +18 -0
- package/node_modules/lodash-es/_getMatchData.js +24 -0
- package/node_modules/lodash-es/_getNative.js +17 -0
- package/node_modules/lodash-es/_getPrototype.js +6 -0
- package/node_modules/lodash-es/_getRawTag.js +46 -0
- package/node_modules/lodash-es/_getSymbols.js +30 -0
- package/node_modules/lodash-es/_getSymbolsIn.js +25 -0
- package/node_modules/lodash-es/_getTag.js +58 -0
- package/node_modules/lodash-es/_getValue.js +13 -0
- package/node_modules/lodash-es/_getView.js +33 -0
- package/node_modules/lodash-es/_getWrapDetails.js +17 -0
- package/node_modules/lodash-es/_hasPath.js +39 -0
- package/node_modules/lodash-es/_hasUnicode.js +26 -0
- package/node_modules/lodash-es/_hasUnicodeWord.js +15 -0
- package/node_modules/lodash-es/_hashClear.js +15 -0
- package/node_modules/lodash-es/_hashDelete.js +17 -0
- package/node_modules/lodash-es/_hashGet.js +30 -0
- package/node_modules/lodash-es/_hashHas.js +23 -0
- package/node_modules/lodash-es/_hashSet.js +23 -0
- package/node_modules/lodash-es/_initCloneArray.js +26 -0
- package/node_modules/lodash-es/_initCloneByTag.js +77 -0
- package/node_modules/lodash-es/_initCloneObject.js +18 -0
- package/node_modules/lodash-es/_insertWrapDetails.js +23 -0
- package/node_modules/lodash-es/_isFlattenable.js +20 -0
- package/node_modules/lodash-es/_isIndex.js +25 -0
- package/node_modules/lodash-es/_isIterateeCall.js +30 -0
- package/node_modules/lodash-es/_isKey.js +29 -0
- package/node_modules/lodash-es/_isKeyable.js +15 -0
- package/node_modules/lodash-es/_isLaziable.js +28 -0
- package/node_modules/lodash-es/_isMaskable.js +14 -0
- package/node_modules/lodash-es/_isMasked.js +20 -0
- package/node_modules/lodash-es/_isPrototype.js +18 -0
- package/node_modules/lodash-es/_isStrictComparable.js +15 -0
- package/node_modules/lodash-es/_iteratorToArray.js +18 -0
- package/node_modules/lodash-es/_lazyClone.js +23 -0
- package/node_modules/lodash-es/_lazyReverse.js +23 -0
- package/node_modules/lodash-es/_lazyValue.js +69 -0
- package/node_modules/lodash-es/_listCacheClear.js +13 -0
- package/node_modules/lodash-es/_listCacheDelete.js +35 -0
- package/node_modules/lodash-es/_listCacheGet.js +19 -0
- package/node_modules/lodash-es/_listCacheHas.js +16 -0
- package/node_modules/lodash-es/_listCacheSet.js +26 -0
- package/node_modules/lodash-es/_mapCacheClear.js +21 -0
- package/node_modules/lodash-es/_mapCacheDelete.js +18 -0
- package/node_modules/lodash-es/_mapCacheGet.js +16 -0
- package/node_modules/lodash-es/_mapCacheHas.js +16 -0
- package/node_modules/lodash-es/_mapCacheSet.js +22 -0
- package/node_modules/lodash-es/_mapToArray.js +18 -0
- package/node_modules/lodash-es/_matchesStrictComparable.js +20 -0
- package/node_modules/lodash-es/_memoizeCapped.js +26 -0
- package/node_modules/lodash-es/_mergeData.js +90 -0
- package/node_modules/lodash-es/_metaMap.js +6 -0
- package/node_modules/lodash-es/_nativeCreate.js +6 -0
- package/node_modules/lodash-es/_nativeKeys.js +6 -0
- package/node_modules/lodash-es/_nativeKeysIn.js +20 -0
- package/node_modules/lodash-es/_nodeUtil.js +30 -0
- package/node_modules/lodash-es/_objectToString.js +22 -0
- package/node_modules/lodash-es/_overArg.js +15 -0
- package/node_modules/lodash-es/_overRest.js +36 -0
- package/node_modules/lodash-es/_parent.js +16 -0
- package/node_modules/lodash-es/_reEscape.js +4 -0
- package/node_modules/lodash-es/_reEvaluate.js +4 -0
- package/node_modules/lodash-es/_reInterpolate.js +4 -0
- package/node_modules/lodash-es/_realNames.js +4 -0
- package/node_modules/lodash-es/_reorder.js +29 -0
- package/node_modules/lodash-es/_replaceHolders.js +29 -0
- package/node_modules/lodash-es/_root.js +9 -0
- package/node_modules/lodash-es/_safeGet.js +21 -0
- package/node_modules/lodash-es/_setCacheAdd.js +19 -0
- package/node_modules/lodash-es/_setCacheHas.js +14 -0
- package/node_modules/lodash-es/_setData.js +20 -0
- package/node_modules/lodash-es/_setToArray.js +18 -0
- package/node_modules/lodash-es/_setToPairs.js +18 -0
- package/node_modules/lodash-es/_setToString.js +14 -0
- package/node_modules/lodash-es/_setWrapToString.js +21 -0
- package/node_modules/lodash-es/_shortOut.js +37 -0
- package/node_modules/lodash-es/_shuffleSelf.js +28 -0
- package/node_modules/lodash-es/_stackClear.js +15 -0
- package/node_modules/lodash-es/_stackDelete.js +18 -0
- package/node_modules/lodash-es/_stackGet.js +14 -0
- package/node_modules/lodash-es/_stackHas.js +14 -0
- package/node_modules/lodash-es/_stackSet.js +34 -0
- package/node_modules/lodash-es/_strictIndexOf.js +23 -0
- package/node_modules/lodash-es/_strictLastIndexOf.js +21 -0
- package/node_modules/lodash-es/_stringSize.js +18 -0
- package/node_modules/lodash-es/_stringToArray.js +18 -0
- package/node_modules/lodash-es/_stringToPath.js +27 -0
- package/node_modules/lodash-es/_toKey.js +21 -0
- package/node_modules/lodash-es/_toSource.js +26 -0
- package/node_modules/lodash-es/_trimmedEndIndex.js +19 -0
- package/node_modules/lodash-es/_unescapeHtmlChar.js +21 -0
- package/node_modules/lodash-es/_unicodeSize.js +44 -0
- package/node_modules/lodash-es/_unicodeToArray.js +40 -0
- package/node_modules/lodash-es/_unicodeWords.js +69 -0
- package/node_modules/lodash-es/_updateWrapDetails.js +46 -0
- package/node_modules/lodash-es/_wrapperClone.js +23 -0
- package/node_modules/lodash-es/add.js +22 -0
- package/node_modules/lodash-es/after.js +42 -0
- package/node_modules/lodash-es/array.default.js +81 -0
- package/node_modules/lodash-es/array.js +66 -0
- package/node_modules/lodash-es/ary.js +29 -0
- package/node_modules/lodash-es/assign.js +58 -0
- package/node_modules/lodash-es/assignIn.js +40 -0
- package/node_modules/lodash-es/assignInWith.js +38 -0
- package/node_modules/lodash-es/assignWith.js +37 -0
- package/node_modules/lodash-es/at.js +23 -0
- package/node_modules/lodash-es/attempt.js +35 -0
- package/node_modules/lodash-es/before.js +40 -0
- package/node_modules/lodash-es/bind.js +57 -0
- package/node_modules/lodash-es/bindAll.js +41 -0
- package/node_modules/lodash-es/bindKey.js +68 -0
- package/node_modules/lodash-es/camelCase.js +29 -0
- package/node_modules/lodash-es/capitalize.js +23 -0
- package/node_modules/lodash-es/castArray.js +44 -0
- package/node_modules/lodash-es/ceil.js +26 -0
- package/node_modules/lodash-es/chain.js +38 -0
- package/node_modules/lodash-es/chunk.js +50 -0
- package/node_modules/lodash-es/clamp.js +39 -0
- package/node_modules/lodash-es/clone.js +36 -0
- package/node_modules/lodash-es/cloneDeep.js +29 -0
- package/node_modules/lodash-es/cloneDeepWith.js +40 -0
- package/node_modules/lodash-es/cloneWith.js +42 -0
- package/node_modules/lodash-es/collection.default.js +37 -0
- package/node_modules/lodash-es/collection.js +29 -0
- package/node_modules/lodash-es/commit.js +33 -0
- package/node_modules/lodash-es/compact.js +31 -0
- package/node_modules/lodash-es/concat.js +43 -0
- package/node_modules/lodash-es/cond.js +60 -0
- package/node_modules/lodash-es/conforms.js +35 -0
- package/node_modules/lodash-es/conformsTo.js +32 -0
- package/node_modules/lodash-es/constant.js +26 -0
- package/node_modules/lodash-es/countBy.js +40 -0
- package/node_modules/lodash-es/create.js +43 -0
- package/node_modules/lodash-es/curry.js +57 -0
- package/node_modules/lodash-es/curryRight.js +54 -0
- package/node_modules/lodash-es/date.default.js +5 -0
- package/node_modules/lodash-es/date.js +2 -0
- package/node_modules/lodash-es/debounce.js +191 -0
- package/node_modules/lodash-es/deburr.js +45 -0
- package/node_modules/lodash-es/defaultTo.js +25 -0
- package/node_modules/lodash-es/defaults.js +64 -0
- package/node_modules/lodash-es/defaultsDeep.js +30 -0
- package/node_modules/lodash-es/defer.js +26 -0
- package/node_modules/lodash-es/delay.js +28 -0
- package/node_modules/lodash-es/difference.js +33 -0
- package/node_modules/lodash-es/differenceBy.js +44 -0
- package/node_modules/lodash-es/differenceWith.js +40 -0
- package/node_modules/lodash-es/divide.js +22 -0
- package/node_modules/lodash-es/drop.js +38 -0
- package/node_modules/lodash-es/dropRight.js +39 -0
- package/node_modules/lodash-es/dropRightWhile.js +45 -0
- package/node_modules/lodash-es/dropWhile.js +45 -0
- package/node_modules/lodash-es/each.js +1 -0
- package/node_modules/lodash-es/eachRight.js +1 -0
- package/node_modules/lodash-es/endsWith.js +43 -0
- package/node_modules/lodash-es/entries.js +1 -0
- package/node_modules/lodash-es/entriesIn.js +1 -0
- package/node_modules/lodash-es/eq.js +37 -0
- package/node_modules/lodash-es/escape.js +43 -0
- package/node_modules/lodash-es/escapeRegExp.js +32 -0
- package/node_modules/lodash-es/every.js +56 -0
- package/node_modules/lodash-es/extend.js +1 -0
- package/node_modules/lodash-es/extendWith.js +1 -0
- package/node_modules/lodash-es/fill.js +45 -0
- package/node_modules/lodash-es/filter.js +52 -0
- package/node_modules/lodash-es/find.js +42 -0
- package/node_modules/lodash-es/findIndex.js +55 -0
- package/node_modules/lodash-es/findKey.js +44 -0
- package/node_modules/lodash-es/findLast.js +25 -0
- package/node_modules/lodash-es/findLastIndex.js +59 -0
- package/node_modules/lodash-es/findLastKey.js +44 -0
- package/node_modules/lodash-es/first.js +1 -0
- package/node_modules/lodash-es/flatMap.js +29 -0
- package/node_modules/lodash-es/flatMapDeep.js +31 -0
- package/node_modules/lodash-es/flatMapDepth.js +31 -0
- package/node_modules/lodash-es/flatten.js +22 -0
- package/node_modules/lodash-es/flattenDeep.js +25 -0
- package/node_modules/lodash-es/flattenDepth.js +33 -0
- package/node_modules/lodash-es/flip.js +28 -0
- package/node_modules/lodash-es/floor.js +26 -0
- package/node_modules/lodash-es/flow.js +27 -0
- package/node_modules/lodash-es/flowRight.js +26 -0
- package/node_modules/lodash-es/forEach.js +41 -0
- package/node_modules/lodash-es/forEachRight.js +31 -0
- package/node_modules/lodash-es/forIn.js +39 -0
- package/node_modules/lodash-es/forInRight.js +37 -0
- package/node_modules/lodash-es/forOwn.js +36 -0
- package/node_modules/lodash-es/forOwnRight.js +34 -0
- package/node_modules/lodash-es/fromPairs.js +30 -0
- package/node_modules/lodash-es/function.default.js +31 -0
- package/node_modules/lodash-es/function.js +24 -0
- package/node_modules/lodash-es/functions.js +31 -0
- package/node_modules/lodash-es/functionsIn.js +31 -0
- package/node_modules/lodash-es/get.js +33 -0
- package/node_modules/lodash-es/groupBy.js +41 -0
- package/node_modules/lodash-es/gt.js +29 -0
- package/node_modules/lodash-es/gte.js +30 -0
- package/node_modules/lodash-es/has.js +35 -0
- package/node_modules/lodash-es/hasIn.js +34 -0
- package/node_modules/lodash-es/head.js +23 -0
- package/node_modules/lodash-es/identity.js +21 -0
- package/node_modules/lodash-es/inRange.js +55 -0
- package/node_modules/lodash-es/includes.js +53 -0
- package/node_modules/lodash-es/indexOf.js +42 -0
- package/node_modules/lodash-es/initial.js +22 -0
- package/node_modules/lodash-es/intersection.js +30 -0
- package/node_modules/lodash-es/intersectionBy.js +45 -0
- package/node_modules/lodash-es/intersectionWith.js +41 -0
- package/node_modules/lodash-es/invert.js +42 -0
- package/node_modules/lodash-es/invertBy.js +56 -0
- package/node_modules/lodash-es/invoke.js +24 -0
- package/node_modules/lodash-es/invokeMap.js +41 -0
- package/node_modules/lodash-es/isArguments.js +36 -0
- package/node_modules/lodash-es/isArray.js +26 -0
- package/node_modules/lodash-es/isArrayBuffer.js +27 -0
- package/node_modules/lodash-es/isArrayLike.js +33 -0
- package/node_modules/lodash-es/isArrayLikeObject.js +33 -0
- package/node_modules/lodash-es/isBoolean.js +29 -0
- package/node_modules/lodash-es/isBuffer.js +38 -0
- package/node_modules/lodash-es/isDate.js +27 -0
- package/node_modules/lodash-es/isElement.js +25 -0
- package/node_modules/lodash-es/isEmpty.js +77 -0
- package/node_modules/lodash-es/isEqual.js +35 -0
- package/node_modules/lodash-es/isEqualWith.js +41 -0
- package/node_modules/lodash-es/isError.js +36 -0
- package/node_modules/lodash-es/isFinite.js +36 -0
- package/node_modules/lodash-es/isFunction.js +37 -0
- package/node_modules/lodash-es/isInteger.js +33 -0
- package/node_modules/lodash-es/isLength.js +35 -0
- package/node_modules/lodash-es/isMap.js +27 -0
- package/node_modules/lodash-es/isMatch.js +36 -0
- package/node_modules/lodash-es/isMatchWith.js +41 -0
- package/node_modules/lodash-es/isNaN.js +38 -0
- package/node_modules/lodash-es/isNative.js +40 -0
- package/node_modules/lodash-es/isNil.js +25 -0
- package/node_modules/lodash-es/isNull.js +22 -0
- package/node_modules/lodash-es/isNumber.js +38 -0
- package/node_modules/lodash-es/isObject.js +31 -0
- package/node_modules/lodash-es/isObjectLike.js +29 -0
- package/node_modules/lodash-es/isPlainObject.js +62 -0
- package/node_modules/lodash-es/isRegExp.js +27 -0
- package/node_modules/lodash-es/isSafeInteger.js +37 -0
- package/node_modules/lodash-es/isSet.js +27 -0
- package/node_modules/lodash-es/isString.js +30 -0
- package/node_modules/lodash-es/isSymbol.js +29 -0
- package/node_modules/lodash-es/isTypedArray.js +27 -0
- package/node_modules/lodash-es/isUndefined.js +22 -0
- package/node_modules/lodash-es/isWeakMap.js +28 -0
- package/node_modules/lodash-es/isWeakSet.js +28 -0
- package/node_modules/lodash-es/iteratee.js +53 -0
- package/node_modules/lodash-es/join.js +26 -0
- package/node_modules/lodash-es/kebabCase.js +28 -0
- package/node_modules/lodash-es/keyBy.js +36 -0
- package/node_modules/lodash-es/keys.js +37 -0
- package/node_modules/lodash-es/keysIn.js +32 -0
- package/node_modules/lodash-es/lang.default.js +71 -0
- package/node_modules/lodash-es/lang.js +57 -0
- package/node_modules/lodash-es/last.js +20 -0
- package/node_modules/lodash-es/lastIndexOf.js +46 -0
- package/node_modules/lodash-es/lodash.default.js +643 -0
- package/node_modules/lodash-es/lodash.js +331 -0
- package/node_modules/lodash-es/lowerCase.js +27 -0
- package/node_modules/lodash-es/lowerFirst.js +22 -0
- package/node_modules/lodash-es/lt.js +29 -0
- package/node_modules/lodash-es/lte.js +30 -0
- package/node_modules/lodash-es/map.js +53 -0
- package/node_modules/lodash-es/mapKeys.js +36 -0
- package/node_modules/lodash-es/mapValues.js +43 -0
- package/node_modules/lodash-es/matches.js +46 -0
- package/node_modules/lodash-es/matchesProperty.js +44 -0
- package/node_modules/lodash-es/math.default.js +21 -0
- package/node_modules/lodash-es/math.js +16 -0
- package/node_modules/lodash-es/max.js +29 -0
- package/node_modules/lodash-es/maxBy.js +34 -0
- package/node_modules/lodash-es/mean.js +22 -0
- package/node_modules/lodash-es/meanBy.js +31 -0
- package/node_modules/lodash-es/memoize.js +73 -0
- package/node_modules/lodash-es/merge.js +39 -0
- package/node_modules/lodash-es/mergeWith.js +39 -0
- package/node_modules/lodash-es/method.js +34 -0
- package/node_modules/lodash-es/methodOf.js +33 -0
- package/node_modules/lodash-es/min.js +29 -0
- package/node_modules/lodash-es/minBy.js +34 -0
- package/node_modules/lodash-es/mixin.js +74 -0
- package/node_modules/lodash-es/multiply.js +22 -0
- package/node_modules/lodash-es/negate.js +40 -0
- package/node_modules/lodash-es/next.js +35 -0
- package/node_modules/lodash-es/noop.js +17 -0
- package/node_modules/lodash-es/now.js +23 -0
- package/node_modules/lodash-es/nth.js +29 -0
- package/node_modules/lodash-es/nthArg.js +32 -0
- package/node_modules/lodash-es/number.default.js +7 -0
- package/node_modules/lodash-es/number.js +4 -0
- package/node_modules/lodash-es/object.default.js +60 -0
- package/node_modules/lodash-es/object.js +48 -0
- package/node_modules/lodash-es/omit.js +57 -0
- package/node_modules/lodash-es/omitBy.js +29 -0
- package/node_modules/lodash-es/once.js +25 -0
- package/node_modules/lodash-es/orderBy.js +47 -0
- package/node_modules/lodash-es/over.js +24 -0
- package/node_modules/lodash-es/overArgs.js +61 -0
- package/node_modules/lodash-es/overEvery.js +34 -0
- package/node_modules/lodash-es/overSome.js +37 -0
- package/node_modules/lodash-es/package.json +23 -0
- package/node_modules/lodash-es/pad.js +49 -0
- package/node_modules/lodash-es/padEnd.js +39 -0
- package/node_modules/lodash-es/padStart.js +39 -0
- package/node_modules/lodash-es/parseInt.js +43 -0
- package/node_modules/lodash-es/partial.js +50 -0
- package/node_modules/lodash-es/partialRight.js +49 -0
- package/node_modules/lodash-es/partition.js +43 -0
- package/node_modules/lodash-es/pick.js +25 -0
- package/node_modules/lodash-es/pickBy.js +37 -0
- package/node_modules/lodash-es/plant.js +48 -0
- package/node_modules/lodash-es/property.js +32 -0
- package/node_modules/lodash-es/propertyOf.js +30 -0
- package/node_modules/lodash-es/pull.js +29 -0
- package/node_modules/lodash-es/pullAll.js +29 -0
- package/node_modules/lodash-es/pullAllBy.js +33 -0
- package/node_modules/lodash-es/pullAllWith.js +32 -0
- package/node_modules/lodash-es/pullAt.js +43 -0
- package/node_modules/lodash-es/random.js +91 -0
- package/node_modules/lodash-es/range.js +46 -0
- package/node_modules/lodash-es/rangeRight.js +41 -0
- package/node_modules/lodash-es/rearg.js +33 -0
- package/node_modules/lodash-es/reduce.js +51 -0
- package/node_modules/lodash-es/reduceRight.js +36 -0
- package/node_modules/lodash-es/reject.js +46 -0
- package/node_modules/lodash-es/remove.js +53 -0
- package/node_modules/lodash-es/repeat.js +37 -0
- package/node_modules/lodash-es/replace.js +29 -0
- package/node_modules/lodash-es/rest.js +40 -0
- package/node_modules/lodash-es/result.js +56 -0
- package/node_modules/lodash-es/reverse.js +34 -0
- package/node_modules/lodash-es/round.js +26 -0
- package/node_modules/lodash-es/sample.js +24 -0
- package/node_modules/lodash-es/sampleSize.js +37 -0
- package/node_modules/lodash-es/seq.default.js +20 -0
- package/node_modules/lodash-es/seq.js +15 -0
- package/node_modules/lodash-es/set.js +35 -0
- package/node_modules/lodash-es/setWith.js +32 -0
- package/node_modules/lodash-es/shuffle.js +25 -0
- package/node_modules/lodash-es/size.js +46 -0
- package/node_modules/lodash-es/slice.js +37 -0
- package/node_modules/lodash-es/snakeCase.js +28 -0
- package/node_modules/lodash-es/some.js +51 -0
- package/node_modules/lodash-es/sortBy.js +48 -0
- package/node_modules/lodash-es/sortedIndex.js +24 -0
- package/node_modules/lodash-es/sortedIndexBy.js +33 -0
- package/node_modules/lodash-es/sortedIndexOf.js +31 -0
- package/node_modules/lodash-es/sortedLastIndex.js +25 -0
- package/node_modules/lodash-es/sortedLastIndexBy.js +33 -0
- package/node_modules/lodash-es/sortedLastIndexOf.js +31 -0
- package/node_modules/lodash-es/sortedUniq.js +24 -0
- package/node_modules/lodash-es/sortedUniqBy.js +26 -0
- package/node_modules/lodash-es/split.js +52 -0
- package/node_modules/lodash-es/spread.js +63 -0
- package/node_modules/lodash-es/startCase.js +29 -0
- package/node_modules/lodash-es/startsWith.js +39 -0
- package/node_modules/lodash-es/string.default.js +41 -0
- package/node_modules/lodash-es/string.js +32 -0
- package/node_modules/lodash-es/stubArray.js +23 -0
- package/node_modules/lodash-es/stubFalse.js +18 -0
- package/node_modules/lodash-es/stubObject.js +23 -0
- package/node_modules/lodash-es/stubString.js +18 -0
- package/node_modules/lodash-es/stubTrue.js +18 -0
- package/node_modules/lodash-es/subtract.js +22 -0
- package/node_modules/lodash-es/sum.js +24 -0
- package/node_modules/lodash-es/sumBy.js +33 -0
- package/node_modules/lodash-es/tail.js +22 -0
- package/node_modules/lodash-es/take.js +37 -0
- package/node_modules/lodash-es/takeRight.js +39 -0
- package/node_modules/lodash-es/takeRightWhile.js +45 -0
- package/node_modules/lodash-es/takeWhile.js +45 -0
- package/node_modules/lodash-es/tap.js +29 -0
- package/node_modules/lodash-es/template.js +284 -0
- package/node_modules/lodash-es/templateSettings.js +71 -0
- package/node_modules/lodash-es/throttle.js +69 -0
- package/node_modules/lodash-es/thru.js +28 -0
- package/node_modules/lodash-es/times.js +51 -0
- package/node_modules/lodash-es/toArray.js +58 -0
- package/node_modules/lodash-es/toFinite.js +42 -0
- package/node_modules/lodash-es/toInteger.js +36 -0
- package/node_modules/lodash-es/toIterator.js +23 -0
- package/node_modules/lodash-es/toJSON.js +1 -0
- package/node_modules/lodash-es/toLength.js +38 -0
- package/node_modules/lodash-es/toLower.js +28 -0
- package/node_modules/lodash-es/toNumber.js +64 -0
- package/node_modules/lodash-es/toPairs.js +30 -0
- package/node_modules/lodash-es/toPairsIn.js +30 -0
- package/node_modules/lodash-es/toPath.js +33 -0
- package/node_modules/lodash-es/toPlainObject.js +32 -0
- package/node_modules/lodash-es/toSafeInteger.js +37 -0
- package/node_modules/lodash-es/toString.js +28 -0
- package/node_modules/lodash-es/toUpper.js +28 -0
- package/node_modules/lodash-es/transform.js +65 -0
- package/node_modules/lodash-es/trim.js +47 -0
- package/node_modules/lodash-es/trimEnd.js +41 -0
- package/node_modules/lodash-es/trimStart.js +43 -0
- package/node_modules/lodash-es/truncate.js +111 -0
- package/node_modules/lodash-es/unary.js +22 -0
- package/node_modules/lodash-es/unescape.js +34 -0
- package/node_modules/lodash-es/union.js +26 -0
- package/node_modules/lodash-es/unionBy.js +39 -0
- package/node_modules/lodash-es/unionWith.js +34 -0
- package/node_modules/lodash-es/uniq.js +25 -0
- package/node_modules/lodash-es/uniqBy.js +31 -0
- package/node_modules/lodash-es/uniqWith.js +28 -0
- package/node_modules/lodash-es/uniqueId.js +28 -0
- package/node_modules/lodash-es/unset.js +34 -0
- package/node_modules/lodash-es/unzip.js +45 -0
- package/node_modules/lodash-es/unzipWith.js +39 -0
- package/node_modules/lodash-es/update.js +35 -0
- package/node_modules/lodash-es/updateWith.js +33 -0
- package/node_modules/lodash-es/upperCase.js +27 -0
- package/node_modules/lodash-es/upperFirst.js +22 -0
- package/node_modules/lodash-es/util.default.js +42 -0
- package/node_modules/lodash-es/util.js +33 -0
- package/node_modules/lodash-es/value.js +1 -0
- package/node_modules/lodash-es/valueOf.js +1 -0
- package/node_modules/lodash-es/values.js +34 -0
- package/node_modules/lodash-es/valuesIn.js +32 -0
- package/node_modules/lodash-es/without.js +31 -0
- package/node_modules/lodash-es/words.js +35 -0
- package/node_modules/lodash-es/wrap.js +30 -0
- package/node_modules/lodash-es/wrapperAt.js +48 -0
- package/node_modules/lodash-es/wrapperChain.js +34 -0
- package/node_modules/lodash-es/wrapperLodash.js +147 -0
- package/node_modules/lodash-es/wrapperReverse.js +44 -0
- package/node_modules/lodash-es/wrapperValue.js +21 -0
- package/node_modules/lodash-es/xor.js +28 -0
- package/node_modules/lodash-es/xorBy.js +39 -0
- package/node_modules/lodash-es/xorWith.js +34 -0
- package/node_modules/lodash-es/zip.js +22 -0
- package/node_modules/lodash-es/zipObject.js +24 -0
- package/node_modules/lodash-es/zipObjectDeep.js +23 -0
- package/node_modules/lodash-es/zipWith.js +32 -0
- package/node_modules/lodash.debounce/LICENSE +47 -0
- package/node_modules/lodash.debounce/README.md +18 -0
- package/node_modules/lodash.debounce/index.js +377 -0
- package/node_modules/lodash.debounce/package.json +17 -0
- package/node_modules/require-from-string/index.js +34 -0
- package/node_modules/require-from-string/license +21 -0
- package/node_modules/require-from-string/package.json +28 -0
- package/node_modules/require-from-string/readme.md +56 -0
- package/node_modules/semver/LICENSE +15 -0
- package/node_modules/semver/README.md +665 -0
- package/node_modules/semver/bin/semver.js +191 -0
- package/node_modules/semver/classes/comparator.js +143 -0
- package/node_modules/semver/classes/index.js +7 -0
- package/node_modules/semver/classes/range.js +557 -0
- package/node_modules/semver/classes/semver.js +333 -0
- package/node_modules/semver/functions/clean.js +8 -0
- package/node_modules/semver/functions/cmp.js +54 -0
- package/node_modules/semver/functions/coerce.js +62 -0
- package/node_modules/semver/functions/compare-build.js +9 -0
- package/node_modules/semver/functions/compare-loose.js +5 -0
- package/node_modules/semver/functions/compare.js +7 -0
- package/node_modules/semver/functions/diff.js +60 -0
- package/node_modules/semver/functions/eq.js +5 -0
- package/node_modules/semver/functions/gt.js +5 -0
- package/node_modules/semver/functions/gte.js +5 -0
- package/node_modules/semver/functions/inc.js +21 -0
- package/node_modules/semver/functions/lt.js +5 -0
- package/node_modules/semver/functions/lte.js +5 -0
- package/node_modules/semver/functions/major.js +5 -0
- package/node_modules/semver/functions/minor.js +5 -0
- package/node_modules/semver/functions/neq.js +5 -0
- package/node_modules/semver/functions/parse.js +18 -0
- package/node_modules/semver/functions/patch.js +5 -0
- package/node_modules/semver/functions/prerelease.js +8 -0
- package/node_modules/semver/functions/rcompare.js +5 -0
- package/node_modules/semver/functions/rsort.js +5 -0
- package/node_modules/semver/functions/satisfies.js +12 -0
- package/node_modules/semver/functions/sort.js +5 -0
- package/node_modules/semver/functions/valid.js +8 -0
- package/node_modules/semver/index.js +91 -0
- package/node_modules/semver/internal/constants.js +37 -0
- package/node_modules/semver/internal/debug.js +11 -0
- package/node_modules/semver/internal/identifiers.js +29 -0
- package/node_modules/semver/internal/lrucache.js +42 -0
- package/node_modules/semver/internal/parse-options.js +17 -0
- package/node_modules/semver/internal/re.js +223 -0
- package/node_modules/semver/package.json +78 -0
- package/node_modules/semver/preload.js +4 -0
- package/node_modules/semver/range.bnf +16 -0
- package/node_modules/semver/ranges/gtr.js +6 -0
- package/node_modules/semver/ranges/intersects.js +9 -0
- package/node_modules/semver/ranges/ltr.js +6 -0
- package/node_modules/semver/ranges/max-satisfying.js +27 -0
- package/node_modules/semver/ranges/min-satisfying.js +26 -0
- package/node_modules/semver/ranges/min-version.js +63 -0
- package/node_modules/semver/ranges/outside.js +82 -0
- package/node_modules/semver/ranges/simplify.js +49 -0
- package/node_modules/semver/ranges/subset.js +249 -0
- package/node_modules/semver/ranges/to-comparators.js +10 -0
- package/node_modules/semver/ranges/valid.js +13 -0
- package/node_modules/signal-exit/LICENSE.txt +16 -0
- package/node_modules/signal-exit/README.md +74 -0
- package/node_modules/signal-exit/dist/cjs/browser.d.ts +12 -0
- package/node_modules/signal-exit/dist/cjs/browser.d.ts.map +1 -0
- package/node_modules/signal-exit/dist/cjs/browser.js +10 -0
- package/node_modules/signal-exit/dist/cjs/browser.js.map +1 -0
- package/node_modules/signal-exit/dist/cjs/index.d.ts +48 -0
- package/node_modules/signal-exit/dist/cjs/index.d.ts.map +1 -0
- package/node_modules/signal-exit/dist/cjs/index.js +279 -0
- package/node_modules/signal-exit/dist/cjs/index.js.map +1 -0
- package/node_modules/signal-exit/dist/cjs/package.json +3 -0
- package/node_modules/signal-exit/dist/cjs/signals.d.ts +29 -0
- package/node_modules/signal-exit/dist/cjs/signals.d.ts.map +1 -0
- package/node_modules/signal-exit/dist/cjs/signals.js +42 -0
- package/node_modules/signal-exit/dist/cjs/signals.js.map +1 -0
- package/node_modules/signal-exit/dist/mjs/browser.d.ts +12 -0
- package/node_modules/signal-exit/dist/mjs/browser.d.ts.map +1 -0
- package/node_modules/signal-exit/dist/mjs/browser.js +4 -0
- package/node_modules/signal-exit/dist/mjs/browser.js.map +1 -0
- package/node_modules/signal-exit/dist/mjs/index.d.ts +48 -0
- package/node_modules/signal-exit/dist/mjs/index.d.ts.map +1 -0
- package/node_modules/signal-exit/dist/mjs/index.js +275 -0
- package/node_modules/signal-exit/dist/mjs/index.js.map +1 -0
- package/node_modules/signal-exit/dist/mjs/package.json +3 -0
- package/node_modules/signal-exit/dist/mjs/signals.d.ts +29 -0
- package/node_modules/signal-exit/dist/mjs/signals.d.ts.map +1 -0
- package/node_modules/signal-exit/dist/mjs/signals.js +39 -0
- package/node_modules/signal-exit/dist/mjs/signals.js.map +1 -0
- package/node_modules/signal-exit/package.json +106 -0
- package/node_modules/slice-ansi/index.d.ts +19 -0
- package/node_modules/slice-ansi/index.js +169 -0
- package/node_modules/slice-ansi/license +10 -0
- package/node_modules/slice-ansi/package.json +58 -0
- package/node_modules/slice-ansi/readme.md +54 -0
- package/node_modules/stack-utils/LICENSE.md +21 -0
- package/node_modules/stack-utils/index.js +344 -0
- package/node_modules/stack-utils/package.json +39 -0
- package/node_modules/stack-utils/readme.md +143 -0
- package/node_modules/string-width/index.d.ts +39 -0
- package/node_modules/string-width/index.js +82 -0
- package/node_modules/string-width/license +9 -0
- package/node_modules/string-width/package.json +64 -0
- package/node_modules/string-width/readme.md +66 -0
- package/node_modules/strip-ansi/index.d.ts +15 -0
- package/node_modules/strip-ansi/index.js +19 -0
- package/node_modules/strip-ansi/license +9 -0
- package/node_modules/strip-ansi/package.json +59 -0
- package/node_modules/strip-ansi/readme.md +37 -0
- package/node_modules/supports-hyperlinks/browser.js +10 -0
- package/node_modules/supports-hyperlinks/index.d.ts +25 -0
- package/node_modules/supports-hyperlinks/index.js +157 -0
- package/node_modules/supports-hyperlinks/license +10 -0
- package/node_modules/supports-hyperlinks/node_modules/has-flag/index.d.ts +39 -0
- package/node_modules/supports-hyperlinks/node_modules/has-flag/index.js +8 -0
- package/node_modules/supports-hyperlinks/node_modules/has-flag/license +9 -0
- package/node_modules/supports-hyperlinks/node_modules/has-flag/package.json +49 -0
- package/node_modules/supports-hyperlinks/node_modules/has-flag/readme.md +74 -0
- package/node_modules/supports-hyperlinks/node_modules/supports-color/browser.d.ts +1 -0
- package/node_modules/supports-hyperlinks/node_modules/supports-color/browser.js +35 -0
- package/node_modules/supports-hyperlinks/node_modules/supports-color/index.d.ts +55 -0
- package/node_modules/supports-hyperlinks/node_modules/supports-color/index.js +202 -0
- package/node_modules/supports-hyperlinks/node_modules/supports-color/license +9 -0
- package/node_modules/supports-hyperlinks/node_modules/supports-color/package.json +64 -0
- package/node_modules/supports-hyperlinks/node_modules/supports-color/readme.md +75 -0
- package/node_modules/supports-hyperlinks/package.json +47 -0
- package/node_modules/supports-hyperlinks/readme.md +39 -0
- package/node_modules/tagged-tag/index.d.ts +3 -0
- package/node_modules/tagged-tag/license +9 -0
- package/node_modules/tagged-tag/package.json +36 -0
- package/node_modules/tagged-tag/readme.md +5 -0
- package/node_modules/type-fest/index.d.ts +221 -0
- package/node_modules/type-fest/license-cc0 +121 -0
- package/node_modules/type-fest/license-mit +9 -0
- package/node_modules/type-fest/package.json +75 -0
- package/node_modules/type-fest/readme.md +1077 -0
- package/node_modules/type-fest/source/absolute.d.ts +52 -0
- package/node_modules/type-fest/source/all-extend.d.ts +119 -0
- package/node_modules/type-fest/source/all-union-fields.d.ts +91 -0
- package/node_modules/type-fest/source/and-all.d.ts +76 -0
- package/node_modules/type-fest/source/and.d.ts +82 -0
- package/node_modules/type-fest/source/array-element.d.ts +46 -0
- package/node_modules/type-fest/source/array-indices.d.ts +25 -0
- package/node_modules/type-fest/source/array-length.d.ts +36 -0
- package/node_modules/type-fest/source/array-reverse.d.ts +84 -0
- package/node_modules/type-fest/source/array-slice.d.ts +132 -0
- package/node_modules/type-fest/source/array-splice.d.ts +104 -0
- package/node_modules/type-fest/source/array-tail.d.ts +70 -0
- package/node_modules/type-fest/source/array-values.d.ts +24 -0
- package/node_modules/type-fest/source/arrayable.d.ts +31 -0
- package/node_modules/type-fest/source/async-return-type.d.ts +28 -0
- package/node_modules/type-fest/source/asyncify.d.ts +25 -0
- package/node_modules/type-fest/source/basic.d.ts +38 -0
- package/node_modules/type-fest/source/camel-case.d.ts +125 -0
- package/node_modules/type-fest/source/camel-cased-properties-deep.d.ts +106 -0
- package/node_modules/type-fest/source/camel-cased-properties.d.ts +49 -0
- package/node_modules/type-fest/source/characters.d.ts +67 -0
- package/node_modules/type-fest/source/conditional-except.d.ts +47 -0
- package/node_modules/type-fest/source/conditional-keys.d.ts +63 -0
- package/node_modules/type-fest/source/conditional-pick-deep.d.ts +122 -0
- package/node_modules/type-fest/source/conditional-pick.d.ts +48 -0
- package/node_modules/type-fest/source/conditional-simplify-deep.d.ts +73 -0
- package/node_modules/type-fest/source/conditional-simplify.d.ts +50 -0
- package/node_modules/type-fest/source/delimiter-case.d.ts +78 -0
- package/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts +115 -0
- package/node_modules/type-fest/source/delimiter-cased-properties.d.ts +52 -0
- package/node_modules/type-fest/source/distributed-omit.d.ts +96 -0
- package/node_modules/type-fest/source/distributed-pick.d.ts +92 -0
- package/node_modules/type-fest/source/empty-object.d.ts +51 -0
- package/node_modules/type-fest/source/entries.d.ts +64 -0
- package/node_modules/type-fest/source/entry.d.ts +67 -0
- package/node_modules/type-fest/source/exact.d.ts +73 -0
- package/node_modules/type-fest/source/except.d.ts +112 -0
- package/node_modules/type-fest/source/exclude-exactly.d.ts +57 -0
- package/node_modules/type-fest/source/exclude-rest-element.d.ts +40 -0
- package/node_modules/type-fest/source/exclude-strict.d.ts +51 -0
- package/node_modules/type-fest/source/exclusify-union.d.ts +147 -0
- package/node_modules/type-fest/source/extends-strict.d.ts +44 -0
- package/node_modules/type-fest/source/extract-rest-element.d.ts +30 -0
- package/node_modules/type-fest/source/extract-strict.d.ts +51 -0
- package/node_modules/type-fest/source/find-global-type.d.ts +68 -0
- package/node_modules/type-fest/source/fixed-length-array.d.ts +97 -0
- package/node_modules/type-fest/source/get.d.ts +227 -0
- package/node_modules/type-fest/source/global-this.d.ts +24 -0
- package/node_modules/type-fest/source/globals/index.d.ts +3 -0
- package/node_modules/type-fest/source/globals/observable-like.d.ts +78 -0
- package/node_modules/type-fest/source/greater-than-or-equal.d.ts +63 -0
- package/node_modules/type-fest/source/greater-than.d.ts +92 -0
- package/node_modules/type-fest/source/has-optional-keys.d.ts +23 -0
- package/node_modules/type-fest/source/has-readonly-keys.d.ts +23 -0
- package/node_modules/type-fest/source/has-required-keys.d.ts +61 -0
- package/node_modules/type-fest/source/has-writable-keys.d.ts +23 -0
- package/node_modules/type-fest/source/if-any.d.ts +28 -0
- package/node_modules/type-fest/source/if-empty-object.d.ts +30 -0
- package/node_modules/type-fest/source/if-never.d.ts +28 -0
- package/node_modules/type-fest/source/if-null.d.ts +28 -0
- package/node_modules/type-fest/source/if-unknown.d.ts +28 -0
- package/node_modules/type-fest/source/if.d.ts +102 -0
- package/node_modules/type-fest/source/includes.d.ts +24 -0
- package/node_modules/type-fest/source/int-closed-range.d.ts +45 -0
- package/node_modules/type-fest/source/int-range.d.ts +67 -0
- package/node_modules/type-fest/source/internal/array.d.ts +144 -0
- package/node_modules/type-fest/source/internal/characters.d.ts +65 -0
- package/node_modules/type-fest/source/internal/enforce-optional.d.ts +49 -0
- package/node_modules/type-fest/source/internal/index.d.ts +11 -0
- package/node_modules/type-fest/source/internal/keys.d.ts +100 -0
- package/node_modules/type-fest/source/internal/numeric.d.ts +141 -0
- package/node_modules/type-fest/source/internal/object.d.ts +292 -0
- package/node_modules/type-fest/source/internal/string.d.ts +202 -0
- package/node_modules/type-fest/source/internal/tuple.d.ts +79 -0
- package/node_modules/type-fest/source/internal/type.d.ts +165 -0
- package/node_modules/type-fest/source/invariant-of.d.ts +85 -0
- package/node_modules/type-fest/source/is-any.d.ts +31 -0
- package/node_modules/type-fest/source/is-equal.d.ts +41 -0
- package/node_modules/type-fest/source/is-float.d.ts +43 -0
- package/node_modules/type-fest/source/is-integer.d.ts +60 -0
- package/node_modules/type-fest/source/is-literal.d.ts +315 -0
- package/node_modules/type-fest/source/is-lowercase.d.ts +38 -0
- package/node_modules/type-fest/source/is-never.d.ts +56 -0
- package/node_modules/type-fest/source/is-null.d.ts +22 -0
- package/node_modules/type-fest/source/is-nullable.d.ts +30 -0
- package/node_modules/type-fest/source/is-optional-key-of.d.ts +51 -0
- package/node_modules/type-fest/source/is-optional.d.ts +28 -0
- package/node_modules/type-fest/source/is-readonly-key-of.d.ts +55 -0
- package/node_modules/type-fest/source/is-required-key-of.d.ts +51 -0
- package/node_modules/type-fest/source/is-tuple.d.ts +92 -0
- package/node_modules/type-fest/source/is-undefined.d.ts +22 -0
- package/node_modules/type-fest/source/is-union.d.ts +40 -0
- package/node_modules/type-fest/source/is-unknown.d.ts +43 -0
- package/node_modules/type-fest/source/is-uppercase.d.ts +38 -0
- package/node_modules/type-fest/source/is-writable-key-of.d.ts +51 -0
- package/node_modules/type-fest/source/iterable-element.d.ts +66 -0
- package/node_modules/type-fest/source/join.d.ts +79 -0
- package/node_modules/type-fest/source/json-value.d.ts +33 -0
- package/node_modules/type-fest/source/jsonifiable.d.ts +37 -0
- package/node_modules/type-fest/source/jsonify.d.ts +127 -0
- package/node_modules/type-fest/source/kebab-case.d.ts +47 -0
- package/node_modules/type-fest/source/kebab-cased-properties-deep.d.ts +72 -0
- package/node_modules/type-fest/source/kebab-cased-properties.d.ts +46 -0
- package/node_modules/type-fest/source/key-as-string.d.ts +27 -0
- package/node_modules/type-fest/source/keys-of-union.d.ts +44 -0
- package/node_modules/type-fest/source/last-array-element.d.ts +36 -0
- package/node_modules/type-fest/source/less-than-or-equal.d.ts +60 -0
- package/node_modules/type-fest/source/less-than.d.ts +60 -0
- package/node_modules/type-fest/source/literal-to-primitive-deep.d.ts +71 -0
- package/node_modules/type-fest/source/literal-to-primitive.d.ts +38 -0
- package/node_modules/type-fest/source/literal-union.d.ts +39 -0
- package/node_modules/type-fest/source/merge-deep.d.ts +495 -0
- package/node_modules/type-fest/source/merge-exclusive.d.ts +45 -0
- package/node_modules/type-fest/source/merge.d.ts +87 -0
- package/node_modules/type-fest/source/multidimensional-array.d.ts +38 -0
- package/node_modules/type-fest/source/multidimensional-readonly-array.d.ts +38 -0
- package/node_modules/type-fest/source/non-empty-object.d.ts +38 -0
- package/node_modules/type-fest/source/non-empty-string.d.ts +32 -0
- package/node_modules/type-fest/source/non-empty-tuple.d.ts +24 -0
- package/node_modules/type-fest/source/non-nullable-deep.d.ts +102 -0
- package/node_modules/type-fest/source/numeric.d.ts +226 -0
- package/node_modules/type-fest/source/object-merge.d.ts +194 -0
- package/node_modules/type-fest/source/omit-deep.d.ts +153 -0
- package/node_modules/type-fest/source/omit-index-signature.d.ts +98 -0
- package/node_modules/type-fest/source/opaque.d.ts +3 -0
- package/node_modules/type-fest/source/optional-keys-of.d.ts +46 -0
- package/node_modules/type-fest/source/optional.d.ts +31 -0
- package/node_modules/type-fest/source/or-all.d.ts +73 -0
- package/node_modules/type-fest/source/or.d.ts +82 -0
- package/node_modules/type-fest/source/override-properties.d.ts +43 -0
- package/node_modules/type-fest/source/package-json.d.ts +710 -0
- package/node_modules/type-fest/source/partial-deep.d.ts +157 -0
- package/node_modules/type-fest/source/partial-on-undefined-deep.d.ts +81 -0
- package/node_modules/type-fest/source/pascal-case.d.ts +52 -0
- package/node_modules/type-fest/source/pascal-cased-properties-deep.d.ts +79 -0
- package/node_modules/type-fest/source/pascal-cased-properties.d.ts +46 -0
- package/node_modules/type-fest/source/paths.d.ts +241 -0
- package/node_modules/type-fest/source/pick-deep.d.ts +139 -0
- package/node_modules/type-fest/source/pick-index-signature.d.ts +52 -0
- package/node_modules/type-fest/source/primitive.d.ts +15 -0
- package/node_modules/type-fest/source/promisable.d.ts +27 -0
- package/node_modules/type-fest/source/readonly-deep.d.ts +118 -0
- package/node_modules/type-fest/source/readonly-keys-of.d.ts +38 -0
- package/node_modules/type-fest/source/readonly-tuple.d.ts +34 -0
- package/node_modules/type-fest/source/remove-prefix.d.ts +132 -0
- package/node_modules/type-fest/source/replace.d.ts +87 -0
- package/node_modules/type-fest/source/require-all-or-none.d.ts +54 -0
- package/node_modules/type-fest/source/require-at-least-one.d.ts +48 -0
- package/node_modules/type-fest/source/require-exactly-one.d.ts +48 -0
- package/node_modules/type-fest/source/require-one-or-none.d.ts +49 -0
- package/node_modules/type-fest/source/required-deep.d.ts +78 -0
- package/node_modules/type-fest/source/required-keys-of.d.ts +38 -0
- package/node_modules/type-fest/source/schema.d.ts +119 -0
- package/node_modules/type-fest/source/screaming-snake-case.d.ts +31 -0
- package/node_modules/type-fest/source/set-field-type.d.ts +67 -0
- package/node_modules/type-fest/source/set-non-nullable-deep.d.ts +88 -0
- package/node_modules/type-fest/source/set-non-nullable.d.ts +34 -0
- package/node_modules/type-fest/source/set-optional.d.ts +42 -0
- package/node_modules/type-fest/source/set-parameter-type.d.ts +125 -0
- package/node_modules/type-fest/source/set-readonly.d.ts +40 -0
- package/node_modules/type-fest/source/set-required-deep.d.ts +64 -0
- package/node_modules/type-fest/source/set-required.d.ts +75 -0
- package/node_modules/type-fest/source/set-return-type.d.ts +31 -0
- package/node_modules/type-fest/source/shared-union-fields-deep.d.ts +180 -0
- package/node_modules/type-fest/source/shared-union-fields.d.ts +79 -0
- package/node_modules/type-fest/source/simplify-deep.d.ts +117 -0
- package/node_modules/type-fest/source/simplify.d.ts +61 -0
- package/node_modules/type-fest/source/single-key-object.d.ts +28 -0
- package/node_modules/type-fest/source/snake-case.d.ts +48 -0
- package/node_modules/type-fest/source/snake-cased-properties-deep.d.ts +72 -0
- package/node_modules/type-fest/source/snake-cased-properties.d.ts +46 -0
- package/node_modules/type-fest/source/some-extend.d.ts +113 -0
- package/node_modules/type-fest/source/split-on-rest-element.d.ts +106 -0
- package/node_modules/type-fest/source/split.d.ts +90 -0
- package/node_modules/type-fest/source/spread.d.ts +78 -0
- package/node_modules/type-fest/source/string-repeat.d.ts +49 -0
- package/node_modules/type-fest/source/string-slice.d.ts +39 -0
- package/node_modules/type-fest/source/stringified.d.ts +25 -0
- package/node_modules/type-fest/source/structured-cloneable.d.ts +89 -0
- package/node_modules/type-fest/source/subtract.d.ts +87 -0
- package/node_modules/type-fest/source/sum.d.ts +82 -0
- package/node_modules/type-fest/source/tagged-union.d.ts +53 -0
- package/node_modules/type-fest/source/tagged.d.ts +261 -0
- package/node_modules/type-fest/source/trim.d.ts +29 -0
- package/node_modules/type-fest/source/tsconfig-json.d.ts +1356 -0
- package/node_modules/type-fest/source/tuple-of.d.ts +80 -0
- package/node_modules/type-fest/source/tuple-to-object.d.ts +47 -0
- package/node_modules/type-fest/source/tuple-to-union.d.ts +54 -0
- package/node_modules/type-fest/source/typed-array.d.ts +19 -0
- package/node_modules/type-fest/source/undefined-on-partial-deep.d.ts +83 -0
- package/node_modules/type-fest/source/union-length.d.ts +27 -0
- package/node_modules/type-fest/source/union-member.d.ts +65 -0
- package/node_modules/type-fest/source/union-to-intersection.d.ts +35 -0
- package/node_modules/type-fest/source/union-to-tuple.d.ts +49 -0
- package/node_modules/type-fest/source/unknown-array.d.ts +27 -0
- package/node_modules/type-fest/source/unknown-map.d.ts +26 -0
- package/node_modules/type-fest/source/unknown-record.d.ts +33 -0
- package/node_modules/type-fest/source/unknown-set.d.ts +26 -0
- package/node_modules/type-fest/source/unwrap-partial.d.ts +33 -0
- package/node_modules/type-fest/source/value-of.d.ts +24 -0
- package/node_modules/type-fest/source/words.d.ts +148 -0
- package/node_modules/type-fest/source/writable-deep.d.ts +84 -0
- package/node_modules/type-fest/source/writable-keys-of.d.ts +34 -0
- package/node_modules/type-fest/source/writable.d.ts +68 -0
- package/node_modules/type-fest/source/xor.d.ts +83 -0
- package/node_modules/usehooks-ts/LICENSE +22 -0
- package/node_modules/usehooks-ts/README.md +473 -0
- package/node_modules/usehooks-ts/dist/index.cjs +1084 -0
- package/node_modules/usehooks-ts/dist/index.d.cts +953 -0
- package/node_modules/usehooks-ts/dist/index.d.ts +953 -0
- package/node_modules/usehooks-ts/dist/index.js +1046 -0
- package/node_modules/usehooks-ts/package.json +74 -0
- package/node_modules/wrap-ansi/index.d.ts +41 -0
- package/node_modules/wrap-ansi/index.js +222 -0
- package/node_modules/wrap-ansi/license +9 -0
- package/node_modules/wrap-ansi/package.json +69 -0
- package/node_modules/wrap-ansi/readme.md +75 -0
- package/package.json +3 -2
|
@@ -0,0 +1,1499 @@
|
|
|
1
|
+
// @ts-nocheck — react-reconciler internals (FiberRoot, ConcurrentRoot) lag the runtime types.
|
|
2
|
+
|
|
3
|
+
import autoBind from 'auto-bind';
|
|
4
|
+
import { closeSync, constants as fsConstants, openSync, readSync, writeSync } from 'fs';
|
|
5
|
+
import noop from 'lodash-es/noop.js';
|
|
6
|
+
import throttle from 'lodash-es/throttle.js';
|
|
7
|
+
import React, { type ReactNode } from 'react';
|
|
8
|
+
import type { FiberRoot } from 'react-reconciler';
|
|
9
|
+
import { ConcurrentRoot } from 'react-reconciler/constants.js';
|
|
10
|
+
import { onExit } from 'signal-exit';
|
|
11
|
+
import { flushInteractionTime } from './_internal/state.js';
|
|
12
|
+
import { getYogaCounters } from './_internal/yoga-layout.js';
|
|
13
|
+
import { logForDebugging } from './_internal/debug.js';
|
|
14
|
+
import { logError } from './_internal/log.js';
|
|
15
|
+
import { format } from 'util';
|
|
16
|
+
import { colorize } from './colorize.js';
|
|
17
|
+
import App from './components/App.js';
|
|
18
|
+
import type { CursorDeclaration, CursorDeclarationSetter } from './components/CursorDeclarationContext.js';
|
|
19
|
+
import { FRAME_INTERVAL_MS } from './constants.js';
|
|
20
|
+
import * as dom from './dom.js';
|
|
21
|
+
import { KeyboardEvent } from './events/keyboard-event.js';
|
|
22
|
+
import { FocusManager } from './focus.js';
|
|
23
|
+
import { emptyFrame, type Frame, type FrameEvent } from './frame.js';
|
|
24
|
+
import { dispatchClick, dispatchHover } from './hit-test.js';
|
|
25
|
+
import instances from './instances.js';
|
|
26
|
+
import { LogUpdate } from './log-update.js';
|
|
27
|
+
import { nodeCache } from './node-cache.js';
|
|
28
|
+
import { optimize } from './optimizer.js';
|
|
29
|
+
import Output from './output.js';
|
|
30
|
+
import type { ParsedKey } from './parse-keypress.js';
|
|
31
|
+
import reconciler, { dispatcher, getLastCommitMs, getLastYogaMs, isDebugRepaintsEnabled, recordYogaMs, resetProfileCounters } from './reconciler.js';
|
|
32
|
+
import renderNodeToOutput, { consumeFollowScroll, didLayoutShift } from './render-node-to-output.js';
|
|
33
|
+
import { applyPositionedHighlight, type MatchPosition, scanPositions } from './render-to-screen.js';
|
|
34
|
+
import createRenderer, { type Renderer } from './renderer.js';
|
|
35
|
+
import { CellWidth, CharPool, cellAt, createScreen, HyperlinkPool, isEmptyCellAt, migrateScreenPools, StylePool } from './screen.js';
|
|
36
|
+
import { applySearchHighlight } from './searchHighlight.js';
|
|
37
|
+
import { applySelectionOverlay, captureScrolledRows, clearSelection, createSelectionState, extendSelection, type FocusMove, findPlainTextUrlAt, getSelectedText, hasSelection, moveFocus, type SelectionState, selectLineAt, selectWordAt, shiftAnchor, shiftSelection, shiftSelectionForFollow, startSelection, updateSelection } from './selection.js';
|
|
38
|
+
import { SYNC_OUTPUT_SUPPORTED, supportsExtendedKeys, type Terminal, writeDiffToTerminal } from './terminal.js';
|
|
39
|
+
import { CURSOR_HOME, cursorMove, cursorPosition, DISABLE_KITTY_KEYBOARD, DISABLE_MODIFY_OTHER_KEYS, ENABLE_KITTY_KEYBOARD, ENABLE_MODIFY_OTHER_KEYS, ERASE_SCREEN } from './termio/csi.js';
|
|
40
|
+
import { DBP, DFE, DISABLE_MOUSE_TRACKING, ENABLE_MOUSE_TRACKING, ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, SHOW_CURSOR } from './termio/dec.js';
|
|
41
|
+
import { CLEAR_ITERM2_PROGRESS, CLEAR_TAB_STATUS, setClipboard, supportsTabStatus, wrapForMultiplexer } from './termio/osc.js';
|
|
42
|
+
import { TerminalWriteProvider } from './useTerminalNotification.js';
|
|
43
|
+
|
|
44
|
+
// In alt-screen mode the cursor is always hidden: `renderer.ts` derives
|
|
45
|
+
// `cursor.visible = !isTTY || screen.height === 0`, both of which are
|
|
46
|
+
// false here (TTY plus content that fills the screen). Freezing a
|
|
47
|
+
// single shared object instead of building one each frame removes one
|
|
48
|
+
// allocation from the hot path.
|
|
49
|
+
const ALT_SCREEN_ANCHOR_CURSOR = Object.freeze({
|
|
50
|
+
x: 0,
|
|
51
|
+
y: 0,
|
|
52
|
+
visible: false
|
|
53
|
+
});
|
|
54
|
+
const CURSOR_HOME_PATCH = Object.freeze({
|
|
55
|
+
type: 'stdout' as const,
|
|
56
|
+
content: CURSOR_HOME
|
|
57
|
+
});
|
|
58
|
+
const ERASE_THEN_HOME_PATCH = Object.freeze({
|
|
59
|
+
type: 'stdout' as const,
|
|
60
|
+
content: ERASE_SCREEN + CURSOR_HOME
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Park-cursor escape cached per `Ink` instance and invalidated whenever
|
|
64
|
+
// the terminal resizes. In alt-screen mode `frame.cursor.y` is always
|
|
65
|
+
// `terminalRows - 1` (see `renderer.ts`), so a single CSI move suffices.
|
|
66
|
+
function makeAltScreenParkPatch(terminalRows: number) {
|
|
67
|
+
return Object.freeze({
|
|
68
|
+
type: 'stdout' as const,
|
|
69
|
+
content: cursorPosition(terminalRows, 1)
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export type Options = {
|
|
73
|
+
stdout: NodeJS.WriteStream;
|
|
74
|
+
stdin: NodeJS.ReadStream;
|
|
75
|
+
stderr: NodeJS.WriteStream;
|
|
76
|
+
exitOnCtrlC: boolean;
|
|
77
|
+
patchConsole: boolean;
|
|
78
|
+
waitUntilExit?: () => Promise<void>;
|
|
79
|
+
onFrame?: (event: FrameEvent) => void;
|
|
80
|
+
};
|
|
81
|
+
export default class Ink {
|
|
82
|
+
private readonly log: LogUpdate;
|
|
83
|
+
private readonly terminal: Terminal;
|
|
84
|
+
private scheduleRender: (() => void) & {
|
|
85
|
+
cancel?: () => void;
|
|
86
|
+
};
|
|
87
|
+
// Ignore last render after unmounting a tree to prevent empty output before exit
|
|
88
|
+
private isUnmounted = false;
|
|
89
|
+
private isPaused = false;
|
|
90
|
+
private readonly container: FiberRoot;
|
|
91
|
+
private rootNode: dom.DOMElement;
|
|
92
|
+
readonly focusManager: FocusManager;
|
|
93
|
+
private renderer: Renderer;
|
|
94
|
+
private readonly stylePool: StylePool;
|
|
95
|
+
private charPool: CharPool;
|
|
96
|
+
private hyperlinkPool: HyperlinkPool;
|
|
97
|
+
private exitPromise?: Promise<void>;
|
|
98
|
+
private restoreConsole?: () => void;
|
|
99
|
+
private restoreStderr?: () => void;
|
|
100
|
+
private readonly unsubscribeTTYHandlers?: () => void;
|
|
101
|
+
private terminalColumns: number;
|
|
102
|
+
private terminalRows: number;
|
|
103
|
+
private currentNode: ReactNode = null;
|
|
104
|
+
private frontFrame: Frame;
|
|
105
|
+
private backFrame: Frame;
|
|
106
|
+
private lastPoolResetTime = performance.now();
|
|
107
|
+
private drainTimer: ReturnType<typeof setTimeout> | null = null;
|
|
108
|
+
private lastYogaCounters: {
|
|
109
|
+
ms: number;
|
|
110
|
+
visited: number;
|
|
111
|
+
measured: number;
|
|
112
|
+
cacheHits: number;
|
|
113
|
+
live: number;
|
|
114
|
+
} = {
|
|
115
|
+
ms: 0,
|
|
116
|
+
visited: 0,
|
|
117
|
+
measured: 0,
|
|
118
|
+
cacheHits: 0,
|
|
119
|
+
live: 0
|
|
120
|
+
};
|
|
121
|
+
private altScreenParkPatch: Readonly<{
|
|
122
|
+
type: 'stdout';
|
|
123
|
+
content: string;
|
|
124
|
+
}>;
|
|
125
|
+
// Text-selection state. Only relevant in alt-screen mode. Lives on
|
|
126
|
+
// the Ink instance so the selection-overlay pass in `onRender` can
|
|
127
|
+
// read it and `App.tsx` can mutate it in response to mouse events.
|
|
128
|
+
// Made public so consumers reached via `instances.get(...)` can
|
|
129
|
+
// read selection state without re-implementing it.
|
|
130
|
+
readonly selection: SelectionState = createSelectionState();
|
|
131
|
+
// Search highlight query (alt-screen only). Setter below triggers
|
|
132
|
+
// scheduleRender; applySearchHighlight in onRender inverts matching cells.
|
|
133
|
+
private searchHighlightQuery = '';
|
|
134
|
+
// Position-based highlight (used by virtual-message-list search).
|
|
135
|
+
// The owning component scans match positions exactly once via
|
|
136
|
+
// `scanElementSubtree` when the target message is mounted, stores
|
|
137
|
+
// them message-relative, and updates this struct on every frame so
|
|
138
|
+
// `applyPositionedHighlight` can paint them.
|
|
139
|
+
// - `rowOffset` is the message's current screen-top, used to
|
|
140
|
+
// translate stored positions into absolute screen coordinates.
|
|
141
|
+
// - `currentIdx` selects the currently focused match (rendered in
|
|
142
|
+
// yellow); any other match uses the plain inverse overlay.
|
|
143
|
+
// - `null` clears the highlight entirely.
|
|
144
|
+
// Navigation between matches is plain index arithmetic — there is no
|
|
145
|
+
// re-scan, so there is no risk of a feedback loop with the renderer.
|
|
146
|
+
private searchPositions: {
|
|
147
|
+
positions: MatchPosition[];
|
|
148
|
+
rowOffset: number;
|
|
149
|
+
currentIdx: number;
|
|
150
|
+
} | null = null;
|
|
151
|
+
// React-land subscribers for selection state changes (useHasSelection).
|
|
152
|
+
// Fired alongside the terminal repaint whenever the selection mutates
|
|
153
|
+
// so UI (e.g. footer hints) can react to selection appearing/clearing.
|
|
154
|
+
private readonly selectionListeners = new Set<() => void>();
|
|
155
|
+
// DOM nodes currently under the pointer (mode-1003 motion). Held here
|
|
156
|
+
// so App.tsx's handleMouseEvent is stateless — dispatchHover diffs
|
|
157
|
+
// against this set and mutates it in place.
|
|
158
|
+
private readonly hoveredNodes = new Set<dom.DOMElement>();
|
|
159
|
+
// Set by <AlternateScreen> via setAltScreenActive(). Controls the
|
|
160
|
+
// renderer's cursor.y clamping (keeps cursor in-viewport to avoid
|
|
161
|
+
// LF-induced scroll when screen.height === terminalRows) and gates
|
|
162
|
+
// alt-screen-aware SIGCONT/resize/unmount handling.
|
|
163
|
+
private altScreenActive = false;
|
|
164
|
+
// Set alongside altScreenActive so SIGCONT resume knows whether to
|
|
165
|
+
// re-enable mouse tracking (not all <AlternateScreen> uses want it).
|
|
166
|
+
private altScreenMouseTracking = false;
|
|
167
|
+
// True when the previous frame's screen buffer cannot be trusted for
|
|
168
|
+
// blit — selection overlay mutated it, resetFramesForAltScreen()
|
|
169
|
+
// replaced it with blanks, or forceRedraw() reset it to 0×0. Forces
|
|
170
|
+
// one full-render frame; steady-state frames after clear it and regain
|
|
171
|
+
// the blit + narrow-damage fast path.
|
|
172
|
+
private prevFrameContaminated = false;
|
|
173
|
+
// Set by handleResize: prepend ERASE_SCREEN to the next onRender's patches
|
|
174
|
+
// INSIDE the BSU/ESU block so clear+paint is atomic. Writing ERASE_SCREEN
|
|
175
|
+
// synchronously in handleResize would leave the screen blank for the ~80ms
|
|
176
|
+
// render() takes; deferring into the atomic block means old content stays
|
|
177
|
+
// visible until the new frame is fully ready.
|
|
178
|
+
private needsEraseBeforePaint = false;
|
|
179
|
+
// Native cursor positioning: a component (via useDeclaredCursor) declares
|
|
180
|
+
// where the terminal cursor should be parked after each frame. Terminal
|
|
181
|
+
// emulators render IME preedit text at the physical cursor position, and
|
|
182
|
+
// screen readers / screen magnifiers track it — so parking at the text
|
|
183
|
+
// input's caret makes CJK input appear inline and lets a11y tools follow.
|
|
184
|
+
private cursorDeclaration: CursorDeclaration | null = null;
|
|
185
|
+
// Main-screen: physical cursor position after the declared-cursor move,
|
|
186
|
+
// tracked separately from frame.cursor (which must stay at content-bottom
|
|
187
|
+
// for log-update's relative-move invariants). Alt-screen doesn't need
|
|
188
|
+
// this — every frame begins with CSI H. null = no move emitted last frame.
|
|
189
|
+
private displayCursor: {
|
|
190
|
+
x: number;
|
|
191
|
+
y: number;
|
|
192
|
+
} | null = null;
|
|
193
|
+
constructor(private readonly options: Options) {
|
|
194
|
+
autoBind(this);
|
|
195
|
+
if (this.options.patchConsole) {
|
|
196
|
+
this.restoreConsole = this.patchConsole();
|
|
197
|
+
this.restoreStderr = this.patchStderr();
|
|
198
|
+
}
|
|
199
|
+
this.terminal = {
|
|
200
|
+
stdout: options.stdout,
|
|
201
|
+
stderr: options.stderr
|
|
202
|
+
};
|
|
203
|
+
this.terminalColumns = options.stdout.columns || 80;
|
|
204
|
+
this.terminalRows = options.stdout.rows || 24;
|
|
205
|
+
this.altScreenParkPatch = makeAltScreenParkPatch(this.terminalRows);
|
|
206
|
+
this.stylePool = new StylePool();
|
|
207
|
+
this.charPool = new CharPool();
|
|
208
|
+
this.hyperlinkPool = new HyperlinkPool();
|
|
209
|
+
this.frontFrame = emptyFrame(this.terminalRows, this.terminalColumns, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
210
|
+
this.backFrame = emptyFrame(this.terminalRows, this.terminalColumns, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
211
|
+
this.log = new LogUpdate({
|
|
212
|
+
isTTY: options.stdout.isTTY as boolean | undefined || false,
|
|
213
|
+
stylePool: this.stylePool
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// scheduleRender is called from the reconciler's resetAfterCommit, which
|
|
217
|
+
// runs BEFORE React's layout phase (ref attach + useLayoutEffect). Any
|
|
218
|
+
// state set in layout effects — notably the cursorDeclaration from
|
|
219
|
+
// useDeclaredCursor — would lag one commit behind if we rendered
|
|
220
|
+
// synchronously. Deferring to a microtask runs onRender after layout
|
|
221
|
+
// effects have committed, so the native cursor tracks the caret without
|
|
222
|
+
// a one-keystroke lag. Same event-loop tick, so throughput is unchanged.
|
|
223
|
+
// Test env uses onImmediateRender (direct onRender, no throttle) so
|
|
224
|
+
// existing synchronous lastFrame() tests are unaffected.
|
|
225
|
+
const deferredRender = (): void => queueMicrotask(this.onRender);
|
|
226
|
+
this.scheduleRender = throttle(deferredRender, FRAME_INTERVAL_MS, {
|
|
227
|
+
leading: true,
|
|
228
|
+
trailing: true
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Ignore last render after unmounting a tree to prevent empty output before exit
|
|
232
|
+
this.isUnmounted = false;
|
|
233
|
+
|
|
234
|
+
// Unmount when process exits
|
|
235
|
+
this.unsubscribeExit = onExit(this.unmount, {
|
|
236
|
+
alwaysLast: false
|
|
237
|
+
});
|
|
238
|
+
if (options.stdout.isTTY) {
|
|
239
|
+
options.stdout.on('resize', this.handleResize);
|
|
240
|
+
process.on('SIGCONT', this.handleResume);
|
|
241
|
+
this.unsubscribeTTYHandlers = () => {
|
|
242
|
+
options.stdout.off('resize', this.handleResize);
|
|
243
|
+
process.off('SIGCONT', this.handleResume);
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
this.rootNode = dom.createNode('ink-root');
|
|
247
|
+
this.focusManager = new FocusManager((target, event) => dispatcher.dispatchDiscrete(target, event));
|
|
248
|
+
this.rootNode.focusManager = this.focusManager;
|
|
249
|
+
this.renderer = createRenderer(this.rootNode, this.stylePool);
|
|
250
|
+
this.rootNode.onRender = this.scheduleRender;
|
|
251
|
+
this.rootNode.onImmediateRender = this.onRender;
|
|
252
|
+
this.rootNode.onComputeLayout = () => {
|
|
253
|
+
// Calculate layout during React's commit phase so useLayoutEffect hooks
|
|
254
|
+
// have access to fresh layout data
|
|
255
|
+
// Guard against accessing freed Yoga nodes after unmount
|
|
256
|
+
if (this.isUnmounted) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (this.rootNode.yogaNode) {
|
|
260
|
+
const t0 = performance.now();
|
|
261
|
+
this.rootNode.yogaNode.setWidth(this.terminalColumns);
|
|
262
|
+
this.rootNode.yogaNode.calculateLayout(this.terminalColumns);
|
|
263
|
+
const ms = performance.now() - t0;
|
|
264
|
+
recordYogaMs(ms);
|
|
265
|
+
const c = getYogaCounters();
|
|
266
|
+
this.lastYogaCounters = {
|
|
267
|
+
ms,
|
|
268
|
+
...c
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
this.container = reconciler.createContainer(this.rootNode, ConcurrentRoot, null, false, null, 'id', noop,
|
|
274
|
+
// onUncaughtError
|
|
275
|
+
noop,
|
|
276
|
+
// onCaughtError
|
|
277
|
+
noop,
|
|
278
|
+
// onRecoverableError
|
|
279
|
+
noop // onDefaultTransitionIndicator
|
|
280
|
+
);
|
|
281
|
+
if (("production" as string) === 'development') {
|
|
282
|
+
reconciler.injectIntoDevTools({
|
|
283
|
+
bundleType: 0,
|
|
284
|
+
// The `version` field here must report the React version we
|
|
285
|
+
// were *built against*, not our own package version. React
|
|
286
|
+
// DevTools uses it to pick the matching internal API surface;
|
|
287
|
+
// reporting our own version causes it to fall back to a
|
|
288
|
+
// generic renderer view with no component tree.
|
|
289
|
+
version: '16.13.1',
|
|
290
|
+
rendererPackageName: 'ink'
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
private handleResume = () => {
|
|
295
|
+
if (!this.options.stdout.isTTY) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Alt screen: after SIGCONT, content is stale (shell may have written
|
|
300
|
+
// to main screen, switching focus away) and mouse tracking was
|
|
301
|
+
// disabled by handleSuspend.
|
|
302
|
+
if (this.altScreenActive) {
|
|
303
|
+
this.reenterAltScreen();
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Main screen: start fresh to prevent clobbering terminal content
|
|
308
|
+
this.frontFrame = emptyFrame(this.frontFrame.viewport.height, this.frontFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
309
|
+
this.backFrame = emptyFrame(this.backFrame.viewport.height, this.backFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
310
|
+
this.log.reset();
|
|
311
|
+
// Physical cursor position is unknown after the shell took over during
|
|
312
|
+
// suspend. Clear displayCursor so the next frame's cursor preamble
|
|
313
|
+
// doesn't emit a relative move from a stale park position.
|
|
314
|
+
this.displayCursor = null;
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// Deliberately *not* debounced. A debounce window opens a short
|
|
318
|
+
// interval where `stdout.columns` already reflects the new size but
|
|
319
|
+
// `this.terminalColumns` (and the Yoga layout that depends on it)
|
|
320
|
+
// are still the old size. Any unrelated `scheduleRender` during that
|
|
321
|
+
// window — a spinner tick, a clock tick — makes `log-update` notice
|
|
322
|
+
// the width disagreement, force a screen clear, then the debounce
|
|
323
|
+
// fires and clears again. The user sees a double blank-to-paint
|
|
324
|
+
// flicker for every resize. Per-resize layout cost is already
|
|
325
|
+
// bounded by `useVirtualScroll`'s height scaling, so synchronous
|
|
326
|
+
// handling is the lesser evil.
|
|
327
|
+
private handleResize = () => {
|
|
328
|
+
const cols = this.options.stdout.columns || 80;
|
|
329
|
+
const rows = this.options.stdout.rows || 24;
|
|
330
|
+
// Terminals often emit 2+ resize events for one user action (window
|
|
331
|
+
// settling). Same-dimension events are no-ops; skip to avoid redundant
|
|
332
|
+
// frame resets and renders.
|
|
333
|
+
if (cols === this.terminalColumns && rows === this.terminalRows) return;
|
|
334
|
+
this.terminalColumns = cols;
|
|
335
|
+
this.terminalRows = rows;
|
|
336
|
+
this.altScreenParkPatch = makeAltScreenParkPatch(this.terminalRows);
|
|
337
|
+
|
|
338
|
+
// Alt screen: reset frame buffers so the next render repaints from
|
|
339
|
+
// scratch (prevFrameContaminated → every cell written, wrapped in
|
|
340
|
+
// BSU/ESU — old content stays visible until the new frame swaps
|
|
341
|
+
// atomically). Re-assert mouse tracking (some emulators reset it on
|
|
342
|
+
// resize). Do NOT write ENTER_ALT_SCREEN: iTerm2 treats ?1049h as a
|
|
343
|
+
// buffer clear even when already in alt — that's the blank flicker.
|
|
344
|
+
// Self-healing re-entry (if something kicked us out of alt) is handled
|
|
345
|
+
// by handleResume (SIGCONT) and the sleep-wake detector; resize itself
|
|
346
|
+
// doesn't exit alt-screen. Do NOT write ERASE_SCREEN: render() below
|
|
347
|
+
// can take ~80ms; erasing first leaves the screen blank that whole time.
|
|
348
|
+
if (this.altScreenActive && !this.isPaused && this.options.stdout.isTTY) {
|
|
349
|
+
if (this.altScreenMouseTracking) {
|
|
350
|
+
this.options.stdout.write(ENABLE_MOUSE_TRACKING);
|
|
351
|
+
}
|
|
352
|
+
this.resetFramesForAltScreen();
|
|
353
|
+
this.needsEraseBeforePaint = true;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Re-render the React tree with updated props so the context value changes.
|
|
357
|
+
// React's commit phase will call onComputeLayout() to recalculate yoga layout
|
|
358
|
+
// with the new dimensions, then call onRender() to render the updated frame.
|
|
359
|
+
// We don't call scheduleRender() here because that would render before the
|
|
360
|
+
// layout is updated, causing a mismatch between viewport and content dimensions.
|
|
361
|
+
if (this.currentNode !== null) {
|
|
362
|
+
this.render(this.currentNode);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
resolveExitPromise: () => void = () => {};
|
|
366
|
+
rejectExitPromise: (reason?: Error) => void = () => {};
|
|
367
|
+
unsubscribeExit: () => void = () => {};
|
|
368
|
+
|
|
369
|
+
/** Pause Ink and hand the terminal over to an external TUI (e.g. */
|
|
370
|
+
enterAlternateScreen(): void {
|
|
371
|
+
this.pause();
|
|
372
|
+
this.suspendStdin();
|
|
373
|
+
this.options.stdout.write(
|
|
374
|
+
// Disable extended key reporting first — editors that don't speak
|
|
375
|
+
// CSI-u (e.g. nano) show "Unknown sequence" for every Ctrl-<key> if
|
|
376
|
+
// kitty/modifyOtherKeys stays active. exitAlternateScreen re-enables.
|
|
377
|
+
DISABLE_KITTY_KEYBOARD + DISABLE_MODIFY_OTHER_KEYS + (this.altScreenMouseTracking ? DISABLE_MOUSE_TRACKING : '') + (
|
|
378
|
+
// disable mouse (no-op if off)
|
|
379
|
+
this.altScreenActive ? '' : '\x1b[?1049h') +
|
|
380
|
+
// enter alt (already in alt if fullscreen)
|
|
381
|
+
'\x1b[?1004l' +
|
|
382
|
+
// disable focus reporting
|
|
383
|
+
'\x1b[0m' +
|
|
384
|
+
// reset attributes
|
|
385
|
+
'\x1b[?25h' +
|
|
386
|
+
// show cursor
|
|
387
|
+
'\x1b[2J' +
|
|
388
|
+
// clear screen
|
|
389
|
+
'\x1b[H' // cursor home
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/** Resume Ink after an external TUI handoff with a full repaint. */
|
|
394
|
+
exitAlternateScreen(): void {
|
|
395
|
+
this.options.stdout.write((this.altScreenActive ? ENTER_ALT_SCREEN : '') +
|
|
396
|
+
// re-enter alt — vim's rmcup dropped us to main
|
|
397
|
+
'\x1b[2J' +
|
|
398
|
+
// clear screen (now alt if fullscreen)
|
|
399
|
+
'\x1b[H' + (
|
|
400
|
+
// cursor home
|
|
401
|
+
this.altScreenMouseTracking ? ENABLE_MOUSE_TRACKING : '') + (
|
|
402
|
+
// re-enable mouse (skip if REASONIX_DISABLE_MOUSE)
|
|
403
|
+
this.altScreenActive ? '' : '\x1b[?1049l') +
|
|
404
|
+
// exit alt (non-fullscreen only)
|
|
405
|
+
'\x1b[?25l' // hide cursor (Ink manages)
|
|
406
|
+
);
|
|
407
|
+
this.resumeStdin();
|
|
408
|
+
if (this.altScreenActive) {
|
|
409
|
+
this.resetFramesForAltScreen();
|
|
410
|
+
} else {
|
|
411
|
+
this.repaint();
|
|
412
|
+
}
|
|
413
|
+
this.resume();
|
|
414
|
+
// Re-enable focus reporting and extended key reporting — terminal
|
|
415
|
+
// editors (vim, nano, etc.) write their own modifyOtherKeys level on
|
|
416
|
+
// entry and reset it on exit, leaving us unable to distinguish
|
|
417
|
+
// ctrl+shift+<letter> from ctrl+<letter>. Pop-before-push keeps the
|
|
418
|
+
// Kitty stack balanced (a well-behaved editor restores our entry, so
|
|
419
|
+
// without the pop we'd accumulate depth on each editor round-trip).
|
|
420
|
+
this.options.stdout.write('\x1b[?1004h' + (supportsExtendedKeys() ? DISABLE_KITTY_KEYBOARD + ENABLE_KITTY_KEYBOARD + ENABLE_MODIFY_OTHER_KEYS : ''));
|
|
421
|
+
}
|
|
422
|
+
onRender() {
|
|
423
|
+
if (this.isUnmounted || this.isPaused) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
// Entering a render cancels any pending drain tick — this render will
|
|
427
|
+
// handle the drain (and re-schedule below if needed). Prevents a
|
|
428
|
+
// wheel-event-triggered render AND a drain-timer render both firing.
|
|
429
|
+
if (this.drainTimer !== null) {
|
|
430
|
+
clearTimeout(this.drainTimer);
|
|
431
|
+
this.drainTimer = null;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Reset the "last user activity" timestamp at frame start. Read via
|
|
435
|
+
// the public `getLastInteractionTime`, the value is meant to mean
|
|
436
|
+
// "ms since the last input event during this frame"; without the
|
|
437
|
+
// flush, an app that committed once a day ago would still report
|
|
438
|
+
// itself as "just interacted" forever.
|
|
439
|
+
flushInteractionTime();
|
|
440
|
+
const renderStart = performance.now();
|
|
441
|
+
const terminalWidth = this.options.stdout.columns || 80;
|
|
442
|
+
const terminalRows = this.options.stdout.rows || 24;
|
|
443
|
+
const frame = this.renderer({
|
|
444
|
+
frontFrame: this.frontFrame,
|
|
445
|
+
backFrame: this.backFrame,
|
|
446
|
+
isTTY: this.options.stdout.isTTY,
|
|
447
|
+
terminalWidth,
|
|
448
|
+
terminalRows,
|
|
449
|
+
altScreen: this.altScreenActive,
|
|
450
|
+
prevFrameContaminated: this.prevFrameContaminated
|
|
451
|
+
});
|
|
452
|
+
const rendererMs = performance.now() - renderStart;
|
|
453
|
+
|
|
454
|
+
// Sticky/auto-follow scrolled the ScrollBox this frame. Translate the
|
|
455
|
+
// selection by the same delta so the highlight stays anchored to the
|
|
456
|
+
// TEXT (native terminal behavior — the selection walks up the screen
|
|
457
|
+
// as content scrolls, eventually clipping at the top). frontFrame
|
|
458
|
+
// still holds the PREVIOUS frame's screen (swap is at ~500 below), so
|
|
459
|
+
// captureScrolledRows reads the rows that are about to scroll out
|
|
460
|
+
// before they're overwritten — the text stays copyable until the
|
|
461
|
+
// selection scrolls entirely off. During drag, focus tracks the mouse
|
|
462
|
+
// (screen-local) so only anchor shifts — selection grows toward the
|
|
463
|
+
// mouse as the anchor walks up. After release, both ends are text-
|
|
464
|
+
// anchored and move as a block.
|
|
465
|
+
const follow = consumeFollowScroll();
|
|
466
|
+
if (follow && this.selection.anchor &&
|
|
467
|
+
// Only translate if the selection is ON scrollbox content. Selections
|
|
468
|
+
// in the footer/prompt/StickyPromptHeader are on static text — the
|
|
469
|
+
// scroll doesn't move what's under them. Without this guard, a
|
|
470
|
+
// footer selection would be shifted by -delta then clamped to
|
|
471
|
+
// viewportBottom, teleporting it into the scrollbox. Mirror the
|
|
472
|
+
// bounds check the deleted check() in ScrollKeybindingHandler had.
|
|
473
|
+
this.selection.anchor.row >= follow.viewportTop && this.selection.anchor.row <= follow.viewportBottom) {
|
|
474
|
+
const {
|
|
475
|
+
delta,
|
|
476
|
+
viewportTop,
|
|
477
|
+
viewportBottom
|
|
478
|
+
} = follow;
|
|
479
|
+
// captureScrolledRows and shift* are a pair: capture grabs rows about
|
|
480
|
+
// to scroll off, shift moves the selection endpoint so the same rows
|
|
481
|
+
// won't intersect again next frame. Capturing without shifting leaves
|
|
482
|
+
// the endpoint in place, so the SAME viewport rows re-intersect every
|
|
483
|
+
// frame and scrolledOffAbove grows without bound — getSelectedText
|
|
484
|
+
// then returns ever-growing text on each re-copy. Keep capture inside
|
|
485
|
+
// each shift branch so the pairing can't be broken by a new guard.
|
|
486
|
+
if (this.selection.isDragging) {
|
|
487
|
+
if (hasSelection(this.selection)) {
|
|
488
|
+
captureScrolledRows(this.selection, this.frontFrame.screen, viewportTop, viewportTop + delta - 1, 'above');
|
|
489
|
+
}
|
|
490
|
+
shiftAnchor(this.selection, -delta, viewportTop, viewportBottom);
|
|
491
|
+
} else if (
|
|
492
|
+
// Flag-3 guard: the anchor check above only proves ONE endpoint is
|
|
493
|
+
// on scrollbox content. A drag from row 3 (scrollbox) into the
|
|
494
|
+
// footer at row 6, then release, leaves focus outside the viewport
|
|
495
|
+
// — shiftSelectionForFollow would clamp it to viewportBottom,
|
|
496
|
+
// teleporting the highlight from static footer into the scrollbox.
|
|
497
|
+
// Symmetric check: require BOTH ends inside to translate. A
|
|
498
|
+
// straddling selection falls through to NEITHER shift NOR capture:
|
|
499
|
+
// the footer endpoint pins the selection, text scrolls away under
|
|
500
|
+
// the highlight, and getSelectedText reads the CURRENT screen
|
|
501
|
+
// contents — no accumulation. Dragging branch doesn't need this:
|
|
502
|
+
// shiftAnchor ignores focus, and the anchor DOES shift (so capture
|
|
503
|
+
// is correct there even when focus is in the footer).
|
|
504
|
+
!this.selection.focus || this.selection.focus.row >= viewportTop && this.selection.focus.row <= viewportBottom) {
|
|
505
|
+
if (hasSelection(this.selection)) {
|
|
506
|
+
captureScrolledRows(this.selection, this.frontFrame.screen, viewportTop, viewportTop + delta - 1, 'above');
|
|
507
|
+
}
|
|
508
|
+
const cleared = shiftSelectionForFollow(this.selection, -delta, viewportTop, viewportBottom);
|
|
509
|
+
// Auto-clear (both ends overshot minRow) must notify React-land
|
|
510
|
+
// so useHasSelection re-renders and the footer copy/escape hint
|
|
511
|
+
// disappears. notifySelectionChange() would recurse into onRender;
|
|
512
|
+
// fire the listeners directly — they schedule a React update for
|
|
513
|
+
// LATER, they don't re-enter this frame.
|
|
514
|
+
if (cleared) for (const cb of this.selectionListeners) cb();
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Selection overlay: invert cell styles in the screen buffer itself,
|
|
519
|
+
// so the diff picks up selection as ordinary cell changes and
|
|
520
|
+
// LogUpdate remains a pure diff engine.
|
|
521
|
+
//
|
|
522
|
+
// Full-screen damage (PR #20120) is a correctness backstop for the
|
|
523
|
+
// sibling-resize bleed: when flexbox siblings resize between frames
|
|
524
|
+
// (spinner appears → bottom grows → scrollbox shrinks), the
|
|
525
|
+
// cached-clear + clip-and-cull + setCellAt damage union can miss
|
|
526
|
+
// transition cells at the boundary. But that only happens when layout
|
|
527
|
+
// actually SHIFTS — didLayoutShift() tracks exactly this (any node's
|
|
528
|
+
// cached yoga position/size differs from current, or a child was
|
|
529
|
+
// removed). Steady-state frames (spinner rotate, clock tick, text
|
|
530
|
+
// stream into fixed-height box) don't shift layout, so normal damage
|
|
531
|
+
// bounds are correct and diffEach only compares the damaged region.
|
|
532
|
+
//
|
|
533
|
+
// Selection also requires full damage: overlay writes via setCellStyleId
|
|
534
|
+
// which doesn't track damage, and prev-frame overlay cells need to be
|
|
535
|
+
// compared when selection moves/clears. prevFrameContaminated covers
|
|
536
|
+
// the frame-after-selection-clears case.
|
|
537
|
+
let selActive = false;
|
|
538
|
+
let hlActive = false;
|
|
539
|
+
if (this.altScreenActive) {
|
|
540
|
+
selActive = hasSelection(this.selection);
|
|
541
|
+
if (selActive) {
|
|
542
|
+
applySelectionOverlay(frame.screen, this.selection, this.stylePool);
|
|
543
|
+
}
|
|
544
|
+
// Scan-highlight: inverse on ALL visible matches (less/vim style).
|
|
545
|
+
// Position-highlight (below) overlays CURRENT (yellow) on top.
|
|
546
|
+
hlActive = applySearchHighlight(frame.screen, this.searchHighlightQuery, this.stylePool);
|
|
547
|
+
// Position-based CURRENT: write yellow at positions[currentIdx] +
|
|
548
|
+
// rowOffset. No scanning — positions came from a prior scan when
|
|
549
|
+
// the message first mounted. Message-relative + rowOffset = screen.
|
|
550
|
+
if (this.searchPositions) {
|
|
551
|
+
const sp = this.searchPositions;
|
|
552
|
+
const posApplied = applyPositionedHighlight(frame.screen, this.stylePool, sp.positions, sp.rowOffset, sp.currentIdx);
|
|
553
|
+
hlActive = hlActive || posApplied;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Full-damage backstop: applies on BOTH alt-screen and main-screen.
|
|
558
|
+
// Layout shifts (spinner appears, status line resizes) can leave stale
|
|
559
|
+
// cells at sibling boundaries that per-node damage tracking misses.
|
|
560
|
+
// Selection/highlight overlays write via setCellStyleId which doesn't
|
|
561
|
+
// track damage. prevFrameContaminated covers the cleanup frame.
|
|
562
|
+
if (didLayoutShift() || selActive || hlActive || this.prevFrameContaminated) {
|
|
563
|
+
frame.screen.damage = {
|
|
564
|
+
x: 0,
|
|
565
|
+
y: 0,
|
|
566
|
+
width: frame.screen.width,
|
|
567
|
+
height: frame.screen.height
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Alt-screen: anchor the physical cursor to (0,0) before every diff.
|
|
572
|
+
// All cursor moves in log-update are RELATIVE to prev.cursor; if tmux
|
|
573
|
+
// (or any emulator) perturbs the physical cursor out-of-band (status
|
|
574
|
+
// bar refresh, pane redraw, Cmd+K wipe), the relative moves drift and
|
|
575
|
+
// content creeps up 1 row/frame. CSI H resets the physical cursor;
|
|
576
|
+
// passing prev.cursor=(0,0) makes the diff compute from the same spot.
|
|
577
|
+
// Self-healing against any external cursor manipulation. Main-screen
|
|
578
|
+
// can't do this — cursor.y tracks scrollback rows CSI H can't reach.
|
|
579
|
+
// The CSI H write is deferred until after the diff is computed so we
|
|
580
|
+
// can skip it for empty diffs (no writes → physical cursor unused).
|
|
581
|
+
let prevFrame = this.frontFrame;
|
|
582
|
+
if (this.altScreenActive) {
|
|
583
|
+
prevFrame = {
|
|
584
|
+
...this.frontFrame,
|
|
585
|
+
cursor: ALT_SCREEN_ANCHOR_CURSOR
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
const tDiff = performance.now();
|
|
589
|
+
const diff = this.log.render(prevFrame, frame, this.altScreenActive,
|
|
590
|
+
// DECSTBM needs BSU/ESU atomicity — without it the outer terminal
|
|
591
|
+
// renders the scrolled-but-not-yet-repainted intermediate state.
|
|
592
|
+
// tmux is the main case (re-emits DECSTBM with its own timing and
|
|
593
|
+
// doesn't implement DEC 2026, so SYNC_OUTPUT_SUPPORTED is false).
|
|
594
|
+
SYNC_OUTPUT_SUPPORTED);
|
|
595
|
+
const diffMs = performance.now() - tDiff;
|
|
596
|
+
// Swap buffers
|
|
597
|
+
this.backFrame = this.frontFrame;
|
|
598
|
+
this.frontFrame = frame;
|
|
599
|
+
|
|
600
|
+
// Periodically reset char/hyperlink pools to prevent unbounded growth
|
|
601
|
+
// during long sessions. 5 minutes is infrequent enough that the O(cells)
|
|
602
|
+
// migration cost is negligible. Reuses renderStart to avoid extra clock call.
|
|
603
|
+
if (renderStart - this.lastPoolResetTime > 5 * 60 * 1000) {
|
|
604
|
+
this.resetPools();
|
|
605
|
+
this.lastPoolResetTime = renderStart;
|
|
606
|
+
}
|
|
607
|
+
const flickers: FrameEvent['flickers'] = [];
|
|
608
|
+
for (const patch of diff) {
|
|
609
|
+
if (patch.type === 'clearTerminal') {
|
|
610
|
+
flickers.push({
|
|
611
|
+
desiredHeight: frame.screen.height,
|
|
612
|
+
availableHeight: frame.viewport.height,
|
|
613
|
+
reason: patch.reason
|
|
614
|
+
});
|
|
615
|
+
if (isDebugRepaintsEnabled() && patch.debug) {
|
|
616
|
+
const chain = dom.findOwnerChainAtRow(this.rootNode, patch.debug.triggerY);
|
|
617
|
+
logForDebugging(`[REPAINT] full reset · ${patch.reason} · row ${patch.debug.triggerY}\n` + ` prev: "${patch.debug.prevLine}"\n` + ` next: "${patch.debug.nextLine}"\n` + ` culprit: ${chain.length ? chain.join(' < ') : '(no owner chain captured)'}`, {
|
|
618
|
+
level: 'warn'
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const tOptimize = performance.now();
|
|
624
|
+
const optimized = optimize(diff);
|
|
625
|
+
const optimizeMs = performance.now() - tOptimize;
|
|
626
|
+
const hasDiff = optimized.length > 0;
|
|
627
|
+
if (this.altScreenActive && hasDiff) {
|
|
628
|
+
// Prepend CSI H to anchor the physical cursor to (0,0) so
|
|
629
|
+
// log-update's relative moves compute from a known spot (self-healing
|
|
630
|
+
// against out-of-band cursor drift, see the ALT_SCREEN_ANCHOR_CURSOR
|
|
631
|
+
// comment above). Append CSI row;1 H to park the cursor at the bottom
|
|
632
|
+
// row (where the prompt input is) — without this, the cursor ends
|
|
633
|
+
// wherever the last diff write landed (a different row every frame),
|
|
634
|
+
// making iTerm2's cursor guide flicker as it chases the cursor.
|
|
635
|
+
// BSU/ESU protects content atomicity but iTerm2's guide tracks cursor
|
|
636
|
+
// position independently. Parking at bottom (not 0,0) keeps the guide
|
|
637
|
+
// where the user's attention is.
|
|
638
|
+
//
|
|
639
|
+
// After resize, prepend ERASE_SCREEN too. The diff only writes cells
|
|
640
|
+
// that changed; cells where new=blank and prev-buffer=blank get skipped
|
|
641
|
+
// — but the physical terminal still has stale content there (shorter
|
|
642
|
+
// lines at new width leave old-width text tails visible). ERASE inside
|
|
643
|
+
// BSU/ESU is atomic: old content stays visible until the whole
|
|
644
|
+
// erase+paint lands, then swaps in one go. Writing ERASE_SCREEN
|
|
645
|
+
// synchronously in handleResize would blank the screen for the ~80ms
|
|
646
|
+
// render() takes.
|
|
647
|
+
if (this.needsEraseBeforePaint) {
|
|
648
|
+
this.needsEraseBeforePaint = false;
|
|
649
|
+
optimized.unshift(ERASE_THEN_HOME_PATCH);
|
|
650
|
+
} else {
|
|
651
|
+
optimized.unshift(CURSOR_HOME_PATCH);
|
|
652
|
+
}
|
|
653
|
+
optimized.push(this.altScreenParkPatch);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Native cursor positioning: park the terminal cursor at the declared
|
|
657
|
+
// position so IME preedit text renders inline and screen readers /
|
|
658
|
+
// magnifiers can follow the input. nodeCache holds the absolute screen
|
|
659
|
+
// rect populated by renderNodeToOutput this frame (including scrollTop
|
|
660
|
+
// translation) — if the declared node didn't render (stale declaration
|
|
661
|
+
// after remount, or scrolled out of view), it won't be in the cache
|
|
662
|
+
// and no move is emitted.
|
|
663
|
+
const decl = this.cursorDeclaration;
|
|
664
|
+
const rect = decl !== null ? nodeCache.get(decl.node) : undefined;
|
|
665
|
+
const target = decl !== null && rect !== undefined ? {
|
|
666
|
+
x: rect.x + decl.relativeX,
|
|
667
|
+
y: rect.y + decl.relativeY
|
|
668
|
+
} : null;
|
|
669
|
+
const parked = this.displayCursor;
|
|
670
|
+
|
|
671
|
+
// Preserve the empty-diff zero-write fast path: skip all cursor writes
|
|
672
|
+
// when nothing rendered AND the park target is unchanged.
|
|
673
|
+
const targetMoved = target !== null && (parked === null || parked.x !== target.x || parked.y !== target.y);
|
|
674
|
+
if (hasDiff || targetMoved || target === null && parked !== null) {
|
|
675
|
+
// Main-screen preamble: log-update's relative moves assume the
|
|
676
|
+
// physical cursor is at prevFrame.cursor. If last frame parked it
|
|
677
|
+
// elsewhere, move back before the diff runs. Alt-screen's CSI H
|
|
678
|
+
// already resets to (0,0) so no preamble needed.
|
|
679
|
+
if (parked !== null && !this.altScreenActive && hasDiff) {
|
|
680
|
+
const pdx = prevFrame.cursor.x - parked.x;
|
|
681
|
+
const pdy = prevFrame.cursor.y - parked.y;
|
|
682
|
+
if (pdx !== 0 || pdy !== 0) {
|
|
683
|
+
optimized.unshift({
|
|
684
|
+
type: 'stdout',
|
|
685
|
+
content: cursorMove(pdx, pdy)
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
if (target !== null) {
|
|
690
|
+
if (this.altScreenActive) {
|
|
691
|
+
// Absolute CUP (1-indexed); next frame's CSI H resets regardless.
|
|
692
|
+
// Emitted after altScreenParkPatch so the declared position wins.
|
|
693
|
+
const row = Math.min(Math.max(target.y + 1, 1), terminalRows);
|
|
694
|
+
const col = Math.min(Math.max(target.x + 1, 1), terminalWidth);
|
|
695
|
+
optimized.push({
|
|
696
|
+
type: 'stdout',
|
|
697
|
+
content: cursorPosition(row, col)
|
|
698
|
+
});
|
|
699
|
+
} else {
|
|
700
|
+
// After the diff (or preamble), cursor is at frame.cursor. If no
|
|
701
|
+
// diff AND previously parked, it's still at the old park position
|
|
702
|
+
// (log-update wrote nothing). Otherwise it's at frame.cursor.
|
|
703
|
+
const from = !hasDiff && parked !== null ? parked : {
|
|
704
|
+
x: frame.cursor.x,
|
|
705
|
+
y: frame.cursor.y
|
|
706
|
+
};
|
|
707
|
+
const dx = target.x - from.x;
|
|
708
|
+
const dy = target.y - from.y;
|
|
709
|
+
if (dx !== 0 || dy !== 0) {
|
|
710
|
+
optimized.push({
|
|
711
|
+
type: 'stdout',
|
|
712
|
+
content: cursorMove(dx, dy)
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
this.displayCursor = target;
|
|
717
|
+
} else {
|
|
718
|
+
// Declaration cleared (input blur, unmount). Restore physical cursor
|
|
719
|
+
// to frame.cursor before forgetting the park position — otherwise
|
|
720
|
+
// displayCursor=null lies about where the cursor is, and the NEXT
|
|
721
|
+
// frame's preamble (or log-update's relative moves) computes from a
|
|
722
|
+
// wrong spot. The preamble above handles hasDiff; this handles
|
|
723
|
+
// !hasDiff (e.g. accessibility mode where blur doesn't change
|
|
724
|
+
// renderedValue since invert is identity).
|
|
725
|
+
if (parked !== null && !this.altScreenActive && !hasDiff) {
|
|
726
|
+
const rdx = frame.cursor.x - parked.x;
|
|
727
|
+
const rdy = frame.cursor.y - parked.y;
|
|
728
|
+
if (rdx !== 0 || rdy !== 0) {
|
|
729
|
+
optimized.push({
|
|
730
|
+
type: 'stdout',
|
|
731
|
+
content: cursorMove(rdx, rdy)
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
this.displayCursor = null;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const tWrite = performance.now();
|
|
739
|
+
writeDiffToTerminal(this.terminal, optimized, this.altScreenActive && !SYNC_OUTPUT_SUPPORTED);
|
|
740
|
+
const writeMs = performance.now() - tWrite;
|
|
741
|
+
|
|
742
|
+
// Update blit safety for the NEXT frame. The frame just rendered
|
|
743
|
+
// becomes frontFrame (= next frame's prevScreen). If we applied the
|
|
744
|
+
// selection overlay, that buffer has inverted cells. selActive/hlActive
|
|
745
|
+
// are only ever true in alt-screen; in main-screen this is false→false.
|
|
746
|
+
this.prevFrameContaminated = selActive || hlActive;
|
|
747
|
+
|
|
748
|
+
// A ScrollBox has pendingScrollDelta left to drain — schedule the next
|
|
749
|
+
// frame. MUST NOT call this.scheduleRender() here: we're inside a
|
|
750
|
+
// trailing-edge throttle invocation, timerId is undefined, and lodash's
|
|
751
|
+
// debounce sees timeSinceLastCall >= wait (last call was at the start
|
|
752
|
+
// of this window) → leadingEdge fires IMMEDIATELY → double render ~0.1ms
|
|
753
|
+
// apart → jank. Use a plain timeout. If a wheel event arrives first,
|
|
754
|
+
// its scheduleRender path fires a render which clears this timer at
|
|
755
|
+
// the top of onRender — no double.
|
|
756
|
+
//
|
|
757
|
+
// Drain frames are cheap (DECSTBM + ~10 patches, ~200 bytes) so run at
|
|
758
|
+
// quarter interval (~250fps, setTimeout practical floor) for max scroll
|
|
759
|
+
// speed. Regular renders stay at FRAME_INTERVAL_MS via the throttle.
|
|
760
|
+
if (frame.scrollDrainPending) {
|
|
761
|
+
this.drainTimer = setTimeout(() => this.onRender(), FRAME_INTERVAL_MS >> 2);
|
|
762
|
+
}
|
|
763
|
+
const yogaMs = getLastYogaMs();
|
|
764
|
+
const commitMs = getLastCommitMs();
|
|
765
|
+
const yc = this.lastYogaCounters;
|
|
766
|
+
// Reset so drain-only frames (no React commit) don't repeat stale values.
|
|
767
|
+
resetProfileCounters();
|
|
768
|
+
this.lastYogaCounters = {
|
|
769
|
+
ms: 0,
|
|
770
|
+
visited: 0,
|
|
771
|
+
measured: 0,
|
|
772
|
+
cacheHits: 0,
|
|
773
|
+
live: 0
|
|
774
|
+
};
|
|
775
|
+
this.options.onFrame?.({
|
|
776
|
+
durationMs: performance.now() - renderStart,
|
|
777
|
+
phases: {
|
|
778
|
+
renderer: rendererMs,
|
|
779
|
+
diff: diffMs,
|
|
780
|
+
optimize: optimizeMs,
|
|
781
|
+
write: writeMs,
|
|
782
|
+
patches: diff.length,
|
|
783
|
+
yoga: yogaMs,
|
|
784
|
+
commit: commitMs,
|
|
785
|
+
yogaVisited: yc.visited,
|
|
786
|
+
yogaMeasured: yc.measured,
|
|
787
|
+
yogaCacheHits: yc.cacheHits,
|
|
788
|
+
yogaLive: yc.live
|
|
789
|
+
},
|
|
790
|
+
flickers
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
pause(): void {
|
|
794
|
+
// Flush pending React updates and render before pausing.
|
|
795
|
+
reconciler.flushSyncFromReconciler();
|
|
796
|
+
this.onRender();
|
|
797
|
+
this.isPaused = true;
|
|
798
|
+
}
|
|
799
|
+
resume(): void {
|
|
800
|
+
this.isPaused = false;
|
|
801
|
+
this.onRender();
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/** Reset frame buffers so the next render writes the full screen from scratch. */
|
|
805
|
+
repaint(): void {
|
|
806
|
+
this.frontFrame = emptyFrame(this.frontFrame.viewport.height, this.frontFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
807
|
+
this.backFrame = emptyFrame(this.backFrame.viewport.height, this.backFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
808
|
+
this.log.reset();
|
|
809
|
+
// Physical cursor position is unknown after external terminal corruption.
|
|
810
|
+
// Clear displayCursor so the cursor preamble doesn't emit a stale
|
|
811
|
+
// relative move from where we last parked it.
|
|
812
|
+
this.displayCursor = null;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
forceRedraw(): void {
|
|
816
|
+
if (!this.options.stdout.isTTY || this.isUnmounted || this.isPaused) return;
|
|
817
|
+
this.options.stdout.write(ERASE_SCREEN + CURSOR_HOME);
|
|
818
|
+
if (this.altScreenActive) {
|
|
819
|
+
this.resetFramesForAltScreen();
|
|
820
|
+
} else {
|
|
821
|
+
this.repaint();
|
|
822
|
+
// repaint() resets frontFrame to 0×0. Without this flag the next
|
|
823
|
+
// frame's blit optimization copies from that empty screen and the
|
|
824
|
+
// diff sees no content. onRender resets the flag at frame end.
|
|
825
|
+
this.prevFrameContaminated = true;
|
|
826
|
+
}
|
|
827
|
+
this.onRender();
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
invalidatePrevFrame(): void {
|
|
831
|
+
this.prevFrameContaminated = true;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/** Called by the <AlternateScreen> component on mount/unmount. */
|
|
835
|
+
setAltScreenActive(active: boolean, mouseTracking = false): void {
|
|
836
|
+
if (this.altScreenActive === active) return;
|
|
837
|
+
this.altScreenActive = active;
|
|
838
|
+
this.altScreenMouseTracking = active && mouseTracking;
|
|
839
|
+
if (active) {
|
|
840
|
+
this.resetFramesForAltScreen();
|
|
841
|
+
} else {
|
|
842
|
+
this.repaint();
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
get isAltScreenActive(): boolean {
|
|
846
|
+
return this.altScreenActive;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
reassertTerminalModes = (includeAltScreen = false): void => {
|
|
850
|
+
if (!this.options.stdout.isTTY) return;
|
|
851
|
+
// Don't touch the terminal during an editor handoff — re-enabling kitty
|
|
852
|
+
// keyboard here would undo enterAlternateScreen's disable and nano would
|
|
853
|
+
// start seeing CSI-u sequences again.
|
|
854
|
+
if (this.isPaused) return;
|
|
855
|
+
// Extended keys — re-assert if enabled (App.tsx enables these on
|
|
856
|
+
// allowlisted terminals at raw-mode entry; a terminal reset clears them).
|
|
857
|
+
// Pop-before-push keeps Kitty stack depth at 1 instead of accumulating
|
|
858
|
+
// on each call.
|
|
859
|
+
if (supportsExtendedKeys()) {
|
|
860
|
+
this.options.stdout.write(DISABLE_KITTY_KEYBOARD + ENABLE_KITTY_KEYBOARD + ENABLE_MODIFY_OTHER_KEYS);
|
|
861
|
+
}
|
|
862
|
+
if (!this.altScreenActive) return;
|
|
863
|
+
// Mouse tracking — idempotent, safe to re-assert on every stdin gap.
|
|
864
|
+
if (this.altScreenMouseTracking) {
|
|
865
|
+
this.options.stdout.write(ENABLE_MOUSE_TRACKING);
|
|
866
|
+
}
|
|
867
|
+
// Alt-screen re-entry — destructive (ERASE_SCREEN). Only for callers that
|
|
868
|
+
// have a strong signal the terminal actually dropped mode 1049.
|
|
869
|
+
if (includeAltScreen) {
|
|
870
|
+
this.reenterAltScreen();
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
/** Mark this instance as unmounted so future unmount() calls early-return. */
|
|
875
|
+
detachForShutdown(): void {
|
|
876
|
+
this.isUnmounted = true;
|
|
877
|
+
// Cancel any pending throttled render so it doesn't fire between
|
|
878
|
+
// cleanupTerminalModes() and process.exit() and write to main screen.
|
|
879
|
+
this.scheduleRender.cancel?.();
|
|
880
|
+
// Restore stdin from raw mode. unmount() used to do this via React
|
|
881
|
+
// unmount (App.componentWillUnmount → handleSetRawMode(false)) but we're
|
|
882
|
+
// short-circuiting that path. Must use this.options.stdin — NOT
|
|
883
|
+
// process.stdin — because getStdinOverride() may have opened /dev/tty
|
|
884
|
+
// when stdin is piped.
|
|
885
|
+
const stdin = this.options.stdin as NodeJS.ReadStream & {
|
|
886
|
+
isRaw?: boolean;
|
|
887
|
+
setRawMode?: (m: boolean) => void;
|
|
888
|
+
};
|
|
889
|
+
this.drainStdin();
|
|
890
|
+
if (stdin.isTTY && stdin.isRaw && stdin.setRawMode) {
|
|
891
|
+
stdin.setRawMode(false);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/** @see drainStdin */
|
|
896
|
+
drainStdin(): void {
|
|
897
|
+
drainStdin(this.options.stdin);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
private reenterAltScreen(): void {
|
|
901
|
+
this.options.stdout.write(ENTER_ALT_SCREEN + ERASE_SCREEN + CURSOR_HOME + (this.altScreenMouseTracking ? ENABLE_MOUSE_TRACKING : ''));
|
|
902
|
+
this.resetFramesForAltScreen();
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
private resetFramesForAltScreen(): void {
|
|
906
|
+
const rows = this.terminalRows;
|
|
907
|
+
const cols = this.terminalColumns;
|
|
908
|
+
const blank = (): Frame => ({
|
|
909
|
+
screen: createScreen(cols, rows, this.stylePool, this.charPool, this.hyperlinkPool),
|
|
910
|
+
viewport: {
|
|
911
|
+
width: cols,
|
|
912
|
+
height: rows + 1
|
|
913
|
+
},
|
|
914
|
+
cursor: {
|
|
915
|
+
x: 0,
|
|
916
|
+
y: 0,
|
|
917
|
+
visible: true
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
this.frontFrame = blank();
|
|
921
|
+
this.backFrame = blank();
|
|
922
|
+
this.log.reset();
|
|
923
|
+
// Defense-in-depth: alt-screen skips the cursor preamble anyway (CSI H
|
|
924
|
+
// resets), but a stale displayCursor would be misleading if we later
|
|
925
|
+
// exit to main-screen without an intervening render.
|
|
926
|
+
this.displayCursor = null;
|
|
927
|
+
// Fresh frontFrame is blank rows×cols — blitting from it would copy
|
|
928
|
+
// blanks over content. Next alt-screen frame must full-render.
|
|
929
|
+
this.prevFrameContaminated = true;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
copySelectionNoClear(): string {
|
|
933
|
+
if (!hasSelection(this.selection)) return '';
|
|
934
|
+
const text = getSelectedText(this.selection, this.frontFrame.screen);
|
|
935
|
+
if (text) {
|
|
936
|
+
// Raw OSC 52, or DCS-passthrough-wrapped OSC 52 inside tmux (tmux
|
|
937
|
+
// drops it silently unless allow-passthrough is on — no regression).
|
|
938
|
+
void setClipboard(text).then(raw => {
|
|
939
|
+
if (raw) this.options.stdout.write(raw);
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
return text;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
copySelection(): string {
|
|
946
|
+
if (!hasSelection(this.selection)) return '';
|
|
947
|
+
const text = this.copySelectionNoClear();
|
|
948
|
+
clearSelection(this.selection);
|
|
949
|
+
this.notifySelectionChange();
|
|
950
|
+
return text;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
/** Clear the current text selection without copying. */
|
|
954
|
+
clearTextSelection(): void {
|
|
955
|
+
if (!hasSelection(this.selection)) return;
|
|
956
|
+
clearSelection(this.selection);
|
|
957
|
+
this.notifySelectionChange();
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/** Set the search highlight query. */
|
|
961
|
+
setSearchHighlight(query: string): void {
|
|
962
|
+
if (this.searchHighlightQuery === query) return;
|
|
963
|
+
this.searchHighlightQuery = query;
|
|
964
|
+
this.scheduleRender();
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
scanElementSubtree(el: dom.DOMElement): MatchPosition[] {
|
|
968
|
+
if (!this.searchHighlightQuery || !el.yogaNode) return [];
|
|
969
|
+
const width = Math.ceil(el.yogaNode.getComputedWidth());
|
|
970
|
+
const height = Math.ceil(el.yogaNode.getComputedHeight());
|
|
971
|
+
if (width <= 0 || height <= 0) return [];
|
|
972
|
+
// renderNodeToOutput adds el's OWN computedLeft/Top to offsetX/Y.
|
|
973
|
+
// Passing -elLeft/-elTop nets to 0 → paints at (0,0) in our buffer.
|
|
974
|
+
const elLeft = el.yogaNode.getComputedLeft();
|
|
975
|
+
const elTop = el.yogaNode.getComputedTop();
|
|
976
|
+
const screen = createScreen(width, height, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
977
|
+
const output = new Output({
|
|
978
|
+
width,
|
|
979
|
+
height,
|
|
980
|
+
stylePool: this.stylePool,
|
|
981
|
+
screen
|
|
982
|
+
});
|
|
983
|
+
renderNodeToOutput(el, output, {
|
|
984
|
+
offsetX: -elLeft,
|
|
985
|
+
offsetY: -elTop,
|
|
986
|
+
prevScreen: undefined
|
|
987
|
+
});
|
|
988
|
+
const rendered = output.get();
|
|
989
|
+
// renderNodeToOutput wrote our offset positions to nodeCache —
|
|
990
|
+
// corrupts the main render (it'd blit from wrong coords). Mark the
|
|
991
|
+
// subtree dirty so the next main render repaints + re-caches
|
|
992
|
+
// correctly. One extra paint of this message, but correct > fast.
|
|
993
|
+
dom.markDirty(el);
|
|
994
|
+
const positions = scanPositions(rendered, this.searchHighlightQuery);
|
|
995
|
+
logForDebugging(`scanElementSubtree: q='${this.searchHighlightQuery}' ` + `el=${width}x${height}@(${elLeft},${elTop}) n=${positions.length} ` + `[${positions.slice(0, 10).map(p => `${p.row}:${p.col}`).join(',')}` + `${positions.length > 10 ? ',…' : ''}]`);
|
|
996
|
+
return positions;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/** Set the position-based highlight state. */
|
|
1000
|
+
setSearchPositions(state: {
|
|
1001
|
+
positions: MatchPosition[];
|
|
1002
|
+
rowOffset: number;
|
|
1003
|
+
currentIdx: number;
|
|
1004
|
+
} | null): void {
|
|
1005
|
+
this.searchPositions = state;
|
|
1006
|
+
this.scheduleRender();
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
/** Set the selection highlight background color. */
|
|
1010
|
+
setSelectionBgColor(color: string): void {
|
|
1011
|
+
// Wrap a NUL marker, then split on it to extract the open/close SGR.
|
|
1012
|
+
// colorize returns the input unchanged if the color string is bad —
|
|
1013
|
+
// no NUL-split then, so fall through to null (inverse fallback).
|
|
1014
|
+
const wrapped = colorize('\0', color, 'background');
|
|
1015
|
+
const nul = wrapped.indexOf('\0');
|
|
1016
|
+
if (nul <= 0 || nul === wrapped.length - 1) {
|
|
1017
|
+
this.stylePool.setSelectionBg(null);
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
this.stylePool.setSelectionBg({
|
|
1021
|
+
type: 'ansi',
|
|
1022
|
+
code: wrapped.slice(0, nul),
|
|
1023
|
+
endCode: wrapped.slice(nul + 1) // always \x1b[49m for bg
|
|
1024
|
+
});
|
|
1025
|
+
// No scheduleRender: this is called from a React effect that already
|
|
1026
|
+
// runs inside the render cycle, and the bg only matters once a
|
|
1027
|
+
// selection exists (which itself triggers a full-damage frame).
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
captureScrolledRows(firstRow: number, lastRow: number, side: 'above' | 'below'): void {
|
|
1031
|
+
captureScrolledRows(this.selection, this.frontFrame.screen, firstRow, lastRow, side);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/** Shift anchor AND focus by dRow, clamped to [minRow, maxRow]. */
|
|
1035
|
+
shiftSelectionForScroll(dRow: number, minRow: number, maxRow: number): void {
|
|
1036
|
+
const hadSel = hasSelection(this.selection);
|
|
1037
|
+
shiftSelection(this.selection, dRow, minRow, maxRow, this.frontFrame.screen.width);
|
|
1038
|
+
// shiftSelection clears when both endpoints overshoot the same edge
|
|
1039
|
+
// (Home/g/End/G page-jump past the selection). Notify subscribers so
|
|
1040
|
+
// useHasSelection updates. Safe to call notifySelectionChange here —
|
|
1041
|
+
// this runs from keyboard handlers, not inside onRender().
|
|
1042
|
+
if (hadSel && !hasSelection(this.selection)) {
|
|
1043
|
+
this.notifySelectionChange();
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
/** Keyboard selection extension (shift+arrow/home/end). */
|
|
1048
|
+
moveSelectionFocus(move: FocusMove): void {
|
|
1049
|
+
if (!this.altScreenActive) return;
|
|
1050
|
+
const {
|
|
1051
|
+
focus
|
|
1052
|
+
} = this.selection;
|
|
1053
|
+
if (!focus) return;
|
|
1054
|
+
const {
|
|
1055
|
+
width,
|
|
1056
|
+
height
|
|
1057
|
+
} = this.frontFrame.screen;
|
|
1058
|
+
const maxCol = width - 1;
|
|
1059
|
+
const maxRow = height - 1;
|
|
1060
|
+
let {
|
|
1061
|
+
col,
|
|
1062
|
+
row
|
|
1063
|
+
} = focus;
|
|
1064
|
+
switch (move) {
|
|
1065
|
+
case 'left':
|
|
1066
|
+
if (col > 0) col--;else if (row > 0) {
|
|
1067
|
+
col = maxCol;
|
|
1068
|
+
row--;
|
|
1069
|
+
}
|
|
1070
|
+
break;
|
|
1071
|
+
case 'right':
|
|
1072
|
+
if (col < maxCol) col++;else if (row < maxRow) {
|
|
1073
|
+
col = 0;
|
|
1074
|
+
row++;
|
|
1075
|
+
}
|
|
1076
|
+
break;
|
|
1077
|
+
case 'up':
|
|
1078
|
+
if (row > 0) row--;
|
|
1079
|
+
break;
|
|
1080
|
+
case 'down':
|
|
1081
|
+
if (row < maxRow) row++;
|
|
1082
|
+
break;
|
|
1083
|
+
case 'lineStart':
|
|
1084
|
+
col = 0;
|
|
1085
|
+
break;
|
|
1086
|
+
case 'lineEnd':
|
|
1087
|
+
col = maxCol;
|
|
1088
|
+
break;
|
|
1089
|
+
}
|
|
1090
|
+
if (col === focus.col && row === focus.row) return;
|
|
1091
|
+
moveFocus(this.selection, col, row);
|
|
1092
|
+
this.notifySelectionChange();
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
/** Whether there is an active text selection. */
|
|
1096
|
+
hasTextSelection(): boolean {
|
|
1097
|
+
return hasSelection(this.selection);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/** Subscribe to selection state changes. */
|
|
1101
|
+
subscribeToSelectionChange(cb: () => void): () => void {
|
|
1102
|
+
this.selectionListeners.add(cb);
|
|
1103
|
+
return () => this.selectionListeners.delete(cb);
|
|
1104
|
+
}
|
|
1105
|
+
private notifySelectionChange(): void {
|
|
1106
|
+
this.onRender();
|
|
1107
|
+
for (const cb of this.selectionListeners) cb();
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
dispatchClick(col: number, row: number): boolean {
|
|
1111
|
+
if (!this.altScreenActive) return false;
|
|
1112
|
+
const blank = isEmptyCellAt(this.frontFrame.screen, col, row);
|
|
1113
|
+
return dispatchClick(this.rootNode, col, row, blank);
|
|
1114
|
+
}
|
|
1115
|
+
dispatchHover(col: number, row: number): void {
|
|
1116
|
+
if (!this.altScreenActive) return;
|
|
1117
|
+
dispatchHover(this.rootNode, col, row, this.hoveredNodes);
|
|
1118
|
+
}
|
|
1119
|
+
dispatchKeyboardEvent(parsedKey: ParsedKey): void {
|
|
1120
|
+
const target = this.focusManager.activeElement ?? this.rootNode;
|
|
1121
|
+
const event = new KeyboardEvent(parsedKey);
|
|
1122
|
+
dispatcher.dispatchDiscrete(target, event);
|
|
1123
|
+
|
|
1124
|
+
// Tab cycling is the default action — only fires if no handler
|
|
1125
|
+
// called preventDefault(). Mirrors browser behavior.
|
|
1126
|
+
if (!event.defaultPrevented && parsedKey.name === 'tab' && !parsedKey.ctrl && !parsedKey.meta) {
|
|
1127
|
+
if (parsedKey.shift) {
|
|
1128
|
+
this.focusManager.focusPrevious(this.rootNode);
|
|
1129
|
+
} else {
|
|
1130
|
+
this.focusManager.focusNext(this.rootNode);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
/** Look up the URL at (col, row) in the current front frame. */
|
|
1135
|
+
getHyperlinkAt(col: number, row: number): string | undefined {
|
|
1136
|
+
if (!this.altScreenActive) return undefined;
|
|
1137
|
+
const screen = this.frontFrame.screen;
|
|
1138
|
+
const cell = cellAt(screen, col, row);
|
|
1139
|
+
let url = cell?.hyperlink;
|
|
1140
|
+
// SpacerTail cells (right half of wide/CJK/emoji chars) store the
|
|
1141
|
+
// hyperlink on the head cell at col-1.
|
|
1142
|
+
if (!url && cell?.width === CellWidth.SpacerTail && col > 0) {
|
|
1143
|
+
url = cellAt(screen, col - 1, row)?.hyperlink;
|
|
1144
|
+
}
|
|
1145
|
+
return url ?? findPlainTextUrlAt(screen, col, row);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
onHyperlinkClick: ((url: string) => void) | undefined;
|
|
1149
|
+
|
|
1150
|
+
/** Stable prototype wrapper for onHyperlinkClick. */
|
|
1151
|
+
openHyperlink(url: string): void {
|
|
1152
|
+
this.onHyperlinkClick?.(url);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
handleMultiClick(col: number, row: number, count: 2 | 3): void {
|
|
1156
|
+
if (!this.altScreenActive) return;
|
|
1157
|
+
const screen = this.frontFrame.screen;
|
|
1158
|
+
// selectWordAt/selectLineAt no-op on noSelect/out-of-bounds. Seed with
|
|
1159
|
+
// a char-mode selection so the press still starts a drag even if the
|
|
1160
|
+
// word/line scan finds nothing selectable.
|
|
1161
|
+
startSelection(this.selection, col, row);
|
|
1162
|
+
if (count === 2) selectWordAt(this.selection, screen, col, row);else selectLineAt(this.selection, screen, row);
|
|
1163
|
+
// Ensure hasSelection is true so release doesn't re-dispatch onClickAt.
|
|
1164
|
+
// selectWordAt no-ops on noSelect; selectLineAt no-ops out-of-bounds.
|
|
1165
|
+
if (!this.selection.focus) this.selection.focus = this.selection.anchor;
|
|
1166
|
+
this.notifySelectionChange();
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
/** Handle a drag-motion at (col, row). */
|
|
1170
|
+
handleSelectionDrag(col: number, row: number): void {
|
|
1171
|
+
if (!this.altScreenActive) return;
|
|
1172
|
+
const sel = this.selection;
|
|
1173
|
+
if (sel.anchorSpan) {
|
|
1174
|
+
extendSelection(sel, this.frontFrame.screen, col, row);
|
|
1175
|
+
} else {
|
|
1176
|
+
updateSelection(sel, col, row);
|
|
1177
|
+
}
|
|
1178
|
+
this.notifySelectionChange();
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// Methods to properly suspend stdin for external editor usage
|
|
1182
|
+
// This is needed to prevent Ink from swallowing keystrokes when an external editor is active
|
|
1183
|
+
private stdinListeners: Array<{
|
|
1184
|
+
event: string;
|
|
1185
|
+
listener: (...args: unknown[]) => void;
|
|
1186
|
+
}> = [];
|
|
1187
|
+
private wasRawMode = false;
|
|
1188
|
+
suspendStdin(): void {
|
|
1189
|
+
const stdin = this.options.stdin;
|
|
1190
|
+
if (!stdin.isTTY) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
// Store and remove all 'readable' event listeners temporarily
|
|
1195
|
+
// This prevents Ink from consuming stdin while the editor is active
|
|
1196
|
+
const readableListeners = stdin.listeners('readable');
|
|
1197
|
+
logForDebugging(`[stdin] suspendStdin: removing ${readableListeners.length} readable listener(s), wasRawMode=${(stdin as NodeJS.ReadStream & {
|
|
1198
|
+
isRaw?: boolean;
|
|
1199
|
+
}).isRaw ?? false}`);
|
|
1200
|
+
readableListeners.forEach(listener => {
|
|
1201
|
+
this.stdinListeners.push({
|
|
1202
|
+
event: 'readable',
|
|
1203
|
+
listener: listener as (...args: unknown[]) => void
|
|
1204
|
+
});
|
|
1205
|
+
stdin.removeListener('readable', listener as (...args: unknown[]) => void);
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
// If raw mode is enabled, disable it temporarily
|
|
1209
|
+
const stdinWithRaw = stdin as NodeJS.ReadStream & {
|
|
1210
|
+
isRaw?: boolean;
|
|
1211
|
+
setRawMode?: (mode: boolean) => void;
|
|
1212
|
+
};
|
|
1213
|
+
if (stdinWithRaw.isRaw && stdinWithRaw.setRawMode) {
|
|
1214
|
+
stdinWithRaw.setRawMode(false);
|
|
1215
|
+
this.wasRawMode = true;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
resumeStdin(): void {
|
|
1219
|
+
const stdin = this.options.stdin;
|
|
1220
|
+
if (!stdin.isTTY) {
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// Re-attach all the stored listeners
|
|
1225
|
+
if (this.stdinListeners.length === 0 && !this.wasRawMode) {
|
|
1226
|
+
logForDebugging('[stdin] resumeStdin: called with no stored listeners and wasRawMode=false (possible desync)', {
|
|
1227
|
+
level: 'warn'
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
logForDebugging(`[stdin] resumeStdin: re-attaching ${this.stdinListeners.length} listener(s), wasRawMode=${this.wasRawMode}`);
|
|
1231
|
+
this.stdinListeners.forEach(({
|
|
1232
|
+
event,
|
|
1233
|
+
listener
|
|
1234
|
+
}) => {
|
|
1235
|
+
stdin.addListener(event, listener);
|
|
1236
|
+
});
|
|
1237
|
+
this.stdinListeners = [];
|
|
1238
|
+
|
|
1239
|
+
// Re-enable raw mode if it was enabled before
|
|
1240
|
+
if (this.wasRawMode) {
|
|
1241
|
+
const stdinWithRaw = stdin as NodeJS.ReadStream & {
|
|
1242
|
+
setRawMode?: (mode: boolean) => void;
|
|
1243
|
+
};
|
|
1244
|
+
if (stdinWithRaw.setRawMode) {
|
|
1245
|
+
stdinWithRaw.setRawMode(true);
|
|
1246
|
+
}
|
|
1247
|
+
this.wasRawMode = false;
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// Stable identity for TerminalWriteContext. An inline arrow here would
|
|
1252
|
+
// change on every render() call (initial mount + each resize), which
|
|
1253
|
+
// cascades through useContext → <AlternateScreen>'s useLayoutEffect dep
|
|
1254
|
+
// array → spurious exit+re-enter of the alt screen on every SIGWINCH.
|
|
1255
|
+
private writeRaw(data: string): void {
|
|
1256
|
+
this.options.stdout.write(data);
|
|
1257
|
+
}
|
|
1258
|
+
private setCursorDeclaration: CursorDeclarationSetter = (decl, clearIfNode) => {
|
|
1259
|
+
if (decl === null && clearIfNode !== undefined && this.cursorDeclaration?.node !== clearIfNode) {
|
|
1260
|
+
return;
|
|
1261
|
+
}
|
|
1262
|
+
this.cursorDeclaration = decl;
|
|
1263
|
+
};
|
|
1264
|
+
render(node: ReactNode): void {
|
|
1265
|
+
this.currentNode = node;
|
|
1266
|
+
const tree = <App stdin={this.options.stdin} stdout={this.options.stdout} stderr={this.options.stderr} exitOnCtrlC={this.options.exitOnCtrlC} onExit={this.unmount} terminalColumns={this.terminalColumns} terminalRows={this.terminalRows} selection={this.selection} onSelectionChange={this.notifySelectionChange} onClickAt={this.dispatchClick} onHoverAt={this.dispatchHover} getHyperlinkAt={this.getHyperlinkAt} onOpenHyperlink={this.openHyperlink} onMultiClick={this.handleMultiClick} onSelectionDrag={this.handleSelectionDrag} onStdinResume={this.reassertTerminalModes} onCursorDeclaration={this.setCursorDeclaration} dispatchKeyboardEvent={this.dispatchKeyboardEvent}>
|
|
1267
|
+
<TerminalWriteProvider value={this.writeRaw}>
|
|
1268
|
+
{node}
|
|
1269
|
+
</TerminalWriteProvider>
|
|
1270
|
+
</App>;
|
|
1271
|
+
|
|
1272
|
+
reconciler.updateContainerSync(tree, this.container, null, noop);
|
|
1273
|
+
reconciler.flushSyncWork();
|
|
1274
|
+
}
|
|
1275
|
+
unmount(error?: Error | number | null): void {
|
|
1276
|
+
if (this.isUnmounted) {
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
this.onRender();
|
|
1280
|
+
this.unsubscribeExit();
|
|
1281
|
+
if (typeof this.restoreConsole === 'function') {
|
|
1282
|
+
this.restoreConsole();
|
|
1283
|
+
}
|
|
1284
|
+
this.restoreStderr?.();
|
|
1285
|
+
this.unsubscribeTTYHandlers?.();
|
|
1286
|
+
|
|
1287
|
+
// Non-TTY environments don't handle erasing ansi escapes well, so it's better to
|
|
1288
|
+
// only render last frame of non-static output
|
|
1289
|
+
const diff = this.log.renderPreviousOutput_DEPRECATED(this.frontFrame);
|
|
1290
|
+
writeDiffToTerminal(this.terminal, optimize(diff));
|
|
1291
|
+
|
|
1292
|
+
// Clean up terminal modes synchronously before process exit.
|
|
1293
|
+
// React's componentWillUnmount won't run in time when process.exit() is called,
|
|
1294
|
+
// so we must reset terminal modes here to prevent escape sequence leakage.
|
|
1295
|
+
// Use writeSync to stdout (fd 1) to ensure writes complete before exit.
|
|
1296
|
+
// We unconditionally send all disable sequences because terminal detection
|
|
1297
|
+
// may not work correctly (e.g., in tmux, screen) and these are no-ops on
|
|
1298
|
+
// terminals that don't support them.
|
|
1299
|
+
/* eslint-disable custom-rules/no-sync-fs -- process exiting; async writes would be dropped */
|
|
1300
|
+
if (this.options.stdout.isTTY) {
|
|
1301
|
+
if (this.altScreenActive) {
|
|
1302
|
+
// <AlternateScreen>'s unmount effect won't run during signal-exit.
|
|
1303
|
+
// Exit alt screen FIRST so other cleanup sequences go to the main screen.
|
|
1304
|
+
writeSync(1, EXIT_ALT_SCREEN);
|
|
1305
|
+
}
|
|
1306
|
+
// Disable mouse tracking — unconditional because altScreenActive can be
|
|
1307
|
+
// stale if AlternateScreen's unmount (which flips the flag) raced a
|
|
1308
|
+
// blocked event loop + SIGINT. No-op if tracking was never enabled.
|
|
1309
|
+
writeSync(1, DISABLE_MOUSE_TRACKING);
|
|
1310
|
+
// Drain stdin so in-flight mouse events don't leak to the shell
|
|
1311
|
+
this.drainStdin();
|
|
1312
|
+
// Disable extended key reporting (both kitty and modifyOtherKeys)
|
|
1313
|
+
writeSync(1, DISABLE_MODIFY_OTHER_KEYS);
|
|
1314
|
+
writeSync(1, DISABLE_KITTY_KEYBOARD);
|
|
1315
|
+
// Disable focus events (DECSET 1004)
|
|
1316
|
+
writeSync(1, DFE);
|
|
1317
|
+
// Disable bracketed paste mode
|
|
1318
|
+
writeSync(1, DBP);
|
|
1319
|
+
// Show cursor
|
|
1320
|
+
writeSync(1, SHOW_CURSOR);
|
|
1321
|
+
// Clear iTerm2 progress bar
|
|
1322
|
+
writeSync(1, CLEAR_ITERM2_PROGRESS);
|
|
1323
|
+
// Clear tab status (OSC 21337) so a stale dot doesn't linger
|
|
1324
|
+
if (supportsTabStatus()) writeSync(1, wrapForMultiplexer(CLEAR_TAB_STATUS));
|
|
1325
|
+
}
|
|
1326
|
+
/* eslint-enable custom-rules/no-sync-fs */
|
|
1327
|
+
|
|
1328
|
+
this.isUnmounted = true;
|
|
1329
|
+
|
|
1330
|
+
// Cancel any pending throttled renders to prevent accessing freed Yoga nodes
|
|
1331
|
+
this.scheduleRender.cancel?.();
|
|
1332
|
+
if (this.drainTimer !== null) {
|
|
1333
|
+
clearTimeout(this.drainTimer);
|
|
1334
|
+
this.drainTimer = null;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
reconciler.updateContainerSync(null, this.container, null, noop);
|
|
1338
|
+
reconciler.flushSyncWork();
|
|
1339
|
+
instances.delete(this.options.stdout);
|
|
1340
|
+
|
|
1341
|
+
// Free the root yoga node, then clear its reference. Children are already
|
|
1342
|
+
// freed by the reconciler's removeChildFromContainer; using .free() (not
|
|
1343
|
+
// .freeRecursive()) avoids double-freeing them.
|
|
1344
|
+
this.rootNode.yogaNode?.free();
|
|
1345
|
+
this.rootNode.yogaNode = undefined;
|
|
1346
|
+
if (error instanceof Error) {
|
|
1347
|
+
this.rejectExitPromise(error);
|
|
1348
|
+
} else {
|
|
1349
|
+
this.resolveExitPromise();
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
async waitUntilExit(): Promise<void> {
|
|
1353
|
+
this.exitPromise ||= new Promise((resolve, reject) => {
|
|
1354
|
+
this.resolveExitPromise = resolve;
|
|
1355
|
+
this.rejectExitPromise = reject;
|
|
1356
|
+
});
|
|
1357
|
+
return this.exitPromise;
|
|
1358
|
+
}
|
|
1359
|
+
resetLineCount(): void {
|
|
1360
|
+
if (this.options.stdout.isTTY) {
|
|
1361
|
+
// Swap so old front becomes back (for screen reuse), then reset front
|
|
1362
|
+
this.backFrame = this.frontFrame;
|
|
1363
|
+
this.frontFrame = emptyFrame(this.frontFrame.viewport.height, this.frontFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
1364
|
+
this.log.reset();
|
|
1365
|
+
// frontFrame is reset, so frame.cursor on the next render is (0,0).
|
|
1366
|
+
// Clear displayCursor so the preamble doesn't compute a stale delta.
|
|
1367
|
+
this.displayCursor = null;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
resetPools(): void {
|
|
1372
|
+
this.charPool = new CharPool();
|
|
1373
|
+
this.hyperlinkPool = new HyperlinkPool();
|
|
1374
|
+
migrateScreenPools(this.frontFrame.screen, this.charPool, this.hyperlinkPool);
|
|
1375
|
+
// Back frame's data is zeroed by resetScreen before reads, but its pool
|
|
1376
|
+
// references are used by the renderer to intern new characters. Point
|
|
1377
|
+
// them at the new pools so the next frame's IDs are comparable.
|
|
1378
|
+
this.backFrame.screen.charPool = this.charPool;
|
|
1379
|
+
this.backFrame.screen.hyperlinkPool = this.hyperlinkPool;
|
|
1380
|
+
}
|
|
1381
|
+
patchConsole(): () => void {
|
|
1382
|
+
// biome-ignore lint/suspicious/noConsole: intentionally patching global console
|
|
1383
|
+
const con = console;
|
|
1384
|
+
const originals: Partial<Record<keyof Console, Console[keyof Console]>> = {};
|
|
1385
|
+
const toDebug = (...args: unknown[]) => logForDebugging(`console.log: ${format(...args)}`);
|
|
1386
|
+
const toError = (...args: unknown[]) => logError(new Error(`console.error: ${format(...args)}`));
|
|
1387
|
+
for (const m of CONSOLE_STDOUT_METHODS) {
|
|
1388
|
+
originals[m] = con[m];
|
|
1389
|
+
con[m] = toDebug;
|
|
1390
|
+
}
|
|
1391
|
+
for (const m of CONSOLE_STDERR_METHODS) {
|
|
1392
|
+
originals[m] = con[m];
|
|
1393
|
+
con[m] = toError;
|
|
1394
|
+
}
|
|
1395
|
+
originals.assert = con.assert;
|
|
1396
|
+
con.assert = (condition: unknown, ...args: unknown[]) => {
|
|
1397
|
+
if (!condition) toError(...args);
|
|
1398
|
+
};
|
|
1399
|
+
return () => Object.assign(con, originals);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
private patchStderr(): () => void {
|
|
1403
|
+
const stderr = process.stderr;
|
|
1404
|
+
const originalWrite = stderr.write;
|
|
1405
|
+
let reentered = false;
|
|
1406
|
+
const intercept = (chunk: Uint8Array | string, encodingOrCb?: BufferEncoding | ((err?: Error) => void), cb?: (err?: Error) => void): boolean => {
|
|
1407
|
+
const callback = typeof encodingOrCb === 'function' ? encodingOrCb : cb;
|
|
1408
|
+
// Reentrancy guard: logForDebugging → writeToStderr → here. Pass
|
|
1409
|
+
// through to the original so --debug-to-stderr still works and we
|
|
1410
|
+
// don't stack-overflow.
|
|
1411
|
+
if (reentered) {
|
|
1412
|
+
const encoding = typeof encodingOrCb === 'string' ? encodingOrCb : undefined;
|
|
1413
|
+
return originalWrite.call(stderr, chunk, encoding, callback);
|
|
1414
|
+
}
|
|
1415
|
+
reentered = true;
|
|
1416
|
+
try {
|
|
1417
|
+
const text = typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
|
|
1418
|
+
logForDebugging(`[stderr] ${text}`, {
|
|
1419
|
+
level: 'warn'
|
|
1420
|
+
});
|
|
1421
|
+
if (this.altScreenActive && !this.isUnmounted && !this.isPaused) {
|
|
1422
|
+
this.prevFrameContaminated = true;
|
|
1423
|
+
this.scheduleRender();
|
|
1424
|
+
}
|
|
1425
|
+
} finally {
|
|
1426
|
+
reentered = false;
|
|
1427
|
+
callback?.();
|
|
1428
|
+
}
|
|
1429
|
+
return true;
|
|
1430
|
+
};
|
|
1431
|
+
stderr.write = intercept;
|
|
1432
|
+
return () => {
|
|
1433
|
+
if (stderr.write === intercept) {
|
|
1434
|
+
stderr.write = originalWrite;
|
|
1435
|
+
}
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
/* eslint-disable custom-rules/no-sync-fs -- must be sync; called from signal handler / unmount */
|
|
1441
|
+
export function drainStdin(stdin: NodeJS.ReadStream = process.stdin): void {
|
|
1442
|
+
if (!stdin.isTTY) return;
|
|
1443
|
+
// Drain Node's stream buffer (bytes libuv already pulled in). read()
|
|
1444
|
+
// returns null when empty — never blocks.
|
|
1445
|
+
try {
|
|
1446
|
+
while (stdin.read() !== null) {
|
|
1447
|
+
/* discard */
|
|
1448
|
+
}
|
|
1449
|
+
} catch {
|
|
1450
|
+
/* stream may be destroyed */
|
|
1451
|
+
}
|
|
1452
|
+
// No /dev/tty on Windows; CONIN$ doesn't support O_NONBLOCK semantics.
|
|
1453
|
+
// Windows Terminal also doesn't buffer mouse reports the same way.
|
|
1454
|
+
if (process.platform === 'win32') return;
|
|
1455
|
+
// termios is per-device: flip stdin to raw so canonical-mode line
|
|
1456
|
+
// buffering doesn't hide partial input from the non-blocking read.
|
|
1457
|
+
// Restored in the finally block.
|
|
1458
|
+
const tty = stdin as NodeJS.ReadStream & {
|
|
1459
|
+
isRaw?: boolean;
|
|
1460
|
+
setRawMode?: (raw: boolean) => void;
|
|
1461
|
+
};
|
|
1462
|
+
const wasRaw = tty.isRaw === true;
|
|
1463
|
+
// Drain the kernel TTY buffer via a fresh O_NONBLOCK fd. Bounded at 64
|
|
1464
|
+
// reads (64KB) — a real mouse burst is a few hundred bytes; the cap
|
|
1465
|
+
// guards against a terminal that ignores O_NONBLOCK.
|
|
1466
|
+
let fd = -1;
|
|
1467
|
+
try {
|
|
1468
|
+
// setRawMode inside try: on revoked TTY (SIGHUP/SSH disconnect) the
|
|
1469
|
+
// ioctl throws EBADF — same recovery path as openSync/readSync below.
|
|
1470
|
+
if (!wasRaw) tty.setRawMode?.(true);
|
|
1471
|
+
fd = openSync('/dev/tty', fsConstants.O_RDONLY | fsConstants.O_NONBLOCK);
|
|
1472
|
+
const buf = Buffer.alloc(1024);
|
|
1473
|
+
for (let i = 0; i < 64; i++) {
|
|
1474
|
+
if (readSync(fd, buf, 0, buf.length, null) <= 0) break;
|
|
1475
|
+
}
|
|
1476
|
+
} catch {
|
|
1477
|
+
// EAGAIN (buffer empty — expected), ENXIO/ENOENT (no controlling tty),
|
|
1478
|
+
// EBADF/EIO (TTY revoked — SIGHUP, SSH disconnect)
|
|
1479
|
+
} finally {
|
|
1480
|
+
if (fd >= 0) {
|
|
1481
|
+
try {
|
|
1482
|
+
closeSync(fd);
|
|
1483
|
+
} catch {
|
|
1484
|
+
/* ignore */
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
if (!wasRaw) {
|
|
1488
|
+
try {
|
|
1489
|
+
tty.setRawMode?.(false);
|
|
1490
|
+
} catch {
|
|
1491
|
+
/* TTY may be gone */
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
/* eslint-enable custom-rules/no-sync-fs */
|
|
1497
|
+
|
|
1498
|
+
const CONSOLE_STDOUT_METHODS = ['log', 'info', 'debug', 'dir', 'dirxml', 'count', 'countReset', 'group', 'groupCollapsed', 'groupEnd', 'table', 'time', 'timeEnd', 'timeLog'] as const;
|
|
1499
|
+
const CONSOLE_STDERR_METHODS = ['warn', 'error', 'trace'] as const;
|