New design

This commit is contained in:
Majo
2022-09-12 21:09:48 +00:00
parent 34e14a5165
commit 766a03044a
18 changed files with 1735 additions and 294 deletions

View File

@@ -2,73 +2,72 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="favicon.png" />
<link rel="icon" href="/src/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FDB Converter</title>
<title>FDB to SQLite | FDB Converter</title>
<meta
name="description"
content="Convert FDB files of the game LEGO Universe to SQLite files and SQLite files back to FDB files. The conversion takes place entirely client-side. Nothing is uploaded to a server."
content="Convert FDB files of the game LEGO Universe to SQLite files. The conversion takes place entirely client-side. Nothing is uploaded to a server."
/>
<meta name="color-scheme" content="light dark" />
</head>
<body>
<h3 class="center-align margin">FDB Converter</h3>
<div id="chips">
<button id="fts-chip" class="chip small-margin">
<i class="small outlined fts">check</i>
<span>FDB to SQLite</span>
</button>
<button id="stf-chip" class="chip small-margin border">
<i class="small outlined stf invisible">check</i>
<span>SQLite to FDB</span>
</button>
<body class="surface on-surface-text body-large">
<div>
<h1 class="display-large">FDB To SQLite</h1>
<p class="title-large">
Convert FDB files of the game LEGO Universe to SQLite files.
</p>
</div>
<div class="large-margin">
<article id="drop-area" class="border round">
<label for="file">
<h4 id="file-label" class="center-align fts">FDB File</h4>
<h4 id="file-label" class="center-align stf invisible">
SQLite File
</h4>
</label>
<i id="file-icon" class="outlined">upload_file</i>
<div id="loader" class="loader invisible"></div>
<p class="center-align fts">
Drag and drop your FDB file or click to select your FDB file.
</p>
<p class="center-align stf invisible">
Drag and drop your SQlite file or click to select your SQLite file.
</p>
<input id="file" type="file" accept=".fdb" />
</article>
<label>
<h2 class="headline-small">FDB File</h2>
<div class="file-icon material-icons-outlined">upload_file</div>
<p>Drag and drop your FDB file or click to select your FDB file.</p>
<input
type="file"
accept=".fdb"
data-input-extension="fdb"
data-output-extension="sqlite"
/>
<md-ripple></md-ripple>
</label>
<div>
<p>
The conversion takes place entirely client-side. Nothing is uploaded to
a server.
</p>
<p>
Based on
<a class="primary-text" href="https://assembly.lu-dev.net/">
Assembly RS</a
>. The source code of this website can be found
<a class="primary-text" href="https://github.com/IAmMajo/FDB-Converter">
here</a
>.
</p>
</div>
<p class="center-align margin">
The conversion takes place entirely client-side. Nothing is uploaded to a
server.
</p>
<p class="center-align margin">
Based on
<a class="link" href="https://assembly.lu-dev.net/">Assembly RS</a>. The
source code of this website can be found
<a class="link" href="https://github.com/IAmMajo/FDB-Converter">here</a>.
</p>
<div id="error-file-type" class="toast error round small-padding">
<span class="small-margin">
The file does not have the correct file type.
</span>
<button
id="error-file-type-close"
class="small-margin small round error-container"
>
Close
</button>
</div>
<div id="error" class="toast error round small-padding">
<span class="small-margin">An error occured while converting.</span>
<button id="error-close" class="small-margin small round error-container">
Close
</button>
</div>
<script type="module" src="/main.js"></script>
<md-navigation-bar>
<nav>
<a href="/">
<md-navigation-tab label="FDB to SQLite" active>
<span slot="activeIcon" class="material-icons">circle</span>
</md-navigation-tab>
</a>
<a href="/sqlite-to-fdb/">
<md-navigation-tab label="SQLite to FDB">
<span slot="inactiveIcon" class="material-icons-outlined">
square
</span>
</md-navigation-tab>
</a>
<a href="/xml-to-fdb/">
<md-navigation-tab label="XML to FDB">
<span slot="inactiveIcon" class="material-icons-outlined">
hexagon
</span>
</md-navigation-tab>
</a>
</nav>
</md-navigation-bar>
<script type="module" src="/src/main.js"></script>
</body>
</html>

119
main.js
View File

@@ -1,119 +0,0 @@
import "beercss";
import "./style.css";
let isFdbToSqlite = true;
let module = null;
let objectUrl = null;
const ftsChip = document.getElementById("fts-chip");
const stfChip = document.getElementById("stf-chip");
const fileElement = document.getElementById("file");
const error = document.getElementById("error");
const errorFileType = document.getElementById("error-file-type");
const errorClose = document.getElementById("error-close");
const errorFileTypeClose = document.getElementById("error-file-type-close");
const fileIcon = document.getElementById("file-icon");
const loader = document.getElementById("loader");
const dropArea = document.getElementById("drop-area");
ftsChip.addEventListener("click", () => {
ftsChip.classList.remove("border");
stfChip.classList.add("border");
document
.querySelectorAll(".fts")
.forEach((element) => element.classList.remove("invisible"));
document
.querySelectorAll(".stf")
.forEach((element) => element.classList.add("invisible"));
fileElement.setAttribute("accept", ".fdb");
isFdbToSqlite = true;
});
stfChip.addEventListener("click", () => {
stfChip.classList.remove("border");
ftsChip.classList.add("border");
document
.querySelectorAll(".stf")
.forEach((element) => element.classList.remove("invisible"));
document
.querySelectorAll(".fts")
.forEach((element) => element.classList.add("invisible"));
fileElement.setAttribute("accept", ".sqlite");
isFdbToSqlite = false;
});
dropArea.addEventListener("dragover", () =>
dropArea.classList.remove("border")
);
dropArea.addEventListener("dragleave", () => dropArea.classList.add("border"));
errorClose.addEventListener("click", () => error.classList.remove("active"));
errorFileTypeClose.addEventListener("click", () =>
errorFileType.classList.remove("active")
);
fileElement.addEventListener("change", async () => {
if (objectUrl) {
window.URL.revokeObjectURL(objectUrl);
}
const file = fileElement.files[0];
fileElement.value = null;
error.classList.remove("active");
errorFileType.classList.remove("active");
let inputFileExtension;
let outputFileExtension;
if (isFdbToSqlite) {
inputFileExtension = "fdb";
outputFileExtension = "sqlite";
} else {
inputFileExtension = "sqlite";
outputFileExtension = "fdb";
}
if (!file.name.endsWith("." + inputFileExtension)) {
errorFileType.classList.add("active");
dropArea.classList.add("border");
return;
}
fileIcon.classList.add("invisible");
loader.classList.remove("invisible");
fileElement.disabled = true;
if (!module) {
const script = document.createElement("script");
script.src = "/fdb-converter.js";
const scriptLoad = new Promise((resolve) =>
script.addEventListener("load", () => resolve())
);
document.head.append(script);
await scriptLoad;
module = await Module();
}
const input = new Uint8Array(await file.arrayBuffer());
module.FS.writeFile("input." + inputFileExtension, input);
let output;
try {
module.ccall(inputFileExtension + "_to_" + outputFileExtension, null);
} catch (e) {
error.classList.add("active");
return;
} finally {
module.FS.unlink("input." + inputFileExtension);
fileIcon.classList.remove("invisible");
loader.classList.add("invisible");
fileElement.disabled = false;
dropArea.classList.add("border");
}
output = module.FS.readFile("output." + outputFileExtension);
module.FS.unlink("output." + outputFileExtension);
objectUrl = window.URL.createObjectURL(
new Blob([output], { type: "application/octet-stream" })
);
const a = document.createElement("a");
a.href = objectUrl;
a.download =
file.name.split(".").slice(0, -1).join(".") + "." + outputFileExtension;
document.body.appendChild(a);
a.click();
a.remove();
});

545
package-lock.json generated
View File

@@ -8,7 +8,11 @@
"name": "@iammajo/fdb-converter",
"version": "0.0.0",
"dependencies": {
"beercss": "2.0.2"
"@fontsource/material-icons": "^4.5.4",
"@fontsource/material-icons-outlined": "^4.5.4",
"@fontsource/roboto": "^4.5.8",
"@loadingio/css-spinner": "^2.0.2",
"@material/web": "^0.1.0-alpha.0"
},
"devDependencies": {
"prettier": "2.7.1",
@@ -32,6 +36,40 @@
"node": ">=12"
}
},
"node_modules/@fontsource/material-icons": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/@fontsource/material-icons/-/material-icons-4.5.4.tgz",
"integrity": "sha512-YGmXkkEdu6EIgpFKNmB/nIXzZocwSmbI01Ninpmml8x8BT0M6RR++V1KqOfpzZ6Cw/FQ2/KYonQ3x4IY/4VRRA=="
},
"node_modules/@fontsource/material-icons-outlined": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/@fontsource/material-icons-outlined/-/material-icons-outlined-4.5.4.tgz",
"integrity": "sha512-2SLQe/pAlOzoE2Kd5cBxqTgI9U63hf3a7RrCF8GFvgPkYhF6WOcIzFzsLc1Fdf+UhcYS+Hgpp6o8peguwZGK9Q=="
},
"node_modules/@fontsource/roboto": {
"version": "4.5.8",
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz",
"integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA=="
},
"node_modules/@lit/reactive-element": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz",
"integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw=="
},
"node_modules/@loadingio/css-spinner": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@loadingio/css-spinner/-/css-spinner-2.0.2.tgz",
"integrity": "sha512-cEn4mcvtd6q2YlSIjklGm8jP4ENkH0bxIC6lVqBC97oXtc8eRuCg16MfD94f0UvukFpeQwX2akJVsUX9LjpLRw=="
},
"node_modules/@material/web": {
"version": "0.1.0-alpha.0",
"resolved": "https://registry.npmjs.org/@material/web/-/web-0.1.0-alpha.0.tgz",
"integrity": "sha512-GNsNyWOtYKezXwvrD1ZBfnOHClVya31ZEQH1O83+PsPqlVZK6cBfnf1cwJmEFQ6FezB6q6q+cHGGqx0lb90Jug==",
"dependencies": {
"lit": "^2.3.0",
"tslib": "^2.4.0"
}
},
"node_modules/@toml-tools/lexer": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@toml-tools/lexer/-/lexer-0.3.1.tgz",
@@ -51,10 +89,50 @@
"chevrotain": "4.1.1"
}
},
"node_modules/beercss": {
"node_modules/@types/trusted-types": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/beercss/-/beercss-2.0.2.tgz",
"integrity": "sha512-KcJGmvYX3ty2/9jBWeeOpVmZrG4luOcc3hDWqpuiPa/fkUtxtC3Ssgr/HOgM+S9UYzM+nIoegWtjKO5LVQehLw=="
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz",
"integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
},
"node_modules/anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=8"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"fill-range": "^7.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/chevrotain": {
"version": "4.1.1",
@@ -65,6 +143,35 @@
"regexp-to-ast": "0.3.5"
}
},
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
],
"optional": true,
"peer": true,
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/esbuild": {
"version": "0.15.7",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz",
@@ -421,6 +528,20 @@
"node": ">=12"
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -441,6 +562,20 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -453,6 +588,28 @@
"node": ">= 0.4.0"
}
},
"node_modules/immutable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
"integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
"dev": true,
"optional": true,
"peer": true
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-core-module": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
@@ -465,6 +622,69 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/lit": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lit/-/lit-2.3.1.tgz",
"integrity": "sha512-TejktDR4mqG3qB32Y8Lm5Lye3c8SUehqz7qRsxe1PqGYL6me2Ef+jeQAEqh20BnnGncv4Yxy2njEIT0kzK1WCw==",
"dependencies": {
"@lit/reactive-element": "^1.4.0",
"lit-element": "^3.2.0",
"lit-html": "^2.3.0"
}
},
"node_modules/lit-element": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.2.tgz",
"integrity": "sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==",
"dependencies": {
"@lit/reactive-element": "^1.3.0",
"lit-html": "^2.2.0"
}
},
"node_modules/lit-html": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.3.1.tgz",
"integrity": "sha512-FyKH6LTW6aBdkfNhNSHyZTnLgJSTe5hMk7HFtc/+DcN1w74C215q8B+Cfxc2OuIEpBNcEKxgF64qL8as30FDHA==",
"dependencies": {
"@types/trusted-types": "^2.0.2"
}
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
@@ -477,6 +697,17 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -489,6 +720,20 @@
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/postcss": {
"version": "8.4.16",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
@@ -550,6 +795,20 @@
"node": ">=4"
}
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/regexp-to-ast": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.3.5.tgz",
@@ -588,6 +847,25 @@
"fsevents": "~2.3.2"
}
},
"node_modules/sass": {
"version": "1.54.9",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.54.9.tgz",
"integrity": "sha512-xb1hjASzEH+0L0WI9oFjqhRi51t/gagWnxLiwUNMltA0Ab6jIDkAacgKiGYKM9Jhy109osM7woEEai6SXeJo5Q==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
"sass": "sass.js"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@@ -609,6 +887,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/vite": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.0.tgz",
@@ -659,6 +956,40 @@
"dev": true,
"optional": true
},
"@fontsource/material-icons": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/@fontsource/material-icons/-/material-icons-4.5.4.tgz",
"integrity": "sha512-YGmXkkEdu6EIgpFKNmB/nIXzZocwSmbI01Ninpmml8x8BT0M6RR++V1KqOfpzZ6Cw/FQ2/KYonQ3x4IY/4VRRA=="
},
"@fontsource/material-icons-outlined": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/@fontsource/material-icons-outlined/-/material-icons-outlined-4.5.4.tgz",
"integrity": "sha512-2SLQe/pAlOzoE2Kd5cBxqTgI9U63hf3a7RrCF8GFvgPkYhF6WOcIzFzsLc1Fdf+UhcYS+Hgpp6o8peguwZGK9Q=="
},
"@fontsource/roboto": {
"version": "4.5.8",
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz",
"integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA=="
},
"@lit/reactive-element": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz",
"integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw=="
},
"@loadingio/css-spinner": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@loadingio/css-spinner/-/css-spinner-2.0.2.tgz",
"integrity": "sha512-cEn4mcvtd6q2YlSIjklGm8jP4ENkH0bxIC6lVqBC97oXtc8eRuCg16MfD94f0UvukFpeQwX2akJVsUX9LjpLRw=="
},
"@material/web": {
"version": "0.1.0-alpha.0",
"resolved": "https://registry.npmjs.org/@material/web/-/web-0.1.0-alpha.0.tgz",
"integrity": "sha512-GNsNyWOtYKezXwvrD1ZBfnOHClVya31ZEQH1O83+PsPqlVZK6cBfnf1cwJmEFQ6FezB6q6q+cHGGqx0lb90Jug==",
"requires": {
"lit": "^2.3.0",
"tslib": "^2.4.0"
}
},
"@toml-tools/lexer": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@toml-tools/lexer/-/lexer-0.3.1.tgz",
@@ -678,10 +1009,41 @@
"chevrotain": "4.1.1"
}
},
"beercss": {
"@types/trusted-types": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/beercss/-/beercss-2.0.2.tgz",
"integrity": "sha512-KcJGmvYX3ty2/9jBWeeOpVmZrG4luOcc3hDWqpuiPa/fkUtxtC3Ssgr/HOgM+S9UYzM+nIoegWtjKO5LVQehLw=="
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz",
"integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
},
"anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
}
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true,
"optional": true,
"peer": true
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"chevrotain": {
"version": "4.1.1",
@@ -692,6 +1054,24 @@
"regexp-to-ast": "0.3.5"
}
},
"chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
}
},
"esbuild": {
"version": "0.15.7",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz",
@@ -861,6 +1241,17 @@
"dev": true,
"optional": true
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -874,6 +1265,17 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -883,6 +1285,25 @@
"function-bind": "^1.1.1"
}
},
"immutable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
"integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
"dev": true,
"optional": true,
"peer": true
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"binary-extensions": "^2.0.0"
}
},
"is-core-module": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
@@ -892,12 +1313,74 @@
"has": "^1.0.3"
}
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"optional": true,
"peer": true
},
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"optional": true,
"peer": true
},
"lit": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lit/-/lit-2.3.1.tgz",
"integrity": "sha512-TejktDR4mqG3qB32Y8Lm5Lye3c8SUehqz7qRsxe1PqGYL6me2Ef+jeQAEqh20BnnGncv4Yxy2njEIT0kzK1WCw==",
"requires": {
"@lit/reactive-element": "^1.4.0",
"lit-element": "^3.2.0",
"lit-html": "^2.3.0"
}
},
"lit-element": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.2.tgz",
"integrity": "sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==",
"requires": {
"@lit/reactive-element": "^1.3.0",
"lit-html": "^2.2.0"
}
},
"lit-html": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.3.1.tgz",
"integrity": "sha512-FyKH6LTW6aBdkfNhNSHyZTnLgJSTe5hMk7HFtc/+DcN1w74C215q8B+Cfxc2OuIEpBNcEKxgF64qL8as30FDHA==",
"requires": {
"@types/trusted-types": "^2.0.2"
}
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"dev": true
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"optional": true,
"peer": true
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -910,6 +1393,14 @@
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"optional": true,
"peer": true
},
"postcss": {
"version": "8.4.16",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
@@ -945,6 +1436,17 @@
}
}
},
"readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"picomatch": "^2.2.1"
}
},
"regexp-to-ast": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.3.5.tgz",
@@ -971,6 +1473,19 @@
"fsevents": "~2.3.2"
}
},
"sass": {
"version": "1.54.9",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.54.9.tgz",
"integrity": "sha512-xb1hjASzEH+0L0WI9oFjqhRi51t/gagWnxLiwUNMltA0Ab6jIDkAacgKiGYKM9Jhy109osM7woEEai6SXeJo5Q==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
}
},
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@@ -983,6 +1498,22 @@
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"is-number": "^7.0.0"
}
},
"tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"vite": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.0.tgz",

View File

@@ -16,6 +16,10 @@
"npm": "8.19.1"
},
"dependencies": {
"beercss": "^2.0.2"
"@fontsource/material-icons": "^4.5.4",
"@fontsource/material-icons-outlined": "^4.5.4",
"@fontsource/roboto": "^4.5.8",
"@loadingio/css-spinner": "^2.0.2",
"@material/web": "^0.1.0-alpha.0"
}
}

71
sqlite-to-fdb/index.html Normal file
View File

@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/src/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SQLite to FDB | FDB Converter</title>
<meta
name="description"
content="Convert SQLite files back to FDB files. The conversion takes place entirely client-side. Nothing is uploaded to a server."
/>
<meta name="color-scheme" content="light dark" />
</head>
<body class="surface on-surface-text body-large">
<div>
<h1 class="display-large">SQLite to FDB</h1>
<p class="title-large">Convert SQLite files back to FDB files.</p>
</div>
<label>
<h2 class="headline-small">SQLite File</h2>
<div class="file-icon material-icons-outlined">upload_file</div>
<p>Drag and drop your SQLite file or click to select your SQLite file.</p>
<input
type="file"
accept=".sqlite"
data-input-extension="sqlite"
data-output-extension="fdb"
/>
<md-ripple></md-ripple>
</label>
<div>
<p>
The conversion takes place entirely client-side. Nothing is uploaded to
a server.
</p>
<p>
Based on
<a class="primary-text" href="https://assembly.lu-dev.net/">
Assembly RS</a
>. The source code of this website can be found
<a class="primary-text" href="https://github.com/IAmMajo/FDB-Converter">
here</a
>.
</p>
</div>
<md-navigation-bar>
<nav>
<a href="/">
<md-navigation-tab label="FDB to SQLite">
<span slot="inactiveIcon" class="material-icons-outlined">
circle
</span>
</md-navigation-tab>
</a>
<a href="/sqlite-to-fdb/">
<md-navigation-tab label="SQLite to FDB" active>
<span slot="activeIcon" class="material-icons">square</span>
</md-navigation-tab>
</a>
<a href="/xml-to-fdb/">
<md-navigation-tab label="XML to FDB">
<span slot="inactiveIcon" class="material-icons-outlined">
hexagon
</span>
</md-navigation-tab>
</a>
</nav>
</md-navigation-bar>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

129
src/main.js Normal file
View File

@@ -0,0 +1,129 @@
import "@fontsource/roboto/latin-400.css";
import "@fontsource/roboto/latin-500.css";
import "./theme/theme.css";
import "@fontsource/material-icons";
import "@fontsource/material-icons-outlined";
import "@material/web/ripple/ripple";
import "@material/web/navigationbar/navigation-bar";
import "@material/web/navigationtab/navigation-tab";
import "@loadingio/css-spinner/entries/ring/index.css";
import "@material/web/button/text-button";
import "./style.css";
import { ActionController } from "@material/web/controller/action-controller";
document.querySelectorAll("md-navigation-tab").forEach((tab) => {
const tabStyle = document.createElement("style");
tabStyle.textContent =
"@media (min-width: 600px) and (orientation: portrait), " +
"(min-width: 916px) { span.md3-navigation-tab__label-text { height: 32px " +
"} }";
tab.shadowRoot.append(tabStyle);
});
const dropArea = document.querySelector("label");
const ripple = document.querySelector("md-ripple");
const controller = new ActionController(ripple);
dropArea.addEventListener("pointerenter", (event) => ripple.beginHover(event));
dropArea.addEventListener("pointerleave", (event) => {
ripple.endHover();
controller.pointerLeave(event);
});
dropArea.addEventListener("pointerdown", controller.pointerDown);
dropArea.addEventListener("pointerup", controller.pointerUp);
dropArea.addEventListener("click", controller.click);
dropArea.addEventListener("pointercancel", controller.pointerCancel);
dropArea.addEventListener("contextmenu", controller.contextMenu);
dropArea.addEventListener("dragover", () =>
dropArea.classList.add("surface-variant", "on-surface-variant-text")
);
dropArea.addEventListener("dragleave", () =>
dropArea.classList.remove("surface-variant", "on-surface-variant-text")
);
let objectUrl = null;
let module = null;
const fileElement = document.querySelector("input");
const fileIcon = document.querySelector(".file-icon");
fileElement.addEventListener("change", async () => {
if (objectUrl) {
window.URL.revokeObjectURL(objectUrl);
}
dropArea.classList.remove("surface-variant", "on-surface-variant-text");
closeError();
const file = fileElement.files[0];
fileElement.value = null;
const inputExtension = fileElement.dataset.inputExtension;
const outputExtension = fileElement.dataset.outputExtension;
if (!file.name.endsWith("." + inputExtension)) {
showError("The file does not have the correct file type.");
return;
}
fileIcon.style.display = "none";
const loader = document.createElement("div");
loader.classList.add("lds-ring");
const emptyDiv = document.createElement("div");
loader.appendChild(emptyDiv);
loader.appendChild(emptyDiv.cloneNode());
loader.appendChild(emptyDiv.cloneNode());
loader.appendChild(emptyDiv.cloneNode());
fileIcon.insertAdjacentElement("afterend", loader);
fileElement.disabled = true;
if (!module) {
const script = document.createElement("script");
script.src = "/fdb-converter.js";
const scriptLoad = new Promise((resolve) =>
script.addEventListener("load", () => resolve())
);
document.head.append(script);
await scriptLoad;
module = await Module();
}
const input = new Uint8Array(await file.arrayBuffer());
module.FS.writeFile("input", input);
try {
module.ccall(inputExtension + "_to_" + outputExtension, null);
} catch (e) {
showError("An error occured while converting.");
return;
} finally {
module.FS.unlink("input");
fileIcon.style.display = "";
loader.remove();
fileElement.disabled = false;
}
const output = module.FS.readFile("output");
module.FS.unlink("output");
objectUrl = window.URL.createObjectURL(
new Blob([output], { type: "application/octet-stream" })
);
const a = document.createElement("a");
a.href = objectUrl;
a.download =
file.name.split(".").slice(0, -1).join(".") + "." + outputExtension;
document.body.appendChild(a);
a.click();
a.remove();
});
function showError(message) {
const wrapper = document.createElement("div");
wrapper.classList.add("error-wrapper");
const error = document.createElement("div");
error.classList.add("error-container", "on-error-container-text");
const p = document.createElement("p");
p.textContent = message;
error.appendChild(p);
const button = document.createElement("md-text-button");
button.label = "Close";
error.appendChild(button);
wrapper.appendChild(error);
document.body.appendChild(wrapper);
button.addEventListener("click", closeError);
}
function closeError() {
const wrapper = document.querySelector(".error-wrapper");
if (wrapper) {
wrapper.remove();
}
}

View File

@@ -34,14 +34,14 @@ fn main() {}
pub extern "C" fn fdb_to_sqlite() {
let start = Instant::now();
let src_file = File::open("input.fdb").unwrap();
let src_file = File::open("input").unwrap();
let mmap = unsafe { Mmap::map(&src_file).unwrap() };
let buffer: &[u8] = &mmap;
println!("Copying data, this may take a few seconds...");
let db = Database::new(buffer);
let mut conn = Connection::open("output.sqlite").unwrap();
let mut conn = Connection::open("output").unwrap();
try_export_db(&mut conn, db).unwrap();
@@ -61,11 +61,10 @@ pub extern "C" fn sqlite_to_fdb() {
// sqlite input
let conn =
Connection::open_with_flags("input.sqlite", rusqlite::OpenFlags::SQLITE_OPEN_READ_ONLY)
.unwrap();
Connection::open_with_flags("input", rusqlite::OpenFlags::SQLITE_OPEN_READ_ONLY).unwrap();
// fdb output
let dest_file = File::create("output.fdb").unwrap();
let dest_file = File::create("output").unwrap();
let mut dest_out = BufWriter::new(dest_file);
let mut dest_db = store::Database::new();
@@ -185,17 +184,17 @@ pub extern "C" fn sqlite_to_fdb() {
duration.subsec_millis()
);
println!("Output written to 'output.fdb'");
println!("Output written to 'output'");
}
/// Code adapted from
/// https://github.com/LUDevNet/Assembly/blob/dd2a7e0e9494cc94f7cc4df814f2631d1af1f306/modules/data/examples/xmldb-to-fdb.rs#L38
#[no_mangle]
pub extern "C" fn xml_to_fdb() {
let src_file = File::open("input.xml").unwrap();
let src_file = File::open("input").unwrap();
let reader = BufReader::new(src_file);
let dest_file = File::create("output.fdb").unwrap();
let dest_file = File::create("output").unwrap();
let mut dest_out = BufWriter::new(dest_file);
println!("Copying file, this may take a few seconds...");

142
src/style.css Normal file
View File

@@ -0,0 +1,142 @@
html {
--file-icon-size: max(min(calc(100vh - 747.22px), calc(100vw - 50px)), 230px);
max-width: 1304px;
margin: auto;
}
body {
margin: 0 8px 80px;
text-align: center;
min-height: calc(100vh - 80px);
display: flex;
flex-direction: column;
justify-content: space-between;
}
label {
position: relative;
border: 1px solid var(--md-sys-color-outline);
border-radius: 12px;
padding: 0 16px;
--md-ripple-hover-state-layer-color: var(--md-sys-color-on-surface);
--md-ripple-pressed-state-layer-color: var(--md-sys-color-on-surface);
}
label.surface-variant {
border-color: transparent;
--md-ripple-hover-state-layer-color: var(--md-sys-color-on-surface-variant);
--md-ripple-pressed-state-layer-color: var(--md-sys-color-on-surface-variant);
}
.file-icon {
font-size: var(--file-icon-size);
}
input {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
md-navigation-bar {
position: fixed;
left: 0;
bottom: 0;
}
nav {
display: flex;
width: 100%;
}
nav a {
display: flex;
flex-grow: 1;
text-decoration: none;
}
.lds-ring {
display: flex;
justify-content: center;
align-items: center;
margin: auto;
color: var(--md-sys-color-primary);
width: var(--file-icon-size);
height: var(--file-icon-size);
}
.lds-ring div {
width: calc(var(--file-icon-size) * 0.5 - 16px);
height: calc(var(--file-icon-size) * 0.5 - 16px);
}
.error-wrapper {
position: fixed;
display: flex;
justify-content: center;
bottom: 96px;
left: 8px;
right: 8px;
}
.error-container {
border-radius: 12px;
display: flex;
align-items: center;
padding: 0 4px 0 16px;
text-align: left;
}
.error-container p {
margin-right: 24px;
}
@media (min-width: 600px) and (orientation: portrait), (min-width: 916px) {
html {
--file-icon-size: max(
min(calc(100vh - 490.22px), calc(100vw - 138px)),
230px
);
}
body {
margin: 0 12px 0 92px;
min-height: 100vh;
}
md-navigation-bar {
top: 0;
width: 80px;
--md-navigation-bar-container-height: 100%;
}
nav {
flex-direction: column;
justify-content: center;
}
nav a {
flex-grow: unset;
}
.error-wrapper {
left: 88px;
}
}
@media (min-width: 840px) and (orientation: portrait), (min-width: 916px) {
html {
--file-icon-size: max(
min(calc(100vh - 452.22px), calc(100vw - 178px)),
230px
);
}
body {
margin: 0 32px 0 112px;
}
}

174
src/theme/colors.module.css Normal file
View File

@@ -0,0 +1,174 @@
.primary {
background-color: var(--md-sys-color-primary);
}
.primary-text {
color: var(--md-sys-color-primary);
}
.on-primary {
background-color: var(--md-sys-color-on-primary);
}
.on-primary-text {
color: var(--md-sys-color-on-primary);
}
.primary-container {
background-color: var(--md-sys-color-primary-container);
}
.primary-container-text {
color: var(--md-sys-color-primary-container);
}
.on-primary-container {
background-color: var(--md-sys-color-on-primary-container);
}
.on-primary-container-text {
color: var(--md-sys-color-on-primary-container);
}
.secondary {
background-color: var(--md-sys-color-secondary);
}
.secondary-text {
color: var(--md-sys-color-secondary);
}
.on-secondary {
background-color: var(--md-sys-color-on-secondary);
}
.on-secondary-text {
color: var(--md-sys-color-on-secondary);
}
.secondary-container {
background-color: var(--md-sys-color-secondary-container);
}
.secondary-container-text {
color: var(--md-sys-color-secondary-container);
}
.on-secondary-container {
background-color: var(--md-sys-color-on-secondary-container);
}
.on-secondary-container-text {
color: var(--md-sys-color-on-secondary-container);
}
.tertiary {
background-color: var(--md-sys-color-tertiary);
}
.tertiary-text {
color: var(--md-sys-color-tertiary);
}
.on-tertiary {
background-color: var(--md-sys-color-on-tertiary);
}
.on-tertiary-text {
color: var(--md-sys-color-on-tertiary);
}
.tertiary-container {
background-color: var(--md-sys-color-tertiary-container);
}
.tertiary-container-text {
color: var(--md-sys-color-tertiary-container);
}
.on-tertiary-container {
background-color: var(--md-sys-color-on-tertiary-container);
}
.on-tertiary-container-text {
color: var(--md-sys-color-on-tertiary-container);
}
.error {
background-color: var(--md-sys-color-error);
}
.error-text {
color: var(--md-sys-color-error);
}
.error-container {
background-color: var(--md-sys-color-error-container);
}
.error-container-text {
color: var(--md-sys-color-error-container);
}
.on-error {
background-color: var(--md-sys-color-on-error);
}
.on-error-text {
color: var(--md-sys-color-on-error);
}
.on-error-container {
background-color: var(--md-sys-color-on-error-container);
}
.on-error-container-text {
color: var(--md-sys-color-on-error-container);
}
.background {
background-color: var(--md-sys-color-background);
}
.background-text {
color: var(--md-sys-color-background);
}
.on-background {
background-color: var(--md-sys-color-on-background);
}
.on-background-text {
color: var(--md-sys-color-on-background);
}
.surface {
background-color: var(--md-sys-color-surface);
}
.surface-text {
color: var(--md-sys-color-surface);
}
.on-surface {
background-color: var(--md-sys-color-on-surface);
}
.on-surface-text {
color: var(--md-sys-color-on-surface);
}
.surface-variant {
background-color: var(--md-sys-color-surface-variant);
}
.surface-variant-text {
color: var(--md-sys-color-surface-variant);
}
.on-surface-variant {
background-color: var(--md-sys-color-on-surface-variant);
}
.on-surface-variant-text {
color: var(--md-sys-color-on-surface-variant);
}
.outline {
background-color: var(--md-sys-color-outline);
}
.outline-text {
color: var(--md-sys-color-outline);
}
.inverse-on-surface {
background-color: var(--md-sys-color-inverse-on-surface);
}
.inverse-on-surface-text {
color: var(--md-sys-color-inverse-on-surface);
}
.inverse-surface {
background-color: var(--md-sys-color-inverse-surface);
}
.inverse-surface-text {
color: var(--md-sys-color-inverse-surface);
}
.inverse-primary {
background-color: var(--md-sys-color-inverse-primary);
}
.inverse-primary-text {
color: var(--md-sys-color-inverse-primary);
}
.shadow {
background-color: var(--md-sys-color-shadow);
}
.shadow-text {
color: var(--md-sys-color-shadow);
}
.surface-tint {
background-color: var(--md-sys-color-surface-tint);
}
.surface-tint-text {
color: var(--md-sys-color-surface-tint);
}
.surface-tint-color {
background-color: var(--md-sys-color-surface-tint-color);
}
.surface-tint-color-text {
color: var(--md-sys-color-surface-tint-color);
}

5
src/theme/theme.css Normal file
View File

@@ -0,0 +1,5 @@
@import url(tokens.css);
@import url(colors.module.css);
@import url(typography.module.css);
@import url(theme.light.css) (prefers-color-scheme: light);
@import url(theme.dark.css) (prefers-color-scheme: dark);

49
src/theme/theme.dark.css Normal file
View File

@@ -0,0 +1,49 @@
:root {
--md-sys-color-primary: var(--md-sys-color-primary-dark);
--md-sys-color-on-primary: var(--md-sys-color-on-primary-dark);
--md-sys-color-primary-container: var(--md-sys-color-primary-container-dark);
--md-sys-color-on-primary-container: var(
--md-sys-color-on-primary-container-dark
);
--md-sys-color-secondary: var(--md-sys-color-secondary-dark);
--md-sys-color-on-secondary: var(--md-sys-color-on-secondary-dark);
--md-sys-color-secondary-container: var(
--md-sys-color-secondary-container-dark
);
--md-sys-color-on-secondary-container: var(
--md-sys-color-on-secondary-container-dark
);
--md-sys-color-tertiary: var(--md-sys-color-tertiary-dark);
--md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-dark);
--md-sys-color-tertiary-container: var(
--md-sys-color-tertiary-container-dark
);
--md-sys-color-on-tertiary-container: var(
--md-sys-color-on-tertiary-container-dark
);
--md-sys-color-error: var(--md-sys-color-error-dark);
--md-sys-color-error-container: var(--md-sys-color-error-container-dark);
--md-sys-color-on-error: var(--md-sys-color-on-error-dark);
--md-sys-color-on-error-container: var(
--md-sys-color-on-error-container-dark
);
--md-sys-color-background: var(--md-sys-color-background-dark);
--md-sys-color-on-background: var(--md-sys-color-on-background-dark);
--md-sys-color-surface: var(--md-sys-color-surface-dark);
--md-sys-color-on-surface: var(--md-sys-color-on-surface-dark);
--md-sys-color-surface-variant: var(--md-sys-color-surface-variant-dark);
--md-sys-color-on-surface-variant: var(
--md-sys-color-on-surface-variant-dark
);
--md-sys-color-outline: var(--md-sys-color-outline-dark);
--md-sys-color-inverse-on-surface: var(
--md-sys-color-inverse-on-surface-dark
);
--md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-dark);
--md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-dark);
--md-sys-color-shadow: var(--md-sys-color-shadow-dark);
--md-sys-color-surface-tint: var(--md-sys-color-surface-tint-dark);
--md-sys-color-surface-tint-color: var(
--md-sys-color-surface-tint-color-dark
);
}

49
src/theme/theme.light.css Normal file
View File

@@ -0,0 +1,49 @@
:root {
--md-sys-color-primary: var(--md-sys-color-primary-light);
--md-sys-color-on-primary: var(--md-sys-color-on-primary-light);
--md-sys-color-primary-container: var(--md-sys-color-primary-container-light);
--md-sys-color-on-primary-container: var(
--md-sys-color-on-primary-container-light
);
--md-sys-color-secondary: var(--md-sys-color-secondary-light);
--md-sys-color-on-secondary: var(--md-sys-color-on-secondary-light);
--md-sys-color-secondary-container: var(
--md-sys-color-secondary-container-light
);
--md-sys-color-on-secondary-container: var(
--md-sys-color-on-secondary-container-light
);
--md-sys-color-tertiary: var(--md-sys-color-tertiary-light);
--md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-light);
--md-sys-color-tertiary-container: var(
--md-sys-color-tertiary-container-light
);
--md-sys-color-on-tertiary-container: var(
--md-sys-color-on-tertiary-container-light
);
--md-sys-color-error: var(--md-sys-color-error-light);
--md-sys-color-error-container: var(--md-sys-color-error-container-light);
--md-sys-color-on-error: var(--md-sys-color-on-error-light);
--md-sys-color-on-error-container: var(
--md-sys-color-on-error-container-light
);
--md-sys-color-background: var(--md-sys-color-background-light);
--md-sys-color-on-background: var(--md-sys-color-on-background-light);
--md-sys-color-surface: var(--md-sys-color-surface-light);
--md-sys-color-on-surface: var(--md-sys-color-on-surface-light);
--md-sys-color-surface-variant: var(--md-sys-color-surface-variant-light);
--md-sys-color-on-surface-variant: var(
--md-sys-color-on-surface-variant-light
);
--md-sys-color-outline: var(--md-sys-color-outline-light);
--md-sys-color-inverse-on-surface: var(
--md-sys-color-inverse-on-surface-light
);
--md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-light);
--md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-light);
--md-sys-color-shadow: var(--md-sys-color-shadow-light);
--md-sys-color-surface-tint: var(--md-sys-color-surface-tint-light);
--md-sys-color-surface-tint-color: var(
--md-sys-color-surface-tint-color-light
);
}

270
src/theme/tokens.css Normal file
View File

@@ -0,0 +1,270 @@
:root {
--md-source: #4285f4;
/* primary */
--md-ref-palette-primary0: #000000;
--md-ref-palette-primary10: #001a41;
--md-ref-palette-primary20: #002e69;
--md-ref-palette-primary25: #00397e;
--md-ref-palette-primary30: #004494;
--md-ref-palette-primary35: #004faa;
--md-ref-palette-primary40: #005ac1;
--md-ref-palette-primary50: #2b74e2;
--md-ref-palette-primary60: #4d8efe;
--md-ref-palette-primary70: #80aaff;
--md-ref-palette-primary80: #adc6ff;
--md-ref-palette-primary90: #d8e2ff;
--md-ref-palette-primary95: #edf0ff;
--md-ref-palette-primary98: #f9f9ff;
--md-ref-palette-primary99: #fefbff;
--md-ref-palette-primary100: #ffffff;
/* secondary */
--md-ref-palette-secondary0: #000000;
--md-ref-palette-secondary10: #141b2c;
--md-ref-palette-secondary20: #293041;
--md-ref-palette-secondary25: #343b4d;
--md-ref-palette-secondary30: #3f4759;
--md-ref-palette-secondary35: #4b5265;
--md-ref-palette-secondary40: #575e71;
--md-ref-palette-secondary50: #6f778b;
--md-ref-palette-secondary60: #8991a5;
--md-ref-palette-secondary70: #a3abc0;
--md-ref-palette-secondary80: #bfc6dc;
--md-ref-palette-secondary90: #dbe2f9;
--md-ref-palette-secondary95: #edf0ff;
--md-ref-palette-secondary98: #f9f9ff;
--md-ref-palette-secondary99: #fefbff;
--md-ref-palette-secondary100: #ffffff;
/* tertiary */
--md-ref-palette-tertiary0: #000000;
--md-ref-palette-tertiary10: #29132d;
--md-ref-palette-tertiary20: #402843;
--md-ref-palette-tertiary25: #4c334f;
--md-ref-palette-tertiary30: #583e5b;
--md-ref-palette-tertiary35: #644967;
--md-ref-palette-tertiary40: #715573;
--md-ref-palette-tertiary50: #8b6d8d;
--md-ref-palette-tertiary60: #a687a8;
--md-ref-palette-tertiary70: #c2a1c3;
--md-ref-palette-tertiary80: #debcdf;
--md-ref-palette-tertiary90: #fbd7fc;
--md-ref-palette-tertiary95: #ffebfc;
--md-ref-palette-tertiary98: #fff7fa;
--md-ref-palette-tertiary99: #fffbff;
--md-ref-palette-tertiary100: #ffffff;
/* neutral */
--md-ref-palette-neutral0: #000000;
--md-ref-palette-neutral10: #1b1b1f;
--md-ref-palette-neutral20: #303033;
--md-ref-palette-neutral25: #3b3b3f;
--md-ref-palette-neutral30: #46464a;
--md-ref-palette-neutral35: #525256;
--md-ref-palette-neutral40: #5e5e62;
--md-ref-palette-neutral50: #77777a;
--md-ref-palette-neutral60: #919094;
--md-ref-palette-neutral70: #ababaf;
--md-ref-palette-neutral80: #c7c6ca;
--md-ref-palette-neutral90: #e3e2e6;
--md-ref-palette-neutral95: #f2f0f4;
--md-ref-palette-neutral98: #faf9fd;
--md-ref-palette-neutral99: #fefbff;
--md-ref-palette-neutral100: #ffffff;
/* neutral-variant */
--md-ref-palette-neutral-variant0: #000000;
--md-ref-palette-neutral-variant10: #191b22;
--md-ref-palette-neutral-variant20: #2e3038;
--md-ref-palette-neutral-variant25: #393b43;
--md-ref-palette-neutral-variant30: #44474f;
--md-ref-palette-neutral-variant35: #50525a;
--md-ref-palette-neutral-variant40: #5c5e66;
--md-ref-palette-neutral-variant50: #74777f;
--md-ref-palette-neutral-variant60: #8e9099;
--md-ref-palette-neutral-variant70: #a9abb4;
--md-ref-palette-neutral-variant80: #c4c6d0;
--md-ref-palette-neutral-variant90: #e1e2ec;
--md-ref-palette-neutral-variant95: #eff0fa;
--md-ref-palette-neutral-variant98: #f9f9ff;
--md-ref-palette-neutral-variant99: #fefbff;
--md-ref-palette-neutral-variant100: #ffffff;
/* error */
--md-ref-palette-error0: #000000;
--md-ref-palette-error10: #410002;
--md-ref-palette-error20: #690005;
--md-ref-palette-error25: #7e0007;
--md-ref-palette-error30: #93000a;
--md-ref-palette-error35: #a80710;
--md-ref-palette-error40: #ba1a1a;
--md-ref-palette-error50: #de3730;
--md-ref-palette-error60: #ff5449;
--md-ref-palette-error70: #ff897d;
--md-ref-palette-error80: #ffb4ab;
--md-ref-palette-error90: #ffdad6;
--md-ref-palette-error95: #ffedea;
--md-ref-palette-error98: #fff8f7;
--md-ref-palette-error99: #fffbff;
--md-ref-palette-error100: #ffffff;
/* light */
--md-sys-color-primary-light: #005ac1;
--md-sys-color-on-primary-light: #ffffff;
--md-sys-color-primary-container-light: #d8e2ff;
--md-sys-color-on-primary-container-light: #001a41;
--md-sys-color-secondary-light: #575e71;
--md-sys-color-on-secondary-light: #ffffff;
--md-sys-color-secondary-container-light: #dbe2f9;
--md-sys-color-on-secondary-container-light: #141b2c;
--md-sys-color-tertiary-light: #715573;
--md-sys-color-on-tertiary-light: #ffffff;
--md-sys-color-tertiary-container-light: #fbd7fc;
--md-sys-color-on-tertiary-container-light: #29132d;
--md-sys-color-error-light: #ba1a1a;
--md-sys-color-error-container-light: #ffdad6;
--md-sys-color-on-error-light: #ffffff;
--md-sys-color-on-error-container-light: #410002;
--md-sys-color-background-light: #fefbff;
--md-sys-color-on-background-light: #1b1b1f;
--md-sys-color-surface-light: #fefbff;
--md-sys-color-on-surface-light: #1b1b1f;
--md-sys-color-surface-variant-light: #e1e2ec;
--md-sys-color-on-surface-variant-light: #44474f;
--md-sys-color-outline-light: #74777f;
--md-sys-color-inverse-on-surface-light: #f2f0f4;
--md-sys-color-inverse-surface-light: #303033;
--md-sys-color-inverse-primary-light: #adc6ff;
--md-sys-color-shadow-light: #000000;
--md-sys-color-surface-tint-light: #005ac1;
--md-sys-color-surface-tint-color-light: #005ac1;
/* dark */
--md-sys-color-primary-dark: #adc6ff;
--md-sys-color-on-primary-dark: #002e69;
--md-sys-color-primary-container-dark: #004494;
--md-sys-color-on-primary-container-dark: #d8e2ff;
--md-sys-color-secondary-dark: #bfc6dc;
--md-sys-color-on-secondary-dark: #293041;
--md-sys-color-secondary-container-dark: #3f4759;
--md-sys-color-on-secondary-container-dark: #dbe2f9;
--md-sys-color-tertiary-dark: #debcdf;
--md-sys-color-on-tertiary-dark: #402843;
--md-sys-color-tertiary-container-dark: #583e5b;
--md-sys-color-on-tertiary-container-dark: #fbd7fc;
--md-sys-color-error-dark: #ffb4ab;
--md-sys-color-error-container-dark: #93000a;
--md-sys-color-on-error-dark: #690005;
--md-sys-color-on-error-container-dark: #ffdad6;
--md-sys-color-background-dark: #1b1b1f;
--md-sys-color-on-background-dark: #e3e2e6;
--md-sys-color-surface-dark: #1b1b1f;
--md-sys-color-on-surface-dark: #e3e2e6;
--md-sys-color-surface-variant-dark: #44474f;
--md-sys-color-on-surface-variant-dark: #c4c6d0;
--md-sys-color-outline-dark: #8e9099;
--md-sys-color-inverse-on-surface-dark: #1b1b1f;
--md-sys-color-inverse-surface-dark: #e3e2e6;
--md-sys-color-inverse-primary-dark: #005ac1;
--md-sys-color-shadow-dark: #000000;
--md-sys-color-surface-tint-dark: #adc6ff;
--md-sys-color-surface-tint-color-dark: #adc6ff;
/* label - small */
--md-sys-typescale-label-small-font-family-name: Roboto;
--md-sys-typescale-label-small-font-family-style: Medium;
--md-sys-typescale-label-small-font-weight: 500px;
--md-sys-typescale-label-small-font-size: 11px;
--md-sys-typescale-label-small-letter-spacing: 0.5px;
--md-sys-typescale-label-small-line-height: 16px;
/* label - medium */
--md-sys-typescale-label-medium-font-family-name: Roboto;
--md-sys-typescale-label-medium-font-family-style: Medium;
--md-sys-typescale-label-medium-font-weight: 500px;
--md-sys-typescale-label-medium-font-size: 12px;
--md-sys-typescale-label-medium-letter-spacing: 0.5px;
--md-sys-typescale-label-medium-line-height: 16px;
/* label - large */
--md-sys-typescale-label-large-font-family-name: Roboto;
--md-sys-typescale-label-large-font-family-style: Medium;
--md-sys-typescale-label-large-font-weight: 500px;
--md-sys-typescale-label-large-font-size: 14px;
--md-sys-typescale-label-large-letter-spacing: 0.1px;
--md-sys-typescale-label-large-line-height: 20px;
/* body - small */
--md-sys-typescale-body-small-font-family-name: Roboto;
--md-sys-typescale-body-small-font-family-style: Regular;
--md-sys-typescale-body-small-font-weight: 400px;
--md-sys-typescale-body-small-font-size: 12px;
--md-sys-typescale-body-small-letter-spacing: 0.4px;
--md-sys-typescale-body-small-line-height: 16px;
/* body - medium */
--md-sys-typescale-body-medium-font-family-name: Roboto;
--md-sys-typescale-body-medium-font-family-style: Regular;
--md-sys-typescale-body-medium-font-weight: 400px;
--md-sys-typescale-body-medium-font-size: 14px;
--md-sys-typescale-body-medium-letter-spacing: 0.25px;
--md-sys-typescale-body-medium-line-height: 20px;
/* body - large */
--md-sys-typescale-body-large-font-family-name: Roboto;
--md-sys-typescale-body-large-font-family-style: Regular;
--md-sys-typescale-body-large-font-weight: 400px;
--md-sys-typescale-body-large-font-size: 16px;
--md-sys-typescale-body-large-letter-spacing: 0.5px;
--md-sys-typescale-body-large-line-height: 24px;
/* headline - small */
--md-sys-typescale-headline-small-font-family-name: Roboto;
--md-sys-typescale-headline-small-font-family-style: Regular;
--md-sys-typescale-headline-small-font-weight: 400px;
--md-sys-typescale-headline-small-font-size: 24px;
--md-sys-typescale-headline-small-letter-spacing: 0px;
--md-sys-typescale-headline-small-line-height: 32px;
/* headline - medium */
--md-sys-typescale-headline-medium-font-family-name: Roboto;
--md-sys-typescale-headline-medium-font-family-style: Regular;
--md-sys-typescale-headline-medium-font-weight: 400px;
--md-sys-typescale-headline-medium-font-size: 28px;
--md-sys-typescale-headline-medium-letter-spacing: 0px;
--md-sys-typescale-headline-medium-line-height: 36px;
/* headline - large */
--md-sys-typescale-headline-large-font-family-name: Roboto;
--md-sys-typescale-headline-large-font-family-style: Regular;
--md-sys-typescale-headline-large-font-weight: 400px;
--md-sys-typescale-headline-large-font-size: 32px;
--md-sys-typescale-headline-large-letter-spacing: 0px;
--md-sys-typescale-headline-large-line-height: 40px;
/* display - small */
--md-sys-typescale-display-small-font-family-name: Roboto;
--md-sys-typescale-display-small-font-family-style: Regular;
--md-sys-typescale-display-small-font-weight: 400px;
--md-sys-typescale-display-small-font-size: 36px;
--md-sys-typescale-display-small-letter-spacing: 0px;
--md-sys-typescale-display-small-line-height: 44px;
/* display - medium */
--md-sys-typescale-display-medium-font-family-name: Roboto;
--md-sys-typescale-display-medium-font-family-style: Regular;
--md-sys-typescale-display-medium-font-weight: 400px;
--md-sys-typescale-display-medium-font-size: 45px;
--md-sys-typescale-display-medium-letter-spacing: 0px;
--md-sys-typescale-display-medium-line-height: 52px;
/* display - large */
--md-sys-typescale-display-large-font-family-name: Roboto;
--md-sys-typescale-display-large-font-family-style: Regular;
--md-sys-typescale-display-large-font-weight: 400px;
--md-sys-typescale-display-large-font-size: 57px;
--md-sys-typescale-display-large-letter-spacing: -0.25px;
--md-sys-typescale-display-large-line-height: 64px;
/* title - small */
--md-sys-typescale-title-small-font-family-name: Roboto;
--md-sys-typescale-title-small-font-family-style: Medium;
--md-sys-typescale-title-small-font-weight: 500px;
--md-sys-typescale-title-small-font-size: 14px;
--md-sys-typescale-title-small-letter-spacing: 0.1px;
--md-sys-typescale-title-small-line-height: 20px;
/* title - medium */
--md-sys-typescale-title-medium-font-family-name: Roboto;
--md-sys-typescale-title-medium-font-family-style: Medium;
--md-sys-typescale-title-medium-font-weight: 500px;
--md-sys-typescale-title-medium-font-size: 16px;
--md-sys-typescale-title-medium-letter-spacing: 0.15px;
--md-sys-typescale-title-medium-line-height: 24px;
/* title - large */
--md-sys-typescale-title-large-font-family-name: Roboto;
--md-sys-typescale-title-large-font-family-style: Regular;
--md-sys-typescale-title-large-font-weight: 400px;
--md-sys-typescale-title-large-font-size: 22px;
--md-sys-typescale-title-large-letter-spacing: 0px;
--md-sys-typescale-title-large-line-height: 28px;
}

View File

@@ -0,0 +1,150 @@
.label-small {
font-family: var(--md-sys-typescale-label-small-font-family-name);
font-style: var(--md-sys-typescale-label-small-font-family-style);
font-weight: var(--md-sys-typescale-label-small-font-weight);
font-size: var(--md-sys-typescale-label-small-font-size);
letter-spacing: var(--md-sys-typescale-label-small-tracking);
line-height: var(--md-sys-typescale-label-small-height);
text-transform: var(--md-sys-typescale-label-small-text-transform);
text-decoration: var(--md-sys-typescale-label-small-text-decoration);
}
.label-medium {
font-family: var(--md-sys-typescale-label-medium-font-family-name);
font-style: var(--md-sys-typescale-label-medium-font-family-style);
font-weight: var(--md-sys-typescale-label-medium-font-weight);
font-size: var(--md-sys-typescale-label-medium-font-size);
letter-spacing: var(--md-sys-typescale-label-medium-tracking);
line-height: var(--md-sys-typescale-label-medium-height);
text-transform: var(--md-sys-typescale-label-medium-text-transform);
text-decoration: var(--md-sys-typescale-label-medium-text-decoration);
}
.label-large {
font-family: var(--md-sys-typescale-label-large-font-family-name);
font-style: var(--md-sys-typescale-label-large-font-family-style);
font-weight: var(--md-sys-typescale-label-large-font-weight);
font-size: var(--md-sys-typescale-label-large-font-size);
letter-spacing: var(--md-sys-typescale-label-large-tracking);
line-height: var(--md-sys-typescale-label-large-height);
text-transform: var(--md-sys-typescale-label-large-text-transform);
text-decoration: var(--md-sys-typescale-label-large-text-decoration);
}
.body-small {
font-family: var(--md-sys-typescale-body-small-font-family-name);
font-style: var(--md-sys-typescale-body-small-font-family-style);
font-weight: var(--md-sys-typescale-body-small-font-weight);
font-size: var(--md-sys-typescale-body-small-font-size);
letter-spacing: var(--md-sys-typescale-body-small-tracking);
line-height: var(--md-sys-typescale-body-small-height);
text-transform: var(--md-sys-typescale-body-small-text-transform);
text-decoration: var(--md-sys-typescale-body-small-text-decoration);
}
.body-medium {
font-family: var(--md-sys-typescale-body-medium-font-family-name);
font-style: var(--md-sys-typescale-body-medium-font-family-style);
font-weight: var(--md-sys-typescale-body-medium-font-weight);
font-size: var(--md-sys-typescale-body-medium-font-size);
letter-spacing: var(--md-sys-typescale-body-medium-tracking);
line-height: var(--md-sys-typescale-body-medium-height);
text-transform: var(--md-sys-typescale-body-medium-text-transform);
text-decoration: var(--md-sys-typescale-body-medium-text-decoration);
}
.body-large {
font-family: var(--md-sys-typescale-body-large-font-family-name);
font-style: var(--md-sys-typescale-body-large-font-family-style);
font-weight: var(--md-sys-typescale-body-large-font-weight);
font-size: var(--md-sys-typescale-body-large-font-size);
letter-spacing: var(--md-sys-typescale-body-large-tracking);
line-height: var(--md-sys-typescale-body-large-height);
text-transform: var(--md-sys-typescale-body-large-text-transform);
text-decoration: var(--md-sys-typescale-body-large-text-decoration);
}
.headline-small {
font-family: var(--md-sys-typescale-headline-small-font-family-name);
font-style: var(--md-sys-typescale-headline-small-font-family-style);
font-weight: var(--md-sys-typescale-headline-small-font-weight);
font-size: var(--md-sys-typescale-headline-small-font-size);
letter-spacing: var(--md-sys-typescale-headline-small-tracking);
line-height: var(--md-sys-typescale-headline-small-height);
text-transform: var(--md-sys-typescale-headline-small-text-transform);
text-decoration: var(--md-sys-typescale-headline-small-text-decoration);
}
.headline-medium {
font-family: var(--md-sys-typescale-headline-medium-font-family-name);
font-style: var(--md-sys-typescale-headline-medium-font-family-style);
font-weight: var(--md-sys-typescale-headline-medium-font-weight);
font-size: var(--md-sys-typescale-headline-medium-font-size);
letter-spacing: var(--md-sys-typescale-headline-medium-tracking);
line-height: var(--md-sys-typescale-headline-medium-height);
text-transform: var(--md-sys-typescale-headline-medium-text-transform);
text-decoration: var(--md-sys-typescale-headline-medium-text-decoration);
}
.headline-large {
font-family: var(--md-sys-typescale-headline-large-font-family-name);
font-style: var(--md-sys-typescale-headline-large-font-family-style);
font-weight: var(--md-sys-typescale-headline-large-font-weight);
font-size: var(--md-sys-typescale-headline-large-font-size);
letter-spacing: var(--md-sys-typescale-headline-large-tracking);
line-height: var(--md-sys-typescale-headline-large-height);
text-transform: var(--md-sys-typescale-headline-large-text-transform);
text-decoration: var(--md-sys-typescale-headline-large-text-decoration);
}
.display-small {
font-family: var(--md-sys-typescale-display-small-font-family-name);
font-style: var(--md-sys-typescale-display-small-font-family-style);
font-weight: var(--md-sys-typescale-display-small-font-weight);
font-size: var(--md-sys-typescale-display-small-font-size);
letter-spacing: var(--md-sys-typescale-display-small-tracking);
line-height: var(--md-sys-typescale-display-small-height);
text-transform: var(--md-sys-typescale-display-small-text-transform);
text-decoration: var(--md-sys-typescale-display-small-text-decoration);
}
.display-medium {
font-family: var(--md-sys-typescale-display-medium-font-family-name);
font-style: var(--md-sys-typescale-display-medium-font-family-style);
font-weight: var(--md-sys-typescale-display-medium-font-weight);
font-size: var(--md-sys-typescale-display-medium-font-size);
letter-spacing: var(--md-sys-typescale-display-medium-tracking);
line-height: var(--md-sys-typescale-display-medium-height);
text-transform: var(--md-sys-typescale-display-medium-text-transform);
text-decoration: var(--md-sys-typescale-display-medium-text-decoration);
}
.display-large {
font-family: var(--md-sys-typescale-display-large-font-family-name);
font-style: var(--md-sys-typescale-display-large-font-family-style);
font-weight: var(--md-sys-typescale-display-large-font-weight);
font-size: var(--md-sys-typescale-display-large-font-size);
letter-spacing: var(--md-sys-typescale-display-large-tracking);
line-height: var(--md-sys-typescale-display-large-height);
text-transform: var(--md-sys-typescale-display-large-text-transform);
text-decoration: var(--md-sys-typescale-display-large-text-decoration);
}
.title-small {
font-family: var(--md-sys-typescale-title-small-font-family-name);
font-style: var(--md-sys-typescale-title-small-font-family-style);
font-weight: var(--md-sys-typescale-title-small-font-weight);
font-size: var(--md-sys-typescale-title-small-font-size);
letter-spacing: var(--md-sys-typescale-title-small-tracking);
line-height: var(--md-sys-typescale-title-small-height);
text-transform: var(--md-sys-typescale-title-small-text-transform);
text-decoration: var(--md-sys-typescale-title-small-text-decoration);
}
.title-medium {
font-family: var(--md-sys-typescale-title-medium-font-family-name);
font-style: var(--md-sys-typescale-title-medium-font-family-style);
font-weight: var(--md-sys-typescale-title-medium-font-weight);
font-size: var(--md-sys-typescale-title-medium-font-size);
letter-spacing: var(--md-sys-typescale-title-medium-tracking);
line-height: var(--md-sys-typescale-title-medium-height);
text-transform: var(--md-sys-typescale-title-medium-text-transform);
text-decoration: var(--md-sys-typescale-title-medium-text-decoration);
}
.title-large {
font-family: var(--md-sys-typescale-title-large-font-family-name);
font-style: var(--md-sys-typescale-title-large-font-family-style);
font-weight: var(--md-sys-typescale-title-large-font-weight);
font-size: var(--md-sys-typescale-title-large-font-size);
letter-spacing: var(--md-sys-typescale-title-large-tracking);
line-height: var(--md-sys-typescale-title-large-height);
text-transform: var(--md-sys-typescale-title-large-text-transform);
text-decoration: var(--md-sys-typescale-title-large-text-decoration);
}

View File

@@ -1,99 +0,0 @@
:root {
--primary: #666000;
--on-primary: #ffffff;
--primary-container: #efe750;
--on-primary-container: #1e1c00;
--secondary: #626042;
--on-secondary: #ffffff;
--secondary-container: #e9e4be;
--on-secondary-container: #1d1c05;
--tertiary: #3e6654;
--on-tertiary: #ffffff;
--tertiary-container: #c1ecd6;
--on-tertiary-container: #002115;
--error: #ba1b1b;
--error-container: #ffdad4;
--on-error: #ffffff;
--on-error-container: #410001;
--background: #fffcf3;
--on-background: #1c1c16;
--surface: #fffcf3;
--on-surface: #1c1c16;
--surface-variant: #e7e3d1;
--on-surface-variant: #49473a;
--outline: #797768;
--inverse-on-surface: #f4f0e7;
--inverse-surface: #31302b;
--overlay: rgba(0, 0, 0, 0.5);
--active: rgba(0, 0, 0, 0.1);
}
#chips {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.invisible {
display: none !important;
}
article {
max-width: 768rem;
margin: auto;
}
input[disabled] {
cursor: auto;
}
#file-icon,
#loader {
display: block;
font-size: 192rem;
width: 192rem;
margin: auto;
}
#loader {
height: 192rem;
}
.toast {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
}
@media (prefers-color-scheme: dark) {
:root {
--primary: #d2cb36;
--on-primary: #353200;
--primary-container: #4c4800;
--on-primary-container: #efe750;
--secondary: #ccc8a4;
--on-secondary: #333118;
--secondary-container: #4a482c;
--on-secondary-container: #e9e4be;
--tertiary: #a5d0ba;
--on-tertiary: #0d3728;
--tertiary-container: #274e3e;
--on-tertiary-container: #c1ecd6;
--error: #ffb4a9;
--error-container: #930006;
--on-error: #680003;
--on-error-container: #ffdad4;
--background: #1c1c16;
--on-background: #e6e2da;
--surface: #1c1c16;
--on-surface: #e6e2da;
--surface-variant: #49473a;
--on-surface-variant: #cac7b5;
--outline: #949181;
--inverse-on-surface: #1c1c16;
--inverse-surface: #e6e2da;
--overlay: rgba(0, 0, 0, 0.5);
--active: rgba(255, 255, 255, 0.2);
}
}

13
vite.config.js Normal file
View File

@@ -0,0 +1,13 @@
import { defineConfig } from "vite";
export default defineConfig({
build: {
rollupOptions: {
input: [
"index.html",
"sqlite-to-fdb/index.html",
"xml-to-fdb/index.html",
],
},
},
});

74
xml-to-fdb/index.html Normal file
View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/src/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>XML to FDB | FDB Converter</title>
<meta
name="description"
content="Convert XML database files used during the development of LEGO Universe to FDB files. The conversion takes place entirely client-side. Nothing is uploaded to a server."
/>
<meta name="color-scheme" content="light dark" />
</head>
<body class="surface on-surface-text body-large">
<div>
<h1 class="display-large">XML to FDB</h1>
<p class="title-large">
Convert XML database files used during the development of LEGO Universe
to FDB files.
</p>
</div>
<label>
<h2 class="headline-small">XML File</h2>
<div class="file-icon material-icons-outlined">upload_file</div>
<p>Drag and drop your XML file or click to select your XML file.</p>
<input
type="file"
accept=".xml"
data-input-extension="xml"
data-output-extension="fdb"
/>
<md-ripple></md-ripple>
</label>
<div>
<p>
The conversion takes place entirely client-side. Nothing is uploaded to
a server.
</p>
<p>
Based on
<a class="primary-text" href="https://assembly.lu-dev.net/">
Assembly RS</a
>. The source code of this website can be found
<a class="primary-text" href="https://github.com/IAmMajo/FDB-Converter">
here</a
>.
</p>
</div>
<md-navigation-bar>
<nav>
<a href="/">
<md-navigation-tab label="FDB to SQLite">
<span slot="inactiveIcon" class="material-icons-outlined">
circle
</span>
</md-navigation-tab>
</a>
<a href="/sqlite-to-fdb/">
<md-navigation-tab label="SQLite to FDB">
<span slot="inactiveIcon" class="material-icons-outlined">
square
</span>
</md-navigation-tab>
</a>
<a href="/xml-to-fdb/">
<md-navigation-tab label="XML to FDB" active>
<span slot="activeIcon" class="material-icons">hexagon</span>
</md-navigation-tab>
</a>
</nav>
</md-navigation-bar>
<script type="module" src="/src/main.js"></script>
</body>
</html>