UNPKG

easy-keyvalues

Version:

Parse Valve KeyValues Format and easy to use in nodejs or browser.

1,269 lines (1,254 loc) 104 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.web = global.web || {}, global.web.js = {}))); })(this, (function (exports) { 'use strict'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var defaultAdapter = { readFile: function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, '']; }); }); }, writeFile: function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/]; }); }); }, resolvePath: function (filename, basePath) { return filename + basePath; }, createKeyValuesID: function () { return ''; }, }; function setKeyValuesAdapter(adapter) { defaultAdapter = adapter; } function getKeyValuesAdapter() { return defaultAdapter; } var KeyValuesComments = /** @class */ (function () { function KeyValuesComments(comments, endOfLineComment) { if (comments === void 0) { comments = []; } if (endOfLineComment === void 0) { endOfLineComment = ''; } this.comments = comments; this.endOfLineComment = endOfLineComment; } KeyValuesComments.prototype.GetComments = function () { return this.comments; }; KeyValuesComments.prototype.HasComments = function () { return this.comments.length > 0; }; KeyValuesComments.prototype.SetComments = function (list) { var e_1, _a; try { for (var list_1 = __values(list), list_1_1 = list_1.next(); !list_1_1.done; list_1_1 = list_1.next()) { var v = list_1_1.value; if (v.includes('\n')) { throw Error('The comment only allowed one line'); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (list_1_1 && !list_1_1.done && (_a = list_1.return)) _a.call(list_1); } finally { if (e_1) throw e_1.error; } } this.comments = list; return this; }; KeyValuesComments.prototype.AppendComment = function (text) { if (text.includes('\n')) { throw Error('The comment only allowed one line'); } this.comments.push(text); return this; }; KeyValuesComments.prototype.SetEndOfLineComment = function (text) { if (text.includes('\n')) { throw Error('The comment only allowed one line'); } this.endOfLineComment = text; return this; }; KeyValuesComments.prototype.GetEndOfLineComment = function () { return this.endOfLineComment; }; KeyValuesComments.prototype.HasEndOfLineComment = function () { return this.endOfLineComment.length > 0; }; return KeyValuesComments; }()); var KeyValues3Comments = /** @class */ (function () { function KeyValues3Comments(comments, endOfLineComment) { if (comments === void 0) { comments = []; } if (endOfLineComment === void 0) { endOfLineComment = ''; } this.comments = comments; this.endOfLineComment = endOfLineComment; } KeyValues3Comments.prototype.GetComments = function () { return this.comments; }; KeyValues3Comments.prototype.HasComments = function () { return this.comments.length > 0; }; KeyValues3Comments.prototype.SetComments = function (list) { this.comments = list; return this; }; KeyValues3Comments.prototype.AppendComment = function (text) { this.comments.push(text); return this; }; KeyValues3Comments.prototype.SetEndOfLineComment = function (text) { if (text.includes('\n')) { throw Error('The end of line comment only allowed one line'); } this.endOfLineComment = text; return this; }; KeyValues3Comments.prototype.GetEndOfLineComment = function () { return this.endOfLineComment; }; KeyValues3Comments.prototype.HasEndOfLineComment = function () { return this.endOfLineComment.length > 0; }; KeyValues3Comments.prototype.Format = function (tab) { var e_2, _a; if (tab === void 0) { tab = ''; } var text = ''; try { for (var _b = __values(this.comments), _c = _b.next(); !_c.done; _c = _b.next()) { var comment = _c.value; if (comment.includes('\n')) { var lines = comment.split('\n').map(function (v) { return v.trimStart(); }); text += "".concat(tab, "/*\n"); if (lines.some(function (v) { return v.startsWith('*'); })) { text += lines .map(function (v) { if (v.startsWith('*')) { v = v.trimStart(); } else { v = '* ' + v.trimStart(); } return "".concat(tab, " ") + v + '\n'; }) .join(''); text += "".concat(tab, " */\n"); } else { text += lines.map(function (v) { return "".concat(tab) + v + '\n'; }).join(''); text += "".concat(tab, "*/\n"); } } else { text += "".concat(tab, "// ").concat(comment.trimStart(), "\n"); } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } return text; }; return KeyValues3Comments; }()); var KeyValuesRootKey = '__KeyValues_Root__'; function createID$1() { var adapter = getKeyValuesAdapter(); return adapter.createKeyValuesID(); } var KeyValues = /** @class */ (function () { function KeyValues(Key, defaultValue) { this.Key = Key; /** * Comment */ this.Comments = new KeyValuesComments(); /** * The KeyValues flags, such as [$WIN32] [$X360] */ this.Flags = ''; /** * Unique id of KeyValues */ this.ID = createID$1(); this.baseFilePath = ''; this.SetValue(defaultValue || ''); } Object.defineProperty(KeyValues.prototype, "filename", { get: function () { return this.__filename || ''; }, set: function (s) { this.__filename = s ? s.replace(/\\/g, '/') : s; }, enumerable: false, configurable: true }); /** * The parent of this KeyValues */ KeyValues.prototype.GetParent = function () { return this.parent; }; /** * Return true that the KeyValues is root. */ KeyValues.prototype.IsRoot = function () { return this.Key === KeyValuesRootKey; }; /** * The key is #base? */ KeyValues.prototype.IsBase = function () { return this.Key === '#base'; }; /** * Return #base's value */ KeyValues.prototype.GetBaseFilePath = function () { return this.baseFilePath; }; /** * KeyValues list of #base */ KeyValues.prototype.GetBaseList = function () { return this.FindAllKeys('#base'); }; /** * The children of this KeyValues, * if no children then return empty array. */ KeyValues.prototype.GetChildren = function () { return this.children || []; }; KeyValues.prototype.GetChildCount = function () { return this.GetChildren().length; }; KeyValues.prototype.GetFirstChild = function () { return this.GetChildren()[0]; }; KeyValues.prototype.GetLastChild = function () { return this.GetChildren()[this.GetChildCount() - 1]; }; /** * Create a KeyValues to children and return it. */ KeyValues.prototype.CreateChild = function (key, value) { var kv = new KeyValues(key, value); this.Append(kv); return kv; }; /** * The value of this KeyValues, * if no value then return empty string. */ KeyValues.prototype.GetValue = function () { return this.value || ''; }; /** * Return true that the KeyValues exists children and no value. */ KeyValues.prototype.HasChildren = function () { return !!this.children; }; /** * Set value or children. */ KeyValues.prototype.SetValue = function (v) { var e_1, _a; if (Array.isArray(v)) { this.children = v.map(function (c) { return c.Free(); }); delete this.value; try { for (var _b = __values(this.children), _c = _b.next(); !_c.done; _c = _b.next()) { var kv = _c.value; if (kv === this) { throw new Error("SetValue(): The value can not includes self"); } kv.parent = this; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } } else { if (this.IsRoot()) { throw new Error('The value of the root node kv must be an array'); } this.value = v; delete this.children; } return this; }; /** * Append a KeyValues to children, * if no children then throw error. */ KeyValues.prototype.Append = function (child) { if (this.children) { if (child === this) { throw new Error("Append(): Can not append self"); } this.children.push(child.Free()); child.parent = this; } else { throw new Error("The KeyValues [Key = ".concat(this.Key, "] does not have children")); } return this; }; /** * Insert a KeyValues to children, * if no children then throw error. */ KeyValues.prototype.Insert = function (child, index) { if (this.children) { if (child === this) { throw new Error("Insert(): Can not insert self"); } this.children.splice(index, 0, child.Free()); child.parent = this; } else { throw new Error("The KeyValues [Key = ".concat(this.Key, "] does not have children")); } return this; }; /** * Find a KeyValues from children */ KeyValues.prototype.Find = function (callback) { var e_2, _a; if (!this.children) { return; } try { for (var _b = __values(this.children.entries()), _c = _b.next(); !_c.done; _c = _b.next()) { var _d = __read(_c.value, 2), i = _d[0], kv = _d[1]; if (callback(kv, i, this) === true) { return kv; } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } }; /** * Find all KeyValues from children */ KeyValues.prototype.FindAll = function (callback) { var e_3, _a; if (!this.children) { return []; } var result = []; try { for (var _b = __values(this.children.entries()), _c = _b.next(); !_c.done; _c = _b.next()) { var _d = __read(_c.value, 2), i = _d[0], kv = _d[1]; if (callback(kv, i, this) === true) { result.push(kv); } } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_3) throw e_3.error; } } return result; }; /** * Find a KeyValues */ KeyValues.prototype.FindKey = function (key) { return this.Find(function (kv) { return kv.Key === key; }); }; /** * Find all KeyValues */ KeyValues.prototype.FindAllKeys = function () { var keys = []; for (var _i = 0; _i < arguments.length; _i++) { keys[_i] = arguments[_i]; } return this.FindAll(function (kv) { return keys.includes(kv.Key); }); }; /** * Find a KeyValues from children and children's children... */ KeyValues.prototype.FindTraverse = function (callback) { if (!this.children) { return; } return KeyValues.FindTraverse(this, callback); }; /** * Find a KeyValues from children and children's children... */ KeyValues.FindTraverse = function (root, callback) { var e_4, _a; if (root.HasChildren()) { try { for (var _b = __values(root.GetChildren().entries()), _c = _b.next(); !_c.done; _c = _b.next()) { var _d = __read(_c.value, 2), i = _d[0], kv = _d[1]; if (callback(kv, i, root) === true) { return kv; } var result = KeyValues.FindTraverse(kv, callback); if (result) { return result; } } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_4) throw e_4.error; } } } }; /** * Find child from the current KeyValues */ KeyValues.prototype.FindID = function (id) { return this.Find(function (kv) { return kv.ID === id; }); }; /** * Recursively iterate through all children to find the value that matches the ID */ KeyValues.prototype.FindIDTraverse = function (id) { return this.FindTraverse(function (kv) { return kv.ID === id; }); }; /** * Delete a KeyValues from children */ KeyValues.prototype.Delete = function (child) { if (!this.children) { return; } var kv; if (typeof child === 'string') { kv = this.children.find(function (v) { return v.Key === child; }); } else { kv = this.children.find(function (v) { return v === child; }); } if (kv) { this.children = this.children.filter(function (v) { return v !== kv; }); kv.Free(); } return kv; }; /** * Delete this KeyValues from parent */ KeyValues.prototype.Free = function () { if (this.parent) { this.parent.Delete(this); delete this.parent; } return this; }; /** * Format KeyValues to file text */ KeyValues.prototype.Format = function (tab, maxLength) { var e_5, _a; if (tab === void 0) { tab = ''; } if (maxLength === void 0) { maxLength = -1; } if (this.IsRoot()) { if (!this.children) { throw new Error('The value of the root node kv must be an array'); } return this.children.map(function (v) { return v.Format(); }).join('\n'); } var text = ''; if (this.Comments.HasComments()) { text += this.Comments.GetComments() .map(function (v) { return "".concat(tab, "// ").concat(v.trimStart(), "\n"); }) .join(''); } if (this.children) { if (this.IsBase()) { text += "".concat(tab).concat(this.Key, " \"").concat(this.GetBaseFilePath(), "\""); if (this.Comments.HasEndOfLineComment()) { text += " // ".concat(this.Comments.GetEndOfLineComment()); } return text; } var maxLength_1 = Math.max.apply(Math, __spreadArray([], __read(this.children.map(function (v) { return v.Key.length; })), false)); text += "".concat(tab, "\"").concat(this.Key, "\""); if (this.Comments.HasEndOfLineComment()) { text += " // ".concat(this.Comments.GetEndOfLineComment()); } text += "\n".concat(tab, "{"); try { for (var _b = __values(this.children), _c = _b.next(); !_c.done; _c = _b.next()) { var kv = _c.value; text += '\n' + kv.Format(tab + ' ', maxLength_1); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_5) throw e_5.error; } } text += "\n".concat(tab, "}"); } else { if (this.IsBase()) { text += "".concat(tab).concat(this.Key, " \"").concat(this.value, "\""); if (this.Comments.HasEndOfLineComment()) { text += " // ".concat(this.Comments.GetEndOfLineComment()); } } else { text += "".concat(tab, "\"").concat(this.Key, "\"").concat(' '.repeat(Math.max(0, maxLength - this.Key.length))); text += " \"".concat(this.value, "\""); if (this.Comments.HasEndOfLineComment()) { text += " // ".concat(this.Comments.GetEndOfLineComment()); } } } return text; }; KeyValues.prototype.toString = function () { return this.Format(); }; /** * Deep clone KeyValues */ KeyValues.prototype.Clone = function () { if (!this.children) { return new KeyValues(this.Key, this.value); } return new KeyValues(this.Key, this.children.map(function (v) { return v.Clone(); })); }; /** * Create root node */ KeyValues.CreateRoot = function () { return new KeyValues(KeyValuesRootKey, []); }; /** * Parse string */ KeyValues.Parse = function (body, filename) { return __awaiter(this, void 0, void 0, function () { var root, baseList, adapter, baseList_1, baseList_1_1, base, v, filePath, baseKV, e_6_1; var e_6, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: root = this.CreateRoot(); root.filename = filename; this._parse({ body: body, pos: 0, line: 1 }, root); if (!filename) return [3 /*break*/, 8]; baseList = root.FindAllKeys('#base'); adapter = getKeyValuesAdapter(); _b.label = 1; case 1: _b.trys.push([1, 6, 7, 8]); baseList_1 = __values(baseList), baseList_1_1 = baseList_1.next(); _b.label = 2; case 2: if (!!baseList_1_1.done) return [3 /*break*/, 5]; base = baseList_1_1.value; v = base.GetValue().trim(); if (!v) return [3 /*break*/, 4]; base.baseFilePath = v; filePath = adapter.resolvePath(filename, v); return [4 /*yield*/, KeyValues.Load(filePath)]; case 3: baseKV = _b.sent(); base.filename = baseKV.filename; base.SetValue(baseKV.GetChildren().map(function (v) { return v.Free(); })); _b.label = 4; case 4: baseList_1_1 = baseList_1.next(); return [3 /*break*/, 2]; case 5: return [3 /*break*/, 8]; case 6: e_6_1 = _b.sent(); e_6 = { error: e_6_1 }; return [3 /*break*/, 8]; case 7: try { if (baseList_1_1 && !baseList_1_1.done && (_a = baseList_1.return)) _a.call(baseList_1); } finally { if (e_6) throw e_6.error; } return [7 /*endfinally*/]; case 8: return [2 /*return*/, root]; } }); }); }; KeyValues._parse = function (data, parent) { var kv = new KeyValues(''); var key = false; var leftMark = false; var inQoute = false; var str = ''; var isEndOfLineComment = false; var lastKV; var matchFlag = false; for (; data.pos < data.body.length; data.pos++) { var c = data.body[data.pos]; var isNewLine = c === '\n'; var isSpace = isNewLine || c === ' ' || c === '\t' || c === '\r'; if (isNewLine) { data.line += 1; isEndOfLineComment = false; } // Merge flags text if (lastKV && matchFlag) { if (c === ']') { lastKV.Flags = str; matchFlag = false; str = ''; continue; } str += c; continue; } // If leftMark is true then merge char to str if (leftMark) { if (!inQoute) { if (c === '{' || c === '"' || c === '[' || c === ']') { throw Error("Not readable in line ".concat(data.line)); } if (isSpace || c === '}') { if (key) { kv.Key = str; } else { kv.SetValue(str); parent.Append(kv); lastKV = kv; kv = new KeyValues(''); } leftMark = false; inQoute = false; str = ''; if (c === '}') { data.pos--; } continue; } str += c; continue; } if (c === '\\') { data.pos++; str += c + data.body[data.pos]; continue; } if (c === '"') { if (key) { kv.Key = str; } else { kv.SetValue(str); parent.Append(kv); lastKV = kv; kv = new KeyValues(''); } leftMark = false; inQoute = false; str = ''; continue; } str += c; continue; } // if comment if (c === '/') { if (data.body[data.pos + 1] === '*') { throw Error("Line ".concat(data.line, ": not support multi-line comment")); } if (data.body[data.pos + 1] === '/') { var endIndex = data.body.indexOf('\n', data.pos + 1); if (endIndex < 0) { break; } var comment = data.body.slice(data.pos + 2, endIndex).trim(); if (comment) { if (isEndOfLineComment) { if (key) { kv.Comments.SetEndOfLineComment(comment); } else { var lastChild = parent.GetLastChild(); if (lastChild) { lastChild.Comments.SetEndOfLineComment(comment); } } } else { kv.Comments.AppendComment(comment); } } isEndOfLineComment = false; data.pos = endIndex; continue; } } // If open breace if (c === '{') { data.pos++; kv.SetValue([]); parent.Append(kv); this._parse(data, kv); lastKV = kv; kv = new KeyValues(''); key = false; continue; } // If close breace if (c === '}') { data.pos++; break; } // If space if (isSpace) { continue; } // Match flag if (lastKV && c === '[') { str = ''; matchFlag = true; continue; } // start merge char key = !key; leftMark = true; inQoute = c === '"'; str = inQoute ? '' : c; isEndOfLineComment = true; } }; /** * Convert KeyValues to object and exclude comments. */ KeyValues.prototype.toObject = function () { var e_7, _a, e_8, _b; var obj = {}; if (!this.HasChildren()) { throw Error('Not found children in this KeyValues'); } try { for (var _c = __values(this.children), _d = _c.next(); !_d.done; _d = _c.next()) { var kv = _d.value; if (kv.Key === '#base') { continue; } if (!kv.HasChildren()) { obj[kv.Key] = kv.GetValue(); } else { obj[kv.Key] = kv.toObject(); } } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_7) throw e_7.error; } } if (this.IsRoot()) { try { for (var _e = __values(this.GetBaseList()), _f = _e.next(); !_f.done; _f = _e.next()) { var base = _f.value; var root = base.toObject(); for (var key in root) { var baseChildren = root[key]; if (obj[key] === undefined) { obj[key] = baseChildren; } else { var children = obj[key]; for (var k in baseChildren) { children[k] = baseChildren[k]; } } } } } catch (e_8_1) { e_8 = { error: e_8_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_8) throw e_8.error; } } } return obj; }; /** * Load KeyValues from file */ KeyValues.Load = function (filename, encoding) { return __awaiter(this, void 0, void 0, function () { var adapter, text; return __generator(this, function (_a) { switch (_a.label) { case 0: adapter = getKeyValuesAdapter(); return [4 /*yield*/, adapter.readFile(filename, encoding)]; case 1: text = _a.sent(); if (!(text.charCodeAt(0) === 0xfeff)) return [3 /*break*/, 3]; return [4 /*yield*/, this.Parse(text.slice(1), filename)]; case 2: return [2 /*return*/, _a.sent()]; case 3: return [4 /*yield*/, this.Parse(text, filename)]; case 4: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Save KeyValues to file */ KeyValues.prototype.Save = function (otherFilename, encoding) { return __awaiter(this, void 0, void 0, function () { var filename, adapter, baseList, baseList_2, baseList_2_1, base, content, filePath, e_9_1; var e_9, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: filename = otherFilename !== null && otherFilename !== void 0 ? otherFilename : this.filename; if (!filename) { throw new Error('Not found filename in KeyValues'); } adapter = getKeyValuesAdapter(); return [4 /*yield*/, adapter.writeFile(filename, this.Format(), encoding)]; case 1: _b.sent(); baseList = this.FindAllKeys('#base'); _b.label = 2; case 2: _b.trys.push([2, 9, 10, 11]); baseList_2 = __values(baseList), baseList_2_1 = baseList_2.next(); _b.label = 3; case 3: if (!!baseList_2_1.done) return [3 /*break*/, 8]; base = baseList_2_1.value; content = base .GetChildren() .map(function (v) { return v.Format(); }) .join('\n'); if (!otherFilename) return [3 /*break*/, 5]; filePath = adapter.resolvePath(filename, base.GetBaseFilePath()); return [4 /*yield*/, adapter.writeFile(filePath, content, encoding)]; case 4: _b.sent(); return [3 /*break*/, 7]; case 5: return [4 /*yield*/, adapter.writeFile(base.filename, content, encoding)]; case 6: _b.sent(); _b.label = 7; case 7: baseList_2_1 = baseList_2.next(); return [3 /*break*/, 3]; case 8: return [3 /*break*/, 11]; case 9: e_9_1 = _b.sent(); e_9 = { error: e_9_1 }; return [3 /*break*/, 11]; case 10: try { if (baseList_2_1 && !baseList_2_1.done && (_a = baseList_2.return)) _a.call(baseList_2); } finally { if (e_9) throw e_9.error; } return [7 /*endfinally*/]; case 11: return [2 /*return*/]; } }); }); }; return KeyValues; }()); function createID() { var adapter = getKeyValuesAdapter(); return adapter.createKeyValuesID(); } var KV3BaseValue = /** @class */ (function () { function KV3BaseValue(owner) { this.Comments = new KeyValues3Comments(); this.owner = owner; } KV3BaseValue.prototype.Value = function () { return this.value; }; KV3BaseValue.prototype.GetOwner = function () { return this.owner; }; KV3BaseValue.prototype.SetOwner = function (owner) { this.owner = owner; }; KV3BaseValue.prototype.IsBoolean = function () { return this instanceof ValueBoolean; }; KV3BaseValue.prototype.IsInt = function () { return this instanceof ValueInt; }; KV3BaseValue.prototype.IsDouble = function () { return this instanceof ValueDouble; }; KV3BaseValue.prototype.IsString = function () { return this instanceof ValueString; }; KV3BaseValue.prototype.IsFeature = function () { return this instanceof ValueFeature; }; KV3BaseValue.prototype.IsArray = function () { return this instanceof ValueArray; }; KV3BaseValue.prototype.IsObject = function () { return this instanceof ValueObject; }; KV3BaseValue.prototype.IsNull = function () { return this instanceof ValueNull; }; KV3BaseValue.prototype.IsFeatureObject = function () { return this instanceof ValueFeatureObject; }; KV3BaseValue.prototype.Format = function () { return String(this.value); }; KV3BaseValue.prototype.Clone = function () { var v = new KV3BaseValue(this.owner); v.value = this.value; return v; }; return KV3BaseValue; }()); /** * Null */ var ValueNull = /** @class */ (function (_super) { __extends(ValueNull, _super); function ValueNull() { return _super.call(this) || this; } ValueNull.prototype.Value = function () { return null; }; ValueNull.prototype.Format = function () { return "null"; }; ValueNull.prototype.Clone = function () { var v = new ValueNull(); v.SetOwner(this.owner); return v; }; return ValueNull; }(KV3BaseValue)); /** * String */ var ValueString = /** @class */ (function (_super) { __extends(ValueString, _super); function ValueString(initValue) { var _this = _super.call(this) || this; _this.value = ''; if (initValue) { _this.SetValue(initValue); } return _this; } ValueString.prototype.Value = function () { return this.value; }; ValueString.prototype.SetValue = function (v) { this.value = String(v); return this; }; ValueString.prototype.Format = function () { if (this.value.includes('\n')) { return "\"\"\"".concat(this.value, "\"\"\""); } return "\"".concat(this.value, "\""); }; ValueString.prototype.Clone = function () { var v = new ValueString(this.value); v.SetOwner(this.owner); return v; }; return ValueString; }(KV3BaseValue)); /** * Boolean */ var ValueBoolean = /** @class */ (function (_super) { __extends(ValueBoolean, _super); function ValueBoolean(initValue) { var _this = _super.call(this) || this; _this.value = false; if (initValue) { _this.SetValue(initValue); } return _this; } ValueBoolean.prototype.Value = function () { return this.value; }; ValueBoolean.prototype.SetValue = function (v) { this.value = v === true; return this; }; ValueBoolean.prototype.Clone = function () { var v = new ValueBoolean(this.value); v.SetOwner(this.owner); return v; }; return ValueBoolean; }(KV3BaseValue)); /** * Int */ var ValueInt = /** @class */ (function (_super) { __extends(ValueInt, _super); function ValueInt(initValue) { var _this = _super.call(this) || this; _this.value = 0; if (initValue) { _this.SetValue(initValue); } return _this; } ValueInt.prototype.Value = function () { return this.value; }; ValueInt.prototype.SetValue = function (v) { this.value = Math.floor(v); return this; }; ValueInt.prototype.Clone = function () { var v = new ValueInt(this.value); v.SetOwner(this.owner); return v; }; return ValueInt; }(KV3BaseValue)); /** * Double */ var ValueDouble = /** @class */ (function (_super) { __extends(ValueDouble, _super); function ValueDouble(initValue) { var _this = _super.call(this) || this; _this.value = 0; if (initValue) { _this.SetValue(initValue); } return _this; } ValueDouble.prototype.Value = function () { return this.value; }; ValueDouble.prototype.SetValue = function (v) { this.value = v; return this; }; ValueDouble.prototype.Format = function () { return this.value.toFixed(6); }; ValueDouble.prototype.Clone = function () { var v = new ValueDouble(this.value); v.SetOwner(this.owner); return v; }; return ValueDouble; }(KV3BaseValue)); /** * Similar values: * resource:"" * deferred_resource:"" * soundevent:"" */ var ValueFeature = /** @class */ (function (_super) { __extends(ValueFeature, _super); function ValueFeature(Feature, initValue) { if (Feature === void 0) { Feature = 'resource'; } var _this = _super.call(this) || this; _this.Feature = Feature; _this.value = ''; if (initValue) { _this.SetValue(initValue); } return _this; } ValueFeature.prototype.Value = function () { return this.value; }; ValueFeature.prototype.SetValue = function (v) { this.value = v; return this; }; ValueFeature.prototype.Format = function () { return "".concat(this.Feature, ":\"").concat(this.value, "\""); }; ValueFeature.prototype.Clone = function () { var v = new ValueFeature(this.value); v.SetOwner(this.owner); return v; }; return ValueFeature; }(KV3BaseValue)); /** * Array */ var ValueArray = /** @class */ (function (_super) { __extends(ValueArray, _super); function ValueArray(initValue) { var _this = _super.call(this) || this; _this.value = []; if (initValue) { _this.SetValue(initValue); } return _this; } ValueArray.prototype.Value = function () { return this.value; }; ValueArray.prototype.SetValue = function (list) { this.value = list.map(function (v) { return v; }); return this; }; ValueArray.prototype.Append = function () { var _a; var kv = []; f