Spaces:
Running
Running
Commit
·
e2a9158
1
Parent(s):
ec4ef43
copy from app in xet-core
Browse files- APP_README.md +98 -0
- index.html +0 -13
- package.json +27 -18
- pnpm-lock.yaml +964 -0
- public/vite.svg +0 -1
- src/App.svelte +0 -47
- src/app.css +0 -79
- src/app.d.ts +13 -0
- src/app.html +16 -0
- src/assets/svelte.svg +0 -1
- src/lib/Counter.svelte +0 -10
- src/lib/assets/favicon.svg +1 -0
- src/lib/components/ErrorDisplay.svelte +101 -0
- src/lib/components/FileUpload.svelte +241 -0
- src/lib/components/ShardViewer.svelte +543 -0
- src/lib/components/XorbViewer.svelte +273 -0
- src/lib/index.ts +1 -0
- src/lib/parsers.ts +412 -0
- src/lib/types.ts +119 -0
- src/main.ts +0 -9
- src/routes/+layout.svelte +11 -0
- src/routes/+page.svelte +305 -0
- src/vite-env.d.ts +0 -2
- static/robots.txt +3 -0
- svelte.config.js +17 -6
- tsconfig.app.json +0 -20
- tsconfig.json +17 -5
- tsconfig.node.json +0 -25
- vite.config.ts +4 -5
APP_README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# XORB & Shard File Viewer
|
| 2 |
+
|
| 3 |
+
A static web application built with Svelte that allows you to upload and analyze XORB or Shard object files to view their metadata structure.
|
| 4 |
+
|
| 5 |
+
## Features
|
| 6 |
+
|
| 7 |
+
- **File Upload**: Drag & drop or click to upload XORB and Shard files
|
| 8 |
+
- **Automatic Detection**: Automatically detects file type based on binary structure
|
| 9 |
+
- **Comprehensive Metadata Display**: Shows detailed information about file contents
|
| 10 |
+
- **Responsive Design**: Works on desktop and mobile devices
|
| 11 |
+
- **Error Handling**: Provides clear error messages for invalid files
|
| 12 |
+
|
| 13 |
+
## Supported File Types
|
| 14 |
+
|
| 15 |
+
### 📦 XORB Files
|
| 16 |
+
|
| 17 |
+
XORB (Xet Orb) files contain collections of compressed chunks with metadata. The viewer displays:
|
| 18 |
+
|
| 19 |
+
- Chunk count and sizes
|
| 20 |
+
- Compression ratios
|
| 21 |
+
- Hash information
|
| 22 |
+
- Boundary offsets
|
| 23 |
+
- Individual chunk details
|
| 24 |
+
|
| 25 |
+
### 🗂️ Shard Files
|
| 26 |
+
|
| 27 |
+
MDB Shard files store file metadata and content-addressable storage information for efficient deduplication. The viewer shows:
|
| 28 |
+
|
| 29 |
+
- File information entries
|
| 30 |
+
- CAS (Content Addressable Storage) data
|
| 31 |
+
- Lookup tables
|
| 32 |
+
- Timestamps and security keys
|
| 33 |
+
- Header and footer details
|
| 34 |
+
|
| 35 |
+
## Development
|
| 36 |
+
|
| 37 |
+
### Prerequisites
|
| 38 |
+
|
| 39 |
+
- Node.js 18+
|
| 40 |
+
- pnpm (or npm/yarn)
|
| 41 |
+
|
| 42 |
+
### Setup
|
| 43 |
+
|
| 44 |
+
```bash
|
| 45 |
+
cd xorb-shard-viewer
|
| 46 |
+
pnpm install
|
| 47 |
+
pnpm run dev
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
The application will be available at `http://localhost:5173`
|
| 51 |
+
|
| 52 |
+
### Build for Production
|
| 53 |
+
|
| 54 |
+
```bash
|
| 55 |
+
pnpm run build
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
The static files will be generated in the `build` directory.
|
| 59 |
+
|
| 60 |
+
## File Format Support
|
| 61 |
+
|
| 62 |
+
The application implements binary parsers for:
|
| 63 |
+
|
| 64 |
+
- **XORB Format**: Based on the CAS object format with chunk compression and merkle hashing
|
| 65 |
+
- **Shard Format**: MDB shard file format v2 with header, footer, file info, and CAS info sections
|
| 66 |
+
|
| 67 |
+
## Architecture
|
| 68 |
+
|
| 69 |
+
- **Frontend**: Svelte + TypeScript
|
| 70 |
+
- **Parsing**: Custom binary parsers for both file formats
|
| 71 |
+
- **Styling**: Component-scoped CSS with responsive design
|
| 72 |
+
- **Type Safety**: Full TypeScript support with detailed type definitions
|
| 73 |
+
|
| 74 |
+
## Browser Compatibility
|
| 75 |
+
|
| 76 |
+
Works in all modern browsers that support:
|
| 77 |
+
|
| 78 |
+
- File API
|
| 79 |
+
- ArrayBuffer/Uint8Array
|
| 80 |
+
- ES2020+ features
|
| 81 |
+
|
| 82 |
+
## Security
|
| 83 |
+
|
| 84 |
+
- All file processing happens client-side
|
| 85 |
+
- No data is uploaded to any server
|
| 86 |
+
- Files are processed entirely in the browser's memory
|
| 87 |
+
|
| 88 |
+
## Contributing
|
| 89 |
+
|
| 90 |
+
1. Fork the repository
|
| 91 |
+
2. Create a feature branch
|
| 92 |
+
3. Make your changes
|
| 93 |
+
4. Test thoroughly
|
| 94 |
+
5. Submit a pull request
|
| 95 |
+
|
| 96 |
+
## License
|
| 97 |
+
|
| 98 |
+
See the parent repository's LICENSE file for licensing information.
|
index.html
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
<!doctype html>
|
| 2 |
-
<html lang="en">
|
| 3 |
-
<head>
|
| 4 |
-
<meta charset="UTF-8" />
|
| 5 |
-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
-
<title>Vite + Svelte + TS</title>
|
| 8 |
-
</head>
|
| 9 |
-
<body>
|
| 10 |
-
<div id="app"></div>
|
| 11 |
-
<script type="module" src="/src/main.ts"></script>
|
| 12 |
-
</body>
|
| 13 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package.json
CHANGED
|
@@ -1,20 +1,29 @@
|
|
| 1 |
{
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
}
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "xorb-shard-viewer",
|
| 3 |
+
"private": true,
|
| 4 |
+
"version": "0.0.1",
|
| 5 |
+
"type": "module",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "vite dev",
|
| 8 |
+
"build": "vite build",
|
| 9 |
+
"preview": "vite preview",
|
| 10 |
+
"prepare": "svelte-kit sync || echo ''",
|
| 11 |
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
| 12 |
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
| 13 |
+
},
|
| 14 |
+
"devDependencies": {
|
| 15 |
+
"@sveltejs/adapter-auto": "^6.0.0",
|
| 16 |
+
"@sveltejs/kit": "^2.22.0",
|
| 17 |
+
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
| 18 |
+
"svelte": "^5.0.0",
|
| 19 |
+
"svelte-check": "^4.0.0",
|
| 20 |
+
"typescript": "^5.0.0",
|
| 21 |
+
"vite": "^7.0.4"
|
| 22 |
+
},
|
| 23 |
+
"pnpm": {
|
| 24 |
+
"onlyBuiltDependencies": [
|
| 25 |
+
"esbuild"
|
| 26 |
+
]
|
| 27 |
+
},
|
| 28 |
+
"packageManager": "[email protected]+sha512.e519b9f7639869dc8d5c3c5dfef73b3f091094b0a006d7317353c72b124e80e1afd429732e28705ad6bfa1ee879c1fce46c128ccebd3192101f43dd67c667912"
|
| 29 |
}
|
pnpm-lock.yaml
ADDED
|
@@ -0,0 +1,964 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
lockfileVersion: '9.0'
|
| 2 |
+
|
| 3 |
+
settings:
|
| 4 |
+
autoInstallPeers: true
|
| 5 |
+
excludeLinksFromLockfile: false
|
| 6 |
+
|
| 7 |
+
importers:
|
| 8 |
+
|
| 9 |
+
.:
|
| 10 |
+
devDependencies:
|
| 11 |
+
'@sveltejs/adapter-auto':
|
| 12 |
+
specifier: ^6.0.0
|
| 13 |
+
version: 6.0.1(@sveltejs/[email protected](@sveltejs/[email protected]([email protected])([email protected]))([email protected])([email protected]))
|
| 14 |
+
'@sveltejs/kit':
|
| 15 |
+
specifier: ^2.22.0
|
| 16 |
+
version: 2.27.0(@sveltejs/[email protected]([email protected])([email protected]))([email protected])([email protected])
|
| 17 |
+
'@sveltejs/vite-plugin-svelte':
|
| 18 |
+
specifier: ^6.0.0
|
| 19 |
+
version: 6.1.0([email protected])([email protected])
|
| 20 |
+
svelte:
|
| 21 |
+
specifier: ^5.0.0
|
| 22 |
+
version: 5.37.3
|
| 23 |
+
svelte-check:
|
| 24 |
+
specifier: ^4.0.0
|
| 25 |
+
version: 4.3.1([email protected])([email protected])([email protected])
|
| 26 |
+
typescript:
|
| 27 |
+
specifier: ^5.0.0
|
| 28 |
+
version: 5.9.2
|
| 29 |
+
vite:
|
| 30 |
+
specifier: ^7.0.4
|
| 31 |
+
version: 7.0.6
|
| 32 |
+
|
| 33 |
+
packages:
|
| 34 |
+
|
| 35 |
+
'@ampproject/[email protected]':
|
| 36 |
+
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
| 37 |
+
engines: {node: '>=6.0.0'}
|
| 38 |
+
|
| 39 |
+
'@esbuild/[email protected]':
|
| 40 |
+
resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==}
|
| 41 |
+
engines: {node: '>=18'}
|
| 42 |
+
cpu: [ppc64]
|
| 43 |
+
os: [aix]
|
| 44 |
+
|
| 45 |
+
'@esbuild/[email protected]':
|
| 46 |
+
resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==}
|
| 47 |
+
engines: {node: '>=18'}
|
| 48 |
+
cpu: [arm64]
|
| 49 |
+
os: [android]
|
| 50 |
+
|
| 51 |
+
'@esbuild/[email protected]':
|
| 52 |
+
resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==}
|
| 53 |
+
engines: {node: '>=18'}
|
| 54 |
+
cpu: [arm]
|
| 55 |
+
os: [android]
|
| 56 |
+
|
| 57 |
+
'@esbuild/[email protected]':
|
| 58 |
+
resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==}
|
| 59 |
+
engines: {node: '>=18'}
|
| 60 |
+
cpu: [x64]
|
| 61 |
+
os: [android]
|
| 62 |
+
|
| 63 |
+
'@esbuild/[email protected]':
|
| 64 |
+
resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==}
|
| 65 |
+
engines: {node: '>=18'}
|
| 66 |
+
cpu: [arm64]
|
| 67 |
+
os: [darwin]
|
| 68 |
+
|
| 69 |
+
'@esbuild/[email protected]':
|
| 70 |
+
resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==}
|
| 71 |
+
engines: {node: '>=18'}
|
| 72 |
+
cpu: [x64]
|
| 73 |
+
os: [darwin]
|
| 74 |
+
|
| 75 |
+
'@esbuild/[email protected]':
|
| 76 |
+
resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==}
|
| 77 |
+
engines: {node: '>=18'}
|
| 78 |
+
cpu: [arm64]
|
| 79 |
+
os: [freebsd]
|
| 80 |
+
|
| 81 |
+
'@esbuild/[email protected]':
|
| 82 |
+
resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==}
|
| 83 |
+
engines: {node: '>=18'}
|
| 84 |
+
cpu: [x64]
|
| 85 |
+
os: [freebsd]
|
| 86 |
+
|
| 87 |
+
'@esbuild/[email protected]':
|
| 88 |
+
resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==}
|
| 89 |
+
engines: {node: '>=18'}
|
| 90 |
+
cpu: [arm64]
|
| 91 |
+
os: [linux]
|
| 92 |
+
|
| 93 |
+
'@esbuild/[email protected]':
|
| 94 |
+
resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==}
|
| 95 |
+
engines: {node: '>=18'}
|
| 96 |
+
cpu: [arm]
|
| 97 |
+
os: [linux]
|
| 98 |
+
|
| 99 |
+
'@esbuild/[email protected]':
|
| 100 |
+
resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==}
|
| 101 |
+
engines: {node: '>=18'}
|
| 102 |
+
cpu: [ia32]
|
| 103 |
+
os: [linux]
|
| 104 |
+
|
| 105 |
+
'@esbuild/[email protected]':
|
| 106 |
+
resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==}
|
| 107 |
+
engines: {node: '>=18'}
|
| 108 |
+
cpu: [loong64]
|
| 109 |
+
os: [linux]
|
| 110 |
+
|
| 111 |
+
'@esbuild/[email protected]':
|
| 112 |
+
resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==}
|
| 113 |
+
engines: {node: '>=18'}
|
| 114 |
+
cpu: [mips64el]
|
| 115 |
+
os: [linux]
|
| 116 |
+
|
| 117 |
+
'@esbuild/[email protected]':
|
| 118 |
+
resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==}
|
| 119 |
+
engines: {node: '>=18'}
|
| 120 |
+
cpu: [ppc64]
|
| 121 |
+
os: [linux]
|
| 122 |
+
|
| 123 |
+
'@esbuild/[email protected]':
|
| 124 |
+
resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==}
|
| 125 |
+
engines: {node: '>=18'}
|
| 126 |
+
cpu: [riscv64]
|
| 127 |
+
os: [linux]
|
| 128 |
+
|
| 129 |
+
'@esbuild/[email protected]':
|
| 130 |
+
resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==}
|
| 131 |
+
engines: {node: '>=18'}
|
| 132 |
+
cpu: [s390x]
|
| 133 |
+
os: [linux]
|
| 134 |
+
|
| 135 |
+
'@esbuild/[email protected]':
|
| 136 |
+
resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==}
|
| 137 |
+
engines: {node: '>=18'}
|
| 138 |
+
cpu: [x64]
|
| 139 |
+
os: [linux]
|
| 140 |
+
|
| 141 |
+
'@esbuild/[email protected]':
|
| 142 |
+
resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==}
|
| 143 |
+
engines: {node: '>=18'}
|
| 144 |
+
cpu: [arm64]
|
| 145 |
+
os: [netbsd]
|
| 146 |
+
|
| 147 |
+
'@esbuild/[email protected]':
|
| 148 |
+
resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==}
|
| 149 |
+
engines: {node: '>=18'}
|
| 150 |
+
cpu: [x64]
|
| 151 |
+
os: [netbsd]
|
| 152 |
+
|
| 153 |
+
'@esbuild/[email protected]':
|
| 154 |
+
resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==}
|
| 155 |
+
engines: {node: '>=18'}
|
| 156 |
+
cpu: [arm64]
|
| 157 |
+
os: [openbsd]
|
| 158 |
+
|
| 159 |
+
'@esbuild/[email protected]':
|
| 160 |
+
resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==}
|
| 161 |
+
engines: {node: '>=18'}
|
| 162 |
+
cpu: [x64]
|
| 163 |
+
os: [openbsd]
|
| 164 |
+
|
| 165 |
+
'@esbuild/[email protected]':
|
| 166 |
+
resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==}
|
| 167 |
+
engines: {node: '>=18'}
|
| 168 |
+
cpu: [arm64]
|
| 169 |
+
os: [openharmony]
|
| 170 |
+
|
| 171 |
+
'@esbuild/[email protected]':
|
| 172 |
+
resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==}
|
| 173 |
+
engines: {node: '>=18'}
|
| 174 |
+
cpu: [x64]
|
| 175 |
+
os: [sunos]
|
| 176 |
+
|
| 177 |
+
'@esbuild/[email protected]':
|
| 178 |
+
resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==}
|
| 179 |
+
engines: {node: '>=18'}
|
| 180 |
+
cpu: [arm64]
|
| 181 |
+
os: [win32]
|
| 182 |
+
|
| 183 |
+
'@esbuild/[email protected]':
|
| 184 |
+
resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==}
|
| 185 |
+
engines: {node: '>=18'}
|
| 186 |
+
cpu: [ia32]
|
| 187 |
+
os: [win32]
|
| 188 |
+
|
| 189 |
+
'@esbuild/[email protected]':
|
| 190 |
+
resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==}
|
| 191 |
+
engines: {node: '>=18'}
|
| 192 |
+
cpu: [x64]
|
| 193 |
+
os: [win32]
|
| 194 |
+
|
| 195 |
+
'@jridgewell/[email protected]':
|
| 196 |
+
resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==}
|
| 197 |
+
|
| 198 |
+
'@jridgewell/[email protected]':
|
| 199 |
+
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
| 200 |
+
engines: {node: '>=6.0.0'}
|
| 201 |
+
|
| 202 |
+
'@jridgewell/[email protected]':
|
| 203 |
+
resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==}
|
| 204 |
+
|
| 205 |
+
'@jridgewell/[email protected]':
|
| 206 |
+
resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==}
|
| 207 |
+
|
| 208 |
+
'@polka/[email protected]':
|
| 209 |
+
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
| 210 |
+
|
| 211 |
+
'@rollup/[email protected]':
|
| 212 |
+
resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==}
|
| 213 |
+
cpu: [arm]
|
| 214 |
+
os: [android]
|
| 215 |
+
|
| 216 |
+
'@rollup/[email protected]':
|
| 217 |
+
resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==}
|
| 218 |
+
cpu: [arm64]
|
| 219 |
+
os: [android]
|
| 220 |
+
|
| 221 |
+
'@rollup/[email protected]':
|
| 222 |
+
resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==}
|
| 223 |
+
cpu: [arm64]
|
| 224 |
+
os: [darwin]
|
| 225 |
+
|
| 226 |
+
'@rollup/[email protected]':
|
| 227 |
+
resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==}
|
| 228 |
+
cpu: [x64]
|
| 229 |
+
os: [darwin]
|
| 230 |
+
|
| 231 |
+
'@rollup/[email protected]':
|
| 232 |
+
resolution: {integrity: sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==}
|
| 233 |
+
cpu: [arm64]
|
| 234 |
+
os: [freebsd]
|
| 235 |
+
|
| 236 |
+
'@rollup/[email protected]':
|
| 237 |
+
resolution: {integrity: sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==}
|
| 238 |
+
cpu: [x64]
|
| 239 |
+
os: [freebsd]
|
| 240 |
+
|
| 241 |
+
'@rollup/[email protected]':
|
| 242 |
+
resolution: {integrity: sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==}
|
| 243 |
+
cpu: [arm]
|
| 244 |
+
os: [linux]
|
| 245 |
+
|
| 246 |
+
'@rollup/[email protected]':
|
| 247 |
+
resolution: {integrity: sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==}
|
| 248 |
+
cpu: [arm]
|
| 249 |
+
os: [linux]
|
| 250 |
+
|
| 251 |
+
'@rollup/[email protected]':
|
| 252 |
+
resolution: {integrity: sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==}
|
| 253 |
+
cpu: [arm64]
|
| 254 |
+
os: [linux]
|
| 255 |
+
|
| 256 |
+
'@rollup/[email protected]':
|
| 257 |
+
resolution: {integrity: sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==}
|
| 258 |
+
cpu: [arm64]
|
| 259 |
+
os: [linux]
|
| 260 |
+
|
| 261 |
+
'@rollup/[email protected]':
|
| 262 |
+
resolution: {integrity: sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==}
|
| 263 |
+
cpu: [loong64]
|
| 264 |
+
os: [linux]
|
| 265 |
+
|
| 266 |
+
'@rollup/[email protected]':
|
| 267 |
+
resolution: {integrity: sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==}
|
| 268 |
+
cpu: [ppc64]
|
| 269 |
+
os: [linux]
|
| 270 |
+
|
| 271 |
+
'@rollup/[email protected]':
|
| 272 |
+
resolution: {integrity: sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==}
|
| 273 |
+
cpu: [riscv64]
|
| 274 |
+
os: [linux]
|
| 275 |
+
|
| 276 |
+
'@rollup/[email protected]':
|
| 277 |
+
resolution: {integrity: sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==}
|
| 278 |
+
cpu: [riscv64]
|
| 279 |
+
os: [linux]
|
| 280 |
+
|
| 281 |
+
'@rollup/[email protected]':
|
| 282 |
+
resolution: {integrity: sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==}
|
| 283 |
+
cpu: [s390x]
|
| 284 |
+
os: [linux]
|
| 285 |
+
|
| 286 |
+
'@rollup/[email protected]':
|
| 287 |
+
resolution: {integrity: sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==}
|
| 288 |
+
cpu: [x64]
|
| 289 |
+
os: [linux]
|
| 290 |
+
|
| 291 |
+
'@rollup/[email protected]':
|
| 292 |
+
resolution: {integrity: sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==}
|
| 293 |
+
cpu: [x64]
|
| 294 |
+
os: [linux]
|
| 295 |
+
|
| 296 |
+
'@rollup/[email protected]':
|
| 297 |
+
resolution: {integrity: sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==}
|
| 298 |
+
cpu: [arm64]
|
| 299 |
+
os: [win32]
|
| 300 |
+
|
| 301 |
+
'@rollup/[email protected]':
|
| 302 |
+
resolution: {integrity: sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==}
|
| 303 |
+
cpu: [ia32]
|
| 304 |
+
os: [win32]
|
| 305 |
+
|
| 306 |
+
'@rollup/[email protected]':
|
| 307 |
+
resolution: {integrity: sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==}
|
| 308 |
+
cpu: [x64]
|
| 309 |
+
os: [win32]
|
| 310 |
+
|
| 311 |
+
'@standard-schema/[email protected]':
|
| 312 |
+
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
|
| 313 |
+
|
| 314 |
+
'@sveltejs/[email protected]':
|
| 315 |
+
resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==}
|
| 316 |
+
peerDependencies:
|
| 317 |
+
acorn: ^8.9.0
|
| 318 |
+
|
| 319 |
+
'@sveltejs/[email protected]':
|
| 320 |
+
resolution: {integrity: sha512-mcWud3pYGPWM2Pphdj8G9Qiq24nZ8L4LB7coCUckUEy5Y7wOWGJ/enaZ4AtJTcSm5dNK1rIkBRoqt+ae4zlxcQ==}
|
| 321 |
+
peerDependencies:
|
| 322 |
+
'@sveltejs/kit': ^2.0.0
|
| 323 |
+
|
| 324 |
+
'@sveltejs/[email protected]':
|
| 325 |
+
resolution: {integrity: sha512-pEX1Z2Km8tqmkni+ykIIou+ojp/7gb3M9tpllN5nDWNo9zlI0dI8/hDKFyBwQvb4jYR+EyLriFtrmgJ6GvbnBA==}
|
| 326 |
+
engines: {node: '>=18.13'}
|
| 327 |
+
hasBin: true
|
| 328 |
+
peerDependencies:
|
| 329 |
+
'@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0
|
| 330 |
+
svelte: ^4.0.0 || ^5.0.0-next.0
|
| 331 |
+
vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0
|
| 332 |
+
|
| 333 |
+
'@sveltejs/[email protected]':
|
| 334 |
+
resolution: {integrity: sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ==}
|
| 335 |
+
engines: {node: ^20.19 || ^22.12 || >=24}
|
| 336 |
+
peerDependencies:
|
| 337 |
+
'@sveltejs/vite-plugin-svelte': ^6.0.0-next.0
|
| 338 |
+
svelte: ^5.0.0
|
| 339 |
+
vite: ^6.3.0 || ^7.0.0
|
| 340 |
+
|
| 341 |
+
'@sveltejs/[email protected]':
|
| 342 |
+
resolution: {integrity: sha512-+U6lz1wvGEG/BvQyL4z/flyNdQ9xDNv5vrh+vWBWTHaebqT0c9RNggpZTo/XSPoHsSCWBlYaTlRX8pZ9GATXCw==}
|
| 343 |
+
engines: {node: ^20.19 || ^22.12 || >=24}
|
| 344 |
+
peerDependencies:
|
| 345 |
+
svelte: ^5.0.0
|
| 346 |
+
vite: ^6.3.0 || ^7.0.0
|
| 347 |
+
|
| 348 |
+
'@types/[email protected]':
|
| 349 |
+
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
| 350 |
+
|
| 351 |
+
'@types/[email protected]':
|
| 352 |
+
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
| 353 |
+
|
| 354 | |
| 355 |
+
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
|
| 356 |
+
engines: {node: '>=0.4.0'}
|
| 357 |
+
hasBin: true
|
| 358 |
+
|
| 359 | |
| 360 |
+
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
|
| 361 |
+
engines: {node: '>= 0.4'}
|
| 362 |
+
|
| 363 | |
| 364 |
+
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
|
| 365 |
+
engines: {node: '>= 0.4'}
|
| 366 |
+
|
| 367 | |
| 368 |
+
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
|
| 369 |
+
engines: {node: '>= 14.16.0'}
|
| 370 |
+
|
| 371 | |
| 372 |
+
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
| 373 |
+
engines: {node: '>=6'}
|
| 374 |
+
|
| 375 | |
| 376 |
+
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
|
| 377 |
+
engines: {node: '>= 0.6'}
|
| 378 |
+
|
| 379 | |
| 380 |
+
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
| 381 |
+
engines: {node: '>=6.0'}
|
| 382 |
+
peerDependencies:
|
| 383 |
+
supports-color: '*'
|
| 384 |
+
peerDependenciesMeta:
|
| 385 |
+
supports-color:
|
| 386 |
+
optional: true
|
| 387 |
+
|
| 388 | |
| 389 |
+
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
| 390 |
+
engines: {node: '>=0.10.0'}
|
| 391 |
+
|
| 392 | |
| 393 |
+
resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==}
|
| 394 |
+
|
| 395 | |
| 396 |
+
resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==}
|
| 397 |
+
engines: {node: '>=18'}
|
| 398 |
+
hasBin: true
|
| 399 |
+
|
| 400 | |
| 401 |
+
resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==}
|
| 402 |
+
|
| 403 | |
| 404 |
+
resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==}
|
| 405 |
+
|
| 406 | |
| 407 |
+
resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==}
|
| 408 |
+
peerDependencies:
|
| 409 |
+
picomatch: ^3 || ^4
|
| 410 |
+
peerDependenciesMeta:
|
| 411 |
+
picomatch:
|
| 412 |
+
optional: true
|
| 413 |
+
|
| 414 | |
| 415 |
+
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
| 416 |
+
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
| 417 |
+
os: [darwin]
|
| 418 |
+
|
| 419 | |
| 420 |
+
resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==}
|
| 421 |
+
|
| 422 | |
| 423 |
+
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
| 424 |
+
engines: {node: '>=6'}
|
| 425 |
+
|
| 426 | |
| 427 |
+
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
|
| 428 |
+
|
| 429 | |
| 430 |
+
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
| 431 |
+
|
| 432 | |
| 433 |
+
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
| 434 |
+
engines: {node: '>=4'}
|
| 435 |
+
|
| 436 | |
| 437 |
+
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
| 438 |
+
engines: {node: '>=10'}
|
| 439 |
+
|
| 440 | |
| 441 |
+
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
| 442 |
+
|
| 443 | |
| 444 |
+
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
| 445 |
+
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
| 446 |
+
hasBin: true
|
| 447 |
+
|
| 448 | |
| 449 |
+
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
| 450 |
+
|
| 451 | |
| 452 |
+
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
| 453 |
+
engines: {node: '>=12'}
|
| 454 |
+
|
| 455 | |
| 456 |
+
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
| 457 |
+
engines: {node: ^10 || ^12 || >=14}
|
| 458 |
+
|
| 459 | |
| 460 |
+
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
| 461 |
+
engines: {node: '>= 14.18.0'}
|
| 462 |
+
|
| 463 | |
| 464 |
+
resolution: {integrity: sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==}
|
| 465 |
+
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
| 466 |
+
hasBin: true
|
| 467 |
+
|
| 468 | |
| 469 |
+
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
|
| 470 |
+
engines: {node: '>=6'}
|
| 471 |
+
|
| 472 | |
| 473 |
+
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
|
| 474 |
+
|
| 475 | |
| 476 |
+
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
|
| 477 |
+
engines: {node: '>=18'}
|
| 478 |
+
|
| 479 | |
| 480 |
+
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
| 481 |
+
engines: {node: '>=0.10.0'}
|
| 482 |
+
|
| 483 | |
| 484 |
+
resolution: {integrity: sha512-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg==}
|
| 485 |
+
engines: {node: '>= 18.0.0'}
|
| 486 |
+
hasBin: true
|
| 487 |
+
peerDependencies:
|
| 488 |
+
svelte: ^4.0.0 || ^5.0.0-next.0
|
| 489 |
+
typescript: '>=5.0.0'
|
| 490 |
+
|
| 491 | |
| 492 |
+
resolution: {integrity: sha512-7t/ejshehHd+95z3Z7ebS7wsqHDQxi/8nBTuTRwpMgNegfRBfuitCSKTUDKIBOExqfT2+DhQ2VLG8Xn+cBXoaQ==}
|
| 493 |
+
engines: {node: '>=18'}
|
| 494 |
+
|
| 495 | |
| 496 |
+
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
|
| 497 |
+
engines: {node: '>=12.0.0'}
|
| 498 |
+
|
| 499 | |
| 500 |
+
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
| 501 |
+
engines: {node: '>=6'}
|
| 502 |
+
|
| 503 | |
| 504 |
+
resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==}
|
| 505 |
+
engines: {node: '>=14.17'}
|
| 506 |
+
hasBin: true
|
| 507 |
+
|
| 508 | |
| 509 |
+
resolution: {integrity: sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==}
|
| 510 |
+
engines: {node: ^20.19.0 || >=22.12.0}
|
| 511 |
+
hasBin: true
|
| 512 |
+
peerDependencies:
|
| 513 |
+
'@types/node': ^20.19.0 || >=22.12.0
|
| 514 |
+
jiti: '>=1.21.0'
|
| 515 |
+
less: ^4.0.0
|
| 516 |
+
lightningcss: ^1.21.0
|
| 517 |
+
sass: ^1.70.0
|
| 518 |
+
sass-embedded: ^1.70.0
|
| 519 |
+
stylus: '>=0.54.8'
|
| 520 |
+
sugarss: ^5.0.0
|
| 521 |
+
terser: ^5.16.0
|
| 522 |
+
tsx: ^4.8.1
|
| 523 |
+
yaml: ^2.4.2
|
| 524 |
+
peerDependenciesMeta:
|
| 525 |
+
'@types/node':
|
| 526 |
+
optional: true
|
| 527 |
+
jiti:
|
| 528 |
+
optional: true
|
| 529 |
+
less:
|
| 530 |
+
optional: true
|
| 531 |
+
lightningcss:
|
| 532 |
+
optional: true
|
| 533 |
+
sass:
|
| 534 |
+
optional: true
|
| 535 |
+
sass-embedded:
|
| 536 |
+
optional: true
|
| 537 |
+
stylus:
|
| 538 |
+
optional: true
|
| 539 |
+
sugarss:
|
| 540 |
+
optional: true
|
| 541 |
+
terser:
|
| 542 |
+
optional: true
|
| 543 |
+
tsx:
|
| 544 |
+
optional: true
|
| 545 |
+
yaml:
|
| 546 |
+
optional: true
|
| 547 |
+
|
| 548 | |
| 549 |
+
resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==}
|
| 550 |
+
peerDependencies:
|
| 551 |
+
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0
|
| 552 |
+
peerDependenciesMeta:
|
| 553 |
+
vite:
|
| 554 |
+
optional: true
|
| 555 |
+
|
| 556 | |
| 557 |
+
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
|
| 558 |
+
|
| 559 |
+
snapshots:
|
| 560 |
+
|
| 561 |
+
'@ampproject/[email protected]':
|
| 562 |
+
dependencies:
|
| 563 |
+
'@jridgewell/gen-mapping': 0.3.12
|
| 564 |
+
'@jridgewell/trace-mapping': 0.3.29
|
| 565 |
+
|
| 566 |
+
'@esbuild/[email protected]':
|
| 567 |
+
optional: true
|
| 568 |
+
|
| 569 |
+
'@esbuild/[email protected]':
|
| 570 |
+
optional: true
|
| 571 |
+
|
| 572 |
+
'@esbuild/[email protected]':
|
| 573 |
+
optional: true
|
| 574 |
+
|
| 575 |
+
'@esbuild/[email protected]':
|
| 576 |
+
optional: true
|
| 577 |
+
|
| 578 |
+
'@esbuild/[email protected]':
|
| 579 |
+
optional: true
|
| 580 |
+
|
| 581 |
+
'@esbuild/[email protected]':
|
| 582 |
+
optional: true
|
| 583 |
+
|
| 584 |
+
'@esbuild/[email protected]':
|
| 585 |
+
optional: true
|
| 586 |
+
|
| 587 |
+
'@esbuild/[email protected]':
|
| 588 |
+
optional: true
|
| 589 |
+
|
| 590 |
+
'@esbuild/[email protected]':
|
| 591 |
+
optional: true
|
| 592 |
+
|
| 593 |
+
'@esbuild/[email protected]':
|
| 594 |
+
optional: true
|
| 595 |
+
|
| 596 |
+
'@esbuild/[email protected]':
|
| 597 |
+
optional: true
|
| 598 |
+
|
| 599 |
+
'@esbuild/[email protected]':
|
| 600 |
+
optional: true
|
| 601 |
+
|
| 602 |
+
'@esbuild/[email protected]':
|
| 603 |
+
optional: true
|
| 604 |
+
|
| 605 |
+
'@esbuild/[email protected]':
|
| 606 |
+
optional: true
|
| 607 |
+
|
| 608 |
+
'@esbuild/[email protected]':
|
| 609 |
+
optional: true
|
| 610 |
+
|
| 611 |
+
'@esbuild/[email protected]':
|
| 612 |
+
optional: true
|
| 613 |
+
|
| 614 |
+
'@esbuild/[email protected]':
|
| 615 |
+
optional: true
|
| 616 |
+
|
| 617 |
+
'@esbuild/[email protected]':
|
| 618 |
+
optional: true
|
| 619 |
+
|
| 620 |
+
'@esbuild/[email protected]':
|
| 621 |
+
optional: true
|
| 622 |
+
|
| 623 |
+
'@esbuild/[email protected]':
|
| 624 |
+
optional: true
|
| 625 |
+
|
| 626 |
+
'@esbuild/[email protected]':
|
| 627 |
+
optional: true
|
| 628 |
+
|
| 629 |
+
'@esbuild/[email protected]':
|
| 630 |
+
optional: true
|
| 631 |
+
|
| 632 |
+
'@esbuild/[email protected]':
|
| 633 |
+
optional: true
|
| 634 |
+
|
| 635 |
+
'@esbuild/[email protected]':
|
| 636 |
+
optional: true
|
| 637 |
+
|
| 638 |
+
'@esbuild/[email protected]':
|
| 639 |
+
optional: true
|
| 640 |
+
|
| 641 |
+
'@esbuild/[email protected]':
|
| 642 |
+
optional: true
|
| 643 |
+
|
| 644 |
+
'@jridgewell/[email protected]':
|
| 645 |
+
dependencies:
|
| 646 |
+
'@jridgewell/sourcemap-codec': 1.5.4
|
| 647 |
+
'@jridgewell/trace-mapping': 0.3.29
|
| 648 |
+
|
| 649 |
+
'@jridgewell/[email protected]': {}
|
| 650 |
+
|
| 651 |
+
'@jridgewell/[email protected]': {}
|
| 652 |
+
|
| 653 |
+
'@jridgewell/[email protected]':
|
| 654 |
+
dependencies:
|
| 655 |
+
'@jridgewell/resolve-uri': 3.1.2
|
| 656 |
+
'@jridgewell/sourcemap-codec': 1.5.4
|
| 657 |
+
|
| 658 |
+
'@polka/[email protected]': {}
|
| 659 |
+
|
| 660 |
+
'@rollup/[email protected]':
|
| 661 |
+
optional: true
|
| 662 |
+
|
| 663 |
+
'@rollup/[email protected]':
|
| 664 |
+
optional: true
|
| 665 |
+
|
| 666 |
+
'@rollup/[email protected]':
|
| 667 |
+
optional: true
|
| 668 |
+
|
| 669 |
+
'@rollup/[email protected]':
|
| 670 |
+
optional: true
|
| 671 |
+
|
| 672 |
+
'@rollup/[email protected]':
|
| 673 |
+
optional: true
|
| 674 |
+
|
| 675 |
+
'@rollup/[email protected]':
|
| 676 |
+
optional: true
|
| 677 |
+
|
| 678 |
+
'@rollup/[email protected]':
|
| 679 |
+
optional: true
|
| 680 |
+
|
| 681 |
+
'@rollup/[email protected]':
|
| 682 |
+
optional: true
|
| 683 |
+
|
| 684 |
+
'@rollup/[email protected]':
|
| 685 |
+
optional: true
|
| 686 |
+
|
| 687 |
+
'@rollup/[email protected]':
|
| 688 |
+
optional: true
|
| 689 |
+
|
| 690 |
+
'@rollup/[email protected]':
|
| 691 |
+
optional: true
|
| 692 |
+
|
| 693 |
+
'@rollup/[email protected]':
|
| 694 |
+
optional: true
|
| 695 |
+
|
| 696 |
+
'@rollup/[email protected]':
|
| 697 |
+
optional: true
|
| 698 |
+
|
| 699 |
+
'@rollup/[email protected]':
|
| 700 |
+
optional: true
|
| 701 |
+
|
| 702 |
+
'@rollup/[email protected]':
|
| 703 |
+
optional: true
|
| 704 |
+
|
| 705 |
+
'@rollup/[email protected]':
|
| 706 |
+
optional: true
|
| 707 |
+
|
| 708 |
+
'@rollup/[email protected]':
|
| 709 |
+
optional: true
|
| 710 |
+
|
| 711 |
+
'@rollup/[email protected]':
|
| 712 |
+
optional: true
|
| 713 |
+
|
| 714 |
+
'@rollup/[email protected]':
|
| 715 |
+
optional: true
|
| 716 |
+
|
| 717 |
+
'@rollup/[email protected]':
|
| 718 |
+
optional: true
|
| 719 |
+
|
| 720 |
+
'@standard-schema/[email protected]': {}
|
| 721 |
+
|
| 722 |
+
'@sveltejs/[email protected]([email protected])':
|
| 723 |
+
dependencies:
|
| 724 |
+
acorn: 8.15.0
|
| 725 |
+
|
| 726 |
+
'@sveltejs/[email protected](@sveltejs/[email protected](@sveltejs/[email protected]([email protected])([email protected]))([email protected])([email protected]))':
|
| 727 |
+
dependencies:
|
| 728 |
+
'@sveltejs/kit': 2.27.0(@sveltejs/[email protected]([email protected])([email protected]))([email protected])([email protected])
|
| 729 |
+
|
| 730 |
+
'@sveltejs/[email protected](@sveltejs/[email protected]([email protected])([email protected]))([email protected])([email protected])':
|
| 731 |
+
dependencies:
|
| 732 |
+
'@standard-schema/spec': 1.0.0
|
| 733 |
+
'@sveltejs/acorn-typescript': 1.0.5([email protected])
|
| 734 |
+
'@sveltejs/vite-plugin-svelte': 6.1.0([email protected])([email protected])
|
| 735 |
+
'@types/cookie': 0.6.0
|
| 736 |
+
acorn: 8.15.0
|
| 737 |
+
cookie: 0.6.0
|
| 738 |
+
devalue: 5.1.1
|
| 739 |
+
esm-env: 1.2.2
|
| 740 |
+
kleur: 4.1.5
|
| 741 |
+
magic-string: 0.30.17
|
| 742 |
+
mrmime: 2.0.1
|
| 743 |
+
sade: 1.8.1
|
| 744 |
+
set-cookie-parser: 2.7.1
|
| 745 |
+
sirv: 3.0.1
|
| 746 |
+
svelte: 5.37.3
|
| 747 |
+
vite: 7.0.6
|
| 748 |
+
|
| 749 |
+
'@sveltejs/[email protected](@sveltejs/[email protected]([email protected])([email protected]))([email protected])([email protected])':
|
| 750 |
+
dependencies:
|
| 751 |
+
'@sveltejs/vite-plugin-svelte': 6.1.0([email protected])([email protected])
|
| 752 |
+
debug: 4.4.1
|
| 753 |
+
svelte: 5.37.3
|
| 754 |
+
vite: 7.0.6
|
| 755 |
+
transitivePeerDependencies:
|
| 756 |
+
- supports-color
|
| 757 |
+
|
| 758 |
+
'@sveltejs/[email protected]([email protected])([email protected])':
|
| 759 |
+
dependencies:
|
| 760 |
+
'@sveltejs/vite-plugin-svelte-inspector': 5.0.0(@sveltejs/[email protected]([email protected])([email protected]))([email protected])([email protected])
|
| 761 |
+
debug: 4.4.1
|
| 762 |
+
deepmerge: 4.3.1
|
| 763 |
+
kleur: 4.1.5
|
| 764 |
+
magic-string: 0.30.17
|
| 765 |
+
svelte: 5.37.3
|
| 766 |
+
vite: 7.0.6
|
| 767 |
+
vitefu: 1.1.1([email protected])
|
| 768 |
+
transitivePeerDependencies:
|
| 769 |
+
- supports-color
|
| 770 |
+
|
| 771 |
+
'@types/[email protected]': {}
|
| 772 |
+
|
| 773 |
+
'@types/[email protected]': {}
|
| 774 |
+
|
| 775 |
+
[email protected]: {}
|
| 776 |
+
|
| 777 |
+
[email protected]: {}
|
| 778 |
+
|
| 779 |
+
[email protected]: {}
|
| 780 |
+
|
| 781 | |
| 782 |
+
dependencies:
|
| 783 |
+
readdirp: 4.1.2
|
| 784 |
+
|
| 785 |
+
[email protected]: {}
|
| 786 |
+
|
| 787 |
+
[email protected]: {}
|
| 788 |
+
|
| 789 | |
| 790 |
+
dependencies:
|
| 791 |
+
ms: 2.1.3
|
| 792 |
+
|
| 793 |
+
[email protected]: {}
|
| 794 |
+
|
| 795 |
+
[email protected]: {}
|
| 796 |
+
|
| 797 | |
| 798 |
+
optionalDependencies:
|
| 799 |
+
'@esbuild/aix-ppc64': 0.25.8
|
| 800 |
+
'@esbuild/android-arm': 0.25.8
|
| 801 |
+
'@esbuild/android-arm64': 0.25.8
|
| 802 |
+
'@esbuild/android-x64': 0.25.8
|
| 803 |
+
'@esbuild/darwin-arm64': 0.25.8
|
| 804 |
+
'@esbuild/darwin-x64': 0.25.8
|
| 805 |
+
'@esbuild/freebsd-arm64': 0.25.8
|
| 806 |
+
'@esbuild/freebsd-x64': 0.25.8
|
| 807 |
+
'@esbuild/linux-arm': 0.25.8
|
| 808 |
+
'@esbuild/linux-arm64': 0.25.8
|
| 809 |
+
'@esbuild/linux-ia32': 0.25.8
|
| 810 |
+
'@esbuild/linux-loong64': 0.25.8
|
| 811 |
+
'@esbuild/linux-mips64el': 0.25.8
|
| 812 |
+
'@esbuild/linux-ppc64': 0.25.8
|
| 813 |
+
'@esbuild/linux-riscv64': 0.25.8
|
| 814 |
+
'@esbuild/linux-s390x': 0.25.8
|
| 815 |
+
'@esbuild/linux-x64': 0.25.8
|
| 816 |
+
'@esbuild/netbsd-arm64': 0.25.8
|
| 817 |
+
'@esbuild/netbsd-x64': 0.25.8
|
| 818 |
+
'@esbuild/openbsd-arm64': 0.25.8
|
| 819 |
+
'@esbuild/openbsd-x64': 0.25.8
|
| 820 |
+
'@esbuild/openharmony-arm64': 0.25.8
|
| 821 |
+
'@esbuild/sunos-x64': 0.25.8
|
| 822 |
+
'@esbuild/win32-arm64': 0.25.8
|
| 823 |
+
'@esbuild/win32-ia32': 0.25.8
|
| 824 |
+
'@esbuild/win32-x64': 0.25.8
|
| 825 |
+
|
| 826 |
+
[email protected]: {}
|
| 827 |
+
|
| 828 | |
| 829 |
+
dependencies:
|
| 830 |
+
'@jridgewell/sourcemap-codec': 1.5.4
|
| 831 |
+
|
| 832 | |
| 833 |
+
optionalDependencies:
|
| 834 |
+
picomatch: 4.0.3
|
| 835 |
+
|
| 836 | |
| 837 |
+
optional: true
|
| 838 |
+
|
| 839 | |
| 840 |
+
dependencies:
|
| 841 |
+
'@types/estree': 1.0.8
|
| 842 |
+
|
| 843 |
+
[email protected]: {}
|
| 844 |
+
|
| 845 |
+
[email protected]: {}
|
| 846 |
+
|
| 847 | |
| 848 |
+
dependencies:
|
| 849 |
+
'@jridgewell/sourcemap-codec': 1.5.4
|
| 850 |
+
|
| 851 |
+
[email protected]: {}
|
| 852 |
+
|
| 853 |
+
[email protected]: {}
|
| 854 |
+
|
| 855 |
+
[email protected]: {}
|
| 856 |
+
|
| 857 |
+
[email protected]: {}
|
| 858 |
+
|
| 859 |
+
[email protected]: {}
|
| 860 |
+
|
| 861 |
+
[email protected]: {}
|
| 862 |
+
|
| 863 | |
| 864 |
+
dependencies:
|
| 865 |
+
nanoid: 3.3.11
|
| 866 |
+
picocolors: 1.1.1
|
| 867 |
+
source-map-js: 1.2.1
|
| 868 |
+
|
| 869 |
+
[email protected]: {}
|
| 870 |
+
|
| 871 | |
| 872 |
+
dependencies:
|
| 873 |
+
'@types/estree': 1.0.8
|
| 874 |
+
optionalDependencies:
|
| 875 |
+
'@rollup/rollup-android-arm-eabi': 4.46.2
|
| 876 |
+
'@rollup/rollup-android-arm64': 4.46.2
|
| 877 |
+
'@rollup/rollup-darwin-arm64': 4.46.2
|
| 878 |
+
'@rollup/rollup-darwin-x64': 4.46.2
|
| 879 |
+
'@rollup/rollup-freebsd-arm64': 4.46.2
|
| 880 |
+
'@rollup/rollup-freebsd-x64': 4.46.2
|
| 881 |
+
'@rollup/rollup-linux-arm-gnueabihf': 4.46.2
|
| 882 |
+
'@rollup/rollup-linux-arm-musleabihf': 4.46.2
|
| 883 |
+
'@rollup/rollup-linux-arm64-gnu': 4.46.2
|
| 884 |
+
'@rollup/rollup-linux-arm64-musl': 4.46.2
|
| 885 |
+
'@rollup/rollup-linux-loongarch64-gnu': 4.46.2
|
| 886 |
+
'@rollup/rollup-linux-ppc64-gnu': 4.46.2
|
| 887 |
+
'@rollup/rollup-linux-riscv64-gnu': 4.46.2
|
| 888 |
+
'@rollup/rollup-linux-riscv64-musl': 4.46.2
|
| 889 |
+
'@rollup/rollup-linux-s390x-gnu': 4.46.2
|
| 890 |
+
'@rollup/rollup-linux-x64-gnu': 4.46.2
|
| 891 |
+
'@rollup/rollup-linux-x64-musl': 4.46.2
|
| 892 |
+
'@rollup/rollup-win32-arm64-msvc': 4.46.2
|
| 893 |
+
'@rollup/rollup-win32-ia32-msvc': 4.46.2
|
| 894 |
+
'@rollup/rollup-win32-x64-msvc': 4.46.2
|
| 895 |
+
fsevents: 2.3.3
|
| 896 |
+
|
| 897 | |
| 898 |
+
dependencies:
|
| 899 |
+
mri: 1.2.0
|
| 900 |
+
|
| 901 |
+
[email protected]: {}
|
| 902 |
+
|
| 903 | |
| 904 |
+
dependencies:
|
| 905 |
+
'@polka/url': 1.0.0-next.29
|
| 906 |
+
mrmime: 2.0.1
|
| 907 |
+
totalist: 3.0.1
|
| 908 |
+
|
| 909 |
+
[email protected]: {}
|
| 910 |
+
|
| 911 | |
| 912 |
+
dependencies:
|
| 913 |
+
'@jridgewell/trace-mapping': 0.3.29
|
| 914 |
+
chokidar: 4.0.3
|
| 915 |
+
fdir: 6.4.6([email protected])
|
| 916 |
+
picocolors: 1.1.1
|
| 917 |
+
sade: 1.8.1
|
| 918 |
+
svelte: 5.37.3
|
| 919 |
+
typescript: 5.9.2
|
| 920 |
+
transitivePeerDependencies:
|
| 921 |
+
- picomatch
|
| 922 |
+
|
| 923 | |
| 924 |
+
dependencies:
|
| 925 |
+
'@ampproject/remapping': 2.3.0
|
| 926 |
+
'@jridgewell/sourcemap-codec': 1.5.4
|
| 927 |
+
'@sveltejs/acorn-typescript': 1.0.5([email protected])
|
| 928 |
+
'@types/estree': 1.0.8
|
| 929 |
+
acorn: 8.15.0
|
| 930 |
+
aria-query: 5.3.2
|
| 931 |
+
axobject-query: 4.1.0
|
| 932 |
+
clsx: 2.1.1
|
| 933 |
+
esm-env: 1.2.2
|
| 934 |
+
esrap: 2.1.0
|
| 935 |
+
is-reference: 3.0.3
|
| 936 |
+
locate-character: 3.0.0
|
| 937 |
+
magic-string: 0.30.17
|
| 938 |
+
zimmerframe: 1.1.2
|
| 939 |
+
|
| 940 | |
| 941 |
+
dependencies:
|
| 942 |
+
fdir: 6.4.6([email protected])
|
| 943 |
+
picomatch: 4.0.3
|
| 944 |
+
|
| 945 |
+
[email protected]: {}
|
| 946 |
+
|
| 947 |
+
[email protected]: {}
|
| 948 |
+
|
| 949 | |
| 950 |
+
dependencies:
|
| 951 |
+
esbuild: 0.25.8
|
| 952 |
+
fdir: 6.4.6([email protected])
|
| 953 |
+
picomatch: 4.0.3
|
| 954 |
+
postcss: 8.5.6
|
| 955 |
+
rollup: 4.46.2
|
| 956 |
+
tinyglobby: 0.2.14
|
| 957 |
+
optionalDependencies:
|
| 958 |
+
fsevents: 2.3.3
|
| 959 |
+
|
| 960 | |
| 961 |
+
optionalDependencies:
|
| 962 |
+
vite: 7.0.6
|
| 963 |
+
|
| 964 |
+
[email protected]: {}
|
public/vite.svg
DELETED
src/App.svelte
DELETED
|
@@ -1,47 +0,0 @@
|
|
| 1 |
-
<script lang="ts">
|
| 2 |
-
import svelteLogo from './assets/svelte.svg'
|
| 3 |
-
import viteLogo from '/vite.svg'
|
| 4 |
-
import Counter from './lib/Counter.svelte'
|
| 5 |
-
</script>
|
| 6 |
-
|
| 7 |
-
<main>
|
| 8 |
-
<div>
|
| 9 |
-
<a href="https://vite.dev" target="_blank" rel="noreferrer">
|
| 10 |
-
<img src={viteLogo} class="logo" alt="Vite Logo" />
|
| 11 |
-
</a>
|
| 12 |
-
<a href="https://svelte.dev" target="_blank" rel="noreferrer">
|
| 13 |
-
<img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
|
| 14 |
-
</a>
|
| 15 |
-
</div>
|
| 16 |
-
<h1>Vite + Svelte</h1>
|
| 17 |
-
|
| 18 |
-
<div class="card">
|
| 19 |
-
<Counter />
|
| 20 |
-
</div>
|
| 21 |
-
|
| 22 |
-
<p>
|
| 23 |
-
Check out <a href="https://github.com/sveltejs/kit#readme" target="_blank" rel="noreferrer">SvelteKit</a>, the official Svelte app framework powered by Vite!
|
| 24 |
-
</p>
|
| 25 |
-
|
| 26 |
-
<p class="read-the-docs">
|
| 27 |
-
Click on the Vite and Svelte logos to learn more
|
| 28 |
-
</p>
|
| 29 |
-
</main>
|
| 30 |
-
|
| 31 |
-
<style>
|
| 32 |
-
.logo {
|
| 33 |
-
height: 6em;
|
| 34 |
-
padding: 1.5em;
|
| 35 |
-
will-change: filter;
|
| 36 |
-
transition: filter 300ms;
|
| 37 |
-
}
|
| 38 |
-
.logo:hover {
|
| 39 |
-
filter: drop-shadow(0 0 2em #646cffaa);
|
| 40 |
-
}
|
| 41 |
-
.logo.svelte:hover {
|
| 42 |
-
filter: drop-shadow(0 0 2em #ff3e00aa);
|
| 43 |
-
}
|
| 44 |
-
.read-the-docs {
|
| 45 |
-
color: #888;
|
| 46 |
-
}
|
| 47 |
-
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/app.css
DELETED
|
@@ -1,79 +0,0 @@
|
|
| 1 |
-
:root {
|
| 2 |
-
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
| 3 |
-
line-height: 1.5;
|
| 4 |
-
font-weight: 400;
|
| 5 |
-
|
| 6 |
-
color-scheme: light dark;
|
| 7 |
-
color: rgba(255, 255, 255, 0.87);
|
| 8 |
-
background-color: #242424;
|
| 9 |
-
|
| 10 |
-
font-synthesis: none;
|
| 11 |
-
text-rendering: optimizeLegibility;
|
| 12 |
-
-webkit-font-smoothing: antialiased;
|
| 13 |
-
-moz-osx-font-smoothing: grayscale;
|
| 14 |
-
}
|
| 15 |
-
|
| 16 |
-
a {
|
| 17 |
-
font-weight: 500;
|
| 18 |
-
color: #646cff;
|
| 19 |
-
text-decoration: inherit;
|
| 20 |
-
}
|
| 21 |
-
a:hover {
|
| 22 |
-
color: #535bf2;
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
body {
|
| 26 |
-
margin: 0;
|
| 27 |
-
display: flex;
|
| 28 |
-
place-items: center;
|
| 29 |
-
min-width: 320px;
|
| 30 |
-
min-height: 100vh;
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
h1 {
|
| 34 |
-
font-size: 3.2em;
|
| 35 |
-
line-height: 1.1;
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
.card {
|
| 39 |
-
padding: 2em;
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
#app {
|
| 43 |
-
max-width: 1280px;
|
| 44 |
-
margin: 0 auto;
|
| 45 |
-
padding: 2rem;
|
| 46 |
-
text-align: center;
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
button {
|
| 50 |
-
border-radius: 8px;
|
| 51 |
-
border: 1px solid transparent;
|
| 52 |
-
padding: 0.6em 1.2em;
|
| 53 |
-
font-size: 1em;
|
| 54 |
-
font-weight: 500;
|
| 55 |
-
font-family: inherit;
|
| 56 |
-
background-color: #1a1a1a;
|
| 57 |
-
cursor: pointer;
|
| 58 |
-
transition: border-color 0.25s;
|
| 59 |
-
}
|
| 60 |
-
button:hover {
|
| 61 |
-
border-color: #646cff;
|
| 62 |
-
}
|
| 63 |
-
button:focus,
|
| 64 |
-
button:focus-visible {
|
| 65 |
-
outline: 4px auto -webkit-focus-ring-color;
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
@media (prefers-color-scheme: light) {
|
| 69 |
-
:root {
|
| 70 |
-
color: #213547;
|
| 71 |
-
background-color: #ffffff;
|
| 72 |
-
}
|
| 73 |
-
a:hover {
|
| 74 |
-
color: #747bff;
|
| 75 |
-
}
|
| 76 |
-
button {
|
| 77 |
-
background-color: #f9f9f9;
|
| 78 |
-
}
|
| 79 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/app.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// See https://svelte.dev/docs/kit/types#app.d.ts
|
| 2 |
+
// for information about these interfaces
|
| 3 |
+
declare global {
|
| 4 |
+
namespace App {
|
| 5 |
+
// interface Error {}
|
| 6 |
+
// interface Locals {}
|
| 7 |
+
// interface PageData {}
|
| 8 |
+
// interface PageState {}
|
| 9 |
+
// interface Platform {}
|
| 10 |
+
}
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export {};
|
src/app.html
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
|
| 4 |
+
<head>
|
| 5 |
+
<meta charset="utf-8" />
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
+
<title>XORB & Shard File Viewer</title>
|
| 8 |
+
<meta name="description" content="Parse and view metadata from XORB and Shard object files" />
|
| 9 |
+
%sveltekit.head%
|
| 10 |
+
</head>
|
| 11 |
+
|
| 12 |
+
<body data-sveltekit-preload-data="hover">
|
| 13 |
+
<div style="display: contents">%sveltekit.body%</div>
|
| 14 |
+
</body>
|
| 15 |
+
|
| 16 |
+
</html>
|
src/assets/svelte.svg
DELETED
src/lib/Counter.svelte
DELETED
|
@@ -1,10 +0,0 @@
|
|
| 1 |
-
<script lang="ts">
|
| 2 |
-
let count: number = $state(0)
|
| 3 |
-
const increment = () => {
|
| 4 |
-
count += 1
|
| 5 |
-
}
|
| 6 |
-
</script>
|
| 7 |
-
|
| 8 |
-
<button onclick={increment}>
|
| 9 |
-
count is {count}
|
| 10 |
-
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/assets/favicon.svg
ADDED
|
|
src/lib/components/ErrorDisplay.svelte
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script lang="ts">
|
| 2 |
+
export let error: string;
|
| 3 |
+
export let filename: string = "";
|
| 4 |
+
</script>
|
| 5 |
+
|
| 6 |
+
<div class="error-container">
|
| 7 |
+
<div class="error-content">
|
| 8 |
+
<div class="error-icon">⚠️</div>
|
| 9 |
+
<h3>Error Parsing File</h3>
|
| 10 |
+
{#if filename}
|
| 11 |
+
<p class="filename">File: {filename}</p>
|
| 12 |
+
{/if}
|
| 13 |
+
<div class="error-message">
|
| 14 |
+
{error}
|
| 15 |
+
</div>
|
| 16 |
+
<div class="suggestions">
|
| 17 |
+
<h4>Suggestions:</h4>
|
| 18 |
+
<ul>
|
| 19 |
+
<li>Verify that the file is a valid XORB or Shard file</li>
|
| 20 |
+
<li>Check that the file is not corrupted</li>
|
| 21 |
+
<li>Ensure the file format matches the expected binary structure</li>
|
| 22 |
+
</ul>
|
| 23 |
+
</div>
|
| 24 |
+
</div>
|
| 25 |
+
</div>
|
| 26 |
+
|
| 27 |
+
<style>
|
| 28 |
+
.error-container {
|
| 29 |
+
max-width: 600px;
|
| 30 |
+
margin: 20px auto;
|
| 31 |
+
padding: 20px;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
.error-content {
|
| 35 |
+
background: #fee;
|
| 36 |
+
border: 1px solid #fcc;
|
| 37 |
+
border-radius: 8px;
|
| 38 |
+
padding: 30px;
|
| 39 |
+
text-align: center;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
.error-icon {
|
| 43 |
+
font-size: 48px;
|
| 44 |
+
margin-bottom: 16px;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
.error-content h3 {
|
| 48 |
+
margin: 0 0 16px 0;
|
| 49 |
+
color: #d32f2f;
|
| 50 |
+
font-size: 20px;
|
| 51 |
+
font-weight: 600;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.filename {
|
| 55 |
+
font-family: "Monaco", "Consolas", monospace;
|
| 56 |
+
background: #fff;
|
| 57 |
+
padding: 8px 12px;
|
| 58 |
+
border-radius: 4px;
|
| 59 |
+
margin: 0 0 20px 0;
|
| 60 |
+
color: #666;
|
| 61 |
+
border: 1px solid #eee;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.error-message {
|
| 65 |
+
background: #fff;
|
| 66 |
+
border: 1px solid #fcc;
|
| 67 |
+
border-radius: 4px;
|
| 68 |
+
padding: 16px;
|
| 69 |
+
margin: 20px 0;
|
| 70 |
+
font-family: "Monaco", "Consolas", monospace;
|
| 71 |
+
font-size: 14px;
|
| 72 |
+
color: #d32f2f;
|
| 73 |
+
text-align: left;
|
| 74 |
+
white-space: pre-wrap;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.suggestions {
|
| 78 |
+
text-align: left;
|
| 79 |
+
margin-top: 20px;
|
| 80 |
+
background: #fff9c4;
|
| 81 |
+
border: 1px solid #f7e97d;
|
| 82 |
+
border-radius: 4px;
|
| 83 |
+
padding: 16px;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.suggestions h4 {
|
| 87 |
+
margin: 0 0 12px 0;
|
| 88 |
+
color: #8d6e00;
|
| 89 |
+
font-size: 16px;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
.suggestions ul {
|
| 93 |
+
margin: 0;
|
| 94 |
+
padding-left: 20px;
|
| 95 |
+
color: #8d6e00;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
.suggestions li {
|
| 99 |
+
margin-bottom: 8px;
|
| 100 |
+
}
|
| 101 |
+
</style>
|
src/lib/components/FileUpload.svelte
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script lang="ts">
|
| 2 |
+
import { createEventDispatcher } from "svelte";
|
| 3 |
+
|
| 4 |
+
const dispatch = createEventDispatcher<{
|
| 5 |
+
fileSelected: { file: File; type: "xorb" | "shard" };
|
| 6 |
+
}>();
|
| 7 |
+
|
| 8 |
+
let xorbDragActive = false;
|
| 9 |
+
let shardDragActive = false;
|
| 10 |
+
let xorbFileInput: HTMLInputElement;
|
| 11 |
+
let shardFileInput: HTMLInputElement;
|
| 12 |
+
|
| 13 |
+
function handleDragOver(event: DragEvent, type: "xorb" | "shard") {
|
| 14 |
+
event.preventDefault();
|
| 15 |
+
if (type === "xorb") {
|
| 16 |
+
xorbDragActive = true;
|
| 17 |
+
} else {
|
| 18 |
+
shardDragActive = true;
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
function handleDragLeave(type: "xorb" | "shard") {
|
| 23 |
+
if (type === "xorb") {
|
| 24 |
+
xorbDragActive = false;
|
| 25 |
+
} else {
|
| 26 |
+
shardDragActive = false;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
function handleDrop(event: DragEvent, type: "xorb" | "shard") {
|
| 31 |
+
event.preventDefault();
|
| 32 |
+
if (type === "xorb") {
|
| 33 |
+
xorbDragActive = false;
|
| 34 |
+
} else {
|
| 35 |
+
shardDragActive = false;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
const files = event.dataTransfer?.files;
|
| 39 |
+
if (files && files.length > 0) {
|
| 40 |
+
handleFile(files[0], type);
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
function handleFileInput(event: Event, type: "xorb" | "shard") {
|
| 45 |
+
const input = event.target as HTMLInputElement;
|
| 46 |
+
if (input.files && input.files.length > 0) {
|
| 47 |
+
handleFile(input.files[0], type);
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
function handleFile(file: File, type: "xorb" | "shard") {
|
| 52 |
+
dispatch("fileSelected", { file, type });
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
function openFileDialog(type: "xorb" | "shard") {
|
| 56 |
+
if (type === "xorb") {
|
| 57 |
+
xorbFileInput.click();
|
| 58 |
+
} else {
|
| 59 |
+
shardFileInput.click();
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
</script>
|
| 63 |
+
|
| 64 |
+
<div class="upload-container">
|
| 65 |
+
<div class="upload-areas">
|
| 66 |
+
<!-- XORB Upload Area -->
|
| 67 |
+
<div class="upload-section">
|
| 68 |
+
<h3>📦 Upload XORB File</h3>
|
| 69 |
+
<div
|
| 70 |
+
class="upload-area xorb-area"
|
| 71 |
+
class:drag-active={xorbDragActive}
|
| 72 |
+
on:dragover={(e) => handleDragOver(e, "xorb")}
|
| 73 |
+
on:dragleave={() => handleDragLeave("xorb")}
|
| 74 |
+
on:drop={(e) => handleDrop(e, "xorb")}
|
| 75 |
+
on:click={() => openFileDialog("xorb")}
|
| 76 |
+
on:keydown={(e) => e.key === "Enter" && openFileDialog("xorb")}
|
| 77 |
+
role="button"
|
| 78 |
+
tabindex="0"
|
| 79 |
+
>
|
| 80 |
+
<div class="upload-content">
|
| 81 |
+
<div class="upload-icon">📦</div>
|
| 82 |
+
<h4>Drop XORB file here</h4>
|
| 83 |
+
<p>or click to browse</p>
|
| 84 |
+
<span class="format-tag xorb-tag">XORB</span>
|
| 85 |
+
</div>
|
| 86 |
+
</div>
|
| 87 |
+
</div>
|
| 88 |
+
|
| 89 |
+
<!-- Shard Upload Area -->
|
| 90 |
+
<div class="upload-section">
|
| 91 |
+
<h3>🗂️ Upload Shard File</h3>
|
| 92 |
+
<div
|
| 93 |
+
class="upload-area shard-area"
|
| 94 |
+
class:drag-active={shardDragActive}
|
| 95 |
+
on:dragover={(e) => handleDragOver(e, "shard")}
|
| 96 |
+
on:dragleave={() => handleDragLeave("shard")}
|
| 97 |
+
on:drop={(e) => handleDrop(e, "shard")}
|
| 98 |
+
on:click={() => openFileDialog("shard")}
|
| 99 |
+
on:keydown={(e) => e.key === "Enter" && openFileDialog("shard")}
|
| 100 |
+
role="button"
|
| 101 |
+
tabindex="0"
|
| 102 |
+
>
|
| 103 |
+
<div class="upload-content">
|
| 104 |
+
<div class="upload-icon">🗂️</div>
|
| 105 |
+
<h4>Drop Shard file here</h4>
|
| 106 |
+
<p>or click to browse</p>
|
| 107 |
+
<span class="format-tag shard-tag">SHARD</span>
|
| 108 |
+
</div>
|
| 109 |
+
</div>
|
| 110 |
+
</div>
|
| 111 |
+
</div>
|
| 112 |
+
|
| 113 |
+
<input
|
| 114 |
+
bind:this={xorbFileInput}
|
| 115 |
+
type="file"
|
| 116 |
+
on:change={(e) => handleFileInput(e, "xorb")}
|
| 117 |
+
style="display: none;"
|
| 118 |
+
/>
|
| 119 |
+
|
| 120 |
+
<input
|
| 121 |
+
bind:this={shardFileInput}
|
| 122 |
+
type="file"
|
| 123 |
+
on:change={(e) => handleFileInput(e, "shard")}
|
| 124 |
+
style="display: none;"
|
| 125 |
+
/>
|
| 126 |
+
</div>
|
| 127 |
+
|
| 128 |
+
<style>
|
| 129 |
+
.upload-container {
|
| 130 |
+
width: 100%;
|
| 131 |
+
max-width: 800px;
|
| 132 |
+
margin: 0 auto;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
.upload-areas {
|
| 136 |
+
display: grid;
|
| 137 |
+
grid-template-columns: 1fr 1fr;
|
| 138 |
+
gap: 30px;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
.upload-section {
|
| 142 |
+
text-align: center;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.upload-section h3 {
|
| 146 |
+
margin: 0 0 20px 0;
|
| 147 |
+
color: #2c3e50;
|
| 148 |
+
font-size: 18px;
|
| 149 |
+
font-weight: 600;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
.upload-area {
|
| 153 |
+
border: 2px dashed #ccc;
|
| 154 |
+
border-radius: 8px;
|
| 155 |
+
padding: 30px 20px;
|
| 156 |
+
text-align: center;
|
| 157 |
+
cursor: pointer;
|
| 158 |
+
transition: all 0.3s ease;
|
| 159 |
+
background: #fafafa;
|
| 160 |
+
min-height: 200px;
|
| 161 |
+
display: flex;
|
| 162 |
+
align-items: center;
|
| 163 |
+
justify-content: center;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
.xorb-area:hover {
|
| 167 |
+
border-color: #28a745;
|
| 168 |
+
background: #f0fff4;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.xorb-area.drag-active {
|
| 172 |
+
border-color: #28a745;
|
| 173 |
+
background: #e8f5e8;
|
| 174 |
+
transform: scale(1.02);
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
.shard-area:hover {
|
| 178 |
+
border-color: #007bff;
|
| 179 |
+
background: #f0f8ff;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.shard-area.drag-active {
|
| 183 |
+
border-color: #007bff;
|
| 184 |
+
background: #e3f2fd;
|
| 185 |
+
transform: scale(1.02);
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
.upload-content {
|
| 189 |
+
pointer-events: none;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
.upload-icon {
|
| 193 |
+
font-size: 36px;
|
| 194 |
+
margin-bottom: 12px;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
.upload-area h4 {
|
| 198 |
+
margin: 0 0 8px 0;
|
| 199 |
+
color: #333;
|
| 200 |
+
font-weight: 600;
|
| 201 |
+
font-size: 16px;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
.upload-area p {
|
| 205 |
+
margin: 0 0 16px 0;
|
| 206 |
+
color: #666;
|
| 207 |
+
font-size: 14px;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
.format-tag {
|
| 211 |
+
color: white;
|
| 212 |
+
padding: 4px 12px;
|
| 213 |
+
border-radius: 16px;
|
| 214 |
+
font-size: 12px;
|
| 215 |
+
font-weight: 600;
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
.xorb-tag {
|
| 219 |
+
background: #28a745;
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
.shard-tag {
|
| 223 |
+
background: #007bff;
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
@media (max-width: 768px) {
|
| 227 |
+
.upload-areas {
|
| 228 |
+
grid-template-columns: 1fr;
|
| 229 |
+
gap: 20px;
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
.upload-area {
|
| 233 |
+
padding: 20px 15px;
|
| 234 |
+
min-height: 150px;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
.upload-icon {
|
| 238 |
+
font-size: 28px;
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
</style>
|
src/lib/components/ShardViewer.svelte
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script lang="ts">
|
| 2 |
+
import type { ShardData } from "../types.js";
|
| 3 |
+
import { formatBytes, formatHash, formatTimestamp } from "../parsers.js";
|
| 4 |
+
|
| 5 |
+
export let data: ShardData;
|
| 6 |
+
export let filename: string;
|
| 7 |
+
export let fileSize: number;
|
| 8 |
+
|
| 9 |
+
$: header = data.header;
|
| 10 |
+
$: footer = data.footer;
|
| 11 |
+
$: totalFiles = data.file_info.length;
|
| 12 |
+
$: totalXorbs = data.cas_info.length;
|
| 13 |
+
$: totalChunks = data.cas_info.reduce(
|
| 14 |
+
(sum, cas) => sum + cas.header.num_entries,
|
| 15 |
+
0
|
| 16 |
+
);
|
| 17 |
+
|
| 18 |
+
// Check verification and metadata status across all files
|
| 19 |
+
$: {
|
| 20 |
+
const filesWithVerification = data.file_info.filter(
|
| 21 |
+
(fileInfo) => fileInfo.header.file_flags & 0x80000000
|
| 22 |
+
).length;
|
| 23 |
+
const filesWithMetadata = data.file_info.filter(
|
| 24 |
+
(fileInfo) => fileInfo.header.file_flags & 0x40000000
|
| 25 |
+
).length;
|
| 26 |
+
|
| 27 |
+
verificationStatus =
|
| 28 |
+
filesWithVerification === totalFiles
|
| 29 |
+
? "✅"
|
| 30 |
+
: filesWithVerification === 0
|
| 31 |
+
? "❌"
|
| 32 |
+
: "❓";
|
| 33 |
+
|
| 34 |
+
metadataStatus =
|
| 35 |
+
filesWithMetadata === totalFiles
|
| 36 |
+
? "✅"
|
| 37 |
+
: filesWithMetadata === 0
|
| 38 |
+
? "❌"
|
| 39 |
+
: "❓";
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
let verificationStatus = "";
|
| 43 |
+
let metadataStatus = "";
|
| 44 |
+
$: totalStoredBytes = data.cas_info.reduce(
|
| 45 |
+
(sum, cas) => sum + cas.header.num_bytes_in_cas,
|
| 46 |
+
0
|
| 47 |
+
);
|
| 48 |
+
|
| 49 |
+
// Track which files are expanded
|
| 50 |
+
let expandedFiles = new Set<number>();
|
| 51 |
+
|
| 52 |
+
function toggleFileExpansion(fileIndex: number) {
|
| 53 |
+
if (expandedFiles.has(fileIndex)) {
|
| 54 |
+
expandedFiles.delete(fileIndex);
|
| 55 |
+
} else {
|
| 56 |
+
expandedFiles.add(fileIndex);
|
| 57 |
+
}
|
| 58 |
+
expandedFiles = expandedFiles; // Trigger reactivity
|
| 59 |
+
}
|
| 60 |
+
</script>
|
| 61 |
+
|
| 62 |
+
<div class="shard-viewer">
|
| 63 |
+
<div class="header">
|
| 64 |
+
<h2>🗂️ Shard File Analysis</h2>
|
| 65 |
+
<div class="file-info">
|
| 66 |
+
<span class="filename">{filename}</span>
|
| 67 |
+
<span class="file-size">{formatBytes(fileSize)}</span>
|
| 68 |
+
</div>
|
| 69 |
+
</div>
|
| 70 |
+
|
| 71 |
+
<div class="metadata-grid">
|
| 72 |
+
<div class="metadata-section">
|
| 73 |
+
<h3>Header Information</h3>
|
| 74 |
+
<div class="metadata-item">
|
| 75 |
+
<span class="label">Version:</span>
|
| 76 |
+
<span class="value">{header.version}</span>
|
| 77 |
+
</div>
|
| 78 |
+
<div class="metadata-item">
|
| 79 |
+
<span class="label">Footer Size:</span>
|
| 80 |
+
<span class="value">{formatBytes(header.footer_size)}</span>
|
| 81 |
+
</div>
|
| 82 |
+
</div>
|
| 83 |
+
|
| 84 |
+
<div class="metadata-section">
|
| 85 |
+
<h3>Content Statistics</h3>
|
| 86 |
+
<div class="metadata-item">
|
| 87 |
+
<span class="label">Files:</span>
|
| 88 |
+
<span class="value">{totalFiles.toLocaleString()}</span>
|
| 89 |
+
</div>
|
| 90 |
+
<div class="metadata-item">
|
| 91 |
+
<span class="label">XORBs:</span>
|
| 92 |
+
<span class="value">{totalXorbs.toLocaleString()}</span>
|
| 93 |
+
</div>
|
| 94 |
+
<div class="metadata-item">
|
| 95 |
+
<span class="label">Total Chunks:</span>
|
| 96 |
+
<span class="value">{totalChunks.toLocaleString()}</span>
|
| 97 |
+
</div>
|
| 98 |
+
<div class="metadata-item">
|
| 99 |
+
<span class="label">Stored Bytes:</span>
|
| 100 |
+
<span class="value">{formatBytes(totalStoredBytes)}</span>
|
| 101 |
+
</div>
|
| 102 |
+
</div>
|
| 103 |
+
|
| 104 |
+
<div class="metadata-section">
|
| 105 |
+
<h3>Timestamps & Security</h3>
|
| 106 |
+
<div class="metadata-item">
|
| 107 |
+
<span class="label">Created:</span>
|
| 108 |
+
<span class="value"
|
| 109 |
+
>{formatTimestamp(footer.shard_creation_timestamp)}</span
|
| 110 |
+
>
|
| 111 |
+
</div>
|
| 112 |
+
<div class="metadata-item">
|
| 113 |
+
<span class="label">Key Expiry:</span>
|
| 114 |
+
<span class="value">{formatTimestamp(footer.shard_key_expiry)}</span>
|
| 115 |
+
</div>
|
| 116 |
+
<div class="metadata-item">
|
| 117 |
+
<span class="label">HMAC Key:</span>
|
| 118 |
+
<span class="value hash" title={formatHash(footer.chunk_hash_hmac_key)}>
|
| 119 |
+
{formatHash(footer.chunk_hash_hmac_key)}
|
| 120 |
+
</span>
|
| 121 |
+
</div>
|
| 122 |
+
</div>
|
| 123 |
+
</div>
|
| 124 |
+
|
| 125 |
+
{#if data.file_info.length > 0}
|
| 126 |
+
<div class="file-details">
|
| 127 |
+
<h3>
|
| 128 |
+
File Information ({data.file_info.length} files) - Verification: {verificationStatus}
|
| 129 |
+
Metadata: {metadataStatus}
|
| 130 |
+
</h3>
|
| 131 |
+
<div class="table-container">
|
| 132 |
+
<table class="data-table">
|
| 133 |
+
<thead>
|
| 134 |
+
<tr>
|
| 135 |
+
<th>File Hash</th>
|
| 136 |
+
<th>Entries</th>
|
| 137 |
+
<th>Total Length</th>
|
| 138 |
+
<th>SHA256</th>
|
| 139 |
+
</tr>
|
| 140 |
+
</thead>
|
| 141 |
+
<tbody>
|
| 142 |
+
{#each data.file_info as fileInfo, fileIndex}
|
| 143 |
+
<tr
|
| 144 |
+
class="file-row"
|
| 145 |
+
class:expanded={expandedFiles.has(fileIndex)}
|
| 146 |
+
on:click={() => toggleFileExpansion(fileIndex)}
|
| 147 |
+
role="button"
|
| 148 |
+
tabindex="0"
|
| 149 |
+
on:keydown={(e) =>
|
| 150 |
+
e.key === "Enter" && toggleFileExpansion(fileIndex)}
|
| 151 |
+
>
|
| 152 |
+
<td class="hash" title={formatHash(fileInfo.header.file_hash)}>
|
| 153 |
+
<span class="expand-icon">
|
| 154 |
+
{expandedFiles.has(fileIndex) ? "▼" : "▶"}
|
| 155 |
+
</span>
|
| 156 |
+
{formatHash(fileInfo.header.file_hash)}
|
| 157 |
+
</td>
|
| 158 |
+
<td>{fileInfo.header.num_entries}</td>
|
| 159 |
+
<td>
|
| 160 |
+
{formatBytes(
|
| 161 |
+
fileInfo.entries.reduce(
|
| 162 |
+
(sum, entry) => sum + entry.unpacked_segment_bytes,
|
| 163 |
+
0
|
| 164 |
+
)
|
| 165 |
+
)}
|
| 166 |
+
</td>
|
| 167 |
+
<td>
|
| 168 |
+
{#if fileInfo.metadata_ext}
|
| 169 |
+
<span
|
| 170 |
+
class="hash"
|
| 171 |
+
title={formatHash(fileInfo.metadata_ext.sha256)}
|
| 172 |
+
>
|
| 173 |
+
{formatHash(fileInfo.metadata_ext.sha256)}
|
| 174 |
+
</span>
|
| 175 |
+
{:else}
|
| 176 |
+
<span class="no-data">—</span>
|
| 177 |
+
{/if}
|
| 178 |
+
</td>
|
| 179 |
+
</tr>
|
| 180 |
+
{#if expandedFiles.has(fileIndex)}
|
| 181 |
+
<tr class="file-details-row">
|
| 182 |
+
<td colspan="4">
|
| 183 |
+
<div class="file-entries-container">
|
| 184 |
+
<div class="entries-table-container">
|
| 185 |
+
<h4>Data Entries for File</h4>
|
| 186 |
+
<table class="entries-table">
|
| 187 |
+
<thead>
|
| 188 |
+
<tr>
|
| 189 |
+
<th>Entry #</th>
|
| 190 |
+
<th>CAS Hash</th>
|
| 191 |
+
<th>Chunk Range</th>
|
| 192 |
+
<th>Unpacked Size</th>
|
| 193 |
+
</tr>
|
| 194 |
+
</thead>
|
| 195 |
+
<tbody>
|
| 196 |
+
{#each fileInfo.entries as entry, entryIndex}
|
| 197 |
+
<tr>
|
| 198 |
+
<td>{entryIndex + 1}</td>
|
| 199 |
+
<td
|
| 200 |
+
class="hash"
|
| 201 |
+
title={formatHash(entry.cas_hash)}
|
| 202 |
+
>
|
| 203 |
+
{formatHash(entry.cas_hash)}
|
| 204 |
+
</td>
|
| 205 |
+
<td
|
| 206 |
+
>{entry.chunk_index_start} - {entry.chunk_index_end}</td
|
| 207 |
+
>
|
| 208 |
+
<td
|
| 209 |
+
>{formatBytes(
|
| 210 |
+
entry.unpacked_segment_bytes
|
| 211 |
+
)}</td
|
| 212 |
+
>
|
| 213 |
+
</tr>
|
| 214 |
+
{/each}
|
| 215 |
+
</tbody>
|
| 216 |
+
</table>
|
| 217 |
+
</div>
|
| 218 |
+
</div>
|
| 219 |
+
</td>
|
| 220 |
+
</tr>
|
| 221 |
+
{/if}
|
| 222 |
+
{/each}
|
| 223 |
+
</tbody>
|
| 224 |
+
</table>
|
| 225 |
+
</div>
|
| 226 |
+
</div>
|
| 227 |
+
{/if}
|
| 228 |
+
|
| 229 |
+
{#if data.cas_info.length > 0}
|
| 230 |
+
<div class="cas-details">
|
| 231 |
+
<h3>CAS Information ({data.cas_info.length} XORBs)</h3>
|
| 232 |
+
<div class="table-container">
|
| 233 |
+
<table class="data-table">
|
| 234 |
+
<thead>
|
| 235 |
+
<tr>
|
| 236 |
+
<th>CAS Hash</th>
|
| 237 |
+
<th>Chunks</th>
|
| 238 |
+
<th>Bytes in CAS</th>
|
| 239 |
+
<th>Bytes on Disk</th>
|
| 240 |
+
<th>Compression</th>
|
| 241 |
+
</tr>
|
| 242 |
+
</thead>
|
| 243 |
+
<tbody>
|
| 244 |
+
{#each data.cas_info as casInfo}
|
| 245 |
+
<tr>
|
| 246 |
+
<td class="hash" title={formatHash(casInfo.header.cas_hash)}>
|
| 247 |
+
{formatHash(casInfo.header.cas_hash)}
|
| 248 |
+
</td>
|
| 249 |
+
<td>{casInfo.header.num_entries}</td>
|
| 250 |
+
<td>{formatBytes(casInfo.header.num_bytes_in_cas)}</td>
|
| 251 |
+
<td>{formatBytes(casInfo.header.num_bytes_on_disk)}</td>
|
| 252 |
+
<td>
|
| 253 |
+
{casInfo.header.num_bytes_in_cas > 0
|
| 254 |
+
? (
|
| 255 |
+
(casInfo.header.num_bytes_on_disk /
|
| 256 |
+
casInfo.header.num_bytes_in_cas) *
|
| 257 |
+
100
|
| 258 |
+
).toFixed(1) + "%"
|
| 259 |
+
: "N/A"}
|
| 260 |
+
</td>
|
| 261 |
+
</tr>
|
| 262 |
+
{/each}
|
| 263 |
+
</tbody>
|
| 264 |
+
</table>
|
| 265 |
+
</div>
|
| 266 |
+
</div>
|
| 267 |
+
{/if}
|
| 268 |
+
</div>
|
| 269 |
+
|
| 270 |
+
<style>
|
| 271 |
+
.shard-viewer {
|
| 272 |
+
max-width: 1200px;
|
| 273 |
+
margin: 0 auto;
|
| 274 |
+
padding: 20px;
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
.header {
|
| 278 |
+
display: flex;
|
| 279 |
+
justify-content: space-between;
|
| 280 |
+
align-items: center;
|
| 281 |
+
margin-bottom: 30px;
|
| 282 |
+
padding-bottom: 20px;
|
| 283 |
+
border-bottom: 2px solid #eee;
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
.header h2 {
|
| 287 |
+
margin: 0;
|
| 288 |
+
color: #333;
|
| 289 |
+
font-size: 24px;
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
.file-info {
|
| 293 |
+
display: flex;
|
| 294 |
+
flex-direction: column;
|
| 295 |
+
align-items: flex-end;
|
| 296 |
+
gap: 4px;
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
.filename {
|
| 300 |
+
font-weight: 600;
|
| 301 |
+
color: #555;
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
.file-size {
|
| 305 |
+
font-size: 14px;
|
| 306 |
+
color: #888;
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
.metadata-grid {
|
| 310 |
+
display: grid;
|
| 311 |
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
| 312 |
+
gap: 20px;
|
| 313 |
+
margin-bottom: 30px;
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
.metadata-section {
|
| 317 |
+
background: #f8f9fa;
|
| 318 |
+
padding: 20px;
|
| 319 |
+
border-radius: 8px;
|
| 320 |
+
border: 1px solid #e9ecef;
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
.metadata-section h3 {
|
| 324 |
+
margin: 0 0 15px 0;
|
| 325 |
+
color: #495057;
|
| 326 |
+
font-size: 18px;
|
| 327 |
+
font-weight: 600;
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
.metadata-item {
|
| 331 |
+
display: flex;
|
| 332 |
+
justify-content: space-between;
|
| 333 |
+
align-items: center;
|
| 334 |
+
margin-bottom: 12px;
|
| 335 |
+
padding: 8px 0;
|
| 336 |
+
border-bottom: 1px solid #e9ecef;
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
.metadata-item:last-child {
|
| 340 |
+
border-bottom: none;
|
| 341 |
+
margin-bottom: 0;
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
.metadata-item .label {
|
| 345 |
+
font-weight: 500;
|
| 346 |
+
color: #6c757d;
|
| 347 |
+
margin-right: 10px;
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
.metadata-item .value {
|
| 351 |
+
font-family: "Monaco", "Consolas", monospace;
|
| 352 |
+
font-size: 14px;
|
| 353 |
+
color: #212529;
|
| 354 |
+
text-align: right;
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
.hash {
|
| 358 |
+
font-family: "Monaco", "Consolas", monospace;
|
| 359 |
+
background: #e9ecef;
|
| 360 |
+
padding: 2px 6px;
|
| 361 |
+
border-radius: 4px;
|
| 362 |
+
cursor: help;
|
| 363 |
+
font-size: 12px;
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
.file-details,
|
| 367 |
+
.cas-details {
|
| 368 |
+
margin-top: 30px;
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
.file-details h3,
|
| 372 |
+
.cas-details h3 {
|
| 373 |
+
margin: 0 0 20px 0;
|
| 374 |
+
color: #495057;
|
| 375 |
+
font-size: 18px;
|
| 376 |
+
font-weight: 600;
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
.table-container {
|
| 380 |
+
overflow-x: auto;
|
| 381 |
+
border-radius: 8px;
|
| 382 |
+
border: 1px solid #e9ecef;
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
.data-table {
|
| 386 |
+
width: 100%;
|
| 387 |
+
border-collapse: collapse;
|
| 388 |
+
background: white;
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
.data-table th,
|
| 392 |
+
.data-table td {
|
| 393 |
+
padding: 12px;
|
| 394 |
+
text-align: left;
|
| 395 |
+
border-bottom: 1px solid #e9ecef;
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
.data-table th {
|
| 399 |
+
background: #f8f9fa;
|
| 400 |
+
font-weight: 600;
|
| 401 |
+
color: #495057;
|
| 402 |
+
}
|
| 403 |
+
|
| 404 |
+
.data-table tr:hover {
|
| 405 |
+
background: #f8f9fa;
|
| 406 |
+
}
|
| 407 |
+
|
| 408 |
+
.no-data {
|
| 409 |
+
color: #999;
|
| 410 |
+
font-style: italic;
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
/* Expandable file rows */
|
| 414 |
+
.file-row {
|
| 415 |
+
cursor: pointer;
|
| 416 |
+
transition: background-color 0.2s ease;
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
.file-row:hover {
|
| 420 |
+
background-color: #f0f7ff !important;
|
| 421 |
+
}
|
| 422 |
+
|
| 423 |
+
.file-row.expanded {
|
| 424 |
+
background-color: #e3f2fd;
|
| 425 |
+
}
|
| 426 |
+
|
| 427 |
+
.expand-icon {
|
| 428 |
+
display: inline-block;
|
| 429 |
+
margin-right: 8px;
|
| 430 |
+
font-size: 12px;
|
| 431 |
+
width: 12px;
|
| 432 |
+
transition: transform 0.2s ease;
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
.file-details-row {
|
| 436 |
+
background-color: #f8f9fa;
|
| 437 |
+
}
|
| 438 |
+
|
| 439 |
+
.file-details-row td {
|
| 440 |
+
padding: 0;
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
.file-entries-container {
|
| 444 |
+
padding: 16px;
|
| 445 |
+
border-left: 3px solid #007bff;
|
| 446 |
+
margin-left: 12px;
|
| 447 |
+
max-height: 90vh;
|
| 448 |
+
overflow-y: auto;
|
| 449 |
+
overflow-x: hidden;
|
| 450 |
+
border-radius: 6px;
|
| 451 |
+
background-color: #f8f9fa;
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
/* Scrollbar styling for webkit browsers */
|
| 455 |
+
.file-entries-container::-webkit-scrollbar {
|
| 456 |
+
width: 6px;
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
.file-entries-container::-webkit-scrollbar-track {
|
| 460 |
+
background: #f1f1f1;
|
| 461 |
+
border-radius: 3px;
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
.file-entries-container::-webkit-scrollbar-thumb {
|
| 465 |
+
background: #c1c1c1;
|
| 466 |
+
border-radius: 3px;
|
| 467 |
+
}
|
| 468 |
+
|
| 469 |
+
.file-entries-container::-webkit-scrollbar-thumb:hover {
|
| 470 |
+
background: #a8a8a8;
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
+
.file-entries-container h4 {
|
| 474 |
+
margin: 0 0 12px 0;
|
| 475 |
+
color: #495057;
|
| 476 |
+
font-size: 14px;
|
| 477 |
+
font-weight: 600;
|
| 478 |
+
position: sticky;
|
| 479 |
+
top: 0;
|
| 480 |
+
background-color: #f8f9fa;
|
| 481 |
+
padding: 8px 0;
|
| 482 |
+
z-index: 1;
|
| 483 |
+
}
|
| 484 |
+
|
| 485 |
+
.entries-table-container {
|
| 486 |
+
overflow-x: auto;
|
| 487 |
+
border-radius: 6px;
|
| 488 |
+
border: 1px solid #dee2e6;
|
| 489 |
+
}
|
| 490 |
+
|
| 491 |
+
.entries-table {
|
| 492 |
+
width: 100%;
|
| 493 |
+
border-collapse: collapse;
|
| 494 |
+
background: white;
|
| 495 |
+
font-size: 13px;
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
.entries-table th,
|
| 499 |
+
.entries-table td {
|
| 500 |
+
padding: 8px 12px;
|
| 501 |
+
text-align: left;
|
| 502 |
+
border-bottom: 1px solid #dee2e6;
|
| 503 |
+
}
|
| 504 |
+
|
| 505 |
+
.entries-table th {
|
| 506 |
+
background: #f1f3f4;
|
| 507 |
+
font-weight: 600;
|
| 508 |
+
color: #495057;
|
| 509 |
+
font-size: 12px;
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
.entries-table tr:hover {
|
| 513 |
+
background: #f8f9fa;
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
.entries-table .hash {
|
| 517 |
+
font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
|
| 518 |
+
font-size: 11px;
|
| 519 |
+
color: #6c757d;
|
| 520 |
+
}
|
| 521 |
+
|
| 522 |
+
@media (max-width: 768px) {
|
| 523 |
+
.header {
|
| 524 |
+
flex-direction: column;
|
| 525 |
+
align-items: flex-start;
|
| 526 |
+
gap: 10px;
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
.metadata-grid {
|
| 530 |
+
grid-template-columns: 1fr;
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
+
.metadata-item {
|
| 534 |
+
flex-direction: column;
|
| 535 |
+
align-items: flex-start;
|
| 536 |
+
gap: 4px;
|
| 537 |
+
}
|
| 538 |
+
|
| 539 |
+
.metadata-item .value {
|
| 540 |
+
text-align: left;
|
| 541 |
+
}
|
| 542 |
+
}
|
| 543 |
+
</style>
|
src/lib/components/XorbViewer.svelte
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script lang="ts">
|
| 2 |
+
import type { Chunk } from "../types.js";
|
| 3 |
+
import { formatBytes } from "../parsers.js";
|
| 4 |
+
|
| 5 |
+
export let data: Chunk[];
|
| 6 |
+
export let filename: string;
|
| 7 |
+
export let fileSize: number;
|
| 8 |
+
|
| 9 |
+
$: totalChunks = data.length;
|
| 10 |
+
$: totalCompressedSize = data.reduce(
|
| 11 |
+
(sum, chunk) => sum + chunk.header.compressed_size,
|
| 12 |
+
0
|
| 13 |
+
);
|
| 14 |
+
$: totalUncompressedSize = data.reduce(
|
| 15 |
+
(sum, chunk) => sum + chunk.header.uncompressed_size,
|
| 16 |
+
0
|
| 17 |
+
);
|
| 18 |
+
$: averageChunkSize =
|
| 19 |
+
totalChunks > 0 ? totalUncompressedSize / totalChunks : 0;
|
| 20 |
+
$: compressionRatio =
|
| 21 |
+
totalUncompressedSize > 0
|
| 22 |
+
? (totalCompressedSize / totalUncompressedSize) * 100
|
| 23 |
+
: 0;
|
| 24 |
+
|
| 25 |
+
function getCompressionTypeName(type: number): string {
|
| 26 |
+
switch (type) {
|
| 27 |
+
case 0:
|
| 28 |
+
return "None";
|
| 29 |
+
case 1:
|
| 30 |
+
return "LZ4";
|
| 31 |
+
case 2:
|
| 32 |
+
return "Zstd";
|
| 33 |
+
case 3:
|
| 34 |
+
return "Gzip";
|
| 35 |
+
default:
|
| 36 |
+
return `Unknown (${type})`;
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
</script>
|
| 40 |
+
|
| 41 |
+
<div class="xorb-viewer">
|
| 42 |
+
<div class="header">
|
| 43 |
+
<h2>📦 XORB File Analysis</h2>
|
| 44 |
+
<div class="file-info">
|
| 45 |
+
<span class="filename">{filename}</span>
|
| 46 |
+
<span class="file-size">{formatBytes(fileSize)}</span>
|
| 47 |
+
</div>
|
| 48 |
+
</div>
|
| 49 |
+
|
| 50 |
+
<div class="metadata-grid">
|
| 51 |
+
<div class="metadata-section">
|
| 52 |
+
<h3>File Information</h3>
|
| 53 |
+
<div class="metadata-item">
|
| 54 |
+
<span class="label">File Size:</span>
|
| 55 |
+
<span class="value">{formatBytes(fileSize)}</span>
|
| 56 |
+
</div>
|
| 57 |
+
<div class="metadata-item">
|
| 58 |
+
<span class="label">Total Chunks:</span>
|
| 59 |
+
<span class="value">{totalChunks.toLocaleString()}</span>
|
| 60 |
+
</div>
|
| 61 |
+
</div>
|
| 62 |
+
|
| 63 |
+
<div class="metadata-section">
|
| 64 |
+
<h3>Compression Statistics</h3>
|
| 65 |
+
<div class="metadata-item">
|
| 66 |
+
<span class="label">Total Compressed Size:</span>
|
| 67 |
+
<span class="value">{formatBytes(totalCompressedSize)}</span>
|
| 68 |
+
</div>
|
| 69 |
+
<div class="metadata-item">
|
| 70 |
+
<span class="label">Total Uncompressed Size:</span>
|
| 71 |
+
<span class="value">{formatBytes(totalUncompressedSize)}</span>
|
| 72 |
+
</div>
|
| 73 |
+
<div class="metadata-item">
|
| 74 |
+
<span class="label">Overall Compression Ratio:</span>
|
| 75 |
+
<span class="value">{compressionRatio.toFixed(1)}%</span>
|
| 76 |
+
</div>
|
| 77 |
+
<div class="metadata-item">
|
| 78 |
+
<span class="label">Average Chunk Size:</span>
|
| 79 |
+
<span class="value">{formatBytes(averageChunkSize)}</span>
|
| 80 |
+
</div>
|
| 81 |
+
</div>
|
| 82 |
+
</div>
|
| 83 |
+
|
| 84 |
+
{#if data.length > 0}
|
| 85 |
+
<div class="chunk-details">
|
| 86 |
+
<h3>Chunk Headers ({data.length} chunks)</h3>
|
| 87 |
+
<div class="chunk-table-container">
|
| 88 |
+
<table class="chunk-table">
|
| 89 |
+
<thead>
|
| 90 |
+
<tr>
|
| 91 |
+
<th>Index</th>
|
| 92 |
+
<th>Version</th>
|
| 93 |
+
<th>Compression Type</th>
|
| 94 |
+
<th>Compressed Size</th>
|
| 95 |
+
<th>Uncompressed Size</th>
|
| 96 |
+
<th>Compression Ratio</th>
|
| 97 |
+
</tr>
|
| 98 |
+
</thead>
|
| 99 |
+
<tbody>
|
| 100 |
+
{#each data as chunk, i}
|
| 101 |
+
<tr>
|
| 102 |
+
<td>{i}</td>
|
| 103 |
+
<td>{chunk.header.version}</td>
|
| 104 |
+
<td>{getCompressionTypeName(chunk.header.compression_type)}</td>
|
| 105 |
+
<td>{formatBytes(chunk.header.compressed_size)}</td>
|
| 106 |
+
<td>{formatBytes(chunk.header.uncompressed_size)}</td>
|
| 107 |
+
<td>
|
| 108 |
+
{chunk.header.uncompressed_size > 0
|
| 109 |
+
? (
|
| 110 |
+
(chunk.header.compressed_size /
|
| 111 |
+
chunk.header.uncompressed_size) *
|
| 112 |
+
100
|
| 113 |
+
).toFixed(1) + "%"
|
| 114 |
+
: "N/A"}
|
| 115 |
+
</td>
|
| 116 |
+
</tr>
|
| 117 |
+
{/each}
|
| 118 |
+
</tbody>
|
| 119 |
+
</table>
|
| 120 |
+
</div>
|
| 121 |
+
</div>
|
| 122 |
+
{/if}
|
| 123 |
+
</div>
|
| 124 |
+
|
| 125 |
+
<style>
|
| 126 |
+
.xorb-viewer {
|
| 127 |
+
max-width: 1200px;
|
| 128 |
+
margin: 0 auto;
|
| 129 |
+
padding: 20px;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
.header {
|
| 133 |
+
display: flex;
|
| 134 |
+
justify-content: space-between;
|
| 135 |
+
align-items: center;
|
| 136 |
+
margin-bottom: 30px;
|
| 137 |
+
padding-bottom: 20px;
|
| 138 |
+
border-bottom: 2px solid #eee;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
.header h2 {
|
| 142 |
+
margin: 0;
|
| 143 |
+
color: #333;
|
| 144 |
+
font-size: 24px;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.file-info {
|
| 148 |
+
display: flex;
|
| 149 |
+
flex-direction: column;
|
| 150 |
+
align-items: flex-end;
|
| 151 |
+
gap: 4px;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
.filename {
|
| 155 |
+
font-weight: 600;
|
| 156 |
+
color: #555;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
.file-size {
|
| 160 |
+
font-size: 14px;
|
| 161 |
+
color: #888;
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
.metadata-grid {
|
| 165 |
+
display: grid;
|
| 166 |
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
| 167 |
+
gap: 20px;
|
| 168 |
+
margin-bottom: 30px;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.metadata-section {
|
| 172 |
+
background: #f8f9fa;
|
| 173 |
+
padding: 20px;
|
| 174 |
+
border-radius: 8px;
|
| 175 |
+
border: 1px solid #e9ecef;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
.metadata-section h3 {
|
| 179 |
+
margin: 0 0 15px 0;
|
| 180 |
+
color: #495057;
|
| 181 |
+
font-size: 18px;
|
| 182 |
+
font-weight: 600;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
.metadata-item {
|
| 186 |
+
display: flex;
|
| 187 |
+
justify-content: space-between;
|
| 188 |
+
align-items: center;
|
| 189 |
+
margin-bottom: 12px;
|
| 190 |
+
padding: 8px 0;
|
| 191 |
+
border-bottom: 1px solid #e9ecef;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
.metadata-item:last-child {
|
| 195 |
+
border-bottom: none;
|
| 196 |
+
margin-bottom: 0;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
.metadata-item .label {
|
| 200 |
+
font-weight: 500;
|
| 201 |
+
color: #6c757d;
|
| 202 |
+
margin-right: 10px;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
.metadata-item .value {
|
| 206 |
+
font-family: "Monaco", "Consolas", monospace;
|
| 207 |
+
font-size: 14px;
|
| 208 |
+
color: #212529;
|
| 209 |
+
text-align: right;
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
.chunk-details {
|
| 213 |
+
margin-top: 30px;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
.chunk-details h3 {
|
| 217 |
+
margin: 0 0 20px 0;
|
| 218 |
+
color: #495057;
|
| 219 |
+
font-size: 18px;
|
| 220 |
+
font-weight: 600;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.chunk-table-container {
|
| 224 |
+
overflow-x: auto;
|
| 225 |
+
border-radius: 8px;
|
| 226 |
+
border: 1px solid #e9ecef;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
.chunk-table {
|
| 230 |
+
width: 100%;
|
| 231 |
+
border-collapse: collapse;
|
| 232 |
+
background: white;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
.chunk-table th,
|
| 236 |
+
.chunk-table td {
|
| 237 |
+
padding: 12px;
|
| 238 |
+
text-align: left;
|
| 239 |
+
border-bottom: 1px solid #e9ecef;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
.chunk-table th {
|
| 243 |
+
background: #f8f9fa;
|
| 244 |
+
font-weight: 600;
|
| 245 |
+
color: #495057;
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
.chunk-table tr:hover {
|
| 249 |
+
background: #f8f9fa;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
@media (max-width: 768px) {
|
| 253 |
+
.header {
|
| 254 |
+
flex-direction: column;
|
| 255 |
+
align-items: flex-start;
|
| 256 |
+
gap: 10px;
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
.metadata-grid {
|
| 260 |
+
grid-template-columns: 1fr;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
.metadata-item {
|
| 264 |
+
flex-direction: column;
|
| 265 |
+
align-items: flex-start;
|
| 266 |
+
gap: 4px;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
.metadata-item .value {
|
| 270 |
+
text-align: left;
|
| 271 |
+
}
|
| 272 |
+
}
|
| 273 |
+
</style>
|
src/lib/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
// place files you want to import through the `$lib` alias in this folder.
|
src/lib/parsers.ts
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Binary parsers for xorb and shard files
|
| 2 |
+
|
| 3 |
+
import type {
|
| 4 |
+
ParsedFileMetadata,
|
| 5 |
+
Chunk,
|
| 6 |
+
ChunkHeader,
|
| 7 |
+
ShardData,
|
| 8 |
+
MerkleHash,
|
| 9 |
+
HMACKey,
|
| 10 |
+
MDBShardFileHeader,
|
| 11 |
+
MDBShardFileFooter,
|
| 12 |
+
FileDataSequenceHeader,
|
| 13 |
+
FileDataSequenceEntry,
|
| 14 |
+
FileVerificationEntry,
|
| 15 |
+
FileMetadataExt,
|
| 16 |
+
CASChunkSequenceHeader,
|
| 17 |
+
CASChunkSequenceEntry,
|
| 18 |
+
MDBFileInfo,
|
| 19 |
+
MDBCASInfo,
|
| 20 |
+
} from "./types.js";
|
| 21 |
+
import { MDB_SHARD_HEADER_TAG, XORB_IDENT } from "./types.js";
|
| 22 |
+
|
| 23 |
+
export class BinaryReader {
|
| 24 |
+
private data: Uint8Array;
|
| 25 |
+
private offset: number = 0;
|
| 26 |
+
|
| 27 |
+
constructor(data: Uint8Array) {
|
| 28 |
+
this.data = data;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
readUint8(): number {
|
| 32 |
+
if (this.offset >= this.data.length) {
|
| 33 |
+
console.trace();
|
| 34 |
+
throw new Error("Unexpected end of data");
|
| 35 |
+
}
|
| 36 |
+
return this.data[this.offset++];
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
readUint32LE(): number {
|
| 40 |
+
if (this.offset + 4 > this.data.length) {
|
| 41 |
+
console.trace();
|
| 42 |
+
throw new Error("Unexpected end of data");
|
| 43 |
+
}
|
| 44 |
+
const result = new DataView(this.data.buffer).getUint32(this.offset, true);
|
| 45 |
+
this.offset += 4;
|
| 46 |
+
return result;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
readUint64LE(): bigint {
|
| 50 |
+
if (this.offset + 8 > this.data.length) {
|
| 51 |
+
console.trace();
|
| 52 |
+
throw new Error("Unexpected end of data");
|
| 53 |
+
}
|
| 54 |
+
const result = new DataView(this.data.buffer).getBigUint64(
|
| 55 |
+
this.offset,
|
| 56 |
+
true
|
| 57 |
+
);
|
| 58 |
+
this.offset += 8;
|
| 59 |
+
return result;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
readBytes(length: number): Uint8Array {
|
| 63 |
+
if (this.offset + length > this.data.length) {
|
| 64 |
+
console.trace();
|
| 65 |
+
throw new Error("Unexpected end of data");
|
| 66 |
+
}
|
| 67 |
+
const result = this.data.slice(this.offset, this.offset + length);
|
| 68 |
+
this.offset += length;
|
| 69 |
+
return result;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
readHash(): MerkleHash {
|
| 73 |
+
return { data: this.readBytes(32) };
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
readHMACKey(): HMACKey {
|
| 77 |
+
return { data: this.readBytes(32) };
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
readString(length: number): string {
|
| 81 |
+
const bytes = this.readBytes(length);
|
| 82 |
+
return new TextDecoder().decode(bytes);
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
seek(position: number): void {
|
| 86 |
+
this.offset = position;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
seekFromEnd(offsetFromEnd: number): void {
|
| 90 |
+
this.offset = this.data.length - offsetFromEnd;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
get position(): number {
|
| 94 |
+
return this.offset;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
get remaining(): number {
|
| 98 |
+
return this.data.length - this.offset;
|
| 99 |
+
}
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
function arraysEqual(a: Uint8Array, b: Uint8Array): boolean {
|
| 103 |
+
if (a.length !== b.length) return false;
|
| 104 |
+
for (let i = 0; i < a.length; i++) {
|
| 105 |
+
if (a[i] !== b[i]) return false;
|
| 106 |
+
}
|
| 107 |
+
return true;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
function isBookendHash(hash: MerkleHash): boolean {
|
| 111 |
+
// Bookend hash is all 0xFF bytes
|
| 112 |
+
return hash.data.every((byte) => byte === 0xff);
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
function reorderHash(hash: MerkleHash): Array<number> {
|
| 116 |
+
const data = new Array(32);
|
| 117 |
+
let start = 0;
|
| 118 |
+
for (let i = 0; i < 32; i++) {
|
| 119 |
+
if (i % 8 === 0) {
|
| 120 |
+
start += 8;
|
| 121 |
+
}
|
| 122 |
+
data.push(hash.data[start - (i % 8) - 1]);
|
| 123 |
+
}
|
| 124 |
+
return data;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
function formatHash(hash: MerkleHash): string {
|
| 128 |
+
return reorderHash(hash)
|
| 129 |
+
.map((b) => b.toString(16).padStart(2, "0"))
|
| 130 |
+
.join("");
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
// File type detection removed - type is now specified by user selection
|
| 134 |
+
|
| 135 |
+
function parseXorbFile(data: Uint8Array): Chunk[] {
|
| 136 |
+
const reader = new BinaryReader(data);
|
| 137 |
+
|
| 138 |
+
const chunks: Chunk[] = [];
|
| 139 |
+
|
| 140 |
+
while (reader.remaining > 0) {
|
| 141 |
+
// Check if we have enough bytes for a header
|
| 142 |
+
if (reader.remaining < 8) {
|
| 143 |
+
console.error("Unexpected end of data parsing xorb file");
|
| 144 |
+
break;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
const header_bytes = reader.readBytes(8);
|
| 148 |
+
let is_xorb_ident = true;
|
| 149 |
+
// Urgh how do I compare two Uint8Arrays?
|
| 150 |
+
for (let i = 0; i < 7; i++) {
|
| 151 |
+
if (header_bytes[i] !== XORB_IDENT[i]) {
|
| 152 |
+
is_xorb_ident = false;
|
| 153 |
+
break;
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
if (is_xorb_ident) {
|
| 157 |
+
// reached optional xorb footer, skip rest
|
| 158 |
+
break;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
const header = new DataView(header_bytes.buffer);
|
| 162 |
+
|
| 163 |
+
const version = header.getUint8(0);
|
| 164 |
+
const compressed_size =
|
| 165 |
+
header.getUint8(1) |
|
| 166 |
+
(header.getUint8(2) << 8) |
|
| 167 |
+
(header.getUint8(3) << 16);
|
| 168 |
+
const compression_type = header.getUint8(4);
|
| 169 |
+
const uncompressed_size =
|
| 170 |
+
header.getUint8(5) |
|
| 171 |
+
(header.getUint8(6) << 8) |
|
| 172 |
+
(header.getUint8(7) << 16);
|
| 173 |
+
|
| 174 |
+
const chunkHeader: ChunkHeader = {
|
| 175 |
+
version,
|
| 176 |
+
compressed_size,
|
| 177 |
+
compression_type,
|
| 178 |
+
uncompressed_size,
|
| 179 |
+
};
|
| 180 |
+
|
| 181 |
+
const compressed_data = reader.readBytes(compressed_size);
|
| 182 |
+
|
| 183 |
+
chunks.push({ header: chunkHeader, compressed_data });
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
return chunks;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
function parseShardFile(data: Uint8Array): ShardData {
|
| 190 |
+
const reader = new BinaryReader(data);
|
| 191 |
+
|
| 192 |
+
// Parse header
|
| 193 |
+
const tag = reader.readBytes(32);
|
| 194 |
+
if (!arraysEqual(tag, MDB_SHARD_HEADER_TAG)) {
|
| 195 |
+
throw new Error("Invalid shard file header tag");
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
const header: MDBShardFileHeader = {
|
| 199 |
+
tag,
|
| 200 |
+
version: Number(reader.readUint64LE()),
|
| 201 |
+
footer_size: Number(reader.readUint64LE()),
|
| 202 |
+
};
|
| 203 |
+
|
| 204 |
+
if (header.version !== 2) {
|
| 205 |
+
throw new Error(`Unsupported shard header version: ${header.version}`);
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
// Parse footer (from end of file)
|
| 209 |
+
reader.seekFromEnd(header.footer_size);
|
| 210 |
+
const version = Number(reader.readUint64LE());
|
| 211 |
+
const file_info_offset = Number(reader.readUint64LE());
|
| 212 |
+
const cas_info_offset = Number(reader.readUint64LE());
|
| 213 |
+
|
| 214 |
+
// Skip first buffer (48 bytes)
|
| 215 |
+
reader.readBytes(48);
|
| 216 |
+
|
| 217 |
+
const chunk_hash_hmac_key = reader.readHMACKey();
|
| 218 |
+
const shard_creation_timestamp = Number(reader.readUint64LE());
|
| 219 |
+
const shard_key_expiry = Number(reader.readUint64LE());
|
| 220 |
+
|
| 221 |
+
// Skip second buffer (72 bytes)
|
| 222 |
+
reader.readBytes(72);
|
| 223 |
+
|
| 224 |
+
const footer_offset = Number(reader.readUint64LE());
|
| 225 |
+
|
| 226 |
+
const footer: MDBShardFileFooter = {
|
| 227 |
+
version,
|
| 228 |
+
file_info_offset,
|
| 229 |
+
cas_info_offset,
|
| 230 |
+
chunk_hash_hmac_key,
|
| 231 |
+
shard_creation_timestamp,
|
| 232 |
+
shard_key_expiry,
|
| 233 |
+
footer_offset,
|
| 234 |
+
};
|
| 235 |
+
|
| 236 |
+
if (footer.version !== 1) {
|
| 237 |
+
throw new Error(`Unsupported shard footer version: ${footer.version}`);
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
// Parse file info section
|
| 241 |
+
const file_info: MDBFileInfo[] = [];
|
| 242 |
+
reader.seek(footer.file_info_offset);
|
| 243 |
+
|
| 244 |
+
while (reader.position < footer.cas_info_offset) {
|
| 245 |
+
const pos = reader.position;
|
| 246 |
+
const file_hash = reader.readHash();
|
| 247 |
+
|
| 248 |
+
// Check for bookend
|
| 249 |
+
if (isBookendHash(file_hash)) {
|
| 250 |
+
reader.readBytes(16); // unused
|
| 251 |
+
break;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
const file_flags = reader.readUint32LE();
|
| 255 |
+
const num_entries = reader.readUint32LE();
|
| 256 |
+
const _unused = reader.readBytes(8);
|
| 257 |
+
|
| 258 |
+
const header: FileDataSequenceHeader = {
|
| 259 |
+
file_hash,
|
| 260 |
+
file_flags,
|
| 261 |
+
num_entries,
|
| 262 |
+
_unused,
|
| 263 |
+
};
|
| 264 |
+
|
| 265 |
+
// Read entries
|
| 266 |
+
const entries: FileDataSequenceEntry[] = [];
|
| 267 |
+
for (let i = 0; i < num_entries; i++) {
|
| 268 |
+
const cas_hash = reader.readHash();
|
| 269 |
+
const cas_flags = reader.readUint32LE();
|
| 270 |
+
const unpacked_segment_bytes = reader.readUint32LE();
|
| 271 |
+
const chunk_index_start = reader.readUint32LE();
|
| 272 |
+
const chunk_index_end = reader.readUint32LE();
|
| 273 |
+
entries.push({
|
| 274 |
+
cas_hash,
|
| 275 |
+
cas_flags,
|
| 276 |
+
unpacked_segment_bytes,
|
| 277 |
+
chunk_index_start,
|
| 278 |
+
chunk_index_end,
|
| 279 |
+
});
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
// Read verification entries if present
|
| 283 |
+
let verification_entries: FileVerificationEntry[] | undefined;
|
| 284 |
+
if (file_flags & 0x80000000) {
|
| 285 |
+
verification_entries = [];
|
| 286 |
+
for (let i = 0; i < num_entries; i++) {
|
| 287 |
+
verification_entries.push({
|
| 288 |
+
chunk_hash: reader.readHash(),
|
| 289 |
+
_unused: reader.readBytes(16),
|
| 290 |
+
});
|
| 291 |
+
}
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
// Read metadata extension if present
|
| 295 |
+
let metadata_ext: FileMetadataExt | undefined;
|
| 296 |
+
if (file_flags & 0x40000000) {
|
| 297 |
+
metadata_ext = {
|
| 298 |
+
sha256: reader.readHash(),
|
| 299 |
+
_unused: reader.readBytes(16),
|
| 300 |
+
};
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
file_info.push({
|
| 304 |
+
header,
|
| 305 |
+
entries,
|
| 306 |
+
verification_entries,
|
| 307 |
+
metadata_ext,
|
| 308 |
+
});
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
// Parse CAS info section
|
| 312 |
+
const cas_info: MDBCASInfo[] = [];
|
| 313 |
+
reader.seek(footer.cas_info_offset);
|
| 314 |
+
|
| 315 |
+
while (reader.position < footer.footer_offset) {
|
| 316 |
+
const cas_hash = reader.readHash();
|
| 317 |
+
|
| 318 |
+
// Check for bookend
|
| 319 |
+
if (isBookendHash(cas_hash)) {
|
| 320 |
+
break;
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
const cas_flags = reader.readUint32LE();
|
| 324 |
+
const num_entries = reader.readUint32LE();
|
| 325 |
+
const num_bytes_in_cas = reader.readUint32LE();
|
| 326 |
+
const num_bytes_on_disk = reader.readUint32LE();
|
| 327 |
+
|
| 328 |
+
const header: CASChunkSequenceHeader = {
|
| 329 |
+
cas_hash,
|
| 330 |
+
cas_flags,
|
| 331 |
+
num_entries,
|
| 332 |
+
num_bytes_in_cas,
|
| 333 |
+
num_bytes_on_disk,
|
| 334 |
+
};
|
| 335 |
+
|
| 336 |
+
// Read entries
|
| 337 |
+
const entries: CASChunkSequenceEntry[] = [];
|
| 338 |
+
for (let i = 0; i < num_entries; i++) {
|
| 339 |
+
entries.push({
|
| 340 |
+
chunk_hash: reader.readHash(),
|
| 341 |
+
chunk_byte_range_start: reader.readUint32LE(),
|
| 342 |
+
unpacked_segment_bytes: reader.readUint32LE(),
|
| 343 |
+
_unused: Number(reader.readUint64LE()),
|
| 344 |
+
});
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
cas_info.push({
|
| 348 |
+
header,
|
| 349 |
+
entries,
|
| 350 |
+
});
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
return {
|
| 354 |
+
header,
|
| 355 |
+
footer,
|
| 356 |
+
file_info,
|
| 357 |
+
cas_info,
|
| 358 |
+
};
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
export async function parseFile(
|
| 362 |
+
file: File,
|
| 363 |
+
fileType: "xorb" | "shard"
|
| 364 |
+
): Promise<ParsedFileMetadata> {
|
| 365 |
+
try {
|
| 366 |
+
const arrayBuffer = await file.arrayBuffer();
|
| 367 |
+
const data = new Uint8Array(arrayBuffer);
|
| 368 |
+
|
| 369 |
+
let parsedData: Chunk[] | ShardData;
|
| 370 |
+
|
| 371 |
+
if (fileType === "xorb") {
|
| 372 |
+
parsedData = parseXorbFile(data);
|
| 373 |
+
} else {
|
| 374 |
+
parsedData = parseShardFile(data);
|
| 375 |
+
}
|
| 376 |
+
|
| 377 |
+
return {
|
| 378 |
+
type: fileType,
|
| 379 |
+
filename: file.name,
|
| 380 |
+
fileSize: file.size,
|
| 381 |
+
data: parsedData,
|
| 382 |
+
};
|
| 383 |
+
} catch (error) {
|
| 384 |
+
return {
|
| 385 |
+
type: fileType,
|
| 386 |
+
filename: file.name,
|
| 387 |
+
fileSize: file.size,
|
| 388 |
+
data: [] as any,
|
| 389 |
+
error: error instanceof Error ? error.message : "Unknown error occurred",
|
| 390 |
+
};
|
| 391 |
+
}
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
// Helper functions for displaying data
|
| 395 |
+
export function formatBytes(bytes: number): string {
|
| 396 |
+
if (bytes === 0) return "0 B";
|
| 397 |
+
const k = 1000;
|
| 398 |
+
const sizes = ["B", "KB", "MB", "GB"];
|
| 399 |
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
| 400 |
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
export function formatTimestamp(timestamp: number): string {
|
| 404 |
+
return new Date(timestamp * 1000).toISOString();
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
export function formatHashShort(hash: MerkleHash): string {
|
| 408 |
+
const fullHash = formatHash(hash);
|
| 409 |
+
return fullHash.substring(0, 16) + "...";
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
export { formatHash };
|
src/lib/types.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Type definitions for xorb and shard file formats
|
| 2 |
+
|
| 3 |
+
export interface MerkleHash {
|
| 4 |
+
data: Uint8Array; // 32 bytes
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
export interface HMACKey {
|
| 8 |
+
data: Uint8Array; // 32 bytes
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
// === XORB Types ===
|
| 12 |
+
|
| 13 |
+
export interface ChunkHeader {
|
| 14 |
+
version: number;
|
| 15 |
+
compressed_size: number;
|
| 16 |
+
compression_type: number;
|
| 17 |
+
uncompressed_size: number;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
export interface Chunk {
|
| 21 |
+
header: ChunkHeader;
|
| 22 |
+
compressed_data: Uint8Array;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
// === SHARD Types ===
|
| 26 |
+
|
| 27 |
+
export interface MDBShardFileHeader {
|
| 28 |
+
tag: Uint8Array; // 32 bytes magic number
|
| 29 |
+
version: number;
|
| 30 |
+
footer_size: number;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
export interface MDBShardFileFooter {
|
| 34 |
+
version: number;
|
| 35 |
+
file_info_offset: number;
|
| 36 |
+
cas_info_offset: number;
|
| 37 |
+
chunk_hash_hmac_key: HMACKey;
|
| 38 |
+
shard_creation_timestamp: number;
|
| 39 |
+
shard_key_expiry: number;
|
| 40 |
+
footer_offset: number;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
export interface FileDataSequenceHeader {
|
| 44 |
+
file_hash: MerkleHash;
|
| 45 |
+
file_flags: number;
|
| 46 |
+
num_entries: number;
|
| 47 |
+
_unused: Uint8Array;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
export interface FileDataSequenceEntry {
|
| 51 |
+
cas_hash: MerkleHash;
|
| 52 |
+
cas_flags: number;
|
| 53 |
+
unpacked_segment_bytes: number;
|
| 54 |
+
chunk_index_start: number;
|
| 55 |
+
chunk_index_end: number;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
export interface FileVerificationEntry {
|
| 59 |
+
chunk_hash: MerkleHash;
|
| 60 |
+
_unused: Uint8Array;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
export interface FileMetadataExt {
|
| 64 |
+
sha256: MerkleHash;
|
| 65 |
+
_unused: Uint8Array;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
export interface CASChunkSequenceHeader {
|
| 69 |
+
cas_hash: MerkleHash;
|
| 70 |
+
cas_flags: number;
|
| 71 |
+
num_entries: number;
|
| 72 |
+
num_bytes_in_cas: number;
|
| 73 |
+
num_bytes_on_disk: number;
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
export interface CASChunkSequenceEntry {
|
| 77 |
+
chunk_hash: MerkleHash;
|
| 78 |
+
chunk_byte_range_start: number;
|
| 79 |
+
unpacked_segment_bytes: number;
|
| 80 |
+
_unused: number;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
export interface MDBFileInfo {
|
| 84 |
+
header: FileDataSequenceHeader;
|
| 85 |
+
entries: FileDataSequenceEntry[];
|
| 86 |
+
verification_entries?: FileVerificationEntry[];
|
| 87 |
+
metadata_ext?: FileMetadataExt;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
export interface MDBCASInfo {
|
| 91 |
+
header: CASChunkSequenceHeader;
|
| 92 |
+
entries: CASChunkSequenceEntry[];
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
export interface ShardData {
|
| 96 |
+
header: MDBShardFileHeader;
|
| 97 |
+
footer: MDBShardFileFooter;
|
| 98 |
+
file_info: MDBFileInfo[];
|
| 99 |
+
cas_info: MDBCASInfo[];
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
// === Parsed Metadata for Display ===
|
| 103 |
+
|
| 104 |
+
export interface ParsedFileMetadata {
|
| 105 |
+
type: "xorb" | "shard";
|
| 106 |
+
filename: string;
|
| 107 |
+
fileSize: number;
|
| 108 |
+
data: Chunk[] | ShardData;
|
| 109 |
+
error?: string;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
// File type detection
|
| 113 |
+
export const MDB_SHARD_HEADER_TAG = new Uint8Array([
|
| 114 |
+
0x48, 0x46, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74,
|
| 115 |
+
0x61, 0x00, 0x55, 0x69, 0x67, 0x45, 0x6a, 0x7b, 0x81, 0x57, 0x83, 0xa5, 0xbd,
|
| 116 |
+
0xd9, 0x5c, 0xcd, 0xd1, 0x4a, 0xa9,
|
| 117 |
+
]);
|
| 118 |
+
|
| 119 |
+
export const XORB_IDENT = new Uint8Array([88, 69, 84, 66, 76, 79, 66]);
|
src/main.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
| 1 |
-
import { mount } from 'svelte'
|
| 2 |
-
import './app.css'
|
| 3 |
-
import App from './App.svelte'
|
| 4 |
-
|
| 5 |
-
const app = mount(App, {
|
| 6 |
-
target: document.getElementById('app')!,
|
| 7 |
-
})
|
| 8 |
-
|
| 9 |
-
export default app
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/routes/+layout.svelte
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script lang="ts">
|
| 2 |
+
import favicon from '$lib/assets/favicon.svg';
|
| 3 |
+
|
| 4 |
+
let { children } = $props();
|
| 5 |
+
</script>
|
| 6 |
+
|
| 7 |
+
<svelte:head>
|
| 8 |
+
<link rel="icon" href={favicon} />
|
| 9 |
+
</svelte:head>
|
| 10 |
+
|
| 11 |
+
{@render children?.()}
|
src/routes/+page.svelte
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script lang="ts">
|
| 2 |
+
import FileUpload from "$lib/components/FileUpload.svelte";
|
| 3 |
+
import XorbViewer from "$lib/components/XorbViewer.svelte";
|
| 4 |
+
import ShardViewer from "$lib/components/ShardViewer.svelte";
|
| 5 |
+
import ErrorDisplay from "$lib/components/ErrorDisplay.svelte";
|
| 6 |
+
import { parseFile } from "$lib/parsers.js";
|
| 7 |
+
import type { ParsedFileMetadata, Chunk, ShardData } from "$lib/types.js";
|
| 8 |
+
|
| 9 |
+
let parsedData: ParsedFileMetadata | null = null;
|
| 10 |
+
let loading = false;
|
| 11 |
+
|
| 12 |
+
async function handleFileSelected(
|
| 13 |
+
event: CustomEvent<{ file: File; type: "xorb" | "shard" }>
|
| 14 |
+
) {
|
| 15 |
+
loading = true;
|
| 16 |
+
parsedData = null;
|
| 17 |
+
|
| 18 |
+
try {
|
| 19 |
+
const { file, type } = event.detail;
|
| 20 |
+
const result = await parseFile(file, type);
|
| 21 |
+
parsedData = result;
|
| 22 |
+
} catch (error) {
|
| 23 |
+
parsedData = {
|
| 24 |
+
type: event.detail.type,
|
| 25 |
+
filename: event.detail.file.name,
|
| 26 |
+
fileSize: event.detail.file.size,
|
| 27 |
+
data: {} as any,
|
| 28 |
+
error:
|
| 29 |
+
error instanceof Error ? error.message : "Unknown error occurred",
|
| 30 |
+
};
|
| 31 |
+
} finally {
|
| 32 |
+
loading = false;
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
function resetView() {
|
| 37 |
+
parsedData = null;
|
| 38 |
+
loading = false;
|
| 39 |
+
}
|
| 40 |
+
</script>
|
| 41 |
+
|
| 42 |
+
<svelte:head>
|
| 43 |
+
<title>XORB & Shard File Viewer</title>
|
| 44 |
+
<meta
|
| 45 |
+
name="description"
|
| 46 |
+
content="Parse and view metadata from XORB and Shard object files"
|
| 47 |
+
/>
|
| 48 |
+
</svelte:head>
|
| 49 |
+
|
| 50 |
+
<main>
|
| 51 |
+
<div class="container">
|
| 52 |
+
<header>
|
| 53 |
+
<h1>🔍 XORB & Shard File Viewer</h1>
|
| 54 |
+
<p>
|
| 55 |
+
Upload and analyze XORB or Shard object files to view their metadata
|
| 56 |
+
structure
|
| 57 |
+
</p>
|
| 58 |
+
{#if parsedData}
|
| 59 |
+
<button class="reset-btn" on:click={resetView}>
|
| 60 |
+
← Upload New File
|
| 61 |
+
</button>
|
| 62 |
+
{/if}
|
| 63 |
+
</header>
|
| 64 |
+
|
| 65 |
+
{#if loading}
|
| 66 |
+
<div class="loading">
|
| 67 |
+
<div class="spinner"></div>
|
| 68 |
+
<p>Parsing file...</p>
|
| 69 |
+
</div>
|
| 70 |
+
{:else if parsedData}
|
| 71 |
+
{#if parsedData.error}
|
| 72 |
+
<ErrorDisplay error={parsedData.error} filename={parsedData.filename} />
|
| 73 |
+
{:else if parsedData.type === "xorb"}
|
| 74 |
+
<XorbViewer
|
| 75 |
+
data={parsedData.data as Chunk[]}
|
| 76 |
+
filename={parsedData.filename}
|
| 77 |
+
fileSize={parsedData.fileSize}
|
| 78 |
+
/>
|
| 79 |
+
{:else if parsedData.type === "shard"}
|
| 80 |
+
<ShardViewer
|
| 81 |
+
data={parsedData.data as ShardData}
|
| 82 |
+
filename={parsedData.filename}
|
| 83 |
+
fileSize={parsedData.fileSize}
|
| 84 |
+
/>
|
| 85 |
+
{/if}
|
| 86 |
+
{:else}
|
| 87 |
+
<FileUpload on:fileSelected={handleFileSelected} />
|
| 88 |
+
|
| 89 |
+
<div class="info-section">
|
| 90 |
+
<h2>Supported File Types</h2>
|
| 91 |
+
<div class="file-types">
|
| 92 |
+
<div class="file-type">
|
| 93 |
+
<h3>📦 XORB Files</h3>
|
| 94 |
+
<p>
|
| 95 |
+
XORB (Xet Orb) files contain collections of compressed chunks with
|
| 96 |
+
metadata. The viewer will display chunk information, compression
|
| 97 |
+
statistics, and structural details.
|
| 98 |
+
</p>
|
| 99 |
+
<ul>
|
| 100 |
+
<li>Chunk count and sizes</li>
|
| 101 |
+
<li>Compression ratios</li>
|
| 102 |
+
<li>Hash information</li>
|
| 103 |
+
<li>Boundary offsets</li>
|
| 104 |
+
</ul>
|
| 105 |
+
</div>
|
| 106 |
+
|
| 107 |
+
<div class="file-type">
|
| 108 |
+
<h3>🗂️ Shard Files</h3>
|
| 109 |
+
<p>
|
| 110 |
+
MDB Shard files store file metadata and content-addressable
|
| 111 |
+
storage information for efficient deduplication. The viewer shows
|
| 112 |
+
file and CAS details.
|
| 113 |
+
</p>
|
| 114 |
+
<ul>
|
| 115 |
+
<li>File information entries</li>
|
| 116 |
+
<li>CAS (Content Addressable Storage) data</li>
|
| 117 |
+
<li>Lookup tables</li>
|
| 118 |
+
<li>Timestamps and security keys</li>
|
| 119 |
+
</ul>
|
| 120 |
+
</div>
|
| 121 |
+
</div>
|
| 122 |
+
</div>
|
| 123 |
+
{/if}
|
| 124 |
+
</div>
|
| 125 |
+
</main>
|
| 126 |
+
|
| 127 |
+
<style>
|
| 128 |
+
:global(body) {
|
| 129 |
+
margin: 0;
|
| 130 |
+
padding: 0;
|
| 131 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
| 132 |
+
sans-serif;
|
| 133 |
+
background: #f5f7fa;
|
| 134 |
+
color: #333;
|
| 135 |
+
line-height: 1.6;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
:global(*) {
|
| 139 |
+
box-sizing: border-box;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
main {
|
| 143 |
+
min-height: 100vh;
|
| 144 |
+
padding: 20px;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.container {
|
| 148 |
+
max-width: 1200px;
|
| 149 |
+
margin: 0 auto;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
header {
|
| 153 |
+
text-align: center;
|
| 154 |
+
margin-bottom: 40px;
|
| 155 |
+
position: relative;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
header h1 {
|
| 159 |
+
font-size: 36px;
|
| 160 |
+
margin: 0 0 16px 0;
|
| 161 |
+
color: #2c3e50;
|
| 162 |
+
font-weight: 700;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
header p {
|
| 166 |
+
font-size: 18px;
|
| 167 |
+
color: #6c757d;
|
| 168 |
+
margin: 0;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.reset-btn {
|
| 172 |
+
position: absolute;
|
| 173 |
+
left: 0;
|
| 174 |
+
top: 50%;
|
| 175 |
+
transform: translateY(-50%);
|
| 176 |
+
background: #007bff;
|
| 177 |
+
color: white;
|
| 178 |
+
border: none;
|
| 179 |
+
padding: 10px 20px;
|
| 180 |
+
border-radius: 6px;
|
| 181 |
+
cursor: pointer;
|
| 182 |
+
font-size: 14px;
|
| 183 |
+
font-weight: 500;
|
| 184 |
+
transition: background-color 0.2s;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
.reset-btn:hover {
|
| 188 |
+
background: #0056b3;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
.loading {
|
| 192 |
+
text-align: center;
|
| 193 |
+
padding: 60px 20px;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
.spinner {
|
| 197 |
+
width: 40px;
|
| 198 |
+
height: 40px;
|
| 199 |
+
border: 4px solid #f3f3f3;
|
| 200 |
+
border-top: 4px solid #007bff;
|
| 201 |
+
border-radius: 50%;
|
| 202 |
+
animation: spin 1s linear infinite;
|
| 203 |
+
margin: 0 auto 20px;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
@keyframes spin {
|
| 207 |
+
0% {
|
| 208 |
+
transform: rotate(0deg);
|
| 209 |
+
}
|
| 210 |
+
100% {
|
| 211 |
+
transform: rotate(360deg);
|
| 212 |
+
}
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
.loading p {
|
| 216 |
+
color: #6c757d;
|
| 217 |
+
font-size: 16px;
|
| 218 |
+
margin: 0;
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
.info-section {
|
| 222 |
+
margin-top: 60px;
|
| 223 |
+
text-align: center;
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
.info-section h2 {
|
| 227 |
+
font-size: 24px;
|
| 228 |
+
color: #2c3e50;
|
| 229 |
+
margin: 0 0 30px 0;
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
.file-types {
|
| 233 |
+
display: grid;
|
| 234 |
+
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
| 235 |
+
gap: 30px;
|
| 236 |
+
margin-top: 30px;
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
.file-type {
|
| 240 |
+
background: white;
|
| 241 |
+
padding: 30px;
|
| 242 |
+
border-radius: 12px;
|
| 243 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
| 244 |
+
text-align: left;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
.file-type h3 {
|
| 248 |
+
font-size: 20px;
|
| 249 |
+
margin: 0 0 16px 0;
|
| 250 |
+
color: #2c3e50;
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
.file-type p {
|
| 254 |
+
color: #6c757d;
|
| 255 |
+
margin: 0 0 20px 0;
|
| 256 |
+
line-height: 1.6;
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
.file-type ul {
|
| 260 |
+
list-style: none;
|
| 261 |
+
padding: 0;
|
| 262 |
+
margin: 0;
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
.file-type li {
|
| 266 |
+
padding: 8px 0;
|
| 267 |
+
border-bottom: 1px solid #eee;
|
| 268 |
+
color: #495057;
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
.file-type li:before {
|
| 272 |
+
content: "✓";
|
| 273 |
+
color: #28a745;
|
| 274 |
+
font-weight: bold;
|
| 275 |
+
margin-right: 8px;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
.file-type li:last-child {
|
| 279 |
+
border-bottom: none;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
@media (max-width: 768px) {
|
| 283 |
+
header h1 {
|
| 284 |
+
font-size: 28px;
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
header p {
|
| 288 |
+
font-size: 16px;
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
.reset-btn {
|
| 292 |
+
position: static;
|
| 293 |
+
transform: none;
|
| 294 |
+
margin-top: 20px;
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
.file-types {
|
| 298 |
+
grid-template-columns: 1fr;
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
.file-type {
|
| 302 |
+
padding: 20px;
|
| 303 |
+
}
|
| 304 |
+
}
|
| 305 |
+
</style>
|
src/vite-env.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
| 1 |
-
/// <reference types="svelte" />
|
| 2 |
-
/// <reference types="vite/client" />
|
|
|
|
|
|
|
|
|
static/robots.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# allow crawling everything by default
|
| 2 |
+
User-agent: *
|
| 3 |
+
Disallow:
|
svelte.config.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
| 1 |
-
import
|
|
|
|
| 2 |
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import adapter from '@sveltejs/adapter-auto';
|
| 2 |
+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
| 3 |
|
| 4 |
+
/** @type {import('@sveltejs/kit').Config} */
|
| 5 |
+
const config = {
|
| 6 |
+
// Consult https://svelte.dev/docs/kit/integrations
|
| 7 |
+
// for more information about preprocessors
|
| 8 |
+
preprocess: vitePreprocess(),
|
| 9 |
+
|
| 10 |
+
kit: {
|
| 11 |
+
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
| 12 |
+
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
| 13 |
+
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
| 14 |
+
adapter: adapter()
|
| 15 |
+
}
|
| 16 |
+
};
|
| 17 |
+
|
| 18 |
+
export default config;
|
tsconfig.app.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"extends": "@tsconfig/svelte/tsconfig.json",
|
| 3 |
-
"compilerOptions": {
|
| 4 |
-
"target": "ESNext",
|
| 5 |
-
"useDefineForClassFields": true,
|
| 6 |
-
"module": "ESNext",
|
| 7 |
-
"resolveJsonModule": true,
|
| 8 |
-
/**
|
| 9 |
-
* Typecheck JS in `.svelte` and `.js` files by default.
|
| 10 |
-
* Disable checkJs if you'd like to use dynamic types in JS.
|
| 11 |
-
* Note that setting allowJs false does not prevent the use
|
| 12 |
-
* of JS in `.svelte` files.
|
| 13 |
-
*/
|
| 14 |
-
"allowJs": true,
|
| 15 |
-
"checkJs": true,
|
| 16 |
-
"isolatedModules": true,
|
| 17 |
-
"moduleDetection": "force"
|
| 18 |
-
},
|
| 19 |
-
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
|
| 20 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tsconfig.json
CHANGED
|
@@ -1,7 +1,19 @@
|
|
| 1 |
{
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
}
|
|
|
|
| 1 |
{
|
| 2 |
+
"extends": "./.svelte-kit/tsconfig.json",
|
| 3 |
+
"compilerOptions": {
|
| 4 |
+
"allowJs": true,
|
| 5 |
+
"checkJs": true,
|
| 6 |
+
"esModuleInterop": true,
|
| 7 |
+
"forceConsistentCasingInFileNames": true,
|
| 8 |
+
"resolveJsonModule": true,
|
| 9 |
+
"skipLibCheck": true,
|
| 10 |
+
"sourceMap": true,
|
| 11 |
+
"strict": true,
|
| 12 |
+
"moduleResolution": "bundler"
|
| 13 |
+
}
|
| 14 |
+
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
| 15 |
+
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
| 16 |
+
//
|
| 17 |
+
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
| 18 |
+
// from the referenced tsconfig.json - TypeScript does not merge them in
|
| 19 |
}
|
tsconfig.node.json
DELETED
|
@@ -1,25 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"compilerOptions": {
|
| 3 |
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
| 4 |
-
"target": "ES2022",
|
| 5 |
-
"lib": ["ES2023"],
|
| 6 |
-
"module": "ESNext",
|
| 7 |
-
"skipLibCheck": true,
|
| 8 |
-
|
| 9 |
-
/* Bundler mode */
|
| 10 |
-
"moduleResolution": "bundler",
|
| 11 |
-
"allowImportingTsExtensions": true,
|
| 12 |
-
"verbatimModuleSyntax": true,
|
| 13 |
-
"moduleDetection": "force",
|
| 14 |
-
"noEmit": true,
|
| 15 |
-
|
| 16 |
-
/* Linting */
|
| 17 |
-
"strict": true,
|
| 18 |
-
"noUnusedLocals": true,
|
| 19 |
-
"noUnusedParameters": true,
|
| 20 |
-
"erasableSyntaxOnly": true,
|
| 21 |
-
"noFallthroughCasesInSwitch": true,
|
| 22 |
-
"noUncheckedSideEffectImports": true
|
| 23 |
-
},
|
| 24 |
-
"include": ["vite.config.ts"]
|
| 25 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vite.config.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
-
import {
|
| 2 |
-
import {
|
| 3 |
|
| 4 |
-
// https://vite.dev/config/
|
| 5 |
export default defineConfig({
|
| 6 |
-
|
| 7 |
-
})
|
|
|
|
| 1 |
+
import { sveltekit } from '@sveltejs/kit/vite';
|
| 2 |
+
import { defineConfig } from 'vite';
|
| 3 |
|
|
|
|
| 4 |
export default defineConfig({
|
| 5 |
+
plugins: [sveltekit()]
|
| 6 |
+
});
|