-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
466 lines (425 loc) · 25.1 KB
/
script.js
File metadata and controls
466 lines (425 loc) · 25.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
const STORAGE_KEY = "ultesoft-language";
const endpoints = {
org: "https://api.github.com/orgs/UlteSoft",
repo: "https://api.github.com/repos/UlteSoft/uwvm2",
};
const translations = {
zh: {
metaTitle: "UlteSoft | 面向未来去中心化、边缘计算",
metaDescription:
"认识 UlteSoft 与 uwvm2:一个面向未来去中心化、边缘计算,并围绕 WebAssembly、WASI 与跨平台执行而构建的开源组织及其旗舰虚拟机。",
"brand.tagline": "面向 Wasm 前沿的开源系统软件",
"nav.ultesoft": "UlteSoft",
"nav.uwvm2": "uwvm2",
"nav.ecosystem": "生态",
"hero.eyebrow": "为 Wasm 前沿而生",
"hero.title":
'把大胆的 <span class="hero-emphasis">WebAssembly</span> 想法,做成真正能运行、能扩展、能被记住的系统软件。',
"hero.text":
"UlteSoft 正在以 WebAssembly 为底座,把运行时、WASI、跨平台执行与实验性扩展连接成一套面向未来去中心化与边缘计算的技术版图,而位于这张版图中心的,正是 <code>uwvm2</code>。",
"hero.primaryCta": "探索 UlteSoft",
"hero.secondaryCta": "进入 uwvm2",
"panel.liveLabel": "实时热度",
"metric.publicRepos": "公开仓库",
"metric.followers": "组织关注者",
"metric.stars": "uwvm2 Stars",
"metric.forks": "uwvm2 Forks",
"panel.snapshotLabel": "关键快照",
"facts.created": "组织创建时间",
"facts.language": "仓库主语言",
"facts.updated": "最近推送",
"org.eyebrow": "Why UlteSoft Matters",
"org.title": "UlteSoft,不只是一个普通的 GitHub 组织",
"org.body1":
"UlteSoft 是一个很新的开源组织,但方向异常清晰:<strong>WebAssembly 虚拟机</strong>、<strong>WASI 宿主能力</strong>、<strong>跨平台执行</strong>、<strong>扩展提案探索</strong>。这种聚焦,在技术型组织里本身就很有吸引力。",
"org.body2":
"从 <code>uwvm</code> 到 <code>uwvm2</code>,再到 GPU/JIT 相关扩展与 wrapper demo,这些仓库不像零散实验,更像一张正在逐渐铺开的路线图。你看到的不是一个点,而是一条生态链的起点。",
"org.card1title": "一个很强的技术信号",
"org.card1body": "这是偏系统软件的组织气质:底层、硬核、愿意处理复杂平台和困难目标。",
"org.card2title": "它为什么值得看",
"org.card2body": "仓库范围从虚拟机核心延伸到扩展能力和集成示例,说明 UlteSoft 在思考的是体系,不只是单个项目。",
"org.card3title": "为什么现在就值得关注",
"org.card3body": "因为旗舰项目已经公开、开发者稳定、并且仍在快速演进。现在入场,正好能看清它的成长曲线。",
"project.eyebrow": "The Flagship",
"project.title": "uwvm2,把愿景真正落成代码",
"project.badge": "开发者稳定版",
"project.tagline": "UlteSoft WebAssembly 版图里的旗舰运行时项目。",
"project.body1":
"根据公开 README 与开发文档,<code>uwvm2</code> 不是一次轻量升级,而是对 Ultimate WebAssembly Virtual Machine 的一次<strong>重新架构</strong>。它以 <strong>C++26</strong> 与 Concept-Oriented Programming 思路为基础,强调可扩展性、规范导向与内存安全。",
"project.body2":
"更重要的是,README 已经把它的能力版图写得非常完整:WASM 特性扩展、多平台支持、运行时执行后端、高性能标准解析器、WASI 宿主扩展、面向插件的宿主 API,以及灵活的线性内存模型。下面这些能力点,我都按 README 展开列出来了。",
"readme.label": "README 全量特性",
"readme.title": "README 列出的核心能力,一项不落",
"readme.text":
"为了让首页真正把 uwvm2 讲清楚,这里直接按照官方 README 的特性结构,把项目公开强调的能力完整整理出来。",
"readme.item1title": "WASM Feature Extensions",
"readme.item1body":
"README 明确写到大多数 Wasm 标准特性都已纳入支持范围,并提供专门的特性文档与 WebAssembly 版本变更说明。",
"readme.item2title": "Supports multiple platforms",
"readme.item2body":
"项目面向 100+ triplet 平台,覆盖 DOS、POSIX、Windows 9x、Windows NT 与 Host C Library 系列,并规划解释执行、JIT 与分层编译。",
"readme.item3title": "Runtime execution backends",
"readme.item3body":
"uwvm2 包含多种运行时执行后端,既有解释器,也有内存内编译组件;README 还特别点出了 u2 interpreter 的架构设计。",
"readme.item4title": "High-performance standard parser",
"readme.item4body":
"README 将它描述为一个高性能、规范兼容、可扩展且强调安全性的 WebAssembly 二进制解析器,并提到 SIMD-aware 设计与大量 fuzzing。",
"readme.item5title": "WASI host extensions",
"readme.item5body":
"项目提供面向 <code>wasm32-wasip1</code> 与 <code>wasm64-wasip1</code> 的 WASI Preview 1 宿主绑定,把文件系统等能力暴露给 Wasm 模块。",
"readme.item6title": "Plugin-facing host APIs",
"readme.item6body":
"预加载模块无论是动态库还是 weak-symbol 插件,都可以使用稳定的宿主侧线性内存 API,并可选接入 UWVM2 的 WASI Preview 1 host API。",
"readme.item7title": "Flexible linear memory models",
"readme.item7body":
"README 列出三种宿主侧线性内存模型:基于 <code>mmap</code>、基于多线程分配器、以及基于单线程分配器,以适配是否具备虚拟内存的不同平台。",
"cli.label": "Command Line",
"cli.title": "README 还给出了直接可用的命令行入口",
"cli.text":
"这不是只停留在理念层的项目。官方 README 已经给出了最基本也最关键的命令行使用方式,方便快速上手。",
"cli.item1": "<code>uwvm --version</code> 查看版本信息",
"cli.item2": "<code>uwvm --help</code> 查看命令列表",
"cli.item3": "<code>uwvm <params...> --run <wasm> <argv...></code> 运行 Wasm 虚拟机",
"cli.item4":
"<code>uwvm --wasip1-mount-dir <wasi dir> <system dir> ... --run ...</code> 挂载 WASI 目录后执行",
"cli.item5":
"<code>uwvm --wasm-expose-wasip1-host-api --wasm-register-dl <plugin> <module> --run ...</code> 向预加载插件暴露 WASI Preview 1 host API",
"build.label": "Build Targets",
"build.title": "构建入口同样覆盖了主流与特殊平台",
"build.text":
"README 的构建部分不是一句“支持跨平台”带过,而是明确列出了官方构建文档入口,方便按目标平台查阅。",
"build.item1": "Windows / <code>unknown-windows-msvc</code>",
"build.item2": "MinGW / <code>unknown-windows-gnu</code>",
"build.item3": "Linux / <code>unknown-linux-unknown</code>",
"build.item4": "Darwin / <code>unknown-apple-darwin</code>",
"build.item5": "FreeBSD / <code>unknown-freebsd(Version)</code>",
"build.item6": "WASM-WASI 自举构建 / <code>wasm32|wasm64-[wasip1|wasip2]</code>",
"build.item7": "其他平台也提供独立 how-to-build 文档入口",
"feature1.title": "跨平台,不是口头上的",
"feature1.body":
"公开支持矩阵直接指向 100+ triplet 平台,覆盖 POSIX、Windows NT/9x、DOS、WASM-WASI、Emscripten 及部分 freestanding 场景。",
"feature2.title": "按规范推进,而不是拍脑袋",
"feature2.body":
"现有文档已经明确列出 CLI 与 Wasm 1.0 Parser 的完成进度,路线图也继续向模块初始化、校验和执行后端推进。",
"feature3.title": "WASI,意味着真正可用",
"feature3.body":
"WASI Preview 1 是当前的重要方向之一,这决定了 uwvm2 不只是在跑字节码,更是在向真实宿主能力靠近。",
"feature4.title": "为不同执行模型而设计",
"feature4.body":
"从解释执行到 JIT,再到多种线性内存模型,uwvm2 的架构目标明显不是单一场景,而是更完整的 Wasm runtime 版图。",
"ecosystem.eyebrow": "Beyond One Repo",
"ecosystem.title": "不是孤零零的仓库,而是一条正在成形的生态线",
"repo1.body": "原始的 Ultimate WebAssembly Virtual Machine。想理解 uwvm2 为什么值得重构,这里是最好的背景入口。",
"repo2.body": "面向特殊平台的依赖补充仓库,侧面说明 UlteSoft 对老环境和边缘平台也有认真考虑。",
"repo3.body": "把 Wasm 与 GPU IR 连接起来的实验方向,展示出组织对高阶扩展能力的想象力。",
"repo4.body": "围绕 JIT 扩展能力展开讨论,释放出一个信号:UlteSoft 想做的不只是解释器。",
"repo5.body": "通过 ROS 2 wrapper demo,把 uwvm2 从“能运行”推进到“能接入真实生态”。",
"repo6.body": "面向图形与系统集成的示例,说明这套运行时正在尝试进入更复杂、更有展示力的宿主环境。",
"timeline.eyebrow": "Momentum",
"timeline.title": "这不是停在概念里的路线图",
"timeline.item1label": "已经落地",
"timeline.item1body":
"CLI、WebAssembly 1.0 Parser 与模块 section 处理已经出现在公开开发文档的完成项里。",
"timeline.item2label": "正在推进",
"timeline.item2body":
"WASI Preview 1 支持处于进行中,这是把 Wasm 程序带向真实执行环境的关键步骤。",
"timeline.item3label": "下一波重点",
"timeline.item3body":
"模块初始化与校验、高性能解释器、LLVM JIT、分层编译和代码缓存,都已被明确写进后续目标。",
"footer.body":
"本页基于 UlteSoft 与 uwvm2 的公开 GitHub 元数据,以及 uwvm2 仓库中的 README、支持矩阵与开发状态文档整理而成。",
statusLoading: "正在从 GitHub 获取最新公开数据",
statusSuccess: "GitHub 实时数据已更新",
statusFailure: "GitHub 实时数据更新失败,当前显示的是页面内置快照",
},
en: {
metaTitle: "UlteSoft | For The Future Of Decentralization And Edge Computing",
metaDescription:
"Meet UlteSoft and uwvm2: an open-source organization built for the future of decentralization and edge computing, grounded in WebAssembly, WASI, cross-platform execution, and a flagship next-generation virtual machine.",
"brand.tagline": "Open-source systems software for the Wasm frontier",
"nav.ultesoft": "UlteSoft",
"nav.uwvm2": "uwvm2",
"nav.ecosystem": "Ecosystem",
"hero.eyebrow": "Built For The Wasm Frontier",
"hero.title":
'Turning bold <span class="hero-emphasis">WebAssembly</span> ideas into systems software that can run, scale, and stand out.',
"hero.text":
"Built on WebAssembly, UlteSoft is connecting runtime design, WASI, cross-platform execution, and experimental extensions into a technology map for the future of decentralization and edge computing, with <code>uwvm2</code> at its core.",
"hero.primaryCta": "Explore UlteSoft",
"hero.secondaryCta": "Open uwvm2",
"panel.liveLabel": "Live GitHub Snapshot",
"metric.publicRepos": "Public Repos",
"metric.followers": "Followers",
"metric.stars": "uwvm2 Stars",
"metric.forks": "uwvm2 Forks",
"panel.snapshotLabel": "Key Snapshot",
"facts.created": "Org created",
"facts.language": "Primary language",
"facts.updated": "Latest push",
"org.eyebrow": "Why UlteSoft Matters",
"org.title": "UlteSoft is more than just another GitHub organization",
"org.body1":
"UlteSoft is young, but its direction is unusually focused: <strong>WebAssembly virtual machines</strong>, <strong>WASI host capabilities</strong>, <strong>cross-platform execution</strong>, and <strong>extension research</strong>. That level of focus is compelling on its own.",
"org.body2":
"From <code>uwvm</code> to <code>uwvm2</code>, and from GPU/JIT extension repos to wrapper demos, the public repo list feels less like scattered experiments and more like the first draft of a serious ecosystem.",
"org.card1title": "A strong technical signal",
"org.card1body": "This is systems-software energy: low-level, ambitious, and willing to target difficult platforms.",
"org.card2title": "Why it stands out",
"org.card2body":
"The repo spread runs from VM cores to extensions and integration demos, which suggests platform thinking instead of a one-off project.",
"org.card3title": "Why now is the right time",
"org.card3body":
"The flagship is public, developer-stable, and moving in the open. This is exactly when a project becomes exciting to follow.",
"project.eyebrow": "The Flagship",
"project.title": "uwvm2 turns the vision into code",
"project.badge": "Developer Stable",
"project.tagline": "The flagship runtime in UlteSoft's WebAssembly push.",
"project.body1":
"According to the public README and development notes, <code>uwvm2</code> is not framed as a small revision. It is a <strong>ground-up rearchitecture</strong> of Ultimate WebAssembly Virtual Machine, built around <strong>C++26</strong>, extensibility, spec-driven design, and memory-safe execution.",
"project.body2":
"More importantly, the README already outlines a full capability map: WASM feature extensions, broad platform support, runtime execution backends, a high-performance standard parser, WASI host extensions, plugin-facing host APIs, and flexible linear-memory models. The blocks below follow that README structure directly.",
"readme.label": "README Feature Set",
"readme.title": "Every core capability named in the README, brought onto the page",
"readme.text":
"To make uwvm2 the real centerpiece of this landing page, the feature list below follows the official README and expands every public capability it calls out.",
"readme.item1title": "WASM Feature Extensions",
"readme.item1body":
"The README states that most standardized Wasm features are supported, with dedicated feature documentation and release-by-release WebAssembly change notes.",
"readme.item2title": "Supports multiple platforms",
"readme.item2body":
"uwvm2 targets 100+ triplet platforms spanning DOS, POSIX, Windows 9x, Windows NT, and Host C Library families, while also planning for INT, JIT, and tiered compilation.",
"readme.item3title": "Runtime execution backends",
"readme.item3body":
"The project includes multiple runtime execution backends, covering interpreter paths and in-memory compilation components, with the README explicitly pointing to the u2 interpreter architecture.",
"readme.item4title": "High-performance standard parser",
"readme.item4body":
"The README presents uwvm2 as a high-performance, spec-compliant, scalable, and security-aware WebAssembly binary parser with SIMD-aware design and extensive fuzzing.",
"readme.item5title": "WASI host extensions",
"readme.item5body":
"uwvm2 exposes WASI Preview 1 host bindings for <code>wasm32-wasip1</code> and <code>wasm64-wasip1</code>, allowing filesystem and related services to reach Wasm modules.",
"readme.item6title": "Plugin-facing host APIs",
"readme.item6body":
"Preload modules, whether dynamic libraries or weak-symbol plugins, can consume a stable host-side linear-memory API and optionally the UWVM2 WASI Preview 1 host API.",
"readme.item7title": "Flexible linear memory models",
"readme.item7body":
"The README names three host-side linear-memory models: an <code>mmap</code>-based backend, a multi-threaded allocator backend, and a single-thread allocator backend for different platform constraints.",
"cli.label": "Command Line",
"cli.title": "The README also gives you a direct command-line on-ramp",
"cli.text":
"This project is not only conceptual. The official README already exposes the most useful command-line entry points for getting started quickly.",
"cli.item1": "<code>uwvm --version</code> Show version information",
"cli.item2": "<code>uwvm --help</code> Show the command list",
"cli.item3": "<code>uwvm <params...> --run <wasm> <argv...></code> Run the Wasm virtual machine",
"cli.item4":
"<code>uwvm --wasip1-mount-dir <wasi dir> <system dir> ... --run ...</code> Run with a mounted WASI directory",
"cli.item5":
"<code>uwvm --wasm-expose-wasip1-host-api --wasm-register-dl <plugin> <module> --run ...</code> Expose the WASI Preview 1 host API to preload plugins",
"build.label": "Build Targets",
"build.title": "The build entry points are just as broad",
"build.text":
"The README does not hide platform support behind a vague claim. It explicitly points to official build guides for mainstream and specialized targets.",
"build.item1": "Windows / <code>unknown-windows-msvc</code>",
"build.item2": "MinGW / <code>unknown-windows-gnu</code>",
"build.item3": "Linux / <code>unknown-linux-unknown</code>",
"build.item4": "Darwin / <code>unknown-apple-darwin</code>",
"build.item5": "FreeBSD / <code>unknown-freebsd(Version)</code>",
"build.item6": "WASM-WASI self-hosting / <code>wasm32|wasm64-[wasip1|wasip2]</code>",
"build.item7": "Additional targets are documented under the broader how-to-build guides",
"feature1.title": "Portability with real ambition",
"feature1.body":
"The public support matrix points to 100+ triplet targets across POSIX, Windows NT/9x, DOS, WASM-WASI, Emscripten, and selected freestanding environments.",
"feature2.title": "Spec-first engineering",
"feature2.body":
"The documentation already names completed work such as the CLI foundation and the Wasm 1.0 parser, while the roadmap continues into validation, initialization, and execution backends.",
"feature3.title": "WASI that makes the runtime matter",
"feature3.body":
"WASI Preview 1 is a declared workstream, which means uwvm2 is not only about parsing and executing bytes. It is aiming at real host-facing capability.",
"feature4.title": "Designed for more than one execution model",
"feature4.body":
"From interpretation to JIT and multiple linear-memory strategies, the architecture clearly aims at a broader Wasm runtime landscape rather than a single narrow use case.",
"ecosystem.eyebrow": "Beyond One Repo",
"ecosystem.title": "Not a lonely repository. An ecosystem taking shape.",
"repo1.body":
"The original Ultimate WebAssembly Virtual Machine. It is the best place to see where the story started before uwvm2 widened the ambition.",
"repo2.body":
"A platform-focused prerequisites repo that hints at serious attention to older, stranger, and more constrained environments.",
"repo3.body":
"An experimental bridge between Wasm and GPU IR, showing that UlteSoft is willing to imagine higher-order extension paths.",
"repo4.body":
"A repository centered on JIT-oriented extension ideas, and a clear reminder that UlteSoft is thinking beyond interpretation alone.",
"repo5.body":
"A ROS 2 wrapper demo that pushes uwvm2 from 'it runs' toward 'it can plug into real ecosystems.'",
"repo6.body":
"A graphics and systems integration demo that suggests this runtime is already being tested against more demanding host environments.",
"timeline.eyebrow": "Momentum",
"timeline.title": "This roadmap is not stuck at the idea stage",
"timeline.item1label": "Already landed",
"timeline.item1body":
"The public development notes already list the CLI, the WebAssembly 1.0 parser, and section handling as completed work.",
"timeline.item2label": "In motion",
"timeline.item2body":
"WASI Preview 1 support is the active push right now, and it is a crucial step toward real execution environments.",
"timeline.item3label": "What comes next",
"timeline.item3body":
"Module initialization and validation, a high-performance interpreter, LLVM JIT, tiered compilation, and code caching are all clearly named on the public roadmap.",
"footer.body":
"This page combines public GitHub metadata with the uwvm2 README, support matrix, and development-status documents to present a compact introduction to the organization and its flagship runtime.",
statusLoading: "Fetching the latest public snapshot from GitHub",
statusSuccess: "Live GitHub data loaded",
statusFailure: "GitHub refresh failed, showing the bundled snapshot instead",
},
};
const githubState = {
org: null,
repo: null,
status: "loading",
};
let currentLanguage = "zh";
function getLocale(language) {
return language === "zh" ? "zh-CN" : "en-US";
}
function formatNumber(value) {
return new Intl.NumberFormat(getLocale(currentLanguage)).format(value);
}
function formatIsoDate(isoDate) {
const date = new Date(isoDate);
if (Number.isNaN(date.getTime())) {
return isoDate;
}
return new Intl.DateTimeFormat(getLocale(currentLanguage), {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).format(date);
}
function setText(selector, value) {
const element = document.querySelector(selector);
if (element && value !== undefined && value !== null && value !== "") {
element.textContent = value;
}
}
function updateTopics(topics) {
const container = document.querySelector("#repo-topics");
if (!container || !Array.isArray(topics) || topics.length === 0) {
return;
}
container.innerHTML = "";
topics.slice(0, 6).forEach((topic) => {
const chip = document.createElement("span");
chip.textContent = topic;
container.appendChild(chip);
});
}
function renderStatus() {
const label = document.querySelector("#data-status");
if (!label) {
return;
}
const dictionary = translations[currentLanguage];
if (githubState.status === "success") {
label.textContent = dictionary.statusSuccess;
return;
}
if (githubState.status === "failure") {
label.textContent = dictionary.statusFailure;
return;
}
label.textContent = dictionary.statusLoading;
}
function renderGithubData() {
if (githubState.org) {
setText("[data-org-repos]", formatNumber(githubState.org.public_repos));
setText("[data-org-followers]", formatNumber(githubState.org.followers));
setText("[data-org-created]", formatIsoDate(githubState.org.created_at));
}
if (githubState.repo) {
setText("[data-repo-stars]", formatNumber(githubState.repo.stargazers_count));
setText("[data-repo-forks]", formatNumber(githubState.repo.forks_count));
setText("[data-repo-language]", githubState.repo.language || "C++");
setText("[data-repo-updated]", formatIsoDate(githubState.repo.pushed_at));
updateTopics(githubState.repo.topics);
}
renderStatus();
}
function applyTranslations(language) {
const dictionary = translations[language];
document.documentElement.lang = language === "zh" ? "zh-CN" : "en";
document.title = dictionary.metaTitle;
const metaDescription = document.querySelector("#meta-description");
const metaOgTitle = document.querySelector("#meta-og-title");
const metaOgDescription = document.querySelector("#meta-og-description");
if (metaDescription) {
metaDescription.setAttribute("content", dictionary.metaDescription);
}
if (metaOgTitle) {
metaOgTitle.setAttribute("content", dictionary.metaTitle);
}
if (metaOgDescription) {
metaOgDescription.setAttribute("content", dictionary.metaDescription);
}
document.querySelectorAll("[data-i18n]").forEach((element) => {
const key = element.dataset.i18n;
const value = dictionary[key];
if (value) {
element.innerHTML = value;
}
});
document.querySelectorAll("[data-lang-switch]").forEach((button) => {
const isActive = button.dataset.langSwitch === language;
button.classList.toggle("is-active", isActive);
button.setAttribute("aria-pressed", String(isActive));
});
renderGithubData();
}
function setLanguage(language) {
if (!translations[language]) {
return;
}
currentLanguage = language;
applyTranslations(language);
window.localStorage.setItem(STORAGE_KEY, language);
}
function detectInitialLanguage() {
const savedLanguage = window.localStorage.getItem(STORAGE_KEY);
if (savedLanguage && translations[savedLanguage]) {
return savedLanguage;
}
const browserLanguage = navigator.language.toLowerCase();
return browserLanguage.startsWith("zh") ? "zh" : "en";
}
async function fetchJson(url) {
const response = await fetch(url, {
headers: {
Accept: "application/vnd.github+json",
},
});
if (!response.ok) {
throw new Error(`Failed to fetch ${url}: ${response.status}`);
}
return response.json();
}
async function hydrateGithubSnapshot() {
githubState.status = "loading";
renderStatus();
try {
const [org, repo] = await Promise.all([
fetchJson(endpoints.org),
fetchJson(endpoints.repo),
]);
githubState.org = org;
githubState.repo = repo;
githubState.status = "success";
renderGithubData();
} catch (error) {
githubState.status = "failure";
renderStatus();
console.error(error);
}
}
document.querySelectorAll("[data-lang-switch]").forEach((button) => {
button.addEventListener("click", () => {
setLanguage(button.dataset.langSwitch);
});
});
setLanguage(detectInitialLanguage());
hydrateGithubSnapshot();