Build log
nerves_system_rpi4
ghostty 0.5.0 · fail · run ghostty-0.5.0-1789365473951
226 of 226 lines
1Resolving Hex dependencies...2Resolution completed in 0.37s3Unchanged:4 castore 1.0.215 circular_buffer 1.1.06 elixir_make 0.10.07 ghostty 0.5.08 interactive_cmd 0.1.49 jason 1.4.510 nerves 1.15.011 nerves_discovery 0.1.512 nerves_logging 0.2.413 nerves_runtime 0.13.1314 nerves_system_bbb 2.30.215 nerves_system_br 1.34.416 nerves_system_mangopi_mq_pro 0.17.217 nerves_system_qemu_aarch64 0.4.218 nerves_system_rpi 2.1.219 nerves_system_rpi0 2.1.220 nerves_system_rpi0_2 2.1.221 nerves_system_rpi2 2.1.222 nerves_system_rpi3 2.1.223 nerves_system_rpi4 2.1.224 nerves_system_rpi5 2.1.225 nerves_system_x86_64 1.34.226 nerves_toolchain_aarch64_nerves_linux_gnu 15.3.127 nerves_toolchain_armv6_nerves_linux_gnueabihf 15.3.128 nerves_toolchain_armv7_nerves_linux_gnueabihf 15.3.129 nerves_toolchain_riscv64_nerves_linux_gnu 15.3.130 nerves_toolchain_x86_64_nerves_linux_musl 15.3.131 nerves_uevent 0.1.732 oxc 0.17.833 property_table 0.3.434 ring_logger 0.11.735 rustler_precompiled 0.9.036 shoehorn 0.9.337 tablet 0.3.338 toolshed 0.5.039 uboot_env 1.0.240 zigler_precompiled 0.1.641* Getting ghostty (Hex package)42* Getting nerves (Hex package)43* Getting shoehorn (Hex package)44* Getting ring_logger (Hex package)45* Getting toolshed (Hex package)46* Getting nerves_runtime (Hex package)47* Getting nerves_system_bbb (Hex package)48* Getting nerves_system_mangopi_mq_pro (Hex package)49* Getting nerves_system_qemu_aarch64 (Hex package)50* Getting nerves_system_rpi (Hex package)51* Getting nerves_system_rpi0 (Hex package)52* Getting nerves_system_rpi0_2 (Hex package)53* Getting nerves_system_rpi2 (Hex package)54* Getting nerves_system_rpi3 (Hex package)55* Getting nerves_system_rpi4 (Hex package)56* Getting nerves_system_rpi5 (Hex package)57* Getting nerves_system_x86_64 (Hex package)58* Getting nerves_system_br (Hex package)59* Getting nerves_toolchain_x86_64_nerves_linux_musl (Hex package)60* Getting nerves_toolchain_aarch64_nerves_linux_gnu (Hex package)61* Getting nerves_toolchain_armv7_nerves_linux_gnueabihf (Hex package)62* Getting nerves_toolchain_armv6_nerves_linux_gnueabihf (Hex package)63* Getting nerves_toolchain_riscv64_nerves_linux_gnu (Hex package)64* Getting nerves_logging (Hex package)65* Getting nerves_uevent (Hex package)66* Getting uboot_env (Hex package)67* Getting elixir_make (Hex package)68* Getting property_table (Hex package)69* Getting circular_buffer (Hex package)70* Getting interactive_cmd (Hex package)71* Getting jason (Hex package)72* Getting nerves_discovery (Hex package)73* Getting tablet (Hex package)74* Getting oxc (Hex package)75* Getting zigler_precompiled (Hex package)76* Getting castore (Hex package)77* Getting rustler_precompiled (Hex package)78==> jason79Compiling 10 files (.ex)80Generated jason app81==> tablet82Compiling 2 files (.ex)83Generated tablet app84==> elixir_make85Compiling 8 files (.ex)86Generated elixir_make app87==> nerves_discovery88Compiling 5 files (.ex)89Generated nerves_discovery app90==> interactive_cmd91Compiling 1 file (.ex)92Generated interactive_cmd app93==> nerves94HOST_CC port.o95HOST_LD port96Compiling 55 files (.ex)97Generated nerves app98==> nerves_compatibility_test99100Nerves environment101 MIX_TARGET: rpi4102 MIX_ENV: prod103104Checking for prebuilt Nerves artifacts...105 Found nerves_system_rpi4 in cache106 /home/nerves/.nerves/artifacts/nerves_system_rpi4-portable-2.1.2107 Found nerves_toolchain_aarch64_nerves_linux_gnu in cache108 /home/nerves/.nerves/artifacts/nerves_toolchain_aarch64_nerves_linux_gnu-linux_x86_64-15.3.1109==> jason110Compiling 10 files (.ex)111Compiling lib/decoder.ex (it's taking more than 10s)112Generated jason app113==> tablet114Compiling 2 files (.ex)115Generated tablet app116==> elixir_make117Compiling 8 files (.ex)118Generated elixir_make app119==> nerves_discovery120Compiling 5 files (.ex)121Generated nerves_discovery app122==> interactive_cmd123Compiling 1 file (.ex)124Generated interactive_cmd app125==> nerves126HOST_CC port.o127HOST_LD port128Compiling 55 files (.ex)129Generated nerves app130==> nerves_system_br131Generated nerves_system_br app132==> nerves_toolchain_aarch64_nerves_linux_gnu133Compiling 1 file (.ex)134Generated nerves_toolchain_aarch64_nerves_linux_gnu app135==> nerves_system_rpi4136Generated nerves_system_rpi4 app137==> nerves_compatibility_test138139Nerves environment140 MIX_TARGET: rpi4141 MIX_ENV: prod142143==> circular_buffer144Compiling 1 file (.ex)145Generated circular_buffer app146==> nerves_logging147 CC kmsg_tailer.o148 LD kmsg_tailer149Compiling 5 files (.ex)150Generated nerves_logging app151==> castore152Compiling 1 file (.ex)153Generated castore app154==> ring_logger155Compiling 7 files (.ex)156Generated ring_logger app157==> shoehorn158Compiling 8 files (.ex)159Generated shoehorn app160==> rustler_precompiled161Compiling 4 files (.ex)162Generated rustler_precompiled app163==> oxc164Compiling 17 files (.ex)16516606:02:04.830 [debug] Downloading NIF from https://github.com/elixir-volt/oxc_ex/releases/download/v0.17.8/liboxc_lint_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz16716806:02:04.843 [debug] Downloading NIF from https://github.com/elixir-volt/oxc_ex/releases/download/v0.17.8/liboxc_fmt_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz16917006:02:06.336 [debug] NIF cached at /home/nerves/.cache/rustler_precompiled/precompiled_nifs/liboxc_fmt_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz and extracted to /work/proj/_build/rpi4/lib/oxc/priv/native/liboxc_fmt_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz17117206:02:06.568 [debug] Downloading NIF from https://github.com/elixir-volt/oxc_ex/releases/download/v0.17.8/liboxc_ex_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz17317406:02:06.974 [debug] NIF cached at /home/nerves/.cache/rustler_precompiled/precompiled_nifs/liboxc_lint_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz and extracted to /work/proj/_build/rpi4/lib/oxc/priv/native/liboxc_lint_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz17517606:02:08.555 [debug] NIF cached at /home/nerves/.cache/rustler_precompiled/precompiled_nifs/liboxc_ex_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz and extracted to /work/proj/_build/rpi4/lib/oxc/priv/native/liboxc_ex_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so.tar.gz177Generated oxc app178==> uboot_env179Compiling 5 files (.ex)180Generated uboot_env app181==> property_table182Compiling 8 files (.ex)183Generated property_table app184==> nerves_uevent185 CC uevent.o186 LD uevent187Compiling 5 files (.ex)188Generated nerves_uevent app189==> nerves_runtime190Compiling 14 files (.ex)191Generated nerves_runtime app192==> toolshed193Compiling 5 files (.ex)194Generated toolshed app195==> zigler_precompiled196Compiling 5 files (.ex)197Generated zigler_precompiled app198==> ghostty199Compiling 19 files (.ex)20020106:02:21.691 [debug] Downloading NIF from https://github.com/dannote/ghostty_ex/releases/download/v0.5.0/Elixir.Ghostty.PTY.Nif-v0.5.0-aarch64-linux-gnu.so.tar.gz20220306:02:22.422 [debug] Downloading NIF from https://github.com/dannote/ghostty_ex/releases/download/v0.5.0/Elixir.Ghostty.Terminal.Nif-v0.5.0-aarch64-linux-gnu.so.tar.gz204Generated ghostty app205could not compile dependency :ghostty, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile ghostty --force", update it with "mix deps.update ghostty" or clean it with "mix deps.clean ghostty"20620706:02:25.822 [warning] The on_load function for module Elixir.OXC.Native returned:208{:error,209 {:load_failed,210 ~c"Failed to load NIF library: '/work/proj/_build/rpi4/lib/oxc/priv/native/liboxc_ex_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so: cannot open shared object file: No such file or directory'"}}21121221306:02:25.912 [warning] The on_load function for module Elixir.OXC.Native returned:214{:error,215 {:load_failed,216 ~c"Failed to load NIF library: '/work/proj/_build/rpi4/lib/oxc/priv/native/liboxc_ex_nif-v0.17.8-nif-2.15-aarch64-unknown-linux-gnu.so: cannot open shared object file: No such file or directory'"}}217218** (UndefinedFunctionError) function OXC.Native.bundle/2 is undefined (module OXC.Native is not available)219 (oxc 0.17.8) OXC.Native.bundle([{"cursor.ts", "import { applyCellTextStyles } from './render'\nimport { rgb } from './util'\n\nimport type { Cell, CellMetrics, CursorState } from './types'\n\nexport function cursorVisible(cursor: CursorState | null, blinkVisible: boolean): boolean {\n return Boolean(cursor && cursor.visible && cursor.x !== null && cursor.y !== null && blinkVisible)\n}\n\nexport function cursorDisplayStyle(style: string, focused: boolean): string {\n if (!focused && style === 'block') {\n return 'block_hollow'\n }\n return style\n}\n\nexport function cursorCell(cursor: CursorState, rowsData: Cell[][]): Cell | null {\n if (cursor.y === null || cursor.x === null) return null\n\n const row = rowsData[cursor.y]\n if (!row) return null\n\n if (cursor.wide_tail && cursor.x > 0) {\n return row[cursor.x - 1] ?? null\n }\n\n return row[cursor.x] ?? null\n}\n\nexport function cursorChar(cell: Cell | null): string {\n return cell?.[0] || ' '\n}\n\nexport function cursorColor(cursor: CursorState, pre: HTMLPreElement): string {\n if (cursor.color) {\n return rgb(cursor.color)\n }\n return window.getComputedStyle(pre).color || '#cdd6f4'\n}\n\nexport function cursorTextColor(cell: Cell | null, pre: HTMLPreElement): string {\n if (cell?.[2]) {\n return rgb(cell[2])\n }\n return window.getComputedStyle(pre).backgroundColor || '#1e1e2e'\n}\n\nexport function renderCursor(\n cursorEl: HTMLDivElement,\n cursorTextEl: HTMLSpanElement,\n cursor: CursorState | null,\n rowsData: Cell[][],\n focused: boolean,\n blinkVisible: boolean,\n metrics: CellMetrics,\n pre: HTMLPreElement,\n input: HTMLTextAreaElement\n): void {\n if (!cursorVisible(cursor, blinkVisible)) {\n cursorEl.style.display = 'none'\n syncInputPosition(input, null)\n return\n }\n\n const c = cursor as CursorState\n const cx = c.x as number\n const cy = c.y as number\n let leftCol = cx\n let widthCols = 1\n\n if (c.wide_tail && cx > 0) {\n leftCol -= 1\n widthCols = 2\n }\n\n const left = metrics.paddingLeft + leftCol * metrics.width\n const top = metrics.paddingTop + cy * metrics.height\n const width = metrics.width * widthCols\n const height = metrics.height\n const style = cursorDisplayStyle(c.style, focused)\n const color = cursorColor(c, pre)\n\n syncInputPosition(input, { left, top, height })\n\n cursorEl.style.display = 'block'\n cursorEl.style.left = `${left}px`\n cursorEl.style.top = `${top}px`\n cursorEl.style.width = `${width}px`\n cursorEl.style.height = `${height}px`\n cursorEl.style.opacity = focused ? '1' : '0.85'\n\n cursorTextEl.textContent = ''\n cursorTextEl.style.color = ''\n cursorTextEl.style.backgroundColor = 'transparent'\n cursorTextEl.style.fontWeight = ''\n cursorTextEl.style.fontStyle = ''\n cursorTextEl.style.opacity = '1'\n cursorTextEl.style.textDecoration = 'none'\n\n cursorEl.style.backgroundColor = 'transparent'\n cursorEl.style.border = 'none'\n cursorEl.style.borderBottom = 'none'\n cursorEl.style.borderLeft = 'none'\n\n if (style === 'block') {\n const cell = cursorCell(c, rowsData)\n cursorEl.style.backgroundColor = color\n cursorTextEl.textContent = cursorChar(cell)\n cursorTextEl.style.color = cursorTextColor(cell, pre)\n applyCellTextStyles(cursorTextEl, cell)\n return\n }\n\n if (style === 'underline') {\n cursorEl.style.borderBottom = `2px solid ${color}`\n return\n }\n\n if (style === 'bar') {\n const barWidth = Math.max(2, Math.round(metrics.width * 0.15))\n cursorEl.style.width = `${barWidth}px`\n cursorEl.style.backgroundColor = color\n return\n }\n\n cursorEl.style.border = `1px solid ${color}`\n}\n\nfunction syncInputPosition(\n input: HTMLTextAreaElement,\n position: { left: number; top: number; height: number } | null\n): void {\n if (!position) {\n input.style.left = '0'\n input.style.top = '0'\n return\n }\n\n input.style.left = `${position.left}px`\n input.style.top = `${position.top}px`\n input.style.height = `${position.height}px`\n}\n"}, {"dom.ts", "import { rgb } from './util'\n\nimport type { Color } from './types'\n\nexport function createScreen(): HTMLDivElement {\n const screen = document.createElement('div')\n screen.style.position = 'relative'\n screen.style.display = 'block'\n screen.style.width = '100%'\n // Fill explicitly sized containers while retaining content-based height\n // when the terminal container itself has no configured height.\n screen.style.height = '100%'\n screen.style.overflow = 'hidden'\n return screen\n}\n\nexport function createPre(): HTMLPreElement {\n const pre = document.createElement('pre')\n pre.style.margin = '0'\n pre.style.padding = '8px'\n pre.style.backgroundColor = '#1e1e2e'\n pre.style.color = '#cdd6f4'\n pre.style.overflow = 'hidden'\n // Keep the rendered rows in normal flow so an auto-height terminal gets\n // its height from its content. Fit mode measures the container directly.\n pre.style.position = 'relative'\n pre.style.width = '100%'\n pre.style.minHeight = '100%'\n pre.style.boxSizing = 'border-box'\n pre.style.userSelect = 'none'\n pre.style.webkitUserSelect = 'none'\n pre.style.cursor = 'text'\n // Lock advance width to font's nominal monospace metric. Without these,\n // the browser can insert sub-pixel kerning / ligature shifts that drift\n // the actual char position away from the cursor's `col * metrics.width`\n // offset — by col 80 the cursor is visibly off by several characters.\n pre.style.letterSpacing = '0'\n pre.style.fontKerning = 'none'\n pre.style.fontFeatureSettings = 'normal'\n pre.style.fontVariantLigatures = 'none'\n pre.style.textRendering = 'geometricPrecision'\n return pre\n}\n\nexport function applyTerminalColors(\n pre: HTMLPreElement,\n foreground: Color | null,\n background: Color | null,\n defaultForeground: string,\n defaultBackground: string\n): void {\n pre.style.color = foreground ? rgb(foreground) : defaultForeground\n pre.style.backgroundColor = background ? rgb(background) : defaultBackground\n}\n\nexport function createSelectionLayer(): HTMLDivElement {\n const layer = document.createElement('div')\n layer.setAttribute('aria-hidden', 'true')\n layer.setAttribute('data-ghostty-selection-layer', 'true')\n layer.style.position = 'absolute'\n layer.style.inset = '0'\n layer.style.pointerEvents = 'none'\n layer.style.zIndex = '0'\n return layer\n}\n\nexport function createMeasure(): HTMLSpanElement {\n const span = document.createElement('span')\n span.textContent = 'MMMMMMMMMM'\n span.setAttribute('aria-hidden', 'true')\n span.style.position = 'absolute'\n span.style.visibility = 'hidden'\n span.style.pointerEvents = 'none'\n span.style.whiteSpace = 'pre'\n span.style.font = 'inherit'\n span.style.lineHeight = 'inherit'\n return span\n}\n\nexport function createCursorEl(): { cursorEl: HTMLDivElement; cursorText: HTMLSpanElement } {\n const cursorEl = document.createElement('div')\n cursorEl.setAttribute('aria-hidden', 'true')\n cursorEl.style.position = 'absolute'\n cursorEl.style.display = 'none'\n cursorEl.style.pointerEvents = 'none'\n cursorEl.style.boxSizing = 'border-box'\n cursorEl.style.whiteSpace = 'pre'\n cursorEl.style.zIndex = '1'\n\n const cursorText = document.createElement('span')\n cursorText.style.display = 'block'\n cursorText.style.width = '100%'\n cursorText.style.height = '100%'\n cursorText.style.font = 'inherit'\n cursorText.style.lineHeight = 'inherit'\n cursorEl.appendChild(cursorText)\n\n return { cursorEl, cursorText }\n}\n\nexport function setupInput(input: HTMLTextAreaElement): void {\n input.setAttribute('data-ghostty-input', 'true')\n input.setAttribute('aria-label', 'Terminal input')\n input.setAttribute('autocapitalize', 'off')\n input.setAttribute('autocomplete', 'off')\n input.setAttribute('autocorrect', 'off')\n input.setAttribute('spellcheck', 'false')\n input.style.position = 'absolute'\n input.style.left = '0'\n input.style.top = '0'\n input.style.width = '1px'\n input.style.height = '1em'\n input.style.padding = '0'\n input.style.margin = '0'\n input.style.border = '0'\n input.style.outline = 'none'\n input.style.opacity = '0'\n input.style.resize = 'none'\n input.sty" <> ...}, {"hook.ts", "import { renderCursor } from './cursor'\nimport {\n applyTerminalColors,\n createCursorEl,\n createMeasure,\n createPre,\n createScreen,\n createSelectionLayer,\n measureCellMetrics,\n setupInput\n} from './dom'\nimport {\n hasMouseModifiers,\n isBrowserDevShortcut,\n isCopyShortcut,\n isPasteShortcut,\n mouseButtonName,\n primaryPressedButton\n} from './input'\nimport { applyRowUpdates, renderCells, renderRows, renderSelection } from './render'\nimport { normalizeSelection, selectedText } from './selection'\nimport { DEFAULT_MOUSE } from './types'\nimport { clamp } from './util'\n\nimport type {\n Cell,\n CellMetrics,\n CellPoint,\n CursorState,\n MouseModes,\n RenderPayload,\n RenderRow,\n ScrollbarState\n} from './types'\n\ninterface DeferredRender {\n rowsData: Cell[][]\n payload: RenderPayload\n}\n\ninterface PendingMousePress {\n event: MouseEvent\n point: CellPoint\n}\n\ninterface TerminalState {\n cols: number\n rows: number\n fit: boolean\n autofocus: boolean\n copyMode: boolean\n rowsData: Cell[][]\n cursor: CursorState | null\n mouse: MouseModes\n scrollbar: ScrollbarState | null\n focusReporting: boolean\n focused: boolean\n composing: boolean\n cursorBlinkVisible: boolean\n cursorBlinkTimer: ReturnType<typeof setInterval> | null\n target: string | null\n resizeObserver: ResizeObserver | null\n pendingFitTimer: ReturnType<typeof setTimeout> | null\n lastFitCols: number | null\n lastFitRows: number | null\n selectionAnchor: CellPoint | null\n selectionFocus: CellPoint | null\n selecting: boolean\n pointerActive: boolean\n autofocusTimers: ReturnType<typeof setTimeout>[]\n readySent: boolean\n autofocusPending: boolean\n deferredRender: DeferredRender | null\n pendingMousePress: PendingMousePress | null\n defaultForeground: string\n defaultBackground: string\n\n onRenderCells?: (pre: HTMLPreElement, rows: Cell[][]) => void\n onRenderRows?: (pre: HTMLPreElement, rows: RenderRow[], allRows: Cell[][]) => void\n\n screen: HTMLDivElement\n pre: HTMLPreElement\n selectionLayer: HTMLDivElement\n measure: HTMLSpanElement\n input: HTMLTextAreaElement\n cursorEl: HTMLDivElement\n cursorText: HTMLSpanElement\n\n onContainerFocus: () => void\n onContainerBlur: () => void\n onPointerDown: (e: MouseEvent) => void\n onPointerMove: (e: MouseEvent) => void\n onPointerUp: (e: MouseEvent) => void\n onDocumentPointerDown: (e: MouseEvent) => void\n onDocumentFocusIn: (e: FocusEvent) => void\n onContextMenu: (e: Event) => void\n onWindowResize: () => void\n onKeydown: (e: KeyboardEvent) => void\n onPaste: (e: ClipboardEvent) => void\n onCopy: (e: ClipboardEvent) => void\n onCompositionStart: () => void\n onCompositionEnd: (e: CompositionEvent) => void\n onInputFocus: () => void\n onInputBlur: () => void\n}\n\n// Phoenix LiveView hook methods\ninterface HookMethods {\n el: HTMLElement\n pushEvent(event: string, payload: object): void\n pushEventTo(target: string, event: string, payload: object): void\n handleEvent(event: string, callback: (payload: never) => void): void\n}\n\ntype Hook = TerminalState & HookMethods\n\nfunction pushHookEvent(hook: Hook, name: string, payload: object): void {\n if (hook.target) {\n hook.pushEventTo(hook.target, name, payload)\n } else {\n hook.pushEvent(name, payload)\n }\n}\n\nfunction metrics(hook: Hook): CellMetrics {\n return measureCellMetrics(hook.pre, hook.measure, hook.input, hook.cursorEl)\n}\n\nfunction isInsideTerminal(hook: Hook, node: Node | null): boolean {\n return Boolean(node && (node === hook.el || node === hook.input || hook.el.contains(node)))\n}\n\nfunction mouseModeActive(hook: Hook): boolean {\n return Boolean(hook.mouse?.tracking)\n}\n\nfunction selectionAllowed(hook: Hook): boolean {\n return !mouseModeActive(hook) || hook.copyMode\n}\n\nfunction hasSelection(hook: Hook): boolean {\n return (\n selectionAllowed(hook) && normalizeSelection(hook.selectionAnchor, hook.selectionFocus) !== null\n )\n}\n\nfunction defersRenderingForSelection(hook: Hook): boolean {\n return hook.copyMode && mouseModeActive(hook) && (hook.selecting || hasSelection(hook))\n}\n\nfunction clearSelection(hook: Hook): void {\n hook.selectionAnchor = nu" <> ...}, {"input.ts", "export function isCopyShortcut(e: KeyboardEvent): boolean {\n return (e.metaKey || e.ctrlKey) && !e.altKey && e.key.toLowerCase() === 'c'\n}\n\nexport function isPasteShortcut(e: KeyboardEvent): boolean {\n return (e.metaKey || e.ctrlKey) && !e.altKey && e.key.toLowerCase() === 'v'\n}\n\nexport function isBrowserDevShortcut(e: KeyboardEvent): boolean {\n const key = e.key.toLowerCase()\n\n if (key === 'f5' || key === 'f12') return true\n\n // Hard refresh and Chromium/Firefox developer tools on Windows and Linux.\n if ((e.ctrlKey || e.metaKey) && e.shiftKey && ['r', 'i', 'j', 'c'].includes(key)) {\n return true\n }\n\n // Chromium/Safari developer tools on macOS.\n return e.metaKey && e.altKey && ['i', 'j', 'c'].includes(key)\n}\n\nexport function mouseButtonName(button: number): string | null {\n switch (button) {\n case 0:\n return 'left'\n case 1:\n return 'middle'\n case 2:\n return 'right'\n case 3:\n return 'four'\n case 4:\n return 'five'\n default:\n return null\n }\n}\n\nexport function primaryPressedButton(e: MouseEvent): number {\n if (e.buttons & 1) return 0\n if (e.buttons & 4) return 1\n if (e.buttons & 2) return 2\n if (e.buttons & 8) return 3\n if (e.buttons & 16) return 4\n return -1\n}\n\nexport function hasMouseModifiers(e: MouseEvent): boolean {\n return e.shiftKey || e.ctrlKey || e.altKey || e.metaKey\n}\n"}, {"phoenix.d.ts", "interface ViewHook {\n el: HTMLElement\n pushEvent(event: string, payload: object): void\n pushEventTo(target: string, event: string, payload: object): void\n handleEvent(event: string, callback: (payload: never) => void): void\n}\n\ntype ViewHookObject = ThisType<ViewHook> & {\n mounted?(): void\n destroyed?(): void\n}\n"}, {"render.ts", "import { CellFlags } from './types'\nimport { esc, rgb } from './util'\n\nimport type { Cell, CellMetrics, Color, RenderRow, Selection } from './types'\n\nexport function renderCells(pre: HTMLPreElement, rows: Cell[][]): void {\n pre.innerHTML = rows\n .map((row, index) => `<span data-ghostty-row=\"${index}\">${renderRow(row)}</span>\\n`)\n .join('')\n}\n\nexport function applyRowUpdates(rows: Cell[][], updates: RenderRow[]): RenderRow[] {\n const accepted: RenderRow[] = []\n\n for (const update of updates) {\n const { index, cells } = update\n const current = rows[index]\n\n if (\n Number.isInteger(index) &&\n index >= 0 &&\n Array.isArray(cells) &&\n current !== undefined &&\n cells.length === current.length\n ) {\n rows[index] = cells\n accepted.push(update)\n }\n }\n\n return accepted\n}\n\nexport function renderRows(pre: HTMLPreElement, rows: RenderRow[]): boolean {\n const replacements: Array<{ element: Element; html: string }> = []\n\n for (const { index, cells } of rows) {\n const element = pre.children.item(index)\n if (!element || element.getAttribute('data-ghostty-row') !== String(index)) {\n return false\n }\n replacements.push({ element, html: renderRow(cells) })\n }\n\n for (const { element, html } of replacements) {\n element.innerHTML = html\n }\n\n return true\n}\n\nfunction renderRow(row: Cell[]): string {\n // Coalesce runs of consecutive cells with identical style into one span.\n let html = ''\n let runStyle: string | null = null\n let runChars = ''\n\n for (const [char, fg, bg, flags] of row) {\n const styles = cellStyles(fg, bg, flags)\n const styleStr = styles.length > 0 ? styles.join(';') : ''\n const ch = char || ' '\n if (styleStr === runStyle) {\n runChars += esc(ch)\n } else {\n if (runChars) {\n html += runStyle ? `<span style=\"${runStyle}\">${runChars}</span>` : runChars\n }\n runStyle = styleStr\n runChars = esc(ch)\n }\n }\n\n if (runChars) {\n html += runStyle ? `<span style=\"${runStyle}\">${runChars}</span>` : runChars\n }\n\n return html\n}\n\nexport function renderSelection(\n layer: HTMLDivElement,\n selection: Selection | null,\n cols: number,\n metrics: CellMetrics\n): void {\n layer.innerHTML = ''\n\n if (!selection) {\n return\n }\n\n for (let row = selection.start.row; row <= selection.end.row; row += 1) {\n const startCol = row === selection.start.row ? selection.start.col : 0\n const endCol = row === selection.end.row ? selection.end.col : cols - 1\n const rect = document.createElement('div')\n rect.style.position = 'absolute'\n rect.style.left = `${metrics.paddingLeft + startCol * metrics.width}px`\n rect.style.top = `${metrics.paddingTop + row * metrics.height}px`\n rect.style.width = `${Math.max(1, endCol - startCol + 1) * metrics.width}px`\n rect.style.height = `${metrics.height}px`\n rect.style.background = 'rgba(137, 180, 250, 0.35)'\n rect.style.borderRadius = '2px'\n layer.appendChild(rect)\n }\n}\n\nfunction cellStyles(fg: Color | null, bg: Color | null, flags: number): string[] {\n const styles: string[] = []\n const decorations: string[] = []\n\n if (fg) styles.push(`color:${rgb(fg)}`)\n if (bg) styles.push(`background:${rgb(bg)}`)\n if (flags & CellFlags.BOLD) styles.push('font-weight:bold')\n if (flags & CellFlags.ITALIC) styles.push('font-style:italic')\n if (flags & CellFlags.DIM) styles.push('opacity:0.5')\n if (flags & CellFlags.UNDERLINE) decorations.push('underline')\n if (flags & CellFlags.STRIKETHROUGH) decorations.push('line-through')\n if (flags & CellFlags.OVERLINE) decorations.push('overline')\n if (decorations.length > 0) styles.push(`text-decoration:${decorations.join(' ')}`)\n\n return styles\n}\n\nexport function applyCellTextStyles(el: HTMLElement, cell: Cell | null): void {\n if (!cell) return\n\n const [, , , flags] = cell\n const decorations: string[] = []\n\n el.style.fontWeight = flags & CellFlags.BOLD ? 'bold' : ''\n el.style.fontStyle = flags & CellFlags.ITALIC ? 'italic' : ''\n el.style.opacity = flags & CellFlags.DIM ? '0.5' : '1'\n if (flags & CellFlags.UNDERLINE" <> ...}, {"selection.ts", "import type { Cell, CellPoint, Selection } from './types'\n\nexport function normalizeSelection(\n anchor: CellPoint | null,\n focus: CellPoint | null\n): Selection | null {\n if (!anchor || !focus) {\n return null\n }\n\n const start = { ...anchor }\n const end = { ...focus }\n\n if (end.row < start.row || (end.row === start.row && end.col < start.col)) {\n return { start: end, end: start }\n }\n\n if (start.row === end.row && start.col === end.col) {\n return null\n }\n\n return { start, end }\n}\n\nexport function selectedText(\n selection: Selection | null,\n rowsData: Cell[][],\n cols: number\n): string {\n if (!selection) {\n return ''\n }\n\n const lines: string[] = []\n\n for (let row = selection.start.row; row <= selection.end.row; row += 1) {\n const sourceRow = rowsData[row] || []\n const startCol = row === selection.start.row ? selection.start.col : 0\n const endCol = row === selection.end.row ? selection.end.col : cols - 1\n let text = ''\n\n for (let col = startCol; col <= endCol; col += 1) {\n const cell = sourceRow[col]\n text += cell?.[0] || ' '\n }\n\n lines.push(text.trimEnd())\n }\n\n return lines.join('\\n')\n}\n"}, {"types.ts", "export type Color = [number, number, number]\n\nexport type Cell = [string, Color | null, Color | null, number]\n\nexport interface CellPoint {\n col: number\n row: number\n encodeX: number\n encodeY: number\n}\n\nexport interface MouseModes {\n tracking: boolean\n x10: boolean\n normal: boolean\n button: boolean\n any: boolean\n sgr: boolean\n}\n\nexport interface CursorState {\n x: number | null\n y: number | null\n visible: boolean\n blinking: boolean\n style: 'block' | 'bar' | 'underline' | 'block_hollow'\n wide_tail: boolean\n color: Color | null\n}\n\nexport interface ScrollbarState {\n total: number\n offset: number\n len: number\n}\n\nexport interface RenderRow {\n index: number\n cells: Cell[]\n}\n\ninterface RenderPayloadMetadata {\n id: string\n cursor: CursorState\n foreground: Color | null\n background: Color | null\n mouse: MouseModes\n scrollbar: ScrollbarState\n focus_reporting: boolean\n}\n\nexport type RenderPayload = RenderPayloadMetadata &\n ({ cells: Cell[][]; rows?: never } | { cells?: never; rows: RenderRow[] })\n\nexport interface CellMetrics {\n width: number\n height: number\n paddingLeft: number\n paddingRight: number\n paddingTop: number\n paddingBottom: number\n}\n\nexport interface Selection {\n start: CellPoint\n end: CellPoint\n}\n\nexport const DEFAULT_MOUSE: MouseModes = {\n tracking: false,\n x10: false,\n normal: false,\n button: false,\n any: false,\n sgr: false\n}\n\nexport const CellFlags = {\n BOLD: 1,\n ITALIC: 2,\n DIM: 4,\n UNDERLINE: 8,\n STRIKETHROUGH: 16,\n OVERLINE: 128\n} as const\n"}, {"util.ts", "import type { Color } from './types'\n\nexport function esc(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')\n}\n\nexport function rgb(color: Color): string {\n return `rgb(${color[0]},${color[1]},${color[2]})`\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n"}], %{entry: "hook.ts", exports: "auto", external: [], format: "esm", modules: [], cwd: "", define: %{}, target: "", footer: nil, sourcemap: false, minify: false, treeshake: false, drop_console: false, banner: nil, preamble: nil, conditions: [], main_fields: [], module_types: %{}, preserve_entry_signatures: "", jsx: "automatic", jsx_factory: "", jsx_fragment: "", import_source: ""})220 (oxc 0.17.8) lib/oxc.ex:487: OXC.bundle/2221 (ghostty 0.5.0) lib/mix/compilers/ghostty_js.ex:47: Mix.Compilers.GhosttyJS.do_bundle/2222 (mix 1.20.3) lib/mix/task.ex:589: Mix.Task.run_alias/6223 (mix 1.20.3) lib/mix/tasks/deps.compile.ex:230: anonymous fn/2 in Mix.Tasks.Deps.Compile.do_mix/2224 (mix 1.20.3) lib/mix/project.ex:557: Mix.Project.in_project/4225 (elixir 1.20.3) lib/file.ex:2100: File.cd!/2226 (mix 1.20.3) lib/mix/dep.ex:279: Mix.Dep.in_dependency/3