flexdesk 0.17.8 → 0.17.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/THIRD_PARTY_LICENSES.md +0 -0
- package/canvas.js +0 -0
- package/charts.js +0 -0
- package/core.js +0 -0
- package/css/base.css +78 -56
- package/css/flexdesk.css +111 -89
- package/css/overrides.css +12 -12
- package/css/reset.css +0 -0
- package/css/tokens.css +11 -2
- package/dist/canvas.js +0 -0
- package/dist/canvas.js.map +0 -0
- package/dist/charts.js +7 -6
- package/dist/charts.js.map +2 -2
- package/dist/{chunk-EIYNF4BD.js → chunk-2YTM3GJE.js} +2 -2
- package/dist/chunk-2YTM3GJE.js.map +7 -0
- package/dist/chunk-3PHCPZHT.js +0 -0
- package/dist/chunk-3PHCPZHT.js.map +0 -0
- package/dist/{chunk-UURZ37SD.js → chunk-7U4IB65H.js} +27 -9
- package/dist/chunk-7U4IB65H.js.map +7 -0
- package/dist/{chunk-D3COLZZ2.js → chunk-BE2PU3LL.js} +2 -2
- package/dist/{chunk-D3COLZZ2.js.map → chunk-BE2PU3LL.js.map} +0 -0
- package/dist/chunk-CVMCZZX2.js +0 -0
- package/dist/chunk-CVMCZZX2.js.map +0 -0
- package/dist/{chunk-UWO43BZU.js → chunk-F35XSQWA.js} +16 -20
- package/dist/chunk-F35XSQWA.js.map +7 -0
- package/dist/chunk-FOOS3T5L.js +0 -0
- package/dist/chunk-FOOS3T5L.js.map +0 -0
- package/dist/chunk-GOQLR5WR.js +0 -0
- package/dist/chunk-GOQLR5WR.js.map +0 -0
- package/dist/chunk-HNU6MM2B.js +0 -0
- package/dist/chunk-HNU6MM2B.js.map +0 -0
- package/dist/chunk-JKZLNKG6.js +0 -0
- package/dist/chunk-JKZLNKG6.js.map +0 -0
- package/dist/chunk-JYWURG5T.js +0 -0
- package/dist/chunk-JYWURG5T.js.map +0 -0
- package/dist/{chunk-RKNFBX5K.js → chunk-MIW7D6WC.js} +16 -4
- package/dist/{chunk-RKNFBX5K.js.map → chunk-MIW7D6WC.js.map} +2 -2
- package/dist/chunk-N7HC3ADV.js +0 -0
- package/dist/chunk-N7HC3ADV.js.map +0 -0
- package/dist/{chunk-LWV23YVE.js → chunk-NIJEJAZ7.js} +42 -18
- package/dist/chunk-NIJEJAZ7.js.map +7 -0
- package/dist/{chunk-HYJYYEPK.js → chunk-REJ5HLIM.js} +2 -2
- package/dist/{chunk-HYJYYEPK.js.map → chunk-REJ5HLIM.js.map} +0 -0
- package/dist/{chunk-WVFGV5FT.js → chunk-WUFLGETN.js} +39 -2
- package/dist/{chunk-WVFGV5FT.js.map → chunk-WUFLGETN.js.map} +3 -3
- package/dist/core.js +0 -0
- package/dist/core.js.map +0 -0
- package/dist/editor.js +2 -2
- package/dist/editor.js.map +0 -0
- package/dist/flexdesk.css +111 -89
- package/dist/flow.js +3 -3
- package/dist/flow.js.map +0 -0
- package/dist/host.js +0 -0
- package/dist/host.js.map +0 -0
- package/dist/reset.css +0 -0
- package/dist/tile_registry-6WZPTUZV.js +0 -0
- package/dist/tile_registry-6WZPTUZV.js.map +0 -0
- package/dist/tiles.js +63 -20
- package/dist/tiles.js.map +2 -2
- package/dist/tokens.css +11 -2
- package/dist/widgets.js +6 -6
- package/dist/widgets.js.map +0 -0
- package/dist/wm.js +5 -5
- package/dist/wm.js.map +0 -0
- package/docs/README.md +0 -0
- package/docs/best-practices.md +0 -0
- package/docs/components/charts.md +29 -0
- package/docs/components/command-palette.md +0 -0
- package/docs/components/conversation.md +0 -0
- package/docs/components/data-table-grid.md +0 -0
- package/docs/components/data-table.md +0 -0
- package/docs/components/editor.md +0 -0
- package/docs/components/flow-canvas-editor.md +0 -0
- package/docs/components/flow-editors.md +0 -0
- package/docs/components/flow-lane-editor.md +0 -0
- package/docs/components/flow-outline-editor.md +0 -0
- package/docs/components/forms-and-dialogs.md +0 -0
- package/docs/components/input-fields.md +0 -0
- package/docs/components/keymap.md +0 -0
- package/docs/components/markdown-and-outline.md +0 -0
- package/docs/components/menus.md +41 -0
- package/docs/components/notifications.md +0 -0
- package/docs/components/panels-and-desktops.md +0 -0
- package/docs/components/record-list-and-fact-table.md +0 -0
- package/docs/components/settings-view.md +0 -0
- package/docs/components/shell.md +0 -0
- package/docs/components/slide-out-panel.md +0 -0
- package/docs/components/tiles.md +25 -0
- package/docs/components/wizard.md +0 -0
- package/docs/concepts/building-and-packaging.md +0 -0
- package/docs/concepts/domain-neutrality.md +0 -0
- package/docs/concepts/host-port.md +0 -0
- package/docs/concepts/packages-and-entry-points.md +0 -0
- package/docs/concepts/peer-dependencies.md +0 -0
- package/docs/concepts/state-guard.md +0 -0
- package/docs/concepts/styling.md +68 -0
- package/docs/quickstart.md +0 -0
- package/editor.js +0 -0
- package/flow.js +0 -0
- package/host.js +0 -0
- package/package.json +1 -1
- package/src/canvas/canvas_adapter.js +0 -0
- package/src/canvas/edge_router.js +0 -0
- package/src/canvas/graph/connector_router.js +0 -0
- package/src/canvas/graph/history_service.js +0 -0
- package/src/canvas/graph/node_platform.js +0 -0
- package/src/canvas/index.js +0 -0
- package/src/canvas/layered_layout.js +0 -0
- package/src/charts/chart_types.js +3 -2
- package/src/charts/data_series_plot_window.js +0 -0
- package/src/charts/downsample.js +0 -0
- package/src/charts/plot_config.js +0 -0
- package/src/charts/plot_config_editor.js +8 -2
- package/src/charts/plotly_wrapper.js +0 -0
- package/src/core/event_bus.js +0 -0
- package/src/core/logging.js +0 -0
- package/src/core/settings.js +0 -0
- package/src/core/state_guard.js +0 -0
- package/src/core/state_guard_config.js +0 -0
- package/src/core/state_machine.js +0 -0
- package/src/editor/editor_pane.js +0 -0
- package/src/editor/monaco_editor_factory.js +0 -0
- package/src/editor/monaco_loader.js +0 -0
- package/src/editor/notebook_search.js +0 -0
- package/src/editor/notebook_tab_bar.js +26 -7
- package/src/editor/notebook_undo_manager.js +0 -0
- package/src/editor/split_pane_container.js +0 -0
- package/src/flow/canvas_editor/connections.js +0 -0
- package/src/flow/canvas_editor/editor.js +0 -0
- package/src/flow/canvas_editor/index.js +0 -0
- package/src/flow/canvas_editor/layout.js +0 -0
- package/src/flow/canvas_editor/strings.js +0 -0
- package/src/flow/kit/always_before.js +0 -0
- package/src/flow/kit/catalogue.js +0 -0
- package/src/flow/kit/chip_input.js +0 -0
- package/src/flow/kit/dom.js +0 -0
- package/src/flow/kit/findings.js +0 -0
- package/src/flow/kit/history.js +0 -0
- package/src/flow/kit/index.js +0 -0
- package/src/flow/kit/keys.js +0 -0
- package/src/flow/kit/logic_graph.js +0 -0
- package/src/flow/kit/references.js +0 -0
- package/src/flow/kit/settings_panel.js +0 -0
- package/src/flow/kit/settings_schema.js +0 -0
- package/src/flow/kit/step_picker.js +0 -0
- package/src/flow/kit/strings.js +0 -0
- package/src/flow/kit/value_picker.js +0 -0
- package/src/flow/kit/widgets.js +0 -0
- package/src/flow/lanes/editor.js +0 -0
- package/src/flow/lanes/index.js +0 -0
- package/src/flow/lanes/layout.js +0 -0
- package/src/flow/lanes/pipeline.js +0 -0
- package/src/flow/lanes/preview.js +0 -0
- package/src/flow/lanes/strings.js +0 -0
- package/src/flow/outline/editor.js +0 -0
- package/src/flow/outline/index.js +0 -0
- package/src/flow/outline/mapping.js +0 -0
- package/src/flow/outline/menu.js +0 -0
- package/src/flow/outline/operations.js +0 -0
- package/src/flow/outline/recognise.js +0 -0
- package/src/flow/outline/strings.js +0 -0
- package/src/help/help_modal.js +0 -0
- package/src/help/help_registry.js +0 -0
- package/src/host/external_links.js +0 -0
- package/src/host/file_picker.js +0 -0
- package/src/host/host.js +0 -0
- package/src/host/photino_host.js +0 -0
- package/src/host/photino_host.md +0 -0
- package/src/host/pywebview_host.js +0 -0
- package/src/tiles/chart_tiles.js +0 -0
- package/src/tiles/config_schema.js +0 -0
- package/src/tiles/figure_tile.js +0 -0
- package/src/tiles/layout_persistence.js +0 -0
- package/src/tiles/list_tiles.js +0 -0
- package/src/tiles/scope_picker.js +0 -0
- package/src/tiles/tile_base.js +67 -16
- package/src/tiles/tile_config_form.js +0 -0
- package/src/tiles/tile_grid.js +0 -0
- package/src/tiles/tile_registry.js +0 -0
- package/src/tiling/bottom_panel_tabs.js +0 -0
- package/src/tiling/command_palette.js +0 -0
- package/src/tiling/content_registry.js +0 -0
- package/src/tiling/desktops.js +0 -0
- package/src/tiling/entity_sources.js +0 -0
- package/src/tiling/keymap.js +0 -0
- package/src/tiling/kind_taxonomy.js +0 -0
- package/src/tiling/landing_table.js +0 -0
- package/src/tiling/loading_overlay.js +0 -0
- package/src/tiling/nav_panel.js +0 -0
- package/src/tiling/page_factory.js +0 -0
- package/src/tiling/panel_availability.js +0 -0
- package/src/tiling/panel_keys.js +0 -0
- package/src/tiling/shell.js +0 -0
- package/src/tiling/tab_strip.js +0 -0
- package/src/tiling/tile_breadcrumb.js +0 -0
- package/src/tiling/tile_renderer.js +0 -0
- package/src/tiling/tile_tab_menu.js +0 -0
- package/src/tiling/tile_tree.js +0 -0
- package/src/tiling/wm.js +0 -0
- package/src/tiling/zoom.js +0 -0
- package/src/ui/base/component_base.js +0 -0
- package/src/ui/base/controller_base.js +0 -0
- package/src/ui/base/page_base.js +0 -0
- package/src/ui/components/about_dialog.js +0 -0
- package/src/ui/components/action_dropdown.js +19 -6
- package/src/ui/components/alert_log.js +0 -0
- package/src/ui/components/alerts_pane.js +0 -0
- package/src/ui/components/attribute_list_editor.js +0 -0
- package/src/ui/components/autocomplete_field.js +0 -0
- package/src/ui/components/cell_editor_host.js +0 -0
- package/src/ui/components/cell_editors.js +0 -0
- package/src/ui/components/cell_grid.js +0 -0
- package/src/ui/components/cell_paste.js +0 -0
- package/src/ui/components/cell_selection.js +0 -0
- package/src/ui/components/choice_controls.js +0 -0
- package/src/ui/components/color_field.js +0 -0
- package/src/ui/components/color_list_field.js +0 -0
- package/src/ui/components/column_fit.js +0 -0
- package/src/ui/components/column_groups.js +0 -0
- package/src/ui/components/column_order.js +0 -0
- package/src/ui/components/computing_status_window.js +0 -0
- package/src/ui/components/confirm_dialog.js +0 -0
- package/src/ui/components/context_menu.js +20 -20
- package/src/ui/components/conversation_view.js +0 -0
- package/src/ui/components/crosstab.js +0 -0
- package/src/ui/components/data_table.js +45 -19
- package/src/ui/components/detail_header.js +0 -0
- package/src/ui/components/document_outline.js +0 -0
- package/src/ui/components/drag_reorder.js +0 -0
- package/src/ui/components/fact_table.js +0 -0
- package/src/ui/components/fill_handle.js +0 -0
- package/src/ui/components/gallery_picker.js +0 -0
- package/src/ui/components/header_actions.js +0 -0
- package/src/ui/components/inline_renamer.js +0 -0
- package/src/ui/components/job_progress.js +0 -0
- package/src/ui/components/managed_window.js +0 -0
- package/src/ui/components/menu_bar.js +0 -0
- package/src/ui/components/modal.js +0 -0
- package/src/ui/components/notification_history.js +0 -0
- package/src/ui/components/progress.js +0 -0
- package/src/ui/components/record_list.js +0 -0
- package/src/ui/components/row_activation.js +0 -0
- package/src/ui/components/section_stack.js +0 -0
- package/src/ui/components/series.js +0 -0
- package/src/ui/components/settings_view.js +0 -0
- package/src/ui/components/slide_out_panel.js +0 -0
- package/src/ui/components/slider_field.js +0 -0
- package/src/ui/components/sortable_list.js +0 -0
- package/src/ui/components/staged_edits.js +0 -0
- package/src/ui/components/staged_history.js +0 -0
- package/src/ui/components/table_filter_chips.js +0 -0
- package/src/ui/components/table_state_store.js +0 -0
- package/src/ui/components/table_structure.js +0 -0
- package/src/ui/components/table_values.js +0 -0
- package/src/ui/components/tabs.js +0 -0
- package/src/ui/components/tag_input.js +0 -0
- package/src/ui/components/toast.js +0 -0
- package/src/ui/components/toggle_field.js +0 -0
- package/src/ui/components/tree_view.js +0 -0
- package/src/ui/components/tsv.js +0 -0
- package/src/ui/components/window_taskbar.js +0 -0
- package/src/ui/components/wizard.js +0 -0
- package/src/ui/controllers/window_chrome_controller.js +0 -0
- package/src/ui/notification_center.js +0 -0
- package/src/ui/utils/auto_scrollbars.js +0 -0
- package/src/ui/utils/markdown.js +0 -0
- package/src/ui/utils/menu_viewport.js +81 -0
- package/src/ui/utils/native_context_menu.js +0 -0
- package/src/ui/utils/overlay_scrollbar.js +0 -0
- package/src/ui/utils/raf_resize_observer.js +0 -0
- package/src/ui/utils/scroll_lock.js +0 -0
- package/src/ui/utils/strip_scroll.js +0 -0
- package/src/ui/utils/tooltip_service.js +0 -0
- package/tiles.js +0 -0
- package/widgets.js +0 -0
- package/wm.js +0 -0
- package/dist/chunk-EIYNF4BD.js.map +0 -7
- package/dist/chunk-LWV23YVE.js.map +0 -7
- package/dist/chunk-UURZ37SD.js.map +0 -7
- package/dist/chunk-UWO43BZU.js.map +0 -7
package/dist/tokens.css
CHANGED
|
@@ -90,6 +90,13 @@
|
|
|
90
90
|
--accent-hover: #1177bb;
|
|
91
91
|
--accent-bright: #007acc; /* --layout-accent value */
|
|
92
92
|
|
|
93
|
+
/* Every other accent colour is DERIVED from the three above, so a
|
|
94
|
+
consumer that sets them (on :root) rethemes the whole accent (BUG-0044).
|
|
95
|
+
The light accents mix --accent-bright toward white: a slider thumb, a
|
|
96
|
+
sortable list's drop line and add button, a focused filter input. */
|
|
97
|
+
--accent-light: color-mix(in srgb, var(--accent-bright) 70%, white); /* ≈ #4da2db, was #569cd6 */
|
|
98
|
+
--accent-lighter: color-mix(in srgb, var(--accent-bright) 55%, white); /* ≈ #73b6e3, was #6eb3e9 */
|
|
99
|
+
|
|
93
100
|
/* ── Semantic colors ───────────────────────────────────────── */
|
|
94
101
|
--color-success: #3fb950;
|
|
95
102
|
--color-warning: #ff9800;
|
|
@@ -100,7 +107,9 @@
|
|
|
100
107
|
/* ── Surface state overlays ────────────────────────────────── */
|
|
101
108
|
--state-hover: rgba(255, 255, 255, 0.05);
|
|
102
109
|
--state-active: rgba(255, 255, 255, 0.08);
|
|
103
|
-
--state-selected: rgba(0, 122, 204, 0.15)
|
|
110
|
+
--state-selected: color-mix(in srgb, var(--accent-bright) 15%, transparent); /* rgba(0, 122, 204, 0.15) */
|
|
111
|
+
/* A DataTable row or cell that has just arrived flashes from this to transparent. */
|
|
112
|
+
--twm-dt-new-bg: color-mix(in srgb, var(--accent-bright) 22%, transparent); /* rgba(0, 122, 204, 0.22) */
|
|
104
113
|
|
|
105
114
|
/* ── Overlay scrollbars (installOverlayScrollbar) ─────────── */
|
|
106
115
|
--scrollbar-size: 6px;
|
|
@@ -114,7 +123,7 @@
|
|
|
114
123
|
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
115
124
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
|
|
116
125
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
|
|
117
|
-
--shadow-glow: 0 0 2px rgba(0, 122, 204, 0.3)
|
|
126
|
+
--shadow-glow: 0 0 2px color-mix(in srgb, var(--accent-bright) 30%, transparent); /* rgba(0, 122, 204, 0.3) */
|
|
118
127
|
|
|
119
128
|
/* ── Z-index layers ───────────────────────────────────────── */
|
|
120
129
|
--z-base: 0;
|
package/dist/widgets.js
CHANGED
|
@@ -17,16 +17,16 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
TAB_LEVELS,
|
|
19
19
|
createTabs
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-REJ5HLIM.js";
|
|
21
21
|
import {
|
|
22
22
|
ActionDropdown,
|
|
23
23
|
ComponentBase,
|
|
24
24
|
SlideOutPanel
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-MIW7D6WC.js";
|
|
26
26
|
import {
|
|
27
27
|
hideContextMenu,
|
|
28
28
|
showContextMenu
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-F35XSQWA.js";
|
|
30
30
|
import {
|
|
31
31
|
ColorListField,
|
|
32
32
|
SortableList,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
openForm,
|
|
36
36
|
openModal,
|
|
37
37
|
setModalHost
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-BE2PU3LL.js";
|
|
39
39
|
import {
|
|
40
40
|
ACTIONS,
|
|
41
41
|
AutocompleteField,
|
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
resolvePaging,
|
|
83
83
|
toTSV,
|
|
84
84
|
tsvCell
|
|
85
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-NIJEJAZ7.js";
|
|
86
86
|
import {
|
|
87
87
|
ColorField,
|
|
88
88
|
DEFAULT_WINDOW_STORAGE_KEY,
|
|
@@ -106,7 +106,7 @@ import {
|
|
|
106
106
|
} from "./chunk-N7HC3ADV.js";
|
|
107
107
|
import {
|
|
108
108
|
DragReorder
|
|
109
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-WUFLGETN.js";
|
|
110
110
|
import "./chunk-JYWURG5T.js";
|
|
111
111
|
|
|
112
112
|
// src/ui/base/controller_base.js
|
package/dist/widgets.js.map
CHANGED
|
File without changes
|
package/dist/wm.js
CHANGED
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
TAB_LEVELS,
|
|
7
7
|
createTabs
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-REJ5HLIM.js";
|
|
9
9
|
import {
|
|
10
10
|
showContextMenu
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-F35XSQWA.js";
|
|
12
12
|
import {
|
|
13
13
|
openForm
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-BE2PU3LL.js";
|
|
15
15
|
import {
|
|
16
16
|
ManagedWindow,
|
|
17
17
|
isRowActivation
|
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
import "./chunk-HNU6MM2B.js";
|
|
20
20
|
import {
|
|
21
21
|
NotebookTabBar
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-7U4IB65H.js";
|
|
23
23
|
import "./chunk-N7HC3ADV.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-WUFLGETN.js";
|
|
25
25
|
import "./chunk-JYWURG5T.js";
|
|
26
26
|
|
|
27
27
|
// src/tiling/bottom_panel_tabs.js
|
package/dist/wm.js.map
CHANGED
|
File without changes
|
package/docs/README.md
CHANGED
|
File without changes
|
package/docs/best-practices.md
CHANGED
|
File without changes
|
|
@@ -4,6 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
Plotly-backed charts: the wrapper, the chart types, subplot layouts, downsampling, the plot grid, the plot-config editor and the two plot windows. Plotly itself is not in the bundle; call `setPlotlySource()` with the path to your copy. The plot window's `streamEvents` option is described with the [other application-neutral options](../concepts/domain-neutrality.md#no-application-globals-the-gallery-picker-and-plot-window-events-0170).
|
|
6
6
|
|
|
7
|
+
## Interpolation `'auto'` is a listed choice (0.17.9)
|
|
8
|
+
|
|
9
|
+
A subplot's `interpolation` is `'linear'`, `'step'`, `'cubic'` or `'auto'`.
|
|
10
|
+
`'auto'` draws straight segments between the points, exactly as `'linear'`
|
|
11
|
+
does (`buildTrace` gives both the Plotly line shape `linear`, as it always
|
|
12
|
+
has); it is the value embedders such as EcoSim save for their plots.
|
|
13
|
+
[`renderPlotConfigEditor`](#editing-a-plot-config-renderplotconfigeditor-0170)
|
|
14
|
+
offered only Linear, Step and Cubic spline, so a subplot saved with `'auto'`
|
|
15
|
+
opened with `auto (not found)` in **Interpolation**. The select now offers
|
|
16
|
+
**Auto**, **Linear**, **Step** and **Cubic spline**: a subplot saved with
|
|
17
|
+
`'auto'` opens with Auto chosen and keeps `'auto'` until you pick something
|
|
18
|
+
else, and picking Auto writes `'auto'`. A new subplot is still `'linear'`
|
|
19
|
+
(`makeDefaultSubplot`), and every value draws as before.
|
|
20
|
+
|
|
21
|
+
`tests/plot_config_editor.test.mjs` §11 pins it.
|
|
22
|
+
|
|
23
|
+
## The plot config editor writes no stray "null" (0.17.9)
|
|
24
|
+
|
|
25
|
+
[`renderPlotConfigEditor`](#editing-a-plot-config-renderplotconfigeditor-0170)
|
|
26
|
+
drew a subplot's sections into one body and appended the sections a subplot
|
|
27
|
+
does not have as `null`, which `Element.append()` writes as the text `null`.
|
|
28
|
+
So every 2D subplot showed a `null` line between the Y axes and **Reference
|
|
29
|
+
lines** (where a 3D chart's **Z axis** goes), and an editor without
|
|
30
|
+
`seriesTransforms` showed another after **Shaded bands** (where **Derived
|
|
31
|
+
series** goes). The body now holds its sections and nothing else: a section
|
|
32
|
+
the subplot does not have is left out. Nothing else about the editor changed.
|
|
33
|
+
|
|
34
|
+
`tests/plot_config_editor.test.mjs` §10 pins it.
|
|
35
|
+
|
|
7
36
|
## A series transform knows its series, and takes a choice parameter (0.17.8)
|
|
8
37
|
|
|
9
38
|
Two additions to [`seriesTransforms`](#derived-series-seriestransforms-0170).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/docs/components/menus.md
CHANGED
|
@@ -4,6 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
`createMenuBar` draws File / Edit / View menus from one declarative model, with pointer and keyboard behaviour and the WAI-ARIA menubar roles, and plugs into the shell. `ActionDropdown` draws a dropdown of action buttons from a trigger.
|
|
6
6
|
|
|
7
|
+
## Context menus stay inside the window (0.17.9)
|
|
8
|
+
|
|
9
|
+
FlexDesk's own context menus: `showContextMenu(x, y, items, onAction)`, the
|
|
10
|
+
DataTable's right-click menu (its copy items and your `contextMenuItems`), and
|
|
11
|
+
`NotebookTabBar`'s tab menu. All three are placed the same way, however many
|
|
12
|
+
items they hold:
|
|
13
|
+
|
|
14
|
+
- **At most the window's height.** A menu is capped at the window's height
|
|
15
|
+
less 8px above and below. A longer menu scrolls inside (flexdesk.css gives
|
|
16
|
+
`.twm-context-menu` and `.nb-context-menu` `overflow-y: auto` and
|
|
17
|
+
`box-sizing: border-box`). Before, a menu had no cap: the DataTable's
|
|
18
|
+
opened above the window's top edge (a 101-item menu at y=-2153 in a 761px
|
|
19
|
+
window), and `showContextMenu`'s ran off the bottom. In both cases the items
|
|
20
|
+
past the edge could not be reached.
|
|
21
|
+
- **At the pointer, moved only to fit.** A menu opens with its top-left
|
|
22
|
+
corner at the pointer. When that does not fit, it moves left or up just
|
|
23
|
+
enough, and never past the window's top or left edge.
|
|
24
|
+
- **Every item can be reached from the keyboard.** The first enabled item has
|
|
25
|
+
focus when the menu opens. Up/Down (wrapping), Home and End move focus and
|
|
26
|
+
scroll the focused item into view inside the menu. Enter and Space choose,
|
|
27
|
+
and Escape closes. When the menu closes, focus goes back to where it was
|
|
28
|
+
(unless a click elsewhere has already moved it). The DataTable's menu and
|
|
29
|
+
the tab menu now do this too: before, only `showContextMenu` did.
|
|
30
|
+
- **Scrolling the menu does not close it.** `showContextMenu` still closes
|
|
31
|
+
when the page scrolls, and the DataTable's menu when anything outside it
|
|
32
|
+
scrolls.
|
|
33
|
+
|
|
34
|
+
Nothing changes in how you call them.
|
|
35
|
+
|
|
7
36
|
## A menu bar: `createMenuBar` (0.17.0)
|
|
8
37
|
|
|
9
38
|
File / Edit / View menus from one declarative model, instead of hand-built
|
|
@@ -84,3 +113,15 @@ doubled rule. `setOptions` follows the same rules, and an option's
|
|
|
84
113
|
`data-index` stays its index in `options`.
|
|
85
114
|
|
|
86
115
|
`tests/action_dropdown_separators.test.mjs` drives it in jsdom.
|
|
116
|
+
|
|
117
|
+
## Action dropdowns: positioning against the end edge (0.17.9)
|
|
118
|
+
|
|
119
|
+
`ActionDropdown.position(trigger, menu, { align })` places any menu against
|
|
120
|
+
any trigger: `position: fixed`, under the trigger when it fits there (else above it
|
|
121
|
+
when it fits there, else on the side with more room, scrolling inside), and kept 8px
|
|
122
|
+
inside the window. `align` says which trigger edge the menu lines up with
|
|
123
|
+
first: `'start'` (the default, and what it did before) its left edge, `'end'`
|
|
124
|
+
its right edge. Either flips to the other edge when the menu would leave the
|
|
125
|
+
window. A tile's ⋯ menu uses `'end'`
|
|
126
|
+
([Dashboard tiles](tiles.md#the--menu-is-drawn-over-the-page-0179)).
|
|
127
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/docs/components/shell.md
CHANGED
|
File without changes
|
|
File without changes
|
package/docs/components/tiles.md
CHANGED
|
@@ -13,6 +13,7 @@ Two different things in FlexDesk are called "tiles". `@flexdesk/wm` tiles the *w
|
|
|
13
13
|
- [Figure tiles: one override, the draw is the base's (0.17.0)](#figure-tiles-one-override-the-draw-is-the-bases-0170)
|
|
14
14
|
- [List and people tiles, and one scope for the board (0.16.1)](#list-and-people-tiles-and-one-scope-for-the-board-0161)
|
|
15
15
|
- [A tile's settings as a form: `mountTileConfigForm` (0.17.0)](#a-tiles-settings-as-a-form-mounttileconfigform-0170)
|
|
16
|
+
- [The ⋯ menu is drawn over the page (0.17.9)](#the--menu-is-drawn-over-the-page-0179)
|
|
16
17
|
|
|
17
18
|
## Layouts are keyed by whatever you key them by
|
|
18
19
|
|
|
@@ -208,3 +209,27 @@ modal is open is ignored. It answers a function that unsubscribes and closes the
|
|
|
208
209
|
slide-out; an open modal is left to the user, keeps its form and still saves on
|
|
209
210
|
Save. A renderer's `commit` on a `readonly` field applies nothing and answers
|
|
210
211
|
`{valid: false, error}`.
|
|
212
|
+
|
|
213
|
+
## The ⋯ menu is drawn over the page (0.17.9)
|
|
214
|
+
|
|
215
|
+
A tile's **More actions** menu (`.tile-menu-dropdown`, the entries of
|
|
216
|
+
`menuItems()`) is no longer drawn inside the tile. While it is open it is
|
|
217
|
+
moved to `document.body` (or to the open modal's host, as `showContextMenu`
|
|
218
|
+
does) and placed with `ActionDropdown.position(button, menu, { align: 'end' })`:
|
|
219
|
+
|
|
220
|
+
- **Nothing clips it.** It is `position: fixed`, on `--z-over-windows`, so it
|
|
221
|
+
draws over neighbouring tiles, and over the managed window a grid sits in.
|
|
222
|
+
- **It stays in the window.** Its right edge lines up with the ⋯ button's
|
|
223
|
+
when there is room; otherwise its left edge does, clamped 8px inside the
|
|
224
|
+
window. It opens under the button when it fits there, else above it when it
|
|
225
|
+
fits there, else on the side with more room, scrolling inside.
|
|
226
|
+
- **It goes back when it closes.** Choosing an entry, a press outside it, or
|
|
227
|
+
the ⋯ button again closes it and puts it back in the tile's header, so
|
|
228
|
+
`tile.element.querySelector('.tile-menu-item')` finds the entries while it
|
|
229
|
+
is closed. `dispose()` closes an open menu first, so none is left on the
|
|
230
|
+
page.
|
|
231
|
+
|
|
232
|
+
Until 0.17.8 the menu was `position: absolute` inside the tile, so in a tile
|
|
233
|
+
narrower than about 220px its left part and its labels were cut off
|
|
234
|
+
(BUG-0043). `tests/tile_menu_unclipped.test.mjs` holds it.
|
|
235
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/docs/concepts/styling.md
CHANGED
|
@@ -45,3 +45,71 @@ its plain elements (headings, code, tables, lists).
|
|
|
45
45
|
Icons are rendered by applying the `material-symbols-outlined` class. FlexDesk does
|
|
46
46
|
not ship the font — supply it from Google Fonts or self-host. Without it, icons fall
|
|
47
47
|
back to their text names and nothing breaks.
|
|
48
|
+
|
|
49
|
+
## Retheming the accent (0.17.10)
|
|
50
|
+
|
|
51
|
+
The accent colours in `flexdesk.css` that were the literal `#007acc`
|
|
52
|
+
(`rgb(0, 122, 204)`), its tints, and the light accent `#569cd6` /
|
|
53
|
+
`#6eb3e9` are now derived from an accent token. Setting the tokens on `:root`
|
|
54
|
+
rethemes all of them:
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
:root {
|
|
58
|
+
--accent: #8a2be2;
|
|
59
|
+
--accent-hover: #9b4dea;
|
|
60
|
+
--accent-bright: #a64dff; /* selections, focus rings, tints, primary buttons, the slider thumb */
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`--accent` and `--accent-hover` stay literals. `--accent-bright` is the one
|
|
65
|
+
the rest is derived from, in `tokens.css`:
|
|
66
|
+
|
|
67
|
+
- `--state-selected`: `color-mix(in srgb, var(--accent-bright) 15%, transparent)`.
|
|
68
|
+
It was `rgba(0, 122, 204, 0.15)`, the same colour.
|
|
69
|
+
- `--shadow-glow`: `0 0 2px color-mix(in srgb, var(--accent-bright) 30%, transparent)`.
|
|
70
|
+
It was `0 0 2px rgba(0, 122, 204, 0.3)`, the same colour.
|
|
71
|
+
- `--twm-dt-new-bg` (new): `color-mix(in srgb, var(--accent-bright) 22%, transparent)`,
|
|
72
|
+
the colour a DataTable row or cell that has just arrived flashes from.
|
|
73
|
+
The stylesheet read it before, with an `rgba(0, 122, 204, 0.22)`
|
|
74
|
+
fallback, but nothing defined it.
|
|
75
|
+
- `--accent-light` (new): `color-mix(in srgb, var(--accent-bright) 70%, white)`,
|
|
76
|
+
about `#4da2db`. It replaces `#569cd6`.
|
|
77
|
+
- `--accent-lighter` (new): `color-mix(in srgb, var(--accent-bright) 55%, white)`,
|
|
78
|
+
about `#73b6e3`. It replaces `#6eb3e9`.
|
|
79
|
+
|
|
80
|
+
You can still set `--state-selected`, `--shadow-glow` or `--twm-dt-new-bg`
|
|
81
|
+
yourself. Set the derived tokens on `:root`, as `tokens.css` does: a custom
|
|
82
|
+
property that reads `var(--accent-bright)` is resolved where it is declared,
|
|
83
|
+
so an `--accent-bright` set on a lower element does not reach the tokens
|
|
84
|
+
derived from it on `:root`.
|
|
85
|
+
|
|
86
|
+
What changed in the stylesheet:
|
|
87
|
+
|
|
88
|
+
- **Tints.** The `rgba(0, 122, 204, a)` tints are now
|
|
89
|
+
`color-mix(in srgb, var(--accent-bright) a%, transparent)`, with the same
|
|
90
|
+
colour by default. They are the DataTable's selected rows and cells, the
|
|
91
|
+
filter chip when on, the autocomplete's namespace pill and active item,
|
|
92
|
+
`.add-widget-btn`, `.tile.resizing`, `.tile-ghost`, the focused leaf's inset
|
|
93
|
+
shadow, the document outline's active link, the canvas marquee and the
|
|
94
|
+
flow graph's port dots.
|
|
95
|
+
- **The light accent.** The SliderField thumb, the SortableList drop line,
|
|
96
|
+
add button and input focus, the DataTable filter inputs' focus border and
|
|
97
|
+
the notebook autocomplete's border read `--accent-light`. The active thumb
|
|
98
|
+
reads `--accent-lighter`. `#569cd6` cannot be mixed exactly from `#007acc`,
|
|
99
|
+
so these move to the nearest mix of `--accent-bright` with white: the thumb
|
|
100
|
+
goes from `#569cd6` to about `#4da2db`, and the active thumb from `#6eb3e9`
|
|
101
|
+
to about `#73b6e3`, a difference of about 1.5 to 1.7 ΔE (OKLab × 100).
|
|
102
|
+
- **No fallbacks.** `var(--accent-bright, #007acc)`, `var(--state-selected, …)`,
|
|
103
|
+
`var(--ea-accent, …)` and `var(--accent, …)` no longer carry fallbacks.
|
|
104
|
+
`tokens.css` defines all of them, so no computed colour changes, but
|
|
105
|
+
`flexdesk.css` now needs `tokens.css` (or your own definitions of these tokens).
|
|
106
|
+
|
|
107
|
+
Not part of the accent, and still literals: the autocomplete's type colours
|
|
108
|
+
(`stock` is `#569cd6` beside `#4ec9b0`, `#ce9178`, …), the notification
|
|
109
|
+
border `#4fc1ff`, and links (`#3794ff`).
|
|
110
|
+
|
|
111
|
+
Some accent blues in other shades are still literals, because no mix of an
|
|
112
|
+
accent token gives their colour exactly. They include the selected tile
|
|
113
|
+
(`#78b9ff`), the primary button's hover (`#1683c4`, `#1486cf`), the row
|
|
114
|
+
cursor and snap preview (`rgba(17, 119, 179, a)`), and some flow-lanes and
|
|
115
|
+
plot-window colours. To retheme them, override their rules.
|
package/docs/quickstart.md
CHANGED
|
File without changes
|
package/editor.js
CHANGED
|
File without changes
|
package/flow.js
CHANGED
|
File without changes
|
package/host.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/canvas/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -61,7 +61,8 @@ const LINE_DASH_MAP = {
|
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Interpolation mapping (Chart.js to Plotly line shape)
|
|
64
|
+
* Interpolation mapping (Chart.js to Plotly line shape). 'auto' draws straight
|
|
65
|
+
* segments between the points, as 'linear' does.
|
|
65
66
|
*/
|
|
66
67
|
const INTERPOLATION_MAP = {
|
|
67
68
|
linear: 'linear',
|
|
@@ -81,7 +82,7 @@ const INTERPOLATION_MAP = {
|
|
|
81
82
|
* @param {string} [options.color] - Series color (hex)
|
|
82
83
|
* @param {number} [options.lineWidth] - Line width in pixels
|
|
83
84
|
* @param {string} [options.lineStyle] - Line style: solid, dashed, dotted
|
|
84
|
-
* @param {string} [options.interpolation] - Interpolation: linear, step, cubic
|
|
85
|
+
* @param {string} [options.interpolation] - Interpolation: linear, step, cubic, or auto (drawn as linear)
|
|
85
86
|
* @param {string} [options.yAxisId] - Y-axis identifier (y, y2, y3, etc.)
|
|
86
87
|
* @param {boolean} [options.showMarkers] - Show data point markers
|
|
87
88
|
* @param {number} [options.seriesIndex] - Index for default color selection
|
|
File without changes
|
package/src/charts/downsample.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -63,7 +63,10 @@ const LEGEND_POSITIONS = Object.freeze([
|
|
|
63
63
|
{ value: 'hidden', label: 'Hidden' }, { value: 'top', label: 'Top' }, { value: 'bottom', label: 'Bottom' },
|
|
64
64
|
{ value: 'left', label: 'Left' }, { value: 'right', label: 'Right' },
|
|
65
65
|
]);
|
|
66
|
+
// 'auto' is drawn as 'linear' (buildTrace); it is listed so a config saved with it
|
|
67
|
+
// shows it and keeps it.
|
|
66
68
|
const INTERPOLATIONS = Object.freeze([
|
|
69
|
+
{ value: 'auto', label: 'Auto' },
|
|
67
70
|
{ value: 'linear', label: 'Linear' }, { value: 'step', label: 'Step' }, { value: 'cubic', label: 'Cubic spline' },
|
|
68
71
|
]);
|
|
69
72
|
const NAN_STRATEGIES = Object.freeze([
|
|
@@ -364,7 +367,10 @@ function renderPlotConfigEditor(container, config, options = {}) {
|
|
|
364
367
|
let sources = null;
|
|
365
368
|
const overlaySources = () => (sources ??= Promise.resolve().then(() => opts.overlaySources()));
|
|
366
369
|
|
|
367
|
-
|
|
370
|
+
// Element.append() writes a null child as the text "null": a section the
|
|
371
|
+
// subplot does not have (the z axis of a 2D chart, the transforms when
|
|
372
|
+
// there are none) is left out, not appended.
|
|
373
|
+
body.append(...[
|
|
368
374
|
section('Subplot', field('Title', textInput(sp.displayName, (v) => { sp.displayName = v; notify(); },
|
|
369
375
|
{ placeholder: 'Untitled' }))),
|
|
370
376
|
section('Display', ...displayFields(sp)),
|
|
@@ -374,7 +380,7 @@ function renderPlotConfigEditor(container, config, options = {}) {
|
|
|
374
380
|
section('Reference lines', referenceLinesEditor(sp)),
|
|
375
381
|
section('Shaded bands', shadedBandsEditor(sp)),
|
|
376
382
|
transformsSection(sp),
|
|
377
|
-
);
|
|
383
|
+
].filter(Boolean));
|
|
378
384
|
}
|
|
379
385
|
|
|
380
386
|
function displayFields(sp) {
|
|
File without changes
|
package/src/core/event_bus.js
CHANGED
|
File without changes
|
package/src/core/logging.js
CHANGED
|
File without changes
|
package/src/core/settings.js
CHANGED
|
File without changes
|
package/src/core/state_guard.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
import { DragReorder } from '../ui/components/drag_reorder.js';
|
|
26
26
|
import { revealInStrip, wheelStripSideways } from '../ui/utils/strip_scroll.js';
|
|
27
|
+
import { placeMenuInViewport, moveMenuFocus, focusMenuItem } from '../ui/utils/menu_viewport.js';
|
|
27
28
|
|
|
28
29
|
/** The MIME type a dragged editor tab carries when the embedder names none. */
|
|
29
30
|
export const DEFAULT_TAB_DRAG_MIME = 'application/x-flexdesk-tab';
|
|
@@ -64,6 +65,8 @@ export class NotebookTabBar {
|
|
|
64
65
|
|
|
65
66
|
/** @type {HTMLElement|null} */
|
|
66
67
|
#contextMenuEl = null;
|
|
68
|
+
/** BUG-0040. What had focus when the menu opened. @type {Element|null} */
|
|
69
|
+
#contextMenuReturnFocus = null;
|
|
67
70
|
|
|
68
71
|
/** @type {Function|null} */
|
|
69
72
|
#boundHideContextMenu = null;
|
|
@@ -417,6 +420,7 @@ export class NotebookTabBar {
|
|
|
417
420
|
|
|
418
421
|
const menu = document.createElement('div');
|
|
419
422
|
menu.className = 'nb-context-menu';
|
|
423
|
+
menu.setAttribute('role', 'menu');
|
|
420
424
|
|
|
421
425
|
for (const item of cleaned) {
|
|
422
426
|
if (item.separator) {
|
|
@@ -427,6 +431,8 @@ export class NotebookTabBar {
|
|
|
427
431
|
}
|
|
428
432
|
|
|
429
433
|
const btn = document.createElement('button');
|
|
434
|
+
btn.type = 'button';
|
|
435
|
+
btn.setAttribute('role', 'menuitem');
|
|
430
436
|
btn.className = 'nb-context-menu__item';
|
|
431
437
|
if (item.danger) btn.classList.add('nb-context-menu__item--danger');
|
|
432
438
|
if (item.disabled) btn.classList.add('nb-context-menu__item--disabled');
|
|
@@ -445,15 +451,14 @@ export class NotebookTabBar {
|
|
|
445
451
|
menu.appendChild(btn);
|
|
446
452
|
}
|
|
447
453
|
|
|
454
|
+
this.#contextMenuReturnFocus = document.activeElement;
|
|
448
455
|
document.body.appendChild(menu);
|
|
449
456
|
this.#contextMenuEl = menu;
|
|
450
457
|
|
|
451
|
-
//
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
menu.style.left = `${Math.max(0, left)}px`;
|
|
456
|
-
menu.style.top = `${Math.max(0, top)}px`;
|
|
458
|
+
// BUG-0040. Inside the window, at most its height, scrolling when
|
|
459
|
+
// longer; the keyboard starts on the first item it can use.
|
|
460
|
+
placeMenuInViewport(menu, x, y);
|
|
461
|
+
focusMenuItem(this.#contextMenuItems()[0]);
|
|
457
462
|
|
|
458
463
|
// Animate in
|
|
459
464
|
requestAnimationFrame(() => menu.classList.add('visible'));
|
|
@@ -468,15 +473,29 @@ export class NotebookTabBar {
|
|
|
468
473
|
|
|
469
474
|
#hideContextMenu() {
|
|
470
475
|
if (!this.#contextMenuEl) return;
|
|
476
|
+
const returnTo = this.#contextMenuReturnFocus;
|
|
477
|
+
const held = this.#contextMenuEl.contains(document.activeElement);
|
|
471
478
|
this.#contextMenuEl.remove();
|
|
472
479
|
this.#contextMenuEl = null;
|
|
480
|
+
this.#contextMenuReturnFocus = null;
|
|
473
481
|
document.removeEventListener('click', this.#boundHideContextMenu, true);
|
|
474
482
|
document.removeEventListener('contextmenu', this.#boundHideContextMenu, true);
|
|
475
483
|
document.removeEventListener('keydown', this.#onKeyDown);
|
|
484
|
+
if (held && returnTo?.isConnected) returnTo.focus?.({ preventScroll: true });
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/** BUG-0040. The menu's items the keyboard can land on. */
|
|
488
|
+
#contextMenuItems() {
|
|
489
|
+
return this.#contextMenuEl
|
|
490
|
+
? [...this.#contextMenuEl.querySelectorAll('.nb-context-menu__item:not(.nb-context-menu__item--disabled)')]
|
|
491
|
+
: [];
|
|
476
492
|
}
|
|
477
493
|
|
|
478
494
|
#onKeyDown = (e) => {
|
|
479
|
-
if (e.key === 'Escape') this.#hideContextMenu();
|
|
495
|
+
if (e.key === 'Escape') { this.#hideContextMenu(); return; }
|
|
496
|
+
// BUG-0040. Up/Down/Home/End move between the items and scroll the
|
|
497
|
+
// focused one into view; Enter and Space are the buttons' own.
|
|
498
|
+
moveMenuFocus(e, this.#contextMenuItems());
|
|
480
499
|
};
|
|
481
500
|
|
|
482
501
|
#handleContextMenuAction(action, filePath) {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/flow/kit/dom.js
CHANGED
|
File without changes
|
package/src/flow/kit/findings.js
CHANGED
|
File without changes
|
package/src/flow/kit/history.js
CHANGED
|
File without changes
|
package/src/flow/kit/index.js
CHANGED
|
File without changes
|
package/src/flow/kit/keys.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|