1
2/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */
3function isNothing(subject) {
4  return (typeof subject === 'undefined') || (subject === null);
5}
6
7
8function isObject(subject) {
9  return (typeof subject === 'object') && (subject !== null);
10}
11
12
13function toArray(sequence) {
14  if (Array.isArray(sequence)) return sequence;
15  else if (isNothing(sequence)) return [];
16
17  return [ sequence ];
18}
19
20
21function extend(target, source) {
22  var index, length, key, sourceKeys;
23
24  if (source) {
25    sourceKeys = Object.keys(source);
26
27    for (index = 0, length = sourceKeys.length; index < length; index += 1) {
28      key = sourceKeys[index];
29      target[key] = source[key];
30    }
31  }
32
33  return target;
34}
35
36
37function repeat(string, count) {
38  var result = '', cycle;
39
40  for (cycle = 0; cycle < count; cycle += 1) {
41    result += string;
42  }
43
44  return result;
45}
46
47
48function isNegativeZero(number) {
49  return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);
50}
51
52
53var isNothing_1      = isNothing;
54var isObject_1       = isObject;
55var toArray_1        = toArray;
56var repeat_1         = repeat;
57var isNegativeZero_1 = isNegativeZero;
58var extend_1         = extend;
59
60var common = {
61	isNothing: isNothing_1,
62	isObject: isObject_1,
63	toArray: toArray_1,
64	repeat: repeat_1,
65	isNegativeZero: isNegativeZero_1,
66	extend: extend_1
67};
68
69// YAML error class. http://stackoverflow.com/questions/8458984
70
71
72function formatError(exception, compact) {
73  var where = '', message = exception.reason || '(unknown reason)';
74
75  if (!exception.mark) return message;
76
77  if (exception.mark.name) {
78    where += 'in "' + exception.mark.name + '" ';
79  }
80
81  where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';
82
83  if (!compact && exception.mark.snippet) {
84    where += '\n\n' + exception.mark.snippet;
85  }
86
87  return message + ' ' + where;
88}
89
90
91function YAMLException$1(reason, mark) {
92  // Super constructor
93  Error.call(this);
94
95  this.name = 'YAMLException';
96  this.reason = reason;
97  this.mark = mark;
98  this.message = formatError(this, false);
99
100  // Include stack trace in error object
101  if (Error.captureStackTrace) {
102    // Chrome and NodeJS
103    Error.captureStackTrace(this, this.constructor);
104  } else {
105    // FF, IE 10+ and Safari 6+. Fallback for others
106    this.stack = (new Error()).stack || '';
107  }
108}
109
110
111// Inherit from Error
112YAMLException$1.prototype = Object.create(Error.prototype);
113YAMLException$1.prototype.constructor = YAMLException$1;
114
115
116YAMLException$1.prototype.toString = function toString(compact) {
117  return this.name + ': ' + formatError(this, compact);
118};
119
120
121var exception = YAMLException$1;
122
123// get snippet for a single line, respecting maxLength
124function getLine(buffer, lineStart, lineEnd, position, maxLineLength) {
125  var head = '';
126  var tail = '';
127  var maxHalfLength = Math.floor(maxLineLength / 2) - 1;
128
129  if (position - lineStart > maxHalfLength) {
130    head = ' ... ';
131    lineStart = position - maxHalfLength + head.length;
132  }
133
134  if (lineEnd - position > maxHalfLength) {
135    tail = ' ...';
136    lineEnd = position + maxHalfLength - tail.length;
137  }
138
139  return {
140    str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail,
141    pos: position - lineStart + head.length // relative position
142  };
143}
144
145
146function padStart(string, max) {
147  return common.repeat(' ', max - string.length) + string;
148}
149
150
151function makeSnippet(mark, options) {
152  options = Object.create(options || null);
153
154  if (!mark.buffer) return null;
155
156  if (!options.maxLength) options.maxLength = 79;
157  if (typeof options.indent      !== 'number') options.indent      = 1;
158  if (typeof options.linesBefore !== 'number') options.linesBefore = 3;
159  if (typeof options.linesAfter  !== 'number') options.linesAfter  = 2;
160
161  var re = /\r?\n|\r|\0/g;
162  var lineStarts = [ 0 ];
163  var lineEnds = [];
164  var match;
165  var foundLineNo = -1;
166
167  while ((match = re.exec(mark.buffer))) {
168    lineEnds.push(match.index);
169    lineStarts.push(match.index + match[0].length);
170
171    if (mark.position <= match.index && foundLineNo < 0) {
172      foundLineNo = lineStarts.length - 2;
173    }
174  }
175
176  if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;
177
178  var result = '', i, line;
179  var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;
180  var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);
181
182  for (i = 1; i <= options.linesBefore; i++) {
183    if (foundLineNo - i < 0) break;
184    line = getLine(
185      mark.buffer,
186      lineStarts[foundLineNo - i],
187      lineEnds[foundLineNo - i],
188      mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),
189      maxLineLength
190    );
191    result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +
192      ' | ' + line.str + '\n' + result;
193  }
194
195  line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);
196  result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +
197    ' | ' + line.str + '\n';
198  result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n';
199
200  for (i = 1; i <= options.linesAfter; i++) {
201    if (foundLineNo + i >= lineEnds.length) break;
202    line = getLine(
203      mark.buffer,
204      lineStarts[foundLineNo + i],
205      lineEnds[foundLineNo + i],
206      mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),
207      maxLineLength
208    );
209    result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +
210      ' | ' + line.str + '\n';
211  }
212
213  return result.replace(/\n$/, '');
214}
215
216
217var snippet = makeSnippet;
218
219var TYPE_CONSTRUCTOR_OPTIONS = [
220  'kind',
221  'multi',
222  'resolve',
223  'construct',
224  'instanceOf',
225  'predicate',
226  'represent',
227  'representName',
228  'defaultStyle',
229  'styleAliases'
230];
231
232var YAML_NODE_KINDS = [
233  'scalar',
234  'sequence',
235  'mapping'
236];
237
238function compileStyleAliases(map) {
239  var result = {};
240
241  if (map !== null) {
242    Object.keys(map).forEach(function (style) {
243      map[style].forEach(function (alias) {
244        result[String(alias)] = style;
245      });
246    });
247  }
248
249  return result;
250}
251
252function Type$1(tag, options) {
253  options = options || {};
254
255  Object.keys(options).forEach(function (name) {
256    if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
257      throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
258    }
259  });
260
261  // TODO: Add tag format check.
262  this.options       = options; // keep original options in case user wants to extend this type later
263  this.tag           = tag;
264  this.kind          = options['kind']          || null;
265  this.resolve       = options['resolve']       || function () { return true; };
266  this.construct     = options['construct']     || function (data) { return data; };
267  this.instanceOf    = options['instanceOf']    || null;
268  this.predicate     = options['predicate']     || null;
269  this.represent     = options['represent']     || null;
270  this.representName = options['representName'] || null;
271  this.defaultStyle  = options['defaultStyle']  || null;
272  this.multi         = options['multi']         || false;
273  this.styleAliases  = compileStyleAliases(options['styleAliases'] || null);
274
275  if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
276    throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
277  }
278}
279
280var type = Type$1;
281
282/*eslint-disable max-len*/
283
284
285
286
287
288function compileList(schema, name) {
289  var result = [];
290
291  schema[name].forEach(function (currentType) {
292    var newIndex = result.length;
293
294    result.forEach(function (previousType, previousIndex) {
295      if (previousType.tag === currentType.tag &&
296          previousType.kind === currentType.kind &&
297          previousType.multi === currentType.multi) {
298
299        newIndex = previousIndex;
300      }
301    });
302
303    result[newIndex] = currentType;
304  });
305
306  return result;
307}
308
309
310function compileMap(/* lists... */) {
311  var result = {
312        scalar: {},
313        sequence: {},
314        mapping: {},
315        fallback: {},
316        multi: {
317          scalar: [],
318          sequence: [],
319          mapping: [],
320          fallback: []
321        }
322      }, index, length;
323
324  function collectType(type) {
325    if (type.multi) {
326      result.multi[type.kind].push(type);
327      result.multi['fallback'].push(type);
328    } else {
329      result[type.kind][type.tag] = result['fallback'][type.tag] = type;
330    }
331  }
332
333  for (index = 0, length = arguments.length; index < length; index += 1) {
334    arguments[index].forEach(collectType);
335  }
336  return result;
337}
338
339
340function Schema$1(definition) {
341  return this.extend(definition);
342}
343
344
345Schema$1.prototype.extend = function extend(definition) {
346  var implicit = [];
347  var explicit = [];
348
349  if (definition instanceof type) {
350    // Schema.extend(type)
351    explicit.push(definition);
352
353  } else if (Array.isArray(definition)) {
354    // Schema.extend([ type1, type2, ... ])
355    explicit = explicit.concat(definition);
356
357  } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
358    // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })
359    if (definition.implicit) implicit = implicit.concat(definition.implicit);
360    if (definition.explicit) explicit = explicit.concat(definition.explicit);
361
362  } else {
363    throw new exception('Schema.extend argument should be a Type, [ Type ], ' +
364      'or a schema definition ({ implicit: [...], explicit: [...] })');
365  }
366
367  implicit.forEach(function (type$1) {
368    if (!(type$1 instanceof type)) {
369      throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');
370    }
371
372    if (type$1.loadKind && type$1.loadKind !== 'scalar') {
373      throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
374    }
375
376    if (type$1.multi) {
377      throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');
378    }
379  });
380
381  explicit.forEach(function (type$1) {
382    if (!(type$1 instanceof type)) {
383      throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');
384    }
385  });
386
387  var result = Object.create(Schema$1.prototype);
388
389  result.implicit = (this.implicit || []).concat(implicit);
390  result.explicit = (this.explicit || []).concat(explicit);
391
392  result.compiledImplicit = compileList(result, 'implicit');
393  result.compiledExplicit = compileList(result, 'explicit');
394  result.compiledTypeMap  = compileMap(result.compiledImplicit, result.compiledExplicit);
395
396  return result;
397};
398
399
400var schema = Schema$1;
401
402var str = new type('tag:yaml.org,2002:str', {
403  kind: 'scalar',
404  construct: function (data) { return data !== null ? data : ''; }
405});
406
407var seq = new type('tag:yaml.org,2002:seq', {
408  kind: 'sequence',
409  construct: function (data) { return data !== null ? data : []; }
410});
411
412var map = new type('tag:yaml.org,2002:map', {
413  kind: 'mapping',
414  construct: function (data) { return data !== null ? data : {}; }
415});
416
417var failsafe = new schema({
418  explicit: [
419    str,
420    seq,
421    map
422  ]
423});
424
425function resolveYamlNull(data) {
426  if (data === null) return true;
427
428  var max = data.length;
429
430  return (max === 1 && data === '~') ||
431         (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
432}
433
434function constructYamlNull() {
435  return null;
436}
437
438function isNull(object) {
439  return object === null;
440}
441
442var _null = new type('tag:yaml.org,2002:null', {
443  kind: 'scalar',
444  resolve: resolveYamlNull,
445  construct: constructYamlNull,
446  predicate: isNull,
447  represent: {
448    canonical: function () { return '~';    },
449    lowercase: function () { return 'null'; },
450    uppercase: function () { return 'NULL'; },
451    camelcase: function () { return 'Null'; },
452    empty:     function () { return '';     }
453  },
454  defaultStyle: 'lowercase'
455});
456
457function resolveYamlBoolean(data) {
458  if (data === null) return false;
459
460  var max = data.length;
461
462  return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
463         (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
464}
465
466function constructYamlBoolean(data) {
467  return data === 'true' ||
468         data === 'True' ||
469         data === 'TRUE';
470}
471
472function isBoolean(object) {
473  return Object.prototype.toString.call(object) === '[object Boolean]';
474}
475
476var bool = new type('tag:yaml.org,2002:bool', {
477  kind: 'scalar',
478  resolve: resolveYamlBoolean,
479  construct: constructYamlBoolean,
480  predicate: isBoolean,
481  represent: {
482    lowercase: function (object) { return object ? 'true' : 'false'; },
483    uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },
484    camelcase: function (object) { return object ? 'True' : 'False'; }
485  },
486  defaultStyle: 'lowercase'
487});
488
489function isHexCode(c) {
490  return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
491         ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
492         ((0x61/* a */ <= c) && (c <= 0x66/* f */));
493}
494
495function isOctCode(c) {
496  return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
497}
498
499function isDecCode(c) {
500  return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
501}
502
503function resolveYamlInteger(data) {
504  if (data === null) return false;
505
506  var max = data.length,
507      index = 0,
508      hasDigits = false,
509      ch;
510
511  if (!max) return false;
512
513  ch = data[index];
514
515  // sign
516  if (ch === '-' || ch === '+') {
517    ch = data[++index];
518  }
519
520  if (ch === '0') {
521    // 0
522    if (index + 1 === max) return true;
523    ch = data[++index];
524
525    // base 2, base 8, base 16
526
527    if (ch === 'b') {
528      // base 2
529      index++;
530
531      for (; index < max; index++) {
532        ch = data[index];
533        if (ch === '_') continue;
534        if (ch !== '0' && ch !== '1') return false;
535        hasDigits = true;
536      }
537      return hasDigits && ch !== '_';
538    }
539
540
541    if (ch === 'x') {
542      // base 16
543      index++;
544
545      for (; index < max; index++) {
546        ch = data[index];
547        if (ch === '_') continue;
548        if (!isHexCode(data.charCodeAt(index))) return false;
549        hasDigits = true;
550      }
551      return hasDigits && ch !== '_';
552    }
553
554
555    if (ch === 'o') {
556      // base 8
557      index++;
558
559      for (; index < max; index++) {
560        ch = data[index];
561        if (ch === '_') continue;
562        if (!isOctCode(data.charCodeAt(index))) return false;
563        hasDigits = true;
564      }
565      return hasDigits && ch !== '_';
566    }
567  }
568
569  // base 10 (except 0)
570
571  // value should not start with `_`;
572  if (ch === '_') return false;
573
574  for (; index < max; index++) {
575    ch = data[index];
576    if (ch === '_') continue;
577    if (!isDecCode(data.charCodeAt(index))) {
578      return false;
579    }
580    hasDigits = true;
581  }
582
583  // Should have digits and should not end with `_`
584  if (!hasDigits || ch === '_') return false;
585
586  return true;
587}
588
589function constructYamlInteger(data) {
590  var value = data, sign = 1, ch;
591
592  if (value.indexOf('_') !== -1) {
593    value = value.replace(/_/g, '');
594  }
595
596  ch = value[0];
597
598  if (ch === '-' || ch === '+') {
599    if (ch === '-') sign = -1;
600    value = value.slice(1);
601    ch = value[0];
602  }
603
604  if (value === '0') return 0;
605
606  if (ch === '0') {
607    if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
608    if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);
609    if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);
610  }
611
612  return sign * parseInt(value, 10);
613}
614
615function isInteger(object) {
616  return (Object.prototype.toString.call(object)) === '[object Number]' &&
617         (object % 1 === 0 && !common.isNegativeZero(object));
618}
619
620var int = new type('tag:yaml.org,2002:int', {
621  kind: 'scalar',
622  resolve: resolveYamlInteger,
623  construct: constructYamlInteger,
624  predicate: isInteger,
625  represent: {
626    binary:      function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },
627    octal:       function (obj) { return obj >= 0 ? '0o'  + obj.toString(8) : '-0o'  + obj.toString(8).slice(1); },
628    decimal:     function (obj) { return obj.toString(10); },
629    /* eslint-disable max-len */
630    hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() :  '-0x' + obj.toString(16).toUpperCase().slice(1); }
631  },
632  defaultStyle: 'decimal',
633  styleAliases: {
634    binary:      [ 2,  'bin' ],
635    octal:       [ 8,  'oct' ],
636    decimal:     [ 10, 'dec' ],
637    hexadecimal: [ 16, 'hex' ]
638  }
639});
640
641var YAML_FLOAT_PATTERN = new RegExp(
642  // 2.5e4, 2.5 and integers
643  '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +
644  // .2e4, .2
645  // special case, seems not from spec
646  '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +
647  // .inf
648  '|[-+]?\\.(?:inf|Inf|INF)' +
649  // .nan
650  '|\\.(?:nan|NaN|NAN))$');
651
652function resolveYamlFloat(data) {
653  if (data === null) return false;
654
655  if (!YAML_FLOAT_PATTERN.test(data) ||
656      // Quick hack to not allow integers end with `_`
657      // Probably should update regexp & check speed
658      data[data.length - 1] === '_') {
659    return false;
660  }
661
662  return true;
663}
664
665function constructYamlFloat(data) {
666  var value, sign;
667
668  value  = data.replace(/_/g, '').toLowerCase();
669  sign   = value[0] === '-' ? -1 : 1;
670
671  if ('+-'.indexOf(value[0]) >= 0) {
672    value = value.slice(1);
673  }
674
675  if (value === '.inf') {
676    return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
677
678  } else if (value === '.nan') {
679    return NaN;
680  }
681  return sign * parseFloat(value, 10);
682}
683
684
685var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
686
687function representYamlFloat(object, style) {
688  var res;
689
690  if (isNaN(object)) {
691    switch (style) {
692      case 'lowercase': return '.nan';
693      case 'uppercase': return '.NAN';
694      case 'camelcase': return '.NaN';
695    }
696  } else if (Number.POSITIVE_INFINITY === object) {
697    switch (style) {
698      case 'lowercase': return '.inf';
699      case 'uppercase': return '.INF';
700      case 'camelcase': return '.Inf';
701    }
702  } else if (Number.NEGATIVE_INFINITY === object) {
703    switch (style) {
704      case 'lowercase': return '-.inf';
705      case 'uppercase': return '-.INF';
706      case 'camelcase': return '-.Inf';
707    }
708  } else if (common.isNegativeZero(object)) {
709    return '-0.0';
710  }
711
712  res = object.toString(10);
713
714  // JS stringifier can build scientific format without dots: 5e-100,
715  // while YAML requres dot: 5.e-100. Fix it with simple hack
716
717  return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
718}
719
720function isFloat(object) {
721  return (Object.prototype.toString.call(object) === '[object Number]') &&
722         (object % 1 !== 0 || common.isNegativeZero(object));
723}
724
725var float = new type('tag:yaml.org,2002:float', {
726  kind: 'scalar',
727  resolve: resolveYamlFloat,
728  construct: constructYamlFloat,
729  predicate: isFloat,
730  represent: representYamlFloat,
731  defaultStyle: 'lowercase'
732});
733
734var json = failsafe.extend({
735  implicit: [
736    _null,
737    bool,
738    int,
739    float
740  ]
741});
742
743var core = json;
744
745var YAML_DATE_REGEXP = new RegExp(
746  '^([0-9][0-9][0-9][0-9])'          + // [1] year
747  '-([0-9][0-9])'                    + // [2] month
748  '-([0-9][0-9])$');                   // [3] day
749
750var YAML_TIMESTAMP_REGEXP = new RegExp(
751  '^([0-9][0-9][0-9][0-9])'          + // [1] year
752  '-([0-9][0-9]?)'                   + // [2] month
753  '-([0-9][0-9]?)'                   + // [3] day
754  '(?:[Tt]|[ \\t]+)'                 + // ...
755  '([0-9][0-9]?)'                    + // [4] hour
756  ':([0-9][0-9])'                    + // [5] minute
757  ':([0-9][0-9])'                    + // [6] second
758  '(?:\\.([0-9]*))?'                 + // [7] fraction
759  '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour
760  '(?::([0-9][0-9]))?))?$');           // [11] tz_minute
761
762function resolveYamlTimestamp(data) {
763  if (data === null) return false;
764  if (YAML_DATE_REGEXP.exec(data) !== null) return true;
765  if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
766  return false;
767}
768
769function constructYamlTimestamp(data) {
770  var match, year, month, day, hour, minute, second, fraction = 0,
771      delta = null, tz_hour, tz_minute, date;
772
773  match = YAML_DATE_REGEXP.exec(data);
774  if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
775
776  if (match === null) throw new Error('Date resolve error');
777
778  // match: [1] year [2] month [3] day
779
780  year = +(match[1]);
781  month = +(match[2]) - 1; // JS month starts with 0
782  day = +(match[3]);
783
784  if (!match[4]) { // no hour
785    return new Date(Date.UTC(year, month, day));
786  }
787
788  // match: [4] hour [5] minute [6] second [7] fraction
789
790  hour = +(match[4]);
791  minute = +(match[5]);
792  second = +(match[6]);
793
794  if (match[7]) {
795    fraction = match[7].slice(0, 3);
796    while (fraction.length < 3) { // milli-seconds
797      fraction += '0';
798    }
799    fraction = +fraction;
800  }
801
802  // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute
803
804  if (match[9]) {
805    tz_hour = +(match[10]);
806    tz_minute = +(match[11] || 0);
807    delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds
808    if (match[9] === '-') delta = -delta;
809  }
810
811  date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
812
813  if (delta) date.setTime(date.getTime() - delta);
814
815  return date;
816}
817
818function representYamlTimestamp(object /*, style*/) {
819  return object.toISOString();
820}
821
822var timestamp = new type('tag:yaml.org,2002:timestamp', {
823  kind: 'scalar',
824  resolve: resolveYamlTimestamp,
825  construct: constructYamlTimestamp,
826  instanceOf: Date,
827  represent: representYamlTimestamp
828});
829
830function resolveYamlMerge(data) {
831  return data === '<<' || data === null;
832}
833
834var merge = new type('tag:yaml.org,2002:merge', {
835  kind: 'scalar',
836  resolve: resolveYamlMerge
837});
838
839/*eslint-disable no-bitwise*/
840
841
842
843
844
845// [ 64, 65, 66 ] -> [ padding, CR, LF ]
846var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
847
848
849function resolveYamlBinary(data) {
850  if (data === null) return false;
851
852  var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
853
854  // Convert one by one.
855  for (idx = 0; idx < max; idx++) {
856    code = map.indexOf(data.charAt(idx));
857
858    // Skip CR/LF
859    if (code > 64) continue;
860
861    // Fail on illegal characters
862    if (code < 0) return false;
863
864    bitlen += 6;
865  }
866
867  // If there are any bits left, source was corrupted
868  return (bitlen % 8) === 0;
869}
870
871function constructYamlBinary(data) {
872  var idx, tailbits,
873      input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
874      max = input.length,
875      map = BASE64_MAP,
876      bits = 0,
877      result = [];
878
879  // Collect by 6*4 bits (3 bytes)
880
881  for (idx = 0; idx < max; idx++) {
882    if ((idx % 4 === 0) && idx) {
883      result.push((bits >> 16) & 0xFF);
884      result.push((bits >> 8) & 0xFF);
885      result.push(bits & 0xFF);
886    }
887
888    bits = (bits << 6) | map.indexOf(input.charAt(idx));
889  }
890
891  // Dump tail
892
893  tailbits = (max % 4) * 6;
894
895  if (tailbits === 0) {
896    result.push((bits >> 16) & 0xFF);
897    result.push((bits >> 8) & 0xFF);
898    result.push(bits & 0xFF);
899  } else if (tailbits === 18) {
900    result.push((bits >> 10) & 0xFF);
901    result.push((bits >> 2) & 0xFF);
902  } else if (tailbits === 12) {
903    result.push((bits >> 4) & 0xFF);
904  }
905
906  return new Uint8Array(result);
907}
908
909function representYamlBinary(object /*, style*/) {
910  var result = '', bits = 0, idx, tail,
911      max = object.length,
912      map = BASE64_MAP;
913
914  // Convert every three bytes to 4 ASCII characters.
915
916  for (idx = 0; idx < max; idx++) {
917    if ((idx % 3 === 0) && idx) {
918      result += map[(bits >> 18) & 0x3F];
919      result += map[(bits >> 12) & 0x3F];
920      result += map[(bits >> 6) & 0x3F];
921      result += map[bits & 0x3F];
922    }
923
924    bits = (bits << 8) + object[idx];
925  }
926
927  // Dump tail
928
929  tail = max % 3;
930
931  if (tail === 0) {
932    result += map[(bits >> 18) & 0x3F];
933    result += map[(bits >> 12) & 0x3F];
934    result += map[(bits >> 6) & 0x3F];
935    result += map[bits & 0x3F];
936  } else if (tail === 2) {
937    result += map[(bits >> 10) & 0x3F];
938    result += map[(bits >> 4) & 0x3F];
939    result += map[(bits << 2) & 0x3F];
940    result += map[64];
941  } else if (tail === 1) {
942    result += map[(bits >> 2) & 0x3F];
943    result += map[(bits << 4) & 0x3F];
944    result += map[64];
945    result += map[64];
946  }
947
948  return result;
949}
950
951function isBinary(obj) {
952  return Object.prototype.toString.call(obj) ===  '[object Uint8Array]';
953}
954
955var binary = new type('tag:yaml.org,2002:binary', {
956  kind: 'scalar',
957  resolve: resolveYamlBinary,
958  construct: constructYamlBinary,
959  predicate: isBinary,
960  represent: representYamlBinary
961});
962
963var _hasOwnProperty$3 = Object.prototype.hasOwnProperty;
964var _toString$2       = Object.prototype.toString;
965
966function resolveYamlOmap(data) {
967  if (data === null) return true;
968
969  var objectKeys = [], index, length, pair, pairKey, pairHasKey,
970      object = data;
971
972  for (index = 0, length = object.length; index < length; index += 1) {
973    pair = object[index];
974    pairHasKey = false;
975
976    if (_toString$2.call(pair) !== '[object Object]') return false;
977
978    for (pairKey in pair) {
979      if (_hasOwnProperty$3.call(pair, pairKey)) {
980        if (!pairHasKey) pairHasKey = true;
981        else return false;
982      }
983    }
984
985    if (!pairHasKey) return false;
986
987    if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
988    else return false;
989  }
990
991  return true;
992}
993
994function constructYamlOmap(data) {
995  return data !== null ? data : [];
996}
997
998var omap = new type('tag:yaml.org,2002:omap', {
999  kind: 'sequence',
1000  resolve: resolveYamlOmap,
1001  construct: constructYamlOmap
1002});
1003
1004var _toString$1 = Object.prototype.toString;
1005
1006function resolveYamlPairs(data) {
1007  if (data === null) return true;
1008
1009  var index, length, pair, keys, result,
1010      object = data;
1011
1012  result = new Array(object.length);
1013
1014  for (index = 0, length = object.length; index < length; index += 1) {
1015    pair = object[index];
1016
1017    if (_toString$1.call(pair) !== '[object Object]') return false;
1018
1019    keys = Object.keys(pair);
1020
1021    if (keys.length !== 1) return false;
1022
1023    result[index] = [ keys[0], pair[keys[0]] ];
1024  }
1025
1026  return true;
1027}
1028
1029function constructYamlPairs(data) {
1030  if (data === null) return [];
1031
1032  var index, length, pair, keys, result,
1033      object = data;
1034
1035  result = new Array(object.length);
1036
1037  for (index = 0, length = object.length; index < length; index += 1) {
1038    pair = object[index];
1039
1040    keys = Object.keys(pair);
1041
1042    result[index] = [ keys[0], pair[keys[0]] ];
1043  }
1044
1045  return result;
1046}
1047
1048var pairs = new type('tag:yaml.org,2002:pairs', {
1049  kind: 'sequence',
1050  resolve: resolveYamlPairs,
1051  construct: constructYamlPairs
1052});
1053
1054var _hasOwnProperty$2 = Object.prototype.hasOwnProperty;
1055
1056function resolveYamlSet(data) {
1057  if (data === null) return true;
1058
1059  var key, object = data;
1060
1061  for (key in object) {
1062    if (_hasOwnProperty$2.call(object, key)) {
1063      if (object[key] !== null) return false;
1064    }
1065  }
1066
1067  return true;
1068}
1069
1070function constructYamlSet(data) {
1071  return data !== null ? data : {};
1072}
1073
1074var set = new type('tag:yaml.org,2002:set', {
1075  kind: 'mapping',
1076  resolve: resolveYamlSet,
1077  construct: constructYamlSet
1078});
1079
1080var _default = core.extend({
1081  implicit: [
1082    timestamp,
1083    merge
1084  ],
1085  explicit: [
1086    binary,
1087    omap,
1088    pairs,
1089    set
1090  ]
1091});
1092
1093/*eslint-disable max-len,no-use-before-define*/
1094
1095
1096
1097
1098
1099
1100
1101var _hasOwnProperty$1 = Object.prototype.hasOwnProperty;
1102
1103
1104var CONTEXT_FLOW_IN   = 1;
1105var CONTEXT_FLOW_OUT  = 2;
1106var CONTEXT_BLOCK_IN  = 3;
1107var CONTEXT_BLOCK_OUT = 4;
1108
1109
1110var CHOMPING_CLIP  = 1;
1111var CHOMPING_STRIP = 2;
1112var CHOMPING_KEEP  = 3;
1113
1114
1115var PATTERN_NON_PRINTABLE         = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
1116var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
1117var PATTERN_FLOW_INDICATORS       = /[,\[\]\{\}]/;
1118var PATTERN_TAG_HANDLE            = /^(?:!|!!|![a-z\-]+!)$/i;
1119var PATTERN_TAG_URI               = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
1120
1121
1122function _class(obj) { return Object.prototype.toString.call(obj); }
1123
1124function is_EOL(c) {
1125  return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);
1126}
1127
1128function is_WHITE_SPACE(c) {
1129  return (c === 0x09/* Tab */) || (c === 0x20/* Space */);
1130}
1131
1132function is_WS_OR_EOL(c) {
1133  return (c === 0x09/* Tab */) ||
1134         (c === 0x20/* Space */) ||
1135         (c === 0x0A/* LF */) ||
1136         (c === 0x0D/* CR */);
1137}
1138
1139function is_FLOW_INDICATOR(c) {
1140  return c === 0x2C/* , */ ||
1141         c === 0x5B/* [ */ ||
1142         c === 0x5D/* ] */ ||
1143         c === 0x7B/* { */ ||
1144         c === 0x7D/* } */;
1145}
1146
1147function fromHexCode(c) {
1148  var lc;
1149
1150  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
1151    return c - 0x30;
1152  }
1153
1154  /*eslint-disable no-bitwise*/
1155  lc = c | 0x20;
1156
1157  if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {
1158    return lc - 0x61 + 10;
1159  }
1160
1161  return -1;
1162}
1163
1164function escapedHexLen(c) {
1165  if (c === 0x78/* x */) { return 2; }
1166  if (c === 0x75/* u */) { return 4; }
1167  if (c === 0x55/* U */) { return 8; }
1168  return 0;
1169}
1170
1171function fromDecimalCode(c) {
1172  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
1173    return c - 0x30;
1174  }
1175
1176  return -1;
1177}
1178
1179function simpleEscapeSequence(c) {
1180  /* eslint-disable indent */
1181  return (c === 0x30/* 0 */) ? '\x00' :
1182        (c === 0x61/* a */) ? '\x07' :
1183        (c === 0x62/* b */) ? '\x08' :
1184        (c === 0x74/* t */) ? '\x09' :
1185        (c === 0x09/* Tab */) ? '\x09' :
1186        (c === 0x6E/* n */) ? '\x0A' :
1187        (c === 0x76/* v */) ? '\x0B' :
1188        (c === 0x66/* f */) ? '\x0C' :
1189        (c === 0x72/* r */) ? '\x0D' :
1190        (c === 0x65/* e */) ? '\x1B' :
1191        (c === 0x20/* Space */) ? ' ' :
1192        (c === 0x22/* " */) ? '\x22' :
1193        (c === 0x2F/* / */) ? '/' :
1194        (c === 0x5C/* \ */) ? '\x5C' :
1195        (c === 0x4E/* N */) ? '\x85' :
1196        (c === 0x5F/* _ */) ? '\xA0' :
1197        (c === 0x4C/* L */) ? '\u2028' :
1198        (c === 0x50/* P */) ? '\u2029' : '';
1199}
1200
1201function charFromCodepoint(c) {
1202  if (c <= 0xFFFF) {
1203    return String.fromCharCode(c);
1204  }
1205  // Encode UTF-16 surrogate pair
1206  // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
1207  return String.fromCharCode(
1208    ((c - 0x010000) >> 10) + 0xD800,
1209    ((c - 0x010000) & 0x03FF) + 0xDC00
1210  );
1211}
1212
1213var simpleEscapeCheck = new Array(256); // integer, for fast access
1214var simpleEscapeMap = new Array(256);
1215for (var i = 0; i < 256; i++) {
1216  simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
1217  simpleEscapeMap[i] = simpleEscapeSequence(i);
1218}
1219
1220
1221function State$1(input, options) {
1222  this.input = input;
1223
1224  this.filename  = options['filename']  || null;
1225  this.schema    = options['schema']    || _default;
1226  this.onWarning = options['onWarning'] || null;
1227  // (Hidden) Remove? makes the loader to expect YAML 1.1 documents
1228  // if such documents have no explicit %YAML directive
1229  this.legacy    = options['legacy']    || false;
1230
1231  this.json      = options['json']      || false;
1232  this.listener  = options['listener']  || null;
1233
1234  this.implicitTypes = this.schema.compiledImplicit;
1235  this.typeMap       = this.schema.compiledTypeMap;
1236
1237  this.length     = input.length;
1238  this.position   = 0;
1239  this.line       = 0;
1240  this.lineStart  = 0;
1241  this.lineIndent = 0;
1242
1243  // position of first leading tab in the current line,
1244  // used to make sure there are no tabs in the indentation
1245  this.firstTabInLine = -1;
1246
1247  this.documents = [];
1248
1249  /*
1250  this.version;
1251  this.checkLineBreaks;
1252  this.tagMap;
1253  this.anchorMap;
1254  this.tag;
1255  this.anchor;
1256  this.kind;
1257  this.result;*/
1258
1259}
1260
1261
1262function generateError(state, message) {
1263  var mark = {
1264    name:     state.filename,
1265    buffer:   state.input.slice(0, -1), // omit trailing \0
1266    position: state.position,
1267    line:     state.line,
1268    column:   state.position - state.lineStart
1269  };
1270
1271  mark.snippet = snippet(mark);
1272
1273  return new exception(message, mark);
1274}
1275
1276function throwError(state, message) {
1277  throw generateError(state, message);
1278}
1279
1280function throwWarning(state, message) {
1281  if (state.onWarning) {
1282    state.onWarning.call(null, generateError(state, message));
1283  }
1284}
1285
1286
1287var directiveHandlers = {
1288
1289  YAML: function handleYamlDirective(state, name, args) {
1290
1291    var match, major, minor;
1292
1293    if (state.version !== null) {
1294      throwError(state, 'duplication of %YAML directive');
1295    }
1296
1297    if (args.length !== 1) {
1298      throwError(state, 'YAML directive accepts exactly one argument');
1299    }
1300
1301    match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
1302
1303    if (match === null) {
1304      throwError(state, 'ill-formed argument of the YAML directive');
1305    }
1306
1307    major = parseInt(match[1], 10);
1308    minor = parseInt(match[2], 10);
1309
1310    if (major !== 1) {
1311      throwError(state, 'unacceptable YAML version of the document');
1312    }
1313
1314    state.version = args[0];
1315    state.checkLineBreaks = (minor < 2);
1316
1317    if (minor !== 1 && minor !== 2) {
1318      throwWarning(state, 'unsupported YAML version of the document');
1319    }
1320  },
1321
1322  TAG: function handleTagDirective(state, name, args) {
1323
1324    var handle, prefix;
1325
1326    if (args.length !== 2) {
1327      throwError(state, 'TAG directive accepts exactly two arguments');
1328    }
1329
1330    handle = args[0];
1331    prefix = args[1];
1332
1333    if (!PATTERN_TAG_HANDLE.test(handle)) {
1334      throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
1335    }
1336
1337    if (_hasOwnProperty$1.call(state.tagMap, handle)) {
1338      throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
1339    }
1340
1341    if (!PATTERN_TAG_URI.test(prefix)) {
1342      throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
1343    }
1344
1345    try {
1346      prefix = decodeURIComponent(prefix);
1347    } catch (err) {
1348      throwError(state, 'tag prefix is malformed: ' + prefix);
1349    }
1350
1351    state.tagMap[handle] = prefix;
1352  }
1353};
1354
1355
1356function captureSegment(state, start, end, checkJson) {
1357  var _position, _length, _character, _result;
1358
1359  if (start < end) {
1360    _result = state.input.slice(start, end);
1361
1362    if (checkJson) {
1363      for (_position = 0, _length = _result.length; _position < _length; _position += 1) {
1364        _character = _result.charCodeAt(_position);
1365        if (!(_character === 0x09 ||
1366              (0x20 <= _character && _character <= 0x10FFFF))) {
1367          throwError(state, 'expected valid JSON character');
1368        }
1369      }
1370    } else if (PATTERN_NON_PRINTABLE.test(_result)) {
1371      throwError(state, 'the stream contains non-printable characters');
1372    }
1373
1374    state.result += _result;
1375  }
1376}
1377
1378function mergeMappings(state, destination, source, overridableKeys) {
1379  var sourceKeys, key, index, quantity;
1380
1381  if (!common.isObject(source)) {
1382    throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
1383  }
1384
1385  sourceKeys = Object.keys(source);
1386
1387  for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
1388    key = sourceKeys[index];
1389
1390    if (!_hasOwnProperty$1.call(destination, key)) {
1391      destination[key] = source[key];
1392      overridableKeys[key] = true;
1393    }
1394  }
1395}
1396
1397function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,
1398  startLine, startLineStart, startPos) {
1399
1400  var index, quantity;
1401
1402  // The output is a plain object here, so keys can only be strings.
1403  // We need to convert keyNode to a string, but doing so can hang the process
1404  // (deeply nested arrays that explode exponentially using aliases).
1405  if (Array.isArray(keyNode)) {
1406    keyNode = Array.prototype.slice.call(keyNode);
1407
1408    for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {
1409      if (Array.isArray(keyNode[index])) {
1410        throwError(state, 'nested arrays are not supported inside keys');
1411      }
1412
1413      if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {
1414        keyNode[index] = '[object Object]';
1415      }
1416    }
1417  }
1418
1419  // Avoid code execution in load() via toString property
1420  // (still use its own toString for arrays, timestamps,
1421  // and whatever user schema extensions happen to have @@toStringTag)
1422  if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {
1423    keyNode = '[object Object]';
1424  }
1425
1426
1427  keyNode = String(keyNode);
1428
1429  if (_result === null) {
1430    _result = {};
1431  }
1432
1433  if (keyTag === 'tag:yaml.org,2002:merge') {
1434    if (Array.isArray(valueNode)) {
1435      for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
1436        mergeMappings(state, _result, valueNode[index], overridableKeys);
1437      }
1438    } else {
1439      mergeMappings(state, _result, valueNode, overridableKeys);
1440    }
1441  } else {
1442    if (!state.json &&
1443        !_hasOwnProperty$1.call(overridableKeys, keyNode) &&
1444        _hasOwnProperty$1.call(_result, keyNode)) {
1445      state.line = startLine || state.line;
1446      state.lineStart = startLineStart || state.lineStart;
1447      state.position = startPos || state.position;
1448      throwError(state, 'duplicated mapping key');
1449    }
1450
1451    // used for this specific key only because Object.defineProperty is slow
1452    if (keyNode === '__proto__') {
1453      Object.defineProperty(_result, keyNode, {
1454        configurable: true,
1455        enumerable: true,
1456        writable: true,
1457        value: valueNode
1458      });
1459    } else {
1460      _result[keyNode] = valueNode;
1461    }
1462    delete overridableKeys[keyNode];
1463  }
1464
1465  return _result;
1466}
1467
1468function readLineBreak(state) {
1469  var ch;
1470
1471  ch = state.input.charCodeAt(state.position);
1472
1473  if (ch === 0x0A/* LF */) {
1474    state.position++;
1475  } else if (ch === 0x0D/* CR */) {
1476    state.position++;
1477    if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {
1478      state.position++;
1479    }
1480  } else {
1481    throwError(state, 'a line break is expected');
1482  }
1483
1484  state.line += 1;
1485  state.lineStart = state.position;
1486  state.firstTabInLine = -1;
1487}
1488
1489function skipSeparationSpace(state, allowComments, checkIndent) {
1490  var lineBreaks = 0,
1491      ch = state.input.charCodeAt(state.position);
1492
1493  while (ch !== 0) {
1494    while (is_WHITE_SPACE(ch)) {
1495      if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {
1496        state.firstTabInLine = state.position;
1497      }
1498      ch = state.input.charCodeAt(++state.position);
1499    }
1500
1501    if (allowComments && ch === 0x23/* # */) {
1502      do {
1503        ch = state.input.charCodeAt(++state.position);
1504      } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);
1505    }
1506
1507    if (is_EOL(ch)) {
1508      readLineBreak(state);
1509
1510      ch = state.input.charCodeAt(state.position);
1511      lineBreaks++;
1512      state.lineIndent = 0;
1513
1514      while (ch === 0x20/* Space */) {
1515        state.lineIndent++;
1516        ch = state.input.charCodeAt(++state.position);
1517      }
1518    } else {
1519      break;
1520    }
1521  }
1522
1523  if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {
1524    throwWarning(state, 'deficient indentation');
1525  }
1526
1527  return lineBreaks;
1528}
1529
1530function testDocumentSeparator(state) {
1531  var _position = state.position,
1532      ch;
1533
1534  ch = state.input.charCodeAt(_position);
1535
1536  // Condition state.position === state.lineStart is tested
1537  // in parent on each call, for efficiency. No needs to test here again.
1538  if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&
1539      ch === state.input.charCodeAt(_position + 1) &&
1540      ch === state.input.charCodeAt(_position + 2)) {
1541
1542    _position += 3;
1543
1544    ch = state.input.charCodeAt(_position);
1545
1546    if (ch === 0 || is_WS_OR_EOL(ch)) {
1547      return true;
1548    }
1549  }
1550
1551  return false;
1552}
1553
1554function writeFoldedLines(state, count) {
1555  if (count === 1) {
1556    state.result += ' ';
1557  } else if (count > 1) {
1558    state.result += common.repeat('\n', count - 1);
1559  }
1560}
1561
1562
1563function readPlainScalar(state, nodeIndent, withinFlowCollection) {
1564  var preceding,
1565      following,
1566      captureStart,
1567      captureEnd,
1568      hasPendingContent,
1569      _line,
1570      _lineStart,
1571      _lineIndent,
1572      _kind = state.kind,
1573      _result = state.result,
1574      ch;
1575
1576  ch = state.input.charCodeAt(state.position);
1577
1578  if (is_WS_OR_EOL(ch)      ||
1579      is_FLOW_INDICATOR(ch) ||
1580      ch === 0x23/* # */    ||
1581      ch === 0x26/* & */    ||
1582      ch === 0x2A/* * */    ||
1583      ch === 0x21/* ! */    ||
1584      ch === 0x7C/* | */    ||
1585      ch === 0x3E/* > */    ||
1586      ch === 0x27/* ' */    ||
1587      ch === 0x22/* " */    ||
1588      ch === 0x25/* % */    ||
1589      ch === 0x40/* @ */    ||
1590      ch === 0x60/* ` */) {
1591    return false;
1592  }
1593
1594  if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {
1595    following = state.input.charCodeAt(state.position + 1);
1596
1597    if (is_WS_OR_EOL(following) ||
1598        withinFlowCollection && is_FLOW_INDICATOR(following)) {
1599      return false;
1600    }
1601  }
1602
1603  state.kind = 'scalar';
1604  state.result = '';
1605  captureStart = captureEnd = state.position;
1606  hasPendingContent = false;
1607
1608  while (ch !== 0) {
1609    if (ch === 0x3A/* : */) {
1610      following = state.input.charCodeAt(state.position + 1);
1611
1612      if (is_WS_OR_EOL(following) ||
1613          withinFlowCollection && is_FLOW_INDICATOR(following)) {
1614        break;
1615      }
1616
1617    } else if (ch === 0x23/* # */) {
1618      preceding = state.input.charCodeAt(state.position - 1);
1619
1620      if (is_WS_OR_EOL(preceding)) {
1621        break;
1622      }
1623
1624    } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||
1625               withinFlowCollection && is_FLOW_INDICATOR(ch)) {
1626      break;
1627
1628    } else if (is_EOL(ch)) {
1629      _line = state.line;
1630      _lineStart = state.lineStart;
1631      _lineIndent = state.lineIndent;
1632      skipSeparationSpace(state, false, -1);
1633
1634      if (state.lineIndent >= nodeIndent) {
1635        hasPendingContent = true;
1636        ch = state.input.charCodeAt(state.position);
1637        continue;
1638      } else {
1639        state.position = captureEnd;
1640        state.line = _line;
1641        state.lineStart = _lineStart;
1642        state.lineIndent = _lineIndent;
1643        break;
1644      }
1645    }
1646
1647    if (hasPendingContent) {
1648      captureSegment(state, captureStart, captureEnd, false);
1649      writeFoldedLines(state, state.line - _line);
1650      captureStart = captureEnd = state.position;
1651      hasPendingContent = false;
1652    }
1653
1654    if (!is_WHITE_SPACE(ch)) {
1655      captureEnd = state.position + 1;
1656    }
1657
1658    ch = state.input.charCodeAt(++state.position);
1659  }
1660
1661  captureSegment(state, captureStart, captureEnd, false);
1662
1663  if (state.result) {
1664    return true;
1665  }
1666
1667  state.kind = _kind;
1668  state.result = _result;
1669  return false;
1670}
1671
1672function readSingleQuotedScalar(state, nodeIndent) {
1673  var ch,
1674      captureStart, captureEnd;
1675
1676  ch = state.input.charCodeAt(state.position);
1677
1678  if (ch !== 0x27/* ' */) {
1679    return false;
1680  }
1681
1682  state.kind = 'scalar';
1683  state.result = '';
1684  state.position++;
1685  captureStart = captureEnd = state.position;
1686
1687  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
1688    if (ch === 0x27/* ' */) {
1689      captureSegment(state, captureStart, state.position, true);
1690      ch = state.input.charCodeAt(++state.position);
1691
1692      if (ch === 0x27/* ' */) {
1693        captureStart = state.position;
1694        state.position++;
1695        captureEnd = state.position;
1696      } else {
1697        return true;
1698      }
1699
1700    } else if (is_EOL(ch)) {
1701      captureSegment(state, captureStart, captureEnd, true);
1702      writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
1703      captureStart = captureEnd = state.position;
1704
1705    } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
1706      throwError(state, 'unexpected end of the document within a single quoted scalar');
1707
1708    } else {
1709      state.position++;
1710      captureEnd = state.position;
1711    }
1712  }
1713
1714  throwError(state, 'unexpected end of the stream within a single quoted scalar');
1715}
1716
1717function readDoubleQuotedScalar(state, nodeIndent) {
1718  var captureStart,
1719      captureEnd,
1720      hexLength,
1721      hexResult,
1722      tmp,
1723      ch;
1724
1725  ch = state.input.charCodeAt(state.position);
1726
1727  if (ch !== 0x22/* " */) {
1728    return false;
1729  }
1730
1731  state.kind = 'scalar';
1732  state.result = '';
1733  state.position++;
1734  captureStart = captureEnd = state.position;
1735
1736  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
1737    if (ch === 0x22/* " */) {
1738      captureSegment(state, captureStart, state.position, true);
1739      state.position++;
1740      return true;
1741
1742    } else if (ch === 0x5C/* \ */) {
1743      captureSegment(state, captureStart, state.position, true);
1744      ch = state.input.charCodeAt(++state.position);
1745
1746      if (is_EOL(ch)) {
1747        skipSeparationSpace(state, false, nodeIndent);
1748
1749        // TODO: rework to inline fn with no type cast?
1750      } else if (ch < 256 && simpleEscapeCheck[ch]) {
1751        state.result += simpleEscapeMap[ch];
1752        state.position++;
1753
1754      } else if ((tmp = escapedHexLen(ch)) > 0) {
1755        hexLength = tmp;
1756        hexResult = 0;
1757
1758        for (; hexLength > 0; hexLength--) {
1759          ch = state.input.charCodeAt(++state.position);
1760
1761          if ((tmp = fromHexCode(ch)) >= 0) {
1762            hexResult = (hexResult << 4) + tmp;
1763
1764          } else {
1765            throwError(state, 'expected hexadecimal character');
1766          }
1767        }
1768
1769        state.result += charFromCodepoint(hexResult);
1770
1771        state.position++;
1772
1773      } else {
1774        throwError(state, 'unknown escape sequence');
1775      }
1776
1777      captureStart = captureEnd = state.position;
1778
1779    } else if (is_EOL(ch)) {
1780      captureSegment(state, captureStart, captureEnd, true);
1781      writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
1782      captureStart = captureEnd = state.position;
1783
1784    } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
1785      throwError(state, 'unexpected end of the document within a double quoted scalar');
1786
1787    } else {
1788      state.position++;
1789      captureEnd = state.position;
1790    }
1791  }
1792
1793  throwError(state, 'unexpected end of the stream within a double quoted scalar');
1794}
1795
1796function readFlowCollection(state, nodeIndent) {
1797  var readNext = true,
1798      _line,
1799      _lineStart,
1800      _pos,
1801      _tag     = state.tag,
1802      _result,
1803      _anchor  = state.anchor,
1804      following,
1805      terminator,
1806      isPair,
1807      isExplicitPair,
1808      isMapping,
1809      overridableKeys = Object.create(null),
1810      keyNode,
1811      keyTag,
1812      valueNode,
1813      ch;
1814
1815  ch = state.input.charCodeAt(state.position);
1816
1817  if (ch === 0x5B/* [ */) {
1818    terminator = 0x5D;/* ] */
1819    isMapping = false;
1820    _result = [];
1821  } else if (ch === 0x7B/* { */) {
1822    terminator = 0x7D;/* } */
1823    isMapping = true;
1824    _result = {};
1825  } else {
1826    return false;
1827  }
1828
1829  if (state.anchor !== null) {
1830    state.anchorMap[state.anchor] = _result;
1831  }
1832
1833  ch = state.input.charCodeAt(++state.position);
1834
1835  while (ch !== 0) {
1836    skipSeparationSpace(state, true, nodeIndent);
1837
1838    ch = state.input.charCodeAt(state.position);
1839
1840    if (ch === terminator) {
1841      state.position++;
1842      state.tag = _tag;
1843      state.anchor = _anchor;
1844      state.kind = isMapping ? 'mapping' : 'sequence';
1845      state.result = _result;
1846      return true;
1847    } else if (!readNext) {
1848      throwError(state, 'missed comma between flow collection entries');
1849    } else if (ch === 0x2C/* , */) {
1850      // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4
1851      throwError(state, "expected the node content, but found ','");
1852    }
1853
1854    keyTag = keyNode = valueNode = null;
1855    isPair = isExplicitPair = false;
1856
1857    if (ch === 0x3F/* ? */) {
1858      following = state.input.charCodeAt(state.position + 1);
1859
1860      if (is_WS_OR_EOL(following)) {
1861        isPair = isExplicitPair = true;
1862        state.position++;
1863        skipSeparationSpace(state, true, nodeIndent);
1864      }
1865    }
1866
1867    _line = state.line; // Save the current line.
1868    _lineStart = state.lineStart;
1869    _pos = state.position;
1870    composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
1871    keyTag = state.tag;
1872    keyNode = state.result;
1873    skipSeparationSpace(state, true, nodeIndent);
1874
1875    ch = state.input.charCodeAt(state.position);
1876
1877    if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {
1878      isPair = true;
1879      ch = state.input.charCodeAt(++state.position);
1880      skipSeparationSpace(state, true, nodeIndent);
1881      composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
1882      valueNode = state.result;
1883    }
1884
1885    if (isMapping) {
1886      storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);
1887    } else if (isPair) {
1888      _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));
1889    } else {
1890      _result.push(keyNode);
1891    }
1892
1893    skipSeparationSpace(state, true, nodeIndent);
1894
1895    ch = state.input.charCodeAt(state.position);
1896
1897    if (ch === 0x2C/* , */) {
1898      readNext = true;
1899      ch = state.input.charCodeAt(++state.position);
1900    } else {
1901      readNext = false;
1902    }
1903  }
1904
1905  throwError(state, 'unexpected end of the stream within a flow collection');
1906}
1907
1908function readBlockScalar(state, nodeIndent) {
1909  var captureStart,
1910      folding,
1911      chomping       = CHOMPING_CLIP,
1912      didReadContent = false,
1913      detectedIndent = false,
1914      textIndent     = nodeIndent,
1915      emptyLines     = 0,
1916      atMoreIndented = false,
1917      tmp,
1918      ch;
1919
1920  ch = state.input.charCodeAt(state.position);
1921
1922  if (ch === 0x7C/* | */) {
1923    folding = false;
1924  } else if (ch === 0x3E/* > */) {
1925    folding = true;
1926  } else {
1927    return false;
1928  }
1929
1930  state.kind = 'scalar';
1931  state.result = '';
1932
1933  while (ch !== 0) {
1934    ch = state.input.charCodeAt(++state.position);
1935
1936    if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {
1937      if (CHOMPING_CLIP === chomping) {
1938        chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;
1939      } else {
1940        throwError(state, 'repeat of a chomping mode identifier');
1941      }
1942
1943    } else if ((tmp = fromDecimalCode(ch)) >= 0) {
1944      if (tmp === 0) {
1945        throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');
1946      } else if (!detectedIndent) {
1947        textIndent = nodeIndent + tmp - 1;
1948        detectedIndent = true;
1949      } else {
1950        throwError(state, 'repeat of an indentation width identifier');
1951      }
1952
1953    } else {
1954      break;
1955    }
1956  }
1957
1958  if (is_WHITE_SPACE(ch)) {
1959    do { ch = state.input.charCodeAt(++state.position); }
1960    while (is_WHITE_SPACE(ch));
1961
1962    if (ch === 0x23/* # */) {
1963      do { ch = state.input.charCodeAt(++state.position); }
1964      while (!is_EOL(ch) && (ch !== 0));
1965    }
1966  }
1967
1968  while (ch !== 0) {
1969    readLineBreak(state);
1970    state.lineIndent = 0;
1971
1972    ch = state.input.charCodeAt(state.position);
1973
1974    while ((!detectedIndent || state.lineIndent < textIndent) &&
1975           (ch === 0x20/* Space */)) {
1976      state.lineIndent++;
1977      ch = state.input.charCodeAt(++state.position);
1978    }
1979
1980    if (!detectedIndent && state.lineIndent > textIndent) {
1981      textIndent = state.lineIndent;
1982    }
1983
1984    if (is_EOL(ch)) {
1985      emptyLines++;
1986      continue;
1987    }
1988
1989    // End of the scalar.
1990    if (state.lineIndent < textIndent) {
1991
1992      // Perform the chomping.
1993      if (chomping === CHOMPING_KEEP) {
1994        state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
1995      } else if (chomping === CHOMPING_CLIP) {
1996        if (didReadContent) { // i.e. only if the scalar is not empty.
1997          state.result += '\n';
1998        }
1999      }
2000
2001      // Break this `while` cycle and go to the funciton's epilogue.
2002      break;
2003    }
2004
2005    // Folded style: use fancy rules to handle line breaks.
2006    if (folding) {
2007
2008      // Lines starting with white space characters (more-indented lines) are not folded.
2009      if (is_WHITE_SPACE(ch)) {
2010        atMoreIndented = true;
2011        // except for the first content line (cf. Example 8.1)
2012        state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
2013
2014      // End of more-indented block.
2015      } else if (atMoreIndented) {
2016        atMoreIndented = false;
2017        state.result += common.repeat('\n', emptyLines + 1);
2018
2019      // Just one line break - perceive as the same line.
2020      } else if (emptyLines === 0) {
2021        if (didReadContent) { // i.e. only if we have already read some scalar content.
2022          state.result += ' ';
2023        }
2024
2025      // Several line breaks - perceive as different lines.
2026      } else {
2027        state.result += common.repeat('\n', emptyLines);
2028      }
2029
2030    // Literal style: just add exact number of line breaks between content lines.
2031    } else {
2032      // Keep all line breaks except the header line break.
2033      state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
2034    }
2035
2036    didReadContent = true;
2037    detectedIndent = true;
2038    emptyLines = 0;
2039    captureStart = state.position;
2040
2041    while (!is_EOL(ch) && (ch !== 0)) {
2042      ch = state.input.charCodeAt(++state.position);
2043    }
2044
2045    captureSegment(state, captureStart, state.position, false);
2046  }
2047
2048  return true;
2049}
2050
2051function readBlockSequence(state, nodeIndent) {
2052  var _line,
2053      _tag      = state.tag,
2054      _anchor   = state.anchor,
2055      _result   = [],
2056      following,
2057      detected  = false,
2058      ch;
2059
2060  // there is a leading tab before this token, so it can't be a block sequence/mapping;
2061  // it can still be flow sequence/mapping or a scalar
2062  if (state.firstTabInLine !== -1) return false;
2063
2064  if (state.anchor !== null) {
2065    state.anchorMap[state.anchor] = _result;
2066  }
2067
2068  ch = state.input.charCodeAt(state.position);
2069
2070  while (ch !== 0) {
2071    if (state.firstTabInLine !== -1) {
2072      state.position = state.firstTabInLine;
2073      throwError(state, 'tab characters must not be used in indentation');
2074    }
2075
2076    if (ch !== 0x2D/* - */) {
2077      break;
2078    }
2079
2080    following = state.input.charCodeAt(state.position + 1);
2081
2082    if (!is_WS_OR_EOL(following)) {
2083      break;
2084    }
2085
2086    detected = true;
2087    state.position++;
2088
2089    if (skipSeparationSpace(state, true, -1)) {
2090      if (state.lineIndent <= nodeIndent) {
2091        _result.push(null);
2092        ch = state.input.charCodeAt(state.position);
2093        continue;
2094      }
2095    }
2096
2097    _line = state.line;
2098    composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);
2099    _result.push(state.result);
2100    skipSeparationSpace(state, true, -1);
2101
2102    ch = state.input.charCodeAt(state.position);
2103
2104    if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {
2105      throwError(state, 'bad indentation of a sequence entry');
2106    } else if (state.lineIndent < nodeIndent) {
2107      break;
2108    }
2109  }
2110
2111  if (detected) {
2112    state.tag = _tag;
2113    state.anchor = _anchor;
2114    state.kind = 'sequence';
2115    state.result = _result;
2116    return true;
2117  }
2118  return false;
2119}
2120
2121function readBlockMapping(state, nodeIndent, flowIndent) {
2122  var following,
2123      allowCompact,
2124      _line,
2125      _keyLine,
2126      _keyLineStart,
2127      _keyPos,
2128      _tag          = state.tag,
2129      _anchor       = state.anchor,
2130      _result       = {},
2131      overridableKeys = Object.create(null),
2132      keyTag        = null,
2133      keyNode       = null,
2134      valueNode     = null,
2135      atExplicitKey = false,
2136      detected      = false,
2137      ch;
2138
2139  // there is a leading tab before this token, so it can't be a block sequence/mapping;
2140  // it can still be flow sequence/mapping or a scalar
2141  if (state.firstTabInLine !== -1) return false;
2142
2143  if (state.anchor !== null) {
2144    state.anchorMap[state.anchor] = _result;
2145  }
2146
2147  ch = state.input.charCodeAt(state.position);
2148
2149  while (ch !== 0) {
2150    if (!atExplicitKey && state.firstTabInLine !== -1) {
2151      state.position = state.firstTabInLine;
2152      throwError(state, 'tab characters must not be used in indentation');
2153    }
2154
2155    following = state.input.charCodeAt(state.position + 1);
2156    _line = state.line; // Save the current line.
2157
2158    //
2159    // Explicit notation case. There are two separate blocks:
2160    // first for the key (denoted by "?") and second for the value (denoted by ":")
2161    //
2162    if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {
2163
2164      if (ch === 0x3F/* ? */) {
2165        if (atExplicitKey) {
2166          storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);
2167          keyTag = keyNode = valueNode = null;
2168        }
2169
2170        detected = true;
2171        atExplicitKey = true;
2172        allowCompact = true;
2173
2174      } else if (atExplicitKey) {
2175        // i.e. 0x3A/* : */ === character after the explicit key.
2176        atExplicitKey = false;
2177        allowCompact = true;
2178
2179      } else {
2180        throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');
2181      }
2182
2183      state.position += 1;
2184      ch = following;
2185
2186    //
2187    // Implicit notation case. Flow-style node as the key first, then ":", and the value.
2188    //
2189    } else {
2190      _keyLine = state.line;
2191      _keyLineStart = state.lineStart;
2192      _keyPos = state.position;
2193
2194      if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
2195        // Neither implicit nor explicit notation.
2196        // Reading is done. Go to the epilogue.
2197        break;
2198      }
2199
2200      if (state.line === _line) {
2201        ch = state.input.charCodeAt(state.position);
2202
2203        while (is_WHITE_SPACE(ch)) {
2204          ch = state.input.charCodeAt(++state.position);
2205        }
2206
2207        if (ch === 0x3A/* : */) {
2208          ch = state.input.charCodeAt(++state.position);
2209
2210          if (!is_WS_OR_EOL(ch)) {
2211            throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');
2212          }
2213
2214          if (atExplicitKey) {
2215            storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);
2216            keyTag = keyNode = valueNode = null;
2217          }
2218
2219          detected = true;
2220          atExplicitKey = false;
2221          allowCompact = false;
2222          keyTag = state.tag;
2223          keyNode = state.result;
2224
2225        } else if (detected) {
2226          throwError(state, 'can not read an implicit mapping pair; a colon is missed');
2227
2228        } else {
2229          state.tag = _tag;
2230          state.anchor = _anchor;
2231          return true; // Keep the result of `composeNode`.
2232        }
2233
2234      } else if (detected) {
2235        throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');
2236
2237      } else {
2238        state.tag = _tag;
2239        state.anchor = _anchor;
2240        return true; // Keep the result of `composeNode`.
2241      }
2242    }
2243
2244    //
2245    // Common reading code for both explicit and implicit notations.
2246    //
2247    if (state.line === _line || state.lineIndent > nodeIndent) {
2248      if (atExplicitKey) {
2249        _keyLine = state.line;
2250        _keyLineStart = state.lineStart;
2251        _keyPos = state.position;
2252      }
2253
2254      if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
2255        if (atExplicitKey) {
2256          keyNode = state.result;
2257        } else {
2258          valueNode = state.result;
2259        }
2260      }
2261
2262      if (!atExplicitKey) {
2263        storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);
2264        keyTag = keyNode = valueNode = null;
2265      }
2266
2267      skipSeparationSpace(state, true, -1);
2268      ch = state.input.charCodeAt(state.position);
2269    }
2270
2271    if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {
2272      throwError(state, 'bad indentation of a mapping entry');
2273    } else if (state.lineIndent < nodeIndent) {
2274      break;
2275    }
2276  }
2277
2278  //
2279  // Epilogue.
2280  //
2281
2282  // Special case: last mapping's node contains only the key in explicit notation.
2283  if (atExplicitKey) {
2284    storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);
2285  }
2286
2287  // Expose the resulting mapping.
2288  if (detected) {
2289    state.tag = _tag;
2290    state.anchor = _anchor;
2291    state.kind = 'mapping';
2292    state.result = _result;
2293  }
2294
2295  return detected;
2296}
2297
2298function readTagProperty(state) {
2299  var _position,
2300      isVerbatim = false,
2301      isNamed    = false,
2302      tagHandle,
2303      tagName,
2304      ch;
2305
2306  ch = state.input.charCodeAt(state.position);
2307
2308  if (ch !== 0x21/* ! */) return false;
2309
2310  if (state.tag !== null) {
2311    throwError(state, 'duplication of a tag property');
2312  }
2313
2314  ch = state.input.charCodeAt(++state.position);
2315
2316  if (ch === 0x3C/* < */) {
2317    isVerbatim = true;
2318    ch = state.input.charCodeAt(++state.position);
2319
2320  } else if (ch === 0x21/* ! */) {
2321    isNamed = true;
2322    tagHandle = '!!';
2323    ch = state.input.charCodeAt(++state.position);
2324
2325  } else {
2326    tagHandle = '!';
2327  }
2328
2329  _position = state.position;
2330
2331  if (isVerbatim) {
2332    do { ch = state.input.charCodeAt(++state.position); }
2333    while (ch !== 0 && ch !== 0x3E/* > */);
2334
2335    if (state.position < state.length) {
2336      tagName = state.input.slice(_position, state.position);
2337      ch = state.input.charCodeAt(++state.position);
2338    } else {
2339      throwError(state, 'unexpected end of the stream within a verbatim tag');
2340    }
2341  } else {
2342    while (ch !== 0 && !is_WS_OR_EOL(ch)) {
2343
2344      if (ch === 0x21/* ! */) {
2345        if (!isNamed) {
2346          tagHandle = state.input.slice(_position - 1, state.position + 1);
2347
2348          if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
2349            throwError(state, 'named tag handle cannot contain such characters');
2350          }
2351
2352          isNamed = true;
2353          _position = state.position + 1;
2354        } else {
2355          throwError(state, 'tag suffix cannot contain exclamation marks');
2356        }
2357      }
2358
2359      ch = state.input.charCodeAt(++state.position);
2360    }
2361
2362    tagName = state.input.slice(_position, state.position);
2363
2364    if (PATTERN_FLOW_INDICATORS.test(tagName)) {
2365      throwError(state, 'tag suffix cannot contain flow indicator characters');
2366    }
2367  }
2368
2369  if (tagName && !PATTERN_TAG_URI.test(tagName)) {
2370    throwError(state, 'tag name cannot contain such characters: ' + tagName);
2371  }
2372
2373  try {
2374    tagName = decodeURIComponent(tagName);
2375  } catch (err) {
2376    throwError(state, 'tag name is malformed: ' + tagName);
2377  }
2378
2379  if (isVerbatim) {
2380    state.tag = tagName;
2381
2382  } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {
2383    state.tag = state.tagMap[tagHandle] + tagName;
2384
2385  } else if (tagHandle === '!') {
2386    state.tag = '!' + tagName;
2387
2388  } else if (tagHandle === '!!') {
2389    state.tag = 'tag:yaml.org,2002:' + tagName;
2390
2391  } else {
2392    throwError(state, 'undeclared tag handle "' + tagHandle + '"');
2393  }
2394
2395  return true;
2396}
2397
2398function readAnchorProperty(state) {
2399  var _position,
2400      ch;
2401
2402  ch = state.input.charCodeAt(state.position);
2403
2404  if (ch !== 0x26/* & */) return false;
2405
2406  if (state.anchor !== null) {
2407    throwError(state, 'duplication of an anchor property');
2408  }
2409
2410  ch = state.input.charCodeAt(++state.position);
2411  _position = state.position;
2412
2413  while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
2414    ch = state.input.charCodeAt(++state.position);
2415  }
2416
2417  if (state.position === _position) {
2418    throwError(state, 'name of an anchor node must contain at least one character');
2419  }
2420
2421  state.anchor = state.input.slice(_position, state.position);
2422  return true;
2423}
2424
2425function readAlias(state) {
2426  var _position, alias,
2427      ch;
2428
2429  ch = state.input.charCodeAt(state.position);
2430
2431  if (ch !== 0x2A/* * */) return false;
2432
2433  ch = state.input.charCodeAt(++state.position);
2434  _position = state.position;
2435
2436  while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
2437    ch = state.input.charCodeAt(++state.position);
2438  }
2439
2440  if (state.position === _position) {
2441    throwError(state, 'name of an alias node must contain at least one character');
2442  }
2443
2444  alias = state.input.slice(_position, state.position);
2445
2446  if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {
2447    throwError(state, 'unidentified alias "' + alias + '"');
2448  }
2449
2450  state.result = state.anchorMap[alias];
2451  skipSeparationSpace(state, true, -1);
2452  return true;
2453}
2454
2455function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {
2456  var allowBlockStyles,
2457      allowBlockScalars,
2458      allowBlockCollections,
2459      indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent
2460      atNewLine  = false,
2461      hasContent = false,
2462      typeIndex,
2463      typeQuantity,
2464      typeList,
2465      type,
2466      flowIndent,
2467      blockIndent;
2468
2469  if (state.listener !== null) {
2470    state.listener('open', state);
2471  }
2472
2473  state.tag    = null;
2474  state.anchor = null;
2475  state.kind   = null;
2476  state.result = null;
2477
2478  allowBlockStyles = allowBlockScalars = allowBlockCollections =
2479    CONTEXT_BLOCK_OUT === nodeContext ||
2480    CONTEXT_BLOCK_IN  === nodeContext;
2481
2482  if (allowToSeek) {
2483    if (skipSeparationSpace(state, true, -1)) {
2484      atNewLine = true;
2485
2486      if (state.lineIndent > parentIndent) {
2487        indentStatus = 1;
2488      } else if (state.lineIndent === parentIndent) {
2489        indentStatus = 0;
2490      } else if (state.lineIndent < parentIndent) {
2491        indentStatus = -1;
2492      }
2493    }
2494  }
2495
2496  if (indentStatus === 1) {
2497    while (readTagProperty(state) || readAnchorProperty(state)) {
2498      if (skipSeparationSpace(state, true, -1)) {
2499        atNewLine = true;
2500        allowBlockCollections = allowBlockStyles;
2501
2502        if (state.lineIndent > parentIndent) {
2503          indentStatus = 1;
2504        } else if (state.lineIndent === parentIndent) {
2505          indentStatus = 0;
2506        } else if (state.lineIndent < parentIndent) {
2507          indentStatus = -1;
2508        }
2509      } else {
2510        allowBlockCollections = false;
2511      }
2512    }
2513  }
2514
2515  if (allowBlockCollections) {
2516    allowBlockCollections = atNewLine || allowCompact;
2517  }
2518
2519  if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
2520    if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
2521      flowIndent = parentIndent;
2522    } else {
2523      flowIndent = parentIndent + 1;
2524    }
2525
2526    blockIndent = state.position - state.lineStart;
2527
2528    if (indentStatus === 1) {
2529      if (allowBlockCollections &&
2530          (readBlockSequence(state, blockIndent) ||
2531           readBlockMapping(state, blockIndent, flowIndent)) ||
2532          readFlowCollection(state, flowIndent)) {
2533        hasContent = true;
2534      } else {
2535        if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||
2536            readSingleQuotedScalar(state, flowIndent) ||
2537            readDoubleQuotedScalar(state, flowIndent)) {
2538          hasContent = true;
2539
2540        } else if (readAlias(state)) {
2541          hasContent = true;
2542
2543          if (state.tag !== null || state.anchor !== null) {
2544            throwError(state, 'alias node should not have any properties');
2545          }
2546
2547        } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
2548          hasContent = true;
2549
2550          if (state.tag === null) {
2551            state.tag = '?';
2552          }
2553        }
2554
2555        if (state.anchor !== null) {
2556          state.anchorMap[state.anchor] = state.result;
2557        }
2558      }
2559    } else if (indentStatus === 0) {
2560      // Special case: block sequences are allowed to have same indentation level as the parent.
2561      // http://www.yaml.org/spec/1.2/spec.html#id2799784
2562      hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);
2563    }
2564  }
2565
2566  if (state.tag === null) {
2567    if (state.anchor !== null) {
2568      state.anchorMap[state.anchor] = state.result;
2569    }
2570
2571  } else if (state.tag === '?') {
2572    // Implicit resolving is not allowed for non-scalar types, and '?'
2573    // non-specific tag is only automatically assigned to plain scalars.
2574    //
2575    // We only need to check kind conformity in case user explicitly assigns '?'
2576    // tag, for example like this: "!<?> [0]"
2577    //
2578    if (state.result !== null && state.kind !== 'scalar') {
2579      throwError(state, 'unacceptable node kind for !<?> tag; it should be "scalar", not "' + state.kind + '"');
2580    }
2581
2582    for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {
2583      type = state.implicitTypes[typeIndex];
2584
2585      if (type.resolve(state.result)) { // `state.result` updated in resolver if matched
2586        state.result = type.construct(state.result);
2587        state.tag = type.tag;
2588        if (state.anchor !== null) {
2589          state.anchorMap[state.anchor] = state.result;
2590        }
2591        break;
2592      }
2593    }
2594  } else if (state.tag !== '!') {
2595    if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {
2596      type = state.typeMap[state.kind || 'fallback'][state.tag];
2597    } else {
2598      // looking for multi type
2599      type = null;
2600      typeList = state.typeMap.multi[state.kind || 'fallback'];
2601
2602      for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {
2603        if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {
2604          type = typeList[typeIndex];
2605          break;
2606        }
2607      }
2608    }
2609
2610    if (!type) {
2611      throwError(state, 'unknown tag !<' + state.tag + '>');
2612    }
2613
2614    if (state.result !== null && type.kind !== state.kind) {
2615      throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');
2616    }
2617
2618    if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched
2619      throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');
2620    } else {
2621      state.result = type.construct(state.result, state.tag);
2622      if (state.anchor !== null) {
2623        state.anchorMap[state.anchor] = state.result;
2624      }
2625    }
2626  }
2627
2628  if (state.listener !== null) {
2629    state.listener('close', state);
2630  }
2631  return state.tag !== null ||  state.anchor !== null || hasContent;
2632}
2633
2634function readDocument(state) {
2635  var documentStart = state.position,
2636      _position,
2637      directiveName,
2638      directiveArgs,
2639      hasDirectives = false,
2640      ch;
2641
2642  state.version = null;
2643  state.checkLineBreaks = state.legacy;
2644  state.tagMap = Object.create(null);
2645  state.anchorMap = Object.create(null);
2646
2647  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
2648    skipSeparationSpace(state, true, -1);
2649
2650    ch = state.input.charCodeAt(state.position);
2651
2652    if (state.lineIndent > 0 || ch !== 0x25/* % */) {
2653      break;
2654    }
2655
2656    hasDirectives = true;
2657    ch = state.input.charCodeAt(++state.position);
2658    _position = state.position;
2659
2660    while (ch !== 0 && !is_WS_OR_EOL(ch)) {
2661      ch = state.input.charCodeAt(++state.position);
2662    }
2663
2664    directiveName = state.input.slice(_position, state.position);
2665    directiveArgs = [];
2666
2667    if (directiveName.length < 1) {
2668      throwError(state, 'directive name must not be less than one character in length');
2669    }
2670
2671    while (ch !== 0) {
2672      while (is_WHITE_SPACE(ch)) {
2673        ch = state.input.charCodeAt(++state.position);
2674      }
2675
2676      if (ch === 0x23/* # */) {
2677        do { ch = state.input.charCodeAt(++state.position); }
2678        while (ch !== 0 && !is_EOL(ch));
2679        break;
2680      }
2681
2682      if (is_EOL(ch)) break;
2683
2684      _position = state.position;
2685
2686      while (ch !== 0 && !is_WS_OR_EOL(ch)) {
2687        ch = state.input.charCodeAt(++state.position);
2688      }
2689
2690      directiveArgs.push(state.input.slice(_position, state.position));
2691    }
2692
2693    if (ch !== 0) readLineBreak(state);
2694
2695    if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {
2696      directiveHandlers[directiveName](state, directiveName, directiveArgs);
2697    } else {
2698      throwWarning(state, 'unknown document directive "' + directiveName + '"');
2699    }
2700  }
2701
2702  skipSeparationSpace(state, true, -1);
2703
2704  if (state.lineIndent === 0 &&
2705      state.input.charCodeAt(state.position)     === 0x2D/* - */ &&
2706      state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&
2707      state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {
2708    state.position += 3;
2709    skipSeparationSpace(state, true, -1);
2710
2711  } else if (hasDirectives) {
2712    throwError(state, 'directives end mark is expected');
2713  }
2714
2715  composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
2716  skipSeparationSpace(state, true, -1);
2717
2718  if (state.checkLineBreaks &&
2719      PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {
2720    throwWarning(state, 'non-ASCII line breaks are interpreted as content');
2721  }
2722
2723  state.documents.push(state.result);
2724
2725  if (state.position === state.lineStart && testDocumentSeparator(state)) {
2726
2727    if (state.input.charCodeAt(state.position) === 0x2E/* . */) {
2728      state.position += 3;
2729      skipSeparationSpace(state, true, -1);
2730    }
2731    return;
2732  }
2733
2734  if (state.position < (state.length - 1)) {
2735    throwError(state, 'end of the stream or a document separator is expected');
2736  } else {
2737    return;
2738  }
2739}
2740
2741
2742function loadDocuments(input, options) {
2743  input = String(input);
2744  options = options || {};
2745
2746  if (input.length !== 0) {
2747
2748    // Add tailing `\n` if not exists
2749    if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&
2750        input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {
2751      input += '\n';
2752    }
2753
2754    // Strip BOM
2755    if (input.charCodeAt(0) === 0xFEFF) {
2756      input = input.slice(1);
2757    }
2758  }
2759
2760  var state = new State$1(input, options);
2761
2762  var nullpos = input.indexOf('\0');
2763
2764  if (nullpos !== -1) {
2765    state.position = nullpos;
2766    throwError(state, 'null byte is not allowed in input');
2767  }
2768
2769  // Use 0 as string terminator. That significantly simplifies bounds check.
2770  state.input += '\0';
2771
2772  while (state.input.charCodeAt(state.position) === 0x20/* Space */) {
2773    state.lineIndent += 1;
2774    state.position += 1;
2775  }
2776
2777  while (state.position < (state.length - 1)) {
2778    readDocument(state);
2779  }
2780
2781  return state.documents;
2782}
2783
2784
2785function loadAll$1(input, iterator, options) {
2786  if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {
2787    options = iterator;
2788    iterator = null;
2789  }
2790
2791  var documents = loadDocuments(input, options);
2792
2793  if (typeof iterator !== 'function') {
2794    return documents;
2795  }
2796
2797  for (var index = 0, length = documents.length; index < length; index += 1) {
2798    iterator(documents[index]);
2799  }
2800}
2801
2802
2803function load$1(input, options) {
2804  var documents = loadDocuments(input, options);
2805
2806  if (documents.length === 0) {
2807    /*eslint-disable no-undefined*/
2808    return undefined;
2809  } else if (documents.length === 1) {
2810    return documents[0];
2811  }
2812  throw new exception('expected a single document in the stream, but found more');
2813}
2814
2815
2816var loadAll_1 = loadAll$1;
2817var load_1    = load$1;
2818
2819var loader = {
2820	loadAll: loadAll_1,
2821	load: load_1
2822};
2823
2824/*eslint-disable no-use-before-define*/
2825
2826
2827
2828
2829
2830var _toString       = Object.prototype.toString;
2831var _hasOwnProperty = Object.prototype.hasOwnProperty;
2832
2833var CHAR_BOM                  = 0xFEFF;
2834var CHAR_TAB                  = 0x09; /* Tab */
2835var CHAR_LINE_FEED            = 0x0A; /* LF */
2836var CHAR_CARRIAGE_RETURN      = 0x0D; /* CR */
2837var CHAR_SPACE                = 0x20; /* Space */
2838var CHAR_EXCLAMATION          = 0x21; /* ! */
2839var CHAR_DOUBLE_QUOTE         = 0x22; /* " */
2840var CHAR_SHARP                = 0x23; /* # */
2841var CHAR_PERCENT              = 0x25; /* % */
2842var CHAR_AMPERSAND            = 0x26; /* & */
2843var CHAR_SINGLE_QUOTE         = 0x27; /* ' */
2844var CHAR_ASTERISK             = 0x2A; /* * */
2845var CHAR_COMMA                = 0x2C; /* , */
2846var CHAR_MINUS                = 0x2D; /* - */
2847var CHAR_COLON                = 0x3A; /* : */
2848var CHAR_EQUALS               = 0x3D; /* = */
2849var CHAR_GREATER_THAN         = 0x3E; /* > */
2850var CHAR_QUESTION             = 0x3F; /* ? */
2851var CHAR_COMMERCIAL_AT        = 0x40; /* @ */
2852var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */
2853var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
2854var CHAR_GRAVE_ACCENT         = 0x60; /* ` */
2855var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */
2856var CHAR_VERTICAL_LINE        = 0x7C; /* | */
2857var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */
2858
2859var ESCAPE_SEQUENCES = {};
2860
2861ESCAPE_SEQUENCES[0x00]   = '\\0';
2862ESCAPE_SEQUENCES[0x07]   = '\\a';
2863ESCAPE_SEQUENCES[0x08]   = '\\b';
2864ESCAPE_SEQUENCES[0x09]   = '\\t';
2865ESCAPE_SEQUENCES[0x0A]   = '\\n';
2866ESCAPE_SEQUENCES[0x0B]   = '\\v';
2867ESCAPE_SEQUENCES[0x0C]   = '\\f';
2868ESCAPE_SEQUENCES[0x0D]   = '\\r';
2869ESCAPE_SEQUENCES[0x1B]   = '\\e';
2870ESCAPE_SEQUENCES[0x22]   = '\\"';
2871ESCAPE_SEQUENCES[0x5C]   = '\\\\';
2872ESCAPE_SEQUENCES[0x85]   = '\\N';
2873ESCAPE_SEQUENCES[0xA0]   = '\\_';
2874ESCAPE_SEQUENCES[0x2028] = '\\L';
2875ESCAPE_SEQUENCES[0x2029] = '\\P';
2876
2877var DEPRECATED_BOOLEANS_SYNTAX = [
2878  'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
2879  'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
2880];
2881
2882var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;
2883
2884function compileStyleMap(schema, map) {
2885  var result, keys, index, length, tag, style, type;
2886
2887  if (map === null) return {};
2888
2889  result = {};
2890  keys = Object.keys(map);
2891
2892  for (index = 0, length = keys.length; index < length; index += 1) {
2893    tag = keys[index];
2894    style = String(map[tag]);
2895
2896    if (tag.slice(0, 2) === '!!') {
2897      tag = 'tag:yaml.org,2002:' + tag.slice(2);
2898    }
2899    type = schema.compiledTypeMap['fallback'][tag];
2900
2901    if (type && _hasOwnProperty.call(type.styleAliases, style)) {
2902      style = type.styleAliases[style];
2903    }
2904
2905    result[tag] = style;
2906  }
2907
2908  return result;
2909}
2910
2911function encodeHex(character) {
2912  var string, handle, length;
2913
2914  string = character.toString(16).toUpperCase();
2915
2916  if (character <= 0xFF) {
2917    handle = 'x';
2918    length = 2;
2919  } else if (character <= 0xFFFF) {
2920    handle = 'u';
2921    length = 4;
2922  } else if (character <= 0xFFFFFFFF) {
2923    handle = 'U';
2924    length = 8;
2925  } else {
2926    throw new exception('code point within a string may not be greater than 0xFFFFFFFF');
2927  }
2928
2929  return '\\' + handle + common.repeat('0', length - string.length) + string;
2930}
2931
2932
2933var QUOTING_TYPE_SINGLE = 1,
2934    QUOTING_TYPE_DOUBLE = 2;
2935
2936function State(options) {
2937  this.schema        = options['schema'] || _default;
2938  this.indent        = Math.max(1, (options['indent'] || 2));
2939  this.noArrayIndent = options['noArrayIndent'] || false;
2940  this.skipInvalid   = options['skipInvalid'] || false;
2941  this.flowLevel     = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
2942  this.styleMap      = compileStyleMap(this.schema, options['styles'] || null);
2943  this.sortKeys      = options['sortKeys'] || false;
2944  this.lineWidth     = options['lineWidth'] || 80;
2945  this.noRefs        = options['noRefs'] || false;
2946  this.noCompatMode  = options['noCompatMode'] || false;
2947  this.condenseFlow  = options['condenseFlow'] || false;
2948  this.quotingType   = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;
2949  this.forceQuotes   = options['forceQuotes'] || false;
2950  this.replacer      = typeof options['replacer'] === 'function' ? options['replacer'] : null;
2951
2952  this.implicitTypes = this.schema.compiledImplicit;
2953  this.explicitTypes = this.schema.compiledExplicit;
2954
2955  this.tag = null;
2956  this.result = '';
2957
2958  this.duplicates = [];
2959  this.usedDuplicates = null;
2960}
2961
2962// Indents every line in a string. Empty lines (\n only) are not indented.
2963function indentString(string, spaces) {
2964  var ind = common.repeat(' ', spaces),
2965      position = 0,
2966      next = -1,
2967      result = '',
2968      line,
2969      length = string.length;
2970
2971  while (position < length) {
2972    next = string.indexOf('\n', position);
2973    if (next === -1) {
2974      line = string.slice(position);
2975      position = length;
2976    } else {
2977      line = string.slice(position, next + 1);
2978      position = next + 1;
2979    }
2980
2981    if (line.length && line !== '\n') result += ind;
2982
2983    result += line;
2984  }
2985
2986  return result;
2987}
2988
2989function generateNextLine(state, level) {
2990  return '\n' + common.repeat(' ', state.indent * level);
2991}
2992
2993function testImplicitResolving(state, str) {
2994  var index, length, type;
2995
2996  for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
2997    type = state.implicitTypes[index];
2998
2999    if (type.resolve(str)) {
3000      return true;
3001    }
3002  }
3003
3004  return false;
3005}
3006
3007// [33] s-white ::= s-space | s-tab
3008function isWhitespace(c) {
3009  return c === CHAR_SPACE || c === CHAR_TAB;
3010}
3011
3012// Returns true if the character can be printed without escaping.
3013// From YAML 1.2: "any allowed characters known to be non-printable
3014// should also be escaped. [However,] This isn’t mandatory"
3015// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029.
3016function isPrintable(c) {
3017  return  (0x00020 <= c && c <= 0x00007E)
3018      || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)
3019      || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)
3020      ||  (0x10000 <= c && c <= 0x10FFFF);
3021}
3022
3023// [34] ns-char ::= nb-char - s-white
3024// [27] nb-char ::= c-printable - b-char - c-byte-order-mark
3025// [26] b-char  ::= b-line-feed | b-carriage-return
3026// Including s-white (for some reason, examples doesn't match specs in this aspect)
3027// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark
3028function isNsCharOrWhitespace(c) {
3029  return isPrintable(c)
3030    && c !== CHAR_BOM
3031    // - b-char
3032    && c !== CHAR_CARRIAGE_RETURN
3033    && c !== CHAR_LINE_FEED;
3034}
3035
3036// [127]  ns-plain-safe(c) ::= c = flow-out  ⇒ ns-plain-safe-out
3037//                             c = flow-in   ⇒ ns-plain-safe-in
3038//                             c = block-key ⇒ ns-plain-safe-out
3039//                             c = flow-key  ⇒ ns-plain-safe-in
3040// [128] ns-plain-safe-out ::= ns-char
3041// [129]  ns-plain-safe-in ::= ns-char - c-flow-indicator
3042// [130]  ns-plain-char(c) ::=  ( ns-plain-safe(c) - “:” - “#” )
3043//                            | ( /* An ns-char preceding */ “#” )
3044//                            | ( “:” /* Followed by an ns-plain-safe(c) */ )
3045function isPlainSafe(c, prev, inblock) {
3046  var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);
3047  var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);
3048  return (
3049    // ns-plain-safe
3050    inblock ? // c = flow-in
3051      cIsNsCharOrWhitespace
3052      : cIsNsCharOrWhitespace
3053        // - c-flow-indicator
3054        && c !== CHAR_COMMA
3055        && c !== CHAR_LEFT_SQUARE_BRACKET
3056        && c !== CHAR_RIGHT_SQUARE_BRACKET
3057        && c !== CHAR_LEFT_CURLY_BRACKET
3058        && c !== CHAR_RIGHT_CURLY_BRACKET
3059  )
3060    // ns-plain-char
3061    && c !== CHAR_SHARP // false on '#'
3062    && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '
3063    || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'
3064    || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'
3065}
3066
3067// Simplified test for values allowed as the first character in plain style.
3068function isPlainSafeFirst(c) {
3069  // Uses a subset of ns-char - c-indicator
3070  // where ns-char = nb-char - s-white.
3071  // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part
3072  return isPrintable(c) && c !== CHAR_BOM
3073    && !isWhitespace(c) // - s-white
3074    // - (c-indicator ::=
3075    // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”
3076    && c !== CHAR_MINUS
3077    && c !== CHAR_QUESTION
3078    && c !== CHAR_COLON
3079    && c !== CHAR_COMMA
3080    && c !== CHAR_LEFT_SQUARE_BRACKET
3081    && c !== CHAR_RIGHT_SQUARE_BRACKET
3082    && c !== CHAR_LEFT_CURLY_BRACKET
3083    && c !== CHAR_RIGHT_CURLY_BRACKET
3084    // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"”
3085    && c !== CHAR_SHARP
3086    && c !== CHAR_AMPERSAND
3087    && c !== CHAR_ASTERISK
3088    && c !== CHAR_EXCLAMATION
3089    && c !== CHAR_VERTICAL_LINE
3090    && c !== CHAR_EQUALS
3091    && c !== CHAR_GREATER_THAN
3092    && c !== CHAR_SINGLE_QUOTE
3093    && c !== CHAR_DOUBLE_QUOTE
3094    // | “%” | “@” | “`”)
3095    && c !== CHAR_PERCENT
3096    && c !== CHAR_COMMERCIAL_AT
3097    && c !== CHAR_GRAVE_ACCENT;
3098}
3099
3100// Simplified test for values allowed as the last character in plain style.
3101function isPlainSafeLast(c) {
3102  // just not whitespace or colon, it will be checked to be plain character later
3103  return !isWhitespace(c) && c !== CHAR_COLON;
3104}
3105
3106// Same as 'string'.codePointAt(pos), but works in older browsers.
3107function codePointAt(string, pos) {
3108  var first = string.charCodeAt(pos), second;
3109  if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {
3110    second = string.charCodeAt(pos + 1);
3111    if (second >= 0xDC00 && second <= 0xDFFF) {
3112      // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
3113      return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
3114    }
3115  }
3116  return first;
3117}
3118
3119// Determines whether block indentation indicator is required.
3120function needIndentIndicator(string) {
3121  var leadingSpaceRe = /^\n* /;
3122  return leadingSpaceRe.test(string);
3123}
3124
3125var STYLE_PLAIN   = 1,
3126    STYLE_SINGLE  = 2,
3127    STYLE_LITERAL = 3,
3128    STYLE_FOLDED  = 4,
3129    STYLE_DOUBLE  = 5;
3130
3131// Determines which scalar styles are possible and returns the preferred style.
3132// lineWidth = -1 => no limit.
3133// Pre-conditions: str.length > 0.
3134// Post-conditions:
3135//    STYLE_PLAIN or STYLE_SINGLE => no \n are in the string.
3136//    STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).
3137//    STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
3138function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,
3139  testAmbiguousType, quotingType, forceQuotes, inblock) {
3140
3141  var i;
3142  var char = 0;
3143  var prevChar = null;
3144  var hasLineBreak = false;
3145  var hasFoldableLine = false; // only checked if shouldTrackWidth
3146  var shouldTrackWidth = lineWidth !== -1;
3147  var previousLineBreak = -1; // count the first line correctly
3148  var plain = isPlainSafeFirst(codePointAt(string, 0))
3149          && isPlainSafeLast(codePointAt(string, string.length - 1));
3150
3151  if (singleLineOnly || forceQuotes) {
3152    // Case: no block styles.
3153    // Check for disallowed characters to rule out plain and single.
3154    for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {
3155      char = codePointAt(string, i);
3156      if (!isPrintable(char)) {
3157        return STYLE_DOUBLE;
3158      }
3159      plain = plain && isPlainSafe(char, prevChar, inblock);
3160      prevChar = char;
3161    }
3162  } else {
3163    // Case: block styles permitted.
3164    for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {
3165      char = codePointAt(string, i);
3166      if (char === CHAR_LINE_FEED) {
3167        hasLineBreak = true;
3168        // Check if any line can be folded.
3169        if (shouldTrackWidth) {
3170          hasFoldableLine = hasFoldableLine ||
3171            // Foldable line = too long, and not more-indented.
3172            (i - previousLineBreak - 1 > lineWidth &&
3173             string[previousLineBreak + 1] !== ' ');
3174          previousLineBreak = i;
3175        }
3176      } else if (!isPrintable(char)) {
3177        return STYLE_DOUBLE;
3178      }
3179      plain = plain && isPlainSafe(char, prevChar, inblock);
3180      prevChar = char;
3181    }
3182    // in case the end is missing a \n
3183    hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
3184      (i - previousLineBreak - 1 > lineWidth &&
3185       string[previousLineBreak + 1] !== ' '));
3186  }
3187  // Although every style can represent \n without escaping, prefer block styles
3188  // for multiline, since they're more readable and they don't add empty lines.
3189  // Also prefer folding a super-long line.
3190  if (!hasLineBreak && !hasFoldableLine) {
3191    // Strings interpretable as another type have to be quoted;
3192    // e.g. the string 'true' vs. the boolean true.
3193    if (plain && !forceQuotes && !testAmbiguousType(string)) {
3194      return STYLE_PLAIN;
3195    }
3196    return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;
3197  }
3198  // Edge case: block indentation indicator can only have one digit.
3199  if (indentPerLevel > 9 && needIndentIndicator(string)) {
3200    return STYLE_DOUBLE;
3201  }
3202  // At this point we know block styles are valid.
3203  // Prefer literal style unless we want to fold.
3204  if (!forceQuotes) {
3205    return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;
3206  }
3207  return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;
3208}
3209
3210// Note: line breaking/folding is implemented for only the folded style.
3211// NB. We drop the last trailing newline (if any) of a returned block scalar
3212//  since the dumper adds its own newline. This always works:
3213//    • No ending newline => unaffected; already using strip "-" chomping.
3214//    • Ending newline    => removed then restored.
3215//  Importantly, this keeps the "+" chomp indicator from gaining an extra line.
3216function writeScalar(state, string, level, iskey, inblock) {
3217  state.dump = (function () {
3218    if (string.length === 0) {
3219      return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''";
3220    }
3221    if (!state.noCompatMode) {
3222      if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {
3223        return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'");
3224      }
3225    }
3226
3227    var indent = state.indent * Math.max(1, level); // no 0-indent scalars
3228    // As indentation gets deeper, let the width decrease monotonically
3229    // to the lower bound min(state.lineWidth, 40).
3230    // Note that this implies
3231    //  state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.
3232    //  state.lineWidth > 40 + state.indent: width decreases until the lower bound.
3233    // This behaves better than a constant minimum width which disallows narrower options,
3234    // or an indent threshold which causes the width to suddenly increase.
3235    var lineWidth = state.lineWidth === -1
3236      ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);
3237
3238    // Without knowing if keys are implicit/explicit, assume implicit for safety.
3239    var singleLineOnly = iskey
3240      // No block styles in flow mode.
3241      || (state.flowLevel > -1 && level >= state.flowLevel);
3242    function testAmbiguity(string) {
3243      return testImplicitResolving(state, string);
3244    }
3245
3246    switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,
3247      testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {
3248
3249      case STYLE_PLAIN:
3250        return string;
3251      case STYLE_SINGLE:
3252        return "'" + string.replace(/'/g, "''") + "'";
3253      case STYLE_LITERAL:
3254        return '|' + blockHeader(string, state.indent)
3255          + dropEndingNewline(indentString(string, indent));
3256      case STYLE_FOLDED:
3257        return '>' + blockHeader(string, state.indent)
3258          + dropEndingNewline(indentString(foldString(string, lineWidth), indent));
3259      case STYLE_DOUBLE:
3260        return '"' + escapeString(string) + '"';
3261      default:
3262        throw new exception('impossible error: invalid scalar style');
3263    }
3264  }());
3265}
3266
3267// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.
3268function blockHeader(string, indentPerLevel) {
3269  var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';
3270
3271  // note the special case: the string '\n' counts as a "trailing" empty line.
3272  var clip =          string[string.length - 1] === '\n';
3273  var keep = clip && (string[string.length - 2] === '\n' || string === '\n');
3274  var chomp = keep ? '+' : (clip ? '' : '-');
3275
3276  return indentIndicator + chomp + '\n';
3277}
3278
3279// (See the note for writeScalar.)
3280function dropEndingNewline(string) {
3281  return string[string.length - 1] === '\n' ? string.slice(0, -1) : string;
3282}
3283
3284// Note: a long line without a suitable break point will exceed the width limit.
3285// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.
3286function foldString(string, width) {
3287  // In folded style, $k$ consecutive newlines output as $k+1$ newlines—
3288  // unless they're before or after a more-indented line, or at the very
3289  // beginning or end, in which case $k$ maps to $k$.
3290  // Therefore, parse each chunk as newline(s) followed by a content line.
3291  var lineRe = /(\n+)([^\n]*)/g;
3292
3293  // first line (possibly an empty line)
3294  var result = (function () {
3295    var nextLF = string.indexOf('\n');
3296    nextLF = nextLF !== -1 ? nextLF : string.length;
3297    lineRe.lastIndex = nextLF;
3298    return foldLine(string.slice(0, nextLF), width);
3299  }());
3300  // If we haven't reached the first content line yet, don't add an extra \n.
3301  var prevMoreIndented = string[0] === '\n' || string[0] === ' ';
3302  var moreIndented;
3303
3304  // rest of the lines
3305  var match;
3306  while ((match = lineRe.exec(string))) {
3307    var prefix = match[1], line = match[2];
3308    moreIndented = (line[0] === ' ');
3309    result += prefix
3310      + (!prevMoreIndented && !moreIndented && line !== ''
3311        ? '\n' : '')
3312      + foldLine(line, width);
3313    prevMoreIndented = moreIndented;
3314  }
3315
3316  return result;
3317}
3318
3319// Greedy line breaking.
3320// Picks the longest line under the limit each time,
3321// otherwise settles for the shortest line over the limit.
3322// NB. More-indented lines *cannot* be folded, as that would add an extra \n.
3323function foldLine(line, width) {
3324  if (line === '' || line[0] === ' ') return line;
3325
3326  // Since a more-indented line adds a \n, breaks can't be followed by a space.
3327  var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.
3328  var match;
3329  // start is an inclusive index. end, curr, and next are exclusive.
3330  var start = 0, end, curr = 0, next = 0;
3331  var result = '';
3332
3333  // Invariants: 0 <= start <= length-1.
3334  //   0 <= curr <= next <= max(0, length-2). curr - start <= width.
3335  // Inside the loop:
3336  //   A match implies length >= 2, so curr and next are <= length-2.
3337  while ((match = breakRe.exec(line))) {
3338    next = match.index;
3339    // maintain invariant: curr - start <= width
3340    if (next - start > width) {
3341      end = (curr > start) ? curr : next; // derive end <= length-2
3342      result += '\n' + line.slice(start, end);
3343      // skip the space that was output as \n
3344      start = end + 1;                    // derive start <= length-1
3345    }
3346    curr = next;
3347  }
3348
3349  // By the invariants, start <= length-1, so there is something left over.
3350  // It is either the whole string or a part starting from non-whitespace.
3351  result += '\n';
3352  // Insert a break if the remainder is too long and there is a break available.
3353  if (line.length - start > width && curr > start) {
3354    result += line.slice(start, curr) + '\n' + line.slice(curr + 1);
3355  } else {
3356    result += line.slice(start);
3357  }
3358
3359  return result.slice(1); // drop extra \n joiner
3360}
3361
3362// Escapes a double-quoted string.
3363function escapeString(string) {
3364  var result = '';
3365  var char = 0;
3366  var escapeSeq;
3367
3368  for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {
3369    char = codePointAt(string, i);
3370    escapeSeq = ESCAPE_SEQUENCES[char];
3371
3372    if (!escapeSeq && isPrintable(char)) {
3373      result += string[i];
3374      if (char >= 0x10000) result += string[i + 1];
3375    } else {
3376      result += escapeSeq || encodeHex(char);
3377    }
3378  }
3379
3380  return result;
3381}
3382
3383function writeFlowSequence(state, level, object) {
3384  var _result = '',
3385      _tag    = state.tag,
3386      index,
3387      length,
3388      value;
3389
3390  for (index = 0, length = object.length; index < length; index += 1) {
3391    value = object[index];
3392
3393    if (state.replacer) {
3394      value = state.replacer.call(object, String(index), value);
3395    }
3396
3397    // Write only valid elements, put null instead of invalid elements.
3398    if (writeNode(state, level, value, false, false) ||
3399        (typeof value === 'undefined' &&
3400         writeNode(state, level, null, false, false))) {
3401
3402      if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');
3403      _result += state.dump;
3404    }
3405  }
3406
3407  state.tag = _tag;
3408  state.dump = '[' + _result + ']';
3409}
3410
3411function writeBlockSequence(state, level, object, compact) {
3412  var _result = '',
3413      _tag    = state.tag,
3414      index,
3415      length,
3416      value;
3417
3418  for (index = 0, length = object.length; index < length; index += 1) {
3419    value = object[index];
3420
3421    if (state.replacer) {
3422      value = state.replacer.call(object, String(index), value);
3423    }
3424
3425    // Write only valid elements, put null instead of invalid elements.
3426    if (writeNode(state, level + 1, value, true, true, false, true) ||
3427        (typeof value === 'undefined' &&
3428         writeNode(state, level + 1, null, true, true, false, true))) {
3429
3430      if (!compact || _result !== '') {
3431        _result += generateNextLine(state, level);
3432      }
3433
3434      if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
3435        _result += '-';
3436      } else {
3437        _result += '- ';
3438      }
3439
3440      _result += state.dump;
3441    }
3442  }
3443
3444  state.tag = _tag;
3445  state.dump = _result || '[]'; // Empty sequence if no valid values.
3446}
3447
3448function writeFlowMapping(state, level, object) {
3449  var _result       = '',
3450      _tag          = state.tag,
3451      objectKeyList = Object.keys(object),
3452      index,
3453      length,
3454      objectKey,
3455      objectValue,
3456      pairBuffer;
3457
3458  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
3459
3460    pairBuffer = '';
3461    if (_result !== '') pairBuffer += ', ';
3462
3463    if (state.condenseFlow) pairBuffer += '"';
3464
3465    objectKey = objectKeyList[index];
3466    objectValue = object[objectKey];
3467
3468    if (state.replacer) {
3469      objectValue = state.replacer.call(object, objectKey, objectValue);
3470    }
3471
3472    if (!writeNode(state, level, objectKey, false, false)) {
3473      continue; // Skip this pair because of invalid key;
3474    }
3475
3476    if (state.dump.length > 1024) pairBuffer += '? ';
3477
3478    pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' ');
3479
3480    if (!writeNode(state, level, objectValue, false, false)) {
3481      continue; // Skip this pair because of invalid value.
3482    }
3483
3484    pairBuffer += state.dump;
3485
3486    // Both key and value are valid.
3487    _result += pairBuffer;
3488  }
3489
3490  state.tag = _tag;
3491  state.dump = '{' + _result + '}';
3492}
3493
3494function writeBlockMapping(state, level, object, compact) {
3495  var _result       = '',
3496      _tag          = state.tag,
3497      objectKeyList = Object.keys(object),
3498      index,
3499      length,
3500      objectKey,
3501      objectValue,
3502      explicitPair,
3503      pairBuffer;
3504
3505  // Allow sorting keys so that the output file is deterministic
3506  if (state.sortKeys === true) {
3507    // Default sorting
3508    objectKeyList.sort();
3509  } else if (typeof state.sortKeys === 'function') {
3510    // Custom sort function
3511    objectKeyList.sort(state.sortKeys);
3512  } else if (state.sortKeys) {
3513    // Something is wrong
3514    throw new exception('sortKeys must be a boolean or a function');
3515  }
3516
3517  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
3518    pairBuffer = '';
3519
3520    if (!compact || _result !== '') {
3521      pairBuffer += generateNextLine(state, level);
3522    }
3523
3524    objectKey = objectKeyList[index];
3525    objectValue = object[objectKey];
3526
3527    if (state.replacer) {
3528      objectValue = state.replacer.call(object, objectKey, objectValue);
3529    }
3530
3531    if (!writeNode(state, level + 1, objectKey, true, true, true)) {
3532      continue; // Skip this pair because of invalid key.
3533    }
3534
3535    explicitPair = (state.tag !== null && state.tag !== '?') ||
3536                   (state.dump && state.dump.length > 1024);
3537
3538    if (explicitPair) {
3539      if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
3540        pairBuffer += '?';
3541      } else {
3542        pairBuffer += '? ';
3543      }
3544    }
3545
3546    pairBuffer += state.dump;
3547
3548    if (explicitPair) {
3549      pairBuffer += generateNextLine(state, level);
3550    }
3551
3552    if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
3553      continue; // Skip this pair because of invalid value.
3554    }
3555
3556    if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
3557      pairBuffer += ':';
3558    } else {
3559      pairBuffer += ': ';
3560    }
3561
3562    pairBuffer += state.dump;
3563
3564    // Both key and value are valid.
3565    _result += pairBuffer;
3566  }
3567
3568  state.tag = _tag;
3569  state.dump = _result || '{}'; // Empty mapping if no valid pairs.
3570}
3571
3572function detectType(state, object, explicit) {
3573  var _result, typeList, index, length, type, style;
3574
3575  typeList = explicit ? state.explicitTypes : state.implicitTypes;
3576
3577  for (index = 0, length = typeList.length; index < length; index += 1) {
3578    type = typeList[index];
3579
3580    if ((type.instanceOf  || type.predicate) &&
3581        (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
3582        (!type.predicate  || type.predicate(object))) {
3583
3584      if (explicit) {
3585        if (type.multi && type.representName) {
3586          state.tag = type.representName(object);
3587        } else {
3588          state.tag = type.tag;
3589        }
3590      } else {
3591        state.tag = '?';
3592      }
3593
3594      if (type.represent) {
3595        style = state.styleMap[type.tag] || type.defaultStyle;
3596
3597        if (_toString.call(type.represent) === '[object Function]') {
3598          _result = type.represent(object, style);
3599        } else if (_hasOwnProperty.call(type.represent, style)) {
3600          _result = type.represent[style](object, style);
3601        } else {
3602          throw new exception('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
3603        }
3604
3605        state.dump = _result;
3606      }
3607
3608      return true;
3609    }
3610  }
3611
3612  return false;
3613}
3614
3615// Serializes `object` and writes it to global `result`.
3616// Returns true on success, or false on invalid object.
3617//
3618function writeNode(state, level, object, block, compact, iskey, isblockseq) {
3619  state.tag = null;
3620  state.dump = object;
3621
3622  if (!detectType(state, object, false)) {
3623    detectType(state, object, true);
3624  }
3625
3626  var type = _toString.call(state.dump);
3627  var inblock = block;
3628  var tagStr;
3629
3630  if (block) {
3631    block = (state.flowLevel < 0 || state.flowLevel > level);
3632  }
3633
3634  var objectOrArray = type === '[object Object]' || type === '[object Array]',
3635      duplicateIndex,
3636      duplicate;
3637
3638  if (objectOrArray) {
3639    duplicateIndex = state.duplicates.indexOf(object);
3640    duplicate = duplicateIndex !== -1;
3641  }
3642
3643  if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
3644    compact = false;
3645  }
3646
3647  if (duplicate && state.usedDuplicates[duplicateIndex]) {
3648    state.dump = '*ref_' + duplicateIndex;
3649  } else {
3650    if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
3651      state.usedDuplicates[duplicateIndex] = true;
3652    }
3653    if (type === '[object Object]') {
3654      if (block && (Object.keys(state.dump).length !== 0)) {
3655        writeBlockMapping(state, level, state.dump, compact);
3656        if (duplicate) {
3657          state.dump = '&ref_' + duplicateIndex + state.dump;
3658        }
3659      } else {
3660        writeFlowMapping(state, level, state.dump);
3661        if (duplicate) {
3662          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
3663        }
3664      }
3665    } else if (type === '[object Array]') {
3666      if (block && (state.dump.length !== 0)) {
3667        if (state.noArrayIndent && !isblockseq && level > 0) {
3668          writeBlockSequence(state, level - 1, state.dump, compact);
3669        } else {
3670          writeBlockSequence(state, level, state.dump, compact);
3671        }
3672        if (duplicate) {
3673          state.dump = '&ref_' + duplicateIndex + state.dump;
3674        }
3675      } else {
3676        writeFlowSequence(state, level, state.dump);
3677        if (duplicate) {
3678          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
3679        }
3680      }
3681    } else if (type === '[object String]') {
3682      if (state.tag !== '?') {
3683        writeScalar(state, state.dump, level, iskey, inblock);
3684      }
3685    } else if (type === '[object Undefined]') {
3686      return false;
3687    } else {
3688      if (state.skipInvalid) return false;
3689      throw new exception('unacceptable kind of an object to dump ' + type);
3690    }
3691
3692    if (state.tag !== null && state.tag !== '?') {
3693      // Need to encode all characters except those allowed by the spec:
3694      //
3695      // [35] ns-dec-digit    ::=  [#x30-#x39] /* 0-9 */
3696      // [36] ns-hex-digit    ::=  ns-dec-digit
3697      //                         | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */
3698      // [37] ns-ascii-letter ::=  [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */
3699      // [38] ns-word-char    ::=  ns-dec-digit | ns-ascii-letter | “-”
3700      // [39] ns-uri-char     ::=  “%” ns-hex-digit ns-hex-digit | ns-word-char | “#”
3701      //                         | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,”
3702      //                         | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]”
3703      //
3704      // Also need to encode '!' because it has special meaning (end of tag prefix).
3705      //
3706      tagStr = encodeURI(
3707        state.tag[0] === '!' ? state.tag.slice(1) : state.tag
3708      ).replace(/!/g, '%21');
3709
3710      if (state.tag[0] === '!') {
3711        tagStr = '!' + tagStr;
3712      } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {
3713        tagStr = '!!' + tagStr.slice(18);
3714      } else {
3715        tagStr = '!<' + tagStr + '>';
3716      }
3717
3718      state.dump = tagStr + ' ' + state.dump;
3719    }
3720  }
3721
3722  return true;
3723}
3724
3725function getDuplicateReferences(object, state) {
3726  var objects = [],
3727      duplicatesIndexes = [],
3728      index,
3729      length;
3730
3731  inspectNode(object, objects, duplicatesIndexes);
3732
3733  for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
3734    state.duplicates.push(objects[duplicatesIndexes[index]]);
3735  }
3736  state.usedDuplicates = new Array(length);
3737}
3738
3739function inspectNode(object, objects, duplicatesIndexes) {
3740  var objectKeyList,
3741      index,
3742      length;
3743
3744  if (object !== null && typeof object === 'object') {
3745    index = objects.indexOf(object);
3746    if (index !== -1) {
3747      if (duplicatesIndexes.indexOf(index) === -1) {
3748        duplicatesIndexes.push(index);
3749      }
3750    } else {
3751      objects.push(object);
3752
3753      if (Array.isArray(object)) {
3754        for (index = 0, length = object.length; index < length; index += 1) {
3755          inspectNode(object[index], objects, duplicatesIndexes);
3756        }
3757      } else {
3758        objectKeyList = Object.keys(object);
3759
3760        for (index = 0, length = objectKeyList.length; index < length; index += 1) {
3761          inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
3762        }
3763      }
3764    }
3765  }
3766}
3767
3768function dump$1(input, options) {
3769  options = options || {};
3770
3771  var state = new State(options);
3772
3773  if (!state.noRefs) getDuplicateReferences(input, state);
3774
3775  var value = input;
3776
3777  if (state.replacer) {
3778    value = state.replacer.call({ '': value }, '', value);
3779  }
3780
3781  if (writeNode(state, 0, value, true, true)) return state.dump + '\n';
3782
3783  return '';
3784}
3785
3786var dump_1 = dump$1;
3787
3788var dumper = {
3789	dump: dump_1
3790};
3791
3792function renamed(from, to) {
3793  return function () {
3794    throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +
3795      'Use yaml.' + to + ' instead, which is now safe by default.');
3796  };
3797}
3798
3799
3800var Type                = type;
3801var Schema              = schema;
3802var FAILSAFE_SCHEMA     = failsafe;
3803var JSON_SCHEMA         = json;
3804var CORE_SCHEMA         = core;
3805var DEFAULT_SCHEMA      = _default;
3806var load                = loader.load;
3807var loadAll             = loader.loadAll;
3808var dump                = dumper.dump;
3809var YAMLException       = exception;
3810
3811// Re-export all types in case user wants to create custom schema
3812var types = {
3813  binary:    binary,
3814  float:     float,
3815  map:       map,
3816  null:      _null,
3817  pairs:     pairs,
3818  set:       set,
3819  timestamp: timestamp,
3820  bool:      bool,
3821  int:       int,
3822  merge:     merge,
3823  omap:      omap,
3824  seq:       seq,
3825  str:       str
3826};
3827
3828// Removed functions from JS-YAML 3.0.x
3829var safeLoad            = renamed('safeLoad', 'load');
3830var safeLoadAll         = renamed('safeLoadAll', 'loadAll');
3831var safeDump            = renamed('safeDump', 'dump');
3832
3833var jsYaml = {
3834	Type: Type,
3835	Schema: Schema,
3836	FAILSAFE_SCHEMA: FAILSAFE_SCHEMA,
3837	JSON_SCHEMA: JSON_SCHEMA,
3838	CORE_SCHEMA: CORE_SCHEMA,
3839	DEFAULT_SCHEMA: DEFAULT_SCHEMA,
3840	load: load,
3841	loadAll: loadAll,
3842	dump: dump,
3843	YAMLException: YAMLException,
3844	types: types,
3845	safeLoad: safeLoad,
3846	safeLoadAll: safeLoadAll,
3847	safeDump: safeDump
3848};
3849
3850export default jsYaml;
3851export { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };
3852