@magmonium/one 0.2.99 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/docs/en/app-release.md +55 -0
- package/assets/i18n/en.json +30 -0
- package/assets/icons/bold.svg +4 -0
- package/assets/icons/heading.svg +6 -0
- package/assets/icons/italic.svg +5 -0
- package/assets/icons/link.svg +4 -0
- package/assets/icons/list.svg +8 -0
- package/assets/icons/quote.svg +4 -0
- package/assets/icons/sparkles.svg +5 -0
- package/assets/icons/strikethrough.svg +5 -0
- package/assets/icons/svg.json +10 -0
- package/assets/icons/table.svg +6 -0
- package/assets/icons/wand.svg +6 -0
- package/assets/index.json +1 -1
- package/fesm2022/{magmonium-one-image-editor-BWrlxgdY.mjs → magmonium-one-image-editor-DKFMr1hF.mjs} +2 -2
- package/fesm2022/{magmonium-one-image-editor-BWrlxgdY.mjs.map → magmonium-one-image-editor-DKFMr1hF.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-magmonium-one-C_-B9_Hl.mjs → magmonium-one-magmonium-one-YIfvzI6x.mjs} +1007 -20
- package/fesm2022/magmonium-one-magmonium-one-YIfvzI6x.mjs.map +1 -0
- package/fesm2022/{magmonium-one-otp-CEFYwChx.mjs → magmonium-one-otp-CoTAftI5.mjs} +2 -2
- package/fesm2022/{magmonium-one-otp-CEFYwChx.mjs.map → magmonium-one-otp-CoTAftI5.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-password-BSd9P128.mjs → magmonium-one-password-BDnu6JUW.mjs} +2 -2
- package/fesm2022/{magmonium-one-password-BSd9P128.mjs.map → magmonium-one-password-BDnu6JUW.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-toggle-DQuHT48L.mjs → magmonium-one-toggle-QVCyppFj.mjs} +2 -2
- package/fesm2022/{magmonium-one-toggle-DQuHT48L.mjs.map → magmonium-one-toggle-QVCyppFj.mjs.map} +1 -1
- package/fesm2022/magmonium-one.mjs +1 -1
- package/package.json +6 -5
- package/types/magmonium-one.d.ts +325 -4
- package/fesm2022/magmonium-one-magmonium-one-C_-B9_Hl.mjs.map +0 -1
|
@@ -12,6 +12,7 @@ import * as i1 from '@angular/common';
|
|
|
12
12
|
import { APP_BASE_HREF, Location, NgOptimizedImage, IMAGE_LOADER, NgTemplateOutlet, CommonModule, NgComponentOutlet, DecimalPipe, NgClass, DatePipe, NgStyle } from '@angular/common';
|
|
13
13
|
import { FormField, email, required, validate, minLength, maxLength, min, max, apply, form } from '@angular/forms/signals';
|
|
14
14
|
import { createCustomElement } from '@angular/elements';
|
|
15
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
15
16
|
import { bootstrapApplication, DomSanitizer } from '@angular/platform-browser';
|
|
16
17
|
import { provideAnimations } from '@angular/platform-browser/animations';
|
|
17
18
|
|
|
@@ -35,6 +36,8 @@ var Assets;
|
|
|
35
36
|
Assets["SVG"] = "svg";
|
|
36
37
|
Assets["PNG"] = "png";
|
|
37
38
|
Assets["CSS"] = "css";
|
|
39
|
+
/** A DocAsset — markdown, copied verbatim rather than compiled. */
|
|
40
|
+
Assets["MD"] = "md";
|
|
38
41
|
})(Assets || (Assets = {}));
|
|
39
42
|
|
|
40
43
|
// Single source for the layout primitives' asset subFolder — each
|
|
@@ -223,8 +226,11 @@ class HttpService {
|
|
|
223
226
|
params: this.toParams(params),
|
|
224
227
|
});
|
|
225
228
|
}
|
|
226
|
-
deleteWithBody(domain, path, body, version) {
|
|
227
|
-
return this.http.delete(this.createUrl(domain, path, version), {
|
|
229
|
+
deleteWithBody(domain, path, body, version, params) {
|
|
230
|
+
return this.http.delete(this.createUrl(domain, path, version), {
|
|
231
|
+
body,
|
|
232
|
+
params: this.toParams(params),
|
|
233
|
+
});
|
|
228
234
|
}
|
|
229
235
|
setUrl(url) {
|
|
230
236
|
this.url = url;
|
|
@@ -253,6 +259,10 @@ class HttpService {
|
|
|
253
259
|
blob(url) {
|
|
254
260
|
return this.http.get(url, { responseType: 'blob' });
|
|
255
261
|
}
|
|
262
|
+
/** A whole url read as text — what a document fetched from a Remote needs. */
|
|
263
|
+
text(url) {
|
|
264
|
+
return this.http.get(url, { responseType: 'text' });
|
|
265
|
+
}
|
|
256
266
|
wc(link, filePath) {
|
|
257
267
|
if (isLocalhost) {
|
|
258
268
|
return this.http.get(`/local-dist/m-${link}-wc/${filePath.join('/')}`);
|
|
@@ -357,6 +367,7 @@ class HttpService {
|
|
|
357
367
|
switch (assets) {
|
|
358
368
|
case Assets.SVG:
|
|
359
369
|
case Assets.CSS:
|
|
370
|
+
case Assets.MD:
|
|
360
371
|
responseType = 'text';
|
|
361
372
|
break;
|
|
362
373
|
case Assets.PNG:
|
|
@@ -5039,6 +5050,7 @@ const SHARED_ICONS = [
|
|
|
5039
5050
|
'arrow-up',
|
|
5040
5051
|
'arrow_back',
|
|
5041
5052
|
'bell',
|
|
5053
|
+
'bold',
|
|
5042
5054
|
'books',
|
|
5043
5055
|
'calendar',
|
|
5044
5056
|
'calendar-open',
|
|
@@ -5079,6 +5091,7 @@ const SHARED_ICONS = [
|
|
|
5079
5091
|
'folder',
|
|
5080
5092
|
'games',
|
|
5081
5093
|
'gear',
|
|
5094
|
+
'heading',
|
|
5082
5095
|
'heart',
|
|
5083
5096
|
'heart_filled',
|
|
5084
5097
|
'help',
|
|
@@ -5087,9 +5100,12 @@ const SHARED_ICONS = [
|
|
|
5087
5100
|
'install',
|
|
5088
5101
|
'instrument',
|
|
5089
5102
|
'investments',
|
|
5103
|
+
'italic',
|
|
5090
5104
|
'language',
|
|
5091
5105
|
'layers',
|
|
5092
5106
|
'layouts',
|
|
5107
|
+
'link',
|
|
5108
|
+
'list',
|
|
5093
5109
|
'loading',
|
|
5094
5110
|
'loading-bars',
|
|
5095
5111
|
'loading-dots',
|
|
@@ -5113,6 +5129,7 @@ const SHARED_ICONS = [
|
|
|
5113
5129
|
'play',
|
|
5114
5130
|
'plus',
|
|
5115
5131
|
'posts',
|
|
5132
|
+
'quote',
|
|
5116
5133
|
'redo',
|
|
5117
5134
|
'reload',
|
|
5118
5135
|
'reset',
|
|
@@ -5126,11 +5143,14 @@ const SHARED_ICONS = [
|
|
|
5126
5143
|
'smartphone',
|
|
5127
5144
|
'sort-alpha-asc',
|
|
5128
5145
|
'sort-alpha-desc',
|
|
5146
|
+
'sparkles',
|
|
5129
5147
|
'square',
|
|
5130
5148
|
'star',
|
|
5131
5149
|
'store',
|
|
5132
5150
|
'strategies',
|
|
5151
|
+
'strikethrough',
|
|
5133
5152
|
'sun',
|
|
5153
|
+
'table',
|
|
5134
5154
|
'tablet',
|
|
5135
5155
|
'target',
|
|
5136
5156
|
'theme',
|
|
@@ -5144,6 +5164,7 @@ const SHARED_ICONS = [
|
|
|
5144
5164
|
'wallet_manager',
|
|
5145
5165
|
'wallet_owner',
|
|
5146
5166
|
'wallet_shareholder',
|
|
5167
|
+
'wand',
|
|
5147
5168
|
'wifi',
|
|
5148
5169
|
'x',
|
|
5149
5170
|
'zap',
|
|
@@ -7347,7 +7368,7 @@ class SectionFormItemComponent extends ConfigComponent {
|
|
|
7347
7368
|
break;
|
|
7348
7369
|
}
|
|
7349
7370
|
case InputType.TOGGLE: {
|
|
7350
|
-
const { ToggleInputComponent } = await import('./magmonium-one-toggle-
|
|
7371
|
+
const { ToggleInputComponent } = await import('./magmonium-one-toggle-QVCyppFj.mjs');
|
|
7351
7372
|
this.createDynamicComponent(seq, ToggleInputComponent, [], true);
|
|
7352
7373
|
break;
|
|
7353
7374
|
}
|
|
@@ -7359,12 +7380,12 @@ class SectionFormItemComponent extends ConfigComponent {
|
|
|
7359
7380
|
break;
|
|
7360
7381
|
}
|
|
7361
7382
|
case InputType.PASSWORD: {
|
|
7362
|
-
const { PasswordInputComponent } = await import('./magmonium-one-password-
|
|
7383
|
+
const { PasswordInputComponent } = await import('./magmonium-one-password-BDnu6JUW.mjs');
|
|
7363
7384
|
this.createDynamicComponent(seq, PasswordInputComponent);
|
|
7364
7385
|
break;
|
|
7365
7386
|
}
|
|
7366
7387
|
case InputType.OTP: {
|
|
7367
|
-
const { OtpInputComponent } = await import('./magmonium-one-otp-
|
|
7388
|
+
const { OtpInputComponent } = await import('./magmonium-one-otp-CoTAftI5.mjs');
|
|
7368
7389
|
this.createDynamicComponent(seq, OtpInputComponent);
|
|
7369
7390
|
break;
|
|
7370
7391
|
}
|
|
@@ -10194,13 +10215,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
10194
10215
|
class BaseTextInputComponent extends BaseInputComponent {
|
|
10195
10216
|
value = model();
|
|
10196
10217
|
inputElement = viewChild('inputElement', ...(ngDevMode ? [{ debugName: "inputElement" }] : /* istanbul ignore next */ []));
|
|
10218
|
+
document = inject(DOCUMENT);
|
|
10219
|
+
/** The element this field has already claimed the caret for, once. */
|
|
10220
|
+
autofocused;
|
|
10197
10221
|
constructor() {
|
|
10198
10222
|
super();
|
|
10199
10223
|
afterRenderEffect(() => {
|
|
10200
10224
|
const element = this.inputElement();
|
|
10201
|
-
if (this.focused()
|
|
10202
|
-
|
|
10203
|
-
|
|
10225
|
+
if (!this.focused() || !element)
|
|
10226
|
+
return;
|
|
10227
|
+
const node = element.nativeElement;
|
|
10228
|
+
// Once per element. A form that re-renders — an inspector rebuilt on
|
|
10229
|
+
// every store change — mounts a fresh input each time, and a focus per
|
|
10230
|
+
// mount is a focus per keystroke somewhere else on the screen.
|
|
10231
|
+
if (this.autofocused === node)
|
|
10232
|
+
return;
|
|
10233
|
+
// And never out of a surface the User is already working in. Same rule
|
|
10234
|
+
// the form makes for its own first field: a caret that has been placed
|
|
10235
|
+
// is theirs, not the next form's to take.
|
|
10236
|
+
const active = this.document.activeElement;
|
|
10237
|
+
if (active && active !== this.document.body && active !== node)
|
|
10238
|
+
return;
|
|
10239
|
+
this.autofocused = node;
|
|
10240
|
+
node.focus();
|
|
10204
10241
|
});
|
|
10205
10242
|
}
|
|
10206
10243
|
isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : /* istanbul ignore next */ []));
|
|
@@ -18730,6 +18767,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18730
18767
|
class TextareaInputComponent extends BaseTextInputComponent {
|
|
18731
18768
|
iconSize = Size.SMALL;
|
|
18732
18769
|
translateService = inject(TranslateService);
|
|
18770
|
+
/**
|
|
18771
|
+
* The element itself, for a host that edits the text around the caret — a
|
|
18772
|
+
* markdown toolbar wrapping a selection in `**` has to read what is selected
|
|
18773
|
+
* and hand the caret back afterwards, which no value binding can express.
|
|
18774
|
+
* The Field still owns the value; this is the selection, nothing else.
|
|
18775
|
+
*/
|
|
18776
|
+
control = viewChild('inputElement', ...(ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []));
|
|
18777
|
+
/** What is selected right now, or `undefined` before the field is drawn. */
|
|
18778
|
+
selection = () => {
|
|
18779
|
+
const element = this.control()?.nativeElement;
|
|
18780
|
+
if (!element)
|
|
18781
|
+
return undefined;
|
|
18782
|
+
return {
|
|
18783
|
+
value: element.value,
|
|
18784
|
+
start: element.selectionStart ?? 0,
|
|
18785
|
+
end: element.selectionEnd ?? 0,
|
|
18786
|
+
};
|
|
18787
|
+
};
|
|
18788
|
+
/**
|
|
18789
|
+
* Writes text and puts the caret where the caller says. The element is
|
|
18790
|
+
* written directly because the caret has to survive the write: a value that
|
|
18791
|
+
* arrives back through the binding lands with the caret at the end.
|
|
18792
|
+
*/
|
|
18793
|
+
writeSelection = (value, start, end) => {
|
|
18794
|
+
const element = this.control()?.nativeElement;
|
|
18795
|
+
if (!element)
|
|
18796
|
+
return;
|
|
18797
|
+
element.value = value;
|
|
18798
|
+
element.focus();
|
|
18799
|
+
element.setSelectionRange(start, end);
|
|
18800
|
+
};
|
|
18733
18801
|
placeholder(key) {
|
|
18734
18802
|
return key ? this.translateService.translate(key) : '';
|
|
18735
18803
|
}
|
|
@@ -18738,7 +18806,7 @@ class TextareaInputComponent extends BaseTextInputComponent {
|
|
|
18738
18806
|
this.setValue(target?.value ?? '');
|
|
18739
18807
|
}
|
|
18740
18808
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: TextareaInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
18741
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: TextareaInputComponent, isStandalone: true, selector: "m-textarea-input", usesInheritance: true, ngImport: i0, template: `
|
|
18809
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: TextareaInputComponent, isStandalone: true, selector: "m-textarea-input", viewQueries: [{ propertyName: "control", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
|
|
18742
18810
|
@if (config(); as text) {
|
|
18743
18811
|
@if (text.label) {
|
|
18744
18812
|
<m-label
|
|
@@ -18749,7 +18817,7 @@ class TextareaInputComponent extends BaseTextInputComponent {
|
|
|
18749
18817
|
[disabled]="disabled()"
|
|
18750
18818
|
/>
|
|
18751
18819
|
}
|
|
18752
|
-
<div class="input-wrapper">
|
|
18820
|
+
<div class="input-wrapper" [class.auto-grow]="!!text.autoGrow">
|
|
18753
18821
|
@if (text.icon) {
|
|
18754
18822
|
<m-icon
|
|
18755
18823
|
[name]="text.icon"
|
|
@@ -18758,8 +18826,11 @@ class TextareaInputComponent extends BaseTextInputComponent {
|
|
|
18758
18826
|
/>
|
|
18759
18827
|
}
|
|
18760
18828
|
<textarea
|
|
18829
|
+
[class.auto-grow]="!!text.autoGrow"
|
|
18761
18830
|
[id]="text.name ?? ''"
|
|
18762
18831
|
[value]="value()"
|
|
18832
|
+
[attr.aria-label]="text.label ? null : placeholder(text.placeholder)"
|
|
18833
|
+
[attr.spellcheck]="text.spellcheck ?? null"
|
|
18763
18834
|
#inputElement
|
|
18764
18835
|
[class.error]="showErrors()"
|
|
18765
18836
|
[class.has-icon]="!!text.icon"
|
|
@@ -18779,7 +18850,7 @@ class TextareaInputComponent extends BaseTextInputComponent {
|
|
|
18779
18850
|
}
|
|
18780
18851
|
}
|
|
18781
18852
|
}
|
|
18782
|
-
`, isInline: true, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%;--m-textarea-background: var(--m-textarea-input-background, color-mix(in srgb, var(--m-focus) 2%, var(--m-background)));--m-textarea-padding: var(--m-textarea-input-padding, .375em calc(var(--input-size, 1em) * .5 * .7));--m-textarea-shadow: var(--m-textarea-input-shadow, none)}.input-wrapper{display:flex;align-items:center;background:var(--m-background);overflow:hidden;height:calc(var(--input-size, 1em) * 2);min-height:calc(var(--input-size, 1em) * 2);border-width:max(1px,var(--input-size, 1em) * .0625);border-radius:calc(var(--input-size, 1em) * .4);padding:calc(var(--input-size, 1em) * .5) calc(var(--input-size, 1em) * .5);gap:calc(var(--input-size, 1em) * .375);font-size:var(--input-size, 1em);border-width:var(--m-input-border-width, 1px);border-radius:var(--m-input-radius, calc(var(--input-size, 1em) * .5));height:calc(var(--input-size, 1em) * 2.25);min-height:calc(var(--input-size, 1em) * 2.25);padding-top:0;padding-bottom:0;border-color:var(--m-input-color, var(--m-mm));transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease,opacity .2s ease}.input-wrapper:hover:not(:disabled){background-color:color-mix(in srgb,var(--m-input-color, var(--m-mm)) 6%,transparent)}.input-wrapper:disabled{opacity:.6;cursor:not-allowed}.input-wrapper{border-style:solid;backdrop-filter:var(--m-text-input-backdrop-filter, none);-webkit-backdrop-filter:var(--m-text-input-backdrop-filter, none);box-shadow:var(--m-text-input-shadow, none)}.input-wrapper:has(>m-one-button,>m-button,>.input-indicator,>.input-suffix,>m-icon:last-child){padding-right:0}.input-wrapper:focus-visible:not(:disabled),.input-wrapper:focus-within:not(:disabled){border-color:var(--m-text-input-focus-border, var(--m-focus));box-shadow:none}.input-wrapper:has(.warning){border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)));box-shadow:none}.input-wrapper:has(.warning):focus-within{border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)))}.input-wrapper:has(.warning) input::placeholder,.input-wrapper:has(.warning) textarea::placeholder{color:var(--m-warning, var(--m-warning))}.input-wrapper:has(.error){border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper:has(.error):focus-within{border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper input::placeholder,.input-wrapper textarea::placeholder{color:var(--m-border, var(--m-border))}.input-wrapper:focus-within input::placeholder,.input-wrapper:focus-visible input::placeholder,.input-wrapper:focus-within textarea::placeholder,.input-wrapper:focus-visible textarea::placeholder{color:var(--m-focus, var(--m-focus))}.input-wrapper:has(.error) input::placeholder,.input-wrapper:has(.error) textarea::placeholder{color:var(--m-error, var(--m-error))}.input-wrapper input,.input-wrapper textarea{flex:1;border:none;outline:none;background:transparent;color:var(--m-text);font-family:inherit;font-size:inherit;padding:0}.input-wrapper input:focus,.input-wrapper textarea:focus{border-color:transparent;box-shadow:none}.input-wrapper{width:100%;align-items:flex-start;position:relative;min-height:2em;height:auto
|
|
18853
|
+
`, isInline: true, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%;--m-textarea-background: var(--m-textarea-input-background, color-mix(in srgb, var(--m-focus) 2%, var(--m-background)));--m-textarea-padding: var(--m-textarea-input-padding, .375em calc(var(--input-size, 1em) * .5 * .7));--m-textarea-shadow: var(--m-textarea-input-shadow, none)}.input-wrapper{display:flex;align-items:center;background:var(--m-background);overflow:hidden;height:calc(var(--input-size, 1em) * 2);min-height:calc(var(--input-size, 1em) * 2);border-width:max(1px,var(--input-size, 1em) * .0625);border-radius:calc(var(--input-size, 1em) * .4);padding:calc(var(--input-size, 1em) * .5) calc(var(--input-size, 1em) * .5);gap:calc(var(--input-size, 1em) * .375);font-size:var(--input-size, 1em);border-width:var(--m-input-border-width, 1px);border-radius:var(--m-input-radius, calc(var(--input-size, 1em) * .5));height:calc(var(--input-size, 1em) * 2.25);min-height:calc(var(--input-size, 1em) * 2.25);padding-top:0;padding-bottom:0;border-color:var(--m-input-color, var(--m-mm));transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease,opacity .2s ease}.input-wrapper:hover:not(:disabled){background-color:color-mix(in srgb,var(--m-input-color, var(--m-mm)) 6%,transparent)}.input-wrapper:disabled{opacity:.6;cursor:not-allowed}.input-wrapper{border-style:solid;backdrop-filter:var(--m-text-input-backdrop-filter, none);-webkit-backdrop-filter:var(--m-text-input-backdrop-filter, none);box-shadow:var(--m-text-input-shadow, none)}.input-wrapper:has(>m-one-button,>m-button,>.input-indicator,>.input-suffix,>m-icon:last-child){padding-right:0}.input-wrapper:focus-visible:not(:disabled),.input-wrapper:focus-within:not(:disabled){border-color:var(--m-text-input-focus-border, var(--m-focus));box-shadow:none}.input-wrapper:has(.warning){border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)));box-shadow:none}.input-wrapper:has(.warning):focus-within{border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)))}.input-wrapper:has(.warning) input::placeholder,.input-wrapper:has(.warning) textarea::placeholder{color:var(--m-warning, var(--m-warning))}.input-wrapper:has(.error){border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper:has(.error):focus-within{border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper input::placeholder,.input-wrapper textarea::placeholder{color:var(--m-border, var(--m-border))}.input-wrapper:focus-within input::placeholder,.input-wrapper:focus-visible input::placeholder,.input-wrapper:focus-within textarea::placeholder,.input-wrapper:focus-visible textarea::placeholder{color:var(--m-focus, var(--m-focus))}.input-wrapper:has(.error) input::placeholder,.input-wrapper:has(.error) textarea::placeholder{color:var(--m-error, var(--m-error))}.input-wrapper input,.input-wrapper textarea{flex:1;border:none;outline:none;background:transparent;color:var(--m-text);font-family:inherit;font-size:inherit;padding:0}.input-wrapper input:focus,.input-wrapper textarea:focus{border-color:transparent;box-shadow:none}.input-wrapper{width:100%;align-items:flex-start;position:relative;min-height:2em;height:var(--m-textarea-input-wrapper-height, auto)}.input-wrapper.auto-grow{height:auto}.input-wrapper{padding:var(--m-textarea-padding);padding-left:var(--m-textarea-input-padding-left, var(--m-label-required-space, .75em));gap:.375em;background:var(--m-textarea-background);border:var(--m-textarea-input-border, var(--m-input-border-width, 1px) solid color-mix(in srgb, var(--m-text) 18%, var(--m-background)));box-shadow:var(--m-textarea-shadow)}.input-wrapper textarea{appearance:none;border:none;outline:none;flex:1;resize:none;display:block;box-sizing:border-box;height:var(--m-textarea-input-height, 4.5em);min-height:var(--m-textarea-input-height, 4.5em);overflow-y:auto;background:transparent;color:var(--m-text);font-family:inherit;font-size:1em;padding:0;line-height:1.5}.input-wrapper textarea.auto-grow{field-sizing:content;height:auto;min-height:var(--m-textarea-input-height, 4.5em);max-height:var(--m-textarea-input-max-height, none)}.input-wrapper textarea:focus{box-shadow:none;background:transparent}.input-wrapper .m-icon{margin-top:.125rem;display:flex;align-items:center;justify-content:center;--m-icon-size: 1.1em !important}\n"], dependencies: [{ kind: "component", type: LabelComponent, selector: "m-label", inputs: ["for", "placeholder", "params", "required", "disabled", "color"] }, { kind: "component", type: TextOutputComponent, selector: "m-text-output", inputs: ["config", "align", "variant", "color", "fontWeight", "label", "noTranslate", "params"], outputs: ["configChange", "clicked"] }, { kind: "component", type: IconComponent, selector: "m-icon, m-one-icon", inputs: ["config", "name", "color", "size", "one", "baseUrl", "remote"], outputs: ["configChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18783
18854
|
}
|
|
18784
18855
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: TextareaInputComponent, decorators: [{
|
|
18785
18856
|
type: Component,
|
|
@@ -18794,7 +18865,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18794
18865
|
[disabled]="disabled()"
|
|
18795
18866
|
/>
|
|
18796
18867
|
}
|
|
18797
|
-
<div class="input-wrapper">
|
|
18868
|
+
<div class="input-wrapper" [class.auto-grow]="!!text.autoGrow">
|
|
18798
18869
|
@if (text.icon) {
|
|
18799
18870
|
<m-icon
|
|
18800
18871
|
[name]="text.icon"
|
|
@@ -18803,8 +18874,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18803
18874
|
/>
|
|
18804
18875
|
}
|
|
18805
18876
|
<textarea
|
|
18877
|
+
[class.auto-grow]="!!text.autoGrow"
|
|
18806
18878
|
[id]="text.name ?? ''"
|
|
18807
18879
|
[value]="value()"
|
|
18880
|
+
[attr.aria-label]="text.label ? null : placeholder(text.placeholder)"
|
|
18881
|
+
[attr.spellcheck]="text.spellcheck ?? null"
|
|
18808
18882
|
#inputElement
|
|
18809
18883
|
[class.error]="showErrors()"
|
|
18810
18884
|
[class.has-icon]="!!text.icon"
|
|
@@ -18824,8 +18898,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18824
18898
|
}
|
|
18825
18899
|
}
|
|
18826
18900
|
}
|
|
18827
|
-
`, imports: [LabelComponent, TextOutputComponent, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%;--m-textarea-background: var(--m-textarea-input-background, color-mix(in srgb, var(--m-focus) 2%, var(--m-background)));--m-textarea-padding: var(--m-textarea-input-padding, .375em calc(var(--input-size, 1em) * .5 * .7));--m-textarea-shadow: var(--m-textarea-input-shadow, none)}.input-wrapper{display:flex;align-items:center;background:var(--m-background);overflow:hidden;height:calc(var(--input-size, 1em) * 2);min-height:calc(var(--input-size, 1em) * 2);border-width:max(1px,var(--input-size, 1em) * .0625);border-radius:calc(var(--input-size, 1em) * .4);padding:calc(var(--input-size, 1em) * .5) calc(var(--input-size, 1em) * .5);gap:calc(var(--input-size, 1em) * .375);font-size:var(--input-size, 1em);border-width:var(--m-input-border-width, 1px);border-radius:var(--m-input-radius, calc(var(--input-size, 1em) * .5));height:calc(var(--input-size, 1em) * 2.25);min-height:calc(var(--input-size, 1em) * 2.25);padding-top:0;padding-bottom:0;border-color:var(--m-input-color, var(--m-mm));transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease,opacity .2s ease}.input-wrapper:hover:not(:disabled){background-color:color-mix(in srgb,var(--m-input-color, var(--m-mm)) 6%,transparent)}.input-wrapper:disabled{opacity:.6;cursor:not-allowed}.input-wrapper{border-style:solid;backdrop-filter:var(--m-text-input-backdrop-filter, none);-webkit-backdrop-filter:var(--m-text-input-backdrop-filter, none);box-shadow:var(--m-text-input-shadow, none)}.input-wrapper:has(>m-one-button,>m-button,>.input-indicator,>.input-suffix,>m-icon:last-child){padding-right:0}.input-wrapper:focus-visible:not(:disabled),.input-wrapper:focus-within:not(:disabled){border-color:var(--m-text-input-focus-border, var(--m-focus));box-shadow:none}.input-wrapper:has(.warning){border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)));box-shadow:none}.input-wrapper:has(.warning):focus-within{border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)))}.input-wrapper:has(.warning) input::placeholder,.input-wrapper:has(.warning) textarea::placeholder{color:var(--m-warning, var(--m-warning))}.input-wrapper:has(.error){border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper:has(.error):focus-within{border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper input::placeholder,.input-wrapper textarea::placeholder{color:var(--m-border, var(--m-border))}.input-wrapper:focus-within input::placeholder,.input-wrapper:focus-visible input::placeholder,.input-wrapper:focus-within textarea::placeholder,.input-wrapper:focus-visible textarea::placeholder{color:var(--m-focus, var(--m-focus))}.input-wrapper:has(.error) input::placeholder,.input-wrapper:has(.error) textarea::placeholder{color:var(--m-error, var(--m-error))}.input-wrapper input,.input-wrapper textarea{flex:1;border:none;outline:none;background:transparent;color:var(--m-text);font-family:inherit;font-size:inherit;padding:0}.input-wrapper input:focus,.input-wrapper textarea:focus{border-color:transparent;box-shadow:none}.input-wrapper{width:100%;align-items:flex-start;position:relative;min-height:2em;height:auto
|
|
18828
|
-
}] });
|
|
18901
|
+
`, imports: [LabelComponent, TextOutputComponent, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%;--m-textarea-background: var(--m-textarea-input-background, color-mix(in srgb, var(--m-focus) 2%, var(--m-background)));--m-textarea-padding: var(--m-textarea-input-padding, .375em calc(var(--input-size, 1em) * .5 * .7));--m-textarea-shadow: var(--m-textarea-input-shadow, none)}.input-wrapper{display:flex;align-items:center;background:var(--m-background);overflow:hidden;height:calc(var(--input-size, 1em) * 2);min-height:calc(var(--input-size, 1em) * 2);border-width:max(1px,var(--input-size, 1em) * .0625);border-radius:calc(var(--input-size, 1em) * .4);padding:calc(var(--input-size, 1em) * .5) calc(var(--input-size, 1em) * .5);gap:calc(var(--input-size, 1em) * .375);font-size:var(--input-size, 1em);border-width:var(--m-input-border-width, 1px);border-radius:var(--m-input-radius, calc(var(--input-size, 1em) * .5));height:calc(var(--input-size, 1em) * 2.25);min-height:calc(var(--input-size, 1em) * 2.25);padding-top:0;padding-bottom:0;border-color:var(--m-input-color, var(--m-mm));transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease,opacity .2s ease}.input-wrapper:hover:not(:disabled){background-color:color-mix(in srgb,var(--m-input-color, var(--m-mm)) 6%,transparent)}.input-wrapper:disabled{opacity:.6;cursor:not-allowed}.input-wrapper{border-style:solid;backdrop-filter:var(--m-text-input-backdrop-filter, none);-webkit-backdrop-filter:var(--m-text-input-backdrop-filter, none);box-shadow:var(--m-text-input-shadow, none)}.input-wrapper:has(>m-one-button,>m-button,>.input-indicator,>.input-suffix,>m-icon:last-child){padding-right:0}.input-wrapper:focus-visible:not(:disabled),.input-wrapper:focus-within:not(:disabled){border-color:var(--m-text-input-focus-border, var(--m-focus));box-shadow:none}.input-wrapper:has(.warning){border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)));box-shadow:none}.input-wrapper:has(.warning):focus-within{border-color:var(--m-input-warning-border, var(--m-warning));background:var(--m-input-warning-background, color-mix(in srgb, var(--m-warning) 6%, var(--m-background)))}.input-wrapper:has(.warning) input::placeholder,.input-wrapper:has(.warning) textarea::placeholder{color:var(--m-warning, var(--m-warning))}.input-wrapper:has(.error){border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper:has(.error):focus-within{border-color:var(--m-error);background:var(--m-input-error-background, color-mix(in srgb, var(--m-error) 5%, var(--m-background)));box-shadow:none}.input-wrapper input::placeholder,.input-wrapper textarea::placeholder{color:var(--m-border, var(--m-border))}.input-wrapper:focus-within input::placeholder,.input-wrapper:focus-visible input::placeholder,.input-wrapper:focus-within textarea::placeholder,.input-wrapper:focus-visible textarea::placeholder{color:var(--m-focus, var(--m-focus))}.input-wrapper:has(.error) input::placeholder,.input-wrapper:has(.error) textarea::placeholder{color:var(--m-error, var(--m-error))}.input-wrapper input,.input-wrapper textarea{flex:1;border:none;outline:none;background:transparent;color:var(--m-text);font-family:inherit;font-size:inherit;padding:0}.input-wrapper input:focus,.input-wrapper textarea:focus{border-color:transparent;box-shadow:none}.input-wrapper{width:100%;align-items:flex-start;position:relative;min-height:2em;height:var(--m-textarea-input-wrapper-height, auto)}.input-wrapper.auto-grow{height:auto}.input-wrapper{padding:var(--m-textarea-padding);padding-left:var(--m-textarea-input-padding-left, var(--m-label-required-space, .75em));gap:.375em;background:var(--m-textarea-background);border:var(--m-textarea-input-border, var(--m-input-border-width, 1px) solid color-mix(in srgb, var(--m-text) 18%, var(--m-background)));box-shadow:var(--m-textarea-shadow)}.input-wrapper textarea{appearance:none;border:none;outline:none;flex:1;resize:none;display:block;box-sizing:border-box;height:var(--m-textarea-input-height, 4.5em);min-height:var(--m-textarea-input-height, 4.5em);overflow-y:auto;background:transparent;color:var(--m-text);font-family:inherit;font-size:1em;padding:0;line-height:1.5}.input-wrapper textarea.auto-grow{field-sizing:content;height:auto;min-height:var(--m-textarea-input-height, 4.5em);max-height:var(--m-textarea-input-max-height, none)}.input-wrapper textarea:focus{box-shadow:none;background:transparent}.input-wrapper .m-icon{margin-top:.125rem;display:flex;align-items:center;justify-content:center;--m-icon-size: 1.1em !important}\n"] }]
|
|
18902
|
+
}], propDecorators: { control: [{ type: i0.ViewChild, args: ['inputElement', { isSignal: true }] }] } });
|
|
18829
18903
|
|
|
18830
18904
|
var textarea = /*#__PURE__*/Object.freeze({
|
|
18831
18905
|
__proto__: null,
|
|
@@ -21479,7 +21553,7 @@ class WrapperInputComponent extends ConfigComponent {
|
|
|
21479
21553
|
break;
|
|
21480
21554
|
}
|
|
21481
21555
|
case InputType.TOGGLE: {
|
|
21482
|
-
const { ToggleInputComponent } = await import('./magmonium-one-toggle-
|
|
21556
|
+
const { ToggleInputComponent } = await import('./magmonium-one-toggle-QVCyppFj.mjs');
|
|
21483
21557
|
this.createDynamicComponent(seq, ToggleInputComponent, [], true);
|
|
21484
21558
|
break;
|
|
21485
21559
|
}
|
|
@@ -21491,12 +21565,12 @@ class WrapperInputComponent extends ConfigComponent {
|
|
|
21491
21565
|
break;
|
|
21492
21566
|
}
|
|
21493
21567
|
case InputType.PASSWORD: {
|
|
21494
|
-
const { PasswordInputComponent } = await import('./magmonium-one-password-
|
|
21568
|
+
const { PasswordInputComponent } = await import('./magmonium-one-password-BDnu6JUW.mjs');
|
|
21495
21569
|
this.createDynamicComponent(seq, PasswordInputComponent);
|
|
21496
21570
|
break;
|
|
21497
21571
|
}
|
|
21498
21572
|
case InputType.OTP: {
|
|
21499
|
-
const { OtpInputComponent } = await import('./magmonium-one-otp-
|
|
21573
|
+
const { OtpInputComponent } = await import('./magmonium-one-otp-CoTAftI5.mjs');
|
|
21500
21574
|
this.createDynamicComponent(seq, OtpInputComponent);
|
|
21501
21575
|
break;
|
|
21502
21576
|
}
|
|
@@ -23203,7 +23277,7 @@ class FileUploadInputComponent extends BaseInputComponent {
|
|
|
23203
23277
|
const modalStore = this.modalStore;
|
|
23204
23278
|
if (!modalStore)
|
|
23205
23279
|
return undefined;
|
|
23206
|
-
const { ImageEditorComponent } = await import('./magmonium-one-image-editor-
|
|
23280
|
+
const { ImageEditorComponent } = await import('./magmonium-one-image-editor-DKFMr1hF.mjs');
|
|
23207
23281
|
const ratio = String(this.config()?.ratio ?? '');
|
|
23208
23282
|
return new Promise((resolve) => {
|
|
23209
23283
|
const modalRef = new ModalRef();
|
|
@@ -26447,6 +26521,919 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
26447
26521
|
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:inline-flex;align-items:flex-start;line-height:1}.score__prefix,.score__suffix{font-size:.8em;font-weight:500;margin:0 .2em}.score__int{font-size:1.2em;font-weight:600}.score__sep{font-size:.4em;font-weight:400;opacity:.45;margin-top:.15em}.score__dec{font-size:.6em;font-weight:400;opacity:.65;margin-top:.15em}\n"] }]
|
|
26448
26522
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }] } });
|
|
26449
26523
|
|
|
26524
|
+
/** The one folder a DocAsset lives in, under `assets/` and under `assets/one/`. */
|
|
26525
|
+
const DOCS_FOLDER = 'docs';
|
|
26526
|
+
/** The library tier's own root, as `HttpService.asset` reads a tree's head. */
|
|
26527
|
+
const LIBRARY_TIER = 'one';
|
|
26528
|
+
/**
|
|
26529
|
+
* Where one document may be found, in the order it is asked for.
|
|
26530
|
+
*
|
|
26531
|
+
* App tier before library tier, so an app's own document wins the name; active
|
|
26532
|
+
* language before default, because a missing translation is a fallback and not
|
|
26533
|
+
* a failure. The `<lang>/` segment is never optional — one resolution shape.
|
|
26534
|
+
*/
|
|
26535
|
+
function docAssetCandidates({ name, lang, defaultLang, }) {
|
|
26536
|
+
if (!name)
|
|
26537
|
+
return [];
|
|
26538
|
+
const langs = lang === defaultLang ? [lang] : [lang, defaultLang];
|
|
26539
|
+
return langs.flatMap((language) => [
|
|
26540
|
+
[DOCS_FOLDER, language, name],
|
|
26541
|
+
[LIBRARY_TIER, DOCS_FOLDER, language, name],
|
|
26542
|
+
]);
|
|
26543
|
+
}
|
|
26544
|
+
/**
|
|
26545
|
+
* The path a document sits at inside another Remote's own assets, which the
|
|
26546
|
+
* `wc` route serves as `text/markdown` without any backend work.
|
|
26547
|
+
*/
|
|
26548
|
+
function docRemotePath(name, lang) {
|
|
26549
|
+
return `${DOCS_FOLDER}/${lang}/${name}.md`;
|
|
26550
|
+
}
|
|
26551
|
+
|
|
26552
|
+
/**
|
|
26553
|
+
* Renders a **document** — CommonMark plus GFM tables, which MiniMark
|
|
26554
|
+
* deliberately does not carry (libs/one ADR 0002 and its amendment).
|
|
26555
|
+
*
|
|
26556
|
+
* The output vocabulary is closed the way MiniMark's is, just wider: raw HTML
|
|
26557
|
+
* is dropped rather than passed through, images are not served at all, and a
|
|
26558
|
+
* link's href is gated by scheme. Everything that survives sits on Angular's
|
|
26559
|
+
* own sanitizer allowlist, so binding the result with a plain `[innerHTML]`
|
|
26560
|
+
* keeps the same safety net the MiniMark path relies on — no
|
|
26561
|
+
* `bypassSecurityTrustHtml`, no second sanitizer to keep in sync.
|
|
26562
|
+
*/
|
|
26563
|
+
/** `marked` is only ever loaded by an `m-doc` that actually renders something. */
|
|
26564
|
+
let parser = null;
|
|
26565
|
+
const EXTERNAL_SCHEME = /^(?:https?:|mailto:|tel:)/i;
|
|
26566
|
+
const ANY_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
|
|
26567
|
+
/**
|
|
26568
|
+
* Anything that is not an allowed scheme stays literal text. A relative or
|
|
26569
|
+
* hash href is allowed and is *not* opened in a new tab — it points inside the
|
|
26570
|
+
* app that is rendering the document.
|
|
26571
|
+
*/
|
|
26572
|
+
function isExternal(href) {
|
|
26573
|
+
return EXTERNAL_SCHEME.test(href) || href.startsWith('//');
|
|
26574
|
+
}
|
|
26575
|
+
function isAllowed(href) {
|
|
26576
|
+
if (isExternal(href))
|
|
26577
|
+
return true;
|
|
26578
|
+
// No scheme at all: relative, absolute-path or hash.
|
|
26579
|
+
return !ANY_SCHEME.test(href);
|
|
26580
|
+
}
|
|
26581
|
+
/** The href is the one attribute value this renderer emits, so it is fenced. */
|
|
26582
|
+
function hardenHref(href) {
|
|
26583
|
+
return href
|
|
26584
|
+
// eslint-disable-next-line no-control-regex
|
|
26585
|
+
.replace(/[\u0000-\u001f\u007f]/g, '')
|
|
26586
|
+
.replace(/"/g, '%22');
|
|
26587
|
+
}
|
|
26588
|
+
async function getParser() {
|
|
26589
|
+
if (!parser) {
|
|
26590
|
+
parser = import('marked').then(({ Marked }) => {
|
|
26591
|
+
const marked = new Marked({
|
|
26592
|
+
gfm: true,
|
|
26593
|
+
breaks: false,
|
|
26594
|
+
renderer: {
|
|
26595
|
+
// Raw HTML — block and inline alike — never reaches the DOM. The
|
|
26596
|
+
// text around it survives; the markup does not.
|
|
26597
|
+
html: () => '',
|
|
26598
|
+
// Off in v1: an image in a document fetched from the Store is a
|
|
26599
|
+
// remote request the reader did not ask for.
|
|
26600
|
+
image: () => '',
|
|
26601
|
+
link(token) {
|
|
26602
|
+
const text = this.parser.parseInline(token.tokens);
|
|
26603
|
+
if (!isAllowed(token.href))
|
|
26604
|
+
return text;
|
|
26605
|
+
const href = hardenHref(token.href);
|
|
26606
|
+
const title = token.title
|
|
26607
|
+
? ` title="${hardenHref(token.title)}"`
|
|
26608
|
+
: '';
|
|
26609
|
+
const external = isExternal(token.href)
|
|
26610
|
+
? ' target="_blank" rel="noopener noreferrer"'
|
|
26611
|
+
: '';
|
|
26612
|
+
return `<a href="${href}"${title}${external}>${text}</a>`;
|
|
26613
|
+
},
|
|
26614
|
+
},
|
|
26615
|
+
});
|
|
26616
|
+
return marked;
|
|
26617
|
+
});
|
|
26618
|
+
}
|
|
26619
|
+
return parser;
|
|
26620
|
+
}
|
|
26621
|
+
/** Markdown in, closed-vocabulary HTML out. */
|
|
26622
|
+
async function renderDocument(markdown) {
|
|
26623
|
+
if (!markdown)
|
|
26624
|
+
return '';
|
|
26625
|
+
const marked = await getParser();
|
|
26626
|
+
return marked.parse(markdown, { async: false });
|
|
26627
|
+
}
|
|
26628
|
+
|
|
26629
|
+
/** What a missing translation of a document falls back to before giving up. */
|
|
26630
|
+
const DEFAULT_DOC_LANG = 'en';
|
|
26631
|
+
/**
|
|
26632
|
+
* Renders one DocAsset — a markdown document, not a message.
|
|
26633
|
+
*
|
|
26634
|
+
* Folderless like `m-img` and `m-logo`: three inputs, literal attributes, no
|
|
26635
|
+
* `config` bag and therefore no ControlAsset. It fetches its own content the
|
|
26636
|
+
* way an Img does, so nothing has to be wired to it: a name resolves app tier
|
|
26637
|
+
* then library tier and active language then default, a `remote` reads the
|
|
26638
|
+
* named Remote's own copy, and a `designSrc` short-circuits both because the
|
|
26639
|
+
* editor's Canvas has no backend to resolve either against.
|
|
26640
|
+
*
|
|
26641
|
+
* A document that is nowhere renders as nothing. Loading and error belong to
|
|
26642
|
+
* the interceptor (ADR 0026), and a missing translation is not an app failure.
|
|
26643
|
+
*/
|
|
26644
|
+
class DocComponent {
|
|
26645
|
+
/** The DocAsset's name — never a path and never a url. */
|
|
26646
|
+
name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
26647
|
+
/** Another Remote's AppLink, whose own copy of that name is read instead. */
|
|
26648
|
+
remote = input('', ...(ngDevMode ? [{ debugName: "remote" }] : /* istanbul ignore next */ []));
|
|
26649
|
+
/**
|
|
26650
|
+
* A whole url the document is fetched from at runtime, for a document this
|
|
26651
|
+
* app does not ship. It wins over `name` and `remote`: a url is the most
|
|
26652
|
+
* specific thing a caller can say about where the text lives.
|
|
26653
|
+
*/
|
|
26654
|
+
url = input('', ...(ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []));
|
|
26655
|
+
/** Design-time only: what the Canvas draws in place of a read it cannot make. */
|
|
26656
|
+
designSrc = input('', ...(ngDevMode ? [{ debugName: "designSrc" }] : /* istanbul ignore next */ []));
|
|
26657
|
+
http = inject(HttpService);
|
|
26658
|
+
translate = inject(TranslateService);
|
|
26659
|
+
html = signal('', ...(ngDevMode ? [{ debugName: "html" }] : /* istanbul ignore next */ []));
|
|
26660
|
+
pending = signal(false, ...(ngDevMode ? [{ debugName: "pending" }] : /* istanbul ignore next */ []));
|
|
26661
|
+
/** Only the newest read may write; an input changed mid-flight wins. */
|
|
26662
|
+
token = 0;
|
|
26663
|
+
constructor() {
|
|
26664
|
+
effect(() => {
|
|
26665
|
+
const name = this.name();
|
|
26666
|
+
const remote = this.remote();
|
|
26667
|
+
const url = this.url();
|
|
26668
|
+
const designSrc = this.designSrc();
|
|
26669
|
+
const lang = this.translate.lang();
|
|
26670
|
+
const request = ++this.token;
|
|
26671
|
+
if (designSrc) {
|
|
26672
|
+
this.pending.set(true);
|
|
26673
|
+
void this.show(designSrc, request);
|
|
26674
|
+
return;
|
|
26675
|
+
}
|
|
26676
|
+
if (!name && !url) {
|
|
26677
|
+
this.pending.set(false);
|
|
26678
|
+
this.html.set('');
|
|
26679
|
+
return;
|
|
26680
|
+
}
|
|
26681
|
+
this.pending.set(true);
|
|
26682
|
+
void this.load({ name, remote, url, lang, request });
|
|
26683
|
+
});
|
|
26684
|
+
}
|
|
26685
|
+
async load({ name, remote, url, lang, request, }) {
|
|
26686
|
+
const source = url
|
|
26687
|
+
? await this.readUrl(url)
|
|
26688
|
+
: remote
|
|
26689
|
+
? await this.readRemote(remote, name, lang)
|
|
26690
|
+
: await this.readAsset(name, lang);
|
|
26691
|
+
await this.show(source ?? '', request);
|
|
26692
|
+
}
|
|
26693
|
+
/** App tier then library tier, active language then default — first hit wins. */
|
|
26694
|
+
async readAsset(name, lang) {
|
|
26695
|
+
for (const tree of docAssetCandidates({
|
|
26696
|
+
name,
|
|
26697
|
+
lang,
|
|
26698
|
+
defaultLang: DEFAULT_DOC_LANG,
|
|
26699
|
+
})) {
|
|
26700
|
+
try {
|
|
26701
|
+
return await firstValueFrom(this.http.asset(tree, Assets.MD));
|
|
26702
|
+
}
|
|
26703
|
+
catch {
|
|
26704
|
+
continue;
|
|
26705
|
+
}
|
|
26706
|
+
}
|
|
26707
|
+
return null;
|
|
26708
|
+
}
|
|
26709
|
+
/** The named Remote's own copy, served by the `wc` route as `text/markdown`. */
|
|
26710
|
+
async readRemote(remote, name, lang) {
|
|
26711
|
+
const langs = lang === DEFAULT_DOC_LANG ? [lang] : [lang, DEFAULT_DOC_LANG];
|
|
26712
|
+
for (const language of langs) {
|
|
26713
|
+
try {
|
|
26714
|
+
return await firstValueFrom(this.http.text(this.http.buildWcAssetUrl(remote, docRemotePath(name, language))));
|
|
26715
|
+
}
|
|
26716
|
+
catch {
|
|
26717
|
+
continue;
|
|
26718
|
+
}
|
|
26719
|
+
}
|
|
26720
|
+
return null;
|
|
26721
|
+
}
|
|
26722
|
+
/** A whole url, read as text. Nothing is appended to it and no tier applies. */
|
|
26723
|
+
async readUrl(url) {
|
|
26724
|
+
try {
|
|
26725
|
+
return await firstValueFrom(this.http.text(url));
|
|
26726
|
+
}
|
|
26727
|
+
catch {
|
|
26728
|
+
return null;
|
|
26729
|
+
}
|
|
26730
|
+
}
|
|
26731
|
+
async show(markdown, request) {
|
|
26732
|
+
const rendered = await renderDocument(markdown);
|
|
26733
|
+
if (request !== this.token)
|
|
26734
|
+
return;
|
|
26735
|
+
this.html.set(rendered);
|
|
26736
|
+
this.pending.set(false);
|
|
26737
|
+
}
|
|
26738
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DocComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
26739
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DocComponent, isStandalone: true, selector: "m-doc", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, remote: { classPropertyName: "remote", publicName: "remote", isSignal: true, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null }, designSrc: { classPropertyName: "designSrc", publicName: "designSrc", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
26740
|
+
<div class="m-doc">
|
|
26741
|
+
@if (pending()) {
|
|
26742
|
+
<div class="m-doc__skeleton"></div>
|
|
26743
|
+
}
|
|
26744
|
+
<div class="m-doc__body" [innerHTML]="html()"></div>
|
|
26745
|
+
</div>
|
|
26746
|
+
`, isInline: true, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%}.m-doc{position:relative;width:100%;color:var(--m-text);line-height:1.65}.m-doc__skeleton{height:12rem;border-radius:.5rem;background:#ffffff0a;animation:m-doc-pulse 1.4s ease-in-out infinite}.m-doc__body{display:block}.m-doc__body :is(h1,h2,h3,h4,h5,h6){margin:1.5em 0 .5em;line-height:1.25}.m-doc__body p,.m-doc__body ul,.m-doc__body ol,.m-doc__body blockquote,.m-doc__body pre,.m-doc__body table{margin:0 0 1em}.m-doc__body a{color:var(--m-mm);text-decoration:underline}.m-doc__body code{padding:.15em .35em;border-radius:.25rem;background:#ffffff0f;font-size:.9em}.m-doc__body pre{overflow-x:auto;padding:1em;border-radius:.5rem;background:#ffffff0d}.m-doc__body pre code{padding:0;background:none}.m-doc__body blockquote{padding-left:1em;border-left:2px solid rgba(255,255,255,.15);opacity:.85}.m-doc__body table{width:100%;border-collapse:collapse}.m-doc__body table :is(th,td){padding:.5em .75em;border-bottom:1px solid rgba(255,255,255,.1);text-align:left}@keyframes m-doc-pulse{0%,to{opacity:.5}50%{opacity:.9}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
26747
|
+
}
|
|
26748
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DocComponent, decorators: [{
|
|
26749
|
+
type: Component,
|
|
26750
|
+
args: [{ selector: 'm-doc', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
26751
|
+
<div class="m-doc">
|
|
26752
|
+
@if (pending()) {
|
|
26753
|
+
<div class="m-doc__skeleton"></div>
|
|
26754
|
+
}
|
|
26755
|
+
<div class="m-doc__body" [innerHTML]="html()"></div>
|
|
26756
|
+
</div>
|
|
26757
|
+
`, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%}.m-doc{position:relative;width:100%;color:var(--m-text);line-height:1.65}.m-doc__skeleton{height:12rem;border-radius:.5rem;background:#ffffff0a;animation:m-doc-pulse 1.4s ease-in-out infinite}.m-doc__body{display:block}.m-doc__body :is(h1,h2,h3,h4,h5,h6){margin:1.5em 0 .5em;line-height:1.25}.m-doc__body p,.m-doc__body ul,.m-doc__body ol,.m-doc__body blockquote,.m-doc__body pre,.m-doc__body table{margin:0 0 1em}.m-doc__body a{color:var(--m-mm);text-decoration:underline}.m-doc__body code{padding:.15em .35em;border-radius:.25rem;background:#ffffff0f;font-size:.9em}.m-doc__body pre{overflow-x:auto;padding:1em;border-radius:.5rem;background:#ffffff0d}.m-doc__body pre code{padding:0;background:none}.m-doc__body blockquote{padding-left:1em;border-left:2px solid rgba(255,255,255,.15);opacity:.85}.m-doc__body table{width:100%;border-collapse:collapse}.m-doc__body table :is(th,td){padding:.5em .75em;border-bottom:1px solid rgba(255,255,255,.1);text-align:left}@keyframes m-doc-pulse{0%,to{opacity:.5}50%{opacity:.9}}\n"] }]
|
|
26758
|
+
}], ctorParameters: () => [], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], remote: [{ type: i0.Input, args: [{ isSignal: true, alias: "remote", required: false }] }], url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], designSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "designSrc", required: false }] }] } });
|
|
26759
|
+
|
|
26760
|
+
/**
|
|
26761
|
+
* The markdown a toolbar press writes, as a pure transform over the textarea's
|
|
26762
|
+
* own state.
|
|
26763
|
+
*
|
|
26764
|
+
* Pure so the editor stays a view: the component reads `value/start/end` off
|
|
26765
|
+
* the element, hands them here, and writes the answer back. Nothing about a
|
|
26766
|
+
* document is decided in a DOM handler.
|
|
26767
|
+
*
|
|
26768
|
+
* There is deliberately no `image` action — the renderer does not serve images
|
|
26769
|
+
* in v1 (libs/one ADR 0034), and a toolbar that writes markup the renderer
|
|
26770
|
+
* drops is a toolbar that lies.
|
|
26771
|
+
*/
|
|
26772
|
+
const DOC_EDIT_ACTIONS = [
|
|
26773
|
+
'bold',
|
|
26774
|
+
'italic',
|
|
26775
|
+
'strike',
|
|
26776
|
+
'heading',
|
|
26777
|
+
'list',
|
|
26778
|
+
'quote',
|
|
26779
|
+
'link',
|
|
26780
|
+
'code',
|
|
26781
|
+
'table',
|
|
26782
|
+
];
|
|
26783
|
+
const WRAPPERS = {
|
|
26784
|
+
bold: '**',
|
|
26785
|
+
italic: '*',
|
|
26786
|
+
strike: '~~',
|
|
26787
|
+
};
|
|
26788
|
+
const MAX_HEADING = 6;
|
|
26789
|
+
const TABLE_SKELETON = ['| Name | Value |', '| --- | --- |', '| a | b |'].join('\n');
|
|
26790
|
+
/** Where the line the caret sits in begins and ends. */
|
|
26791
|
+
function lineBounds(value, start, end) {
|
|
26792
|
+
const from = value.lastIndexOf('\n', start - 1) + 1;
|
|
26793
|
+
const lineEnd = value.indexOf('\n', end);
|
|
26794
|
+
return { from, to: lineEnd === -1 ? value.length : lineEnd };
|
|
26795
|
+
}
|
|
26796
|
+
function replace(state, from, to, text, select) {
|
|
26797
|
+
return {
|
|
26798
|
+
value: state.value.slice(0, from) + text + state.value.slice(to),
|
|
26799
|
+
...select,
|
|
26800
|
+
};
|
|
26801
|
+
}
|
|
26802
|
+
function wrap(state, delimiter) {
|
|
26803
|
+
const { value, start, end } = state;
|
|
26804
|
+
const selected = value.slice(start, end);
|
|
26805
|
+
const before = value.slice(Math.max(0, start - delimiter.length), start);
|
|
26806
|
+
const after = value.slice(end, end + delimiter.length);
|
|
26807
|
+
// Already wrapped: the second press takes it off rather than nesting.
|
|
26808
|
+
if (before === delimiter && after === delimiter) {
|
|
26809
|
+
return replace(state, start - delimiter.length, end + delimiter.length, selected, { start: start - delimiter.length, end: end - delimiter.length });
|
|
26810
|
+
}
|
|
26811
|
+
return replace(state, start, end, `${delimiter}${selected}${delimiter}`, {
|
|
26812
|
+
start: start + delimiter.length,
|
|
26813
|
+
end: end + delimiter.length,
|
|
26814
|
+
});
|
|
26815
|
+
}
|
|
26816
|
+
/** `#` → `##` → … → `######` → none, so one button reaches every level. */
|
|
26817
|
+
function heading(state) {
|
|
26818
|
+
const { from, to } = lineBounds(state.value, state.start, state.end);
|
|
26819
|
+
const line = state.value.slice(from, to);
|
|
26820
|
+
const current = /^(#{1,6})\s/.exec(line);
|
|
26821
|
+
const level = current ? current[1].length : 0;
|
|
26822
|
+
const body = current ? line.slice(current[0].length) : line;
|
|
26823
|
+
const next = level >= MAX_HEADING ? '' : `${'#'.repeat(level + 1)} `;
|
|
26824
|
+
const text = `${next}${body}`;
|
|
26825
|
+
return replace(state, from, to, text, {
|
|
26826
|
+
start: from + text.length,
|
|
26827
|
+
end: from + text.length,
|
|
26828
|
+
});
|
|
26829
|
+
}
|
|
26830
|
+
function prefixLines(state, marker) {
|
|
26831
|
+
const { from, to } = lineBounds(state.value, state.start, state.end);
|
|
26832
|
+
const text = state.value
|
|
26833
|
+
.slice(from, to)
|
|
26834
|
+
.split('\n')
|
|
26835
|
+
.map((line) => (line.startsWith(marker) ? line.slice(marker.length) : `${marker}${line}`))
|
|
26836
|
+
.join('\n');
|
|
26837
|
+
return replace(state, from, to, text, {
|
|
26838
|
+
start: from,
|
|
26839
|
+
end: from + text.length,
|
|
26840
|
+
});
|
|
26841
|
+
}
|
|
26842
|
+
function link(state) {
|
|
26843
|
+
const selected = state.value.slice(state.start, state.end) || 'text';
|
|
26844
|
+
const text = `[${selected}](url)`;
|
|
26845
|
+
const urlStart = state.start + text.length - 'url)'.length;
|
|
26846
|
+
return replace(state, state.start, state.end, text, {
|
|
26847
|
+
start: urlStart,
|
|
26848
|
+
end: urlStart + 'url'.length,
|
|
26849
|
+
});
|
|
26850
|
+
}
|
|
26851
|
+
function code(state) {
|
|
26852
|
+
const selected = state.value.slice(state.start, state.end);
|
|
26853
|
+
const text = '```\n' + selected + '\n```';
|
|
26854
|
+
return replace(state, state.start, state.end, text, {
|
|
26855
|
+
start: state.start + 4,
|
|
26856
|
+
end: state.start + 4 + selected.length,
|
|
26857
|
+
});
|
|
26858
|
+
}
|
|
26859
|
+
function table(state) {
|
|
26860
|
+
const { value, start, end } = state;
|
|
26861
|
+
const needsBreak = start > 0 && value[start - 1] !== '\n';
|
|
26862
|
+
const text = `${needsBreak ? '\n' : ''}${TABLE_SKELETON}\n`;
|
|
26863
|
+
return replace(state, start, end, text, {
|
|
26864
|
+
start: start + text.length,
|
|
26865
|
+
end: start + text.length,
|
|
26866
|
+
});
|
|
26867
|
+
}
|
|
26868
|
+
function applyDocEdit(action, state) {
|
|
26869
|
+
const delimiter = WRAPPERS[action];
|
|
26870
|
+
if (delimiter)
|
|
26871
|
+
return wrap(state, delimiter);
|
|
26872
|
+
switch (action) {
|
|
26873
|
+
case 'heading':
|
|
26874
|
+
return heading(state);
|
|
26875
|
+
case 'list':
|
|
26876
|
+
return prefixLines(state, '- ');
|
|
26877
|
+
case 'quote':
|
|
26878
|
+
return prefixLines(state, '> ');
|
|
26879
|
+
case 'link':
|
|
26880
|
+
return link(state);
|
|
26881
|
+
case 'code':
|
|
26882
|
+
return code(state);
|
|
26883
|
+
case 'table':
|
|
26884
|
+
return table(state);
|
|
26885
|
+
default:
|
|
26886
|
+
return state;
|
|
26887
|
+
}
|
|
26888
|
+
}
|
|
26889
|
+
|
|
26890
|
+
const DOC_TOOLBAR_GROUPS = [
|
|
26891
|
+
['bold', 'italic', 'strike'],
|
|
26892
|
+
['heading', 'list', 'quote'],
|
|
26893
|
+
['link', 'code', 'table'],
|
|
26894
|
+
];
|
|
26895
|
+
/** The IconAsset each action shows. `strike` is the one name that differs. */
|
|
26896
|
+
const DOC_ACTION_ICONS = {
|
|
26897
|
+
bold: 'bold',
|
|
26898
|
+
italic: 'italic',
|
|
26899
|
+
strike: 'strikethrough',
|
|
26900
|
+
heading: 'heading',
|
|
26901
|
+
list: 'list',
|
|
26902
|
+
quote: 'quote',
|
|
26903
|
+
link: 'link',
|
|
26904
|
+
code: 'code',
|
|
26905
|
+
table: 'table',
|
|
26906
|
+
};
|
|
26907
|
+
/** The translation key behind an action's label, e.g. `doc-action-bold`. */
|
|
26908
|
+
function docActionKey(action) {
|
|
26909
|
+
return `doc-action-${action}`;
|
|
26910
|
+
}
|
|
26911
|
+
/**
|
|
26912
|
+
* Every action reaches a group exactly once — the toolbar is the whole action
|
|
26913
|
+
* list, drawn in a different order, never a subset of it.
|
|
26914
|
+
*/
|
|
26915
|
+
function ungroupedDocActions() {
|
|
26916
|
+
const grouped = new Set(DOC_TOOLBAR_GROUPS.flat());
|
|
26917
|
+
return DOC_EDIT_ACTIONS.filter((action) => !grouped.has(action));
|
|
26918
|
+
}
|
|
26919
|
+
|
|
26920
|
+
/**
|
|
26921
|
+
* What is wrong with a document, as a pure transform over its markdown.
|
|
26922
|
+
*
|
|
26923
|
+
* Markdown never fails to parse — `~~~~` followed by a bare fence renders
|
|
26924
|
+
* happily as an emphasised run of tildes inside a heading — so "parse error"
|
|
26925
|
+
* cannot mean "the parser threw". It means a construct whose output cannot be
|
|
26926
|
+
* what the author meant, and that judgement is made here rather than by the
|
|
26927
|
+
* parser (libs/one ADR 0035).
|
|
26928
|
+
*
|
|
26929
|
+
* Deterministic on purpose: the editor must be able to say a document is
|
|
26930
|
+
* broken with no [AiProvider] configured, because an endpoint the User has not
|
|
26931
|
+
* pasted a token for may not take validation down with it (m-one-ui ADR 0048).
|
|
26932
|
+
*
|
|
26933
|
+
* The two `dropped` kinds answer for the renderer: `m-doc` drops raw HTML and
|
|
26934
|
+
* images without a word, and a silent drop is the surprise this list exists to
|
|
26935
|
+
* remove. They are found in the source rather than reported by the render so
|
|
26936
|
+
* that checking a document never costs a parse.
|
|
26937
|
+
*/
|
|
26938
|
+
const FENCE = /^\s{0,3}(`{3,}|~{3,})/;
|
|
26939
|
+
const HEADING = /^\s{0,3}(#{1,6})\s*(.*)$/;
|
|
26940
|
+
const TABLE_ROW = /^\s{0,3}\|.*\|\s*$/;
|
|
26941
|
+
const RAW_HTML = /<\/?[a-z][a-z0-9-]*(\s[^<>]*)?\/?>/i;
|
|
26942
|
+
const IMAGE = /!\[[^\]]*\]\(/;
|
|
26943
|
+
/** Four or more of a wrapper's character: a wrap applied over its own output. */
|
|
26944
|
+
const STACKED = /(\*{4,}|_{4,}|~{4,})/;
|
|
26945
|
+
/** `[text](` with no closing paren on the same line. */
|
|
26946
|
+
const DANGLING_LINK = /\[[^\]]*\]\([^)]*$/;
|
|
26947
|
+
/** A table row's cell count, ignoring the leading and trailing pipes. */
|
|
26948
|
+
function cellCount(line) {
|
|
26949
|
+
const trimmed = line.trim().replace(/^\|/, '').replace(/\|$/, '');
|
|
26950
|
+
// An escaped pipe is content, not a cell boundary.
|
|
26951
|
+
return trimmed.split(/(?<!\\)\|/).length;
|
|
26952
|
+
}
|
|
26953
|
+
function problem(kind, line, text) {
|
|
26954
|
+
return { kind, line, text: text.trim().slice(0, 120) };
|
|
26955
|
+
}
|
|
26956
|
+
/**
|
|
26957
|
+
* Markdown in, everything the renderer will quietly do differently out.
|
|
26958
|
+
*
|
|
26959
|
+
* An empty document has no problems — a document nobody has written yet is not
|
|
26960
|
+
* a broken one.
|
|
26961
|
+
*/
|
|
26962
|
+
function checkDoc(markdown) {
|
|
26963
|
+
if (!markdown.trim())
|
|
26964
|
+
return [];
|
|
26965
|
+
const lines = markdown.split('\n');
|
|
26966
|
+
const problems = [];
|
|
26967
|
+
let fenceMarker;
|
|
26968
|
+
let fenceLine = 0;
|
|
26969
|
+
let fenceBody = 0;
|
|
26970
|
+
let tableHeaderCells = 0;
|
|
26971
|
+
let inTable = false;
|
|
26972
|
+
lines.forEach((line, index) => {
|
|
26973
|
+
const number = index + 1;
|
|
26974
|
+
const fence = FENCE.exec(line);
|
|
26975
|
+
if (fence) {
|
|
26976
|
+
if (fenceMarker && line.trim().startsWith(fenceMarker)) {
|
|
26977
|
+
if (fenceBody === 0) {
|
|
26978
|
+
problems.push(problem('empty-fence', fenceLine, line));
|
|
26979
|
+
}
|
|
26980
|
+
fenceMarker = undefined;
|
|
26981
|
+
return;
|
|
26982
|
+
}
|
|
26983
|
+
if (!fenceMarker) {
|
|
26984
|
+
fenceMarker = fence[1][0].repeat(3);
|
|
26985
|
+
fenceLine = number;
|
|
26986
|
+
fenceBody = 0;
|
|
26987
|
+
return;
|
|
26988
|
+
}
|
|
26989
|
+
}
|
|
26990
|
+
if (fenceMarker) {
|
|
26991
|
+
if (line.trim())
|
|
26992
|
+
fenceBody += 1;
|
|
26993
|
+
return;
|
|
26994
|
+
}
|
|
26995
|
+
const heading = HEADING.exec(line);
|
|
26996
|
+
if (heading && !heading[2].trim()) {
|
|
26997
|
+
problems.push(problem('empty-heading', number, line || '#'));
|
|
26998
|
+
}
|
|
26999
|
+
if (TABLE_ROW.test(line)) {
|
|
27000
|
+
if (!inTable) {
|
|
27001
|
+
inTable = true;
|
|
27002
|
+
tableHeaderCells = cellCount(line);
|
|
27003
|
+
}
|
|
27004
|
+
else if (cellCount(line) !== tableHeaderCells) {
|
|
27005
|
+
// The divider counts too: a divider narrower than its header is the
|
|
27006
|
+
// one table mistake `marked` answers by rendering no table at all.
|
|
27007
|
+
problems.push(problem('table-width', number, line));
|
|
27008
|
+
}
|
|
27009
|
+
}
|
|
27010
|
+
else if (inTable && !line.trim()) {
|
|
27011
|
+
inTable = false;
|
|
27012
|
+
tableHeaderCells = 0;
|
|
27013
|
+
}
|
|
27014
|
+
if (STACKED.test(line)) {
|
|
27015
|
+
problems.push(problem('stacked-marker', number, line));
|
|
27016
|
+
}
|
|
27017
|
+
if (DANGLING_LINK.test(line)) {
|
|
27018
|
+
problems.push(problem('dangling-link', number, line));
|
|
27019
|
+
}
|
|
27020
|
+
if (IMAGE.test(line)) {
|
|
27021
|
+
problems.push(problem('dropped-image', number, line));
|
|
27022
|
+
}
|
|
27023
|
+
if (RAW_HTML.test(line)) {
|
|
27024
|
+
problems.push(problem('dropped-html', number, line));
|
|
27025
|
+
}
|
|
27026
|
+
});
|
|
27027
|
+
if (fenceMarker) {
|
|
27028
|
+
problems.push(problem('unclosed-fence', fenceLine, lines[fenceLine - 1]));
|
|
27029
|
+
}
|
|
27030
|
+
return problems.sort((a, b) => a.line - b.line);
|
|
27031
|
+
}
|
|
27032
|
+
/** The translation key behind a problem's message, e.g. `doc-problem-table-width`. */
|
|
27033
|
+
function docProblemKey(kind) {
|
|
27034
|
+
return `doc-problem-${kind}`;
|
|
27035
|
+
}
|
|
27036
|
+
/** Where a problem sits in the source, for a click that moves the caret. */
|
|
27037
|
+
function offsetOfLine(markdown, line) {
|
|
27038
|
+
const lines = markdown.split('\n');
|
|
27039
|
+
const upTo = Math.min(Math.max(line, 1), lines.length) - 1;
|
|
27040
|
+
return lines.slice(0, upTo).reduce((sum, text) => sum + text.length + 1, 0);
|
|
27041
|
+
}
|
|
27042
|
+
|
|
27043
|
+
/**
|
|
27044
|
+
* Authors one DocAsset: the markdown on the left, what `m-doc` makes of it on
|
|
27045
|
+
* the right.
|
|
27046
|
+
*
|
|
27047
|
+
* Source plus preview rather than WYSIWYG — a contenteditable surface needs an
|
|
27048
|
+
* inverse HTML→markdown transform that has to agree with the parser forever,
|
|
27049
|
+
* and the preview here *is* the parser, so the two cannot drift.
|
|
27050
|
+
*
|
|
27051
|
+
* A ControlValueAccessor from the first day: that is the whole of what lets a
|
|
27052
|
+
* FieldControl bind one later without this component changing. It holds no
|
|
27053
|
+
* assets, fetches nothing and knows no tiers — the markdown arrives through the
|
|
27054
|
+
* form and leaves the same way.
|
|
27055
|
+
*
|
|
27056
|
+
* Of an AI exchange it draws one thing: the proposal, in the preview pane,
|
|
27057
|
+
* with the two buttons that answer it. Asking for one is not an editor state
|
|
27058
|
+
* at all — the instruction, the clarifying question and the outline to confirm
|
|
27059
|
+
* are a request, and a request is drawn by the host in its own docked
|
|
27060
|
+
* SidePanel beside this one, where no pane here is spent on it (m-one-ui ADR
|
|
27061
|
+
* 0048, ADR 0147). A host that binds no proposal shows no AI at all.
|
|
27062
|
+
*/
|
|
27063
|
+
class DocEditorComponent {
|
|
27064
|
+
groups = DOC_TOOLBAR_GROUPS;
|
|
27065
|
+
icons = DOC_ACTION_ICONS;
|
|
27066
|
+
docActionKey = docActionKey;
|
|
27067
|
+
translate = inject(TranslateService);
|
|
27068
|
+
value = signal('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
27069
|
+
disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
27070
|
+
/** Narrow screens show one pane at a time; wide ones show both. */
|
|
27071
|
+
previewOnly = signal(false, ...(ngDevMode ? [{ debugName: "previewOnly" }] : /* istanbul ignore next */ []));
|
|
27072
|
+
/**
|
|
27073
|
+
* Markdown awaiting a verdict. The one piece of an AI exchange the editor
|
|
27074
|
+
* draws, because it is the one piece that is an editor state: it renders in
|
|
27075
|
+
* the preview pane while the textarea keeps the document underneath, so
|
|
27076
|
+
* dropping it is structurally a no-op rather than an undo that has to work.
|
|
27077
|
+
*
|
|
27078
|
+
* Everything before it — the instruction, the one clarifying question, the
|
|
27079
|
+
* outline to confirm — is a request the host asks for in its own docked
|
|
27080
|
+
* SidePanel, where no pane of this editor is involved (m-one-ui ADR 0147).
|
|
27081
|
+
*/
|
|
27082
|
+
proposal = input(undefined, ...(ngDevMode ? [{ debugName: "proposal" }] : /* istanbul ignore next */ []));
|
|
27083
|
+
proposalResolved = output();
|
|
27084
|
+
constructor() {
|
|
27085
|
+
// The panes show one surface at a time, and a proposal is something to
|
|
27086
|
+
// read: arriving while the source is up, it would otherwise be an offer
|
|
27087
|
+
// rendered in a pane the editor is hiding.
|
|
27088
|
+
effect(() => {
|
|
27089
|
+
if (this.proposal())
|
|
27090
|
+
this.previewOnly.set(true);
|
|
27091
|
+
});
|
|
27092
|
+
}
|
|
27093
|
+
source = viewChild('source', ...(ngDevMode ? [{ debugName: "source" }] : /* istanbul ignore next */ []));
|
|
27094
|
+
/**
|
|
27095
|
+
* The document's own field. A `ln` Field rather than a bare element so the
|
|
27096
|
+
* editor is painted by the theme like every other input, with no label and
|
|
27097
|
+
* no error list: the problems are drawn below the panes, by line.
|
|
27098
|
+
*/
|
|
27099
|
+
sourceConfig = computed(() => ({
|
|
27100
|
+
name: 'doc_source',
|
|
27101
|
+
type: InputType.TEXTAREA,
|
|
27102
|
+
placeholder: 'document',
|
|
27103
|
+
spellcheck: false,
|
|
27104
|
+
// Grows with the document. The floor is the pane, so a short document
|
|
27105
|
+
// still fills the panel; a long one pushes the panes into their own
|
|
27106
|
+
// scroll rather than a scrollbar inside a field inside a panel.
|
|
27107
|
+
autoGrow: true,
|
|
27108
|
+
}), ...(ngDevMode ? [{ debugName: "sourceConfig" }] : /* istanbul ignore next */ []));
|
|
27109
|
+
/**
|
|
27110
|
+
* What the renderer will quietly do differently, recomputed as the document
|
|
27111
|
+
* is typed. Deterministic and local: no provider, no network (ADR 0035).
|
|
27112
|
+
*/
|
|
27113
|
+
problems = computed(() => checkDoc(this.value()), ...(ngDevMode ? [{ debugName: "problems" }] : /* istanbul ignore next */ []));
|
|
27114
|
+
onChange = () => undefined;
|
|
27115
|
+
onTouched = () => undefined;
|
|
27116
|
+
writeValue(value) {
|
|
27117
|
+
this.value.set(value ?? '');
|
|
27118
|
+
}
|
|
27119
|
+
registerOnChange(fn) {
|
|
27120
|
+
this.onChange = fn;
|
|
27121
|
+
}
|
|
27122
|
+
registerOnTouched(fn) {
|
|
27123
|
+
this.onTouched = fn;
|
|
27124
|
+
}
|
|
27125
|
+
setDisabledState(isDisabled) {
|
|
27126
|
+
this.disabled.set(isDisabled);
|
|
27127
|
+
}
|
|
27128
|
+
onBlur = () => this.onTouched();
|
|
27129
|
+
togglePreview = () => this.previewOnly.update((only) => !only);
|
|
27130
|
+
/**
|
|
27131
|
+
* Accept is the only gesture that moves a proposal into the document. Until
|
|
27132
|
+
* then the textarea is authoritative, so dropping one is structurally a
|
|
27133
|
+
* no-op rather than an undo that has to work.
|
|
27134
|
+
*/
|
|
27135
|
+
acceptProposal = () => {
|
|
27136
|
+
const offer = this.proposal();
|
|
27137
|
+
if (!offer)
|
|
27138
|
+
return;
|
|
27139
|
+
this.commit(offer.markdown);
|
|
27140
|
+
this.source()?.writeSelection(offer.markdown, offer.markdown.length, offer.markdown.length);
|
|
27141
|
+
this.proposalResolved.emit(true);
|
|
27142
|
+
};
|
|
27143
|
+
dropProposal = () => this.proposalResolved.emit(false);
|
|
27144
|
+
/** Line and message on one Button, the offending text beside it. */
|
|
27145
|
+
problemLabel = (problem) => `${problem.line} · ${this.translate.translate(docProblemKey(problem.kind))}`;
|
|
27146
|
+
/** A problem points at a line, and clicking it puts the caret there. */
|
|
27147
|
+
goTo = (problem) => {
|
|
27148
|
+
const field = this.source();
|
|
27149
|
+
if (!field)
|
|
27150
|
+
return;
|
|
27151
|
+
const offset = offsetOfLine(this.value(), problem.line);
|
|
27152
|
+
this.previewOnly.set(false);
|
|
27153
|
+
field.writeSelection(this.value(), offset, offset + problem.text.length);
|
|
27154
|
+
};
|
|
27155
|
+
/** The textarea owns the caret, so an edit reads it and hands it back. */
|
|
27156
|
+
edit = (action) => {
|
|
27157
|
+
const field = this.source();
|
|
27158
|
+
const selection = field?.selection();
|
|
27159
|
+
if (!field || !selection || this.disabled())
|
|
27160
|
+
return;
|
|
27161
|
+
const next = applyDocEdit(action, selection);
|
|
27162
|
+
this.commit(next.value);
|
|
27163
|
+
field.writeSelection(next.value, next.start, next.end);
|
|
27164
|
+
};
|
|
27165
|
+
commit(value) {
|
|
27166
|
+
this.value.set(value);
|
|
27167
|
+
this.onChange(value);
|
|
27168
|
+
}
|
|
27169
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DocEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
27170
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DocEditorComponent, isStandalone: true, selector: "m-doc-editor", inputs: { proposal: { classPropertyName: "proposal", publicName: "proposal", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { proposalResolved: "proposalResolved" }, providers: [
|
|
27171
|
+
{
|
|
27172
|
+
provide: NG_VALUE_ACCESSOR,
|
|
27173
|
+
useExisting: forwardRef(() => DocEditorComponent),
|
|
27174
|
+
multi: true,
|
|
27175
|
+
},
|
|
27176
|
+
], viewQueries: [{ propertyName: "source", first: true, predicate: ["source"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
27177
|
+
<div class="m-doc-editor" [class.m-doc-editor--preview]="previewOnly()">
|
|
27178
|
+
<div class="m-doc-editor__toolbar">
|
|
27179
|
+
<!-- The edits belong to the source; reading is not a thing to edit. -->
|
|
27180
|
+
@if (!previewOnly()) {
|
|
27181
|
+
@for (group of groups; track $index) {
|
|
27182
|
+
@if (!$first) {
|
|
27183
|
+
<span class="m-doc-editor__divider"></span>
|
|
27184
|
+
}
|
|
27185
|
+
@for (action of group; track action) {
|
|
27186
|
+
<m-button
|
|
27187
|
+
[attr.data-doc-action]="action"
|
|
27188
|
+
variant="ghost"
|
|
27189
|
+
[icon]="icons[action]"
|
|
27190
|
+
[one]="true"
|
|
27191
|
+
iconOnly="true"
|
|
27192
|
+
[label]="docActionKey(action) | translate"
|
|
27193
|
+
noTranslate="true"
|
|
27194
|
+
[disabled]="disabled() || !!proposal()"
|
|
27195
|
+
(clicked)="edit(action)"
|
|
27196
|
+
/>
|
|
27197
|
+
}
|
|
27198
|
+
}
|
|
27199
|
+
|
|
27200
|
+
<span class="m-doc-editor__divider"></span>
|
|
27201
|
+
}
|
|
27202
|
+
<m-button
|
|
27203
|
+
variant="ghost"
|
|
27204
|
+
[icon]="previewOnly() ? 'pencil' : 'eye'"
|
|
27205
|
+
[one]="true"
|
|
27206
|
+
iconOnly="true"
|
|
27207
|
+
[label]="(previewOnly() ? 'write' : 'preview') | translate"
|
|
27208
|
+
noTranslate="true"
|
|
27209
|
+
(clicked)="togglePreview()"
|
|
27210
|
+
/>
|
|
27211
|
+
|
|
27212
|
+
<!--
|
|
27213
|
+
Whatever the host hangs on the document itself — the panel's own menu
|
|
27214
|
+
of languages, AI and delete. It rides the toolbar because it is one
|
|
27215
|
+
more icon over the same document, not a row of its own above it.
|
|
27216
|
+
-->
|
|
27217
|
+
<div class="m-doc-editor__host-actions">
|
|
27218
|
+
<ng-content select="[docActions]" />
|
|
27219
|
+
</div>
|
|
27220
|
+
</div>
|
|
27221
|
+
|
|
27222
|
+
<div class="m-doc-editor__panes">
|
|
27223
|
+
<m-textarea-input
|
|
27224
|
+
#source
|
|
27225
|
+
[config]="sourceConfig()"
|
|
27226
|
+
[value]="value()"
|
|
27227
|
+
[disabled]="disabled()"
|
|
27228
|
+
(valueChange)="commit($event)"
|
|
27229
|
+
(touchedChange)="onBlur()"
|
|
27230
|
+
/>
|
|
27231
|
+
|
|
27232
|
+
<div class="m-doc-editor__preview">
|
|
27233
|
+
@if (proposal(); as offer) {
|
|
27234
|
+
<!--
|
|
27235
|
+
The verdict rides the pane the proposal is rendered in: the offer
|
|
27236
|
+
and the two buttons that answer it are one thing, and a verdict
|
|
27237
|
+
asked for from another surface is a verdict about something the
|
|
27238
|
+
User has to look somewhere else to read.
|
|
27239
|
+
-->
|
|
27240
|
+
<div class="m-doc-editor__proposal" data-doc-ai="proposal">
|
|
27241
|
+
<p class="m-doc-editor__preview-banner">
|
|
27242
|
+
{{
|
|
27243
|
+
(offer.origin === 'fix'
|
|
27244
|
+
? 'doc-ai-proposal-fix'
|
|
27245
|
+
: 'doc-ai-proposal-write'
|
|
27246
|
+
) | translate
|
|
27247
|
+
}}
|
|
27248
|
+
</p>
|
|
27249
|
+
<m-section-button-group>
|
|
27250
|
+
<m-button
|
|
27251
|
+
variant="primary"
|
|
27252
|
+
[label]="'doc-ai-accept' | translate"
|
|
27253
|
+
noTranslate="true"
|
|
27254
|
+
(clicked)="acceptProposal()"
|
|
27255
|
+
/>
|
|
27256
|
+
<m-button
|
|
27257
|
+
variant="ghost"
|
|
27258
|
+
[label]="'doc-ai-drop' | translate"
|
|
27259
|
+
noTranslate="true"
|
|
27260
|
+
(clicked)="dropProposal()"
|
|
27261
|
+
/>
|
|
27262
|
+
</m-section-button-group>
|
|
27263
|
+
</div>
|
|
27264
|
+
<m-doc [designSrc]="offer.markdown" />
|
|
27265
|
+
} @else {
|
|
27266
|
+
<m-doc [designSrc]="value()" />
|
|
27267
|
+
}
|
|
27268
|
+
</div>
|
|
27269
|
+
</div>
|
|
27270
|
+
|
|
27271
|
+
@if (problems().length) {
|
|
27272
|
+
<ul class="m-doc-editor__problems" data-doc-problems>
|
|
27273
|
+
@for (problem of problems(); track $index) {
|
|
27274
|
+
<li class="m-doc-editor__problem" [attr.data-doc-problem]="problem.kind">
|
|
27275
|
+
<m-button
|
|
27276
|
+
variant="ghost"
|
|
27277
|
+
icon="alert-circle"
|
|
27278
|
+
[one]="true"
|
|
27279
|
+
[label]="problemLabel(problem)"
|
|
27280
|
+
noTranslate="true"
|
|
27281
|
+
(clicked)="goTo(problem)"
|
|
27282
|
+
/>
|
|
27283
|
+
<code>{{ problem.text }}</code>
|
|
27284
|
+
</li>
|
|
27285
|
+
}
|
|
27286
|
+
</ul>
|
|
27287
|
+
}
|
|
27288
|
+
</div>
|
|
27289
|
+
`, isInline: true, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%;height:100%;min-height:0}.m-doc-editor{display:flex;flex-direction:column;gap:.5rem;width:100%;height:100%;min-height:0}.m-doc-editor__toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;flex:0 0 auto}.m-doc-editor__host-actions{display:flex;align-items:center;margin-left:auto}.m-doc-editor__divider{width:1px;align-self:stretch;margin:.15rem .35rem;background:var(--m-backdrop-border)}.m-doc-editor__proposal{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.4rem;margin-bottom:.5rem;padding-bottom:.5rem;border-bottom:var(--m-input-border-width, 1px) solid color-mix(in srgb,var(--m-text) 18%,var(--m-background))}.m-doc-editor__preview-banner{margin:0;font-size:.75rem;opacity:.75}.m-doc-editor__panes{display:grid;grid-template-columns:1fr;grid-template-rows:minmax(0,1fr);gap:.75rem;flex:1 1 auto;min-height:0;overflow:auto}.m-doc-editor__preview{height:100%;min-height:0;padding:.75rem;border:var(--m-input-border-width, 1px) solid color-mix(in srgb,var(--m-text) 18%,var(--m-background));border-radius:.5rem;overflow:auto}.m-doc-editor__problems{flex:0 0 auto;max-height:9rem;margin:0;padding:0;overflow-y:auto;list-style:none}.m-doc-editor__problem{display:flex;align-items:center;gap:.4rem;width:100%;padding:.25rem .35rem;border:0;border-radius:.3rem;background:transparent;color:inherit;font-size:.75rem;text-align:left;cursor:pointer}.m-doc-editor__problem:hover{background:color-mix(in srgb,var(--m-focus) 6%,var(--m-background))}.m-doc-editor__problem code{opacity:.6;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.m-doc-editor__problem-line{min-width:1.5rem;opacity:.6}.m-doc-editor--preview .m-doc-editor__source{display:none}.m-doc-editor:not(.m-doc-editor--preview) .m-doc-editor__preview{display:none}m-textarea-input{min-height:100%;--m-textarea-input-height: 100%;--m-textarea-input-wrapper-height: 100%;font-family:monospace;font-size:.9rem}\n"], dependencies: [{ kind: "component", type: DocComponent, selector: "m-doc", inputs: ["name", "remote", "url", "designSrc"] }, { kind: "component", type: ButtonComponent, selector: "m-button,m-one-button", inputs: ["config", "color", "labelClass", "fullWidth", "nav", "navParams", "href", "disabled", "variant", "name", "baseUrl", "one", "remote", "label", "noTranslate", "params", "noNative", "icon", "isRightIcon", "iconOnly", "stacked", "imgSrc", "nonClickable", "inverted", "isSubmit", "tabindex"], outputs: ["configChange", "clicked"] }, { kind: "component", type: SectionButtonGroupComponent, selector: "m-section-button-group", inputs: ["vertical", "align", "variant", "size", "fullWidth"] }, { kind: "component", type: TextareaInputComponent, selector: "m-textarea-input" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
27290
|
+
}
|
|
27291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DocEditorComponent, decorators: [{
|
|
27292
|
+
type: Component,
|
|
27293
|
+
args: [{ selector: 'm-doc-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
27294
|
+
DocComponent,
|
|
27295
|
+
ButtonComponent,
|
|
27296
|
+
SectionButtonGroupComponent,
|
|
27297
|
+
TextareaInputComponent,
|
|
27298
|
+
TranslatePipe,
|
|
27299
|
+
], providers: [
|
|
27300
|
+
{
|
|
27301
|
+
provide: NG_VALUE_ACCESSOR,
|
|
27302
|
+
useExisting: forwardRef(() => DocEditorComponent),
|
|
27303
|
+
multi: true,
|
|
27304
|
+
},
|
|
27305
|
+
], template: `
|
|
27306
|
+
<div class="m-doc-editor" [class.m-doc-editor--preview]="previewOnly()">
|
|
27307
|
+
<div class="m-doc-editor__toolbar">
|
|
27308
|
+
<!-- The edits belong to the source; reading is not a thing to edit. -->
|
|
27309
|
+
@if (!previewOnly()) {
|
|
27310
|
+
@for (group of groups; track $index) {
|
|
27311
|
+
@if (!$first) {
|
|
27312
|
+
<span class="m-doc-editor__divider"></span>
|
|
27313
|
+
}
|
|
27314
|
+
@for (action of group; track action) {
|
|
27315
|
+
<m-button
|
|
27316
|
+
[attr.data-doc-action]="action"
|
|
27317
|
+
variant="ghost"
|
|
27318
|
+
[icon]="icons[action]"
|
|
27319
|
+
[one]="true"
|
|
27320
|
+
iconOnly="true"
|
|
27321
|
+
[label]="docActionKey(action) | translate"
|
|
27322
|
+
noTranslate="true"
|
|
27323
|
+
[disabled]="disabled() || !!proposal()"
|
|
27324
|
+
(clicked)="edit(action)"
|
|
27325
|
+
/>
|
|
27326
|
+
}
|
|
27327
|
+
}
|
|
27328
|
+
|
|
27329
|
+
<span class="m-doc-editor__divider"></span>
|
|
27330
|
+
}
|
|
27331
|
+
<m-button
|
|
27332
|
+
variant="ghost"
|
|
27333
|
+
[icon]="previewOnly() ? 'pencil' : 'eye'"
|
|
27334
|
+
[one]="true"
|
|
27335
|
+
iconOnly="true"
|
|
27336
|
+
[label]="(previewOnly() ? 'write' : 'preview') | translate"
|
|
27337
|
+
noTranslate="true"
|
|
27338
|
+
(clicked)="togglePreview()"
|
|
27339
|
+
/>
|
|
27340
|
+
|
|
27341
|
+
<!--
|
|
27342
|
+
Whatever the host hangs on the document itself — the panel's own menu
|
|
27343
|
+
of languages, AI and delete. It rides the toolbar because it is one
|
|
27344
|
+
more icon over the same document, not a row of its own above it.
|
|
27345
|
+
-->
|
|
27346
|
+
<div class="m-doc-editor__host-actions">
|
|
27347
|
+
<ng-content select="[docActions]" />
|
|
27348
|
+
</div>
|
|
27349
|
+
</div>
|
|
27350
|
+
|
|
27351
|
+
<div class="m-doc-editor__panes">
|
|
27352
|
+
<m-textarea-input
|
|
27353
|
+
#source
|
|
27354
|
+
[config]="sourceConfig()"
|
|
27355
|
+
[value]="value()"
|
|
27356
|
+
[disabled]="disabled()"
|
|
27357
|
+
(valueChange)="commit($event)"
|
|
27358
|
+
(touchedChange)="onBlur()"
|
|
27359
|
+
/>
|
|
27360
|
+
|
|
27361
|
+
<div class="m-doc-editor__preview">
|
|
27362
|
+
@if (proposal(); as offer) {
|
|
27363
|
+
<!--
|
|
27364
|
+
The verdict rides the pane the proposal is rendered in: the offer
|
|
27365
|
+
and the two buttons that answer it are one thing, and a verdict
|
|
27366
|
+
asked for from another surface is a verdict about something the
|
|
27367
|
+
User has to look somewhere else to read.
|
|
27368
|
+
-->
|
|
27369
|
+
<div class="m-doc-editor__proposal" data-doc-ai="proposal">
|
|
27370
|
+
<p class="m-doc-editor__preview-banner">
|
|
27371
|
+
{{
|
|
27372
|
+
(offer.origin === 'fix'
|
|
27373
|
+
? 'doc-ai-proposal-fix'
|
|
27374
|
+
: 'doc-ai-proposal-write'
|
|
27375
|
+
) | translate
|
|
27376
|
+
}}
|
|
27377
|
+
</p>
|
|
27378
|
+
<m-section-button-group>
|
|
27379
|
+
<m-button
|
|
27380
|
+
variant="primary"
|
|
27381
|
+
[label]="'doc-ai-accept' | translate"
|
|
27382
|
+
noTranslate="true"
|
|
27383
|
+
(clicked)="acceptProposal()"
|
|
27384
|
+
/>
|
|
27385
|
+
<m-button
|
|
27386
|
+
variant="ghost"
|
|
27387
|
+
[label]="'doc-ai-drop' | translate"
|
|
27388
|
+
noTranslate="true"
|
|
27389
|
+
(clicked)="dropProposal()"
|
|
27390
|
+
/>
|
|
27391
|
+
</m-section-button-group>
|
|
27392
|
+
</div>
|
|
27393
|
+
<m-doc [designSrc]="offer.markdown" />
|
|
27394
|
+
} @else {
|
|
27395
|
+
<m-doc [designSrc]="value()" />
|
|
27396
|
+
}
|
|
27397
|
+
</div>
|
|
27398
|
+
</div>
|
|
27399
|
+
|
|
27400
|
+
@if (problems().length) {
|
|
27401
|
+
<ul class="m-doc-editor__problems" data-doc-problems>
|
|
27402
|
+
@for (problem of problems(); track $index) {
|
|
27403
|
+
<li class="m-doc-editor__problem" [attr.data-doc-problem]="problem.kind">
|
|
27404
|
+
<m-button
|
|
27405
|
+
variant="ghost"
|
|
27406
|
+
icon="alert-circle"
|
|
27407
|
+
[one]="true"
|
|
27408
|
+
[label]="problemLabel(problem)"
|
|
27409
|
+
noTranslate="true"
|
|
27410
|
+
(clicked)="goTo(problem)"
|
|
27411
|
+
/>
|
|
27412
|
+
<code>{{ problem.text }}</code>
|
|
27413
|
+
</li>
|
|
27414
|
+
}
|
|
27415
|
+
</ul>
|
|
27416
|
+
}
|
|
27417
|
+
</div>
|
|
27418
|
+
`, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}:host{display:block;width:100%;height:100%;min-height:0}.m-doc-editor{display:flex;flex-direction:column;gap:.5rem;width:100%;height:100%;min-height:0}.m-doc-editor__toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;flex:0 0 auto}.m-doc-editor__host-actions{display:flex;align-items:center;margin-left:auto}.m-doc-editor__divider{width:1px;align-self:stretch;margin:.15rem .35rem;background:var(--m-backdrop-border)}.m-doc-editor__proposal{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.4rem;margin-bottom:.5rem;padding-bottom:.5rem;border-bottom:var(--m-input-border-width, 1px) solid color-mix(in srgb,var(--m-text) 18%,var(--m-background))}.m-doc-editor__preview-banner{margin:0;font-size:.75rem;opacity:.75}.m-doc-editor__panes{display:grid;grid-template-columns:1fr;grid-template-rows:minmax(0,1fr);gap:.75rem;flex:1 1 auto;min-height:0;overflow:auto}.m-doc-editor__preview{height:100%;min-height:0;padding:.75rem;border:var(--m-input-border-width, 1px) solid color-mix(in srgb,var(--m-text) 18%,var(--m-background));border-radius:.5rem;overflow:auto}.m-doc-editor__problems{flex:0 0 auto;max-height:9rem;margin:0;padding:0;overflow-y:auto;list-style:none}.m-doc-editor__problem{display:flex;align-items:center;gap:.4rem;width:100%;padding:.25rem .35rem;border:0;border-radius:.3rem;background:transparent;color:inherit;font-size:.75rem;text-align:left;cursor:pointer}.m-doc-editor__problem:hover{background:color-mix(in srgb,var(--m-focus) 6%,var(--m-background))}.m-doc-editor__problem code{opacity:.6;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.m-doc-editor__problem-line{min-width:1.5rem;opacity:.6}.m-doc-editor--preview .m-doc-editor__source{display:none}.m-doc-editor:not(.m-doc-editor--preview) .m-doc-editor__preview{display:none}m-textarea-input{min-height:100%;--m-textarea-input-height: 100%;--m-textarea-input-wrapper-height: 100%;font-family:monospace;font-size:.9rem}\n"] }]
|
|
27419
|
+
}], ctorParameters: () => [], propDecorators: { proposal: [{ type: i0.Input, args: [{ isSignal: true, alias: "proposal", required: false }] }], proposalResolved: [{ type: i0.Output, args: ["proposalResolved"] }], source: [{ type: i0.ViewChild, args: ['source', { isSignal: true }] }] } });
|
|
27420
|
+
|
|
27421
|
+
/**
|
|
27422
|
+
* The shapes an AI-assisted document write passes through, named here so the
|
|
27423
|
+
* editor can draw them without knowing who answers.
|
|
27424
|
+
*
|
|
27425
|
+
* `libs/one` holds no endpoint, no token and no prompt: those are workspace
|
|
27426
|
+
* state owned by the editor app (m-one-ui ADR 0048), and this library ships
|
|
27427
|
+
* inside every emitted app. What lives here is the vocabulary of the exchange
|
|
27428
|
+
* — an instruction goes out, an outline comes back for the User to confirm,
|
|
27429
|
+
* and a proposal arrives that the User accepts or drops (m-one-ui ADR 0147).
|
|
27430
|
+
*
|
|
27431
|
+
* Only `DocProposal` reaches `m-doc-editor`. The instruction, the question and
|
|
27432
|
+
* the outline are drawn by the host's own docked SidePanel, and these shapes
|
|
27433
|
+
* are named here because the two surfaces have to agree on them, not because
|
|
27434
|
+
* the editor draws them.
|
|
27435
|
+
*/
|
|
27436
|
+
|
|
26450
27437
|
var TableFilterCondition;
|
|
26451
27438
|
(function (TableFilterCondition) {
|
|
26452
27439
|
TableFilterCondition["Eq"] = "eq";
|
|
@@ -36994,5 +37981,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
36994
37981
|
* Generated bundle index. Do not edit.
|
|
36995
37982
|
*/
|
|
36996
37983
|
|
|
36997
|
-
export { ColComponent as $, ACCESS_DOMAINS as A, ButtonComponent as B, Assets as C, AuthActivityPageComponent as D, AuthApiService as E, AuthStore as F, AutosizeDirective as G, HeaderComponent$1 as H, InputType as I, BadgeComponent as J, BandingComponent as K, LabelComponent as L, MODAL_REF as M, BaseArrayInputComponent as N, BaseRootWebComponent as O, BaseWebComponent as P, ButtonGroupComponent as Q, RangeInputComponent as R, COMPONENT_INPUT_REGISTRY as S, TranslatePipe as T, CardComponent as U, CardWrapperComponent as V, CarouselComponent as W, ChartComponent as X, ChatBubbleComponent as Y, CheckboxInputComponent as Z, ClearableInputComponent as _, MIN_ZOOM as a, MHeroColorDirective as a$, ColorPickerInputComponent as a0, CommentItemComponent as a1, CommentsApiService as a2, CommentsComponent as a3, CommentsStore as a4, CompactNumberPipe as a5, ComponentInputComponent as a6, ComponentStepperComponent as a7, ConfigComponent as a8, ConfirmComponent as a9, FileService as aA, FileUploadDirective as aB, FileUploadInputComponent as aC, FlexComponent as aD, FlexItemComponent as aE, FormGroupComponent as aF, FrameComponent as aG, FreezeService as aH, GRID_BREAKPOINTS as aI, GetNavService as aJ, HighlightDirective as aK, HttpService as aL, ICON_SOURCE as aM, IS_SIDE_PANEL as aN, IconComponent as aO, ImgComponent as aP, InstrumentScoreComponent as aQ, InterceptorObservables as aR, JumbotronComponent as aS, KeyValueComponent as aT, LAYOUT_ASSET_FOLDER as aU, LOGIN_COMPONENT as aV, LOGIN_STORE as aW, LanguageComponent as aX, ListComponent as aY, LogoComponent as aZ, MAG_SOCKET_EVENT as a_, ContextMenuComponent as aa, CustomIconClass as ab, CustomIconEditComponent as ac, DEFAULT_DENIAL as ad, DEFAULT_FILTER_RANGE_MODE as ae, DEFAULT_FILTER_VARIANT as af, DEFAULT_NAV_PARAM as ag, DEFAULT_NAV_SEGMENT as ah, DEFAULT_SIZE as ai, DashboardCardComponent as aj, DateInputComponent as ak, DatePickerComponent as al, DeviceService as am, DomService as an, Domain as ao, DotGridComponent as ap, DragListDirective as aq, DragListItemDirective as ar, DraggableDirective as as, DropdownInputComponent as at, FILTER_GROUP_CONTEXT as au, FILTER_RANGE_MODES as av, FILTER_VARIANTS as aw, FLEX_VARIANTS as ax, FOLDER_PICK_LISTENER as ay, FORM_ASSET_FOLDER as az, MAX_ZOOM as b, SEARCH_QUERY as b$, MHeroComponent as b0, MODAL_STORE_REF as b1, MRefDirective as b2, MStepComponent as b3, MURL_PARAM as b4, MURL_SEP as b5, ManifestEnrichmentService as b6, MenuComponent as b7, ModalDirective as b8, ModalRef as b9, OPTIONS_SOURCE as bA, OVERLAY_WIDGETS as bB, OneApp as bC, OptionsSourceDirective as bD, OverlayBodyComponent as bE, OverlayRef as bF, OverlayService as bG, PLATFORM_BUTTON_NAV_IDS as bH, PLATFORM_EXTENSIBLE_NAV_IDS as bI, PLATFORM_NAV_MAP as bJ, PLATFORM_ROOT_CHILDREN as bK, PaginationComponent as bL, PanelComponent as bM, PercentagePipe as bN, PlaygroundComponent as bO, PositionDirective as bP, PwaInstallComponent as bQ, ROOT_NAV$1 as bR, RadioGroupComponent as bS, RadioInputComponent as bT, RatingInputComponent as bU, ReactiveElementComponent as bV, RemoteComponent as bW, RemoteLoaderService as bX, ResizeElementComponent as bY, RouteContainer as bZ, RowComponent as b_, ModalStore as ba, MoneyPipe as bb, MultiRangeInputComponent as bc, MurlUrlSerializer as bd, NAV_DEFAULT_MURL as be, NAV_ID_SEP as bf, NAV_MAIN_BUTTONS as bg, NAV_SEGMENT_RE as bh, NAV_STORE_REF as bi, NAV_WC_COMPONENTS as bj, NAV_WIDGET_MAP as bk, NavComponent as bl, NavDetailsComponent as bm, NavHeaderComponent as bn, NavMenuComponent as bo, NavStore as bp, NavTrailComponent as bq, NothingComponent as br, NotificationElementComponent as bs, NotificationGroupComponent as bt, NotificationPopupComponent as bu, NotificationService as bv, NotificationStore as bw, NotificationType as bx, NotificationWidgetComponent as by, ONE_ASSET_BASE_URL as bz, cropRect as c, ThemeDataService as c$, SEARCH_RESULTS_EVENT as c0, SECTION_ACCORDION_GROUP as c1, SECTION_FORM_CONTEXT as c2, SHARED_ICONS as c3, SIZE_CONTEXT as c4, ScoreComponent as c5, ScrollComponent as c6, ScrollService as c7, SearchPanelComponent as c8, SearchStore as c9, SelectorDirective as cA, SettingsSearchBarComponent as cB, SettingsSearchService as cC, ShapeComponent as cD, SharedStoreRegistry as cE, SidePanelDirective as cF, Size as cG, SocketStore as cH, SortComponent as cI, StatComponent as cJ, StepComponent as cK, StepperComponent as cL, StepsComponent as cM, StorageService as cN, StrokeLinecap as cO, StrokeLinejoin as cP, SummaryComponent as cQ, SvgGeneratorComponent as cR, SvgGeneratorService as cS, SvgService as cT, TOTAL_COLUMNS as cU, TRANSLATION_SOURCE as cV, TableComponent as cW, TechnicalMeterComponent as cX, TextInputComponent as cY, TextareaInputComponent as cZ, ThemeComponent as c_, SearchUserPanelComponent as ca, SectionAccordionDirective as cb, SectionAccordionGroupDirective as cc, SectionBackComponent as cd, SectionBadgesComponent as ce, SectionButtonGroupComponent as cf, SectionCardComponent as cg, SectionCarouselComponent as ch, SectionComponent as ci, SectionFilterComponent as cj, SectionFilterGroupComponent as ck, SectionFilterMenuComponent as cl, SectionFilterPanelComponent as cm, SectionFilterRangePanelComponent as cn, SectionFooterComponent as co, SectionFormComponent as cp, SectionFormItemComponent as cq, SectionHeaderComponent as cr, SectionHeroComponent as cs, SectionPaginationComponent as ct, SectionSearchComponent as cu, SectionStepperComponent as cv, SectionTabsComponent as cw, SectionToggleComponent as cx, SectionToggleItemDirective as cy, SelectableCardInputComponent as cz, drawFramed as d, filterNumberList as d$, ThemeService as d0, ThemeStore as d1, TimeAgoPipe as d2, TimelineComponent as d3, ToggleButtonComponent as d4, ToggleInputComponent as d5, ToggleRadioInputComponent as d6, ToolTipDirective as d7, TooltipComponent as d8, TranslateService as d9, calculateRanks as dA, cellText as dB, checkFilterCondition as dC, childNavId as dD, claimDenial as dE, classListSignal as dF, coerceSize as dG, cornerEdge as dH, cornerSide as dI, createMap as dJ, createPlatformNavMap as dK, deriveAvatarGradient as dL, deriveContrastColor as dM, deriveOppositeColor as dN, derivePropertyName as dO, emailValidation as dP, evaluate as dQ, evaluateBool as dR, fieldBoolean as dS, fieldNumber as dT, fieldString as dU, filterHoldsList as dV, filterHoldsOneBound as dW, filterHoldsOptions as dX, filterHoldsRange as dY, filterList as dZ, filterNumber as d_, TreeGridComponent as da, URL_SEP as db, USER_STORE_REF as dc, USER_TAB_MAP as dd, UniverseComponent as de, UserApiService as df, UserAvatarComponent as dg, UserComponent as dh, UserNavComponent as di, UserSettingsComponent as dj, UserStore as dk, WC_ROUTE_CHANGED_EVENT as dl, WC_SEARCH_GROUPS as dm, WIN_USER_TAB_HOOK as dn, WIN_USER_TAB_KEY as dp, WatermarkComponent as dq, WcRouterStore as dr, WrapperInputComponent as ds, anchorNavId as dt, applyColorsToElement as du, assetOptions as dv, bootstrapMagApp as dw, bootstrapPwaInstall as dx, buildWcBaseUrl as dy, calculateLuminance as dz, encodeFramed as e, miniMarkToHtml as e$, filterOne as e0, filterPanelOf as e1, filterPanelWidth as e2, filterRange as e3, filterTreeGridRows as e4, filterValueList as e5, filterValues as e6, flattenTreeGridRows as e7, formatBadgeCount as e8, fullName as e9, isLocalhost as eA, isNavInstanceConfig as eB, isNavMenuConfig as eC, isNavRowsConfig as eD, isNavVisibilityConfig as eE, isPlatformNavId as eF, isSize as eG, isTierPreview as eH, isUrlLocalhost as eI, isValidNavId as eJ, isValidNavSegment as eK, isWebComponent as eL, linkToId as eM, linkToNav as eN, loadingActions as eO, mInterceptor as eP, manualValidation as eQ, matchFieldValidation as eR, maxLengthValidation as eS, maxValidation as eT, mergePlatformNav as eU, mergeUnique as eV, mergeUniqueBy as eW, mergeUniqueWith as eX, minAgeValidation as eY, minLengthValidation as eZ, minValidation as e_, generateClipPath as ea, generateTransform as eb, getClassList as ec, getProperty as ed, getScrollParent as ee, getTierFromPreviewPath as ef, getTreeGridRow as eg, getUniqueId as eh, getValue as ei, hasErrorComputed as ej, hexToRgb as ek, hslToRgb$1 as el, initMagmoniumApp as em, initialNotificationState as en, initialState$2 as eo, initials as ep, injectAuthenticate as eq, injectDefaultDenial as er, injectInstallApp as es, injectParentSize as et, injectScrollSticky as eu, isButtonName as ev, isCancelledComputed as ew, isExtensiblePlatformNavId as ex, isJson as ey, isLoadingComputed as ez, clampFraming as f, navIdChain as f0, navIdFor as f1, navIdSegment as f2, navIdToRoutePath as f3, navIdToSegments as f4, navParamOf as f5, navToId as f6, navVisibilityGuard as f7, normalizeAssetOptions as f8, parentNavId as f9, resolveIconSize as fA, resolvePallet as fB, resolvePatternRules as fC, resolveSize as fD, rgbToHex as fE, rgbToHsl as fF, rowHasChildren as fG, samePatterns as fH, segmentsToNavId as fI, setProperty as fJ, setTreeGridChildren as fK, settingsWidgets as fL, shouldShowBadge as fM, splitNavId as fN, splitOnMatch as fO, stringToColor as fP, toAttrBool as fQ, toAttrNumber as fR, toCssLength as fS, toHostNavId as fT, toLength$1 as fU, toLocalNavId as fV, toggleTreeGridRow as fW, unfetchedPlatformNav as fX, urlValidation as fY, parseAddress as fa, parseColor as fb, parsePatternNames as fc, patternValidation as fd, patternsValidation as fe, permissionRefusal as ff, platformNavWidgets as fg, privateGuard as fh, processImageToSvg as fi, provideAppContext as fj, provideMagAppConfig as fk, provideMagWcConfig as fl, provideMagWcRoutes as fm, provideModalComponents as fn, provideMurlUrlSerializer as fo, provideNavWidgets as fp, provideOverlayWidgets as fq, providePlatformNavWidgets as fr, provideSearch as fs, provideSizeContext as ft, provideUserTabs as fu, publicGuard as fv, readFieldPatterns as fw, renderAddress as fx, requiredValidation as fy, resolveConfigAsset as fz, BaseInputComponent as g, BaseTextInputComponent as h, initialFraming as i, TextOutputComponent as j, IS_DESIGN_MODE as k, APP_CONTEXT_REF as l, ASSET_BASE_URL as m, AccordionBodyDirective as n, outputSize as o, parseRatio as p, AccordionComponent as q, renameForType as r, AccordionGroupComponent as s, ActionComponent as t, AnimatedGraphsComponent as u, AppCardComponent as v, AppRelationType as w, AppTileComponent as x, AssetStore as y, AssetUrlPipe as z };
|
|
36998
|
-
//# sourceMappingURL=magmonium-one-magmonium-one-
|
|
37984
|
+
export { ColComponent as $, ACCESS_DOMAINS as A, ButtonComponent as B, Assets as C, AuthActivityPageComponent as D, AuthApiService as E, AuthStore as F, AutosizeDirective as G, HeaderComponent$1 as H, InputType as I, BadgeComponent as J, BandingComponent as K, LabelComponent as L, MODAL_REF as M, BaseArrayInputComponent as N, BaseRootWebComponent as O, BaseWebComponent as P, ButtonGroupComponent as Q, RangeInputComponent as R, COMPONENT_INPUT_REGISTRY as S, TranslatePipe as T, CardComponent as U, CardWrapperComponent as V, CarouselComponent as W, ChartComponent as X, ChatBubbleComponent as Y, CheckboxInputComponent as Z, ClearableInputComponent as _, MIN_ZOOM as a, LAYOUT_ASSET_FOLDER as a$, ColorPickerInputComponent as a0, CommentItemComponent as a1, CommentsApiService as a2, CommentsComponent as a3, CommentsStore as a4, CompactNumberPipe as a5, ComponentInputComponent as a6, ComponentStepperComponent as a7, ConfigComponent as a8, ConfirmComponent as a9, DropdownInputComponent as aA, FILTER_GROUP_CONTEXT as aB, FILTER_RANGE_MODES as aC, FILTER_VARIANTS as aD, FLEX_VARIANTS as aE, FOLDER_PICK_LISTENER as aF, FORM_ASSET_FOLDER as aG, FileService as aH, FileUploadDirective as aI, FileUploadInputComponent as aJ, FlexComponent as aK, FlexItemComponent as aL, FormGroupComponent as aM, FrameComponent as aN, FreezeService as aO, GRID_BREAKPOINTS as aP, GetNavService as aQ, HighlightDirective as aR, HttpService as aS, ICON_SOURCE as aT, IS_SIDE_PANEL as aU, IconComponent as aV, ImgComponent as aW, InstrumentScoreComponent as aX, InterceptorObservables as aY, JumbotronComponent as aZ, KeyValueComponent as a_, ContextMenuComponent as aa, CustomIconClass as ab, CustomIconEditComponent as ac, DEFAULT_DENIAL as ad, DEFAULT_FILTER_RANGE_MODE as ae, DEFAULT_FILTER_VARIANT as af, DEFAULT_NAV_PARAM as ag, DEFAULT_NAV_SEGMENT as ah, DEFAULT_SIZE as ai, DOCK_MIN_PAGE_REMAINDER as aj, DOCS_FOLDER as ak, DOC_ACTION_ICONS as al, DOC_EDIT_ACTIONS as am, DOC_TOOLBAR_GROUPS as an, DashboardCardComponent as ao, DateInputComponent as ap, DatePickerComponent as aq, DeviceService as ar, DocComponent as as, DocEditorComponent as at, DomService as au, Domain as av, DotGridComponent as aw, DragListDirective as ax, DragListItemDirective as ay, DraggableDirective as az, MAX_ZOOM as b, RatingInputComponent as b$, LOGIN_COMPONENT as b0, LOGIN_STORE as b1, LanguageComponent as b2, ListComponent as b3, LogoComponent as b4, MAG_SOCKET_EVENT as b5, MHeroColorDirective as b6, MHeroComponent as b7, MODAL_STORE_REF as b8, MRefDirective as b9, NotificationGroupComponent as bA, NotificationPopupComponent as bB, NotificationService as bC, NotificationStore as bD, NotificationType as bE, NotificationWidgetComponent as bF, ONE_ASSET_BASE_URL as bG, OPTIONS_SOURCE as bH, OVERLAY_WIDGETS as bI, OneApp as bJ, OptionsSourceDirective as bK, OverlayBodyComponent as bL, OverlayRef as bM, OverlayService as bN, PLATFORM_BUTTON_NAV_IDS as bO, PLATFORM_EXTENSIBLE_NAV_IDS as bP, PLATFORM_NAV_MAP as bQ, PLATFORM_ROOT_CHILDREN as bR, PaginationComponent as bS, PanelComponent as bT, PercentagePipe as bU, PlaygroundComponent as bV, PositionDirective as bW, PwaInstallComponent as bX, ROOT_NAV$1 as bY, RadioGroupComponent as bZ, RadioInputComponent as b_, MStepComponent as ba, MURL_PARAM as bb, MURL_SEP as bc, ManifestEnrichmentService as bd, MenuComponent as be, ModalDirective as bf, ModalRef as bg, ModalStore as bh, MoneyPipe as bi, MultiRangeInputComponent as bj, MurlUrlSerializer as bk, NAV_DEFAULT_MURL as bl, NAV_ID_SEP as bm, NAV_MAIN_BUTTONS as bn, NAV_SEGMENT_RE as bo, NAV_STORE_REF as bp, NAV_WC_COMPONENTS as bq, NAV_WIDGET_MAP as br, NavComponent as bs, NavDetailsComponent as bt, NavHeaderComponent as bu, NavMenuComponent as bv, NavStore as bw, NavTrailComponent as bx, NothingComponent as by, NotificationElementComponent as bz, cropRect as c, TOTAL_COLUMNS as c$, ReactiveElementComponent as c0, RemoteComponent as c1, RemoteLoaderService as c2, ResizeElementComponent as c3, RouteContainer as c4, RowComponent as c5, SEARCH_QUERY as c6, SEARCH_RESULTS_EVENT as c7, SECTION_ACCORDION_GROUP as c8, SECTION_FORM_CONTEXT as c9, SectionPaginationComponent as cA, SectionSearchComponent as cB, SectionStepperComponent as cC, SectionTabsComponent as cD, SectionToggleComponent as cE, SectionToggleItemDirective as cF, SelectableCardInputComponent as cG, SelectorDirective as cH, SettingsSearchBarComponent as cI, SettingsSearchService as cJ, ShapeComponent as cK, SharedStoreRegistry as cL, SidePanelDirective as cM, Size as cN, SocketStore as cO, SortComponent as cP, StatComponent as cQ, StepComponent as cR, StepperComponent as cS, StepsComponent as cT, StorageService as cU, StrokeLinecap as cV, StrokeLinejoin as cW, SummaryComponent as cX, SvgGeneratorComponent as cY, SvgGeneratorService as cZ, SvgService as c_, SHARED_ICONS as ca, SIZE_CONTEXT as cb, ScoreComponent as cc, ScrollComponent as cd, ScrollService as ce, SearchPanelComponent as cf, SearchStore as cg, SearchUserPanelComponent as ch, SectionAccordionDirective as ci, SectionAccordionGroupDirective as cj, SectionBackComponent as ck, SectionBadgesComponent as cl, SectionButtonGroupComponent as cm, SectionCardComponent as cn, SectionCarouselComponent as co, SectionComponent as cp, SectionFilterComponent as cq, SectionFilterGroupComponent as cr, SectionFilterMenuComponent as cs, SectionFilterPanelComponent as ct, SectionFilterRangePanelComponent as cu, SectionFooterComponent as cv, SectionFormComponent as cw, SectionFormItemComponent as cx, SectionHeaderComponent as cy, SectionHeroComponent as cz, drawFramed as d, docRemotePath as d$, TRANSLATION_SOURCE as d0, TableComponent as d1, TechnicalMeterComponent as d2, TextInputComponent as d3, TextareaInputComponent as d4, ThemeComponent as d5, ThemeDataService as d6, ThemeService as d7, ThemeStore as d8, TimeAgoPipe as d9, anchorNavId as dA, applyColorsToElement as dB, applyDocEdit as dC, assetOptions as dD, bootstrapMagApp as dE, bootstrapPwaInstall as dF, buildWcBaseUrl as dG, calculateLuminance as dH, calculateRanks as dI, cellText as dJ, checkDoc as dK, checkFilterCondition as dL, childNavId as dM, claimDenial as dN, classListSignal as dO, coerceSize as dP, cornerEdge as dQ, cornerSide as dR, createMap as dS, createPlatformNavMap as dT, deriveAvatarGradient as dU, deriveContrastColor as dV, deriveOppositeColor as dW, derivePropertyName as dX, docActionKey as dY, docAssetCandidates as dZ, docProblemKey as d_, TimelineComponent as da, ToggleButtonComponent as db, ToggleInputComponent as dc, ToggleRadioInputComponent as dd, ToolTipDirective as de, TooltipComponent as df, TranslateService as dg, TreeGridComponent as dh, URL_SEP as di, USER_STORE_REF as dj, USER_TAB_MAP as dk, UniverseComponent as dl, UserApiService as dm, UserAvatarComponent as dn, UserComponent as dp, UserNavComponent as dq, UserSettingsComponent as dr, UserStore as ds, WC_ROUTE_CHANGED_EVENT as dt, WC_SEARCH_GROUPS as du, WIN_USER_TAB_HOOK as dv, WIN_USER_TAB_KEY as dw, WatermarkComponent as dx, WcRouterStore as dy, WrapperInputComponent as dz, encodeFramed as e, loadingActions as e$, emailValidation as e0, evaluate as e1, evaluateBool as e2, fieldBoolean as e3, fieldNumber as e4, fieldString as e5, filterHoldsList as e6, filterHoldsOneBound as e7, filterHoldsOptions as e8, filterHoldsRange as e9, initialNotificationState as eA, initialState$2 as eB, initials as eC, injectAuthenticate as eD, injectDefaultDenial as eE, injectInstallApp as eF, injectParentSize as eG, injectScrollSticky as eH, isButtonName as eI, isCancelledComputed as eJ, isExtensiblePlatformNavId as eK, isJson as eL, isLoadingComputed as eM, isLocalhost as eN, isNavInstanceConfig as eO, isNavMenuConfig as eP, isNavRowsConfig as eQ, isNavVisibilityConfig as eR, isPlatformNavId as eS, isSize as eT, isTierPreview as eU, isUrlLocalhost as eV, isValidNavId as eW, isValidNavSegment as eX, isWebComponent as eY, linkToId as eZ, linkToNav as e_, filterList as ea, filterNumber as eb, filterNumberList as ec, filterOne as ed, filterPanelOf as ee, filterPanelWidth as ef, filterRange as eg, filterTreeGridRows as eh, filterValueList as ei, filterValues as ej, flattenTreeGridRows as ek, formatBadgeCount as el, fullName as em, generateClipPath as en, generateTransform as eo, getClassList as ep, getProperty as eq, getScrollParent as er, getTierFromPreviewPath as es, getTreeGridRow as et, getUniqueId as eu, getValue as ev, hasErrorComputed as ew, hexToRgb as ex, hslToRgb$1 as ey, initMagmoniumApp as ez, clampFraming as f, shouldShowBadge as f$, mInterceptor as f0, manualValidation as f1, matchFieldValidation as f2, maxLengthValidation as f3, maxValidation as f4, mergePlatformNav as f5, mergeUnique as f6, mergeUniqueBy as f7, mergeUniqueWith as f8, minAgeValidation as f9, provideMagWcRoutes as fA, provideModalComponents as fB, provideMurlUrlSerializer as fC, provideNavWidgets as fD, provideOverlayWidgets as fE, providePlatformNavWidgets as fF, provideSearch as fG, provideSizeContext as fH, provideUserTabs as fI, publicGuard as fJ, readFieldPatterns as fK, renderAddress as fL, renderDocument as fM, requiredValidation as fN, resolveConfigAsset as fO, resolveIconSize as fP, resolvePallet as fQ, resolvePatternRules as fR, resolveSize as fS, rgbToHex as fT, rgbToHsl as fU, rowHasChildren as fV, samePatterns as fW, segmentsToNavId as fX, setProperty as fY, setTreeGridChildren as fZ, settingsWidgets as f_, minLengthValidation as fa, minValidation as fb, miniMarkToHtml as fc, navIdChain as fd, navIdFor as fe, navIdSegment as ff, navIdToRoutePath as fg, navIdToSegments as fh, navParamOf as fi, navToId as fj, navVisibilityGuard as fk, normalizeAssetOptions as fl, offsetOfLine as fm, parentNavId as fn, parseAddress as fo, parseColor as fp, parsePatternNames as fq, patternValidation as fr, patternsValidation as fs, permissionRefusal as ft, platformNavWidgets as fu, privateGuard as fv, processImageToSvg as fw, provideAppContext as fx, provideMagAppConfig as fy, provideMagWcConfig as fz, BaseInputComponent as g, splitNavId as g0, splitOnMatch as g1, stringToColor as g2, toAttrBool as g3, toAttrNumber as g4, toCssLength as g5, toHostNavId as g6, toLength$1 as g7, toLocalNavId as g8, toggleTreeGridRow as g9, unfetchedPlatformNav as ga, ungroupedDocActions as gb, urlValidation as gc, BaseTextInputComponent as h, initialFraming as i, TextOutputComponent as j, IS_DESIGN_MODE as k, APP_CONTEXT_REF as l, ASSET_BASE_URL as m, AccordionBodyDirective as n, outputSize as o, parseRatio as p, AccordionComponent as q, renameForType as r, AccordionGroupComponent as s, ActionComponent as t, AnimatedGraphsComponent as u, AppCardComponent as v, AppRelationType as w, AppTileComponent as x, AssetStore as y, AssetUrlPipe as z };
|
|
37985
|
+
//# sourceMappingURL=magmonium-one-magmonium-one-YIfvzI6x.mjs.map
|