Set up wasm generation (#42)
This commit is contained in:
parent
2d89355566
commit
2161f594bf
35
.github/workflows/deploy.yml
vendored
Normal file
35
.github/workflows/deploy.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: Deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
web:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build SvelteKit project
|
||||
run: npm run build
|
||||
|
||||
- name: Deploy Project Artifacts to Vercel
|
||||
run: npx vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
|
||||
env:
|
||||
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
||||
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||
35
.github/workflows/preview.yml
vendored
Normal file
35
.github/workflows/preview.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: Deploy
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
web:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build SvelteKit project
|
||||
run: npm run build
|
||||
|
||||
- name: Deploy Project Artifacts to Vercel
|
||||
run: npx vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
|
||||
env:
|
||||
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
||||
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||
@ -1,8 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
## Next
|
||||
- Switch to the fastnum crate's d128
|
||||
- Fix exp function
|
||||
- Create a [website interface](https://cpc.kasper.space)
|
||||
- Add wasm version
|
||||
- Switch to the `fastnum` crate's d128
|
||||
- Fix `exp` function
|
||||
|
||||
## 2.0.0 - 2025 May 30
|
||||
- Remove the `degrees` keyword which referred to `celcius` by default
|
||||
|
||||
157
Cargo.lock
generated
157
Cargo.lock
generated
@ -23,13 +23,39 @@ version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f781dba93de3a5ef6dc5b17c9958b208f6f3f021623b360fb605ea51ce443f10"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpc"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"fastnum",
|
||||
"js-sys",
|
||||
"regex",
|
||||
"unicode-segmentation",
|
||||
"wasm-bindgen",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -42,12 +68,52 @@ dependencies = [
|
||||
"bnum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
@ -77,8 +143,99 @@ version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-time"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
@ -18,9 +18,18 @@ categories = [
|
||||
"value-formatting",
|
||||
]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
fastnum = "0.2"
|
||||
unicode-segmentation = "1.12"
|
||||
web-time = "1.1.0"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
console_error_panic_hook = "0.1.7"
|
||||
wasm-bindgen = "0.2"
|
||||
js-sys = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
regex = "1.11"
|
||||
|
||||
@ -11,6 +11,10 @@ It also lets you mix units, so for example `1 km - 1m` results in `999 Meter`.
|
||||
|
||||
[List of all supported units](https://docs.rs/cpc/latest/cpc/units/enum.Unit.html)
|
||||
|
||||
## ## [Web Interface](https://cpc.kasper.space)
|
||||
|
||||
Try it out at [cpc.kasper.space](https://cpc.kasper.space)
|
||||
|
||||
## CLI Installation
|
||||
Install using `cargo`:
|
||||
```
|
||||
|
||||
17
src/lib.rs
17
src/lib.rs
@ -25,7 +25,7 @@
|
||||
use crate::units::Unit;
|
||||
use fastnum::{dec128 as d, D128};
|
||||
use std::fmt::{self, Display};
|
||||
use std::time::Instant;
|
||||
use web_time::Instant;
|
||||
|
||||
/// Turns an [`AstNode`](parser::AstNode) into a [`Number`]
|
||||
pub mod evaluator;
|
||||
@ -284,6 +284,21 @@ pub fn eval(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[wasm_bindgen]
|
||||
pub fn wasm_eval(expression: &str) -> String {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let result = eval(expression, true, false);
|
||||
match result {
|
||||
Ok(result) => result.to_string(),
|
||||
Err(e) => format!("Error: {e}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
23
web/.gitignore
vendored
Normal file
23
web/.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
node_modules
|
||||
|
||||
# Output
|
||||
.output
|
||||
.vercel
|
||||
.netlify
|
||||
.wrangler
|
||||
/.svelte-kit
|
||||
/build
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
# Vite
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
38
web/README.md
Normal file
38
web/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# sv
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npx sv create
|
||||
|
||||
# create a new project in my-app
|
||||
npx sv create my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
||||
5970
web/package-lock.json
generated
Normal file
5970
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
web/package.json
Normal file
31
web/package.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build-wasm": "npx wasm-pack build --target bundler",
|
||||
"dev": "npm run build-wasm && vite dev",
|
||||
"build": "npm run build-wasm && vite build",
|
||||
"preview": "vite preview",
|
||||
"prepare": "svelte-kit sync || echo ''",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-vercel": "^5.7.2",
|
||||
"@sveltejs/kit": "^2.16.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
"cpc": "file:../pkg",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"typescript": "^5.0.0",
|
||||
"vercel": "^42.2.0",
|
||||
"vite": "^6.2.6",
|
||||
"vite-plugin-top-level-await": "^1.5.0",
|
||||
"vite-plugin-wasm": "^3.4.1",
|
||||
"wasm-pack": "^0.13.1"
|
||||
}
|
||||
}
|
||||
1
web/src/app.css
Normal file
1
web/src/app.css
Normal file
@ -0,0 +1 @@
|
||||
@import 'tailwindcss';
|
||||
13
web/src/app.d.ts
vendored
Normal file
13
web/src/app.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// See https://svelte.dev/docs/kit/types#app.d.ts
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
19
web/src/app.html
Normal file
19
web/src/app.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<link rel="icon" type="image/png" href="%sveltekit.assets%/favicon-96x96.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/favicon.svg" />
|
||||
<link rel="shortcut icon" href="%sveltekit.assets%/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="%sveltekit.assets%/apple-touch-icon.png" />
|
||||
<meta name="apple-mobile-web-app-title" content="cpc" />
|
||||
<link rel="manifest" href="%sveltekit.assets%/site.webmanifest" />
|
||||
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
39
web/src/lib/helpers.ts
Normal file
39
web/src/lib/helpers.ts
Normal file
@ -0,0 +1,39 @@
|
||||
type ShortcutOptions = {
|
||||
shift?: boolean
|
||||
alt?: boolean
|
||||
cmd_or_ctrl?: boolean
|
||||
}
|
||||
const is_mac = navigator.userAgent.indexOf('Mac') !== -1
|
||||
|
||||
function check_modifiers(e: KeyboardEvent | MouseEvent, options: ShortcutOptions) {
|
||||
const target = {
|
||||
shift: options.shift || false,
|
||||
alt: options.alt || false,
|
||||
ctrl: (!is_mac && options.cmd_or_ctrl) || false,
|
||||
meta: (is_mac && options.cmd_or_ctrl) || false,
|
||||
}
|
||||
|
||||
const pressed = {
|
||||
shift: !!e.shiftKey,
|
||||
alt: !!e.altKey,
|
||||
ctrl: !!e.ctrlKey,
|
||||
meta: !!e.metaKey,
|
||||
}
|
||||
|
||||
const ignore_ctrl = is_mac && e instanceof MouseEvent
|
||||
|
||||
return (
|
||||
pressed.shift === target.shift &&
|
||||
pressed.alt === target.alt &&
|
||||
(pressed.ctrl === target.ctrl || ignore_ctrl) &&
|
||||
pressed.meta === target.meta
|
||||
)
|
||||
}
|
||||
|
||||
export function check_shortcut(e: KeyboardEvent, key: string, options: ShortcutOptions = {}) {
|
||||
if (e.key.toUpperCase() !== key.toUpperCase()) return false
|
||||
return check_modifiers(e, options)
|
||||
}
|
||||
export function check_mouse_shortcut(e: MouseEvent, options: ShortcutOptions = {}) {
|
||||
return check_modifiers(e, options)
|
||||
}
|
||||
7
web/src/routes/+layout.svelte
Normal file
7
web/src/routes/+layout.svelte
Normal file
@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import "../app.css";
|
||||
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
{@render children()}
|
||||
2
web/src/routes/+layout.ts
Normal file
2
web/src/routes/+layout.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export const ssr = false;
|
||||
export const prerender = true;
|
||||
99
web/src/routes/+page.svelte
Normal file
99
web/src/routes/+page.svelte
Normal file
@ -0,0 +1,99 @@
|
||||
<script lang="ts">
|
||||
import { check_shortcut } from "$lib/helpers";
|
||||
import { wasm_eval } from "cpc";
|
||||
import { flip } from "svelte/animate";
|
||||
import { fly } from "svelte/transition";
|
||||
|
||||
let input = $state("");
|
||||
let output = $derived.by(() => {
|
||||
try {
|
||||
if (input.trim().length === 0) {
|
||||
return "";
|
||||
}
|
||||
return wasm_eval(input);
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
let saved_queries: { id: number; in: string; out: string }[] = $state([]);
|
||||
</script>
|
||||
|
||||
<main class="w-full px-4 lg:px-8 text-base lg:text-lg">
|
||||
<nav class="flex items-center justify-between py-4 lg:py-6">
|
||||
<h1 class="text-3xl font-bold text-amber-600 dark:text-amber-400">
|
||||
cpc
|
||||
</h1>
|
||||
<a
|
||||
href="https://github.com/probablykasper/cpc"
|
||||
aria-label="GitHub repository"
|
||||
class="svelte-1ugh5mt"
|
||||
>
|
||||
<svg
|
||||
height="24"
|
||||
viewBox="-2 -2 28 28"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="svelte-8lfi33 svelte-1ugh5mt"
|
||||
><path
|
||||
d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
class="svelte-8lfi33"
|
||||
></path></svg
|
||||
>
|
||||
</a>
|
||||
</nav>
|
||||
<input
|
||||
type="text"
|
||||
class="border border-gray-500/50 w-full rounded-lg px-3 py-2 outline-none"
|
||||
bind:value={input}
|
||||
onkeydown={(e) => {
|
||||
if (check_shortcut(e, "Enter")) {
|
||||
const input = e.currentTarget.value;
|
||||
let out;
|
||||
try {
|
||||
out = wasm_eval(e.currentTarget.value);
|
||||
} catch (e) {
|
||||
out = "";
|
||||
}
|
||||
console.log(out);
|
||||
saved_queries.unshift({
|
||||
id: saved_queries.length,
|
||||
in: input,
|
||||
out,
|
||||
});
|
||||
e.currentTarget.value = "";
|
||||
output = "";
|
||||
}
|
||||
}}
|
||||
placeholder="10km/h * 1 decade in light seconds"
|
||||
/>
|
||||
<div class="pt-1 leading-tight">
|
||||
<div class="px-3 py-2">
|
||||
{output}<span class="invisible select-none">x</span>
|
||||
</div>
|
||||
{#each saved_queries as query (query.id)}
|
||||
<div
|
||||
class="px-3 py-2"
|
||||
in:fly={{ y: -10, duration: 150 }}
|
||||
animate:flip={{ duration: 150 }}
|
||||
>
|
||||
<p class="opacity-65 text-base leading-tight">{query.in}</p>
|
||||
<p>{query.out}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style lang="postcss">
|
||||
@reference "../app.css";
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:global(body) {
|
||||
@apply bg-black text-white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
web/static/apple-touch-icon.png
Normal file
BIN
web/static/apple-touch-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
web/static/favicon-96x96.png
Normal file
BIN
web/static/favicon-96x96.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
web/static/favicon.ico
Normal file
BIN
web/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
3
web/static/favicon.svg
Normal file
3
web/static/favicon.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 16 KiB |
21
web/static/site.webmanifest
Normal file
21
web/static/site.webmanifest
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "cpc",
|
||||
"short_name": "cpc",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/web-app-manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/web-app-manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"theme_color": "#faff00",
|
||||
"background_color": "#000000",
|
||||
"display": "standalone"
|
||||
}
|
||||
BIN
web/static/web-app-manifest-192x192.png
Normal file
BIN
web/static/web-app-manifest-192x192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
BIN
web/static/web-app-manifest-512x512.png
Normal file
BIN
web/static/web-app-manifest-512x512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
9
web/svelte.config.js
Normal file
9
web/svelte.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
import adapter from '@sveltejs/adapter-vercel';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
const config = {
|
||||
preprocess: vitePreprocess(),
|
||||
kit: { adapter: adapter() }
|
||||
};
|
||||
|
||||
export default config;
|
||||
19
web/tsconfig.json
Normal file
19
web/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
||||
14
web/vite.config.ts
Normal file
14
web/vite.config.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
import wasm from 'vite-plugin-wasm';
|
||||
import top_level_await from 'vite-plugin-top-level-await';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss(), sveltekit(), wasm(), top_level_await()],
|
||||
server: {
|
||||
fs: {
|
||||
allow: ['../pkg']
|
||||
}
|
||||
}
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user