@fw-components/formula-editor 2.0.7-formula-editor-enhancements.12 → 2.0.7-formula-editor.22

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.
@@ -6,89 +6,41 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { html, LitElement } from "lit";
8
8
  import { customElement, property, state, query } from "lit/decorators.js";
9
- import { FormulaEditorStyles } from "./styles/formula-editor-styles.js";
10
- import { Parser } from "./parser.js";
11
9
  import "./suggestion-menu.js";
10
+ import { Parser } from "./utils/parser.js";
11
+ import { FormulaEditorStyles } from "./styles/editor.js";
12
12
  let FormulaEditor = class FormulaEditor extends LitElement {
13
13
  constructor() {
14
- super();
14
+ super(...arguments);
15
+ this.recommendations = [];
16
+ this.currentCursorPosition = 0;
17
+ this.isFocused = false;
15
18
  /**
16
- * These `states` and `properties` can't be defined as `static get properties`,
17
- * because TS doesn't support that.
18
- * @see https://github.com/lit/lit-element/issues/414
19
+ * Text area input value
19
20
  */
20
- this._formattedContent = null;
21
- this._recommendations = null;
22
- this._calculatedResult = undefined;
23
- /**
24
- * If `parseInput` is called to add a recommendation, say by clicking,
25
- * browser removes focus from the input box. In that case, we have no way
26
- * of knowing where the cursor previously was, other than storing it somewhere.
27
- */
28
- this.currentCursorPosition = null;
29
- this.currentCursorRect = undefined;
30
- this.lastInputType = "";
31
- this.isFocus = false;
32
21
  this.content = "";
33
22
  this.placeholder = "Type your formula...";
34
23
  this.variables = new Map();
35
24
  this.minSuggestionLen = 2;
36
- this.errorString = null;
37
- this._parser = new Parser(this.variables, this.minSuggestionLen);
25
+ this.errorString = "";
38
26
  }
39
27
  firstUpdated(_changedProperties) {
40
- this._parser = new Parser(this.variables, this.minSuggestionLen);
41
- let editor = this.shadowRoot?.getElementById("wysiwyg-editor");
42
28
  const inputListener = this.handleContentUpdate.bind(this);
43
- editor.addEventListener("input", inputListener);
44
- editor.focus();
45
- }
46
- navigateRecommendations(direction) {
47
- if (!this._recommendations)
48
- return;
49
- const currentIndex = this._recommendations.indexOf(this._selectedRecommendation);
50
- const newIndex = direction === "ArrowDown"
51
- ? (currentIndex + 1) % this._recommendations.length
52
- : direction === "ArrowUp"
53
- ? (currentIndex - 1 + this._recommendations.length) % this._recommendations.length
54
- : currentIndex;
55
- this._selectedRecommendation = this._recommendations[newIndex];
56
- this.scrollToSelectedRecommendation(newIndex);
29
+ this.editor.addEventListener("input", inputListener);
30
+ this.editor.focus();
57
31
  }
58
- scrollToSelectedRecommendation(index) {
59
- const suggestionMenu = this.shadowRoot?.querySelector("suggestion-menu");
60
- if (suggestionMenu) {
61
- const listItem = suggestionMenu.shadowRoot?.querySelectorAll("li")[index];
62
- if (listItem) {
63
- listItem.scrollIntoView({
64
- block: "nearest",
65
- inline: "nearest",
66
- });
32
+ updated(_changedProperties) {
33
+ if (_changedProperties.has("content")) {
34
+ if (!this.content?.trim()) {
35
+ this.recommendations = Array.from(this.variables.keys());
67
36
  }
37
+ this._adjustTextAreaHeight();
68
38
  }
69
- }
70
- handleKeyboardEvents(event) {
71
- if (event.code == "Tab" && this._recommendations?.length == 1) {
72
- this._selectedRecommendation = null;
73
- event.preventDefault();
74
- this.parseInput(this._recommendations[0]);
75
- }
76
- else if (event.code === "ArrowDown" || event.code === "ArrowUp") {
77
- if (this._recommendations)
78
- event.preventDefault();
79
- this.navigateRecommendations(event.code);
80
- this.requestUpdate();
81
- }
82
- else if (event.code === "Enter" && this._selectedRecommendation) {
83
- event.preventDefault();
84
- this.parseInput(this._selectedRecommendation);
85
- this._selectedRecommendation = null;
39
+ if (_changedProperties.has("variables") && this.variables.size) {
40
+ this._parser = new Parser(this.variables, this.minSuggestionLen);
86
41
  }
87
42
  }
88
43
  onClickRecommendation(recommendation) {
89
- let editor = this.shadowRoot?.getElementById("wysiwyg-editor");
90
- if (!editor)
91
- return;
92
44
  this.parseInput(recommendation);
93
45
  }
94
46
  handleContentUpdate(event) {
@@ -97,149 +49,116 @@ let FormulaEditor = class FormulaEditor extends LitElement {
97
49
  this.content = event.target.value;
98
50
  this.parseInput();
99
51
  }
100
- _adjustInputHeight() {
101
- const editor = this.shadowRoot?.getElementById("wysiwyg-editor");
52
+ _adjustTextAreaHeight() {
102
53
  if (!this.content)
103
- editor.style.height = "var(--fe-height, 30px)";
104
- if (editor.scrollHeight > editor.clientHeight)
105
- editor.style.height = (editor.scrollHeight + 5) + "px";
54
+ this.editor.style.height = "var(--fe-height, 30px)";
55
+ if (this.editor.scrollHeight > this.editor.clientHeight)
56
+ this.editor.style.height = String(this.editor.scrollHeight + 5).concat("px");
106
57
  }
107
58
  /**
108
- *
109
59
  * @param recommendation The recommendation which needs to be inserted
110
60
  * at the current cursor position
111
- * @param manageCursor Whether or not cursor management is needed. Not
112
- * needed when manual insertion of text is required (eg: during initialization)
113
61
  * @returns void
114
62
  */
115
- parseInput(recommendation = null) {
116
- let editor = this.shadowRoot?.getElementById("wysiwyg-editor");
117
- if (!editor)
118
- return;
119
- this.currentCursorPosition = editor.selectionStart;
63
+ parseInput(recommendation = "") {
64
+ this.currentCursorPosition = this.editor.selectionStart;
120
65
  const parseOutput = this._parser.parseInput(this.content, this.currentCursorPosition, recommendation);
121
- this._recommendations = parseOutput.recommendations;
122
- this._formattedContent = parseOutput.formattedContent;
66
+ this.recommendations = parseOutput.recommendations;
123
67
  this.errorString = parseOutput.errorString;
124
68
  /**
125
69
  * Don't modify the text stream manually if the text is being composed,
126
- * unless the user manually chooses to do so by selecting a suggestion.
70
+ * unless the user manually chooses to do so by selecting a recommendation.
127
71
  * @see https://github.com/w3c/input-events/issues/86
128
72
  * @see https://github.com/w3c/input-events/pull/122
129
73
  * @see https://bugs.chromium.org/p/chromium/issues/detail?id=689541
130
- * */
74
+ */
131
75
  if (this.lastInputType !== "insertCompositionText" || recommendation) {
132
- const formattedString = parseOutput.formattedString;
133
- this.content = formattedString;
76
+ this.content = parseOutput.formattedString;
134
77
  }
135
- if (recommendation) {
136
- this._recommendations = null;
78
+ if (Boolean(recommendation)) {
79
+ this.recommendations = [];
137
80
  this.currentCursorPosition = parseOutput.newCursorPosition;
81
+ /**
82
+ * update cursor position in text area
83
+ */
138
84
  setTimeout(() => {
139
- editor.setSelectionRange(this.currentCursorPosition, this.currentCursorPosition);
85
+ this.editor.setSelectionRange(this.currentCursorPosition, this.currentCursorPosition);
140
86
  }, 0);
141
87
  }
142
88
  this.dispatchEvent(new CustomEvent("fw-formula-content-changed", {
143
89
  detail: {
144
90
  formulaString: this.content,
145
91
  error: this.errorString,
146
- recommendations: this._recommendations
92
+ recommendations: this.recommendations,
147
93
  },
148
94
  bubbles: true,
149
95
  }));
150
- editor.focus();
151
96
  }
152
- requestCalculate() {
153
- if (this._parser.parseInput(this.content).errorString) {
97
+ formatFormula() {
98
+ if (!Boolean(this.content))
154
99
  return;
155
- }
156
- const calculatedResult = this._parser.calculate(this.content);
157
100
  this.content = this._parser.addParentheses(this.content) ?? this.content;
158
101
  this.parseInput();
159
- this._calculatedResult = calculatedResult.result;
160
- this.errorString = calculatedResult.errorString;
161
- this._recommendations = null;
162
- this.requestUpdate();
102
+ this.recommendations = [];
163
103
  }
164
- requestFormat() {
165
- if (!Boolean(this.content)) {
166
- return;
167
- }
168
- this.content = this._parser.addParentheses(this.content) ?? this.content;
169
- this.parseInput();
170
- this._recommendations = null;
171
- this.requestUpdate();
104
+ handleFocus(focus) {
105
+ this.isFocused = focus;
172
106
  }
173
- async updated(_changedProperties) {
174
- if (_changedProperties.has("content")) {
175
- if (!this.content.trim()) {
176
- this._recommendations = Array.from(this.variables.keys());
107
+ handleKeydown(event) {
108
+ if (event.code === "Tab") {
109
+ event.preventDefault();
110
+ if (this.recommendations?.length === 1) {
111
+ this.suggestionMenu._handleRecommendationSelect();
112
+ }
113
+ else {
114
+ const direction = event.shiftKey ? "up" : "down";
115
+ this.suggestionMenu.navigate(direction);
177
116
  }
178
- this._adjustInputHeight();
179
117
  }
180
- if (_changedProperties.has("variables")) {
181
- this._parser = new Parser(this.variables, this.minSuggestionLen);
118
+ else if (event.code === "ArrowDown" || event.code === "ArrowUp") {
119
+ event.preventDefault();
120
+ const direction = event.code === "ArrowDown" ? "down" : "up";
121
+ this.suggestionMenu.navigate(direction);
182
122
  }
183
- }
184
- handleFocusOut(e) {
185
- this.isFocus = false;
186
- this._recommendations = null;
187
- this.requestUpdate();
188
- }
189
- handleFocus(e) {
190
- this.isFocus = true;
191
- if (!this.content.trim()) {
192
- this._recommendations = Array.from(this.variables.keys());
123
+ else if (event.code === "Enter") {
124
+ event.preventDefault();
125
+ this.suggestionMenu._handleRecommendationSelect();
193
126
  }
194
127
  }
195
128
  render() {
196
129
  return html `
197
- <style>
198
- ${FormulaEditorStyles}
199
- </style>
130
+ <style>${FormulaEditorStyles}</style>
131
+
132
+ ${this.label ? html `<label for="wysiwyg-editor" class="editor-label">${this.label}</label>` : ""}
133
+
134
+ <textarea
135
+ id="wysiwyg-editor"
136
+ class=${this.errorString?.length ? "error" : ""}
137
+ .value=${this.content}
138
+ .placeholder=${this.placeholder}
139
+ spellcheck="false"
140
+ autocomplete="off"
141
+ @keydown=${this.handleKeydown}
142
+ @blur=${() => this.handleFocus(false)}
143
+ @focus=${() => this.handleFocus(true)}
144
+ ></textarea>
200
145
 
201
- ${this.label
202
- ? html `<label for="wysiwyg-editor" class="formula-editor-label">
203
- ${this.label}
204
- </label>`
205
- : ""}
206
-
207
- <textarea
208
- placeholder=${this.placeholder}
209
- id="wysiwyg-editor"
210
- class=${this.errorString?.length ? "error" : ""}
211
- .value=${this.content}
212
- @keydown=${this.handleKeyboardEvents}
213
- @blur=${this.handleFocusOut}
214
- @focus=${this.handleFocus}
215
- ></textarea>
216
- ${this._recommendations && this.isFocus
217
- ? html ` <suggestion-menu
218
- .recommendations=${this._recommendations}
219
- .currentSelection=${this._selectedRecommendation}
220
- .onClickRecommendation=${(e) => this.onClickRecommendation(e)}
221
- @mousedown=${(e) => e.preventDefault()}
222
- ></suggestion-menu>`
223
- : html ``}
224
- <p>${this._calculatedResult}</p>
146
+ ${this.isFocused && this.recommendations?.length
147
+ ? html `<suggestion-menu
148
+ .recommendations=${this.recommendations}
149
+ .currentSelection=${this._selectedRecommendation}
150
+ .onClickRecommendation=${this.onClickRecommendation.bind(this)}
151
+ ></suggestion-menu>`
152
+ : ''}
225
153
  `;
226
154
  }
227
155
  };
228
156
  __decorate([
229
157
  state()
230
- ], FormulaEditor.prototype, "_formattedContent", void 0);
231
- __decorate([
232
- state()
233
- ], FormulaEditor.prototype, "_recommendations", void 0);
234
- __decorate([
235
- state()
236
- ], FormulaEditor.prototype, "_calculatedResult", void 0);
158
+ ], FormulaEditor.prototype, "recommendations", void 0);
237
159
  __decorate([
238
160
  state()
239
161
  ], FormulaEditor.prototype, "currentCursorPosition", void 0);
240
- __decorate([
241
- state()
242
- ], FormulaEditor.prototype, "currentCursorRect", void 0);
243
162
  __decorate([
244
163
  state()
245
164
  ], FormulaEditor.prototype, "lastInputType", void 0);
@@ -248,7 +167,7 @@ __decorate([
248
167
  ], FormulaEditor.prototype, "_selectedRecommendation", void 0);
249
168
  __decorate([
250
169
  state()
251
- ], FormulaEditor.prototype, "isFocus", void 0);
170
+ ], FormulaEditor.prototype, "isFocused", void 0);
252
171
  __decorate([
253
172
  property()
254
173
  ], FormulaEditor.prototype, "content", void 0);
@@ -259,19 +178,7 @@ __decorate([
259
178
  property()
260
179
  ], FormulaEditor.prototype, "label", void 0);
261
180
  __decorate([
262
- property({
263
- type: (Map),
264
- converter: {
265
- fromAttribute: (value) => {
266
- if (value) {
267
- return new Map(JSON.parse(value));
268
- }
269
- },
270
- toAttribute: (value) => {
271
- return JSON.stringify(Array.from(value.entries()));
272
- },
273
- },
274
- })
181
+ property()
275
182
  ], FormulaEditor.prototype, "variables", void 0);
276
183
  __decorate([
277
184
  property()
@@ -280,8 +187,11 @@ __decorate([
280
187
  property()
281
188
  ], FormulaEditor.prototype, "errorString", void 0);
282
189
  __decorate([
283
- query("wysiwyg-editor")
190
+ query("#wysiwyg-editor")
284
191
  ], FormulaEditor.prototype, "editor", void 0);
192
+ __decorate([
193
+ query("suggestion-menu")
194
+ ], FormulaEditor.prototype, "suggestionMenu", void 0);
285
195
  FormulaEditor = __decorate([
286
196
  customElement("formula-editor")
287
197
  ], FormulaEditor);
@@ -1,6 +1,6 @@
1
1
  import { css } from "lit";
2
2
  export const FormulaEditorStyles = css `
3
- .formula-editor-label {
3
+ .editor-label {
4
4
  display: block;
5
5
  font-size: var(--fe-label-font-size, 0.8rem);
6
6
  color: var(--fe-label-color, #515151);
@@ -13,7 +13,7 @@ export const FormulaEditorStyles = css `
13
13
  padding: var(--fe-padding, 4px);
14
14
  caret-color: var(--fe-caret-color, #fff);
15
15
  color: var(--fe-text-color, #f7f1ff);
16
- font-size: var(--fe-text-font-size, 12px);
16
+ font-size: var(--fe-text-font-size, 14px);
17
17
  min-width: 100%;
18
18
  min-height: 30px;
19
19
  height: var(--fe-height, 30px);
@@ -0,0 +1,58 @@
1
+ import { css } from "lit";
2
+ export const SuggestionMenuStyles = css `
3
+ ul {
4
+ position: relative;
5
+ border: 1px solid var(--fe-suggestion-color, white);
6
+ color: var(--fe-suggestion-color, #bab6c0);
7
+ background-color: var(--fe-suggestion-background-color, white);
8
+ box-sizing: border-box;
9
+ width: var(--fe-suggestion-width, 20vw);
10
+ max-height: 25vh;
11
+ overflow-x: auto;
12
+ overflow-y: auto;
13
+ list-style-type: none;
14
+ padding: 0;
15
+ margin: 0;
16
+ box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
17
+ border-radius: 5px;
18
+ z-index: 99999;
19
+ }
20
+
21
+ li {
22
+ margin: 0;
23
+ padding: 0.5em 1rem;
24
+ cursor: pointer;
25
+ font-family: var(--theme-font);
26
+ font-size: var(--secondary-font-size, 16px);
27
+ color: var(--secondary-color, #bab6c0);
28
+ }
29
+
30
+ li:hover, li:focus-visible, li.selected {
31
+ color: var(--fe-suggestion-focus-color, #69676c);
32
+ background: rgba(var(--fe-suggestion-focus-background, 86, 86, 86), 0.1);
33
+ }
34
+
35
+
36
+ /* Scrollbar styling */
37
+ ::-webkit-scrollbar {
38
+ width: 10px;
39
+ }
40
+
41
+ ::-webkit-scrollbar-track {
42
+ background: transparent;
43
+ }
44
+
45
+ ::-webkit-scrollbar-thumb {
46
+ background: #ccc;
47
+ border-radius: 5px;
48
+ }
49
+
50
+ ::-webkit-scrollbar-thumb:hover {
51
+ background: #aaa;
52
+ }
53
+
54
+ /* Optional shadow for the dropdown */
55
+ .content {
56
+ box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
57
+ }
58
+ `;
@@ -4,101 +4,52 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { css, html, LitElement } from "lit";
8
- import { customElement, property } from "lit/decorators.js";
7
+ import { html, LitElement } from "lit";
8
+ import { customElement, property, query, state } from "lit/decorators.js";
9
+ import { SuggestionMenuStyles } from "./styles/suggestion-menu";
9
10
  let SuggestionMenu = class SuggestionMenu extends LitElement {
10
11
  constructor() {
11
12
  super(...arguments);
12
13
  this.recommendations = [];
13
14
  this.onClickRecommendation = (recommendation) => { };
14
- this.currentSelection = "";
15
+ this._selectedRecommendationIndex = 0;
15
16
  }
16
- static { this.styles = css `
17
- ul {
18
- position: relative;
19
- border: 1px solid var(--fe-suggestion-color, white);
20
- color: var(--fe-suggestion-color, #bab6c0);
21
- background-color: var(--fe-suggestion-background-color, white);
22
- box-sizing: border-box;
23
- width: var(--fe-suggestion-width, 20vw);
24
- max-height: 25vh;
25
- overflow-x: auto;
26
- overflow-y: auto;
27
- list-style-type: none;
28
- padding: 0;
29
- margin: 0;
30
- box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
31
- border-radius: 5px;
32
- z-index: 99999
33
- }
34
-
35
- li {
36
- margin: 0;
37
- padding: 0.5em 1rem;
38
- cursor: pointer;
39
- font-family: var(--theme-font);
40
- font-size: var(--secondary-font-size, 16px);
41
- color: var(--secondary-color, #bab6c0);
42
- }
43
-
44
- li:hover,
45
- li:focus-visible {
46
- font-weight: bold;
47
- color: var(--fe-suggestion-focus-color, #69676c);
48
- }
49
-
50
- li.selected {
51
- color: var(--fe-suggestion-focus-color, #69676c);
52
- font-weight: bold;
53
- }
54
-
55
- li[focused] {
56
- font-weight: bold;
57
- }
58
-
59
- /* Scrollbar styling */
60
- ::-webkit-scrollbar {
61
- width: 10px;
62
- }
63
-
64
- ::-webkit-scrollbar-track {
65
- background: transparent;
66
- }
67
-
68
- ::-webkit-scrollbar-thumb {
69
- background: #ccc;
70
- border-radius: 5px;
71
- }
72
-
73
- ::-webkit-scrollbar-thumb:hover {
74
- background: #aaa;
75
- }
76
-
77
- /* Optional shadow for the dropdown */
78
- .content {
79
- box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
80
- }
81
- `; }
82
- handleKeydown(event, recommendation) {
83
- if (event.code == "Enter") {
84
- event.preventDefault();
85
- event.stopPropagation();
86
- this.onClickRecommendation(recommendation);
87
- }
17
+ scrollToSelectedRecommendation(index) {
18
+ const listItem = this.suggestionList?.querySelectorAll("li")[index];
19
+ if (!listItem)
20
+ return;
21
+ listItem.scrollIntoView({
22
+ block: "nearest",
23
+ inline: "nearest",
24
+ behavior: "smooth"
25
+ });
26
+ }
27
+ navigate(direction) {
28
+ if (!this.recommendations)
29
+ return;
30
+ let newIndex = this._selectedRecommendationIndex;
31
+ if (direction === "down")
32
+ newIndex = (this._selectedRecommendationIndex + 1) % this.recommendations.length;
33
+ else if (direction === "up")
34
+ newIndex = (this._selectedRecommendationIndex - 1 + this.recommendations.length) % this.recommendations.length;
35
+ this._selectedRecommendationIndex = newIndex;
36
+ this.scrollToSelectedRecommendation(newIndex);
37
+ }
38
+ _handleRecommendationSelect(index = this._selectedRecommendationIndex) {
39
+ const recommendation = this.recommendations[index];
40
+ if (!recommendation)
41
+ return;
42
+ this.onClickRecommendation(recommendation);
43
+ this._selectedRecommendationIndex = -1;
88
44
  }
89
45
  render() {
90
46
  return html `
91
- <ul class="wysiwyg-suggestion-menu">
92
- ${this.recommendations.map((recommendation) => {
93
- return html `<li
94
- class="${this.currentSelection === recommendation ? 'selected' : ''}"
95
- tabindex="0"
96
- @click=${(e) => this.onClickRecommendation(recommendation)}
97
- @keydown=${(e) => this.handleKeydown(e, recommendation)}
98
- >
99
- ${recommendation}
100
- </li>`;
101
- })}
47
+ <style>${SuggestionMenuStyles}</style>
48
+ <ul class="wysiwyg-suggestion-menu" @mousedown=${(e) => e.preventDefault()}>
49
+ ${this.recommendations.map((recommendation, index) => html `<li
50
+ class="${this._selectedRecommendationIndex === index ? "selected" : ""}"
51
+ @click=${(e) => this._handleRecommendationSelect(index)}
52
+ >${recommendation}</li>`)}
102
53
  </ul>
103
54
  `;
104
55
  }
@@ -110,8 +61,14 @@ __decorate([
110
61
  property()
111
62
  ], SuggestionMenu.prototype, "onClickRecommendation", void 0);
112
63
  __decorate([
113
- property()
114
- ], SuggestionMenu.prototype, "currentSelection", void 0);
64
+ state()
65
+ ], SuggestionMenu.prototype, "_selectedRecommendationIndex", void 0);
66
+ __decorate([
67
+ state()
68
+ ], SuggestionMenu.prototype, "abortController", void 0);
69
+ __decorate([
70
+ query(".wysiwyg-suggestion-menu")
71
+ ], SuggestionMenu.prototype, "suggestionList", void 0);
115
72
  SuggestionMenu = __decorate([
116
73
  customElement("suggestion-menu")
117
74
  ], SuggestionMenu);
@@ -1,3 +1,9 @@
1
+ export var Expectation;
2
+ (function (Expectation) {
3
+ Expectation[Expectation["VARIABLE"] = 0] = "VARIABLE";
4
+ Expectation[Expectation["OPERATOR"] = 1] = "OPERATOR";
5
+ Expectation[Expectation["UNDEFINED"] = 2] = "UNDEFINED";
6
+ })(Expectation || (Expectation = {}));
1
7
  export var Operator;
2
8
  (function (Operator) {
3
9
  Operator["PLUS"] = "+";
@@ -0,0 +1,8 @@
1
+ export const mathematicalOperators = new Set(["^", "+", "-", "*", "/"]);
2
+ export const operatorPrecedence = {
3
+ "^": 3,
4
+ "/": 2,
5
+ "*": 2,
6
+ "+": 1,
7
+ "-": 1,
8
+ };