forked from zhurui/management
553 lines
57 KiB
JavaScript
553 lines
57 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
exports.__esModule = true;
|
||
|
|
||
|
var _declaration = require('./declaration');
|
||
|
|
||
|
var _declaration2 = _interopRequireDefault(_declaration);
|
||
|
|
||
|
var _tokenize = require('./tokenize');
|
||
|
|
||
|
var _tokenize2 = _interopRequireDefault(_tokenize);
|
||
|
|
||
|
var _comment = require('./comment');
|
||
|
|
||
|
var _comment2 = _interopRequireDefault(_comment);
|
||
|
|
||
|
var _atRule = require('./at-rule');
|
||
|
|
||
|
var _atRule2 = _interopRequireDefault(_atRule);
|
||
|
|
||
|
var _root = require('./root');
|
||
|
|
||
|
var _root2 = _interopRequireDefault(_root);
|
||
|
|
||
|
var _rule = require('./rule');
|
||
|
|
||
|
var _rule2 = _interopRequireDefault(_rule);
|
||
|
|
||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
|
||
|
var Parser = function () {
|
||
|
function Parser(input) {
|
||
|
_classCallCheck(this, Parser);
|
||
|
|
||
|
this.input = input;
|
||
|
|
||
|
this.root = new _root2.default();
|
||
|
this.current = this.root;
|
||
|
this.spaces = '';
|
||
|
this.semicolon = false;
|
||
|
|
||
|
this.createTokenizer();
|
||
|
this.root.source = { input: input, start: { line: 1, column: 1 } };
|
||
|
}
|
||
|
|
||
|
Parser.prototype.createTokenizer = function createTokenizer() {
|
||
|
this.tokenizer = (0, _tokenize2.default)(this.input);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.parse = function parse() {
|
||
|
var token = void 0;
|
||
|
while (!this.tokenizer.endOfFile()) {
|
||
|
token = this.tokenizer.nextToken();
|
||
|
|
||
|
switch (token[0]) {
|
||
|
|
||
|
case 'space':
|
||
|
this.spaces += token[1];
|
||
|
break;
|
||
|
|
||
|
case ';':
|
||
|
this.freeSemicolon(token);
|
||
|
break;
|
||
|
|
||
|
case '}':
|
||
|
this.end(token);
|
||
|
break;
|
||
|
|
||
|
case 'comment':
|
||
|
this.comment(token);
|
||
|
break;
|
||
|
|
||
|
case 'at-word':
|
||
|
this.atrule(token);
|
||
|
break;
|
||
|
|
||
|
case '{':
|
||
|
this.emptyRule(token);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
this.other(token);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
this.endFile();
|
||
|
};
|
||
|
|
||
|
Parser.prototype.comment = function comment(token) {
|
||
|
var node = new _comment2.default();
|
||
|
this.init(node, token[2], token[3]);
|
||
|
node.source.end = { line: token[4], column: token[5] };
|
||
|
|
||
|
var text = token[1].slice(2, -2);
|
||
|
if (/^\s*$/.test(text)) {
|
||
|
node.text = '';
|
||
|
node.raws.left = text;
|
||
|
node.raws.right = '';
|
||
|
} else {
|
||
|
var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/);
|
||
|
node.text = match[2];
|
||
|
node.raws.left = match[1];
|
||
|
node.raws.right = match[3];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Parser.prototype.emptyRule = function emptyRule(token) {
|
||
|
var node = new _rule2.default();
|
||
|
this.init(node, token[2], token[3]);
|
||
|
node.selector = '';
|
||
|
node.raws.between = '';
|
||
|
this.current = node;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.other = function other(start) {
|
||
|
var end = false;
|
||
|
var type = null;
|
||
|
var colon = false;
|
||
|
var bracket = null;
|
||
|
var brackets = [];
|
||
|
|
||
|
var tokens = [];
|
||
|
var token = start;
|
||
|
while (token) {
|
||
|
type = token[0];
|
||
|
tokens.push(token);
|
||
|
|
||
|
if (type === '(' || type === '[') {
|
||
|
if (!bracket) bracket = token;
|
||
|
brackets.push(type === '(' ? ')' : ']');
|
||
|
} else if (brackets.length === 0) {
|
||
|
if (type === ';') {
|
||
|
if (colon) {
|
||
|
this.decl(tokens);
|
||
|
return;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
} else if (type === '{') {
|
||
|
this.rule(tokens);
|
||
|
return;
|
||
|
} else if (type === '}') {
|
||
|
this.tokenizer.back(tokens.pop());
|
||
|
end = true;
|
||
|
break;
|
||
|
} else if (type === ':') {
|
||
|
colon = true;
|
||
|
}
|
||
|
} else if (type === brackets[brackets.length - 1]) {
|
||
|
brackets.pop();
|
||
|
if (brackets.length === 0) bracket = null;
|
||
|
}
|
||
|
|
||
|
token = this.tokenizer.nextToken();
|
||
|
}
|
||
|
|
||
|
if (this.tokenizer.endOfFile()) end = true;
|
||
|
if (brackets.length > 0) this.unclosedBracket(bracket);
|
||
|
|
||
|
if (end && colon) {
|
||
|
while (tokens.length) {
|
||
|
token = tokens[tokens.length - 1][0];
|
||
|
if (token !== 'space' && token !== 'comment') break;
|
||
|
this.tokenizer.back(tokens.pop());
|
||
|
}
|
||
|
this.decl(tokens);
|
||
|
return;
|
||
|
} else {
|
||
|
this.unknownWord(tokens);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Parser.prototype.rule = function rule(tokens) {
|
||
|
tokens.pop();
|
||
|
|
||
|
var node = new _rule2.default();
|
||
|
this.init(node, tokens[0][2], tokens[0][3]);
|
||
|
|
||
|
node.raws.between = this.spacesAndCommentsFromEnd(tokens);
|
||
|
this.raw(node, 'selector', tokens);
|
||
|
this.current = node;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.decl = function decl(tokens) {
|
||
|
var node = new _declaration2.default();
|
||
|
this.init(node);
|
||
|
|
||
|
var last = tokens[tokens.length - 1];
|
||
|
if (last[0] === ';') {
|
||
|
this.semicolon = true;
|
||
|
tokens.pop();
|
||
|
}
|
||
|
if (last[4]) {
|
||
|
node.source.end = { line: last[4], column: last[5] };
|
||
|
} else {
|
||
|
node.source.end = { line: last[2], column: last[3] };
|
||
|
}
|
||
|
|
||
|
while (tokens[0][0] !== 'word') {
|
||
|
if (tokens.length === 1) this.unknownWord(tokens);
|
||
|
node.raws.before += tokens.shift()[1];
|
||
|
}
|
||
|
node.source.start = { line: tokens[0][2], column: tokens[0][3] };
|
||
|
|
||
|
node.prop = '';
|
||
|
while (tokens.length) {
|
||
|
var type = tokens[0][0];
|
||
|
if (type === ':' || type === 'space' || type === 'comment') {
|
||
|
break;
|
||
|
}
|
||
|
node.prop += tokens.shift()[1];
|
||
|
}
|
||
|
|
||
|
node.raws.between = '';
|
||
|
|
||
|
var token = void 0;
|
||
|
while (tokens.length) {
|
||
|
token = tokens.shift();
|
||
|
|
||
|
if (token[0] === ':') {
|
||
|
node.raws.between += token[1];
|
||
|
break;
|
||
|
} else {
|
||
|
node.raws.between += token[1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (node.prop[0] === '_' || node.prop[0] === '*') {
|
||
|
node.raws.before += node.prop[0];
|
||
|
node.prop = node.prop.slice(1);
|
||
|
}
|
||
|
node.raws.between += this.spacesAndCommentsFromStart(tokens);
|
||
|
this.precheckMissedSemicolon(tokens);
|
||
|
|
||
|
for (var i = tokens.length - 1; i > 0; i--) {
|
||
|
token = tokens[i];
|
||
|
if (token[1].toLowerCase() === '!important') {
|
||
|
node.important = true;
|
||
|
var string = this.stringFrom(tokens, i);
|
||
|
string = this.spacesFromEnd(tokens) + string;
|
||
|
if (string !== ' !important') node.raws.important = string;
|
||
|
break;
|
||
|
} else if (token[1].toLowerCase() === 'important') {
|
||
|
var cache = tokens.slice(0);
|
||
|
var str = '';
|
||
|
for (var j = i; j > 0; j--) {
|
||
|
var _type = cache[j][0];
|
||
|
if (str.trim().indexOf('!') === 0 && _type !== 'space') {
|
||
|
break;
|
||
|
}
|
||
|
str = cache.pop()[1] + str;
|
||
|
}
|
||
|
if (str.trim().indexOf('!') === 0) {
|
||
|
node.important = true;
|
||
|
node.raws.important = str;
|
||
|
tokens = cache;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (token[0] !== 'space' && token[0] !== 'comment') {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.raw(node, 'value', tokens);
|
||
|
|
||
|
if (node.value.indexOf(':') !== -1) this.checkMissedSemicolon(tokens);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.atrule = function atrule(token) {
|
||
|
var node = new _atRule2.default();
|
||
|
node.name = token[1].slice(1);
|
||
|
if (node.name === '') {
|
||
|
this.unnamedAtrule(node, token);
|
||
|
}
|
||
|
this.init(node, token[2], token[3]);
|
||
|
|
||
|
var prev = void 0;
|
||
|
var shift = void 0;
|
||
|
var last = false;
|
||
|
var open = false;
|
||
|
var params = [];
|
||
|
|
||
|
while (!this.tokenizer.endOfFile()) {
|
||
|
token = this.tokenizer.nextToken();
|
||
|
|
||
|
if (token[0] === ';') {
|
||
|
node.source.end = { line: token[2], column: token[3] };
|
||
|
this.semicolon = true;
|
||
|
break;
|
||
|
} else if (token[0] === '{') {
|
||
|
open = true;
|
||
|
break;
|
||
|
} else if (token[0] === '}') {
|
||
|
if (params.length > 0) {
|
||
|
shift = params.length - 1;
|
||
|
prev = params[shift];
|
||
|
while (prev && prev[0] === 'space') {
|
||
|
prev = params[--shift];
|
||
|
}
|
||
|
if (prev) {
|
||
|
node.source.end = { line: prev[4], column: prev[5] };
|
||
|
}
|
||
|
}
|
||
|
this.end(token);
|
||
|
break;
|
||
|
} else {
|
||
|
params.push(token);
|
||
|
}
|
||
|
|
||
|
if (this.tokenizer.endOfFile()) {
|
||
|
last = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
node.raws.between = this.spacesAndCommentsFromEnd(params);
|
||
|
if (params.length) {
|
||
|
node.raws.afterName = this.spacesAndCommentsFromStart(params);
|
||
|
this.raw(node, 'params', params);
|
||
|
if (last) {
|
||
|
token = params[params.length - 1];
|
||
|
node.source.end = { line: token[4], column: token[5] };
|
||
|
this.spaces = node.raws.between;
|
||
|
node.raws.between = '';
|
||
|
}
|
||
|
} else {
|
||
|
node.raws.afterName = '';
|
||
|
node.params = '';
|
||
|
}
|
||
|
|
||
|
if (open) {
|
||
|
node.nodes = [];
|
||
|
this.current = node;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Parser.prototype.end = function end(token) {
|
||
|
if (this.current.nodes && this.current.nodes.length) {
|
||
|
this.current.raws.semicolon = this.semicolon;
|
||
|
}
|
||
|
this.semicolon = false;
|
||
|
|
||
|
this.current.raws.after = (this.current.raws.after || '') + this.spaces;
|
||
|
this.spaces = '';
|
||
|
|
||
|
if (this.current.parent) {
|
||
|
this.current.source.end = { line: token[2], column: token[3] };
|
||
|
this.current = this.current.parent;
|
||
|
} else {
|
||
|
this.unexpectedClose(token);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Parser.prototype.endFile = function endFile() {
|
||
|
if (this.current.parent) this.unclosedBlock();
|
||
|
if (this.current.nodes && this.current.nodes.length) {
|
||
|
this.current.raws.semicolon = this.semicolon;
|
||
|
}
|
||
|
this.current.raws.after = (this.current.raws.after || '') + this.spaces;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.freeSemicolon = function freeSemicolon(token) {
|
||
|
this.spaces += token[1];
|
||
|
if (this.current.nodes) {
|
||
|
var prev = this.current.nodes[this.current.nodes.length - 1];
|
||
|
if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) {
|
||
|
prev.raws.ownSemicolon = this.spaces;
|
||
|
this.spaces = '';
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Helpers
|
||
|
|
||
|
Parser.prototype.init = function init(node, line, column) {
|
||
|
this.current.push(node);
|
||
|
|
||
|
node.source = { start: { line: line, column: column }, input: this.input };
|
||
|
node.raws.before = this.spaces;
|
||
|
this.spaces = '';
|
||
|
if (node.type !== 'comment') this.semicolon = false;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.raw = function raw(node, prop, tokens) {
|
||
|
var token = void 0,
|
||
|
type = void 0;
|
||
|
var length = tokens.length;
|
||
|
var value = '';
|
||
|
var clean = true;
|
||
|
var next = void 0,
|
||
|
prev = void 0;
|
||
|
var pattern = /^([.|#])?([\w])+/i;
|
||
|
|
||
|
for (var i = 0; i < length; i += 1) {
|
||
|
token = tokens[i];
|
||
|
type = token[0];
|
||
|
|
||
|
if (type === 'comment' && node.type === 'rule') {
|
||
|
prev = tokens[i - 1];
|
||
|
next = tokens[i + 1];
|
||
|
|
||
|
if (prev[0] !== 'space' && next[0] !== 'space' && pattern.test(prev[1]) && pattern.test(next[1])) {
|
||
|
value += token[1];
|
||
|
} else {
|
||
|
clean = false;
|
||
|
}
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (type === 'comment' || type === 'space' && i === length - 1) {
|
||
|
clean = false;
|
||
|
} else {
|
||
|
value += token[1];
|
||
|
}
|
||
|
}
|
||
|
if (!clean) {
|
||
|
var raw = tokens.reduce(function (all, i) {
|
||
|
return all + i[1];
|
||
|
}, '');
|
||
|
node.raws[prop] = { value: value, raw: raw };
|
||
|
}
|
||
|
node[prop] = value;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.spacesAndCommentsFromEnd = function spacesAndCommentsFromEnd(tokens) {
|
||
|
var lastTokenType = void 0;
|
||
|
var spaces = '';
|
||
|
while (tokens.length) {
|
||
|
lastTokenType = tokens[tokens.length - 1][0];
|
||
|
if (lastTokenType !== 'space' && lastTokenType !== 'comment') break;
|
||
|
spaces = tokens.pop()[1] + spaces;
|
||
|
}
|
||
|
return spaces;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.spacesAndCommentsFromStart = function spacesAndCommentsFromStart(tokens) {
|
||
|
var next = void 0;
|
||
|
var spaces = '';
|
||
|
while (tokens.length) {
|
||
|
next = tokens[0][0];
|
||
|
if (next !== 'space' && next !== 'comment') break;
|
||
|
spaces += tokens.shift()[1];
|
||
|
}
|
||
|
return spaces;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.spacesFromEnd = function spacesFromEnd(tokens) {
|
||
|
var lastTokenType = void 0;
|
||
|
var spaces = '';
|
||
|
while (tokens.length) {
|
||
|
lastTokenType = tokens[tokens.length - 1][0];
|
||
|
if (lastTokenType !== 'space') break;
|
||
|
spaces = tokens.pop()[1] + spaces;
|
||
|
}
|
||
|
return spaces;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.stringFrom = function stringFrom(tokens, from) {
|
||
|
var result = '';
|
||
|
for (var i = from; i < tokens.length; i++) {
|
||
|
result += tokens[i][1];
|
||
|
}
|
||
|
tokens.splice(from, tokens.length - from);
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.colon = function colon(tokens) {
|
||
|
var brackets = 0;
|
||
|
var token = void 0,
|
||
|
type = void 0,
|
||
|
prev = void 0;
|
||
|
for (var i = 0; i < tokens.length; i++) {
|
||
|
token = tokens[i];
|
||
|
type = token[0];
|
||
|
|
||
|
if (type === '(') {
|
||
|
brackets += 1;
|
||
|
} else if (type === ')') {
|
||
|
brackets -= 1;
|
||
|
} else if (brackets === 0 && type === ':') {
|
||
|
if (!prev) {
|
||
|
this.doubleColon(token);
|
||
|
} else if (prev[0] === 'word' && prev[1] === 'progid') {
|
||
|
continue;
|
||
|
} else {
|
||
|
return i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
prev = token;
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
// Errors
|
||
|
|
||
|
Parser.prototype.unclosedBracket = function unclosedBracket(bracket) {
|
||
|
throw this.input.error('Unclosed bracket', bracket[2], bracket[3]);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.unknownWord = function unknownWord(tokens) {
|
||
|
throw this.input.error('Unknown word', tokens[0][2], tokens[0][3]);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.unexpectedClose = function unexpectedClose(token) {
|
||
|
throw this.input.error('Unexpected }', token[2], token[3]);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.unclosedBlock = function unclosedBlock() {
|
||
|
var pos = this.current.source.start;
|
||
|
throw this.input.error('Unclosed block', pos.line, pos.column);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.doubleColon = function doubleColon(token) {
|
||
|
throw this.input.error('Double colon', token[2], token[3]);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.unnamedAtrule = function unnamedAtrule(node, token) {
|
||
|
throw this.input.error('At-rule without name', token[2], token[3]);
|
||
|
};
|
||
|
|
||
|
Parser.prototype.precheckMissedSemicolon = function precheckMissedSemicolon(tokens) {
|
||
|
// Hook for Safe Parser
|
||
|
tokens;
|
||
|
};
|
||
|
|
||
|
Parser.prototype.checkMissedSemicolon = function checkMissedSemicolon(tokens) {
|
||
|
var colon = this.colon(tokens);
|
||
|
if (colon === false) return;
|
||
|
|
||
|
var founded = 0;
|
||
|
var token = void 0;
|
||
|
for (var j = colon - 1; j >= 0; j--) {
|
||
|
token = tokens[j];
|
||
|
if (token[0] !== 'space') {
|
||
|
founded += 1;
|
||
|
if (founded === 2) break;
|
||
|
}
|
||
|
}
|
||
|
throw this.input.error('Missed semicolon', token[2], token[3]);
|
||
|
};
|
||
|
|
||
|
return Parser;
|
||
|
}();
|
||
|
|
||
|
exports.default = Parser;
|
||
|
module.exports = exports['default'];
|
||
|
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhcnNlci5lczYiXSwibmFtZXMiOlsiUGFyc2VyIiwiaW5wdXQiLCJyb290IiwiUm9vdCIsImN1cnJlbnQiLCJzcGFjZXMiLCJzZW1pY29sb24iLCJjcmVhdGVUb2tlbml6ZXIiLCJzb3VyY2UiLCJzdGFydCIsImxpbmUiLCJjb2x1bW4iLCJ0b2tlbml6ZXIiLCJwYXJzZSIsInRva2VuIiwiZW5kT2ZGaWxlIiwibmV4dFRva2VuIiwiZnJlZVNlbWljb2xvbiIsImVuZCIsImNvbW1lbnQiLCJhdHJ1bGUiLCJlbXB0eVJ1bGUiLCJvdGhlciIsImVuZEZpbGUiLCJub2RlIiwiQ29tbWVudCIsImluaXQiLCJ0ZXh0Iiwic2xpY2UiLCJ0ZXN0IiwicmF3cyIsImxlZnQiLCJyaWdodCIsIm1hdGNoIiwiUnVsZSIsInNlbGVjdG9yIiwiYmV0d2VlbiIsInR5cGUiLCJjb2xvbiIsImJyYWNrZXQiLCJicmFja2V0cyIsInRva2VucyIsInB1c2giLCJsZW5ndGgiLCJkZWNsIiwicnVsZSIsImJhY2siLCJwb3AiLCJ1bmNsb3NlZEJyYWNrZXQiLCJ1bmtub3duV29yZCIsInNwYWNlc0FuZENvbW1lbnRzRnJvbUVuZCIsInJhdyIsIkRlY2xhcmF0aW9uIiwibGFzdCIsImJlZm9yZSIsInNoaWZ0IiwicHJvcCIsInNwYWNlc0FuZENvbW1lbnRzRnJvbVN0YXJ0IiwicHJlY2hlY2tNaXNzZWRTZW1pY29sb24iLCJpIiwidG9Mb3dlckNhc2UiLCJpbXBvcnRhbnQiLCJzdHJpbmciLCJzdHJpbmdGcm9tIiwic3BhY2VzRnJvbUVuZCIsImNhY2hlIiwic3RyIiwiaiIsInRyaW0iLCJpbmRleE9mIiwidmFsdWUiLCJjaGVja01pc3NlZFNlbWljb2xvbiIsIkF0UnVsZSIsIm5hbWUiLCJ1bm5hbWVkQXRydWxlIiwicHJldiIsIm9wZW4iLCJwYXJhbXMiLCJhZnRlck5hbWUiLCJub2RlcyIsImFmdGVyIiwicGFyZW50IiwidW5leHBlY3RlZENsb3NlIiwidW5jbG9zZWRCbG9jayIsIm93blNlbWljb2xvbiIsImNsZWFuIiwibmV4dCIsInBhdHRlcm4iLCJyZWR1Y2UiLCJhbGwiLCJsYXN0VG9rZW5UeXBlIiwiZnJvbSIsInJlc3VsdCIsInNwbGljZSIsImRvdWJsZUNvbG9uIiwiZXJyb3IiLCJwb3MiLCJmb3VuZGVkIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7OztJQUVxQkEsTTtBQUVqQixvQkFBWUMsS0FBWixFQUFtQjtBQUFBOztBQUNmLGFBQUtBLEtBQUwsR0FBYUEsS0FBYjs7QUFFQSxhQUFLQyxJQUFMLEdBQWlCLElBQUlDLGNBQUosRUFBakI7QUFDQSxhQUFLQyxPQUFMLEdBQWlCLEtBQUtGLElBQXRCO0FBQ0EsYUFBS0csTUFBTCxHQUFpQixFQUFqQjtBQUNBLGFBQUtDLFNBQUwsR0FBaUIsS0FBakI7O0FBRUEsYUFBS0MsZUFBTDtBQUNBLGFBQUtMLElBQUwsQ0FBVU0sTUFBVixHQUFtQixFQUFFUCxZQUFGLEVBQVNRLE9BQU8sRUFBRUMsTUFBTSxDQUFSLEVBQVdDLFFBQVEsQ0FBbkIsRUFBaEIsRUFBbkI7QUFDSDs7cUJBRURKLGUsOEJBQWtCO0FBQ2QsYUFBS0ssU0FBTCxHQUFpQix3QkFBVSxLQUFLWCxLQUFmLENBQWpCO0FBQ0gsSzs7cUJBRURZLEssb0JBQVE7QUFDSixZQUFJQyxjQUFKO0FBQ0EsZUFBUSxDQUFDLEtBQUtGLFNBQUwsQ0FBZUcsU0FBZixFQUFULEVBQXNDO0FBQ2xDRCxvQkFBUSxLQUFLRixTQUFMLENBQWVJLFNBQWYsRUFBUjs7QUFFQSxvQkFBU0YsTUFBTSxDQUFOLENBQVQ7O0FBRUEscUJBQUssT0FBTDtBQUNJLHlCQUFLVCxNQUFMLElBQWVTLE1BQU0sQ0FBTixDQUFmO0FBQ0E7O0FBRUoscUJBQUssR0FBTDtBQUNJLHlCQUFLRyxhQUFMLENBQW1CSCxLQUFuQjtBQUNBOztBQUVKLHFCQUFLLEdBQUw7QUFDSSx5QkFBS0ksR0FBTCxDQUFTSixLQUFUO0FBQ0E7O0FBRUoscUJBQUssU0FBTDtBQUNJLHlCQUFLSyxPQUFMLENBQWFMLEtBQWI7QUFDQTs7QUFFSixxQkFBSyxTQUFMO0FBQ0kseUJBQUtNLE1BQUwsQ0FBWU4sS0FBWjtBQUNBOztBQUVKLHFCQUFLLEdBQUw7QUFDSSx5QkFBS08sU0FBTCxDQUFlUCxLQUFmO0FBQ0E7O0FBRUo7QUFDSSx5QkFBS1EsS0FBTCxDQUFXUixLQUFYO0FBQ0E7QUE1Qko7QUE4Qkg7QUFDRCxhQUFLUyxPQUFMO0FBQ0gsSzs7cUJBRURKLE8sb0JBQVFMLEssRUFBTztBQUNYLFlBQUlVLE9BQU8sSUFBSUMsaUJBQUosRUFBWDtBQUNBLGFBQUtDLElBQUwsQ0FBVUYsSUFBVixFQUFnQlYsTUFBTSxDQUFOLENBQWhCLEVBQTBCQSxNQUFNLENBQU4sQ0FBMUI7QUFDQVUsYUFBS2hCLE1BQUwsQ0FBWVUsR0FBWixHQUFrQixFQUFFUixNQUFNSSxNQUFNLENBQU4sQ0FBUixFQUFrQkgsUUFBUUcsTUFBTSxDQUFOLENBQTFCLEVBQWxCOztBQUVBLFlBQUlhLE9BQU9iLE1BQU0sQ0FBTixFQUFTYyxLQUFULENBQWUsQ0FBZixFQUFrQixDQUFDLENBQW5CLENBQVg7QUFDQSxZQUFLLFFBQVFDLElBQVIsQ0FBYUYsSUFBYixDQUFMLEVBQTBCO0FBQ3RCSCxpQkFBS0csSUFBTCxHQUFrQixFQUFsQjtBQUNBSCxpQkFBS00sSUFBTCxDQUFVQyxJQUFWLEdBQWtCSixJQUFsQjtBQUNBSCxpQkFBS00sSUFBTCxDQUFVRSxLQUFWLEdBQWtCLEVBQWxCO0FBQ0gsU0FKRCxNQUlPO0FBQ0gsZ0JBQUlDLFFBQVFOLEtBQUtNLEtBQUwsQ0FBVyx5QkFBWCxDQUFaO0FBQ0FULGlCQUFLRyxJQUFMLEdBQWtCTSxNQUFNLENBQU4sQ0FBbEI7QUFDQVQsaUJBQUtNLElBQUwsQ0FBVUMsSUFBVixHQUFrQkUsTUFBTSxDQUFOLENBQWxCO0FBQ0FULGlCQUFLTSxJQUFMLENBQVVFLEtBQVYsR0FBa0JDLE1BQU0sQ0FBTixDQUFsQjtBQUNIO0FBQ0osSzs7cUJBRURaLFMsc0JBQVVQLEssRUFBTztBQUNiLFlBQUlVLE9BQU8sSUFBSVUsY0FBSixFQUFYO0FBQ0EsYUFBS1IsSUFBTCxDQUFVRixJQUFWLEVBQWdCVixNQUFNLENBQU4sQ0FBaEIsRUFBMEJBLE1BQU0sQ0FBTixDQUExQjtBQUNBVSxhQUFLVyxRQUFMLEdBQWdCLEVBQWhCO0FBQ0FYLGFBQUtNLElBQUwsQ0FBVU0sT0FBVixHQUFvQixFQUFwQjtBQUNBLGFBQUtoQyxPQUFMLEdBQWVvQixJQUFmO0FBQ0gsSzs7cUJBRURGLEssa0JBQU1iLEssRUFBTztBQUNULFlBQUlTLE1BQVcsS0FBZjtBQUNBLFlBQUltQixPQUFXLElBQWY7QUFDQSxZQUFJQyxRQUFXLEtBQWY7QUFDQSxZ
|