tedious
Version:
A TDS driver, for connecting to MS SQLServer databases.
141 lines (138 loc) • 17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _iconvLite = _interopRequireDefault(require("iconv-lite"));
var _plpStream = require("./plp-stream");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const MAX = (1 << 16) - 1;
const NULL_LENGTH = Buffer.from([0xFF, 0xFF]);
const MAX_NULL_LENGTH = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
const NO_COLLATION = Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00]);
const VarChar = {
id: 0xA7,
type: 'BIGVARCHR',
name: 'VarChar',
maximumLength: 8000,
declaration: function (parameter) {
const value = parameter.value;
if ((0, _plpStream.isAsyncIterable)(value)) {
return 'varchar(max)';
}
let length;
if (parameter.length) {
length = parameter.length;
} else if (value != null) {
length = value.length || 1;
} else if (value === null && !parameter.output) {
length = 1;
} else {
length = this.maximumLength;
}
if (length <= this.maximumLength) {
return 'varchar(' + length + ')';
} else {
return 'varchar(max)';
}
},
resolveLength: function (parameter) {
const value = parameter.value;
if (parameter.length != null) {
return parameter.length;
} else if (value != null) {
return value.length || 1;
} else {
return this.maximumLength;
}
},
validate: function (value, collation) {
if (value == null) {
return null;
}
if (typeof value !== 'string') {
throw new TypeError('Invalid string.');
}
if (!collation) {
throw new Error('No collation was set by the server for the current connection.');
}
if (!collation.codepage) {
throw new Error('The collation set by the server has no associated encoding.');
}
return _iconvLite.default.encode(value, collation.codepage);
},
resolve(parameter, collation) {
if ((0, _plpStream.isAsyncIterable)(parameter.value)) {
// Read from its source while the request is written, and sent as
// `varchar(max)` since its length is not known up front. The chunks
// are encoded as they arrive, so the collation is checked here, as
// `validate` does for an in-memory value, rather than once the
// request is already being written.
if (!collation) {
throw new Error('No collation was set by the server for the current connection.');
}
if (!collation.codepage) {
throw new Error('The collation set by the server has no associated encoding.');
}
return {
value: parameter.value,
length: MAX,
collation
};
}
const value = this.validate(parameter.value, collation);
const data = {
value
};
data.length = parameter.length != null ? parameter.length : this.resolveLength({
...parameter,
value
});
if (collation) {
data.collation = collation;
}
return data;
},
writeTypeInfo(buffer, parameter) {
buffer.writeUInt8(this.id);
if (parameter.length <= this.maximumLength) {
buffer.writeUInt16LE(parameter.length);
} else {
buffer.writeUInt16LE(MAX);
}
if (parameter.collation) {
buffer.writeBuffer(parameter.collation.toBuffer().subarray(0, 5));
} else {
buffer.writeBuffer(NO_COLLATION);
}
},
writeValue(buffer, parameter) {
if (parameter.value == null) {
buffer.writeBuffer(parameter.length <= this.maximumLength ? NULL_LENGTH : MAX_NULL_LENGTH);
return;
}
// Read from its source while the request is written; `resolve` declared
// it as `varchar(max)` and checked the collation.
if ((0, _plpStream.isAsyncIterable)(parameter.value)) {
const codepage = parameter.collation.codepage;
const encoder = _iconvLite.default.getEncoder(codepage);
return (0, _plpStream.writePlpStream)(buffer, parameter.value, chunk => {
if (typeof chunk !== 'string') {
throw new TypeError('Invalid string.');
}
return encoder.write(chunk);
}, () => encoder.end());
}
// `validate` encoded the value.
const value = parameter.value;
if (parameter.length <= this.maximumLength) {
buffer.writeUInt16LE(value.length);
buffer.writeBuffer(value);
} else {
(0, _plpStream.writePlpValue)(buffer, value);
}
}
};
var _default = exports.default = VarChar;
module.exports = VarChar;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfaWNvbnZMaXRlIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfcGxwU3RyZWFtIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiTUFYIiwiTlVMTF9MRU5HVEgiLCJCdWZmZXIiLCJmcm9tIiwiTUFYX05VTExfTEVOR1RIIiwiTk9fQ09MTEFUSU9OIiwiVmFyQ2hhciIsImlkIiwidHlwZSIsIm5hbWUiLCJtYXhpbXVtTGVuZ3RoIiwiZGVjbGFyYXRpb24iLCJwYXJhbWV0ZXIiLCJ2YWx1ZSIsImlzQXN5bmNJdGVyYWJsZSIsImxlbmd0aCIsIm91dHB1dCIsInJlc29sdmVMZW5ndGgiLCJ2YWxpZGF0ZSIsImNvbGxhdGlvbiIsIlR5cGVFcnJvciIsIkVycm9yIiwiY29kZXBhZ2UiLCJpY29udiIsImVuY29kZSIsInJlc29sdmUiLCJkYXRhIiwid3JpdGVUeXBlSW5mbyIsImJ1ZmZlciIsIndyaXRlVUludDgiLCJ3cml0ZVVJbnQxNkxFIiwid3JpdGVCdWZmZXIiLCJ0b0J1ZmZlciIsInN1YmFycmF5Iiwid3JpdGVWYWx1ZSIsImVuY29kZXIiLCJnZXRFbmNvZGVyIiwid3JpdGVQbHBTdHJlYW0iLCJjaHVuayIsIndyaXRlIiwiZW5kIiwid3JpdGVQbHBWYWx1ZSIsIl9kZWZhdWx0IiwiZXhwb3J0cyIsIm1vZHVsZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhLXR5cGVzL3ZhcmNoYXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGljb252IGZyb20gJ2ljb252LWxpdGUnO1xuXG5pbXBvcnQgeyB0eXBlIERhdGFUeXBlLCB0eXBlIFBhcmFtZXRlckRhdGEgfSBmcm9tICcuLi9kYXRhLXR5cGUnO1xuaW1wb3J0IHsgaXNBc3luY0l0ZXJhYmxlLCB3cml0ZVBscFN0cmVhbSwgd3JpdGVQbHBWYWx1ZSB9IGZyb20gJy4vcGxwLXN0cmVhbSc7XG5cbmNvbnN0IE1BWCA9ICgxIDw8IDE2KSAtIDE7XG5cbmNvbnN0IE5VTExfTEVOR1RIID0gQnVmZmVyLmZyb20oWzB4RkYsIDB4RkZdKTtcbmNvbnN0IE1BWF9OVUxMX0xFTkdUSCA9IEJ1ZmZlci5mcm9tKFsweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGXSk7XG5jb25zdCBOT19DT0xMQVRJT04gPSBCdWZmZXIuZnJvbShbMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMF0pO1xuXG5jb25zdCBWYXJDaGFyOiB7IG1heGltdW1MZW5ndGg6IG51bWJlciB9ICYgRGF0YVR5cGUgPSB7XG4gIGlkOiAweEE3LFxuICB0eXBlOiAnQklHVkFSQ0hSJyxcbiAgbmFtZTogJ1ZhckNoYXInLFxuICBtYXhpbXVtTGVuZ3RoOiA4MDAwLFxuXG4gIGRlY2xhcmF0aW9uOiBmdW5jdGlvbihwYXJhbWV0ZXIpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHBhcmFtZXRlci52YWx1ZSBhcyBCdWZmZXIgfCBudWxsO1xuXG4gICAgaWYgKGlzQXN5bmNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiAndmFyY2hhcihtYXgpJztcbiAgICB9XG5cbiAgICBsZXQgbGVuZ3RoO1xuICAgIGlmIChwYXJhbWV0ZXIubGVuZ3RoKSB7XG4gICAgICBsZW5ndGggPSBwYXJhbWV0ZXIubGVuZ3RoO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgbGVuZ3RoID0gdmFsdWUubGVuZ3RoIHx8IDE7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gbnVsbCAmJiAhcGFyYW1ldGVyLm91dHB1dCkge1xuICAgICAgbGVuZ3RoID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGVuZ3RoID0gdGhpcy5tYXhpbXVtTGVuZ3RoO1xuICAgIH1cblxuICAgIGlmIChsZW5ndGggPD0gdGhpcy5tYXhpbXVtTGVuZ3RoKSB7XG4gICAgICByZXR1cm4gJ3ZhcmNoYXIoJyArIGxlbmd0aCArICcpJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICd2YXJjaGFyKG1heCknO1xuICAgIH1cbiAgfSxcblxuICByZXNvbHZlTGVuZ3RoOiBmdW5jdGlvbihwYXJhbWV0ZXIpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHBhcmFtZXRlci52YWx1ZSBhcyBCdWZmZXIgfCBudWxsO1xuXG4gICAgaWYgKHBhcmFtZXRlci5sZW5ndGggIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHBhcmFtZXRlci5sZW5ndGg7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gdmFsdWUubGVuZ3RoIHx8IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLm1heGltdW1MZW5ndGg7XG4gICAgfVxuICB9LFxuXG4gIHZhbGlkYXRlOiBmdW5jdGlvbih2YWx1ZSwgY29sbGF0aW9uKTogQnVmZmVyIHwgbnVsbCB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHN0cmluZy4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWNvbGxhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb2xsYXRpb24gd2FzIHNldCBieSB0aGUgc2VydmVyIGZvciB0aGUgY3VycmVudCBjb25uZWN0aW9uLicpO1xuICAgIH1cblxuICAgIGlmICghY29sbGF0aW9uLmNvZGVwYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb2xsYXRpb24gc2V0IGJ5IHRoZSBzZXJ2ZXIgaGFzIG5vIGFzc29jaWF0ZWQgZW5jb2RpbmcuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGljb252LmVuY29kZSh2YWx1ZSwgY29sbGF0aW9uLmNvZGVwYWdlKTtcbiAgfSxcblxuICByZXNvbHZlKHBhcmFtZXRlciwgY29sbGF0aW9uKSB7XG4gICAgaWYgKGlzQXN5bmNJdGVyYWJsZShwYXJhbWV0ZXIudmFsdWUpKSB7XG4gICAgICAvLyBSZWFkIGZyb20gaXRzIHNvdXJjZSB3aGlsZSB0aGUgcmVxdWVzdCBpcyB3cml0dGVuLCBhbmQgc2VudCBhc1xuICAgICAgLy8gYHZhcmNoYXIobWF4KWAgc2luY2UgaXRzIGxlbmd0aCBpcyBub3Qga25vd24gdXAgZnJvbnQuIFRoZSBjaHVua3NcbiAgICAgIC8vIGFyZSBlbmNvZGVkIGFzIHRoZXkgYXJyaXZlLCBzbyB0aGUgY29sbGF0aW9uIGlzIGNoZWNrZWQgaGVyZSwgYXNcbiAgICAgIC8vIGB2YWxpZGF0ZWAgZG9lcyBmb3IgYW4gaW4tbWVtb3J5IHZhbHVlLCByYXRoZXIgdGhhbiBvbmNlIHRoZVxuICAgICAgLy8gcmVxdWVzdCBpcyBhbHJlYWR5IGJlaW5nIHdyaXR0ZW4uXG4gICAgICBpZiAoIWNvbGxhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbGxhdGlvbiB3YXMgc2V0IGJ5IHRoZSBzZXJ2ZXIgZm9yIHRoZSBjdXJyZW50IGNvbm5lY3Rpb24uJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghY29sbGF0aW9uLmNvZGVwYWdlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNvbGxhdGlvbiBzZXQgYnkgdGhlIHNlcnZlciBoYXMgbm8gYXNzb2NpYXRlZCBlbmNvZGluZy4nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgdmFsdWU6IHBhcmFtZXRlci52YWx1ZSwgbGVuZ3RoOiBNQVgsIGNvbGxhdGlvbiB9O1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy52YWxpZGF0ZShwYXJhbWV0ZXIudmFsdWUsIGNvbGxhdGlvbik7XG4gICAgY29uc3QgZGF0YTogUGFyYW1ldGVyRGF0YSA9IHsgdmFsdWUgfTtcbiAgICBkYXRhLmxlbmd0aCA9IHBhcmFtZXRlci5sZW5ndGggIT0gbnVsbCA/IHBhcmFtZXRlci5sZW5ndGggOiB0aGlzLnJlc29sdmVMZW5ndGghKHsgLi4ucGFyYW1ldGVyLCB2YWx1ZSB9KTtcbiAgICBpZiAoY29sbGF0aW9uKSB7XG4gICAgICBkYXRhLmNvbGxhdGlvbiA9IGNvbGxhdGlvbjtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH0sXG5cbiAgd3JpdGVUeXBlSW5mbyhidWZmZXIsIHBhcmFtZXRlcikge1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHRoaXMuaWQpO1xuXG4gICAgaWYgKHBhcmFtZXRlci5sZW5ndGghIDw9IHRoaXMubWF4aW11bUxlbmd0aCkge1xuICAgICAgYnVmZmVyLndyaXRlVUludDE2TEUocGFyYW1ldGVyLmxlbmd0aCEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBidWZmZXIud3JpdGVVSW50MTZMRShNQVgpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbWV0ZXIuY29sbGF0aW9uKSB7XG4gICAgICBidWZmZXIud3JpdGVCdWZmZXIocGFyYW1ldGVyLmNvbGxhdGlvbi50b0J1ZmZlcigpLnN1YmFycmF5KDAsIDUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyLndyaXRlQnVmZmVyKE5PX0NPTExBVElPTik7XG4gICAgfVxuICB9LFxuXG4gIHdyaXRlVmFsdWUoYnVmZmVyLCBwYXJhbWV0ZXIpIHtcbiAgICBpZiAocGFyYW1ldGVyLnZhbHVlID09IG51bGwpIHtcbiAgICAgIGJ1ZmZlci53cml0ZUJ1ZmZlcihwYXJhbWV0ZXIubGVuZ3RoISA8PSB0aGlzLm1heGltdW1MZW5ndGggPyBOVUxMX0xFTkdUSCA6IE1BWF9OVUxMX0xFTkdUSCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmVhZCBmcm9tIGl0cyBzb3VyY2Ugd2hpbGUgdGhlIHJlcXVlc3QgaXMgd3JpdHRlbjsgYHJlc29sdmVgIGRlY2xhcmVkXG4gICAgLy8gaXQgYXMgYHZhcmNoYXIobWF4KWAgYW5kIGNoZWNrZWQgdGhlIGNvbGxhdGlvbi5cbiAgICBpZiAoaXNBc3luY0l0ZXJhYmxlKHBhcmFtZXRlci52YWx1ZSkpIHtcbiAgICAgIGNvbnN0IGNvZGVwYWdlID0gcGFyYW1ldGVyLmNvbGxhdGlvbiEuY29kZXBhZ2UhO1xuICAgICAgY29uc3QgZW5jb2RlciA9IGljb252LmdldEVuY29kZXIoY29kZXBhZ2UpO1xuICAgICAgcmV0dXJuIHdyaXRlUGxwU3RyZWFtKFxuICAgICAgICBidWZmZXIsXG4gICAgICAgIHBhcmFtZXRlci52YWx1ZSxcbiAgICAgICAgKGNodW5rKSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgc3RyaW5nLicpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBlbmNvZGVyLndyaXRlKGNodW5rKTtcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4gZW5jb2Rlci5lbmQoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBgdmFsaWRhdGVgIGVuY29kZWQgdGhlIHZhbHVlLlxuICAgIGNvbnN0IHZhbHVlID0gcGFyYW1ldGVyLnZhbHVlIGFzIEJ1ZmZlcjtcbiAgICBpZiAocGFyYW1ldGVyLmxlbmd0aCEgPD0gdGhpcy5tYXhpbXVtTGVuZ3RoKSB7XG4gICAgICBidWZmZXIud3JpdGVVSW50MTZMRSh2YWx1ZS5sZW5ndGgpO1xuICAgICAgYnVmZmVyLndyaXRlQnVmZmVyKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd3JpdGVQbHBWYWx1ZShidWZmZXIsIHZhbHVlKTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFZhckNoYXI7XG5tb2R1bGUuZXhwb3J0cyA9IFZhckNoYXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQUFBLFVBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUdBLElBQUFDLFVBQUEsR0FBQUQsT0FBQTtBQUE4RSxTQUFBRCx1QkFBQUcsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQUU5RSxNQUFNRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUM7QUFFekIsTUFBTUMsV0FBVyxHQUFHQyxNQUFNLENBQUNDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM3QyxNQUFNQyxlQUFlLEdBQUdGLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3JGLE1BQU1FLFlBQVksR0FBR0gsTUFBTSxDQUFDQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFFaEUsTUFBTUcsT0FBNkMsR0FBRztFQUNwREMsRUFBRSxFQUFFLElBQUk7RUFDUkMsSUFBSSxFQUFFLFdBQVc7RUFDakJDLElBQUksRUFBRSxTQUFTO0VBQ2ZDLGFBQWEsRUFBRSxJQUFJO0VBRW5CQyxXQUFXLEVBQUUsU0FBQUEsQ0FBU0MsU0FBUyxFQUFFO0lBQy9CLE1BQU1DLEtBQUssR0FBR0QsU0FBUyxDQUFDQyxLQUFzQjtJQUU5QyxJQUFJLElBQUFDLDBCQUFlLEVBQUNELEtBQUssQ0FBQyxFQUFFO01BQzFCLE9BQU8sY0FBYztJQUN2QjtJQUVBLElBQUlFLE1BQU07SUFDVixJQUFJSCxTQUFTLENBQUNHLE1BQU0sRUFBRTtNQUNwQkEsTUFBTSxHQUFHSCxTQUFTLENBQUNHLE1BQU07SUFDM0IsQ0FBQyxNQUFNLElBQUlGLEtBQUssSUFBSSxJQUFJLEVBQUU7TUFDeEJFLE1BQU0sR0FBR0YsS0FBSyxDQUFDRSxNQUFNLElBQUksQ0FBQztJQUM1QixDQUFDLE1BQU0sSUFBSUYsS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDRCxTQUFTLENBQUNJLE1BQU0sRUFBRTtNQUM5Q0QsTUFBTSxHQUFHLENBQUM7SUFDWixDQUFDLE1BQU07TUFDTEEsTUFBTSxHQUFHLElBQUksQ0FBQ0wsYUFBYTtJQUM3QjtJQUVBLElBQUlLLE1BQU0sSUFBSSxJQUFJLENBQUNMLGFBQWEsRUFBRTtNQUNoQyxPQUFPLFVBQVUsR0FBR0ssTUFBTSxHQUFHLEdBQUc7SUFDbEMsQ0FBQyxNQUFNO01BQ0wsT0FBTyxjQUFjO0lBQ3ZCO0VBQ0YsQ0FBQztFQUVERSxhQUFhLEVBQUUsU0FBQUEsQ0FBU0wsU0FBUyxFQUFFO0lBQ2pDLE1BQU1DLEtBQUssR0FBR0QsU0FBUyxDQUFDQyxLQUFzQjtJQUU5QyxJQUFJRCxTQUFTLENBQUNHLE1BQU0sSUFBSSxJQUFJLEVBQUU7TUFDNUIsT0FBT0gsU0FBUyxDQUFDRyxNQUFNO0lBQ3pCLENBQUMsTUFBTSxJQUFJRixLQUFLLElBQUksSUFBSSxFQUFFO01BQ3hCLE9BQU9BLEtBQUssQ0FBQ0UsTUFBTSxJQUFJLENBQUM7SUFDMUIsQ0FBQyxNQUFNO01BQ0wsT0FBTyxJQUFJLENBQUNMLGFBQWE7SUFDM0I7RUFDRixDQUFDO0VBRURRLFFBQVEsRUFBRSxTQUFBQSxDQUFTTCxLQUFLLEVBQUVNLFNBQVMsRUFBaUI7SUFDbEQsSUFBSU4sS0FBSyxJQUFJLElBQUksRUFBRTtNQUNqQixPQUFPLElBQUk7SUFDYjtJQUVBLElBQUksT0FBT0EsS0FBSyxLQUFLLFFBQVEsRUFBRTtNQUM3QixNQUFNLElBQUlPLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQztJQUN4QztJQUVBLElBQUksQ0FBQ0QsU0FBUyxFQUFFO01BQ2QsTUFBTSxJQUFJRSxLQUFLLENBQUMsZ0VBQWdFLENBQUM7SUFDbkY7SUFFQSxJQUFJLENBQUNGLFNBQVMsQ0FBQ0csUUFBUSxFQUFFO01BQ3ZCLE1BQU0sSUFBSUQsS0FBSyxDQUFDLDZEQUE2RCxDQUFDO0lBQ2hGO0lBRUEsT0FBT0Usa0JBQUssQ0FBQ0MsTUFBTSxDQUFDWCxLQUFLLEVBQUVNLFNBQVMsQ0FBQ0csUUFBUSxDQUFDO0VBQ2hELENBQUM7RUFFREcsT0FBT0EsQ0FBQ2IsU0FBUyxFQUFFTyxTQUFTLEVBQUU7SUFDNUIsSUFBSSxJQUFBTCwwQkFBZSxFQUFDRixTQUFTLENBQUNDLEtBQUssQ0FBQyxFQUFFO01BQ3BDO01BQ0E7TUFDQTtNQUNBO01BQ0E7TUFDQSxJQUFJLENBQUNNLFNBQVMsRUFBRTtRQUNkLE1BQU0sSUFBSUUsS0FBSyxDQUFDLGdFQUFnRSxDQUFDO01BQ25GO01BRUEsSUFBSSxDQUFDRixTQUFTLENBQUNHLFFBQVEsRUFBRTtRQUN2QixNQUFNLElBQUlELEtBQUssQ0FBQyw2REFBNkQsQ0FBQztNQUNoRjtNQUVBLE9BQU87UUFBRVIsS0FBSyxFQUFFRCxTQUFTLENBQUNDLEtBQUs7UUFBRUUsTUFBTSxFQUFFZixHQUFHO1FBQUVtQjtNQUFVLENBQUM7SUFDM0Q7SUFFQSxNQUFNTixLQUFLLEdBQUcsSUFBSSxDQUFDSyxRQUFRLENBQUNOLFNBQVMsQ0FBQ0MsS0FBSyxFQUFFTSxTQUFTLENBQUM7SUFDdkQsTUFBTU8sSUFBbUIsR0FBRztNQUFFYjtJQUFNLENBQUM7SUFDckNhLElBQUksQ0FBQ1gsTUFBTSxHQUFHSCxTQUFTLENBQUNHLE1BQU0sSUFBSSxJQUFJLEdBQUdILFNBQVMsQ0FBQ0csTUFBTSxHQUFHLElBQUksQ0FBQ0UsYUFBYSxDQUFFO01BQUUsR0FBR0wsU0FBUztNQUFFQztJQUFNLENBQUMsQ0FBQztJQUN4RyxJQUFJTSxTQUFTLEVBQUU7TUFDYk8sSUFBSSxDQUFDUCxTQUFTLEdBQUdBLFNBQVM7SUFDNUI7SUFDQSxPQUFPTyxJQUFJO0VBQ2IsQ0FBQztFQUVEQyxhQUFhQSxDQUFDQyxNQUFNLEVBQUVoQixTQUFTLEVBQUU7SUFDL0JnQixNQUFNLENBQUNDLFVBQVUsQ0FBQyxJQUFJLENBQUN0QixFQUFFLENBQUM7SUFFMUIsSUFBSUssU0FBUyxDQUFDRyxNQUFNLElBQUssSUFBSSxDQUFDTCxhQUFhLEVBQUU7TUFDM0NrQixNQUFNLENBQUNFLGFBQWEsQ0FBQ2xCLFNBQVMsQ0FBQ0csTUFBTyxDQUFDO0lBQ3pDLENBQUMsTUFBTTtNQUNMYSxNQUFNLENBQUNFLGFBQWEsQ0FBQzlCLEdBQUcsQ0FBQztJQUMzQjtJQUVBLElBQUlZLFNBQVMsQ0FBQ08sU0FBUyxFQUFFO01BQ3ZCUyxNQUFNLENBQUNHLFdBQVcsQ0FBQ25CLFNBQVMsQ0FBQ08sU0FBUyxDQUFDYSxRQUFRLENBQUMsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ25FLENBQUMsTUFBTTtNQUNMTCxNQUFNLENBQUNHLFdBQVcsQ0FBQzFCLFlBQVksQ0FBQztJQUNsQztFQUNGLENBQUM7RUFFRDZCLFVBQVVBLENBQUNOLE1BQU0sRUFBRWhCLFNBQVMsRUFBRTtJQUM1QixJQUFJQSxTQUFTLENBQUNDLEtBQUssSUFBSSxJQUFJLEVBQUU7TUFDM0JlLE1BQU0sQ0FBQ0csV0FBVyxDQUFDbkIsU0FBUyxDQUFDRyxNQUFNLElBQUssSUFBSSxDQUFDTCxhQUFhLEdBQUdULFdBQVcsR0FBR0csZUFBZSxDQUFDO01BQzNGO0lBQ0Y7O0lBRUE7SUFDQTtJQUNBLElBQUksSUFBQVUsMEJBQWUsRUFBQ0YsU0FBUyxDQUFDQyxLQUFLLENBQUMsRUFBRTtNQUNwQyxNQUFNUyxRQUFRLEdBQUdWLFNBQVMsQ0FBQ08sU0FBUyxDQUFFRyxRQUFTO01BQy9DLE1BQU1hLE9BQU8sR0FBR1osa0JBQUssQ0FBQ2EsVUFBVSxDQUFDZCxRQUFRLENBQUM7TUFDMUMsT0FBTyxJQUFBZSx5QkFBYyxFQUNuQlQsTUFBTSxFQUNOaEIsU0FBUyxDQUFDQyxLQUFLLEVBQ2R5QixLQUFLLElBQUs7UUFDVCxJQUFJLE9BQU9BLEtBQUssS0FBSyxRQUFRLEVBQUU7VUFDN0IsTUFBTSxJQUFJbEIsU0FBUyxDQUFDLGlCQUFpQixDQUFDO1FBQ3hDO1FBRUEsT0FBT2UsT0FBTyxDQUFDSSxLQUFLLENBQUNELEtBQUssQ0FBQztNQUM3QixDQUFDLEVBQ0QsTUFBTUgsT0FBTyxDQUFDSyxHQUFHLENBQUMsQ0FDcEIsQ0FBQztJQUNIOztJQUVBO0lBQ0EsTUFBTTNCLEtBQUssR0FBR0QsU0FBUyxDQUFDQyxLQUFlO0lBQ3ZDLElBQUlELFNBQVMsQ0FBQ0csTUFBTSxJQUFLLElBQUksQ0FBQ0wsYUFBYSxFQUFFO01BQzNDa0IsTUFBTSxDQUFDRSxhQUFhLENBQUNqQixLQUFLLENBQUNFLE1BQU0sQ0FBQztNQUNsQ2EsTUFBTSxDQUFDRyxXQUFXLENBQUNsQixLQUFLLENBQUM7SUFDM0IsQ0FBQyxNQUFNO01BQ0wsSUFBQTRCLHdCQUFhLEVBQUNiLE1BQU0sRUFBRWYsS0FBSyxDQUFDO0lBQzlCO0VBQ0Y7QUFDRixDQUFDO0FBQUMsSUFBQTZCLFFBQUEsR0FBQUMsT0FBQSxDQUFBNUMsT0FBQSxHQUVhTyxPQUFPO0FBQ3RCc0MsTUFBTSxDQUFDRCxPQUFPLEdBQUdyQyxPQUFPIiwiaWdub3JlTGlzdCI6W119