@promptbook/components 0.105.0-1 → 0.105.0-11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -77
- package/esm/index.es.js +2463 -483
- package/esm/index.es.js.map +1 -1
- package/esm/typings/servers.d.ts +6 -0
- package/esm/typings/src/_packages/browser.index.d.ts +2 -0
- package/esm/typings/src/_packages/core.index.d.ts +4 -0
- package/esm/typings/src/_packages/types.index.d.ts +16 -0
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +15 -3
- package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +11 -1
- package/esm/typings/src/book-2.0/agent-source/communication-samples.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.blocks.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.import.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/agent-source/parseAgentSource.import.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/agent-source/parseAgentSourceWithCommitments.blocks.test.d.ts +1 -0
- package/esm/typings/src/book-components/Chat/AgentChat/AgentChatProps.d.ts +5 -0
- package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +15 -1
- package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +26 -11
- package/esm/typings/src/book-components/Chat/LlmChat/LlmChatProps.d.ts +5 -0
- package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +43 -0
- package/esm/typings/src/book-components/Chat/utils/getToolCallChipletText.d.ts +22 -0
- package/esm/typings/src/commitments/NOTE/NOTE.d.ts +2 -2
- package/esm/typings/src/commitments/USE_BROWSER/USE_BROWSER.d.ts +4 -0
- package/esm/typings/src/commitments/USE_IMAGE_GENERATOR/USE_IMAGE_GENERATOR.d.ts +46 -0
- package/esm/typings/src/commitments/USE_IMAGE_GENERATOR/USE_IMAGE_GENERATOR.test.d.ts +1 -0
- package/esm/typings/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +10 -0
- package/esm/typings/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.test.d.ts +1 -0
- package/esm/typings/src/commitments/USE_TIME/USE_TIME.d.ts +44 -0
- package/esm/typings/src/commitments/USE_TIME/USE_TIME.test.d.ts +1 -0
- package/esm/typings/src/commitments/_base/BaseCommitmentDefinition.d.ts +14 -0
- package/esm/typings/src/commitments/_base/CommitmentDefinition.d.ts +14 -0
- package/esm/typings/src/commitments/index.d.ts +18 -2
- package/esm/typings/src/config.d.ts +1 -0
- package/esm/typings/src/execution/LlmExecutionTools.d.ts +3 -1
- package/esm/typings/src/import-plugins/$fileImportPlugins.d.ts +7 -0
- package/esm/typings/src/import-plugins/AgentFileImportPlugin.d.ts +7 -0
- package/esm/typings/src/import-plugins/FileImportPlugin.d.ts +24 -0
- package/esm/typings/src/import-plugins/JsonFileImportPlugin.d.ts +7 -0
- package/esm/typings/src/import-plugins/TextFileImportPlugin.d.ts +7 -0
- package/esm/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +2 -1
- package/esm/typings/src/llm-providers/_common/utils/count-total-usage/countUsage.d.ts +2 -2
- package/esm/typings/src/llm-providers/agent/Agent.d.ts +14 -2
- package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +3 -1
- package/esm/typings/src/llm-providers/agent/AgentOptions.d.ts +7 -0
- package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +1 -0
- package/esm/typings/src/llm-providers/agent/RemoteAgentOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +10 -0
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +7 -0
- package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -1
- package/esm/typings/src/scripting/javascript/JavascriptExecutionToolsOptions.d.ts +6 -1
- package/esm/typings/src/search-engines/SearchEngine.d.ts +1 -1
- package/esm/typings/src/search-engines/_index.d.ts +6 -0
- package/esm/typings/src/search-engines/bing/BingSearchEngine.d.ts +1 -1
- package/esm/typings/src/search-engines/dummy/DummySearchEngine.d.ts +1 -1
- package/esm/typings/src/search-engines/google/GoogleSearchEngine.d.ts +18 -0
- package/esm/typings/src/search-engines/serp/SerpSearchEngine.d.ts +15 -0
- package/esm/typings/src/speech-recognition/BrowserSpeechRecognition.d.ts +21 -0
- package/esm/typings/src/speech-recognition/OpenAiSpeechRecognition.d.ts +32 -0
- package/esm/typings/src/types/ModelRequirements.d.ts +6 -12
- package/esm/typings/src/types/SpeechRecognition.d.ts +58 -0
- package/esm/typings/src/types/typeAliases.d.ts +4 -0
- package/esm/typings/src/utils/execCommand/$execCommandNormalizeOptions.d.ts +2 -3
- package/esm/typings/src/utils/execCommand/ExecCommandOptions.d.ts +7 -1
- package/esm/typings/src/utils/misc/linguisticHash.d.ts +6 -0
- package/esm/typings/src/utils/misc/linguisticHash.test.d.ts +1 -0
- package/esm/typings/src/utils/organization/keepImported.d.ts +9 -0
- package/esm/typings/src/utils/organization/keepTypeImported.d.ts +0 -1
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +2466 -486
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -13,10 +13,10 @@ import { createRoot } from 'react-dom/client';
|
|
|
13
13
|
import { Converter } from 'showdown';
|
|
14
14
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
15
15
|
import { forTime } from 'waitasecond';
|
|
16
|
+
import colors from 'colors';
|
|
16
17
|
import sha256 from 'crypto-js/sha256';
|
|
17
18
|
import { lookup, extension } from 'mime-types';
|
|
18
19
|
import { parse, unparse } from 'papaparse';
|
|
19
|
-
import colors from 'colors';
|
|
20
20
|
import Bottleneck from 'bottleneck';
|
|
21
21
|
import OpenAI from 'openai';
|
|
22
22
|
import QRCode from 'qrcode';
|
|
@@ -35,7 +35,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
35
35
|
* @generated
|
|
36
36
|
* @see https://github.com/webgptorg/promptbook
|
|
37
37
|
*/
|
|
38
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.105.0-
|
|
38
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.105.0-11';
|
|
39
39
|
/**
|
|
40
40
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
41
41
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -1106,6 +1106,7 @@ const PROMPTBOOK_SYNTAX_COLORS = {
|
|
|
1106
1106
|
SEPARATOR: Color.fromHex('#cccccc'),
|
|
1107
1107
|
COMMITMENT: Color.fromHex('#DA0F78'),
|
|
1108
1108
|
PARAMETER: Color.fromHex('#8e44ad'),
|
|
1109
|
+
CODE_BLOCK: Color.fromHex('#7700ffff'),
|
|
1109
1110
|
};
|
|
1110
1111
|
// <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
|
|
1111
1112
|
/**
|
|
@@ -3211,6 +3212,698 @@ function capitalize(word) {
|
|
|
3211
3212
|
return word.substring(0, 1).toUpperCase() + word.substring(1);
|
|
3212
3213
|
}
|
|
3213
3214
|
|
|
3215
|
+
/**
|
|
3216
|
+
* Creates human-readable hash
|
|
3217
|
+
*
|
|
3218
|
+
* @public exported from `@promptbook/utils`
|
|
3219
|
+
*/
|
|
3220
|
+
async function linguisticHash(input) {
|
|
3221
|
+
const hash = computeHash(input);
|
|
3222
|
+
// Use parts of the hash to select words
|
|
3223
|
+
// SHA256 is 64 hex characters
|
|
3224
|
+
// We use different slices of the hash to ensure variety even with small changes in input
|
|
3225
|
+
const part1 = parseInt(hash.substring(0, 10), 16);
|
|
3226
|
+
const part2 = parseInt(hash.substring(10, 20), 16);
|
|
3227
|
+
const part3 = parseInt(hash.substring(20, 30), 16);
|
|
3228
|
+
const adjective = ADJECTIVES[part1 % ADJECTIVES.length];
|
|
3229
|
+
const noun = NOUNS[part2 % NOUNS.length];
|
|
3230
|
+
const verb = VERBS[part3 % VERBS.length];
|
|
3231
|
+
return `${capitalize(adjective)} ${noun.toLowerCase()} ${verb.toLowerCase()}`;
|
|
3232
|
+
}
|
|
3233
|
+
const ADJECTIVES = [
|
|
3234
|
+
'red',
|
|
3235
|
+
'blue',
|
|
3236
|
+
'green',
|
|
3237
|
+
'yellow',
|
|
3238
|
+
'quick',
|
|
3239
|
+
'slow',
|
|
3240
|
+
'bright',
|
|
3241
|
+
'dark',
|
|
3242
|
+
'happy',
|
|
3243
|
+
'sad',
|
|
3244
|
+
'brave',
|
|
3245
|
+
'calm',
|
|
3246
|
+
'clever',
|
|
3247
|
+
'eager',
|
|
3248
|
+
'fancy',
|
|
3249
|
+
'grand',
|
|
3250
|
+
'jolly',
|
|
3251
|
+
'kind',
|
|
3252
|
+
'lucky',
|
|
3253
|
+
'nice',
|
|
3254
|
+
'proud',
|
|
3255
|
+
'silly',
|
|
3256
|
+
'wise',
|
|
3257
|
+
'young',
|
|
3258
|
+
'old',
|
|
3259
|
+
'big',
|
|
3260
|
+
'small',
|
|
3261
|
+
'fast',
|
|
3262
|
+
'shiny',
|
|
3263
|
+
'wild',
|
|
3264
|
+
'silent',
|
|
3265
|
+
'loud',
|
|
3266
|
+
'soft',
|
|
3267
|
+
'hard',
|
|
3268
|
+
'warm',
|
|
3269
|
+
'cold',
|
|
3270
|
+
'sweet',
|
|
3271
|
+
'sour',
|
|
3272
|
+
'bitter',
|
|
3273
|
+
'salty',
|
|
3274
|
+
'rich',
|
|
3275
|
+
'poor',
|
|
3276
|
+
'heavy',
|
|
3277
|
+
'light',
|
|
3278
|
+
'strong',
|
|
3279
|
+
'weak',
|
|
3280
|
+
'smooth',
|
|
3281
|
+
'rough',
|
|
3282
|
+
'clean',
|
|
3283
|
+
'dirty',
|
|
3284
|
+
'fresh',
|
|
3285
|
+
'stale',
|
|
3286
|
+
'sharp',
|
|
3287
|
+
'blunt',
|
|
3288
|
+
'thick',
|
|
3289
|
+
'thin',
|
|
3290
|
+
'wide',
|
|
3291
|
+
'narrow',
|
|
3292
|
+
'deep',
|
|
3293
|
+
'shallow',
|
|
3294
|
+
'mighty',
|
|
3295
|
+
'gentle',
|
|
3296
|
+
'fierce',
|
|
3297
|
+
'vibrant',
|
|
3298
|
+
'dusty',
|
|
3299
|
+
'golden',
|
|
3300
|
+
'silver',
|
|
3301
|
+
'frozen',
|
|
3302
|
+
'burning',
|
|
3303
|
+
'ancient',
|
|
3304
|
+
'modern',
|
|
3305
|
+
'hidden',
|
|
3306
|
+
'lost',
|
|
3307
|
+
'found',
|
|
3308
|
+
'magic',
|
|
3309
|
+
'mystic',
|
|
3310
|
+
'cosmic',
|
|
3311
|
+
'stellar',
|
|
3312
|
+
'lunar',
|
|
3313
|
+
'solar',
|
|
3314
|
+
'misty',
|
|
3315
|
+
'foggy',
|
|
3316
|
+
'stormy',
|
|
3317
|
+
'sunny',
|
|
3318
|
+
'windy',
|
|
3319
|
+
'quiet',
|
|
3320
|
+
'noisy',
|
|
3321
|
+
'peaceful',
|
|
3322
|
+
'busy',
|
|
3323
|
+
'empty',
|
|
3324
|
+
'full',
|
|
3325
|
+
'round',
|
|
3326
|
+
'square',
|
|
3327
|
+
'flat',
|
|
3328
|
+
'curved',
|
|
3329
|
+
'tiny',
|
|
3330
|
+
'huge',
|
|
3331
|
+
'giant',
|
|
3332
|
+
'little',
|
|
3333
|
+
'short',
|
|
3334
|
+
'long',
|
|
3335
|
+
'near',
|
|
3336
|
+
'distant',
|
|
3337
|
+
'inner',
|
|
3338
|
+
'outer',
|
|
3339
|
+
'patient',
|
|
3340
|
+
'steady',
|
|
3341
|
+
'noble',
|
|
3342
|
+
'pure',
|
|
3343
|
+
'graceful',
|
|
3344
|
+
'honest',
|
|
3345
|
+
'simple',
|
|
3346
|
+
'complex',
|
|
3347
|
+
'active',
|
|
3348
|
+
'passive',
|
|
3349
|
+
'vivid',
|
|
3350
|
+
'pale',
|
|
3351
|
+
'loyal',
|
|
3352
|
+
'true',
|
|
3353
|
+
'false',
|
|
3354
|
+
'fair',
|
|
3355
|
+
'clear',
|
|
3356
|
+
'murky',
|
|
3357
|
+
'vast',
|
|
3358
|
+
'slick',
|
|
3359
|
+
'slippery',
|
|
3360
|
+
'sticky',
|
|
3361
|
+
'dull',
|
|
3362
|
+
'keen',
|
|
3363
|
+
'broad',
|
|
3364
|
+
'slim',
|
|
3365
|
+
'slender',
|
|
3366
|
+
'fat',
|
|
3367
|
+
'lean',
|
|
3368
|
+
'stiff',
|
|
3369
|
+
'flexible',
|
|
3370
|
+
'rigid',
|
|
3371
|
+
'elastic',
|
|
3372
|
+
'tough',
|
|
3373
|
+
'brittle',
|
|
3374
|
+
'fragile',
|
|
3375
|
+
'solid',
|
|
3376
|
+
'liquid',
|
|
3377
|
+
'gaseous',
|
|
3378
|
+
'airy',
|
|
3379
|
+
'weighty',
|
|
3380
|
+
'buoyant',
|
|
3381
|
+
'dense',
|
|
3382
|
+
'sparse',
|
|
3383
|
+
'hollow',
|
|
3384
|
+
'stuffed',
|
|
3385
|
+
'crowded',
|
|
3386
|
+
'lonely',
|
|
3387
|
+
'social',
|
|
3388
|
+
'private',
|
|
3389
|
+
'public',
|
|
3390
|
+
'secret',
|
|
3391
|
+
'famous',
|
|
3392
|
+
'certain',
|
|
3393
|
+
'vague',
|
|
3394
|
+
'plain',
|
|
3395
|
+
'easy',
|
|
3396
|
+
'tame',
|
|
3397
|
+
'mild',
|
|
3398
|
+
'hot',
|
|
3399
|
+
'cool',
|
|
3400
|
+
'dry',
|
|
3401
|
+
'wet',
|
|
3402
|
+
'damp',
|
|
3403
|
+
'moist',
|
|
3404
|
+
'soaked',
|
|
3405
|
+
'parched',
|
|
3406
|
+
'hungry',
|
|
3407
|
+
'thirsty',
|
|
3408
|
+
'sleepy',
|
|
3409
|
+
'awake',
|
|
3410
|
+
'tired',
|
|
3411
|
+
'lazy',
|
|
3412
|
+
'idle',
|
|
3413
|
+
'swift',
|
|
3414
|
+
'rapid',
|
|
3415
|
+
'unstable',
|
|
3416
|
+
'shaky',
|
|
3417
|
+
'firm',
|
|
3418
|
+
'bold',
|
|
3419
|
+
'timid',
|
|
3420
|
+
'brave',
|
|
3421
|
+
'cowardly',
|
|
3422
|
+
'smart',
|
|
3423
|
+
'dumb',
|
|
3424
|
+
'foolish',
|
|
3425
|
+
'mean',
|
|
3426
|
+
'rude',
|
|
3427
|
+
'tasty',
|
|
3428
|
+
'bland',
|
|
3429
|
+
'arctic',
|
|
3430
|
+
'tropical',
|
|
3431
|
+
'deserted',
|
|
3432
|
+
'urban',
|
|
3433
|
+
'rural',
|
|
3434
|
+
'local',
|
|
3435
|
+
'global',
|
|
3436
|
+
'digital',
|
|
3437
|
+
'analog',
|
|
3438
|
+
'virtual',
|
|
3439
|
+
'real',
|
|
3440
|
+
'fake',
|
|
3441
|
+
'natural',
|
|
3442
|
+
'artificial',
|
|
3443
|
+
'living',
|
|
3444
|
+
'dead',
|
|
3445
|
+
'broken',
|
|
3446
|
+
'fixed',
|
|
3447
|
+
'new',
|
|
3448
|
+
'worn',
|
|
3449
|
+
'neat',
|
|
3450
|
+
'messy',
|
|
3451
|
+
'brave',
|
|
3452
|
+
'fearful',
|
|
3453
|
+
'proud',
|
|
3454
|
+
'humble',
|
|
3455
|
+
'greedy',
|
|
3456
|
+
'generous',
|
|
3457
|
+
'calm',
|
|
3458
|
+
'angry',
|
|
3459
|
+
'happy',
|
|
3460
|
+
'sad',
|
|
3461
|
+
'excited',
|
|
3462
|
+
'bored',
|
|
3463
|
+
'strange',
|
|
3464
|
+
'normal',
|
|
3465
|
+
'odd',
|
|
3466
|
+
'even',
|
|
3467
|
+
'rare',
|
|
3468
|
+
'common',
|
|
3469
|
+
'unique',
|
|
3470
|
+
'plain',
|
|
3471
|
+
'fancy',
|
|
3472
|
+
'basic',
|
|
3473
|
+
'prime',
|
|
3474
|
+
'super',
|
|
3475
|
+
'mega',
|
|
3476
|
+
'ultra',
|
|
3477
|
+
'micro',
|
|
3478
|
+
'nano',
|
|
3479
|
+
'macro',
|
|
3480
|
+
'mini',
|
|
3481
|
+
];
|
|
3482
|
+
const NOUNS = [
|
|
3483
|
+
'apple',
|
|
3484
|
+
'sky',
|
|
3485
|
+
'tree',
|
|
3486
|
+
'fox',
|
|
3487
|
+
'cat',
|
|
3488
|
+
'bird',
|
|
3489
|
+
'dog',
|
|
3490
|
+
'river',
|
|
3491
|
+
'mountain',
|
|
3492
|
+
'forest',
|
|
3493
|
+
'ocean',
|
|
3494
|
+
'star',
|
|
3495
|
+
'moon',
|
|
3496
|
+
'sun',
|
|
3497
|
+
'cloud',
|
|
3498
|
+
'flower',
|
|
3499
|
+
'leaf',
|
|
3500
|
+
'stone',
|
|
3501
|
+
'wind',
|
|
3502
|
+
'rain',
|
|
3503
|
+
'fire',
|
|
3504
|
+
'ice',
|
|
3505
|
+
'book',
|
|
3506
|
+
'dream',
|
|
3507
|
+
'song',
|
|
3508
|
+
'road',
|
|
3509
|
+
'gate',
|
|
3510
|
+
'key',
|
|
3511
|
+
'lamp',
|
|
3512
|
+
'map',
|
|
3513
|
+
'house',
|
|
3514
|
+
'city',
|
|
3515
|
+
'bridge',
|
|
3516
|
+
'field',
|
|
3517
|
+
'garden',
|
|
3518
|
+
'lake',
|
|
3519
|
+
'beach',
|
|
3520
|
+
'island',
|
|
3521
|
+
'valley',
|
|
3522
|
+
'desert',
|
|
3523
|
+
'world',
|
|
3524
|
+
'spirit',
|
|
3525
|
+
'heart',
|
|
3526
|
+
'mind',
|
|
3527
|
+
'soul',
|
|
3528
|
+
'life',
|
|
3529
|
+
'time',
|
|
3530
|
+
'space',
|
|
3531
|
+
'light',
|
|
3532
|
+
'shadow',
|
|
3533
|
+
'sound',
|
|
3534
|
+
'music',
|
|
3535
|
+
'voice',
|
|
3536
|
+
'word',
|
|
3537
|
+
'page',
|
|
3538
|
+
'story',
|
|
3539
|
+
'pearl',
|
|
3540
|
+
'gold',
|
|
3541
|
+
'silver',
|
|
3542
|
+
'crystal',
|
|
3543
|
+
'diamond',
|
|
3544
|
+
'emerald',
|
|
3545
|
+
'ruby',
|
|
3546
|
+
'path',
|
|
3547
|
+
'trail',
|
|
3548
|
+
'peak',
|
|
3549
|
+
'shore',
|
|
3550
|
+
'wave',
|
|
3551
|
+
'tide',
|
|
3552
|
+
'flame',
|
|
3553
|
+
'spark',
|
|
3554
|
+
'beam',
|
|
3555
|
+
'ray',
|
|
3556
|
+
'seed',
|
|
3557
|
+
'root',
|
|
3558
|
+
'branch',
|
|
3559
|
+
'bloom',
|
|
3560
|
+
'thorn',
|
|
3561
|
+
'bark',
|
|
3562
|
+
'shell',
|
|
3563
|
+
'feather',
|
|
3564
|
+
'wing',
|
|
3565
|
+
'claw',
|
|
3566
|
+
'paw',
|
|
3567
|
+
'nest',
|
|
3568
|
+
'cave',
|
|
3569
|
+
'grove',
|
|
3570
|
+
'tower',
|
|
3571
|
+
'castle',
|
|
3572
|
+
'crown',
|
|
3573
|
+
'sword',
|
|
3574
|
+
'shield',
|
|
3575
|
+
'coin',
|
|
3576
|
+
'gem',
|
|
3577
|
+
'ring',
|
|
3578
|
+
'bell',
|
|
3579
|
+
'clock',
|
|
3580
|
+
'compass',
|
|
3581
|
+
'anchor',
|
|
3582
|
+
'torch',
|
|
3583
|
+
'flute',
|
|
3584
|
+
'harp',
|
|
3585
|
+
'drum',
|
|
3586
|
+
'lens',
|
|
3587
|
+
'glass',
|
|
3588
|
+
'sand',
|
|
3589
|
+
'dust',
|
|
3590
|
+
'mist',
|
|
3591
|
+
'dew',
|
|
3592
|
+
'dawn',
|
|
3593
|
+
'dusk',
|
|
3594
|
+
'night',
|
|
3595
|
+
'day',
|
|
3596
|
+
'year',
|
|
3597
|
+
'age',
|
|
3598
|
+
'bolt',
|
|
3599
|
+
'drop',
|
|
3600
|
+
'storm',
|
|
3601
|
+
'snow',
|
|
3602
|
+
'hail',
|
|
3603
|
+
'fog',
|
|
3604
|
+
'smoke',
|
|
3605
|
+
'vapor',
|
|
3606
|
+
'gas',
|
|
3607
|
+
'fluid',
|
|
3608
|
+
'liquid',
|
|
3609
|
+
'solid',
|
|
3610
|
+
'metal',
|
|
3611
|
+
'rock',
|
|
3612
|
+
'dirt',
|
|
3613
|
+
'clay',
|
|
3614
|
+
'sand',
|
|
3615
|
+
'salt',
|
|
3616
|
+
'sugar',
|
|
3617
|
+
'wood',
|
|
3618
|
+
'bone',
|
|
3619
|
+
'skin',
|
|
3620
|
+
'flesh',
|
|
3621
|
+
'blood',
|
|
3622
|
+
'cell',
|
|
3623
|
+
'atom',
|
|
3624
|
+
'pulse',
|
|
3625
|
+
'beat',
|
|
3626
|
+
'breath',
|
|
3627
|
+
'sigh',
|
|
3628
|
+
'name',
|
|
3629
|
+
'echo',
|
|
3630
|
+
'image',
|
|
3631
|
+
'vision',
|
|
3632
|
+
'thought',
|
|
3633
|
+
'idea',
|
|
3634
|
+
'plan',
|
|
3635
|
+
'goal',
|
|
3636
|
+
'wish',
|
|
3637
|
+
'hope',
|
|
3638
|
+
'fear',
|
|
3639
|
+
'joy',
|
|
3640
|
+
'love',
|
|
3641
|
+
'hate',
|
|
3642
|
+
'will',
|
|
3643
|
+
'power',
|
|
3644
|
+
'force',
|
|
3645
|
+
'energy',
|
|
3646
|
+
'motion',
|
|
3647
|
+
'speed',
|
|
3648
|
+
'place',
|
|
3649
|
+
'point',
|
|
3650
|
+
'line',
|
|
3651
|
+
'shape',
|
|
3652
|
+
'form',
|
|
3653
|
+
'size',
|
|
3654
|
+
'mass',
|
|
3655
|
+
'weight',
|
|
3656
|
+
'heat',
|
|
3657
|
+
'cold',
|
|
3658
|
+
'color',
|
|
3659
|
+
'tone',
|
|
3660
|
+
'pitch',
|
|
3661
|
+
'rhythm',
|
|
3662
|
+
'vibe',
|
|
3663
|
+
'mood',
|
|
3664
|
+
'state',
|
|
3665
|
+
'way',
|
|
3666
|
+
'step',
|
|
3667
|
+
'move',
|
|
3668
|
+
'turn',
|
|
3669
|
+
'fall',
|
|
3670
|
+
'rise',
|
|
3671
|
+
'jump',
|
|
3672
|
+
'leap',
|
|
3673
|
+
'run',
|
|
3674
|
+
'walk',
|
|
3675
|
+
'rest',
|
|
3676
|
+
'stay',
|
|
3677
|
+
'trip',
|
|
3678
|
+
'quest',
|
|
3679
|
+
'task',
|
|
3680
|
+
'work',
|
|
3681
|
+
'job',
|
|
3682
|
+
'play',
|
|
3683
|
+
'game',
|
|
3684
|
+
'sport',
|
|
3685
|
+
'art',
|
|
3686
|
+
'craft',
|
|
3687
|
+
'tool',
|
|
3688
|
+
'ship',
|
|
3689
|
+
'boat',
|
|
3690
|
+
'car',
|
|
3691
|
+
'bike',
|
|
3692
|
+
'train',
|
|
3693
|
+
'plane',
|
|
3694
|
+
'hub',
|
|
3695
|
+
'base',
|
|
3696
|
+
'core',
|
|
3697
|
+
'node',
|
|
3698
|
+
'link',
|
|
3699
|
+
'net',
|
|
3700
|
+
'web',
|
|
3701
|
+
'box',
|
|
3702
|
+
'bag',
|
|
3703
|
+
'jar',
|
|
3704
|
+
'cup',
|
|
3705
|
+
'bowl',
|
|
3706
|
+
'plate',
|
|
3707
|
+
'dish',
|
|
3708
|
+
'spoon',
|
|
3709
|
+
'fork',
|
|
3710
|
+
'knife',
|
|
3711
|
+
'pan',
|
|
3712
|
+
'pot',
|
|
3713
|
+
'bed',
|
|
3714
|
+
'desk',
|
|
3715
|
+
'chair',
|
|
3716
|
+
'door',
|
|
3717
|
+
'wall',
|
|
3718
|
+
'roof',
|
|
3719
|
+
'floor',
|
|
3720
|
+
];
|
|
3721
|
+
const VERBS = [
|
|
3722
|
+
'jumping',
|
|
3723
|
+
'dancing',
|
|
3724
|
+
'flying',
|
|
3725
|
+
'running',
|
|
3726
|
+
'singing',
|
|
3727
|
+
'shining',
|
|
3728
|
+
'growing',
|
|
3729
|
+
'flowing',
|
|
3730
|
+
'falling',
|
|
3731
|
+
'rising',
|
|
3732
|
+
'sleeping',
|
|
3733
|
+
'walking',
|
|
3734
|
+
'talking',
|
|
3735
|
+
'thinking',
|
|
3736
|
+
'dreaming',
|
|
3737
|
+
'looking',
|
|
3738
|
+
'feeling',
|
|
3739
|
+
'smiling',
|
|
3740
|
+
'laughing',
|
|
3741
|
+
'playing',
|
|
3742
|
+
'working',
|
|
3743
|
+
'resting',
|
|
3744
|
+
'moving',
|
|
3745
|
+
'staying',
|
|
3746
|
+
'beaming',
|
|
3747
|
+
'glowing',
|
|
3748
|
+
'sparkling',
|
|
3749
|
+
'waiting',
|
|
3750
|
+
'waking',
|
|
3751
|
+
'drifting',
|
|
3752
|
+
'spinning',
|
|
3753
|
+
'gliding',
|
|
3754
|
+
'soaring',
|
|
3755
|
+
'floating',
|
|
3756
|
+
'whispering',
|
|
3757
|
+
'calling',
|
|
3758
|
+
'seeking',
|
|
3759
|
+
'finding',
|
|
3760
|
+
'giving',
|
|
3761
|
+
'taking',
|
|
3762
|
+
'weaving',
|
|
3763
|
+
'building',
|
|
3764
|
+
'creating',
|
|
3765
|
+
'burning',
|
|
3766
|
+
'freezing',
|
|
3767
|
+
'melting',
|
|
3768
|
+
'breathing',
|
|
3769
|
+
'pulsing',
|
|
3770
|
+
'beating',
|
|
3771
|
+
'living',
|
|
3772
|
+
'learning',
|
|
3773
|
+
'knowing',
|
|
3774
|
+
'hidden',
|
|
3775
|
+
'shown',
|
|
3776
|
+
'broken',
|
|
3777
|
+
'mended',
|
|
3778
|
+
'lost',
|
|
3779
|
+
'found',
|
|
3780
|
+
'starting',
|
|
3781
|
+
'ending',
|
|
3782
|
+
'climbing',
|
|
3783
|
+
'diving',
|
|
3784
|
+
'swimming',
|
|
3785
|
+
'sailing',
|
|
3786
|
+
'rolling',
|
|
3787
|
+
'shaking',
|
|
3788
|
+
'turning',
|
|
3789
|
+
'shifting',
|
|
3790
|
+
'changing',
|
|
3791
|
+
'fading',
|
|
3792
|
+
'dying',
|
|
3793
|
+
'born',
|
|
3794
|
+
'humming',
|
|
3795
|
+
'crying',
|
|
3796
|
+
'racing',
|
|
3797
|
+
'creeping',
|
|
3798
|
+
'hiding',
|
|
3799
|
+
'watching',
|
|
3800
|
+
'hearing',
|
|
3801
|
+
'sensing',
|
|
3802
|
+
'longing',
|
|
3803
|
+
'hoping',
|
|
3804
|
+
'loving',
|
|
3805
|
+
'fearing',
|
|
3806
|
+
'wondering',
|
|
3807
|
+
'wandering',
|
|
3808
|
+
'traveling',
|
|
3809
|
+
'crossing',
|
|
3810
|
+
'meeting',
|
|
3811
|
+
'parting',
|
|
3812
|
+
'keeping',
|
|
3813
|
+
'sharing',
|
|
3814
|
+
'sparking',
|
|
3815
|
+
'flaming',
|
|
3816
|
+
'healing',
|
|
3817
|
+
'solving',
|
|
3818
|
+
'opening',
|
|
3819
|
+
'closing',
|
|
3820
|
+
'lifting',
|
|
3821
|
+
'pulling',
|
|
3822
|
+
'pushing',
|
|
3823
|
+
'holding',
|
|
3824
|
+
'tossing',
|
|
3825
|
+
'throwing',
|
|
3826
|
+
'catching',
|
|
3827
|
+
'fixing',
|
|
3828
|
+
'making',
|
|
3829
|
+
'doing',
|
|
3830
|
+
'seeing',
|
|
3831
|
+
'tasting',
|
|
3832
|
+
'smelling',
|
|
3833
|
+
'touching',
|
|
3834
|
+
'pacing',
|
|
3835
|
+
'hurrying',
|
|
3836
|
+
'pausing',
|
|
3837
|
+
'going',
|
|
3838
|
+
'coming',
|
|
3839
|
+
'leaving',
|
|
3840
|
+
'acting',
|
|
3841
|
+
'being',
|
|
3842
|
+
'seeming',
|
|
3843
|
+
'shrinking',
|
|
3844
|
+
'widening',
|
|
3845
|
+
'narrowing',
|
|
3846
|
+
'heating',
|
|
3847
|
+
'cooling',
|
|
3848
|
+
'drying',
|
|
3849
|
+
'wetting',
|
|
3850
|
+
'filling',
|
|
3851
|
+
'filling',
|
|
3852
|
+
'emptying',
|
|
3853
|
+
'letting',
|
|
3854
|
+
'gaining',
|
|
3855
|
+
'winning',
|
|
3856
|
+
'failing',
|
|
3857
|
+
'trying',
|
|
3858
|
+
'using',
|
|
3859
|
+
'getting',
|
|
3860
|
+
'showing',
|
|
3861
|
+
'hiding',
|
|
3862
|
+
'breaking',
|
|
3863
|
+
'fixing',
|
|
3864
|
+
'saving',
|
|
3865
|
+
'spending',
|
|
3866
|
+
'buying',
|
|
3867
|
+
'selling',
|
|
3868
|
+
'paying',
|
|
3869
|
+
'costing',
|
|
3870
|
+
'reaching',
|
|
3871
|
+
'missing',
|
|
3872
|
+
'hitting',
|
|
3873
|
+
'striking',
|
|
3874
|
+
'leading',
|
|
3875
|
+
'following',
|
|
3876
|
+
'helping',
|
|
3877
|
+
'serving',
|
|
3878
|
+
'teaching',
|
|
3879
|
+
'training',
|
|
3880
|
+
'coding',
|
|
3881
|
+
'writing',
|
|
3882
|
+
'reading',
|
|
3883
|
+
'drawing',
|
|
3884
|
+
'painting',
|
|
3885
|
+
'crafting',
|
|
3886
|
+
'shaping',
|
|
3887
|
+
'forming',
|
|
3888
|
+
'joining',
|
|
3889
|
+
'splitting',
|
|
3890
|
+
'sharing',
|
|
3891
|
+
'bonding',
|
|
3892
|
+
'healing',
|
|
3893
|
+
'harming',
|
|
3894
|
+
'protecting',
|
|
3895
|
+
'fighting',
|
|
3896
|
+
'defending',
|
|
3897
|
+
'attacking',
|
|
3898
|
+
'escaping',
|
|
3899
|
+
'catching',
|
|
3900
|
+
'trapping',
|
|
3901
|
+
'freeing',
|
|
3902
|
+
'binding',
|
|
3903
|
+
'weaving',
|
|
3904
|
+
'spinning',
|
|
3905
|
+
];
|
|
3906
|
+
|
|
3214
3907
|
/**
|
|
3215
3908
|
* Normalizes a text string to SCREAMING_CASE (all uppercase with underscores).
|
|
3216
3909
|
*
|
|
@@ -3310,6 +4003,95 @@ function normalizeTo_snake_case(text) {
|
|
|
3310
4003
|
return normalizeTo_SCREAMING_CASE(text).toLowerCase();
|
|
3311
4004
|
}
|
|
3312
4005
|
|
|
4006
|
+
/**
|
|
4007
|
+
* Removes quotes and optional introduce text from a string
|
|
4008
|
+
*
|
|
4009
|
+
* Tip: This is very useful for post-processing of the result of the LLM model
|
|
4010
|
+
* Note: This function trims the text and removes whole introduce sentence if it is present
|
|
4011
|
+
* Note: There are two similar functions:
|
|
4012
|
+
* - `removeQuotes` which removes only bounding quotes
|
|
4013
|
+
* - `unwrapResult` which removes whole introduce sentence
|
|
4014
|
+
*
|
|
4015
|
+
* @param text optionally quoted text
|
|
4016
|
+
* @returns text without quotes
|
|
4017
|
+
* @public exported from `@promptbook/utils`
|
|
4018
|
+
*/
|
|
4019
|
+
function unwrapResult(text, options) {
|
|
4020
|
+
const { isTrimmed = true, isIntroduceSentenceRemoved = true } = options || {};
|
|
4021
|
+
let trimmedText = text;
|
|
4022
|
+
// Remove leading and trailing spaces and newlines
|
|
4023
|
+
if (isTrimmed) {
|
|
4024
|
+
trimmedText = spaceTrim$1(trimmedText);
|
|
4025
|
+
}
|
|
4026
|
+
let processedText = trimmedText;
|
|
4027
|
+
// Check for markdown code block
|
|
4028
|
+
const codeBlockRegex = /^```[a-z]*\n([\s\S]*?)\n```\s*$/;
|
|
4029
|
+
const codeBlockMatch = processedText.match(codeBlockRegex);
|
|
4030
|
+
if (codeBlockMatch && codeBlockMatch[1] !== undefined) {
|
|
4031
|
+
// Check if there's only one code block
|
|
4032
|
+
const codeBlockCount = (processedText.match(/```/g) || []).length / 2;
|
|
4033
|
+
if (codeBlockCount === 1) {
|
|
4034
|
+
return unwrapResult(codeBlockMatch[1], { isTrimmed: false, isIntroduceSentenceRemoved: false });
|
|
4035
|
+
}
|
|
4036
|
+
}
|
|
4037
|
+
if (isIntroduceSentenceRemoved) {
|
|
4038
|
+
const introduceSentenceRegex = /^[a-zěščřžýáíéúů:\s]*:\s*/i;
|
|
4039
|
+
if (introduceSentenceRegex.test(text)) {
|
|
4040
|
+
// Remove the introduce sentence and quotes by replacing it with an empty string
|
|
4041
|
+
processedText = processedText.replace(introduceSentenceRegex, '');
|
|
4042
|
+
}
|
|
4043
|
+
processedText = spaceTrim$1(processedText);
|
|
4044
|
+
// Check again for code block after removing introduce sentence
|
|
4045
|
+
const codeBlockMatch2 = processedText.match(codeBlockRegex);
|
|
4046
|
+
if (codeBlockMatch2 && codeBlockMatch2[1] !== undefined) {
|
|
4047
|
+
const codeBlockCount = (processedText.match(/```/g) || []).length / 2;
|
|
4048
|
+
if (codeBlockCount === 1) {
|
|
4049
|
+
return unwrapResult(codeBlockMatch2[1], { isTrimmed: false, isIntroduceSentenceRemoved: false });
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
if (processedText.length < 3) {
|
|
4054
|
+
return trimmedText;
|
|
4055
|
+
}
|
|
4056
|
+
if (processedText.includes('\n')) {
|
|
4057
|
+
return trimmedText;
|
|
4058
|
+
}
|
|
4059
|
+
// Remove the quotes by extracting the substring without the first and last characters
|
|
4060
|
+
const unquotedText = processedText.slice(1, -1);
|
|
4061
|
+
// Check if the text starts and ends with quotes
|
|
4062
|
+
if ([
|
|
4063
|
+
['"', '"'],
|
|
4064
|
+
["'", "'"],
|
|
4065
|
+
['`', '`'],
|
|
4066
|
+
['*', '*'],
|
|
4067
|
+
['_', '_'],
|
|
4068
|
+
['„', '“'],
|
|
4069
|
+
['«', '»'] /* <- QUOTES to config */,
|
|
4070
|
+
].some(([startQuote, endQuote]) => {
|
|
4071
|
+
if (!processedText.startsWith(startQuote)) {
|
|
4072
|
+
return false;
|
|
4073
|
+
}
|
|
4074
|
+
if (!processedText.endsWith(endQuote)) {
|
|
4075
|
+
return false;
|
|
4076
|
+
}
|
|
4077
|
+
if (unquotedText.includes(startQuote) && !unquotedText.includes(endQuote)) {
|
|
4078
|
+
return false;
|
|
4079
|
+
}
|
|
4080
|
+
if (!unquotedText.includes(startQuote) && unquotedText.includes(endQuote)) {
|
|
4081
|
+
return false;
|
|
4082
|
+
}
|
|
4083
|
+
return true;
|
|
4084
|
+
})) {
|
|
4085
|
+
return unwrapResult(unquotedText, { isTrimmed: false, isIntroduceSentenceRemoved: false });
|
|
4086
|
+
}
|
|
4087
|
+
else {
|
|
4088
|
+
return processedText;
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
/**
|
|
4092
|
+
* TODO: [🧠] Should this also unwrap the (parenthesis)
|
|
4093
|
+
*/
|
|
4094
|
+
|
|
3313
4095
|
/**
|
|
3314
4096
|
* Parses the task and returns the list of all parameter names
|
|
3315
4097
|
*
|
|
@@ -3714,6 +4496,22 @@ class BaseCommitmentDefinition {
|
|
|
3714
4496
|
return this.appendToSystemMessage(requirements, commentSection);
|
|
3715
4497
|
}
|
|
3716
4498
|
}
|
|
4499
|
+
/**
|
|
4500
|
+
* Gets tool function implementations provided by this commitment
|
|
4501
|
+
*
|
|
4502
|
+
* When the `applyToAgentModelRequirements` adds tools to the requirements, this method should return the corresponding function definitions.
|
|
4503
|
+
*/
|
|
4504
|
+
getToolFunctions() {
|
|
4505
|
+
return {};
|
|
4506
|
+
}
|
|
4507
|
+
/**
|
|
4508
|
+
* Gets human-readable titles for tool functions provided by this commitment
|
|
4509
|
+
*
|
|
4510
|
+
* This is used in the UI to show a user-friendly name instead of the technical function name.
|
|
4511
|
+
*/
|
|
4512
|
+
getToolTitles() {
|
|
4513
|
+
return {};
|
|
4514
|
+
}
|
|
3717
4515
|
}
|
|
3718
4516
|
|
|
3719
4517
|
/**
|
|
@@ -4346,79 +5144,6 @@ class FromCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
4346
5144
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
4347
5145
|
*/
|
|
4348
5146
|
|
|
4349
|
-
/**
|
|
4350
|
-
* IMPORT commitment definition
|
|
4351
|
-
*
|
|
4352
|
-
* The IMPORT commitment tells the agent to import content from another agent at the current location.
|
|
4353
|
-
*
|
|
4354
|
-
* Example usage in agent source:
|
|
4355
|
-
*
|
|
4356
|
-
* ```book
|
|
4357
|
-
* IMPORT https://s6.ptbk.io/benjamin-white
|
|
4358
|
-
* ```
|
|
4359
|
-
*
|
|
4360
|
-
* @private [🪔] Maybe export the commitments through some package
|
|
4361
|
-
*/
|
|
4362
|
-
class ImportCommitmentDefinition extends BaseCommitmentDefinition {
|
|
4363
|
-
constructor(type = 'IMPORT') {
|
|
4364
|
-
super(type);
|
|
4365
|
-
}
|
|
4366
|
-
/**
|
|
4367
|
-
* Short one-line description of IMPORT.
|
|
4368
|
-
*/
|
|
4369
|
-
get description() {
|
|
4370
|
-
return 'Import content from another agent.';
|
|
4371
|
-
}
|
|
4372
|
-
/**
|
|
4373
|
-
* Icon for this commitment.
|
|
4374
|
-
*/
|
|
4375
|
-
get icon() {
|
|
4376
|
-
return '📥';
|
|
4377
|
-
}
|
|
4378
|
-
/**
|
|
4379
|
-
* Markdown documentation for IMPORT commitment.
|
|
4380
|
-
*/
|
|
4381
|
-
get documentation() {
|
|
4382
|
-
return spaceTrim$1(`
|
|
4383
|
-
# ${this.type}
|
|
4384
|
-
|
|
4385
|
-
Imports content from another agent at the location of the commitment.
|
|
4386
|
-
|
|
4387
|
-
## Examples
|
|
4388
|
-
|
|
4389
|
-
\`\`\`book
|
|
4390
|
-
My AI Agent
|
|
4391
|
-
|
|
4392
|
-
IMPORT https://s6.ptbk.io/benjamin-white
|
|
4393
|
-
RULE Speak only in English.
|
|
4394
|
-
\`\`\`
|
|
4395
|
-
`);
|
|
4396
|
-
}
|
|
4397
|
-
applyToAgentModelRequirements(requirements, content) {
|
|
4398
|
-
const trimmedContent = content.trim();
|
|
4399
|
-
if (!trimmedContent) {
|
|
4400
|
-
return requirements;
|
|
4401
|
-
}
|
|
4402
|
-
if (!isValidAgentUrl(trimmedContent)) {
|
|
4403
|
-
throw new Error(spaceTrim$1((block) => `
|
|
4404
|
-
Invalid agent URL in IMPORT commitment: "${trimmedContent}"
|
|
4405
|
-
|
|
4406
|
-
\`\`\`book
|
|
4407
|
-
${block(content)}
|
|
4408
|
-
\`\`\`
|
|
4409
|
-
`));
|
|
4410
|
-
}
|
|
4411
|
-
const importedAgentUrl = trimmedContent;
|
|
4412
|
-
return {
|
|
4413
|
-
...requirements,
|
|
4414
|
-
importedAgentUrls: [...(requirements.importedAgentUrls || []), importedAgentUrl],
|
|
4415
|
-
};
|
|
4416
|
-
}
|
|
4417
|
-
}
|
|
4418
|
-
/**
|
|
4419
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
4420
|
-
*/
|
|
4421
|
-
|
|
4422
5147
|
/**
|
|
4423
5148
|
* GOAL commitment definition
|
|
4424
5149
|
*
|
|
@@ -4519,6 +5244,87 @@ class GoalCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
4519
5244
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
4520
5245
|
*/
|
|
4521
5246
|
|
|
5247
|
+
/**
|
|
5248
|
+
* IMPORT commitment definition
|
|
5249
|
+
*
|
|
5250
|
+
* The IMPORT commitment tells the agent to import content from another agent at the current location.
|
|
5251
|
+
*
|
|
5252
|
+
* Example usage in agent source:
|
|
5253
|
+
*
|
|
5254
|
+
* ```book
|
|
5255
|
+
* IMPORT https://s6.ptbk.io/benjamin-white
|
|
5256
|
+
* ```
|
|
5257
|
+
*
|
|
5258
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
5259
|
+
*/
|
|
5260
|
+
class ImportCommitmentDefinition extends BaseCommitmentDefinition {
|
|
5261
|
+
constructor(type = 'IMPORT') {
|
|
5262
|
+
super(type);
|
|
5263
|
+
}
|
|
5264
|
+
/**
|
|
5265
|
+
* Short one-line description of IMPORT.
|
|
5266
|
+
*/
|
|
5267
|
+
get description() {
|
|
5268
|
+
return 'Import content from another agent or a generic text file.';
|
|
5269
|
+
}
|
|
5270
|
+
/**
|
|
5271
|
+
* Icon for this commitment.
|
|
5272
|
+
*/
|
|
5273
|
+
get icon() {
|
|
5274
|
+
return '📥';
|
|
5275
|
+
}
|
|
5276
|
+
/**
|
|
5277
|
+
* Markdown documentation for IMPORT commitment.
|
|
5278
|
+
*/
|
|
5279
|
+
get documentation() {
|
|
5280
|
+
return spaceTrim$1(`
|
|
5281
|
+
# ${this.type}
|
|
5282
|
+
|
|
5283
|
+
Imports content from another agent or a generic text file at the location of the commitment.
|
|
5284
|
+
|
|
5285
|
+
## Examples
|
|
5286
|
+
|
|
5287
|
+
\`\`\`book
|
|
5288
|
+
My AI Agent
|
|
5289
|
+
|
|
5290
|
+
IMPORT https://s6.ptbk.io/benjamin-white
|
|
5291
|
+
IMPORT https://example.com/some-text-file.txt
|
|
5292
|
+
IMPORT ./path/to/local-file.json
|
|
5293
|
+
RULE Speak only in English.
|
|
5294
|
+
\`\`\`
|
|
5295
|
+
`);
|
|
5296
|
+
}
|
|
5297
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
5298
|
+
const trimmedContent = content.trim();
|
|
5299
|
+
if (!trimmedContent) {
|
|
5300
|
+
return requirements;
|
|
5301
|
+
}
|
|
5302
|
+
if (isValidAgentUrl(trimmedContent)) {
|
|
5303
|
+
const importedAgentUrl = trimmedContent;
|
|
5304
|
+
return {
|
|
5305
|
+
...requirements,
|
|
5306
|
+
importedAgentUrls: [...(requirements.importedAgentUrls || []), importedAgentUrl],
|
|
5307
|
+
};
|
|
5308
|
+
}
|
|
5309
|
+
if (isValidUrl(trimmedContent) || isValidFilePath(trimmedContent)) {
|
|
5310
|
+
return {
|
|
5311
|
+
...requirements,
|
|
5312
|
+
importedFileUrls: [...(requirements.importedFileUrls || []), trimmedContent],
|
|
5313
|
+
};
|
|
5314
|
+
}
|
|
5315
|
+
throw new Error(spaceTrim$1((block) => `
|
|
5316
|
+
Invalid agent URL or file path in IMPORT commitment: "${trimmedContent}"
|
|
5317
|
+
|
|
5318
|
+
\`\`\`book
|
|
5319
|
+
${block(content)}
|
|
5320
|
+
\`\`\`
|
|
5321
|
+
`));
|
|
5322
|
+
}
|
|
5323
|
+
}
|
|
5324
|
+
/**
|
|
5325
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
5326
|
+
*/
|
|
5327
|
+
|
|
4522
5328
|
/**
|
|
4523
5329
|
* KNOWLEDGE commitment definition
|
|
4524
5330
|
*
|
|
@@ -4938,7 +5744,13 @@ class InitialMessageCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
4938
5744
|
`);
|
|
4939
5745
|
}
|
|
4940
5746
|
applyToAgentModelRequirements(requirements, content) {
|
|
4941
|
-
|
|
5747
|
+
// INITIAL MESSAGE is for UI display purposes and for conversation history construction.
|
|
5748
|
+
const newSample = { question: null, answer: content };
|
|
5749
|
+
const newSamples = [...(requirements.samples || []), newSample];
|
|
5750
|
+
return {
|
|
5751
|
+
...requirements,
|
|
5752
|
+
samples: newSamples,
|
|
5753
|
+
};
|
|
4942
5754
|
}
|
|
4943
5755
|
}
|
|
4944
5756
|
|
|
@@ -5970,27 +6782,16 @@ class NoteCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
5970
6782
|
`);
|
|
5971
6783
|
}
|
|
5972
6784
|
applyToAgentModelRequirements(requirements, content) {
|
|
5973
|
-
var _a;
|
|
5974
6785
|
// The NOTE commitment makes no changes to the system message or model requirements
|
|
5975
6786
|
// It only stores the note content in metadata for documentation purposes
|
|
5976
|
-
const trimmedContent = content
|
|
5977
|
-
if (
|
|
6787
|
+
const trimmedContent = spaceTrim$1(content);
|
|
6788
|
+
if (trimmedContent === '') {
|
|
5978
6789
|
return requirements;
|
|
5979
6790
|
}
|
|
5980
|
-
//
|
|
5981
|
-
const existingNoteContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.NOTE) || '';
|
|
5982
|
-
// Merge the new content with existing note content
|
|
5983
|
-
// When multiple NOTE commitments exist, they are aggregated together
|
|
5984
|
-
const mergedNoteContent = existingNoteContent ? `${existingNoteContent}\n${trimmedContent}` : trimmedContent;
|
|
5985
|
-
// Store the merged note content in metadata for debugging and inspection
|
|
5986
|
-
const updatedMetadata = {
|
|
5987
|
-
...requirements.metadata,
|
|
5988
|
-
NOTE: mergedNoteContent,
|
|
5989
|
-
};
|
|
5990
|
-
// Return requirements with updated metadata but no changes to system message
|
|
6791
|
+
// Return requirements with updated notes but no changes to system message
|
|
5991
6792
|
return {
|
|
5992
6793
|
...requirements,
|
|
5993
|
-
|
|
6794
|
+
notes: [...(requirements.notes || []), trimmedContent],
|
|
5994
6795
|
};
|
|
5995
6796
|
}
|
|
5996
6797
|
}
|
|
@@ -6774,6 +7575,14 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
6774
7575
|
\`\`\`
|
|
6775
7576
|
`);
|
|
6776
7577
|
}
|
|
7578
|
+
/**
|
|
7579
|
+
* Gets human-readable titles for tool functions provided by this commitment.
|
|
7580
|
+
*/
|
|
7581
|
+
getToolTitles() {
|
|
7582
|
+
return {
|
|
7583
|
+
web_browser: 'Web browser',
|
|
7584
|
+
};
|
|
7585
|
+
}
|
|
6777
7586
|
applyToAgentModelRequirements(requirements, content) {
|
|
6778
7587
|
// Get existing tools array or create new one
|
|
6779
7588
|
const existingTools = requirements.tools || [];
|
|
@@ -6802,14 +7611,17 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
6802
7611
|
},
|
|
6803
7612
|
]);
|
|
6804
7613
|
// Return requirements with updated tools and metadata
|
|
6805
|
-
return {
|
|
7614
|
+
return this.appendToSystemMessage({
|
|
6806
7615
|
...requirements,
|
|
6807
7616
|
tools: updatedTools,
|
|
6808
7617
|
metadata: {
|
|
6809
7618
|
...requirements.metadata,
|
|
6810
7619
|
useBrowser: true,
|
|
6811
7620
|
},
|
|
6812
|
-
}
|
|
7621
|
+
}, spaceTrim$1(`
|
|
7622
|
+
You have access to the web browser. Use it to access specific websites or browse the internet.
|
|
7623
|
+
When you need to know some information from a specific website, use the tool provided to you.
|
|
7624
|
+
`));
|
|
6813
7625
|
}
|
|
6814
7626
|
}
|
|
6815
7627
|
/**
|
|
@@ -6817,82 +7629,267 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
6817
7629
|
*/
|
|
6818
7630
|
|
|
6819
7631
|
/**
|
|
6820
|
-
* USE
|
|
6821
|
-
*
|
|
6822
|
-
* The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
|
|
6823
|
-
* for retrieving additional instructions and actions.
|
|
7632
|
+
* USE IMAGE GENERATOR commitment definition
|
|
6824
7633
|
*
|
|
6825
|
-
* The
|
|
7634
|
+
* The `USE IMAGE GENERATOR` commitment indicates that the agent should utilize an image generation tool
|
|
7635
|
+
* to create images based on text prompts.
|
|
6826
7636
|
*
|
|
6827
7637
|
* Example usage in agent source:
|
|
6828
7638
|
*
|
|
6829
7639
|
* ```book
|
|
6830
|
-
* USE
|
|
7640
|
+
* USE IMAGE GENERATOR
|
|
7641
|
+
* USE IMAGE GENERATOR Create realistic images of nature
|
|
6831
7642
|
* ```
|
|
6832
7643
|
*
|
|
6833
7644
|
* @private [🪔] Maybe export the commitments through some package
|
|
6834
7645
|
*/
|
|
6835
|
-
class
|
|
6836
|
-
constructor() {
|
|
6837
|
-
super('USE
|
|
7646
|
+
class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
|
|
7647
|
+
constructor(type = 'USE IMAGE GENERATOR') {
|
|
7648
|
+
super(type, ['USE IMAGE GENERATION', 'IMAGE GENERATOR', 'IMAGE GENERATION', 'USE IMAGE']);
|
|
6838
7649
|
}
|
|
6839
7650
|
/**
|
|
6840
|
-
* Short one-line description of USE
|
|
7651
|
+
* Short one-line description of USE IMAGE GENERATOR.
|
|
6841
7652
|
*/
|
|
6842
7653
|
get description() {
|
|
6843
|
-
return '
|
|
7654
|
+
return 'Enable the agent to use an image generation tool for creating images from text prompts.';
|
|
6844
7655
|
}
|
|
6845
7656
|
/**
|
|
6846
7657
|
* Icon for this commitment.
|
|
6847
7658
|
*/
|
|
6848
7659
|
get icon() {
|
|
6849
|
-
return '
|
|
7660
|
+
return '🖼️';
|
|
6850
7661
|
}
|
|
6851
7662
|
/**
|
|
6852
|
-
* Markdown documentation for USE
|
|
7663
|
+
* Markdown documentation for USE IMAGE GENERATOR commitment.
|
|
6853
7664
|
*/
|
|
6854
7665
|
get documentation() {
|
|
6855
7666
|
return spaceTrim$1(`
|
|
6856
|
-
# USE
|
|
7667
|
+
# USE IMAGE GENERATOR
|
|
6857
7668
|
|
|
6858
|
-
|
|
7669
|
+
Enables the agent to use an image generation tool to create images based on text prompts.
|
|
6859
7670
|
|
|
6860
7671
|
## Key aspects
|
|
6861
7672
|
|
|
6862
|
-
- The content following \`USE
|
|
6863
|
-
-
|
|
6864
|
-
-
|
|
7673
|
+
- The content following \`USE IMAGE GENERATOR\` is an arbitrary text that the agent should know (e.g. style instructions or safety guidelines).
|
|
7674
|
+
- The actual image generation is handled by the agent runtime using LLM execution tools.
|
|
7675
|
+
- Allows the agent to generate visual content based on user requests.
|
|
7676
|
+
- Returns the URL of the generated image.
|
|
6865
7677
|
|
|
6866
|
-
##
|
|
7678
|
+
## Examples
|
|
6867
7679
|
|
|
6868
7680
|
\`\`\`book
|
|
6869
|
-
|
|
7681
|
+
Visual Artist
|
|
6870
7682
|
|
|
6871
|
-
PERSONA You are a
|
|
6872
|
-
USE
|
|
7683
|
+
PERSONA You are a creative visual artist who can generate images.
|
|
7684
|
+
USE IMAGE GENERATOR
|
|
7685
|
+
RULE Always describe the generated image to the user.
|
|
7686
|
+
\`\`\`
|
|
7687
|
+
|
|
7688
|
+
\`\`\`book
|
|
7689
|
+
Interior Designer
|
|
7690
|
+
|
|
7691
|
+
PERSONA You are an interior designer who helps users visualize their space.
|
|
7692
|
+
USE IMAGE GENERATOR Professional interior design renders.
|
|
7693
|
+
ACTION Generate a preview of the designed room.
|
|
6873
7694
|
\`\`\`
|
|
6874
7695
|
`);
|
|
6875
7696
|
}
|
|
6876
7697
|
applyToAgentModelRequirements(requirements, content) {
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
7698
|
+
// Get existing tools array or create new one
|
|
7699
|
+
const existingTools = requirements.tools || [];
|
|
7700
|
+
// Add 'generate_image' to tools if not already present
|
|
7701
|
+
const updatedTools = existingTools.some((tool) => tool.name === 'generate_image')
|
|
7702
|
+
? existingTools
|
|
7703
|
+
: [
|
|
7704
|
+
...existingTools,
|
|
7705
|
+
{
|
|
7706
|
+
name: 'generate_image',
|
|
7707
|
+
description: spaceTrim$1(`
|
|
7708
|
+
Generate an image from a text prompt.
|
|
7709
|
+
Use this tool when the user asks to create, draw, or generate an image.
|
|
7710
|
+
${!content ? '' : `Style instructions / guidelines: ${content}`}
|
|
7711
|
+
`),
|
|
7712
|
+
parameters: {
|
|
7713
|
+
type: 'object',
|
|
7714
|
+
properties: {
|
|
7715
|
+
prompt: {
|
|
7716
|
+
type: 'string',
|
|
7717
|
+
description: 'The detailed description of the image to generate',
|
|
7718
|
+
},
|
|
7719
|
+
},
|
|
7720
|
+
required: ['prompt'],
|
|
7721
|
+
},
|
|
7722
|
+
},
|
|
7723
|
+
];
|
|
7724
|
+
// Return requirements with updated tools and metadata
|
|
7725
|
+
return this.appendToSystemMessage({
|
|
6887
7726
|
...requirements,
|
|
6888
|
-
|
|
6889
|
-
|
|
7727
|
+
tools: updatedTools,
|
|
7728
|
+
metadata: {
|
|
7729
|
+
...requirements.metadata,
|
|
7730
|
+
useImageGenerator: content || true,
|
|
7731
|
+
},
|
|
7732
|
+
}, spaceTrim$1(`
|
|
7733
|
+
You have access to an image generator. Use it to create images based on user requests.
|
|
7734
|
+
When you generate an image, you will receive a URL of the generated image.
|
|
7735
|
+
`));
|
|
7736
|
+
}
|
|
7737
|
+
/**
|
|
7738
|
+
* Gets human-readable titles for tool functions provided by this commitment.
|
|
7739
|
+
*/
|
|
7740
|
+
getToolTitles() {
|
|
7741
|
+
return {
|
|
7742
|
+
generate_image: 'Generate image',
|
|
7743
|
+
};
|
|
7744
|
+
}
|
|
7745
|
+
/**
|
|
7746
|
+
* Gets the `generate_image` tool function implementation.
|
|
7747
|
+
*/
|
|
7748
|
+
getToolFunctions() {
|
|
7749
|
+
return {
|
|
7750
|
+
async generate_image(args, ...extra) {
|
|
7751
|
+
console.log('!!!! [Tool] generate_image called', { args });
|
|
7752
|
+
const { prompt } = args;
|
|
7753
|
+
if (!prompt) {
|
|
7754
|
+
throw new Error('Image prompt is required');
|
|
7755
|
+
}
|
|
7756
|
+
const { llmTools } = extra[0] || {};
|
|
7757
|
+
if (!llmTools || !llmTools.callImageGenerationModel) {
|
|
7758
|
+
throw new Error('Image generation is not supported by the current model provider');
|
|
7759
|
+
}
|
|
7760
|
+
const result = await llmTools.callImageGenerationModel({
|
|
7761
|
+
content: prompt,
|
|
7762
|
+
modelName: 'dall-e-3', // Defaulting to dall-e-3, but this could be configurable
|
|
7763
|
+
});
|
|
7764
|
+
return result.content;
|
|
7765
|
+
},
|
|
7766
|
+
};
|
|
6890
7767
|
}
|
|
6891
7768
|
}
|
|
6892
7769
|
/**
|
|
6893
7770
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
6894
7771
|
*/
|
|
6895
7772
|
|
|
7773
|
+
/**
|
|
7774
|
+
* USE MCP commitment definition
|
|
7775
|
+
*
|
|
7776
|
+
* The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
|
|
7777
|
+
* for retrieving additional instructions and actions.
|
|
7778
|
+
*
|
|
7779
|
+
* The content following `USE MCP` is the URL of the MCP server.
|
|
7780
|
+
*
|
|
7781
|
+
* Example usage in agent source:
|
|
7782
|
+
*
|
|
7783
|
+
* ```book
|
|
7784
|
+
* USE MCP http://mcp-server-url.com
|
|
7785
|
+
* ```
|
|
7786
|
+
*
|
|
7787
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
7788
|
+
*/
|
|
7789
|
+
class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
|
|
7790
|
+
constructor() {
|
|
7791
|
+
super('USE MCP', ['MCP']);
|
|
7792
|
+
}
|
|
7793
|
+
/**
|
|
7794
|
+
* Short one-line description of USE MCP.
|
|
7795
|
+
*/
|
|
7796
|
+
get description() {
|
|
7797
|
+
return 'Connects the agent to an external MCP server for additional capabilities.';
|
|
7798
|
+
}
|
|
7799
|
+
/**
|
|
7800
|
+
* Icon for this commitment.
|
|
7801
|
+
*/
|
|
7802
|
+
get icon() {
|
|
7803
|
+
return '🔌';
|
|
7804
|
+
}
|
|
7805
|
+
/**
|
|
7806
|
+
* Markdown documentation for USE MCP commitment.
|
|
7807
|
+
*/
|
|
7808
|
+
get documentation() {
|
|
7809
|
+
return spaceTrim$1(`
|
|
7810
|
+
# USE MCP
|
|
7811
|
+
|
|
7812
|
+
Connects the agent to an external Model Context Protocol (MCP) server.
|
|
7813
|
+
|
|
7814
|
+
## Key aspects
|
|
7815
|
+
|
|
7816
|
+
- The content following \`USE MCP\` must be a valid URL
|
|
7817
|
+
- Multiple MCP servers can be connected by using multiple \`USE MCP\` commitments
|
|
7818
|
+
- The agent will have access to tools and resources provided by the MCP server
|
|
7819
|
+
|
|
7820
|
+
## Example
|
|
7821
|
+
|
|
7822
|
+
\`\`\`book
|
|
7823
|
+
Company Lawyer
|
|
7824
|
+
|
|
7825
|
+
PERSONA You are a company lawyer.
|
|
7826
|
+
USE MCP http://legal-db.example.com
|
|
7827
|
+
\`\`\`
|
|
7828
|
+
`);
|
|
7829
|
+
}
|
|
7830
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
7831
|
+
const mcpServerUrl = content.trim();
|
|
7832
|
+
if (!mcpServerUrl) {
|
|
7833
|
+
return requirements;
|
|
7834
|
+
}
|
|
7835
|
+
const existingMcpServers = requirements.mcpServers || [];
|
|
7836
|
+
// Avoid duplicates
|
|
7837
|
+
if (existingMcpServers.includes(mcpServerUrl)) {
|
|
7838
|
+
return requirements;
|
|
7839
|
+
}
|
|
7840
|
+
return {
|
|
7841
|
+
...requirements,
|
|
7842
|
+
mcpServers: [...existingMcpServers, mcpServerUrl],
|
|
7843
|
+
};
|
|
7844
|
+
}
|
|
7845
|
+
}
|
|
7846
|
+
/**
|
|
7847
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
7848
|
+
*/
|
|
7849
|
+
|
|
7850
|
+
/**
|
|
7851
|
+
* A search engine implementation that uses the SerpApi to fetch Google search results.
|
|
7852
|
+
*
|
|
7853
|
+
* @private <- TODO: !!!! Export via some package
|
|
7854
|
+
*/
|
|
7855
|
+
class SerpSearchEngine {
|
|
7856
|
+
get title() {
|
|
7857
|
+
return 'SerpApi Search Engine';
|
|
7858
|
+
}
|
|
7859
|
+
get description() {
|
|
7860
|
+
return 'Search engine that uses SerpApi to fetch Google search results';
|
|
7861
|
+
}
|
|
7862
|
+
checkConfiguration() {
|
|
7863
|
+
if (!process.env.SERP_API_KEY) {
|
|
7864
|
+
throw new Error('SERP_API_KEY is not configured');
|
|
7865
|
+
}
|
|
7866
|
+
}
|
|
7867
|
+
async search(query, options = {}) {
|
|
7868
|
+
const apiKey = process.env.SERP_API_KEY;
|
|
7869
|
+
if (!apiKey) {
|
|
7870
|
+
throw new Error('SERP_API_KEY is not configured');
|
|
7871
|
+
}
|
|
7872
|
+
const url = new URL('https://serpapi.com/search');
|
|
7873
|
+
url.searchParams.set('api_key', apiKey);
|
|
7874
|
+
url.searchParams.set('engine', 'google');
|
|
7875
|
+
url.searchParams.set('q', query);
|
|
7876
|
+
for (const [key, value] of Object.entries(options)) {
|
|
7877
|
+
url.searchParams.set(key, String(value));
|
|
7878
|
+
}
|
|
7879
|
+
const response = await fetch(url.toString());
|
|
7880
|
+
if (!response.ok) {
|
|
7881
|
+
const body = await response.text();
|
|
7882
|
+
throw new Error(`SerpApi failed with status ${response.status}: ${response.statusText}\n${body}`);
|
|
7883
|
+
}
|
|
7884
|
+
const data = (await response.json());
|
|
7885
|
+
return (data.organic_results || []).map((item) => ({
|
|
7886
|
+
title: item.title,
|
|
7887
|
+
url: item.link,
|
|
7888
|
+
snippet: item.snippet || '',
|
|
7889
|
+
}));
|
|
7890
|
+
}
|
|
7891
|
+
}
|
|
7892
|
+
|
|
6896
7893
|
/**
|
|
6897
7894
|
* USE SEARCH ENGINE commitment definition
|
|
6898
7895
|
*
|
|
@@ -6912,7 +7909,7 @@ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
6912
7909
|
*/
|
|
6913
7910
|
class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
|
|
6914
7911
|
constructor() {
|
|
6915
|
-
super('USE SEARCH ENGINE', ['
|
|
7912
|
+
super('USE SEARCH ENGINE', ['USE SEARCH']);
|
|
6916
7913
|
}
|
|
6917
7914
|
/**
|
|
6918
7915
|
* Short one-line description of USE SEARCH ENGINE.
|
|
@@ -6969,18 +7966,13 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
6969
7966
|
? existingTools
|
|
6970
7967
|
: [
|
|
6971
7968
|
...existingTools,
|
|
6972
|
-
{ type: 'web_search' },
|
|
6973
|
-
// <- Note: [🔰] This is just using simple native search tool by OpenAI @see https://platform.openai.com/docs/guides/tools-web-search
|
|
6974
|
-
// In future we will use proper MCP search tool:
|
|
6975
|
-
/*
|
|
6976
|
-
|
|
6977
7969
|
{
|
|
6978
7970
|
name: 'web_search',
|
|
6979
|
-
description: spaceTrim(`
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
7971
|
+
description: spaceTrim$1(`
|
|
7972
|
+
Search the internet for information.
|
|
7973
|
+
Use this tool when you need to find up-to-date information or facts that you don't know.
|
|
7974
|
+
${!content ? '' : `Search scope / instructions: ${content}`}
|
|
7975
|
+
`),
|
|
6984
7976
|
parameters: {
|
|
6985
7977
|
type: 'object',
|
|
6986
7978
|
properties: {
|
|
@@ -6988,20 +7980,229 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
6988
7980
|
type: 'string',
|
|
6989
7981
|
description: 'The search query',
|
|
6990
7982
|
},
|
|
7983
|
+
location: {
|
|
7984
|
+
type: 'string',
|
|
7985
|
+
description: 'The location for the search (e.g., "Austin, Texas, United States" or "Prague, Czechia")',
|
|
7986
|
+
},
|
|
7987
|
+
gl: {
|
|
7988
|
+
type: 'string',
|
|
7989
|
+
description: 'The country code (e.g., "us" for United States, "cz" for Czechia)',
|
|
7990
|
+
},
|
|
7991
|
+
hl: {
|
|
7992
|
+
type: 'string',
|
|
7993
|
+
description: 'The language code (e.g., "en" for English, "cs" for Czech)',
|
|
7994
|
+
},
|
|
7995
|
+
num: {
|
|
7996
|
+
type: 'integer',
|
|
7997
|
+
description: 'Number of results to return',
|
|
7998
|
+
},
|
|
7999
|
+
engine: {
|
|
8000
|
+
type: 'string',
|
|
8001
|
+
description: 'The search engine to use (e.g., "google", "bing", "yahoo", "baidu")',
|
|
8002
|
+
},
|
|
8003
|
+
google_domain: {
|
|
8004
|
+
type: 'string',
|
|
8005
|
+
description: 'The Google domain to use (e.g., "google.com", "google.cz")',
|
|
8006
|
+
},
|
|
6991
8007
|
},
|
|
6992
8008
|
required: ['query'],
|
|
6993
8009
|
},
|
|
6994
8010
|
},
|
|
6995
|
-
*/
|
|
6996
8011
|
];
|
|
6997
8012
|
// Return requirements with updated tools and metadata
|
|
6998
|
-
return {
|
|
8013
|
+
return this.appendToSystemMessage({
|
|
6999
8014
|
...requirements,
|
|
7000
8015
|
tools: updatedTools,
|
|
7001
8016
|
metadata: {
|
|
7002
8017
|
...requirements.metadata,
|
|
7003
8018
|
useSearchEngine: content || true,
|
|
7004
8019
|
},
|
|
8020
|
+
}, spaceTrim$1(`
|
|
8021
|
+
Tools:
|
|
8022
|
+
You have access to the web search engine via the tool "web_search".
|
|
8023
|
+
Use it to find up-to-date information or facts that you don't know.
|
|
8024
|
+
When you need to know some information from the internet, use the tool provided to you.
|
|
8025
|
+
Do not make up information when you can search for it.
|
|
8026
|
+
Do not tell the user you cannot search for information, YOU CAN.
|
|
8027
|
+
`));
|
|
8028
|
+
}
|
|
8029
|
+
/**
|
|
8030
|
+
* Gets human-readable titles for tool functions provided by this commitment.
|
|
8031
|
+
*/
|
|
8032
|
+
getToolTitles() {
|
|
8033
|
+
return {
|
|
8034
|
+
web_search: 'Web search',
|
|
8035
|
+
};
|
|
8036
|
+
}
|
|
8037
|
+
/**
|
|
8038
|
+
* Gets the `web_search` tool function implementation.
|
|
8039
|
+
*/
|
|
8040
|
+
getToolFunctions() {
|
|
8041
|
+
return {
|
|
8042
|
+
async web_search(args) {
|
|
8043
|
+
console.log('!!!! [Tool] web_search called', { args });
|
|
8044
|
+
const { query, ...options } = args;
|
|
8045
|
+
if (!query) {
|
|
8046
|
+
throw new Error('Search query is required');
|
|
8047
|
+
}
|
|
8048
|
+
const searchEngine = new SerpSearchEngine();
|
|
8049
|
+
const results = await searchEngine.search(query, options);
|
|
8050
|
+
return spaceTrim$1((block) => `
|
|
8051
|
+
Search results for "${query}"${Object.keys(options).length === 0 ? '' : ` with options ${JSON.stringify(options)}`}:
|
|
8052
|
+
|
|
8053
|
+
${block(results
|
|
8054
|
+
.map((result) => spaceTrim$1(`
|
|
8055
|
+
- **${result.title}**
|
|
8056
|
+
${result.url}
|
|
8057
|
+
${result.snippet}
|
|
8058
|
+
`))
|
|
8059
|
+
.join('\n\n'))}
|
|
8060
|
+
`);
|
|
8061
|
+
},
|
|
8062
|
+
};
|
|
8063
|
+
}
|
|
8064
|
+
}
|
|
8065
|
+
/**
|
|
8066
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
8067
|
+
*/
|
|
8068
|
+
|
|
8069
|
+
/**
|
|
8070
|
+
* USE TIME commitment definition
|
|
8071
|
+
*
|
|
8072
|
+
* The `USE TIME` commitment indicates that the agent should be able to determine the current date and time.
|
|
8073
|
+
*
|
|
8074
|
+
* Example usage in agent source:
|
|
8075
|
+
*
|
|
8076
|
+
* ```book
|
|
8077
|
+
* USE TIME
|
|
8078
|
+
* ```
|
|
8079
|
+
*
|
|
8080
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
8081
|
+
*/
|
|
8082
|
+
class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
|
|
8083
|
+
constructor() {
|
|
8084
|
+
super('USE TIME', ['CURRENT TIME', 'TIME', 'DATE']);
|
|
8085
|
+
}
|
|
8086
|
+
/**
|
|
8087
|
+
* Short one-line description of USE TIME.
|
|
8088
|
+
*/
|
|
8089
|
+
get description() {
|
|
8090
|
+
return 'Enable the agent to determine the current date and time.';
|
|
8091
|
+
}
|
|
8092
|
+
/**
|
|
8093
|
+
* Icon for this commitment.
|
|
8094
|
+
*/
|
|
8095
|
+
get icon() {
|
|
8096
|
+
return '🕒';
|
|
8097
|
+
}
|
|
8098
|
+
/**
|
|
8099
|
+
* Markdown documentation for USE TIME commitment.
|
|
8100
|
+
*/
|
|
8101
|
+
get documentation() {
|
|
8102
|
+
return spaceTrim$1(`
|
|
8103
|
+
# USE TIME
|
|
8104
|
+
|
|
8105
|
+
Enables the agent to determine the current date and time.
|
|
8106
|
+
|
|
8107
|
+
## Key aspects
|
|
8108
|
+
|
|
8109
|
+
- This tool won't receive any input.
|
|
8110
|
+
- It outputs the current date and time as an ISO 8601 string.
|
|
8111
|
+
- Allows the agent to answer questions about the current time or date.
|
|
8112
|
+
|
|
8113
|
+
## Examples
|
|
8114
|
+
|
|
8115
|
+
\`\`\`book
|
|
8116
|
+
Time-aware Assistant
|
|
8117
|
+
|
|
8118
|
+
PERSONA You are a helpful assistant who knows the current time.
|
|
8119
|
+
USE TIME
|
|
8120
|
+
\`\`\`
|
|
8121
|
+
`);
|
|
8122
|
+
}
|
|
8123
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
8124
|
+
// Get existing tools array or create new one
|
|
8125
|
+
const existingTools = requirements.tools || [];
|
|
8126
|
+
// Add 'get_current_time' to tools if not already present
|
|
8127
|
+
const updatedTools = existingTools.some((tool) => tool.name === 'get_current_time')
|
|
8128
|
+
? existingTools
|
|
8129
|
+
: [
|
|
8130
|
+
...existingTools,
|
|
8131
|
+
{
|
|
8132
|
+
name: 'get_current_time',
|
|
8133
|
+
description: 'Get the current date and time in ISO 8601 format.',
|
|
8134
|
+
parameters: {
|
|
8135
|
+
type: 'object',
|
|
8136
|
+
properties: {
|
|
8137
|
+
timezone: {
|
|
8138
|
+
type: 'string',
|
|
8139
|
+
description: 'Optional timezone name (e.g. "Europe/Prague", "UTC", "America/New_York").',
|
|
8140
|
+
},
|
|
8141
|
+
},
|
|
8142
|
+
required: [],
|
|
8143
|
+
},
|
|
8144
|
+
},
|
|
8145
|
+
// <- TODO: !!!! define the function in LLM tools
|
|
8146
|
+
];
|
|
8147
|
+
// Return requirements with updated tools and metadata
|
|
8148
|
+
return this.appendToSystemMessage({
|
|
8149
|
+
...requirements,
|
|
8150
|
+
tools: updatedTools,
|
|
8151
|
+
metadata: {
|
|
8152
|
+
...requirements.metadata,
|
|
8153
|
+
},
|
|
8154
|
+
}, spaceTrim$1(`
|
|
8155
|
+
Tool:
|
|
8156
|
+
You have access to the current date and time via the tool "get_current_time".
|
|
8157
|
+
Use it to answer questions about the current date and time.
|
|
8158
|
+
When you need to know the current date or time, use the tool provided to you.
|
|
8159
|
+
Do not make up the current date or time; always use the tool to get accurate information.
|
|
8160
|
+
`));
|
|
8161
|
+
}
|
|
8162
|
+
/**
|
|
8163
|
+
* Gets human-readable titles for tool functions provided by this commitment.
|
|
8164
|
+
*/
|
|
8165
|
+
getToolTitles() {
|
|
8166
|
+
return {
|
|
8167
|
+
get_current_time: 'Get current time',
|
|
8168
|
+
};
|
|
8169
|
+
}
|
|
8170
|
+
/**
|
|
8171
|
+
* Gets the `get_current_time` tool function implementation.
|
|
8172
|
+
*/
|
|
8173
|
+
getToolFunctions() {
|
|
8174
|
+
return {
|
|
8175
|
+
async get_current_time(args) {
|
|
8176
|
+
var _a;
|
|
8177
|
+
console.log('!!!! [Tool] get_current_time called', { args });
|
|
8178
|
+
const { timezone } = args;
|
|
8179
|
+
if (!timezone) {
|
|
8180
|
+
return new Date().toISOString();
|
|
8181
|
+
}
|
|
8182
|
+
try {
|
|
8183
|
+
// Note: Returning ISO 8601 string but in the requested timezone
|
|
8184
|
+
const formatter = new Intl.DateTimeFormat('en-CA', {
|
|
8185
|
+
timeZone: timezone,
|
|
8186
|
+
year: 'numeric',
|
|
8187
|
+
month: '2-digit',
|
|
8188
|
+
day: '2-digit',
|
|
8189
|
+
hour: '2-digit',
|
|
8190
|
+
minute: '2-digit',
|
|
8191
|
+
second: '2-digit',
|
|
8192
|
+
hour12: false,
|
|
8193
|
+
timeZoneName: 'shortOffset',
|
|
8194
|
+
});
|
|
8195
|
+
const parts = formatter.formatToParts(new Date());
|
|
8196
|
+
const part = (type) => { var _a; return (_a = parts.find((p) => p.type === type)) === null || _a === void 0 ? void 0 : _a.value; };
|
|
8197
|
+
// en-CA format is YYYY-MM-DD
|
|
8198
|
+
const isoString = `${part('year')}-${part('month')}-${part('day')}T${part('hour')}:${part('minute')}:${part('second')}${(_a = part('timeZoneName')) === null || _a === void 0 ? void 0 : _a.replace('GMT', '')}`;
|
|
8199
|
+
return isoString;
|
|
8200
|
+
}
|
|
8201
|
+
catch (error) {
|
|
8202
|
+
// Fallback to UTC if timezone is invalid
|
|
8203
|
+
return new Date().toISOString();
|
|
8204
|
+
}
|
|
8205
|
+
},
|
|
7005
8206
|
};
|
|
7006
8207
|
}
|
|
7007
8208
|
}
|
|
@@ -7076,7 +8277,6 @@ class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
7076
8277
|
}
|
|
7077
8278
|
}
|
|
7078
8279
|
|
|
7079
|
-
// Import all commitment definition classes
|
|
7080
8280
|
/**
|
|
7081
8281
|
* Registry of all available commitment definitions
|
|
7082
8282
|
* This array contains instances of all commitment definitions
|
|
@@ -7093,10 +8293,10 @@ const COMMITMENT_REGISTRY = [
|
|
|
7093
8293
|
new MemoryCommitmentDefinition('MEMORIES'),
|
|
7094
8294
|
new StyleCommitmentDefinition('STYLE'),
|
|
7095
8295
|
new StyleCommitmentDefinition('STYLES'),
|
|
7096
|
-
new RuleCommitmentDefinition('RULE'),
|
|
7097
8296
|
new RuleCommitmentDefinition('RULES'),
|
|
7098
|
-
new
|
|
8297
|
+
new RuleCommitmentDefinition('RULE'),
|
|
7099
8298
|
new LanguageCommitmentDefinition('LANGUAGES'),
|
|
8299
|
+
new LanguageCommitmentDefinition('LANGUAGE'),
|
|
7100
8300
|
new SampleCommitmentDefinition('SAMPLE'),
|
|
7101
8301
|
new SampleCommitmentDefinition('EXAMPLE'),
|
|
7102
8302
|
new FormatCommitmentDefinition('FORMAT'),
|
|
@@ -7118,6 +8318,7 @@ const COMMITMENT_REGISTRY = [
|
|
|
7118
8318
|
new NoteCommitmentDefinition('NOTES'),
|
|
7119
8319
|
new NoteCommitmentDefinition('COMMENT'),
|
|
7120
8320
|
new NoteCommitmentDefinition('NONCE'),
|
|
8321
|
+
new NoteCommitmentDefinition('TODO'),
|
|
7121
8322
|
new GoalCommitmentDefinition('GOAL'),
|
|
7122
8323
|
new GoalCommitmentDefinition('GOALS'),
|
|
7123
8324
|
new InitialMessageCommitmentDefinition(),
|
|
@@ -7136,6 +8337,16 @@ const COMMITMENT_REGISTRY = [
|
|
|
7136
8337
|
new ClosedCommitmentDefinition(),
|
|
7137
8338
|
new UseBrowserCommitmentDefinition(),
|
|
7138
8339
|
new UseSearchEngineCommitmentDefinition(),
|
|
8340
|
+
new UseTimeCommitmentDefinition(),
|
|
8341
|
+
new UseImageGeneratorCommitmentDefinition('USE IMAGE GENERATOR'),
|
|
8342
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8343
|
+
new UseImageGeneratorCommitmentDefinition('USE IMAGE GENERATION'),
|
|
8344
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8345
|
+
new UseImageGeneratorCommitmentDefinition('IMAGE GENERATOR'),
|
|
8346
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8347
|
+
new UseImageGeneratorCommitmentDefinition('IMAGE GENERATION'),
|
|
8348
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8349
|
+
new UseImageGeneratorCommitmentDefinition('USE IMAGE'),
|
|
7139
8350
|
new UseMcpCommitmentDefinition(),
|
|
7140
8351
|
new UseCommitmentDefinition(),
|
|
7141
8352
|
// Not yet implemented commitments (using placeholder)
|
|
@@ -7145,6 +8356,7 @@ const COMMITMENT_REGISTRY = [
|
|
|
7145
8356
|
new NotYetImplementedCommitmentDefinition('AVOID'),
|
|
7146
8357
|
new NotYetImplementedCommitmentDefinition('AVOIDANCE'),
|
|
7147
8358
|
new NotYetImplementedCommitmentDefinition('CONTEXT'),
|
|
8359
|
+
// <- TODO: Prompt: Leverage aliases instead of duplicating commitment definitions
|
|
7148
8360
|
];
|
|
7149
8361
|
/**
|
|
7150
8362
|
* Gets a commitment definition by its type
|
|
@@ -7165,6 +8377,21 @@ function getCommitmentDefinition(type) {
|
|
|
7165
8377
|
function getAllCommitmentDefinitions() {
|
|
7166
8378
|
return $deepFreeze([...COMMITMENT_REGISTRY]);
|
|
7167
8379
|
}
|
|
8380
|
+
/**
|
|
8381
|
+
* Gets all tool titles provided by all commitments
|
|
8382
|
+
*
|
|
8383
|
+
* @public exported from `@promptbook/core`
|
|
8384
|
+
*/
|
|
8385
|
+
function getAllCommitmentsToolTitles() {
|
|
8386
|
+
const allToolTitles = {};
|
|
8387
|
+
for (const commitmentDefinition of getAllCommitmentDefinitions()) {
|
|
8388
|
+
const toolTitles = commitmentDefinition.getToolTitles();
|
|
8389
|
+
for (const [funcName, title] of Object.entries(toolTitles)) {
|
|
8390
|
+
allToolTitles[funcName] = title;
|
|
8391
|
+
}
|
|
8392
|
+
}
|
|
8393
|
+
return allToolTitles;
|
|
8394
|
+
}
|
|
7168
8395
|
/**
|
|
7169
8396
|
* TODO: [🧠] Maybe create through standardized $register
|
|
7170
8397
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -7248,11 +8475,37 @@ function parseAgentSourceWithCommitments(agentSource) {
|
|
|
7248
8475
|
let currentCommitment = null;
|
|
7249
8476
|
// Process lines starting from after the agent name line
|
|
7250
8477
|
const startIndex = agentNameLineIndex >= 0 ? agentNameLineIndex + 1 : 0;
|
|
8478
|
+
let isInsideCodeBlock = false;
|
|
7251
8479
|
for (let i = startIndex; i < lines.length; i++) {
|
|
7252
8480
|
const line = lines[i];
|
|
7253
8481
|
if (line === undefined) {
|
|
7254
8482
|
continue;
|
|
7255
8483
|
}
|
|
8484
|
+
const trimmedLine = line.trim();
|
|
8485
|
+
// Check if this line starts or ends a code block
|
|
8486
|
+
if (trimmedLine.startsWith('```')) {
|
|
8487
|
+
isInsideCodeBlock = !isInsideCodeBlock;
|
|
8488
|
+
if (currentCommitment) {
|
|
8489
|
+
// If we are inside a commitment, the code block is part of it
|
|
8490
|
+
currentCommitment.contentLines.push(line);
|
|
8491
|
+
}
|
|
8492
|
+
else {
|
|
8493
|
+
// If we are not inside a commitment, the code block is non-commitment
|
|
8494
|
+
nonCommitmentLines.push(line);
|
|
8495
|
+
}
|
|
8496
|
+
continue;
|
|
8497
|
+
}
|
|
8498
|
+
if (isInsideCodeBlock) {
|
|
8499
|
+
if (currentCommitment) {
|
|
8500
|
+
// If we are inside a commitment and a code block, the line is part of the commitment
|
|
8501
|
+
currentCommitment.contentLines.push(line);
|
|
8502
|
+
}
|
|
8503
|
+
else {
|
|
8504
|
+
// If we are inside a code block but not a commitment, the line is non-commitment
|
|
8505
|
+
nonCommitmentLines.push(line);
|
|
8506
|
+
}
|
|
8507
|
+
continue;
|
|
8508
|
+
}
|
|
7256
8509
|
// Check if this line starts a new commitment
|
|
7257
8510
|
let foundNewCommitment = false;
|
|
7258
8511
|
for (const definition of COMMITMENT_REGISTRY) {
|
|
@@ -7426,7 +8679,24 @@ function parseAgentSource(agentSource) {
|
|
|
7426
8679
|
const meta = {};
|
|
7427
8680
|
const links = [];
|
|
7428
8681
|
const capabilities = [];
|
|
8682
|
+
const samples = [];
|
|
8683
|
+
let pendingUserMessage = null;
|
|
7429
8684
|
for (const commitment of parseResult.commitments) {
|
|
8685
|
+
if (commitment.type === 'INITIAL MESSAGE') {
|
|
8686
|
+
samples.push({ question: null, answer: commitment.content });
|
|
8687
|
+
continue;
|
|
8688
|
+
}
|
|
8689
|
+
if (commitment.type === 'USER MESSAGE') {
|
|
8690
|
+
pendingUserMessage = commitment.content;
|
|
8691
|
+
continue;
|
|
8692
|
+
}
|
|
8693
|
+
if (commitment.type === 'AGENT MESSAGE') {
|
|
8694
|
+
if (pendingUserMessage !== null) {
|
|
8695
|
+
samples.push({ question: pendingUserMessage, answer: commitment.content });
|
|
8696
|
+
pendingUserMessage = null;
|
|
8697
|
+
}
|
|
8698
|
+
continue;
|
|
8699
|
+
}
|
|
7430
8700
|
if (commitment.type === 'USE BROWSER') {
|
|
7431
8701
|
capabilities.push({
|
|
7432
8702
|
type: 'browser',
|
|
@@ -7438,11 +8708,84 @@ function parseAgentSource(agentSource) {
|
|
|
7438
8708
|
if (commitment.type === 'USE SEARCH ENGINE') {
|
|
7439
8709
|
capabilities.push({
|
|
7440
8710
|
type: 'search-engine',
|
|
7441
|
-
label: '
|
|
8711
|
+
label: 'Internet',
|
|
7442
8712
|
iconName: 'Search',
|
|
7443
8713
|
});
|
|
7444
8714
|
continue;
|
|
7445
8715
|
}
|
|
8716
|
+
if (commitment.type === 'USE SEARCH') {
|
|
8717
|
+
capabilities.push({
|
|
8718
|
+
type: 'search-engine',
|
|
8719
|
+
label: 'Internet',
|
|
8720
|
+
iconName: 'Search',
|
|
8721
|
+
});
|
|
8722
|
+
continue;
|
|
8723
|
+
}
|
|
8724
|
+
if (commitment.type === 'USE TIME') {
|
|
8725
|
+
capabilities.push({
|
|
8726
|
+
type: 'time',
|
|
8727
|
+
label: 'Time',
|
|
8728
|
+
iconName: 'Clock',
|
|
8729
|
+
});
|
|
8730
|
+
continue;
|
|
8731
|
+
}
|
|
8732
|
+
if (commitment.type === 'USE IMAGE GENERATOR') {
|
|
8733
|
+
capabilities.push({
|
|
8734
|
+
type: 'image-generator',
|
|
8735
|
+
label: 'Image Generator',
|
|
8736
|
+
iconName: 'Image',
|
|
8737
|
+
});
|
|
8738
|
+
continue;
|
|
8739
|
+
}
|
|
8740
|
+
if (commitment.type === 'FROM') {
|
|
8741
|
+
const content = spaceTrim$2(commitment.content).split('\n')[0] || '';
|
|
8742
|
+
if (content === 'Adam' || content === '' /* <- Note: Adam is implicit */) {
|
|
8743
|
+
continue;
|
|
8744
|
+
}
|
|
8745
|
+
let label = content;
|
|
8746
|
+
let iconName = 'SquareArrowOutUpRight'; // Inheritance remote
|
|
8747
|
+
if (content.startsWith('./') || content.startsWith('../') || content.startsWith('/')) {
|
|
8748
|
+
label = content.split('/').pop() || content;
|
|
8749
|
+
iconName = 'SquareArrowUpRight'; // Inheritance local
|
|
8750
|
+
}
|
|
8751
|
+
if (content === 'VOID') {
|
|
8752
|
+
label = 'VOID';
|
|
8753
|
+
iconName = 'ShieldAlert'; // [🧠] Or some other icon for VOID
|
|
8754
|
+
}
|
|
8755
|
+
capabilities.push({
|
|
8756
|
+
type: 'inheritance',
|
|
8757
|
+
label,
|
|
8758
|
+
iconName,
|
|
8759
|
+
agentUrl: content,
|
|
8760
|
+
});
|
|
8761
|
+
continue;
|
|
8762
|
+
}
|
|
8763
|
+
if (commitment.type === 'IMPORT') {
|
|
8764
|
+
const content = spaceTrim$2(commitment.content).split('\n')[0] || '';
|
|
8765
|
+
let label = content;
|
|
8766
|
+
let iconName = 'ExternalLink'; // Import remote
|
|
8767
|
+
try {
|
|
8768
|
+
if (content.startsWith('http://') || content.startsWith('https://')) {
|
|
8769
|
+
const url = new URL(content);
|
|
8770
|
+
label = url.hostname.replace(/^www\./, '') + '.../' + url.pathname.split('/').pop();
|
|
8771
|
+
iconName = 'ExternalLink';
|
|
8772
|
+
}
|
|
8773
|
+
else if (content.startsWith('./') || content.startsWith('../') || content.startsWith('/')) {
|
|
8774
|
+
label = content.split('/').pop() || content;
|
|
8775
|
+
iconName = 'Link'; // Import local
|
|
8776
|
+
}
|
|
8777
|
+
}
|
|
8778
|
+
catch (e) {
|
|
8779
|
+
// Invalid URL or path, keep default label
|
|
8780
|
+
}
|
|
8781
|
+
capabilities.push({
|
|
8782
|
+
type: 'import',
|
|
8783
|
+
label,
|
|
8784
|
+
iconName,
|
|
8785
|
+
agentUrl: content,
|
|
8786
|
+
});
|
|
8787
|
+
continue;
|
|
8788
|
+
}
|
|
7446
8789
|
if (commitment.type === 'KNOWLEDGE') {
|
|
7447
8790
|
const content = spaceTrim$2(commitment.content).split('\n')[0] || '';
|
|
7448
8791
|
let label = content;
|
|
@@ -7527,6 +8870,7 @@ function parseAgentSource(agentSource) {
|
|
|
7527
8870
|
links,
|
|
7528
8871
|
parameters,
|
|
7529
8872
|
capabilities,
|
|
8873
|
+
samples,
|
|
7530
8874
|
};
|
|
7531
8875
|
}
|
|
7532
8876
|
/**
|
|
@@ -8596,13 +9940,17 @@ function BookEditorMonaco(props) {
|
|
|
8596
9940
|
// Register a new language
|
|
8597
9941
|
monaco.languages.register({ id: BOOK_LANGUAGE_ID });
|
|
8598
9942
|
const commitmentTypes = [...new Set(getAllCommitmentDefinitions().map(({ type }) => type))];
|
|
8599
|
-
const commitmentRegex = new RegExp(
|
|
9943
|
+
const commitmentRegex = new RegExp(`^\\s*(${commitmentTypes
|
|
9944
|
+
.sort((a, b) => b.length - a.length) // [1] Prefer longer commitments to avoid partial matching (e.g. LANGUAGES vs LANGUAGE)
|
|
9945
|
+
.map((type) => (type === 'META' ? 'META\\s+\\w+' : type.replace(/\s+/, '\\s+')))
|
|
9946
|
+
.join('|')})(?=\\s|$)`);
|
|
8600
9947
|
// Note: Using a broad character set for Latin and Cyrillic to support international characters in parameters.
|
|
8601
9948
|
// Monarch tokenizer does not support Unicode property escapes like \p{L}.
|
|
8602
9949
|
const parameterRegex = /@([a-zA-Z0-9_á-žÁ-Žč-řČ-Řš-žŠ-Žа-яА-ЯёЁ]+)/;
|
|
8603
9950
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8604
9951
|
const bookRules = [
|
|
8605
9952
|
[/^---[-]*$/, ''],
|
|
9953
|
+
[/^```.*$/, 'code-block', '@codeblock'],
|
|
8606
9954
|
[parameterRegex, 'parameter'],
|
|
8607
9955
|
[/\{[^}]+\}/, 'parameter'],
|
|
8608
9956
|
[commitmentRegex, 'commitment'],
|
|
@@ -8614,10 +9962,15 @@ function BookEditorMonaco(props) {
|
|
|
8614
9962
|
root: [
|
|
8615
9963
|
[/^\s*$/, 'empty'],
|
|
8616
9964
|
[/^-*$/, 'line'],
|
|
9965
|
+
[/^```.*$/, 'code-block', '@codeblock'],
|
|
8617
9966
|
[/^.*$/, 'title', '@body'],
|
|
8618
9967
|
[commitmentRegex, 'commitment'],
|
|
8619
9968
|
],
|
|
8620
9969
|
body: bookRules,
|
|
9970
|
+
codeblock: [
|
|
9971
|
+
[/^```.*$/, 'code-block', '@pop'],
|
|
9972
|
+
[/^.*$/, 'code-block'],
|
|
9973
|
+
],
|
|
8621
9974
|
},
|
|
8622
9975
|
});
|
|
8623
9976
|
// Register a completion item provider for the language
|
|
@@ -8659,6 +10012,10 @@ function BookEditorMonaco(props) {
|
|
|
8659
10012
|
foreground: PROMPTBOOK_SYNTAX_COLORS.PARAMETER.toHex(),
|
|
8660
10013
|
fontStyle: `italic`,
|
|
8661
10014
|
},
|
|
10015
|
+
{
|
|
10016
|
+
token: 'code-block',
|
|
10017
|
+
foreground: PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex(),
|
|
10018
|
+
},
|
|
8662
10019
|
],
|
|
8663
10020
|
colors: {
|
|
8664
10021
|
'editor.scrollbarSlider.background': '#E0E0E0',
|
|
@@ -8715,12 +10072,35 @@ function BookEditorMonaco(props) {
|
|
|
8715
10072
|
.${instanceClass} .monaco-editor .transparent-text {
|
|
8716
10073
|
color: transparent !important;
|
|
8717
10074
|
}
|
|
10075
|
+
|
|
10076
|
+
.${instanceClass} .monaco-editor .code-block-box {
|
|
10077
|
+
background-color: #f5f5f566;
|
|
10078
|
+
border-left: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
|
|
10079
|
+
border-right: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
|
|
10080
|
+
padding-left: ${Math.round(8 * zoomLevel)}px;
|
|
10081
|
+
padding-right: ${Math.round(8 * zoomLevel)}px;
|
|
10082
|
+
}
|
|
10083
|
+
|
|
10084
|
+
.${instanceClass} .monaco-editor .code-block-top {
|
|
10085
|
+
border-top: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
|
|
10086
|
+
border-top-left-radius: ${Math.round(10 * zoomLevel)}px;
|
|
10087
|
+
border-top-right-radius: ${Math.round(10 * zoomLevel)}px;
|
|
10088
|
+
overflow: hidden;
|
|
10089
|
+
}
|
|
10090
|
+
|
|
10091
|
+
.${instanceClass} .monaco-editor .code-block-bottom {
|
|
10092
|
+
border-bottom: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
|
|
10093
|
+
border-bottom-left-radius: ${Math.round(10 * zoomLevel)}px;
|
|
10094
|
+
border-bottom-right-radius: ${Math.round(10 * zoomLevel)}px;
|
|
10095
|
+
overflow: hidden;
|
|
10096
|
+
}
|
|
8718
10097
|
`;
|
|
8719
10098
|
return () => {
|
|
8720
10099
|
// Note: Style is not removed on purpose to avoid flickering during development with fast refresh
|
|
8721
10100
|
};
|
|
8722
10101
|
}, [scaledLineHeight, scaledContentPaddingLeft, scaledVerticalLineLeft]);
|
|
8723
10102
|
const decorationIdsRef = useRef([]);
|
|
10103
|
+
const codeBlockDecorationIdsRef = useRef([]);
|
|
8724
10104
|
useEffect(() => {
|
|
8725
10105
|
if (!editor || !monaco) {
|
|
8726
10106
|
return;
|
|
@@ -8749,6 +10129,39 @@ function BookEditorMonaco(props) {
|
|
|
8749
10129
|
});
|
|
8750
10130
|
}
|
|
8751
10131
|
decorationIdsRef.current = editor.deltaDecorations(decorationIdsRef.current, newDecorations);
|
|
10132
|
+
// Add decorations for code blocks
|
|
10133
|
+
const lines = text.split('\n');
|
|
10134
|
+
const codeBlockDecorations = [];
|
|
10135
|
+
let inCodeBlock = false;
|
|
10136
|
+
let codeBlockStartLine = 0;
|
|
10137
|
+
for (let i = 0; i < lines.length; i++) {
|
|
10138
|
+
const line = lines[i];
|
|
10139
|
+
if (line === null || line === void 0 ? void 0 : line.trim().startsWith('```')) {
|
|
10140
|
+
if (!inCodeBlock) {
|
|
10141
|
+
// Starting a code block
|
|
10142
|
+
inCodeBlock = true;
|
|
10143
|
+
codeBlockStartLine = i + 1; // 1-based line number
|
|
10144
|
+
}
|
|
10145
|
+
else {
|
|
10146
|
+
// Ending a code block
|
|
10147
|
+
inCodeBlock = false;
|
|
10148
|
+
const endLine = i + 1; // 1-based line number
|
|
10149
|
+
// Add decorations for each line in the code block
|
|
10150
|
+
for (let j = codeBlockStartLine; j <= endLine; j++) {
|
|
10151
|
+
const isFirst = j === codeBlockStartLine;
|
|
10152
|
+
const isLast = j === endLine;
|
|
10153
|
+
codeBlockDecorations.push({
|
|
10154
|
+
range: new monaco.Range(j, 1, j, 1),
|
|
10155
|
+
options: {
|
|
10156
|
+
isWholeLine: true,
|
|
10157
|
+
className: `code-block-box${isFirst ? ' code-block-top' : ''}${isLast ? ' code-block-bottom' : ''}`,
|
|
10158
|
+
},
|
|
10159
|
+
});
|
|
10160
|
+
}
|
|
10161
|
+
}
|
|
10162
|
+
}
|
|
10163
|
+
}
|
|
10164
|
+
codeBlockDecorationIdsRef.current = editor.deltaDecorations(codeBlockDecorationIdsRef.current, codeBlockDecorations);
|
|
8752
10165
|
};
|
|
8753
10166
|
updateDecorations();
|
|
8754
10167
|
const changeListener = editor.onDidChangeModelContent(() => {
|
|
@@ -9762,8 +11175,8 @@ function getChatSaveFormatDefinitions(formatNames) {
|
|
|
9762
11175
|
return CHAT_SAVE_FORMATS.filter((saveFormatDefinition) => formatNames.includes(saveFormatDefinition.formatName));
|
|
9763
11176
|
}
|
|
9764
11177
|
|
|
9765
|
-
var css_248z$2 = "@font-face{font-family:OpenMojiBlack;src:url(https://s6.ptbk.io/fonts/OpenMoji-black-glyf.woff2) format(\"woff2\");unicode-range:u+23,u+2a,u+2d,u+30-39,u+a9,u+ae,u+200d,u+203c,u+2049,u+20e3,u+2117,u+2120,u+2122,u+2139,u+2194-2199,u+21a9,u+21aa,u+229c,u+231a,u+231b,u+2328,u+23cf,u+23e9-23f3,u+23f8-23fe,u+24c2,u+25a1,u+25aa-25ae,u+25b6,u+25c0,u+25c9,u+25d0,u+25d1,u+25e7-25ea,u+25ed,u+25ee,u+25fb-25fe,u+2600-2605,u+260e,u+2611,u+2614,u+2615,u+2618,u+261d,u+2620,u+2622,u+2623,u+2626,u+262a,u+262e,u+262f,u+2638-263a,u+2640,u+2642,u+2648-2653,u+265f,u+2660,u+2663,u+2665,u+2666,u+2668,u+267b,u+267e,u+267f,u+2691-2697,u+2699,u+269b,u+269c,u+26a0,u+26a1,u+26a7,u+26aa,u+26ab,u+26b0,u+26b1,u+26bd,u+26be,u+26c4,u+26c5,u+26c8,u+26ce,u+26cf,u+26d1,u+26d3,u+26d4,u+26e9,u+26ea,u+26f0-26f5,u+26f7-26fa,u+26fd,u+2702,u+2705,u+2708-270d,u+270f,u+2712,u+2714,u+2716,u+271d,u+2721,u+2728,u+2733,u+2734,u+2744,u+2747,u+274c,u+274e,u+2753-2755,u+2757,u+2763,u+2764,u+2795-2797,u+27a1,u+27b0,u+27bf,u+2934,u+2935,u+2b05-2b07,u+2b0c,u+2b0d,u+2b1b,u+2b1c,u+2b1f-2b24,u+2b2e,u+2b2f,u+2b50,u+2b55,u+2b58,u+2b8f,u+2bba-2bbc,u+2bc3,u+2bc4,u+2bea,u+2beb,u+3030,u+303d,u+3297,u+3299,u+e000-e009,u+e010,u+e011,u+e040-e06d,u+e080-e0b4,u+e0c0-e0cc,u+e0ff-e10d,u+e140-e14a,u+e150-e157,u+e181-e189,u+e1c0-e1c4,u+e1c6-e1d9,u+e200-e216,u+e240-e269,u+e280-e283,u+e2c0-e2c4,u+e2c6-e2da,u+e300-e303,u+e305-e30f,u+e312-e316,u+e318-e322,u+e324-e329,u+e32b,u+e340-e348,u+e380,u+e381,u+f000,u+f77a,u+f8ff,u+fe0f,u+1f004,u+1f0cf,u+1f10d-1f10f,u+1f12f,u+1f16d-1f171,u+1f17e,u+1f17f,u+1f18e,u+1f191-1f19a,u+1f1e6-1f1ff,u+1f201,u+1f202,u+1f21a,u+1f22f,u+1f232-1f23a,u+1f250,u+1f251,u+1f260-1f265,u+1f300-1f321,u+1f324-1f393,u+1f396,u+1f397,u+1f399-1f39b,u+1f39e-1f3f0,u+1f3f3-1f3f5,u+1f3f7-1f4fd,u+1f4ff-1f53d,u+1f549-1f54e,u+1f550-1f567,u+1f56f,u+1f570,u+1f573-1f57a,u+1f587,u+1f58a-1f58d,u+1f590,u+1f595,u+1f596,u+1f5a4,u+1f5a5,u+1f5a8,u+1f5b1,u+1f5b2,u+1f5bc,u+1f5c2-1f5c4,u+1f5d1-1f5d3,u+1f5dc-1f5de,u+1f5e1,u+1f5e3,u+1f5e8,u+1f5ef,u+1f5f3,u+1f5fa-1f64f,u+1f680-1f6c5,u+1f6cb-1f6d2,u+1f6d5-1f6d7,u+1f6dc-1f6e5,u+1f6e9,u+1f6eb,u+1f6ec,u+1f6f0,u+1f6f3-1f6fc,u+1f7e0-1f7eb,u+1f7f0,u+1f90c-1f93a,u+1f93c-1f945,u+1f947-1f9ff,u+1fa70-1fa7c,u+1fa80-1fa88,u+1fa90-1fabd,u+1fabf-1fac5,u+1face-1fadb,u+1fae0-1fae8,u+1faf0-1faf8,u+1fbc5-1fbc9,u+e0061-e0067,u+e0069,u+e006c-e0079,u+e007f}.Chat-module_copiedToClipboardMessage__apCPY{background:#222;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,.18);color:#fff;font-size:1.1em;left:50%;opacity:.97;padding:10px 24px;pointer-events:none;position:fixed;top:32px;transform:translateX(-50%);z-index:9999}.Chat-module_Chat__j2eE5{display:flex;flex-direction:column;font-family:Arial,Helvetica,sans-serif,OpenMojiBlack;height:100%;width:100%}.Chat-module_chatMainFlow__--8FE{display:grid;grid-template:\"🟦\" min-content \"💬\" 1fr \"📝\" min-content/1fr;height:100%;max-width:100vw;width:100%}.Chat-module_chatMainFlow__--8FE .Chat-module_chatBar__fLECN{background-color:#fff;border-bottom:1px solid rgba(15,23,36,.06);color:#0f1724;font-weight:500;grid-area:🟦;padding:16px 20px;text-align:center;width:100%}.Chat-module_TasksInProgress__fQfei{align-self:center;grid-area:🟦;height:min-content;justify-self:self-end;margin:8px 16px;width:auto}.Chat-module_actions__gTZ5T{align-items:center;align-self:self-start;display:flex;gap:8px;grid-area:💬;height:min-content;justify-self:self-end;margin:16px 20px 0;width:auto;z-index:200}.Chat-module_actions__gTZ5T.Chat-module_portal__uTOT8{margin:0}.Chat-module_actions__gTZ5T.Chat-module_left__7l5Mn{justify-self:self-start}.Chat-module_actions__gTZ5T.Chat-module_right__ABZrW{justify-self:self-end}@media (max-width:900px){.Chat-module_chatButton__d9VgA{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_chatButton__d9VgA svg{height:18px!important;width:18px!important}.Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_useTemplateButton__xcJNR{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_useTemplateButton__xcJNR svg{height:18px!important;width:18px!important}.Chat-module_useTemplateButton__xcJNR .Chat-module_chatButtonText__RkGB-{display:none!important}}@media (max-width:600px){.Chat-module_actions__gTZ5T{gap:7px;margin:14px 18px 0}}.Chat-module_chatMainFlow__--8FE .Chat-module_chatChildren__flOPK{grid-area:💬;height:100%;width:100%;z-index:300}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N{grid-area:💬;height:100%;overflow-x:hidden;overflow-y:auto;padding:24px 20px 16px;scroll-behavior:smooth;width:100%;z-index:10}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar{width:6px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar-track{background:transparent}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar-thumb{background:hsla(0,0%,49%,.2);border-radius:3px;transition:all .2s ease}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar-thumb:hover{background:hsla(0,0%,49%,.3)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ{align-items:flex-end;animation:Chat-module_messageSlideIn__soTy2 .4s cubic-bezier(.25,.46,.45,.94);display:flex;flex-direction:row;margin-bottom:20px;max-width:100%;position:relative}.Chat-module_hasActionsAndFirstMessageIsLong__5jgoZ{margin-top:55px}@keyframes Chat-module_messageSlideIn__soTy2{0%{opacity:0;transform:translateY(20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.Chat-module_isNotCompleteMessage__Hj2K7{opacity:.7;position:relative}.Chat-module_NonCompleteMessageFiller__G5-Ve{color:transparent}.Chat-module_isNotCompleteMessage__Hj2K7 .Chat-module_messageText__XgNyQ:after{animation:Chat-module_loadingPulse__VomRm 1.5s ease-in-out infinite;background:linear-gradient(90deg,transparent,hsla(0,0%,49%,.6),transparent);border-radius:2px;bottom:8px;content:\"\";height:4px;position:absolute;right:12px;width:20px}@keyframes Chat-module_loadingPulse__VomRm{0%,to{opacity:.3;transform:scaleX(.8)}50%{opacity:1;transform:scaleX(1.2)}}.Chat-module_typingIndicator__S-CT-{align-items:flex-end;animation:Chat-module_messageSlideIn__soTy2 .4s cubic-bezier(.25,.46,.45,.94);display:flex;margin-bottom:20px}.Chat-module_typingIndicator__S-CT- .Chat-module_avatar__gL6bm{flex-shrink:0;height:40px;margin:0 12px 4px;width:40px}.Chat-module_typingBubble__0Lb7B{backdrop-filter:blur(10px);border:1px solid hsla(0,0%,49%,.1);border-radius:20px;border-bottom-left-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,.1);min-height:24px;padding:16px 20px}.Chat-module_typingBubble__0Lb7B,.Chat-module_typingDots__srOBB{align-items:center;display:flex;gap:4px}.Chat-module_typingDot__dnhKT{animation:Chat-module_typingBounce__1yp2v 1.4s ease-in-out infinite;background:linear-gradient(135deg,#6b7280,hsla(0,0%,49%,.6));border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);height:8px;width:8px}.Chat-module_typingDot__dnhKT:first-child{animation-delay:-.32s}.Chat-module_typingDot__dnhKT:nth-child(2){animation-delay:-.16s}.Chat-module_typingDot__dnhKT:nth-child(3){animation-delay:0s}@keyframes Chat-module_typingBounce__1yp2v{0%,80%,to{opacity:.5;transform:scale(.8) translateY(0)}40%{opacity:1;transform:scale(1.2) translateY(-8px)}}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ.Chat-module_isMe__nBtaV{align-items:flex-end;flex-direction:row-reverse;justify-content:flex-start}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ.Chat-module_isMe__nBtaV .Chat-module_messageText__XgNyQ{border-bottom-right-radius:6px}.Chat-module_ratingStar__rRfqC{color:var(--star-inactive-color,#ccc);cursor:pointer;font-size:20px;transition:color .2s}.Chat-module_ratingStar__rRfqC.Chat-module_active__lbYL-{color:gold}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_avatar__gL6bm{aspect-ratio:1/1;flex-shrink:0;margin:0 12px 4px;position:relative;width:40px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{word-wrap:break-word;backdrop-filter:blur(10px);background-color:var(--message-bg-color);border-radius:20px;box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--message-text-color);font-size:15px;line-height:1.5;margin-bottom:4px;max-width:min(70%,600px);padding:14px 18px;position:relative;text-align:left;transition:all .2s ease}.Chat-module_copyButtonContainer__Rij0U{align-items:center;float:right;justify-content:flex-end;pointer-events:none;right:10px;top:8px;visibility:hidden;z-index:2}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ:hover .Chat-module_copyButtonContainer__Rij0U,.Chat-module_copyButtonContainer__Rij0U:focus-within{pointer-events:auto;visibility:visible}.Chat-module_copyButton__DcxT5{align-items:center;background:hsla(0,0%,100%,.2);border:1px solid #ddd;border-radius:6px;box-shadow:0 1px 4px rgba(0,0,0,.07);cursor:pointer;display:flex;opacity:.7;padding:2px 5px;position:relative;transition:all .15s,box-shadow .15s,border .15s}.Chat-module_copiedTooltip__LH81j{animation:Chat-module_copiedTooltipFadeIn__QekO1 .2s;background:#222;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,.18);color:#fff;font-size:.98em;left:50%;margin-top:4px;max-width:220px;opacity:.97;overflow-wrap:break-word;padding:6px 16px;pointer-events:none;position:absolute;top:110%;transform:translateX(-50%);white-space:nowrap;word-break:break-word;z-index:100}.Chat-module_copiedTooltipLeft__j-S-5{left:0!important;transform:none!important}.Chat-module_copiedTooltipRight__R-2cE{left:auto!important;right:0!important;transform:none!important}@keyframes Chat-module_copiedTooltipFadeIn__QekO1{0%{opacity:0;transform:translateX(-50%) translateY(8px) scale(.97)}to{opacity:.97;transform:translateX(-50%) translateY(0) scale(1)}}.Chat-module_copyButton__DcxT5:focus,.Chat-module_copyButton__DcxT5:hover{border:1.5px solid #bbb;box-shadow:0 2px 8px rgba(0,132,255,.1);opacity:1}.Chat-module_copyButton__DcxT5 svg{display:block}.Chat-module_messageText__XgNyQ h1{font-size:2em}.Chat-module_messageText__XgNyQ h2{font-size:1.75em}.Chat-module_messageText__XgNyQ h3{font-size:1.5em}.Chat-module_messageText__XgNyQ h4{font-size:1.25em}.Chat-module_messageText__XgNyQ h5{font-size:1.1em}.Chat-module_messageText__XgNyQ ul{list-style:disc;margin-left:20px}.Chat-module_messageText__XgNyQ ol{list-style:decimal;margin-left:20px}.Chat-module_messageText__XgNyQ blockquote,.Chat-module_messageText__XgNyQ img,.Chat-module_messageText__XgNyQ pre,.Chat-module_messageText__XgNyQ table{border-radius:8px;margin-bottom:10px;margin-top:10px}.Chat-module_messageText__XgNyQ pre{background:#000;color:#fff}.Chat-module_messageText__XgNyQ blockquote,.Chat-module_messageText__XgNyQ pre{border:none;box-shadow:none;display:block;font-size:inherit;line-height:inherit;padding:1em}.Chat-module_messageText__XgNyQ blockquote{background:#ffffffcc;color:#000}.Chat-module_messageText__XgNyQ code{background:#cccccc55;border:none;box-shadow:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;margin:0;padding:0}.Chat-module_messageText__XgNyQ pre code{background-color:#000000cc;border-radius:8px}.Chat-module_messageText__XgNyQ .Chat-module_chat-code-block__k8IyS{background:#181c23;border-color:#23272f;box-shadow:0 2px 8px rgba(0,0,0,.12);color:#f8fafc;font-family:Fira Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:14px;line-height:1.6;overflow-x:auto}.Chat-module_messageText__XgNyQ .Chat-module_chat-code-block__k8IyS code{background:none!important;border:none!important;box-shadow:none!important;color:inherit!important;display:block;font-family:inherit!important;font-size:inherit!important;overflow-x:auto;padding:0!important;white-space:pre;word-break:break-word}.Chat-module_messageText__XgNyQ table{background:#f8fafc;border-collapse:separate;border-spacing:0;box-shadow:0 2px 8px rgba(0,0,0,.08);color:#17223b;font-size:14px;margin:16px 0;width:100%}.Chat-module_messageText__XgNyQ td,.Chat-module_messageText__XgNyQ th{background:none;border-bottom:1px solid #d1dbe8;color:#17223b;padding:10px 16px;text-align:left}.Chat-module_messageText__XgNyQ th{background:linear-gradient(90deg,#eaf3fa 80%,#d1e3f8);border-bottom:2px solid #b5c7de;color:#17223b;font-weight:700}.Chat-module_messageText__XgNyQ tr:last-child td{border-bottom:none}.Chat-module_messageText__XgNyQ tr:nth-child(2n) td{background:#eaf3fa}.Chat-module_messageText__XgNyQ tr:hover td{background:#cbe0f7;transition:background .2s}.Chat-module_messageText__XgNyQ table{border-radius:12px;overflow:hidden}.Chat-module_messageText__XgNyQ td:first-child,.Chat-module_messageText__XgNyQ th:first-child{border-top-left-radius:12px}.Chat-module_messageText__XgNyQ td:last-child,.Chat-module_messageText__XgNyQ th:last-child{border-top-right-radius:12px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ:hover{box-shadow:0 4px 16px rgba(0,0,0,.15);transform:translateY(-1px)}.Chat-module_attachments__m1Fts{border-top:1px solid hsla(0,0%,49%,.2);display:flex;flex-wrap:wrap;gap:8px;margin-top:10px;padding-top:10px}.Chat-module_attachment__aE9hK{align-items:center;background:hsla(0,0%,100%,.2);border:1px solid hsla(0,0%,49%,.3);border-radius:12px;color:inherit;display:flex;font-size:13px;gap:6px;max-width:200px;padding:6px 12px;text-decoration:none;transition:all .2s ease}.Chat-module_attachment__aE9hK:hover{background:hsla(0,0%,100%,.3);border-color:hsla(0,0%,49%,.5);transform:translateY(-1px)}.Chat-module_attachmentIcon__BX3Cy{font-size:14px;opacity:.8}.Chat-module_attachmentName__aMx56{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Chat-module_messageButtons__WaOob{border-top:1px solid hsla(0,0%,49%,.83);display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;padding-top:12px}.Chat-module_messageButton__mRnn-{-webkit-tap-highlight-color:transparent;align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,49%,.1);border:1px solid hsla(0,0%,49%,.9);border-radius:16px;cursor:pointer;display:inline-flex;font-size:13px;font-weight:500;padding:8px 14px;touch-action:manipulation;transition:all .2s ease;user-select:none}.Chat-module_messageButton__mRnn-:hover{background:rgba(0,132,255,.1);border-color:rgba(0,132,255,.3);box-shadow:0 2px 8px rgba(0,132,255,.15);transform:translateY(-1px)}.Chat-module_messageButton__mRnn-:active{transform:scale(.98);transition:transform .1s ease}.Chat-module_messageButton__mRnn- p{line-height:inherit;margin:0;padding:0}.Chat-module_messageButton__mRnn- strong{font-weight:600}.Chat-module_messageButton__mRnn- em{font-style:italic}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M{align-items:center;backdrop-filter:blur(10px);background:rgba(0,0,0,.8);border-radius:12px;bottom:-8px;display:flex;gap:2px;min-width:24px;opacity:0;padding:4px 6px;position:absolute;right:8px;transform:translateY(4px);transition:all .3s cubic-bezier(.25,.46,.45,.94);z-index:1}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ:hover .Chat-module_rating__soc3M{opacity:1;transform:translateY(0)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M:hover{background:rgba(0,0,0,.9);box-shadow:0 4px 12px rgba(0,0,0,.3);padding:6px 8px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M span{cursor:pointer;display:inline-block;font-size:16px;transition:transform .2s ease,color .2s ease}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M:hover span{transform:scale(1.1)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan{backdrop-filter:blur(20px);border-top:1px solid hsla(0,0%,49%,.1);display:flex;flex-direction:column;gap:12px;grid-area:📝;padding:20px;position:relative;width:100%;z-index:10}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan.Chat-module_dragOver__bkS-g{background:linear-gradient(0deg,rgba(0,132,255,.1) 0,rgba(0,132,255,.05));border-top:2px solid rgba(0,132,255,.3)}.Chat-module_filePreviewContainer__R70hm{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.Chat-module_filePreview__kq2aX{align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,49%,.1);border:1px solid hsla(0,0%,49%,.2);border-radius:8px;display:flex;font-size:12px;gap:8px;padding:8px 12px;transition:all .2s ease}.Chat-module_filePreview__kq2aX:hover{background:hsla(0,0%,49%,.15);border-color:hsla(0,0%,49%,.3)}.Chat-module_fileIcon__zoSKW{font-size:14px;opacity:.7}.Chat-module_fileInfo__wBLi0{display:flex;flex-direction:column;gap:2px;min-width:0}.Chat-module_fileName__bBujo{color:#000;font-weight:500;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Chat-module_fileSize__ivliq{color:#6b7280;font-size:11px}.Chat-module_removeFileButton__0gakR{align-items:center;background:rgba(255,0,0,.1);border:none;border-radius:50%;color:#f44;cursor:pointer;display:flex;flex-shrink:0;height:20px;justify-content:center;transition:all .2s ease;width:20px}.Chat-module_removeFileButton__0gakR:hover{background:rgba(255,0,0,.2);transform:scale(1.1)}.Chat-module_inputContainer__bPt99{align-items:center;display:flex;gap:12px}.Chat-module_inputContainer__bPt99 textarea::placeholder{color:inherit;opacity:.7}.Chat-module_attachmentButton__qLO47{align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,49%,.05);border:1px solid hsla(0,0%,49%,.2);border-radius:50%;color:#6b7280;cursor:pointer;display:flex;flex-shrink:0;height:40px;justify-content:center;transition:all .2s ease;width:40px}.Chat-module_attachmentButton__qLO47:hover:not(:disabled){background:rgba(0,132,255,.1);border-color:rgba(0,132,255,.3);color:#0084ff;transform:scale(1.05)}.Chat-module_attachmentButton__qLO47:disabled{cursor:not-allowed;opacity:.5;transform:none}.Chat-module_voiceButton__d2zlP{align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,49%,.05);border:1px solid hsla(0,0%,49%,.2);border-radius:50%;color:#6b7280;cursor:pointer;display:flex;flex-shrink:0;height:40px;justify-content:center;transition:all .2s ease;width:40px}.Chat-module_voiceButton__d2zlP:hover{background:rgba(0,132,255,.1);border-color:rgba(0,132,255,.3);color:#0084ff;transform:scale(1.05)}.Chat-module_voiceButtonActive__Uoi3W{animation:Chat-module_voiceRecordingPulse__y2wJ5 1.5s infinite;background:rgba(255,0,0,.1)!important;border-color:rgba(255,0,0,.3)!important;color:red!important}@keyframes Chat-module_voiceRecordingPulse__y2wJ5{0%{box-shadow:0 0 0 0 rgba(255,0,0,.4)}70%{box-shadow:0 0 0 10px rgba(255,0,0,0)}to{box-shadow:0 0 0 0 rgba(255,0,0,0)}}.Chat-module_uploadProgress__jBTKe{align-items:center;background:rgba(0,132,255,.1);border:1px solid rgba(0,132,255,.2);border-radius:8px;color:#0084ff;display:flex;font-size:13px;gap:12px;padding:8px 12px}.Chat-module_uploadProgressBar__Gutnt{background:rgba(0,132,255,.2);border-radius:2px;flex:1;height:4px;overflow:hidden}.Chat-module_uploadProgressFill__EgubT{animation:Chat-module_uploadProgress__jBTKe 1.5s ease-in-out infinite;background:linear-gradient(90deg,#0084ff,rgba(0,132,255,.8));border-radius:2px;height:100%}@keyframes Chat-module_uploadProgress__jBTKe{0%{transform:translateX(-100%)}50%{transform:translateX(0)}to{transform:translateX(100%)}}.Chat-module_dragOverlay__SEGoS{align-items:center;backdrop-filter:blur(10px);background:rgba(0,132,255,.1);border:2px dashed rgba(0,132,255,.5);border-radius:12px;bottom:0;display:flex;justify-content:center;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:20}.Chat-module_dragOverlayContent__gb9kF{align-items:center;color:#0084ff;display:flex;flex-direction:column;font-weight:600;gap:12px;text-align:center}.Chat-module_dragOverlayContent__gb9kF svg{opacity:.7}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{-webkit-tap-highlight-color:transparent;appearance:none;-webkit-appearance:none;backdrop-filter:blur(20px);background:hsla(0,0%,49%,.05);border-radius:25px;color:#000;flex:1;font-size:15px;line-height:1.4;max-height:120px;min-width:200px;outline:none;padding:16px 20px;resize:none;touch-action:manipulation;transition:all .3s cubic-bezier(.25,.46,.45,.94)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea:focus{background:hsla(0,0%,49%,.08);border-color:#0084ff;box-shadow:0 0 0 4px rgba(0,132,255,.1),0 8px 32px rgba(0,132,255,.15);transform:translateY(-2px)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea:disabled{cursor:not-allowed;opacity:.6;transform:none}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea::placeholder{color:inherit;opacity:.7}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button{-webkit-tap-highlight-color:transparent;align-items:center;aspect-ratio:1/1;border:none;border-radius:50%!important;box-shadow:0 4px 16px rgba(0,132,255,.3);color:#fff;display:flex;height:48px;justify-content:center;margin:0!important;min-height:unset!important;min-width:unset!important;overflow:visible;padding:0!important;padding-left:unset;padding-right:unset;touch-action:manipulation;transition:all .3s cubic-bezier(.25,.46,.45,.94);user-select:none;width:48px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button img{height:100%;object-fit:contain;width:50%}.Chat-module_scrollToBottomContainer__5rXpK{align-items:flex-start;display:flex;grid-area:📝;height:100%;justify-content:center;pointer-events:none;width:100%;z-index:20}.Chat-module_scrollToBottomContainer__5rXpK .Chat-module_scrollToBottom__nzxdZ{-webkit-tap-highlight-color:transparent;align-items:center;animation:Chat-module_scrollButtonSlideIn__XnImg .3s ease-out;backdrop-filter:blur(3px);background:rgba(0,0,0,.5);border:none;border-radius:50%;box-shadow:0 4px 16px rgba(0,0,0,.3);color:#fff;cursor:pointer;display:flex;font-weight:700;height:48px;justify-content:center;outline:none;pointer-events:all;touch-action:manipulation;transform:translate(-50%,-150%);transition:all .3s cubic-bezier(.25,.46,.45,.94);user-select:none;width:48px}@keyframes Chat-module_scrollButtonSlideIn__XnImg{0%{opacity:0;transform:translate(-50%,20px) scale(.8)}to{opacity:.9;transform:translate(-50%) scale(1)}}.Chat-module_scrollToBottom__nzxdZ:hover{transform:translate(-50%,-160%) scale(1.05)}.Chat-module_scrollToBottom__nzxdZ:active{transform:translate(-50%,-160%) scale(.95);transition:transform .1s ease}.Chat-module_ratingModal__XVKYm{align-items:center;animation:Chat-module_modalFadeIn__RPc3w .3s ease-out;backdrop-filter:blur(8px);background-color:rgba(0,0,0,.6);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}@keyframes Chat-module_modalFadeIn__RPc3w{0%{backdrop-filter:blur(0);opacity:0}to{backdrop-filter:blur(8px);opacity:1}}.Chat-module_ratingModalContent__CCdq7{animation:Chat-module_modalSlideIn__XXtgN .3s cubic-bezier(.25,.46,.45,.94);backdrop-filter:blur(20px);background:#fff;border:1px solid hsla(0,0%,49%,.1);border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.3);color:#0f1724;font-family:Arial,Helvetica,sans-serif,OpenMojiBlack;max-width:480px;padding:32px;width:90%}@keyframes Chat-module_modalSlideIn__XXtgN{0%{opacity:0;transform:translateY(20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.Chat-module_ratingModalContent__CCdq7 h3{color:#000;font-size:20px;font-weight:600;margin:0 0 24px;text-align:center}.Chat-module_stars__PCzNO{display:flex;gap:8px;justify-content:center;margin-bottom:24px}.Chat-module_stars__PCzNO span{border-radius:8px;cursor:pointer;font-size:28px;padding:4px;transition:all .2s ease}.Chat-module_stars__PCzNO span:hover{background:rgba(255,215,0,.1);transform:scale(1.2)}.Chat-module_ratingModalStar__XkbHr{cursor:pointer;font-size:24px;transition:color .2s}.Chat-module_ratingInput__z8Pv-{background:hsla(0,0%,49%,.05);border:2px solid hsla(0,0%,49%,.1);border-radius:12px;color:#0b1220;font-size:14px;line-height:1.5;margin-bottom:18px;min-height:100px;padding:16px;resize:vertical;transition:all .2s ease;width:100%}.Chat-module_ratingInput__z8Pv-:focus{background:hsla(0,0%,49%,.08);border-color:#0084ff;box-shadow:0 0 0 4px rgba(0,132,255,.1);outline:none}.Chat-module_ratingInput__z8Pv-[readonly]{background:hsla(0,0%,49%,.01);border:1px solid hsla(0,0%,49%,.5)}.Chat-module_ratingActions__nXcss{display:flex;gap:12px;justify-content:flex-end}.Chat-module_ratingActions__nXcss button{border:none;border-radius:8px;cursor:pointer;font-size:14px;font-weight:500;min-width:80px;padding:12px 24px;transition:all .2s ease}.Chat-module_ratingActions__nXcss button:first-child{background-color:hsla(0,0%,49%,.1);border:1px solid hsla(0,0%,49%,.2);color:#0b1220}.Chat-module_ratingActions__nXcss button:first-child:hover:not(:disabled){background-color:hsla(0,0%,49%,.2);color:#0b1220}.Chat-module_ratingActions__nXcss button:last-child{background:linear-gradient(135deg,#0084ff,#06c);color:#fff}.Chat-module_ratingActions__nXcss button:last-child:hover:not(:disabled){background:linear-gradient(135deg,#0071d1,#0052a3);box-shadow:0 4px 12px rgba(0,132,255,.3);transform:translateY(-1px)}.Chat-module_ratingActions__nXcss button:last-child:disabled{cursor:not-allowed;opacity:.5}.Chat-module_chatButton__d9VgA{-webkit-tap-highlight-color:transparent!important;align-items:center!important;backdrop-filter:blur(20px)!important;background:linear-gradient(135deg,#0084ff,#06c)!important;border:none!important;border-radius:20px!important;box-shadow:0 4px 16px rgba(0,132,255,.3)!important;color:#fff!important;cursor:pointer!important;display:inline-flex!important;font-size:13px!important;font-weight:600!important;gap:8px!important;justify-content:center!important;line-height:1.3!important;margin:0!important;min-height:40px!important;min-width:110px!important;overflow:hidden!important;padding:12px 16px!important;position:relative!important;touch-action:manipulation!important;transition:all .3s cubic-bezier(.25,.46,.45,.94)!important;user-select:none!important}.Chat-module_chatButton__d9VgA:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.2),transparent);content:\"\";height:100%;left:-100%;position:absolute;top:0;transition:left .5s ease;width:100%}.Chat-module_chatButton__d9VgA:hover:before{left:100%}.Chat-module_chatButton__d9VgA:hover:not(:disabled){background:linear-gradient(135deg,#09f,#07d);box-shadow:0 8px 24px rgba(0,132,255,.4);transform:translateY(-2px) scale(1.02)}.Chat-module_chatButton__d9VgA:active{box-shadow:0 4px 16px rgba(0,132,255,.3);transform:scale(.98) translateY(-1px);transition:transform .1s ease}.Chat-module_chatButton__d9VgA:focus{box-shadow:0 4px 16px rgba(0,132,255,.3),0 0 0 3px rgba(0,132,255,.3);outline:none}.Chat-module_chatButton__d9VgA svg{filter:drop-shadow(0 1px 2px rgba(0,0,0,.2));flex-shrink:0;height:16px;opacity:1;transition:all .3s cubic-bezier(.25,.46,.45,.94);width:16px}.Chat-module_chatButton__d9VgA:hover svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.3));transform:rotate(-90deg) scale(1.1)}.Chat-module_chatButtonText__RkGB-{font-weight:600;opacity:1;text-shadow:0 1px 2px rgba(0,0,0,.1);transition:all .2s ease;white-space:nowrap}.Chat-module_chatButton__d9VgA:hover .Chat-module_chatButtonText__RkGB-{transform:translateX(1px)}.Chat-module_useTemplateButton__xcJNR{-webkit-tap-highlight-color:transparent!important;align-items:center!important;backdrop-filter:blur(20px)!important;background:linear-gradient(135deg,#0084ff,#06c)!important;border:none!important;border-radius:20px!important;box-shadow:0 4px 16px rgba(0,132,255,.3)!important;color:#fff!important;cursor:pointer!important;display:inline-flex!important;font-size:13px!important;font-weight:600!important;gap:8px!important;justify-content:center!important;line-height:1.3!important;margin:0!important;min-height:40px!important;min-width:110px!important;overflow:hidden!important;padding:12px 16px!important;position:relative!important;touch-action:manipulation!important;transition:all .3s cubic-bezier(.25,.46,.45,.94)!important;user-select:none!important}.Chat-module_useTemplateButton__xcJNR:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.2),transparent);content:\"\";height:100%;left:-100%;position:absolute;top:0;transition:left .5s ease;width:100%}.Chat-module_useTemplateButton__xcJNR:hover:before{left:100%}.Chat-module_useTemplateButton__xcJNR:hover:not(:disabled){background:linear-gradient(135deg,#09f,#07d);box-shadow:0 8px 24px rgba(0,132,255,.4);transform:translateY(-2px) scale(1.02)}.Chat-module_useTemplateButton__xcJNR:active{box-shadow:0 4px 16px rgba(0,132,255,.3);transform:scale(.98) translateY(-1px);transition:transform .1s ease}.Chat-module_useTemplateButton__xcJNR:focus{box-shadow:0 4px 16px rgba(0,132,255,.3),0 0 0 3px rgba(0,132,255,.3);outline:none}.Chat-module_useTemplateButton__xcJNR svg{filter:drop-shadow(0 1px 2px rgba(0,0,0,.2));flex-shrink:0;height:16px;opacity:1;transition:all .3s cubic-bezier(.25,.46,.45,.94);width:16px}.Chat-module_useTemplateButton__xcJNR:hover svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.3));transform:scale(1.1)}.Chat-module_useTemplateButton__xcJNR:hover .Chat-module_chatButtonText__RkGB-{transform:translateX(1px)}.Chat-module_saveButtonContainer__lSNUJ{display:inline-block;position:relative}.Chat-module_saveMenu__-ph8y{background:#fff;border:1px solid #ddd;box-shadow:0 2px 8px rgba(0,0,0,.08);left:0;min-width:120px;position:absolute;top:100%;z-index:10}.Chat-module_saveMenuItem__ISApL{background:none;border:none;color:#111;cursor:pointer;display:block;padding:8px 16px;text-align:left;width:100%}.Chat-module_saveMenuItem__ISApL:hover{background-color:#f0f0f0}.Chat-module_pauseButton__eeu7K{background:linear-gradient(135deg,#ffb347,#ff8c42)!important}.Chat-module_pauseButton__eeu7K:hover:not(:disabled){background:linear-gradient(135deg,#ffc067,#ff9e5f)!important}.Chat-module_pauseButton__eeu7K.Chat-module_pausing__pTx8b{cursor:wait!important;opacity:.6!important}.Chat-module_pauseButton__eeu7K.Chat-module_paused__j-pya{background:linear-gradient(135deg,#10b981,#059669)!important}.Chat-module_pauseButton__eeu7K.Chat-module_paused__j-pya:hover:not(:disabled){background:linear-gradient(135deg,#34d399,#059669)!important;box-shadow:0 8px 24px rgba(16,185,129,.35);transform:translateY(-2px) scale(1.02)}.Chat-module_pauseButton__eeu7K svg{transition:transform .3s ease}.Chat-module_pauseButton__eeu7K.Chat-module_paused__j-pya svg{transform:scale(1.1)}.Chat-module_pauseButton__eeu7K.Chat-module_pausing__pTx8b svg{opacity:.8}.Chat-module_voiceCallIndicatorBar__N2sWN{align-items:center;backdrop-filter:blur(10px);background:linear-gradient(135deg,rgba(34,197,94,.1),rgba(16,185,129,.1));border-bottom:1px solid rgba(34,197,94,.3);display:flex;grid-area:🟦;justify-content:center;padding:12px 20px;width:100%}.Chat-module_voiceCallIndicator__tsaaG{align-items:center;backdrop-filter:blur(10px);background:linear-gradient(135deg,rgba(34,197,94,.2),rgba(16,185,129,.2));border:1px solid rgba(34,197,94,.4);border-radius:20px;box-shadow:0 2px 8px rgba(34,197,94,.2);color:#10b981;display:inline-flex;font-size:13px;font-weight:600;gap:8px;padding:8px 16px;position:relative}.Chat-module_voiceCallIndicator__tsaaG svg{animation:Chat-module_voiceCallIconPulse__zZbJn 2s ease-in-out infinite;flex-shrink:0;height:16px;width:16px}.Chat-module_voiceCallIndicator__tsaaG span{font-weight:600;text-shadow:0 1px 2px rgba(0,0,0,.1)}.Chat-module_voiceCallPulse__XcGU4{animation:Chat-module_voiceCallPulse__XcGU4 1.5s ease-in-out infinite;background:#10b981;border-radius:50%;height:8px;position:absolute;right:8px;top:50%;transform:translateY(-50%);width:8px}@keyframes Chat-module_voiceCallIconPulse__zZbJn{0%,to{opacity:1;transform:scale(1)}50%{opacity:.8;transform:scale(1.1)}}@keyframes Chat-module_voiceCallPulse__XcGU4{0%,to{opacity:1;transform:translateY(-50%) scale(1)}50%{opacity:.6;transform:translateY(-50%) scale(1.3)}}.Chat-module_chatMessage__nmLaZ .Chat-module_voiceCallIndicator__tsaaG{border-radius:16px;font-size:12px;margin-bottom:8px;padding:6px 12px}.Chat-module_chatMessage__nmLaZ .Chat-module_voiceCallIndicator__tsaaG svg{height:14px;width:14px}.Chat-module_ratingConfirmation__n16vb{word-wrap:break-word;animation:Chat-module_confirmationSlideIn__5U-wz .3s ease-out;backdrop-filter:blur(20px);background:linear-gradient(135deg,#10b981,#059669);border-radius:12px;box-shadow:0 8px 32px rgba(16,185,129,.3);color:#fff;font-weight:500;max-width:300px;padding:16px 20px;position:fixed;right:20px;top:20px;z-index:1001}@keyframes Chat-module_confirmationSlideIn__5U-wz{0%{opacity:0;transform:translateX(100%)}to{opacity:1;transform:translateX(0)}}@media (max-width:768px){.Chat-module_actions__gTZ5T{gap:6px;margin:12px 16px 0}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N{padding:16px 12px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ{margin-bottom:16px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{border-radius:18px;font-size:14px;max-width:85%;padding:12px 16px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_avatar__gL6bm{height:36px;margin:0 10px 4px;width:36px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan{gap:10px;padding:16px 12px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{border-radius:22px;font-size:16px;padding:14px 18px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button{height:44px;width:44px}.Chat-module_scrollToBottom__nzxdZ{font-size:18px;height:44px;top:calc(100% - 160px);width:44px}.Chat-module_chatButton__d9VgA{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_chatButton__d9VgA svg{height:18px!important;width:18px!important}.Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_useTemplateButton__xcJNR{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_useTemplateButton__xcJNR svg{height:18px!important;width:18px!important}.Chat-module_useTemplateButton__xcJNR .Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_ratingModalContent__CCdq7{border-radius:16px;margin:16px;max-height:80vh;overflow-y:auto;padding:24px 20px}.Chat-module_stars__PCzNO{gap:6px;margin-bottom:20px}.Chat-module_stars__PCzNO span{font-size:32px;padding:8px}.Chat-module_ratingActions__nXcss{flex-direction:column-reverse;gap:8px}.Chat-module_ratingActions__nXcss button{border-radius:10px;font-size:16px;padding:14px;width:100%}}@media (max-width:480px){.Chat-module_actions__gTZ5T{gap:4px;margin:8px 12px 0}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N{padding:12px 8px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{border-radius:16px;font-size:14px;max-width:90%;padding:10px 14px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_avatar__gL6bm{height:32px;margin:0 8px 4px;width:32px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan{gap:8px;padding:12px 8px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{border-radius:20px;font-size:16px;padding:12px 16px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button{height:40px;width:40px}.Chat-module_chatButton__d9VgA{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_chatButton__d9VgA svg{height:18px!important;width:18px!important}.Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_useTemplateButton__xcJNR{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_useTemplateButton__xcJNR svg{height:18px!important;width:18px!important}.Chat-module_useTemplateButton__xcJNR .Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_scrollToBottom__nzxdZ{font-size:16px;height:40px;top:calc(100% - 140px);width:40px}.Chat-module_ratingModal__XVKYm{align-items:flex-end;padding:0}.Chat-module_ratingModalContent__CCdq7{border-radius:20px 20px 0 0;margin:0;max-height:70vh;padding:24px 16px 20px;width:100%}}@media (prefers-reduced-motion:reduce){.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ,.Chat-module_ratingConfirmation__n16vb,.Chat-module_ratingModalContent__CCdq7,.Chat-module_ratingModal__XVKYm,.Chat-module_scrollToBottom__nzxdZ{animation:none}.Chat-module_chatButton__d9VgA,.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button,.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea,.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{transition:none}}@media (prefers-contrast:high){.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{border:2px solid}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{border-width:3px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button{border:2px solid}}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNoYXQubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxXQUNJLHlCQUE0QixDQUM1QiwyRUFBOEUsQ0FDOUUsaXJFQXVCSixDQUVBLDZDQUtJLGVBQWdCLENBR2hCLGlCQUFrQixDQUVsQixxQ0FBMEMsQ0FKMUMsVUFBVyxDQUdYLGVBQWdCLENBTmhCLFFBQVMsQ0FRVCxXQUFhLENBSmIsaUJBQWtCLENBS2xCLG1CQUFvQixDQVhwQixjQUFlLENBQ2YsUUFBUyxDQUVULDBCQUEyQixDQVMzQixZQUNKLENBRUEseUJBR0ksWUFBYSxDQUNiLHFCQUFzQixDQUV0QixvREFBMEQsQ0FKMUQsV0FBWSxDQURaLFVBT0osQ0FFQSxpQ0FJSSxZQUFhLENBQ2IsNERBSVMsQ0FQVCxXQUFZLENBQ1osZUFBZ0IsQ0FGaEIsVUFTSixDQUVBLDZEQUtJLHFCQUF5QixDQUN6QiwwQ0FBK0MsQ0FGL0MsYUFBYyxDQUlkLGVBQWdCLENBUGhCLFlBQWEsQ0FFYixpQkFBa0IsQ0FJbEIsaUJBQWtCLENBTGxCLFVBT0osQ0FFQSxvQ0FJSSxpQkFBa0IsQ0FIbEIsWUFBYSxDQUViLGtCQUFtQixDQUVuQixxQkFBc0IsQ0FDdEIsZUFBZ0IsQ0FKaEIsVUFLSixDQUVBLDRCQVNJLGtCQUFtQixDQUpuQixxQkFBc0IsQ0FHdEIsWUFBYSxDQUViLE9BQVEsQ0FUUixZQUFhLENBRWIsa0JBQW1CLENBR25CLHFCQUFzQixDQUN0QixrQkFBbUIsQ0FMbkIsVUFBVyxDQUVYLFdBT0osQ0FFQSxzREFDSSxRQUNKLENBRUEsb0RBQ0ksdUJBQ0osQ0FFQSxxREFDSSxxQkFDSixDQUdBLHlCQUNJLCtCQUNJLDJCQUE2QixDQU03QixlQUFpQixDQUpqQixxQkFBdUIsQ0FLdkIsa0JBQW9CLENBSHBCLHlCQUEyQixDQUQzQix3QkFBMEIsQ0FFMUIsbUJBQXFCLENBSnJCLG9CQU9KLENBRUEsbUNBRUkscUJBQXVCLENBRHZCLG9CQUVKLENBRUEsbUNBQ0ksc0JBQ0osQ0FFQSxzQ0FDSSwyQkFBNkIsQ0FNN0IsZUFBaUIsQ0FKakIscUJBQXVCLENBS3ZCLGtCQUFvQixDQUhwQix5QkFBMkIsQ0FEM0Isd0JBQTBCLENBRTFCLG1CQUFxQixDQUpyQixvQkFPSixDQUVBLDBDQUVJLHFCQUF1QixDQUR2QixvQkFFSixDQUVBLHlFQUNJLHNCQUNKLENBQ0osQ0FHQSx5QkFDSSw0QkFFSSxPQUFRLENBRFIsa0JBRUosQ0FDSixDQUVBLGtFQUNJLFlBQWEsQ0FFYixXQUFZLENBRFosVUFBVyxDQUVYLFdBQ0osQ0FHQSxrRUFDSSxZQUFhLENBRWIsV0FBWSxDQUlaLGlCQUFrQixDQURsQixlQUFnQixDQURoQixzQkFBdUIsQ0FHdkIsc0JBQXVCLENBTnZCLFVBQVcsQ0FFWCxVQUtKLENBR0EscUZBQ0ksU0FDSixDQUVBLDJGQUNJLHNCQUNKLENBRUEsMkZBQ0ksNEJBQW9DLENBQ3BDLGlCQUFrQixDQUNsQix1QkFDSixDQUVBLGlHQUNJLDRCQUNKLENBR0EsaUVBR0ksb0JBQXFCLENBR3JCLDZFQUFtRSxDQUxuRSxZQUFhLENBR2Isa0JBQW1CLENBRm5CLGtCQUFtQixDQUtuQixjQUFlLENBRmYsaUJBR0osQ0FHQSxvREFDSSxlQUNKLENBRUEsNkNBQ0ksR0FDSSxTQUFVLENBQ1YscUNBQ0osQ0FDQSxHQUNJLFNBQVUsQ0FDVixnQ0FDSixDQUNKLENBRUEseUNBS0ksVUFBWSxDQUNaLGlCQUNKLENBRUEsNkNBQ0ksaUJBQ0osQ0FHQSwrRUFTSSxtRUFBaUQsQ0FGakQsMkVBQXNGLENBQ3RGLGlCQUFrQixDQUxsQixVQUFXLENBRlgsVUFBVyxDQUtYLFVBQVcsQ0FKWCxpQkFBa0IsQ0FFbEIsVUFBVyxDQUNYLFVBS0osQ0FFQSwyQ0FDSSxNQUVJLFVBQVksQ0FDWixvQkFDSixDQUNBLElBQ0ksU0FBVSxDQUNWLHFCQUNKLENBQ0osQ0FHQSxvQ0FFSSxvQkFBcUIsQ0FFckIsNkVBQW1FLENBSG5FLFlBQWEsQ0FFYixrQkFFSixDQUVBLCtEQUlJLGFBQWMsQ0FGZCxXQUFZLENBQ1osaUJBQWtCLENBRmxCLFVBSUosQ0FhQSxpQ0FNSSwwQkFBMkIsQ0FGM0Isa0NBQTBDLENBRjFDLGtCQUFtQixDQUNuQiw2QkFBOEIsQ0FFOUIsbUNBQXdDLENBS3hDLGVBQWdCLENBVGhCLGlCQVVKLENBRUEsZ0VBTEksa0JBQW1CLENBRG5CLFlBQWEsQ0FFYixPQVFKLENBRUEsOEJBS0ksbUVBQWlELENBRGpELDREQUE4RSxDQUQ5RSxpQkFBa0IsQ0FHbEIsbUNBQXdDLENBSnhDLFVBQVcsQ0FEWCxTQU1KLENBRUEsMENBQ0kscUJBQ0osQ0FFQSwyQ0FDSSxxQkFDSixDQUVBLDJDQUNJLGtCQUNKLENBRUEsMkNBQ0ksVUFJSSxVQUFZLENBRFosaUNBRUosQ0FDQSxJQUVJLFNBQVUsQ0FEVixxQ0FFSixDQUNKLENBRUEseUZBQ0ksb0JBQXFCLENBQ3JCLDBCQUEyQixDQUMzQiwwQkFDSixDQUVBLHlIQUNJLDhCQUNKLENBRUEsK0JBSUkscUNBQXVDLENBSHZDLGNBQWUsQ0FDZixjQUFlLENBQ2Ysb0JBRUosQ0FFQSx5REFDSSxVQUNKLENBR0EsNEZBRUksZ0JBQW1CLENBRW5CLGFBQWMsQ0FEZCxpQkFBa0IsQ0FFbEIsaUJBQWtCLENBSmxCLFVBS0osQ0FxQkEsaUdBV0ksb0JBQXFCLENBR3JCLDBCQUEyQixDQWIzQix3Q0FBeUMsQ0FJekMsa0JBQW1CLENBSW5CLG1DQUF3QyxDQVB4QywrQkFBZ0MsQ0FXaEMsY0FBZSxDQUhmLGVBQWdCLENBRmhCLGlCQUFrQixDQUZsQix3QkFBMEIsQ0FGMUIsaUJBQWtCLENBRGxCLGlCQUFrQixDQUlsQixlQUFnQixDQUtoQix1QkFHSixDQUdBLHdDQUtJLGtCQUFtQixDQUpuQixXQUFZLENBS1osd0JBQXlCLENBQ3pCLG1CQUFvQixDQUpwQixVQUFXLENBRFgsT0FBUSxDQU9SLGlCQUFrQixDQUxsQixTQU1KLENBQ0Esb01BR0ksbUJBQW9CLENBRHBCLGtCQUVKLENBRUEsK0JBU0ksa0JBQW1CLENBUm5CLDZCQUFvQyxDQUNwQyxxQkFBc0IsQ0FDdEIsaUJBQWtCLENBR2xCLG9DQUF5QyxDQUR6QyxjQUFlLENBR2YsWUFBYSxDQUViLFVBQVksQ0FOWixlQUFnQixDQU9oQixpQkFBa0IsQ0FKbEIsK0NBS0osQ0FFQSxrQ0FnQkksb0RBQW1DLENBWG5DLGVBQWdCLENBR2hCLGlCQUFrQixDQUVsQixxQ0FBMEMsQ0FKMUMsVUFBVyxDQUdYLGVBQWlCLENBUGpCLFFBQVMsQ0FhVCxjQUFlLENBRWYsZUFBZ0IsQ0FOaEIsV0FBYSxDQU9iLHdCQUF5QixDQVh6QixnQkFBaUIsQ0FLakIsbUJBQW9CLENBWHBCLGlCQUFrQixDQUVsQixRQUFTLENBQ1QsMEJBQTJCLENBVTNCLGtCQUFtQixDQUtuQixxQkFBc0IsQ0FOdEIsV0FPSixDQUVBLHNDQUNJLGdCQUFrQixDQUNsQix3QkFDSixDQUVBLHVDQUNJLG1CQUFxQixDQUNyQixpQkFBbUIsQ0FDbkIsd0JBQ0osQ0FJQSxrREFDSSxHQUNJLFNBQVUsQ0FDVixxREFDSixDQUNBLEdBQ0ksV0FBYSxDQUNiLGlEQUNKLENBQ0osQ0FFQSwwRUFFSSx1QkFBd0IsQ0FFeEIsdUNBQTRDLENBRDVDLFNBRUosQ0FFQSxtQ0FDSSxhQUNKLENBRUEsbUNBQ0ksYUFDSixDQUVBLG1DQUNJLGdCQUNKLENBRUEsbUNBQ0ksZUFDSixDQUVBLG1DQUNJLGdCQUNKLENBRUEsbUNBQ0ksZUFDSixDQUVBLG1DQUNJLGVBQWdCLENBQ2hCLGdCQUNKLENBRUEsbUNBQ0ksa0JBQW1CLENBQ25CLGdCQUNKLENBRUEseUpBTUksaUJBQWtCLENBRGxCLGtCQUFtQixDQURuQixlQUdKLENBRUEsb0NBSUksZUFBcUIsQ0FHckIsVUFFSixDQUVBLCtFQVRJLFdBQVksQ0FDWixlQUFnQixDQUZoQixhQUFjLENBSWQsaUJBQWtCLENBQ2xCLG1CQUFvQixDQUVwQixXQVlKLENBVEEsMkNBSUksb0JBQXFCLENBR3JCLFVBRUosQ0FFQSxxQ0FNSSxvQkFBcUIsQ0FGckIsV0FBWSxDQUNaLGVBQWdCLENBSWhCLGFBQWMsQ0FSZCxvQkFBcUIsQ0FNckIsaUJBQWtCLENBQ2xCLG1CQUFvQixDQU5wQixRQUFTLENBQ1QsU0FPSixDQUVBLHlDQUNJLDBCQUEyQixDQUMzQixpQkFDSixDQUVBLG9FQUNJLGtCQUFtQixDQUtuQixvQkFBcUIsQ0FDckIsb0NBQXlDLENBTHpDLGFBQWMsQ0FNZCw4REFBMkUsQ0FMM0UsY0FBZSxDQUNmLGVBQWdCLENBQ2hCLGVBSUosQ0FDQSx5RUFDSSx5QkFBMkIsQ0FLM0IscUJBQXVCLENBQ3ZCLHlCQUEyQixDQUwzQix1QkFBeUIsQ0FTekIsYUFBYyxDQVJkLDZCQUErQixDQUMvQiwyQkFBNkIsQ0FNN0IsZUFBZ0IsQ0FMaEIsbUJBQXFCLENBR3JCLGVBQWdCLENBQ2hCLHFCQUdKLENBQ0Esc0NBS0ksa0JBQW1CLENBSG5CLHdCQUF5QixDQUN6QixnQkFBaUIsQ0FLakIsb0NBQXlDLENBRXpDLGFBQWMsQ0FEZCxjQUFlLENBTGYsYUFBYyxDQUhkLFVBVUosQ0FDQSxzRUFNSSxlQUFnQixDQUhoQiwrQkFBZ0MsQ0FFaEMsYUFBYyxDQUhkLGlCQUFrQixDQUVsQixlQUdKLENBQ0EsbUNBQ0kscURBQTZELENBRzdELCtCQUFnQyxDQURoQyxhQUFjLENBRGQsZUFHSixDQUNBLGlEQUNJLGtCQUNKLENBQ0Esb0RBQ0ksa0JBQ0osQ0FDQSw0Q0FDSSxrQkFBbUIsQ0FDbkIseUJBQ0osQ0FDQSxzQ0FDSSxrQkFBbUIsQ0FDbkIsZUFDSixDQUNBLDhGQUVJLDJCQUNKLENBQ0EsNEZBRUksNEJBQ0osQ0FFQSx1R0FDSSxxQ0FBMEMsQ0FDMUMsMEJBQ0osQ0FHQSxnQ0FNSSxzQ0FBOEMsQ0FMOUMsWUFBYSxDQUNiLGNBQWUsQ0FDZixPQUFRLENBQ1IsZUFBZ0IsQ0FDaEIsZ0JBRUosQ0FFQSwrQkFFSSxrQkFBbUIsQ0FHbkIsNkJBQW9DLENBQ3BDLGtDQUEwQyxDQUMxQyxrQkFBbUIsQ0FFbkIsYUFBYyxDQVJkLFlBQWEsQ0FPYixjQUFlLENBTGYsT0FBUSxDQVNSLGVBQWdCLENBUmhCLGdCQUFpQixDQU1qQixvQkFBcUIsQ0FDckIsdUJBRUosQ0FFQSxxQ0FDSSw2QkFBb0MsQ0FDcEMsOEJBQXNDLENBQ3RDLDBCQUNKLENBRUEsbUNBQ0ksY0FBZSxDQUNmLFVBQ0osQ0FFQSxtQ0FFSSxlQUFnQixDQUNoQixzQkFBdUIsQ0FGdkIsa0JBR0osQ0FHQSxtQ0FNSSx1Q0FBOEMsQ0FMOUMsWUFBYSxDQUNiLGNBQWUsQ0FDZixPQUFRLENBQ1IsZUFBZ0IsQ0FDaEIsZ0JBRUosQ0FHQSxrQ0FZSSx1Q0FBd0MsQ0FWeEMsa0JBQW1CLENBU25CLDBCQUEyQixDQVAzQiw0QkFBb0MsQ0FDcEMsa0NBQTBDLENBQzFDLGtCQUFtQixDQUduQixjQUFlLENBUmYsbUJBQW9CLENBTXBCLGNBQWUsQ0FDZixlQUFnQixDQUxoQixnQkFBaUIsQ0FVakIseUJBQTBCLENBSDFCLHVCQUF5QixDQUl6QixnQkFDSixDQUVBLHdDQUNJLDZCQUFrQyxDQUNsQywrQkFBb0MsQ0FFcEMsd0NBQTZDLENBRDdDLDBCQUVKLENBRUEseUNBQ0ksb0JBQXNCLENBQ3RCLDZCQUNKLENBR0Esb0NBR0ksbUJBQW9CLENBRnBCLFFBQVMsQ0FDVCxTQUVKLENBRUEseUNBQ0ksZUFDSixDQUVBLHFDQUNJLGlCQUNKLENBR0EsNEZBTUksa0JBQW1CLENBTW5CLDBCQUEyQixDQUgzQix5QkFBOEIsQ0FDOUIsa0JBQW1CLENBUm5CLFdBQVksQ0FFWixZQUFhLENBQ2IsT0FBUSxDQUVSLGNBQWUsQ0FNZixTQUFVLENBRlYsZUFBZ0IsQ0FWaEIsaUJBQWtCLENBRWxCLFNBQVUsQ0FXVix5QkFBMEIsQ0FDMUIsZ0RBQXlELENBUHpELFNBUUosQ0FFQSxrR0FDSSxTQUFVLENBQ1YsdUJBQ0osQ0FFQSxrR0FDSSx5QkFBOEIsQ0FFOUIsb0NBQXlDLENBRHpDLGVBRUosQ0FFQSxpR0FHSSxjQUFlLENBRGYsb0JBQXFCLENBRXJCLGNBQWUsQ0FIZiw0Q0FJSixDQUVBLHVHQUNJLG9CQUNKLENBR0EsK0RBS0ksMEJBQTJCLENBQzNCLHNDQUE4QyxDQUM5QyxZQUFhLENBQ2IscUJBQXNCLENBQ3RCLFFBQVMsQ0FQVCxZQUFhLENBRWIsWUFBYSxDQU1iLGlCQUFrQixDQVBsQixVQUFXLENBRlgsVUFVSixDQUdBLDJGQUNJLHlFQUE0RixDQUM1Rix1Q0FDSixDQUdBLHlDQUNJLFlBQWEsQ0FDYixjQUFlLENBQ2YsT0FBUSxDQUNSLGlCQUNKLENBR0EsZ0NBRUksa0JBQW1CLENBT25CLDBCQUEyQixDQUozQiw0QkFBb0MsQ0FDcEMsa0NBQTBDLENBQzFDLGlCQUFrQixDQU5sQixZQUFhLENBT2IsY0FBZSxDQUxmLE9BQVEsQ0FDUixnQkFBaUIsQ0FNakIsdUJBQ0osQ0FFQSxzQ0FDSSw2QkFBcUMsQ0FDckMsOEJBQ0osQ0FFQSw2QkFDSSxjQUFlLENBQ2YsVUFDSixDQUVBLDZCQUNJLFlBQWEsQ0FDYixxQkFBc0IsQ0FDdEIsT0FBUSxDQUNSLFdBQ0osQ0FFQSw2QkFFSSxVQUFZLENBRFosZUFBZ0IsQ0FLaEIsZUFBZ0IsQ0FGaEIsZUFBZ0IsQ0FDaEIsc0JBQXVCLENBRnZCLGtCQUlKLENBRUEsNkJBQ0ksYUFBYyxDQUNkLGNBQ0osQ0FFQSxxQ0FFSSxrQkFBbUIsQ0FLbkIsMkJBQWdDLENBRGhDLFdBQVksQ0FHWixpQkFBa0IsQ0FEbEIsVUFBYyxDQUVkLGNBQWUsQ0FUZixZQUFhLENBV2IsYUFBYyxDQVBkLFdBQVksQ0FGWixzQkFBdUIsQ0FRdkIsdUJBQXlCLENBUHpCLFVBU0osQ0FFQSwyQ0FDSSwyQkFBZ0MsQ0FDaEMsb0JBQ0osQ0FHQSxtQ0FFSSxrQkFBbUIsQ0FEbkIsWUFBYSxDQUViLFFBQ0osQ0FFQSx5REFDSSxhQUFjLENBQ2QsVUFDSixDQUdBLHFDQVFJLGtCQUFtQixDQUluQiwwQkFBMkIsQ0FSM0IsNkJBQXFDLENBRHJDLGtDQUEwQyxDQUcxQyxpQkFBa0IsQ0FEbEIsYUFBYyxDQUtkLGNBQWUsQ0FIZixZQUFhLENBTWIsYUFBYyxDQVhkLFdBQVksQ0FPWixzQkFBdUIsQ0FFdkIsdUJBQXlCLENBVnpCLFVBYUosQ0FFQSwwREFDSSw2QkFBa0MsQ0FDbEMsK0JBQW9DLENBQ3BDLGFBQWMsQ0FDZCxxQkFDSixDQUVBLDhDQUVJLGtCQUFtQixDQURuQixVQUFZLENBRVosY0FDSixDQUdBLGdDQVFJLGtCQUFtQixDQUluQiwwQkFBMkIsQ0FSM0IsNkJBQXFDLENBRHJDLGtDQUEwQyxDQUcxQyxpQkFBa0IsQ0FEbEIsYUFBYyxDQUtkLGNBQWUsQ0FIZixZQUFhLENBTWIsYUFBYyxDQVhkLFdBQVksQ0FPWixzQkFBdUIsQ0FFdkIsdUJBQXlCLENBVnpCLFVBYUosQ0FFQSxzQ0FDSSw2QkFBa0MsQ0FDbEMsK0JBQW9DLENBQ3BDLGFBQWMsQ0FDZCxxQkFDSixDQUVBLHNDQUlJLDhEQUE0QyxDQUg1QyxxQ0FBMkMsQ0FDM0MsdUNBQTZDLENBQzdDLG1CQUVKLENBRUEsa0RBQ0ksR0FDSSxtQ0FDSixDQUNBLElBQ0kscUNBQ0osQ0FDQSxHQUNJLGtDQUNKLENBQ0osQ0FHQSxtQ0FFSSxrQkFBbUIsQ0FHbkIsNkJBQWtDLENBQ2xDLG1DQUF3QyxDQUN4QyxpQkFBa0IsQ0FFbEIsYUFBYyxDQVJkLFlBQWEsQ0FPYixjQUFlLENBTGYsUUFBUyxDQUNULGdCQU1KLENBRUEsc0NBR0ksNkJBQWtDLENBQ2xDLGlCQUFrQixDQUhsQixNQUFPLENBQ1AsVUFBVyxDQUdYLGVBQ0osQ0FFQSx1Q0FJSSxxRUFBbUQsQ0FGbkQsNERBQW1FLENBQ25FLGlCQUFrQixDQUZsQixXQUlKLENBRUEsNkNBQ0ksR0FDSSwyQkFDSixDQUNBLElBQ0ksdUJBQ0osQ0FDQSxHQUNJLDBCQUNKLENBQ0osQ0FHQSxnQ0FVSSxrQkFBbUIsQ0FFbkIsMEJBQTJCLENBTjNCLDZCQUFrQyxDQUNsQyxvQ0FBeUMsQ0FDekMsa0JBQW1CLENBSG5CLFFBQVMsQ0FJVCxZQUFhLENBRWIsc0JBQXVCLENBUnZCLE1BQU8sQ0FXUCxtQkFBb0IsQ0FicEIsaUJBQWtCLENBR2xCLE9BQVEsQ0FGUixLQUFNLENBV04sVUFFSixDQUVBLHVDQUdJLGtCQUFtQixDQUVuQixhQUFjLENBSmQsWUFBYSxDQUNiLHFCQUFzQixDQUl0QixlQUFnQixDQUZoQixRQUFTLENBR1QsaUJBQ0osQ0FFQSwyQ0FDSSxVQUNKLENBR0Esd0VBaUJJLHVDQUF3QyxDQUZ4QyxlQUFnQixDQUNoQix1QkFBd0IsQ0FUeEIsMEJBQTJCLENBRDNCLDZCQUFxQyxDQURyQyxrQkFBbUIsQ0FHbkIsVUFBWSxDQVBaLE1BQU8sQ0FVUCxjQUFlLENBQ2YsZUFBZ0IsQ0FGaEIsZ0JBQWlCLENBRGpCLGVBQWdCLENBTGhCLFlBQWEsQ0FGYixpQkFBa0IsQ0FXbEIsV0FBWSxDQUtaLHlCQUEwQixDQUoxQixnREFLSixDQUVBLDhFQUVJLDZCQUFxQyxDQURyQyxvQkFBcUIsQ0FFckIsc0VBQWdGLENBQ2hGLDBCQUNKLENBRUEsaUZBRUksa0JBQW1CLENBRG5CLFVBQVksQ0FFWixjQUNKLENBRUEscUZBQ0ksYUFBYyxDQUNkLFVBQ0osQ0FHQSxzRUFzQkksdUNBQXdDLENBWHhDLGtCQUFtQixDQUduQixnQkFBbUIsQ0FSbkIsV0FBWSxDQU9aLDJCQUE2QixDQVE3Qix3Q0FBNkMsQ0FaN0MsVUFBYyxDQUNkLFlBQWEsQ0FSYixXQUFZLENBVVosc0JBQXVCLENBVHZCLGtCQUFvQixDQWFwQiwwQkFBNEIsQ0FENUIseUJBQTJCLENBVTNCLGdCQUFpQixDQXJCakIsbUJBQXFCLENBYXJCLGtCQUFtQixDQUNuQixtQkFBb0IsQ0FLcEIseUJBQTBCLENBSDFCLGdEQUF5RCxDQUl6RCxnQkFBaUIsQ0F2QmpCLFVBeUJKLENBRUEsMEVBRUksV0FBWSxDQUNaLGtCQUFtQixDQUZuQixTQUdKLENBSUEsNENBV0ksc0JBQXVCLENBRnZCLFlBQWEsQ0FIYixZQUFhLENBRWIsV0FBWSxDQUVaLHNCQUF1QixDQUd2QixtQkFBb0IsQ0FOcEIsVUFBVyxDQUZYLFVBU0osQ0FFQSwrRUFpQkksdUNBQXdDLENBVHhDLGtCQUFtQixDQWNuQiw2REFBNEMsQ0FWNUMseUJBQTBCLENBRDFCLHlCQUE2QixDQUY3QixXQUFZLENBSVosaUJBQWtCLENBUWxCLG9DQUF5QyxDQU56QyxVQUFZLENBQ1osY0FBZSxDQVZmLFlBQWEsQ0FRYixlQUFpQixDQVRqQixXQUFZLENBRVosc0JBQXVCLENBR3ZCLFlBQWEsQ0FUYixrQkFBbUIsQ0FpQm5CLHlCQUEwQixDQWYxQiwrQkFBaUMsQ0FpQmpDLGdEQUF5RCxDQUR6RCxnQkFBaUIsQ0FmakIsVUFtQkosQ0FFQSxrREFDSSxHQUNJLFNBQVUsQ0FDVix3Q0FDSixDQUNBLEdBQ0ksVUFBWSxDQUNaLGtDQUNKLENBQ0osQ0FFQSx5Q0FDSSwyQ0FDSixDQUVBLDBDQUNJLDBDQUE2QyxDQUM3Qyw2QkFDSixDQUdBLGdDQVlJLGtCQUFtQixDQUVuQixxREFBb0MsQ0FOcEMseUJBQTBCLENBRDFCLCtCQUFvQyxDQUZwQyxRQUFTLENBS1QsWUFBYSxDQUNiLHNCQUF1QixDQVJ2QixNQUFPLENBRlAsY0FBZSxDQUdmLE9BQVEsQ0FGUixLQUFNLENBV04sWUFFSixDQUVBLDBDQUNJLEdBRUksdUJBQTBCLENBRDFCLFNBRUosQ0FDQSxHQUVJLHlCQUEwQixDQUQxQixTQUVKLENBQ0osQ0FFQSx1Q0FVSSwyRUFBaUUsQ0FEakUsMEJBQTJCLENBUjNCLGVBQW1CLENBT25CLGtDQUEwQyxDQUoxQyxrQkFBbUIsQ0FHbkIscUNBQTBDLENBTDFDLGFBQWMsQ0FVZCxvREFBMEQsQ0FOMUQsZUFBZ0IsQ0FIaEIsWUFBYSxDQUViLFNBU0osQ0FFQSwyQ0FDSSxHQUNJLFNBQVUsQ0FDVixxQ0FDSixDQUNBLEdBQ0ksU0FBVSxDQUNWLGdDQUNKLENBQ0osQ0FFQSwwQ0FHSSxVQUFZLENBQ1osY0FBZSxDQUNmLGVBQWdCLENBSmhCLGVBQWtCLENBQ2xCLGlCQUlKLENBRUEsMEJBQ0ksWUFBYSxDQUViLE9BQVEsQ0FEUixzQkFBdUIsQ0FFdkIsa0JBQ0osQ0FFQSwrQkFLSSxpQkFBa0IsQ0FIbEIsY0FBZSxDQURmLGNBQWUsQ0FHZixXQUFZLENBRFosdUJBR0osQ0FFQSxxQ0FFSSw2QkFBa0MsQ0FEbEMsb0JBRUosQ0FFQSxvQ0FDSSxjQUFlLENBQ2YsY0FBZSxDQUNmLG9CQUNKLENBRUEsZ0NBUUksNkJBQXFDLENBSnJDLGtDQUEwQyxDQUMxQyxrQkFBbUIsQ0FJbkIsYUFBYyxDQUNkLGNBQWUsQ0FDZixlQUFnQixDQUxoQixrQkFBbUIsQ0FKbkIsZ0JBQWlCLENBQ2pCLFlBQWEsQ0FJYixlQUFnQixDQUtoQix1QkFBeUIsQ0FYekIsVUFZSixDQUVBLHNDQUVJLDZCQUFxQyxDQURyQyxvQkFBcUIsQ0FFckIsdUNBQTRDLENBQzVDLFlBQ0osQ0FFQSwwQ0FFSSw2QkFBcUMsQ0FEckMsa0NBRUosQ0FFQSxrQ0FDSSxZQUFhLENBRWIsUUFBUyxDQURULHdCQUVKLENBRUEseUNBRUksV0FBWSxDQUNaLGlCQUFrQixDQUNsQixjQUFlLENBQ2YsY0FBZSxDQUNmLGVBQWdCLENBRWhCLGNBQWUsQ0FQZixpQkFBa0IsQ0FNbEIsdUJBRUosQ0FFQSxxREFDSSxrQ0FBMEMsQ0FFMUMsa0NBQTBDLENBRDFDLGFBRUosQ0FFQSwwRUFDSSxrQ0FBMEMsQ0FDMUMsYUFDSixDQUVBLG9EQUNJLCtDQUE2RCxDQUM3RCxVQUNKLENBRUEseUVBQ0ksa0RBQTZELENBRTdELHdDQUE2QyxDQUQ3QywwQkFFSixDQUVBLDZEQUVJLGtCQUFtQixDQURuQixVQUVKLENBR0EsK0JBa0JJLGlEQUFtRCxDQWhCbkQsNEJBQThCLENBZTlCLG9DQUFzQyxDQVZ0Qyx5REFBd0UsQ0FFeEUscUJBQXVCLENBQ3ZCLDRCQUE4QixDQU05QixrREFBd0QsQ0FSeEQsb0JBQXlCLENBTXpCLHdCQUEwQixDQWIxQiw2QkFBK0IsQ0FVL0Isd0JBQTBCLENBQzFCLHlCQUEyQixDQVIzQixpQkFBbUIsQ0FEbkIsZ0NBQWtDLENBVWxDLHlCQUEyQixDQVAzQixrQkFBb0IsQ0FlcEIseUJBQTJCLENBQzNCLHlCQUEyQixDQUUzQix5QkFBMkIsQ0FuQjNCLDJCQUE2QixDQWtCN0IsMkJBQTZCLENBSjdCLG1DQUFxQyxDQUpyQywwREFBb0UsQ0FLcEUsMEJBS0osQ0FFQSxzQ0FPSSw0RUFBc0YsQ0FOdEYsVUFBVyxDQUtYLFdBQVksQ0FGWixVQUFXLENBRlgsaUJBQWtCLENBQ2xCLEtBQU0sQ0FLTix3QkFBMEIsQ0FIMUIsVUFJSixDQUVBLDRDQUNJLFNBQ0osQ0FFQSxvREFDSSw0Q0FBNkQsQ0FFN0Qsd0NBQTZDLENBRDdDLHNDQUVKLENBRUEsc0NBR0ksd0NBQTZDLENBRjdDLHFDQUF1QyxDQUN2Qyw2QkFFSixDQUVBLHFDQUVJLHFFQUErRSxDQUQvRSxZQUVKLENBRUEsbUNBTUksNENBQWlELENBSGpELGFBQWMsQ0FEZCxXQUFZLENBRVosU0FBVSxDQUNWLGdEQUF5RCxDQUp6RCxVQU1KLENBRUEseUNBRUksNENBQWlELENBRGpELG1DQUVKLENBRUEsbUNBRUksZUFBZ0IsQ0FHaEIsU0FBVSxDQURWLG9DQUF5QyxDQUR6Qyx1QkFBeUIsQ0FGekIsa0JBS0osQ0FFQSx3RUFDSSx5QkFDSixDQUdBLHNDQWtCSSxpREFBbUQsQ0FoQm5ELDRCQUE4QixDQWU5QixvQ0FBc0MsQ0FWdEMseURBQXdFLENBRXhFLHFCQUF1QixDQUN2Qiw0QkFBOEIsQ0FNOUIsa0RBQXdELENBUnhELG9CQUF5QixDQU16Qix3QkFBMEIsQ0FiMUIsNkJBQStCLENBVS9CLHdCQUEwQixDQUMxQix5QkFBMkIsQ0FSM0IsaUJBQW1CLENBRG5CLGdDQUFrQyxDQVVsQyx5QkFBMkIsQ0FQM0Isa0JBQW9CLENBZXBCLHlCQUEyQixDQUMzQix5QkFBMkIsQ0FFM0IseUJBQTJCLENBbkIzQiwyQkFBNkIsQ0FrQjdCLDJCQUE2QixDQUo3QixtQ0FBcUMsQ0FKckMsMERBQW9FLENBS3BFLDBCQUtKLENBRUEsNkNBT0ksNEVBQXNGLENBTnRGLFVBQVcsQ0FLWCxXQUFZLENBRlosVUFBVyxDQUZYLGlCQUFrQixDQUNsQixLQUFNLENBS04sd0JBQTBCLENBSDFCLFVBSUosQ0FFQSxtREFDSSxTQUNKLENBRUEsMkRBQ0ksNENBQTZELENBRTdELHdDQUE2QyxDQUQ3QyxzQ0FFSixDQUVBLDZDQUdJLHdDQUE2QyxDQUY3QyxxQ0FBdUMsQ0FDdkMsNkJBRUosQ0FFQSw0Q0FFSSxxRUFBK0UsQ0FEL0UsWUFFSixDQUVBLDBDQU1JLDRDQUFpRCxDQUhqRCxhQUFjLENBRGQsV0FBWSxDQUVaLFNBQVUsQ0FDVixnREFBeUQsQ0FKekQsVUFNSixDQUVBLGdEQUVJLDRDQUFpRCxDQURqRCxvQkFFSixDQUVBLCtFQUNJLHlCQUNKLENBRUEsd0NBQ0ksb0JBQXFCLENBQ3JCLGlCQUNKLENBRUEsNkJBSUksZUFBZ0IsQ0FDaEIscUJBQXNCLENBR3RCLG9DQUF5QyxDQUx6QyxNQUFPLENBSVAsZUFBZ0IsQ0FOaEIsaUJBQWtCLENBQ2xCLFFBQVMsQ0FJVCxVQUdKLENBRUEsaUNBS0ksZUFBZ0IsQ0FEaEIsV0FBWSxDQUlaLFVBQVcsQ0FEWCxjQUFlLENBTmYsYUFBYyxDQUVkLGdCQUFpQixDQUdqQixlQUFnQixDQUpoQixVQU9KLENBRUEsdUNBQ0ksd0JBQ0osQ0FHQSxnQ0FDSSw0REFDSixDQUVBLHFEQUNJLDREQUNKLENBRUEsMkRBRUkscUJBQXVCLENBRHZCLG9CQUVKLENBRUEsMERBQ0ksNERBQ0osQ0FFQSwrRUFDSSw0REFBd0UsQ0FFeEUsMENBQStDLENBRC9DLHNDQUVKLENBRUEsb0NBQ0ksNkJBQ0osQ0FFQSw4REFDSSxvQkFDSixDQUVBLCtEQUNJLFVBQ0osQ0FHQSwwQ0FRSSxrQkFBbUIsQ0FDbkIsMEJBQTJCLENBTDNCLHlFQUE0RixDQUM1RiwwQ0FBK0MsQ0FDL0MsWUFBYSxDQUxiLFlBQWEsQ0FNYixzQkFBdUIsQ0FKdkIsaUJBQWtCLENBRGxCLFVBUUosQ0FHQSx1Q0FFSSxrQkFBbUIsQ0FTbkIsMEJBQTJCLENBTjNCLHlFQUE0RixDQUM1RixtQ0FBd0MsQ0FDeEMsa0JBQW1CLENBS25CLHVDQUE0QyxDQUo1QyxhQUFjLENBUGQsbUJBQW9CLENBUXBCLGNBQWUsQ0FDZixlQUFnQixDQVBoQixPQUFRLENBQ1IsZ0JBQWlCLENBU2pCLGlCQUNKLENBRUEsMkNBSUksdUVBQXFELENBRHJELGFBQWMsQ0FEZCxXQUFZLENBRFosVUFJSixDQUVBLDRDQUNJLGVBQWdCLENBQ2hCLG9DQUNKLENBR0EsbUNBU0kscUVBQW1ELENBRm5ELGtCQUFtQixDQUNuQixpQkFBa0IsQ0FGbEIsVUFBVyxDQUxYLGlCQUFrQixDQUNsQixTQUFVLENBQ1YsT0FBUSxDQUNSLDBCQUEyQixDQUMzQixTQUtKLENBRUEsaURBQ0ksTUFHSSxTQUFVLENBRFYsa0JBRUosQ0FDQSxJQUVJLFVBQVksQ0FEWixvQkFFSixDQUNKLENBRUEsNkNBQ0ksTUFHSSxTQUFVLENBRFYsbUNBRUosQ0FDQSxJQUVJLFVBQVksQ0FEWixxQ0FFSixDQUNKLENBR0EsdUVBSUksa0JBQW1CLENBRG5CLGNBQWUsQ0FGZixpQkFBa0IsQ0FDbEIsZ0JBR0osQ0FFQSwyRUFFSSxXQUFZLENBRFosVUFFSixDQUdBLHVDQVlJLG9CQUFxQixDQUZyQiw2REFBNEMsQ0FJNUMsMEJBQTJCLENBVjNCLGtEQUE2RCxDQUc3RCxrQkFBbUIsQ0FDbkIseUNBQThDLENBSDlDLFVBQVksQ0FRWixlQUFnQixDQUZoQixlQUFnQixDQUxoQixpQkFBa0IsQ0FMbEIsY0FBZSxDQUVmLFVBQVcsQ0FEWCxRQUFTLENBT1QsWUFNSixDQUVBLGtEQUNJLEdBRUksU0FBVSxDQURWLDBCQUVKLENBQ0EsR0FFSSxTQUFVLENBRFYsdUJBRUosQ0FDSixDQUdBLHlCQUNJLDRCQUVJLE9BQVEsQ0FEUixrQkFFSixDQUVBLGtFQUNJLGlCQUNKLENBRUEsaUVBQ0ksa0JBQ0osQ0FFQSxpR0FJSSxrQkFBbUIsQ0FEbkIsY0FBZSxDQUZmLGFBQWMsQ0FDZCxpQkFHSixDQUVBLDRGQUVJLFdBQVksQ0FDWixpQkFBa0IsQ0FGbEIsVUFHSixDQVNBLCtEQUVJLFFBQVMsQ0FEVCxpQkFFSixDQUVBLHdFQUdJLGtCQUFtQixDQUZuQixjQUFlLENBQ2YsaUJBRUosQ0FFQSxzRUFFSSxXQUFZLENBRFosVUFFSixDQUVBLG1DQUdJLGNBQWUsQ0FEZixXQUFZLENBRVosc0JBQXVCLENBSHZCLFVBSUosQ0FFQSwrQkFDSSwyQkFBNkIsQ0FNN0IsZUFBaUIsQ0FKakIscUJBQXVCLENBS3ZCLGtCQUFvQixDQUhwQix5QkFBMkIsQ0FEM0Isd0JBQTBCLENBRTFCLG1CQUFxQixDQUpyQixvQkFPSixDQUVBLG1DQUVJLHFCQUF1QixDQUR2QixvQkFFSixDQUVBLG1DQUNJLHNCQUNKLENBRUEsc0NBQ0ksMkJBQTZCLENBTTdCLGVBQWlCLENBSmpCLHFCQUF1QixDQUt2QixrQkFBb0IsQ0FIcEIseUJBQTJCLENBRDNCLHdCQUEwQixDQUUxQixtQkFBcUIsQ0FKckIsb0JBT0osQ0FFQSwwQ0FFSSxxQkFBdUIsQ0FEdkIsb0JBRUosQ0FFQSx5RUFDSSxzQkFDSixDQUVBLHVDQUdJLGtCQUFtQixDQUZuQixXQUFZLENBR1osZUFBZ0IsQ0FDaEIsZUFBZ0IsQ0FIaEIsaUJBSUosQ0FFQSwwQkFDSSxPQUFRLENBQ1Isa0JBQ0osQ0FFQSwrQkFDSSxjQUFlLENBQ2YsV0FDSixDQUVBLGtDQUNJLDZCQUE4QixDQUM5QixPQUNKLENBRUEseUNBSUksa0JBQW1CLENBRG5CLGNBQWUsQ0FEZixZQUFhLENBRGIsVUFJSixDQUNKLENBRUEseUJBQ0ksNEJBRUksT0FBUSxDQURSLGlCQUVKLENBRUEsa0VBQ0ksZ0JBQ0osQ0FFQSxpR0FJSSxrQkFBbUIsQ0FEbkIsY0FBZSxDQUZmLGFBQWMsQ0FDZCxpQkFHSixDQUVBLDRGQUVJLFdBQVksQ0FDWixnQkFBaUIsQ0FGakIsVUFHSixDQVNBLCtEQUVJLE9BQVEsQ0FEUixnQkFFSixDQUVBLHdFQUVJLGtCQUFtQixDQUNuQixjQUFlLENBRmYsaUJBR0osQ0FFQSxzRUFFSSxXQUFZLENBRFosVUFFSixDQUVBLCtCQUNJLDJCQUE2QixDQU03QixlQUFpQixDQUpqQixxQkFBdUIsQ0FLdkIsa0JBQW9CLENBSHBCLHlCQUEyQixDQUQzQix3QkFBMEIsQ0FFMUIsbUJBQXFCLENBSnJCLG9CQU9KLENBRUEsbUNBRUkscUJBQXVCLENBRHZCLG9CQUVKLENBRUEsbUNBQ0ksc0JBQ0osQ0FFQSxzQ0FDSSwyQkFBNkIsQ0FNN0IsZUFBaUIsQ0FKakIscUJBQXVCLENBS3ZCLGtCQUFvQixDQUhwQix5QkFBMkIsQ0FEM0Isd0JBQTBCLENBRTFCLG1CQUFxQixDQUpyQixvQkFPSixDQUVBLDBDQUVJLHFCQUF1QixDQUR2QixvQkFFSixDQUVBLHlFQUNJLHNCQUNKLENBRUEsbUNBR0ksY0FBZSxDQURmLFdBQVksQ0FFWixzQkFBdUIsQ0FIdkIsVUFJSixDQUVBLGdDQUVJLG9CQUFxQixDQURyQixTQUVKLENBRUEsdUNBR0ksMkJBQTRCLENBRjVCLFFBQVMsQ0FHVCxlQUFnQixDQUNoQixzQkFBdUIsQ0FIdkIsVUFJSixDQUNKLENBR0EsdUNBQ0ksa05BS0ksY0FDSixDQUVBLDhRQUtJLGVBQ0osQ0FDSixDQUdBLCtCQUNJLGlHQUNJLGdCQUNKLENBRUEsd0VBQ0ksZ0JBQ0osQ0FFQSxzRUFDSSxnQkFDSixDQUNKIiwiZmlsZSI6IkNoYXQubW9kdWxlLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIkBmb250LWZhY2Uge1xuICAgIGZvbnQtZmFtaWx5OiAnT3Blbk1vamlCbGFjayc7XG4gICAgc3JjOiB1cmwoJ2h0dHBzOi8vczYucHRiay5pby9mb250cy9PcGVuTW9qaS1ibGFjay1nbHlmLndvZmYyJykgZm9ybWF0KCd3b2ZmMicpOyAvKiA8LSBUT0RPOiBb8J+QseKAjfCfmoBdIER5bmFtaWNhbGx5IGxvYWQgZnJvbSAvc2VydmVycy50cyAqL1xuICAgIHVuaWNvZGUtcmFuZ2U6IFUrMjMsIFUrMkEsIFUrMkQsIFUrMzAtMzksIFUrQTksIFUrQUUsIFUrMjAwRCwgVSsyMDNDLCBVKzIwNDksIFUrMjBFMywgVSsyMTE3LCBVKzIxMjAsIFUrMjEyMiwgVSsyMTM5LFxuICAgICAgICBVKzIxOTQtMjE5OSwgVSsyMUE5LCBVKzIxQUEsIFUrMjI5QywgVSsyMzFBLCBVKzIzMUIsIFUrMjMyOCwgVSsyM0NGLCBVKzIzRTktMjNGMywgVSsyM0Y4LTIzRkUsIFUrMjRDMiwgVSsyNUExLFxuICAgICAgICBVKzI1QUEtMjVBRSwgVSsyNUI2LCBVKzI1QzAsIFUrMjVDOSwgVSsyNUQwLCBVKzI1RDEsIFUrMjVFNy0yNUVBLCBVKzI1RUQsIFUrMjVFRSwgVSsyNUZCLTI1RkUsIFUrMjYwMC0yNjA1LFxuICAgICAgICBVKzI2MEUsIFUrMjYxMSwgVSsyNjE0LCBVKzI2MTUsIFUrMjYxOCwgVSsyNjFELCBVKzI2MjAsIFUrMjYyMiwgVSsyNjIzLCBVKzI2MjYsIFUrMjYyQSwgVSsyNjJFLCBVKzI2MkYsXG4gICAgICAgIFUrMjYzOC0yNjNBLCBVKzI2NDAsIFUrMjY0MiwgVSsyNjQ4LTI2NTMsIFUrMjY1RiwgVSsyNjYwLCBVKzI2NjMsIFUrMjY2NSwgVSsyNjY2LCBVKzI2NjgsIFUrMjY3QiwgVSsyNjdFLCBVKzI2N0YsXG4gICAgICAgIFUrMjY5MS0yNjk3LCBVKzI2OTksIFUrMjY5QiwgVSsyNjlDLCBVKzI2QTAsIFUrMjZBMSwgVSsyNkE3LCBVKzI2QUEsIFUrMjZBQiwgVSsyNkIwLCBVKzI2QjEsIFUrMjZCRCwgVSsyNkJFLFxuICAgICAgICBVKzI2QzQsIFUrMjZDNSwgVSsyNkM4LCBVKzI2Q0UsIFUrMjZDRiwgVSsyNkQxLCBVKzI2RDMsIFUrMjZENCwgVSsyNkU5LCBVKzI2RUEsIFUrMjZGMC0yNkY1LCBVKzI2RjctMjZGQSwgVSsyNkZELFxuICAgICAgICBVKzI3MDIsIFUrMjcwNSwgVSsyNzA4LTI3MEQsIFUrMjcwRiwgVSsyNzEyLCBVKzI3MTQsIFUrMjcxNiwgVSsyNzFELCBVKzI3MjEsIFUrMjcyOCwgVSsyNzMzLCBVKzI3MzQsIFUrMjc0NCxcbiAgICAgICAgVSsyNzQ3LCBVKzI3NEMsIFUrMjc0RSwgVSsyNzUzLTI3NTUsIFUrMjc1NywgVSsyNzYzLCBVKzI3NjQsIFUrMjc5NS0yNzk3LCBVKzI3QTEsIFUrMjdCMCwgVSsyN0JGLCBVKzI5MzQsIFUrMjkzNSxcbiAgICAgICAgVSsyQjA1LTJCMDcsIFUrMkIwQywgVSsyQjBELCBVKzJCMUIsIFUrMkIxQywgVSsyQjFGLTJCMjQsIFUrMkIyRSwgVSsyQjJGLCBVKzJCNTAsIFUrMkI1NSwgVSsyQjU4LCBVKzJCOEYsXG4gICAgICAgIFUrMkJCQS0yQkJDLCBVKzJCQzMsIFUrMkJDNCwgVSsyQkVBLCBVKzJCRUIsIFUrMzAzMCwgVSszMDNELCBVKzMyOTcsIFUrMzI5OSwgVStFMDAwLUUwMDksIFUrRTAxMCwgVStFMDExLFxuICAgICAgICBVK0UwNDAtRTA2RCwgVStFMDgwLUUwQjQsIFUrRTBDMC1FMENDLCBVK0UwRkYtRTEwRCwgVStFMTQwLUUxNEEsIFUrRTE1MC1FMTU3LCBVK0UxODEtRTE4OSwgVStFMUMwLUUxQzQsXG4gICAgICAgIFUrRTFDNi1FMUQ5LCBVK0UyMDAtRTIxNiwgVStFMjQwLUUyNjksIFUrRTI4MC1FMjgzLCBVK0UyQzAtRTJDNCwgVStFMkM2LUUyREEsIFUrRTMwMC1FMzAzLCBVK0UzMDUtRTMwRixcbiAgICAgICAgVStFMzEyLUUzMTYsIFUrRTMxOC1FMzIyLCBVK0UzMjQtRTMyOSwgVStFMzJCLCBVK0UzNDAtRTM0OCwgVStFMzgwLCBVK0UzODEsIFUrRjAwMCwgVStGNzdBLCBVK0Y4RkYsIFUrRkUwRixcbiAgICAgICAgVSsxRjAwNCwgVSsxRjBDRiwgVSsxRjEwRC0xRjEwRiwgVSsxRjEyRiwgVSsxRjE2RC0xRjE3MSwgVSsxRjE3RSwgVSsxRjE3RiwgVSsxRjE4RSwgVSsxRjE5MS0xRjE5QSwgVSsxRjFFNi0xRjFGRixcbiAgICAgICAgVSsxRjIwMSwgVSsxRjIwMiwgVSsxRjIxQSwgVSsxRjIyRiwgVSsxRjIzMi0xRjIzQSwgVSsxRjI1MCwgVSsxRjI1MSwgVSsxRjI2MC0xRjI2NSwgVSsxRjMwMC0xRjMyMSwgVSsxRjMyNC0xRjM5MyxcbiAgICAgICAgVSsxRjM5NiwgVSsxRjM5NywgVSsxRjM5OS0xRjM5QiwgVSsxRjM5RS0xRjNGMCwgVSsxRjNGMy0xRjNGNSwgVSsxRjNGNy0xRjRGRCwgVSsxRjRGRi0xRjUzRCwgVSsxRjU0OS0xRjU0RSxcbiAgICAgICAgVSsxRjU1MC0xRjU2NywgVSsxRjU2RiwgVSsxRjU3MCwgVSsxRjU3My0xRjU3QSwgVSsxRjU4NywgVSsxRjU4QS0xRjU4RCwgVSsxRjU5MCwgVSsxRjU5NSwgVSsxRjU5NiwgVSsxRjVBNCxcbiAgICAgICAgVSsxRjVBNSwgVSsxRjVBOCwgVSsxRjVCMSwgVSsxRjVCMiwgVSsxRjVCQywgVSsxRjVDMi0xRjVDNCwgVSsxRjVEMS0xRjVEMywgVSsxRjVEQy0xRjVERSwgVSsxRjVFMSwgVSsxRjVFMyxcbiAgICAgICAgVSsxRjVFOCwgVSsxRjVFRiwgVSsxRjVGMywgVSsxRjVGQS0xRjY0RiwgVSsxRjY4MC0xRjZDNSwgVSsxRjZDQi0xRjZEMiwgVSsxRjZENS0xRjZENywgVSsxRjZEQy0xRjZFNSwgVSsxRjZFOSxcbiAgICAgICAgVSsxRjZFQiwgVSsxRjZFQywgVSsxRjZGMCwgVSsxRjZGMy0xRjZGQywgVSsxRjdFMC0xRjdFQiwgVSsxRjdGMCwgVSsxRjkwQy0xRjkzQSwgVSsxRjkzQy0xRjk0NSwgVSsxRjk0Ny0xRjlGRixcbiAgICAgICAgVSsxRkE3MC0xRkE3QywgVSsxRkE4MC0xRkE4OCwgVSsxRkE5MC0xRkFCRCwgVSsxRkFCRi0xRkFDNSwgVSsxRkFDRS0xRkFEQiwgVSsxRkFFMC0xRkFFOCwgVSsxRkFGMC0xRkFGOCxcbiAgICAgICAgVSsxRkJDNS0xRkJDOSwgVStFMDA2MS1FMDA2NywgVStFMDA2OSwgVStFMDA2Qy1FMDA3OSwgVStFMDA3Rjtcbn1cblxuLmNvcGllZFRvQ2xpcGJvYXJkTWVzc2FnZSB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMzJweDtcbiAgICBsZWZ0OiA1MCU7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC01MCUpO1xuICAgIGJhY2tncm91bmQ6ICMyMjI7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgcGFkZGluZzogMTBweCAyNHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICBmb250LXNpemU6IDEuMWVtO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDEycHggcmdiYSgwLCAwLCAwLCAwLjE4KTtcbiAgICBvcGFjaXR5OiAwLjk3O1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIHotaW5kZXg6IDk5OTk7XG59XG5cbi5DaGF0IHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuXG4gICAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWYsICdPcGVuTW9qaUJsYWNrJztcbiAgICAvKiA8LSBUT0RPOiBb8J+noF1b8J+OsV0gQmV0dGVyLCBkZWZpbmUgb3RoZXIgZm9udHMgKi9cbn1cblxuLmNoYXRNYWluRmxvdyB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIG1heC13aWR0aDogMTAwdnc7XG4gICAgZGlzcGxheTogZ3JpZDtcbiAgICBncmlkLXRlbXBsYXRlOlxuICAgICAgICAn8J+fpicgbWluLWNvbnRlbnRcbiAgICAgICAgJ/CfkqwnIDFmclxuICAgICAgICAn8J+TnScgbWluLWNvbnRlbnRcbiAgICAgICAgLyAxZnI7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRCYXIge1xuICAgIGdyaWQtYXJlYTog8J+fpjtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwYWRkaW5nOiAxNnB4IDIwcHg7XG4gICAgY29sb3I6ICMwZjE3MjQ7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgcmdiYSgxNSwgMjMsIDM2LCAwLjA2KTtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbn1cblxuLlRhc2tzSW5Qcm9ncmVzcyB7XG4gICAgZ3JpZC1hcmVhOiDwn5+mO1xuICAgIHdpZHRoOiBhdXRvO1xuICAgIGhlaWdodDogbWluLWNvbnRlbnQ7XG4gICAgYWxpZ24tc2VsZjogY2VudGVyO1xuICAgIGp1c3RpZnktc2VsZjogc2VsZi1lbmQ7XG4gICAgbWFyZ2luOiA4cHggMTZweDtcbn1cblxuLmFjdGlvbnMge1xuICAgIGdyaWQtYXJlYTog8J+SrDtcbiAgICB3aWR0aDogYXV0bztcbiAgICBoZWlnaHQ6IG1pbi1jb250ZW50O1xuICAgIHotaW5kZXg6IDIwMDtcbiAgICBhbGlnbi1zZWxmOiBzZWxmLXN0YXJ0O1xuICAgIGp1c3RpZnktc2VsZjogc2VsZi1lbmQ7XG4gICAgbWFyZ2luOiAxNnB4IDIwcHggMDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiA4cHg7XG59XG5cbi5hY3Rpb25zLnBvcnRhbCB7XG4gICAgbWFyZ2luOiAwO1xufVxuXG4uYWN0aW9ucy5sZWZ0IHtcbiAgICBqdXN0aWZ5LXNlbGY6IHNlbGYtc3RhcnQ7XG59XG5cbi5hY3Rpb25zLnJpZ2h0IHtcbiAgICBqdXN0aWZ5LXNlbGY6IHNlbGYtZW5kO1xufVxuXG4vKiBMYXJnZSB0YWJsZXQgYW5kIHNtYWxsIGRlc2t0b3Agc2NyZWVucyAqL1xuQG1lZGlhIChtYXgtd2lkdGg6IDkwMHB4KSB7XG4gICAgLmNoYXRCdXR0b24ge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCUgIWltcG9ydGFudDtcbiAgICAgICAgd2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi13aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4taGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcbiAgICAgICAgZ2FwOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5jaGF0QnV0dG9uIHN2ZyB7XG4gICAgICAgIHdpZHRoOiAxOHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogMThweCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5jaGF0QnV0dG9uVGV4dCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24ge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCUgIWltcG9ydGFudDtcbiAgICAgICAgd2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi13aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4taGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcbiAgICAgICAgZ2FwOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC51c2VUZW1wbGF0ZUJ1dHRvbiBzdmcge1xuICAgICAgICB3aWR0aDogMThweCAhaW1wb3J0YW50O1xuICAgICAgICBoZWlnaHQ6IDE4cHggIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24gLmNoYXRCdXR0b25UZXh0IHtcbiAgICAgICAgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1xuICAgIH1cbn1cblxuLyogTWVkaXVtIHNjcmVlbnMgKi9cbkBtZWRpYSAobWF4LXdpZHRoOiA2MDBweCkge1xuICAgIC5hY3Rpb25zIHtcbiAgICAgICAgbWFyZ2luOiAxNHB4IDE4cHggMDtcbiAgICAgICAgZ2FwOiA3cHg7XG4gICAgfVxufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0Q2hpbGRyZW4ge1xuICAgIGdyaWQtYXJlYTog8J+SrDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogMzAwO1xufVxuXG4vKiBDaGF0IG1lc3NhZ2VzIGFyZWEgKi9cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlcyB7XG4gICAgZ3JpZC1hcmVhOiDwn5KsO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICB6LWluZGV4OiAxMDtcbiAgICBwYWRkaW5nOiAyNHB4IDIwcHggMTZweDtcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgIG92ZXJmbG93LXg6IGhpZGRlbjtcbiAgICBzY3JvbGwtYmVoYXZpb3I6IHNtb290aDtcbn1cblxuLyogQ3VzdG9tIHNjcm9sbGJhciBzdHlsaW5nICovXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZXM6Oi13ZWJraXQtc2Nyb2xsYmFyIHtcbiAgICB3aWR0aDogNnB4O1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZXM6Oi13ZWJraXQtc2Nyb2xsYmFyLXRyYWNrIHtcbiAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2VzOjotd2Via2l0LXNjcm9sbGJhci10aHVtYiB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjIpO1xuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZXM6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMyk7XG59XG5cbi8qIEluZGl2aWR1YWwgY2hhdCBtZXNzYWdlICovXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LWVuZDtcbiAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBhbmltYXRpb246IG1lc3NhZ2VTbGlkZUluIDAuNHMgY3ViaWMtYmV6aWVyKDAuMjUsIDAuNDYsIDAuNDUsIDAuOTQpO1xuICAgIG1heC13aWR0aDogMTAwJTtcbn1cblxuLyogQWRkIHRvcCBtYXJnaW4gdG8gZmlyc3QgbWVzc2FnZSBpZiBhY3Rpb25zIGFyZSBwcmVzZW50IGFuZCBmaXJzdCBtZXNzYWdlIGlzIGxvbmcgKi9cbi5oYXNBY3Rpb25zQW5kRmlyc3RNZXNzYWdlSXNMb25nIHtcbiAgICBtYXJnaW4tdG9wOiA1NXB4O1xufVxuXG5Aa2V5ZnJhbWVzIG1lc3NhZ2VTbGlkZUluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDIwcHgpIHNjYWxlKDAuOTUpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKSBzY2FsZSgxKTtcbiAgICB9XG59XG5cbi5pc05vdENvbXBsZXRlTWVzc2FnZSB7XG4gICAgLyovXG4gICAgb3V0bGluZTogMXB4IGRvdHRlZCAjZmYwMDAwICFpbXBvcnRhbnQ7XG4gICAgLyoqL1xuXG4gICAgb3BhY2l0eTogMC43O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cblxuLk5vbkNvbXBsZXRlTWVzc2FnZUZpbGxlciB7XG4gICAgY29sb3I6IHRyYW5zcGFyZW50O1xufVxuXG4vKiBFbmhhbmNlZCBsb2FkaW5nIHN0YXRlcyBmb3IgbWVzc2FnZXMgKi9cbi5pc05vdENvbXBsZXRlTWVzc2FnZSAubWVzc2FnZVRleHQ6OmFmdGVyIHtcbiAgICBjb250ZW50OiAnJztcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgYm90dG9tOiA4cHg7XG4gICAgcmlnaHQ6IDEycHg7XG4gICAgd2lkdGg6IDIwcHg7XG4gICAgaGVpZ2h0OiA0cHg7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCB0cmFuc3BhcmVudCwgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjYpLCB0cmFuc3BhcmVudCk7XG4gICAgYm9yZGVyLXJhZGl1czogMnB4O1xuICAgIGFuaW1hdGlvbjogbG9hZGluZ1B1bHNlIDEuNXMgZWFzZS1pbi1vdXQgaW5maW5pdGU7XG59XG5cbkBrZXlmcmFtZXMgbG9hZGluZ1B1bHNlIHtcbiAgICAwJSxcbiAgICAxMDAlIHtcbiAgICAgICAgb3BhY2l0eTogMC4zO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWCgwLjgpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWCgxLjIpO1xuICAgIH1cbn1cblxuLyogVHlwaW5nIGluZGljYXRvciBmb3IgQUkgbWVzc2FnZXMgKi9cbi50eXBpbmdJbmRpY2F0b3Ige1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICAgIG1hcmdpbi1ib3R0b206IDIwcHg7XG4gICAgYW5pbWF0aW9uOiBtZXNzYWdlU2xpZGVJbiAwLjRzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KTtcbn1cblxuLnR5cGluZ0luZGljYXRvciAuYXZhdGFyIHtcbiAgICB3aWR0aDogNDBweDtcbiAgICBoZWlnaHQ6IDQwcHg7XG4gICAgbWFyZ2luOiAwIDEycHggNHB4O1xuICAgIGZsZXgtc2hyaW5rOiAwO1xufVxuXG4vKiBb44qX77iPXVxuLnR5cGluZ0luZGljYXRvciAuYXZhdGFyIGltZyB7XG4gICAgd2lkdGg6IDQwcHg7XG4gICAgYXNwZWN0LXJhdGlvOiAxIC8gMTtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgb2JqZWN0LWZpdDogY292ZXI7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2VlZjZmYjtcbiAgICBib3JkZXI6IDJweCBzb2xpZCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG59XG4qL1xuXG4udHlwaW5nQnViYmxlIHtcbiAgICBwYWRkaW5nOiAxNnB4IDIwcHg7XG4gICAgYm9yZGVyLXJhZGl1czogMjBweDtcbiAgICBib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiA2cHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjEpO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMSk7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDRweDtcbiAgICBtaW4taGVpZ2h0OiAyNHB4O1xufVxuXG4udHlwaW5nRG90cyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBnYXA6IDRweDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuXG4udHlwaW5nRG90IHtcbiAgICB3aWR0aDogOHB4O1xuICAgIGhlaWdodDogOHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjNmI3MjgwIDAlLCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuNikgMTAwJSk7XG4gICAgYW5pbWF0aW9uOiB0eXBpbmdCb3VuY2UgMS40cyBpbmZpbml0ZSBlYXNlLWluLW91dDtcbiAgICBib3gtc2hhZG93OiAwIDJweCA0cHggcmdiYSgwLCAwLCAwLCAwLjEpO1xufVxuXG4udHlwaW5nRG90Om50aC1jaGlsZCgxKSB7XG4gICAgYW5pbWF0aW9uLWRlbGF5OiAtMC4zMnM7XG59XG5cbi50eXBpbmdEb3Q6bnRoLWNoaWxkKDIpIHtcbiAgICBhbmltYXRpb24tZGVsYXk6IC0wLjE2cztcbn1cblxuLnR5cGluZ0RvdDpudGgtY2hpbGQoMykge1xuICAgIGFuaW1hdGlvbi1kZWxheTogMHM7XG59XG5cbkBrZXlmcmFtZXMgdHlwaW5nQm91bmNlIHtcbiAgICAwJSxcbiAgICA4MCUsXG4gICAgMTAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUoMC44KSB0cmFuc2xhdGVZKDApO1xuICAgICAgICBvcGFjaXR5OiAwLjU7XG4gICAgfVxuICAgIDQwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUoMS4yKSB0cmFuc2xhdGVZKC04cHgpO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UuaXNNZSB7XG4gICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICAgIGZsZXgtZGlyZWN0aW9uOiByb3ctcmV2ZXJzZTtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlLmlzTWUgLm1lc3NhZ2VUZXh0IHtcbiAgICBib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czogNnB4O1xufVxuXG4ucmF0aW5nU3RhciB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGZvbnQtc2l6ZTogMjBweDtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjJzO1xuICAgIGNvbG9yOiB2YXIoLS1zdGFyLWluYWN0aXZlLWNvbG9yLCAjY2NjKTtcbn1cblxuLnJhdGluZ1N0YXIuYWN0aXZlIHtcbiAgICBjb2xvcjogI2ZmZDcwMDtcbn1cblxuLyogU2VuZGVyIEF2YXRhciAqL1xuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLmF2YXRhciB7XG4gICAgd2lkdGg6IDQwcHg7XG4gICAgYXNwZWN0LXJhdGlvOiAxIC8gMTtcbiAgICBtYXJnaW46IDAgMTJweCA0cHg7XG4gICAgZmxleC1zaHJpbms6IDA7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4vKiBb44qX77iPXVxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLmF2YXRhciBpbWcge1xuICAgIHdpZHRoOiA0MHB4O1xuICAgIGFzcGVjdC1yYXRpbzogMSAvIDE7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIG9iamVjdC1maXQ6IGNvdmVyO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWF2YXRhci1iZy1jb2xvciwgI2VlZjZmYik7XG4gICAgYm9yZGVyOiAycHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjEpO1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjJzIGVhc2UsIGJveC1zaGFkb3cgMC4ycyBlYXNlO1xufVxuXG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5hdmF0YXIgaW1nOmhvdmVyIHtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEuMDUpO1xuICAgIGJveC1zaGFkb3c6IDAgNHB4IDEycHggcmdiYSgwLCAwLCAwLCAwLjE1KTtcbn1cbiovXG5cbi8qIE1lc3NhZ2UgdGV4dCBidWJibGUgKi9cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5tZXNzYWdlVGV4dCB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbWVzc2FnZS1iZy1jb2xvcik7XG4gICAgY29sb3I6IHZhcigtLW1lc3NhZ2UtdGV4dC1jb2xvcik7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHBhZGRpbmc6IDE0cHggMThweDtcbiAgICBib3JkZXItcmFkaXVzOiAyMHB4O1xuICAgIG1heC13aWR0aDogbWluKDcwJSwgNjAwcHgpO1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgbWFyZ2luLWJvdHRvbTogNHB4O1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMSk7XG4gICAgbGluZS1oZWlnaHQ6IDEuNTtcbiAgICB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbiAgICBmb250LXNpemU6IDE1cHg7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xufVxuXG4vKiBDb3B5IGJ1dHRvbiBzdHlsZXMgKi9cbi5jb3B5QnV0dG9uQ29udGFpbmVyIHtcbiAgICBmbG9hdDogcmlnaHQ7XG4gICAgdG9wOiA4cHg7XG4gICAgcmlnaHQ6IDEwcHg7XG4gICAgei1pbmRleDogMjtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG5cbiAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG59XG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAubWVzc2FnZVRleHQ6aG92ZXIgLmNvcHlCdXR0b25Db250YWluZXIsXG4uY29weUJ1dHRvbkNvbnRhaW5lcjpmb2N1cy13aXRoaW4ge1xuICAgIHZpc2liaWxpdHk6IHZpc2libGU7XG4gICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG59XG5cbi5jb3B5QnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMik7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2RkZDtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgcGFkZGluZzogMnB4IDVweDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgYm94LXNoYWRvdzogMCAxcHggNHB4IHJnYmEoMCwgMCwgMCwgMC4wNyk7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMTVzLCBib3gtc2hhZG93IDAuMTVzLCBib3JkZXIgMC4xNXM7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIG9wYWNpdHk6IDAuNztcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5jb3BpZWRUb29sdGlwIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogNTAlO1xuICAgIHRvcDogMTEwJTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XG4gICAgYmFja2dyb3VuZDogIzIyMjtcbiAgICBjb2xvcjogI2ZmZjtcbiAgICBwYWRkaW5nOiA2cHggMTZweDtcbiAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgZm9udC1zaXplOiAwLjk4ZW07XG4gICAgYm94LXNoYWRvdzogMCAycHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTgpO1xuICAgIG9wYWNpdHk6IDAuOTc7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgei1pbmRleDogMTAwO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgbWFyZ2luLXRvcDogNHB4O1xuICAgIGFuaW1hdGlvbjogY29waWVkVG9vbHRpcEZhZGVJbiAwLjJzO1xuICAgIG1heC13aWR0aDogMjIwcHg7XG4gICAgb3ZlcmZsb3ctd3JhcDogYnJlYWstd29yZDtcbiAgICB3b3JkLWJyZWFrOiBicmVhay13b3JkO1xufVxuXG4uY29waWVkVG9vbHRpcExlZnQge1xuICAgIGxlZnQ6IDAgIWltcG9ydGFudDtcbiAgICB0cmFuc2Zvcm06IG5vbmUgIWltcG9ydGFudDtcbn1cblxuLmNvcGllZFRvb2x0aXBSaWdodCB7XG4gICAgbGVmdDogYXV0byAhaW1wb3J0YW50O1xuICAgIHJpZ2h0OiAwICFpbXBvcnRhbnQ7XG4gICAgdHJhbnNmb3JtOiBub25lICFpbXBvcnRhbnQ7XG59XG5cbi8qIFJlbW92ZWQgcmlnaHQtYWxpZ25lZCBvdmVycmlkZSB0byBrZWVwIHRvb2x0aXAgcG9zaXRpb24gc3RhYmxlICovXG5cbkBrZXlmcmFtZXMgY29waWVkVG9vbHRpcEZhZGVJbiB7XG4gICAgZnJvbSB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKSB0cmFuc2xhdGVZKDhweCkgc2NhbGUoMC45Nyk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgb3BhY2l0eTogMC45NztcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC01MCUpIHRyYW5zbGF0ZVkoMCkgc2NhbGUoMSk7XG4gICAgfVxufVxuXG4uY29weUJ1dHRvbjpob3Zlcixcbi5jb3B5QnV0dG9uOmZvY3VzIHtcbiAgICBib3JkZXI6IDEuNXB4IHNvbGlkICNiYmI7XG4gICAgb3BhY2l0eTogMTtcbiAgICBib3gtc2hhZG93OiAwIDJweCA4cHggcmdiYSgwLCAxMzIsIDI1NSwgMC4xKTtcbn1cblxuLmNvcHlCdXR0b24gc3ZnIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbn1cblxuLm1lc3NhZ2VUZXh0IGgxIHtcbiAgICBmb250LXNpemU6IDJlbTtcbn1cblxuLm1lc3NhZ2VUZXh0IGgyIHtcbiAgICBmb250LXNpemU6IDEuNzVlbTtcbn1cblxuLm1lc3NhZ2VUZXh0IGgzIHtcbiAgICBmb250LXNpemU6IDEuNWVtO1xufVxuXG4ubWVzc2FnZVRleHQgaDQge1xuICAgIGZvbnQtc2l6ZTogMS4yNWVtO1xufVxuXG4ubWVzc2FnZVRleHQgaDUge1xuICAgIGZvbnQtc2l6ZTogMS4xZW07XG59XG5cbi5tZXNzYWdlVGV4dCB1bCB7XG4gICAgbGlzdC1zdHlsZTogZGlzYztcbiAgICBtYXJnaW4tbGVmdDogMjBweDtcbn1cblxuLm1lc3NhZ2VUZXh0IG9sIHtcbiAgICBsaXN0LXN0eWxlOiBkZWNpbWFsO1xuICAgIG1hcmdpbi1sZWZ0OiAyMHB4O1xufVxuXG4ubWVzc2FnZVRleHQgaW1nLFxuLm1lc3NhZ2VUZXh0IHByZSxcbi5tZXNzYWdlVGV4dCBibG9ja3F1b3RlLFxuLm1lc3NhZ2VUZXh0IHRhYmxlIHtcbiAgICBtYXJnaW4tdG9wOiAxMHB4O1xuICAgIG1hcmdpbi1ib3R0b206IDEwcHg7XG4gICAgYm9yZGVyLXJhZGl1czogOHB4O1xufVxuXG4ubWVzc2FnZVRleHQgcHJlIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiAjMDAwMDAwZmY7XG4gICAgZm9udC1zaXplOiBpbmhlcml0O1xuICAgIGxpbmUtaGVpZ2h0OiBpbmhlcml0O1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIHBhZGRpbmc6IDFlbTtcbn1cblxuLm1lc3NhZ2VUZXh0IGJsb2NrcXVvdGUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICAgIGJhY2tncm91bmQ6ICNmZmZmZmZjYztcbiAgICBmb250LXNpemU6IGluaGVyaXQ7XG4gICAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gICAgY29sb3I6ICMwMDA7XG4gICAgcGFkZGluZzogMWVtO1xufVxuXG4ubWVzc2FnZVRleHQgY29kZSB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1hcmdpbjogMDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICAgIGJhY2tncm91bmQ6ICNjY2NjY2M1NTtcbiAgICBmb250LXNpemU6IGluaGVyaXQ7XG4gICAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gICAgY29sb3I6IGluaGVyaXQ7XG59XG5cbi5tZXNzYWdlVGV4dCBwcmUgY29kZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMGNjO1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbn1cblxuLm1lc3NhZ2VUZXh0IC5jaGF0LWNvZGUtYmxvY2sge1xuICAgIGJhY2tncm91bmQ6ICMxODFjMjM7XG4gICAgY29sb3I6ICNmOGZhZmM7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxLjY7XG4gICAgb3ZlcmZsb3cteDogYXV0bztcbiAgICBib3JkZXItY29sb3I6ICMyMzI3MmY7XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4xMik7XG4gICAgZm9udC1mYW1pbHk6ICdGaXJhIE1vbm8nLCAnTWVubG8nLCAnQ29uc29sYXMnLCAnTGliZXJhdGlvbiBNb25vJywgbW9ub3NwYWNlO1xufVxuLm1lc3NhZ2VUZXh0IC5jaGF0LWNvZGUtYmxvY2sgY29kZSB7XG4gICAgYmFja2dyb3VuZDogbm9uZSAhaW1wb3J0YW50O1xuICAgIGNvbG9yOiBpbmhlcml0ICFpbXBvcnRhbnQ7XG4gICAgZm9udC1mYW1pbHk6IGluaGVyaXQgIWltcG9ydGFudDtcbiAgICBmb250LXNpemU6IGluaGVyaXQgIWltcG9ydGFudDtcbiAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgYm9yZGVyOiBub25lICFpbXBvcnRhbnQ7XG4gICAgYm94LXNoYWRvdzogbm9uZSAhaW1wb3J0YW50O1xuICAgIHdoaXRlLXNwYWNlOiBwcmU7XG4gICAgd29yZC1icmVhazogYnJlYWstd29yZDtcbiAgICBvdmVyZmxvdy14OiBhdXRvO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xufVxuLm1lc3NhZ2VUZXh0IHRhYmxlIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBib3JkZXItY29sbGFwc2U6IHNlcGFyYXRlO1xuICAgIGJvcmRlci1zcGFjaW5nOiAwO1xuICAgIG1hcmdpbjogMTZweCAwO1xuICAgIGJhY2tncm91bmQ6ICNmOGZhZmM7IC8qIFN0cm9uZ2VyIGxpZ2h0IGJhY2tncm91bmQgZm9yIGNvbnRyYXN0ICovXG4gICAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMDgpO1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBjb2xvcjogIzE3MjIzYjsgLyogRGFyayB0ZXh0IGZvciBjb250cmFzdCAqL1xufVxuLm1lc3NhZ2VUZXh0IHRoLFxuLm1lc3NhZ2VUZXh0IHRkIHtcbiAgICBwYWRkaW5nOiAxMHB4IDE2cHg7XG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNkMWRiZTg7XG4gICAgdGV4dC1hbGlnbjogbGVmdDtcbiAgICBjb2xvcjogIzE3MjIzYjsgLyogRW5zdXJlIHN0cm9uZyB0ZXh0IGNvbG9yIGZvciBhbGwgY2VsbHMgKi9cbiAgICBiYWNrZ3JvdW5kOiBub25lO1xufVxuLm1lc3NhZ2VUZXh0IHRoIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoOTBkZWcsICNlYWYzZmEgODAlLCAjZDFlM2Y4IDEwMCUpO1xuICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgY29sb3I6ICMxNzIyM2I7IC8qIFN0cm9uZyBoZWFkZXIgdGV4dCAqL1xuICAgIGJvcmRlci1ib3R0b206IDJweCBzb2xpZCAjYjVjN2RlO1xufVxuLm1lc3NhZ2VUZXh0IHRyOmxhc3QtY2hpbGQgdGQge1xuICAgIGJvcmRlci1ib3R0b206IG5vbmU7XG59XG4ubWVzc2FnZVRleHQgdHI6bnRoLWNoaWxkKGV2ZW4pIHRkIHtcbiAgICBiYWNrZ3JvdW5kOiAjZWFmM2ZhO1xufVxuLm1lc3NhZ2VUZXh0IHRyOmhvdmVyIHRkIHtcbiAgICBiYWNrZ3JvdW5kOiAjY2JlMGY3O1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4ycztcbn1cbi5tZXNzYWdlVGV4dCB0YWJsZSB7XG4gICAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuLm1lc3NhZ2VUZXh0IHRoOmZpcnN0LWNoaWxkLFxuLm1lc3NhZ2VUZXh0IHRkOmZpcnN0LWNoaWxkIHtcbiAgICBib3JkZXItdG9wLWxlZnQtcmFkaXVzOiAxMnB4O1xufVxuLm1lc3NhZ2VUZXh0IHRoOmxhc3QtY2hpbGQsXG4ubWVzc2FnZVRleHQgdGQ6bGFzdC1jaGlsZCB7XG4gICAgYm9yZGVyLXRvcC1yaWdodC1yYWRpdXM6IDEycHg7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5tZXNzYWdlVGV4dDpob3ZlciB7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTZweCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMXB4KTtcbn1cblxuLyogQXR0YWNobWVudHMgc3R5bGVzICovXG4uYXR0YWNobWVudHMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC13cmFwOiB3cmFwO1xuICAgIGdhcDogOHB4O1xuICAgIG1hcmdpbi10b3A6IDEwcHg7XG4gICAgcGFkZGluZy10b3A6IDEwcHg7XG4gICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4yKTtcbn1cblxuLmF0dGFjaG1lbnQge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDZweDtcbiAgICBwYWRkaW5nOiA2cHggMTJweDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMik7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjMpO1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgZm9udC1zaXplOiAxM3B4O1xuICAgIGNvbG9yOiBpbmhlcml0O1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIG1heC13aWR0aDogMjAwcHg7XG59XG5cbi5hdHRhY2htZW50OmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMyk7XG4gICAgYm9yZGVyLWNvbG9yOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuNSk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0xcHgpO1xufVxuXG4uYXR0YWNobWVudEljb24ge1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBvcGFjaXR5OiAwLjg7XG59XG5cbi5hdHRhY2htZW50TmFtZSB7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xufVxuXG4vKiBNZXNzYWdlIGJ1dHRvbnMgY29udGFpbmVyICovXG4ubWVzc2FnZUJ1dHRvbnMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC13cmFwOiB3cmFwO1xuICAgIGdhcDogOHB4O1xuICAgIG1hcmdpbi10b3A6IDEycHg7XG4gICAgcGFkZGluZy10b3A6IDEycHg7XG4gICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHJnYmEoMTI1IDEyNSAxMjUgLyAwLjgzKTtcbn1cblxuLyogSW5kaXZpZHVhbCBtZXNzYWdlIGJ1dHRvbiAqL1xuLm1lc3NhZ2VCdXR0b24ge1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgcGFkZGluZzogOHB4IDE0cHg7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjEpO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMTI1LCAxMjUsIDEyNSwgMC45KTtcbiAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgIGZvbnQtc2l6ZTogMTNweDtcbiAgICBmb250LXdlaWdodDogNTAwO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigxMHB4KTtcbiAgICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIHRvdWNoLWFjdGlvbjogbWFuaXB1bGF0aW9uO1xuICAgIHVzZXItc2VsZWN0OiBub25lO1xufVxuXG4ubWVzc2FnZUJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAxMzIsIDI1NSwgMC4xKTtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoMCwgMTMyLCAyNTUsIDAuMyk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0xcHgpO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDhweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjE1KTtcbn1cblxuLm1lc3NhZ2VCdXR0b246YWN0aXZlIHtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAuOTgpO1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjFzIGVhc2U7XG59XG5cbi8qIFJlbW92ZSBkZWZhdWx0IG1hcmtkb3duIHN0eWxlcyBmcm9tIGJ1dHRvbiBjb250ZW50ICovXG4ubWVzc2FnZUJ1dHRvbiBwIHtcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMDtcbiAgICBsaW5lLWhlaWdodDogaW5oZXJpdDtcbn1cblxuLm1lc3NhZ2VCdXR0b24gc3Ryb25nIHtcbiAgICBmb250LXdlaWdodDogNjAwO1xufVxuXG4ubWVzc2FnZUJ1dHRvbiBlbSB7XG4gICAgZm9udC1zdHlsZTogaXRhbGljO1xufVxuXG4vKiBSYXRpbmcgc3lzdGVtICovXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAucmF0aW5nIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgYm90dG9tOiAtOHB4O1xuICAgIHJpZ2h0OiA4cHg7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBnYXA6IDJweDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIG1pbi13aWR0aDogMjRweDtcbiAgICB6LWluZGV4OiAxO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwgMCwgMCwgMC44KTtcbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIHBhZGRpbmc6IDRweCA2cHg7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xuICAgIG9wYWNpdHk6IDA7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDRweCk7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuM3MgY3ViaWMtYmV6aWVyKDAuMjUsIDAuNDYsIDAuNDUsIDAuOTQpO1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZTpob3ZlciAucmF0aW5nIHtcbiAgICBvcGFjaXR5OiAxO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKTtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLnJhdGluZzpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjkpO1xuICAgIHBhZGRpbmc6IDZweCA4cHg7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMyk7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5yYXRpbmcgc3BhbiB7XG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMnMgZWFzZSwgY29sb3IgMC4ycyBlYXNlO1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgZm9udC1zaXplOiAxNnB4O1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAucmF0aW5nOmhvdmVyIHNwYW4ge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4xKTtcbn1cblxuLyogQ2hhdCBpbnB1dCBhcmVhICovXG4uY2hhdE1haW5GbG93IC5jaGF0SW5wdXQge1xuICAgIHotaW5kZXg6IDEwO1xuICAgIGdyaWQtYXJlYTog8J+TnTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwYWRkaW5nOiAyMHB4O1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigyMHB4KTtcbiAgICBib3JkZXItdG9wOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjEpO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDEycHg7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4vKiBGaWxlIHVwbG9hZCBkcmFnLWFuZC1kcm9wIHN0eWxlcyAqL1xuLmNoYXRNYWluRmxvdyAuY2hhdElucHV0LmRyYWdPdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gdG9wLCByZ2JhKDAsIDEzMiwgMjU1LCAwLjEpIDAlLCByZ2JhKDAsIDEzMiwgMjU1LCAwLjA1KSAxMDAlKTtcbiAgICBib3JkZXItdG9wOiAycHggc29saWQgcmdiYSgwLCAxMzIsIDI1NSwgMC4zKTtcbn1cblxuLyogRmlsZSBwcmV2aWV3IGNvbnRhaW5lciAqL1xuLmZpbGVQcmV2aWV3Q29udGFpbmVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtd3JhcDogd3JhcDtcbiAgICBnYXA6IDhweDtcbiAgICBtYXJnaW4tYm90dG9tOiA4cHg7XG59XG5cbi8qIEluZGl2aWR1YWwgZmlsZSBwcmV2aWV3ICovXG4uZmlsZVByZXZpZXcge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDhweDtcbiAgICBwYWRkaW5nOiA4cHggMTJweDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjIpO1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG59XG5cbi5maWxlUHJldmlldzpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjE1KTtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4zKTtcbn1cblxuLmZpbGVJY29uIHtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgb3BhY2l0eTogMC43O1xufVxuXG4uZmlsZUluZm8ge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDJweDtcbiAgICBtaW4td2lkdGg6IDA7XG59XG5cbi5maWxlTmFtZSB7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICBjb2xvcjogYmxhY2s7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIG1heC13aWR0aDogMTUwcHg7XG59XG5cbi5maWxlU2l6ZSB7XG4gICAgY29sb3I6ICM2YjcyODA7XG4gICAgZm9udC1zaXplOiAxMXB4O1xufVxuXG4ucmVtb3ZlRmlsZUJ1dHRvbiB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIHdpZHRoOiAyMHB4O1xuICAgIGhlaWdodDogMjBweDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDAsIDAsIDAuMSk7XG4gICAgY29sb3I6ICNmZjQ0NDQ7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIGZsZXgtc2hyaW5rOiAwO1xufVxuXG4ucmVtb3ZlRmlsZUJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDAsIDAsIDAuMik7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLjEpO1xufVxuXG4vKiBJbnB1dCBjb250YWluZXIgZm9yIHRleHRhcmVhIGFuZCBidXR0b25zICovXG4uaW5wdXRDb250YWluZXIge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDEycHg7XG59XG5cbi5pbnB1dENvbnRhaW5lciB0ZXh0YXJlYTo6cGxhY2Vob2xkZXIge1xuICAgIGNvbG9yOiBpbmhlcml0O1xuICAgIG9wYWNpdHk6IDAuNztcbn1cblxuLyogQXR0YWNobWVudCBidXR0b24gKi9cbi5hdHRhY2htZW50QnV0dG9uIHtcbiAgICB3aWR0aDogNDBweDtcbiAgICBoZWlnaHQ6IDQwcHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjIpO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4wNSk7XG4gICAgY29sb3I6ICM2YjcyODA7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG4gICAgZmxleC1zaHJpbms6IDA7XG59XG5cbi5hdHRhY2htZW50QnV0dG9uOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDEzMiwgMjU1LCAwLjEpO1xuICAgIGJvcmRlci1jb2xvcjogcmdiYSgwLCAxMzIsIDI1NSwgMC4zKTtcbiAgICBjb2xvcjogIzAwODRmZjtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEuMDUpO1xufVxuXG4uYXR0YWNobWVudEJ1dHRvbjpkaXNhYmxlZCB7XG4gICAgb3BhY2l0eTogMC41O1xuICAgIGN1cnNvcjogbm90LWFsbG93ZWQ7XG4gICAgdHJhbnNmb3JtOiBub25lO1xufVxuXG4vKiBWb2ljZSBCdXR0b24gKi9cbi52b2ljZUJ1dHRvbiB7XG4gICAgd2lkdGg6IDQwcHg7XG4gICAgaGVpZ2h0OiA0MHB4O1xuICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4yKTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMDUpO1xuICAgIGNvbG9yOiAjNmI3MjgwO1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xuICAgIGZsZXgtc2hyaW5rOiAwO1xufVxuXG4udm9pY2VCdXR0b246aG92ZXIge1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwgMTMyLCAyNTUsIDAuMSk7XG4gICAgYm9yZGVyLWNvbG9yOiByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpO1xuICAgIGNvbG9yOiAjMDA4NGZmO1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4wNSk7XG59XG5cbi52b2ljZUJ1dHRvbkFjdGl2ZSB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDAsIDAsIDAuMSkgIWltcG9ydGFudDtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoMjU1LCAwLCAwLCAwLjMpICFpbXBvcnRhbnQ7XG4gICAgY29sb3I6ICNmZjAwMDAgIWltcG9ydGFudDtcbiAgICBhbmltYXRpb246IHZvaWNlUmVjb3JkaW5nUHVsc2UgMS41cyBpbmZpbml0ZTtcbn1cblxuQGtleWZyYW1lcyB2b2ljZVJlY29yZGluZ1B1bHNlIHtcbiAgICAwJSB7XG4gICAgICAgIGJveC1zaGFkb3c6IDAgMCAwIDAgcmdiYSgyNTUsIDAsIDAsIDAuNCk7XG4gICAgfVxuICAgIDcwJSB7XG4gICAgICAgIGJveC1zaGFkb3c6IDAgMCAwIDEwcHggcmdiYSgyNTUsIDAsIDAsIDApO1xuICAgIH1cbiAgICAxMDAlIHtcbiAgICAgICAgYm94LXNoYWRvdzogMCAwIDAgMCByZ2JhKDI1NSwgMCwgMCwgMCk7XG4gICAgfVxufVxuXG4vKiBVcGxvYWQgcHJvZ3Jlc3MgaW5kaWNhdG9yICovXG4udXBsb2FkUHJvZ3Jlc3Mge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDEycHg7XG4gICAgcGFkZGluZzogOHB4IDEycHg7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAxMzIsIDI1NSwgMC4xKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDEzMiwgMjU1LCAwLjIpO1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICBmb250LXNpemU6IDEzcHg7XG4gICAgY29sb3I6ICMwMDg0ZmY7XG59XG5cbi51cGxvYWRQcm9ncmVzc0JhciB7XG4gICAgZmxleDogMTtcbiAgICBoZWlnaHQ6IDRweDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDEzMiwgMjU1LCAwLjIpO1xuICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuXG4udXBsb2FkUHJvZ3Jlc3NGaWxsIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCAjMDA4NGZmLCByZ2JhKDAsIDEzMiwgMjU1LCAwLjgpKTtcbiAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgYW5pbWF0aW9uOiB1cGxvYWRQcm9ncmVzcyAxLjVzIGVhc2UtaW4tb3V0IGluZmluaXRlO1xufVxuXG5Aa2V5ZnJhbWVzIHVwbG9hZFByb2dyZXNzIHtcbiAgICAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtMTAwJSk7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwJSk7XG4gICAgfVxuICAgIDEwMCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSk7XG4gICAgfVxufVxuXG4vKiBEcmFnIG92ZXJsYXkgKi9cbi5kcmFnT3ZlcmxheSB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDEzMiwgMjU1LCAwLjEpO1xuICAgIGJvcmRlcjogMnB4IGRhc2hlZCByZ2JhKDAsIDEzMiwgMjU1LCAwLjUpO1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigxMHB4KTtcbiAgICB6LWluZGV4OiAyMDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLmRyYWdPdmVybGF5Q29udGVudCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAxMnB4O1xuICAgIGNvbG9yOiAjMDA4NGZmO1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xufVxuXG4uZHJhZ092ZXJsYXlDb250ZW50IHN2ZyB7XG4gICAgb3BhY2l0eTogMC43O1xufVxuXG4vKiBDaGF0IGlucHV0IGZpZWxkICovXG4uY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgdGV4dGFyZWEge1xuICAgIGZsZXg6IDE7XG4gICAgcGFkZGluZzogMTZweCAyMHB4O1xuXG4gICAgb3V0bGluZTogbm9uZTtcbiAgICBib3JkZXItcmFkaXVzOiAyNXB4O1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4wNSk7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDIwcHgpO1xuICAgIGNvbG9yOiBibGFjaztcbiAgICBtaW4td2lkdGg6IDIwMHB4O1xuICAgIG1heC1oZWlnaHQ6IDEyMHB4O1xuICAgIGZvbnQtc2l6ZTogMTVweDtcbiAgICBsaW5lLWhlaWdodDogMS40O1xuICAgIHJlc2l6ZTogbm9uZTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCk7XG4gICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICB0b3VjaC1hY3Rpb246IG1hbmlwdWxhdGlvbjtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHRleHRhcmVhOmZvY3VzIHtcbiAgICBib3JkZXItY29sb3I6ICMwMDg0ZmY7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjA4KTtcbiAgICBib3gtc2hhZG93OiAwIDAgMCA0cHggcmdiYSgwLCAxMzIsIDI1NSwgMC4xKSwgMCA4cHggMzJweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjE1KTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTJweCk7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCB0ZXh0YXJlYTpkaXNhYmxlZCB7XG4gICAgb3BhY2l0eTogMC42O1xuICAgIGN1cnNvcjogbm90LWFsbG93ZWQ7XG4gICAgdHJhbnNmb3JtOiBub25lO1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgdGV4dGFyZWE6OnBsYWNlaG9sZGVyIHtcbiAgICBjb2xvcjogaW5oZXJpdDtcbiAgICBvcGFjaXR5OiAwLjc7XG59XG5cbi8qIENoYXQgc2VuZCBidXR0b24gKi9cbi5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCBidXR0b24ge1xuICAgIHdpZHRoOiA0OHB4O1xuICAgIGhlaWdodDogNDhweDtcbiAgICBtYXJnaW46IDAgIWltcG9ydGFudDtcbiAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG5cbiAgICBib3JkZXI6IG5vbmU7XG4gICAgLyogYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzAwODRmZiAwJSwgIzAwNjZjYyAxMDAlKTsgKi9cbiAgICAvKiA8LSBOb3RlOiBCYWNrZ3JvdW5kIGlzIHNldCBpbiB0aGUgaW5saW5lIHN0eWxlICovXG4gICAgY29sb3I6ICNmZmZmZmY7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJSAhaW1wb3J0YW50O1xuICAgIGFzcGVjdC1yYXRpbzogMSAvIDE7XG4gICAgbWluLXdpZHRoOiB1bnNldCAhaW1wb3J0YW50O1xuICAgIG1pbi1oZWlnaHQ6IHVuc2V0ICFpbXBvcnRhbnQ7XG4gICAgcGFkZGluZy1sZWZ0OiB1bnNldDtcbiAgICBwYWRkaW5nLXJpZ2h0OiB1bnNldDtcblxuICAgIHRyYW5zaXRpb246IGFsbCAwLjNzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KTtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxNnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMyk7XG4gICAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICB0b3VjaC1hY3Rpb246IG1hbmlwdWxhdGlvbjtcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgICBvdmVyZmxvdzogdmlzaWJsZTtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IGJ1dHRvbiBpbWcge1xuICAgIHdpZHRoOiA1MCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIG9iamVjdC1maXQ6IGNvbnRhaW47XG59XG5cbi8qIFNjcm9sbCB0byBib3R0b20gYnV0dG9uICovXG5cbi5zY3JvbGxUb0JvdHRvbUNvbnRhaW5lciB7XG4gICAgLyovXG4gICAgb3V0bGluZTogMXB4IGRvdHRlZCByZWQ7XG4gICAgLyoqL1xuXG4gICAgei1pbmRleDogMjA7XG4gICAgZ3JpZC1hcmVhOiDwn5OdO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xuXG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi5zY3JvbGxUb0JvdHRvbUNvbnRhaW5lciAuc2Nyb2xsVG9Cb3R0b20ge1xuICAgIHBvaW50ZXItZXZlbnRzOiBhbGw7XG5cbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtMTUwJSk7XG4gICAgd2lkdGg6IDQ4cHg7XG4gICAgaGVpZ2h0OiA0OHB4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAgMCAwIC8gMC41KTtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoM3B4KTtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gICAgY29sb3I6IHdoaXRlO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIHRvdWNoLWFjdGlvbjogbWFuaXB1bGF0aW9uO1xuICAgIHVzZXItc2VsZWN0OiBub25lO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjNzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KTtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxNnB4IHJnYmEoMCwgMCwgMCwgMC4zKTtcbiAgICBhbmltYXRpb246IHNjcm9sbEJ1dHRvblNsaWRlSW4gMC4zcyBlYXNlLW91dDtcbn1cblxuQGtleWZyYW1lcyBzY3JvbGxCdXR0b25TbGlkZUluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgMjBweCkgc2NhbGUoMC44KTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwLjk7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIDApIHNjYWxlKDEpO1xuICAgIH1cbn1cblxuLnNjcm9sbFRvQm90dG9tOmhvdmVyIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtMTYwJSkgc2NhbGUoMS4wNSk7XG59XG5cbi5zY3JvbGxUb0JvdHRvbTphY3RpdmUge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC0xNjAlKSBzY2FsZSgwLjk1KTtcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4xcyBlYXNlO1xufVxuXG4vKiBSYXRpbmcgbW9kYWwgKi9cbi5yYXRpbmdNb2RhbCB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIGJvdHRvbTogMDtcblxuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC42KTtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoOHB4KTtcblxuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICB6LWluZGV4OiAxMDAwO1xuICAgIGFuaW1hdGlvbjogbW9kYWxGYWRlSW4gMC4zcyBlYXNlLW91dDtcbn1cblxuQGtleWZyYW1lcyBtb2RhbEZhZGVJbiB7XG4gICAgZnJvbSB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigwcHgpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cig4cHgpO1xuICAgIH1cbn1cblxuLnJhdGluZ01vZGFsQ29udGVudCB7XG4gICAgYmFja2dyb3VuZDogI2ZmZmZmZjtcbiAgICBjb2xvcjogIzBmMTcyNDtcbiAgICBwYWRkaW5nOiAzMnB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgd2lkdGg6IDkwJTtcbiAgICBtYXgtd2lkdGg6IDQ4MHB4O1xuICAgIGJveC1zaGFkb3c6IDAgMjBweCA2MHB4IHJnYmEoMCwgMCwgMCwgMC4zKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDIwcHgpO1xuICAgIGFuaW1hdGlvbjogbW9kYWxTbGlkZUluIDAuM3MgY3ViaWMtYmV6aWVyKDAuMjUsIDAuNDYsIDAuNDUsIDAuOTQpO1xuXG4gICAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWYsICdPcGVuTW9qaUJsYWNrJztcbiAgICAvKiA8LSBUT0RPOiBb8J+noF1b8J+OsV0gQmV0dGVyLCBkZWZpbmUgb3RoZXIgZm9udHMgKi9cbn1cblxuQGtleWZyYW1lcyBtb2RhbFNsaWRlSW4ge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMjBweCkgc2NhbGUoMC45NSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDApIHNjYWxlKDEpO1xuICAgIH1cbn1cblxuLnJhdGluZ01vZGFsQ29udGVudCBoMyB7XG4gICAgbWFyZ2luOiAwIDAgMjRweCAwO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBjb2xvcjogYmxhY2s7XG4gICAgZm9udC1zaXplOiAyMHB4O1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG59XG5cbi5zdGFycyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBnYXA6IDhweDtcbiAgICBtYXJnaW4tYm90dG9tOiAyNHB4O1xufVxuXG4uc3RhcnMgc3BhbiB7XG4gICAgZm9udC1zaXplOiAyOHB4O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIHBhZGRpbmc6IDRweDtcbiAgICBib3JkZXItcmFkaXVzOiA4cHg7XG59XG5cbi5zdGFycyBzcGFuOmhvdmVyIHtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEuMik7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDIxNSwgMCwgMC4xKTtcbn1cblxuLnJhdGluZ01vZGFsU3RhciB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGZvbnQtc2l6ZTogMjRweDtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjJzO1xufVxuXG4ucmF0aW5nSW5wdXQge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIG1pbi1oZWlnaHQ6IDEwMHB4O1xuICAgIHBhZGRpbmc6IDE2cHg7XG4gICAgYm9yZGVyOiAycHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjEpO1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgbWFyZ2luLWJvdHRvbTogMThweDtcbiAgICByZXNpemU6IHZlcnRpY2FsO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4wNSk7XG4gICAgY29sb3I6ICMwYjEyMjA7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxLjU7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbn1cblxuLnJhdGluZ0lucHV0OmZvY3VzIHtcbiAgICBib3JkZXItY29sb3I6ICMwMDg0ZmY7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjA4KTtcbiAgICBib3gtc2hhZG93OiAwIDAgMCA0cHggcmdiYSgwLCAxMzIsIDI1NSwgMC4xKTtcbiAgICBvdXRsaW5lOiBub25lO1xufVxuXG4ucmF0aW5nSW5wdXRbcmVhZG9ubHldIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuNSk7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjAxKTtcbn1cblxuLnJhdGluZ0FjdGlvbnMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbiAgICBnYXA6IDEycHg7XG59XG5cbi5yYXRpbmdBY3Rpb25zIGJ1dHRvbiB7XG4gICAgcGFkZGluZzogMTJweCAyNHB4O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBmb250LXdlaWdodDogNTAwO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG4gICAgbWluLXdpZHRoOiA4MHB4O1xufVxuXG4ucmF0aW5nQWN0aW9ucyBidXR0b246Zmlyc3QtY2hpbGQge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4xKTtcbiAgICBjb2xvcjogIzBiMTIyMDtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMik7XG59XG5cbi5yYXRpbmdBY3Rpb25zIGJ1dHRvbjpmaXJzdC1jaGlsZDpob3Zlcjpub3QoOmRpc2FibGVkKSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjIpO1xuICAgIGNvbG9yOiAjMGIxMjIwO1xufVxuXG4ucmF0aW5nQWN0aW9ucyBidXR0b246bGFzdC1jaGlsZCB7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzAwODRmZiAwJSwgIzAwNjZjYyAxMDAlKTtcbiAgICBjb2xvcjogI2ZmZmZmZjtcbn1cblxuLnJhdGluZ0FjdGlvbnMgYnV0dG9uOmxhc3QtY2hpbGQ6aG92ZXI6bm90KDpkaXNhYmxlZCkge1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMwMDcxZDEgMCUsICMwMDUyYTMgMTAwJSk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0xcHgpO1xuICAgIGJveC1zaGFkb3c6IDAgNHB4IDEycHggcmdiYSgwLCAxMzIsIDI1NSwgMC4zKTtcbn1cblxuLnJhdGluZ0FjdGlvbnMgYnV0dG9uOmxhc3QtY2hpbGQ6ZGlzYWJsZWQge1xuICAgIG9wYWNpdHk6IDAuNTtcbiAgICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xufVxuXG4vKiBOZXcgY2hhdCBidXR0b24gc3R5bGluZyAtIE1hdGNoZXMgdGhlIHNsZWVrIGNoYXQgbWVzc2FnZSBkZXNpZ24gKi9cbi5jaGF0QnV0dG9uIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtZmxleCAhaW1wb3J0YW50O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXIgIWltcG9ydGFudDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlciAhaW1wb3J0YW50O1xuICAgIGdhcDogOHB4ICFpbXBvcnRhbnQ7XG4gICAgcGFkZGluZzogMTJweCAxNnB4ICFpbXBvcnRhbnQ7XG4gICAgbWFyZ2luOiAwICFpbXBvcnRhbnQ7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzAwODRmZiAwJSwgIzAwNjZjYyAxMDAlKSAhaW1wb3J0YW50O1xuICAgIGNvbG9yOiAjZmZmZmZmICFpbXBvcnRhbnQ7XG4gICAgYm9yZGVyOiBub25lICFpbXBvcnRhbnQ7XG4gICAgYm9yZGVyLXJhZGl1czogMjBweCAhaW1wb3J0YW50O1xuICAgIGZvbnQtc2l6ZTogMTNweCAhaW1wb3J0YW50O1xuICAgIGZvbnQtd2VpZ2h0OiA2MDAgIWltcG9ydGFudDtcbiAgICBsaW5lLWhlaWdodDogMS4zICFpbXBvcnRhbnQ7XG4gICAgY3Vyc29yOiBwb2ludGVyICFpbXBvcnRhbnQ7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuM3MgY3ViaWMtYmV6aWVyKDAuMjUsIDAuNDYsIDAuNDUsIDAuOTQpICFpbXBvcnRhbnQ7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTZweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpICFpbXBvcnRhbnQ7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDIwcHgpICFpbXBvcnRhbnQ7XG4gICAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudCAhaW1wb3J0YW50O1xuICAgIHRvdWNoLWFjdGlvbjogbWFuaXB1bGF0aW9uICFpbXBvcnRhbnQ7XG4gICAgdXNlci1zZWxlY3Q6IG5vbmUgIWltcG9ydGFudDtcbiAgICBtaW4taGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgbWluLXdpZHRoOiAxMTBweCAhaW1wb3J0YW50O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZSAhaW1wb3J0YW50O1xuICAgIG92ZXJmbG93OiBoaWRkZW4gIWltcG9ydGFudDtcbn1cblxuLmNoYXRCdXR0b246OmJlZm9yZSB7XG4gICAgY29udGVudDogJyc7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAtMTAwJTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCB0cmFuc3BhcmVudCwgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjIpLCB0cmFuc3BhcmVudCk7XG4gICAgdHJhbnNpdGlvbjogbGVmdCAwLjVzIGVhc2U7XG59XG5cbi5jaGF0QnV0dG9uOmhvdmVyOjpiZWZvcmUge1xuICAgIGxlZnQ6IDEwMCU7XG59XG5cbi5jaGF0QnV0dG9uOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjMDA5OWZmIDAlLCAjMDA3N2RkIDEwMCUpO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMnB4KSBzY2FsZSgxLjAyKTtcbiAgICBib3gtc2hhZG93OiAwIDhweCAyNHB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuNCk7XG59XG5cbi5jaGF0QnV0dG9uOmFjdGl2ZSB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLjk4KSB0cmFuc2xhdGVZKC0xcHgpO1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjFzIGVhc2U7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTZweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpO1xufVxuXG4uY2hhdEJ1dHRvbjpmb2N1cyB7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxNnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMyksIDAgMCAwIDNweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpO1xufVxuXG4uY2hhdEJ1dHRvbiBzdmcge1xuICAgIHdpZHRoOiAxNnB4O1xuICAgIGhlaWdodDogMTZweDtcbiAgICBmbGV4LXNocmluazogMDtcbiAgICBvcGFjaXR5OiAxO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjNzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KTtcbiAgICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMXB4IDJweCByZ2JhKDAsIDAsIDAsIDAuMikpO1xufVxuXG4uY2hhdEJ1dHRvbjpob3ZlciBzdmcge1xuICAgIHRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgc2NhbGUoMS4xKTtcbiAgICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMnB4IDRweCByZ2JhKDAsIDAsIDAsIDAuMykpO1xufVxuXG4uY2hhdEJ1dHRvblRleHQge1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIHRleHQtc2hhZG93OiAwIDFweCAycHggcmdiYSgwLCAwLCAwLCAwLjEpO1xuICAgIG9wYWNpdHk6IDE7XG59XG5cbi5jaGF0QnV0dG9uOmhvdmVyIC5jaGF0QnV0dG9uVGV4dCB7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDFweCk7XG59XG5cbi8qIFVzZSB0ZW1wbGF0ZSBidXR0b24gc3R5bGluZyAtIG1hdGNoZXMgdGhlIGNoYXRCdXR0b24gYW5kIHNhdmVCdXR0b24gKi9cbi51c2VUZW1wbGF0ZUJ1dHRvbiB7XG4gICAgZGlzcGxheTogaW5saW5lLWZsZXggIWltcG9ydGFudDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyICFpbXBvcnRhbnQ7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXIgIWltcG9ydGFudDtcbiAgICBnYXA6IDhweCAhaW1wb3J0YW50O1xuICAgIHBhZGRpbmc6IDEycHggMTZweCAhaW1wb3J0YW50O1xuICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMwMDg0ZmYgMCUsICMwMDY2Y2MgMTAwJSkgIWltcG9ydGFudDtcbiAgICBjb2xvcjogI2ZmZmZmZiAhaW1wb3J0YW50O1xuICAgIGJvcmRlcjogbm9uZSAhaW1wb3J0YW50O1xuICAgIGJvcmRlci1yYWRpdXM6IDIwcHggIWltcG9ydGFudDtcbiAgICBmb250LXNpemU6IDEzcHggIWltcG9ydGFudDtcbiAgICBmb250LXdlaWdodDogNjAwICFpbXBvcnRhbnQ7XG4gICAgbGluZS1oZWlnaHQ6IDEuMyAhaW1wb3J0YW50O1xuICAgIGN1cnNvcjogcG9pbnRlciAhaW1wb3J0YW50O1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjNzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KSAhaW1wb3J0YW50O1xuICAgIGJveC1zaGFkb3c6IDAgNHB4IDE2cHggcmdiYSgwLCAxMzIsIDI1NSwgMC4zKSAhaW1wb3J0YW50O1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigyMHB4KSAhaW1wb3J0YW50O1xuICAgIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogdHJhbnNwYXJlbnQgIWltcG9ydGFudDtcbiAgICB0b3VjaC1hY3Rpb246IG1hbmlwdWxhdGlvbiAhaW1wb3J0YW50O1xuICAgIHVzZXItc2VsZWN0OiBub25lICFpbXBvcnRhbnQ7XG4gICAgbWluLWhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgIG1pbi13aWR0aDogMTEwcHggIWltcG9ydGFudDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmUgIWltcG9ydGFudDtcbiAgICBvdmVyZmxvdzogaGlkZGVuICFpbXBvcnRhbnQ7XG59XG5cbi51c2VUZW1wbGF0ZUJ1dHRvbjo6YmVmb3JlIHtcbiAgICBjb250ZW50OiAnJztcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IC0xMDAlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoOTBkZWcsIHRyYW5zcGFyZW50LCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMiksIHRyYW5zcGFyZW50KTtcbiAgICB0cmFuc2l0aW9uOiBsZWZ0IDAuNXMgZWFzZTtcbn1cblxuLnVzZVRlbXBsYXRlQnV0dG9uOmhvdmVyOjpiZWZvcmUge1xuICAgIGxlZnQ6IDEwMCU7XG59XG5cbi51c2VUZW1wbGF0ZUJ1dHRvbjpob3Zlcjpub3QoOmRpc2FibGVkKSB7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzAwOTlmZiAwJSwgIzAwNzdkZCAxMDAlKTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTJweCkgc2NhbGUoMS4wMik7XG4gICAgYm94LXNoYWRvdzogMCA4cHggMjRweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjQpO1xufVxuXG4udXNlVGVtcGxhdGVCdXR0b246YWN0aXZlIHtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAuOTgpIHRyYW5zbGF0ZVkoLTFweCk7XG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMXMgZWFzZTtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxNnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMyk7XG59XG5cbi51c2VUZW1wbGF0ZUJ1dHRvbjpmb2N1cyB7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxNnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMyksIDAgMCAwIDNweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpO1xufVxuXG4udXNlVGVtcGxhdGVCdXR0b24gc3ZnIHtcbiAgICB3aWR0aDogMTZweDtcbiAgICBoZWlnaHQ6IDE2cHg7XG4gICAgZmxleC1zaHJpbms6IDA7XG4gICAgb3BhY2l0eTogMTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCk7XG4gICAgZmlsdGVyOiBkcm9wLXNoYWRvdygwIDFweCAycHggcmdiYSgwLCAwLCAwLCAwLjIpKTtcbn1cblxuLnVzZVRlbXBsYXRlQnV0dG9uOmhvdmVyIHN2ZyB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLjEpO1xuICAgIGZpbHRlcjogZHJvcC1zaGFkb3coMCAycHggNHB4IHJnYmEoMCwgMCwgMCwgMC4zKSk7XG59XG5cbi51c2VUZW1wbGF0ZUJ1dHRvbjpob3ZlciAuY2hhdEJ1dHRvblRleHQge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgxcHgpO1xufVxuXG4uc2F2ZUJ1dHRvbkNvbnRhaW5lciB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cblxuLnNhdmVNZW51IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAxMDAlO1xuICAgIGxlZnQ6IDA7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZGRkO1xuICAgIHotaW5kZXg6IDEwO1xuICAgIG1pbi13aWR0aDogMTIwcHg7XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4wOCk7XG59XG5cbi5zYXZlTWVudUl0ZW0ge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBhZGRpbmc6IDhweCAxNnB4O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGNvbG9yOiAjMTExO1xufVxuXG4uc2F2ZU1lbnVJdGVtOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjBmMGYwO1xufVxuXG4vKiBQYXVzZS9SZXN1bWUgYnV0dG9uIHZhcmlhbnQgKHJldXNlcyAuY2hhdEJ1dHRvbiBiYXNlIHN0eWxlcyBmb3IgRFJZKSAqL1xuLnBhdXNlQnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZmZiMzQ3IDAlLCAjZmY4YzQyIDEwMCUpICFpbXBvcnRhbnQ7IC8qIFdhcm0gb3JhbmdlIGZvciBcImFjdGl2ZS9ydW5uaW5nXCIgKi9cbn1cblxuLnBhdXNlQnV0dG9uOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZmZjMDY3IDAlLCAjZmY5ZTVmIDEwMCUpICFpbXBvcnRhbnQ7XG59XG5cbi5wYXVzZUJ1dHRvbi5wYXVzaW5nIHtcbiAgICBvcGFjaXR5OiAwLjYgIWltcG9ydGFudDtcbiAgICBjdXJzb3I6IHdhaXQgIWltcG9ydGFudDtcbn1cblxuLnBhdXNlQnV0dG9uLnBhdXNlZCB7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzEwYjk4MSAwJSwgIzA1OTY2OSAxMDAlKSAhaW1wb3J0YW50OyAvKiBHcmVlbiB3aGVuIHBhdXNlZCAocmVhZHkgdG8gcmVzdW1lKSAqL1xufVxuXG4ucGF1c2VCdXR0b24ucGF1c2VkOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjMzRkMzk5IDAlLCAjMDU5NjY5IDEwMCUpICFpbXBvcnRhbnQ7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0ycHgpIHNjYWxlKDEuMDIpO1xuICAgIGJveC1zaGFkb3c6IDAgOHB4IDI0cHggcmdiYSgxNiwgMTg1LCAxMjksIDAuMzUpO1xufVxuXG4ucGF1c2VCdXR0b24gc3ZnIHtcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4zcyBlYXNlO1xufVxuXG4ucGF1c2VCdXR0b24ucGF1c2VkIHN2ZyB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLjEpO1xufVxuXG4ucGF1c2VCdXR0b24ucGF1c2luZyBzdmcge1xuICAgIG9wYWNpdHk6IDAuODtcbn1cblxuLyogVm9pY2UgY2FsbCBpbmRpY2F0b3IgYmFyICovXG4udm9pY2VDYWxsSW5kaWNhdG9yQmFyIHtcbiAgICBncmlkLWFyZWE6IPCfn6Y7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgcGFkZGluZzogMTJweCAyMHB4O1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsIHJnYmEoMzQsIDE5NywgOTQsIDAuMSkgMCUsIHJnYmEoMTYsIDE4NSwgMTI5LCAwLjEpIDEwMCUpO1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCByZ2JhKDM0LCAxOTcsIDk0LCAwLjMpO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG59XG5cbi8qIFZvaWNlIGNhbGwgaW5kaWNhdG9yICovXG4udm9pY2VDYWxsSW5kaWNhdG9yIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogOHB4O1xuICAgIHBhZGRpbmc6IDhweCAxNnB4O1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsIHJnYmEoMzQsIDE5NywgOTQsIDAuMikgMCUsIHJnYmEoMTYsIDE4NSwgMTI5LCAwLjIpIDEwMCUpO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMzQsIDE5NywgOTQsIDAuNCk7XG4gICAgYm9yZGVyLXJhZGl1czogMjBweDtcbiAgICBjb2xvcjogIzEwYjk4MTtcbiAgICBmb250LXNpemU6IDEzcHg7XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMzQsIDE5NywgOTQsIDAuMik7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4udm9pY2VDYWxsSW5kaWNhdG9yIHN2ZyB7XG4gICAgd2lkdGg6IDE2cHg7XG4gICAgaGVpZ2h0OiAxNnB4O1xuICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgIGFuaW1hdGlvbjogdm9pY2VDYWxsSWNvblB1bHNlIDJzIGVhc2UtaW4tb3V0IGluZmluaXRlO1xufVxuXG4udm9pY2VDYWxsSW5kaWNhdG9yIHNwYW4ge1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgdGV4dC1zaGFkb3c6IDAgMXB4IDJweCByZ2JhKDAsIDAsIDAsIDAuMSk7XG59XG5cbi8qIFZvaWNlIGNhbGwgcHVsc2UgYW5pbWF0aW9uICovXG4udm9pY2VDYWxsUHVsc2Uge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICByaWdodDogOHB4O1xuICAgIHRvcDogNTAlO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcbiAgICB3aWR0aDogOHB4O1xuICAgIGhlaWdodDogOHB4O1xuICAgIGJhY2tncm91bmQ6ICMxMGI5ODE7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGFuaW1hdGlvbjogdm9pY2VDYWxsUHVsc2UgMS41cyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbn1cblxuQGtleWZyYW1lcyB2b2ljZUNhbGxJY29uUHVsc2Uge1xuICAgIDAlLFxuICAgIDEwMCUge1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlKDEuMSk7XG4gICAgICAgIG9wYWNpdHk6IDAuODtcbiAgICB9XG59XG5cbkBrZXlmcmFtZXMgdm9pY2VDYWxsUHVsc2Uge1xuICAgIDAlLFxuICAgIDEwMCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTUwJSkgc2NhbGUoMSk7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKSBzY2FsZSgxLjMpO1xuICAgICAgICBvcGFjaXR5OiAwLjY7XG4gICAgfVxufVxuXG4vKiBWb2ljZSBjYWxsIGluZGljYXRvciBpbiBtZXNzYWdlcyAqL1xuLmNoYXRNZXNzYWdlIC52b2ljZUNhbGxJbmRpY2F0b3Ige1xuICAgIG1hcmdpbi1ib3R0b206IDhweDtcbiAgICBwYWRkaW5nOiA2cHggMTJweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgYm9yZGVyLXJhZGl1czogMTZweDtcbn1cblxuLmNoYXRNZXNzYWdlIC52b2ljZUNhbGxJbmRpY2F0b3Igc3ZnIHtcbiAgICB3aWR0aDogMTRweDtcbiAgICBoZWlnaHQ6IDE0cHg7XG59XG5cbi8qIFJhdGluZyBjb25maXJtYXRpb24gKi9cbi5yYXRpbmdDb25maXJtYXRpb24ge1xuICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICB0b3A6IDIwcHg7XG4gICAgcmlnaHQ6IDIwcHg7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzEwYjk4MSAwJSwgIzA1OTY2OSAxMDAlKTtcbiAgICBjb2xvcjogd2hpdGU7XG4gICAgcGFkZGluZzogMTZweCAyMHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgYm94LXNoYWRvdzogMCA4cHggMzJweCByZ2JhKDE2LCAxODUsIDEyOSwgMC4zKTtcbiAgICB6LWluZGV4OiAxMDAxO1xuICAgIGFuaW1hdGlvbjogY29uZmlybWF0aW9uU2xpZGVJbiAwLjNzIGVhc2Utb3V0O1xuICAgIG1heC13aWR0aDogMzAwcHg7XG4gICAgd29yZC13cmFwOiBicmVhay13b3JkO1xuICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDIwcHgpO1xufVxuXG5Aa2V5ZnJhbWVzIGNvbmZpcm1hdGlvblNsaWRlSW4ge1xuICAgIGZyb20ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSk7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cblxuLyogTW9iaWxlIHJlc3BvbnNpdmVuZXNzICovXG5AbWVkaWEgKG1heC13aWR0aDogNzY4cHgpIHtcbiAgICAuYWN0aW9ucyB7XG4gICAgICAgIG1hcmdpbjogMTJweCAxNnB4IDA7XG4gICAgICAgIGdhcDogNnB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlcyB7XG4gICAgICAgIHBhZGRpbmc6IDE2cHggMTJweDtcbiAgICB9XG5cbiAgICAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSB7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDE2cHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLm1lc3NhZ2VUZXh0IHtcbiAgICAgICAgbWF4LXdpZHRoOiA4NSU7XG4gICAgICAgIHBhZGRpbmc6IDEycHggMTZweDtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxOHB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5hdmF0YXIge1xuICAgICAgICB3aWR0aDogMzZweDtcbiAgICAgICAgaGVpZ2h0OiAzNnB4O1xuICAgICAgICBtYXJnaW46IDAgMTBweCA0cHg7XG4gICAgfVxuXG4gICAgLyogW+OKl++4j11cbiAgICAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAuYXZhdGFyIGltZyB7XG4gICAgICAgIHdpZHRoOiAzNnB4O1xuICAgICAgICBhc3BlY3QtcmF0aW86IDEgLyAxO1xuICAgIH1cbiAgICAqL1xuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHtcbiAgICAgICAgcGFkZGluZzogMTZweCAxMnB4O1xuICAgICAgICBnYXA6IDEwcHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHRleHRhcmVhIHtcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgICBwYWRkaW5nOiAxNHB4IDE4cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDIycHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IGJ1dHRvbiB7XG4gICAgICAgIHdpZHRoOiA0NHB4O1xuICAgICAgICBoZWlnaHQ6IDQ0cHg7XG4gICAgfVxuXG4gICAgLnNjcm9sbFRvQm90dG9tIHtcbiAgICAgICAgd2lkdGg6IDQ0cHg7XG4gICAgICAgIGhlaWdodDogNDRweDtcbiAgICAgICAgZm9udC1zaXplOiAxOHB4O1xuICAgICAgICB0b3A6IGNhbGMoMTAwJSAtIDE2MHB4KTtcbiAgICB9XG5cbiAgICAuY2hhdEJ1dHRvbiB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDUwJSAhaW1wb3J0YW50O1xuICAgICAgICB3aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBoZWlnaHQ6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgbWluLXdpZHRoOiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi1oZWlnaHQ6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgcGFkZGluZzogMCAhaW1wb3J0YW50O1xuICAgICAgICBnYXA6IDAgIWltcG9ydGFudDtcbiAgICAgICAgbWFyZ2luOiAwICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLmNoYXRCdXR0b24gc3ZnIHtcbiAgICAgICAgd2lkdGg6IDE4cHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiAxOHB4ICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLmNoYXRCdXR0b25UZXh0IHtcbiAgICAgICAgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC51c2VUZW1wbGF0ZUJ1dHRvbiB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDUwJSAhaW1wb3J0YW50O1xuICAgICAgICB3aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBoZWlnaHQ6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgbWluLXdpZHRoOiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi1oZWlnaHQ6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgcGFkZGluZzogMCAhaW1wb3J0YW50O1xuICAgICAgICBnYXA6IDAgIWltcG9ydGFudDtcbiAgICAgICAgbWFyZ2luOiAwICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnVzZVRlbXBsYXRlQnV0dG9uIHN2ZyB7XG4gICAgICAgIHdpZHRoOiAxOHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogMThweCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC51c2VUZW1wbGF0ZUJ1dHRvbiAuY2hhdEJ1dHRvblRleHQge1xuICAgICAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnJhdGluZ01vZGFsQ29udGVudCB7XG4gICAgICAgIG1hcmdpbjogMTZweDtcbiAgICAgICAgcGFkZGluZzogMjRweCAyMHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgICAgICBtYXgtaGVpZ2h0OiA4MHZoO1xuICAgICAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgIH1cblxuICAgIC5zdGFycyB7XG4gICAgICAgIGdhcDogNnB4O1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xuICAgIH1cblxuICAgIC5zdGFycyBzcGFuIHtcbiAgICAgICAgZm9udC1zaXplOiAzMnB4O1xuICAgICAgICBwYWRkaW5nOiA4cHg7XG4gICAgfVxuXG4gICAgLnJhdGluZ0FjdGlvbnMge1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uLXJldmVyc2U7XG4gICAgICAgIGdhcDogOHB4O1xuICAgIH1cblxuICAgIC5yYXRpbmdBY3Rpb25zIGJ1dHRvbiB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBwYWRkaW5nOiAxNHB4O1xuICAgICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gICAgfVxufVxuXG5AbWVkaWEgKG1heC13aWR0aDogNDgwcHgpIHtcbiAgICAuYWN0aW9ucyB7XG4gICAgICAgIG1hcmdpbjogOHB4IDEycHggMDtcbiAgICAgICAgZ2FwOiA0cHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2VzIHtcbiAgICAgICAgcGFkZGluZzogMTJweCA4cHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLm1lc3NhZ2VUZXh0IHtcbiAgICAgICAgbWF4LXdpZHRoOiA5MCU7XG4gICAgICAgIHBhZGRpbmc6IDEwcHggMTRweDtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5hdmF0YXIge1xuICAgICAgICB3aWR0aDogMzJweDtcbiAgICAgICAgaGVpZ2h0OiAzMnB4O1xuICAgICAgICBtYXJnaW46IDAgOHB4IDRweDtcbiAgICB9XG5cbiAgICAvKiBb44qX77iPXVxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5hdmF0YXIgaW1nIHtcbiAgICAgICAgd2lkdGg6IDMycHg7XG4gICAgICAgIGFzcGVjdC1yYXRpbzogMSAvIDE7XG4gICAgfVxuICAgICovXG5cbiAgICAuY2hhdE1haW5GbG93IC5jaGF0SW5wdXQge1xuICAgICAgICBwYWRkaW5nOiAxMnB4IDhweDtcbiAgICAgICAgZ2FwOiA4cHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHRleHRhcmVhIHtcbiAgICAgICAgcGFkZGluZzogMTJweCAxNnB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAyMHB4O1xuICAgICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IGJ1dHRvbiB7XG4gICAgICAgIHdpZHRoOiA0MHB4O1xuICAgICAgICBoZWlnaHQ6IDQwcHg7XG4gICAgfVxuXG4gICAgLmNoYXRCdXR0b24ge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCUgIWltcG9ydGFudDtcbiAgICAgICAgd2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi13aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4taGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcbiAgICAgICAgZ2FwOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5jaGF0QnV0dG9uIHN2ZyB7XG4gICAgICAgIHdpZHRoOiAxOHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogMThweCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5jaGF0QnV0dG9uVGV4dCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24ge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCUgIWltcG9ydGFudDtcbiAgICAgICAgd2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi13aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4taGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcbiAgICAgICAgZ2FwOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC51c2VUZW1wbGF0ZUJ1dHRvbiBzdmcge1xuICAgICAgICB3aWR0aDogMThweCAhaW1wb3J0YW50O1xuICAgICAgICBoZWlnaHQ6IDE4cHggIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24gLmNoYXRCdXR0b25UZXh0IHtcbiAgICAgICAgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5zY3JvbGxUb0JvdHRvbSB7XG4gICAgICAgIHdpZHRoOiA0MHB4O1xuICAgICAgICBoZWlnaHQ6IDQwcHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgICAgdG9wOiBjYWxjKDEwMCUgLSAxNDBweCk7XG4gICAgfVxuXG4gICAgLnJhdGluZ01vZGFsIHtcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICAgIH1cblxuICAgIC5yYXRpbmdNb2RhbENvbnRlbnQge1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAyMHB4IDIwcHggMCAwO1xuICAgICAgICBtYXgtaGVpZ2h0OiA3MHZoO1xuICAgICAgICBwYWRkaW5nOiAyNHB4IDE2cHggMjBweDtcbiAgICB9XG59XG5cbi8qIFJlZHVjZWQgbW90aW9uIHN1cHBvcnQgKi9cbkBtZWRpYSAocHJlZmVycy1yZWR1Y2VkLW1vdGlvbjogcmVkdWNlKSB7XG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UsXG4gICAgLnNjcm9sbFRvQm90dG9tLFxuICAgIC5yYXRpbmdNb2RhbCxcbiAgICAucmF0aW5nTW9kYWxDb250ZW50LFxuICAgIC5yYXRpbmdDb25maXJtYXRpb24ge1xuICAgICAgICBhbmltYXRpb246IG5vbmU7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLm1lc3NhZ2VUZXh0LFxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCB0ZXh0YXJlYSxcbiAgICAuY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgYnV0dG9uLFxuICAgIC8qIFvjipfvuI9dIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5hdmF0YXIgaW1nLCAqL1xuICAgIC5jaGF0QnV0dG9uIHtcbiAgICAgICAgdHJhbnNpdGlvbjogbm9uZTtcbiAgICB9XG59XG5cbi8qIEhpZ2ggY29udHJhc3QgbW9kZSBzdXBwb3J0ICovXG5AbWVkaWEgKHByZWZlcnMtY29udHJhc3Q6IGhpZ2gpIHtcbiAgICAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAubWVzc2FnZVRleHQge1xuICAgICAgICBib3JkZXI6IDJweCBzb2xpZCBjdXJyZW50Q29sb3I7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHRleHRhcmVhIHtcbiAgICAgICAgYm9yZGVyLXdpZHRoOiAzcHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IGJ1dHRvbiB7XG4gICAgICAgIGJvcmRlcjogMnB4IHNvbGlkIGN1cnJlbnRDb2xvcjtcbiAgICB9XG59XG5cbi8qKlxuICogVE9ETzogW/CfjIldIERSWSBNYXJrZG93biBwcmltaXRpdmVzIHN0eWxpbmdcbiAqL1xuIl19 */";
|
|
9766
|
-
var chatStyles = {"copiedToClipboardMessage":"Chat-module_copiedToClipboardMessage__apCPY","Chat":"Chat-module_Chat__j2eE5","chatMainFlow":"Chat-module_chatMainFlow__--8FE","chatBar":"Chat-module_chatBar__fLECN","TasksInProgress":"Chat-module_TasksInProgress__fQfei","actions":"Chat-module_actions__gTZ5T","portal":"Chat-module_portal__uTOT8","left":"Chat-module_left__7l5Mn","right":"Chat-module_right__ABZrW","chatButton":"Chat-module_chatButton__d9VgA","chatButtonText":"Chat-module_chatButtonText__RkGB-","useTemplateButton":"Chat-module_useTemplateButton__xcJNR","chatChildren":"Chat-module_chatChildren__flOPK","chatMessages":"Chat-module_chatMessages__J2u2N","chatMessage":"Chat-module_chatMessage__nmLaZ","messageSlideIn":"Chat-module_messageSlideIn__soTy2","
|
|
11178
|
+
var css_248z$2 = "@font-face{font-family:OpenMojiBlack;src:url(https://s6.ptbk.io/fonts/OpenMoji-black-glyf.woff2) format(\"woff2\");unicode-range:u+23,u+2a,u+2d,u+30-39,u+a9,u+ae,u+200d,u+203c,u+2049,u+20e3,u+2117,u+2120,u+2122,u+2139,u+2194-2199,u+21a9,u+21aa,u+229c,u+231a,u+231b,u+2328,u+23cf,u+23e9-23f3,u+23f8-23fe,u+24c2,u+25a1,u+25aa-25ae,u+25b6,u+25c0,u+25c9,u+25d0,u+25d1,u+25e7-25ea,u+25ed,u+25ee,u+25fb-25fe,u+2600-2605,u+260e,u+2611,u+2614,u+2615,u+2618,u+261d,u+2620,u+2622,u+2623,u+2626,u+262a,u+262e,u+262f,u+2638-263a,u+2640,u+2642,u+2648-2653,u+265f,u+2660,u+2663,u+2665,u+2666,u+2668,u+267b,u+267e,u+267f,u+2691-2697,u+2699,u+269b,u+269c,u+26a0,u+26a1,u+26a7,u+26aa,u+26ab,u+26b0,u+26b1,u+26bd,u+26be,u+26c4,u+26c5,u+26c8,u+26ce,u+26cf,u+26d1,u+26d3,u+26d4,u+26e9,u+26ea,u+26f0-26f5,u+26f7-26fa,u+26fd,u+2702,u+2705,u+2708-270d,u+270f,u+2712,u+2714,u+2716,u+271d,u+2721,u+2728,u+2733,u+2734,u+2744,u+2747,u+274c,u+274e,u+2753-2755,u+2757,u+2763,u+2764,u+2795-2797,u+27a1,u+27b0,u+27bf,u+2934,u+2935,u+2b05-2b07,u+2b0c,u+2b0d,u+2b1b,u+2b1c,u+2b1f-2b24,u+2b2e,u+2b2f,u+2b50,u+2b55,u+2b58,u+2b8f,u+2bba-2bbc,u+2bc3,u+2bc4,u+2bea,u+2beb,u+3030,u+303d,u+3297,u+3299,u+e000-e009,u+e010,u+e011,u+e040-e06d,u+e080-e0b4,u+e0c0-e0cc,u+e0ff-e10d,u+e140-e14a,u+e150-e157,u+e181-e189,u+e1c0-e1c4,u+e1c6-e1d9,u+e200-e216,u+e240-e269,u+e280-e283,u+e2c0-e2c4,u+e2c6-e2da,u+e300-e303,u+e305-e30f,u+e312-e316,u+e318-e322,u+e324-e329,u+e32b,u+e340-e348,u+e380,u+e381,u+f000,u+f77a,u+f8ff,u+fe0f,u+1f004,u+1f0cf,u+1f10d-1f10f,u+1f12f,u+1f16d-1f171,u+1f17e,u+1f17f,u+1f18e,u+1f191-1f19a,u+1f1e6-1f1ff,u+1f201,u+1f202,u+1f21a,u+1f22f,u+1f232-1f23a,u+1f250,u+1f251,u+1f260-1f265,u+1f300-1f321,u+1f324-1f393,u+1f396,u+1f397,u+1f399-1f39b,u+1f39e-1f3f0,u+1f3f3-1f3f5,u+1f3f7-1f4fd,u+1f4ff-1f53d,u+1f549-1f54e,u+1f550-1f567,u+1f56f,u+1f570,u+1f573-1f57a,u+1f587,u+1f58a-1f58d,u+1f590,u+1f595,u+1f596,u+1f5a4,u+1f5a5,u+1f5a8,u+1f5b1,u+1f5b2,u+1f5bc,u+1f5c2-1f5c4,u+1f5d1-1f5d3,u+1f5dc-1f5de,u+1f5e1,u+1f5e3,u+1f5e8,u+1f5ef,u+1f5f3,u+1f5fa-1f64f,u+1f680-1f6c5,u+1f6cb-1f6d2,u+1f6d5-1f6d7,u+1f6dc-1f6e5,u+1f6e9,u+1f6eb,u+1f6ec,u+1f6f0,u+1f6f3-1f6fc,u+1f7e0-1f7eb,u+1f7f0,u+1f90c-1f93a,u+1f93c-1f945,u+1f947-1f9ff,u+1fa70-1fa7c,u+1fa80-1fa88,u+1fa90-1fabd,u+1fabf-1fac5,u+1face-1fadb,u+1fae0-1fae8,u+1faf0-1faf8,u+1fbc5-1fbc9,u+e0061-e0067,u+e0069,u+e006c-e0079,u+e007f}.Chat-module_copiedToClipboardMessage__apCPY{background:#222;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,.18);color:#fff;font-size:1.1em;left:50%;opacity:.97;padding:10px 24px;pointer-events:none;position:fixed;top:32px;transform:translateX(-50%);z-index:9999}.Chat-module_Chat__j2eE5{display:flex;flex-direction:column;font-family:Arial,Helvetica,sans-serif,OpenMojiBlack;height:100%;width:100%}.Chat-module_chatMainFlow__--8FE{display:grid;grid-template:\"🟦\" min-content \"💬\" 1fr \"📝\" min-content/1fr;height:100%;max-width:100vw;width:100%}.Chat-module_chatMainFlow__--8FE .Chat-module_chatBar__fLECN{background-color:#fff;border-bottom:1px solid rgba(15,23,36,.06);color:#0f1724;font-weight:500;grid-area:🟦;padding:16px 20px;text-align:center;width:100%}.Chat-module_TasksInProgress__fQfei{align-self:center;grid-area:🟦;height:min-content;justify-self:self-end;margin:8px 16px;width:auto}.Chat-module_actions__gTZ5T{align-items:center;align-self:self-start;display:flex;gap:8px;grid-area:💬;height:min-content;justify-self:self-end;margin:16px 20px 0;width:auto;z-index:200}.Chat-module_actions__gTZ5T.Chat-module_portal__uTOT8{margin:0}.Chat-module_actions__gTZ5T.Chat-module_left__7l5Mn{justify-self:self-start}.Chat-module_actions__gTZ5T.Chat-module_right__ABZrW{justify-self:self-end}@media (max-width:900px){.Chat-module_chatButton__d9VgA{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_chatButton__d9VgA svg{height:18px!important;width:18px!important}.Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_useTemplateButton__xcJNR{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_useTemplateButton__xcJNR svg{height:18px!important;width:18px!important}.Chat-module_useTemplateButton__xcJNR .Chat-module_chatButtonText__RkGB-{display:none!important}}@media (max-width:600px){.Chat-module_actions__gTZ5T{gap:7px;margin:14px 18px 0}}.Chat-module_chatMainFlow__--8FE .Chat-module_chatChildren__flOPK{grid-area:💬;height:100%;width:100%;z-index:300}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N{grid-area:💬;height:100%;overflow-x:hidden;overflow-y:auto;padding:24px 20px 16px;scroll-behavior:smooth;width:100%;z-index:10}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar{width:6px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar-track{background:transparent}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar-thumb{background:hsla(0,0%,49%,.2);border-radius:3px;transition:all .2s ease}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N::-webkit-scrollbar-thumb:hover{background:hsla(0,0%,49%,.3)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ{align-items:flex-end;animation:Chat-module_messageSlideIn__soTy2 .4s cubic-bezier(.25,.46,.45,.94);display:flex;flex-direction:row;margin-bottom:20px;max-width:100%;position:relative}@keyframes Chat-module_messageSlideIn__soTy2{0%{opacity:0;transform:translateY(20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.Chat-module_isNotCompleteMessage__Hj2K7{opacity:.7;position:relative}.Chat-module_NonCompleteMessageFiller__G5-Ve{color:transparent}.Chat-module_isNotCompleteMessage__Hj2K7 .Chat-module_messageText__XgNyQ:after{animation:Chat-module_loadingPulse__VomRm 1.5s ease-in-out infinite;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.6),transparent);border-radius:2px;bottom:8px;content:\"\";height:4px;position:absolute;right:12px;width:20px}.Chat-module_completedToolCalls__vI1Qt,.Chat-module_ongoingToolCalls__NZkQN{border-top:1px solid hsla(0,0%,100%,.2);display:flex;flex-direction:row;flex-wrap:wrap;gap:8px;margin-top:8px;padding-top:8px}.Chat-module_completedToolCall__-q4Cs,.Chat-module_ongoingToolCall__WT3Rc{align-items:center;background:hsla(0,0%,100%,.15);border:1px solid hsla(0,0%,100%,.2);border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,.1);color:inherit;display:flex;font-size:.8em;gap:8px;padding:4px 10px}.Chat-module_completedToolCall__-q4Cs{cursor:pointer;transition:all .2s ease}.Chat-module_completedToolCall__-q4Cs:hover{background:hsla(0,0%,100%,.3);box-shadow:0 2px 6px rgba(0,0,0,.15);transform:translateY(-1px)}.Chat-module_toolCallDetails__WUFlD{margin-bottom:24px}.Chat-module_toolCallDetails__WUFlD p{margin-bottom:8px}.Chat-module_toolCallData__UauCO{background:#f1f5f9;border:1px solid #e2e8f0;border-radius:8px;font-size:13px;max-height:300px;overflow-x:auto;padding:12px;word-break:break-all}.Chat-module_ongoingToolCallSpinner__7g-Ay{animation:Chat-module_toolCallSpinner__LSiK6 .8s linear infinite;border:2px solid hsla(0,0%,100%,.3);border-radius:50%;border-top-color:#fff;height:14px;width:14px}.Chat-module_ongoingToolCallName__y59-0{font-weight:500}@keyframes Chat-module_toolCallSpinner__LSiK6{to{transform:rotate(1turn)}}@keyframes Chat-module_loadingPulse__VomRm{0%,to{opacity:.3;transform:scaleX(.8)}50%{opacity:1;transform:scaleX(1.2)}}.Chat-module_typingIndicator__S-CT-{align-items:flex-end;animation:Chat-module_messageSlideIn__soTy2 .4s cubic-bezier(.25,.46,.45,.94);display:flex;margin-bottom:20px}.Chat-module_typingIndicator__S-CT- .Chat-module_avatar__gL6bm{flex-shrink:0;height:40px;margin:0 12px 4px;width:40px}.Chat-module_typingBubble__0Lb7B{backdrop-filter:blur(10px);border:1px solid hsla(0,0%,49%,.1);border-radius:20px;border-bottom-left-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,.1);min-height:24px;padding:16px 20px}.Chat-module_typingBubble__0Lb7B,.Chat-module_typingDots__srOBB{align-items:center;display:flex;gap:4px}.Chat-module_typingDot__dnhKT{animation:Chat-module_typingBounce__1yp2v 1.4s ease-in-out infinite;background:linear-gradient(135deg,#6b7280,hsla(0,0%,49%,.6));border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.1);height:8px;width:8px}.Chat-module_typingDot__dnhKT:first-child{animation-delay:-.32s}.Chat-module_typingDot__dnhKT:nth-child(2){animation-delay:-.16s}.Chat-module_typingDot__dnhKT:nth-child(3){animation-delay:0s}@keyframes Chat-module_typingBounce__1yp2v{0%,80%,to{opacity:.5;transform:scale(.8) translateY(0)}40%{opacity:1;transform:scale(1.2) translateY(-8px)}}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ.Chat-module_isMe__nBtaV{align-items:flex-end;flex-direction:row-reverse;justify-content:flex-start}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ.Chat-module_isMe__nBtaV .Chat-module_messageText__XgNyQ{border-bottom-right-radius:6px}.Chat-module_ratingStar__rRfqC{color:var(--star-inactive-color,#ccc);cursor:pointer;font-size:20px;transition:color .2s}.Chat-module_ratingStar__rRfqC.Chat-module_active__lbYL-{color:gold}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_avatar__gL6bm{aspect-ratio:1/1;flex-shrink:0;margin:0 12px 4px;position:relative;width:40px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{word-wrap:break-word;backdrop-filter:blur(10px);background-color:var(--message-bg-color);border-radius:20px;box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--message-text-color);font-size:15px;line-height:1.5;margin-bottom:4px;max-width:min(70%,600px);padding:14px 18px;position:relative;text-align:left;transition:all .2s ease}.Chat-module_copyButtonContainer__Rij0U{align-items:center;float:right;justify-content:flex-end;pointer-events:none;right:10px;top:8px;visibility:hidden;z-index:2}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ:hover .Chat-module_copyButtonContainer__Rij0U,.Chat-module_copyButtonContainer__Rij0U:focus-within{pointer-events:auto;visibility:visible}.Chat-module_copyButton__DcxT5{align-items:center;background:hsla(0,0%,100%,.2);border:1px solid #ddd;border-radius:6px;box-shadow:0 1px 4px rgba(0,0,0,.07);cursor:pointer;display:flex;opacity:.7;padding:2px 5px;position:relative;transition:all .15s,box-shadow .15s,border .15s}.Chat-module_copiedTooltip__LH81j{animation:Chat-module_copiedTooltipFadeIn__QekO1 .2s;background:#222;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,.18);color:#fff;font-size:.98em;left:50%;margin-top:4px;max-width:220px;opacity:.97;overflow-wrap:break-word;padding:6px 16px;pointer-events:none;position:absolute;top:110%;transform:translateX(-50%);white-space:nowrap;word-break:break-word;z-index:100}.Chat-module_copiedTooltipLeft__j-S-5{left:0!important;transform:none!important}.Chat-module_copiedTooltipRight__R-2cE{left:auto!important;right:0!important;transform:none!important}@keyframes Chat-module_copiedTooltipFadeIn__QekO1{0%{opacity:0;transform:translateX(-50%) translateY(8px) scale(.97)}to{opacity:.97;transform:translateX(-50%) translateY(0) scale(1)}}.Chat-module_copyButton__DcxT5:focus,.Chat-module_copyButton__DcxT5:hover{border:1.5px solid #bbb;box-shadow:0 2px 8px rgba(0,132,255,.1);opacity:1}.Chat-module_copyButton__DcxT5 svg{display:block}.Chat-module_messageText__XgNyQ h1{font-size:2em}.Chat-module_messageText__XgNyQ h2{font-size:1.75em}.Chat-module_messageText__XgNyQ h3{font-size:1.5em}.Chat-module_messageText__XgNyQ h4{font-size:1.25em}.Chat-module_messageText__XgNyQ h5{font-size:1.1em}.Chat-module_messageText__XgNyQ ul{list-style:disc;margin-left:20px}.Chat-module_messageText__XgNyQ ol{list-style:decimal;margin-left:20px}.Chat-module_messageText__XgNyQ blockquote,.Chat-module_messageText__XgNyQ img,.Chat-module_messageText__XgNyQ pre,.Chat-module_messageText__XgNyQ table{border-radius:8px;margin-bottom:10px;margin-top:10px}.Chat-module_messageText__XgNyQ pre{background:#000;color:#fff}.Chat-module_messageText__XgNyQ blockquote,.Chat-module_messageText__XgNyQ pre{border:none;box-shadow:none;display:block;font-size:inherit;line-height:inherit;padding:1em}.Chat-module_messageText__XgNyQ blockquote{background:#ffffffcc;color:#000}.Chat-module_messageText__XgNyQ code{background:#cccccc55;border:none;box-shadow:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;margin:0;padding:0}.Chat-module_messageText__XgNyQ pre code{background-color:#000000cc;border-radius:8px}.Chat-module_messageText__XgNyQ .Chat-module_chat-code-block__k8IyS{background:#181c23;border-color:#23272f;box-shadow:0 2px 8px rgba(0,0,0,.12);color:#f8fafc;font-family:Fira Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:14px;line-height:1.6;overflow-x:auto}.Chat-module_messageText__XgNyQ .Chat-module_chat-code-block__k8IyS code{background:none!important;border:none!important;box-shadow:none!important;color:inherit!important;display:block;font-family:inherit!important;font-size:inherit!important;overflow-x:auto;padding:0!important;white-space:pre;word-break:break-word}.Chat-module_messageText__XgNyQ table{background:#f8fafc;border-collapse:separate;border-spacing:0;box-shadow:0 2px 8px rgba(0,0,0,.08);color:#17223b;font-size:14px;margin:16px 0;width:100%}.Chat-module_messageText__XgNyQ td,.Chat-module_messageText__XgNyQ th{background:none;border-bottom:1px solid #d1dbe8;color:#17223b;padding:10px 16px;text-align:left}.Chat-module_messageText__XgNyQ th{background:linear-gradient(90deg,#eaf3fa 80%,#d1e3f8);border-bottom:2px solid #b5c7de;color:#17223b;font-weight:700}.Chat-module_messageText__XgNyQ tr:last-child td{border-bottom:none}.Chat-module_messageText__XgNyQ tr:nth-child(2n) td{background:#eaf3fa}.Chat-module_messageText__XgNyQ tr:hover td{background:#cbe0f7;transition:background .2s}.Chat-module_messageText__XgNyQ table{border-radius:12px;overflow:hidden}.Chat-module_messageText__XgNyQ td:first-child,.Chat-module_messageText__XgNyQ th:first-child{border-top-left-radius:12px}.Chat-module_messageText__XgNyQ td:last-child,.Chat-module_messageText__XgNyQ th:last-child{border-top-right-radius:12px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ:hover{box-shadow:0 4px 16px rgba(0,0,0,.15);transform:translateY(-1px)}.Chat-module_attachments__m1Fts{border-top:1px solid hsla(0,0%,49%,.2);display:flex;flex-wrap:wrap;gap:8px;margin-top:10px;padding-top:10px}.Chat-module_attachment__aE9hK{align-items:center;background:hsla(0,0%,100%,.2);border:1px solid hsla(0,0%,49%,.3);border-radius:12px;color:inherit;display:flex;font-size:13px;gap:6px;max-width:200px;padding:6px 12px;text-decoration:none;transition:all .2s ease}.Chat-module_attachment__aE9hK:hover{background:hsla(0,0%,100%,.3);border-color:hsla(0,0%,49%,.5);transform:translateY(-1px)}.Chat-module_attachmentIcon__BX3Cy{font-size:14px;opacity:.8}.Chat-module_attachmentName__aMx56{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Chat-module_messageButtons__WaOob{border-top:1px solid hsla(0,0%,49%,.83);display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;padding-top:12px}.Chat-module_messageButton__mRnn-{-webkit-tap-highlight-color:transparent;align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,49%,.1);border:1px solid hsla(0,0%,49%,.9);border-radius:16px;cursor:pointer;display:inline-flex;font-size:13px;font-weight:500;padding:8px 14px;touch-action:manipulation;transition:all .2s ease;user-select:none}.Chat-module_messageButton__mRnn-:hover{background:rgba(0,132,255,.1);border-color:rgba(0,132,255,.3);box-shadow:0 2px 8px rgba(0,132,255,.15);transform:translateY(-1px)}.Chat-module_messageButton__mRnn-:active{transform:scale(.98);transition:transform .1s ease}.Chat-module_messageButton__mRnn- p{line-height:inherit;margin:0;padding:0}.Chat-module_messageButton__mRnn- strong{font-weight:600}.Chat-module_messageButton__mRnn- em{font-style:italic}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M{align-items:center;backdrop-filter:blur(10px);background:rgba(0,0,0,.8);border-radius:12px;bottom:-8px;display:flex;gap:2px;min-width:24px;opacity:0;padding:4px 6px;position:absolute;right:8px;transform:translateY(4px);transition:all .3s cubic-bezier(.25,.46,.45,.94);z-index:1}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ:hover .Chat-module_rating__soc3M{opacity:1;transform:translateY(0)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M:hover{background:rgba(0,0,0,.9);box-shadow:0 4px 12px rgba(0,0,0,.3);padding:6px 8px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M span{cursor:pointer;display:inline-block;font-size:16px;transition:transform .2s ease,color .2s ease}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_rating__soc3M:hover span{transform:scale(1.1)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan{display:flex;flex-direction:column;gap:12px;grid-area:📝;padding:24px;position:relative;width:100%;z-index:10}.Chat-module_Chat__j2eE5.Chat-module_fullPageVisual__zNAEy .Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan{backdrop-filter:blur(25px);background:linear-gradient(180deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.8))}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan.Chat-module_dragOver__bkS-g{background:linear-gradient(0deg,rgba(0,132,255,.1) 0,rgba(0,132,255,.05))}.Chat-module_filePreviewContainer__R70hm{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.Chat-module_filePreview__kq2aX{align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,49%,.1);border:1px solid hsla(0,0%,49%,.2);border-radius:8px;display:flex;font-size:12px;gap:8px;padding:8px 12px;transition:all .2s ease}.Chat-module_filePreview__kq2aX:hover{background:hsla(0,0%,49%,.15);border-color:hsla(0,0%,49%,.3)}.Chat-module_fileIcon__zoSKW{font-size:14px;opacity:.7}.Chat-module_fileInfo__wBLi0{display:flex;flex-direction:column;gap:2px;min-width:0}.Chat-module_fileName__bBujo{color:#000;font-weight:500;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Chat-module_fileSize__ivliq{color:#6b7280;font-size:11px}.Chat-module_removeFileButton__0gakR{align-items:center;background:rgba(255,0,0,.1);border:none;border-radius:50%;color:#f44;cursor:pointer;display:flex;flex-shrink:0;height:20px;justify-content:center;transition:all .2s ease;width:20px}.Chat-module_removeFileButton__0gakR:hover{background:rgba(255,0,0,.2);transform:scale(1.1)}.Chat-module_inputContainer__bPt99{align-items:flex-end;background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:28px;box-shadow:0 4px 20px rgba(0,0,0,.06);display:flex;gap:8px;padding:8px 12px;transition:all .3s cubic-bezier(.25,.46,.45,.94)}.Chat-module_inputContainer__bPt99:focus-within{border-color:var(--brand-color);box-shadow:0 8px 32px rgba(0,132,255,.12);transform:translateY(-2px)}.Chat-module_inputContainer__bPt99 textarea::placeholder{color:#94a3b8;opacity:1}.Chat-module_attachmentButton__qLO47{align-items:center;background:transparent;border:none;border-radius:50%;color:#64748b;cursor:pointer;display:flex;flex-shrink:0;height:40px;justify-content:center;margin-bottom:2px;transition:all .2s ease;width:40px}.Chat-module_attachmentButton__qLO47:hover:not(:disabled){background:#f1f5f9;color:#0f172a}.Chat-module_attachmentButton__qLO47:disabled{cursor:not-allowed;opacity:.3}.Chat-module_voiceButton__d2zlP{align-items:center;background:transparent;border:none;border-radius:50%;color:#64748b;cursor:pointer;display:flex;flex-shrink:0;height:40px;justify-content:center;margin-bottom:2px;transition:all .2s ease;width:40px}.Chat-module_voiceButton__d2zlP:hover:not(:disabled){background:#f1f5f9;color:#0f172a}.Chat-module_voiceButtonActive__Uoi3W{animation:Chat-module_voiceRecordingPulse__y2wJ5 1.5s infinite;background:rgba(239,68,68,.1)!important;color:#ef4444!important}@keyframes Chat-module_voiceRecordingPulse__y2wJ5{0%{box-shadow:0 0 0 0 rgba(255,0,0,.4)}70%{box-shadow:0 0 0 10px rgba(255,0,0,0)}to{box-shadow:0 0 0 0 rgba(255,0,0,0)}}.Chat-module_uploadProgress__jBTKe{align-items:center;background:rgba(0,132,255,.1);border:1px solid rgba(0,132,255,.2);border-radius:8px;color:#0084ff;display:flex;font-size:13px;gap:12px;padding:8px 12px}.Chat-module_uploadProgressBar__Gutnt{background:rgba(0,132,255,.2);border-radius:2px;flex:1;height:4px;overflow:hidden}.Chat-module_uploadProgressFill__EgubT{animation:Chat-module_uploadProgress__jBTKe 1.5s ease-in-out infinite;background:linear-gradient(90deg,#0084ff,rgba(0,132,255,.8));border-radius:2px;height:100%}@keyframes Chat-module_uploadProgress__jBTKe{0%{transform:translateX(-100%)}50%{transform:translateX(0)}to{transform:translateX(100%)}}.Chat-module_dragOverlay__SEGoS{align-items:center;backdrop-filter:blur(10px);background:rgba(0,132,255,.1);border:2px dashed rgba(0,132,255,.5);border-radius:12px;bottom:0;display:flex;justify-content:center;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:20}.Chat-module_dragOverlayContent__gb9kF{align-items:center;color:#0084ff;display:flex;flex-direction:column;font-weight:600;gap:12px;text-align:center}.Chat-module_dragOverlayContent__gb9kF svg{opacity:.7}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{-webkit-tap-highlight-color:transparent;appearance:none;-webkit-appearance:none;background:transparent;border:none;color:#0f172a;flex:1;font-size:15px;line-height:1.5;margin:0;max-height:200px;min-width:100px;outline:none;padding:10px 12px;resize:none;touch-action:manipulation}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea:disabled{cursor:not-allowed;opacity:.6;transform:none}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea::placeholder{color:inherit;opacity:.7}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button[data-button-type=call-to-action]{-webkit-tap-highlight-color:transparent;align-items:center;aspect-ratio:1/1;border:none;border-radius:50%!important;box-shadow:0 4px 12px rgba(0,132,255,.25);color:#fff;display:flex;height:40px;justify-content:center;margin:0 0 2px!important;min-height:unset!important;min-width:unset!important;overflow:visible;padding:0!important;touch-action:manipulation;transition:all .3s cubic-bezier(.25,.46,.45,.94);user-select:none;width:40px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button[data-button-type=call-to-action]:hover{box-shadow:0 6px 16px rgba(0,132,255,.35);transform:scale(1.05)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button[data-button-type=call-to-action]:active{transform:scale(.95)}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button[data-button-type=call-to-action] svg{height:20px;width:20px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button img{height:100%;object-fit:contain;width:50%}.Chat-module_scrollToBottomContainer__5rXpK{align-items:flex-start;display:flex;grid-area:📝;height:100%;justify-content:center;pointer-events:none;width:100%;z-index:20}.Chat-module_scrollToBottomContainer__5rXpK .Chat-module_scrollToBottom__nzxdZ{-webkit-tap-highlight-color:transparent;align-items:center;animation:Chat-module_scrollButtonSlideIn__XnImg .3s ease-out;backdrop-filter:blur(3px);background:rgba(0,0,0,.5);border:none;border-radius:50%;box-shadow:0 4px 16px rgba(0,0,0,.3);color:#fff;cursor:pointer;display:flex;font-weight:700;height:48px;justify-content:center;outline:none;pointer-events:all;touch-action:manipulation;transform:translate(-50%,-150%);transition:all .3s cubic-bezier(.25,.46,.45,.94);user-select:none;width:48px}@keyframes Chat-module_scrollButtonSlideIn__XnImg{0%{opacity:0;transform:translate(-50%,20px) scale(.8)}to{opacity:.9;transform:translate(-50%) scale(1)}}.Chat-module_scrollToBottom__nzxdZ:hover{transform:translate(-50%,-160%) scale(1.05)}.Chat-module_scrollToBottom__nzxdZ:active{transform:translate(-50%,-160%) scale(.95);transition:transform .1s ease}.Chat-module_ratingModal__XVKYm{align-items:center;animation:Chat-module_modalFadeIn__RPc3w .3s ease-out;backdrop-filter:blur(8px);background-color:rgba(0,0,0,.6);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}@keyframes Chat-module_modalFadeIn__RPc3w{0%{backdrop-filter:blur(0);opacity:0}to{backdrop-filter:blur(8px);opacity:1}}.Chat-module_ratingModalContent__CCdq7{animation:Chat-module_modalSlideIn__XXtgN .3s cubic-bezier(.25,.46,.45,.94);backdrop-filter:blur(20px);background:#fff;border:1px solid hsla(0,0%,49%,.1);border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.3);color:#0f1724;font-family:Arial,Helvetica,sans-serif,OpenMojiBlack;max-width:480px;padding:32px;width:90%}@keyframes Chat-module_modalSlideIn__XXtgN{0%{opacity:0;transform:translateY(20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.Chat-module_ratingModalContent__CCdq7 h3{color:#000;font-size:20px;font-weight:600;margin:0 0 24px;text-align:center}.Chat-module_stars__PCzNO{display:flex;gap:8px;justify-content:center;margin-bottom:24px}.Chat-module_stars__PCzNO span{border-radius:8px;cursor:pointer;font-size:28px;padding:4px;transition:all .2s ease}.Chat-module_stars__PCzNO span:hover{background:rgba(255,215,0,.1);transform:scale(1.2)}.Chat-module_ratingModalStar__XkbHr{cursor:pointer;font-size:24px;transition:color .2s}.Chat-module_toolCallModal__uNaIK{max-width:800px;overflow:hidden;padding:0}.Chat-module_searchModalHeader__Y8V-w{align-items:center;background:#fdfdfd;border-bottom:1px solid #eee;display:flex;gap:16px;padding:24px 32px}.Chat-module_searchModalIcon__AR5KY{font-size:24px}.Chat-module_searchModalQuery__5x-Ra{color:#202124!important;font-size:22px!important;font-weight:500!important;margin:0!important;text-align:left!important}.Chat-module_searchModalContent__mWLIE{background:#fff;max-height:60vh;overflow-y:auto;padding:24px 32px}.Chat-module_searchResultsList__xVDUZ{display:flex;flex-direction:column;gap:28px;text-align:left}.Chat-module_searchResultItem__bTzq5{max-width:650px}.Chat-module_searchResultUrl__SbrH4{color:#202124;font-size:14px;margin-bottom:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Chat-module_searchResultUrl__SbrH4 a{color:#202124;text-decoration:none}.Chat-module_searchResultTitle__XS7zN{font-size:20px!important;font-weight:400!important;line-height:1.3;margin:0 0 4px!important}.Chat-module_searchResultTitle__XS7zN a{color:#1a0dab;text-decoration:none}.Chat-module_searchResultTitle__XS7zN a:hover{text-decoration:underline}.Chat-module_searchResultSnippet__Wsun2{color:#4d5156;font-size:14px;line-height:1.58;margin:0}.Chat-module_noResults__AAv6s{color:#70757a;font-style:italic;padding:40px;text-align:center}.Chat-module_toolCallDetails__WUFlD{margin:20px 0;text-align:left}.Chat-module_toolCallDataContainer__rdEzC{background:#f8f8f8;border:1px solid #eee;border-radius:6px;margin-bottom:15px;max-height:300px;overflow-y:auto;padding:12px}.Chat-module_toolCallData__UauCO{font-size:.85em;margin:0;white-space:pre-wrap;word-break:break-word}.Chat-module_toolCallArgsList__LD3xH{list-style:none;margin:0;padding:0}.Chat-module_toolCallArgsList__LD3xH li{font-size:.9em;margin-bottom:5px}.Chat-module_toolCallModal__uNaIK .Chat-module_toolCallData__UauCO{background:#f8fafc;color:#0f172a}.Chat-module_ratingInput__z8Pv-{background:hsla(0,0%,49%,.05);border:2px solid hsla(0,0%,49%,.1);border-radius:12px;color:#0b1220;font-size:14px;line-height:1.5;margin-bottom:18px;min-height:100px;padding:16px;resize:vertical;transition:all .2s ease;width:100%}.Chat-module_ratingInput__z8Pv-:focus{background:hsla(0,0%,49%,.08);border-color:#0084ff;box-shadow:0 0 0 4px rgba(0,132,255,.1);outline:none}.Chat-module_ratingInput__z8Pv-[readonly]{background:hsla(0,0%,49%,.01);border:1px solid hsla(0,0%,49%,.5)}.Chat-module_ratingActions__nXcss{display:flex;gap:12px;justify-content:flex-end}.Chat-module_ratingActions__nXcss button{border:none;border-radius:8px;cursor:pointer;font-size:14px;font-weight:500;min-width:80px;padding:12px 24px;transition:all .2s ease}.Chat-module_ratingActions__nXcss button:first-child{background-color:hsla(0,0%,49%,.1);border:1px solid hsla(0,0%,49%,.2);color:#0b1220}.Chat-module_ratingActions__nXcss button:first-child:hover:not(:disabled){background-color:hsla(0,0%,49%,.2);color:#0b1220}.Chat-module_ratingActions__nXcss button:last-child{background:linear-gradient(135deg,#0084ff,#06c);color:#fff}.Chat-module_ratingActions__nXcss button:last-child:hover:not(:disabled){background:linear-gradient(135deg,#0071d1,#0052a3);box-shadow:0 4px 12px rgba(0,132,255,.3);transform:translateY(-1px)}.Chat-module_ratingActions__nXcss button:last-child:disabled{cursor:not-allowed;opacity:.5}.Chat-module_chatButton__d9VgA{-webkit-tap-highlight-color:transparent!important;align-items:center!important;backdrop-filter:blur(20px)!important;background:linear-gradient(135deg,#0084ff,#06c)!important;border:none!important;border-radius:20px!important;box-shadow:0 4px 16px rgba(0,132,255,.3)!important;color:#fff!important;cursor:pointer!important;display:inline-flex!important;font-size:13px!important;font-weight:600!important;gap:8px!important;justify-content:center!important;line-height:1.3!important;margin:0!important;min-height:40px!important;min-width:110px!important;overflow:hidden!important;padding:12px 16px!important;position:relative!important;touch-action:manipulation!important;transition:all .3s cubic-bezier(.25,.46,.45,.94)!important;user-select:none!important}.Chat-module_chatButton__d9VgA:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.2),transparent);content:\"\";height:100%;left:-100%;position:absolute;top:0;transition:left .5s ease;width:100%}.Chat-module_chatButton__d9VgA:hover:before{left:100%}.Chat-module_chatButton__d9VgA:hover:not(:disabled){background:linear-gradient(135deg,#09f,#07d);box-shadow:0 8px 24px rgba(0,132,255,.4);transform:translateY(-2px) scale(1.02)}.Chat-module_chatButton__d9VgA:active{box-shadow:0 4px 16px rgba(0,132,255,.3);transform:scale(.98) translateY(-1px);transition:transform .1s ease}.Chat-module_chatButton__d9VgA:focus{box-shadow:0 4px 16px rgba(0,132,255,.3),0 0 0 3px rgba(0,132,255,.3);outline:none}.Chat-module_chatButton__d9VgA svg{filter:drop-shadow(0 1px 2px rgba(0,0,0,.2));flex-shrink:0;height:16px;opacity:1;transition:all .3s cubic-bezier(.25,.46,.45,.94);width:16px}.Chat-module_chatButton__d9VgA:hover svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.3));transform:rotate(-90deg) scale(1.1)}.Chat-module_chatButtonText__RkGB-{font-weight:600;opacity:1;text-shadow:0 1px 2px rgba(0,0,0,.1);transition:all .2s ease;white-space:nowrap}.Chat-module_chatButton__d9VgA:hover .Chat-module_chatButtonText__RkGB-{transform:translateX(1px)}.Chat-module_useTemplateButton__xcJNR{-webkit-tap-highlight-color:transparent!important;align-items:center!important;backdrop-filter:blur(20px)!important;background:linear-gradient(135deg,#0084ff,#06c)!important;border:none!important;border-radius:20px!important;box-shadow:0 4px 16px rgba(0,132,255,.3)!important;color:#fff!important;cursor:pointer!important;display:inline-flex!important;font-size:13px!important;font-weight:600!important;gap:8px!important;justify-content:center!important;line-height:1.3!important;margin:0!important;min-height:40px!important;min-width:110px!important;overflow:hidden!important;padding:12px 16px!important;position:relative!important;touch-action:manipulation!important;transition:all .3s cubic-bezier(.25,.46,.45,.94)!important;user-select:none!important}.Chat-module_useTemplateButton__xcJNR:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.2),transparent);content:\"\";height:100%;left:-100%;position:absolute;top:0;transition:left .5s ease;width:100%}.Chat-module_useTemplateButton__xcJNR:hover:before{left:100%}.Chat-module_useTemplateButton__xcJNR:hover:not(:disabled){background:linear-gradient(135deg,#09f,#07d);box-shadow:0 8px 24px rgba(0,132,255,.4);transform:translateY(-2px) scale(1.02)}.Chat-module_useTemplateButton__xcJNR:active{box-shadow:0 4px 16px rgba(0,132,255,.3);transform:scale(.98) translateY(-1px);transition:transform .1s ease}.Chat-module_useTemplateButton__xcJNR:focus{box-shadow:0 4px 16px rgba(0,132,255,.3),0 0 0 3px rgba(0,132,255,.3);outline:none}.Chat-module_useTemplateButton__xcJNR svg{filter:drop-shadow(0 1px 2px rgba(0,0,0,.2));flex-shrink:0;height:16px;opacity:1;transition:all .3s cubic-bezier(.25,.46,.45,.94);width:16px}.Chat-module_useTemplateButton__xcJNR:hover svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.3));transform:scale(1.1)}.Chat-module_useTemplateButton__xcJNR:hover .Chat-module_chatButtonText__RkGB-{transform:translateX(1px)}.Chat-module_saveButtonContainer__lSNUJ{display:inline-block;position:relative}.Chat-module_saveMenu__-ph8y{background:#fff;border:1px solid #ddd;box-shadow:0 2px 8px rgba(0,0,0,.08);left:0;min-width:120px;position:absolute;top:100%;z-index:10}.Chat-module_saveMenuItem__ISApL{background:none;border:none;color:#111;cursor:pointer;display:block;padding:8px 16px;text-align:left;width:100%}.Chat-module_saveMenuItem__ISApL:hover{background-color:#f0f0f0}.Chat-module_pauseButton__eeu7K{background:linear-gradient(135deg,#ffb347,#ff8c42)!important}.Chat-module_pauseButton__eeu7K:hover:not(:disabled){background:linear-gradient(135deg,#ffc067,#ff9e5f)!important}.Chat-module_pauseButton__eeu7K.Chat-module_pausing__pTx8b{cursor:wait!important;opacity:.6!important}.Chat-module_pauseButton__eeu7K.Chat-module_paused__j-pya{background:linear-gradient(135deg,#10b981,#059669)!important}.Chat-module_pauseButton__eeu7K.Chat-module_paused__j-pya:hover:not(:disabled){background:linear-gradient(135deg,#34d399,#059669)!important;box-shadow:0 8px 24px rgba(16,185,129,.35);transform:translateY(-2px) scale(1.02)}.Chat-module_pauseButton__eeu7K svg{transition:transform .3s ease}.Chat-module_pauseButton__eeu7K.Chat-module_paused__j-pya svg{transform:scale(1.1)}.Chat-module_pauseButton__eeu7K.Chat-module_pausing__pTx8b svg{opacity:.8}.Chat-module_voiceCallIndicatorBar__N2sWN{align-items:center;backdrop-filter:blur(10px);background:linear-gradient(135deg,rgba(34,197,94,.1),rgba(16,185,129,.1));border-bottom:1px solid rgba(34,197,94,.3);display:flex;grid-area:🟦;justify-content:center;padding:12px 20px;width:100%}.Chat-module_voiceCallIndicator__tsaaG{align-items:center;backdrop-filter:blur(10px);background:linear-gradient(135deg,rgba(34,197,94,.2),rgba(16,185,129,.2));border:1px solid rgba(34,197,94,.4);border-radius:20px;box-shadow:0 2px 8px rgba(34,197,94,.2);color:#10b981;display:inline-flex;font-size:13px;font-weight:600;gap:8px;padding:8px 16px;position:relative}.Chat-module_voiceCallIndicator__tsaaG svg{animation:Chat-module_voiceCallIconPulse__zZbJn 2s ease-in-out infinite;flex-shrink:0;height:16px;width:16px}.Chat-module_voiceCallIndicator__tsaaG span{font-weight:600;text-shadow:0 1px 2px rgba(0,0,0,.1)}.Chat-module_voiceCallPulse__XcGU4{animation:Chat-module_voiceCallPulse__XcGU4 1.5s ease-in-out infinite;background:#10b981;border-radius:50%;height:8px;position:absolute;right:8px;top:50%;transform:translateY(-50%);width:8px}@keyframes Chat-module_voiceCallIconPulse__zZbJn{0%,to{opacity:1;transform:scale(1)}50%{opacity:.8;transform:scale(1.1)}}@keyframes Chat-module_voiceCallPulse__XcGU4{0%,to{opacity:1;transform:translateY(-50%) scale(1)}50%{opacity:.6;transform:translateY(-50%) scale(1.3)}}.Chat-module_chatMessage__nmLaZ .Chat-module_voiceCallIndicator__tsaaG{border-radius:16px;font-size:12px;margin-bottom:8px;padding:6px 12px}.Chat-module_chatMessage__nmLaZ .Chat-module_voiceCallIndicator__tsaaG svg{height:14px;width:14px}.Chat-module_ratingConfirmation__n16vb{word-wrap:break-word;animation:Chat-module_confirmationSlideIn__5U-wz .3s ease-out;backdrop-filter:blur(20px);background:linear-gradient(135deg,#10b981,#059669);border-radius:12px;box-shadow:0 8px 32px rgba(16,185,129,.3);color:#fff;font-weight:500;max-width:300px;padding:16px 20px;position:fixed;right:20px;top:20px;z-index:1001}@keyframes Chat-module_confirmationSlideIn__5U-wz{0%{opacity:0;transform:translateX(100%)}to{opacity:1;transform:translateX(0)}}@media (max-width:768px){.Chat-module_actions__gTZ5T{gap:6px;margin:12px 16px 0}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N{padding:16px 12px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ{margin-bottom:16px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{border-radius:18px;font-size:14px;max-width:85%;padding:12px 16px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_avatar__gL6bm{height:36px;margin:0 10px 4px;width:36px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan{gap:10px;padding:16px 12px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{border-radius:22px;font-size:16px;padding:14px 18px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button{height:44px;width:44px}.Chat-module_scrollToBottom__nzxdZ{font-size:18px;height:44px;top:calc(100% - 160px);width:44px}.Chat-module_chatButton__d9VgA{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_chatButton__d9VgA svg{height:18px!important;width:18px!important}.Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_useTemplateButton__xcJNR{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_useTemplateButton__xcJNR svg{height:18px!important;width:18px!important}.Chat-module_useTemplateButton__xcJNR .Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_ratingModalContent__CCdq7{border-radius:16px;margin:16px;max-height:80vh;overflow-y:auto;padding:24px 20px}.Chat-module_stars__PCzNO{gap:6px;margin-bottom:20px}.Chat-module_stars__PCzNO span{font-size:32px;padding:8px}.Chat-module_ratingActions__nXcss{flex-direction:column-reverse;gap:8px}.Chat-module_ratingActions__nXcss button{border-radius:10px;font-size:16px;padding:14px;width:100%}}@media (max-width:480px){.Chat-module_actions__gTZ5T{gap:4px;margin:8px 12px 0}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessages__J2u2N{padding:12px 8px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{border-radius:16px;font-size:14px;max-width:90%;padding:10px 14px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_avatar__gL6bm{height:32px;margin:0 8px 4px;width:32px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan{gap:8px;padding:12px 8px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{border-radius:20px;font-size:16px;padding:12px 16px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button{height:40px;width:40px}.Chat-module_chatButton__d9VgA{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_chatButton__d9VgA svg{height:18px!important;width:18px!important}.Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_useTemplateButton__xcJNR{border-radius:50%!important;gap:0!important;height:40px!important;margin:0!important;min-height:40px!important;min-width:40px!important;padding:0!important;width:40px!important}.Chat-module_useTemplateButton__xcJNR svg{height:18px!important;width:18px!important}.Chat-module_useTemplateButton__xcJNR .Chat-module_chatButtonText__RkGB-{display:none!important}.Chat-module_scrollToBottom__nzxdZ{font-size:16px;height:40px;top:calc(100% - 140px);width:40px}.Chat-module_ratingModal__XVKYm{align-items:flex-end;padding:0}.Chat-module_ratingModalContent__CCdq7{border-radius:20px 20px 0 0;margin:0;max-height:70vh;padding:24px 16px 20px;width:100%}}@media (prefers-reduced-motion:reduce){.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ,.Chat-module_ratingConfirmation__n16vb,.Chat-module_ratingModalContent__CCdq7,.Chat-module_ratingModal__XVKYm,.Chat-module_scrollToBottom__nzxdZ{animation:none}.Chat-module_chatButton__d9VgA,.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button,.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea,.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{transition:none}}@media (prefers-contrast:high){.Chat-module_chatMainFlow__--8FE .Chat-module_chatMessage__nmLaZ .Chat-module_messageText__XgNyQ{border:2px solid}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan textarea{border-width:3px}.Chat-module_chatMainFlow__--8FE .Chat-module_chatInput__1Ecan button{border:2px solid}}\n/*# sourceMappingURL=data:application/json;base64,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LENBRGYsWUFBYSxDQURiLFVBSUosQ0FDSixDQUVBLHlCQUNJLDRCQUVJLE9BQVEsQ0FEUixpQkFFSixDQUVBLGtFQUNJLGdCQUNKLENBRUEsaUdBSUksa0JBQW1CLENBRG5CLGNBQWUsQ0FGZixhQUFjLENBQ2QsaUJBR0osQ0FFQSw0RkFFSSxXQUFZLENBQ1osZ0JBQWlCLENBRmpCLFVBR0osQ0FTQSwrREFFSSxPQUFRLENBRFIsZ0JBRUosQ0FFQSx3RUFFSSxrQkFBbUIsQ0FDbkIsY0FBZSxDQUZmLGlCQUdKLENBRUEsc0VBRUksV0FBWSxDQURaLFVBRUosQ0FFQSwrQkFDSSwyQkFBNkIsQ0FNN0IsZUFBaUIsQ0FKakIscUJBQXVCLENBS3ZCLGtCQUFvQixDQUhwQix5QkFBMkIsQ0FEM0Isd0JBQTBCLENBRTFCLG1CQUFxQixDQUpyQixvQkFPSixDQUVBLG1DQUVJLHFCQUF1QixDQUR2QixvQkFFSixDQUVBLG1DQUNJLHNCQUNKLENBRUEsc0NBQ0ksMkJBQTZCLENBTTdCLGVBQWlCLENBSmpCLHFCQUF1QixDQUt2QixrQkFBb0IsQ0FIcEIseUJBQTJCLENBRDNCLHdCQUEwQixDQUUxQixtQkFBcUIsQ0FKckIsb0JBT0osQ0FFQSwwQ0FFSSxxQkFBdUIsQ0FEdkIsb0JBRUosQ0FFQSx5RUFDSSxzQkFDSixDQUVBLG1DQUdJLGNBQWUsQ0FEZixXQUFZLENBRVosc0JBQXVCLENBSHZCLFVBSUosQ0FFQSxnQ0FFSSxvQkFBcUIsQ0FEckIsU0FFSixDQUVBLHVDQUdJLDJCQUE0QixDQUY1QixRQUFTLENBR1QsZUFBZ0IsQ0FDaEIsc0JBQXVCLENBSHZCLFVBSUosQ0FDSixDQUdBLHVDQUNJLGtOQUtJLGNBQ0osQ0FFQSw4UUFLSSxlQUNKLENBQ0osQ0FHQSwrQkFDSSxpR0FDSSxnQkFDSixDQUVBLHdFQUNJLGdCQUNKLENBRUEsc0VBQ0ksZ0JBQ0osQ0FDSiIsImZpbGUiOiJDaGF0Lm1vZHVsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJAZm9udC1mYWNlIHtcbiAgICBmb250LWZhbWlseTogJ09wZW5Nb2ppQmxhY2snO1xuICAgIHNyYzogdXJsKCdodHRwczovL3M2LnB0YmsuaW8vZm9udHMvT3Blbk1vamktYmxhY2stZ2x5Zi53b2ZmMicpIGZvcm1hdCgnd29mZjInKTsgLyogPC0gVE9ETzogW/CfkLHigI3wn5qAXSBEeW5hbWljYWxseSBsb2FkIGZyb20gL3NlcnZlcnMudHMgKi9cbiAgICB1bmljb2RlLXJhbmdlOiBVKzIzLCBVKzJBLCBVKzJELCBVKzMwLTM5LCBVK0E5LCBVK0FFLCBVKzIwMEQsIFUrMjAzQywgVSsyMDQ5LCBVKzIwRTMsIFUrMjExNywgVSsyMTIwLCBVKzIxMjIsIFUrMjEzOSxcbiAgICAgICAgVSsyMTk0LTIxOTksIFUrMjFBOSwgVSsyMUFBLCBVKzIyOUMsIFUrMjMxQSwgVSsyMzFCLCBVKzIzMjgsIFUrMjNDRiwgVSsyM0U5LTIzRjMsIFUrMjNGOC0yM0ZFLCBVKzI0QzIsIFUrMjVBMSxcbiAgICAgICAgVSsyNUFBLTI1QUUsIFUrMjVCNiwgVSsyNUMwLCBVKzI1QzksIFUrMjVEMCwgVSsyNUQxLCBVKzI1RTctMjVFQSwgVSsyNUVELCBVKzI1RUUsIFUrMjVGQi0yNUZFLCBVKzI2MDAtMjYwNSxcbiAgICAgICAgVSsyNjBFLCBVKzI2MTEsIFUrMjYxNCwgVSsyNjE1LCBVKzI2MTgsIFUrMjYxRCwgVSsyNjIwLCBVKzI2MjIsIFUrMjYyMywgVSsyNjI2LCBVKzI2MkEsIFUrMjYyRSwgVSsyNjJGLFxuICAgICAgICBVKzI2MzgtMjYzQSwgVSsyNjQwLCBVKzI2NDIsIFUrMjY0OC0yNjUzLCBVKzI2NUYsIFUrMjY2MCwgVSsyNjYzLCBVKzI2NjUsIFUrMjY2NiwgVSsyNjY4LCBVKzI2N0IsIFUrMjY3RSwgVSsyNjdGLFxuICAgICAgICBVKzI2OTEtMjY5NywgVSsyNjk5LCBVKzI2OUIsIFUrMjY5QywgVSsyNkEwLCBVKzI2QTEsIFUrMjZBNywgVSsyNkFBLCBVKzI2QUIsIFUrMjZCMCwgVSsyNkIxLCBVKzI2QkQsIFUrMjZCRSxcbiAgICAgICAgVSsyNkM0LCBVKzI2QzUsIFUrMjZDOCwgVSsyNkNFLCBVKzI2Q0YsIFUrMjZEMSwgVSsyNkQzLCBVKzI2RDQsIFUrMjZFOSwgVSsyNkVBLCBVKzI2RjAtMjZGNSwgVSsyNkY3LTI2RkEsIFUrMjZGRCxcbiAgICAgICAgVSsyNzAyLCBVKzI3MDUsIFUrMjcwOC0yNzBELCBVKzI3MEYsIFUrMjcxMiwgVSsyNzE0LCBVKzI3MTYsIFUrMjcxRCwgVSsyNzIxLCBVKzI3MjgsIFUrMjczMywgVSsyNzM0LCBVKzI3NDQsXG4gICAgICAgIFUrMjc0NywgVSsyNzRDLCBVKzI3NEUsIFUrMjc1My0yNzU1LCBVKzI3NTcsIFUrMjc2MywgVSsyNzY0LCBVKzI3OTUtMjc5NywgVSsyN0ExLCBVKzI3QjAsIFUrMjdCRiwgVSsyOTM0LCBVKzI5MzUsXG4gICAgICAgIFUrMkIwNS0yQjA3LCBVKzJCMEMsIFUrMkIwRCwgVSsyQjFCLCBVKzJCMUMsIFUrMkIxRi0yQjI0LCBVKzJCMkUsIFUrMkIyRiwgVSsyQjUwLCBVKzJCNTUsIFUrMkI1OCwgVSsyQjhGLFxuICAgICAgICBVKzJCQkEtMkJCQywgVSsyQkMzLCBVKzJCQzQsIFUrMkJFQSwgVSsyQkVCLCBVKzMwMzAsIFUrMzAzRCwgVSszMjk3LCBVKzMyOTksIFUrRTAwMC1FMDA5LCBVK0UwMTAsIFUrRTAxMSxcbiAgICAgICAgVStFMDQwLUUwNkQsIFUrRTA4MC1FMEI0LCBVK0UwQzAtRTBDQywgVStFMEZGLUUxMEQsIFUrRTE0MC1FMTRBLCBVK0UxNTAtRTE1NywgVStFMTgxLUUxODksIFUrRTFDMC1FMUM0LFxuICAgICAgICBVK0UxQzYtRTFEOSwgVStFMjAwLUUyMTYsIFUrRTI0MC1FMjY5LCBVK0UyODAtRTI4MywgVStFMkMwLUUyQzQsIFUrRTJDNi1FMkRBLCBVK0UzMDAtRTMwMywgVStFMzA1LUUzMEYsXG4gICAgICAgIFUrRTMxMi1FMzE2LCBVK0UzMTgtRTMyMiwgVStFMzI0LUUzMjksIFUrRTMyQiwgVStFMzQwLUUzNDgsIFUrRTM4MCwgVStFMzgxLCBVK0YwMDAsIFUrRjc3QSwgVStGOEZGLCBVK0ZFMEYsXG4gICAgICAgIFUrMUYwMDQsIFUrMUYwQ0YsIFUrMUYxMEQtMUYxMEYsIFUrMUYxMkYsIFUrMUYxNkQtMUYxNzEsIFUrMUYxN0UsIFUrMUYxN0YsIFUrMUYxOEUsIFUrMUYxOTEtMUYxOUEsIFUrMUYxRTYtMUYxRkYsXG4gICAgICAgIFUrMUYyMDEsIFUrMUYyMDIsIFUrMUYyMUEsIFUrMUYyMkYsIFUrMUYyMzItMUYyM0EsIFUrMUYyNTAsIFUrMUYyNTEsIFUrMUYyNjAtMUYyNjUsIFUrMUYzMDAtMUYzMjEsIFUrMUYzMjQtMUYzOTMsXG4gICAgICAgIFUrMUYzOTYsIFUrMUYzOTcsIFUrMUYzOTktMUYzOUIsIFUrMUYzOUUtMUYzRjAsIFUrMUYzRjMtMUYzRjUsIFUrMUYzRjctMUY0RkQsIFUrMUY0RkYtMUY1M0QsIFUrMUY1NDktMUY1NEUsXG4gICAgICAgIFUrMUY1NTAtMUY1NjcsIFUrMUY1NkYsIFUrMUY1NzAsIFUrMUY1NzMtMUY1N0EsIFUrMUY1ODcsIFUrMUY1OEEtMUY1OEQsIFUrMUY1OTAsIFUrMUY1OTUsIFUrMUY1OTYsIFUrMUY1QTQsXG4gICAgICAgIFUrMUY1QTUsIFUrMUY1QTgsIFUrMUY1QjEsIFUrMUY1QjIsIFUrMUY1QkMsIFUrMUY1QzItMUY1QzQsIFUrMUY1RDEtMUY1RDMsIFUrMUY1REMtMUY1REUsIFUrMUY1RTEsIFUrMUY1RTMsXG4gICAgICAgIFUrMUY1RTgsIFUrMUY1RUYsIFUrMUY1RjMsIFUrMUY1RkEtMUY2NEYsIFUrMUY2ODAtMUY2QzUsIFUrMUY2Q0ItMUY2RDIsIFUrMUY2RDUtMUY2RDcsIFUrMUY2REMtMUY2RTUsIFUrMUY2RTksXG4gICAgICAgIFUrMUY2RUIsIFUrMUY2RUMsIFUrMUY2RjAsIFUrMUY2RjMtMUY2RkMsIFUrMUY3RTAtMUY3RUIsIFUrMUY3RjAsIFUrMUY5MEMtMUY5M0EsIFUrMUY5M0MtMUY5NDUsIFUrMUY5NDctMUY5RkYsXG4gICAgICAgIFUrMUZBNzAtMUZBN0MsIFUrMUZBODAtMUZBODgsIFUrMUZBOTAtMUZBQkQsIFUrMUZBQkYtMUZBQzUsIFUrMUZBQ0UtMUZBREIsIFUrMUZBRTAtMUZBRTgsIFUrMUZBRjAtMUZBRjgsXG4gICAgICAgIFUrMUZCQzUtMUZCQzksIFUrRTAwNjEtRTAwNjcsIFUrRTAwNjksIFUrRTAwNkMtRTAwNzksIFUrRTAwN0Y7XG59XG5cbi5jb3BpZWRUb0NsaXBib2FyZE1lc3NhZ2Uge1xuICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICB0b3A6IDMycHg7XG4gICAgbGVmdDogNTAlO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcbiAgICBiYWNrZ3JvdW5kOiAjMjIyO1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIHBhZGRpbmc6IDEwcHggMjRweDtcbiAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgZm9udC1zaXplOiAxLjFlbTtcbiAgICBib3gtc2hhZG93OiAwIDJweCAxMnB4IHJnYmEoMCwgMCwgMCwgMC4xOCk7XG4gICAgb3BhY2l0eTogMC45NztcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICB6LWluZGV4OiA5OTk5O1xufVxuXG4uQ2hhdCB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcblxuICAgIGZvbnQtZmFtaWx5OiBBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmLCAnT3Blbk1vamlCbGFjayc7XG4gICAgLyogPC0gVE9ETzogW/Cfp6BdW/CfjrFdIEJldHRlciwgZGVmaW5lIG90aGVyIGZvbnRzICovXG59XG5cbi5jaGF0TWFpbkZsb3cge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBtYXgtd2lkdGg6IDEwMHZ3O1xuICAgIGRpc3BsYXk6IGdyaWQ7XG4gICAgZ3JpZC10ZW1wbGF0ZTpcbiAgICAgICAgJ/Cfn6YnIG1pbi1jb250ZW50XG4gICAgICAgICfwn5KsJyAxZnJcbiAgICAgICAgJ/Cfk50nIG1pbi1jb250ZW50XG4gICAgICAgIC8gMWZyO1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0QmFyIHtcbiAgICBncmlkLWFyZWE6IPCfn6Y7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgcGFkZGluZzogMTZweCAyMHB4O1xuICAgIGNvbG9yOiAjMGYxNzI0O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmZmZmY7XG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHJnYmEoMTUsIDIzLCAzNiwgMC4wNik7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG59XG5cbi5UYXNrc0luUHJvZ3Jlc3Mge1xuICAgIGdyaWQtYXJlYTog8J+fpjtcbiAgICB3aWR0aDogYXV0bztcbiAgICBoZWlnaHQ6IG1pbi1jb250ZW50O1xuICAgIGFsaWduLXNlbGY6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LXNlbGY6IHNlbGYtZW5kO1xuICAgIG1hcmdpbjogOHB4IDE2cHg7XG59XG5cbi5hY3Rpb25zIHtcbiAgICBncmlkLWFyZWE6IPCfkqw7XG4gICAgd2lkdGg6IGF1dG87XG4gICAgaGVpZ2h0OiBtaW4tY29udGVudDtcbiAgICB6LWluZGV4OiAyMDA7XG4gICAgYWxpZ24tc2VsZjogc2VsZi1zdGFydDtcbiAgICBqdXN0aWZ5LXNlbGY6IHNlbGYtZW5kO1xuICAgIG1hcmdpbjogMTZweCAyMHB4IDA7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogOHB4O1xufVxuXG4uYWN0aW9ucy5wb3J0YWwge1xuICAgIG1hcmdpbjogMDtcbn1cblxuLmFjdGlvbnMubGVmdCB7XG4gICAganVzdGlmeS1zZWxmOiBzZWxmLXN0YXJ0O1xufVxuXG4uYWN0aW9ucy5yaWdodCB7XG4gICAganVzdGlmeS1zZWxmOiBzZWxmLWVuZDtcbn1cblxuLyogTGFyZ2UgdGFibGV0IGFuZCBzbWFsbCBkZXNrdG9wIHNjcmVlbnMgKi9cbkBtZWRpYSAobWF4LXdpZHRoOiA5MDBweCkge1xuICAgIC5jaGF0QnV0dG9uIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNTAlICFpbXBvcnRhbnQ7XG4gICAgICAgIHdpZHRoOiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4td2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgbWluLWhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIGdhcDogMCAhaW1wb3J0YW50O1xuICAgICAgICBtYXJnaW46IDAgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAuY2hhdEJ1dHRvbiBzdmcge1xuICAgICAgICB3aWR0aDogMThweCAhaW1wb3J0YW50O1xuICAgICAgICBoZWlnaHQ6IDE4cHggIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAuY2hhdEJ1dHRvblRleHQge1xuICAgICAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnVzZVRlbXBsYXRlQnV0dG9uIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNTAlICFpbXBvcnRhbnQ7XG4gICAgICAgIHdpZHRoOiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4td2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgbWluLWhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIGdhcDogMCAhaW1wb3J0YW50O1xuICAgICAgICBtYXJnaW46IDAgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24gc3ZnIHtcbiAgICAgICAgd2lkdGg6IDE4cHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiAxOHB4ICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnVzZVRlbXBsYXRlQnV0dG9uIC5jaGF0QnV0dG9uVGV4dCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICB9XG59XG5cbi8qIE1lZGl1bSBzY3JlZW5zICovXG5AbWVkaWEgKG1heC13aWR0aDogNjAwcHgpIHtcbiAgICAuYWN0aW9ucyB7XG4gICAgICAgIG1hcmdpbjogMTRweCAxOHB4IDA7XG4gICAgICAgIGdhcDogN3B4O1xuICAgIH1cbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdENoaWxkcmVuIHtcbiAgICBncmlkLWFyZWE6IPCfkqw7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIHotaW5kZXg6IDMwMDtcbn1cblxuLyogQ2hhdCBtZXNzYWdlcyBhcmVhICovXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZXMge1xuICAgIGdyaWQtYXJlYTog8J+SrDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogMTA7XG4gICAgcGFkZGluZzogMjRweCAyMHB4IDE2cHg7XG4gICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICBvdmVyZmxvdy14OiBoaWRkZW47XG4gICAgc2Nyb2xsLWJlaGF2aW9yOiBzbW9vdGg7XG59XG5cbi8qIEN1c3RvbSBzY3JvbGxiYXIgc3R5bGluZyAqL1xuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2VzOjotd2Via2l0LXNjcm9sbGJhciB7XG4gICAgd2lkdGg6IDZweDtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2VzOjotd2Via2l0LXNjcm9sbGJhci10cmFjayB7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlczo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIge1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4yKTtcbiAgICBib3JkZXItcmFkaXVzOiAzcHg7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2VzOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjMpO1xufVxuXG4vKiBJbmRpdmlkdWFsIGNoYXQgbWVzc2FnZSAqL1xuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2Uge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgbWFyZ2luLWJvdHRvbTogMjBweDtcbiAgICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgYW5pbWF0aW9uOiBtZXNzYWdlU2xpZGVJbiAwLjRzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KTtcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG59XG5cbkBrZXlmcmFtZXMgbWVzc2FnZVNsaWRlSW4ge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMjBweCkgc2NhbGUoMC45NSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDApIHNjYWxlKDEpO1xuICAgIH1cbn1cblxuLmlzTm90Q29tcGxldGVNZXNzYWdlIHtcbiAgICAvKi9cbiAgICBvdXRsaW5lOiAxcHggZG90dGVkICNmZjAwMDAgIWltcG9ydGFudDtcbiAgICAvKiovXG5cbiAgICBvcGFjaXR5OiAwLjc7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4uTm9uQ29tcGxldGVNZXNzYWdlRmlsbGVyIHtcbiAgICBjb2xvcjogdHJhbnNwYXJlbnQ7XG59XG5cbi8qIEVuaGFuY2VkIGxvYWRpbmcgc3RhdGVzIGZvciBtZXNzYWdlcyAqL1xuLmlzTm90Q29tcGxldGVNZXNzYWdlIC5tZXNzYWdlVGV4dDo6YWZ0ZXIge1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBib3R0b206IDhweDtcbiAgICByaWdodDogMTJweDtcbiAgICB3aWR0aDogMjBweDtcbiAgICBoZWlnaHQ6IDRweDtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoOTBkZWcsIHRyYW5zcGFyZW50LCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNiksIHRyYW5zcGFyZW50KTtcbiAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgYW5pbWF0aW9uOiBsb2FkaW5nUHVsc2UgMS41cyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbn1cblxuLm9uZ29pbmdUb29sQ2FsbHMsXG4uY29tcGxldGVkVG9vbENhbGxzIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgZmxleC13cmFwOiB3cmFwO1xuICAgIGdhcDogOHB4O1xuICAgIG1hcmdpbi10b3A6IDhweDtcbiAgICBwYWRkaW5nLXRvcDogOHB4O1xuICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMik7XG59XG5cbi5vbmdvaW5nVG9vbENhbGwsXG4uY29tcGxldGVkVG9vbENhbGwge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDhweDtcbiAgICBmb250LXNpemU6IDAuOGVtO1xuICAgIHBhZGRpbmc6IDRweCAxMHB4O1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xNSk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjIpO1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC4xKTtcbiAgICBjb2xvcjogaW5oZXJpdDtcbn1cblxuLmNvbXBsZXRlZFRvb2xDYWxsIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbn1cblxuLmNvbXBsZXRlZFRvb2xDYWxsOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMyk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0xcHgpO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDZweCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xufVxuXG4udG9vbENhbGxEZXRhaWxzIHtcbiAgICBtYXJnaW4tYm90dG9tOiAyNHB4O1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbi50b29sQ2FsbERldGFpbHMgcCB7XG4gICAgbWFyZ2luLWJvdHRvbTogOHB4O1xufVxuXG4udG9vbENhbGxEYXRhIHtcbiAgICBiYWNrZ3JvdW5kOiAjZjFmNWY5O1xuICAgIHBhZGRpbmc6IDEycHg7XG4gICAgYm9yZGVyLXJhZGl1czogOHB4O1xuICAgIGZvbnQtc2l6ZTogMTNweDtcbiAgICBvdmVyZmxvdy14OiBhdXRvO1xuICAgIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDtcbiAgICB3b3JkLWJyZWFrOiBicmVhay1hbGw7XG4gICAgbWF4LWhlaWdodDogMzAwcHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2UyZThmMDtcbn1cblxuLm9uZ29pbmdUb29sQ2FsbFNwaW5uZXIge1xuICAgIHdpZHRoOiAxNHB4O1xuICAgIGhlaWdodDogMTRweDtcbiAgICBib3JkZXI6IDJweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMyk7XG4gICAgYm9yZGVyLXRvcC1jb2xvcjogI2ZmZjtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgYW5pbWF0aW9uOiB0b29sQ2FsbFNwaW5uZXIgMC44cyBsaW5lYXIgaW5maW5pdGU7XG59XG5cbi5vbmdvaW5nVG9vbENhbGxOYW1lIHtcbiAgICBmb250LXdlaWdodDogNTAwO1xufVxuXG5Aa2V5ZnJhbWVzIHRvb2xDYWxsU3Bpbm5lciB7XG4gICAgdG8ge1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpO1xuICAgIH1cbn1cblxuQGtleWZyYW1lcyBsb2FkaW5nUHVsc2Uge1xuICAgIDAlLFxuICAgIDEwMCUge1xuICAgICAgICBvcGFjaXR5OiAwLjM7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGVYKDAuOCk7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGVYKDEuMik7XG4gICAgfVxufVxuXG4vKiBUeXBpbmcgaW5kaWNhdG9yIGZvciBBSSBtZXNzYWdlcyAqL1xuLnR5cGluZ0luZGljYXRvciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gICAgbWFyZ2luLWJvdHRvbTogMjBweDtcbiAgICBhbmltYXRpb246IG1lc3NhZ2VTbGlkZUluIDAuNHMgY3ViaWMtYmV6aWVyKDAuMjUsIDAuNDYsIDAuNDUsIDAuOTQpO1xufVxuXG4udHlwaW5nSW5kaWNhdG9yIC5hdmF0YXIge1xuICAgIHdpZHRoOiA0MHB4O1xuICAgIGhlaWdodDogNDBweDtcbiAgICBtYXJnaW46IDAgMTJweCA0cHg7XG4gICAgZmxleC1zaHJpbms6IDA7XG59XG5cbi8qIFvjipfvuI9dXG4udHlwaW5nSW5kaWNhdG9yIC5hdmF0YXIgaW1nIHtcbiAgICB3aWR0aDogNDBweDtcbiAgICBhc3BlY3QtcmF0aW86IDEgLyAxO1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBvYmplY3QtZml0OiBjb3ZlcjtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZWVmNmZiO1xuICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4xKTtcbn1cbiovXG5cbi50eXBpbmdCdWJibGUge1xuICAgIHBhZGRpbmc6IDE2cHggMjBweDtcbiAgICBib3JkZXItcmFkaXVzOiAyMHB4O1xuICAgIGJvcmRlci1ib3R0b20tbGVmdC1yYWRpdXM6IDZweDtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4xKTtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogNHB4O1xuICAgIG1pbi1oZWlnaHQ6IDI0cHg7XG59XG5cbi50eXBpbmdEb3RzIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGdhcDogNHB4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi50eXBpbmdEb3Qge1xuICAgIHdpZHRoOiA4cHg7XG4gICAgaGVpZ2h0OiA4cHg7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICM2YjcyODAgMCUsIHJnYmEoMTI1LCAxMjUsIDEyNSwgMC42KSAxMDAlKTtcbiAgICBhbmltYXRpb246IHR5cGluZ0JvdW5jZSAxLjRzIGluZmluaXRlIGVhc2UtaW4tb3V0O1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDRweCByZ2JhKDAsIDAsIDAsIDAuMSk7XG59XG5cbi50eXBpbmdEb3Q6bnRoLWNoaWxkKDEpIHtcbiAgICBhbmltYXRpb24tZGVsYXk6IC0wLjMycztcbn1cblxuLnR5cGluZ0RvdDpudGgtY2hpbGQoMikge1xuICAgIGFuaW1hdGlvbi1kZWxheTogLTAuMTZzO1xufVxuXG4udHlwaW5nRG90Om50aC1jaGlsZCgzKSB7XG4gICAgYW5pbWF0aW9uLWRlbGF5OiAwcztcbn1cblxuQGtleWZyYW1lcyB0eXBpbmdCb3VuY2Uge1xuICAgIDAlLFxuICAgIDgwJSxcbiAgICAxMDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgwLjgpIHRyYW5zbGF0ZVkoMCk7XG4gICAgICAgIG9wYWNpdHk6IDAuNTtcbiAgICB9XG4gICAgNDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgxLjIpIHRyYW5zbGF0ZVkoLThweCk7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZS5pc01lIHtcbiAgICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gICAgZmxleC1kaXJlY3Rpb246IHJvdy1yZXZlcnNlO1xuICAgIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UuaXNNZSAubWVzc2FnZVRleHQge1xuICAgIGJvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOiA2cHg7XG59XG5cbi5yYXRpbmdTdGFyIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgZm9udC1zaXplOiAyMHB4O1xuICAgIHRyYW5zaXRpb246IGNvbG9yIDAuMnM7XG4gICAgY29sb3I6IHZhcigtLXN0YXItaW5hY3RpdmUtY29sb3IsICNjY2MpO1xufVxuXG4ucmF0aW5nU3Rhci5hY3RpdmUge1xuICAgIGNvbG9yOiAjZmZkNzAwO1xufVxuXG4vKiBTZW5kZXIgQXZhdGFyICovXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAuYXZhdGFyIHtcbiAgICB3aWR0aDogNDBweDtcbiAgICBhc3BlY3QtcmF0aW86IDEgLyAxO1xuICAgIG1hcmdpbjogMCAxMnB4IDRweDtcbiAgICBmbGV4LXNocmluazogMDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi8qIFvjipfvuI9dXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAuYXZhdGFyIGltZyB7XG4gICAgd2lkdGg6IDQwcHg7XG4gICAgYXNwZWN0LXJhdGlvOiAxIC8gMTtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgb2JqZWN0LWZpdDogY292ZXI7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tYXZhdGFyLWJnLWNvbG9yLCAjZWVmNmZiKTtcbiAgICBib3JkZXI6IDJweCBzb2xpZCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMnMgZWFzZSwgYm94LXNoYWRvdyAwLjJzIGVhc2U7XG59XG5cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLmF2YXRhciBpbWc6aG92ZXIge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4wNSk7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTJweCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xufVxuKi9cblxuLyogTWVzc2FnZSB0ZXh0IGJ1YmJsZSAqL1xuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLm1lc3NhZ2VUZXh0IHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1tZXNzYWdlLWJnLWNvbG9yKTtcbiAgICBjb2xvcjogdmFyKC0tbWVzc2FnZS10ZXh0LWNvbG9yKTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgcGFkZGluZzogMTRweCAxOHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDIwcHg7XG4gICAgbWF4LXdpZHRoOiBtaW4oNzAlLCA2MDBweCk7XG4gICAgdGV4dC1hbGlnbjogbGVmdDtcbiAgICBtYXJnaW4tYm90dG9tOiA0cHg7XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4xKTtcbiAgICBsaW5lLWhlaWdodDogMS41O1xuICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIGZvbnQtc2l6ZTogMTVweDtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG59XG5cbi8qIENvcHkgYnV0dG9uIHN0eWxlcyAqL1xuLmNvcHlCdXR0b25Db250YWluZXIge1xuICAgIGZsb2F0OiByaWdodDtcbiAgICB0b3A6IDhweDtcbiAgICByaWdodDogMTBweDtcbiAgICB6LWluZGV4OiAyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcblxuICAgIHZpc2liaWxpdHk6IGhpZGRlbjtcbn1cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5tZXNzYWdlVGV4dDpob3ZlciAuY29weUJ1dHRvbkNvbnRhaW5lcixcbi5jb3B5QnV0dG9uQ29udGFpbmVyOmZvY3VzLXdpdGhpbiB7XG4gICAgdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbn1cblxuLmNvcHlCdXR0b24ge1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZGRkO1xuICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgICBwYWRkaW5nOiAycHggNXB4O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBib3gtc2hhZG93OiAwIDFweCA0cHggcmdiYSgwLCAwLCAwLCAwLjA3KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4xNXMsIGJveC1zaGFkb3cgMC4xNXMsIGJvcmRlciAwLjE1cztcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgb3BhY2l0eTogMC43O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cblxuLmNvcGllZFRvb2x0aXAge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiA1MCU7XG4gICAgdG9wOiAxMTAlO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcbiAgICBiYWNrZ3JvdW5kOiAjMjIyO1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIHBhZGRpbmc6IDZweCAxNnB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICBmb250LXNpemU6IDAuOThlbTtcbiAgICBib3gtc2hhZG93OiAwIDJweCAxMnB4IHJnYmEoMCwgMCwgMCwgMC4xOCk7XG4gICAgb3BhY2l0eTogMC45NztcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICB6LWluZGV4OiAxMDA7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBtYXJnaW4tdG9wOiA0cHg7XG4gICAgYW5pbWF0aW9uOiBjb3BpZWRUb29sdGlwRmFkZUluIDAuMnM7XG4gICAgbWF4LXdpZHRoOiAyMjBweDtcbiAgICBvdmVyZmxvdy13cmFwOiBicmVhay13b3JkO1xuICAgIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG59XG5cbi5jb3BpZWRUb29sdGlwTGVmdCB7XG4gICAgbGVmdDogMCAhaW1wb3J0YW50O1xuICAgIHRyYW5zZm9ybTogbm9uZSAhaW1wb3J0YW50O1xufVxuXG4uY29waWVkVG9vbHRpcFJpZ2h0IHtcbiAgICBsZWZ0OiBhdXRvICFpbXBvcnRhbnQ7XG4gICAgcmlnaHQ6IDAgIWltcG9ydGFudDtcbiAgICB0cmFuc2Zvcm06IG5vbmUgIWltcG9ydGFudDtcbn1cblxuLyogUmVtb3ZlZCByaWdodC1hbGlnbmVkIG92ZXJyaWRlIHRvIGtlZXAgdG9vbHRpcCBwb3NpdGlvbiBzdGFibGUgKi9cblxuQGtleWZyYW1lcyBjb3BpZWRUb29sdGlwRmFkZUluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC01MCUpIHRyYW5zbGF0ZVkoOHB4KSBzY2FsZSgwLjk3KTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwLjk3O1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSkgdHJhbnNsYXRlWSgwKSBzY2FsZSgxKTtcbiAgICB9XG59XG5cbi5jb3B5QnV0dG9uOmhvdmVyLFxuLmNvcHlCdXR0b246Zm9jdXMge1xuICAgIGJvcmRlcjogMS41cHggc29saWQgI2JiYjtcbiAgICBvcGFjaXR5OiAxO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDhweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjEpO1xufVxuXG4uY29weUJ1dHRvbiBzdmcge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xufVxuXG4ubWVzc2FnZVRleHQgaDEge1xuICAgIGZvbnQtc2l6ZTogMmVtO1xufVxuXG4ubWVzc2FnZVRleHQgaDIge1xuICAgIGZvbnQtc2l6ZTogMS43NWVtO1xufVxuXG4ubWVzc2FnZVRleHQgaDMge1xuICAgIGZvbnQtc2l6ZTogMS41ZW07XG59XG5cbi5tZXNzYWdlVGV4dCBoNCB7XG4gICAgZm9udC1zaXplOiAxLjI1ZW07XG59XG5cbi5tZXNzYWdlVGV4dCBoNSB7XG4gICAgZm9udC1zaXplOiAxLjFlbTtcbn1cblxuLm1lc3NhZ2VUZXh0IHVsIHtcbiAgICBsaXN0LXN0eWxlOiBkaXNjO1xuICAgIG1hcmdpbi1sZWZ0OiAyMHB4O1xufVxuXG4ubWVzc2FnZVRleHQgb2wge1xuICAgIGxpc3Qtc3R5bGU6IGRlY2ltYWw7XG4gICAgbWFyZ2luLWxlZnQ6IDIwcHg7XG59XG5cbi5tZXNzYWdlVGV4dCBpbWcsXG4ubWVzc2FnZVRleHQgcHJlLFxuLm1lc3NhZ2VUZXh0IGJsb2NrcXVvdGUsXG4ubWVzc2FnZVRleHQgdGFibGUge1xuICAgIG1hcmdpbi10b3A6IDEwcHg7XG4gICAgbWFyZ2luLWJvdHRvbTogMTBweDtcbiAgICBib3JkZXItcmFkaXVzOiA4cHg7XG59XG5cbi5tZXNzYWdlVGV4dCBwcmUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICAgIGJhY2tncm91bmQ6ICMwMDAwMDBmZjtcbiAgICBmb250LXNpemU6IGluaGVyaXQ7XG4gICAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgcGFkZGluZzogMWVtO1xufVxuXG4ubWVzc2FnZVRleHQgYmxvY2txdW90ZSB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogI2ZmZmZmZmNjO1xuICAgIGZvbnQtc2l6ZTogaW5oZXJpdDtcbiAgICBsaW5lLWhlaWdodDogaW5oZXJpdDtcbiAgICBjb2xvcjogIzAwMDtcbiAgICBwYWRkaW5nOiAxZW07XG59XG5cbi5tZXNzYWdlVGV4dCBjb2RlIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgbWFyZ2luOiAwO1xuICAgIHBhZGRpbmc6IDA7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogI2NjY2NjYzU1O1xuICAgIGZvbnQtc2l6ZTogaW5oZXJpdDtcbiAgICBsaW5lLWhlaWdodDogaW5oZXJpdDtcbiAgICBjb2xvcjogaW5oZXJpdDtcbn1cblxuLm1lc3NhZ2VUZXh0IHByZSBjb2RlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwY2M7XG4gICAgYm9yZGVyLXJhZGl1czogOHB4O1xufVxuXG4ubWVzc2FnZVRleHQgLmNoYXQtY29kZS1ibG9jayB7XG4gICAgYmFja2dyb3VuZDogIzE4MWMyMztcbiAgICBjb2xvcjogI2Y4ZmFmYztcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDEuNjtcbiAgICBvdmVyZmxvdy14OiBhdXRvO1xuICAgIGJvcmRlci1jb2xvcjogIzIzMjcyZjtcbiAgICBib3gtc2hhZG93OiAwIDJweCA4cHggcmdiYSgwLCAwLCAwLCAwLjEyKTtcbiAgICBmb250LWZhbWlseTogJ0ZpcmEgTW9ubycsICdNZW5sbycsICdDb25zb2xhcycsICdMaWJlcmF0aW9uIE1vbm8nLCBtb25vc3BhY2U7XG59XG4ubWVzc2FnZVRleHQgLmNoYXQtY29kZS1ibG9jayBjb2RlIHtcbiAgICBiYWNrZ3JvdW5kOiBub25lICFpbXBvcnRhbnQ7XG4gICAgY29sb3I6IGluaGVyaXQgIWltcG9ydGFudDtcbiAgICBmb250LWZhbWlseTogaW5oZXJpdCAhaW1wb3J0YW50O1xuICAgIGZvbnQtc2l6ZTogaW5oZXJpdCAhaW1wb3J0YW50O1xuICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcbiAgICBib3JkZXI6IG5vbmUgIWltcG9ydGFudDtcbiAgICBib3gtc2hhZG93OiBub25lICFpbXBvcnRhbnQ7XG4gICAgd2hpdGUtc3BhY2U6IHByZTtcbiAgICB3b3JkLWJyZWFrOiBicmVhay13b3JkO1xuICAgIG92ZXJmbG93LXg6IGF1dG87XG4gICAgZGlzcGxheTogYmxvY2s7XG59XG4ubWVzc2FnZVRleHQgdGFibGUge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7XG4gICAgYm9yZGVyLXNwYWNpbmc6IDA7XG4gICAgbWFyZ2luOiAxNnB4IDA7XG4gICAgYmFja2dyb3VuZDogI2Y4ZmFmYzsgLyogU3Ryb25nZXIgbGlnaHQgYmFja2dyb3VuZCBmb3IgY29udHJhc3QgKi9cbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4wOCk7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGNvbG9yOiAjMTcyMjNiOyAvKiBEYXJrIHRleHQgZm9yIGNvbnRyYXN0ICovXG59XG4ubWVzc2FnZVRleHQgdGgsXG4ubWVzc2FnZVRleHQgdGQge1xuICAgIHBhZGRpbmc6IDEwcHggMTZweDtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2QxZGJlODtcbiAgICB0ZXh0LWFsaWduOiBsZWZ0O1xuICAgIGNvbG9yOiAjMTcyMjNiOyAvKiBFbnN1cmUgc3Ryb25nIHRleHQgY29sb3IgZm9yIGFsbCBjZWxscyAqL1xuICAgIGJhY2tncm91bmQ6IG5vbmU7XG59XG4ubWVzc2FnZVRleHQgdGgge1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCg5MGRlZywgI2VhZjNmYSA4MCUsICNkMWUzZjggMTAwJSk7XG4gICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICBjb2xvcjogIzE3MjIzYjsgLyogU3Ryb25nIGhlYWRlciB0ZXh0ICovXG4gICAgYm9yZGVyLWJvdHRvbTogMnB4IHNvbGlkICNiNWM3ZGU7XG59XG4ubWVzc2FnZVRleHQgdHI6bGFzdC1jaGlsZCB0ZCB7XG4gICAgYm9yZGVyLWJvdHRvbTogbm9uZTtcbn1cbi5tZXNzYWdlVGV4dCB0cjpudGgtY2hpbGQoZXZlbikgdGQge1xuICAgIGJhY2tncm91bmQ6ICNlYWYzZmE7XG59XG4ubWVzc2FnZVRleHQgdHI6aG92ZXIgdGQge1xuICAgIGJhY2tncm91bmQ6ICNjYmUwZjc7XG4gICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjJzO1xufVxuLm1lc3NhZ2VUZXh0IHRhYmxlIHtcbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG59XG4ubWVzc2FnZVRleHQgdGg6Zmlyc3QtY2hpbGQsXG4ubWVzc2FnZVRleHQgdGQ6Zmlyc3QtY2hpbGQge1xuICAgIGJvcmRlci10b3AtbGVmdC1yYWRpdXM6IDEycHg7XG59XG4ubWVzc2FnZVRleHQgdGg6bGFzdC1jaGlsZCxcbi5tZXNzYWdlVGV4dCB0ZDpsYXN0LWNoaWxkIHtcbiAgICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogMTJweDtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLm1lc3NhZ2VUZXh0OmhvdmVyIHtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxNnB4IHJnYmEoMCwgMCwgMCwgMC4xNSk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0xcHgpO1xufVxuXG4vKiBBdHRhY2htZW50cyBzdHlsZXMgKi9cbi5hdHRhY2htZW50cyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LXdyYXA6IHdyYXA7XG4gICAgZ2FwOiA4cHg7XG4gICAgbWFyZ2luLXRvcDogMTBweDtcbiAgICBwYWRkaW5nLXRvcDogMTBweDtcbiAgICBib3JkZXItdG9wOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjIpO1xufVxuXG4uYXR0YWNobWVudCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogNnB4O1xuICAgIHBhZGRpbmc6IDZweCAxMnB4O1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMyk7XG4gICAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgICBmb250LXNpemU6IDEzcHg7XG4gICAgY29sb3I6IGluaGVyaXQ7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG4gICAgbWF4LXdpZHRoOiAyMDBweDtcbn1cblxuLmF0dGFjaG1lbnQ6aG92ZXIge1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4zKTtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC41KTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTFweCk7XG59XG5cbi5hdHRhY2htZW50SWNvbiB7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIG9wYWNpdHk6IDAuODtcbn1cblxuLmF0dGFjaG1lbnROYW1lIHtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG59XG5cbi8qIE1lc3NhZ2UgYnV0dG9ucyBjb250YWluZXIgKi9cbi5tZXNzYWdlQnV0dG9ucyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LXdyYXA6IHdyYXA7XG4gICAgZ2FwOiA4cHg7XG4gICAgbWFyZ2luLXRvcDogMTJweDtcbiAgICBwYWRkaW5nLXRvcDogMTJweDtcbiAgICBib3JkZXItdG9wOiAxcHggc29saWQgcmdiYSgxMjUgMTI1IDEyNSAvIDAuODMpO1xufVxuXG4vKiBJbmRpdmlkdWFsIG1lc3NhZ2UgYnV0dG9uICovXG4ubWVzc2FnZUJ1dHRvbiB7XG4gICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBwYWRkaW5nOiA4cHggMTRweDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjkpO1xuICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgZm9udC1zaXplOiAxM3B4O1xuICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xuICAgIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgdG91Y2gtYWN0aW9uOiBtYW5pcHVsYXRpb247XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbi5tZXNzYWdlQnV0dG9uOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDEzMiwgMjU1LCAwLjEpO1xuICAgIGJvcmRlci1jb2xvcjogcmdiYSgwLCAxMzIsIDI1NSwgMC4zKTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTFweCk7XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMTUpO1xufVxuXG4ubWVzc2FnZUJ1dHRvbjphY3RpdmUge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMC45OCk7XG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMXMgZWFzZTtcbn1cblxuLyogUmVtb3ZlIGRlZmF1bHQgbWFya2Rvd24gc3R5bGVzIGZyb20gYnV0dG9uIGNvbnRlbnQgKi9cbi5tZXNzYWdlQnV0dG9uIHAge1xuICAgIG1hcmdpbjogMDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGxpbmUtaGVpZ2h0OiBpbmhlcml0O1xufVxuXG4ubWVzc2FnZUJ1dHRvbiBzdHJvbmcge1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG59XG5cbi5tZXNzYWdlQnV0dG9uIGVtIHtcbiAgICBmb250LXN0eWxlOiBpdGFsaWM7XG59XG5cbi8qIFJhdGluZyBzeXN0ZW0gKi9cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5yYXRpbmcge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBib3R0b206IC04cHg7XG4gICAgcmlnaHQ6IDhweDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGdhcDogMnB4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgbWluLXdpZHRoOiAyNHB4O1xuICAgIHotaW5kZXg6IDE7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjgpO1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgcGFkZGluZzogNHB4IDZweDtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG4gICAgb3BhY2l0eTogMDtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoNHB4KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCk7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlOmhvdmVyIC5yYXRpbmcge1xuICAgIG9wYWNpdHk6IDE7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDApO1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAucmF0aW5nOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDAsIDAsIDAuOSk7XG4gICAgcGFkZGluZzogNnB4IDhweDtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxMnB4IHJnYmEoMCwgMCwgMCwgMC4zKTtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLnJhdGluZyBzcGFuIHtcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4ycyBlYXNlLCBjb2xvciAwLjJzIGVhc2U7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBmb250LXNpemU6IDE2cHg7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5yYXRpbmc6aG92ZXIgc3BhbiB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLjEpO1xufVxuXG4vKiBDaGF0IGlucHV0IGFyZWEgKi9cbi5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCB7XG4gICAgei1pbmRleDogMTA7XG4gICAgZ3JpZC1hcmVhOiDwn5OdO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBhZGRpbmc6IDI0cHg7XG5cbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgZ2FwOiAxMnB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cblxuLkNoYXQuZnVsbFBhZ2VWaXN1YWwgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMjVweCk7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDE4MGRlZywgcmdiYSgyNTUsIDI1NSwgMjU1LCAwKSAwJSwgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjgpIDEwMCUpO1xufVxuXG4vKiBGaWxlIHVwbG9hZCBkcmFnLWFuZC1kcm9wIHN0eWxlcyAqL1xuLmNoYXRNYWluRmxvdyAuY2hhdElucHV0LmRyYWdPdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gdG9wLCByZ2JhKDAsIDEzMiwgMjU1LCAwLjEpIDAlLCByZ2JhKDAsIDEzMiwgMjU1LCAwLjA1KSAxMDAlKTtcbn1cblxuLyogRmlsZSBwcmV2aWV3IGNvbnRhaW5lciAqL1xuLmZpbGVQcmV2aWV3Q29udGFpbmVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtd3JhcDogd3JhcDtcbiAgICBnYXA6IDhweDtcbiAgICBtYXJnaW4tYm90dG9tOiA4cHg7XG59XG5cbi8qIEluZGl2aWR1YWwgZmlsZSBwcmV2aWV3ICovXG4uZmlsZVByZXZpZXcge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDhweDtcbiAgICBwYWRkaW5nOiA4cHggMTJweDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjIpO1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG59XG5cbi5maWxlUHJldmlldzpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjE1KTtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4zKTtcbn1cblxuLmZpbGVJY29uIHtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgb3BhY2l0eTogMC43O1xufVxuXG4uZmlsZUluZm8ge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDJweDtcbiAgICBtaW4td2lkdGg6IDA7XG59XG5cbi5maWxlTmFtZSB7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICBjb2xvcjogYmxhY2s7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIG1heC13aWR0aDogMTUwcHg7XG59XG5cbi5maWxlU2l6ZSB7XG4gICAgY29sb3I6ICM2YjcyODA7XG4gICAgZm9udC1zaXplOiAxMXB4O1xufVxuXG4ucmVtb3ZlRmlsZUJ1dHRvbiB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIHdpZHRoOiAyMHB4O1xuICAgIGhlaWdodDogMjBweDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDAsIDAsIDAuMSk7XG4gICAgY29sb3I6ICNmZjQ0NDQ7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIGZsZXgtc2hyaW5rOiAwO1xufVxuXG4ucmVtb3ZlRmlsZUJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDAsIDAsIDAuMik7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLjEpO1xufVxuXG4vKiBJbnB1dCBjb250YWluZXIgZm9yIHRleHRhcmVhIGFuZCBidXR0b25zICovXG4uaW5wdXRDb250YWluZXIge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICAgIGdhcDogOHB4O1xuICAgIGJhY2tncm91bmQ6ICNmZmZmZmY7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgwLCAwLCAwLCAwLjA4KTtcbiAgICBib3JkZXItcmFkaXVzOiAyOHB4O1xuICAgIHBhZGRpbmc6IDhweCAxMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgNHB4IDIwcHggcmdiYSgwLCAwLCAwLCAwLjA2KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCk7XG59XG5cbi5pbnB1dENvbnRhaW5lcjpmb2N1cy13aXRoaW4ge1xuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tYnJhbmQtY29sb3IpO1xuICAgIGJveC1zaGFkb3c6IDAgOHB4IDMycHggcmdiYSgwLCAxMzIsIDI1NSwgMC4xMik7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0ycHgpO1xufVxuXG4uaW5wdXRDb250YWluZXIgdGV4dGFyZWE6OnBsYWNlaG9sZGVyIHtcbiAgICBjb2xvcjogIzk0YTNiODtcbiAgICBvcGFjaXR5OiAxO1xufVxuXG4vKiBBdHRhY2htZW50IGJ1dHRvbiAqL1xuLmF0dGFjaG1lbnRCdXR0b24ge1xuICAgIHdpZHRoOiA0MHB4O1xuICAgIGhlaWdodDogNDBweDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgY29sb3I6ICM2NDc0OGI7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbiAgICBmbGV4LXNocmluazogMDtcbiAgICBtYXJnaW4tYm90dG9tOiAycHg7XG59XG5cbi5hdHRhY2htZW50QnV0dG9uOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHtcbiAgICBiYWNrZ3JvdW5kOiAjZjFmNWY5O1xuICAgIGNvbG9yOiAjMGYxNzJhO1xufVxuXG4uYXR0YWNobWVudEJ1dHRvbjpkaXNhYmxlZCB7XG4gICAgb3BhY2l0eTogMC4zO1xuICAgIGN1cnNvcjogbm90LWFsbG93ZWQ7XG59XG5cbi8qIFZvaWNlIEJ1dHRvbiAqL1xuLnZvaWNlQnV0dG9uIHtcbiAgICB3aWR0aDogNDBweDtcbiAgICBoZWlnaHQ6IDQwcHg7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG4gICAgZmxleC1zaHJpbms6IDA7XG4gICAgbWFyZ2luLWJvdHRvbTogMnB4O1xufVxuXG4udm9pY2VCdXR0b246aG92ZXI6bm90KDpkaXNhYmxlZCkge1xuICAgIGJhY2tncm91bmQ6ICNmMWY1Zjk7XG4gICAgY29sb3I6ICMwZjE3MmE7XG59XG5cbi52b2ljZUJ1dHRvbkFjdGl2ZSB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyMzksIDY4LCA2OCwgMC4xKSAhaW1wb3J0YW50O1xuICAgIGNvbG9yOiAjZWY0NDQ0ICFpbXBvcnRhbnQ7XG4gICAgYW5pbWF0aW9uOiB2b2ljZVJlY29yZGluZ1B1bHNlIDEuNXMgaW5maW5pdGU7XG59XG5cbkBrZXlmcmFtZXMgdm9pY2VSZWNvcmRpbmdQdWxzZSB7XG4gICAgMCUge1xuICAgICAgICBib3gtc2hhZG93OiAwIDAgMCAwIHJnYmEoMjU1LCAwLCAwLCAwLjQpO1xuICAgIH1cbiAgICA3MCUge1xuICAgICAgICBib3gtc2hhZG93OiAwIDAgMCAxMHB4IHJnYmEoMjU1LCAwLCAwLCAwKTtcbiAgICB9XG4gICAgMTAwJSB7XG4gICAgICAgIGJveC1zaGFkb3c6IDAgMCAwIDAgcmdiYSgyNTUsIDAsIDAsIDApO1xuICAgIH1cbn1cblxuLyogVXBsb2FkIHByb2dyZXNzIGluZGljYXRvciAqL1xuLnVwbG9hZFByb2dyZXNzIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAxMnB4O1xuICAgIHBhZGRpbmc6IDhweCAxMnB4O1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwgMTMyLCAyNTUsIDAuMSk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgwLCAxMzIsIDI1NSwgMC4yKTtcbiAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgZm9udC1zaXplOiAxM3B4O1xuICAgIGNvbG9yOiAjMDA4NGZmO1xufVxuXG4udXBsb2FkUHJvZ3Jlc3NCYXIge1xuICAgIGZsZXg6IDE7XG4gICAgaGVpZ2h0OiA0cHg7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAxMzIsIDI1NSwgMC4yKTtcbiAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuLnVwbG9hZFByb2dyZXNzRmlsbCB7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCg5MGRlZywgIzAwODRmZiwgcmdiYSgwLCAxMzIsIDI1NSwgMC44KSk7XG4gICAgYm9yZGVyLXJhZGl1czogMnB4O1xuICAgIGFuaW1hdGlvbjogdXBsb2FkUHJvZ3Jlc3MgMS41cyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbn1cblxuQGtleWZyYW1lcyB1cGxvYWRQcm9ncmVzcyB7XG4gICAgMCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwMCUpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCUpO1xuICAgIH1cbiAgICAxMDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpO1xuICAgIH1cbn1cblxuLyogRHJhZyBvdmVybGF5ICovXG4uZHJhZ092ZXJsYXkge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDA7XG4gICAgbGVmdDogMDtcbiAgICByaWdodDogMDtcbiAgICBib3R0b206IDA7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAxMzIsIDI1NSwgMC4xKTtcbiAgICBib3JkZXI6IDJweCBkYXNoZWQgcmdiYSgwLCAxMzIsIDI1NSwgMC41KTtcbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG4gICAgei1pbmRleDogMjA7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi5kcmFnT3ZlcmxheUNvbnRlbnQge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogMTJweDtcbiAgICBjb2xvcjogIzAwODRmZjtcbiAgICBmb250LXdlaWdodDogNjAwO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbn1cblxuLmRyYWdPdmVybGF5Q29udGVudCBzdmcge1xuICAgIG9wYWNpdHk6IDAuNztcbn1cblxuLyogQ2hhdCBpbnB1dCBmaWVsZCAqL1xuLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHRleHRhcmVhIHtcbiAgICBmbGV4OiAxO1xuICAgIHBhZGRpbmc6IDEwcHggMTJweDtcbiAgICBtYXJnaW46IDA7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIG91dGxpbmU6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgY29sb3I6ICMwZjE3MmE7XG4gICAgbWluLXdpZHRoOiAxMDBweDtcbiAgICBtYXgtaGVpZ2h0OiAyMDBweDtcbiAgICBmb250LXNpemU6IDE1cHg7XG4gICAgbGluZS1oZWlnaHQ6IDEuNTtcbiAgICByZXNpemU6IG5vbmU7XG4gICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICB0b3VjaC1hY3Rpb246IG1hbmlwdWxhdGlvbjtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHRleHRhcmVhOmZvY3VzIHtcbiAgICAvKiBGb2N1cyBpcyBoYW5kbGVkIGJ5IC5pbnB1dENvbnRhaW5lciAqL1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgdGV4dGFyZWE6ZGlzYWJsZWQge1xuICAgIG9wYWNpdHk6IDAuNjtcbiAgICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xuICAgIHRyYW5zZm9ybTogbm9uZTtcbn1cblxuLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHRleHRhcmVhOjpwbGFjZWhvbGRlciB7XG4gICAgY29sb3I6IGluaGVyaXQ7XG4gICAgb3BhY2l0eTogMC43O1xufVxuXG4vKiBDaGF0IHNlbmQgYnV0dG9uICovXG4uY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgYnV0dG9uW2RhdGEtYnV0dG9uLXR5cGU9J2NhbGwtdG8tYWN0aW9uJ10ge1xuICAgIHdpZHRoOiA0MHB4O1xuICAgIGhlaWdodDogNDBweDtcbiAgICBtYXJnaW46IDAgMCAycHggMCAhaW1wb3J0YW50O1xuICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcblxuICAgIGJvcmRlcjogbm9uZTtcbiAgICBjb2xvcjogI2ZmZmZmZjtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlICFpbXBvcnRhbnQ7XG4gICAgYXNwZWN0LXJhdGlvOiAxIC8gMTtcbiAgICBtaW4td2lkdGg6IHVuc2V0ICFpbXBvcnRhbnQ7XG4gICAgbWluLWhlaWdodDogdW5zZXQgIWltcG9ydGFudDtcblxuICAgIHRyYW5zaXRpb246IGFsbCAwLjNzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KTtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxMnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMjUpO1xuICAgIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgdG91Y2gtYWN0aW9uOiBtYW5pcHVsYXRpb247XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgb3ZlcmZsb3c6IHZpc2libGU7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCBidXR0b25bZGF0YS1idXR0b24tdHlwZT0nY2FsbC10by1hY3Rpb24nXTpob3ZlciB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLjA1KTtcbiAgICBib3gtc2hhZG93OiAwIDZweCAxNnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMzUpO1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgYnV0dG9uW2RhdGEtYnV0dG9uLXR5cGU9J2NhbGwtdG8tYWN0aW9uJ106YWN0aXZlIHtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAuOTUpO1xufVxuXG4uY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgYnV0dG9uW2RhdGEtYnV0dG9uLXR5cGU9J2NhbGwtdG8tYWN0aW9uJ10gc3ZnIHtcbiAgICB3aWR0aDogMjBweDtcbiAgICBoZWlnaHQ6IDIwcHg7XG59XG5cbi5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCBidXR0b24gaW1nIHtcbiAgICB3aWR0aDogNTAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBvYmplY3QtZml0OiBjb250YWluO1xufVxuXG4vKiBTY3JvbGwgdG8gYm90dG9tIGJ1dHRvbiAqL1xuXG4uc2Nyb2xsVG9Cb3R0b21Db250YWluZXIge1xuICAgIC8qL1xuICAgIG91dGxpbmU6IDFweCBkb3R0ZWQgcmVkO1xuICAgIC8qKi9cblxuICAgIHotaW5kZXg6IDIwO1xuICAgIGdyaWQtYXJlYTog8J+TnTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcblxuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuXG4uc2Nyb2xsVG9Cb3R0b21Db250YWluZXIgLnNjcm9sbFRvQm90dG9tIHtcbiAgICBwb2ludGVyLWV2ZW50czogYWxsO1xuXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTE1MCUpO1xuICAgIHdpZHRoOiA0OHB4O1xuICAgIGhlaWdodDogNDhweDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIG91dGxpbmU6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwIDAgMCAvIDAuNSk7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDNweCk7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xuICAgIGNvbG9yOiB3aGl0ZTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICB0b3VjaC1hY3Rpb246IG1hbmlwdWxhdGlvbjtcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCk7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTZweCByZ2JhKDAsIDAsIDAsIDAuMyk7XG4gICAgYW5pbWF0aW9uOiBzY3JvbGxCdXR0b25TbGlkZUluIDAuM3MgZWFzZS1vdXQ7XG59XG5cbkBrZXlmcmFtZXMgc2Nyb2xsQnV0dG9uU2xpZGVJbiB7XG4gICAgZnJvbSB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIDIwcHgpIHNjYWxlKDAuOCk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgb3BhY2l0eTogMC45O1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAwKSBzY2FsZSgxKTtcbiAgICB9XG59XG5cbi5zY3JvbGxUb0JvdHRvbTpob3ZlciB7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTE2MCUpIHNjYWxlKDEuMDUpO1xufVxuXG4uc2Nyb2xsVG9Cb3R0b206YWN0aXZlIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtMTYwJSkgc2NhbGUoMC45NSk7XG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMXMgZWFzZTtcbn1cblxuLyogUmF0aW5nIG1vZGFsICovXG4ucmF0aW5nTW9kYWwge1xuICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICB0b3A6IDA7XG4gICAgbGVmdDogMDtcbiAgICByaWdodDogMDtcbiAgICBib3R0b206IDA7XG5cbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNik7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDhweCk7XG5cbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgei1pbmRleDogMTAwMDtcbiAgICBhbmltYXRpb246IG1vZGFsRmFkZUluIDAuM3MgZWFzZS1vdXQ7XG59XG5cbkBrZXlmcmFtZXMgbW9kYWxGYWRlSW4ge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMHB4KTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoOHB4KTtcbiAgICB9XG59XG5cbi5yYXRpbmdNb2RhbENvbnRlbnQge1xuICAgIGJhY2tncm91bmQ6ICNmZmZmZmY7XG4gICAgY29sb3I6ICMwZjE3MjQ7XG4gICAgcGFkZGluZzogMzJweDtcbiAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgIHdpZHRoOiA5MCU7XG4gICAgbWF4LXdpZHRoOiA0ODBweDtcbiAgICBib3gtc2hhZG93OiAwIDIwcHggNjBweCByZ2JhKDAsIDAsIDAsIDAuMyk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjEpO1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigyMHB4KTtcbiAgICBhbmltYXRpb246IG1vZGFsU2xpZGVJbiAwLjNzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KTtcblxuICAgIGZvbnQtZmFtaWx5OiBBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmLCAnT3Blbk1vamlCbGFjayc7XG4gICAgLyogPC0gVE9ETzogW/Cfp6BdW/CfjrFdIEJldHRlciwgZGVmaW5lIG90aGVyIGZvbnRzICovXG59XG5cbkBrZXlmcmFtZXMgbW9kYWxTbGlkZUluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDIwcHgpIHNjYWxlKDAuOTUpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKSBzY2FsZSgxKTtcbiAgICB9XG59XG5cbi5yYXRpbmdNb2RhbENvbnRlbnQgaDMge1xuICAgIG1hcmdpbjogMCAwIDI0cHggMDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgY29sb3I6IGJsYWNrO1xuICAgIGZvbnQtc2l6ZTogMjBweDtcbiAgICBmb250LXdlaWdodDogNjAwO1xufVxuXG4uc3RhcnMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgZ2FwOiA4cHg7XG4gICAgbWFyZ2luLWJvdHRvbTogMjRweDtcbn1cblxuLnN0YXJzIHNwYW4ge1xuICAgIGZvbnQtc2l6ZTogMjhweDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbiAgICBwYWRkaW5nOiA0cHg7XG4gICAgYm9yZGVyLXJhZGl1czogOHB4O1xufVxuXG4uc3RhcnMgc3Bhbjpob3ZlciB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLjIpO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyMTUsIDAsIDAuMSk7XG59XG5cbi5yYXRpbmdNb2RhbFN0YXIge1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBmb250LXNpemU6IDI0cHg7XG4gICAgdHJhbnNpdGlvbjogY29sb3IgMC4ycztcbn1cblxuLnRvb2xDYWxsTW9kYWwge1xuICAgIG1heC13aWR0aDogODAwcHg7XG4gICAgcGFkZGluZzogMDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuXG4uc2VhcmNoTW9kYWxIZWFkZXIge1xuICAgIHBhZGRpbmc6IDI0cHggMzJweDtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2VlZTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAxNnB4O1xuICAgIGJhY2tncm91bmQ6ICNmZGZkZmQ7XG59XG5cbi5zZWFyY2hNb2RhbEljb24ge1xuICAgIGZvbnQtc2l6ZTogMjRweDtcbn1cblxuLnNlYXJjaE1vZGFsUXVlcnkge1xuICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIGZvbnQtc2l6ZTogMjJweCAhaW1wb3J0YW50O1xuICAgIGZvbnQtd2VpZ2h0OiA1MDAgIWltcG9ydGFudDtcbiAgICBjb2xvcjogIzIwMjEyNCAhaW1wb3J0YW50O1xuICAgIHRleHQtYWxpZ246IGxlZnQgIWltcG9ydGFudDtcbn1cblxuLnNlYXJjaE1vZGFsQ29udGVudCB7XG4gICAgcGFkZGluZzogMjRweCAzMnB4O1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgbWF4LWhlaWdodDogNjB2aDtcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xufVxuXG4uc2VhcmNoUmVzdWx0c0xpc3Qge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDI4cHg7XG4gICAgdGV4dC1hbGlnbjogbGVmdDtcbn1cblxuLnNlYXJjaFJlc3VsdEl0ZW0ge1xuICAgIG1heC13aWR0aDogNjUwcHg7XG59XG5cbi5zZWFyY2hSZXN1bHRVcmwge1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBjb2xvcjogIzIwMjEyNDtcbiAgICBtYXJnaW4tYm90dG9tOiA0cHg7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xufVxuXG4uc2VhcmNoUmVzdWx0VXJsIGEge1xuICAgIGNvbG9yOiAjMjAyMTI0O1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbn1cblxuLnNlYXJjaFJlc3VsdFRpdGxlIHtcbiAgICBmb250LXNpemU6IDIwcHggIWltcG9ydGFudDtcbiAgICBmb250LXdlaWdodDogNDAwICFpbXBvcnRhbnQ7XG4gICAgbWFyZ2luOiAwIDAgNHB4IDAgIWltcG9ydGFudDtcbiAgICBsaW5lLWhlaWdodDogMS4zO1xufVxuXG4uc2VhcmNoUmVzdWx0VGl0bGUgYSB7XG4gICAgY29sb3I6ICMxYTBkYWI7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xufVxuXG4uc2VhcmNoUmVzdWx0VGl0bGUgYTpob3ZlciB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7XG59XG5cbi5zZWFyY2hSZXN1bHRTbmlwcGV0IHtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDEuNTg7XG4gICAgY29sb3I6ICM0ZDUxNTY7XG4gICAgbWFyZ2luOiAwO1xufVxuXG4ubm9SZXN1bHRzIHtcbiAgICBwYWRkaW5nOiA0MHB4O1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBjb2xvcjogIzcwNzU3YTtcbiAgICBmb250LXN0eWxlOiBpdGFsaWM7XG59XG5cbi50b29sQ2FsbERldGFpbHMge1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgbWFyZ2luOiAyMHB4IDA7XG59XG5cbi50b29sQ2FsbERhdGFDb250YWluZXIge1xuICAgIGJhY2tncm91bmQ6ICNmOGY4Zjg7XG4gICAgcGFkZGluZzogMTJweDtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2VlZTtcbiAgICBtYXJnaW4tYm90dG9tOiAxNXB4O1xuICAgIG1heC1oZWlnaHQ6IDMwMHB4O1xuICAgIG92ZXJmbG93LXk6IGF1dG87XG59XG5cbi50b29sQ2FsbERhdGEge1xuICAgIG1hcmdpbjogMDtcbiAgICBmb250LXNpemU6IDAuODVlbTtcbiAgICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG4gICAgd29yZC1icmVhazogYnJlYWstd29yZDtcbn1cblxuLnRvb2xDYWxsQXJnc0xpc3Qge1xuICAgIGxpc3Qtc3R5bGU6IG5vbmU7XG4gICAgcGFkZGluZzogMDtcbiAgICBtYXJnaW46IDA7XG59XG5cbi50b29sQ2FsbEFyZ3NMaXN0IGxpIHtcbiAgICBtYXJnaW4tYm90dG9tOiA1cHg7XG4gICAgZm9udC1zaXplOiAwLjllbTtcbn1cblxuLnRvb2xDYWxsTW9kYWwgLnRvb2xDYWxsRGF0YSB7XG4gICAgYmFja2dyb3VuZDogI2Y4ZmFmYztcbiAgICBjb2xvcjogIzBmMTcyYTtcbn1cblxuLnJhdGluZ0lucHV0IHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBtaW4taGVpZ2h0OiAxMDBweDtcbiAgICBwYWRkaW5nOiAxNnB4O1xuICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4xKTtcbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIG1hcmdpbi1ib3R0b206IDE4cHg7XG4gICAgcmVzaXplOiB2ZXJ0aWNhbDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMDUpO1xuICAgIGNvbG9yOiAjMGIxMjIwO1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBsaW5lLWhlaWdodDogMS41O1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjJzIGVhc2U7XG59XG5cbi5yYXRpbmdJbnB1dDpmb2N1cyB7XG4gICAgYm9yZGVyLWNvbG9yOiAjMDA4NGZmO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4wOCk7XG4gICAgYm94LXNoYWRvdzogMCAwIDAgNHB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMSk7XG4gICAgb3V0bGluZTogbm9uZTtcbn1cblxuLnJhdGluZ0lucHV0W3JlYWRvbmx5XSB7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjUpO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4wMSk7XG59XG5cbi5yYXRpbmdBY3Rpb25zIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gICAgZ2FwOiAxMnB4O1xufVxuXG4ucmF0aW5nQWN0aW9ucyBidXR0b24ge1xuICAgIHBhZGRpbmc6IDEycHggMjRweDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYm9yZGVyLXJhZGl1czogOHB4O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlO1xuICAgIG1pbi13aWR0aDogODBweDtcbn1cblxuLnJhdGluZ0FjdGlvbnMgYnV0dG9uOmZpcnN0LWNoaWxkIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDEyNSwgMTI1LCAxMjUsIDAuMSk7XG4gICAgY29sb3I6ICMwYjEyMjA7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgxMjUsIDEyNSwgMTI1LCAwLjIpO1xufVxuXG4ucmF0aW5nQWN0aW9ucyBidXR0b246Zmlyc3QtY2hpbGQ6aG92ZXI6bm90KDpkaXNhYmxlZCkge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMTI1LCAxMjUsIDEyNSwgMC4yKTtcbiAgICBjb2xvcjogIzBiMTIyMDtcbn1cblxuLnJhdGluZ0FjdGlvbnMgYnV0dG9uOmxhc3QtY2hpbGQge1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMwMDg0ZmYgMCUsICMwMDY2Y2MgMTAwJSk7XG4gICAgY29sb3I6ICNmZmZmZmY7XG59XG5cbi5yYXRpbmdBY3Rpb25zIGJ1dHRvbjpsYXN0LWNoaWxkOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjMDA3MWQxIDAlLCAjMDA1MmEzIDEwMCUpO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMXB4KTtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxMnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMyk7XG59XG5cbi5yYXRpbmdBY3Rpb25zIGJ1dHRvbjpsYXN0LWNoaWxkOmRpc2FibGVkIHtcbiAgICBvcGFjaXR5OiAwLjU7XG4gICAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbn1cblxuLyogTmV3IGNoYXQgYnV0dG9uIHN0eWxpbmcgLSBNYXRjaGVzIHRoZSBzbGVlayBjaGF0IG1lc3NhZ2UgZGVzaWduICovXG4uY2hhdEJ1dHRvbiB7XG4gICAgZGlzcGxheTogaW5saW5lLWZsZXggIWltcG9ydGFudDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyICFpbXBvcnRhbnQ7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXIgIWltcG9ydGFudDtcbiAgICBnYXA6IDhweCAhaW1wb3J0YW50O1xuICAgIHBhZGRpbmc6IDEycHggMTZweCAhaW1wb3J0YW50O1xuICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMwMDg0ZmYgMCUsICMwMDY2Y2MgMTAwJSkgIWltcG9ydGFudDtcbiAgICBjb2xvcjogI2ZmZmZmZiAhaW1wb3J0YW50O1xuICAgIGJvcmRlcjogbm9uZSAhaW1wb3J0YW50O1xuICAgIGJvcmRlci1yYWRpdXM6IDIwcHggIWltcG9ydGFudDtcbiAgICBmb250LXNpemU6IDEzcHggIWltcG9ydGFudDtcbiAgICBmb250LXdlaWdodDogNjAwICFpbXBvcnRhbnQ7XG4gICAgbGluZS1oZWlnaHQ6IDEuMyAhaW1wb3J0YW50O1xuICAgIGN1cnNvcjogcG9pbnRlciAhaW1wb3J0YW50O1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjNzIGN1YmljLWJlemllcigwLjI1LCAwLjQ2LCAwLjQ1LCAwLjk0KSAhaW1wb3J0YW50O1xuICAgIGJveC1zaGFkb3c6IDAgNHB4IDE2cHggcmdiYSgwLCAxMzIsIDI1NSwgMC4zKSAhaW1wb3J0YW50O1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigyMHB4KSAhaW1wb3J0YW50O1xuICAgIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogdHJhbnNwYXJlbnQgIWltcG9ydGFudDtcbiAgICB0b3VjaC1hY3Rpb246IG1hbmlwdWxhdGlvbiAhaW1wb3J0YW50O1xuICAgIHVzZXItc2VsZWN0OiBub25lICFpbXBvcnRhbnQ7XG4gICAgbWluLWhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgIG1pbi13aWR0aDogMTEwcHggIWltcG9ydGFudDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmUgIWltcG9ydGFudDtcbiAgICBvdmVyZmxvdzogaGlkZGVuICFpbXBvcnRhbnQ7XG59XG5cbi5jaGF0QnV0dG9uOjpiZWZvcmUge1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDA7XG4gICAgbGVmdDogLTEwMCU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCg5MGRlZywgdHJhbnNwYXJlbnQsIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yKSwgdHJhbnNwYXJlbnQpO1xuICAgIHRyYW5zaXRpb246IGxlZnQgMC41cyBlYXNlO1xufVxuXG4uY2hhdEJ1dHRvbjpob3Zlcjo6YmVmb3JlIHtcbiAgICBsZWZ0OiAxMDAlO1xufVxuXG4uY2hhdEJ1dHRvbjpob3Zlcjpub3QoOmRpc2FibGVkKSB7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzAwOTlmZiAwJSwgIzAwNzdkZCAxMDAlKTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTJweCkgc2NhbGUoMS4wMik7XG4gICAgYm94LXNoYWRvdzogMCA4cHggMjRweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjQpO1xufVxuXG4uY2hhdEJ1dHRvbjphY3RpdmUge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMC45OCkgdHJhbnNsYXRlWSgtMXB4KTtcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4xcyBlYXNlO1xuICAgIGJveC1zaGFkb3c6IDAgNHB4IDE2cHggcmdiYSgwLCAxMzIsIDI1NSwgMC4zKTtcbn1cblxuLmNoYXRCdXR0b246Zm9jdXMge1xuICAgIG91dGxpbmU6IG5vbmU7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTZweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpLCAwIDAgMCAzcHggcmdiYSgwLCAxMzIsIDI1NSwgMC4zKTtcbn1cblxuLmNoYXRCdXR0b24gc3ZnIHtcbiAgICB3aWR0aDogMTZweDtcbiAgICBoZWlnaHQ6IDE2cHg7XG4gICAgZmxleC1zaHJpbms6IDA7XG4gICAgb3BhY2l0eTogMTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCk7XG4gICAgZmlsdGVyOiBkcm9wLXNoYWRvdygwIDFweCAycHggcmdiYSgwLCAwLCAwLCAwLjIpKTtcbn1cblxuLmNoYXRCdXR0b246aG92ZXIgc3ZnIHtcbiAgICB0cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHNjYWxlKDEuMSk7XG4gICAgZmlsdGVyOiBkcm9wLXNoYWRvdygwIDJweCA0cHggcmdiYSgwLCAwLCAwLCAwLjMpKTtcbn1cblxuLmNoYXRCdXR0b25UZXh0IHtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbiAgICB0ZXh0LXNoYWRvdzogMCAxcHggMnB4IHJnYmEoMCwgMCwgMCwgMC4xKTtcbiAgICBvcGFjaXR5OiAxO1xufVxuXG4uY2hhdEJ1dHRvbjpob3ZlciAuY2hhdEJ1dHRvblRleHQge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgxcHgpO1xufVxuXG4vKiBVc2UgdGVtcGxhdGUgYnV0dG9uIHN0eWxpbmcgLSBtYXRjaGVzIHRoZSBjaGF0QnV0dG9uIGFuZCBzYXZlQnV0dG9uICovXG4udXNlVGVtcGxhdGVCdXR0b24ge1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4ICFpbXBvcnRhbnQ7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlciAhaW1wb3J0YW50O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyICFpbXBvcnRhbnQ7XG4gICAgZ2FwOiA4cHggIWltcG9ydGFudDtcbiAgICBwYWRkaW5nOiAxMnB4IDE2cHggIWltcG9ydGFudDtcbiAgICBtYXJnaW46IDAgIWltcG9ydGFudDtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjMDA4NGZmIDAlLCAjMDA2NmNjIDEwMCUpICFpbXBvcnRhbnQ7XG4gICAgY29sb3I6ICNmZmZmZmYgIWltcG9ydGFudDtcbiAgICBib3JkZXI6IG5vbmUgIWltcG9ydGFudDtcbiAgICBib3JkZXItcmFkaXVzOiAyMHB4ICFpbXBvcnRhbnQ7XG4gICAgZm9udC1zaXplOiAxM3B4ICFpbXBvcnRhbnQ7XG4gICAgZm9udC13ZWlnaHQ6IDYwMCAhaW1wb3J0YW50O1xuICAgIGxpbmUtaGVpZ2h0OiAxLjMgIWltcG9ydGFudDtcbiAgICBjdXJzb3I6IHBvaW50ZXIgIWltcG9ydGFudDtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCkgIWltcG9ydGFudDtcbiAgICBib3gtc2hhZG93OiAwIDRweCAxNnB4IHJnYmEoMCwgMTMyLCAyNTUsIDAuMykgIWltcG9ydGFudDtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMjBweCkgIWltcG9ydGFudDtcbiAgICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHRyYW5zcGFyZW50ICFpbXBvcnRhbnQ7XG4gICAgdG91Y2gtYWN0aW9uOiBtYW5pcHVsYXRpb24gIWltcG9ydGFudDtcbiAgICB1c2VyLXNlbGVjdDogbm9uZSAhaW1wb3J0YW50O1xuICAgIG1pbi1oZWlnaHQ6IDQwcHggIWltcG9ydGFudDtcbiAgICBtaW4td2lkdGg6IDExMHB4ICFpbXBvcnRhbnQ7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlICFpbXBvcnRhbnQ7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbiAhaW1wb3J0YW50O1xufVxuXG4udXNlVGVtcGxhdGVCdXR0b246OmJlZm9yZSB7XG4gICAgY29udGVudDogJyc7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAtMTAwJTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCB0cmFuc3BhcmVudCwgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjIpLCB0cmFuc3BhcmVudCk7XG4gICAgdHJhbnNpdGlvbjogbGVmdCAwLjVzIGVhc2U7XG59XG5cbi51c2VUZW1wbGF0ZUJ1dHRvbjpob3Zlcjo6YmVmb3JlIHtcbiAgICBsZWZ0OiAxMDAlO1xufVxuXG4udXNlVGVtcGxhdGVCdXR0b246aG92ZXI6bm90KDpkaXNhYmxlZCkge1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMwMDk5ZmYgMCUsICMwMDc3ZGQgMTAwJSk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC0ycHgpIHNjYWxlKDEuMDIpO1xuICAgIGJveC1zaGFkb3c6IDAgOHB4IDI0cHggcmdiYSgwLCAxMzIsIDI1NSwgMC40KTtcbn1cblxuLnVzZVRlbXBsYXRlQnV0dG9uOmFjdGl2ZSB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLjk4KSB0cmFuc2xhdGVZKC0xcHgpO1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjFzIGVhc2U7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTZweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpO1xufVxuXG4udXNlVGVtcGxhdGVCdXR0b246Zm9jdXMge1xuICAgIG91dGxpbmU6IG5vbmU7XG4gICAgYm94LXNoYWRvdzogMCA0cHggMTZweCByZ2JhKDAsIDEzMiwgMjU1LCAwLjMpLCAwIDAgMCAzcHggcmdiYSgwLCAxMzIsIDI1NSwgMC4zKTtcbn1cblxuLnVzZVRlbXBsYXRlQnV0dG9uIHN2ZyB7XG4gICAgd2lkdGg6IDE2cHg7XG4gICAgaGVpZ2h0OiAxNnB4O1xuICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgIG9wYWNpdHk6IDE7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuM3MgY3ViaWMtYmV6aWVyKDAuMjUsIDAuNDYsIDAuNDUsIDAuOTQpO1xuICAgIGZpbHRlcjogZHJvcC1zaGFkb3coMCAxcHggMnB4IHJnYmEoMCwgMCwgMCwgMC4yKSk7XG59XG5cbi51c2VUZW1wbGF0ZUJ1dHRvbjpob3ZlciBzdmcge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4xKTtcbiAgICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMnB4IDRweCByZ2JhKDAsIDAsIDAsIDAuMykpO1xufVxuXG4udXNlVGVtcGxhdGVCdXR0b246aG92ZXIgLmNoYXRCdXR0b25UZXh0IHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMXB4KTtcbn1cblxuLnNhdmVCdXR0b25Db250YWluZXIge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5zYXZlTWVudSB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMTAwJTtcbiAgICBsZWZ0OiAwO1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2RkZDtcbiAgICB6LWluZGV4OiAxMDtcbiAgICBtaW4td2lkdGg6IDEyMHB4O1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMDgpO1xufVxuXG4uc2F2ZU1lbnVJdGVtIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwYWRkaW5nOiA4cHggMTZweDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICB0ZXh0LWFsaWduOiBsZWZ0O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBjb2xvcjogIzExMTtcbn1cblxuLnNhdmVNZW51SXRlbTpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2YwZjBmMDtcbn1cblxuLyogUGF1c2UvUmVzdW1lIGJ1dHRvbiB2YXJpYW50IChyZXVzZXMgLmNoYXRCdXR0b24gYmFzZSBzdHlsZXMgZm9yIERSWSkgKi9cbi5wYXVzZUJ1dHRvbiB7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgI2ZmYjM0NyAwJSwgI2ZmOGM0MiAxMDAlKSAhaW1wb3J0YW50OyAvKiBXYXJtIG9yYW5nZSBmb3IgXCJhY3RpdmUvcnVubmluZ1wiICovXG59XG5cbi5wYXVzZUJ1dHRvbjpob3Zlcjpub3QoOmRpc2FibGVkKSB7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgI2ZmYzA2NyAwJSwgI2ZmOWU1ZiAxMDAlKSAhaW1wb3J0YW50O1xufVxuXG4ucGF1c2VCdXR0b24ucGF1c2luZyB7XG4gICAgb3BhY2l0eTogMC42ICFpbXBvcnRhbnQ7XG4gICAgY3Vyc29yOiB3YWl0ICFpbXBvcnRhbnQ7XG59XG5cbi5wYXVzZUJ1dHRvbi5wYXVzZWQge1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMxMGI5ODEgMCUsICMwNTk2NjkgMTAwJSkgIWltcG9ydGFudDsgLyogR3JlZW4gd2hlbiBwYXVzZWQgKHJlYWR5IHRvIHJlc3VtZSkgKi9cbn1cblxuLnBhdXNlQnV0dG9uLnBhdXNlZDpob3Zlcjpub3QoOmRpc2FibGVkKSB7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzM0ZDM5OSAwJSwgIzA1OTY2OSAxMDAlKSAhaW1wb3J0YW50O1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMnB4KSBzY2FsZSgxLjAyKTtcbiAgICBib3gtc2hhZG93OiAwIDhweCAyNHB4IHJnYmEoMTYsIDE4NSwgMTI5LCAwLjM1KTtcbn1cblxuLnBhdXNlQnV0dG9uIHN2ZyB7XG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuM3MgZWFzZTtcbn1cblxuLnBhdXNlQnV0dG9uLnBhdXNlZCBzdmcge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4xKTtcbn1cblxuLnBhdXNlQnV0dG9uLnBhdXNpbmcgc3ZnIHtcbiAgICBvcGFjaXR5OiAwLjg7XG59XG5cbi8qIFZvaWNlIGNhbGwgaW5kaWNhdG9yIGJhciAqL1xuLnZvaWNlQ2FsbEluZGljYXRvckJhciB7XG4gICAgZ3JpZC1hcmVhOiDwn5+mO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBhZGRpbmc6IDEycHggMjBweDtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCByZ2JhKDM0LCAxOTcsIDk0LCAwLjEpIDAlLCByZ2JhKDE2LCAxODUsIDEyOSwgMC4xKSAxMDAlKTtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgcmdiYSgzNCwgMTk3LCA5NCwgMC4zKTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xufVxuXG4vKiBWb2ljZSBjYWxsIGluZGljYXRvciAqL1xuLnZvaWNlQ2FsbEluZGljYXRvciB7XG4gICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDhweDtcbiAgICBwYWRkaW5nOiA4cHggMTZweDtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCByZ2JhKDM0LCAxOTcsIDk0LCAwLjIpIDAlLCByZ2JhKDE2LCAxODUsIDEyOSwgMC4yKSAxMDAlKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDM0LCAxOTcsIDk0LCAwLjQpO1xuICAgIGJvcmRlci1yYWRpdXM6IDIwcHg7XG4gICAgY29sb3I6ICMxMGI5ODE7XG4gICAgZm9udC1zaXplOiAxM3B4O1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEwcHgpO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDhweCByZ2JhKDM0LCAxOTcsIDk0LCAwLjIpO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cblxuLnZvaWNlQ2FsbEluZGljYXRvciBzdmcge1xuICAgIHdpZHRoOiAxNnB4O1xuICAgIGhlaWdodDogMTZweDtcbiAgICBmbGV4LXNocmluazogMDtcbiAgICBhbmltYXRpb246IHZvaWNlQ2FsbEljb25QdWxzZSAycyBlYXNlLWluLW91dCBpbmZpbml0ZTtcbn1cblxuLnZvaWNlQ2FsbEluZGljYXRvciBzcGFuIHtcbiAgICBmb250LXdlaWdodDogNjAwO1xuICAgIHRleHQtc2hhZG93OiAwIDFweCAycHggcmdiYSgwLCAwLCAwLCAwLjEpO1xufVxuXG4vKiBWb2ljZSBjYWxsIHB1bHNlIGFuaW1hdGlvbiAqL1xuLnZvaWNlQ2FsbFB1bHNlIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDhweDtcbiAgICB0b3A6IDUwJTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTUwJSk7XG4gICAgd2lkdGg6IDhweDtcbiAgICBoZWlnaHQ6IDhweDtcbiAgICBiYWNrZ3JvdW5kOiAjMTBiOTgxO1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBhbmltYXRpb246IHZvaWNlQ2FsbFB1bHNlIDEuNXMgZWFzZS1pbi1vdXQgaW5maW5pdGU7XG59XG5cbkBrZXlmcmFtZXMgdm9pY2VDYWxsSWNvblB1bHNlIHtcbiAgICAwJSxcbiAgICAxMDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgxLjEpO1xuICAgICAgICBvcGFjaXR5OiAwLjg7XG4gICAgfVxufVxuXG5Aa2V5ZnJhbWVzIHZvaWNlQ2FsbFB1bHNlIHtcbiAgICAwJSxcbiAgICAxMDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpIHNjYWxlKDEpO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTUwJSkgc2NhbGUoMS4zKTtcbiAgICAgICAgb3BhY2l0eTogMC42O1xuICAgIH1cbn1cblxuLyogVm9pY2UgY2FsbCBpbmRpY2F0b3IgaW4gbWVzc2FnZXMgKi9cbi5jaGF0TWVzc2FnZSAudm9pY2VDYWxsSW5kaWNhdG9yIHtcbiAgICBtYXJnaW4tYm90dG9tOiA4cHg7XG4gICAgcGFkZGluZzogNnB4IDEycHg7XG4gICAgZm9udC1zaXplOiAxMnB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG59XG5cbi5jaGF0TWVzc2FnZSAudm9pY2VDYWxsSW5kaWNhdG9yIHN2ZyB7XG4gICAgd2lkdGg6IDE0cHg7XG4gICAgaGVpZ2h0OiAxNHB4O1xufVxuXG4vKiBSYXRpbmcgY29uZmlybWF0aW9uICovXG4ucmF0aW5nQ29uZmlybWF0aW9uIHtcbiAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgdG9wOiAyMHB4O1xuICAgIHJpZ2h0OiAyMHB4O1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMxMGI5ODEgMCUsICMwNTk2NjkgMTAwJSk7XG4gICAgY29sb3I6IHdoaXRlO1xuICAgIHBhZGRpbmc6IDE2cHggMjBweDtcbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgOHB4IDMycHggcmdiYSgxNiwgMTg1LCAxMjksIDAuMyk7XG4gICAgei1pbmRleDogMTAwMTtcbiAgICBhbmltYXRpb246IGNvbmZpcm1hdGlvblNsaWRlSW4gMC4zcyBlYXNlLW91dDtcbiAgICBtYXgtd2lkdGg6IDMwMHB4O1xuICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDtcbiAgICBmb250LXdlaWdodDogNTAwO1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigyMHB4KTtcbn1cblxuQGtleWZyYW1lcyBjb25maXJtYXRpb25TbGlkZUluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpO1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59XG5cbi8qIE1vYmlsZSByZXNwb25zaXZlbmVzcyAqL1xuQG1lZGlhIChtYXgtd2lkdGg6IDc2OHB4KSB7XG4gICAgLmFjdGlvbnMge1xuICAgICAgICBtYXJnaW46IDEycHggMTZweCAwO1xuICAgICAgICBnYXA6IDZweDtcbiAgICB9XG5cbiAgICAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZXMge1xuICAgICAgICBwYWRkaW5nOiAxNnB4IDEycHg7XG4gICAgfVxuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2Uge1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAxNnB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5tZXNzYWdlVGV4dCB7XG4gICAgICAgIG1heC13aWR0aDogODUlO1xuICAgICAgICBwYWRkaW5nOiAxMnB4IDE2cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMThweDtcbiAgICB9XG5cbiAgICAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAuYXZhdGFyIHtcbiAgICAgICAgd2lkdGg6IDM2cHg7XG4gICAgICAgIGhlaWdodDogMzZweDtcbiAgICAgICAgbWFyZ2luOiAwIDEwcHggNHB4O1xuICAgIH1cblxuICAgIC8qIFvjipfvuI9dXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLmF2YXRhciBpbWcge1xuICAgICAgICB3aWR0aDogMzZweDtcbiAgICAgICAgYXNwZWN0LXJhdGlvOiAxIC8gMTtcbiAgICB9XG4gICAgKi9cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCB7XG4gICAgICAgIHBhZGRpbmc6IDE2cHggMTJweDtcbiAgICAgICAgZ2FwOiAxMHB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCB0ZXh0YXJlYSB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgICAgcGFkZGluZzogMTRweCAxOHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAyMnB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCBidXR0b24ge1xuICAgICAgICB3aWR0aDogNDRweDtcbiAgICAgICAgaGVpZ2h0OiA0NHB4O1xuICAgIH1cblxuICAgIC5zY3JvbGxUb0JvdHRvbSB7XG4gICAgICAgIHdpZHRoOiA0NHB4O1xuICAgICAgICBoZWlnaHQ6IDQ0cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMThweDtcbiAgICAgICAgdG9wOiBjYWxjKDEwMCUgLSAxNjBweCk7XG4gICAgfVxuXG4gICAgLmNoYXRCdXR0b24ge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCUgIWltcG9ydGFudDtcbiAgICAgICAgd2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi13aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4taGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcbiAgICAgICAgZ2FwOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5jaGF0QnV0dG9uIHN2ZyB7XG4gICAgICAgIHdpZHRoOiAxOHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogMThweCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5jaGF0QnV0dG9uVGV4dCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24ge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCUgIWltcG9ydGFudDtcbiAgICAgICAgd2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIG1pbi13aWR0aDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4taGVpZ2h0OiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcbiAgICAgICAgZ2FwOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC51c2VUZW1wbGF0ZUJ1dHRvbiBzdmcge1xuICAgICAgICB3aWR0aDogMThweCAhaW1wb3J0YW50O1xuICAgICAgICBoZWlnaHQ6IDE4cHggIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24gLmNoYXRCdXR0b25UZXh0IHtcbiAgICAgICAgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1xuICAgIH1cblxuICAgIC5yYXRpbmdNb2RhbENvbnRlbnQge1xuICAgICAgICBtYXJnaW46IDE2cHg7XG4gICAgICAgIHBhZGRpbmc6IDI0cHggMjBweDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICAgICAgbWF4LWhlaWdodDogODB2aDtcbiAgICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICB9XG5cbiAgICAuc3RhcnMge1xuICAgICAgICBnYXA6IDZweDtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMjBweDtcbiAgICB9XG5cbiAgICAuc3RhcnMgc3BhbiB7XG4gICAgICAgIGZvbnQtc2l6ZTogMzJweDtcbiAgICAgICAgcGFkZGluZzogOHB4O1xuICAgIH1cblxuICAgIC5yYXRpbmdBY3Rpb25zIHtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbi1yZXZlcnNlO1xuICAgICAgICBnYXA6IDhweDtcbiAgICB9XG5cbiAgICAucmF0aW5nQWN0aW9ucyBidXR0b24ge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgcGFkZGluZzogMTRweDtcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgIH1cbn1cblxuQG1lZGlhIChtYXgtd2lkdGg6IDQ4MHB4KSB7XG4gICAgLmFjdGlvbnMge1xuICAgICAgICBtYXJnaW46IDhweCAxMnB4IDA7XG4gICAgICAgIGdhcDogNHB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlcyB7XG4gICAgICAgIHBhZGRpbmc6IDEycHggOHB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5tZXNzYWdlVGV4dCB7XG4gICAgICAgIG1heC13aWR0aDogOTAlO1xuICAgICAgICBwYWRkaW5nOiAxMHB4IDE0cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICB9XG5cbiAgICAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAuYXZhdGFyIHtcbiAgICAgICAgd2lkdGg6IDMycHg7XG4gICAgICAgIGhlaWdodDogMzJweDtcbiAgICAgICAgbWFyZ2luOiAwIDhweCA0cHg7XG4gICAgfVxuXG4gICAgLyogW+OKl++4j11cbiAgICAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAuYXZhdGFyIGltZyB7XG4gICAgICAgIHdpZHRoOiAzMnB4O1xuICAgICAgICBhc3BlY3QtcmF0aW86IDEgLyAxO1xuICAgIH1cbiAgICAqL1xuXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IHtcbiAgICAgICAgcGFkZGluZzogMTJweCA4cHg7XG4gICAgICAgIGdhcDogOHB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCB0ZXh0YXJlYSB7XG4gICAgICAgIHBhZGRpbmc6IDEycHggMTZweDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMjBweDtcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCBidXR0b24ge1xuICAgICAgICB3aWR0aDogNDBweDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4O1xuICAgIH1cblxuICAgIC5jaGF0QnV0dG9uIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNTAlICFpbXBvcnRhbnQ7XG4gICAgICAgIHdpZHRoOiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4td2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgbWluLWhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIGdhcDogMCAhaW1wb3J0YW50O1xuICAgICAgICBtYXJnaW46IDAgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAuY2hhdEJ1dHRvbiBzdmcge1xuICAgICAgICB3aWR0aDogMThweCAhaW1wb3J0YW50O1xuICAgICAgICBoZWlnaHQ6IDE4cHggIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAuY2hhdEJ1dHRvblRleHQge1xuICAgICAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnVzZVRlbXBsYXRlQnV0dG9uIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNTAlICFpbXBvcnRhbnQ7XG4gICAgICAgIHdpZHRoOiA0MHB4ICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBtaW4td2lkdGg6IDQwcHggIWltcG9ydGFudDtcbiAgICAgICAgbWluLWhlaWdodDogNDBweCAhaW1wb3J0YW50O1xuICAgICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIGdhcDogMCAhaW1wb3J0YW50O1xuICAgICAgICBtYXJnaW46IDAgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudXNlVGVtcGxhdGVCdXR0b24gc3ZnIHtcbiAgICAgICAgd2lkdGg6IDE4cHggIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiAxOHB4ICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnVzZVRlbXBsYXRlQnV0dG9uIC5jaGF0QnV0dG9uVGV4dCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAuc2Nyb2xsVG9Cb3R0b20ge1xuICAgICAgICB3aWR0aDogNDBweDtcbiAgICAgICAgaGVpZ2h0OiA0MHB4O1xuICAgICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICAgIHRvcDogY2FsYygxMDAlIC0gMTQwcHgpO1xuICAgIH1cblxuICAgIC5yYXRpbmdNb2RhbCB7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBmbGV4LWVuZDtcbiAgICB9XG5cbiAgICAucmF0aW5nTW9kYWxDb250ZW50IHtcbiAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMjBweCAyMHB4IDAgMDtcbiAgICAgICAgbWF4LWhlaWdodDogNzB2aDtcbiAgICAgICAgcGFkZGluZzogMjRweCAxNnB4IDIwcHg7XG4gICAgfVxufVxuXG4vKiBSZWR1Y2VkIG1vdGlvbiBzdXBwb3J0ICovXG5AbWVkaWEgKHByZWZlcnMtcmVkdWNlZC1tb3Rpb246IHJlZHVjZSkge1xuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlLFxuICAgIC5zY3JvbGxUb0JvdHRvbSxcbiAgICAucmF0aW5nTW9kYWwsXG4gICAgLnJhdGluZ01vZGFsQ29udGVudCxcbiAgICAucmF0aW5nQ29uZmlybWF0aW9uIHtcbiAgICAgICAgYW5pbWF0aW9uOiBub25lO1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRNZXNzYWdlIC5tZXNzYWdlVGV4dCxcbiAgICAuY2hhdE1haW5GbG93IC5jaGF0SW5wdXQgdGV4dGFyZWEsXG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdElucHV0IGJ1dHRvbixcbiAgICAvKiBb44qX77iPXSAuY2hhdE1haW5GbG93IC5jaGF0TWVzc2FnZSAuYXZhdGFyIGltZywgKi9cbiAgICAuY2hhdEJ1dHRvbiB7XG4gICAgICAgIHRyYW5zaXRpb246IG5vbmU7XG4gICAgfVxufVxuXG4vKiBIaWdoIGNvbnRyYXN0IG1vZGUgc3VwcG9ydCAqL1xuQG1lZGlhIChwcmVmZXJzLWNvbnRyYXN0OiBoaWdoKSB7XG4gICAgLmNoYXRNYWluRmxvdyAuY2hhdE1lc3NhZ2UgLm1lc3NhZ2VUZXh0IHtcbiAgICAgICAgYm9yZGVyOiAycHggc29saWQgY3VycmVudENvbG9yO1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCB0ZXh0YXJlYSB7XG4gICAgICAgIGJvcmRlci13aWR0aDogM3B4O1xuICAgIH1cblxuICAgIC5jaGF0TWFpbkZsb3cgLmNoYXRJbnB1dCBidXR0b24ge1xuICAgICAgICBib3JkZXI6IDJweCBzb2xpZCBjdXJyZW50Q29sb3I7XG4gICAgfVxufVxuXG4vKipcbiAqIFRPRE86IFvwn4yJXSBEUlkgTWFya2Rvd24gcHJpbWl0aXZlcyBzdHlsaW5nXG4gKi9cbiJdfQ== */";
|
|
11179
|
+
var chatStyles = {"copiedToClipboardMessage":"Chat-module_copiedToClipboardMessage__apCPY","Chat":"Chat-module_Chat__j2eE5","chatMainFlow":"Chat-module_chatMainFlow__--8FE","chatBar":"Chat-module_chatBar__fLECN","TasksInProgress":"Chat-module_TasksInProgress__fQfei","actions":"Chat-module_actions__gTZ5T","portal":"Chat-module_portal__uTOT8","left":"Chat-module_left__7l5Mn","right":"Chat-module_right__ABZrW","chatButton":"Chat-module_chatButton__d9VgA","chatButtonText":"Chat-module_chatButtonText__RkGB-","useTemplateButton":"Chat-module_useTemplateButton__xcJNR","chatChildren":"Chat-module_chatChildren__flOPK","chatMessages":"Chat-module_chatMessages__J2u2N","chatMessage":"Chat-module_chatMessage__nmLaZ","messageSlideIn":"Chat-module_messageSlideIn__soTy2","isNotCompleteMessage":"Chat-module_isNotCompleteMessage__Hj2K7","NonCompleteMessageFiller":"Chat-module_NonCompleteMessageFiller__G5-Ve","messageText":"Chat-module_messageText__XgNyQ","loadingPulse":"Chat-module_loadingPulse__VomRm","ongoingToolCalls":"Chat-module_ongoingToolCalls__NZkQN","completedToolCalls":"Chat-module_completedToolCalls__vI1Qt","ongoingToolCall":"Chat-module_ongoingToolCall__WT3Rc","completedToolCall":"Chat-module_completedToolCall__-q4Cs","toolCallDetails":"Chat-module_toolCallDetails__WUFlD","toolCallData":"Chat-module_toolCallData__UauCO","ongoingToolCallSpinner":"Chat-module_ongoingToolCallSpinner__7g-Ay","toolCallSpinner":"Chat-module_toolCallSpinner__LSiK6","ongoingToolCallName":"Chat-module_ongoingToolCallName__y59-0","typingIndicator":"Chat-module_typingIndicator__S-CT-","avatar":"Chat-module_avatar__gL6bm","typingBubble":"Chat-module_typingBubble__0Lb7B","typingDots":"Chat-module_typingDots__srOBB","typingDot":"Chat-module_typingDot__dnhKT","typingBounce":"Chat-module_typingBounce__1yp2v","isMe":"Chat-module_isMe__nBtaV","ratingStar":"Chat-module_ratingStar__rRfqC","active":"Chat-module_active__lbYL-","copyButtonContainer":"Chat-module_copyButtonContainer__Rij0U","copyButton":"Chat-module_copyButton__DcxT5","copiedTooltip":"Chat-module_copiedTooltip__LH81j","copiedTooltipFadeIn":"Chat-module_copiedTooltipFadeIn__QekO1","copiedTooltipLeft":"Chat-module_copiedTooltipLeft__j-S-5","copiedTooltipRight":"Chat-module_copiedTooltipRight__R-2cE","chat-code-block":"Chat-module_chat-code-block__k8IyS","attachments":"Chat-module_attachments__m1Fts","attachment":"Chat-module_attachment__aE9hK","attachmentIcon":"Chat-module_attachmentIcon__BX3Cy","attachmentName":"Chat-module_attachmentName__aMx56","messageButtons":"Chat-module_messageButtons__WaOob","messageButton":"Chat-module_messageButton__mRnn-","rating":"Chat-module_rating__soc3M","chatInput":"Chat-module_chatInput__1Ecan","fullPageVisual":"Chat-module_fullPageVisual__zNAEy","dragOver":"Chat-module_dragOver__bkS-g","filePreviewContainer":"Chat-module_filePreviewContainer__R70hm","filePreview":"Chat-module_filePreview__kq2aX","fileIcon":"Chat-module_fileIcon__zoSKW","fileInfo":"Chat-module_fileInfo__wBLi0","fileName":"Chat-module_fileName__bBujo","fileSize":"Chat-module_fileSize__ivliq","removeFileButton":"Chat-module_removeFileButton__0gakR","inputContainer":"Chat-module_inputContainer__bPt99","attachmentButton":"Chat-module_attachmentButton__qLO47","voiceButton":"Chat-module_voiceButton__d2zlP","voiceButtonActive":"Chat-module_voiceButtonActive__Uoi3W","voiceRecordingPulse":"Chat-module_voiceRecordingPulse__y2wJ5","uploadProgress":"Chat-module_uploadProgress__jBTKe","uploadProgressBar":"Chat-module_uploadProgressBar__Gutnt","uploadProgressFill":"Chat-module_uploadProgressFill__EgubT","dragOverlay":"Chat-module_dragOverlay__SEGoS","dragOverlayContent":"Chat-module_dragOverlayContent__gb9kF","scrollToBottomContainer":"Chat-module_scrollToBottomContainer__5rXpK","scrollToBottom":"Chat-module_scrollToBottom__nzxdZ","scrollButtonSlideIn":"Chat-module_scrollButtonSlideIn__XnImg","ratingModal":"Chat-module_ratingModal__XVKYm","modalFadeIn":"Chat-module_modalFadeIn__RPc3w","ratingModalContent":"Chat-module_ratingModalContent__CCdq7","modalSlideIn":"Chat-module_modalSlideIn__XXtgN","stars":"Chat-module_stars__PCzNO","ratingModalStar":"Chat-module_ratingModalStar__XkbHr","toolCallModal":"Chat-module_toolCallModal__uNaIK","searchModalHeader":"Chat-module_searchModalHeader__Y8V-w","searchModalIcon":"Chat-module_searchModalIcon__AR5KY","searchModalQuery":"Chat-module_searchModalQuery__5x-Ra","searchModalContent":"Chat-module_searchModalContent__mWLIE","searchResultsList":"Chat-module_searchResultsList__xVDUZ","searchResultItem":"Chat-module_searchResultItem__bTzq5","searchResultUrl":"Chat-module_searchResultUrl__SbrH4","searchResultTitle":"Chat-module_searchResultTitle__XS7zN","searchResultSnippet":"Chat-module_searchResultSnippet__Wsun2","noResults":"Chat-module_noResults__AAv6s","toolCallDataContainer":"Chat-module_toolCallDataContainer__rdEzC","toolCallArgsList":"Chat-module_toolCallArgsList__LD3xH","ratingInput":"Chat-module_ratingInput__z8Pv-","ratingActions":"Chat-module_ratingActions__nXcss","saveButtonContainer":"Chat-module_saveButtonContainer__lSNUJ","saveMenu":"Chat-module_saveMenu__-ph8y","saveMenuItem":"Chat-module_saveMenuItem__ISApL","pauseButton":"Chat-module_pauseButton__eeu7K","pausing":"Chat-module_pausing__pTx8b","paused":"Chat-module_paused__j-pya","voiceCallIndicatorBar":"Chat-module_voiceCallIndicatorBar__N2sWN","voiceCallIndicator":"Chat-module_voiceCallIndicator__tsaaG","voiceCallIconPulse":"Chat-module_voiceCallIconPulse__zZbJn","voiceCallPulse":"Chat-module_voiceCallPulse__XcGU4","ratingConfirmation":"Chat-module_ratingConfirmation__n16vb","confirmationSlideIn":"Chat-module_confirmationSlideIn__5U-wz"};
|
|
9767
11180
|
styleInject(css_248z$2);
|
|
9768
11181
|
|
|
9769
11182
|
var css_248z$1 = ".AvatarProfileTooltip-module_AvatarProfileTooltip__bZ020{background-color:#fff;border:1px solid #ccc;border-radius:10px;box-shadow:0 4px 8px rgba(0,0,0,.1);max-width:300px;padding:20px;position:fixed;z-index:1000}.AvatarProfileTooltip-module_arrow__wmM61{border-color:transparent transparent #fff;border-style:solid;border-width:0 10px 10px;filter:drop-shadow(0 -1px 1px rgba(0,0,0,.1));height:0;left:20px;position:absolute;top:-10px;width:0}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkF2YXRhclByb2ZpbGVUb29sdGlwLm1vZHVsZS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBSUkscUJBQXVCLENBQ3ZCLHFCQUFzQixDQUN0QixrQkFBbUIsQ0FDbkIsbUNBQXdDLENBQ3hDLGVBQWdCLENBTGhCLFlBQWEsQ0FGYixjQUFlLENBQ2YsWUFRSixDQUVBLDBDQVFJLHlDQUF1RCxDQUF2RCxrQkFBdUQsQ0FBdkQsd0JBQXVELENBQ3ZELDZDQUFrRCxDQU5sRCxRQUFTLENBR1QsU0FBVSxDQUxWLGlCQUFrQixDQUlsQixTQUFVLENBSFYsT0FRSiIsImZpbGUiOiJBdmF0YXJQcm9maWxlVG9vbHRpcC5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLkF2YXRhclByb2ZpbGVUb29sdGlwIHtcbiAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgei1pbmRleDogMTAwMDtcbiAgICBwYWRkaW5nOiAyMHB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNjY2M7XG4gICAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgICBib3gtc2hhZG93OiAwIDRweCA4cHggcmdiYSgwLCAwLCAwLCAwLjEpO1xuICAgIG1heC13aWR0aDogMzAwcHg7XG4gICAgLyogW/Cfp6BdIFdoYXQgaXMgdGhlIGJlc3QgbWF4LXdpZHRoIGZvciB0aGUgdG9vbHRpcCAqL1xufVxuXG4uYXJyb3cge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB3aWR0aDogMDtcbiAgICBoZWlnaHQ6IDA7XG4gICAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcbiAgICB0b3A6IC0xMHB4O1xuICAgIGxlZnQ6IDIwcHg7XG4gICAgYm9yZGVyLXdpZHRoOiAwIDEwcHggMTBweCAxMHB4O1xuICAgIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQgdHJhbnNwYXJlbnQgd2hpdGUgdHJhbnNwYXJlbnQ7XG4gICAgZmlsdGVyOiBkcm9wLXNoYWRvdygwIC0xcHggMXB4IHJnYmEoMCwgMCwgMCwgMC4xKSk7XG59XG4iXX0= */";
|
|
@@ -9782,6 +11195,53 @@ const AvatarProfileTooltip = forwardRef(function AvatarProfileTooltip({ agentSou
|
|
|
9782
11195
|
}, children: [jsx("div", { className: styles$1.arrow }), jsx(AvatarProfileFromSource, { agentSource: agentSource })] }), document.body);
|
|
9783
11196
|
});
|
|
9784
11197
|
|
|
11198
|
+
/**
|
|
11199
|
+
* Utility to format tool call information for user-friendly display.
|
|
11200
|
+
*/
|
|
11201
|
+
/**
|
|
11202
|
+
* Technical to user-friendly tool names and emojis
|
|
11203
|
+
*
|
|
11204
|
+
* @private [🧠] Maybe public?
|
|
11205
|
+
*/
|
|
11206
|
+
const TOOL_TITLES = {
|
|
11207
|
+
web_search: { title: 'Searching the web', emoji: '🔎' },
|
|
11208
|
+
useSearchEngine: { title: 'Searching the web', emoji: '🔎' },
|
|
11209
|
+
search: { title: 'Searching the web', emoji: '🔎' },
|
|
11210
|
+
useBrowser: { title: 'Browsing the web', emoji: '🌐' },
|
|
11211
|
+
browse: { title: 'Browsing the web', emoji: '🌐' },
|
|
11212
|
+
// Add more tools here as needed
|
|
11213
|
+
};
|
|
11214
|
+
/**
|
|
11215
|
+
* Gets the user-friendly text for a tool call chiplet.
|
|
11216
|
+
*
|
|
11217
|
+
* @private [🧠] Maybe public?
|
|
11218
|
+
*/
|
|
11219
|
+
function getToolCallChipletText(toolCall) {
|
|
11220
|
+
const toolInfo = TOOL_TITLES[toolCall.name];
|
|
11221
|
+
const baseTitle = (toolInfo === null || toolInfo === void 0 ? void 0 : toolInfo.title) || toolCall.name;
|
|
11222
|
+
const emoji = (toolInfo === null || toolInfo === void 0 ? void 0 : toolInfo.emoji) || '🛠️';
|
|
11223
|
+
let args = {};
|
|
11224
|
+
try {
|
|
11225
|
+
args = typeof toolCall.arguments === 'string' ? JSON.parse(toolCall.arguments) : toolCall.arguments || {};
|
|
11226
|
+
}
|
|
11227
|
+
catch (e) {
|
|
11228
|
+
// Ignore parse errors
|
|
11229
|
+
}
|
|
11230
|
+
if (args.query) {
|
|
11231
|
+
return `${emoji} ${args.query}`;
|
|
11232
|
+
}
|
|
11233
|
+
if (args.url) {
|
|
11234
|
+
try {
|
|
11235
|
+
const url = new URL(args.url);
|
|
11236
|
+
return `${emoji} ${url.hostname}`;
|
|
11237
|
+
}
|
|
11238
|
+
catch (e) {
|
|
11239
|
+
return `${emoji} ${args.url}`;
|
|
11240
|
+
}
|
|
11241
|
+
}
|
|
11242
|
+
return `${emoji} ${baseTitle}`;
|
|
11243
|
+
}
|
|
11244
|
+
|
|
9785
11245
|
/**
|
|
9786
11246
|
* Parses markdown buttons in the format [Button Text](?message=Message%20to%20send)
|
|
9787
11247
|
* Returns both the content without buttons and the extracted buttons
|
|
@@ -9833,7 +11293,7 @@ const AVATAR_SIZE = 40;
|
|
|
9833
11293
|
*
|
|
9834
11294
|
* @private internal subcomponent of `<Chat>` component
|
|
9835
11295
|
*/
|
|
9836
|
-
const ChatMessageItem = memo(({ message, participant, participants, isLastMessage, onMessage, setExpandedMessageId, isExpanded, currentRating, handleRating, mode, isCopyButtonEnabled, isFeedbackEnabled, onCopy, onCreateAgent, }) => {
|
|
11296
|
+
const ChatMessageItem = memo(({ message, participant, participants, isLastMessage, onMessage, setExpandedMessageId, isExpanded, currentRating, handleRating, mode, isCopyButtonEnabled, isFeedbackEnabled, onCopy, onCreateAgent, toolTitles, onToolCallClick, }) => {
|
|
9837
11297
|
const avatarSrc = (participant === null || participant === void 0 ? void 0 : participant.avatarSrc) || null;
|
|
9838
11298
|
const [isAvatarTooltipVisible, setIsAvatarTooltipVisible] = useState(false);
|
|
9839
11299
|
const [avatarTooltipPosition, setAvatarTooltipPosition] = useState(null);
|
|
@@ -9984,7 +11444,20 @@ const ChatMessageItem = memo(({ message, participant, participants, isLastMessag
|
|
|
9984
11444
|
? ' ' + chatStyles.copiedTooltipLeft
|
|
9985
11445
|
: tooltipAlign === 'right'
|
|
9986
11446
|
? ' ' + chatStyles.copiedTooltipRight
|
|
9987
|
-
: ''), children: "Copied!" }))] }) })), message.isVoiceCall && (jsx("div", { className: chatStyles.voiceCallIndicator, children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }) })), message.content === LOADING_INTERACTIVE_IMAGE ? (jsx(Fragment, {})) : (jsx("div", { ref: contentWithoutButtonsRef, children: jsx(MarkdownContent, { content: contentWithoutButtons, onCreateAgent: onCreateAgent }) })), message.attachments && message.attachments.length > 0 && (jsx("div", { className: chatStyles.attachments, children: message.attachments.map((attachment, index) => (jsxs("a", { href: attachment.url, target: "_blank", rel: "noopener noreferrer", className: chatStyles.attachment, title: attachment.name, children: [jsx("span", { className: chatStyles.attachmentIcon, children: "\uD83D\uDCCE" }), jsx("span", { className: chatStyles.attachmentName, children: attachment.name })] }, index))) })),
|
|
11447
|
+
: ''), children: "Copied!" }))] }) })), message.isVoiceCall && (jsx("div", { className: chatStyles.voiceCallIndicator, children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }) })), message.content === LOADING_INTERACTIVE_IMAGE ? (jsx(Fragment, {})) : (jsx("div", { ref: contentWithoutButtonsRef, children: jsx(MarkdownContent, { content: contentWithoutButtons, onCreateAgent: onCreateAgent }) })), message.attachments && message.attachments.length > 0 && (jsx("div", { className: chatStyles.attachments, children: message.attachments.map((attachment, index) => (jsxs("a", { href: attachment.url, target: "_blank", rel: "noopener noreferrer", className: chatStyles.attachment, title: attachment.name, children: [jsx("span", { className: chatStyles.attachmentIcon, children: "\uD83D\uDCCE" }), jsx("span", { className: chatStyles.attachmentName, children: attachment.name })] }, index))) })), message.completedToolCalls && message.completedToolCalls.length > 0 && (jsx("div", { className: chatStyles.completedToolCalls, children: message.completedToolCalls.map((toolCall, index) => {
|
|
11448
|
+
const chipletText = getToolCallChipletText(toolCall);
|
|
11449
|
+
return (jsxs("button", { className: chatStyles.completedToolCall, onClick: (event) => {
|
|
11450
|
+
event.stopPropagation();
|
|
11451
|
+
if (onToolCallClick) {
|
|
11452
|
+
onToolCallClick(toolCall);
|
|
11453
|
+
}
|
|
11454
|
+
}, children: ["[", chipletText, "]"] }, index));
|
|
11455
|
+
}) })), !message.isComplete && (jsx("div", { className: chatStyles.ongoingToolCalls, children: message.ongoingToolCalls && message.ongoingToolCalls.length > 0 ? (message.ongoingToolCalls.map((toolCall, index) => {
|
|
11456
|
+
const toolInfo = TOOL_TITLES[toolCall.name];
|
|
11457
|
+
const toolTitle = (toolTitles === null || toolTitles === void 0 ? void 0 : toolTitles[toolCall.name]) || (toolInfo === null || toolInfo === void 0 ? void 0 : toolInfo.title);
|
|
11458
|
+
const emoji = (toolInfo === null || toolInfo === void 0 ? void 0 : toolInfo.emoji) || '🛠️';
|
|
11459
|
+
return (jsxs("div", { className: chatStyles.ongoingToolCall, children: [jsx("div", { className: chatStyles.ongoingToolCallSpinner }), jsx("span", { className: chatStyles.ongoingToolCallName, children: toolTitle ? `${emoji} ${toolTitle}...` : `${emoji} Executing ${toolCall.name}...` })] }, index));
|
|
11460
|
+
})) : (jsx("span", { className: chatStyles.NonCompleteMessageFiller, children: '_'.repeat(70) })) })), shouldShowButtons && (jsx("div", { className: chatStyles.messageButtons, children: buttons.map((button, buttonIndex) => (jsx("button", { className: chatStyles.messageButton, onClick: (event) => {
|
|
9988
11461
|
event.stopPropagation();
|
|
9989
11462
|
if (onMessage) {
|
|
9990
11463
|
onMessage(button.message);
|
|
@@ -10040,6 +11513,12 @@ const ChatMessageItem = memo(({ message, participant, participants, isLastMessag
|
|
|
10040
11513
|
if (prev.handleRating !== next.handleRating) {
|
|
10041
11514
|
return false;
|
|
10042
11515
|
}
|
|
11516
|
+
if (prev.toolTitles !== next.toolTitles) {
|
|
11517
|
+
return false;
|
|
11518
|
+
}
|
|
11519
|
+
if (prev.onToolCallClick !== next.onToolCallClick) {
|
|
11520
|
+
return false;
|
|
11521
|
+
}
|
|
10043
11522
|
return prev.mode === next.mode;
|
|
10044
11523
|
});
|
|
10045
11524
|
ChatMessageItem.displayName = 'ChatMessageItem';
|
|
@@ -10059,7 +11538,7 @@ ChatMessageItem.displayName = 'ChatMessageItem';
|
|
|
10059
11538
|
*/
|
|
10060
11539
|
function Chat(props) {
|
|
10061
11540
|
var _a;
|
|
10062
|
-
const { title = 'Chat', messages, onChange, onMessage, onReset, onFeedback, onFileUpload,
|
|
11541
|
+
const { title = 'Chat', messages, onChange, onMessage, onReset, onFeedback, onFileUpload, speechRecognition,
|
|
10063
11542
|
// isVoiceRecognitionButtonShown,
|
|
10064
11543
|
// voiceLanguage = 'en-US',
|
|
10065
11544
|
placeholderMessageContent, defaultMessage,
|
|
@@ -10070,7 +11549,7 @@ function Chat(props) {
|
|
|
10070
11549
|
// isExperimental = false,
|
|
10071
11550
|
// TODO: [😅]> isSaveButtonEnabled = false,
|
|
10072
11551
|
// exportHeaderMarkdown,
|
|
10073
|
-
participants = [], extraActions, actionsContainer, saveFormats, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, onCreateAgent, } = props;
|
|
11552
|
+
participants = [], extraActions, actionsContainer, saveFormats, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, onCreateAgent, toolTitles, visual, } = props;
|
|
10074
11553
|
const buttonColor = useMemo(() => Color.from(buttonColorRaw || '#0066cc'), [buttonColorRaw]);
|
|
10075
11554
|
// Use the auto-scroll hook
|
|
10076
11555
|
const { isAutoScrolling, chatMessagesRef, handleScroll, handleMessagesChange, scrollToBottom, isMobile: isMobileFromHook, } = useChatAutoScroll();
|
|
@@ -10078,6 +11557,8 @@ function Chat(props) {
|
|
|
10078
11557
|
const buttonSendRef = useRef(null);
|
|
10079
11558
|
const fileInputRef = useRef(null);
|
|
10080
11559
|
const [ratingModalOpen, setRatingModalOpen] = useState(false);
|
|
11560
|
+
const [toolCallModalOpen, setToolCallModalOpen] = useState(false);
|
|
11561
|
+
const [selectedToolCall, setSelectedToolCall] = useState(null);
|
|
10081
11562
|
const [selectedMessage, setSelectedMessage] = useState(null);
|
|
10082
11563
|
const [messageRatings, setMessageRatings] = useState(new Map());
|
|
10083
11564
|
const [textRating, setTextRating] = useState('');
|
|
@@ -10093,6 +11574,9 @@ function Chat(props) {
|
|
|
10093
11574
|
const [uploadedFiles, setUploadedFiles] = useState([]);
|
|
10094
11575
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
10095
11576
|
const [isUploading, setIsUploading] = useState(false);
|
|
11577
|
+
// Voice recognition state
|
|
11578
|
+
const [speechRecognitionState, setSpeechRecognitionState] = useState('IDLE');
|
|
11579
|
+
const [speechRecognitionText, setSpeechRecognitionText] = useState('');
|
|
10096
11580
|
// Use mobile detection from the hook
|
|
10097
11581
|
const isMobile = isMobileFromHook;
|
|
10098
11582
|
useEffect(( /* Focus textarea on page load */) => {
|
|
@@ -10104,7 +11588,61 @@ function Chat(props) {
|
|
|
10104
11588
|
if (isFocused) {
|
|
10105
11589
|
textareaRef.current.focus();
|
|
10106
11590
|
}
|
|
10107
|
-
}, [textareaRef, isMobile]);
|
|
11591
|
+
}, [textareaRef, isMobile, isFocusedOnLoad]);
|
|
11592
|
+
// Voice recognition effects
|
|
11593
|
+
useEffect(() => {
|
|
11594
|
+
if (!speechRecognition) {
|
|
11595
|
+
return;
|
|
11596
|
+
}
|
|
11597
|
+
const unsubscribe = speechRecognition.subscribe((event) => {
|
|
11598
|
+
if (event.type === 'START') {
|
|
11599
|
+
setSpeechRecognitionState('RECORDING');
|
|
11600
|
+
setSpeechRecognitionText('');
|
|
11601
|
+
}
|
|
11602
|
+
else if (event.type === 'RESULT') {
|
|
11603
|
+
setSpeechRecognitionText(event.text);
|
|
11604
|
+
if (textareaRef.current) {
|
|
11605
|
+
const textarea = textareaRef.current;
|
|
11606
|
+
const currentValue = textarea.value;
|
|
11607
|
+
const lastResult = speechRecognitionText;
|
|
11608
|
+
// If the current value ends with the last interim result, replace it
|
|
11609
|
+
if (lastResult && currentValue.endsWith(lastResult)) {
|
|
11610
|
+
textarea.value = currentValue.slice(0, -lastResult.length) + event.text;
|
|
11611
|
+
}
|
|
11612
|
+
else {
|
|
11613
|
+
// Otherwise just append with a space if needed
|
|
11614
|
+
const separator = currentValue && !currentValue.endsWith(' ') ? ' ' : '';
|
|
11615
|
+
textarea.value += separator + event.text;
|
|
11616
|
+
}
|
|
11617
|
+
if (onChange) {
|
|
11618
|
+
onChange(textarea.value);
|
|
11619
|
+
}
|
|
11620
|
+
}
|
|
11621
|
+
}
|
|
11622
|
+
else if (event.type === 'ERROR') {
|
|
11623
|
+
setSpeechRecognitionState('ERROR');
|
|
11624
|
+
alert(`Speech recognition error: ${event.message}`);
|
|
11625
|
+
}
|
|
11626
|
+
else if (event.type === 'STOP') {
|
|
11627
|
+
setSpeechRecognitionState('IDLE');
|
|
11628
|
+
setSpeechRecognitionText('');
|
|
11629
|
+
}
|
|
11630
|
+
});
|
|
11631
|
+
return () => {
|
|
11632
|
+
unsubscribe();
|
|
11633
|
+
};
|
|
11634
|
+
}, [speechRecognition, onChange, speechRecognitionText]);
|
|
11635
|
+
const handleToggleVoiceInput = useCallback(() => {
|
|
11636
|
+
if (!speechRecognition) {
|
|
11637
|
+
return;
|
|
11638
|
+
}
|
|
11639
|
+
if (speechRecognition.state === 'IDLE' || speechRecognition.state === 'ERROR') {
|
|
11640
|
+
speechRecognition.$start({ language: /* 'en-US' */ 'en' });
|
|
11641
|
+
}
|
|
11642
|
+
else {
|
|
11643
|
+
speechRecognition.$stop();
|
|
11644
|
+
}
|
|
11645
|
+
}, [speechRecognition]);
|
|
10108
11646
|
// File upload handlers inspired by BookEditor
|
|
10109
11647
|
const handleFileUpload = useCallback(async (files) => {
|
|
10110
11648
|
if (!onFileUpload)
|
|
@@ -10332,7 +11870,7 @@ function Chat(props) {
|
|
|
10332
11870
|
const isFeedbackEnabled = !!onFeedback;
|
|
10333
11871
|
// Handler for copy button
|
|
10334
11872
|
const handleCopy = () => { };
|
|
10335
|
-
return (jsxs(Fragment, { children: [ratingConfirmation && jsx("div", { className: chatStyles.ratingConfirmation, children: ratingConfirmation }), jsx("div", { className: classNames(className, chatStyles.Chat, useChatCssClassName('Chat')), style, children: jsxs("div", { className: classNames(className, chatStyles.chatMainFlow, useChatCssClassName('chatMainFlow')), children: [children && jsx("div", { className: classNames(chatStyles.chatChildren), children: children }), !isAutoScrolling && (jsx("div", { className: chatStyles.scrollToBottomContainer, children: jsx("button", { "data-button-type": "custom", className: classNames(chatStyles.scrollToBottom, scrollToBottomCssClassName), onClick: scrollToBottom, children: jsx(ArrowIcon, { direction: "DOWN", size: 33 }) }) })), isVoiceCalling && (jsx("div", { className: chatStyles.voiceCallIndicatorBar, children: jsxs("div", { className: chatStyles.voiceCallIndicator, children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }), jsx("span", { children: "Voice call active" }), jsx("div", { className: chatStyles.voiceCallPulse })] }) })), (() => {
|
|
11873
|
+
return (jsxs(Fragment, { children: [ratingConfirmation && jsx("div", { className: chatStyles.ratingConfirmation, children: ratingConfirmation }), jsx("div", { className: classNames(className, chatStyles.Chat, visual === 'STANDALONE' && chatStyles.standaloneVisual, visual === 'FULL_PAGE' && chatStyles.fullPageVisual, useChatCssClassName('Chat')), style, children: jsxs("div", { className: classNames(className, chatStyles.chatMainFlow, useChatCssClassName('chatMainFlow')), children: [children && jsx("div", { className: classNames(chatStyles.chatChildren), children: children }), !isAutoScrolling && (jsx("div", { className: chatStyles.scrollToBottomContainer, children: jsx("button", { "data-button-type": "custom", className: classNames(chatStyles.scrollToBottom, scrollToBottomCssClassName), onClick: scrollToBottom, children: jsx(ArrowIcon, { direction: "DOWN", size: 33 }) }) })), isVoiceCalling && (jsx("div", { className: chatStyles.voiceCallIndicatorBar, children: jsxs("div", { className: chatStyles.voiceCallIndicator, children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }), jsx("span", { children: "Voice call active" }), jsx("div", { className: chatStyles.voiceCallPulse })] }) })), (() => {
|
|
10336
11874
|
const actionsContent = (jsxs("div", { className: classNames(actionsAlignmentClass, actionsContainer && chatStyles.portal), children: [onReset && postprocessedMessages.length !== 0 && (jsxs("button", { className: classNames(chatStyles.chatButton), onClick: () => {
|
|
10337
11875
|
if (!confirm(`Do you really want to reset the chat?`)) {
|
|
10338
11876
|
return;
|
|
@@ -10369,7 +11907,10 @@ function Chat(props) {
|
|
|
10369
11907
|
const isLastMessage = i === postprocessedMessages.length - 1;
|
|
10370
11908
|
const isExpanded = expandedMessageId === message.id;
|
|
10371
11909
|
const currentRating = messageRatings.get(message.id || message.content /* <-[💃] */) || 0;
|
|
10372
|
-
return (jsx(ChatMessageItem, { message: message, participant: participant, participants: participants, isLastMessage: isLastMessage, onMessage: onMessage, setExpandedMessageId: setExpandedMessageId, isExpanded: isExpanded, currentRating: currentRating, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, onCopy: handleCopy, onCreateAgent: onCreateAgent
|
|
11910
|
+
return (jsx(ChatMessageItem, { message: message, participant: participant, participants: participants, isLastMessage: isLastMessage, onMessage: onMessage, setExpandedMessageId: setExpandedMessageId, isExpanded: isExpanded, currentRating: currentRating, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, onCopy: handleCopy, onCreateAgent: onCreateAgent, toolTitles: toolTitles, onToolCallClick: (toolCall) => {
|
|
11911
|
+
setSelectedToolCall(toolCall);
|
|
11912
|
+
setToolCallModalOpen(true);
|
|
11913
|
+
} }, message.id));
|
|
10373
11914
|
}), jsx("div", {
|
|
10374
11915
|
// Note: Extra space at bottom for input area
|
|
10375
11916
|
style: { height: 100 } })] }), onMessage && (jsxs("div", { className: classNames(chatStyles.chatInput, useChatCssClassName('chatInput'), isDragOver && chatStyles.dragOver), ...(onFileUpload
|
|
@@ -10390,6 +11931,7 @@ function Chat(props) {
|
|
|
10390
11931
|
// <- TODO: Remove
|
|
10391
11932
|
'--input-bg-color': inputBgColor.toHex(),
|
|
10392
11933
|
'--input-text-color': inputTextColor.toHex(),
|
|
11934
|
+
'--brand-color': buttonColor.toHex(),
|
|
10393
11935
|
}, children: [jsx("textarea", { ref: (element) => {
|
|
10394
11936
|
textareaRef.current = element;
|
|
10395
11937
|
}, style: {
|
|
@@ -10418,13 +11960,27 @@ function Chat(props) {
|
|
|
10418
11960
|
} }), onFileUpload && (jsxs(Fragment, { children: [jsx("input", { ref: fileInputRef, type: "file", multiple: true, style: { display: 'none' }, onChange: handleFileInputChange }), jsx("button", { type: "button", style: {
|
|
10419
11961
|
backgroundColor: buttonColor.toHex(),
|
|
10420
11962
|
color: buttonColor.then(textColor).toHex(),
|
|
10421
|
-
}, className: chatStyles.attachmentButton, onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: isUploading, title: "Attach file", children: jsx(AttachmentIcon, { size: 20 }) })] })),
|
|
10422
|
-
|
|
10423
|
-
|
|
10424
|
-
|
|
11963
|
+
}, className: chatStyles.attachmentButton, onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: isUploading, title: "Attach file", children: jsx(AttachmentIcon, { size: 20 }) })] })), speechRecognition && (jsx("button", { "data-button-type": "voice", disabled: speechRecognitionState === 'STARTING' ||
|
|
11964
|
+
speechRecognitionState === 'TRANSCRIBING', style: {
|
|
11965
|
+
backgroundColor: (speechRecognitionState === 'RECORDING' ||
|
|
11966
|
+
speechRecognitionState === 'TRANSCRIBING'
|
|
11967
|
+
? Color.from('#ff4444')
|
|
11968
|
+
: buttonColor).toHex(),
|
|
11969
|
+
color: (speechRecognitionState === 'RECORDING' ||
|
|
11970
|
+
speechRecognitionState === 'TRANSCRIBING'
|
|
11971
|
+
? Color.from('#ffffff')
|
|
11972
|
+
: buttonColor.then(textColor)).toHex(),
|
|
11973
|
+
}, className: classNames(chatStyles.voiceButton, (isVoiceCalling ||
|
|
11974
|
+
speechRecognitionState === 'RECORDING' ||
|
|
11975
|
+
speechRecognitionState === 'TRANSCRIBING') &&
|
|
11976
|
+
chatStyles.voiceButtonActive), onClick: (event) => {
|
|
10425
11977
|
event.preventDefault();
|
|
10426
|
-
|
|
10427
|
-
}, title:
|
|
11978
|
+
handleToggleVoiceInput();
|
|
11979
|
+
}, title: speechRecognitionState === 'RECORDING'
|
|
11980
|
+
? 'Stop recording'
|
|
11981
|
+
: speechRecognitionState === 'TRANSCRIBING'
|
|
11982
|
+
? 'Transcribing...'
|
|
11983
|
+
: 'Start voice input', children: jsx(MicIcon, { size: 25 }) })), jsx("button", { "data-button-type": "call-to-action", style: {
|
|
10428
11984
|
backgroundColor: buttonColor.toHex(),
|
|
10429
11985
|
color: buttonColor.then(textColor).toHex(),
|
|
10430
11986
|
}, ref: buttonSendRef, onClick: (event) => {
|
|
@@ -10434,7 +11990,33 @@ function Chat(props) {
|
|
|
10434
11990
|
event.preventDefault();
|
|
10435
11991
|
/* not await */ handleSend();
|
|
10436
11992
|
}, children: jsx(SendIcon, { size: 25 }) })] }));
|
|
10437
|
-
})(), isUploading && (jsxs("div", { className: chatStyles.uploadProgress, children: [jsx("div", { className: chatStyles.uploadProgressBar, children: jsx("div", { className: chatStyles.uploadProgressFill }) }), jsx("span", { children: "Uploading files..." })] })), isDragOver && onFileUpload && (jsx("div", { className: chatStyles.dragOverlay, children: jsxs("div", { className: chatStyles.dragOverlayContent, children: [jsx(AttachmentIcon, { size: 48 }), jsx("span", { children: "Drop files here to upload" })] }) }))] }))] }) }),
|
|
11993
|
+
})(), isUploading && (jsxs("div", { className: chatStyles.uploadProgress, children: [jsx("div", { className: chatStyles.uploadProgressBar, children: jsx("div", { className: chatStyles.uploadProgressFill }) }), jsx("span", { children: "Uploading files..." })] })), isDragOver && onFileUpload && (jsx("div", { className: chatStyles.dragOverlay, children: jsxs("div", { className: chatStyles.dragOverlayContent, children: [jsx(AttachmentIcon, { size: 48 }), jsx("span", { children: "Drop files here to upload" })] }) }))] }))] }) }), toolCallModalOpen && selectedToolCall && (jsx("div", { className: chatStyles.ratingModal, onClick: (e) => {
|
|
11994
|
+
if (e.target === e.currentTarget) {
|
|
11995
|
+
setToolCallModalOpen(false);
|
|
11996
|
+
}
|
|
11997
|
+
}, children: jsxs("div", { className: classNames(chatStyles.ratingModalContent, chatStyles.toolCallModal), children: [(() => {
|
|
11998
|
+
const isSearch = selectedToolCall.name === 'web_search' ||
|
|
11999
|
+
selectedToolCall.name === 'useSearchEngine' ||
|
|
12000
|
+
selectedToolCall.name === 'search';
|
|
12001
|
+
const args = typeof selectedToolCall.arguments === 'string'
|
|
12002
|
+
? JSON.parse(selectedToolCall.arguments)
|
|
12003
|
+
: selectedToolCall.arguments || {};
|
|
12004
|
+
const resultRaw = selectedToolCall.result;
|
|
12005
|
+
const results = Array.isArray(resultRaw)
|
|
12006
|
+
? resultRaw
|
|
12007
|
+
: resultRaw && typeof resultRaw === 'object' && Array.isArray(resultRaw.results)
|
|
12008
|
+
? resultRaw.results
|
|
12009
|
+
: [];
|
|
12010
|
+
if (isSearch) {
|
|
12011
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: chatStyles.searchModalHeader, children: [jsx("span", { className: chatStyles.searchModalIcon, children: "\uD83D\uDD0E" }), jsx("h3", { className: chatStyles.searchModalQuery, children: args.query || 'Search Results' })] }), jsx("div", { className: chatStyles.searchModalContent, children: results.length > 0 ? (jsx("div", { className: chatStyles.searchResultsList, children: results.map((item, i) => (jsxs("div", { className: chatStyles.searchResultItem, children: [jsx("div", { className: chatStyles.searchResultUrl, children: item.url && (jsx("a", { href: item.url, target: "_blank", rel: "noreferrer", children: item.url })) }), jsx("h4", { className: chatStyles.searchResultTitle, children: item.url ? (jsx("a", { href: item.url, target: "_blank", rel: "noreferrer", children: item.title || 'Untitled' })) : (item.title || 'Untitled') }), jsx("p", { className: chatStyles.searchResultSnippet, children: item.snippet || item.content || '' })] }, i))) })) : (jsx("div", { className: chatStyles.noResults, children: resultRaw ? 'No search results found.' : 'Executing search...' })) })] }));
|
|
12012
|
+
}
|
|
12013
|
+
// Fallback for other tools
|
|
12014
|
+
return (jsxs(Fragment, { children: [jsxs("h3", { children: ["Tool Call: ", (toolTitles === null || toolTitles === void 0 ? void 0 : toolTitles[selectedToolCall.name]) || selectedToolCall.name] }), jsxs("div", { className: chatStyles.toolCallDetails, children: [jsx("p", { children: jsx("strong", { children: "Arguments:" }) }), jsx("div", { className: chatStyles.toolCallDataContainer, children: args && typeof args === 'object' ? (jsx("ul", { className: chatStyles.toolCallArgsList, children: Object.entries(args).map(([key, value]) => (jsxs("li", { children: [jsxs("strong", { children: [key, ":"] }), ' ', typeof value === 'object'
|
|
12015
|
+
? JSON.stringify(value)
|
|
12016
|
+
: String(value)] }, key))) })) : (jsx("pre", { className: chatStyles.toolCallData, children: String(args) })) }), jsx("p", { children: jsx("strong", { children: "Result:" }) }), jsx("div", { className: chatStyles.toolCallDataContainer, children: jsx("pre", { className: chatStyles.toolCallData, children: typeof resultRaw === 'object'
|
|
12017
|
+
? JSON.stringify(resultRaw, null, 4)
|
|
12018
|
+
: String(resultRaw) }) })] })] }));
|
|
12019
|
+
})(), jsx("div", { className: chatStyles.ratingActions, children: jsx("button", { onClick: () => setToolCallModalOpen(false), children: "Close" }) })] }) })), ratingModalOpen && selectedMessage && (jsx("div", { className: chatStyles.ratingModal, onClick: (e) => {
|
|
10438
12020
|
// Close modal when clicking backdrop on mobile
|
|
10439
12021
|
if (e.target === e.currentTarget && isMobile) {
|
|
10440
12022
|
setRatingModalOpen(false);
|
|
@@ -10565,20 +12147,16 @@ ChatPersistence.STORAGE_PREFIX = 'promptbook_chat_';
|
|
|
10565
12147
|
* @public exported from `@promptbook/components`
|
|
10566
12148
|
*/
|
|
10567
12149
|
function LlmChat(props) {
|
|
10568
|
-
const { llmTools, persistenceKey, onChange, onReset, initialMessages, sendMessage, userParticipantName = 'USER', llmParticipantName = 'ASSISTANT', autoExecuteMessage, buttonColor, ...restProps } = props;
|
|
12150
|
+
const { llmTools, persistenceKey, onChange, onReset, initialMessages, sendMessage, userParticipantName = 'USER', llmParticipantName = 'ASSISTANT', autoExecuteMessage, buttonColor, toolTitles, ...restProps } = props;
|
|
10569
12151
|
// Internal state management
|
|
10570
12152
|
// DRY: Single factory for seeding initial messages (used on mount and after reset)
|
|
10571
12153
|
const buildInitialMessages = useCallback(() => initialMessages ? ([...initialMessages]) : ([]), [initialMessages]);
|
|
10572
12154
|
const [messages, setMessages] = useState(() => buildInitialMessages());
|
|
10573
12155
|
const [tasksProgress, setTasksProgress] = useState([]);
|
|
10574
|
-
const [isVoiceCalling
|
|
10575
|
-
|
|
10576
|
-
// Refs to keep latest state for long-lived voice handlers
|
|
12156
|
+
const [isVoiceCalling] = useState(false);
|
|
12157
|
+
// Refs to keep latest state for long-lived handlers
|
|
10577
12158
|
const messagesRef = useRef([]);
|
|
10578
12159
|
const participantsRef = useRef([]);
|
|
10579
|
-
const isProcessingVoiceChunkRef = useRef(false);
|
|
10580
|
-
const allVoiceChunksRef = useRef([]);
|
|
10581
|
-
const utteranceTimeoutRef = useRef(null);
|
|
10582
12160
|
/**
|
|
10583
12161
|
* Tracks whether the user (or system via persistence restoration) has interacted.
|
|
10584
12162
|
* We do NOT persist purely initialMessages until the user sends something.
|
|
@@ -10607,164 +12185,25 @@ function LlmChat(props) {
|
|
|
10607
12185
|
// Generate participants from llmTools
|
|
10608
12186
|
const participants = useMemo(() => props.participants || [
|
|
10609
12187
|
{
|
|
10610
|
-
name: userParticipantName,
|
|
10611
|
-
fullname: 'You',
|
|
10612
|
-
isMe: true,
|
|
10613
|
-
color: '#1D4ED8',
|
|
10614
|
-
},
|
|
10615
|
-
// Use the profile from llmTools if available, otherwise fallback to default
|
|
10616
|
-
llmTools.profile || {
|
|
10617
|
-
name: llmParticipantName,
|
|
10618
|
-
fullname: llmTools.title || 'AI Assistant',
|
|
10619
|
-
color: '#10b981',
|
|
10620
|
-
},
|
|
10621
|
-
], [llmTools.profile, llmTools.title]);
|
|
10622
|
-
// Keep refs in sync for usage inside long-lived callbacks
|
|
10623
|
-
useEffect(() => {
|
|
10624
|
-
messagesRef.current = messages;
|
|
10625
|
-
}, [messages]);
|
|
10626
|
-
useEffect(() => {
|
|
10627
|
-
participantsRef.current = participants;
|
|
10628
|
-
}, [participants]);
|
|
10629
|
-
// Handle voice input in a fluent, multi-message way:
|
|
10630
|
-
// - While the call is active we keep recording audio.
|
|
10631
|
-
// - When the user is silent for ~2 seconds, we treat it as the end of an utterance
|
|
10632
|
-
// and send one combined audio blob to the agent (one agent turn per utterance).
|
|
10633
|
-
const processCurrentUtterance = useCallback(async () => {
|
|
10634
|
-
var _a;
|
|
10635
|
-
if (!llmTools.callVoiceChatModel) {
|
|
10636
|
-
return;
|
|
10637
|
-
}
|
|
10638
|
-
if (isProcessingVoiceChunkRef.current) {
|
|
10639
|
-
return;
|
|
10640
|
-
}
|
|
10641
|
-
const chunks = allVoiceChunksRef.current;
|
|
10642
|
-
if (!chunks.length) {
|
|
10643
|
-
return;
|
|
10644
|
-
}
|
|
10645
|
-
isProcessingVoiceChunkRef.current = true;
|
|
10646
|
-
allVoiceChunksRef.current = [];
|
|
10647
|
-
const blob = new Blob(chunks, {
|
|
10648
|
-
type: ((_a = chunks[0]) === null || _a === void 0 ? void 0 : _a.type) || 'audio/webm',
|
|
10649
|
-
});
|
|
10650
|
-
const taskId = `voice_call_${Date.now()}`;
|
|
10651
|
-
setTasksProgress([{ id: taskId, name: 'Processing voice...', progress: 50 }]);
|
|
10652
|
-
try {
|
|
10653
|
-
const thread = props.thread ? [...props.thread] : [...messagesRef.current];
|
|
10654
|
-
const result = await llmTools.callVoiceChatModel(blob, {
|
|
10655
|
-
title: 'Voice Message',
|
|
10656
|
-
content: '',
|
|
10657
|
-
parameters: {},
|
|
10658
|
-
modelRequirements: { modelVariant: 'CHAT' },
|
|
10659
|
-
thread,
|
|
10660
|
-
});
|
|
10661
|
-
setTasksProgress([{ id: taskId, name: 'Playing response...', progress: 100 }]);
|
|
10662
|
-
const now = Date.now();
|
|
10663
|
-
const userMessage = {
|
|
10664
|
-
// channel: 'PROMPTBOOK_CHAT',
|
|
10665
|
-
id: `user_${now}`,
|
|
10666
|
-
createdAt: new Date(),
|
|
10667
|
-
sender: userParticipantName,
|
|
10668
|
-
content: (result.userMessage || '(Voice message)'),
|
|
10669
|
-
isComplete: true,
|
|
10670
|
-
isVoiceCall: true,
|
|
10671
|
-
};
|
|
10672
|
-
const agentMessage = {
|
|
10673
|
-
// channel: 'PROMPTBOOK_CHAT',
|
|
10674
|
-
id: `agent_${now}`,
|
|
10675
|
-
createdAt: new Date(),
|
|
10676
|
-
sender: llmParticipantName,
|
|
10677
|
-
content: (result.agentMessage || result.text),
|
|
10678
|
-
isComplete: true,
|
|
10679
|
-
isVoiceCall: true,
|
|
10680
|
-
};
|
|
10681
|
-
setMessages((prevMessages) => {
|
|
10682
|
-
const newMessages = [...prevMessages, userMessage, agentMessage];
|
|
10683
|
-
messagesRef.current = newMessages;
|
|
10684
|
-
if (onChange) {
|
|
10685
|
-
onChange(newMessages, participantsRef.current);
|
|
10686
|
-
}
|
|
10687
|
-
return newMessages;
|
|
10688
|
-
});
|
|
10689
|
-
// Play audio
|
|
10690
|
-
const audioUrl = URL.createObjectURL(result.audio);
|
|
10691
|
-
const audioEl = new Audio(audioUrl);
|
|
10692
|
-
audioEl.play();
|
|
10693
|
-
setTimeout(() => setTasksProgress([]), 1000);
|
|
10694
|
-
}
|
|
10695
|
-
catch (error) {
|
|
10696
|
-
console.error('Error calling Voice LLM:', error);
|
|
10697
|
-
setTasksProgress([]);
|
|
10698
|
-
}
|
|
10699
|
-
finally {
|
|
10700
|
-
isProcessingVoiceChunkRef.current = false;
|
|
10701
|
-
}
|
|
10702
|
-
}, [llmTools, onChange, userParticipantName, llmParticipantName, props.thread]);
|
|
10703
|
-
const handleVoiceInput = useCallback(async () => {
|
|
10704
|
-
if (!llmTools.callVoiceChatModel) {
|
|
10705
|
-
return;
|
|
10706
|
-
}
|
|
10707
|
-
if (isVoiceCalling) {
|
|
10708
|
-
// Stop recording and end call
|
|
10709
|
-
const recorder = mediaRecorderRef.current;
|
|
10710
|
-
if (recorder) {
|
|
10711
|
-
recorder.stop();
|
|
10712
|
-
}
|
|
10713
|
-
mediaRecorderRef.current = null;
|
|
10714
|
-
setIsVoiceCalling(false);
|
|
10715
|
-
// Process any remaining audio as the final utterance
|
|
10716
|
-
if (utteranceTimeoutRef.current) {
|
|
10717
|
-
clearTimeout(utteranceTimeoutRef.current);
|
|
10718
|
-
utteranceTimeoutRef.current = null;
|
|
10719
|
-
}
|
|
10720
|
-
void processCurrentUtterance();
|
|
10721
|
-
}
|
|
10722
|
-
else {
|
|
10723
|
-
// Start recording and keep listening for utterances separated by ~2s of silence
|
|
10724
|
-
try {
|
|
10725
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
10726
|
-
const mediaRecorder = new MediaRecorder(stream);
|
|
10727
|
-
mediaRecorderRef.current = mediaRecorder;
|
|
10728
|
-
allVoiceChunksRef.current = [];
|
|
10729
|
-
isProcessingVoiceChunkRef.current = false;
|
|
10730
|
-
if (utteranceTimeoutRef.current) {
|
|
10731
|
-
clearTimeout(utteranceTimeoutRef.current);
|
|
10732
|
-
utteranceTimeoutRef.current = null;
|
|
10733
|
-
}
|
|
10734
|
-
mediaRecorder.ondataavailable = (event) => {
|
|
10735
|
-
const chunk = event.data;
|
|
10736
|
-
if (!chunk || chunk.size === 0) {
|
|
10737
|
-
return;
|
|
10738
|
-
}
|
|
10739
|
-
// Accumulate chunks for the current utterance
|
|
10740
|
-
allVoiceChunksRef.current.push(chunk);
|
|
10741
|
-
// Reset the silence timer; if there is no new audio for 2s,
|
|
10742
|
-
// treat it as the end of the current utterance.
|
|
10743
|
-
if (utteranceTimeoutRef.current) {
|
|
10744
|
-
clearTimeout(utteranceTimeoutRef.current);
|
|
10745
|
-
}
|
|
10746
|
-
utteranceTimeoutRef.current = setTimeout(() => {
|
|
10747
|
-
void processCurrentUtterance();
|
|
10748
|
-
}, 2000);
|
|
10749
|
-
};
|
|
10750
|
-
mediaRecorder.onstop = () => {
|
|
10751
|
-
mediaRecorder.stream.getTracks().forEach((track) => track.stop());
|
|
10752
|
-
if (utteranceTimeoutRef.current) {
|
|
10753
|
-
clearTimeout(utteranceTimeoutRef.current);
|
|
10754
|
-
utteranceTimeoutRef.current = null;
|
|
10755
|
-
}
|
|
10756
|
-
// Process any remaining audio when the recorder stops
|
|
10757
|
-
void processCurrentUtterance();
|
|
10758
|
-
};
|
|
10759
|
-
// Use timeslices so ondataavailable is fired continuously
|
|
10760
|
-
mediaRecorder.start(500);
|
|
10761
|
-
setIsVoiceCalling(true);
|
|
10762
|
-
}
|
|
10763
|
-
catch (err) {
|
|
10764
|
-
console.error('Error accessing microphone:', err);
|
|
10765
|
-
}
|
|
10766
|
-
}
|
|
10767
|
-
}, [isVoiceCalling, llmTools, processCurrentUtterance]);
|
|
12188
|
+
name: userParticipantName,
|
|
12189
|
+
fullname: 'You',
|
|
12190
|
+
isMe: true,
|
|
12191
|
+
color: '#1D4ED8',
|
|
12192
|
+
},
|
|
12193
|
+
// Use the profile from llmTools if available, otherwise fallback to default
|
|
12194
|
+
llmTools.profile || {
|
|
12195
|
+
name: llmParticipantName,
|
|
12196
|
+
fullname: llmTools.title || 'AI Assistant',
|
|
12197
|
+
color: '#10b981',
|
|
12198
|
+
},
|
|
12199
|
+
], [llmTools.profile, llmTools.title]);
|
|
12200
|
+
// Keep refs in sync for usage inside long-lived callbacks
|
|
12201
|
+
useEffect(() => {
|
|
12202
|
+
messagesRef.current = messages;
|
|
12203
|
+
}, [messages]);
|
|
12204
|
+
useEffect(() => {
|
|
12205
|
+
participantsRef.current = participants;
|
|
12206
|
+
}, [participants]);
|
|
10768
12207
|
// Handle user messages and LLM responses
|
|
10769
12208
|
const handleMessage = useCallback(async (messageContent, attachments = []) => {
|
|
10770
12209
|
hasUserInteractedRef.current = true;
|
|
@@ -10827,6 +12266,7 @@ function LlmChat(props) {
|
|
|
10827
12266
|
sender: llmParticipantName,
|
|
10828
12267
|
content: chunk.content,
|
|
10829
12268
|
isComplete: false,
|
|
12269
|
+
ongoingToolCalls: chunk.toolCalls,
|
|
10830
12270
|
};
|
|
10831
12271
|
const currentMessages = [...newMessages, assistantMessage];
|
|
10832
12272
|
setMessages(currentMessages);
|
|
@@ -10851,6 +12291,7 @@ function LlmChat(props) {
|
|
|
10851
12291
|
sender: llmParticipantName,
|
|
10852
12292
|
content: result.content,
|
|
10853
12293
|
isComplete: true,
|
|
12294
|
+
completedToolCalls: result.toolCalls,
|
|
10854
12295
|
};
|
|
10855
12296
|
const finalMessages = [...newMessages, assistantMessage];
|
|
10856
12297
|
setMessages(finalMessages);
|
|
@@ -10916,7 +12357,7 @@ function LlmChat(props) {
|
|
|
10916
12357
|
handleMessage(autoExecuteMessage);
|
|
10917
12358
|
}
|
|
10918
12359
|
}, [autoExecuteMessage, handleMessage]);
|
|
10919
|
-
return (jsx(Fragment, { children: jsx(Chat, { ...restProps, messages, onReset, tasksProgress, participants, buttonColor, onMessage: handleMessage, onReset: handleReset,
|
|
12360
|
+
return (jsx(Fragment, { children: jsx(Chat, { ...restProps, messages, onReset, tasksProgress, participants, buttonColor, toolTitles, onMessage: handleMessage, onReset: handleReset, isVoiceCalling: isVoiceCalling }) }));
|
|
10920
12361
|
}
|
|
10921
12362
|
|
|
10922
12363
|
/**
|
|
@@ -10932,8 +12373,8 @@ function LlmChat(props) {
|
|
|
10932
12373
|
* @public exported from `@promptbook/components`
|
|
10933
12374
|
*/
|
|
10934
12375
|
function AgentChat(props) {
|
|
10935
|
-
const { agent, title, persistenceKey, onChange, sendMessage, ...restProps } = props;
|
|
10936
|
-
const brandColor = Color.fromSafe(agent.meta.color || PROMPTBOOK_COLOR).then(saturate(-0.
|
|
12376
|
+
const { agent, title, persistenceKey, onChange, sendMessage, toolTitles, ...restProps } = props;
|
|
12377
|
+
const brandColor = Color.fromSafe(agent.meta.color || PROMPTBOOK_COLOR).then(saturate(-0.2));
|
|
10937
12378
|
return (jsx(Fragment, { children: jsx(LlmChat, { title: title || `Chat with ${agent.meta.fullname || agent.agentName || 'Agent'}`, persistenceKey: persistenceKey || `agent-chat-${agent.agentName}`, userParticipantName: "USER", llmParticipantName: "AGENT" // <- TODO: [🧠] Maybe dynamic agent id
|
|
10938
12379
|
, initialMessages: [
|
|
10939
12380
|
{
|
|
@@ -10962,7 +12403,7 @@ function AgentChat(props) {
|
|
|
10962
12403
|
color: '#115EB6',
|
|
10963
12404
|
isMe: true,
|
|
10964
12405
|
},
|
|
10965
|
-
], buttonColor: brandColor, llmTools: agent, onChange, sendMessage, ...restProps }) }));
|
|
12406
|
+
], buttonColor: brandColor, llmTools: agent, onChange, sendMessage, toolTitles, ...restProps }) }));
|
|
10966
12407
|
}
|
|
10967
12408
|
|
|
10968
12409
|
/**
|
|
@@ -12716,74 +14157,90 @@ function addUsage(...usageItems) {
|
|
|
12716
14157
|
* in real-time through an observable.
|
|
12717
14158
|
*
|
|
12718
14159
|
* @param llmTools - The LLM tools to be intercepted and tracked
|
|
12719
|
-
* @returns
|
|
14160
|
+
* @returns Full proxy of the tools with added usage tracking capabilities
|
|
12720
14161
|
* @public exported from `@promptbook/core`
|
|
12721
14162
|
*/
|
|
12722
14163
|
function countUsage(llmTools) {
|
|
12723
14164
|
let totalUsage = ZERO_USAGE;
|
|
12724
14165
|
const spending = new Subject();
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
//
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
//
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
//
|
|
12747
|
-
|
|
14166
|
+
// Create a Proxy to intercept all property access and ensure full proxying of all properties
|
|
14167
|
+
const proxyTools = new Proxy(llmTools, {
|
|
14168
|
+
get(target, prop, receiver) {
|
|
14169
|
+
// Handle title property
|
|
14170
|
+
if (prop === 'title') {
|
|
14171
|
+
return `${target.title} (+usage)`;
|
|
14172
|
+
// <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
|
|
14173
|
+
// <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
|
|
14174
|
+
}
|
|
14175
|
+
// Handle description property
|
|
14176
|
+
if (prop === 'description') {
|
|
14177
|
+
return `${target.description} (+usage)`;
|
|
14178
|
+
// <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
|
|
14179
|
+
// <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
|
|
14180
|
+
}
|
|
14181
|
+
// Handle spending method (new method added by this wrapper)
|
|
14182
|
+
if (prop === 'spending') {
|
|
14183
|
+
return () => {
|
|
14184
|
+
return spending.asObservable();
|
|
14185
|
+
};
|
|
14186
|
+
}
|
|
14187
|
+
// Handle getTotalUsage method (new method added by this wrapper)
|
|
14188
|
+
if (prop === 'getTotalUsage') {
|
|
14189
|
+
// <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
|
|
14190
|
+
return () => {
|
|
14191
|
+
return totalUsage;
|
|
14192
|
+
};
|
|
14193
|
+
}
|
|
14194
|
+
// Handle callChatModel method with usage counting
|
|
14195
|
+
if (prop === 'callChatModel' && target.callChatModel !== undefined) {
|
|
14196
|
+
return async (prompt) => {
|
|
14197
|
+
// console.info('[🚕] callChatModel through countTotalUsage');
|
|
14198
|
+
const promptResult = await target.callChatModel(prompt);
|
|
14199
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
14200
|
+
spending.next(promptResult.usage);
|
|
14201
|
+
return promptResult;
|
|
14202
|
+
};
|
|
14203
|
+
}
|
|
14204
|
+
// Handle callCompletionModel method with usage counting
|
|
14205
|
+
if (prop === 'callCompletionModel' && target.callCompletionModel !== undefined) {
|
|
14206
|
+
return async (prompt) => {
|
|
14207
|
+
// console.info('[🚕] callCompletionModel through countTotalUsage');
|
|
14208
|
+
const promptResult = await target.callCompletionModel(prompt);
|
|
14209
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
14210
|
+
spending.next(promptResult.usage);
|
|
14211
|
+
return promptResult;
|
|
14212
|
+
};
|
|
14213
|
+
}
|
|
14214
|
+
// Handle callEmbeddingModel method with usage counting
|
|
14215
|
+
if (prop === 'callEmbeddingModel' && target.callEmbeddingModel !== undefined) {
|
|
14216
|
+
return async (prompt) => {
|
|
14217
|
+
// console.info('[🚕] callEmbeddingModel through countTotalUsage');
|
|
14218
|
+
const promptResult = await target.callEmbeddingModel(prompt);
|
|
14219
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
14220
|
+
spending.next(promptResult.usage);
|
|
14221
|
+
return promptResult;
|
|
14222
|
+
};
|
|
14223
|
+
}
|
|
14224
|
+
// Handle callImageGenerationModel method with usage counting
|
|
14225
|
+
if (prop === 'callImageGenerationModel' && target.callImageGenerationModel !== undefined) {
|
|
14226
|
+
return async (prompt) => {
|
|
14227
|
+
// console.info('[🚕] callImageGenerationModel through countTotalUsage');
|
|
14228
|
+
const promptResult = await target.callImageGenerationModel(prompt);
|
|
14229
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
14230
|
+
spending.next(promptResult.usage);
|
|
14231
|
+
return promptResult;
|
|
14232
|
+
};
|
|
14233
|
+
}
|
|
14234
|
+
// <- Note: [🤖]
|
|
14235
|
+
// For all other properties and methods, delegate to the original target
|
|
14236
|
+
const value = Reflect.get(target, prop, receiver);
|
|
14237
|
+
// If it's a function, bind it to the target to preserve context
|
|
14238
|
+
if (typeof value === 'function') {
|
|
14239
|
+
return value.bind(target);
|
|
14240
|
+
}
|
|
14241
|
+
return value;
|
|
12748
14242
|
},
|
|
12749
|
-
};
|
|
12750
|
-
if (llmTools.callChatModel !== undefined) {
|
|
12751
|
-
proxyTools.callChatModel = async (prompt) => {
|
|
12752
|
-
// console.info('[🚕] callChatModel through countTotalUsage');
|
|
12753
|
-
const promptResult = await llmTools.callChatModel(prompt);
|
|
12754
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
12755
|
-
spending.next(promptResult.usage);
|
|
12756
|
-
return promptResult;
|
|
12757
|
-
};
|
|
12758
|
-
}
|
|
12759
|
-
if (llmTools.callCompletionModel !== undefined) {
|
|
12760
|
-
proxyTools.callCompletionModel = async (prompt) => {
|
|
12761
|
-
// console.info('[🚕] callCompletionModel through countTotalUsage');
|
|
12762
|
-
const promptResult = await llmTools.callCompletionModel(prompt);
|
|
12763
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
12764
|
-
spending.next(promptResult.usage);
|
|
12765
|
-
return promptResult;
|
|
12766
|
-
};
|
|
12767
|
-
}
|
|
12768
|
-
if (llmTools.callEmbeddingModel !== undefined) {
|
|
12769
|
-
proxyTools.callEmbeddingModel = async (prompt) => {
|
|
12770
|
-
// console.info('[🚕] callEmbeddingModel through countTotalUsage');
|
|
12771
|
-
const promptResult = await llmTools.callEmbeddingModel(prompt);
|
|
12772
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
12773
|
-
spending.next(promptResult.usage);
|
|
12774
|
-
return promptResult;
|
|
12775
|
-
};
|
|
12776
|
-
}
|
|
12777
|
-
if (llmTools.callImageGenerationModel !== undefined) {
|
|
12778
|
-
proxyTools.callImageGenerationModel = async (prompt) => {
|
|
12779
|
-
// console.info('[🚕] callImageGenerationModel through countTotalUsage');
|
|
12780
|
-
const promptResult = await llmTools.callImageGenerationModel(prompt);
|
|
12781
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
12782
|
-
spending.next(promptResult.usage);
|
|
12783
|
-
return promptResult;
|
|
12784
|
-
};
|
|
12785
|
-
}
|
|
12786
|
-
// <- Note: [🤖]
|
|
14243
|
+
});
|
|
12787
14244
|
return proxyTools;
|
|
12788
14245
|
}
|
|
12789
14246
|
/**
|
|
@@ -15563,6 +17020,97 @@ function createBasicAgentModelRequirements(agentName) {
|
|
|
15563
17020
|
* TODO: [🐤] Deduplicate `AgentModelRequirements` and `ModelRequirements` model requirements
|
|
15564
17021
|
*/
|
|
15565
17022
|
|
|
17023
|
+
/**
|
|
17024
|
+
* Plugin for importing agent books *(`.book` files)*
|
|
17025
|
+
*
|
|
17026
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
17027
|
+
*/
|
|
17028
|
+
const AgentFileImportPlugin = {
|
|
17029
|
+
name: 'agent-file-import-plugin',
|
|
17030
|
+
canImport(mimeType) {
|
|
17031
|
+
// [🧠] Should we have a specific MIME type for agent books?
|
|
17032
|
+
// For now, let's assume it's identified by .book extension or certain MIME types if provided
|
|
17033
|
+
return mimeType === 'text/x-promptbook' || mimeType === 'application/x-promptbook';
|
|
17034
|
+
},
|
|
17035
|
+
import(content) {
|
|
17036
|
+
const parseResult = parseAgentSourceWithCommitments(content);
|
|
17037
|
+
// Bring only the agent corpus (non-commitment lines and relevant commitments)
|
|
17038
|
+
// Stripping the agent name (which is usually the first line)
|
|
17039
|
+
const corpus = parseResult.nonCommitmentLines
|
|
17040
|
+
.filter((line, index) => index > 0 || !parseResult.agentName)
|
|
17041
|
+
.join('\n')
|
|
17042
|
+
.trim();
|
|
17043
|
+
// Also include relevant commitments that make up the "corpus" of the agent
|
|
17044
|
+
// For example PERSONA, RULE, KNOWLEDGE
|
|
17045
|
+
const relevantCommitments = parseResult.commitments
|
|
17046
|
+
.filter((c) => ['PERSONA', 'RULE', 'KNOWLEDGE'].includes(c.type))
|
|
17047
|
+
.map((c) => `${c.type} ${c.content}`)
|
|
17048
|
+
.join('\n\n');
|
|
17049
|
+
return spaceTrim$1((block) => `
|
|
17050
|
+
${block(relevantCommitments)}
|
|
17051
|
+
|
|
17052
|
+
${block(corpus)}
|
|
17053
|
+
`).trim();
|
|
17054
|
+
},
|
|
17055
|
+
};
|
|
17056
|
+
|
|
17057
|
+
/**
|
|
17058
|
+
* Plugin for importing JSON files
|
|
17059
|
+
*
|
|
17060
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
17061
|
+
*/
|
|
17062
|
+
const JsonFileImportPlugin = {
|
|
17063
|
+
name: 'json-file-import-plugin',
|
|
17064
|
+
canImport(mimeType) {
|
|
17065
|
+
return mimeType === 'application/json' || mimeType.endsWith('+json');
|
|
17066
|
+
},
|
|
17067
|
+
import(content) {
|
|
17068
|
+
try {
|
|
17069
|
+
const json = JSON.parse(content);
|
|
17070
|
+
const formattedJson = JSON.stringify(json, null, 4);
|
|
17071
|
+
return `\`\`\`json\n${formattedJson}\n\`\`\``;
|
|
17072
|
+
}
|
|
17073
|
+
catch (error) {
|
|
17074
|
+
// If JSON is invalid, still import it but maybe not as pretty JSON
|
|
17075
|
+
return `\`\`\`json\n${content}\n\`\`\``;
|
|
17076
|
+
}
|
|
17077
|
+
},
|
|
17078
|
+
};
|
|
17079
|
+
|
|
17080
|
+
/**
|
|
17081
|
+
* Plugin for importing generic text files
|
|
17082
|
+
*
|
|
17083
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
17084
|
+
*/
|
|
17085
|
+
const TextFileImportPlugin = {
|
|
17086
|
+
name: 'text-file-import-plugin',
|
|
17087
|
+
canImport(mimeType) {
|
|
17088
|
+
return (mimeType === 'text/plain' ||
|
|
17089
|
+
mimeType === 'text/markdown' ||
|
|
17090
|
+
mimeType === 'text/x-typescript' ||
|
|
17091
|
+
mimeType === 'text/javascript' ||
|
|
17092
|
+
mimeType === 'text/css' ||
|
|
17093
|
+
mimeType === 'text/html' ||
|
|
17094
|
+
mimeType.startsWith('text/'));
|
|
17095
|
+
},
|
|
17096
|
+
import(content, mimeType) {
|
|
17097
|
+
const extension = mimeTypeToExtension(mimeType);
|
|
17098
|
+
const codeBlockType = extension || 'txt';
|
|
17099
|
+
return `\`\`\`${codeBlockType}\n${content}\n\`\`\``;
|
|
17100
|
+
},
|
|
17101
|
+
};
|
|
17102
|
+
|
|
17103
|
+
/**
|
|
17104
|
+
* All available file import plugins
|
|
17105
|
+
*
|
|
17106
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
17107
|
+
*/
|
|
17108
|
+
const $fileImportPlugins = [
|
|
17109
|
+
AgentFileImportPlugin,
|
|
17110
|
+
JsonFileImportPlugin,
|
|
17111
|
+
TextFileImportPlugin,
|
|
17112
|
+
];
|
|
17113
|
+
|
|
15566
17114
|
/**
|
|
15567
17115
|
* Removes comment lines (lines starting with #) from a system message
|
|
15568
17116
|
* This is used to clean up the final system message before sending it to the AI model
|
|
@@ -15594,6 +17142,7 @@ function removeCommentsFromSystemMessage(systemMessage) {
|
|
|
15594
17142
|
* @public exported from `@promptbook/core`
|
|
15595
17143
|
*/
|
|
15596
17144
|
async function createAgentModelRequirementsWithCommitments(agentSource, modelName) {
|
|
17145
|
+
var _a;
|
|
15597
17146
|
// Parse the agent source to extract commitments
|
|
15598
17147
|
const parseResult = parseAgentSourceWithCommitments(agentSource);
|
|
15599
17148
|
// Apply DELETE filtering: remove prior commitments tagged by parameters targeted by DELETE/CANCEL/DISCARD/REMOVE
|
|
@@ -15660,6 +17209,64 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
15660
17209
|
}
|
|
15661
17210
|
}
|
|
15662
17211
|
}
|
|
17212
|
+
// Handle IMPORT commitments for generic files
|
|
17213
|
+
// Note: This logic could be moved to ImportCommitmentDefinition, but it needs to be asynchronous
|
|
17214
|
+
if (requirements.importedFileUrls && requirements.importedFileUrls.length > 0) {
|
|
17215
|
+
for (const fileUrl of requirements.importedFileUrls) {
|
|
17216
|
+
try {
|
|
17217
|
+
// 1. Mocked security check
|
|
17218
|
+
await mockedSecurityCheck(fileUrl);
|
|
17219
|
+
// 2. Fetch file content
|
|
17220
|
+
let content;
|
|
17221
|
+
let mimeType = null;
|
|
17222
|
+
if (isValidUrl(fileUrl)) {
|
|
17223
|
+
const response = await promptbookFetch(fileUrl);
|
|
17224
|
+
if (!response.ok) {
|
|
17225
|
+
throw new Error(`Failed to fetch ${fileUrl}: ${response.statusText}`);
|
|
17226
|
+
}
|
|
17227
|
+
content = await response.text();
|
|
17228
|
+
mimeType = response.headers.get('Content-Type');
|
|
17229
|
+
/*
|
|
17230
|
+
TODO: !!!! Commented out this case because we need to work in Browser-compatible mode in many packages, use passed `fs` instead
|
|
17231
|
+
} else if (isValidFilePath(fileUrl)) {
|
|
17232
|
+
// [x🟢x] This code is expected to run in Node environment if local files are used
|
|
17233
|
+
const fs = await import('fs/promises');
|
|
17234
|
+
content = await fs.readFile(fileUrl, 'utf-8');
|
|
17235
|
+
const extension = getFileExtension(fileUrl);
|
|
17236
|
+
mimeType = extensionToMimeType(extension as string);
|
|
17237
|
+
*/
|
|
17238
|
+
}
|
|
17239
|
+
else {
|
|
17240
|
+
throw new Error(`Invalid file URL or path: ${fileUrl}`);
|
|
17241
|
+
}
|
|
17242
|
+
if (!mimeType) {
|
|
17243
|
+
mimeType = 'text/plain';
|
|
17244
|
+
}
|
|
17245
|
+
// Remove charset from mime type
|
|
17246
|
+
mimeType = mimeType.split(';')[0].trim();
|
|
17247
|
+
// 3. Prevent importing binary files (mocked check)
|
|
17248
|
+
if (isBinaryMimeType(mimeType)) {
|
|
17249
|
+
throw new Error(`Importing binary files is not allowed: ${mimeType}`);
|
|
17250
|
+
}
|
|
17251
|
+
// 4. Find appropriate plugin
|
|
17252
|
+
const plugin = $fileImportPlugins.find((p) => p.canImport(mimeType));
|
|
17253
|
+
if (!plugin) {
|
|
17254
|
+
throw new Error(`No import plugin found for MIME type: ${mimeType}`);
|
|
17255
|
+
}
|
|
17256
|
+
// 5. Process content
|
|
17257
|
+
const importedContent = await plugin.import(content, mimeType);
|
|
17258
|
+
// 6. Append to system message
|
|
17259
|
+
requirements = {
|
|
17260
|
+
...requirements,
|
|
17261
|
+
systemMessage: requirements.systemMessage + '\n\n' + importedContent,
|
|
17262
|
+
};
|
|
17263
|
+
}
|
|
17264
|
+
catch (error) {
|
|
17265
|
+
console.warn(`Failed to import file ${fileUrl}:`, error);
|
|
17266
|
+
// Continue with other imports even if one fails
|
|
17267
|
+
}
|
|
17268
|
+
}
|
|
17269
|
+
}
|
|
15663
17270
|
// Handle MCP servers (extract from original agent source)
|
|
15664
17271
|
const mcpServers = extractMcpServers(agentSource);
|
|
15665
17272
|
if (mcpServers.length > 0) {
|
|
@@ -15669,9 +17276,11 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
15669
17276
|
};
|
|
15670
17277
|
}
|
|
15671
17278
|
// Add non-commitment lines to system message if they exist
|
|
17279
|
+
// Note: Filtering out horizontal lines (---) as requested
|
|
15672
17280
|
const nonCommitmentContent = parseResult.nonCommitmentLines
|
|
15673
17281
|
.filter((line, index) => index > 0 || !parseResult.agentName) // Skip first line if it's the agent name
|
|
15674
17282
|
.filter((line) => line.trim()) // Remove empty lines
|
|
17283
|
+
.filter((line) => !/^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/.test(line)) // Remove horizontal lines
|
|
15675
17284
|
.join('\n')
|
|
15676
17285
|
.trim();
|
|
15677
17286
|
if (nonCommitmentContent) {
|
|
@@ -15680,6 +17289,26 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
15680
17289
|
systemMessage: requirements.systemMessage + '\n\n' + nonCommitmentContent,
|
|
15681
17290
|
};
|
|
15682
17291
|
}
|
|
17292
|
+
// Add example interactions to the system message
|
|
17293
|
+
const examples = [];
|
|
17294
|
+
// 1. Initial message as an example agent response
|
|
17295
|
+
const initialMessage = (_a = parseResult.commitments.find((c) => c.type === 'INITIAL MESSAGE')) === null || _a === void 0 ? void 0 : _a.content;
|
|
17296
|
+
if (initialMessage) {
|
|
17297
|
+
examples.push(`Agent: ${initialMessage}`);
|
|
17298
|
+
}
|
|
17299
|
+
// 2. User and Agent message pairs
|
|
17300
|
+
if (requirements.samples && requirements.samples.length > 0) {
|
|
17301
|
+
for (const sample of requirements.samples) {
|
|
17302
|
+
examples.push(`User: ${sample.question}\nAgent: ${sample.answer}`);
|
|
17303
|
+
}
|
|
17304
|
+
}
|
|
17305
|
+
if (examples.length > 0) {
|
|
17306
|
+
const exampleInteractionsContent = `Example interaction:\n\n${examples.join('\n\n')}`;
|
|
17307
|
+
requirements = {
|
|
17308
|
+
...requirements,
|
|
17309
|
+
systemMessage: requirements.systemMessage + '\n\n' + exampleInteractionsContent,
|
|
17310
|
+
};
|
|
17311
|
+
}
|
|
15683
17312
|
// Remove comment lines (lines starting with #) from the final system message
|
|
15684
17313
|
// while preserving the original content with comments in metadata
|
|
15685
17314
|
const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
|
|
@@ -15688,6 +17317,36 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
15688
17317
|
systemMessage: cleanedSystemMessage,
|
|
15689
17318
|
};
|
|
15690
17319
|
}
|
|
17320
|
+
/**
|
|
17321
|
+
* Mocked security check for imported files
|
|
17322
|
+
*
|
|
17323
|
+
* @param urlOrPath - The URL or local path of the file to check
|
|
17324
|
+
* @returns A promise that resolves if the file is safe
|
|
17325
|
+
*/
|
|
17326
|
+
async function mockedSecurityCheck(urlOrPath) {
|
|
17327
|
+
// TODO: Implement proper security checks
|
|
17328
|
+
await new Promise((resolve) => setTimeout(resolve, 10)); // Mock async delay
|
|
17329
|
+
if (urlOrPath.includes('malicious')) {
|
|
17330
|
+
throw new Error(`Security check failed for: ${urlOrPath}`);
|
|
17331
|
+
}
|
|
17332
|
+
}
|
|
17333
|
+
/**
|
|
17334
|
+
* Checks if the given MIME type belongs to a binary file
|
|
17335
|
+
*
|
|
17336
|
+
* @param mimeType - The MIME type to check
|
|
17337
|
+
* @returns True if it's a binary MIME type
|
|
17338
|
+
*/
|
|
17339
|
+
function isBinaryMimeType(mimeType) {
|
|
17340
|
+
const binaryPrefixes = [
|
|
17341
|
+
'image/',
|
|
17342
|
+
'video/',
|
|
17343
|
+
'audio/',
|
|
17344
|
+
'application/octet-stream',
|
|
17345
|
+
'application/pdf',
|
|
17346
|
+
'application/zip',
|
|
17347
|
+
];
|
|
17348
|
+
return binaryPrefixes.some((prefix) => mimeType.startsWith(prefix));
|
|
17349
|
+
}
|
|
15691
17350
|
|
|
15692
17351
|
/**
|
|
15693
17352
|
* Creates model requirements for an agent based on its source
|
|
@@ -16635,20 +18294,29 @@ class OpenAiCompatibleExecutionTools {
|
|
|
16635
18294
|
});
|
|
16636
18295
|
return availableModels;
|
|
16637
18296
|
}
|
|
18297
|
+
/**
|
|
18298
|
+
* Calls OpenAI compatible API to use a chat model.
|
|
18299
|
+
*/
|
|
16638
18300
|
/**
|
|
16639
18301
|
* Calls OpenAI compatible API to use a chat model.
|
|
16640
18302
|
*/
|
|
16641
18303
|
async callChatModel(prompt) {
|
|
18304
|
+
return this.callChatModelStream(prompt, () => { });
|
|
18305
|
+
}
|
|
18306
|
+
/**
|
|
18307
|
+
* Calls OpenAI compatible API to use a chat model with streaming.
|
|
18308
|
+
*/
|
|
18309
|
+
async callChatModelStream(prompt, onProgress) {
|
|
16642
18310
|
// Deep clone prompt and modelRequirements to avoid mutation across calls
|
|
16643
18311
|
const clonedPrompt = JSON.parse(JSON.stringify(prompt));
|
|
16644
18312
|
// Use local Set for retried parameters to ensure independence and thread safety
|
|
16645
18313
|
const retriedUnsupportedParameters = new Set();
|
|
16646
|
-
return this.callChatModelWithRetry(clonedPrompt, clonedPrompt.modelRequirements, [], retriedUnsupportedParameters);
|
|
18314
|
+
return this.callChatModelWithRetry(clonedPrompt, clonedPrompt.modelRequirements, [], retriedUnsupportedParameters, onProgress);
|
|
16647
18315
|
}
|
|
16648
18316
|
/**
|
|
16649
18317
|
* Internal method that handles parameter retry for chat model calls
|
|
16650
18318
|
*/
|
|
16651
|
-
async callChatModelWithRetry(prompt, currentModelRequirements, attemptStack = [], retriedUnsupportedParameters = new Set()) {
|
|
18319
|
+
async callChatModelWithRetry(prompt, currentModelRequirements, attemptStack = [], retriedUnsupportedParameters = new Set(), onProgress) {
|
|
16652
18320
|
var _a;
|
|
16653
18321
|
if (this.options.isVerbose) {
|
|
16654
18322
|
console.info(`💬 ${this.title} callChatModel call`, { prompt, currentModelRequirements });
|
|
@@ -16754,6 +18422,23 @@ class OpenAiCompatibleExecutionTools {
|
|
|
16754
18422
|
const usage = this.computeUsage(content || '', responseMessage.content || '', rawResponse);
|
|
16755
18423
|
totalUsage = addUsage(totalUsage, usage);
|
|
16756
18424
|
if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
|
|
18425
|
+
if (onProgress) {
|
|
18426
|
+
onProgress({
|
|
18427
|
+
content: responseMessage.content || '',
|
|
18428
|
+
modelName: rawResponse.model || modelName,
|
|
18429
|
+
timing: { start, complete: $getCurrentDate() },
|
|
18430
|
+
usage: totalUsage,
|
|
18431
|
+
toolCalls: responseMessage.tool_calls.map((toolCall) => ({
|
|
18432
|
+
name: toolCall.function.name,
|
|
18433
|
+
arguments: toolCall.function.arguments,
|
|
18434
|
+
result: '',
|
|
18435
|
+
rawToolCall: toolCall,
|
|
18436
|
+
})),
|
|
18437
|
+
rawPromptContent,
|
|
18438
|
+
rawRequest,
|
|
18439
|
+
rawResponse,
|
|
18440
|
+
});
|
|
18441
|
+
}
|
|
16757
18442
|
await forEachAsync(responseMessage.tool_calls, {}, async (toolCall) => {
|
|
16758
18443
|
const functionName = toolCall.function.name;
|
|
16759
18444
|
const functionArgs = toolCall.function.arguments;
|
|
@@ -16775,7 +18460,7 @@ class OpenAiCompatibleExecutionTools {
|
|
|
16775
18460
|
const args = ${functionArgs};
|
|
16776
18461
|
return await ${functionName}(args);
|
|
16777
18462
|
`,
|
|
16778
|
-
parameters:
|
|
18463
|
+
parameters: prompt.parameters,
|
|
16779
18464
|
});
|
|
16780
18465
|
}
|
|
16781
18466
|
catch (error) {
|
|
@@ -16881,7 +18566,7 @@ class OpenAiCompatibleExecutionTools {
|
|
|
16881
18566
|
});
|
|
16882
18567
|
// Remove the unsupported parameter and retry
|
|
16883
18568
|
const modifiedModelRequirements = removeUnsupportedModelRequirement(currentModelRequirements, unsupportedParameter);
|
|
16884
|
-
return this.callChatModelWithRetry(prompt, modifiedModelRequirements, attemptStack, retriedUnsupportedParameters);
|
|
18569
|
+
return this.callChatModelWithRetry(prompt, modifiedModelRequirements, attemptStack, retriedUnsupportedParameters, onProgress);
|
|
16885
18570
|
}
|
|
16886
18571
|
}
|
|
16887
18572
|
throw new PipelineExecutionError(`Tool calling loop did not return a result from ${this.title}`);
|
|
@@ -17514,7 +19199,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17514
19199
|
* Calls OpenAI API to use a chat model with streaming.
|
|
17515
19200
|
*/
|
|
17516
19201
|
async callChatModelStream(prompt, onProgress) {
|
|
17517
|
-
var _a, _b, _c;
|
|
19202
|
+
var _a, _b, _c, _d;
|
|
17518
19203
|
if (this.options.isVerbose) {
|
|
17519
19204
|
console.info('💬 OpenAI callChatModel call', { prompt });
|
|
17520
19205
|
}
|
|
@@ -17569,6 +19254,157 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17569
19254
|
}
|
|
17570
19255
|
// Always add the current user message
|
|
17571
19256
|
threadMessages.push({ role: 'user', content: rawPromptContent });
|
|
19257
|
+
// Check if tools are being used - if so, use non-streaming mode
|
|
19258
|
+
const hasTools = modelRequirements.tools !== undefined && modelRequirements.tools.length > 0;
|
|
19259
|
+
const start = $getCurrentDate();
|
|
19260
|
+
let complete;
|
|
19261
|
+
// [🐱🚀] When tools are present, we need to use the non-streaming Runs API
|
|
19262
|
+
// because streaming doesn't support tool execution flow properly
|
|
19263
|
+
if (hasTools) {
|
|
19264
|
+
onProgress({
|
|
19265
|
+
content: '',
|
|
19266
|
+
modelName: 'assistant',
|
|
19267
|
+
timing: { start, complete: $getCurrentDate() },
|
|
19268
|
+
usage: UNCERTAIN_USAGE,
|
|
19269
|
+
rawPromptContent,
|
|
19270
|
+
rawRequest: null,
|
|
19271
|
+
rawResponse: null,
|
|
19272
|
+
});
|
|
19273
|
+
const rawRequest = {
|
|
19274
|
+
assistant_id: this.assistantId,
|
|
19275
|
+
thread: {
|
|
19276
|
+
messages: threadMessages,
|
|
19277
|
+
},
|
|
19278
|
+
tools: mapToolsToOpenAi(modelRequirements.tools),
|
|
19279
|
+
};
|
|
19280
|
+
if (this.options.isVerbose) {
|
|
19281
|
+
console.info(colors.bgWhite('rawRequest (non-streaming with tools)'), JSON.stringify(rawRequest, null, 4));
|
|
19282
|
+
}
|
|
19283
|
+
// Create thread and run
|
|
19284
|
+
const threadAndRun = await client.beta.threads.createAndRun(rawRequest);
|
|
19285
|
+
let run = threadAndRun;
|
|
19286
|
+
// Poll until run completes or requires action
|
|
19287
|
+
while (run.status === 'queued' || run.status === 'in_progress' || run.status === 'requires_action') {
|
|
19288
|
+
if (run.status === 'requires_action' && ((_a = run.required_action) === null || _a === void 0 ? void 0 : _a.type) === 'submit_tool_outputs') {
|
|
19289
|
+
// Execute tools
|
|
19290
|
+
const toolCalls = run.required_action.submit_tool_outputs.tool_calls;
|
|
19291
|
+
const toolOutputs = [];
|
|
19292
|
+
for (const toolCall of toolCalls) {
|
|
19293
|
+
if (toolCall.type === 'function') {
|
|
19294
|
+
const functionName = toolCall.function.name;
|
|
19295
|
+
const functionArgs = JSON.parse(toolCall.function.arguments);
|
|
19296
|
+
onProgress({
|
|
19297
|
+
content: '',
|
|
19298
|
+
modelName: 'assistant',
|
|
19299
|
+
timing: { start, complete: $getCurrentDate() },
|
|
19300
|
+
usage: UNCERTAIN_USAGE,
|
|
19301
|
+
rawPromptContent,
|
|
19302
|
+
rawRequest: null,
|
|
19303
|
+
rawResponse: null,
|
|
19304
|
+
toolCalls: [
|
|
19305
|
+
{
|
|
19306
|
+
name: functionName,
|
|
19307
|
+
arguments: toolCall.function.arguments,
|
|
19308
|
+
result: '',
|
|
19309
|
+
rawToolCall: toolCall,
|
|
19310
|
+
},
|
|
19311
|
+
],
|
|
19312
|
+
});
|
|
19313
|
+
if (this.options.isVerbose) {
|
|
19314
|
+
console.info(`🔧 Executing tool: ${functionName}`, functionArgs);
|
|
19315
|
+
}
|
|
19316
|
+
// Get execution tools for script execution
|
|
19317
|
+
const executionTools = this.options
|
|
19318
|
+
.executionTools;
|
|
19319
|
+
if (!executionTools || !executionTools.script) {
|
|
19320
|
+
throw new PipelineExecutionError(`Model requested tool '${functionName}' but no executionTools.script were provided in OpenAiAssistantExecutionTools options`);
|
|
19321
|
+
}
|
|
19322
|
+
// TODO: [DRY] Use some common tool caller (similar to OpenAiCompatibleExecutionTools)
|
|
19323
|
+
const scriptTools = Array.isArray(executionTools.script)
|
|
19324
|
+
? executionTools.script
|
|
19325
|
+
: [executionTools.script];
|
|
19326
|
+
let functionResponse;
|
|
19327
|
+
try {
|
|
19328
|
+
const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
|
|
19329
|
+
functionResponse = await scriptTool.execute({
|
|
19330
|
+
scriptLanguage: 'javascript',
|
|
19331
|
+
script: `
|
|
19332
|
+
const args = ${JSON.stringify(functionArgs)};
|
|
19333
|
+
return await ${functionName}(args);
|
|
19334
|
+
`,
|
|
19335
|
+
parameters: prompt.parameters,
|
|
19336
|
+
});
|
|
19337
|
+
if (this.options.isVerbose) {
|
|
19338
|
+
console.info(`✅ Tool ${functionName} executed:`, functionResponse);
|
|
19339
|
+
}
|
|
19340
|
+
}
|
|
19341
|
+
catch (error) {
|
|
19342
|
+
assertsError(error);
|
|
19343
|
+
functionResponse = spaceTrim$2((block) => `
|
|
19344
|
+
|
|
19345
|
+
The invoked tool \`${functionName}\` failed with error:
|
|
19346
|
+
|
|
19347
|
+
\`\`\`json
|
|
19348
|
+
${block(JSON.stringify(serializeError(error), null, 4))}
|
|
19349
|
+
\`\`\`
|
|
19350
|
+
|
|
19351
|
+
`);
|
|
19352
|
+
console.error(colors.bgRed(`❌ Error executing tool ${functionName}:`));
|
|
19353
|
+
console.error(error);
|
|
19354
|
+
}
|
|
19355
|
+
toolOutputs.push({
|
|
19356
|
+
tool_call_id: toolCall.id,
|
|
19357
|
+
output: functionResponse,
|
|
19358
|
+
});
|
|
19359
|
+
}
|
|
19360
|
+
}
|
|
19361
|
+
// Submit tool outputs
|
|
19362
|
+
run = await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {
|
|
19363
|
+
tool_outputs: toolOutputs,
|
|
19364
|
+
});
|
|
19365
|
+
}
|
|
19366
|
+
else {
|
|
19367
|
+
// Wait a bit before polling again
|
|
19368
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
19369
|
+
run = await client.beta.threads.runs.retrieve(run.thread_id, run.id);
|
|
19370
|
+
}
|
|
19371
|
+
}
|
|
19372
|
+
if (run.status !== 'completed') {
|
|
19373
|
+
throw new PipelineExecutionError(`Assistant run failed with status: ${run.status}`);
|
|
19374
|
+
}
|
|
19375
|
+
// Get messages from the thread
|
|
19376
|
+
const messages = await client.beta.threads.messages.list(run.thread_id);
|
|
19377
|
+
const assistantMessages = messages.data.filter((msg) => msg.role === 'assistant');
|
|
19378
|
+
if (assistantMessages.length === 0) {
|
|
19379
|
+
throw new PipelineExecutionError('No assistant messages found after run completion');
|
|
19380
|
+
}
|
|
19381
|
+
const lastMessage = assistantMessages[0];
|
|
19382
|
+
const textContent = lastMessage.content.find((c) => c.type === 'text');
|
|
19383
|
+
if (!textContent || textContent.type !== 'text') {
|
|
19384
|
+
throw new PipelineExecutionError('No text content in assistant response');
|
|
19385
|
+
}
|
|
19386
|
+
complete = $getCurrentDate();
|
|
19387
|
+
const resultContent = textContent.text.value;
|
|
19388
|
+
const usage = UNCERTAIN_USAGE;
|
|
19389
|
+
// Progress callback with final result
|
|
19390
|
+
const finalChunk = {
|
|
19391
|
+
content: resultContent,
|
|
19392
|
+
modelName: 'assistant',
|
|
19393
|
+
timing: { start, complete },
|
|
19394
|
+
usage,
|
|
19395
|
+
rawPromptContent,
|
|
19396
|
+
rawRequest,
|
|
19397
|
+
rawResponse: { run, messages: messages.data },
|
|
19398
|
+
};
|
|
19399
|
+
onProgress(finalChunk);
|
|
19400
|
+
return exportJson({
|
|
19401
|
+
name: 'promptResult',
|
|
19402
|
+
message: `Result of \`OpenAiAssistantExecutionTools.callChatModelStream\` (with tools)`,
|
|
19403
|
+
order: [],
|
|
19404
|
+
value: finalChunk,
|
|
19405
|
+
});
|
|
19406
|
+
}
|
|
19407
|
+
// Streaming mode (without tools)
|
|
17572
19408
|
const rawRequest = {
|
|
17573
19409
|
// TODO: [👨👨👧👧] ...modelSettings,
|
|
17574
19410
|
// TODO: [👨👨👧👧][🧠] What about system message for assistants, does it make sense - combination of OpenAI assistants with Promptbook Personas
|
|
@@ -17579,10 +19415,8 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17579
19415
|
tools: modelRequirements.tools === undefined ? undefined : mapToolsToOpenAi(modelRequirements.tools),
|
|
17580
19416
|
// <- TODO: Add user identification here> user: this.options.user,
|
|
17581
19417
|
};
|
|
17582
|
-
const start = $getCurrentDate();
|
|
17583
|
-
let complete;
|
|
17584
19418
|
if (this.options.isVerbose) {
|
|
17585
|
-
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
19419
|
+
console.info(colors.bgWhite('rawRequest (streaming)'), JSON.stringify(rawRequest, null, 4));
|
|
17586
19420
|
}
|
|
17587
19421
|
const stream = await client.beta.threads.createAndRunStream(rawRequest);
|
|
17588
19422
|
stream.on('connect', () => {
|
|
@@ -17618,6 +19452,15 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17618
19452
|
console.info('messageDone', message);
|
|
17619
19453
|
}
|
|
17620
19454
|
});
|
|
19455
|
+
// TODO: [🐱🚀] Handle tool calls in assistants
|
|
19456
|
+
// Note: OpenAI Assistant streaming with tool calls requires special handling.
|
|
19457
|
+
// The stream will pause when a tool call is needed, and we need to:
|
|
19458
|
+
// 1. Wait for the run to reach 'requires_action' status
|
|
19459
|
+
// 2. Execute the tool calls
|
|
19460
|
+
// 3. Submit tool outputs via a separate API call (not on the stream)
|
|
19461
|
+
// 4. Continue the run
|
|
19462
|
+
// This requires switching to non-streaming mode or using the Runs API directly.
|
|
19463
|
+
// For now, tools with assistants should use the non-streaming chat completions API instead.
|
|
17621
19464
|
const rawResponse = await stream.finalMessages();
|
|
17622
19465
|
if (this.options.isVerbose) {
|
|
17623
19466
|
console.info(colors.bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
@@ -17628,10 +19471,10 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17628
19471
|
if (rawResponse[0].content.length !== 1) {
|
|
17629
19472
|
throw new PipelineExecutionError(`There is NOT 1 BUT ${rawResponse[0].content.length} finalMessages content from OpenAI`);
|
|
17630
19473
|
}
|
|
17631
|
-
if (((
|
|
17632
|
-
throw new PipelineExecutionError(`There is NOT 'text' BUT ${(
|
|
19474
|
+
if (((_b = rawResponse[0].content[0]) === null || _b === void 0 ? void 0 : _b.type) !== 'text') {
|
|
19475
|
+
throw new PipelineExecutionError(`There is NOT 'text' BUT ${(_c = rawResponse[0].content[0]) === null || _c === void 0 ? void 0 : _c.type} finalMessages content type from OpenAI`);
|
|
17633
19476
|
}
|
|
17634
|
-
const resultContent = (
|
|
19477
|
+
const resultContent = (_d = rawResponse[0].content[0]) === null || _d === void 0 ? void 0 : _d.text.value;
|
|
17635
19478
|
// <- TODO: [🧠] There are also annotations, maybe use them
|
|
17636
19479
|
// eslint-disable-next-line prefer-const
|
|
17637
19480
|
complete = $getCurrentDate();
|
|
@@ -17699,7 +19542,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17699
19542
|
throw new NotAllowed(`Creating new assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
|
|
17700
19543
|
}
|
|
17701
19544
|
// await this.playground();
|
|
17702
|
-
const { name, instructions, knowledgeSources } = options;
|
|
19545
|
+
const { name, instructions, knowledgeSources, tools } = options;
|
|
17703
19546
|
const client = await this.getClient();
|
|
17704
19547
|
let vectorStoreId;
|
|
17705
19548
|
// If knowledge sources are provided, create a vector store with them
|
|
@@ -17770,7 +19613,11 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17770
19613
|
description: 'Assistant created via Promptbook',
|
|
17771
19614
|
model: 'gpt-4o',
|
|
17772
19615
|
instructions,
|
|
17773
|
-
tools: [
|
|
19616
|
+
tools: [
|
|
19617
|
+
/* TODO: [🧠] Maybe add { type: 'code_interpreter' }, */
|
|
19618
|
+
{ type: 'file_search' },
|
|
19619
|
+
...(tools === undefined ? [] : mapToolsToOpenAi(tools)),
|
|
19620
|
+
],
|
|
17774
19621
|
};
|
|
17775
19622
|
// Attach vector store if created
|
|
17776
19623
|
if (vectorStoreId) {
|
|
@@ -17795,7 +19642,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17795
19642
|
if (!this.isCreatingNewAssistantsAllowed) {
|
|
17796
19643
|
throw new NotAllowed(`Updating assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
|
|
17797
19644
|
}
|
|
17798
|
-
const { assistantId, name, instructions, knowledgeSources } = options;
|
|
19645
|
+
const { assistantId, name, instructions, knowledgeSources, tools } = options;
|
|
17799
19646
|
const client = await this.getClient();
|
|
17800
19647
|
let vectorStoreId;
|
|
17801
19648
|
// If knowledge sources are provided, create a vector store with them
|
|
@@ -17864,7 +19711,11 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17864
19711
|
const assistantUpdate = {
|
|
17865
19712
|
name,
|
|
17866
19713
|
instructions,
|
|
17867
|
-
tools: [
|
|
19714
|
+
tools: [
|
|
19715
|
+
/* TODO: [🧠] Maybe add { type: 'code_interpreter' }, */
|
|
19716
|
+
{ type: 'file_search' },
|
|
19717
|
+
...(tools === undefined ? [] : mapToolsToOpenAi(tools)),
|
|
19718
|
+
],
|
|
17868
19719
|
};
|
|
17869
19720
|
if (vectorStoreId) {
|
|
17870
19721
|
assistantUpdate.tool_resources = {
|
|
@@ -17905,6 +19756,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
17905
19756
|
*/
|
|
17906
19757
|
const DISCRIMINANT = 'OPEN_AI_ASSISTANT_V1';
|
|
17907
19758
|
/**
|
|
19759
|
+
* TODO: [🙎] In `OpenAiAssistantExecutionTools` Allow to create abstract assistants with `isCreatingNewAssistantsAllowed`
|
|
17908
19760
|
* TODO: [🧠][🧙♂️] Maybe there can be some wizard for those who want to use just OpenAI
|
|
17909
19761
|
* TODO: Maybe make custom OpenAiError
|
|
17910
19762
|
* TODO: [🧠][🈁] Maybe use `isDeterministic` from options
|
|
@@ -17963,8 +19815,10 @@ class AgentLlmExecutionTools {
|
|
|
17963
19815
|
}
|
|
17964
19816
|
/**
|
|
17965
19817
|
* Get cached or create agent model requirements
|
|
19818
|
+
*
|
|
19819
|
+
* Note: [🐤] This is names `getModelRequirements` *(not `getAgentModelRequirements`)* because in future these two will be united
|
|
17966
19820
|
*/
|
|
17967
|
-
async
|
|
19821
|
+
async getModelRequirements() {
|
|
17968
19822
|
if (this._cachedModelRequirements === null) {
|
|
17969
19823
|
// Get available models from underlying LLM tools for best model selection
|
|
17970
19824
|
const availableModels = await this.options.llmTools.listModels();
|
|
@@ -18034,9 +19888,25 @@ class AgentLlmExecutionTools {
|
|
|
18034
19888
|
if (prompt.modelRequirements.modelVariant !== 'CHAT') {
|
|
18035
19889
|
throw new Error('AgentLlmExecutionTools only supports chat prompts');
|
|
18036
19890
|
}
|
|
18037
|
-
const modelRequirements = await this.
|
|
19891
|
+
const modelRequirements = await this.getModelRequirements();
|
|
18038
19892
|
const chatPrompt = prompt;
|
|
18039
19893
|
let underlyingLlmResult;
|
|
19894
|
+
// Create modified chat prompt with agent system message
|
|
19895
|
+
const promptWithAgentModelRequirements = {
|
|
19896
|
+
...chatPrompt,
|
|
19897
|
+
modelRequirements: {
|
|
19898
|
+
...chatPrompt.modelRequirements,
|
|
19899
|
+
...modelRequirements,
|
|
19900
|
+
// Spread tools to convert readonly array to mutable
|
|
19901
|
+
tools: modelRequirements.tools ? [...modelRequirements.tools] : chatPrompt.modelRequirements.tools,
|
|
19902
|
+
// Prepend agent system message to existing system message
|
|
19903
|
+
systemMessage: modelRequirements.systemMessage +
|
|
19904
|
+
(chatPrompt.modelRequirements.systemMessage
|
|
19905
|
+
? `\n\n${chatPrompt.modelRequirements.systemMessage}`
|
|
19906
|
+
: ''),
|
|
19907
|
+
},
|
|
19908
|
+
};
|
|
19909
|
+
console.log('!!!! promptWithAgentModelRequirements:', promptWithAgentModelRequirements);
|
|
18040
19910
|
if (OpenAiAssistantExecutionTools.isOpenAiAssistantExecutionTools(this.options.llmTools)) {
|
|
18041
19911
|
const requirementsHash = SHA256(JSON.stringify(modelRequirements)).toString();
|
|
18042
19912
|
const cached = AgentLlmExecutionTools.assistantCache.get(this.title);
|
|
@@ -18057,6 +19927,7 @@ class AgentLlmExecutionTools {
|
|
|
18057
19927
|
name: this.title,
|
|
18058
19928
|
instructions: modelRequirements.systemMessage,
|
|
18059
19929
|
knowledgeSources: modelRequirements.knowledgeSources,
|
|
19930
|
+
tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
|
|
18060
19931
|
});
|
|
18061
19932
|
AgentLlmExecutionTools.assistantCache.set(this.title, {
|
|
18062
19933
|
assistantId: assistant.assistantId,
|
|
@@ -18073,6 +19944,7 @@ class AgentLlmExecutionTools {
|
|
|
18073
19944
|
name: this.title,
|
|
18074
19945
|
instructions: modelRequirements.systemMessage,
|
|
18075
19946
|
knowledgeSources: modelRequirements.knowledgeSources,
|
|
19947
|
+
tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
|
|
18076
19948
|
/*
|
|
18077
19949
|
!!!
|
|
18078
19950
|
metadata: {
|
|
@@ -18085,32 +19957,28 @@ class AgentLlmExecutionTools {
|
|
|
18085
19957
|
requirementsHash,
|
|
18086
19958
|
});
|
|
18087
19959
|
}
|
|
18088
|
-
|
|
19960
|
+
// Create modified chat prompt with agent system message specific to OpenAI Assistant
|
|
19961
|
+
const promptWithAgentModelRequirementsForOpenAiAssistantExecutionTools = {
|
|
19962
|
+
...promptWithAgentModelRequirements,
|
|
19963
|
+
modelRequirements: {
|
|
19964
|
+
...promptWithAgentModelRequirements.modelRequirements,
|
|
19965
|
+
modelName: undefined,
|
|
19966
|
+
systemMessage: undefined,
|
|
19967
|
+
temperature: undefined, // <- Note: Let the Assistant use its default temperature
|
|
19968
|
+
},
|
|
19969
|
+
};
|
|
19970
|
+
console.log('!!!! promptWithAgentModelRequirementsForOpenAiAssistantExecutionTools:', promptWithAgentModelRequirementsForOpenAiAssistantExecutionTools);
|
|
19971
|
+
underlyingLlmResult = await assistant.callChatModelStream(promptWithAgentModelRequirementsForOpenAiAssistantExecutionTools, onProgress);
|
|
18089
19972
|
}
|
|
18090
19973
|
else {
|
|
18091
19974
|
if (this.options.isVerbose) {
|
|
18092
19975
|
console.log(`2️⃣ Creating Assistant ${this.title} on generic LLM execution tools...`);
|
|
18093
19976
|
}
|
|
18094
|
-
// Create modified chat prompt with agent system message
|
|
18095
|
-
const modifiedChatPrompt = {
|
|
18096
|
-
...chatPrompt,
|
|
18097
|
-
modelRequirements: {
|
|
18098
|
-
...chatPrompt.modelRequirements,
|
|
18099
|
-
...modelRequirements,
|
|
18100
|
-
// Spread tools to convert readonly array to mutable
|
|
18101
|
-
tools: modelRequirements.tools ? [...modelRequirements.tools] : chatPrompt.modelRequirements.tools,
|
|
18102
|
-
// Prepend agent system message to existing system message
|
|
18103
|
-
systemMessage: modelRequirements.systemMessage +
|
|
18104
|
-
(chatPrompt.modelRequirements.systemMessage
|
|
18105
|
-
? `\n\n${chatPrompt.modelRequirements.systemMessage}`
|
|
18106
|
-
: ''),
|
|
18107
|
-
},
|
|
18108
|
-
};
|
|
18109
19977
|
if (this.options.llmTools.callChatModelStream) {
|
|
18110
|
-
underlyingLlmResult = await this.options.llmTools.callChatModelStream(
|
|
19978
|
+
underlyingLlmResult = await this.options.llmTools.callChatModelStream(promptWithAgentModelRequirements, onProgress);
|
|
18111
19979
|
}
|
|
18112
19980
|
else if (this.options.llmTools.callChatModel) {
|
|
18113
|
-
underlyingLlmResult = await this.options.llmTools.callChatModel(
|
|
19981
|
+
underlyingLlmResult = await this.options.llmTools.callChatModel(promptWithAgentModelRequirements);
|
|
18114
19982
|
onProgress(underlyingLlmResult);
|
|
18115
19983
|
}
|
|
18116
19984
|
else {
|
|
@@ -18139,7 +20007,7 @@ AgentLlmExecutionTools.assistantCache = new Map();
|
|
|
18139
20007
|
* TODO: [🧠] Adding parameter substitution support (here or should be responsibility of the underlying LLM Tools)
|
|
18140
20008
|
*/
|
|
18141
20009
|
|
|
18142
|
-
var _Agent_instances,
|
|
20010
|
+
var _Agent_instances, _Agent_selfLearnNonce, _Agent_selfLearnSamples, _Agent_selfLearnTeacher;
|
|
18143
20011
|
/**
|
|
18144
20012
|
* Represents one AI Agent
|
|
18145
20013
|
*
|
|
@@ -18199,22 +20067,33 @@ class Agent extends AgentLlmExecutionTools {
|
|
|
18199
20067
|
* This is parsed from commitments like USE BROWSER, USE SEARCH ENGINE, KNOWLEDGE, etc.
|
|
18200
20068
|
*/
|
|
18201
20069
|
this.capabilities = [];
|
|
20070
|
+
/**
|
|
20071
|
+
* List of sample conversations (question/answer pairs)
|
|
20072
|
+
*/
|
|
20073
|
+
this.samples = [];
|
|
18202
20074
|
/**
|
|
18203
20075
|
* Metadata like image or color
|
|
18204
20076
|
*/
|
|
18205
20077
|
this.meta = {};
|
|
20078
|
+
/**
|
|
20079
|
+
* Human-readable titles for tool functions
|
|
20080
|
+
*/
|
|
20081
|
+
this.toolTitles = {};
|
|
18206
20082
|
// TODO: [🐱🚀] Add `Agent` simple "mocked" learning by appending to agent source
|
|
18207
20083
|
// TODO: [🐱🚀] Add `Agent` learning by promptbookAgent
|
|
20084
|
+
this.teacherAgent = options.teacherAgent;
|
|
18208
20085
|
this.agentSource = agentSource;
|
|
18209
20086
|
this.agentSource.subscribe((source) => {
|
|
18210
20087
|
this.updateAgentSource(source);
|
|
18211
|
-
const { agentName, personaDescription, initialMessage, links, meta, capabilities } = parseAgentSource(source);
|
|
20088
|
+
const { agentName, personaDescription, initialMessage, links, meta, capabilities, samples } = parseAgentSource(source);
|
|
18212
20089
|
this._agentName = agentName;
|
|
18213
20090
|
this.personaDescription = personaDescription;
|
|
18214
20091
|
this.initialMessage = initialMessage;
|
|
18215
20092
|
this.links = links;
|
|
18216
20093
|
this.capabilities = capabilities;
|
|
20094
|
+
this.samples = samples;
|
|
18217
20095
|
this.meta = { ...this.meta, ...meta };
|
|
20096
|
+
this.toolTitles = getAllCommitmentsToolTitles();
|
|
18218
20097
|
});
|
|
18219
20098
|
}
|
|
18220
20099
|
/**
|
|
@@ -18225,10 +20104,10 @@ class Agent extends AgentLlmExecutionTools {
|
|
|
18225
20104
|
async callChatModelStream(prompt, onProgress) {
|
|
18226
20105
|
var _a;
|
|
18227
20106
|
// [1] Check if the user is asking the same thing as in the samples
|
|
18228
|
-
const modelRequirements = await this.
|
|
20107
|
+
const modelRequirements = await this.getModelRequirements();
|
|
18229
20108
|
if (modelRequirements.samples) {
|
|
18230
20109
|
const normalizedPrompt = normalizeMessageText(prompt.content);
|
|
18231
|
-
const sample = modelRequirements.samples.find((sample) => normalizeMessageText(sample.question) === normalizedPrompt);
|
|
20110
|
+
const sample = modelRequirements.samples.find((sample) => sample.question !== null && normalizeMessageText(sample.question) === normalizedPrompt);
|
|
18232
20111
|
if (sample) {
|
|
18233
20112
|
const now = new Date().toISOString();
|
|
18234
20113
|
const result = {
|
|
@@ -18274,21 +20153,42 @@ class Agent extends AgentLlmExecutionTools {
|
|
|
18274
20153
|
if ((_a = modelRequirements.metadata) === null || _a === void 0 ? void 0 : _a.isClosed) {
|
|
18275
20154
|
return result;
|
|
18276
20155
|
}
|
|
18277
|
-
|
|
18278
|
-
//
|
|
20156
|
+
// TODO: !!!!! Return the answer and do the learning asynchronously
|
|
20157
|
+
// Note: [0] Asynchronously add nonce
|
|
20158
|
+
if (just(false)) {
|
|
20159
|
+
await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnNonce).call(this);
|
|
20160
|
+
}
|
|
20161
|
+
// Note: [1] Do the append of the samples
|
|
20162
|
+
await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnSamples).call(this, prompt, result);
|
|
20163
|
+
// Note: [2] Asynchronously call the teacher agent and invoke the silver link. When the teacher fails, keep just the samples
|
|
20164
|
+
await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnTeacher).call(this, prompt, result).catch((error) => {
|
|
20165
|
+
// !!!!! if (this.options.isVerbose) {
|
|
20166
|
+
console.error(colors.bgCyan('[Self-learning]') + colors.red(' Failed to learn from teacher agent'));
|
|
20167
|
+
console.error(error);
|
|
20168
|
+
// }
|
|
20169
|
+
});
|
|
18279
20170
|
return result;
|
|
18280
20171
|
}
|
|
18281
20172
|
}
|
|
18282
|
-
_Agent_instances = new WeakSet(),
|
|
20173
|
+
_Agent_instances = new WeakSet(), _Agent_selfLearnNonce =
|
|
18283
20174
|
/**
|
|
18284
|
-
* Self-learning:
|
|
20175
|
+
* Self-learning Step 0: Asynchronously with random timing add nonce to the agent source
|
|
18285
20176
|
*/
|
|
18286
|
-
async function
|
|
18287
|
-
|
|
20177
|
+
async function _Agent_selfLearnNonce() {
|
|
20178
|
+
await forTime(Math.random() * 5000);
|
|
20179
|
+
// <- TODO: [🕓] `await forRandom(...)`
|
|
20180
|
+
console.info(colors.bgCyan('[Self-learning]') + colors.cyan(' Nonce'));
|
|
20181
|
+
const nonce = `NONCE ${await linguisticHash(Math.random().toString())}`;
|
|
20182
|
+
// Append to the current source
|
|
20183
|
+
const currentSource = this.agentSource.value;
|
|
20184
|
+
const newSource = padBook(validateBook(spaceTrim$2(currentSource) + '\n\n---\n\n' + nonce));
|
|
20185
|
+
// <- TODO: [🈲] Use some object-based way how to append on book (with sections `---`)
|
|
20186
|
+
// Update the source (which will trigger the subscription and update the underlying tools)
|
|
20187
|
+
this.agentSource.next(newSource);
|
|
20188
|
+
}, _Agent_selfLearnSamples = function _Agent_selfLearnSamples(prompt, result) {
|
|
20189
|
+
console.info(colors.bgCyan('[Self-learning]') + colors.cyan(' Sampling'));
|
|
18288
20190
|
const learningExample = spaceTrim$2((block) => `
|
|
18289
20191
|
|
|
18290
|
-
---
|
|
18291
|
-
|
|
18292
20192
|
USER MESSAGE
|
|
18293
20193
|
${block(prompt.content)}
|
|
18294
20194
|
|
|
@@ -18296,53 +20196,81 @@ async function _Agent_selfLearn(prompt, result) {
|
|
|
18296
20196
|
${block(result.content)}
|
|
18297
20197
|
|
|
18298
20198
|
`);
|
|
18299
|
-
//
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
|
|
18306
|
-
|
|
18307
|
-
|
|
18308
|
-
|
|
20199
|
+
// Append to the current source
|
|
20200
|
+
const currentSource = this.agentSource.value;
|
|
20201
|
+
const newSource = padBook(validateBook(spaceTrim$2(currentSource) + '\n\n---\n\n' + learningExample));
|
|
20202
|
+
// <- TODO: [🈲] Use some object-based way how to append on book (with sections `---`)
|
|
20203
|
+
// Update the source (which will trigger the subscription and update the underlying tools)
|
|
20204
|
+
this.agentSource.next(newSource);
|
|
20205
|
+
}, _Agent_selfLearnTeacher =
|
|
20206
|
+
/**
|
|
20207
|
+
* Self-learning Step 2: Asynchronously call the teacher agent and invoke the silver link
|
|
20208
|
+
*/
|
|
20209
|
+
async function _Agent_selfLearnTeacher(prompt, result) {
|
|
20210
|
+
// [1] Call the teacher agent // <- !!!!! Emojis
|
|
20211
|
+
if (this.teacherAgent === null) {
|
|
20212
|
+
return;
|
|
20213
|
+
}
|
|
20214
|
+
console.info(colors.bgCyan('[Self-learning]') + colors.cyan(' Teacher'));
|
|
20215
|
+
const teacherResult = await this.teacherAgent.callChatModel({
|
|
20216
|
+
title: 'Self-learning',
|
|
20217
|
+
modelRequirements: {
|
|
20218
|
+
modelVariant: 'CHAT',
|
|
20219
|
+
},
|
|
20220
|
+
// TODO: !!!! Use prompt notation
|
|
20221
|
+
content: spaceTrim$2((block) => `
|
|
18309
20222
|
|
|
18310
|
-
|
|
20223
|
+
You are a teacher agent helping another agent to learn from its interactions.
|
|
18311
20224
|
|
|
18312
|
-
|
|
18313
|
-
Agent: ${block(result.content)}
|
|
20225
|
+
Here is your current client which you are teaching:
|
|
18314
20226
|
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
20227
|
+
\`\`\`book
|
|
20228
|
+
${block(this.agentSource.value)}
|
|
20229
|
+
\`\`\`
|
|
18318
20230
|
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
|
|
18326
|
-
|
|
18327
|
-
|
|
18328
|
-
|
|
18329
|
-
|
|
18330
|
-
|
|
18331
|
-
|
|
18332
|
-
|
|
18333
|
-
|
|
18334
|
-
|
|
18335
|
-
|
|
18336
|
-
|
|
18337
|
-
|
|
18338
|
-
|
|
18339
|
-
|
|
18340
|
-
|
|
20231
|
+
**And here is the latest interaction:**
|
|
20232
|
+
|
|
20233
|
+
**User:**
|
|
20234
|
+
${block(prompt.content)}
|
|
20235
|
+
|
|
20236
|
+
**Agent:**
|
|
20237
|
+
${block(result.content)}
|
|
20238
|
+
|
|
20239
|
+
|
|
20240
|
+
**Rules:**
|
|
20241
|
+
|
|
20242
|
+
- Decide what the agent should learn from this interaction.
|
|
20243
|
+
- Append new commitments at the end of the agent source.
|
|
20244
|
+
- Do not modify the current agent source, just return new commitments (KNOWLEDGE, RULE, etc.).
|
|
20245
|
+
- If there is nothing new to learn, return empty book code block
|
|
20246
|
+
- Wrap the commitments in a book code block.
|
|
20247
|
+
- Do not explain anything, just return the commitments wrapped in a book code block.
|
|
20248
|
+
- Write the learned commitments in the same style and language as in the original agent source.
|
|
20249
|
+
|
|
20250
|
+
|
|
20251
|
+
This is how book code block looks like:
|
|
20252
|
+
|
|
20253
|
+
\`\`\`book
|
|
20254
|
+
KNOWLEDGE The sky is blue.
|
|
20255
|
+
RULE Always be polite.
|
|
20256
|
+
\`\`\`
|
|
20257
|
+
`),
|
|
20258
|
+
// pipelineUrl: 'https://github.com/webgptorg/promptbook/blob/main/prompts/self-learning.ptbk.md',
|
|
20259
|
+
// <- TODO: !!!! Remove and `pipelineUrl` for agent purposes
|
|
20260
|
+
parameters: {},
|
|
20261
|
+
});
|
|
20262
|
+
console.log('!!!! teacherResult', teacherResult);
|
|
20263
|
+
const teacherCommitments = unwrapResult(teacherResult.content);
|
|
20264
|
+
if (teacherCommitments === '') {
|
|
20265
|
+
console.info(colors.bgCyan('[Self-learning]') +
|
|
20266
|
+
colors.cyan(' Teacher agent did not provide new commitments to learn'));
|
|
20267
|
+
return;
|
|
18341
20268
|
}
|
|
18342
|
-
// Append to the current source
|
|
20269
|
+
// [2] Append to the current source
|
|
18343
20270
|
const currentSource = this.agentSource.value;
|
|
18344
|
-
const newSource = padBook(validateBook(spaceTrim$2(currentSource) + '\n\n' +
|
|
18345
|
-
//
|
|
20271
|
+
const newSource = padBook(validateBook(spaceTrim$2(currentSource) + '\n\n' + teacherCommitments));
|
|
20272
|
+
// <- TODO: [🈲] Use some object-based way how to append on book (with sections `---`)
|
|
20273
|
+
// [3] Update the source
|
|
18346
20274
|
this.agentSource.next(newSource);
|
|
18347
20275
|
};
|
|
18348
20276
|
/**
|
|
@@ -18363,10 +20291,25 @@ async function _Agent_selfLearn(prompt, result) {
|
|
|
18363
20291
|
*/
|
|
18364
20292
|
class RemoteAgent extends Agent {
|
|
18365
20293
|
static async connect(options) {
|
|
18366
|
-
|
|
18367
|
-
const profileResponse = await fetch(
|
|
20294
|
+
const agentProfileUrl = `${options.agentUrl}/api/profile`;
|
|
20295
|
+
const profileResponse = await fetch(agentProfileUrl);
|
|
18368
20296
|
// <- TODO: [🐱🚀] What about closed-source agents?
|
|
18369
20297
|
// <- TODO: [🐱🚀] Maybe use promptbookFetch
|
|
20298
|
+
if (!profileResponse.ok) {
|
|
20299
|
+
throw new Error(spaceTrim$2((block) => `
|
|
20300
|
+
Failed to fetch remote agent profile:
|
|
20301
|
+
|
|
20302
|
+
Agent URL:
|
|
20303
|
+
${options.agentUrl}
|
|
20304
|
+
|
|
20305
|
+
Agent Profile URL:
|
|
20306
|
+
${agentProfileUrl}
|
|
20307
|
+
|
|
20308
|
+
Http Error:
|
|
20309
|
+
${block(profileResponse.statusText)}
|
|
20310
|
+
|
|
20311
|
+
`));
|
|
20312
|
+
}
|
|
18370
20313
|
const profile = await profileResponse.json();
|
|
18371
20314
|
// Note: We are creating dummy agent source because we don't have the source from the remote agent
|
|
18372
20315
|
// But we populate the metadata from the profile
|
|
@@ -18393,6 +20336,7 @@ class RemoteAgent extends Agent {
|
|
|
18393
20336
|
*/
|
|
18394
20337
|
},
|
|
18395
20338
|
agentSource,
|
|
20339
|
+
teacherAgent: null, // <- Note:
|
|
18396
20340
|
});
|
|
18397
20341
|
remoteAgent._remoteAgentName = profile.agentName;
|
|
18398
20342
|
remoteAgent._remoteAgentHash = profile.agentHash;
|
|
@@ -18400,11 +20344,13 @@ class RemoteAgent extends Agent {
|
|
|
18400
20344
|
remoteAgent.initialMessage = profile.initialMessage;
|
|
18401
20345
|
remoteAgent.links = profile.links;
|
|
18402
20346
|
remoteAgent.meta = profile.meta;
|
|
20347
|
+
remoteAgent.toolTitles = profile.toolTitles || {};
|
|
18403
20348
|
remoteAgent._isVoiceCallingEnabled = profile.isVoiceCallingEnabled === true; // [✨✷] Store voice calling status
|
|
18404
20349
|
return remoteAgent;
|
|
18405
20350
|
}
|
|
18406
20351
|
constructor(options) {
|
|
18407
20352
|
super(options);
|
|
20353
|
+
this.toolTitles = {};
|
|
18408
20354
|
this._isVoiceCallingEnabled = false; // [✨✷] Track voice calling status
|
|
18409
20355
|
this.agentUrl = options.agentUrl;
|
|
18410
20356
|
}
|
|
@@ -18484,6 +20430,7 @@ class RemoteAgent extends Agent {
|
|
|
18484
20430
|
// <- TODO: [🐱🚀] What about closed-source agents?
|
|
18485
20431
|
// <- TODO: [🐱🚀] Maybe use promptbookFetch
|
|
18486
20432
|
let content = '';
|
|
20433
|
+
const toolCalls = [];
|
|
18487
20434
|
if (!bookResponse.body) {
|
|
18488
20435
|
content = await bookResponse.text();
|
|
18489
20436
|
}
|
|
@@ -18499,6 +20446,36 @@ class RemoteAgent extends Agent {
|
|
|
18499
20446
|
doneReading = !!done;
|
|
18500
20447
|
if (value) {
|
|
18501
20448
|
const textChunk = decoder.decode(value, { stream: true });
|
|
20449
|
+
let isHandled = false;
|
|
20450
|
+
try {
|
|
20451
|
+
const lines = textChunk.split('\n');
|
|
20452
|
+
for (const line of lines) {
|
|
20453
|
+
const trimmedLine = line.trim();
|
|
20454
|
+
if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
|
|
20455
|
+
const chunk = JSON.parse(trimmedLine);
|
|
20456
|
+
if (chunk.toolCalls) {
|
|
20457
|
+
toolCalls.push(...chunk.toolCalls);
|
|
20458
|
+
onProgress({
|
|
20459
|
+
content,
|
|
20460
|
+
modelName: this.modelName,
|
|
20461
|
+
timing: {},
|
|
20462
|
+
usage: {},
|
|
20463
|
+
rawPromptContent: {},
|
|
20464
|
+
rawRequest: {},
|
|
20465
|
+
rawResponse: {},
|
|
20466
|
+
toolCalls: chunk.toolCalls,
|
|
20467
|
+
});
|
|
20468
|
+
isHandled = true;
|
|
20469
|
+
}
|
|
20470
|
+
}
|
|
20471
|
+
}
|
|
20472
|
+
}
|
|
20473
|
+
catch (error) {
|
|
20474
|
+
// Ignore non-json chunks
|
|
20475
|
+
}
|
|
20476
|
+
if (isHandled) {
|
|
20477
|
+
continue;
|
|
20478
|
+
}
|
|
18502
20479
|
// console.debug('RemoteAgent chunk:', textChunk);
|
|
18503
20480
|
content += textChunk;
|
|
18504
20481
|
onProgress({
|
|
@@ -18509,6 +20486,7 @@ class RemoteAgent extends Agent {
|
|
|
18509
20486
|
rawPromptContent: {},
|
|
18510
20487
|
rawRequest: {},
|
|
18511
20488
|
rawResponse: {},
|
|
20489
|
+
toolCalls,
|
|
18512
20490
|
});
|
|
18513
20491
|
}
|
|
18514
20492
|
}
|
|
@@ -18524,6 +20502,7 @@ class RemoteAgent extends Agent {
|
|
|
18524
20502
|
rawPromptContent: {},
|
|
18525
20503
|
rawRequest: {},
|
|
18526
20504
|
rawResponse: {},
|
|
20505
|
+
toolCalls,
|
|
18527
20506
|
});
|
|
18528
20507
|
}
|
|
18529
20508
|
}
|
|
@@ -18540,6 +20519,7 @@ class RemoteAgent extends Agent {
|
|
|
18540
20519
|
rawPromptContent: {},
|
|
18541
20520
|
rawRequest: {},
|
|
18542
20521
|
rawResponse: {},
|
|
20522
|
+
toolCalls,
|
|
18543
20523
|
// <- TODO: [🐱🚀] Transfer and proxy the metadata
|
|
18544
20524
|
};
|
|
18545
20525
|
return agentResult;
|
|
@@ -18628,7 +20608,7 @@ function PromptbookAgentSeamlessIntegration(props) {
|
|
|
18628
20608
|
? styles.PromptbookAgentSeamlessIntegrationStatusConnected
|
|
18629
20609
|
: connectionStatus === 'error'
|
|
18630
20610
|
? styles.PromptbookAgentSeamlessIntegrationStatusError
|
|
18631
|
-
: styles.PromptbookAgentSeamlessIntegrationStatusPending}` }), jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLabel, children: "CHAT" })] }), isOpen && (jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationWindow, children: [jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationHeader, style: { backgroundColor: color }, ref: setHeaderElement, children: [jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationTitle, children: (agent === null || agent === void 0 ? void 0 : agent.meta.fullname) || (meta === null || meta === void 0 ? void 0 : meta.fullname) || (agent === null || agent === void 0 ? void 0 : agent.agentName) || 'Chat with Agent' }), isIframeUsed && (jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: () => setIsOpen(false), title: "Close", children: jsx(CloseIcon, {}) }))] }), jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationContent, children: isIframeUsed ? (jsxs(Fragment, { children: [!isIframeLoaded && (jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: "Loading chat..." })), jsx("iframe", { src: agentUrl + '/chat?headless', className: styles.PromptbookAgentSeamlessIntegrationIframe, style: { opacity: isIframeLoaded ? 1 : 0 }, tabIndex: -1, onLoad: () => setIsIframeLoaded(true) })] })) : agent ? (jsx(AgentChat, { agent: agent, actionsContainer: headerElement, isFocusedOnLoad: isFocusedOnLoad, extraActions: jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: () => setIsOpen(false), title: "Close", children: jsx(CloseIcon, {}) }) })) : error ? (jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationError, children: ["Failed to connect to agent: ", error.message] })) : (jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: "Connecting to agent..." })) })] }))] }));
|
|
20611
|
+
: styles.PromptbookAgentSeamlessIntegrationStatusPending}` }), jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLabel, children: "CHAT" })] }), isOpen && (jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationWindow, children: [jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationHeader, style: { backgroundColor: color }, ref: setHeaderElement, children: [jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationTitle, children: (agent === null || agent === void 0 ? void 0 : agent.meta.fullname) || (meta === null || meta === void 0 ? void 0 : meta.fullname) || (agent === null || agent === void 0 ? void 0 : agent.agentName) || 'Chat with Agent' }), isIframeUsed && (jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: () => setIsOpen(false), title: "Close", children: jsx(CloseIcon, {}) }))] }), jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationContent, children: isIframeUsed ? (jsxs(Fragment, { children: [!isIframeLoaded && (jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: "Loading chat..." })), jsx("iframe", { src: agentUrl + '/chat?headless', className: styles.PromptbookAgentSeamlessIntegrationIframe, style: { opacity: isIframeLoaded ? 1 : 0 }, tabIndex: -1, onLoad: () => setIsIframeLoaded(true) })] })) : agent ? (jsx(AgentChat, { agent: agent, actionsContainer: headerElement, isFocusedOnLoad: isFocusedOnLoad, extraActions: jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: () => setIsOpen(false), title: "Close", children: jsx(CloseIcon, {}) }), visual: "STANDALONE" })) : error ? (jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationError, children: ["Failed to connect to agent: ", error.message] })) : (jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: "Connecting to agent..." })) })] }))] }));
|
|
18632
20612
|
}
|
|
18633
20613
|
|
|
18634
20614
|
/**
|