diff options
| -rw-r--r-- | .eslintrc.yaml | 29 | ||||
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | editor/editor.d.ts | 110 | ||||
| -rw-r--r-- | editor/editor.ts | 436 | ||||
| -rw-r--r-- | editor/example.ts | 14 | ||||
| -rw-r--r-- | input/checkboxes.d.ts | 48 | ||||
| -rw-r--r-- | input/checkboxes.ts | 42 | ||||
| -rw-r--r-- | input/example.ts | 132 | ||||
| -rw-r--r-- | input/number.d.ts | 52 | ||||
| -rw-r--r-- | input/number.ts | 8 | ||||
| -rw-r--r-- | input/option.d.ts | 4 | ||||
| -rw-r--r-- | input/select.d.ts | 56 | ||||
| -rw-r--r-- | input/select.ts | 29 | ||||
| -rw-r--r-- | input/string.d.ts | 46 | ||||
| -rw-r--r-- | input/string.ts | 4 | ||||
| -rw-r--r-- | notif/example.ts | 34 | ||||
| -rw-r--r-- | notif/notif.d.ts | 12 | ||||
| -rw-r--r-- | notif/notif.ts | 16 | ||||
| -rw-r--r-- | package-lock.json | 2116 | ||||
| -rw-r--r-- | package.json | 12 | ||||
| -rw-r--r-- | response.d.ts | 6 | ||||
| -rw-r--r-- | response.ts | 2 | ||||
| -rw-r--r-- | tsconfig.json | 21 | ||||
| -rw-r--r-- | vfs/example.ts | 28 | ||||
| -rw-r--r-- | vfs/vfs.d.ts | 40 | ||||
| -rw-r--r-- | vfs/vfs.ts | 77 | ||||
| -rw-r--r-- | websocket_client.d.ts | 64 | ||||
| -rw-r--r-- | websocket_client.ts | 37 |
28 files changed, 2842 insertions, 644 deletions
diff --git a/.eslintrc.yaml b/.eslintrc.yaml new file mode 100644 index 0000000..9c2b441 --- /dev/null +++ b/.eslintrc.yaml @@ -0,0 +1,29 @@ +root: true +extends: google +parserOptions: + ecmaVersion: 2018 +rules: + require-jsdoc: 'off' + indent: 'off' + arrow-parens: 'off' + comma-dangle: ['error', {'functions': 'never'}] +overrides: + - files: + - '*.ts' + parser: '@typescript-eslint/parser' + env: + browser: true + plugins: + - '@typescript-eslint' + extends: + - eslint:recommended + - plugin:@typescript-eslint/recommended + - plugin:prettier/recommended + rules: + valid-jsdoc: + - error + - requireParamType: false + requireReturnType: false + requireReturn: false +ignorePatterns: + - '*.js' @@ -1,10 +1,17 @@ ## SPDX-FileCopyrightText: 2021 M. Shulhan <ms@kilabit.info> ## SPDX-License-Identifier: GPL-3.0-or-later -.PHONY: all watch +.PHONY: all +all: build lint -all: +.PHONY: lint +lint: + npx eslint --fix . + +.PHONY: build +build: tsc --outDir . +.PHONY: watch watch: tsc --outDir . --watch diff --git a/editor/editor.d.ts b/editor/editor.d.ts index ccd669e..29ab3b6 100644 --- a/editor/editor.d.ts +++ b/editor/editor.d.ts @@ -1,63 +1,67 @@ import { WuiVfsNodeInterface } from "../vfs/vfs"; export interface WuiEditorOptions { - id: string; - is_editable: boolean; - OnSelection(begin: number, end: number): void; - OnSave(content: string): void; + id: string; + is_editable: boolean; + OnSelection(begin: number, end: number): void; + OnSave(content: string): void; } export declare class WuiEditor { - opts: WuiEditorOptions; - id: string; - is_editable: boolean; - lines: WuiEditorLine[]; - private el; - private sel; - private active_file; - private active_text; - private range_begin; - private range_end; - private raw_lines; - private range; - private is_key_control; - private unre; - constructor(opts: WuiEditorOptions); - GetContent(): string; - GetSelectionRange(): WuiEditorSelectionRangeInterface; - OnClickText(text: HTMLElement): void; - OnKeyup(x: number, text: HTMLElement, ev: KeyboardEvent): boolean | undefined; - OnKeydownOnLine(x: number, el_text: HTMLElement, ev: KeyboardEvent): false | undefined; - OnMouseDownAtLine(x: number): void; - OnMouseUpAtLine(x: number): void; - SetEditOff(): void; - SetEditOn(): void; - Open(node: WuiVfsNodeInterface): void; - ClearSelection(): void; - private initStyle; - private doJoin; - private doSplit; - private doUpdate; - private doRedo; - private doUndo; - private deleteLine; - private insertNewline; - private onKeyupDocument; - private render; - private setCaret; + opts: WuiEditorOptions; + id: string; + is_editable: boolean; + lines: WuiEditorLine[]; + private el; + private sel; + private active_file; + private active_text; + private range_begin; + private range_end; + private raw_lines; + private range; + private is_key_control; + private unre; + constructor(opts: WuiEditorOptions); + GetContent(): string; + GetSelectionRange(): WuiEditorSelectionRangeInterface; + OnClickText(text: HTMLElement): void; + OnKeyup(x: number, text: HTMLElement, ev: KeyboardEvent): boolean | undefined; + OnKeydownOnLine( + x: number, + el_text: HTMLElement, + ev: KeyboardEvent, + ): false | undefined; + OnMouseDownAtLine(x: number): void; + OnMouseUpAtLine(x: number): void; + SetEditOff(): void; + SetEditOn(): void; + Open(node: WuiVfsNodeInterface): void; + ClearSelection(): void; + private initStyle; + private doJoin; + private doSplit; + private doUpdate; + private doRedo; + private doUndo; + private deleteLine; + private insertNewline; + private onKeyupDocument; + private render; + private setCaret; } declare class WuiEditorLine { - x: number; - text: string; - private line_num; - el: HTMLElement; - el_number: HTMLElement; - el_text: HTMLElement; - constructor(x: number, text: string, ed: WuiEditor); - SetNumber(x: number): void; - SetEditOn(): void; - SetEditOff(): void; + x: number; + text: string; + private line_num; + el: HTMLElement; + el_number: HTMLElement; + el_text: HTMLElement; + constructor(x: number, text: string, ed: WuiEditor); + SetNumber(x: number): void; + SetEditOn(): void; + SetEditOff(): void; } interface WuiEditorSelectionRangeInterface { - begin_at: number; - end_at: number; + begin_at: number; + end_at: number; } export {}; diff --git a/editor/editor.ts b/editor/editor.ts index b8fd42a..0e919ab 100644 --- a/editor/editor.ts +++ b/editor/editor.ts @@ -13,10 +13,10 @@ export interface WuiEditorOptions { is_editable: boolean; // Handler that will be called when user select lines. - OnSelection(begin: number, end: number): void; + onSelection(begin: number, end: number): void; // Handler that will be called when user press CTRL+S. - OnSave(content: string): void; + onSave(content: string): void; } export class WuiEditor { @@ -25,8 +25,6 @@ export class WuiEditor { lines: WuiEditorLine[] = []; private el!: HTMLElement; private sel!: Selection; - private active_file: WuiVfsNodeInterface | null = null; - private active_text: HTMLElement | null = null; private range_begin: number = -1; private range_end: number = -1; private raw_lines: string[] = []; @@ -38,7 +36,7 @@ export class WuiEditor { this.id = opts.id; this.is_editable = opts.is_editable; - let el = document.getElementById(opts.id); + const el = document.getElementById(opts.id); if (!el) { console.error("WuiEditor: element ID not found:", opts.id); return; @@ -49,7 +47,7 @@ export class WuiEditor { this.el.classList.add(WUI_EDITOR_CLASS); - let sel = window.getSelection(); + const sel = window.getSelection(); if (!sel) { console.error("WuiEditor: cannot get window selection", opts.id); return; @@ -62,35 +60,37 @@ export class WuiEditor { }; } - // GetContent return content of file. - GetContent(): string { + // getContent return content of file. + getContent(): string { let content = ""; for (let x = 0; x < this.lines.length; x++) { if (x > 0) { content += "\n"; } - content += this.lines[x].el_text.innerText; + content += this.lines[x]!.elText.innerText; } return content; } - GetSelectionRange(): WuiEditorSelectionRangeInterface { + getSelectionRange(): RangeInterface { return { begin_at: this.range_begin, end_at: this.range_end, - } as WuiEditorSelectionRangeInterface; + } as RangeInterface; } - OnClickText(text: HTMLElement) { - let sel = window.getSelection(); + onClickText() { + const sel = window.getSelection(); if (sel) { this.sel = sel; } } - OnKeyup(x: number, text: HTMLElement, ev: KeyboardEvent) { - let text_before: string; - let text_after: string; + onKeyup(x: number, ev: KeyboardEvent) { + let elTextCurr: HTMLElement; + let elTextPrev: HTMLElement; + let textBefore: string; + let textAfter: string; let off: number; switch (ev.key) { @@ -116,32 +116,31 @@ export class WuiEditor { case "Backspace": ev.preventDefault(); - text_before = this.raw_lines[x]; - let el_text_curr = this.lines[x].el_text; - text_after = el_text_curr.innerText; + textBefore = this.raw_lines[x]!; + elTextCurr = this.lines[x]!.elText; + textAfter = elTextCurr.innerText; off = this.sel.focusOffset; if (off > 0) { - this.unre.DoUpdate(x, text_before, text_after); + this.unre.doUpdate(x, textBefore, textAfter); - this.raw_lines[x] = text_after; - this.setCaret(el_text_curr, off); + this.raw_lines[x] = textAfter; + this.setCaret(elTextCurr, off); return false; } // Join current line with previous. - let el_text_prev = this.lines[x - 1].el_text; + elTextPrev = this.lines[x - 1]!.elText; - this.unre.DoJoin(x - 1, el_text_prev.innerText, el_text_curr.innerText); + this.unre.doJoin(x - 1, elTextPrev.innerText, elTextCurr.innerText); - off = el_text_prev.innerText.length; - el_text_prev.innerText = - el_text_prev.innerText + el_text_curr.innerText; - this.raw_lines[x - 1] = el_text_prev.innerText; + off = elTextPrev.innerText.length; + elTextPrev.innerText = elTextPrev.innerText + elTextCurr.innerText; + this.raw_lines[x - 1] = elTextPrev.innerText; // Remove the current line this.deleteLine(x); - this.setCaret(el_text_prev, off); + this.setCaret(elTextPrev, off); return false; case "Control": @@ -170,20 +169,24 @@ export class WuiEditor { if (this.is_key_control) { break; } - this.unre.DoUpdate( + this.unre.doUpdate( x, - this.raw_lines[x], - this.lines[x].el_text.innerText, + this.raw_lines[x]!, + this.lines[x]!.elText.innerText, ); - this.raw_lines[x] = this.lines[x].el_text.innerText; + this.raw_lines[x] = this.lines[x]!.elText.innerText; } return true; } - OnKeydownOnLine(x: number, el_text: HTMLElement, ev: KeyboardEvent) { - let text_before: string; - let text_after: string; + onKeydownOnLine(x: number, ev: KeyboardEvent) { + let textBefore: string; + let textAfter: string; let off: number; + let elText: HTMLElement | undefined; + let elTextCurrent: HTMLElement; + let text: string; + let isJoinLineAfter: boolean; switch (ev.key) { case "ArrowUp": @@ -192,12 +195,12 @@ export class WuiEditor { } ev.preventDefault(); - let el_text = this.lines[x - 1].el_text; - let off = this.sel.focusOffset; - if (off > el_text.innerText.length) { - off = el_text.innerText.length; + elText = this.lines[x - 1]!.elText; + off = this.sel.focusOffset; + if (off > elText.innerText.length) { + off = elText.innerText.length; } - this.setCaret(el_text, off); + this.setCaret(elText, off); if (x == 1) { this.el.scrollTop = 0; @@ -212,12 +215,12 @@ export class WuiEditor { } ev.preventDefault(); - el_text = this.lines[x + 1].el_text; + elText = this.lines[x + 1]!.elText; off = this.sel.focusOffset; - if (off > el_text.innerText.length) { - off = el_text.innerText.length; + if (off > elText.innerText.length) { + off = elText.innerText.length; } - this.setCaret(el_text, off); + this.setCaret(elText, off); x += 2; if (x * 25 >= this.el.clientHeight + this.el.scrollTop) { @@ -232,59 +235,60 @@ export class WuiEditor { case "Delete": ev.preventDefault(); - let is_join_line_after = false; - let el_text_current = this.lines[x].el_text; + isJoinLineAfter = false; + elTextCurrent = this.lines[x]!.elText; off = this.sel.focusOffset; - text_before = el_text_current.innerText; - text_after = ""; + textBefore = elTextCurrent.innerText; + textAfter = ""; - if (text_before.length === 0 || off === text_before.length) { + if (textBefore.length === 0 || off === textBefore.length) { // Current line is empty, join the next line to current // line; or // Current offset is at the end of text, join the next // line to current line. - is_join_line_after = true; + isJoinLineAfter = true; } - if (is_join_line_after) { + if (isJoinLineAfter) { if (x + 1 < this.lines.length) { - let el_text_after = this.lines[x + 1].el_text; - text_after = el_text_after.innerText; - el_text_after.innerText = ""; + const elTextAfter = this.lines[x + 1]!.elText; + textAfter = elTextAfter.innerText; + elTextAfter.innerText = ""; - this.unre.DoJoin(x, text_before, text_after); + this.unre.doJoin(x, textBefore, textAfter); this.deleteLine(x + 1); - text_after = text_before + text_after; + textAfter = textBefore + textAfter; } } else { - text_after = - text_before.slice(0, off) + - text_before.slice(off + 1, text_before.length); + textAfter = + textBefore.slice(0, off) + + textBefore.slice(off + 1, textBefore.length); - this.unre.DoUpdate(x, text_before, text_after); + this.unre.doUpdate(x, textBefore, textAfter); } - this.lines[x].el_text.innerText = text_after; - this.raw_lines[x] = text_after; - this.setCaret(el_text_current, off); + this.lines[x]!.elText.innerText = textAfter; + this.raw_lines[x] = textAfter; + this.setCaret(elTextCurrent, off); break; case "Enter": ev.preventDefault(); + elText = this.lines[x]!.elText; off = this.sel.focusOffset; - let text = this.lines[x].el_text.innerText; - text_before = text.slice(0, off); - text_after = text.slice(off, text.length); + text = elText.innerText; + textBefore = text.slice(0, off); + textAfter = text.slice(off, text.length); - this.unre.DoSplit(x, text_before, text_after); + this.unre.doSplit(x, textBefore, textAfter); - this.lines[x].el_text.innerText = text_before; - this.raw_lines[x] = text_before; + elText.innerText = textBefore; + this.raw_lines[x] = textBefore; - this.insertNewline(x + 1, text_after); + this.insertNewline(x + 1, textAfter); if (x + 3 >= this.raw_lines.length) { this.el.scrollTop = this.el.scrollHeight; } @@ -293,19 +297,23 @@ export class WuiEditor { case "Tab": ev.preventDefault(); - el_text = this.lines[x].el_text; + elText = this.lines[x]?.elText; + if (!elText) { + break; + } + off = this.sel.focusOffset; - text_before = el_text.innerText; - text_after = - text_before.slice(0, off) + + textBefore = elText.innerText; + textAfter = + textBefore.slice(0, off) + "\t" + - text_before.slice(off, text_before.length); + textBefore.slice(off, textBefore.length); - this.unre.DoUpdate(x, text_before, text_after); - el_text.innerText = text_after; - this.raw_lines[x] = text_after; + this.unre.doUpdate(x, textBefore, textAfter); + elText.innerText = textAfter; + this.raw_lines[x] = textAfter; - this.setCaret(el_text, off + 1); + this.setCaret(elText, off + 1); break; case "r": @@ -320,8 +328,8 @@ export class WuiEditor { if (this.is_key_control) { ev.preventDefault(); ev.stopPropagation(); - if (this.opts.OnSave) { - this.opts.OnSave(this.GetContent()); + if (this.opts.onSave) { + this.opts.onSave(this.getContent()); } return false; } @@ -335,82 +343,80 @@ export class WuiEditor { } break; } + return true; } - OnMouseDownAtLine(x: number) { + onMouseDownAtLine(x: number) { this.range_begin = x; } - OnMouseUpAtLine(x: number) { + onMouseUpAtLine(x: number) { this.range_end = x; if (this.range_end < this.range_begin) { return; } let y = 0; for (; y < this.range_begin; y++) { - this.el.children[y].setAttribute("style", ""); + this.el.children[y]?.setAttribute("style", ""); } for (; y <= this.range_end; y++) { - this.el.children[y].setAttribute("style", "background-color:lightsalmon"); + this.el.children[y]?.setAttribute( + "style", + "background-color:lightsalmon", + ); } for (; y < this.el.children.length; y++) { - this.el.children[y].setAttribute("style", ""); + this.el.children[y]?.setAttribute("style", ""); } - if (this.opts.OnSelection) { - this.opts.OnSelection(this.range_begin, this.range_end); + if (this.opts.onSelection) { + this.opts.onSelection(this.range_begin, this.range_end); } } - // - // SetEditOff make the content not editable. - // - SetEditOff() { - for (let x = 0; x < this.lines.length; x++) { - this.lines[x].SetEditOff(); - } + // setEditOff make the content not editable. + setEditOff() { + this.lines.forEach((line) => { + line.setEditOff(); + }); } - // - // SetEditOn make the content to be editable. - // - SetEditOn() { - for (let x = 0; x < this.lines.length; x++) { - this.lines[x].SetEditOn(); - } + // setEditOn make the content to be editable. + setEditOn() { + this.lines.forEach((line) => { + line.setEditOn(); + }); } - // Open the node for editing. + // open the node for editing. // The content MUST be encoded in base64. - Open(node: WuiVfsNodeInterface): void { - this.active_file = node; - + open(node: WuiVfsNodeInterface): void { let content = atob(node.content); content = content.replace("\r\n", "\n"); this.raw_lines = content.split("\n"); this.lines = []; - for (let x = 0; x < this.raw_lines.length; x++) { - let line = new WuiEditorLine(x, this.raw_lines[x], this); + this.raw_lines.forEach((rawLine, x) => { + const line = new WuiEditorLine(x, rawLine, this); this.lines.push(line); - } + }); this.render(); } - // ClearSelection clear selection range indicator. - ClearSelection() { + // clearSelection clear selection range indicator. + clearSelection() { if (this.range_begin < 0 || this.range_end == 0) { return; } for (let x = this.range_begin; x <= this.range_end; x++) { - this.el.children[x].setAttribute("style", ""); + this.el.children[x]?.setAttribute("style", ""); } this.range_begin = -1; this.range_end = -1; } private initStyle() { - let style = document.createElement("style"); + const style = document.createElement("style"); style.type = "text/css"; style.innerText = ` [contenteditable] { @@ -452,24 +458,36 @@ export class WuiEditor { document.head.appendChild(style); } - private doJoin(changes: WuiEditorActionChangesInterface) { - this.lines[changes.curr_line].el_text.innerText = changes.curr_text; - this.deleteLine(changes.next_line); - this.setCaret(this.lines[changes.curr_line].el_text, 0); + private doJoin(changes: ChangesInterface) { + const line = this.lines[changes.currLine]; + if (!line) { + return; + } + line.elText.innerText = changes.currText; + this.deleteLine(changes.nextLine); + this.setCaret(line.elText, 0); } - private doSplit(changes: WuiEditorActionChangesInterface) { - this.lines[changes.curr_line].el_text.innerText = changes.curr_text; - this.insertNewline(changes.next_line, changes.next_text); + private doSplit(changes: ChangesInterface) { + const line = this.lines[changes.currLine]; + if (!line) { + return; + } + line.elText.innerText = changes.currText; + this.insertNewline(changes.nextLine, changes.nextText); } - private doUpdate(changes: WuiEditorActionChangesInterface) { - this.lines[changes.curr_line].el_text.innerText = changes.curr_text; - this.setCaret(this.lines[changes.curr_line].el_text, 0); + private doUpdate(changes: ChangesInterface) { + const line = this.lines[changes.currLine]; + if (!line) { + return; + } + line.elText.innerText = changes.currText; + this.setCaret(line.elText, 0); } private doRedo() { - const act = this.unre.Redo(); + const act = this.unre.redo(); if (!act) { return; } @@ -487,7 +505,7 @@ export class WuiEditor { } private doUndo() { - const act = this.unre.Undo(); + const act = this.unre.undo(); if (!act) { return; } @@ -510,29 +528,29 @@ export class WuiEditor { // Reset the line numbers. for (; x < this.lines.length; x++) { - this.lines[x].SetNumber(x); + this.lines[x]?.setNumber(x); } this.render(); } private insertNewline(x: number, text: string) { - let newline = new WuiEditorLine(x, text, this); + const newline = new WuiEditorLine(x, text, this); for (let y = x; y < this.lines.length; y++) { - this.lines[y].SetNumber(y + 1); + this.lines[y]?.setNumber(y + 1); } this.lines.splice(x, 0, newline); this.raw_lines.splice(x, 0, text); this.render(); - this.setCaret(newline.el_text, 0); + this.setCaret(newline.elText, 0); } private onKeyupDocument(ed: WuiEditor, ev: KeyboardEvent) { switch (ev.key) { case "Escape": ev.preventDefault(); - ed.ClearSelection(); + ed.clearSelection(); break; } return true; @@ -545,11 +563,11 @@ export class WuiEditor { } } - private setCaret(el_text: HTMLElement, off: number) { - if (el_text.firstChild) { - this.range.setStart(el_text.firstChild, off); + private setCaret(elText: HTMLElement, off: number) { + if (elText.firstChild) { + this.range.setStart(elText.firstChild, off); } else { - this.range.setStart(el_text, off); + this.range.setStart(elText, off); } this.range.collapse(true); this.sel.removeAllRanges(); @@ -558,48 +576,48 @@ export class WuiEditor { } class WuiEditorLine { - private line_num: number = 0; + private lineNum: number = 0; el!: HTMLElement; el_number!: HTMLElement; - el_text!: HTMLElement; + elText!: HTMLElement; constructor( public x: number, public text: string, ed: WuiEditor, ) { - this.line_num = x; + this.lineNum = x; this.el = document.createElement("div"); this.el.classList.add(WUI_EDITOR_CLASS_LINE); this.el_number = document.createElement("span"); this.el_number.classList.add(WUI_EDITOR_CLASS_LINE_NUMBER); - this.el_number.innerText = this.line_num + 1 + ""; + this.el_number.innerText = this.lineNum + 1 + ""; - this.el_number.onmousedown = (ev: MouseEvent) => { - ed.OnMouseDownAtLine(this.line_num); + this.el_number.onmousedown = () => { + ed.onMouseDownAtLine(this.lineNum); }; - this.el_number.onmouseup = (ev: MouseEvent) => { - ed.OnMouseUpAtLine(this.line_num); + this.el_number.onmouseup = () => { + ed.onMouseUpAtLine(this.lineNum); }; - this.el_text = document.createElement("span"); - this.el_text.classList.add(WUI_EDITOR_CLASS_LINE_TEXT); - this.el_text.innerText = text; - this.el_text.contentEditable = "true"; + this.elText = document.createElement("span"); + this.elText.classList.add(WUI_EDITOR_CLASS_LINE_TEXT); + this.elText.innerText = text; + this.elText.contentEditable = "true"; - this.el_text.onclick = (ev: MouseEvent) => { - ed.OnClickText(this.el_text); + this.elText.onclick = () => { + ed.onClickText(); }; - this.el_text.onkeydown = (ev: KeyboardEvent) => { - return ed.OnKeydownOnLine(this.line_num, this.el_text, ev); + this.elText.onkeydown = (ev: KeyboardEvent) => { + return ed.onKeydownOnLine(this.lineNum, ev); }; - this.el_text.onkeyup = (ev: KeyboardEvent) => { - return ed.OnKeyup(this.line_num, this.el_text, ev); + this.elText.onkeyup = (ev: KeyboardEvent) => { + return ed.onKeyup(this.lineNum, ev); }; - this.el_text.addEventListener("paste", (ev: ClipboardEvent) => { + this.elText.addEventListener("paste", (ev: ClipboardEvent) => { if (!ev.clipboardData) { return; } @@ -609,20 +627,20 @@ class WuiEditorLine { }); this.el.appendChild(this.el_number); - this.el.appendChild(this.el_text); + this.el.appendChild(this.elText); } - SetNumber(x: number) { - this.line_num = x; + setNumber(x: number) { + this.lineNum = x; this.el_number.innerText = x + 1 + ""; } - SetEditOn() { - this.el_text.contentEditable = "true"; + setEditOn() { + this.elText.contentEditable = "true"; } - SetEditOff() { - this.el_text.contentEditable = "false"; + setEditOff() { + this.elText.contentEditable = "false"; } } @@ -631,23 +649,22 @@ class WuiEditorLine { // class WuiEditorUndoRedo { private idx: number = 0; - private actions: WuiEditorActionInterface[] = []; + private actions: ActionInterface[] = []; - DoJoin(prevLine: number, prevText: string, curr_text: string) { - let curr_line = prevLine + 1; - let action: WuiEditorActionInterface = { + doJoin(prevLine: number, prevText: string, currText: string) { + const action: ActionInterface = { kind: "join", before: { - curr_line: prevLine, - curr_text: prevText, - next_line: prevLine + 1, - next_text: curr_text, + currLine: prevLine, + currText: prevText, + nextLine: prevLine + 1, + nextText: currText, }, after: { - curr_line: prevLine, - curr_text: prevText + curr_text, - next_line: prevLine + 1, - next_text: "", + currLine: prevLine, + currText: prevText + currText, + nextLine: prevLine + 1, + nextText: "", }, }; if (this.actions.length > 0) { @@ -657,20 +674,20 @@ class WuiEditorUndoRedo { this.idx++; } - DoSplit(curr_line: number, curr_text: string, next_text: string) { - let action = { + doSplit(currLine: number, currText: string, nextText: string) { + const action = { kind: "split", before: { - curr_line: curr_line, - curr_text: curr_text + next_text, - next_line: curr_line + 1, - next_text: "", + currLine: currLine, + currText: currText + nextText, + nextLine: currLine + 1, + nextText: "", }, after: { - curr_line: curr_line, - curr_text: curr_text, - next_line: curr_line + 1, - next_text: next_text, + currLine: currLine, + currText: currText, + nextLine: currLine + 1, + nextText: nextText, }, }; if (this.actions.length > 0) { @@ -680,20 +697,20 @@ class WuiEditorUndoRedo { this.idx++; } - DoUpdate(line_num: number, text_before: string, text_after: string) { - const action: WuiEditorActionInterface = { + doUpdate(lineNum: number, textBefore: string, textAfter: string) { + const action: ActionInterface = { kind: "update", before: { - curr_line: line_num, - curr_text: text_before, - next_line: 0, - next_text: "", + currLine: lineNum, + currText: textBefore, + nextLine: 0, + nextText: "", }, after: { - curr_line: line_num, - curr_text: text_after, - next_line: 0, - next_text: "", + currLine: lineNum, + currText: textAfter, + nextLine: 0, + nextText: "", }, }; @@ -704,19 +721,26 @@ class WuiEditorUndoRedo { this.idx++; } - Undo(): WuiEditorActionInterface | null { + undo(): ActionInterface | null { if (this.idx == 0) { return null; } this.idx--; - return this.actions[this.idx]; + const action = this.actions[this.idx]; + if (!action) { + return null; + } + return action; } - Redo(): WuiEditorActionInterface | null { + redo(): ActionInterface | null { if (this.idx == this.actions.length) { return null; } - let action = this.actions[this.idx]; + const action = this.actions[this.idx]; + if (!action) { + return null; + } this.idx++; return action; } @@ -728,20 +752,20 @@ class WuiEditorUndoRedo { // * split: split line using enter // * join: join line using backspace. // -interface WuiEditorActionInterface { +interface ActionInterface { kind: string; - before: WuiEditorActionChangesInterface; - after: WuiEditorActionChangesInterface; + before: ChangesInterface; + after: ChangesInterface; } -interface WuiEditorActionChangesInterface { - curr_line: number; - curr_text: string; - next_line: number; - next_text: string; +interface ChangesInterface { + currLine: number; + currText: string; + nextLine: number; + nextText: string; } -interface WuiEditorSelectionRangeInterface { +interface RangeInterface { begin_at: number; end_at: number; } diff --git a/editor/example.ts b/editor/example.ts index 19bc0b9..a967045 100644 --- a/editor/example.ts +++ b/editor/example.ts @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: 2019 M. Shulhan <ms@kilabit.info> // SPDX-License-Identifier: GPL-3.0-or-later -import { WuiEditor, WuiEditorOptions } from "./editor.js"; +import { WuiEditor } from "./editor.js"; import { WuiVfsNodeInterface } from "../vfs/vfs.js"; -let nodeFile: WuiVfsNodeInterface = { +const nodeFile: WuiVfsNodeInterface = { name: "Test", path: "/test", is_dir: false, @@ -46,15 +46,15 @@ sudo systemctl status telegraf `), }; -let opts = { +const opts = { id: "editor", is_editable: true, - OnSelection: (begin: number, end: number) => { + onSelection: (begin: number, end: number) => { console.log("OnSelection: ", begin, end); }, - OnSave: (content: string) => { + onSave: (content: string) => { console.log("OnSave: ", content); }, }; -let wuiEditor = new WuiEditor(opts); -wuiEditor.Open(nodeFile); +const wuiEditor = new WuiEditor(opts); +wuiEditor.open(nodeFile); diff --git a/input/checkboxes.d.ts b/input/checkboxes.d.ts index dde0476..e0cced0 100644 --- a/input/checkboxes.d.ts +++ b/input/checkboxes.d.ts @@ -1,33 +1,33 @@ import { WuiInputOption } from "./option.js"; export interface WuiKeyValue { - [key: string]: string; + [key: string]: string; } export interface WuiKeySelectOption { - [key: string]: WuiInputOption; + [key: string]: WuiInputOption; } export interface WuiInputCheckboxesOpts { - label: string; - name: string; - options: WuiKeySelectOption; - id?: string; - hint?: string; - is_disabled?: boolean; - is_hint_toggled?: boolean; - onChangeHandler?: (values: string[]) => void; + label: string; + name: string; + options: WuiKeySelectOption; + id?: string; + hint?: string; + is_disabled?: boolean; + is_hint_toggled?: boolean; + onChangeHandler?: (values: string[]) => void; } export declare class WuiInputCheckboxes { - opts: WuiInputCheckboxesOpts; - el: HTMLElement; - private el_label; - private el_fieldset; - private el_hint; - private el_hint_toggler; - private values; - constructor(opts: WuiInputCheckboxesOpts); - private generateLabel; - private generateInput; - private generateHintToggler; - private generateHint; - private onClickHintToggler; - private onClickCheckbox; + opts: WuiInputCheckboxesOpts; + el: HTMLElement; + private el_label; + private el_fieldset; + private el_hint; + private el_hint_toggler; + private values; + constructor(opts: WuiInputCheckboxesOpts); + private generateLabel; + private generateInput; + private generateHintToggler; + private generateHint; + private onClickHintToggler; + private onClickCheckbox; } diff --git a/input/checkboxes.ts b/input/checkboxes.ts index 72d3da8..7226a7d 100644 --- a/input/checkboxes.ts +++ b/input/checkboxes.ts @@ -59,7 +59,7 @@ const WUI_INPUT_CHECKBOXES_CLASS_LABEL = "wui_input_checkboxes_label"; // export class WuiInputCheckboxes { el: HTMLElement; - private el_label!: HTMLElement; + private elLabel!: HTMLElement; private el_fieldset!: HTMLFieldSetElement; private el_hint!: HTMLElement; private el_hint_toggler!: HTMLElement; @@ -85,41 +85,39 @@ export class WuiInputCheckboxes { } private generateLabel(wrapper: HTMLElement) { - this.el_label = document.createElement("label"); - this.el_label.classList.add(WUI_INPUT_CHECKBOXES_CLASS_LABEL); - this.el_label.innerHTML = `${this.opts.label} `; - wrapper.appendChild(this.el_label); + this.elLabel = document.createElement("label"); + this.elLabel.classList.add(WUI_INPUT_CHECKBOXES_CLASS_LABEL); + this.elLabel.innerHTML = `${this.opts.label} `; + wrapper.appendChild(this.elLabel); } private generateInput(wrapper: HTMLElement) { this.el_fieldset = document.createElement("fieldset"); this.el_fieldset.classList.add(WUI_INPUT_CHECKBOXES_CLASS_INPUT); - for (let key in this.opts.options) { - let option = this.opts.options[key]; - let value = option.value; + Object.entries(this.opts.options).forEach(([key, option]) => { + const value = option.value; + const wrapper = document.createElement("div"); - let wrapper = document.createElement("div"); - - let el_cb = document.createElement("input"); - el_cb.type = "checkbox"; - el_cb.name = this.opts.name; - el_cb.value = option.value; + const elCb = document.createElement("input"); + elCb.type = "checkbox"; + elCb.name = this.opts.name; + elCb.value = option.value; if (option.selected) { - el_cb.checked = true; + elCb.checked = true; this.values.push(value); } - el_cb.onclick = () => { - this.onClickCheckbox(el_cb.value, el_cb.checked); + elCb.onclick = () => { + this.onClickCheckbox(elCb.value, elCb.checked); }; - wrapper.appendChild(el_cb); + wrapper.appendChild(elCb); - let el_label = document.createElement("label"); - el_label.innerHTML = key; - wrapper.appendChild(el_label); + const elLabel = document.createElement("label"); + elLabel.innerHTML = key; + wrapper.appendChild(elLabel); this.el_fieldset.appendChild(wrapper); - } + }); if (this.opts.is_disabled) { this.el_fieldset.disabled = true; diff --git a/input/example.ts b/input/example.ts index 660ea20..2fbd5ad 100644 --- a/input/example.ts +++ b/input/example.ts @@ -7,13 +7,13 @@ import { WuiInputSelect, WuiInputSelectOpts } from "./select.js"; import { WuiInputCheckboxes, WuiInputCheckboxesOpts } from "./checkboxes.js"; function exampleInputString() { - let el_example = document.createElement("div"); + const elExample = document.createElement("div"); - let el_title = document.createElement("h3"); - el_title.innerText = "Input string"; - el_example.appendChild(el_title); + const elTitle = document.createElement("h3"); + elTitle.innerText = "Input string"; + elExample.appendChild(elTitle); - let el_out = document.createElement("span"); + const elOut = document.createElement("span"); let opts: WuiInputStringOpts = { id: "my_input_string", @@ -21,11 +21,11 @@ function exampleInputString() { value: "Hello, input string", hint: "The input ID is 'my_input_string'", onChangeHandler: (v: string) => { - el_out.innerText = v; + elOut.innerText = v; }, }; - let el_input_string = new WuiInputString(opts); - el_example.appendChild(el_input_string.el); + let elInputString = new WuiInputString(opts); + elExample.appendChild(elInputString.el); opts = { label: "Input string disabled", @@ -34,48 +34,48 @@ function exampleInputString() { hint: "The input string is disabled", is_hint_toggled: true, onChangeHandler: (v: string) => { - el_out.innerText = v; + elOut.innerText = v; }, }; - el_input_string = new WuiInputString(opts); - el_example.appendChild(el_input_string.el); + elInputString = new WuiInputString(opts); + elExample.appendChild(elInputString.el); opts = { label: "Input string without hint", value: "Hello, input string without hint", onChangeHandler: (v: string) => { - el_out.innerText = v; + elOut.innerText = v; }, }; - el_input_string = new WuiInputString(opts); - el_example.appendChild(el_input_string.el); + elInputString = new WuiInputString(opts); + elExample.appendChild(elInputString.el); - let el_out_label = document.createElement("div"); - el_out_label.innerText = "Input string changes to "; - el_out_label.appendChild(el_out); - el_example.appendChild(el_out_label); + const elOutLabel = document.createElement("div"); + elOutLabel.innerText = "Input string changes to "; + elOutLabel.appendChild(elOut); + elExample.appendChild(elOutLabel); - document.body.appendChild(el_example); + document.body.appendChild(elExample); } function exampleInputNumber() { - let el_example = document.createElement("div"); + const elExample = document.createElement("div"); - let el_title = document.createElement("h3"); - el_title.innerText = "Input number"; - el_example.appendChild(el_title); + const elTitle = document.createElement("h3"); + elTitle.innerText = "Input number"; + elExample.appendChild(elTitle); - let el_out = document.createElement("span"); + const elOut = document.createElement("span"); let opts: WuiInputNumberOpts = { label: "Input number", value: 1, onChangeHandler: (val: number) => { - el_out.innerText = "" + val; + elOut.innerText = "" + val; }, }; - let input_num = new WuiInputNumber(opts); - el_example.appendChild(input_num.el); + let inputNum = new WuiInputNumber(opts); + elExample.appendChild(inputNum.el); opts = { id: "my_input_number", @@ -83,11 +83,11 @@ function exampleInputNumber() { value: 10, hint: "The ID for this input is 'my_input_number'", onChangeHandler: (val: number) => { - el_out.innerText = "" + val; + elOut.innerText = "" + val; }, }; - input_num = new WuiInputNumber(opts); - el_example.appendChild(input_num.el); + inputNum = new WuiInputNumber(opts); + elExample.appendChild(inputNum.el); opts = { label: "Input number disabled", @@ -96,22 +96,22 @@ function exampleInputNumber() { is_disabled: true, is_hint_toggled: true, onChangeHandler: (val: number) => { - el_out.innerText = "" + val; + elOut.innerText = "" + val; }, }; - input_num = new WuiInputNumber(opts); - el_example.appendChild(input_num.el); + inputNum = new WuiInputNumber(opts); + elExample.appendChild(inputNum.el); opts = { label: "Input number with hint", value: 10000, hint: "This is the <b>hint</b>", onChangeHandler: (val: number) => { - el_out.innerText = "" + val; + elOut.innerText = "" + val; }, }; - input_num = new WuiInputNumber(opts); - el_example.appendChild(input_num.el); + inputNum = new WuiInputNumber(opts); + elExample.appendChild(inputNum.el); opts = { label: "Input number with max and min", @@ -119,31 +119,31 @@ function exampleInputNumber() { max: 12, min: -20, onChangeHandler: (val: number) => { - el_out.innerText = "" + val; + elOut.innerText = "" + val; }, }; - input_num = new WuiInputNumber(opts); - el_example.appendChild(input_num.el); + inputNum = new WuiInputNumber(opts); + elExample.appendChild(inputNum.el); - let el_out_label = document.createElement("div"); - el_out_label.innerText = "Input number changes to "; - el_out_label.appendChild(el_out); - el_example.appendChild(el_out_label); + const elOutLabel = document.createElement("div"); + elOutLabel.innerText = "Input number changes to "; + elOutLabel.appendChild(elOut); + elExample.appendChild(elOutLabel); - document.body.appendChild(el_example); + document.body.appendChild(elExample); } function exampleInputSelect() { - let el_example = document.createElement("div"); - document.body.appendChild(el_example); + const elExample = document.createElement("div"); + document.body.appendChild(elExample); - let el_title = document.createElement("h3"); - el_title.innerText = "Input select"; - el_example.appendChild(el_title); + const elTitle = document.createElement("h3"); + elTitle.innerText = "Input select"; + elExample.appendChild(elTitle); - let el_log = document.createElement("div"); + const elLog = document.createElement("div"); - let opts: WuiInputSelectOpts = { + const opts: WuiInputSelectOpts = { name: "my_fruit_price", label: "Input select", options: { @@ -163,23 +163,23 @@ function exampleInputSelect() { hint: "Select one of the option to see the price.", is_hint_toggled: true, onChangeHandler: (key: string, value: string) => { - el_log.innerText = `The select input changes to '${key}' with price '${value}'`; + elLog.innerText = `The select input changes to '${key}' with price '${value}'`; }, }; - let input = new WuiInputSelect(opts); - el_example.appendChild(input.el); - el_example.appendChild(el_log); + const input = new WuiInputSelect(opts); + elExample.appendChild(input.el); + elExample.appendChild(elLog); } function exampleInputCheckboxes() { - let el_example = document.createElement("div"); - document.body.appendChild(el_example); + const elExample = document.createElement("div"); + document.body.appendChild(elExample); - let el_title = document.createElement("h3"); - el_title.innerText = "Input checkboxes"; - el_example.appendChild(el_title); + const elTitle = document.createElement("h3"); + elTitle.innerText = "Input checkboxes"; + elExample.appendChild(elTitle); - let el_log = document.createElement("div"); + const elLog = document.createElement("div"); let opts: WuiInputCheckboxesOpts = { name: "my_fruits", @@ -200,11 +200,11 @@ function exampleInputCheckboxes() { }, hint: "Select fruits.", onChangeHandler: (values: string[]) => { - el_log.innerText = `You are selecting ${values}`; + elLog.innerText = `You are selecting ${values}`; }, }; let input = new WuiInputCheckboxes(opts); - el_example.appendChild(input.el); + elExample.appendChild(input.el); opts = { name: "my_fruits", @@ -227,13 +227,13 @@ function exampleInputCheckboxes() { is_disabled: true, is_hint_toggled: true, onChangeHandler: (values: string[]) => { - el_log.innerText = `You are selecting ${values}`; + elLog.innerText = `You are selecting ${values}`; }, }; input = new WuiInputCheckboxes(opts); - el_example.appendChild(input.el); + elExample.appendChild(input.el); - el_example.appendChild(el_log); + elExample.appendChild(elLog); } exampleInputString(); diff --git a/input/number.d.ts b/input/number.d.ts index 34b4cf5..885f1cb 100644 --- a/input/number.d.ts +++ b/input/number.d.ts @@ -1,30 +1,30 @@ export interface WuiInputNumberOpts { - label: string | HTMLElement; - value: number; - id?: string; - hint?: string; - max?: number; - min?: number; - class_label?: string; - class_input?: string; - is_disabled?: boolean; - is_hint_toggled?: boolean; - onChangeHandler: (new_value: number) => void; + label: string | HTMLElement; + value: number; + id?: string; + hint?: string; + max?: number; + min?: number; + class_label?: string; + class_input?: string; + is_disabled?: boolean; + is_hint_toggled?: boolean; + onChangeHandler: (new_value: number) => void; } export declare class WuiInputNumber { - opts: WuiInputNumberOpts; - el: HTMLElement; - private el_label; - private el_input; - private el_hint; - private el_hint_toggler; - private value; - constructor(opts: WuiInputNumberOpts); - private generateLabel; - private generateInput; - private generateHintToggler; - private generateHint; - private onClickHintToggler; - private onKeyUp; - Set(v: number): void; + opts: WuiInputNumberOpts; + el: HTMLElement; + private el_label; + private el_input; + private el_hint; + private el_hint_toggler; + private value; + constructor(opts: WuiInputNumberOpts); + private generateLabel; + private generateInput; + private generateHintToggler; + private generateHint; + private onClickHintToggler; + private onKeyUp; + Set(v: number): void; } diff --git a/input/number.ts b/input/number.ts index 0b59dbe..e5c22a1 100644 --- a/input/number.ts +++ b/input/number.ts @@ -67,7 +67,7 @@ export class WuiInputNumber { this.el.classList.add(WUI_INPUT_NUMBER_CLASS); this.el.style.padding = "2px"; - let wrapper = document.createElement("div"); + const wrapper = document.createElement("div"); this.generateLabel(wrapper); this.generateInput(wrapper); if (opts.hint) { @@ -151,7 +151,7 @@ export class WuiInputNumber { } private generateHint() { - let hint = this.opts.hint || ""; + const hint = this.opts.hint || ""; this.el_hint = document.createElement("div"); this.el_hint.classList.add(WUI_INPUT_NUMBER_CLASS_HINT); @@ -176,10 +176,10 @@ export class WuiInputNumber { } private onKeyUp(ev: KeyboardEvent) { - let target = ev.target as HTMLInputElement; + const target = ev.target as HTMLInputElement; ev.preventDefault(); - let newValue = +target.value; + const newValue = +target.value; if (newValue === null) { this.el_input.style.backgroundColor = "lightsalmon"; return false; diff --git a/input/option.d.ts b/input/option.d.ts index ac723d2..8077182 100644 --- a/input/option.d.ts +++ b/input/option.d.ts @@ -1,4 +1,4 @@ export interface WuiInputOption { - value: string; - selected: boolean; + value: string; + selected: boolean; } diff --git a/input/select.d.ts b/input/select.d.ts index e92d82d..3f39184 100644 --- a/input/select.d.ts +++ b/input/select.d.ts @@ -1,37 +1,37 @@ import { WuiInputOption } from "./option.js"; export interface WuiKeyValue { - [key: string]: string; + [key: string]: string; } export interface WuiKeySelectOption { - [key: string]: WuiInputOption; + [key: string]: WuiInputOption; } export interface WuiInputSelectOpts { - label: string | HTMLElement; - name: string; - options: WuiKeySelectOption; - id?: string; - hint?: string; - class_label?: string; - class_input?: string; - is_disabled?: boolean; - is_hint_toggled?: boolean; - onChangeHandler?: (key: string, value: string) => void; + label: string | HTMLElement; + name: string; + options: WuiKeySelectOption; + id?: string; + hint?: string; + class_label?: string; + class_input?: string; + is_disabled?: boolean; + is_hint_toggled?: boolean; + onChangeHandler?: (key: string, value: string) => void; } export declare class WuiInputSelect { - opts: WuiInputSelectOpts; - el: HTMLElement; - private el_label; - private el_input; - private el_hint; - private el_hint_toggler; - private value_key; - private value; - constructor(opts: WuiInputSelectOpts); - private generateLabel; - private generateInput; - private generateHintToggler; - private generateHint; - private onClickHintToggler; - private onClickInput; - Set(v: string): void; + opts: WuiInputSelectOpts; + el: HTMLElement; + private el_label; + private el_input; + private el_hint; + private el_hint_toggler; + private value_key; + private value; + constructor(opts: WuiInputSelectOpts); + private generateLabel; + private generateInput; + private generateHintToggler; + private generateHint; + private onClickHintToggler; + private onClickInput; + Set(v: string): void; } diff --git a/input/select.ts b/input/select.ts index 6bf4810..e874a29 100644 --- a/input/select.ts +++ b/input/select.ts @@ -73,7 +73,7 @@ export class WuiInputSelect { this.el.classList.add(WUI_INPUT_SELECT_CLASS); this.el.style.padding = "2px"; - let wrapper = document.createElement("div"); + const wrapper = document.createElement("div"); this.generateLabel(wrapper); this.generateInput(wrapper); if (opts.hint) { @@ -109,21 +109,19 @@ export class WuiInputSelect { this.el_input.classList.add(this.opts.class_input); } - for (let key in this.opts.options) { - let option = this.opts.options[key]; - - let el_option = document.createElement("option"); - el_option.value = option.value; - el_option.innerHTML = key; + Object.entries(this.opts.options).forEach(([key, option]) => { + const elOption = document.createElement("option"); + elOption.value = option.value; + elOption.innerHTML = key; if (option.selected) { - el_option.selected = true; + elOption.selected = true; } - this.el_input.appendChild(el_option); + this.el_input.appendChild(elOption); this.value_key[option.value] = key; - } + }); if (this.opts.is_disabled) { this.el_input.disabled = true; @@ -182,12 +180,15 @@ export class WuiInputSelect { return false; } - let value = this.el_input.value; - let key = this.value_key[value]; + const value = this.el_input.value; if (this.value !== value) { - this.opts.onChangeHandler(key, value); - this.value = value; + const key = this.value_key[value]; + if (key) { + this.opts.onChangeHandler(key, value); + this.value = value; + } } + return true; } // Set the input value. diff --git a/input/string.d.ts b/input/string.d.ts index 747c4c6..e1b73ff 100644 --- a/input/string.d.ts +++ b/input/string.d.ts @@ -1,27 +1,27 @@ export interface WuiInputStringOpts { - label: string | HTMLElement; - value: string; - id?: string; - hint?: string; - class_label?: string; - class_input?: string; - is_disabled?: boolean; - is_hint_toggled?: boolean; - onChangeHandler?: (new_value: string) => void; + label: string | HTMLElement; + value: string; + id?: string; + hint?: string; + class_label?: string; + class_input?: string; + is_disabled?: boolean; + is_hint_toggled?: boolean; + onChangeHandler?: (new_value: string) => void; } export declare class WuiInputString { - opts: WuiInputStringOpts; - el: HTMLElement; - private el_label; - private el_input; - private el_hint; - private el_hint_toggler; - private value; - constructor(opts: WuiInputStringOpts); - private generateLabel; - private generateInput; - private generateHintToggler; - private generateHint; - private onClickHintToggler; - Set(v: string): void; + opts: WuiInputStringOpts; + el: HTMLElement; + private el_label; + private el_input; + private el_hint; + private el_hint_toggler; + private value; + constructor(opts: WuiInputStringOpts); + private generateLabel; + private generateInput; + private generateHintToggler; + private generateHint; + private onClickHintToggler; + Set(v: string): void; } diff --git a/input/string.ts b/input/string.ts index d428c32..f37a68f 100644 --- a/input/string.ts +++ b/input/string.ts @@ -62,7 +62,7 @@ export class WuiInputString { this.el.classList.add(WUI_INPUT_STRING_CLASS); this.el.style.padding = "2px"; - let wrapper = document.createElement("div"); + const wrapper = document.createElement("div"); this.generateLabel(wrapper); this.generateInput(wrapper); if (opts.hint) { @@ -104,7 +104,7 @@ export class WuiInputString { } if (this.opts.onChangeHandler) { - this.el_input.onkeyup = (ev: Event) => { + this.el_input.onkeyup = () => { if (this.opts.onChangeHandler) { if (this.value !== this.el_input.value) { this.opts.onChangeHandler(this.el_input.value); diff --git a/notif/example.ts b/notif/example.ts index a15f986..b2ff5d7 100644 --- a/notif/example.ts +++ b/notif/example.ts @@ -18,42 +18,42 @@ function main() { inputMsg.value = `Hello world, this is a notification with HTML format using <b>bold</b> and <u>underline</u> words.`; document.body.appendChild(inputMsg); - let el_wrapper = document.createElement("div"); - el_wrapper.style.marginTop = "10px"; - document.body.appendChild(el_wrapper); + const elWrapper = document.createElement("div"); + elWrapper.style.marginTop = "10px"; + document.body.appendChild(elWrapper); - let el_button_info = document.createElement("button"); - el_button_info.innerText = "Info"; - el_button_info.style.marginRight = "10px"; - el_button_info.onclick = notifInfo; - el_wrapper.appendChild(el_button_info); + const elButtonInfo = document.createElement("button"); + elButtonInfo.innerText = "Info"; + elButtonInfo.style.marginRight = "10px"; + elButtonInfo.onclick = notifInfo; + elWrapper.appendChild(elButtonInfo); - let el_button_error = document.createElement("button"); - el_button_error.innerText = "Error"; - el_button_error.onclick = notifError; - el_wrapper.appendChild(el_button_error); + const elButtonError = document.createElement("button"); + elButtonError.innerText = "Error"; + elButtonError.onclick = notifError; + elWrapper.appendChild(elButtonError); document.body.appendChild(document.createElement("p")); - let previewError = document.createElement("div"); + const previewError = document.createElement("div"); previewError.classList.add(`${WUI_NOTIF_CLASS_ERROR}`); previewError.innerText = `Preview of error style`; document.body.appendChild(previewError); - let previewInfo = document.createElement("div"); + const previewInfo = document.createElement("div"); previewInfo.classList.add(`${WUI_NOTIF_CLASS_INFO}`); previewInfo.innerText = `Preview of info style`; document.body.appendChild(previewInfo); } function notifInfo() { - wuiNotif.Info(inputMsg.value); + wuiNotif.info(inputMsg.value); } function notifError() { - wuiNotif.Error(inputMsg.value); + wuiNotif.error(inputMsg.value); } -//---- +// ---- main(); diff --git a/notif/notif.d.ts b/notif/notif.d.ts index ae2c331..0f90919 100644 --- a/notif/notif.d.ts +++ b/notif/notif.d.ts @@ -2,10 +2,10 @@ export declare const WUI_NOTIF_ID = "wui_notif"; export declare const WUI_NOTIF_CLASS_INFO = "wui_notif_info"; export declare const WUI_NOTIF_CLASS_ERROR = "wui_notif_error"; export declare class WuiNotif { - private el; - private timeout; - constructor(); - Info(msg: string): void; - Error(msg: string): void; - private initStyle; + private el; + private timeout; + constructor(); + Info(msg: string): void; + Error(msg: string): void; + private initStyle; } diff --git a/notif/notif.ts b/notif/notif.ts index 8bc5d84..23933ab 100644 --- a/notif/notif.ts +++ b/notif/notif.ts @@ -6,7 +6,7 @@ export const WUI_NOTIF_CLASS_INFO = "wui_notif_info"; export const WUI_NOTIF_CLASS_ERROR = "wui_notif_error"; // WuiNotif implement the HTML interface to display pop-up notification. -// The notification can be triggered by calling method Info() or Error(). +// The notification can be triggered by calling method info() or error(). // Each pop-up has 5 seconds duration, after that they will be removed // automatically. export class WuiNotif { @@ -22,9 +22,9 @@ export class WuiNotif { this.initStyle(); } - // Info show the msg as information. - Info(msg: string) { - let item = document.createElement("div"); + // info show the msg as information. + info(msg: string) { + const item = document.createElement("div"); item.innerHTML = msg; item.classList.add(WUI_NOTIF_CLASS_INFO); this.el.appendChild(item); @@ -34,9 +34,9 @@ export class WuiNotif { }, this.timeout); } - // Info show the msg as an error. - Error(msg: string) { - let item = document.createElement("div"); + // error show the msg as an error. + error(msg: string) { + const item = document.createElement("div"); item.innerHTML = msg; item.classList.add(WUI_NOTIF_CLASS_ERROR); this.el.appendChild(item); @@ -47,7 +47,7 @@ export class WuiNotif { } private initStyle() { - let style = document.createElement("style"); + const style = document.createElement("style"); style.type = "text/css"; style.innerText = ` #${WUI_NOTIF_ID} { diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a6b1453 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2116 @@ +{ + "name": "wui", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^6.8.0", + "@typescript-eslint/parser": "^6.8.0", + "eslint": "^8.52.0", + "eslint-config-google": "^0.14.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.1", + "prettier": "^3.0.3", + "typescript": "^5.2.2" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", + "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", + "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/type-utils": "6.8.0", + "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", + "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", + "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", + "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/utils": "6.8.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", + "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", + "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", + "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", + "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.8.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "dependencies": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "dependencies": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", + "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.52.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", + "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/run-applescript/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/run-applescript/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/run-applescript/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-applescript/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "dependencies": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b14910a --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^6.8.0", + "@typescript-eslint/parser": "^6.8.0", + "eslint": "^8.52.0", + "eslint-config-google": "^0.14.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.1", + "prettier": "^3.0.3", + "typescript": "^5.2.2" + } +} diff --git a/response.d.ts b/response.d.ts index 532028d..84bf392 100644 --- a/response.d.ts +++ b/response.d.ts @@ -1,5 +1,5 @@ export interface WuiResponseInterface { - code: number; - message: string; - data?: any; + code: number; + message: string; + data?: any; // eslint-disable-line @typescript-eslint/no-explicit-any } diff --git a/response.ts b/response.ts index f74161a..9991976 100644 --- a/response.ts +++ b/response.ts @@ -12,5 +12,5 @@ export interface WuiResponseInterface { code: number; message: string; - data?: any; + data?: any; // eslint-disable-line @typescript-eslint/no-explicit-any } diff --git a/tsconfig.json b/tsconfig.json index bcb70d1..707ff90 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,23 @@ { "compilerOptions": { - "declaration": true, + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + "target": "es2018", + "module": "es2020", + "isolatedModules": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "inlineSourceMap": true, - "lib": ["es2015", "dom", "es2015.promise"], - "module": "es2015", "strict": true, - "target": "es2015" + "noImplicitAny": true, + "noImplicitThis": true, + "useUnknownInCatchVariables": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "exactOptionalPropertyTypes": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "skipLibCheck": true, } } diff --git a/vfs/example.ts b/vfs/example.ts index f2bc91d..6c963d0 100644 --- a/vfs/example.ts +++ b/vfs/example.ts @@ -1,14 +1,14 @@ // SPDX-FileCopyrightText: 2021 M. Shulhan <ms@kilabit.info> // SPDX-License-Identifier: GPL-3.0-or-later -import { WuiVfs, WuiVfsNodeInterface } from "./vfs.js"; +import { WuiVfs, WuiVfsNodeInterface, WuiVfsOptions } from "./vfs.js"; import { WuiResponseInterface } from "../response.js"; interface PathNodeInterface { [key: string]: WuiVfsNodeInterface; } -let dummyfs: PathNodeInterface = { +const dummyfs: PathNodeInterface = { "/": { name: "/", path: "/", @@ -100,27 +100,27 @@ let dummyfs: PathNodeInterface = { }; async function main() { - let opts = { + const opts: WuiVfsOptions = { id: "vfs", - Open: Open, - OpenNode: OpenNode, + open: open, + openNode: openNode, }; - let wui_vfs = new WuiVfs(opts); - wui_vfs.OpenDir("/"); + const wuiVFS = new WuiVfs(opts); + wuiVFS.openDir("/"); } -async function Open( +async function open( path: string, - is_dir: boolean, + isDir: boolean, ): Promise<WuiResponseInterface> { - console.log("Open:", path, is_dir); - let res: WuiResponseInterface = { + console.log("Open:", path, isDir); + const res: WuiResponseInterface = { code: 200, message: "", }; - if (is_dir) { + if (isDir) { res.data = dummyfs[path]; return res; } @@ -158,10 +158,10 @@ async function Open( return res; } -async function OpenNode( +async function openNode( node: WuiVfsNodeInterface, ): Promise<WuiResponseInterface> { - return await Open(node.path, node.is_dir); + return await open(node.path, node.is_dir); } main(); diff --git a/vfs/vfs.d.ts b/vfs/vfs.d.ts index 5e89b33..a7d365d 100644 --- a/vfs/vfs.d.ts +++ b/vfs/vfs.d.ts @@ -1,27 +1,27 @@ import { WuiResponseInterface } from "../response"; export interface WuiVfsNodeInterface { - name: string; - path: string; - is_dir: boolean; - content_type?: string; - mod_time?: number; - size?: number; - mode?: string; - childs?: WuiVfsNodeInterface[]; - content: string; + name: string; + path: string; + is_dir: boolean; + content_type?: string; + mod_time?: number; + size?: number; + mode?: string; + childs?: WuiVfsNodeInterface[]; + content: string; } export interface WuiVfsOptions { - id: string; - Open(path: string, is_dir: boolean): Promise<WuiResponseInterface>; - OpenNode(node: WuiVfsNodeInterface): Promise<WuiResponseInterface>; + id: string; + Open(path: string, is_dir: boolean): Promise<WuiResponseInterface>; + OpenNode(node: WuiVfsNodeInterface): Promise<WuiResponseInterface>; } export declare class WuiVfs { - opts: WuiVfsOptions; - private el; - private com_path; - private com_list; - constructor(opts: WuiVfsOptions); - OpenNode(node: WuiVfsNodeInterface): void; - OpenDir(path: string): Promise<void>; - Set(node: WuiVfsNodeInterface): void; + opts: WuiVfsOptions; + private el; + private com_path; + private com_list; + constructor(opts: WuiVfsOptions); + OpenNode(node: WuiVfsNodeInterface): void; + OpenDir(path: string): Promise<void>; + Set(node: WuiVfsNodeInterface): void; } @@ -24,13 +24,13 @@ type NodeClickHandler = (node: WuiVfsNodeInterface) => void; export interface WuiVfsOptions { id: string; - // Open define an handler that will be called when a directory is clicked + // open define an handler that will be called when a directory is clicked // from the WuiVfsPath. - Open(path: string, is_dir: boolean): Promise<WuiResponseInterface>; + open(path: string, is_dir: boolean): Promise<WuiResponseInterface>; - // OpenNode define an handler that will be called when a file is clicked + // openNode define an handler that will be called when a file is clicked // from the WuiVfsList. - OpenNode(node: WuiVfsNodeInterface): Promise<WuiResponseInterface>; + openNode(node: WuiVfsNodeInterface): Promise<WuiResponseInterface>; } export class WuiVfs { @@ -41,7 +41,7 @@ export class WuiVfs { constructor(public opts: WuiVfsOptions) { this.opts = opts; - let el = document.getElementById(opts.id); + const el = document.getElementById(opts.id); if (!el) { console.error("WuiVfs: element id", opts.id, "not found"); return; @@ -49,40 +49,40 @@ export class WuiVfs { this.el = el; this.com_path = new WuiVfsPath((path: string) => { - this.OpenDir(path); + this.openDir(path); }); this.el.appendChild(this.com_path.el); this.com_list = new WuiVfsList((node: WuiVfsNodeInterface) => { - this.OpenNode(node); + this.openNode(node); }); this.el.appendChild(this.com_list.el); } - // OpenNode is a handler that will be called when a node is clicked + // openNode is a handler that will be called when a node is clicked // inside the WuiVfsList. - OpenNode(node: WuiVfsNodeInterface): void { + openNode(node: WuiVfsNodeInterface): void { if (node.is_dir) { - this.OpenDir(node.path); + this.openDir(node.path); } else { - this.opts.OpenNode(node); + this.opts.openNode(node); } } - // OpenDir is a handler that will be called when a path is clicked + // openDir is a handler that will be called when a path is clicked // inside the WuiVfsPath. - async OpenDir(path: string): Promise<void> { - let res = await this.opts.Open(path, true); + async openDir(path: string): Promise<void> { + const res = await this.opts.open(path, true); if (res.code != 200) { return; } - this.Set(res.data as WuiVfsNodeInterface); + this.set(res.data as WuiVfsNodeInterface); } - Set(node: WuiVfsNodeInterface) { + set(node: WuiVfsNodeInterface) { if (node.is_dir) { - this.com_path.Open(node); - this.com_list.Open(node); + this.com_path.open(node); + this.com_list.open(node); } } } @@ -99,14 +99,14 @@ class WuiVfsList { this.el.style.borderColor = "silver"; } - Open(node: WuiVfsNodeInterface) { + open(node: WuiVfsNodeInterface) { this.node = node; this.el.innerHTML = ""; if (!this.node.childs) { return; } - for (let c of this.node.childs) { - let el = document.createElement("div"); + for (const c of this.node.childs) { + const el = document.createElement("div"); el.style.padding = "1em"; el.style.cursor = "pointer"; el.innerHTML = c.name; @@ -115,17 +115,17 @@ class WuiVfsList { el.style.backgroundColor = "cornsilk"; } - el.onclick = (ev: MouseEvent) => { + el.onclick = () => { this.onClick(c); }; - el.onmouseout = (event) => { + el.onmouseout = () => { if (c.is_dir) { el.style.backgroundColor = "cornsilk"; } else { el.style.backgroundColor = "white"; } }; - el.onmouseover = (event) => { + el.onmouseover = () => { el.style.backgroundColor = "aliceblue"; }; @@ -136,7 +136,6 @@ class WuiVfsList { class WuiVfsPath { el: HTMLElement; - private crumbs: string[]; private onClick: PathClickHandler; constructor(onClick: PathClickHandler) { @@ -146,14 +145,12 @@ class WuiVfsPath { this.el.style.borderWidth = "1px"; this.el.style.borderStyle = "solid"; this.el.style.borderColor = "silver"; - this.crumbs = []; this.onClick = onClick; } - Open(node: WuiVfsNodeInterface) { + open(node: WuiVfsNodeInterface) { this.el.innerHTML = ""; - this.crumbs = []; - let paths = []; + let paths: string[] = []; if (node.path == "/") { paths.push(node.path); @@ -161,35 +158,35 @@ class WuiVfsPath { paths = node.path.split("/"); } - for (let x = 0; x < paths.length; x++) { - let full_path = ""; + paths.forEach((path, x) => { + let fullPath = ""; let p = ""; if (x == 0) { p = "/"; - full_path = "/"; + fullPath = "/"; } else { - p = paths[x]; - full_path = paths.slice(0, x + 1).join("/"); + p = path; + fullPath = paths.slice(0, x + 1).join("/"); } - let crumb = document.createElement("span"); + const crumb = document.createElement("span"); crumb.style.display = "inline-block"; crumb.style.padding = "1em"; crumb.style.cursor = "pointer"; crumb.innerHTML = p; - crumb.onclick = (event) => { - this.onClick(full_path); + crumb.onclick = () => { + this.onClick(fullPath); }; - crumb.onmouseout = (event) => { + crumb.onmouseout = () => { crumb.style.backgroundColor = "white"; }; - crumb.onmouseover = (event) => { + crumb.onmouseover = () => { crumb.style.backgroundColor = "aliceblue"; }; this.el.appendChild(crumb); - } + }); } } diff --git a/websocket_client.d.ts b/websocket_client.d.ts index 00eb4c1..189f20d 100644 --- a/websocket_client.d.ts +++ b/websocket_client.d.ts @@ -1,44 +1,44 @@ import { WuiResponseInterface } from "./response.js"; interface RequestQueue { - req: WuiWebSocketRequest; - cbSuccess: (res: WuiWebSocketResponse) => void; - cbFail: (err: string) => void; + req: WuiWebSocketRequest; + cbSuccess: (res: WuiWebSocketResponse) => void; + cbFail: (err: string) => void; } export interface WuiWebSocketOptions { - address: string; - auto_reconnect: boolean; - auto_reconnect_interval: number; - onBroadcast: (res: WuiWebSocketResponse) => void; - onConnected: () => void; - onDisconnected: () => void; - onError: () => void; + address: string; + auto_reconnect: boolean; + auto_reconnect_interval: number; + onBroadcast: (res: WuiWebSocketResponse) => void; + onConnected: () => void; + onDisconnected: () => void; + onError: () => void; } export interface WuiWebSocketRequest { - id: number; - method: string; - target: string; - body?: string; + id: number; + method: string; + target: string; + body?: string; } export interface WuiWebSocketResponse { - id: number; - code: number; - message: string; - body: string; + id: number; + code: number; + message: string; + body: string; } export declare class WuiWebSocketClient { - opts: WuiWebSocketOptions; - address: string; - conn: WebSocket; - requestQueue: RequestQueue[]; - reconnect_id: number; - isOpen: boolean; - error: string; - constructor(opts: WuiWebSocketOptions); - Send(req: WuiWebSocketRequest): Promise<WuiResponseInterface>; - connect(): void; - onClose(ev: CloseEvent): void; - onError(ev: Event): void; - onMessage(ev: MessageEvent): void; - onOpen(ev: Event): void; + opts: WuiWebSocketOptions; + address: string; + conn: WebSocket; + requestQueue: RequestQueue[]; + reconnect_id: number; + isOpen: boolean; + error: string; + constructor(opts: WuiWebSocketOptions); + Send(req: WuiWebSocketRequest): Promise<WuiResponseInterface>; + connect(): void; + onClose(ev: CloseEvent): void; + onError(ev: Event): void; + onMessage(ev: MessageEvent): void; + onOpen(ev: Event): void; } export {}; diff --git a/websocket_client.ts b/websocket_client.ts index 7ffdbc0..7e02982 100644 --- a/websocket_client.ts +++ b/websocket_client.ts @@ -58,12 +58,12 @@ export class WuiWebSocketClient { // request-response. // async Send(req: WuiWebSocketRequest): Promise<WuiResponseInterface> { - return new Promise((resolve, reject) => { - let wuiRes: WuiResponseInterface = { + return new Promise((resolve) => { + const wuiRes: WuiResponseInterface = { code: 0, message: "", }; - let reqQueue: RequestQueue = { + const reqQueue: RequestQueue = { req: req, cbSuccess: (res: WuiWebSocketResponse) => { wuiRes.code = res.code; @@ -87,26 +87,26 @@ export class WuiWebSocketClient { connect() { this.conn = new WebSocket(this.address); - this.conn.onclose = (ev: CloseEvent) => { - this.onClose(ev); + this.conn.onclose = () => { + this.onClose(); }; - this.conn.onerror = (ev: Event) => { - this.onError(ev); + this.conn.onerror = () => { + this.onError(); }; this.conn.onmessage = (ev: MessageEvent) => { this.onMessage(ev); }; - this.conn.onopen = (ev: Event) => { - this.onOpen(ev); + this.conn.onopen = () => { + this.onOpen(); }; } // onClose handle connection closed by cleaning up the request // queue. - onClose(ev: CloseEvent) { - for (let x = 0; x < this.requestQueue.length; x++) { - this.requestQueue[x].cbFail("connection closed"); - } + onClose() { + this.requestQueue.forEach((reqq) => { + reqq.cbFail("connection closed"); + }); this.isOpen = false; this.error = "connection is closed by server"; @@ -121,30 +121,29 @@ export class WuiWebSocketClient { } } - onError(ev: Event) { + onError() { if (this.opts.onError) { this.opts.onError(); } } onMessage(ev: MessageEvent) { - let res: WuiWebSocketResponse = JSON.parse(ev.data); + const res: WuiWebSocketResponse = JSON.parse(ev.data); - for (let x = 0; x < this.requestQueue.length; x++) { - let reqq = this.requestQueue[x]; + this.requestQueue.forEach((reqq, x) => { if (reqq.req.id === res.id) { reqq.cbSuccess(res); this.requestQueue.splice(x, 1); return; } - } + }); if (this.opts.onBroadcast && res.id == 0) { this.opts.onBroadcast(res); } } - onOpen(ev: Event) { + onOpen() { this.isOpen = true; this.error = ""; |
