@genexus/genexus-ide-ui 0.0.76 → 0.0.78

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 (52) hide show
  1. package/dist/cjs/ch-shortcuts_2.cjs.entry.js +230 -0
  2. package/dist/cjs/genexus-ide-ui.cjs.js +1 -1
  3. package/dist/cjs/gx-ide-ai-assistant.cjs.entry.js +16 -2
  4. package/dist/cjs/gx-ide-ai-message.cjs.entry.js +1 -1
  5. package/dist/cjs/gx-ide-new-environment.cjs.entry.js +7 -2
  6. package/dist/cjs/gxg-form-text.cjs.entry.js +3 -5
  7. package/dist/cjs/gxg-test.cjs.entry.js +7 -1
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/collection/collection-manifest.json +1 -0
  10. package/dist/collection/components/ai-assistant/ai-assistant.css +1 -0
  11. package/dist/collection/components/ai-assistant/ai-assistant.js +15 -1
  12. package/dist/collection/components/ai-assistant/ai-message.css +3 -6
  13. package/dist/collection/components/new-environment/gx-ide-assets/new-environment/shortcuts.json +21 -0
  14. package/dist/collection/components/new-environment/new-environment.js +8 -3
  15. package/dist/components/ai-message.js +1 -1
  16. package/dist/components/ch-shortcuts.js +1 -236
  17. package/dist/{esm/ch-shortcuts.entry.js → components/ch-shortcuts2.js} +40 -9
  18. package/dist/components/form-text.js +3 -5
  19. package/dist/components/gx-ide-ai-assistant.js +16 -2
  20. package/dist/components/gx-ide-new-environment.js +58 -29
  21. package/dist/components/gxg-shortcuts.js +6 -0
  22. package/dist/components/gxg-test.js +32 -2
  23. package/dist/components/index.js +1 -0
  24. package/dist/components/shortcuts.js +58 -0
  25. package/dist/esm/ch-shortcuts_2.entry.js +225 -0
  26. package/dist/esm/genexus-ide-ui.js +1 -1
  27. package/dist/esm/gx-ide-ai-assistant.entry.js +16 -2
  28. package/dist/esm/gx-ide-ai-message.entry.js +1 -1
  29. package/dist/esm/gx-ide-new-environment.entry.js +8 -3
  30. package/dist/esm/gxg-form-text.entry.js +3 -5
  31. package/dist/esm/gxg-test.entry.js +7 -1
  32. package/dist/esm/loader.js +1 -1
  33. package/dist/genexus-ide-ui/genexus-ide-ui.esm.js +1 -1
  34. package/dist/genexus-ide-ui/gx-ide-assets/new-environment/shortcuts.json +21 -0
  35. package/dist/genexus-ide-ui/p-0967fafc.entry.js +1 -0
  36. package/dist/genexus-ide-ui/p-0b6d53e1.entry.js +1 -0
  37. package/dist/genexus-ide-ui/p-2d77e2a3.entry.js +1 -0
  38. package/dist/genexus-ide-ui/p-4bceda48.entry.js +1 -0
  39. package/dist/genexus-ide-ui/p-ab4e48bc.entry.js +1 -0
  40. package/dist/genexus-ide-ui/p-e4e7e070.entry.js +1 -0
  41. package/dist/node_modules/@genexus/gemini/dist/collection/components/form-text/form-text.css +1 -1
  42. package/dist/node_modules/@genexus/gemini/dist/collection/components/shortcuts/shortcuts.css +366 -0
  43. package/dist/types/components/ai-assistant/ai-assistant.d.ts +3 -0
  44. package/dist/types/components/new-environment/new-environment.d.ts +2 -0
  45. package/package.json +3 -3
  46. package/dist/cjs/ch-shortcuts.cjs.entry.js +0 -211
  47. package/dist/genexus-ide-ui/p-0f3c3a5e.entry.js +0 -1
  48. package/dist/genexus-ide-ui/p-2e7d1eef.entry.js +0 -1
  49. package/dist/genexus-ide-ui/p-4a8187c1.entry.js +0 -1
  50. package/dist/genexus-ide-ui/p-72fad9dd.entry.js +0 -1
  51. package/dist/genexus-ide-ui/p-9f4e169e.entry.js +0 -1
  52. package/dist/genexus-ide-ui/p-f13a59cc.entry.js +0 -1
@@ -1028,7 +1028,7 @@ STYLE
1028
1028
  /*****************************************************
1029
1029
  INPUT TYPE FILE
1030
1030
  *****************************************************/
1031
- :host(.file) .input {
1031
+ :host(.file) .form-element--readonly {
1032
1032
  user-select: none;
1033
1033
  cursor: pointer;
1034
1034
  }
@@ -0,0 +1,366 @@
1
+ :root {
2
+ --ui-animaton-speed: 0.2s;
3
+ }
4
+
5
+ /*ALIGNMENT*/
6
+ /*Ellipsis*/
7
+ /*****************************************************
8
+ TYPOGRAPHY
9
+ *****************************************************/
10
+ /*Title 01 (Positive)*/
11
+ .gxg-title-01 {
12
+ font-family: var(--font-family-primary);
13
+ font-weight: var(--font-weight-bold);
14
+ font-size: var(--font-size-md);
15
+ letter-spacing: var(--letter-spacing-md);
16
+ color: var(--color-on-background);
17
+ text-align: start;
18
+ line-height: 1.455em;
19
+ }
20
+
21
+ /*Title 01 (Negative)*/
22
+ .gxg-title-01--negative {
23
+ font-family: var(--font-family-primary);
24
+ font-weight: var(--font-weight-bold);
25
+ font-size: var(--font-size-md);
26
+ letter-spacing: var(--letter-spacing-md);
27
+ color: var(--color-on-background);
28
+ text-align: start;
29
+ line-height: 1.455em;
30
+ color: var(--color-on-primary);
31
+ }
32
+
33
+ /*Title 02 (Positive)*/
34
+ .gxg-title-02 {
35
+ font-family: var(--font-family-primary);
36
+ font-weight: var(--font-weight-bold);
37
+ font-size: var(--font-size-sm);
38
+ letter-spacing: var(--letter-spacing-sm);
39
+ color: var(--color-on-background);
40
+ text-align: start;
41
+ text-transform: uppercase;
42
+ line-height: 1.556em;
43
+ }
44
+
45
+ .gxg-title-02--negative {
46
+ font-family: var(--font-family-primary);
47
+ font-weight: var(--font-weight-bold);
48
+ font-size: var(--font-size-sm);
49
+ letter-spacing: var(--letter-spacing-sm);
50
+ color: var(--color-on-background);
51
+ text-align: start;
52
+ text-transform: uppercase;
53
+ line-height: 1.556em;
54
+ color: var(--color-on-primary);
55
+ }
56
+
57
+ /*Title 03*/
58
+ .gxg-title-03 {
59
+ font-family: var(--font-family-primary);
60
+ font-weight: var(--font-weight-regular);
61
+ font-size: var(--font-size-xs);
62
+ letter-spacing: var(--letter-spacing-sm);
63
+ color: var(--color-on-background);
64
+ text-align: start;
65
+ text-transform: uppercase;
66
+ line-height: 1.556em;
67
+ }
68
+
69
+ .gxg-title-03--negative {
70
+ font-family: var(--font-family-primary);
71
+ font-weight: var(--font-weight-regular);
72
+ font-size: var(--font-size-xs);
73
+ letter-spacing: var(--letter-spacing-sm);
74
+ color: var(--color-on-background);
75
+ text-align: start;
76
+ text-transform: uppercase;
77
+ line-height: 1.556em;
78
+ color: var(--color-on-primary);
79
+ }
80
+
81
+ /*Title 04*/
82
+ .gxg-title-04 {
83
+ font-family: var(--font-family-primary);
84
+ font-weight: var(--font-weight-semibold);
85
+ font-size: var(--font-size-md);
86
+ letter-spacing: var(--letter-spacing-md);
87
+ color: var(--color-on-background);
88
+ text-align: start;
89
+ line-height: 1.455em;
90
+ }
91
+
92
+ .gxg-title-04--negative {
93
+ font-family: var(--font-family-primary);
94
+ font-weight: var(--font-weight-semibold);
95
+ font-size: var(--font-size-md);
96
+ letter-spacing: var(--letter-spacing-md);
97
+ color: var(--color-on-background);
98
+ text-align: start;
99
+ line-height: 1.455em;
100
+ color: var(--color-on-primary);
101
+ }
102
+
103
+ /*Title 05*/
104
+ .gxg-title-05 {
105
+ font-family: var(--font-family-primary);
106
+ font-weight: var(--font-weight-semibold);
107
+ font-size: var(--font-size-sm);
108
+ letter-spacing: var(--letter-spacing-sm);
109
+ color: var(--color-on-background);
110
+ text-align: start;
111
+ line-height: 1.556em;
112
+ }
113
+
114
+ .gxg-title-05--negative {
115
+ font-family: var(--font-family-primary);
116
+ font-weight: var(--font-weight-semibold);
117
+ font-size: var(--font-size-sm);
118
+ letter-spacing: var(--letter-spacing-sm);
119
+ color: var(--color-on-background);
120
+ text-align: start;
121
+ line-height: 1.556em;
122
+ color: var(--color-on-primary);
123
+ }
124
+
125
+ /*Text*/
126
+ .gxg-text {
127
+ font-family: var(--font-family-primary);
128
+ font-weight: var(--font-weight-regular);
129
+ font-size: var(--font-size-sm);
130
+ letter-spacing: var(--letter-spacing-xs);
131
+ color: var(--color-on-background);
132
+ text-align: start;
133
+ line-height: 1.455em;
134
+ }
135
+
136
+ .gxg-text--negative {
137
+ font-family: var(--font-family-primary);
138
+ font-weight: var(--font-weight-regular);
139
+ font-size: var(--font-size-sm);
140
+ letter-spacing: var(--letter-spacing-xs);
141
+ color: var(--color-on-background);
142
+ text-align: start;
143
+ line-height: 1.455em;
144
+ color: var(--color-on-primary);
145
+ }
146
+
147
+ .gxg-text--gray {
148
+ font-family: var(--font-family-primary);
149
+ font-weight: var(--font-weight-regular);
150
+ font-size: var(--font-size-sm);
151
+ letter-spacing: var(--letter-spacing-xs);
152
+ color: var(--color-on-background);
153
+ text-align: start;
154
+ line-height: 1.455em;
155
+ color: var(--gray-05);
156
+ }
157
+
158
+ /*Quote*/
159
+ .gxg-quote {
160
+ font-family: var(--font-family-primary);
161
+ font-weight: var(--font-weight-regular);
162
+ font-size: var(--font-size-sm);
163
+ letter-spacing: var(--letter-spacing-xs);
164
+ color: var(--color-on-background);
165
+ text-align: start;
166
+ line-height: 1.455em;
167
+ font-style: italic;
168
+ }
169
+
170
+ .gxg-quote--negative {
171
+ color: var(--color-on-primary);
172
+ }
173
+
174
+ /*Link*/
175
+ .gxg-link {
176
+ font-family: var(--font-family-primary);
177
+ font-weight: var(--font-weight-regular);
178
+ font-size: var(--font-size-sm);
179
+ letter-spacing: var(--letter-spacing-xs);
180
+ color: var(--color-on-background);
181
+ text-align: start;
182
+ line-height: 1.455em;
183
+ color: var(--color-primary);
184
+ text-decoration: underline;
185
+ cursor: pointer;
186
+ display: inline-block;
187
+ }
188
+ .gxg-link:hover {
189
+ color: var(--color-primary-hover);
190
+ }
191
+ .gxg-link:active {
192
+ color: var(--color-primary-active);
193
+ }
194
+
195
+ .gxg-link-gray {
196
+ font-family: var(--font-family-primary);
197
+ font-weight: var(--font-weight-regular);
198
+ font-size: var(--font-size-sm);
199
+ letter-spacing: var(--letter-spacing-xs);
200
+ color: var(--color-on-background);
201
+ text-align: start;
202
+ line-height: 1.455em;
203
+ color: var(--color-primary);
204
+ text-decoration: underline;
205
+ cursor: pointer;
206
+ display: inline-block;
207
+ color: var(--gray-04);
208
+ }
209
+ .gxg-link-gray:hover {
210
+ font-family: var(--font-family-primary);
211
+ font-weight: var(--font-weight-regular);
212
+ font-size: var(--font-size-sm);
213
+ letter-spacing: var(--letter-spacing-xs);
214
+ color: var(--color-on-background);
215
+ text-align: start;
216
+ line-height: 1.455em;
217
+ color: var(--color-primary);
218
+ text-decoration: underline;
219
+ cursor: pointer;
220
+ display: inline-block;
221
+ color: var(--gray-04);
222
+ color: var(--gray-06);
223
+ }
224
+
225
+ /*Alerts*/
226
+ .gxg-alert-error {
227
+ font-family: var(--font-family-primary);
228
+ font-weight: var(--font-weight-regular);
229
+ font-size: var(--font-size-sm);
230
+ letter-spacing: var(--letter-spacing-xs);
231
+ color: var(--color-on-background);
232
+ text-align: start;
233
+ line-height: 1.455em;
234
+ color: var(--color-error-dark);
235
+ display: inline-block;
236
+ }
237
+
238
+ .gxg-alert-warning {
239
+ font-family: var(--font-family-primary);
240
+ font-weight: var(--font-weight-regular);
241
+ font-size: var(--font-size-sm);
242
+ letter-spacing: var(--letter-spacing-xs);
243
+ color: var(--color-on-background);
244
+ text-align: start;
245
+ line-height: 1.455em;
246
+ color: var(--color-warning-dark);
247
+ display: inline-block;
248
+ }
249
+
250
+ .gxg-alert-success {
251
+ font-family: var(--font-family-primary);
252
+ font-weight: var(--font-weight-regular);
253
+ font-size: var(--font-size-sm);
254
+ letter-spacing: var(--letter-spacing-xs);
255
+ color: var(--color-on-background);
256
+ text-align: start;
257
+ line-height: 1.455em;
258
+ color: var(--color-success-dark);
259
+ display: inline-block;
260
+ }
261
+
262
+ /*Tab*/
263
+ .gxg-tab--disabled {
264
+ color: var(--color-primary-disabled);
265
+ pointer-events: none;
266
+ }
267
+ .gxg-tab--disabled[disabled] {
268
+ color: var(--color-primary-disabled);
269
+ pointer-events: none;
270
+ }
271
+
272
+ /*Label*/
273
+ .gxg-label {
274
+ font-family: var(--font-family-primary) !important;
275
+ font-weight: var(--font-weight-semibold);
276
+ font-size: var(--font-size-sm) !important;
277
+ letter-spacing: var(--letter-spacing-xs);
278
+ color: var(--color-primary-enabled);
279
+ text-align: center;
280
+ line-height: 1.455em;
281
+ }
282
+ .gxg-label:hover {
283
+ color: var(--color-primary-hover);
284
+ }
285
+ .gxg-label:focus {
286
+ color: var(--color-primary-active);
287
+ }
288
+ .gxg-label:active {
289
+ color: var(--color-primary-active);
290
+ }
291
+ .gxg-label[disabled] {
292
+ color: var(--color-primary-disabled);
293
+ }
294
+
295
+ .gxg-label--negative {
296
+ color: var(--color-on-primary);
297
+ }
298
+ .gxg-label--negative[disabled] {
299
+ color: var(--color-on-disabled);
300
+ }
301
+
302
+ /*****************************************************
303
+ GXG-BUTTON and GXG-BUTTON-GROUP COMMON STYLES
304
+ *****************************************************/
305
+ .gxg-button-styles {
306
+ font-family: var(--font-family-primary) !important;
307
+ font-weight: var(--font-weight-semibold);
308
+ font-size: var(--font-size-sm) !important;
309
+ letter-spacing: var(--letter-spacing-xs);
310
+ color: var(--color-primary-enabled);
311
+ text-align: center;
312
+ line-height: 1.455em;
313
+ }
314
+
315
+ /*****************************************************
316
+ FORM ELEMENTS
317
+ *****************************************************/
318
+ .gxg-scrollbar {
319
+ /* Track */
320
+ /* Handle */
321
+ /* Handle on hover */
322
+ cursor: initial;
323
+ }
324
+ .gxg-scrollbar::-webkit-scrollbar {
325
+ width: var(--gxg-scrollbar-width, 6px);
326
+ height: var(--gxg-scrollbar-width, 6px);
327
+ }
328
+ .gxg-scrollbar::-webkit-scrollbar-track {
329
+ background-color: var(--gxg-scrollbar-track-background, --gray-02);
330
+ border-radius: var(--gxg-scrollbar-track-border-radius, 10px);
331
+ }
332
+ .gxg-scrollbar::-webkit-scrollbar-thumb {
333
+ background-color: var(--gxg-scrollbar-track-thumb-background, --gray-05);
334
+ border-radius: var(--gxg-scrollbar-track-thumb-radius, 10px);
335
+ border: var(--gxg-scrollbar-track-thumb-border);
336
+ background-clip: padding-box;
337
+ }
338
+ .gxg-scrollbar::-webkit-scrollbar-thumb:hover {
339
+ background-color: var(--gxg-scrollbar-track-thumb-hover-background, --gray-04);
340
+ }
341
+
342
+ :host {
343
+ display: block;
344
+ }
345
+
346
+ ch-shortcuts::part(tooltip) {
347
+ font-family: monospace;
348
+ background-color: var(--gray-06);
349
+ color: var(--gray-01);
350
+ padding: var(--spacing-comp-00) var(--spacing-comp-01);
351
+ font-size: var(--font-size-sm);
352
+ border-radius: var(--border-radius-sm);
353
+ position: relative;
354
+ top: -2.5px;
355
+ right: -2px;
356
+ }
357
+
358
+ ch-shortcuts::part(element) {
359
+ outline: var(--border-width-md) solid var(--gxg-border-color--focused);
360
+ outline-offset: -2px;
361
+ outline-color: var(--gray-06);
362
+ }
363
+
364
+ :host([show-tooltip]) ch-shortcuts::part(tooltip) {
365
+ opacity: 1;
366
+ }
@@ -7,10 +7,12 @@ export declare class GxIdeTemplate {
7
7
  private renderedFirstTime;
8
8
  private lastUserMessageHeight;
9
9
  private setFocus;
10
+ private scrollToBottomFlag;
10
11
  el: HTMLGxIdeAiAssistantElement;
11
12
  private textAreaEl;
12
13
  private textareaShadowPart;
13
14
  private filterEl;
15
+ private messagesWrapperEl;
14
16
  /**
15
17
  * Flag used to hide the shortcuts
16
18
  */
@@ -88,6 +90,7 @@ export declare class GxIdeTemplate {
88
90
  private toggleFilterHandler;
89
91
  private promptFocusHandler;
90
92
  private promptBlurHandler;
93
+ private scrollToBottom;
91
94
  render(): any;
92
95
  }
93
96
  export type AiStatus = "indeterminate" | "success" | "error";
@@ -12,6 +12,7 @@ export declare class GxIdeNewEnvironment {
12
12
  private selectedLanguageId;
13
13
  private selectedDataStoreId;
14
14
  private envNameModifiedByUser;
15
+ private shortcutsSrc;
15
16
  el: HTMLGxIdeNewEnvironmentElement;
16
17
  private environmentNameEl;
17
18
  private languageEl;
@@ -99,6 +100,7 @@ export declare class GxIdeNewEnvironment {
99
100
  private updateFrontEnds;
100
101
  private updateEnvironmentName;
101
102
  private evaluateSingleRuntimeIcon;
103
+ private keyDownHandler;
102
104
  private renderTabBasic;
103
105
  private renderTabAdvanced;
104
106
  render(): any;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genexus/genexus-ide-ui",
3
3
  "license": "Apache-2.0",
4
- "version": "0.0.76",
4
+ "version": "0.0.78",
5
5
  "description": "GeneXus IDE UI components",
6
6
  "main": "dist/index.cjs.js",
7
7
  "module": "dist/index.js",
@@ -36,10 +36,10 @@
36
36
  "@types/react": "^18.2.8"
37
37
  },
38
38
  "peerDependencies": {
39
- "@genexus/gemini": "*0.2.41"
39
+ "@genexus/gemini": "*0.2.44"
40
40
  },
41
41
  "devDependencies": {
42
- "@genexus/gemini": "*0.2.41",
42
+ "@genexus/gemini": "*0.2.44",
43
43
  "@stencil-community/eslint-plugin": "^0.5.0",
44
44
  "@stencil/core": "^2.17.0",
45
45
  "@stencil/sass": "^2.0.1",
@@ -1,211 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- const index = require('./index-f9bb1815.js');
6
- const helpers = require('./helpers-291cb1cb.js');
7
-
8
- const SHORTCUTS = new Map();
9
- let LATEST_SHORTCUT;
10
- function loadShortcuts(name, root, shortcuts) {
11
- shortcuts.forEach(shortcut => {
12
- const keyShortcuts = parseKeyShortcuts(shortcut.keyShortcuts);
13
- keyShortcuts.forEach(keyShortcut => {
14
- SHORTCUTS.set(normalize(keyShortcut.ctrl, keyShortcut.alt, keyShortcut.shift, keyShortcut.meta, keyShortcut.key), {
15
- name,
16
- root,
17
- shortcut
18
- });
19
- });
20
- });
21
- addListener();
22
- }
23
- function unloadShortcuts(name) {
24
- const removeKeyShortcuts = [];
25
- SHORTCUTS.forEach((shortcutMap, key) => {
26
- if (shortcutMap.name === name) {
27
- removeKeyShortcuts.push(key);
28
- }
29
- });
30
- removeKeyShortcuts.forEach(key => SHORTCUTS.delete(key));
31
- removeListener();
32
- }
33
- function getShortcuts() {
34
- return Array.from(SHORTCUTS.values())
35
- .filter(shortcutMap => {
36
- var _a;
37
- return !((_a = shortcutMap.shortcut.conditions) === null || _a === void 0 ? void 0 : _a.focusInclude);
38
- })
39
- .map(shortcutMap => ({
40
- element: querySelectorPlus(shortcutMap.shortcut.selector, shortcutMap.root),
41
- keyShortcuts: shortcutMap.shortcut.keyShortcuts,
42
- legendPosition: shortcutMap.shortcut.legendPosition
43
- }));
44
- }
45
- function addListener() {
46
- if (SHORTCUTS.size > 0) {
47
- window.addEventListener("keydown", keydownHandler, { capture: true });
48
- }
49
- }
50
- function removeListener() {
51
- if (SHORTCUTS.size === 0) {
52
- window.removeEventListener("keydown", keydownHandler, { capture: true });
53
- }
54
- }
55
- function keydownHandler(eventInfo) {
56
- var _a;
57
- if (!eventInfo.repeat ||
58
- (eventInfo.repeat && ((_a = LATEST_SHORTCUT === null || LATEST_SHORTCUT === void 0 ? void 0 : LATEST_SHORTCUT.shortcut.conditions) === null || _a === void 0 ? void 0 : _a.allowRepeat))) {
59
- LATEST_SHORTCUT = triggerShortcut(eventInfo);
60
- }
61
- }
62
- function triggerShortcut(eventInfo) {
63
- const shortcutMap = SHORTCUTS.get(normalize(eventInfo.ctrlKey, eventInfo.altKey, eventInfo.shiftKey, eventInfo.metaKey, eventInfo.key));
64
- if (shortcutMap && conditions(shortcutMap)) {
65
- const element = querySelectorPlus(shortcutMap.shortcut.selector, shortcutMap.root);
66
- if (element) {
67
- switch (shortcutMap.shortcut.action) {
68
- case "click":
69
- element.dispatchEvent(new Event("click"));
70
- break;
71
- default:
72
- element.focus();
73
- }
74
- if (shortcutMap.shortcut.preventDefault !== false) {
75
- eventInfo.preventDefault();
76
- }
77
- }
78
- }
79
- return shortcutMap;
80
- }
81
- function parseKeyShortcuts(value = "") {
82
- return value.split(" ").map(item => {
83
- return item.split("+").reduce((keyShortcut, key) => {
84
- switch (key.toLowerCase()) {
85
- case "ctrl":
86
- keyShortcut.ctrl = true;
87
- break;
88
- case "alt":
89
- keyShortcut.alt = true;
90
- break;
91
- case "shift":
92
- keyShortcut.shift = true;
93
- break;
94
- case "meta":
95
- keyShortcut.meta = true;
96
- break;
97
- default:
98
- keyShortcut.key = key;
99
- }
100
- return keyShortcut;
101
- }, {
102
- ctrl: false,
103
- alt: false,
104
- shift: false,
105
- meta: false,
106
- key: ""
107
- });
108
- });
109
- }
110
- function normalize(ctrl, alt, shift, meta, key) {
111
- return [
112
- ctrl ? "Ctrl" : null,
113
- alt ? "Alt" : null,
114
- shift ? "Shift" : null,
115
- meta ? "Meta" : null,
116
- key ? key.charAt(0).toUpperCase() + key.slice(1) : null
117
- ]
118
- .filter(element => {
119
- return element !== null;
120
- })
121
- .join("+");
122
- }
123
- function conditions(shortcutMap) {
124
- var _a, _b, _c, _d;
125
- const focus = helpers.focusComposedPath();
126
- if ((_a = shortcutMap.shortcut.conditions) === null || _a === void 0 ? void 0 : _a.focusInclude) {
127
- return Array.from(shortcutMap.root.querySelectorAll((_b = shortcutMap.shortcut.conditions) === null || _b === void 0 ? void 0 : _b.focusInclude)).some((el) => focus.includes(el));
128
- }
129
- if ((_c = shortcutMap.shortcut.conditions) === null || _c === void 0 ? void 0 : _c.focusExclude) {
130
- return !Array.from(shortcutMap.root.querySelectorAll((_d = shortcutMap.shortcut.conditions) === null || _d === void 0 ? void 0 : _d.focusExclude)).some((el) => focus.includes(el));
131
- }
132
- return true;
133
- }
134
- function querySelectorPlus(selector, root) {
135
- const querySelectorDeep = (element, parts) => {
136
- const shadow = element.shadowRoot;
137
- const partList = parts.split(" ");
138
- const partElement = shadow.querySelector(partList.map(partName => `[part~="${partName}"]`).join(""));
139
- if (partElement) {
140
- return partElement;
141
- }
142
- const exportPartElement = shadow.querySelector(partList.map(partName => `[exportparts*="${partName}"]`).join(""));
143
- if (exportPartElement) {
144
- const exportPartList = [];
145
- const exportparts = exportPartElement.getAttribute("exportparts");
146
- partList.forEach(partItem => {
147
- const exportPartName = exportparts.match(`(?:([\\w-]+):)?(${partItem})`)[1];
148
- if (exportPartName) {
149
- exportPartList.push(exportPartName);
150
- }
151
- });
152
- if (partList.length === exportPartList.length) {
153
- return querySelectorDeep(exportPartElement, exportPartList.join(" "));
154
- }
155
- }
156
- return null;
157
- };
158
- if (selector.includes("::part")) {
159
- const selectorItems = selector.match("(.*)::part\\(([^)]+)\\)");
160
- const entity = selectorItems[1];
161
- const partName = selectorItems[2];
162
- return querySelectorDeep(root.querySelector(entity), partName);
163
- }
164
- else {
165
- return root.querySelector(selector);
166
- }
167
- }
168
-
169
- const chShortcutsCss = ":host{display:contents}";
170
-
171
- const ChShortcuts = class {
172
- constructor(hostRef) {
173
- index.registerInstance(this, hostRef);
174
- this.showShortcuts = false;
175
- this.showKey = "F10";
176
- this.windowClosedHandler = () => {
177
- this.showShortcuts = false;
178
- };
179
- }
180
- componentDidLoad() {
181
- if (this.src) {
182
- fetch(this.src).then(response => {
183
- if (response.ok) {
184
- response.json().then(json => {
185
- const root = this.el.getRootNode();
186
- loadShortcuts(this.src, root, json);
187
- });
188
- }
189
- });
190
- }
191
- }
192
- disconnectedCallback() {
193
- unloadShortcuts(this.src);
194
- }
195
- windowKeyDownHandler(eventInfo) {
196
- if (eventInfo.key === this.showKey) {
197
- this.showShortcuts = !this.showShortcuts;
198
- eventInfo.preventDefault();
199
- }
200
- }
201
- renderShortcuts() {
202
- return getShortcuts().map(shortcut => (index.h("ch-window", { container: shortcut.element, modal: false, hidden: false, closeOnEscape: true, closeOnOutsideClick: true, xAlign: "outside-end", yAlign: "inside-start", onWindowClosed: this.windowClosedHandler, exportparts: "mask:element" }, index.h("span", { part: "tooltip" }, shortcut.keyShortcuts))));
203
- }
204
- render() {
205
- return index.h(index.Host, null, this.showShortcuts && this.renderShortcuts());
206
- }
207
- get el() { return index.getElement(this); }
208
- };
209
- ChShortcuts.style = chShortcutsCss;
210
-
211
- exports.ch_shortcuts = ChShortcuts;
@@ -1 +0,0 @@
1
- import{r,c as t,h as a,H as i,g as o}from"./p-0906fb46.js";import{L as e}from"./p-26957490.js";const s=class{constructor(i){r(this,i),this.componentDidRenderFirstTime=t(this,"componentDidRenderFirstTime",7),this.renderedFirstTime=!1,this.setFocus=!0,this.evaluateAiInProgress=()=>{var r;this.aIInProgress=(null===(r=this.messages)||void 0===r?void 0:r.length)>0&&"assistant-in-progress"===this.messages[this.messages.length-1].type},this.evaluateAiStatus=()=>{var r;this.assistantStatus=0!==(null===(r=this.messages)||void 0===r?void 0:r.length)?"assistant-in-progress"===this.messages[this.messages.length-1].type||"user"===this.messages[this.messages.length-1].type?"indeterminate":"assistant-error"===this.messages[this.messages.length-1].type?"error":"success":"indeterminate"},this.renderMessage=(r,t)=>{if(r.text.length>0)return a("gx-ide-ai-message",{message:r.text,messageType:r.type,hidden:r.hidden,filterValue:this.filterValue,key:`${t.toString()}-${r.type}`,translations:this._componentLocale.aiMessage})},this.textAreaInputHandler=()=>{this.userHasTyped=!0,this.showFilter=!1,this.filterEl.value="",this.filterValue=""},this.promptEnterHandler=async r=>{const t=r.detail.replace(/\s+/g," ");this.textAreaEl.value=t,setTimeout((()=>{this.lastUserMessageHeight=this.textAreaEl.offsetHeight}),0),this.textAreaEl.value="",this.addMessage({type:"user",text:t}),this.userMessageCallback&&!this.aIInProgress&&(this.aIInProgress=!0,this.userMessageCallback(t).then((()=>{this.aIInProgress=!1})))},this.filterMessagesHandler=r=>{this.filterValue=r.detail.toLowerCase();const t=[...this.messages];t.forEach((r=>{r.hidden=!r.text.toLowerCase().includes(this.filterValue)})),this.messages=t},this.clearMessages=()=>{this.messages=[],this.textAreaEl.focus()},this.attachShortcuts=()=>{var r;if((null===(r=this.focusShortcuts)||void 0===r?void 0:r.length)>0){const r=this.focusShortcuts.findIndex((r=>"ctrl"===r.toLocaleLowerCase())),t=this.focusShortcuts.findIndex((r=>"shift"===r.toLocaleLowerCase())),a=this.focusShortcuts.findIndex((r=>"cmd"===r.toLocaleLowerCase())),i=this.focusShortcuts.find((r=>"ctrl"!==r.toLocaleLowerCase()&&"shift"!==r.toLocaleLowerCase()&&"cmd"!==r.toLocaleLowerCase())).toLowerCase();document.addEventListener("keydown",(o=>{(o.key===i&&-1!==r&&o.ctrlKey||o.key===i&&-1!==t&&o.shiftKey||o.key===i&&-1!==a&&o.metaKey)&&(this.textAreaEl.focus(),this.userHasTyped=!0)}))}},this.promptArrowUpHandler=()=>{var r;this.userHasTyped=!0;const t=null===(r=this.messages)||void 0===r?void 0:r.find((r=>"user"===r.type));t&&(this.lastUserMessageHeight&&(this.textareaShadowPart.style.height=`${this.lastUserMessageHeight}px`),this.textAreaEl.value=t.text)},this.toggleFilterHandler=()=>{this.showFilter=!this.showFilter,this.showFilter&&this.filterEl.focus()},this.promptFocusHandler=()=>{this.promptHasFocus=!0},this.promptBlurHandler=()=>{this.promptHasFocus=!1},this.userHasTyped=!1,this.aIInProgress=!1,this.showFilter=!1,this.promptHasFocus=!1,this.filterValue=void 0,this.messages=[],this.promptMaxHeight="128px",this.assistantStatus="indeterminate",this.focusShortcuts=void 0,this.userMessageCallback=void 0,this.promptValue=void 0,this.filter=!0}watchAIInProgressHandler(r){r||(this.setFocus=!0)}watchMessagesHandler(){this.evaluateAiInProgress(),this.evaluateAiStatus()}async componentWillLoad(){this._componentLocale=await e.getComponentStrings(this.el),this.evaluateAiInProgress(),this.evaluateAiStatus(),this.attachShortcuts()}componentDidLoad(){this.textareaShadowPart=this.textAreaEl.shadowRoot.querySelector("textarea")}componentDidRender(){this.renderedFirstTime||(this.componentDidRenderFirstTime.emit(this._componentLocale.componentName),this.renderedFirstTime=!0),this.setFocus&&setTimeout((()=>{this.textAreaEl.focus(),this.setFocus=!1}),0)}async clear(){this.messages=[]}async addMessage(r){var t;if((null===(t=r.text)||void 0===t?void 0:t.length)>0){const t=[...this.messages];(null==t?void 0:t.length)>0&&"assistant-in-progress"===t[t.length-1].type&&t.pop(),t.push(r),this.messages=t}}render(){var r,t;return a(i,{class:{[`assistant--${this.assistantStatus}`]:!0,"assistant--in-progress":this.aIInProgress}},a("div",{class:"gx-ide-main-wrapper"},a("header",{class:"header"},a("div",{class:"header__first-row"},a("gxg-title",{type:"title-02"},this._componentLocale.componentName),a("div",{class:"header__actions-wrapper"},this.filter?a("gxg-button",{class:"header__filter-button",type:"tertiary",icon:"menus/find",onClick:this.toggleFilterHandler,disabled:0===this.messages.length}):null,a("gxg-button",{class:"header__clear-button",type:"tertiary",icon:"bpm/delete",onClick:this.clearMessages,disabled:0===this.messages.length}))),this.filter?a("div",{class:{"header__second-row":!0,"header__second-row--visible":this.showFilter}},a("div",{class:"filter-inner-wrapper"},a("gxg-form-text",{class:"header__filter",onInput:this.filterMessagesHandler,ref:r=>this.filterEl=r}))):null),a("div",{class:{"messages-wrapper":!0}},(null===(r=this.messages)||void 0===r?void 0:r.length)?a("ol",{class:{messages:!0}},this.messages.map(((r,t)=>this.renderMessage(r,t)))):null),a("div",{class:{prompt:!0}},a("gxg-form-textarea",{ai:!0,class:"prompt__textarea",value:this.promptValue,maxHeight:this.promptMaxHeight,placeholder:this.aIInProgress?this._componentLocale.processingQueryPlaceholder:this._componentLocale.promptPlaceholder,onInput:this.textAreaInputHandler,onEnter:this.promptEnterHandler,onArrowUpPressed:this.promptArrowUpHandler,onBlur:this.promptBlurHandler,onFocus:this.promptFocusHandler,disabled:this.aIInProgress,ref:r=>this.textAreaEl=r}),!this.userHasTyped&&!this.aIInProgress&&!this.promptHasFocus&&(null===(t=this.focusShortcuts)||void 0===t?void 0:t.length)>0?a("div",{class:{prompt__shortcuts:!0}},this.focusShortcuts.map(((r,t)=>t<=2?a("span",{class:"prompt__shortcut"},r):null))):null)))}static get assetsDirs(){return["gx-ide-assets/ai-assistant"]}get el(){return o(this)}static get watchers(){return{aIInProgress:["watchAIInProgressHandler"],messages:["watchMessagesHandler"]}}};s.style=".gxi-hidden{display:none !important}.gxi-full-height{height:100%}.gxi-overflow-auto{overflow:auto}.gxi-display-flex{display:flex}.align-start{display:flex;align-items:start}.align-center{display:flex;align-items:center}.align-end{display:flex;align-items:end}.overflow-auto{overflow:auto}.grid{display:grid;grid-row-gap:var(--gx-ide-grid-row-gap);grid-column-gap:var(--gx-ide-grid-column-gap);grid-template-rows:auto}ch-grid-cell{display:flex}ch-grid{overflow:auto;height:100%}ch-grid-column{z-index:99;border-bottom:1px solid var(--gray-01)}ch-grid-column:first-child{padding-inline-start:var(--gxg-container--padding) !important}ch-grid-column:last-child{padding-inline-end:var(--gxg-container--padding) !important}ch-grid-cell{--spacing-comp-02:var(--gxg-container--padding)}gxg-tabs{box-shadow:none}:host(.gx-ide-component){box-shadow:var(--box-shadow-01) !important;height:100% !important;display:flex !important;flex-direction:column !important}:host(:focus-within) gx-ide-top-bar::part(wrapper){background-color:var(--color-secondary-enabled)}.gx-ide-main-wrapper{color:var(--gx-ide-component-text-color);font-weight:var(--font-weight-regular);font-size:var(--font-size-lg);font-family:var(--font-family-primary);line-height:1.6em;height:100%;background-color:var(--gx-ide-component-background-color);display:flex;flex-direction:column;flex-grow:1;box-sizing:border-box}.gx-ide-main{flex-grow:1;overflow-y:auto;}.gx-ide-main::-webkit-scrollbar{width:6px;height:6px}.gx-ide-main::-webkit-scrollbar-track{background-color:var(--gray-02);border-radius:10px}.gx-ide-main::-webkit-scrollbar-thumb{background:var(--gray-05);border-radius:10px}.gx-ide-main::-webkit-scrollbar-thumb:hover{background:var(--gray-04);cursor:pointer}.gx-ide-main .gxg-scroll{display:block;overflow-y:auto;padding-inline-end:2px}.gx-ide-overflow{overflow-y:auto;}.gx-ide-overflow::-webkit-scrollbar{width:6px;height:6px}.gx-ide-overflow::-webkit-scrollbar-track{background-color:var(--gray-02);border-radius:10px}.gx-ide-overflow::-webkit-scrollbar-thumb{background:var(--gray-05);border-radius:10px}.gx-ide-overflow::-webkit-scrollbar-thumb:hover{background:var(--gray-04);cursor:pointer}.gx-ide-overflow .gxg-scroll{display:block;overflow-y:auto;padding-inline-end:2px}.tree-container{display:flex;height:100%;width:100%;box-sizing:border-box}:root{--ui-animaton-speed:0.2s}.gxg-title-01{font-family:var(--font-family-primary);font-weight:var(--font-weight-bold);font-size:var(--font-size-md);letter-spacing:var(--letter-spacing-md);color:var(--color-on-background);text-align:start;line-height:1.455em}.gxg-title-01--negative{font-family:var(--font-family-primary);font-weight:var(--font-weight-bold);font-size:var(--font-size-md);letter-spacing:var(--letter-spacing-md);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-on-primary)}.gxg-title-02{font-family:var(--font-family-primary);font-weight:var(--font-weight-bold);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-sm);color:var(--color-on-background);text-align:start;text-transform:uppercase;line-height:1.556em}.gxg-title-02--negative{font-family:var(--font-family-primary);font-weight:var(--font-weight-bold);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-sm);color:var(--color-on-background);text-align:start;text-transform:uppercase;line-height:1.556em;color:var(--color-on-primary)}.gxg-title-03{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-xs);letter-spacing:var(--letter-spacing-sm);color:var(--color-on-background);text-align:start;text-transform:uppercase;line-height:1.556em}.gxg-title-03--negative{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-xs);letter-spacing:var(--letter-spacing-sm);color:var(--color-on-background);text-align:start;text-transform:uppercase;line-height:1.556em;color:var(--color-on-primary)}.gxg-title-04{font-family:var(--font-family-primary);font-weight:var(--font-weight-semibold);font-size:var(--font-size-md);letter-spacing:var(--letter-spacing-md);color:var(--color-on-background);text-align:start;line-height:1.455em}.gxg-title-04--negative{font-family:var(--font-family-primary);font-weight:var(--font-weight-semibold);font-size:var(--font-size-md);letter-spacing:var(--letter-spacing-md);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-on-primary)}.gxg-title-05{font-family:var(--font-family-primary);font-weight:var(--font-weight-semibold);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-sm);color:var(--color-on-background);text-align:start;line-height:1.556em}.gxg-title-05--negative{font-family:var(--font-family-primary);font-weight:var(--font-weight-semibold);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-sm);color:var(--color-on-background);text-align:start;line-height:1.556em;color:var(--color-on-primary)}.gxg-text{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em}.gxg-text--negative{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-on-primary)}.gxg-text--gray{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--gray-05)}.gxg-quote{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;font-style:italic}.gxg-quote--negative{color:var(--color-on-primary)}.gxg-link{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-primary);text-decoration:underline;cursor:pointer;display:inline-block}.gxg-link:hover{color:var(--color-primary-hover)}.gxg-link:active{color:var(--color-primary-active)}.gxg-link-gray{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-primary);text-decoration:underline;cursor:pointer;display:inline-block;color:var(--gray-04)}.gxg-link-gray:hover{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-primary);text-decoration:underline;cursor:pointer;display:inline-block;color:var(--gray-04);color:var(--gray-06)}.gxg-alert-error{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-error-dark);display:inline-block}.gxg-alert-warning{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-warning-dark);display:inline-block}.gxg-alert-success{font-family:var(--font-family-primary);font-weight:var(--font-weight-regular);font-size:var(--font-size-sm);letter-spacing:var(--letter-spacing-xs);color:var(--color-on-background);text-align:start;line-height:1.455em;color:var(--color-success-dark);display:inline-block}.gxg-tab--disabled{color:var(--color-primary-disabled);pointer-events:none}.gxg-tab--disabled[disabled]{color:var(--color-primary-disabled);pointer-events:none}.gxg-label{font-family:var(--font-family-primary) !important;font-weight:var(--font-weight-semibold);font-size:var(--font-size-sm) !important;letter-spacing:var(--letter-spacing-xs);color:var(--color-primary-enabled);text-align:center;line-height:1.455em}.gxg-label:hover{color:var(--color-primary-hover)}.gxg-label:focus{color:var(--color-primary-active)}.gxg-label:active{color:var(--color-primary-active)}.gxg-label[disabled]{color:var(--color-primary-disabled)}.gxg-label--negative{color:var(--color-on-primary)}.gxg-label--negative[disabled]{color:var(--color-on-disabled)}.gxg-button-styles{font-family:var(--font-family-primary) !important;font-weight:var(--font-weight-semibold);font-size:var(--font-size-sm) !important;letter-spacing:var(--letter-spacing-xs);color:var(--color-primary-enabled);text-align:center;line-height:1.455em}.gxg-scrollbar{cursor:initial}.gxg-scrollbar::-webkit-scrollbar{width:var(--gxg-scrollbar-width, 6px);height:var(--gxg-scrollbar-width, 6px)}.gxg-scrollbar::-webkit-scrollbar-track{background-color:var(--gxg-scrollbar-track-background, --gray-02);border-radius:var(--gxg-scrollbar-track-border-radius, 10px)}.gxg-scrollbar::-webkit-scrollbar-thumb{background-color:var(--gxg-scrollbar-track-thumb-background, --gray-05);border-radius:var(--gxg-scrollbar-track-thumb-radius, 10px);border:var(--gxg-scrollbar-track-thumb-border);background-clip:padding-box}.gxg-scrollbar::-webkit-scrollbar-thumb:hover{background-color:var(--gxg-scrollbar-track-thumb-hover-background, --gray-04)}:host{--ai-dot-bg-color:var(--color-success-dark);display:block;height:100%;--assistant-bg-color:var(--gray-11);flex-basis:286px;flex-shrink:0;height:100%;overflow-y:auto}.gx-ide-main-wrapper{padding:106px 10px 52px 10px;background-color:var(--gray-10);height:100%;display:grid;grid-template-rows:auto 1fr auto;gap:var(--spacing-comp-03)}.header{border-block-start:1px solid var(--gray-13);padding-block-start:var(--spacing-comp-03);display:flex;flex-direction:column}.header__actions-wrapper{display:flex;gap:var(--spacing-comp-02);margin-inline-start:auto}.header__first-row{display:flex;gap:var(--spacing-comp-02);align-items:center;justify-content:space-between}.header__filter{margin-block-start:var(--spacing-comp-02)}.header__second-row{transition:100ms grid-template-rows;display:grid;grid-template-rows:0fr}.header__second-row--visible{grid-template-rows:1fr}.header .filter-inner-wrapper{overflow:hidden}.messages-wrapper{position:relative;overflow:auto;display:flex;flex-direction:column;cursor:initial}.messages-wrapper::-webkit-scrollbar{width:var(--gxg-scrollbar-width, 6px);height:var(--gxg-scrollbar-width, 6px)}.messages-wrapper::-webkit-scrollbar-track{background-color:var(--gxg-scrollbar-track-background, --gray-02);border-radius:var(--gxg-scrollbar-track-border-radius, 10px)}.messages-wrapper::-webkit-scrollbar-thumb{background-color:var(--gxg-scrollbar-track-thumb-background, --gray-05);border-radius:var(--gxg-scrollbar-track-thumb-radius, 10px);border:var(--gxg-scrollbar-track-thumb-border);background-clip:padding-box}.messages-wrapper::-webkit-scrollbar-thumb:hover{background-color:var(--gxg-scrollbar-track-thumb-hover-background, --gray-04)}.messages{display:flex;flex-direction:column;list-style-type:none;padding:0;margin:0}.prompt{position:relative;margin-top:auto}.prompt__textarea::part(textarea-wrapper){border:none;background-color:var(--assistant-bg-color)}.prompt__shortcuts{position:absolute;display:flex;align-items:center;gap:var(--spacing-comp-01);padding-right:var(--spacing-comp-02);right:0;top:0;height:100%}.prompt__shortcut{padding:var(--spacing-comp-00) var(--spacing-comp-02);background-color:var(--gray-00);border-radius:var(--border-width-md)}";export{s as gx_ide_ai_assistant}