| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161 | 'use strict';var PlainValue = require('./PlainValue-ec8e588e.js');function addCommentBefore(str, indent, comment) {  if (!comment) return str;  const cc = comment.replace(/[\s\S]^/gm, `$&${indent}#`);  return `#${cc}\n${indent}${str}`;}function addComment(str, indent, comment) {  return !comment ? str : comment.indexOf('\n') === -1 ? `${str} #${comment}` : `${str}\n` + comment.replace(/^/gm, `${indent || ''}#`);}class Node {}function toJSON(value, arg, ctx) {  if (Array.isArray(value)) return value.map((v, i) => toJSON(v, String(i), ctx));  if (value && typeof value.toJSON === 'function') {    const anchor = ctx && ctx.anchors && ctx.anchors.get(value);    if (anchor) ctx.onCreate = res => {      anchor.res = res;      delete ctx.onCreate;    };    const res = value.toJSON(arg, ctx);    if (anchor && ctx.onCreate) ctx.onCreate(res);    return res;  }  if ((!ctx || !ctx.keep) && typeof value === 'bigint') return Number(value);  return value;}class Scalar extends Node {  constructor(value) {    super();    this.value = value;  }  toJSON(arg, ctx) {    return ctx && ctx.keep ? this.value : toJSON(this.value, arg, ctx);  }  toString() {    return String(this.value);  }}function collectionFromPath(schema, path, value) {  let v = value;  for (let i = path.length - 1; i >= 0; --i) {    const k = path[i];    if (Number.isInteger(k) && k >= 0) {      const a = [];      a[k] = v;      v = a;    } else {      const o = {};      Object.defineProperty(o, k, {        value: v,        writable: true,        enumerable: true,        configurable: true      });      v = o;    }  }  return schema.createNode(v, false);} // null, undefined, or an empty non-string iterable (e.g. [])const isEmptyPath = path => path == null || typeof path === 'object' && path[Symbol.iterator]().next().done;class Collection extends Node {  constructor(schema) {    super();    PlainValue._defineProperty(this, "items", []);    this.schema = schema;  }  addIn(path, value) {    if (isEmptyPath(path)) this.add(value);else {      const [key, ...rest] = path;      const node = this.get(key, true);      if (node instanceof Collection) node.addIn(rest, value);else if (node === undefined && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);    }  }  deleteIn([key, ...rest]) {    if (rest.length === 0) return this.delete(key);    const node = this.get(key, true);    if (node instanceof Collection) return node.deleteIn(rest);else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);  }  getIn([key, ...rest], keepScalar) {    const node = this.get(key, true);    if (rest.length === 0) return !keepScalar && node instanceof Scalar ? node.value : node;else return node instanceof Collection ? node.getIn(rest, keepScalar) : undefined;  }  hasAllNullValues() {    return this.items.every(node => {      if (!node || node.type !== 'PAIR') return false;      const n = node.value;      return n == null || n instanceof Scalar && n.value == null && !n.commentBefore && !n.comment && !n.tag;    });  }  hasIn([key, ...rest]) {    if (rest.length === 0) return this.has(key);    const node = this.get(key, true);    return node instanceof Collection ? node.hasIn(rest) : false;  }  setIn([key, ...rest], value) {    if (rest.length === 0) {      this.set(key, value);    } else {      const node = this.get(key, true);      if (node instanceof Collection) node.setIn(rest, value);else if (node === undefined && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);    }  } // overridden in implementations  /* istanbul ignore next */  toJSON() {    return null;  }  toString(ctx, {    blockItem,    flowChars,    isMap,    itemIndent  }, onComment, onChompKeep) {    const {      indent,      indentStep,      stringify    } = ctx;    const inFlow = this.type === PlainValue.Type.FLOW_MAP || this.type === PlainValue.Type.FLOW_SEQ || ctx.inFlow;    if (inFlow) itemIndent += indentStep;    const allNullValues = isMap && this.hasAllNullValues();    ctx = Object.assign({}, ctx, {      allNullValues,      indent: itemIndent,      inFlow,      type: null    });    let chompKeep = false;    let hasItemWithNewLine = false;    const nodes = this.items.reduce((nodes, item, i) => {      let comment;      if (item) {        if (!chompKeep && item.spaceBefore) nodes.push({          type: 'comment',          str: ''        });        if (item.commentBefore) item.commentBefore.match(/^.*$/gm).forEach(line => {          nodes.push({            type: 'comment',            str: `#${line}`          });        });        if (item.comment) comment = item.comment;        if (inFlow && (!chompKeep && item.spaceBefore || item.commentBefore || item.comment || item.key && (item.key.commentBefore || item.key.comment) || item.value && (item.value.commentBefore || item.value.comment))) hasItemWithNewLine = true;      }      chompKeep = false;      let str = stringify(item, ctx, () => comment = null, () => chompKeep = true);      if (inFlow && !hasItemWithNewLine && str.includes('\n')) hasItemWithNewLine = true;      if (inFlow && i < this.items.length - 1) str += ',';      str = addComment(str, itemIndent, comment);      if (chompKeep && (comment || inFlow)) chompKeep = false;      nodes.push({        type: 'item',        str      });      return nodes;    }, []);    let str;    if (nodes.length === 0) {      str = flowChars.start + flowChars.end;    } else if (inFlow) {      const {        start,        end      } = flowChars;      const strings = nodes.map(n => n.str);      if (hasItemWithNewLine || strings.reduce((sum, str) => sum + str.length + 2, 2) > Collection.maxFlowStringSingleLineLength) {        str = start;        for (const s of strings) {          str += s ? `\n${indentStep}${indent}${s}` : '\n';        }        str += `\n${indent}${end}`;      } else {        str = `${start} ${strings.join(' ')} ${end}`;      }    } else {      const strings = nodes.map(blockItem);      str = strings.shift();      for (const s of strings) str += s ? `\n${indent}${s}` : '\n';    }    if (this.comment) {      str += '\n' + this.comment.replace(/^/gm, `${indent}#`);      if (onComment) onComment();    } else if (chompKeep && onChompKeep) onChompKeep();    return str;  }}PlainValue._defineProperty(Collection, "maxFlowStringSingleLineLength", 60);function asItemIndex(key) {  let idx = key instanceof Scalar ? key.value : key;  if (idx && typeof idx === 'string') idx = Number(idx);  return Number.isInteger(idx) && idx >= 0 ? idx : null;}class YAMLSeq extends Collection {  add(value) {    this.items.push(value);  }  delete(key) {    const idx = asItemIndex(key);    if (typeof idx !== 'number') return false;    const del = this.items.splice(idx, 1);    return del.length > 0;  }  get(key, keepScalar) {    const idx = asItemIndex(key);    if (typeof idx !== 'number') return undefined;    const it = this.items[idx];    return !keepScalar && it instanceof Scalar ? it.value : it;  }  has(key) {    const idx = asItemIndex(key);    return typeof idx === 'number' && idx < this.items.length;  }  set(key, value) {    const idx = asItemIndex(key);    if (typeof idx !== 'number') throw new Error(`Expected a valid index, not ${key}.`);    this.items[idx] = value;  }  toJSON(_, ctx) {    const seq = [];    if (ctx && ctx.onCreate) ctx.onCreate(seq);    let i = 0;    for (const item of this.items) seq.push(toJSON(item, String(i++), ctx));    return seq;  }  toString(ctx, onComment, onChompKeep) {    if (!ctx) return JSON.stringify(this);    return super.toString(ctx, {      blockItem: n => n.type === 'comment' ? n.str : `- ${n.str}`,      flowChars: {        start: '[',        end: ']'      },      isMap: false,      itemIndent: (ctx.indent || '') + '  '    }, onComment, onChompKeep);  }}const stringifyKey = (key, jsKey, ctx) => {  if (jsKey === null) return '';  if (typeof jsKey !== 'object') return String(jsKey);  if (key instanceof Node && ctx && ctx.doc) return key.toString({    anchors: Object.create(null),    doc: ctx.doc,    indent: '',    indentStep: ctx.indentStep,    inFlow: true,    inStringifyKey: true,    stringify: ctx.stringify  });  return JSON.stringify(jsKey);};class Pair extends Node {  constructor(key, value = null) {    super();    this.key = key;    this.value = value;    this.type = Pair.Type.PAIR;  }  get commentBefore() {    return this.key instanceof Node ? this.key.commentBefore : undefined;  }  set commentBefore(cb) {    if (this.key == null) this.key = new Scalar(null);    if (this.key instanceof Node) this.key.commentBefore = cb;else {      const msg = 'Pair.commentBefore is an alias for Pair.key.commentBefore. To set it, the key must be a Node.';      throw new Error(msg);    }  }  addToJSMap(ctx, map) {    const key = toJSON(this.key, '', ctx);    if (map instanceof Map) {      const value = toJSON(this.value, key, ctx);      map.set(key, value);    } else if (map instanceof Set) {      map.add(key);    } else {      const stringKey = stringifyKey(this.key, key, ctx);      const value = toJSON(this.value, stringKey, ctx);      if (stringKey in map) Object.defineProperty(map, stringKey, {        value,        writable: true,        enumerable: true,        configurable: true      });else map[stringKey] = value;    }    return map;  }  toJSON(_, ctx) {    const pair = ctx && ctx.mapAsMap ? new Map() : {};    return this.addToJSMap(ctx, pair);  }  toString(ctx, onComment, onChompKeep) {    if (!ctx || !ctx.doc) return JSON.stringify(this);    const {      indent: indentSize,      indentSeq,      simpleKeys    } = ctx.doc.options;    let {      key,      value    } = this;    let keyComment = key instanceof Node && key.comment;    if (simpleKeys) {      if (keyComment) {        throw new Error('With simple keys, key nodes cannot have comments');      }      if (key instanceof Collection) {        const msg = 'With simple keys, collection cannot be used as a key value';        throw new Error(msg);      }    }    let explicitKey = !simpleKeys && (!key || keyComment || (key instanceof Node ? key instanceof Collection || key.type === PlainValue.Type.BLOCK_FOLDED || key.type === PlainValue.Type.BLOCK_LITERAL : typeof key === 'object'));    const {      doc,      indent,      indentStep,      stringify    } = ctx;    ctx = Object.assign({}, ctx, {      implicitKey: !explicitKey,      indent: indent + indentStep    });    let chompKeep = false;    let str = stringify(key, ctx, () => keyComment = null, () => chompKeep = true);    str = addComment(str, ctx.indent, keyComment);    if (!explicitKey && str.length > 1024) {      if (simpleKeys) throw new Error('With simple keys, single line scalar must not span more than 1024 characters');      explicitKey = true;    }    if (ctx.allNullValues && !simpleKeys) {      if (this.comment) {        str = addComment(str, ctx.indent, this.comment);        if (onComment) onComment();      } else if (chompKeep && !keyComment && onChompKeep) onChompKeep();      return ctx.inFlow && !explicitKey ? str : `? ${str}`;    }    str = explicitKey ? `? ${str}\n${indent}:` : `${str}:`;    if (this.comment) {      // expected (but not strictly required) to be a single-line comment      str = addComment(str, ctx.indent, this.comment);      if (onComment) onComment();    }    let vcb = '';    let valueComment = null;    if (value instanceof Node) {      if (value.spaceBefore) vcb = '\n';      if (value.commentBefore) {        const cs = value.commentBefore.replace(/^/gm, `${ctx.indent}#`);        vcb += `\n${cs}`;      }      valueComment = value.comment;    } else if (value && typeof value === 'object') {      value = doc.schema.createNode(value, true);    }    ctx.implicitKey = false;    if (!explicitKey && !this.comment && value instanceof Scalar) ctx.indentAtStart = str.length + 1;    chompKeep = false;    if (!indentSeq && indentSize >= 2 && !ctx.inFlow && !explicitKey && value instanceof YAMLSeq && value.type !== PlainValue.Type.FLOW_SEQ && !value.tag && !doc.anchors.getName(value)) {      // If indentSeq === false, consider '- ' as part of indentation where possible      ctx.indent = ctx.indent.substr(2);    }    const valueStr = stringify(value, ctx, () => valueComment = null, () => chompKeep = true);    let ws = ' ';    if (vcb || this.comment) {      ws = `${vcb}\n${ctx.indent}`;    } else if (!explicitKey && value instanceof Collection) {      const flow = valueStr[0] === '[' || valueStr[0] === '{';      if (!flow || valueStr.includes('\n')) ws = `\n${ctx.indent}`;    } else if (valueStr[0] === '\n') ws = '';    if (chompKeep && !valueComment && onChompKeep) onChompKeep();    return addComment(str + ws + valueStr, ctx.indent, valueComment);  }}PlainValue._defineProperty(Pair, "Type", {  PAIR: 'PAIR',  MERGE_PAIR: 'MERGE_PAIR'});const getAliasCount = (node, anchors) => {  if (node instanceof Alias) {    const anchor = anchors.get(node.source);    return anchor.count * anchor.aliasCount;  } else if (node instanceof Collection) {    let count = 0;    for (const item of node.items) {      const c = getAliasCount(item, anchors);      if (c > count) count = c;    }    return count;  } else if (node instanceof Pair) {    const kc = getAliasCount(node.key, anchors);    const vc = getAliasCount(node.value, anchors);    return Math.max(kc, vc);  }  return 1;};class Alias extends Node {  static stringify({    range,    source  }, {    anchors,    doc,    implicitKey,    inStringifyKey  }) {    let anchor = Object.keys(anchors).find(a => anchors[a] === source);    if (!anchor && inStringifyKey) anchor = doc.anchors.getName(source) || doc.anchors.newName();    if (anchor) return `*${anchor}${implicitKey ? ' ' : ''}`;    const msg = doc.anchors.getName(source) ? 'Alias node must be after source node' : 'Source node not found for alias node';    throw new Error(`${msg} [${range}]`);  }  constructor(source) {    super();    this.source = source;    this.type = PlainValue.Type.ALIAS;  }  set tag(t) {    throw new Error('Alias nodes cannot have tags');  }  toJSON(arg, ctx) {    if (!ctx) return toJSON(this.source, arg, ctx);    const {      anchors,      maxAliasCount    } = ctx;    const anchor = anchors.get(this.source);    /* istanbul ignore if */    if (!anchor || anchor.res === undefined) {      const msg = 'This should not happen: Alias anchor was not resolved?';      if (this.cstNode) throw new PlainValue.YAMLReferenceError(this.cstNode, msg);else throw new ReferenceError(msg);    }    if (maxAliasCount >= 0) {      anchor.count += 1;      if (anchor.aliasCount === 0) anchor.aliasCount = getAliasCount(this.source, anchors);      if (anchor.count * anchor.aliasCount > maxAliasCount) {        const msg = 'Excessive alias count indicates a resource exhaustion attack';        if (this.cstNode) throw new PlainValue.YAMLReferenceError(this.cstNode, msg);else throw new ReferenceError(msg);      }    }    return anchor.res;  } // Only called when stringifying an alias mapping key while constructing  // Object output.  toString(ctx) {    return Alias.stringify(this, ctx);  }}PlainValue._defineProperty(Alias, "default", true);function findPair(items, key) {  const k = key instanceof Scalar ? key.value : key;  for (const it of items) {    if (it instanceof Pair) {      if (it.key === key || it.key === k) return it;      if (it.key && it.key.value === k) return it;    }  }  return undefined;}class YAMLMap extends Collection {  add(pair, overwrite) {    if (!pair) pair = new Pair(pair);else if (!(pair instanceof Pair)) pair = new Pair(pair.key || pair, pair.value);    const prev = findPair(this.items, pair.key);    const sortEntries = this.schema && this.schema.sortMapEntries;    if (prev) {      if (overwrite) prev.value = pair.value;else throw new Error(`Key ${pair.key} already set`);    } else if (sortEntries) {      const i = this.items.findIndex(item => sortEntries(pair, item) < 0);      if (i === -1) this.items.push(pair);else this.items.splice(i, 0, pair);    } else {      this.items.push(pair);    }  }  delete(key) {    const it = findPair(this.items, key);    if (!it) return false;    const del = this.items.splice(this.items.indexOf(it), 1);    return del.length > 0;  }  get(key, keepScalar) {    const it = findPair(this.items, key);    const node = it && it.value;    return !keepScalar && node instanceof Scalar ? node.value : node;  }  has(key) {    return !!findPair(this.items, key);  }  set(key, value) {    this.add(new Pair(key, value), true);  }  /**   * @param {*} arg ignored   * @param {*} ctx Conversion context, originally set in Document#toJSON()   * @param {Class} Type If set, forces the returned collection type   * @returns {*} Instance of Type, Map, or Object   */  toJSON(_, ctx, Type) {    const map = Type ? new Type() : ctx && ctx.mapAsMap ? new Map() : {};    if (ctx && ctx.onCreate) ctx.onCreate(map);    for (const item of this.items) item.addToJSMap(ctx, map);    return map;  }  toString(ctx, onComment, onChompKeep) {    if (!ctx) return JSON.stringify(this);    for (const item of this.items) {      if (!(item instanceof Pair)) throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);    }    return super.toString(ctx, {      blockItem: n => n.str,      flowChars: {        start: '{',        end: '}'      },      isMap: true,      itemIndent: ctx.indent || ''    }, onComment, onChompKeep);  }}const MERGE_KEY = '<<';class Merge extends Pair {  constructor(pair) {    if (pair instanceof Pair) {      let seq = pair.value;      if (!(seq instanceof YAMLSeq)) {        seq = new YAMLSeq();        seq.items.push(pair.value);        seq.range = pair.value.range;      }      super(pair.key, seq);      this.range = pair.range;    } else {      super(new Scalar(MERGE_KEY), new YAMLSeq());    }    this.type = Pair.Type.MERGE_PAIR;  } // If the value associated with a merge key is a single mapping node, each of  // its key/value pairs is inserted into the current mapping, unless the key  // already exists in it. If the value associated with the merge key is a  // sequence, then this sequence is expected to contain mapping nodes and each  // of these nodes is merged in turn according to its order in the sequence.  // Keys in mapping nodes earlier in the sequence override keys specified in  // later mapping nodes. -- http://yaml.org/type/merge.html  addToJSMap(ctx, map) {    for (const {      source    } of this.value.items) {      if (!(source instanceof YAMLMap)) throw new Error('Merge sources must be maps');      const srcMap = source.toJSON(null, ctx, Map);      for (const [key, value] of srcMap) {        if (map instanceof Map) {          if (!map.has(key)) map.set(key, value);        } else if (map instanceof Set) {          map.add(key);        } else if (!Object.prototype.hasOwnProperty.call(map, key)) {          Object.defineProperty(map, key, {            value,            writable: true,            enumerable: true,            configurable: true          });        }      }    }    return map;  }  toString(ctx, onComment) {    const seq = this.value;    if (seq.items.length > 1) return super.toString(ctx, onComment);    this.value = seq.items[0];    const str = super.toString(ctx, onComment);    this.value = seq;    return str;  }}const binaryOptions = {  defaultType: PlainValue.Type.BLOCK_LITERAL,  lineWidth: 76};const boolOptions = {  trueStr: 'true',  falseStr: 'false'};const intOptions = {  asBigInt: false};const nullOptions = {  nullStr: 'null'};const strOptions = {  defaultType: PlainValue.Type.PLAIN,  doubleQuoted: {    jsonEncoding: false,    minMultiLineLength: 40  },  fold: {    lineWidth: 80,    minContentWidth: 20  }};function resolveScalar(str, tags, scalarFallback) {  for (const {    format,    test,    resolve  } of tags) {    if (test) {      const match = str.match(test);      if (match) {        let res = resolve.apply(null, match);        if (!(res instanceof Scalar)) res = new Scalar(res);        if (format) res.format = format;        return res;      }    }  }  if (scalarFallback) str = scalarFallback(str);  return new Scalar(str);}const FOLD_FLOW = 'flow';const FOLD_BLOCK = 'block';const FOLD_QUOTED = 'quoted'; // presumes i+1 is at the start of a line// returns index of last newline in more-indented blockconst consumeMoreIndentedLines = (text, i) => {  let ch = text[i + 1];  while (ch === ' ' || ch === '\t') {    do {      ch = text[i += 1];    } while (ch && ch !== '\n');    ch = text[i + 1];  }  return i;};/** * Tries to keep input at up to `lineWidth` characters, splitting only on spaces * not followed by newlines or spaces unless `mode` is `'quoted'`. Lines are * terminated with `\n` and started with `indent`. * * @param {string} text * @param {string} indent * @param {string} [mode='flow'] `'block'` prevents more-indented lines *   from being folded; `'quoted'` allows for `\` escapes, including escaped *   newlines * @param {Object} options * @param {number} [options.indentAtStart] Accounts for leading contents on *   the first line, defaulting to `indent.length` * @param {number} [options.lineWidth=80] * @param {number} [options.minContentWidth=20] Allow highly indented lines to *   stretch the line width or indent content from the start * @param {function} options.onFold Called once if the text is folded * @param {function} options.onFold Called once if any line of text exceeds *   lineWidth characters */function foldFlowLines(text, indent, mode, {  indentAtStart,  lineWidth = 80,  minContentWidth = 20,  onFold,  onOverflow}) {  if (!lineWidth || lineWidth < 0) return text;  const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);  if (text.length <= endStep) return text;  const folds = [];  const escapedFolds = {};  let end = lineWidth - indent.length;  if (typeof indentAtStart === 'number') {    if (indentAtStart > lineWidth - Math.max(2, minContentWidth)) folds.push(0);else end = lineWidth - indentAtStart;  }  let split = undefined;  let prev = undefined;  let overflow = false;  let i = -1;  let escStart = -1;  let escEnd = -1;  if (mode === FOLD_BLOCK) {    i = consumeMoreIndentedLines(text, i);    if (i !== -1) end = i + endStep;  }  for (let ch; ch = text[i += 1];) {    if (mode === FOLD_QUOTED && ch === '\\') {      escStart = i;      switch (text[i + 1]) {        case 'x':          i += 3;          break;        case 'u':          i += 5;          break;        case 'U':          i += 9;          break;        default:          i += 1;      }      escEnd = i;    }    if (ch === '\n') {      if (mode === FOLD_BLOCK) i = consumeMoreIndentedLines(text, i);      end = i + endStep;      split = undefined;    } else {      if (ch === ' ' && prev && prev !== ' ' && prev !== '\n' && prev !== '\t') {        // space surrounded by non-space can be replaced with newline + indent        const next = text[i + 1];        if (next && next !== ' ' && next !== '\n' && next !== '\t') split = i;      }      if (i >= end) {        if (split) {          folds.push(split);          end = split + endStep;          split = undefined;        } else if (mode === FOLD_QUOTED) {          // white-space collected at end may stretch past lineWidth          while (prev === ' ' || prev === '\t') {            prev = ch;            ch = text[i += 1];            overflow = true;          } // Account for newline escape, but don't break preceding escape          const j = i > escEnd + 1 ? i - 2 : escStart - 1; // Bail out if lineWidth & minContentWidth are shorter than an escape string          if (escapedFolds[j]) return text;          folds.push(j);          escapedFolds[j] = true;          end = j + endStep;          split = undefined;        } else {          overflow = true;        }      }    }    prev = ch;  }  if (overflow && onOverflow) onOverflow();  if (folds.length === 0) return text;  if (onFold) onFold();  let res = text.slice(0, folds[0]);  for (let i = 0; i < folds.length; ++i) {    const fold = folds[i];    const end = folds[i + 1] || text.length;    if (fold === 0) res = `\n${indent}${text.slice(0, end)}`;else {      if (mode === FOLD_QUOTED && escapedFolds[fold]) res += `${text[fold]}\\`;      res += `\n${indent}${text.slice(fold + 1, end)}`;    }  }  return res;}const getFoldOptions = ({  indentAtStart}) => indentAtStart ? Object.assign({  indentAtStart}, strOptions.fold) : strOptions.fold; // Also checks for lines starting with %, as parsing the output as YAML 1.1 will// presume that's starting a new document.const containsDocumentMarker = str => /^(%|---|\.\.\.)/m.test(str);function lineLengthOverLimit(str, lineWidth, indentLength) {  if (!lineWidth || lineWidth < 0) return false;  const limit = lineWidth - indentLength;  const strLen = str.length;  if (strLen <= limit) return false;  for (let i = 0, start = 0; i < strLen; ++i) {    if (str[i] === '\n') {      if (i - start > limit) return true;      start = i + 1;      if (strLen - start <= limit) return false;    }  }  return true;}function doubleQuotedString(value, ctx) {  const {    implicitKey  } = ctx;  const {    jsonEncoding,    minMultiLineLength  } = strOptions.doubleQuoted;  const json = JSON.stringify(value);  if (jsonEncoding) return json;  const indent = ctx.indent || (containsDocumentMarker(value) ? '  ' : '');  let str = '';  let start = 0;  for (let i = 0, ch = json[i]; ch; ch = json[++i]) {    if (ch === ' ' && json[i + 1] === '\\' && json[i + 2] === 'n') {      // space before newline needs to be escaped to not be folded      str += json.slice(start, i) + '\\ ';      i += 1;      start = i;      ch = '\\';    }    if (ch === '\\') switch (json[i + 1]) {      case 'u':        {          str += json.slice(start, i);          const code = json.substr(i + 2, 4);          switch (code) {            case '0000':              str += '\\0';              break;            case '0007':              str += '\\a';              break;            case '000b':              str += '\\v';              break;            case '001b':              str += '\\e';              break;            case '0085':              str += '\\N';              break;            case '00a0':              str += '\\_';              break;            case '2028':              str += '\\L';              break;            case '2029':              str += '\\P';              break;            default:              if (code.substr(0, 2) === '00') str += '\\x' + code.substr(2);else str += json.substr(i, 6);          }          i += 5;          start = i + 1;        }        break;      case 'n':        if (implicitKey || json[i + 2] === '"' || json.length < minMultiLineLength) {          i += 1;        } else {          // folding will eat first newline          str += json.slice(start, i) + '\n\n';          while (json[i + 2] === '\\' && json[i + 3] === 'n' && json[i + 4] !== '"') {            str += '\n';            i += 2;          }          str += indent; // space after newline needs to be escaped to not be folded          if (json[i + 2] === ' ') str += '\\';          i += 1;          start = i + 1;        }        break;      default:        i += 1;    }  }  str = start ? str + json.slice(start) : json;  return implicitKey ? str : foldFlowLines(str, indent, FOLD_QUOTED, getFoldOptions(ctx));}function singleQuotedString(value, ctx) {  if (ctx.implicitKey) {    if (/\n/.test(value)) return doubleQuotedString(value, ctx);  } else {    // single quoted string can't have leading or trailing whitespace around newline    if (/[ \t]\n|\n[ \t]/.test(value)) return doubleQuotedString(value, ctx);  }  const indent = ctx.indent || (containsDocumentMarker(value) ? '  ' : '');  const res = "'" + value.replace(/'/g, "''").replace(/\n+/g, `$&\n${indent}`) + "'";  return ctx.implicitKey ? res : foldFlowLines(res, indent, FOLD_FLOW, getFoldOptions(ctx));}function blockString({  comment,  type,  value}, ctx, onComment, onChompKeep) {  // 1. Block can't end in whitespace unless the last line is non-empty.  // 2. Strings consisting of only whitespace are best rendered explicitly.  if (/\n[\t ]+$/.test(value) || /^\s*$/.test(value)) {    return doubleQuotedString(value, ctx);  }  const indent = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? '  ' : '');  const indentSize = indent ? '2' : '1'; // root is at -1  const literal = type === PlainValue.Type.BLOCK_FOLDED ? false : type === PlainValue.Type.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, strOptions.fold.lineWidth, indent.length);  let header = literal ? '|' : '>';  if (!value) return header + '\n';  let wsStart = '';  let wsEnd = '';  value = value.replace(/[\n\t ]*$/, ws => {    const n = ws.indexOf('\n');    if (n === -1) {      header += '-'; // strip    } else if (value === ws || n !== ws.length - 1) {      header += '+'; // keep      if (onChompKeep) onChompKeep();    }    wsEnd = ws.replace(/\n$/, '');    return '';  }).replace(/^[\n ]*/, ws => {    if (ws.indexOf(' ') !== -1) header += indentSize;    const m = ws.match(/ +$/);    if (m) {      wsStart = ws.slice(0, -m[0].length);      return m[0];    } else {      wsStart = ws;      return '';    }  });  if (wsEnd) wsEnd = wsEnd.replace(/\n+(?!\n|$)/g, `$&${indent}`);  if (wsStart) wsStart = wsStart.replace(/\n+/g, `$&${indent}`);  if (comment) {    header += ' #' + comment.replace(/ ?[\r\n]+/g, ' ');    if (onComment) onComment();  }  if (!value) return `${header}${indentSize}\n${indent}${wsEnd}`;  if (literal) {    value = value.replace(/\n+/g, `$&${indent}`);    return `${header}\n${indent}${wsStart}${value}${wsEnd}`;  }  value = value.replace(/\n+/g, '\n$&').replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded  //         ^ ind.line  ^ empty     ^ capture next empty lines only at end of indent  .replace(/\n+/g, `$&${indent}`);  const body = foldFlowLines(`${wsStart}${value}${wsEnd}`, indent, FOLD_BLOCK, strOptions.fold);  return `${header}\n${indent}${body}`;}function plainString(item, ctx, onComment, onChompKeep) {  const {    comment,    type,    value  } = item;  const {    actualString,    implicitKey,    indent,    inFlow  } = ctx;  if (implicitKey && /[\n[\]{},]/.test(value) || inFlow && /[[\]{},]/.test(value)) {    return doubleQuotedString(value, ctx);  }  if (!value || /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {    // not allowed:    // - empty string, '-' or '?'    // - start with an indicator character (except [?:-]) or /[?-] /    // - '\n ', ': ' or ' \n' anywhere    // - '#' not preceded by a non-space char    // - end with ' ' or ':'    return implicitKey || inFlow || value.indexOf('\n') === -1 ? value.indexOf('"') !== -1 && value.indexOf("'") === -1 ? singleQuotedString(value, ctx) : doubleQuotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep);  }  if (!implicitKey && !inFlow && type !== PlainValue.Type.PLAIN && value.indexOf('\n') !== -1) {    // Where allowed & type not set explicitly, prefer block style for multiline strings    return blockString(item, ctx, onComment, onChompKeep);  }  if (indent === '' && containsDocumentMarker(value)) {    ctx.forceBlockIndent = true;    return blockString(item, ctx, onComment, onChompKeep);  }  const str = value.replace(/\n+/g, `$&\n${indent}`); // Verify that output will be parsed as a string, as e.g. plain numbers and  // booleans get parsed with those types in v1.2 (e.g. '42', 'true' & '0.9e-3'),  // and others in v1.1.  if (actualString) {    const {      tags    } = ctx.doc.schema;    const resolved = resolveScalar(str, tags, tags.scalarFallback).value;    if (typeof resolved !== 'string') return doubleQuotedString(value, ctx);  }  const body = implicitKey ? str : foldFlowLines(str, indent, FOLD_FLOW, getFoldOptions(ctx));  if (comment && !inFlow && (body.indexOf('\n') !== -1 || comment.indexOf('\n') !== -1)) {    if (onComment) onComment();    return addCommentBefore(body, indent, comment);  }  return body;}function stringifyString(item, ctx, onComment, onChompKeep) {  const {    defaultType  } = strOptions;  const {    implicitKey,    inFlow  } = ctx;  let {    type,    value  } = item;  if (typeof value !== 'string') {    value = String(value);    item = Object.assign({}, item, {      value    });  }  const _stringify = _type => {    switch (_type) {      case PlainValue.Type.BLOCK_FOLDED:      case PlainValue.Type.BLOCK_LITERAL:        return blockString(item, ctx, onComment, onChompKeep);      case PlainValue.Type.QUOTE_DOUBLE:        return doubleQuotedString(value, ctx);      case PlainValue.Type.QUOTE_SINGLE:        return singleQuotedString(value, ctx);      case PlainValue.Type.PLAIN:        return plainString(item, ctx, onComment, onChompKeep);      default:        return null;    }  };  if (type !== PlainValue.Type.QUOTE_DOUBLE && /[\x00-\x08\x0b-\x1f\x7f-\x9f]/.test(value)) {    // force double quotes on control characters    type = PlainValue.Type.QUOTE_DOUBLE;  } else if ((implicitKey || inFlow) && (type === PlainValue.Type.BLOCK_FOLDED || type === PlainValue.Type.BLOCK_LITERAL)) {    // should not happen; blocks are not valid inside flow containers    type = PlainValue.Type.QUOTE_DOUBLE;  }  let res = _stringify(type);  if (res === null) {    res = _stringify(defaultType);    if (res === null) throw new Error(`Unsupported default string type ${defaultType}`);  }  return res;}function stringifyNumber({  format,  minFractionDigits,  tag,  value}) {  if (typeof value === 'bigint') return String(value);  if (!isFinite(value)) return isNaN(value) ? '.nan' : value < 0 ? '-.inf' : '.inf';  let n = JSON.stringify(value);  if (!format && minFractionDigits && (!tag || tag === 'tag:yaml.org,2002:float') && /^\d/.test(n)) {    let i = n.indexOf('.');    if (i < 0) {      i = n.length;      n += '.';    }    let d = minFractionDigits - (n.length - i - 1);    while (d-- > 0) n += '0';  }  return n;}function checkFlowCollectionEnd(errors, cst) {  let char, name;  switch (cst.type) {    case PlainValue.Type.FLOW_MAP:      char = '}';      name = 'flow map';      break;    case PlainValue.Type.FLOW_SEQ:      char = ']';      name = 'flow sequence';      break;    default:      errors.push(new PlainValue.YAMLSemanticError(cst, 'Not a flow collection!?'));      return;  }  let lastItem;  for (let i = cst.items.length - 1; i >= 0; --i) {    const item = cst.items[i];    if (!item || item.type !== PlainValue.Type.COMMENT) {      lastItem = item;      break;    }  }  if (lastItem && lastItem.char !== char) {    const msg = `Expected ${name} to end with ${char}`;    let err;    if (typeof lastItem.offset === 'number') {      err = new PlainValue.YAMLSemanticError(cst, msg);      err.offset = lastItem.offset + 1;    } else {      err = new PlainValue.YAMLSemanticError(lastItem, msg);      if (lastItem.range && lastItem.range.end) err.offset = lastItem.range.end - lastItem.range.start;    }    errors.push(err);  }}function checkFlowCommentSpace(errors, comment) {  const prev = comment.context.src[comment.range.start - 1];  if (prev !== '\n' && prev !== '\t' && prev !== ' ') {    const msg = 'Comments must be separated from other tokens by white space characters';    errors.push(new PlainValue.YAMLSemanticError(comment, msg));  }}function getLongKeyError(source, key) {  const sk = String(key);  const k = sk.substr(0, 8) + '...' + sk.substr(-8);  return new PlainValue.YAMLSemanticError(source, `The "${k}" key is too long`);}function resolveComments(collection, comments) {  for (const {    afterKey,    before,    comment  } of comments) {    let item = collection.items[before];    if (!item) {      if (comment !== undefined) {        if (collection.comment) collection.comment += '\n' + comment;else collection.comment = comment;      }    } else {      if (afterKey && item.value) item = item.value;      if (comment === undefined) {        if (afterKey || !item.commentBefore) item.spaceBefore = true;      } else {        if (item.commentBefore) item.commentBefore += '\n' + comment;else item.commentBefore = comment;      }    }  }}// on error, will return { str: string, errors: Error[] }function resolveString(doc, node) {  const res = node.strValue;  if (!res) return '';  if (typeof res === 'string') return res;  res.errors.forEach(error => {    if (!error.source) error.source = node;    doc.errors.push(error);  });  return res.str;}function resolveTagHandle(doc, node) {  const {    handle,    suffix  } = node.tag;  let prefix = doc.tagPrefixes.find(p => p.handle === handle);  if (!prefix) {    const dtp = doc.getDefaults().tagPrefixes;    if (dtp) prefix = dtp.find(p => p.handle === handle);    if (!prefix) throw new PlainValue.YAMLSemanticError(node, `The ${handle} tag handle is non-default and was not declared.`);  }  if (!suffix) throw new PlainValue.YAMLSemanticError(node, `The ${handle} tag has no suffix.`);  if (handle === '!' && (doc.version || doc.options.version) === '1.0') {    if (suffix[0] === '^') {      doc.warnings.push(new PlainValue.YAMLWarning(node, 'YAML 1.0 ^ tag expansion is not supported'));      return suffix;    }    if (/[:/]/.test(suffix)) {      // word/foo -> tag:word.yaml.org,2002:foo      const vocab = suffix.match(/^([a-z0-9-]+)\/(.*)/i);      return vocab ? `tag:${vocab[1]}.yaml.org,2002:${vocab[2]}` : `tag:${suffix}`;    }  }  return prefix.prefix + decodeURIComponent(suffix);}function resolveTagName(doc, node) {  const {    tag,    type  } = node;  let nonSpecific = false;  if (tag) {    const {      handle,      suffix,      verbatim    } = tag;    if (verbatim) {      if (verbatim !== '!' && verbatim !== '!!') return verbatim;      const msg = `Verbatim tags aren't resolved, so ${verbatim} is invalid.`;      doc.errors.push(new PlainValue.YAMLSemanticError(node, msg));    } else if (handle === '!' && !suffix) {      nonSpecific = true;    } else {      try {        return resolveTagHandle(doc, node);      } catch (error) {        doc.errors.push(error);      }    }  }  switch (type) {    case PlainValue.Type.BLOCK_FOLDED:    case PlainValue.Type.BLOCK_LITERAL:    case PlainValue.Type.QUOTE_DOUBLE:    case PlainValue.Type.QUOTE_SINGLE:      return PlainValue.defaultTags.STR;    case PlainValue.Type.FLOW_MAP:    case PlainValue.Type.MAP:      return PlainValue.defaultTags.MAP;    case PlainValue.Type.FLOW_SEQ:    case PlainValue.Type.SEQ:      return PlainValue.defaultTags.SEQ;    case PlainValue.Type.PLAIN:      return nonSpecific ? PlainValue.defaultTags.STR : null;    default:      return null;  }}function resolveByTagName(doc, node, tagName) {  const {    tags  } = doc.schema;  const matchWithTest = [];  for (const tag of tags) {    if (tag.tag === tagName) {      if (tag.test) matchWithTest.push(tag);else {        const res = tag.resolve(doc, node);        return res instanceof Collection ? res : new Scalar(res);      }    }  }  const str = resolveString(doc, node);  if (typeof str === 'string' && matchWithTest.length > 0) return resolveScalar(str, matchWithTest, tags.scalarFallback);  return null;}function getFallbackTagName({  type}) {  switch (type) {    case PlainValue.Type.FLOW_MAP:    case PlainValue.Type.MAP:      return PlainValue.defaultTags.MAP;    case PlainValue.Type.FLOW_SEQ:    case PlainValue.Type.SEQ:      return PlainValue.defaultTags.SEQ;    default:      return PlainValue.defaultTags.STR;  }}function resolveTag(doc, node, tagName) {  try {    const res = resolveByTagName(doc, node, tagName);    if (res) {      if (tagName && node.tag) res.tag = tagName;      return res;    }  } catch (error) {    /* istanbul ignore if */    if (!error.source) error.source = node;    doc.errors.push(error);    return null;  }  try {    const fallback = getFallbackTagName(node);    if (!fallback) throw new Error(`The tag ${tagName} is unavailable`);    const msg = `The tag ${tagName} is unavailable, falling back to ${fallback}`;    doc.warnings.push(new PlainValue.YAMLWarning(node, msg));    const res = resolveByTagName(doc, node, fallback);    res.tag = tagName;    return res;  } catch (error) {    const refError = new PlainValue.YAMLReferenceError(node, error.message);    refError.stack = error.stack;    doc.errors.push(refError);    return null;  }}const isCollectionItem = node => {  if (!node) return false;  const {    type  } = node;  return type === PlainValue.Type.MAP_KEY || type === PlainValue.Type.MAP_VALUE || type === PlainValue.Type.SEQ_ITEM;};function resolveNodeProps(errors, node) {  const comments = {    before: [],    after: []  };  let hasAnchor = false;  let hasTag = false;  const props = isCollectionItem(node.context.parent) ? node.context.parent.props.concat(node.props) : node.props;  for (const {    start,    end  } of props) {    switch (node.context.src[start]) {      case PlainValue.Char.COMMENT:        {          if (!node.commentHasRequiredWhitespace(start)) {            const msg = 'Comments must be separated from other tokens by white space characters';            errors.push(new PlainValue.YAMLSemanticError(node, msg));          }          const {            header,            valueRange          } = node;          const cc = valueRange && (start > valueRange.start || header && start > header.start) ? comments.after : comments.before;          cc.push(node.context.src.slice(start + 1, end));          break;        }      // Actual anchor & tag resolution is handled by schema, here we just complain      case PlainValue.Char.ANCHOR:        if (hasAnchor) {          const msg = 'A node can have at most one anchor';          errors.push(new PlainValue.YAMLSemanticError(node, msg));        }        hasAnchor = true;        break;      case PlainValue.Char.TAG:        if (hasTag) {          const msg = 'A node can have at most one tag';          errors.push(new PlainValue.YAMLSemanticError(node, msg));        }        hasTag = true;        break;    }  }  return {    comments,    hasAnchor,    hasTag  };}function resolveNodeValue(doc, node) {  const {    anchors,    errors,    schema  } = doc;  if (node.type === PlainValue.Type.ALIAS) {    const name = node.rawValue;    const src = anchors.getNode(name);    if (!src) {      const msg = `Aliased anchor not found: ${name}`;      errors.push(new PlainValue.YAMLReferenceError(node, msg));      return null;    } // Lazy resolution for circular references    const res = new Alias(src);    anchors._cstAliases.push(res);    return res;  }  const tagName = resolveTagName(doc, node);  if (tagName) return resolveTag(doc, node, tagName);  if (node.type !== PlainValue.Type.PLAIN) {    const msg = `Failed to resolve ${node.type} node here`;    errors.push(new PlainValue.YAMLSyntaxError(node, msg));    return null;  }  try {    const str = resolveString(doc, node);    return resolveScalar(str, schema.tags, schema.tags.scalarFallback);  } catch (error) {    if (!error.source) error.source = node;    errors.push(error);    return null;  }} // sets node.resolved on successfunction resolveNode(doc, node) {  if (!node) return null;  if (node.error) doc.errors.push(node.error);  const {    comments,    hasAnchor,    hasTag  } = resolveNodeProps(doc.errors, node);  if (hasAnchor) {    const {      anchors    } = doc;    const name = node.anchor;    const prev = anchors.getNode(name); // At this point, aliases for any preceding node with the same anchor    // name have already been resolved, so it may safely be renamed.    if (prev) anchors.map[anchors.newName(name)] = prev; // During parsing, we need to store the CST node in anchors.map as    // anchors need to be available during resolution to allow for    // circular references.    anchors.map[name] = node;  }  if (node.type === PlainValue.Type.ALIAS && (hasAnchor || hasTag)) {    const msg = 'An alias node must not specify any properties';    doc.errors.push(new PlainValue.YAMLSemanticError(node, msg));  }  const res = resolveNodeValue(doc, node);  if (res) {    res.range = [node.range.start, node.range.end];    if (doc.options.keepCstNodes) res.cstNode = node;    if (doc.options.keepNodeTypes) res.type = node.type;    const cb = comments.before.join('\n');    if (cb) {      res.commentBefore = res.commentBefore ? `${res.commentBefore}\n${cb}` : cb;    }    const ca = comments.after.join('\n');    if (ca) res.comment = res.comment ? `${res.comment}\n${ca}` : ca;  }  return node.resolved = res;}function resolveMap(doc, cst) {  if (cst.type !== PlainValue.Type.MAP && cst.type !== PlainValue.Type.FLOW_MAP) {    const msg = `A ${cst.type} node cannot be resolved as a mapping`;    doc.errors.push(new PlainValue.YAMLSyntaxError(cst, msg));    return null;  }  const {    comments,    items  } = cst.type === PlainValue.Type.FLOW_MAP ? resolveFlowMapItems(doc, cst) : resolveBlockMapItems(doc, cst);  const map = new YAMLMap();  map.items = items;  resolveComments(map, comments);  let hasCollectionKey = false;  for (let i = 0; i < items.length; ++i) {    const {      key: iKey    } = items[i];    if (iKey instanceof Collection) hasCollectionKey = true;    if (doc.schema.merge && iKey && iKey.value === MERGE_KEY) {      items[i] = new Merge(items[i]);      const sources = items[i].value.items;      let error = null;      sources.some(node => {        if (node instanceof Alias) {          // During parsing, alias sources are CST nodes; to account for          // circular references their resolved values can't be used here.          const {            type          } = node.source;          if (type === PlainValue.Type.MAP || type === PlainValue.Type.FLOW_MAP) return false;          return error = 'Merge nodes aliases can only point to maps';        }        return error = 'Merge nodes can only have Alias nodes as values';      });      if (error) doc.errors.push(new PlainValue.YAMLSemanticError(cst, error));    } else {      for (let j = i + 1; j < items.length; ++j) {        const {          key: jKey        } = items[j];        if (iKey === jKey || iKey && jKey && Object.prototype.hasOwnProperty.call(iKey, 'value') && iKey.value === jKey.value) {          const msg = `Map keys must be unique; "${iKey}" is repeated`;          doc.errors.push(new PlainValue.YAMLSemanticError(cst, msg));          break;        }      }    }  }  if (hasCollectionKey && !doc.options.mapAsMap) {    const warn = 'Keys with collection values will be stringified as YAML due to JS Object restrictions. Use mapAsMap: true to avoid this.';    doc.warnings.push(new PlainValue.YAMLWarning(cst, warn));  }  cst.resolved = map;  return map;}const valueHasPairComment = ({  context: {    lineStart,    node,    src  },  props}) => {  if (props.length === 0) return false;  const {    start  } = props[0];  if (node && start > node.valueRange.start) return false;  if (src[start] !== PlainValue.Char.COMMENT) return false;  for (let i = lineStart; i < start; ++i) if (src[i] === '\n') return false;  return true;};function resolvePairComment(item, pair) {  if (!valueHasPairComment(item)) return;  const comment = item.getPropValue(0, PlainValue.Char.COMMENT, true);  let found = false;  const cb = pair.value.commentBefore;  if (cb && cb.startsWith(comment)) {    pair.value.commentBefore = cb.substr(comment.length + 1);    found = true;  } else {    const cc = pair.value.comment;    if (!item.node && cc && cc.startsWith(comment)) {      pair.value.comment = cc.substr(comment.length + 1);      found = true;    }  }  if (found) pair.comment = comment;}function resolveBlockMapItems(doc, cst) {  const comments = [];  const items = [];  let key = undefined;  let keyStart = null;  for (let i = 0; i < cst.items.length; ++i) {    const item = cst.items[i];    switch (item.type) {      case PlainValue.Type.BLANK_LINE:        comments.push({          afterKey: !!key,          before: items.length        });        break;      case PlainValue.Type.COMMENT:        comments.push({          afterKey: !!key,          before: items.length,          comment: item.comment        });        break;      case PlainValue.Type.MAP_KEY:        if (key !== undefined) items.push(new Pair(key));        if (item.error) doc.errors.push(item.error);        key = resolveNode(doc, item.node);        keyStart = null;        break;      case PlainValue.Type.MAP_VALUE:        {          if (key === undefined) key = null;          if (item.error) doc.errors.push(item.error);          if (!item.context.atLineStart && item.node && item.node.type === PlainValue.Type.MAP && !item.node.context.atLineStart) {            const msg = 'Nested mappings are not allowed in compact mappings';            doc.errors.push(new PlainValue.YAMLSemanticError(item.node, msg));          }          let valueNode = item.node;          if (!valueNode && item.props.length > 0) {            // Comments on an empty mapping value need to be preserved, so we            // need to construct a minimal empty node here to use instead of the            // missing `item.node`. -- eemeli/yaml#19            valueNode = new PlainValue.PlainValue(PlainValue.Type.PLAIN, []);            valueNode.context = {              parent: item,              src: item.context.src            };            const pos = item.range.start + 1;            valueNode.range = {              start: pos,              end: pos            };            valueNode.valueRange = {              start: pos,              end: pos            };            if (typeof item.range.origStart === 'number') {              const origPos = item.range.origStart + 1;              valueNode.range.origStart = valueNode.range.origEnd = origPos;              valueNode.valueRange.origStart = valueNode.valueRange.origEnd = origPos;            }          }          const pair = new Pair(key, resolveNode(doc, valueNode));          resolvePairComment(item, pair);          items.push(pair);          if (key && typeof keyStart === 'number') {            if (item.range.start > keyStart + 1024) doc.errors.push(getLongKeyError(cst, key));          }          key = undefined;          keyStart = null;        }        break;      default:        if (key !== undefined) items.push(new Pair(key));        key = resolveNode(doc, item);        keyStart = item.range.start;        if (item.error) doc.errors.push(item.error);        next: for (let j = i + 1;; ++j) {          const nextItem = cst.items[j];          switch (nextItem && nextItem.type) {            case PlainValue.Type.BLANK_LINE:            case PlainValue.Type.COMMENT:              continue next;            case PlainValue.Type.MAP_VALUE:              break next;            default:              {                const msg = 'Implicit map keys need to be followed by map values';                doc.errors.push(new PlainValue.YAMLSemanticError(item, msg));                break next;              }          }        }        if (item.valueRangeContainsNewline) {          const msg = 'Implicit map keys need to be on a single line';          doc.errors.push(new PlainValue.YAMLSemanticError(item, msg));        }    }  }  if (key !== undefined) items.push(new Pair(key));  return {    comments,    items  };}function resolveFlowMapItems(doc, cst) {  const comments = [];  const items = [];  let key = undefined;  let explicitKey = false;  let next = '{';  for (let i = 0; i < cst.items.length; ++i) {    const item = cst.items[i];    if (typeof item.char === 'string') {      const {        char,        offset      } = item;      if (char === '?' && key === undefined && !explicitKey) {        explicitKey = true;        next = ':';        continue;      }      if (char === ':') {        if (key === undefined) key = null;        if (next === ':') {          next = ',';          continue;        }      } else {        if (explicitKey) {          if (key === undefined && char !== ',') key = null;          explicitKey = false;        }        if (key !== undefined) {          items.push(new Pair(key));          key = undefined;          if (char === ',') {            next = ':';            continue;          }        }      }      if (char === '}') {        if (i === cst.items.length - 1) continue;      } else if (char === next) {        next = ':';        continue;      }      const msg = `Flow map contains an unexpected ${char}`;      const err = new PlainValue.YAMLSyntaxError(cst, msg);      err.offset = offset;      doc.errors.push(err);    } else if (item.type === PlainValue.Type.BLANK_LINE) {      comments.push({        afterKey: !!key,        before: items.length      });    } else if (item.type === PlainValue.Type.COMMENT) {      checkFlowCommentSpace(doc.errors, item);      comments.push({        afterKey: !!key,        before: items.length,        comment: item.comment      });    } else if (key === undefined) {      if (next === ',') doc.errors.push(new PlainValue.YAMLSemanticError(item, 'Separator , missing in flow map'));      key = resolveNode(doc, item);    } else {      if (next !== ',') doc.errors.push(new PlainValue.YAMLSemanticError(item, 'Indicator : missing in flow map entry'));      items.push(new Pair(key, resolveNode(doc, item)));      key = undefined;      explicitKey = false;    }  }  checkFlowCollectionEnd(doc.errors, cst);  if (key !== undefined) items.push(new Pair(key));  return {    comments,    items  };}function resolveSeq(doc, cst) {  if (cst.type !== PlainValue.Type.SEQ && cst.type !== PlainValue.Type.FLOW_SEQ) {    const msg = `A ${cst.type} node cannot be resolved as a sequence`;    doc.errors.push(new PlainValue.YAMLSyntaxError(cst, msg));    return null;  }  const {    comments,    items  } = cst.type === PlainValue.Type.FLOW_SEQ ? resolveFlowSeqItems(doc, cst) : resolveBlockSeqItems(doc, cst);  const seq = new YAMLSeq();  seq.items = items;  resolveComments(seq, comments);  if (!doc.options.mapAsMap && items.some(it => it instanceof Pair && it.key instanceof Collection)) {    const warn = 'Keys with collection values will be stringified as YAML due to JS Object restrictions. Use mapAsMap: true to avoid this.';    doc.warnings.push(new PlainValue.YAMLWarning(cst, warn));  }  cst.resolved = seq;  return seq;}function resolveBlockSeqItems(doc, cst) {  const comments = [];  const items = [];  for (let i = 0; i < cst.items.length; ++i) {    const item = cst.items[i];    switch (item.type) {      case PlainValue.Type.BLANK_LINE:        comments.push({          before: items.length        });        break;      case PlainValue.Type.COMMENT:        comments.push({          comment: item.comment,          before: items.length        });        break;      case PlainValue.Type.SEQ_ITEM:        if (item.error) doc.errors.push(item.error);        items.push(resolveNode(doc, item.node));        if (item.hasProps) {          const msg = 'Sequence items cannot have tags or anchors before the - indicator';          doc.errors.push(new PlainValue.YAMLSemanticError(item, msg));        }        break;      default:        if (item.error) doc.errors.push(item.error);        doc.errors.push(new PlainValue.YAMLSyntaxError(item, `Unexpected ${item.type} node in sequence`));    }  }  return {    comments,    items  };}function resolveFlowSeqItems(doc, cst) {  const comments = [];  const items = [];  let explicitKey = false;  let key = undefined;  let keyStart = null;  let next = '[';  let prevItem = null;  for (let i = 0; i < cst.items.length; ++i) {    const item = cst.items[i];    if (typeof item.char === 'string') {      const {        char,        offset      } = item;      if (char !== ':' && (explicitKey || key !== undefined)) {        if (explicitKey && key === undefined) key = next ? items.pop() : null;        items.push(new Pair(key));        explicitKey = false;        key = undefined;        keyStart = null;      }      if (char === next) {        next = null;      } else if (!next && char === '?') {        explicitKey = true;      } else if (next !== '[' && char === ':' && key === undefined) {        if (next === ',') {          key = items.pop();          if (key instanceof Pair) {            const msg = 'Chaining flow sequence pairs is invalid';            const err = new PlainValue.YAMLSemanticError(cst, msg);            err.offset = offset;            doc.errors.push(err);          }          if (!explicitKey && typeof keyStart === 'number') {            const keyEnd = item.range ? item.range.start : item.offset;            if (keyEnd > keyStart + 1024) doc.errors.push(getLongKeyError(cst, key));            const {              src            } = prevItem.context;            for (let i = keyStart; i < keyEnd; ++i) if (src[i] === '\n') {              const msg = 'Implicit keys of flow sequence pairs need to be on a single line';              doc.errors.push(new PlainValue.YAMLSemanticError(prevItem, msg));              break;            }          }        } else {          key = null;        }        keyStart = null;        explicitKey = false;        next = null;      } else if (next === '[' || char !== ']' || i < cst.items.length - 1) {        const msg = `Flow sequence contains an unexpected ${char}`;        const err = new PlainValue.YAMLSyntaxError(cst, msg);        err.offset = offset;        doc.errors.push(err);      }    } else if (item.type === PlainValue.Type.BLANK_LINE) {      comments.push({        before: items.length      });    } else if (item.type === PlainValue.Type.COMMENT) {      checkFlowCommentSpace(doc.errors, item);      comments.push({        comment: item.comment,        before: items.length      });    } else {      if (next) {        const msg = `Expected a ${next} in flow sequence`;        doc.errors.push(new PlainValue.YAMLSemanticError(item, msg));      }      const value = resolveNode(doc, item);      if (key === undefined) {        items.push(value);        prevItem = item;      } else {        items.push(new Pair(key, value));        key = undefined;      }      keyStart = item.range.start;      next = ',';    }  }  checkFlowCollectionEnd(doc.errors, cst);  if (key !== undefined) items.push(new Pair(key));  return {    comments,    items  };}exports.Alias = Alias;exports.Collection = Collection;exports.Merge = Merge;exports.Node = Node;exports.Pair = Pair;exports.Scalar = Scalar;exports.YAMLMap = YAMLMap;exports.YAMLSeq = YAMLSeq;exports.addComment = addComment;exports.binaryOptions = binaryOptions;exports.boolOptions = boolOptions;exports.findPair = findPair;exports.intOptions = intOptions;exports.isEmptyPath = isEmptyPath;exports.nullOptions = nullOptions;exports.resolveMap = resolveMap;exports.resolveNode = resolveNode;exports.resolveSeq = resolveSeq;exports.resolveString = resolveString;exports.strOptions = strOptions;exports.stringifyNumber = stringifyNumber;exports.stringifyString = stringifyString;exports.toJSON = toJSON;
 |