@odoo/o-spreadsheet 16.0.21 → 16.0.23

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.
@@ -0,0 +1,3263 @@
1
+ <odoo>
2
+ <t t-name="o-spreadsheet-Autofill" owl="1">
3
+ <div
4
+ class="o-autofill"
5
+ t-on-mousedown="onMouseDown"
6
+ t-att-style="style"
7
+ t-on-dblclick="onDblClick">
8
+ <div class="o-autofill-handler" t-att-style="styleHandler"/>
9
+ <t t-set="tooltip" t-value="getTooltip()"/>
10
+ <div t-if="tooltip" class="o-autofill-nextvalue" t-att-style="styleNextvalue">
11
+ <t t-component="tooltip.component" t-props="tooltip.props"/>
12
+ </div>
13
+ </div>
14
+ </t>
15
+
16
+ <t t-name="o-spreadsheet-BottomBar" owl="1">
17
+ <div
18
+ class="o-spreadsheet-bottom-bar o-two-columns"
19
+ t-on-click="props.onClick"
20
+ t-ref="bottomBar">
21
+ <div
22
+ class="o-sheet-item o-add-sheet"
23
+ t-att-class="{'disabled': env.model.getters.isReadonly()}"
24
+ t-on-click="addSheet">
25
+ <t t-call="o-spreadsheet-Icon.PLUS"/>
26
+ </div>
27
+ <div class="o-sheet-item o-list-sheets" t-on-click="listSheets">
28
+ <t t-call="o-spreadsheet-Icon.LIST"/>
29
+ </div>
30
+ <div class="o-all-sheets flex-shrink-0 me-3">
31
+ <t t-foreach="getVisibleSheets()" t-as="sheet" t-key="sheet.id">
32
+ <div
33
+ class="o-sheet-item o-sheet"
34
+ t-on-click="(ev) => this.activateSheet(sheet.id, ev)"
35
+ t-on-contextmenu.prevent="(ev) => this.onContextMenu(sheet.id, ev)"
36
+ t-att-title="sheet.name"
37
+ t-att-data-id="sheet.id"
38
+ t-att-class="{active: sheet.id === env.model.getters.getActiveSheetId()}">
39
+ <span
40
+ class="o-sheet-name"
41
+ t-esc="sheet.name"
42
+ t-on-dblclick="(ev) => this.onDblClick(sheet.id, ev)"
43
+ />
44
+ <span class="o-sheet-icon" t-on-click="(ev) => this.onIconClick(sheet.id, ev)">
45
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
46
+ </span>
47
+ </div>
48
+ </t>
49
+ </div>
50
+
51
+ <t t-set="selectedStatistic" t-value="getSelectedStatistic()"/>
52
+ <div
53
+ t-if="selectedStatistic !== undefined"
54
+ class="o-selection-statistic text-truncate"
55
+ t-on-click="listSelectionStatistics">
56
+ <t t-esc="selectedStatistic"/>
57
+ <span>
58
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
59
+ </span>
60
+ </div>
61
+
62
+ <Menu
63
+ t-if="menuState.isOpen"
64
+ position="menuState.position"
65
+ menuItems="menuState.menuItems"
66
+ onClose="() => this.menuState.isOpen=false"
67
+ menuId="menuState.menuId"
68
+ />
69
+ </div>
70
+ </t>
71
+
72
+ <t t-name="o-spreadsheet-ClientTag" owl="1">
73
+ <div>
74
+ <div class="o-client-tag" t-att-style="tagStyle" t-esc="props.name"/>
75
+ </div>
76
+ </t>
77
+
78
+ <t t-name="o-spreadsheet-ColorPicker" owl="1">
79
+ <div
80
+ class="o-color-picker"
81
+ t-att-class="props.dropdownDirection || 'right'"
82
+ t-att-style="colorPickerStyle">
83
+ <div class="o-color-picker-section-name">Standard</div>
84
+ <div class="colors-grid">
85
+ <div
86
+ t-foreach="COLORS"
87
+ t-as="color"
88
+ t-key="color"
89
+ class="o-color-picker-line-item"
90
+ t-att-data-color="color"
91
+ t-on-click="() => this.onColorClick(color)"
92
+ t-attf-style="background-color:{{color}};">
93
+ <div
94
+ t-if="isSameColor(props.currentColor, color)"
95
+ align="center"
96
+ t-attf-style="color:{{getCheckMarkColor()}}">
97
+ ✓
98
+ </div>
99
+ </div>
100
+ </div>
101
+ <div class="o-separator"/>
102
+ <div class="o-color-picker-section-name">
103
+ <span>Custom</span>
104
+ </div>
105
+ <div class="colors-grid">
106
+ <div
107
+ class="o-color-picker-toggler o-color-picker-line-item"
108
+ t-on-click.stop="toggleColorPicker">
109
+ <div class="o-color-picker-toggler-sign">
110
+ <t t-call="o-spreadsheet-Icon.PLUS"/>
111
+ </div>
112
+ </div>
113
+ <div
114
+ t-foreach="env.model.getters.getCustomColors()"
115
+ t-as="color"
116
+ t-key="color"
117
+ class="o-color-picker-line-item"
118
+ t-att-data-color="color"
119
+ t-attf-style="background-color:{{color}};"
120
+ t-on-click="() => this.onColorClick(color)">
121
+ <div
122
+ t-if="isSameColor(props.currentColor, color)"
123
+ align="center"
124
+ t-attf-style="color:{{getCheckMarkColor()}}">
125
+ ✓
126
+ </div>
127
+ </div>
128
+ </div>
129
+ <div t-if="state.showGradient" class="o-custom-selector">
130
+ <div class="o-magnifier-glass" t-att-style="magnifyingGlassStyle"/>
131
+ <div
132
+ class="o-gradient"
133
+ t-on-click.stop="computeCustomColor"
134
+ t-on-mouseout="hideMagnifier"
135
+ t-on-mousemove="moveMagnifier"
136
+ t-on-mouseover="showMagnifier"
137
+ />
138
+ <div class="o-custom-input-preview">
139
+ <input
140
+ type="text"
141
+ t-att-class="{'o-wrong-color': state.isCurrentColorInvalid }"
142
+ t-on-click.stop=""
143
+ t-model="state.currentColor"
144
+ />
145
+ <div class="o-color-preview" t-attf-style="background-color:{{state.currentColor}}"/>
146
+ </div>
147
+ <div class="o-custom-input-buttons">
148
+ <button class="o-add-button" t-on-click="setCustomColor">Add</button>
149
+ </div>
150
+ </div>
151
+ <div class="o-separator"/>
152
+ <div class="o-buttons">
153
+ <button t-on-click="resetColor" class="o-cancel">Reset</button>
154
+ </div>
155
+ </div>
156
+ </t>
157
+
158
+ <t t-name="o-spreadsheet-TextValueProvider" owl="1">
159
+ <div
160
+ t-att-class="{'o-autocomplete-dropdown':state.values.length}"
161
+ t-att-style="state.values.length > 0 ? props.borderStyle : null">
162
+ <t t-foreach="state.values" t-as="v" t-key="v.text">
163
+ <div
164
+ t-att-class="{'o-autocomplete-value-focus': state.selectedIndex === v_index}"
165
+ t-on-click.stop.prevent="() => this.fillValue(v_index)">
166
+ <div class="o-autocomplete-value" t-esc="v.text"/>
167
+ <div
168
+ class="o-autocomplete-description"
169
+ t-esc="v.description"
170
+ t-if="state.selectedIndex === v_index"
171
+ />
172
+ </div>
173
+ </t>
174
+ </div>
175
+ </t>
176
+
177
+ <t t-name="o-spreadsheet-Composer" owl="1">
178
+ <div class="o-composer-container">
179
+ <div
180
+ t-att-class="{ 'o-composer': true, 'text-muted': env.model.getters.isReadonly(), 'unfocusable': env.model.getters.isReadonly() }"
181
+ t-att-style="props.inputStyle"
182
+ t-ref="o_composer"
183
+ tabindex="1"
184
+ t-att-contenteditable="env.model.getters.isReadonly() ? 'false' : 'true'"
185
+ spellcheck="false"
186
+ t-on-keydown="onKeydown"
187
+ t-on-mousedown="onMousedown"
188
+ t-on-input="onInput"
189
+ t-on-keyup="onKeyup"
190
+ t-on-click="onClick"
191
+ t-on-blur="onBlur"
192
+ t-on-paste.stop=""
193
+ t-on-compositionstart="onCompositionStart"
194
+ t-on-compositionend="onCompositionEnd"
195
+ />
196
+
197
+ <div
198
+ t-if="props.focus !== 'inactive' and (autoCompleteState.showProvider or functionDescriptionState.showDescription)"
199
+ class="o-composer-assistant"
200
+ t-att-style="assistantStyle">
201
+ <TextValueProvider
202
+ t-if="autoCompleteState.showProvider"
203
+ exposeAPI="(api) => this.autocompleteAPI = api"
204
+ search="autoCompleteState.search"
205
+ provider="autoCompleteState.provider"
206
+ onCompleted="(text) => this.onCompleted(text)"
207
+ borderStyle="borderStyle"
208
+ />
209
+ <FunctionDescriptionProvider
210
+ t-if="functionDescriptionState.showDescription"
211
+ functionName="functionDescriptionState.functionName"
212
+ functionDescription="functionDescriptionState.functionDescription"
213
+ argToFocus="functionDescriptionState.argToFocus"
214
+ borderStyle="borderStyle"
215
+ />
216
+ </div>
217
+ </div>
218
+ </t>
219
+
220
+ <t t-name="o-spreadsheet-FunctionDescriptionProvider" owl="1">
221
+ <div
222
+ class="o-formula-assistant-container"
223
+ t-att-style="props.borderStyle"
224
+ t-att-class="{
225
+ 'o-formula-assistant-event-none': assistantState.allowCellSelectionBehind,
226
+ 'o-formula-assistant-event-auto': !assistantState.allowCellSelectionBehind
227
+ }">
228
+ <t t-set="context" t-value="getContext()"/>
229
+ <div
230
+ class="o-formula-assistant"
231
+ t-if="context.functionName"
232
+ t-on-mousemove="onMouseMove"
233
+ t-att-class="{'o-formula-assistant-transparency': assistantState.allowCellSelectionBehind}">
234
+ <div class="o-formula-assistant-head">
235
+ <span t-esc="context.functionName"/>
236
+ (
237
+ <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
238
+ <span t-if="arg_index > '0'">,&#xA0;</span>
239
+ <span t-att-class="{ 'o-formula-assistant-focus': context.argToFocus === arg_index }">
240
+ <span>
241
+ <span t-if="arg.optional || arg.repeating || arg.default">[</span>
242
+ <span t-esc="arg.name"/>
243
+ <span t-if="arg.repeating">, ...</span>
244
+ <span t-if="arg.optional || arg.repeating || arg.default">]</span>
245
+ </span>
246
+ </span>
247
+ </t>
248
+ )
249
+ </div>
250
+
251
+ <div class="o-formula-assistant-core">
252
+ <div class="o-formula-assistant-gray">ABOUT</div>
253
+ <div t-esc="context.functionDescription.description"/>
254
+ </div>
255
+
256
+ <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
257
+ <div
258
+ class="o-formula-assistant-arg"
259
+ t-att-class="{
260
+ 'o-formula-assistant-gray': context.argToFocus >= '0',
261
+ 'o-formula-assistant-focus': context.argToFocus === arg_index,
262
+ }">
263
+ <div>
264
+ <span t-esc="arg.name"/>
265
+ <span
266
+ t-if="arg.optional || arg.repeating || arg.default ">&#xA0;- [optional]&#xA0;</span>
267
+ <span t-if="arg.default">
268
+ <t t-esc="arg.defaultValue"/>
269
+ <span>&#xA0;by default</span>
270
+ </span>
271
+ <span t-if="arg.repeating">repeatable</span>
272
+ </div>
273
+ <div class="o-formula-assistant-arg-description" t-esc="arg.description"/>
274
+ </div>
275
+ </t>
276
+ </div>
277
+ </div>
278
+ </t>
279
+
280
+ <t t-name="o-spreadsheet-GridComposer" owl="1">
281
+ <div class="o-grid-composer" t-att-style="containerStyle" t-ref="gridComposer">
282
+ <Composer
283
+ focus="props.focus"
284
+ inputStyle="composerStyle"
285
+ rect="composerState.rect"
286
+ delimitation="composerState.delimitation"
287
+ onComposerUnmounted="props.onComposerUnmounted"
288
+ onComposerContentFocused="props.onComposerContentFocused"
289
+ />
290
+ </div>
291
+ </t>
292
+
293
+ <t t-name="o-spreadsheet-SpreadsheetDashboard" owl="1">
294
+ <div
295
+ class="o-grid o-two-columns"
296
+ tabindex="-1"
297
+ t-on-wheel="onMouseWheel"
298
+ t-on-click="onClosePopover">
299
+ <div class="mx-auto h-100 position-relative" t-ref="grid" t-att-style="gridContainer">
300
+ <GridOverlay
301
+ onCellHovered.bind="onCellHovered"
302
+ onGridResized.bind="onGridResized"
303
+ onGridMoved.bind="moveCanvas"
304
+ gridOverlayDimensions="gridOverlayDimensions"
305
+ />
306
+ <canvas t-ref="canvas"/>
307
+ <GridPopover
308
+ gridPosition="canvasPosition"
309
+ hoveredCell="hoveredCell"
310
+ onMouseWheel.bind="onMouseWheel"
311
+ onClosePopover.bind="onClosePopover"
312
+ />
313
+ <div
314
+ t-foreach="getClickableCells()"
315
+ t-as="clickableCell"
316
+ t-key="clickableCell.cell.id"
317
+ class="o-dashboard-clickable-cell"
318
+ t-on-click="() => this.selectClickableCell(clickableCell)"
319
+ t-on-contextmenu.prevent=""
320
+ t-att-style="getCellClickableStyle(clickableCell.coordinates)"
321
+ />
322
+ <FilterIconsOverlay/>
323
+ </div>
324
+ <VerticalScrollBar/>
325
+ <HorizontalScrollBar/>
326
+ <div class="o-scrollbar corner"/>
327
+ </div>
328
+ </t>
329
+
330
+ <t t-name="o-spreadsheet-ErrorToolTip" owl="1">
331
+ <div class="o-error-tooltip">
332
+ <t t-esc="props.text"/>
333
+ </div>
334
+ </t>
335
+
336
+ <t t-name="o-spreadsheet-ChartJsComponent" owl="1">
337
+ <canvas class="o-figure-canvas w-100 h-100" t-att-style="canvasStyle" t-ref="graphContainer"/>
338
+ </t>
339
+
340
+ <t t-name="o-spreadsheet-ScorecardChart" owl="1">
341
+ <div class="o-scorecard w-100 h-100" t-att-style="chartStyle" t-ref="chart">
342
+ <t t-set="textStyles" t-value="getTextStyles()"/>
343
+ <div t-if="title" class="o-title-text" t-esc="title" t-att-style="textStyles.titleStyle"/>
344
+ <div class="o-scorecard-content" t-att-style="chartContentStyle">
345
+ <div class="o-key-text" t-if="keyValue" t-esc="keyValue" t-att-style="textStyles.keyStyle"/>
346
+ <t t-if="baseline || baselineDescr">
347
+ <div class="o-baseline-text" t-att-style="textStyles.baselineStyle">
348
+ <t t-if="baseline">
349
+ <t t-if="baselineArrowDirection === 'up'">
350
+ <t t-call="o-spreadsheet-Icon.ARROW_UP">
351
+ <t t-set="color" t-value="'fill : ' + runtime.baselineColor"/>
352
+ </t>
353
+ </t>
354
+ <t t-if="baselineArrowDirection === 'down'">
355
+ <t t-call="o-spreadsheet-Icon.ARROW_DOWN">
356
+ <t t-set="color" t-value="'fill : ' + runtime.baselineColor"/>
357
+ </t>
358
+ </t>
359
+ <span t-att-style="textStyles.baselineValueStyle" class="o-baseline-text-value">
360
+ <t t-esc="baseline"/>
361
+ </span>
362
+ </t>
363
+ <span t-att-style="textStyles.baselineDescrStyle" class="o-baseline-text-description">
364
+ <t t-esc="env._t(baselineDescr)"/>
365
+ </span>
366
+ </div>
367
+ </t>
368
+ </div>
369
+ </div>
370
+ </t>
371
+
372
+ <t t-name="o-spreadsheet-FigureComponent" owl="1">
373
+ <div class="o-figure-wrapper pe-auto" t-att-style="wrapperStyle">
374
+ <div
375
+ class="o-figure w-100 h-100"
376
+ t-on-mousedown.stop="(ev) => this.onMouseDown(ev)"
377
+ t-ref="figure"
378
+ t-att-style="props.style"
379
+ tabindex="0"
380
+ t-on-keydown.stop="(ev) => this.onKeyDown(ev)"
381
+ t-on-keyup.stop="">
382
+ <t
383
+ t-component="figureRegistry.get(props.figure.tag).Component"
384
+ t-key="props.figure.id"
385
+ onFigureDeleted="props.onFigureDeleted"
386
+ figure="props.figure"
387
+ />
388
+ </div>
389
+ <div class="o-figure-border w-100 h-100 position-absolute pe-none" t-att-style="borderStyle"/>
390
+ <t t-if="isSelected">
391
+ <div
392
+ class="o-fig-anchor o-top"
393
+ t-att-style="this.getResizerPosition('top')"
394
+ t-on-mousedown="(ev) => this.clickAnchor(0,-1, ev)"
395
+ />
396
+ <div
397
+ class="o-fig-anchor o-topRight"
398
+ t-att-style="this.getResizerPosition('top right')"
399
+ t-on-mousedown="(ev) => this.clickAnchor(1,-1, ev)"
400
+ />
401
+ <div
402
+ class="o-fig-anchor o-right"
403
+ t-att-style="this.getResizerPosition('right')"
404
+ t-on-mousedown="(ev) => this.clickAnchor(1,0, ev)"
405
+ />
406
+ <div
407
+ class="o-fig-anchor o-bottomRight"
408
+ t-att-style="this.getResizerPosition('bottom right')"
409
+ t-on-mousedown="(ev) => this.clickAnchor(1,1, ev)"
410
+ />
411
+ <div
412
+ class="o-fig-anchor o-bottom"
413
+ t-att-style="this.getResizerPosition('bottom')"
414
+ t-on-mousedown="(ev) => this.clickAnchor(0,1, ev)"
415
+ />
416
+ <div
417
+ class="o-fig-anchor o-bottomLeft"
418
+ t-att-style="this.getResizerPosition('bottom left')"
419
+ t-on-mousedown="(ev) => this.clickAnchor(-1,1, ev)"
420
+ />
421
+ <div
422
+ class="o-fig-anchor o-left"
423
+ t-att-style="this.getResizerPosition('left')"
424
+ t-on-mousedown="(ev) => this.clickAnchor(-1,0, ev)"
425
+ />
426
+ <div
427
+ class="o-fig-anchor o-topLeft"
428
+ t-att-style="this.getResizerPosition('top left')"
429
+ t-on-mousedown="(ev) => this.clickAnchor(-1,-1, ev)"
430
+ />
431
+ </t>
432
+ </div>
433
+ </t>
434
+
435
+ <t t-name="o-spreadsheet-ChartFigure" owl="1">
436
+ <div
437
+ class="o-chart-container w-100 h-100"
438
+ t-ref="chartContainer"
439
+ t-on-contextmenu.prevent.stop="(ev) => !env.isDashboard() and !env.model.getters.isReadonly() and this.onContextMenu(ev)">
440
+ <div class="o-chart-menu" t-if="!env.isDashboard()">
441
+ <div
442
+ class="o-chart-menu-item"
443
+ t-if="!env.model.getters.isReadonly()"
444
+ t-on-click="showMenu"
445
+ t-ref="menuButton"
446
+ t-on-contextmenu.prevent.stop="showMenu">
447
+ <t t-call="o-spreadsheet-Icon.LIST"/>
448
+ </div>
449
+ </div>
450
+ <t
451
+ t-component="chartComponent"
452
+ figure="this.props.figure"
453
+ t-key="this.props.figure.id + '-' + chartType"
454
+ />
455
+
456
+ <Menu
457
+ t-if="menuState.isOpen"
458
+ position="menuState.position"
459
+ menuItems="menuState.menuItems"
460
+ onClose="() => this.menuState.isOpen=false"
461
+ />
462
+ </div>
463
+ </t>
464
+
465
+ <t t-name="o-spreadsheet-FiguresContainer" owl="1">
466
+ <div>
467
+ <t t-foreach="containers" t-as="container" t-key="container.type">
468
+ <div
469
+ class="o-figure-container position-absolute pe-none overflow-hidden"
470
+ t-att-style="container.style"
471
+ t-att-data-id="container.type + 'Container'">
472
+ <div
473
+ class="o-figure-viewport-inverse w-0 h-0 overflow-visible position-absolute"
474
+ t-att-style="container.inverseViewportStyle">
475
+ <t t-foreach="container.figures" t-as="figure" t-key="figure.id">
476
+ <FigureComponent
477
+ onFigureDeleted="this.props.onFigureDeleted"
478
+ figure="figure"
479
+ style="getFigureStyle(figure)"
480
+ onMouseDown="(ev) => this.startDraggingFigure(figure, ev)"
481
+ onClickAnchor="(dirX, dirY, ev) => this.startResize(figure, dirX, dirY, ev)"
482
+ />
483
+ </t>
484
+ </div>
485
+ </div>
486
+ </t>
487
+ </div>
488
+ </t>
489
+
490
+ <t t-name="o-spreadsheet-FilterIcon" owl="1">
491
+ <div class="o-filter-icon" t-att-style="style" t-on-click.stop="props.onClick">
492
+ <t t-if="props.isActive" t-call="o-spreadsheet-Icon.FILTER_ICON_ACTIVE"/>
493
+ <t t-else="" t-call="o-spreadsheet-Icon.FILTER_ICON"/>
494
+ </div>
495
+ </t>
496
+
497
+ <t t-name="o-spreadsheet-FilterIconsOverlay" owl="1">
498
+ <t
499
+ t-foreach="getVisibleFilterHeaders()"
500
+ t-as="header"
501
+ t-key="'filter'+header.col + '_' + header.row">
502
+ <FilterIcon
503
+ position="getFilterHeaderPosition(header)"
504
+ isActive="isFilterActive(header)"
505
+ t-key="'icon_'+header.col + '_' + header.row"
506
+ onClick="() => this.toggleFilterMenu(header)"
507
+ />
508
+ </t>
509
+ </t>
510
+
511
+ <t t-name="o-spreadsheet-FilterMenu" owl="1">
512
+ <div class="o-filter-menu d-flex flex-column bg-white" t-on-wheel.stop="">
513
+ <div t-if="!isReadonly">
514
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('ascending')">
515
+ Sort ascending (A ⟶ Z)
516
+ </div>
517
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('descending')">
518
+ Sort descending (Z ⟶ A)
519
+ </div>
520
+ </div>
521
+ <div class="o-separator" t-if="!isReadonly"/>
522
+ <div class="o-filter-menu-actions">
523
+ <div class="o-filter-menu-action-text" t-on-click="selectAll">Select all</div>
524
+ <div class="o-filter-menu-action-text" t-on-click="clearAll">Clear</div>
525
+ </div>
526
+ <div class="position-relative">
527
+ <input
528
+ class="w-100"
529
+ t-ref="filterMenuSearchBar"
530
+ type="text"
531
+ t-model="state.textFilter"
532
+ placeholder="Search..."
533
+ t-on-keydown="(ev) => this.onKeyDown(ev)"
534
+ />
535
+ <i class="o-search-icon position-absolute">
536
+ <t t-call="o-spreadsheet-Icon.SEARCH"/>
537
+ </i>
538
+ </div>
539
+ <div
540
+ class="o-filter-menu-list d-flex flex-column rounded"
541
+ t-ref="filterValueList"
542
+ t-on-click="this.clearScrolledToValue"
543
+ t-on-scroll="this.clearScrolledToValue">
544
+ <t t-foreach="displayedValues" t-as="value" t-key="value.string">
545
+ <FilterMenuValueItem
546
+ onClick="() => this.checkValue(value)"
547
+ onMouseMove="() => this.onMouseMove(value)"
548
+ value="value.string"
549
+ isChecked="value.checked"
550
+ isSelected="value.string === state.selectedValue"
551
+ scrolledTo="value.scrolledTo"
552
+ />
553
+ </t>
554
+ <div
555
+ t-if="displayedValues.length === 0"
556
+ class="o-filter-menu-no-values d-flex align-items-center justify-content-center w-100 h-100 ">
557
+ No results
558
+ </div>
559
+ </div>
560
+ <div class="o-filter-menu-buttons d-flex justify-content-end">
561
+ <div class="o-filter-menu-button o-filter-menu-button-cancel" t-on-click="cancel">
562
+ Cancel
563
+ </div>
564
+ <div class="o-filter-menu-button o-filter-menu-button-primary" t-on-click="confirm">
565
+ Confirm
566
+ </div>
567
+ </div>
568
+ </div>
569
+ </t>
570
+
571
+ <t t-name="o-spreadsheet-FilterMenuValueItem" owl="1">
572
+ <div
573
+ t-on-click="this.props.onClick"
574
+ t-on-mousemove="this.props.onMouseMove"
575
+ class="o-filter-menu-item o-filter-menu-value"
576
+ t-ref="menuValueItem"
577
+ t-att-class="{'selected': this.props.isSelected}">
578
+ <div>
579
+ <div class="o-filter-menu-value-checked">
580
+ <span t-if="this.props.isChecked">✓</span>
581
+ </div>
582
+ </div>
583
+ <div class="o-filter-menu-value-text text-truncate">
584
+ <t t-if="this.props.value === ''">(Blanks)</t>
585
+ <t t-else="" t-esc="this.props.value"/>
586
+ </div>
587
+ </div>
588
+ </t>
589
+
590
+ <t t-name="o-spreadsheet-Grid" owl="1">
591
+ <div
592
+ class="o-grid"
593
+ tabindex="-1"
594
+ t-att-class="{'o-two-columns': !props.sidePanelIsOpen}"
595
+ t-on-click="focus"
596
+ t-on-keydown="onKeydown"
597
+ t-on-wheel="onMouseWheel"
598
+ t-ref="grid">
599
+ <GridOverlay
600
+ onCellClicked.bind="onCellClicked"
601
+ onCellDoubleClicked.bind="onCellDoubleClicked"
602
+ onCellRightClicked.bind="onCellRightClicked"
603
+ onCellHovered.bind="onCellHovered"
604
+ onGridResized.bind="onGridResized"
605
+ onGridMoved.bind="moveCanvas"
606
+ gridOverlayDimensions="gridOverlayDimensions"
607
+ sidePanelIsOpen="props.sidePanelIsOpen"
608
+ onFigureDeleted.bind="focus"
609
+ />
610
+ <HeadersOverlay onOpenContextMenu="(type, x, y) => this.toggleContextMenu(type, x, y)"/>
611
+
612
+ <t t-if="env.model.getters.getEditionMode() !== 'inactive'">
613
+ <GridComposer
614
+ onComposerUnmounted="() => this.focus()"
615
+ onComposerContentFocused="props.onComposerContentFocused"
616
+ focus="props.focusComposer"
617
+ />
618
+ </t>
619
+ <t else="1">
620
+ <input
621
+ class="position-absolute"
622
+ style="z-index:-1000;"
623
+ t-on-input="onInput"
624
+ t-on-contextmenu="onInputContextMenu"
625
+ t-ref="hiddenInput"
626
+ />
627
+ </t>
628
+ <canvas t-ref="canvas"/>
629
+ <t
630
+ t-foreach="env.model.getters.getClientsToDisplay()"
631
+ t-as="client"
632
+ t-key="getClientPositionKey(client)">
633
+ <ClientTag
634
+ name="client.name"
635
+ color="client.color"
636
+ col="client.position.col"
637
+ row="client.position.row"
638
+ active="isCellHovered(client.position.col, client.position.row)"
639
+ />
640
+ </t>
641
+ <GridPopover
642
+ t-if="!menuState.isOpen"
643
+ gridPosition="canvasPosition"
644
+ hoveredCell="hoveredCell"
645
+ onMouseWheel.bind="onMouseWheel"
646
+ onClosePopover.bind="onClosePopover"
647
+ />
648
+ <t t-if="env.model.getters.getEditionMode() === 'inactive' and isAutoFillActive()">
649
+ <Autofill position="getAutofillPosition()"/>
650
+ </t>
651
+ <t t-if="env.model.getters.getEditionMode() !== 'inactive'">
652
+ <t t-foreach="env.model.getters.getHighlights()" t-as="highlight" t-key="highlight_index">
653
+ <t t-if="highlight.sheetId === env.model.getters.getActiveSheetId()">
654
+ <Highlight zone="highlight.zone" color="highlight.color"/>
655
+ </t>
656
+ </t>
657
+ </t>
658
+ <Menu
659
+ t-if="menuState.isOpen"
660
+ menuItems="menuState.menuItems"
661
+ position="menuState.position"
662
+ onClose="() => this.closeMenu()"
663
+ />
664
+ <FilterIconsOverlay gridPosition="{ x: HEADER_WIDTH, y : HEADER_HEIGHT }"/>
665
+ <VerticalScrollBar position="{ top: HEADER_HEIGHT }"/>
666
+ <HorizontalScrollBar position="{ left: HEADER_WIDTH }"/>
667
+ <div class="o-scrollbar corner"/>
668
+ </div>
669
+ </t>
670
+
671
+ <t t-name="o-spreadsheet-GridOverlay" owl="1">
672
+ <div
673
+ t-ref="gridOverlay"
674
+ class="o-grid-overlay overflow-hidden"
675
+ t-att-style="props.gridOverlayDimensions"
676
+ t-on-mousedown="onMouseDown"
677
+ t-on-dblclick.self="onDoubleClick"
678
+ t-on-contextmenu="onContextMenu">
679
+ <!-- TODO remove sidePanelIsOpen props. It is wrong.
680
+ If you have a CF sidepanel open, selecting a figure should
681
+ not open the figure side panel -->
682
+ <FiguresContainer
683
+ model="env.model"
684
+ sidePanelIsOpen="props.sidePanelIsOpen"
685
+ onFigureDeleted="props.onFigureDeleted"
686
+ />
687
+ </div>
688
+ </t>
689
+
690
+ <t t-name="o-spreadsheet-GridPopover" owl="1">
691
+ <Popover
692
+ t-if="cellPopover.isOpen"
693
+ position="cellPopover.coordinates"
694
+ childWidth="cellPopover.Component.size.width"
695
+ childHeight="cellPopover.Component.size.height"
696
+ flipHorizontalOffset="cellPopover.cellWidth"
697
+ flipVerticalOffset="cellPopover.cellHeight"
698
+ onMouseWheel="props.onMouseWheel"
699
+ zIndex="zIndex">
700
+ <t
701
+ t-component="cellPopover.Component"
702
+ t-props="{...cellPopover.props, onClosed : () => props.onClosePopover()}"
703
+ />
704
+ </Popover>
705
+ </t>
706
+
707
+ <t t-name="o-spreadsheet-HeadersOverlay" owl="1">
708
+ <div class="o-overlay">
709
+ <ColResizer onOpenContextMenu="props.onOpenContextMenu"/>
710
+ <RowResizer onOpenContextMenu="props.onOpenContextMenu"/>
711
+ <div class="all" t-on-mousedown.self="selectAll"/>
712
+ </div>
713
+ </t>
714
+
715
+ <t t-name="o-spreadsheet-RowResizer" owl="1">
716
+ <div
717
+ class="o-row-resizer"
718
+ t-on-mousemove.self="onMouseMove"
719
+ t-on-mouseleave="onMouseLeave"
720
+ t-on-mousedown.self.prevent="select"
721
+ t-ref="rowResizer"
722
+ t-on-mouseup.self="onMouseUp"
723
+ t-on-contextmenu.self="onContextMenu"
724
+ t-att-class="{'o-grab': state.waitingForMove, 'o-dragging': state.isMoving}">
725
+ <div
726
+ t-if="state.isMoving"
727
+ class="dragging-row-line"
728
+ t-attf-style="top:{{state.draggerLinePosition}}px;"
729
+ />
730
+ <div
731
+ t-if="state.isMoving"
732
+ class="dragging-row-shadow"
733
+ t-attf-style="top:{{state.draggerShadowPosition}}px; height:{{state.draggerShadowThickness}}px;"
734
+ />
735
+ <t t-if="state.resizerIsActive">
736
+ <div
737
+ class="o-handle"
738
+ t-on-mousedown="onMouseDown"
739
+ t-on-dblclick="onDblClick"
740
+ t-on-contextmenu.prevent=""
741
+ t-attf-style="top:{{state.draggerLinePosition - 2}}px;">
742
+ <div class="dragging-resizer" t-if="state.isResizing"/>
743
+ </div>
744
+ </t>
745
+ <t
746
+ t-foreach="env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId())"
747
+ t-as="hiddenItem"
748
+ t-key="hiddenItem_index">
749
+ <t t-if="!hiddenItem.includes(0)">
750
+ <div
751
+ class="o-unhide"
752
+ t-att-data-index="hiddenItem_index"
753
+ t-attf-style="top:{{unhideStyleValue(hiddenItem[0]) - 17}}px;"
754
+ t-on-click="() => this.unhide(hiddenItem)">
755
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_UP"/>
756
+ </div>
757
+ </t>
758
+ <t
759
+ t-if="!hiddenItem.includes(env.model.getters.getNumberRows(env.model.getters.getActiveSheetId())-1)">
760
+ <div
761
+ class="o-unhide"
762
+ t-att-data-index="hiddenItem_index"
763
+ t-attf-style="top:{{unhideStyleValue(hiddenItem[0]) + 3}}px;"
764
+ t-on-click="() => this.unhide(hiddenItem)">
765
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
766
+ </div>
767
+ </t>
768
+ </t>
769
+ </div>
770
+ </t>
771
+
772
+ <t t-name="o-spreadsheet-ColResizer" owl="1">
773
+ <div
774
+ class="o-col-resizer"
775
+ t-on-mousemove.self="onMouseMove"
776
+ t-on-mouseleave="onMouseLeave"
777
+ t-on-mousedown.self.prevent="select"
778
+ t-ref="colResizer"
779
+ t-on-mouseup.self="onMouseUp"
780
+ t-on-contextmenu.self="onContextMenu"
781
+ t-att-class="{'o-grab': state.waitingForMove, 'o-dragging': state.isMoving, }">
782
+ <div
783
+ t-if="state.isMoving"
784
+ class="dragging-col-line"
785
+ t-attf-style="left:{{state.draggerLinePosition}}px;"
786
+ />
787
+ <div
788
+ t-if="state.isMoving"
789
+ class="dragging-col-shadow"
790
+ t-attf-style="left:{{state.draggerShadowPosition}}px; width:{{state.draggerShadowThickness}}px"
791
+ />
792
+ <t t-if="state.resizerIsActive">
793
+ <div
794
+ class="o-handle"
795
+ t-on-mousedown="onMouseDown"
796
+ t-on-dblclick="onDblClick"
797
+ t-on-contextmenu.prevent=""
798
+ t-attf-style="left:{{state.draggerLinePosition - 2}}px;">
799
+ <div class="dragging-resizer" t-if="state.isResizing"/>
800
+ </div>
801
+ </t>
802
+ <t
803
+ t-foreach="env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId())"
804
+ t-as="hiddenItem"
805
+ t-key="hiddenItem_index">
806
+ <t t-if="!hiddenItem.includes(0)">
807
+ <div
808
+ class="o-unhide"
809
+ t-att-data-index="hiddenItem_index"
810
+ t-attf-style="left:{{unhideStyleValue(hiddenItem[0]) - 17}}px; margin-right:6px;"
811
+ t-on-click="() => this.unhide(hiddenItem)">
812
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_LEFT"/>
813
+ </div>
814
+ </t>
815
+ <t
816
+ t-if="!hiddenItem.includes(env.model.getters.getNumberCols(env.model.getters.getActiveSheetId())-1)">
817
+ <div
818
+ class="o-unhide"
819
+ t-att-data-index="hiddenItem_index"
820
+ t-attf-style="left:{{unhideStyleValue(hiddenItem[0]) + 3}}px;"
821
+ t-on-click="() => this.unhide(hiddenItem)">
822
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"/>
823
+ </div>
824
+ </t>
825
+ </t>
826
+ </div>
827
+ </t>
828
+
829
+ <t t-name="o-spreadsheet-Border" owl="1">
830
+ <div
831
+ class="o-border"
832
+ t-on-mousedown="onMouseDown"
833
+ t-att-style="style"
834
+ t-att-class="{
835
+ 'o-moving': props.isMoving,
836
+ 'o-border-n': props.orientation === 'n',
837
+ 'o-border-s': props.orientation === 's',
838
+ 'o-border-w': props.orientation === 'w',
839
+ 'o-border-e': props.orientation === 'e',
840
+ }"
841
+ />
842
+ </t>
843
+
844
+ <t t-name="o-spreadsheet-Corner" owl="1">
845
+ <div
846
+ class="o-corner"
847
+ t-on-mousedown="onMouseDown"
848
+ t-att-style="style"
849
+ t-att-class="{
850
+ 'o-resizing': props.isResizing,
851
+ 'o-corner-nw': props.orientation === 'nw',
852
+ 'o-corner-ne': props.orientation === 'ne',
853
+ 'o-corner-sw': props.orientation === 'sw',
854
+ 'o-corner-se': props.orientation === 'se',
855
+ }"
856
+ />
857
+ </t>
858
+
859
+ <t t-name="o-spreadsheet-Highlight" owl="1">
860
+ <div class="o-highlight" t-ref="highlight">
861
+ <t t-foreach="['n', 's', 'w', 'e']" t-as="orientation" t-key="orientation">
862
+ <Border
863
+ onMoveHighlight="(x, y) => this.onMoveHighlight(x,y)"
864
+ isMoving='highlightState.shiftingMode === "isMoving"'
865
+ orientation="orientation"
866
+ zone="props.zone"
867
+ />
868
+ </t>
869
+ <t t-foreach="['nw', 'ne', 'sw', 'se']" t-as="orientation" t-key="orientation">
870
+ <Corner
871
+ onResizeHighlight="(isLeft, isTop) => this.onResizeHighlight(isLeft, isTop)"
872
+ isResizing='highlightState.shiftingMode === "isResizing"'
873
+ orientation="orientation"
874
+ zone="props.zone"
875
+ color="props.color"
876
+ />
877
+ </t>
878
+ </div>
879
+ </t>
880
+
881
+ <t t-name="o-spreadsheet-IconPicker" owl="1">
882
+ <div class="o-icon-picker">
883
+ <t t-foreach="iconSets" t-as="iconSet" t-key="iconSet">
884
+ <div class="o-cf-icon-line">
885
+ <div
886
+ class="o-icon-picker-item"
887
+ t-on-click="() => this.onIconClick(iconSets[iconSet].good)">
888
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].good].template}}"/>
889
+ </div>
890
+ <div
891
+ class="o-icon-picker-item"
892
+ t-on-click="() => this.onIconClick(iconSets[iconSet].neutral)">
893
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].neutral].template}}"/>
894
+ </div>
895
+ <div
896
+ class="o-icon-picker-item"
897
+ t-on-click="() => this.onIconClick(iconSets[iconSet].bad)">
898
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].bad].template}}"/>
899
+ </div>
900
+ </div>
901
+ </t>
902
+ </div>
903
+ </t>
904
+
905
+ <t t-name="o-spreadsheet-Icon.UNDO" owl="1">
906
+ <svg class="o-icon">
907
+ <path
908
+ fill="#000000"
909
+ d="M11.5656391,4.43436088 L9,7 L16,7 L16,0 L13.0418424,2.95815758 C11.5936787,1.73635959 9.72260775,1 7.67955083,1 C4.22126258,1 1.25575599,3.10984908 0,6 L2,7 C2.93658775,4.60974406 5.12943697,3.08011229 7.67955083,3 C9.14881247,3.0528747 10.4994783,3.57862053 11.5656391,4.43436088 Z"
910
+ transform="matrix(-1 0 0 1 17 5)"
911
+ />
912
+ </svg>
913
+ </t>
914
+ <t t-name="o-spreadsheet-Icon.REDO" owl="1">
915
+ <svg class="o-icon">
916
+ <path
917
+ fill="#000000"
918
+ d="M11.5656391,4.43436088 L9,7 L16,7 L16,0 L13.0418424,2.95815758 C11.5936787,1.73635959 9.72260775,1 7.67955083,1 C4.22126258,1 1.25575599,3.10984908 0,6 L2,7 C2.93658775,4.60974406 5.12943697,3.08011229 7.67955083,3 C9.14881247,3.0528747 10.4994783,3.57862053 11.5656391,4.43436088 Z"
919
+ transform="translate(1 5)"
920
+ />
921
+ </svg>
922
+ </t>
923
+ <t t-name="o-spreadsheet-Icon.PAINT_FORMAT" owl="1">
924
+ <svg class="o-icon">
925
+ <path
926
+ fill="#000000"
927
+ d="M9,0 L1,0 C0.45,0 0,0.45 0,1 L0,4 C0,4.55 0.45,5 1,5 L9,5 C9.55,5 10,4.55 10,4 L10,3 L11,3 L11,6 L4,6 L4,14 L6,14 L6,8 L13,8 L13,2 L10,2 L10,1 C10,0.45 9.55,0 9,0 Z"
928
+ transform="translate(3 2)"
929
+ />
930
+ </svg>
931
+ </t>
932
+ <t t-name="o-spreadsheet-Icon.CLEAR_FORMAT" owl="1">
933
+ <svg class="o-icon">
934
+ <path
935
+ fill="#000000"
936
+ d="M0.27,1.55 L5.43,6.7 L3,12 L5.5,12 L7.14,8.42 L11.73,13 L13,11.73 L1.55,0.27 L0.27,1.55 L0.27,1.55 Z M3.82,0 L5.82,2 L7.58,2 L7.03,3.21 L8.74,4.92 L10.08,2 L14,2 L14,0 L3.82,0 L3.82,0 Z"
937
+ transform="translate(2 3)"
938
+ />
939
+ </svg>
940
+ </t>
941
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_DOWN" owl="1">
942
+ <svg class="o-icon">
943
+ <polygon fill="#000000" points="0 0 4 4 8 0" transform="translate(5 7)"/>
944
+ </svg>
945
+ </t>
946
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_UP" owl="1">
947
+ <svg class="o-icon">
948
+ <polygon fill="#000000" points="4 0 0 4 8 4" transform="translate(5 7)"/>
949
+ </svg>
950
+ </t>
951
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_RIGHT" owl="1">
952
+ <svg class="o-icon">
953
+ <polygon fill="#000000" points="0 0 4 4 0 8" transform="translate(5 5)"/>
954
+ </svg>
955
+ </t>
956
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_LEFT" owl="1">
957
+ <svg class="o-icon">
958
+ <polygon fill="#000000" points="4 0 0 4 4 8" transform="translate(5 5)"/>
959
+ </svg>
960
+ </t>
961
+ <t t-name="o-spreadsheet-Icon.BOLD" owl="1">
962
+ <svg class="o-icon">
963
+ <path
964
+ fill="#000000"
965
+ fill-rule="evenodd"
966
+ d="M9,3.5 C9,1.57 7.43,0 5.5,0 L1.77635684e-15,0 L1.77635684e-15,12 L6.25,12 C8.04,12 9.5,10.54 9.5,8.75 C9.5,7.45 8.73,6.34 7.63,5.82 C8.46,5.24 9,4.38 9,3.5 Z M5,2 C5.82999992,2 6.5,2.67 6.5,3.5 C6.5,4.33 5.82999992,5 5,5 L3,5 L3,2 L5,2 Z M3,10 L3,7 L5.5,7 C6.32999992,7 7,7.67 7,8.5 C7,9.33 6.32999992,10 5.5,10 L3,10 Z"
967
+ transform="translate(4 3)"
968
+ />
969
+ </svg>
970
+ </t>
971
+ <t t-name="o-spreadsheet-Icon.ITALIC" owl="1">
972
+ <svg class="o-icon">
973
+ <polygon
974
+ fill="#000000"
975
+ fill-rule="evenodd"
976
+ points="4 0 4 2 6.58 2 2.92 10 0 10 0 12 8 12 8 10 5.42 10 9.08 2 12 2 12 0"
977
+ transform="translate(3 3)"
978
+ />
979
+ </svg>
980
+ </t>
981
+ <t t-name="o-spreadsheet-Icon.UNDERLINE" owl="1">
982
+ <svg class="o-icon">
983
+ <path
984
+ fill="#000000"
985
+ d="M6,12 C8.76,12 11,9.76 11,7 L11,0 L9,0 L9,7 C9,8.75029916 7.49912807,10 6,10 C4.50087193,10 3,8.75837486 3,7 L3,0 L1,0 L1,7 C1,9.76 3.24,12 6,12 Z M0,13 L0,15 L12,15 L12,13 L0,13 Z"
986
+ transform="translate(3 3)"
987
+ />
988
+ </svg>
989
+ </t>
990
+ <t t-name="o-spreadsheet-Icon.STRIKE" owl="1">
991
+ <svg class="o-icon">
992
+ <path
993
+ fill="#010101"
994
+ fill-rule="evenodd"
995
+ d="M2.8875,3.06 C2.8875,2.6025 2.985,2.18625 3.18375,1.8075 C3.3825,1.42875 3.66,1.10625 4.02,0.84 C4.38,0.57375 4.80375,0.3675 5.29875,0.22125 C5.79375,0.075 6.33375,0 6.92625,0 C7.53375,0 8.085,0.0825 8.58,0.25125 C9.075,0.42 9.49875,0.6525 9.85125,0.95625 C10.20375,1.25625 10.47375,1.6125 10.665,2.02875 C10.85625,2.44125 10.95,2.895 10.95,3.38625 L8.6925,3.38625 C8.6925,3.1575 8.655,2.94375 8.58375,2.74875 C8.5125,2.55 8.4,2.38125 8.25,2.2425 C8.1,2.10375 7.9125,1.99125 7.6875,1.91625 C7.4625,1.8375 7.19625,1.8 6.88875,1.8 C6.5925,1.8 6.3375,1.83375 6.11625,1.8975 C5.89875,1.96125 5.71875,2.05125 5.57625,2.1675 C5.43375,2.28375 5.325,2.41875 5.25375,2.5725 C5.1825,2.72625 5.145,2.895 5.145,3.0675 C5.145,3.4275 5.32875,3.73125 5.69625,3.975 C5.71780203,3.98908066 5.73942012,4.00311728 5.76118357,4.01733315 C6.02342923,4.18863185 6.5,4.5 7,5 L4,5 C4,5 3.21375,4.37625 3.17625,4.30875 C2.985,3.9525 2.8875,3.53625 2.8875,3.06 Z M14,6 L0,6 L0,8 L7.21875,8 C7.35375,8.0525 7.51875,8.105 7.63125,8.15375 C7.90875,8.2775 8.12625,8.40875 8.28375,8.53625 C8.44125,8.6675 8.54625,8.81 8.6025,8.96 C8.65875,9.11375 8.685,9.28625 8.685,9.47375 C8.685,9.65 8.65125,9.815 8.58375,9.965 C8.51625,10.11875 8.41125,10.25 8.2725,10.35875 C8.13375,10.4675 7.95375,10.55375 7.74,10.6175 C7.5225,10.68125 7.27125,10.71125 6.97875,10.71125 C6.6525,10.71125 6.35625,10.6775 6.09,10.61375 C5.82375,10.55 5.59875,10.445 5.41125,10.3025 C5.22375,10.16 5.0775,9.9725 4.9725,9.74375 C4.8675,9.515 4.78125,9.17 4.78125,9 L2.55,9 C2.55,9.2525 2.61,9.6875 2.72625,10.025 C2.8425,10.3625 3.0075,10.66625 3.21375,10.9325 C3.42,11.19875 3.6675,11.4275 3.94875,11.6225 C4.23,11.8175 4.53375,11.9825 4.86375,12.11 C5.19375,12.24125 5.535,12.33875 5.89875,12.39875 C6.25875,12.4625 6.6225,12.4925 6.9825,12.4925 C7.5825,12.4925 8.13,12.425 8.6175,12.28625 C9.105,12.1475 9.525,11.94875 9.87,11.69375 C10.215,11.435 10.48125,11.12 10.6725,10.74125 C10.86375,10.3625 10.95375,9.935 10.95375,9.455 C10.95375,9.005 10.875,8.6 10.72125,8.24375 C10.68375,8.1575 10.6425,8.075 10.59375,7.9925 L14,8 L14,6 Z"
996
+ transform="translate(2 3)"
997
+ />
998
+ </svg>
999
+ </t>
1000
+
1001
+ <t t-name="o-spreadsheet-Icon.TEXT_COLOR" owl="1">
1002
+ <svg class="o-icon">
1003
+ <path
1004
+ fill="#000000"
1005
+ d="M7,0 L5,0 L0.5,12 L2.5,12 L3.62,9 L8.37,9 L9.49,12 L11.49,12 L7,0 L7,0 Z M4.38,7 L6,2.67 L7.62,7 L4.38,7 L4.38,7 Z"
1006
+ transform="translate(3 1)"
1007
+ />
1008
+ </svg>
1009
+ </t>
1010
+ <t t-name="o-spreadsheet-Icon.FILL_COLOR" owl="1">
1011
+ <svg class="o-icon">
1012
+ <path
1013
+ fill="#000000"
1014
+ d="M14.5,8.87 C14.5,8.87 13,10.49 13,11.49 C13,12.32 13.67,12.99 14.5,12.99 C15.33,12.99 16,12.32 16,11.49 C16,10.5 14.5,8.87 14.5,8.87 L14.5,8.87 Z M12.71,6.79 L5.91,0 L4.85,1.06 L6.44,2.65 L2.29,6.79 C1.9,7.18 1.9,7.81 2.29,8.2 L6.79,12.7 C6.99,12.9 7.24,13 7.5,13 C7.76,13 8.01,12.9 8.21,12.71 L12.71,8.21 C13.1,7.82 13.1,7.18 12.71,6.79 L12.71,6.79 Z M4.21,7 L7.5,3.71 L10.79,7 L4.21,7 L4.21,7 Z"
1015
+ />
1016
+ </svg>
1017
+ </t>
1018
+ <t t-name="o-spreadsheet-Icon.MERGE_CELL" owl="1">
1019
+ <svg class="o-icon">
1020
+ <path
1021
+ fill="#000000"
1022
+ d="M3,6 L1,6 L1,2 L8,2 L8,4 L3,4 L3,6 Z M10,4 L10,2 L17,2 L17,6 L15,6 L15,4 L10,4 Z M10,14 L15,14 L15,12 L17,12 L17,16 L10,16 L10,14 Z M1,12 L3,12 L3,14 L8,14 L8,16 L1,16 L1,12 Z M1,8 L5,8 L5,6 L8,9 L5,12 L5,10 L1,10 L1,8 Z M10,9 L13,6 L13,8 L17,8 L17,10 L13,10 L13,12 L10,9 Z"
1023
+ />
1024
+ </svg>
1025
+ </t>
1026
+ <t t-name="o-spreadsheet-Icon.ALIGN_LEFT" owl="1">
1027
+ <svg class="o-icon align-left">
1028
+ <path
1029
+ fill="#000000"
1030
+ d="M0,14 L10,14 L10,12 L0,12 L0,14 Z M10,4 L0,4 L0,6 L10,6 L10,4 Z M0,0 L0,2 L14,2 L14,0 L0,0 Z M0,10 L14,10 L14,8 L0,8 L0,10 Z"
1031
+ transform="translate(2 2)"
1032
+ />
1033
+ </svg>
1034
+ </t>
1035
+ <t t-name="o-spreadsheet-Icon.ALIGN_CENTER" owl="1">
1036
+ <svg class="o-icon align-center">
1037
+ <path
1038
+ fill="#000000"
1039
+ d="M2,12 L2,14 L12,14 L12,12 L2,12 Z M2,4 L2,6 L12,6 L12,4 L2,4 Z M0,10 L14,10 L14,8 L0,8 L0,10 Z M0,0 L0,2 L14,2 L14,0 L0,0 Z"
1040
+ transform="translate(2 2)"
1041
+ />
1042
+ </svg>
1043
+ </t>
1044
+ <t t-name="o-spreadsheet-Icon.ALIGN_RIGHT" owl="1">
1045
+ <svg class="o-icon align-right">
1046
+ <path
1047
+ fill="#000000"
1048
+ d="M4,14 L14,14 L14,12 L4,12 L4,14 Z M0,10 L14,10 L14,8 L0,8 L0,10 Z M0,0 L0,2 L14,2 L14,0 L0,0 Z M4,6 L14,6 L14,4 L4,4 L4,6 Z"
1049
+ transform="translate(2 2)"
1050
+ />
1051
+ </svg>
1052
+ </t>
1053
+ <t t-name="o-spreadsheet-Icon.ALIGN_MIDDLE" owl="1">
1054
+ <svg class="o-icon">
1055
+ <path
1056
+ fill="#000000"
1057
+ d="M9.5,3 L7,3 L7,0 L5,0 L5,3 L2.5,3 L6,6.5 L9.5,3 L9.5,3 Z M0,8 L0,10 L12,10 L12,8 L0,8 L0,8 Z M2.5,15 L5,15 L5,18 L7,18 L7,15 L9.5,15 L6,11.5 L2.5,15 L2.5,15 Z"
1058
+ transform="translate(3)"
1059
+ />
1060
+ </svg>
1061
+ </t>
1062
+ <t t-name="o-spreadsheet-Icon.TEXT_WRAPPING" owl="1">
1063
+ <svg class="o-icon">
1064
+ <path
1065
+ fill="#000000"
1066
+ d="M14,0 L0,0 L0,2 L14,2 L14,0 Z M0,12 L4,12 L4,10 L0,10 L0,12 Z M11.5,5 L0,5 L0,7 L11.75,7 C12.58,7 13.25,7.67 13.25,8.5 C13.25,9.33 12.58,10 11.75,10 L9,10 L9,8 L6,11 L9,14 L9,12 L11.5,12 C13.43,12 15,10.43 15,8.5 C15,6.57 13.43,5 11.5,5 Z"
1067
+ transform="translate(2 3)"
1068
+ />
1069
+ </svg>
1070
+ </t>
1071
+ <t t-name="o-spreadsheet-Icon.BORDERS" owl="1">
1072
+ <svg class="o-icon">
1073
+ <path
1074
+ fill="#000000"
1075
+ d="M0,0 L0,14 L14,14 L14,0 L0,0 L0,0 Z M6,12 L2,12 L2,8 L6,8 L6,12 L6,12 Z M6,6 L2,6 L2,2 L6,2 L6,6 L6,6 Z M12,12 L8,12 L8,8 L12,8 L12,12 L12,12 Z M12,6 L8,6 L8,2 L12,2 L12,6 L12,6 Z"
1076
+ transform="translate(2 2)"
1077
+ />
1078
+ </svg>
1079
+ </t>
1080
+ <t t-name="o-spreadsheet-Icon.BORDER_HV" owl="1">
1081
+ <svg class="o-icon">
1082
+ <g fill="#000000" transform="translate(2 2)">
1083
+ <path
1084
+ d="M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M2,3 L0,3 L0,5 L2,5 L2,3 L2,3 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M11,0 L9,0 L9,2 L11,2 L11,0 L11,0 Z M2,0 L0,0 L0,2 L2,2 L2,0 L2,0 Z M5,0 L3,0 L3,2 L5,2 L5,0 L5,0 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z"
1085
+ opacity=".54"
1086
+ />
1087
+ <polygon points="8 0 6 0 6 6 0 6 0 8 6 8 6 14 8 14 8 8 14 8 14 6 8 6"/>
1088
+ </g>
1089
+ </svg>
1090
+ </t>
1091
+ <t t-name="o-spreadsheet-Icon.BORDER_H" owl="1">
1092
+ <svg class="o-icon">
1093
+ <g fill="#000000" transform="translate(2 2)">
1094
+ <path
1095
+ d="M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z"
1096
+ opacity=".54"
1097
+ />
1098
+ <polygon points="0 8 14 8 14 6 0 6"/>
1099
+ </g>
1100
+ </svg>
1101
+ </t>
1102
+ <t t-name="o-spreadsheet-Icon.BORDER_V" owl="1">
1103
+ <svg class="o-icon">
1104
+ <g fill="#000000" transform="translate(2 2)">
1105
+ <path
1106
+ d="M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z"
1107
+ opacity=".54"
1108
+ />
1109
+ <polygon points="6 14 8 14 8 0 6 0"/>
1110
+ </g>
1111
+ </svg>
1112
+ </t>
1113
+ <t t-name="o-spreadsheet-Icon.BORDER_EXTERNAL" owl="1">
1114
+ <svg class="o-icon">
1115
+ <g fill="#000000" transform="translate(2 2)">
1116
+ <path
1117
+ d="M8,3 L6,3 L6,5 L8,5 L8,3 L8,3 Z M11,6 L9,6 L9,8 L11,8 L11,6 L11,6 Z M8,6 L6,6 L6,8 L8,8 L8,6 L8,6 Z M8,9 L6,9 L6,11 L8,11 L8,9 L8,9 Z M5,6 L3,6 L3,8 L5,8 L5,6 L5,6 Z"
1118
+ opacity=".54"
1119
+ />
1120
+ <path d="M0,0 L14,0 L14,14 L0,14 L0,0 Z M12,12 L12,2 L2,2 L2,12 L12,12 Z"/>
1121
+ </g>
1122
+ </svg>
1123
+ </t>
1124
+ <t t-name="o-spreadsheet-Icon.BORDER_LEFT" owl="1">
1125
+ <svg class="o-icon">
1126
+ <g fill="#000000" transform="translate(2 2)">
1127
+ <path
1128
+ d="M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z"
1129
+ opacity=".54"
1130
+ />
1131
+ <polygon points="0 14 2 14 2 0 0 0"/>
1132
+ </g>
1133
+ </svg>
1134
+ </t>
1135
+ <t t-name="o-spreadsheet-Icon.BORDER_TOP" owl="1">
1136
+ <svg class="o-icon">
1137
+ <g fill="#000000" transform="translate(2 2)">
1138
+ <path
1139
+ d="M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z"
1140
+ opacity=".54"
1141
+ />
1142
+ <polygon points="0 0 0 2 14 2 14 0"/>
1143
+ </g>
1144
+ </svg>
1145
+ </t>
1146
+ <t t-name="o-spreadsheet-Icon.BORDER_RIGHT" owl="1">
1147
+ <svg class="o-icon">
1148
+ <g fill="#000000" transform="translate(2 2)">
1149
+ <path
1150
+ d="M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z"
1151
+ opacity=".54"
1152
+ />
1153
+ <polygon points="12 0 12 14 14 14 14 0"/>
1154
+ </g>
1155
+ </svg>
1156
+ </t>
1157
+ <t t-name="o-spreadsheet-Icon.BORDER_BOTTOM" owl="1">
1158
+ <svg class="o-icon">
1159
+ <g fill="#000000" transform="translate(2 2)">
1160
+ <path
1161
+ d="M5,0 L3,0 L3,2 L5,2 L5,0 L5,0 Z M8,6 L6,6 L6,8 L8,8 L8,6 L8,6 Z M8,9 L6,9 L6,11 L8,11 L8,9 L8,9 Z M11,6 L9,6 L9,8 L11,8 L11,6 L11,6 Z M5,6 L3,6 L3,8 L5,8 L5,6 L5,6 Z M11,0 L9,0 L9,2 L11,2 L11,0 L11,0 Z M8,3 L6,3 L6,5 L8,5 L8,3 L8,3 Z M8,0 L6,0 L6,2 L8,2 L8,0 L8,0 Z M2,9 L0,9 L0,11 L2,11 L2,9 L2,9 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M2,0 L0,0 L0,2 L2,2 L2,0 L2,0 Z M2,3 L0,3 L0,5 L2,5 L2,3 L2,3 Z M2,6 L0,6 L0,8 L2,8 L2,6 L2,6 Z"
1162
+ opacity=".54"
1163
+ />
1164
+ <polygon points="0 14 14 14 14 12 0 12"/>
1165
+ </g>
1166
+ </svg>
1167
+ </t>
1168
+ <t t-name="o-spreadsheet-Icon.BORDER_CLEAR" owl="1">
1169
+ <svg class="o-icon">
1170
+ <path
1171
+ fill="#000000"
1172
+ fill-rule="evenodd"
1173
+ d="M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z"
1174
+ transform="translate(2 2)"
1175
+ opacity=".54"
1176
+ />
1177
+ </svg>
1178
+ </t>
1179
+
1180
+ <t t-name="o-spreadsheet-Icon.PLUS" owl="1">
1181
+ <svg class="o-icon" viewBox="0 0 18 18">
1182
+ <path d="M8,0 L10,0 L10,8 L18,8 L18,10 L10,10 L10,18 L8,18 L8,10 L0,10 L0,8 L8,8"/>
1183
+ </svg>
1184
+ </t>
1185
+ <t t-name="o-spreadsheet-Icon.LIST" owl="1">
1186
+ <svg class="o-icon" viewBox="0 0 384 384">
1187
+ <rect x="0" y="277.333" width="384" height="42.667"/>
1188
+ <rect x="0" y="170.667" width="384" height="42.667"/>
1189
+ <rect x="0" y="64" width="384" height="42.667"/>
1190
+ </svg>
1191
+ </t>
1192
+
1193
+ <t t-name="o-spreadsheet-Icon.EDIT" owl="1">
1194
+ <svg class="o-icon" viewBox="0 0 576 512">
1195
+ <path
1196
+ fill="currentColor"
1197
+ d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"
1198
+ />
1199
+ </svg>
1200
+ </t>
1201
+ <t t-name="o-spreadsheet-Icon.UNLINK" owl="1">
1202
+ <svg class="o-icon" viewBox="0 0 512 512">
1203
+ <path
1204
+ fill="currentColor"
1205
+ d="M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z"
1206
+ />
1207
+ </svg>
1208
+ </t>
1209
+ /** Font Awesome by Dave Gandy
1210
+ * http://fontawesome.io/
1211
+ * https://fontawesome.com/license
1212
+ */
1213
+ <t t-name="o-spreadsheet-Icon.CARET_UP" owl="1">
1214
+ <svg class="caret-up" viewBox="0 0 320 512">
1215
+ <path
1216
+ fill="currentColor"
1217
+ d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"
1218
+ />
1219
+ </svg>
1220
+ </t>
1221
+ <t t-name="o-spreadsheet-Icon.CARET_DOWN" owl="1">
1222
+ <svg class="caret-down" viewBox="0 0 320 512">
1223
+ <path
1224
+ fill="currentColor"
1225
+ d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
1226
+ />
1227
+ </svg>
1228
+ </t>
1229
+
1230
+ <t t-name="o-spreadsheet-Icon.TRASH" owl="1">
1231
+ <svg class="o-cf-icon trash" viewBox="0 0 448 512">
1232
+ <path
1233
+ fill="currentColor"
1234
+ d="M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z"
1235
+ />
1236
+ </svg>
1237
+ </t>
1238
+ <t t-name="o-spreadsheet-Icon.REFRESH" owl="1">
1239
+ <svg class="o-cf-icon refresh" viewBox="0 0 512 512">
1240
+ <path
1241
+ fill="currentColor"
1242
+ d="M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z"
1243
+ />
1244
+ </svg>
1245
+ </t>
1246
+
1247
+ <t t-name="o-spreadsheet-Icon.ARROW_DOWN" owl="1">
1248
+ <svg
1249
+ class="o-cf-icon arrow-down"
1250
+ width="10"
1251
+ height="10"
1252
+ focusable="false"
1253
+ viewBox="0 0 448 512">
1254
+ <path
1255
+ fill="#DC6965"
1256
+ t-att-style="color"
1257
+ d="M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"
1258
+ />
1259
+ </svg>
1260
+ </t>
1261
+ <t t-name="o-spreadsheet-Icon.ARROW_UP" owl="1">
1262
+ <svg class="o-cf-icon arrow-up" width="10" height="10" focusable="false" viewBox="0 0 448 512">
1263
+ <path
1264
+ fill="#00A04A"
1265
+ t-att-style="color"
1266
+ d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"
1267
+ />
1268
+ </svg>
1269
+ </t>
1270
+ <t t-name="o-spreadsheet-Icon.ARROW_RIGHT" owl="1">
1271
+ <svg
1272
+ class="o-cf-icon arrow-right"
1273
+ width="10"
1274
+ height="10"
1275
+ focusable="false"
1276
+ viewBox="0 0 448 512">
1277
+ <path
1278
+ fill="#F0AD4E"
1279
+ d="M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"
1280
+ />
1281
+ </svg>
1282
+ </t>
1283
+
1284
+ <t t-name="o-spreadsheet-Icon.SMILE" owl="1">
1285
+ <svg class="o-cf-icon smile" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1286
+ <path
1287
+ fill="#00A04A"
1288
+ d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm4 72.6c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.7-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.1-8.4-25.3-7.1-33.8 3.1z"
1289
+ />
1290
+ </svg>
1291
+ </t>
1292
+ <t t-name="o-spreadsheet-Icon.MEH" owl="1">
1293
+ <svg class="o-cf-icon meh" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1294
+ <path
1295
+ fill="#F0AD4E"
1296
+ d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm8 144H160c-13.2 0-24 10.8-24 24s10.8 24 24 24h176c13.2 0 24-10.8 24-24s-10.8-24-24-24z"
1297
+ />
1298
+ </svg>
1299
+ </t>
1300
+ <t t-name="o-spreadsheet-Icon.FROWN" owl="1">
1301
+ <svg class="o-cf-icon frown" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1302
+ <path
1303
+ fill="#DC6965"
1304
+ d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-80 128c-40.2 0-78 17.7-103.8 48.6-8.5 10.2-7.1 25.3 3.1 33.8 10.2 8.4 25.3 7.1 33.8-3.1 16.6-19.9 41-31.4 66.9-31.4s50.3 11.4 66.9 31.4c8.1 9.7 23.1 11.9 33.8 3.1 10.2-8.5 11.5-23.6 3.1-33.8C326 321.7 288.2 304 248 304z"
1305
+ />
1306
+ </svg>
1307
+ </t>
1308
+
1309
+ <t t-name="o-spreadsheet-Icon.GREEN_DOT" owl="1">
1310
+ <svg class="o-cf-icon green-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1311
+ <path
1312
+ fill="#00A04A"
1313
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1314
+ />
1315
+ </svg>
1316
+ </t>
1317
+ <t t-name="o-spreadsheet-Icon.YELLOW_DOT" owl="1">
1318
+ <svg
1319
+ class="o-cf-icon yellow-dot"
1320
+ width="10"
1321
+ height="10"
1322
+ focusable="false"
1323
+ viewBox="0 0 512 512">
1324
+ <path
1325
+ fill="#F0AD4E"
1326
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1327
+ />
1328
+ </svg>
1329
+ </t>
1330
+ <t t-name="o-spreadsheet-Icon.RED_DOT" owl="1">
1331
+ <svg class="o-cf-icon red-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1332
+ <path
1333
+ fill="#DC6965"
1334
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1335
+ />
1336
+ </svg>
1337
+ </t>
1338
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON" owl="1">
1339
+ <svg
1340
+ class="o-cf-icon filter-icon"
1341
+ width="10"
1342
+ height="10"
1343
+ focusable="false"
1344
+ viewBox="0 0 850 850">
1345
+ <path
1346
+ fill="#000"
1347
+ d="M 339.667 681 L 510.333 681 L 510.333 595.667 L 339.667 595.667 L 339.667 681 Z M 41 169 L 41 254.333 L 809 254.333 L 809 169 L 41 169 Z M 169 467.667 L 681 467.667 L 681 382.333 L 169 382.333 L 169 467.667 Z"
1348
+ />
1349
+ </svg>
1350
+ </t>
1351
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON_ACTIVE" owl="1">
1352
+ <svg
1353
+ class="o-cf-icon filter-icon-active"
1354
+ width="10"
1355
+ height="10"
1356
+ focusable="false"
1357
+ viewBox="0 0 512 512">
1358
+ <path
1359
+ fill="#188038"
1360
+ d="M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"
1361
+ />
1362
+ </svg>
1363
+ </t>
1364
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON_INACTIVE" owl="1">
1365
+ <svg
1366
+ class="o-cf-icon filter-icon-inactive"
1367
+ width="10"
1368
+ height="10"
1369
+ focusable="false"
1370
+ viewBox="0 0 512 512">
1371
+ <path
1372
+ fill="#606162"
1373
+ d="M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"
1374
+ />
1375
+ </svg>
1376
+ </t>
1377
+ <t t-name="o-spreadsheet-Icon.SEARCH" owl="1">
1378
+ <svg class="search-icon" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1379
+ <path
1380
+ fill="#949494"
1381
+ d="M500.3 443.7l-119.7-119.7c27.22-40.41 40.65-90.9 33.46-144.7C401.8 87.79 326.8 13.32 235.2 1.723C99.01-15.51-15.51 99.01 1.724 235.2c11.6 91.64 86.08 166.7 177.6 178.9c53.8 7.189 104.3-6.236 144.7-33.46l119.7 119.7c15.62 15.62 40.95 15.62 56.57 0C515.9 484.7 515.9 459.3 500.3 443.7zM79.1 208c0-70.58 57.42-128 128-128s128 57.42 128 128c0 70.58-57.42 128-128 128S79.1 278.6 79.1 208z"
1382
+ />
1383
+ </svg>
1384
+ </t>
1385
+
1386
+ <t t-name="o-spreadsheet-LinkDisplay" owl="1">
1387
+ <div class="o-link-tool d-flex align-items-center">
1388
+ <t t-set="link" t-value="cell.link"/>
1389
+ <!-- t-key to prevent owl from re-using the previous img element when the link changes.
1390
+ The wrong/previous image would be displayed while the new one loads -->
1391
+ <img
1392
+ t-if="link.isExternal"
1393
+ t-key="link.url"
1394
+ t-attf-src="https://www.google.com/s2/favicons?sz=16&amp;domain={{link.url}}"
1395
+ />
1396
+ <a
1397
+ t-if="link.isExternal"
1398
+ class="o-link"
1399
+ t-att-href="link.url"
1400
+ target="_blank"
1401
+ t-on-click.prevent="openLink"
1402
+ t-att-title="link.url">
1403
+ <t t-esc="cell.urlRepresentation"/>
1404
+ </a>
1405
+ <a
1406
+ t-else=""
1407
+ class="o-link"
1408
+ t-on-click.prevent="openLink"
1409
+ t-att-title="cell.urlRepresentation">
1410
+ <t t-esc="cell.urlRepresentation"/>
1411
+ </a>
1412
+ <span
1413
+ t-if="!env.model.getters.isReadonly()"
1414
+ class="o-link-icon o-unlink"
1415
+ t-on-click="unlink"
1416
+ title="Remove link">
1417
+ <t t-call="o-spreadsheet-Icon.UNLINK"/>
1418
+ </span>
1419
+ <span
1420
+ t-if="!env.model.getters.isReadonly()"
1421
+ class="o-link-icon o-edit-link"
1422
+ t-on-click="edit"
1423
+ title="Edit link">
1424
+ <t t-call="o-spreadsheet-Icon.EDIT"/>
1425
+ </span>
1426
+ </div>
1427
+ </t>
1428
+
1429
+ <t t-name="o-spreadsheet-LinkEditor" owl="1">
1430
+ <div
1431
+ class="o-link-editor"
1432
+ t-on-click.stop="() => this.menu.isOpen=false"
1433
+ t-on-keydown.stop="onKeyDown"
1434
+ t-ref="linkEditor">
1435
+ <div class="o-section">
1436
+ <div class="o-section-title">Text</div>
1437
+ <div class="d-flex">
1438
+ <input type="text" class="o-input flex-grow-1" t-model="state.link.label"/>
1439
+ </div>
1440
+
1441
+ <div class="o-section-title mt-3">Link</div>
1442
+ <div class="o-link-url">
1443
+ <t t-if="state.isUrlEditable">
1444
+ <input type="text" t-ref="urlInput" t-model="state.link.url"/>
1445
+ </t>
1446
+ <t t-else="">
1447
+ <input type="text" t-att-value="state.urlRepresentation" disabled="1"/>
1448
+ </t>
1449
+ <button t-if="state.link.url" t-on-click="removeLink" class="o-remove-url">✖</button>
1450
+ <button t-if="!state.link.url" t-on-click.stop="openMenu" class="o-special-link">
1451
+ <t t-call="o-spreadsheet-Icon.LIST"/>
1452
+ </button>
1453
+ </div>
1454
+ </div>
1455
+ <Menu
1456
+ t-if="menu.isOpen"
1457
+ position="menuPosition"
1458
+ menuItems="menuItems"
1459
+ onMenuClicked="(ev) => this.onSpecialLink(ev)"
1460
+ onClose="() => this.menu.isOpen=false"
1461
+ />
1462
+ <div class="o-buttons">
1463
+ <button t-on-click="cancel" class="o-button o-cancel">Cancel</button>
1464
+ <button t-on-click="save" class="o-button o-save" t-att-disabled="!state.link.url">
1465
+ Confirm
1466
+ </button>
1467
+ </div>
1468
+ </div>
1469
+ </t>
1470
+
1471
+ <t t-name="o-spreadsheet-Menu" owl="1">
1472
+ <Popover
1473
+ t-if="visibleMenuItems.length"
1474
+ position="props.position"
1475
+ childWidth="MENU_WIDTH"
1476
+ childHeight="menuHeight"
1477
+ flipHorizontalOffset="popover.flipHorizontalOffset"
1478
+ flipVerticalOffset="popover.flipVerticalOffset"
1479
+ marginTop="popover.marginTop">
1480
+ <div
1481
+ t-ref="menu"
1482
+ class="o-menu"
1483
+ t-on-scroll="onScroll"
1484
+ t-on-wheel.stop=""
1485
+ t-on-click.stop=""
1486
+ t-on-contextmenu.prevent="">
1487
+ <t t-foreach="visibleMenuItems" t-as="menuItem" t-key="menuItem.id">
1488
+ <t t-set="isMenuRoot" t-value="isRoot(menuItem)"/>
1489
+ <t t-set="isMenuEnabled" t-value="isEnabled(menuItem)"/>
1490
+ <div
1491
+ t-att-title="getName(menuItem)"
1492
+ t-att-data-name="menuItem.id"
1493
+ t-on-click="() => this.onClickMenu(menuItem, menuItem_index)"
1494
+ t-on-mouseover="() => this.onMouseOver(menuItem, menuItem_index)"
1495
+ class="o-menu-item"
1496
+ t-att-class="{ 'o-menu-root': isMenuRoot, 'disabled': !isMenuEnabled, 'o-menu-item-active': isParentMenu(subMenu, menuItem)}"
1497
+ t-att-style="getColor(menuItem)">
1498
+ <span class="o-menu-item-name" t-esc="getName(menuItem)"/>
1499
+ <span
1500
+ t-if="getDescription(menuItem)"
1501
+ class="o-menu-item-description"
1502
+ t-esc="getDescription(menuItem)"
1503
+ />
1504
+ <t t-if="isMenuRoot">
1505
+ <span t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"/>
1506
+ </t>
1507
+ <t t-elif="menuItem.icon">
1508
+ <i t-att-class="menuItem.icon" class="o-menu-item-icon"/>
1509
+ </t>
1510
+ </div>
1511
+ <div t-if="menuItem.separator and !menuItem_last" class="o-separator"/>
1512
+ </t>
1513
+ </div>
1514
+ <Menu
1515
+ t-if="subMenu.isOpen"
1516
+ position="subMenuPosition"
1517
+ menuItems="subMenu.menuItems"
1518
+ depth="props.depth + 1"
1519
+ onMenuClicked="props.onMenuClicked"
1520
+ onClose="() => this.close()"
1521
+ menuId="props.menuId"
1522
+ />
1523
+ </Popover>
1524
+ </t>
1525
+
1526
+ <t t-name="o-spreadsheet-Popover" owl="1">
1527
+ <t t-portal="'.o-spreadsheet'">
1528
+ <div t-att-style="style" class="o-popover" t-on-wheel="props.onMouseWheel">
1529
+ <t t-slot="default"/>
1530
+ </div>
1531
+ </t>
1532
+ </t>
1533
+
1534
+ <t t-name="o-spreadsheet-ScrollBar" owl="1">
1535
+ <div class="o-scrollbar" t-on-scroll="onScroll" t-ref="scrollbar" t-att-style="positionCss">
1536
+ <div t-att-style="sizeCss"/>
1537
+ </div>
1538
+ </t>
1539
+
1540
+ <t t-name="o-spreadsheet-SelectionInput" owl="1">
1541
+ <div class="o-selection">
1542
+ <div
1543
+ t-foreach="ranges"
1544
+ t-as="range"
1545
+ t-key="range.id"
1546
+ class="o-selection-input"
1547
+ t-att-class="props.class">
1548
+ <input
1549
+ type="text"
1550
+ spellcheck="false"
1551
+ t-on-change="(ev) => this.onInputChanged(range.id, ev)"
1552
+ t-on-focus="() => this.focus(range.id)"
1553
+ t-att-value="range.xc"
1554
+ t-att-style="getColor(range)"
1555
+ t-att-class="{
1556
+ 'o-focused' : range.isFocused,
1557
+ 'o-required': props.required,
1558
+ 'o-optional': !props.required,
1559
+ 'o-invalid': isInvalid || !range.isValidRange,
1560
+ }"
1561
+ />
1562
+ <button
1563
+ class="o-btn o-remove-selection"
1564
+ t-if="ranges.length > 1"
1565
+ t-on-click="() => this.removeInput(range.id)">
1566
+ ✕
1567
+ </button>
1568
+ </div>
1569
+
1570
+ <div class="o-selection-input">
1571
+ <button class="o-btn-action o-add-selection" t-if="canAddRange" t-on-click="addEmptyInput">
1572
+ Add range
1573
+ </button>
1574
+ <button class="o-btn-action o-selection-ok" t-if="hasFocus" t-on-click="confirm">
1575
+ Confirm
1576
+ </button>
1577
+ </div>
1578
+ </div>
1579
+ </t>
1580
+
1581
+ <t t-name="o-spreadsheet-BarConfigPanel" owl="1">
1582
+ <div>
1583
+ <div class="o-section pt-0">
1584
+ <div class="o-checkbox">
1585
+ <label>
1586
+ <input
1587
+ type="checkbox"
1588
+ name="stacked"
1589
+ t-att-checked="props.definition.stacked"
1590
+ t-on-change="onUpdateStacked"
1591
+ class="align-middle"
1592
+ />
1593
+ Stacked barchart
1594
+ </label>
1595
+ </div>
1596
+ </div>
1597
+ <div class="o-section o-data-series">
1598
+ <div class="o-section-title">Data Series</div>
1599
+ <SelectionInput
1600
+ ranges="dataSeriesRanges"
1601
+ isInvalid="isDatasetInvalid"
1602
+ required="true"
1603
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
1604
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
1605
+ />
1606
+ <label>
1607
+ <input
1608
+ type="checkbox"
1609
+ t-att-checked="props.definition.dataSetsHaveTitle"
1610
+ t-on-change="onUpdateDataSetsHaveTitle"
1611
+ class="align-middle"
1612
+ />
1613
+ Data series include title
1614
+ </label>
1615
+ </div>
1616
+ <div class="o-section o-data-labels">
1617
+ <div class="o-section-title">Categories / Labels</div>
1618
+ <SelectionInput
1619
+ ranges="[props.definition.labelRange || '']"
1620
+ isInvalid="isLabelInvalid"
1621
+ hasSingleRange="true"
1622
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
1623
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
1624
+ />
1625
+ </div>
1626
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
1627
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
1628
+ <t t-esc="error"/>
1629
+ </div>
1630
+ </div>
1631
+ </div>
1632
+ </t>
1633
+
1634
+ <t t-name="o-spreadsheet-BarChartDesignPanel" owl="1">
1635
+ <div>
1636
+ <div class="o-section">
1637
+ <div class="o-section-title">Background color</div>
1638
+ <div class="o-with-color-picker">
1639
+ Select a color...
1640
+ <span
1641
+ t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
1642
+ t-on-click.stop="toggleColorPicker">
1643
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
1644
+ </span>
1645
+ <ColorPicker
1646
+ t-if="state.fillColorTool"
1647
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
1648
+ currentColor="props.definition.background"
1649
+ t-key="backgroundColor"
1650
+ />
1651
+ </div>
1652
+ </div>
1653
+ <div class="o-section o-chart-title">
1654
+ <div class="o-section-title">Title</div>
1655
+ <input
1656
+ type="text"
1657
+ t-att-value="env._t(props.definition.title)"
1658
+ t-on-change="updateTitle"
1659
+ class="o-input o-optional"
1660
+ placeholder="New Chart"
1661
+ />
1662
+ </div>
1663
+ <div class="o-section">
1664
+ <div class="o-section-title">Vertical axis position</div>
1665
+ <select
1666
+ t-att-value="props.definition.verticalAxisPosition"
1667
+ class="o-input o-type-selector"
1668
+ t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
1669
+ <option value="left">Left</option>
1670
+ <option value="right">Right</option>
1671
+ </select>
1672
+ </div>
1673
+ <div class="o-section">
1674
+ <div class="o-section-title">Legend position</div>
1675
+ <select
1676
+ t-att-value="props.definition.legendPosition"
1677
+ class="o-input o-type-selector"
1678
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
1679
+ <option value="none">None</option>
1680
+ <option value="top">Top</option>
1681
+ <option value="bottom">Bottom</option>
1682
+ <option value="left">Left</option>
1683
+ <option value="right">Right</option>
1684
+ </select>
1685
+ </div>
1686
+ </div>
1687
+ </t>
1688
+
1689
+ <t t-name="o-spreadsheet-GaugeChartConfigPanel" owl="1">
1690
+ <div>
1691
+ <div class="o-section o-data-series">
1692
+ <div class="o-section-title">Data range</div>
1693
+ <SelectionInput
1694
+ ranges="[props.definition.dataRange || '']"
1695
+ isInvalid="isDataRangeInvalid"
1696
+ hasSingleRange="true"
1697
+ required="true"
1698
+ onSelectionChanged="(ranges) => this.onDataRangeChanged(ranges)"
1699
+ onSelectionConfirmed="() => this.updateDataRange()"
1700
+ />
1701
+ </div>
1702
+ <div class="o-section o-sidepanel-error" t-if="configurationErrorMessages">
1703
+ <div t-foreach="configurationErrorMessages" t-as="error" t-key="error">
1704
+ <t t-esc="error"/>
1705
+ </div>
1706
+ </div>
1707
+ </div>
1708
+ </t>
1709
+
1710
+ <t t-name="o-spreadsheet-GaugeChartDesignPanel" owl="1">
1711
+ <div>
1712
+ <div class="o-section">
1713
+ <div class="o-section-title">Background color</div>
1714
+ <div class="o-with-color-picker">
1715
+ Select a color...
1716
+ <span
1717
+ title="Background Color"
1718
+ t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
1719
+ t-on-click.stop="() => this.toggleMenu('backgroundColor', ev)">
1720
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
1721
+ </span>
1722
+ <ColorPicker
1723
+ t-if="state.openedMenu === 'backgroundColor'"
1724
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
1725
+ currentColor="props.definition.background"
1726
+ t-key="backgroundColor"
1727
+ />
1728
+ </div>
1729
+ </div>
1730
+
1731
+ <div class="o-section o-chart-title">
1732
+ <div class="o-section-title">Title</div>
1733
+ <input
1734
+ type="text"
1735
+ t-att-value="env._t(props.definition.title)"
1736
+ t-on-change="updateTitle"
1737
+ class="o-input o-optional"
1738
+ placeholder="New Chart"
1739
+ />
1740
+ </div>
1741
+
1742
+ <div class="o-section">
1743
+ <div class="o-section-title">Range</div>
1744
+ <div class="o-subsection-left">
1745
+ <input
1746
+ type="text"
1747
+ t-att-value="props.definition.sectionRule.rangeMin"
1748
+ t-on-change="updateRangeMin"
1749
+ class="o-input o-data-range-min"
1750
+ t-att-class="{ 'o-invalid': isRangeMinInvalid() }"
1751
+ />
1752
+ </div>
1753
+ <div class="o-subsection-right">
1754
+ <input
1755
+ type="text"
1756
+ t-att-value="props.definition.sectionRule.rangeMax"
1757
+ t-on-change="updateRangeMax"
1758
+ class="o-input o-data-range-max"
1759
+ t-att-class="{ 'o-invalid': isRangeMaxInvalid() }"
1760
+ />
1761
+ </div>
1762
+ </div>
1763
+
1764
+ <div class="o-section">
1765
+ <div class="o-section-title">Thresholds</div>
1766
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplate">
1767
+ <t t-set="sectionRule" t-value="props.definition.sectionRule"/>
1768
+ </t>
1769
+ </div>
1770
+
1771
+ <div class="o-section o-sidepanel-error" t-if="designErrorMessages.length">
1772
+ <div t-foreach="designErrorMessages" t-as="error" t-key="error">
1773
+ <t t-esc="error"/>
1774
+ </div>
1775
+ </div>
1776
+ </div>
1777
+ </t>
1778
+
1779
+ <t t-name="o-spreadsheet-GaugeChartColorSectionTemplate" owl="1">
1780
+ <div class="o-gauge-color-set">
1781
+ <table>
1782
+ <tr>
1783
+ <th class="o-gauge-color-set-colorPicker"/>
1784
+ <th class="o-gauge-color-set-text"/>
1785
+ <th class="o-gauge-color-set-value">Value</th>
1786
+ <th class="o-gauge-color-set-type">Type</th>
1787
+ </tr>
1788
+
1789
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplateRow">
1790
+ <t t-set="sectionColor" t-value="sectionRule.colors.lowerColor"/>
1791
+ <t t-set="sectionType" t-value="'lowerColor'"/>
1792
+ <t t-set="inflectionPoint" t-value="sectionRule.lowerInflectionPoint"/>
1793
+ <t t-set="isInvalid" t-value="isLowerInflectionPointInvalid"/>
1794
+ <t t-set="inflectionPointName" t-value="'lowerInflectionPoint'"/>
1795
+ </t>
1796
+
1797
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplateRow">
1798
+ <t t-set="sectionColor" t-value="sectionRule.colors.middleColor"/>
1799
+ <t t-set="sectionType" t-value="'middleColor'"/>
1800
+ <t t-set="inflectionPoint" t-value="sectionRule.upperInflectionPoint"/>
1801
+ <t t-set="isInvalid" t-value="isUpperInflectionPointInvalid"/>
1802
+ <t t-set="inflectionPointName" t-value="'upperInflectionPoint'"/>
1803
+ </t>
1804
+
1805
+ <tr>
1806
+ <td>
1807
+ <div class="o-tools">
1808
+ <div class="o-tool o-dropdown o-with-color">
1809
+ <span
1810
+ title="Fill Color"
1811
+ t-attf-style="border-color:{{sectionRule.colors.upperColor}}"
1812
+ t-on-click.stop="(ev) => this.toggleMenu('sectionColor-upperColor', ev)">
1813
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
1814
+ </span>
1815
+ <ColorPicker
1816
+ t-if="state.openedMenu === 'sectionColor-upperColor'"
1817
+ onColorPicked="(color) => this.updateSectionColor('upperColor', color)"
1818
+ currentColor="sectionRule.colors.upperColor"
1819
+ dropdownDirection="'right'"
1820
+ />
1821
+ </div>
1822
+ </div>
1823
+ </td>
1824
+ <td>Else</td>
1825
+ <td/>
1826
+ <td/>
1827
+ <td/>
1828
+ </tr>
1829
+ </table>
1830
+ </div>
1831
+ </t>
1832
+
1833
+ <t t-name="o-spreadsheet-GaugeChartColorSectionTemplateRow" owl="1">
1834
+ <tr>
1835
+ <td>
1836
+ <div class="o-tools">
1837
+ <div class="o-tool o-dropdown o-with-color">
1838
+ <span
1839
+ title="Fill Color"
1840
+ t-attf-style="border-color:{{sectionColor}}"
1841
+ t-on-click.stop="(ev) => this.toggleMenu('sectionColor-'+sectionType, ev)">
1842
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
1843
+ </span>
1844
+ <ColorPicker
1845
+ t-if="state.openedMenu === 'sectionColor-'+sectionType"
1846
+ onColorPicked="(color) => this.updateSectionColor(sectionType, color)"
1847
+ currentColor="sectionColor"
1848
+ dropdownDirection="'right'"
1849
+ />
1850
+ </div>
1851
+ </div>
1852
+ </td>
1853
+ <td>When value is below</td>
1854
+ <td>
1855
+ <input
1856
+ type="text"
1857
+ class="o-input"
1858
+ t-on-change="(ev) => this.updateInflectionPointValue(inflectionPointName, ev)"
1859
+ t-attf-class="o-input-{{inflectionPointName}}"
1860
+ t-att-class="{ 'o-invalid': isInvalid }"
1861
+ t-model="inflectionPoint.value"
1862
+ />
1863
+ </td>
1864
+ <td>
1865
+ <select
1866
+ class="o-input"
1867
+ name="valueType"
1868
+ t-model="inflectionPoint.type"
1869
+ t-on-change="(ev) => this.updateInflectionPointType(inflectionPointName, ev)">
1870
+ <option value="number">Number</option>
1871
+ <option value="percentage">Percentage</option>
1872
+ </select>
1873
+ </td>
1874
+ </tr>
1875
+ </t>
1876
+
1877
+ <t t-name="o-spreadsheet-LineBarPieConfigPanel" owl="1">
1878
+ <div>
1879
+ <div class="o-section o-data-series">
1880
+ <div class="o-section-title">Data Series</div>
1881
+ <SelectionInput
1882
+ ranges="dataSeriesRanges"
1883
+ isInvalid="isDatasetInvalid"
1884
+ required="true"
1885
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
1886
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
1887
+ />
1888
+ <label>
1889
+ <input
1890
+ type="checkbox"
1891
+ t-att-checked="props.definition.dataSetsHaveTitle"
1892
+ t-on-change="onUpdateDataSetsHaveTitle"
1893
+ class="align-middle"
1894
+ />
1895
+ Data series include title
1896
+ </label>
1897
+ </div>
1898
+ <div class="o-section o-data-labels">
1899
+ <div class="o-section-title">Categories / Labels</div>
1900
+ <SelectionInput
1901
+ ranges="[props.definition.labelRange || '']"
1902
+ isInvalid="isLabelInvalid"
1903
+ hasSingleRange="true"
1904
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
1905
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
1906
+ />
1907
+ </div>
1908
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
1909
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
1910
+ <t t-esc="error"/>
1911
+ </div>
1912
+ </div>
1913
+ </div>
1914
+ </t>
1915
+
1916
+ <t t-name="o-spreadsheet-LineBarPieDesignPanel" owl="1">
1917
+ <div>
1918
+ <div class="o-section">
1919
+ <div class="o-section-title">Background color</div>
1920
+ <div class="o-with-color-picker">
1921
+ Select a color...
1922
+ <span
1923
+ t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
1924
+ t-on-click.stop="toggleColorPicker">
1925
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
1926
+ </span>
1927
+ <ColorPicker
1928
+ t-if="state.fillColorTool"
1929
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
1930
+ currentColor="props.definition.background"
1931
+ t-key="backgroundColor"
1932
+ />
1933
+ </div>
1934
+ </div>
1935
+ <div class="o-section o-chart-title">
1936
+ <div class="o-section-title">Title</div>
1937
+ <input
1938
+ type="text"
1939
+ t-att-value="env._t(props.definition.title)"
1940
+ t-on-change="updateTitle"
1941
+ class="o-input o-optional"
1942
+ placeholder="New Chart"
1943
+ />
1944
+ </div>
1945
+ <div class="o-section">
1946
+ <div class="o-section-title">Legend position</div>
1947
+ <select
1948
+ t-att-value="props.definition.legendPosition"
1949
+ class="o-input o-type-selector"
1950
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
1951
+ <option value="none">None</option>
1952
+ <option value="top">Top</option>
1953
+ <option value="bottom">Bottom</option>
1954
+ <option value="left">Left</option>
1955
+ <option value="right">Right</option>
1956
+ </select>
1957
+ </div>
1958
+ </div>
1959
+ </t>
1960
+
1961
+ <t t-name="o-spreadsheet-LineConfigPanel" owl="1">
1962
+ <div>
1963
+ <div class="o-section pt-0">
1964
+ <div class="o-checkbox">
1965
+ <label>
1966
+ <input
1967
+ type="checkbox"
1968
+ name="stacked"
1969
+ t-att-checked="props.definition.stacked"
1970
+ t-on-change="onUpdateStacked"
1971
+ class="align-middle"
1972
+ />
1973
+ Stacked linechart
1974
+ </label>
1975
+ </div>
1976
+ <div class="o-checkbox">
1977
+ <label>
1978
+ <input
1979
+ type="checkbox"
1980
+ name="cumulative"
1981
+ t-att-checked="props.definition.cumulative"
1982
+ t-on-change="onUpdateCumulative"
1983
+ class="align-middle"
1984
+ />
1985
+ Cumulative data
1986
+ </label>
1987
+ </div>
1988
+ </div>
1989
+ <div class="o-section o-data-series">
1990
+ <div class="o-section-title">Data Series</div>
1991
+ <SelectionInput
1992
+ ranges="dataSeriesRanges"
1993
+ isInvalid="isDatasetInvalid"
1994
+ required="true"
1995
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
1996
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
1997
+ />
1998
+ <label>
1999
+ <input
2000
+ type="checkbox"
2001
+ t-att-checked="props.definition.dataSetsHaveTitle"
2002
+ t-on-change="onUpdateDataSetsHaveTitle"
2003
+ class="align-middle"
2004
+ />
2005
+ Data series include title
2006
+ </label>
2007
+ </div>
2008
+ <div class="o-section o-data-labels">
2009
+ <div class="o-section-title">Categories / Labels</div>
2010
+ <SelectionInput
2011
+ ranges="[props.definition.labelRange || '']"
2012
+ isInvalid="isLabelInvalid"
2013
+ hasSingleRange="true"
2014
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2015
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2016
+ />
2017
+ <div t-if="canTreatLabelsAsText">
2018
+ <label>
2019
+ <input
2020
+ type="checkbox"
2021
+ name="labelsAsText"
2022
+ t-att-checked="props.definition.labelsAsText"
2023
+ t-on-change="onUpdateLabelsAsText"
2024
+ />
2025
+ Treat labels as text
2026
+ </label>
2027
+ </div>
2028
+ </div>
2029
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2030
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2031
+ <t t-esc="error"/>
2032
+ </div>
2033
+ </div>
2034
+ </div>
2035
+ </t>
2036
+
2037
+ <t t-name="o-spreadsheet-LineChartDesignPanel" owl="1">
2038
+ <div>
2039
+ <div class="o-section">
2040
+ <div class="o-section-title">Background color</div>
2041
+ <div class="o-with-color-picker">
2042
+ Select a color...
2043
+ <span
2044
+ t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
2045
+ t-on-click.stop="toggleColorPicker">
2046
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
2047
+ </span>
2048
+ <ColorPicker
2049
+ t-if="state.fillColorTool"
2050
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
2051
+ currentColor="props.definition.background"
2052
+ t-key="backgroundColor"
2053
+ />
2054
+ </div>
2055
+ </div>
2056
+ <div class="o-section o-chart-title">
2057
+ <div class="o-section-title">Title</div>
2058
+ <input
2059
+ type="text"
2060
+ t-att-value="props.definition.title"
2061
+ t-on-change="updateTitle"
2062
+ class="o-input o-optional"
2063
+ placeholder="New Chart"
2064
+ />
2065
+ </div>
2066
+ <div class="o-section">
2067
+ <div class="o-section-title">Vertical axis position</div>
2068
+ <select
2069
+ t-att-value="props.definition.verticalAxisPosition"
2070
+ class="o-input o-type-selector"
2071
+ t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
2072
+ <option value="left">Left</option>
2073
+ <option value="right">Right</option>
2074
+ </select>
2075
+ </div>
2076
+ <div class="o-section">
2077
+ <div class="o-section-title">Legend position</div>
2078
+ <select
2079
+ t-att-value="props.definition.legendPosition"
2080
+ class="o-input o-type-selector"
2081
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2082
+ <option value="none">None</option>
2083
+ <option value="top">Top</option>
2084
+ <option value="bottom">Bottom</option>
2085
+ <option value="left">Left</option>
2086
+ <option value="right">Right</option>
2087
+ </select>
2088
+ </div>
2089
+ </div>
2090
+ </t>
2091
+
2092
+ <t t-name="o-spreadsheet-ChartPanel" owl="1">
2093
+ <div class="o-chart">
2094
+ <div class="o-panel">
2095
+ <div
2096
+ class="o-panel-element o-panel-configuration"
2097
+ t-att-class="state.panel !== 'configuration' ? 'inactive' : ''"
2098
+ t-on-click="() => this.activatePanel('configuration')">
2099
+ <i class="fa fa-sliders"/>
2100
+ Configuration
2101
+ </div>
2102
+ <div
2103
+ class="o-panel-element o-panel-design"
2104
+ t-att-class="state.panel !== 'design' ? 'inactive' : ''"
2105
+ t-on-click="() => this.activatePanel('design')">
2106
+ <i class="fa fa-paint-brush"/>
2107
+ Design
2108
+ </div>
2109
+ </div>
2110
+
2111
+ <t t-set="definition" t-value="getChartDefinition()"/>
2112
+ <t t-if="state.panel === 'configuration'">
2113
+ <div class="o-section">
2114
+ <div class="o-section-title">Chart type</div>
2115
+ <t t-set="types" t-value="chartTypes"/>
2116
+ <select
2117
+ class="o-input o-type-selector"
2118
+ t-on-change="(ev) => this.onTypeChange(ev.target.value)">
2119
+ <option
2120
+ t-foreach="chartTypes"
2121
+ t-as="type"
2122
+ t-key="type"
2123
+ t-att-value="type"
2124
+ t-esc="types[type]"
2125
+ t-att-selected="definition.type === type"
2126
+ />
2127
+ </select>
2128
+ </div>
2129
+ <t
2130
+ t-component="chartPanel.configuration"
2131
+ definition="definition"
2132
+ figureId="figureId"
2133
+ updateChart.bind="updateChart"
2134
+ t-key="figureId + definition.type"
2135
+ />
2136
+ </t>
2137
+ <t t-else="">
2138
+ <t
2139
+ t-component="chartPanel.design"
2140
+ definition="definition"
2141
+ figureId="figureId"
2142
+ updateChart.bind="updateChart"
2143
+ t-key="figureId + definition.type"
2144
+ />
2145
+ </t>
2146
+ </div>
2147
+ </t>
2148
+
2149
+ <t t-name="o-spreadsheet-ScorecardChartConfigPanel" owl="1">
2150
+ <div>
2151
+ <div class="o-section o-data-series">
2152
+ <div class="o-section-title">Key value</div>
2153
+ <SelectionInput
2154
+ ranges="[props.definition.keyValue || '']"
2155
+ isInvalid="isKeyValueInvalid"
2156
+ hasSingleRange="true"
2157
+ required="true"
2158
+ onSelectionChanged="(ranges) => this.onKeyValueRangeChanged(ranges)"
2159
+ onSelectionConfirmed="() => this.updateKeyValueRange()"
2160
+ />
2161
+ </div>
2162
+ <div class="o-section o-data-labels">
2163
+ <div class="o-section-title">Baseline configuration</div>
2164
+ <div class="o-section-subtitle">Baseline value</div>
2165
+ <SelectionInput
2166
+ ranges="[props.definition.baseline || '']"
2167
+ isInvalid="isBaselineInvalid"
2168
+ hasSingleRange="true"
2169
+ onSelectionChanged="(ranges) => this.onBaselineRangeChanged(ranges)"
2170
+ onSelectionConfirmed="() => this.updateBaselineRange()"
2171
+ />
2172
+ <div class="o-section-subtitle">Baseline format</div>
2173
+ <select
2174
+ t-att-value="props.definition.baselineMode"
2175
+ class="o-input o-type-selector o-optional"
2176
+ t-on-change="(ev) => this.updateBaselineMode(ev)">
2177
+ <option value="text">Absolute value</option>
2178
+ <option value="difference">Value change from key value</option>
2179
+ <option value="percentage">Percentage change from key value</option>
2180
+ </select>
2181
+ </div>
2182
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2183
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2184
+ <t t-esc="error"/>
2185
+ </div>
2186
+ </div>
2187
+ </div>
2188
+ </t>
2189
+
2190
+ <t t-name="o-spreadsheet-ScorecardChartDesignPanel" owl="1">
2191
+ <div>
2192
+ <div class="o-section">
2193
+ <div class="o-section-title">Background color</div>
2194
+ <div class="o-with-color-picker">
2195
+ Select a color...
2196
+ <span
2197
+ title="Background Color"
2198
+ t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
2199
+ t-on-click.stop="() => this.openColorPicker('backgroundColor')">
2200
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
2201
+ </span>
2202
+ <ColorPicker
2203
+ t-if="state.openedColorPicker === 'backgroundColor'"
2204
+ onColorPicked="(color) => this.setColor(color, 'backgroundColor')"
2205
+ currentColor="props.definition.background"
2206
+ t-key="backgroundColor"
2207
+ />
2208
+ </div>
2209
+ </div>
2210
+
2211
+ <div class="o-section o-chart-title">
2212
+ <div class="o-section-title">Title</div>
2213
+ <input
2214
+ type="text"
2215
+ t-att-value="env._t(props.definition.title)"
2216
+ t-on-change="updateTitle"
2217
+ class="o-input o-optional"
2218
+ placeholder="New Chart"
2219
+ />
2220
+ </div>
2221
+ <div class="o-section">
2222
+ <div class="o-section-title">Baseline description</div>
2223
+ <input
2224
+ type="text"
2225
+ t-att-value="env._t(props.definition.baselineDescr)"
2226
+ t-on-change="updateBaselineDescr"
2227
+ class="o-input o-optional"
2228
+ />
2229
+ </div>
2230
+ </div>
2231
+ <div class="o-section">
2232
+ <div class="o-section-title">Baseline color</div>
2233
+ <div class="o-with-color-picker">
2234
+ Color on value increase
2235
+ <span
2236
+ title="Color Up"
2237
+ t-attf-style="border-color:{{props.definition.baselineColorUp}}"
2238
+ t-on-click.stop="() => this.openColorPicker('baselineColorUp')">
2239
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
2240
+ </span>
2241
+ <ColorPicker
2242
+ t-if="state.openedColorPicker === 'baselineColorUp'"
2243
+ onColorPicked="(color) => this.setColor(color, 'baselineColorUp')"
2244
+ currentColor="props.definition.baselineColorUp"
2245
+ t-key="baselineColorUp"
2246
+ />
2247
+ </div>
2248
+ <br/>
2249
+ <div class="o-with-color-picker">
2250
+ Color on value decrease
2251
+ <span
2252
+ title="Background Color"
2253
+ t-attf-style="border-color:{{props.definition.baselineColorDown}}"
2254
+ t-on-click.stop="() => this.openColorPicker('baselineColorDown')">
2255
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
2256
+ </span>
2257
+ <ColorPicker
2258
+ t-if="state.openedColorPicker === 'baselineColorDown'"
2259
+ onColorPicked="(color) => this.setColor(color, 'baselineColorDown')"
2260
+ currentColor="props.definition.baselineColorDown"
2261
+ t-key="baselineColorDown"
2262
+ />
2263
+ </div>
2264
+ </div>
2265
+ </t>
2266
+
2267
+ <t t-name="o-spreadsheet-CellIsRuleEditorPreview" owl="1">
2268
+ <div
2269
+ class="o-cf-preview-line"
2270
+ t-attf-style="font-weight:{{currentStyle.bold ?'bold':'normal'}};
2271
+ text-decoration:{{getTextDecoration(currentStyle)}};
2272
+ font-style:{{currentStyle.italic?'italic':'normal'}};
2273
+ color:{{currentStyle.textColor || '#000'}};
2274
+ border-radius: 4px;
2275
+ background-color:{{currentStyle.fillColor}};">
2276
+ <t t-if="previewText" t-esc="previewText"/>
2277
+ <t t-else="">Preview text</t>
2278
+ </div>
2279
+ </t>
2280
+
2281
+ <t t-name="o-spreadsheet-CellIsRuleEditor" owl="1">
2282
+ <div class="o-cf-cell-is-rule">
2283
+ <div class="o-section-subtitle">Format cells if...</div>
2284
+ <select t-model="rule.operator" class="o-input o-cell-is-operator">
2285
+ <t t-foreach="Object.keys(cellIsOperators)" t-as="op" t-key="op_index">
2286
+ <option t-att-value="op" t-esc="cellIsOperators[op]"/>
2287
+ </t>
2288
+ </select>
2289
+ <t t-if="rule.operator !== 'IsEmpty' and rule.operator !== 'IsNotEmpty'">
2290
+ <input
2291
+ type="text"
2292
+ placeholder="Value"
2293
+ t-model="rule.values[0]"
2294
+ t-att-class="{ 'o-invalid': isValue1Invalid }"
2295
+ class="o-input o-cell-is-value o-required"
2296
+ />
2297
+ <t t-if="rule.operator === 'Between' || rule.operator === 'NotBetween'">
2298
+ <input
2299
+ type="text"
2300
+ placeholder="and value"
2301
+ t-model="rule.values[1]"
2302
+ t-att-class="{ 'o-invalid': isValue2Invalid }"
2303
+ class="o-input o-cell-is-value o-required"
2304
+ />
2305
+ </t>
2306
+ </t>
2307
+ <div class="o-section-subtitle">Formatting style</div>
2308
+
2309
+ <t t-call="o-spreadsheet-CellIsRuleEditorPreview">
2310
+ <t t-set="currentStyle" t-value="rule.style"/>
2311
+ </t>
2312
+ <div class="o-tools">
2313
+ <div
2314
+ class="o-tool"
2315
+ title="Bold"
2316
+ t-att-class="{active:rule.style.bold}"
2317
+ t-on-click="() => this.toggleStyle('bold')">
2318
+ <t t-call="o-spreadsheet-Icon.BOLD"/>
2319
+ </div>
2320
+ <div
2321
+ class="o-tool"
2322
+ title="Italic"
2323
+ t-att-class="{active:rule.style.italic}"
2324
+ t-on-click="() => this.toggleStyle('italic')">
2325
+ <t t-call="o-spreadsheet-Icon.ITALIC"/>
2326
+ </div>
2327
+ <div
2328
+ class="o-tool"
2329
+ title="Underline"
2330
+ t-att-class="{active:rule.style.underline}"
2331
+ t-on-click="(ev) => this.toggleStyle('underline', ev)">
2332
+ <t t-call="o-spreadsheet-Icon.UNDERLINE"/>
2333
+ </div>
2334
+ <div
2335
+ class="o-tool"
2336
+ title="Strikethrough"
2337
+ t-att-class="{active:rule.style.strikethrough}"
2338
+ t-on-click="(ev) => this.toggleStyle('strikethrough', ev)">
2339
+ <t t-call="o-spreadsheet-Icon.STRIKE"/>
2340
+ </div>
2341
+ <div class="o-tool o-dropdown o-with-color">
2342
+ <span
2343
+ title="TextColor"
2344
+ t-attf-style="border-color:{{rule.style.textColor}}"
2345
+ t-on-click.stop="(ev) => this.toggleMenu('cellIsRule-textColor', ev)">
2346
+ <t t-call="o-spreadsheet-Icon.TEXT_COLOR"/>
2347
+ </span>
2348
+ <ColorPicker
2349
+ t-if="state.openedMenu === 'cellIsRule-textColor'"
2350
+ dropdownDirection="'center'"
2351
+ onColorPicked="(color) => this.setColor('textColor', color)"
2352
+ currentColor="rule.style.textColor"
2353
+ t-key="textColor"
2354
+ />
2355
+ </div>
2356
+ <div class="o-divider"/>
2357
+ <div class="o-tool o-dropdown o-with-color">
2358
+ <span
2359
+ title="FillColor"
2360
+ t-attf-style="border-color:{{rule.style.fillColor}}"
2361
+ t-on-click.stop="(ev) => this.toggleMenu('cellIsRule-fillColor', ev)">
2362
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
2363
+ </span>
2364
+ <ColorPicker
2365
+ t-if="state.openedMenu === 'cellIsRule-fillColor'"
2366
+ dropdownDirection="'center'"
2367
+ onColorPicked="(color) => this.setColor('fillColor', color)"
2368
+ currentColor="rule.style.fillColor"
2369
+ t-key="fillColor"
2370
+ />
2371
+ </div>
2372
+ </div>
2373
+ </div>
2374
+ </t>
2375
+
2376
+ <t t-name="o-spreadsheet-ColorScaleRuleEditorPreview" owl="1">
2377
+ <div class="o-cf-preview-gradient" t-attf-style="{{getPreviewGradient()}}">Preview text</div>
2378
+ </t>
2379
+
2380
+ <t t-name="o-spreadsheet-ColorScaleRuleEditorThreshold" owl="1">
2381
+ <div t-attf-class="o-threshold o-threshold-{{thresholdType}}">
2382
+ <t t-if="thresholdType === 'midpoint'">
2383
+ <t t-set="type" t-value="threshold and threshold.type"/>
2384
+ <select
2385
+ class="o-input"
2386
+ name="valueType"
2387
+ t-on-change="onMidpointChange"
2388
+ t-on-click="closeMenus">
2389
+ <option value="none" t-att-selected="threshold === undefined">None</option>
2390
+ <option value="number" t-att-selected="type === 'number'">FixedNumber</option>
2391
+ <option value="percentage" t-att-selected="type === 'percentage'">Percentage</option>
2392
+ <option value="percentile" t-att-selected="type === 'percentile'">Percentile</option>
2393
+ <option value="formula" t-att-selected="type === 'formula'">Formula</option>
2394
+ </select>
2395
+ </t>
2396
+ <t t-else="">
2397
+ <select class="o-input" name="valueType" t-model="threshold.type" t-on-click="closeMenus">
2398
+ <option value="value">Cell values</option>
2399
+ <option value="number">Number</option>
2400
+ <option value="percentage">Percentage</option>
2401
+ <option value="percentile">Percentile</option>
2402
+ <option value="formula">Formula</option>
2403
+ </select>
2404
+ </t>
2405
+ <input
2406
+ type="text"
2407
+ class="o-input o-threshold-value o-required"
2408
+ t-model="rule[thresholdType].value"
2409
+ t-att-class="{ 'o-invalid': isValueInvalid(thresholdType) }"
2410
+ t-if="threshold !== undefined and threshold.type !== 'value'"
2411
+ />
2412
+ <input type="text" class="o-input o-threshold-value" t-else="" disabled="1"/>
2413
+ <div class="o-tools">
2414
+ <div class="o-tool o-dropdown o-with-color" t-att-disabled="threshold === undefined">
2415
+ <span
2416
+ title="Fill Color"
2417
+ t-attf-style="border-color:{{getThresholdColor(threshold)}}"
2418
+ t-on-click.stop="(ev) => this.toggleMenu('colorScale-'+thresholdType+'Color', ev)">
2419
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
2420
+ </span>
2421
+ <ColorPicker
2422
+ t-if="state.openedMenu === 'colorScale-'+thresholdType+'Color'"
2423
+ dropdownDirection="'left'"
2424
+ onColorPicked="(color) => this.setColorScaleColor(thresholdType, color)"
2425
+ currentColor="getThresholdColor(threshold)"
2426
+ />
2427
+ </div>
2428
+ </div>
2429
+ </div>
2430
+ </t>
2431
+
2432
+ <t t-name="o-spreadsheet-ColorScaleRuleEditor" owl="1">
2433
+ <div class="o-cf-color-scale-editor">
2434
+ <div class="o-section-subtitle">Preview</div>
2435
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorPreview"/>
2436
+ <div class="o-section-subtitle">Minpoint</div>
2437
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
2438
+ <t t-set="threshold" t-value="rule.minimum"/>
2439
+ <t t-set="thresholdType" t-value="'minimum'"/>
2440
+ </t>
2441
+ <div class="o-section-subtitle">MidPoint</div>
2442
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
2443
+ <t t-set="threshold" t-value="rule.midpoint"/>
2444
+ <t t-set="thresholdType" t-value="'midpoint'"/>
2445
+ </t>
2446
+ <div class="o-section-subtitle">MaxPoint</div>
2447
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
2448
+ <t t-set="threshold" t-value="rule.maximum"/>
2449
+ <t t-set="thresholdType" t-value="'maximum'"/>
2450
+ </t>
2451
+ </div>
2452
+ </t>
2453
+
2454
+ <t t-name="o-spreadsheet-ConditionalFormattingPanel" owl="1">
2455
+ <div class="o-cf">
2456
+ <t t-if="state.mode === 'list' || state.mode === 'reorder'">
2457
+ <div class="o-cf-preview-list">
2458
+ <div
2459
+ t-on-click="(ev) => this.editConditionalFormat(cf, ev)"
2460
+ t-foreach="conditionalFormats"
2461
+ t-as="cf"
2462
+ t-key="cf.id">
2463
+ <t t-call="o-spreadsheet-ConditionalFormattingPanelPreview"/>
2464
+ </div>
2465
+ </div>
2466
+ <t t-if="state.mode === 'list'">
2467
+ <div
2468
+ class="btn btn-link o-cf-btn-link o-cf-add"
2469
+ t-on-click.prevent.stop="addConditionalFormat">
2470
+ + Add another rule
2471
+ </div>
2472
+ <div
2473
+ class="btn btn-link o-cf-btn-link o-cf-reorder"
2474
+ t-on-click="reorderConditionalFormats">
2475
+ Reorder rules
2476
+ </div>
2477
+ </t>
2478
+ <t t-if="state.mode === 'reorder'">
2479
+ <div class="btn btn-link o-cf-btn-link o-cf-exit-reorder" t-on-click="switchToList">
2480
+ Stop reordering rules
2481
+ </div>
2482
+ </t>
2483
+ </t>
2484
+ <t t-if="state.mode === 'edit' || state.mode === 'add'" t-key="state.currentCF.id">
2485
+ <div class="o-cf-ruleEditor">
2486
+ <div class="o-section o-cf-range">
2487
+ <div class="o-section-title">Apply to range</div>
2488
+ <div class="o-selection-cf">
2489
+ <SelectionInput
2490
+ ranges="state.currentCF.ranges"
2491
+ class="'o-range'"
2492
+ isInvalid="isRangeValid"
2493
+ onSelectionChanged="(ranges) => this.onRangesChanged(ranges)"
2494
+ required="true"
2495
+ />
2496
+ </div>
2497
+ <div class="o-section-title">Format rules</div>
2498
+ <div class="o_field_radio o_horizontal o_field_widget o-cf-type-selector">
2499
+ <div
2500
+ class="custom-control form-check o_cf_radio_item"
2501
+ t-on-click="() => this.changeRuleType('CellIsRule')">
2502
+ <input
2503
+ class="form-check-input o_radio_input"
2504
+ t-att-checked="state.currentCFType === 'CellIsRule'"
2505
+ type="radio"
2506
+ id="cellIsRule"
2507
+ name="ruleType"
2508
+ value="CellIsRule"
2509
+ />
2510
+ <label for="cellIsRule" class="form-check-label o_form_label">Single color</label>
2511
+ </div>
2512
+ <div
2513
+ class="custom-control form-check o_cf_radio_item"
2514
+ t-on-click="() => this.changeRuleType('ColorScaleRule')">
2515
+ <input
2516
+ class="form-check-input o_radio_input"
2517
+ t-att-checked="state.currentCFType === 'ColorScaleRule'"
2518
+ type="radio"
2519
+ id="colorScaleRule"
2520
+ name="ruleType"
2521
+ value="ColorScaleRule"
2522
+ />
2523
+ <label for="colorScaleRule" class="form-check-label o_form_label">
2524
+ Color scale
2525
+ </label>
2526
+ </div>
2527
+
2528
+ <div
2529
+ class="custom-control form-check o_cf_radio_item"
2530
+ t-on-click="() => this.changeRuleType('IconSetRule')">
2531
+ <input
2532
+ class="form-check-input o_radio_input"
2533
+ t-att-checked="state.currentCFType === 'IconSetRule'"
2534
+ type="radio"
2535
+ id="iconSetRule"
2536
+ name="ruleType"
2537
+ value="IconSetRule"
2538
+ />
2539
+ <label for="iconSetRule" class="form-check-label o_form_label">Icon set</label>
2540
+ </div>
2541
+ </div>
2542
+ </div>
2543
+ <div class="o-section o-cf-editor">
2544
+ <t t-if="state.currentCFType === 'CellIsRule'" t-call="o-spreadsheet-CellIsRuleEditor">
2545
+ <t t-set="rule" t-value="state.rules.cellIs"/>
2546
+ </t>
2547
+ <t
2548
+ t-if="state.currentCFType === 'ColorScaleRule'"
2549
+ t-call="o-spreadsheet-ColorScaleRuleEditor">
2550
+ <t t-set="rule" t-value="state.rules.colorScale"/>
2551
+ </t>
2552
+ <t t-if="state.currentCFType === 'IconSetRule'" t-call="o-spreadsheet-IconSetEditor">
2553
+ <t t-set="rule" t-value="state.rules.iconSet"/>
2554
+ </t>
2555
+ <div class="o-sidePanelButtons">
2556
+ <button t-on-click="switchToList" class="o-sidePanelButton o-cf-cancel">
2557
+ Cancel
2558
+ </button>
2559
+ <button t-on-click="saveConditionalFormat" class="o-sidePanelButton o-cf-save">
2560
+ Save
2561
+ </button>
2562
+ </div>
2563
+ </div>
2564
+ <div class="o-section">
2565
+ <div class="o-cf-error" t-foreach="state.errors || []" t-as="error" t-key="error_index">
2566
+ <t t-esc="errorMessage(error)"/>
2567
+ </div>
2568
+ </div>
2569
+ </div>
2570
+ </t>
2571
+ </div>
2572
+ </t>
2573
+
2574
+ <t t-name="o-spreadsheet-ConditionalFormattingPanelPreview" owl="1">
2575
+ <div class="o-cf-preview" t-att-class="{ 'o-cf-cursor-ptr': state.mode !== 'reorder' }">
2576
+ <t t-if="cf.rule.type==='IconSetRule'">
2577
+ <div class="o-cf-preview-icon">
2578
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.upper].template}}"/>
2579
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.middle].template}}"/>
2580
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.lower].template}}"/>
2581
+ </div>
2582
+ </t>
2583
+ <t t-else="">
2584
+ <div t-att-style="getStyle(cf.rule)" class="o-cf-preview-image">123</div>
2585
+ </t>
2586
+ <div class="o-cf-preview-description">
2587
+ <div class="o-cf-preview-ruletype">
2588
+ <div class="o-cf-preview-description-rule">
2589
+ <t t-esc="getDescription(cf)"/>
2590
+ </div>
2591
+ </div>
2592
+ <div class="o-cf-preview-range" t-esc="cf.ranges"/>
2593
+ </div>
2594
+ <t t-if="state.mode === 'reorder'">
2595
+ <div class="o-cf-reorder">
2596
+ <t t-if="!cf_first">
2597
+ <div
2598
+ class="o-cf-reorder-button-up o-cf-reorder-button"
2599
+ t-on-click="(ev) => this.reorderRule(cf, 'up', ev)">
2600
+ <t t-call="o-spreadsheet-Icon.CARET_UP"/>
2601
+ </div>
2602
+ </t>
2603
+ <t t-if="!cf_last">
2604
+ <div
2605
+ class="o-cf-reorder-button-down o-cf-reorder-button"
2606
+ t-on-click="(ev) => this.reorderRule(cf, 'down', ev)">
2607
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
2608
+ </div>
2609
+ </t>
2610
+ </div>
2611
+ </t>
2612
+ <t t-else="">
2613
+ <div class="o-cf-delete">
2614
+ <div
2615
+ class="o-cf-delete-button"
2616
+ t-on-click.stop="(ev) => this.deleteConditionalFormat(cf, ev)"
2617
+ aria-label="Remove rule">
2618
+ <t t-call="o-spreadsheet-Icon.TRASH"/>
2619
+ </div>
2620
+ </div>
2621
+ </t>
2622
+ </div>
2623
+ </t>
2624
+
2625
+ <t t-name="o-spreadsheet-IconSets" owl="1">
2626
+ <div>
2627
+ <div class="o-section-subtitle">Icons</div>
2628
+ <div class="o-cf-iconsets">
2629
+ <div
2630
+ class="o-cf-iconset"
2631
+ t-foreach="['arrows', 'smiley', 'dots']"
2632
+ t-as="iconSet"
2633
+ t-key="iconSet"
2634
+ t-on-click="(ev) => this.setIconSet(iconSet, ev)">
2635
+ <div class="o-cf-icon">
2636
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].good].template}}"/>
2637
+ </div>
2638
+ <div class="o-cf-icon">
2639
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].neutral].template}}"/>
2640
+ </div>
2641
+ <div class="o-cf-icon">
2642
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].bad].template}}"/>
2643
+ </div>
2644
+ </div>
2645
+ </div>
2646
+ </div>
2647
+ </t>
2648
+
2649
+ <t t-name="o-spreadsheet-IconSetInflexionPointRow" owl="1">
2650
+ <tr>
2651
+ <td>
2652
+ <div t-on-click.stop="(ev) => this.toggleMenu('iconSet-'+icon+'Icon', ev)">
2653
+ <div class="o-cf-icon-button">
2654
+ <t t-call="o-spreadsheet-Icon.{{icons[iconValue].template}}"/>
2655
+ </div>
2656
+ </div>
2657
+ <IconPicker
2658
+ t-if="state.openedMenu === 'iconSet-'+icon+'Icon'"
2659
+ onIconPicked="(i) => this.setIcon(icon, i)"
2660
+ />
2661
+ </td>
2662
+ <td>When value is</td>
2663
+ <td>
2664
+ <select class="o-input" name="valueType" t-model="inflectionPointValue.operator">
2665
+ <option value="gt">
2666
+ <span>&#62;</span>
2667
+ </option>
2668
+ <option value="ge">
2669
+ <span>&#8805;</span>
2670
+ </option>
2671
+ </select>
2672
+ </td>
2673
+ <td>
2674
+ <input
2675
+ type="text"
2676
+ class="o-input"
2677
+ t-att-class="{ 'o-invalid': isInflectionPointInvalid(inflectionPoint) }"
2678
+ t-model="rule[inflectionPoint].value"
2679
+ />
2680
+ </td>
2681
+ <td>
2682
+ <select class="o-input" name="valueType" t-model="inflectionPointValue.type">
2683
+ <option value="number">Number</option>
2684
+ <option value="percentage">Percentage</option>
2685
+ <option value="percentile">Percentile</option>
2686
+ <option value="formula">Formula</option>
2687
+ </select>
2688
+ </td>
2689
+ </tr>
2690
+ </t>
2691
+
2692
+ <t t-name="o-spreadsheet-IconSetInflexionPoints" owl="1">
2693
+ <div class="o-inflection">
2694
+ <table>
2695
+ <tr>
2696
+ <th class="o-cf-iconset-icons"/>
2697
+ <th class="o-cf-iconset-text"/>
2698
+ <th class="o-cf-iconset-operator"/>
2699
+ <th class="o-cf-iconset-value">Value</th>
2700
+ <th class="o-cf-iconset-type">Type</th>
2701
+ </tr>
2702
+ <t t-call="o-spreadsheet-IconSetInflexionPointRow">
2703
+ <t t-set="iconValue" t-value="rule.icons.upper"/>
2704
+ <t t-set="icon" t-value="'upper'"/>
2705
+ <t t-set="inflectionPointValue" t-value="rule.upperInflectionPoint"/>
2706
+ <t t-set="inflectionPoint" t-value="'upperInflectionPoint'"/>
2707
+ </t>
2708
+ <t t-call="o-spreadsheet-IconSetInflexionPointRow">
2709
+ <t t-set="iconValue" t-value="rule.icons.middle"/>
2710
+ <t t-set="icon" t-value="'middle'"/>
2711
+ <t t-set="inflectionPointValue" t-value="rule.lowerInflectionPoint"/>
2712
+ <t t-set="inflectionPoint" t-value="'lowerInflectionPoint'"/>
2713
+ </t>
2714
+ <tr>
2715
+ <td>
2716
+ <div t-on-click.stop="(ev) => this.toggleMenu('iconSet-lowerIcon', ev)">
2717
+ <div class="o-cf-icon-button">
2718
+ <t t-call="o-spreadsheet-Icon.{{icons[rule.icons.lower].template}}"/>
2719
+ </div>
2720
+ </div>
2721
+ <IconPicker
2722
+ t-if="state.openedMenu === 'iconSet-lowerIcon'"
2723
+ onIconPicked="(icon) => this.setIcon('lower', icon)"
2724
+ />
2725
+ </td>
2726
+ <td>Else</td>
2727
+ <td/>
2728
+ <td/>
2729
+ <td/>
2730
+ </tr>
2731
+ </table>
2732
+ </div>
2733
+ </t>
2734
+ <t t-name="o-spreadsheet-IconSetEditor" owl="1">
2735
+ <div class="o-cf-iconset-rule">
2736
+ <t t-call="o-spreadsheet-IconSets"/>
2737
+ <t t-call="o-spreadsheet-IconSetInflexionPoints"/>
2738
+ <div class="btn btn-link o_refresh_measures o-cf-iconset-reverse" t-on-click="reverseIcons">
2739
+ <div class="me-1 d-inline-block">
2740
+ <t t-call="o-spreadsheet-Icon.REFRESH"/>
2741
+ </div>
2742
+ Reverse icons
2743
+ </div>
2744
+ </div>
2745
+ </t>
2746
+
2747
+ <t t-name="o-spreadsheet-CustomCurrencyPanel" owl="1">
2748
+ <div class="o-custom-currency">
2749
+ <div class="o-section" t-if="availableCurrencies.length > 1">
2750
+ <div class="o-section-title">Currency</div>
2751
+ <select
2752
+ class="o-input o-available-currencies"
2753
+ t-on-change="(ev) => this.updateSelectCurrency(ev)">
2754
+ <t t-foreach="availableCurrencies" t-as="currency" t-key="currency_index">
2755
+ <option
2756
+ t-att-value="currency_index"
2757
+ t-esc="currencyDisplayName(currency)"
2758
+ t-att-selected="currency_index === state.selectedCurrencyIndex"
2759
+ />
2760
+ </t>
2761
+ </select>
2762
+ </div>
2763
+ <div class="o-section">
2764
+ <div class="o-subsection-left">
2765
+ <div class="o-section-title">Code</div>
2766
+ <input
2767
+ type="text"
2768
+ class="o-input"
2769
+ t-model="state.currencyCode"
2770
+ t-on-input="(ev) => this.updateCode(ev)"
2771
+ />
2772
+ </div>
2773
+ <div class="o-subsection-right">
2774
+ <div class="o-section-title">Symbol</div>
2775
+ <input
2776
+ type="text"
2777
+ class="o-input"
2778
+ t-model="state.currencySymbol"
2779
+ t-on-input="(ev) => this.updateSymbol(ev)"
2780
+ />
2781
+ </div>
2782
+ </div>
2783
+ <div class="o-section">
2784
+ <div class="o-section-title">Format</div>
2785
+ <select
2786
+ class="o-input o-format-proposals"
2787
+ t-on-change="(ev) => this.updateSelectFormat(ev)"
2788
+ t-att-disabled="!formatProposals.length">
2789
+ <t t-foreach="formatProposals" t-as="proposal" t-key="proposal_index">
2790
+ <option
2791
+ t-att-value="proposal_index"
2792
+ t-esc="proposal.example"
2793
+ t-att-selected="proposal_index === state.selectedFormatIndex"
2794
+ />
2795
+ </t>
2796
+ </select>
2797
+ </div>
2798
+ <div class="o-sidePanelButtons">
2799
+ <button
2800
+ class="o-sidePanelButton"
2801
+ t-on-click="() => this.apply()"
2802
+ t-att-disabled="!formatProposals.length || isSameFormat">
2803
+ Apply
2804
+ </button>
2805
+ </div>
2806
+ </div>
2807
+ </t>
2808
+
2809
+ <t t-name="o-spreadsheet-FindAndReplacePanel" owl="1">
2810
+ <div class="o-find-and-replace" tabindex="0" t-ref="findAndReplace">
2811
+ <div class="o-section">
2812
+ <div class="o-section-title">Search</div>
2813
+ <div class="o-input-search-container">
2814
+ <input
2815
+ type="text"
2816
+ class="o-input o-input-with-count"
2817
+ t-on-input="onInput"
2818
+ t-on-keydown="onKeydownSearch"
2819
+ />
2820
+ <div class="o-input-count" t-if="hasSearchResult">
2821
+ <t t-esc="env.model.getters.getCurrentSelectedMatchIndex()+1"/>
2822
+ /
2823
+ <t t-esc="env.model.getters.getSearchMatches().length"/>
2824
+ </div>
2825
+ </div>
2826
+ <div>
2827
+ <!-- TODO: go through this css, the group misses a padding and could profit from BootStrap -->
2828
+ <div class="o-far-item">
2829
+ <label class="o-far-checkbox">
2830
+ <input
2831
+ t-model="state.searchOptions.matchCase"
2832
+ t-on-change="updateSearch"
2833
+ class="o-far-input"
2834
+ type="checkbox"
2835
+ />
2836
+ <span class="o-far-label">Match case</span>
2837
+ </label>
2838
+ </div>
2839
+ <div class="o-far-item">
2840
+ <label class="o-far-checkbox">
2841
+ <input
2842
+ t-model="state.searchOptions.exactMatch"
2843
+ t-on-change="updateSearch"
2844
+ class="o-far-input"
2845
+ type="checkbox"
2846
+ />
2847
+ <span class="o-far-label">Match entire cell content</span>
2848
+ </label>
2849
+ </div>
2850
+ <div class="o-far-item">
2851
+ <label class="o-far-checkbox">
2852
+ <input
2853
+ t-model="state.searchOptions.searchFormulas"
2854
+ t-on-change="searchFormulas"
2855
+ class="o-far-input"
2856
+ type="checkbox"
2857
+ />
2858
+ <span class="o-far-label">Search in formulas</span>
2859
+ </label>
2860
+ </div>
2861
+ </div>
2862
+ </div>
2863
+ <div class="o-sidePanelButtons">
2864
+ <button
2865
+ t-att-disabled="!hasSearchResult"
2866
+ t-on-click="onSelectPreviousCell"
2867
+ class="o-sidePanelButton">
2868
+ Previous
2869
+ </button>
2870
+ <button
2871
+ t-att-disabled="!hasSearchResult"
2872
+ t-on-click="onSelectNextCell"
2873
+ class="o-sidePanelButton">
2874
+ Next
2875
+ </button>
2876
+ </div>
2877
+ <div class="o-section" t-if="!env.model.getters.isReadonly()">
2878
+ <div class="o-section-title">Replace</div>
2879
+ <div class="o-input-search-container">
2880
+ <input
2881
+ type="text"
2882
+ class="o-input o-input-without-count"
2883
+ t-model="state.replaceWith"
2884
+ t-on-keydown="onKeydownReplace"
2885
+ />
2886
+ </div>
2887
+ </div>
2888
+
2889
+ <div class="o-sidePanelButtons" t-if="!env.model.getters.isReadonly()">
2890
+ <button
2891
+ t-att-disabled="env.model.getters.getCurrentSelectedMatchIndex() === null"
2892
+ t-on-click="replace"
2893
+ class="o-sidePanelButton">
2894
+ Replace
2895
+ </button>
2896
+ <button
2897
+ t-att-disabled="env.model.getters.getCurrentSelectedMatchIndex() === null"
2898
+ t-on-click="replaceAll"
2899
+ class="o-sidePanelButton">
2900
+ Replace all
2901
+ </button>
2902
+ </div>
2903
+ </div>
2904
+ </t>
2905
+
2906
+ <t t-name="o-spreadsheet-SidePanel" owl="1">
2907
+ <div class="o-sidePanel">
2908
+ <div class="o-sidePanelHeader">
2909
+ <div class="o-sidePanelTitle" t-esc="getTitle()"/>
2910
+ <div class="o-sidePanelClose" t-on-click="() => this.props.onCloseSidePanel()">✕</div>
2911
+ </div>
2912
+ <div class="o-sidePanelBody">
2913
+ <t
2914
+ t-component="state.panel.Body"
2915
+ t-props="props.panelProps"
2916
+ onCloseSidePanel="props.onCloseSidePanel"
2917
+ t-key="'Body_' + props.component"
2918
+ />
2919
+ </div>
2920
+ <div class="o-sidePanelFooter" t-if="state.panel.Footer">
2921
+ <t
2922
+ t-component="state.panel.Footer"
2923
+ t-props="props.panelProps"
2924
+ t-key="'Footer_' + props.component"
2925
+ />
2926
+ </div>
2927
+ </div>
2928
+ </t>
2929
+
2930
+ <t t-name="o-spreadsheet-Spreadsheet" owl="1">
2931
+ <div
2932
+ class="o-spreadsheet"
2933
+ t-on-keydown="(ev) => !env.isDashboard() and this.onKeydown(ev)"
2934
+ t-att-style="getStyle()">
2935
+ <t t-if="env.isDashboard()">
2936
+ <SpreadsheetDashboard/>
2937
+ </t>
2938
+ <t t-else="">
2939
+ <TopBar
2940
+ onClick="() => this.focusGrid()"
2941
+ onComposerContentFocused="(selection) => this.onTopBarComposerFocused(selection)"
2942
+ focusComposer="focusTopBarComposer"
2943
+ dropdownMaxHeight="gridHeight"
2944
+ />
2945
+ <Grid
2946
+ sidePanelIsOpen="sidePanel.isOpen"
2947
+ onSaveRequested="() => this.save()"
2948
+ focusComposer="focusGridComposer"
2949
+ exposeFocus="(focus) => this._focusGrid = focus"
2950
+ onComposerContentFocused="() => this.onGridComposerContentFocused()"
2951
+ onGridComposerCellFocused="(content, selection) => this.onGridComposerCellFocused(content, selection)"
2952
+ />
2953
+ <SidePanel
2954
+ t-if="sidePanel.isOpen"
2955
+ onCloseSidePanel="() => this.closeSidePanel()"
2956
+ component="sidePanel.component"
2957
+ panelProps="sidePanel.panelProps"
2958
+ />
2959
+ <BottomBar onClick="() => this.focusGrid()"/>
2960
+ </t>
2961
+ </div>
2962
+ </t>
2963
+
2964
+ <t t-name="o-spreadsheet-TopBar" owl="1">
2965
+ <div class="o-spreadsheet-topbar o-two-columns" t-on-click="props.onClick">
2966
+ <div class="o-topbar-top">
2967
+ <!-- Menus -->
2968
+ <div class="o-topbar-topleft">
2969
+ <t t-foreach="menus" t-as="menu" t-key="menu_index">
2970
+ <div
2971
+ t-if="menu.children.length !== 0"
2972
+ class="o-topbar-menu"
2973
+ t-att-class="{'o-topbar-menu-active': state.menuState.parentMenu and state.menuState.parentMenu.id === menu.id}"
2974
+ t-on-click="(ev) => this.toggleContextMenu(menu, ev)"
2975
+ t-on-mouseover="(ev) => this.onMenuMouseOver(menu, ev)"
2976
+ t-att-data-id="menu.id">
2977
+ <t t-esc="getMenuName(menu)"/>
2978
+ </div>
2979
+ </t>
2980
+ <Menu
2981
+ t-if="state.menuState.isOpen"
2982
+ position="state.menuState.position"
2983
+ menuItems="state.menuState.menuItems"
2984
+ onClose="() => this.closeMenus()"
2985
+ onMenuClicked="() => this.props.onClick()"
2986
+ />
2987
+ </div>
2988
+ <div class="o-topbar-topright">
2989
+ <div t-foreach="topbarComponents" t-as="comp" t-key="comp.id">
2990
+ <t t-component="comp.component"/>
2991
+ </div>
2992
+ </div>
2993
+ </div>
2994
+ <!-- Toolbar and Cell Content -->
2995
+ <div class="o-topbar-toolbar">
2996
+ <!-- Toolbar -->
2997
+ <div t-if="env.model.getters.isReadonly()" class="o-readonly-toolbar text-muted">
2998
+ <span>
2999
+ <i class="fa fa-eye"/>
3000
+ Readonly Access
3001
+ </span>
3002
+ </div>
3003
+ <div t-else="" class="o-toolbar-tools">
3004
+ <div
3005
+ class="o-tool"
3006
+ title="Undo"
3007
+ t-att-class="{'o-disabled': !undoTool}"
3008
+ t-on-click="undo">
3009
+ <t t-call="o-spreadsheet-Icon.UNDO"/>
3010
+ </div>
3011
+ <div
3012
+ class="o-tool"
3013
+ t-att-class="{'o-disabled': !redoTool}"
3014
+ title="Redo"
3015
+ t-on-click="redo">
3016
+ <t t-call="o-spreadsheet-Icon.REDO"/>
3017
+ </div>
3018
+ <div
3019
+ class="o-tool"
3020
+ title="Paint Format"
3021
+ t-att-class="{active:paintFormatTool}"
3022
+ t-on-click="paintFormat">
3023
+ <t t-call="o-spreadsheet-Icon.PAINT_FORMAT"/>
3024
+ </div>
3025
+ <div class="o-tool" title="Clear Format" t-on-click="clearFormatting">
3026
+ <t t-call="o-spreadsheet-Icon.CLEAR_FORMAT"/>
3027
+ </div>
3028
+ <div class="o-divider"/>
3029
+ <div
3030
+ class="o-tool"
3031
+ title="Format as percent"
3032
+ t-on-click="(ev) => this.toogleFormat('percent', ev)">
3033
+ %
3034
+ </div>
3035
+ <div
3036
+ class="o-tool"
3037
+ title="Decrease decimal places"
3038
+ t-on-click="(ev) => this.setDecimal(-1, ev)">
3039
+ .0
3040
+ </div>
3041
+ <div
3042
+ class="o-tool"
3043
+ title="Increase decimal places"
3044
+ t-on-click="(ev) => this.setDecimal(+1, ev)">
3045
+ .00
3046
+ </div>
3047
+ <div
3048
+ class="o-tool o-dropdown"
3049
+ title="More formats"
3050
+ t-on-click="(ev) => this.toggleDropdownTool('formatTool', ev)">
3051
+ <div class="o-text-icon">
3052
+ 123
3053
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
3054
+ </div>
3055
+ <div
3056
+ class="o-dropdown-content o-text-options o-format-tool "
3057
+ t-att-style="dropdownStyle"
3058
+ t-if="state.activeTool === 'formatTool'"
3059
+ t-on-click="setFormat">
3060
+ <t t-foreach="commonFormats" t-as="commonFormat" t-key="commonFormat.name">
3061
+ <div
3062
+ t-att-data-format="commonFormat.name"
3063
+ t-att-class="{active: currentFormatName === commonFormat.name}">
3064
+ <t t-esc="commonFormat.text"/>
3065
+ <span class="float-end text-muted" t-esc="commonFormat.description"/>
3066
+ </div>
3067
+ </t>
3068
+ <t t-foreach="customFormats" t-as="customFormat" t-key="customFormat.name">
3069
+ <div t-att-data-custom="customFormat.name">
3070
+ <t t-esc="customFormat.text"/>
3071
+ </div>
3072
+ </t>
3073
+ </div>
3074
+ </div>
3075
+ <div class="o-divider"/>
3076
+ <div
3077
+ class="o-tool o-dropdown"
3078
+ title="Font Size"
3079
+ t-on-click="(ev) => this.toggleDropdownTool('fontSizeTool', ev)">
3080
+ <div class="o-text-icon">
3081
+ <t t-esc="style.fontSize || DEFAULT_FONT_SIZE"/>
3082
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
3083
+ </div>
3084
+ <div
3085
+ class="o-dropdown-content o-text-options "
3086
+ t-att-style="dropdownStyle"
3087
+ t-if="state.activeTool === 'fontSizeTool'"
3088
+ t-on-click="setSize">
3089
+ <t t-foreach="fontSizes" t-as="font" t-key="font_index">
3090
+ <div t-esc="font.pt" t-att-data-size="font.pt"/>
3091
+ </t>
3092
+ </div>
3093
+ </div>
3094
+ <div class="o-divider"/>
3095
+ <div
3096
+ class="o-tool"
3097
+ title="Bold"
3098
+ t-att-class="{active:style.bold}"
3099
+ t-on-click="(ev) => this.toogleStyle('bold', ev)">
3100
+ <t t-call="o-spreadsheet-Icon.BOLD"/>
3101
+ </div>
3102
+ <div
3103
+ class="o-tool"
3104
+ title="Italic"
3105
+ t-att-class="{active:style.italic}"
3106
+ t-on-click="(ev) => this.toogleStyle('italic', ev)">
3107
+ <t t-call="o-spreadsheet-Icon.ITALIC"/>
3108
+ </div>
3109
+ <div
3110
+ class="o-tool"
3111
+ title="Strikethrough"
3112
+ t-att-class="{active:style.strikethrough}"
3113
+ t-on-click="(ev) => this.toogleStyle('strikethrough', ev)">
3114
+ <t t-call="o-spreadsheet-Icon.STRIKE"/>
3115
+ </div>
3116
+ <div
3117
+ class="o-tool o-dropdown o-with-color"
3118
+ title="Text Color"
3119
+ t-on-click="(ev) => this.toggleDropdownTool('textColorTool', ev)">
3120
+ <span t-attf-style="border-color:{{textColor}}">
3121
+ <t t-call="o-spreadsheet-Icon.TEXT_COLOR"/>
3122
+ </span>
3123
+ <ColorPicker
3124
+ t-if="state.activeTool === 'textColorTool'"
3125
+ onColorPicked="(color) => this.setColor('textColor', color)"
3126
+ currentColor="textColor"
3127
+ t-key="textColor"
3128
+ maxHeight="this.props.dropdownMaxHeight"
3129
+ />
3130
+ </div>
3131
+ <div class="o-divider"/>
3132
+ <div
3133
+ class="o-tool o-dropdown o-with-color"
3134
+ title="Fill Color"
3135
+ t-on-click="(ev) => this.toggleDropdownTool('fillColorTool', ev)">
3136
+ <span t-attf-style="border-color:{{fillColor}}">
3137
+ <t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
3138
+ </span>
3139
+ <ColorPicker
3140
+ t-if="state.activeTool === 'fillColorTool'"
3141
+ onColorPicked="(color) => this.setColor('fillColor', color)"
3142
+ currentColor="fillColor"
3143
+ t-key="fillColor"
3144
+ maxHeight="this.props.dropdownMaxHeight"
3145
+ />
3146
+ </div>
3147
+ <div
3148
+ class="o-tool o-dropdown"
3149
+ title="Borders"
3150
+ t-on-click="(ev) => this.toggleDropdownTool('borderTool', ev)">
3151
+ <span>
3152
+ <t t-call="o-spreadsheet-Icon.BORDERS"/>
3153
+ </span>
3154
+ <div
3155
+ class="o-dropdown-content o-border-dropdown"
3156
+ t-att-style="dropdownStyle"
3157
+ t-if="state.activeTool === 'borderTool'">
3158
+ <div class="o-dropdown-line">
3159
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('all', ev)">
3160
+ <t t-call="o-spreadsheet-Icon.BORDERS"/>
3161
+ </span>
3162
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('hv', ev)">
3163
+ <t t-call="o-spreadsheet-Icon.BORDER_HV"/>
3164
+ </span>
3165
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('h', ev)">
3166
+ <t t-call="o-spreadsheet-Icon.BORDER_H"/>
3167
+ </span>
3168
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('v', ev)">
3169
+ <t t-call="o-spreadsheet-Icon.BORDER_V"/>
3170
+ </span>
3171
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('external', ev)">
3172
+ <t t-call="o-spreadsheet-Icon.BORDER_EXTERNAL"/>
3173
+ </span>
3174
+ </div>
3175
+ <div class="o-dropdown-line">
3176
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('left', ev)">
3177
+ <t t-call="o-spreadsheet-Icon.BORDER_LEFT"/>
3178
+ </span>
3179
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('top', ev)">
3180
+ <t t-call="o-spreadsheet-Icon.BORDER_TOP"/>
3181
+ </span>
3182
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('right', ev)">
3183
+ <t t-call="o-spreadsheet-Icon.BORDER_RIGHT"/>
3184
+ </span>
3185
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('bottom', ev)">
3186
+ <t t-call="o-spreadsheet-Icon.BORDER_BOTTOM"/>
3187
+ </span>
3188
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('clear', ev)">
3189
+ <t t-call="o-spreadsheet-Icon.BORDER_CLEAR"/>
3190
+ </span>
3191
+ </div>
3192
+ </div>
3193
+ </div>
3194
+ <div
3195
+ class="o-tool o-merge-tool"
3196
+ title="Merge Cells"
3197
+ t-att-class="{active:inMerge, 'o-disabled': cannotMerge}"
3198
+ t-on-click="toggleMerge">
3199
+ <t t-call="o-spreadsheet-Icon.MERGE_CELL"/>
3200
+ </div>
3201
+ <div class="o-divider"/>
3202
+ <div
3203
+ class="o-tool o-dropdown"
3204
+ title="Horizontal align"
3205
+ t-on-click="(ev) => this.toggleDropdownTool('alignTool', ev)">
3206
+ <span>
3207
+ <t t-if="style.align === 'right'">
3208
+ <t t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
3209
+ </t>
3210
+ <t t-elif="style.align === 'center'">
3211
+ <t t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
3212
+ </t>
3213
+ <t t-else="">
3214
+ <t t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
3215
+ </t>
3216
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
3217
+ </span>
3218
+ <div
3219
+ t-if="state.activeTool === 'alignTool'"
3220
+ class="o-dropdown-content"
3221
+ t-att-style="dropdownStyle">
3222
+ <div class="o-dropdown-item" t-on-click="(ev) => this.toggleAlign('left', ev)">
3223
+ <t t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
3224
+ </div>
3225
+ <div class="o-dropdown-item" t-on-click="(ev) => this.toggleAlign('center', ev)">
3226
+ <t t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
3227
+ </div>
3228
+ <div class="o-dropdown-item" t-on-click="(ev) => this.toggleAlign('right', ev)">
3229
+ <t t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
3230
+ </div>
3231
+ </div>
3232
+ </div>
3233
+ <div class="o-divider"/>
3234
+ <div
3235
+ t-if="selectionContainsFilter"
3236
+ class="o-tool o-filter-tool o-tool-outlined"
3237
+ title="Remove selected filters"
3238
+ t-on-click="removeFilter">
3239
+ <t t-call="o-spreadsheet-Icon.FILTER_ICON_ACTIVE"/>
3240
+ </div>
3241
+ <div
3242
+ t-else=""
3243
+ class="o-tool o-filter-tool"
3244
+ t-att-class="{'o-disabled': cannotCreateFilter}"
3245
+ title="Create filter"
3246
+ t-on-click="createFilter">
3247
+ <t t-call="o-spreadsheet-Icon.FILTER_ICON_INACTIVE"/>
3248
+ </div>
3249
+ </div>
3250
+ <Composer
3251
+ inputStyle="composerStyle"
3252
+ focus="props.focusComposer"
3253
+ onComposerContentFocused="props.onComposerContentFocused"
3254
+ />
3255
+ </div>
3256
+ </div>
3257
+ </t>
3258
+ </odoo>
3259
+ <!--
3260
+ __info__.version = '16.0.23';
3261
+ __info__.date = '2023-11-02T09:31:44.063Z';
3262
+ __info__.hash = '06ef793';
3263
+ -->