@hmcts/ccd-case-ui-toolkit 7.2.54-exui-2600 → 7.2.54-markdown-validation

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.
@@ -52,10 +52,15 @@ export class FormValidatorsService {
52
52
  return validator;
53
53
  }
54
54
  static markDownPatternValidator() {
55
- const pattern = /(\[[^\]]{0,500}\]\([^)]{0,500}\)|!\[[^\]]{0,500}\]\([^)]{0,500}\)|<img[^>]{0,500}>|<a[^>]{0,500}>.*?<\/a>)/;
55
+ // Matches: [text](url), ![alt](url), <img ...>, <a ...>...</a>
56
+ const inlineMarkdownPattern = /(?:!?\[[^\]]{0,500}\]\([^)]{0,500}\)|<(?:img\b[^>]{0,500}>|a\b[^>]{0,500}>[\s\S]*?<\/a>))/i;
57
+ // Matches: [text][id], ![alt][id], and the collapsed form [text][]
58
+ const referenceBoxPattern = /(!)?\[((?:[^[\]\\]|\\.){0,500})\]\s*\[([^\]]{0,100})\]/;
59
+ // Matches: autolinks such as <http://example.com>
60
+ const autolinkPattern = /<(?:[A-Za-z][A-Za-z0-9+.-]*:[^ <>\n]*|[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+)>/;
56
61
  return (control) => {
57
62
  const value = control?.value?.toString().trim();
58
- return (value && pattern.test(value)) ? { markDownPattern: {} } : null;
63
+ return (value && (inlineMarkdownPattern.test(value) || referenceBoxPattern.test(value) || this.matchesReferenceUrlDef(value) || autolinkPattern.test(value) || this.hasMultiBracket(value))) ? { markDownPattern: {} } : null;
59
64
  };
60
65
  }
61
66
  // TODO: Strip this out as it's only here for the moment because
@@ -73,10 +78,111 @@ export class FormValidatorsService {
73
78
  }
74
79
  return control;
75
80
  }
81
+ // Check for multi-bracket markdown links and validate destination URL
82
+ static hasMultiBracket(value) {
83
+ const maxUrlString = 2048; // inside (...) excluding the final ')'
84
+ // Sonar-friendly detector: opening-run + text + first closing ']'
85
+ const openingTextClosePattern = /\[{1,10}[^[\]\n]{1,60}\]/;
86
+ // Destination must be "balanced () segments, no spaces/</>/newline"
87
+ const destinationPattern = /^[^()\s<>]+(?:\([^()\s<>]*\)[^()\s<>]*)*$/;
88
+ let scanIndex = 0;
89
+ const totalLength = value.length;
90
+ while (scanIndex < totalLength) {
91
+ const seg = this.findOpeningTextClose(value, scanIndex, openingTextClosePattern);
92
+ if (!seg) {
93
+ return false; // no candidate -> no match
94
+ }
95
+ const runs = this.extendClosingRunAndRequireParen(value, seg.absStart, seg.afterFirstClose);
96
+ if (runs && runs.openingRunCount === runs.closingRunCount) {
97
+ if (this.hasBalancedDestination(value, runs.afterOpenParen, maxUrlString, destinationPattern)) {
98
+ return true; // valid multi-bracket link found
99
+ }
100
+ }
101
+ // Advance to avoid stalling on overlaps
102
+ scanIndex = seg.absStart + 1;
103
+ }
104
+ return false;
105
+ }
106
+ // Find opening '[' run, text, and first closing ']'
107
+ static findOpeningTextClose(source, fromIndex, pattern) {
108
+ const slice = source.slice(fromIndex);
109
+ const match = pattern.exec(slice);
110
+ if (!match) {
111
+ return null;
112
+ }
113
+ const absStart = fromIndex + match.index;
114
+ const afterFirstClose = absStart + match[0].length; // index just after the first ']'
115
+ return { absStart, afterFirstClose };
116
+ }
117
+ // Count opening '[' run, extend the ']' run, and require '(' right after the full ']' run
118
+ static extendClosingRunAndRequireParen(source, absStart, afterFirstClose) {
119
+ const n = source.length;
120
+ // Count opening '[' run (e.g., '[[[')
121
+ let openingRunCount = 0;
122
+ for (let i = absStart; i < n && source[i] === '['; i++) {
123
+ openingRunCount++;
124
+ }
125
+ // Extend closing ']' run forward from the first one
126
+ let closingRunCount = 1;
127
+ let afterClosingRun = afterFirstClose;
128
+ while (afterClosingRun < n && source[afterClosingRun] === ']') {
129
+ closingRunCount++;
130
+ afterClosingRun++;
131
+ }
132
+ // '(' must immediately follow the full closing run
133
+ if (afterClosingRun >= n || source[afterClosingRun] !== '(') {
134
+ return null;
135
+ }
136
+ return { openingRunCount, closingRunCount, afterOpenParen: afterClosingRun + 1 };
137
+ }
138
+ // Scan destination from afterOpenParen until its matching ')', enforcing simple URL rules
139
+ static hasBalancedDestination(source, afterOpenParen, maxDest, destPattern) {
140
+ const n = source.length;
141
+ let depth = 0;
142
+ let cursor = afterOpenParen;
143
+ let consumed = 0;
144
+ // Try successive ')' positions to allow inner balanced parentheses.
145
+ while (cursor < n && consumed <= maxDest) {
146
+ const ch = source[cursor];
147
+ if (ch === '(') {
148
+ depth++;
149
+ }
150
+ else if (ch === ')') {
151
+ if (depth === 0) {
152
+ const candidate = source.slice(afterOpenParen, cursor);
153
+ return candidate.length > 0 && destPattern.test(candidate);
154
+ }
155
+ depth--;
156
+ }
157
+ else if (ch === ' ' || ch === '\t' || ch === '<' || ch === '>' || ch === '\n') {
158
+ return false; // illegal destination character
159
+ }
160
+ cursor++;
161
+ consumed++;
162
+ }
163
+ return false; // ran out without a valid closing ')'
164
+ }
165
+ static isValidReferenceUrlTitleTail(tail) {
166
+ const possibleTitle = tail.trim();
167
+ // Accept exactly one of: "title", 'title', (title) — bounded and single-line.
168
+ if (!possibleTitle || /^"[^"\r\n]{0,300}"$/.test(possibleTitle) || /^'[^'\r\n]{0,300}'$/.test(possibleTitle) || /^\([^)\r\n]{0,300}\)$/.test(possibleTitle)) {
169
+ return true;
170
+ }
171
+ return false;
172
+ }
173
+ static matchesReferenceUrlDef(line) {
174
+ // Single-line, pragmatic CommonMark-style reference definition e.g. [text]: http://example.com
175
+ const baseReferenceUrlPattern = /^[ \t]{0,3}\[([^\]]{1,100})\]:[ \t]*<?([^\s>]{1,2048})>?[ \t]*([^ \t\r\n].*)?$/m;
176
+ const mainRegEx = baseReferenceUrlPattern.exec(line);
177
+ if (!mainRegEx)
178
+ return false;
179
+ const tail = mainRegEx[3] ?? "";
180
+ return this.isValidReferenceUrlTitleTail(tail);
181
+ }
76
182
  static ɵfac = function FormValidatorsService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FormValidatorsService)(); };
77
183
  static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: FormValidatorsService, factory: FormValidatorsService.ɵfac });
78
184
  }
79
185
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FormValidatorsService, [{
80
186
  type: Injectable
81
187
  }], null, null); })();
82
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS12YWxpZGF0b3JzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jY2QtY2FzZS11aS10b29sa2l0L3NyYy9saWIvc2hhcmVkL3NlcnZpY2VzL2Zvcm0vZm9ybS12YWxpZGF0b3JzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWtELFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7QUFLcEQsTUFBTSxPQUFPLHFCQUFxQjtJQUN4QixNQUFNLENBQVUsc0JBQXNCLEdBQW9CO1FBQ2hFLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLGNBQWM7S0FDNUMsQ0FBQztJQUNNLE1BQU0sQ0FBVSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7SUFDNUMsTUFBTSxDQUFVLHNCQUFzQixHQUFHLFdBQVcsQ0FBQztJQUV0RCxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQW9CLEVBQUUsT0FBd0I7UUFDeEUsSUFDRSxTQUFTLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxTQUFTO1lBQ2pELHFCQUFxQixDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUN0RixDQUFDO1lBQ0QsTUFBTSxVQUFVLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekMsSUFBSSxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDekMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLFNBQVMsQ0FBQyxVQUFVLENBQUMsa0JB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QUFDO1FBQ3pFLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRCxnRUFBZ0U7SUFDaEUsa0VBQWtFO0lBQ2xFLGlFQUFpRTtJQUNqRSxzQkFBc0I7SUFDZixhQUFhLENBQUMsU0FBb0IsRUFBRSxPQUF3QjtRQUNqRSxPQUFPLHFCQUFxQixDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVNLHFCQUFxQixDQUFDLFNBQTBCLEVBQUUsV0FBbUI7UUFDMUUsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMzQyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osT0FBTyxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDLENBQUM7WUFDeEUsT0FBTyxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDbkMsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7K0dBL0VVLHFCQUFxQjtnRUFBckIscUJBQXFCLFdBQXJCLHFCQUFxQjs7aUZBQXJCLHFCQUFxQjtjQURqQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBWYWxpZGF0aW9uRXJyb3JzLCBWYWxpZGF0b3JGbiwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgQ29uc3RhbnRzIH0gZnJvbSAnLi4vLi4vY29tbW9ucy9jb25zdGFudHMnO1xuaW1wb3J0IHsgQ2FzZUZpZWxkIH0gZnJvbSAnLi4vLi4vZG9tYWluL2RlZmluaXRpb24vY2FzZS1maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBGaWVsZFR5cGVFbnVtIH0gZnJvbSAnLi4vLi4vZG9tYWluL2RlZmluaXRpb24vZmllbGQtdHlwZS1lbnVtLm1vZGVsJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZvcm1WYWxpZGF0b3JzU2VydmljZSB7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IENVU1RPTV9WQUxJREFURURfVFlQRVM6IEZpZWxkVHlwZUVudW1bXSA9IFtcbiAgICAnRGF0ZScsICdNb25leUdCUCcsICdMYWJlbCcsICdKdWRpY2lhbFVzZXInXG4gIF07XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfSU5QVVRfVEVYVCA9ICd0ZXh0JztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9JTlBVVF9URVhUQVJFQSA9ICd0ZXh0QXJlYXMnO1xuXG4gIHB1YmxpYyBzdGF0aWMgYWRkVmFsaWRhdG9ycyhjYXNlRmllbGQ6IENhc2VGaWVsZCwgY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICBpZiAoXG4gICAgICBjYXNlRmllbGQuZGlzcGxheV9jb250ZXh0ID09PSBDb25zdGFudHMuTUFOREFUT1JZICYmXG4gICAgICBGb3JtVmFsaWRhdG9yc1NlcnZpY2UuQ1VTVE9NX1ZBTElEQVRFRF9UWVBFUy5pbmRleE9mKGNhc2VGaWVsZC5maWVsZF90eXBlLnR5cGUpID09PSAtMVxuICAgICkge1xuICAgICAgY29uc3QgdmFsaWRhdG9ycyA9IFtWYWxpZGF0b3JzLnJlcXVpcmVkXTtcbiAgICAgIGlmIChjYXNlRmllbGQuZmllbGRfdHlwZS50eXBlID09PSAnVGV4dCcpIHtcbiAgICAgICAgdmFsaWRhdG9ycy5wdXNoKHRoaXMubWFya0Rvd25QYXR0ZXJuVmFsaWRhdG9yKCkpO1xuICAgICAgICBpZiAoY2FzZUZpZWxkLmZpZWxkX3R5cGUucmVndWxhcl9leHByZXNzaW9uKSB7XG4gICAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMucGF0dGVybihjYXNlRmllbGQuZmllbGRfdHlwZS5yZWd1bGFyX2V4cHJlc3Npb24pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWxpZGF0b3JzLnB1c2godGhpcy5lbXB0eVZhbGlkYXRvcigpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FzZUZpZWxkLmZpZWxkX3R5cGUubWluICYmICh0eXBlb2YgY2FzZUZpZWxkLmZpZWxkX3R5cGUubWluID09PSAnbnVtYmVyJykpIHtcbiAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW5MZW5ndGgoY2FzZUZpZWxkLmZpZWxkX3R5cGUubWluKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNhc2VGaWVsZC5maWVsZF90eXBlLm1heCAmJiAodHlwZW9mIGNhc2VGaWVsZC5maWVsZF90eXBlLm1heCA9PT0gJ251bWJlcicpKSB7XG4gICAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWF4TGVuZ3RoKGNhc2VGaWVsZC5maWVsZF90eXBlLm1heCkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjYXNlRmllbGQuZmllbGRfdHlwZS50eXBlID09PSAnVGV4dEFyZWEnKSB7XG4gICAgICAgIHZhbGlkYXRvcnMucHVzaCh0aGlzLmVtcHR5VmFsaWRhdG9yKCkpO1xuICAgICAgICB2YWxpZGF0b3JzLnB1c2godGhpcy5tYXJrRG93blBhdHRlcm5WYWxpZGF0b3IoKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb250cm9sLnZhbGlkYXRvcikge1xuICAgICAgICB2YWxpZGF0b3JzLnB1c2goY29udHJvbC52YWxpZGF0b3IpO1xuICAgICAgfVxuICAgICAgY29udHJvbC5zZXRWYWxpZGF0b3JzKHZhbGlkYXRvcnMpO1xuICAgIH0gZWxzZSBpZiAoY2FzZUZpZWxkLmRpc3BsYXlfY29udGV4dCA9PT0gJ09QVElPTkFMJyAmJiAoY2FzZUZpZWxkLmZpZWxkX3R5cGUudHlwZSA9PT0gJ1RleHQnIHx8IGNhc2VGaWVsZC5maWVsZF90eXBlLnR5cGUgPT09ICdUZXh0QXJlYScpXG4gICAgfHwgKGNhc2VGaWVsZC5kaXNwbGF5X2NvbnRleHQgPT09ICdDT01QTEVYJyAmJiBjYXNlRmllbGQuZmllbGRfdHlwZS50eXBlID09PSAnQ29tcGxleCcpKSB7XG4gICAgICBjb250cm9sLnNldFZhbGlkYXRvcnModGhpcy5tYXJrRG93blBhdHRlcm5WYWxpZGF0b3IoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRyb2w7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGVtcHR5VmFsaWRhdG9yKCk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCB2YWxpZGF0b3IgPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTpWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBpZiAoY29udHJvbD8udmFsdWU/LnRvU3RyaW5nKCkudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4geyByZXF1aXJlZDoge30gfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIHZhbGlkYXRvcjtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgbWFya0Rvd25QYXR0ZXJuVmFsaWRhdG9yKCk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCBwYXR0ZXJuID0gLyhcXFtbXlxcXV17MCw1MDB9XFxdXFwoW14pXXswLDUwMH1cXCl8IVxcW1teXFxdXXswLDUwMH1cXF1cXChbXildezAsNTAwfVxcKXw8aW1nW14+XXswLDUwMH0+fDxhW14+XXswLDUwMH0+Lio/PFxcL2E+KS87XG5cbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gY29udHJvbD8udmFsdWU/LnRvU3RyaW5nKCkudHJpbSgpO1xuICAgICAgcmV0dXJuICh2YWx1ZSAmJiBwYXR0ZXJuLnRlc3QodmFsdWUpKSA/IHsgbWFya0Rvd25QYXR0ZXJuOiB7fSB9IDogbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgLy8gVE9ETzogU3RyaXAgdGhpcyBvdXQgYXMgaXQncyBvbmx5IGhlcmUgZm9yIHRoZSBtb21lbnQgYmVjYXVzZVxuICAvLyB0aGUgc2VydmljZSBpcyBiZWluZyBpbmplY3RlZCBhbGwgb3ZlciB0aGUgcGxhY2UgYnV0IGl0IGRvZXNuJ3RcbiAgLy8gbmVlZCB0byBiZSBhcyBGb3JtVmFsaWRhdG9yc1NlcnZpY2UuYWRkVmFsaWRhdG9ycyBpcyBwZXJmZWN0bHlcbiAgLy8gaGFwcHkgYmVpbmcgc3RhdGljLlxuICBwdWJsaWMgYWRkVmFsaWRhdG9ycyhjYXNlRmllbGQ6IENhc2VGaWVsZCwgY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICByZXR1cm4gRm9ybVZhbGlkYXRvcnNTZXJ2aWNlLmFkZFZhbGlkYXRvcnMoY2FzZUZpZWxkLCBjb250cm9sKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRNYXJrRG93blZhbGlkYXRvcnMoZm9ybUdyb3VwOiBBYnN0cmFjdENvbnRyb2wsIGNvbnRyb2xQYXRoOiBzdHJpbmcpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtR3JvdXAuZ2V0KGNvbnRyb2xQYXRoKTtcbiAgICBpZiAoY29udHJvbCkge1xuICAgICAgY29udHJvbC5zZXRWYWxpZGF0b3JzKEZvcm1WYWxpZGF0b3JzU2VydmljZS5tYXJrRG93blBhdHRlcm5WYWxpZGF0b3IoKSk7XG4gICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRyb2w7XG4gIH1cbn1cbiJdfQ==
188
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS12YWxpZGF0b3JzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jY2QtY2FzZS11aS10b29sa2l0L3NyYy9saWIvc2hhcmVkL3NlcnZpY2VzL2Zvcm0vZm9ybS12YWxpZGF0b3JzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWtELFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7QUFLcEQsTUFBTSxPQUFPLHFCQUFxQjtJQUN4QixNQUFNLENBQVUsc0JBQXNCLEdBQW9CO1FBQ2hFLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLGNBQWM7S0FDNUMsQ0FBQztJQUNNLE1BQU0sQ0FBVSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7SUFDNUMsTUFBTSxDQUFVLHNCQUFzQixHQUFHLFdBQVcsQ0FBQztJQUV0RCxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQW9CLEVBQUUsT0FBd0I7UUFDeEUsSUFDRSxTQUFTLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxTQUFTO1lBQ2pELHFCQUFxQixDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUN0RixDQUFDO1lBQ0QsTUFBTSxVQUFVLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekMsSUFBSSxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDekMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLFNBQVMsQ0FBQyxVQUFVLENBQUMsa0JB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QyxJQUFZO1FBQ3RELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQyw4RUFBOEU7UUFDOUUsSUFBSSxDQUFDLGFBQWEsSUFBSSxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUkscUJBQXFCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLHVCQUF1QixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1lBQzVKLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUdPLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxJQUFZO1FBQ2hELCtGQUErRjtRQUMvRixNQUFNLHVCQUF1QixHQUFHLGlGQUFpRixDQUFDO1FBRWxILE1BQU0sU0FBUyxHQUFHLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzdCLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDaEMsT0FBTyxJQUFJLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakQsQ0FBQzsrR0F0TlUscUJBQXFCO2dFQUFyQixxQkFBcUIsV0FBckIscUJBQXFCOztpRkFBckIscUJBQXFCO2NBRGpDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIFZhbGlkYXRpb25FcnJvcnMsIFZhbGlkYXRvckZuLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBDb25zdGFudHMgfSBmcm9tICcuLi8uLi9jb21tb25zL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBDYXNlRmllbGQgfSBmcm9tICcuLi8uLi9kb21haW4vZGVmaW5pdGlvbi9jYXNlLWZpZWxkLm1vZGVsJztcbmltcG9ydCB7IEZpZWxkVHlwZUVudW0gfSBmcm9tICcuLi8uLi9kb21haW4vZGVmaW5pdGlvbi9maWVsZC10eXBlLWVudW0ubW9kZWwnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRm9ybVZhbGlkYXRvcnNTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ1VTVE9NX1ZBTElEQVRFRF9UWVBFUzogRmllbGRUeXBlRW51bVtdID0gW1xuICAgICdEYXRlJywgJ01vbmV5R0JQJywgJ0xhYmVsJywgJ0p1ZGljaWFsVXNlcidcbiAgXTtcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9JTlBVVF9URVhUID0gJ3RleHQnO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0lOUFVUX1RFWFRBUkVBID0gJ3RleHRBcmVhcyc7XG5cbiAgcHVibGljIHN0YXRpYyBhZGRWYWxpZGF0b3JzKGNhc2VGaWVsZDogQ2FzZUZpZWxkLCBjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgIGlmIChcbiAgICAgIGNhc2VGaWVsZC5kaXNwbGF5X2NvbnRleHQgPT09IENvbnN0YW50cy5NQU5EQVRPUlkgJiZcbiAgICAgIEZvcm1WYWxpZGF0b3JzU2VydmljZS5DVVNUT01fVkFMSURBVEVEX1RZUEVTLmluZGV4T2YoY2FzZUZpZWxkLmZpZWxkX3R5cGUudHlwZSkgPT09IC0xXG4gICAgKSB7XG4gICAgICBjb25zdCB2YWxpZGF0b3JzID0gW1ZhbGlkYXRvcnMucmVxdWlyZWRdO1xuICAgICAgaWYgKGNhc2VGaWVsZC5maWVsZF90eXBlLnR5cGUgPT09ICdUZXh0Jykge1xuICAgICAgICB2YWxpZGF0b3JzLnB1c2godGhpcy5tYXJrRG93blBhdHRlcm5WYWxpZGF0b3IoKSk7XG4gICAgICAgIGlmIChjYXNlRmllbGQuZmllbGRfdHlwZS5yZWd1bGFyX2V4cHJlc3Npb24pIHtcbiAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5wYXR0ZXJuKGNhc2VGaWVsZC5maWVsZF90eXBlLnJlZ3VsYXJfZXhwcmVzc2lvbikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbGlkYXRvcnMucHVzaCh0aGlzLmVtcHR5VmFsaWRhdG9yKCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjYXNlRmllbGQuZmllbGRfdHlwZS5taW4gJiYgKHR5cGVvZiBjYXNlRmllbGQuZmllbGRfdHlwZS5taW4gPT09ICdudW1iZXInKSkge1xuICAgICAgICAgIHZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1pbkxlbmd0aChjYXNlRmllbGQuZmllbGRfdHlwZS5taW4pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FzZUZpZWxkLmZpZWxkX3R5cGUubWF4ICYmICh0eXBlb2YgY2FzZUZpZWxkLmZpZWxkX3R5cGUubWF4ID09PSAnbnVtYmVyJykpIHtcbiAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5tYXhMZW5ndGgoY2FzZUZpZWxkLmZpZWxkX3R5cGUubWF4KSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNhc2VGaWVsZC5maWVsZF90eXBlLnR5cGUgPT09ICdUZXh0QXJlYScpIHtcbiAgICAgICAgdmFsaWRhdG9ycy5wdXNoKHRoaXMuZW1wdHlWYWxpZGF0b3IoKSk7XG4gICAgICAgIHZhbGlkYXRvcnMucHVzaCh0aGlzLm1hcmtEb3duUGF0dGVyblZhbGlkYXRvcigpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRyb2wudmFsaWRhdG9yKSB7XG4gICAgICAgIHZhbGlkYXRvcnMucHVzaChjb250cm9sLnZhbGlkYXRvcik7XG4gICAgICB9XG4gICAgICBjb250cm9sLnNldFZhbGlkYXRvcnModmFsaWRhdG9ycyk7XG4gICAgfSBlbHNlIGlmIChjYXNlRmllbGQuZGlzcGxheV9jb250ZXh0ID09PSAnT1BUSU9OQUwnICYmIChjYXNlRmllbGQuZmllbGRfdHlwZS50eXBlID09PSAnVGV4dCcgfHwgY2FzZUZpZWxkLmZpZWxkX3R5cGUudHlwZSA9PT0gJ1RleHRBcmVhJylcbiAgICAgIHx8IChjYXNlRmllbGQuZGlzcGxheV9jb250ZXh0ID09PSAnQ09NUExFWCcgJiYgY2FzZUZpZWxkLmZpZWxkX3R5cGUudHlwZSA9PT0gJ0NvbXBsZXgnKSkge1xuICAgICAgY29udHJvbC5zZXRWYWxpZGF0b3JzKHRoaXMubWFya0Rvd25QYXR0ZXJuVmFsaWRhdG9yKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBjb250cm9sO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBlbXB0eVZhbGlkYXRvcigpOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgdmFsaWRhdG9yID0gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGlmIChjb250cm9sPy52YWx1ZT8udG9TdHJpbmcoKS50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB7IHJlcXVpcmVkOiB7fSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gdmFsaWRhdG9yO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBtYXJrRG93blBhdHRlcm5WYWxpZGF0b3IoKTogVmFsaWRhdG9yRm4ge1xuICAgIC8vIE1hdGNoZXM6IFt0ZXh0XSh1cmwpLCAhW2FsdF0odXJsKSwgPGltZyAuLi4+LCA8YSAuLi4+Li4uPC9hPlxuICAgIGNvbnN0IGlubGluZU1hcmtkb3duUGF0dGVybiA9IC8oPzohP1xcW1teXFxdXXswLDUwMH1cXF1cXChbXildezAsNTAwfVxcKXw8KD86aW1nXFxiW14+XXswLDUwMH0+fGFcXGJbXj5dezAsNTAwfT5bXFxzXFxTXSo/PFxcL2E+KSkvaTtcblxuICAgIC8vIE1hdGNoZXM6IFt0ZXh0XVtpZF0sICFbYWx0XVtpZF0sIGFuZCB0aGUgY29sbGFwc2VkIGZvcm0gW3RleHRdW11cbiAgICBjb25zdCByZWZlcmVuY2VCb3hQYXR0ZXJuID0gLyghKT9cXFsoKD86W15bXFxdXFxcXF18XFxcXC4pezAsNTAwfSlcXF1cXHMqXFxbKFteXFxdXXswLDEwMH0pXFxdLztcblxuICAgIC8vIE1hdGNoZXM6IGF1dG9saW5rcyBzdWNoIGFzIDxodHRwOi8vZXhhbXBsZS5jb20+XG4gICAgY29uc3QgYXV0b2xpbmtQYXR0ZXJuID0gLzwoPzpbQS1aYS16XVtBLVphLXowLTkrLi1dKjpbXiA8Plxcbl0qfFtBLVphLXowLTkuISMkJSYnKisvPT9eX2B7fH1+LV0rQFtBLVphLXowLTktXSsoPzpcXC5bQS1aYS16MC05LV0rKSspPi87XG5cbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gY29udHJvbD8udmFsdWU/LnRvU3RyaW5nKCkudHJpbSgpO1xuICAgICAgcmV0dXJuICh2YWx1ZSAmJiAoaW5saW5lTWFya2Rvd25QYXR0ZXJuLnRlc3QodmFsdWUpIHx8IHJlZmVyZW5jZUJveFBhdHRlcm4udGVzdCh2YWx1ZSkgfHwgdGhpcy5tYXRjaGVzUmVmZXJlbmNlVXJsRGVmKHZhbHVlKSB8fCBhdXRvbGlua1BhdHRlcm4udGVzdCh2YWx1ZSkgfHwgdGhpcy5oYXNNdWx0aUJyYWNrZXQodmFsdWUgYXMgc3RyaW5nKSkpID8geyBtYXJrRG93blBhdHRlcm46IHt9IH0gOiBudWxsO1xuICAgIH07XG4gIH1cblxuICAvLyBUT0RPOiBTdHJpcCB0aGlzIG91dCBhcyBpdCdzIG9ubHkgaGVyZSBmb3IgdGhlIG1vbWVudCBiZWNhdXNlXG4gIC8vIHRoZSBzZXJ2aWNlIGlzIGJlaW5nIGluamVjdGVkIGFsbCBvdmVyIHRoZSBwbGFjZSBidXQgaXQgZG9lc24ndFxuICAvLyBuZWVkIHRvIGJlIGFzIEZvcm1WYWxpZGF0b3JzU2VydmljZS5hZGRWYWxpZGF0b3JzIGlzIHBlcmZlY3RseVxuICAvLyBoYXBweSBiZWluZyBzdGF0aWMuXG4gIHB1YmxpYyBhZGRWYWxpZGF0b3JzKGNhc2VGaWVsZDogQ2FzZUZpZWxkLCBjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgIHJldHVybiBGb3JtVmFsaWRhdG9yc1NlcnZpY2UuYWRkVmFsaWRhdG9ycyhjYXNlRmllbGQsIGNvbnRyb2wpO1xuICB9XG5cbiAgcHVibGljIGFkZE1hcmtEb3duVmFsaWRhdG9ycyhmb3JtR3JvdXA6IEFic3RyYWN0Q29udHJvbCwgY29udHJvbFBhdGg6IHN0cmluZyk6IEFic3RyYWN0Q29udHJvbCB7XG4gICAgY29uc3QgY29udHJvbCA9IGZvcm1Hcm91cC5nZXQoY29udHJvbFBhdGgpO1xuICAgIGlmIChjb250cm9sKSB7XG4gICAgICBjb250cm9sLnNldFZhbGlkYXRvcnMoRm9ybVZhbGlkYXRvcnNTZXJ2aWNlLm1hcmtEb3duUGF0dGVyblZhbGlkYXRvcigpKTtcbiAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgIH1cbiAgICByZXR1cm4gY29udHJvbDtcbiAgfVxuXG4gIC8vIENoZWNrIGZvciBtdWx0aS1icmFja2V0IG1hcmtkb3duIGxpbmtzIGFuZCB2YWxpZGF0ZSBkZXN0aW5hdGlvbiBVUkxcbiAgcHJpdmF0ZSBzdGF0aWMgaGFzTXVsdGlCcmFja2V0KHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBtYXhVcmxTdHJpbmcgPSAyMDQ4OyAgICAvLyBpbnNpZGUgKC4uLikgZXhjbHVkaW5nIHRoZSBmaW5hbCAnKSdcblxuICAgIC8vIFNvbmFyLWZyaWVuZGx5IGRldGVjdG9yOiBvcGVuaW5nLXJ1biArIHRleHQgKyBmaXJzdCBjbG9zaW5nICddJ1xuICAgIGNvbnN0IG9wZW5pbmdUZXh0Q2xvc2VQYXR0ZXJuID0gL1xcW3sxLDEwfVteW1xcXVxcbl17MSw2MH1cXF0vO1xuXG4gICAgLy8gRGVzdGluYXRpb24gbXVzdCBiZSBcImJhbGFuY2VkICgpIHNlZ21lbnRzLCBubyBzcGFjZXMvPC8+L25ld2xpbmVcIlxuICAgIGNvbnN0IGRlc3RpbmF0aW9uUGF0dGVybiA9IC9eW14oKVxcczw+XSsoPzpcXChbXigpXFxzPD5dKlxcKVteKClcXHM8Pl0qKSokLztcblxuICAgIGxldCBzY2FuSW5kZXggPSAwO1xuICAgIGNvbnN0IHRvdGFsTGVuZ3RoID0gdmFsdWUubGVuZ3RoO1xuXG4gICAgd2hpbGUgKHNjYW5JbmRleCA8IHRvdGFsTGVuZ3RoKSB7XG4gICAgICBjb25zdCBzZWcgPSB0aGlzLmZpbmRPcGVuaW5nVGV4dENsb3NlKHZhbHVlLCBzY2FuSW5kZXgsIG9wZW5pbmdUZXh0Q2xvc2VQYXR0ZXJuKTtcbiAgICAgIGlmICghc2VnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTsgLy8gbm8gY2FuZGlkYXRlIC0+IG5vIG1hdGNoXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJ1bnMgPSB0aGlzLmV4dGVuZENsb3NpbmdSdW5BbmRSZXF1aXJlUGFyZW4odmFsdWUsIHNlZy5hYnNTdGFydCwgc2VnLmFmdGVyRmlyc3RDbG9zZSk7XG4gICAgICBpZiAocnVucyAmJiBydW5zLm9wZW5pbmdSdW5Db3VudCA9PT0gcnVucy5jbG9zaW5nUnVuQ291bnQpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQmFsYW5jZWREZXN0aW5hdGlvbih2YWx1ZSwgcnVucy5hZnRlck9wZW5QYXJlbiwgbWF4VXJsU3RyaW5nLCBkZXN0aW5hdGlvblBhdHRlcm4pKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7IC8vIHZhbGlkIG11bHRpLWJyYWNrZXQgbGluayBmb3VuZFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEFkdmFuY2UgdG8gYXZvaWQgc3RhbGxpbmcgb24gb3ZlcmxhcHNcbiAgICAgIHNjYW5JbmRleCA9IHNlZy5hYnNTdGFydCArIDE7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIEZpbmQgb3BlbmluZyAnWycgcnVuLCB0ZXh0LCBhbmQgZmlyc3QgY2xvc2luZyAnXSdcbiAgcHJpdmF0ZSBzdGF0aWMgZmluZE9wZW5pbmdUZXh0Q2xvc2UoXG4gICAgc291cmNlOiBzdHJpbmcsXG4gICAgZnJvbUluZGV4OiBudW1iZXIsXG4gICAgcGF0dGVybjogUmVnRXhwXG4gICk6IHsgYWJzU3RhcnQ6IG51bWJlcjsgYWZ0ZXJGaXJzdENsb3NlOiBudW1iZXIgfSB8IG51bGwge1xuICAgIGNvbnN0IHNsaWNlID0gc291cmNlLnNsaWNlKGZyb21JbmRleCk7XG4gICAgY29uc3QgbWF0Y2ggPSBwYXR0ZXJuLmV4ZWMoc2xpY2UpO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBhYnNTdGFydCA9IGZyb21JbmRleCArIG1hdGNoLmluZGV4O1xuICAgIGNvbnN0IGFmdGVyRmlyc3RDbG9zZSA9IGFic1N0YXJ0ICsgbWF0Y2hbMF0ubGVuZ3RoOyAvLyBpbmRleCBqdXN0IGFmdGVyIHRoZSBmaXJzdCAnXSdcbiAgICByZXR1cm4geyBhYnNTdGFydCwgYWZ0ZXJGaXJzdENsb3NlIH07XG4gIH1cblxuICAvLyBDb3VudCBvcGVuaW5nICdbJyBydW4sIGV4dGVuZCB0aGUgJ10nIHJ1biwgYW5kIHJlcXVpcmUgJygnIHJpZ2h0IGFmdGVyIHRoZSBmdWxsICddJyBydW5cbiAgcHJpdmF0ZSBzdGF0aWMgZXh0ZW5kQ2xvc2luZ1J1bkFuZFJlcXVpcmVQYXJlbihcbiAgICBzb3VyY2U6IHN0cmluZyxcbiAgICBhYnNTdGFydDogbnVtYmVyLFxuICAgIGFmdGVyRmlyc3RDbG9zZTogbnVtYmVyXG4gICk6IHsgb3BlbmluZ1J1bkNvdW50OiBudW1iZXI7IGNsb3NpbmdSdW5Db3VudDogbnVtYmVyOyBhZnRlck9wZW5QYXJlbjogbnVtYmVyIH0gfCBudWxsIHtcbiAgICBjb25zdCBuID0gc291cmNlLmxlbmd0aDtcblxuICAgIC8vIENvdW50IG9wZW5pbmcgJ1snIHJ1biAoZS5nLiwgJ1tbWycpXG4gICAgbGV0IG9wZW5pbmdSdW5Db3VudCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IGFic1N0YXJ0OyBpIDwgbiAmJiBzb3VyY2VbaV0gPT09ICdbJzsgaSsrKSB7XG4gICAgICBvcGVuaW5nUnVuQ291bnQrKztcbiAgICB9XG5cbiAgICAvLyBFeHRlbmQgY2xvc2luZyAnXScgcnVuIGZvcndhcmQgZnJvbSB0aGUgZmlyc3Qgb25lXG4gICAgbGV0IGNsb3NpbmdSdW5Db3VudCA9IDE7XG4gICAgbGV0IGFmdGVyQ2xvc2luZ1J1biA9IGFmdGVyRmlyc3RDbG9zZTtcbiAgICB3aGlsZSAoYWZ0ZXJDbG9zaW5nUnVuIDwgbiAmJiBzb3VyY2VbYWZ0ZXJDbG9zaW5nUnVuXSA9PT0gJ10nKSB7XG4gICAgICBjbG9zaW5nUnVuQ291bnQrKztcbiAgICAgIGFmdGVyQ2xvc2luZ1J1bisrO1xuICAgIH1cblxuICAgIC8vICcoJyBtdXN0IGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgZnVsbCBjbG9zaW5nIHJ1blxuICAgIGlmIChhZnRlckNsb3NpbmdSdW4gPj0gbiB8fCBzb3VyY2VbYWZ0ZXJDbG9zaW5nUnVuXSAhPT0gJygnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHsgb3BlbmluZ1J1bkNvdW50LCBjbG9zaW5nUnVuQ291bnQsIGFmdGVyT3BlblBhcmVuOiBhZnRlckNsb3NpbmdSdW4gKyAxIH07XG4gIH1cblxuICAvLyBTY2FuIGRlc3RpbmF0aW9uIGZyb20gYWZ0ZXJPcGVuUGFyZW4gdW50aWwgaXRzIG1hdGNoaW5nICcpJywgZW5mb3JjaW5nIHNpbXBsZSBVUkwgcnVsZXNcbiAgcHJpdmF0ZSBzdGF0aWMgaGFzQmFsYW5jZWREZXN0aW5hdGlvbihcbiAgICBzb3VyY2U6IHN0cmluZyxcbiAgICBhZnRlck9wZW5QYXJlbjogbnVtYmVyLFxuICAgIG1heERlc3Q6IG51bWJlcixcbiAgICBkZXN0UGF0dGVybjogUmVnRXhwXG4gICk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG4gPSBzb3VyY2UubGVuZ3RoO1xuICAgIGxldCBkZXB0aCA9IDA7XG4gICAgbGV0IGN1cnNvciA9IGFmdGVyT3BlblBhcmVuO1xuICAgIGxldCBjb25zdW1lZCA9IDA7XG5cbiAgICAvLyBUcnkgc3VjY2Vzc2l2ZSAnKScgcG9zaXRpb25zIHRvIGFsbG93IGlubmVyIGJhbGFuY2VkIHBhcmVudGhlc2VzLlxuICAgIHdoaWxlIChjdXJzb3IgPCBuICYmIGNvbnN1bWVkIDw9IG1heERlc3QpIHtcbiAgICAgIGNvbnN0IGNoID0gc291cmNlW2N1cnNvcl07XG4gICAgICBpZiAoY2ggPT09ICcoJykgeyBkZXB0aCsrOyB9XG4gICAgICBlbHNlIGlmIChjaCA9PT0gJyknKSB7XG4gICAgICAgIGlmIChkZXB0aCA9PT0gMCkge1xuICAgICAgICAgIGNvbnN0IGNhbmRpZGF0ZSA9IHNvdXJjZS5zbGljZShhZnRlck9wZW5QYXJlbiwgY3Vyc29yKTtcbiAgICAgICAgICByZXR1cm4gY2FuZGlkYXRlLmxlbmd0aCA+IDAgJiYgZGVzdFBhdHRlcm4udGVzdChjYW5kaWRhdGUpO1xuICAgICAgICB9XG4gICAgICAgIGRlcHRoLS07XG4gICAgICB9IGVsc2UgaWYgKGNoID09PSAnICcgfHwgY2ggPT09ICdcXHQnIHx8IGNoID09PSAnPCcgfHwgY2ggPT09ICc+JyB8fCBjaCA9PT0gJ1xcbicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBpbGxlZ2FsIGRlc3RpbmF0aW9uIGNoYXJhY3RlclxuICAgICAgfVxuICAgICAgY3Vyc29yKys7XG4gICAgICBjb25zdW1lZCsrO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7IC8vIHJhbiBvdXQgd2l0aG91dCBhIHZhbGlkIGNsb3NpbmcgJyknXG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBpc1ZhbGlkUmVmZXJlbmNlVXJsVGl0bGVUYWlsKHRhaWw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBvc3NpYmxlVGl0bGUgPSB0YWlsLnRyaW0oKTtcbiAgICAvLyBBY2NlcHQgZXhhY3RseSBvbmUgb2Y6IFwidGl0bGVcIiwgJ3RpdGxlJywgKHRpdGxlKSDigJQgYm91bmRlZCBhbmQgc2luZ2xlLWxpbmUuXG4gICAgaWYgKCFwb3NzaWJsZVRpdGxlIHx8IC9eXCJbXlwiXFxyXFxuXXswLDMwMH1cIiQvLnRlc3QocG9zc2libGVUaXRsZSkgfHwgL14nW14nXFxyXFxuXXswLDMwMH0nJC8udGVzdChwb3NzaWJsZVRpdGxlKSB8fCAvXlxcKFteKVxcclxcbl17MCwzMDB9XFwpJC8udGVzdChwb3NzaWJsZVRpdGxlKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSBzdGF0aWMgbWF0Y2hlc1JlZmVyZW5jZVVybERlZihsaW5lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAvLyBTaW5nbGUtbGluZSwgcHJhZ21hdGljIENvbW1vbk1hcmstc3R5bGUgcmVmZXJlbmNlIGRlZmluaXRpb24gZS5nLiBbdGV4dF06IGh0dHA6Ly9leGFtcGxlLmNvbVxuICAgIGNvbnN0IGJhc2VSZWZlcmVuY2VVcmxQYXR0ZXJuID0gL15bIFxcdF17MCwzfVxcWyhbXlxcXV17MSwxMDB9KVxcXTpbIFxcdF0qPD8oW15cXHM+XXsxLDIwNDh9KT4/WyBcXHRdKihbXiBcXHRcXHJcXG5dLiopPyQvbTtcblxuICAgIGNvbnN0IG1haW5SZWdFeCA9IGJhc2VSZWZlcmVuY2VVcmxQYXR0ZXJuLmV4ZWMobGluZSk7XG4gICAgaWYgKCFtYWluUmVnRXgpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCB0YWlsID0gbWFpblJlZ0V4WzNdID8/IFwiXCI7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZFJlZmVyZW5jZVVybFRpdGxlVGFpbCh0YWlsKTtcbiAgfVxufVxuIl19
@@ -5093,10 +5093,15 @@ class FormValidatorsService {
5093
5093
  return validator;
5094
5094
  }
5095
5095
  static markDownPatternValidator() {
5096
- const pattern = /(\[[^\]]{0,500}\]\([^)]{0,500}\)|!\[[^\]]{0,500}\]\([^)]{0,500}\)|<img[^>]{0,500}>|<a[^>]{0,500}>.*?<\/a>)/;
5096
+ // Matches: [text](url), ![alt](url), <img ...>, <a ...>...</a>
5097
+ const inlineMarkdownPattern = /(?:!?\[[^\]]{0,500}\]\([^)]{0,500}\)|<(?:img\b[^>]{0,500}>|a\b[^>]{0,500}>[\s\S]*?<\/a>))/i;
5098
+ // Matches: [text][id], ![alt][id], and the collapsed form [text][]
5099
+ const referenceBoxPattern = /(!)?\[((?:[^[\]\\]|\\.){0,500})\]\s*\[([^\]]{0,100})\]/;
5100
+ // Matches: autolinks such as <http://example.com>
5101
+ const autolinkPattern = /<(?:[A-Za-z][A-Za-z0-9+.-]*:[^ <>\n]*|[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+)>/;
5097
5102
  return (control) => {
5098
5103
  const value = control?.value?.toString().trim();
5099
- return (value && pattern.test(value)) ? { markDownPattern: {} } : null;
5104
+ return (value && (inlineMarkdownPattern.test(value) || referenceBoxPattern.test(value) || this.matchesReferenceUrlDef(value) || autolinkPattern.test(value) || this.hasMultiBracket(value))) ? { markDownPattern: {} } : null;
5100
5105
  };
5101
5106
  }
5102
5107
  // TODO: Strip this out as it's only here for the moment because
@@ -5114,6 +5119,107 @@ class FormValidatorsService {
5114
5119
  }
5115
5120
  return control;
5116
5121
  }
5122
+ // Check for multi-bracket markdown links and validate destination URL
5123
+ static hasMultiBracket(value) {
5124
+ const maxUrlString = 2048; // inside (...) excluding the final ')'
5125
+ // Sonar-friendly detector: opening-run + text + first closing ']'
5126
+ const openingTextClosePattern = /\[{1,10}[^[\]\n]{1,60}\]/;
5127
+ // Destination must be "balanced () segments, no spaces/</>/newline"
5128
+ const destinationPattern = /^[^()\s<>]+(?:\([^()\s<>]*\)[^()\s<>]*)*$/;
5129
+ let scanIndex = 0;
5130
+ const totalLength = value.length;
5131
+ while (scanIndex < totalLength) {
5132
+ const seg = this.findOpeningTextClose(value, scanIndex, openingTextClosePattern);
5133
+ if (!seg) {
5134
+ return false; // no candidate -> no match
5135
+ }
5136
+ const runs = this.extendClosingRunAndRequireParen(value, seg.absStart, seg.afterFirstClose);
5137
+ if (runs && runs.openingRunCount === runs.closingRunCount) {
5138
+ if (this.hasBalancedDestination(value, runs.afterOpenParen, maxUrlString, destinationPattern)) {
5139
+ return true; // valid multi-bracket link found
5140
+ }
5141
+ }
5142
+ // Advance to avoid stalling on overlaps
5143
+ scanIndex = seg.absStart + 1;
5144
+ }
5145
+ return false;
5146
+ }
5147
+ // Find opening '[' run, text, and first closing ']'
5148
+ static findOpeningTextClose(source, fromIndex, pattern) {
5149
+ const slice = source.slice(fromIndex);
5150
+ const match = pattern.exec(slice);
5151
+ if (!match) {
5152
+ return null;
5153
+ }
5154
+ const absStart = fromIndex + match.index;
5155
+ const afterFirstClose = absStart + match[0].length; // index just after the first ']'
5156
+ return { absStart, afterFirstClose };
5157
+ }
5158
+ // Count opening '[' run, extend the ']' run, and require '(' right after the full ']' run
5159
+ static extendClosingRunAndRequireParen(source, absStart, afterFirstClose) {
5160
+ const n = source.length;
5161
+ // Count opening '[' run (e.g., '[[[')
5162
+ let openingRunCount = 0;
5163
+ for (let i = absStart; i < n && source[i] === '['; i++) {
5164
+ openingRunCount++;
5165
+ }
5166
+ // Extend closing ']' run forward from the first one
5167
+ let closingRunCount = 1;
5168
+ let afterClosingRun = afterFirstClose;
5169
+ while (afterClosingRun < n && source[afterClosingRun] === ']') {
5170
+ closingRunCount++;
5171
+ afterClosingRun++;
5172
+ }
5173
+ // '(' must immediately follow the full closing run
5174
+ if (afterClosingRun >= n || source[afterClosingRun] !== '(') {
5175
+ return null;
5176
+ }
5177
+ return { openingRunCount, closingRunCount, afterOpenParen: afterClosingRun + 1 };
5178
+ }
5179
+ // Scan destination from afterOpenParen until its matching ')', enforcing simple URL rules
5180
+ static hasBalancedDestination(source, afterOpenParen, maxDest, destPattern) {
5181
+ const n = source.length;
5182
+ let depth = 0;
5183
+ let cursor = afterOpenParen;
5184
+ let consumed = 0;
5185
+ // Try successive ')' positions to allow inner balanced parentheses.
5186
+ while (cursor < n && consumed <= maxDest) {
5187
+ const ch = source[cursor];
5188
+ if (ch === '(') {
5189
+ depth++;
5190
+ }
5191
+ else if (ch === ')') {
5192
+ if (depth === 0) {
5193
+ const candidate = source.slice(afterOpenParen, cursor);
5194
+ return candidate.length > 0 && destPattern.test(candidate);
5195
+ }
5196
+ depth--;
5197
+ }
5198
+ else if (ch === ' ' || ch === '\t' || ch === '<' || ch === '>' || ch === '\n') {
5199
+ return false; // illegal destination character
5200
+ }
5201
+ cursor++;
5202
+ consumed++;
5203
+ }
5204
+ return false; // ran out without a valid closing ')'
5205
+ }
5206
+ static isValidReferenceUrlTitleTail(tail) {
5207
+ const possibleTitle = tail.trim();
5208
+ // Accept exactly one of: "title", 'title', (title) — bounded and single-line.
5209
+ if (!possibleTitle || /^"[^"\r\n]{0,300}"$/.test(possibleTitle) || /^'[^'\r\n]{0,300}'$/.test(possibleTitle) || /^\([^)\r\n]{0,300}\)$/.test(possibleTitle)) {
5210
+ return true;
5211
+ }
5212
+ return false;
5213
+ }
5214
+ static matchesReferenceUrlDef(line) {
5215
+ // Single-line, pragmatic CommonMark-style reference definition e.g. [text]: http://example.com
5216
+ const baseReferenceUrlPattern = /^[ \t]{0,3}\[([^\]]{1,100})\]:[ \t]*<?([^\s>]{1,2048})>?[ \t]*([^ \t\r\n].*)?$/m;
5217
+ const mainRegEx = baseReferenceUrlPattern.exec(line);
5218
+ if (!mainRegEx)
5219
+ return false;
5220
+ const tail = mainRegEx[3] ?? "";
5221
+ return this.isValidReferenceUrlTitleTail(tail);
5222
+ }
5117
5223
  static ɵfac = function FormValidatorsService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FormValidatorsService)(); };
5118
5224
  static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: FormValidatorsService, factory: FormValidatorsService.ɵfac });
5119
5225
  }