UNPKG

objection

Version:
155 lines (130 loc) 19.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _jsonFieldExpressionParser = require('../../parsers/jsonFieldExpressionParser'); var _jsonFieldExpressionParser2 = _interopRequireDefault(_jsonFieldExpressionParser); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @typedef {String} FieldExpression * * Field expressions allow one to refer to separate JSONB fields inside columns. * * Syntax: <column reference>[:<json field reference>] * * e.g. `Person.jsonColumnName:details.names[1]` would refer to value `'Second'` * in column `Person.jsonColumnName` which has * `{ details: { names: ['First', 'Second', 'Last'] } }` object stored in it. * * First part `<column reference>` is compatible with column references used in * knex e.g. `MyFancyTable.tributeToThBestColumnNameEver`. * * Second part describes a path to an attribute inside the referred column. * It is optional and it always starts with colon which follows directly with * first path element. e.g. `Table.jsonObjectColumnName:jsonFieldName` or * `Table.jsonArrayColumn:[321]`. * * Syntax supports `[<key or index>]` and `.<key or index>` flavors of reference * to json keys / array indexes: * * e.g. both `Table.myColumn:[1][3]` and `Table.myColumn:1.3` would access correctly * both of the following objects `[null, [null,null,null, "I was accessed"]]` and * `{ "1": { "3" : "I was accessed" } }` * * Caveats when using special characters in keys: * * 1. `objectColumn.key` This is the most common syntax, good if you are * not using dots or square brackets `[]` in your json object key name. * 2. Keys containing dots `objectColumn:[keywith.dots]` Column `{ "keywith.dots" : "I was referred" }` * 3. Keys containing square brackets `column['[]']` `{ "[]" : "This is getting ridiculous..." }` * 4. Keys containing square brackets and quotes * `objectColumn:['Double."Quote".[]']` and `objectColumn:["Sinlge.'Quote'.[]"]` * Column `{ "Double.\"Quote\".[]" : "I was referred", "Single.'Quote'.[]" : "Mee too!" }` * 99. Keys containing dots, square brackets, single quotes and double quotes in one json key is * not currently supported */ exports.default = { parseFieldExpression: parseFieldExpression, whereJsonbRefOnLeftJsonbValOrRefOnRight: whereJsonbRefOnLeftJsonbValOrRefOnRight, whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams: whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams, whereJsonFieldRightStringArrayOnLeftQuery: whereJsonFieldRightStringArrayOnLeftQuery, whereJsonFieldQuery: whereJsonFieldQuery }; function parseFieldExpression(expression, extractAsText) { var parsed = _jsonFieldExpressionParser2.default.parse(expression); var jsonRefs = (0, _lodash2.default)(parsed.access).map('ref').value().join(","); var extractor = extractAsText ? '#>>' : '#>'; var middleQuotedColumnName = parsed.columnName.split('.').join('"."'); return '"' + middleQuotedColumnName + '"' + extractor + '\'{' + jsonRefs + '}\''; } function whereJsonbRefOnLeftJsonbValOrRefOnRight(builder, fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { var queryParams = whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix); return builder.whereRaw.apply(builder, queryParams); } function whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { var fieldReference = parseFieldExpression(fieldExpression); if (_lodash2.default.isString(jsonObjectOrFieldExpression)) { var rightHandReference = parseFieldExpression(jsonObjectOrFieldExpression); var refRefQuery = ["(", fieldReference, ")::jsonb", operator, "(", rightHandReference, ")::jsonb"]; if (queryPrefix) { refRefQuery.unshift(queryPrefix); } return [refRefQuery.join(" ")]; } else if (_lodash2.default.isObject(jsonObjectOrFieldExpression)) { var refValQuery = ["(", fieldReference, ")::jsonb", operator, "?::jsonb"]; if (queryPrefix) { refValQuery.unshift(queryPrefix); } return [refValQuery.join(" "), (0, _stringify2.default)(jsonObjectOrFieldExpression)]; } throw new Error("Invalid right hand expression."); } function whereJsonFieldRightStringArrayOnLeftQuery(builder, fieldExpression, operator, keys) { var knex = builder._knex; var fieldReference = parseFieldExpression(fieldExpression); keys = _lodash2.default.isArray(keys) ? keys : [keys]; var questionMarksArray = _lodash2.default.map(keys, function (key) { if (!_lodash2.default.isString(key)) { throw new Error("All keys to find must be strings."); } return "?"; }); var rawSqlTemplateString = "array[" + questionMarksArray.join(",") + "]"; var rightHandExpression = knex.raw(rawSqlTemplateString, keys); return fieldReference + ' ' + operator.replace('?', '\\?') + ' ' + rightHandExpression; } function whereJsonFieldQuery(knex, fieldExpression, operator, value) { var fieldReference = parseFieldExpression(fieldExpression, true); var normalizedOperator = normalizeOperator(knex, operator); // json type comparison takes json type in string format var cast = void 0; var escapedValue = knex.raw(" ?", [value]); if (_lodash2.default.isNumber(value)) { cast = "::NUMERIC"; } else if (_lodash2.default.isBoolean(value)) { cast = "::BOOLEAN"; } else if (_lodash2.default.isString(value)) { cast = "::TEXT"; } else if (_lodash2.default.isNull(value)) { cast = "::TEXT"; escapedValue = 'NULL'; } else { throw new Error("Value must be string, number, boolean or null."); } return '(' + fieldReference + ')' + cast + ' ' + normalizedOperator + ' ' + escapedValue; } function normalizeOperator(knex, operator) { var trimmedLowerCase = operator.trim().toLowerCase(); switch (trimmedLowerCase) { case "is": case "is not": return trimmedLowerCase; default: return knex.client.formatter().operator(operator); } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBvc3RncmVzSnNvbkFwaS5qcyJdLCJuYW1lcyI6WyJwYXJzZUZpZWxkRXhwcmVzc2lvbiIsIndoZXJlSnNvbmJSZWZPbkxlZnRKc29uYlZhbE9yUmVmT25SaWdodCIsIndoZXJlSnNvbmJSZWZPbkxlZnRKc29uYlZhbE9yUmVmT25SaWdodFJhd1F1ZXJ5UGFyYW1zIiwid2hlcmVKc29uRmllbGRSaWdodFN0cmluZ0FycmF5T25MZWZ0UXVlcnkiLCJ3aGVyZUpzb25GaWVsZFF1ZXJ5IiwiZXhwcmVzc2lvbiIsImV4dHJhY3RBc1RleHQiLCJwYXJzZWQiLCJwYXJzZSIsImpzb25SZWZzIiwiYWNjZXNzIiwibWFwIiwidmFsdWUiLCJqb2luIiwiZXh0cmFjdG9yIiwibWlkZGxlUXVvdGVkQ29sdW1uTmFtZSIsImNvbHVtbk5hbWUiLCJzcGxpdCIsImJ1aWxkZXIiLCJmaWVsZEV4cHJlc3Npb24iLCJvcGVyYXRvciIsImpzb25PYmplY3RPckZpZWxkRXhwcmVzc2lvbiIsInF1ZXJ5UHJlZml4IiwicXVlcnlQYXJhbXMiLCJ3aGVyZVJhdyIsImFwcGx5IiwiZmllbGRSZWZlcmVuY2UiLCJpc1N0cmluZyIsInJpZ2h0SGFuZFJlZmVyZW5jZSIsInJlZlJlZlF1ZXJ5IiwidW5zaGlmdCIsImlzT2JqZWN0IiwicmVmVmFsUXVlcnkiLCJFcnJvciIsImtleXMiLCJrbmV4IiwiX2tuZXgiLCJpc0FycmF5IiwicXVlc3Rpb25NYXJrc0FycmF5Iiwia2V5IiwicmF3U3FsVGVtcGxhdGVTdHJpbmciLCJyaWdodEhhbmRFeHByZXNzaW9uIiwicmF3IiwicmVwbGFjZSIsIm5vcm1hbGl6ZWRPcGVyYXRvciIsIm5vcm1hbGl6ZU9wZXJhdG9yIiwiY2FzdCIsImVzY2FwZWRWYWx1ZSIsImlzTnVtYmVyIiwiaXNCb29sZWFuIiwiaXNOdWxsIiwidHJpbW1lZExvd2VyQ2FzZSIsInRyaW0iLCJ0b0xvd2VyQ2FzZSIsImNsaWVudCIsImZvcm1hdHRlciJdLCJtYXBwaW5ncyI6Ijs7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QUFDRCxHQUhNLE1BR0E7QUFDTCxVQUFNLElBQUlkLEtBQUosQ0FBVSxnREFBVixDQUFOO0FBQ0Q7O0FBRUQsZUFBV1AsY0FBWCxTQUE2Qm9CLElBQTdCLFNBQXFDRixrQkFBckMsU0FBMkRHLFlBQTNEO0FBQ0Q7O0FBRUQsU0FBU0YsaUJBQVQsQ0FBMkJWLElBQTNCLEVBQWlDZixRQUFqQyxFQUEyQztBQUN6QyxNQUFJK0IsbUJBQW1CL0IsU0FBU2dDLElBQVQsR0FBZ0JDLFdBQWhCLEVBQXZCOztBQUVBLFVBQVFGLGdCQUFSO0FBQ0UsU0FBSyxJQUFMO0FBQ0EsU0FBSyxRQUFMO0FBQ0UsYUFBT0EsZ0JBQVA7QUFDRjtBQUNFLGFBQU9oQixLQUFLbUIsTUFBTCxDQUFZQyxTQUFaLEdBQXdCbkMsUUFBeEIsQ0FBaUNBLFFBQWpDLENBQVA7QUFMSjtBQU9EIiwiZmlsZSI6InBvc3RncmVzSnNvbkFwaS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQganNvbkZpZWxkRXhwcmVzc2lvblBhcnNlciBmcm9tICcuLi8uLi9wYXJzZXJzL2pzb25GaWVsZEV4cHJlc3Npb25QYXJzZXInO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtTdHJpbmd9IEZpZWxkRXhwcmVzc2lvblxuICpcbiAqIEZpZWxkIGV4cHJlc3Npb25zIGFsbG93IG9uZSB0byByZWZlciB0byBzZXBhcmF0ZSBKU09OQiBmaWVsZHMgaW5zaWRlIGNvbHVtbnMuXG4gKlxuICogU3ludGF4OiA8Y29sdW1uIHJlZmVyZW5jZT5bOjxqc29uIGZpZWxkIHJlZmVyZW5jZT5dXG4gKlxuICogZS5nLiBgUGVyc29uLmpzb25Db2x1bW5OYW1lOmRldGFpbHMubmFtZXNbMV1gIHdvdWxkIHJlZmVyIHRvIHZhbHVlIGAnU2Vjb25kJ2BcbiAqIGluIGNvbHVtbiBgUGVyc29uLmpzb25Db2x1bW5OYW1lYCB3aGljaCBoYXNcbiAqIGB7IGRldGFpbHM6IHsgbmFtZXM6IFsnRmlyc3QnLCAnU2Vjb25kJywgJ0xhc3QnXSB9IH1gIG9iamVjdCBzdG9yZWQgaW4gaXQuXG4gKlxuICogRmlyc3QgcGFydCBgPGNvbHVtbiByZWZlcmVuY2U+YCBpcyBjb21wYXRpYmxlIHdpdGggY29sdW1uIHJlZmVyZW5jZXMgdXNlZCBpblxuICoga25leCBlLmcuIGBNeUZhbmN5VGFibGUudHJpYnV0ZVRvVGhCZXN0Q29sdW1uTmFtZUV2ZXJgLlxuICpcbiAqIFNlY29uZCBwYXJ0IGRlc2NyaWJlcyBhIHBhdGggdG8gYW4gYXR0cmlidXRlIGluc2lkZSB0aGUgcmVmZXJyZWQgY29sdW1uLlxuICogSXQgaXMgb3B0aW9uYWwgYW5kIGl0IGFsd2F5cyBzdGFydHMgd2l0aCBjb2xvbiB3aGljaCBmb2xsb3dzIGRpcmVjdGx5IHdpdGhcbiAqIGZpcnN0IHBhdGggZWxlbWVudC4gZS5nLiBgVGFibGUuanNvbk9iamVjdENvbHVtbk5hbWU6anNvbkZpZWxkTmFtZWAgb3JcbiAqIGBUYWJsZS5qc29uQXJyYXlDb2x1bW46WzMyMV1gLlxuICpcbiAqIFN5bnRheCBzdXBwb3J0cyBgWzxrZXkgb3IgaW5kZXg+XWAgYW5kIGAuPGtleSBvciBpbmRleD5gIGZsYXZvcnMgb2YgcmVmZXJlbmNlXG4gKiB0byBqc29uIGtleXMgLyBhcnJheSBpbmRleGVzOlxuICpcbiAqIGUuZy4gYm90aCBgVGFibGUubXlDb2x1bW46WzFdWzNdYCBhbmQgYFRhYmxlLm15Q29sdW1uOjEuM2Agd291bGQgYWNjZXNzIGNvcnJlY3RseVxuICogYm90aCBvZiB0aGUgZm9sbG93aW5nIG9iamVjdHMgYFtudWxsLCBbbnVsbCxudWxsLG51bGwsIFwiSSB3YXMgYWNjZXNzZWRcIl1dYCBhbmRcbiAqIGB7IFwiMVwiOiB7IFwiM1wiIDogXCJJIHdhcyBhY2Nlc3NlZFwiIH0gfWBcbiAqXG4gKiBDYXZlYXRzIHdoZW4gdXNpbmcgc3BlY2lhbCBjaGFyYWN0ZXJzIGluIGtleXM6XG4gKlxuICogMS4gYG9iamVjdENvbHVtbi5rZXlgIFRoaXMgaXMgdGhlIG1vc3QgY29tbW9uIHN5bnRheCwgZ29vZCBpZiB5b3UgYXJlXG4gKiAgICBub3QgdXNpbmcgZG90cyBvciBzcXVhcmUgYnJhY2tldHMgYFtdYCBpbiB5b3VyIGpzb24gb2JqZWN0IGtleSBuYW1lLlxuICogMi4gS2V5cyBjb250YWluaW5nIGRvdHMgYG9iamVjdENvbHVtbjpba2V5d2l0aC5kb3RzXWAgQ29sdW1uIGB7IFwia2V5d2l0aC5kb3RzXCIgOiBcIkkgd2FzIHJlZmVycmVkXCIgfWBcbiAqIDMuIEtleXMgY29udGFpbmluZyBzcXVhcmUgYnJhY2tldHMgYGNvbHVtblsnW10nXWAgYHsgXCJbXVwiIDogXCJUaGlzIGlzIGdldHRpbmcgcmlkaWN1bG91cy4uLlwiIH1gXG4gKiA0LiBLZXlzIGNvbnRhaW5pbmcgc3F1YXJlIGJyYWNrZXRzIGFuZCBxdW90ZXNcbiAqICAgIGBvYmplY3RDb2x1bW46WydEb3VibGUuXCJRdW90ZVwiLltdJ11gIGFuZCBgb2JqZWN0Q29sdW1uOltcIlNpbmxnZS4nUXVvdGUnLltdXCJdYFxuICogICAgQ29sdW1uIGB7IFwiRG91YmxlLlxcXCJRdW90ZVxcXCIuW11cIiA6IFwiSSB3YXMgcmVmZXJyZWRcIiwgIFwiU2luZ2xlLidRdW90ZScuW11cIiA6IFwiTWVlIHRvbyFcIiB9YFxuICogOTkuIEtleXMgY29udGFpbmluZyBkb3RzLCBzcXVhcmUgYnJhY2tldHMsIHNpbmdsZSBxdW90ZXMgYW5kIGRvdWJsZSBxdW90ZXMgaW4gb25lIGpzb24ga2V5IGlzXG4gKiAgICAgbm90IGN1cnJlbnRseSBzdXBwb3J0ZWRcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIHBhcnNlRmllbGRFeHByZXNzaW9uLFxuICB3aGVyZUpzb25iUmVmT25MZWZ0SnNvbmJWYWxPclJlZk9uUmlnaHQsXG4gIHdoZXJlSnNvbmJSZWZPbkxlZnRKc29uYlZhbE9yUmVmT25SaWdodFJhd1F1ZXJ5UGFyYW1zLFxuICB3aGVyZUpzb25GaWVsZFJpZ2h0U3RyaW5nQXJyYXlPbkxlZnRRdWVyeSxcbiAgd2hlcmVKc29uRmllbGRRdWVyeVxufVxuXG5mdW5jdGlvbiBwYXJzZUZpZWxkRXhwcmVzc2lvbihleHByZXNzaW9uLCBleHRyYWN0QXNUZXh0KSB7XG4gIGxldCBwYXJzZWQgPSBqc29uRmllbGRFeHByZXNzaW9uUGFyc2VyLnBhcnNlKGV4cHJlc3Npb24pO1xuICBsZXQganNvblJlZnMgPSBfKHBhcnNlZC5hY2Nlc3MpLm1hcCgncmVmJykudmFsdWUoKS5qb2luKFwiLFwiKTtcbiAgbGV0IGV4dHJhY3RvciA9IGV4dHJhY3RBc1RleHQgPyAnIz4+JyA6ICcjPic7XG4gIGxldCBtaWRkbGVRdW90ZWRDb2x1bW5OYW1lID0gcGFyc2VkLmNvbHVtbk5hbWUuc3BsaXQoJy4nKS5qb2luKCdcIi5cIicpO1xuICByZXR1cm4gYFwiJHttaWRkbGVRdW90ZWRDb2x1bW5OYW1lfVwiJHtleHRyYWN0b3J9J3ske2pzb25SZWZzfX0nYDtcbn1cblxuZnVuY3Rpb24gd2hlcmVKc29uYlJlZk9uTGVmdEpzb25iVmFsT3JSZWZPblJpZ2h0KGJ1aWxkZXIsIGZpZWxkRXhwcmVzc2lvbiwgb3BlcmF0b3IsIGpzb25PYmplY3RPckZpZWxkRXhwcmVzc2lvbiwgcXVlcnlQcmVmaXgpIHtcbiAgbGV0IHF1ZXJ5UGFyYW1zID0gd2hlcmVKc29uYlJlZk9uTGVmdEpzb25iVmFsT3JSZWZPblJpZ2h0UmF3UXVlcnlQYXJhbXMoZmllbGRFeHByZXNzaW9uLCBvcGVyYXRvciwganNvbk9iamVjdE9yRmllbGRFeHByZXNzaW9uLCBxdWVyeVByZWZpeCk7XG4gIHJldHVybiBidWlsZGVyLndoZXJlUmF3LmFwcGx5KGJ1aWxkZXIsIHF1ZXJ5UGFyYW1zKTtcbn1cblxuZnVuY3Rpb24gd2hlcmVKc29uYlJlZk9uTGVmdEpzb25iVmFsT3JSZWZPblJpZ2h0UmF3UXVlcnlQYXJhbXMoZmllbGRFeHByZXNzaW9uLCBvcGVyYXRvciwganNvbk9iamVjdE9yRmllbGRFeHByZXNzaW9uLCBxdWVyeVByZWZpeCkge1xuICBsZXQgZmllbGRSZWZlcmVuY2UgPSBwYXJzZUZpZWxkRXhwcmVzc2lvbihmaWVsZEV4cHJlc3Npb24pO1xuXG4gIGlmIChfLmlzU3RyaW5nKGpzb25PYmplY3RPckZpZWxkRXhwcmVzc2lvbikpIHtcbiAgICBsZXQgcmlnaHRIYW5kUmVmZXJlbmNlID0gcGFyc2VGaWVsZEV4cHJlc3Npb24oanNvbk9iamVjdE9yRmllbGRFeHByZXNzaW9uKTtcbiAgICBsZXQgcmVmUmVmUXVlcnkgPSBbXCIoXCIsIGZpZWxkUmVmZXJlbmNlLCBcIik6Ompzb25iXCIsIG9wZXJhdG9yLCBcIihcIiwgcmlnaHRIYW5kUmVmZXJlbmNlLCBcIik6Ompzb25iXCJdO1xuICAgIGlmIChxdWVyeVByZWZpeCkge1xuICAgICAgcmVmUmVmUXVlcnkudW5zaGlmdChxdWVyeVByZWZpeCk7XG4gICAgfVxuICAgIHJldHVybiBbcmVmUmVmUXVlcnkuam9pbihcIiBcIildO1xuICB9IGVsc2UgaWYgKF8uaXNPYmplY3QoanNvbk9iamVjdE9yRmllbGRFeHByZXNzaW9uKSkge1xuICAgIGxldCByZWZWYWxRdWVyeSA9IFtcIihcIiwgZmllbGRSZWZlcmVuY2UsIFwiKTo6anNvbmJcIiwgb3BlcmF0b3IsIFwiPzo6anNvbmJcIl07XG4gICAgaWYgKHF1ZXJ5UHJlZml4KSB7XG4gICAgICByZWZWYWxRdWVyeS51bnNoaWZ0KHF1ZXJ5UHJlZml4KTtcbiAgICB9XG4gICAgcmV0dXJuIFtyZWZWYWxRdWVyeS5qb2luKFwiIFwiKSwgSlNPTi5zdHJpbmdpZnkoanNvbk9iamVjdE9yRmllbGRFeHByZXNzaW9uKV07XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHJpZ2h0IGhhbmQgZXhwcmVzc2lvbi5cIik7XG59XG5cbmZ1bmN0aW9uIHdoZXJlSnNvbkZpZWxkUmlnaHRTdHJpbmdBcnJheU9uTGVmdFF1ZXJ5KGJ1aWxkZXIsIGZpZWxkRXhwcmVzc2lvbiwgb3BlcmF0b3IsIGtleXMpIHtcbiAgbGV0IGtuZXggPSBidWlsZGVyLl9rbmV4O1xuICBsZXQgZmllbGRSZWZlcmVuY2UgPSBwYXJzZUZpZWxkRXhwcmVzc2lvbihmaWVsZEV4cHJlc3Npb24pO1xuICBrZXlzID0gXy5pc0FycmF5KGtleXMpID8ga2V5cyA6IFtrZXlzXTtcblxuICBsZXQgcXVlc3Rpb25NYXJrc0FycmF5ID0gXy5tYXAoa2V5cywgZnVuY3Rpb24gKGtleSkge1xuICAgIGlmICghXy5pc1N0cmluZyhrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBbGwga2V5cyB0byBmaW5kIG11c3QgYmUgc3RyaW5ncy5cIik7XG4gICAgfVxuICAgIHJldHVybiBcIj9cIjtcbiAgfSk7XG5cbiAgbGV0IHJhd1NxbFRlbXBsYXRlU3RyaW5nID0gXCJhcnJheVtcIiArIHF1ZXN0aW9uTWFya3NBcnJheS5qb2luKFwiLFwiKSArIFwiXVwiO1xuICBsZXQgcmlnaHRIYW5kRXhwcmVzc2lvbiA9IGtuZXgucmF3KHJhd1NxbFRlbXBsYXRlU3RyaW5nLCBrZXlzKTtcblxuICByZXR1cm4gYCR7ZmllbGRSZWZlcmVuY2V9ICR7b3BlcmF0b3IucmVwbGFjZSgnPycsICdcXFxcPycpfSAke3JpZ2h0SGFuZEV4cHJlc3Npb259YDtcbn1cblxuZnVuY3Rpb24gd2hlcmVKc29uRmllbGRRdWVyeShrbmV4LCBmaWVsZEV4cHJlc3Npb24sIG9wZXJhdG9yLCB2YWx1ZSkge1xuICBsZXQgZmllbGRSZWZlcmVuY2UgPSBwYXJzZUZpZWxkRXhwcmVzc2lvbihmaWVsZEV4cHJlc3Npb24sIHRydWUpO1xuICBsZXQgbm9ybWFsaXplZE9wZXJhdG9yID0gbm9ybWFsaXplT3BlcmF0b3Ioa25leCwgb3BlcmF0b3IpO1xuXG4gIC8vIGpzb24gdHlwZSBjb21wYXJpc29uIHRha2VzIGpzb24gdHlwZSBpbiBzdHJpbmcgZm9ybWF0XG4gIGxldCBjYXN0O1xuICBsZXQgZXNjYXBlZFZhbHVlID0ga25leC5yYXcoXCIgP1wiLCBbdmFsdWVdKTtcbiAgaWYgKF8uaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgY2FzdCA9IFwiOjpOVU1FUklDXCI7XG4gIH0gZWxzZSBpZiAoXy5pc0Jvb2xlYW4odmFsdWUpKSB7XG4gICAgY2FzdCA9IFwiOjpCT09MRUFOXCI7XG4gIH0gZWxzZSBpZiAoXy5pc1N0cmluZyh2YWx1ZSkpIHtcbiAgICBjYXN0ID0gXCI6OlRFWFRcIjtcbiAgfSBlbHNlIGlmIChfLmlzTnVsbCh2YWx1ZSkpIHtcbiAgICBjYXN0ID0gXCI6OlRFWFRcIjtcbiAgICBlc2NhcGVkVmFsdWUgPSAnTlVMTCc7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVmFsdWUgbXVzdCBiZSBzdHJpbmcsIG51bWJlciwgYm9vbGVhbiBvciBudWxsLlwiKTtcbiAgfVxuXG4gIHJldHVybiBgKCR7ZmllbGRSZWZlcmVuY2V9KSR7Y2FzdH0gJHtub3JtYWxpemVkT3BlcmF0b3J9ICR7ZXNjYXBlZFZhbHVlfWA7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZU9wZXJhdG9yKGtuZXgsIG9wZXJhdG9yKSB7XG4gIGxldCB0cmltbWVkTG93ZXJDYXNlID0gb3BlcmF0b3IudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG5cbiAgc3dpdGNoICh0cmltbWVkTG93ZXJDYXNlKSB7XG4gICAgY2FzZSBcImlzXCI6XG4gICAgY2FzZSBcImlzIG5vdFwiOlxuICAgICAgcmV0dXJuIHRyaW1tZWRMb3dlckNhc2U7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBrbmV4LmNsaWVudC5mb3JtYXR0ZXIoKS5vcGVyYXRvcihvcGVyYXRvcik7XG4gIH1cbn1cbiJdfQ==