console-gui-tools
Version:
A simple library to draw option menu, text popup or other widgets and layout on a Node.js console.
8 lines • 449 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/ConsoleGui.ts", "../../src/components/Utils.ts", "../../src/components/PageBuilder.ts", "../../src/components/InPageWidgetBuilder.ts", "../../src/components/Screen.ts", "../../node_modules/chalk/source/vendor/ansi-styles/index.js", "../../node_modules/chalk/source/vendor/supports-color/index.js", "../../node_modules/chalk/source/utilities.js", "../../node_modules/chalk/source/index.js", "../../src/components/widgets/CustomPopup.ts", "../../src/components/widgets/ButtonPopup.ts", "../../src/components/widgets/ConfirmPopup.ts", "../../src/components/widgets/FileSelectorPopup.ts", "../../src/components/widgets/InputPopup.ts", "../../src/components/widgets/OptionPopup.ts", "../../src/components/widgets/Control.ts", "../../src/components/widgets/Box.ts", "../../src/components/widgets/Button.ts", "../../src/components/widgets/ProgressBar.ts", "../../src/components/layout/DoubleLayout.ts", "../../src/components/layout/QuadLayout.ts", "../../src/components/layout/SingleLayout.ts", "../../src/components/layout/LayoutManager.ts", "../../src/components/MouseManager.ts"],
"sourcesContent": ["import { EventEmitter } from \"events\"\nimport readline from \"readline\"\nimport PageBuilder from \"./components/PageBuilder.js\"\nimport InPageWidgetBuilder from \"./components/InPageWidgetBuilder.js\"\nimport Screen from \"./components/Screen.js\"\nimport { CustomPopup, PopupConfig } from \"./components/widgets/CustomPopup.js\"\nimport { ButtonPopup, ButtonPopupConfig } from \"./components/widgets/ButtonPopup.js\"\nimport { ConfirmPopup, ConfirmPopupConfig } from \"./components/widgets/ConfirmPopup.js\"\nimport { FileSelectorPopup, FileSelectorPopupConfig } from \"./components/widgets/FileSelectorPopup.js\"\nimport { InputPopup, InputPopupConfig } from \"./components/widgets/InputPopup.js\"\nimport { OptionPopup, OptionPopupConfig } from \"./components/widgets/OptionPopup.js\"\nimport { Control, ControlConfig } from \"./components/widgets/Control.js\"\nimport { Box, BoxConfig, BoxStyle } from \"./components/widgets/Box.js\"\nimport { Button, ButtonConfig, ButtonKey, ButtonStyle } from \"./components/widgets/Button.js\"\nimport { Progress, ProgressConfig, Orientation, ProgressStyle } from \"./components/widgets/ProgressBar.js\"\nimport LayoutManager, { LayoutOptions } from \"./components/layout/LayoutManager.js\"\nimport { MouseEvent, MouseManager, MouseEventArgs, RelativeMouseEvent } from \"./components/MouseManager.js\"\nimport { PhisicalValues, StyledElement, SimplifiedStyledElement, StyleObject } from \"./components/Utils.js\"\nimport { EOL } from \"node:os\"\n\n\n/**\n * @description This type is used to define the parameters of the KeyListener event (keypress).\n * @typedef {Object} KeyListenerArgs\n * @prop {string} name - The name of the key pressed.\n * @prop {boolean} ctrl - If the ctrl key is pressed.\n * @prop {boolean} shift - If the shift key is pressed.\n * @prop {boolean} alt - If the alt key is pressed.\n * @prop {boolean} meta - If the meta key is pressed.\n * @prop {boolean} sequence - If the sequence of keys is pressed.\n *\n * @export\n * @interface KeyListenerArgs\n */\n// @type definition\nexport interface KeyListenerArgs {\n name: string;\n sequence: string;\n ctrl: boolean;\n alt: boolean;\n shift: boolean;\n meta: boolean;\n code: string;\n}\n\n/**\n * @description This type is used to define the ConsoleGui options.\n * @typedef {Object} ConsoleGuiOptions\n * @prop {string} [title] - The title of the ConsoleGui.\n * @prop {0 | 1 | 2 | 3 | \"popup\"} [logLocation] - The location of the logs.\n * @prop {string} [showLogKey] - The key to show the log.\n * @prop {number} [logPageSize] - The size of the log page.\n * @prop {LayoutOptions} [layoutOptions] - The options of the layout.\n * @prop {boolean} [enableMouse] - If the mouse should be enabled.\n * @prop {boolean} [overrideConsole = true] - If the console.log|warn|error|info should be overridden.\n * @prop {string} [focusKey = \"tab\"] - The key to focus the next widget.\n * \n * @export\n * @interface ConsoleGuiOptions\n */\n// @type definition\nexport interface ConsoleGuiOptions {\n logLocation?: 0 | 1 | 2 | 3 | \"popup\";\n showLogKey?: string;\n logPageSize?: number;\n layoutOptions?: LayoutOptions;\n title?: string;\n enableMouse?: boolean; // enable the mouse support (default: true) - Only for Linux and other Mouse Tracking terminals\n overrideConsole?: boolean; // override the console.log, console.warn, console.error, console.info, console.debug (default: true)\n focusKey?: string; // the key to focus the next widget (default: tab)\n}\n\n/**\n * @class ConsoleManager\n * @extends EventEmitter\n * @description This class is used to manage the console GUI and all the widgets.\n * This is a singleton class, so you can use it like this: const CM = new ConsoleManager()\n * Emits the following events: \n * - \"keypressed\" to propagate the key pressed event to the application\n * - \"layoutratiochanged\" when the layout ratio is changed\n * - \"exit\" when the user wants to exit the application\n * @param {object} options - The options of the ConsoleManager.\n * @example const CM = new ConsoleManager({ logPageSize: 10, layoutBorder: true, changeLayoutKey: 'ctrl+l', title: 'Console Application' })\n */\nclass ConsoleManager extends EventEmitter {\n Terminal: NodeJS.WriteStream & { fd: 1 }\n Input: NodeJS.ReadStream & { fd: 0 }\n static instance: ConsoleManager\n Screen!: Screen\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n popupCollection: { [key: string]: any } = {}\n controlsCollection: { [key: string]: Control } = {}\n eventListenersContainer: { [key: string]: (_str: string, key: KeyListenerArgs) => void } | { [key: string]: (key: MouseEvent) => void } = {}\n logLocation!: 0 | 1 | 2 | 3 | \"popup\"\n logPageSize!: number\n logPageTitle!: string\n pages!: PageBuilder[]\n layoutOptions!: LayoutOptions\n layout!: LayoutManager\n changeLayoutKey!: string\n maxListeners = 128\n private changeLayoutkeys!: string[]\n applicationTitle!: string\n private showLogKey!: string\n stdOut!: PageBuilder\n mouse!: MouseManager\n private parsingMouseFrame = false // used to avoid the mouse event to be triggered multiple times\n private previousFocusedWidgetsId: string[] = []\n private focusKey!: string\n\n public constructor(options: ConsoleGuiOptions | undefined = undefined) {\n super()\n this.Terminal = process.stdout\n this.Input = process.stdin\n this.Input.setMaxListeners(this.maxListeners)\n if (!ConsoleManager.instance) {\n ConsoleManager.instance = this\n\n /** @const {Screen} Screen - The screen instance */\n this.Screen = new Screen(this.Terminal)\n this.Screen.on(\"resize\", () => {\n this.emit(\"resize\")\n })\n this.Screen.on(\"error\", (err) => {\n this.error(err)\n })\n\n this.mouse = new MouseManager(this.Terminal, this.Input)\n this.mouse.setMaxListeners(this.maxListeners)\n this.popupCollection = {}\n this.controlsCollection = {}\n this.eventListenersContainer = {}\n\n /** @const {number | 'popup'} logLocation - Choose where the logs are displayed: number (0,1) - to pot them on one of the two layouts, string (\"popup\") - to put them on a CustomPopup that can be displayed on the window. */\n this.logLocation = 1\n this.logPageTitle = \"LOGS\"\n\n this.layoutOptions = {\n showTitle: true,\n boxed: true,\n boxColor: \"cyan\",\n boxStyle: \"bold\",\n changeFocusKey: \"ctrl+l\",\n type: \"double\",\n direction: \"vertical\",\n }\n \n if (options) {\n if (options.logLocation !== undefined) {\n if (typeof options.logLocation === \"number\") {\n this.logLocation = options.logLocation > 0 ? options.logLocation : 0\n } else {\n if (options.logLocation === \"popup\") {\n this.logLocation = \"popup\"\n this.showLogKey = options.showLogKey || \"o\"\n } else {\n this.logLocation = 1\n }\n }\n }\n if (options.enableMouse) {\n this.mouse.enableMouse()\n }\n if (options.overrideConsole) {\n if (options.overrideConsole === true) {\n this.overrideConsole()\n }\n } else {\n this.overrideConsole()\n }\n if (typeof options.layoutOptions !== \"undefined\") {\n this.setLayoutOptions(options.layoutOptions, false)\n }\n }\n \n this.logPageSize = options && options.logPageSize || 10\n this.applicationTitle = options && options.title || \"\"\n this.focusKey = options && options.focusKey || \"tab\"\n \n /** @const {PageBuilder} stdOut - The logs page */\n this.stdOut = new PageBuilder()\n this.stdOut.setRowsPerPage(this.logPageSize)\n\n this.updateLayout()\n this.addGenericListeners()\n\n // Create a Interface from STDIN so this interface can be close later otherwise the Process hangs\n this.inputInterface = readline.createInterface ({ input: process.stdin, escapeCodeTimeout: 50 })\n // I use readline to manage the keypress event\n readline.emitKeypressEvents(this.Input, this.inputInterface)\n this.Input.setRawMode(true) // With this I only get the key value\n }\n return ConsoleManager.instance\n }\n private inputInterface : readline.Interface | undefined\n\n /**\n * @description This method is used to change the layout options.\n * if update is true, the layout will be updated.\n *\n * @param {LayoutOptions} options\n * @param {boolean} [update=true]\n * @memberof ConsoleManager\n * \n * @example CM.setLayoutOptions({ showTitle: true, boxed: true, boxColor: 'cyan', boxStyle: 'bold', changeFocusKey: 'ctrl+l', type: 'double', direction: 'vertical' })\n * @example CM.setLayoutOptions({ ...CM.getLayoutOptions(), type: \"quad\" })\n */\n public setLayoutOptions(options: LayoutOptions, update = true): void {\n this.layoutOptions = options\n if (update) this.updateLayout()\n }\n\n /** \n * @description This method is used to update the layout\n * @memberof ConsoleManager\n */\n public updateLayout(): void {\n /** @const {string} changeLayoutKey - The key or combination to switch the selected page */\n this.changeLayoutKey = this.layoutOptions.changeFocusKey || \"\"\n this.changeLayoutkeys = this.changeLayoutKey ? this.changeLayoutKey.split(\"+\") : []\n /** @const {Array<PageBuilder>} homePage - The main application */\n switch (this.layoutOptions.type) {\n case \"single\":\n this.pages = [new PageBuilder()]\n break\n case \"double\":\n this.pages = [new PageBuilder(), new PageBuilder()]\n break\n case \"triple\":\n this.pages = [new PageBuilder(), new PageBuilder(), new PageBuilder()]\n break\n case \"quad\":\n this.pages = [new PageBuilder(), new PageBuilder(), new PageBuilder(), new PageBuilder()]\n break\n default:\n this.pages = [new PageBuilder(), new PageBuilder()]\n break\n }\n\n /** @const {LayoutManager} layout - The layout instance */\n this.layout = new LayoutManager(this.pages, this.layoutOptions)\n\n if (this.logLocation === \"popup\") {\n this.setPages(this.pages)\n } else if (typeof this.logLocation === \"number\") {\n this.setPage(this.stdOut, this.logLocation)\n this.pages.forEach((page, index) => {\n if (index !== this.logLocation) {\n this.setPage(page, index)\n }\n })\n this.layout.setTitle(this.logPageTitle, this.logLocation)\n } else {\n this.setPages([...this.pages, this.stdOut])\n this.layout.setTitle(this.applicationTitle, 0)\n this.layout.setTitle(this.logPageTitle, 1)\n }\n }\n\n /**\n * @description This method is used to get the layout options.\n * @returns {LayoutOptions} The layout options.\n * @memberof ConsoleManager\n * @example CM.getLayoutOptions()\n * @example CM.getLayoutOptions().boxed\n */\n public getLayoutOptions(): LayoutOptions {\n return this.layoutOptions\n }\n\n /**\n * @description This method is used to get the log page size.\n * @returns {number} The log page size.\n * @memberof ConsoleManager\n * @example CM.getLogPageSize()\n */\n public getLogPageSize(): number {\n return this.logPageSize\n }\n\n /**\n * @description This method is used to set the log page size.\n * @param {number} size - The new log page size.\n * @returns {void}\n * @example CM.setLogPageSize(10)\n */\n public setLogPageSize(size: number): void {\n this.logPageSize = size\n }\n\n /**\n * @description This method is used to remove focus from other widgets.\n *\n * @param {string} widget\n * @memberof ConsoleManager\n */\n public unfocusOtherWidgets(widget: string): void {\n Object.keys(this.controlsCollection).forEach((key: string) => {\n if (key !== widget) {\n this.controlsCollection[key].unfocus()\n this.previousFocusedWidgetsId.push(key)\n }\n })\n Object.keys(this.popupCollection).forEach((key: string) => {\n if (key !== widget) {\n if (this.popupCollection[key].unfocus) this.popupCollection[key].unfocus()\n this.previousFocusedWidgetsId.push(key)\n }\n })\n }\n\n public restoreFocusInWidgets(): void {\n this.previousFocusedWidgetsId.forEach((key: string) => {\n if (this.controlsCollection[key]) {\n this.controlsCollection[key].focus()\n } else if (this.popupCollection[key]) {\n if (this.popupCollection[key].focus) this.popupCollection[key].focus()\n }\n })\n this.previousFocusedWidgetsId = []\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when no widgets are showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @memberof ConsoleManager\n */\n private addGenericListeners(): void {\n this.Input.addListener(\"keypress\", (_str: string, key: KeyListenerArgs): void => {\n //this.log(`Key pressed: ${JSON.stringify(key)}`)\n const checkResult = this.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n let change = false\n if (this.changeLayoutkeys.length > 1) {\n if (this.changeLayoutkeys[0] == \"ctrl\") {\n if (key.ctrl && key.name === this.changeLayoutkeys[1])\n change = true\n }\n if (this.changeLayoutkeys[0] == \"meta\") {\n if (key.alt && key.name === this.changeLayoutkeys[1])\n change = true\n }\n if (this.changeLayoutkeys[0] == \"shift\") {\n if (key.shift && key.name === this.changeLayoutkeys[1])\n change = true\n }\n } else {\n if (key.name === this.changeLayoutkeys[0])\n change = true\n }\n\n if (this.focusKey && key.name === this.focusKey) {\n // Find current focused widget\n let focusedWidget = \"\"\n Object.keys(this.controlsCollection).forEach((key: string) => {\n if (this.controlsCollection[key].isFocused()) {\n focusedWidget = key\n }\n })\n // If there is a focused widget, unfocus it\n if (focusedWidget !== \"\") {\n this.controlsCollection[focusedWidget].unfocus()\n }\n // Focus the next widget\n let found = false\n Object.keys(this.controlsCollection).forEach((key: string) => {\n if (found) {\n this.controlsCollection[key].focus()\n found = false\n }\n if (key === focusedWidget) {\n found = true\n }\n })\n if (found) {\n this.controlsCollection[Object.keys(this.controlsCollection)[0]].focus()\n }\n }\n\n if (this.showLogKey && key.name === this.showLogKey) {\n this.showLogPopup()\n }\n\n if (change) {\n this.layout.changeLayout()\n this.refresh()\n return\n }\n\n if (key.ctrl && key.name === \"c\") {\n this.inputInterface?.close()\n this.emit(\"exit\")\n } else {\n if (Object.keys(this.popupCollection).length === 0) {\n if (key.name === \"down\") {\n this.layout.pages[this.layout.getSelected()].decreaseScrollIndex()\n this.refresh()\n return\n } else if (key.name === \"up\") {\n this.layout.pages[this.layout.getSelected()].increaseScrollIndex()\n this.refresh()\n return\n }\n if (this.layoutOptions.type !== \"single\") {\n if (key.name === \"left\") {\n this.emit(\"layoutratiochanged\", key)\n this.layout.decreaseRatio(0.01)\n this.refresh()\n return\n } else if (key.name === \"right\") {\n this.emit(\"layoutratiochanged\", key)\n this.layout.increaseRatio(0.01)\n this.refresh()\n return\n }\n }\n this.emit(\"keypressed\", key)\n }\n }\n })\n\n /** @eventlistener this is used to set the focus over the top viewed widget if the mouse is over it */\n this.mouse.addListener(\"mouseevent\", (e: MouseEvent) => {\n if (e.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n // Check if the mouse is over a widget. if there are more widgets, the one on top is selected.\n Object.keys(this.controlsCollection).forEach((key: string) => {\n if (this.controlsCollection[key].absoluteValues.x <= e.data.x && this.controlsCollection[key].absoluteValues.x + this.controlsCollection[key].absoluteValues.width >= e.data.x) {\n if (this.controlsCollection[key].absoluteValues.y <= e.data.y && this.controlsCollection[key].absoluteValues.y + this.controlsCollection[key].absoluteValues.height >= e.data.y) {\n if (!this.controlsCollection[key].isFocused()) {\n this.controlsCollection[key].focus()\n }\n }\n }\n })\n }\n })\n }\n\n /**\n * @description This function is used to set a key listener for a specific widget. The event listener is stored in the eventListenersContainer object.\n * @param {string} id - The id of the widget.\n * @param {function} manageFunction - The function to call when the key is pressed.\n * @memberof ConsoleManager\n * @example CM.setKeyListener('inputPopup', popup.keyListener)\n */\n public setKeyListener(id: string, manageFunction: (_str: string, key: KeyListenerArgs) => void): void {\n if (this.eventListenersContainer[id] !== undefined) {\n this.removeKeyListener(id)\n }\n this.eventListenersContainer[id] = manageFunction\n this.Input.addListener(\"keypress\", this.eventListenersContainer[id])\n }\n\n /**\n * @description This function is used to remove a key listener for a specific widget. The event listener is removed from the eventListenersContainer object.\n * @param {string} id - The id of the widget.\n * @memberof ConsoleManager\n * @example CM.removeKeyListener('inputPopup')\n */\n public removeKeyListener(id: string): void {\n this.Input.removeListener(\"keypress\", this.eventListenersContainer[id])\n delete this.eventListenersContainer[id]\n }\n\n /**\n * @description This function is used to set a mouse listener for a specific widget. The event listener is stored in the eventListenersContainer object.\n * @param {string} id - The id of the widget.\n * @param {function} manageFunction - The function to call when the key is pressed.\n * @memberof ConsoleManager\n * @example CM.setMouseListener('inputPopup', popup.mouseListener)\n */\n public setMouseListener(id: string, manageFunction: (key: MouseEvent) => void): void {\n if (this.eventListenersContainer[id] !== undefined) {\n this.removeMouseListener(id)\n }\n this.eventListenersContainer[id] = manageFunction\n this.mouse.addListener(\"mouseevent\", this.eventListenersContainer[id])\n }\n\n /**\n * @description This function is used to remove a mouse listener for a specific widget. The event listener is removed from the eventListenersContainer object.\n * @param {string} id - The id of the widget.\n * @memberof ConsoleManager\n * @example CM.removeMouseListener('inputPopup')\n */\n public removeMouseListener(id: string): void {\n this.mouse.removeListener(\"mouseevent\", this.eventListenersContainer[id])\n delete this.eventListenersContainer[id]\n }\n\n /**\n * @description This function is used to register a popup. The popup is stored in the popupCollection object. That is called by the popups in show().\n * @param {popup} popup - The popup to register.\n * @memberof ConsoleManager\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public registerPopup(popup: any): void {\n this.popupCollection[popup.id] = popup\n }\n\n /**\n * @description This function is used to unregister a popup. The popup is removed from the popupCollection object. That is called by the popups in hide().\n * @param {string} id - The id of the popup.\n * @memberof ConsoleManager\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public unregisterPopup(popup: any): void {\n if (this.popupCollection[popup.id]) {\n delete this.popupCollection[popup.id]\n }\n }\n\n /**\n * @description This function is used to register a control. The control is stored in the controlCollection object. That is called by the controls in show().\n * @param {control} control - The control to register.\n * @memberof ConsoleManager\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public registerControl(control: any): void {\n this.controlsCollection[control.id] = control\n }\n\n /**\n * @description This function is used to unregister a control. The control is removed from the controlCollection object. That is called by the controls in hide().\n * @param {string} id - The id of the control.\n * @memberof ConsoleManager\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public unregisterControl(control: any): void {\n if (this.controlsCollection[control.id]) {\n delete this.controlsCollection[control.id]\n }\n }\n\n /**\n * @description This function is used to set the home page. It also refresh the screen.\n * @param {PageBuilder} page - The page to set as home page.\n * @memberof ConsoleManager\n * @example CM.setHomePage(p)\n * @deprecated since version 1.1.12 - Use setPage or setPages instead\n */\n public setHomePage(page: PageBuilder): void {\n this.pages[0] = page\n if (this.logLocation === \"popup\") {\n this.layout.setPage(page, 0)\n } else if (typeof this.logLocation === \"number\") {\n if (this.logLocation === 0) {\n this.layout.setPage(page, 1)\n } else {\n this.layout.setPage(page, 0)\n }\n } else {\n this.layout.setPage(page, 1)\n }\n this.refresh()\n }\n\n /**\n * @description This function is used to set a page of layout. It also refresh the screen.\n * @param {PageBuilder} page - The page to set as home page.\n * @param {number} [pageNumber] - The page number to set. 0 is the first page, 1 is the second page.\n * @param {string | null} [title] - The title of the page to overwrite the default title. Default is null.\n * @memberof ConsoleManager\n * @example CM.setPage(p, 0)\n */\n public setPage(page: PageBuilder, pageNumber = 0, title: string | null = null): void {\n this.pages[pageNumber] = page\n if (typeof this.logLocation === \"number\") {\n if (this.logLocation === pageNumber) {\n this.pages[this.logLocation] = this.stdOut\n }\n }\n this.layout.setPage(this.pages[pageNumber], pageNumber)\n if (title) this.layout.setTitle(title, pageNumber)\n this.refresh()\n }\n\n /**\n * @description This function is used to set both pages of layout. It also refresh the screen.\n * @param {Array<PageBuilder>} pages - The page to set as home page.\n * @param {string[] | null} [titles] - The titles of the page to overwrite the default titles. Default is null.\n * @memberof ConsoleManager\n * @example CM.setPages([p1, p2], 0)\n */\n public setPages(pages: Array<PageBuilder>, titles: string[] | null = null): void {\n pages.forEach((page, index) => {\n if (typeof this.logLocation === \"number\" && this.logLocation === index) {\n return\n } else {\n this.pages[index] = page\n }\n })\n this.layout.setPages(this.pages)\n if (titles) this.layout.setTitles(titles)\n this.refresh()\n }\n\n /**\n * @description This function is used to refresh the screen. It do the following sequence: Clear the screen, draw layout, draw widgets and finally print the screen to the stdOut.\n * @memberof ConsoleManager\n * @example CM.refresh()\n */\n public refresh(): void {\n this.Screen.update()\n this.layout.draw()\n for (const widget in this.controlsCollection) {\n if (this.controlsCollection[widget].isVisible())\n this.controlsCollection[widget].draw()\n }\n for (const widget in this.popupCollection) {\n if (this.popupCollection[widget].isVisible())\n this.popupCollection[widget].draw()\n }\n this.Screen.print()\n }\n\n /**\n * @description This function is used to show a popup containing all the stdOut of the console.\n * @memberof ConsoleManager\n * @returns the instance of the generated popup.\n * @example CM.showLogPopup()\n */\n public showLogPopup(): CustomPopup {\n return new CustomPopup({\n id: \"logPopup\", \n title: \"Application Logs\", \n content: this.stdOut, \n width: this.Screen.width - 12\n }).show()\n }\n\n /**\n * @description This function is used to log a message. It is used to log messages in the log page. Don't add colors to the message.\n * @param {string} message - The message to log.\n * @memberof ConsoleManager\n * @example CM.log(\"Hello world\")\n */\n public log(message: string): void {\n this.stdOut.addRow({ text: message, color: \"white\" })\n this.updateLogsConsole(true)\n }\n\n /** \n * @description This function is used to log an error message. It is used to log red messages in the log page. Don't add colors to the message.\n * @param {string} message - The message to log.\n * @memberof ConsoleManager\n * @example CM.error(\"Anomaly detected\")\n */\n public error(message: string): void {\n this.stdOut.addRow({ text: message, color: \"red\" })\n this.updateLogsConsole(true)\n }\n\n /**\n * @description This function is used to log a warning message. It is used to log yellow messages in the log page. Don't add colors to the message.\n * @param {string} message - The message to log.\n * @memberof ConsoleManager\n * @example CM.warn(\"Anomaly detected\")\n */\n public warn(message: string): void {\n this.stdOut.addRow({ text: message, color: \"yellow\" })\n this.updateLogsConsole(true)\n }\n\n /**\n * @description This function is used to log an info message. It is used to log blue messages in the log page. Don't add colors to the message.\n * @param {string} message - The message to log.\n * @memberof ConsoleManager\n * @example CM.info(\"Anomaly detected\")\n */\n public info(message: string): void {\n this.stdOut.addRow({ text: message, color: \"blue\" })\n this.updateLogsConsole(true)\n }\n\n /**\n * @description This function is used to update the logs console. It is called by the log functions.\n * @param {boolean} resetCursor - If true, the log scroll index is resetted.\n * @memberof ConsoleManager\n */\n private updateLogsConsole(resetCursor: boolean): void {\n if (resetCursor) {\n this.stdOut.setScrollIndex(0)\n }\n this.refresh()\n }\n\n /**\n * @description This function is used to override the console.log, console.error, console.warn and console.info functions.\n * @memberof ConsoleManager\n * @example CM.overrideConsole()\n * @example console.log(\"Hello world\") // Will be logged in the log page.\n * @example console.error(\"Anomaly detected\") // Will be logged in the log page.\n * @example console.warn(\"Anomaly detected\") // Will be logged in the log page.\n * @example console.info(\"Anomaly detected\") // Will be logged in the log page.\n * @example console.debug(\"Anomaly detected\") // Will be logged in the log page.\n * @since 1.1.42\n */\n private overrideConsole(): void {\n console.log = (message: string) => {\n this.log(message)\n }\n console.error = (message: string) => {\n this.error(message)\n }\n console.warn = (message: string) => {\n this.warn(message)\n }\n console.info = (message: string) => {\n this.info(message)\n }\n console.debug = (message: string) => {\n this.log(message)\n }\n }\n}\n\nexport {\n EOL,\n RelativeMouseEvent, MouseEventArgs, MouseEvent,\n PhisicalValues,\n StyledElement, SimplifiedStyledElement, StyleObject,\n PageBuilder, InPageWidgetBuilder,\n Control, ControlConfig,\n Box, BoxConfig, BoxStyle,\n Button, ButtonConfig, ButtonStyle, ButtonKey,\n Progress, ProgressConfig, ProgressStyle, Orientation,\n ConsoleManager,\n OptionPopup, OptionPopupConfig,\n InputPopup, InputPopupConfig,\n ConfirmPopup, ConfirmPopupConfig,\n ButtonPopup, ButtonPopupConfig,\n CustomPopup, PopupConfig,\n FileSelectorPopup, FileSelectorPopupConfig,\n}", "import { BackgroundColorName, ForegroundColorName } from \"chalk\"\n\n/**\n * @typedef {string} HEX - The type of the HEX color.\n * @example const hexColor = \"#FF0000\"\n *\n * @typedef {string} RGB - The type of the RGB color.\n * @example const rgbColor = \"rgb(255, 0, 0)\"\n */\nexport type HEX = `#${string}`;\nexport type RGB =\n | `rgb(${number}, ${number}, ${number})`\n | `rgb(${number},${number},${number})`;\n\n/**\n * @description The type containing all the possible styles for the text.\n *\n * @typedef {Object} StyleObject\n * @prop {chalk.ForegroundColorName | HEX | RGB | \"\"} [color] - The color of the text taken from the chalk library.\n * @prop {chalk.BackgroundColorName | HEX | RGB | \"\"} [backgroundColor] - The background color of the text taken from the chalk library.\n * @prop {boolean} [italic] - If the text is italic.\n * @prop {boolean} [bold] - If the text is bold.\n * @prop {boolean} [dim] - If the text is dim.\n * @prop {boolean} [underline] - If the text is underlined.\n * @prop {boolean} [inverse] - If the text is inverse.\n * @prop {boolean} [hidden] - If the text is hidden.\n * @prop {boolean} [strikethrough] - If the text is strikethrough.\n * @prop {boolean} [overline] - If the text is overlined.\n *\n * @example const textStyle = { color: \"red\", backgroundColor: \"blue\", bold: true, italic: true }\n *\n * @export\n * @interface StyleObject\n */\n// @type definition\nexport interface StyleObject {\n color?: ForegroundColorName | HEX | RGB | \"\";\n bg?: BackgroundColorName | HEX | RGB | \"\";\n italic?: boolean;\n bold?: boolean;\n dim?: boolean;\n underline?: boolean;\n inverse?: boolean;\n hidden?: boolean;\n strikethrough?: boolean;\n overline?: boolean;\n}\n\n/**\n * @description The type of the single styled text, stored in a line of the PageBuilder.\n *\n * @typedef {Object} StyledElement\n * @prop {string} text - The text of the styled text.\n * @prop {StyleObject} style - The style of the styled text.\n *\n * @example const styledText = { text: \"Hello\", style: { color: \"red\", backgroundColor: \"blue\", bold: true, italic: true } }\n *\n * @export\n * @interface StyledElement\n */\n// @type definition\nexport interface StyledElement {\n text: string;\n style: StyleObject;\n}\n\n/**\n * @description The type containing all the possible styles for the text and the text on the same level. It's used on the higher level.\n *\n * @typedef {Object} SimplifiedStyledElement\n * @prop {string} text - The text of the styled text.\n * @prop {chalk.ForegroundColorName | HEX | RGB | \"\"} [color] - The color of the text taken from the chalk library.\n * @prop {chalk.BackgroundColorName | HEX | RGB | \"\" | \"\"} [backgroundColor] - The background color of the text taken from the chalk library.\n * @prop {boolean} [italic] - If the text is italic.\n * @prop {boolean} [bold] - If the text is bold.\n * @prop {boolean} [dim] - If the text is dim.\n * @prop {boolean} [underline] - If the text is underlined.\n * @prop {boolean} [inverse] - If the text is inverse.\n * @prop {boolean} [hidden] - If the text is hidden.\n * @prop {boolean} [strikethrough] - If the text is strikethrough.\n * @prop {boolean} [overline] - If the text is overlined.\n *\n * @example const textStyle = { color: \"red\", backgroundColor: \"blue\", bold: true, italic: true }\n *\n * @export\n * @interface SimplifiedStyledElement\n */\n// @type definition\nexport interface SimplifiedStyledElement {\n text: string;\n color?: ForegroundColorName | HEX | RGB | \"\";\n bg?: BackgroundColorName | HEX | RGB | \"\" | \"\";\n italic?: boolean;\n bold?: boolean;\n dim?: boolean;\n underline?: boolean;\n inverse?: boolean;\n hidden?: boolean;\n strikethrough?: boolean;\n overline?: boolean;\n}\n\n/**\n * @description The type that contains the phisical values of an element (x, y, width, height)\n *\n * @export\n * @interface PhisicalValues\n */\n// @type definition\nexport interface PhisicalValues {\n x: number;\n y: number;\n width: number;\n height: number;\n id?: number;\n}\n\n/** @const {Object} boxChars - The characters used to draw the box. */\nexport const boxChars = {\n normal: {\n topLeft: \"\u250C\",\n topRight: \"\u2510\",\n bottomLeft: \"\u2514\",\n bottomRight: \"\u2518\",\n horizontal: \"\u2500\",\n vertical: \"\u2502\",\n cross: \"\u253C\",\n left: \"\u251C\",\n right: \"\u2524\",\n top: \"\u252C\",\n bottom: \"\u2534\",\n start: \"\",\n end: \"\",\n color: \"\" as ForegroundColorName | HEX | RGB | \"\",\n },\n selected: {\n topLeft: \"\u2554\",\n topRight: \"\u2557\",\n bottomLeft: \"\u255A\",\n bottomRight: \"\u255D\",\n horizontal: \"\u2550\",\n vertical: \"\u2551\",\n cross: \"\u256C\",\n left: \"\u2560\",\n right: \"\u2563\",\n top: \"\u2566\",\n bottom: \"\u2569\",\n start: \"\",\n end: \"\",\n color: \"\" as ForegroundColorName | HEX | RGB | \"\",\n },\n hovered: {\n topLeft: \"\u2553\",\n topRight: \"\u2556\",\n bottomLeft: \"\u2559\",\n bottomRight: \"\u255C\",\n horizontal: \"\u2500\",\n vertical: \"\u2502\",\n cross: \"\u256B\",\n left: \"\u255F\",\n right: \"\u2562\",\n top: \"\u2565\",\n bottom: \"\u2568\",\n start: \"\",\n end: \"\",\n color: \"\" as ForegroundColorName | HEX | RGB | \"\",\n },\n}\n\n/**\n * @description This function is used to truncate a string adding ... at the end.\n * @param {string} str - The string to truncate.\n * @param {number} n - The number of characters to keep.\n * @param {boolean} useWordBoundary - If true, the truncation will be done at the end of the word.\n * @example CM.truncate(\"Hello world\", 5, true) // \"Hello...\"\n */\nexport function truncate(\n str: string,\n n: number,\n useWordBoundary: boolean\n): string {\n if (visibleLength(str) <= n) {\n return str\n }\n const subString = str.substring(0, n - 1) // the original check\n return (\n (useWordBoundary\n ? subString.substring(0, subString.lastIndexOf(\" \"))\n : subString) + \"\u2026\"\n )\n}\n\n/**\n * @description This function is used to convert a styled element to a simplified styled element.\n *\n * @export\n * @param {StyledElement} styled\n * @return {*} {SimplifiedStyledElement}\n *\n * @example const simplifiedStyledElement = styledToSimplifiedStyled({ text: \"Hello world\", style: { color: \"red\", backgroundColor: \"blue\", bold: true, italic: true } })\n * // returns { text: \"Hello world\", color: \"red\", backgroundColor: \"blue\", bold: true, italic: true }\n */\nexport function styledToSimplifiedStyled(\n styled: StyledElement\n): SimplifiedStyledElement {\n return {\n text: styled.text,\n color: styled.style?.color,\n bg: styled.style?.bg,\n italic: styled.style?.italic,\n bold: styled.style?.bold,\n dim: styled.style?.dim,\n underline: styled.style?.underline,\n inverse: styled.style?.inverse,\n hidden: styled.style?.hidden,\n strikethrough: styled.style?.strikethrough,\n overline: styled.style?.overline,\n }\n}\n\n/**\n * @description This function is used to convert a simplified styled element to a styled element.\n *\n * @export\n * @param {SimplifiedStyledElement} simplifiedStyled\n * @return {*} {StyledElement}\n *\n * @example const styledElement = simplifiedStyledToStyled({ text: \"Hello world\", color: \"red\", bold: true })\n * // returns { text: \"Hello world\", style: { color: \"red\", bold: true } }\n */\nexport function simplifiedStyledToStyled(\n simplifiedStyled: SimplifiedStyledElement\n): StyledElement {\n return {\n text: simplifiedStyled.text,\n style: {\n color: simplifiedStyled?.color,\n bg: simplifiedStyled?.bg,\n italic: simplifiedStyled?.italic,\n bold: simplifiedStyled?.bold,\n dim: simplifiedStyled?.dim,\n underline: simplifiedStyled?.underline,\n inverse: simplifiedStyled?.inverse,\n hidden: simplifiedStyled?.hidden,\n strikethrough: simplifiedStyled?.strikethrough,\n overline: simplifiedStyled?.overline,\n },\n }\n}\n\n/**\n * @description Count true visible length of a string\n *\n * @export\n * @param {string} input\n * @return {number}\n * \n * @author Vitalik Gordon (xpl)\n */\nexport function visibleLength(input: string): number {\n // eslint-disable-next-line no-control-regex\n const regex = new RegExp(\n /* eslint-disable-next-line no-control-regex */\n \"[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]\",\n \"g\"\n )\n // Array.from is used to correctly count emojis\n return Array.from(input.replace(regex, \"\")).length\n}\n", "import { SimplifiedStyledElement, StyledElement, simplifiedStyledToStyled } from \"./Utils.js\"\n\n/**\n * @class PageBuilder\n * @description Defines a new page:\n * It's a sort of collection of styled rows.\n * @param {number} rowsPerPage - The number of rows per page. Default is 100. Useful for scrolling.\n *\n * @export\n * @class PageBuilder\n */\nexport class PageBuilder {\n rowsPerPage: number\n scrollIndex: number\n content: StyledElement[][]\n\n public constructor(rowsPerPage = 100) {\n this.rowsPerPage = rowsPerPage\n\n /**\n * @const {number} scrollIndex - The index of the scroll bar.\n * @memberOf PageBuilder \n */\n this.scrollIndex = 0\n\n /**\n * @const {Array<Array<object>>} content The content of the page.\n * @memberOf PageBuilder\n */\n this.content = []\n }\n\n /**\n * @description Add a new styled row to the page.\n * @param {parameters<object>} row - The styled row to add.\n * @returns {PageBuilder}\n * @memberOf PageBuilder\n * @example\n * page.addRow({ text: 'Hello World', color: 'white' })\n * page.addRow({ text: 'Hello World', color: 'white' }, { text: 'Hello World', color: 'white' })\n */\n public addRow(...args: SimplifiedStyledElement[]): PageBuilder {\n // each argument is an object like {text: string, color: string}\n const _row: StyledElement[] = args.map((arg) => simplifiedStyledToStyled(arg)) // convert to StyledElement\n this.content.push(_row)\n return this\n }\n\n /**\n * @description Add an empty row to the page. (like <br /> in HTML)\n * @param {number} [count=1] - The number of empty rows to add.\n * @returns {PageBuilder}\n * @memberOf PageBuilder\n * @example page.addEmptyRow()\n * page.addEmptyRow(2)\n */\n public addSpacer(height = 1): PageBuilder {\n if (height > 0) {\n for (let i = 0; i < height; i++) {\n this.addRow({ text: \"\", color: \"\" })\n }\n }\n return this\n }\n\n /**\n * @description Returns the content of the page.\n * @returns {Array<Array<object>>}\n * @memberOf PageBuilder\n * @example page.getContent()\n */\n public getContent(): StyledElement[][] {\n if (this.getPageHeight() > this.rowsPerPage) {\n return this.content.slice(this.getPageHeight() - this.scrollIndex - this.rowsPerPage, this.getPageHeight() - this.scrollIndex)\n } else {\n return this.content\n }\n }\n\n /**\n * @description Returns the height of the page.\n * @returns {number}\n * @memberOf PageBuilder\n * @example page.getPageHeight()\n */\n public getPageHeight(): number {\n return this.content.length\n }\n\n /**\n * @description Returns the height of the viewed page. It excludes the rows that are not visible.\n * @returns {number}\n * @memberOf PageBuilder\n * @example page.getViewedPageHeight() // returns the height of the page that is visible\n */\n public getViewedPageHeight(): number {\n return this.getContent().length\n }\n\n /**\n * @description Changes the index of the scroll bar.\n * @param {number} index - The index of the scroll bar.\n * @returns {PageBuilder}\n * @memberOf PageBuilder\n * @example page.setScrollIndex(10)\n */\n public setScrollIndex(index: number): PageBuilder {\n this.scrollIndex = index\n return this\n }\n\n /**\n * @description Changes the number of rows per page.\n * @param {number} rowsPerPage - The number of rows per page.\n * @returns {PageBuilder}\n * @memberOf PageBuilder\n * @example page.setRowsPerPage(10)\n */\n public setRowsPerPage(rpp: number): PageBuilder {\n this.rowsPerPage = rpp\n return this\n }\n\n /**\n * @description Increases the index of the scroll bar.\n * @returns {PageBuilder}\n * @memberOf PageBuilder\n * @example page.increaseScrollIndex()\n */\n public increaseScrollIndex(): PageBuilder {\n if (this.scrollIndex < this.getPageHeight() - this.rowsPerPage) {\n this.scrollIndex++\n }\n return this\n }\n\n /**\n * @description Decreases the index of the scroll bar.\n * @returns {PageBuilder}\n * @memberOf PageBuilder\n * @example page.increaseScrollIndex()\n */\n public decreaseScrollIndex(): PageBuilder {\n if (this.scrollIndex > 0) {\n this.scrollIndex--\n }\n return this\n }\n\n /**\n * @description Clears the page.\n * @returns {PageBuilder}\n * @memberOf PageBuilder\n * @example page.clear()\n * @since 1.2.0\n */\n public clear(): PageBuilder {\n this.content = []\n return this\n }\n}\n\nexport default PageBuilder", "import PageBuilder from \"./PageBuilder.js\"\n\n/**\n * @class InPageWidgetBuilder\n * @extends PageBuilder\n * @description Defines a new widget content:\n * It's a sort of collection of styled rows.\n * @param {number} rowsPerPage - The number of rows per page. Default is 100. Useful for scrolling.\n *\n * @export\n * @class InPageWidgetBuilder\n */\nexport class InPageWidgetBuilder extends PageBuilder {\n public constructor(rowsPerPage = 100) {\n super(rowsPerPage)\n }\n}\n\nexport default InPageWidgetBuilder\nexport * from \"./PageBuilder.js\"", "import { EventEmitter } from \"events\"\nimport chalk, { BackgroundColorName, ForegroundColorName } from \"chalk\"\nimport { StyledElement, StyleObject, visibleLength } from \"./Utils.js\"\nchalk.level = 3\n\n/**\n * @description The type containing all the possible styles for the text and the index array.\n * @typedef {Object} StyleIndexObject\n * @prop {Array<number>} index - The index of the style in the style array.\n * \n * @interface StyleIndexObject\n * @extends {StyleObject}\n */\ninterface StyleIndexObject extends StyleObject {\n index: [number, number];\n}\n\n/**\n * @description The type containing all the possible styles for the text and the index array and the text.\n * @typedef {Object} StyledElementWithIndex\n * @prop {string} text - The text of the styled element.\n * @prop {StyleIndexObject[]} styleIndex - The styles array with index.\n * \n * @interface StyledElementWithIndex\n */\ninterface StyledElementWithIndex {\n text: string;\n styleIndex: StyleIndexObject[];\n}\n\n/**\n * @class Screen\n * @description This class is used to manage the screen buffer.\n * @param {object} Terminal - The terminal object (process.stdout).\n * @extends EventEmitter\n * @example const screen = new Screen(process.stdout)\n */\nexport class Screen extends EventEmitter {\n Terminal: NodeJS.WriteStream\n width: number\n height: number\n buffer: StyledElementWithIndex[]\n cursor: { x: number; y: number }\n currentY = 0\n\n constructor(_Terminal: NodeJS.WriteStream) {\n super()\n this.Terminal = _Terminal\n\n /** @const {number} width - The width of the screen. */\n this.width = this.Terminal.columns\n\n /** @const {number} height - The height of the screen. */\n this.height = this.Terminal.rows\n\n /** @const {Array} buffer - The screen buffer object. */\n this.buffer = []\n\n /** @const {object} cursor - The cursor object. */\n this.cursor = { x: 0, y: 0 }\n\n this.Terminal.on(\"resize\", () => {\n this.emit(\"resize\")\n })\n }\n\n /**\n * @description This method is used to write or overwrite a row in the screen buffer at a specific position.\n * @param {arguments<object>} args - The row to write.\n * @returns {void}\n * @memberOf Screen\n * @example screen.write({ text: 'Hello World', color: 'white' })\n screen.write({ text: 'Hello World', color: 'white' }, { text: 'Hello World', color: 'white' })\n */\n write(...args: StyledElement[]): void {\n this.currentY++\n if (this.cursor.y < this.buffer.length) {\n let row = \"\"\n const newStyleIndex = []\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (arg.text !== undefined) {\n const txt = arg.text.toString()\n const style: StyleIndexObject = { ...arg.style, index: [visibleLength(row), visibleLength(row) + visibleLength(txt)] }\n newStyleIndex.push(style)\n row += txt\n }\n }\n const currentStyleIndex = this.buffer[this.cursor.y].styleIndex\n\n // Now recalculate the styleIndex for the current row mixing the old one with the new one\n // Create a new styleIndex merging the old one with the new one\n const mergedStyleIndex = this.mergeStyles(newStyleIndex, currentStyleIndex, this.cursor.x, visibleLength(row))\n\n this.buffer[this.cursor.y].styleIndex = mergedStyleIndex\n this.buffer[this.cursor.y].text = this.replaceAt(this.buffer[this.cursor.y].text, this.cursor.x, row)\n this.cursorTo(0, this.cursor.y + 1)\n }\n }\n\n /**\n * @description This method is used to change the cursor position.\n * @param {number} x - The x position.\n * @param {number} y - The y position.\n * @returns {void}\n * @memberOf Screen\n * @example screen.cursorTo(0, 0)\n */\n cursorTo(x: number, y: number): void {\n this.cursor.x = x\n this.cursor.y = y\n }\n\n /**\n * @description This method is used to change the Terminal cursor position.\n * @param {number} x - The x position.\n * @param {number} y - The y position.\n * @returns {void}\n * @memberOf Screen\n * @example screen.moveCursor(0, 0)\n */\n moveCursor(x: number, y: number): void {\n this.Terminal.cursorTo(x, y)\n }\n\n /**\n * @description This method is used to clear the screen. It fills the screen buffer with empty rows with the size of the screen.\n * @returns {void}\n * @memberOf Screen\n * @example screen.clear()\n */\n update(): void {\n this.cursorTo(0, 0)\n this.width = this.Terminal.columns\n this.height = this.Terminal.rows\n this.buffer = []\n for (let i = 0; i < this.Terminal.rows; i++) {\n this.buffer[i] = { text: \" \".repeat(this.Terminal.columns), styleIndex: [{ color: \"gray\", bg: \"\", italic: false, bold: false, index: [0, this.Terminal.columns] }] }\n }\n }\n\n /**\n * @description This method is used to print the screen buffer to the terminal. It also converts the styles to the terminal format using Chalk.\n * @returns {void}\n * @memberOf Screen\n * @example screen.print()\n */\n print(): void {\n this.buffer.forEach((row, i) => {\n this.Terminal.cursorTo(0, i)\n let outString = \"\"\n\n // convert styleIndex to chalk functions and apply them to the row text\n row.styleIndex.forEach(style => {\n let color = (_in: string): string => _in\n if (style.color) {\n if (style.color[0] === \"#\") {\n color = chalk.hex(style.color)\n } else if (style.color.includes(\"rgb\")) {\n const rgb = [...style.color.matchAll(/\\d+/g)].map(x => x[0])\n color = chalk.rgb(Number(rgb[0]), Number(rgb[1]), Number(rgb[2]))\n } else {\n color = chalk[style.color as ForegroundColorName]\n }\n }\n let bg = (_in: string): string => _in\n if (style.bg) {\n if (style.bg[0] === \"#\") {\n bg = chalk.bgHex(style.bg)\n } else if (style.bg.includes(\"rgb\")) {\n const rgb = [...style.bg.matchAll(/\\d+/g)].map(x => x[0])\n bg = chalk.bgRgb(Number(rgb[0]), Number(rgb[1]), Number(rgb[2]))\n } else {\n bg = chalk[style.bg as BackgroundColorName]\n }\n }\n const italic = style.italic ? chalk.italic : (_in: string): string => _in\n const bold = style.bold ? chalk.bold : (_in: string): string => _in\n const dim = style.dim ? chalk.dim : (_in: string): string => _in\n const underline = style.underline ? chalk.underline : (_in: string): string => _in\n const overline = style.overline ? chalk.overline : (_in: string): string => _in\n const inverse = style.inverse ? chalk.inverse : (_in: string): string => _in\n const hidden = style.hidden ? chalk.hidden : (_in: string): string => _in\n const strikethrough = style.strikethrough ? chalk.strikethrough : (_in: string): string => _in\n outString += color(bg(italic(bold(dim(underline(overline(inverse(hidden(strikethrough(row.text.substring(style.index[0], style.index[1])))))))))))\n })\n this.Terminal.write(outString)\n })\n this.Terminal.clearScreenDown()\n }\n\n /**\n * @description This method is used to insert a substring into a string at a specific position.\n * @param {string} str - The string to insert into.\n * @param {number} index - The position to insert the substring.\n * @param {string} replacement - The substring to insert.\n * @returns {string}\n * @memberOf Screen\n * @example screen.replaceAt('Hello Luca', 6, 'Elia') // returns 'Hello Elia'\n */\n replaceAt(str: string, index: number, replacement: string): string {\n return str.substring(0, index) + replacement + str.substring(index + replacement.length)\n }\n\n /**\n * @description This method is used to merge two styleIndex arrays into one. It also recalculates the indexes for the new row.\n * @param {Array<StyleIndexObject>} newStyleIndex - The new styleIndex array.\n * @param {Array<StyleIndexObject>} currentStyleIndex - The current styleIndex array.\n * @param {number} startIndex - The start index of the new styleIndex array (Usually the cursor.x).\n * @param {number} newSize - The new size of the string.\n * @returns {Array<StyleIndexObject>}\n * @memberOf Screen\n * @example screen.mergeStyles([{ color: 'red', bg: 'black', italic: false, bold: false, index: [0, 5] }, { color: 'white', bg: 'black', italic: false, bold: false, index: [6, 10] }], [{ color: 'magenta', bg: 'black', italic: false, bold: false, index: [0, 30] }], 5, 15)\n * returns [{ color: 'magenta', bg: 'black', italic: false, bold: false, index: [0, 4] }, { color: 'red', bg: 'black', italic: false, bold: false, index: [5, 10] }, { color: 'white', bg: 'black', italic: false, bold: false, index: [11, 15] }, { color: 'magenta', bg: 'black', italic: false, bold: false, index: [16, 30] }]\n */\n mergeStyles(newStyleIndex: Array<StyleIndexObject>, currentStyleIndex: Array<StyleIndexObject>, startIndex: number, newSize: number): Array<StyleIndexObject> {\n const new_ = [...newStyleIndex]\n const current = [...currentStyleIndex]\n const offset = startIndex\n const _newSize = newSize\n const merged: StyleIndexObject[] = []\n current.forEach(style => {\n if (style.index[0] < offset && style.index[1] < offset) {\n merged.push(style)\n return\n } else if (style.index[0] < offset && style.index[1] >= offset && style.index[1] <= offset + _newSize) {\n merged.push({ ...style, index: [style.index[0], offset] })\n return\n } else if (style.index[0] < offset && style.index[1] > offset + _newSize) {\n merged.push({ ...style, index: [style.index[0], offset] })\n merged.push({ ...style, index: [offset + _newSize, style.index[1]] })\n return\n } else if (style.index[0] >= offset && style.index[1] <= offset + _newSize) {\n // Do nothing\n return\n } else if (style.index[0] >= offset && style.index[0] <= offset + _newSize && style.index[1] > offset + _newSize) {\n merged.push({ ...style, index: [offset + _newSize, style.index[1]] })\n return\n } else if (style.index[0] > offset + _newSize && style.index[1] > offset + _newSize) {\n merged.push(style)\n return\n }\n this.emit(\"error\", new Error(\"mergeStyles: This should never happen\"))\n })\n\n // Then add the new style to the merged array\n new_.forEach(newStyle => {\n merged.push({ ...newStyle, index: [newStyle.index[0] + offset, newStyle.index[1] + offset] })\n })\n\n // Sort the merged array by index[0]\n merged.sort(this.sortByIndex)\n return merged\n }\n\n /**\n * @description This method is used to sort an array of styleIndex objects by child index[0].\n * @param {StyleIndexObject} a - The first object to compare.\n * @param {StyleIndexObject} b - The second object to compare.\n * @returns {number}\n * @memberOf Screen\n * @example merged.sort(this.sortByIndex)\n */\n sortByIndex(a: StyleIndexObject, b: StyleIndexObject): number {\n if (a.index[0] < b.index[0]) {\n return -1\n } else if (a.index[0] > b.index[0]) {\n return 1\n } else {\n return 0\n }\n }\n}\n\nexport default Screen", "const ANSI_BACKGROUND_OFFSET = 10;\n\nconst wrapAnsi16 = (offset = 0) => code => `\\u001B[${code + offset}m`;\n\nconst wrapAnsi256 = (offset = 0) => code => `\\u001B[${38 + offset};5;${code}m`;\n\nconst wrapAnsi16m = (offset = 0) => (red, green, blue) => `\\u001B[${38 + offset};2;${red};${green};${blue}m`;\n\nconst styles = {\n\tmodifier: {\n\t\treset: [0, 0],\n\t\t// 21 isn't widely supported and 22 does the same thing\n\t\tbold: [1, 22],\n\t\tdim: [2, 22],\n\t\titalic: [3, 23],\n\t\tunderline: [4, 24],\n\t\toverline: [53, 55],\n\t\tinverse: [7, 27],\n\t\thidden: [8, 28],\n\t\tstrikethrough: [9, 29],\n\t},\n\tcolor: {\n\t\tblack: [30, 39],\n\t\tred: [31, 39],\n\t\tgreen: [32, 39],\n\t\tyellow: [33, 39],\n\t\tblue: [34, 39],\n\t\tmagenta: [35, 39],\n\t\tcyan: [36, 39],\n\t\twhite: [37, 39],\n\n\t\t// Bright color\n\t\tblackBright: [90, 39],\n\t\tgray: [90, 39], // Alias of `blackBright`\n\t\tgrey: [90, 39], // Alias of `blackBright`\n\t\tredBright: [91, 39],\n\t\tgreenBright: [92, 39],\n\t\tyellowBright: [93, 39],\n\t\tblueBright: [94, 39],\n\t\tmagentaBright: [95, 39],\n\t\tcyanBright: [96, 39],\n\t\twhiteBright: [97, 39],\n\t},\n\tbgColor: {\n\t\tbgBlack: [40, 49],\n\t\tbgRed: [41, 49],\n\t\tbgGreen: [42, 49],\n\t\tbgYellow: [43, 49],\n\t\tbgBlue: [44, 49],\n\t\tbgMagenta: [45, 49],\n\t\tbgCyan: [46, 49],\n\t\tbgWhite: [47, 49],\n\n\t\t// Bright color\n\t\tbgBlackBright: [100, 49],\n\t\tbgGray: [100, 49], // Alias of `bgBlackBright`\n\t\tbgGrey: [100, 49], // Alias of `bgBlackBright`\n\t\tbgRedBright: [101, 49],\n\t\tbgGreenBright: [102, 49],\n\t\tbgYellowBright: [103, 49],\n\t\tbgBlueBright: [104, 49],\n\t\tbgMagentaBright: [105, 49],\n\t\tbgCyanBright: [106, 49],\n\t\tbgWhiteBright: [107, 49],\n\t},\n};\n\nexport const modifierNames = Object.keys(styles.modifier);\nexport const foregroundColorNames = Object.keys(styles.color);\nexport const backgroundColorNames = Object.keys(styles.bgColor);\nexport const colorNames = [...foregroundColorNames, ...backgroundColorNames];\n\nfunction assembleStyles() {\n\tconst codes = new Map();\n\n\tfor (const [groupName, group] of Object.entries(styles)) {\n\t\tfor (const [styleName, style] of Object.entries(group)) {\n\t\t\tstyles[styleName] = {\n\t\t\t\topen: `\\u001B[${style[0]}m`,\n\t\t\t\tclose: `\\u001B[${style[1]}m`,\n\t\t\t};\n\n\t\t\tgroup[styleName] = styles[styleName];\n\n\t\t\tcodes.set(style[0], style[1]);\n\t\t}\n\n\t\tObject.defineProperty(styles, groupName, {\n\t\t\tvalue: group,\n\t\t\tenumerable: false,\n\t\t});\n\t}\n\n\tObject.defineProperty(styles, 'codes', {\n\t\tvalue: codes,\n\t\tenumerable: false,\n\t});\n\n\tstyles.color.close = '\\u001B[39m';\n\tstyles.bgColor.close = '\\u001B[49m';\n\n\tstyles.color.ansi = wrapAnsi16();\n\tstyles.color.ansi256 = wrapAnsi256();\n\tstyles.color.ansi16m = wrapAnsi16m();\n\tstyles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);\n\n\t// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js\n\tObject.defineProperties(styles, {\n\t\trgbToAnsi256: {\n\t\t\tvalue(red, green, blue) {\n\t\t\t\t// We use the extended greyscale palette here, with the exception of\n\t\t\t\t// black and white. normal palette only has 4 greyscale shades.\n\t\t\t\tif (red === green && green === blue) {\n\t\t\t\t\tif (red < 8) {\n\t\t\t\t\t\treturn 16;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (red > 248) {\n\t\t\t\t\t\treturn 231;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Math.round(((red - 8) / 247) * 24) + 232;\n\t\t\t\t}\n\n\t\t\t\treturn 16\n\t\t\t\t\t+ (36 * Math.round(red / 255 * 5))\n\t\t\t\t\t+ (6 * Math.round(green / 255 * 5))\n\t\t\t\t\t+ Math.round(blue / 255 * 5);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToRgb: {\n\t\t\tvalue(hex) {\n\t\t\t\tconst matches = /[a-f\\d]{6}|[a-f\\d]{3}/i.exec(hex.toString(16));\n\t\t\t\tif (!matches) {\n\t\t\t\t\treturn [0, 0, 0];\n\t\t\t\t}\n\n\t\t\t\tlet [colorString] = matches;\n\n\t\t\t\tif (colorString.length === 3) {\n\t\t\t\t\tcolorString = [...colorString].map(character => character + character).join('');\n\t\t\t\t}\n\n\t\t\t\tconst integer = Number.parseInt(colorString, 16);\n\n\t\t\t\treturn [\n\t\t\t\t\t/* eslint-disable no-bitwise */\n\t\t\t\t\t(integer >> 16) & 0xFF,\n\t\t\t\t\t(integer >> 8) & 0xFF,\n\t\t\t\t\tinteger & 0xFF,\n\t\t\t\t\t/* eslint-enable no-bitwise */\n\t\t\t\t];\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi256: {\n\t\t\tvalue: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t\tansi256ToAnsi: {\n\t\t\tvalue(code) {\n\t\t\t\tif (code < 8) {\n\t\t\t\t\treturn 30 + code;\n\t\t\t\t}\n\n\t\t\t\tif (code < 16) {\n\t\t\t\t\treturn 90 + (code - 8);\n\t\t\t\t}\n\n\t\t\t\tlet red;\n\t\t\t\tlet green;\n\t\t\t\tlet blue;\n\n\t\t\t\tif (code >= 232) {\n\t\t\t\t\tred = (((code - 232) * 10) + 8) / 255;\n\t\t\t\t\tgreen = red;\n\t\t\t\t\tblue = red;\n\t\t\t\t} else {\n\t\t\t\t\tcode -= 16;\n\n\t\t\t\t\tconst remainder = code % 36;\n\n\t\t\t\t\tred = Math.floor(code / 36) / 5;\n\t\t\t\t\tgreen = Math.floor(remainder / 6) / 5;\n\t\t\t\t\tblue = (remainder % 6) / 5;\n\t\t\t\t}\n\n\t\t\t\tconst value = Math.max(red, green, blue) * 2;\n\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn 30;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tlet result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));\n\n\t\t\t\tif (value === 2) {\n\t\t\t\t\tresult += 60;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\trgbToAnsi: {\n\t\t\tvalue: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi: {\n\t\t\tvalue: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t});\n\n\treturn styles;\n}\n\nconst ansiStyles = assembleStyles();\n\nexport default ansiStyles;\n", "import process from 'node:process';\nimport os from 'node:os';\nimport tty from 'node:tty';\n\n// From: https://github.com/sindresorhus/has-flag/blob/main/index.js\nfunction hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst position = argv.indexOf(prefix + flag);\n\tconst terminatorPosition = argv.indexOf('--');\n\treturn position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);\n}\n\nconst {env} = process;\n\nlet flagForceColor;\nif (\n\thasFlag('no-color')\n\t|| hasFlag('no-colors')\n\t|| hasFlag('color=false')\n\t|| hasFlag('color=never')\n) {\n\tflagForceColor = 0;\n} else if (\n\thasFlag('color')\n\t|| hasFlag('colors')\n\t|| hasFlag('color=true')\n\t|| hasFlag('color=always')\n) {\n\tflagForceColor = 1;\n}\n\nfunction envForceColor() {\n\tif ('FORCE_COLOR' in env) {\n\t\tif (env.FORCE_COLOR === 'true') {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (env.FORCE_COLOR === 'false') {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);\n\t}\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3,\n\t};\n}\n\nfunction _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {\n\tconst noFlagForceColor = envForceColor();\n\tif (noFlagForceColor !== undefined) {\n\t\tflagForceColor = noFlagForceColor;\n\t}\n\n\tconst forceColor = sniffFlags ? flagForceColor : noFlagForceColor;\n\n\tif (forceColor === 0) {\n\t\treturn 0;\n\t}\n\n\tif (sniffFlags) {\n\t\tif (hasFlag('color=16m')\n\t\t\t|| hasFlag('color=full')\n\t\t\t|| hasFlag('color=truecolor')) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (hasFlag('color=256')) {\n\t\t\treturn 2;\n\t\t}\n\t}\n\n\t// Check for Azure DevOps pipelines.\n\t// Has to be above the `!streamIsTTY` check.\n\tif ('TF_BUILD' in env && 'AGENT_NAME' in env) {\n\t\treturn 1;\n\t}\n\n\tif (haveStream && !streamIsTTY && forceColor === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor || 0;\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\tif (process.platform === 'win32') {\n\t\t// Windows 10 build 10586 is the first Windows release that supports 256 colors.\n\t\t// Windows 10 build 14931 is the first release that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(osRelease[0]) >= 10\n\t\t\t&& Number(osRelease[2]) >= 10_586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14_931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif ('GITHUB_ACTIONS' in env) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-kitty') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app': {\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\t}\n\n\t\t\tcase 'Apple_Terminal': {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\treturn min;\n}\n\nexport function createSupportsColor(stream, options = {}) {\n\tconst level = _supportsColor(stream, {\n\t\tstreamIsTTY: stream && stream.isTTY,\n\t\t...options,\n\t});\n\n\treturn translateLevel(level);\n}\n\nconst supportsColor = {\n\tstdout: createSupportsColor({isTTY: tty.isatty(1)}),\n\tstderr: createSupportsColor({isTTY: tty.isatty(2)}),\n};\n\nexport default supportsColor;\n", "// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.\nexport function stringReplaceAll(string, substring, replacer) {\n\tlet index = string.indexOf(substring);\n\tif (index === -1) {\n\t\treturn string;\n\t}\n\n\tconst substringLength = substring.length;\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\treturnValue += string.slice(endIndex, index) + substring + replacer;\n\t\tendIndex = index + substringLength;\n\t\tindex = string.indexOf(substring, endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n\nexport function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\tconst gotCR = string[index - 1] === '\\r';\n\t\treturnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\\r\\n' : '\\n') + postfix;\n\t\tendIndex = index + 1;\n\t\tindex = string.indexOf('\\n', endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n", "import ansiStyles from '#ansi-styles';\nimport supportsColor from '#supports-color';\nimport { // eslint-disable-line import/order\n\tstringReplaceAll,\n\tstringEncaseCRLFWithFirstIndex,\n} from './utilities.js';\n\nconst {stdout: stdoutColor, stderr: stderrColor} = supportsColor;\n\nconst GENERATOR = Symbol('GENERATOR');\nconst STYLER = Symbol('STYLER');\nconst IS_EMPTY = Symbol('IS_EMPTY');\n\n// `supportsColor.level` \u2192 `ansiStyles.color[name]` mapping\nconst levelMapping = [\n\t'ansi',\n\t'ansi',\n\t'ansi256',\n\t'ansi16m',\n];\n\nconst styles = Object.create(null);\n\nconst applyOptions = (object, options = {}) => {\n\tif (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {\n\t\tthrow new Error('The `level` option should be an integer from 0 to 3');\n\t}\n\n\t// Detect level if not set manually\n\tconst colorLevel = stdoutColor ? stdoutColor.level : 0;\n\tobject.level = options.level === undefined ? colorLevel : options.level;\n};\n\nexport class Chalk {\n\tconstructor(options) {\n\t\t// eslint-disable-next-line no-constructor-return\n\t\treturn chalkFactory(options);\n\t}\n}\n\nconst chalkFactory = options => {\n\tconst chalk = (...strings) => strings.join(' ');\n\tapplyOptions(chalk, options);\n\n\tObject.setPrototypeOf(chalk, createChalk.prototype);\n\n\treturn chalk;\n};\n\nfunction createChalk(options) {\n\treturn chalkFactory(options);\n}\n\nObject.setPrototypeOf(createChalk.prototype, Function.prototype);\n\nfor (const [styleName, style] of Object.entries(ansiStyles)) {\n\tstyles[styleName] = {\n\t\tget() {\n\t\t\tconst builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);\n\t\t\tObject.defineProperty(this, styleName, {value: builder});\n\t\t\treturn builder;\n\t\t},\n\t};\n}\n\nstyles.visible = {\n\tget() {\n\t\tconst builder = createBuilder(this, this[STYLER], true);\n\t\tObject.defineProperty(this, 'visible', {value: builder});\n\t\treturn builder;\n\t},\n};\n\nconst getModelAnsi = (model, level, type, ...arguments_) => {\n\tif (model === 'rgb') {\n\t\tif (level === 'ansi16m') {\n\t\t\treturn ansiStyles[type].ansi16m(...arguments_);\n\t\t}\n\n\t\tif (level === 'ansi256') {\n\t\t\treturn ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));\n\t\t}\n\n\t\treturn ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));\n\t}\n\n\tif (model === 'hex') {\n\t\treturn getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));\n\t}\n\n\treturn ansiStyles[type][model](...arguments_);\n};\n\nconst usedModels = ['rgb', 'hex', 'ansi256'];\n\nfor (const model of usedModels) {\n\tstyles[model] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n\n\tconst bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);\n\tstyles[bgModel] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n}\n\nconst proto = Object.defineProperties(() => {}, {\n\t...styles,\n\tlevel: {\n\t\tenumerable: true,\n\t\tget() {\n\t\t\treturn this[GENERATOR].level;\n\t\t},\n\t\tset(level) {\n\t\t\tthis[GENERATOR].level = level;\n\t\t},\n\t},\n});\n\nconst createStyler = (open, close, parent) => {\n\tlet openAll;\n\tlet closeAll;\n\tif (parent === undefined) {\n\t\topenAll = open;\n\t\tcloseAll = close;\n\t} else {\n\t\topenAll = parent.openAll + open;\n\t\tcloseAll = close + parent.closeAll;\n\t}\n\n\treturn {\n\t\topen,\n\t\tclose,\n\t\topenAll,\n\t\tcloseAll,\n\t\tparent,\n\t};\n};\n\nconst createBuilder = (self, _styler, _isEmpty) => {\n\t// Single argument is hot path, implicit coercion is faster than anything\n\t// eslint-disable-next-line no-implicit-coercion\n\tconst builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));\n\n\t// We alter the prototype because we must return a function, but there is\n\t// no way to create a function with a different prototype\n\tObject.setPrototypeOf(builder, proto);\n\n\tbuilder[GENERATOR] = self;\n\tbuilder[STYLER] = _styler;\n\tbuilder[IS_EMPTY] = _isEmpty;\n\n\treturn builder;\n};\n\nconst applyStyle = (self, string) => {\n\tif (self.level <= 0 || !string) {\n\t\treturn self[IS_EMPTY] ? '' : string;\n\t}\n\n\tlet styler = self[STYLER];\n\n\tif (styler === undefined) {\n\t\treturn string;\n\t}\n\n\tconst {openAll, closeAll} = styler;\n\tif (string.includes('\\u001B')) {\n\t\twhile (styler !== undefined) {\n\t\t\t// Replace any instances already present with a re-opening code\n\t\t\t// otherwise only the part of the string until said closing code\n\t\t\t// will be colored, and the rest will simply be 'plain'.\n\t\t\tstring = stringReplaceAll(string, styler.close, styler.open);\n\n\t\t\tstyler = styler.parent;\n\t\t}\n\t}\n\n\t// We can move both next actions out of loop, because remaining actions in loop won't have\n\t// any/visible effect on parts we add here. Close the styling before a linebreak and reopen\n\t// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92\n\tconst lfIndex = string.indexOf('\\n');\n\tif (lfIndex !== -1) {\n\t\tstring = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);\n\t}\n\n\treturn openAll + string + closeAll;\n};\n\nObject.defineProperties(createChalk.prototype, styles);\n\nconst chalk = createChalk();\nexport const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});\n\nexport {\n\tmodifierNames,\n\tforegroundColorNames,\n\tbackgroundColorNames,\n\tcolorNames,\n\n\t// TODO: Remove these aliases in the next major version\n\tmodifierNames as modifiers,\n\tforegroundColorNames as foregroundColors,\n\tbackgroundColorNames as backgroundColors,\n\tcolorNames as colors,\n} from './vendor/ansi-styles/index.js';\n\nexport {\n\tstdoutColor as supportsColor,\n\tstderrColor as supportsColorStderr,\n};\n\nexport default chalk;\n", "import { EventEmitter } from \"events\"\nimport { ConsoleManager, KeyListenerArgs, EOL } from \"../../ConsoleGui.js\"\nimport { MouseEvent } from \"../MouseManager.js\"\nimport PageBuilder from \"../PageBuilder.js\"\nimport { boxChars, PhisicalValues, StyledElement, truncate, visibleLength } from \"../Utils.js\"\n\n/**\n * @description The configuration for the CustomPopup class.\n * @typedef {Object} PopupConfig\n * \n * @prop {string} id - The id of the popup.\n * @prop {string} title - The title of the popup.\n * @prop {PageBuilder} content - The content of the popup.\n * @prop {number} width - The width of the popup.\n * @prop {boolean} [visible] - If the popup is visible.\n *\n * @export\n * @interface PopupConfig\n */\n// @type definition\nexport interface PopupConfig {\n id: string,\n title: string,\n content: PageBuilder,\n width: number,\n visible?: boolean,\n}\n\n/**\n * @class CustomPopup\n * @extends EventEmitter\n * @description This class is used to create a popup with a free content built with PageBuilder class. \n * \n * \n * \n * Emits the following events: \n * - \"confirm\" when the user confirm\n * - \"cancel\" when the user cancel\n * - \"exit\" when the user exit\n * - \"data\" when the user send custom event - the data is an object with the data and the event name\n * @param {PopupConfig} config - The configuration of the popup.\n * \n * @example ```ts\n * const popup = new CustomPopup({\n * id: \"popup1\",\n * title: \"See that values\",\n * content: new PageBuilder().addText(\"Hello world!\"),\n * }).show()\n */\nexport class CustomPopup extends EventEmitter {\n readonly CM: ConsoleManager\n readonly id: string\n title: string\n content: PageBuilder\n width: number\n private visible: boolean\n private marginTop: number\n parsingMouseFrame = false\n /** @var {number} x - The x offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetX: number\n /** @var {number} y - The y offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetY: number\n private absoluteValues: PhisicalValues\n private dragging = false\n private dragStart: { x: number, y: number } = { x: 0, y: 0 }\n focused = false\n\n public constructor(config: PopupConfig) {\n if (!config) throw new Error(\"PopupConfig is required\")\n const { id, title, content, width, visible = false } = config\n if (!id) throw new Error(\"id is required\")\n if (!title) throw new Error(\"title is required\")\n if (!content) throw new Error(\"content is required\")\n if (!width) throw new Error(\"width is required\")\n super()\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n this.id = id\n this.title = title\n this.content = content\n this.width = width\n this.visible = visible\n this.marginTop = 4\n this.offsetX = 0\n this.offsetY = 0\n this.absoluteValues = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n }\n if (this.CM.popupCollection[this.id]) {\n this.CM.unregisterPopup(this)\n const message = `CustomPopup ${this.id} already exists.`\n this.CM.error(message)\n throw new Error(message)\n }\n this.CM.registerPopup(this)\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when the input is text and it is showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @param {string} str - The string of the input.\n * @param {Object} key - The key object.\n * @memberof CustomPopup\n */\n public keyListener(_str: string, key : KeyListenerArgs): void {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n switch (key.name) {\n case \"up\":\n this.content.increaseScrollIndex()\n break\n case \"down\":\n this.content.decreaseScrollIndex()\n break\n case \"return\":\n {\n this.emit(\"confirm\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"escape\":\n {\n this.emit(\"cancel\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"q\":\n {\n this.CM.emit(\"exit\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n default:\n break\n }\n this.CM.refresh()\n }\n\n /**\n * @description This function is used to get the content of the popup.\n * @returns {PageBuilder} The content of the popup.\n * @memberof CustomPopup\n */\n public getContent(): PageBuilder {\n return this.content\n }\n\n /**\n * @description This function is used to change the content of the popup. It also refresh the ConsoleManager.\n * @param {PageBuilder} newContent - The new content of the popup.\n * @memberof CustomPopup\n * @returns {CustomPopup} The instance of the CustomPopup.\n */\n public setContent(newContent: PageBuilder): CustomPopup {\n this.content = newContent\n this.CM.refresh()\n return this\n }\n\n /**\n * @description This function is used to change the popup width. It also refresh the ConsoleManager.\n * @param {number} newWidth - The new width of the popup.\n * @memberof CustomPopup\n * @returns {CustomPopup} The instance of the CustomPopup.\n */\n public setWidth(newWidth: number): this {\n this.width = newWidth\n this.CM.refresh()\n return this\n }\n\n /**\n * @description This function is used to show the popup. It also register the key events and refresh the ConsoleManager.\n * @returns {CustomPopup} The instance of the CustomPopup.\n * @memberof CustomPopup\n */\n public show(): this {\n if (!this.visible) {\n this.manageInput()\n this.visible = true\n this.CM.refresh()\n this.CM.unfocusOtherWidgets(this.id)\n }\n return this\n }\n\n /**\n * @description This function is used to hide the popup. It also unregister the key events and refresh the ConsoleManager.\n * @returns {CustomPopup} The instance of the CustomPopup.\n * @memberof CustomPopup\n */\n public hide(): this {\n if (this.visible) {\n this.unManageInput()\n this.visible = false\n this.CM.restoreFocusInWidgets()\n this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to get the visibility of the popup.\n * @returns {boolean} The visibility of the popup.\n * @memberof CustomPopup\n */\n public isVisible(): boolean {\n return this.visible\n }\n \n /**\n * @description This function is used to return the PhisicalValues of the popup (x, y, width, height).\n * @memberof CustomPopup\n * @private\n * @returns {CustomPopup} The instance of the CustomPopup.\n * @memberof CustomPopup\n */\n public getPosition(): PhisicalValues {\n return this.absoluteValues\n }\n\n /**\n * @description This function is used to add the CustomPopup key listener callback to te ConsoleManager.\n * @returns {CustomPopup} The instance of the CustomPopup.\n * @memberof CustomPopup\n */\n private manageInput(): CustomPopup {\n // Add a command input listener to change mode\n this.CM.setKeyListener(this.id, this.keyListener.bind(this))\n if (this.CM.mouse) this.CM.setMouseListener(`${this.id}_mouse`, this.mouseListener.bind(this))\n return this\n }\n\n /**\n * @description This function is used to remove the CustomPopup key listener callback to te ConsoleManager.\n * @returns {CustomPopup} The instance of the CustomPopup.\n * @memberof CustomPopup\n */\n private unManageInput(): CustomPopup {\n // Add a command input listener to change mode\n this.CM.removeKeyListener(this.id/*, this.keyListener.bind(this)*/)\n if (this.CM.mouse) this.CM.removeMouseListener(`${this.id}_mouse`)\n return this\n }\n\n /**\n * @description This function is used to draw a single line of the layout to the screen. It also trim the line if it is too long.\n * @param {Array<object>} line the line to be drawn\n * @memberof CustomPopup\n * @returns {void}\n */\n private drawLine(line: StyledElement[], width: number): void {\n let unformattedLine = \"\"\n let newLine = [...line]\n line.forEach((element: { text: string }) => {\n unformattedLine += element.text\n })\n if (visibleLength(unformattedLine) > width - 2) { // Need to truncate\n const offset = 2\n newLine = JSON.parse(JSON.stringify(line)) // Shallow copy because I don't want to modify the values but not the original\n let diff = visibleLength(unformattedLine) - width\n // remove truncated text\n for (let i = newLine.length - 1; i >= 0; i--) {\n if (visibleLength(newLine[i].text) > diff + offset) {\n newLine[i].text = truncate(newLine[i].text, (visibleLength(newLine[i].text) - diff) - offset, true)\n break\n } else {\n diff -= visibleLength(newLine[i].text)\n newLine.splice(i, 1)\n }\n }\n // Update unformatted line\n unformattedLine = \"\"\n newLine.forEach(element => {\n unformattedLine += element.text\n })\n }\n newLine.unshift({ text: boxChars[\"normal\"].vertical, style: { color: \"white\" } })\n if (visibleLength(unformattedLine) <= width) {\n newLine.push({ text: `${\" \".repeat((width - visibleLength(unformattedLine)))}`, style: { color: \"\" } })\n }\n newLine.push({ text: boxChars[\"normal\"].vertical, style: { color: \"white\" } })\n this.CM.Screen.write(...newLine)\n }\n\n /**\n * @description This function is used to manage the mouse events on the OptionPopup.\n * @param {MouseEvent} event - The string of the input.\n * @memberof OptionPopup\n */\n private mouseListener = (event: MouseEvent) => {\n const x = event.data.x\n const y = event.data.y\n\n //this.CM.log(event.name)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + this.absoluteValues.height) {\n // The mouse is inside the popup\n //this.CM.log(\"Mouse inside popup\")\n if (event.name === \"MOUSE_WHEEL_DOWN\") {\n this.content.increaseScrollIndex()\n this.focused = true\n } else if (event.name === \"MOUSE_WHEEL_UP\") {\n this.content.decreaseScrollIndex()\n this.focused = true\n } else if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n // find the selected index of the click and set it as selected\n this.focused = true\n }\n } else {\n this.focused = false\n }\n if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === false && this.focused) {\n // check if the mouse is on the header of the popup (first three lines)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + 3/* 3 = header height */) {\n this.dragging = true\n this.dragStart = { x: x, y: y }\n }\n } else if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === true) {\n if ((y - this.dragStart.y) + this.absoluteValues.y < 0) {\n return // prevent the popup to go out of the top of the screen\n }\n if ((x - this.dragStart.x) + this.absoluteValues.x < 0) {\n return // prevent the popup to go out of the left of the screen\n }\n this.offsetX += x - this.dragStart.x\n this.offsetY += y - this.dragStart.y\n this.dragStart = { x: x, y: y }\n this.CM.refresh()\n } else if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\" && this.dragging === true) {\n this.dragging = false\n this.CM.refresh()\n }\n }\n\n /**\n * @description This function is used to draw the CustomPopup to the screen in the middle.\n * @returns {CustomPopup} The instance of the CustomPopup.\n * @memberof CustomPopup\n */\n public draw(): CustomPopup {\n const offset = 2\n const windowWidth = this.title.length > this.width ? this.title.length + (2 * offset) : this.width + (2 * offset) + 1\n const halfWidth = Math.round((windowWidth - this.title.length) / 2)\n const x = Math.round((this.CM.Screen.width / 2) - (windowWidth / 2))\n let header = boxChars[\"normal\"].topLeft\n for (let i = 0; i < windowWidth; i++) {\n header += boxChars[\"normal\"].horizontal\n }\n header += `${boxChars[\"normal\"].topRight}${EOL}`\n header += `${boxChars[\"normal\"].vertical}${\" \".repeat(halfWidth)}${this.title}${\" \".repeat(windowWidth - halfWidth - this.title.length)}${boxChars[\"normal\"].vertical}${EOL}`\n header += `${boxChars[\"normal\"].left}${boxChars[\"normal\"].horizontal.repeat(windowWidth)}${boxChars[\"normal\"].right}${EOL}`\n\n const windowDesign = `${header}`\n const windowDesignLines = windowDesign.split(EOL)\n const centerScreen = Math.round((this.CM.Screen.width / 2) - (windowWidth / 2))\n windowDesignLines.forEach((line, index) => {\n this.CM.Screen.cursorTo(x + this.offsetX, this.marginTop + index + this.offsetY)\n this.CM.Screen.write({ text: line, style: { color: \"white\" } })\n })\n const _content = this.content.getContent()\n _content.forEach((line: StyledElement[], index: number) => {\n this.CM.Screen.cursorTo(x + this.offsetX, this.marginTop + index + windowDesignLines.length - 1 + this.offsetY)\n this.drawLine(line, windowWidth)\n })\n this.CM.Screen.cursorTo(x + this.offsetX, this.marginTop + _content.length + windowDesignLines.length - 1 + this.offsetY)\n this.CM.Screen.write({ text: `${boxChars[\"normal\"].bottomLeft}${boxChars[\"normal\"].horizontal.repeat(windowWidth)}${boxChars[\"normal\"].bottomRight}`, style: { color: \"white\" } })\n \n this.absoluteValues = {\n x: centerScreen + this.offsetX,\n y: this.marginTop + this.offsetY,\n width: windowWidth,\n height: windowDesignLines.length,\n }\n return this\n }\n}\n\nexport default CustomPopup", "import { EventEmitter } from \"events\"\nimport { ConsoleManager, KeyListenerArgs, EOL } from \"../../ConsoleGui.js\"\nimport { MouseEvent } from \"../MouseManager.js\"\nimport { boxChars, PhisicalValues, truncate } from \"../Utils.js\"\n\n/**\n * @description The configuration for the ButtonPopup class.\n * @typedef {Object} ButtonPopupConfig\n * \n * @prop {string} id - The id of the popup.\n * @prop {string} title - The title of the popup.\n * @prop {string} message - The message of the popup.\n * @prop {Array<string>} [buttons] - The buttons of the popup (default is [\"Ok\", \"Cancel\", \"?\"]).\n * @prop {boolean} [visible] - If the popup is visible. Default is false (make it appears using show()).\n *\n * @export\n * @interface ButtonPopupConfig\n */\n// @type definition\nexport interface ButtonPopupConfig {\n id: string,\n title: string,\n message?: string,\n buttons?: Array<string>,\n visible?: boolean,\n}\n\n/**\n * @class ButtonPopup\n * @extends EventEmitter\n * @description This class is used to create a popup with That asks for a confirm. \n * \n * \n * \n * Emits the following events: \n * - \"confirm\" when the user confirm\n * - \"cancel\" when the user cancel\n * - \"exit\" when the user exit\n * @param {ButtonPopupConfig} config - The configuration of the popup.\n * \n * @example ```ts\n * const popup = new ButtonPopup({\n * id: \"popup1\", \n * title: \"Choose the option\", \n * buttons: [\"YES\", \"NO\", \"?\"],\n * }) \n * popup.show() // show the popup\n * popup.on(\"confirm\", () => {\n * console.log(\"User confirmed\")\n * })\n * popup.on(\"cancel\", () => {\n * console.log(\"User canceled\")\n * })\n * ```\n */\nexport class ButtonPopup extends EventEmitter {\n readonly CM: ConsoleManager\n readonly id: string\n title: string\n message: string\n readonly buttons: string[]\n selected: number\n private hovered: number\n private visible: boolean\n private marginTop: number\n parsingMouseFrame = false\n /** @var {number} x - The x offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetX: number\n /** @var {number} y - The y offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetY: number\n private absoluteValues: PhisicalValues\n private buttonsAbsoluteValues: PhisicalValues[] = []\n private dragging = false\n private dragStart: { x: number, y: number } = { x: 0, y: 0 }\n private focused = false\n\n public constructor(config: ButtonPopupConfig) {\n if (!config) throw new Error(\"The config is required\")\n const { id, title, message, buttons = [\"Ok\", \"Cancel\", \"?\"], visible = false } = config\n if (!id) throw new Error(\"The id is required\")\n if (!title) throw new Error(\"The title is required\")\n super()\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n this.id = id\n this.title = title\n this.message = message || \"\"\n this.buttons = buttons\n this.selected = 0 // The selected option\n this.hovered = -1 // The selected option\n this.visible = visible\n this.marginTop = 4\n this.offsetX = 0\n this.offsetY = 0\n this.absoluteValues = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n }\n if (this.CM.popupCollection[this.id]) {\n this.CM.unregisterPopup(this)\n const message = `ButtonPopup ${this.id} already exists.`\n this.CM.error(message)\n throw new Error(message)\n }\n this.CM.registerPopup(this)\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when the popup is showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @param {string} _str - The string of the input.\n * @param {any} key - The key object.\n * @memberof ButtonPopup\n */\n public keyListener(_str: string, key : KeyListenerArgs): void {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n switch (key.name) {\n case \"left\":\n if (this.selected > 0 && this.selected <= this.buttons.length) {\n this.selected--\n } else {\n return\n }\n break\n case \"right\":\n if (this.selected >= 0 && this.selected < this.buttons.length - 1) {\n this.selected++\n } else {\n return\n }\n break\n case \"return\":\n {\n this.emit(\"confirm\", this.buttons[this.selected])\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"escape\":\n {\n this.emit(\"cancel\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"q\":\n {\n this.CM.emit(\"exit\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n default:\n break\n }\n this.CM.refresh()\n }\n\n /**\n * @description This function is used to show the popup. It also register the key events and refresh the ConsoleManager.\n * @returns {ButtonPopup} The instance of the ButtonPopup.\n * @memberof ButtonPopup\n */\n public show(): ButtonPopup {\n if (!this.visible) {\n this.manageInput()\n this.visible = true\n this.CM.refresh()\n this.CM.unfocusOtherWidgets(this.id)\n }\n return this\n }\n\n /**\n * @description This function is used to hide the popup. It also unregister the key events and refresh the ConsoleManager.\n * @returns {ButtonPopup} The instance of the ButtonPopup.\n * @memberof ButtonPopup\n */\n public hide(): ButtonPopup {\n if (this.visible) {\n this.unManageInput()\n this.visible = false\n this.CM.restoreFocusInWidgets()\n this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to get the visibility of the popup.\n * @returns {boolean} The visibility of the popup.\n * @memberof ButtonPopup\n */\n public isVisible(): boolean {\n return this.visible\n }\n\n /**\n * @description This function is used to return the PhisicalValues of the popup (x, y, width, height).\n * @memberof ButtonPopup\n * @private\n * @returns {ButtonPopup} The instance of the ButtonPopup.\n * @memberof ButtonPopup\n */\n public getPosition(): PhisicalValues {\n return this.absoluteValues\n }\n\n /**\n * @description This function is used to add the ButtonPopup key listener callback to te ConsoleManager.\n * @returns {ButtonPopup} The instance of the ButtonPopup.\n * @memberof ButtonPopup\n */\n private manageInput(): ButtonPopup {\n // Add a command input listener to change mode\n this.CM.setKeyListener(this.id, this.keyListener.bind(this))\n if (this.CM.mouse) this.CM.setMouseListener(`${this.id}_mouse`, this.mouseListener.bind(this))\n return this\n }\n\n /**\n * @description This function is used to remove the ButtonPopup key listener callback to te ConsoleManager.\n * @returns {ButtonPopup} The instance of the ButtonPopup.\n * @memberof ButtonPopup\n */\n private unManageInput(): ButtonPopup {\n // Add a command input listener to change mode\n this.CM.removeKeyListener(this.id)\n if (this.CM.mouse) this.CM.removeMouseListener(`${this.id}_mouse`)\n return this\n }\n\n /**\n * @description This function is used to manage the mouse events on the OptionPopup.\n * @param {MouseEvent} event - The string of the input.\n * @memberof OptionPopup\n */\n private mouseListener = (event: MouseEvent) => {\n const x = event.data.x\n const y = event.data.y\n\n //this.CM.log(event.name)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + this.absoluteValues.height) {\n // The mouse is inside the popup\n //this.CM.log(\"Mouse inside popup\")\n if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n // find the selected button of the click using the this.buttonsAbsoluteValues array\n for (let i = 0; i < this.buttonsAbsoluteValues.length; i++) {\n const button = this.buttonsAbsoluteValues[i]\n if (x > button.x && x < button.x + button.width && y > button.y && y < button.y + button.height) {\n this.selected = i\n this.CM.refresh()\n break\n }\n }\n this.focused = true\n return\n }\n if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\") {\n if (this.focused) {\n if (this.buttons && this.buttons.length === 2 && this.buttons[0].toLowerCase() === \"yes\" && this.buttons[1].toLowerCase() === \"no\") { // If the popup is a yes/no popup\n if (this.selected === 0) {\n this.emit(\"confirm\")\n } else {\n this.emit(\"cancel\")\n }\n } else {\n this.emit(\"confirm\", this.buttons[this.selected])\n }\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n return\n }\n if (event.name === \"MOUSE_MOTION\") {\n for (let i = 0; i < this.buttonsAbsoluteValues.length; i++) {\n const button = this.buttonsAbsoluteValues[i]\n if (x > button.x && x < button.x + button.width && y > button.y && y < button.y + button.height) {\n this.hovered = i\n this.CM.refresh()\n break\n }\n }\n }\n } else {\n this.focused = false\n }\n if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === false && this.focused) {\n // check if the mouse is on the header of the popup (first three lines)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + 3/* 3 = header height */) {\n this.dragging = true\n this.dragStart = { x: x, y: y }\n }\n } else if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === true) {\n if ((y - this.dragStart.y) + this.absoluteValues.y < 0) {\n return // prevent the popup to go out of the top of the screen\n }\n if ((x - this.dragStart.x) + this.absoluteValues.x < 0) {\n return // prevent the popup to go out of the left of the screen\n }\n this.offsetX += x - this.dragStart.x\n this.offsetY += y - this.dragStart.y\n this.dragStart = { x: x, y: y }\n this.CM.refresh()\n } else if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\" && this.dragging === true) {\n this.dragging = false\n this.CM.refresh()\n }\n }\n\n /**\n * @description This function is used to draw the ButtonPopup to the screen in the middle.\n * @returns {ButtonPopup} The instance of the ButtonPopup.\n * @memberof ButtonPopup\n */\n public draw(): ButtonPopup {\n const offset = 1\n const borderSize = 2\n const spaceBetweenButtons = 1\n let maxRowLength = 0\n const buttonGrid: string[][] = []\n let rowLength = 0\n let rows = 0\n \n this.buttons.forEach((button) => {\n const newButtonLength = button.length + (2 * borderSize) + spaceBetweenButtons\n // Divide into rows and columns the buttons (balance the buttons number between rows and columns)\n if (rowLength + newButtonLength > this.CM.Screen.width - (2 * offset)) {\n rows++\n if (buttonGrid[rows]) {\n buttonGrid[rows].push(button)\n } else {\n buttonGrid[rows] = [button]\n }\n rowLength = newButtonLength\n if (rowLength > maxRowLength) {\n maxRowLength = rowLength - spaceBetweenButtons\n }\n } else {\n if (buttonGrid[rows]) {\n buttonGrid[rows].push(button)\n } else {\n buttonGrid[rows] = [button]\n }\n rowLength += newButtonLength\n if (rowLength > maxRowLength) {\n maxRowLength = rowLength - spaceBetweenButtons\n }\n }\n })\n let title = `${this.title}`\n if (title.length > this.CM.Screen.width - (2 * offset)) {\n title = truncate(title, this.CM.Screen.width - (2 * offset), true)\n }\n let windowWidth = title.length + (2 * offset)\n const msg = this.message ? `${this.message}` : \"\"\n let mstLines = msg.split(EOL)\n if (mstLines.length > 0) {\n mstLines = mstLines.map((line) => {\n if (line.length > this.CM.Screen.width - (2 * offset)) {\n return truncate(line, this.CM.Screen.width - (2 * offset), true)\n }\n return line\n })\n }\n mstLines.forEach((line) => {\n if (line.length > windowWidth) {\n windowWidth = line.length\n }\n })\n \n if (windowWidth < maxRowLength) {\n windowWidth = maxRowLength + (2 * offset)\n }\n const halfWidthTitle = Math.round((windowWidth - title.length) / 2)\n const halfWidthMessage = mstLines.map((line) => Math.round((windowWidth - line.length) / 2))\n \n let header = boxChars[\"normal\"].topLeft\n for (let i = 0; i < windowWidth; i++) {\n header += boxChars[\"normal\"].horizontal\n }\n header += `${boxChars[\"normal\"].topRight}${EOL}`\n header += `${boxChars[\"normal\"].vertical}${\" \".repeat(halfWidthTitle)}${title}${\" \".repeat(windowWidth - halfWidthTitle - title.length)}${boxChars[\"normal\"].vertical}${EOL}`\n header += `${boxChars[\"normal\"].left}${boxChars[\"normal\"].horizontal.repeat(windowWidth)}${boxChars[\"normal\"].right}${EOL}`\n \n let footer = boxChars[\"normal\"].bottomLeft\n for (let i = 0; i < windowWidth; i++) {\n footer += boxChars[\"normal\"].horizontal\n }\n footer += `${boxChars[\"normal\"].bottomRight}${EOL}`\n\n let content = \"\"\n if (mstLines.length > 0 && mstLines[0].length > 0) {\n mstLines.forEach((line, index) => {\n content += `${boxChars[\"normal\"].vertical}${\" \".repeat(halfWidthMessage[index])}${line}${\" \".repeat(windowWidth - halfWidthMessage[index] - line.length)}${boxChars[\"normal\"].vertical}${EOL}`\n })\n }\n const buttonsYOffset = mstLines.length + 3 // 3 = header height\n this.buttonsAbsoluteValues = []\n const centerScreen = Math.round((this.CM.Screen.width / 2) - (windowWidth / 2))\n buttonGrid.forEach((row) => {\n for (let k = 0; k < 3; k++) {\n const buttonLength = row.map(button => button.length + (2 * borderSize) + spaceBetweenButtons)\n const sumRowLength = buttonLength.reduce((a, b) => a + b, 0) - spaceBetweenButtons\n const emptySpace = windowWidth - sumRowLength >= 0 ? windowWidth - sumRowLength : 0\n row.forEach((button, colIndex) => {\n let btnBoxType: keyof typeof boxChars\n btnBoxType = this.selected === this.buttons.indexOf(button) ? \"selected\" : \"normal\"\n if (this.hovered === this.buttons.indexOf(button) && this.selected !== this.buttons.indexOf(button)) {\n btnBoxType = \"hovered\"\n }\n if (colIndex < row.length) {\n if (colIndex === 0) {\n content += `${boxChars[\"normal\"].vertical}${\" \".repeat(emptySpace / 2)}`\n }\n if (k === 0) {\n content += `${boxChars[btnBoxType].topLeft}${boxChars[btnBoxType].horizontal.repeat(borderSize > 1 ? 2 * (borderSize - 1) + button.length : button.length)}${boxChars[btnBoxType].topRight}`\n } else if (k === 1) {\n content += `${boxChars[btnBoxType].vertical}${borderSize > 1 ? \" \".repeat(borderSize-1):\"\"}${button}${borderSize > 1 ? \" \".repeat(borderSize-1):\"\"}${boxChars[btnBoxType].vertical}`\n } else if (k === 2) {\n content += `${boxChars[btnBoxType].bottomLeft}${boxChars[btnBoxType].horizontal.repeat(borderSize > 1 ? 2 * (borderSize - 1) + button.length : button.length)}${boxChars[btnBoxType].bottomRight}`\n } else {\n this.CM.error(\"Error in ButtonPopup draw function\")\n }\n if (colIndex === row.length - 1) {\n content += \" \".repeat(!(emptySpace % 2) ? emptySpace / 2 : Math.round(emptySpace / 2)) + `${boxChars[\"normal\"].vertical}${EOL}`\n } else {\n content += \" \".repeat(spaceBetweenButtons)\n }\n } else if (colIndex === row.length) {\n content += \" \".repeat(!(emptySpace % 2) ? emptySpace / 2 : Math.round(emptySpace / 2)) + `${boxChars[\"normal\"].vertical}${EOL}`\n }\n const buttonPh: PhisicalValues = {\n id: this.buttons.indexOf(button),\n x: centerScreen + this.offsetX + emptySpace / 2 + buttonLength.slice(0, colIndex).reduce((a, b) => a + b, 0) + 1,\n y: this.marginTop + this.offsetY - (rows + 1) / 2 + this.buttons.indexOf(button) + buttonsYOffset,\n width: buttonLength[colIndex] - spaceBetweenButtons + 1,\n height: 3\n }\n // We have to add the real button size and place to the buttonSizes array\n this.buttonsAbsoluteValues.push(buttonPh)\n })\n }\n })\n\n const windowDesign = `${header}${content}${footer}`\n const windowDesignLines = windowDesign.split(EOL)\n windowDesignLines.forEach((line, index) => {\n this.CM.Screen.cursorTo(centerScreen + this.offsetX, this.marginTop + index + this.offsetY)\n this.CM.Screen.write({ text: line, style: { color: \"white\" } })\n })\n this.absoluteValues = {\n x: centerScreen + this.offsetX,\n y: this.marginTop + this.offsetY,\n width: windowWidth,\n height: windowDesignLines.length,\n }\n return this\n }\n}\n\nexport default ButtonPopup", "import { KeyListenerArgs } from \"../../ConsoleGui.js\"\nimport ButtonPopup from \"./ButtonPopup.js\"\n\n/**\n * @description The configuration for the ConfirmPopup class.\n * @typedef {Object} ConfirmPopupConfig\n * \n * @prop {string} id - The id of the popup.\n * @prop {string} title - The title of the popup.\n * @prop {string} [message] - The message of the popup.\n *\n * @export\n * @interface ConfirmPopupConfig\n */\n// @type definition\nexport interface ConfirmPopupConfig {\n id: string,\n title: string,\n message?: string,\n}\n\n/**\n * @class ConfirmPopup\n * @extends ButtonPopup\n * @description This class is an overload of ButtonPopup that is used to create a popup with That asks for a confirm [Yes, No]. \n * \n * \n * \n * Emits the following events: \n * - \"confirm\" when the user confirm\n * - \"cancel\" when the user cancel\n * - \"exit\" when the user exit\n * @param {ConfirmPopupConfig} config - The configuration of the popup.\n * \n * @example ```ts\n * const popup = new ConfirmPopup({\n * id: \"popup1\", \n * title: \"Are you shure\",\n * }) \n * popup.show() // show the popup\n * popup.on(\"confirm\", (answer) => {\n * console.log(console.log(answer))\n * })\n * ```\n */\nexport class ConfirmPopup extends ButtonPopup {\n public constructor(config: ConfirmPopupConfig) {\n if (!config) throw new Error(\"The config is not defined\")\n const { id, title, message } = config\n super({\n id,\n title,\n message,\n buttons: [\"Yes\", \"No\"],\n visible: false,\n })\n super.keyListener = (_str: string, key : KeyListenerArgs) => {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n switch (key.name) {\n case \"left\":\n if (this.selected > 0 && this.selected <= this.buttons.length) {\n this.selected--\n } else {\n return\n }\n break\n case \"right\":\n if (this.selected >= 0 && this.selected < this.buttons.length - 1) {\n this.selected++\n } else {\n return\n }\n break\n case \"return\":\n {\n if (this.selected === 0) {\n this.emit(\"confirm\")\n } else {\n this.emit(\"cancel\")\n }\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"escape\":\n {\n this.emit(\"cancel\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"q\":\n {\n this.CM.emit(\"exit\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n default:\n break\n }\n this.CM.refresh()\n }\n }\n}\n\nexport default ConfirmPopup", "import { EventEmitter } from \"events\"\nimport { ConsoleManager, KeyListenerArgs, EOL } from \"../../ConsoleGui.js\"\nimport fs from \"fs\"\nimport path from \"path\"\nimport { MouseEvent } from \"../MouseManager.js\"\nimport { boxChars, PhisicalValues } from \"../Utils.js\"\n\n/**\n * @description The configuration for the FileSelectorPopup class.\n * @typedef {Object} FileSelectorPopupConfig\n * \n * @prop {string} id - The id of the file selector popup.\n * @prop {string} title - The title of the file selector popup.\n * @prop {string} basePath - The base path of the file selector popup.\n * @prop {boolean} [selectDirectory] - If the file selector popup can select directories.\n * @prop {Array<string>} [allowedExtensions] - The allowed extensions. If not set, all extensions are allowed.\n * @prop {boolean} [limitToPath] - If true, the user can select a directory. Otherwise, only files are selectable. When true, to enter a directory, the user must press the space key instead of the enter key.\n * @prop {boolean} [visible] - If the file selector popup is visible.\n *\n * @export\n * @interface FileSelectorPopupConfig\n */\n// @type definition\nexport interface FileSelectorPopupConfig {\n id: string, \n title: string, \n basePath: string, \n selectDirectory?: boolean, \n allowedExtensions ?: string[], \n limitToPath?: boolean, \n visible?: boolean\n}\n\n/**\n * @description The file descriptions for the file selector popup.\n * @typedef {Object} FileItemObject\n * @prop {string} name - The name of the file.\n * @prop {string} path - The path to the file.\n * @prop {\"dir\" | \"file\"} type - The type of the file.\n * @prop {string} text - The display text of the file.\n *\n * @interface FileItemObject\n */\ninterface FileItemObject { \n text: string; \n name: string; \n type: \"dir\" | \"file\"; \n path: string;\n}\n\n/**\n * @class FileSelectorPopup\n * @extends EventEmitter\n * @description This class is used to create a popup with a file input to select a file or a directory.\n * It will run a promise with fs.readdir to get the list of files and directories.\n * The user can select a file or a directory and the popup will be closed. \n * \n * \n * \n * Emits the following events: \n * - \"confirm\" when the user confirm the file or directory selection. The file or directory path is passed as parameter like this: {path: \"path/to/file\", name: \"file.ext\"}\n * - \"cancel\" when the user cancel the file or directory selection.\n * - \"exit\" when the user exit\n * @param {FileSelectorPopupConfig} config - The configuration for the FileSelectorPopup class.\n * \n * @example ```ts\n * const popup = new FileSelectorPopup({\n * id: \"popup1\",\n * title: \"Choose the file\",\n * basePath: \"./examples\"\n * }).show().on(\"confirm\", (selected) => {\n * console.log(selected)\n * }) // show the popup and wait for the user to confirm\n */\nexport class FileSelectorPopup extends EventEmitter {\n readonly CM: ConsoleManager\n readonly id: string\n title: string\n private basePath: string\n currentPath: string\n private selectDirectory: boolean\n private allowedExtensions: string[]\n private limitToPath: boolean\n private visible: boolean\n private marginTop: number\n private startIndex: number\n private selected: FileItemObject\n private options: FileItemObject[]\n private parsingMouseFrame = false\n /** @var {number} x - The x offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetX: number\n /** @var {number} y - The y offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetY: number\n private absoluteValues: PhisicalValues\n private dragging = false\n private dragStart: { x: number, y: number } = { x: 0, y: 0 }\n private focused = false\n\n public constructor(config: FileSelectorPopupConfig) {\n if (!config) throw new Error(\"The config is required\")\n const { id, title, basePath, selectDirectory = false, allowedExtensions = [], limitToPath = false, visible = false } = config\n if (!id) throw new Error(\"The id is required\")\n if (!title) throw new Error(\"The title is required\")\n if (!basePath) throw new Error(\"The basePath is required\")\n super()\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n this.id = id\n this.title = title\n this.basePath = basePath\n this.currentPath = basePath\n this.selectDirectory = selectDirectory\n this.allowedExtensions = allowedExtensions\n this.limitToPath = limitToPath\n this.visible = visible\n this.marginTop = 4\n this.startIndex = 0\n this.selected = { text: \"../\", name: \"../\", type: \"dir\", path: path.join(basePath, \"../\") }\n this.offsetX = 0\n this.offsetY = 0\n this.absoluteValues = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n }\n if (this.CM.popupCollection[this.id]) {\n this.CM.unregisterPopup(this)\n const message = `FileSelectorPopup ${this.id} already exists.`\n this.CM.error(message)\n throw new Error(message)\n }\n this.CM.registerPopup(this)\n this.options = [{ text: \"../\", name: \"../\", type: \"dir\", path: path.join(basePath, \"../\") }]\n this.updateList(this.basePath)\n }\n\n /**\n * @description This function is used to load the list of files and directories in the current path.\n it return a promise with the list of files and directories. The list is an array of objects like this:\n [{text: \"\uD83D\uDCC4 file.ext\", name: \"file.ext\", type: \"file\", path: \"path/to/file.ext\"}, {text: \"\uD83D\uDCC1 dir/\", name: \"dir\", type: \"dir\", path: \"path/to/dir\"}]\n * @param {string} dir - The path to load the list.\n * @returns {Promise<Array<object>>} The list of files and directories.\n * @memberof FileSelectorPopup\n */\n private listDir(dir: string): Promise<Array<FileItemObject>> {\n return new Promise((resolve, reject) => {\n fs.readdir(dir, (err, files) => {\n if (err) {\n reject(err)\n } else {\n resolve(files.map(file => {\n const filePath = path.join(dir, file)\n const stats = fs.statSync(filePath)\n const isDirectory = stats.isDirectory()\n //const isFile = stats.isFile()\n if (isDirectory) {\n return { text: `\uD83D\uDCC1 ${file}/`, name: file, type: \"dir\", path: filePath }\n } else {\n return { text: `\uD83D\uDCC4 ${file}`, name: file, type: \"file\", path: filePath }\n }\n }).filter(file => {\n const isAllowed = this.allowedExtensions.length === 0 || this.allowedExtensions.includes(path.extname(file.name))\n if (this.selectDirectory && file.type === \"file\") {\n return false\n }\n return isAllowed || file.type === \"dir\"\n }) as Array<FileItemObject>)\n }\n })\n })\n }\n\n /**\n * @description This function calls the updateList function and store the result to this.options, it also refresh the list of files and directories.\n * @param {string} _path - The path to load the list.\n * @memberof FileSelectorPopup\n */\n private updateList(_path: string) {\n if (this.limitToPath) {\n if (!path.resolve(_path).includes(path.resolve(this.basePath))) {\n return\n }\n }\n this.currentPath = _path\n this.listDir(this.currentPath).then((files) => {\n this.options = [{ text: \"../\", name: \"../\", type: \"dir\", path: path.join(this.currentPath, \"../\")} as FileItemObject].concat(files)\n this.setSelected(this.options[0])\n this.CM.refresh()\n })\n }\n\n private adaptOptions() {\n return this.options.slice(this.startIndex, this.startIndex + this.CM.Screen.height - this.marginTop - 6)\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when the popup is showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @param {string} str - The string of the input.\n * @param {Object} key - The key object.\n * @memberof FileSelectorPopup\n */\n public keyListener(_str: string, key: KeyListenerArgs) {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n const ind = this.options.indexOf(this.selected)\n switch (key.name) {\n case \"down\":\n this.setSelected(this.options[(ind + 1) % this.options.length])\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n if (this.selected === this.options[this.adaptOptions().length + this.startIndex]) {\n this.startIndex++\n }\n } else {\n this.startIndex = 0\n }\n break\n case \"up\":\n this.setSelected(this.options[(ind - 1 + this.options.length) % this.options.length])\n if (this.startIndex > 0 && this.selected === this.adaptOptions()[0]) {\n this.startIndex--\n }\n break\n case \"pagedown\":\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n this.setSelected(this.options[(ind + this.adaptOptions().length) % this.options.length])\n if (this.startIndex + this.adaptOptions().length < this.options.length) {\n this.startIndex += this.adaptOptions().length\n } else {\n this.startIndex = 0\n }\n } else {\n return\n }\n break\n case \"pageup\":\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n this.setSelected(this.options[(ind - this.adaptOptions().length + this.options.length) % this.options.length])\n if (this.startIndex > this.adaptOptions().length) {\n this.startIndex -= this.adaptOptions().length\n } else {\n this.startIndex = 0\n }\n } else {\n return\n }\n break\n case \"return\":\n {\n if (this.selectDirectory) {\n if (this.selected.type === \"dir\") {\n this.emit(\"confirm\", { path: this.selected.path, name: this.selected.name })\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n } else {\n if (this.selected.type === \"dir\") {\n this.updateList(this.selected.path)\n } else {\n this.emit(\"confirm\", { path: this.selected.path, name: this.selected.name })\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n }\n }\n break\n case \"space\":\n if (this.selected.type === \"dir\") {\n this.updateList(this.selected.path)\n }\n break\n case \"escape\":\n {\n this.emit(\"cancel\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"q\":\n {\n this.CM.emit(\"exit\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n default:\n break\n }\n this.CM.refresh()\n }\n\n /**\n * @description This function is used to get the selected option.\n * @returns {FileItemObject} The selected value of the popup.\n * @memberof FileSelectorPopup\n */\n public getSelected(): FileItemObject {\n return this.selected\n }\n\n /**\n * @description This function is used to change the selection of the popup. It also refresh the ConsoleManager.\n * @param {FileItemObject} selected - The new value of the selection.\n * @memberof FileSelectorPopup\n * @returns {FileSelectorPopup} The instance of the FileSelectorPopup.\n */\n private setSelected(selected : FileItemObject): FileSelectorPopup {\n this.selected = selected\n this.CM.refresh()\n return this\n }\n\n /**\n * @description This function is used to show the popup. It also register the key events and refresh the ConsoleManager.\n * @returns {FileSelectorPopup} The instance of the FileSelectorPopup.\n * @memberof FileSelectorPopup\n */\n public show(): FileSelectorPopup {\n if (!this.visible) {\n this.manageInput()\n this.visible = true\n this.CM.refresh()\n this.CM.unfocusOtherWidgets(this.id)\n }\n return this\n }\n\n /**\n * @description This function is used to hide the popup. It also unregister the key events and refresh the ConsoleManager.\n * @returns {FileSelectorPopup} The instance of the FileSelectorPopup.\n * @memberof FileSelectorPopup\n */\n public hide(): FileSelectorPopup {\n if (this.visible) {\n this.unManageInput()\n this.visible = false\n this.CM.restoreFocusInWidgets()\n this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to get the visibility of the popup.\n * @returns {boolean} The visibility of the popup.\n * @memberof FileSelectorPopup\n */\n public isVisible(): boolean {\n return this.visible\n }\n\n \n /**\n * @description This function is used to return the PhisicalValues of the popup (x, y, width, height).\n * @memberof FileSelectorPopup\n * @private\n * @returns {FileSelectorPopup} The instance of the FileSelectorPopup.\n * @memberof FileSelectorPopup\n */\n public getPosition(): PhisicalValues {\n return this.absoluteValues\n }\n\n /**\n * @description This function is used to add the FileSelectorPopup key listener callback to te ConsoleManager.\n * @returns {FileSelectorPopup} The instance of the FileSelectorPopup.\n * @memberof FileSelectorPopup\n */\n private manageInput(): FileSelectorPopup {\n // Add a command input listener to change mode\n this.CM.setKeyListener(this.id, this.keyListener.bind(this))\n if (this.CM.mouse) this.CM.setMouseListener(`${this.id}_mouse`, this.mouseListener.bind(this))\n return this\n }\n\n /**\n * @description This function is used to remove the FileSelectorPopup key listener callback to te ConsoleManager.\n * @returns {FileSelectorPopup} The instance of the FileSelectorPopup.\n * @memberof FileSelectorPopup\n */\n private unManageInput(): FileSelectorPopup {\n // Add a command input listener to change mode\n this.CM.removeKeyListener(this.id)\n if (this.CM.mouse) this.CM.removeMouseListener(`${this.id}_mouse`)\n return this\n }\n\n /**\n * @description This function is used to manage the mouse events on the OptionPopup.\n * @param {MouseEvent} event - The string of the input.\n * @memberof OptionPopup\n */\n private mouseListener = (event: MouseEvent) => {\n const x = event.data.x\n const y = event.data.y\n\n //this.CM.log(event.name)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + this.absoluteValues.height) {\n // The mouse is inside the popup\n //this.CM.log(\"Mouse inside popup\")\n if (event.name === \"MOUSE_WHEEL_DOWN\") {\n const ind = this.options.indexOf(this.selected)\n this.setSelected(this.options[(ind + 1) % this.options.length])\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n if (this.selected === this.options[this.adaptOptions().length + this.startIndex]) {\n this.startIndex++\n }\n } else {\n this.startIndex = 0\n }\n this.focused = true\n } else if (event.name === \"MOUSE_WHEEL_UP\") {\n const ind = this.options.indexOf(this.selected)\n this.setSelected(this.options[(ind - 1 + this.options.length) % this.options.length])\n if (this.startIndex > 0 && this.selected === this.adaptOptions()[0]) {\n this.startIndex--\n }\n this.focused = true\n } else if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n // find the selected index of the click and set it as selected\n const index = y - this.absoluteValues.y - 4\n if (index >= 0 && index < this.adaptOptions().length) {\n this.setSelected(this.options[this.startIndex + index])\n }\n this.focused = true\n }\n } else {\n this.focused = false\n }\n if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === false && this.focused) {\n // check if the mouse is on the header of the popup (first three lines)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + 3/* 3 = header height */) {\n this.dragging = true\n this.dragStart = { x: x, y: y }\n }\n } else if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === true) {\n if ((y - this.dragStart.y) + this.absoluteValues.y < 0) {\n return // prevent the popup to go out of the top of the screen\n }\n if ((x - this.dragStart.x) + this.absoluteValues.x < 0) {\n return // prevent the popup to go out of the left of the screen\n }\n this.offsetX += x - this.dragStart.x\n this.offsetY += y - this.dragStart.y\n this.dragStart = { x: x, y: y }\n this.CM.refresh()\n } else if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\" && this.dragging === true) {\n this.dragging = false\n this.CM.refresh()\n }\n }\n\n /**\n * @description This function is used to draw the FileSelectorPopup to the screen in the middle.\n * @returns {FileSelectorPopup} The instance of the FileSelectorPopup.\n * @memberof FileSelectorPopup\n */\n public draw(): FileSelectorPopup {\n // Change start index if selected is not in the adaptOptions return array\n const ind = this.adaptOptions().indexOf(this.selected)\n const ind1 = this.options.indexOf(this.selected)\n if (ind === -1) {\n this.startIndex = ind1 - this.adaptOptions().length + 1 > 0 ? ind1 - this.adaptOptions().length + 1 : 0\n }\n const offset = 2\n const maxOptionsLength = this.options.map((o) => o.text).reduce((max, option) => Math.max(max, option.length), 0)\n const windowWidth = maxOptionsLength > this.title.length ? maxOptionsLength + (2 * offset) : this.title.length + (2 * offset)\n const halfWidth = Math.round((windowWidth - this.title.length) / 2)\n\n let header = boxChars[\"normal\"].topLeft\n for (let i = 0; i < windowWidth; i++) {\n header += boxChars[\"normal\"].horizontal\n }\n header += `${boxChars[\"normal\"].topRight}${EOL}`\n header += `${boxChars[\"normal\"].vertical}${\" \".repeat(halfWidth)}${this.title}${\" \".repeat(windowWidth - halfWidth - this.title.length)}${boxChars[\"normal\"].vertical}${EOL}`\n header += `${boxChars[\"normal\"].left}${boxChars[\"normal\"].horizontal.repeat(windowWidth)}${boxChars[\"normal\"].right}${EOL}`\n\n let footer = boxChars[\"normal\"].bottomLeft\n for (let i = 0; i < windowWidth; i++) {\n footer += boxChars[\"normal\"].horizontal\n }\n footer += `${boxChars[\"normal\"].bottomRight}${EOL}`\n\n let content = \"\"\n this.adaptOptions().forEach((option) => {\n content += `${boxChars[\"normal\"].vertical}${option.name === this.selected.name ? \"<\" : \" \"} ${option.text}${option.name === this.selected.name ? \" >\" : \" \"}${\" \".repeat(windowWidth - option.text.toString().length - 4)}${boxChars[\"normal\"].vertical}${EOL}`\n })\n\n const windowDesign = `${header}${content}${footer}`\n const windowDesignLines = windowDesign.split(EOL)\n const centerScreen = Math.round((this.CM.Screen.width / 2) - (windowWidth / 2))\n windowDesignLines.forEach((line, index) => {\n this.CM.Screen.cursorTo(centerScreen + this.offsetX, this.marginTop + index + this.offsetY)\n this.CM.Screen.write({ text: line, style: { color: \"white\" } })\n })\n this.absoluteValues = {\n x: centerScreen + this.offsetX,\n y: this.marginTop + this.offsetY,\n width: windowWidth,\n height: windowDesignLines.length,\n }\n return this\n }\n}\n\nexport default FileSelectorPopup", "import { EventEmitter } from \"events\"\nimport { ConsoleManager, KeyListenerArgs, EOL } from \"../../ConsoleGui.js\"\nimport { MouseEvent } from \"../MouseManager.js\"\nimport { boxChars, PhisicalValues, visibleLength } from \"../Utils.js\"\n\n/**\n * @description The configuration for the InputPopup class.\n * @typedef {Object} InputPopupConfig\n *\n * @prop {string} id - The id of the popup.\n * @prop {string} title - The title of the popup.\n * @prop {string | number} value - The value of the popup.\n * @prop {boolean} numeric - If the input is numeric.\n * @prop {boolean} [visible] - If the popup is visible.\n * @prop {string} [placeholder] - Optional placeholder to show if empty\n * @prop {number} [maxLen] - Optional max length of the input (default 20). Set to 0 for no limit (not recommended). Since v3.4.0\n *\n * @export\n * @interface InputPopupConfig\n */\n// @type definition\nexport interface InputPopupConfig {\n id: string;\n title: string;\n value: string | number;\n numeric?: boolean;\n visible?: boolean;\n placeholder?: string;\n maxLen?: number;\n}\n\n/**\n * @class InputPopup\n * @extends EventEmitter\n * @description This class is used to create a popup with a text or numeric input.\n *\n * \n *\n * Emits the following events:\n * - \"confirm\" when the user confirm the input\n * - \"cancel\" when the user cancel the input\n * - \"exit\" when the user exit the input\n * @param {InputPopupConfig} config - The config of the popup.\n *\n * @example ```ts\n * const popup = new InputPopup({\n * id: \"popup1\",\n * title: \"Choose the number\",\n * value: selectedNumber,\n * numeric: true\n * }).show().on(\"confirm\", (value) => { console.log(value) }) // show the popup and wait for the user to confirm\n * ```\n */\nexport class InputPopup extends EventEmitter {\n readonly CM: ConsoleManager\n readonly id: string\n title: string\n value: string | number\n // Position of the cursor. 0-indexed (0 = before all the text)\n /** @var {number} cursorPos - Since v3.1.0 a blinking cursor has been added to InputPopup (thanks @Compositr) */\n cursorPos: number\n /** @var {setInterval} flashLoop - Since v3.1.0 a blinking cursor has been added to InputPopup (thanks @Compositr) */\n flashLoop = setInterval(() => {\n this.draw(); this.CM.refresh()\n }, 500)\n private numeric: boolean\n private visible: boolean\n private marginTop: number\n private parsingMouseFrame = false\n /** @var {number} x - The x offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetX: number\n /** @var {number} y - The y offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetY: number\n private absoluteValues: PhisicalValues\n private dragging = false\n private dragStart: { x: number; y: number } = { x: 0, y: 0 }\n private focused = false\n private placeholder?: string\n private maxLen: number\n\n public constructor(config: InputPopupConfig) {\n if (!config) throw new Error(\"InputPopup config is required\")\n const { id, title, value, numeric, visible = false } = config\n if (!id) throw new Error(\"InputPopup id is required\")\n if (!title) throw new Error(\"InputPopup title is required\")\n if (value === undefined) throw new Error(\"InputPopup value is required\")\n super()\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n this.id = id\n this.title = title\n this.value = value\n this.cursorPos = 0\n this.numeric = numeric || false\n this.visible = visible\n this.marginTop = 4\n this.offsetX = 0\n this.offsetY = 0\n this.absoluteValues = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n }\n this.placeholder = config.placeholder\n this.maxLen = config.maxLen || 20\n if (this.CM.popupCollection[this.id]) {\n this.CM.unregisterPopup(this)\n const message = `InputPopup ${this.id} already exists.`\n this.CM.error(message)\n throw new Error(message)\n }\n this.CM.registerPopup(this)\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when the input is numeric and it is showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @param {string} _str - The string of the input.\n * @param {Object} key - The key object.\n * @memberof InputPopup\n */\n public keyListenerNumeric(_str: string, key: KeyListenerArgs): void {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n let v = Number(this.value)\n if (Number.isNaN(v)) {\n v = 0\n }\n if (!Number.isNaN(Number(key.name))) {\n if (v.toString().length < this.maxLen || this.maxLen === 0) { // if maxLen is 0 there is no limit\n let tmp = this.value.toString()\n tmp += key.name\n this.value = Number(tmp)\n }\n // To change the sign I check for the keys \"+\" and \"-\"\n } else if (key.sequence === \"-\") {\n this.value = v * -1\n } else if (key.sequence === \"+\") {\n this.value = Math.abs(v)\n } else if (key.sequence === \".\" || key.sequence === \",\") {\n if (this.value.toString().indexOf(\".\") === -1) {\n this.value = v + \".\"\n }\n } else {\n switch (key.name) {\n case \"backspace\":\n // If backspace is pressed I remove the last character from the typed value\n if (this.value.toString().length > 0) {\n if (\n this.value.toString().indexOf(\".\") ===\n this.value.toString().length - 1\n ) {\n this.value = v.toString()\n } else if (\n this.value.toString().indexOf(\".\") ===\n this.value.toString().length - 2\n ) {\n this.value = this.value\n .toString()\n .slice(0, this.value.toString().length - 1)\n } else if (\n this.value.toString().indexOf(\"-\") === 0 &&\n this.value.toString().length === 2\n ) {\n this.value = 0\n } else {\n this.value = Number(\n v.toString().slice(0, v.toString().length - 1)\n )\n }\n }\n break\n case \"return\":\n {\n this.confirmDel()\n }\n break\n case \"escape\":\n {\n this.delete()\n }\n break\n case \"q\":\n {\n this.delete()\n }\n break\n default:\n break\n }\n }\n this.CM.refresh()\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when the input is text and it is showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @param {string} _str - The string of the input.\n * @param {Object} key - The key object.\n * @memberof InputPopup\n */\n public keyListenerText(_str: string, key: KeyListenerArgs): void {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n const v = this.value\n switch (key.name) {\n case \"backspace\":\n // If backspace is pressed I remove the last character from the typed value\n if (v.toString().length > 0) {\n this.value = v.toString().slice(0, v.toString().length - 1)\n }\n break\n case \"return\":\n {\n this.confirmDel()\n }\n break\n case \"escape\":\n {\n this.delete()\n }\n break\n case \"q\":\n {\n this.delete()\n }\n break\n case \"delete\":\n {\n // no-op for now\n }\n break\n case \"tab\":\n {\n // Add two spaces\n this.value = v.toString() + \" \"\n }\n break\n\n default:\n if ((visibleLength(v.toString()) < this.maxLen || this.maxLen === 0) && key.sequence.length === 1) {\n let tmp = v.toString()\n tmp += key.sequence\n this.value = tmp\n }\n break\n }\n this.CM.refresh()\n }\n\n /**\n * @description This function is used to get the value of the input.\n * @returns {string | number} The value of the input.\n * @memberof InputPopup\n */\n public getValue(): string | number {\n return this.value\n }\n\n /**\n * @description This function is used to change the value of the input. It also refresh the ConsoleManager.\n * @param {string | number} newValue - The new value of the input.\n * @memberof InputPopup\n * @returns {InputPopup} The instance of the InputPopup.\n */\n public setValue(newValue: string | number): this {\n this.value = newValue\n this.CM.refresh()\n return this\n }\n\n /**\n * @description This function is used to show the popup. It also register the key events and refresh the ConsoleManager.\n * @returns {InputPopup} The instance of the InputPopup.\n * @memberof InputPopup\n */\n public show(): InputPopup {\n if (!this.visible) {\n this.manageInput()\n this.visible = true\n this.CM.refresh()\n this.CM.unfocusOtherWidgets(this.id)\n }\n return this\n }\n\n /**\n * @description This function is used to hide the popup. It also unregister the key events and refresh the ConsoleManager.\n * @returns {InputPopup} The instance of the InputPopup.\n * @memberof InputPopup\n */\n public hide(): InputPopup {\n if (this.visible) {\n this.unManageInput()\n this.visible = false\n this.CM.restoreFocusInWidgets()\n this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to get the visibility of the popup.\n * @returns {boolean} The visibility of the popup.\n * @memberof InputPopup\n */\n public isVisible(): boolean {\n return this.visible\n }\n\n /**\n * @description This function is used to return the PhisicalValues of the popup (x, y, width, height).\n * @memberof InputPopup\n * @private\n * @returns {InputPopup} The instance of the InputPopup.\n * @memberof InputPopup\n */\n public getPosition(): PhisicalValues {\n return this.absoluteValues\n }\n\n /**\n * @description This function is used to add the InputPopup key listener callback to te ConsoleManager.\n * @returns {InputPopup} The instance of the InputPopup.\n * @memberof InputPopup\n */\n private manageInput(): InputPopup {\n // Add a command input listener to change mode\n if (this.numeric) {\n this.CM.setKeyListener(this.id, this.keyListenerNumeric.bind(this))\n } else {\n this.CM.setKeyListener(this.id, this.keyListenerText.bind(this))\n }\n if (this.CM.mouse)\n this.CM.setMouseListener(\n `${this.id}_mouse`,\n this.mouseListener.bind(this)\n )\n return this\n }\n\n /**\n * @description This function is used to remove the InputPopup key listener callback to te ConsoleManager.\n * @returns {InputPopup} The instance of the InputPopup.\n * @memberof InputPopup\n */\n private unManageInput(): InputPopup {\n // Add a command input listener to change mode\n if (this.numeric) {\n this.CM.removeKeyListener(\n this.id /*, this.keyListenerNumeric.bind(this)*/\n )\n } else {\n this.CM.removeKeyListener(this.id /*, this.keyListenerText.bind(this)*/)\n }\n if (this.CM.mouse) this.CM.removeMouseListener(`${this.id}_mouse`)\n return this\n }\n\n /**\n * @description This function is used to manage the mouse events on the OptionPopup.\n * @param {MouseEvent} event - The string of the input.\n * @memberof OptionPopup\n */\n private mouseListener = (event: MouseEvent) => {\n const x = event.data.x\n const y = event.data.y\n\n //this.CM.log(event.name)\n if (x > this.absoluteValues.x &&\n x < this.absoluteValues.x + this.absoluteValues.width &&\n y > this.absoluteValues.y &&\n y < this.absoluteValues.y + this.absoluteValues.height) {\n // The mouse is inside the popup\n //this.CM.log(\"Mouse inside popup\")\n if (event.name === \"MOUSE_WHEEL_DOWN\") {\n if (this.numeric) {\n this.value = Number(this.value) - 1\n this.CM.refresh()\n }\n this.focused = true\n } else if (event.name === \"MOUSE_WHEEL_UP\") {\n if (this.numeric) {\n this.value = Number(this.value) + 1\n this.CM.refresh()\n }\n this.focused = true\n } else if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n // find the selected index of the click and set it as selected\n this.focused = true\n }\n } else {\n this.focused = false\n }\n if (\n event.name === \"MOUSE_DRAG\" &&\n event.data.left === true &&\n this.dragging === false &&\n this.focused\n ) {\n // check if the mouse is on the header of the popup (first three lines)\n if (x > this.absoluteValues.x &&\n x < this.absoluteValues.x + this.absoluteValues.width &&\n y > this.absoluteValues.y &&\n y < this.absoluteValues.y + 3 /* 3 = header height */) {\n this.dragging = true\n this.dragStart = { x: x, y: y }\n }\n } else if (event.name === \"MOUSE_DRAG\" &&\n event.data.left === true &&\n this.dragging === true) {\n if (y - this.dragStart.y + this.absoluteValues.y < 0) {\n return // prevent the popup to go out of the top of the screen\n }\n if (x - this.dragStart.x + this.absoluteValues.x < 0) {\n return // prevent the popup to go out of the left of the screen\n }\n this.offsetX += x - this.dragStart.x\n this.offsetY += y - this.dragStart.y\n this.dragStart = { x: x, y: y }\n this.CM.refresh()\n } else if (\n event.name === \"MOUSE_LEFT_BUTTON_RELEASED\" &&\n this.dragging === true\n ) {\n this.dragging = false\n this.CM.refresh()\n }\n }\n\n /**\n * @description This function is used to draw the InputPopup to the screen in the middle.\n * @returns {InputPopup} The instance of the InputPopup.\n * @memberof InputPopup\n */\n public draw(): InputPopup {\n const offset = 2\n const windowWidth =\n this.title.length > this.value.toString().length\n ? this.title.length + 2 * offset\n : this.value.toString().length + 2 * offset + 1\n const halfWidth = Math.round((windowWidth - this.title.length) / 2)\n let header = boxChars[\"normal\"].topLeft\n for (let i = 0; i < windowWidth; i++) {\n header += boxChars[\"normal\"].horizontal\n }\n header += `${boxChars[\"normal\"].topRight}${EOL}`\n header += `${boxChars[\"normal\"].vertical}${\" \".repeat(halfWidth)}${this.title\n }${\" \".repeat(windowWidth - halfWidth - this.title.length)}${boxChars[\"normal\"].vertical\n }${EOL}`\n header += `${boxChars[\"normal\"].left}${boxChars[\"normal\"].horizontal.repeat(\n windowWidth\n )}${boxChars[\"normal\"].right}${EOL}`\n\n let footer = boxChars[\"normal\"].bottomLeft\n for (let i = 0; i < windowWidth; i++) {\n footer += boxChars[\"normal\"].horizontal\n }\n footer += `${boxChars[\"normal\"].bottomRight}${EOL}`\n\n const windowDesign = `${header}${footer}`\n const windowDesignLines = windowDesign.split(EOL)\n const centerScreen = Math.round(this.CM.Screen.width / 2 - windowWidth / 2)\n windowDesign.split(EOL).forEach((line, index) => {\n this.CM.Screen.cursorTo(\n centerScreen + this.offsetX,\n this.marginTop + index + this.offsetY\n )\n \n if (index === 3) {\n const isOddSecond = Math.round(Date.now() / 100) % 2\n if (this.placeholder && this.placeholder.length && this.value.toString().length === 0) {\n const totalLength = 2 + this.placeholder.length + 1; // 2 for \"> \", 1 for cursor\n this.CM.Screen.write(\n { text: boxChars[\"normal\"].vertical, style: { color: \"white\" } },\n { text: \"> \", style: { color: \"cyan\" } },\n { text: isOddSecond ? \"\u2588\" : \" \", style: { color: \"white\" } },\n { text: this.placeholder, style: { color: \"gray\" } },\n { text: `${\" \".repeat(windowWidth - totalLength)}${boxChars[\"normal\"].vertical}`, style: { color: \"white\" } })\n } else {\n const totalLength = 2 + this.value.toString().length + 1; // 2 for \"> \", 1 for cursor\n this.CM.Screen.write(\n { text: boxChars[\"normal\"].vertical, style: { color: \"white\" } },\n { text: \"> \", style: { color: \"cyan\" } },\n { text: this.value.toString(), style: { color: \"white\" } },\n { text: isOddSecond ? \"\u2588\" : \" \", style: { color: \"white\" } },\n { text: `${\" \".repeat(windowWidth - totalLength)}${boxChars[\"normal\"].vertical}`, style: { color: \"white\" } })\n }\n this.CM.Screen.cursorTo(\n centerScreen + this.offsetX,\n this.marginTop + index + 1 + this.offsetY\n )\n }\n this.CM.Screen.write({ text: line, style: { color: \"white\" } })\n })\n this.absoluteValues = {\n x: centerScreen + this.offsetX,\n y: this.marginTop + this.offsetY,\n width: windowWidth,\n height: windowDesignLines.length,\n }\n return this\n }\n\n confirmDel() {\n this.emit(\"confirm\", this.numeric ? Number(this.value) : this.value)\n this.delete()\n }\n\n delete() {\n this.CM.unregisterPopup(this)\n this.hide()\n clearInterval(this.flashLoop)\n }\n}\n\nexport default InputPopup\n", "import { EventEmitter } from \"events\"\nimport { ConsoleManager, KeyListenerArgs, EOL } from \"../../ConsoleGui.js\"\nimport { MouseEvent } from \"../MouseManager.js\"\nimport { boxChars, PhisicalValues } from \"../Utils.js\"\n\n/**\n * @description The configuration for the OptionPopup class.\n * @typedef {Object} OptionPopupConfig\n * \n * @prop {string} id - The id of the popup.\n * @prop {string} title - The title of the popup.\n * @prop {Array<string | number>} options - The options of the popup.\n * @prop {string | number} selected - The selected option of the popup.\n * @prop {boolean} [visible] - If the popup is visible.\n *\n * @export\n * @interface OptionPopupConfig\n */\n// @type definition\nexport interface OptionPopupConfig {\n id: string\n title: string\n options: Array<string | number>\n selected: string | number\n visible?: boolean\n}\n\n/**\n * @class OptionPopup\n * @extends EventEmitter\n * @description This class is used to create a popup with a list of selectable options. \n * \n * \n * \n * Emits the following events: \n * - \"confirm\" when the user confirm the option\n * - \"cancel\" when the user cancel the option\n * - \"exit\" when the user exit the option\n * @param {string} id - The id of the popup.\n * @param {string} title - The title of the popup.\n * @param {Array<string | number>} options - The options of the popup.\n * @param {string | number} selected - The selected option.\n * @param {boolean} visible - If the popup is visible. Default is false (make it appears using show()).\n * \n * @example ```ts\n * const popup = new OptionPopup({\n * id:\"popup1\", \n * title: \"Choose the option\", \n * options, \n * selected\n * }).show().on(\"confirm\", (option) => { console.log(option) }) // show the popup and wait for the user to confirm\n * ```\n */\nexport class OptionPopup extends EventEmitter {\n readonly CM: ConsoleManager\n readonly id: string\n title: string\n private options: Array<string | number>\n private selected: string | number\n private visible: boolean\n private marginTop: number\n private startIndex: number\n private parsingMouseFrame = false\n /** @var {number} x - The x offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetX: number\n /** @var {number} y - The y offset of the popup to be drown. If 0 it will be placed on the center */\n private offsetY: number\n private absoluteValues: PhisicalValues\n private dragging = false\n private dragStart: { x: number, y: number } = { x: 0, y: 0 }\n private focused = false\n \n public constructor(config: OptionPopupConfig) {\n if (!config) throw new Error(\"OptionPopup config is required\")\n const { id, title, options, selected, visible = false } = config\n if (!id) throw new Error(\"OptionPopup id is required\")\n if (!title) throw new Error(\"OptionPopup title is required\")\n if (!options) throw new Error(\"OptionPopup options is required\")\n if (selected === undefined || selected === null) throw new Error(\"OptionPopup selected is required\")\n super()\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n this.id = id\n this.title = title\n this.options = options\n this.selected = selected\n this.visible = visible\n this.marginTop = 4\n this.startIndex = 0\n this.offsetX = 0\n this.offsetY = 0\n this.absoluteValues = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n }\n if (this.CM.popupCollection[this.id]) {\n this.CM.unregisterPopup(this)\n const message = `OptionPopup ${this.id} already exists.`\n this.CM.error(message)\n throw new Error(message)\n }\n this.CM.registerPopup(this)\n }\n\n private adaptOptions(): Array<string | number> {\n return this.options.slice(this.startIndex, this.startIndex + this.CM.Screen.height - this.marginTop - 6)\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when the popup is showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @param {string} str - The string of the input.\n * @param {Object} key - The key object.\n * @memberof OptionPopup\n */\n keyListener(_str: string, key: KeyListenerArgs) {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n switch (key.name) {\n case \"down\":\n this.setSelected(this.options[(this.options.indexOf(this.selected) + 1) % this.options.length])\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n if (this.selected === this.options[this.adaptOptions().length + this.startIndex]) {\n this.startIndex++\n }\n } else {\n this.startIndex = 0\n }\n break\n case \"up\":\n this.setSelected(this.options[(this.options.indexOf(this.selected) - 1 + this.options.length) % this.options.length])\n if (this.startIndex > 0 && this.selected === this.adaptOptions()[0]) {\n this.startIndex--\n }\n break\n case \"pagedown\":\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n this.setSelected(this.options[(this.options.indexOf(this.selected) + this.adaptOptions().length) % this.options.length])\n if (this.startIndex + this.adaptOptions().length < this.options.length) {\n this.startIndex += this.adaptOptions().length\n } else {\n this.startIndex = 0\n }\n } else {\n return\n }\n break\n case \"pageup\":\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n this.setSelected(this.options[(this.options.indexOf(this.selected) - this.adaptOptions().length + this.options.length) % this.options.length])\n if (this.startIndex > this.adaptOptions().length) {\n this.startIndex -= this.adaptOptions().length\n } else {\n this.startIndex = 0\n }\n } else {\n return\n }\n break\n case \"return\":\n {\n this.emit(\"confirm\", this.selected)\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"escape\":\n {\n this.emit(\"cancel\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n case \"q\":\n {\n this.CM.emit(\"exit\")\n this.CM.unregisterPopup(this)\n this.hide()\n //delete this\n }\n break\n default:\n break\n }\n this.CM.refresh()\n }\n\n /**\n * @description This function is used to get the selected option.\n * @returns {string | number} The selected value of the popup.\n * @memberof OptionPopup\n */\n public getSelected(): string | number {\n return this.selected\n }\n\n /**\n * @description This function is used to change the selection of the popup. It also refresh the ConsoleManager.\n * @param {string | number} selected - The new value of the selection.\n * @memberof OptionPopup\n * @returns {OptionPopup} The instance of the OptionPopup.\n */\n public setSelected(selected: string | number): OptionPopup {\n this.selected = selected\n this.CM.refresh()\n return this\n }\n\n /**\n * @description This function is used to show the popup. It also register the key events and refresh the ConsoleManager.\n * @returns {OptionPopup} The instance of the OptionPopup.\n * @memberof OptionPopup\n */\n public show(): OptionPopup {\n if (!this.visible) {\n this.manageInput()\n this.visible = true\n this.CM.refresh()\n this.CM.unfocusOtherWidgets(this.id)\n }\n return this\n }\n\n /**\n * @description This function is used to hide the popup. It also unregister the key events and refresh the ConsoleManager.\n * @returns {OptionPopup} The instance of the OptionPopup.\n * @memberof OptionPopup\n */\n public hide(): OptionPopup {\n if (this.visible) {\n this.unManageInput()\n this.visible = false\n this.CM.restoreFocusInWidgets()\n this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to get the visibility of the popup.\n * @returns {boolean} The visibility of the popup.\n * @memberof OptionPopup\n */\n public isVisible(): boolean {\n return this.visible\n }\n \n /**\n * @description This function is used to return the PhisicalValues of the popup (x, y, width, height).\n * @memberof OptionPopup\n * @private\n * @returns {OptionPopup} The instance of the OptionPopup.\n * @memberof OptionPopup\n */\n public getPosition(): PhisicalValues {\n return this.absoluteValues\n }\n\n /**\n * @description This function is used to add the OptionPopup key listener callback to te ConsoleManager.\n * @returns {OptionPopup} The instance of the OptionPopup.\n * @memberof OptionPopup\n */\n private manageInput(): OptionPopup {\n // Add a command input listener to change mode\n this.CM.setKeyListener(this.id, this.keyListener.bind(this))\n if (this.CM.mouse) this.CM.setMouseListener(`${this.id}_mouse`, this.mouseListener.bind(this))\n return this\n }\n\n /**\n * @description This function is used to remove the OptionPopup key listener callback to te ConsoleManager.\n * @returns {OptionPopup} The instance of the OptionPopup.\n * @memberof OptionPopup\n */\n private unManageInput(): OptionPopup {\n // Add a command input listener to change mode\n this.CM.removeKeyListener(this.id)\n if (this.CM.mouse) this.CM.removeMouseListener(`${this.id}_mouse`)\n return this\n }\n\n /**\n * @description This function is used to manage the mouse events on the OptionPopup.\n * @param {MouseEvent} event - The string of the input.\n * @memberof OptionPopup\n */\n private mouseListener = (event: MouseEvent) => {\n const x = event.data.x\n const y = event.data.y\n\n //this.CM.log(event.name)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + this.absoluteValues.height) {\n // The mouse is inside the popup\n //this.CM.log(\"Mouse inside popup\")\n if (event.name === \"MOUSE_WHEEL_DOWN\") {\n this.setSelected(this.options[(this.options.indexOf(this.selected) + 1) % this.options.length])\n if (this.CM.Screen.height - this.marginTop - 4 < this.options.length) {\n if (this.selected === this.options[this.adaptOptions().length + this.startIndex]) {\n this.startIndex++\n }\n } else {\n this.startIndex = 0\n }\n this.focused = true\n } else if (event.name === \"MOUSE_WHEEL_UP\") {\n this.setSelected(this.options[(this.options.indexOf(this.selected) - 1 + this.options.length) % this.options.length])\n if (this.startIndex > 0 && this.selected === this.adaptOptions()[0]) {\n this.startIndex--\n }\n this.focused = true\n } else if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n // find the selected index of the click and set it as selected\n const index = y - this.absoluteValues.y - 4\n if (index >= 0 && index < this.adaptOptions().length) {\n this.setSelected(this.options[this.startIndex + index])\n }\n this.focused = true\n }\n } else {\n this.focused = false\n }\n if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === false && this.focused) {\n // check if the mouse is on the header of the popup (first three lines)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y < this.absoluteValues.y + 3/* 3 = header height */) {\n this.dragging = true\n this.dragStart = { x: x, y: y }\n }\n } else if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === true) {\n if ((y - this.dragStart.y) + this.absoluteValues.y < 0) {\n return // prevent the popup to go out of the top of the screen\n }\n if ((x - this.dragStart.x) + this.absoluteValues.x < 0) {\n return // prevent the popup to go out of the left of the screen\n }\n this.offsetX += x - this.dragStart.x\n this.offsetY += y - this.dragStart.y\n this.dragStart = { x: x, y: y }\n this.CM.refresh()\n } else if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\" && this.dragging === true) {\n this.dragging = false\n this.CM.refresh()\n }\n }\n\n /**\n * @description This function is used to draw the OptionPopup to the screen in the middle.\n * @returns {OptionPopup} The instance of the OptionPopup.\n * @memberof OptionPopup\n */\n public draw(): OptionPopup {\n // Change start index if selected is not in the adaptOptions return array\n if (this.adaptOptions().indexOf(this.selected) === -1) {\n this.startIndex = this.options.indexOf(this.selected) - this.adaptOptions().length + 1 > 0 ? this.options.indexOf(this.selected) - this.adaptOptions().length + 1 : 0\n }\n const offset = 2\n const maxOptionsLength = this.options.map((o) => o.toString()).reduce((max, option) => Math.max(max, option.length), 0)\n const windowWidth = maxOptionsLength > this.title.length ? maxOptionsLength + (2 * offset) : this.title.length + (2 * offset)\n const halfWidth = Math.round((windowWidth - this.title.length) / 2)\n\n let header = boxChars[\"normal\"].topLeft\n for (let i = 0; i < windowWidth; i++) {\n header += boxChars[\"normal\"].horizontal\n }\n header += `${boxChars[\"normal\"].topRight}${EOL}`\n header += `${boxChars[\"normal\"].vertical}${\" \".repeat(halfWidth)}${this.title}${\" \".repeat(windowWidth - halfWidth - this.title.length)}${boxChars[\"normal\"].vertical}${EOL}`\n header += `${boxChars[\"normal\"].left}${boxChars[\"normal\"].horizontal.repeat(windowWidth)}${boxChars[\"normal\"].right}${EOL}`\n\n let footer = boxChars[\"normal\"].bottomLeft\n for (let i = 0; i < windowWidth; i++) {\n footer += boxChars[\"normal\"].horizontal\n \n }\n footer += `${boxChars[\"normal\"].bottomRight}${EOL}`\n\n let content = \"\"\n this.adaptOptions().forEach((option) => {\n content += `${boxChars[\"normal\"].vertical}${option === this.selected ? \"<\" : \" \"} ${option}${option === this.selected ? \" >\" : \" \"}${\" \".repeat(windowWidth - option.toString().length - 4)}${boxChars[\"normal\"].vertical}${EOL}`\n })\n\n const windowDesign = `${header}${content}${footer}`\n const windowDesignLines = windowDesign.split(EOL)\n const centerScreen = Math.round((this.CM.Screen.width / 2) - (windowWidth / 2))\n windowDesignLines.forEach((line, index) => {\n this.CM.Screen.cursorTo(centerScreen + this.offsetX, this.marginTop + index + this.offsetY)\n this.CM.Screen.write({ text: line, style: { color: \"white\" } })\n })\n this.absoluteValues = {\n x: centerScreen + this.offsetX,\n y: this.marginTop + this.offsetY,\n width: windowWidth,\n height: windowDesignLines.length,\n }\n return this\n }\n}\n\nexport default OptionPopup", "import { EventEmitter } from \"events\"\nimport { ConsoleManager, KeyListenerArgs, InPageWidgetBuilder } from \"../../ConsoleGui.js\"\nimport { MouseEvent, RelativeMouseEvent } from \"../MouseManager.js\"\nimport { PhisicalValues, StyledElement, truncate, visibleLength } from \"../Utils.js\"\n\n/**\n * @typedef {Object} ControlConfig\n * @property {string} id - The id of the control.\n * @property {PhisicalValues} attributes - The phisical values of the control.\n * @property {InPageWidgetBuilder} children - The children of the control.\n * @property {boolean} [visible=true] - If the control is visible or not.\n * @property {boolean} [draggable=false] - If the control is draggable or not.\n *\n * @export\n * @interface ControlConfig\n */\n// @type definition\nexport interface ControlConfig {\n id: string\n attributes: PhisicalValues\n children: InPageWidgetBuilder\n visible?: boolean\n draggable?: boolean\n}\n\n/**\n * @class Control\n * @extends EventEmitter\n * @description This class is used to create a custom control (widget) with That is showed in a\n * absolute position on the screen. It's a base class for all the controls (widgets).\n * \n * Emits the following events:\n * - \"mouse\": It carries the pure mouse event, but it fires only if the mouse is over the control.\n * - \"relativeMouse\": It's like the \"mouse\" event, but it carries the relative mouse X and Y (relative to the control).\n * \n * \n *\n * Emits the following events: \n * \n * @param {ControlConfig} config The configuration object for the control.\n * \n * @example ```ts\n * const widget1 = new InPageWidgetBuilder()\n * widget1.addRow({ text: \"\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\", color: \"yellow\", style: \"bold\" })\n * widget1.addRow({ text: \"\u2502 START! \u2502\", color: \"yellow\", style: \"bold\" })\n * widget1.addRow({ text: \"\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\", color: \"yellow\", style: \"bold\" })\n * \n * const button1 = new Control({\n * id: \"btn1\",\n * visible: false,\n * attributes: { x: 30, y: 18, width: 10, height: 3 },\n * children: widget1\n * })\n * button1.on(\"relativeMouse\", (event) => {\n * // The relative mouse event is triggered with the mouse position relative to the widget\n * //console.log(`Mouse event: x: ${event.data.x}, y: ${event.data.y}`)\n * if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\") {\n * GUI.log(\"Button 1 clicked!\")\n * if (valueEmitter) {\n * clearInterval(valueEmitter)\n * valueEmitter = null\n * } else {\n * valueEmitter = setInterval(frame, period)\n * }\n * }\n * })\n * button1.show()\n * ```\n */\nexport class Control extends EventEmitter {\n CM: ConsoleManager\n id: string\n visible: boolean\n private parsingMouseFrame = false\n absoluteValues: PhisicalValues = { x: 0, y: 0, width: 0, height: 0 }\n children: InPageWidgetBuilder\n draggable = true\n dragging = false\n private dragStart: { x: number, y: number } = { x: 0, y: 0 }\n focused = false\n hovered = false\n\n public constructor(config: ControlConfig) {\n if (!config) {\n throw new Error(\"The configuration object is required.\")\n } \n if (!config.id) {\n throw new Error(\"The id is required.\")\n } \n if (!config.attributes) {\n throw new Error(\"The attributes are required.\")\n } \n if (!config.children) {\n throw new Error(\"The children are required.\")\n }\n super()\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n this.id = config.id\n this.visible = config.visible || true\n this.absoluteValues = config.attributes\n this.children = config.children\n if (this.CM.controlsCollection[this.id]) {\n this.CM.unregisterControl(this)\n const message = `Control ${this.id} already exists.`\n this.CM.error(message)\n throw new Error(message)\n }\n this.CM.registerControl(this)\n if (this.visible) {\n this.manageInput()\n this.CM.refresh()\n }\n }\n\n /**\n * @description This function is used to delete the Control and remove it from the ConsoleManager.\n *\n * @memberof Control\n */\n public delete() {\n this.unfocus()\n this.hide()\n this.CM.unregisterControl(this)\n }\n\n /**\n * @description This function is used to make the ConsoleManager handle the key events when the popup is showed.\n * Inside this function are defined all the keys that can be pressed and the actions to do when they are pressed.\n * @param {string} _str - The string of the input.\n * @param {any} key - The key object.\n * @memberof Control\n */\n public keyListener(_str: string, key: KeyListenerArgs): void {\n const checkResult = this.CM.mouse.isMouseFrame(key, this.parsingMouseFrame)\n if (checkResult === 1) {\n this.parsingMouseFrame = true\n return\n } else if (checkResult === -1) {\n this.parsingMouseFrame = false\n return\n } // Continue only if the result is 0\n switch (key.name) {\n case \"return\":\n // TODO\n break\n case \"escape\":\n this.unfocus()\n break\n default:\n break\n }\n this.emit(\"keypress\", key)\n this.CM.refresh()\n }\n\n /**\n * getContent()\n * @description This function is used to get the content of the Control.\n * @returns {InPageWidgetBuilder} The content of the Control.\n * @memberof Control\n * @example ```ts\n * const content = control.getContent()\n * ```\n */\n public getContent(): InPageWidgetBuilder {\n return this.children\n }\n\n /**\n * @description This function is used to focus the Control. It also register the key events.\n * @returns {Control} The instance of the Control.\n * @memberof Control\n */\n public focus(): Control {\n if (this.visible && !this.focused) {\n this.focused = true\n this.manageInput()\n //this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to unfocus the Control. It also unregister the key events.\n * @returns {Control} The instance of the Control.\n * @memberof Control\n */\n public unfocus(): Control {\n if (this.visible && this.focused) {\n this.unManageInput()\n this.focused = false\n //this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to show the Control. It also register the mouse events and refresh the ConsoleManager.\n * @returns {Control} The instance of the Control.\n * @memberof Control\n */\n public show(): Control {\n if (!this.visible) {\n this.manageInput()\n this.visible = true\n this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to hide the Control. It also unregister the mouse events and refresh the ConsoleManager.\n * @returns {Control} The instance of the Control.\n * @memberof Control\n */\n public hide(): Control {\n if (this.visible) {\n this.unManageInput()\n this.visible = false\n this.CM.refresh()\n }\n return this\n }\n\n /**\n * @description This function is used to get the visibility of the Control.\n * @returns {boolean} The visibility of the Control.\n * @memberof Control\n */\n public isVisible(): boolean {\n return this.visible\n }\n\n /**\n * @description This function is used to get the focus status of the Control.\n * @returns {boolean} The focused status of the Control.\n * @memberof Control\n */\n public isFocused(): boolean {\n return this.focused\n }\n\n /**\n * @description This function is used to add the Control key listener callback to te ConsoleManager.\n * @returns {Control} The instance of the Control.\n * @memberof Control\n */\n private manageInput(): Control {\n this.CM.setKeyListener(this.id, this.keyListener.bind(this))\n if (this.CM.mouse) this.CM.setMouseListener(`${this.id}_mouse`, this.mouseListener.bind(this))\n return this\n }\n\n /**\n * @description This function is used to remove the Control key listener callback to te ConsoleManager.\n * @returns {Control} The instance of the Control.\n * @memberof Control\n */\n private unManageInput(): Control {\n this.CM.removeKeyListener(this.id)\n if (this.CM.mouse) this.CM.removeMouseListener(`${this.id}_mouse`)\n return this\n }\n\n /**\n * @description This function is used to manage the mouse events on the Control.\n * @param {MouseEvent} event - The string of the input.\n * @memberof Control\n */\n private mouseListener = (event: MouseEvent) => {\n const x = event.data.x\n const y = event.data.y\n\n //this.CM.log(event.name)\n if (x > this.absoluteValues.x && x < this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y <= this.absoluteValues.y + this.absoluteValues.height) {\n // The mouse is inside the popup\n //this.CM.log(\"Mouse inside popup\")\n // Check if there is no popup over this control\n const popups = Object.keys(this.CM.popupCollection)\n for (let i = popups.length - 1; i >= 0; i--) {\n const popup = this.CM.popupCollection[popups[i]]\n if (popup.isVisible() && popup.getPosition) {\n const popupPosition = popup.getPosition()\n if (x > popupPosition.x && x < popupPosition.x + popupPosition.width \n && y > popupPosition.y && y < popupPosition.y + popupPosition.height) {\n // There is a popup under this control\n //this.CM.log(\"Popup under this control\")\n return\n }\n }\n }\n this.emit(\"mouse\", event)\n const relativeMouseEvent = {\n name: event.name,\n data: {\n x: x - this.absoluteValues.x,\n y: y - this.absoluteValues.y\n }\n } as RelativeMouseEvent\n this.emit(\"relativeMouse\", relativeMouseEvent)\n // class can handle the mouse event without overriding this function\n if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n if (!this.focused) {\n this.focused = true\n }\n return\n }\n if (event.name === \"MOUSE_MOTION\") {\n this.focused = true\n if (!this.hovered) this.hovered = true\n }\n } else {\n if (event.name !== \"MOUSE_MOTION\") this.focused = false // only if you click outside the widget\n if (this.hovered) {\n this.hovered = false\n this.emit(\"hoverOut\", event)\n }\n }\n if (!this.draggable) return\n if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === false && this.focused) {\n // check if the mouse is on the header of the popup (first three lines)\n if (x > this.absoluteValues.x && x <= this.absoluteValues.x + this.absoluteValues.width && y > this.absoluteValues.y && y <= this.absoluteValues.y + this.absoluteValues.height) {\n this.dragging = true\n this.dragStart = { x: x, y: y }\n }\n } else if (event.name === \"MOUSE_DRAG\" && event.data.left === true && this.dragging === true) {\n if ((y - this.dragStart.y) + this.absoluteValues.y < 0) {\n return // prevent the popup to go out of the top of the screen\n }\n if ((x - this.dragStart.x) + this.absoluteValues.x < 0) {\n return // prevent the popup to go out of the left of the screen\n }\n this.absoluteValues.x += x - this.dragStart.x\n this.absoluteValues.y += y - this.dragStart.y\n this.dragStart = { x: x, y: y }\n this.CM.refresh()\n } else if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\" && this.dragging === true) {\n this.dragging = false\n this.CM.refresh()\n }\n }\n\n /**\n * @description This function is used to draw a single line of the widget to the screen. It also trim the line if it is too long.\n * @param {Array<StyledElement>} line the line to be drawn\n * @memberof Control\n * @returns {void}\n */\n private drawLine(line: Array<StyledElement>): void {\n let unformattedLine = \"\"\n let newLine = [...line]\n\n line.forEach((element: { text: string; }) => {\n unformattedLine += element.text\n })\n\n if (visibleLength(unformattedLine) > this.absoluteValues.width) {\n const offset = 2\n newLine = [...JSON.parse(JSON.stringify(line))] // Shallow copy because I just want to modify the values but not the original\n\n let diff = visibleLength(unformattedLine) - this.CM.Screen.width + 1\n\n // remove truncated text\n for (let j = newLine.length - 1; j >= 0; j--) {\n if (visibleLength(newLine[j].text) > diff + offset) {\n newLine[j].text = truncate(newLine[j].text, (visibleLength(newLine[j].text) - diff) - offset, true)\n break\n } else {\n diff -= visibleLength(newLine[j].text)\n newLine.splice(j, 1)\n }\n }\n // Update unformatted line\n unformattedLine = newLine.map((element: { text: string; }) => element.text).join(\"\")\n }\n if (visibleLength(unformattedLine) <= this.absoluteValues.width) {\n newLine.push({ text: `${\" \".repeat(this.absoluteValues.width - visibleLength(unformattedLine))}`, style: { color: \"\" } })\n }\n this.CM.Screen.write(...newLine)\n }\n\n /**\n * @description This function is used to draw the Control to the screen in the middle.\n * @returns {Control} The instance of the Control.\n * @memberof Control\n */\n public draw(): Control {\n this.children.getContent().forEach((line: StyledElement[], index: number) => {\n this.CM.Screen.cursorTo(this.absoluteValues.x, index + this.absoluteValues.y)\n this.drawLine(line)\n })\n return this\n }\n}\n\nexport default Control", "/* eslint-disable @typescript-eslint/no-empty-function */\nimport { ForegroundColorName } from \"chalk/source/vendor/ansi-styles/index.js\"\nimport InPageWidgetBuilder from \"../InPageWidgetBuilder.js\"\nimport { boxChars, HEX, PhisicalValues, RGB, StyledElement, styledToSimplifiedStyled, truncate, visibleLength } from \"../Utils.js\"\nimport Control from \"./Control.js\"\nimport { KeyListenerArgs } from \"../../ConsoleGui.js\"\nimport { RelativeMouseEvent } from \"../MouseManager.js\"\n\n/**\n * @description The configuration for the Box class.\n * @typedef {Object} BoxConfig\n * \n * @prop {string} id - The id of the box.\n * @prop {number} x - The x position of the box.\n * @prop {number} y - The y position of the box.\n * @prop {number} [width] - The width of the box.\n * @prop {number} [height] - The height of the box.\n * @prop {BoxStyle} [style] - The style of the box.\n * @prop {boolean} [visible] - If the box is visible.\n * @prop {boolean} [draggable] - If the box is draggable.\n *\n * @export\n * @interface BoxConfig\n */\n// @type definition\nexport interface BoxConfig {\n id: string,\n x: number,\n y: number,\n width?: number,\n height?: number,\n style?: BoxStyle,\n visible?: boolean,\n draggable?: boolean,\n}\n\n/**\n * @description The style of the box.\n * @typedef {Object} BoxStyle\n * \n * @prop {boolean} [boxed] - If the box is boxed.\n * @prop {chalk.ForegroundColorName | HEX | RGB | \"\"} [color] - The color of the box.\n * @prop {string} [label] - The label of the box.\n *\n * @export\n * @interface BoxStyle\n */\n// @type definition\nexport interface BoxStyle {\n boxed?: boolean,\n color?: ForegroundColorName | HEX | RGB | \"\",\n label?: string,\n}\n\n/**\n * @description The class that represents a box.\n * \n * \n * \n * Example of a box containing a list of process running on the computer.\n * \n * @param {BoxConfig} config - The configuration of the box.\n * \n * @example ```ts\n * const box = new Box({ \n * id: \"box\", \n * x: 0, \n * y: 0, \n * width: 10, \n * height: 5, \n * style: { boxed: true, color: \"red\", label: \"Box\" } \n * })\n * box.setContent(new InPageWidgetBuilder(5).addText(\"Hello World!\"))\n * ```\n *\n * @export\n * @class Box\n * @extends {Control}\n */\nexport class Box extends Control {\n public content: InPageWidgetBuilder\n private style: BoxStyle = {\n boxed: false,\n label: \"\",\n color: \"white\",\n }\n\n public constructor(config: BoxConfig) {\n if (!config.id) throw new Error(\"The id is required\")\n if (config.x === undefined || config.y === undefined) throw new Error(\"The x and y values are required\")\n const tmpSizes = { width: config.width || 10, height: config.height || 5 }\n const pv = { x: config.x, y: config.y, width: tmpSizes.width, height: tmpSizes.height } as PhisicalValues\n super({\n id: config.id, visible: config.visible || true, attributes: pv, children: new InPageWidgetBuilder(pv.height)\n })\n this.style.label = config.style?.label || \"\"\n this.style = config.style ? { ...this.style, ...config.style } : this.style\n this.content = new InPageWidgetBuilder(this.style.boxed ? this.absoluteValues.height - 2 : this.absoluteValues.height)\n this.draggable = config.draggable || false\n\n // Manage input events\n this.on(\"keypress\", (key: KeyListenerArgs) => {\n if (!this.focused) return\n if (key.name === \"up\") {\n this.content.increaseScrollIndex()\n this.update()\n } else if (key.name === \"down\") {\n this.content.decreaseScrollIndex()\n this.update()\n }\n })\n this.on(\"relativeMouse\", (e: RelativeMouseEvent) => {\n if (!this.focused) return\n if (e.name === \"MOUSE_WHEEL_UP\") {\n this.content.increaseScrollIndex()\n this.update()\n } else if (e.name === \"MOUSE_WHEEL_DOWN\") {\n this.content.decreaseScrollIndex()\n this.update()\n }\n })\n this.update()\n }\n\n /**\n * @description Draws a line inside the box. It keeps the style of the text.\n *\n * @private\n * @param {Array<StyledElement>} line\n * @memberof Box\n */\n private drawInnerLine(line: Array<StyledElement>): void {\n let unformattedLine = \"\"\n let newLine = [...line]\n\n line.forEach((element: { text: string; }) => {\n unformattedLine += element.text\n })\n\n if (visibleLength(unformattedLine) > this.absoluteValues.width) {\n const offset = 2\n newLine = [...JSON.parse(JSON.stringify(line))] // Shallow copy because I just want to modify the values but not the original\n\n let diff = visibleLength(unformattedLine) - this.absoluteValues.width + 1\n\n // remove truncated text\n for (let j = newLine.length - 1; j >= 0; j--) {\n if (visibleLength(newLine[j].text) > diff + offset) {\n newLine[j].text = truncate(newLine[j].text, (visibleLength(newLine[j].text) - diff) - offset, false)\n break\n } else {\n diff -= visibleLength(newLine[j].text)\n newLine.splice(j, 1)\n }\n }\n // Update unformatted line\n unformattedLine = newLine.map((element: { text: string; }) => element.text).join(\"\")\n\n if (this.style.boxed) {\n newLine.push({ text: `${\" \".repeat(this.absoluteValues.width - visibleLength(unformattedLine) - 1)}${boxChars[\"normal\"].vertical}`, style: { color: this.style.color } })\n }\n }\n if (visibleLength(unformattedLine) <= this.absoluteValues.width) {\n newLine.push({ text: `${\" \".repeat(this.absoluteValues.width - visibleLength(unformattedLine))}`, style: { color: \"\" } })\n }\n this.getContent().addRow(...newLine.map((element: StyledElement) => styledToSimplifiedStyled(element)))\n }\n\n /**\n * @description Sets the content of the box.\n *\n * @returns {Box}\n * @memberof Box\n */\n public update = () => {\n if (this.style.boxed) {\n const absVal = this.absoluteValues\n const truncatedText = this.style.label ? truncate(this.style.label, absVal.width - 2, false) : \"\"\n\n this.getContent().clear()\n this.getContent().addRow({ text: `${boxChars[\"normal\"].topLeft}${truncatedText}${boxChars[\"normal\"].horizontal.repeat(absVal.width - (2 + visibleLength(truncatedText)))}${boxChars[\"normal\"].topRight}`, color: this.style.color })\n for (let i = 0; i < absVal.height - 2; i++) {\n if (this.content.getViewedPageHeight() > i) {\n const rowlength = this.content.getContent()[i].reduce((acc, curr) => acc + visibleLength(curr.text), 0)\n const spaces = absVal.width - (rowlength + 2)\n const styledArr = [{ text: `${boxChars[\"normal\"].vertical}`, style: { color: this.style.color }}, ...this.content.getContent()[i], { text: `${\" \".repeat(spaces > 0 ? spaces : 0)}${boxChars[\"normal\"].vertical}`, style: { color: this.style.color } }] as StyledElement[]\n \n this.drawInnerLine(styledArr)\n }\n }\n this.getContent().addRow({ text: `${boxChars[\"normal\"].bottomLeft}${boxChars[\"normal\"].horizontal.repeat(absVal.width - 2)}${boxChars[\"normal\"].bottomRight}`, color: this.style.color })\n } else {\n this.getContent().clear()\n for (let i = 0; i < this.absoluteValues.height; i++) {\n if (this.content.getViewedPageHeight() > i) {\n this.drawInnerLine(this.content.getContent()[i])\n }\n }\n }\n this.CM.refresh()\n return this\n }\n\n /**\n * @description Sets the label of the box.\n *\n * @param {string} text\n * @returns {Box}\n * @memberof Box\n */\n public setLabel = (text: string): Box => {\n this.style.label = text\n this.update()\n return this\n }\n\n /**\n * @description Sets the style of the box.\n *\n * @param {BoxStyle} style\n * @returns {Box}\n * @memberof Box\n */\n public setStyle = (style: BoxStyle): Box => {\n this.style = style\n this.update()\n return this\n }\n\n /**\n * @description Sets the content of the box.\n *\n * @param {InPageWidgetBuilder} content\n * @returns {Box}\n * @memberof Box\n */\n public setContent = (content: InPageWidgetBuilder): Box => {\n this.content = content\n this.content.setRowsPerPage(this.style.boxed ? this.absoluteValues.height - 2 : this.absoluteValues.height)\n this.update()\n return this\n }\n}\n\nexport default Box", "/* eslint-disable @typescript-eslint/no-empty-function */\nimport { BackgroundColorName, ForegroundColorName } from \"chalk/source/vendor/ansi-styles/index.js\"\nimport InPageWidgetBuilder from \"../InPageWidgetBuilder.js\"\nimport { boxChars, HEX, PhisicalValues, RGB, truncate } from \"../Utils.js\"\nimport Control from \"./Control.js\"\nimport { KeyListenerArgs } from \"../../ConsoleGui.js\"\n\n/**\n * @description The configuration object for the Button class\n * \n * @property {string} id The id of the button (required)\n * @property {string} text The text of the button (if not specified, it will be \"TEXT\")\n * @property {number} width The width of the button (if not specified, it will be the length of the text + 4)\n * @property {number} height The height of the button (if not specified, it will be 3)\n * @property {number} x The x position of the button (required)\n * @property {number} y The y position of the button (required)\n * @property {ButtonStyle} style The style of the button (if not specified, it will be { background: \"bgBlack\", borderColor: \"white\", color: \"white\", bold: true })\n * @property {ButtonKey} key The key to press to trigger the button\n * @property {function} onClick The function to call when the button is clicked\n * @property {function} onRelease The function to call when the button is released\n * @property {boolean} visible If the button is visible or not (default: true)\n * @property {boolean} enabled If the button is enabled or not (default: true)\n * @property {boolean} draggable If the button is draggable or not (default: false)\n *\n * @export\n * @interface ButtonConfig\n */\n// @type definition\nexport interface ButtonConfig {\n id: string,\n text: string,\n width?: number,\n height?: number,\n x: number,\n y: number,\n style?: ButtonStyle,\n key?: ButtonKey,\n onClick?: () => void,\n onRelease?: () => void,\n visible?: boolean,\n enabled?: boolean,\n draggable?: boolean,\n}\n\n/**\n * The configuration object for the ButtonKey class\n * @export ButtonKey\n * @interface ButtonKey\n * @property {string} name The name of the key (required)\n * @property {boolean} ctrl If the key is pressed with the ctrl key (default: false)\n * @property {boolean} shift If the key is pressed with the shift key (default: false)\n */\n// @type definition\nexport interface ButtonKey {\n name: string,\n ctrl?: boolean,\n shift?: boolean,\n meta?: boolean\n}\n\n/**\n * @description The configuration object for the ButtonStyle class\n * \n * @property {BackgroundColorName | HEX | RGB | \"\"} background The background color of the button (if not specified, it will be \"bgBlack\")\n * @property {ForegroundColorName | HEX | RGB | \"\"} borderColor The border color of the button (if not specified, it will be \"white\")\n * @property {ForegroundColorName | HEX | RGB | \"\"} color The text color of the button (if not specified, it will be \"white\")\n * @property {boolean} bold If the text is bold or not (default: true)\n * @property {boolean} italic If the text is italic or not (default: false)\n * @property {boolean} dim If the text is dim or not (default: false)\n * @property {boolean} underline If the text is underlined or not (default: false)\n * @property {boolean} inverse If the text is inverted or not (default: false)\n * @property {boolean} hidden If the text is hidden or not (default: false)\n * @property {boolean} strikethrough If the text is strikethrough or not (default: false)\n * @property {boolean} overline If the text is overlined or not (default: false)\n *\n * @export\n * @interface ButtonStyle\n */\n// @type definition\nexport interface ButtonStyle {\n background?: BackgroundColorName | HEX | RGB | \"\";\n borderColor?: ForegroundColorName | HEX | RGB | \"\";\n color?: ForegroundColorName | HEX | RGB | \"\";\n bold?: boolean;\n italic?: boolean;\n dim?: boolean;\n underline?: boolean;\n inverse?: boolean;\n hidden?: boolean;\n strikethrough?: boolean;\n overline?: boolean;\n}\n\n/**\n * @class Button\n * @extends Control\n * @description This class is an overload of Control that is used to create a button. \n * \n * \n * \n * Emits the following events: \n * - \"click\" when the user confirm\n * - \"relese\" when the user cancel\n * @param {ButtonConfig} config The configuration object\n * \n * @example ```js\n * new Button({\n id: \"btnRun\", \n text: \"Run me!\", \n x: 21, \n y: 18,\n style: {\n color: \"magentaBright\",\n bold: true,\n italic: true,\n borderColor: \"green\"\n },\n onRelease: () => {\n GUI.log(\"Button clicked!\")\n },\n draggable: true,\n })\n * ```\n */\nexport class Button extends Control {\n private text = \"TEXT\"\n private enabled = true\n private style: ButtonStyle = {\n background: \"bgBlack\",\n borderColor: \"white\",\n color: \"white\",\n bold: true\n }\n public onClick: () => void\n public onRelease: () => void\n private status: \"normal\" | \"hovered\" | \"selected\" = \"normal\"\n private key: ButtonKey | undefined\n\n public constructor(config: ButtonConfig) {\n const tmpSizes = { width: 0, height: 0 }\n if (!config.width) {\n tmpSizes.width = config.text.length + 4\n } else {\n tmpSizes.width = config.width\n }\n if (!config.height) {\n tmpSizes.height = 3\n } else {\n tmpSizes.height = config.height\n } \n if (!config.id) throw new Error(\"The id is required\")\n if (config.x === undefined || config.y === undefined) throw new Error(\"The x and y values are required\")\n const pv = { x: config.x, y: config.y, width: tmpSizes.width, height: tmpSizes.height } as PhisicalValues\n super({\n id: config.id, visible: config.visible || true, attributes: pv, children: new InPageWidgetBuilder()\n })\n this.text = config.text || \"TEXT\"\n this.enabled = config.enabled || true\n this.onClick = config.onClick || (() => { })\n this.onRelease = config.onRelease || (() => { })\n this.style = config.style? { ...this.style, ...config.style } : this.style\n this.draggable = config.draggable || false\n this.key = config.key ? { name: config.key.name, ctrl: config.key.ctrl || false, shift: config.key.shift || false, meta: config.key.meta || false } : undefined\n\n this.on(\"keypress\", (event: KeyListenerArgs) => {\n if (this.key) {\n if (event.name === this.key.name && event.ctrl === this.key.ctrl && event.shift === this.key.shift && event.meta === this.key.meta) {\n this.status = \"selected\"\n this.update()\n if (this.onClick) this.onClick.call(this)\n this.emit(\"click\")\n return\n }\n this.status = \"normal\"\n this.update()\n }\n })\n\n this.on(\"relativeMouse\", (event) => {\n if (!this.enabled) {\n return\n }\n if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n this.status = \"selected\"\n this.update()\n if (this.onClick) this.onClick.call(this)\n this.emit(\"click\")\n }\n if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\") {\n this.status = \"hovered\"\n this.update()\n if (this.onRelease) this.onRelease.call(this)\n this.emit(\"release\")\n }\n if (event.name === \"MOUSE_RIGHT_BUTTON_PRESSED\") {\n this.emit(\"rightClick\")\n }\n if (event.name === \"MOUSE_RIGHT_BUTTON_RELEASED\") {\n this.emit(\"rightRelease\")\n }\n if (event.name === \"MOUSE_MOTION\") {\n if (this.status === \"normal\") {\n this.status = \"hovered\"\n this.update()\n }\n }\n })\n this.on(\"hoverOut\", () => {\n this.status = \"normal\"\n this.update()\n })\n this.update()\n }\n\n /**\n * @description Used to draw the button to the content of the control.\n *\n * @returns {Button}\n * @memberof Button\n */\n public update = () => {\n const absVal = this.absoluteValues\n let truncatedText = truncate(this.text, absVal.width - 2, false)\n\n // add a white space to the end of the truncated text if the sum of the length of the text and the width of the button is odd\n if ((truncatedText.length + (absVal.width - 2)) % 2 === 1) {\n truncatedText += \" \"\n }\n\n this.getContent().clear()\n this.getContent().addRow({ text: `${boxChars[this.status].topLeft}${boxChars[this.status].horizontal.repeat(absVal.width - 2)}${boxChars[this.status].topRight}`, bg: this.style.background, color: this.style.borderColor, bold: this.style.bold })\n this.getContent().addRow(\n {\n text: `${boxChars[this.status].vertical}`,\n bg: this.style.background,\n color: this.style.borderColor,\n bold: this.style.bold\n },\n {\n text: `${\" \".repeat(((absVal.width - 2) - truncatedText.length) / 2)}${truncatedText}${\" \".repeat(((absVal.width - 2) - truncatedText.length) / 2)}`,\n bg: this.style.background,\n color: this.style.color,\n bold: this.style.bold,\n italic: this.style.italic,\n dim: this.style.dim,\n underline: this.style.underline,\n inverse: this.style.inverse,\n hidden: this.style.hidden,\n strikethrough: this.style.strikethrough,\n overline: this.style.overline\n },\n {\n text: `${boxChars[this.status].vertical}`,\n bg: this.style.background,\n color: this.style.borderColor,\n bold: this.style.bold\n }\n )\n this.getContent().addRow({ text: `${boxChars[this.status].bottomLeft}${boxChars[this.status].horizontal.repeat(absVal.width - 2)}${boxChars[this.status].bottomRight}`, bg: this.style.background, color: this.style.borderColor, bold: this.style.bold })\n this.CM.refresh()\n return this\n }\n\n /**\n * @description Used to set the text of the button.\n *\n * @param {string} text\n * @returns {Button}\n * @memberof Button\n */\n public setText = (text: string) => {\n this.text = text\n this.update()\n return this\n }\n\n /**\n * @description Used to set the style of the button.\n *\n * @param {ButtonStyle} style\n * @returns {Button}\n * @memberof Button\n */\n public setStyle = (style: ButtonStyle) => {\n this.style = style\n this.update()\n return this\n }\n\n /**\n * @description Used to set the enabled state of the button.\n *\n * @param {boolean} enabled\n * @returns {Button}\n * @memberof Button\n */\n public setEnabled = (enabled: boolean) => {\n this.enabled = enabled\n this.update()\n return this\n }\n}\n\nexport default Button", "/* eslint-disable @typescript-eslint/no-empty-function */\nimport { BackgroundColorName, ForegroundColorName } from \"chalk\"\nimport InPageWidgetBuilder from \"../InPageWidgetBuilder.js\"\nimport { boxChars, HEX, PhisicalValues, RGB, SimplifiedStyledElement/*, truncate*/ } from \"../Utils.js\"\nimport Control from \"./Control.js\"\n\n/** @const {Object} drawingChars - The characters used to draw the progress bar. */\nconst drawingChars = {\n \"precision\": {\n horizontal: {\n 100: { char: \"\u2588\", color: undefined },\n 88: { char: \"\u2589\", color: undefined },\n 75: { char: \"\u258A\", color: undefined },\n 63: { char: \"\u258B\", color: undefined },\n 50: { char: \"\u258C\", color: undefined },\n 38: { char: \"\u258D\", color: undefined },\n 25: { char: \"\u258E\", color: undefined },\n 13: { char: \"\u258F\", color: undefined },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n vertical: {\n 100: { char: \"\u2588\", color: undefined },\n 88: { char: \"\u2587\", color: undefined },\n 75: { char: \"\u2586\", color: undefined },\n 63: { char: \"\u2585\", color: undefined },\n 50: { char: \"\u2584\", color: undefined },\n 38: { char: \"\u2583\", color: undefined },\n 25: { char: \"\u2582\", color: undefined },\n 13: { char: \"\u2581\", color: undefined },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n block: {\n full: { char: \"\u2593\", color: undefined },\n half: { char: \"\u2592\", color: undefined },\n empty: { char: \"\u2591\", color: undefined },\n boxDrawing: boxChars.normal,\n labelStyle: undefined,\n valueStyle: undefined\n }\n },\n \"htop-light\": {\n horizontal: {\n 100: { char: \"\u2502\", color: \"#15a121\" },\n 75: { char: \"\u2502\", color: \"#c09c22\" },\n 50: { char: \"\u2502\", color: \"#0c37d6\" },\n 25: { char: \"\u2502\", color: \"#c40c26\" },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n vertical: {\n 100: { char: \"\u2500\", color: \"#15a121\" },\n 75: { char: \"\u2500\", color: \"#c09c22\" },\n 50: { char: \"\u2500\", color: \"#0c37d6\" },\n 25: { char: \"\u2500\", color: \"#c40c26\" },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n block: {\n full: { char: \"\u2588\", color: undefined },\n half: { char: \"\u2593\", color: undefined },\n empty: { char: \"\u2591\", color: undefined },\n boxDrawing: {\n left: \"[\",\n right: \"]\"\n } as typeof boxChars.normal,\n labelStyle: { color: \"#3d96da\", bold: false },\n valueStyle: { color: \"gray\", dim: true },\n }\n },\n \"htop-heavy\": {\n horizontal: {\n 100: { char: \"\u2503\", color: \"#15a121\" },\n 75: { char: \"\u2503\", color: \"#c09c22\" },\n 50: { char: \"\u2503\", color: \"#0c37d6\" },\n 25: { char: \"\u2503\", color: \"#c40c26\" },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n vertical: {\n 100: { char: \"\u2501\", color: \"#15a121\" },\n 75: { char: \"\u2501\", color: \"#c09c22\" },\n 50: { char: \"\u2501\", color: \"#0c37d6\" },\n 25: { char: \"\u2501\", color: \"#c40c26\" },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n block: {\n full: { char: \"\u2588\", color: undefined },\n half: { char: \"\u2593\", color: undefined },\n empty: { char: \"\u2591\", color: undefined },\n boxDrawing: {\n color: \"white\",\n left: \"[\",\n right: \"]\"\n } as typeof boxChars.normal,\n labelStyle: { color: \"#3d96da\", bold: true },\n valueStyle: { color: \"gray\", dim: true }\n }\n },\n \"htop\": {\n horizontal: {\n 100: { char: \"|\", color: \"#15a121\" },\n 75: { char: \"|\", color: \"#c09c22\" },\n 50: { char: \"|\", color: \"#0c37d6\" },\n 25: { char: \"|\", color: \"#c40c26\" },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n vertical: {//\u2015\u23AF\n 100: { char: \"\u2015\", color: \"#15a121\" },\n 75: { char: \"\u2015\", color: \"#c09c22\" },\n 50: { char: \"\u2015\", color: \"#0c37d6\" },\n 25: { char: \"\u2015\", color: \"#c40c26\" },\n 0: { char: \" \", color: undefined }\n } as { [key: number]: { char: string, color: ForegroundColorName | HEX | RGB | undefined } },\n block: {\n full: { char: \"\u2588\", color: undefined },\n half: { char: \"\u2593\", color: undefined },\n empty: { char: \"\u2591\", color: undefined },\n boxDrawing: {\n start: \"[\",\n end: \"]\"\n } as typeof boxChars.normal,\n labelStyle: { color: \"#3d96da\", bold: true },\n valueStyle: { color: \"gray\", dim: true }\n }\n }\n}\n\n/**\n * @description The configuration object for the progress class\n * \n * @property {string} id The id of the progress (required)\n * @property {number} length The length of the progress bar (required)\n * @property {number} thickness The thickness of the progress bar (required)\n * @property {number} x The x position of the progress bar (required)\n * @property {number} y The y position of the progress bar (required)\n * @property {number} [value] The value of the progress bar (optional)\n * @property {number} [min] The minimum value of the progress bar (optional)\n * @property {number} [max] The maximum value of the progress bar (optional)\n * @property {string} [unit] The unit of the progress bar (optional)\n * @property {number} [increment] The increment of the progress bar (optional)\n * @property {string} [label] The label of the progress bar (optional)\n * @property {ProgressStyle} [style] The style of the progress bar (optional)\n * @property {Orientation} orientation The orientation of the progress bar (required)\n * @property {boolean} [interactive] Whether the progress bar is interactive (optional)\n * @property {boolean} [visible] Whether the progress bar is visible (optional)\n * @property {boolean} [enabled] Whether the progress bar is enabled (optional)\n * @property {boolean} [draggable] Whether the progress bar is draggable (optional)\n *\n * @export\n * @interface ProgressConfig\n */\n// @type definition\nexport interface ProgressConfig {\n id: string;\n length: number;\n thickness: number;\n x: number;\n y: number;\n increment?: number;\n value?: number;\n min?: number;\n max?: number;\n unit?: string;\n label?: string;\n style?: ProgressStyle;\n orientation?: Orientation;\n interactive?: boolean;\n visible?: boolean;\n enabled?: boolean;\n draggable?: boolean;\n onValueChanged?: (value: number) => void;\n}\n\nexport type Orientation = \"horizontal\" | \"vertical\";\n\n/**\n * @description Defines the styles and settings for the progress bar\n * \n * @param {BackgroundColorName | HEX | RGB} background The background color of the progress bar\n * @param {ForegroundColorName | HEX | RGB} borderColor The color of the border\n * @param {ForegroundColorName | HEX | RGB} [textColor] The color of the text\n * @param {ForegroundColorName | HEX | RGB} color The color of the progress bar\n * @param {\"precision\" | \"htop\" | \"htop-light\" | \"htop-heavy\"} [theme] The theme to use for the progress bar [\"precision\", \"htop\", \"htop-light\", \"htop-heavy\"]\n * @param {boolean} [boxed] Whether or not to draw a box around the progress bar\n * @param {boolean} [showPercentage] Whether or not to show the percentage\n * @param {boolean} [showValue] Whether or not to show the value\n * @param {boolean} [showMinMax] Whether or not to show the min and max values\n * @param {boolean} [showTitle] Whether or not to show the title\n * @param {boolean} [bold] Whether or not to bold the text\n * @param {boolean} [italic] Whether or not to italicize the text\n * @param {boolean} [dim] Whether or not to dim the text\n * @param {boolean} [underline] Whether or not to underline the text\n * @param {boolean} [inverse] Whether or not to inverse the text\n * @param {boolean} [hidden] Whether or not to hide the text\n * @param {boolean} [strikethrough] Whether or not to strikethrough the text\n * @param {boolean} [overline] Whether or not to overline the text\n *\n * @export\n * @interface ProgressStyle\n */\n// @type definition\nexport interface ProgressStyle {\n background: BackgroundColorName | HEX | RGB;\n borderColor: ForegroundColorName | HEX | RGB;\n textColor?: ForegroundColorName | HEX | RGB;\n color: ForegroundColorName | HEX | RGB;\n theme?: keyof typeof drawingChars;\n boxed?: boolean;\n showPercentage?: boolean;\n showValue?: boolean;\n showMinMax?: boolean;\n showTitle?: boolean;\n bold?: boolean;\n italic?: boolean;\n dim?: boolean;\n underline?: boolean;\n inverse?: boolean;\n hidden?: boolean;\n strikethrough?: boolean;\n overline?: boolean;\n}\n\n/**\n * @class Progress\n * @extends Control\n * @description This class is an overload of Control that is used to create a Progress bar. \n * \n * \n * \n * Emits the following events: \n * - \"valueChanged\" when the user changes the value of the progress bar with the scroll wheel (if interactive is true).\n * - \"click\" when the user clicks on the progress bar (if interactive is true).\n * - \"relese\" when the user releases the mouse button on the progress bar (if interactive is true).\n * - \"rightClick\" when the user clicks on the progress bar with right button (if interactive is true).\n * - \"rightRelese\" when the user releases the right mouse button on the progress bar (if interactive is true).\n * \n * ### Example of interactive progress bar\n * \n * \n * @param {ProgressConfig} config The configuration object for the progress bar\n * \n * @example ```js\n * const pStyle = {\n * boxed: true,\n * showTitle: true,\n * showValue: true,\n * showPercentage: true,\n * showMinMax: false,\n * }\n * const p = new Progress({\n * id: \"prog1\", \n * x: 10, y: 2,\n * style: pStyle, \n * theme: \"htop\",\n * length: 25,\n * label: \"Mem\"\n * })\n * const incr = setInterval(() => {\n * const value = p.getValue() + 0.25\n * p.setValue(value)\n * if (value >= p.getMax()) {\n * clearInterval(incr)\n * }\n * }, 100)\n *\n * const p1Style = {\n * background: \"bgBlack\",\n * borderColor: \"yellow\",\n * color: \"green\",\n * boxed: true,\n * showTitle: true,\n * showValue: true,\n * showPercentage: true,\n * showMinMax: true,\n * }\n * const p1 = new Progress({\n * id: \"prog1\", \n * x: 10, y: 4,\n * style: pStyle, \n * theme: \"precision\",\n * length: 25,\n * label: \"Precision\"\n * })\n * const incr1 = setInterval(() => {\n * const value = p1.getValue() + 0.25\n * p1.setValue(value)\n * if (value >= p1.getMax()) {\n * clearInterval(incr1)\n * }\n * }, 100)\n * const p2Style = {\n * background: \"bgBlack\",\n * borderColor: \"yellow\",\n * color: \"magenta\",\n * boxed: true,\n * showTitle: true,\n * showValue: true,\n * showPercentage: true,\n * showMinMax: true,\n * }\n * const p2 = new Progress({\n * id: \"prog3\", \n * x: 10, y: 6,\n * style: pStyle, \n * theme: \"precision\",\n * length: 25,\n * label: \"Interactive\",\n * direction: \"vertical\",\n * interactive: true,\n * })\n * p2.on(\"valueChanged\", (value) => {\n * console.log(`Value changed: ${value}`)\n * })\n * ```\n */\nexport class Progress extends Control {\n private value: number\n private max: number\n private min: number\n private unit: string | undefined\n private length: number\n private thickness = 1\n private orientation: Orientation = \"horizontal\"\n private increment = 1\n private interactive = false\n private label = \"\"\n private enabled = true\n theme: keyof typeof drawingChars = \"precision\"\n private style: ProgressStyle = {\n background: \"bgBlack\",\n borderColor: \"white\",\n color: \"white\",\n textColor: \"white\",\n bold: true,\n boxed: true,\n showPercentage: true,\n showValue: true,\n showMinMax: true,\n showTitle: true,\n }\n private status: \"normal\" | \"hovered\" | \"selected\" = \"normal\"\n private onValueChanged: (value: number) => void = () => { }\n\n public constructor(config: ProgressConfig) {\n if (!config.id) throw new Error(\"The id is required\")\n if (config.x === undefined || config.y === undefined) throw new Error(\"The x and y values are required\")\n const orientation = config.orientation || \"horizontal\"\n const length = config.length || 20\n const thickness = config.thickness || 1\n let width = orientation === \"horizontal\" ? length : thickness\n let height = orientation === \"horizontal\" ? thickness : length\n if (config.style && config.style.boxed) {\n width += 2\n height += 2\n }\n const pv = { x: config.x, y: config.y, width, height } as PhisicalValues\n super({\n id: config.id, visible: config.visible || true, attributes: pv, children: new InPageWidgetBuilder()\n })\n this.id = config.id\n this.theme = config.style?.theme || this.theme\n this.enabled = config.enabled || true\n this.onValueChanged = config.onValueChanged || (() => { })\n this.style = config.style? { ...this.style, ...config.style } : this.style\n this.draggable = config.draggable || false\n this.interactive = config.interactive || false\n this.length = length\n this.thickness = thickness\n this.orientation = orientation\n this.increment = config.increment || 1\n this.value = config.value || 0\n this.max = config.max || 100\n this.min = config.min || 0\n this.label = config.label || \"\"\n this.unit = config.unit || undefined\n\n if (this.interactive) {\n this.on(\"relativeMouse\", (event) => {\n if (!this.enabled) {\n return\n }\n if (event.name === \"MOUSE_LEFT_BUTTON_PRESSED\") {\n this.status = \"selected\"\n this.update()\n this.emit(\"click\")\n }\n if (event.name === \"MOUSE_LEFT_BUTTON_RELEASED\") {\n this.status = \"hovered\"\n this.update()\n this.emit(\"release\")\n }\n if (event.name === \"MOUSE_RIGHT_BUTTON_PRESSED\") {\n this.emit(\"rightClick\")\n }\n if (event.name === \"MOUSE_RIGHT_BUTTON_RELEASED\") {\n this.emit(\"rightRelease\")\n }\n if (event.name === \"MOUSE_MOTION\") {\n if (this.status === \"normal\") {\n this.status = \"hovered\"\n //this.update()\n }\n }\n if (event.name === \"MOUSE_WHEEL_DOWN\") {\n if (this.value > this.min + 1) {\n this.value -= this.increment\n } else {\n this.value = this.min\n }\n this.emit(\"valueChanged\", this.value)\n if (this.onValueChanged) this.onValueChanged.call(this, this.value)\n this.update()\n }\n if (event.name === \"MOUSE_WHEEL_UP\") {\n if (this.value < this.max - 1) {\n this.value += this.increment\n } else {\n this.value = this.max\n }\n this.emit(\"valueChanged\", this.value)\n if (this.onValueChanged) this.onValueChanged.call(this, this.value)\n this.update()\n }\n })\n this.on(\"hoverOut\", () => {\n this.status = \"normal\"\n //this.update()\n })\n }\n\n this.update()\n }\n\n /**\n * @description This method is used to render the Progress. It only returns the styled element of the Progress Bar and not the container.\n * The progress bar is calculated based on the value, min and max.\n * It's drawn using the drawingChars property. It uses the full block character and in the last block it uses one of the fractions of the block.\n * for example: \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C (the last block is half full).\n * Every block can have 8 different states: 100%, 90%, 75%, 60%, 50%, 40%, 25% and 10%.\n * So the whole bar should be divided by the the number of blocks multiplied by 8.\n * @returns {SimplifiedStyledElement[][]} The styled element array of the Progress Bar.\n * \n * @example ```js\n * const p = this.getProgress() // returns the styled element array of the Progress Bar.\n * // p = [ {text: \"\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\", style: {background: \"bgBlack\", color: \"white\", bold: true}} ]\n * ```\n * @memberof Progress\n */\n private getProgress: () => SimplifiedStyledElement[][] = (): SimplifiedStyledElement[][] => {\n const styledProgress = [[]] as SimplifiedStyledElement[][]\n let percentage = (this.value / this.max) * 100\n if (percentage > 100) percentage = 100\n if (percentage < 0) percentage = 0\n\n const length = this.length\n const blocks = length * 8\n const blocksToFill = Math.round((percentage / 100) * blocks)\n // Now we need to calculate the percentage of the last block and it should be casted to one of the keys of the drawingChars.horizontal object.\n const lastBlockPercentage = Math.round((blocksToFill % 8) * 10)\n const fullBlocks = Math.floor(blocksToFill / 8)\n let emptyBlocks = length - fullBlocks - 1\n if (lastBlockPercentage === 0) {\n emptyBlocks = length - fullBlocks\n for (let i = 0; i < fullBlocks; i++) {\n styledProgress[0].push({\n text: drawingChars[this.theme][this.orientation][100].char,\n color: drawingChars[this.theme][this.orientation][100].color || this.style.color\n } as SimplifiedStyledElement)\n }\n } else {\n const lastBlockPercentageKey = Number(Object.keys(drawingChars[this.theme][this.orientation]).find(key => Number(key) >= lastBlockPercentage))\n const lastBlockPercentageValue = drawingChars[this.theme][this.orientation][Number(lastBlockPercentageKey)].char\n for (let i = 0; i < fullBlocks; i++) {\n styledProgress[0].push({\n text: drawingChars[this.theme][this.orientation][100].char,\n color: drawingChars[this.theme][this.orientation][100].color || this.style.color,\n } as SimplifiedStyledElement)\n }\n styledProgress[0].push({\n text: lastBlockPercentageValue,\n color: drawingChars[this.theme][this.orientation][lastBlockPercentageKey].color || this.style.color\n } as SimplifiedStyledElement)\n }\n for (let i = 0; i < emptyBlocks; i++) {\n styledProgress[0].push({\n text: drawingChars[this.theme][this.orientation][0].char,\n color: drawingChars[this.theme][this.orientation][0].color || this.style.color\n })\n }\n // copy each block to the other rows of the progress bar (thickness)\n for (let i = 1; i < this.thickness; i++) {\n styledProgress.push([...styledProgress[0]])\n }\n return styledProgress\n }\n\n /**\n * @description This method is used to render the Progress. It returns the styled element of the Progress Bar and the container.\n * \n * @returns {Progress} \n * @memberof Progress\n */\n public update = (): Progress => {\n const progress = this.getProgress()\n\n if (this.style.boxed) {\n if (Object.keys(drawingChars[this.theme].block.boxDrawing).includes(\"start\")) {\n progress[0].unshift({ text: drawingChars[this.theme].block.boxDrawing.start, color: drawingChars[this.theme].block.boxDrawing.color, bold: true })\n progress[0].push({ text: drawingChars[this.theme].block.boxDrawing.end, color: drawingChars[this.theme].block.boxDrawing.color, bold: true })\n } else {\n // disable eslint because we need to add the box drawing characters to the progress bar\n let ch = {} as typeof boxChars.normal\n if (this.orientation === \"vertical\") {\n const boxC = JSON.parse(JSON.stringify(drawingChars[this.theme].block.boxDrawing))\n // rotate the box drawing characters 90 degrees counter clockwise\n ch = {\n topLeft: boxC.bottomLeft,\n topRight: boxC.topLeft,\n bottomLeft: boxC.bottomRight,\n bottomRight: boxC.topRight,\n horizontal: boxC.vertical,\n vertical: boxC.horizontal,\n cross: boxC.cross,\n left: boxC.bottom,\n right: boxC.top,\n top: boxC.left,\n bottom: boxC.right\n } as typeof boxChars.normal\n } else {\n ch = drawingChars[this.theme].block.boxDrawing\n }\n\n progress.unshift([{ text: ch.topLeft, color: this.style.borderColor }])\n for (let i = 0; i < this.length; i++) {\n progress[0].push({ text: ch.horizontal, color: this.style.borderColor })\n }\n progress[0].push({ text: ch.topRight, color: this.style.borderColor })\n // add vertical char before and after the progress bar\n for (let i = 0; i < this.thickness; i++) {\n progress[i + 1].unshift({ text: ch.vertical, color: this.style.borderColor })\n progress[i + 1].push({ text: ch.vertical, color: this.style.borderColor })\n }\n // add the last line\n progress.push([{ text: ch.bottomLeft, color: this.style.borderColor }])\n for (let i = 0; i < this.length; i++) {\n progress[1 + this.thickness].push({ text: ch.horizontal, color: this.style.borderColor })\n }\n progress[1 + this.thickness].push({ text: ch.bottomRight, color: this.style.borderColor })\n }\n }\n\n // Add the text, value and percentage to the progress bar\n const size = progress.length\n const singleLine = size === 1\n const perc = Math.round((this.value / this.max) * 100)\n\n this.getContent().clear()\n if (this.orientation === \"horizontal\") {\n if (singleLine) {\n if (this.style.showTitle) progress[0].unshift({ text: this.label, ...drawingChars[this.theme].block.labelStyle } as SimplifiedStyledElement)\n if (this.style.showValue) {\n progress[0].push({ text: `${this.value.toFixed(2)}${this.unit ? this.unit : \"\"}`, ...drawingChars[this.theme].block.valueStyle } as SimplifiedStyledElement)\n if (this.style.showPercentage) progress[0].push({ text: \"/\", ...drawingChars[this.theme].block.valueStyle } as SimplifiedStyledElement)\n }\n if (this.style.showPercentage) progress[0].push({ text: `${perc}%`, ...drawingChars[this.theme].block.valueStyle } as SimplifiedStyledElement)\n if (this.style.showMinMax) progress.push([{ text: `(${this.min}/${this.max})`, ...drawingChars[this.theme].block.valueStyle } as SimplifiedStyledElement])\n } else {\n // all texts are added to a new line on the bottom of the progress bar\n const textLine = [] as SimplifiedStyledElement[]\n if (this.style.showTitle) textLine.push({ text: this.label, ...drawingChars[this.theme].block.labelStyle } as SimplifiedStyledElement)\n let valuesString = \" \"\n if (this.style.showValue) valuesString += `${this.value.toFixed(2)}${this.unit ? this.unit : \"\"}`\n if (this.style.showPercentage) valuesString += ` ${perc}%`\n if (this.style.showMinMax) valuesString += ` (${this.min}/${this.max})`\n if (valuesString.length > 0) textLine.push({ text: valuesString, ...drawingChars[this.theme].block.valueStyle } as SimplifiedStyledElement)\n \n progress.push(textLine)\n } \n this.absoluteValues.height = progress.length\n this.absoluteValues.width = progress[0].length\n progress.forEach((row: SimplifiedStyledElement[]) => {\n this.getContent().addRow(... row)\n })\n } else {\n this.absoluteValues.height = progress[0].length\n this.absoluteValues.width = progress.length\n // reverse the progress bar\n for (let i = progress[0].length - 1; i >= 0; i--) {\n const row: SimplifiedStyledElement[] = []\n const newthickness = progress.length\n for (let j = 0; j < newthickness; j++) {\n row.push(progress[j][i])\n }\n this.getContent().addRow(... row)\n }\n const textLine = [] as SimplifiedStyledElement[]\n if (this.style.showTitle) textLine.push({ text: this.label, ...drawingChars[this.theme].block.labelStyle } as SimplifiedStyledElement)\n let valuesString = \" \"\n if (this.style.showValue) valuesString += `${this.value.toFixed(2)}${this.unit ? this.unit : \"\"}`\n if (this.style.showPercentage) valuesString += ` ${perc}%`\n if (this.style.showMinMax) valuesString += ` (${this.min}/${this.max})`\n if (valuesString.length > 0) textLine.push({ text: valuesString, ...drawingChars[this.theme].block.valueStyle } as SimplifiedStyledElement)\n this.getContent().addRow(... textLine)\n }\n this.CM.refresh()\n return this\n }\n\n /**\n * @description Get the maximum value of the progress bar\n * \n * @returns {number} The maximum value of the progress bar\n * @memberof ProgressBar\n */\n public getMax = (): number => this.max\n\n /**\n * @description Get the minimum value of the progress bar\n *\n * @returns {number} The minimum value of the progress bar\n * @memberof Progress\n */\n public getMin = (): number => this.min\n\n /**\n * @description Get the value of the progress bar\n *\n * @returns {number} The value of the progress bar\n * @memberof Progress\n */\n public getValue = (): number => this.value\n\n /**\n * @description Get the length of the progress bar\n *\n * @returns {number} The length of the progress bar\n * @memberof Progress\n */\n public getLength = (): number => this.length\n\n /**\n * @description Get the progress bar thickness\n *\n * @returns {number} The progress bar thickness\n * @memberof Progress\n */\n public getThickness = (): number => this.thickness\n \n /**\n * @description Get the increment value\n *\n * @returns {number} The increment value\n * @memberof Progress\n */\n public getIncrement = (): number => this.increment \n\n /**\n * @description Sets the increment value\n *\n * @param {number} value The increment value\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setIncrement = (value: number) => {\n {\n const notNonNegativeNumber = typeof value !== \"number\" || Number.isNaN(value) || value <= 0\n if (notNonNegativeNumber) throw new TypeError(\"The \\\"increment\\\" value must a nonnegative number.\")\n }\n\n this.increment = value\n return this\n }\n\n /**\n * @description Sets the value of the progress bar\n *\n * @param {number} length The length of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setLength = (length: number) => {\n this.length = length\n if (this.orientation === \"horizontal\") {\n this.absoluteValues.width = length + (this.style.boxed ? 2 : 0)\n } else {\n this.absoluteValues.height = length + (this.style.boxed ? 2 : 0)\n }\n this.update()\n return this\n }\n\n /**\n * @description Sets the thickness of the progress bar\n *\n * @param {number} thickness The thickness of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setThickness = (thickness: number) => {\n this.thickness = thickness\n if (this.orientation === \"horizontal\") {\n this.absoluteValues.width = thickness + (this.style.boxed ? 2 : 0)\n } else {\n this.absoluteValues.height = thickness + (this.style.boxed ? 2 : 0)\n }\n this.update()\n return this\n }\n\n /**\n * @description Sets the value of the progress bar\n *\n * @param {number} value The value of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setValue = (value: number) => {\n if (value !== this.value) {\n this.value = value\n this.update()\n }\n return this\n }\n\n /**\n * @description Sets the maximum value of the progress bar\n *\n * @param {number} max The maximum value of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setMax = (max: number) => {\n if (max !== this.max) {\n this.max = max\n this.update()\n }\n return this\n }\n\n /**\n * @description Set the minimum value of the progress bar\n *\n * @param {number} min The minimum value of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setMin = (min: number) => {\n if (min !== this.min) {\n this.min = min\n this.update()\n }\n return this\n }\n\n /**\n * @description Sets the progress bar label and updates the progress bar\n *\n * @param {string} label The text of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setLabel = (label: string) => {\n this.label = label\n this.update()\n return this\n }\n\n /**\n * @description Sets the style of the progress bar and updates it\n *\n * @param {ProgressStyle} style The style of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setStyle = (style: ProgressStyle) => {\n this.style = style\n this.update()\n return this\n }\n\n /**\n * @description Sets the enabled state of the progress bar (if interactive)\n *\n * @param {boolean} enabled The enabled state of the progress bar\n * @returns {Progress} The progress bar instance\n * @memberof Progress\n */\n public setEnabled = (enabled: boolean) => {\n this.enabled = enabled\n this.update()\n return this\n }\n}\n\nexport default Progress\n", "import { ForegroundColorName } from \"chalk\"\nimport { ConsoleManager, PageBuilder } from \"../../ConsoleGui.js\"\nimport {\n boxChars,\n visibleLength,\n HEX,\n RGB,\n StyledElement,\n truncate,\n} from \"../Utils.js\"\n\n/**\n * @description The type containing all the possible options for the DoubleLayout.\n * @typedef {Object} DoubleLayoutOptions\n * @prop {boolean} [showTitle] - If the title should be shown.\n * @prop {boolean} [boxed] - If the layout should be boxed.\n * @prop {ForegroundColorName | HEX | RGB | \"\"} [boxColor] - The color of the box taken from the chalk library.\n * @prop {\"bold\"} [boxStyle] - If the border of the box should be bold.\n * @prop {string} [changeFocusKey] - The key that should be pressed to change the focus.\n * @prop {\"horizontal\" | \"vertical\"} [direction] - The direction of the layout.\n * @prop {string} [page1Title] - The title of the first page.\n * @prop {string} [page2Title] - The title of the second page.\n * @prop {number[]} [pageRatio] - The ratio of the pages. (in horizontal direction)\n * @prop {boolean} [fitHeight] - If the height of the pages should be the same.\n *\n * @export\n * @interface DoubleLayoutOptions\n */\n// @type definition\nexport interface DoubleLayoutOptions {\n showTitle?: boolean;\n boxed?: boolean;\n boxColor?: ForegroundColorName | HEX | RGB | \"\"; // add color list from chalk\n boxStyle?: \"bold\";\n changeFocusKey?: string;\n direction?: \"horizontal\" | \"vertical\";\n page1Title?: string;\n page2Title?: string;\n pageRatio?: [number, number];\n fitHeight?: boolean;\n}\n\n/**\n * @class DoubleLayout\n * @description This class is a layout that has two pages.\n *\n * \n *\n * @param {PageBuilder} page1 The first page.\n * @param {PageBuilder} page2 The second page.\n * @param {boolean} options Layout options.\n * @param {number} selected The selected page.\n * @example const layout = new DoubleLayout(page1, page2, true, 0)\n */\nexport class DoubleLayout {\n CM: ConsoleManager\n options: DoubleLayoutOptions\n selected: 0 | 1\n page1: PageBuilder\n page2: PageBuilder\n boxBold: boolean\n proportions: [number, number]\n page2Title: string\n page1Title: string\n realWidth: number | [number, number] = 0\n isOdd: boolean | undefined\n\n public constructor(\n page1: PageBuilder,\n page2: PageBuilder,\n options: DoubleLayoutOptions,\n selected: 0 | 1 = 0\n ) {\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n\n this.options = options\n this.selected = selected\n this.page1 = page1\n this.page2 = page2\n\n this.boxBold = this.options.boxStyle === \"bold\" ? true : false\n this.proportions = this.options.pageRatio || [0.7, 0.3]\n\n /** @const {string} page2Title The title of page2. */\n this.page2Title = this.options.page2Title || \"\"\n\n /** @const {string} page1Title The application title. */\n this.page1Title = this.options.page1Title || \"\"\n }\n\n /**\n * @description This function is used to overwrite the page content.\n * @param {PageBuilder} page the page to be added\n * @memberof DoubleLayout\n */\n public setPage(page: PageBuilder, index: number): void {\n if (index == 0) {\n this.page1 = page\n } else {\n this.page2 = page\n }\n }\n\n /**\n * @description This function is used to overwrite the page content.\n * @param {PageBuilder} page the page to be added\n * @memberof DoubleLayout\n */\n public setPage1(page: PageBuilder): void {\n this.page1 = page\n }\n\n /**\n * @description This function is used to overwrite the page content.\n * @param {PageBuilder} page the page to be added\n * @memberof DoubleLayout\n */\n public setPage2(page: PageBuilder): void {\n this.page2 = page\n }\n\n /**\n * @description This function is used to set the page titles.\n * @param {string[]} titles the titles of the pages\n * @memberof DoubleLayout\n * @example layout.setTitles([\"Page 1\", \"Page 2\"])\n */\n public setTitles(titles: string[]) {\n this.page1Title = titles[0]\n this.page2Title = titles[1]\n }\n\n /**\n * @description This function is used to set the page title at the given index.\n * @param {string} title the title of the page\n * @param {number} index the index of the page\n * @memberof DoubleLayout\n * @example layout.setTitle(\"Page 1\", 0)\n */\n public setTitle(title: string, index: number): void {\n if (index == 0) {\n this.page1Title = title\n } else {\n this.page2Title = title\n }\n }\n\n /**\n * @description This function is used to enable or disable the layout border.\n * @param {boolean} border enable or disable the border\n * @memberof DoubleLayout\n */\n public setBorder(border: boolean): void {\n this.options.boxed = border\n }\n\n /**\n * @description This function is used to choose the page to be highlighted.\n * @param {number} selected 0 for page1, 1 for page2\n * @memberof DoubleLayout\n */\n public setSelected(selected: 0 | 1): void {\n this.selected = selected\n }\n\n /**\n * @description This function is used to get the selected page.\n * @returns {number} 0 for page1, 1 for page2\n * @memberof DoubleLayout\n */\n public getSelected(): number {\n return this.selected\n }\n\n /**\n * @description This function is used to get switch the selected page.\n * @returns {void}\n * @memberof DoubleLayout\n */\n public changeLayout(): void {\n if (this.selected == 0) {\n this.selected = 1\n } else {\n this.selected = 0\n }\n }\n\n /**\n * @description This function is used to change the page ratio.\n * @param {Array<number>} ratio the ratio of pages\n * @memberof QuadLayout\n * @example layout.setRatio([0.4, 0.6])\n */\n public setRatio(ratio: [number, number]): void {\n this.proportions = ratio\n }\n\n /**\n * @description This function is used to increase the page ratio by the given ratio to add. (Only works if the direction is horizontal)\n * @param {number} quantity the ratio to add\n * @memberof QuadLayout\n * @example layout.increaseRatio(0.01)\n */\n public increaseRatio(quantity: number): void {\n if (this.options.direction == \"horizontal\") {\n if (this.proportions[0] < 0.9) {\n this.proportions[0] = Number(\n (this.proportions[0] + quantity).toFixed(2)\n )\n this.proportions[1] = Number(\n (this.proportions[1] - quantity).toFixed(2)\n )\n }\n }\n }\n\n /**\n * @description This function is used to decrease the page ratio by the given ratio to subtract. (Only works if the direction is horizontal).\n * @param {number} quantity the ratio to subtract\n * @memberof QuadLayout\n * @example layout.decreaseRatio(0.01)\n */\n public decreaseRatio(quantity: number): void {\n if (this.options.direction == \"horizontal\") {\n if (this.proportions[0] > 0.1) {\n this.proportions[0] = Number(\n (this.proportions[0] - quantity).toFixed(2)\n )\n this.proportions[1] = Number(\n (this.proportions[1] + quantity).toFixed(2)\n )\n }\n }\n }\n\n /**\n * @description This function is used to draw a single line of the layout to the screen. It also trim the line if it is too long.\n * @param {Array<StyledElement>} line the line to be drawn\n * @param {number} lineIndex the index of the selected line\n * @memberof DoubleLayout\n * @returns {void}\n */\n private drawLine(\n line: Array<StyledElement>,\n secondLine?: Array<StyledElement>,\n index = 0\n ): void {\n const dir =\n !this.options.direction || this.options.direction === \"vertical\"\n ? \"vertical\"\n : \"horizontal\"\n const bsize = this.options.boxed ? (dir === \"vertical\" ? 2 : 3) : 0\n let unformattedLine = [\"\"]\n let newLine = [[...line]]\n if (dir === \"vertical\") {\n line.forEach((element) => {\n unformattedLine[0] += element.text\n })\n } else {\n newLine = [[...line], [...(secondLine ? secondLine : line)]]\n unformattedLine.push(\"\")\n line.forEach((element: StyledElement) => {\n unformattedLine[0] += element.text\n })\n secondLine?.forEach((element: StyledElement) => {\n unformattedLine[1] += element.text\n })\n }\n\n if (\n unformattedLine.filter(\n (e, i) =>\n visibleLength(e) >\n (typeof this.realWidth === \"number\"\n ? this.realWidth\n : this.realWidth[i]) -\n bsize\n ).length > 0\n ) {\n unformattedLine = unformattedLine.map((e, i) => {\n const width =\n typeof this.realWidth === \"number\"\n ? this.realWidth\n : this.realWidth[i]\n if (visibleLength(e) > width - bsize) {\n // Need to truncate\n const offset = 2\n if (dir === \"vertical\") {\n newLine[i] = [...JSON.parse(JSON.stringify(line))] // Shallow copy because I just want to modify the values but not the original\n } else {\n newLine[i] =\n i === 0\n ? JSON.parse(JSON.stringify(line))\n : JSON.parse(JSON.stringify(secondLine))\n }\n let diff = visibleLength(e) - width + 1\n\n // remove truncated text\n for (let j = newLine[i].length - 1; j >= 0; j--) {\n if (visibleLength(newLine[i][j].text) > diff + offset) {\n newLine[i][j].text = truncate(\n newLine[i][j].text,\n visibleLength(newLine[i][j].text) - diff - offset,\n false\n )\n break\n } else {\n diff -= visibleLength(newLine[i][j].text)\n newLine[i].splice(j, 1)\n }\n }\n // Update unformatted line\n return newLine[i].map((element) => element.text).join(\"\")\n }\n return e\n })\n }\n if (dir === \"vertical\") {\n if (this.options.boxed)\n newLine[0].unshift({\n text: boxChars[\"normal\"].vertical,\n style: {\n color: this.selected === index ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n if (visibleLength(unformattedLine[0]) <= this.CM.Screen.width - bsize) {\n newLine[0].push({\n text: `${\" \".repeat(\n this.CM.Screen.width -\n visibleLength(unformattedLine[0]) -\n bsize\n )}`,\n style: { },\n })\n }\n if (this.options.boxed)\n newLine[0].push({\n text: boxChars[\"normal\"].vertical,\n style: {\n color: this.selected === index ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n this.CM.Screen.write(...newLine[0])\n } else {\n const width =\n typeof this.realWidth === \"number\"\n ? [this.realWidth, 0]\n : [this.realWidth[0], this.realWidth[1]]\n const ret: StyledElement[] = []\n if (this.options.boxed)\n ret.push({\n text: boxChars[\"normal\"].vertical,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n ret.push(...newLine[0])\n if (visibleLength(unformattedLine[0]) <= width[0] - bsize) {\n ret.push({\n text: `${\" \".repeat(\n width[0] - visibleLength(unformattedLine[0]) - (bsize > 0 ? 2 : 0) \n )}`,\n style: { color: \"\" },\n })\n }\n if (this.options.boxed)\n ret.push({\n text: boxChars[\"normal\"].vertical,\n style: { color: this.options.boxColor, bold: this.boxBold },\n })\n ret.push(...newLine[1])\n if (visibleLength(unformattedLine[1]) <= width[1] - bsize) {\n ret.push({\n text: `${\" \".repeat(\n width[1] - visibleLength(unformattedLine[1]) - (bsize > 0 ? 1 : 0) \n )}`,\n style: { color: \"\" },\n })\n }\n if (this.options.boxed)\n ret.push({\n text: boxChars[\"normal\"].vertical,\n style: {\n color: this.selected === 1 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n this.CM.Screen.write(...ret)\n }\n }\n\n /**\n * @description This function is used to draw the layout to the screen.\n * @memberof DoubleLayout\n * @returns {void}\n * @example layout.draw()\n */\n public draw(): void {\n this.isOdd = this.CM.Screen.width % 2 === 1\n if (!this.options.direction || this.options.direction === \"vertical\") {\n this.realWidth = [\n Math.round(this.CM.Screen.width * 1),\n Math.round(this.CM.Screen.width * 1),\n ]\n const trimmedTitle = [\n truncate(this.page1Title, this.realWidth[0] - 4, false),\n truncate(this.page2Title, this.realWidth[1] - 4, false),\n ]\n\n const pageHeights = [\n this.page1.getViewedPageHeight(),\n this.page2.getViewedPageHeight(),\n ]\n\n if (this.options.fitHeight) {\n const decorationHeight = this.options.boxed || this.options.showTitle ? 2 : 0\n const halfHeight = (this.CM.Screen.height - decorationHeight) / 2 - 1\n if (Math.max(...pageHeights) > halfHeight) {\n // Change pageHeights to fit the screen\n const ratio = halfHeight / Math.max(...pageHeights)\n pageHeights[0] = Math.round(pageHeights[0] * ratio)\n pageHeights[1] = Math.round(pageHeights[1] * ratio)\n } else {\n pageHeights[0] = halfHeight\n pageHeights[1] = halfHeight\n }\n }\n\n if (this.options.boxed) {\n // Draw pages with borders\n if (this.options.showTitle) {\n this.CM.Screen.write({\n text: `${boxChars[\"normal\"].topLeft}${\n boxChars[\"normal\"].horizontal\n }${trimmedTitle[0]}${boxChars[\"normal\"].horizontal.repeat(\n this.CM.Screen.width - visibleLength(trimmedTitle[0]) - 3\n )}${boxChars[\"normal\"].topRight}`,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n } else {\n this.CM.Screen.write({\n text: `${boxChars[\"normal\"].topLeft}${\n boxChars[\"normal\"].horizontal\n }${boxChars[\"normal\"].horizontal.repeat(this.CM.Screen.width - 3)}${\n boxChars[\"normal\"].topRight\n }`,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n }\n for (let i = 0; i < pageHeights[0]; i++) {\n this.drawLine(this.page1.getContent()[i] || [{ text: \"\", style: { color: \"\" } }], undefined, 0)\n }\n if (this.options.showTitle) {\n this.CM.Screen.write({\n text: `${boxChars[\"normal\"].left}${boxChars[\"normal\"].horizontal}${\n trimmedTitle[1]\n }${boxChars[\"normal\"].horizontal.repeat(\n this.CM.Screen.width - visibleLength(trimmedTitle[1]) - 3\n )}${boxChars[\"normal\"].right}`,\n style: { color: this.options.boxColor, bold: this.boxBold },\n })\n } else {\n this.CM.Screen.write({\n text: `${boxChars[\"normal\"].left}${boxChars[\n \"normal\"\n ].horizontal.repeat(this.CM.Screen.width - 2)}${\n boxChars[\"normal\"].right\n }`,\n style: { color: this.options.boxColor, bold: this.boxBold },\n })\n }\n for (let i = 0; i < pageHeights[1]; i++) {\n this.drawLine(this.page2.getContent()[i] || [{ text: \"\", style: { color: \"\" } }], undefined, 1)\n }\n this.CM.Screen.write({\n text: `${boxChars[\"normal\"].bottomLeft}${boxChars[\n \"normal\"\n ].horizontal.repeat(this.CM.Screen.width - 2)}${\n boxChars[\"normal\"].bottomRight\n }`,\n style: {\n color: this.selected === 1 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n } else {\n // Draw pages without borders\n if (this.options.showTitle) {\n this.CM.Screen.write({\n text: `${trimmedTitle[0]}`,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n }\n for (let i = 0; i < pageHeights[0]; i++) {\n this.drawLine(this.page1.getContent()[i] || [{ text: \"\", style: { color: \"\" } }], undefined, 0)\n }\n if (this.options.showTitle) {\n this.CM.Screen.write({\n text: `${trimmedTitle[1]}`,\n style: {\n color: this.selected === 1 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n }\n for (let i = 0; i < pageHeights[1]; i++) {\n this.drawLine(this.page2.getContent()[i] || [{ text: \"\", style: { color: \"\" } }], undefined, 1)\n }\n }\n } else {\n // Draw horizontally\n this.realWidth = [\n Math.round(this.CM.Screen.width * this.proportions[0]),\n Math.round(this.CM.Screen.width * this.proportions[1]),\n ]\n const trimmedTitle = [\n truncate(this.page1Title, this.realWidth[0] - 4, false),\n truncate(this.page2Title, this.realWidth[1] - 3, false),\n ]\n let maxPageHeight = Math.max(\n this.page1.getViewedPageHeight(),\n this.page2.getViewedPageHeight()\n )\n \n if (this.options.fitHeight) {\n const decorationHeight = this.options.boxed || this.options.showTitle ? 2 : 0\n maxPageHeight = this.CM.Screen.height - decorationHeight\n }\n\n const p1 = this.page1.getContent()\n const p2 = this.page2.getContent()\n if (this.options.boxed) {\n // Draw pages with borders\n if (this.options.showTitle) {\n this.CM.Screen.write(\n {\n text: `${boxChars[\"normal\"].topLeft}${\n boxChars[\"normal\"].horizontal\n }${trimmedTitle[0]}${boxChars[\"normal\"].horizontal.repeat(\n this.realWidth[0] - visibleLength(trimmedTitle[0]) - 3\n )}${boxChars[\"normal\"].top}`,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n },\n {\n text: `${boxChars[\"normal\"].horizontal}${\n trimmedTitle[1]\n }${boxChars[\"normal\"].horizontal.repeat(\n this.realWidth[1] - visibleLength(trimmedTitle[1]) - 2\n )}${boxChars[\"normal\"].topRight}`,\n style: {\n color: this.selected === 1 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n }\n )\n } else {\n this.CM.Screen.write(\n {\n text: `${boxChars[\"normal\"].topLeft}${\n boxChars[\"normal\"].horizontal\n }${boxChars[\"normal\"].horizontal.repeat(this.realWidth[0] - 3)}${\n boxChars[\"normal\"].top\n }`,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n },\n {\n text: `${boxChars[\"normal\"].horizontal}${boxChars[\n \"normal\"\n ].horizontal.repeat(this.realWidth[1] - 2)}${\n boxChars[\"normal\"].topRight\n }`,\n style: {\n color: this.selected === 1 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n }\n )\n }\n for (let i = 0; i < maxPageHeight; i++) {\n this.drawLine(\n p1[i] || [{ text: \"\", style: { color: \"\" } }],\n p2[i] || [{ text: \"\", style: { color: \"\" } }]\n )\n }\n // Draw the bottom border\n this.CM.Screen.write(\n {\n text: `${boxChars[\"normal\"].bottomLeft}${boxChars[\n \"normal\"\n ].horizontal.repeat(this.realWidth[0] - 2)}${\n boxChars[\"normal\"].bottom\n }`,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n },\n {\n text: `${boxChars[\"normal\"].horizontal.repeat(\n this.realWidth[1] - 1\n )}${boxChars[\"normal\"].bottomRight}`,\n style: {\n color: this.selected === 1 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n }\n )\n } else {\n // Draw pages without borders\n if (this.options.showTitle) {\n this.CM.Screen.write({\n text: `${trimmedTitle[0]}${\" \".repeat(\n this.realWidth[0] - visibleLength(trimmedTitle[0])\n )}${trimmedTitle[1]}`,\n style: {\n color: this.selected === 0 ? this.options.boxColor : \"white\",\n bold: this.boxBold,\n },\n })\n }\n for (let i = 0; i < maxPageHeight; i++) {\n this.drawLine(\n p1[i] || [{ text: \"\", style: { color: \"\" } }],\n p2[i] || [{ text: \"\", style: { color: \"\" } }]\n )\n }\n }\n }\n }\n}\n\nexport default DoubleLayout\n", "import { ForegroundColorName } from \"chalk\"\nimport { ConsoleManager, PageBuilder } from \"../../ConsoleGui.js\"\nimport { boxChars, HEX, RGB, StyledElement, truncate } from \"../Utils.js\"\n\n/**\n * @description The type containing all the possible options for the QuadLayout.\n * @typedef {Object} QuadLayoutOptions\n * @prop {boolean} [showTitle] - If the title should be shown.\n * @prop {boolean} [boxed] - If the layout should be boxed.\n * @prop {ForegroundColorName | HEX | RGB | \"\"} [boxColor] - The color of the box taken from the chalk library.\n * @prop {\"bold\"} [boxStyle] - If the border of the box should be bold.\n * @prop {string} [changeFocusKey] - The key that should be pressed to change the focus.\n * @prop {string} [page1Title] - The title of the first page.\n * @prop {string} [page2Title] - The title of the second page.\n * @prop {string} [page3Title] - The title of the third page.\n * @prop {string} [page4Title] - The title of the fourth page.\n * @prop {number[]} [pageRatio] - The ratio of the pages.\n * @prop {boolean} [fitHeight] - If the height of the pages should be the same.\n *\n * @export\n * @interface DoubleLayoutOptions\n */\n// @type definition\nexport interface QuadLayoutOptions {\n showTitle?: boolean;\n boxed?: boolean;\n boxColor?: ForegroundColorName | HEX | RGB | \"\"; // add color list from chalk\n boxStyle?: \"bold\";\n changeFocusKey?: string;\n page1Title?: string;\n page2Title?: string;\n page3Title?: string;\n page4Title?: string;\n pageRatio?: [[number, number], [number, number]];\n fitHeight?: boolean;\n}\n\n/**\n * @class QuadLayout\n * @description This class is a layout that has two pages.\n * \n * \n * \n * @param {PageBuilder} page1 The first page.\n * @param {PageBuilder} page2 The second page.\n * @param {PageBuilder} page3 The third page.\n * @param {PageBuilder} page4 The fourth page.\n * @param {boolean} options Layout options.\n * @param {number} selected The selected page.\n * @example const layout = new QuadLayout(page1, page2, true, 0)\n */\nexport class QuadLayout {\n CM: ConsoleManager\n options: QuadLayoutOptions\n selected: 0 | 1 | 2 | 3\n page1: PageBuilder\n page2: PageBuilder\n page3: PageBuilder\n page4: PageBuilder\n boxBold: boolean\n proportions: [[number, number], [number, number]]\n page1Title: string\n page2Title: string\n page3Title: string\n page4Title: string\n realWidth: [[number, number], [number, number]] = [[0, 0], [0, 0]]\n isOdd: boolean | undefined\n\n public constructor(page1: PageBuilder, page2: PageBuilder, page3: PageBuilder, page4: PageBuilder, options: QuadLayoutOptions, selected: 0 | 1 | 2 | 3 = 0) {\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n\n this.options = options\n this.selected = selected\n this.page1 = page1\n this.page2 = page2\n this.page3 = page3\n this.page4 = page4\n\n this.boxBold = this.options.boxStyle === \"bold\" ? true : false\n this.proportions = this.options.pageRatio || [[0.4, 0.6], [0.5, 0.5]]\n\n /** @const {string} page1Title The application title. */\n this.page1Title = this.options.page1Title || \"\"\n\n /** @const {string} page2Title The title of page2. */\n this.page2Title = this.options.page2Title || \"\"\n\n /** @const {string} page3Title The title of page3. */\n this.page3Title = this.options.page3Title || \"\"\n\n /** @const {string} page4Title The title of page4. */\n this.page4Title = this.options.page4Title || \"\"\n }\n\n /**\n * @description This function is used to overwrite the page content.\n * @param {PageBuilder} page the page to be added\n * @memberof QuadLayout \n */\n public setPage(page: PageBuilder, index: number): void {\n switch (index) {\n case 0:\n this.page1 = page\n break\n case 1:\n this.page2 = page\n break\n case 2:\n this.page3 = page\n break\n case 3:\n this.page4 = page\n break\n default:\n break\n }\n }\n\n /**\n * @description This function is used to overwrite the first page content.\n * @param {PageBuilder} page the page to be added\n * @memberof QuadLayout\n */\n public setPage1(page: PageBuilder): void { this.page1 = page }\n\n /**\n * @description This function is used to overwrite the second page content.\n * @param {PageBuilder} page the page to be added\n * @memberof QuadLayout\n */\n public setPage2(page: PageBuilder): void { this.page2 = page }\n\n /**\n * @description This function is used to overwrite the third page content.\n * @param {PageBuilder} page the page to be added\n * @memberof QuadLayout\n */\n public setPage3(page: PageBuilder): void { this.page3 = page }\n\n /**\n * @description This function is used to overwrite the forth page content.\n * @param {PageBuilder} page the page to be added\n * @memberof QuadLayout\n */\n public setPage4(page: PageBuilder): void { this.page4 = page }\n\n /**\n * @description This function is used to set the page titles.\n * @param {string[]} titles the titles of the pages\n * @memberof QuadLayout\n * @example layout.setTitles([\"Page 1\", \"Page 2\", \"Page 3\", \"Page 4\"])\n */\n public setTitles(titles: string[]) {\n this.page1Title = titles[0]\n this.page2Title = titles[1]\n this.page3Title = titles[2]\n this.page4Title = titles[3]\n }\n\n /**\n * @description This function is used to set the page title at the given index.\n * @param {string} title the title of the page\n * @param {number} index the index of the page\n * @memberof QuadLayout\n * @example layout.setTitle(\"Page 1\", 0)\n */\n public setTitle(title: string, index: number): void {\n switch (index) {\n case 0:\n this.page1Title = title\n break\n case 1:\n this.page2Title = title\n break\n case 2:\n this.page3Title = title\n break\n case 3:\n this.page4Title = title\n break\n default:\n break\n }\n }\n\n /**\n * @description This function is used to enable or disable the layout border.\n * @param {boolean} border enable or disable the border\n * @memberof QuadLayout\n */\n public setBorder(border: boolean): void { this.options.boxed = border }\n\n /**\n * @description This function is used to choose the page to be highlighted.\n * @param {number} selected 0 for page1, 1 for page2\n * @memberof QuadLayout\n */\n public setSelected(selected: 0 | 1 | 2 | 3): void { this.selected = selected }\n\n /**\n * @description This function is used to get the selected page.\n * @returns {number} 0 for page1, 1 for page2\n * @memberof QuadLayout\n */\n public getSelected(): number {\n return this.selected\n }\n\n /**\n * @description This function is used to get switch the selected page.\n * @returns {void}\n * @memberof QuadLayout\n */\n public changeLayout(): void {\n if (this.selected >= 0 && this.selected < 3) {\n this.selected++\n } else {\n this.selected = 0\n }\n }\n\n /**\n * @description This function is used to change the page ratio.\n * @param {Array<Array<number>>} ratio the ratio of pages\n * @memberof QuadLayout\n * @example layout.setRatio([[0.4, 0.6], [0.5, 0.5]])\n */\n public setRatio(ratio: [[number, number], [number, number]]): void {\n this.proportions = ratio\n }\n\n /**\n * @description This function is used to increase the page ratio of the selected row by the given ratio to add.\n * @param {number} quantity the ratio to add\n * @memberof QuadLayout\n * @example layout.increaseRatio(0.01)\n */\n public increaseRatio(quantity: number): void {\n if (this.selected < 2) {\n if (this.proportions[0][0] < 0.9) {\n this.proportions[0][0] = Number((this.proportions[0][0] + quantity).toFixed(2))\n this.proportions[0][1] = Number((this.proportions[0][1] - quantity).toFixed(2))\n }\n } else {\n if (this.proportions[1][0] < 0.9) {\n this.proportions[1][0] = Number((this.proportions[1][0] + quantity).toFixed(2))\n this.proportions[1][1] = Number((this.proportions[1][1] - quantity).toFixed(2))\n }\n }\n }\n\n /**\n * @description This function is used to decrease the page ratio of the selected row by the given ratio to add.\n * @param {number} quantity the ratio to subtract\n * @memberof QuadLayout\n * @example layout.decreaseRatio(0.01)\n */\n public decreaseRatio(quantity: number): void {\n if (this.selected < 2) {\n if (this.proportions[0][0] > 0.1) {\n this.proportions[0][0] = Number((this.proportions[0][0] - quantity).toFixed(2))\n this.proportions[0][1] = Number((this.proportions[0][1] + quantity).toFixed(2))\n }\n } else {\n if (this.proportions[1][0] > 0.1) {\n this.proportions[1][0] = Number((this.proportions[1][0] - quantity).toFixed(2))\n this.proportions[1][1] = Number((this.proportions[1][1] + quantity).toFixed(2))\n }\n }\n }\n\n /**\n * @description This function is used to draw a single line of the layout to the screen. It also trim the line if it is too long.\n * @param {Array<StyledElement>} line the line to be drawn\n * @param {Array<StyledElement>} secondLine the line to be drawn\n * @param {number} row the row of the quad grid to be drawn\n * @memberof QuadLayout\n * @returns {void}\n */\n private drawLine(line: Array<StyledElement>, secondLine: Array<StyledElement>, row = 0): void {\n const bsize = this.options.boxed ? 3 : 0\n let unformattedLine = [\"\"]\n let newLine = [\n [...line]\n ]\n newLine = [\n [...line],\n [...secondLine ? secondLine : line]\n ]\n unformattedLine.push(\"\")\n line.forEach((element: StyledElement) => {\n unformattedLine[0] += element.text\n })\n secondLine?.forEach((element: StyledElement) => {\n unformattedLine[1] += element.text\n })\n if (unformattedLine.filter((e, i) => e.length > this.realWidth[row][i] - bsize).length > 0) {\n unformattedLine = unformattedLine.map((e, i) => {\n if (e.length > this.realWidth[row][i] - bsize) { // Need to truncate\n const offset = 2\n newLine[i] = i === 0 ? JSON.parse(JSON.stringify(line)) : JSON.parse(JSON.stringify(secondLine))\n let diff = e.length - this.realWidth[row][i] + 1\n // remove truncated text\n for (let j = newLine[i].length - 1; j >= 0; j--) {\n if (newLine[i][j].text.length > diff + offset) {\n newLine[i][j].text = truncate(newLine[i][j].text, (newLine[i][j].text.length - diff) - offset, false)\n break\n } else {\n diff -= newLine[i][j].text.length\n newLine[i].splice(j, 1)\n }\n }\n // Update unformatted line\n return newLine[i].map(element => element.text).join(\"\")\n }\n return e\n })\n }\n const ret: StyledElement[] = []\n if (this.options.boxed) ret.push({ text: boxChars[\"normal\"].vertical, style: { color: this.selected === 0 && row === 0 || this.selected === 2 && row === 1 ? this.options.boxColor : \"white\", bold: this.boxBold } })\n ret.push(...newLine[0])\n if (unformattedLine[0].length <= this.realWidth[row][0] - bsize) {\n ret.push({ text: `${\" \".repeat((this.realWidth[row][0] - unformattedLine[0].length) - (bsize > 0 ? 2 : 0))}`, style: { color: \"\" } })\n }\n if (this.options.boxed) ret.push({ text: boxChars[\"normal\"].vertical, style: { color: ((this.selected < 2 && row === 0) || (this.selected > 1 && row === 1)) ? this.options.boxColor : \"white\", bold: this.boxBold } })\n ret.push(...newLine[1])\n if (unformattedLine[1].length <= this.realWidth[row][1] - bsize) {\n ret.push({ text: `${\" \".repeat((this.realWidth[row][1] - unformattedLine[1].length) - (bsize > 0 ? 1 : 0))}`, style: { color: \"\" } })\n }\n if (this.options.boxed) ret.push({ text: boxChars[\"normal\"].vertical, style: { color: this.selected === 1 && row === 0 || this.selected === 3 && row === 1 ? this.options.boxColor : \"white\", bold: this.boxBold } })\n this.CM.Screen.write(...ret)\n }\n\n /**\n * @description This function is used to draw the layout to the screen.\n * @memberof QuadLayout\n * @returns {void}\n * @example layout.draw()\n */\n public draw(): void {\n this.isOdd = this.CM.Screen.width % 2 === 1\n this.realWidth = [\n [\n Math.round(this.CM.Screen.width * this.proportions[0][0]),\n Math.round(this.CM.Screen.width * this.proportions[0][1])\n ],\n [\n Math.round(this.CM.Screen.width * this.proportions[1][0]),\n Math.round(this.CM.Screen.width * this.proportions[1][1])\n ]\n ]\n const trimmedTitle = [\n [\n truncate(this.page1Title, this.realWidth[0][0] - 4, false),\n truncate(this.page2Title, this.realWidth[0][1] - 3, false)\n ],\n [\n truncate(this.page3Title, this.realWidth[1][0] - 4, false),\n truncate(this.page4Title, this.realWidth[1][1] - 3, false)\n ]\n ]\n let maxPageHeight = Math.max(\n this.page1.getViewedPageHeight(),\n this.page2.getViewedPageHeight(),\n this.page3.getViewedPageHeight(),\n this.page4.getViewedPageHeight()\n )\n\n if (this.options.fitHeight) {\n const decorationHeight = this.options.boxed || this.options.showTitle ? 4 : 0\n maxPageHeight = (this.CM.Screen.height - decorationHeight) / 2\n }\n\n const p = [\n this.page1.getContent(),\n this.page2.getContent(),\n this.page3.getContent(),\n this.page4.getContent()\n ]\n\n for (let j = 0; j < 2; j++) {\n if (this.options.boxed) { // Draw pages with borders\n if (j === 0) {\n if (this.options.showTitle) {\n this.CM.Screen.write(\n { text: `${boxChars[\"normal\"].topLeft}${boxChars[\"normal\"].horizontal}${trimmedTitle[j][0]}${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][0] - trimmedTitle[j][0].length - 3)}${boxChars[\"normal\"].top}`, style: { color: this.selected === 0 ? this.options.boxColor : \"white\", bold: this.boxBold } },\n { text: `${boxChars[\"normal\"].horizontal}${trimmedTitle[j][1]}${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][1] - trimmedTitle[j][1].length - 2)}${boxChars[\"normal\"].topRight}`, style: { color: this.selected === 1 ? this.options.boxColor : \"white\", bold: this.boxBold } }\n )\n } else {\n this.CM.Screen.write(\n { text: `${boxChars[\"normal\"].topLeft}${boxChars[\"normal\"].horizontal}${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][0] - 3)}${boxChars[\"normal\"].top}`, style: { color: this.selected === 0 ? this.options.boxColor : \"white\", bold: this.boxBold } },\n { text: `${boxChars[\"normal\"].horizontal}${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][1] - 2)}${boxChars[\"normal\"].topRight}`, style: { color: this.selected === 1 ? this.options.boxColor : \"white\", bold: this.boxBold } }\n )\n }\n }\n for (let i = 0; i < maxPageHeight; i++) {\n this.drawLine(p[j + (j * 1)][i] || [{ text: \"\", style: { color: \"\" } }], p[j + (j * 1) + 1][i] || [{ text: \"\", style: { color: \"\" } }], j)\n }\n // Draw the bottom border\n if (j === 0) {\n const first = this.realWidth[j][0]\n const second = this.realWidth[j + 1][0]\n if (this.options.showTitle) {\n let str\n if (first === second)\n str = `${boxChars[\"normal\"].horizontal.repeat(first - trimmedTitle[j + 1][0].length - 3)}${boxChars[\"normal\"].cross}`\n if (first > second)\n str = `${boxChars[\"normal\"].horizontal.repeat(second - trimmedTitle[j + 1][0].length - 3)}${boxChars[\"normal\"].top}`\n if (first < second && trimmedTitle[j + 1][0].length < first - 2)\n str = `${boxChars[\"normal\"].horizontal.repeat(first - trimmedTitle[j + 1][0].length - 3)}${boxChars[\"normal\"].bottom}${boxChars[\"normal\"].horizontal.repeat(second - first - 1)}${boxChars[\"normal\"].top}`\n if (first < second && trimmedTitle[j + 1][0].length >= first - 2)\n str = `${boxChars[\"normal\"].horizontal.repeat(second - trimmedTitle[j + 1][0].length - 3)}${boxChars[\"normal\"].top}`\n let str2\n if (first === second || first < second)\n str2 = `${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j + 1][1] - trimmedTitle[j + 1][1].length - 2)}`\n if (first > second) {\n if (first - second >= trimmedTitle[j + 1][1].length + 2) {\n str2 = `${boxChars[\"normal\"].horizontal.repeat(first - second - (trimmedTitle[j + 1][1].length + 2))}${boxChars[\"normal\"].bottom}${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][1] - 1)}`\n } else {\n str2 = `${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j + 1][1] - (trimmedTitle[j + 1][1].length + 2))}`\n }\n }\n\n this.CM.Screen.write(\n { text: `${boxChars[\"normal\"].left}${boxChars[\"normal\"].horizontal}${trimmedTitle[j + 1][0]}${str}`, style: { color: this.selected === 2 ? this.options.boxColor : \"white\", bold: this.boxBold } },\n { text: `${boxChars[\"normal\"].horizontal}${trimmedTitle[j + 1][1]}${str2}${boxChars[\"normal\"].right}`, style: { color: this.selected === 3 ? this.options.boxColor : \"white\", bold: this.boxBold } }\n )\n } else {\n let str\n if (first === second)\n str = `${boxChars[\"normal\"].horizontal.repeat(first - 2)}${boxChars[\"normal\"].cross}`\n if (first > second)\n str = `${boxChars[\"normal\"].horizontal.repeat(second - 2)}${boxChars[\"normal\"].top}`\n if (first < second)\n str = `${boxChars[\"normal\"].horizontal.repeat(first - 2)}${boxChars[\"normal\"].bottom}${boxChars[\"normal\"].horizontal.repeat(second - first - 1)}${boxChars[\"normal\"].top}`\n let str2\n if (first <= second)\n str2 = `${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j + 1][1] - 1)}`\n if (first > second) {\n str2 = `${boxChars[\"normal\"].horizontal.repeat(first - second - 1)}${boxChars[\"normal\"].bottom}${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][1] - 1)}`\n }\n this.CM.Screen.write(\n { text: `${boxChars[\"normal\"].left}${str}`, style: { color: this.selected === 0 || this.selected === 2 ? this.options.boxColor : \"white\", bold: this.boxBold } },\n { text: `${str2}${boxChars[\"normal\"].right}`, style: { color: this.selected === 1 || this.selected === 3 ? this.options.boxColor : \"white\", bold: this.boxBold } }\n )\n }\n } else {\n this.CM.Screen.write(\n { text: `${boxChars[\"normal\"].bottomLeft}${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][0] - 2)}${boxChars[\"normal\"].bottom}`, style: { color: this.selected === 2 ? this.options.boxColor : \"white\", bold: this.boxBold } },\n { text: `${boxChars[\"normal\"].horizontal.repeat(this.realWidth[j][1] - 1)}${boxChars[\"normal\"].bottomRight}`, style: { color: this.selected === 3 ? this.options.boxColor : \"white\", bold: this.boxBold } }\n )\n }\n } else { // Draw pages without borders\n if (this.options.showTitle) {\n if (j === 0) {\n this.CM.Screen.write(\n { text: `${trimmedTitle[j][0]}${\" \".repeat(this.realWidth[j][0] - trimmedTitle[j][0].length)}`, style: { color: this.selected === 0 ? this.options.boxColor : \"white\", bold: this.boxBold } },\n { text: `${trimmedTitle[j][1]}`, style: { color: this.selected === 1 ? this.options.boxColor : \"white\", bold: this.boxBold } }\n )\n } else {\n this.CM.Screen.write(\n { text: `${trimmedTitle[j][0]}${\" \".repeat(this.realWidth[j][0] - trimmedTitle[j][0].length)}`, style: { color: this.selected === 2 ? this.options.boxColor : \"white\", bold: this.boxBold } },\n { text: `${trimmedTitle[j][1]}`, style: { color: this.selected === 3 ? this.options.boxColor : \"white\", bold: this.boxBold } }\n )\n }\n }\n for (let i = 0; i < maxPageHeight; i++) {\n this.drawLine(p[j + (j * 1)][i] || [{ text: \"\", style: { color: \"\" } }], p[j + (j * 1) + 1][i] || [{ text: \"\", style: { color: \"\" } }], j)\n }\n }\n }\n }\n}\n\nexport default QuadLayout", "import { ForegroundColorName } from \"chalk\"\nimport { ConsoleManager, PageBuilder } from \"../../ConsoleGui.js\"\nimport { boxChars, HEX, RGB, StyledElement, truncate } from \"../Utils.js\"\n\n/**\n * @description The type containing all the possible options for the SingleLayout.\n * @typedef {Object} SingleLayoutOptions\n * @prop {boolean} [showTitle] - If the title should be shown.\n * @prop {boolean} [boxed] - If the layout should be boxed.\n * @prop {ForegroundColorName | HEX | RGB | \"\"} [boxColor] - The color of the box taken from the chalk library.\n * @prop {\"bold\"} [boxStyle] - If the border of the box should be bold.\n * @prop {string} [pageTitle] - The title of the first page.\n * @prop {boolean} [fitHeight] - If the height of the layout should be the same as the height of the screen.\n *\n * @export\n * @interface SingleLayoutOptions\n */\n// @type definition\nexport interface SingleLayoutOptions {\n showTitle?: boolean;\n boxed?: boolean;\n boxColor?: ForegroundColorName | HEX | RGB | \"\"; // add color list from chalk\n boxStyle?: \"bold\";\n pageTitle?: string;\n fitHeight?: boolean;\n}\n\n/**\n * @class SingleLayout\n * @description This class is a layout that has two pages.\n * \n * \n * \n * @param {PageBuilder} page The first page.\n * @param {boolean} options Layout options.\n * @example const layout = new SingleLayout(page1, page2, true, 0)\n */\nexport class SingleLayout {\n CM: ConsoleManager\n options: SingleLayoutOptions\n page: PageBuilder\n boxBold: boolean\n pageTitle: string\n isOdd: boolean | undefined\n\n public constructor(page: PageBuilder, options: SingleLayoutOptions) {\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n\n this.options = options\n this.page = page\n\n this.boxBold = this.options.boxStyle === \"bold\" ? true : false\n\n /** @const {string} pageTitle The application title. */\n this.pageTitle = this.options.pageTitle || this.CM.applicationTitle\n }\n\n /**\n * @description This function is used to overwrite the page content.\n * @param {PageBuilder} page the page to be added\n * @memberof SingleLayout\n */\n public setPage(page: PageBuilder): void { this.page = page }\n\n /**\n * @description This function is used to set the title of the layout.\n * @param {string} title the title to be set\n * @memberof SingleLayout\n * @returns {void}\n * @example layout.setTitle(\"My Title\")\n */\n public setTitle(title: string): void { this.pageTitle = title }\n\n /**\n * @description This function is used to enable or disable the layout border.\n * @param {boolean} border enable or disable the border\n * @memberof SingleLayout\n */\n public setBorder(border: boolean): void { this.options.boxed = border }\n\n /**\n * @description This function is used to draw a single line of the layout to the screen. It also trim the line if it is too long.\n * @param {Array<StyledElement>} line the line to be drawn\n * @memberof SingleLayout\n * @returns {void}\n */\n private drawLine(line: Array<StyledElement>): void {\n const bsize = this.options.boxed ? 2 : 0\n let unformattedLine = \"\"\n let newLine = [...line]\n\n line.forEach((element: { text: string; }) => {\n unformattedLine += element.text\n })\n\n if (unformattedLine.length > this.CM.Screen.width - bsize) { // Need to truncate\n const offset = 2\n newLine = [...JSON.parse(JSON.stringify(line))] // Shallow copy because I just want to modify the values but not the original\n\n let diff = unformattedLine.length - this.CM.Screen.width + 1\n\n // remove truncated text\n for (let j = newLine.length - 1; j >= 0; j--) {\n if (newLine[j].text.length > diff + offset) {\n newLine[j].text = truncate(newLine[j].text, (newLine[j].text.length - diff) - offset, true)\n break\n } else {\n diff -= newLine[j].text.length\n newLine.splice(j, 1)\n }\n }\n // Update unformatted line\n unformattedLine = newLine.map((element: { text: string; }) => element.text).join(\"\")\n }\n if (this.options.boxed) newLine.unshift({ text: boxChars[\"normal\"].vertical, style: { color: this.options.boxColor, bold: this.boxBold } })\n if (unformattedLine.length <= this.CM.Screen.width - bsize) {\n newLine.push({ text: `${\" \".repeat((this.CM.Screen.width - unformattedLine.length) - bsize)}`, style: { color: \"\" } })\n }\n if (this.options.boxed) newLine.push({ text: boxChars[\"normal\"].vertical, style: { color: this.options.boxColor, bold: this.boxBold } })\n this.CM.Screen.write(...newLine)\n }\n\n /**\n * @description This function is used to draw the layout to the screen.\n * @memberof SingleLayout\n * @returns {void}\n * @example layout.draw()\n */\n public draw(): void {\n this.isOdd = this.CM.Screen.width % 2 === 1\n const trimmedTitle = truncate(this.pageTitle, this.CM.Screen.width - 2, false)\n if (this.options.boxed) { // Draw pages with borders\n if (this.options.showTitle) {\n this.CM.Screen.write({ text: `${boxChars[\"normal\"].topLeft}${boxChars[\"normal\"].horizontal}${trimmedTitle}${boxChars[\"normal\"].horizontal.repeat(this.CM.Screen.width - trimmedTitle.length - 3)}${boxChars[\"normal\"].topRight}`, style: { color: this.options.boxColor, bold: this.boxBold } })\n } else {\n this.CM.Screen.write({ text: `${boxChars[\"normal\"].topLeft}${boxChars[\"normal\"].horizontal}${boxChars[\"normal\"].horizontal.repeat(this.CM.Screen.width - 3)}${boxChars[\"normal\"].topRight}`, style: { color: this.options.boxColor, bold: this.boxBold } })\n }\n if (this.options.fitHeight) {\n for (let i = 0; i < this.CM.Screen.height - 2; i++) {\n this.drawLine(this.page.getContent()[i] || [{ text: \"\", style: { color: \"\" } }])\n }\n } else {\n this.page.getContent().forEach((line: StyledElement[]) => {\n this.drawLine(line)\n })\n }\n this.CM.Screen.write({ text: `${boxChars[\"normal\"].bottomLeft}${boxChars[\"normal\"].horizontal.repeat(this.CM.Screen.width - 2)}${boxChars[\"normal\"].bottomRight}`, style: { color: this.options.boxColor, bold: this.boxBold } })\n } else { // Draw pages without borders\n if (this.options.showTitle) {\n this.CM.Screen.write({ text: `${trimmedTitle}`, style: { color: this.options.boxColor, bold: this.boxBold } })\n }\n if (this.options.fitHeight) {\n for (let i = 0; i < this.CM.Screen.height - 2; i++) {\n this.drawLine(this.page.getContent()[i] || [{ text: \"\", style: { color: \"\" } }])\n }\n } else {\n this.page.getContent().forEach((line: StyledElement[]) => {\n this.drawLine(line)\n })\n }\n }\n }\n}\n\nexport default SingleLayout", "import { ForegroundColorName } from \"chalk\"\nimport { ConsoleManager } from \"../../ConsoleGui.js\"\nimport PageBuilder from \"../PageBuilder.js\"\nimport { HEX, RGB } from \"../Utils.js\"\nimport DoubleLayout, { DoubleLayoutOptions } from \"./DoubleLayout.js\"\nimport QuadLayout, { QuadLayoutOptions } from \"./QuadLayout.js\"\nimport SingleLayout, { SingleLayoutOptions } from \"./SingleLayout.js\"\n\n/**\n * @description The type containing all the possible options for the layout.\n * @typedef {Object} LayoutOptions\n * @prop {boolean} [showTitle] - If the title should be shown.\n * @prop {boolean} [boxed] - If the layout should be boxed.\n * @prop {ForegroundColorName | HEX | RGB | \"\"} [boxColor] - The color of the box taken from the chalk library.\n * @prop {\"bold\"} [boxStyle] - If the border of the box should be bold.\n * @prop {\"single\" | \"double\" | \"triple\" | \"quad\"} [type] - The type of the layout.\n * @prop {string} [changeFocusKey] - The key that should be pressed to change the focus.\n * @prop {\"horizontal\" | \"vertical\"} [direction] - The direction of the layout.\n * @prop {string[]} [pageTitles] - The title of the first page.\n * @prop {number[]} [pageRatio] - The ratio of the pages. (in horizontal direction)\n * @prop {boolean} [fitHeight] - If the height of the pages should be the same.\n *\n * @export\n * @interface LayoutOptions\n */\n// @type definition\nexport interface LayoutOptions {\n showTitle?: boolean;\n boxed?: boolean;\n boxColor?: ForegroundColorName | HEX | RGB | \"\"; // add color list from chalk\n boxStyle?: \"bold\";\n changeFocusKey?: string;\n type: \"single\" | \"double\" | \"triple\" | \"quad\";\n direction?: \"horizontal\" | \"vertical\";\n pageTitles?: string[];\n pageRatio?: [number, number] | [[number, number], [number, number]];\n fitHeight?: boolean;\n}\n\n/**\n * @class LayoutManager\n * @description This class is a layout that has two pages.\n * \n * \n * \n * @param {PageBuilder[]} pages The pages that should be shown.\n * @param {boolean} options Layout options.\n * @example const layout = new LayoutManager([page1, page2], pageOptions);\n */\nexport class LayoutManager {\n private CM!: ConsoleManager\n private options!: LayoutOptions\n private optionsRelative!: SingleLayoutOptions | DoubleLayoutOptions | QuadLayoutOptions\n public pages: { [key: number]: PageBuilder } = {}\n private pageTitles: string[] = []\n public layout!: SingleLayout | DoubleLayout | QuadLayout\n private instance!: LayoutManager\n\n public constructor(pages: PageBuilder[], options: LayoutOptions) {\n if (this.instance) {\n return this.instance\n } else {\n this.instance = this\n /** @const {ConsoleManager} CM the instance of ConsoleManager (singleton) */\n this.CM = new ConsoleManager()\n\n\n this.options = options\n pages.forEach((page, index) => {\n this.pages[index] = page\n })\n\n /** @const {string} pageTitle The application title. */\n this.pageTitles = this.options.pageTitles || [this.CM.applicationTitle]\n\n switch (this.options.type) {\n case \"single\":\n this.optionsRelative = {\n showTitle: this.options.showTitle,\n boxed: this.options.boxed,\n boxColor: this.options.boxColor,\n boxStyle: this.options.boxStyle,\n pageTitle: this.pageTitles ? this.pageTitles[0] : \"\",\n fitHeight: this.options.fitHeight,\n } as SingleLayoutOptions\n this.layout = new SingleLayout(this.pages[0], this.optionsRelative)\n break\n case \"double\":\n this.optionsRelative = {\n showTitle: this.options.showTitle,\n boxed: this.options.boxed,\n boxColor: this.options.boxColor,\n boxStyle: this.options.boxStyle,\n changeFocusKey: this.options.changeFocusKey || \"\",\n direction: this.options.direction,\n page1Title: this.pageTitles ? this.pageTitles[0] : \"\",\n page2Title: this.pageTitles ? this.pageTitles[1] : \"\",\n pageRatio: this.options.pageRatio,\n fitHeight: this.options.fitHeight,\n } as DoubleLayoutOptions\n this.layout = new DoubleLayout(this.pages[0], this.pages[1], this.optionsRelative as DoubleLayoutOptions)\n break\n case \"triple\":\n\n break\n case \"quad\":\n this.optionsRelative = {\n showTitle: this.options.showTitle,\n boxed: this.options.boxed,\n boxColor: this.options.boxColor,\n boxStyle: this.options.boxStyle,\n changeFocusKey: this.options.changeFocusKey || \"\",\n direction: this.options.direction,\n page1Title: this.pageTitles ? this.pageTitles[0] : \"\",\n page2Title: this.pageTitles ? this.pageTitles[1] : \"\",\n page3Title: this.pageTitles ? this.pageTitles[2] : \"\",\n page4Title: this.pageTitles ? this.pageTitles[3] : \"\",\n pageRatio: this.options.pageRatio,\n fitHeight: this.options.fitHeight,\n } as QuadLayoutOptions\n this.layout = new QuadLayout(this.pages[0], this.pages[1], this.pages[2], this.pages[3], this.optionsRelative as QuadLayoutOptions)\n break\n default:\n break\n }\n }\n }\n\n /**\n * @description This function is used to check if the layout is a single layout by checking the type of the instance.\n * @param {unknown} x - The instance of the layout.\n * @returns {boolean} - If the layout is a single layout.\n * @memberof LayoutManager\n * @example const isSingleLayout = this.isSingleLayout(layout)\n */\n private isSingleLayout = (x: unknown): x is SingleLayout => {\n return x instanceof SingleLayout\n }\n\n /**\n * @description This function is used to update the layout pages.\n * @param {PageBuilder[]} pages The pages that should be shown.\n * @memberof LayoutManager\n * @example layout.updatePages([page1, page2])\n * @example layout.updatePages([page1, page2, page3])\n */\n public setPages(pages: PageBuilder[]): void {\n pages.forEach((page, index) => {\n this.pages[index] = page\n if (this.isSingleLayout(this.layout)) {\n this.layout.setPage(page)\n } else {\n this.layout.setPage(page, index)\n }\n })\n }\n\n /**\n * @description This function is used to overwrite the page content.\n * @param {PageBuilder} page the page to be added\n * @param {number} index the index of the page\n * @memberof LayoutManager\n */\n public setPage(page: PageBuilder, index: number): void {\n this.pages[index] = page\n if (this.isSingleLayout(this.layout)) {\n this.layout.setPage(page)\n } else {\n this.layout.setPage(page, index)\n }\n }\n\n /**\n * @description This function is used to update the page title.\n * @param {string} title The title of the page.\n * @param {number} index The index of the page.\n * @memberof LayoutManager\n * @example layout.setTitle(\"Page Title\", 1)\n */\n public setTitle(title: string, index: number): void {\n this.pageTitles[index] = title\n if (this.isSingleLayout(this.layout)) {\n this.layout.setTitle(title)\n } else {\n this.layout.setTitle(title, index)\n }\n }\n\n /**\n * @description This function is used to update the page titles.\n * @param {string[]} titles The titles of the pages.\n * @memberof LayoutManager\n * @example layout.setTitles([\"Page Title 1\", \"Page Title 2\"])\n */\n public setTitles(titles: string[]): void {\n this.pageTitles = titles\n if (this.isSingleLayout(this.layout)) {\n this.layout.setTitle(titles[0])\n } else {\n this.layout.setTitles(titles)\n }\n }\n\n /**\n * @description This function is used to enable or disable the layout border.\n * @param {boolean} border enable or disable the border\n * @memberof LayoutManager\n */\n public setBorder(border: boolean): void { this.options.boxed = border }\n\n /**\n * @description This function is used to choose the page to be highlighted.\n * @param {0 | 1 | 2 | 3} selected 0 for page1, 1 for page2\n * @memberof LayoutManager\n */\n public setSelected(selected: 0 | 1 | 2 | 3): void {\n if (!this.isSingleLayout(this.layout)) {\n this.layout.setSelected(selected as 0 | 1)\n }\n }\n\n /**\n * @description This function is used to get the selected page.\n * @returns {0 | 1 | 2 | 3} 0 for page1, 1 for page2, 2 for page3, 3 for page4\n * @memberof LayoutManager\n */\n public getSelected(): number {\n if (!this.isSingleLayout(this.layout)) {\n return this.layout.selected\n }\n return 0\n }\n\n /**\n * @description This function is used to get switch the selected page. If the layout is a single layout, it will do nothing.\n * @returns {void}\n * @memberof LayoutManager\n */\n public changeLayout(): void {\n if (!this.isSingleLayout(this.layout)) {\n this.layout.changeLayout()\n }\n }\n\n /**\n * @description This function is used to decrease the row ratio between the pages in the selected row. This is propagated to the layout instance.\n * @param {quantity} quantity The amount of aspect ratio to be decreased.\n * @memberof LayoutManager\n * @example layout.decreaseRowRatio(0.01)\n */\n public decreaseRatio(quantity: number) {\n if (!this.isSingleLayout(this.layout)) {\n this.layout.decreaseRatio(quantity)\n }\n }\n\n /**\n * @description This function is used to increase the row ratio between the pages in the selected row. This is propagated to the layout instance.\n * @param {quantity} quantity The amount of aspect ratio to be increased.\n * @memberof LayoutManager\n * @example layout.increaseRowRatio(0.01)\n */\n public increaseRatio(quantity: number) {\n if (!this.isSingleLayout(this.layout)) {\n this.layout.increaseRatio(quantity)\n }\n }\n\n /**\n * @description This function is used to draw the layout to the screen.\n * @memberof LayoutManager\n * @returns {void}\n * @example layout.draw()\n */\n public draw(): void {\n this.layout.draw()\n }\n}\n\nexport default LayoutManager\n", "import { EventEmitter } from \"events\"\n\n/**\n * @typedef {Object} MouseEventArgs\n * @description This type is used to define the parameters of the Mouse Listener event (mouseevent) data.\n * \n * @prop {string} code - The code of the pressed key.\n * @prop {boolean} alt - If the alt key is pressed.\n * @prop {boolean} ctrl - If the ctrl key is pressed.\n * @prop {boolean} shift - If the shift key is pressed.\n * @prop {boolean} left - If the left mouse key is pressed.\n * @prop {boolean} right - If the right mouse key is pressed.\n * @prop {number} x - The x position of the mouse (terminal column).\n * @prop {number} y - The y position of the mouse (terminal row).\n * @prop {number | null} xFrom - The original x position of the mouse (terminal column) when the drag started.\n * @prop {number | null} yFrom - The original y position of the mouse (terminal row) when the drag started.\n *\n * @example const mouseEventArgs = { code: \"MOUSE\", alt: false, ctrl: false, shift: false, left: true, right: false, x: 10, y: 10, xFrom: null, yFrom: null }\n * \n * @export\n * @interface MouseEventArgs\n */\n// @type definition\nexport interface MouseEventArgs {\n code: number;\n alt: boolean;\n ctrl: boolean;\n shift: boolean;\n left: boolean;\n right: boolean;\n x: number;\n y: number;\n xFrom: number | null;\n yFrom: number | null;\n}\n\n/**\n * @typedef {Object} MouseEvent\n * @description This type is used to define the parameters of the Mouse Listener event (mouseevent).\n * available event names:\n * - MOUSE_MOTION: mouse moved (no button pressed / hover)\n * - MOUSE_DRAG: Valorized xFrom and yFrom. Use left or right to know which button is pressed.\n * - MOUSE_LEFT_BUTTON_PRESS\n * - MOUSE_LEFT_BUTTON_RELEASE\n * - MOUSE_RIGHT_BUTTON_PRESS\n * - MOUSE_RIGHT_BUTTON_RELEASE\n * - MOUSE_MIDDLE_BUTTON_PRESS\n * - MOUSE_MIDDLE_BUTTON_RELEASE\n * - MOUSE_WHEEL_UP\n * - MOUSE_WHEEL_DOWN\n * \n * @prop {string} name - The name of the event.\n * @prop {number} eaten - The number of eaten events.\n * @prop {MouseEventArgs} args - The arguments of the event.\n *\n * @example const mouseEvent = { name: \"MOUSE_MOTION\", eaten: 0, args: { code: \"MOUSE\", alt: false, ctrl: false, shift: false, left: true, right: false, x: 10, y: 10, xFrom: null, yFrom: null } }\n * \n * @export\n * @interface MouseEvent\n */\n// @type definition\nexport interface MouseEvent {\n name: string;\n eaten: number;\n data: MouseEventArgs;\n}\n\n/**\n * @typedef {Object} RelativeMouseEvent\n * @description This type is used to define the parameters of the Mouse Listener event (mouseevent) data, relative to a widget.\n * \n * @prop {string} name - The name of the event.\n * @prop {object} data - The data of the event.\n * @prop {number} data.x - The x position of the mouse (terminal column).\n * @prop {number} data.y - The y position of the mouse (terminal row).\n *\n * @export\n * @interface RelativeMouseEvent\n */\n// @type definition\nexport interface RelativeMouseEvent {\n name: string;\n data: {\n x: number;\n y: number;\n }\n}\n\n/**\n * @class MouseManager\n * @description This class is used to manage the mouse tracking events.\n * \n * \n * \n * Emits the following events: \n * - \"mouseevent\" when the user confirm\n * - \"error\" when an error occurs\n * @param {object} Terminal - The terminal object (process.stdout).\n * @emits mouseevent - The mouse event.\n * \n * @extends EventEmitter\n * @example const mouse = new MouseManager(process.stdout)\n */\nexport class MouseManager extends EventEmitter {\n Terminal: NodeJS.WriteStream\n Input: NodeJS.ReadStream\n prependStdinChunk: null | Buffer\n /** @const {Object} keymap - Object containing \"MOUSE\" array of key codes. */ \n keymap = {\n MOUSE: [\n { code: \"\\x1b[<\", event: \"mouse\", handler: \"mouseSGRProtocol\" },\n { code: \"\\x1b[M\", event: \"mouse\", handler: \"mouseX11Protocol\" }\n ]\n }\n /** @const {Object} state - Object containing the state of the mouse buttons. */\n state = {\n button: {\n left: null as null | { x: number, y: number },\n middle: null as null | { x: number, y: number },\n right: null as null | { x: number, y: number },\n other: null as null | { x: number, y: number }\n }\n }\n\n constructor(_Terminal: NodeJS.WriteStream, _Input: NodeJS.ReadStream) {\n super()\n this.Terminal = _Terminal\n this.Input = _Input\n this.prependStdinChunk = null\n }\n\n /**\n * @description Manage the mouse events for the x11 protocol.\n * @param {string} basename - The name of the event.\n * @param {Buffer} buffer - The data of the event.\n **/\n mouseX11Protocol = (basename: string, buffer: Buffer) => {\n const code = buffer[0]\n const result = {\n data: {\n shift: !!(code & 4),\n alt: !!(code & 8),\n ctrl: !!(code & 16),\n x: 0,\n y: 0,\n code: 0\n },\n name: \"\",\n eaten: 0\n } as MouseEvent\n\n if (code & 32) {\n if (code & 64) {\n result.name = basename + (code & 1 ? \"_WHEEL_DOWN\" : \"_WHEEL_UP\")\n }\n else {\n // Button event\n switch (code & 3) {\n case 0: result.name = basename + \"_LEFT_BUTTON_PRESSED\"; break\n case 1: result.name = basename + \"_MIDDLE_BUTTON_PRESSED\"; break\n case 2: result.name = basename + \"_RIGHT_BUTTON_PRESSED\"; break\n case 3: result.name = basename + \"_BUTTON_RELEASED\"; break\n }\n }\n }\n else if (code & 64) {\n // Motion event\n result.name = basename + \"_MOTION\"\n }\n\n result.eaten = 3\n result.data.code = code\n result.data.x = buffer[1] - 32\n result.data.y = buffer[2] - 32\n\n return result\n }\n\n /**\n * @description Manage the mouse events for the SGR protocol.\n * @param {string} basename - The name of the event.\n * @param {Buffer} buffer - The data of the event.\n **/\n mouseSGRProtocol = (basename: string, buffer: Buffer) => {\n const matches = buffer.toString().match(/^(-?[0-9]*);?([0-9]*);?([0-9]*)(M|m)/)\n\n if (!matches || matches[3].length === 0) {\n return {\n name: \"ERROR\",\n eaten: matches ? matches[0].length : 0,\n data: { matches }\n }\n }\n\n const code = parseInt(matches[1], 10)\n const pressed = matches[4] !== \"m\"\n\n const result = {\n data: {\n shift: !!(code & 4),\n alt: !!(code & 8),\n ctrl: !!(code & 16),\n // , pressed: pressed\n x: 0,\n y: 0,\n code: 0,\n left: false,\n right: false,\n xFrom: null,\n yFrom: null\n },\n name: \"\",\n eaten: 0\n } as MouseEvent\n\n result.data.x = parseInt(matches[2], 10)\n result.data.y = parseInt(matches[3], 10)\n result.eaten = matches[0].length\n\n if (code & 32) {\n // Motions / drag event\n\n switch (code & 3) {\n case 0:\n // Left drag, or maybe something else (left+right combo)\n result.name = basename + \"_DRAG\"\n result.data.left = true\n result.data.right = false\n result.data.xFrom = this.state.button.left ? this.state.button.left.x : null\n result.data.yFrom = this.state.button.left ? this.state.button.left.y : null\n break\n\n // Doesn\"t seem to exist, middle drag does not discriminate from motion\n //case 1 :\n\n case 2:\n // Right drag\n result.name = basename + \"_DRAG\"\n result.data.left = false\n result.data.right = true\n result.data.xFrom = this.state.button.right ? this.state.button.right.x : null\n result.data.yFrom = this.state.button.right ? this.state.button.right.y : null\n break\n\n case 3:\n default:\n result.name = basename + \"_MOTION\"\n break\n }\n }\n else if (code & 64) {\n result.name = basename + (code & 1 ? \"_WHEEL_DOWN\" : \"_WHEEL_UP\")\n }\n else {\n // Button event\n switch (code & 3) {\n case 0:\n result.name = basename + \"_LEFT_BUTTON\"\n //if ( this.state.button.left === pressed ) { result.disable = true ; }\n this.state.button.left = pressed ? result.data : null\n break\n\n case 1:\n result.name = basename + \"_MIDDLE_BUTTON\"\n //if ( this.state.button.middle === pressed ) { result.disable = true ; }\n this.state.button.middle = pressed ? result.data : null\n break\n\n case 2:\n result.name = basename + \"_RIGHT_BUTTON\"\n //if ( this.state.button.right === pressed ) { result.disable = true ; }\n this.state.button.right = pressed ? result.data : null\n break\n\n case 3:\n result.name = basename + \"_OTHER_BUTTON\"\n //if ( this.state.button.other === pressed ) { result.disable = true ; }\n this.state.button.other = pressed ? result.data : null\n break\n }\n\n result.name += pressed ? \"_PRESSED\" : \"_RELEASED\"\n }\n\n result.data.code = code\n\n return result\n }\n\n /**\n * @description Enables \"mouseevent\" event on the *input* stream. Note that `stream` must be\n * an *output* stream (i.e. a Writable Stream instance), usually `process.stdout`.\n *\n * @api public\n */\n public enableMouse() {\n process.on(\"exit\", () => {\n this.disableMouse()\n })\n //this.Terminal.write(\"\\x1b[?1000h\")\n this.Terminal.write(\"\\x1b[?1006h\")\n this.Terminal.write(\"\\x1b[?1003h\")\n this.Input.on(\"data\", this.onStdin)\n }\n\n /**\n * @description Disables \"mouseevent\" event from being sent to the *input* stream.\n * Note that `stream` must be an *output* stream (i.e. a Writable Stream instance),\n * usually `process.stdout`.\n *\n * @api public\n */\n public disableMouse() {\n //this.Terminal.write(\"\\x1b[?1000l\")\n this.Input.removeListener(\"data\", this.onStdin)\n this.Terminal.write(\"\\x1b[?1006l\")\n this.Terminal.write(\"\\x1b[?1003l\")\n }\n\n /**\n * @description Manage the stdin data to detect mouse events.\n * @param {Buffer} chunk - The data of the event.\n **/\n onStdin = (chunk: Buffer) => {\n let i, bytes, handlerResult, index = 0\n const length = chunk.length\n\n //if ( shutdown ) { return ; }\n\n if (this.prependStdinChunk) {\n chunk = Buffer.concat([this.prependStdinChunk, chunk])\n }\n\n while (index < length) {\n bytes = 1\n\n if (chunk[index] <= 0x1f || chunk[index] === 0x7f) {\n // Those are ASCII control character and DEL key\n //const buffer = chunk.subarray(index)\n //const keymapCode = buffer.toString()\n const startBuffer = chunk.subarray(index, 3)\n const keymapStartCode = startBuffer.toString()\n\n const mKeymap = this.keymap[\"MOUSE\"].filter(function (e: { code: string }) { return e.code === keymapStartCode })\n if (mKeymap.length > 0) {\n // First test fixed sequences\n if (mKeymap[0].handler) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - TS doesn't like the dynamic call\n handlerResult = this[mKeymap[0].handler].call(this, \"MOUSE\", chunk.subarray(index + 3))\n bytes = i + handlerResult.eaten\n\n if (!handlerResult.disable) {\n //console.log(\"emit:\", mKeymap[0].event, handlerResult.name, handlerResult.data)\n this.emit(\"mouseevent\", handlerResult)\n }\n }\n }\n }\n index += bytes\n }\n }\n\n /**\n * @description Test if the key is a part of the mouse event.\n * @param {{ code: string, sequence: string }} key - The key object to test.\n * @return {number} - 1 if the key is the header of a mouse event, -1 if is a body part, 0 otherwise.\n **/\n public isMouseFrame(key: { code: string, sequence: string }, lock: boolean): number {\n /* \n The only way we have to detect mouse events is to check the first key code of the sequence. \n it should one of the codes listed in: this.keymap[\"MOUSE\"][x].code\n To capture the end frame of a mouse event, we need to check the last key code of the sequence.\n it should be \"m\" or \"M\" (depending on the mouse mode)\n */\n if (key.code && this.keymap[\"MOUSE\"].filter((e: { code: string }) => e.code === key.sequence).length > 0) {\n return 1\n }\n if (lock) {\n if (key.sequence.toLowerCase() === \"m\") {\n return -1\n }\n return 1\n }\n return 0\n }\n}\n\nexport default MouseManager"],
"mappings": "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",
"names": ["EventEmitter", "readline", "boxChars", "truncate", "str", "n", "useWordBoundary", "visibleLength", "subString", "styledToSimplifiedStyled", "styled", "simplifiedStyledToStyled", "simplifiedStyled", "input", "regex", "PageBuilder", "rowsPerPage", "args", "_row", "arg", "simplifiedStyledToStyled", "height", "i", "index", "rpp", "PageBuilder_default", "InPageWidgetBuilder", "PageBuilder_default", "rowsPerPage", "InPageWidgetBuilder_default", "EventEmitter", "wrapAnsi16", "offset", "code", "wrapAnsi256", "wrapAnsi16m", "red", "green", "blue", "styles", "modifierNames", "foregroundColorNames", "backgroundColorNames", "colorNames", "assembleStyles", "codes", "groupName", "group", "styleName", "style", "hex", "matches", "colorString", "character", "integer", "remainder", "value", "result", "ansiStyles", "ansi_styles_default", "process", "os", "tty", "hasFlag", "flag", "argv", "prefix", "position", "terminatorPosition", "env", "flagForceColor", "envForceColor", "translateLevel", "level", "_supportsColor", "haveStream", "streamIsTTY", "sniffFlags", "noFlagForceColor", "forceColor", "min", "osRelease", "sign", "version", "createSupportsColor", "stream", "options", "supportsColor", "supports_color_default", "stringReplaceAll", "string", "substring", "replacer", "index", "substringLength", "endIndex", "returnValue", "stringEncaseCRLFWithFirstIndex", "prefix", "postfix", "gotCR", "stdoutColor", "stderrColor", "supports_color_default", "GENERATOR", "STYLER", "IS_EMPTY", "levelMapping", "styles", "applyOptions", "object", "options", "colorLevel", "chalkFactory", "options", "chalk", "strings", "applyOptions", "createChalk", "styleName", "style", "ansi_styles_default", "styles", "builder", "createBuilder", "createStyler", "STYLER", "IS_EMPTY", "getModelAnsi", "model", "level", "type", "arguments_", "usedModels", "styler", "levelMapping", "bgModel", "proto", "GENERATOR", "open", "close", "parent", "openAll", "closeAll", "self", "_styler", "_isEmpty", "applyStyle", "string", "stringReplaceAll", "lfIndex", "stringEncaseCRLFWithFirstIndex", "chalkStderr", "stderrColor", "source_default", "chalk", "source_default", "Screen", "EventEmitter", "_Terminal", "args", "row", "newStyleIndex", "i", "arg", "txt", "style", "visibleLength", "currentStyleIndex", "mergedStyleIndex", "x", "y", "outString", "color", "_in", "rgb", "bg", "italic", "bold", "dim", "underline", "overline", "inverse", "hidden", "strikethrough", "str", "index", "replacement", "startIndex", "newSize", "new_", "current", "offset", "_newSize", "merged", "newStyle", "a", "b", "Screen_default", "EventEmitter", "CustomPopup", "EventEmitter", "config", "id", "title", "content", "width", "visible", "event", "x", "y", "ConsoleManager", "message", "_str", "key", "checkResult", "newContent", "newWidth", "line", "unformattedLine", "newLine", "element", "visibleLength", "diff", "i", "truncate", "boxChars", "windowWidth", "halfWidth", "header", "EOL", "windowDesignLines", "centerScreen", "index", "_content", "EventEmitter", "ButtonPopup", "EventEmitter", "config", "id", "title", "message", "buttons", "visible", "event", "x", "y", "i", "button", "ConsoleManager", "_str", "key", "checkResult", "maxRowLength", "buttonGrid", "rowLength", "rows", "newButtonLength", "truncate", "windowWidth", "mstLines", "EOL", "line", "halfWidthTitle", "halfWidthMessage", "header", "boxChars", "footer", "content", "index", "buttonsYOffset", "centerScreen", "row", "k", "buttonLength", "sumRowLength", "a", "b", "emptySpace", "colIndex", "btnBoxType", "buttonPh", "windowDesignLines", "ButtonPopup_default", "ConfirmPopup", "ButtonPopup_default", "config", "id", "title", "message", "_str", "key", "checkResult", "EventEmitter", "fs", "path", "FileSelectorPopup", "EventEmitter", "config", "id", "title", "basePath", "selectDirectory", "allowedExtensions", "limitToPath", "visible", "event", "x", "y", "ind", "index", "ConsoleManager", "path", "message", "dir", "resolve", "reject", "fs", "err", "files", "file", "filePath", "isAllowed", "_path", "_str", "key", "checkResult", "selected", "ind1", "offset", "maxOptionsLength", "o", "max", "option", "windowWidth", "halfWidth", "header", "boxChars", "i", "EOL", "footer", "content", "windowDesignLines", "centerScreen", "line", "EventEmitter", "InputPopup", "EventEmitter", "config", "id", "title", "value", "numeric", "visible", "event", "x", "y", "ConsoleManager", "message", "_str", "key", "checkResult", "v", "tmp", "visibleLength", "newValue", "windowWidth", "halfWidth", "header", "boxChars", "i", "EOL", "footer", "windowDesign", "windowDesignLines", "centerScreen", "line", "index", "isOddSecond", "totalLength", "EventEmitter", "OptionPopup", "EventEmitter", "config", "id", "title", "options", "selected", "visible", "event", "x", "y", "index", "ConsoleManager", "message", "_str", "key", "checkResult", "offset", "maxOptionsLength", "o", "max", "option", "windowWidth", "halfWidth", "header", "boxChars", "i", "EOL", "footer", "content", "windowDesignLines", "centerScreen", "line", "EventEmitter", "Control", "EventEmitter", "config", "event", "x", "y", "popups", "i", "popup", "popupPosition", "relativeMouseEvent", "ConsoleManager", "message", "_str", "key", "checkResult", "line", "unformattedLine", "newLine", "element", "visibleLength", "diff", "j", "truncate", "index", "Control_default", "Box", "Control_default", "config", "tmpSizes", "pv", "InPageWidgetBuilder_default", "absVal", "truncatedText", "truncate", "boxChars", "visibleLength", "rowlength", "acc", "curr", "spaces", "styledArr", "i", "text", "style", "content", "key", "e", "line", "unformattedLine", "newLine", "element", "diff", "j", "styledToSimplifiedStyled", "Button", "Control_default", "config", "tmpSizes", "pv", "InPageWidgetBuilder_default", "absVal", "truncatedText", "truncate", "boxChars", "text", "style", "enabled", "event", "drawingChars", "boxChars", "Progress", "Control_default", "config", "orientation", "length", "thickness", "width", "height", "pv", "InPageWidgetBuilder_default", "styledProgress", "percentage", "blocks", "blocksToFill", "lastBlockPercentage", "fullBlocks", "emptyBlocks", "i", "lastBlockPercentageKey", "key", "lastBlockPercentageValue", "progress", "ch", "boxC", "singleLine", "perc", "textLine", "valuesString", "row", "newthickness", "j", "value", "max", "min", "label", "style", "enabled", "event", "DoubleLayout", "page1", "page2", "options", "selected", "ConsoleManager", "page", "index", "titles", "title", "border", "ratio", "quantity", "line", "secondLine", "dir", "bsize", "unformattedLine", "newLine", "element", "e", "i", "visibleLength", "width", "diff", "j", "truncate", "boxChars", "ret", "trimmedTitle", "pageHeights", "decorationHeight", "halfHeight", "maxPageHeight", "p1", "p2", "DoubleLayout_default", "QuadLayout", "page1", "page2", "page3", "page4", "options", "selected", "ConsoleManager", "page", "index", "titles", "title", "border", "ratio", "quantity", "line", "secondLine", "row", "bsize", "unformattedLine", "newLine", "element", "e", "i", "diff", "j", "truncate", "ret", "boxChars", "trimmedTitle", "maxPageHeight", "decorationHeight", "p", "first", "second", "str", "str2", "QuadLayout_default", "SingleLayout", "page", "options", "ConsoleManager", "title", "border", "line", "bsize", "unformattedLine", "newLine", "element", "diff", "j", "truncate", "boxChars", "trimmedTitle", "i", "SingleLayout_default", "LayoutManager", "pages", "options", "x", "SingleLayout_default", "ConsoleManager", "page", "index", "DoubleLayout_default", "QuadLayout_default", "title", "titles", "border", "selected", "quantity", "LayoutManager_default", "EventEmitter", "MouseManager", "_Terminal", "_Input", "basename", "buffer", "code", "result", "matches", "pressed", "chunk", "i", "bytes", "handlerResult", "index", "length", "keymapStartCode", "mKeymap", "e", "key", "lock", "EOL", "ConsoleManager", "EventEmitter", "options", "Screen_default", "err", "MouseManager", "PageBuilder_default", "readline", "update", "LayoutManager_default", "page", "index", "size", "widget", "key", "_str", "checkResult", "change", "focusedWidget", "found", "e", "id", "manageFunction", "popup", "control", "pageNumber", "title", "pages", "titles", "CustomPopup", "message", "resetCursor"]
}