earningscall
Version:
The EarningsCall JavaScript library provides convenient access to the EarningsCall API. It includes a pre-defined set of classes for API resources that initialize themselves dynamically from API responses.
257 lines • 19.9 kB
JavaScript
import { getTranscript, getEvents, getSp500CompaniesTxtFile, downloadAudioFile, isDemoAccount, } from './api';
import { camelCaseKeys } from './camel-case';
import { InsufficientApiAccessError, MissingApiKeyError, NotFoundError, } from './errors';
import { EXCHANGES_IN_ORDER, getSymbols } from './symbols';
export class Company {
companyInfo;
name;
events_;
constructor(companyInfo) {
this.companyInfo = companyInfo;
this.name = companyInfo.name;
this.events_ = undefined;
}
toString() {
return String(this.name);
}
/**
* Get the events for the company. Useful for getting the earnings events for a company.
*
* @returns A promise that resolves to an array of EarningsEvent objects.
*/
async getEvents() {
const rawResponse = await getEvents(this.companyInfo.exchange, this.companyInfo.symbol);
const responseAsRecord = rawResponse;
const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true });
const eventsResponse = camelCasedObject;
this.events_ = eventsResponse.events;
return this.events_;
}
async events() {
return await this.getEvents();
}
validateTranscriptOptions(options) {
const { year, quarter } = options;
if (year === undefined || quarter === undefined) {
throw new Error('Must specify either event or year and quarter');
}
if (year < 1990 || year > 2030) {
throw new Error('Invalid year. Must be between 1990 and 2030');
}
if (![1, 2, 3, 4].includes(quarter)) {
throw new Error('Invalid quarter. Must be one of: {1,2,3,4}');
}
}
getOptions(options) {
if (options.event !== undefined) {
const event = options.event;
const { year, quarter } = event;
return { year, quarter };
}
const { year, quarter } = options;
return { year, quarter };
}
/**
* Retrieve a single transcript for this company. This is the basic transcript with no speaker groups.
*
* @param options - The options for getting a transcript.
* @returns A promise that resolves to a Transcript object or undefined if not found.
*/
async getBasicTranscript(options) {
const transcriptOptions = this.getOptions(options);
this.validateTranscriptOptions(transcriptOptions);
const { year, quarter } = transcriptOptions;
try {
const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 1);
const responseAsRecord = response;
const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true });
const transcript = camelCasedObject;
return transcript;
}
catch (error) {
if (error instanceof NotFoundError) {
return undefined; // Transcript not found
}
throw error;
}
}
handleEnhancedTranscriptDataError(error) {
if (error instanceof InsufficientApiAccessError) {
const planName = error.response.headers.get('X-Plan-Name');
throw new InsufficientApiAccessError(`Your plan (${planName}) does not include Enhanced Transcript Data. Upgrade your plan here: https://earningscall.biz/api-pricing`, error.response);
}
}
/**
* Retrieve a single transcript for this company with speaker groups.
*
* Requires an Enhanced Transcript Data plan.
*
* @param options - The options for getting a transcript.
* @returns A promise that resolves to a Transcript object or undefined if not found.
*/
async getSpeakerGroups(options) {
const transcriptOptions = this.getOptions(options);
this.validateTranscriptOptions(transcriptOptions);
const { year, quarter } = transcriptOptions;
try {
const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 2);
const responseAsRecord = response;
const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true });
const transcript = camelCasedObject;
if (transcript.speakerNameMapV2) {
for (const speaker of transcript.speakers) {
const speakerLabel = speaker.speaker;
if (transcript.speakerNameMapV2[speakerLabel]) {
speaker.speakerInfo = transcript.speakerNameMapV2[speakerLabel];
}
}
}
return transcript;
}
catch (error) {
if (error instanceof NotFoundError) {
return undefined; // Transcript not found
}
this.handleEnhancedTranscriptDataError(error);
throw error;
}
}
/**
* Retrieve a single transcript for this company with word level timestamps.
*
* Requires an Enhanced Transcript Data plan.
*
* @param options - The options for getting a transcript.
* @returns A promise that resolves to a TranscriptV3 object or undefined if not found.
*/
async getWordLevelTimestamps(options) {
const transcriptOptions = this.getOptions(options);
this.validateTranscriptOptions(transcriptOptions);
const { year, quarter } = transcriptOptions;
try {
const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 3);
const responseAsRecord = response;
const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true });
const transcript = camelCasedObject;
return transcript;
}
catch (error) {
if (error instanceof NotFoundError) {
return undefined; // Transcript not found
}
this.handleEnhancedTranscriptDataError(error);
throw error;
}
}
/**
* Retrieve a single transcript for this company with question and answer transcripts.
*
* Requires an Enhanced Transcript Data plan.
*
* @param options - The options for getting a transcript.
* @returns A promise that resolves to a TranscriptV4 object or undefined if not found.
*/
async getQuestionAndAnswerTranscript(options) {
const transcriptOptions = this.getOptions(options);
this.validateTranscriptOptions(transcriptOptions);
const { year, quarter } = transcriptOptions;
try {
const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 4);
const responseAsRecord = response;
const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true });
const transcript = camelCasedObject;
return transcript;
}
catch (error) {
if (error instanceof NotFoundError) {
return undefined; // Transcript not found
}
this.handleEnhancedTranscriptDataError(error);
throw error;
}
}
/**
* Downloads a single audio file for this company to disk.
*
* @param options - The options for getting an audio file.
* @returns A promise that resolves to a GetAudioFileResponse object.
*/
async downloadAudioFile(options) {
const { year, quarter, outputFilePath } = options;
try {
const response = await downloadAudioFile(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, outputFilePath);
return response;
}
catch (error) {
if (error instanceof NotFoundError) {
return undefined;
}
throw error;
}
}
}
/**
* Get a company by symbol and optionally, exchange.
*
* @param options - The options for getting a company.
* @returns A promise that resolves to a Company object.
*/
export async function getCompany(options) {
const companyInfo = await lookupCompany(options);
if (!companyInfo) {
throw new Error(`Symbol not found: ${options.symbol}`);
}
return new Company(companyInfo);
}
export async function lookupCompany(options) {
const { exchange, symbol } = options;
const symbols = await getSymbols();
if (exchange) {
return symbols.get(exchange.toUpperCase(), symbol.toUpperCase());
}
for (const exchange of EXCHANGES_IN_ORDER) {
const info = symbols.get(exchange, symbol.toUpperCase());
if (info) {
return info;
}
}
if (isDemoAccount()) {
throw new MissingApiKeyError(`"${symbol}" requires an API Key for access. To get your API Key, ` +
'see: https://earningscall.biz/api-pricing');
}
return undefined;
}
export async function getAllCompaniesInfos() {
const symbols = await getSymbols();
return Array.from(symbols.getAll());
}
/**
* Get all companies.
*
* @returns A promise that resolves to an array of Company objects.
*/
export async function getAllCompanies() {
const infos = await getAllCompaniesInfos();
return infos.map((info) => new Company(info));
}
/**
* Get all S&P 500 companies.
*
* @returns A promise that resolves to an array of Company objects.
*/
export async function getSP500Companies() {
const sp500CompaniesTxtFile = await getSp500CompaniesTxtFile();
const symbols = sp500CompaniesTxtFile.split('\n').map((line) => line.trim());
const companyPromises = symbols.map(async (symbol) => {
try {
return await getCompany({ symbol });
}
catch (error) {
return null;
}
});
const results = await Promise.all(companyPromises);
// Filter out null values and explicitly type as Company[]
return results.filter((company) => company !== null);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGFueS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvY29tcGFueS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFlQSxPQUFPLEVBQ0wsYUFBYSxFQUNiLFNBQVMsRUFDVCx3QkFBd0IsRUFDeEIsaUJBQWlCLEVBQ2pCLGFBQWEsR0FDZCxNQUFNLE9BQU8sQ0FBQztBQUNmLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUNMLDBCQUEwQixFQUMxQixrQkFBa0IsRUFDbEIsYUFBYSxHQUNkLE1BQU0sVUFBVSxDQUFDO0FBRWxCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFM0QsTUFBTSxPQUFPLE9BQU87SUFDVCxXQUFXLENBQWM7SUFDekIsSUFBSSxDQUFVO0lBQ2YsT0FBTyxDQUFtQjtJQUVsQyxZQUFZLFdBQXdCO1FBQ2xDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztJQUMzQixDQUFDO0lBRUQsUUFBUTtRQUNOLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLEtBQUssQ0FBQyxTQUFTO1FBQ3JCLE1BQU0sV0FBVyxHQUFHLE1BQU0sU0FBUyxDQUNqQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQ3hCLENBQUM7UUFDRixNQUFNLGdCQUFnQixHQUFHLFdBQXNDLENBQUM7UUFDaEUsTUFBTSxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN6RSxNQUFNLGNBQWMsR0FBRyxnQkFBa0MsQ0FBQztRQUMxRCxJQUFJLENBQUMsT0FBTyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFDckMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTTtRQUNWLE9BQU8sTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDaEMsQ0FBQztJQUVELHlCQUF5QixDQUFDLE9BQTZCO1FBQ3JELE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxDQUFDO1FBRWxDLElBQUksSUFBSSxLQUFLLFNBQVMsSUFBSSxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDaEQsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO1FBQ25FLENBQUM7UUFFRCxJQUFJLElBQUksR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBRUQsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1FBQ2hFLENBQUM7SUFDSCxDQUFDO0lBRUQsVUFBVSxDQUNSLE9BQTZEO1FBRTdELElBQUssT0FBeUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkUsTUFBTSxLQUFLLEdBQUksT0FBeUMsQ0FBQyxLQUFLLENBQUM7WUFDL0QsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUFLLENBQUM7WUFDaEMsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUErQixDQUFDO1FBQzFELE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUN0QixPQUE2RDtRQUU3RCxNQUFNLGlCQUFpQixHQUF5QixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsaUJBQWlCLENBQUM7UUFFNUMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxhQUFhLENBQ2xDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFDdkIsSUFBSSxFQUNKLE9BQU8sRUFDUCxDQUFDLENBQ0YsQ0FBQztZQUNGLE1BQU0sZ0JBQWdCLEdBQUcsUUFBbUMsQ0FBQztZQUM3RCxNQUFNLGdCQUFnQixHQUFHLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sVUFBVSxHQUFHLGdCQUFtQyxDQUFDO1lBQ3ZELE9BQU8sVUFBVSxDQUFDO1FBQ3BCLENBQUM7UUFBQyxPQUFPLEtBQWMsRUFBRSxDQUFDO1lBQ3hCLElBQUksS0FBSyxZQUFZLGFBQWEsRUFBRSxDQUFDO2dCQUNuQyxPQUFPLFNBQVMsQ0FBQyxDQUFDLHVCQUF1QjtZQUMzQyxDQUFDO1lBQ0QsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELGlDQUFpQyxDQUFDLEtBQWM7UUFDOUMsSUFBSSxLQUFLLFlBQVksMEJBQTBCLEVBQUUsQ0FBQztZQUNoRCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDM0QsTUFBTSxJQUFJLDBCQUEwQixDQUNsQyxjQUFjLFFBQVEsMkdBQTJHLEVBQ2pJLEtBQUssQ0FBQyxRQUFRLENBQ2YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxnQkFBZ0IsQ0FDcEIsT0FBNkQ7UUFFN0QsTUFBTSxpQkFBaUIsR0FBeUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMseUJBQXlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsRCxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLGlCQUFpQixDQUFDO1FBRTVDLElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sYUFBYSxDQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQ3ZCLElBQUksRUFDSixPQUFPLEVBQ1AsQ0FBQyxDQUNGLENBQUM7WUFFRixNQUFNLGdCQUFnQixHQUFHLFFBQW1DLENBQUM7WUFDN0QsTUFBTSxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN6RSxNQUFNLFVBQVUsR0FBRyxnQkFBaUMsQ0FBQztZQUNyRCxJQUFJLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUNoQyxLQUFLLE1BQU0sT0FBTyxJQUFJLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDMUMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztvQkFDckMsSUFBSSxVQUFVLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQzt3QkFDOUMsT0FBTyxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ2xFLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFDRCxPQUFPLFVBQVUsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLEtBQUssWUFBWSxhQUFhLEVBQUUsQ0FBQztnQkFDbkMsT0FBTyxTQUFTLENBQUMsQ0FBQyx1QkFBdUI7WUFDM0MsQ0FBQztZQUNELElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxzQkFBc0IsQ0FDMUIsT0FBNkQ7UUFFN0QsTUFBTSxpQkFBaUIsR0FBeUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMseUJBQXlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsRCxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLGlCQUFpQixDQUFDO1FBQzVDLElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sYUFBYSxDQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQ3ZCLElBQUksRUFDSixPQUFPLEVBQ1AsQ0FBQyxDQUNGLENBQUM7WUFDRixNQUFNLGdCQUFnQixHQUFHLFFBQW1DLENBQUM7WUFDN0QsTUFBTSxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN6RSxNQUFNLFVBQVUsR0FBRyxnQkFBaUQsQ0FBQztZQUNyRSxPQUFPLFVBQVUsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLEtBQUssWUFBWSxhQUFhLEVBQUUsQ0FBQztnQkFDbkMsT0FBTyxTQUFTLENBQUMsQ0FBQyx1QkFBdUI7WUFDM0MsQ0FBQztZQUNELElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyw4QkFBOEIsQ0FDbEMsT0FBNkQ7UUFFN0QsTUFBTSxpQkFBaUIsR0FBeUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMseUJBQXlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsRCxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLGlCQUFpQixDQUFDO1FBQzVDLElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sYUFBYSxDQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQ3ZCLElBQUksRUFDSixPQUFPLEVBQ1AsQ0FBQyxDQUNGLENBQUM7WUFDRixNQUFNLGdCQUFnQixHQUFHLFFBQW1DLENBQUM7WUFDN0QsTUFBTSxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN6RSxNQUFNLFVBQVUsR0FBRyxnQkFBZ0QsQ0FBQztZQUNwRSxPQUFPLFVBQVUsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLEtBQUssWUFBWSxhQUFhLEVBQUUsQ0FBQztnQkFDbkMsT0FBTyxTQUFTLENBQUMsQ0FBQyx1QkFBdUI7WUFDM0MsQ0FBQztZQUNELElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQ3JCLE9BQWlDO1FBRWpDLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUNsRCxJQUFJLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRyxNQUFNLGlCQUFpQixDQUN0QyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQ3ZCLElBQUksRUFDSixPQUFPLEVBQ1AsY0FBYyxDQUNmLENBQUM7WUFDRixPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDO1FBQUMsT0FBTyxLQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLEtBQUssWUFBWSxhQUFhLEVBQUUsQ0FBQztnQkFDbkMsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7Q0FDRjtBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxVQUFVLENBQUMsT0FBMEI7SUFDekQsTUFBTSxXQUFXLEdBQUcsTUFBTSxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFDRCxPQUFPLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ2xDLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLGFBQWEsQ0FDakMsT0FBMEI7SUFFMUIsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFDckMsTUFBTSxPQUFPLEdBQUcsTUFBTSxVQUFVLEVBQUUsQ0FBQztJQUNuQyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQ2IsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRUQsS0FBSyxNQUFNLFFBQVEsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1FBQzFDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELElBQUksSUFBSSxFQUFFLENBQUM7WUFDVCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxhQUFhLEVBQUUsRUFBRSxDQUFDO1FBQ3BCLE1BQU0sSUFBSSxrQkFBa0IsQ0FDMUIsSUFBSSxNQUFNLHlEQUF5RDtZQUNqRSwyQ0FBMkMsQ0FDOUMsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0I7SUFDeEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxVQUFVLEVBQUUsQ0FBQztJQUNuQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGVBQWU7SUFDbkMsTUFBTSxLQUFLLEdBQUcsTUFBTSxvQkFBb0IsRUFBRSxDQUFDO0lBQzNDLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsaUJBQWlCO0lBQ3JDLE1BQU0scUJBQXFCLEdBQUcsTUFBTSx3QkFBd0IsRUFBRSxDQUFDO0lBQy9ELE1BQU0sT0FBTyxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdFLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ25ELElBQUksQ0FBQztZQUNILE9BQU8sTUFBTSxVQUFVLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDbkQsMERBQTBEO0lBQzFELE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBc0IsRUFBRSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsQ0FBQztBQUMzRSxDQUFDIn0=