25 Commits

Author SHA1 Message Date
Ubuntu
39840f469f feat: customer demo - remove breakout game, numeric matrix, 3D module switcher
- Remove NeonBreakoutArena split panel from CenterStage
- Remove numeric matrix display mode toggle (keep dot matrix only)
- Remove 3D module stage mode switcher from HudPanel
- Remove precision-test config link and related UI state
- Cargo check passes (1 warning: unused import in log.rs)
2026-05-25 15:17:48 +08:00
lenn
b581e310ed update frontend components and cargo config 2026-05-20 10:18:27 +08:00
lenn
c579544351 Revert "fix: compensate tangential force edge and full-surface cases"
This reverts commit aa08a75aef.
2026-05-20 09:45:47 +08:00
lenn
aa08a75aef fix: compensate tangential force edge and full-surface cases 2026-05-20 09:39:14 +08:00
lenn
6187976b6b feat: integrate tangential force HUD 2026-05-20 08:33:20 +08:00
lenn
59e9203363 feat: add 3D model viewer, HUD panel updates, and eskin-finger-sdk submodule
- Add ModelStage component for 3D model rendering
- Update CenterStage to integrate ModelStage viewer
- Expand HudPanel with new functionality
- Add HUD type definitions
- Add je-skin-model.glb 3D model asset
- Add eskin-finger-sdk as git submodule
2026-05-18 23:37:01 +08:00
lenn
83832139a8 Merge branch 'display'
# Conflicts:
#	.gitignore
#	package-lock.json
#	package.json
#	src-tauri/Cargo.lock
#	src-tauri/Cargo.toml
#	src-tauri/tauri.conf.json
#	src/routes/+page.svelte
2026-04-29 16:08:46 +08:00
lenn
eb6f318348 chore: 更新 Cargo.lock 2026-04-29 16:06:20 +08:00
lenn
5eff91b898 chore: 版本升级至 0.4.0 2026-04-29 15:54:23 +08:00
lenn
326f07ed4f fix: 修复打砖块游戏碰撞穿透bug,添加渐进提速机制 2026-04-29 15:43:56 +08:00
lenn
26533f6916 Migrate updater LAN and devkit features from old repo 2026-04-27 16:37:40 +08:00
lenn
b33c952eb6 update:清理误提交构建产物并更新range适配 2026-04-27 11:25:38 +08:00
lenn
e5b869fda6 fix:修复日志bug;feat:增加unix适配 2026-04-26 22:02:26 +08:00
lenn
ac2d40aa89 update serial.rs, use round 3 data 2026-04-26 16:29:34 +08:00
lenn
f7b92268cd update .gitignore 2026-04-26 16:25:52 +08:00
lenn
50700e73df update .gitignore 2026-04-20 09:32:43 +08:00
lenn
7e047daf00 remove log file 2026-04-15 09:50:29 +08:00
lenn
842d4980d9 remove target dirs 2026-04-15 09:49:33 +08:00
lenn
04a0c3e46b remove unnecessary dotfiles 2026-04-15 09:46:19 +08:00
lenn
d4e1da6219 更新软件版本号 2026-04-15 09:44:54 +08:00
lenn
d1c9be56ec Merge branch 'main' of https://gitea.e-skin.top/E-Skin/JE-Skin 2026-04-15 09:28:09 +08:00
lenn
2e30fa388a 导出数据添加summary列 2026-04-15 09:20:56 +08:00
Lenn
4b2203e008 合并请求 #2
feat:增加点和数字切换,减小点最大尺寸,增加range配色方案
2026-04-09 01:18:56 +00:00
lenn
a3cefc3c79 feat:增加点和数字切换,减小点最大尺寸,增加range配色方案 2026-04-09 09:17:07 +08:00
Lenn
1c3a811154 合并请求 #1
feat:add game!
2026-04-06 17:45:38 +00:00
154 changed files with 9721 additions and 2564 deletions

View File

@@ -1,62 +0,0 @@
# Details
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 8908 codes, 94 comments, 1250 blanks, all 10252 lines
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
| [.idea/modules.xml](/.idea/modules.xml) | XML | 8 | 0 | 0 | 8 |
| [.idea/tauri-demo.iml](/.idea/tauri-demo.iml) | XML | 11 | 0 | 0 | 11 |
| [README.md](/README.md) | Markdown | 34 | 0 | 20 | 54 |
| [flowus\_tools.json](/flowus_tools.json) | JSON | 1 | 0 | 1 | 2 |
| [frontend\_prompt.md](/frontend_prompt.md) | Markdown | 189 | 0 | 66 | 255 |
| [package-lock.json](/package-lock.json) | JSON | 1,957 | 0 | 1 | 1,958 |
| [package.json](/package.json) | JSON | 31 | 0 | 1 | 32 |
| [src-tauri/build.rs](/src-tauri/build.rs) | Rust | 3 | 0 | 1 | 4 |
| [src-tauri/capabilities/default.json](/src-tauri/capabilities/default.json) | JSON | 15 | 0 | 1 | 16 |
| [src-tauri/src/commands/mod.rs](/src-tauri/src/commands/mod.rs) | Rust | 2 | 0 | 1 | 3 |
| [src-tauri/src/commands/serial.rs](/src-tauri/src/commands/serial.rs) | Rust | 246 | 0 | 44 | 290 |
| [src-tauri/src/commands/window.rs](/src-tauri/src/commands/window.rs) | Rust | 27 | 0 | 6 | 33 |
| [src-tauri/src/lib.rs](/src-tauri/src/lib.rs) | Rust | 22 | 0 | 2 | 24 |
| [src-tauri/src/log.rs](/src-tauri/src/log.rs) | Rust | 34 | 0 | 2 | 36 |
| [src-tauri/src/main.rs](/src-tauri/src/main.rs) | Rust | 8 | 1 | 2 | 11 |
| [src-tauri/src/serial\_core/codec.rs](/src-tauri/src/serial_core/codec.rs) | Rust | 6 | 0 | 1 | 7 |
| [src-tauri/src/serial\_core/codecs/mod.rs](/src-tauri/src/serial_core/codecs/mod.rs) | Rust | 4 | 0 | 1 | 5 |
| [src-tauri/src/serial\_core/codecs/tactile\_a.rs](/src-tauri/src/serial_core/codecs/tactile_a.rs) | Rust | 67 | 0 | 17 | 84 |
| [src-tauri/src/serial\_core/codecs/test.rs](/src-tauri/src/serial_core/codecs/test.rs) | Rust | 213 | 7 | 40 | 260 |
| [src-tauri/src/serial\_core/error.rs](/src-tauri/src/serial_core/error.rs) | Rust | 47 | 0 | 6 | 53 |
| [src-tauri/src/serial\_core/frame.rs](/src-tauri/src/serial_core/frame.rs) | Rust | 46 | 3 | 9 | 58 |
| [src-tauri/src/serial\_core/mod.rs](/src-tauri/src/serial_core/mod.rs) | Rust | 22 | 0 | 7 | 29 |
| [src-tauri/src/serial\_core/model.rs](/src-tauri/src/serial_core/model.rs) | Rust | 377 | 57 | 67 | 501 |
| [src-tauri/src/serial\_core/record.rs](/src-tauri/src/serial_core/record.rs) | Rust | 50 | 4 | 11 | 65 |
| [src-tauri/src/serial\_core/serial.rs](/src-tauri/src/serial_core/serial.rs) | Rust | 73 | 0 | 8 | 81 |
| [src-tauri/src/serial\_core/utils.rs](/src-tauri/src/serial_core/utils.rs) | Rust | 26 | 0 | 6 | 32 |
| [src-tauri/tauri.conf.json](/src-tauri/tauri.conf.json) | JSON | 36 | 0 | 1 | 37 |
| [src/app.html](/src/app.html) | HTML | 13 | 0 | 1 | 14 |
| [src/lib/components/CenterStage.svelte](/src/lib/components/CenterStage.svelte) | Svelte | 691 | 0 | 96 | 787 |
| [src/lib/components/ConfigPanel.svelte](/src/lib/components/ConfigPanel.svelte) | Svelte | 398 | 0 | 63 | 461 |
| [src/lib/components/HudPanel.svelte](/src/lib/components/HudPanel.svelte) | Svelte | 861 | 0 | 110 | 971 |
| [src/lib/components/PressureMatrixViewer.svelte](/src/lib/components/PressureMatrixViewer.svelte) | Svelte | 558 | 0 | 97 | 655 |
| [src/lib/components/SignalChart.svelte](/src/lib/components/SignalChart.svelte) | Svelte | 382 | 0 | 71 | 453 |
| [src/lib/components/SummaryCurve.svelte](/src/lib/components/SummaryCurve.svelte) | Svelte | 497 | 0 | 88 | 585 |
| [src/lib/config/color-map.ts](/src/lib/config/color-map.ts) | TypeScript | 55 | 0 | 3 | 58 |
| [src/lib/styles/theme.css](/src/lib/styles/theme.css) | PostCSS | 43 | 1 | 7 | 51 |
| [src/lib/types/hud.ts](/src/lib/types/hud.ts) | TypeScript | 126 | 0 | 20 | 146 |
| [src/routes/+layout.svelte](/src/routes/+layout.svelte) | Svelte | 13 | 0 | 5 | 18 |
| [src/routes/+layout.ts](/src/routes/+layout.ts) | TypeScript | 1 | 4 | 1 | 6 |
| [src/routes/+page.svelte](/src/routes/+page.svelte) | Svelte | 1,286 | 0 | 176 | 1,462 |
| [static/svelte.svg](/static/svelte.svg) | XML | 1 | 0 | 0 | 1 |
| [static/tauri.svg](/static/tauri.svg) | XML | 6 | 0 | 1 | 7 |
| [static/vite.svg](/static/vite.svg) | XML | 1 | 0 | 0 | 1 |
| [svelte.config.js](/svelte.config.js) | JavaScript | 11 | 5 | 3 | 19 |
| [tauri-event.md](/tauri-event.md) | Markdown | 374 | 0 | 181 | 555 |
| [tsconfig.json](/tsconfig.json) | JSON with Comments | 14 | 5 | 1 | 20 |
| [vite.config.js](/vite.config.js) | JavaScript | 22 | 7 | 4 | 33 |
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,15 +0,0 @@
# Diff Details
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details

View File

@@ -1,2 +0,0 @@
"filename", "language", "", "comment", "blank", "total"
"Total", "-", , 0, 0, 0
1 filename language comment blank total
2 Total - 0 0 0

View File

@@ -1,19 +0,0 @@
# Diff Summary
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)

View File

@@ -1,22 +0,0 @@
Date : 2026-04-01 16:39:17
Directory : e:\Workspace\JE-Skin
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
Languages
+----------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+----------+------------+------------+------------+------------+------------+
+----------+------------+------------+------------+------------+------------+
Directories
+------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+------+------------+------------+------------+------------+------------+
+------+------------+------------+------------+------------+------------+
Files
+----------+----------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+----------+----------+------------+------------+------------+------------+
| Total | | 0 | 0 | 0 | 0 |
+----------+----------+------------+------------+------------+------------+

View File

@@ -1,49 +0,0 @@
"filename", "language", "JavaScript", "JSON", "Markdown", "JSON with Comments", "XML", "TypeScript", "Svelte", "Rust", "PostCSS", "HTML", "comment", "blank", "total"
"e:\Workspace\JE-Skin\.idea\modules.xml", "XML", 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8
"e:\Workspace\JE-Skin\.idea\tauri-demo.iml", "XML", 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 11
"e:\Workspace\JE-Skin\README.md", "Markdown", 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 20, 54
"e:\Workspace\JE-Skin\flowus_tools.json", "JSON", 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2
"e:\Workspace\JE-Skin\frontend_prompt.md", "Markdown", 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 0, 66, 255
"e:\Workspace\JE-Skin\package-lock.json", "JSON", 0, 1957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1958
"e:\Workspace\JE-Skin\package.json", "JSON", 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32
"e:\Workspace\JE-Skin\src-tauri\build.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 4
"e:\Workspace\JE-Skin\src-tauri\capabilities\default.json", "JSON", 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16
"e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 3
"e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 44, 290
"e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 6, 33
"e:\Workspace\JE-Skin\src-tauri\src\lib.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 2, 24
"e:\Workspace\JE-Skin\src-tauri\src\log.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 2, 36
"e:\Workspace\JE-Skin\src-tauri\src\main.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 1, 2, 11
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 5
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 17, 84
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 7, 40, 260
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 6, 53
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 3, 9, 58
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 7, 29
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 377, 0, 0, 57, 67, 501
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 4, 11, 65
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 8, 81
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs", "Rust", 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 6, 32
"e:\Workspace\JE-Skin\src-tauri\tauri.conf.json", "JSON", 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 37
"e:\Workspace\JE-Skin\src\app.html", "HTML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 1, 14
"e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 691, 0, 0, 0, 0, 96, 787
"e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 63, 461
"e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 861, 0, 0, 0, 0, 110, 971
"e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 97, 655
"e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 382, 0, 0, 0, 0, 71, 453
"e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 497, 0, 0, 0, 0, 88, 585
"e:\Workspace\JE-Skin\src\lib\config\color-map.ts", "TypeScript", 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 3, 58
"e:\Workspace\JE-Skin\src\lib\styles\theme.css", "PostCSS", 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 1, 7, 51
"e:\Workspace\JE-Skin\src\lib\types\hud.ts", "TypeScript", 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 20, 146
"e:\Workspace\JE-Skin\src\routes\+layout.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 5, 18
"e:\Workspace\JE-Skin\src\routes\+layout.ts", "TypeScript", 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 1, 6
"e:\Workspace\JE-Skin\src\routes\+page.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 1286, 0, 0, 0, 0, 176, 1462
"e:\Workspace\JE-Skin\static\svelte.svg", "XML", 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\static\tauri.svg", "XML", 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\static\vite.svg", "XML", 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\svelte.config.js", "JavaScript", 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 19
"e:\Workspace\JE-Skin\tauri-event.md", "Markdown", 0, 0, 374, 0, 0, 0, 0, 0, 0, 0, 0, 181, 555
"e:\Workspace\JE-Skin\tsconfig.json", "JSON with Comments", 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 5, 1, 20
"e:\Workspace\JE-Skin\vite.config.js", "JavaScript", 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 33
"Total", "-", 33, 2040, 597, 14, 27, 182, 4686, 1273, 43, 13, 94, 1250, 10252
1 filename language JavaScript JSON Markdown JSON with Comments XML TypeScript Svelte Rust PostCSS HTML comment blank total
2 e:\Workspace\JE-Skin\.idea\modules.xml XML 0 0 0 0 8 0 0 0 0 0 0 0 8
3 e:\Workspace\JE-Skin\.idea\tauri-demo.iml XML 0 0 0 0 11 0 0 0 0 0 0 0 11
4 e:\Workspace\JE-Skin\README.md Markdown 0 0 34 0 0 0 0 0 0 0 0 20 54
5 e:\Workspace\JE-Skin\flowus_tools.json JSON 0 1 0 0 0 0 0 0 0 0 0 1 2
6 e:\Workspace\JE-Skin\frontend_prompt.md Markdown 0 0 189 0 0 0 0 0 0 0 0 66 255
7 e:\Workspace\JE-Skin\package-lock.json JSON 0 1957 0 0 0 0 0 0 0 0 0 1 1958
8 e:\Workspace\JE-Skin\package.json JSON 0 31 0 0 0 0 0 0 0 0 0 1 32
9 e:\Workspace\JE-Skin\src-tauri\build.rs Rust 0 0 0 0 0 0 0 3 0 0 0 1 4
10 e:\Workspace\JE-Skin\src-tauri\capabilities\default.json JSON 0 15 0 0 0 0 0 0 0 0 0 1 16
11 e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs Rust 0 0 0 0 0 0 0 2 0 0 0 1 3
12 e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs Rust 0 0 0 0 0 0 0 246 0 0 0 44 290
13 e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs Rust 0 0 0 0 0 0 0 27 0 0 0 6 33
14 e:\Workspace\JE-Skin\src-tauri\src\lib.rs Rust 0 0 0 0 0 0 0 22 0 0 0 2 24
15 e:\Workspace\JE-Skin\src-tauri\src\log.rs Rust 0 0 0 0 0 0 0 34 0 0 0 2 36
16 e:\Workspace\JE-Skin\src-tauri\src\main.rs Rust 0 0 0 0 0 0 0 8 0 0 1 2 11
17 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs Rust 0 0 0 0 0 0 0 6 0 0 0 1 7
18 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs Rust 0 0 0 0 0 0 0 4 0 0 0 1 5
19 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs Rust 0 0 0 0 0 0 0 67 0 0 0 17 84
20 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs Rust 0 0 0 0 0 0 0 213 0 0 7 40 260
21 e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs Rust 0 0 0 0 0 0 0 47 0 0 0 6 53
22 e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs Rust 0 0 0 0 0 0 0 46 0 0 3 9 58
23 e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs Rust 0 0 0 0 0 0 0 22 0 0 0 7 29
24 e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs Rust 0 0 0 0 0 0 0 377 0 0 57 67 501
25 e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs Rust 0 0 0 0 0 0 0 50 0 0 4 11 65
26 e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs Rust 0 0 0 0 0 0 0 73 0 0 0 8 81
27 e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs Rust 0 0 0 0 0 0 0 26 0 0 0 6 32
28 e:\Workspace\JE-Skin\src-tauri\tauri.conf.json JSON 0 36 0 0 0 0 0 0 0 0 0 1 37
29 e:\Workspace\JE-Skin\src\app.html HTML 0 0 0 0 0 0 0 0 0 13 0 1 14
30 e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte Svelte 0 0 0 0 0 0 691 0 0 0 0 96 787
31 e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte Svelte 0 0 0 0 0 0 398 0 0 0 0 63 461
32 e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte Svelte 0 0 0 0 0 0 861 0 0 0 0 110 971
33 e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte Svelte 0 0 0 0 0 0 558 0 0 0 0 97 655
34 e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte Svelte 0 0 0 0 0 0 382 0 0 0 0 71 453
35 e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte Svelte 0 0 0 0 0 0 497 0 0 0 0 88 585
36 e:\Workspace\JE-Skin\src\lib\config\color-map.ts TypeScript 0 0 0 0 0 55 0 0 0 0 0 3 58
37 e:\Workspace\JE-Skin\src\lib\styles\theme.css PostCSS 0 0 0 0 0 0 0 0 43 0 1 7 51
38 e:\Workspace\JE-Skin\src\lib\types\hud.ts TypeScript 0 0 0 0 0 126 0 0 0 0 0 20 146
39 e:\Workspace\JE-Skin\src\routes\+layout.svelte Svelte 0 0 0 0 0 0 13 0 0 0 0 5 18
40 e:\Workspace\JE-Skin\src\routes\+layout.ts TypeScript 0 0 0 0 0 1 0 0 0 0 4 1 6
41 e:\Workspace\JE-Skin\src\routes\+page.svelte Svelte 0 0 0 0 0 0 1286 0 0 0 0 176 1462
42 e:\Workspace\JE-Skin\static\svelte.svg XML 0 0 0 0 1 0 0 0 0 0 0 0 1
43 e:\Workspace\JE-Skin\static\tauri.svg XML 0 0 0 0 6 0 0 0 0 0 0 1 7
44 e:\Workspace\JE-Skin\static\vite.svg XML 0 0 0 0 1 0 0 0 0 0 0 0 1
45 e:\Workspace\JE-Skin\svelte.config.js JavaScript 11 0 0 0 0 0 0 0 0 0 5 3 19
46 e:\Workspace\JE-Skin\tauri-event.md Markdown 0 0 374 0 0 0 0 0 0 0 0 181 555
47 e:\Workspace\JE-Skin\tsconfig.json JSON with Comments 0 0 0 14 0 0 0 0 0 0 5 1 20
48 e:\Workspace\JE-Skin\vite.config.js JavaScript 22 0 0 0 0 0 0 0 0 0 7 4 33
49 Total - 33 2040 597 14 27 182 4686 1273 43 13 94 1250 10252

File diff suppressed because one or more lines are too long

View File

@@ -1,50 +0,0 @@
# Summary
Date : 2026-04-01 16:39:17
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 8908 codes, 94 comments, 1250 blanks, all 10252 lines
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,273 | 72 | 231 | 1,576 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| . | 47 | 8,908 | 94 | 1,250 | 10,252 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,324 | 72 | 233 | 1,629 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\\src | 17 | 1,270 | 72 | 230 | 1,572 |
| src-tauri\\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\\src\\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\\src\\serial_core | 11 | 931 | 71 | 173 | 1,175 |
| src-tauri\\src\\serial_core (Files) | 8 | 647 | 64 | 115 | 826 |
| src-tauri\\src\\serial_core\\codecs | 3 | 284 | 7 | 58 | 349 |
| src\\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\\lib\\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\\lib\\config | 1 | 55 | 0 | 3 | 58 |
| src\\lib\\styles | 1 | 43 | 1 | 7 | 51 |
| src\\lib\\types | 1 | 126 | 0 | 20 | 146 |
| src\\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,100 +0,0 @@
Date : 2026-04-01 16:39:17
Directory : e:\Workspace\JE-Skin
Total : 47 files, 8908 codes, 94 comments, 1250 blanks, all 10252 lines
Languages
+--------------------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+--------------------+------------+------------+------------+------------+------------+
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,273 | 72 | 231 | 1,576 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
+--------------------+------------+------------+------------+------------+------------+
Directories
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| . | 47 | 8,908 | 94 | 1,250 | 10,252 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,324 | 72 | 233 | 1,629 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\src | 17 | 1,270 | 72 | 230 | 1,572 |
| src-tauri\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\src\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\src\serial_core | 11 | 931 | 71 | 173 | 1,175 |
| src-tauri\src\serial_core (Files) | 8 | 647 | 64 | 115 | 826 |
| src-tauri\src\serial_core\codecs | 3 | 284 | 7 | 58 | 349 |
| src\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\lib\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\lib\config | 1 | 55 | 0 | 3 | 58 |
| src\lib\styles | 1 | 43 | 1 | 7 | 51 |
| src\lib\types | 1 | 126 | 0 | 20 | 146 |
| src\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
Files
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| e:\Workspace\JE-Skin\.idea\modules.xml | XML | 8 | 0 | 0 | 8 |
| e:\Workspace\JE-Skin\.idea\tauri-demo.iml | XML | 11 | 0 | 0 | 11 |
| e:\Workspace\JE-Skin\README.md | Markdown | 34 | 0 | 20 | 54 |
| e:\Workspace\JE-Skin\flowus_tools.json | JSON | 1 | 0 | 1 | 2 |
| e:\Workspace\JE-Skin\frontend_prompt.md | Markdown | 189 | 0 | 66 | 255 |
| e:\Workspace\JE-Skin\package-lock.json | JSON | 1,957 | 0 | 1 | 1,958 |
| e:\Workspace\JE-Skin\package.json | JSON | 31 | 0 | 1 | 32 |
| e:\Workspace\JE-Skin\src-tauri\build.rs | Rust | 3 | 0 | 1 | 4 |
| e:\Workspace\JE-Skin\src-tauri\capabilities\default.json | JSON | 15 | 0 | 1 | 16 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs | Rust | 2 | 0 | 1 | 3 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs | Rust | 246 | 0 | 44 | 290 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs | Rust | 27 | 0 | 6 | 33 |
| e:\Workspace\JE-Skin\src-tauri\src\lib.rs | Rust | 22 | 0 | 2 | 24 |
| e:\Workspace\JE-Skin\src-tauri\src\log.rs | Rust | 34 | 0 | 2 | 36 |
| e:\Workspace\JE-Skin\src-tauri\src\main.rs | Rust | 8 | 1 | 2 | 11 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs | Rust | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs | Rust | 4 | 0 | 1 | 5 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs | Rust | 67 | 0 | 17 | 84 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs | Rust | 213 | 7 | 40 | 260 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs | Rust | 47 | 0 | 6 | 53 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs | Rust | 46 | 3 | 9 | 58 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs | Rust | 22 | 0 | 7 | 29 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs | Rust | 377 | 57 | 67 | 501 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs | Rust | 50 | 4 | 11 | 65 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs | Rust | 73 | 0 | 8 | 81 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs | Rust | 26 | 0 | 6 | 32 |
| e:\Workspace\JE-Skin\src-tauri\tauri.conf.json | JSON | 36 | 0 | 1 | 37 |
| e:\Workspace\JE-Skin\src\app.html | HTML | 13 | 0 | 1 | 14 |
| e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte | Svelte | 691 | 0 | 96 | 787 |
| e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte | Svelte | 398 | 0 | 63 | 461 |
| e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte | Svelte | 861 | 0 | 110 | 971 |
| e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte | Svelte | 558 | 0 | 97 | 655 |
| e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte | Svelte | 382 | 0 | 71 | 453 |
| e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte | Svelte | 497 | 0 | 88 | 585 |
| e:\Workspace\JE-Skin\src\lib\config\color-map.ts | TypeScript | 55 | 0 | 3 | 58 |
| e:\Workspace\JE-Skin\src\lib\styles\theme.css | PostCSS | 43 | 1 | 7 | 51 |
| e:\Workspace\JE-Skin\src\lib\types\hud.ts | TypeScript | 126 | 0 | 20 | 146 |
| e:\Workspace\JE-Skin\src\routes\+layout.svelte | Svelte | 13 | 0 | 5 | 18 |
| e:\Workspace\JE-Skin\src\routes\+layout.ts | TypeScript | 1 | 4 | 1 | 6 |
| e:\Workspace\JE-Skin\src\routes\+page.svelte | Svelte | 1,286 | 0 | 176 | 1,462 |
| e:\Workspace\JE-Skin\static\svelte.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\static\tauri.svg | XML | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\static\vite.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\svelte.config.js | JavaScript | 11 | 5 | 3 | 19 |
| e:\Workspace\JE-Skin\tauri-event.md | Markdown | 374 | 0 | 181 | 555 |
| e:\Workspace\JE-Skin\tsconfig.json | JSON with Comments | 14 | 5 | 1 | 20 |
| e:\Workspace\JE-Skin\vite.config.js | JavaScript | 22 | 7 | 4 | 33 |
| Total | | 8,908 | 94 | 1,250 | 10,252 |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+

View File

@@ -1,62 +0,0 @@
# Details
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 9155 codes, 95 comments, 1279 blanks, all 10529 lines
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
| [.idea/modules.xml](/.idea/modules.xml) | XML | 8 | 0 | 0 | 8 |
| [.idea/tauri-demo.iml](/.idea/tauri-demo.iml) | XML | 11 | 0 | 0 | 11 |
| [README.md](/README.md) | Markdown | 34 | 0 | 20 | 54 |
| [flowus\_tools.json](/flowus_tools.json) | JSON | 1 | 0 | 1 | 2 |
| [frontend\_prompt.md](/frontend_prompt.md) | Markdown | 189 | 0 | 66 | 255 |
| [package-lock.json](/package-lock.json) | JSON | 1,957 | 0 | 1 | 1,958 |
| [package.json](/package.json) | JSON | 31 | 0 | 1 | 32 |
| [src-tauri/build.rs](/src-tauri/build.rs) | Rust | 3 | 0 | 1 | 4 |
| [src-tauri/capabilities/default.json](/src-tauri/capabilities/default.json) | JSON | 15 | 0 | 1 | 16 |
| [src-tauri/src/commands/mod.rs](/src-tauri/src/commands/mod.rs) | Rust | 2 | 0 | 1 | 3 |
| [src-tauri/src/commands/serial.rs](/src-tauri/src/commands/serial.rs) | Rust | 246 | 0 | 44 | 290 |
| [src-tauri/src/commands/window.rs](/src-tauri/src/commands/window.rs) | Rust | 27 | 0 | 6 | 33 |
| [src-tauri/src/lib.rs](/src-tauri/src/lib.rs) | Rust | 22 | 0 | 2 | 24 |
| [src-tauri/src/log.rs](/src-tauri/src/log.rs) | Rust | 34 | 0 | 2 | 36 |
| [src-tauri/src/main.rs](/src-tauri/src/main.rs) | Rust | 8 | 1 | 2 | 11 |
| [src-tauri/src/serial\_core/codec.rs](/src-tauri/src/serial_core/codec.rs) | Rust | 6 | 0 | 1 | 7 |
| [src-tauri/src/serial\_core/codecs/mod.rs](/src-tauri/src/serial_core/codecs/mod.rs) | Rust | 4 | 0 | 1 | 5 |
| [src-tauri/src/serial\_core/codecs/tactile\_a.rs](/src-tauri/src/serial_core/codecs/tactile_a.rs) | Rust | 220 | 0 | 28 | 248 |
| [src-tauri/src/serial\_core/codecs/test.rs](/src-tauri/src/serial_core/codecs/test.rs) | Rust | 215 | 8 | 38 | 261 |
| [src-tauri/src/serial\_core/error.rs](/src-tauri/src/serial_core/error.rs) | Rust | 49 | 0 | 6 | 55 |
| [src-tauri/src/serial\_core/frame.rs](/src-tauri/src/serial_core/frame.rs) | Rust | 47 | 3 | 8 | 58 |
| [src-tauri/src/serial\_core/mod.rs](/src-tauri/src/serial_core/mod.rs) | Rust | 22 | 0 | 7 | 29 |
| [src-tauri/src/serial\_core/model.rs](/src-tauri/src/serial_core/model.rs) | Rust | 377 | 57 | 67 | 501 |
| [src-tauri/src/serial\_core/record.rs](/src-tauri/src/serial_core/record.rs) | Rust | 50 | 4 | 11 | 65 |
| [src-tauri/src/serial\_core/serial.rs](/src-tauri/src/serial_core/serial.rs) | Rust | 141 | 0 | 22 | 163 |
| [src-tauri/src/serial\_core/utils.rs](/src-tauri/src/serial_core/utils.rs) | Rust | 47 | 0 | 13 | 60 |
| [src-tauri/tauri.conf.json](/src-tauri/tauri.conf.json) | JSON | 36 | 0 | 1 | 37 |
| [src/app.html](/src/app.html) | HTML | 13 | 0 | 1 | 14 |
| [src/lib/components/CenterStage.svelte](/src/lib/components/CenterStage.svelte) | Svelte | 691 | 0 | 96 | 787 |
| [src/lib/components/ConfigPanel.svelte](/src/lib/components/ConfigPanel.svelte) | Svelte | 398 | 0 | 63 | 461 |
| [src/lib/components/HudPanel.svelte](/src/lib/components/HudPanel.svelte) | Svelte | 861 | 0 | 110 | 971 |
| [src/lib/components/PressureMatrixViewer.svelte](/src/lib/components/PressureMatrixViewer.svelte) | Svelte | 558 | 0 | 97 | 655 |
| [src/lib/components/SignalChart.svelte](/src/lib/components/SignalChart.svelte) | Svelte | 382 | 0 | 71 | 453 |
| [src/lib/components/SummaryCurve.svelte](/src/lib/components/SummaryCurve.svelte) | Svelte | 497 | 0 | 88 | 585 |
| [src/lib/config/color-map.ts](/src/lib/config/color-map.ts) | TypeScript | 55 | 0 | 3 | 58 |
| [src/lib/styles/theme.css](/src/lib/styles/theme.css) | PostCSS | 43 | 1 | 7 | 51 |
| [src/lib/types/hud.ts](/src/lib/types/hud.ts) | TypeScript | 126 | 0 | 20 | 146 |
| [src/routes/+layout.svelte](/src/routes/+layout.svelte) | Svelte | 13 | 0 | 5 | 18 |
| [src/routes/+layout.ts](/src/routes/+layout.ts) | TypeScript | 1 | 4 | 1 | 6 |
| [src/routes/+page.svelte](/src/routes/+page.svelte) | Svelte | 1,286 | 0 | 176 | 1,462 |
| [static/svelte.svg](/static/svelte.svg) | XML | 1 | 0 | 0 | 1 |
| [static/tauri.svg](/static/tauri.svg) | XML | 6 | 0 | 1 | 7 |
| [static/vite.svg](/static/vite.svg) | XML | 1 | 0 | 0 | 1 |
| [svelte.config.js](/svelte.config.js) | JavaScript | 11 | 5 | 3 | 19 |
| [tauri-event.md](/tauri-event.md) | Markdown | 374 | 0 | 181 | 555 |
| [tsconfig.json](/tsconfig.json) | JSON with Comments | 14 | 5 | 1 | 20 |
| [vite.config.js](/vite.config.js) | JavaScript | 22 | 7 | 4 | 33 |
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,21 +0,0 @@
# Diff Details
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 6 files, 247 codes, 1 comments, 29 blanks, all 277 lines
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
| [src-tauri/src/serial\_core/codecs/tactile\_a.rs](/src-tauri/src/serial_core/codecs/tactile_a.rs) | Rust | 153 | 0 | 11 | 164 |
| [src-tauri/src/serial\_core/codecs/test.rs](/src-tauri/src/serial_core/codecs/test.rs) | Rust | 2 | 1 | -2 | 1 |
| [src-tauri/src/serial\_core/error.rs](/src-tauri/src/serial_core/error.rs) | Rust | 2 | 0 | 0 | 2 |
| [src-tauri/src/serial\_core/frame.rs](/src-tauri/src/serial_core/frame.rs) | Rust | 1 | 0 | -1 | 0 |
| [src-tauri/src/serial\_core/serial.rs](/src-tauri/src/serial_core/serial.rs) | Rust | 68 | 0 | 14 | 82 |
| [src-tauri/src/serial\_core/utils.rs](/src-tauri/src/serial_core/utils.rs) | Rust | 21 | 0 | 7 | 28 |
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details

View File

@@ -1,8 +0,0 @@
"filename", "language", "Rust", "comment", "blank", "total"
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs", "Rust", 153, 0, 11, 164
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs", "Rust", 2, 1, -2, 1
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs", "Rust", 2, 0, 0, 2
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs", "Rust", 1, 0, -1, 0
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs", "Rust", 68, 0, 14, 82
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs", "Rust", 21, 0, 7, 28
"Total", "-", 247, 1, 29, 277
1 filename language Rust comment blank total
2 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs Rust 153 0 11 164
3 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs Rust 2 1 -2 1
4 e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs Rust 2 0 0 2
5 e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs Rust 1 0 -1 0
6 e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs Rust 68 0 14 82
7 e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs Rust 21 0 7 28
8 Total - 247 1 29 277

View File

@@ -1,26 +0,0 @@
# Diff Summary
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 6 files, 247 codes, 1 comments, 29 blanks, all 277 lines
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| Rust | 6 | 247 | 1 | 29 | 277 |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| . | 6 | 247 | 1 | 29 | 277 |
| src-tauri | 6 | 247 | 1 | 29 | 277 |
| src-tauri\\src | 6 | 247 | 1 | 29 | 277 |
| src-tauri\\src\\serial_core | 6 | 247 | 1 | 29 | 277 |
| src-tauri\\src\\serial_core (Files) | 4 | 92 | 0 | 20 | 112 |
| src-tauri\\src\\serial_core\\codecs | 2 | 155 | 1 | 9 | 165 |
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)

View File

@@ -1,35 +0,0 @@
Date : 2026-04-02 14:42:07
Directory : e:\Workspace\JE-Skin
Total : 6 files, 247 codes, 1 comments, 29 blanks, all 277 lines
Languages
+----------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+----------+------------+------------+------------+------------+------------+
| Rust | 6 | 247 | 1 | 29 | 277 |
+----------+------------+------------+------------+------------+------------+
Directories
+--------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+--------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| . | 6 | 247 | 1 | 29 | 277 |
| src-tauri | 6 | 247 | 1 | 29 | 277 |
| src-tauri\src | 6 | 247 | 1 | 29 | 277 |
| src-tauri\src\serial_core | 6 | 247 | 1 | 29 | 277 |
| src-tauri\src\serial_core (Files) | 4 | 92 | 0 | 20 | 112 |
| src-tauri\src\serial_core\codecs | 2 | 155 | 1 | 9 | 165 |
+--------------------------------------------------------------------------+------------+------------+------------+------------+------------+
Files
+--------------------------------------------------------------------------+----------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+--------------------------------------------------------------------------+----------+------------+------------+------------+------------+
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs | Rust | 153 | 0 | 11 | 164 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs | Rust | 2 | 1 | -2 | 1 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs | Rust | 2 | 0 | 0 | 2 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs | Rust | 1 | 0 | -1 | 0 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs | Rust | 68 | 0 | 14 | 82 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs | Rust | 21 | 0 | 7 | 28 |
| Total | | 247 | 1 | 29 | 277 |
+--------------------------------------------------------------------------+----------+------------+------------+------------+------------+

View File

@@ -1,49 +0,0 @@
"filename", "language", "Markdown", "JSON with Comments", "JSON", "XML", "JavaScript", "HTML", "Rust", "TypeScript", "Svelte", "PostCSS", "comment", "blank", "total"
"e:\Workspace\JE-Skin\.idea\modules.xml", "XML", 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8
"e:\Workspace\JE-Skin\.idea\tauri-demo.iml", "XML", 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 11
"e:\Workspace\JE-Skin\README.md", "Markdown", 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 54
"e:\Workspace\JE-Skin\flowus_tools.json", "JSON", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2
"e:\Workspace\JE-Skin\frontend_prompt.md", "Markdown", 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 255
"e:\Workspace\JE-Skin\package-lock.json", "JSON", 0, 0, 1957, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1958
"e:\Workspace\JE-Skin\package.json", "JSON", 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32
"e:\Workspace\JE-Skin\src-tauri\build.rs", "Rust", 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 4
"e:\Workspace\JE-Skin\src-tauri\capabilities\default.json", "JSON", 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16
"e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 3
"e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 44, 290
"e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs", "Rust", 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 6, 33
"e:\Workspace\JE-Skin\src-tauri\src\lib.rs", "Rust", 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 2, 24
"e:\Workspace\JE-Skin\src-tauri\src\log.rs", "Rust", 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 2, 36
"e:\Workspace\JE-Skin\src-tauri\src\main.rs", "Rust", 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 2, 11
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs", "Rust", 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 5
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs", "Rust", 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 28, 248
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs", "Rust", 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 8, 38, 261
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs", "Rust", 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 6, 55
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs", "Rust", 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 3, 8, 58
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs", "Rust", 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 7, 29
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs", "Rust", 0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 57, 67, 501
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs", "Rust", 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 4, 11, 65
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs", "Rust", 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 22, 163
"e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs", "Rust", 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 13, 60
"e:\Workspace\JE-Skin\src-tauri\tauri.conf.json", "JSON", 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 1, 37
"e:\Workspace\JE-Skin\src\app.html", "HTML", 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 1, 14
"e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 691, 0, 0, 96, 787
"e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 63, 461
"e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 861, 0, 0, 110, 971
"e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 97, 655
"e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 382, 0, 0, 71, 453
"e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 497, 0, 0, 88, 585
"e:\Workspace\JE-Skin\src\lib\config\color-map.ts", "TypeScript", 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 3, 58
"e:\Workspace\JE-Skin\src\lib\styles\theme.css", "PostCSS", 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 1, 7, 51
"e:\Workspace\JE-Skin\src\lib\types\hud.ts", "TypeScript", 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 20, 146
"e:\Workspace\JE-Skin\src\routes\+layout.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 5, 18
"e:\Workspace\JE-Skin\src\routes\+layout.ts", "TypeScript", 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 1, 6
"e:\Workspace\JE-Skin\src\routes\+page.svelte", "Svelte", 0, 0, 0, 0, 0, 0, 0, 0, 1286, 0, 0, 176, 1462
"e:\Workspace\JE-Skin\static\svelte.svg", "XML", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\static\tauri.svg", "XML", 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 7
"e:\Workspace\JE-Skin\static\vite.svg", "XML", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1
"e:\Workspace\JE-Skin\svelte.config.js", "JavaScript", 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 5, 3, 19
"e:\Workspace\JE-Skin\tauri-event.md", "Markdown", 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 555
"e:\Workspace\JE-Skin\tsconfig.json", "JSON with Comments", 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 20
"e:\Workspace\JE-Skin\vite.config.js", "JavaScript", 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 7, 4, 33
"Total", "-", 597, 14, 2040, 27, 33, 13, 1520, 182, 4686, 43, 95, 1279, 10529
1 filename language Markdown JSON with Comments JSON XML JavaScript HTML Rust TypeScript Svelte PostCSS comment blank total
2 e:\Workspace\JE-Skin\.idea\modules.xml XML 0 0 0 8 0 0 0 0 0 0 0 0 8
3 e:\Workspace\JE-Skin\.idea\tauri-demo.iml XML 0 0 0 11 0 0 0 0 0 0 0 0 11
4 e:\Workspace\JE-Skin\README.md Markdown 34 0 0 0 0 0 0 0 0 0 0 20 54
5 e:\Workspace\JE-Skin\flowus_tools.json JSON 0 0 1 0 0 0 0 0 0 0 0 1 2
6 e:\Workspace\JE-Skin\frontend_prompt.md Markdown 189 0 0 0 0 0 0 0 0 0 0 66 255
7 e:\Workspace\JE-Skin\package-lock.json JSON 0 0 1957 0 0 0 0 0 0 0 0 1 1958
8 e:\Workspace\JE-Skin\package.json JSON 0 0 31 0 0 0 0 0 0 0 0 1 32
9 e:\Workspace\JE-Skin\src-tauri\build.rs Rust 0 0 0 0 0 0 3 0 0 0 0 1 4
10 e:\Workspace\JE-Skin\src-tauri\capabilities\default.json JSON 0 0 15 0 0 0 0 0 0 0 0 1 16
11 e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs Rust 0 0 0 0 0 0 2 0 0 0 0 1 3
12 e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs Rust 0 0 0 0 0 0 246 0 0 0 0 44 290
13 e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs Rust 0 0 0 0 0 0 27 0 0 0 0 6 33
14 e:\Workspace\JE-Skin\src-tauri\src\lib.rs Rust 0 0 0 0 0 0 22 0 0 0 0 2 24
15 e:\Workspace\JE-Skin\src-tauri\src\log.rs Rust 0 0 0 0 0 0 34 0 0 0 0 2 36
16 e:\Workspace\JE-Skin\src-tauri\src\main.rs Rust 0 0 0 0 0 0 8 0 0 0 1 2 11
17 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs Rust 0 0 0 0 0 0 6 0 0 0 0 1 7
18 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs Rust 0 0 0 0 0 0 4 0 0 0 0 1 5
19 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs Rust 0 0 0 0 0 0 220 0 0 0 0 28 248
20 e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs Rust 0 0 0 0 0 0 215 0 0 0 8 38 261
21 e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs Rust 0 0 0 0 0 0 49 0 0 0 0 6 55
22 e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs Rust 0 0 0 0 0 0 47 0 0 0 3 8 58
23 e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs Rust 0 0 0 0 0 0 22 0 0 0 0 7 29
24 e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs Rust 0 0 0 0 0 0 377 0 0 0 57 67 501
25 e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs Rust 0 0 0 0 0 0 50 0 0 0 4 11 65
26 e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs Rust 0 0 0 0 0 0 141 0 0 0 0 22 163
27 e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs Rust 0 0 0 0 0 0 47 0 0 0 0 13 60
28 e:\Workspace\JE-Skin\src-tauri\tauri.conf.json JSON 0 0 36 0 0 0 0 0 0 0 0 1 37
29 e:\Workspace\JE-Skin\src\app.html HTML 0 0 0 0 0 13 0 0 0 0 0 1 14
30 e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte Svelte 0 0 0 0 0 0 0 0 691 0 0 96 787
31 e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte Svelte 0 0 0 0 0 0 0 0 398 0 0 63 461
32 e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte Svelte 0 0 0 0 0 0 0 0 861 0 0 110 971
33 e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte Svelte 0 0 0 0 0 0 0 0 558 0 0 97 655
34 e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte Svelte 0 0 0 0 0 0 0 0 382 0 0 71 453
35 e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte Svelte 0 0 0 0 0 0 0 0 497 0 0 88 585
36 e:\Workspace\JE-Skin\src\lib\config\color-map.ts TypeScript 0 0 0 0 0 0 0 55 0 0 0 3 58
37 e:\Workspace\JE-Skin\src\lib\styles\theme.css PostCSS 0 0 0 0 0 0 0 0 0 43 1 7 51
38 e:\Workspace\JE-Skin\src\lib\types\hud.ts TypeScript 0 0 0 0 0 0 0 126 0 0 0 20 146
39 e:\Workspace\JE-Skin\src\routes\+layout.svelte Svelte 0 0 0 0 0 0 0 0 13 0 0 5 18
40 e:\Workspace\JE-Skin\src\routes\+layout.ts TypeScript 0 0 0 0 0 0 0 1 0 0 4 1 6
41 e:\Workspace\JE-Skin\src\routes\+page.svelte Svelte 0 0 0 0 0 0 0 0 1286 0 0 176 1462
42 e:\Workspace\JE-Skin\static\svelte.svg XML 0 0 0 1 0 0 0 0 0 0 0 0 1
43 e:\Workspace\JE-Skin\static\tauri.svg XML 0 0 0 6 0 0 0 0 0 0 0 1 7
44 e:\Workspace\JE-Skin\static\vite.svg XML 0 0 0 1 0 0 0 0 0 0 0 0 1
45 e:\Workspace\JE-Skin\svelte.config.js JavaScript 0 0 0 0 11 0 0 0 0 0 5 3 19
46 e:\Workspace\JE-Skin\tauri-event.md Markdown 374 0 0 0 0 0 0 0 0 0 0 181 555
47 e:\Workspace\JE-Skin\tsconfig.json JSON with Comments 0 14 0 0 0 0 0 0 0 0 5 1 20
48 e:\Workspace\JE-Skin\vite.config.js JavaScript 0 0 0 0 22 0 0 0 0 0 7 4 33
49 Total - 597 14 2040 27 33 13 1520 182 4686 43 95 1279 10529

File diff suppressed because one or more lines are too long

View File

@@ -1,50 +0,0 @@
# Summary
Date : 2026-04-02 14:42:07
Directory e:\\Workspace\\JE-Skin
Total : 47 files, 9155 codes, 95 comments, 1279 blanks, all 10529 lines
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,520 | 73 | 260 | 1,853 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| . | 47 | 9,155 | 95 | 1,279 | 10,529 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,571 | 73 | 262 | 1,906 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\\src | 17 | 1,517 | 73 | 259 | 1,849 |
| src-tauri\\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\\src\\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\\src\\serial_core | 11 | 1,178 | 72 | 202 | 1,452 |
| src-tauri\\src\\serial_core (Files) | 8 | 739 | 64 | 135 | 938 |
| src-tauri\\src\\serial_core\\codecs | 3 | 439 | 8 | 67 | 514 |
| src\\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\\lib\\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\\lib\\config | 1 | 55 | 0 | 3 | 58 |
| src\\lib\\styles | 1 | 43 | 1 | 7 | 51 |
| src\\lib\\types | 1 | 126 | 0 | 20 | 146 |
| src\\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@@ -1,100 +0,0 @@
Date : 2026-04-02 14:42:07
Directory : e:\Workspace\JE-Skin
Total : 47 files, 9155 codes, 95 comments, 1279 blanks, all 10529 lines
Languages
+--------------------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+--------------------+------------+------------+------------+------------+------------+
| Svelte | 8 | 4,686 | 0 | 706 | 5,392 |
| JSON | 5 | 2,040 | 0 | 5 | 2,045 |
| Rust | 18 | 1,520 | 73 | 260 | 1,853 |
| Markdown | 3 | 597 | 0 | 267 | 864 |
| TypeScript | 3 | 182 | 4 | 24 | 210 |
| PostCSS | 1 | 43 | 1 | 7 | 51 |
| JavaScript | 2 | 33 | 12 | 7 | 52 |
| XML | 5 | 27 | 0 | 1 | 28 |
| JSON with Comments | 1 | 14 | 5 | 1 | 20 |
| HTML | 1 | 13 | 0 | 1 | 14 |
+--------------------+------------+------------+------------+------------+------------+
Directories
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| . | 47 | 9,155 | 95 | 1,279 | 10,529 |
| . (Files) | 9 | 2,633 | 17 | 278 | 2,928 |
| .idea | 2 | 19 | 0 | 0 | 19 |
| src | 13 | 4,924 | 5 | 738 | 5,667 |
| src (Files) | 1 | 13 | 0 | 1 | 14 |
| src-tauri | 20 | 1,571 | 73 | 262 | 1,906 |
| src-tauri (Files) | 2 | 39 | 0 | 2 | 41 |
| src-tauri\capabilities | 1 | 15 | 0 | 1 | 16 |
| src-tauri\src | 17 | 1,517 | 73 | 259 | 1,849 |
| src-tauri\src (Files) | 3 | 64 | 1 | 6 | 71 |
| src-tauri\src\commands | 3 | 275 | 0 | 51 | 326 |
| src-tauri\src\serial_core | 11 | 1,178 | 72 | 202 | 1,452 |
| src-tauri\src\serial_core (Files) | 8 | 739 | 64 | 135 | 938 |
| src-tauri\src\serial_core\codecs | 3 | 439 | 8 | 67 | 514 |
| src\lib | 9 | 3,611 | 1 | 555 | 4,167 |
| src\lib\components | 6 | 3,387 | 0 | 525 | 3,912 |
| src\lib\config | 1 | 55 | 0 | 3 | 58 |
| src\lib\styles | 1 | 43 | 1 | 7 | 51 |
| src\lib\types | 1 | 126 | 0 | 20 | 146 |
| src\routes | 3 | 1,300 | 4 | 182 | 1,486 |
| static | 3 | 8 | 0 | 1 | 9 |
+---------------------------------------------------------------------------+------------+------------+------------+------------+------------+
Files
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+
| e:\Workspace\JE-Skin\.idea\modules.xml | XML | 8 | 0 | 0 | 8 |
| e:\Workspace\JE-Skin\.idea\tauri-demo.iml | XML | 11 | 0 | 0 | 11 |
| e:\Workspace\JE-Skin\README.md | Markdown | 34 | 0 | 20 | 54 |
| e:\Workspace\JE-Skin\flowus_tools.json | JSON | 1 | 0 | 1 | 2 |
| e:\Workspace\JE-Skin\frontend_prompt.md | Markdown | 189 | 0 | 66 | 255 |
| e:\Workspace\JE-Skin\package-lock.json | JSON | 1,957 | 0 | 1 | 1,958 |
| e:\Workspace\JE-Skin\package.json | JSON | 31 | 0 | 1 | 32 |
| e:\Workspace\JE-Skin\src-tauri\build.rs | Rust | 3 | 0 | 1 | 4 |
| e:\Workspace\JE-Skin\src-tauri\capabilities\default.json | JSON | 15 | 0 | 1 | 16 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\mod.rs | Rust | 2 | 0 | 1 | 3 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\serial.rs | Rust | 246 | 0 | 44 | 290 |
| e:\Workspace\JE-Skin\src-tauri\src\commands\window.rs | Rust | 27 | 0 | 6 | 33 |
| e:\Workspace\JE-Skin\src-tauri\src\lib.rs | Rust | 22 | 0 | 2 | 24 |
| e:\Workspace\JE-Skin\src-tauri\src\log.rs | Rust | 34 | 0 | 2 | 36 |
| e:\Workspace\JE-Skin\src-tauri\src\main.rs | Rust | 8 | 1 | 2 | 11 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codec.rs | Rust | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\mod.rs | Rust | 4 | 0 | 1 | 5 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\tactile_a.rs | Rust | 220 | 0 | 28 | 248 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\codecs\test.rs | Rust | 215 | 8 | 38 | 261 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\error.rs | Rust | 49 | 0 | 6 | 55 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\frame.rs | Rust | 47 | 3 | 8 | 58 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\mod.rs | Rust | 22 | 0 | 7 | 29 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\model.rs | Rust | 377 | 57 | 67 | 501 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\record.rs | Rust | 50 | 4 | 11 | 65 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\serial.rs | Rust | 141 | 0 | 22 | 163 |
| e:\Workspace\JE-Skin\src-tauri\src\serial_core\utils.rs | Rust | 47 | 0 | 13 | 60 |
| e:\Workspace\JE-Skin\src-tauri\tauri.conf.json | JSON | 36 | 0 | 1 | 37 |
| e:\Workspace\JE-Skin\src\app.html | HTML | 13 | 0 | 1 | 14 |
| e:\Workspace\JE-Skin\src\lib\components\CenterStage.svelte | Svelte | 691 | 0 | 96 | 787 |
| e:\Workspace\JE-Skin\src\lib\components\ConfigPanel.svelte | Svelte | 398 | 0 | 63 | 461 |
| e:\Workspace\JE-Skin\src\lib\components\HudPanel.svelte | Svelte | 861 | 0 | 110 | 971 |
| e:\Workspace\JE-Skin\src\lib\components\PressureMatrixViewer.svelte | Svelte | 558 | 0 | 97 | 655 |
| e:\Workspace\JE-Skin\src\lib\components\SignalChart.svelte | Svelte | 382 | 0 | 71 | 453 |
| e:\Workspace\JE-Skin\src\lib\components\SummaryCurve.svelte | Svelte | 497 | 0 | 88 | 585 |
| e:\Workspace\JE-Skin\src\lib\config\color-map.ts | TypeScript | 55 | 0 | 3 | 58 |
| e:\Workspace\JE-Skin\src\lib\styles\theme.css | PostCSS | 43 | 1 | 7 | 51 |
| e:\Workspace\JE-Skin\src\lib\types\hud.ts | TypeScript | 126 | 0 | 20 | 146 |
| e:\Workspace\JE-Skin\src\routes\+layout.svelte | Svelte | 13 | 0 | 5 | 18 |
| e:\Workspace\JE-Skin\src\routes\+layout.ts | TypeScript | 1 | 4 | 1 | 6 |
| e:\Workspace\JE-Skin\src\routes\+page.svelte | Svelte | 1,286 | 0 | 176 | 1,462 |
| e:\Workspace\JE-Skin\static\svelte.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\static\tauri.svg | XML | 6 | 0 | 1 | 7 |
| e:\Workspace\JE-Skin\static\vite.svg | XML | 1 | 0 | 0 | 1 |
| e:\Workspace\JE-Skin\svelte.config.js | JavaScript | 11 | 5 | 3 | 19 |
| e:\Workspace\JE-Skin\tauri-event.md | Markdown | 374 | 0 | 181 | 555 |
| e:\Workspace\JE-Skin\tsconfig.json | JSON with Comments | 14 | 5 | 1 | 20 |
| e:\Workspace\JE-Skin\vite.config.js | JavaScript | 22 | 7 | 4 | 33 |
| Total | | 9,155 | 95 | 1,279 | 10,529 |
+---------------------------------------------------------------------------+--------------------+------------+------------+------------+------------+

37
.gitignore vendored
View File

@@ -1,10 +1,39 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
Thumbs.db
.idea/
.vscode/
.VSCodeCounter/
.codex
/node_modules/
.env
.env.*
!.env.example
/build/
/package/
/.svelte-kit/
/.vite/
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
*.tsbuildinfo
/target/
/target-codex-check*/
/src-tauri/target/
/src-tauri/target-codex-check*/
/src-tauri/gen/schemas/
/src-tauri/gen/android/app/build/
/src-tauri/gen/android/buildSrc/build/
/src-tauri/gen/android/.gradle/
/src-tauri/gen/android/app/.gradle/
/src-tauri/gen/android/buildSrc/.gradle/
/src-tauri/gen/android/build/reports/
/src-tauri/program.log*
/src-tauri/recording_replay_debug_*.csv
npm-debug.log*
yarn-debug.log*
pnpm-debug.log*

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "eskin-finger-sdk"]
path = eskin-finger-sdk
url = https://gitea.e-skin.top/yanjie/eskin-finger-sdk.git

10
.idea/.gitignore generated vendored
View File

@@ -1,10 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tauri-demo.iml" filepath="$PROJECT_DIR$/.idea/tauri-demo.iml" />
</modules>
</component>
</project>

11
.idea/tauri-demo.iml generated
View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src-tauri/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/src-tauri/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,7 +0,0 @@
{
"recommendations": [
"svelte.svelte-vscode",
"tauri-apps.tauri-vscode",
"rust-lang.rust-analyzer"
]
}

View File

@@ -1,3 +0,0 @@
{
"svelte.enable-ts-plugin": true
}

Binary file not shown.

24
devkit/build_server.bat Normal file
View File

@@ -0,0 +1,24 @@
@echo off
REM ── JE-Skin DevKit: 打包 Python gRPC server 为 exe ──
REM 前提: pip install pyinstaller grpcio grpcio-tools numpy openpyxl
echo [1/3] Generating gRPC stubs...
python -m grpc_tools.protoc ^
-I../src-tauri/proto ^
--python_out=. ^
--grpc_python_out=. ^
../src-tauri/proto/sensor_stream.proto
echo [2/3] Building exe with PyInstaller...
pyinstaller ^
--onefile ^
--name je-skin-devkit-server ^
--add-data "sensor_stream_pb2*.py;." ^
--hidden-import grpc ^
--hidden-import openpyxl ^
--noconfirm ^
sensor_server.py
echo [3/3] Done!
echo Output: dist/je-skin-devkit-server.exe
pause

View File

@@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['sensor_server.py'],
pathex=[],
binaries=[],
datas=[('sensor_stream_pb2.py', '.'), ('sensor_stream_pb2_grpc.py', '.')],
hiddenimports=['grpc', 'openpyxl', 'numpy'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='je-skin-devkit-server',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

467
devkit/sensor_server.py Normal file
View File

@@ -0,0 +1,467 @@
"""
JE-Skin DevKit — Python gRPC Sensor Server
提供两个服务:
1. SensorPush (streaming) — 接收实时传感器帧
2. ExportProcessor (unary) — 处理导出的 CSV 文件梯度过滤、xlsx 转换
安装依赖:
pip install grpcio grpcio-tools openpyxl
生成 gRPC 代码:
python -m grpc_tools.protoc -I../src-tauri/proto --python_out=. --grpc_python_out=. ../src-tauri/proto/sensor_stream.proto
启动:
python sensor_server.py [--port 50051]
"""
from __future__ import annotations
import argparse
import csv
import os
import signal
import statistics
import sys
import time
from concurrent import futures
from pathlib import Path
import grpc
import sensor_stream_pb2
import sensor_stream_pb2_grpc
# ── 梯度过滤逻辑(来自用户的 main.py ─────────────────────────
def load_rows(path: Path) -> list[list[str]]:
with path.open("r", encoding="utf-8-sig", newline="") as f:
return [row for row in csv.reader(f) if row]
def row_sum(row: list[str]) -> float:
return sum(float(v) for v in row[1:] if v.strip())
def find_threshold(sum_values: list[float]) -> float:
if len(sum_values) < 2:
raise ValueError("At least two rows are required.")
sorted_v = sorted(sum_values)
idx = max(
range(len(sorted_v) - 1),
key=lambda i: sorted_v[i + 1] - sorted_v[i],
)
return (sorted_v[idx] + sorted_v[idx + 1]) / 2.0
def extract_press_groups(
rows: list[list[str]], sum_values: list[float], threshold: float
) -> tuple[list[list[str]], list[float]]:
filtered: list[list[str]] = []
group_means: list[float] = []
current_group: list[float] = []
for row, total in zip(rows, sum_values):
if total >= threshold:
filtered.append(row)
current_group.append(total)
continue
if current_group:
group_means.append(statistics.fmean(current_group))
current_group = []
if current_group:
group_means.append(statistics.fmean(current_group))
return filtered, group_means
def write_csv(path: Path, rows: list[list[str]]) -> Path:
out = path.with_name(f"{path.stem}_filtered.csv")
with out.open("w", encoding="utf-8-sig", newline="") as f:
csv.writer(f).writerows(rows)
return out
def write_xlsx(path: Path, rows: list[list[str]], stats: dict) -> Path:
"""将过滤后的数据和统计信息写入 xlsx"""
try:
import openpyxl
except ImportError:
raise RuntimeError("openpyxl is required for xlsx output. Install it with: pip install openpyxl")
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
wb = openpyxl.Workbook()
# Sheet 1: 过滤后的数据
ws_data = wb.active
ws_data.title = "Filtered Data"
for row in rows:
ws_data.append([float(c) if c.strip().replace(".", "").replace("-", "").isdigit() else c for c in row])
# Sheet 2: 统计信息
ws_stats = wb.create_sheet("Statistics")
header_font = Font(bold=True, size=11)
header_fill = PatternFill(start_color="E0E0E0", end_color="E0E0E0", fill_type="solid")
ws_stats.append(["Parameter", "Value"])
ws_stats["A1"].font = header_font
ws_stats["A1"].fill = header_fill
ws_stats["B1"].font = header_font
ws_stats["B1"].fill = header_fill
stats_rows = [
("Source File", stats.get("source_file", "")),
("Total Rows", stats.get("rows_total", 0)),
("Filtered Rows", stats.get("rows_kept", 0)),
("Groups Used", stats.get("groups_used", 0)),
("Mean Value", f"{stats.get('mean_value', 0):.3f}"),
("Threshold", f"{stats.get('threshold', 0):.3f}"),
("Process Time", stats.get("process_time", "")),
]
for label, value in stats_rows:
ws_stats.append([label, value])
ws_stats.column_dimensions["A"].width = 18
ws_stats.column_dimensions["B"].width = 30
out = path.with_name(f"{path.stem}_filtered.xlsx")
wb.save(str(out))
return out
def process_csv(csv_path: str, save_as_xlsx: bool) -> dict:
"""执行梯度过滤,返回结果统计"""
path = Path(csv_path)
if not path.is_file():
raise FileNotFoundError(f"CSV file not found: {csv_path}")
rows = load_rows(path)
if not rows:
raise ValueError("CSV file is empty.")
sum_values = [row_sum(r) for r in rows]
threshold = find_threshold(sum_values)
filtered_rows, group_means = extract_press_groups(rows, sum_values, threshold)
if not filtered_rows:
raise ValueError("No large press-down data was found.")
overall_mean = statistics.fmean(group_means)
stats = {
"source_file": path.name,
"rows_total": len(rows),
"rows_kept": len(filtered_rows),
"groups_used": len(group_means),
"mean_value": overall_mean,
"threshold": threshold,
"process_time": time.strftime("%Y-%m-%d %H:%M:%S"),
}
if save_as_xlsx:
output_path = write_xlsx(path, filtered_rows, stats)
# 删除源 CSV
try:
path.unlink()
except OSError:
pass
else:
output_path = write_csv(path, filtered_rows)
# 用过滤后的文件替换源文件
try:
path.unlink()
output_path.rename(path)
output_path = path
except OSError:
pass
# 追加一行到汇总 xlsx
_append_analysis_log(csv_path, stats)
return {
"ok": True,
"output_path": str(output_path),
"groups_used": len(group_means),
"mean_value": overall_mean,
"threshold": threshold,
"rows_total": len(rows),
"rows_kept": len(filtered_rows),
"message": "OK",
}
def _append_analysis_log(source_csv: str, stats: dict):
"""将处理结果追加到 devkit_analysis_results.xlsx"""
try:
import openpyxl
except ImportError:
return # openpyxl 不可用时跳过
log_path = Path(source_csv).parent / "devkit_analysis_results.xlsx"
if log_path.exists():
wb = openpyxl.load_workbook(str(log_path))
ws = wb.active
else:
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "Analysis Log"
ws.append(["Time", "Source File", "Total Rows", "Kept Rows",
"Groups", "Mean Value", "Threshold", "Output File"])
ws.append([
stats.get("process_time", ""),
stats.get("source_file", ""),
stats.get("rows_total", 0),
stats.get("rows_kept", 0),
stats.get("groups_used", 0),
round(stats.get("mean_value", 0), 3),
round(stats.get("threshold", 0), 3),
f"{Path(stats.get('source_file', '')).stem}_filtered",
])
wb.save(str(log_path))
# ── gRPC 服务实现 ────────────────────────────────────────────────
class SensorPushServicer(sensor_stream_pb2_grpc.SensorPushServicer):
"""接收实时传感器帧streaming"""
def __init__(self):
self.frame_count = 0
self.last_report_time = time.time()
self.last_angle = None
def Upload(self, request_iterator, context):
print("[SensorPush] Client connected, waiting for frames...")
reset_baseline()
self.last_angle = None
for frame in request_iterator:
self.frame_count += 1
angle = 0.0
ok = True
message = "OK"
if len(frame.matrix) == SENSOR_ROWS * SENSOR_COLS:
try:
angle = get_pzt_angle(frame.matrix)
self.last_angle = angle
if self.frame_count <= 10 or self.frame_count % 30 == 0:
print(
f"[SensorPush] PZT angle frame #{frame.seq} "
f"dts={frame.dts_ms} angle={angle:.2f}"
)
except Exception as e:
ok = False
message = str(e)
print(f"[SensorPush] PZT compute error on frame #{frame.seq}: {e}")
else:
ok = False
message = f"Invalid matrix length: {len(frame.matrix)}"
yield sensor_stream_pb2.PztAngleResponse(
seq=frame.seq,
timestamp_ms=frame.timestamp_ms,
angle=angle,
dts_ms=frame.dts_ms,
ok=ok,
message=message,
)
if self.frame_count % 100 == 0:
now = time.time()
elapsed = now - self.last_report_time
fps = 100 / elapsed if elapsed > 0 else 0
self.last_report_time = now
angle_text = (
f"{self.last_angle:.2f}"
if self.last_angle is not None
else "n/a"
)
print(
f"[SensorPush] Frame #{frame.seq} | "
f"{frame.rows}x{frame.cols} | "
f"angle={angle_text} | "
f"force={frame.resultant_force:.1f} | "
f"total={self.frame_count} | ~{fps:.1f} fps"
)
print(f"[SensorPush] Stream ended. Total: {self.frame_count}")
class ExportProcessorServicer(sensor_stream_pb2_grpc.ExportProcessorServicer):
"""处理导出的 CSV 文件unary"""
def ProcessFile(self, request, context):
csv_path = request.csv_path
save_as_xlsx = request.save_as_xlsx
print(f"[ExportProcessor] Processing: {csv_path} (xlsx={save_as_xlsx})")
try:
result = process_csv(csv_path, save_as_xlsx)
return sensor_stream_pb2.ProcessResponse(
ok=result["ok"],
output_path=result["output_path"],
groups_used=result["groups_used"],
mean_value=result["mean_value"],
threshold=result["threshold"],
rows_total=result["rows_total"],
rows_kept=result["rows_kept"],
message=result["message"],
)
except Exception as e:
print(f"[ExportProcessor] Error: {e}")
return sensor_stream_pb2.ProcessResponse(
ok=False,
output_path="",
message=str(e),
)
# ── 启动 ────────────────────────────────────────────────────────
def serve(port: int):
server = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
sensor_stream_pb2_grpc.add_SensorPushServicer_to_server(SensorPushServicer(), server)
sensor_stream_pb2_grpc.add_ExportProcessorServicer_to_server(ExportProcessorServicer(), server)
listen_addr = f"0.0.0.0:{port}"
server.add_insecure_port(listen_addr)
server.start()
print(f"[DevKit Server] gRPC listening on {listen_addr}")
print(f"[DevKit Server] Services: SensorPush (streaming), ExportProcessor (unary)")
def shutdown(signum, frame):
print("\n[DevKit Server] Shutting down...")
server.stop(grace=5)
sys.exit(0)
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)
server.wait_for_termination()
import numpy as np
import threading
# ===================== 算法参数=====================
TOTAL_PRESSURE_LOW_THRESHOLD = 500
COP_STABILITY_FRAMES_REQUIRED = 5
SENSOR_ROWS = 12
SENSOR_COLS = 7
# ===================== 线程安全全局状态 =====================
first_frame = None
first_frame_lock = threading.Lock()
first_contact_CoP_x = None
first_contact_CoP_y = None
contact_initialized = False
total_pressure_low_counter = 0
# ===================== 基线减除 =====================
def subtract_baseline(current_frame):
global first_frame
current_frame = np.array(current_frame, dtype=np.float32).flatten()
with first_frame_lock:
if first_frame is None:
first_frame = current_frame.copy()
diff = current_frame - first_frame
return np.clip(diff, 0, None)
# ===================== 重置CoP状态 =====================
def reset_cop_state():
global first_contact_CoP_x, first_contact_CoP_y, contact_initialized
global total_pressure_low_counter
first_contact_CoP_x = None
first_contact_CoP_y = None
contact_initialized = False
total_pressure_low_counter = 0
# ===================== CoP压力中心计算 =====================
def compute_pressure_direction(baseline_subtracted_frame):
global first_contact_CoP_x, first_contact_CoP_y, contact_initialized
global total_pressure_low_counter
rows, cols = SENSOR_ROWS, SENSOR_COLS
frame_flat = np.asarray(baseline_subtracted_frame, dtype=np.float32).flatten()
frame2d = frame_flat.reshape(rows, cols)
total_pressure = np.sum(frame2d)
if total_pressure < TOTAL_PRESSURE_LOW_THRESHOLD:
total_pressure_low_counter += 1
else:
total_pressure_low_counter = 0
if total_pressure_low_counter >= COP_STABILITY_FRAMES_REQUIRED:
reset_cop_state()
return 0.0, 0.0
if total_pressure == 0:
return 0.0, 0.0
x_grid = np.tile(np.arange(cols), (rows, 1))
y_grid = np.repeat(np.arange(rows), cols).reshape(rows, cols)
cop_x = np.sum(frame2d * x_grid) / total_pressure
cop_y = np.sum(frame2d * y_grid) / total_pressure
delta_CoP_x = 0.0
delta_CoP_y = 0.0
if not contact_initialized:
first_contact_CoP_x = cop_x
first_contact_CoP_y = cop_y
contact_initialized = True
else:
delta_CoP_x = cop_x - first_contact_CoP_x
delta_CoP_y = cop_y - first_contact_CoP_y
return delta_CoP_x, delta_CoP_y
# ===================== 角度计算核心 =====================
def compute_vector_angle(x: float, y: float) -> tuple[float, float]:
epsilon = 1e-8
mag = np.hypot(x, y)
angle = np.degrees(np.arctan2(y, x + epsilon))
if angle < 0:
angle += 360
return angle, mag
def compute_PZT_angle(Px: float, Py: float) -> tuple[float, float]:
return compute_vector_angle(Px, -Py)
# ===================== 核心入口函数 =====================
def get_pzt_angle(adc_data):
if len(adc_data) != 84:
raise ValueError("ADC数据长度必须为84")
baseline_subtracted = subtract_baseline(adc_data)
dx, dy = compute_pressure_direction(baseline_subtracted)
pzt_angle, _ = compute_PZT_angle(dx, dy)
return pzt_angle
# ===================== 重置基线(校准用) =====================
def reset_baseline():
global first_frame
with first_frame_lock:
first_frame = None
reset_cop_state()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="JE-Skin DevKit gRPC Server")
parser.add_argument("--port", type=int, default=50051, help="gRPC listen port (default: 50051)")
args = parser.parse_args()
serve(args.port)

View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: sensor_stream.proto
# Protobuf Python Version: 6.31.1
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
6,
31,
1,
'',
'sensor_stream.proto'
)
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13sensor_stream.proto\x12\rsensor_stream\"\x85\x01\n\x0bSensorFrame\x12\x0b\n\x03seq\x18\x01 \x01(\x04\x12\x14\n\x0ctimestamp_ms\x18\x02 \x01(\x04\x12\x0c\n\x04rows\x18\x03 \x01(\r\x12\x0c\n\x04\x63ols\x18\x04 \x01(\r\x12\x0e\n\x06matrix\x18\x05 \x03(\r\x12\x17\n\x0fresultant_force\x18\x06 \x01(\x01\x12\x0e\n\x06\x64ts_ms\x18\x07 \x01(\r\"q\n\x10PztAngleResponse\x12\x0b\n\x03seq\x18\x01 \x01(\x04\x12\x14\n\x0ctimestamp_ms\x18\x02 \x01(\x04\x12\r\n\x05\x61ngle\x18\x03 \x01(\x02\x12\x0e\n\x06\x64ts_ms\x18\x04 \x01(\r\x12\n\n\x02ok\x18\x05 \x01(\x08\x12\x0f\n\x07message\x18\x06 \x01(\t\"8\n\x0eProcessRequest\x12\x10\n\x08\x63sv_path\x18\x01 \x01(\t\x12\x14\n\x0csave_as_xlsx\x18\x02 \x01(\x08\"\xa6\x01\n\x0fProcessResponse\x12\n\n\x02ok\x18\x01 \x01(\x08\x12\x13\n\x0boutput_path\x18\x02 \x01(\t\x12\x13\n\x0bgroups_used\x18\x03 \x01(\r\x12\x12\n\nmean_value\x18\x04 \x01(\x01\x12\x11\n\tthreshold\x18\x05 \x01(\x01\x12\x12\n\nrows_total\x18\x06 \x01(\r\x12\x11\n\trows_kept\x18\x07 \x01(\r\x12\x0f\n\x07message\x18\x08 \x01(\t2W\n\nSensorPush\x12I\n\x06Upload\x12\x1a.sensor_stream.SensorFrame\x1a\x1f.sensor_stream.PztAngleResponse(\x01\x30\x01\x32_\n\x0f\x45xportProcessor\x12L\n\x0bProcessFile\x12\x1d.sensor_stream.ProcessRequest\x1a\x1e.sensor_stream.ProcessResponseb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'sensor_stream_pb2', _globals)
if not _descriptor._USE_C_DESCRIPTORS:
DESCRIPTOR._loaded_options = None
_globals['_SENSORFRAME']._serialized_start=39
_globals['_SENSORFRAME']._serialized_end=172
_globals['_PZTANGLERESPONSE']._serialized_start=174
_globals['_PZTANGLERESPONSE']._serialized_end=287
_globals['_PROCESSREQUEST']._serialized_start=289
_globals['_PROCESSREQUEST']._serialized_end=345
_globals['_PROCESSRESPONSE']._serialized_start=348
_globals['_PROCESSRESPONSE']._serialized_end=514
_globals['_SENSORPUSH']._serialized_start=516
_globals['_SENSORPUSH']._serialized_end=603
_globals['_EXPORTPROCESSOR']._serialized_start=605
_globals['_EXPORTPROCESSOR']._serialized_end=700
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,169 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import warnings
import sensor_stream_pb2 as sensor__stream__pb2
GRPC_GENERATED_VERSION = '1.80.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False
try:
from grpc._utilities import first_version_is_lower
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
except ImportError:
_version_not_supported = True
if _version_not_supported:
raise RuntimeError(
f'The grpc package installed is at version {GRPC_VERSION},'
+ ' but the generated code in sensor_stream_pb2_grpc.py depends on'
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
)
class SensorPushStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Upload = channel.stream_stream(
'/sensor_stream.SensorPush/Upload',
request_serializer=sensor__stream__pb2.SensorFrame.SerializeToString,
response_deserializer=sensor__stream__pb2.PztAngleResponse.FromString,
_registered_method=True)
class SensorPushServicer(object):
"""Missing associated documentation comment in .proto file."""
def Upload(self, request_iterator, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_SensorPushServicer_to_server(servicer, server):
rpc_method_handlers = {
'Upload': grpc.stream_stream_rpc_method_handler(
servicer.Upload,
request_deserializer=sensor__stream__pb2.SensorFrame.FromString,
response_serializer=sensor__stream__pb2.PztAngleResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'sensor_stream.SensorPush', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
server.add_registered_method_handlers('sensor_stream.SensorPush', rpc_method_handlers)
# This class is part of an EXPERIMENTAL API.
class SensorPush(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def Upload(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(
request_iterator,
target,
'/sensor_stream.SensorPush/Upload',
sensor__stream__pb2.SensorFrame.SerializeToString,
sensor__stream__pb2.PztAngleResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
class ExportProcessorStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.ProcessFile = channel.unary_unary(
'/sensor_stream.ExportProcessor/ProcessFile',
request_serializer=sensor__stream__pb2.ProcessRequest.SerializeToString,
response_deserializer=sensor__stream__pb2.ProcessResponse.FromString,
_registered_method=True)
class ExportProcessorServicer(object):
"""Missing associated documentation comment in .proto file."""
def ProcessFile(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_ExportProcessorServicer_to_server(servicer, server):
rpc_method_handlers = {
'ProcessFile': grpc.unary_unary_rpc_method_handler(
servicer.ProcessFile,
request_deserializer=sensor__stream__pb2.ProcessRequest.FromString,
response_serializer=sensor__stream__pb2.ProcessResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'sensor_stream.ExportProcessor', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
server.add_registered_method_handlers('sensor_stream.ExportProcessor', rpc_method_handlers)
# This class is part of an EXPERIMENTAL API.
class ExportProcessor(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def ProcessFile(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/sensor_stream.ExportProcessor/ProcessFile',
sensor__stream__pb2.ProcessRequest.SerializeToString,
sensor__stream__pb2.ProcessResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)

1
eskin-finger-sdk Submodule

Submodule eskin-finger-sdk added at 705375085f

381
package-lock.json generated
View File

@@ -1,16 +1,18 @@
{
"name": "JE-Skin",
"version": "0.1.0",
"version": "0.4.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "JE-Skin",
"version": "0.1.0",
"version": "0.3.0",
"license": "MIT",
"dependencies": {
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-opener": "^2",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.10.1",
"three": "^0.183.2"
},
"devDependencies": {
@@ -532,9 +534,9 @@
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz",
"integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==",
"cpu": [
"arm"
],
@@ -546,9 +548,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz",
"integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==",
"cpu": [
"arm64"
],
@@ -560,9 +562,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz",
"integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==",
"cpu": [
"arm64"
],
@@ -574,9 +576,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz",
"integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==",
"cpu": [
"x64"
],
@@ -588,9 +590,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz",
"integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==",
"cpu": [
"arm64"
],
@@ -602,9 +604,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz",
"integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==",
"cpu": [
"x64"
],
@@ -616,13 +618,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz",
"integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==",
"cpu": [
"arm"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -630,13 +635,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz",
"integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==",
"cpu": [
"arm"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -644,13 +652,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz",
"integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -658,13 +669,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz",
"integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -672,13 +686,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz",
"integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==",
"cpu": [
"loong64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -686,13 +703,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz",
"integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==",
"cpu": [
"loong64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -700,13 +720,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz",
"integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==",
"cpu": [
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -714,13 +737,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz",
"integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==",
"cpu": [
"ppc64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -728,13 +754,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz",
"integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -742,13 +771,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz",
"integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -756,13 +788,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz",
"integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==",
"cpu": [
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -770,13 +805,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz",
"integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -784,13 +822,16 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz",
"integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -798,9 +839,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz",
"integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==",
"cpu": [
"x64"
],
@@ -812,9 +853,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz",
"integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==",
"cpu": [
"arm64"
],
@@ -826,9 +867,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz",
"integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==",
"cpu": [
"arm64"
],
@@ -840,9 +881,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz",
"integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==",
"cpu": [
"ia32"
],
@@ -854,9 +895,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz",
"integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==",
"cpu": [
"x64"
],
@@ -868,9 +909,9 @@
]
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz",
"integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==",
"cpu": [
"x64"
],
@@ -909,9 +950,9 @@
}
},
"node_modules/@sveltejs/kit": {
"version": "2.55.0",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.55.0.tgz",
"integrity": "sha512-MdFRjevVxmAknf2NbaUkDF16jSIzXMWd4Nfah0Qp8TtQVoSp3bV4jKt8mX7z7qTUTWvgSaxtR0EG5WJf53gcuA==",
"version": "2.58.0",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.58.0.tgz",
"integrity": "sha512-kT9GCN8yJTkCK1W+Gi/bvGooWAM7y7WXP+yd+rf6QOIjyoK1ERPrMwSufXJUNu2pMWIqruhFvmz+LbOqsEmKmA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -938,7 +979,7 @@
"@opentelemetry/api": "^1.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0",
"svelte": "^4.0.0 || ^5.0.0-next.0",
"typescript": "^5.3.3",
"typescript": "^5.3.3 || ^6.0.0",
"vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0"
},
"peerDependenciesMeta": {
@@ -1089,6 +1130,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
@@ -1106,6 +1150,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
@@ -1123,6 +1170,9 @@
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
@@ -1140,6 +1190,9 @@
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
@@ -1157,6 +1210,9 @@
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
@@ -1226,6 +1282,24 @@
"@tauri-apps/api": "^2.8.0"
}
},
"node_modules/@tauri-apps/plugin-process": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz",
"integrity": "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==",
"license": "MIT OR Apache-2.0",
"dependencies": {
"@tauri-apps/api": "^2.8.0"
}
},
"node_modules/@tauri-apps/plugin-updater": {
"version": "2.10.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.10.1.tgz",
"integrity": "sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA==",
"license": "MIT OR Apache-2.0",
"dependencies": {
"@tauri-apps/api": "^2.10.1"
}
},
"node_modules/@tweenjs/tween.js": {
"version": "23.1.3",
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
@@ -1284,20 +1358,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/types": {
"version": "8.57.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz",
"integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@webgpu/types": {
"version": "0.1.69",
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz",
@@ -1403,9 +1463,9 @@
}
},
"node_modules/devalue": {
"version": "5.6.4",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.4.tgz",
"integrity": "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==",
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.7.1.tgz",
"integrity": "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA==",
"dev": true,
"license": "MIT"
},
@@ -1459,14 +1519,21 @@
"license": "MIT"
},
"node_modules/esrap": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.4.tgz",
"integrity": "sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg==",
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.5.tgz",
"integrity": "sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15",
"@jridgewell/sourcemap-codec": "^1.4.15"
},
"peerDependencies": {
"@typescript-eslint/types": "^8.2.0"
},
"peerDependenciesMeta": {
"@typescript-eslint/types": {
"optional": true
}
}
},
"node_modules/fdir": {
@@ -1607,9 +1674,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1620,9 +1687,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
"integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
"dev": true,
"funding": [
{
@@ -1663,9 +1730,9 @@
}
},
"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==",
"version": "4.60.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz",
"integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1679,31 +1746,31 @@
"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",
"@rollup/rollup-android-arm-eabi": "4.60.2",
"@rollup/rollup-android-arm64": "4.60.2",
"@rollup/rollup-darwin-arm64": "4.60.2",
"@rollup/rollup-darwin-x64": "4.60.2",
"@rollup/rollup-freebsd-arm64": "4.60.2",
"@rollup/rollup-freebsd-x64": "4.60.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.60.2",
"@rollup/rollup-linux-arm-musleabihf": "4.60.2",
"@rollup/rollup-linux-arm64-gnu": "4.60.2",
"@rollup/rollup-linux-arm64-musl": "4.60.2",
"@rollup/rollup-linux-loong64-gnu": "4.60.2",
"@rollup/rollup-linux-loong64-musl": "4.60.2",
"@rollup/rollup-linux-ppc64-gnu": "4.60.2",
"@rollup/rollup-linux-ppc64-musl": "4.60.2",
"@rollup/rollup-linux-riscv64-gnu": "4.60.2",
"@rollup/rollup-linux-riscv64-musl": "4.60.2",
"@rollup/rollup-linux-s390x-gnu": "4.60.2",
"@rollup/rollup-linux-x64-gnu": "4.60.2",
"@rollup/rollup-linux-x64-musl": "4.60.2",
"@rollup/rollup-openbsd-x64": "4.60.2",
"@rollup/rollup-openharmony-arm64": "4.60.2",
"@rollup/rollup-win32-arm64-msvc": "4.60.2",
"@rollup/rollup-win32-ia32-msvc": "4.60.2",
"@rollup/rollup-win32-x64-gnu": "4.60.2",
"@rollup/rollup-win32-x64-msvc": "4.60.2",
"fsevents": "~2.3.2"
}
},
@@ -1721,9 +1788,9 @@
}
},
"node_modules/set-cookie-parser": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.0.1.tgz",
"integrity": "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz",
"integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==",
"dev": true,
"license": "MIT"
},
@@ -1753,9 +1820,9 @@
}
},
"node_modules/svelte": {
"version": "5.54.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.54.0.tgz",
"integrity": "sha512-TTDxwYnHkova6Wsyj1PGt9TByuWqvMoeY1bQiuAf2DM/JeDSMw7FjRKzk8K/5mJ99vGOKhbCqTDpyAKwjp4igg==",
"version": "5.55.5",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.5.tgz",
"integrity": "sha512-2uCs/LZ9us+AktdzYJM8OcxQ8qnPS1kpaO7syGT/MgO+6Qr1Ybl+TqPq+97u7PHqmmMlye5ZkoyXONy5mjjAbw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1770,7 +1837,7 @@
"clsx": "^2.1.1",
"devalue": "^5.6.4",
"esm-env": "^1.2.1",
"esrap": "^2.2.2",
"esrap": "^2.2.4",
"is-reference": "^3.0.3",
"locate-character": "^3.0.0",
"magic-string": "^0.30.11",
@@ -1781,9 +1848,9 @@
}
},
"node_modules/svelte-check": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.5.tgz",
"integrity": "sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==",
"version": "4.4.6",
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.6.tgz",
"integrity": "sha512-kP1zG81EWaFe9ZyTv4ZXv44Csi6Pkdpb7S3oj6m+K2ec/IcDg/a8LsFsnVLqm2nxtkSwsd5xPj/qFkTBgXHXjg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1811,14 +1878,14 @@
"license": "MIT"
},
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"version": "0.2.16",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.3"
"picomatch": "^4.0.4"
},
"engines": {
"node": ">=12.0.0"
@@ -1852,9 +1919,9 @@
}
},
"node_modules/vite": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz",
"integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1927,9 +1994,9 @@
}
},
"node_modules/vitefu": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.2.tgz",
"integrity": "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz",
"integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -1938,7 +2005,7 @@
"tests/projects/workspace/packages/*"
],
"peerDependencies": {
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0"
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"vite": {

View File

@@ -1,6 +1,6 @@
{
"name": "JE-Skin",
"version": "0.1.0",
"version": "0.4.0",
"description": "",
"type": "module",
"scripts": {
@@ -9,12 +9,16 @@
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"tauri": "tauri"
"tauri": "tauri",
"tauri:devkit": "tauri dev -- --features devkit",
"tauri:devkit:build": "tauri build -- --features devkit"
},
"license": "MIT",
"dependencies": {
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-opener": "^2",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.10.1",
"three": "^0.183.2"
},
"devDependencies": {

View File

@@ -1,7 +1,9 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/target-*/
# Generated by Tauri
# will have schema files for capabilities auto-completion
/gen/schemas
*log*

2229
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "JE-Skin"
version = "0.1.0"
version = "0.4.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"
@@ -14,14 +14,27 @@ edition = "2021"
name = "tauri_demo_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[features]
default = ["multi-dim"]
devkit = ["dep:tonic", "dep:prost", "dep:prost-types", "dep:async-stream", "dep:dirs"]
multi-dim = ["dep:ndarray"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
tonic-build = { version = "0.12" }
protoc-bin-vendored = "3"
[dependencies]
tauri = { version = "2", features = ["tray-icon"] }
tauri-plugin-opener = "2"
tauri-plugin-process = "2"
serde = { version = "1", features = ["derive"] }
anyhow = "1.0.102"
tonic = { version = "0.12", optional = true }
prost = { version = "0.13", optional = true }
prost-types = { version = "0.13", optional = true }
async-stream = { version = "0.3", optional = true }
dirs = { version = "6", optional = true }
tokio-serial = { version = "5.4.5" }
tokio = { version = "1.50.0", features = ["full"] }
async-trait = "0.1.89"
@@ -33,3 +46,13 @@ humantime = "2.3.0"
csv = "1.4.0"
chrono = "0.4.44"
crc = "3.4.0"
axum = { version = "0.8", features = ["ws"] }
tower-http = { version = "0.6", features = ["cors"] }
futures-util = "0.3"
uuid = { version = "1", features = ["v4", "serde"] }
rand = "0.8"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
ndarray = { version = "0.15", optional = true }
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-updater = "2"

View File

@@ -1,3 +1,11 @@
fn main() {
if std::env::var("CARGO_FEATURE_DEVKIT").is_ok() {
let protoc = protoc_bin_vendored::protoc_bin_path()
.unwrap_or_else(|error| panic!("Failed to resolve bundled protoc: {error}"));
std::env::set_var("PROTOC", protoc);
tonic_build::compile_protos("proto/sensor_stream.proto")
.unwrap_or_else(|error| panic!("Failed to compile devkit proto: {error}"));
}
tauri_build::build()
}

View File

@@ -10,6 +10,8 @@
"core:window:allow-inner-size",
"core:window:allow-set-size",
"core:window:allow-start-dragging",
"opener:default"
"opener:default",
"process:default",
"updater:default"
]
}

View File

@@ -0,0 +1,5 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-keep class com.lenn.tauri_serial.TauriActivity {
public app.tauri.plugin.PluginManager getPluginManager();
}

View File

@@ -0,0 +1 @@
{"$schema":"https://schema.tauri.app/config/2","productName":"JE-Skin","version":"0.4.0","identifier":"com.lenn.tauri-serial","app":{"windows":[{"label":"main","create":true,"url":"index.html","dragDropEnabled":true,"center":false,"width":1366.0,"height":860.0,"resizable":true,"maximizable":true,"minimizable":true,"closable":true,"title":"JE-Skin","fullscreen":false,"focus":true,"focusable":true,"transparent":false,"maximized":false,"visible":true,"decorations":false,"alwaysOnBottom":false,"alwaysOnTop":false,"visibleOnAllWorkspaces":false,"contentProtected":false,"skipTaskbar":false,"titleBarStyle":"Visible","hiddenTitle":false,"acceptFirstMouse":false,"shadow":true,"incognito":false,"zoomHotkeysEnabled":false,"browserExtensionsEnabled":false,"useHttpsScheme":false,"javascriptDisabled":false,"allowLinkPreview":true,"disableInputAccessoryView":false,"scrollBarStyle":"default"}],"security":{"freezePrototype":false,"dangerousDisableAssetCspModification":false,"assetProtocol":{"scope":[],"enable":false},"pattern":{"use":"brownfield"},"capabilities":[]},"macOSPrivateApi":false,"withGlobalTauri":false,"enableGTKAppId":false},"build":{"devUrl":"http://localhost:1420/","frontendDist":"../build","beforeDevCommand":"npm run dev","beforeBuildCommand":"npm run build","removeUnusedCommands":false,"additionalWatchFolders":[]},"bundle":{"active":true,"targets":"all","createUpdaterArtifacts":true,"icon":["icons/32x32.png","icons/128x128.png","icons/128x128@2x.png","icons/icon.icns","icons/icon.ico"],"resources":["resources/je-skin-devkit-server.exe"],"useLocalToolsDir":false,"windows":{"digestAlgorithm":null,"certificateThumbprint":null,"timestampUrl":null,"tsp":false,"webviewInstallMode":{"type":"downloadBootstrapper","silent":true},"allowDowngrades":true,"wix":null,"nsis":{"template":"nsis/installer.nsi","headerImage":null,"sidebarImage":null,"installerIcon":"icons/icon.ico","installMode":"both","languages":null,"customLanguageFiles":null,"displayLanguageSelector":false,"compression":"lzma","startMenuFolder":null,"installerHooks":null,"minimumWebview2Version":null},"signCommand":null},"linux":{"appimage":{"bundleMediaFramework":false,"files":{}},"deb":{"files":{}},"rpm":{"release":"1","epoch":0,"files":{}}},"macOS":{"files":{},"minimumSystemVersion":"10.13","hardenedRuntime":true,"dmg":{"windowSize":{"width":660,"height":400},"appPosition":{"x":180,"y":170},"applicationFolderPosition":{"x":480,"y":170}}},"iOS":{"minimumSystemVersion":"14.0"},"android":{"minSdkVersion":24,"autoIncrementVersionCode":false}},"plugins":{}}

View File

@@ -0,0 +1,33 @@
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
@file:Suppress("unused")
package com.lenn.tauri_serial
import android.webkit.*
class Ipc(val webViewClient: RustWebViewClient) {
@JavascriptInterface
fun postMessage(message: String?) {
message?.let {m ->
// we're not using WebView::getUrl() here because it needs to be executed on the main thread
// and it would slow down the Ipc
// so instead we track the current URL on the webview client
this.ipc(webViewClient.currentUrl, m)
}
}
companion object {
init {
System.loadLibrary("tauri_demo_lib")
}
}
private external fun ipc(url: String, message: String)
}

View File

@@ -0,0 +1,89 @@
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.lenn.tauri_serial
// taken from https://github.com/ionic-team/capacitor/blob/6658bca41e78239347e458175b14ca8bd5c1d6e8/android/capacitor/src/main/java/com/getcapacitor/Logger.java
import android.text.TextUtils
import android.util.Log
class Logger {
companion object {
private const val LOG_TAG_CORE = "Tauri"
fun tags(vararg subtags: String): String {
return if (subtags.isNotEmpty()) {
LOG_TAG_CORE + "/" + TextUtils.join("/", subtags)
} else LOG_TAG_CORE
}
fun verbose(message: String) {
verbose(LOG_TAG_CORE, message)
}
private fun verbose(tag: String, message: String) {
if (!shouldLog()) {
return
}
Log.v(tag, message)
}
fun debug(message: String) {
debug(LOG_TAG_CORE, message)
}
fun debug(tag: String, message: String) {
if (!shouldLog()) {
return
}
Log.d(tag, message)
}
fun info(message: String) {
info(LOG_TAG_CORE, message)
}
fun info(tag: String, message: String) {
if (!shouldLog()) {
return
}
Log.i(tag, message)
}
fun warn(message: String) {
warn(LOG_TAG_CORE, message)
}
fun warn(tag: String, message: String) {
if (!shouldLog()) {
return
}
Log.w(tag, message)
}
fun error(message: String) {
error(LOG_TAG_CORE, message, null)
}
fun error(message: String, e: Throwable?) {
error(LOG_TAG_CORE, message, e)
}
fun error(tag: String, message: String, e: Throwable?) {
if (!shouldLog()) {
return
}
Log.e(tag, message, e)
}
private fun shouldLog(): Boolean {
return BuildConfig.DEBUG
}
}
}

View File

@@ -0,0 +1,117 @@
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
package com.lenn.tauri_serial
// taken from https://github.com/ionic-team/capacitor/blob/6658bca41e78239347e458175b14ca8bd5c1d6e8/android/capacitor/src/main/java/com/getcapacitor/PermissionHelper.java
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.app.ActivityCompat
import java.util.ArrayList
object PermissionHelper {
/**
* Checks if a list of given permissions are all granted by the user
*
* @param permissions Permissions to check.
* @return True if all permissions are granted, false if at least one is not.
*/
fun hasPermissions(context: Context?, permissions: Array<String>): Boolean {
for (perm in permissions) {
if (ActivityCompat.checkSelfPermission(
context!!,
perm
) != PackageManager.PERMISSION_GRANTED
) {
return false
}
}
return true
}
/**
* Check whether the given permission has been defined in the AndroidManifest.xml
*
* @param permission A permission to check.
* @return True if the permission has been defined in the Manifest, false if not.
*/
fun hasDefinedPermission(context: Context, permission: String): Boolean {
var hasPermission = false
val requestedPermissions = getManifestPermissions(context)
if (!requestedPermissions.isNullOrEmpty()) {
val requestedPermissionsList = listOf(*requestedPermissions)
val requestedPermissionsArrayList = ArrayList(requestedPermissionsList)
if (requestedPermissionsArrayList.contains(permission)) {
hasPermission = true
}
}
return hasPermission
}
/**
* Check whether all of the given permissions have been defined in the AndroidManifest.xml
* @param context the app context
* @param permissions a list of permissions
* @return true only if all permissions are defined in the AndroidManifest.xml
*/
fun hasDefinedPermissions(context: Context, permissions: Array<String>): Boolean {
for (permission in permissions) {
if (!hasDefinedPermission(context, permission)) {
return false
}
}
return true
}
/**
* Get the permissions defined in AndroidManifest.xml
*
* @return The permissions defined in AndroidManifest.xml
*/
private fun getManifestPermissions(context: Context): Array<String>? {
var requestedPermissions: Array<String>? = null
try {
val pm = context.packageManager
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
pm.getPackageInfo(context.packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_PERMISSIONS.toLong()))
} else {
@Suppress("DEPRECATION")
pm.getPackageInfo(context.packageName, PackageManager.GET_PERMISSIONS)
}
if (packageInfo != null) {
requestedPermissions = packageInfo.requestedPermissions
}
} catch (_: Exception) {
}
return requestedPermissions
}
/**
* Given a list of permissions, return a new list with the ones not present in AndroidManifest.xml
*
* @param neededPermissions The permissions needed.
* @return The permissions not present in AndroidManifest.xml
*/
fun getUndefinedPermissions(context: Context, neededPermissions: Array<String?>): Array<String?> {
val undefinedPermissions = ArrayList<String?>()
val requestedPermissions = getManifestPermissions(context)
if (!requestedPermissions.isNullOrEmpty()) {
val requestedPermissionsList = listOf(*requestedPermissions)
val requestedPermissionsArrayList = ArrayList(requestedPermissionsList)
for (permission in neededPermissions) {
if (!requestedPermissionsArrayList.contains(permission)) {
undefinedPermissions.add(permission)
}
}
var undefinedPermissionArray = arrayOfNulls<String>(undefinedPermissions.size)
undefinedPermissionArray = undefinedPermissions.toArray(undefinedPermissionArray)
return undefinedPermissionArray
}
return neededPermissions
}
}

View File

@@ -0,0 +1,495 @@
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
@file:Suppress("ObsoleteSdkInt", "RedundantOverride", "QueryPermissionsNeeded", "SimpleDateFormat")
package com.lenn.tauri_serial
// taken from https://github.com/ionic-team/capacitor/blob/6658bca41e78239347e458175b14ca8bd5c1d6e8/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java
import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.content.ActivityNotFoundException
import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import android.webkit.*
import android.widget.EditText
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.FileProvider
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
class RustWebChromeClient(appActivity: WryActivity) : WebChromeClient() {
private interface PermissionListener {
fun onPermissionSelect(isGranted: Boolean?)
}
private interface ActivityResultListener {
fun onActivityResult(result: ActivityResult?)
}
private val activity: WryActivity
private var permissionLauncher: ActivityResultLauncher<Array<String>>
private var activityLauncher: ActivityResultLauncher<Intent>
private var permissionListener: PermissionListener? = null
private var activityListener: ActivityResultListener? = null
init {
activity = appActivity
val permissionCallback =
ActivityResultCallback { isGranted: Map<String, Boolean> ->
if (permissionListener != null) {
var granted = true
for ((_, value) in isGranted) {
if (!value) granted = false
}
permissionListener!!.onPermissionSelect(granted)
}
}
permissionLauncher =
activity.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions(), permissionCallback)
activityLauncher = activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (activityListener != null) {
activityListener!!.onActivityResult(result)
}
}
}
/**
* Render web content in `view`.
*
* Both this method and [.onHideCustomView] are required for
* rendering web content in full screen.
*
* @see [](https://developer.android.com/reference/android/webkit/WebChromeClient.onShowCustomView
) */
override fun onShowCustomView(view: View, callback: CustomViewCallback) {
callback.onCustomViewHidden()
super.onShowCustomView(view, callback)
}
/**
* Render web content in the original Web View again.
*
* Do not remove this method--@see #onShowCustomView(View, CustomViewCallback).
*/
override fun onHideCustomView() {
super.onHideCustomView()
}
override fun onPermissionRequest(request: PermissionRequest) {
val isRequestPermissionRequired = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
val permissionList: MutableList<String> = ArrayList()
if (listOf(*request.resources).contains("android.webkit.resource.VIDEO_CAPTURE")) {
permissionList.add(Manifest.permission.CAMERA)
}
if (listOf(*request.resources).contains("android.webkit.resource.AUDIO_CAPTURE")) {
permissionList.add(Manifest.permission.MODIFY_AUDIO_SETTINGS)
permissionList.add(Manifest.permission.RECORD_AUDIO)
}
if (permissionList.isNotEmpty() && isRequestPermissionRequired) {
val permissions = permissionList.toTypedArray()
permissionListener = object : PermissionListener {
override fun onPermissionSelect(isGranted: Boolean?) {
if (isGranted == true) {
request.grant(request.resources)
} else {
request.deny()
}
}
}
permissionLauncher.launch(permissions)
} else {
request.grant(request.resources)
}
}
/**
* Show the browser alert modal
* @param view
* @param url
* @param message
* @param result
* @return
*/
override fun onJsAlert(view: WebView, url: String, message: String, result: JsResult): Boolean {
if (activity.isFinishing) {
return true
}
val builder = AlertDialog.Builder(view.context)
builder
.setMessage(message)
.setPositiveButton(
"OK"
) { dialog: DialogInterface, _: Int ->
dialog.dismiss()
result.confirm()
}
.setOnCancelListener { dialog: DialogInterface ->
dialog.dismiss()
result.cancel()
}
val dialog = builder.create()
dialog.show()
return true
}
/**
* Show the browser confirm modal
* @param view
* @param url
* @param message
* @param result
* @return
*/
override fun onJsConfirm(view: WebView, url: String, message: String, result: JsResult): Boolean {
if (activity.isFinishing) {
return true
}
val builder = AlertDialog.Builder(view.context)
builder
.setMessage(message)
.setPositiveButton(
"OK"
) { dialog: DialogInterface, _: Int ->
dialog.dismiss()
result.confirm()
}
.setNegativeButton(
"Cancel"
) { dialog: DialogInterface, _: Int ->
dialog.dismiss()
result.cancel()
}
.setOnCancelListener { dialog: DialogInterface ->
dialog.dismiss()
result.cancel()
}
val dialog = builder.create()
dialog.show()
return true
}
/**
* Show the browser prompt modal
* @param view
* @param url
* @param message
* @param defaultValue
* @param result
* @return
*/
override fun onJsPrompt(
view: WebView,
url: String,
message: String,
defaultValue: String,
result: JsPromptResult
): Boolean {
if (activity.isFinishing) {
return true
}
val builder = AlertDialog.Builder(view.context)
val input = EditText(view.context)
builder
.setMessage(message)
.setView(input)
.setPositiveButton(
"OK"
) { dialog: DialogInterface, _: Int ->
dialog.dismiss()
val inputText1 = input.text.toString().trim { it <= ' ' }
result.confirm(inputText1)
}
.setNegativeButton(
"Cancel"
) { dialog: DialogInterface, _: Int ->
dialog.dismiss()
result.cancel()
}
.setOnCancelListener { dialog: DialogInterface ->
dialog.dismiss()
result.cancel()
}
val dialog = builder.create()
dialog.show()
return true
}
/**
* Handle the browser geolocation permission prompt
* @param origin
* @param callback
*/
override fun onGeolocationPermissionsShowPrompt(
origin: String,
callback: GeolocationPermissions.Callback
) {
super.onGeolocationPermissionsShowPrompt(origin, callback)
Logger.debug("onGeolocationPermissionsShowPrompt: DOING IT HERE FOR ORIGIN: $origin")
val geoPermissions =
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
if (!PermissionHelper.hasPermissions(activity, geoPermissions)) {
permissionListener = object : PermissionListener {
override fun onPermissionSelect(isGranted: Boolean?) {
if (isGranted == true) {
callback.invoke(origin, true, false)
} else {
val coarsePermission =
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
PermissionHelper.hasPermissions(activity, coarsePermission)
) {
callback.invoke(origin, true, false)
} else {
callback.invoke(origin, false, false)
}
}
}
}
permissionLauncher.launch(geoPermissions)
} else {
// permission is already granted
callback.invoke(origin, true, false)
Logger.debug("onGeolocationPermissionsShowPrompt: has required permission")
}
}
override fun onShowFileChooser(
webView: WebView,
filePathCallback: ValueCallback<Array<Uri?>?>,
fileChooserParams: FileChooserParams
): Boolean {
val acceptTypes = listOf(*fileChooserParams.acceptTypes)
val captureEnabled = fileChooserParams.isCaptureEnabled
val capturePhoto = captureEnabled && acceptTypes.contains("image/*")
val captureVideo = captureEnabled && acceptTypes.contains("video/*")
if (capturePhoto || captureVideo) {
if (isMediaCaptureSupported) {
showMediaCaptureOrFilePicker(filePathCallback, fileChooserParams, captureVideo)
} else {
permissionListener = object : PermissionListener {
override fun onPermissionSelect(isGranted: Boolean?) {
if (isGranted == true) {
showMediaCaptureOrFilePicker(filePathCallback, fileChooserParams, captureVideo)
} else {
Logger.warn(Logger.tags("FileChooser"), "Camera permission not granted")
filePathCallback.onReceiveValue(null)
}
}
}
val camPermission = arrayOf(Manifest.permission.CAMERA)
permissionLauncher.launch(camPermission)
}
} else {
showFilePicker(filePathCallback, fileChooserParams)
}
return true
}
private val isMediaCaptureSupported: Boolean
get() {
val permissions = arrayOf(Manifest.permission.CAMERA)
return PermissionHelper.hasPermissions(activity, permissions) ||
!PermissionHelper.hasDefinedPermission(activity, Manifest.permission.CAMERA)
}
private fun showMediaCaptureOrFilePicker(
filePathCallback: ValueCallback<Array<Uri?>?>,
fileChooserParams: FileChooserParams,
isVideo: Boolean
) {
val isVideoCaptureSupported = true
val shown = if (isVideo && isVideoCaptureSupported) {
showVideoCapturePicker(filePathCallback)
} else {
showImageCapturePicker(filePathCallback)
}
if (!shown) {
Logger.warn(
Logger.tags("FileChooser"),
"Media capture intent could not be launched. Falling back to default file picker."
)
showFilePicker(filePathCallback, fileChooserParams)
}
}
private fun showImageCapturePicker(filePathCallback: ValueCallback<Array<Uri?>?>): Boolean {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(activity.packageManager) == null) {
return false
}
val imageFileUri: Uri = try {
createImageFileUri()
} catch (ex: Exception) {
Logger.error("Unable to create temporary media capture file: " + ex.message)
return false
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri)
activityListener = object : ActivityResultListener {
override fun onActivityResult(result: ActivityResult?) {
var res: Array<Uri?>? = null
if (result?.resultCode == Activity.RESULT_OK) {
res = arrayOf(imageFileUri)
}
filePathCallback.onReceiveValue(res)
}
}
activityLauncher.launch(takePictureIntent)
return true
}
private fun showVideoCapturePicker(filePathCallback: ValueCallback<Array<Uri?>?>): Boolean {
val takeVideoIntent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
if (takeVideoIntent.resolveActivity(activity.packageManager) == null) {
return false
}
activityListener = object : ActivityResultListener {
override fun onActivityResult(result: ActivityResult?) {
var res: Array<Uri?>? = null
if (result?.resultCode == Activity.RESULT_OK) {
res = arrayOf(result.data!!.data)
}
filePathCallback.onReceiveValue(res)
}
}
activityLauncher.launch(takeVideoIntent)
return true
}
private fun showFilePicker(
filePathCallback: ValueCallback<Array<Uri?>?>,
fileChooserParams: FileChooserParams
) {
val intent = fileChooserParams.createIntent()
if (fileChooserParams.mode == FileChooserParams.MODE_OPEN_MULTIPLE) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
if (fileChooserParams.acceptTypes.size > 1 || intent.type!!.startsWith(".")) {
val validTypes = getValidTypes(fileChooserParams.acceptTypes)
intent.putExtra(Intent.EXTRA_MIME_TYPES, validTypes)
if (intent.type!!.startsWith(".")) {
intent.type = validTypes[0]
}
}
try {
activityListener = object : ActivityResultListener {
override fun onActivityResult(result: ActivityResult?) {
val res: Array<Uri?>?
val resultIntent = result?.data
if (result?.resultCode == Activity.RESULT_OK && resultIntent!!.clipData != null) {
val numFiles = resultIntent.clipData!!.itemCount
res = arrayOfNulls(numFiles)
for (i in 0 until numFiles) {
res[i] = resultIntent.clipData!!.getItemAt(i).uri
}
} else {
res = FileChooserParams.parseResult(
result?.resultCode ?: 0,
resultIntent
)
}
filePathCallback.onReceiveValue(res)
}
}
activityLauncher.launch(intent)
} catch (e: ActivityNotFoundException) {
filePathCallback.onReceiveValue(null)
}
}
private fun getValidTypes(currentTypes: Array<String>): Array<String> {
val validTypes: MutableList<String> = ArrayList()
val mtm = MimeTypeMap.getSingleton()
for (mime in currentTypes) {
if (mime.startsWith(".")) {
val extension = mime.substring(1)
val extensionMime = mtm.getMimeTypeFromExtension(extension)
if (extensionMime != null && !validTypes.contains(extensionMime)) {
validTypes.add(extensionMime)
}
} else if (!validTypes.contains(mime)) {
validTypes.add(mime)
}
}
val validObj: Array<Any> = validTypes.toTypedArray()
return Arrays.copyOf(
validObj, validObj.size,
Array<String>::class.java
)
}
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
val tag: String = Logger.tags("Console")
if (consoleMessage.message() != null && isValidMsg(consoleMessage.message())) {
val msg = String.format(
"File: %s - Line %d - Msg: %s",
consoleMessage.sourceId(),
consoleMessage.lineNumber(),
consoleMessage.message()
)
val level = consoleMessage.messageLevel().name
if ("ERROR".equals(level, ignoreCase = true)) {
Logger.error(tag, msg, null)
} else if ("WARNING".equals(level, ignoreCase = true)) {
Logger.warn(tag, msg)
} else if ("TIP".equals(level, ignoreCase = true)) {
Logger.debug(tag, msg)
} else {
Logger.info(tag, msg)
}
}
return true
}
private fun isValidMsg(msg: String): Boolean {
return !(msg.contains("%cresult %c") ||
msg.contains("%cnative %c") ||
msg.equals("[object Object]", ignoreCase = true) ||
msg.equals("console.groupEnd", ignoreCase = true))
}
@Throws(IOException::class)
private fun createImageFileUri(): Uri {
val photoFile = createImageFile(activity)
return FileProvider.getUriForFile(
activity,
activity.packageName.toString() + ".fileprovider",
photoFile
)
}
@Throws(IOException::class)
private fun createImageFile(activity: Activity): File {
// Create an image file name
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val imageFileName = "JPEG_" + timeStamp + "_"
val storageDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(imageFileName, ".jpg", storageDir)
}
override fun onReceivedTitle(
view: WebView,
title: String
) {
handleReceivedTitle(view, title)
}
private external fun handleReceivedTitle(webview: WebView, title: String)
}

View File

@@ -0,0 +1,101 @@
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
@file:Suppress("unused", "SetJavaScriptEnabled")
package com.lenn.tauri_serial
import android.annotation.SuppressLint
import android.webkit.*
import android.content.Context
import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature
import kotlin.collections.Map
@SuppressLint("RestrictedApi")
class RustWebView(context: Context, val initScripts: Array<String>, val id: String): WebView(context) {
val isDocumentStartScriptEnabled: Boolean
init {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
settings.setGeolocationEnabled(true)
settings.databaseEnabled = true
settings.mediaPlaybackRequiresUserGesture = false
settings.javaScriptCanOpenWindowsAutomatically = true
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
isDocumentStartScriptEnabled = true
for (script in initScripts) {
WebViewCompat.addDocumentStartJavaScript(this, script, setOf("*"));
}
} else {
isDocumentStartScriptEnabled = false
}
}
fun loadUrlMainThread(url: String) {
post {
loadUrl(url)
}
}
fun loadUrlMainThread(url: String, additionalHttpHeaders: Map<String, String>) {
post {
loadUrl(url, additionalHttpHeaders)
}
}
override fun loadUrl(url: String) {
if (!shouldOverride(url)) {
super.loadUrl(url);
}
}
override fun loadUrl(url: String, additionalHttpHeaders: Map<String, String>) {
if (!shouldOverride(url)) {
super.loadUrl(url, additionalHttpHeaders);
}
}
fun loadHTMLMainThread(html: String) {
post {
super.loadData(html, "text/html", null)
}
}
fun evalScript(id: Int, script: String) {
post {
super.evaluateJavascript(script) { result ->
onEval(id, result)
}
}
}
fun clearAllBrowsingData() {
try {
super.getContext().deleteDatabase("webviewCache.db")
super.getContext().deleteDatabase("webview.db")
super.clearCache(true)
super.clearHistory()
super.clearFormData()
} catch (ex: Exception) {
Logger.error("Unable to create temporary media capture file: " + ex.message)
}
}
fun getCookies(url: String): String {
val cookieManager = CookieManager.getInstance()
return cookieManager.getCookie(url)
}
private external fun shouldOverride(url: String): Boolean
private external fun onEval(id: Int, result: String)
}

View File

@@ -0,0 +1,107 @@
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
package com.lenn.tauri_serial
import android.net.Uri
import android.webkit.*
import android.content.Context
import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import androidx.webkit.WebViewAssetLoader
class RustWebViewClient(context: Context): WebViewClient() {
private val interceptedState = mutableMapOf<String, Boolean>()
var currentUrl: String = "about:blank"
private var lastInterceptedUrl: Uri? = null
private var pendingUrlRedirect: String? = null
private val assetLoader = WebViewAssetLoader.Builder()
.setDomain(assetLoaderDomain())
.addPathHandler("/", WebViewAssetLoader.AssetsPathHandler(context))
.build()
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
pendingUrlRedirect?.let {
Handler(Looper.getMainLooper()).post {
view.loadUrl(it)
}
pendingUrlRedirect = null
return null
}
lastInterceptedUrl = request.url
return if (withAssetLoader()) {
assetLoader.shouldInterceptRequest(request.url)
} else {
val rustWebview = view as RustWebView;
val response = handleRequest(rustWebview.id, request, rustWebview.isDocumentStartScriptEnabled)
interceptedState[request.url.toString()] = response != null
return response
}
}
override fun shouldOverrideUrlLoading(
view: WebView,
request: WebResourceRequest
): Boolean {
return shouldOverride(request.url.toString())
}
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
currentUrl = url
if (interceptedState[url] == false) {
val webView = view as RustWebView
for (script in webView.initScripts) {
view.evaluateJavascript(script, null)
}
}
return onPageLoading(url)
}
override fun onPageFinished(view: WebView, url: String) {
onPageLoaded(url)
}
override fun onReceivedError(
view: WebView,
request: WebResourceRequest,
error: WebResourceError
) {
// we get a net::ERR_CONNECTION_REFUSED when an external URL redirects to a custom protocol
// e.g. oauth flow, because shouldInterceptRequest is not called on redirects
// so we must force retry here with loadUrl() to get a chance of the custom protocol to kick in
if (error.errorCode == ERROR_CONNECT && request.isForMainFrame && request.url != lastInterceptedUrl) {
// prevent the default error page from showing
view.stopLoading()
// without this initial loadUrl the app is stuck
view.loadUrl(request.url.toString())
// ensure the URL is actually loaded - for some reason there's a race condition and we need to call loadUrl() again later
pendingUrlRedirect = request.url.toString()
} else {
super.onReceivedError(view, request, error)
}
}
companion object {
init {
System.loadLibrary("tauri_demo_lib")
}
}
private external fun assetLoaderDomain(): String
private external fun withAssetLoader(): Boolean
private external fun handleRequest(webviewId: String, request: WebResourceRequest, isDocumentStartScriptEnabled: Boolean): WebResourceResponse?
private external fun shouldOverride(url: String): Boolean
private external fun onPageLoading(url: String)
private external fun onPageLoaded(url: String)
}

View File

@@ -0,0 +1,51 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
package com.lenn.tauri_serial
import android.content.Intent
import android.content.res.Configuration
import app.tauri.plugin.PluginManager
abstract class TauriActivity : WryActivity() {
var pluginManager: PluginManager = PluginManager(this)
override val handleBackNavigation: Boolean = false
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
pluginManager.onNewIntent(intent)
}
override fun onResume() {
super.onResume()
pluginManager.onResume()
}
override fun onPause() {
super.onPause()
pluginManager.onPause()
}
override fun onRestart() {
super.onRestart()
pluginManager.onRestart()
}
override fun onStop() {
super.onStop()
pluginManager.onStop()
}
override fun onDestroy() {
super.onDestroy()
pluginManager.onDestroy()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
pluginManager.onConfigurationChanged(newConfig)
}
}

View File

@@ -0,0 +1,146 @@
/* THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!! */
// Copyright 2020-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
package com.lenn.tauri_serial
import com.lenn.tauri_serial.RustWebView
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.webkit.WebView
import android.view.KeyEvent
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
abstract class WryActivity : AppCompatActivity() {
private lateinit var mWebView: RustWebView
open val handleBackNavigation: Boolean = true
open fun onWebViewCreate(webView: WebView) { }
fun setWebView(webView: RustWebView) {
mWebView = webView
if (handleBackNavigation) {
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (this@WryActivity.mWebView.canGoBack()) {
this@WryActivity.mWebView.goBack()
} else {
this.isEnabled = false
this@WryActivity.onBackPressed()
this.isEnabled = true
}
}
}
onBackPressedDispatcher.addCallback(this, callback)
}
onWebViewCreate(webView)
}
val version: String
@SuppressLint("WebViewApiAvailability", "ObsoleteSdkInt")
get() {
// Check getCurrentWebViewPackage() directly if above Android 8
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return WebView.getCurrentWebViewPackage()?.versionName ?: ""
}
// Otherwise manually check WebView versions
var webViewPackage = "com.google.android.webview"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
webViewPackage = "com.android.chrome"
}
try {
@Suppress("DEPRECATION")
val info = packageManager.getPackageInfo(webViewPackage, 0)
return info.versionName.toString()
} catch (ex: Exception) {
Logger.warn("Unable to get package info for '$webViewPackage'$ex")
}
try {
@Suppress("DEPRECATION")
val info = packageManager.getPackageInfo("com.android.webview", 0)
return info.versionName.toString()
} catch (ex: Exception) {
Logger.warn("Unable to get package info for 'com.android.webview'$ex")
}
// Could not detect any webview, return empty string
return ""
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
create(this)
}
override fun onStart() {
super.onStart()
start()
}
override fun onResume() {
super.onResume()
resume()
}
override fun onPause() {
super.onPause()
pause()
}
override fun onStop() {
super.onStop()
stop()
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
focus(hasFocus)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
save()
}
override fun onDestroy() {
super.onDestroy()
destroy()
onActivityDestroy()
}
override fun onLowMemory() {
super.onLowMemory()
memory()
}
fun getAppClass(name: String): Class<*> {
return Class.forName(name)
}
companion object {
init {
System.loadLibrary("tauri_demo_lib")
}
}
private external fun create(activity: WryActivity)
private external fun start()
private external fun resume()
private external fun pause()
private external fun stop()
private external fun save()
private external fun destroy()
private external fun onActivityDestroy()
private external fun memory()
private external fun focus(focus: Boolean)
}

View File

@@ -0,0 +1,35 @@
# THIS FILE IS AUTO-GENERATED. DO NOT MODIFY!!
# Copyright 2020-2023 Tauri Programme within The Commons Conservancy
# SPDX-License-Identifier: Apache-2.0
# SPDX-License-Identifier: MIT
-keep class com.lenn.tauri_serial.* {
native <methods>;
}
-keep class com.lenn.tauri_serial.WryActivity {
public <init>(...);
void setWebView(com.lenn.tauri_serial.RustWebView);
java.lang.Class getAppClass(...);
java.lang.String getVersion();
}
-keep class com.lenn.tauri_serial.Ipc {
public <init>(...);
@android.webkit.JavascriptInterface public <methods>;
}
-keep class com.lenn.tauri_serial.RustWebView {
public <init>(...);
void loadUrlMainThread(...);
void loadHTMLMainThread(...);
void evalScript(...);
}
-keep class com.lenn.tauri_serial.RustWebChromeClient,com.lenn.tauri_serial.RustWebViewClient {
public <init>(...);
}

View File

@@ -0,0 +1 @@
/home/lenn/Workspace/JE-Skin/src-tauri/target/aarch64-linux-android/release/libtauri_demo_lib.so

View File

@@ -0,0 +1 @@
/home/lenn/Workspace/JE-Skin/src-tauri/target/armv7-linux-androideabi/release/libtauri_demo_lib.so

View File

@@ -0,0 +1 @@
/home/lenn/Workspace/JE-Skin/src-tauri/target/i686-linux-android/release/libtauri_demo_lib.so

View File

@@ -0,0 +1 @@
/home/lenn/Workspace/JE-Skin/src-tauri/target/x86_64-linux-android/release/libtauri_demo_lib.so

View File

@@ -0,0 +1,6 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
val implementation by configurations
dependencies {
implementation(project(":tauri-android"))
implementation(project(":tauri-plugin-opener"))
}

View File

@@ -0,0 +1,3 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
tauri.android.versionName=0.4.0
tauri.android.versionCode=4000

View File

@@ -0,0 +1,5 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
include ':tauri-android'
project(':tauri-android').projectDir = new File("/home/lenn/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.10.3/mobile/android")
include ':tauri-plugin-opener'
project(':tauri-plugin-opener').projectDir = new File("/home/lenn/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-opener-2.5.3/android")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src-tauri/icons/16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

BIN
src-tauri/icons/192x192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
src-tauri/icons/256x256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src-tauri/icons/512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
src-tauri/icons/64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<background android:drawable="@color/ic_launcher_background"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#fff</color>
</resources>

BIN
src-tauri/icons/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src-tauri/icons/icon.icns Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Some files were not shown because too many files have changed in this diff Show More