From 7f6a52ae7c3ffaafa3384820ca112e3506086895 Mon Sep 17 00:00:00 2001 From: Kam Date: Wed, 11 Mar 2026 05:55:21 -0400 Subject: [PATCH] Add Java Doc Resource / API Registration --- .github/javadoc/javadoc-footer.html | 44 + .github/javadoc/javadoc-header.html | 11 + .github/javadoc/javadoc-theme.css | 954 +++++++++ .github/pages/index.html | 14 + .github/pages/package-lock.json | 1794 +++++++++++++++++ .github/pages/package.json | 19 + .github/pages/public/manifest.json | 6 + .github/pages/src/App.jsx | 64 + .github/pages/src/App.module.css | 16 + .github/pages/src/components/Card.jsx | 97 + .github/pages/src/components/Card.module.css | 143 ++ .github/pages/src/components/Footer.jsx | 29 + .../pages/src/components/Footer.module.css | 36 + .github/pages/src/components/Section.jsx | 18 + .../pages/src/components/Section.module.css | 46 + .github/pages/src/components/States.jsx | 30 + .../pages/src/components/States.module.css | 47 + .../pages/src/components/TerminalHeader.jsx | 186 ++ .../src/components/TerminalHeader.module.css | 303 +++ .github/pages/src/config.js | 38 + .github/pages/src/index.css | 50 + .github/pages/src/main.jsx | 13 + .github/pages/src/useDocs.js | 94 + .github/pages/vite.config.js | 12 + .github/scripts/doc-config.sh | 18 + .github/scripts/generate-index.sh | 107 + .github/scripts/resolve-doc-path.sh | 52 + .github/workflows/build-and-test.yml | 140 +- .github/workflows/buildscript-maintenance.yml | 39 - .github/workflows/javadoc.yml | 260 +++ .gitignore | 4 + build.gradle | 29 + gradle.properties | 2 +- .../goodbird/npcgecko/CustomNpcPlusGecko.java | 4 +- 34 files changed, 4675 insertions(+), 44 deletions(-) create mode 100644 .github/javadoc/javadoc-footer.html create mode 100644 .github/javadoc/javadoc-header.html create mode 100644 .github/javadoc/javadoc-theme.css create mode 100644 .github/pages/index.html create mode 100644 .github/pages/package-lock.json create mode 100644 .github/pages/package.json create mode 100644 .github/pages/public/manifest.json create mode 100644 .github/pages/src/App.jsx create mode 100644 .github/pages/src/App.module.css create mode 100644 .github/pages/src/components/Card.jsx create mode 100644 .github/pages/src/components/Card.module.css create mode 100644 .github/pages/src/components/Footer.jsx create mode 100644 .github/pages/src/components/Footer.module.css create mode 100644 .github/pages/src/components/Section.jsx create mode 100644 .github/pages/src/components/Section.module.css create mode 100644 .github/pages/src/components/States.jsx create mode 100644 .github/pages/src/components/States.module.css create mode 100644 .github/pages/src/components/TerminalHeader.jsx create mode 100644 .github/pages/src/components/TerminalHeader.module.css create mode 100644 .github/pages/src/config.js create mode 100644 .github/pages/src/index.css create mode 100644 .github/pages/src/main.jsx create mode 100644 .github/pages/src/useDocs.js create mode 100644 .github/pages/vite.config.js create mode 100644 .github/scripts/doc-config.sh create mode 100644 .github/scripts/generate-index.sh create mode 100644 .github/scripts/resolve-doc-path.sh delete mode 100644 .github/workflows/buildscript-maintenance.yml create mode 100644 .github/workflows/javadoc.yml diff --git a/.github/javadoc/javadoc-footer.html b/.github/javadoc/javadoc-footer.html new file mode 100644 index 0000000..487326d --- /dev/null +++ b/.github/javadoc/javadoc-footer.html @@ -0,0 +1,44 @@ + diff --git a/.github/javadoc/javadoc-header.html b/.github/javadoc/javadoc-header.html new file mode 100644 index 0000000..2c86e91 --- /dev/null +++ b/.github/javadoc/javadoc-header.html @@ -0,0 +1,11 @@ +
+ +
+ CustomNPC+ DBC Addon + Javadoc Reference +
+
+ + Back to Index + +
diff --git a/.github/javadoc/javadoc-theme.css b/.github/javadoc/javadoc-theme.css new file mode 100644 index 0000000..3f691d8 --- /dev/null +++ b/.github/javadoc/javadoc-theme.css @@ -0,0 +1,954 @@ +/* ============================================================ + CustomNPC+ DBC Addon — Javadoc Theme (Javadoc 11) + Tokyo Night — Styled Edition + ============================================================ */ + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap'); + +:root { + /* ── Tokyo Night palette ── */ + --bg: #1a1b26; + --bg2: #1f2335; + --bg3: #24283b; + --bg-elevated: #292e42; + --border: #3b4261; + --border2: #414868; + --text: #c0caf5; + --text-mid: #a9b1d6; + --text-dim: #565f89; + --green: #9ece6a; + --green-dim: rgba(158, 206, 106, 0.12); + --blue: #7aa2f7; + --blue-dim: rgba(122, 162, 247, 0.12); + --amber: #e0af68; + --amber-dim: rgba(224, 175, 104, 0.10); + --purple: #bb9af7; + --purple-dim: rgba(187, 154, 247, 0.10); + --cyan: #7dcfff; + --cyan-dim: rgba(125, 207, 255, 0.10); + --red: #f7768e; + --highlight-bg: rgba(122, 162, 247, 0.08); + --hover-bg: rgba(187, 154, 247, 0.08); + --nav-h: 44px; + --subnav-h: 36px; + + /* ── Font stacks ── */ + --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --font-mono: 'JetBrains Mono', 'Cascadia Code', 'Fira Code', monospace; +} + +* { box-sizing: border-box !important; } + +html, body { + height: 100%; +} + +body { + background: var(--bg) !important; + color: var(--text) !important; + font-family: var(--font-mono) !important; + font-size: 13px !important; + line-height: 1.6 !important; + margin: 0 !important; + padding: 0 !important; + min-height: 100vh !important; + display: flex !important; + flex-direction: column !important; +} + +.skipNav { display: none !important; } + +/* ══════════════════════════════════════════════ + NAVIGATION + ══════════════════════════════════════════════ */ + +.fixedNav { + position: fixed !important; + top: 0 !important; left: 0 !important; right: 0 !important; + z-index: 100 !important; +} + +/* Top bar — gradient accent stripe on top */ +.topNav { + position: relative !important; + background: var(--bg2) !important; + border-bottom: 1px solid var(--border) !important; + height: var(--nav-h) !important; + margin: 0 !important; padding: 0 !important; + display: flex !important; + align-items: stretch !important; + overflow: visible !important; +} + +/* Gradient accent line across the very top */ +.topNav::before { + content: '' !important; + position: absolute !important; + top: 0 !important; left: 0 !important; right: 0 !important; + height: 2px !important; + background: linear-gradient(90deg, var(--blue), var(--purple), var(--cyan)) !important; + z-index: 10 !important; +} + +/* Nav list — leave room on right for brand */ +.topNav > ul.navList { + list-style: none !important; + margin: 0 !important; + padding: 2px 0 0 8px !important; + padding-right: 320px !important; + display: flex !important; + align-items: stretch !important; + flex-shrink: 0 !important; +} + +.topNav > ul.navList > li { + display: flex !important; + align-items: center !important; + margin: 0 !important; + padding: 0 16px !important; + height: var(--nav-h) !important; + font-family: var(--font-ui) !important; + font-size: 12px !important; + font-weight: 500 !important; + white-space: nowrap !important; + text-transform: none !important; + letter-spacing: 0.01em !important; + color: var(--text-dim) !important; + border-bottom: 2px solid transparent !important; + transition: color 0.2s !important; +} + +.topNav > ul.navList > li > a { + display: flex !important; + align-items: center !important; + height: var(--nav-h) !important; + margin: 0 -16px !important; + padding: 0 16px !important; + color: var(--text-dim) !important; + font-family: var(--font-ui) !important; + font-size: 12px !important; + font-weight: 500 !important; + text-decoration: none !important; + text-transform: none !important; + letter-spacing: 0.01em !important; + white-space: nowrap !important; + border-bottom: 2px solid transparent !important; + transition: color 0.2s, border-color 0.2s !important; +} + +.topNav > ul.navList > li > a:hover { + color: var(--text) !important; + border-bottom-color: var(--purple) !important; + background: transparent !important; + text-shadow: none !important; + text-decoration: none !important; +} + +/* Active item — gradient underline */ +.topNav > ul.navList > li.navBarCell1Rev { + color: var(--text) !important; + border-image: linear-gradient(90deg, var(--blue), var(--purple)) 1 !important; + border-bottom-width: 2px !important; + border-bottom-style: solid !important; +} + +/* ── Brand — pinned to far right of topNav ── */ +.topNav > .aboutLanguage { + position: absolute !important; + top: 0 !important; right: 0 !important; + height: var(--nav-h) !important; + display: flex !important; + align-items: center !important; + gap: 12px !important; + padding: 0 16px !important; + background: var(--bg2) !important; + border-left: 1px solid var(--border) !important; + z-index: 5 !important; +} + +/* Hide the duplicate in bottom nav */ +.bottomNav > .aboutLanguage, +.bottomNav .aboutLanguage { + display: none !important; +} + +#javadoc-header { + display: flex !important; + align-items: center !important; + gap: 12px !important; +} + +.header-brand { text-decoration: none !important; } + +/* Brand title — gradient text */ +.header-title { + font-family: var(--font-ui) !important; + font-size: 14px !important; + font-weight: 700 !important; + background: linear-gradient(135deg, var(--blue), var(--purple)) !important; + -webkit-background-clip: text !important; + -webkit-text-fill-color: transparent !important; + background-clip: text !important; + line-height: 1.4 !important; + white-space: nowrap !important; +} + +.header-title span { + display: block !important; + font-family: var(--font-mono) !important; + font-size: 9px !important; + font-weight: 400 !important; + background: none !important; + -webkit-text-fill-color: var(--text-dim) !important; + color: var(--text-dim) !important; + margin-top: 1px !important; + letter-spacing: 0.1em !important; + text-transform: uppercase !important; +} + +.header-back { + display: inline-flex !important; + align-items: center !important; + text-decoration: none !important; + color: var(--text-dim) !important; + font-family: var(--font-ui) !important; + font-size: 11px !important; + font-weight: 500 !important; + padding: 5px 12px !important; + border: 1px solid var(--border2) !important; + border-radius: 6px !important; + white-space: nowrap !important; + transition: all 0.2s !important; +} + +.header-back:hover { + color: var(--text) !important; + border-color: var(--purple) !important; + background: var(--purple-dim) !important; + text-decoration: none !important; + text-shadow: none !important; +} + +/* ── Sub nav ── */ +.subNav { + background: var(--bg3) !important; + border-bottom: 1px solid var(--border) !important; + height: var(--subnav-h) !important; + margin: 0 !important; + padding: 0 14px !important; + display: flex !important; + align-items: center !important; + gap: 12px !important; + overflow: hidden !important; +} + +/* Search first */ +.subNav > ul.navListSearch { + order: -1 !important; +} + +.subNav ul, +.subNav ul.navList, +.subNav ul.subNavList, +.subNav ul.navListSearch { + list-style: none !important; + margin: 0 !important; + padding: 0 !important; + display: flex !important; + align-items: center !important; + gap: 0 !important; +} + +.subNav li { + display: flex !important; + align-items: center !important; + font-family: var(--font-ui) !important; + font-size: 11px !important; + color: var(--text-dim) !important; + padding: 0 6px !important; + white-space: nowrap !important; + border: none !important; + height: auto !important; + text-transform: none !important; +} + +.subNav a { + color: var(--blue) !important; + text-decoration: none !important; + font-size: 11px !important; + font-family: var(--font-ui) !important; + transition: color 0.15s !important; +} + +.subNav a:hover { color: var(--purple) !important; text-shadow: none !important; } + +.subNav label { + font-family: var(--font-ui) !important; + font-size: 11px !important; + color: var(--text-dim) !important; + text-transform: none !important; + margin-right: 4px !important; +} + +/* ══════════════════════════════════════════════ + CONTENT + ══════════════════════════════════════════════ */ + +main { + background: var(--bg) !important; + padding: 28px !important; + flex: 1 0 auto !important; +} + +.contentContainer, div.contentContainer { + background: var(--bg) !important; + padding: 0 28px 0px !important; +} + +.header { + padding: 0 28px 0 !important; + margin-bottom: 20px !important; +} + +/* Subtitle under h1 on help/overview pages */ +.header .subTitle, +div.subTitle { + color: var(--text-mid) !important; + font-family: var(--font-ui) !important; + font-size: 13px !important; + line-height: 1.7 !important; + margin-top: 8px !important; +} + +.packageLabelInType { + font-family: var(--font-mono) !important; + font-size: 11px !important; + color: var(--text-dim) !important; +} + +/* ── Headings ── */ +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-ui) !important; + font-weight: 600 !important; + line-height: 1.5 !important; + text-transform: none !important; + letter-spacing: -0.01em !important; +} + +/* Page title — gradient accent bar */ +h1.title, h2.title { + font-size: 22px !important; + font-weight: 700 !important; + color: var(--text) !important; + border-bottom: none !important; + padding-bottom: 16px !important; + padding-left: 16px !important; + margin-bottom: 24px !important; + margin-top: 0 !important; + border-left: 4px solid transparent !important; + border-image: linear-gradient(180deg, var(--blue), var(--purple)) 1 !important; +} + +/* Section h2 — colored panel */ +section > h2, +li.blockList > section > h2 { + font-size: 14px !important; + color: var(--green) !important; + border-left: 3px solid var(--green) !important; + border-bottom: none !important; + padding: 10px 14px !important; + margin: 0 !important; + background: var(--green-dim) !important; +} + +/* Generic h2 (table section headers like "Method Summary") */ +h2 { + font-size: 14px !important; + color: var(--amber) !important; + border-bottom: none !important; + border-left: 3px solid var(--amber) !important; + padding: 8px 12px !important; + margin-top: 28px !important; + margin-bottom: 12px !important; + background: var(--amber-dim) !important; +} + +/* h3 — table section headers inside blockList */ +h3 { + font-size: 12px !important; + color: var(--text-mid) !important; + margin: 0 !important; + padding: 10px 14px !important; + background: var(--bg3) !important; + border-bottom: 1px solid var(--border) !important; +} + +/* h4 — method detail names */ +h4 { + font-size: 13px !important; + font-weight: 600 !important; + color: var(--cyan) !important; + margin: 0 !important; + padding: 10px 14px !important; + background: var(--bg3) !important; + border-bottom: 1px solid var(--border) !important; + border-left: 3px solid var(--cyan) !important; +} + +/* ── blockList sections — card-like containers ── */ +ul.blockList > li.blockList, +ul.blockListLast > li.blockList { + border: 1px solid var(--border) !important; + border-radius: 6px !important; + margin-bottom: 14px !important; + padding: 0 !important; + background: var(--bg2) !important; + overflow: hidden !important; +} + +/* Help page: section cards with padding around their content */ +ul.blockList > li.blockList > section { + padding: 0 !important; +} + +ul.blockList > li.blockList > section > p, +ul.blockList > li.blockList > section > ul:not(.blockList):not(.blockListLast) { + padding: 14px 18px !important; + margin: 0 !important; + color: var(--text-mid) !important; + font-family: var(--font-ui) !important; + font-size: 13px !important; + line-height: 1.7 !important; +} + +/* Nested lists inside section content */ +ul.blockList > li.blockList > section > ul:not(.blockList):not(.blockListLast) > li { + color: var(--text-mid) !important; + font-family: var(--font-ui) !important; + font-size: 13px !important; + padding: 3px 0 !important; + list-style: none !important; +} + +ul.blockList > li.blockList > section > ul:not(.blockList):not(.blockListLast) > li::before { + content: '\203A' !important; + color: var(--purple) !important; + margin-right: 8px !important; + font-weight: 700 !important; +} + +/* ── Inherited methods block ── */ +ul.blockList > li.blockList > h3, +ul.blockList > li.blockList > ul.blockList > li.blockList > h3 { + font-size: 11px !important; + color: var(--text-dim) !important; + padding: 8px 14px !important; + background: var(--bg3) !important; + border-bottom: 1px solid var(--border) !important; + margin: 0 !important; +} + +/* The comma-separated code block of inherited method names */ +ul.blockList > li.blockList > code, +li.blockList > code { + display: block !important; + padding: 10px 16px !important; + color: var(--text-dim) !important; + font-family: var(--font-mono) !important; + font-size: 12px !important; + background: var(--bg) !important; + border: none !important; + line-height: 1.8 !important; +} + +/* ── Inheritance chain ── */ +ul.inheritance { + list-style: none !important; + padding: 0 !important; + margin: 0 0 16px !important; + font-size: 12px !important; + color: var(--text-dim) !important; +} +ul.inheritance li { padding-left: 16px !important; } +ul.inheritance li:first-child { padding-left: 0 !important; } + +/* ── General content lists (help page) ── */ +main ul:not(.blockList):not(.blockListLast):not(.navList):not(.subNavList):not(.navListSearch):not(.inheritance) { + padding-left: 0 !important; + margin: 4px 0 4px 12px !important; + list-style: none !important; +} +main ul:not(.blockList):not(.blockListLast):not(.navList):not(.subNavList):not(.navListSearch):not(.inheritance) > li { + color: var(--text-mid) !important; + font-family: var(--font-ui) !important; + font-size: 13px !important; + padding: 3px 0 !important; + line-height: 1.7 !important; +} +main ul:not(.blockList):not(.blockListLast):not(.navList):not(.subNavList):not(.navListSearch):not(.inheritance) > li::before { + content: '\203A' !important; + color: var(--purple) !important; + margin-right: 8px !important; + font-weight: 700 !important; +} + +/* General paragraphs in content */ +main > div p, .contentContainer p { + color: var(--text-mid) !important; + font-family: var(--font-ui) !important; + font-size: 13px !important; + line-height: 1.7 !important; + margin: 8px 0 !important; +} + +/* Emphasized phrase */ +.emphasizedPhrase { + display: block !important; + color: var(--text-dim) !important; + font-family: var(--font-mono) !important; + font-size: 12px !important; + font-style: italic !important; + border-left: 2px solid var(--purple) !important; + padding: 8px 14px !important; + margin-top: 16px !important; + background: var(--purple-dim) !important; + border-radius: 0 4px 4px 0 !important; +} + +/* Bottom footer subNav */ +footer { + /*margin-top: auto;*/ +} +footer .subNav { + background: var(--bg3) !important; + border-top: 1px solid var(--border) !important; + border-bottom: none !important; + height: var(--subnav-h) !important; + padding: 0 14px !important; + display: flex !important; + align-items: center !important; + gap: 12px !important; + overflow: hidden !important; +} + +/* ══════════════════════════════════════════════ + TABLES + ══════════════════════════════════════════════ */ + +table { + width: 100% !important; + border-collapse: collapse !important; + border: 1px solid var(--border) !important; + border-radius: 6px !important; + margin: 16px 0 !important; + font-size: 13px !important; + overflow: hidden !important; +} + +caption { + background: var(--bg3) !important; + padding: 8px 14px !important; + text-align: left !important; + border-bottom: 1px solid var(--border2) !important; + caption-side: top !important; +} + +/* Table tabs — pill style */ +.activeTableTab, .tableTab { + font-family: var(--font-ui) !important; + font-size: 11px !important; + font-weight: 500 !important; + text-transform: none !important; + padding: 4px 12px !important; + border: 1px solid var(--border2) !important; + border-radius: 20px !important; + display: inline-block !important; + margin-right: 6px !important; + cursor: pointer !important; + transition: all 0.2s !important; +} + +.activeTableTab { + color: var(--text) !important; + border-color: var(--blue) !important; + background: var(--blue-dim) !important; +} + +.tableTab { color: var(--text-dim) !important; background: var(--bg3) !important; } +.tableTab a { color: var(--text-dim) !important; text-decoration: none !important; } +.tableTab a:hover { color: var(--text) !important; text-shadow: none !important; } + +/* Column headers */ +th[scope="col"] { + background: var(--bg-elevated) !important; + color: var(--text-dim) !important; + font-family: var(--font-ui) !important; + font-size: 10px !important; + font-weight: 600 !important; + letter-spacing: 0.06em !important; + text-transform: uppercase !important; + padding: 10px 14px !important; + border-bottom: 2px solid var(--border2) !important; + text-align: left !important; +} + +/* Data cells */ +th[scope="row"], td { + background: var(--bg2) !important; + color: var(--text) !important; + padding: 10px 14px !important; + border-bottom: 1px solid var(--border) !important; + vertical-align: top !important; + text-align: left !important; + font-family: var(--font-mono) !important; + font-size: 12px !important; + font-weight: 400 !important; + text-transform: none !important; + letter-spacing: 0 !important; + transition: background 0.15s !important; +} + +/* Stronger alternating row contrast */ +tr.altColor > td, tr.altColor > th[scope="row"] { background: var(--bg) !important; } +tr.rowColor > td, tr.rowColor > th[scope="row"] { background: var(--bg2) !important; } + +tr:hover > td, tr:hover > th[scope="row"] { + background: var(--purple-dim) !important; + border-bottom-color: rgba(187, 154, 247, 0.25) !important; +} +tr:hover > td a, tr:hover > th[scope="row"] a { + color: var(--purple) !important; +} + +/* ── Links ── */ +a, a:visited { color: var(--blue) !important; text-decoration: none !important; transition: color 0.15s !important; } +a:hover { color: var(--purple) !important; text-decoration: none !important; } +.memberNameLink a { color: var(--cyan) !important; font-weight: 500 !important; } +.memberNameLink a:hover { color: var(--purple) !important; } +.externalLink { color: var(--blue) !important; } + +/* ── Description blocks ── */ +div.block { + color: var(--text-mid) !important; + font-family: var(--font-ui) !important; + font-size: 13px !important; + line-height: 1.7 !important; + padding: 4px 0 !important; +} +ul.blockList > li.blockList > div.block{ padding: 12px 16px !important; margin: 0 !important; } + +/* ── Method detail ── */ +ul.blockList, ul.blockListLast { list-style: none !important; padding: 0 !important; margin: 0 !important; } +ul.blockList > li.blockList, ul.blockListLast > li.blockList { + border: 1px solid var(--border) !important; + border-radius: 6px !important; + margin-bottom: 12px !important; + padding: 0 !important; + overflow: hidden !important; +} + +/* Method/type signatures — accent left bar */ +pre.methodSignature, pre.typeSignature { + background: var(--bg2) !important; + border: none !important; + border-bottom: 1px solid var(--border) !important; + border-left: 3px solid var(--cyan) !important; + margin: 0 !important; + padding: 14px 18px !important; + font-family: var(--font-mono) !important; + font-size: 12px !important; + color: var(--text) !important; + overflow-x: auto !important; + white-space: pre-wrap !important; +} + +pre { + background: var(--bg2) !important; + border: 1px solid var(--border) !important; + border-left: 3px solid var(--blue) !important; + border-radius: 6px !important; + padding: 14px 18px !important; + font-family: var(--font-mono) !important; + font-size: 12px !important; + color: var(--text) !important; + overflow-x: auto !important; + margin: 0 !important; + white-space: pre-wrap !important; +} + +code { + font-family: var(--font-mono) !important; + font-size: 12px !important; + color: var(--cyan) !important; + background: var(--bg3) !important; + padding: 2px 6px !important; + border-radius: 4px !important; +} + +dl { padding: 12px 16px !important; margin: 0 !important; } +dt { margin-bottom: 4px !important; } +dd { margin: 0 0 8px 16px !important; color: var(--text-mid) !important; font-size: 12px !important; } + +.paramLabel, .returnLabel, .throwsLabel, .seeLabel, .simpleTagLabel { + font-family: var(--font-ui) !important; + font-size: 10px !important; + font-weight: 600 !important; + color: var(--purple) !important; + text-transform: uppercase !important; + letter-spacing: 0.06em !important; +} + +.typeNameLabel { color: var(--cyan) !important; } + +.deprecationBlock { + background: var(--amber-dim) !important; + border-left: 3px solid var(--amber) !important; + border-radius: 0 6px 6px 0 !important; + padding: 10px 14px !important; + color: var(--amber) !important; + font-size: 12px !important; +} + +/* ── Inputs ── */ +input[type="text"] { + background: var(--bg) !important; + border: 1px solid var(--border2) !important; + color: var(--text) !important; + font-family: var(--font-mono) !important; + font-size: 12px !important; + padding: 5px 12px !important; + outline: none !important; + border-radius: 6px !important; + transition: border-color 0.2s, box-shadow 0.2s !important; +} +input[type="text"]:focus { + border-color: var(--blue) !important; + box-shadow: 0 0 0 2px var(--blue-dim) !important; +} +input[type="reset"] { + background: var(--bg3) !important; + border: 1px solid var(--border2) !important; + color: var(--text-dim) !important; + font-family: var(--font-ui) !important; + font-size: 11px !important; + padding: 5px 12px !important; + cursor: pointer !important; + border-radius: 6px !important; + transition: all 0.2s !important; +} +input[type="reset"]:hover { + border-color: var(--text-dim) !important; + color: var(--text-mid) !important; +} + +/* ══════════════════════════════════════════════ + BOTTOM NAV + ══════════════════════════════════════════════ */ + +.bottomNav { + background: var(--bg2) !important; + border-top: 1px solid var(--border) !important; + min-height: var(--nav-h) !important; + padding: 0 !important; + margin-top: 32px !important; + overflow: hidden !important; + position: relative !important; +} + +/* Gradient accent line on bottom nav too */ +.bottomNav::after { + content: '' !important; + position: absolute !important; + bottom: 0 !important; left: 0 !important; right: 0 !important; + height: 2px !important; + background: linear-gradient(90deg, var(--blue), var(--purple), var(--cyan)) !important; +} + +.bottomNav ul.navList[title="Navigation"] { + list-style: none !important; + margin: 0 !important; + padding: 0 0 0 8px !important; + display: flex !important; + align-items: stretch !important; + height: var(--nav-h) !important; +} + +.bottomNav ul.navList[title="Navigation"] li { + display: flex !important; + align-items: center !important; + margin: 0 !important; + padding: 0 16px !important; + height: var(--nav-h) !important; + font-family: var(--font-ui) !important; + font-size: 12px !important; + font-weight: 500 !important; + white-space: nowrap !important; + text-transform: none !important; + letter-spacing: 0.01em !important; + color: var(--text-dim) !important; + border-top: 2px solid transparent !important; + transition: color 0.2s !important; +} + +.bottomNav ul.navList[title="Navigation"] li > a { + display: flex !important; + align-items: center !important; + height: var(--nav-h) !important; + margin: 0 -16px !important; + padding: 0 16px !important; + color: var(--text-dim) !important; + text-decoration: none !important; + font-family: var(--font-ui) !important; + font-size: 12px !important; + font-weight: 500 !important; + transition: color 0.2s !important; +} + +.bottomNav ul.navList[title="Navigation"] li > a:hover { + color: var(--text) !important; + text-shadow: none !important; +} + +.bottomNav ul.navList[title="Navigation"] li.navBarCell1Rev { + color: var(--text) !important; + border-image: linear-gradient(90deg, var(--blue), var(--purple)) 1 !important; + border-top-width: 2px !important; + border-top-style: solid !important; +} + +.bottomNav .aboutLanguage { + display: none !important; +} + +.legalCopy { + background: var(--bg2) !important; + color: var(--text-dim) !important; + font-size: 11px !important; + font-family: var(--font-ui) !important; + padding: 14px 18px !important; + text-align: center !important; + border-top: 1px solid var(--border) !important; +} + +/* ══════════════════════════════════════════════ + SEARCH RESULTS DROPDOWN (jQuery UI Autocomplete) + ══════════════════════════════════════════════ */ + +.ui-autocomplete { + background: var(--bg2) !important; + border: 1px solid var(--border2) !important; + border-radius: 8px !important; + max-height: 400px !important; + overflow-y: auto !important; + overflow-x: hidden !important; + z-index: 9999 !important; + list-style: none !important; + padding: 4px 0 !important; + margin: 4px 0 0 !important; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(122, 162, 247, 0.05) !important; +} + +/* Category headers */ +.ui-autocomplete .ui-autocomplete-category { + background: var(--bg-elevated) !important; + color: var(--text-dim) !important; + font-family: var(--font-ui) !important; + font-size: 10px !important; + font-weight: 600 !important; + text-transform: uppercase !important; + letter-spacing: 0.06em !important; + padding: 6px 14px !important; + border-bottom: 1px solid var(--border) !important; + border-top: 1px solid var(--border) !important; + cursor: default !important; +} + +/* Individual result items */ +.ui-autocomplete .ui-menu-item { + background: var(--bg2) !important; + margin: 0 !important; + list-style: none !important; +} + +.ui-autocomplete .ui-menu-item > div, +.ui-autocomplete .ui-menu-item-wrapper { + background: var(--bg2) !important; + color: var(--text) !important; + font-family: var(--font-mono) !important; + font-size: 12px !important; + padding: 7px 14px !important; + border: none !important; + border-left: 2px solid transparent !important; + cursor: pointer !important; + line-height: 1.5 !important; + transition: all 0.1s !important; +} + +/* Hover / focus state */ +.ui-autocomplete .ui-menu-item > div.ui-state-active, +.ui-autocomplete .ui-menu-item > div.ui-state-focus, +.ui-autocomplete .ui-menu-item-wrapper.ui-state-active, +.ui-autocomplete .ui-menu-item-wrapper.ui-state-focus, +.ui-autocomplete .ui-state-active, +.ui-autocomplete .ui-state-focus { + background: var(--purple-dim) !important; + color: var(--text) !important; + border: none !important; + border-left: 2px solid var(--purple) !important; + margin: 0 !important; +} + +/* Highlighted matching text */ +.resultHighlight { + color: var(--cyan) !important; + font-weight: 600 !important; +} + +/* Search tag result extras */ +.searchTagHolderResult { + color: var(--text-dim) !important; + font-size: 11px !important; +} + +.searchTagDescResult { + color: var(--text-dim) !important; + font-size: 11px !important; + font-style: italic !important; +} + +/* "No results found" */ +.ui-autocomplete .ui-menu-item:only-child > div { + color: var(--text-dim) !important; + font-style: italic !important; +} + +/* Override jQuery UI defaults */ +.ui-widget { + font-family: var(--font-mono) !important; +} + +.ui-widget-content { + background: var(--bg2) !important; + color: var(--text) !important; + border-color: var(--border2) !important; +} + +.ui-menu .ui-menu-item { + padding: 0 !important; +} + +/* Watermark style for search input placeholder */ +.watermark { + color: var(--text-dim) !important; +} + +/* ══════════════════════════════════════════════ + MISC + ══════════════════════════════════════════════ */ + +::-webkit-scrollbar { width: 8px; height: 8px; } +::-webkit-scrollbar-track { background: var(--bg); } +::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; } +::-webkit-scrollbar-thumb:hover { background: var(--text-dim); } +::selection { background: rgba(187, 154, 247, 0.25); color: var(--text); } +hr { border: none !important; border-top: 1px solid var(--border) !important; margin: 24px 0 !important; } diff --git a/.github/pages/index.html b/.github/pages/index.html new file mode 100644 index 0000000..5e467c9 --- /dev/null +++ b/.github/pages/index.html @@ -0,0 +1,14 @@ + + + + + + Javadoc Index + + + + +
+ + + diff --git a/.github/pages/package-lock.json b/.github/pages/package-lock.json new file mode 100644 index 0000000..037a565 --- /dev/null +++ b/.github/pages/package-lock.json @@ -0,0 +1,1794 @@ +{ + "name": "javadoc-index", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "javadoc-index", + "version": "1.0.0", + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.2.1", + "vite": "^7.3.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001777", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001777.tgz", + "integrity": "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", + "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/.github/pages/package.json b/.github/pages/package.json new file mode 100644 index 0000000..c7ccaf3 --- /dev/null +++ b/.github/pages/package.json @@ -0,0 +1,19 @@ +{ + "name": "javadoc-index", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.2.1", + "vite": "^7.3.1" + } +} diff --git a/.github/pages/public/manifest.json b/.github/pages/public/manifest.json new file mode 100644 index 0000000..9c2e85b --- /dev/null +++ b/.github/pages/public/manifest.json @@ -0,0 +1,6 @@ +{ + "releases": [], + "experimental": [], + "generated": "", + "source": "manifest" +} diff --git a/.github/pages/src/App.jsx b/.github/pages/src/App.jsx new file mode 100644 index 0000000..b306112 --- /dev/null +++ b/.github/pages/src/App.jsx @@ -0,0 +1,64 @@ +import styles from './App.module.css' +import { useDocs } from './useDocs' +import TerminalHeader from './components/TerminalHeader' +import Section from './components/Section' +import { ReleaseCard, ExperimentalCard } from './components/Card' +import { LoadingState, ErrorState, EmptyState } from './components/States' +import Footer from './components/Footer' + +export default function App() { + const { data, loading, error } = useDocs() + + const releases = data?.releases || [] + const experimental = data?.experimental || [] + + return ( +
+ + + {/* ── Releases ── */} +
+ {loading ? ( + + ) : error ? ( + + ) : releases.length === 0 ? ( + + ) : ( +
+ {releases.map((r, i) => ( + + ))} +
+ )} +
+ + {/* ── Experimental ── */} +
+ {loading ? ( + + ) : error ? null : experimental.length === 0 ? ( + + ) : ( +
+ {experimental.map((b, i) => ( + + ))} +
+ )} +
+ + {!loading && !error && ( +
+ )} +
+ ) +} diff --git a/.github/pages/src/App.module.css b/.github/pages/src/App.module.css new file mode 100644 index 0000000..395790d --- /dev/null +++ b/.github/pages/src/App.module.css @@ -0,0 +1,16 @@ +.root { + max-width: 1100px; + margin: 0 auto; + padding: 48px 32px 96px; +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 10px; +} + +@media (max-width: 600px) { + .root { padding: 24px 16px 64px; } + .grid { grid-template-columns: 1fr; } +} diff --git a/.github/pages/src/components/Card.jsx b/.github/pages/src/components/Card.jsx new file mode 100644 index 0000000..73b1f7c --- /dev/null +++ b/.github/pages/src/components/Card.jsx @@ -0,0 +1,97 @@ +import styles from './Card.module.css' +import { REPO_NAME } from '../config' + +const BASE_PATH = `/${REPO_NAME}` + +function formatDate(iso) { + if (!iso) return null + try { + return new Intl.DateTimeFormat('en-GB', { + day: '2-digit', month: 'short', year: 'numeric' + }).format(new Date(iso)) + } catch (e) { return null } +} + +export function ReleaseCard({ release, index }) { + const isLatest = release.isLatest + const date = formatDate(release.date) + const cardClass = isLatest + ? styles.card + ' ' + styles.latest + : styles.card + ' ' + styles.release + + return ( + +
+
+ {isLatest && ( + ● latest + )} + release +
+ → +
+ +
+ v{release.version} +
+
+ {date && ( +
+ date + {date} +
+ )} +
+ path + {release.path}/ +
+
+
+ ) +} + +export function ExperimentalCard({ branch, index }) { + const date = formatDate(branch.date) + + return ( + +
+ + experimental + + → +
+ +
+ {branch.branch} +
+ +
+ {date && ( +
+ date + {date} +
+ )} + {branch.hash && ( +
+ sha + {branch.hash} +
+ )} +
+ path + {branch.path}/ +
+
+
+ ) +} diff --git a/.github/pages/src/components/Card.module.css b/.github/pages/src/components/Card.module.css new file mode 100644 index 0000000..b19f37f --- /dev/null +++ b/.github/pages/src/components/Card.module.css @@ -0,0 +1,143 @@ +.card { + display: block; + text-decoration: none; + background: var(--bg2); + border: 1px solid var(--border); + border-radius: 6px; + padding: 20px 22px; + transition: border-color 0.15s, background 0.15s, transform 0.15s; + position: relative; + overflow: hidden; + animation: fadeUp 0.35s ease both; +} + +.card::before { + content: ''; + position: absolute; + top: 0; left: 0; right: 0; + height: 2px; + opacity: 0; + transition: opacity 0.15s; +} + +.release::before { background: var(--green); } +.latest::before { background: linear-gradient(90deg, var(--green), var(--blue)); } +.experimental::before { background: var(--amber); } + +.card:hover { + border-color: var(--border2); + background: var(--bg3); + transform: translateY(-2px); +} + +.card:hover::before { opacity: 1; } + +/* ── Header ── */ +.header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 14px; +} + +.badges { + display: flex; + align-items: center; + gap: 6px; +} + +.badge { + font-size: 9px; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + padding: 2px 8px; + border-radius: 2px; + border: 1px solid; +} + +.badgeLatest { + color: var(--green); + border-color: var(--green-dim); + background: rgba(57, 211, 83, 0.08); + animation: pulseBorder 2s ease infinite; +} + +.badgeRelease { + color: var(--text-dim); + border-color: var(--border2); + background: transparent; +} + +.badgeExperimental { + color: var(--amber); + border-color: var(--amber-dim); + background: rgba(240, 160, 48, 0.08); +} + +.arrow { + font-size: 14px; + color: var(--border2); + transition: color 0.15s, transform 0.15s; +} + +.card:hover .arrow { + color: var(--text-mid); + transform: translateX(3px); +} + +/* ── Version ── */ +.version { + font-size: 20px; + font-weight: 500; + color: var(--text); + margin-bottom: 4px; + letter-spacing: -0.01em; +} + +.latest .version { color: var(--green); } +.versionBranch { font-size: 16px; color: var(--amber); } + +/* ── Meta ── */ +.meta { + display: flex; + flex-direction: column; + gap: 3px; + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid var(--border); +} + +.metaRow { + display: flex; + align-items: center; + gap: 8px; + font-size: 10px; + color: var(--text-dim); +} + +.metaKey { + min-width: 36px; + color: var(--text-dim); +} + +.metaVal { + color: var(--text-mid); + font-family: 'IBM Plex Mono', monospace; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.hash { color: var(--blue); } + +/* ── Animations ── */ +@keyframes fadeUp { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +@keyframes pulseBorder { + 0%, 100% { border-color: var(--green-dim); } + 50% { border-color: var(--green); } +} diff --git a/.github/pages/src/components/Footer.jsx b/.github/pages/src/components/Footer.jsx new file mode 100644 index 0000000..503f5e0 --- /dev/null +++ b/.github/pages/src/components/Footer.jsx @@ -0,0 +1,29 @@ +import styles from './Footer.module.css' +import { REPO_OWNER, REPO_NAME } from '../useDocs' + +export default function Footer({ source }) { + const now = new Intl.DateTimeFormat('en-GB', { + day: '2-digit', month: 'short', year: 'numeric', + hour: '2-digit', minute: '2-digit', timeZoneName: 'short' + }).format(new Date()) + + return ( + + ) +} diff --git a/.github/pages/src/components/Footer.module.css b/.github/pages/src/components/Footer.module.css new file mode 100644 index 0000000..26424d3 --- /dev/null +++ b/.github/pages/src/components/Footer.module.css @@ -0,0 +1,36 @@ +.footer { + margin-top: 64px; + padding-top: 20px; + border-top: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 8px; + font-size: 11px; + color: var(--text-dim); +} + +.dot { + display: inline-block; + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--green); + margin-right: 6px; + animation: blink 2s ease infinite; +} + +.link { + color: var(--blue); + text-decoration: none; +} + +.link:hover { + text-decoration: underline; +} + +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.3; } +} diff --git a/.github/pages/src/components/Section.jsx b/.github/pages/src/components/Section.jsx new file mode 100644 index 0000000..dc28e1d --- /dev/null +++ b/.github/pages/src/components/Section.jsx @@ -0,0 +1,18 @@ +import styles from './Section.module.css' + +export default function Section({ label, count, variant, children }) { + return ( +
+
+ {label} +
+ {count !== undefined && ( + + {count} {label.toLowerCase()}{count !== 1 ? 's' : ''} + + )} +
+ {children} +
+ ) +} diff --git a/.github/pages/src/components/Section.module.css b/.github/pages/src/components/Section.module.css new file mode 100644 index 0000000..00f90a8 --- /dev/null +++ b/.github/pages/src/components/Section.module.css @@ -0,0 +1,46 @@ +.section { + margin-top: 40px; + margin-bottom: 8px; +} + +.header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; +} + +.tag { + font-size: 10px; + font-weight: 600; + letter-spacing: 0.15em; + text-transform: uppercase; + padding: 3px 10px; + border-radius: 3px; + border: 1px solid; + white-space: nowrap; +} + +.releases { + color: var(--green); + border-color: var(--green-dim); + background: rgba(57, 211, 83, 0.06); +} + +.experimental { + color: var(--amber); + border-color: var(--amber-dim); + background: rgba(240, 160, 48, 0.06); +} + +.line { + flex: 1; + height: 1px; + background: var(--border); +} + +.count { + font-size: 11px; + color: var(--text-dim); + white-space: nowrap; +} diff --git a/.github/pages/src/components/States.jsx b/.github/pages/src/components/States.jsx new file mode 100644 index 0000000..2827d40 --- /dev/null +++ b/.github/pages/src/components/States.jsx @@ -0,0 +1,30 @@ +import styles from './States.module.css' + +export function LoadingState() { + return ( +
+
+

Fetching documentation index...

+
+ ) +} + +export function ErrorState({ message }) { + return ( +
+
⚠
+

{message}

+

+ Check that the gh-pages branch exists and is publicly accessible. +

+
+ ) +} + +export function EmptyState({ label }) { + return ( +
+

No {label} found.

+
+ ) +} diff --git a/.github/pages/src/components/States.module.css b/.github/pages/src/components/States.module.css new file mode 100644 index 0000000..319fc6e --- /dev/null +++ b/.github/pages/src/components/States.module.css @@ -0,0 +1,47 @@ +.box { + border: 1px solid var(--border); + border-radius: 6px; + padding: 48px; + text-align: center; + background: var(--bg2); +} + +.empty { + padding: 24px; +} + +.spinner { + width: 22px; + height: 22px; + border: 2px solid var(--border2); + border-top-color: var(--green); + border-radius: 50%; + animation: spin 0.75s linear infinite; + margin: 0 auto 14px; +} + +.label { + font-size: 12px; + color: var(--text-dim); +} + +.errorIcon { + font-size: 22px; + margin-bottom: 10px; + color: var(--red); +} + +.errorMsg { + font-size: 13px; + color: var(--red); + margin-bottom: 6px; +} + +.errorSub { + font-size: 11px; + color: var(--text-dim); +} + +@keyframes spin { + to { transform: rotate(360deg); } +} diff --git a/.github/pages/src/components/TerminalHeader.jsx b/.github/pages/src/components/TerminalHeader.jsx new file mode 100644 index 0000000..e2efb27 --- /dev/null +++ b/.github/pages/src/components/TerminalHeader.jsx @@ -0,0 +1,186 @@ +import { useState, useEffect } from 'react' +import styles from './TerminalHeader.module.css' +import { PROJECT_NAME, REPO_NAME, LINKS, AUTHORS } from '../config' + +function useGitHubProfile(username) { + const [profile, setProfile] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + const cacheKey = 'gh-profile-' + username + + // Check sessionStorage first — avoids hammering the API on every render + try { + const cached = sessionStorage.getItem(cacheKey) + if (cached) { + setProfile(JSON.parse(cached)) + setLoading(false) + return + } + } catch (e) {} + + fetch('https://api.github.com/users/' + username) + .then(r => { + if (!r.ok) throw new Error('HTTP ' + r.status) + return r.json() + }) + .then(d => { + // Don't cache error responses like rate limit messages + if (!d.message) { + try { sessionStorage.setItem(cacheKey, JSON.stringify(d)) } catch (e) {} + } + setProfile(d) + setLoading(false) + }) + .catch(() => setLoading(false)) + }, [username]) + + return { profile, loading } +} + +function AuthorTile({ username, active }) { + const { profile, loading } = useGitHubProfile(username) + const tileClass = styles.authorTile + (active ? ' ' + styles.authorTileActive : '') + + if (loading) { + return ( +
+
+
+
+
+
+
+
+ ) + } + + if (!profile || profile.message) { + return ( + +
+
+ {username} + @{username} +
+
+
+ ) + } + + return ( + + {profile.login} +
+ {profile.name || profile.login} + @{profile.login} + {profile.bio + ? {profile.bio} + :
+ } +
+
+ ) +} + +function AuthorsTiles() { + const [active, setActive] = useState(0) + + useEffect(() => { + if (AUTHORS.length <= 1) return + const t = setInterval(() => { + setActive(i => (i + 1) % AUTHORS.length) + }, 4000) + return () => clearInterval(t) + }, []) + + return ( +
+
+ › Authors: +
+
+ {AUTHORS.map((username, i) => ( + + ))} +
+
+ ) +} + +export default function TerminalHeader() { + return ( +
+
+
+
+
+ javadoc-index — bash +
+
+

+ {PROJECT_NAME} +

+ +
+ $ + browse-docs + {REPO_NAME} + --all-versions +
+ +
+ › Fetching available documentation builds... +
+
+ › Found project links: +
+ +
+ {LINKS.map(function(l) { + return ( + + + {l.tag} + + {l.label} + ↗ + + ) + })} +
+ + + +
+ $ + +
+
+
+ ) +} diff --git a/.github/pages/src/components/TerminalHeader.module.css b/.github/pages/src/components/TerminalHeader.module.css new file mode 100644 index 0000000..84853ab --- /dev/null +++ b/.github/pages/src/components/TerminalHeader.module.css @@ -0,0 +1,303 @@ +.wrap { + margin-bottom: 48px; +} + +.bar { + display: flex; + align-items: center; + gap: 6px; + background: var(--bg3); + border: 1px solid var(--border2); + border-bottom: none; + border-radius: 8px 8px 0 0; + padding: 10px 16px; +} + +.dot { + width: 12px; + height: 12px; + border-radius: 50%; +} +.red { background: #ff5f57; } +.amber { background: #febc2e; } +.green { background: #28c840; } + +.title { + margin-left: 8px; + font-size: 11px; + color: var(--text-dim); + letter-spacing: 0.05em; +} + +.body { + background: var(--bg2); + border: 1px solid var(--border2); + border-radius: 0 0 8px 8px; + padding: 16px 36px 36px; +} + +/* ── Heading ── */ +.heading { + font-family: 'IBM Plex Sans', sans-serif; + font-size: clamp(28px, 5vw, 52px); + font-weight: 300; + letter-spacing: -0.02em; + color: var(--text); + line-height: 1.05; + margin-bottom: 20px; +} + +.heading strong { + font-weight: 600; + color: var(--green); +} + +/* ── Prompt ── */ +.promptLine { + display: flex; + align-items: baseline; + gap: 10px; + margin-bottom: 6px; + font-size: 13px; + flex-wrap: wrap; +} + +.prompt { color: var(--green); font-weight: 600; } +.cmd { color: var(--text); } +.arg { color: var(--blue); } +.flag { color: var(--amber); } + +/* ── Output lines ── */ +.outputLine { + font-size: 12px; + color: var(--text-dim); + line-height: 1.8; + padding-left: 20px; +} + +.chevron { + color: var(--text-mid); + margin-right: 4px; +} + +/* ── Links ── */ +.links { + display: flex; + flex-direction: column; + gap: 4px; + padding-left: 36px; + margin-top: 4px; + margin-bottom: 12px; +} + +.link { + display: inline-flex; + align-items: center; + gap: 10px; + text-decoration: none; + padding: 3px 0; + width: fit-content; + transition: opacity 0.15s; +} + +.link:hover { opacity: 0.8; } + +.link:hover .linkLabel { + text-decoration: underline; + text-underline-offset: 3px; +} + +.linkTag { + font-size: 9px; + font-weight: 600; + letter-spacing: 0.1em; + border: 1px solid; + border-radius: 2px; + padding: 1px 5px; + min-width: 28px; + text-align: center; + opacity: 0.9; + font-family: 'IBM Plex Mono', monospace; +} + +.linkLabel { + font-size: 12px; + color: var(--text-mid); + font-family: 'IBM Plex Mono', monospace; +} + +.linkArrow { + font-size: 11px; + opacity: 0.6; + transition: opacity 0.15s, transform 0.15s; +} + +.link:hover .linkArrow { + opacity: 1; + transform: translate(2px, -2px); +} + +/* ── Authors ── */ +.authors { + margin-bottom: 8px; +} + +.authorRow { + display: flex; + flex-direction: row; + gap: 8px; + padding-left: 36px; + margin-top: 6px; + flex-wrap: wrap; +} + +/* ── Author tile ── */ +.authorTile { + display: flex; + align-items: center; + gap: 10px; + background: var(--bg3); + border: 1px solid var(--border); + border-radius: 6px; + padding: 8px 12px; + text-decoration: none; + cursor: pointer; + /* width is dynamic — grows with content */ + width: max-content; + min-width: 140px; + position: relative; + overflow: hidden; + transition: border-color 0.2s, background 0.2s, transform 0.2s; +} + +.authorTile::before { + content: ''; + position: absolute; + top: 0; left: 0; right: 0; + height: 2px; + background: var(--green); + opacity: 0; + transition: opacity 0.2s; +} + +.authorTileActive::before, +.authorTile:hover::before { + opacity: 1; +} + +.authorTileActive { + border-color: var(--green-dim); + background: rgba(57, 211, 83, 0.04); +} + +.authorTile:hover { + border-color: var(--border2); + background: #161b22; + transform: translateY(-1px); +} + +/* ── Author content ── */ +.authorAvatar { + width: 32px; + height: 32px; + border-radius: 50%; + border: 1px solid var(--border2); + flex-shrink: 0; +} + +.authorAvatarSkeleton { + width: 32px; + height: 32px; + border-radius: 50%; + background: var(--border2); + flex-shrink: 0; + animation: shimmer 1.5s ease infinite; +} + +.authorInfo { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 0; +} + +.authorName { + font-size: 12px; + font-weight: 500; + color: var(--text); + font-family: 'IBM Plex Sans', sans-serif; + white-space: nowrap; +} + +.authorLogin { + font-size: 10px; + color: var(--blue); + font-family: 'IBM Plex Mono', monospace; + white-space: nowrap; +} + +/* Bio — always reserves vertical height, width animates open */ +.authorBio { + display: block; + font-size: 10px; + color: var(--text-dim); + font-family: 'IBM Plex Sans', sans-serif; + margin-top: 2px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + /* always reserve vertical space */ + height: 14px; + /* collapsed horizontally */ + width: 0; + opacity: 0; + transition: opacity 0.25s ease, width 0.3s ease; +} + +.authorTileActive .authorBio, +.authorTile:hover .authorBio { + width: 200px; + opacity: 1; +} + +/* Placeholder for loading/no-profile/no-bio states */ +.authorBioPlaceholder { + height: 14px; + margin-top: 2px; + width: 0; /* never takes horizontal space, never expands */ +} + +.authorSkeleton { + height: 9px; + border-radius: 4px; + background: var(--border2); + animation: shimmer 1.5s ease infinite; +} + +/* ── Cursor ── */ +.cursor { + display: inline-block; + width: 8px; + height: 13px; + background: var(--green); + margin-left: 2px; + vertical-align: text-bottom; + animation: blink 1s step-end infinite; +} + +/* ── Animations ── */ +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + +@keyframes shimmer { + 0%, 100% { opacity: 0.4; } + 50% { opacity: 0.8; } +} + +@media (max-width: 600px) { + .body { padding: 20px; } + .links { padding-left: 20px; } + .authorRow { padding-left: 20px; } +} diff --git a/.github/pages/src/config.js b/.github/pages/src/config.js new file mode 100644 index 0000000..41525f3 --- /dev/null +++ b/.github/pages/src/config.js @@ -0,0 +1,38 @@ +// ─── Project Configuration ─────────────────────────────────── +// This is the ONLY file that should differ between projects. +// Everything else in the pages app is generic. +// ───────────────────────────────────────────────────────────── + +export const PROJECT_NAME = 'CustomNPC+ Gecko Addon' +export const REPO_OWNER = 'KAMKEEL' +export const REPO_NAME = 'CustomNPC-Gecko-Addon' + +export const LINKS = [ + { + tag: 'GH', + label: 'github.com/KAMKEEL/CustomNPC-Gecko-Addon', + href: 'https://github.com/KAMKEEL/CustomNPC-Gecko-Addon', + color: '#e6edf3', + }, + { + tag: 'DC', + label: 'discord.gg/94qmjEDxkp', + href: 'https://discord.gg/94qmjEDxkp', + color: '#5865f2', + }, + { + tag: 'MR', + label: 'modrinth.com/mod/customnpc-plus-gecko-addon', + href: 'https://modrinth.com/mod/customnpc-plus-gecko-addon', + color: '#1bd96a', + }, + { + tag: 'CF', + label: 'curseforge.com/minecraft/mc-mods/cnpc-custom-model-addon', + href: 'https://www.curseforge.com/minecraft/mc-mods/cnpc-custom-model-addon', + color: '#f16436', + }, +] + +// GitHub usernames — profiles are fetched at runtime +export const AUTHORS = ['goodbird-git', 'kamkeel'] diff --git a/.github/pages/src/index.css b/.github/pages/src/index.css new file mode 100644 index 0000000..fef4fe1 --- /dev/null +++ b/.github/pages/src/index.css @@ -0,0 +1,50 @@ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +:root { + --bg: #080b0f; + --bg2: #0d1117; + --bg3: #131920; + --border: #1e2936; + --border2: #253040; + --green: #39d353; + --green-dim: #1a6b2a; + --amber: #f0a030; + --amber-dim: #7a4e10; + --blue: #58a6ff; + --blue-dim: #1a3a6b; + --text: #cdd9e5; + --text-dim: #636e7b; + --text-mid: #8b949e; + --red: #f85149; +} + +html, body { + height: 100%; + background: var(--bg); + color: var(--text); + font-family: 'IBM Plex Mono', monospace; + overflow-x: hidden; +} + +/* Scanlines */ +body::after { + content: ''; + position: fixed; + inset: 0; + background: repeating-linear-gradient( + 0deg, + transparent, + transparent 2px, + rgba(0,0,0,0.025) 2px, + rgba(0,0,0,0.025) 4px + ); + pointer-events: none; + z-index: 9999; +} + +a { color: inherit; text-decoration: none; } + +::-webkit-scrollbar { width: 6px; } +::-webkit-scrollbar-track { background: var(--bg2); } +::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 3px; } +::-webkit-scrollbar-thumb:hover { background: var(--text-dim); } diff --git a/.github/pages/src/main.jsx b/.github/pages/src/main.jsx new file mode 100644 index 0000000..22bbe14 --- /dev/null +++ b/.github/pages/src/main.jsx @@ -0,0 +1,13 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App' +import { PROJECT_NAME } from './config' +import './index.css' + +document.title = `${PROJECT_NAME} — Javadoc Index` + +ReactDOM.createRoot(document.getElementById('root')).render( + + + +) diff --git a/.github/pages/src/useDocs.js b/.github/pages/src/useDocs.js new file mode 100644 index 0000000..1c8c5b8 --- /dev/null +++ b/.github/pages/src/useDocs.js @@ -0,0 +1,94 @@ +import { useState, useEffect } from 'react' +import { REPO_OWNER, REPO_NAME } from './config' + +const BASE_PATH = `/${REPO_NAME}` +const API_BASE = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}` + +// Cache bust on every page load — appends current timestamp to manifest URL +// so the browser never serves a stale manifest.json +async function fetchFromManifest() { + const bust = `?t=${Date.now()}` + const res = await fetch(`${BASE_PATH}/manifest.json${bust}`, { + cache: 'no-store', // tells browser not to cache this request at all + }) + if (!res.ok) throw new Error('No manifest') + return res.json() +} + +async function fetchFromGitHubAPI() { + const refRes = await fetch(`${API_BASE}/git/ref/heads/gh-pages`) + if (!refRes.ok) throw new Error('gh-pages branch not found') + const refData = await refRes.json() + const sha = refData.object.sha + + const treeRes = await fetch(`${API_BASE}/git/trees/${sha}?recursive=1`) + if (!treeRes.ok) throw new Error('Could not fetch tree') + const treeData = await treeRes.json() + + const commitsRes = await fetch(`${API_BASE}/commits?sha=gh-pages&per_page=100`) + const commits = commitsRes.ok ? await commitsRes.json() : [] + + const commitMap = {} + commits.forEach(c => { + const date = c.commit?.committer?.date || c.commit?.author?.date || '' + const hash = c.sha?.slice(0, 7) || '' + const msg = c.commit?.message || '' + const vMatch = msg.match(/releases\/([\d.]+)/) + if (vMatch) commitMap[`releases/${vMatch[1]}`] = { date, hash } + const eMatch = msg.match(/experimental\/([\w-]+)/) + if (eMatch) commitMap[`experimental/${eMatch[1]}`] = { date, hash } + }) + + const releaseDirs = new Set() + const experimentalDirs = new Set() + + treeData.tree.forEach(item => { + if (item.type !== 'tree') return + const parts = item.path.split('/') + if (parts[0] === 'releases' && parts.length === 2) releaseDirs.add(parts[1]) + if (parts[0] === 'experimental' && parts.length === 2) experimentalDirs.add(parts[1]) + }) + + // Sort releases newest first, mark first as latest + const sortedReleases = [...releaseDirs] + .sort((a, b) => b.localeCompare(a, undefined, { numeric: true })) + + const releases = sortedReleases.map((v, i) => { + const c = commitMap[`releases/${v}`] || {} + return { + id: v, + version: v, + path: `releases/${v}`, + date: c.date, + hash: c.hash, + isLatest: i === 0, // newest version is always latest + } + }) + + const experimental = [...experimentalDirs].sort().map(b => { + const c = commitMap[`experimental/${b}`] || {} + return { id: b, branch: b, path: `experimental/${b}`, date: c.date, hash: c.hash } + }) + + return { releases, experimental, source: 'api' } +} + +export function useDocs() { + const [data, setData] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + + useEffect(() => { + fetchFromManifest() + .then(d => { setData(d); setLoading(false) }) + .catch(() => + fetchFromGitHubAPI() + .then(d => { setData(d); setLoading(false) }) + .catch(e => { setError(e.message); setLoading(false) }) + ) + }, []) + + return { data, loading, error } +} + +export { BASE_PATH, REPO_OWNER, REPO_NAME } diff --git a/.github/pages/vite.config.js b/.github/pages/vite.config.js new file mode 100644 index 0000000..1b00c45 --- /dev/null +++ b/.github/pages/vite.config.js @@ -0,0 +1,12 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { REPO_NAME } from './src/config.js' + +export default defineConfig({ + plugins: [react()], + base: `/${REPO_NAME}/`, + build: { + outDir: '../../.github/pages-dist', + emptyOutDir: true, + } +}) diff --git a/.github/scripts/doc-config.sh b/.github/scripts/doc-config.sh new file mode 100644 index 0000000..8289bbe --- /dev/null +++ b/.github/scripts/doc-config.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# ----------------------------------------------- +# doc-config.sh — shared config for javadoc deploy +# +# Sourced by: +# - resolve-doc-path.sh +# - javadoc.yml (via sanity-check job) +# +# ADD WHITELISTED BRANCHES HERE AND NOWHERE ELSE. +# main is always handled automatically. +# ----------------------------------------------- + +MAIN_BRANCH_NAME="main" + +EXPERIMENTAL_WHITELIST=( + "dev" + # "new-branch" +) diff --git a/.github/scripts/generate-index.sh b/.github/scripts/generate-index.sh new file mode 100644 index 0000000..7651a80 --- /dev/null +++ b/.github/scripts/generate-index.sh @@ -0,0 +1,107 @@ +#!/bin/bash +set -e + +RELEASES=() +EXPERIMENTAL=() + +# Collect releases +if [ -d "./releases" ]; then + for dir in ./releases/*/; do + [ -d "$dir" ] || continue + name=$(basename "$dir") + RELEASES+=("$name") + done +fi + +# Collect experimental branches +if [ -d "./experimental" ]; then + for dir in ./experimental/*/; do + [ -d "$dir" ] || continue + name=$(basename "$dir") + EXPERIMENTAL+=("$name") + done +fi + +# Sort releases in reverse semver order (newest first) +if [ ${#RELEASES[@]} -gt 0 ]; then + IFS=$'\n' RELEASES=($(sort -rV <<< "${RELEASES[*]}")); unset IFS +fi + +# ── Store source commit metadata for this deploy ─────────────── +# DEPLOY_PATH, SOURCE_HASH, SOURCE_DATE are passed in as env vars from the workflow +if [ -n "$DEPLOY_PATH" ] && [ -n "$SOURCE_HASH" ]; then + mkdir -p ".doc-meta" + META_KEY="${DEPLOY_PATH//\//_}" + cat > ".doc-meta/${META_KEY}.json" << JSON +{"hash":"${SOURCE_HASH}","date":"${SOURCE_DATE}"} +JSON + echo "Stored source metadata for $DEPLOY_PATH → $SOURCE_HASH @ $SOURCE_DATE" +fi + +# ── Helper: get source commit hash + date for a path ────────── +get_commit_info() { + local path="$1" + + # If this is the path we just deployed, use the injected source commit + if [ "$path" = "$DEPLOY_PATH" ] && [ -n "$SOURCE_HASH" ]; then + echo "${SOURCE_HASH} ${SOURCE_DATE}" + return + fi + + # Try reading from stored metadata file (set by previous deploys) + local meta=".doc-meta/${path//\//_}.json" + if [ -f "$meta" ]; then + local hash date + hash=$(python3 -c "import json,sys; d=json.load(open('$meta')); print(d.get('hash',''))" 2>/dev/null || grep -o '"hash":"[^"]*"' "$meta" | cut -d'"' -f4) + date=$(python3 -c "import json,sys; d=json.load(open('$meta')); print(d.get('date',''))" 2>/dev/null || grep -o '"date":"[^"]*"' "$meta" | cut -d'"' -f4) + echo "${hash:-} ${date:-}" + return + fi + + # Last resort: gh-pages git log (hash will be wrong but better than empty) + local hash date + hash=$(git log --oneline -1 -- "$path" 2>/dev/null | awk '{print $1}') + date=$(git log --format="%cI" -1 -- "$path" 2>/dev/null) + echo "${hash:-} ${date:-}" +} + +# ── Build releases JSON ──────────────────────────────────────── +RELEASES_JSON="[" + +for i in "${!RELEASES[@]}"; do + version="${RELEASES[$i]}" + read -r HASH DATE <<< "$(get_commit_info "releases/$version")" + if [ "$i" -eq 0 ]; then + IS_LATEST="true" + else + IS_LATEST="false" + fi + RELEASES_JSON+="{\"id\":\"${version}\",\"version\":\"${version}\",\"path\":\"releases/${version}\",\"date\":\"${DATE}\",\"isLatest\":${IS_LATEST}}," +done + +RELEASES_JSON="${RELEASES_JSON%,}]" + +# ── Build experimental JSON ──────────────────────────────────── +EXPERIMENTAL_JSON="[" + +for branch in "${EXPERIMENTAL[@]}"; do + read -r HASH DATE <<< "$(get_commit_info "experimental/$branch")" + EXPERIMENTAL_JSON+="{\"id\":\"${branch}\",\"branch\":\"${branch}\",\"path\":\"experimental/${branch}\",\"hash\":\"${HASH}\",\"date\":\"${DATE}\"}," +done + +EXPERIMENTAL_JSON="${EXPERIMENTAL_JSON%,}]" + +# ── Write manifest.json ──────────────────────────────────────── +cat > manifest.json << JSON +{ + "releases": ${RELEASES_JSON}, + "experimental": ${EXPERIMENTAL_JSON}, + "generated": "$(date -u '+%Y-%m-%dT%H:%M:%SZ')", + "source": "manifest" +} +JSON + +echo "manifest.json generated:" +cat manifest.json +echo "" +echo "Done." diff --git a/.github/scripts/resolve-doc-path.sh b/.github/scripts/resolve-doc-path.sh new file mode 100644 index 0000000..92ad7ac --- /dev/null +++ b/.github/scripts/resolve-doc-path.sh @@ -0,0 +1,52 @@ +#!/bin/bash +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/doc-config.sh" + +BRANCH="${GITHUB_REF#refs/heads/}" +SAFE_BRANCH="${BRANCH//\//-}" + +if [ "$BRANCH" = "$MAIN_BRANCH_NAME" ]; then + # Version resolution order: + # -> check if gradle.properties has a `modVersion` tag. If it does, just grab it. + # -> check if it has the `version` tag. Grab it if it does + # -> check build.gradle for the version tag. + if [ -f "gradle.properties" ] && grep -q "^modVersion=" gradle.properties; then + VERSION=$(grep "^modVersion=" gradle.properties | cut -d'=' -f2 | tr -d '[:space:]') + elif [ -f "gradle.properties" ] && grep -q "^version=" gradle.properties; then + VERSION=$(grep "^version=" gradle.properties | cut -d'=' -f2 | tr -d '[:space:]') + elif [ -f "build.gradle" ]; then + VERSION=$(grep "^version" build.gradle | head -1 | sed "s/version\s*=\s*['\"]//;s/['\"].*//;s/\s//g") + elif [ -f "build.gradle.kts" ]; then + VERSION=$(grep "^version" build.gradle.kts | head -1 | sed "s/version\s*=\s*\"//;s/\".*//;s/\s//g") + else + echo "Could not find version. Defaulting to 'unknown'." + VERSION="unknown" + fi + + echo "Resolved version: $VERSION" + + # Only deploy to releases/ — isLatest is handled by generate-index.sh + echo "path=releases/$VERSION" >> $GITHUB_OUTPUT + echo "extra_path=" >> $GITHUB_OUTPUT + +else + MATCHED=false + for ALLOWED in "${EXPERIMENTAL_WHITELIST[@]}"; do + if [ "$BRANCH" = "$ALLOWED" ]; then + MATCHED=true + break + fi + done + + if [ "$MATCHED" = true ]; then + echo "path=experimental/$SAFE_BRANCH" >> $GITHUB_OUTPUT + echo "extra_path=" >> $GITHUB_OUTPUT + echo "Branch '$BRANCH' is whitelisted, deploying to experimental/$SAFE_BRANCH" + else + echo "path=" >> $GITHUB_OUTPUT + echo "extra_path=" >> $GITHUB_OUTPUT + echo "Branch '$BRANCH' is not whitelisted. Skipping deploy." + fi +fi diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 3ee2f68..a5e8bb4 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,4 +1,3 @@ - name: Build and test on: @@ -9,5 +8,140 @@ on: jobs: build-and-test: - uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/build-and-test.yml@master - secrets: inherit + runs-on: ubuntu-24.04 + env: + WORKSPACE_TASK: ${{ vars.WORKSPACE_TASK || 'setupCIWorkspace' }} + RUN_SERVER_TIMEOUT: ${{ vars.RUN_SERVER_TIMEOUT || 90 }} + RUN_SERVER_ENABLED: ${{ vars.RUN_SERVER_ENABLED || 'true' }} + steps: + - name: Install Ubuntu dependencies + run: | + sudo apt-get update -y + sudo apt-get install -y mesa-utils xvfb x11-xserver-utils + + - name: Checkout mod repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Initialize submodules + run: git submodule update --init --recursive + + - name: Checkout workflows repo + uses: actions/checkout@v4 + with: + repository: GTNewHorizons/GTNH-Actions-Workflows + path: .gtnh-workflows + fetch-depth: 0 + + - name: Set up JDK versions + uses: actions/setup-java@v4 + with: + java-version: | + 8 + 17 + 21 + distribution: 'zulu' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + with: + build-scan-publish: true + build-scan-terms-of-use-url: "https://gradle.com/terms-of-service" + build-scan-terms-of-use-agree: "yes" + validate-wrappers: true + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Setup the workspace + run: ./gradlew --build-cache --info --stacktrace "${WORKSPACE_TASK}" + + - name: Compile the mod + run: ./gradlew --build-cache --info --stacktrace assemble + + - name: Attach compilation artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ github.repository_id }}-build-libs + path: build/libs/ + retention-days: 90 + + - name: Run post-build checks + id: build_mod + run: xvfb-run --server-args="-screen 0 1366x768x24" ./gradlew --build-cache --info --stacktrace build + + - name: Attach gradle reports + if: failure() && steps.build_mod.conclusion == 'failure' + uses: actions/upload-artifact@v4 + continue-on-error: true + with: + name: ${{ github.repository_id }}-reports + path: build/reports/ + retention-days: 31 + + - name: Attempt to make a PR fixing spotless errors + if: >- + ${{ failure() && steps.build_mod.conclusion == 'failure' + && github.event_name == 'pull_request' + && !github.event.pull_request.draft + && github.event.pull_request.head.repo.full_name == github.repository }} + run: | + git reset --hard + git checkout "${PR_BRANCH}" + ./gradlew --build-cache --info --stacktrace spotlessApply || exit 1 + git diff --exit-code && exit 1 + git config user.name "GitHub GTNH Actions" + git config user.email "<>" + git switch -c "${FIXED_BRANCH}" + git commit -am "spotlessApply" + git push --force-with-lease origin "${FIXED_BRANCH}" + gh pr create \ + --head "${FIXED_BRANCH}" \ + --base "${PR_BRANCH}" \ + --title "Spotless apply for branch ${PR_BRANCH} for #${{ github.event.pull_request.number }}" \ + --body "Automatic spotless apply to fix formatting errors, applies to PR #${{ github.event.pull_request.number }}" \ + 2>&1 | tee pr-message.log || true + gh pr comment "${PR_BRANCH}" -F pr-message.log || true + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_BRANCH: ${{ github.head_ref }} + FIXED_BRANCH: ${{ github.head_ref }}-spotless-fixes + + - name: Run server for up to ${{ env.RUN_SERVER_TIMEOUT }} seconds + if: ${{ env.RUN_SERVER_ENABLED == 'true' }} + run: | + mkdir -p run + echo "eula=true" > run/eula.txt + echo "level-seed=-6202107849386030209\nonline-mode=true\n" > run/server.properties + echo "stop" > run/stop.txt + timeout "${RUN_SERVER_TIMEOUT}" ./gradlew --build-cache --info --stacktrace runServer 2>&1 < run/stop.txt | tee -a server.log || true + + - name: Test no errors reported during server run + if: ${{ env.RUN_SERVER_ENABLED == 'true' }} + run: | + chmod +x .gtnh-workflows/scripts/test_no_error_reports + .gtnh-workflows/scripts/test_no_error_reports + + - name: Test no prerelease dependencies used + run: | + ! grep -P -- "-pre(?!shadow)" dependencies.gradle* + + - name: Make sure asset files are not overoptimized + if: github.event_name == 'pull_request' + run: | + echo "Checking for grayscale asset files which are not supported by the java8 image loader" + fail=0 + set -o pipefail + while IFS= read -r -d $'\n' file; do + if $(file --brief -- "$file" | grep -q grayscale); then + printf "found grayscale image '%s'\n" "$file" + fail=1 + fi + done < <(gh pr diff --name-only "${PR_NUMBER}" | grep 'src/main/resources/.*\.png$') + + exit $fail + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.number }} diff --git a/.github/workflows/buildscript-maintenance.yml b/.github/workflows/buildscript-maintenance.yml deleted file mode 100644 index a9d5486..0000000 --- a/.github/workflows/buildscript-maintenance.yml +++ /dev/null @@ -1,39 +0,0 @@ -# This workflow only meant for the source mod you shouldn't bring it into your own project - -name: Buildscript maintenance - -on: - push: - branches: [ master, main ] - paths: - - build.gradle - workflow_dispatch: { } - -jobs: - buildscript-maintenance: - runs-on: ubuntu-latest - # Avoid running this workflow on forks - if: github.repository == 'GTNewHorizons/ExampleMod1.7.10' - permissions: - contents: write - pull-requests: write - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Ensure build script version is up to date - id: update-buildscript - run: | - new_version="$(date +%s)" - sed --in-place "1s!^//version:.*!//version: $new_version!g" build.gradle - echo "::set-output name=new_version::$new_version" - - - name: Create Pull Request - id: create-pull-request - uses: peter-evans/create-pull-request@v4 - with: - add-paths: build.gradle - commit-message: '[ci skip] update build script version to ${{ steps.update-buildscript.outputs.new_version }}' - branch: buildscript-maintenance - title: Update build script version to ${{ steps.update-buildscript.outputs.new_version }} - body: This pull request is created by the buildscript-maintenance workflow diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml new file mode 100644 index 0000000..f0f767f --- /dev/null +++ b/.github/workflows/javadoc.yml @@ -0,0 +1,260 @@ +name: Generate and Deploy Javadoc + +on: + push: + branches: + - main + - '**' + delete: + workflow_dispatch: + inputs: + force_deploy: + description: 'Force redeploy Javadocs without a new commit' + required: false + default: 'true' + +jobs: + sanity-check: + runs-on: ubuntu-latest + outputs: + should_deploy: ${{ steps.deploy_check.outputs.should_deploy }} + steps: + - uses: actions/checkout@v4 + - name: Check for deploy tag + id: deploy_check + run: | + source .github/scripts/doc-config.sh + + BRANCH="${GITHUB_REF#refs/heads/}" + + # Always deploy on manual trigger + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "should_deploy=true" >> $GITHUB_OUTPUT + echo "Reason: workflow_dispatch" + exit 0 + fi + + # Main branch: only deploy if commit message contains [deploy-docs] + if [ "$BRANCH" = "$MAIN_BRANCH_NAME" ]; then + if echo "${{ github.event.head_commit.message }}" | grep -q "\[deploy-docs\]"; then + echo "should_deploy=true" >> $GITHUB_OUTPUT + echo "Reason: main branch with [deploy-docs] tag" + else + echo "should_deploy=false" >> $GITHUB_OUTPUT + echo "Reason: main branch without [deploy-docs] tag, skipping" + fi + exit 0 + fi + + # Experimental branches: only deploy if whitelisted + for ALLOWED in "${EXPERIMENTAL_WHITELIST[@]}"; do + if [ "$BRANCH" = "$ALLOWED" ]; then + echo "should_deploy=true" >> $GITHUB_OUTPUT + echo "Reason: branch '$BRANCH' is whitelisted" + exit 0 + fi + done + + echo "should_deploy=false" >> $GITHUB_OUTPUT + echo "Reason: branch '$BRANCH' is not whitelisted, skipping" + + build-and-deploy-javadoc: + needs: sanity-check + if: needs.sanity-check.outputs.should_deploy == 'true' + runs-on: ubuntu-latest + + steps: + - name: Checkout source branch + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Setup JDK 8 (compile) + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'temurin' + + - name: Setup JDK 11 (javadoc) + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Extract convention plugin version + id: convention + run: | + VERSION=$(grep "id 'com.gtnewhorizons.gtnhsettingsconvention'" settings.gradle settings.gradle.kts 2>/dev/null | grep -o "version '[0-9]\+\.[0-9]\+\.[0-9]\+'" | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Detected convention version: $VERSION" + + - name: Get source commit info + id: source_commit + run: | + echo "hash=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + echo "date=$(git log -1 --format='%cI')" >> $GITHUB_OUTPUT + + - name: Cache Gradle wrapper + uses: actions/cache@v4 + with: + path: ~/.gradle/wrapper + key: gradle-wrapper-${{ hashFiles('**/gradle-wrapper.properties') }} + + - name: Cache Gradle dependencies + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/caches/modules-* + ~/.gradle/caches/jars-* + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Cache RFG + uses: actions/cache@v4 + with: + path: | + build/rfg + build/tmp/.cache/expanded + build/tmp/deobfuscateMergedJarToSrg + key: ${{ runner.os }}-rfg-convention${{ steps.convention.outputs.version }} + restore-keys: | + ${{ runner.os }}-rfg- + + - name: Cache Node modules + uses: actions/cache@v4 + with: + path: .github/pages/node_modules + key: ${{ runner.os }}-node-${{ hashFiles('.github/pages/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Resolve CNPC+ Javadoc URL + id: cnpc_docs + run: | + BRANCH="${GITHUB_REF#refs/heads/}" + CNPC_BASE="https://kamkeel.github.io/CustomNPC-Plus" + + if [ "$BRANCH" = "main" ]; then + # Main branch links to CNPC+ master (releases/) + cd CustomNPC-Plus + if [ -f "gradle.properties" ] && grep -q "^modVersion=" gradle.properties; then + CNPC_VER=$(grep "^modVersion=" gradle.properties | cut -d'=' -f2 | tr -d '[:space:]') + elif [ -f "gradle.properties" ] && grep -q "^version=" gradle.properties; then + CNPC_VER=$(grep "^version=" gradle.properties | cut -d'=' -f2 | tr -d '[:space:]') + elif [ -f "build.gradle" ]; then + CNPC_VER=$(grep "^version" build.gradle | head -1 | sed "s/version\s*=\s*['\"]//;s/['\"].*//;s/\s//g") + else + CNPC_VER="unknown" + fi + cd .. + CNPC_DOC_URL="${CNPC_BASE}/releases/${CNPC_VER}" + echo "Linking Gecko main -> CNPC+ releases/${CNPC_VER}" + else + # Dev / experimental branches link to CNPC+ experimental/ + SAFE_BRANCH="${BRANCH//\//-}" + CNPC_DOC_URL="${CNPC_BASE}/experimental/${SAFE_BRANCH}" + echo "Linking Gecko ${BRANCH} -> CNPC+ experimental/${SAFE_BRANCH}" + fi + + # Download the element-list so javadoc can resolve cross-references + mkdir -p build/cnpc-element-list + if curl -fsSL "${CNPC_DOC_URL}/element-list" -o build/cnpc-element-list/element-list; then + echo "Downloaded element-list from ${CNPC_DOC_URL}" + elif curl -fsSL "${CNPC_DOC_URL}/package-list" -o build/cnpc-element-list/element-list; then + echo "Downloaded package-list (JDK 8 format) from ${CNPC_DOC_URL}" + else + echo "::warning::Could not download element-list from ${CNPC_DOC_URL}. Cross-links to CNPC+ will not work." + fi + + echo "url=${CNPC_DOC_URL}" >> $GITHUB_OUTPUT + + - name: Generate Javadoc + run: | + ./gradlew javadoc \ + -PcnpcDocUrl=${{ steps.cnpc_docs.outputs.url }} \ + -PcnpcDocElementList=build/cnpc-element-list + + - name: Get deploy path + id: deploy_path + run: bash .github/scripts/resolve-doc-path.sh + + - name: Deploy to gh-pages + if: steps.deploy_path.outputs.path != '' + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build/docs/javadoc + destination_dir: ${{ steps.deploy_path.outputs.path }} + keep_files: true + + # Give GitHub a moment to settle after the peaceiris push + - name: Wait for gh-pages to settle + run: sleep 10 + + - name: Checkout gh-pages + uses: actions/checkout@v4 + with: + ref: gh-pages + path: gh-pages-index + + - name: Generate manifest + run: | + cd gh-pages-index + SOURCE_HASH="${{ steps.source_commit.outputs.hash }}" \ + SOURCE_DATE="${{ steps.source_commit.outputs.date }}" \ + DEPLOY_PATH="${{ steps.deploy_path.outputs.path }}" \ + bash ../.github/scripts/generate-index.sh + + - name: Install page dependencies + run: npm ci --prefix .github/pages + + - name: Build index page + run: | + mkdir -p .github/pages/public + cp gh-pages-index/manifest.json .github/pages/public/manifest.json + npm run build --prefix .github/pages + + - name: Deploy index to gh-pages + run: | + cp -r .github/pages-dist/* gh-pages-index/ + cd gh-pages-index + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git add -A + git commit -m "Regenerate index and manifest [skip ci]" || echo "Unchanged" + git push + + cleanup-on-delete: + if: github.event_name == 'delete' && github.event.ref_type == 'branch' + runs-on: ubuntu-latest + + steps: + - name: Checkout gh-pages + uses: actions/checkout@v4 + with: + ref: 'gh-pages' + + - name: Remove deleted branch docs + run: | + BRANCH="${{ github.event.ref }}" + SAFE="experimental/${BRANCH//\//-}" + if [ -d "./$SAFE" ]; then + rm -rf "./$SAFE" + META_KEY="${SAFE//\//_}" + rm -f ".doc-meta/${META_KEY}.json" + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git add -A + git commit -m "Remove docs for deleted branch: $BRANCH" + git push + else + echo "No docs found for $SAFE, skipping." + fi diff --git a/.gitignore b/.gitignore index c14be0d..da701c6 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,7 @@ layout.json # Generated D.TS files (rebuilt by gradle on every build) src/main/resources/assets/npcgecko/api + +# GitHub Pages build output +.github/pages-dist/ +.github/pages/node_modules/ diff --git a/build.gradle b/build.gradle index dcec51b..c682bd9 100644 --- a/build.gradle +++ b/build.gradle @@ -29,3 +29,32 @@ tasks.named("generateTypeScriptDefinitions").configure { } processResources.dependsOn generateTypeScriptDefinitions sourcesJar.dependsOn generateTypeScriptDefinitions + +// ============================================================================ +// Javadoc Generation (for GitHub Pages deployment) +// ============================================================================ +javadoc { + options.encoding = 'UTF-8' + options.charSet = 'UTF-8' + options.docEncoding = 'UTF-8' + + options.stylesheetFile = file('.github/javadoc/javadoc-theme.css') + options.header = file('.github/javadoc/javadoc-header.html').text + options.footer = file('.github/javadoc/javadoc-footer.html').text + + options.addBooleanOption('-allow-script-in-comments', true) + + // Only document public API + include 'com/goodbird/npcgecko/api/**' + + options.links('https://docs.oracle.com/en/java/javase/11/docs/api/') + + // Cross-link to CNPC+ javadoc (URL injected by CI workflow) + if (project.hasProperty('cnpcDocUrl') && project.hasProperty('cnpcDocElementList')) { + options.linksOffline(project.property('cnpcDocUrl'), project.property('cnpcDocElementList')) + } + + javadocTool = javaToolchains.javadocToolFor { + languageVersion = JavaLanguageVersion.of(11) + } +} diff --git a/gradle.properties b/gradle.properties index 9d0a507..6e726ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ modName = CustomNPC-Plus-Gecko-Addon # This is a case-sensitive string to identify your mod. Convention is to use lower case. modId = npcgecko modGroup = com.goodbird.npcgecko -modVersion = 1.3 +modVersion = 1.4 gtnh.modules.codeStyle=true gtnh.modules.gitVersion=false diff --git a/src/main/java/com/goodbird/npcgecko/CustomNpcPlusGecko.java b/src/main/java/com/goodbird/npcgecko/CustomNpcPlusGecko.java index cd04e5e..11f4525 100644 --- a/src/main/java/com/goodbird/npcgecko/CustomNpcPlusGecko.java +++ b/src/main/java/com/goodbird/npcgecko/CustomNpcPlusGecko.java @@ -4,10 +4,11 @@ import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import noppes.npcs.controllers.APIRegistry; @Mod(modid = "npcgecko", name = "CustomNPC+ Gecko Addon", - version = "1.3", + version = "1.4", dependencies = "required-after:customnpcs;required-after:geckolib3") public class CustomNpcPlusGecko { @@ -25,5 +26,6 @@ public class CustomNpcPlusGecko { @Mod.EventHandler public void init(FMLInitializationEvent ev) { proxy.init(ev); + APIRegistry.Instance.register("Gecko Addon API", "https://kamkeel.github.io/CustomNPC-Gecko-Addon/"); } }