@itwin/rpcinterface-full-stack-tests 5.3.0-dev.2 → 5.3.0-dev.4

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.
@@ -73140,17 +73140,17 @@ class TextBlockComponent {
73140
73140
  _styleOverrides;
73141
73141
  /** @internal */
73142
73142
  constructor(props) {
73143
- this._styleOverrides = _TextStyle__WEBPACK_IMPORTED_MODULE_0__.TextStyleSettings.cloneProps(props?.styleOverrides ?? {});
73143
+ this._styleOverrides = structuredClone(props?.styleOverrides ?? {});
73144
73144
  }
73145
73145
  /** Deviations in individual properties of the [[TextStyleSettings]] in the [AnnotationTextStyle]($backend).
73146
- * For example, if the style uses the "Arial" font, you can override that by settings `styleOverrides.fontName` to "Comic Sans".
73146
+ * For example, if the style uses the "Arial" font, you can override that by settings `styleOverrides.font.name` to "Comic Sans".
73147
73147
  * @see [[clearStyleOverrides]] to reset this to an empty object.
73148
73148
  */
73149
73149
  get styleOverrides() {
73150
73150
  return this._styleOverrides;
73151
73151
  }
73152
73152
  set styleOverrides(overrides) {
73153
- this._styleOverrides = _TextStyle__WEBPACK_IMPORTED_MODULE_0__.TextStyleSettings.cloneProps(overrides);
73153
+ this._styleOverrides = structuredClone(overrides);
73154
73154
  }
73155
73155
  /** Reset any [[styleOverrides]] applied to this component. */
73156
73156
  clearStyleOverrides(_options) {
@@ -73171,23 +73171,14 @@ class TextBlockComponent {
73171
73171
  /** Convert this component to its JSON representation. */
73172
73172
  toJSON() {
73173
73173
  return {
73174
- styleOverrides: _TextStyle__WEBPACK_IMPORTED_MODULE_0__.TextStyleSettings.cloneProps(this.styleOverrides),
73174
+ styleOverrides: structuredClone(this.styleOverrides),
73175
73175
  };
73176
73176
  }
73177
73177
  /** Returns true if `this` is equivalent to `other`. */
73178
73178
  equals(other) {
73179
- const myKeys = Object.keys(this.styleOverrides);
73180
- const yrKeys = Object.keys(other._styleOverrides);
73181
- if (myKeys.length !== yrKeys.length) {
73182
- return false;
73183
- }
73184
- for (const name of myKeys) {
73185
- const key = name;
73186
- if (this.styleOverrides[key] !== other.styleOverrides[key]) {
73187
- return false;
73188
- }
73189
- }
73190
- return true;
73179
+ const mySettings = _TextStyle__WEBPACK_IMPORTED_MODULE_0__.TextStyleSettings.fromJSON(this.styleOverrides);
73180
+ const otherSettings = _TextStyle__WEBPACK_IMPORTED_MODULE_0__.TextStyleSettings.fromJSON(other.styleOverrides);
73181
+ return mySettings.equals(otherSettings);
73191
73182
  }
73192
73183
  }
73193
73184
  /** A sequence of characters within a [[Paragraph]] that share a single style. Runs are the leaf nodes of a [[TextBlock]] document. When laid out for display, a single run may span
@@ -73555,7 +73546,6 @@ class List extends TextBlockComponent {
73555
73546
  return (other instanceof List) && super.equals(other);
73556
73547
  }
73557
73548
  }
73558
- ;
73559
73549
  /** Represents a formatted text document consisting of a series of [[Paragraph]]s, each laid out on a separate line and containing their own content.
73560
73550
  * No word-wrapping is applied to the document unless a [[width]] greater than zero is specified.
73561
73551
  * @see [[TextAnnotation]] to position a text block as an annotation in 2d or 3d space.
@@ -73568,21 +73558,9 @@ class TextBlock extends TextBlockComponent {
73568
73558
  * Default: 0
73569
73559
  */
73570
73560
  width;
73571
- /** The alignment of the document's content. */
73572
- justification;
73573
- /** The margins of the document. */
73574
- margins;
73575
73561
  constructor(props) {
73576
73562
  super(props);
73577
73563
  this.width = props.width ?? 0;
73578
- this.justification = props.justification ?? "left";
73579
- // Assign default margins if not provided
73580
- this.margins = {
73581
- left: props.margins?.left ?? 0,
73582
- right: props.margins?.right ?? 0,
73583
- top: props.margins?.top ?? 0,
73584
- bottom: props.margins?.bottom ?? 0,
73585
- };
73586
73564
  this.children = props?.children?.map((para) => Paragraph.create(para)) ?? [];
73587
73565
  }
73588
73566
  clearStyleOverrides(options) {
@@ -73592,8 +73570,6 @@ class TextBlock extends TextBlockComponent {
73592
73570
  return {
73593
73571
  ...super.toJSON(),
73594
73572
  width: this.width,
73595
- justification: this.justification,
73596
- margins: this.margins,
73597
73573
  children: this.children.map((x) => x.toJSON()),
73598
73574
  };
73599
73575
  }
@@ -73638,12 +73614,9 @@ class TextBlock extends TextBlockComponent {
73638
73614
  if (!super.equals(other)) {
73639
73615
  return false;
73640
73616
  }
73641
- if (this.width !== other.width || this.justification !== other.justification) {
73617
+ if (this.width !== other.width) {
73642
73618
  return false;
73643
73619
  }
73644
- const marginsAreEqual = Object.entries(this.margins).every(([key, value]) => value === other.margins[key]);
73645
- if (!marginsAreEqual)
73646
- return false;
73647
73620
  if (this.children && other.children) {
73648
73621
  if (this.children.length !== other.children.length) {
73649
73622
  return false;
@@ -73808,6 +73781,7 @@ __webpack_require__.r(__webpack_exports__);
73808
73781
  /* harmony export */ textAnnotationFrameShapes: () => (/* binding */ textAnnotationFrameShapes)
73809
73782
  /* harmony export */ });
73810
73783
  /* harmony import */ var _ColorDef__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../ColorDef */ "../../core/common/lib/esm/ColorDef.js");
73784
+ /* harmony import */ var _Fonts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Fonts */ "../../core/common/lib/esm/Fonts.js");
73811
73785
  /*---------------------------------------------------------------------------------------------
73812
73786
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
73813
73787
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -73816,6 +73790,7 @@ __webpack_require__.r(__webpack_exports__);
73816
73790
  * @module Annotation
73817
73791
  */
73818
73792
 
73793
+
73819
73794
  /** Predefined markers for list items in text annotations.
73820
73795
  * These values control the appearance of list item markers (e.g., bullet, circle, square, dash, number) that denote the start of a list item in a list.
73821
73796
  * @beta
@@ -73837,6 +73812,7 @@ var ListMarkerEnumerator;
73837
73812
  */
73838
73813
  const textAnnotationFrameShapes = ["none", "line", "rectangle", "circle", "equilateralTriangle", "diamond", "square", "pentagon", "hexagon", "octagon", "capsule", "roundedRectangle"];
73839
73814
  ;
73815
+ ;
73840
73816
  function deepFreeze(obj) {
73841
73817
  if (obj === null || typeof obj !== "object" || Object.isFrozen(obj))
73842
73818
  return;
@@ -73857,20 +73833,20 @@ function deepFreeze(obj) {
73857
73833
  class TextStyleSettings {
73858
73834
  /** The color of the text. */
73859
73835
  color;
73860
- /** The name of a font stored in an iModel, used to draw the contents of a [[TextRun]].
73836
+ /** The font stored in an iModel, used to draw the contents of a [[TextRun]].
73861
73837
  */
73862
- fontName;
73863
- /** The height each line of text, in meters. Many other settings use the line height as the basis for computing their own values.
73864
- * For example, the height and offset from baseline of a subscript [[TextRun]] are computed as lineHeight * [[subScriptScale]] and
73865
- * lineHeight * [[subScriptOffsetFactor]], respectively.
73838
+ font;
73839
+ /** The height of the text, in meters. Many other settings use the text height as the basis for computing their own values.
73840
+ * For example, the height and offset from baseline of a subscript [[TextRun]] are computed as textHeight * [[subScriptScale]] and
73841
+ * textHeight * [[subScriptOffsetFactor]], respectively.
73866
73842
  */
73867
- lineHeight;
73843
+ textHeight;
73868
73844
  /** Multiplier used to compute the vertical distance between two lines of text.
73869
- * The distance is computed in meters as lineSpacingFactor * [[lineHeight]].
73845
+ * The distance is computed in meters as lineSpacingFactor * [[textHeight]] of the [[TextBlock]].
73870
73846
  */
73871
73847
  lineSpacingFactor;
73872
73848
  /** Multiplier used to compute the vertical distance between two paragraphs of text.
73873
- * The distance is computed in meters as paragraphSpacingFactor * [[lineHeight]].
73849
+ * The distance is computed in meters as paragraphSpacingFactor * the [[TextBlock]]'s [[textHeight]].
73874
73850
  */
73875
73851
  paragraphSpacingFactor;
73876
73852
  /** Specifies whether the content of a [[TextRun]] should be rendered **bold**. */
@@ -73880,28 +73856,28 @@ class TextStyleSettings {
73880
73856
  /** Specifies whether the content of a [[TextRun]] should be underlined. */
73881
73857
  isUnderlined;
73882
73858
  /** Multiplier used to compute the height of both the numerator and denominator of a [[FractionRun]].
73883
- * The height is computed in meters as stackedFractionScale * [[lineHeight]].
73859
+ * The height is computed in meters as stackedFractionScale * [[textHeight]].
73884
73860
  */
73885
73861
  stackedFractionScale;
73886
73862
  /** Specifies how to separate the numerator and denominator of a [[FractionRun]]. */
73887
73863
  stackedFractionType;
73888
73864
  /** Multiplier used to compute the vertical offset from the baseline for a subscript [[TextRun]].
73889
- * The offset is computed in meters as subScriptOffsetFactor * [[lineHeight]].
73865
+ * The offset is computed in meters as subScriptOffsetFactor * [[textHeight]].
73890
73866
  */
73891
73867
  subScriptOffsetFactor;
73892
73868
  /** Multiplier used to compute the height of a subscript [[TextRun]].
73893
- * The height is computed as subScriptScale * [[lineHeight]].
73869
+ * The height is computed as subScriptScale * [[textHeight]].
73894
73870
  */
73895
73871
  subScriptScale;
73896
73872
  /** Multiplier used to compute the vertical offset from the baseline for a super [[TextRun]].
73897
- * The offset is computed in meters as superScriptOffsetFactor * [[lineHeight]].
73873
+ * The offset is computed in meters as superScriptOffsetFactor * [[textHeight]].
73898
73874
  */
73899
73875
  superScriptOffsetFactor;
73900
73876
  /** Multiplier used to compute the height of a superscript [[TextRun]].
73901
- * The height is computed as superScriptScale * [[lineHeight]].
73877
+ * The height is computed as superScriptScale * [[textHeight]].
73902
73878
  */
73903
73879
  superScriptScale;
73904
- /** Multiplier used to compute the width of each glyph, relative to [[lineHeight]]. */
73880
+ /** Multiplier used to compute the width of each glyph, relative to [[textHeight]]. */
73905
73881
  widthFactor;
73906
73882
  /** Properties describing appearance of leaders in a [[TextAnnotation]].
73907
73883
  * Used when producing geometry for [[TextAnnotation]].
@@ -73926,11 +73902,15 @@ class TextStyleSettings {
73926
73902
  listMarker;
73927
73903
  /** The frame settings of the [[TextAnnotation]]. */
73928
73904
  frame;
73929
- /** A fully-populated JSON representation of the default settings. A real `fontName` must be provided before use. */
73905
+ /** The margins to surround the document content. */
73906
+ margins;
73907
+ /** The alignment of the text content. */
73908
+ justification;
73909
+ /** A fully-populated JSON representation of the default settings. A real `font` must be provided before use. */
73930
73910
  static defaultProps = {
73931
73911
  color: "subcategory",
73932
- fontName: "",
73933
- lineHeight: 1,
73912
+ font: { name: "", type: _Fonts__WEBPACK_IMPORTED_MODULE_1__.FontType.TrueType },
73913
+ textHeight: 1,
73934
73914
  lineSpacingFactor: 0.5,
73935
73915
  paragraphSpacingFactor: 0.5,
73936
73916
  isBold: false,
@@ -73955,10 +73935,17 @@ class TextStyleSettings {
73955
73935
  listMarker: { enumerator: "1", terminator: "period", case: "lower" },
73956
73936
  frame: {
73957
73937
  shape: "none",
73958
- fill: "none",
73959
- border: _ColorDef__WEBPACK_IMPORTED_MODULE_0__.ColorDef.black.toJSON(),
73938
+ fillColor: "none",
73939
+ borderColor: _ColorDef__WEBPACK_IMPORTED_MODULE_0__.ColorDef.black.toJSON(),
73960
73940
  borderWeight: 1,
73961
73941
  },
73942
+ margins: {
73943
+ left: 0,
73944
+ right: 0,
73945
+ top: 0,
73946
+ bottom: 0
73947
+ },
73948
+ justification: "left",
73962
73949
  };
73963
73950
  /** Settings initialized to all default values. */
73964
73951
  static defaults = new TextStyleSettings({});
@@ -73967,8 +73954,12 @@ class TextStyleSettings {
73967
73954
  defaults = TextStyleSettings.defaultProps;
73968
73955
  }
73969
73956
  this.color = props.color ?? defaults.color;
73970
- this.fontName = props.fontName ?? defaults.fontName;
73971
- this.lineHeight = props.lineHeight ?? defaults.lineHeight;
73957
+ const font = {
73958
+ name: props.font?.name ?? defaults.font.name,
73959
+ type: props.font?.type ?? defaults.font.type,
73960
+ };
73961
+ this.font = Object.freeze(font);
73962
+ this.textHeight = props.textHeight ?? defaults.textHeight;
73972
73963
  this.lineSpacingFactor = props.lineSpacingFactor ?? defaults.lineSpacingFactor;
73973
73964
  this.paragraphSpacingFactor = props.paragraphSpacingFactor ?? defaults.paragraphSpacingFactor;
73974
73965
  this.isBold = props.isBold ?? defaults.isBold;
@@ -73994,34 +73985,30 @@ class TextStyleSettings {
73994
73985
  this.listMarker = props.listMarker ?? defaults.listMarker;
73995
73986
  const frame = {
73996
73987
  shape: props.frame?.shape ?? defaults.frame.shape,
73997
- fill: props.frame?.fill ?? defaults.frame.fill,
73998
- border: props.frame?.border ?? defaults.frame.border,
73988
+ fillColor: props.frame?.fillColor ?? defaults.frame.fillColor,
73989
+ borderColor: props.frame?.borderColor ?? defaults.frame.borderColor,
73999
73990
  borderWeight: props.frame?.borderWeight ?? defaults.frame.borderWeight,
74000
73991
  };
74001
73992
  // Cast to indicate to TypeScript that the frame properties are all defined
74002
73993
  this.frame = Object.freeze(frame);
73994
+ this.margins = Object.freeze({
73995
+ left: props.margins?.left ?? defaults.margins.left,
73996
+ right: props.margins?.right ?? defaults.margins.right,
73997
+ top: props.margins?.top ?? defaults.margins.top,
73998
+ bottom: props.margins?.bottom ?? defaults.margins.bottom,
73999
+ });
74000
+ this.justification = props.justification ?? defaults.justification;
74003
74001
  }
74004
74002
  /** Create a copy of these settings, modified according to the properties defined by `alteredProps`. */
74005
74003
  clone(alteredProps) {
74006
74004
  return alteredProps ? new TextStyleSettings(alteredProps, this) : this;
74007
74005
  }
74008
- /** Creates a deep copy of the `TextStyleSettingsProps`. */
74009
- static cloneProps(props) {
74010
- const copy = { ...props };
74011
- if (props.leader) {
74012
- copy.leader = { ...props.leader };
74013
- }
74014
- if (props.frame) {
74015
- copy.frame = { ...props.frame };
74016
- }
74017
- return copy;
74018
- }
74019
74006
  /** Create settings from their JSON representation. */
74020
74007
  static fromJSON(props) {
74021
74008
  return props ? new TextStyleSettings(props) : TextStyleSettings.defaults;
74022
74009
  }
74023
74010
  toJSON() {
74024
- return { ...this };
74011
+ return structuredClone(this);
74025
74012
  }
74026
74013
  /** Compare two [[TextLeaderStyleProps]] for equality.
74027
74014
  * @param other The other leader style properties to compare against.
@@ -74034,21 +74021,27 @@ class TextStyleSettings {
74034
74021
  }
74035
74022
  frameEquals(other) {
74036
74023
  return this.frame?.shape === other.shape
74037
- && this.frame?.fill === other.fill
74038
- && this.frame?.border === other.border
74024
+ && this.frame?.fillColor === other.fillColor
74025
+ && this.frame?.borderColor === other.borderColor
74039
74026
  && this.frame?.borderWeight === other.borderWeight;
74040
74027
  }
74028
+ marginsEqual(other) {
74029
+ return Object.entries(this.margins).every(([key, value]) => value === other[key]);
74030
+ }
74041
74031
  equals(other) {
74042
- return this.color === other.color && this.fontName === other.fontName
74043
- && this.lineHeight === other.lineHeight && this.lineSpacingFactor === other.lineSpacingFactor && this.paragraphSpacingFactor === other.paragraphSpacingFactor && this.widthFactor === other.widthFactor
74032
+ return this.color === other.color && this.font.name === other.font.name && this.font.type === other.font.type
74033
+ && this.textHeight === other.textHeight && this.widthFactor === other.widthFactor
74034
+ && this.lineSpacingFactor === other.lineSpacingFactor && this.paragraphSpacingFactor === other.paragraphSpacingFactor
74044
74035
  && this.isBold === other.isBold && this.isItalic === other.isItalic && this.isUnderlined === other.isUnderlined
74045
74036
  && this.stackedFractionType === other.stackedFractionType && this.stackedFractionScale === other.stackedFractionScale
74046
74037
  && this.subScriptOffsetFactor === other.subScriptOffsetFactor && this.subScriptScale === other.subScriptScale
74047
74038
  && this.superScriptOffsetFactor === other.superScriptOffsetFactor && this.superScriptScale === other.superScriptScale
74048
74039
  && this.tabInterval === other.tabInterval && this.indentation === other.indentation
74049
74040
  && this.listMarker.case === other.listMarker.case && this.listMarker.enumerator === other.listMarker.enumerator && this.listMarker.terminator === other.listMarker.terminator
74041
+ && this.justification === other.justification
74050
74042
  && this.leaderEquals(other.leader)
74051
- && this.frameEquals(other.frame);
74043
+ && this.frameEquals(other.frame)
74044
+ && this.marginsEqual(other.margins);
74052
74045
  }
74053
74046
  /**
74054
74047
  * Returns a list of validation errors for this instance.
@@ -74062,11 +74055,11 @@ class TextStyleSettings {
74062
74055
  */
74063
74056
  getValidationErrors() {
74064
74057
  const errorMessages = [];
74065
- if (this.fontName.trim() === "") {
74066
- errorMessages.push("fontName must be provided");
74058
+ if (this.font.name.trim() === "") {
74059
+ errorMessages.push("font name must be provided");
74067
74060
  }
74068
- if (this.lineHeight <= 0) {
74069
- errorMessages.push("lineHeight must be greater than 0");
74061
+ if (this.textHeight <= 0) {
74062
+ errorMessages.push("textHeight must be greater than 0");
74070
74063
  }
74071
74064
  if (this.stackedFractionScale <= 0) {
74072
74065
  errorMessages.push("stackedFractionScale must be greater than 0");
@@ -185305,10 +185298,14 @@ class StandardQuantityTypeDefinition {
185305
185298
  */
185306
185299
  class QuantityTypeFormatsProvider {
185307
185300
  onFormatsChanged = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
185301
+ _removeListeners = [];
185308
185302
  constructor() {
185309
- _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.quantityFormatter.onActiveFormattingUnitSystemChanged.addListener(() => {
185303
+ this._removeListeners.push(_IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.quantityFormatter.onActiveFormattingUnitSystemChanged.addListener(() => {
185310
185304
  this.onFormatsChanged.raiseEvent({ formatsChanged: "all" });
185311
- });
185305
+ }));
185306
+ }
185307
+ [Symbol.dispose]() {
185308
+ this._removeListeners.forEach(listener => listener());
185312
185309
  }
185313
185310
  _kindOfQuantityMap = new Map([
185314
185311
  ["AecUnits.LENGTH", QuantityType.Length],
@@ -334950,8 +334947,8 @@ class Formatter {
334950
334947
  */
334951
334948
  static formatComposite(magnitude, spec) {
334952
334949
  const compositeStrings = [];
334953
- // Caller will deal with appending +||-||() value sign as specified by formatting options so just format positive value
334954
- let posMagnitude = Math.abs(magnitude);
334950
+ let isNegative = false;
334951
+ let remainingMagnitude = magnitude;
334955
334952
  for (let i = 0; i < spec.unitConversions.length; i++) {
334956
334953
  const currentLabel = spec.unitConversions[i].label;
334957
334954
  const unitConversion = spec.unitConversions[i].conversion;
@@ -334961,40 +334958,43 @@ class Formatter {
334961
334958
  throw new _Exception__WEBPACK_IMPORTED_MODULE_1__.QuantityError(_Exception__WEBPACK_IMPORTED_MODULE_1__.QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has a invalid unit specification.`);
334962
334959
  let unitValue = 0.0;
334963
334960
  if (spec.format.type === _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Ratio) {
334964
- if (1 !== spec.format.units.length)
334961
+ if (1 !== (spec.format.units?.length ?? 0))
334965
334962
  throw new _Exception__WEBPACK_IMPORTED_MODULE_1__.QuantityError(_Exception__WEBPACK_IMPORTED_MODULE_1__.QuantityStatus.InvalidCompositeFormat, `The Format '${spec.format.name}' with type 'ratio' must have exactly one unit.`);
334966
334963
  try {
334967
- unitValue = (0,_Quantity__WEBPACK_IMPORTED_MODULE_3__.applyConversion)(posMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;
334964
+ unitValue = (0,_Quantity__WEBPACK_IMPORTED_MODULE_3__.applyConversion)(remainingMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;
334968
334965
  }
334969
334966
  catch (e) {
334970
334967
  // The "InvertingZero" error is thrown when the value is zero and the conversion factor is inverted.
334971
334968
  // For ratio, we actually want to support this corner case and return "1:0" as the formatted value.
334972
334969
  if (e instanceof _Exception__WEBPACK_IMPORTED_MODULE_1__.QuantityError && e.errorNumber === _Exception__WEBPACK_IMPORTED_MODULE_1__.QuantityStatus.InvertingZero) {
334973
- return "1:0";
334970
+ return { componentText: "1:0", isNegative: false };
334974
334971
  }
334975
334972
  }
334976
334973
  compositeStrings.push(this.formatRatio(unitValue, spec));
334974
+ isNegative = unitValue < 0;
334977
334975
  continue;
334978
334976
  }
334979
- unitValue = (0,_Quantity__WEBPACK_IMPORTED_MODULE_3__.applyConversion)(posMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;
334977
+ unitValue = (0,_Quantity__WEBPACK_IMPORTED_MODULE_3__.applyConversion)(remainingMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;
334980
334978
  if (0 === i) {
334979
+ // Only set isNegative from the first (major) unit conversion
334980
+ isNegative = unitValue < 0;
334981
334981
  const precisionScale = Math.pow(10, 8); // use a fixed round off precision of 8 to avoid loss of precision in actual magnitude
334982
334982
  unitValue = Math.floor(unitValue * precisionScale + FPV_ROUNDFACTOR) / precisionScale;
334983
334983
  if ((Math.abs(unitValue) < 0.0001) && spec.format.hasFormatTraitSet(_FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatTraits.ZeroEmpty))
334984
- return "";
334984
+ return { componentText: "", isNegative: false };
334985
334985
  }
334986
- if (i < spec.format.units.length - 1) {
334987
- const wholePart = Math.floor(unitValue);
334988
- const componentText = Formatter.formatCompositePart(wholePart, false, currentLabel, spec);
334989
- posMagnitude = unitValue - wholePart;
334986
+ if (i < (spec.format.units?.length ?? 0) - 1) {
334987
+ const wholePart = Math.trunc(unitValue);
334988
+ const componentText = Formatter.formatCompositePart(Math.abs(wholePart), false, currentLabel, spec);
334989
+ remainingMagnitude = unitValue - wholePart;
334990
334990
  compositeStrings.push(componentText);
334991
334991
  }
334992
334992
  else {
334993
- const componentText = Formatter.formatCompositePart(unitValue, true, currentLabel, spec);
334993
+ const componentText = Formatter.formatCompositePart(Math.abs(unitValue), true, currentLabel, spec);
334994
334994
  compositeStrings.push(componentText);
334995
334995
  }
334996
334996
  }
334997
- return compositeStrings.join(spec.format.spacerOrDefault);
334997
+ return { componentText: compositeStrings.join(spec.format.spacerOrDefault), isNegative };
334998
334998
  }
334999
334999
  /** Format a quantity value into a single text string. Imitate how formatting done by server method NumericFormatSpec::FormatDouble.
335000
335000
  * @param magnitude quantity value
@@ -335123,45 +335123,58 @@ class Formatter {
335123
335123
  }
335124
335124
  return value;
335125
335125
  }
335126
- /** Format a quantity value into a single text string based on the current format specification of this class.
335127
- * @param magnitude defines the value to spec.format.
335128
- * @param spec A FormatterSpec object the defines specification for the magnitude and unit conversions for the formatter.
335126
+ /** Helper function to apply sign formatting based on showSignOption
335127
+ * @param isNegative whether the value should be treated as negative
335128
+ * @param showSignOption the sign display option
335129
+ * @param formatType the format type (to handle bearing/azimuth exceptions)
335130
+ * @returns object containing prefix and suffix strings
335129
335131
  */
335130
- static formatQuantity(magnitude, spec) {
335131
- const valueIsNegative = magnitude < 0.0;
335132
+ static applySignFormatting(isNegative, showSignOption, formatType) {
335132
335133
  let prefix = "";
335133
335134
  let suffix = "";
335134
- let formattedValue = "";
335135
- if (spec.format.type === _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Bearing || spec.format.type === _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Azimuth) {
335136
- const result = this.processBearingAndAzimuth(magnitude, spec);
335137
- magnitude = result.magnitude;
335138
- prefix = result.prefix ?? "";
335139
- suffix = result.suffix ?? "";
335140
- }
335141
- switch (spec.format.showSignOption) {
335135
+ switch (showSignOption) {
335142
335136
  case _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.ShowSignOption.NegativeParentheses:
335143
- if (valueIsNegative) {
335144
- prefix += "(";
335145
- suffix = `)${suffix}`;
335137
+ if (isNegative) {
335138
+ prefix = "(";
335139
+ suffix = ")";
335146
335140
  }
335147
335141
  break;
335148
335142
  case _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.ShowSignOption.OnlyNegative:
335149
- if (valueIsNegative && spec.format.type !== _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Bearing && spec.format.type !== _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Azimuth)
335150
- prefix += "-";
335143
+ if (isNegative && formatType !== _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Bearing && formatType !== _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Azimuth) {
335144
+ prefix = "-";
335145
+ }
335151
335146
  break;
335152
335147
  case _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.ShowSignOption.SignAlways:
335153
- if (valueIsNegative)
335154
- prefix += "-";
335155
- else
335156
- prefix += "+";
335148
+ prefix = isNegative ? "-" : "+";
335157
335149
  break;
335158
335150
  case _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.ShowSignOption.NoSign:
335159
335151
  default:
335160
335152
  break;
335161
335153
  }
335154
+ return { prefix, suffix };
335155
+ }
335156
+ /** Format a quantity value into a single text string based on the current format specification of this class.
335157
+ * @param magnitude defines the value to spec.format.
335158
+ * @param spec A FormatterSpec object the defines specification for the magnitude and unit conversions for the formatter.
335159
+ */
335160
+ static formatQuantity(magnitude, spec) {
335161
+ let valueIsNegative = magnitude < 0.0;
335162
+ let prefix = "";
335163
+ let suffix = "";
335164
+ let formattedValue = "";
335165
+ // Handle bearing/azimuth special formatting
335166
+ if (spec.format.type === _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Bearing || spec.format.type === _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Azimuth) {
335167
+ const result = this.processBearingAndAzimuth(magnitude, spec);
335168
+ magnitude = result.magnitude;
335169
+ prefix = result.prefix ?? "";
335170
+ suffix = result.suffix ?? "";
335171
+ }
335162
335172
  let formattedMagnitude = "";
335163
335173
  if (spec.format.hasUnits) {
335164
- formattedMagnitude = Formatter.formatComposite(magnitude, spec);
335174
+ const compositeResult = Formatter.formatComposite(magnitude, spec);
335175
+ formattedMagnitude = compositeResult.componentText;
335176
+ // Override the sign detection with the composite conversion result
335177
+ valueIsNegative = compositeResult.isNegative;
335165
335178
  }
335166
335179
  else {
335167
335180
  // unitless quantity
@@ -335172,7 +335185,12 @@ class Formatter {
335172
335185
  else
335173
335186
  formattedMagnitude = formattedMagnitude + spec.format.uomSeparator + spec.unitConversions[0].label;
335174
335187
  }
335188
+ // For unitless quantities, keep original sign detection
335175
335189
  }
335190
+ // Apply sign formatting based on the final determined sign
335191
+ const signFormatting = this.applySignFormatting(valueIsNegative, spec.format.showSignOption, spec.format.type);
335192
+ prefix += signFormatting.prefix;
335193
+ suffix = signFormatting.suffix + suffix;
335176
335194
  // add Sign prefix and suffix as necessary
335177
335195
  if ((prefix.length > 0 || suffix.length > 0) && formattedMagnitude.length > 0)
335178
335196
  formattedValue = prefix + formattedMagnitude + suffix;
@@ -335193,7 +335211,8 @@ class Formatter {
335193
335211
  magnitude -= quarterRevolution;
335194
335212
  quadrant++;
335195
335213
  }
335196
- let prefix, suffix;
335214
+ let prefix = "";
335215
+ let suffix = "";
335197
335216
  // Quadrants are
335198
335217
  // 3 0
335199
335218
  // 2 1
@@ -335220,7 +335239,7 @@ class Formatter {
335220
335239
  prefix = "N";
335221
335240
  }
335222
335241
  }
335223
- return { magnitude, prefix, suffix: suffix };
335242
+ return { magnitude, prefix, suffix };
335224
335243
  }
335225
335244
  if (type === _FormatEnums__WEBPACK_IMPORTED_MODULE_2__.FormatType.Azimuth) {
335226
335245
  let azimuthBase = 0; // default base is North
@@ -337687,7 +337706,7 @@ class TestContext {
337687
337706
  this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
337688
337707
  const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
337689
337708
  await core_frontend_1.NoRenderApp.startup({
337690
- applicationVersion: "5.3.0-dev.2",
337709
+ applicationVersion: "5.3.0-dev.4",
337691
337710
  applicationId: this.settings.gprid,
337692
337711
  authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.serviceAuthToken),
337693
337712
  hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
@@ -362954,7 +362973,7 @@ var loadLanguages = instance.loadLanguages;
362954
362973
  /***/ ((module) => {
362955
362974
 
362956
362975
  "use strict";
362957
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.3.0-dev.2","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/eslint-plugin":"5.2.2-dev.2","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.3.12","playwright":"~1.47.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","typemoq":"^2.1.0","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/cloud-agnostic-core":"^2.2.4","@itwin/object-storage-core":"^2.3.0","@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^4.3.4","@loaders.gl/draco":"^4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
362976
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.3.0-dev.4","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/eslint-plugin":"5.2.2-dev.2","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.3.12","playwright":"~1.47.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","typemoq":"^2.1.0","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/cloud-agnostic-core":"^2.2.4","@itwin/object-storage-core":"^2.3.0","@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^4.3.4","@loaders.gl/draco":"^4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
362958
362977
 
362959
362978
  /***/ }),
362960
362979