mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-10 16:51:59 +03:00
Write plain text, get live results per line. English + Russian, units, live currency rates with crypto, percents, dates and timezones, bitwise ops, variables and sheet totals. Tauri 2 + TypeScript engine + CodeMirror 6; daily backups and a deleted-sheets bin. Inspired by Numi for macOS (numi.app); built from scratch for Windows.
135 lines
7 KiB
TypeScript
135 lines
7 KiB
TypeScript
// Conversion ratios. Base units per dimension: length=meter, area=m²,
|
|
// volume=m³, weight=gram, time=second, angle=radian, data=bit,
|
|
// temperature=kelvin (ratio+offset).
|
|
import { Decimal, Dimension } from "./types";
|
|
|
|
export interface UnitData {
|
|
id: string;
|
|
/** vocab category that holds `<id>.variants` / `<id>.format` */
|
|
category: string;
|
|
dimension: Dimension;
|
|
ratio: string;
|
|
offset?: string;
|
|
/** which prefix family applies (si => mm/cm/km..., data => kilo..yotta + kibi..yobi) */
|
|
prefixes?: "si" | "data";
|
|
/** fallback format if vocab has none */
|
|
format?: string;
|
|
}
|
|
|
|
const IN = 0.0254;
|
|
|
|
export const UNIT_DATA: UnitData[] = [
|
|
// Length (base: meter)
|
|
{ id: "meter", category: "Length", dimension: "length", ratio: "1", prefixes: "si" },
|
|
{ id: "inch", category: "Length", dimension: "length", ratio: String(IN) },
|
|
{ id: "mile", category: "Length", dimension: "length", ratio: "1609.344" },
|
|
{ id: "foot", category: "Length", dimension: "length", ratio: "0.3048" },
|
|
{ id: "yard", category: "Length", dimension: "length", ratio: "0.9144" },
|
|
{ id: "point", category: "Length", dimension: "length", ratio: String(IN / 72) },
|
|
{ id: "cable", category: "Length", dimension: "length", ratio: "185.2" },
|
|
{ id: "league", category: "Length", dimension: "length", ratio: "4828.032" },
|
|
{ id: "furlong", category: "Length", dimension: "length", ratio: "201.168" },
|
|
{ id: "nautical_mile", category: "Length", dimension: "length", ratio: "1852" },
|
|
{ id: "chain", category: "Length", dimension: "length", ratio: "20.1168" },
|
|
// CSS lengths (reference: 96px = 1in, 1em = 16px)
|
|
{ id: "pixel", category: "Css", dimension: "length", ratio: String(IN / 96) },
|
|
{ id: "em", category: "Css", dimension: "length", ratio: String(IN / 6) },
|
|
|
|
// Area (base: m²)
|
|
{ id: "are", category: "Area", dimension: "area", ratio: "100" },
|
|
{ id: "hectare", category: "Area", dimension: "area", ratio: "10000" },
|
|
{ id: "acre", category: "Area", dimension: "area", ratio: "4046.8564224" },
|
|
{ id: "ping", category: "Area", dimension: "area", ratio: "3.30579" },
|
|
|
|
// Volume (base: m³)
|
|
{ id: "litre", category: "Volume", dimension: "volume", ratio: "0.001", prefixes: "si" },
|
|
{ id: "cup", category: "Volume", dimension: "volume", ratio: "0.0002365882365" },
|
|
{ id: "tablespoon", category: "Volume", dimension: "volume", ratio: "0.0000147867647825" },
|
|
{ id: "teaspoon", category: "Volume", dimension: "volume", ratio: "0.00000492892159375" },
|
|
{ id: "quart", category: "Volume", dimension: "volume", ratio: "0.000946352946" },
|
|
{ id: "pint", category: "Volume", dimension: "volume", ratio: "0.000473176473" },
|
|
{ id: "gallon", category: "Volume", dimension: "volume", ratio: "0.003785411784" },
|
|
{ id: "cbinch", category: "Volume", dimension: "volume", ratio: "0.000016387064", format: "in³" },
|
|
{ id: "cbcm", category: "Volume", dimension: "volume", ratio: "0.000001", format: "cm³" },
|
|
|
|
// Weight (base: gram)
|
|
{ id: "gram", category: "Weight", dimension: "weight", ratio: "1", prefixes: "si" },
|
|
{ id: "tonne", category: "Weight", dimension: "weight", ratio: "1000000" },
|
|
{ id: "stone", category: "Weight", dimension: "weight", ratio: "6350.29318" },
|
|
{ id: "carat", category: "Weight", dimension: "weight", ratio: "0.2" },
|
|
{ id: "pound", category: "Weight", dimension: "weight", ratio: "453.59237" },
|
|
{ id: "centner", category: "Weight", dimension: "weight", ratio: "100000" },
|
|
{ id: "ounce", category: "Weight", dimension: "weight", ratio: "28.349523125" },
|
|
|
|
// Temperature (base: kelvin); base = value*ratio + offset
|
|
{ id: "celsius", category: "Temperature", dimension: "temperature", ratio: "1", offset: "273.15" },
|
|
{ id: "fahrenheit", category: "Temperature", dimension: "temperature", ratio: String(5 / 9), offset: String((459.67 * 5) / 9) },
|
|
{ id: "kelvin", category: "Temperature", dimension: "temperature", ratio: "1" },
|
|
|
|
// Time (base: second). Month = 30 days, year = 365 days here;
|
|
// date arithmetic uses real calendar months separately.
|
|
{ id: "second", category: "Time", dimension: "time", ratio: "1", prefixes: "si" },
|
|
{ id: "minute", category: "Time", dimension: "time", ratio: "60" },
|
|
{ id: "hour", category: "Time", dimension: "time", ratio: "3600" },
|
|
{ id: "day", category: "Time", dimension: "time", ratio: "86400" },
|
|
{ id: "week", category: "Time", dimension: "time", ratio: "604800" },
|
|
{ id: "month", category: "Time", dimension: "time", ratio: "2592000" },
|
|
{ id: "year", category: "Time", dimension: "time", ratio: "31536000" },
|
|
|
|
// Angle (base: radian)
|
|
{ id: "radian", category: "Angle", dimension: "angle", ratio: "1" },
|
|
{ id: "degree", category: "Angle", dimension: "angle", ratio: String(Math.PI / 180) },
|
|
|
|
// Data (base: bit)
|
|
{ id: "bit", category: "Data", dimension: "data", ratio: "1", prefixes: "data" },
|
|
{ id: "byte", category: "Data", dimension: "data", ratio: "8", prefixes: "data" },
|
|
];
|
|
|
|
export interface PrefixData {
|
|
id: string; // vocab id in SIPrefixes/IECPrefixes
|
|
category: "SIPrefixes" | "IECPrefixes";
|
|
mult: string;
|
|
}
|
|
|
|
export const SI_PREFIXES: PrefixData[] = [
|
|
{ id: "yotta", category: "SIPrefixes", mult: "1e24" },
|
|
{ id: "zetta", category: "SIPrefixes", mult: "1e21" },
|
|
{ id: "exa", category: "SIPrefixes", mult: "1e18" },
|
|
{ id: "peta", category: "SIPrefixes", mult: "1e15" },
|
|
{ id: "tera", category: "SIPrefixes", mult: "1e12" },
|
|
{ id: "giga", category: "SIPrefixes", mult: "1e9" },
|
|
{ id: "mega", category: "SIPrefixes", mult: "1e6" },
|
|
{ id: "kilo", category: "SIPrefixes", mult: "1e3" },
|
|
{ id: "hecto", category: "SIPrefixes", mult: "1e2" },
|
|
{ id: "deca", category: "SIPrefixes", mult: "1e1" },
|
|
{ id: "deci", category: "SIPrefixes", mult: "1e-1" },
|
|
{ id: "centi", category: "SIPrefixes", mult: "1e-2" },
|
|
{ id: "milli", category: "SIPrefixes", mult: "1e-3" },
|
|
{ id: "micro", category: "SIPrefixes", mult: "1e-6" },
|
|
{ id: "nano", category: "SIPrefixes", mult: "1e-9" },
|
|
{ id: "pico", category: "SIPrefixes", mult: "1e-12" },
|
|
{ id: "femto", category: "SIPrefixes", mult: "1e-15" },
|
|
{ id: "atto", category: "SIPrefixes", mult: "1e-18" },
|
|
{ id: "zepto", category: "SIPrefixes", mult: "1e-21" },
|
|
{ id: "yocto", category: "SIPrefixes", mult: "1e-24" },
|
|
];
|
|
|
|
/** Prefixes ≥ kilo, applied to data units (no millibits). */
|
|
export const DATA_SI_PREFIXES = SI_PREFIXES.filter((p) => new Decimal(p.mult).gte(1000));
|
|
|
|
export const IEC_PREFIXES: PrefixData[] = [
|
|
{ id: "kibi", category: "IECPrefixes", mult: "1024" },
|
|
{ id: "mebi", category: "IECPrefixes", mult: String(2 ** 20) },
|
|
{ id: "gibi", category: "IECPrefixes", mult: String(2 ** 30) },
|
|
{ id: "tebi", category: "IECPrefixes", mult: String(2 ** 40) },
|
|
{ id: "pebi", category: "IECPrefixes", mult: new Decimal(2).pow(50).toString() },
|
|
{ id: "exbi", category: "IECPrefixes", mult: new Decimal(2).pow(60).toString() },
|
|
{ id: "zebi", category: "IECPrefixes", mult: new Decimal(2).pow(70).toString() },
|
|
{ id: "yobi", category: "IECPrefixes", mult: new Decimal(2).pow(80).toString() },
|
|
];
|
|
|
|
export const SCALE_DATA: Record<string, string> = {
|
|
thousand: "1e3",
|
|
million: "1e6",
|
|
billion: "1e9",
|
|
};
|