Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@microsoft/bf-lu

Package Overview
Dependencies
Maintainers
2
Versions
197
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@microsoft/bf-lu - npm Package Compare versions

Comparing version 4.9.1 to 4.10.0-dev.20200714.6b8b8a9

lib/parser/utils/enums/invalidchars.js

46

lib/parser/cross-train/cross-train.js

@@ -10,4 +10,2 @@ "use strict";

const fileExtEnum = require('../utils/helpers').FileExtTypeEnum;
const exception = require('../utils/exception');
const retCode = require('../utils/enums/CLI-errors');
const crossTrainer = require('./crossTrainer');

@@ -31,48 +29,14 @@ const confighelper = require('./confighelper');

* @param {string} config path to config of mapping rules or mapping rules json content itself. If undefined, it will read config.json from input folder.
* @param {boolean} verbose verbose to indicate whether log warnings and errors or not when parsing cross-train files.
* @returns {luResult: any, qnaResult: any} trainedResult of luResult and qnaResult or undefined if no results.
*/
train: async function (input, intentName, config) {
train: async function (input, intentName, config, verbose) {
// Get all related file content.
const luContents = await file.getFilesContent(input, fileExtEnum.LUFile);
const qnaContents = await file.getFilesContent(input, fileExtEnum.QnAFile);
const configContent = config && !fs.existsSync(config) ? { id: path.join(input, 'config.json'), content: config } : await file.getConfigContent(config || input);
const configObject = file.getConfigObject(configContent, intentName);
const trainedResult = crossTrainer.crossTrain(luContents, qnaContents, configObject);
const configContent = config && !fs.existsSync(config) ? { id: path.join(input, 'config.json'), content: config } : await file.getConfigContent(config);
const configObject = file.getConfigObject(configContent, intentName, verbose);
const trainedResult = await crossTrainer.crossTrain(luContents, qnaContents, configObject);
return trainedResult;
},
/**
* Write lu and qna files
* @param {Map<string, any>} fileIdToLuResourceMap lu or qna file id to lu resource map.
* @param {string} out output folder name. If not specified, source lu and qna files will be updated.
* @throws {exception} Throws on errors.
*/
writeFiles: async function (fileIdToLuResourceMap, out) {
if (fileIdToLuResourceMap) {
let newFolder;
if (out) {
newFolder = out;
if (!path.isAbsolute(out)) {
newFolder = path.resolve(out);
}
if (!fs.existsSync(newFolder)) {
fs.mkdirSync(newFolder);
}
}
for (const fileId of fileIdToLuResourceMap.keys()) {
try {
if (newFolder) {
const fileName = path.basename(fileId);
const newFileId = path.join(newFolder, fileName);
await fs.writeFile(newFileId, fileIdToLuResourceMap.get(fileId).Content, 'utf-8');
}
else {
await fs.writeFile(fileId, fileIdToLuResourceMap.get(fileId).Content, 'utf-8');
}
}
catch (err) {
throw (new exception(retCode.errorCode.OUTPUT_FOLDER_INVALID, `Unable to write to file ${fileId}. Error: ${err.message}`));
}
}
}
}
};

@@ -7,2 +7,3 @@ "use strict";

const helpers = require('../utils/helpers');
const fileExtEnum = require('../utils/helpers').FileExtTypeEnum;
const luParser = require('../lufile/luParser');

@@ -17,5 +18,9 @@ const SectionOperator = require('../lufile/sectionOperator');

const prebuiltEntityTypes = require('../utils/enums/luisbuiltintypes').consolidatedList;
const LuisBuilderVerbose = require('./../luis/luisCollate');
const Luis = require('./../luis/luis');
const qnaBuilderVerbose = require('./../qna/qnamaker/kbCollate');
const NEWLINE = require('os').EOL;
const path = require('path');
const QNA_GENERIC_SOURCE = "custom editorial";
const MAX_QUESTIONS_PER_ANSWER = 1000;
module.exports = {

@@ -30,10 +35,17 @@ /**

*/
crossTrain: function (luContents, qnaContents, crossTrainConfig) {
crossTrain: async function (luContents, qnaContents, crossTrainConfig) {
try {
const { luObjectArray, qnaObjectArray } = pretreatment(luContents, qnaContents);
let { luObjectArray, qnaObjectArray } = pretreatment(luContents, qnaContents);
const { rootIds, triggerRules, intentName, verbose } = crossTrainConfig;
let triggerFileIds = Object.keys(triggerRules).map(x => x.toLowerCase());
let destFileIds = Object.values(triggerRules).flatMap(x => Object.values(x)).flatMap(y => y).map(x => x.toLowerCase());
luObjectArray = luObjectArray.filter(x => triggerFileIds.includes(x.id.toLowerCase()) || destFileIds.includes(x.id.toLowerCase()));
qnaObjectArray = qnaObjectArray.filter(x => {
const luFileId = x.id.toLowerCase().replace(new RegExp(helpers.FileExtTypeEnum.QnAFile + '$'), helpers.FileExtTypeEnum.LUFile);
return triggerFileIds.includes(luFileId) || destFileIds.includes(luFileId);
});
// parse lu content to LUResource object
let luFileIdToResourceMap = parseAndValidateContent(luObjectArray, verbose);
let luFileIdToResourceMap = await parseAndValidateContent(luObjectArray, verbose);
// parse qna content to LUResource object
let qnaFileIdToResourceMap = parseAndValidateContent(qnaObjectArray, verbose);
let qnaFileIdToResourceMap = await parseAndValidateContent(qnaObjectArray, verbose);
// construct resource tree to build the father-children relationship among lu files

@@ -43,3 +55,3 @@ let resources = constructResoureTree(luFileIdToResourceMap, triggerRules);

for (const rootObjectId of rootIds) {
if (resources.some(r => r.id === rootObjectId)) {
if (resources.some(r => r.id.toLowerCase() === rootObjectId.toLowerCase())) {
// do cross training for each root at top level

@@ -74,2 +86,5 @@ const result = luCrossTrain(rootObjectId, resources, qnaFileIdToResourceMap, intentName);

let fileIdsFromInput = Array.from(fileIdToLuResourceMap.keys());
let lowerCasefileIdsFromInput = Array.from(fileIdToLuResourceMap.keys()).map(x => x.toLowerCase());
let triggerKeys = Object.keys(triggerRules);
let lowerCaseTriggerKeys = triggerKeys.map(x => x.toLowerCase());
for (const fileId of fileIdsFromInput) {

@@ -82,3 +97,3 @@ let luResource = fileIdToLuResourceMap.get(fileId);

};
if (!(fileId in triggerRules)) {
if (!lowerCaseTriggerKeys.includes(fileId.toLowerCase())) {
resources.push(resource);

@@ -94,3 +109,3 @@ continue;

}
const intentToDestLuFiles = triggerRules[fileId];
const intentToDestLuFiles = triggerRules[triggerKeys.find(k => k.toLowerCase() === fileId.toLowerCase())];
for (const triggerIntent of Object.keys(intentToDestLuFiles)) {

@@ -105,3 +120,3 @@ if (triggerIntent !== '' && !intents.some(i => i.Name === triggerIntent)) {

destLuFiles.forEach(destLuFile => {
if (destLuFile !== '' && !fileIdsFromInput.includes(destLuFile)) {
if (destLuFile !== '' && !lowerCasefileIdsFromInput.includes(destLuFile.toLowerCase())) {
throw (new exception(retCode.errorCode.INVALID_INPUT, `Sorry, lu file '${destLuFile}' is not found`));

@@ -111,3 +126,3 @@ }

resource.children.push({
target: destLuFile,
target: fileIdsFromInput.find(x => x.toLowerCase() === destLuFile.toLowerCase()) || '',
intent: triggerIntent

@@ -143,3 +158,3 @@ });

// Parse resources
let rootResource = resources.filter(r => r.id === rootResourceId)[0];
let rootResource = resources.filter(r => r.id.toLowerCase() === rootResourceId.toLowerCase())[0];
rootResource.visited = true;

@@ -157,3 +172,4 @@ mergeRootInterruptionToLeaves(rootResource, idToResourceMap, qnaFileToResourceMap, intentName);

if (childResource && childResource.visited === undefined) {
const rootQnaFileId = rootResource.id.replace(new RegExp(helpers.FileExtTypeEnum.LUFile + '$'), helpers.FileExtTypeEnum.QnAFile);
let rootQnaFileId = rootResource.id.toLowerCase().replace(new RegExp(helpers.FileExtTypeEnum.LUFile + '$'), helpers.FileExtTypeEnum.QnAFile);
rootQnaFileId = Array.from(qnaFileToResourceMap.keys()).find(x => x.toLowerCase() === rootQnaFileId);
const rootQnaResource = qnaFileToResourceMap.get(rootQnaFileId);

@@ -222,3 +238,3 @@ const newChildResource = mergeFatherInterruptionToChild(rootResource, rootQnaResource, childResource, intentName);

const dedupFromUtterances = Array.from(new Set(fromUtterances));
let existingUtterances = extractIntentUtterances(toResource.content);
let existingUtterances = extractIntentUtterances(toResource.content).map(u => u.toLowerCase());
const toInterruptions = toResource.content.Sections.filter(section => section.Name === intentName);

@@ -230,3 +246,3 @@ if (toInterruptions && toInterruptions.length > 0) {

dedupFromUtterances.forEach(utterance => {
if (!existingUtterances.includes(utterance)) {
if (!existingUtterances.includes(utterance.toLowerCase())) {
newFileContent += '- ' + utterance + NEWLINE;

@@ -258,3 +274,3 @@ }

// construct new content here
const dedupUtterances = dedupFromUtterances.filter(u => !existingUtterances.includes(u));
const dedupUtterances = dedupFromUtterances.filter(u => !existingUtterances.includes(u.toLowerCase()));
if (dedupUtterances && dedupUtterances.length > 0) {

@@ -320,7 +336,8 @@ let newFileContent = `${NEWLINE}> Source: cross training. Please do not edit these directly!${NEWLINE}# ${intentName}${NEWLINE}- `;

for (const luObjectId of Array.from(luFileIdToResourceMap.keys())) {
const qnaObjectId = luObjectId.replace(new RegExp(helpers.FileExtTypeEnum.LUFile + '$'), helpers.FileExtTypeEnum.QnAFile);
let qnaObjectId = luObjectId.toLowerCase().replace(new RegExp(helpers.FileExtTypeEnum.LUFile + '$'), helpers.FileExtTypeEnum.QnAFile);
let fileName = path.basename(luObjectId, path.extname(luObjectId));
const culture = fileHelper.getCultureFromPath(luObjectId);
fileName = culture ? fileName.substring(0, fileName.length - culture.length - 1) : fileName;
if (Array.from(qnaFileIdToResourceMap.keys()).some(q => q === qnaObjectId)) {
qnaObjectId = Array.from(qnaFileIdToResourceMap.keys()).find(x => x.toLowerCase() === qnaObjectId);
if (qnaObjectId) {
const { luResource, qnaResource } = qnaCrossTrainCore(luFileIdToResourceMap.get(luObjectId), qnaFileIdToResourceMap.get(qnaObjectId), fileName, interruptionIntentName);

@@ -359,8 +376,9 @@ luFileIdToResourceMap.set(luObjectId, luResource);

// extract lu utterances except interruption
let utterancesOfLocalIntents = utterances.filter(u => !utterancesOfInterruption.includes(u));
let utterancesOfLocalIntents = utterances.filter(u => !utterancesOfInterruption.includes(u)).map(u => u.toLowerCase());
// remove questions which are duplicated with local lu utterances
let dedupedQuestions = questions.filter(q => !utterancesOfLocalIntents.includes(q));
let dedupedQuestions = questions.filter(q => !utterancesOfLocalIntents.includes(q.toLowerCase()));
// update interruption intent if there are duplications with questions
if (utterancesOfInterruption.some(u => dedupedQuestions.includes(u))) {
utterancesOfInterruption = utterancesOfInterruption.filter(u => !dedupedQuestions.includes(u));
let dedupedQuestionsOfLowerCase = dedupedQuestions.map(u => u.toLowerCase());
if (utterancesOfInterruption.some(u => dedupedQuestionsOfLowerCase.includes(u.toLowerCase()))) {
utterancesOfInterruption = utterancesOfInterruption.filter(u => !dedupedQuestionsOfLowerCase.includes(u.toLowerCase()));
// get section id

@@ -381,3 +399,3 @@ const sectionId = trainedLuResource.Sections.filter(s => s.Name === interruptionIntentName)[0].Id;

// add questions from qna file to corresponding lu file with intent named DeferToRecognizer_QnA_${fileName}
if (questionsContent && questionsContent !== '' && utterances.length > 0) {
if (questionsContent && questionsContent !== '') {
const questionsToUtterances = `${NEWLINE}${crossTrainingComments}${NEWLINE}# DeferToRecognizer_QnA_${fileName}${NEWLINE}${questionsContent}`;

@@ -394,4 +412,4 @@ trainedLuResource = new SectionOperator(trainedLuResource).addSection(questionsToUtterances);

}
if (qnaSection.Id) {
qnaSectionContent += `<a id = "${qnaSection.Id}"></a>${NEWLINE}${NEWLINE}`;
if (qnaSection.QAPairId) {
qnaSectionContent += `<a id = "${qnaSection.QAPairId}"></a>${NEWLINE}${NEWLINE}`;
}

@@ -415,8 +433,11 @@ qnaSectionContent += `# ? ${Array.from(new Set(qnaSection.Questions)).join(NEWLINE + '- ')}${NEWLINE}${NEWLINE}**Filters:**${NEWLINE}- ${qnaSection.FilterPairs.map(f => f.key + '=' + f.value).join(NEWLINE + '- ')}${NEWLINE}${NEWLINE}\`\`\`${NEWLINE}${qnaSection.Answer}${NEWLINE}\`\`\``;

// remove utterances which are duplicated with local qna questions
const dedupedUtterances = utterancesWithoutPatterns.filter(u => !questions.includes(u));
// construct new question content for qna resource
let utterancesContent = dedupedUtterances.join(NEWLINE + '- ');
let questionsOfLowerCase = questions.map(q => q.toLowerCase());
let dedupedUtterances = utterancesWithoutPatterns.filter(u => !questionsOfLowerCase.includes(u.toLowerCase()));
// add utterances from lu file to corresponding qna file with question set to all utterances
if (utterancesContent && utterancesContent !== '' && qnaSections.length > 0) {
const utterancesToQuestion = `${NEWLINE}${crossTrainingComments}${NEWLINE}# ? ${utterancesContent}${NEWLINE}${NEWLINE}**Filters:**${NEWLINE}- dialogName=${fileName}${NEWLINE}${NEWLINE}\`\`\`${NEWLINE}intent=DeferToRecognizer_LUIS_${fileName}${NEWLINE}\`\`\``;
// split large QA pair to multiple smaller ones to overcome the limit that the maximum number of questions per answer is 300
while (dedupedUtterances.length > 0) {
let subDedupedUtterances = dedupedUtterances.splice(0, MAX_QUESTIONS_PER_ANSWER);
// construct new question content for qna resource
let utterancesContent = subDedupedUtterances.join(NEWLINE + '- ');
let utterancesToQuestion = `${NEWLINE}${crossTrainingComments}${NEWLINE}# ? ${utterancesContent}${NEWLINE}${NEWLINE}**Filters:**${NEWLINE}- dialogName=${fileName}${NEWLINE}${NEWLINE}\`\`\`${NEWLINE}intent=DeferToRecognizer_LUIS_${fileName}${NEWLINE}\`\`\``;
trainedQnaResource = new SectionOperator(trainedQnaResource).addSection(utterancesToQuestion);

@@ -433,8 +454,18 @@ }

*/
const parseAndValidateContent = function (objectArray, verbose) {
const parseAndValidateContent = async function (objectArray, verbose) {
let fileIdToResourceMap = new Map();
for (const object of objectArray) {
let content = object.content;
content = helpers.sanitizeNewLines(content);
let resource = luParser.parse(content);
let fileContent = object.content;
if (object.content && object.content !== '') {
if (object.id.toLowerCase().endsWith(fileExtEnum.LUFile)) {
let result = await LuisBuilderVerbose.build([object], verbose);
let luisObj = new Luis(result);
fileContent = luisObj.parseToLuContent();
}
else {
let result = await qnaBuilderVerbose.build([object], verbose);
fileContent = result.parseToQnAContent();
}
}
let resource = luParser.parse(fileContent);
if (resource.Errors && resource.Errors.length > 0) {

@@ -458,4 +489,4 @@ if (verbose) {

// Parse lu and qna objects
const luObjectArray = fileHelper.getParsedObjects(luContents);
const qnaObjectArray = fileHelper.getParsedObjects(qnaContents);
let luObjectArray = fileHelper.getParsedObjects(luContents);
let qnaObjectArray = fileHelper.getParsedObjects(qnaContents);
return { luObjectArray, qnaObjectArray };

@@ -467,6 +498,10 @@ };

if (matchedEntity !== null) {
patternAnyEntity = matchedEntity[1];
patternAnyEntity = matchedEntity[1].trim();
if (patternAnyEntity && patternAnyEntity.startsWith('@')) {
patternAnyEntity = patternAnyEntity.slice(1);
patternAnyEntity = patternAnyEntity.slice(1).trim();
}
let patternAnyEntityWithRole = patternAnyEntity.split(':');
if (patternAnyEntityWithRole.length > 1) {
patternAnyEntity = patternAnyEntityWithRole[0].trim();
}
if (prebuiltEntityTypes.includes(patternAnyEntity)) {

@@ -473,0 +508,0 @@ return true;

@@ -29,3 +29,3 @@ "use strict";

}
async loadContents(files, culture, suffix, region) {
async loadContents(files, culture, suffix, region, schema) {
let multiRecognizers = new Map();

@@ -71,7 +71,10 @@ let settings = new Map();

let multiRecognizerContent = {};
let multiRecognizerSchema = schema;
if (fs.existsSync(multiRecognizerPath)) {
multiRecognizerContent = JSON.parse(await fileHelper.getContentFromFile(multiRecognizerPath)).recognizers;
let multiRecognizerObject = JSON.parse(await fileHelper.getContentFromFile(multiRecognizerPath));
multiRecognizerContent = multiRecognizerObject.recognizers;
multiRecognizerSchema = multiRecognizerSchema || multiRecognizerObject.$schema;
this.handler(`${multiRecognizerPath} loaded\n`);
}
multiRecognizers.set(fileName, new multi_language_recognizer_1.MultiLanguageRecognizer(multiRecognizerPath, multiRecognizerContent));
multiRecognizers.set(fileName, new multi_language_recognizer_1.MultiLanguageRecognizer(multiRecognizerPath, multiRecognizerContent, multiRecognizerSchema));
}

@@ -95,3 +98,6 @@ const settingsPath = path.join(fileFolder, `luis.settings.${suffix}.${region}.json`);

}
let recognizer = recognizer_1.Recognizer.load(content.path, content.name, dialogFile, settings.get(fileFolder), existingDialogObj);
if (existingDialogObj && schema) {
existingDialogObj.$schema = schema;
}
let recognizer = recognizer_1.Recognizer.load(content.path, content.name, dialogFile, settings.get(fileFolder), existingDialogObj, schema);
recognizers.set(content.name, recognizer);

@@ -109,9 +115,13 @@ }

}
async build(luContents, recognizers, authoringKey, endpoint, botName, suffix, fallbackLocale, deleteOldVersion, multiRecognizers, settings) {
async build(luContents, recognizers, authoringKey, endpoint, botName, suffix, fallbackLocale, deleteOldVersion, multiRecognizers, settings, luisAPITPS, timeBucketOfRequests, retryCount, retryDuration) {
// luis api TPS which means 5 concurrent transactions to luis api in 1 second
// can set to other value if switched to a higher TPS(transaction per second) key
let luisApiTps = 5;
let luisApiTps = luisAPITPS || 5;
// set luis call delay duration to 1100 millisecond because 1000 can hit corner case of rate limit
let delayDuration = 1100;
const luBuildCore = new core_1.LuBuildCore(authoringKey, endpoint);
let timeBucket = timeBucketOfRequests || 1100;
// set retry count for rate limit luis API failure
let countForRetry = retryCount || 1;
// set retry duration for rate limit luis API failure
let durationForRetry = retryDuration || 1000;
const luBuildCore = new core_1.LuBuildCore(authoringKey, endpoint, countForRetry, durationForRetry);
const apps = await luBuildCore.getApplicationList();

@@ -142,11 +152,11 @@ // here we do a while loop to make full use of luis tps capacity

// To see if need update the model
needTrainAndPublish = await this.updateApplication(currentApp, luBuildCore, recognizer, delayDuration, deleteOldVersion);
needTrainAndPublish = await this.updateApplication(currentApp, luBuildCore, recognizer, timeBucket, deleteOldVersion);
}
else {
// create a new application
needTrainAndPublish = await this.createApplication(currentApp, luBuildCore, recognizer, delayDuration);
needTrainAndPublish = await this.createApplication(currentApp, luBuildCore, recognizer, timeBucket);
}
if (needTrainAndPublish) {
// train and publish application
await this.trainAndPublishApplication(luBuildCore, recognizer, delayDuration);
await this.trainAndPublishApplication(luBuildCore, recognizer, timeBucket);
}

@@ -184,3 +194,3 @@ // update multiLanguageRecognizer asset

}
async writeDialogAssets(contents, force, out, dialogType, luconfig) {
async writeDialogAssets(contents, force, out, dialogType, luconfig, schema) {
let writeDone = false;

@@ -210,3 +220,3 @@ let writeContents = contents.filter(c => c.id.endsWith('.dialog'));

this.handler(`Writing to ${outFilePath}\n`);
await this.writeDialog(content.content, outFilePath, dialogType);
await this.writeDialog(content.content, outFilePath, dialogType, schema);
writeDone = true;

@@ -223,3 +233,3 @@ }

this.handler(`Writing to ${content.path}\n`);
await this.writeDialog(content.content, content.path, dialogType);
await this.writeDialog(content.content, content.path, dialogType, schema);
writeDone = true;

@@ -231,4 +241,4 @@ }

}
async getActiveVersionIds(appNames, authoringKey, region) {
const luBuildCore = new core_1.LuBuildCore(authoringKey, `https://${region}.api.cognitive.microsoft.com`);
async getActiveVersionIds(appNames, authoringKey, region, retryCount, retryDuration) {
const luBuildCore = new core_1.LuBuildCore(authoringKey, `https://${region}.api.cognitive.microsoft.com`, retryCount || 1, retryDuration || 1000);
const apps = await luBuildCore.getApplicationList();

@@ -260,7 +270,7 @@ let appNameVersionMap = new Map();

}
async updateApplication(currentApp, luBuildCore, recognizer, delayDuration, deleteOldVersion) {
await delay(delayDuration);
async updateApplication(currentApp, luBuildCore, recognizer, timeBucket, deleteOldVersion) {
await delay(timeBucket);
const appInfo = await luBuildCore.getApplicationInfo(recognizer.getAppId());
recognizer.versionId = appInfo.activeVersion;
await delay(delayDuration);
recognizer.versionId = appInfo.activeVersion || appInfo.endpoints.PRODUCTION.versionId;
await delay(timeBucket);
const existingApp = await luBuildCore.exportApplication(recognizer.getAppId(), recognizer.versionId);

@@ -276,6 +286,6 @@ // compare models

this.handler(`${recognizer.getLuPath()} creating version=${newVersionId}\n`);
await delay(delayDuration);
await delay(timeBucket);
await luBuildCore.importNewVersion(recognizer.getAppId(), currentApp, options);
if (deleteOldVersion) {
await delay(delayDuration);
await delay(timeBucket);
const versionObjs = await luBuildCore.listApplicationVersions(recognizer.getAppId());

@@ -285,3 +295,3 @@ for (const versionObj of versionObjs) {

this.handler(`${recognizer.getLuPath()} deleting old version=${versionObj.version}`);
await delay(delayDuration);
await delay(timeBucket);
await luBuildCore.deleteVersion(recognizer.getAppId(), versionObj.version);

@@ -298,7 +308,7 @@ }

}
async createApplication(currentApp, luBuildCore, recognizer, delayDuration) {
async createApplication(currentApp, luBuildCore, recognizer, timeBucket) {
currentApp.versionId = currentApp.versionId && currentApp.versionId !== '' ? currentApp.versionId : '0.1';
recognizer.versionId = currentApp.versionId;
this.handler(`Creating LUIS.ai application: ${currentApp.name} version:${currentApp.versionId}\n`);
await delay(delayDuration);
await delay(timeBucket);
const response = await luBuildCore.importApplication(currentApp);

@@ -308,11 +318,11 @@ recognizer.setAppId(typeof response === 'string' ? response : response[Object.keys(response)[0]]);

}
async trainAndPublishApplication(luBuildCore, recognizer, delayDuration) {
async trainAndPublishApplication(luBuildCore, recognizer, timeBucket) {
// send train application request
this.handler(`${recognizer.getLuPath()} training version=${recognizer.versionId}\n`);
await delay(delayDuration);
await delay(timeBucket);
await luBuildCore.trainApplication(recognizer.getAppId(), recognizer.versionId);
this.handler(`${recognizer.getLuPath()} waiting for training for version=${recognizer.versionId}...`);
this.handler(`${recognizer.getLuPath()} waiting for training for version=${recognizer.versionId}...\n`);
let done = true;
do {
await delay(delayDuration);
await delay(timeBucket);
// get training status to see if training completed

@@ -333,3 +343,3 @@ let trainingStatus = await luBuildCore.getTrainingStatus(recognizer.getAppId(), recognizer.versionId);

this.handler(`${recognizer.getLuPath()} publishing version=${recognizer.versionId}\n`);
await delay(delayDuration);
await delay(timeBucket);
await luBuildCore.publishApplication(recognizer.getAppId(), recognizer.versionId);

@@ -360,3 +370,3 @@ this.handler(`${recognizer.getLuPath()} publishing finished\n`);

}
async writeDialog(content, filePath, dialogType) {
async writeDialog(content, filePath, dialogType, schema) {
await fs.writeFile(filePath, content, 'utf-8');

@@ -377,3 +387,3 @@ const contentObj = JSON.parse(content);

const recognizers = [fileName + '.lu'];
content = new cross_trained_recognizer_1.CrossTrainedRecognizer(crossTrainedFilePath, recognizers).save();
content = new cross_trained_recognizer_1.CrossTrainedRecognizer(crossTrainedFilePath, recognizers, schema).save();
}

@@ -380,0 +390,0 @@ await fs.writeFile(crossTrainedFilePath, content, 'utf-8');

@@ -11,2 +11,3 @@ "use strict";

const node_fetch_1 = require("node-fetch");
const delay = require('delay');
const retCode = require('./../utils/enums/CLI-errors');

@@ -17,6 +18,9 @@ const exception = require('./../utils/exception');

const Luis = require('./../luis/luis');
const rateLimitErrorCode = 429;
class LuBuildCore {
constructor(subscriptionKey, endpoint) {
constructor(subscriptionKey, endpoint, retryCount, retryDuration) {
this.subscriptionKey = subscriptionKey;
this.endpoint = endpoint;
this.retryCount = retryCount;
this.retryDuration = retryDuration;
// new luis api client

@@ -27,7 +31,51 @@ const creds = new ms_rest_azure_js_1.CognitiveServicesCredentials(subscriptionKey);

async getApplicationList() {
let apps = await this.client.apps.list(undefined, undefined);
let apps;
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
apps = await this.client.apps.list(undefined, undefined);
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
return apps;
}
async getApplicationInfo(appId) {
let appInfo = await this.client.apps.get(appId);
let appInfo;
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
appInfo = await this.client.apps.get(appId);
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
return appInfo;

@@ -43,4 +91,55 @@ }

};
const response = await node_fetch_1.default(url, { method: 'POST', headers, body: JSON.stringify(currentApp) });
const messageData = await response.json();
let messageData;
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.code === rateLimitErrorCode.toString()) {
let response = await node_fetch_1.default(url, { method: 'POST', headers, body: JSON.stringify(currentApp) });
messageData = await response.json();
if (messageData.error === undefined)
break;
error = messageData.error;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
else {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, error.message));
}
}
if (retryCount === 0) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, error.message));
}
return messageData;
}
async exportApplication(appId, versionId) {
const url = this.endpoint + '/luis/authoring/v3.0-preview/apps/' + appId + '/versions/' + versionId + '/export?format=json';
const headers = {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': this.subscriptionKey
};
let messageData;
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
const response = await node_fetch_1.default(url, { method: 'GET', headers });
messageData = await response.json();
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
if (messageData.error) {

@@ -51,6 +150,2 @@ throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, messageData.error.message));

}
async exportApplication(appId, versionId) {
const response = await this.client.versions.exportMethod(appId, versionId);
return response;
}
compareApplications(currentApp, existingApp) {

@@ -106,27 +201,151 @@ currentApp.desc = currentApp.desc && currentApp.desc !== '' && currentApp.desc !== existingApp.desc ? currentApp.desc : existingApp.desc;

};
const response = await node_fetch_1.default(url, { method: 'POST', headers, body: JSON.stringify(app) });
const messageData = await response.json();
if (messageData.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, messageData.error.message));
let messageData;
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.code === rateLimitErrorCode.toString()) {
let response = await node_fetch_1.default(url, { method: 'POST', headers, body: JSON.stringify(app) });
messageData = await response.json();
if (messageData.error === undefined)
break;
error = messageData.error;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
else {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, error.message));
}
}
if (retryCount === 0) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, error.message));
}
return messageData;
}
async listApplicationVersions(appId) {
return this.client.versions.list(appId);
let appVersions;
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
appVersions = await this.client.versions.list(appId);
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
return appVersions;
}
async deleteVersion(appId, versionId) {
await this.client.versions.deleteMethod(appId, versionId);
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
await this.client.versions.deleteMethod(appId, versionId);
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
}
async trainApplication(appId, versionId) {
await this.client.train.trainVersion(appId, versionId);
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
await this.client.train.trainVersion(appId, versionId);
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
}
async getTrainingStatus(appId, versionId) {
const status = this.client.train.getStatus(appId, versionId);
let status;
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
status = await this.client.train.getStatus(appId, versionId);
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
return status;
}
async publishApplication(appId, versionId) {
this.client.apps.publish(appId, {
versionId,
isStaging: false
});
let retryCount = this.retryCount + 1;
let error;
while (retryCount > 0) {
if (error === undefined || error.statusCode === rateLimitErrorCode) {
try {
await this.client.apps.publish(appId, {
versionId,
isStaging: false
});
break;
}
catch (e) {
error = e;
retryCount--;
if (retryCount > 0)
await delay(this.retryDuration);
}
}
else {
throw error;
}
}
if (retryCount === 0) {
throw error;
}
}

@@ -133,0 +352,0 @@ generateDeclarativeAssets(recognizers, multiRecognizers, settings) {

@@ -8,5 +8,6 @@ "use strict";

class CrossTrainedRecognizer {
constructor(dialogPath, recognizers) {
constructor(dialogPath, recognizers, schema) {
this.dialogPath = dialogPath;
this.recognizers = recognizers;
this.$schema = schema;
}

@@ -18,2 +19,5 @@ save() {

};
if (this.$schema) {
output = Object.assign({ $schema: this.$schema }, output);
}
return JSON.stringify(output, null, 4);

@@ -20,0 +24,0 @@ }

@@ -7,6 +7,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const path = require('path');
class MultiLanguageRecognizer {
constructor(dialogPath, recognizers) {
constructor(dialogPath, recognizers, schema) {
this.id = `LUIS_${path.basename(dialogPath).split('.')[0]}`;
this.dialogPath = dialogPath;
this.recognizers = recognizers;
this.$schema = schema;
}

@@ -16,4 +19,8 @@ save() {

$kind: 'Microsoft.MultiLanguageRecognizer',
id: this.id,
recognizers: this.recognizers
};
if (this.$schema) {
output = Object.assign({ $schema: this.$schema }, output);
}
return JSON.stringify(output, null, 4);

@@ -20,0 +27,0 @@ }

@@ -9,5 +9,6 @@ "use strict";

class Recognizer {
constructor(luFile, targetFileName) {
constructor(luFile, targetFileName, schema) {
this.luFile = luFile;
this.appId = '';
this.id = `LUIS_${targetFileName.split('.')[0]}`;
this.applicationId = `=settings.luis.${targetFileName.split('.').join('_').replace(/-/g, '_')}`;

@@ -17,6 +18,7 @@ this.endpoint = '=settings.luis.endpoint';

this.versionId = '0.1';
this.$schema = schema;
}
static load(luFile, targetFileName, dialogPath, luisSettings, existingRecognizer) {
static load(luFile, targetFileName, dialogPath, luisSettings, existingRecognizer, schema) {
if (existingRecognizer) {
let recognizer = new Recognizer(luFile, targetFileName);
let recognizer = new Recognizer(luFile, targetFileName, schema);
recognizer.dialogPath = dialogPath;

@@ -27,3 +29,3 @@ Object.assign(recognizer, existingRecognizer);

}
let recognizer = new Recognizer(luFile, targetFileName);
let recognizer = new Recognizer(luFile, targetFileName, schema);
recognizer.dialogPath = dialogPath;

@@ -35,2 +37,3 @@ return recognizer;

$kind: 'Microsoft.LuisRecognizer',
id: this.id,
applicationId: this.applicationId,

@@ -40,2 +43,5 @@ endpoint: this.endpoint,

};
if (this.$schema) {
output = Object.assign({ $schema: this.$schema }, output);
}
return JSON.stringify(output, null, 4);

@@ -42,0 +48,0 @@ }

@@ -6,2 +6,3 @@ "use strict";

const LUSectionTypes = require('./../utils/enums/lusectiontypes');
const InvalidCharsInIntentOrEntityName = require('./../utils/enums/invalidchars').InvalidCharsInIntentOrEntityName;
class EntitySection {

@@ -22,4 +23,5 @@ /**

ExtractName(parseTree) {
let entityName;
if (parseTree.entityDefinition().entityLine().entityName()) {
return parseTree.entityDefinition().entityLine().entityName().getText().trim();
entityName = parseTree.entityDefinition().entityLine().entityName().getText().trim();
}

@@ -32,2 +34,11 @@ else {

}
if (entityName && InvalidCharsInIntentOrEntityName.some(x => entityName.includes(x))) {
this.Errors.push(BuildDiagnostic({
message: `Invalid entity line, entity name ${entityName} cannot contain any of the following characters: [<, >, *, %, &, :, \\, $]`,
context: parseTree.newEntityDefinition().newEntityLine()
}));
}
else {
return entityName;
}
}

@@ -34,0 +45,0 @@ ExtractType(parseTree) {

@@ -6,3 +6,3 @@ "use strict";

var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964",
"\u0002)\u02a5\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\u0004",
"\u0002(\u02a2\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\u0004",
"\u0002\t\u0002\u0004\u0003\t\u0003\u0004\u0004\t\u0004\u0004\u0005\t",

@@ -22,417 +22,416 @@ "\u0005\u0004\u0006\t\u0006\u0004\u0007\t\u0007\u0004\b\t\b\u0004\t\t",

"B\tB\u0004C\tC\u0004D\tD\u0004E\tE\u0004F\tF\u0004G\tG\u0004H\tH\u0004",
"I\tI\u0004J\tJ\u0004K\tK\u0004L\tL\u0004M\tM\u0003\u0002\u0003\u0002",
"\u0003\u0003\u0003\u0003\u0003\u0004\u0003\u0004\u0003\u0005\u0003\u0005",
"\u0003\u0006\u0003\u0006\u0003\u0007\u0003\u0007\u0003\b\u0003\b\u0003",
"\t\u0003\t\u0003\n\u0003\n\u0003\u000b\u0003\u000b\u0003\f\u0003\f\u0003",
"\r\u0003\r\u0003\u000e\u0003\u000e\u0003\u000f\u0003\u000f\u0003\u0010",
"\u0003\u0010\u0003\u0011\u0003\u0011\u0003\u0012\u0003\u0012\u0003\u0013",
"\u0003\u0013\u0003\u0014\u0003\u0014\u0003\u0015\u0003\u0015\u0003\u0016",
"\u0003\u0016\u0003\u0017\u0003\u0017\u0003\u0018\u0003\u0018\u0003\u0019",
"\u0003\u0019\u0003\u001a\u0003\u001a\u0003\u001b\u0003\u001b\u0003\u001c",
"\u0003\u001c\u0003\u001d\u0003\u001d\u0003\u001e\u0003\u001e\u0003\u001f",
"\u0003\u001f\u0003 \u0006 \u00de\n \r \u000e \u00df\u0003!\u0005!\u00e3",
"\n!\u0003!\u0003!\u0003!\u0003!\u0003\"\u0007\"\u00ea\n\"\f\"\u000e",
"\"\u00ed\u000b\"\u0003\"\u0003\"\u0007\"\u00f1\n\"\f\"\u000e\"\u00f4",
"\u000b\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003",
"I\tI\u0004J\tJ\u0004K\tK\u0004L\tL\u0003\u0002\u0003\u0002\u0003\u0003",
"\u0003\u0003\u0003\u0004\u0003\u0004\u0003\u0005\u0003\u0005\u0003\u0006",
"\u0003\u0006\u0003\u0007\u0003\u0007\u0003\b\u0003\b\u0003\t\u0003\t",
"\u0003\n\u0003\n\u0003\u000b\u0003\u000b\u0003\f\u0003\f\u0003\r\u0003",
"\r\u0003\u000e\u0003\u000e\u0003\u000f\u0003\u000f\u0003\u0010\u0003",
"\u0010\u0003\u0011\u0003\u0011\u0003\u0012\u0003\u0012\u0003\u0013\u0003",
"\u0013\u0003\u0014\u0003\u0014\u0003\u0015\u0003\u0015\u0003\u0016\u0003",
"\u0016\u0003\u0017\u0003\u0017\u0003\u0018\u0003\u0018\u0003\u0019\u0003",
"\u0019\u0003\u001a\u0003\u001a\u0003\u001b\u0003\u001b\u0003\u001c\u0003",
"\u001c\u0003\u001d\u0003\u001d\u0003\u001e\u0003\u001e\u0003\u001f\u0003",
"\u001f\u0003 \u0006 \u00dc\n \r \u000e \u00dd\u0003!\u0005!\u00e1\n",
"!\u0003!\u0003!\u0003!\u0003!\u0003\"\u0007\"\u00e8\n\"\f\"\u000e\"",
"\u00eb\u000b\"\u0003\"\u0003\"\u0007\"\u00ef\n\"\f\"\u000e\"\u00f2\u000b",
"\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003",
"\"\u0003\"\u0003\"\u0003\"\u0003\"\u0007\"\u010b\n\"\f\"\u000e\"\u010e",
"\u000b\"\u0003\"\u0003\"\u0006\"\u0112\n\"\r\"\u000e\"\u0113\u0003#",
"\u0007#\u0117\n#\f#\u000e#\u011a\u000b#\u0003#\u0003#\u0007#\u011e\n",
"#\f#\u000e#\u0121\u000b#\u0003#\u0003#\u0003#\u0003#\u0006#\u0127\n",
"#\r#\u000e#\u0128\u0003$\u0007$\u012c\n$\f$\u000e$\u012f\u000b$\u0003",
"$\u0003$\u0007$\u0133\n$\f$\u000e$\u0136\u000b$\u0003$\u0003$\u0003",
"%\u0006%\u013b\n%\r%\u000e%\u013c\u0003%\u0007%\u0140\n%\f%\u000e%\u0143",
"\u000b%\u0003%\u0003%\u0003%\u0003%\u0003&\u0003&\u0003&\u0003&\u0003",
"\'\u0003\'\u0003\'\u0003\'\u0003(\u0003(\u0003(\u0003(\u0003)\u0003",
")\u0003)\u0003)\u0003*\u0003*\u0007*\u015b\n*\f*\u000e*\u015e\u000b",
"*\u0003*\u0003*\u0003+\u0003+\u0007+\u0164\n+\f+\u000e+\u0167\u000b",
"+\u0003+\u0003+\u0003,\u0003,\u0003,\u0003,\u0003,\u0003,\u0003,\u0003",
",\u0003,\u0003,\u0003,\u0003,\u0003,\u0003,\u0003-\u0003-\u0003-\u0003",
"-\u0007-\u017d\n-\f-\u000e-\u0180\u000b-\u0003-\u0003-\u0003-\u0003",
"-\u0003-\u0003.\u0003.\u0003.\u0003.\u0003.\u0007.\u018c\n.\f.\u000e",
".\u018f\u000b.\u0003.\u0003.\u0003.\u0003.\u0003/\u0003/\u0003/\u0003",
"/\u0003/\u0003/\u0003/\u0003/\u0003/\u0003/\u0003/\u0003/\u0003/\u0003",
"/\u00030\u00030\u00031\u00031\u00031\u00031\u00032\u00052\u01aa\n2\u0003",
"2\u00032\u00032\u00032\u00032\u00033\u00033\u00034\u00034\u00035\u0003",
"5\u00035\u00035\u00035\u00035\u00035\u00035\u00055\u01bd\n5\u00036\u0003",
"\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003",
"\"\u0003\"\u0003\"\u0003\"\u0007\"\u0109\n\"\f\"\u000e\"\u010c\u000b",
"\"\u0003\"\u0003\"\u0006\"\u0110\n\"\r\"\u000e\"\u0111\u0003#\u0007",
"#\u0115\n#\f#\u000e#\u0118\u000b#\u0003#\u0003#\u0007#\u011c\n#\f#\u000e",
"#\u011f\u000b#\u0003#\u0003#\u0003#\u0003#\u0006#\u0125\n#\r#\u000e",
"#\u0126\u0003$\u0007$\u012a\n$\f$\u000e$\u012d\u000b$\u0003$\u0003$",
"\u0007$\u0131\n$\f$\u000e$\u0134\u000b$\u0003$\u0003$\u0003%\u0006%",
"\u0139\n%\r%\u000e%\u013a\u0003%\u0007%\u013e\n%\f%\u000e%\u0141\u000b",
"%\u0003%\u0003%\u0003%\u0003%\u0003&\u0003&\u0003&\u0003&\u0003\'\u0003",
"\'\u0003\'\u0003\'\u0003(\u0003(\u0003(\u0003(\u0003)\u0003)\u0003)",
"\u0003)\u0003*\u0003*\u0007*\u0159\n*\f*\u000e*\u015c\u000b*\u0003*",
"\u0003*\u0003*\u0007*\u0161\n*\f*\u000e*\u0164\u000b*\u0003*\u0003*",
"\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003",
"+\u0003+\u0003+\u0003+\u0003+\u0003,\u0003,\u0003,\u0003,\u0007,\u017a",
"\n,\f,\u000e,\u017d\u000b,\u0003,\u0003,\u0003,\u0003,\u0003,\u0003",
"-\u0003-\u0003-\u0003-\u0003-\u0007-\u0189\n-\f-\u000e-\u018c\u000b",
"-\u0003-\u0003-\u0003-\u0003-\u0003.\u0003.\u0003.\u0003.\u0003.\u0003",
".\u0003.\u0003.\u0003.\u0003.\u0003.\u0003.\u0003.\u0003.\u0003/\u0003",
"/\u00030\u00030\u00030\u00030\u00031\u00051\u01a7\n1\u00031\u00031\u0003",
"1\u00031\u00031\u00032\u00032\u00033\u00033\u00034\u00034\u00034\u0003",
"4\u00034\u00034\u00034\u00034\u00054\u01ba\n4\u00035\u00035\u00035\u0003",
"5\u00035\u00035\u00035\u00035\u00035\u00035\u00035\u00035\u00055\u01c8",
"\n5\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u0003",
"6\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u0003",
"6\u00056\u01cb\n6\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003",
"7\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003",
"7\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003",
"7\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003",
"7\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003",
"7\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003",
"7\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003",
"7\u00037\u00057\u0212\n7\u00038\u00038\u00078\u0216\n8\f8\u000e8\u0219",
"\u000b8\u00038\u00038\u00039\u00039\u00079\u021f\n9\f9\u000e9\u0222",
"\u000b9\u0003:\u0006:\u0225\n:\r:\u000e:\u0226\u0003;\u0003;\u0006;",
"\u022b\n;\r;\u000e;\u022c\u0003;\u0003;\u0003<\u0003<\u0003<\u0003<",
"\u0003=\u0003=\u0003=\u0003=\u0003>\u0005>\u023a\n>\u0003>\u0003>\u0003",
">\u0003>\u0003>\u0003?\u0003?\u0003?\u0005?\u0244\n?\u0003?\u0003?\u0003",
"?\u0007?\u0249\n?\f?\u000e?\u024c\u000b?\u0003@\u0003@\u0003A\u0003",
"A\u0003A\u0003A\u0003B\u0005B\u0255\nB\u0003B\u0003B\u0003B\u0003B\u0003",
"B\u0003C\u0003C\u0005C\u025e\nC\u0003D\u0003D\u0003D\u0003D\u0007D\u0264",
"\nD\fD\u000eD\u0267\u000bD\u0003D\u0007D\u026a\nD\fD\u000eD\u026d\u000b",
"D\u0003D\u0003D\u0003E\u0006E\u0272\nE\rE\u000eE\u0273\u0003F\u0003",
"F\u0003F\u0003F\u0003G\u0005G\u027b\nG\u0003G\u0003G\u0003G\u0003G\u0003",
"G\u0003H\u0003H\u0007H\u0284\nH\fH\u000eH\u0287\u000bH\u0003H\u0003",
"H\u0003I\u0003I\u0007I\u028d\nI\fI\u000eI\u0290\u000bI\u0003J\u0006",
"J\u0293\nJ\rJ\u000eJ\u0294\u0003K\u0003K\u0003L\u0005L\u029a\nL\u0003",
"L\u0003L\u0003L\u0003L\u0003L\u0003M\u0006M\u02a2\nM\rM\u000eM\u02a3",
"\u0007\u015c\u0165\u017e\u018d\u0273\u0002N\b\u0002\n\u0002\f\u0002",
"\u000e\u0002\u0010\u0002\u0012\u0002\u0014\u0002\u0016\u0002\u0018\u0002",
"\u001a\u0002\u001c\u0002\u001e\u0002 \u0002\"\u0002$\u0002&\u0002(\u0002",
"*\u0002,\u0002.\u00020\u00022\u00024\u00026\u00028\u0002:\u0002<\u0002",
">\u0002@\u0002B\u0002D\u0003F\u0004H\u0005J\u0006L\u0007N\bP\tR\nT\u000b",
"V\fX\rZ\u000e\\\u000f^\u0010`\u0011b\u0012d\u0013f\u0002h\u0002j\u0014",
"l\u0015n\u0016p\u0017r\u0018t\u0019v\u001ax\u001bz\u001c|\u0002~\u0002",
"\u0080\u001d\u0082\u001e\u0084\u001f\u0086\u0002\u0088\u0002\u008a ",
"\u008c!\u008e\"\u0090\u0002\u0092#\u0094$\u0096%\u0098&\u009a\'\u009c",
"(\u009e)\b\u0002\u0003\u0004\u0005\u0006\u0007)\u0004\u0002CCcc\u0004",
"\u0002DDdd\u0004\u0002EEee\u0004\u0002FFff\u0004\u0002GGgg\u0004\u0002",
"HHhh\u0004\u0002IIii\u0004\u0002JJjj\u0004\u0002KKkk\u0004\u0002LLl",
"l\u0004\u0002MMmm\u0004\u0002NNnn\u0004\u0002OOoo\u0004\u0002PPpp\u0004",
"\u0002QQqq\u0004\u0002RRrr\u0004\u0002SSss\u0004\u0002TTtt\u0004\u0002",
"UUuu\u0004\u0002VVvv\u0004\u0002WWww\u0004\u0002XXxx\u0004\u0002YYy",
"y\u0004\u0002ZZzz\u0004\u0002[[{{\u0004\u0002\\\\||\u0004\u0002C\\c",
"|\u0006\u0002\u000b\u000b\"\"\u00a2\u00a2\uff01\uff01\u0004\u0002,-",
"//\u0004\u0002\f\f\u000f\u000f\t\u0002\f\f\u000f\u000f*+]]__}}\u007f",
"\u007f\t\u0002\u000b\f\u000f\u000f\"\"$$))..==\u0004\u0002$$))\b\u0002",
"\u000b\f\u000f\u000f$$))..==\u0004\u0002//aa\u0006\u0002\f\f\u000f\u000f",
"}}\u007f\u007f\u0006\u0002\u000b\f\u000f\u000f\"\"^^\u0006\u0002\u000b",
"\f\u000f\u000f\"\"<<\u0004\u0002\u000b\f\u000f\u000f\u0002\u02b3\u0002",
"D\u0003\u0002\u0002\u0002\u0002F\u0003\u0002\u0002\u0002\u0002H\u0003",
"\u0002\u0002\u0002\u0002J\u0003\u0002\u0002\u0002\u0002L\u0003\u0002",
"\u0002\u0002\u0002N\u0003\u0002\u0002\u0002\u0002P\u0003\u0002\u0002",
"\u0002\u0002R\u0003\u0002\u0002\u0002\u0002T\u0003\u0002\u0002\u0002",
"\u0002V\u0003\u0002\u0002\u0002\u0002X\u0003\u0002\u0002\u0002\u0002",
"Z\u0003\u0002\u0002\u0002\u0002\\\u0003\u0002\u0002\u0002\u0002^\u0003",
"\u0002\u0002\u0002\u0002`\u0003\u0002\u0002\u0002\u0002b\u0003\u0002",
"\u0002\u0002\u0002d\u0003\u0002\u0002\u0002\u0003f\u0003\u0002\u0002",
"\u0002\u0003h\u0003\u0002\u0002\u0002\u0003j\u0003\u0002\u0002\u0002",
"\u0003l\u0003\u0002\u0002\u0002\u0003n\u0003\u0002\u0002\u0002\u0003",
"p\u0003\u0002\u0002\u0002\u0003r\u0003\u0002\u0002\u0002\u0003t\u0003",
"\u0002\u0002\u0002\u0003v\u0003\u0002\u0002\u0002\u0003x\u0003\u0002",
"\u0002\u0002\u0003z\u0003\u0002\u0002\u0002\u0004|\u0003\u0002\u0002",
"\u0002\u0004~\u0003\u0002\u0002\u0002\u0004\u0080\u0003\u0002\u0002",
"\u0002\u0004\u0082\u0003\u0002\u0002\u0002\u0004\u0084\u0003\u0002\u0002",
"\u0002\u0005\u0086\u0003\u0002\u0002\u0002\u0005\u0088\u0003\u0002\u0002",
"\u0002\u0005\u008a\u0003\u0002\u0002\u0002\u0005\u008c\u0003\u0002\u0002",
"\u0002\u0005\u008e\u0003\u0002\u0002\u0002\u0006\u0090\u0003\u0002\u0002",
"\u0002\u0006\u0092\u0003\u0002\u0002\u0002\u0006\u0094\u0003\u0002\u0002",
"\u0002\u0006\u0096\u0003\u0002\u0002\u0002\u0006\u0098\u0003\u0002\u0002",
"\u0002\u0006\u009a\u0003\u0002\u0002\u0002\u0007\u009c\u0003\u0002\u0002",
"\u0002\u0007\u009e\u0003\u0002\u0002\u0002\b\u00a0\u0003\u0002\u0002",
"\u0002\n\u00a2\u0003\u0002\u0002\u0002\f\u00a4\u0003\u0002\u0002\u0002",
"\u000e\u00a6\u0003\u0002\u0002\u0002\u0010\u00a8\u0003\u0002\u0002\u0002",
"\u0012\u00aa\u0003\u0002\u0002\u0002\u0014\u00ac\u0003\u0002\u0002\u0002",
"\u0016\u00ae\u0003\u0002\u0002\u0002\u0018\u00b0\u0003\u0002\u0002\u0002",
"\u001a\u00b2\u0003\u0002\u0002\u0002\u001c\u00b4\u0003\u0002\u0002\u0002",
"\u001e\u00b6\u0003\u0002\u0002\u0002 \u00b8\u0003\u0002\u0002\u0002",
"\"\u00ba\u0003\u0002\u0002\u0002$\u00bc\u0003\u0002\u0002\u0002&\u00be",
"\u0003\u0002\u0002\u0002(\u00c0\u0003\u0002\u0002\u0002*\u00c2\u0003",
"\u0002\u0002\u0002,\u00c4\u0003\u0002\u0002\u0002.\u00c6\u0003\u0002",
"\u0002\u00020\u00c8\u0003\u0002\u0002\u00022\u00ca\u0003\u0002\u0002",
"\u00024\u00cc\u0003\u0002\u0002\u00026\u00ce\u0003\u0002\u0002\u0002",
"8\u00d0\u0003\u0002\u0002\u0002:\u00d2\u0003\u0002\u0002\u0002<\u00d4",
"\u0003\u0002\u0002\u0002>\u00d6\u0003\u0002\u0002\u0002@\u00d8\u0003",
"\u0002\u0002\u0002B\u00da\u0003\u0002\u0002\u0002D\u00dd\u0003\u0002",
"\u0002\u0002F\u00e2\u0003\u0002\u0002\u0002H\u00eb\u0003\u0002\u0002",
"\u0002J\u0118\u0003\u0002\u0002\u0002L\u012d\u0003\u0002\u0002\u0002",
"N\u013a\u0003\u0002\u0002\u0002P\u0148\u0003\u0002\u0002\u0002R\u014c",
"\u0003\u0002\u0002\u0002T\u0150\u0003\u0002\u0002\u0002V\u0154\u0003",
"\u0002\u0002\u0002X\u0158\u0003\u0002\u0002\u0002Z\u0161\u0003\u0002",
"\u0002\u0002\\\u016a\u0003\u0002\u0002\u0002^\u0178\u0003\u0002\u0002",
"\u0002`\u0186\u0003\u0002\u0002\u0002b\u0194\u0003\u0002\u0002\u0002",
"d\u01a2\u0003\u0002\u0002\u0002f\u01a4\u0003\u0002\u0002\u0002h\u01a9",
"\u0003\u0002\u0002\u0002j\u01b0\u0003\u0002\u0002\u0002l\u01b2\u0003",
"\u0002\u0002\u0002n\u01b4\u0003\u0002\u0002\u0002p\u01be\u0003\u0002",
"\u0002\u0002r\u0211\u0003\u0002\u0002\u0002t\u0213\u0003\u0002\u0002",
"\u0002v\u021c\u0003\u0002\u0002\u0002x\u0224\u0003\u0002\u0002\u0002",
"z\u0228\u0003\u0002\u0002\u0002|\u0230\u0003\u0002\u0002\u0002~\u0234",
"\u0003\u0002\u0002\u0002\u0080\u0239\u0003\u0002\u0002\u0002\u0082\u0243",
"\u0003\u0002\u0002\u0002\u0084\u024d\u0003\u0002\u0002\u0002\u0086\u024f",
"\u0003\u0002\u0002\u0002\u0088\u0254\u0003\u0002\u0002\u0002\u008a\u025b",
"\u0003\u0002\u0002\u0002\u008c\u025f\u0003\u0002\u0002\u0002\u008e\u0271",
"\u0003\u0002\u0002\u0002\u0090\u0275\u0003\u0002\u0002\u0002\u0092\u027a",
"\u0003\u0002\u0002\u0002\u0094\u0281\u0003\u0002\u0002\u0002\u0096\u028a",
"\u0003\u0002\u0002\u0002\u0098\u0292\u0003\u0002\u0002\u0002\u009a\u0296",
"\u0003\u0002\u0002\u0002\u009c\u0299\u0003\u0002\u0002\u0002\u009e\u02a1",
"\u0003\u0002\u0002\u0002\u00a0\u00a1\t\u0002\u0002\u0002\u00a1\t\u0003",
"\u0002\u0002\u0002\u00a2\u00a3\t\u0003\u0002\u0002\u00a3\u000b\u0003",
"\u0002\u0002\u0002\u00a4\u00a5\t\u0004\u0002\u0002\u00a5\r\u0003\u0002",
"\u0002\u0002\u00a6\u00a7\t\u0005\u0002\u0002\u00a7\u000f\u0003\u0002",
"\u0002\u0002\u00a8\u00a9\t\u0006\u0002\u0002\u00a9\u0011\u0003\u0002",
"\u0002\u0002\u00aa\u00ab\t\u0007\u0002\u0002\u00ab\u0013\u0003\u0002",
"\u0002\u0002\u00ac\u00ad\t\b\u0002\u0002\u00ad\u0015\u0003\u0002\u0002",
"\u0002\u00ae\u00af\t\t\u0002\u0002\u00af\u0017\u0003\u0002\u0002\u0002",
"\u00b0\u00b1\t\n\u0002\u0002\u00b1\u0019\u0003\u0002\u0002\u0002\u00b2",
"\u00b3\t\u000b\u0002\u0002\u00b3\u001b\u0003\u0002\u0002\u0002\u00b4",
"\u00b5\t\f\u0002\u0002\u00b5\u001d\u0003\u0002\u0002\u0002\u00b6\u00b7",
"\t\r\u0002\u0002\u00b7\u001f\u0003\u0002\u0002\u0002\u00b8\u00b9\t\u000e",
"\u0002\u0002\u00b9!\u0003\u0002\u0002\u0002\u00ba\u00bb\t\u000f\u0002",
"\u0002\u00bb#\u0003\u0002\u0002\u0002\u00bc\u00bd\t\u0010\u0002\u0002",
"\u00bd%\u0003\u0002\u0002\u0002\u00be\u00bf\t\u0011\u0002\u0002\u00bf",
"\'\u0003\u0002\u0002\u0002\u00c0\u00c1\t\u0012\u0002\u0002\u00c1)\u0003",
"\u0002\u0002\u0002\u00c2\u00c3\t\u0013\u0002\u0002\u00c3+\u0003\u0002",
"\u0002\u0002\u00c4\u00c5\t\u0014\u0002\u0002\u00c5-\u0003\u0002\u0002",
"\u0002\u00c6\u00c7\t\u0015\u0002\u0002\u00c7/\u0003\u0002\u0002\u0002",
"\u00c8\u00c9\t\u0016\u0002\u0002\u00c91\u0003\u0002\u0002\u0002\u00ca",
"\u00cb\t\u0017\u0002\u0002\u00cb3\u0003\u0002\u0002\u0002\u00cc\u00cd",
"\t\u0018\u0002\u0002\u00cd5\u0003\u0002\u0002\u0002\u00ce\u00cf\t\u0019",
"\u0002\u0002\u00cf7\u0003\u0002\u0002\u0002\u00d0\u00d1\t\u001a\u0002",
"\u0002\u00d19\u0003\u0002\u0002\u0002\u00d2\u00d3\t\u001b\u0002\u0002",
"\u00d3;\u0003\u0002\u0002\u0002\u00d4\u00d5\t\u001c\u0002\u0002\u00d5",
"=\u0003\u0002\u0002\u0002\u00d6\u00d7\u00042;\u0002\u00d7?\u0003\u0002",
"\u0002\u0002\u00d8\u00d9\t\u001d\u0002\u0002\u00d9A\u0003\u0002\u0002",
"\u0002\u00da\u00db\t\u001e\u0002\u0002\u00dbC\u0003\u0002\u0002\u0002",
"\u00dc\u00de\u0005@\u001e\u0002\u00dd\u00dc\u0003\u0002\u0002\u0002",
"\u00de\u00df\u0003\u0002\u0002\u0002\u00df\u00dd\u0003\u0002\u0002\u0002",
"\u00df\u00e0\u0003\u0002\u0002\u0002\u00e0E\u0003\u0002\u0002\u0002",
"\u00e1\u00e3\u0007\u000f\u0002\u0002\u00e2\u00e1\u0003\u0002\u0002\u0002",
"\u00e2\u00e3\u0003\u0002\u0002\u0002\u00e3\u00e4\u0003\u0002\u0002\u0002",
"\u00e4\u00e5\u0007\f\u0002\u0002\u00e5\u00e6\u0003\u0002\u0002\u0002",
"\u00e6\u00e7\b!\u0002\u0002\u00e7G\u0003\u0002\u0002\u0002\u00e8\u00ea",
"\u0005D \u0002\u00e9\u00e8\u0003\u0002\u0002\u0002\u00ea\u00ed\u0003",
"\u0002\u0002\u0002\u00eb\u00e9\u0003\u0002\u0002\u0002\u00eb\u00ec\u0003",
"\u0002\u0002\u0002\u00ec\u00ee\u0003\u0002\u0002\u0002\u00ed\u00eb\u0003",
"\u0002\u0002\u0002\u00ee\u00f2\u0007@\u0002\u0002\u00ef\u00f1\u0005",
"D \u0002\u00f0\u00ef\u0003\u0002\u0002\u0002\u00f1\u00f4\u0003\u0002",
"\u0002\u0002\u00f2\u00f0\u0003\u0002\u0002\u0002\u00f2\u00f3\u0003\u0002",
"\u0002\u0002\u00f3\u00f5\u0003\u0002\u0002\u0002\u00f4\u00f2\u0003\u0002",
"\u0002\u0002\u00f5\u00f6\u0007#\u0002\u0002\u00f6\u00f7\u0007%\u0002",
"\u0002\u00f7\u00f8\u0007\"\u0002\u0002\u00f8\u00f9\u0007B\u0002\u0002",
"\u00f9\u00fa\u0007s\u0002\u0002\u00fa\u00fb\u0007p\u0002\u0002\u00fb",
"\u00fc\u0007c\u0002\u0002\u00fc\u00fd\u00070\u0002\u0002\u00fd\u00fe",
"\u0007r\u0002\u0002\u00fe\u00ff\u0007c\u0002\u0002\u00ff\u0100\u0007",
"k\u0002\u0002\u0100\u0101\u0007t\u0002\u0002\u0101\u0102\u00070\u0002",
"\u0002\u0102\u0103\u0007u\u0002\u0002\u0103\u0104\u0007q\u0002\u0002",
"\u0104\u0105\u0007w\u0002\u0002\u0105\u0106\u0007t\u0002\u0002\u0106",
"\u0107\u0007e\u0002\u0002\u0107\u0108\u0007g\u0002\u0002\u0108\u010c",
"\u0003\u0002\u0002\u0002\u0109\u010b\u0005D \u0002\u010a\u0109\u0003",
"\u0002\u0002\u0002\u010b\u010e\u0003\u0002\u0002\u0002\u010c\u010a\u0003",
"\u0002\u0002\u0002\u010c\u010d\u0003\u0002\u0002\u0002\u010d\u010f\u0003",
"\u0002\u0002\u0002\u010e\u010c\u0003\u0002\u0002\u0002\u010f\u0111\u0007",
"?\u0002\u0002\u0110\u0112\n\u001f\u0002\u0002\u0111\u0110\u0003\u0002",
"\u0002\u0002\u0112\u0113\u0003\u0002\u0002\u0002\u0113\u0111\u0003\u0002",
"\u0002\u0002\u0113\u0114\u0003\u0002\u0002\u0002\u0114I\u0003\u0002",
"\u0002\u0002\u0115\u0117\u0005D \u0002\u0116\u0115\u0003\u0002\u0002",
"\u0002\u0117\u011a\u0003\u0002\u0002\u0002\u0118\u0116\u0003\u0002\u0002",
"\u0002\u0118\u0119\u0003\u0002\u0002\u0002\u0119\u011b\u0003\u0002\u0002",
"\u0002\u011a\u0118\u0003\u0002\u0002\u0002\u011b\u011f\u0007@\u0002",
"\u0002\u011c\u011e\u0005D \u0002\u011d\u011c\u0003\u0002\u0002\u0002",
"\u011e\u0121\u0003\u0002\u0002\u0002\u011f\u011d\u0003\u0002\u0002\u0002",
"\u011f\u0120\u0003\u0002\u0002\u0002\u0120\u0122\u0003\u0002\u0002\u0002",
"\u0121\u011f\u0003\u0002\u0002\u0002\u0122\u0123\u0007#\u0002\u0002",
"\u0123\u0124\u0007%\u0002\u0002\u0124\u0126\u0003\u0002\u0002\u0002",
"\u0125\u0127\n\u001f\u0002\u0002\u0126\u0125\u0003\u0002\u0002\u0002",
"\u0127\u0128\u0003\u0002\u0002\u0002\u0128\u0126\u0003\u0002\u0002\u0002",
"\u0128\u0129\u0003\u0002\u0002\u0002\u0129K\u0003\u0002\u0002\u0002",
"\u012a\u012c\u0005D \u0002\u012b\u012a\u0003\u0002\u0002\u0002\u012c",
"\u012f\u0003\u0002\u0002\u0002\u012d\u012b\u0003\u0002\u0002\u0002\u012d",
"\u012e\u0003\u0002\u0002\u0002\u012e\u0130\u0003\u0002\u0002\u0002\u012f",
"\u012d\u0003\u0002\u0002\u0002\u0130\u0134\u0007@\u0002\u0002\u0131",
"\u0133\n\u001f\u0002\u0002\u0132\u0131\u0003\u0002\u0002\u0002\u0133",
"\u0136\u0003\u0002\u0002\u0002\u0134\u0132\u0003\u0002\u0002\u0002\u0134",
"\u0135\u0003\u0002\u0002\u0002\u0135\u0137\u0003\u0002\u0002\u0002\u0136",
"\u0134\u0003\u0002\u0002\u0002\u0137\u0138\b$\u0002\u0002\u0138M\u0003",
"\u0002\u0002\u0002\u0139\u013b\u0007%\u0002\u0002\u013a\u0139\u0003",
"\u0002\u0002\u0002\u013b\u013c\u0003\u0002\u0002\u0002\u013c\u013a\u0003",
"\u0002\u0002\u0002\u013c\u013d\u0003\u0002\u0002\u0002\u013d\u0141\u0003",
"\u0002\u0002\u0002\u013e\u0140\u0005D \u0002\u013f\u013e\u0003\u0002",
"\u0002\u0002\u0140\u0143\u0003\u0002\u0002\u0002\u0141\u013f\u0003\u0002",
"\u0002\u0002\u0141\u0142\u0003\u0002\u0002\u0002\u0142\u0144\u0003\u0002",
"\u0002\u0002\u0143\u0141\u0003\u0002\u0002\u0002\u0144\u0145\u0007A",
"\u0002\u0002\u0145\u0146\u0003\u0002\u0002\u0002\u0146\u0147\b%\u0003",
"\u0002\u0147O\u0003\u0002\u0002\u0002\u0148\u0149\u0007%\u0002\u0002",
"\u0149\u014a\u0003\u0002\u0002\u0002\u014a\u014b\b&\u0004\u0002\u014b",
"Q\u0003\u0002\u0002\u0002\u014c\u014d\u0005B\u001f\u0002\u014d\u014e",
"\u0003\u0002\u0002\u0002\u014e\u014f\b\'\u0005\u0002\u014fS\u0003\u0002",
"\u0002\u0002\u0150\u0151\u0007&\u0002\u0002\u0151\u0152\u0003\u0002",
"\u0002\u0002\u0152\u0153\b(\u0006\u0002\u0153U\u0003\u0002\u0002\u0002",
"\u0154\u0155\u0007B\u0002\u0002\u0155\u0156\u0003\u0002\u0002\u0002",
"\u0156\u0157\b)\u0007\u0002\u0157W\u0003\u0002\u0002\u0002\u0158\u015c",
"\u0007]\u0002\u0002\u0159\u015b\u000b\u0002\u0002\u0002\u015a\u0159",
"\u0003\u0002\u0002\u0002\u015b\u015e\u0003\u0002\u0002\u0002\u015c\u015d",
"\u0003\u0002\u0002\u0002\u015c\u015a\u0003\u0002\u0002\u0002\u015d\u015f",
"\u0003\u0002\u0002\u0002\u015e\u015c\u0003\u0002\u0002\u0002\u015f\u0160",
"\u0007_\u0002\u0002\u0160Y\u0003\u0002\u0002\u0002\u0161\u0165\u0007",
"*\u0002\u0002\u0162\u0164\u000b\u0002\u0002\u0002\u0163\u0162\u0003",
"\u0002\u0002\u0002\u0164\u0167\u0003\u0002\u0002\u0002\u0165\u0166\u0003",
"\u0002\u0002\u0002\u0165\u0163\u0003\u0002\u0002\u0002\u0166\u0168\u0003",
"\u0002\u0002\u0002\u0167\u0165\u0003\u0002\u0002\u0002\u0168\u0169\u0007",
"+\u0002\u0002\u0169[\u0003\u0002\u0002\u0002\u016a\u016b\u0007,\u0002",
"\u0002\u016b\u016c\u0007,\u0002\u0002\u016c\u016d\u0003\u0002\u0002",
"\u0002\u016d\u016e\u0005\u0012\u0007\u0002\u016e\u016f\u0005\u0018\n",
"\u0002\u016f\u0170\u0005\u001e\r\u0002\u0170\u0171\u0005.\u0015\u0002",
"\u0171\u0172\u0005\u0010\u0006\u0002\u0172\u0173\u0005*\u0013\u0002",
"\u0173\u0174\u0005,\u0014\u0002\u0174\u0175\u0007<\u0002\u0002\u0175",
"\u0176\u0007,\u0002\u0002\u0176\u0177\u0007,\u0002\u0002\u0177]\u0003",
"\u0002\u0002\u0002\u0178\u0179\u0007>\u0002\u0002\u0179\u017a\u0007",
"c\u0002\u0002\u017a\u017e\u0003\u0002\u0002\u0002\u017b\u017d\u000b",
"\u0002\u0002\u0002\u017c\u017b\u0003\u0002\u0002\u0002\u017d\u0180\u0003",
"\u0002\u0002\u0002\u017e\u017f\u0003\u0002\u0002\u0002\u017e\u017c\u0003",
"\u0002\u0002\u0002\u017f\u0181\u0003\u0002\u0002\u0002\u0180\u017e\u0003",
"\u0002\u0002\u0002\u0181\u0182\u0007>\u0002\u0002\u0182\u0183\u0007",
"1\u0002\u0002\u0183\u0184\u0007c\u0002\u0002\u0184\u0185\u0007@\u0002",
"\u0002\u0185_\u0003\u0002\u0002\u0002\u0186\u0187\u0007b\u0002\u0002",
"\u0187\u0188\u0007b\u0002\u0002\u0188\u0189\u0007b\u0002\u0002\u0189",
"\u018d\u0003\u0002\u0002\u0002\u018a\u018c\u000b\u0002\u0002\u0002\u018b",
"\u018a\u0003\u0002\u0002\u0002\u018c\u018f\u0003\u0002\u0002\u0002\u018d",
"\u018e\u0003\u0002\u0002\u0002\u018d\u018b\u0003\u0002\u0002\u0002\u018e",
"\u0190\u0003\u0002\u0002\u0002\u018f\u018d\u0003\u0002\u0002\u0002\u0190",
"\u0191\u0007b\u0002\u0002\u0191\u0192\u0007b\u0002\u0002\u0192\u0193",
"\u0007b\u0002\u0002\u0193a\u0003\u0002\u0002\u0002\u0194\u0195\u0007",
",\u0002\u0002\u0195\u0196\u0007,\u0002\u0002\u0196\u0197\u0003\u0002",
"\u0002\u0002\u0197\u0198\u0005&\u0011\u0002\u0198\u0199\u0005*\u0013",
"\u0002\u0199\u019a\u0005$\u0010\u0002\u019a\u019b\u0005 \u000e\u0002",
"\u019b\u019c\u0005&\u0011\u0002\u019c\u019d\u0005.\u0015\u0002\u019d",
"\u019e\u0005,\u0014\u0002\u019e\u019f\u0007<\u0002\u0002\u019f\u01a0",
"\u0007,\u0002\u0002\u01a0\u01a1\u0007,\u0002\u0002\u01a1c\u0003\u0002",
"\u0002\u0002\u01a2\u01a3\u000b\u0002\u0002\u0002\u01a3e\u0003\u0002",
"\u0002\u0002\u01a4\u01a5\u0005D \u0002\u01a5\u01a6\u0003\u0002\u0002",
"\u0002\u01a6\u01a7\b1\b\u0002\u01a7g\u0003\u0002\u0002\u0002\u01a8\u01aa",
"\u0007\u000f\u0002\u0002\u01a9\u01a8\u0003\u0002\u0002\u0002\u01a9\u01aa",
"\u0003\u0002\u0002\u0002\u01aa\u01ab\u0003\u0002\u0002\u0002\u01ab\u01ac",
"\u0007\f\u0002\u0002\u01ac\u01ad\u0003\u0002\u0002\u0002\u01ad\u01ae",
"\b2\t\u0002\u01ae\u01af\b2\n\u0002\u01afi\u0003\u0002\u0002\u0002\u01b0",
"\u01b1\u0007?\u0002\u0002\u01b1k\u0003\u0002\u0002\u0002\u01b2\u01b3",
"\u0007.\u0002\u0002\u01b3m\u0003\u0002\u0002\u0002\u01b4\u01b5\u0005",
"\u0016\t\u0002\u01b5\u01b6\u0005\b\u0002\u0002\u01b6\u01b7\u0005,\u0014",
"\u0002\u01b7\u01b8\u0005*\u0013\u0002\u01b8\u01b9\u0005$\u0010\u0002",
"\u01b9\u01ba\u0005\u001e\r\u0002\u01ba\u01bc\u0005\u0010\u0006\u0002",
"\u01bb\u01bd\u0005,\u0014\u0002\u01bc\u01bb\u0003\u0002\u0002\u0002",
"\u01bc\u01bd\u0003\u0002\u0002\u0002\u01bdo\u0003\u0002\u0002\u0002",
"\u01be\u01bf\u00050\u0016\u0002\u01bf\u01c0\u0005,\u0014\u0002\u01c0",
"\u01c1\u0005\u0010\u0006\u0002\u01c1\u01c2\u0005,\u0014\u0002\u01c2",
"\u01c3\u0005\u0012\u0007\u0002\u01c3\u01c4\u0005\u0010\u0006\u0002\u01c4",
"\u01c5\u0005\b\u0002\u0002\u01c5\u01c6\u0005.\u0015\u0002\u01c6\u01c7",
"\u00050\u0016\u0002\u01c7\u01c8\u0005*\u0013\u0002\u01c8\u01ca\u0005",
"\u0010\u0006\u0002\u01c9\u01cb\u0005,\u0014\u0002\u01ca\u01c9\u0003",
"\u0002\u0002\u0002\u01ca\u01cb\u0003\u0002\u0002\u0002\u01cbq\u0003",
"\u0002\u0002\u0002\u01cc\u01cd\u0005,\u0014\u0002\u01cd\u01ce\u0005",
"\u0018\n\u0002\u01ce\u01cf\u0005 \u000e\u0002\u01cf\u01d0\u0005&\u0011",
"\u0002\u01d0\u01d1\u0005\u001e\r\u0002\u01d1\u01d2\u0005\u0010\u0006",
"\u0002\u01d2\u0212\u0003\u0002\u0002\u0002\u01d3\u01d4\u0005\u001e\r",
"\u0002\u01d4\u01d5\u0005\u0018\n\u0002\u01d5\u01d6\u0005,\u0014\u0002",
"\u01d6\u01d7\u0005.\u0015\u0002\u01d7\u0212\u0003\u0002\u0002\u0002",
"\u01d8\u01d9\u0005*\u0013\u0002\u01d9\u01da\u0005\u0010\u0006\u0002",
"\u01da\u01db\u0005\u0014\b\u0002\u01db\u01dc\u0005\u0010\u0006\u0002",
"\u01dc\u01dd\u00056\u0019\u0002\u01dd\u0212\u0003\u0002\u0002\u0002",
"\u01de\u01df\u0005&\u0011\u0002\u01df\u01e0\u0005*\u0013\u0002\u01e0",
"\u01e1\u0005\u0010\u0006\u0002\u01e1\u01e2\u0005\n\u0003\u0002\u01e2",
"\u01e3\u00050\u0016\u0002\u01e3\u01e4\u0005\u0018\n\u0002\u01e4\u01e5",
"\u0005\u001e\r\u0002\u01e5\u01e6\u0005.\u0015\u0002\u01e6\u0212\u0003",
"\u0002\u0002\u0002\u01e7\u01e8\u0005\f\u0004\u0002\u01e8\u01e9\u0005",
"$\u0010\u0002\u01e9\u01ea\u0005 \u000e\u0002\u01ea\u01eb\u0005&\u0011",
"\u0002\u01eb\u01ec\u0005$\u0010\u0002\u01ec\u01ed\u0005,\u0014\u0002",
"\u01ed\u01ee\u0005\u0018\n\u0002\u01ee\u01ef\u0005.\u0015\u0002\u01ef",
"\u01f0\u0005\u0010\u0006\u0002\u01f0\u0212\u0003\u0002\u0002\u0002\u01f1",
"\u01f2\u0005 \u000e\u0002\u01f2\u01f3\u0005\u001e\r\u0002\u01f3\u0212",
"\u0003\u0002\u0002\u0002\u01f4\u01f5\u0005&\u0011\u0002\u01f5\u01f6",
"\u0005\b\u0002\u0002\u01f6\u01f7\u0005.\u0015\u0002\u01f7\u01f8\u0005",
".\u0015\u0002\u01f8\u01f9\u0005\u0010\u0006\u0002\u01f9\u01fa\u0005",
"*\u0013\u0002\u01fa\u01fb\u0005\"\u000f\u0002\u01fb\u01fc\u0005\b\u0002",
"\u0002\u01fc\u01fd\u0005\"\u000f\u0002\u01fd\u01fe\u00058\u001a\u0002",
"\u01fe\u0212\u0003\u0002\u0002\u0002\u01ff\u0200\u0005&\u0011\u0002",
"\u0200\u0201\u0005\u0016\t\u0002\u0201\u0202\u0005*\u0013\u0002\u0202",
"\u0203\u0005\b\u0002\u0002\u0203\u0204\u0005,\u0014\u0002\u0204\u0205",
"\u0005\u0010\u0006\u0002\u0205\u0206\u0005\u001e\r\u0002\u0206\u0207",
"\u0005\u0018\n\u0002\u0207\u0208\u0005,\u0014\u0002\u0208\u0209\u0005",
".\u0015\u0002\u0209\u0212\u0003\u0002\u0002\u0002\u020a\u020b\u0005",
"\u0018\n\u0002\u020b\u020c\u0005\"\u000f\u0002\u020c\u020d\u0005.\u0015",
"\u0002\u020d\u020e\u0005\u0010\u0006\u0002\u020e\u020f\u0005\"\u000f",
"\u0002\u020f\u0210\u0005.\u0015\u0002\u0210\u0212\u0003\u0002\u0002",
"\u0002\u0211\u01cc\u0003\u0002\u0002\u0002\u0211\u01d3\u0003\u0002\u0002",
"\u0002\u0211\u01d8\u0003\u0002\u0002\u0002\u0211\u01de\u0003\u0002\u0002",
"\u0002\u0211\u01e7\u0003\u0002\u0002\u0002\u0211\u01f1\u0003\u0002\u0002",
"\u0002\u0211\u01f4\u0003\u0002\u0002\u0002\u0211\u01ff\u0003\u0002\u0002",
"\u0002\u0211\u020a\u0003\u0002\u0002\u0002\u0212s\u0003\u0002\u0002",
"\u0002\u0213\u0217\u0007]\u0002\u0002\u0214\u0216\n \u0002\u0002\u0215",
"\u0214\u0003\u0002\u0002\u0002\u0216\u0219\u0003\u0002\u0002\u0002\u0217",
"\u0215\u0003\u0002\u0002\u0002\u0217\u0218\u0003\u0002\u0002\u0002\u0218",
"\u021a\u0003\u0002\u0002\u0002\u0219\u0217\u0003\u0002\u0002\u0002\u021a",
"\u021b\u0007_\u0002\u0002\u021bu\u0003\u0002\u0002\u0002\u021c\u0220",
"\u00071\u0002\u0002\u021d\u021f\n\u001f\u0002\u0002\u021e\u021d\u0003",
"\u0002\u0002\u0002\u021f\u0222\u0003\u0002\u0002\u0002\u0220\u021e\u0003",
"\u0002\u0002\u0002\u0220\u0221\u0003\u0002\u0002\u0002\u0221w\u0003",
"\u0002\u0002\u0002\u0222\u0220\u0003\u0002\u0002\u0002\u0223\u0225\n",
"!\u0002\u0002\u0224\u0223\u0003\u0002\u0002\u0002\u0225\u0226\u0003",
"\u0002\u0002\u0002\u0226\u0224\u0003\u0002\u0002\u0002\u0226\u0227\u0003",
"\u0002\u0002\u0002\u0227y\u0003\u0002\u0002\u0002\u0228\u022a\t\"\u0002",
"\u0002\u0229\u022b\n#\u0002\u0002\u022a\u0229\u0003\u0002\u0002\u0002",
"\u022b\u022c\u0003\u0002\u0002\u0002\u022c\u022a\u0003\u0002\u0002\u0002",
"\u022c\u022d\u0003\u0002\u0002\u0002\u022d\u022e\u0003\u0002\u0002\u0002",
"\u022e\u022f\t\"\u0002\u0002\u022f{\u0003\u0002\u0002\u0002\u0230\u0231",
"\u0005D \u0002\u0231\u0232\u0003\u0002\u0002\u0002\u0232\u0233\b<\b",
"\u0002\u0233}\u0003\u0002\u0002\u0002\u0234\u0235\u0007%\u0002\u0002",
"\u0235\u0236\u0003\u0002\u0002\u0002\u0236\u0237\b=\u000b\u0002\u0237",
"\u007f\u0003\u0002\u0002\u0002\u0238\u023a\u0007\u000f\u0002\u0002\u0239",
"\u0238\u0003\u0002\u0002\u0002\u0239\u023a\u0003\u0002\u0002\u0002\u023a",
"\u023b\u0003\u0002\u0002\u0002\u023b\u023c\u0007\f\u0002\u0002\u023c",
"\u023d\u0003\u0002\u0002\u0002\u023d\u023e\b>\u0002\u0002\u023e\u023f",
"\b>\n\u0002\u023f\u0081\u0003\u0002\u0002\u0002\u0240\u0244\u0005<\u001c",
"\u0002\u0241\u0244\u0005>\u001d\u0002\u0242\u0244\u0007a\u0002\u0002",
"\u0243\u0240\u0003\u0002\u0002\u0002\u0243\u0241\u0003\u0002\u0002\u0002",
"\u0243\u0242\u0003\u0002\u0002\u0002\u0244\u024a\u0003\u0002\u0002\u0002",
"\u0245\u0249\u0005<\u001c\u0002\u0246\u0249\u0005>\u001d\u0002\u0247",
"\u0249\t$\u0002\u0002\u0248\u0245\u0003\u0002\u0002\u0002\u0248\u0246",
"\u0003\u0002\u0002\u0002\u0248\u0247\u0003\u0002\u0002\u0002\u0249\u024c",
"\u0003\u0002\u0002\u0002\u024a\u0248\u0003\u0002\u0002\u0002\u024a\u024b",
"\u0003\u0002\u0002\u0002\u024b\u0083\u0003\u0002\u0002\u0002\u024c\u024a",
"\u0003\u0002\u0002\u0002\u024d\u024e\u00070\u0002\u0002\u024e\u0085",
"\u0003\u0002\u0002\u0002\u024f\u0250\u0005D \u0002\u0250\u0251\u0003",
"\u0002\u0002\u0002\u0251\u0252\bA\b\u0002\u0252\u0087\u0003\u0002\u0002",
"\u0002\u0253\u0255\u0007\u000f\u0002\u0002\u0254\u0253\u0003\u0002\u0002",
"\u0002\u0254\u0255\u0003\u0002\u0002\u0002\u0255\u0256\u0003\u0002\u0002",
"\u0002\u0256\u0257\u0007\f\u0002\u0002\u0257\u0258\u0003\u0002\u0002",
"\u0002\u0258\u0259\bB\t\u0002\u0259\u025a\bB\n\u0002\u025a\u0089\u0003",
"\u0002\u0002\u0002\u025b\u025d\u0007^\u0002\u0002\u025c\u025e\n\u001f",
"\u0002\u0002\u025d\u025c\u0003\u0002\u0002\u0002\u025d\u025e\u0003\u0002",
"\u0002\u0002\u025e\u008b\u0003\u0002\u0002\u0002\u025f\u026b\u0007}",
"\u0002\u0002\u0260\u026a\n%\u0002\u0002\u0261\u0265\u0007}\u0002\u0002",
"\u0262\u0264\n\u001f\u0002\u0002\u0263\u0262\u0003\u0002\u0002\u0002",
"\u0264\u0267\u0003\u0002\u0002\u0002\u0265\u0263\u0003\u0002\u0002\u0002",
"\u0265\u0266\u0003\u0002\u0002\u0002\u0266\u0268\u0003\u0002\u0002\u0002",
"\u0267\u0265\u0003\u0002\u0002\u0002\u0268\u026a\u0007\u007f\u0002\u0002",
"\u0269\u0260\u0003\u0002\u0002\u0002\u0269\u0261\u0003\u0002\u0002\u0002",
"\u026a\u026d\u0003\u0002\u0002\u0002\u026b\u0269\u0003\u0002\u0002\u0002",
"\u026b\u026c\u0003\u0002\u0002\u0002\u026c\u026e\u0003\u0002\u0002\u0002",
"\u026d\u026b\u0003\u0002\u0002\u0002\u026e\u026f\u0007\u007f\u0002\u0002",
"\u026f\u008d\u0003\u0002\u0002\u0002\u0270\u0272\n&\u0002\u0002\u0271",
"\u0270\u0003\u0002\u0002\u0002\u0272\u0273\u0003\u0002\u0002\u0002\u0273",
"\u0274\u0003\u0002\u0002\u0002\u0273\u0271\u0003\u0002\u0002\u0002\u0274",
"\u008f\u0003\u0002\u0002\u0002\u0275\u0276\u0005D \u0002\u0276\u0277",
"\u0003\u0002\u0002\u0002\u0277\u0278\bF\b\u0002\u0278\u0091\u0003\u0002",
"\u0002\u0002\u0279\u027b\u0007\u000f\u0002\u0002\u027a\u0279\u0003\u0002",
"\u0002\u0002\u027a\u027b\u0003\u0002\u0002\u0002\u027b\u027c\u0003\u0002",
"\u0002\u0002\u027c\u027d\u0007\f\u0002\u0002\u027d\u027e\u0003\u0002",
"\u0002\u0002\u027e\u027f\bG\u0002\u0002\u027f\u0280\bG\n\u0002\u0280",
"\u0093\u0003\u0002\u0002\u0002\u0281\u0285\u0007]\u0002\u0002\u0282",
"\u0284\n \u0002\u0002\u0283\u0282\u0003\u0002\u0002\u0002\u0284\u0287",
"\u0003\u0002\u0002\u0002\u0285\u0283\u0003\u0002\u0002\u0002\u0285\u0286",
"\u0003\u0002\u0002\u0002\u0286\u0288\u0003\u0002\u0002\u0002\u0287\u0285",
"\u0003\u0002\u0002\u0002\u0288\u0289\u0007_\u0002\u0002\u0289\u0095",
"\u0003\u0002\u0002\u0002\u028a\u028e\u00071\u0002\u0002\u028b\u028d",
"\n\u001f\u0002\u0002\u028c\u028b\u0003\u0002\u0002\u0002\u028d\u0290",
"\u0003\u0002\u0002\u0002\u028e\u028c\u0003\u0002\u0002\u0002\u028e\u028f",
"\u0003\u0002\u0002\u0002\u028f\u0097\u0003\u0002\u0002\u0002\u0290\u028e",
"\u0003\u0002\u0002\u0002\u0291\u0293\n\'\u0002\u0002\u0292\u0291\u0003",
"\u0002\u0002\u0002\u0293\u0294\u0003\u0002\u0002\u0002\u0294\u0292\u0003",
"\u0002\u0002\u0002\u0294\u0295\u0003\u0002\u0002\u0002\u0295\u0099\u0003",
"\u0002\u0002\u0002\u0296\u0297\u0007<\u0002\u0002\u0297\u009b\u0003",
"\u0002\u0002\u0002\u0298\u029a\u0007\u000f\u0002\u0002\u0299\u0298\u0003",
"\u0002\u0002\u0002\u0299\u029a\u0003\u0002\u0002\u0002\u029a\u029b\u0003",
"\u0002\u0002\u0002\u029b\u029c\u0007\f\u0002\u0002\u029c\u029d\u0003",
"\u0002\u0002\u0002\u029d\u029e\bL\u0002\u0002\u029e\u029f\bL\n\u0002",
"\u029f\u009d\u0003\u0002\u0002\u0002\u02a0\u02a2\n(\u0002\u0002\u02a1",
"\u02a0\u0003\u0002\u0002\u0002\u02a2\u02a3\u0003\u0002\u0002\u0002\u02a3",
"\u02a1\u0003\u0002\u0002\u0002\u02a3\u02a4\u0003\u0002\u0002\u0002\u02a4",
"\u009f\u0003\u0002\u0002\u00021\u0002\u0003\u0004\u0005\u0006\u0007",
"\u00df\u00e2\u00eb\u00f2\u010c\u0113\u0118\u011f\u0128\u012d\u0134\u013c",
"\u0141\u015c\u0165\u017e\u018d\u01a9\u01bc\u01ca\u0211\u0217\u0220\u0226",
"\u022c\u0239\u0243\u0248\u024a\u0254\u025d\u0265\u0269\u026b\u0273\u027a",
"\u0285\u028e\u0294\u0299\u02a3\f\b\u0002\u0002\u0007\u0007\u0002\u0007",
"\u0004\u0002\u0007\u0005\u0002\u0007\u0006\u0002\u0007\u0003\u0002\t",
"\u0003\u0002\t\u0004\u0002\u0006\u0002\u0002\t\t\u0002"].join("");
"6\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u0003",
"6\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u0003",
"6\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u0003",
"6\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u0003",
"6\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u00036\u0005",
"6\u020f\n6\u00037\u00037\u00077\u0213\n7\f7\u000e7\u0216\u000b7\u0003",
"7\u00037\u00038\u00038\u00078\u021c\n8\f8\u000e8\u021f\u000b8\u0003",
"9\u00069\u0222\n9\r9\u000e9\u0223\u0003:\u0003:\u0006:\u0228\n:\r:\u000e",
":\u0229\u0003:\u0003:\u0003;\u0003;\u0003;\u0003;\u0003<\u0003<\u0003",
"<\u0003<\u0003=\u0005=\u0237\n=\u0003=\u0003=\u0003=\u0003=\u0003=\u0003",
">\u0003>\u0003>\u0005>\u0241\n>\u0003>\u0003>\u0003>\u0007>\u0246\n",
">\f>\u000e>\u0249\u000b>\u0003?\u0003?\u0003@\u0003@\u0003@\u0003@\u0003",
"A\u0005A\u0252\nA\u0003A\u0003A\u0003A\u0003A\u0003A\u0003B\u0003B\u0005",
"B\u025b\nB\u0003C\u0003C\u0003C\u0003C\u0007C\u0261\nC\fC\u000eC\u0264",
"\u000bC\u0003C\u0007C\u0267\nC\fC\u000eC\u026a\u000bC\u0003C\u0003C",
"\u0003D\u0006D\u026f\nD\rD\u000eD\u0270\u0003E\u0003E\u0003E\u0003E",
"\u0003F\u0005F\u0278\nF\u0003F\u0003F\u0003F\u0003F\u0003F\u0003G\u0003",
"G\u0007G\u0281\nG\fG\u000eG\u0284\u000bG\u0003G\u0003G\u0003H\u0003",
"H\u0007H\u028a\nH\fH\u000eH\u028d\u000bH\u0003I\u0006I\u0290\nI\rI\u000e",
"I\u0291\u0003J\u0003J\u0003K\u0005K\u0297\nK\u0003K\u0003K\u0003K\u0003",
"K\u0003K\u0003L\u0006L\u029f\nL\rL\u000eL\u02a0\u0007\u015a\u0162\u017b",
"\u018a\u0270\u0002M\b\u0002\n\u0002\f\u0002\u000e\u0002\u0010\u0002",
"\u0012\u0002\u0014\u0002\u0016\u0002\u0018\u0002\u001a\u0002\u001c\u0002",
"\u001e\u0002 \u0002\"\u0002$\u0002&\u0002(\u0002*\u0002,\u0002.\u0002",
"0\u00022\u00024\u00026\u00028\u0002:\u0002<\u0002>\u0002@\u0002B\u0002",
"D\u0003F\u0004H\u0005J\u0006L\u0007N\bP\tR\nT\u000bV\fX\rZ\u000e\\\u000f",
"^\u0010`\u0011b\u0012d\u0002f\u0002h\u0013j\u0014l\u0015n\u0016p\u0017",
"r\u0018t\u0019v\u001ax\u001bz\u0002|\u0002~\u001c\u0080\u001d\u0082",
"\u001e\u0084\u0002\u0086\u0002\u0088\u001f\u008a \u008c!\u008e\u0002",
"\u0090\"\u0092#\u0094$\u0096%\u0098&\u009a\'\u009c(\b\u0002\u0003\u0004",
"\u0005\u0006\u0007+\u0004\u0002CCcc\u0004\u0002DDdd\u0004\u0002EEee",
"\u0004\u0002FFff\u0004\u0002GGgg\u0004\u0002HHhh\u0004\u0002IIii\u0004",
"\u0002JJjj\u0004\u0002KKkk\u0004\u0002LLll\u0004\u0002MMmm\u0004\u0002",
"NNnn\u0004\u0002OOoo\u0004\u0002PPpp\u0004\u0002QQqq\u0004\u0002RRr",
"r\u0004\u0002SSss\u0004\u0002TTtt\u0004\u0002UUuu\u0004\u0002VVvv\u0004",
"\u0002WWww\u0004\u0002XXxx\u0004\u0002YYyy\u0004\u0002ZZzz\u0004\u0002",
"[[{{\u0004\u0002\\\\||\u0004\u0002C\\c|\u0006\u0002\u000b\u000b\"\"",
"\u00a2\u00a2\uff01\uff01\u0004\u0002,-//\u0004\u0002\f\f\u000f\u000f",
"\u0006\u0002\f\f\u000f\u000f]]__\u0005\u0002\f\f\u000f\u000f*+\t\u0002",
"\f\f\u000f\u000f*+]]__}}\u007f\u007f\t\u0002\u000b\f\u000f\u000f\"\"",
"$$))..==\u0004\u0002$$))\b\u0002\u000b\f\u000f\u000f$$))..==\u0004\u0002",
"//aa\u0006\u0002\f\f\u000f\u000f}}\u007f\u007f\u0006\u0002\u000b\f\u000f",
"\u000f\"\"^^\u0006\u0002\u000b\f\u000f\u000f\"\"<<\u0004\u0002\u000b",
"\f\u000f\u000f\u0002\u02b0\u0002D\u0003\u0002\u0002\u0002\u0002F\u0003",
"\u0002\u0002\u0002\u0002H\u0003\u0002\u0002\u0002\u0002J\u0003\u0002",
"\u0002\u0002\u0002L\u0003\u0002\u0002\u0002\u0002N\u0003\u0002\u0002",
"\u0002\u0002P\u0003\u0002\u0002\u0002\u0002R\u0003\u0002\u0002\u0002",
"\u0002T\u0003\u0002\u0002\u0002\u0002V\u0003\u0002\u0002\u0002\u0002",
"X\u0003\u0002\u0002\u0002\u0002Z\u0003\u0002\u0002\u0002\u0002\\\u0003",
"\u0002\u0002\u0002\u0002^\u0003\u0002\u0002\u0002\u0002`\u0003\u0002",
"\u0002\u0002\u0002b\u0003\u0002\u0002\u0002\u0003d\u0003\u0002\u0002",
"\u0002\u0003f\u0003\u0002\u0002\u0002\u0003h\u0003\u0002\u0002\u0002",
"\u0003j\u0003\u0002\u0002\u0002\u0003l\u0003\u0002\u0002\u0002\u0003",
"n\u0003\u0002\u0002\u0002\u0003p\u0003\u0002\u0002\u0002\u0003r\u0003",
"\u0002\u0002\u0002\u0003t\u0003\u0002\u0002\u0002\u0003v\u0003\u0002",
"\u0002\u0002\u0003x\u0003\u0002\u0002\u0002\u0004z\u0003\u0002\u0002",
"\u0002\u0004|\u0003\u0002\u0002\u0002\u0004~\u0003\u0002\u0002\u0002",
"\u0004\u0080\u0003\u0002\u0002\u0002\u0004\u0082\u0003\u0002\u0002\u0002",
"\u0005\u0084\u0003\u0002\u0002\u0002\u0005\u0086\u0003\u0002\u0002\u0002",
"\u0005\u0088\u0003\u0002\u0002\u0002\u0005\u008a\u0003\u0002\u0002\u0002",
"\u0005\u008c\u0003\u0002\u0002\u0002\u0006\u008e\u0003\u0002\u0002\u0002",
"\u0006\u0090\u0003\u0002\u0002\u0002\u0006\u0092\u0003\u0002\u0002\u0002",
"\u0006\u0094\u0003\u0002\u0002\u0002\u0006\u0096\u0003\u0002\u0002\u0002",
"\u0006\u0098\u0003\u0002\u0002\u0002\u0007\u009a\u0003\u0002\u0002\u0002",
"\u0007\u009c\u0003\u0002\u0002\u0002\b\u009e\u0003\u0002\u0002\u0002",
"\n\u00a0\u0003\u0002\u0002\u0002\f\u00a2\u0003\u0002\u0002\u0002\u000e",
"\u00a4\u0003\u0002\u0002\u0002\u0010\u00a6\u0003\u0002\u0002\u0002\u0012",
"\u00a8\u0003\u0002\u0002\u0002\u0014\u00aa\u0003\u0002\u0002\u0002\u0016",
"\u00ac\u0003\u0002\u0002\u0002\u0018\u00ae\u0003\u0002\u0002\u0002\u001a",
"\u00b0\u0003\u0002\u0002\u0002\u001c\u00b2\u0003\u0002\u0002\u0002\u001e",
"\u00b4\u0003\u0002\u0002\u0002 \u00b6\u0003\u0002\u0002\u0002\"\u00b8",
"\u0003\u0002\u0002\u0002$\u00ba\u0003\u0002\u0002\u0002&\u00bc\u0003",
"\u0002\u0002\u0002(\u00be\u0003\u0002\u0002\u0002*\u00c0\u0003\u0002",
"\u0002\u0002,\u00c2\u0003\u0002\u0002\u0002.\u00c4\u0003\u0002\u0002",
"\u00020\u00c6\u0003\u0002\u0002\u00022\u00c8\u0003\u0002\u0002\u0002",
"4\u00ca\u0003\u0002\u0002\u00026\u00cc\u0003\u0002\u0002\u00028\u00ce",
"\u0003\u0002\u0002\u0002:\u00d0\u0003\u0002\u0002\u0002<\u00d2\u0003",
"\u0002\u0002\u0002>\u00d4\u0003\u0002\u0002\u0002@\u00d6\u0003\u0002",
"\u0002\u0002B\u00d8\u0003\u0002\u0002\u0002D\u00db\u0003\u0002\u0002",
"\u0002F\u00e0\u0003\u0002\u0002\u0002H\u00e9\u0003\u0002\u0002\u0002",
"J\u0116\u0003\u0002\u0002\u0002L\u012b\u0003\u0002\u0002\u0002N\u0138",
"\u0003\u0002\u0002\u0002P\u0146\u0003\u0002\u0002\u0002R\u014a\u0003",
"\u0002\u0002\u0002T\u014e\u0003\u0002\u0002\u0002V\u0152\u0003\u0002",
"\u0002\u0002X\u0156\u0003\u0002\u0002\u0002Z\u0167\u0003\u0002\u0002",
"\u0002\\\u0175\u0003\u0002\u0002\u0002^\u0183\u0003\u0002\u0002\u0002",
"`\u0191\u0003\u0002\u0002\u0002b\u019f\u0003\u0002\u0002\u0002d\u01a1",
"\u0003\u0002\u0002\u0002f\u01a6\u0003\u0002\u0002\u0002h\u01ad\u0003",
"\u0002\u0002\u0002j\u01af\u0003\u0002\u0002\u0002l\u01b1\u0003\u0002",
"\u0002\u0002n\u01bb\u0003\u0002\u0002\u0002p\u020e\u0003\u0002\u0002",
"\u0002r\u0210\u0003\u0002\u0002\u0002t\u0219\u0003\u0002\u0002\u0002",
"v\u0221\u0003\u0002\u0002\u0002x\u0225\u0003\u0002\u0002\u0002z\u022d",
"\u0003\u0002\u0002\u0002|\u0231\u0003\u0002\u0002\u0002~\u0236\u0003",
"\u0002\u0002\u0002\u0080\u0240\u0003\u0002\u0002\u0002\u0082\u024a\u0003",
"\u0002\u0002\u0002\u0084\u024c\u0003\u0002\u0002\u0002\u0086\u0251\u0003",
"\u0002\u0002\u0002\u0088\u0258\u0003\u0002\u0002\u0002\u008a\u025c\u0003",
"\u0002\u0002\u0002\u008c\u026e\u0003\u0002\u0002\u0002\u008e\u0272\u0003",
"\u0002\u0002\u0002\u0090\u0277\u0003\u0002\u0002\u0002\u0092\u027e\u0003",
"\u0002\u0002\u0002\u0094\u0287\u0003\u0002\u0002\u0002\u0096\u028f\u0003",
"\u0002\u0002\u0002\u0098\u0293\u0003\u0002\u0002\u0002\u009a\u0296\u0003",
"\u0002\u0002\u0002\u009c\u029e\u0003\u0002\u0002\u0002\u009e\u009f\t",
"\u0002\u0002\u0002\u009f\t\u0003\u0002\u0002\u0002\u00a0\u00a1\t\u0003",
"\u0002\u0002\u00a1\u000b\u0003\u0002\u0002\u0002\u00a2\u00a3\t\u0004",
"\u0002\u0002\u00a3\r\u0003\u0002\u0002\u0002\u00a4\u00a5\t\u0005\u0002",
"\u0002\u00a5\u000f\u0003\u0002\u0002\u0002\u00a6\u00a7\t\u0006\u0002",
"\u0002\u00a7\u0011\u0003\u0002\u0002\u0002\u00a8\u00a9\t\u0007\u0002",
"\u0002\u00a9\u0013\u0003\u0002\u0002\u0002\u00aa\u00ab\t\b\u0002\u0002",
"\u00ab\u0015\u0003\u0002\u0002\u0002\u00ac\u00ad\t\t\u0002\u0002\u00ad",
"\u0017\u0003\u0002\u0002\u0002\u00ae\u00af\t\n\u0002\u0002\u00af\u0019",
"\u0003\u0002\u0002\u0002\u00b0\u00b1\t\u000b\u0002\u0002\u00b1\u001b",
"\u0003\u0002\u0002\u0002\u00b2\u00b3\t\f\u0002\u0002\u00b3\u001d\u0003",
"\u0002\u0002\u0002\u00b4\u00b5\t\r\u0002\u0002\u00b5\u001f\u0003\u0002",
"\u0002\u0002\u00b6\u00b7\t\u000e\u0002\u0002\u00b7!\u0003\u0002\u0002",
"\u0002\u00b8\u00b9\t\u000f\u0002\u0002\u00b9#\u0003\u0002\u0002\u0002",
"\u00ba\u00bb\t\u0010\u0002\u0002\u00bb%\u0003\u0002\u0002\u0002\u00bc",
"\u00bd\t\u0011\u0002\u0002\u00bd\'\u0003\u0002\u0002\u0002\u00be\u00bf",
"\t\u0012\u0002\u0002\u00bf)\u0003\u0002\u0002\u0002\u00c0\u00c1\t\u0013",
"\u0002\u0002\u00c1+\u0003\u0002\u0002\u0002\u00c2\u00c3\t\u0014\u0002",
"\u0002\u00c3-\u0003\u0002\u0002\u0002\u00c4\u00c5\t\u0015\u0002\u0002",
"\u00c5/\u0003\u0002\u0002\u0002\u00c6\u00c7\t\u0016\u0002\u0002\u00c7",
"1\u0003\u0002\u0002\u0002\u00c8\u00c9\t\u0017\u0002\u0002\u00c93\u0003",
"\u0002\u0002\u0002\u00ca\u00cb\t\u0018\u0002\u0002\u00cb5\u0003\u0002",
"\u0002\u0002\u00cc\u00cd\t\u0019\u0002\u0002\u00cd7\u0003\u0002\u0002",
"\u0002\u00ce\u00cf\t\u001a\u0002\u0002\u00cf9\u0003\u0002\u0002\u0002",
"\u00d0\u00d1\t\u001b\u0002\u0002\u00d1;\u0003\u0002\u0002\u0002\u00d2",
"\u00d3\t\u001c\u0002\u0002\u00d3=\u0003\u0002\u0002\u0002\u00d4\u00d5",
"\u00042;\u0002\u00d5?\u0003\u0002\u0002\u0002\u00d6\u00d7\t\u001d\u0002",
"\u0002\u00d7A\u0003\u0002\u0002\u0002\u00d8\u00d9\t\u001e\u0002\u0002",
"\u00d9C\u0003\u0002\u0002\u0002\u00da\u00dc\u0005@\u001e\u0002\u00db",
"\u00da\u0003\u0002\u0002\u0002\u00dc\u00dd\u0003\u0002\u0002\u0002\u00dd",
"\u00db\u0003\u0002\u0002\u0002\u00dd\u00de\u0003\u0002\u0002\u0002\u00de",
"E\u0003\u0002\u0002\u0002\u00df\u00e1\u0007\u000f\u0002\u0002\u00e0",
"\u00df\u0003\u0002\u0002\u0002\u00e0\u00e1\u0003\u0002\u0002\u0002\u00e1",
"\u00e2\u0003\u0002\u0002\u0002\u00e2\u00e3\u0007\f\u0002\u0002\u00e3",
"\u00e4\u0003\u0002\u0002\u0002\u00e4\u00e5\b!\u0002\u0002\u00e5G\u0003",
"\u0002\u0002\u0002\u00e6\u00e8\u0005D \u0002\u00e7\u00e6\u0003\u0002",
"\u0002\u0002\u00e8\u00eb\u0003\u0002\u0002\u0002\u00e9\u00e7\u0003\u0002",
"\u0002\u0002\u00e9\u00ea\u0003\u0002\u0002\u0002\u00ea\u00ec\u0003\u0002",
"\u0002\u0002\u00eb\u00e9\u0003\u0002\u0002\u0002\u00ec\u00f0\u0007@",
"\u0002\u0002\u00ed\u00ef\u0005D \u0002\u00ee\u00ed\u0003\u0002\u0002",
"\u0002\u00ef\u00f2\u0003\u0002\u0002\u0002\u00f0\u00ee\u0003\u0002\u0002",
"\u0002\u00f0\u00f1\u0003\u0002\u0002\u0002\u00f1\u00f3\u0003\u0002\u0002",
"\u0002\u00f2\u00f0\u0003\u0002\u0002\u0002\u00f3\u00f4\u0007#\u0002",
"\u0002\u00f4\u00f5\u0007%\u0002\u0002\u00f5\u00f6\u0007\"\u0002\u0002",
"\u00f6\u00f7\u0007B\u0002\u0002\u00f7\u00f8\u0007s\u0002\u0002\u00f8",
"\u00f9\u0007p\u0002\u0002\u00f9\u00fa\u0007c\u0002\u0002\u00fa\u00fb",
"\u00070\u0002\u0002\u00fb\u00fc\u0007r\u0002\u0002\u00fc\u00fd\u0007",
"c\u0002\u0002\u00fd\u00fe\u0007k\u0002\u0002\u00fe\u00ff\u0007t\u0002",
"\u0002\u00ff\u0100\u00070\u0002\u0002\u0100\u0101\u0007u\u0002\u0002",
"\u0101\u0102\u0007q\u0002\u0002\u0102\u0103\u0007w\u0002\u0002\u0103",
"\u0104\u0007t\u0002\u0002\u0104\u0105\u0007e\u0002\u0002\u0105\u0106",
"\u0007g\u0002\u0002\u0106\u010a\u0003\u0002\u0002\u0002\u0107\u0109",
"\u0005D \u0002\u0108\u0107\u0003\u0002\u0002\u0002\u0109\u010c\u0003",
"\u0002\u0002\u0002\u010a\u0108\u0003\u0002\u0002\u0002\u010a\u010b\u0003",
"\u0002\u0002\u0002\u010b\u010d\u0003\u0002\u0002\u0002\u010c\u010a\u0003",
"\u0002\u0002\u0002\u010d\u010f\u0007?\u0002\u0002\u010e\u0110\n\u001f",
"\u0002\u0002\u010f\u010e\u0003\u0002\u0002\u0002\u0110\u0111\u0003\u0002",
"\u0002\u0002\u0111\u010f\u0003\u0002\u0002\u0002\u0111\u0112\u0003\u0002",
"\u0002\u0002\u0112I\u0003\u0002\u0002\u0002\u0113\u0115\u0005D \u0002",
"\u0114\u0113\u0003\u0002\u0002\u0002\u0115\u0118\u0003\u0002\u0002\u0002",
"\u0116\u0114\u0003\u0002\u0002\u0002\u0116\u0117\u0003\u0002\u0002\u0002",
"\u0117\u0119\u0003\u0002\u0002\u0002\u0118\u0116\u0003\u0002\u0002\u0002",
"\u0119\u011d\u0007@\u0002\u0002\u011a\u011c\u0005D \u0002\u011b\u011a",
"\u0003\u0002\u0002\u0002\u011c\u011f\u0003\u0002\u0002\u0002\u011d\u011b",
"\u0003\u0002\u0002\u0002\u011d\u011e\u0003\u0002\u0002\u0002\u011e\u0120",
"\u0003\u0002\u0002\u0002\u011f\u011d\u0003\u0002\u0002\u0002\u0120\u0121",
"\u0007#\u0002\u0002\u0121\u0122\u0007%\u0002\u0002\u0122\u0124\u0003",
"\u0002\u0002\u0002\u0123\u0125\n\u001f\u0002\u0002\u0124\u0123\u0003",
"\u0002\u0002\u0002\u0125\u0126\u0003\u0002\u0002\u0002\u0126\u0124\u0003",
"\u0002\u0002\u0002\u0126\u0127\u0003\u0002\u0002\u0002\u0127K\u0003",
"\u0002\u0002\u0002\u0128\u012a\u0005D \u0002\u0129\u0128\u0003\u0002",
"\u0002\u0002\u012a\u012d\u0003\u0002\u0002\u0002\u012b\u0129\u0003\u0002",
"\u0002\u0002\u012b\u012c\u0003\u0002\u0002\u0002\u012c\u012e\u0003\u0002",
"\u0002\u0002\u012d\u012b\u0003\u0002\u0002\u0002\u012e\u0132\u0007@",
"\u0002\u0002\u012f\u0131\n\u001f\u0002\u0002\u0130\u012f\u0003\u0002",
"\u0002\u0002\u0131\u0134\u0003\u0002\u0002\u0002\u0132\u0130\u0003\u0002",
"\u0002\u0002\u0132\u0133\u0003\u0002\u0002\u0002\u0133\u0135\u0003\u0002",
"\u0002\u0002\u0134\u0132\u0003\u0002\u0002\u0002\u0135\u0136\b$\u0002",
"\u0002\u0136M\u0003\u0002\u0002\u0002\u0137\u0139\u0007%\u0002\u0002",
"\u0138\u0137\u0003\u0002\u0002\u0002\u0139\u013a\u0003\u0002\u0002\u0002",
"\u013a\u0138\u0003\u0002\u0002\u0002\u013a\u013b\u0003\u0002\u0002\u0002",
"\u013b\u013f\u0003\u0002\u0002\u0002\u013c\u013e\u0005D \u0002\u013d",
"\u013c\u0003\u0002\u0002\u0002\u013e\u0141\u0003\u0002\u0002\u0002\u013f",
"\u013d\u0003\u0002\u0002\u0002\u013f\u0140\u0003\u0002\u0002\u0002\u0140",
"\u0142\u0003\u0002\u0002\u0002\u0141\u013f\u0003\u0002\u0002\u0002\u0142",
"\u0143\u0007A\u0002\u0002\u0143\u0144\u0003\u0002\u0002\u0002\u0144",
"\u0145\b%\u0003\u0002\u0145O\u0003\u0002\u0002\u0002\u0146\u0147\u0007",
"%\u0002\u0002\u0147\u0148\u0003\u0002\u0002\u0002\u0148\u0149\b&\u0004",
"\u0002\u0149Q\u0003\u0002\u0002\u0002\u014a\u014b\u0005B\u001f\u0002",
"\u014b\u014c\u0003\u0002\u0002\u0002\u014c\u014d\b\'\u0005\u0002\u014d",
"S\u0003\u0002\u0002\u0002\u014e\u014f\u0007&\u0002\u0002\u014f\u0150",
"\u0003\u0002\u0002\u0002\u0150\u0151\b(\u0006\u0002\u0151U\u0003\u0002",
"\u0002\u0002\u0152\u0153\u0007B\u0002\u0002\u0153\u0154\u0003\u0002",
"\u0002\u0002\u0154\u0155\b)\u0007\u0002\u0155W\u0003\u0002\u0002\u0002",
"\u0156\u015a\u0007]\u0002\u0002\u0157\u0159\n \u0002\u0002\u0158\u0157",
"\u0003\u0002\u0002\u0002\u0159\u015c\u0003\u0002\u0002\u0002\u015a\u015b",
"\u0003\u0002\u0002\u0002\u015a\u0158\u0003\u0002\u0002\u0002\u015b\u015d",
"\u0003\u0002\u0002\u0002\u015c\u015a\u0003\u0002\u0002\u0002\u015d\u015e",
"\u0007_\u0002\u0002\u015e\u0162\u0007*\u0002\u0002\u015f\u0161\n!\u0002",
"\u0002\u0160\u015f\u0003\u0002\u0002\u0002\u0161\u0164\u0003\u0002\u0002",
"\u0002\u0162\u0163\u0003\u0002\u0002\u0002\u0162\u0160\u0003\u0002\u0002",
"\u0002\u0163\u0165\u0003\u0002\u0002\u0002\u0164\u0162\u0003\u0002\u0002",
"\u0002\u0165\u0166\u0007+\u0002\u0002\u0166Y\u0003\u0002\u0002\u0002",
"\u0167\u0168\u0007,\u0002\u0002\u0168\u0169\u0007,\u0002\u0002\u0169",
"\u016a\u0003\u0002\u0002\u0002\u016a\u016b\u0005\u0012\u0007\u0002\u016b",
"\u016c\u0005\u0018\n\u0002\u016c\u016d\u0005\u001e\r\u0002\u016d\u016e",
"\u0005.\u0015\u0002\u016e\u016f\u0005\u0010\u0006\u0002\u016f\u0170",
"\u0005*\u0013\u0002\u0170\u0171\u0005,\u0014\u0002\u0171\u0172\u0007",
"<\u0002\u0002\u0172\u0173\u0007,\u0002\u0002\u0173\u0174\u0007,\u0002",
"\u0002\u0174[\u0003\u0002\u0002\u0002\u0175\u0176\u0007>\u0002\u0002",
"\u0176\u0177\u0007c\u0002\u0002\u0177\u017b\u0003\u0002\u0002\u0002",
"\u0178\u017a\u000b\u0002\u0002\u0002\u0179\u0178\u0003\u0002\u0002\u0002",
"\u017a\u017d\u0003\u0002\u0002\u0002\u017b\u017c\u0003\u0002\u0002\u0002",
"\u017b\u0179\u0003\u0002\u0002\u0002\u017c\u017e\u0003\u0002\u0002\u0002",
"\u017d\u017b\u0003\u0002\u0002\u0002\u017e\u017f\u0007>\u0002\u0002",
"\u017f\u0180\u00071\u0002\u0002\u0180\u0181\u0007c\u0002\u0002\u0181",
"\u0182\u0007@\u0002\u0002\u0182]\u0003\u0002\u0002\u0002\u0183\u0184",
"\u0007b\u0002\u0002\u0184\u0185\u0007b\u0002\u0002\u0185\u0186\u0007",
"b\u0002\u0002\u0186\u018a\u0003\u0002\u0002\u0002\u0187\u0189\u000b",
"\u0002\u0002\u0002\u0188\u0187\u0003\u0002\u0002\u0002\u0189\u018c\u0003",
"\u0002\u0002\u0002\u018a\u018b\u0003\u0002\u0002\u0002\u018a\u0188\u0003",
"\u0002\u0002\u0002\u018b\u018d\u0003\u0002\u0002\u0002\u018c\u018a\u0003",
"\u0002\u0002\u0002\u018d\u018e\u0007b\u0002\u0002\u018e\u018f\u0007",
"b\u0002\u0002\u018f\u0190\u0007b\u0002\u0002\u0190_\u0003\u0002\u0002",
"\u0002\u0191\u0192\u0007,\u0002\u0002\u0192\u0193\u0007,\u0002\u0002",
"\u0193\u0194\u0003\u0002\u0002\u0002\u0194\u0195\u0005&\u0011\u0002",
"\u0195\u0196\u0005*\u0013\u0002\u0196\u0197\u0005$\u0010\u0002\u0197",
"\u0198\u0005 \u000e\u0002\u0198\u0199\u0005&\u0011\u0002\u0199\u019a",
"\u0005.\u0015\u0002\u019a\u019b\u0005,\u0014\u0002\u019b\u019c\u0007",
"<\u0002\u0002\u019c\u019d\u0007,\u0002\u0002\u019d\u019e\u0007,\u0002",
"\u0002\u019ea\u0003\u0002\u0002\u0002\u019f\u01a0\u000b\u0002\u0002",
"\u0002\u01a0c\u0003\u0002\u0002\u0002\u01a1\u01a2\u0005D \u0002\u01a2",
"\u01a3\u0003\u0002\u0002\u0002\u01a3\u01a4\b0\b\u0002\u01a4e\u0003\u0002",
"\u0002\u0002\u01a5\u01a7\u0007\u000f\u0002\u0002\u01a6\u01a5\u0003\u0002",
"\u0002\u0002\u01a6\u01a7\u0003\u0002\u0002\u0002\u01a7\u01a8\u0003\u0002",
"\u0002\u0002\u01a8\u01a9\u0007\f\u0002\u0002\u01a9\u01aa\u0003\u0002",
"\u0002\u0002\u01aa\u01ab\b1\t\u0002\u01ab\u01ac\b1\n\u0002\u01acg\u0003",
"\u0002\u0002\u0002\u01ad\u01ae\u0007?\u0002\u0002\u01aei\u0003\u0002",
"\u0002\u0002\u01af\u01b0\u0007.\u0002\u0002\u01b0k\u0003\u0002\u0002",
"\u0002\u01b1\u01b2\u0005\u0016\t\u0002\u01b2\u01b3\u0005\b\u0002\u0002",
"\u01b3\u01b4\u0005,\u0014\u0002\u01b4\u01b5\u0005*\u0013\u0002\u01b5",
"\u01b6\u0005$\u0010\u0002\u01b6\u01b7\u0005\u001e\r\u0002\u01b7\u01b9",
"\u0005\u0010\u0006\u0002\u01b8\u01ba\u0005,\u0014\u0002\u01b9\u01b8",
"\u0003\u0002\u0002\u0002\u01b9\u01ba\u0003\u0002\u0002\u0002\u01bam",
"\u0003\u0002\u0002\u0002\u01bb\u01bc\u00050\u0016\u0002\u01bc\u01bd",
"\u0005,\u0014\u0002\u01bd\u01be\u0005\u0010\u0006\u0002\u01be\u01bf",
"\u0005,\u0014\u0002\u01bf\u01c0\u0005\u0012\u0007\u0002\u01c0\u01c1",
"\u0005\u0010\u0006\u0002\u01c1\u01c2\u0005\b\u0002\u0002\u01c2\u01c3",
"\u0005.\u0015\u0002\u01c3\u01c4\u00050\u0016\u0002\u01c4\u01c5\u0005",
"*\u0013\u0002\u01c5\u01c7\u0005\u0010\u0006\u0002\u01c6\u01c8\u0005",
",\u0014\u0002\u01c7\u01c6\u0003\u0002\u0002\u0002\u01c7\u01c8\u0003",
"\u0002\u0002\u0002\u01c8o\u0003\u0002\u0002\u0002\u01c9\u01ca\u0005",
",\u0014\u0002\u01ca\u01cb\u0005\u0018\n\u0002\u01cb\u01cc\u0005 \u000e",
"\u0002\u01cc\u01cd\u0005&\u0011\u0002\u01cd\u01ce\u0005\u001e\r\u0002",
"\u01ce\u01cf\u0005\u0010\u0006\u0002\u01cf\u020f\u0003\u0002\u0002\u0002",
"\u01d0\u01d1\u0005\u001e\r\u0002\u01d1\u01d2\u0005\u0018\n\u0002\u01d2",
"\u01d3\u0005,\u0014\u0002\u01d3\u01d4\u0005.\u0015\u0002\u01d4\u020f",
"\u0003\u0002\u0002\u0002\u01d5\u01d6\u0005*\u0013\u0002\u01d6\u01d7",
"\u0005\u0010\u0006\u0002\u01d7\u01d8\u0005\u0014\b\u0002\u01d8\u01d9",
"\u0005\u0010\u0006\u0002\u01d9\u01da\u00056\u0019\u0002\u01da\u020f",
"\u0003\u0002\u0002\u0002\u01db\u01dc\u0005&\u0011\u0002\u01dc\u01dd",
"\u0005*\u0013\u0002\u01dd\u01de\u0005\u0010\u0006\u0002\u01de\u01df",
"\u0005\n\u0003\u0002\u01df\u01e0\u00050\u0016\u0002\u01e0\u01e1\u0005",
"\u0018\n\u0002\u01e1\u01e2\u0005\u001e\r\u0002\u01e2\u01e3\u0005.\u0015",
"\u0002\u01e3\u020f\u0003\u0002\u0002\u0002\u01e4\u01e5\u0005\f\u0004",
"\u0002\u01e5\u01e6\u0005$\u0010\u0002\u01e6\u01e7\u0005 \u000e\u0002",
"\u01e7\u01e8\u0005&\u0011\u0002\u01e8\u01e9\u0005$\u0010\u0002\u01e9",
"\u01ea\u0005,\u0014\u0002\u01ea\u01eb\u0005\u0018\n\u0002\u01eb\u01ec",
"\u0005.\u0015\u0002\u01ec\u01ed\u0005\u0010\u0006\u0002\u01ed\u020f",
"\u0003\u0002\u0002\u0002\u01ee\u01ef\u0005 \u000e\u0002\u01ef\u01f0",
"\u0005\u001e\r\u0002\u01f0\u020f\u0003\u0002\u0002\u0002\u01f1\u01f2",
"\u0005&\u0011\u0002\u01f2\u01f3\u0005\b\u0002\u0002\u01f3\u01f4\u0005",
".\u0015\u0002\u01f4\u01f5\u0005.\u0015\u0002\u01f5\u01f6\u0005\u0010",
"\u0006\u0002\u01f6\u01f7\u0005*\u0013\u0002\u01f7\u01f8\u0005\"\u000f",
"\u0002\u01f8\u01f9\u0005\b\u0002\u0002\u01f9\u01fa\u0005\"\u000f\u0002",
"\u01fa\u01fb\u00058\u001a\u0002\u01fb\u020f\u0003\u0002\u0002\u0002",
"\u01fc\u01fd\u0005&\u0011\u0002\u01fd\u01fe\u0005\u0016\t\u0002\u01fe",
"\u01ff\u0005*\u0013\u0002\u01ff\u0200\u0005\b\u0002\u0002\u0200\u0201",
"\u0005,\u0014\u0002\u0201\u0202\u0005\u0010\u0006\u0002\u0202\u0203",
"\u0005\u001e\r\u0002\u0203\u0204\u0005\u0018\n\u0002\u0204\u0205\u0005",
",\u0014\u0002\u0205\u0206\u0005.\u0015\u0002\u0206\u020f\u0003\u0002",
"\u0002\u0002\u0207\u0208\u0005\u0018\n\u0002\u0208\u0209\u0005\"\u000f",
"\u0002\u0209\u020a\u0005.\u0015\u0002\u020a\u020b\u0005\u0010\u0006",
"\u0002\u020b\u020c\u0005\"\u000f\u0002\u020c\u020d\u0005.\u0015\u0002",
"\u020d\u020f\u0003\u0002\u0002\u0002\u020e\u01c9\u0003\u0002\u0002\u0002",
"\u020e\u01d0\u0003\u0002\u0002\u0002\u020e\u01d5\u0003\u0002\u0002\u0002",
"\u020e\u01db\u0003\u0002\u0002\u0002\u020e\u01e4\u0003\u0002\u0002\u0002",
"\u020e\u01ee\u0003\u0002\u0002\u0002\u020e\u01f1\u0003\u0002\u0002\u0002",
"\u020e\u01fc\u0003\u0002\u0002\u0002\u020e\u0207\u0003\u0002\u0002\u0002",
"\u020fq\u0003\u0002\u0002\u0002\u0210\u0214\u0007]\u0002\u0002\u0211",
"\u0213\n\"\u0002\u0002\u0212\u0211\u0003\u0002\u0002\u0002\u0213\u0216",
"\u0003\u0002\u0002\u0002\u0214\u0212\u0003\u0002\u0002\u0002\u0214\u0215",
"\u0003\u0002\u0002\u0002\u0215\u0217\u0003\u0002\u0002\u0002\u0216\u0214",
"\u0003\u0002\u0002\u0002\u0217\u0218\u0007_\u0002\u0002\u0218s\u0003",
"\u0002\u0002\u0002\u0219\u021d\u00071\u0002\u0002\u021a\u021c\n\u001f",
"\u0002\u0002\u021b\u021a\u0003\u0002\u0002\u0002\u021c\u021f\u0003\u0002",
"\u0002\u0002\u021d\u021b\u0003\u0002\u0002\u0002\u021d\u021e\u0003\u0002",
"\u0002\u0002\u021eu\u0003\u0002\u0002\u0002\u021f\u021d\u0003\u0002",
"\u0002\u0002\u0220\u0222\n#\u0002\u0002\u0221\u0220\u0003\u0002\u0002",
"\u0002\u0222\u0223\u0003\u0002\u0002\u0002\u0223\u0221\u0003\u0002\u0002",
"\u0002\u0223\u0224\u0003\u0002\u0002\u0002\u0224w\u0003\u0002\u0002",
"\u0002\u0225\u0227\t$\u0002\u0002\u0226\u0228\n%\u0002\u0002\u0227\u0226",
"\u0003\u0002\u0002\u0002\u0228\u0229\u0003\u0002\u0002\u0002\u0229\u0227",
"\u0003\u0002\u0002\u0002\u0229\u022a\u0003\u0002\u0002\u0002\u022a\u022b",
"\u0003\u0002\u0002\u0002\u022b\u022c\t$\u0002\u0002\u022cy\u0003\u0002",
"\u0002\u0002\u022d\u022e\u0005D \u0002\u022e\u022f\u0003\u0002\u0002",
"\u0002\u022f\u0230\b;\b\u0002\u0230{\u0003\u0002\u0002\u0002\u0231\u0232",
"\u0007%\u0002\u0002\u0232\u0233\u0003\u0002\u0002\u0002\u0233\u0234",
"\b<\u000b\u0002\u0234}\u0003\u0002\u0002\u0002\u0235\u0237\u0007\u000f",
"\u0002\u0002\u0236\u0235\u0003\u0002\u0002\u0002\u0236\u0237\u0003\u0002",
"\u0002\u0002\u0237\u0238\u0003\u0002\u0002\u0002\u0238\u0239\u0007\f",
"\u0002\u0002\u0239\u023a\u0003\u0002\u0002\u0002\u023a\u023b\b=\u0002",
"\u0002\u023b\u023c\b=\n\u0002\u023c\u007f\u0003\u0002\u0002\u0002\u023d",
"\u0241\u0005<\u001c\u0002\u023e\u0241\u0005>\u001d\u0002\u023f\u0241",
"\u0007a\u0002\u0002\u0240\u023d\u0003\u0002\u0002\u0002\u0240\u023e",
"\u0003\u0002\u0002\u0002\u0240\u023f\u0003\u0002\u0002\u0002\u0241\u0247",
"\u0003\u0002\u0002\u0002\u0242\u0246\u0005<\u001c\u0002\u0243\u0246",
"\u0005>\u001d\u0002\u0244\u0246\t&\u0002\u0002\u0245\u0242\u0003\u0002",
"\u0002\u0002\u0245\u0243\u0003\u0002\u0002\u0002\u0245\u0244\u0003\u0002",
"\u0002\u0002\u0246\u0249\u0003\u0002\u0002\u0002\u0247\u0245\u0003\u0002",
"\u0002\u0002\u0247\u0248\u0003\u0002\u0002\u0002\u0248\u0081\u0003\u0002",
"\u0002\u0002\u0249\u0247\u0003\u0002\u0002\u0002\u024a\u024b\u00070",
"\u0002\u0002\u024b\u0083\u0003\u0002\u0002\u0002\u024c\u024d\u0005D",
" \u0002\u024d\u024e\u0003\u0002\u0002\u0002\u024e\u024f\b@\b\u0002\u024f",
"\u0085\u0003\u0002\u0002\u0002\u0250\u0252\u0007\u000f\u0002\u0002\u0251",
"\u0250\u0003\u0002\u0002\u0002\u0251\u0252\u0003\u0002\u0002\u0002\u0252",
"\u0253\u0003\u0002\u0002\u0002\u0253\u0254\u0007\f\u0002\u0002\u0254",
"\u0255\u0003\u0002\u0002\u0002\u0255\u0256\bA\t\u0002\u0256\u0257\b",
"A\n\u0002\u0257\u0087\u0003\u0002\u0002\u0002\u0258\u025a\u0007^\u0002",
"\u0002\u0259\u025b\n\u001f\u0002\u0002\u025a\u0259\u0003\u0002\u0002",
"\u0002\u025a\u025b\u0003\u0002\u0002\u0002\u025b\u0089\u0003\u0002\u0002",
"\u0002\u025c\u0268\u0007}\u0002\u0002\u025d\u0267\n\'\u0002\u0002\u025e",
"\u0262\u0007}\u0002\u0002\u025f\u0261\n\u001f\u0002\u0002\u0260\u025f",
"\u0003\u0002\u0002\u0002\u0261\u0264\u0003\u0002\u0002\u0002\u0262\u0260",
"\u0003\u0002\u0002\u0002\u0262\u0263\u0003\u0002\u0002\u0002\u0263\u0265",
"\u0003\u0002\u0002\u0002\u0264\u0262\u0003\u0002\u0002\u0002\u0265\u0267",
"\u0007\u007f\u0002\u0002\u0266\u025d\u0003\u0002\u0002\u0002\u0266\u025e",
"\u0003\u0002\u0002\u0002\u0267\u026a\u0003\u0002\u0002\u0002\u0268\u0266",
"\u0003\u0002\u0002\u0002\u0268\u0269\u0003\u0002\u0002\u0002\u0269\u026b",
"\u0003\u0002\u0002\u0002\u026a\u0268\u0003\u0002\u0002\u0002\u026b\u026c",
"\u0007\u007f\u0002\u0002\u026c\u008b\u0003\u0002\u0002\u0002\u026d\u026f",
"\n(\u0002\u0002\u026e\u026d\u0003\u0002\u0002\u0002\u026f\u0270\u0003",
"\u0002\u0002\u0002\u0270\u0271\u0003\u0002\u0002\u0002\u0270\u026e\u0003",
"\u0002\u0002\u0002\u0271\u008d\u0003\u0002\u0002\u0002\u0272\u0273\u0005",
"D \u0002\u0273\u0274\u0003\u0002\u0002\u0002\u0274\u0275\bE\b\u0002",
"\u0275\u008f\u0003\u0002\u0002\u0002\u0276\u0278\u0007\u000f\u0002\u0002",
"\u0277\u0276\u0003\u0002\u0002\u0002\u0277\u0278\u0003\u0002\u0002\u0002",
"\u0278\u0279\u0003\u0002\u0002\u0002\u0279\u027a\u0007\f\u0002\u0002",
"\u027a\u027b\u0003\u0002\u0002\u0002\u027b\u027c\bF\u0002\u0002\u027c",
"\u027d\bF\n\u0002\u027d\u0091\u0003\u0002\u0002\u0002\u027e\u0282\u0007",
"]\u0002\u0002\u027f\u0281\n\"\u0002\u0002\u0280\u027f\u0003\u0002\u0002",
"\u0002\u0281\u0284\u0003\u0002\u0002\u0002\u0282\u0280\u0003\u0002\u0002",
"\u0002\u0282\u0283\u0003\u0002\u0002\u0002\u0283\u0285\u0003\u0002\u0002",
"\u0002\u0284\u0282\u0003\u0002\u0002\u0002\u0285\u0286\u0007_\u0002",
"\u0002\u0286\u0093\u0003\u0002\u0002\u0002\u0287\u028b\u00071\u0002",
"\u0002\u0288\u028a\n\u001f\u0002\u0002\u0289\u0288\u0003\u0002\u0002",
"\u0002\u028a\u028d\u0003\u0002\u0002\u0002\u028b\u0289\u0003\u0002\u0002",
"\u0002\u028b\u028c\u0003\u0002\u0002\u0002\u028c\u0095\u0003\u0002\u0002",
"\u0002\u028d\u028b\u0003\u0002\u0002\u0002\u028e\u0290\n)\u0002\u0002",
"\u028f\u028e\u0003\u0002\u0002\u0002\u0290\u0291\u0003\u0002\u0002\u0002",
"\u0291\u028f\u0003\u0002\u0002\u0002\u0291\u0292\u0003\u0002\u0002\u0002",
"\u0292\u0097\u0003\u0002\u0002\u0002\u0293\u0294\u0007<\u0002\u0002",
"\u0294\u0099\u0003\u0002\u0002\u0002\u0295\u0297\u0007\u000f\u0002\u0002",
"\u0296\u0295\u0003\u0002\u0002\u0002\u0296\u0297\u0003\u0002\u0002\u0002",
"\u0297\u0298\u0003\u0002\u0002\u0002\u0298\u0299\u0007\f\u0002\u0002",
"\u0299\u029a\u0003\u0002\u0002\u0002\u029a\u029b\bK\u0002\u0002\u029b",
"\u029c\bK\n\u0002\u029c\u009b\u0003\u0002\u0002\u0002\u029d\u029f\n",
"*\u0002\u0002\u029e\u029d\u0003\u0002\u0002\u0002\u029f\u02a0\u0003",
"\u0002\u0002\u0002\u02a0\u029e\u0003\u0002\u0002\u0002\u02a0\u02a1\u0003",
"\u0002\u0002\u0002\u02a1\u009d\u0003\u0002\u0002\u00021\u0002\u0003",
"\u0004\u0005\u0006\u0007\u00dd\u00e0\u00e9\u00f0\u010a\u0111\u0116\u011d",
"\u0126\u012b\u0132\u013a\u013f\u015a\u0162\u017b\u018a\u01a6\u01b9\u01c7",
"\u020e\u0214\u021d\u0223\u0229\u0236\u0240\u0245\u0247\u0251\u025a\u0262",
"\u0266\u0268\u0270\u0277\u0282\u028b\u0291\u0296\u02a0\f\b\u0002\u0002",
"\u0007\u0007\u0002\u0007\u0004\u0002\u0007\u0005\u0002\u0007\u0006\u0002",
"\u0007\u0003\u0002\t\u0003\u0002\t\u0004\u0002\u0006\u0002\u0002\t\t",
"\u0002"].join("");
var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN);

@@ -463,31 +462,30 @@ var decisionsToDFA = atn.decisionToState.map(function (ds, index) { return new antlr4.dfa.DFA(ds, index); });

LUFileLexer.AT = 10;
LUFileLexer.IMPORT_DESC = 11;
LUFileLexer.IMPORT_PATH = 12;
LUFileLexer.FILTER_MARK = 13;
LUFileLexer.QNA_ID_MARK = 14;
LUFileLexer.MULTI_LINE_TEXT = 15;
LUFileLexer.PROMPT_MARK = 16;
LUFileLexer.INVALID_TOKEN_DEFAULT_MODE = 17;
LUFileLexer.EQUAL = 18;
LUFileLexer.COMMA = 19;
LUFileLexer.HAS_ROLES_LABEL = 20;
LUFileLexer.HAS_FEATURES_LABEL = 21;
LUFileLexer.NEW_ENTITY_TYPE_IDENTIFIER = 22;
LUFileLexer.NEW_COMPOSITE_ENTITY = 23;
LUFileLexer.NEW_REGEX_ENTITY = 24;
LUFileLexer.NEW_ENTITY_IDENTIFIER = 25;
LUFileLexer.NEW_ENTITY_IDENTIFIER_WITH_WS = 26;
LUFileLexer.NEWLINE_IN_NAME = 27;
LUFileLexer.IDENTIFIER = 28;
LUFileLexer.DOT = 29;
LUFileLexer.ESCAPE_CHARACTER = 30;
LUFileLexer.EXPRESSION = 31;
LUFileLexer.TEXT = 32;
LUFileLexer.NEWLINE_IN_ENTITY = 33;
LUFileLexer.COMPOSITE_ENTITY = 34;
LUFileLexer.REGEX_ENTITY = 35;
LUFileLexer.ENTITY_TEXT = 36;
LUFileLexer.COLON_MARK = 37;
LUFileLexer.NEWLINE_IN_QNA = 38;
LUFileLexer.QNA_TEXT = 39;
LUFileLexer.IMPORT = 11;
LUFileLexer.FILTER_MARK = 12;
LUFileLexer.QNA_ID_MARK = 13;
LUFileLexer.MULTI_LINE_TEXT = 14;
LUFileLexer.PROMPT_MARK = 15;
LUFileLexer.INVALID_TOKEN_DEFAULT_MODE = 16;
LUFileLexer.EQUAL = 17;
LUFileLexer.COMMA = 18;
LUFileLexer.HAS_ROLES_LABEL = 19;
LUFileLexer.HAS_FEATURES_LABEL = 20;
LUFileLexer.NEW_ENTITY_TYPE_IDENTIFIER = 21;
LUFileLexer.NEW_COMPOSITE_ENTITY = 22;
LUFileLexer.NEW_REGEX_ENTITY = 23;
LUFileLexer.NEW_ENTITY_IDENTIFIER = 24;
LUFileLexer.NEW_ENTITY_IDENTIFIER_WITH_WS = 25;
LUFileLexer.NEWLINE_IN_NAME = 26;
LUFileLexer.IDENTIFIER = 27;
LUFileLexer.DOT = 28;
LUFileLexer.ESCAPE_CHARACTER = 29;
LUFileLexer.EXPRESSION = 30;
LUFileLexer.TEXT = 31;
LUFileLexer.NEWLINE_IN_ENTITY = 32;
LUFileLexer.COMPOSITE_ENTITY = 33;
LUFileLexer.REGEX_ENTITY = 34;
LUFileLexer.ENTITY_TEXT = 35;
LUFileLexer.COLON_MARK = 36;
LUFileLexer.NEWLINE_IN_QNA = 37;
LUFileLexer.QNA_TEXT = 38;
LUFileLexer.NEW_ENTITY_MODE = 1;

@@ -503,17 +501,17 @@ LUFileLexer.INTENT_NAME_MODE = 2;

null, null, null, "'$'", "'@'", null,
null, null, null, null, null, "'='",
"','", null, null, null, null, null,
null, null, null, null, "'.'", null,
null, null, null, null, null, null,
"'='", "','", null, null, null, null,
null, null, null, null, null, "'.'",
null, null, null, null, null, null,
null, "':'"];
"':'"];
LUFileLexer.prototype.symbolicNames = [null, "WS", "NEWLINE", "QNA_SOURCE_INFO",
"MODEL_INFO", "COMMENT", "QNA",
"HASH", "DASH", "DOLLAR", "AT",
"IMPORT_DESC", "IMPORT_PATH", "FILTER_MARK",
"QNA_ID_MARK", "MULTI_LINE_TEXT",
"PROMPT_MARK", "INVALID_TOKEN_DEFAULT_MODE",
"EQUAL", "COMMA", "HAS_ROLES_LABEL",
"HAS_FEATURES_LABEL", "NEW_ENTITY_TYPE_IDENTIFIER",
"NEW_COMPOSITE_ENTITY", "NEW_REGEX_ENTITY",
"NEW_ENTITY_IDENTIFIER", "NEW_ENTITY_IDENTIFIER_WITH_WS",
"IMPORT", "FILTER_MARK", "QNA_ID_MARK",
"MULTI_LINE_TEXT", "PROMPT_MARK",
"INVALID_TOKEN_DEFAULT_MODE", "EQUAL",
"COMMA", "HAS_ROLES_LABEL", "HAS_FEATURES_LABEL",
"NEW_ENTITY_TYPE_IDENTIFIER", "NEW_COMPOSITE_ENTITY",
"NEW_REGEX_ENTITY", "NEW_ENTITY_IDENTIFIER",
"NEW_ENTITY_IDENTIFIER_WITH_WS",
"NEWLINE_IN_NAME", "IDENTIFIER",

@@ -530,18 +528,18 @@ "DOT", "ESCAPE_CHARACTER", "EXPRESSION",

"MODEL_INFO", "COMMENT", "QNA", "HASH",
"DASH", "DOLLAR", "AT", "IMPORT_DESC",
"IMPORT_PATH", "FILTER_MARK", "QNA_ID_MARK",
"MULTI_LINE_TEXT", "PROMPT_MARK", "INVALID_TOKEN_DEFAULT_MODE",
"WS_IN_NEW_ENTITY", "NEWLINE_IN_NEW_ENTITY",
"EQUAL", "COMMA", "HAS_ROLES_LABEL",
"HAS_FEATURES_LABEL", "NEW_ENTITY_TYPE_IDENTIFIER",
"NEW_COMPOSITE_ENTITY", "NEW_REGEX_ENTITY",
"NEW_ENTITY_IDENTIFIER", "NEW_ENTITY_IDENTIFIER_WITH_WS",
"WS_IN_NAME", "HASH_IN_NAME", "NEWLINE_IN_NAME",
"IDENTIFIER", "DOT", "WS_IN_LIST_BODY",
"NEWLINE_IN_LIST_BODY", "ESCAPE_CHARACTER",
"EXPRESSION", "TEXT", "WS_IN_ENTITY",
"NEWLINE_IN_ENTITY", "COMPOSITE_ENTITY",
"REGEX_ENTITY", "ENTITY_TEXT", "COLON_MARK",
"NEWLINE_IN_QNA", "QNA_TEXT"];
"DASH", "DOLLAR", "AT", "IMPORT", "FILTER_MARK",
"QNA_ID_MARK", "MULTI_LINE_TEXT", "PROMPT_MARK",
"INVALID_TOKEN_DEFAULT_MODE", "WS_IN_NEW_ENTITY",
"NEWLINE_IN_NEW_ENTITY", "EQUAL", "COMMA",
"HAS_ROLES_LABEL", "HAS_FEATURES_LABEL",
"NEW_ENTITY_TYPE_IDENTIFIER", "NEW_COMPOSITE_ENTITY",
"NEW_REGEX_ENTITY", "NEW_ENTITY_IDENTIFIER",
"NEW_ENTITY_IDENTIFIER_WITH_WS", "WS_IN_NAME",
"HASH_IN_NAME", "NEWLINE_IN_NAME", "IDENTIFIER",
"DOT", "WS_IN_LIST_BODY", "NEWLINE_IN_LIST_BODY",
"ESCAPE_CHARACTER", "EXPRESSION", "TEXT",
"WS_IN_ENTITY", "NEWLINE_IN_ENTITY",
"COMPOSITE_ENTITY", "REGEX_ENTITY",
"ENTITY_TEXT", "COLON_MARK", "NEWLINE_IN_QNA",
"QNA_TEXT"];
LUFileLexer.prototype.grammarFileName = "LUFileLexer.g4";
exports.LUFileLexer = LUFileLexer;

@@ -12,27 +12,31 @@ "use strict";

this.ParseTree = parseTree;
this.Errors = [];
this.SectionType = LUSectionTypes.IMPORTSECTION;
this.Description = this.ExtractDescription(parseTree);
let result = this.ExtractPath(parseTree);
this.Path = result.importPath;
this.Errors = result.errors;
let result = this.ExtractDescriptionAndPath(parseTree);
this.Description = result.description;
this.Path = result.path;
this.Id = `${this.SectionType}_${this.Path}`;
;
}
ExtractDescription(parseTree) {
return parseTree.importDefinition().IMPORT_DESC().getText();
}
ExtractPath(parseTree) {
let errors = [];
let importPath = parseTree.importDefinition().IMPORT_PATH().getText().replace('(', '').replace(')', '');
if (importPath === undefined || importPath === '') {
let errorMsg = `LU file reference path is empty: "${parseTree.getText()}"`;
let error = BuildDiagnostic({
message: errorMsg,
context: parseTree
});
errors.push(error);
ExtractDescriptionAndPath(parseTree) {
let importRegex = new RegExp(/\[([^\]]*)\]\(([^\)]*)\)/);
let importStr = parseTree.importDefinition().IMPORT().getText();
let description;
let path;
let groups = importStr.match(importRegex);
if (groups && groups.length === 3) {
description = groups[1].trim();
path = groups[2].trim();
if (path === undefined || path === '') {
let errorMsg = `LU file reference path is empty: "${parseTree.getText()}"`;
let error = BuildDiagnostic({
message: errorMsg,
context: parseTree
});
this.Errors.push(error);
}
}
return { importPath, errors };
return { description, path };
}
}
module.exports = ImportSection;

@@ -122,3 +122,3 @@ "use strict";

}
this.extractIntentBody(sections, content);
this.extractSectionBody(sections, content);
return new LUResource(sections, content, errors);

@@ -265,7 +265,10 @@ }

*/
static extractIntentBody(sections, content) {
static extractSectionBody(sections, content) {
sections.sort((a, b) => a.ParseTree.start.line - b.ParseTree.start.line);
const originList = content.split(/\r?\n/);
let qnaSectionIndex = 0;
sections.forEach(function (section, index) {
if (section.SectionType === SectionType.SIMPLEINTENTSECTION || section.SectionType === SectionType.NESTEDINTENTSECTION) {
if (section.SectionType === SectionType.SIMPLEINTENTSECTION
|| section.SectionType === SectionType.NESTEDINTENTSECTION
|| section.SectionType === SectionType.QNASECTION) {
const startLine = section.ParseTree.start.line - 1;

@@ -282,3 +285,11 @@ let stopLine;

}
const destList = originList.slice(startLine + 1, stopLine);
let destList;
if (section.SectionType === SectionType.QNASECTION) {
destList = originList.slice(startLine, stopLine);
section.Id = qnaSectionIndex;
qnaSectionIndex++;
}
else {
destList = originList.slice(startLine + 1, stopLine);
}
section.Body = destList.join(NEWLINE);

@@ -288,3 +299,3 @@ section.StartLine = startLine;

if (section.SectionType === SectionType.NESTEDINTENTSECTION) {
LUParser.extractIntentBody(section.SimpleIntentSections, originList.slice(0, stopLine).join(NEWLINE));
LUParser.extractSectionBody(section.SimpleIntentSections, originList.slice(0, stopLine).join(NEWLINE));
}

@@ -291,0 +302,0 @@ }

@@ -6,2 +6,3 @@ "use strict";

const LUSectionTypes = require('./../utils/enums/lusectiontypes');
const InvalidCharsInIntentOrEntityName = require('./../utils/enums/invalidchars').InvalidCharsInIntentOrEntityName;
class NewEntitySection {

@@ -26,7 +27,8 @@ /**

ExtractName(parseTree) {
let entityName;
if (parseTree.newEntityDefinition().newEntityLine().newEntityName()) {
return parseTree.newEntityDefinition().newEntityLine().newEntityName().getText().trim();
entityName = parseTree.newEntityDefinition().newEntityLine().newEntityName().getText().trim();
}
else if (parseTree.newEntityDefinition().newEntityLine().newEntityNameWithWS()) {
return parseTree.newEntityDefinition().newEntityLine().newEntityNameWithWS().getText().trim();
entityName = parseTree.newEntityDefinition().newEntityLine().newEntityNameWithWS().getText().trim();
}

@@ -39,2 +41,11 @@ else {

}
if (entityName && InvalidCharsInIntentOrEntityName.some(x => entityName.includes(x))) {
this.Errors.push(BuildDiagnostic({
message: `Invalid entity line, entity name ${entityName} cannot contain any of the following characters: [<, >, *, %, &, :, \\, $]`,
context: parseTree.newEntityDefinition().newEntityLine()
}));
}
else {
return entityName;
}
}

@@ -41,0 +52,0 @@ ExtractType(parseTree) {

@@ -5,3 +5,2 @@ "use strict";

const BuildDiagnostic = require('./diagnostic').BuildDiagnostic;
const helpers = require('../utils/helpers');
const QNA_GENERIC_SOURCE = "custom editorial";

@@ -28,3 +27,3 @@ class QnaSection {

this.Errors = this.Errors.concat(result.errors);
this.Id = this.ExtractAssignedId(parseTree);
this.QAPairId = this.ExtractAssignedId(parseTree);
this.source = this.ExtractSourceInfo(parseTree);

@@ -35,3 +34,3 @@ }

if (srcAssignment) {
let srcRegExp = new RegExp(/^[ ]*\>[ ]*!#[ ]*@qna.pair.source[ ]*=[ ]*(?<sourceInfo>.*?)$/gmi);
let srcRegExp = /^[ ]*\>[ ]*!#[ ]*@qna.pair.source[ ]*=[ ]*(?<sourceInfo>.*?)$/gmi;
let srcParsed = srcRegExp.exec(srcAssignment.getText().trim());

@@ -45,3 +44,3 @@ return srcParsed.groups.sourceInfo || QNA_GENERIC_SOURCE;

if (idAssignment) {
let idTextRegExp = new RegExp(/^\<a[ ]*id[ ]*=[ ]*[\"\'](?<idCaptured>.*?)[\"\'][ ]*>[ ]*\<\/a\>$/gmi);
let idTextRegExp = /^\<a[ ]*id[ ]*=[ ]*[\"\'](?<idCaptured>.*?)[\"\'][ ]*>[ ]*\<\/a\>$/gmi;
let idTextParsed = idTextRegExp.exec(idAssignment.getText().trim());

@@ -74,3 +73,3 @@ return idTextParsed.groups.idCaptured || undefined;

promptTextList.push(filterLineText);
let promptConfigurationRegExp = new RegExp(/^\[(?<displayText>.*?)]\([ ]*\#[ ]*[ ?]*(?<linkedQuestion>.*?)\)[ ]*(?<contextOnly>\`context-only\`)?.*?$/gmi);
let promptConfigurationRegExp = /^\[(?<displayText>.*?)]\([ ]*\#[ ]*[ ?]*(?<linkedQuestion>.*?)\)[ ]*(?<contextOnly>\`context-only\`)?.*?$/gmi;
let splitLine = promptConfigurationRegExp.exec(filterLineText);

@@ -77,0 +76,0 @@ if (!splitLine) {

@@ -40,9 +40,17 @@ "use strict";

}
insertSection(id, sectionContent) {
sectionContent = helpers.sanitizeNewLines(sectionContent);
const section = this.Luresource.Sections.find(u => u.Id === id);
if (!section && this.Luresource.Sections.length > 0) {
return this.Luresource;
}
const startLine = section ? section.StartLine : 0;
const newContent = this.replaceRangeContent(this.Luresource.Content, startLine, startLine - 1, sectionContent);
const result = luParser.parse(newContent);
return result;
}
replaceRangeContent(originString, startLine, stopLine, replaceString) {
if (!originString) {
throw new Error('replace content with error parameters.');
}
const originList = originString.split(/\r?\n/);
let destList = [];
if (isNaN(startLine) || isNaN(stopLine) || startLine < 0 || startLine > stopLine || originList.length <= stopLine) {
if (isNaN(startLine) || isNaN(stopLine) || startLine < 0 || startLine > stopLine + 1 || originList.length <= stopLine) {
throw new Error("index out of range.");

@@ -49,0 +57,0 @@ }

"use strict";
const lp = require('./generated/LUFileParser').LUFileParser;
const LUISObjNameEnum = require('./../utils/enums/luisobjenum');
const InvalidCharsInIntentOrEntityName = require('./../utils/enums/invalidchars').InvalidCharsInIntentOrEntityName;
class Visitor {

@@ -40,2 +41,7 @@ /**

if (item === Object(item)) {
let entityName = item.entityName.trim();
if (entityName && InvalidCharsInIntentOrEntityName.some(x => entityName.includes(x))) {
errorMsgs.push(`Invalid utterance line, entity name ${entityName} cannot contain any of the following characters: [<, >, *, %, &, :, \\, $]`);
continue;
}
if (item.entityValue === undefined) {

@@ -42,0 +48,0 @@ // we have a pattern.any entity

@@ -98,4 +98,7 @@ "use strict";

}
// remove duplicated whitespaces between words inside utterance to make sure they are aligned with the luis portal
// as luis portal only keeps one whitespace between words even if you type multiple ones
// this will benefit the comparison of lu files that are converted from local and remote luis application
if (updatedText)
fileContent += '- ' + updatedText + NEWLINE;
fileContent += '- ' + updatedText.replace(/\s+/g, ' ') + NEWLINE;
});

@@ -324,4 +327,9 @@ return fileContent;

flags += `disabled`;
if (entity.enabledForAllModels !== undefined && entity.enabledForAllModels) {
flags += (flags !== '') ? `, enabledForAllModels` : `enabledForAllModels`;
if (entity.enabledForAllModels !== undefined) {
if (entity.enabledForAllModels === true) {
flags += (flags !== '') ? `, enabledForAllModels` : `enabledForAllModels`;
}
else {
flags += (flags !== '') ? `, disabledForAllModels` : `disabledForAllModels`;
}
}

@@ -328,0 +336,0 @@ if (flags !== '')

@@ -30,3 +30,3 @@ "use strict";

}
async loadContents(files, inputFolder, botName, suffix, region, culture) {
async loadContents(files, botName, suffix, region, culture, schema) {
let multiRecognizer;

@@ -37,5 +37,13 @@ let settings;

for (const file of files) {
const qnaFiles = await fileHelper.getLuObjects(undefined, file, true, fileExtEnum.QnAFile);
let fileCulture;
let cultureFromPath = fileHelper.getCultureFromPath(file);
if (cultureFromPath) {
fileCulture = cultureFromPath;
}
else {
fileCulture = culture;
}
let fileContent = '';
let result;
const qnaFiles = await fileHelper.getLuObjects(undefined, file, true, fileExtEnum.QnAFile);
try {

@@ -56,21 +64,17 @@ result = await qnaBuilderVerbose.build(qnaFiles, true);

this.handler(`${file} loaded\n`);
let fileCulture;
let cultureFromPath = fileHelper.getCultureFromPath(file);
if (cultureFromPath) {
fileCulture = cultureFromPath;
}
else {
fileCulture = culture;
}
const fileFolder = path.dirname(file);
if (multiRecognizer === undefined) {
const multiRecognizerPath = path.join(inputFolder, `${botName}.qna.dialog`);
const multiRecognizerPath = path.join(fileFolder, `${botName}.qna.dialog`);
let multiRecognizerContent = {};
let multiRecognizerSchema = schema;
if (fs.existsSync(multiRecognizerPath)) {
multiRecognizerContent = JSON.parse(await fileHelper.getContentFromFile(multiRecognizerPath)).recognizers;
let multiRecognizerObject = JSON.parse(await fileHelper.getContentFromFile(multiRecognizerPath));
multiRecognizerContent = multiRecognizerObject.recognizers;
multiRecognizerSchema = multiRecognizerSchema || multiRecognizerObject.$schema;
this.handler(`${multiRecognizerPath} loaded\n`);
}
multiRecognizer = new multi_language_recognizer_1.MultiLanguageRecognizer(multiRecognizerPath, multiRecognizerContent);
multiRecognizer = new multi_language_recognizer_1.MultiLanguageRecognizer(multiRecognizerPath, multiRecognizerContent, multiRecognizerSchema);
}
if (settings === undefined) {
const settingsPath = path.join(inputFolder, `qnamaker.settings.${suffix}.${region}.json`);
const settingsPath = path.join(fileFolder, `qnamaker.settings.${suffix}.${region}.json`);
let settingsContent = {};

@@ -85,3 +89,3 @@ if (fs.existsSync(settingsPath)) {

if (!recognizers.has(content.name)) {
const dialogFile = path.join(inputFolder, `${content.name}.dialog`);
const dialogFile = path.join(fileFolder, `${content.name}.dialog`);
let existingDialogObj;

@@ -92,3 +96,6 @@ if (fs.existsSync(dialogFile)) {

}
let recognizer = recognizer_1.Recognizer.load(content.path, content.name, dialogFile, settings, existingDialogObj);
if (existingDialogObj && schema) {
existingDialogObj.$schema = schema;
}
let recognizer = recognizer_1.Recognizer.load(content.path, content.name, dialogFile, settings, existingDialogObj, schema);
recognizers.set(content.name, recognizer);

@@ -239,3 +246,3 @@ qnaContents.set(content.name, content);

}
async writeDialogAssets(contents, force, out, dialogType, files) {
async writeDialogAssets(contents, force, out, dialogType, files, schema) {
let writeDone = false;

@@ -252,3 +259,3 @@ for (const content of contents) {

this.handler(`Writing to ${outFilePath}\n`);
await this.writeDialog(content.content, outFilePath, dialogType, files);
await this.writeDialog(content.content, outFilePath, dialogType, files, schema);
writeDone = true;

@@ -395,3 +402,3 @@ }

}
async writeDialog(content, filePath, dialogType, files) {
async writeDialog(content, filePath, dialogType, files, schema) {
await fs.writeFile(filePath, content, 'utf-8');

@@ -422,3 +429,3 @@ const contentObj = JSON.parse(content);

let recognizers = [fileName];
content = new cross_trained_recognizer_1.CrossTrainedRecognizer(crossTrainedFilePath, recognizers).save();
content = new cross_trained_recognizer_1.CrossTrainedRecognizer(crossTrainedFilePath, recognizers, schema).save();
}

@@ -425,0 +432,0 @@ await fs.writeFile(crossTrainedFilePath, content, 'utf-8');

@@ -8,2 +8,4 @@ "use strict";

const path = require("path");
const retCode = require('./../utils/enums/CLI-errors');
const exception = require('./../utils/exception');
const Content = require('./../lu/qna');

@@ -20,8 +22,7 @@ const LUOptions = require('./../lu/luOptions');

const text = await response.text();
try {
return JSON.parse(text);
const kbList = JSON.parse(text);
if (kbList.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
return kbList;
}

@@ -31,8 +32,7 @@ async getKB(kbId) {

const text = await response.text();
try {
return JSON.parse(text);
const kb = JSON.parse(text);
if (kb.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
return kb;
}

@@ -42,8 +42,7 @@ async importKB(kbPayload) {

const text = await response.text();
try {
return JSON.parse(text);
const status = JSON.parse(text);
if (status.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
return status;
}

@@ -53,8 +52,7 @@ async getOperationStatus(operationId) {

const text = await response.text();
try {
return JSON.parse(text);
const status = JSON.parse(text);
if (status.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
return status;
}

@@ -64,8 +62,7 @@ async exportKB(kbId, environment) {

const text = await response.text();
try {
return JSON.parse(text);
const kb = JSON.parse(text);
if (kb.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
return kb;
}

@@ -75,8 +72,7 @@ async updateKB(kbId, replaceKb) {

const text = await response.text();
try {
return JSON.parse(text);
const status = JSON.parse(text);
if (status.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
return status;
}

@@ -86,8 +82,5 @@ async replaceKB(kbId, replaceKb) {

const text = await response.text();
try {
return JSON.parse(text);
if (text) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
}

@@ -97,8 +90,5 @@ async publishKB(kbId) {

const text = await response.text();
try {
return JSON.parse(text);
if (text) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
}

@@ -108,8 +98,5 @@ async replaceAlt(altJson) {

const text = await response.text();
try {
return JSON.parse(text);
if (text) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
}

@@ -119,8 +106,7 @@ async getEndpointKeys() {

const text = await response.text();
try {
return JSON.parse(text);
const endpointKeys = JSON.parse(text);
if (endpointKeys.error) {
throw (new exception(retCode.errorCode.LUIS_API_CALL_FAILED, text));
}
catch (_a) {
return text;
}
return endpointKeys;
}

@@ -151,3 +137,3 @@ generateDeclarativeAssets(recognizers, multiRecognizer, settings) {

questions: qna.questions.slice(),
metadata: qna.metadata,
metadata: qna.metadata.slice(),
context: qna.context

@@ -188,3 +174,3 @@ };

fileContent += '**Filters:**' + NEWLINE;
qnaItem.metadata.forEach((filter) => {
qnaItem.metadata.sort((a, b) => (a.name > b.name) ? 1 : -1).forEach((filter) => {
fileContent += '- ' + filter.name + ' = ' + filter.value + NEWLINE;

@@ -191,0 +177,0 @@ });

@@ -8,5 +8,6 @@ "use strict";

class CrossTrainedRecognizer {
constructor(dialogPath, recognizers) {
constructor(dialogPath, recognizers, schema) {
this.dialogPath = dialogPath;
this.recognizers = recognizers;
this.$schema = schema;
}

@@ -18,2 +19,5 @@ save() {

};
if (this.$schema) {
output = Object.assign({ $schema: this.$schema }, output);
}
return JSON.stringify(output, null, 4);

@@ -20,0 +24,0 @@ }

@@ -7,6 +7,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const path = require('path');
class MultiLanguageRecognizer {
constructor(dialogPath, recognizers) {
constructor(dialogPath, recognizers, schema) {
this.id = `QnA_${path.basename(dialogPath).split('.')[0]}`;
this.dialogPath = dialogPath;
this.recognizers = recognizers;
this.$schema = schema;
}

@@ -16,4 +19,8 @@ save() {

$kind: 'Microsoft.MultiLanguageRecognizer',
id: this.id,
recognizers: this.recognizers
};
if (this.$schema) {
output = Object.assign({ $schema: this.$schema }, output);
}
return JSON.stringify(output, null, 4);

@@ -20,0 +27,0 @@ }

@@ -9,3 +9,3 @@ "use strict";

class Recognizer {
constructor(qnaFile, targetFileName) {
constructor(qnaFile, targetFileName, schema) {
this.qnaFile = qnaFile;

@@ -17,6 +17,7 @@ this.kbId = '';

this.endpointKey = '=settings.qna.endpointKey';
this.$schema = schema;
}
static load(qnaFile, targetFileName, dialogPath, qnaSettings, existingRecognizer) {
static load(qnaFile, targetFileName, dialogPath, qnaSettings, existingRecognizer, schema) {
if (existingRecognizer) {
let recognizer = new Recognizer(qnaFile, targetFileName);
let recognizer = new Recognizer(qnaFile, targetFileName, schema);
recognizer.dialogPath = dialogPath;

@@ -27,3 +28,3 @@ Object.assign(recognizer, existingRecognizer);

}
let recognizer = new Recognizer(qnaFile, targetFileName);
let recognizer = new Recognizer(qnaFile, targetFileName, schema);
recognizer.dialogPath = dialogPath;

@@ -40,2 +41,5 @@ return recognizer;

};
if (this.$schema) {
output = Object.assign({ $schema: this.$schema }, output);
}
return JSON.stringify(output, null, 4);

@@ -42,0 +46,0 @@ }

@@ -199,3 +199,3 @@ "use strict";

exports.getParsedObjects = getParsedObjects;
function getConfigObject(configContent, intentName) {
function getConfigObject(configContent, intentName, verbose) {
let finalLuConfigObj = Object.create(null);

@@ -252,3 +252,3 @@ let rootLuFiles = [];

intentName,
verbose: true
verbose
};

@@ -255,0 +255,0 @@ return crossTrainConfig;

{
"name": "@microsoft/bf-lu",
"version": "4.9.1",
"version": "4.10.0-dev.20200714.6b8b8a9",
"author": "Microsoft",

@@ -25,3 +25,2 @@ "bugs": "https://github.com/microsoft/botframework-cli/issues",

"coverage": "nyc npm run test",
"report:coverage": "npm run coverage && nyc report --reporter=text-lcov | coveralls",
"doc": "",

@@ -63,2 +62,3 @@ "doc:readme": "",

"@types/mocha": "^5.2.7",
"@types/nock": "^11.1.0",
"@types/node": "^10.14.15",

@@ -65,0 +65,0 @@ "chai": "^4.2.0",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc