bruce-models 7.1.54 → 7.1.55

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.
@@ -7283,12 +7283,234 @@ var Calculator;
7283
7283
  EValueType[EValueType["RandomColor"] = 5] = "RandomColor";
7284
7284
  })(EValueType = Calculator.EValueType || (Calculator.EValueType = {}));
7285
7285
  /**
7286
- * Calculates a value-type 'T' based on given set of fields.
7287
- * The supplied data + tags are fed into the calculation.
7288
- * When a value fails to be calculated, the 'defaultValue' is returned.
7289
- * If no 'defaultValue' is provided, then 'null' is returned.
7286
+ * Decodes an effective string produced by TraceCalculate back into a structured object.
7287
+ * Returns null if the string is null, empty, or does not match the expected format.
7290
7288
  */
7291
- function Calculate(params) {
7289
+ function DecodeEffective(effective) {
7290
+ if (!effective) {
7291
+ return null;
7292
+ }
7293
+ // Format: f{index}:{type}[:{part1}[:{part2}]]
7294
+ const match = effective.match(/^f(\d+):([^:]+)(?::([^:]+)(?::([^:]+))?)?$/);
7295
+ if (!match) {
7296
+ return null;
7297
+ }
7298
+ const fieldIndex = parseInt(match[1], 10);
7299
+ const type = match[2];
7300
+ const part1 = match[3] != null ? decodeEffective(match[3]) : null;
7301
+ const part2 = match[4] != null ? decodeEffective(match[4]) : null;
7302
+ const base = { type, fieldIndex };
7303
+ switch (type) {
7304
+ case "color":
7305
+ if (part1 == null) {
7306
+ return null;
7307
+ }
7308
+ return Object.assign(Object.assign({}, base), { colorStr: part1 });
7309
+ case "gradient":
7310
+ case "mapping":
7311
+ return Object.assign(Object.assign(Object.assign({}, base), (part1 != null && { path: part1 })), (part2 != null && { entityValue: part2 }));
7312
+ case "input":
7313
+ if (part1 == null || part2 == null) {
7314
+ return null;
7315
+ }
7316
+ return Object.assign(Object.assign({}, base), { template: part1, resolvedValue: part2 });
7317
+ case "tag":
7318
+ if (part1 == null) {
7319
+ return null;
7320
+ }
7321
+ return Object.assign(Object.assign({}, base), { tagColor: part1 });
7322
+ case "random":
7323
+ case "fn":
7324
+ return base;
7325
+ default:
7326
+ return null;
7327
+ }
7328
+ }
7329
+ Calculator.DecodeEffective = DecodeEffective;
7330
+ function encodeEffective(str) {
7331
+ const s = String(str == null ? "" : str);
7332
+ try {
7333
+ if (typeof Buffer !== "undefined") {
7334
+ return Buffer.from(s).toString("base64").replace(/=+$/, "");
7335
+ }
7336
+ // Browser fallback
7337
+ return btoa(s).replace(/=+$/, "");
7338
+ }
7339
+ catch (e) {
7340
+ return encodeURIComponent(s);
7341
+ }
7342
+ }
7343
+ function decodeEffective(encoded) {
7344
+ try {
7345
+ if (typeof Buffer !== "undefined") {
7346
+ return Buffer.from(encoded, "base64").toString("utf8");
7347
+ }
7348
+ return atob(encoded);
7349
+ }
7350
+ catch (e) {
7351
+ return decodeURIComponent(encoded);
7352
+ }
7353
+ }
7354
+ function _getMappingTrace(value, entity) {
7355
+ const attrPaths = parseLegacyPath(value.field);
7356
+ for (let i = 0; i < attrPaths.length; i++) {
7357
+ const attrPath = attrPaths[i];
7358
+ let eValue = Entity.GetValue({
7359
+ entity: entity,
7360
+ path: attrPath
7361
+ });
7362
+ let isValueNum = !isNaN(+eValue);
7363
+ if (eValue == null) {
7364
+ isValueNum = false;
7365
+ }
7366
+ for (let j = 0; j < value.values.length; j++) {
7367
+ const option = value.values[j];
7368
+ const fieldValues = Array.isArray(option.fieldValue) ? option.fieldValue : [option.fieldValue];
7369
+ for (let k = 0; k < fieldValues.length; k++) {
7370
+ let mapValue = fieldValues[k];
7371
+ // If mapValue is prefixed with "JS:", we evaluate it as JavaScript.
7372
+ // This lets us do things like JS:Boolean("${}") as a quick way to map 'existence' to a target value.
7373
+ if (typeof mapValue === "string" && mapValue.startsWith("JS:")) {
7374
+ try {
7375
+ let jsEval = mapValue.replace("JS:", "").trim();
7376
+ const attrPathStr = PathUtils.Wrap(attrPath);
7377
+ jsEval = jsEval.replace("${}", "${" + attrPathStr + "}");
7378
+ jsEval = BruceVariable.SwapValues({
7379
+ str: jsEval,
7380
+ entity: entity
7381
+ });
7382
+ // https://rollupjs.org/guide/en/#avoiding-eval
7383
+ // This stops eval warning.
7384
+ const eval2 = eval;
7385
+ mapValue = eval2(jsEval);
7386
+ if (mapValue) {
7387
+ return { result: option.appliedValue, attrPath, eValue };
7388
+ }
7389
+ else {
7390
+ continue;
7391
+ }
7392
+ }
7393
+ catch (exception) {
7394
+ const e = exception;
7395
+ let suppress = false;
7396
+ if (e && typeof e == "object") {
7397
+ const msg = e.message;
7398
+ suppress = !!msg && (msg.includes("Unexpected end") || msg.includes("got end of script"));
7399
+ }
7400
+ if (!suppress) {
7401
+ console.error(e);
7402
+ }
7403
+ // Eval failed, therefor not a valid mapping-row.
7404
+ continue;
7405
+ }
7406
+ }
7407
+ let isMapValueNum = !isNaN(+mapValue);
7408
+ if (isMapValueNum == null) {
7409
+ isMapValueNum = false;
7410
+ }
7411
+ if (isValueNum && (isMapValueNum || (typeof mapValue === "string" && mapValue.includes("-")))) {
7412
+ if (+mapValue == +eValue) {
7413
+ return { result: option.appliedValue, attrPath, eValue };
7414
+ }
7415
+ const mapSplit = mapValue.split("-");
7416
+ if (mapSplit.length == 2) {
7417
+ const min = mapSplit[0];
7418
+ const max = mapSplit[1];
7419
+ if (min != "") {
7420
+ if (+eValue < +min) {
7421
+ continue;
7422
+ }
7423
+ }
7424
+ if (max != "") {
7425
+ if (+eValue > +max) {
7426
+ continue;
7427
+ }
7428
+ }
7429
+ if (min == "" && max == "") {
7430
+ continue;
7431
+ }
7432
+ return { result: option.appliedValue, attrPath, eValue };
7433
+ }
7434
+ }
7435
+ else {
7436
+ if (mapValue == eValue) {
7437
+ return { result: option.appliedValue, attrPath, eValue };
7438
+ }
7439
+ // Case where Entity value is a boolean but the mapping value is a string.
7440
+ // Common as mapping value is typically a user-entered string.
7441
+ else if (typeof eValue === "boolean" && typeof mapValue === "string") {
7442
+ const eValueStr = eValue ? "true" : "false";
7443
+ if (mapValue.toLowerCase() == eValueStr) {
7444
+ return { result: option.appliedValue, attrPath, eValue };
7445
+ }
7446
+ }
7447
+ // Handling possible case where the opposite is true.
7448
+ // Have not seen this happen yet, but preparing for any future cases.
7449
+ else if (typeof mapValue === "boolean" && typeof eValue === "string") {
7450
+ const mapValueStr = mapValue ? "true" : "false";
7451
+ if (mapValueStr == eValue.toLowerCase()) {
7452
+ return { result: option.appliedValue, attrPath, eValue };
7453
+ }
7454
+ }
7455
+ }
7456
+ }
7457
+ }
7458
+ }
7459
+ return { result: null, attrPath: null, eValue: null };
7460
+ }
7461
+ function _getGradientTrace(value, entity, defaultToMin) {
7462
+ const min = +value.points[0].position;
7463
+ const max = +value.points[value.points.length - 1].position;
7464
+ const attrPaths = parseLegacyPath(value.field);
7465
+ for (let i = 0; i < attrPaths.length; i++) {
7466
+ const attrPath = attrPaths[i];
7467
+ let eValue = Entity.GetValue({
7468
+ entity: entity,
7469
+ path: attrPath
7470
+ });
7471
+ if (typeof eValue == "string") {
7472
+ eValue = Number(eValue);
7473
+ }
7474
+ if ((!eValue && eValue != 0) || isNaN(eValue)) {
7475
+ continue;
7476
+ }
7477
+ if (eValue >= max) {
7478
+ return { result: Color.ColorFromStr(value.points[value.points.length - 1].color), attrPath, eValue };
7479
+ }
7480
+ else if (eValue <= min) {
7481
+ return { result: Color.ColorFromStr(value.points[0].color), attrPath, eValue };
7482
+ }
7483
+ for (let j = 0; j < value.points.length - 1; j++) {
7484
+ const pointA = value.points[j];
7485
+ const pointB = value.points[j + 1];
7486
+ if (eValue >= pointA.position && eValue <= pointB.position) {
7487
+ if (pointA.position == pointB.position) {
7488
+ return { result: Color.ColorFromStr(pointA.color), attrPath, eValue };
7489
+ }
7490
+ const distance = (eValue - pointA.position) / (pointB.position - pointA.position);
7491
+ const colorA = Color.ColorFromStr(pointA.color);
7492
+ const colorB = Color.ColorFromStr(pointB.color);
7493
+ return {
7494
+ result: {
7495
+ red: colorA.red + (colorB.red - colorA.red) * distance,
7496
+ green: colorA.green + (colorB.green - colorA.green) * distance,
7497
+ blue: colorA.blue + (colorB.blue - colorA.blue) * distance,
7498
+ alpha: colorA.alpha + (colorB.alpha - colorA.alpha) * distance
7499
+ },
7500
+ attrPath,
7501
+ eValue
7502
+ };
7503
+ }
7504
+ }
7505
+ }
7506
+ // Fallback to min (static, no data path resolved).
7507
+ return { result: Color.ColorFromStr(value.points[0].color), attrPath: null, eValue: null };
7508
+ }
7509
+ /**
7510
+ * Like Calculate, but also returns an 'effective' key describing how the value
7511
+ * was derived. See ITraceResult for the key format.
7512
+ */
7513
+ function TraceCalculate(params) {
7292
7514
  let { fields, tags, data, defaultValue, type } = params;
7293
7515
  // If params doesn't include a defaultValue, use null.
7294
7516
  // Though passing in undefined is valid!
@@ -7296,7 +7518,7 @@ var Calculator;
7296
7518
  defaultValue = null;
7297
7519
  }
7298
7520
  if (fields == null) {
7299
- return defaultValue;
7521
+ return { value: defaultValue, effective: null };
7300
7522
  }
7301
7523
  if (data == null || typeof data != "object") {
7302
7524
  data = {};
@@ -7341,16 +7563,21 @@ var Calculator;
7341
7563
  }
7342
7564
  return false;
7343
7565
  };
7344
- // Calculate the value.
7345
7566
  let value = null;
7567
+ let computedEffective = null;
7346
7568
  for (let i = 0; i < fieldsArr.length; i++) {
7347
7569
  let field = fieldsArr[i];
7570
+ // Intermediate trace parts — assembled into effective only if value resolves.
7571
+ let traceType = null;
7572
+ let tracePart1 = null;
7573
+ let tracePart2 = null;
7348
7574
  // Bad data has it set to 'color' but expects the input to be a number.
7349
7575
  if (type == "number" && field.type == EValueType.Color) {
7350
7576
  field.type = EValueType.Input;
7351
7577
  }
7352
7578
  // Custom resolution.
7353
7579
  if (field.value instanceof Function) {
7580
+ traceType = "fn";
7354
7581
  value = field.value(data, tags);
7355
7582
  if (type == "number") {
7356
7583
  if (typeof value == "string" && value != "" && value != null && value != undefined) {
@@ -7384,6 +7611,8 @@ var Calculator;
7384
7611
  break;
7385
7612
  }
7386
7613
  value = field.value;
7614
+ traceType = "color";
7615
+ tracePart1 = encodeEffective(value);
7387
7616
  value = assertColor(value);
7388
7617
  if (value && type == "string") {
7389
7618
  value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
@@ -7393,10 +7622,17 @@ var Calculator;
7393
7622
  if (type === "number") {
7394
7623
  break;
7395
7624
  }
7396
- value = GetGradientValue(field.value, data, shouldRangesDefaultToMin);
7397
- value = assertColor(value);
7398
- if (value && type == "string") {
7399
- value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
7625
+ {
7626
+ const gradTrace = _getGradientTrace(field.value, data, shouldRangesDefaultToMin);
7627
+ value = assertColor(gradTrace.result);
7628
+ traceType = "gradient";
7629
+ if (gradTrace.attrPath != null) {
7630
+ tracePart1 = encodeEffective(PathUtils.Wrap(gradTrace.attrPath));
7631
+ tracePart2 = encodeEffective(String(gradTrace.eValue));
7632
+ }
7633
+ if (value && type == "string") {
7634
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
7635
+ }
7400
7636
  }
7401
7637
  break;
7402
7638
  case EValueType.RandomColor:
@@ -7405,6 +7641,7 @@ var Calculator;
7405
7641
  }
7406
7642
  value = Color.RandomColor();
7407
7643
  value = assertColor(value);
7644
+ traceType = "random";
7408
7645
  if (value && type == "string") {
7409
7646
  value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
7410
7647
  }
@@ -7413,12 +7650,14 @@ var Calculator;
7413
7650
  if (type === "number") {
7414
7651
  break;
7415
7652
  }
7416
- for (let i = 0; i < tags.length; i++) {
7417
- const tag = tags[i];
7653
+ for (let ti = 0; ti < tags.length; ti++) {
7654
+ const tag = tags[ti];
7418
7655
  if (tag.Color) {
7419
7656
  value = Color.ColorFromStr(tag.Color);
7420
7657
  value = assertColor(value);
7421
7658
  if (value) {
7659
+ traceType = "tag";
7660
+ tracePart1 = encodeEffective(tag.Color);
7422
7661
  break;
7423
7662
  }
7424
7663
  }
@@ -7432,31 +7671,37 @@ var Calculator;
7432
7671
  // Eg: Result is a colour, a number, a string.
7433
7672
  // This means we first calculate the value, then validate it in the context of the desired type.
7434
7673
  case EValueType.Input:
7435
- value = GetInputValue(field.value, data);
7436
- if (value != null) {
7437
- if (type == "number") {
7438
- if (typeof value == "string" && value != "" && value != null && value != undefined) {
7439
- value = Number(value);
7440
- }
7441
- else if (typeof value != "number") {
7442
- value = null;
7443
- }
7444
- }
7445
- else if (type == "string") {
7446
- if (typeof value == "number") {
7447
- value = String(value);
7448
- }
7449
- else if (typeof value == "object") {
7450
- if (isColor(value)) {
7451
- value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
7674
+ {
7675
+ const inputTemplate = String(field.value);
7676
+ value = GetInputValue(field.value, data);
7677
+ if (value != null) {
7678
+ traceType = "input";
7679
+ tracePart1 = encodeEffective(inputTemplate);
7680
+ tracePart2 = encodeEffective(String(value));
7681
+ if (type == "number") {
7682
+ if (typeof value == "string" && value != "" && value != null && value != undefined) {
7683
+ value = Number(value);
7452
7684
  }
7453
- else {
7685
+ else if (typeof value != "number") {
7454
7686
  value = null;
7455
7687
  }
7456
7688
  }
7457
- }
7458
- else if (type == "color") {
7459
- value = assertColor(value);
7689
+ else if (type == "string") {
7690
+ if (typeof value == "number") {
7691
+ value = String(value);
7692
+ }
7693
+ else if (typeof value == "object") {
7694
+ if (isColor(value)) {
7695
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
7696
+ }
7697
+ else {
7698
+ value = null;
7699
+ }
7700
+ }
7701
+ }
7702
+ else if (type == "color") {
7703
+ value = assertColor(value);
7704
+ }
7460
7705
  }
7461
7706
  }
7462
7707
  break;
@@ -7464,31 +7709,39 @@ var Calculator;
7464
7709
  // Eg: mapping a value to a Client File ID, or a colour, or a number.
7465
7710
  // This means we first calculate the value, then validate it in the context of the desired type.
7466
7711
  case EValueType.Mapping:
7467
- value = GetMappingValue(field.value, data);
7468
- if (value != null) {
7469
- if (type == "number") {
7470
- if (typeof value == "string" && value != "" && value != null && value != undefined) {
7471
- value = Number(value);
7472
- }
7473
- else if (typeof value != "number") {
7474
- value = null;
7475
- }
7476
- }
7477
- else if (type == "string") {
7478
- if (typeof value == "number") {
7479
- value = String(value);
7712
+ {
7713
+ const mapTrace = _getMappingTrace(field.value, data);
7714
+ value = mapTrace.result;
7715
+ if (value != null) {
7716
+ traceType = "mapping";
7717
+ if (mapTrace.attrPath != null) {
7718
+ tracePart1 = encodeEffective(PathUtils.Wrap(mapTrace.attrPath));
7719
+ tracePart2 = encodeEffective(String(mapTrace.eValue));
7480
7720
  }
7481
- else if (typeof value == "object") {
7482
- if (isColor(value)) {
7483
- value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
7721
+ if (type == "number") {
7722
+ if (typeof value == "string" && value != "" && value != null && value != undefined) {
7723
+ value = Number(value);
7484
7724
  }
7485
- else {
7725
+ else if (typeof value != "number") {
7486
7726
  value = null;
7487
7727
  }
7488
7728
  }
7489
- }
7490
- else if (type == "color") {
7491
- value = assertColor(typeof value === "number" ? String(value) : value);
7729
+ else if (type == "string") {
7730
+ if (typeof value == "number") {
7731
+ value = String(value);
7732
+ }
7733
+ else if (typeof value == "object") {
7734
+ if (isColor(value)) {
7735
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
7736
+ }
7737
+ else {
7738
+ value = null;
7739
+ }
7740
+ }
7741
+ }
7742
+ else if (type == "color") {
7743
+ value = assertColor(typeof value === "number" ? String(value) : value);
7744
+ }
7492
7745
  }
7493
7746
  }
7494
7747
  break;
@@ -7512,11 +7765,34 @@ var Calculator;
7512
7765
  }
7513
7766
  }
7514
7767
  if (value != null) {
7768
+ if (traceType != null) {
7769
+ if (tracePart1 != null && tracePart2 != null) {
7770
+ computedEffective = `f${i}:${traceType}:${tracePart1}:${tracePart2}`;
7771
+ }
7772
+ else if (tracePart1 != null) {
7773
+ computedEffective = `f${i}:${traceType}:${tracePart1}`;
7774
+ }
7775
+ else {
7776
+ computedEffective = `f${i}:${traceType}`;
7777
+ }
7778
+ }
7515
7779
  break;
7516
7780
  }
7517
7781
  }
7518
- // Return the value or default.
7519
- return value != null ? value : defaultValue;
7782
+ return {
7783
+ value: value != null ? value : defaultValue,
7784
+ effective: value != null ? computedEffective : null
7785
+ };
7786
+ }
7787
+ Calculator.TraceCalculate = TraceCalculate;
7788
+ /**
7789
+ * Calculates a value-type 'T' based on given set of fields.
7790
+ * The supplied data + tags are fed into the calculation.
7791
+ * When a value fails to be calculated, the 'defaultValue' is returned.
7792
+ * If no 'defaultValue' is provided, then 'null' is returned.
7793
+ */
7794
+ function Calculate(params) {
7795
+ return TraceCalculate(params).value;
7520
7796
  }
7521
7797
  Calculator.Calculate = Calculate;
7522
7798
  /**
@@ -7528,13 +7804,7 @@ var Calculator;
7528
7804
  * @returns
7529
7805
  */
7530
7806
  function GetValue(fields, entity = {}, tags = []) {
7531
- return Calculate({
7532
- fields: fields,
7533
- data: entity,
7534
- defaultValue: null,
7535
- tags: tags,
7536
- type: "any"
7537
- });
7807
+ return TraceGetValue(fields, entity, tags).value;
7538
7808
  }
7539
7809
  Calculator.GetValue = GetValue;
7540
7810
  /**
@@ -7545,13 +7815,7 @@ var Calculator;
7545
7815
  * @param tags
7546
7816
  */
7547
7817
  function GetColor(fields, entity = {}, tags = []) {
7548
- return Calculate({
7549
- fields: fields,
7550
- data: entity,
7551
- defaultValue: null,
7552
- tags: tags,
7553
- type: "color"
7554
- });
7818
+ return TraceGetColor(fields, entity, tags).value;
7555
7819
  }
7556
7820
  Calculator.GetColor = GetColor;
7557
7821
  /**
@@ -7563,13 +7827,7 @@ var Calculator;
7563
7827
  * @returns
7564
7828
  */
7565
7829
  function GetNumber(fields, entity = {}, tags = []) {
7566
- return Calculate({
7567
- fields: fields,
7568
- data: entity,
7569
- defaultValue: null,
7570
- tags: tags,
7571
- type: "number"
7572
- });
7830
+ return TraceGetNumber(fields, entity, tags).value;
7573
7831
  }
7574
7832
  Calculator.GetNumber = GetNumber;
7575
7833
  /**
@@ -7581,15 +7839,61 @@ var Calculator;
7581
7839
  * @returns
7582
7840
  */
7583
7841
  function GetString(fields, entity = {}, tags = []) {
7584
- return Calculate({
7585
- fields: fields,
7842
+ return TraceGetString(fields, entity, tags).value;
7843
+ }
7844
+ Calculator.GetString = GetString;
7845
+ /**
7846
+ * Like GetValue, but also returns 'effective' describing how the value was derived.
7847
+ */
7848
+ function TraceGetValue(fields, entity = {}, tags = []) {
7849
+ return TraceCalculate({
7850
+ fields,
7586
7851
  data: entity,
7587
7852
  defaultValue: null,
7588
- tags: tags,
7853
+ tags,
7854
+ type: "any"
7855
+ });
7856
+ }
7857
+ Calculator.TraceGetValue = TraceGetValue;
7858
+ /**
7859
+ * Like GetColor, but also returns 'effective' describing how the color was derived.
7860
+ */
7861
+ function TraceGetColor(fields, entity = {}, tags = []) {
7862
+ return TraceCalculate({
7863
+ fields,
7864
+ data: entity,
7865
+ defaultValue: null,
7866
+ tags,
7867
+ type: "color"
7868
+ });
7869
+ }
7870
+ Calculator.TraceGetColor = TraceGetColor;
7871
+ /**
7872
+ * Like GetNumber, but also returns 'effective' describing how the number was derived.
7873
+ */
7874
+ function TraceGetNumber(fields, entity = {}, tags = []) {
7875
+ return TraceCalculate({
7876
+ fields,
7877
+ data: entity,
7878
+ defaultValue: null,
7879
+ tags,
7880
+ type: "number"
7881
+ });
7882
+ }
7883
+ Calculator.TraceGetNumber = TraceGetNumber;
7884
+ /**
7885
+ * Like GetString, but also returns 'effective' describing how the string was derived.
7886
+ */
7887
+ function TraceGetString(fields, entity = {}, tags = []) {
7888
+ return TraceCalculate({
7889
+ fields,
7890
+ data: entity,
7891
+ defaultValue: null,
7892
+ tags,
7589
7893
  type: "string"
7590
7894
  });
7591
7895
  }
7592
- Calculator.GetString = GetString;
7896
+ Calculator.TraceGetString = TraceGetString;
7593
7897
  /**
7594
7898
  * Calculates a mapping value. This can return any value type.
7595
7899
  * It is intended to be parsed and validated within a value-type context. Eg: GetColor, GetNumber, GetString.
@@ -7598,114 +7902,7 @@ var Calculator;
7598
7902
  * @returns
7599
7903
  */
7600
7904
  function GetMappingValue(value, entity) {
7601
- const attrPaths = parseLegacyPath(value.field);
7602
- for (let i = 0; i < attrPaths.length; i++) {
7603
- const attrPath = attrPaths[i];
7604
- let eValue = Entity.GetValue({
7605
- entity: entity,
7606
- path: attrPath
7607
- });
7608
- let isValueNum = !isNaN(+eValue);
7609
- if (eValue == null) {
7610
- isValueNum = false;
7611
- }
7612
- for (let i = 0; i < value.values.length; i++) {
7613
- const option = value.values[i];
7614
- const fieldValues = Array.isArray(option.fieldValue) ? option.fieldValue : [option.fieldValue];
7615
- // Check each field value in the array.
7616
- for (let j = 0; j < fieldValues.length; j++) {
7617
- let mapValue = fieldValues[j];
7618
- // If mapValue is prefixed with "JS:", we evaluate it as JavaScript.
7619
- // This lets us do things like JS:Boolean("${}") as a quick way to map 'existence' to a target value.
7620
- if (typeof mapValue === "string" && mapValue.startsWith("JS:")) {
7621
- try {
7622
- let jsEval = mapValue.replace("JS:", "").trim();
7623
- const attrPathStr = PathUtils.Wrap(attrPath);
7624
- jsEval = jsEval.replace("${}", "${" + attrPathStr + "}");
7625
- jsEval = BruceVariable.SwapValues({
7626
- str: jsEval,
7627
- entity: entity
7628
- });
7629
- // https://rollupjs.org/guide/en/#avoiding-eval
7630
- // This stops eval warning.
7631
- const eval2 = eval;
7632
- mapValue = eval2(jsEval);
7633
- // We currently expect eval to return a validity bool.
7634
- // So it either matches and we return it, or it doesn't and we continue.
7635
- if (mapValue) {
7636
- return option.appliedValue;
7637
- }
7638
- else {
7639
- continue;
7640
- }
7641
- }
7642
- catch (exception) {
7643
- const e = exception;
7644
- let suppress = false;
7645
- if (e && typeof e == "object") {
7646
- const msg = e.message;
7647
- suppress = !!msg && (msg.includes("Unexpected end") || msg.includes("got end of script"));
7648
- }
7649
- if (!suppress) {
7650
- console.error(e);
7651
- }
7652
- // Eval failed, therefor not a valid mapping-row.
7653
- continue;
7654
- }
7655
- }
7656
- let isMapValueNum = !isNaN(+mapValue);
7657
- if (isMapValueNum == null) {
7658
- isMapValueNum = false;
7659
- }
7660
- if (isValueNum && (isMapValueNum || (typeof mapValue === "string" && mapValue.includes("-")))) {
7661
- if (+mapValue == +eValue) {
7662
- return option.appliedValue;
7663
- }
7664
- const mapSplit = mapValue.split("-");
7665
- if (mapSplit.length == 2) {
7666
- const min = mapSplit[0];
7667
- const max = mapSplit[1];
7668
- if (min != "") {
7669
- if (+eValue < +min) {
7670
- continue;
7671
- }
7672
- }
7673
- if (max != "") {
7674
- if (+eValue > +max) {
7675
- continue;
7676
- }
7677
- }
7678
- if (min == "" && max == "") {
7679
- continue;
7680
- }
7681
- return option.appliedValue;
7682
- }
7683
- }
7684
- else {
7685
- if (mapValue == eValue) {
7686
- return option.appliedValue;
7687
- }
7688
- // Case where Entity value is a boolean but the mapping value is a string.
7689
- // Common as mapping value is typically a user-entered string.
7690
- else if (typeof eValue === "boolean" && typeof mapValue === "string") {
7691
- const eValueStr = eValue ? "true" : "false";
7692
- if (mapValue.toLowerCase() == eValueStr) {
7693
- return option.appliedValue;
7694
- }
7695
- }
7696
- // Handling possible case where the opposite is true.
7697
- // Have not seen this happen yet, but preparing for any future cases.
7698
- else if (typeof mapValue === "boolean" && typeof eValue === "string") {
7699
- const mapValueStr = mapValue ? "true" : "false";
7700
- if (mapValueStr == eValue.toLowerCase()) {
7701
- return option.appliedValue;
7702
- }
7703
- }
7704
- }
7705
- }
7706
- }
7707
- }
7708
- return null;
7905
+ return _getMappingTrace(value, entity).result;
7709
7906
  }
7710
7907
  Calculator.GetMappingValue = GetMappingValue;
7711
7908
  /**
@@ -7718,47 +7915,7 @@ var Calculator;
7718
7915
  * @returns
7719
7916
  */
7720
7917
  function GetGradientValue(value, entity, defaultToMin) {
7721
- const min = +value.points[0].position;
7722
- const max = +value.points[value.points.length - 1].position;
7723
- const attrPaths = parseLegacyPath(value.field);
7724
- for (let i = 0; i < attrPaths.length; i++) {
7725
- const attrPath = attrPaths[i];
7726
- let eValue = Entity.GetValue({
7727
- entity: entity,
7728
- path: attrPath
7729
- });
7730
- if (typeof eValue == "string") {
7731
- eValue = Number(eValue);
7732
- }
7733
- if ((!eValue && eValue != 0) || isNaN(eValue)) {
7734
- continue;
7735
- }
7736
- if (eValue >= max) {
7737
- return Color.ColorFromStr(value.points[value.points.length - 1].color);
7738
- }
7739
- else if (eValue <= min) {
7740
- return Color.ColorFromStr(value.points[0].color);
7741
- }
7742
- for (let i = 0; i < value.points.length - 1; i++) {
7743
- const pointA = value.points[i];
7744
- const pointB = value.points[i + 1];
7745
- if (eValue >= pointA.position && eValue <= pointB.position) {
7746
- if (pointA.position == pointB.position) {
7747
- return Color.ColorFromStr(pointA.color);
7748
- }
7749
- const distance = (eValue - pointA.position) / (pointB.position - pointA.position);
7750
- const colorA = Color.ColorFromStr(pointA.color);
7751
- const colorB = Color.ColorFromStr(pointB.color);
7752
- return {
7753
- red: colorA.red + (colorB.red - colorA.red) * distance,
7754
- green: colorA.green + (colorB.green - colorA.green) * distance,
7755
- blue: colorA.blue + (colorB.blue - colorA.blue) * distance,
7756
- alpha: colorA.alpha + (colorB.alpha - colorA.alpha) * distance
7757
- };
7758
- }
7759
- }
7760
- }
7761
- return Color.ColorFromStr(value.points[0].color);
7918
+ return _getGradientTrace(value, entity, defaultToMin).result;
7762
7919
  }
7763
7920
  Calculator.GetGradientValue = GetGradientValue;
7764
7921
  /**
@@ -19102,7 +19259,7 @@ var UrlUtils;
19102
19259
  })(UrlUtils || (UrlUtils = {}));
19103
19260
 
19104
19261
  // This is updated with the package.json version on build.
19105
- const VERSION = "7.1.54";
19262
+ const VERSION = "7.1.55";
19106
19263
 
19107
19264
  export { VERSION, Account, AccountAudit, AccountConcept, AccountFeatures, AccountInvite, AccountLimits, AccountTemplate, AccountType, AnnDocument, AbstractApi, Api, ApiGetters, BruceApi, GlobalApi, GuardianApi, Assembly, Calculator, ChangeSet, ClientFile, Bounds, BruceEvent, BruceVariable, CacheControl, Camera, Cartes, Carto, Color, DelayQueue, GeoJson, Geometry, LRUCache, UTC, CustomForm, DashboardView, DataFeed, DataLab, DataLabGroup, DataSource, DataTransform, Comment, Entity, EntityAttachment, EntityAttachmentType, EntityAttribute, EntityComment, EntityCoords, EntityHistoricData, EntityLink, EntityLod, EntityLodCategory, EntityRelation, EntityRelationType, EntitySource, EntityTableView, EntityTag, EntityType, EntityTypeTrigger, ENVIRONMENT, ExportBrz, ExportUsd, ImportAssembly, ImportCad, ImportCsv, ImportGeoJson, ImportJson, ImportKml, ImportLcc, ImportedFile, Uploader, Markup, NAVIGATOR_CHAT_EVENT_ENTITY_HIGHLIGHT_APPLIED, NAVIGATOR_CHAT_EVENT_SCENE_CONTEXT_PREFETCHED, NavigatorChatClient, NavigatorMcpWebSocketClient, Plugin, ProgramKey, MenuItem, ProjectView, ProjectViewBookmark, ProjectViewBookmarkGroup, ProjectViewLegacy, ProjectViewLegacyBookmark, ProjectViewLegacyTile, ProjectViewTile, ZoomControl, Scenario, HostingLocation, MessageBroker, PendingAction, RecordChangeFeed, Style, Tileset, Tracking, Permission, Session, User, UserGroup, UserMfaMethod, EncryptUtils, MathUtils, ObjectUtils, PathUtils, UrlUtils };
19108
19265
  //# sourceMappingURL=bruce-models.es5.js.map