mito-ai 0.1.59__py3-none-any.whl → 0.1.60__py3-none-any.whl

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.
Files changed (50) hide show
  1. mito_ai/_version.py +1 -1
  2. mito_ai/completions/prompt_builders/agent_system_message.py +7 -1
  3. mito_ai/completions/prompt_builders/chat_system_message.py +4 -0
  4. mito_ai/completions/prompt_builders/prompt_constants.py +15 -0
  5. mito_ai/rules/handlers.py +46 -12
  6. mito_ai/rules/utils.py +170 -6
  7. mito_ai/tests/providers/test_providers.py +5 -5
  8. mito_ai/tests/rules/rules_test.py +100 -4
  9. mito_ai/utils/anthropic_utils.py +1 -2
  10. mito_ai/utils/model_utils.py +0 -2
  11. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/build_log.json +1 -1
  12. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/package.json +2 -2
  13. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/package.json.orig +1 -1
  14. mito_ai-0.1.59.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.44c109c7be36fb884d25.js → mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.dccfa541c464ee0e5cd4.js +676 -106
  15. mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.dccfa541c464ee0e5cd4.js.map +1 -0
  16. mito_ai-0.1.59.data/data/share/jupyter/labextensions/mito_ai/static/style_index_js.f5d476ac514294615881.js → mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/node_modules_css-loader_dist_cjs_js_style_base_css.3594c54c9d209e1ed56e.js +2 -460
  17. mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/node_modules_css-loader_dist_cjs_js_style_base_css.3594c54c9d209e1ed56e.js.map +1 -0
  18. mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/node_modules_css-loader_dist_runtime_api_js-node_modules_css-loader_dist_runtime_sourceMaps_j-49e54d.3972dd8e7542bba478ad.js +463 -0
  19. mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/node_modules_css-loader_dist_runtime_api_js-node_modules_css-loader_dist_runtime_sourceMaps_j-49e54d.3972dd8e7542bba478ad.js.map +1 -0
  20. mito_ai-0.1.59.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.f7decebaf69618541e0f.js → mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.9735d9bfc8891147fee0.js +6 -6
  21. mito_ai-0.1.60.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.9735d9bfc8891147fee0.js.map +1 -0
  22. {mito_ai-0.1.59.dist-info → mito_ai-0.1.60.dist-info}/METADATA +1 -1
  23. {mito_ai-0.1.59.dist-info → mito_ai-0.1.60.dist-info}/RECORD +47 -45
  24. mito_ai-0.1.59.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.44c109c7be36fb884d25.js.map +0 -1
  25. mito_ai-0.1.59.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.f7decebaf69618541e0f.js.map +0 -1
  26. mito_ai-0.1.59.data/data/share/jupyter/labextensions/mito_ai/static/style_index_js.f5d476ac514294615881.js.map +0 -1
  27. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/etc/jupyter/jupyter_server_config.d/mito_ai.json +0 -0
  28. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/toolbar-buttons.json +0 -0
  29. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js +0 -0
  30. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js.map +0 -0
  31. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/style.js +0 -0
  32. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js +0 -0
  33. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js.map +0 -0
  34. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js +0 -0
  35. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js.map +0 -0
  36. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js +0 -0
  37. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js.map +0 -0
  38. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js +0 -0
  39. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js.map +0 -0
  40. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js +0 -0
  41. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js.map +0 -0
  42. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js +0 -0
  43. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js.map +0 -0
  44. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js +0 -0
  45. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js.map +0 -0
  46. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/themes/mito_ai/index.css +0 -0
  47. {mito_ai-0.1.59.data → mito_ai-0.1.60.data}/data/share/jupyter/labextensions/mito_ai/themes/mito_ai/index.js +0 -0
  48. {mito_ai-0.1.59.dist-info → mito_ai-0.1.60.dist-info}/WHEEL +0 -0
  49. {mito_ai-0.1.59.dist-info → mito_ai-0.1.60.dist-info}/entry_points.txt +0 -0
  50. {mito_ai-0.1.59.dist-info → mito_ai-0.1.60.dist-info}/licenses/LICENSE +0 -0
@@ -1060,7 +1060,7 @@ const ChatDropdown = ({ options, onSelect, filterText, isDropdownFromButton = fa
1060
1060
  // Rules first
1061
1061
  ...rules.map((rule) => ({
1062
1062
  type: 'rule',
1063
- rule: rule
1063
+ rule: rule.name
1064
1064
  })),
1065
1065
  // Cells second (when user types @Cell or @cell)
1066
1066
  ...cellReferences.map((cell) => ({
@@ -1109,17 +1109,18 @@ const ChatDropdown = ({ options, onSelect, filterText, isDropdownFromButton = fa
1109
1109
  })),
1110
1110
  ];
1111
1111
  let searchFilteredOptions = allOptions.filter((option) => {
1112
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1112
1113
  if (option.type === 'variable') {
1113
- return option.variable.variable_name.toLowerCase().includes(effectiveFilterText.toLowerCase()) &&
1114
+ return ((_b = (_a = option.variable.variable_name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '').includes(effectiveFilterText.toLowerCase()) &&
1114
1115
  option.variable.type !== "<class 'module'>" &&
1115
1116
  option.variable.variable_name !== "FUNCTIONS"; // This is default exported from mitosheet when you run from mitosheet import * as FUNCTIONS
1116
1117
  }
1117
1118
  else if (option.type === 'file') {
1118
- return option.file.variable_name.toLowerCase().includes(effectiveFilterText.toLowerCase());
1119
+ return ((_d = (_c = option.file.variable_name) === null || _c === void 0 ? void 0 : _c.toLowerCase()) !== null && _d !== void 0 ? _d : '').includes(effectiveFilterText.toLowerCase());
1119
1120
  }
1120
1121
  else if (option.type === 'db') {
1121
- return option.variable.variable_name.toLowerCase().includes(effectiveFilterText.toLowerCase()) ||
1122
- option.variable.value.toLowerCase().includes(effectiveFilterText.toLowerCase());
1122
+ return ((_f = (_e = option.variable.variable_name) === null || _e === void 0 ? void 0 : _e.toLowerCase()) !== null && _f !== void 0 ? _f : '').includes(effectiveFilterText.toLowerCase()) ||
1123
+ ((_h = (_g = option.variable.value) === null || _g === void 0 ? void 0 : _g.toLowerCase()) !== null && _h !== void 0 ? _h : '').includes(effectiveFilterText.toLowerCase());
1123
1124
  }
1124
1125
  else if (option.type === 'cell') {
1125
1126
  // Match "CellN" (no space)
@@ -1129,7 +1130,7 @@ const ChatDropdown = ({ options, onSelect, filterText, isDropdownFromButton = fa
1129
1130
  numberText.includes(effectiveFilterText.toLowerCase());
1130
1131
  }
1131
1132
  else {
1132
- return option.rule.toLowerCase().includes(effectiveFilterText.toLowerCase());
1133
+ return ((_k = (_j = option.rule) === null || _j === void 0 ? void 0 : _j.toLowerCase()) !== null && _k !== void 0 ? _k : '').includes(effectiveFilterText.toLowerCase());
1133
1134
  }
1134
1135
  });
1135
1136
  // If user is searching (has filter text), show all matches
@@ -7630,8 +7631,7 @@ __webpack_require__.r(__webpack_exports__);
7630
7631
 
7631
7632
 
7632
7633
  const ChartWizardButton = ({ onButtonClick }) => {
7633
- return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
7634
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_TextAndIconButton__WEBPACK_IMPORTED_MODULE_9__["default"], { icon: _icons_MagicWand__WEBPACK_IMPORTED_MODULE_10__["default"], text: "Chart Wizard", title: "Chart Wizard", onClick: onButtonClick, variant: 'purple', width: 'fit-contents', iconPosition: 'left' })));
7634
+ return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_TextAndIconButton__WEBPACK_IMPORTED_MODULE_9__["default"], { icon: _icons_MagicWand__WEBPACK_IMPORTED_MODULE_10__["default"], text: "Chart Wizard", title: "Chart Wizard", onClick: onButtonClick, variant: "purple", width: "fit-contents", iconPosition: "left" }));
7635
7635
  };
7636
7636
  const ChartWizardPlugin = {
7637
7637
  id: 'mito-ai:chart-wizard',
@@ -7818,16 +7818,18 @@ __webpack_require__.r(__webpack_exports__);
7818
7818
  /* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
7819
7819
  /* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__);
7820
7820
  /* harmony import */ var _utils_parser__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils/parser */ "./lib/Extensions/ChartWizard/utils/parser.js");
7821
+ /* harmony import */ var _utils_chartExport__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils/chartExport */ "./lib/Extensions/ChartWizard/utils/chartExport.js");
7821
7822
  /* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
7822
7823
  /* harmony import */ var _utils_strings__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../utils/strings */ "./lib/utils/strings.js");
7823
- /* harmony import */ var _components_LoadingDots__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../components/LoadingDots */ "./lib/components/LoadingDots.js");
7824
- /* harmony import */ var _AddFieldButton__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./AddFieldButton */ "./lib/Extensions/ChartWizard/AddFieldButton.js");
7825
- /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/BooleanInputRow.js");
7826
- /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/TupleInputRow.js");
7827
- /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/NumberInputRow.js");
7828
- /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/utils.js");
7829
- /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/ColorInputRow.js");
7830
- /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/StringInputRow.js");
7824
+ /* harmony import */ var _components_LoadingDots__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../components/LoadingDots */ "./lib/components/LoadingDots.js");
7825
+ /* harmony import */ var _components_ToggleButton__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../components/ToggleButton */ "./lib/components/ToggleButton.js");
7826
+ /* harmony import */ var _AddFieldButton__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./AddFieldButton */ "./lib/Extensions/ChartWizard/AddFieldButton.js");
7827
+ /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/BooleanInputRow.js");
7828
+ /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/TupleInputRow.js");
7829
+ /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/NumberInputRow.js");
7830
+ /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/utils.js");
7831
+ /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/ColorInputRow.js");
7832
+ /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./inputs */ "./lib/Extensions/ChartWizard/inputs/StringInputRow.js");
7831
7833
  /* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./hooks */ "./lib/Extensions/ChartWizard/hooks/useChartConfig.js");
7832
7834
  /* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./hooks */ "./lib/Extensions/ChartWizard/hooks/useDebouncedNotebookUpdate.js");
7833
7835
  /* harmony import */ var _utils_notebook__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/notebook */ "./lib/utils/notebook.js");
@@ -7847,6 +7849,8 @@ __webpack_require__.r(__webpack_exports__);
7847
7849
 
7848
7850
 
7849
7851
 
7852
+
7853
+
7850
7854
  /**
7851
7855
  * Formats a variable name into a human-readable label.
7852
7856
  * Converts snake_case to Title Case (e.g., "figure_size" -> "Figure Size").
@@ -7864,6 +7868,7 @@ const ChartWizardContent = ({ chartData }) => {
7864
7868
  const widgetRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
7865
7869
  const [overlayHeight, setOverlayHeight] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
7866
7870
  const [isActiveCellMismatch, setIsActiveCellMismatch] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
7871
+ const [exportFormat, setExportFormat] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('png');
7867
7872
  // Reset currentSourceCode when switching to a different chart
7868
7873
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
7869
7874
  setCurrentSourceCode(null);
@@ -7996,6 +8001,18 @@ const ChartWizardContent = ({ chartData }) => {
7996
8001
  // Update the cell with the updated code
7997
8002
  updateNotebookCell(updatedCode);
7998
8003
  }, [updateNotebookCell]);
8004
+ /**
8005
+ * Exports the chart image to disk via the chartExport utility; shows a notification on error.
8006
+ */
8007
+ const handleExportChart = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async () => {
8008
+ void (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_7__.logEvent)('chart_wizard_export_clicked');
8009
+ if (!chartData)
8010
+ return;
8011
+ const result = await (0,_utils_chartExport__WEBPACK_IMPORTED_MODULE_9__.exportChartImage)(chartData, exportFormat);
8012
+ if (!result.success) {
8013
+ _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.Notification.emit(result.error, 'error', { autoClose: 5000 });
8014
+ }
8015
+ }, [chartData, exportFormat]);
7999
8016
  /**
8000
8017
  * Renders the appropriate input field component based on variable type.
8001
8018
  */
@@ -8008,22 +8025,22 @@ const ChartWizardContent = ({ chartData }) => {
8008
8025
  };
8009
8026
  switch (variable.type) {
8010
8027
  case 'boolean':
8011
- return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_9__.BooleanInputRow, { key: variable.name, ...commonProps });
8028
+ return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_10__.BooleanInputRow, { key: variable.name, ...commonProps });
8012
8029
  case 'tuple':
8013
- return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_10__.TupleInputRow, { key: variable.name, ...commonProps });
8030
+ return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_11__.TupleInputRow, { key: variable.name, ...commonProps });
8014
8031
  case 'number':
8015
- return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_11__.NumberInputRow, { key: variable.name, ...commonProps });
8032
+ return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_12__.NumberInputRow, { key: variable.name, ...commonProps });
8016
8033
  case 'string': {
8017
8034
  // String input - check if it's a hex color
8018
8035
  const stringValue = variable.value;
8019
- const isColor = (0,_inputs__WEBPACK_IMPORTED_MODULE_12__.isHexColor)(stringValue);
8036
+ const isColor = (0,_inputs__WEBPACK_IMPORTED_MODULE_13__.isHexColor)(stringValue);
8020
8037
  if (isColor) {
8021
- return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_13__.ColorInputRow, { key: variable.name, ...commonProps });
8038
+ return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_14__.ColorInputRow, { key: variable.name, ...commonProps });
8022
8039
  }
8023
- return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_14__.StringInputRow, { key: variable.name, ...commonProps });
8040
+ return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_15__.StringInputRow, { key: variable.name, ...commonProps });
8024
8041
  }
8025
8042
  default:
8026
- return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_14__.StringInputRow, { key: variable.name, ...commonProps });
8043
+ return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_inputs__WEBPACK_IMPORTED_MODULE_15__.StringInputRow, { key: variable.name, ...commonProps });
8027
8044
  }
8028
8045
  }, [handleVariableChange]);
8029
8046
  // Memoize input fields to prevent unnecessary re-renders
@@ -8062,7 +8079,12 @@ const ChartWizardContent = ({ chartData }) => {
8062
8079
  hasConfig ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-config-container" },
8063
8080
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", { className: "chart-wizard-config-description" }, "Edit values below to customize your chart. Changes will be reflected in the notebook."),
8064
8081
  inputFields,
8065
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_AddFieldButton__WEBPACK_IMPORTED_MODULE_15__["default"], { code: currentSourceCode || (chartData === null || chartData === void 0 ? void 0 : chartData.sourceCode) || null, onFieldAdded: handleFieldAdded, clearPendingUpdate: clearPendingUpdate, onLoadingStateChange: setIsAddingField }))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-no-config" },
8082
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_AddFieldButton__WEBPACK_IMPORTED_MODULE_16__["default"], { code: currentSourceCode || (chartData === null || chartData === void 0 ? void 0 : chartData.sourceCode) || null, onFieldAdded: handleFieldAdded, clearPendingUpdate: clearPendingUpdate, onLoadingStateChange: setIsAddingField }),
8083
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-export-section" },
8084
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h3", { className: "chart-wizard-section-heading" }, "Export"),
8085
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-export-format-row" },
8086
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_ToggleButton__WEBPACK_IMPORTED_MODULE_17__["default"], { leftText: "PNG", rightText: "JPG", isLeftSelected: exportFormat === 'png', onChange: (isPng) => setExportFormat(isPng ? 'png' : 'jpeg') })),
8087
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "button-base button-purple add-field-button", type: "button", title: "Save chart image to file", onClick: handleExportChart }, "Export image")))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-no-config" },
8066
8088
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", null,
8067
8089
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("strong", null, "This chart isn't ready for Chart Wizard yet."),
8068
8090
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("br", null),
@@ -8071,13 +8093,13 @@ const ChartWizardContent = ({ chartData }) => {
8071
8093
  "Converting",
8072
8094
  ' ',
8073
8095
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "chart-wizard-loading-dots" },
8074
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_LoadingDots__WEBPACK_IMPORTED_MODULE_16__["default"], null)))) : ('Convert')))),
8096
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_LoadingDots__WEBPACK_IMPORTED_MODULE_18__["default"], null)))) : ('Convert')))),
8075
8097
  isAddingField && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-overlay", style: { height: overlayHeight > 0 ? `${overlayHeight}px` : '100%' } },
8076
8098
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-overlay-text" },
8077
8099
  "Adding new field",
8078
8100
  ' ',
8079
8101
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "chart-wizard-loading-dots" },
8080
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_LoadingDots__WEBPACK_IMPORTED_MODULE_16__["default"], null)))))));
8102
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_LoadingDots__WEBPACK_IMPORTED_MODULE_18__["default"], null)))))));
8081
8103
  };
8082
8104
  class ChartWizardWidget extends _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.ReactWidget {
8083
8105
  constructor() {
@@ -8322,10 +8344,46 @@ __webpack_require__.r(__webpack_exports__);
8322
8344
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
8323
8345
  */
8324
8346
 
8347
+ function clamp(value, min, max) {
8348
+ return Math.min(Math.max(value, min), max);
8349
+ }
8350
+ /** Use slider when range is small and decimal-friendly (e.g. opacity 0–1). */
8351
+ const SLIDER_RANGE_THRESHOLD = 2;
8352
+ /** Step for decimal ranges: fine for 0–1, coarser for 1–2. */
8353
+ function decimalStep(min, max) {
8354
+ const range = max - min;
8355
+ return range <= 1 ? 0.01 : 0.1;
8356
+ }
8357
+ const SliderWithNumberInput = ({ value, min, max, step, label, onChange }) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-number-slider-row" },
8358
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "range", min: min, max: max, step: step, value: value, onChange: (e) => onChange(clamp(parseFloat(e.target.value), min, max)), className: "chart-wizard-range-slider", "aria-label": label }),
8359
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "number", min: min, max: max, step: step, value: value, onChange: (e) => {
8360
+ let v = parseFloat(e.target.value);
8361
+ if (Number.isNaN(v))
8362
+ v = min;
8363
+ onChange(clamp(v, min, max));
8364
+ }, className: "chart-wizard-number-input chart-wizard-number-input-narrow", "aria-label": `${label} (number)` })));
8365
+ const NumberInputOnly = ({ value, min, max, step, onChange }) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "number", value: value, min: min, max: max, step: step, onChange: (e) => {
8366
+ let v = parseFloat(e.target.value);
8367
+ if (Number.isNaN(v))
8368
+ v = min !== null && min !== void 0 ? min : 0;
8369
+ if (min !== undefined && max !== undefined)
8370
+ v = clamp(v, min, max);
8371
+ onChange(v);
8372
+ }, className: "chart-wizard-number-input" }));
8325
8373
  const NumberInputRow = ({ variable, label, onVariableChange }) => {
8374
+ const numValue = variable.value;
8375
+ const min = variable.min;
8376
+ const max = variable.max;
8377
+ const hasRange = min !== undefined && max !== undefined;
8378
+ const rangeSpan = hasRange ? max - min : 0;
8379
+ const useSlider = hasRange && rangeSpan <= SLIDER_RANGE_THRESHOLD;
8380
+ const step = useSlider ? decimalStep(min, max) : 1;
8381
+ const handleChange = (value) => {
8382
+ onVariableChange(variable.name, value);
8383
+ };
8326
8384
  return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { key: variable.name, className: "chart-wizard-input-row" },
8327
8385
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { className: "chart-wizard-input-label" }, label),
8328
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "number", value: variable.value, onChange: (e) => onVariableChange(variable.name, parseFloat(e.target.value) || 0), className: "chart-wizard-number-input" })));
8386
+ useSlider && min !== undefined && max !== undefined ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(SliderWithNumberInput, { value: numValue, min: min, max: max, step: step, label: label, onChange: handleChange })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(NumberInputOnly, { value: numValue, min: min, max: max, step: step, onChange: handleChange }))));
8329
8387
  };
8330
8388
 
8331
8389
 
@@ -8375,20 +8433,31 @@ __webpack_require__.r(__webpack_exports__);
8375
8433
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
8376
8434
  */
8377
8435
 
8436
+ function clamp(value, min, max) {
8437
+ return Math.min(Math.max(value, min), max);
8438
+ }
8378
8439
  const TupleInputRow = ({ variable, label, onVariableChange }) => {
8379
8440
  const tupleValue = variable.value;
8441
+ const min = variable.min;
8442
+ const max = variable.max;
8443
+ const clampOrIdentity = (v, fallback) => {
8444
+ if (min !== undefined && max !== undefined) {
8445
+ return clamp(v, min, max);
8446
+ }
8447
+ return Number.isNaN(v) ? fallback : v;
8448
+ };
8380
8449
  return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { key: variable.name, className: "chart-wizard-input-row" },
8381
8450
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { className: "chart-wizard-input-label" }, label),
8382
8451
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "chart-wizard-tuple-container" },
8383
8452
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "("),
8384
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "number", value: tupleValue[0], onChange: (e) => {
8385
- const newValue = [parseFloat(e.target.value) || 0, tupleValue[1]];
8386
- onVariableChange(variable.name, newValue);
8453
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "number", value: tupleValue[0], min: min, max: max, step: min !== undefined && max !== undefined && max - min <= 1 ? 'any' : 1, onChange: (e) => {
8454
+ const v = clampOrIdentity(parseFloat(e.target.value), 0);
8455
+ onVariableChange(variable.name, [v, tupleValue[1]]);
8387
8456
  }, className: "chart-wizard-tuple-input" }),
8388
8457
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, ","),
8389
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "number", value: tupleValue[1], onChange: (e) => {
8390
- const newValue = [tupleValue[0], parseFloat(e.target.value) || 0];
8391
- onVariableChange(variable.name, newValue);
8458
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "number", value: tupleValue[1], min: min, max: max, step: min !== undefined && max !== undefined && max - min <= 1 ? 'any' : 1, onChange: (e) => {
8459
+ const v = clampOrIdentity(parseFloat(e.target.value), 0);
8460
+ onVariableChange(variable.name, [tupleValue[0], v]);
8392
8461
  }, className: "chart-wizard-tuple-input" }),
8393
8462
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, ")"))));
8394
8463
  };
@@ -8443,6 +8512,263 @@ const normalizeHexColor = (value) => {
8443
8512
  };
8444
8513
 
8445
8514
 
8515
+ /***/ }),
8516
+
8517
+ /***/ "./lib/Extensions/ChartWizard/utils/chartExport.js":
8518
+ /*!*********************************************************!*\
8519
+ !*** ./lib/Extensions/ChartWizard/utils/chartExport.js ***!
8520
+ \*********************************************************/
8521
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8522
+
8523
+ __webpack_require__.r(__webpack_exports__);
8524
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
8525
+ /* harmony export */ exportChartImage: () => (/* binding */ exportChartImage)
8526
+ /* harmony export */ });
8527
+ /* harmony import */ var _imageFinder__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./imageFinder */ "./lib/Extensions/ChartWizard/utils/imageFinder.js");
8528
+ /* harmony import */ var _fileSaver__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./fileSaver */ "./lib/Extensions/ChartWizard/utils/fileSaver.js");
8529
+ /* harmony import */ var _download__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./download */ "./lib/Extensions/ChartWizard/utils/download.js");
8530
+ /*
8531
+ * Copyright (c) Saga Inc.
8532
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
8533
+ */
8534
+
8535
+
8536
+
8537
+ /**
8538
+ * Exports the chart image to the user's disk. Uses File System Access API when available
8539
+ * so the user can choose the save location; otherwise triggers a download.
8540
+ *
8541
+ * @param chartData - Chart wizard data identifying the notebook panel and cell
8542
+ * @param format - Export format: 'png' or 'jpeg'
8543
+ * @returns Result indicating success or an error message for the UI to display
8544
+ */
8545
+ async function exportChartImage(chartData, format = 'png') {
8546
+ const found = (0,_imageFinder__WEBPACK_IMPORTED_MODULE_0__.findChartImageDataUrl)(chartData);
8547
+ if (!found.ok)
8548
+ return { success: false, error: found.error };
8549
+ if ((0,_fileSaver__WEBPACK_IMPORTED_MODULE_1__.isFileSystemAccessAvailable)()) {
8550
+ try {
8551
+ await (0,_fileSaver__WEBPACK_IMPORTED_MODULE_1__.saveWithFilePicker)(found.dataUrl, format);
8552
+ }
8553
+ catch (err) {
8554
+ if (err.name === 'AbortError') {
8555
+ return { success: true };
8556
+ }
8557
+ await (0,_download__WEBPACK_IMPORTED_MODULE_2__.downloadImage)(found.dataUrl, format);
8558
+ }
8559
+ }
8560
+ else {
8561
+ await (0,_download__WEBPACK_IMPORTED_MODULE_2__.downloadImage)(found.dataUrl, format);
8562
+ }
8563
+ return { success: true };
8564
+ }
8565
+
8566
+
8567
+ /***/ }),
8568
+
8569
+ /***/ "./lib/Extensions/ChartWizard/utils/download.js":
8570
+ /*!******************************************************!*\
8571
+ !*** ./lib/Extensions/ChartWizard/utils/download.js ***!
8572
+ \******************************************************/
8573
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8574
+
8575
+ __webpack_require__.r(__webpack_exports__);
8576
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
8577
+ /* harmony export */ downloadImage: () => (/* binding */ downloadImage)
8578
+ /* harmony export */ });
8579
+ /* harmony import */ var _imageConverter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./imageConverter */ "./lib/Extensions/ChartWizard/utils/imageConverter.js");
8580
+ /*
8581
+ * Copyright (c) Saga Inc.
8582
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
8583
+ */
8584
+
8585
+ const SUGGESTED_NAMES = {
8586
+ png: 'chart.png',
8587
+ jpeg: 'chart.jpg'
8588
+ };
8589
+ /**
8590
+ * Triggers a browser download of a URL.
8591
+ */
8592
+ function triggerDownload(url, filename) {
8593
+ const a = document.createElement('a');
8594
+ a.href = url;
8595
+ a.download = filename;
8596
+ a.click();
8597
+ }
8598
+ /**
8599
+ * Downloads an image using the browser's fallback download mechanism.
8600
+ */
8601
+ async function downloadImage(dataUrl, format) {
8602
+ if (format === 'jpeg') {
8603
+ const blob = await (0,_imageConverter__WEBPACK_IMPORTED_MODULE_0__.dataUrlToBlob)(dataUrl, format);
8604
+ const url = URL.createObjectURL(blob);
8605
+ triggerDownload(url, SUGGESTED_NAMES.jpeg);
8606
+ URL.revokeObjectURL(url);
8607
+ }
8608
+ else {
8609
+ triggerDownload(dataUrl, SUGGESTED_NAMES.png);
8610
+ }
8611
+ }
8612
+
8613
+
8614
+ /***/ }),
8615
+
8616
+ /***/ "./lib/Extensions/ChartWizard/utils/fileSaver.js":
8617
+ /*!*******************************************************!*\
8618
+ !*** ./lib/Extensions/ChartWizard/utils/fileSaver.js ***!
8619
+ \*******************************************************/
8620
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8621
+
8622
+ __webpack_require__.r(__webpack_exports__);
8623
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
8624
+ /* harmony export */ isFileSystemAccessAvailable: () => (/* binding */ isFileSystemAccessAvailable),
8625
+ /* harmony export */ saveWithFilePicker: () => (/* binding */ saveWithFilePicker)
8626
+ /* harmony export */ });
8627
+ /* harmony import */ var _imageConverter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./imageConverter */ "./lib/Extensions/ChartWizard/utils/imageConverter.js");
8628
+ /*
8629
+ * Copyright (c) Saga Inc.
8630
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
8631
+ */
8632
+
8633
+ const SUGGESTED_NAMES = {
8634
+ png: 'chart.png',
8635
+ jpeg: 'chart.jpg'
8636
+ };
8637
+ const FILE_PICKER_TYPES = {
8638
+ png: [{ description: 'PNG Image', accept: { 'image/png': ['.png'] } }],
8639
+ jpeg: [{ description: 'JPEG Image', accept: { 'image/jpeg': ['.jpg', '.jpeg'] } }]
8640
+ };
8641
+ /**
8642
+ * Checks if the File System Access API is available.
8643
+ */
8644
+ function isFileSystemAccessAvailable() {
8645
+ return ('showSaveFilePicker' in window &&
8646
+ typeof window.showSaveFilePicker ===
8647
+ 'function');
8648
+ }
8649
+ /**
8650
+ * Saves a blob to disk using the File System Access API.
8651
+ */
8652
+ async function writeBlobToFile(blob, handle) {
8653
+ const writable = await handle.createWritable();
8654
+ try {
8655
+ await writable.write(blob);
8656
+ }
8657
+ finally {
8658
+ await writable.close();
8659
+ }
8660
+ }
8661
+ /**
8662
+ * Saves an image to disk using the File System Access API.
8663
+ */
8664
+ async function saveWithFilePicker(dataUrl, format) {
8665
+ var _a, _b;
8666
+ const handle = await ((_b = (_a = window).showSaveFilePicker) === null || _b === void 0 ? void 0 : _b.call(_a, {
8667
+ suggestedName: SUGGESTED_NAMES[format],
8668
+ types: FILE_PICKER_TYPES[format]
8669
+ }));
8670
+ if (!handle)
8671
+ return;
8672
+ const blob = await (0,_imageConverter__WEBPACK_IMPORTED_MODULE_0__.dataUrlToBlob)(dataUrl, format);
8673
+ await writeBlobToFile(blob, handle);
8674
+ }
8675
+
8676
+
8677
+ /***/ }),
8678
+
8679
+ /***/ "./lib/Extensions/ChartWizard/utils/imageConverter.js":
8680
+ /*!************************************************************!*\
8681
+ !*** ./lib/Extensions/ChartWizard/utils/imageConverter.js ***!
8682
+ \************************************************************/
8683
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8684
+
8685
+ __webpack_require__.r(__webpack_exports__);
8686
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
8687
+ /* harmony export */ dataUrlToBlob: () => (/* binding */ dataUrlToBlob),
8688
+ /* harmony export */ dataUrlToJpegBlob: () => (/* binding */ dataUrlToJpegBlob)
8689
+ /* harmony export */ });
8690
+ /*
8691
+ * Copyright (c) Saga Inc.
8692
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
8693
+ */
8694
+ const JPEG_QUALITY = 1.0;
8695
+ /**
8696
+ * Converts a data URL image to a JPEG blob.
8697
+ */
8698
+ function dataUrlToJpegBlob(dataUrl) {
8699
+ return new Promise((resolve, reject) => {
8700
+ const img = new Image();
8701
+ img.crossOrigin = 'anonymous';
8702
+ img.onload = () => {
8703
+ const canvas = document.createElement('canvas');
8704
+ canvas.width = img.naturalWidth;
8705
+ canvas.height = img.naturalHeight;
8706
+ const ctx = canvas.getContext('2d');
8707
+ if (!ctx) {
8708
+ reject(new Error('Could not get canvas context'));
8709
+ return;
8710
+ }
8711
+ ctx.drawImage(img, 0, 0);
8712
+ canvas.toBlob((blob) => (blob ? resolve(blob) : reject(new Error('toBlob failed'))), 'image/jpeg', JPEG_QUALITY);
8713
+ };
8714
+ img.onerror = () => reject(new Error('Failed to load image'));
8715
+ img.src = dataUrl;
8716
+ });
8717
+ }
8718
+ /**
8719
+ * Converts a data URL to a blob in the specified format.
8720
+ */
8721
+ async function dataUrlToBlob(dataUrl, format) {
8722
+ if (format === 'jpeg') {
8723
+ return dataUrlToJpegBlob(dataUrl);
8724
+ }
8725
+ return fetch(dataUrl).then((r) => r.blob());
8726
+ }
8727
+
8728
+
8729
+ /***/ }),
8730
+
8731
+ /***/ "./lib/Extensions/ChartWizard/utils/imageFinder.js":
8732
+ /*!*********************************************************!*\
8733
+ !*** ./lib/Extensions/ChartWizard/utils/imageFinder.js ***!
8734
+ \*********************************************************/
8735
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8736
+
8737
+ __webpack_require__.r(__webpack_exports__);
8738
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
8739
+ /* harmony export */ findChartImageDataUrl: () => (/* binding */ findChartImageDataUrl)
8740
+ /* harmony export */ });
8741
+ /* harmony import */ var _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/cells */ "webpack/sharing/consume/default/@jupyterlab/cells");
8742
+ /* harmony import */ var _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0__);
8743
+ /*
8744
+ * Copyright (c) Saga Inc.
8745
+ * Distributed under the terms of the GNU Affero General Public License v3.0 License.
8746
+ */
8747
+
8748
+ /**
8749
+ * Finds the chart image data URL from the notebook cell output.
8750
+ */
8751
+ function findChartImageDataUrl(chartData) {
8752
+ const notebookPanel = chartData.notebookTracker.find((panel) => panel.id === chartData.notebookPanelId);
8753
+ if (!notebookPanel) {
8754
+ return { ok: false, error: 'Could not find the notebook.' };
8755
+ }
8756
+ const cellWidget = notebookPanel.content.widgets.find((cell) => cell.model.id === chartData.cellId);
8757
+ if (!(cellWidget instanceof _jupyterlab_cells__WEBPACK_IMPORTED_MODULE_0__.CodeCell)) {
8758
+ return { ok: false, error: 'Could not find the chart cell.' };
8759
+ }
8760
+ const outputNode = cellWidget.outputArea.node;
8761
+ const img = outputNode.querySelector('.jp-RenderedImage img[src^="data:image"]');
8762
+ if (!img || !img.src || !img.src.startsWith('data:image')) {
8763
+ return {
8764
+ ok: false,
8765
+ error: 'No chart image found. Re-run the chart cell and try again.'
8766
+ };
8767
+ }
8768
+ return { ok: true, dataUrl: img.src };
8769
+ }
8770
+
8771
+
8446
8772
  /***/ }),
8447
8773
 
8448
8774
  /***/ "./lib/Extensions/ChartWizard/utils/parser.js":
@@ -8474,9 +8800,21 @@ function parseChartConfig(sourceCode) {
8474
8800
  }
8475
8801
  const configSection = sourceCode.substring(startIndex + configStartMarker.length, endIndex).trim();
8476
8802
  const lines = configSection.split('\n').map(line => line.trim()).filter(line => line.length > 0);
8803
+ // First pass: collect # RANGE lines (format: # RANGE VARIABLE_NAME MIN MAX)
8804
+ const rangeByVar = new Map();
8805
+ const rangeRegex = /^#\s*RANGE\s+([A-Z_][A-Z0-9_]*)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*$/;
8806
+ for (const line of lines) {
8807
+ const rangeMatch = line.match(rangeRegex);
8808
+ if (rangeMatch && rangeMatch[1] && rangeMatch[2] !== undefined && rangeMatch[3] !== undefined) {
8809
+ const varName = rangeMatch[1];
8810
+ const minVal = parseFloat(rangeMatch[2]);
8811
+ const maxVal = parseFloat(rangeMatch[3]);
8812
+ rangeByVar.set(varName, { min: minVal, max: maxVal });
8813
+ }
8814
+ }
8477
8815
  const variables = [];
8478
8816
  for (const line of lines) {
8479
- // Skip comment lines
8817
+ // Skip comment-only lines (RANGE lines already processed above)
8480
8818
  if (line.startsWith('#')) {
8481
8819
  continue;
8482
8820
  }
@@ -8487,10 +8825,12 @@ function parseChartConfig(sourceCode) {
8487
8825
  const valueStr = match[2];
8488
8826
  const parsed = parseValue(valueStr.trim());
8489
8827
  if (parsed) {
8828
+ const range = rangeByVar.get(varName);
8490
8829
  variables.push({
8491
8830
  name: varName,
8492
8831
  value: parsed.value,
8493
- type: parsed.type
8832
+ type: parsed.type,
8833
+ ...(range && { min: range.min, max: range.max })
8494
8834
  });
8495
8835
  }
8496
8836
  }
@@ -8643,6 +8983,9 @@ function updateChartConfig(sourceCode, variables) {
8643
8983
  // Use updated variables if available, otherwise keep original
8644
8984
  const variablesToWrite = parsed.variables.map(v => varMap.get(v.name) || v);
8645
8985
  for (const variable of variablesToWrite) {
8986
+ if (variable.min !== undefined && variable.max !== undefined) {
8987
+ newConfigSection += `# RANGE ${variable.name} ${variable.min} ${variable.max}\n`;
8988
+ }
8646
8989
  const formattedValue = formatValue(variable.value, variable.type);
8647
8990
  newConfigSection += `${variable.name} = ${formattedValue}\n`;
8648
8991
  }
@@ -11155,6 +11498,7 @@ __webpack_require__.r(__webpack_exports__);
11155
11498
 
11156
11499
 
11157
11500
  const RulesForm = ({ formData, formError, onInputChange, onSubmit, onClose, isEditing }) => {
11501
+ var _a;
11158
11502
  const [isLoading, setIsLoading] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
11159
11503
  const handleSubmit = async (e) => {
11160
11504
  e.preventDefault();
@@ -11175,13 +11519,20 @@ const RulesForm = ({ formData, formError, onInputChange, onSubmit, onClose, isEd
11175
11519
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "text", id: "name", name: "name", value: formData.name, onChange: onInputChange, placeholder: "Enter rule name", required: true })),
11176
11520
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "form-group" },
11177
11521
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { htmlFor: "description" }, "Rule Content"),
11178
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("textarea", { id: "description", name: "description", value: formData.description, onChange: onInputChange, placeholder: "Enter or paste rule content here", rows: 30, required: true, className: "form-textarea" })),
11179
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "form-actions" },
11180
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "button", className: "button-base button-gray", onClick: onClose, disabled: isLoading }, "Cancel"),
11181
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "submit", className: "button-base button-purple", disabled: isLoading }, isLoading ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
11182
- "Saving Rule",
11183
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { color: 'var(--purple-700)' } },
11184
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_LoadingCircle__WEBPACK_IMPORTED_MODULE_3__["default"], null)))) : (isEditing ? 'Update Rule' : 'Add Rule')))));
11522
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("textarea", { id: "description", name: "description", value: formData.description, onChange: onInputChange, placeholder: "Enter or paste rule content here", rows: 10, required: true, className: "form-textarea" })),
11523
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "rules-form-footer" },
11524
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "rules-form-footer-left" },
11525
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "form-group-checkbox" },
11526
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "checkbox", id: "isDefault", name: "isDefault", checked: (_a = formData.isDefault) !== null && _a !== void 0 ? _a : false, onChange: onInputChange }),
11527
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { htmlFor: "isDefault" }, "Default rule")),
11528
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("sub", { className: "rules-form-footer-sub" },
11529
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "Default rules are auto-applied to every prompt."))),
11530
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "form-actions" },
11531
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "button", className: "button-base button-gray", onClick: onClose, disabled: isLoading }, "Cancel"),
11532
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "submit", className: "button-base button-purple", disabled: isLoading }, isLoading ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
11533
+ "Saving Rule",
11534
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { style: { color: 'var(--purple-700)' } },
11535
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_LoadingCircle__WEBPACK_IMPORTED_MODULE_3__["default"], null)))) : (isEditing ? 'Update Rule' : 'Add Rule'))))));
11185
11536
  };
11186
11537
 
11187
11538
 
@@ -11199,9 +11550,10 @@ __webpack_require__.r(__webpack_exports__);
11199
11550
  /* harmony export */ });
11200
11551
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
11201
11552
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
11202
- /* harmony import */ var _RulesForm__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./RulesForm */ "./lib/Extensions/SettingsManager/rules/RulesForm.js");
11203
- /* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
11204
- /* harmony import */ var _utils_fileName__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../utils/fileName */ "./lib/utils/fileName.js");
11553
+ /* harmony import */ var _RulesForm__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./RulesForm */ "./lib/Extensions/SettingsManager/rules/RulesForm.js");
11554
+ /* harmony import */ var _restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../restAPI/RestAPI */ "./lib/restAPI/RestAPI.js");
11555
+ /* harmony import */ var _utils_fileName__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../utils/fileName */ "./lib/utils/fileName.js");
11556
+ /* harmony import */ var _style_button_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../style/button.css */ "./style/button.css");
11205
11557
  /*
11206
11558
  * Copyright (c) Saga Inc.
11207
11559
  * Distributed under the terms of the GNU Affero General Public License v3.0 License.
@@ -11210,19 +11562,23 @@ __webpack_require__.r(__webpack_exports__);
11210
11562
 
11211
11563
 
11212
11564
 
11565
+
11213
11566
  const RulesPage = () => {
11214
11567
  const [modalStatus, setModalStatus] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined);
11215
11568
  const [rules, setRules] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
11216
11569
  const [error, setError] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
11570
+ const [editingRuleName, setEditingRuleName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
11217
11571
  const [formData, setFormData] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({
11218
11572
  name: '',
11219
- description: ''
11573
+ description: '',
11574
+ isDefault: false
11220
11575
  });
11221
11576
  const [formError, setFormError] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
11577
+ const [filterDefaultOnly, setFilterDefaultOnly] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
11222
11578
  const fetchRules = async () => {
11223
11579
  try {
11224
- const rules = await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__.getRules)();
11225
- setRules(rules.sort());
11580
+ const rulesList = await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_2__.getRules)();
11581
+ setRules(rulesList.sort((a, b) => a.name.localeCompare(b.name)));
11226
11582
  }
11227
11583
  catch (err) {
11228
11584
  setError(err instanceof Error ? err.message : 'An error occurred');
@@ -11232,35 +11588,66 @@ const RulesPage = () => {
11232
11588
  void fetchRules();
11233
11589
  }, []);
11234
11590
  const handleInputChange = (e) => {
11235
- const { name, value } = e.target;
11591
+ const target = e.target;
11592
+ const name = target.name;
11593
+ const value = target.type === 'checkbox'
11594
+ ? target.checked
11595
+ : target.value;
11236
11596
  setFormData(prev => ({ ...prev, [name]: value }));
11237
11597
  };
11238
11598
  const handleSubmit = async (e) => {
11239
11599
  e.preventDefault();
11240
- // Make sure tha the rule is a valid file name
11241
- if (!(0,_utils_fileName__WEBPACK_IMPORTED_MODULE_2__.isValidFileName)(formData.name)) {
11242
- setFormError('Invalid rule name. Rules must contain only alphanumeric characters, underscores, or hyphens.');
11600
+ const slugifiedName = (0,_utils_fileName__WEBPACK_IMPORTED_MODULE_3__.slugifyRuleName)(formData.name);
11601
+ if (!slugifiedName) {
11602
+ setFormError('Rule name is required. Use letters, numbers, spaces, hyphens, or underscores.');
11243
11603
  return;
11244
11604
  }
11245
- else {
11246
- setFormError(null);
11605
+ setFormError(null);
11606
+ await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_2__.setRule)(slugifiedName, formData.description, formData.isDefault);
11607
+ if (editingRuleName && editingRuleName !== slugifiedName) {
11608
+ await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_2__.deleteRule)(editingRuleName);
11247
11609
  }
11248
- await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__.setRule)(formData.name, formData.description);
11249
11610
  setModalStatus(undefined);
11611
+ setEditingRuleName(null);
11250
11612
  setFormData({
11251
11613
  name: '',
11252
- description: ''
11614
+ description: '',
11615
+ isDefault: false
11253
11616
  });
11254
11617
  void fetchRules();
11255
11618
  };
11256
- const handleRuleClick = async (rule) => {
11257
- const ruleContent = await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_1__.getRule)(rule);
11619
+ const handleRuleClick = async (ruleName) => {
11620
+ const ruleFile = ruleName.includes('.md') ? ruleName : `${ruleName}.md`;
11621
+ const { content: ruleContent, isDefault } = await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_2__.getRule)(ruleFile);
11622
+ const nameWithoutExt = (0,_utils_fileName__WEBPACK_IMPORTED_MODULE_3__.stripFileEnding)(ruleFile);
11623
+ setEditingRuleName(nameWithoutExt);
11258
11624
  setFormData({
11259
- name: (0,_utils_fileName__WEBPACK_IMPORTED_MODULE_2__.stripFileEnding)(rule),
11260
- description: ruleContent || ''
11625
+ name: nameWithoutExt,
11626
+ description: ruleContent || '',
11627
+ isDefault
11261
11628
  });
11262
11629
  setModalStatus('edit rule');
11263
11630
  };
11631
+ const handleDeleteRule = async (e, ruleItem) => {
11632
+ e.stopPropagation();
11633
+ const ruleName = (0,_utils_fileName__WEBPACK_IMPORTED_MODULE_3__.stripFileEnding)(ruleItem.name);
11634
+ if (!window.confirm(`Are you sure you want to delete the rule "${ruleName}"?`)) {
11635
+ return;
11636
+ }
11637
+ try {
11638
+ await (0,_restAPI_RestAPI__WEBPACK_IMPORTED_MODULE_2__.deleteRule)(ruleName);
11639
+ if (editingRuleName === ruleName) {
11640
+ setModalStatus(undefined);
11641
+ setEditingRuleName(null);
11642
+ setFormData({ name: '', description: '', isDefault: false });
11643
+ }
11644
+ void fetchRules();
11645
+ }
11646
+ catch (err) {
11647
+ setError(err instanceof Error ? err.message : 'Failed to delete rule');
11648
+ }
11649
+ };
11650
+ const displayedRules = filterDefaultOnly ? rules.filter(r => r.isDefault) : rules;
11264
11651
  return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null,
11265
11652
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "settings-header" },
11266
11653
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h2", null, "Rules"),
@@ -11268,20 +11655,29 @@ const RulesPage = () => {
11268
11655
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("b", null, "\uFF0B Add Rule"))),
11269
11656
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", null, "Rules provide more context to Ai models to help them follow your preferences, adhere to your organization's style guides, learn niche topics, and be a better colleague."),
11270
11657
  error && react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", { className: "error" }, error),
11271
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "rules-list" }, rules && rules.length > 0 ? rules.map((rule) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { key: rule, className: "rule-item", onClick: () => handleRuleClick(rule) },
11658
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "rules-list-filter" },
11659
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "button", className: !filterDefaultOnly ? 'button-base button-gray rules-list-filter-active' : 'button-base button-gray', onClick: () => setFilterDefaultOnly(false) }, "All"),
11660
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "button", className: filterDefaultOnly ? 'button-base button-gray rules-list-filter-active' : 'button-base button-gray', onClick: () => setFilterDefaultOnly(true) }, "Default only")),
11661
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "rules-list" }, displayedRules.length > 0 ? displayedRules.map((ruleItem) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { key: ruleItem.name, className: "rule-item", onClick: () => handleRuleClick(ruleItem.name) },
11272
11662
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "rule-content" },
11273
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h4", { className: "rule-name" }, (0,_utils_fileName__WEBPACK_IMPORTED_MODULE_2__.stripFileEnding)(rule)),
11274
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", { className: "rule-description" }, "Click update to edit this rule's description and settings.")),
11663
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h4", { className: "rule-name" },
11664
+ (0,_utils_fileName__WEBPACK_IMPORTED_MODULE_3__.stripFileEnding)(ruleItem.name),
11665
+ ruleItem.isDefault && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "rule-badge" }, "Default")))),
11275
11666
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "rule-actions" },
11276
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "button-base button-gray" }, "Update"))))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "empty-state" },
11277
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", null, "No rules created yet. Add your first rule to get started!")))),
11667
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "button", className: "button-base button-gray" }, "Update"),
11668
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { type: "button", className: "button-base button-red", onClick: e => handleDeleteRule(e, ruleItem) }, "Delete"))))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "empty-state" },
11669
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("p", null, filterDefaultOnly
11670
+ ? 'No default rules. Mark a rule as default in the form to see it here.'
11671
+ : 'No rules created yet. Add your first rule to get started!')))),
11278
11672
  modalStatus && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-overlay" },
11279
11673
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "modal-content modal-content-large", onClick: e => e.stopPropagation() },
11280
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_RulesForm__WEBPACK_IMPORTED_MODULE_3__.RulesForm, { formData: formData, formError: formError, onInputChange: handleInputChange, onSubmit: handleSubmit, onClose: () => {
11674
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_RulesForm__WEBPACK_IMPORTED_MODULE_4__.RulesForm, { formData: formData, formError: formError, onInputChange: handleInputChange, onSubmit: handleSubmit, onClose: () => {
11281
11675
  setModalStatus(undefined);
11676
+ setEditingRuleName(null);
11282
11677
  setFormData({
11283
11678
  name: '',
11284
- description: ''
11679
+ description: '',
11680
+ isDefault: false
11285
11681
  });
11286
11682
  }, isEditing: modalStatus === 'edit rule' }))))));
11287
11683
  };
@@ -12936,16 +13332,6 @@ const MODEL_MAPPINGS = [
12936
13332
  speed: 'Fast',
12937
13333
  complexityHandling: 'Medium'
12938
13334
  },
12939
- {
12940
- displayName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.CLAUDE_SONNET_DISPLAY_NAME,
12941
- fullName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.CLAUDE_SONNET_MODEL_NAME,
12942
- type: 'smart',
12943
- goodFor: [...GOOD_FOR_SMART],
12944
- provider: 'Anthropic',
12945
- tokenLimit: '1M',
12946
- speed: 'Medium',
12947
- complexityHandling: 'High'
12948
- },
12949
13335
  {
12950
13336
  displayName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.GEMINI_3_FLASH_DISPLAY_NAME,
12951
13337
  fullName: _utils_models__WEBPACK_IMPORTED_MODULE_3__.GEMINI_3_FLASH_MODEL_NAME,
@@ -15049,6 +15435,7 @@ __webpack_require__.r(__webpack_exports__);
15049
15435
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
15050
15436
  /* harmony export */ addChartField: () => (/* binding */ addChartField),
15051
15437
  /* harmony export */ convertChartCode: () => (/* binding */ convertChartCode),
15438
+ /* harmony export */ deleteRule: () => (/* binding */ deleteRule),
15052
15439
  /* harmony export */ getChatHistoryThread: () => (/* binding */ getChatHistoryThread),
15053
15440
  /* harmony export */ getChatHistoryThreads: () => (/* binding */ getChatHistoryThreads),
15054
15441
  /* harmony export */ getDatabaseConnections: () => (/* binding */ getDatabaseConnections),
@@ -15114,10 +15501,14 @@ const updateSettings = async (settingsKey, settingsValue) => {
15114
15501
  RULES ENDPOINTS
15115
15502
 
15116
15503
  ************************************/
15117
- const setRule = async (ruleName, ruleContent) => {
15504
+ const setRule = async (ruleName, ruleContent, isDefault) => {
15505
+ const body = { content: ruleContent };
15506
+ if (isDefault !== undefined) {
15507
+ body.is_default = isDefault;
15508
+ }
15118
15509
  const resp = await (0,_utils__WEBPACK_IMPORTED_MODULE_0__.requestAPI)(`rules/${ruleName}`, {
15119
15510
  method: 'PUT',
15120
- body: JSON.stringify({ content: ruleContent }),
15511
+ body: JSON.stringify(body),
15121
15512
  });
15122
15513
  if (resp.error) {
15123
15514
  throw new Error(resp.error.message);
@@ -15125,19 +15516,31 @@ const setRule = async (ruleName, ruleContent) => {
15125
15516
  return resp.data || '';
15126
15517
  };
15127
15518
  const getRule = async (ruleName) => {
15128
- var _a;
15519
+ var _a, _b;
15129
15520
  const resp = await (0,_utils__WEBPACK_IMPORTED_MODULE_0__.requestAPI)(`rules/${ruleName}`);
15130
15521
  if (resp.error) {
15131
15522
  throw new Error(resp.error.message);
15132
15523
  }
15133
- return (_a = resp.data) === null || _a === void 0 ? void 0 : _a.content;
15524
+ return {
15525
+ content: (_a = resp.data) === null || _a === void 0 ? void 0 : _a.content,
15526
+ isDefault: Boolean((_b = resp.data) === null || _b === void 0 ? void 0 : _b.is_default)
15527
+ };
15134
15528
  };
15135
15529
  const getRules = async () => {
15136
15530
  const resp = await (0,_utils__WEBPACK_IMPORTED_MODULE_0__.requestAPI)(`rules`);
15137
15531
  if (resp.error) {
15138
15532
  throw new Error(resp.error.message);
15139
15533
  }
15140
- return resp.data || [];
15534
+ const data = resp.data || [];
15535
+ return data.map(r => ({ name: r.name, isDefault: Boolean(r.is_default) }));
15536
+ };
15537
+ const deleteRule = async (ruleName) => {
15538
+ const resp = await (0,_utils__WEBPACK_IMPORTED_MODULE_0__.requestAPI)(`rules/${ruleName}`, {
15539
+ method: 'DELETE',
15540
+ });
15541
+ if (resp.error) {
15542
+ throw new Error(resp.error.message);
15543
+ }
15141
15544
  };
15142
15545
  /************************************
15143
15546
 
@@ -16464,6 +16867,7 @@ const isErrorFixupMessage = (promptType, message, messageContent) => {
16464
16867
  __webpack_require__.r(__webpack_exports__);
16465
16868
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
16466
16869
  /* harmony export */ isValidFileName: () => (/* binding */ isValidFileName),
16870
+ /* harmony export */ slugifyRuleName: () => (/* binding */ slugifyRuleName),
16467
16871
  /* harmony export */ stripFileEnding: () => (/* binding */ stripFileEnding)
16468
16872
  /* harmony export */ });
16469
16873
  /*
@@ -16475,6 +16879,19 @@ __webpack_require__.r(__webpack_exports__);
16475
16879
  const isValidFileName = (fileName) => {
16476
16880
  return /^[a-zA-Z0-9_-]+$/.test(fileName);
16477
16881
  };
16882
+ /**
16883
+ * Converts a rule name to a valid file-name slug: spaces and other separators
16884
+ * become hyphens, invalid characters removed, multiple hyphens collapsed.
16885
+ */
16886
+ const slugifyRuleName = (name) => {
16887
+ return name
16888
+ .trim()
16889
+ .replace(/\s+/g, '-')
16890
+ .replace(/[^a-zA-Z0-9_-]+/g, '-')
16891
+ .replace(/-+/g, '-')
16892
+ .replace(/^-|-$/g, '')
16893
+ .toLowerCase();
16894
+ };
16478
16895
  const stripFileEnding = (rule) => {
16479
16896
  return rule.replace('.md', '');
16480
16897
  };
@@ -16756,7 +17173,6 @@ async function getAvailableModels() {
16756
17173
  return [
16757
17174
  GPT_4_1_MODEL_NAME,
16758
17175
  GPT_5_2_MODEL_NAME,
16759
- CLAUDE_SONNET_MODEL_NAME,
16760
17176
  CLAUDE_HAIKU_MODEL_NAME,
16761
17177
  GEMINI_3_FLASH_MODEL_NAME,
16762
17178
  GEMINI_3_PRO_MODEL_NAME,
@@ -18721,8 +19137,6 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
18721
19137
 
18722
19138
  .add-field-container {
18723
19139
  margin-top: 16px;
18724
- padding-top: 16px;
18725
- border-top: 1px solid #e0e0e0;
18726
19140
  }
18727
19141
 
18728
19142
  .add-field-button {
@@ -18741,7 +19155,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
18741
19155
  font-family: inherit;
18742
19156
  box-sizing: border-box;
18743
19157
  }
18744
- `, "",{"version":3,"sources":["webpack://./style/AddFieldButton.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,gBAAgB;IAChB,iBAAiB;IACjB,6BAA6B;AACjC;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,WAAW;IACX,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,sBAAsB;IACtB,kBAAkB;IAClB,iBAAiB;IACjB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;AAC1B","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.add-field-container {\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid #e0e0e0;\n}\n\n.add-field-button {\n width: 100%;\n}\n\n.add-field-dialog-textarea {\n width: 100%;\n padding: 8px;\n margin-top: 10px;\n font-size: 14px;\n border: 1px solid #ccc;\n border-radius: 4px;\n min-height: 100px;\n resize: vertical;\n font-family: inherit;\n box-sizing: border-box;\n}\n"],"sourceRoot":""}]);
19158
+ `, "",{"version":3,"sources":["webpack://./style/AddFieldButton.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,gBAAgB;AACpB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,WAAW;IACX,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,sBAAsB;IACtB,kBAAkB;IAClB,iBAAiB;IACjB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;AAC1B","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.add-field-container {\n margin-top: 16px;\n}\n\n.add-field-button {\n width: 100%;\n}\n\n.add-field-dialog-textarea {\n width: 100%;\n padding: 8px;\n margin-top: 10px;\n font-size: 14px;\n border: 1px solid #ccc;\n border-radius: 4px;\n min-height: 100px;\n resize: vertical;\n font-family: inherit;\n box-sizing: border-box;\n}\n"],"sourceRoot":""}]);
18745
19159
  // Exports
18746
19160
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
18747
19161
 
@@ -20527,6 +20941,63 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
20527
20941
  box-sizing: border-box;
20528
20942
  }
20529
20943
 
20944
+ .chart-wizard-number-slider-row {
20945
+ display: flex;
20946
+ align-items: center;
20947
+ gap: 12px;
20948
+ width: 100%;
20949
+ }
20950
+
20951
+ .chart-wizard-range-slider {
20952
+ flex: 1;
20953
+ min-width: 0;
20954
+ height: 6px;
20955
+ -webkit-appearance: none;
20956
+ appearance: none;
20957
+ background: var(--jp-border-color2);
20958
+ border-radius: 3px;
20959
+ outline: none;
20960
+ }
20961
+
20962
+ .chart-wizard-range-slider::-webkit-slider-thumb {
20963
+ -webkit-appearance: none;
20964
+ appearance: none;
20965
+ width: 16px;
20966
+ height: 16px;
20967
+ border-radius: 50%;
20968
+ background: var(--jp-brand-color1);
20969
+ cursor: pointer;
20970
+ border: none;
20971
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
20972
+ }
20973
+
20974
+ .chart-wizard-range-slider::-moz-range-thumb {
20975
+ width: 16px;
20976
+ height: 16px;
20977
+ border-radius: 50%;
20978
+ background: var(--jp-brand-color1);
20979
+ cursor: pointer;
20980
+ border: none;
20981
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
20982
+ }
20983
+
20984
+ .chart-wizard-range-slider:focus {
20985
+ outline: none;
20986
+ }
20987
+
20988
+ .chart-wizard-range-slider:focus::-webkit-slider-thumb {
20989
+ box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.25);
20990
+ }
20991
+
20992
+ .chart-wizard-range-slider:focus::-moz-range-thumb {
20993
+ box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.25);
20994
+ }
20995
+
20996
+ .chart-wizard-number-input-narrow {
20997
+ width: 72px;
20998
+ flex-shrink: 0;
20999
+ }
21000
+
20530
21001
  .chart-wizard-color-container {
20531
21002
  display: flex;
20532
21003
  gap: 8px;
@@ -20557,6 +21028,27 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
20557
21028
  min-height: 0;
20558
21029
  }
20559
21030
 
21031
+ .chart-wizard-export-section {
21032
+ margin-top: 24px;
21033
+ padding-top: 20px;
21034
+ border-top: 1px solid var(--jp-border-color2);
21035
+ }
21036
+
21037
+ .chart-wizard-export-format-row {
21038
+ margin-bottom: 12px;
21039
+ }
21040
+
21041
+ .chart-wizard-export-format-row .toggle-button-container {
21042
+ width: 100%;
21043
+ }
21044
+
21045
+ .chart-wizard-section-heading {
21046
+ font-size: 14px;
21047
+ font-weight: 600;
21048
+ margin: 0 0 12px 0;
21049
+ color: var(--jp-content-font-color1);
21050
+ }
21051
+
20560
21052
  .chart-wizard-empty-state,
20561
21053
  .chart-wizard-no-config {
20562
21054
  flex: 1;
@@ -20637,7 +21129,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
20637
21129
 
20638
21130
  .chart-wizard-warning-button:active {
20639
21131
  background-color: var(--yellow-300);
20640
- }`, "",{"version":3,"sources":["webpack://./style/ChartWizardWidget.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,aAAa;IACb,sBAAsB;IACtB,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,mBAAmB;IACnB,QAAQ;AACZ;;AAEA;IACI,mBAAmB;IACnB,mBAAmB;IACnB,8BAA8B;IAC9B,mBAAmB;IACnB,SAAS;AACb;;AAEA;IACI,oCAAoC;IACpC,eAAe;IACf,gBAAgB;IAChB,oBAAoB;AACxB;;AAEA;IACI,OAAO;IACP,SAAS;IACT,eAAe;AACnB;;AAEA;IACI,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,eAAe;IACf,cAAc;AAClB;;AAEA;IACI,kBAAkB;IAClB,UAAU;IACV,eAAe;IACf,QAAQ;IACR,SAAS;IACT,SAAS;AACb;;AAEA;IACI,kBAAkB;IAClB,qBAAqB;IACrB,WAAW;IACX,YAAY;IACZ,yCAAyC;IACzC,mBAAmB;IACnB,sCAAsC;IACtC,sBAAsB;AAC1B;;AAEA;IACI,WAAW;IACX,kBAAkB;IAClB,WAAW;IACX,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,uBAAuB;IACvB,kBAAkB;IAClB,+BAA+B;IAC/B,wCAAwC;AAC5C;;AAEA;IACI,wCAAwC;AAC5C;;AAEA;IACI,2BAA2B;AAC/B;;AAEA;IACI,6CAA6C;AACjD;;AAEA;IACI,yCAAyC;AAC7C;;AAEA;IACI,wCAAwC;AAC5C;;AAEA;;;;IAII,WAAW;IACX,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,QAAQ;IACR,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,OAAO;AACX;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,QAAQ;IACR,WAAW;AACf;;AAEA;IACI,OAAO;AACX;;AAEA;IACI,OAAO;IACP,aAAa;AACjB;;AAEA;;IAEI,OAAO;IACP,aAAa;IACb,sBAAsB;IACtB,uBAAuB;AAC3B;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,kBAAkB;IAClB,MAAM;IACN,OAAO;IACP,QAAQ;IACR,gFAAgF;IAChF,gBAAgB;IAChB,0CAA0C;IAC1C,aAAa;IACb,mBAAmB;IACnB,uBAAuB;IACvB,aAAa;IACb,mBAAmB;AACvB;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,WAAW;AACf;;AAEA;IACI,mCAAmC;IACnC,wBAAwB;IACxB,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;IACnB,eAAe;IACf,gBAAgB;IAChB,mCAAmC;IACnC,aAAa;IACb,sBAAsB;IACtB,SAAS;AACb;;AAEA;IACI,OAAO;AACX;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,mCAAmC;IACnC,wBAAwB;IACxB,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,sBAAsB;IACtB,sCAAsC;AAC1C;;AAEA;IACI,mCAAmC;AACvC;;AAEA;IACI,mCAAmC;AACvC","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.chart-wizard-widget {\n padding: 10px;\n height: 100%;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n}\n\n.chart-wizard-input-row {\n display: flex;\n flex-direction: column;\n margin-bottom: 15px;\n gap: 5px;\n}\n\n.chart-wizard-boolean-row {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.chart-wizard-input-label {\n color: var(--jp-content-font-color2);\n font-size: 12px;\n font-weight: 500;\n text-transform: none;\n}\n\n.chart-wizard-boolean-label {\n flex: 1;\n margin: 0;\n cursor: pointer;\n}\n\n.chart-wizard-toggle-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.chart-wizard-toggle-input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n width: 0;\n height: 0;\n margin: 0;\n}\n\n.chart-wizard-toggle-slider {\n position: relative;\n display: inline-block;\n width: 44px;\n height: 24px;\n background-color: var(--jp-border-color2);\n border-radius: 12px;\n transition: background-color 0.3s ease;\n box-sizing: border-box;\n}\n\n.chart-wizard-toggle-slider::before {\n content: '';\n position: absolute;\n width: 20px;\n height: 20px;\n left: 2px;\n top: 2px;\n background-color: white;\n border-radius: 50%;\n transition: transform 0.3s ease;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n\n.chart-wizard-toggle-input:checked + .chart-wizard-toggle-slider {\n background-color: var(--jp-brand-color1);\n}\n\n.chart-wizard-toggle-input:checked + .chart-wizard-toggle-slider::before {\n transform: translateX(20px);\n}\n\n.chart-wizard-toggle-input:focus + .chart-wizard-toggle-slider {\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);\n}\n\n.chart-wizard-toggle-input:hover + .chart-wizard-toggle-slider {\n background-color: var(--jp-border-color1);\n}\n\n.chart-wizard-toggle-input:checked:hover + .chart-wizard-toggle-slider {\n background-color: var(--jp-brand-color0);\n}\n\n.chart-wizard-number-input,\n.chart-wizard-text-input,\n.chart-wizard-color-input,\n.chart-wizard-tuple-input {\n width: 100%;\n box-sizing: border-box;\n}\n\n.chart-wizard-color-container {\n display: flex;\n gap: 8px;\n width: 100%;\n}\n\n.chart-wizard-color-picker {\n flex-shrink: 0;\n}\n\n.chart-wizard-color-input {\n flex: 1;\n}\n\n.chart-wizard-tuple-container {\n display: flex;\n align-items: center;\n gap: 5px;\n width: 100%;\n}\n\n.chart-wizard-tuple-input {\n flex: 1;\n}\n\n.chart-wizard-config-container {\n flex: 1;\n min-height: 0;\n}\n\n.chart-wizard-empty-state,\n.chart-wizard-no-config {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.chart-wizard-no-config p {\n text-align: center;\n}\n\n.chart-wizard-loading-dots {\n display: inline-block;\n min-width: 1.5em;\n text-align: left;\n}\n\n.chart-wizard-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n /* Height is set dynamically via inline style to cover full scrollable content */\n min-height: 100%;\n background-color: rgba(255, 255, 255, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n pointer-events: all;\n}\n\n.chart-wizard-overlay-text {\n font-size: 16px;\n font-weight: 500;\n color: #333;\n}\n\n.chart-wizard-warning {\n background-color: var(--yellow-100);\n color: var(--yellow-900);\n padding: 10px 12px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 13px;\n line-height: 1.4;\n border: 1px solid var(--yellow-300);\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.chart-wizard-warning-content {\n flex: 1;\n}\n\n.chart-wizard-warning strong {\n font-weight: 600;\n}\n\n.chart-wizard-warning-button {\n background-color: var(--yellow-600);\n color: var(--yellow-900);\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n align-self: flex-start;\n transition: background-color 0.2s ease;\n}\n\n.chart-wizard-warning-button:hover {\n background-color: var(--yellow-500);\n}\n\n.chart-wizard-warning-button:active {\n background-color: var(--yellow-300);\n}"],"sourceRoot":""}]);
21132
+ }`, "",{"version":3,"sources":["webpack://./style/ChartWizardWidget.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,aAAa;IACb,sBAAsB;IACtB,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,mBAAmB;IACnB,QAAQ;AACZ;;AAEA;IACI,mBAAmB;IACnB,mBAAmB;IACnB,8BAA8B;IAC9B,mBAAmB;IACnB,SAAS;AACb;;AAEA;IACI,oCAAoC;IACpC,eAAe;IACf,gBAAgB;IAChB,oBAAoB;AACxB;;AAEA;IACI,OAAO;IACP,SAAS;IACT,eAAe;AACnB;;AAEA;IACI,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,eAAe;IACf,cAAc;AAClB;;AAEA;IACI,kBAAkB;IAClB,UAAU;IACV,eAAe;IACf,QAAQ;IACR,SAAS;IACT,SAAS;AACb;;AAEA;IACI,kBAAkB;IAClB,qBAAqB;IACrB,WAAW;IACX,YAAY;IACZ,yCAAyC;IACzC,mBAAmB;IACnB,sCAAsC;IACtC,sBAAsB;AAC1B;;AAEA;IACI,WAAW;IACX,kBAAkB;IAClB,WAAW;IACX,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,uBAAuB;IACvB,kBAAkB;IAClB,+BAA+B;IAC/B,wCAAwC;AAC5C;;AAEA;IACI,wCAAwC;AAC5C;;AAEA;IACI,2BAA2B;AAC/B;;AAEA;IACI,6CAA6C;AACjD;;AAEA;IACI,yCAAyC;AAC7C;;AAEA;IACI,wCAAwC;AAC5C;;AAEA;;;;IAII,WAAW;IACX,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,SAAS;IACT,WAAW;AACf;;AAEA;IACI,OAAO;IACP,YAAY;IACZ,WAAW;IACX,wBAAwB;IACxB,gBAAgB;IAChB,mCAAmC;IACnC,kBAAkB;IAClB,aAAa;AACjB;;AAEA;IACI,wBAAwB;IACxB,gBAAgB;IAChB,WAAW;IACX,YAAY;IACZ,kBAAkB;IAClB,kCAAkC;IAClC,eAAe;IACf,YAAY;IACZ,wCAAwC;AAC5C;;AAEA;IACI,WAAW;IACX,YAAY;IACZ,kBAAkB;IAClB,kCAAkC;IAClC,eAAe;IACf,YAAY;IACZ,wCAAwC;AAC5C;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,8CAA8C;AAClD;;AAEA;IACI,8CAA8C;AAClD;;AAEA;IACI,WAAW;IACX,cAAc;AAClB;;AAEA;IACI,aAAa;IACb,QAAQ;IACR,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,OAAO;AACX;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,QAAQ;IACR,WAAW;AACf;;AAEA;IACI,OAAO;AACX;;AAEA;IACI,OAAO;IACP,aAAa;AACjB;;AAEA;IACI,gBAAgB;IAChB,iBAAiB;IACjB,6CAA6C;AACjD;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,kBAAkB;IAClB,oCAAoC;AACxC;;AAEA;;IAEI,OAAO;IACP,aAAa;IACb,sBAAsB;IACtB,uBAAuB;AAC3B;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,kBAAkB;IAClB,MAAM;IACN,OAAO;IACP,QAAQ;IACR,gFAAgF;IAChF,gBAAgB;IAChB,0CAA0C;IAC1C,aAAa;IACb,mBAAmB;IACnB,uBAAuB;IACvB,aAAa;IACb,mBAAmB;AACvB;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,WAAW;AACf;;AAEA;IACI,mCAAmC;IACnC,wBAAwB;IACxB,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;IACnB,eAAe;IACf,gBAAgB;IAChB,mCAAmC;IACnC,aAAa;IACb,sBAAsB;IACtB,SAAS;AACb;;AAEA;IACI,OAAO;AACX;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,mCAAmC;IACnC,wBAAwB;IACxB,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,sBAAsB;IACtB,sCAAsC;AAC1C;;AAEA;IACI,mCAAmC;AACvC;;AAEA;IACI,mCAAmC;AACvC","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.chart-wizard-widget {\n padding: 10px;\n height: 100%;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n}\n\n.chart-wizard-input-row {\n display: flex;\n flex-direction: column;\n margin-bottom: 15px;\n gap: 5px;\n}\n\n.chart-wizard-boolean-row {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.chart-wizard-input-label {\n color: var(--jp-content-font-color2);\n font-size: 12px;\n font-weight: 500;\n text-transform: none;\n}\n\n.chart-wizard-boolean-label {\n flex: 1;\n margin: 0;\n cursor: pointer;\n}\n\n.chart-wizard-toggle-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.chart-wizard-toggle-input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n width: 0;\n height: 0;\n margin: 0;\n}\n\n.chart-wizard-toggle-slider {\n position: relative;\n display: inline-block;\n width: 44px;\n height: 24px;\n background-color: var(--jp-border-color2);\n border-radius: 12px;\n transition: background-color 0.3s ease;\n box-sizing: border-box;\n}\n\n.chart-wizard-toggle-slider::before {\n content: '';\n position: absolute;\n width: 20px;\n height: 20px;\n left: 2px;\n top: 2px;\n background-color: white;\n border-radius: 50%;\n transition: transform 0.3s ease;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n\n.chart-wizard-toggle-input:checked + .chart-wizard-toggle-slider {\n background-color: var(--jp-brand-color1);\n}\n\n.chart-wizard-toggle-input:checked + .chart-wizard-toggle-slider::before {\n transform: translateX(20px);\n}\n\n.chart-wizard-toggle-input:focus + .chart-wizard-toggle-slider {\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);\n}\n\n.chart-wizard-toggle-input:hover + .chart-wizard-toggle-slider {\n background-color: var(--jp-border-color1);\n}\n\n.chart-wizard-toggle-input:checked:hover + .chart-wizard-toggle-slider {\n background-color: var(--jp-brand-color0);\n}\n\n.chart-wizard-number-input,\n.chart-wizard-text-input,\n.chart-wizard-color-input,\n.chart-wizard-tuple-input {\n width: 100%;\n box-sizing: border-box;\n}\n\n.chart-wizard-number-slider-row {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n}\n\n.chart-wizard-range-slider {\n flex: 1;\n min-width: 0;\n height: 6px;\n -webkit-appearance: none;\n appearance: none;\n background: var(--jp-border-color2);\n border-radius: 3px;\n outline: none;\n}\n\n.chart-wizard-range-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--jp-brand-color1);\n cursor: pointer;\n border: none;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.chart-wizard-range-slider::-moz-range-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--jp-brand-color1);\n cursor: pointer;\n border: none;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.chart-wizard-range-slider:focus {\n outline: none;\n}\n\n.chart-wizard-range-slider:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.25);\n}\n\n.chart-wizard-range-slider:focus::-moz-range-thumb {\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.25);\n}\n\n.chart-wizard-number-input-narrow {\n width: 72px;\n flex-shrink: 0;\n}\n\n.chart-wizard-color-container {\n display: flex;\n gap: 8px;\n width: 100%;\n}\n\n.chart-wizard-color-picker {\n flex-shrink: 0;\n}\n\n.chart-wizard-color-input {\n flex: 1;\n}\n\n.chart-wizard-tuple-container {\n display: flex;\n align-items: center;\n gap: 5px;\n width: 100%;\n}\n\n.chart-wizard-tuple-input {\n flex: 1;\n}\n\n.chart-wizard-config-container {\n flex: 1;\n min-height: 0;\n}\n\n.chart-wizard-export-section {\n margin-top: 24px;\n padding-top: 20px;\n border-top: 1px solid var(--jp-border-color2);\n}\n\n.chart-wizard-export-format-row {\n margin-bottom: 12px;\n}\n\n.chart-wizard-export-format-row .toggle-button-container {\n width: 100%;\n}\n\n.chart-wizard-section-heading {\n font-size: 14px;\n font-weight: 600;\n margin: 0 0 12px 0;\n color: var(--jp-content-font-color1);\n}\n\n.chart-wizard-empty-state,\n.chart-wizard-no-config {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n.chart-wizard-no-config p {\n text-align: center;\n}\n\n.chart-wizard-loading-dots {\n display: inline-block;\n min-width: 1.5em;\n text-align: left;\n}\n\n.chart-wizard-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n /* Height is set dynamically via inline style to cover full scrollable content */\n min-height: 100%;\n background-color: rgba(255, 255, 255, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n pointer-events: all;\n}\n\n.chart-wizard-overlay-text {\n font-size: 16px;\n font-weight: 500;\n color: #333;\n}\n\n.chart-wizard-warning {\n background-color: var(--yellow-100);\n color: var(--yellow-900);\n padding: 10px 12px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 13px;\n line-height: 1.4;\n border: 1px solid var(--yellow-300);\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.chart-wizard-warning-content {\n flex: 1;\n}\n\n.chart-wizard-warning strong {\n font-weight: 600;\n}\n\n.chart-wizard-warning-button {\n background-color: var(--yellow-600);\n color: var(--yellow-900);\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n align-self: flex-start;\n transition: background-color 0.2s ease;\n}\n\n.chart-wizard-warning-button:hover {\n background-color: var(--yellow-500);\n}\n\n.chart-wizard-warning-button:active {\n background-color: var(--yellow-300);\n}"],"sourceRoot":""}]);
20641
21133
  // Exports
20642
21134
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
20643
21135
 
@@ -23687,10 +24179,13 @@ __webpack_require__.r(__webpack_exports__);
23687
24179
  /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
23688
24180
  /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
23689
24181
  /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
24182
+ /* harmony import */ var _node_modules_css_loader_dist_cjs_js_base_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! -!../node_modules/css-loader/dist/cjs.js!./base.css */ "./node_modules/css-loader/dist/cjs.js!./style/base.css");
23690
24183
  // Imports
23691
24184
 
23692
24185
 
24186
+
23693
24187
  var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
24188
+ ___CSS_LOADER_EXPORT___.i(_node_modules_css_loader_dist_cjs_js_base_css__WEBPACK_IMPORTED_MODULE_2__["default"]);
23694
24189
  // Module
23695
24190
  ___CSS_LOADER_EXPORT___.push([module.id, `/*
23696
24191
  * Copyright (c) Saga Inc.
@@ -23709,7 +24204,8 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
23709
24204
  transition: border-color 0.2s;
23710
24205
  font-family: var(--jp-ui-font-family);
23711
24206
  resize: vertical;
23712
- min-height: 120px;
24207
+ min-height: 100px;
24208
+ max-height: 50vh;
23713
24209
  }
23714
24210
 
23715
24211
  .rules-form textarea:focus {
@@ -23725,29 +24221,96 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
23725
24221
  display: block;
23726
24222
  }
23727
24223
 
24224
+ .rules-form .form-group-checkbox {
24225
+ display: flex;
24226
+ align-items: center;
24227
+ gap: 8px;
24228
+ }
24229
+
24230
+ .rules-form .form-group-checkbox input[type="checkbox"] {
24231
+ width: 16px;
24232
+ height: 16px;
24233
+ cursor: pointer;
24234
+ }
24235
+
24236
+ .rules-form .form-group-checkbox label {
24237
+ margin: 0;
24238
+ cursor: pointer;
24239
+ }
24240
+
24241
+ .rules-form-footer {
24242
+ display: flex;
24243
+ align-items: center;
24244
+ justify-content: space-between;
24245
+ gap: 16px;
24246
+ margin-top: 24px;
24247
+ flex-wrap: wrap;
24248
+ }
24249
+
24250
+ .rules-form-footer-left {
24251
+ display: flex;
24252
+ align-items: center;
24253
+ gap: 8px;
24254
+ flex-wrap: wrap;
24255
+ }
24256
+
24257
+ .rules-form-footer-left .form-group-checkbox {
24258
+ margin: 0;
24259
+ }
24260
+
24261
+ .rules-form-footer-sub {
24262
+ margin: 0;
24263
+ color: var(--jp-ui-font-color2);
24264
+ font-size: 12px;
24265
+ }
24266
+
24267
+ .rules-form .form-actions {
24268
+ border-top: none;
24269
+ margin-top: 0;
24270
+ padding-top: 0;
24271
+ }
24272
+
24273
+ /* Rules list filter */
24274
+ .rules-list-filter {
24275
+ display: flex;
24276
+ gap: 8px;
24277
+ margin-top: 16px;
24278
+ margin-bottom: 12px;
24279
+ }
24280
+
24281
+ .rules-list-filter .button-base {
24282
+ padding: 6px 12px;
24283
+ font-size: 13px;
24284
+ }
24285
+
24286
+ .rules-list-filter .rules-list-filter-active {
24287
+ background-color: var(--jp-layout-color2);
24288
+ font-weight: 500;
24289
+ }
24290
+
23728
24291
  /* Rules List Styling */
23729
24292
  .rules-list {
23730
- margin-top: 24px;
24293
+ margin-top: 0;
23731
24294
  display: flex;
23732
24295
  flex-direction: column;
23733
- gap: 16px;
23734
24296
  }
23735
24297
 
23736
24298
  .rules-list .rule-item {
23737
24299
  display: flex;
23738
24300
  justify-content: space-between;
23739
24301
  align-items: center;
23740
- padding: 20px;
23741
- border: 1px solid var(--jp-border-color1);
23742
- border-radius: 8px;
23743
- background: var(--jp-layout-color0);
23744
- transition: border-color 0.2s, box-shadow 0.2s;
24302
+ padding: 12px 0;
24303
+ border-bottom: 1px solid var(--jp-border-color1);
24304
+ transition: color 0.15s ease;
23745
24305
  cursor: pointer;
23746
24306
  }
23747
24307
 
23748
- .rules-list .rule-item:hover {
23749
- border-color: var(--jp-border-color2);
23750
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
24308
+ .rules-list .rule-item:last-child {
24309
+ border-bottom: none;
24310
+ }
24311
+
24312
+ .rules-list .rule-item:hover .rule-name {
24313
+ color: var(--purple-600);
23751
24314
  }
23752
24315
 
23753
24316
  .rules-list .rule-content {
@@ -23756,18 +24319,25 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
23756
24319
  }
23757
24320
 
23758
24321
  .rules-list .rule-name {
23759
- margin: 0 0 8px 0;
24322
+ margin: 0;
23760
24323
  color: var(--jp-ui-font-color1);
23761
24324
  font-size: 14px;
23762
24325
  font-weight: 500;
23763
24326
  line-height: 1;
24327
+ display: flex;
24328
+ align-items: center;
24329
+ gap: 8px;
23764
24330
  }
23765
24331
 
23766
- .rules-list .rule-description {
23767
- margin: 0;
23768
- color: var(--jp-ui-font-color2);
23769
- font-size: 14px;
23770
- line-height: 1.5;
24332
+ .rules-list .rule-badge {
24333
+ display: inline-block;
24334
+ padding: 2px 6px;
24335
+ font-size: 11px;
24336
+ font-weight: 500;
24337
+ line-height: 1;
24338
+ border-radius: 3px;
24339
+ background-color: var(--purple-300);
24340
+ color: var(--purple-700);
23771
24341
  }
23772
24342
 
23773
24343
  .rules-list .rule-actions {
@@ -23786,7 +24356,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/*
23786
24356
  margin: 0;
23787
24357
  font-size: 16px;
23788
24358
  }
23789
- `, "",{"version":3,"sources":["webpack://./style/RulesForm.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAEF;IACI,WAAW;IACX,sBAAsB;IACtB,iBAAiB;IACjB,yCAAyC;IACzC,kBAAkB;IAClB,mCAAmC;IACnC,+BAA+B;IAC/B,eAAe;IACf,6BAA6B;IAC7B,qCAAqC;IACrC,gBAAgB;IAChB,iBAAiB;AACrB;;AAEA;IACI,aAAa;IACb,+BAA+B;IAC/B,6CAA6C;AACjD;;AAEA;IACI,+BAA+B;IAC/B,eAAe;IACf,kBAAkB;IAClB,cAAc;AAClB;;AAEA,uBAAuB;AACvB;IACI,gBAAgB;IAChB,aAAa;IACb,sBAAsB;IACtB,SAAS;AACb;;AAEA;IACI,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;IACnB,aAAa;IACb,yCAAyC;IACzC,kBAAkB;IAClB,mCAAmC;IACnC,8CAA8C;IAC9C,eAAe;AACnB;;AAEA;IACI,qCAAqC;IACrC,wCAAwC;AAC5C;;AAEA;IACI,OAAO;IACP,kBAAkB;AACtB;;AAEA;IACI,iBAAiB;IACjB,+BAA+B;IAC/B,eAAe;IACf,gBAAgB;IAChB,cAAc;AAClB;;AAEA;IACI,SAAS;IACT,+BAA+B;IAC/B,eAAe;IACf,gBAAgB;AACpB;;AAEA;IACI,aAAa;IACb,QAAQ;AACZ;;AAEA;IACI,kBAAkB;IAClB,kBAAkB;IAClB,+BAA+B;IAC/B,kBAAkB;AACtB;;AAEA;IACI,SAAS;IACT,eAAe;AACnB","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n.rules-form textarea {\n width: 100%;\n box-sizing: border-box;\n padding: 8px 12px;\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n background: var(--jp-layout-color0);\n color: var(--jp-ui-font-color1);\n font-size: 14px;\n transition: border-color 0.2s;\n font-family: var(--jp-ui-font-family);\n resize: vertical;\n min-height: 120px;\n}\n\n.rules-form textarea:focus {\n outline: none;\n border-color: var(--purple-500);\n box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.1);\n}\n\n.rules-form .form-group sub {\n color: var(--jp-ui-font-color2);\n margin-top: 4px;\n margin-bottom: 4px;\n display: block;\n}\n\n/* Rules List Styling */\n.rules-list {\n margin-top: 24px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.rules-list .rule-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20px;\n border: 1px solid var(--jp-border-color1);\n border-radius: 8px;\n background: var(--jp-layout-color0);\n transition: border-color 0.2s, box-shadow 0.2s;\n cursor: pointer;\n}\n\n.rules-list .rule-item:hover {\n border-color: var(--jp-border-color2);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.rules-list .rule-content {\n flex: 1;\n margin-right: 16px;\n}\n\n.rules-list .rule-name {\n margin: 0 0 8px 0;\n color: var(--jp-ui-font-color1);\n font-size: 14px;\n font-weight: 500;\n line-height: 1;\n}\n\n.rules-list .rule-description {\n margin: 0;\n color: var(--jp-ui-font-color2);\n font-size: 14px;\n line-height: 1.5;\n}\n\n.rules-list .rule-actions {\n display: flex;\n gap: 8px;\n}\n\n.rules-list .empty-state {\n text-align: center;\n padding: 40px 20px;\n color: var(--jp-ui-font-color2);\n font-style: italic;\n}\n\n.rules-list .empty-state p {\n margin: 0;\n font-size: 16px;\n}\n"],"sourceRoot":""}]);
24359
+ `, "",{"version":3,"sources":["webpack://./style/RulesForm.css"],"names":[],"mappings":"AAAA;;;EAGE;;AAIF;IACI,WAAW;IACX,sBAAsB;IACtB,iBAAiB;IACjB,yCAAyC;IACzC,kBAAkB;IAClB,mCAAmC;IACnC,+BAA+B;IAC/B,eAAe;IACf,6BAA6B;IAC7B,qCAAqC;IACrC,gBAAgB;IAChB,iBAAiB;IACjB,gBAAgB;AACpB;;AAEA;IACI,aAAa;IACb,+BAA+B;IAC/B,6CAA6C;AACjD;;AAEA;IACI,+BAA+B;IAC/B,eAAe;IACf,kBAAkB;IAClB,cAAc;AAClB;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,QAAQ;AACZ;;AAEA;IACI,WAAW;IACX,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,SAAS;IACT,eAAe;AACnB;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,8BAA8B;IAC9B,SAAS;IACT,gBAAgB;IAChB,eAAe;AACnB;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,QAAQ;IACR,eAAe;AACnB;;AAEA;IACI,SAAS;AACb;;AAEA;IACI,SAAS;IACT,+BAA+B;IAC/B,eAAe;AACnB;;AAEA;IACI,gBAAgB;IAChB,aAAa;IACb,cAAc;AAClB;;AAEA,sBAAsB;AACtB;IACI,aAAa;IACb,QAAQ;IACR,gBAAgB;IAChB,mBAAmB;AACvB;;AAEA;IACI,iBAAiB;IACjB,eAAe;AACnB;;AAEA;IACI,yCAAyC;IACzC,gBAAgB;AACpB;;AAEA,uBAAuB;AACvB;IACI,aAAa;IACb,aAAa;IACb,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;IACnB,eAAe;IACf,gDAAgD;IAChD,4BAA4B;IAC5B,eAAe;AACnB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,wBAAwB;AAC5B;;AAEA;IACI,OAAO;IACP,kBAAkB;AACtB;;AAEA;IACI,SAAS;IACT,+BAA+B;IAC/B,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,mBAAmB;IACnB,QAAQ;AACZ;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,kBAAkB;IAClB,mCAAmC;IACnC,wBAAwB;AAC5B;;AAEA;IACI,aAAa;IACb,QAAQ;AACZ;;AAEA;IACI,kBAAkB;IAClB,kBAAkB;IAClB,+BAA+B;IAC/B,kBAAkB;AACtB;;AAEA;IACI,SAAS;IACT,eAAe;AACnB","sourcesContent":["/*\n * Copyright (c) Saga Inc.\n * Distributed under the terms of the GNU Affero General Public License v3.0 License.\n */\n\n@import url('base.css');\n\n.rules-form textarea {\n width: 100%;\n box-sizing: border-box;\n padding: 8px 12px;\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n background: var(--jp-layout-color0);\n color: var(--jp-ui-font-color1);\n font-size: 14px;\n transition: border-color 0.2s;\n font-family: var(--jp-ui-font-family);\n resize: vertical;\n min-height: 100px;\n max-height: 50vh;\n}\n\n.rules-form textarea:focus {\n outline: none;\n border-color: var(--purple-500);\n box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.1);\n}\n\n.rules-form .form-group sub {\n color: var(--jp-ui-font-color2);\n margin-top: 4px;\n margin-bottom: 4px;\n display: block;\n}\n\n.rules-form .form-group-checkbox {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rules-form .form-group-checkbox input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.rules-form .form-group-checkbox label {\n margin: 0;\n cursor: pointer;\n}\n\n.rules-form-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-top: 24px;\n flex-wrap: wrap;\n}\n\n.rules-form-footer-left {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.rules-form-footer-left .form-group-checkbox {\n margin: 0;\n}\n\n.rules-form-footer-sub {\n margin: 0;\n color: var(--jp-ui-font-color2);\n font-size: 12px;\n}\n\n.rules-form .form-actions {\n border-top: none;\n margin-top: 0;\n padding-top: 0;\n}\n\n/* Rules list filter */\n.rules-list-filter {\n display: flex;\n gap: 8px;\n margin-top: 16px;\n margin-bottom: 12px;\n}\n\n.rules-list-filter .button-base {\n padding: 6px 12px;\n font-size: 13px;\n}\n\n.rules-list-filter .rules-list-filter-active {\n background-color: var(--jp-layout-color2);\n font-weight: 500;\n}\n\n/* Rules List Styling */\n.rules-list {\n margin-top: 0;\n display: flex;\n flex-direction: column;\n}\n\n.rules-list .rule-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 0;\n border-bottom: 1px solid var(--jp-border-color1);\n transition: color 0.15s ease;\n cursor: pointer;\n}\n\n.rules-list .rule-item:last-child {\n border-bottom: none;\n}\n\n.rules-list .rule-item:hover .rule-name {\n color: var(--purple-600);\n}\n\n.rules-list .rule-content {\n flex: 1;\n margin-right: 16px;\n}\n\n.rules-list .rule-name {\n margin: 0;\n color: var(--jp-ui-font-color1);\n font-size: 14px;\n font-weight: 500;\n line-height: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rules-list .rule-badge {\n display: inline-block;\n padding: 2px 6px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n border-radius: 3px;\n background-color: var(--purple-300);\n color: var(--purple-700);\n}\n\n.rules-list .rule-actions {\n display: flex;\n gap: 8px;\n}\n\n.rules-list .empty-state {\n text-align: center;\n padding: 40px 20px;\n color: var(--jp-ui-font-color2);\n font-style: italic;\n}\n\n.rules-list .empty-state p {\n margin: 0;\n font-size: 16px;\n}\n"],"sourceRoot":""}]);
23790
24360
  // Exports
23791
24361
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
23792
24362
 
@@ -27609,4 +28179,4 @@ var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js
27609
28179
  /***/ })
27610
28180
 
27611
28181
  }]);
27612
- //# sourceMappingURL=lib_index_js.44c109c7be36fb884d25.js.map
28182
+ //# sourceMappingURL=lib_index_js.dccfa541c464ee0e5cd4.js.map