source: frontend/node_modules/yaml/dist/PlainValue-516d5bc2.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 20.3 KB
Line 
1'use strict';
2
3const Char = {
4 ANCHOR: '&',
5 COMMENT: '#',
6 TAG: '!',
7 DIRECTIVES_END: '-',
8 DOCUMENT_END: '.'
9};
10const Type = {
11 ALIAS: 'ALIAS',
12 BLANK_LINE: 'BLANK_LINE',
13 BLOCK_FOLDED: 'BLOCK_FOLDED',
14 BLOCK_LITERAL: 'BLOCK_LITERAL',
15 COMMENT: 'COMMENT',
16 DIRECTIVE: 'DIRECTIVE',
17 DOCUMENT: 'DOCUMENT',
18 FLOW_MAP: 'FLOW_MAP',
19 FLOW_SEQ: 'FLOW_SEQ',
20 MAP: 'MAP',
21 MAP_KEY: 'MAP_KEY',
22 MAP_VALUE: 'MAP_VALUE',
23 PLAIN: 'PLAIN',
24 QUOTE_DOUBLE: 'QUOTE_DOUBLE',
25 QUOTE_SINGLE: 'QUOTE_SINGLE',
26 SEQ: 'SEQ',
27 SEQ_ITEM: 'SEQ_ITEM'
28};
29const defaultTagPrefix = 'tag:yaml.org,2002:';
30const defaultTags = {
31 MAP: 'tag:yaml.org,2002:map',
32 SEQ: 'tag:yaml.org,2002:seq',
33 STR: 'tag:yaml.org,2002:str'
34};
35
36function findLineStarts(src) {
37 const ls = [0];
38 let offset = src.indexOf('\n');
39 while (offset !== -1) {
40 offset += 1;
41 ls.push(offset);
42 offset = src.indexOf('\n', offset);
43 }
44 return ls;
45}
46function getSrcInfo(cst) {
47 let lineStarts, src;
48 if (typeof cst === 'string') {
49 lineStarts = findLineStarts(cst);
50 src = cst;
51 } else {
52 if (Array.isArray(cst)) cst = cst[0];
53 if (cst && cst.context) {
54 if (!cst.lineStarts) cst.lineStarts = findLineStarts(cst.context.src);
55 lineStarts = cst.lineStarts;
56 src = cst.context.src;
57 }
58 }
59 return {
60 lineStarts,
61 src
62 };
63}
64
65/**
66 * @typedef {Object} LinePos - One-indexed position in the source
67 * @property {number} line
68 * @property {number} col
69 */
70
71/**
72 * Determine the line/col position matching a character offset.
73 *
74 * Accepts a source string or a CST document as the second parameter. With
75 * the latter, starting indices for lines are cached in the document as
76 * `lineStarts: number[]`.
77 *
78 * Returns a one-indexed `{ line, col }` location if found, or
79 * `undefined` otherwise.
80 *
81 * @param {number} offset
82 * @param {string|Document|Document[]} cst
83 * @returns {?LinePos}
84 */
85function getLinePos(offset, cst) {
86 if (typeof offset !== 'number' || offset < 0) return null;
87 const {
88 lineStarts,
89 src
90 } = getSrcInfo(cst);
91 if (!lineStarts || !src || offset > src.length) return null;
92 for (let i = 0; i < lineStarts.length; ++i) {
93 const start = lineStarts[i];
94 if (offset < start) {
95 return {
96 line: i,
97 col: offset - lineStarts[i - 1] + 1
98 };
99 }
100 if (offset === start) return {
101 line: i + 1,
102 col: 1
103 };
104 }
105 const line = lineStarts.length;
106 return {
107 line,
108 col: offset - lineStarts[line - 1] + 1
109 };
110}
111
112/**
113 * Get a specified line from the source.
114 *
115 * Accepts a source string or a CST document as the second parameter. With
116 * the latter, starting indices for lines are cached in the document as
117 * `lineStarts: number[]`.
118 *
119 * Returns the line as a string if found, or `null` otherwise.
120 *
121 * @param {number} line One-indexed line number
122 * @param {string|Document|Document[]} cst
123 * @returns {?string}
124 */
125function getLine(line, cst) {
126 const {
127 lineStarts,
128 src
129 } = getSrcInfo(cst);
130 if (!lineStarts || !(line >= 1) || line > lineStarts.length) return null;
131 const start = lineStarts[line - 1];
132 let end = lineStarts[line]; // undefined for last line; that's ok for slice()
133 while (end && end > start && src[end - 1] === '\n') --end;
134 return src.slice(start, end);
135}
136
137/**
138 * Pretty-print the starting line from the source indicated by the range `pos`
139 *
140 * Trims output to `maxWidth` chars while keeping the starting column visible,
141 * using `…` at either end to indicate dropped characters.
142 *
143 * Returns a two-line string (or `null`) with `\n` as separator; the second line
144 * will hold appropriately indented `^` marks indicating the column range.
145 *
146 * @param {Object} pos
147 * @param {LinePos} pos.start
148 * @param {LinePos} [pos.end]
149 * @param {string|Document|Document[]*} cst
150 * @param {number} [maxWidth=80]
151 * @returns {?string}
152 */
153function getPrettyContext({
154 start,
155 end
156}, cst, maxWidth = 80) {
157 let src = getLine(start.line, cst);
158 if (!src) return null;
159 let {
160 col
161 } = start;
162 if (src.length > maxWidth) {
163 if (col <= maxWidth - 10) {
164 src = src.substr(0, maxWidth - 1) + '…';
165 } else {
166 const halfWidth = Math.round(maxWidth / 2);
167 if (src.length > col + halfWidth) src = src.substr(0, col + halfWidth - 1) + '…';
168 col -= src.length - maxWidth;
169 src = '…' + src.substr(1 - maxWidth);
170 }
171 }
172 let errLen = 1;
173 let errEnd = '';
174 if (end) {
175 if (end.line === start.line && col + (end.col - start.col) <= maxWidth + 1) {
176 errLen = end.col - start.col;
177 } else {
178 errLen = Math.min(src.length + 1, maxWidth) - col;
179 errEnd = '…';
180 }
181 }
182 const offset = col > 1 ? ' '.repeat(col - 1) : '';
183 const err = '^'.repeat(errLen);
184 return `${src}\n${offset}${err}${errEnd}`;
185}
186
187class Range {
188 static copy(orig) {
189 return new Range(orig.start, orig.end);
190 }
191 constructor(start, end) {
192 this.start = start;
193 this.end = end || start;
194 }
195 isEmpty() {
196 return typeof this.start !== 'number' || !this.end || this.end <= this.start;
197 }
198
199 /**
200 * Set `origStart` and `origEnd` to point to the original source range for
201 * this node, which may differ due to dropped CR characters.
202 *
203 * @param {number[]} cr - Positions of dropped CR characters
204 * @param {number} offset - Starting index of `cr` from the last call
205 * @returns {number} - The next offset, matching the one found for `origStart`
206 */
207 setOrigRange(cr, offset) {
208 const {
209 start,
210 end
211 } = this;
212 if (cr.length === 0 || end <= cr[0]) {
213 this.origStart = start;
214 this.origEnd = end;
215 return offset;
216 }
217 let i = offset;
218 while (i < cr.length) {
219 if (cr[i] > start) break;else ++i;
220 }
221 this.origStart = start + i;
222 const nextOffset = i;
223 while (i < cr.length) {
224 // if end was at \n, it should now be at \r
225 if (cr[i] >= end) break;else ++i;
226 }
227 this.origEnd = end + i;
228 return nextOffset;
229 }
230}
231
232/** Root class of all nodes */
233class Node {
234 static addStringTerminator(src, offset, str) {
235 if (str[str.length - 1] === '\n') return str;
236 const next = Node.endOfWhiteSpace(src, offset);
237 return next >= src.length || src[next] === '\n' ? str + '\n' : str;
238 }
239
240 // ^(---|...)
241 static atDocumentBoundary(src, offset, sep) {
242 const ch0 = src[offset];
243 if (!ch0) return true;
244 const prev = src[offset - 1];
245 if (prev && prev !== '\n') return false;
246 if (sep) {
247 if (ch0 !== sep) return false;
248 } else {
249 if (ch0 !== Char.DIRECTIVES_END && ch0 !== Char.DOCUMENT_END) return false;
250 }
251 const ch1 = src[offset + 1];
252 const ch2 = src[offset + 2];
253 if (ch1 !== ch0 || ch2 !== ch0) return false;
254 const ch3 = src[offset + 3];
255 return !ch3 || ch3 === '\n' || ch3 === '\t' || ch3 === ' ';
256 }
257 static endOfIdentifier(src, offset) {
258 let ch = src[offset];
259 const isVerbatim = ch === '<';
260 const notOk = isVerbatim ? ['\n', '\t', ' ', '>'] : ['\n', '\t', ' ', '[', ']', '{', '}', ','];
261 while (ch && notOk.indexOf(ch) === -1) ch = src[offset += 1];
262 if (isVerbatim && ch === '>') offset += 1;
263 return offset;
264 }
265 static endOfIndent(src, offset) {
266 let ch = src[offset];
267 while (ch === ' ') ch = src[offset += 1];
268 return offset;
269 }
270 static endOfLine(src, offset) {
271 let ch = src[offset];
272 while (ch && ch !== '\n') ch = src[offset += 1];
273 return offset;
274 }
275 static endOfWhiteSpace(src, offset) {
276 let ch = src[offset];
277 while (ch === '\t' || ch === ' ') ch = src[offset += 1];
278 return offset;
279 }
280 static startOfLine(src, offset) {
281 let ch = src[offset - 1];
282 if (ch === '\n') return offset;
283 while (ch && ch !== '\n') ch = src[offset -= 1];
284 return offset + 1;
285 }
286
287 /**
288 * End of indentation, or null if the line's indent level is not more
289 * than `indent`
290 *
291 * @param {string} src
292 * @param {number} indent
293 * @param {number} lineStart
294 * @returns {?number}
295 */
296 static endOfBlockIndent(src, indent, lineStart) {
297 const inEnd = Node.endOfIndent(src, lineStart);
298 if (inEnd > lineStart + indent) {
299 return inEnd;
300 } else {
301 const wsEnd = Node.endOfWhiteSpace(src, inEnd);
302 const ch = src[wsEnd];
303 if (!ch || ch === '\n') return wsEnd;
304 }
305 return null;
306 }
307 static atBlank(src, offset, endAsBlank) {
308 const ch = src[offset];
309 return ch === '\n' || ch === '\t' || ch === ' ' || endAsBlank && !ch;
310 }
311 static nextNodeIsIndented(ch, indentDiff, indicatorAsIndent) {
312 if (!ch || indentDiff < 0) return false;
313 if (indentDiff > 0) return true;
314 return indicatorAsIndent && ch === '-';
315 }
316
317 // should be at line or string end, or at next non-whitespace char
318 static normalizeOffset(src, offset) {
319 const ch = src[offset];
320 return !ch ? offset : ch !== '\n' && src[offset - 1] === '\n' ? offset - 1 : Node.endOfWhiteSpace(src, offset);
321 }
322
323 // fold single newline into space, multiple newlines to N - 1 newlines
324 // presumes src[offset] === '\n'
325 static foldNewline(src, offset, indent) {
326 let inCount = 0;
327 let error = false;
328 let fold = '';
329 let ch = src[offset + 1];
330 while (ch === ' ' || ch === '\t' || ch === '\n') {
331 switch (ch) {
332 case '\n':
333 inCount = 0;
334 offset += 1;
335 fold += '\n';
336 break;
337 case '\t':
338 if (inCount <= indent) error = true;
339 offset = Node.endOfWhiteSpace(src, offset + 2) - 1;
340 break;
341 case ' ':
342 inCount += 1;
343 offset += 1;
344 break;
345 }
346 ch = src[offset + 1];
347 }
348 if (!fold) fold = ' ';
349 if (ch && inCount <= indent) error = true;
350 return {
351 fold,
352 offset,
353 error
354 };
355 }
356 constructor(type, props, context) {
357 Object.defineProperty(this, 'context', {
358 value: context || null,
359 writable: true
360 });
361 this.error = null;
362 this.range = null;
363 this.valueRange = null;
364 this.props = props || [];
365 this.type = type;
366 this.value = null;
367 }
368 getPropValue(idx, key, skipKey) {
369 if (!this.context) return null;
370 const {
371 src
372 } = this.context;
373 const prop = this.props[idx];
374 return prop && src[prop.start] === key ? src.slice(prop.start + (skipKey ? 1 : 0), prop.end) : null;
375 }
376 get anchor() {
377 for (let i = 0; i < this.props.length; ++i) {
378 const anchor = this.getPropValue(i, Char.ANCHOR, true);
379 if (anchor != null) return anchor;
380 }
381 return null;
382 }
383 get comment() {
384 const comments = [];
385 for (let i = 0; i < this.props.length; ++i) {
386 const comment = this.getPropValue(i, Char.COMMENT, true);
387 if (comment != null) comments.push(comment);
388 }
389 return comments.length > 0 ? comments.join('\n') : null;
390 }
391 commentHasRequiredWhitespace(start) {
392 const {
393 src
394 } = this.context;
395 if (this.header && start === this.header.end) return false;
396 if (!this.valueRange) return false;
397 const {
398 end
399 } = this.valueRange;
400 return start !== end || Node.atBlank(src, end - 1);
401 }
402 get hasComment() {
403 if (this.context) {
404 const {
405 src
406 } = this.context;
407 for (let i = 0; i < this.props.length; ++i) {
408 if (src[this.props[i].start] === Char.COMMENT) return true;
409 }
410 }
411 return false;
412 }
413 get hasProps() {
414 if (this.context) {
415 const {
416 src
417 } = this.context;
418 for (let i = 0; i < this.props.length; ++i) {
419 if (src[this.props[i].start] !== Char.COMMENT) return true;
420 }
421 }
422 return false;
423 }
424 get includesTrailingLines() {
425 return false;
426 }
427 get jsonLike() {
428 const jsonLikeTypes = [Type.FLOW_MAP, Type.FLOW_SEQ, Type.QUOTE_DOUBLE, Type.QUOTE_SINGLE];
429 return jsonLikeTypes.indexOf(this.type) !== -1;
430 }
431 get rangeAsLinePos() {
432 if (!this.range || !this.context) return undefined;
433 const start = getLinePos(this.range.start, this.context.root);
434 if (!start) return undefined;
435 const end = getLinePos(this.range.end, this.context.root);
436 return {
437 start,
438 end
439 };
440 }
441 get rawValue() {
442 if (!this.valueRange || !this.context) return null;
443 const {
444 start,
445 end
446 } = this.valueRange;
447 return this.context.src.slice(start, end);
448 }
449 get tag() {
450 for (let i = 0; i < this.props.length; ++i) {
451 const tag = this.getPropValue(i, Char.TAG, false);
452 if (tag != null) {
453 if (tag[1] === '<') {
454 return {
455 verbatim: tag.slice(2, -1)
456 };
457 } else {
458 // eslint-disable-next-line no-unused-vars
459 const [_, handle, suffix] = tag.match(/^(.*!)([^!]*)$/);
460 return {
461 handle,
462 suffix
463 };
464 }
465 }
466 }
467 return null;
468 }
469 get valueRangeContainsNewline() {
470 if (!this.valueRange || !this.context) return false;
471 const {
472 start,
473 end
474 } = this.valueRange;
475 const {
476 src
477 } = this.context;
478 for (let i = start; i < end; ++i) {
479 if (src[i] === '\n') return true;
480 }
481 return false;
482 }
483 parseComment(start) {
484 const {
485 src
486 } = this.context;
487 if (src[start] === Char.COMMENT) {
488 const end = Node.endOfLine(src, start + 1);
489 const commentRange = new Range(start, end);
490 this.props.push(commentRange);
491 return end;
492 }
493 return start;
494 }
495
496 /**
497 * Populates the `origStart` and `origEnd` values of all ranges for this
498 * node. Extended by child classes to handle descendant nodes.
499 *
500 * @param {number[]} cr - Positions of dropped CR characters
501 * @param {number} offset - Starting index of `cr` from the last call
502 * @returns {number} - The next offset, matching the one found for `origStart`
503 */
504 setOrigRanges(cr, offset) {
505 if (this.range) offset = this.range.setOrigRange(cr, offset);
506 if (this.valueRange) this.valueRange.setOrigRange(cr, offset);
507 this.props.forEach(prop => prop.setOrigRange(cr, offset));
508 return offset;
509 }
510 toString() {
511 const {
512 context: {
513 src
514 },
515 range,
516 value
517 } = this;
518 if (value != null) return value;
519 const str = src.slice(range.start, range.end);
520 return Node.addStringTerminator(src, range.end, str);
521 }
522}
523
524class YAMLError extends Error {
525 constructor(name, source, message) {
526 if (!message || !(source instanceof Node)) throw new Error(`Invalid arguments for new ${name}`);
527 super();
528 this.name = name;
529 this.message = message;
530 this.source = source;
531 }
532 makePretty() {
533 if (!this.source) return;
534 this.nodeType = this.source.type;
535 const cst = this.source.context && this.source.context.root;
536 if (typeof this.offset === 'number') {
537 this.range = new Range(this.offset, this.offset + 1);
538 const start = cst && getLinePos(this.offset, cst);
539 if (start) {
540 const end = {
541 line: start.line,
542 col: start.col + 1
543 };
544 this.linePos = {
545 start,
546 end
547 };
548 }
549 delete this.offset;
550 } else {
551 this.range = this.source.range;
552 this.linePos = this.source.rangeAsLinePos;
553 }
554 if (this.linePos) {
555 const {
556 line,
557 col
558 } = this.linePos.start;
559 this.message += ` at line ${line}, column ${col}`;
560 const ctx = cst && getPrettyContext(this.linePos, cst);
561 if (ctx) this.message += `:\n\n${ctx}\n`;
562 }
563 delete this.source;
564 }
565}
566class YAMLReferenceError extends YAMLError {
567 constructor(source, message) {
568 super('YAMLReferenceError', source, message);
569 }
570}
571class YAMLSemanticError extends YAMLError {
572 constructor(source, message) {
573 super('YAMLSemanticError', source, message);
574 }
575}
576class YAMLSyntaxError extends YAMLError {
577 constructor(source, message) {
578 super('YAMLSyntaxError', source, message);
579 }
580}
581class YAMLWarning extends YAMLError {
582 constructor(source, message) {
583 super('YAMLWarning', source, message);
584 }
585}
586
587function _defineProperty(e, r, t) {
588 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
589 value: t,
590 enumerable: !0,
591 configurable: !0,
592 writable: !0
593 }) : e[r] = t, e;
594}
595function _toPrimitive(t, r) {
596 if ("object" != typeof t || !t) return t;
597 var e = t[Symbol.toPrimitive];
598 if (void 0 !== e) {
599 var i = e.call(t, r || "default");
600 if ("object" != typeof i) return i;
601 throw new TypeError("@@toPrimitive must return a primitive value.");
602 }
603 return ("string" === r ? String : Number)(t);
604}
605function _toPropertyKey(t) {
606 var i = _toPrimitive(t, "string");
607 return "symbol" == typeof i ? i : i + "";
608}
609
610class PlainValue extends Node {
611 static endOfLine(src, start, inFlow) {
612 let ch = src[start];
613 let offset = start;
614 while (ch && ch !== '\n') {
615 if (inFlow && (ch === '[' || ch === ']' || ch === '{' || ch === '}' || ch === ',')) break;
616 const next = src[offset + 1];
617 if (ch === ':' && (!next || next === '\n' || next === '\t' || next === ' ' || inFlow && next === ',')) break;
618 if ((ch === ' ' || ch === '\t') && next === '#') break;
619 offset += 1;
620 ch = next;
621 }
622 return offset;
623 }
624 get strValue() {
625 if (!this.valueRange || !this.context) return null;
626 let {
627 start,
628 end
629 } = this.valueRange;
630 const {
631 src
632 } = this.context;
633 let ch = src[end - 1];
634 while (start < end && (ch === '\n' || ch === '\t' || ch === ' ')) ch = src[--end - 1];
635 let str = '';
636 for (let i = start; i < end; ++i) {
637 const ch = src[i];
638 if (ch === '\n') {
639 const {
640 fold,
641 offset
642 } = Node.foldNewline(src, i, -1);
643 str += fold;
644 i = offset;
645 } else if (ch === ' ' || ch === '\t') {
646 // trim trailing whitespace
647 const wsStart = i;
648 let next = src[i + 1];
649 while (i < end && (next === ' ' || next === '\t')) {
650 i += 1;
651 next = src[i + 1];
652 }
653 if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch;
654 } else {
655 str += ch;
656 }
657 }
658 const ch0 = src[start];
659 switch (ch0) {
660 case '\t':
661 {
662 const msg = 'Plain value cannot start with a tab character';
663 const errors = [new YAMLSemanticError(this, msg)];
664 return {
665 errors,
666 str
667 };
668 }
669 case '@':
670 case '`':
671 {
672 const msg = `Plain value cannot start with reserved character ${ch0}`;
673 const errors = [new YAMLSemanticError(this, msg)];
674 return {
675 errors,
676 str
677 };
678 }
679 default:
680 return str;
681 }
682 }
683 parseBlockValue(start) {
684 const {
685 indent,
686 inFlow,
687 src
688 } = this.context;
689 let offset = start;
690 let valueEnd = start;
691 for (let ch = src[offset]; ch === '\n'; ch = src[offset]) {
692 if (Node.atDocumentBoundary(src, offset + 1)) break;
693 const end = Node.endOfBlockIndent(src, indent, offset + 1);
694 if (end === null || src[end] === '#') break;
695 if (src[end] === '\n') {
696 offset = end;
697 } else {
698 valueEnd = PlainValue.endOfLine(src, end, inFlow);
699 offset = valueEnd;
700 }
701 }
702 if (this.valueRange.isEmpty()) this.valueRange.start = start;
703 this.valueRange.end = valueEnd;
704 return valueEnd;
705 }
706
707 /**
708 * Parses a plain value from the source
709 *
710 * Accepted forms are:
711 * ```
712 * #comment
713 *
714 * first line
715 *
716 * first line #comment
717 *
718 * first line
719 * block
720 * lines
721 *
722 * #comment
723 * block
724 * lines
725 * ```
726 * where block lines are empty or have an indent level greater than `indent`.
727 *
728 * @param {ParseContext} context
729 * @param {number} start - Index of first character
730 * @returns {number} - Index of the character after this scalar, may be `\n`
731 */
732 parse(context, start) {
733 this.context = context;
734 const {
735 inFlow,
736 src
737 } = context;
738 let offset = start;
739 const ch = src[offset];
740 if (ch && ch !== '#' && ch !== '\n') {
741 offset = PlainValue.endOfLine(src, start, inFlow);
742 }
743 this.valueRange = new Range(start, offset);
744 offset = Node.endOfWhiteSpace(src, offset);
745 offset = this.parseComment(offset);
746 if (!this.hasComment || this.valueRange.isEmpty()) {
747 offset = this.parseBlockValue(offset);
748 }
749 return offset;
750 }
751}
752
753exports.Char = Char;
754exports.Node = Node;
755exports.PlainValue = PlainValue;
756exports.Range = Range;
757exports.Type = Type;
758exports.YAMLError = YAMLError;
759exports.YAMLReferenceError = YAMLReferenceError;
760exports.YAMLSemanticError = YAMLSemanticError;
761exports.YAMLSyntaxError = YAMLSyntaxError;
762exports.YAMLWarning = YAMLWarning;
763exports._defineProperty = _defineProperty;
764exports.defaultTagPrefix = defaultTagPrefix;
765exports.defaultTags = defaultTags;
Note: See TracBrowser for help on using the repository browser.