knex-firebird-dialect
Version:
Firebird dialect for Knex.js
293 lines (289 loc) • 37.3 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _lodash = require("lodash");
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // Firebird_DDL
//
//
// columns and changing datatypes.
// -------
var Firebird_DDL = /*#__PURE__*/function () {
function Firebird_DDL(client, tableCompiler, pragma, connection) {
(0, _classCallCheck2["default"])(this, Firebird_DDL);
this.client = client;
this.tableCompiler = tableCompiler;
this.pragma = pragma;
this.tableNameRaw = this.tableCompiler.tableNameRaw;
this.alteredName = (0, _lodash.uniqueId)("_knex_temp_alter");
this.connection = connection;
this.formatter = client && client.config && client.config.wrapIdentifier ? client.config.wrapIdentifier : function (value) {
return value;
};
}
return (0, _createClass2["default"])(Firebird_DDL, [{
key: "tableName",
value: function tableName() {
return this.formatter(this.tableNameRaw, function (value) {
return value;
});
}
}, {
key: "getColumn",
value: function () {
var _getColumn = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(column) {
var _this = this;
var currentCol;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
currentCol = (0, _lodash.find)(this.pragma, function (col) {
return _this.client.wrapIdentifier(col.name).toLowerCase() === _this.client.wrapIdentifier(column).toLowerCase();
});
if (currentCol) {
_context.next = 3;
break;
}
throw new Error("The column ".concat(column, " is not in the ").concat(this.tableName(), " table"));
case 3:
return _context.abrupt("return", currentCol);
case 4:
case "end":
return _context.stop();
}
}, _callee, this);
}));
function getColumn(_x) {
return _getColumn.apply(this, arguments);
}
return getColumn;
}()
}, {
key: "getTableSql",
value: function getTableSql() {
var _this2 = this;
this.trx.disableProcessing();
return this.trx.raw("SELECT name, sql FROM sqlite_master WHERE type=\"table\" AND name=\"".concat(this.tableName(), "\"")).then(function (result) {
_this2.trx.enableProcessing();
return result;
});
}
}, {
key: "renameTable",
value: function () {
var _renameTable = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2() {
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
return _context2.abrupt("return", this.trx.raw("ALTER TABLE \"".concat(this.tableName(), "\" RENAME TO \"").concat(this.alteredName, "\"")));
case 1:
case "end":
return _context2.stop();
}
}, _callee2, this);
}));
function renameTable() {
return _renameTable.apply(this, arguments);
}
return renameTable;
}()
}, {
key: "dropOriginal",
value: function dropOriginal() {
return this.trx.raw("DROP TABLE \"".concat(this.tableName(), "\""));
}
}, {
key: "dropTempTable",
value: function dropTempTable() {
return this.trx.raw("DROP TABLE \"".concat(this.alteredName, "\""));
}
}, {
key: "copyData",
value: function copyData() {
var _this3 = this;
return this.trx.raw("SELECT * FROM \"".concat(this.tableName(), "\"")).then(function (result) {
return _this3.insertChunked(20, _this3.alteredName, _lodash.identity, result);
});
}
}, {
key: "reinsertData",
value: function reinsertData(iterator) {
var _this4 = this;
return this.trx.raw("SELECT * FROM \"".concat(this.alteredName, "\"")).then(function (result) {
return _this4.insertChunked(20, _this4.tableName(), iterator, result);
});
}
}, {
key: "insertChunked",
value: function () {
var _insertChunked = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3(chunkSize, target, iterator, result) {
var chunked, _iterator, _step, batch;
return _regenerator["default"].wrap(function _callee3$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
iterator = iterator || _lodash.identity;
chunked = (0, _lodash.chunk)(result, chunkSize);
_iterator = _createForOfIteratorHelper(chunked);
_context3.prev = 3;
_iterator.s();
case 5:
if ((_step = _iterator.n()).done) {
_context3.next = 11;
break;
}
batch = _step.value;
_context3.next = 9;
return this.trx.queryBuilder().table(target).insert((0, _lodash.map)(batch, iterator));
case 9:
_context3.next = 5;
break;
case 11:
_context3.next = 16;
break;
case 13:
_context3.prev = 13;
_context3.t0 = _context3["catch"](3);
_iterator.e(_context3.t0);
case 16:
_context3.prev = 16;
_iterator.f();
return _context3.finish(16);
case 19:
case "end":
return _context3.stop();
}
}, _callee3, this, [[3, 13, 16, 19]]);
}));
function insertChunked(_x2, _x3, _x4, _x5) {
return _insertChunked.apply(this, arguments);
}
return insertChunked;
}()
}, {
key: "createTempTable",
value: function createTempTable(createTable) {
return this.trx.raw(createTable.sql.replace(this.tableName(), this.alteredName));
}
}, {
key: "_doReplace",
value: function _doReplace(sql, from, to) {
var oneLineSql = sql.replace(/\s+/g, " ");
var matched = oneLineSql.match(/^CREATE TABLE\s+(\S+)\s*\((.*)\)/);
var tableName = matched[1];
var defs = matched[2];
if (!defs) {
throw new Error("No column definitions in this statement!");
}
var parens = 0,
args = [],
ptr = 0;
var i = 0;
var x = defs.length;
for (i = 0; i < x; i++) {
switch (defs[i]) {
case "(":
parens++;
break;
case ")":
parens--;
break;
case ",":
if (parens === 0) {
args.push(defs.slice(ptr, i));
ptr = i + 1;
}
break;
case " ":
if (ptr === i) {
ptr = i + 1;
}
break;
}
}
args.push(defs.slice(ptr, i));
var fromIdentifier = from.replace(/[`"'[\]]/g, "");
args = args.map(function (item) {
item = item.trim();
var split = item.split(" ");
var fromMatchCandidates = [new RegExp("`".concat(fromIdentifier, "`"), "i"), new RegExp("\"".concat(fromIdentifier, "\""), "i"), new RegExp("'".concat(fromIdentifier, "'"), "i"), new RegExp("\\[".concat(fromIdentifier, "\\]"), "i")];
if (fromIdentifier.match(/^\S+$/)) {
fromMatchCandidates.push(new RegExp("\\b".concat(fromIdentifier, "\\b"), "i"));
}
var doesMatchFromIdentifier = function doesMatchFromIdentifier(target) {
return (0, _lodash.some)(fromMatchCandidates, function (c) {
return target.match(c);
});
};
var replaceFromIdentifier = function replaceFromIdentifier(target) {
return fromMatchCandidates.reduce(function (result, candidate) {
return result.replace(candidate, to);
}, target);
};
if (doesMatchFromIdentifier(split[0])) {
// column definition
if (to) {
split[0] = to;
return split.join(" ");
}
return ""; // for deletions
}
// skip constraint name
var idx = /constraint/i.test(split[0]) ? 2 : 0;
// primary key and unique constraints have one or more
// columns from this table listed between (); replace
// one if it matches
if (/primary|unique/i.test(split[idx])) {
var ret = item.replace(/\(.*\)/, replaceFromIdentifier);
// If any member columns are dropped then uniqueness/pk constraint
// can not be retained
if (ret !== item && (0, _lodash.isEmpty)(to)) return "";
return ret;
}
// foreign keys have one or more columns from this table
// listed between (); replace one if it matches
// foreign keys also have a 'references' clause
// which may reference THIS table; if it does, replace
// column references in that too!
if (/foreign/.test(split[idx])) {
split = item.split(/ references /i);
// the quoted column names save us from having to do anything
// other than a straight replace here
var replacedKeySpec = replaceFromIdentifier(split[0]);
if (split[0] !== replacedKeySpec) {
// If we are removing one or more columns of a foreign
// key, then we should not retain the key at all
if ((0, _lodash.isEmpty)(to)) return "";else split[0] = replacedKeySpec;
}
if (split[1].slice(0, tableName.length) === tableName) {
// self-referential foreign key
var replacedKeyTargetSpec = split[1].replace(/\(.*\)/, replaceFromIdentifier);
if (split[1] !== replacedKeyTargetSpec) {
// If we are removing one or more columns of a foreign
// key, then we should not retain the key at all
if ((0, _lodash.isEmpty)(to)) return "";else split[1] = replacedKeyTargetSpec;
}
}
return split.join(" references ");
}
return item;
});
args = args.filter((0, _lodash.negate)(_lodash.isEmpty));
if (args.length === 0) {
throw new Error("Unable to drop last column from table");
}
return oneLineSql.replace(/\(.*\)/, function () {
return "(".concat(args.join(", "), ")");
}).replace(/,\s*([,)])/, "$1");
}
}]);
}();
var _default = exports["default"] = Firebird_DDL;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwicmVxdWlyZSIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiciIsImUiLCJ0IiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJBcnJheSIsImlzQXJyYXkiLCJfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkiLCJsZW5ndGgiLCJfbiIsIkYiLCJzIiwibiIsImRvbmUiLCJ2YWx1ZSIsImYiLCJUeXBlRXJyb3IiLCJvIiwiYSIsInUiLCJjYWxsIiwibmV4dCIsIl9hcnJheUxpa2VUb0FycmF5IiwidG9TdHJpbmciLCJzbGljZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsImZyb20iLCJ0ZXN0IiwiRmlyZWJpcmRfRERMIiwiY2xpZW50IiwidGFibGVDb21waWxlciIsInByYWdtYSIsImNvbm5lY3Rpb24iLCJfY2xhc3NDYWxsQ2hlY2syIiwidGFibGVOYW1lUmF3IiwiYWx0ZXJlZE5hbWUiLCJ1bmlxdWVJZCIsImZvcm1hdHRlciIsImNvbmZpZyIsIndyYXBJZGVudGlmaWVyIiwiX2NyZWF0ZUNsYXNzMiIsImtleSIsInRhYmxlTmFtZSIsIl9nZXRDb2x1bW4iLCJfYXN5bmNUb0dlbmVyYXRvcjIiLCJfcmVnZW5lcmF0b3IiLCJtYXJrIiwiX2NhbGxlZSIsImNvbHVtbiIsIl90aGlzIiwiY3VycmVudENvbCIsIndyYXAiLCJfY2FsbGVlJCIsIl9jb250ZXh0IiwicHJldiIsImZpbmQiLCJjb2wiLCJ0b0xvd2VyQ2FzZSIsIkVycm9yIiwiY29uY2F0IiwiYWJydXB0Iiwic3RvcCIsImdldENvbHVtbiIsIl94IiwiYXBwbHkiLCJhcmd1bWVudHMiLCJnZXRUYWJsZVNxbCIsIl90aGlzMiIsInRyeCIsImRpc2FibGVQcm9jZXNzaW5nIiwicmF3IiwidGhlbiIsInJlc3VsdCIsImVuYWJsZVByb2Nlc3NpbmciLCJfcmVuYW1lVGFibGUiLCJfY2FsbGVlMiIsIl9jYWxsZWUyJCIsIl9jb250ZXh0MiIsInJlbmFtZVRhYmxlIiwiZHJvcE9yaWdpbmFsIiwiZHJvcFRlbXBUYWJsZSIsImNvcHlEYXRhIiwiX3RoaXMzIiwiaW5zZXJ0Q2h1bmtlZCIsImlkZW50aXR5IiwicmVpbnNlcnREYXRhIiwiX3RoaXM0IiwiX2luc2VydENodW5rZWQiLCJfY2FsbGVlMyIsImNodW5rU2l6ZSIsInRhcmdldCIsImNodW5rZWQiLCJfaXRlcmF0b3IiLCJfc3RlcCIsImJhdGNoIiwiX2NhbGxlZTMkIiwiX2NvbnRleHQzIiwiY2h1bmsiLCJxdWVyeUJ1aWxkZXIiLCJ0YWJsZSIsImluc2VydCIsIm1hcCIsInQwIiwiZmluaXNoIiwiX3gyIiwiX3gzIiwiX3g0IiwiX3g1IiwiY3JlYXRlVGVtcFRhYmxlIiwiY3JlYXRlVGFibGUiLCJzcWwiLCJyZXBsYWNlIiwiX2RvUmVwbGFjZSIsInRvIiwib25lTGluZVNxbCIsIm1hdGNoZWQiLCJtYXRjaCIsImRlZnMiLCJwYXJlbnMiLCJhcmdzIiwicHRyIiwiaSIsIngiLCJwdXNoIiwiZnJvbUlkZW50aWZpZXIiLCJpdGVtIiwidHJpbSIsInNwbGl0IiwiZnJvbU1hdGNoQ2FuZGlkYXRlcyIsIlJlZ0V4cCIsImRvZXNNYXRjaEZyb21JZGVudGlmaWVyIiwic29tZSIsImMiLCJyZXBsYWNlRnJvbUlkZW50aWZpZXIiLCJyZWR1Y2UiLCJjYW5kaWRhdGUiLCJqb2luIiwiaWR4IiwicmV0IiwiaXNFbXB0eSIsInJlcGxhY2VkS2V5U3BlYyIsInJlcGxhY2VkS2V5VGFyZ2V0U3BlYyIsImZpbHRlciIsIm5lZ2F0ZSIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY2hlbWEvZGRsLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEZpcmViaXJkX0RETFxuLy9cbi8vXG4vLyBjb2x1bW5zIGFuZCBjaGFuZ2luZyBkYXRhdHlwZXMuXG4vLyAtLS0tLS0tXG5cbmltcG9ydCB7XG4gIHVuaXF1ZUlkLFxuICBmaW5kLFxuICBpZGVudGl0eSxcbiAgbWFwLFxuICBzb21lLFxuICBuZWdhdGUsXG4gIGlzRW1wdHksXG4gIGNodW5rLFxufSBmcm9tIFwibG9kYXNoXCI7XG5cbmNsYXNzIEZpcmViaXJkX0RETCB7XG4gIGNvbnN0cnVjdG9yKGNsaWVudCwgdGFibGVDb21waWxlciwgcHJhZ21hLCBjb25uZWN0aW9uKSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy50YWJsZUNvbXBpbGVyID0gdGFibGVDb21waWxlcjtcbiAgICB0aGlzLnByYWdtYSA9IHByYWdtYTtcbiAgICB0aGlzLnRhYmxlTmFtZVJhdyA9IHRoaXMudGFibGVDb21waWxlci50YWJsZU5hbWVSYXc7XG4gICAgdGhpcy5hbHRlcmVkTmFtZSA9IHVuaXF1ZUlkKFwiX2tuZXhfdGVtcF9hbHRlclwiKTtcbiAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgIHRoaXMuZm9ybWF0dGVyID1cbiAgICAgIGNsaWVudCAmJiBjbGllbnQuY29uZmlnICYmIGNsaWVudC5jb25maWcud3JhcElkZW50aWZpZXJcbiAgICAgICAgPyBjbGllbnQuY29uZmlnLndyYXBJZGVudGlmaWVyXG4gICAgICAgIDogKHZhbHVlKSA9PiB2YWx1ZTtcbiAgfVxuXG4gIHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtYXR0ZXIodGhpcy50YWJsZU5hbWVSYXcsICh2YWx1ZSkgPT4gdmFsdWUpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Q29sdW1uKGNvbHVtbikge1xuICAgIGNvbnN0IGN1cnJlbnRDb2wgPSBmaW5kKHRoaXMucHJhZ21hLCAoY29sKSA9PiB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICB0aGlzLmNsaWVudC53cmFwSWRlbnRpZmllcihjb2wubmFtZSkudG9Mb3dlckNhc2UoKSA9PT1cbiAgICAgICAgdGhpcy5jbGllbnQud3JhcElkZW50aWZpZXIoY29sdW1uKS50b0xvd2VyQ2FzZSgpXG4gICAgICApO1xuICAgIH0pO1xuICAgIGlmICghY3VycmVudENvbClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFRoZSBjb2x1bW4gJHtjb2x1bW59IGlzIG5vdCBpbiB0aGUgJHt0aGlzLnRhYmxlTmFtZSgpfSB0YWJsZWBcbiAgICAgICk7XG4gICAgcmV0dXJuIGN1cnJlbnRDb2w7XG4gIH1cblxuICBnZXRUYWJsZVNxbCgpIHtcbiAgICB0aGlzLnRyeC5kaXNhYmxlUHJvY2Vzc2luZygpO1xuICAgIHJldHVybiB0aGlzLnRyeFxuICAgICAgLnJhdyhcbiAgICAgICAgYFNFTEVDVCBuYW1lLCBzcWwgRlJPTSBzcWxpdGVfbWFzdGVyIFdIRVJFIHR5cGU9XCJ0YWJsZVwiIEFORCBuYW1lPVwiJHt0aGlzLnRhYmxlTmFtZSgpfVwiYFxuICAgICAgKVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICB0aGlzLnRyeC5lbmFibGVQcm9jZXNzaW5nKCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHJlbmFtZVRhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLnRyeC5yYXcoXG4gICAgICBgQUxURVIgVEFCTEUgXCIke3RoaXMudGFibGVOYW1lKCl9XCIgUkVOQU1FIFRPIFwiJHt0aGlzLmFsdGVyZWROYW1lfVwiYFxuICAgICk7XG4gIH1cblxuICBkcm9wT3JpZ2luYWwoKSB7XG4gICAgcmV0dXJuIHRoaXMudHJ4LnJhdyhgRFJPUCBUQUJMRSBcIiR7dGhpcy50YWJsZU5hbWUoKX1cImApO1xuICB9XG5cbiAgZHJvcFRlbXBUYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy50cngucmF3KGBEUk9QIFRBQkxFIFwiJHt0aGlzLmFsdGVyZWROYW1lfVwiYCk7XG4gIH1cblxuICBjb3B5RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy50cnhcbiAgICAgIC5yYXcoYFNFTEVDVCAqIEZST00gXCIke3RoaXMudGFibGVOYW1lKCl9XCJgKVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT5cbiAgICAgICAgdGhpcy5pbnNlcnRDaHVua2VkKDIwLCB0aGlzLmFsdGVyZWROYW1lLCBpZGVudGl0eSwgcmVzdWx0KVxuICAgICAgKTtcbiAgfVxuXG4gIHJlaW5zZXJ0RGF0YShpdGVyYXRvcikge1xuICAgIHJldHVybiB0aGlzLnRyeFxuICAgICAgLnJhdyhgU0VMRUNUICogRlJPTSBcIiR7dGhpcy5hbHRlcmVkTmFtZX1cImApXG4gICAgICAudGhlbigocmVzdWx0KSA9PlxuICAgICAgICB0aGlzLmluc2VydENodW5rZWQoMjAsIHRoaXMudGFibGVOYW1lKCksIGl0ZXJhdG9yLCByZXN1bHQpXG4gICAgICApO1xuICB9XG5cbiAgYXN5bmMgaW5zZXJ0Q2h1bmtlZChjaHVua1NpemUsIHRhcmdldCwgaXRlcmF0b3IsIHJlc3VsdCkge1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgaWRlbnRpdHk7XG4gICAgY29uc3QgY2h1bmtlZCA9IGNodW5rKHJlc3VsdCwgY2h1bmtTaXplKTtcbiAgICBmb3IgKGNvbnN0IGJhdGNoIG9mIGNodW5rZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMudHJ4LnF1ZXJ5QnVpbGRlcigpLnRhYmxlKHRhcmdldCkuaW5zZXJ0KG1hcChiYXRjaCwgaXRlcmF0b3IpKTtcbiAgICB9XG4gIH1cblxuICBjcmVhdGVUZW1wVGFibGUoY3JlYXRlVGFibGUpIHtcbiAgICByZXR1cm4gdGhpcy50cngucmF3KFxuICAgICAgY3JlYXRlVGFibGUuc3FsLnJlcGxhY2UodGhpcy50YWJsZU5hbWUoKSwgdGhpcy5hbHRlcmVkTmFtZSlcbiAgICApO1xuICB9XG5cbiAgX2RvUmVwbGFjZShzcWwsIGZyb20sIHRvKSB7XG4gICAgY29uc3Qgb25lTGluZVNxbCA9IHNxbC5yZXBsYWNlKC9cXHMrL2csIFwiIFwiKTtcbiAgICBjb25zdCBtYXRjaGVkID0gb25lTGluZVNxbC5tYXRjaCgvXkNSRUFURSBUQUJMRVxccysoXFxTKylcXHMqXFwoKC4qKVxcKS8pO1xuXG4gICAgY29uc3QgdGFibGVOYW1lID0gbWF0Y2hlZFsxXTtcbiAgICBjb25zdCBkZWZzID0gbWF0Y2hlZFsyXTtcblxuICAgIGlmICghZGVmcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gY29sdW1uIGRlZmluaXRpb25zIGluIHRoaXMgc3RhdGVtZW50IVwiKTtcbiAgICB9XG5cbiAgICBsZXQgcGFyZW5zID0gMCxcbiAgICAgIGFyZ3MgPSBbXSxcbiAgICAgIHB0ciA9IDA7XG4gICAgbGV0IGkgPSAwO1xuICAgIGNvbnN0IHggPSBkZWZzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgeDsgaSsrKSB7XG4gICAgICBzd2l0Y2ggKGRlZnNbaV0pIHtcbiAgICAgICAgY2FzZSBcIihcIjpcbiAgICAgICAgICBwYXJlbnMrKztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIilcIjpcbiAgICAgICAgICBwYXJlbnMtLTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIixcIjpcbiAgICAgICAgICBpZiAocGFyZW5zID09PSAwKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goZGVmcy5zbGljZShwdHIsIGkpKTtcbiAgICAgICAgICAgIHB0ciA9IGkgKyAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIiBcIjpcbiAgICAgICAgICBpZiAocHRyID09PSBpKSB7XG4gICAgICAgICAgICBwdHIgPSBpICsgMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGFyZ3MucHVzaChkZWZzLnNsaWNlKHB0ciwgaSkpO1xuXG4gICAgY29uc3QgZnJvbUlkZW50aWZpZXIgPSBmcm9tLnJlcGxhY2UoL1tgXCInW1xcXV0vZywgXCJcIik7XG5cbiAgICBhcmdzID0gYXJncy5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGl0ZW0gPSBpdGVtLnRyaW0oKTtcbiAgICAgIGxldCBzcGxpdCA9IGl0ZW0uc3BsaXQoXCIgXCIpO1xuXG4gICAgICBjb25zdCBmcm9tTWF0Y2hDYW5kaWRhdGVzID0gW1xuICAgICAgICBuZXcgUmVnRXhwKGBcXGAke2Zyb21JZGVudGlmaWVyfVxcYGAsIFwiaVwiKSxcbiAgICAgICAgbmV3IFJlZ0V4cChgXCIke2Zyb21JZGVudGlmaWVyfVwiYCwgXCJpXCIpLFxuICAgICAgICBuZXcgUmVnRXhwKGAnJHtmcm9tSWRlbnRpZmllcn0nYCwgXCJpXCIpLFxuICAgICAgICBuZXcgUmVnRXhwKGBcXFxcWyR7ZnJvbUlkZW50aWZpZXJ9XFxcXF1gLCBcImlcIiksXG4gICAgICBdO1xuICAgICAgaWYgKGZyb21JZGVudGlmaWVyLm1hdGNoKC9eXFxTKyQvKSkge1xuICAgICAgICBmcm9tTWF0Y2hDYW5kaWRhdGVzLnB1c2gobmV3IFJlZ0V4cChgXFxcXGIke2Zyb21JZGVudGlmaWVyfVxcXFxiYCwgXCJpXCIpKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZG9lc01hdGNoRnJvbUlkZW50aWZpZXIgPSAodGFyZ2V0KSA9PlxuICAgICAgICBzb21lKGZyb21NYXRjaENhbmRpZGF0ZXMsIChjKSA9PiB0YXJnZXQubWF0Y2goYykpO1xuXG4gICAgICBjb25zdCByZXBsYWNlRnJvbUlkZW50aWZpZXIgPSAodGFyZ2V0KSA9PlxuICAgICAgICBmcm9tTWF0Y2hDYW5kaWRhdGVzLnJlZHVjZShcbiAgICAgICAgICAocmVzdWx0LCBjYW5kaWRhdGUpID0+IHJlc3VsdC5yZXBsYWNlKGNhbmRpZGF0ZSwgdG8pLFxuICAgICAgICAgIHRhcmdldFxuICAgICAgICApO1xuXG4gICAgICBpZiAoZG9lc01hdGNoRnJvbUlkZW50aWZpZXIoc3BsaXRbMF0pKSB7XG4gICAgICAgIC8vIGNvbHVtbiBkZWZpbml0aW9uXG4gICAgICAgIGlmICh0bykge1xuICAgICAgICAgIHNwbGl0WzBdID0gdG87XG4gICAgICAgICAgcmV0dXJuIHNwbGl0LmpvaW4oXCIgXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIlwiOyAvLyBmb3IgZGVsZXRpb25zXG4gICAgICB9XG5cbiAgICAgIC8vIHNraXAgY29uc3RyYWludCBuYW1lXG4gICAgICBjb25zdCBpZHggPSAvY29uc3RyYWludC9pLnRlc3Qoc3BsaXRbMF0pID8gMiA6IDA7XG5cbiAgICAgIC8vIHByaW1hcnkga2V5IGFuZCB1bmlxdWUgY29uc3RyYWludHMgaGF2ZSBvbmUgb3IgbW9yZVxuICAgICAgLy8gY29sdW1ucyBmcm9tIHRoaXMgdGFibGUgbGlzdGVkIGJldHdlZW4gKCk7IHJlcGxhY2VcbiAgICAgIC8vIG9uZSBpZiBpdCBtYXRjaGVzXG4gICAgICBpZiAoL3ByaW1hcnl8dW5pcXVlL2kudGVzdChzcGxpdFtpZHhdKSkge1xuICAgICAgICBjb25zdCByZXQgPSBpdGVtLnJlcGxhY2UoL1xcKC4qXFwpLywgcmVwbGFjZUZyb21JZGVudGlmaWVyKTtcbiAgICAgICAgLy8gSWYgYW55IG1lbWJlciBjb2x1bW5zIGFyZSBkcm9wcGVkIHRoZW4gdW5pcXVlbmVzcy9wayBjb25zdHJhaW50XG4gICAgICAgIC8vIGNhbiBub3QgYmUgcmV0YWluZWRcbiAgICAgICAgaWYgKHJldCAhPT0gaXRlbSAmJiBpc0VtcHR5KHRvKSkgcmV0dXJuIFwiXCI7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgICB9XG5cbiAgICAgIC8vIGZvcmVpZ24ga2V5cyBoYXZlIG9uZSBvciBtb3JlIGNvbHVtbnMgZnJvbSB0aGlzIHRhYmxlXG4gICAgICAvLyBsaXN0ZWQgYmV0d2VlbiAoKTsgcmVwbGFjZSBvbmUgaWYgaXQgbWF0Y2hlc1xuICAgICAgLy8gZm9yZWlnbiBrZXlzIGFsc28gaGF2ZSBhICdyZWZlcmVuY2VzJyBjbGF1c2VcbiAgICAgIC8vIHdoaWNoIG1heSByZWZlcmVuY2UgVEhJUyB0YWJsZTsgaWYgaXQgZG9lcywgcmVwbGFjZVxuICAgICAgLy8gY29sdW1uIHJlZmVyZW5jZXMgaW4gdGhhdCB0b28hXG4gICAgICBpZiAoL2ZvcmVpZ24vLnRlc3Qoc3BsaXRbaWR4XSkpIHtcbiAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KC8gcmVmZXJlbmNlcyAvaSk7XG4gICAgICAgIC8vIHRoZSBxdW90ZWQgY29sdW1uIG5hbWVzIHNhdmUgdXMgZnJvbSBoYXZpbmcgdG8gZG8gYW55dGhpbmdcbiAgICAgICAgLy8gb3RoZXIgdGhhbiBhIHN0cmFpZ2h0IHJlcGxhY2UgaGVyZVxuICAgICAgICBjb25zdCByZXBsYWNlZEtleVNwZWMgPSByZXBsYWNlRnJvbUlkZW50aWZpZXIoc3BsaXRbMF0pO1xuXG4gICAgICAgIGlmIChzcGxpdFswXSAhPT0gcmVwbGFjZWRLZXlTcGVjKSB7XG4gICAgICAgICAgLy8gSWYgd2UgYXJlIHJlbW92aW5nIG9uZSBvciBtb3JlIGNvbHVtbnMgb2YgYSBmb3JlaWduXG4gICAgICAgICAgLy8ga2V5LCB0aGVuIHdlIHNob3VsZCBub3QgcmV0YWluIHRoZSBrZXkgYXQgYWxsXG4gICAgICAgICAgaWYgKGlzRW1wdHkodG8pKSByZXR1cm4gXCJcIjtcbiAgICAgICAgICBlbHNlIHNwbGl0WzBdID0gcmVwbGFjZWRLZXlTcGVjO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNwbGl0WzFdLnNsaWNlKDAsIHRhYmxlTmFtZS5sZW5ndGgpID09PSB0YWJsZU5hbWUpIHtcbiAgICAgICAgICAvLyBzZWxmLXJlZmVyZW50aWFsIGZvcmVpZ24ga2V5XG4gICAgICAgICAgY29uc3QgcmVwbGFjZWRLZXlUYXJnZXRTcGVjID0gc3BsaXRbMV0ucmVwbGFjZShcbiAgICAgICAgICAgIC9cXCguKlxcKS8sXG4gICAgICAgICAgICByZXBsYWNlRnJvbUlkZW50aWZpZXJcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChzcGxpdFsxXSAhPT0gcmVwbGFjZWRLZXlUYXJnZXRTcGVjKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSBhcmUgcmVtb3Zpbmcgb25lIG9yIG1vcmUgY29sdW1ucyBvZiBhIGZvcmVpZ25cbiAgICAgICAgICAgIC8vIGtleSwgdGhlbiB3ZSBzaG91bGQgbm90IHJldGFpbiB0aGUga2V5IGF0IGFsbFxuICAgICAgICAgICAgaWYgKGlzRW1wdHkodG8pKSByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgIGVsc2Ugc3BsaXRbMV0gPSByZXBsYWNlZEtleVRhcmdldFNwZWM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzcGxpdC5qb2luKFwiIHJlZmVyZW5jZXMgXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9KTtcblxuICAgIGFyZ3MgPSBhcmdzLmZpbHRlcihuZWdhdGUoaXNFbXB0eSkpO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmFibGUgdG8gZHJvcCBsYXN0IGNvbHVtbiBmcm9tIHRhYmxlXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBvbmVMaW5lU3FsXG4gICAgICAucmVwbGFjZSgvXFwoLipcXCkvLCAoKSA9PiBgKCR7YXJncy5qb2luKFwiLCBcIil9KWApXG4gICAgICAucmVwbGFjZSgvLFxccyooWywpXSkvLCBcIiQxXCIpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZpcmViaXJkX0RETDtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFNQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFTZ0IsU0FBQUMsMkJBQUFDLENBQUEsRUFBQUMsQ0FBQSxRQUFBQyxDQUFBLHlCQUFBQyxNQUFBLElBQUFILENBQUEsQ0FBQUcsTUFBQSxDQUFBQyxRQUFBLEtBQUFKLENBQUEscUJBQUFFLENBQUEsUUFBQUcsS0FBQSxDQUFBQyxPQUFBLENBQUFOLENBQUEsTUFBQUUsQ0FBQSxHQUFBSywyQkFBQSxDQUFBUCxDQUFBLE1BQUFDLENBQUEsSUFBQUQsQ0FBQSx1QkFBQUEsQ0FBQSxDQUFBUSxNQUFBLElBQUFOLENBQUEsS0FBQUYsQ0FBQSxHQUFBRSxDQUFBLE9BQUFPLEVBQUEsTUFBQUMsQ0FBQSxZQUFBQSxFQUFBLGVBQUFDLENBQUEsRUFBQUQsQ0FBQSxFQUFBRSxDQUFBLFdBQUFBLEVBQUEsV0FBQUgsRUFBQSxJ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