@lhncbc/ucum-lhc 4.1.7 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser-dist/ucum-lhc.js +156 -52
- package/package.json +2 -1
- package/source/config.js +3 -2
- package/source/ucumLhcUtils.js +70 -0
- package/source/unit.js +28 -34
- package/source/unitString.js +29 -13
- package/source/unitTables.js +14 -0
- package/source-cjs/config.js +2 -2
- package/source-cjs/config.js.map +1 -1
- package/source-cjs/ucumLhcUtils.js +70 -0
- package/source-cjs/ucumLhcUtils.js.map +1 -1
- package/source-cjs/unit.js +27 -36
- package/source-cjs/unit.js.map +1 -1
- package/source-cjs/unitString.js +29 -9
- package/source-cjs/unitString.js.map +1 -1
- package/source-cjs/unitTables.js +16 -0
- package/source-cjs/unitTables.js.map +1 -1
- package/CHANGELOG.md +0 -329
package/browser-dist/ucum-lhc.js
CHANGED
|
@@ -86,14 +86,14 @@ var Ucum = {
|
|
|
86
86
|
* displaying messages on a web site; should be blank when output is
|
|
87
87
|
* to a file.
|
|
88
88
|
*/
|
|
89
|
-
openEmphHTML_: '<span class="emphSpan">',
|
|
89
|
+
openEmphHTML_: ' <span class="emphSpan">',
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* Closing HTML used to emphasize portions of error messages. Used when
|
|
93
93
|
* displaying messages on a web site; should be blank when output is
|
|
94
94
|
* to a file.
|
|
95
95
|
*/
|
|
96
|
-
closeEmphHTML_: '</span>',
|
|
96
|
+
closeEmphHTML_: '</span> ',
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Message that is displayed when annotations are included in a unit
|
|
@@ -1817,6 +1817,81 @@ var UcumLhcUtils = /*#__PURE__*/function () {
|
|
|
1817
1817
|
return returnObj;
|
|
1818
1818
|
} // end convertUnitTo
|
|
1819
1819
|
|
|
1820
|
+
/**
|
|
1821
|
+
* Converts the given unit string into its base units, their exponents, and
|
|
1822
|
+
* a magnitude, and returns that data.
|
|
1823
|
+
* @param fromUnit the unit string to be converted to base units information
|
|
1824
|
+
* @param fromVal the number of "from" units to be converted
|
|
1825
|
+
* @returns an object with the properties:
|
|
1826
|
+
* 'msg': an array of one or more messages, if the string is invalid or
|
|
1827
|
+
* an error occurred, indicating the problem, or a suggestion of a
|
|
1828
|
+
* substitution such as the substitution of 'G' for 'Gauss', or
|
|
1829
|
+
* an empty array if no messages were generated. If this is not empty,
|
|
1830
|
+
* no other information will be returned.
|
|
1831
|
+
* 'magnitude': the new value when fromVal units of fromUnits is expressed in the base units.
|
|
1832
|
+
* 'fromUnitIsSpecial': whether the input unit fromUnit is a "special unit"
|
|
1833
|
+
* as defined in UCUM. This means there is some function applied to convert
|
|
1834
|
+
* between fromUnit and the base units, so the returned magnitude is likely not
|
|
1835
|
+
* useful as a scale factor for other conversions (i.e., it only has validity
|
|
1836
|
+
* and usefulness for the input values that produced it).
|
|
1837
|
+
* 'unitToExp': a map of base units in uStr to their exponent
|
|
1838
|
+
*/
|
|
1839
|
+
|
|
1840
|
+
}, {
|
|
1841
|
+
key: "convertToBaseUnits",
|
|
1842
|
+
value: function convertToBaseUnits(fromUnit, fromVal) {
|
|
1843
|
+
var inputUnitLookup = this.getSpecifiedUnit(fromUnit, 'validate');
|
|
1844
|
+
var retObj = {};
|
|
1845
|
+
var unit = inputUnitLookup.unit;
|
|
1846
|
+
retObj.msg = inputUnitLookup.retMsg || [];
|
|
1847
|
+
|
|
1848
|
+
if (!unit) {
|
|
1849
|
+
var _inputUnitLookup$retM;
|
|
1850
|
+
|
|
1851
|
+
if (((_inputUnitLookup$retM = inputUnitLookup.retMsg) === null || _inputUnitLookup$retM === void 0 ? void 0 : _inputUnitLookup$retM.length) == 0) retObj.msg.push('Could not find unit information for ' + fromUnit);
|
|
1852
|
+
} else if (unit.isArbitrary_) {
|
|
1853
|
+
retObj.msg.push('Arbitrary units cannot be converted to base units or other units.');
|
|
1854
|
+
} else if (retObj.msg.length == 0) {
|
|
1855
|
+
var _unit$dim_, _retUnitLookup$retMsg;
|
|
1856
|
+
|
|
1857
|
+
var unitToExp = {};
|
|
1858
|
+
var dimVec = (_unit$dim_ = unit.dim_) === null || _unit$dim_ === void 0 ? void 0 : _unit$dim_.dimVec_;
|
|
1859
|
+
var baseUnitString = '1';
|
|
1860
|
+
|
|
1861
|
+
if (dimVec) {
|
|
1862
|
+
var dimVecIndexToBaseUnit = UnitTables.getInstance().dimVecIndexToBaseUnit_;
|
|
1863
|
+
|
|
1864
|
+
for (var i = 0, len = dimVec.length; i < len; ++i) {
|
|
1865
|
+
var exp = dimVec[i];
|
|
1866
|
+
|
|
1867
|
+
if (exp) {
|
|
1868
|
+
unitToExp[dimVecIndexToBaseUnit[i]] = exp;
|
|
1869
|
+
baseUnitString += '.' + dimVecIndexToBaseUnit[i] + exp;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
} // The unit might have a conversion function, which has to be applied; we
|
|
1873
|
+
// cannot just assume unit_.magnitude_ is the magnitude in base units.
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
var retUnitLookup = this.getSpecifiedUnit(baseUnitString, 'validate'); // There should not be any error in retUnitLookup, unless there is a bug.
|
|
1877
|
+
|
|
1878
|
+
var retUnit = retUnitLookup.unit;
|
|
1879
|
+
if (!retUnit && ((_retUnitLookup$retMsg = retUnitLookup.retMsg) === null || _retUnitLookup$retMsg === void 0 ? void 0 : _retUnitLookup$retMsg.length) == 0) retObj.msg.push('Unable construct base unit string; tried ' + baseUnitString);else {
|
|
1880
|
+
try {
|
|
1881
|
+
retObj.magnitude = retUnit.convertFrom(fromVal, unit);
|
|
1882
|
+
} catch (e) {
|
|
1883
|
+
retObj.msg.push(e.toString());
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
if (retObj.msg.length == 0) {
|
|
1887
|
+
retObj.unitToExp = unitToExp;
|
|
1888
|
+
retObj.fromUnitIsSpecial = unit.isSpecial_;
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
return retObj;
|
|
1894
|
+
}
|
|
1820
1895
|
/**
|
|
1821
1896
|
* This method accepts a term and looks for units that include it as
|
|
1822
1897
|
* a synonym - or that include the term in its name.
|
|
@@ -2419,8 +2494,8 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2419
2494
|
key: "convertFrom",
|
|
2420
2495
|
value: function convertFrom(num, fromUnit) {
|
|
2421
2496
|
var newNum = 0.0;
|
|
2422
|
-
if (this.isArbitrary_) throw new Error("Attempt to convert arbitrary unit ".concat(this.
|
|
2423
|
-
if (fromUnit.isArbitrary_) throw new Error("Attempt to convert
|
|
2497
|
+
if (this.isArbitrary_) throw new Error("Attempt to convert to arbitrary unit \"".concat(this.csCode_, "\""));
|
|
2498
|
+
if (fromUnit.isArbitrary_) throw new Error("Attempt to convert arbitrary unit \"".concat(fromUnit.csCode_, "\"")); // reject request if both units have dimensions that are not equal
|
|
2424
2499
|
|
|
2425
2500
|
if (fromUnit.dim_ && this.dim_ && !fromUnit.dim_.equals(this.dim_)) {
|
|
2426
2501
|
// check first to see if a mole<->mass conversion is appropriate
|
|
@@ -2442,40 +2517,28 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2442
2517
|
}
|
|
2443
2518
|
|
|
2444
2519
|
var fromCnv = fromUnit.cnv_;
|
|
2445
|
-
var fromMag = fromUnit.magnitude_;
|
|
2446
|
-
|
|
2447
|
-
// "from" unit's magnitude by the number passed in and then divide
|
|
2448
|
-
// that result by this unit's magnitude. Do this for units with
|
|
2449
|
-
// and without dimension vectors. PROBLEM with 2 non-commensurable
|
|
2450
|
-
// units with no dimension vector or function, e.g., byte to mol
|
|
2451
|
-
|
|
2452
|
-
if (fromCnv === this.cnv_) {
|
|
2453
|
-
newNum = num * fromMag / this.magnitude_;
|
|
2454
|
-
} // else use a function to get the number to be returned
|
|
2455
|
-
else {
|
|
2456
|
-
var x = 0.0;
|
|
2457
|
-
|
|
2458
|
-
if (fromCnv != null) {
|
|
2459
|
-
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
2460
|
-
// e.g., convert Celsius to Kelvin
|
|
2461
|
-
var fromFunc = _ucumFunctions.default.forName(fromCnv);
|
|
2520
|
+
var fromMag = fromUnit.magnitude_;
|
|
2521
|
+
var x;
|
|
2462
2522
|
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2523
|
+
if (fromCnv != null) {
|
|
2524
|
+
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
2525
|
+
// e.g., convert Celsius to Kelvin
|
|
2526
|
+
var fromFunc = _ucumFunctions.default.forName(fromCnv);
|
|
2467
2527
|
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2528
|
+
x = fromFunc.cnvFrom(num * fromUnit.cnvPfx_) * fromMag; //x = fromFunc.cnvFrom(num * fromMag) * fromUnit.cnvPfx_;
|
|
2529
|
+
} else {
|
|
2530
|
+
x = num * fromMag;
|
|
2531
|
+
}
|
|
2472
2532
|
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
} // end if either unit has a conversion function
|
|
2533
|
+
if (this.cnv_ != null) {
|
|
2534
|
+
// turn mag * origUnit on ratio scale into a non-ratio unit,
|
|
2535
|
+
// e.g. convert Kelvin to Fahrenheit
|
|
2536
|
+
var toFunc = _ucumFunctions.default.forName(this.cnv_);
|
|
2478
2537
|
|
|
2538
|
+
newNum = toFunc.cnvTo(x / this.magnitude_) / this.cnvPfx_;
|
|
2539
|
+
} else {
|
|
2540
|
+
newNum = x / this.magnitude_;
|
|
2541
|
+
}
|
|
2479
2542
|
|
|
2480
2543
|
return newNum;
|
|
2481
2544
|
} // end convertFrom
|
|
@@ -2690,6 +2753,7 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2690
2753
|
else if (unit2.cnv_ != null) {
|
|
2691
2754
|
if (!retUnit.dim_ || retUnit.dim_.isZero()) {
|
|
2692
2755
|
retUnit.cnvPfx_ = unit2.cnvPfx_ * retUnit.magnitude_;
|
|
2756
|
+
retUnit.magnitude_ = unit2.magnitude_;
|
|
2693
2757
|
retUnit.cnv_ = unit2.cnv_;
|
|
2694
2758
|
} else throw new Error("Attempt to multiply non-ratio unit ".concat(unit2.name_));
|
|
2695
2759
|
} // end if unit2 has a conversion function
|
|
@@ -2723,7 +2787,9 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2723
2787
|
// if (!retUnit.isMole_)
|
|
2724
2788
|
// retUnit.isMole_ = unit2.isMole_ ;
|
|
2725
2789
|
|
|
2726
|
-
if (!retUnit.isArbitrary_) retUnit.isArbitrary_ = unit2.isArbitrary_;
|
|
2790
|
+
if (!retUnit.isArbitrary_) retUnit.isArbitrary_ = unit2.isArbitrary_; // Likewise for special units
|
|
2791
|
+
|
|
2792
|
+
if (!retUnit.isSpecial_) retUnit.isSpecial_ = unit2.isSpecial_;
|
|
2727
2793
|
return retUnit;
|
|
2728
2794
|
} // end multiplyThese
|
|
2729
2795
|
|
|
@@ -3073,6 +3139,8 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
|
|
|
3073
3139
|
|
|
3074
3140
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
3075
3141
|
|
|
3142
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
3143
|
+
|
|
3076
3144
|
/**
|
|
3077
3145
|
* This class handles the parsing of a unit string into a unit object
|
|
3078
3146
|
*/
|
|
@@ -3128,18 +3196,19 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
3128
3196
|
|
|
3129
3197
|
this.suggestions = [];
|
|
3130
3198
|
} // end constructor
|
|
3131
|
-
|
|
3132
|
-
/**
|
|
3133
|
-
* Sets the emphasis strings to the HTML used in the webpage display - or
|
|
3134
|
-
* blanks them out, depending on the use parameter.
|
|
3135
|
-
*
|
|
3136
|
-
* @param use flag indicating whether or not to use the html message format;
|
|
3137
|
-
* defaults to true
|
|
3138
|
-
*/
|
|
3199
|
+
// The start of an error message about an invalid annotation character.
|
|
3139
3200
|
|
|
3140
3201
|
|
|
3141
3202
|
_createClass(UnitString, [{
|
|
3142
3203
|
key: "useHTMLInMessages",
|
|
3204
|
+
|
|
3205
|
+
/**
|
|
3206
|
+
* Sets the emphasis strings to the HTML used in the webpage display - or
|
|
3207
|
+
* blanks them out, depending on the use parameter.
|
|
3208
|
+
*
|
|
3209
|
+
* @param use flag indicating whether or not to use the html message format;
|
|
3210
|
+
* defaults to true
|
|
3211
|
+
*/
|
|
3143
3212
|
value: function useHTMLInMessages(use) {
|
|
3144
3213
|
if (use === undefined || use) {
|
|
3145
3214
|
this.openEmph_ = Ucum.openEmphHTML_;
|
|
@@ -3277,6 +3346,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
3277
3346
|
if (intUtils_.isIntegerUnit(finalUnit) || typeof finalUnit === 'number') {
|
|
3278
3347
|
finalUnit = new Unit({
|
|
3279
3348
|
'csCode_': origString,
|
|
3349
|
+
'ciCode_': origString,
|
|
3280
3350
|
'magnitude_': finalUnit,
|
|
3281
3351
|
'name_': origString
|
|
3282
3352
|
});
|
|
@@ -3435,24 +3505,35 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
3435
3505
|
var openBrace = uString.indexOf('{');
|
|
3436
3506
|
|
|
3437
3507
|
while (openBrace >= 0) {
|
|
3438
|
-
var
|
|
3508
|
+
var closeBrace = uString.indexOf('}');
|
|
3439
3509
|
|
|
3440
|
-
if (
|
|
3510
|
+
if (closeBrace < 0) {
|
|
3441
3511
|
this.retMsg_.push('Missing closing brace for annotation starting at ' + this.openEmph_ + uString.substr(openBrace) + this.closeEmph_);
|
|
3442
3512
|
openBrace = -1;
|
|
3443
3513
|
} else {
|
|
3444
|
-
var braceStr = uString.substring(openBrace,
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3514
|
+
var braceStr = uString.substring(openBrace, closeBrace + 1); // Check for valid characters in the annotation.
|
|
3515
|
+
|
|
3516
|
+
if (!UnitString.VALID_ANNOTATION_REGEX.test(braceStr)) {
|
|
3517
|
+
this.retMsg_.push(UnitString.INVALID_ANNOTATION_CHAR_MSG + this.openEmph_ + braceStr + this.closeEmph_);
|
|
3518
|
+
openBrace = -1; // end search for annotations
|
|
3519
|
+
} else {
|
|
3520
|
+
var aIdx = this.annotations_.length.toString();
|
|
3521
|
+
uString = uString.replace(braceStr, this.braceFlag_ + aIdx + this.braceFlag_);
|
|
3522
|
+
this.annotations_.push(braceStr);
|
|
3523
|
+
openBrace = uString.indexOf('{');
|
|
3524
|
+
}
|
|
3449
3525
|
}
|
|
3450
3526
|
} // end do while we have an opening brace
|
|
3451
3527
|
// check for a stray/unmatched closing brace
|
|
3452
3528
|
|
|
3453
3529
|
|
|
3454
|
-
|
|
3455
|
-
|
|
3530
|
+
if (this.retMsg_.length == 0) {
|
|
3531
|
+
// if there were no other errors above
|
|
3532
|
+
var _closeBrace = uString.indexOf('}');
|
|
3533
|
+
|
|
3534
|
+
if (_closeBrace >= 0) this.retMsg_.push('Missing opening brace for closing brace found at ' + this.openEmph_ + uString.substring(0, _closeBrace + 1) + this.closeEmph_);
|
|
3535
|
+
}
|
|
3536
|
+
|
|
3456
3537
|
return uString;
|
|
3457
3538
|
} // end _getAnnotations
|
|
3458
3539
|
|
|
@@ -4480,6 +4561,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4480
4561
|
if (intUtils_.isIntegerUnit(finalUnit)) {
|
|
4481
4562
|
finalUnit = new Unit({
|
|
4482
4563
|
'csCode_': finalUnit,
|
|
4564
|
+
'ciCode_': finalUnit,
|
|
4483
4565
|
'magnitude_': Number(finalUnit),
|
|
4484
4566
|
'name_': finalUnit
|
|
4485
4567
|
});
|
|
@@ -4495,6 +4577,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4495
4577
|
if (intUtils_.isIntegerUnit(nextUnit)) {
|
|
4496
4578
|
nextUnit = new Unit({
|
|
4497
4579
|
'csCode_': nextUnit,
|
|
4580
|
+
'ciCode_': nextUnit,
|
|
4498
4581
|
'magnitude_': Number(nextUnit),
|
|
4499
4582
|
'name_': nextUnit
|
|
4500
4583
|
});
|
|
@@ -4594,6 +4677,11 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4594
4677
|
|
|
4595
4678
|
exports.UnitString = UnitString;
|
|
4596
4679
|
|
|
4680
|
+
_defineProperty(UnitString, "INVALID_ANNOTATION_CHAR_MSG", 'An invalid character was found in the annotation ');
|
|
4681
|
+
|
|
4682
|
+
// A regular expression for validating annotation strings.
|
|
4683
|
+
_defineProperty(UnitString, "VALID_ANNOTATION_REGEX", /^\{[!-z|~]*\}$/);
|
|
4684
|
+
|
|
4597
4685
|
UnitString.getInstance = function () {
|
|
4598
4686
|
return new UnitString();
|
|
4599
4687
|
};
|
|
@@ -4715,6 +4803,11 @@ var UnitTablesFactory = /*#__PURE__*/function () {
|
|
|
4715
4803
|
*/
|
|
4716
4804
|
|
|
4717
4805
|
this.massDimIndex_ = 0;
|
|
4806
|
+
/**
|
|
4807
|
+
* Map of indices in the dimension vector to base unit symbols.
|
|
4808
|
+
*/
|
|
4809
|
+
|
|
4810
|
+
this.dimVecIndexToBaseUnit_ = {};
|
|
4718
4811
|
}
|
|
4719
4812
|
/**
|
|
4720
4813
|
* Provides the number of unit objects written to the tables, using the
|
|
@@ -4755,6 +4848,17 @@ var UnitTablesFactory = /*#__PURE__*/function () {
|
|
|
4755
4848
|
} catch (err) {// do nothing - throws error if the property is null
|
|
4756
4849
|
// and that's OK here.
|
|
4757
4850
|
}
|
|
4851
|
+
|
|
4852
|
+
if (theUnit.isBase_) {
|
|
4853
|
+
var dimVec = theUnit.dim_.dimVec_;
|
|
4854
|
+
var nonZeroIndex;
|
|
4855
|
+
|
|
4856
|
+
for (var i = 0, len = dimVec.length; nonZeroIndex == undefined && i < len; ++i) {
|
|
4857
|
+
if (dimVec[i] != 0) nonZeroIndex = i;
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4860
|
+
this.dimVecIndexToBaseUnit_[nonZeroIndex] = theUnit.csCode_;
|
|
4861
|
+
}
|
|
4758
4862
|
} // end addUnit
|
|
4759
4863
|
|
|
4760
4864
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lhncbc/ucum-lhc",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Implements Unified Code for Units of Measure (UCUM) functions in a javascript library",
|
|
5
5
|
"main": "source-cjs/ucumPkg.js",
|
|
6
6
|
"homepage": "https://lhncbc.github.io/ucum-lhc/",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@babel/cli": "^7.19.3",
|
|
30
30
|
"@babel/core": "^7.3.4",
|
|
31
|
+
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
31
32
|
"@babel/plugin-transform-modules-commonjs": "^7.8.3",
|
|
32
33
|
"@babel/preset-env": "^7.6.2",
|
|
33
34
|
"@babel/register": "^7.6.2",
|
package/source/config.js
CHANGED
|
@@ -24,6 +24,7 @@ export var Ucum = {
|
|
|
24
24
|
*/
|
|
25
25
|
dimLen_: 7,
|
|
26
26
|
|
|
27
|
+
|
|
27
28
|
/**
|
|
28
29
|
* The characters used as valid operators in a UCUM unit expression,
|
|
29
30
|
* where '.' is for multiplication and '/' is for division.
|
|
@@ -63,14 +64,14 @@ export var Ucum = {
|
|
|
63
64
|
* displaying messages on a web site; should be blank when output is
|
|
64
65
|
* to a file.
|
|
65
66
|
*/
|
|
66
|
-
openEmphHTML_ : '<span class="emphSpan">',
|
|
67
|
+
openEmphHTML_ : ' <span class="emphSpan">',
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
70
|
* Closing HTML used to emphasize portions of error messages. Used when
|
|
70
71
|
* displaying messages on a web site; should be blank when output is
|
|
71
72
|
* to a file.
|
|
72
73
|
*/
|
|
73
|
-
closeEmphHTML_ : '</span>' ,
|
|
74
|
+
closeEmphHTML_ : '</span> ' ,
|
|
74
75
|
|
|
75
76
|
/**
|
|
76
77
|
* Message that is displayed when annotations are included in a unit
|
package/source/ucumLhcUtils.js
CHANGED
|
@@ -337,6 +337,76 @@ export class UcumLhcUtils {
|
|
|
337
337
|
} // end convertUnitTo
|
|
338
338
|
|
|
339
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Converts the given unit string into its base units, their exponents, and
|
|
342
|
+
* a magnitude, and returns that data.
|
|
343
|
+
* @param fromUnit the unit string to be converted to base units information
|
|
344
|
+
* @param fromVal the number of "from" units to be converted
|
|
345
|
+
* @returns an object with the properties:
|
|
346
|
+
* 'msg': an array of one or more messages, if the string is invalid or
|
|
347
|
+
* an error occurred, indicating the problem, or a suggestion of a
|
|
348
|
+
* substitution such as the substitution of 'G' for 'Gauss', or
|
|
349
|
+
* an empty array if no messages were generated. If this is not empty,
|
|
350
|
+
* no other information will be returned.
|
|
351
|
+
* 'magnitude': the new value when fromVal units of fromUnits is expressed in the base units.
|
|
352
|
+
* 'fromUnitIsSpecial': whether the input unit fromUnit is a "special unit"
|
|
353
|
+
* as defined in UCUM. This means there is some function applied to convert
|
|
354
|
+
* between fromUnit and the base units, so the returned magnitude is likely not
|
|
355
|
+
* useful as a scale factor for other conversions (i.e., it only has validity
|
|
356
|
+
* and usefulness for the input values that produced it).
|
|
357
|
+
* 'unitToExp': a map of base units in uStr to their exponent
|
|
358
|
+
*/
|
|
359
|
+
convertToBaseUnits(fromUnit, fromVal) {
|
|
360
|
+
let inputUnitLookup = this.getSpecifiedUnit(fromUnit, 'validate');
|
|
361
|
+
let retObj = {};
|
|
362
|
+
let unit = inputUnitLookup.unit;
|
|
363
|
+
retObj.msg = inputUnitLookup.retMsg || [];
|
|
364
|
+
if (!unit) {
|
|
365
|
+
if (inputUnitLookup.retMsg?.length == 0)
|
|
366
|
+
retObj.msg.push('Could not find unit information for '+fromUnit);
|
|
367
|
+
}
|
|
368
|
+
else if (unit.isArbitrary_) {
|
|
369
|
+
retObj.msg.push('Arbitrary units cannot be converted to base units or other units.');
|
|
370
|
+
}
|
|
371
|
+
else if (retObj.msg.length == 0) {
|
|
372
|
+
let unitToExp = {};
|
|
373
|
+
let dimVec = unit.dim_?.dimVec_
|
|
374
|
+
let baseUnitString = '1';
|
|
375
|
+
if (dimVec) {
|
|
376
|
+
let dimVecIndexToBaseUnit = UnitTables.getInstance().dimVecIndexToBaseUnit_;
|
|
377
|
+
for (let i=0, len=dimVec.length; i<len; ++i) {
|
|
378
|
+
let exp = dimVec[i];
|
|
379
|
+
if (exp) {
|
|
380
|
+
unitToExp[dimVecIndexToBaseUnit[i]] = exp;
|
|
381
|
+
baseUnitString += '.' + dimVecIndexToBaseUnit[i] + exp;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// The unit might have a conversion function, which has to be applied; we
|
|
387
|
+
// cannot just assume unit_.magnitude_ is the magnitude in base units.
|
|
388
|
+
let retUnitLookup = this.getSpecifiedUnit(baseUnitString, 'validate');
|
|
389
|
+
// There should not be any error in retUnitLookup, unless there is a bug.
|
|
390
|
+
let retUnit = retUnitLookup.unit;
|
|
391
|
+
if (!retUnit && retUnitLookup.retMsg?.length == 0)
|
|
392
|
+
retObj.msg.push('Unable construct base unit string; tried '+baseUnitString);
|
|
393
|
+
else {
|
|
394
|
+
try {
|
|
395
|
+
retObj.magnitude = retUnit.convertFrom(fromVal, unit);
|
|
396
|
+
}
|
|
397
|
+
catch (e) {
|
|
398
|
+
retObj.msg.push(e.toString());
|
|
399
|
+
}
|
|
400
|
+
if (retObj.msg.length == 0) {
|
|
401
|
+
retObj.unitToExp = unitToExp;
|
|
402
|
+
retObj.fromUnitIsSpecial = unit.isSpecial_;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return retObj;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
340
410
|
/**
|
|
341
411
|
* This method accepts a term and looks for units that include it as
|
|
342
412
|
* a synonym - or that include the term in its name.
|
package/source/unit.js
CHANGED
|
@@ -340,6 +340,7 @@ export class Unit {
|
|
|
340
340
|
return match ;
|
|
341
341
|
}// end of fullEquals
|
|
342
342
|
|
|
343
|
+
|
|
343
344
|
/**
|
|
344
345
|
* This returns the value of the property named by the parameter
|
|
345
346
|
* passed in.
|
|
@@ -380,9 +381,9 @@ export class Unit {
|
|
|
380
381
|
let newNum = 0.0 ;
|
|
381
382
|
|
|
382
383
|
if (this.isArbitrary_)
|
|
383
|
-
throw (new Error(`Attempt to convert arbitrary unit ${this.
|
|
384
|
+
throw (new Error(`Attempt to convert to arbitrary unit "${this.csCode_}"`));
|
|
384
385
|
if (fromUnit.isArbitrary_)
|
|
385
|
-
throw (new Error(`Attempt to convert
|
|
386
|
+
throw (new Error(`Attempt to convert arbitrary unit "${fromUnit.csCode_}"`));
|
|
386
387
|
|
|
387
388
|
// reject request if both units have dimensions that are not equal
|
|
388
389
|
if (fromUnit.dim_ && this.dim_ && !(fromUnit.dim_.equals(this.dim_))) {
|
|
@@ -410,39 +411,27 @@ export class Unit {
|
|
|
410
411
|
let fromCnv = fromUnit.cnv_ ;
|
|
411
412
|
let fromMag = fromUnit.magnitude_ ;
|
|
412
413
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
newNum = (num * fromMag) / this.magnitude_;
|
|
414
|
+
let x;
|
|
415
|
+
if (fromCnv != null) {
|
|
416
|
+
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
417
|
+
// e.g., convert Celsius to Kelvin
|
|
418
|
+
let fromFunc = funcs.forName(fromCnv);
|
|
419
|
+
x = fromFunc.cnvFrom(num * fromUnit.cnvPfx_) * fromMag;
|
|
420
|
+
//x = fromFunc.cnvFrom(num * fromMag) * fromUnit.cnvPfx_;
|
|
421
421
|
}
|
|
422
|
-
// else use a function to get the number to be returned
|
|
423
422
|
else {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
427
|
-
// e.g., convert Celsius to Kelvin
|
|
428
|
-
let fromFunc = funcs.forName(fromCnv);
|
|
429
|
-
x = fromFunc.cnvFrom(num * fromUnit.cnvPfx_) * fromMag;
|
|
430
|
-
//x = fromFunc.cnvFrom(num * fromMag) * fromUnit.cnvPfx_;
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
x = num * fromMag;
|
|
434
|
-
}
|
|
423
|
+
x = num * fromMag;
|
|
424
|
+
}
|
|
435
425
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
} // end if either unit has a conversion function
|
|
426
|
+
if (this.cnv_ != null) {
|
|
427
|
+
// turn mag * origUnit on ratio scale into a non-ratio unit,
|
|
428
|
+
// e.g. convert Kelvin to Fahrenheit
|
|
429
|
+
let toFunc = funcs.forName(this.cnv_);
|
|
430
|
+
newNum = toFunc.cnvTo(x / this.magnitude_) / this.cnvPfx_;
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
newNum = x / this.magnitude_;
|
|
434
|
+
}
|
|
446
435
|
|
|
447
436
|
return newNum;
|
|
448
437
|
|
|
@@ -666,6 +655,7 @@ export class Unit {
|
|
|
666
655
|
else if (unit2.cnv_ != null) {
|
|
667
656
|
if (!retUnit.dim_ || retUnit.dim_.isZero()) {
|
|
668
657
|
retUnit.cnvPfx_ = unit2.cnvPfx_ * retUnit.magnitude_;
|
|
658
|
+
retUnit.magnitude_ = unit2.magnitude_;
|
|
669
659
|
retUnit.cnv_ = unit2.cnv_ ;
|
|
670
660
|
}
|
|
671
661
|
else
|
|
@@ -716,8 +706,12 @@ export class Unit {
|
|
|
716
706
|
// via an arithmetic operation. Taint accordingly
|
|
717
707
|
// if (!retUnit.isMole_)
|
|
718
708
|
// retUnit.isMole_ = unit2.isMole_ ;
|
|
719
|
-
|
|
720
|
-
|
|
709
|
+
if (!retUnit.isArbitrary_)
|
|
710
|
+
retUnit.isArbitrary_ = unit2.isArbitrary_;
|
|
711
|
+
|
|
712
|
+
// Likewise for special units
|
|
713
|
+
if (!retUnit.isSpecial_)
|
|
714
|
+
retUnit.isSpecial_ = unit2.isSpecial_;
|
|
721
715
|
|
|
722
716
|
return retUnit ;
|
|
723
717
|
|
package/source/unitString.js
CHANGED
|
@@ -59,10 +59,15 @@ export class UnitString {
|
|
|
59
59
|
|
|
60
60
|
// suggestions for unit strings that for which no unit was found
|
|
61
61
|
this.suggestions = [] ;
|
|
62
|
-
|
|
63
62
|
} // end constructor
|
|
64
63
|
|
|
65
64
|
|
|
65
|
+
// The start of an error message about an invalid annotation character.
|
|
66
|
+
static INVALID_ANNOTATION_CHAR_MSG = 'An invalid character was found in the annotation ';
|
|
67
|
+
|
|
68
|
+
// A regular expression for validating annotation strings.
|
|
69
|
+
static VALID_ANNOTATION_REGEX = /^\{[!-z|~]*\}$/;
|
|
70
|
+
|
|
66
71
|
/**
|
|
67
72
|
* Sets the emphasis strings to the HTML used in the webpage display - or
|
|
68
73
|
* blanks them out, depending on the use parameter.
|
|
@@ -213,6 +218,7 @@ export class UnitString {
|
|
|
213
218
|
if (intUtils_.isIntegerUnit(finalUnit) || typeof finalUnit === 'number') {
|
|
214
219
|
finalUnit = new Unit({
|
|
215
220
|
'csCode_': origString,
|
|
221
|
+
'ciCode_': origString,
|
|
216
222
|
'magnitude_': finalUnit,
|
|
217
223
|
'name_': origString
|
|
218
224
|
});
|
|
@@ -383,20 +389,30 @@ export class UnitString {
|
|
|
383
389
|
}
|
|
384
390
|
else {
|
|
385
391
|
let braceStr = uString.substring(openBrace, closeBrace + 1);
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
this.
|
|
389
|
-
|
|
390
|
-
|
|
392
|
+
// Check for valid characters in the annotation.
|
|
393
|
+
if (!UnitString.VALID_ANNOTATION_REGEX.test(braceStr)) {
|
|
394
|
+
this.retMsg_.push(UnitString.INVALID_ANNOTATION_CHAR_MSG +
|
|
395
|
+
this.openEmph_ + braceStr + this.closeEmph_);
|
|
396
|
+
openBrace = -1; // end search for annotations
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
let aIdx = this.annotations_.length.toString();
|
|
400
|
+
uString = uString.replace(braceStr, this.braceFlag_ + aIdx +
|
|
401
|
+
this.braceFlag_);
|
|
402
|
+
this.annotations_.push(braceStr);
|
|
403
|
+
openBrace = uString.indexOf('{');
|
|
404
|
+
}
|
|
391
405
|
}
|
|
392
406
|
} // end do while we have an opening brace
|
|
393
407
|
|
|
394
408
|
// check for a stray/unmatched closing brace
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
this.
|
|
399
|
-
|
|
409
|
+
if (this.retMsg_.length == 0) { // if there were no other errors above
|
|
410
|
+
let closeBrace = uString.indexOf('}');
|
|
411
|
+
if (closeBrace >= 0)
|
|
412
|
+
this.retMsg_.push('Missing opening brace for closing brace found at ' +
|
|
413
|
+
this.openEmph_ + uString.substring(0, closeBrace + 1) +
|
|
414
|
+
this.closeEmph_);
|
|
415
|
+
}
|
|
400
416
|
return uString;
|
|
401
417
|
} // end _getAnnotations
|
|
402
418
|
|
|
@@ -1427,7 +1443,7 @@ export class UnitString {
|
|
|
1427
1443
|
|
|
1428
1444
|
let finalUnit = uArray[0]['un'];
|
|
1429
1445
|
if (intUtils_.isIntegerUnit(finalUnit)) {
|
|
1430
|
-
finalUnit = new Unit({'csCode_' : finalUnit,
|
|
1446
|
+
finalUnit = new Unit({'csCode_' : finalUnit, 'ciCode_' : finalUnit,
|
|
1431
1447
|
'magnitude_' : Number(finalUnit),
|
|
1432
1448
|
'name_' : finalUnit}) ;
|
|
1433
1449
|
}
|
|
@@ -1438,7 +1454,7 @@ export class UnitString {
|
|
|
1438
1454
|
for (let u2 = 1; (u2 < uLen) && !endProcessing; u2++) {
|
|
1439
1455
|
let nextUnit = uArray[u2]['un'];
|
|
1440
1456
|
if (intUtils_.isIntegerUnit(nextUnit)) {
|
|
1441
|
-
nextUnit = new Unit({'csCode_' : nextUnit ,
|
|
1457
|
+
nextUnit = new Unit({'csCode_' : nextUnit, 'ciCode_' : nextUnit,
|
|
1442
1458
|
'magnitude_' : Number(nextUnit),
|
|
1443
1459
|
'name_': nextUnit});
|
|
1444
1460
|
}
|
package/source/unitTables.js
CHANGED
|
@@ -97,6 +97,11 @@ class UnitTablesFactory {
|
|
|
97
97
|
* @type integer
|
|
98
98
|
*/
|
|
99
99
|
this.massDimIndex_ = 0;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Map of indices in the dimension vector to base unit symbols.
|
|
103
|
+
*/
|
|
104
|
+
this.dimVecIndexToBaseUnit_ = {};
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
|
|
@@ -138,6 +143,15 @@ class UnitTablesFactory {
|
|
|
138
143
|
// and that's OK here.
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
if (theUnit.isBase_) {
|
|
147
|
+
const dimVec = theUnit.dim_.dimVec_;
|
|
148
|
+
let nonZeroIndex;
|
|
149
|
+
for (let i=0, len=dimVec.length; nonZeroIndex==undefined && i<len; ++i) {
|
|
150
|
+
if (dimVec[i] != 0)
|
|
151
|
+
nonZeroIndex = i;
|
|
152
|
+
}
|
|
153
|
+
this.dimVecIndexToBaseUnit_[nonZeroIndex] = theUnit.csCode_;
|
|
154
|
+
}
|
|
141
155
|
} // end addUnit
|
|
142
156
|
|
|
143
157
|
|