dsh-unitverse 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.cjs ADDED
@@ -0,0 +1,408 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name2 in all)
8
+ __defProp(target, name2, { get: all[name2], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ALIAS_INDEX: () => ALIAS_INDEX,
24
+ CATEGORIES: () => CATEGORIES,
25
+ CATEGORY_ORDER: () => CATEGORY_ORDER,
26
+ DELTA_MARKERS: () => DELTA_MARKERS,
27
+ UNITS: () => UNITS,
28
+ UnitConversionError: () => UnitConversionError,
29
+ apply: () => apply,
30
+ buildAliasIndex: () => buildAliasIndex,
31
+ convert: () => convert,
32
+ convertDetailed: () => convertDetailed,
33
+ convertRaw: () => convertRaw,
34
+ findUnit: () => findUnit,
35
+ inject: () => inject,
36
+ name: () => name,
37
+ normalizeUnit: () => normalizeUnit,
38
+ parseRequest: () => parseRequest,
39
+ resolveUnit: () => resolveUnit,
40
+ roundSignificant: () => roundSignificant,
41
+ stripDeltaMarker: () => stripDeltaMarker,
42
+ unitsByCategory: () => unitsByCategory
43
+ });
44
+ module.exports = __toCommonJS(index_exports);
45
+ var import_dsh_tools = require("@deepseek-ai/dsh-tools");
46
+
47
+ // src/units.ts
48
+ var CATEGORY_ORDER = [
49
+ "length",
50
+ "area",
51
+ "volume",
52
+ "time",
53
+ "angle",
54
+ "speed",
55
+ "temperature",
56
+ "pressure",
57
+ "energy",
58
+ "power"
59
+ ];
60
+ var CATEGORIES = {
61
+ length: { id: "length", labelZh: "\u957F\u5EA6", labelEn: "Length", baseSymbol: "m" },
62
+ area: { id: "area", labelZh: "\u9762\u79EF", labelEn: "Area", baseSymbol: "m\xB2" },
63
+ volume: { id: "volume", labelZh: "\u4F53\u79EF", labelEn: "Volume", baseSymbol: "m\xB3" },
64
+ time: { id: "time", labelZh: "\u65F6\u95F4", labelEn: "Time", baseSymbol: "s" },
65
+ angle: { id: "angle", labelZh: "\u89D2\u5EA6", labelEn: "Angle", baseSymbol: "rad" },
66
+ speed: { id: "speed", labelZh: "\u901F\u5EA6", labelEn: "Speed", baseSymbol: "m/s" },
67
+ temperature: { id: "temperature", labelZh: "\u6E29\u5EA6", labelEn: "Temperature", baseSymbol: "K" },
68
+ pressure: { id: "pressure", labelZh: "\u538B\u529B", labelEn: "Pressure", baseSymbol: "Pa" },
69
+ energy: { id: "energy", labelZh: "\u70ED\u91CF/\u80FD\u91CF", labelEn: "Energy/Heat", baseSymbol: "J" },
70
+ power: { id: "power", labelZh: "\u529F\u7387", labelEn: "Power", baseSymbol: "W" }
71
+ };
72
+ var DELTA_MARKERS = ["\u0394", "delta", "diff"];
73
+ var UNITS = [
74
+ // ---------------------------------------------------------------- length
75
+ { id: "nm", category: "length", symbol: "nm", nameZh: "\u7EB3\u7C73", nameEn: "nanometer", aliases: ["nm", "nanometer", "nanometers", "\u7EB3\u7C73"], factor: 1e-9 },
76
+ { id: "um", category: "length", symbol: "\u03BCm", nameZh: "\u5FAE\u7C73", nameEn: "micrometer", aliases: ["um", "\u03BCm", "\xB5m", "micrometer", "micrometers", "micron", "microns", "\u5FAE\u7C73"], factor: 1e-6 },
77
+ { id: "mm", category: "length", symbol: "mm", nameZh: "\u6BEB\u7C73", nameEn: "millimeter", aliases: ["mm", "millimeter", "millimeters", "millimetre", "millimetres", "\u6BEB\u7C73"], factor: 1e-3 },
78
+ { id: "cm", category: "length", symbol: "cm", nameZh: "\u5398\u7C73", nameEn: "centimeter", aliases: ["cm", "centimeter", "centimeters", "centimetre", "centimetres", "\u5398\u7C73", "\u516C\u5206"], factor: 0.01 },
79
+ { id: "m", category: "length", symbol: "m", nameZh: "\u7C73", nameEn: "meter", aliases: ["m", "meter", "meters", "metre", "metres", "\u7C73", "\u516C\u5C3A"], factor: 1 },
80
+ { id: "km", category: "length", symbol: "km", nameZh: "\u5343\u7C73", nameEn: "kilometer", aliases: ["km", "kilometer", "kilometers", "kilometre", "kilometres", "\u5343\u7C73", "\u516C\u91CC"], factor: 1e3 },
81
+ { id: "in", category: "length", symbol: "in", nameZh: "\u82F1\u5BF8", nameEn: "inch", aliases: ["in", "inch", "inches", "\u82F1\u5BF8", "\u540B"], factor: 0.0254 },
82
+ { id: "ft", category: "length", symbol: "ft", nameZh: "\u82F1\u5C3A", nameEn: "foot", aliases: ["ft", "foot", "feet", "\u82F1\u5C3A"], factor: 0.3048 },
83
+ { id: "yd", category: "length", symbol: "yd", nameZh: "\u7801", nameEn: "yard", aliases: ["yd", "yard", "yards", "\u7801"], factor: 0.9144 },
84
+ { id: "mi", category: "length", symbol: "mi", nameZh: "\u82F1\u91CC", nameEn: "mile", aliases: ["mi", "mile", "miles", "\u82F1\u91CC"], factor: 1609.344 },
85
+ { id: "nmi", category: "length", symbol: "nmi", nameZh: "\u6D77\u91CC", nameEn: "nautical mile", aliases: ["nmi", "nmile", "nautical mile", "nautical miles", "\u6D77\u91CC"], factor: 1852 },
86
+ { id: "li", category: "length", symbol: "\u91CC", nameZh: "\u91CC", nameEn: "li (Chinese mile)", aliases: ["li", "\u91CC", "\u5E02\u91CC", "\u534E\u91CC"], factor: 500 },
87
+ { id: "chi", category: "length", symbol: "\u5C3A", nameZh: "\u5C3A", nameEn: "chi (Chinese foot)", aliases: ["chi", "\u5C3A", "\u5E02\u5C3A"], factor: 1 / 3 },
88
+ // ------------------------------------------------------------------ area
89
+ { id: "mm2", category: "area", symbol: "mm\xB2", nameZh: "\u5E73\u65B9\u6BEB\u7C73", nameEn: "square millimeter", aliases: ["mm2", "mm\xB2", "square millimeter", "square millimeters", "\u5E73\u65B9\u6BEB\u7C73"], factor: 1e-6 },
90
+ { id: "cm2", category: "area", symbol: "cm\xB2", nameZh: "\u5E73\u65B9\u5398\u7C73", nameEn: "square centimeter", aliases: ["cm2", "cm\xB2", "square centimeter", "square centimeters", "\u5E73\u65B9\u5398\u7C73"], factor: 1e-4 },
91
+ { id: "m2", category: "area", symbol: "m\xB2", nameZh: "\u5E73\u65B9\u7C73", nameEn: "square meter", aliases: ["m2", "m\xB2", "square meter", "square meters", "square metre", "square metres", "\u5E73\u65B9\u7C73", "\u5E73\u7C73"], factor: 1 },
92
+ { id: "km2", category: "area", symbol: "km\xB2", nameZh: "\u5E73\u65B9\u5343\u7C73", nameEn: "square kilometer", aliases: ["km2", "km\xB2", "square kilometer", "square kilometers", "\u5E73\u65B9\u5343\u7C73", "\u5E73\u65B9\u516C\u91CC"], factor: 1e6 },
93
+ { id: "ha", category: "area", symbol: "ha", nameZh: "\u516C\u9877", nameEn: "hectare", aliases: ["ha", "hectare", "hectares", "\u516C\u9877"], factor: 1e4 },
94
+ { id: "mu", category: "area", symbol: "\u4EA9", nameZh: "\u4EA9", nameEn: "mu (Chinese acre)", aliases: ["mu", "\u4EA9", "\u5E02\u4EA9"], factor: 2e3 / 3 },
95
+ { id: "in2", category: "area", symbol: "in\xB2", nameZh: "\u5E73\u65B9\u82F1\u5BF8", nameEn: "square inch", aliases: ["in2", "in\xB2", "square inch", "square inches", "\u5E73\u65B9\u82F1\u5BF8"], factor: 0.0254 ** 2 },
96
+ { id: "ft2", category: "area", symbol: "ft\xB2", nameZh: "\u5E73\u65B9\u82F1\u5C3A", nameEn: "square foot", aliases: ["ft2", "ft\xB2", "square foot", "square feet", "\u5E73\u65B9\u82F1\u5C3A"], factor: 0.3048 ** 2 },
97
+ { id: "yd2", category: "area", symbol: "yd\xB2", nameZh: "\u5E73\u65B9\u7801", nameEn: "square yard", aliases: ["yd2", "yd\xB2", "square yard", "square yards", "\u5E73\u65B9\u7801"], factor: 0.9144 ** 2 },
98
+ { id: "acre", category: "area", symbol: "acre", nameZh: "\u82F1\u4EA9", nameEn: "acre", aliases: ["acre", "acres", "\u82F1\u4EA9"], factor: 4046.8564224 },
99
+ { id: "mi2", category: "area", symbol: "mi\xB2", nameZh: "\u5E73\u65B9\u82F1\u91CC", nameEn: "square mile", aliases: ["mi2", "mi\xB2", "square mile", "square miles", "\u5E73\u65B9\u82F1\u91CC"], factor: 1609.344 ** 2 },
100
+ // ---------------------------------------------------------------- volume
101
+ { id: "ml", category: "volume", symbol: "mL", nameZh: "\u6BEB\u5347", nameEn: "milliliter", aliases: ["ml", "mL", "milliliter", "milliliters", "millilitre", "millilitres", "\u6BEB\u5347"], factor: 1e-6 },
102
+ { id: "l", category: "volume", symbol: "L", nameZh: "\u5347", nameEn: "liter", aliases: ["l", "L", "liter", "liters", "litre", "litres", "\u5347", "\u516C\u5347"], factor: 1e-3 },
103
+ { id: "m3", category: "volume", symbol: "m\xB3", nameZh: "\u7ACB\u65B9\u7C73", nameEn: "cubic meter", aliases: ["m3", "m\xB3", "cubic meter", "cubic meters", "cubic metre", "cubic metres", "\u7ACB\u65B9\u7C73", "\u65B9"], factor: 1 },
104
+ { id: "cm3", category: "volume", symbol: "cm\xB3", nameZh: "\u7ACB\u65B9\u5398\u7C73", nameEn: "cubic centimeter", aliases: ["cm3", "cm\xB3", "cc", "cubic centimeter", "cubic centimeters", "\u7ACB\u65B9\u5398\u7C73"], factor: 1e-6 },
105
+ { id: "in3", category: "volume", symbol: "in\xB3", nameZh: "\u7ACB\u65B9\u82F1\u5BF8", nameEn: "cubic inch", aliases: ["in3", "in\xB3", "cubic inch", "cubic inches", "\u7ACB\u65B9\u82F1\u5BF8"], factor: 0.0254 ** 3 },
106
+ { id: "ft3", category: "volume", symbol: "ft\xB3", nameZh: "\u7ACB\u65B9\u82F1\u5C3A", nameEn: "cubic foot", aliases: ["ft3", "ft\xB3", "cubic foot", "cubic feet", "\u7ACB\u65B9\u82F1\u5C3A"], factor: 0.3048 ** 3 },
107
+ { id: "yd3", category: "volume", symbol: "yd\xB3", nameZh: "\u7ACB\u65B9\u7801", nameEn: "cubic yard", aliases: ["yd3", "yd\xB3", "cubic yard", "cubic yards", "\u7ACB\u65B9\u7801"], factor: 0.9144 ** 3 },
108
+ { id: "gal_us", category: "volume", symbol: "gal (US)", nameZh: "\u7F8E\u5236\u52A0\u4ED1", nameEn: "US gallon", aliases: ["gal", "gallon", "gallons", "us gal", "us gallon", "us gallons", "\u7F8E\u5236\u52A0\u4ED1", "\u7F8E\u52A0\u4ED1", "\u52A0\u4ED1"], factor: 0.003785411784 },
109
+ { id: "gal_uk", category: "volume", symbol: "gal (UK)", nameZh: "\u82F1\u5236\u52A0\u4ED1", nameEn: "imperial gallon", aliases: ["imp gal", "uk gal", "imperial gallon", "imperial gallons", "british gallon", "\u82F1\u5236\u52A0\u4ED1", "\u82F1\u52A0\u4ED1"], factor: 454609e-8 },
110
+ { id: "qt_us", category: "volume", symbol: "qt (US)", nameZh: "\u7F8E\u5236\u5938\u8131", nameEn: "US quart", aliases: ["qt", "quart", "quarts", "us quart", "\u7F8E\u5236\u5938\u8131", "\u5938\u8131"], factor: 0.003785411784 / 4 },
111
+ { id: "bbl", category: "volume", symbol: "bbl", nameZh: "\u6876\uFF08\u77F3\u6CB9\uFF09", nameEn: "oil barrel", aliases: ["bbl", "barrel", "oil barrel", "petroleum barrel", "\u6876"], factor: 0.158987294928 },
112
+ // ------------------------------------------------------------------ time
113
+ { id: "ms", category: "time", symbol: "ms", nameZh: "\u6BEB\u79D2", nameEn: "millisecond", aliases: ["ms", "millisecond", "milliseconds", "\u6BEB\u79D2"], factor: 1e-3 },
114
+ { id: "s", category: "time", symbol: "s", nameZh: "\u79D2", nameEn: "second", aliases: ["s", "sec", "secs", "second", "seconds", "\u79D2"], factor: 1 },
115
+ { id: "min", category: "time", symbol: "min", nameZh: "\u5206\u949F", nameEn: "minute", aliases: ["min", "mins", "minute", "minutes", "\u5206\u949F"], factor: 60 },
116
+ { id: "h", category: "time", symbol: "h", nameZh: "\u5C0F\u65F6", nameEn: "hour", aliases: ["h", "hr", "hrs", "hour", "hours", "\u5C0F\u65F6", "\u65F6"], factor: 3600 },
117
+ { id: "d", category: "time", symbol: "d", nameZh: "\u5929", nameEn: "day", aliases: ["d", "day", "days", "\u5929", "\u65E5"], factor: 86400 },
118
+ { id: "wk", category: "time", symbol: "wk", nameZh: "\u5468", nameEn: "week", aliases: ["wk", "week", "weeks", "\u5468", "\u661F\u671F"], factor: 7 * 86400 },
119
+ { id: "mo", category: "time", symbol: "mo", nameZh: "\u6708", nameEn: "month (mean Julian)", aliases: ["mo", "month", "months", "\u6708"], factor: 365.25 / 12 * 86400 },
120
+ { id: "yr", category: "time", symbol: "yr", nameZh: "\u5E74", nameEn: "year (Julian)", aliases: ["y", "yr", "year", "years", "\u5E74"], factor: 365.25 * 86400 },
121
+ // ----------------------------------------------------------------- angle
122
+ { id: "rad", category: "angle", symbol: "rad", nameZh: "\u5F27\u5EA6", nameEn: "radian", aliases: ["rad", "radian", "radians", "\u5F27\u5EA6"], factor: 1 },
123
+ { id: "deg", category: "angle", symbol: "\xB0", nameZh: "\u5EA6", nameEn: "degree", aliases: ["deg", "degree", "degrees", "\xB0", "\u5EA6", "\u89D2\u5EA6"], factor: Math.PI / 180 },
124
+ { id: "grad", category: "angle", symbol: "grad", nameZh: "\u767E\u5206\u5EA6", nameEn: "gradian", aliases: ["grad", "gradian", "gradians", "gon", "\u767E\u5206\u5EA6"], factor: Math.PI / 200 },
125
+ { id: "arcmin", category: "angle", symbol: "\u2032", nameZh: "\u89D2\u5206", nameEn: "arcminute", aliases: ["arcmin", "arcminute", "arcminutes", "\u89D2\u5206", "\u2032"], factor: Math.PI / 10800 },
126
+ { id: "arcsec", category: "angle", symbol: "\u2033", nameZh: "\u89D2\u79D2", nameEn: "arcsecond", aliases: ["arcsec", "arcsecond", "arcseconds", "\u89D2\u79D2", "\u2033"], factor: Math.PI / 648e3 },
127
+ { id: "turn", category: "angle", symbol: "turn", nameZh: "\u5708", nameEn: "turn", aliases: ["turn", "turns", "rev", "revolution", "revolutions", "\u5708", "\u8F6C"], factor: 2 * Math.PI },
128
+ // ----------------------------------------------------------------- speed
129
+ { id: "m_s", category: "speed", symbol: "m/s", nameZh: "\u7C73\u6BCF\u79D2", nameEn: "meter per second", aliases: ["m/s", "mps", "meter per second", "meters per second", "metre per second", "metres per second", "\u7C73\u6BCF\u79D2", "\u7C73/\u79D2"], factor: 1 },
130
+ { id: "km_h", category: "speed", symbol: "km/h", nameZh: "\u5343\u7C73\u6BCF\u5C0F\u65F6", nameEn: "kilometer per hour", aliases: ["km/h", "kmh", "kmph", "kph", "kilometer per hour", "kilometers per hour", "kilometre per hour", "\u5343\u7C73\u6BCF\u5C0F\u65F6", "\u516C\u91CC\u6BCF\u5C0F\u65F6", "\u5343\u7C73/\u5C0F\u65F6", "\u516C\u91CC/\u5C0F\u65F6"], factor: 1 / 3.6 },
131
+ { id: "mph", category: "speed", symbol: "mph", nameZh: "\u82F1\u91CC\u6BCF\u5C0F\u65F6", nameEn: "mile per hour", aliases: ["mph", "mi/h", "mile per hour", "miles per hour", "\u82F1\u91CC\u6BCF\u5C0F\u65F6"], factor: 0.44704 },
132
+ { id: "kn", category: "speed", symbol: "kn", nameZh: "\u8282", nameEn: "knot", aliases: ["kn", "kt", "knot", "knots", "\u8282"], factor: 1852 / 3600 },
133
+ { id: "ft_s", category: "speed", symbol: "ft/s", nameZh: "\u82F1\u5C3A\u6BCF\u79D2", nameEn: "foot per second", aliases: ["ft/s", "fps", "foot per second", "feet per second", "\u82F1\u5C3A\u6BCF\u79D2"], factor: 0.3048 },
134
+ // ----------------------------------------------------------- temperature
135
+ { id: "celsius", category: "temperature", symbol: "\xB0C", nameZh: "\u6444\u6C0F\u5EA6", nameEn: "degree Celsius", aliases: ["c", "\xB0c", "\u2103", "celsius", "\u6444\u6C0F\u5EA6"], a: 1, b: 273.15 },
136
+ { id: "fahrenheit", category: "temperature", symbol: "\xB0F", nameZh: "\u534E\u6C0F\u5EA6", nameEn: "degree Fahrenheit", aliases: ["f", "\xB0f", "\u2109", "fahrenheit", "\u534E\u6C0F\u5EA6"], a: 5 / 9, b: 459.67 * (5 / 9) },
137
+ { id: "kelvin", category: "temperature", symbol: "K", nameZh: "\u5F00\u5C14\u6587", nameEn: "kelvin", aliases: ["k", "kelvin", "\u5F00\u5C14\u6587", "\u5F00"], a: 1, b: 0 },
138
+ { id: "rankine", category: "temperature", symbol: "\xB0R", nameZh: "\u5170\u6C0F\u5EA6", nameEn: "degree Rankine", aliases: ["r", "\xB0r", "rankine", "\u5170\u6C0F\u5EA6"], a: 5 / 9, b: 0 },
139
+ // -------------------------------------------------------------- pressure
140
+ { id: "pa", category: "pressure", symbol: "Pa", nameZh: "\u5E15\u65AF\u5361", nameEn: "pascal", aliases: ["pa", "pascal", "pascals", "\u5E15", "\u5E15\u65AF\u5361"], factor: 1 },
141
+ { id: "kpa", category: "pressure", symbol: "kPa", nameZh: "\u5343\u5E15", nameEn: "kilopascal", aliases: ["kpa", "kilopascal", "kilopascals", "\u5343\u5E15"], factor: 1e3 },
142
+ { id: "mpa", category: "pressure", symbol: "MPa", nameZh: "\u5146\u5E15", nameEn: "megapascal", aliases: ["mpa", "megapascal", "megapascals", "\u5146\u5E15"], factor: 1e6 },
143
+ { id: "hpa", category: "pressure", symbol: "hPa", nameZh: "\u767E\u5E15", nameEn: "hectopascal", aliases: ["hpa", "hectopascal", "hectopascals", "\u767E\u5E15"], factor: 100 },
144
+ { id: "bar", category: "pressure", symbol: "bar", nameZh: "\u5DF4", nameEn: "bar", aliases: ["bar", "bars", "\u5DF4"], factor: 1e5 },
145
+ { id: "atm", category: "pressure", symbol: "atm", nameZh: "\u6807\u51C6\u5927\u6C14\u538B", nameEn: "atmosphere", aliases: ["atm", "atmosphere", "atmospheres", "\u6807\u51C6\u5927\u6C14\u538B", "\u5927\u6C14\u538B"], factor: 101325 },
146
+ { id: "psi", category: "pressure", symbol: "psi", nameZh: "\u78C5\u6BCF\u5E73\u65B9\u82F1\u5BF8", nameEn: "pound per square inch", aliases: ["psi", "pound per square inch", "pounds per square inch", "\u78C5\u6BCF\u5E73\u65B9\u82F1\u5BF8"], factor: 6894.757293168361 },
147
+ { id: "torr", category: "pressure", symbol: "Torr", nameZh: "\u6258", nameEn: "torr", aliases: ["torr", "\u6258"], factor: 101325 / 760 },
148
+ { id: "mmhg", category: "pressure", symbol: "mmHg", nameZh: "\u6BEB\u7C73\u6C5E\u67F1", nameEn: "millimeter of mercury", aliases: ["mmhg", "millimeter of mercury", "millimeters of mercury", "\u6BEB\u7C73\u6C5E\u67F1"], factor: 133.322387415 },
149
+ { id: "inhg", category: "pressure", symbol: "inHg", nameZh: "\u82F1\u5BF8\u6C5E\u67F1", nameEn: "inch of mercury", aliases: ["inhg", "inch of mercury", "inches of mercury", "\u82F1\u5BF8\u6C5E\u67F1"], factor: 25.4 * 133.322387415 },
150
+ // ---------------------------------------------------------------- energy
151
+ { id: "j", category: "energy", symbol: "J", nameZh: "\u7126\u8033", nameEn: "joule", aliases: ["j", "joule", "joules", "\u7126\u8033", "\u7126"], factor: 1 },
152
+ { id: "kj", category: "energy", symbol: "kJ", nameZh: "\u5343\u7126", nameEn: "kilojoule", aliases: ["kj", "kilojoule", "kilojoules", "\u5343\u7126"], factor: 1e3 },
153
+ { id: "mj", category: "energy", symbol: "MJ", nameZh: "\u5146\u7126", nameEn: "megajoule", aliases: ["mj", "megajoule", "megajoules", "\u5146\u7126"], factor: 1e6 },
154
+ { id: "cal", category: "energy", symbol: "cal", nameZh: "\u5361\u8DEF\u91CC", nameEn: "calorie (thermochemical)", aliases: ["cal", "calorie", "calories", "\u5361\u8DEF\u91CC", "\u5361"], factor: 4.184 },
155
+ { id: "kcal", category: "energy", symbol: "kcal", nameZh: "\u5343\u5361", nameEn: "kilocalorie", aliases: ["kcal", "kilocalorie", "kilocalories", "\u5927\u5361", "\u5343\u5361"], factor: 4184 },
156
+ { id: "wh", category: "energy", symbol: "Wh", nameZh: "\u74E6\u65F6", nameEn: "watt-hour", aliases: ["wh", "watt hour", "watt hours", "\u74E6\u65F6"], factor: 3600 },
157
+ { id: "kwh", category: "energy", symbol: "kWh", nameZh: "\u5343\u74E6\u65F6", nameEn: "kilowatt-hour", aliases: ["kwh", "kilowatt hour", "kilowatt hours", "\u5343\u74E6\u65F6"], factor: 36e5 },
158
+ { id: "btu", category: "energy", symbol: "BTU", nameZh: "\u82F1\u70ED\u5355\u4F4D", nameEn: "British thermal unit", aliases: ["btu", "btus", "british thermal unit", "british thermal units", "\u82F1\u70ED\u5355\u4F4D"], factor: 1055.05585262 },
159
+ // ----------------------------------------------------------------- power
160
+ { id: "w", category: "power", symbol: "W", nameZh: "\u74E6", nameEn: "watt", aliases: ["w", "watt", "watts", "\u74E6", "\u74E6\u7279"], factor: 1 },
161
+ { id: "kw", category: "power", symbol: "kW", nameZh: "\u5343\u74E6", nameEn: "kilowatt", aliases: ["kw", "kilowatt", "kilowatts", "\u5343\u74E6"], factor: 1e3 },
162
+ { id: "mw", category: "power", symbol: "MW", nameZh: "\u5146\u74E6", nameEn: "megawatt", aliases: ["mw", "megawatt", "megawatts", "\u5146\u74E6"], factor: 1e6 },
163
+ { id: "gw", category: "power", symbol: "GW", nameZh: "\u5409\u74E6", nameEn: "gigawatt", aliases: ["gw", "gigawatt", "gigawatts", "\u5409\u74E6"], factor: 1e9 },
164
+ { id: "hp", category: "power", symbol: "hp", nameZh: "\u82F1\u5236\u9A6C\u529B", nameEn: "horsepower (mechanical)", aliases: ["hp", "horsepower", "mechanical horsepower", "\u82F1\u5236\u9A6C\u529B"], factor: 745.6998715822702 },
165
+ { id: "ps", category: "power", symbol: "PS", nameZh: "\u516C\u5236\u9A6C\u529B", nameEn: "metric horsepower", aliases: ["ps", "metric horsepower", "pferdest\xE4rke", "\u516C\u5236\u9A6C\u529B", "\u7C73\u5236\u9A6C\u529B", "\u5339"], factor: 735.49875 }
166
+ ];
167
+ function normalizeUnit(raw) {
168
+ return raw.trim().toLowerCase().replace(/\u00b2/g, "2").replace(/\u00b3/g, "3").replace(/\u03bc|\u00b5/g, "u").replace(/[℃]/g, "\xB0c").replace(/[℉]/g, "\xB0f").replace(/\s+/g, "");
169
+ }
170
+ function buildAliasIndex(units = UNITS) {
171
+ const map = /* @__PURE__ */ new Map();
172
+ const conflicts = /* @__PURE__ */ new Map();
173
+ for (const unit of units) {
174
+ const seen = /* @__PURE__ */ new Set();
175
+ const keys = [...unit.aliases, unit.id, unit.symbol, unit.nameZh, unit.nameEn];
176
+ for (const raw of keys) {
177
+ const key = normalizeUnit(raw);
178
+ if (!key || seen.has(key)) continue;
179
+ seen.add(key);
180
+ const existing = map.get(key);
181
+ if (existing) {
182
+ if (existing.id === unit.id) continue;
183
+ const list = conflicts.get(key) ?? [existing];
184
+ if (!list.includes(unit)) list.push(unit);
185
+ conflicts.set(key, list);
186
+ continue;
187
+ }
188
+ map.set(key, unit);
189
+ }
190
+ }
191
+ return { map, conflicts };
192
+ }
193
+ var ALIAS_INDEX = buildAliasIndex();
194
+ function findUnit(token) {
195
+ const key = normalizeUnit(token);
196
+ if (!key) return void 0;
197
+ return ALIAS_INDEX.map.get(key);
198
+ }
199
+ function unitsByCategory(category) {
200
+ return UNITS.filter((u) => u.category === category);
201
+ }
202
+ function stripDeltaMarker(token) {
203
+ const t = token.trim();
204
+ for (const marker of DELTA_MARKERS) {
205
+ if (t.toLowerCase().startsWith(marker.toLowerCase())) {
206
+ const base = t.slice(marker.length).trim();
207
+ return { base, delta: true };
208
+ }
209
+ }
210
+ return { base: t, delta: false };
211
+ }
212
+
213
+ // src/convert.ts
214
+ var UnitConversionError = class extends Error {
215
+ /** Machine-readable kind: `unknown-unit` | `category-mismatch` | `bad-value` | `mixed-delta` | `unsupported`. */
216
+ kind;
217
+ /** The offending raw token for `unknown-unit` errors. */
218
+ token;
219
+ constructor(kind, message, token) {
220
+ super(message);
221
+ this.name = "UnitConversionError";
222
+ this.kind = kind;
223
+ if (token !== void 0) this.token = token;
224
+ }
225
+ };
226
+ function displayNameFor(def, rawToken) {
227
+ const trimmed = rawToken.trim();
228
+ if (/[\u4e00-\u9fff]/.test(trimmed)) return trimmed;
229
+ return def.symbol;
230
+ }
231
+ function resolveUnit(token) {
232
+ const { base, delta } = stripDeltaMarker(token);
233
+ const def = findUnit(base);
234
+ if (def === void 0) {
235
+ throw new UnitConversionError(
236
+ "unknown-unit",
237
+ `unknown unit "${base}": it is not a recognized length/area/volume/time/angle/speed/temperature/pressure/energy/power unit. `,
238
+ base
239
+ );
240
+ }
241
+ if (delta && def.category !== "temperature") {
242
+ throw new UnitConversionError(
243
+ "mixed-delta",
244
+ `"${token}": the \u0394/delta marker only applies to temperature units.`,
245
+ token
246
+ );
247
+ }
248
+ return { def, delta, canonical: displayNameFor(def, base) };
249
+ }
250
+ function assertFiniteValue(value) {
251
+ if (typeof value !== "number" || !Number.isFinite(value)) {
252
+ throw new UnitConversionError("bad-value", `value must be a finite number, got ${JSON.stringify(value)}`);
253
+ }
254
+ }
255
+ function parseRequest(value, from, to) {
256
+ assertFiniteValue(value);
257
+ const fromResolved = resolveUnit(from);
258
+ const toResolved = resolveUnit(to);
259
+ if (fromResolved.def.category !== toResolved.def.category) {
260
+ throw new UnitConversionError(
261
+ "category-mismatch",
262
+ `cannot convert ${from} (${CATEGORIES[fromResolved.def.category].labelZh}) to ${to} (${CATEGORIES[toResolved.def.category].labelZh}): units must belong to the same category.`
263
+ );
264
+ }
265
+ if (fromResolved.delta !== toResolved.delta) {
266
+ throw new UnitConversionError(
267
+ "mixed-delta",
268
+ `cannot mix absolute and \u0394 temperature units: use ${fromResolved.delta ? "\u0394" : ""}${from} and ${toResolved.delta ? "\u0394" : ""}${to} consistently.`
269
+ );
270
+ }
271
+ return { value, from: fromResolved, to: toResolved };
272
+ }
273
+ function roundSignificant(value, digits = 10) {
274
+ if (!Number.isFinite(value)) return value;
275
+ if (value === 0) return 0;
276
+ if (!Number.isFinite(digits) || digits <= 0) digits = 10;
277
+ const clamped = Math.min(15, Math.max(1, Math.floor(digits)));
278
+ const rounded = Number(value.toPrecision(clamped));
279
+ return rounded === 0 ? 0 : rounded;
280
+ }
281
+ function convertRaw(value, from, to) {
282
+ const { def: f } = from;
283
+ const { def: t } = to;
284
+ if (f.category === "temperature") {
285
+ const fA = f.a;
286
+ const fB = f.b;
287
+ const tA = t.a;
288
+ const tB = t.b;
289
+ if (from.delta || to.delta) {
290
+ return value * fA / tA;
291
+ }
292
+ return (value * fA + fB - tB) / tA;
293
+ }
294
+ const fFactor = f.factor;
295
+ const tFactor = t.factor;
296
+ return value * fFactor / tFactor;
297
+ }
298
+ function convert(value, from, to, options = {}) {
299
+ const req = parseRequest(value, from, to);
300
+ const raw = convertRaw(req.value, req.from, req.to);
301
+ const sig = options.significantDigits ?? 10;
302
+ return roundSignificant(raw, sig);
303
+ }
304
+ function convertDetailed(value, from, to, options = {}) {
305
+ const req = parseRequest(value, from, to);
306
+ const raw = convertRaw(req.value, req.from, req.to);
307
+ const sig = options.significantDigits ?? 10;
308
+ const result = roundSignificant(raw, sig);
309
+ const category = req.from.def.category;
310
+ const meta = CATEGORIES[category];
311
+ const fromName = req.from.canonical;
312
+ const toName = req.to.canonical;
313
+ const summary = `${value} ${fromName} = ${result} ${toName} (${meta.labelZh})`;
314
+ return {
315
+ value,
316
+ from: fromName,
317
+ to: toName,
318
+ result,
319
+ category,
320
+ categoryZh: meta.labelZh,
321
+ categoryEn: meta.labelEn,
322
+ fromInput: from,
323
+ toInput: to,
324
+ summary
325
+ };
326
+ }
327
+
328
+ // src/index.ts
329
+ var name = "unitverse";
330
+ var inject = ["tools"];
331
+ var CATEGORY_PREVIEWS = {
332
+ length: "m, km, cm, mm, um, nm, in, ft, yd, mi, nmi; \u7C73/\u5343\u7C73/\u82F1\u91CC/\u82F1\u5C3A/\u82F1\u5BF8\u2026",
333
+ area: "m2, km2, cm2, mm2, ha, acre, mu(\u4EA9); \u5E73\u65B9\u7C73/\u516C\u9877/\u4EA9/\u82F1\u4EA9\u2026",
334
+ volume: "m3, l, ml, cm3, in3, ft3, gal(US), gal(UK), bbl; \u7ACB\u65B9\u7C73/\u5347/\u6BEB\u5347/\u52A0\u4ED1\u2026",
335
+ time: "s, ms, min, h, d, wk, mo, yr; \u79D2/\u5206\u949F/\u5C0F\u65F6/\u5929/\u5468/\u6708/\u5E74\u2026",
336
+ angle: "rad, deg(\xB0), grad, arcmin, arcsec, turn; \u5F27\u5EA6/\u5EA6/\u89D2\u5206/\u89D2\u79D2\u2026",
337
+ speed: "m/s, km/h, mph, kn(knot), ft/s; \u7C73\u6BCF\u79D2/\u5343\u7C73\u6BCF\u5C0F\u65F6/\u8282\u2026",
338
+ temperature: "C(\xB0C), F(\xB0F), K, R(\xB0R); \u6444\u6C0F\u5EA6/\u534E\u6C0F\u5EA6/\u5F00\u5C14\u6587\u2026",
339
+ pressure: "pa, kpa, mpa, hpa, bar, atm, psi, torr, mmhg, inhg; \u5E15/\u5343\u5E15/\u5146\u5E15/\u5DF4/\u6807\u51C6\u5927\u6C14\u538B\u2026",
340
+ energy: "j, kj, mj, cal, kcal, wh, kwh, btu; \u7126\u8033/\u5343\u7126/\u5361\u8DEF\u91CC/\u5343\u5361/\u5343\u74E6\u65F6\u2026",
341
+ power: "w, kw, mw, gw, hp, ps; \u74E6/\u5343\u74E6/\u5146\u74E6/\u9A6C\u529B\u2026"
342
+ };
343
+ var DESCRIPTION = `Universal unit converter across ten categories: length, area, volume, time, angle, speed, temperature, pressure, energy/heat and power. Unit tokens are case-insensitive and accept English names, symbols and Chinese names \u2014 e.g. 'km'/'KM'/'kilometer'/'\u5343\u7C73'/'\u516C\u91CC' are all length units, and '\u516C\u91CC/\u5C0F\u65F6' or 'km/h' are speeds. Supported units: ${CATEGORY_ORDER.map((id) => `${CATEGORIES[id].labelZh}(${id}): ${CATEGORY_PREVIEWS[id]}`).join(" | ")}. Both units must belong to the same category. Temperature is converted as an absolute scale by default (e.g. 25 \xB0C -> \xB0F). For a temperature *difference*, prefix BOTH unit tokens with "\u0394" or "delta" (e.g. value=10, from='\u0394\xB0C', to='\u0394\xB0F' means a 10-degree-Celsius interval equals 18 \xB0F). You cannot mix an absolute and a \u0394 token in one call. Unknown units produce an error naming the token; retry with a listed spelling.`;
344
+ function apply(ctx) {
345
+ ctx.tools.register((0, import_dsh_tools.defineTool)({
346
+ name: "convert",
347
+ description: DESCRIPTION,
348
+ parameters: {
349
+ value: {
350
+ type: "number",
351
+ required: true,
352
+ description: "The numeric amount to convert (finite number)."
353
+ },
354
+ from: {
355
+ type: "string",
356
+ required: true,
357
+ description: "Source unit token: symbol, English or Chinese name (case-insensitive)."
358
+ },
359
+ to: {
360
+ type: "string",
361
+ required: true,
362
+ description: "Target unit token: symbol, English or Chinese name (case-insensitive)."
363
+ }
364
+ },
365
+ output: {
366
+ schema: {
367
+ type: "object",
368
+ additionalProperties: false,
369
+ properties: {
370
+ value: { type: "number", required: true, description: "Original input value." },
371
+ from: { type: "string", required: true, description: "Resolved source unit." },
372
+ to: { type: "string", required: true, description: "Resolved target unit." },
373
+ result: { type: "number", required: true, description: "Converted value." },
374
+ category: { type: "string", required: true, description: "Category id, e.g. length." },
375
+ categoryZh: { type: "string", required: true, description: "Category name in Chinese." },
376
+ summary: { type: "string", required: true, description: "Human-readable result line." }
377
+ }
378
+ },
379
+ render: (_args, value) => [{ type: "text", text: value.summary }]
380
+ },
381
+ async execute(args) {
382
+ return convertDetailed(args.value, args.from, args.to);
383
+ }
384
+ }));
385
+ }
386
+ // Annotate the CommonJS export names for ESM import in node:
387
+ 0 && (module.exports = {
388
+ ALIAS_INDEX,
389
+ CATEGORIES,
390
+ CATEGORY_ORDER,
391
+ DELTA_MARKERS,
392
+ UNITS,
393
+ UnitConversionError,
394
+ apply,
395
+ buildAliasIndex,
396
+ convert,
397
+ convertDetailed,
398
+ convertRaw,
399
+ findUnit,
400
+ inject,
401
+ name,
402
+ normalizeUnit,
403
+ parseRequest,
404
+ resolveUnit,
405
+ roundSignificant,
406
+ stripDeltaMarker,
407
+ unitsByCategory
408
+ });
@@ -0,0 +1,22 @@
1
+ import { Context } from '@deepseek-ai/cordis';
2
+ export { A as ALIAS_INDEX, a as AliasIndex, C as CATEGORIES, b as CATEGORY_ORDER, c as CategoryId, d as CategoryMeta, e as ConvertOptions, f as ConvertRequest, g as ConvertResult, D as DELTA_MARKERS, R as ResolvedUnit, U as UNITS, h as UnitConversionError, i as UnitDef, j as buildAliasIndex, k as convert, l as convertDetailed, m as convertRaw, n as findUnit, o as normalizeUnit, p as parseRequest, r as resolveUnit, q as roundSignificant, s as stripDeltaMarker, u as unitsByCategory } from './convert-D6txqQbW.cjs';
3
+
4
+ /**
5
+ * dsh-unitverse — DeepSeek Harness plugin entry.
6
+ *
7
+ * A Cordis plugin module (see docs/user/develop/basic) that registers one
8
+ * model-facing tool, `convert`, over the pure engine in `./convert`.
9
+ *
10
+ * ```yaml
11
+ * # cordis.patch.yml (bundle layer)
12
+ * - insert:
13
+ * - id: unitverse
14
+ * name: dsh-unitverse
15
+ * ```
16
+ */
17
+
18
+ declare const name = "unitverse";
19
+ declare const inject: readonly ["tools"];
20
+ declare function apply(ctx: Context): void;
21
+
22
+ export { apply, inject, name };
package/lib/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { Context } from '@deepseek-ai/cordis';
2
+ export { A as ALIAS_INDEX, a as AliasIndex, C as CATEGORIES, b as CATEGORY_ORDER, c as CategoryId, d as CategoryMeta, e as ConvertOptions, f as ConvertRequest, g as ConvertResult, D as DELTA_MARKERS, R as ResolvedUnit, U as UNITS, h as UnitConversionError, i as UnitDef, j as buildAliasIndex, k as convert, l as convertDetailed, m as convertRaw, n as findUnit, o as normalizeUnit, p as parseRequest, r as resolveUnit, q as roundSignificant, s as stripDeltaMarker, u as unitsByCategory } from './convert-D6txqQbW.js';
3
+
4
+ /**
5
+ * dsh-unitverse — DeepSeek Harness plugin entry.
6
+ *
7
+ * A Cordis plugin module (see docs/user/develop/basic) that registers one
8
+ * model-facing tool, `convert`, over the pure engine in `./convert`.
9
+ *
10
+ * ```yaml
11
+ * # cordis.patch.yml (bundle layer)
12
+ * - insert:
13
+ * - id: unitverse
14
+ * name: dsh-unitverse
15
+ * ```
16
+ */
17
+
18
+ declare const name = "unitverse";
19
+ declare const inject: readonly ["tools"];
20
+ declare function apply(ctx: Context): void;
21
+
22
+ export { apply, inject, name };
package/lib/index.js ADDED
@@ -0,0 +1,101 @@
1
+ import {
2
+ ALIAS_INDEX,
3
+ CATEGORIES,
4
+ CATEGORY_ORDER,
5
+ DELTA_MARKERS,
6
+ UNITS,
7
+ UnitConversionError,
8
+ buildAliasIndex,
9
+ convert,
10
+ convertDetailed,
11
+ convertRaw,
12
+ findUnit,
13
+ normalizeUnit,
14
+ parseRequest,
15
+ resolveUnit,
16
+ roundSignificant,
17
+ stripDeltaMarker,
18
+ unitsByCategory
19
+ } from "./chunk-KLTLDDLU.js";
20
+
21
+ // src/index.ts
22
+ import { defineTool } from "@deepseek-ai/dsh-tools";
23
+ var name = "unitverse";
24
+ var inject = ["tools"];
25
+ var CATEGORY_PREVIEWS = {
26
+ length: "m, km, cm, mm, um, nm, in, ft, yd, mi, nmi; \u7C73/\u5343\u7C73/\u82F1\u91CC/\u82F1\u5C3A/\u82F1\u5BF8\u2026",
27
+ area: "m2, km2, cm2, mm2, ha, acre, mu(\u4EA9); \u5E73\u65B9\u7C73/\u516C\u9877/\u4EA9/\u82F1\u4EA9\u2026",
28
+ volume: "m3, l, ml, cm3, in3, ft3, gal(US), gal(UK), bbl; \u7ACB\u65B9\u7C73/\u5347/\u6BEB\u5347/\u52A0\u4ED1\u2026",
29
+ time: "s, ms, min, h, d, wk, mo, yr; \u79D2/\u5206\u949F/\u5C0F\u65F6/\u5929/\u5468/\u6708/\u5E74\u2026",
30
+ angle: "rad, deg(\xB0), grad, arcmin, arcsec, turn; \u5F27\u5EA6/\u5EA6/\u89D2\u5206/\u89D2\u79D2\u2026",
31
+ speed: "m/s, km/h, mph, kn(knot), ft/s; \u7C73\u6BCF\u79D2/\u5343\u7C73\u6BCF\u5C0F\u65F6/\u8282\u2026",
32
+ temperature: "C(\xB0C), F(\xB0F), K, R(\xB0R); \u6444\u6C0F\u5EA6/\u534E\u6C0F\u5EA6/\u5F00\u5C14\u6587\u2026",
33
+ pressure: "pa, kpa, mpa, hpa, bar, atm, psi, torr, mmhg, inhg; \u5E15/\u5343\u5E15/\u5146\u5E15/\u5DF4/\u6807\u51C6\u5927\u6C14\u538B\u2026",
34
+ energy: "j, kj, mj, cal, kcal, wh, kwh, btu; \u7126\u8033/\u5343\u7126/\u5361\u8DEF\u91CC/\u5343\u5361/\u5343\u74E6\u65F6\u2026",
35
+ power: "w, kw, mw, gw, hp, ps; \u74E6/\u5343\u74E6/\u5146\u74E6/\u9A6C\u529B\u2026"
36
+ };
37
+ var DESCRIPTION = `Universal unit converter across ten categories: length, area, volume, time, angle, speed, temperature, pressure, energy/heat and power. Unit tokens are case-insensitive and accept English names, symbols and Chinese names \u2014 e.g. 'km'/'KM'/'kilometer'/'\u5343\u7C73'/'\u516C\u91CC' are all length units, and '\u516C\u91CC/\u5C0F\u65F6' or 'km/h' are speeds. Supported units: ${CATEGORY_ORDER.map((id) => `${CATEGORIES[id].labelZh}(${id}): ${CATEGORY_PREVIEWS[id]}`).join(" | ")}. Both units must belong to the same category. Temperature is converted as an absolute scale by default (e.g. 25 \xB0C -> \xB0F). For a temperature *difference*, prefix BOTH unit tokens with "\u0394" or "delta" (e.g. value=10, from='\u0394\xB0C', to='\u0394\xB0F' means a 10-degree-Celsius interval equals 18 \xB0F). You cannot mix an absolute and a \u0394 token in one call. Unknown units produce an error naming the token; retry with a listed spelling.`;
38
+ function apply(ctx) {
39
+ ctx.tools.register(defineTool({
40
+ name: "convert",
41
+ description: DESCRIPTION,
42
+ parameters: {
43
+ value: {
44
+ type: "number",
45
+ required: true,
46
+ description: "The numeric amount to convert (finite number)."
47
+ },
48
+ from: {
49
+ type: "string",
50
+ required: true,
51
+ description: "Source unit token: symbol, English or Chinese name (case-insensitive)."
52
+ },
53
+ to: {
54
+ type: "string",
55
+ required: true,
56
+ description: "Target unit token: symbol, English or Chinese name (case-insensitive)."
57
+ }
58
+ },
59
+ output: {
60
+ schema: {
61
+ type: "object",
62
+ additionalProperties: false,
63
+ properties: {
64
+ value: { type: "number", required: true, description: "Original input value." },
65
+ from: { type: "string", required: true, description: "Resolved source unit." },
66
+ to: { type: "string", required: true, description: "Resolved target unit." },
67
+ result: { type: "number", required: true, description: "Converted value." },
68
+ category: { type: "string", required: true, description: "Category id, e.g. length." },
69
+ categoryZh: { type: "string", required: true, description: "Category name in Chinese." },
70
+ summary: { type: "string", required: true, description: "Human-readable result line." }
71
+ }
72
+ },
73
+ render: (_args, value) => [{ type: "text", text: value.summary }]
74
+ },
75
+ async execute(args) {
76
+ return convertDetailed(args.value, args.from, args.to);
77
+ }
78
+ }));
79
+ }
80
+ export {
81
+ ALIAS_INDEX,
82
+ CATEGORIES,
83
+ CATEGORY_ORDER,
84
+ DELTA_MARKERS,
85
+ UNITS,
86
+ UnitConversionError,
87
+ apply,
88
+ buildAliasIndex,
89
+ convert,
90
+ convertDetailed,
91
+ convertRaw,
92
+ findUnit,
93
+ inject,
94
+ name,
95
+ normalizeUnit,
96
+ parseRequest,
97
+ resolveUnit,
98
+ roundSignificant,
99
+ stripDeltaMarker,
100
+ unitsByCategory
101
+ };