@mxtommy/kip 3.9.0-beta.3 → 3.9.0-beta.30

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.
Files changed (178) hide show
  1. package/.github/copilot-instructions.md +1 -1
  2. package/.github/instructions/angular.instructions.md +46 -0
  3. package/README.md +49 -12
  4. package/package.json +2 -4
  5. package/public/3rdpartylicenses.txt +77 -77
  6. package/public/app-help.component.css.map +7 -0
  7. package/public/app.component.css.map +7 -0
  8. package/public/assets/help-docs/configuration.md +4 -4
  9. package/public/assets/help-docs/dashboards.md +4 -2
  10. package/public/assets/svg/icons.svg +1 -1
  11. package/public/boolean-control-config.component.css.map +7 -0
  12. package/public/boolean-multicontrol-options.component.css.map +7 -0
  13. package/public/chunk-3VR3EA35.js +1022 -0
  14. package/public/chunk-3VR3EA35.js.map +1 -0
  15. package/public/chunk-63ILPRXC.js +2091 -0
  16. package/public/chunk-63ILPRXC.js.map +1 -0
  17. package/public/chunk-65ZWQBS6.js +3102 -0
  18. package/public/chunk-65ZWQBS6.js.map +1 -0
  19. package/public/chunk-ASPAEAIA.js +13727 -0
  20. package/public/chunk-ASPAEAIA.js.map +1 -0
  21. package/public/chunk-B3LKEWZP.js +4950 -0
  22. package/public/chunk-B3LKEWZP.js.map +1 -0
  23. package/public/chunk-BIBIW64D.js +16773 -0
  24. package/public/chunk-BIBIW64D.js.map +1 -0
  25. package/public/chunk-BM53SC5N.js +77 -0
  26. package/public/chunk-BM53SC5N.js.map +7 -0
  27. package/public/chunk-D7ILNFDM.js +3059 -0
  28. package/public/chunk-D7ILNFDM.js.map +1 -0
  29. package/public/chunk-E24UNLSJ.js +2228 -0
  30. package/public/chunk-E24UNLSJ.js.map +1 -0
  31. package/public/chunk-J42S2ELC.js +5927 -0
  32. package/public/chunk-J42S2ELC.js.map +1 -0
  33. package/public/chunk-KC22A6VH.js +17 -0
  34. package/public/chunk-KC22A6VH.js.map +7 -0
  35. package/public/chunk-L6IV3M2T.js +343 -0
  36. package/public/chunk-L6IV3M2T.js.map +7 -0
  37. package/public/chunk-MCEJWZB2.js +116 -0
  38. package/public/chunk-MCEJWZB2.js.map +1 -0
  39. package/public/chunk-NDTHJTFL.js +5237 -0
  40. package/public/chunk-NDTHJTFL.js.map +1 -0
  41. package/public/chunk-RUSRJ6XE.js +89 -0
  42. package/public/chunk-RUSRJ6XE.js.map +7 -0
  43. package/public/chunk-SDOP6T56.js +42377 -0
  44. package/public/chunk-SDOP6T56.js.map +1 -0
  45. package/public/chunk-U2DCSTRY.js +159 -0
  46. package/public/chunk-U2DCSTRY.js.map +7 -0
  47. package/public/chunk-UQYTD5AC.js +2723 -0
  48. package/public/chunk-UQYTD5AC.js.map +1 -0
  49. package/public/chunk-XSABJ5NZ.js +272 -0
  50. package/public/chunk-XSABJ5NZ.js.map +7 -0
  51. package/public/chunk-Y6N6O2IP.js +19852 -0
  52. package/public/chunk-Y6N6O2IP.js.map +1 -0
  53. package/public/chunk-YGJLBLOX.js +2708 -0
  54. package/public/chunk-YGJLBLOX.js.map +1 -0
  55. package/public/chunk-YJ3FT26N.js +4752 -0
  56. package/public/chunk-YJ3FT26N.js.map +1 -0
  57. package/public/chunk-YT33DHC3.js +591 -0
  58. package/public/chunk-YT33DHC3.js.map +7 -0
  59. package/public/chunk-YZXYVP72.js +4934 -0
  60. package/public/chunk-YZXYVP72.js.map +1 -0
  61. package/public/config.component.css.map +7 -0
  62. package/public/dashboard-scroller.component.css.map +7 -0
  63. package/public/dashboard.component.css.map +7 -0
  64. package/public/dashboards-editor.component.css.map +7 -0
  65. package/public/data-inspector-row.component.css.map +7 -0
  66. package/public/data-inspector.component.css.map +7 -0
  67. package/public/dataset-chart-options.component.css.map +7 -0
  68. package/public/datasets.component.css.map +7 -0
  69. package/public/dialog-confirmation.component.css.map +7 -0
  70. package/public/dialog-dashboard-page-editor.component.css.map +7 -0
  71. package/public/dialog-frame.component.css.map +7 -0
  72. package/public/dialog-name.component.css.map +7 -0
  73. package/public/display-chart-options.component.css.map +7 -0
  74. package/public/display.component.css.map +7 -0
  75. package/public/gauge-steel.component.css.map +7 -0
  76. package/public/home.component.css.map +7 -0
  77. package/public/index.html +19 -17
  78. package/public/main.js +36421 -0
  79. package/public/main.js.map +1 -0
  80. package/public/menu-actions.component.css.map +7 -0
  81. package/public/menu-notifications.component.css.map +7 -0
  82. package/public/minichart.component.css.map +7 -0
  83. package/public/modal-user-credential.component.css.map +7 -0
  84. package/public/modal-widget-config.component.css.map +7 -0
  85. package/public/notification-badge.component.css.map +7 -0
  86. package/public/page-header.component.css.map +7 -0
  87. package/public/path-control-config.component.css.map +7 -0
  88. package/public/paths-options.component.css.map +7 -0
  89. package/public/polyfills.js +4422 -0
  90. package/public/polyfills.js.map +1 -0
  91. package/public/select-autopilot.component.css.map +7 -0
  92. package/public/select-icon.component.css.map +7 -0
  93. package/public/settings.component.css.map +7 -0
  94. package/public/signalk.component.css.map +7 -0
  95. package/public/styles.css +1651 -0
  96. package/public/styles.css.map +7 -0
  97. package/public/svg-autopilot.component.css.map +7 -0
  98. package/public/svg-racesteer.component.css.map +7 -0
  99. package/public/svg-simple-linear-gauge.component.css.map +7 -0
  100. package/public/svg-windsteer.component.css.map +7 -0
  101. package/public/tile-large-icon.component.css.map +7 -0
  102. package/public/units.component.css.map +7 -0
  103. package/public/upgrade-config.component.css.map +7 -0
  104. package/public/widget-autopilot.component.css.map +7 -0
  105. package/public/widget-boolean-switch.component.css.map +7 -0
  106. package/public/widget-datetime.component.css.map +7 -0
  107. package/public/widget-freeboardsk.component.css.map +7 -0
  108. package/public/widget-gauge-ng-compass.component.css.map +7 -0
  109. package/public/widget-gauge-ng-linear.component.css.map +7 -0
  110. package/public/widget-gauge-ng-radial.component.css.map +7 -0
  111. package/public/widget-gauge-steel.component.css.map +7 -0
  112. package/public/widget-horizon.component.css.map +7 -0
  113. package/public/widget-host.component.css.map +7 -0
  114. package/public/widget-iframe.component.css.map +7 -0
  115. package/public/widget-label.component.css.map +7 -0
  116. package/public/widget-list-card.component.css.map +7 -0
  117. package/public/widget-numeric.component.css.map +7 -0
  118. package/public/widget-position.component.css.map +7 -0
  119. package/public/widget-race-timer.component.css.map +7 -0
  120. package/public/widget-racer-line.component.css.map +7 -0
  121. package/public/widget-racer-timer.component.css.map +7 -0
  122. package/public/widget-simple-linear.component.css.map +7 -0
  123. package/public/widget-slider.component.css.map +7 -0
  124. package/public/widget-text.component.css.map +7 -0
  125. package/public/widget-title.component.css.map +7 -0
  126. package/public/widget-tutorial.component.css.map +7 -0
  127. package/public/widgets-list.component.css.map +7 -0
  128. package/public/assets/hammer.min.js +0 -7
  129. package/public/chunk-2YVW3TBK.js +0 -2
  130. package/public/chunk-35L7BBBD.js +0 -15
  131. package/public/chunk-3LEMFOCV.js +0 -3
  132. package/public/chunk-4JJLPUET.js +0 -60
  133. package/public/chunk-5I4RHHVN.js +0 -11
  134. package/public/chunk-CBUY7NMR.js +0 -2
  135. package/public/chunk-CQXWGD3T.js +0 -2
  136. package/public/chunk-HCXH72CD.js +0 -5
  137. package/public/chunk-JY3WVS7C.js +0 -2
  138. package/public/chunk-K22CSA3Y.js +0 -1
  139. package/public/chunk-KTDDP73O.js +0 -2
  140. package/public/chunk-NMEZOCU2.js +0 -1
  141. package/public/chunk-NS2FPVWM.js +0 -4
  142. package/public/chunk-PKNLASTF.js +0 -4
  143. package/public/chunk-Q2Y75POI.js +0 -1
  144. package/public/chunk-QJ7KN34C.js +0 -1
  145. package/public/chunk-RRTCHHRC.js +0 -3
  146. package/public/chunk-S3HDPCXO.js +0 -1
  147. package/public/chunk-TA4GACKT.js +0 -4
  148. package/public/chunk-TXPLRBW5.js +0 -2
  149. package/public/chunk-VHFBF47T.js +0 -1
  150. package/public/chunk-VYUMZVH2.js +0 -2
  151. package/public/chunk-YP4L5CLU.js +0 -6
  152. package/public/chunk-YRM4OGRD.js +0 -2
  153. package/public/chunk-ZBCOJLI4.js +0 -6
  154. package/public/main-Z53UATGE.js +0 -64
  155. package/public/polyfills-KH22MU6U.js +0 -2
  156. package/public/styles-RECKN66R.css +0 -1
  157. /package/public/media/{KFOlCnqEu92Fr1MmEU9fABc4AMP6lbBP-ILKS6RVC.woff2 → KFOlCnqEu92Fr1MmEU9fABc4AMP6lbBP.woff2} +0 -0
  158. /package/public/media/{KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ-MJ3CERJ6.woff2 → KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ.woff2} +0 -0
  159. /package/public/media/{KFOlCnqEu92Fr1MmEU9fBxc4AMP6lbBP-UW3XWY7P.woff2 → KFOlCnqEu92Fr1MmEU9fBxc4AMP6lbBP.woff2} +0 -0
  160. /package/public/media/{KFOlCnqEu92Fr1MmEU9fCBc4AMP6lbBP-U3JTBV4H.woff2 → KFOlCnqEu92Fr1MmEU9fCBc4AMP6lbBP.woff2} +0 -0
  161. /package/public/media/{KFOlCnqEu92Fr1MmEU9fCRc4AMP6lbBP-36ULTGLY.woff2 → KFOlCnqEu92Fr1MmEU9fCRc4AMP6lbBP.woff2} +0 -0
  162. /package/public/media/{KFOlCnqEu92Fr1MmEU9fChc4AMP6lbBP-5NJLO2HW.woff2 → KFOlCnqEu92Fr1MmEU9fChc4AMP6lbBP.woff2} +0 -0
  163. /package/public/media/{KFOlCnqEu92Fr1MmEU9fCxc4AMP6lbBP-2EL65J2O.woff2 → KFOlCnqEu92Fr1MmEU9fCxc4AMP6lbBP.woff2} +0 -0
  164. /package/public/media/{KFOlCnqEu92Fr1MmSU5fABc4AMP6lbBP-XWLWMQVU.woff2 → KFOlCnqEu92Fr1MmSU5fABc4AMP6lbBP.woff2} +0 -0
  165. /package/public/media/{KFOlCnqEu92Fr1MmSU5fBBc4AMP6lQ-PWGJWDFE.woff2 → KFOlCnqEu92Fr1MmSU5fBBc4AMP6lQ.woff2} +0 -0
  166. /package/public/media/{KFOlCnqEu92Fr1MmSU5fBxc4AMP6lbBP-ITB7NUJC.woff2 → KFOlCnqEu92Fr1MmSU5fBxc4AMP6lbBP.woff2} +0 -0
  167. /package/public/media/{KFOlCnqEu92Fr1MmSU5fCBc4AMP6lbBP-32PLHKPQ.woff2 → KFOlCnqEu92Fr1MmSU5fCBc4AMP6lbBP.woff2} +0 -0
  168. /package/public/media/{KFOlCnqEu92Fr1MmSU5fCRc4AMP6lbBP-QPSNQEDD.woff2 → KFOlCnqEu92Fr1MmSU5fCRc4AMP6lbBP.woff2} +0 -0
  169. /package/public/media/{KFOlCnqEu92Fr1MmSU5fChc4AMP6lbBP-JKBSJZY3.woff2 → KFOlCnqEu92Fr1MmSU5fChc4AMP6lbBP.woff2} +0 -0
  170. /package/public/media/{KFOlCnqEu92Fr1MmSU5fCxc4AMP6lbBP-OG5AHRIX.woff2 → KFOlCnqEu92Fr1MmSU5fCxc4AMP6lbBP.woff2} +0 -0
  171. /package/public/media/{KFOmCnqEu92Fr1Mu4WxKKTU1Kvnz-PPTELUJT.woff2 → KFOmCnqEu92Fr1Mu4WxKKTU1Kvnz.woff2} +0 -0
  172. /package/public/media/{KFOmCnqEu92Fr1Mu4mxKKTU1Kg-SNGEW7FX.woff2 → KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2} +0 -0
  173. /package/public/media/{KFOmCnqEu92Fr1Mu5mxKKTU1Kvnz-DRL4U32S.woff2 → KFOmCnqEu92Fr1Mu5mxKKTU1Kvnz.woff2} +0 -0
  174. /package/public/media/{KFOmCnqEu92Fr1Mu72xKKTU1Kvnz-PRJ7OQMU.woff2 → KFOmCnqEu92Fr1Mu72xKKTU1Kvnz.woff2} +0 -0
  175. /package/public/media/{KFOmCnqEu92Fr1Mu7GxKKTU1Kvnz-HW6RMPJ3.woff2 → KFOmCnqEu92Fr1Mu7GxKKTU1Kvnz.woff2} +0 -0
  176. /package/public/media/{KFOmCnqEu92Fr1Mu7WxKKTU1Kvnz-KZD6JQRT.woff2 → KFOmCnqEu92Fr1Mu7WxKKTU1Kvnz.woff2} +0 -0
  177. /package/public/media/{KFOmCnqEu92Fr1Mu7mxKKTU1Kvnz-Z72STTMG.woff2 → KFOmCnqEu92Fr1Mu7mxKKTU1Kvnz.woff2} +0 -0
  178. /package/public/media/{flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-CN2J7AYH.woff2 → flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2} +0 -0
@@ -0,0 +1,2228 @@
1
+ import {
2
+ AppSettingsService,
3
+ DataService
4
+ } from "./chunk-BIBIW64D.js";
5
+ import {
6
+ Injectable,
7
+ __commonJS,
8
+ __toESM,
9
+ inject,
10
+ setClassMetadata,
11
+ ɵɵdefineInjectable
12
+ } from "./chunk-SDOP6T56.js";
13
+
14
+ // node_modules/js-quantities/build/quantities.js
15
+ var require_quantities = __commonJS({
16
+ "node_modules/js-quantities/build/quantities.js"(exports, module) {
17
+ (function(global, factory) {
18
+ typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.Qty = factory());
19
+ })(exports, (function() {
20
+ "use strict";
21
+ function isString(value) {
22
+ return typeof value === "string" || value instanceof String;
23
+ }
24
+ var isFiniteImpl = Number.isFinite || window.isFinite;
25
+ function isNumber(value) {
26
+ return isFiniteImpl(value);
27
+ }
28
+ function identity(value) {
29
+ return value;
30
+ }
31
+ function uniq(strings) {
32
+ var seen = {};
33
+ return strings.filter(function(item) {
34
+ return seen.hasOwnProperty(item) ? false : seen[item] = true;
35
+ });
36
+ }
37
+ function compareArray(array1, array2) {
38
+ if (array2.length !== array1.length) {
39
+ return false;
40
+ }
41
+ for (var i2 = 0; i2 < array1.length; i2++) {
42
+ if (array2[i2].compareArray) {
43
+ if (!array2[i2].compareArray(array1[i2])) {
44
+ return false;
45
+ }
46
+ }
47
+ if (array2[i2] !== array1[i2]) {
48
+ return false;
49
+ }
50
+ }
51
+ return true;
52
+ }
53
+ function assign(target, properties) {
54
+ Object.keys(properties).forEach(function(key) {
55
+ target[key] = properties[key];
56
+ });
57
+ }
58
+ function mulSafe() {
59
+ var result = 1, decimals = 0;
60
+ for (var i2 = 0; i2 < arguments.length; i2++) {
61
+ var arg = arguments[i2];
62
+ decimals = decimals + getFractional(arg);
63
+ result *= arg;
64
+ }
65
+ return decimals !== 0 ? round(result, decimals) : result;
66
+ }
67
+ function divSafe(num, den) {
68
+ if (den === 0) {
69
+ throw new Error("Divide by zero");
70
+ }
71
+ var factor = Math.pow(10, getFractional(den));
72
+ var invDen = factor / (factor * den);
73
+ return mulSafe(num, invDen);
74
+ }
75
+ function round(val, decimals) {
76
+ return Math.round(val * Math.pow(10, decimals)) / Math.pow(10, decimals);
77
+ }
78
+ function getFractional(num) {
79
+ if (!isFinite(num)) {
80
+ return 0;
81
+ }
82
+ var count = 0;
83
+ while (num % 1 !== 0) {
84
+ num *= 10;
85
+ count++;
86
+ }
87
+ return count;
88
+ }
89
+ function QtyError() {
90
+ var err;
91
+ if (!this) {
92
+ err = Object.create(QtyError.prototype);
93
+ QtyError.apply(err, arguments);
94
+ return err;
95
+ }
96
+ err = Error.apply(this, arguments);
97
+ this.name = "QtyError";
98
+ this.message = err.message;
99
+ this.stack = err.stack;
100
+ }
101
+ QtyError.prototype = Object.create(Error.prototype, { constructor: { value: QtyError } });
102
+ function throwIncompatibleUnits(left, right) {
103
+ throw new QtyError("Incompatible units: " + left + " and " + right);
104
+ }
105
+ var UNITS = {
106
+ /* prefixes */
107
+ "<googol>": [["googol"], 1e100, "prefix"],
108
+ "<kibi>": [["Ki", "Kibi", "kibi"], Math.pow(2, 10), "prefix"],
109
+ "<mebi>": [["Mi", "Mebi", "mebi"], Math.pow(2, 20), "prefix"],
110
+ "<gibi>": [["Gi", "Gibi", "gibi"], Math.pow(2, 30), "prefix"],
111
+ "<tebi>": [["Ti", "Tebi", "tebi"], Math.pow(2, 40), "prefix"],
112
+ "<pebi>": [["Pi", "Pebi", "pebi"], Math.pow(2, 50), "prefix"],
113
+ "<exi>": [["Ei", "Exi", "exi"], Math.pow(2, 60), "prefix"],
114
+ "<zebi>": [["Zi", "Zebi", "zebi"], Math.pow(2, 70), "prefix"],
115
+ "<yebi>": [["Yi", "Yebi", "yebi"], Math.pow(2, 80), "prefix"],
116
+ "<yotta>": [["Y", "Yotta", "yotta"], 1e24, "prefix"],
117
+ "<zetta>": [["Z", "Zetta", "zetta"], 1e21, "prefix"],
118
+ "<exa>": [["E", "Exa", "exa"], 1e18, "prefix"],
119
+ "<peta>": [["P", "Peta", "peta"], 1e15, "prefix"],
120
+ "<tera>": [["T", "Tera", "tera"], 1e12, "prefix"],
121
+ "<giga>": [["G", "Giga", "giga"], 1e9, "prefix"],
122
+ "<mega>": [["M", "Mega", "mega"], 1e6, "prefix"],
123
+ "<kilo>": [["k", "kilo"], 1e3, "prefix"],
124
+ "<hecto>": [["h", "Hecto", "hecto"], 100, "prefix"],
125
+ "<deca>": [["da", "Deca", "deca", "deka"], 10, "prefix"],
126
+ "<deci>": [["d", "Deci", "deci"], 0.1, "prefix"],
127
+ "<centi>": [["c", "Centi", "centi"], 0.01, "prefix"],
128
+ "<milli>": [["m", "Milli", "milli"], 1e-3, "prefix"],
129
+ "<micro>": [
130
+ ["u", "\u03BC", "\xB5", "Micro", "mc", "micro"],
131
+ 1e-6,
132
+ "prefix"
133
+ ],
134
+ "<nano>": [["n", "Nano", "nano"], 1e-9, "prefix"],
135
+ "<pico>": [["p", "Pico", "pico"], 1e-12, "prefix"],
136
+ "<femto>": [["f", "Femto", "femto"], 1e-15, "prefix"],
137
+ "<atto>": [["a", "Atto", "atto"], 1e-18, "prefix"],
138
+ "<zepto>": [["z", "Zepto", "zepto"], 1e-21, "prefix"],
139
+ "<yocto>": [["y", "Yocto", "yocto"], 1e-24, "prefix"],
140
+ "<1>": [["1", "<1>"], 1, ""],
141
+ /* length units */
142
+ "<meter>": [["m", "meter", "meters", "metre", "metres"], 1, "length", ["<meter>"]],
143
+ "<inch>": [["in", "inch", "inches", '"'], 0.0254, "length", ["<meter>"]],
144
+ "<foot>": [["ft", "foot", "feet", "'"], 0.3048, "length", ["<meter>"]],
145
+ "<yard>": [["yd", "yard", "yards"], 0.9144, "length", ["<meter>"]],
146
+ "<mile>": [["mi", "mile", "miles"], 1609.344, "length", ["<meter>"]],
147
+ "<naut-mile>": [["nmi", "naut-mile"], 1852, "length", ["<meter>"]],
148
+ "<league>": [["league", "leagues"], 4828, "length", ["<meter>"]],
149
+ "<furlong>": [["furlong", "furlongs"], 201.2, "length", ["<meter>"]],
150
+ "<rod>": [["rd", "rod", "rods"], 5.029, "length", ["<meter>"]],
151
+ "<mil>": [["mil", "mils"], 254e-7, "length", ["<meter>"]],
152
+ "<angstrom>": [["ang", "angstrom", "angstroms"], 1e-10, "length", ["<meter>"]],
153
+ "<fathom>": [["fathom", "fathoms"], 1.829, "length", ["<meter>"]],
154
+ "<pica>": [["pica", "picas"], 0.00423333333, "length", ["<meter>"]],
155
+ "<point>": [["pt", "point", "points"], 352777778e-12, "length", ["<meter>"]],
156
+ "<redshift>": [["z", "red-shift", "redshift"], 1302773e20, "length", ["<meter>"]],
157
+ "<AU>": [["AU", "astronomical-unit"], 1495979e5, "length", ["<meter>"]],
158
+ "<light-second>": [["ls", "light-second"], 299792500, "length", ["<meter>"]],
159
+ "<light-minute>": [["lmin", "light-minute"], 1798755e4, "length", ["<meter>"]],
160
+ "<light-year>": [["ly", "light-year"], 9460528e9, "length", ["<meter>"]],
161
+ "<parsec>": [["pc", "parsec", "parsecs"], 3085678e10, "length", ["<meter>"]],
162
+ "<datamile>": [["DM", "datamile"], 1828.8, "length", ["<meter>"]],
163
+ /* mass */
164
+ "<kilogram>": [["kg", "kilogram", "kilograms"], 1, "mass", ["<kilogram>"]],
165
+ "<AMU>": [["u", "AMU", "amu"], 1660538921e-36, "mass", ["<kilogram>"]],
166
+ "<dalton>": [["Da", "Dalton", "Daltons", "dalton", "daltons"], 1660538921e-36, "mass", ["<kilogram>"]],
167
+ "<slug>": [["slug", "slugs"], 14.5939029, "mass", ["<kilogram>"]],
168
+ "<short-ton>": [["tn", "ton", "short-ton"], 907.18474, "mass", ["<kilogram>"]],
169
+ "<metric-ton>": [["t", "tonne", "metric-ton"], 1e3, "mass", ["<kilogram>"]],
170
+ "<carat>": [["ct", "carat", "carats"], 2e-4, "mass", ["<kilogram>"]],
171
+ "<pound>": [["lbs", "lb", "pound", "pounds", "#"], 0.45359237, "mass", ["<kilogram>"]],
172
+ "<ounce>": [["oz", "ounce", "ounces"], 0.0283495231, "mass", ["<kilogram>"]],
173
+ "<gram>": [["g", "gram", "grams", "gramme", "grammes"], 1e-3, "mass", ["<kilogram>"]],
174
+ "<grain>": [["grain", "grains", "gr"], 6479891e-11, "mass", ["<kilogram>"]],
175
+ "<dram>": [["dram", "drams", "dr"], 0.0017718452, "mass", ["<kilogram>"]],
176
+ "<stone>": [["stone", "stones", "st"], 6.35029318, "mass", ["<kilogram>"]],
177
+ /* area */
178
+ "<hectare>": [["hectare"], 1e4, "area", ["<meter>", "<meter>"]],
179
+ "<acre>": [["acre", "acres"], 4046.85642, "area", ["<meter>", "<meter>"]],
180
+ "<sqft>": [["sqft"], 1, "area", ["<foot>", "<foot>"]],
181
+ /* volume */
182
+ "<liter>": [["l", "L", "liter", "liters", "litre", "litres"], 1e-3, "volume", ["<meter>", "<meter>", "<meter>"]],
183
+ "<gallon>": [["gal", "gallon", "gallons"], 0.0037854118, "volume", ["<meter>", "<meter>", "<meter>"]],
184
+ "<gallon-imp>": [["galimp", "gallon-imp", "gallons-imp"], 454609e-8, "volume", ["<meter>", "<meter>", "<meter>"]],
185
+ "<quart>": [["qt", "quart", "quarts"], 94635295e-11, "volume", ["<meter>", "<meter>", "<meter>"]],
186
+ "<pint>": [["pt", "pint", "pints"], 473176475e-12, "volume", ["<meter>", "<meter>", "<meter>"]],
187
+ "<pint-imp>": [["ptimp", "pint-imp", "pints-imp"], 56826125e-11, "volume", ["<meter>", "<meter>", "<meter>"]],
188
+ "<cup>": [["cu", "cup", "cups"], 236588238e-12, "volume", ["<meter>", "<meter>", "<meter>"]],
189
+ "<fluid-ounce>": [["floz", "fluid-ounce", "fluid-ounces"], 295735297e-13, "volume", ["<meter>", "<meter>", "<meter>"]],
190
+ "<fluid-ounce-imp>": [["flozimp", "floz-imp", "fluid-ounce-imp", "fluid-ounces-imp"], 284130625e-13, "volume", ["<meter>", "<meter>", "<meter>"]],
191
+ "<tablespoon>": [["tb", "tbsp", "tbs", "tablespoon", "tablespoons"], 147867648e-13, "volume", ["<meter>", "<meter>", "<meter>"]],
192
+ "<teaspoon>": [["tsp", "teaspoon", "teaspoons"], 492892161e-14, "volume", ["<meter>", "<meter>", "<meter>"]],
193
+ "<bushel>": [["bu", "bsh", "bushel", "bushels"], 0.035239072, "volume", ["<meter>", "<meter>", "<meter>"]],
194
+ "<oilbarrel>": [["bbl", "oilbarrel", "oilbarrels", "oil-barrel", "oil-barrels"], 0.158987294928, "volume", ["<meter>", "<meter>", "<meter>"]],
195
+ "<beerbarrel>": [["bl", "bl-us", "beerbarrel", "beerbarrels", "beer-barrel", "beer-barrels"], 0.1173477658, "volume", ["<meter>", "<meter>", "<meter>"]],
196
+ "<beerbarrel-imp>": [["blimp", "bl-imp", "beerbarrel-imp", "beerbarrels-imp", "beer-barrel-imp", "beer-barrels-imp"], 0.16365924, "volume", ["<meter>", "<meter>", "<meter>"]],
197
+ /* speed */
198
+ "<kph>": [["kph"], 0.277777778, "speed", ["<meter>"], ["<second>"]],
199
+ "<mph>": [["mph"], 0.44704, "speed", ["<meter>"], ["<second>"]],
200
+ "<knot>": [["kt", "kn", "kts", "knot", "knots"], 0.514444444, "speed", ["<meter>"], ["<second>"]],
201
+ "<fps>": [["fps"], 0.3048, "speed", ["<meter>"], ["<second>"]],
202
+ /* acceleration */
203
+ "<gee>": [["gee"], 9.80665, "acceleration", ["<meter>"], ["<second>", "<second>"]],
204
+ "<Gal>": [["Gal"], 0.01, "acceleration", ["<meter>"], ["<second>", "<second>"]],
205
+ /* temperature_difference */
206
+ "<kelvin>": [["degK", "kelvin"], 1, "temperature", ["<kelvin>"]],
207
+ "<celsius>": [["degC", "celsius", "celsius", "centigrade"], 1, "temperature", ["<kelvin>"]],
208
+ "<fahrenheit>": [["degF", "fahrenheit"], 5 / 9, "temperature", ["<kelvin>"]],
209
+ "<rankine>": [["degR", "rankine"], 5 / 9, "temperature", ["<kelvin>"]],
210
+ "<temp-K>": [["tempK", "temp-K"], 1, "temperature", ["<temp-K>"]],
211
+ "<temp-C>": [["tempC", "temp-C"], 1, "temperature", ["<temp-K>"]],
212
+ "<temp-F>": [["tempF", "temp-F"], 5 / 9, "temperature", ["<temp-K>"]],
213
+ "<temp-R>": [["tempR", "temp-R"], 5 / 9, "temperature", ["<temp-K>"]],
214
+ /* time */
215
+ "<second>": [["s", "sec", "secs", "second", "seconds"], 1, "time", ["<second>"]],
216
+ "<minute>": [["min", "mins", "minute", "minutes"], 60, "time", ["<second>"]],
217
+ "<hour>": [["h", "hr", "hrs", "hour", "hours"], 3600, "time", ["<second>"]],
218
+ "<day>": [["d", "day", "days"], 3600 * 24, "time", ["<second>"]],
219
+ "<week>": [["wk", "week", "weeks"], 7 * 3600 * 24, "time", ["<second>"]],
220
+ "<fortnight>": [["fortnight", "fortnights"], 1209600, "time", ["<second>"]],
221
+ "<year>": [["y", "yr", "year", "years", "annum"], 31556926, "time", ["<second>"]],
222
+ "<decade>": [["decade", "decades"], 315569260, "time", ["<second>"]],
223
+ "<century>": [["century", "centuries"], 3155692600, "time", ["<second>"]],
224
+ /* pressure */
225
+ "<pascal>": [["Pa", "pascal", "Pascal"], 1, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
226
+ "<bar>": [["bar", "bars"], 1e5, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
227
+ "<mmHg>": [["mmHg"], 133.322368, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
228
+ "<inHg>": [["inHg"], 3386.3881472, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
229
+ "<torr>": [["torr"], 133.322368, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
230
+ "<atm>": [["atm", "ATM", "atmosphere", "atmospheres"], 101325, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
231
+ "<psi>": [["psi"], 6894.76, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
232
+ "<cmh2o>": [["cmH2O", "cmh2o"], 98.0638, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
233
+ "<inh2o>": [["inH2O", "inh2o"], 249.082052, "pressure", ["<kilogram>"], ["<meter>", "<second>", "<second>"]],
234
+ /* viscosity */
235
+ "<poise>": [["P", "poise"], 0.1, "viscosity", ["<kilogram>"], ["<meter>", "<second>"]],
236
+ "<stokes>": [["St", "stokes"], 1e-4, "viscosity", ["<meter>", "<meter>"], ["<second>"]],
237
+ /* substance */
238
+ "<mole>": [["mol", "mole"], 1, "substance", ["<mole>"]],
239
+ /* molar_concentration */
240
+ "<molar>": [["M", "molar"], 1e3, "molar_concentration", ["<mole>"], ["<meter>", "<meter>", "<meter>"]],
241
+ "<wtpercent>": [["wt%", "wtpercent"], 10, "molar_concentration", ["<kilogram>"], ["<meter>", "<meter>", "<meter>"]],
242
+ /* activity */
243
+ "<katal>": [["kat", "katal", "Katal"], 1, "activity", ["<mole>"], ["<second>"]],
244
+ "<unit>": [["U", "enzUnit", "unit"], 16667e-19, "activity", ["<mole>"], ["<second>"]],
245
+ /* capacitance */
246
+ "<farad>": [["F", "farad", "Farad"], 1, "capacitance", ["<second>", "<second>", "<second>", "<second>", "<ampere>", "<ampere>"], ["<meter>", "<meter>", "<kilogram>"]],
247
+ /* charge */
248
+ "<coulomb>": [["C", "coulomb", "Coulomb"], 1, "charge", ["<ampere>", "<second>"]],
249
+ "<Ah>": [["Ah"], 3600, "charge", ["<ampere>", "<second>"]],
250
+ /* current */
251
+ "<ampere>": [["A", "Ampere", "ampere", "amp", "amps"], 1, "current", ["<ampere>"]],
252
+ /* conductance */
253
+ "<siemens>": [["S", "Siemens", "siemens"], 1, "conductance", ["<second>", "<second>", "<second>", "<ampere>", "<ampere>"], ["<kilogram>", "<meter>", "<meter>"]],
254
+ /* inductance */
255
+ "<henry>": [["H", "Henry", "henry"], 1, "inductance", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>", "<ampere>", "<ampere>"]],
256
+ /* potential */
257
+ "<volt>": [["V", "Volt", "volt", "volts"], 1, "potential", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>", "<second>", "<ampere>"]],
258
+ /* resistance */
259
+ "<ohm>": [
260
+ [
261
+ "Ohm",
262
+ "ohm",
263
+ "\u03A9",
264
+ "\u2126"
265
+ /*Ω as ohm sign*/
266
+ ],
267
+ 1,
268
+ "resistance",
269
+ ["<meter>", "<meter>", "<kilogram>"],
270
+ ["<second>", "<second>", "<second>", "<ampere>", "<ampere>"]
271
+ ],
272
+ /* magnetism */
273
+ "<weber>": [["Wb", "weber", "webers"], 1, "magnetism", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>", "<ampere>"]],
274
+ "<tesla>": [["T", "tesla", "teslas"], 1, "magnetism", ["<kilogram>"], ["<second>", "<second>", "<ampere>"]],
275
+ "<gauss>": [["G", "gauss"], 1e-4, "magnetism", ["<kilogram>"], ["<second>", "<second>", "<ampere>"]],
276
+ "<maxwell>": [["Mx", "maxwell", "maxwells"], 1e-8, "magnetism", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>", "<ampere>"]],
277
+ "<oersted>": [["Oe", "oersted", "oersteds"], 250 / Math.PI, "magnetism", ["<ampere>"], ["<meter>"]],
278
+ /* energy */
279
+ "<joule>": [["J", "joule", "Joule", "joules", "Joules"], 1, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
280
+ "<erg>": [["erg", "ergs"], 1e-7, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
281
+ "<btu>": [["BTU", "btu", "BTUs"], 1055.056, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
282
+ "<calorie>": [["cal", "calorie", "calories"], 4.184, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
283
+ "<Calorie>": [["Cal", "Calorie", "Calories"], 4184, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
284
+ "<therm-US>": [["th", "therm", "therms", "Therm", "therm-US"], 105480400, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
285
+ "<Wh>": [["Wh"], 3600, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
286
+ "<electronvolt>": [["eV", "electronvolt", "electronvolts"], 1602176634e-28, "energy", ["<meter>", "<meter>", "<kilogram>"], ["<second>", "<second>"]],
287
+ /* force */
288
+ "<newton>": [["N", "Newton", "newton"], 1, "force", ["<kilogram>", "<meter>"], ["<second>", "<second>"]],
289
+ "<dyne>": [["dyn", "dyne"], 1e-5, "force", ["<kilogram>", "<meter>"], ["<second>", "<second>"]],
290
+ "<pound-force>": [["lbf", "pound-force"], 4.448222, "force", ["<kilogram>", "<meter>"], ["<second>", "<second>"]],
291
+ /* frequency */
292
+ "<hertz>": [["Hz", "hertz", "Hertz"], 1, "frequency", ["<1>"], ["<second>"]],
293
+ /* angle */
294
+ "<radian>": [["rad", "radian", "radians"], 1, "angle", ["<radian>"]],
295
+ "<degree>": [["deg", "degree", "degrees"], Math.PI / 180, "angle", ["<radian>"]],
296
+ "<arcminute>": [["arcmin", "arcminute", "arcminutes"], Math.PI / 10800, "angle", ["<radian>"]],
297
+ "<arcsecond>": [["arcsec", "arcsecond", "arcseconds"], Math.PI / 648e3, "angle", ["<radian>"]],
298
+ "<gradian>": [["gon", "grad", "gradian", "grads"], Math.PI / 200, "angle", ["<radian>"]],
299
+ "<steradian>": [["sr", "steradian", "steradians"], 1, "solid_angle", ["<steradian>"]],
300
+ /* rotation */
301
+ "<rotation>": [["rotation"], 2 * Math.PI, "angle", ["<radian>"]],
302
+ "<rpm>": [["rpm"], 2 * Math.PI / 60, "angular_velocity", ["<radian>"], ["<second>"]],
303
+ /* information */
304
+ "<byte>": [["B", "byte", "bytes"], 1, "information", ["<byte>"]],
305
+ "<bit>": [["b", "bit", "bits"], 0.125, "information", ["<byte>"]],
306
+ /* information rate */
307
+ "<Bps>": [["Bps"], 1, "information_rate", ["<byte>"], ["<second>"]],
308
+ "<bps>": [["bps"], 0.125, "information_rate", ["<byte>"], ["<second>"]],
309
+ /* currency */
310
+ "<dollar>": [["USD", "dollar"], 1, "currency", ["<dollar>"]],
311
+ "<cents>": [["cents"], 0.01, "currency", ["<dollar>"]],
312
+ /* luminosity */
313
+ "<candela>": [["cd", "candela"], 1, "luminosity", ["<candela>"]],
314
+ "<lumen>": [["lm", "lumen"], 1, "luminous_power", ["<candela>", "<steradian>"]],
315
+ "<lux>": [["lux"], 1, "illuminance", ["<candela>", "<steradian>"], ["<meter>", "<meter>"]],
316
+ /* power */
317
+ "<watt>": [["W", "watt", "watts"], 1, "power", ["<kilogram>", "<meter>", "<meter>"], ["<second>", "<second>", "<second>"]],
318
+ "<volt-ampere>": [["VA", "volt-ampere"], 1, "power", ["<kilogram>", "<meter>", "<meter>"], ["<second>", "<second>", "<second>"]],
319
+ "<volt-ampere-reactive>": [["var", "Var", "VAr", "VAR", "volt-ampere-reactive"], 1, "power", ["<kilogram>", "<meter>", "<meter>"], ["<second>", "<second>", "<second>"]],
320
+ "<horsepower>": [["hp", "horsepower"], 745.699872, "power", ["<kilogram>", "<meter>", "<meter>"], ["<second>", "<second>", "<second>"]],
321
+ /* radiation */
322
+ "<gray>": [["Gy", "gray", "grays"], 1, "radiation", ["<meter>", "<meter>"], ["<second>", "<second>"]],
323
+ "<roentgen>": [["R", "roentgen"], 933e-5, "radiation", ["<meter>", "<meter>"], ["<second>", "<second>"]],
324
+ "<sievert>": [["Sv", "sievert", "sieverts"], 1, "radiation", ["<meter>", "<meter>"], ["<second>", "<second>"]],
325
+ "<becquerel>": [["Bq", "becquerel", "becquerels"], 1, "radiation", ["<1>"], ["<second>"]],
326
+ "<curie>": [["Ci", "curie", "curies"], 37e9, "radiation", ["<1>"], ["<second>"]],
327
+ /* rate */
328
+ "<cpm>": [["cpm"], 1 / 60, "rate", ["<count>"], ["<second>"]],
329
+ "<dpm>": [["dpm"], 1 / 60, "rate", ["<count>"], ["<second>"]],
330
+ "<bpm>": [["bpm"], 1 / 60, "rate", ["<count>"], ["<second>"]],
331
+ /* resolution / typography */
332
+ "<dot>": [["dot", "dots"], 1, "resolution", ["<each>"]],
333
+ "<pixel>": [["pixel", "px"], 1, "resolution", ["<each>"]],
334
+ "<ppi>": [["ppi"], 1, "resolution", ["<pixel>"], ["<inch>"]],
335
+ "<dpi>": [["dpi"], 1, "typography", ["<dot>"], ["<inch>"]],
336
+ /* other */
337
+ "<cell>": [["cells", "cell"], 1, "counting", ["<each>"]],
338
+ "<each>": [["each"], 1, "counting", ["<each>"]],
339
+ "<count>": [["count"], 1, "counting", ["<each>"]],
340
+ "<base-pair>": [["bp", "base-pair"], 1, "counting", ["<each>"]],
341
+ "<nucleotide>": [["nt", "nucleotide"], 1, "counting", ["<each>"]],
342
+ "<molecule>": [["molecule", "molecules"], 1, "counting", ["<1>"]],
343
+ "<dozen>": [["doz", "dz", "dozen"], 12, "prefix_only", ["<each>"]],
344
+ "<percent>": [["%", "percent"], 0.01, "prefix_only", ["<1>"]],
345
+ "<ppm>": [["ppm"], 1e-6, "prefix_only", ["<1>"]],
346
+ "<ppb>": [["ppb"], 1e-9, "prefix_only", ["<1>"]],
347
+ "<ppt>": [["ppt"], 1e-12, "prefix_only", ["<1>"]],
348
+ "<ppq>": [["ppq"], 1e-15, "prefix_only", ["<1>"]],
349
+ "<gross>": [["gr", "gross"], 144, "prefix_only", ["<dozen>", "<dozen>"]],
350
+ "<decibel>": [["dB", "decibel", "decibels"], 1, "logarithmic", ["<decibel>"]]
351
+ };
352
+ var BASE_UNITS = ["<meter>", "<kilogram>", "<second>", "<mole>", "<ampere>", "<radian>", "<kelvin>", "<temp-K>", "<byte>", "<dollar>", "<candela>", "<each>", "<steradian>", "<decibel>"];
353
+ var UNITY = "<1>";
354
+ var UNITY_ARRAY = [UNITY];
355
+ function validateUnitDefinition(unitDef2, definition2) {
356
+ var scalar = definition2[1];
357
+ var numerator = definition2[3] || [];
358
+ var denominator = definition2[4] || [];
359
+ if (!isNumber(scalar)) {
360
+ throw new QtyError(unitDef2 + ": Invalid unit definition. 'scalar' must be a number");
361
+ }
362
+ numerator.forEach(function(unit) {
363
+ if (UNITS[unit] === void 0) {
364
+ throw new QtyError(unitDef2 + ": Invalid unit definition. Unit " + unit + " in 'numerator' is not recognized");
365
+ }
366
+ });
367
+ denominator.forEach(function(unit) {
368
+ if (UNITS[unit] === void 0) {
369
+ throw new QtyError(unitDef2 + ": Invalid unit definition. Unit " + unit + " in 'denominator' is not recognized");
370
+ }
371
+ });
372
+ }
373
+ var PREFIX_VALUES = {};
374
+ var PREFIX_MAP = {};
375
+ var UNIT_VALUES = {};
376
+ var UNIT_MAP = {};
377
+ var OUTPUT_MAP = {};
378
+ for (var unitDef in UNITS) {
379
+ if (UNITS.hasOwnProperty(unitDef)) {
380
+ var definition = UNITS[unitDef];
381
+ if (definition[2] === "prefix") {
382
+ PREFIX_VALUES[unitDef] = definition[1];
383
+ for (var i = 0; i < definition[0].length; i++) {
384
+ PREFIX_MAP[definition[0][i]] = unitDef;
385
+ }
386
+ } else {
387
+ validateUnitDefinition(unitDef, definition);
388
+ UNIT_VALUES[unitDef] = {
389
+ scalar: definition[1],
390
+ numerator: definition[3],
391
+ denominator: definition[4]
392
+ };
393
+ for (var j = 0; j < definition[0].length; j++) {
394
+ UNIT_MAP[definition[0][j]] = unitDef;
395
+ }
396
+ }
397
+ OUTPUT_MAP[unitDef] = definition[0][0];
398
+ }
399
+ }
400
+ function getUnits(kind) {
401
+ var i2;
402
+ var units = [];
403
+ var unitKeys = Object.keys(UNITS);
404
+ if (typeof kind === "undefined") {
405
+ for (i2 = 0; i2 < unitKeys.length; i2++) {
406
+ if (["", "prefix"].indexOf(UNITS[unitKeys[i2]][2]) === -1) {
407
+ units.push(unitKeys[i2].substr(1, unitKeys[i2].length - 2));
408
+ }
409
+ }
410
+ } else if (this.getKinds().indexOf(kind) === -1) {
411
+ throw new QtyError("Kind not recognized");
412
+ } else {
413
+ for (i2 = 0; i2 < unitKeys.length; i2++) {
414
+ if (UNITS[unitKeys[i2]][2] === kind) {
415
+ units.push(unitKeys[i2].substr(1, unitKeys[i2].length - 2));
416
+ }
417
+ }
418
+ }
419
+ return units.sort(function(a, b) {
420
+ if (a.toLowerCase() < b.toLowerCase()) {
421
+ return -1;
422
+ }
423
+ if (a.toLowerCase() > b.toLowerCase()) {
424
+ return 1;
425
+ }
426
+ return 0;
427
+ });
428
+ }
429
+ function getAliases(unitName) {
430
+ if (!UNIT_MAP[unitName]) {
431
+ throw new QtyError("Unit not recognized");
432
+ }
433
+ return UNITS[UNIT_MAP[unitName]][0];
434
+ }
435
+ var SIGNATURE_VECTOR = ["length", "time", "temperature", "mass", "current", "substance", "luminosity", "currency", "information", "angle"];
436
+ function unitSignature() {
437
+ if (this.signature) {
438
+ return this.signature;
439
+ }
440
+ var vector = unitSignatureVector.call(this);
441
+ for (var i2 = 0; i2 < vector.length; i2++) {
442
+ vector[i2] *= Math.pow(20, i2);
443
+ }
444
+ return vector.reduce(
445
+ function(previous, current) {
446
+ return previous + current;
447
+ },
448
+ 0
449
+ );
450
+ }
451
+ function unitSignatureVector() {
452
+ if (!this.isBase()) {
453
+ return unitSignatureVector.call(this.toBase());
454
+ }
455
+ var vector = new Array(SIGNATURE_VECTOR.length);
456
+ for (var i2 = 0; i2 < vector.length; i2++) {
457
+ vector[i2] = 0;
458
+ }
459
+ var r, n;
460
+ for (var j2 = 0; j2 < this.numerator.length; j2++) {
461
+ if (r = UNITS[this.numerator[j2]]) {
462
+ n = SIGNATURE_VECTOR.indexOf(r[2]);
463
+ if (n >= 0) {
464
+ vector[n] = vector[n] + 1;
465
+ }
466
+ }
467
+ }
468
+ for (var k = 0; k < this.denominator.length; k++) {
469
+ if (r = UNITS[this.denominator[k]]) {
470
+ n = SIGNATURE_VECTOR.indexOf(r[2]);
471
+ if (n >= 0) {
472
+ vector[n] = vector[n] - 1;
473
+ }
474
+ }
475
+ }
476
+ return vector;
477
+ }
478
+ var SIGN = "[+-]";
479
+ var INTEGER = "\\d+";
480
+ var SIGNED_INTEGER = SIGN + "?" + INTEGER;
481
+ var FRACTION = "\\." + INTEGER;
482
+ var FLOAT = "(?:" + INTEGER + "(?:" + FRACTION + ")?)|(?:" + FRACTION + ")";
483
+ var EXPONENT = "[Ee]" + SIGNED_INTEGER;
484
+ var SCI_NUMBER = "(?:" + FLOAT + ")(?:" + EXPONENT + ")?";
485
+ var SIGNED_NUMBER = SIGN + "?\\s*" + SCI_NUMBER;
486
+ var QTY_STRING = "(" + SIGNED_NUMBER + ")?\\s*([^/]*)(?:/(.+))?";
487
+ var QTY_STRING_REGEX = new RegExp("^" + QTY_STRING + "$");
488
+ var POWER_OP = "\\^|\\*{2}";
489
+ var SAFE_POWER = "[01234]";
490
+ var TOP_REGEX = new RegExp("([^ \\*\\d]+?)(?:" + POWER_OP + ")?(-?" + SAFE_POWER + "(?![a-zA-Z]))");
491
+ var BOTTOM_REGEX = new RegExp("([^ \\*\\d]+?)(?:" + POWER_OP + ")?(" + SAFE_POWER + "(?![a-zA-Z]))");
492
+ function parse(val) {
493
+ if (!isString(val)) {
494
+ val = val.toString();
495
+ }
496
+ val = val.trim();
497
+ var result = QTY_STRING_REGEX.exec(val);
498
+ if (!result) {
499
+ throw new QtyError(val + ": Quantity not recognized");
500
+ }
501
+ var scalarMatch = result[1];
502
+ if (scalarMatch) {
503
+ scalarMatch = scalarMatch.replace(/\s/g, "");
504
+ this.scalar = parseFloat(scalarMatch);
505
+ } else {
506
+ this.scalar = 1;
507
+ }
508
+ var top = result[2];
509
+ var bottom = result[3];
510
+ var n, x, nx;
511
+ while (result = TOP_REGEX.exec(top)) {
512
+ n = parseFloat(result[2]);
513
+ if (isNaN(n)) {
514
+ throw new QtyError("Unit exponent is not a number");
515
+ }
516
+ if (n === 0 && !UNIT_TEST_REGEX.test(result[1])) {
517
+ throw new QtyError("Unit not recognized");
518
+ }
519
+ x = result[1] + " ";
520
+ nx = "";
521
+ for (var i2 = 0; i2 < Math.abs(n); i2++) {
522
+ nx += x;
523
+ }
524
+ if (n >= 0) {
525
+ top = top.replace(result[0], nx);
526
+ } else {
527
+ bottom = bottom ? bottom + nx : nx;
528
+ top = top.replace(result[0], "");
529
+ }
530
+ }
531
+ while (result = BOTTOM_REGEX.exec(bottom)) {
532
+ n = parseFloat(result[2]);
533
+ if (isNaN(n)) {
534
+ throw new QtyError("Unit exponent is not a number");
535
+ }
536
+ if (n === 0 && !UNIT_TEST_REGEX.test(result[1])) {
537
+ throw new QtyError("Unit not recognized");
538
+ }
539
+ x = result[1] + " ";
540
+ nx = "";
541
+ for (var j2 = 0; j2 < n; j2++) {
542
+ nx += x;
543
+ }
544
+ bottom = bottom.replace(result[0], nx);
545
+ }
546
+ if (top) {
547
+ this.numerator = parseUnits(top.trim());
548
+ }
549
+ if (bottom) {
550
+ this.denominator = parseUnits(bottom.trim());
551
+ }
552
+ }
553
+ var PREFIX_REGEX = Object.keys(PREFIX_MAP).sort(function(a, b) {
554
+ return b.length - a.length;
555
+ }).join("|");
556
+ var UNIT_REGEX = Object.keys(UNIT_MAP).sort(function(a, b) {
557
+ return b.length - a.length;
558
+ }).join("|");
559
+ var BOUNDARY_REGEX = "\\b|$";
560
+ var UNIT_MATCH = "(" + PREFIX_REGEX + ")??(" + UNIT_REGEX + ")(?:" + BOUNDARY_REGEX + ")";
561
+ var UNIT_TEST_REGEX = new RegExp("^\\s*(" + UNIT_MATCH + "[\\s\\*]*)+$");
562
+ var UNIT_MATCH_REGEX = new RegExp(UNIT_MATCH, "g");
563
+ var parsedUnitsCache = {};
564
+ function parseUnits(units) {
565
+ var cached = parsedUnitsCache[units];
566
+ if (cached) {
567
+ return cached;
568
+ }
569
+ var unitMatch, normalizedUnits = [];
570
+ if (!UNIT_TEST_REGEX.test(units)) {
571
+ throw new QtyError("Unit not recognized");
572
+ }
573
+ while (unitMatch = UNIT_MATCH_REGEX.exec(units)) {
574
+ normalizedUnits.push(unitMatch.slice(1));
575
+ }
576
+ normalizedUnits = normalizedUnits.map(function(item) {
577
+ return PREFIX_MAP[item[0]] ? [PREFIX_MAP[item[0]], UNIT_MAP[item[1]]] : [UNIT_MAP[item[1]]];
578
+ });
579
+ normalizedUnits = normalizedUnits.reduce(function(a, b) {
580
+ return a.concat(b);
581
+ }, []);
582
+ normalizedUnits = normalizedUnits.filter(function(item) {
583
+ return item;
584
+ });
585
+ parsedUnitsCache[units] = normalizedUnits;
586
+ return normalizedUnits;
587
+ }
588
+ function globalParse(value) {
589
+ if (!isString(value)) {
590
+ throw new QtyError("Argument should be a string");
591
+ }
592
+ try {
593
+ return this(value);
594
+ } catch (e) {
595
+ return null;
596
+ }
597
+ }
598
+ function isQty(value) {
599
+ return value instanceof Qty2;
600
+ }
601
+ function Qty2(initValue, initUnits) {
602
+ assertValidConstructorArgs.apply(null, arguments);
603
+ if (!isQty(this)) {
604
+ return new Qty2(initValue, initUnits);
605
+ }
606
+ this.scalar = null;
607
+ this.baseScalar = null;
608
+ this.signature = null;
609
+ this._conversionCache = {};
610
+ this.numerator = UNITY_ARRAY;
611
+ this.denominator = UNITY_ARRAY;
612
+ if (isDefinitionObject(initValue)) {
613
+ this.scalar = initValue.scalar;
614
+ this.numerator = initValue.numerator && initValue.numerator.length !== 0 ? initValue.numerator : UNITY_ARRAY;
615
+ this.denominator = initValue.denominator && initValue.denominator.length !== 0 ? initValue.denominator : UNITY_ARRAY;
616
+ } else if (initUnits) {
617
+ parse.call(this, initUnits);
618
+ this.scalar = initValue;
619
+ } else {
620
+ parse.call(this, initValue);
621
+ }
622
+ if (this.denominator.join("*").indexOf("temp") >= 0) {
623
+ throw new QtyError("Cannot divide with temperatures");
624
+ }
625
+ if (this.numerator.join("*").indexOf("temp") >= 0) {
626
+ if (this.numerator.length > 1) {
627
+ throw new QtyError("Cannot multiply by temperatures");
628
+ }
629
+ if (!compareArray(this.denominator, UNITY_ARRAY)) {
630
+ throw new QtyError("Cannot divide with temperatures");
631
+ }
632
+ }
633
+ this.initValue = initValue;
634
+ updateBaseScalar.call(this);
635
+ if (this.isTemperature() && this.baseScalar < 0) {
636
+ throw new QtyError("Temperatures must not be less than absolute zero");
637
+ }
638
+ }
639
+ Qty2.prototype = {
640
+ // Properly set up constructor
641
+ constructor: Qty2
642
+ };
643
+ function assertValidConstructorArgs(value, units) {
644
+ if (units) {
645
+ if (!(isNumber(value) && isString(units))) {
646
+ throw new QtyError("Only number accepted as initialization value when units are explicitly provided");
647
+ }
648
+ } else {
649
+ if (!(isString(value) || isNumber(value) || isQty(value) || isDefinitionObject(value))) {
650
+ throw new QtyError("Only string, number or quantity accepted as single initialization value");
651
+ }
652
+ }
653
+ }
654
+ function isDefinitionObject(value) {
655
+ return value && typeof value === "object" && value.hasOwnProperty("scalar");
656
+ }
657
+ function updateBaseScalar() {
658
+ if (this.baseScalar) {
659
+ return this.baseScalar;
660
+ }
661
+ if (this.isBase()) {
662
+ this.baseScalar = this.scalar;
663
+ this.signature = unitSignature.call(this);
664
+ } else {
665
+ var base = this.toBase();
666
+ this.baseScalar = base.scalar;
667
+ this.signature = base.signature;
668
+ }
669
+ }
670
+ var KINDS = {
671
+ "-312078": "elastance",
672
+ "-312058": "resistance",
673
+ "-312038": "inductance",
674
+ "-152058": "potential",
675
+ "-152040": "magnetism",
676
+ "-152038": "magnetism",
677
+ "-7997": "specific_volume",
678
+ "-79": "snap",
679
+ "-59": "jolt",
680
+ "-39": "acceleration",
681
+ "-38": "radiation",
682
+ "-20": "frequency",
683
+ "-19": "speed",
684
+ "-18": "viscosity",
685
+ "-17": "volumetric_flow",
686
+ "-1": "wavenumber",
687
+ "0": "unitless",
688
+ "1": "length",
689
+ "2": "area",
690
+ "3": "volume",
691
+ "20": "time",
692
+ "400": "temperature",
693
+ "7941": "yank",
694
+ "7942": "power",
695
+ "7959": "pressure",
696
+ "7961": "force",
697
+ "7962": "energy",
698
+ "7979": "viscosity",
699
+ "7981": "momentum",
700
+ "7982": "angular_momentum",
701
+ "7997": "density",
702
+ "7998": "area_density",
703
+ "8000": "mass",
704
+ "152020": "radiation_exposure",
705
+ "159999": "magnetism",
706
+ "160000": "current",
707
+ "160020": "charge",
708
+ "312058": "conductance",
709
+ "312078": "capacitance",
710
+ "3199980": "activity",
711
+ "3199997": "molar_concentration",
712
+ "3200000": "substance",
713
+ "63999998": "illuminance",
714
+ "64000000": "luminous_power",
715
+ "1280000000": "currency",
716
+ "25599999980": "information_rate",
717
+ "25600000000": "information",
718
+ "511999999980": "angular_velocity",
719
+ "512000000000": "angle"
720
+ };
721
+ function getKinds() {
722
+ return uniq(Object.keys(KINDS).map(function(knownSignature) {
723
+ return KINDS[knownSignature];
724
+ }));
725
+ }
726
+ Qty2.prototype.kind = function() {
727
+ return KINDS[this.signature.toString()];
728
+ };
729
+ assign(Qty2.prototype, {
730
+ isDegrees: function() {
731
+ return (this.signature === null || this.signature === 400) && this.numerator.length === 1 && compareArray(this.denominator, UNITY_ARRAY) && (this.numerator[0].match(/<temp-[CFRK]>/) || this.numerator[0].match(/<(kelvin|celsius|rankine|fahrenheit)>/));
732
+ },
733
+ isTemperature: function() {
734
+ return this.isDegrees() && this.numerator[0].match(/<temp-[CFRK]>/);
735
+ }
736
+ });
737
+ function subtractTemperatures(lhs, rhs) {
738
+ var lhsUnits = lhs.units();
739
+ var rhsConverted = rhs.to(lhsUnits);
740
+ var dstDegrees = Qty2(getDegreeUnits(lhsUnits));
741
+ return Qty2({ "scalar": lhs.scalar - rhsConverted.scalar, "numerator": dstDegrees.numerator, "denominator": dstDegrees.denominator });
742
+ }
743
+ function subtractTempDegrees(temp, deg) {
744
+ var tempDegrees = deg.to(getDegreeUnits(temp.units()));
745
+ return Qty2({ "scalar": temp.scalar - tempDegrees.scalar, "numerator": temp.numerator, "denominator": temp.denominator });
746
+ }
747
+ function addTempDegrees(temp, deg) {
748
+ var tempDegrees = deg.to(getDegreeUnits(temp.units()));
749
+ return Qty2({ "scalar": temp.scalar + tempDegrees.scalar, "numerator": temp.numerator, "denominator": temp.denominator });
750
+ }
751
+ function getDegreeUnits(units) {
752
+ if (units === "tempK") {
753
+ return "degK";
754
+ } else if (units === "tempC") {
755
+ return "degC";
756
+ } else if (units === "tempF") {
757
+ return "degF";
758
+ } else if (units === "tempR") {
759
+ return "degR";
760
+ } else {
761
+ throw new QtyError("Unknown type for temp conversion from: " + units);
762
+ }
763
+ }
764
+ function toDegrees(src, dst) {
765
+ var srcDegK = toDegK(src);
766
+ var dstUnits = dst.units();
767
+ var dstScalar;
768
+ if (dstUnits === "degK") {
769
+ dstScalar = srcDegK.scalar;
770
+ } else if (dstUnits === "degC") {
771
+ dstScalar = srcDegK.scalar;
772
+ } else if (dstUnits === "degF") {
773
+ dstScalar = srcDegK.scalar * 9 / 5;
774
+ } else if (dstUnits === "degR") {
775
+ dstScalar = srcDegK.scalar * 9 / 5;
776
+ } else {
777
+ throw new QtyError("Unknown type for degree conversion to: " + dstUnits);
778
+ }
779
+ return Qty2({ "scalar": dstScalar, "numerator": dst.numerator, "denominator": dst.denominator });
780
+ }
781
+ function toDegK(qty) {
782
+ var units = qty.units();
783
+ var q;
784
+ if (units.match(/(deg)[CFRK]/)) {
785
+ q = qty.baseScalar;
786
+ } else if (units === "tempK") {
787
+ q = qty.scalar;
788
+ } else if (units === "tempC") {
789
+ q = qty.scalar;
790
+ } else if (units === "tempF") {
791
+ q = qty.scalar * 5 / 9;
792
+ } else if (units === "tempR") {
793
+ q = qty.scalar * 5 / 9;
794
+ } else {
795
+ throw new QtyError("Unknown type for temp conversion from: " + units);
796
+ }
797
+ return Qty2({ "scalar": q, "numerator": ["<kelvin>"], "denominator": UNITY_ARRAY });
798
+ }
799
+ function toTemp(src, dst) {
800
+ var dstUnits = dst.units();
801
+ var dstScalar;
802
+ if (dstUnits === "tempK") {
803
+ dstScalar = src.baseScalar;
804
+ } else if (dstUnits === "tempC") {
805
+ dstScalar = src.baseScalar - 273.15;
806
+ } else if (dstUnits === "tempF") {
807
+ dstScalar = src.baseScalar * 9 / 5 - 459.67;
808
+ } else if (dstUnits === "tempR") {
809
+ dstScalar = src.baseScalar * 9 / 5;
810
+ } else {
811
+ throw new QtyError("Unknown type for temp conversion to: " + dstUnits);
812
+ }
813
+ return Qty2({ "scalar": dstScalar, "numerator": dst.numerator, "denominator": dst.denominator });
814
+ }
815
+ function toTempK(qty) {
816
+ var units = qty.units();
817
+ var q;
818
+ if (units.match(/(deg)[CFRK]/)) {
819
+ q = qty.baseScalar;
820
+ } else if (units === "tempK") {
821
+ q = qty.scalar;
822
+ } else if (units === "tempC") {
823
+ q = qty.scalar + 273.15;
824
+ } else if (units === "tempF") {
825
+ q = (qty.scalar + 459.67) * 5 / 9;
826
+ } else if (units === "tempR") {
827
+ q = qty.scalar * 5 / 9;
828
+ } else {
829
+ throw new QtyError("Unknown type for temp conversion from: " + units);
830
+ }
831
+ return Qty2({ "scalar": q, "numerator": ["<temp-K>"], "denominator": UNITY_ARRAY });
832
+ }
833
+ assign(Qty2.prototype, {
834
+ /**
835
+ * Converts to other compatible units.
836
+ * Instance's converted quantities are cached for faster subsequent calls.
837
+ *
838
+ * @param {(string|Qty)} other - Target units as string or retrieved from
839
+ * other Qty instance (scalar is ignored)
840
+ *
841
+ * @returns {Qty} New converted Qty instance with target units
842
+ *
843
+ * @throws {QtyError} if target units are incompatible
844
+ *
845
+ * @example
846
+ * var weight = Qty("25 kg");
847
+ * weight.to("lb"); // => Qty("55.11556554621939 lbs");
848
+ * weight.to(Qty("3 g")); // => Qty("25000 g"); // scalar of passed Qty is ignored
849
+ */
850
+ to: function(other) {
851
+ var cached, target;
852
+ if (other === void 0 || other === null) {
853
+ return this;
854
+ }
855
+ if (!isString(other)) {
856
+ return this.to(other.units());
857
+ }
858
+ cached = this._conversionCache[other];
859
+ if (cached) {
860
+ return cached;
861
+ }
862
+ target = Qty2(other);
863
+ if (target.units() === this.units()) {
864
+ return this;
865
+ }
866
+ if (!this.isCompatible(target)) {
867
+ if (this.isInverse(target)) {
868
+ target = this.inverse().to(other);
869
+ } else {
870
+ throwIncompatibleUnits(this.units(), target.units());
871
+ }
872
+ } else {
873
+ if (target.isTemperature()) {
874
+ target = toTemp(this, target);
875
+ } else if (target.isDegrees()) {
876
+ target = toDegrees(this, target);
877
+ } else {
878
+ var q = divSafe(this.baseScalar, target.baseScalar);
879
+ target = Qty2({ "scalar": q, "numerator": target.numerator, "denominator": target.denominator });
880
+ }
881
+ }
882
+ this._conversionCache[other] = target;
883
+ return target;
884
+ },
885
+ // convert to base SI units
886
+ // results of the conversion are cached so subsequent calls to this will be fast
887
+ toBase: function() {
888
+ if (this.isBase()) {
889
+ return this;
890
+ }
891
+ if (this.isTemperature()) {
892
+ return toTempK(this);
893
+ }
894
+ var cached = baseUnitCache[this.units()];
895
+ if (!cached) {
896
+ cached = toBaseUnits(this.numerator, this.denominator);
897
+ baseUnitCache[this.units()] = cached;
898
+ }
899
+ return cached.mul(this.scalar);
900
+ },
901
+ // Converts the unit back to a float if it is unitless. Otherwise raises an exception
902
+ toFloat: function() {
903
+ if (this.isUnitless()) {
904
+ return this.scalar;
905
+ }
906
+ throw new QtyError("Can't convert to Float unless unitless. Use Unit#scalar");
907
+ },
908
+ /**
909
+ * Returns the nearest multiple of quantity passed as
910
+ * precision
911
+ *
912
+ * @param {(Qty|string|number)} precQuantity - Quantity, string formated
913
+ * quantity or number as expected precision
914
+ *
915
+ * @returns {Qty} Nearest multiple of precQuantity
916
+ *
917
+ * @example
918
+ * Qty('5.5 ft').toPrec('2 ft'); // returns 6 ft
919
+ * Qty('0.8 cu').toPrec('0.25 cu'); // returns 0.75 cu
920
+ * Qty('6.3782 m').toPrec('cm'); // returns 6.38 m
921
+ * Qty('1.146 MPa').toPrec('0.1 bar'); // returns 1.15 MPa
922
+ *
923
+ */
924
+ toPrec: function(precQuantity) {
925
+ if (isString(precQuantity)) {
926
+ precQuantity = Qty2(precQuantity);
927
+ }
928
+ if (isNumber(precQuantity)) {
929
+ precQuantity = Qty2(precQuantity + " " + this.units());
930
+ }
931
+ if (!this.isUnitless()) {
932
+ precQuantity = precQuantity.to(this.units());
933
+ } else if (!precQuantity.isUnitless()) {
934
+ throwIncompatibleUnits(this.units(), precQuantity.units());
935
+ }
936
+ if (precQuantity.scalar === 0) {
937
+ throw new QtyError("Divide by zero");
938
+ }
939
+ var precRoundedResult = mulSafe(
940
+ Math.round(this.scalar / precQuantity.scalar),
941
+ precQuantity.scalar
942
+ );
943
+ return Qty2(precRoundedResult + this.units());
944
+ }
945
+ });
946
+ function swiftConverter(srcUnits, dstUnits) {
947
+ var srcQty = Qty2(srcUnits);
948
+ var dstQty = Qty2(dstUnits);
949
+ if (srcQty.eq(dstQty)) {
950
+ return identity;
951
+ }
952
+ var convert;
953
+ if (!srcQty.isTemperature()) {
954
+ convert = function(value) {
955
+ return value * srcQty.baseScalar / dstQty.baseScalar;
956
+ };
957
+ } else {
958
+ convert = function(value) {
959
+ return srcQty.mul(value).to(dstQty).scalar;
960
+ };
961
+ }
962
+ return function converter(value) {
963
+ var i2, length, result;
964
+ if (!Array.isArray(value)) {
965
+ return convert(value);
966
+ } else {
967
+ length = value.length;
968
+ result = [];
969
+ for (i2 = 0; i2 < length; i2++) {
970
+ result.push(convert(value[i2]));
971
+ }
972
+ return result;
973
+ }
974
+ };
975
+ }
976
+ var baseUnitCache = {};
977
+ function toBaseUnits(numerator, denominator) {
978
+ var num = [];
979
+ var den = [];
980
+ var q = 1;
981
+ var unit;
982
+ for (var i2 = 0; i2 < numerator.length; i2++) {
983
+ unit = numerator[i2];
984
+ if (PREFIX_VALUES[unit]) {
985
+ q = mulSafe(q, PREFIX_VALUES[unit]);
986
+ } else {
987
+ if (UNIT_VALUES[unit]) {
988
+ q *= UNIT_VALUES[unit].scalar;
989
+ if (UNIT_VALUES[unit].numerator) {
990
+ num.push(UNIT_VALUES[unit].numerator);
991
+ }
992
+ if (UNIT_VALUES[unit].denominator) {
993
+ den.push(UNIT_VALUES[unit].denominator);
994
+ }
995
+ }
996
+ }
997
+ }
998
+ for (var j2 = 0; j2 < denominator.length; j2++) {
999
+ unit = denominator[j2];
1000
+ if (PREFIX_VALUES[unit]) {
1001
+ q /= PREFIX_VALUES[unit];
1002
+ } else {
1003
+ if (UNIT_VALUES[unit]) {
1004
+ q /= UNIT_VALUES[unit].scalar;
1005
+ if (UNIT_VALUES[unit].numerator) {
1006
+ den.push(UNIT_VALUES[unit].numerator);
1007
+ }
1008
+ if (UNIT_VALUES[unit].denominator) {
1009
+ num.push(UNIT_VALUES[unit].denominator);
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+ num = num.reduce(function(a, b) {
1015
+ return a.concat(b);
1016
+ }, []);
1017
+ den = den.reduce(function(a, b) {
1018
+ return a.concat(b);
1019
+ }, []);
1020
+ return Qty2({ "scalar": q, "numerator": num, "denominator": den });
1021
+ }
1022
+ Qty2.parse = globalParse;
1023
+ Qty2.getUnits = getUnits;
1024
+ Qty2.getAliases = getAliases;
1025
+ Qty2.mulSafe = mulSafe;
1026
+ Qty2.divSafe = divSafe;
1027
+ Qty2.getKinds = getKinds;
1028
+ Qty2.swiftConverter = swiftConverter;
1029
+ Qty2.Error = QtyError;
1030
+ assign(Qty2.prototype, {
1031
+ // Returns new instance with units of this
1032
+ add: function(other) {
1033
+ if (isString(other)) {
1034
+ other = Qty2(other);
1035
+ }
1036
+ if (!this.isCompatible(other)) {
1037
+ throwIncompatibleUnits(this.units(), other.units());
1038
+ }
1039
+ if (this.isTemperature() && other.isTemperature()) {
1040
+ throw new QtyError("Cannot add two temperatures");
1041
+ } else if (this.isTemperature()) {
1042
+ return addTempDegrees(this, other);
1043
+ } else if (other.isTemperature()) {
1044
+ return addTempDegrees(other, this);
1045
+ }
1046
+ return Qty2({ "scalar": this.scalar + other.to(this).scalar, "numerator": this.numerator, "denominator": this.denominator });
1047
+ },
1048
+ sub: function(other) {
1049
+ if (isString(other)) {
1050
+ other = Qty2(other);
1051
+ }
1052
+ if (!this.isCompatible(other)) {
1053
+ throwIncompatibleUnits(this.units(), other.units());
1054
+ }
1055
+ if (this.isTemperature() && other.isTemperature()) {
1056
+ return subtractTemperatures(this, other);
1057
+ } else if (this.isTemperature()) {
1058
+ return subtractTempDegrees(this, other);
1059
+ } else if (other.isTemperature()) {
1060
+ throw new QtyError("Cannot subtract a temperature from a differential degree unit");
1061
+ }
1062
+ return Qty2({ "scalar": this.scalar - other.to(this).scalar, "numerator": this.numerator, "denominator": this.denominator });
1063
+ },
1064
+ mul: function(other) {
1065
+ if (isNumber(other)) {
1066
+ return Qty2({ "scalar": mulSafe(this.scalar, other), "numerator": this.numerator, "denominator": this.denominator });
1067
+ } else if (isString(other)) {
1068
+ other = Qty2(other);
1069
+ }
1070
+ if ((this.isTemperature() || other.isTemperature()) && !(this.isUnitless() || other.isUnitless())) {
1071
+ throw new QtyError("Cannot multiply by temperatures");
1072
+ }
1073
+ var op1 = this;
1074
+ var op2 = other;
1075
+ if (op1.isCompatible(op2) && op1.signature !== 400) {
1076
+ op2 = op2.to(op1);
1077
+ }
1078
+ var numdenscale = cleanTerms(op1.numerator, op1.denominator, op2.numerator, op2.denominator);
1079
+ return Qty2({ "scalar": mulSafe(op1.scalar, op2.scalar, numdenscale[2]), "numerator": numdenscale[0], "denominator": numdenscale[1] });
1080
+ },
1081
+ div: function(other) {
1082
+ if (isNumber(other)) {
1083
+ if (other === 0) {
1084
+ throw new QtyError("Divide by zero");
1085
+ }
1086
+ return Qty2({ "scalar": this.scalar / other, "numerator": this.numerator, "denominator": this.denominator });
1087
+ } else if (isString(other)) {
1088
+ other = Qty2(other);
1089
+ }
1090
+ if (other.scalar === 0) {
1091
+ throw new QtyError("Divide by zero");
1092
+ }
1093
+ if (other.isTemperature()) {
1094
+ throw new QtyError("Cannot divide with temperatures");
1095
+ } else if (this.isTemperature() && !other.isUnitless()) {
1096
+ throw new QtyError("Cannot divide with temperatures");
1097
+ }
1098
+ var op1 = this;
1099
+ var op2 = other;
1100
+ if (op1.isCompatible(op2) && op1.signature !== 400) {
1101
+ op2 = op2.to(op1);
1102
+ }
1103
+ var numdenscale = cleanTerms(op1.numerator, op1.denominator, op2.denominator, op2.numerator);
1104
+ return Qty2({ "scalar": mulSafe(op1.scalar, numdenscale[2]) / op2.scalar, "numerator": numdenscale[0], "denominator": numdenscale[1] });
1105
+ },
1106
+ // Returns a Qty that is the inverse of this Qty,
1107
+ inverse: function() {
1108
+ if (this.isTemperature()) {
1109
+ throw new QtyError("Cannot divide with temperatures");
1110
+ }
1111
+ if (this.scalar === 0) {
1112
+ throw new QtyError("Divide by zero");
1113
+ }
1114
+ return Qty2({ "scalar": 1 / this.scalar, "numerator": this.denominator, "denominator": this.numerator });
1115
+ }
1116
+ });
1117
+ function cleanTerms(num1, den1, num2, den2) {
1118
+ function notUnity(val) {
1119
+ return val !== UNITY;
1120
+ }
1121
+ num1 = num1.filter(notUnity);
1122
+ num2 = num2.filter(notUnity);
1123
+ den1 = den1.filter(notUnity);
1124
+ den2 = den2.filter(notUnity);
1125
+ var combined = {};
1126
+ function combineTerms(terms, direction) {
1127
+ var k;
1128
+ var prefix;
1129
+ var prefixValue;
1130
+ for (var i2 = 0; i2 < terms.length; i2++) {
1131
+ if (PREFIX_VALUES[terms[i2]]) {
1132
+ k = terms[i2 + 1];
1133
+ prefix = terms[i2];
1134
+ prefixValue = PREFIX_VALUES[prefix];
1135
+ i2++;
1136
+ } else {
1137
+ k = terms[i2];
1138
+ prefix = null;
1139
+ prefixValue = 1;
1140
+ }
1141
+ if (k && k !== UNITY) {
1142
+ if (combined[k]) {
1143
+ combined[k][0] += direction;
1144
+ var combinedPrefixValue = combined[k][2] ? PREFIX_VALUES[combined[k][2]] : 1;
1145
+ combined[k][direction === 1 ? 3 : 4] *= divSafe(prefixValue, combinedPrefixValue);
1146
+ } else {
1147
+ combined[k] = [direction, k, prefix, 1, 1];
1148
+ }
1149
+ }
1150
+ }
1151
+ }
1152
+ combineTerms(num1, 1);
1153
+ combineTerms(den1, -1);
1154
+ combineTerms(num2, 1);
1155
+ combineTerms(den2, -1);
1156
+ var num = [];
1157
+ var den = [];
1158
+ var scale = 1;
1159
+ for (var prop in combined) {
1160
+ if (combined.hasOwnProperty(prop)) {
1161
+ var item = combined[prop];
1162
+ var n;
1163
+ if (item[0] > 0) {
1164
+ for (n = 0; n < item[0]; n++) {
1165
+ num.push(item[2] === null ? item[1] : [item[2], item[1]]);
1166
+ }
1167
+ } else if (item[0] < 0) {
1168
+ for (n = 0; n < -item[0]; n++) {
1169
+ den.push(item[2] === null ? item[1] : [item[2], item[1]]);
1170
+ }
1171
+ }
1172
+ scale *= divSafe(item[3], item[4]);
1173
+ }
1174
+ }
1175
+ if (num.length === 0) {
1176
+ num = UNITY_ARRAY;
1177
+ }
1178
+ if (den.length === 0) {
1179
+ den = UNITY_ARRAY;
1180
+ }
1181
+ num = num.reduce(function(a, b) {
1182
+ return a.concat(b);
1183
+ }, []);
1184
+ den = den.reduce(function(a, b) {
1185
+ return a.concat(b);
1186
+ }, []);
1187
+ return [num, den, scale];
1188
+ }
1189
+ assign(Qty2.prototype, {
1190
+ eq: function(other) {
1191
+ return this.compareTo(other) === 0;
1192
+ },
1193
+ lt: function(other) {
1194
+ return this.compareTo(other) === -1;
1195
+ },
1196
+ lte: function(other) {
1197
+ return this.eq(other) || this.lt(other);
1198
+ },
1199
+ gt: function(other) {
1200
+ return this.compareTo(other) === 1;
1201
+ },
1202
+ gte: function(other) {
1203
+ return this.eq(other) || this.gt(other);
1204
+ },
1205
+ // Compare two Qty objects. Throws an exception if they are not of compatible types.
1206
+ // Comparisons are done based on the value of the quantity in base SI units.
1207
+ //
1208
+ // NOTE: We cannot compare inverses as that breaks the general compareTo contract:
1209
+ // if a.compareTo(b) < 0 then b.compareTo(a) > 0
1210
+ // if a.compareTo(b) == 0 then b.compareTo(a) == 0
1211
+ //
1212
+ // Since "10S" == ".1ohm" (10 > .1) and "10ohm" == ".1S" (10 > .1)
1213
+ // Qty("10S").inverse().compareTo("10ohm") == -1
1214
+ // Qty("10ohm").inverse().compareTo("10S") == -1
1215
+ //
1216
+ // If including inverses in the sort is needed, I suggest writing: Qty.sort(qtyArray,units)
1217
+ compareTo: function(other) {
1218
+ if (isString(other)) {
1219
+ return this.compareTo(Qty2(other));
1220
+ }
1221
+ if (!this.isCompatible(other)) {
1222
+ throwIncompatibleUnits(this.units(), other.units());
1223
+ }
1224
+ if (this.baseScalar < other.baseScalar) {
1225
+ return -1;
1226
+ } else if (this.baseScalar === other.baseScalar) {
1227
+ return 0;
1228
+ } else if (this.baseScalar > other.baseScalar) {
1229
+ return 1;
1230
+ }
1231
+ },
1232
+ // Return true if quantities and units match
1233
+ // Unit("100 cm").same(Unit("100 cm")) # => true
1234
+ // Unit("100 cm").same(Unit("1 m")) # => false
1235
+ same: function(other) {
1236
+ return this.scalar === other.scalar && this.units() === other.units();
1237
+ }
1238
+ });
1239
+ assign(Qty2.prototype, {
1240
+ // returns true if no associated units
1241
+ // false, even if the units are "unitless" like 'radians, each, etc'
1242
+ isUnitless: function() {
1243
+ return [this.numerator, this.denominator].every(function(item) {
1244
+ return compareArray(item, UNITY_ARRAY);
1245
+ });
1246
+ },
1247
+ /*
1248
+ check to see if units are compatible, but not the scalar part
1249
+ this check is done by comparing signatures for performance reasons
1250
+ if passed a string, it will create a unit object with the string and then do the comparison
1251
+ this permits a syntax like:
1252
+ unit =~ "mm"
1253
+ if you want to do a regexp on the unit string do this ...
1254
+ unit.units =~ /regexp/
1255
+ */
1256
+ isCompatible: function(other) {
1257
+ if (isString(other)) {
1258
+ return this.isCompatible(Qty2(other));
1259
+ }
1260
+ if (!isQty(other)) {
1261
+ return false;
1262
+ }
1263
+ if (other.signature !== void 0) {
1264
+ return this.signature === other.signature;
1265
+ } else {
1266
+ return false;
1267
+ }
1268
+ },
1269
+ /*
1270
+ check to see if units are inverse of each other, but not the scalar part
1271
+ this check is done by comparing signatures for performance reasons
1272
+ if passed a string, it will create a unit object with the string and then do the comparison
1273
+ this permits a syntax like:
1274
+ unit =~ "mm"
1275
+ if you want to do a regexp on the unit string do this ...
1276
+ unit.units =~ /regexp/
1277
+ */
1278
+ isInverse: function(other) {
1279
+ return this.inverse().isCompatible(other);
1280
+ },
1281
+ // Returns 'true' if the Unit is represented in base units
1282
+ isBase: function() {
1283
+ if (this._isBase !== void 0) {
1284
+ return this._isBase;
1285
+ }
1286
+ if (this.isDegrees() && this.numerator[0].match(/<(kelvin|temp-K)>/)) {
1287
+ this._isBase = true;
1288
+ return this._isBase;
1289
+ }
1290
+ this.numerator.concat(this.denominator).forEach(function(item) {
1291
+ if (item !== UNITY && BASE_UNITS.indexOf(item) === -1) {
1292
+ this._isBase = false;
1293
+ }
1294
+ }, this);
1295
+ if (this._isBase === false) {
1296
+ return this._isBase;
1297
+ }
1298
+ this._isBase = true;
1299
+ return this._isBase;
1300
+ }
1301
+ });
1302
+ function NestedMap() {
1303
+ }
1304
+ NestedMap.prototype.get = function(keys) {
1305
+ if (arguments.length > 1) {
1306
+ keys = Array.apply(null, arguments);
1307
+ }
1308
+ return keys.reduce(
1309
+ function(map, key, index) {
1310
+ if (map) {
1311
+ var childMap = map[key];
1312
+ if (index === keys.length - 1) {
1313
+ return childMap ? childMap.data : void 0;
1314
+ } else {
1315
+ return childMap;
1316
+ }
1317
+ }
1318
+ },
1319
+ this
1320
+ );
1321
+ };
1322
+ NestedMap.prototype.set = function(keys, value) {
1323
+ if (arguments.length > 2) {
1324
+ keys = Array.prototype.slice.call(arguments, 0, -1);
1325
+ value = arguments[arguments.length - 1];
1326
+ }
1327
+ return keys.reduce(function(map, key, index) {
1328
+ var childMap = map[key];
1329
+ if (childMap === void 0) {
1330
+ childMap = map[key] = {};
1331
+ }
1332
+ if (index === keys.length - 1) {
1333
+ childMap.data = value;
1334
+ return value;
1335
+ } else {
1336
+ return childMap;
1337
+ }
1338
+ }, this);
1339
+ };
1340
+ function defaultFormatter(scalar, units) {
1341
+ return (scalar + " " + units).trim();
1342
+ }
1343
+ Qty2.formatter = defaultFormatter;
1344
+ assign(Qty2.prototype, {
1345
+ // returns the 'unit' part of the Unit object without the scalar
1346
+ units: function() {
1347
+ if (this._units !== void 0) {
1348
+ return this._units;
1349
+ }
1350
+ var numIsUnity = compareArray(this.numerator, UNITY_ARRAY);
1351
+ var denIsUnity = compareArray(this.denominator, UNITY_ARRAY);
1352
+ if (numIsUnity && denIsUnity) {
1353
+ this._units = "";
1354
+ return this._units;
1355
+ }
1356
+ var numUnits = stringifyUnits(this.numerator);
1357
+ var denUnits = stringifyUnits(this.denominator);
1358
+ this._units = numUnits + (denIsUnity ? "" : "/" + denUnits);
1359
+ return this._units;
1360
+ },
1361
+ /**
1362
+ * Stringifies the quantity
1363
+ * Deprecation notice: only units parameter is supported.
1364
+ *
1365
+ * @param {(number|string|Qty)} targetUnitsOrMaxDecimalsOrPrec -
1366
+ * target units if string,
1367
+ * max number of decimals if number,
1368
+ * passed to #toPrec before converting if Qty
1369
+ *
1370
+ * @param {number=} maxDecimals - Maximum number of decimals of
1371
+ * formatted output
1372
+ *
1373
+ * @returns {string} reparseable quantity as string
1374
+ */
1375
+ toString: function(targetUnitsOrMaxDecimalsOrPrec, maxDecimals) {
1376
+ var targetUnits;
1377
+ if (isNumber(targetUnitsOrMaxDecimalsOrPrec)) {
1378
+ targetUnits = this.units();
1379
+ maxDecimals = targetUnitsOrMaxDecimalsOrPrec;
1380
+ } else if (isString(targetUnitsOrMaxDecimalsOrPrec)) {
1381
+ targetUnits = targetUnitsOrMaxDecimalsOrPrec;
1382
+ } else if (isQty(targetUnitsOrMaxDecimalsOrPrec)) {
1383
+ return this.toPrec(targetUnitsOrMaxDecimalsOrPrec).toString(maxDecimals);
1384
+ }
1385
+ var out = this.to(targetUnits);
1386
+ var outScalar = maxDecimals !== void 0 ? round(out.scalar, maxDecimals) : out.scalar;
1387
+ out = (outScalar + " " + out.units()).trim();
1388
+ return out;
1389
+ },
1390
+ /**
1391
+ * Format the quantity according to optional passed target units
1392
+ * and formatter
1393
+ *
1394
+ * @param {string} [targetUnits=current units] -
1395
+ * optional units to convert to before formatting
1396
+ *
1397
+ * @param {function} [formatter=Qty.formatter] -
1398
+ * delegates formatting to formatter callback.
1399
+ * formatter is called back with two parameters (scalar, units)
1400
+ * and should return formatted result.
1401
+ * If unspecified, formatting is delegated to default formatter
1402
+ * set to Qty.formatter
1403
+ *
1404
+ * @example
1405
+ * var roundingAndLocalizingFormatter = function(scalar, units) {
1406
+ * // localize or limit scalar to n max decimals for instance
1407
+ * // return formatted result
1408
+ * };
1409
+ * var qty = Qty('1.1234 m');
1410
+ * qty.format(); // same units, default formatter => "1.234 m"
1411
+ * qty.format("cm"); // converted to "cm", default formatter => "123.45 cm"
1412
+ * qty.format(roundingAndLocalizingFormatter); // same units, custom formatter => "1,2 m"
1413
+ * qty.format("cm", roundingAndLocalizingFormatter); // convert to "cm", custom formatter => "123,4 cm"
1414
+ *
1415
+ * @returns {string} quantity as string
1416
+ */
1417
+ format: function(targetUnits, formatter) {
1418
+ if (arguments.length === 1) {
1419
+ if (typeof targetUnits === "function") {
1420
+ formatter = targetUnits;
1421
+ targetUnits = void 0;
1422
+ }
1423
+ }
1424
+ formatter = formatter || Qty2.formatter;
1425
+ var targetQty = this.to(targetUnits);
1426
+ return formatter.call(this, targetQty.scalar, targetQty.units());
1427
+ }
1428
+ });
1429
+ var stringifiedUnitsCache = new NestedMap();
1430
+ function stringifyUnits(units) {
1431
+ var stringified = stringifiedUnitsCache.get(units);
1432
+ if (stringified) {
1433
+ return stringified;
1434
+ }
1435
+ var isUnity = compareArray(units, UNITY_ARRAY);
1436
+ if (isUnity) {
1437
+ stringified = "1";
1438
+ } else {
1439
+ stringified = simplify(getOutputNames(units)).join("*");
1440
+ }
1441
+ stringifiedUnitsCache.set(units, stringified);
1442
+ return stringified;
1443
+ }
1444
+ function getOutputNames(units) {
1445
+ var unitNames = [], token, tokenNext;
1446
+ for (var i2 = 0; i2 < units.length; i2++) {
1447
+ token = units[i2];
1448
+ tokenNext = units[i2 + 1];
1449
+ if (PREFIX_VALUES[token]) {
1450
+ unitNames.push(OUTPUT_MAP[token] + OUTPUT_MAP[tokenNext]);
1451
+ i2++;
1452
+ } else {
1453
+ unitNames.push(OUTPUT_MAP[token]);
1454
+ }
1455
+ }
1456
+ return unitNames;
1457
+ }
1458
+ function simplify(units) {
1459
+ var unitCounts = units.reduce(function(acc, unit) {
1460
+ var unitCounter = acc[unit];
1461
+ if (!unitCounter) {
1462
+ acc.push(unitCounter = acc[unit] = [unit, 0]);
1463
+ }
1464
+ unitCounter[1]++;
1465
+ return acc;
1466
+ }, []);
1467
+ return unitCounts.map(function(unitCount) {
1468
+ return unitCount[0] + (unitCount[1] > 1 ? unitCount[1] : "");
1469
+ });
1470
+ }
1471
+ Qty2.version = "1.8.0";
1472
+ return Qty2;
1473
+ }));
1474
+ }
1475
+ });
1476
+
1477
+ // src/app/core/services/units.service.ts
1478
+ var import_js_quantities = __toESM(require_quantities());
1479
+ var UnitsService = class _UnitsService {
1480
+ AppSettingsService = inject(AppSettingsService);
1481
+ data = inject(DataService);
1482
+ _defaultUnitsSub;
1483
+ /**
1484
+ * Definition of available Kip units to be used for conversion.
1485
+ * Measure property has to match one Unit Conversion Function for proper operation.
1486
+ * Description is human readable property.
1487
+ */
1488
+ _conversionList = [
1489
+ { group: "Unitless", units: [
1490
+ { measure: "unitless", description: "As-Is numeric value" },
1491
+ { measure: " ", description: "No unit label - As-Is numeric value" }
1492
+ ] },
1493
+ { group: "Speed", units: [
1494
+ { measure: "knots", description: "Knots - Nautical miles per hour" },
1495
+ { measure: "kph", description: "kph - Kilometers per hour" },
1496
+ { measure: "mph", description: "mph - Miles per hour" },
1497
+ { measure: "m/s", description: "m/s - Meters per second (base)" }
1498
+ ] },
1499
+ { group: "Flow", units: [
1500
+ { measure: "m3/s", description: "Cubic meters per second (base)" },
1501
+ { measure: "l/min", description: "Liters per minute" },
1502
+ { measure: "l/h", description: "Liters per hour" },
1503
+ { measure: "g/min", description: "Gallons per minute" },
1504
+ { measure: "g/h", description: "Gallons per hour" }
1505
+ ] },
1506
+ { group: "Fuel Distance", units: [
1507
+ { measure: "m/m3", description: "Meters per cubic meter (base)" },
1508
+ { measure: "nm/l", description: "Nautical Miles per liter" },
1509
+ { measure: "nm/g", description: "Nautical Miles per gallon" },
1510
+ { measure: "km/l", description: "Kilometers per liter" },
1511
+ { measure: "mpg", description: "Miles per Gallon" }
1512
+ ] },
1513
+ { group: "Energy Distance", units: [
1514
+ { measure: "m/J", description: "Meters per Joule (base)" },
1515
+ { measure: "nm/J", description: "Nautical Miles per Joule" },
1516
+ { measure: "km/J", description: "Kilometers per Joule" },
1517
+ { measure: "nm/kWh", description: "Nautical Miles per Kilowatt-hour" },
1518
+ { measure: "km/kWh", description: "Kilometers per Kilowatt-hour" }
1519
+ ] },
1520
+ { group: "Temperature", units: [
1521
+ { measure: "K", description: "Kelvin (base)" },
1522
+ { measure: "celsius", description: "Celsius" },
1523
+ { measure: "fahrenheit", description: "Fahrenheit" }
1524
+ ] },
1525
+ { group: "Length", units: [
1526
+ { measure: "m", description: "Meters (base)" },
1527
+ { measure: "mm", description: "Millimeters" },
1528
+ { measure: "fathom", description: "Fathoms" },
1529
+ { measure: "nm", description: "Nautical Miles" },
1530
+ { measure: "km", description: "Kilometers" },
1531
+ { measure: "mi", description: "Miles" },
1532
+ { measure: "feet", description: "Feet" },
1533
+ { measure: "inch", description: "Inches" }
1534
+ ] },
1535
+ { group: "Volume", units: [
1536
+ { measure: "liter", description: "Liters (base)" },
1537
+ { measure: "m3", description: "Cubic Meters" },
1538
+ { measure: "gallon", description: "Gallons" }
1539
+ ] },
1540
+ { group: "Current", units: [
1541
+ { measure: "A", description: "Amperes (base)" },
1542
+ { measure: "mA", description: "Milliamperes" }
1543
+ ] },
1544
+ { group: "Potential", units: [
1545
+ { measure: "V", description: "Volts (base)" },
1546
+ { measure: "mV", description: "Millivolts" }
1547
+ ] },
1548
+ { group: "Charge", units: [
1549
+ { measure: "C", description: "Coulomb (base)" },
1550
+ { measure: "Ah", description: "Ampere*Hours" }
1551
+ ] },
1552
+ { group: "Power", units: [
1553
+ { measure: "W", description: "Watts (base)" },
1554
+ { measure: "mW", description: "Milliwatts" }
1555
+ ] },
1556
+ { group: "Energy", units: [
1557
+ { measure: "J", description: "Joules (base)" },
1558
+ { measure: "kWh", description: "Kilowatt*Hours" }
1559
+ ] },
1560
+ { group: "Resistance", units: [
1561
+ { measure: "ohm", description: "\u2126 (base)" },
1562
+ { measure: "kiloohm", description: "k\u2126" }
1563
+ ] },
1564
+ { group: "Pressure", units: [
1565
+ { measure: "Pa", description: "Pa (base)" },
1566
+ { measure: "kPa", description: "kPa" },
1567
+ { measure: "hPa", description: "hPa" },
1568
+ { measure: "mbar", description: "mbar" },
1569
+ { measure: "bar", description: "Bars" },
1570
+ { measure: "psi", description: "psi" },
1571
+ { measure: "mmHg", description: "mmHg" },
1572
+ { measure: "inHg", description: "inHg" }
1573
+ ] },
1574
+ { group: "Density", units: [{ measure: "kg/m3", description: "Air density - kg/cubic meter (base)" }] },
1575
+ { group: "Time", units: [
1576
+ { measure: "s", description: "Seconds (base)" },
1577
+ { measure: "Minutes", description: "Minutes" },
1578
+ { measure: "Hours", description: "Hours" },
1579
+ { measure: "Days", description: "Days" },
1580
+ { measure: "D HH:MM:SS", description: "Day Hour:Minute:sec" }
1581
+ ] },
1582
+ { group: "Angular Velocity", units: [
1583
+ { measure: "rad/s", description: "Radians per second (base)" },
1584
+ { measure: "deg/s", description: "Degrees per second" },
1585
+ { measure: "deg/min", description: "Degrees per minute" }
1586
+ ] },
1587
+ { group: "Angle", units: [
1588
+ { measure: "rad", description: "Radians (base)" },
1589
+ { measure: "deg", description: "Degrees" },
1590
+ { measure: "grad", description: "Gradians" }
1591
+ ] },
1592
+ { group: "Frequency", units: [
1593
+ { measure: "rpm", description: "RPM - Rotations per minute" },
1594
+ { measure: "Hz", description: "Hz - Hertz (base)" },
1595
+ { measure: "KHz", description: "KHz - Kilohertz" },
1596
+ { measure: "MHz", description: "MHz - Megahertz" },
1597
+ { measure: "GHz", description: "GHz - Gigahertz" }
1598
+ ] },
1599
+ { group: "Ratio", units: [
1600
+ { measure: "percent", description: "As percentage value" },
1601
+ { measure: "percentraw", description: "As ratio 0-1 with % sign" },
1602
+ { measure: "ratio", description: "Ratio 0-1 (base)" }
1603
+ ] },
1604
+ { group: "Position", units: [
1605
+ { measure: "pdeg", description: "Position Degrees" },
1606
+ { measure: "latitudeMin", description: "Latitude in minutes" },
1607
+ { measure: "latitudeSec", description: "Latitude in seconds" },
1608
+ { measure: "longitudeMin", description: "Longitude in minutes" },
1609
+ { measure: "longitudeSec", description: "Longitude in seconds" }
1610
+ ] }
1611
+ ];
1612
+ skBaseUnits = [
1613
+ {
1614
+ unit: "s",
1615
+ properties: {
1616
+ display: "s",
1617
+ quantity: "Time",
1618
+ quantityDisplay: "t",
1619
+ description: "Elapsed time (interval) in seconds"
1620
+ }
1621
+ },
1622
+ {
1623
+ unit: "Hz",
1624
+ properties: {
1625
+ display: "Hz",
1626
+ quantity: "Frequency",
1627
+ quantityDisplay: "f",
1628
+ description: "Frequency in Hertz"
1629
+ }
1630
+ },
1631
+ {
1632
+ unit: "m3",
1633
+ properties: {
1634
+ display: "m\xB3",
1635
+ quantity: "Volume",
1636
+ quantityDisplay: "V",
1637
+ description: "Volume in cubic meters"
1638
+ }
1639
+ },
1640
+ {
1641
+ unit: "m3/s",
1642
+ properties: {
1643
+ display: "m\xB3/s",
1644
+ quantity: "Flow",
1645
+ quantityDisplay: "Q",
1646
+ description: "Liquid or gas flow in cubic meters per second"
1647
+ }
1648
+ },
1649
+ {
1650
+ unit: "kg/s",
1651
+ properties: {
1652
+ display: "kg/s",
1653
+ quantity: "Mass flow rate",
1654
+ quantityDisplay: "\u1E41",
1655
+ description: "Liquid or gas flow in kilograms per second"
1656
+ }
1657
+ },
1658
+ {
1659
+ unit: "kg/m3",
1660
+ properties: {
1661
+ display: "kg/m\xB3",
1662
+ quantity: "Density",
1663
+ quantityDisplay: "\u03C1",
1664
+ description: "Density in kg per cubic meter"
1665
+ }
1666
+ },
1667
+ {
1668
+ unit: "deg",
1669
+ properties: {
1670
+ display: "Position",
1671
+ quantity: "Angle",
1672
+ quantityDisplay: "\u2220",
1673
+ description: "Latitude or longitude in decimal degrees"
1674
+ }
1675
+ },
1676
+ {
1677
+ unit: "rad",
1678
+ properties: {
1679
+ display: "\xB0",
1680
+ quantity: "Angle",
1681
+ quantityDisplay: "\u2220",
1682
+ description: "Angular arc in radians"
1683
+ }
1684
+ },
1685
+ {
1686
+ unit: "rad/s",
1687
+ properties: {
1688
+ display: "\u33AD/s",
1689
+ quantity: "Rotation",
1690
+ quantityDisplay: "\u03C9",
1691
+ description: "Angular rate in radians per second"
1692
+ }
1693
+ },
1694
+ {
1695
+ unit: "A",
1696
+ properties: {
1697
+ display: "A",
1698
+ quantity: "Current",
1699
+ quantityDisplay: "I",
1700
+ description: "Electrical current in ampere"
1701
+ }
1702
+ },
1703
+ {
1704
+ unit: "C",
1705
+ properties: {
1706
+ display: "C",
1707
+ quantity: "Charge",
1708
+ quantityDisplay: "Q",
1709
+ description: "Electrical charge in Coulomb"
1710
+ }
1711
+ },
1712
+ {
1713
+ unit: "V",
1714
+ properties: {
1715
+ display: "V",
1716
+ quantity: "Voltage",
1717
+ quantityDisplay: "V",
1718
+ description: "Electrical potential in volt"
1719
+ }
1720
+ },
1721
+ {
1722
+ unit: "W",
1723
+ properties: {
1724
+ display: "W",
1725
+ quantity: "Power",
1726
+ quantityDisplay: "P",
1727
+ description: "Power in watt"
1728
+ }
1729
+ },
1730
+ {
1731
+ unit: "Nm",
1732
+ properties: {
1733
+ display: "Nm",
1734
+ quantity: "Torque",
1735
+ quantityDisplay: "\u03C4",
1736
+ description: "Torque in Newton meter"
1737
+ }
1738
+ },
1739
+ {
1740
+ unit: "J",
1741
+ properties: {
1742
+ display: "J",
1743
+ quantity: "Energy",
1744
+ quantityDisplay: "E",
1745
+ description: "Electrical energy in joule"
1746
+ }
1747
+ },
1748
+ {
1749
+ unit: "ohm",
1750
+ properties: {
1751
+ display: "\u2126",
1752
+ quantity: "Resistance",
1753
+ quantityDisplay: "R",
1754
+ description: "Electrical resistance in ohm"
1755
+ }
1756
+ },
1757
+ {
1758
+ unit: "m",
1759
+ properties: {
1760
+ display: "m",
1761
+ quantity: "Distance",
1762
+ quantityDisplay: "d",
1763
+ description: "Distance in meters"
1764
+ }
1765
+ },
1766
+ {
1767
+ unit: "m/s",
1768
+ properties: {
1769
+ display: "m/s",
1770
+ quantity: "Speed",
1771
+ quantityDisplay: "v",
1772
+ description: "Speed in meters per second"
1773
+ }
1774
+ },
1775
+ {
1776
+ unit: "m2",
1777
+ properties: {
1778
+ display: "\u33A1",
1779
+ quantity: "Area",
1780
+ quantityDisplay: "A",
1781
+ description: "(Surface) area in square meters"
1782
+ }
1783
+ },
1784
+ {
1785
+ unit: "K",
1786
+ properties: {
1787
+ display: "K",
1788
+ quantity: "Temperature",
1789
+ quantityDisplay: "T",
1790
+ description: "Temperature in kelvin"
1791
+ }
1792
+ },
1793
+ {
1794
+ unit: "Pa",
1795
+ properties: {
1796
+ display: "Pa",
1797
+ quantity: "Pressure",
1798
+ quantityDisplay: "P",
1799
+ description: "Pressure in pascal"
1800
+ }
1801
+ },
1802
+ {
1803
+ unit: "kg",
1804
+ properties: {
1805
+ display: "kg",
1806
+ quantity: "Mass",
1807
+ quantityDisplay: "m",
1808
+ description: "Mass in kilogram"
1809
+ }
1810
+ },
1811
+ {
1812
+ unit: "ratio",
1813
+ properties: {
1814
+ display: "",
1815
+ quantity: "Ratio",
1816
+ quantityDisplay: "\u03C6",
1817
+ description: "Relative value compared to reference or normal value. 0 = 0%, 1 = 100%, 1e-3 = 1 ppt"
1818
+ }
1819
+ },
1820
+ {
1821
+ unit: "m/s2",
1822
+ properties: {
1823
+ display: "m/s\xB2",
1824
+ quantity: "Acceleration",
1825
+ quantityDisplay: "a",
1826
+ description: "Acceleration in meters per second squared"
1827
+ }
1828
+ },
1829
+ {
1830
+ unit: "rad/s2",
1831
+ properties: {
1832
+ display: "rad/s\xB2",
1833
+ quantity: "Angular acceleration",
1834
+ quantityDisplay: "a",
1835
+ description: "Angular acceleration in radians per second squared"
1836
+ }
1837
+ },
1838
+ {
1839
+ unit: "N",
1840
+ properties: {
1841
+ display: "N",
1842
+ quantity: "Force",
1843
+ quantityDisplay: "F",
1844
+ description: "Force in newton"
1845
+ }
1846
+ },
1847
+ {
1848
+ unit: "T",
1849
+ properties: {
1850
+ display: "T",
1851
+ quantity: "Magnetic field",
1852
+ quantityDisplay: "B",
1853
+ description: "Magnetic field strength in tesla"
1854
+ }
1855
+ },
1856
+ {
1857
+ unit: "Lux",
1858
+ properties: {
1859
+ display: "lx",
1860
+ quantity: "Light Intensity",
1861
+ quantityDisplay: "Ev",
1862
+ description: "Light Intensity in lux"
1863
+ }
1864
+ },
1865
+ {
1866
+ unit: "Pa/s",
1867
+ properties: {
1868
+ display: "Pa/s",
1869
+ quantity: "Pressure rate",
1870
+ quantityDisplay: "R",
1871
+ description: "Pressure change rate in pascal per second"
1872
+ }
1873
+ },
1874
+ {
1875
+ unit: "Pa.s",
1876
+ properties: {
1877
+ display: "Pa s",
1878
+ quantity: "Viscosity",
1879
+ quantityDisplay: "\u03BC",
1880
+ description: "Viscosity in pascal seconds"
1881
+ }
1882
+ }
1883
+ ];
1884
+ _defaultUnits = null;
1885
+ constructor() {
1886
+ this._defaultUnitsSub = this.AppSettingsService.getDefaultUnitsAsO().subscribe((appSettings) => {
1887
+ this._defaultUnits = appSettings;
1888
+ });
1889
+ }
1890
+ unitConversionFunctions = {
1891
+ "unitless": function(v) {
1892
+ return v;
1893
+ },
1894
+ " ": function(v) {
1895
+ return v;
1896
+ },
1897
+ // speed
1898
+ "knots": import_js_quantities.default.swiftConverter("m/s", "kn"),
1899
+ "kph": import_js_quantities.default.swiftConverter("m/s", "kph"),
1900
+ "m/s": function(v) {
1901
+ return v;
1902
+ },
1903
+ "mph": import_js_quantities.default.swiftConverter("m/s", "mph"),
1904
+ // volume
1905
+ "liter": import_js_quantities.default.swiftConverter("m^3", "liter"),
1906
+ "gallon": import_js_quantities.default.swiftConverter("m^3", "gallon"),
1907
+ "m3": function(v) {
1908
+ return v;
1909
+ },
1910
+ // flow
1911
+ "m3/s": function(v) {
1912
+ return v;
1913
+ },
1914
+ "l/min": import_js_quantities.default.swiftConverter("m^3/s", "liter/minute"),
1915
+ "l/h": import_js_quantities.default.swiftConverter("m^3/s", "liter/hour"),
1916
+ "g/min": import_js_quantities.default.swiftConverter("m^3/s", "gallon/minute"),
1917
+ "g/h": import_js_quantities.default.swiftConverter("m^3/s", "gallon/hour"),
1918
+ // fuel consumption
1919
+ "m/m3": function(v) {
1920
+ return v;
1921
+ },
1922
+ "nm/l": import_js_quantities.default.swiftConverter("m/m^3", "naut-mile/liter"),
1923
+ "nm/g": import_js_quantities.default.swiftConverter("m/m^3", "naut-mile/gallon"),
1924
+ "km/l": import_js_quantities.default.swiftConverter("m/m^3", "km/liter"),
1925
+ "mpg": import_js_quantities.default.swiftConverter("m/m^3", "mile/gallon"),
1926
+ // energy consumption
1927
+ "m/J": function(v) {
1928
+ return v;
1929
+ },
1930
+ "nm/J": import_js_quantities.default.swiftConverter("m/J", "naut-mile/J"),
1931
+ "km/J": import_js_quantities.default.swiftConverter("km/J", "km/J"),
1932
+ "nm/kWh": import_js_quantities.default.swiftConverter("m/J", "naut-mile/kWh"),
1933
+ "km/kWh": import_js_quantities.default.swiftConverter("m/J", "km/kWh"),
1934
+ // temp
1935
+ "K": function(v) {
1936
+ return v;
1937
+ },
1938
+ "celsius": import_js_quantities.default.swiftConverter("tempK", "tempC"),
1939
+ "fahrenheit": import_js_quantities.default.swiftConverter("tempK", "tempF"),
1940
+ // length
1941
+ "m": function(v) {
1942
+ return v;
1943
+ },
1944
+ "mm": function(v) {
1945
+ return v * 1e3;
1946
+ },
1947
+ "fathom": import_js_quantities.default.swiftConverter("m", "fathom"),
1948
+ "feet": import_js_quantities.default.swiftConverter("m", "foot"),
1949
+ "inch": import_js_quantities.default.swiftConverter("m", "in"),
1950
+ "km": import_js_quantities.default.swiftConverter("m", "km"),
1951
+ "nm": import_js_quantities.default.swiftConverter("m", "nmi"),
1952
+ "mi": import_js_quantities.default.swiftConverter("m", "mi"),
1953
+ // Potential
1954
+ "V": function(v) {
1955
+ return v;
1956
+ },
1957
+ "mV": function(v) {
1958
+ return v * 1e3;
1959
+ },
1960
+ // Current
1961
+ "A": function(v) {
1962
+ return v;
1963
+ },
1964
+ "mA": function(v) {
1965
+ return v * 1e3;
1966
+ },
1967
+ // charge
1968
+ "C": function(v) {
1969
+ return v;
1970
+ },
1971
+ "Ah": import_js_quantities.default.swiftConverter("C", "Ah"),
1972
+ // Power
1973
+ "W": function(v) {
1974
+ return v;
1975
+ },
1976
+ "mW": function(v) {
1977
+ return v * 1e3;
1978
+ },
1979
+ // Energy
1980
+ "J": function(v) {
1981
+ return v;
1982
+ },
1983
+ "kWh": import_js_quantities.default.swiftConverter("J", "kWh"),
1984
+ // Resistance
1985
+ "ohm": function(v) {
1986
+ return v;
1987
+ },
1988
+ "kiloohm": function(v) {
1989
+ return v / 1e3;
1990
+ },
1991
+ // pressure
1992
+ "Pa": function(v) {
1993
+ return v;
1994
+ },
1995
+ "bar": import_js_quantities.default.swiftConverter("Pa", "bar"),
1996
+ "psi": import_js_quantities.default.swiftConverter("Pa", "psi"),
1997
+ "mmHg": import_js_quantities.default.swiftConverter("Pa", "mmHg"),
1998
+ "inHg": import_js_quantities.default.swiftConverter("Pa", "inHg"),
1999
+ "hPa": import_js_quantities.default.swiftConverter("Pa", "hPa"),
2000
+ "kPa": import_js_quantities.default.swiftConverter("Pa", "kPa"),
2001
+ "mbar": import_js_quantities.default.swiftConverter("Pa", "millibar"),
2002
+ // Density - Description: Current outside air density
2003
+ "kg/m3": function(v) {
2004
+ return v;
2005
+ },
2006
+ // Time
2007
+ "s": function(v) {
2008
+ return v;
2009
+ },
2010
+ "Minutes": import_js_quantities.default.swiftConverter("s", "minutes"),
2011
+ "Hours": import_js_quantities.default.swiftConverter("s", "hours"),
2012
+ "Days": import_js_quantities.default.swiftConverter("s", "days"),
2013
+ "D HH:MM:SS": function(v) {
2014
+ v = parseInt(v, 10);
2015
+ const isNegative = v < 0;
2016
+ v = Math.abs(v);
2017
+ const days = Math.floor(v / 86400);
2018
+ const h = Math.floor(v % 86400 / 3600);
2019
+ const m = Math.floor(v % 3600 / 60);
2020
+ const s = Math.floor(v % 60);
2021
+ let result = isNegative ? "-" : "";
2022
+ if (days > 0) {
2023
+ result += days + "d " + h.toString() + ":" + m.toString().padStart(2, "0") + ":" + s.toString().padStart(2, "0");
2024
+ } else {
2025
+ result += h.toString() + ":" + m.toString().padStart(2, "0") + ":" + s.toString().padStart(2, "0");
2026
+ }
2027
+ return result;
2028
+ },
2029
+ // angularVelocity
2030
+ "rad/s": function(v) {
2031
+ return v;
2032
+ },
2033
+ "deg/s": import_js_quantities.default.swiftConverter("rad/s", "deg/s"),
2034
+ "deg/min": import_js_quantities.default.swiftConverter("rad/s", "deg/min"),
2035
+ // frequency
2036
+ "rpm": function(v) {
2037
+ return v * 60;
2038
+ },
2039
+ "Hz": function(v) {
2040
+ return v;
2041
+ },
2042
+ "KHz": function(v) {
2043
+ return v / 1e3;
2044
+ },
2045
+ "MHz": function(v) {
2046
+ return v / 1e6;
2047
+ },
2048
+ "GHz": function(v) {
2049
+ return v / 1e9;
2050
+ },
2051
+ // angle
2052
+ "rad": function(v) {
2053
+ return v;
2054
+ },
2055
+ "deg": import_js_quantities.default.swiftConverter("rad", "deg"),
2056
+ "grad": import_js_quantities.default.swiftConverter("rad", "grad"),
2057
+ // ratio
2058
+ "percent": function(v) {
2059
+ return v * 100;
2060
+ },
2061
+ "percentraw": function(v) {
2062
+ return v;
2063
+ },
2064
+ "ratio": function(v) {
2065
+ return v;
2066
+ },
2067
+ // Position Degrees lat/lon
2068
+ "pdeg": function(v) {
2069
+ return v;
2070
+ },
2071
+ // Signal K uses degrees for lat/lon
2072
+ "latitudeMin": function(v) {
2073
+ let degree = Math.trunc(v);
2074
+ let s = "N";
2075
+ if (v < 0) {
2076
+ s = "S";
2077
+ degree = degree * -1;
2078
+ }
2079
+ let r = v % 1 * 60;
2080
+ if (s == "S") {
2081
+ r = r * -1;
2082
+ }
2083
+ return degree + "\xB0 " + r.toFixed(2).padStart(5, "0") + "' " + s;
2084
+ },
2085
+ "latitudeSec": function(v) {
2086
+ let degree = Math.trunc(v);
2087
+ let s = "N";
2088
+ if (v < 0) {
2089
+ s = "S";
2090
+ degree = degree * -1;
2091
+ }
2092
+ let r = v % 1 * 60;
2093
+ if (s == "S") {
2094
+ r = r * -1;
2095
+ }
2096
+ const minutes = Math.trunc(r);
2097
+ const seconds = r % 1 * 60;
2098
+ return degree + "\xB0 " + minutes + "' " + seconds.toFixed(2).padStart(5, "0") + '" ' + s;
2099
+ },
2100
+ "longitudeMin": function(v) {
2101
+ let degree = Math.trunc(v);
2102
+ let s = "E";
2103
+ if (v < 0) {
2104
+ s = "W";
2105
+ degree = degree * -1;
2106
+ }
2107
+ let r = v % 1 * 60;
2108
+ if (s == "W") {
2109
+ r = r * -1;
2110
+ }
2111
+ return degree + "\xB0 " + r.toFixed(2).padStart(5, "0") + "' " + s;
2112
+ },
2113
+ "longitudeSec": function(v) {
2114
+ let degree = Math.trunc(v);
2115
+ let s = "E";
2116
+ if (v < 0) {
2117
+ s = "W";
2118
+ degree = degree * -1;
2119
+ }
2120
+ let r = v % 1 * 60;
2121
+ if (s == "W") {
2122
+ r = r * -1;
2123
+ }
2124
+ const minutes = Math.trunc(r);
2125
+ const seconds = r % 1 * 60;
2126
+ return degree + "\xB0 " + minutes + "' " + seconds.toFixed(2).padStart(5, "0") + '" ' + s;
2127
+ }
2128
+ };
2129
+ /**
2130
+ * Converts any number to the specified unit. The function does not validate if
2131
+ * source and destination units are compatible, ie. kph to degrees will be converted
2132
+ * but will return meaningless results.
2133
+ *
2134
+ * If the unit is not know, or or the value is null, Null will be returned.
2135
+ *
2136
+ * @param {string} unit The conversion type unit
2137
+ * @param {number} value The source value
2138
+ * @return {*} {number} The result of the conversion
2139
+ * @memberof UnitsService
2140
+ */
2141
+ convertToUnit(unit, value) {
2142
+ if (!(unit in this.unitConversionFunctions)) {
2143
+ return null;
2144
+ }
2145
+ if (value === null) {
2146
+ return null;
2147
+ }
2148
+ const num = +value;
2149
+ return this.unitConversionFunctions[unit](num);
2150
+ }
2151
+ /**
2152
+ * Returns the list KIP base unit conversion settings applied before presentation.
2153
+ * See KIP's Units Settings configuration.
2154
+ *
2155
+ * Ex: If a Signal K path's meta Units is set to 'm/s', could KIP automatically
2156
+ * convert to say, 'knots' before presentation. Received Signal K data is always
2157
+ * kept in native format.
2158
+ *
2159
+ * @return {*} {IUnitDefaults}
2160
+ * @memberof UnitsService
2161
+ */
2162
+ getDefaults() {
2163
+ return this._defaultUnits;
2164
+ }
2165
+ /**
2166
+ * Return the list of possible conversions matrix by unit groups. Useful
2167
+ * to present possible conversion or select a conversation units that are
2168
+ * related.
2169
+ *
2170
+ * @return {*} {IUnitGroup[]} an array of units by groups
2171
+ * @memberof UnitsService
2172
+ */
2173
+ getConversions() {
2174
+ return this._conversionList;
2175
+ }
2176
+ /**
2177
+ * Obtain a list of possible Kip value type conversions for a given path. ie,.: Speed conversion group
2178
+ * (kph, Knots, etc.). The conversion list will be trimmed to only the conversions for the group in question.
2179
+ * If a base value type (provided by server) for a path cannot be found,
2180
+ * the full list is returned and with 'unitless' as the base. Same goes if the value type exists,
2181
+ * but Kip does not handle it...yet.
2182
+ *
2183
+ * @param path The Signal K path of the value
2184
+ * @return conversions Full list array or subset of list array
2185
+ */
2186
+ getConversionsForPath(path) {
2187
+ const pathUnitType = this.data.getPathUnitType(path);
2188
+ const UNITLESS = "unitless";
2189
+ let defaultUnit = "unitless";
2190
+ if (pathUnitType === null || pathUnitType === "RFC 3339 (UTC)") {
2191
+ return { base: UNITLESS, conversions: this._conversionList };
2192
+ } else {
2193
+ const groupList = this._conversionList.filter((unitGroup) => {
2194
+ if (unitGroup.group == "Position" && (path.includes("position.latitude") || path.includes("position.longitude"))) {
2195
+ return true;
2196
+ }
2197
+ const unitExists = unitGroup.units.find((unit) => unit.measure == pathUnitType);
2198
+ if (unitExists) {
2199
+ defaultUnit = this._defaultUnits[unitGroup.group];
2200
+ return true;
2201
+ }
2202
+ return false;
2203
+ });
2204
+ if (groupList.length > 0) {
2205
+ return { base: defaultUnit, conversions: groupList };
2206
+ }
2207
+ console.log("[Units Service] Unit type: " + pathUnitType + ", found for path: " + path + "\nbut Kip does not support it.");
2208
+ return { base: UNITLESS, conversions: this._conversionList };
2209
+ }
2210
+ }
2211
+ ngOnDestroy() {
2212
+ this._defaultUnitsSub?.unsubscribe();
2213
+ }
2214
+ static \u0275fac = function UnitsService_Factory(__ngFactoryType__) {
2215
+ return new (__ngFactoryType__ || _UnitsService)();
2216
+ };
2217
+ static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _UnitsService, factory: _UnitsService.\u0275fac });
2218
+ };
2219
+ (() => {
2220
+ (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(UnitsService, [{
2221
+ type: Injectable
2222
+ }], () => [], null);
2223
+ })();
2224
+
2225
+ export {
2226
+ UnitsService
2227
+ };
2228
+ //# sourceMappingURL=chunk-E24UNLSJ.js.map