diff --git a/app/Console/Commands/LicenseImportCommand.php b/app/Console/Commands/LicenseImportCommand.php deleted file mode 100644 index 8ba6ece505..0000000000 --- a/app/Console/Commands/LicenseImportCommand.php +++ /dev/null @@ -1,398 +0,0 @@ -argument('filename'); - - - if (!$this->option('testrun')=='true') { - $this->comment('======= Importing Licenses from '.$filename.' ========='); - } else { - $this->comment('====== TEST ONLY License Import for '.$filename.' ===='); - $this->comment('============== NO DATA WILL BE WRITTEN =============='); - } - - if (! ini_get("auto_detect_line_endings")) { - ini_set("auto_detect_line_endings", '1'); - } - - $csv = Reader::createFromPath($this->argument('filename')); - $csv->setNewline("\r\n"); - $csv->setOffset(1); - $duplicates = ''; - - // Loop through the records - $nbInsert = $csv->each(function ($row) use ($duplicates) { - $status_id = 1; - - // Let's just map some of these entries to more user friendly words - - if (array_key_exists('0', $row)) { - $user_name = trim($row[0]); - } else { - $user_name = ''; - } - - if (array_key_exists('1', $row)) { - $user_email = trim($row[1]); - } else { - $user_email = ''; - } - - if (array_key_exists('2', $row)) { - $user_username = trim($row[2]); - } else { - $user_username = ''; - } - - if (array_key_exists('3', $row)) { - $user_license_name = trim($row[3]); - } else { - $user_license_name = ''; - } - - if (array_key_exists('4', $row)) { - $user_license_serial = trim($row[4]); - } else { - $user_license_serial = ''; - } - - if (array_key_exists('5', $row)) { - $user_licensed_to_name = trim($row[5]); - } else { - $user_licensed_to_name = ''; - } - - if (array_key_exists('6', $row)) { - $user_licensed_to_email = trim($row[6]); - } else { - $user_licensed_to_email = ''; - } - - if (array_key_exists('7', $row)) { - $user_license_seats = trim($row[7]); - } else { - $user_license_seats = ''; - } - - if (array_key_exists('8', $row)) { - $user_license_reassignable = trim($row[8]); - if ($user_license_reassignable!='') { - if ((strtolower($user_license_reassignable)=='yes') || (strtolower($user_license_reassignable)=='true') || ($user_license_reassignable=='1')) { - $user_license_reassignable = 1; - } - } else { - $user_license_reassignable = 0; - } - } else { - $user_license_reassignable = 0; - } - - if (array_key_exists('9', $row)) { - $user_license_supplier = trim($row[9]); - } else { - $user_license_supplier = ''; - } - - if (array_key_exists('10', $row)) { - $user_license_maintained = trim($row[10]); - - if ($user_license_maintained!='') { - if ((strtolower($user_license_maintained)=='yes') || (strtolower($user_license_maintained)=='true') || ($user_license_maintained=='1')) { - $user_license_maintained = 1; - } - } else { - $user_license_maintained = 0; - } - - - } else { - $user_license_maintained = ''; - } - - if (array_key_exists('11', $row)) { - $user_license_notes = trim($row[11]); - } else { - $user_license_notes = ''; - } - - if (array_key_exists('12', $row)) { - if ($row[12]!='') { - $user_license_purchase_date = date("Y-m-d 00:00:01", strtotime($row[12])); - } else { - $user_license_purchase_date = ''; - } - } else { - $user_license_purchase_date = 0; - } - - if (array_key_exists('13', $row)) { - $user_licensed_to_asset = trim($row[13]); - } else { - $user_licensed_to_asset = ''; - } - - // A number was given instead of a name - if (is_numeric($user_name)) { - $this->comment('User '.$user_name.' is not a name - assume this user already exists'); - $user_username = ''; - // No name was given - - } elseif ($user_name=='') { - $this->comment('No user data provided - skipping user creation, just adding license'); - $first_name = ''; - $last_name = ''; - $user_username = ''; - - } else { - - $name = explode(" ", $user_name); - $first_name = $name[0]; - $email_last_name = ''; - $email_prefix = $first_name; - - if (!array_key_exists(1, $name)) { - $last_name=''; - $email_last_name = $last_name; - $email_prefix = $first_name; - } else { - $last_name = str_replace($first_name, '', $user_name); - - if ($this->option('email_format')=='filastname') { - $email_last_name.=str_replace(' ', '', $last_name); - $email_prefix = $first_name[0].$email_last_name; - - } elseif ($this->option('email_format')=='firstname.lastname') { - $email_last_name.=str_replace(' ', '', $last_name); - $email_prefix = $first_name.'.'.$email_last_name; - - } elseif ($this->option('email_format')=='firstname') { - $email_last_name.=str_replace(' ', '', $last_name); - $email_prefix = $first_name; - } - - - } - - - $user_username = $email_prefix; - - // Generate an email based on their name if no email address is given - if ($user_email=='') { - if ($first_name=='Unknown') { - $status_id = 7; - } - $email = strtolower($email_prefix).'@'.$this->option('domain'); - $user_email = str_replace("'", '', $email); - } - } - - $this->comment('Full Name: '.$user_name); - $this->comment('First Name: '.$first_name); - $this->comment('Last Name: '.$last_name); - $this->comment('Username: '.$user_username); - $this->comment('Email: '.$user_email); - $this->comment('License Name: '.$user_license_name); - $this->comment('Serial No: '.$user_license_serial); - $this->comment('Licensed To Name: '.$user_licensed_to_name); - $this->comment('Licensed To Email: '.$user_licensed_to_email); - $this->comment('Seats: '.$user_license_seats); - $this->comment('Reassignable: '.$user_license_reassignable); - $this->comment('Supplier: '.$user_license_supplier); - $this->comment('Maintained: '.$user_license_maintained); - $this->comment('Notes: '.$user_license_notes); - $this->comment('Purchase Date: '.$user_license_purchase_date); - $this->comment('Asset ID: '.$user_licensed_to_asset); - - $this->comment('------------- Action Summary ----------------'); - - if ($user_username!='') { - if ($user = User::where('username', $user_username)->whereNotNull('username')->first()) { - $this->comment('User '.$user_username.' already exists'); - } else { - - $user = new \App\Models\User; - $password = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20); - - $user->first_name = $first_name; - $user->last_name = $last_name; - $user->username = $user_username; - $user->email = $user_email; - $user->permissions = '{user":1}'; - $user->password = bcrypt($password); - $user->activated = 1; - if ($user->save()) { - $this->comment('User '.$first_name.' created'); - } else { - $this->error('ERROR CREATING User '.$first_name.' '.$last_name); - $this->error($user->getErrors()); - } - - $this->comment('User '.$first_name.' created'); - } - } else { - $user = new User; - $user->user_id = null; - } - - - // Check for the supplier match and create it if it doesn't exist - if ($supplier = Supplier::where('name', $user_license_supplier)->first()) { - $this->comment('Supplier '.$user_license_supplier.' already exists'); - } else { - $supplier = new Supplier(); - $supplier->name = e($user_license_supplier); - $supplier->user_id = 1; - - if ($supplier->save()) { - $this->comment('Supplier '.$user_license_supplier.' was created'); - } else { - $this->comment('Something went wrong! Supplier '.$user_license_supplier.' was NOT created'); - } - - } - - - // Add the license - $license = new License(); - $license->name = e($user_license_name); - if ($user_license_purchase_date!='') { - $license->purchase_date = $user_license_purchase_date; - } else { - $license->purchase_date = null; - } - $license->serial = e($user_license_serial); - $license->seats = e($user_license_seats); - $license->supplier_id = $supplier->id; - $license->user_id = 1; - if ($user_license_purchase_date!='') { - $license->purchase_date = $user_license_purchase_date; - } else { - $license->purchase_date = null; - } - $license->license_name = $user_licensed_to_name; - $license->license_email = $user_licensed_to_email; - $license->notes = e($user_license_notes); - - if ($license->save()) { - $this->comment('License '.$user_license_name.' with serial number '.$user_license_serial.' was created'); - - - $license_seat_created = 0; - - for ($x = 0; $x < $user_license_seats; $x++) { - // Create the license seat entries - $license_seat = new LicenseSeat(); - $license_seat->license_id = $license->id; - - // Only assign the first seat to the user - if ($x==0) { - $license_seat->assigned_to = $user->id; - } else { - $license_seat->assigned_to = null; - } - - if($user_licensed_to_asset) { - $asset = Asset::where('asset_tag', $user_licensed_to_asset)->first(); - if($asset) { - $license_seat->asset_id = $asset->id; - } - } - - if ($license_seat->save()) { - $license_seat_created++; - } - } - - if ($license_seat_created > 0) { - $this->comment($license_seat_created.' seats were created'); - } else { - $this->comment('Something went wrong! NO seats for '.$user_license_name.' were created'); - } - - - - } else { - $this->comment('Something went wrong! License '.$user_license_name.' was NOT created'); - } - - - $this->comment('====================================='); - - return true; - - }); - - - } - - /** - * Get the console command arguments. - * - * @return array - */ - protected function getArguments() - { - return array( - array('filename', InputArgument::REQUIRED, 'File for the CSV import.'), - ); - } - - - /** - * Get the console command options. - * - * @return array - */ - protected function getOptions() - { - return array( - array('domain', null, InputOption::VALUE_REQUIRED, 'Email domain for generated email addresses.', null), - array('email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null), - array('testrun', null, InputOption::VALUE_REQUIRED, 'Test the output without writing to the database or not.', null), - ); - } -} diff --git a/app/Console/Commands/ObjectImportCommand.php b/app/Console/Commands/ObjectImportCommand.php index eb2b48a809..00c08b471a 100644 --- a/app/Console/Commands/ObjectImportCommand.php +++ b/app/Console/Commands/ObjectImportCommand.php @@ -80,10 +80,10 @@ class ObjectImportCommand extends Command $logFile = $this->option('logfile'); \Log::useFiles($logFile); if ($this->option('testrun')) { - $this->comment('====== TEST ONLY Asset Import for '.$filename.' ===='); + $this->comment('====== TEST ONLY Item Import for '.$filename.' ===='); $this->comment('============== NO DATA WILL BE WRITTEN =============='); } else { - $this->comment('======= Importing Assets from '.$filename.' ========='); + $this->comment('======= Importing Items from '.$filename.' ========='); } $importer->import(); @@ -175,7 +175,7 @@ class ObjectImportCommand extends Command array('username_format', null, InputOption::VALUE_REQUIRED, 'The format of the username that should be generated. Options are firstname.lastname, firstname, filastname, email', null), array('testrun', null, InputOption::VALUE_NONE, 'If set, will parse and output data without adding to database', null), array('logfile', null, InputOption::VALUE_REQUIRED, 'The path to log output to. storage/logs/importer.log by default', storage_path('logs/importer.log') ), - array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Or Accessory', 'Asset'), + array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Accessory, License, or User', 'Asset'), array('web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'), array('user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1), array('update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'), diff --git a/app/Console/Commands/PaveIt.php b/app/Console/Commands/PaveIt.php index 2b9cf0fcf2..35b6b03a9b 100644 --- a/app/Console/Commands/PaveIt.php +++ b/app/Console/Commands/PaveIt.php @@ -2,9 +2,6 @@ namespace App\Console\Commands; -use Illuminate\Console\Command; -use DB; - use App\Models\Accessory; use App\Models\Asset; use App\Models\AssetModel; @@ -12,14 +9,18 @@ use App\Models\Category; use App\Models\Company; use App\Models\Component; use App\Models\Consumable; +use App\Models\Department; use App\Models\Depreciation; use App\Models\Group; +use App\Models\Import; use App\Models\License; use App\Models\LicenseSeat; use App\Models\Location; use App\Models\Manufacturer; use App\Models\Statuslabel; use App\Models\Supplier; +use DB; +use Illuminate\Console\Command; class PaveIt extends Command { @@ -63,6 +64,7 @@ class PaveIt extends Command Company::getQuery()->delete(); Component::getQuery()->delete(); Consumable::getQuery()->delete(); + Department::getQuery()->delete(); Depreciation::getQuery()->delete(); License::getQuery()->delete(); LicenseSeat::getQuery()->delete(); @@ -108,6 +110,7 @@ class PaveIt extends Command \DB::statement('drop table IF EXISTS custom_fields'); \DB::statement('drop table IF EXISTS custom_fieldsets'); \DB::statement('drop table IF EXISTS depreciations'); + \DB::statement('drop table IF EXISTS departments'); \DB::statement('drop table IF EXISTS groups'); \DB::statement('drop table IF EXISTS history'); \DB::statement('drop table IF EXISTS components'); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 12a0570472..09741dbd1f 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -17,7 +17,6 @@ class Kernel extends ConsoleKernel Commands\CreateAdmin::class, Commands\SendExpirationAlerts::class, Commands\SendInventoryAlerts::class, - Commands\LicenseImportCommand::class, Commands\ObjectImportCommand::class, Commands\Versioning::class, Commands\SystemBackup::class, diff --git a/app/Http/Controllers/Api/ImportController.php b/app/Http/Controllers/Api/ImportController.php index 2ef18b784f..c565099348 100644 --- a/app/Http/Controllers/Api/ImportController.php +++ b/app/Http/Controllers/Api/ImportController.php @@ -11,6 +11,7 @@ use App\Models\Import; use Illuminate\Http\Request; use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Session; +use League\Csv\Reader; use Symfony\Component\HttpFoundation\File\Exception\FileException; class ImportController extends Controller @@ -29,7 +30,7 @@ class ImportController extends Controller } /** - * Store a newly created resource in storage. + * Process and store a CSV upload file. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response @@ -65,17 +66,21 @@ class ImportController extends Controller $results['error'].= ' ' . $exception->getMessage(); } return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 500); - } $file_name = date('Y-m-d-his').'-'.$fixed_filename; $import->file_path = $file_name; $import->filesize = filesize($path.'/'.$file_name); + //TODO: is there a lighter way to do this? + $reader = Reader::createFromPath("{$path}/{$file_name}"); + $import->header_row = $reader->fetchOne(0); + // Grab the first row to display via ajax as the user picks fields + $import->first_row = $reader->fetchOne(1); $import->save(); $results[] = $import; } $results = (new ImportsTransformer)->transformImports($results); return [ - 'files' => $results + 'files' => $results, ]; } return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.feature_disabled')), 500); @@ -90,7 +95,7 @@ class ImportController extends Controller { $this->authorize('create', Asset::class); $errors = $request->import(Import::find($import_id)); - $redirectTo = "hardware"; + $redirectTo = "hardware.index"; switch ($request->get('import-type')) { case "asset": $redirectTo = "hardware.index"; @@ -107,6 +112,9 @@ class ImportController extends Controller case "license": $redirectTo = "licenses.index"; break; + case "user": + $redirectTo = "users.index"; + break; } if ($errors) { //Failure diff --git a/app/Http/Controllers/AssetsController.php b/app/Http/Controllers/AssetsController.php index 892db747f1..0ced1799f0 100755 --- a/app/Http/Controllers/AssetsController.php +++ b/app/Http/Controllers/AssetsController.php @@ -12,6 +12,7 @@ use App\Models\Asset; use App\Models\AssetModel; use App\Models\Company; use App\Models\CustomField; +use App\Models\Import; use App\Models\Location; use App\Models\Setting; use App\Models\User; @@ -673,84 +674,6 @@ class AssetsController extends Controller } - - /** - * Get the Asset import upload page. - * - * @author [A. Gianotto] [] - * @since [v2.0] - * @return View - */ - public function getImportUpload() - { - $this->authorize('create', Asset::class); - return view('hardware/import'); - } - - - /** - * Map the fields for import - * - * @author [A. Gianotto] [] - * @since [v4.0] - * @return View - */ - public function getImportMap() - { - - $this->authorize('create', Asset::class); - - // This is currently hardcoded for testing - should use a post variable or something to dynamically select the correct file. - $file = storage_path().'/private_uploads/imports/2017-06-08-072329-sample-assets.csv'; - $reader = Reader::createFromPath($file); - $header_rows = $reader->fetchOne(0); - - // Grab the first row to display via ajax as the user picks fields - $first_row = $reader->fetchOne(1); - - // Grab all of the custom fields to we can map those too. - $custom_fields = CustomField::all(); - - return view('importer/fieldmapper')->with('header_rows', $header_rows)->with('first_row',$first_row)->with('custom_fields',$custom_fields); - } - - - /** - * Process the uploaded file - * - * @author [A. Gianotto] [] - * @since [v2.0] - * @return Redirect - */ - public function postProcessImportFile(ItemImportRequest $request) - { - $this->authorize('create', Asset::class); - $errors = $request->import(); - - // We use hardware instead of asset in the url - $redirectTo = "hardware"; - switch (request('import-type')) { - case "asset": - $redirectTo = "hardware.index"; - break; - case "accessory": - $redirectTo = "accessories.index"; - break; - case "consumable": - $redirectTo = "consumables.index"; - break; - case "component": - $redirectTo = "components.index"; - break; - } - - if ($errors) { //Failure - return redirect()->back()->with('import_errors', json_decode(json_encode($errors)))->with('error', trans('admin/hardware/message.import.error')); - } - return redirect()->to(route($redirectTo))->with('success', trans('admin/hardware/message.import.success')); - - } - /** * Returns a view that presents a form to clone an asset. * diff --git a/app/Http/Controllers/ImportsController.php b/app/Http/Controllers/ImportsController.php new file mode 100644 index 0000000000..705e9c9dcf --- /dev/null +++ b/app/Http/Controllers/ImportsController.php @@ -0,0 +1,18 @@ +authorize('create', Asset::class); + $imports = Import::latest()->get(); + $imports = (new ImportsTransformer)->transformImports($imports); + return view('importer/import')->with('imports', $imports); + } +} diff --git a/app/Http/Requests/ItemImportRequest.php b/app/Http/Requests/ItemImportRequest.php index efae398c4e..f0616bdeef 100644 --- a/app/Http/Requests/ItemImportRequest.php +++ b/app/Http/Requests/ItemImportRequest.php @@ -32,22 +32,35 @@ class ItemImportRequest extends FormRequest public function import(Import $import) { + ini_set('max_execution_time', 600); //600 seconds = 10 minutes + ini_set('memory_limit', '500M'); $filename = config('app.private_uploads') . '/imports/' . $import->file_path; - $class = title_case($this->input('import-type')); + $import->import_type = $this->input('import-type'); + $class = title_case($import->import_type); $classString = "App\\Importer\\{$class}Importer"; $importer = new $classString($filename); + $import->field_map = request('column-mappings'); + $import->save(); + $fieldMappings=[]; + if ($import->field_map) { + // We submit as csv field: column, but the importer is happier if we flip it here. + $fieldMappings = array_change_key_case(array_flip($import->field_map), CASE_LOWER); + // dd($fieldMappings); + } $importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback']) ->setUserId(Auth::id()) ->setUpdating($this->has('import-update')) - ->setUsernameFormat('firstname.lastname'); - + ->setUsernameFormat('firstname.lastname') + ->setFieldMappings($fieldMappings); + // $logFile = storage_path('logs/importer.log'); + // \Log::useFiles($logFile); $importer->import(); return $this->errors; } public function log($string) { - return; // FUTURE IMPLEMENTATION + // \Log::Info($string); } public function progress($count) @@ -58,7 +71,6 @@ class ItemImportRequest extends FormRequest public function errorCallback($item, $field, $errorString) { $this->errors[$item->name][$field] = $errorString; - // $this->errors[$item->name] = $errorString; } private $errors; diff --git a/app/Http/Transformers/ImportsTransformer.php b/app/Http/Transformers/ImportsTransformer.php index 4624447158..c20a7a6e73 100644 --- a/app/Http/Transformers/ImportsTransformer.php +++ b/app/Http/Transformers/ImportsTransformer.php @@ -26,6 +26,9 @@ class ImportsTransformer 'name' => $import->name, 'import_type' => $import->import_type, 'created_at' => $import->created_at->diffForHumans(), + 'header_row' => $import->header_row, + 'first_row' => $import->first_row, + 'field_map' => $import->field_map, ]; diff --git a/app/Importer/AccessoryImporter.php b/app/Importer/AccessoryImporter.php index f866ff32f4..51281fcbaf 100644 --- a/app/Importer/AccessoryImporter.php +++ b/app/Importer/AccessoryImporter.php @@ -7,11 +7,9 @@ use App\Models\Accessory; class AccessoryImporter extends ItemImporter { - protected $accessories; public function __construct($filename) { parent::__construct($filename); - $this->accessories = Accessory::all(); } protected function handle($row) @@ -28,17 +26,14 @@ class AccessoryImporter extends ItemImporter */ public function createAccessoryIfNotExists() { - $accessoryId = $this->accessories->search(function ($key) { - return strcasecmp($key->name, $this->item['name']) == 0; - }); - if ($accessoryId !== false) { + $accessory = Accessory::where('name', $this->item['name'])->first(); + if ($accessory) { if (!$this->updating) { $this->log('A matching Accessory ' . $this->item["name"] . ' already exists. '); return; } $this->log('Updating Accessory'); - $accessory = $this->accessories[$accessoryId]; $accessory->update($this->sanitizeItemForUpdating($accessory)); if (!$this->testRun) { $accessory->save(); @@ -57,7 +52,8 @@ class AccessoryImporter extends ItemImporter if ($accessory->save()) { $accessory->logCreate('Imported using CSV Importer'); $this->log('Accessory ' . $this->item["name"] . ' was created'); + return; } - $this->jsonError($accessory, 'Accessory'); + $this->logError($accessory, 'Accessory'); } } diff --git a/app/Importer/AssetImporter.php b/app/Importer/AssetImporter.php index 1604586e0d..cb19316881 100644 --- a/app/Importer/AssetImporter.php +++ b/app/Importer/AssetImporter.php @@ -45,10 +45,11 @@ class AssetImporter extends ItemImporter public function createAssetIfNotExists(array $row) { $editingAsset = false; - $asset = Asset::where(['asset_tag'=> $this->item['asset_tag']])->first(); + $asset_tag = $this->findCsvMatch($row, "asset_tag"); + $asset = Asset::where(['asset_tag'=> $asset_tag])->first(); if ($asset) { if (!$this->updating) { - $this->log('A matching Asset ' . $this->item['asset_tag'] . ' already exists'); + $this->log('A matching Asset ' . $asset_tag . ' already exists'); return; } @@ -58,24 +59,19 @@ class AssetImporter extends ItemImporter $this->log("No Matching Asset, Creating a new one"); $asset = new Asset; } - $this->item['serial'] = $this->array_smart_fetch($row, "serial number"); - $this->item['image'] = $this->array_smart_fetch($row, "image"); - $this->item['warranty_months'] = intval($this->array_smart_fetch($row, "warranty months")); - if ($this->item['asset_model'] = $this->createOrFetchAssetModel($row)) { - $this->item['model_id'] = $this->item['asset_model']->id; - } - if (isset($this->item["status_label"])) { - $this->item['status_id'] = $this->item["status_label"]->id; - } elseif (!$editingAsset) { - // Assume if we are editing, we already have a status and can ignore. + + $this->item['image'] = $this->findCsvMatch($row, "image"); + $this->item['warranty_months'] = intval($this->findCsvMatch($row, "warranty months")); + $this->item['model_id'] = $this->createOrFetchAssetModel($row); + if (!$this->item['status_id'] && !$editingAsset) { $this->log("No status field found, defaulting to first status."); $this->item['status_id'] = $this->defaultStatusLabelId; } - + $this->item['asset_tag'] = $asset_tag; // By default we're set this to location_id in the item. $item = $this->sanitizeItemForStoring($asset, $editingAsset); - if (isset($this->item["location"])) { + if (isset($this->item["location_id"])) { $item['rtd_location_id'] = $this->item['location_id']; unset($item['location_id']); } @@ -95,7 +91,7 @@ class AssetImporter extends ItemImporter $this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created'); return; } - $this->jsonError($asset, 'Asset "' . $this->item['name'].'"'); + $this->logError($asset, 'Asset "' . $this->item['name'].'"'); } } } diff --git a/app/Importer/ComponentImporter.php b/app/Importer/ComponentImporter.php index 4e8c180ffa..1c2f53a290 100644 --- a/app/Importer/ComponentImporter.php +++ b/app/Importer/ComponentImporter.php @@ -7,11 +7,9 @@ use App\Models\Component; class ComponentImporter extends ItemImporter { - protected $components; public function __construct($filename) { parent::__construct($filename); - $this->components = Component::all(); } protected function handle($row) @@ -31,11 +29,9 @@ class ComponentImporter extends ItemImporter $component = null; $editingComponent = false; $this->log("Creating Component"); - $componentId = $this->components->search(function ($key) { - return strcasecmp($key->name, $this->item['name']) == 0; - }); + $component = Component::where('name', $this->item['name']); - if ($componentId !== false) { + if ($component) { $editingComponent = true; $this->log('A matching Component ' . $this->item["name"] . ' already exists. '); if (!$this->updating) { @@ -75,6 +71,6 @@ class ComponentImporter extends ItemImporter } return; } - $this->jsonError($component, 'Component'); + $this->logError($component, 'Component'); } } diff --git a/app/Importer/ConsumableImporter.php b/app/Importer/ConsumableImporter.php index 02b02b5dfc..880c44afd6 100644 --- a/app/Importer/ConsumableImporter.php +++ b/app/Importer/ConsumableImporter.php @@ -7,11 +7,9 @@ use App\Models\Consumable; class ConsumableImporter extends ItemImporter { - protected $consumables; public function __construct($filename) { parent::__construct($filename); - $this->consumables = Consumable::all(); } protected function handle($row) @@ -28,16 +26,13 @@ class ConsumableImporter extends ItemImporter */ public function createConsumableIfNotExists() { - $consumableId = $this->consumables->search(function ($key) { - return strcasecmp($key->name, $this->item['name']) == 0; - }); - if ($consumableId !== false) { + $consumable = Consumable::where('name', $this->item['name'])->first(); + if ($consumable) { if (!$this->updating) { $this->log('A matching Consumable ' . $this->item["name"] . ' already exists. '); return; } $this->log('Updating Consumable'); - $consumable = $this->consumables[$consumableId]; $consumable->update($this->sanitizeItemForUpdating($consumable)); if (!$this->testRun) { $consumable->save(); @@ -57,7 +52,7 @@ class ConsumableImporter extends ItemImporter $this->log("Consumable " . $this->item["name"] . ' was created'); return; } - $this->jsonError($consumable, 'Consumable'); + $this->logError($consumable, 'Consumable'); return; } } diff --git a/app/Importer/Importer.php b/app/Importer/Importer.php index 3ad02a391e..8202ce0dc3 100644 --- a/app/Importer/Importer.php +++ b/app/Importer/Importer.php @@ -33,6 +33,11 @@ abstract class Importer * @var bool */ protected $updating; + /** + * Map of item fields->csv names + * @var array + */ + protected $fieldMap = []; /** * @var callable */ @@ -71,7 +76,7 @@ abstract class Importer public function import() { - $results = $this->normalizeInputArray($this->csv->fetchAssoc()); + $results = $this->csv->fetchAssoc(); $this->customFields = CustomField::All(['name']); DB::transaction(function () use (&$results) { Model::unguard(); @@ -87,20 +92,6 @@ abstract class Importer abstract protected function handle($row); - /** - * @param $results - * @return array - */ - public function normalizeInputArray($results) - { - $newArray = []; - - foreach ($results as $index => $arrayToNormalize) { - $newArray[$index] = array_change_key_case($arrayToNormalize); - } - return $newArray; - } - /** * Check to see if the given key exists in the array, and trim excess white space before returning it * @@ -111,17 +102,38 @@ abstract class Importer * @param $default string * @return string */ - public function array_smart_fetch(array $array, $key, $default = '') + public function findCsvMatch(array $array, $key, $default = '') { $val = $default; - if (array_key_exists(trim($key), $array)) { +// dd($array); + if($customKey = $this->lookupCustomKey($key)) { + $key = $customKey; + } + $this->log("Custom Key: ${key}"); + if (array_key_exists($key, $array)) { $val = e(Encoding::toUTF8(trim($array[ $key ]))); } - $key = title_case($key); // $this->log("${key}: ${val}"); return $val; } + /** + * Looks up A custom key in the custom field map + * + * @author Daniel Melzter + * @since 4.0 + * @param $key string + * @return string|null + */ + public function lookupCustomKey($key) + { + // dd($this->fieldMap); + if (array_key_exists($key, $this->fieldMap)) { + // $this->log("Found a match in our custom map: {$key} is " . $this->fieldMap[$key]); + return $key = $this->fieldMap[$key]; + } + return null; + } /** * Figure out the fieldname of the custom field * @@ -141,7 +153,7 @@ abstract class Importer call_user_func($this->logCallback, $string); } - protected function jsonError($item, $field) + protected function logError($item, $field) { call_user_func($this->errorCallback, $item, $field, $item->getErrors()); } @@ -160,9 +172,9 @@ abstract class Importer */ protected function createOrFetchUser($row) { - $user_name = $this->array_smart_fetch($row, "name"); - $user_email = $this->array_smart_fetch($row, "email"); - $user_username = $this->array_smart_fetch($row, "username"); + $user_name = $this->findCsvMatch($row, "name"); + $user_email = $this->findCsvMatch($row, "email"); + $user_username = $this->findCsvMatch($row, "username"); $first_name = ''; $last_name = ''; // A number was given instead of a name @@ -214,7 +226,7 @@ abstract class Importer if ($user->save()) { $this->log('User '.$first_name.' created'); } else { - $this->jsonError($user, 'User "' . $first_name . '"'); + $this->logError($user, 'User "' . $first_name . '"'); } } } @@ -279,6 +291,22 @@ abstract class Importer return $this; } + /** + * Defines mappings of csv fields + * + * @param bool $updating the updating + * + * @return self + */ + public function setFieldMappings($fields) + { + // Some initial sanitization. + + $this->fieldMap = $fields; + $this->log($this->fieldMap); + return $this; + } + /** * Sets the callbacks for the import * diff --git a/app/Importer/ItemImporter.php b/app/Importer/ItemImporter.php index ed31874b9e..c964567a0b 100644 --- a/app/Importer/ItemImporter.php +++ b/app/Importer/ItemImporter.php @@ -2,6 +2,7 @@ namespace App\Importer; +use App\Importer\UserImporter; use App\Models\AssetModel; use App\Models\Category; use App\Models\Company; @@ -20,61 +21,58 @@ class ItemImporter extends Importer protected function handle($row) { - // TODO: CHeck if this interferes with checkout to user.. it shouldn't.. - $this->item["user_id"] = $this->user_id; - $item_category = $this->array_smart_fetch($row, "category"); - $item_company_name = $this->array_smart_fetch($row, "company"); - $item_location = $this->array_smart_fetch($row, "location"); - $item_manufacturer = $this->array_smart_fetch($row, "manufacturer"); - $item_status_name = $this->array_smart_fetch($row, "status"); - $item_supplier = $this->array_smart_fetch($row, "supplier"); - $this->item["name"] = $this->array_smart_fetch($row, "item name"); - $this->item["purchase_date"] = null; - if ($this->array_smart_fetch($row, "purchase date")!='') { - $this->item["purchase_date"] = date("Y-m-d 00:00:01", strtotime($this->array_smart_fetch($row, "purchase date"))); - } - - $this->item["purchase_cost"] = $this->array_smart_fetch($row, "purchase cost"); - $this->item["order_number"] = $this->array_smart_fetch($row, "order number"); - $this->item["notes"] = $this->array_smart_fetch($row, "notes"); - $this->item["qty"] = $this->array_smart_fetch($row, "quantity"); - $this->item["requestable"] = $this->array_smart_fetch($row, "requestable"); - $this->item["asset_tag"] = $this->array_smart_fetch($row, "asset tag"); - - if ($this->item["user"] = $this->createOrFetchUser($row)) { - $this->item['assigned_to'] = $this->item['user']->id; - } - - if ($this->shouldUpdateField($item_location)) { - if ($this->item["location"] = $this->createOrFetchLocation($item_location)) { - $this->item["location_id"] = $this->item["location"]->id; - } - } + $item_category = $this->findCsvMatch($row, "category"); if ($this->shouldUpdateField($item_category)) { - if ($this->item["category"] = $this->createOrFetchCategory($item_category)) { - $this->item["category_id"] = $this->item["category"]->id; - } - } - if ($this->shouldUpdateField($item_manufacturer)) { - if ($this->item["manufacturer"] = $this->createOrFetchManufacturer($item_manufacturer)) { - $this->item["manufacturer_id"] = $this->item["manufacturer"]->id; - } + $this->item["category_id"] = $this->createOrFetchCategory($item_category); } + + $item_company_name = $this->findCsvMatch($row, "company"); if ($this->shouldUpdateField($item_company_name)) { - if ($this->item["company"] = $this->createOrFetchCompany($item_company_name)) { - $this->item["company_id"] = $this->item["company"]->id; - } + $this->item["company_id"] = $this->createOrFetchCompany($item_company_name); } + + $item_location = $this->findCsvMatch($row, "location"); + if ($this->shouldUpdateField($item_location)) { + $this->item["location_id"] = $this->createOrFetchLocation($item_location); + } + + $item_manufacturer = $this->findCsvMatch($row, "manufacturer"); + if ($this->shouldUpdateField($item_manufacturer)) { + $this->item["manufacturer_id"] = $this->createOrFetchManufacturer($item_manufacturer); + } + + $item_status_name = $this->findCsvMatch($row, "status"); if ($this->shouldUpdateField($item_status_name)) { - if ($this->item["status_label"] = $this->createOrFetchStatusLabel($item_status_name)) { - $this->item["status_label_id"] = $this->item["status_label"]->id; - } + $this->item["status_id"] = $this->createOrFetchStatusLabel($item_status_name); } + + $item_supplier = $this->findCsvMatch($row, "supplier"); if ($this->shouldUpdateField($item_supplier)) { - if ($this->item['supplier'] = $this->createOrFetchSupplier($item_supplier)) { - $this->item['supplier_id'] = $this->item['supplier']->id; + $this->item['supplier_id'] = $this->createOrFetchSupplier($item_supplier); + } + + $this->item["name"] = $this->findCsvMatch($row, "item_name"); + $this->item["notes"] = $this->findCsvMatch($row, "notes"); + $this->item["order_number"] = $this->findCsvMatch($row, "order_number"); + $this->item["purchase_cost"] = $this->findCsvMatch($row, "purchase_cost"); + + $this->item["purchase_date"] = null; + if ($this->findCsvMatch($row, "purchase date")!='') { + $this->item["purchase_date"] = date("Y-m-d 00:00:01", strtotime($this->findCsvMatch($row, "purchase date"))); + } + + $this->item["qty"] = $this->findCsvMatch($row, "quantity"); + $this->item["requestable"] = $this->findCsvMatch($row, "requestable"); + $this->item["user_id"] = $this->user_id; + $this->item['serial'] = $this->findCsvMatch($row, "serial number"); + // NO need to call this method if we're running the user import. + // TODO: Merge these methods. + if(get_class($this) !== UserImporter::class) { + if ($this->item["user"] = $this->createOrFetchUser($row)) { + $this->item['assigned_to'] = $this->item['user']->id; } } + } /** @@ -94,8 +92,8 @@ class ItemImporter extends Importer // Create a collection for all manipulations to come. $item = collect($this->item); // First Filter the item down to the model's fillable fields - $item = $item->only($model->getFillable()); + // Then iterate through the item and, if we are updating, remove any blank values. if ($updating) { $item = $item->reject(function ($value) { @@ -108,8 +106,8 @@ class ItemImporter extends Importer /** * Convenience function for updating that strips the empty values. - * - * + * @param $model SnipeModel Model that's being updated. + * @return array */ protected function sanitizeItemForUpdating($model) { @@ -142,13 +140,13 @@ class ItemImporter extends Importer * @param array * @param $category Category * @param $manufacturer Manufacturer - * @return AssetModel + * @return int Id of asset model created/found * @internal param $asset_modelno string */ public function createOrFetchAssetModel(array $row) { - $asset_model_name = $this->array_smart_fetch($row, "model name"); - $asset_modelNumber = $this->array_smart_fetch($row, "model number"); + $asset_model_name = $this->findCsvMatch($row, "asset_model"); + $asset_modelNumber = $this->findCsvMatch($row, "model_number"); // TODO: At the moment, this means we can't update the model number if the model name stays the same. if (!$this->shouldUpdateField($asset_model_name)) { return; @@ -162,10 +160,9 @@ class ItemImporter extends Importer $asset_model = AssetModel::where(['name' => $asset_model_name, 'model_number' => $asset_modelNumber])->first(); if ($asset_model) { - if (!$this->updating) { $this->log("A matching model already exists, returning it."); - return $asset_model; + return $asset_model->id; } $this->log("Matching Model found, updating it."); $item = $this->sanitizeItemForStoring($asset_model, $editingModel); @@ -175,7 +172,8 @@ class ItemImporter extends Importer if (!$this->testRun) { $asset_model->save(); } - return $asset_model; + $this->log("Asset Model Updated"); + return $asset_model->id; } $this->log("No Matching Model, Creating a new one"); @@ -185,18 +183,18 @@ class ItemImporter extends Importer $item['model_number'] = $asset_modelNumber; $asset_model->fill($item); - + $item = null; if ($this->testRun) { $this->log('TEST RUN - asset_model ' . $asset_model->name . ' not created'); - return $asset_model; + return $asset_model->id; } if ($asset_model->save()) { $this->log('Asset Model ' . $asset_model_name . ' with model number ' . $asset_modelNumber . ' was created'); - return $asset_model; + return $asset_model->id; } - $this->jsonError($asset_model, 'Asset Model "' . $asset_model_name . '"'); - return; + $this->logError($asset_model, 'Asset Model "' . $asset_model_name . '"'); + return null; } /** @@ -205,7 +203,7 @@ class ItemImporter extends Importer * @author Daniel Melzter * @since 3.0 * @param $asset_category string - * @return Category + * @return int Id of category created/found * @internal param string $item_type */ public function createOrFetchCategory($asset_category) @@ -213,6 +211,7 @@ class ItemImporter extends Importer // Magic to transform "AssetImporter" to "asset" or similar. $classname = class_basename(get_class($this)); $item_type = strtolower(substr($classname, 0, strpos($classname, 'Importer'))); + if (empty($asset_category)) { $asset_category = 'Unnamed Category'; } @@ -220,7 +219,7 @@ class ItemImporter extends Importer if ($category) { $this->log("A matching category: " . $asset_category . " already exists"); - return $category; + return $category->id; } $category = new Category(); @@ -229,14 +228,15 @@ class ItemImporter extends Importer $category->user_id = $this->user_id; if ($this->testRun) { - return $category; + return $category->id; } if ($category->save()) { $this->log('Category ' . $asset_category . ' was created'); - return $category; + return $category->id; } - $this->jsonError($category, 'Category "'. $asset_category. '"'); + $this->logError($category, 'Category "'. $asset_category. '"'); + return null; } /** @@ -245,28 +245,28 @@ class ItemImporter extends Importer * @author Daniel Melzter * @since 3.0 * @param $asset_company_name string - * @return Company + * @return int id of company created/found */ public function createOrFetchCompany($asset_company_name) { $company = Company::where(['name' => $asset_company_name])->first(); if ($company) { $this->log('A matching Company ' . $asset_company_name . ' already exists'); - return $company; + return $company->id; } $company = new Company(); $company->name = $asset_company_name; if ($this->testRun) { - return $company; + return $company->id; } if ($company->save()) { $this->log('Company ' . $asset_company_name . ' was created'); - return $company; + return $company->id; } - $this->jsonError($company, 'Company'); - return; + $this->logError($company, 'Company'); + return null; } /** @@ -286,7 +286,7 @@ class ItemImporter extends Importer if ($status) { $this->log('A matching Status ' . $asset_statuslabel_name . ' already exists'); - return $status; + return $status->id; } $this->log("Creating a new status"); $status = new Statuslabel(); @@ -297,16 +297,16 @@ class ItemImporter extends Importer $status->archived = 0; if ($this->testRun) { - return $status; + return $status->id; } if ($status->save()) { $this->log('Status ' . $asset_statuslabel_name . ' was created'); - return $status; + return $status->id; } - $this->jsonError($status, 'Status "'. $asset_statuslabel_name . '"'); - return; + $this->logError($status, 'Status "'. $asset_statuslabel_name . '"'); + return null; } /** @@ -328,7 +328,7 @@ class ItemImporter extends Importer if ($manufacturer) { $this->log('Manufacturer ' . $item_manufacturer . ' already exists') ; - return $manufacturer; + return $manufacturer->id; } //Otherwise create a manufacturer. @@ -337,14 +337,14 @@ class ItemImporter extends Importer $manufacturer->user_id = $this->user_id; if ($this->testRun) { - return $manufacturer; + return $manufacturer->id; } if ($manufacturer->save()) { $this->log('Manufacturer ' . $manufacturer->name . ' was created'); - return $manufacturer; + return $manufacturer->id; } - $this->jsonError($manufacturer, 'Manufacturer "'. $manufacturer->name . '"'); - return; + $this->logError($manufacturer, 'Manufacturer "'. $manufacturer->name . '"'); + return null; } /** @@ -363,9 +363,9 @@ class ItemImporter extends Importer } $location = Location::where(['name' => $asset_location])->first(); - if ($location !== false) { + if ($location) { $this->log('Location ' . $asset_location . ' already exists'); - return $location; + return $location->id; } // No matching locations in the collection, create a new one. $location = new Location(); @@ -377,14 +377,14 @@ class ItemImporter extends Importer $location->user_id = $this->user_id; if ($this->testRun) { - return $location; + return $location->id; } if ($location->save()) { $this->log('Location ' . $asset_location . ' was created'); - return $location; + return $location->id; } - $this->jsonError($location, 'Location'); - return; + $this->logError($location, 'Location'); + return null; } /** @@ -405,7 +405,7 @@ class ItemImporter extends Importer if ($supplier) { $this->log('Supplier ' . $item_supplier . ' already exists'); - return $supplier; + return $supplier->id; } $supplier = new Supplier(); @@ -413,13 +413,13 @@ class ItemImporter extends Importer $supplier->user_id = $this->user_id; if ($this->testRun) { - return $supplier; + return $supplier->id; } if ($supplier->save()) { $this->log('Supplier ' . $item_supplier . ' was created'); - return $supplier; + return $supplier->id; } - $this->jsonError($supplier, 'Supplier'); - return; + $this->logError($supplier, 'Supplier'); + return null; } } diff --git a/app/Importer/LicenseImporter.php b/app/Importer/LicenseImporter.php index 5a2c6264e1..e2a9f01701 100644 --- a/app/Importer/LicenseImporter.php +++ b/app/Importer/LicenseImporter.php @@ -36,11 +36,9 @@ class LicenseImporter extends ItemImporter public function createLicenseIfNotExists(array $row) { $editingLicense = false; - $license = new License; - $license_id = $this->licenses->search(function ($key) { - return strcasecmp($key->name, $this->item['name']) == 0; - }); - if ($license_id !== false) { + $license = License::where('name', $this->item['name'])->first(); + + if ($license) { if (!$this->updating) { $this->log('A matching License ' . $this->item['name'] . ' already exists'); return; @@ -48,30 +46,26 @@ class LicenseImporter extends ItemImporter $this->log("Updating License"); $editingLicense = true; - $license = $this->licenses[$license_id]; } else { $this->log("No Matching License, Creating a new one"); } - - $asset_tag = $this->item['asset_tag'] = $this->array_smart_fetch($row, 'asset_tag'); // used for checkout out to an asset. - $this->item['expiration_date'] = $this->array_smart_fetch($row, 'expiration date'); - $this->item['license_email'] = $this->array_smart_fetch($row, "licensed to email"); - $this->item['license_name'] = $this->array_smart_fetch($row, "licensed to name"); - $this->item['maintained'] = $this->array_smart_fetch($row, 'maintained'); - $this->item['purchase_order'] = $this->array_smart_fetch($row, 'purchase_order'); - $this->item['reassignable'] = $this->array_smart_fetch($row, 'reassignable'); - $this->item['serial'] = $this->array_smart_fetch($row, "serial number"); - $this->item['termination_date'] = $this->array_smart_fetch($row, 'termination_date'); - $this->item['seats'] = $this->array_smart_fetch($row, 'seats'); + $license = new License; + $asset_tag = $this->item['asset_tag'] = $this->findCsvMatch($row, 'asset_tag'); // used for checkout out to an asset. + $this->item['expiration_date'] = $this->findCsvMatch($row, 'expiration_date'); + $this->item['license_email'] = $this->findCsvMatch($row, "licensed_to_email"); + $this->item['license_name'] = $this->findCsvMatch($row, "licensed_to_name"); + $this->item['maintained'] = $this->findCsvMatch($row, 'maintained'); + $this->item['purchase_order'] = $this->findCsvMatch($row, 'purchase_order'); + $this->item['reassignable'] = $this->findCsvMatch($row, 'reassignable'); + $this->item['seats'] = $this->findCsvMatch($row, 'seats'); + $this->item['termination_date'] = $this->findCsvMatch($row, 'termination_date'); if ($editingLicense) { $license->update($this->sanitizeItemForUpdating($license)); } else { $license->fill($this->sanitizeItemForStoring($license)); } - if (!$editingLicense) { - $this->licenses->add($license); - } + if (!$this->testRun) { if ($license->save()) { $license->logCreate('Imported using csv importer'); @@ -95,7 +89,7 @@ class LicenseImporter extends ItemImporter } return; } - $this->jsonError($license, 'License "' . $this->item['name'].'"'); + $this->logError($license, 'License "' . $this->item['name'].'"'); } } } diff --git a/app/Importer/UserImporter.php b/app/Importer/UserImporter.php new file mode 100644 index 0000000000..383088305d --- /dev/null +++ b/app/Importer/UserImporter.php @@ -0,0 +1,73 @@ +users = User::all(); + } + + protected function handle($row) + { + parent::handle($row); + $this->createUserIfNotExists($row); + } + + /** + * Create a user if a duplicate does not exist. + * @todo Investigate how this should interact with Importer::createOrFetchUser + * + * @author Daniel Melzter + * @since 4.0 + */ + public function createUserIfNotExists(array $row) + { + // User Specific Bits + $this->item['username'] = $this->findCsvMatch($row, 'username'); + $this->item['first_name'] = $this->findCsvMatch($row, 'first_name'); + $this->item['last_name'] = $this->findCsvMatch($row, 'last_name'); + $this->item['email'] = $this->findCsvMatch($row, 'user_email'); + $this->item['phone'] = $this->findCsvMatch($row, 'phone_number'); + $this->item['jobtitle'] = $this->findCsvMatch($row, 'jobtitle'); + $this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num'); + $this->item['password'] = $this->tempPassword; + $user = User::where('username', $this->item['username'])->first(); + if ($user) { + if (!$this->updating) { + $this->log('A matching User ' . $this->item["name"] . ' already exists. '); + return; + } + $this->log('Updating User'); + // $user = $this->users[$userId]; + $user->update($this->sanitizeItemForUpdating($user)); + if (!$this->testRun) { + $user->save(); + } + return; + } + $this->log("No matching user, creating one"); + $user = new User(); + $user->fill($this->sanitizeItemForStoring($user)); + + if ($this->testRun) { + $this->log('TEST RUN - User ' . $this->item['name'] . ' not created'); + return; + } + if ($user->save()) { + // $user->logCreate('Imported using CSV Importer'); + $this->log("User " . $this->item["name"] . ' was created'); + $user = null; + $this->item = null; + return; + } + $this->logError($user, 'User'); + return; + } +} diff --git a/app/Importer/import_mappings.md b/app/Importer/import_mappings.md new file mode 100644 index 0000000000..ad356ea615 --- /dev/null +++ b/app/Importer/import_mappings.md @@ -0,0 +1,33 @@ +| CSV | Item | Applicable Types | +|---------------------|------------------|-------------------------------------------| +| asset tag | asset_tag | Asset | +| category | category_id | All | +| company | company_id | All | +| item name | name | All | +| image | image | asset | +| expiration date | expiration_date | License | +| location | location_id | All | +| notes | notes | All | +| licensed to email | license_email | License | +| licensed to name | license_name | License | +| maintained | maintained | License | +| manufacturer | manufacturer_id | All | +| model name | model_id | Asset | +| model number | model_id | Asset | +| order number | order_number | All ? | +| purchase cost | purchase_cost | All ? | +| purchase date | purchase_date | All ? | +| purchase order | purchase_order | License | +| quantity | qty | Accessory, Consumable, Component, License | +| reassignable | reassignable | License | +| requestable | requestable | Asset, Accessory? | +| seats | seats | License | +| serial number | serial | asset, license | +| status | status_id | asset ? All | +| supplier | supplier_id | Asset ? All | +| termination date | termination_date | License | +| warranty months | warranty_months | asset | +| User Related Fields | assigned_to | Asset | +| name | | | +| email | | | +| username | | | \ No newline at end of file diff --git a/app/Models/Import.php b/app/Models/Import.php index d46f7e8240..dbc444ed09 100644 --- a/app/Models/Import.php +++ b/app/Models/Import.php @@ -6,4 +6,9 @@ use Illuminate\Database\Eloquent\Model; class Import extends Model { + protected $casts = [ + 'header_row' => 'array', + 'first_row' => 'array', + 'field_map' => 'json' + ]; } diff --git a/app/Models/User.php b/app/Models/User.php index 42c584fef2..cb242b37c1 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -24,7 +24,19 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo protected $hidden = ['password']; protected $table = 'users'; protected $injectUniqueIdentifier = true; - protected $fillable = ['first_name', 'last_name', 'email','password','username','department_id']; + protected $fillable = [ + 'email', + 'last_name', + 'company_id', + 'department_id', + 'employee_num', + 'jobtitle', + 'location_id', + 'password', + 'phone_number', + 'username', + 'first_name', + ]; protected $casts = [ 'activated' => 'boolean', diff --git a/app/Observers/AccessoryObserver.php b/app/Observers/AccessoryObserver.php index 941296e262..4b2f7e1a7f 100644 --- a/app/Observers/AccessoryObserver.php +++ b/app/Observers/AccessoryObserver.php @@ -24,8 +24,6 @@ class AccessoryObserver $logAction->created_at = date("Y-m-d H:i:s"); $logAction->user_id = Auth::id(); $logAction->logaction('update'); - - } @@ -41,7 +39,6 @@ class AccessoryObserver { $settings = Setting::first(); $settings->increment('next_auto_tag_base'); - \Log::debug('Setting new next_auto_tag_base value'); $logAction = new Actionlog(); $logAction->item_type = Accessory::class; diff --git a/app/Observers/AssetObserver.php b/app/Observers/AssetObserver.php index 73ad2a17e9..85a5a1f1b9 100644 --- a/app/Observers/AssetObserver.php +++ b/app/Observers/AssetObserver.php @@ -17,15 +17,12 @@ class AssetObserver */ public function updated(Asset $asset) { - $logAction = new Actionlog(); $logAction->item_type = Asset::class; $logAction->item_id = $asset->id; $logAction->created_at = date("Y-m-d H:i:s"); $logAction->user_id = Auth::id(); $logAction->logaction('update'); - - } @@ -41,7 +38,6 @@ class AssetObserver { $settings = Setting::first(); $settings->increment('next_auto_tag_base'); - \Log::debug('Setting new next_auto_tag_base value'); $logAction = new Actionlog(); $logAction->item_type = Asset::class; diff --git a/app/Observers/ComponentObserver.php b/app/Observers/ComponentObserver.php index 0229510e74..e3a977852e 100644 --- a/app/Observers/ComponentObserver.php +++ b/app/Observers/ComponentObserver.php @@ -24,8 +24,6 @@ class ComponentObserver $logAction->created_at = date("Y-m-d H:i:s"); $logAction->user_id = Auth::id(); $logAction->logaction('update'); - - } @@ -41,7 +39,6 @@ class ComponentObserver { $settings = Setting::first(); $settings->increment('next_auto_tag_base'); - \Log::debug('Setting new next_auto_tag_base value'); $logAction = new Actionlog(); $logAction->item_type = Component::class; diff --git a/app/Observers/ConsumableObserver.php b/app/Observers/ConsumableObserver.php index 43c3a8fcc4..6f1fa9cd04 100644 --- a/app/Observers/ConsumableObserver.php +++ b/app/Observers/ConsumableObserver.php @@ -24,8 +24,6 @@ class ConsumableObserver $logAction->created_at = date("Y-m-d H:i:s"); $logAction->user_id = Auth::id(); $logAction->logaction('update'); - - } @@ -41,7 +39,6 @@ class ConsumableObserver { $settings = Setting::first(); $settings->increment('next_auto_tag_base'); - \Log::debug('Setting new next_auto_tag_base value'); $logAction = new Actionlog(); $logAction->item_type = Consumable::class; diff --git a/app/Observers/LicenseObserver.php b/app/Observers/LicenseObserver.php index 62928e7049..8ef5ae16e8 100644 --- a/app/Observers/LicenseObserver.php +++ b/app/Observers/LicenseObserver.php @@ -24,8 +24,6 @@ class LicenseObserver $logAction->created_at = date("Y-m-d H:i:s"); $logAction->user_id = Auth::id(); $logAction->logaction('update'); - - } @@ -41,7 +39,6 @@ class LicenseObserver { $settings = Setting::first(); $settings->increment('next_auto_tag_base'); - \Log::debug('Setting new next_auto_tag_base value'); $logAction = new Actionlog(); $logAction->item_type = License::class; diff --git a/build/css/app.css b/build/css/app.css index 8904f67e36..64ad0affc7 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -1,9 +1,4 @@ -/*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ html { font-family: sans-serif; -ms-text-size-adjust: 100%; @@ -230,6 +225,9 @@ th { h3 { page-break-after: avoid; } + select { + background: #fff !important; + } .navbar { display: none; } @@ -254,8 +252,8 @@ th { } @font-face { font-family: 'Glyphicons Halflings'; - src: url('../../../node_modules/bootstrap/fonts/glyphicons-halflings-regular.eot'); - src: url('../../../node_modules/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../../../node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../../../node_modules/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../../../node_modules/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); + src: url('../../../node_modules/bootstrap-less/fonts/glyphicons-halflings-regular.eot'); + src: url('../../../node_modules/bootstrap-less/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/bootstrap-less/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../../../node_modules/bootstrap-less/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../../../node_modules/bootstrap-less/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../../../node_modules/bootstrap-less/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); } .glyphicon { position: relative; @@ -944,24 +942,12 @@ th { .glyphicon-bitcoin:before { content: "\E227"; } -.glyphicon-btc:before { - content: "\E227"; -} -.glyphicon-xbt:before { - content: "\E227"; -} .glyphicon-yen:before { content: "\A5"; } -.glyphicon-jpy:before { - content: "\A5"; -} .glyphicon-ruble:before { content: "\20BD"; } -.glyphicon-rub:before { - content: "\20BD"; -} .glyphicon-scale:before { content: "\E230"; } @@ -1091,6 +1077,7 @@ a:focus { text-decoration: underline; } a:focus { + outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } @@ -1151,9 +1138,6 @@ hr { overflow: visible; clip: auto; } -[role="button"] { - cursor: pointer; -} h1, h2, h3, @@ -1322,72 +1306,62 @@ mark, .text-primary { color: #337ab7; } -a.text-primary:hover, -a.text-primary:focus { +a.text-primary:hover { color: #286090; } .text-success { color: #3c763d; } -a.text-success:hover, -a.text-success:focus { +a.text-success:hover { color: #2b542c; } .text-info { color: #31708f; } -a.text-info:hover, -a.text-info:focus { +a.text-info:hover { color: #245269; } .text-warning { color: #8a6d3b; } -a.text-warning:hover, -a.text-warning:focus { +a.text-warning:hover { color: #66512c; } .text-danger { color: #a94442; } -a.text-danger:hover, -a.text-danger:focus { +a.text-danger:hover { color: #843534; } .bg-primary { color: #fff; background-color: #337ab7; } -a.bg-primary:hover, -a.bg-primary:focus { +a.bg-primary:hover { background-color: #286090; } .bg-success { background-color: #dff0d8; } -a.bg-success:hover, -a.bg-success:focus { +a.bg-success:hover { background-color: #c1e2b3; } .bg-info { background-color: #d9edf7; } -a.bg-info:hover, -a.bg-info:focus { +a.bg-info:hover { background-color: #afd9ee; } .bg-warning { background-color: #fcf8e3; } -a.bg-warning:hover, -a.bg-warning:focus { +a.bg-warning:hover { background-color: #f7ecb5; } .bg-danger { background-color: #f2dede; } -a.bg-danger:hover, -a.bg-danger:focus { +a.bg-danger:hover { background-color: #e4b9b9; } .page-header { @@ -2515,6 +2489,7 @@ select[size] { input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { + outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } @@ -2555,20 +2530,13 @@ output { .form-control::-webkit-input-placeholder { color: #999; } -.form-control::-ms-expand { - border: 0; - background-color: transparent; -} .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + cursor: not-allowed; background-color: #eeeeee; opacity: 1; } -.form-control[disabled], -fieldset[disabled] .form-control { - cursor: not-allowed; -} textarea.form-control { height: auto; } @@ -2576,10 +2544,10 @@ input[type="search"] { -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { - input[type="date"].form-control, - input[type="time"].form-control, - input[type="datetime-local"].form-control, - input[type="month"].form-control { + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { line-height: 34px; } input[type="date"].input-sm, @@ -2635,7 +2603,6 @@ input[type="search"] { } .radio-inline, .checkbox-inline { - position: relative; display: inline-block; padding-left: 20px; margin-bottom: 0; @@ -2672,7 +2639,6 @@ fieldset[disabled] .checkbox label { padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; - min-height: 34px; } .form-control-static.input-lg, .form-control-static.input-sm { @@ -2701,18 +2667,17 @@ select[multiple].input-sm { line-height: 1.5; border-radius: 3px; } -.form-group-sm select.form-control { +select.form-group-sm .form-control { height: 30px; line-height: 30px; } -.form-group-sm textarea.form-control, -.form-group-sm select[multiple].form-control { +textarea.form-group-sm .form-control, +select[multiple].form-group-sm .form-control { height: auto; } .form-group-sm .form-control-static { height: 30px; - min-height: 32px; - padding: 6px 10px; + padding: 5px 10px; font-size: 12px; line-height: 1.5; } @@ -2738,18 +2703,17 @@ select[multiple].input-lg { line-height: 1.3333333; border-radius: 6px; } -.form-group-lg select.form-control { +select.form-group-lg .form-control { height: 46px; line-height: 46px; } -.form-group-lg textarea.form-control, -.form-group-lg select[multiple].form-control { +textarea.form-group-lg .form-control, +select[multiple].form-group-lg .form-control { height: auto; } .form-group-lg .form-control-static { height: 46px; - min-height: 38px; - padding: 11px 16px; + padding: 10px 16px; font-size: 18px; line-height: 1.3333333; } @@ -2771,16 +2735,12 @@ select[multiple].input-lg { text-align: center; pointer-events: none; } -.input-lg + .form-control-feedback, -.input-group-lg + .form-control-feedback, -.form-group-lg .form-control + .form-control-feedback { +.input-lg + .form-control-feedback { width: 46px; height: 46px; line-height: 46px; } -.input-sm + .form-control-feedback, -.input-group-sm + .form-control-feedback, -.form-group-sm .form-control + .form-control-feedback { +.input-sm + .form-control-feedback { width: 30px; height: 30px; line-height: 30px; @@ -2959,14 +2919,12 @@ select[multiple].input-lg { } @media (min-width: 768px) { .form-horizontal .form-group-lg .control-label { - padding-top: 11px; - font-size: 18px; + padding-top: 14.333333px; } } @media (min-width: 768px) { .form-horizontal .form-group-sm .control-label { padding-top: 6px; - font-size: 12px; } } .btn { @@ -2996,6 +2954,7 @@ select[multiple].input-lg { .btn.focus, .btn:active.focus, .btn.active.focus { + outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } @@ -3015,30 +2974,19 @@ select[multiple].input-lg { .btn[disabled], fieldset[disabled] .btn { cursor: not-allowed; + pointer-events: none; opacity: 0.65; filter: alpha(opacity=65); box-shadow: none; } -a.btn.disabled, -fieldset[disabled] a.btn { - pointer-events: none; -} .btn-default { color: #333; background-color: #fff; border-color: #ccc; } +.btn-default:hover, .btn-default:focus, -.btn-default.focus { - color: #333; - background-color: #e6e6e6; - border-color: #8c8c8c; -} -.btn-default:hover { - color: #333; - background-color: #e6e6e6; - border-color: #adadad; -} +.btn-default.focus, .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { @@ -3046,24 +2994,14 @@ fieldset[disabled] a.btn { background-color: #e6e6e6; border-color: #adadad; } -.btn-default:active:hover, -.btn-default.active:hover, -.open > .dropdown-toggle.btn-default:hover, -.btn-default:active:focus, -.btn-default.active:focus, -.open > .dropdown-toggle.btn-default:focus, -.btn-default:active.focus, -.btn-default.active.focus, -.open > .dropdown-toggle.btn-default.focus { - color: #333; - background-color: #d4d4d4; - border-color: #8c8c8c; -} .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { background-image: none; } +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, @@ -3072,7 +3010,13 @@ fieldset[disabled] .btn-default:hover, fieldset[disabled] .btn-default:focus, .btn-default.disabled.focus, .btn-default[disabled].focus, -fieldset[disabled] .btn-default.focus { +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { background-color: #fff; border-color: #ccc; } @@ -3085,17 +3029,9 @@ fieldset[disabled] .btn-default.focus { background-color: #337ab7; border-color: #2e6da4; } +.btn-primary:hover, .btn-primary:focus, -.btn-primary.focus { - color: #fff; - background-color: #286090; - border-color: #122b40; -} -.btn-primary:hover { - color: #fff; - background-color: #286090; - border-color: #204d74; -} +.btn-primary.focus, .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { @@ -3103,24 +3039,14 @@ fieldset[disabled] .btn-default.focus { background-color: #286090; border-color: #204d74; } -.btn-primary:active:hover, -.btn-primary.active:hover, -.open > .dropdown-toggle.btn-primary:hover, -.btn-primary:active:focus, -.btn-primary.active:focus, -.open > .dropdown-toggle.btn-primary:focus, -.btn-primary:active.focus, -.btn-primary.active.focus, -.open > .dropdown-toggle.btn-primary.focus { - color: #fff; - background-color: #204d74; - border-color: #122b40; -} .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { background-image: none; } +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, @@ -3129,7 +3055,13 @@ fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled.focus, .btn-primary[disabled].focus, -fieldset[disabled] .btn-primary.focus { +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { background-color: #337ab7; border-color: #2e6da4; } @@ -3142,17 +3074,9 @@ fieldset[disabled] .btn-primary.focus { background-color: #5cb85c; border-color: #4cae4c; } +.btn-success:hover, .btn-success:focus, -.btn-success.focus { - color: #fff; - background-color: #449d44; - border-color: #255625; -} -.btn-success:hover { - color: #fff; - background-color: #449d44; - border-color: #398439; -} +.btn-success.focus, .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { @@ -3160,24 +3084,14 @@ fieldset[disabled] .btn-primary.focus { background-color: #449d44; border-color: #398439; } -.btn-success:active:hover, -.btn-success.active:hover, -.open > .dropdown-toggle.btn-success:hover, -.btn-success:active:focus, -.btn-success.active:focus, -.open > .dropdown-toggle.btn-success:focus, -.btn-success:active.focus, -.btn-success.active.focus, -.open > .dropdown-toggle.btn-success.focus { - color: #fff; - background-color: #398439; - border-color: #255625; -} .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { background-image: none; } +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, @@ -3186,7 +3100,13 @@ fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, .btn-success.disabled.focus, .btn-success[disabled].focus, -fieldset[disabled] .btn-success.focus { +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { background-color: #5cb85c; border-color: #4cae4c; } @@ -3199,17 +3119,9 @@ fieldset[disabled] .btn-success.focus { background-color: #5bc0de; border-color: #46b8da; } +.btn-info:hover, .btn-info:focus, -.btn-info.focus { - color: #fff; - background-color: #31b0d5; - border-color: #1b6d85; -} -.btn-info:hover { - color: #fff; - background-color: #31b0d5; - border-color: #269abc; -} +.btn-info.focus, .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { @@ -3217,24 +3129,14 @@ fieldset[disabled] .btn-success.focus { background-color: #31b0d5; border-color: #269abc; } -.btn-info:active:hover, -.btn-info.active:hover, -.open > .dropdown-toggle.btn-info:hover, -.btn-info:active:focus, -.btn-info.active:focus, -.open > .dropdown-toggle.btn-info:focus, -.btn-info:active.focus, -.btn-info.active.focus, -.open > .dropdown-toggle.btn-info.focus { - color: #fff; - background-color: #269abc; - border-color: #1b6d85; -} .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { background-image: none; } +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, @@ -3243,7 +3145,13 @@ fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, .btn-info.disabled.focus, .btn-info[disabled].focus, -fieldset[disabled] .btn-info.focus { +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { background-color: #5bc0de; border-color: #46b8da; } @@ -3256,17 +3164,9 @@ fieldset[disabled] .btn-info.focus { background-color: #f0ad4e; border-color: #eea236; } +.btn-warning:hover, .btn-warning:focus, -.btn-warning.focus { - color: #fff; - background-color: #ec971f; - border-color: #985f0d; -} -.btn-warning:hover { - color: #fff; - background-color: #ec971f; - border-color: #d58512; -} +.btn-warning.focus, .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { @@ -3274,24 +3174,14 @@ fieldset[disabled] .btn-info.focus { background-color: #ec971f; border-color: #d58512; } -.btn-warning:active:hover, -.btn-warning.active:hover, -.open > .dropdown-toggle.btn-warning:hover, -.btn-warning:active:focus, -.btn-warning.active:focus, -.open > .dropdown-toggle.btn-warning:focus, -.btn-warning:active.focus, -.btn-warning.active.focus, -.open > .dropdown-toggle.btn-warning.focus { - color: #fff; - background-color: #d58512; - border-color: #985f0d; -} .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { background-image: none; } +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, @@ -3300,7 +3190,13 @@ fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled.focus, .btn-warning[disabled].focus, -fieldset[disabled] .btn-warning.focus { +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { background-color: #f0ad4e; border-color: #eea236; } @@ -3313,17 +3209,9 @@ fieldset[disabled] .btn-warning.focus { background-color: #d9534f; border-color: #d43f3a; } +.btn-danger:hover, .btn-danger:focus, -.btn-danger.focus { - color: #fff; - background-color: #c9302c; - border-color: #761c19; -} -.btn-danger:hover { - color: #fff; - background-color: #c9302c; - border-color: #ac2925; -} +.btn-danger.focus, .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { @@ -3331,24 +3219,14 @@ fieldset[disabled] .btn-warning.focus { background-color: #c9302c; border-color: #ac2925; } -.btn-danger:active:hover, -.btn-danger.active:hover, -.open > .dropdown-toggle.btn-danger:hover, -.btn-danger:active:focus, -.btn-danger.active:focus, -.open > .dropdown-toggle.btn-danger:focus, -.btn-danger:active.focus, -.btn-danger.active.focus, -.open > .dropdown-toggle.btn-danger.focus { - color: #fff; - background-color: #ac2925; - border-color: #761c19; -} .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { background-image: none; } +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, @@ -3357,7 +3235,13 @@ fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled.focus, .btn-danger[disabled].focus, -fieldset[disabled] .btn-danger.focus { +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { background-color: #d9534f; border-color: #d43f3a; } @@ -3439,9 +3323,11 @@ input[type="button"].btn-block { } .collapse { display: none; + visibility: hidden; } .collapse.in { display: block; + visibility: visible; } tr.collapse.in { display: table-row; @@ -3463,8 +3349,7 @@ tbody.collapse.in { height: 0; margin-left: 2px; vertical-align: middle; - border-top: 4px dashed; - border-top: 4px solid \9; + border-top: 4px solid; border-right: 4px solid transparent; border-left: 4px solid transparent; } @@ -3578,8 +3463,7 @@ tbody.collapse.in { .dropup .caret, .navbar-fixed-bottom .dropdown .caret { border-top: 0; - border-bottom: 4px dashed; - border-bottom: 4px solid \9; + border-bottom: 4px solid; content: ""; } .dropup .dropdown-menu, @@ -3628,7 +3512,6 @@ tbody.collapse.in { .btn-toolbar { margin-left: -5px; } -.btn-toolbar .btn, .btn-toolbar .btn-group, .btn-toolbar .input-group { float: left; @@ -3719,15 +3602,13 @@ tbody.collapse.in { } .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 4px; - border-top-left-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { + border-bottom-left-radius: 4px; border-top-right-radius: 0; border-top-left-radius: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; @@ -3784,9 +3665,6 @@ tbody.collapse.in { width: 100%; margin-bottom: 0; } -.input-group .form-control:focus { - z-index: 3; -} .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn { @@ -3922,7 +3800,6 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group { - z-index: 2; margin-left: -1px; } .nav { @@ -4108,9 +3985,11 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } .tab-content > .tab-pane { display: none; + visibility: hidden; } .tab-content > .active { display: block; + visibility: visible; } .nav-tabs .dropdown-menu { margin-top: -1px; @@ -4152,6 +4031,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn { } .navbar-collapse.collapse { display: block !important; + visibility: visible !important; height: auto !important; padding-bottom: 0; overflow: visible !important; @@ -4693,7 +4573,6 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > li > span:hover, .pagination > li > a:focus, .pagination > li > span:focus { - z-index: 2; color: #23527c; background-color: #eeeeee; border-color: #ddd; @@ -4704,7 +4583,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { - z-index: 3; + z-index: 2; color: #fff; background-color: #337ab7; border-color: #337ab7; @@ -4725,7 +4604,6 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination-lg > li > span { padding: 10px 16px; font-size: 18px; - line-height: 1.3333333; } .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span { @@ -4741,7 +4619,6 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination-sm > li > span { padding: 5px 10px; font-size: 12px; - line-height: 1.5; } .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span { @@ -4866,7 +4743,7 @@ a.label:focus { font-weight: bold; color: #fff; line-height: 1; - vertical-align: middle; + vertical-align: baseline; white-space: nowrap; text-align: center; background-color: #777777; @@ -4879,8 +4756,7 @@ a.label:focus { position: relative; top: -1px; } -.btn-xs .badge, -.btn-group-xs > .btn .badge { +.btn-xs .badge { top: 0; padding: 1px 5px; } @@ -4905,8 +4781,7 @@ a.badge:focus { margin-left: 3px; } .jumbotron { - padding-top: 30px; - padding-bottom: 30px; + padding: 30px 15px; margin-bottom: 30px; color: inherit; background-color: #eeeeee; @@ -4926,16 +4801,13 @@ a.badge:focus { .container .jumbotron, .container-fluid .jumbotron { border-radius: 6px; - padding-left: 15px; - padding-right: 15px; } .jumbotron .container { max-width: 100%; } @media screen and (min-width: 768px) { .jumbotron { - padding-top: 48px; - padding-bottom: 48px; + padding: 48px 0; } .container .jumbotron, .container-fluid .jumbotron { @@ -5133,9 +5005,6 @@ a.thumbnail.active { .media-object { display: block; } -.media-object.img-thumbnail { - max-width: none; -} .media-right, .media > .pull-right { padding-left: 10px; @@ -5185,26 +5054,18 @@ a.thumbnail.active { border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; } -a.list-group-item, -button.list-group-item { +a.list-group-item { color: #555; } -a.list-group-item .list-group-item-heading, -button.list-group-item .list-group-item-heading { +a.list-group-item .list-group-item-heading { color: #333; } a.list-group-item:hover, -button.list-group-item:hover, -a.list-group-item:focus, -button.list-group-item:focus { +a.list-group-item:focus { text-decoration: none; color: #555; background-color: #f5f5f5; } -button.list-group-item { - width: 100%; - text-align: left; -} .list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus { @@ -5250,27 +5111,20 @@ button.list-group-item { color: #3c763d; background-color: #dff0d8; } -a.list-group-item-success, -button.list-group-item-success { +a.list-group-item-success { color: #3c763d; } -a.list-group-item-success .list-group-item-heading, -button.list-group-item-success .list-group-item-heading { +a.list-group-item-success .list-group-item-heading { color: inherit; } a.list-group-item-success:hover, -button.list-group-item-success:hover, -a.list-group-item-success:focus, -button.list-group-item-success:focus { +a.list-group-item-success:focus { color: #3c763d; background-color: #d0e9c6; } a.list-group-item-success.active, -button.list-group-item-success.active, a.list-group-item-success.active:hover, -button.list-group-item-success.active:hover, -a.list-group-item-success.active:focus, -button.list-group-item-success.active:focus { +a.list-group-item-success.active:focus { color: #fff; background-color: #3c763d; border-color: #3c763d; @@ -5279,27 +5133,20 @@ button.list-group-item-success.active:focus { color: #31708f; background-color: #d9edf7; } -a.list-group-item-info, -button.list-group-item-info { +a.list-group-item-info { color: #31708f; } -a.list-group-item-info .list-group-item-heading, -button.list-group-item-info .list-group-item-heading { +a.list-group-item-info .list-group-item-heading { color: inherit; } a.list-group-item-info:hover, -button.list-group-item-info:hover, -a.list-group-item-info:focus, -button.list-group-item-info:focus { +a.list-group-item-info:focus { color: #31708f; background-color: #c4e3f3; } a.list-group-item-info.active, -button.list-group-item-info.active, a.list-group-item-info.active:hover, -button.list-group-item-info.active:hover, -a.list-group-item-info.active:focus, -button.list-group-item-info.active:focus { +a.list-group-item-info.active:focus { color: #fff; background-color: #31708f; border-color: #31708f; @@ -5308,27 +5155,20 @@ button.list-group-item-info.active:focus { color: #8a6d3b; background-color: #fcf8e3; } -a.list-group-item-warning, -button.list-group-item-warning { +a.list-group-item-warning { color: #8a6d3b; } -a.list-group-item-warning .list-group-item-heading, -button.list-group-item-warning .list-group-item-heading { +a.list-group-item-warning .list-group-item-heading { color: inherit; } a.list-group-item-warning:hover, -button.list-group-item-warning:hover, -a.list-group-item-warning:focus, -button.list-group-item-warning:focus { +a.list-group-item-warning:focus { color: #8a6d3b; background-color: #faf2cc; } a.list-group-item-warning.active, -button.list-group-item-warning.active, a.list-group-item-warning.active:hover, -button.list-group-item-warning.active:hover, -a.list-group-item-warning.active:focus, -button.list-group-item-warning.active:focus { +a.list-group-item-warning.active:focus { color: #fff; background-color: #8a6d3b; border-color: #8a6d3b; @@ -5337,27 +5177,20 @@ button.list-group-item-warning.active:focus { color: #a94442; background-color: #f2dede; } -a.list-group-item-danger, -button.list-group-item-danger { +a.list-group-item-danger { color: #a94442; } -a.list-group-item-danger .list-group-item-heading, -button.list-group-item-danger .list-group-item-heading { +a.list-group-item-danger .list-group-item-heading { color: inherit; } a.list-group-item-danger:hover, -button.list-group-item-danger:hover, -a.list-group-item-danger:focus, -button.list-group-item-danger:focus { +a.list-group-item-danger:focus { color: #a94442; background-color: #ebcccc; } a.list-group-item-danger.active, -button.list-group-item-danger.active, a.list-group-item-danger.active:hover, -button.list-group-item-danger.active:hover, -a.list-group-item-danger.active:focus, -button.list-group-item-danger.active:focus { +a.list-group-item-danger.active:focus { color: #fff; background-color: #a94442; border-color: #a94442; @@ -5430,10 +5263,6 @@ button.list-group-item-danger.active:focus { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } -.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} .panel-heading + .list-group .list-group-item:first-child { border-top-width: 0; } @@ -5732,10 +5561,10 @@ button.list-group-item-danger.active:focus { width: 100%; border: 0; } -.embed-responsive-16by9 { +.embed-responsive.embed-responsive-16by9 { padding-bottom: 56.25%; } -.embed-responsive-4by3 { +.embed-responsive.embed-responsive-4by3 { padding-bottom: 75%; } .well { @@ -5795,7 +5624,7 @@ button.close { right: 0; bottom: 0; left: 0; - z-index: 1050; + z-index: 1040; -webkit-overflow-scrolling: touch; outline: 0; } @@ -5830,12 +5659,10 @@ button.close { outline: 0; } .modal-backdrop { - position: fixed; + position: absolute; top: 0; right: 0; - bottom: 0; left: 0; - z-index: 1040; background-color: #000; } .modal-backdrop.fade { @@ -5849,6 +5676,7 @@ button.close { .modal-header { padding: 15px; border-bottom: 1px solid #e5e5e5; + min-height: 16.42857143px; } .modal-header .close { margin-top: -2px; @@ -5904,22 +5732,11 @@ button.close { position: absolute; z-index: 1070; display: block; + visibility: visible; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; font-size: 12px; + font-weight: normal; + line-height: 1.4; opacity: 0; filter: alpha(opacity=0); } @@ -5948,6 +5765,7 @@ button.close { padding: 3px 8px; color: #fff; text-align: center; + text-decoration: none; background-color: #000; border-radius: 4px; } @@ -6023,27 +5841,17 @@ button.close { max-width: 276px; padding: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-style: normal; + font-size: 14px; font-weight: normal; - letter-spacing: normal; - line-break: auto; line-height: 1.42857143; text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - font-size: 14px; background-color: #fff; background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.2); border-radius: 6px; box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; } .popover.top { margin-top: -10px; @@ -6168,8 +5976,8 @@ button.close { transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out; -webkit-backface-visibility: hidden; backface-visibility: hidden; - -webkit-perspective: 1000px; - perspective: 1000px; + -webkit-perspective: 1000; + perspective: 1000; } .carousel-inner > .item.next, .carousel-inner > .item.active.right { @@ -6233,7 +6041,6 @@ button.close { color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); - background-color: rgba(0, 0, 0, 0); } .carousel-control.left { background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); @@ -6261,7 +6068,6 @@ button.close { .carousel-control .glyphicon-chevron-right { position: absolute; top: 50%; - margin-top: -10px; z-index: 5; display: inline-block; } @@ -6279,6 +6085,7 @@ button.close { .carousel-control .icon-next { width: 20px; height: 20px; + margin-top: -10px; line-height: 1; font-family: serif; } @@ -6339,16 +6146,16 @@ button.close { .carousel-control .icon-next { width: 30px; height: 30px; - margin-top: -10px; + margin-top: -15px; font-size: 30px; } .carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev { - margin-left: -10px; + margin-left: -15px; } .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next { - margin-right: -10px; + margin-right: -15px; } .carousel-caption { left: 20%; @@ -6387,8 +6194,6 @@ button.close { .pager:after, .panel-body:before, .panel-body:after, -.modal-header:before, -.modal-header:after, .modal-footer:before, .modal-footer:after { content: " "; @@ -6408,7 +6213,6 @@ button.close { .navbar-collapse:after, .pager:after, .panel-body:after, -.modal-header:after, .modal-footer:after { clear: both; } @@ -6441,6 +6245,7 @@ button.close { } .hidden { display: none !important; + visibility: hidden !important; } .affix { position: fixed; @@ -6473,7 +6278,7 @@ button.close { display: block !important; } table.visible-xs { - display: table !important; + display: table; } tr.visible-xs { display: table-row !important; @@ -6503,7 +6308,7 @@ button.close { display: block !important; } table.visible-sm { - display: table !important; + display: table; } tr.visible-sm { display: table-row !important; @@ -6533,7 +6338,7 @@ button.close { display: block !important; } table.visible-md { - display: table !important; + display: table; } tr.visible-md { display: table-row !important; @@ -6563,7 +6368,7 @@ button.close { display: block !important; } table.visible-lg { - display: table !important; + display: table; } tr.visible-lg { display: table-row !important; @@ -6616,7 +6421,7 @@ button.close { display: block !important; } table.visible-print { - display: table !important; + display: table; } tr.visible-print { display: table-row !important; diff --git a/build/mix.js b/build/mix.js index 328b21195a..0ec01806cf 100644 --- a/build/mix.js +++ b/build/mix.js @@ -63,12 +63,19 @@ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 58); +/******/ return __webpack_require__(__webpack_require__.s = 61); /******/ }) /************************************************************************/ /******/ ({ -/***/ 58: +/***/ 6: +/***/ (function(module, exports) { + +eval("// removed by extract-text-webpack-plugin//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvbGVzcy9vdmVycmlkZXMubGVzcz9mZjJhIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIHJlbW92ZWQgYnkgZXh0cmFjdC10ZXh0LXdlYnBhY2stcGx1Z2luXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9yZXNvdXJjZXMvYXNzZXRzL2xlc3Mvb3ZlcnJpZGVzLmxlc3Ncbi8vIG1vZHVsZSBpZCA9IDZcbi8vIG1vZHVsZSBjaHVua3MgPSAxIl0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZVJvb3QiOiIifQ=="); + +/***/ }), + +/***/ 61: /***/ (function(module, exports, __webpack_require__) { __webpack_require__(9); @@ -77,13 +84,6 @@ __webpack_require__(8); module.exports = __webpack_require__(6); -/***/ }), - -/***/ 6: -/***/ (function(module, exports) { - -eval("// removed by extract-text-webpack-plugin//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvbGVzcy9vdmVycmlkZXMubGVzcz9mZjJhIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIHJlbW92ZWQgYnkgZXh0cmFjdC10ZXh0LXdlYnBhY2stcGx1Z2luXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9yZXNvdXJjZXMvYXNzZXRzL2xlc3Mvb3ZlcnJpZGVzLmxlc3Ncbi8vIG1vZHVsZSBpZCA9IDZcbi8vIG1vZHVsZSBjaHVua3MgPSAxIl0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZVJvb3QiOiIifQ=="); - /***/ }), /***/ 7: diff --git a/build/vue.js b/build/vue.js index e47c96887a..39e6e428c0 100644 --- a/build/vue.js +++ b/build/vue.js @@ -63,7 +63,7 @@ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 59); +/******/ return __webpack_require__(__webpack_require__.s = 62); /******/ }) /************************************************************************/ /******/ ([ @@ -82,7 +82,7 @@ eval("// this module is a runtime utility for cleaner component module output an /* 2 */ /***/ (function(module, exports, __webpack_require__) { -eval("/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n Modified by Evan You @yyx990803\n*/\n\nvar hasDocument = typeof document !== 'undefined'\n\nif (typeof DEBUG !== 'undefined' && DEBUG) {\n if (!hasDocument) {\n throw new Error(\n 'vue-style-loader cannot be used in a non-browser environment. ' +\n \"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.\"\n ) }\n}\n\nvar listToStyles = __webpack_require__(52)\n\n/*\ntype StyleObject = {\n id: number;\n parts: Array\n}\n\ntype StyleObjectPart = {\n css: string;\n media: string;\n sourceMap: ?string\n}\n*/\n\nvar stylesInDom = {/*\n [id: number]: {\n id: number,\n refs: number,\n parts: Array<(obj?: StyleObjectPart) => void>\n }\n*/}\n\nvar head = hasDocument && (document.head || document.getElementsByTagName('head')[0])\nvar singletonElement = null\nvar singletonCounter = 0\nvar isProduction = false\nvar noop = function () {}\n\n// Force single-tag solution on IE6-9, which has a hard limit on the # of \\n\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlP2FkYzQiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4uYWN0aW9uLWxpbmtbZGF0YS12LTIyNTc3OGMyXSB7XFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLm0tYi1ub25lW2RhdGEtdi0yMjU3NzhjMl0ge1xcbiAgICBtYXJnaW4tYm90dG9tOiAwO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4uLy4uLy4uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWU/NTczNGY0ZTRcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsaUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxuICAgIC5hY3Rpb24tbGluayB7XFxuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XFxuICAgIH1cXG5cXG4gICAgLm0tYi1ub25lIHtcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICAgIH1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXY+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwgcGFuZWwtZGVmYXVsdFxcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsLWhlYWRpbmdcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cXFwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyBhbGlnbi1pdGVtczogY2VudGVyO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlcnNvbmFsIEFjY2VzcyBUb2tlbnNcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XFxcImFjdGlvbi1saW5rXFxcIiBAY2xpY2s9XFxcInNob3dDcmVhdGVUb2tlbkZvcm1cXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGUgTmV3IFRva2VuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1ib2R5XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTm8gVG9rZW5zIE5vdGljZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVxcXCJtLWItbm9uZVxcXCIgdi1pZj1cXFwidG9rZW5zLmxlbmd0aCA9PT0gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgWW91IGhhdmUgbm90IGNyZWF0ZWQgYW55IHBlcnNvbmFsIGFjY2VzcyB0b2tlbnMuXFxuICAgICAgICAgICAgICAgICAgICA8L3A+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8IS0tIFBlcnNvbmFsIEFjY2VzcyBUb2tlbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XFxcInRhYmxlIHRhYmxlLWJvcmRlcmxlc3MgbS1iLW5vbmVcXFwiIHYtaWY9XFxcInRva2Vucy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5OYW1lPC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD48L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgdi1mb3I9XFxcInRva2VuIGluIHRva2Vuc1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENsaWVudCBOYW1lIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdG9rZW4ubmFtZSB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRGVsZXRlIEJ1dHRvbiAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclxcXCIgQGNsaWNrPVxcXCJyZXZva2UodG9rZW4pXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgIDwhLS0gQ3JlYXRlIFRva2VuIE1vZGFsIC0tPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwgZmFkZVxcXCIgaWQ9XFxcIm1vZGFsLWNyZWF0ZS10b2tlblxcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIiByb2xlPVxcXCJkaWFsb2dcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvbiBcXFwiIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiPiZ0aW1lczs8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIFRva2VuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9oND5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtIEVycm9ycyAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhbGVydCBhbGVydC1kYW5nZXJcXFwiIHYtaWY9XFxcImZvcm0uZXJyb3JzLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD48c3Ryb25nPldob29wcyE8L3N0cm9uZz4gU29tZXRoaW5nIHdlbnQgd3JvbmchPC9wPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSB2LWZvcj1cXFwiZXJyb3IgaW4gZm9ybS5lcnJvcnNcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVycm9yIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRlIFRva2VuIEZvcm0gLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGZvcm0gY2xhc3M9XFxcImZvcm0taG9yaXpvbnRhbFxcXCIgcm9sZT1cXFwiZm9ybVxcXCIgQHN1Ym1pdC5wcmV2ZW50PVxcXCJzdG9yZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZm9ybS1ncm91cFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC00IGNvbnRyb2wtbGFiZWxcXFwiPk5hbWU8L2xhYmVsPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTZcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cXFwiY3JlYXRlLXRva2VuLW5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIG5hbWU9XFxcIm5hbWVcXFwiIHYtbW9kZWw9XFxcImZvcm0ubmFtZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gU2NvcGVzIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIiB2LWlmPVxcXCJzY29wZXMubGVuZ3RoID4gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC00IGNvbnRyb2wtbGFiZWxcXFwiPlNjb3BlczwvbGFiZWw+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNlxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiB2LWZvcj1cXFwic2NvcGUgaW4gc2NvcGVzXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY2hlY2tib3hcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVxcXCJjaGVja2JveFxcXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGNsaWNrPVxcXCJ0b2dnbGVTY29wZShzY29wZS5pZClcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDpjaGVja2VkPVxcXCJzY29wZUlzQXNzaWduZWQoc2NvcGUuaWQpXFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgc2NvcGUuaWQgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNb2RhbCBBY3Rpb25zIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtZm9vdGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tZGVmYXVsdFxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCI+Q2xvc2U8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tcHJpbWFyeVxcXCIgQGNsaWNrPVxcXCJzdG9yZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZVxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICA8IS0tIEFjY2VzcyBUb2tlbiBNb2RhbCAtLT5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsIGZhZGVcXFwiIGlkPVxcXCJtb2RhbC1hY2Nlc3MtdG9rZW5cXFwiIHRhYmluZGV4PVxcXCItMVxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIj5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1kaWFsb2dcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1jb250ZW50XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b24gXFxcIiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj4mdGltZXM7PC9idXR0b24+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVxcXCJtb2RhbC10aXRsZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlcnNvbmFsIEFjY2VzcyBUb2tlblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaDQ+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIZXJlIGlzIHlvdXIgbmV3IHBlcnNvbmFsIGFjY2VzcyB0b2tlbi4gVGhpcyBpcyB0aGUgb25seSB0aW1lIGl0IHdpbGwgYmUgc2hvd24gc28gZG9uJ3QgbG9zZSBpdCFcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWW91IG1heSBub3cgdXNlIHRoaXMgdG9rZW4gdG8gbWFrZSBBUEkgcmVxdWVzdHMuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwcmU+PGNvZGU+e3sgYWNjZXNzVG9rZW4gfX08L2NvZGU+PC9wcmU+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTW9kYWwgQWN0aW9ucyAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWZvb3RlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiPkNsb3NlPC9idXR0b24+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC90ZW1wbGF0ZT5cXG5cXG48c2NyaXB0PlxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgICAvKlxcbiAgICAgICAgICogVGhlIGNvbXBvbmVudCdzIGRhdGEuXFxuICAgICAgICAgKi9cXG4gICAgICAgIGRhdGEoKSB7XFxuICAgICAgICAgICAgcmV0dXJuIHtcXG4gICAgICAgICAgICAgICAgYWNjZXNzVG9rZW46IG51bGwsXFxuXFxuICAgICAgICAgICAgICAgIHRva2VuczogW10sXFxuICAgICAgICAgICAgICAgIHNjb3BlczogW10sXFxuXFxuICAgICAgICAgICAgICAgIGZvcm06IHtcXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICcnLFxcbiAgICAgICAgICAgICAgICAgICAgc2NvcGVzOiBbXSxcXG4gICAgICAgICAgICAgICAgICAgIGVycm9yczogW11cXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICByZWFkeSgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBwcmVwYXJlQ29tcG9uZW50KCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldFRva2VucygpO1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldFNjb3BlcygpO1xcblxcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLXRva2VuJykub24oJ3Nob3duLmJzLm1vZGFsJywgKCkgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgJCgnI2NyZWF0ZS10b2tlbi1uYW1lJykuZm9jdXMoKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBwZXJzb25hbCBhY2Nlc3MgdG9rZW5zIGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBnZXRUb2tlbnMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KCcvb2F1dGgvcGVyc29uYWwtYWNjZXNzLXRva2VucycpXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRva2VucyA9IHJlc3BvbnNlLmRhdGE7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBhdmFpbGFibGUgc2NvcGVzLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIGdldFNjb3BlcygpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9vYXV0aC9zY29wZXMnKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY29wZXMgPSByZXNwb25zZS5kYXRhO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogU2hvdyB0aGUgZm9ybSBmb3IgY3JlYXRpbmcgbmV3IHRva2Vucy5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzaG93Q3JlYXRlVG9rZW5Gb3JtKCkge1xcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLXRva2VuJykubW9kYWwoJ3Nob3cnKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIENyZWF0ZSBhIG5ldyBwZXJzb25hbCBhY2Nlc3MgdG9rZW4uXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgc3RvcmUoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSBudWxsO1xcblxcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gW107XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAucG9zdCgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMnLCB0aGlzLmZvcm0pXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0ubmFtZSA9ICcnO1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzID0gW107XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5lcnJvcnMgPSBbXTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2tlbnMucHVzaChyZXNwb25zZS5kYXRhLnRva2VuKTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93QWNjZXNzVG9rZW4ocmVzcG9uc2UuZGF0YS5hY2Nlc3NUb2tlbik7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2gocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc3BvbnNlLmRhdGEgPT09ICdvYmplY3QnKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gXy5mbGF0dGVuKF8udG9BcnJheShyZXNwb25zZS5kYXRhKSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGlyKHRoaXMuZm9ybSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gWydTb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSBhZ2Fpbi4nXTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogVG9nZ2xlIHRoZSBnaXZlbiBzY29wZSBpbiB0aGUgbGlzdCBvZiBhc3NpZ25lZCBzY29wZXMuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgdG9nZ2xlU2NvcGUoc2NvcGUpIHtcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2NvcGVJc0Fzc2lnbmVkKHNjb3BlKSkge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnNjb3BlcyA9IF8ucmVqZWN0KHRoaXMuZm9ybS5zY29wZXMsIHMgPT4gcyA9PSBzY29wZSk7XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzLnB1c2goc2NvcGUpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGdpdmVuIHNjb3BlIGhhcyBiZWVuIGFzc2lnbmVkIHRvIHRoZSB0b2tlbi5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzY29wZUlzQXNzaWduZWQoc2NvcGUpIHtcXG4gICAgICAgICAgICAgICAgcmV0dXJuIF8uaW5kZXhPZih0aGlzLmZvcm0uc2NvcGVzLCBzY29wZSkgPj0gMDtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFNob3cgdGhlIGdpdmVuIGFjY2VzcyB0b2tlbiB0byB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzaG93QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pIHtcXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWNyZWF0ZS10b2tlbicpLm1vZGFsKCdoaWRlJyk7XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSBhY2Nlc3NUb2tlbjtcXG5cXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWFjY2Vzcy10b2tlbicpLm1vZGFsKCdzaG93Jyk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBSZXZva2UgdGhlIGdpdmVuIHRva2VuLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHJldm9rZSh0b2tlbikge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmRlbGV0ZSgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMvJyArIHRva2VuLmlkKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIH1cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi0yMjU3NzhjMlwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("/* */ \n\"format global\";\n\"deps jquery\";\n\"exports $\";\n/*!\n * Bootstrap v3.3.4 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\nif (typeof jQuery === 'undefined') {\n throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n 'use strict';\n var version = $.fn.jquery.split(' ')[0].split('.')\n if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {\n throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')\n }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.4\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n // ============================================================\n\n function transitionEnd() {\n var el = document.createElement('bootstrap')\n\n var transEndEventNames = {\n WebkitTransition : 'webkitTransitionEnd',\n MozTransition : 'transitionend',\n OTransition : 'oTransitionEnd otransitionend',\n transition : 'transitionend'\n }\n\n for (var name in transEndEventNames) {\n if (el.style[name] !== undefined) {\n return { end: transEndEventNames[name] }\n }\n }\n\n return false // explicit for ie8 ( ._.)\n }\n\n // http://blog.alexmaccaw.com/css-transitions\n $.fn.emulateTransitionEnd = function (duration) {\n var called = false\n var $el = this\n $(this).one('bsTransitionEnd', function () { called = true })\n var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n setTimeout(callback, duration)\n return this\n }\n\n $(function () {\n $.support.transition = transitionEnd()\n\n if (!$.support.transition) return\n\n $.event.special.bsTransitionEnd = {\n bindType: $.support.transition.end,\n delegateType: $.support.transition.end,\n handle: function (e) {\n if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n }\n }\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.4\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // ALERT CLASS DEFINITION\n // ======================\n\n var dismiss = '[data-dismiss=\"alert\"]'\n var Alert = function (el) {\n $(el).on('click', dismiss, this.close)\n }\n\n Alert.VERSION = '3.3.4'\n\n Alert.TRANSITION_DURATION = 150\n\n Alert.prototype.close = function (e) {\n var $this = $(this)\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = $(selector)\n\n if (e) e.preventDefault()\n\n if (!$parent.length) {\n $parent = $this.closest('.alert')\n }\n\n $parent.trigger(e = $.Event('close.bs.alert'))\n\n if (e.isDefaultPrevented()) return\n\n $parent.removeClass('in')\n\n function removeElement() {\n // detach from parent, fire event then clean up data\n $parent.detach().trigger('closed.bs.alert').remove()\n }\n\n $.support.transition && $parent.hasClass('fade') ?\n $parent\n .one('bsTransitionEnd', removeElement)\n .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n removeElement()\n }\n\n\n // ALERT PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.alert')\n\n if (!data) $this.data('bs.alert', (data = new Alert(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.alert\n\n $.fn.alert = Plugin\n $.fn.alert.Constructor = Alert\n\n\n // ALERT NO CONFLICT\n // =================\n\n $.fn.alert.noConflict = function () {\n $.fn.alert = old\n return this\n }\n\n\n // ALERT DATA-API\n // ==============\n\n $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.4\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // BUTTON PUBLIC CLASS DEFINITION\n // ==============================\n\n var Button = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Button.DEFAULTS, options)\n this.isLoading = false\n }\n\n Button.VERSION = '3.3.4'\n\n Button.DEFAULTS = {\n loadingText: 'loading...'\n }\n\n Button.prototype.setState = function (state) {\n var d = 'disabled'\n var $el = this.$element\n var val = $el.is('input') ? 'val' : 'html'\n var data = $el.data()\n\n state = state + 'Text'\n\n if (data.resetText == null) $el.data('resetText', $el[val]())\n\n // push to event loop to allow forms to submit\n setTimeout($.proxy(function () {\n $el[val](data[state] == null ? this.options[state] : data[state])\n\n if (state == 'loadingText') {\n this.isLoading = true\n $el.addClass(d).attr(d, d)\n } else if (this.isLoading) {\n this.isLoading = false\n $el.removeClass(d).removeAttr(d)\n }\n }, this), 0)\n }\n\n Button.prototype.toggle = function () {\n var changed = true\n var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n if ($parent.length) {\n var $input = this.$element.find('input')\n if ($input.prop('type') == 'radio') {\n if ($input.prop('checked') && this.$element.hasClass('active')) changed = false\n else $parent.find('.active').removeClass('active')\n }\n if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')\n } else {\n this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n }\n\n if (changed) this.$element.toggleClass('active')\n }\n\n\n // BUTTON PLUGIN DEFINITION\n // ========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.button')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n if (option == 'toggle') data.toggle()\n else if (option) data.setState(option)\n })\n }\n\n var old = $.fn.button\n\n $.fn.button = Plugin\n $.fn.button.Constructor = Button\n\n\n // BUTTON NO CONFLICT\n // ==================\n\n $.fn.button.noConflict = function () {\n $.fn.button = old\n return this\n }\n\n\n // BUTTON DATA-API\n // ===============\n\n $(document)\n .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n var $btn = $(e.target)\n if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n Plugin.call($btn, 'toggle')\n e.preventDefault()\n })\n .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.4\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CAROUSEL CLASS DEFINITION\n // =========================\n\n var Carousel = function (element, options) {\n this.$element = $(element)\n this.$indicators = this.$element.find('.carousel-indicators')\n this.options = options\n this.paused = null\n this.sliding = null\n this.interval = null\n this.$active = null\n this.$items = null\n\n this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n }\n\n Carousel.VERSION = '3.3.4'\n\n Carousel.TRANSITION_DURATION = 600\n\n Carousel.DEFAULTS = {\n interval: 5000,\n pause: 'hover',\n wrap: true,\n keyboard: true\n }\n\n Carousel.prototype.keydown = function (e) {\n if (/input|textarea/i.test(e.target.tagName)) return\n switch (e.which) {\n case 37: this.prev(); break\n case 39: this.next(); break\n default: return\n }\n\n e.preventDefault()\n }\n\n Carousel.prototype.cycle = function (e) {\n e || (this.paused = false)\n\n this.interval && clearInterval(this.interval)\n\n this.options.interval\n && !this.paused\n && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n return this\n }\n\n Carousel.prototype.getItemIndex = function (item) {\n this.$items = item.parent().children('.item')\n return this.$items.index(item || this.$active)\n }\n\n Carousel.prototype.getItemForDirection = function (direction, active) {\n var activeIndex = this.getItemIndex(active)\n var willWrap = (direction == 'prev' && activeIndex === 0)\n || (direction == 'next' && activeIndex == (this.$items.length - 1))\n if (willWrap && !this.options.wrap) return active\n var delta = direction == 'prev' ? -1 : 1\n var itemIndex = (activeIndex + delta) % this.$items.length\n return this.$items.eq(itemIndex)\n }\n\n Carousel.prototype.to = function (pos) {\n var that = this\n var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n if (pos > (this.$items.length - 1) || pos < 0) return\n\n if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n if (activeIndex == pos) return this.pause().cycle()\n\n return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n }\n\n Carousel.prototype.pause = function (e) {\n e || (this.paused = true)\n\n if (this.$element.find('.next, .prev').length && $.support.transition) {\n this.$element.trigger($.support.transition.end)\n this.cycle(true)\n }\n\n this.interval = clearInterval(this.interval)\n\n return this\n }\n\n Carousel.prototype.next = function () {\n if (this.sliding) return\n return this.slide('next')\n }\n\n Carousel.prototype.prev = function () {\n if (this.sliding) return\n return this.slide('prev')\n }\n\n Carousel.prototype.slide = function (type, next) {\n var $active = this.$element.find('.item.active')\n var $next = next || this.getItemForDirection(type, $active)\n var isCycling = this.interval\n var direction = type == 'next' ? 'left' : 'right'\n var that = this\n\n if ($next.hasClass('active')) return (this.sliding = false)\n\n var relatedTarget = $next[0]\n var slideEvent = $.Event('slide.bs.carousel', {\n relatedTarget: relatedTarget,\n direction: direction\n })\n this.$element.trigger(slideEvent)\n if (slideEvent.isDefaultPrevented()) return\n\n this.sliding = true\n\n isCycling && this.pause()\n\n if (this.$indicators.length) {\n this.$indicators.find('.active').removeClass('active')\n var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n $nextIndicator && $nextIndicator.addClass('active')\n }\n\n var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n if ($.support.transition && this.$element.hasClass('slide')) {\n $next.addClass(type)\n $next[0].offsetWidth // force reflow\n $active.addClass(direction)\n $next.addClass(direction)\n $active\n .one('bsTransitionEnd', function () {\n $next.removeClass([type, direction].join(' ')).addClass('active')\n $active.removeClass(['active', direction].join(' '))\n that.sliding = false\n setTimeout(function () {\n that.$element.trigger(slidEvent)\n }, 0)\n })\n .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n } else {\n $active.removeClass('active')\n $next.addClass('active')\n this.sliding = false\n this.$element.trigger(slidEvent)\n }\n\n isCycling && this.cycle()\n\n return this\n }\n\n\n // CAROUSEL PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.carousel')\n var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n var action = typeof option == 'string' ? option : options.slide\n\n if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n if (typeof option == 'number') data.to(option)\n else if (action) data[action]()\n else if (options.interval) data.pause().cycle()\n })\n }\n\n var old = $.fn.carousel\n\n $.fn.carousel = Plugin\n $.fn.carousel.Constructor = Carousel\n\n\n // CAROUSEL NO CONFLICT\n // ====================\n\n $.fn.carousel.noConflict = function () {\n $.fn.carousel = old\n return this\n }\n\n\n // CAROUSEL DATA-API\n // =================\n\n var clickHandler = function (e) {\n var href\n var $this = $(this)\n var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n if (!$target.hasClass('carousel')) return\n var options = $.extend({}, $target.data(), $this.data())\n var slideIndex = $this.attr('data-slide-to')\n if (slideIndex) options.interval = false\n\n Plugin.call($target, options)\n\n if (slideIndex) {\n $target.data('bs.carousel').to(slideIndex)\n }\n\n e.preventDefault()\n }\n\n $(document)\n .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n $(window).on('load', function () {\n $('[data-ride=\"carousel\"]').each(function () {\n var $carousel = $(this)\n Plugin.call($carousel, $carousel.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.4\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // COLLAPSE PUBLIC CLASS DEFINITION\n // ================================\n\n var Collapse = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Collapse.DEFAULTS, options)\n this.$trigger = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n this.transitioning = null\n\n if (this.options.parent) {\n this.$parent = this.getParent()\n } else {\n this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n }\n\n if (this.options.toggle) this.toggle()\n }\n\n Collapse.VERSION = '3.3.4'\n\n Collapse.TRANSITION_DURATION = 350\n\n Collapse.DEFAULTS = {\n toggle: true\n }\n\n Collapse.prototype.dimension = function () {\n var hasWidth = this.$element.hasClass('width')\n return hasWidth ? 'width' : 'height'\n }\n\n Collapse.prototype.show = function () {\n if (this.transitioning || this.$element.hasClass('in')) return\n\n var activesData\n var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n if (actives && actives.length) {\n activesData = actives.data('bs.collapse')\n if (activesData && activesData.transitioning) return\n }\n\n var startEvent = $.Event('show.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n if (actives && actives.length) {\n Plugin.call(actives, 'hide')\n activesData || actives.data('bs.collapse', null)\n }\n\n var dimension = this.dimension()\n\n this.$element\n .removeClass('collapse')\n .addClass('collapsing')[dimension](0)\n .attr('aria-expanded', true)\n\n this.$trigger\n .removeClass('collapsed')\n .attr('aria-expanded', true)\n\n this.transitioning = 1\n\n var complete = function () {\n this.$element\n .removeClass('collapsing')\n .addClass('collapse in')[dimension]('')\n this.transitioning = 0\n this.$element\n .trigger('shown.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n this.$element\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n }\n\n Collapse.prototype.hide = function () {\n if (this.transitioning || !this.$element.hasClass('in')) return\n\n var startEvent = $.Event('hide.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n var dimension = this.dimension()\n\n this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n this.$element\n .addClass('collapsing')\n .removeClass('collapse in')\n .attr('aria-expanded', false)\n\n this.$trigger\n .addClass('collapsed')\n .attr('aria-expanded', false)\n\n this.transitioning = 1\n\n var complete = function () {\n this.transitioning = 0\n this.$element\n .removeClass('collapsing')\n .addClass('collapse')\n .trigger('hidden.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n this.$element\n [dimension](0)\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n }\n\n Collapse.prototype.toggle = function () {\n this[this.$element.hasClass('in') ? 'hide' : 'show']()\n }\n\n Collapse.prototype.getParent = function () {\n return $(this.options.parent)\n .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n .each($.proxy(function (i, element) {\n var $element = $(element)\n this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n }, this))\n .end()\n }\n\n Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n var isOpen = $element.hasClass('in')\n\n $element.attr('aria-expanded', isOpen)\n $trigger\n .toggleClass('collapsed', !isOpen)\n .attr('aria-expanded', isOpen)\n }\n\n function getTargetFromTrigger($trigger) {\n var href\n var target = $trigger.attr('data-target')\n || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n return $(target)\n }\n\n\n // COLLAPSE PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.collapse')\n var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.collapse\n\n $.fn.collapse = Plugin\n $.fn.collapse.Constructor = Collapse\n\n\n // COLLAPSE NO CONFLICT\n // ====================\n\n $.fn.collapse.noConflict = function () {\n $.fn.collapse = old\n return this\n }\n\n\n // COLLAPSE DATA-API\n // =================\n\n $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n var $this = $(this)\n\n if (!$this.attr('data-target')) e.preventDefault()\n\n var $target = getTargetFromTrigger($this)\n var data = $target.data('bs.collapse')\n var option = data ? 'toggle' : $this.data()\n\n Plugin.call($target, option)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.4\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // DROPDOWN CLASS DEFINITION\n // =========================\n\n var backdrop = '.dropdown-backdrop'\n var toggle = '[data-toggle=\"dropdown\"]'\n var Dropdown = function (element) {\n $(element).on('click.bs.dropdown', this.toggle)\n }\n\n Dropdown.VERSION = '3.3.4'\n\n Dropdown.prototype.toggle = function (e) {\n var $this = $(this)\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n clearMenus()\n\n if (!isActive) {\n if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n // if mobile we use a backdrop because click events don't delegate\n $('
').insertAfter($(this)).on('click', clearMenus)\n }\n\n var relatedTarget = { relatedTarget: this }\n $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this\n .trigger('focus')\n .attr('aria-expanded', 'true')\n\n $parent\n .toggleClass('open')\n .trigger('shown.bs.dropdown', relatedTarget)\n }\n\n return false\n }\n\n Dropdown.prototype.keydown = function (e) {\n if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n var $this = $(this)\n\n e.preventDefault()\n e.stopPropagation()\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {\n if (e.which == 27) $parent.find(toggle).trigger('focus')\n return $this.trigger('click')\n }\n\n var desc = ' li:not(.disabled):visible a'\n var $items = $parent.find('[role=\"menu\"]' + desc + ', [role=\"listbox\"]' + desc)\n\n if (!$items.length) return\n\n var index = $items.index(e.target)\n\n if (e.which == 38 && index > 0) index-- // up\n if (e.which == 40 && index < $items.length - 1) index++ // down\n if (!~index) index = 0\n\n $items.eq(index).trigger('focus')\n }\n\n function clearMenus(e) {\n if (e && e.which === 3) return\n $(backdrop).remove()\n $(toggle).each(function () {\n var $this = $(this)\n var $parent = getParent($this)\n var relatedTarget = { relatedTarget: this }\n\n if (!$parent.hasClass('open')) return\n\n $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this.attr('aria-expanded', 'false')\n $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)\n })\n }\n\n function getParent($this) {\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = selector && $(selector)\n\n return $parent && $parent.length ? $parent : $this.parent()\n }\n\n\n // DROPDOWN PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.dropdown')\n\n if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.dropdown\n\n $.fn.dropdown = Plugin\n $.fn.dropdown.Constructor = Dropdown\n\n\n // DROPDOWN NO CONFLICT\n // ====================\n\n $.fn.dropdown.noConflict = function () {\n $.fn.dropdown = old\n return this\n }\n\n\n // APPLY TO STANDARD DROPDOWN ELEMENTS\n // ===================================\n\n $(document)\n .on('click.bs.dropdown.data-api', clearMenus)\n .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '[role=\"menu\"]', Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '[role=\"listbox\"]', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.4\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // MODAL CLASS DEFINITION\n // ======================\n\n var Modal = function (element, options) {\n this.options = options\n this.$body = $(document.body)\n this.$element = $(element)\n this.$dialog = this.$element.find('.modal-dialog')\n this.$backdrop = null\n this.isShown = null\n this.originalBodyPad = null\n this.scrollbarWidth = 0\n this.ignoreBackdropClick = false\n\n if (this.options.remote) {\n this.$element\n .find('.modal-content')\n .load(this.options.remote, $.proxy(function () {\n this.$element.trigger('loaded.bs.modal')\n }, this))\n }\n }\n\n Modal.VERSION = '3.3.4'\n\n Modal.TRANSITION_DURATION = 300\n Modal.BACKDROP_TRANSITION_DURATION = 150\n\n Modal.DEFAULTS = {\n backdrop: true,\n keyboard: true,\n show: true\n }\n\n Modal.prototype.toggle = function (_relatedTarget) {\n return this.isShown ? this.hide() : this.show(_relatedTarget)\n }\n\n Modal.prototype.show = function (_relatedTarget) {\n var that = this\n var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n this.$element.trigger(e)\n\n if (this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = true\n\n this.checkScrollbar()\n this.setScrollbar()\n this.$body.addClass('modal-open')\n\n this.escape()\n this.resize()\n\n this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n })\n })\n\n this.backdrop(function () {\n var transition = $.support.transition && that.$element.hasClass('fade')\n\n if (!that.$element.parent().length) {\n that.$element.appendTo(that.$body) // don't move modals dom position\n }\n\n that.$element\n .show()\n .scrollTop(0)\n\n that.adjustDialog()\n\n if (transition) {\n that.$element[0].offsetWidth // force reflow\n }\n\n that.$element\n .addClass('in')\n .attr('aria-hidden', false)\n\n that.enforceFocus()\n\n var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n transition ?\n that.$dialog // wait for modal to slide in\n .one('bsTransitionEnd', function () {\n that.$element.trigger('focus').trigger(e)\n })\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n that.$element.trigger('focus').trigger(e)\n })\n }\n\n Modal.prototype.hide = function (e) {\n if (e) e.preventDefault()\n\n e = $.Event('hide.bs.modal')\n\n this.$element.trigger(e)\n\n if (!this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = false\n\n this.escape()\n this.resize()\n\n $(document).off('focusin.bs.modal')\n\n this.$element\n .removeClass('in')\n .attr('aria-hidden', true)\n .off('click.dismiss.bs.modal')\n .off('mouseup.dismiss.bs.modal')\n\n this.$dialog.off('mousedown.dismiss.bs.modal')\n\n $.support.transition && this.$element.hasClass('fade') ?\n this.$element\n .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n this.hideModal()\n }\n\n Modal.prototype.enforceFocus = function () {\n $(document)\n .off('focusin.bs.modal') // guard against infinite focus loop\n .on('focusin.bs.modal', $.proxy(function (e) {\n if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n this.$element.trigger('focus')\n }\n }, this))\n }\n\n Modal.prototype.escape = function () {\n if (this.isShown && this.options.keyboard) {\n this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n e.which == 27 && this.hide()\n }, this))\n } else if (!this.isShown) {\n this.$element.off('keydown.dismiss.bs.modal')\n }\n }\n\n Modal.prototype.resize = function () {\n if (this.isShown) {\n $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n } else {\n $(window).off('resize.bs.modal')\n }\n }\n\n Modal.prototype.hideModal = function () {\n var that = this\n this.$element.hide()\n this.backdrop(function () {\n that.$body.removeClass('modal-open')\n that.resetAdjustments()\n that.resetScrollbar()\n that.$element.trigger('hidden.bs.modal')\n })\n }\n\n Modal.prototype.removeBackdrop = function () {\n this.$backdrop && this.$backdrop.remove()\n this.$backdrop = null\n }\n\n Modal.prototype.backdrop = function (callback) {\n var that = this\n var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n if (this.isShown && this.options.backdrop) {\n var doAnimate = $.support.transition && animate\n\n this.$backdrop = $('
')\n .appendTo(this.$body)\n\n this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n if (this.ignoreBackdropClick) {\n this.ignoreBackdropClick = false\n return\n }\n if (e.target !== e.currentTarget) return\n this.options.backdrop == 'static'\n ? this.$element[0].focus()\n : this.hide()\n }, this))\n\n if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n this.$backdrop.addClass('in')\n\n if (!callback) return\n\n doAnimate ?\n this.$backdrop\n .one('bsTransitionEnd', callback)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callback()\n\n } else if (!this.isShown && this.$backdrop) {\n this.$backdrop.removeClass('in')\n\n var callbackRemove = function () {\n that.removeBackdrop()\n callback && callback()\n }\n $.support.transition && this.$element.hasClass('fade') ?\n this.$backdrop\n .one('bsTransitionEnd', callbackRemove)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callbackRemove()\n\n } else if (callback) {\n callback()\n }\n }\n\n // these following methods are used to handle overflowing modals\n\n Modal.prototype.handleUpdate = function () {\n this.adjustDialog()\n }\n\n Modal.prototype.adjustDialog = function () {\n var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n this.$element.css({\n paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n })\n }\n\n Modal.prototype.resetAdjustments = function () {\n this.$element.css({\n paddingLeft: '',\n paddingRight: ''\n })\n }\n\n Modal.prototype.checkScrollbar = function () {\n var fullWindowWidth = window.innerWidth\n if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n var documentElementRect = document.documentElement.getBoundingClientRect()\n fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n }\n this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n this.scrollbarWidth = this.measureScrollbar()\n }\n\n Modal.prototype.setScrollbar = function () {\n var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n this.originalBodyPad = document.body.style.paddingRight || ''\n if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n }\n\n Modal.prototype.resetScrollbar = function () {\n this.$body.css('padding-right', this.originalBodyPad)\n }\n\n Modal.prototype.measureScrollbar = function () { // thx walsh\n var scrollDiv = document.createElement('div')\n scrollDiv.className = 'modal-scrollbar-measure'\n this.$body.append(scrollDiv)\n var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n this.$body[0].removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n\n // MODAL PLUGIN DEFINITION\n // =======================\n\n function Plugin(option, _relatedTarget) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.modal')\n var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n if (typeof option == 'string') data[option](_relatedTarget)\n else if (options.show) data.show(_relatedTarget)\n })\n }\n\n var old = $.fn.modal\n\n $.fn.modal = Plugin\n $.fn.modal.Constructor = Modal\n\n\n // MODAL NO CONFLICT\n // =================\n\n $.fn.modal.noConflict = function () {\n $.fn.modal = old\n return this\n }\n\n\n // MODAL DATA-API\n // ==============\n\n $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n var $this = $(this)\n var href = $this.attr('href')\n var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n if ($this.is('a')) e.preventDefault()\n\n $target.one('show.bs.modal', function (showEvent) {\n if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n $target.one('hidden.bs.modal', function () {\n $this.is(':visible') && $this.trigger('focus')\n })\n })\n Plugin.call($target, option, this)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.4\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TOOLTIP PUBLIC CLASS DEFINITION\n // ===============================\n\n var Tooltip = function (element, options) {\n this.type = null\n this.options = null\n this.enabled = null\n this.timeout = null\n this.hoverState = null\n this.$element = null\n\n this.init('tooltip', element, options)\n }\n\n Tooltip.VERSION = '3.3.4'\n\n Tooltip.TRANSITION_DURATION = 150\n\n Tooltip.DEFAULTS = {\n animation: true,\n placement: 'top',\n selector: false,\n template: '
',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n container: false,\n viewport: {\n selector: 'body',\n padding: 0\n }\n }\n\n Tooltip.prototype.init = function (type, element, options) {\n this.enabled = true\n this.type = type\n this.$element = $(element)\n this.options = this.getOptions(options)\n this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)\n\n if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n }\n\n var triggers = this.options.trigger.split(' ')\n\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i]\n\n if (trigger == 'click') {\n this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n } else if (trigger != 'manual') {\n var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'\n var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n }\n }\n\n this.options.selector ?\n (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n this.fixTitle()\n }\n\n Tooltip.prototype.getDefaults = function () {\n return Tooltip.DEFAULTS\n }\n\n Tooltip.prototype.getOptions = function (options) {\n options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n if (options.delay && typeof options.delay == 'number') {\n options.delay = {\n show: options.delay,\n hide: options.delay\n }\n }\n\n return options\n }\n\n Tooltip.prototype.getDelegateOptions = function () {\n var options = {}\n var defaults = this.getDefaults()\n\n this._options && $.each(this._options, function (key, value) {\n if (defaults[key] != value) options[key] = value\n })\n\n return options\n }\n\n Tooltip.prototype.enter = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (self && self.$tip && self.$tip.is(':visible')) {\n self.hoverState = 'in'\n return\n }\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'in'\n\n if (!self.options.delay || !self.options.delay.show) return self.show()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'in') self.show()\n }, self.options.delay.show)\n }\n\n Tooltip.prototype.leave = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'out'\n\n if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'out') self.hide()\n }, self.options.delay.hide)\n }\n\n Tooltip.prototype.show = function () {\n var e = $.Event('show.bs.' + this.type)\n\n if (this.hasContent() && this.enabled) {\n this.$element.trigger(e)\n\n var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n if (e.isDefaultPrevented() || !inDom) return\n var that = this\n\n var $tip = this.tip()\n\n var tipId = this.getUID(this.type)\n\n this.setContent()\n $tip.attr('id', tipId)\n this.$element.attr('aria-describedby', tipId)\n\n if (this.options.animation) $tip.addClass('fade')\n\n var placement = typeof this.options.placement == 'function' ?\n this.options.placement.call(this, $tip[0], this.$element[0]) :\n this.options.placement\n\n var autoToken = /\\s?auto?\\s?/i\n var autoPlace = autoToken.test(placement)\n if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n $tip\n .detach()\n .css({ top: 0, left: 0, display: 'block' })\n .addClass(placement)\n .data('bs.' + this.type, this)\n\n this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n\n var pos = this.getPosition()\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (autoPlace) {\n var orgPlacement = placement\n var $container = this.options.container ? $(this.options.container) : this.$element.parent()\n var containerDim = this.getPosition($container)\n\n placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :\n placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :\n placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :\n placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :\n placement\n\n $tip\n .removeClass(orgPlacement)\n .addClass(placement)\n }\n\n var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n this.applyPlacement(calculatedOffset, placement)\n\n var complete = function () {\n var prevHoverState = that.hoverState\n that.$element.trigger('shown.bs.' + that.type)\n that.hoverState = null\n\n if (prevHoverState == 'out') that.leave(that)\n }\n\n $.support.transition && this.$tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n }\n }\n\n Tooltip.prototype.applyPlacement = function (offset, placement) {\n var $tip = this.tip()\n var width = $tip[0].offsetWidth\n var height = $tip[0].offsetHeight\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt($tip.css('margin-top'), 10)\n var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0\n if (isNaN(marginLeft)) marginLeft = 0\n\n offset.top = offset.top + marginTop\n offset.left = offset.left + marginLeft\n\n // $.fn.offset doesn't round pixel values\n // so we use setOffset directly with our own function B-0\n $.offset.setOffset($tip[0], $.extend({\n using: function (props) {\n $tip.css({\n top: Math.round(props.top),\n left: Math.round(props.left)\n })\n }\n }, offset), 0)\n\n $tip.addClass('in')\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (placement == 'top' && actualHeight != height) {\n offset.top = offset.top + height - actualHeight\n }\n\n var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n if (delta.left) offset.left += delta.left\n else offset.top += delta.top\n\n var isVertical = /top|bottom/.test(placement)\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n $tip.offset(offset)\n this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n }\n\n Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n this.arrow()\n .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isVertical ? 'top' : 'left', '')\n }\n\n Tooltip.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n\n $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n $tip.removeClass('fade in top bottom left right')\n }\n\n Tooltip.prototype.hide = function (callback) {\n var that = this\n var $tip = $(this.$tip)\n var e = $.Event('hide.bs.' + this.type)\n\n function complete() {\n if (that.hoverState != 'in') $tip.detach()\n that.$element\n .removeAttr('aria-describedby')\n .trigger('hidden.bs.' + that.type)\n callback && callback()\n }\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n $tip.removeClass('in')\n\n $.support.transition && $tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n\n this.hoverState = null\n\n return this\n }\n\n Tooltip.prototype.fixTitle = function () {\n var $e = this.$element\n if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {\n $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n }\n }\n\n Tooltip.prototype.hasContent = function () {\n return this.getTitle()\n }\n\n Tooltip.prototype.getPosition = function ($element) {\n $element = $element || this.$element\n\n var el = $element[0]\n var isBody = el.tagName == 'BODY'\n\n var elRect = el.getBoundingClientRect()\n if (elRect.width == null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n }\n var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()\n var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n return $.extend({}, elRect, scroll, outerDims, elOffset)\n }\n\n Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n }\n\n Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 }\n if (!this.$viewport) return delta\n\n var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n var viewportDimensions = this.getPosition(this.$viewport)\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll\n var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n }\n } else {\n var leftEdgeOffset = pos.left - viewportPadding\n var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset\n } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n }\n }\n\n return delta\n }\n\n Tooltip.prototype.getTitle = function () {\n var title\n var $e = this.$element\n var o = this.options\n\n title = $e.attr('data-original-title')\n || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)\n\n return title\n }\n\n Tooltip.prototype.getUID = function (prefix) {\n do prefix += ~~(Math.random() * 1000000)\n while (document.getElementById(prefix))\n return prefix\n }\n\n Tooltip.prototype.tip = function () {\n return (this.$tip = this.$tip || $(this.options.template))\n }\n\n Tooltip.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n }\n\n Tooltip.prototype.enable = function () {\n this.enabled = true\n }\n\n Tooltip.prototype.disable = function () {\n this.enabled = false\n }\n\n Tooltip.prototype.toggleEnabled = function () {\n this.enabled = !this.enabled\n }\n\n Tooltip.prototype.toggle = function (e) {\n var self = this\n if (e) {\n self = $(e.currentTarget).data('bs.' + this.type)\n if (!self) {\n self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n $(e.currentTarget).data('bs.' + this.type, self)\n }\n }\n\n self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n }\n\n Tooltip.prototype.destroy = function () {\n var that = this\n clearTimeout(this.timeout)\n this.hide(function () {\n that.$element.off('.' + that.type).removeData('bs.' + that.type)\n })\n }\n\n\n // TOOLTIP PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tooltip')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tooltip\n\n $.fn.tooltip = Plugin\n $.fn.tooltip.Constructor = Tooltip\n\n\n // TOOLTIP NO CONFLICT\n // ===================\n\n $.fn.tooltip.noConflict = function () {\n $.fn.tooltip = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.4\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // POPOVER PUBLIC CLASS DEFINITION\n // ===============================\n\n var Popover = function (element, options) {\n this.init('popover', element, options)\n }\n\n if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n Popover.VERSION = '3.3.4'\n\n Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '

'\n })\n\n\n // NOTE: POPOVER EXTENDS tooltip.js\n // ================================\n\n Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n Popover.prototype.constructor = Popover\n\n Popover.prototype.getDefaults = function () {\n return Popover.DEFAULTS\n }\n\n Popover.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n var content = this.getContent()\n\n $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n ](content)\n\n $tip.removeClass('fade top bottom left right in')\n\n // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n // this manually by checking the contents.\n if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n }\n\n Popover.prototype.hasContent = function () {\n return this.getTitle() || this.getContent()\n }\n\n Popover.prototype.getContent = function () {\n var $e = this.$element\n var o = this.options\n\n return $e.attr('data-content')\n || (typeof o.content == 'function' ?\n o.content.call($e[0]) :\n o.content)\n }\n\n Popover.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n }\n\n\n // POPOVER PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.popover')\n var options = typeof option == 'object' && option\n\n if (!data && /destroy|hide/.test(option)) return\n if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.popover\n\n $.fn.popover = Plugin\n $.fn.popover.Constructor = Popover\n\n\n // POPOVER NO CONFLICT\n // ===================\n\n $.fn.popover.noConflict = function () {\n $.fn.popover = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.4\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // SCROLLSPY CLASS DEFINITION\n // ==========================\n\n function ScrollSpy(element, options) {\n this.$body = $(document.body)\n this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n this.options = $.extend({}, ScrollSpy.DEFAULTS, options)\n this.selector = (this.options.target || '') + ' .nav li > a'\n this.offsets = []\n this.targets = []\n this.activeTarget = null\n this.scrollHeight = 0\n\n this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n this.refresh()\n this.process()\n }\n\n ScrollSpy.VERSION = '3.3.4'\n\n ScrollSpy.DEFAULTS = {\n offset: 10\n }\n\n ScrollSpy.prototype.getScrollHeight = function () {\n return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n }\n\n ScrollSpy.prototype.refresh = function () {\n var that = this\n var offsetMethod = 'offset'\n var offsetBase = 0\n\n this.offsets = []\n this.targets = []\n this.scrollHeight = this.getScrollHeight()\n\n if (!$.isWindow(this.$scrollElement[0])) {\n offsetMethod = 'position'\n offsetBase = this.$scrollElement.scrollTop()\n }\n\n this.$body\n .find(this.selector)\n .map(function () {\n var $el = $(this)\n var href = $el.data('target') || $el.attr('href')\n var $href = /^#./.test(href) && $(href)\n\n return ($href\n && $href.length\n && $href.is(':visible')\n && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n })\n .sort(function (a, b) { return a[0] - b[0] })\n .each(function () {\n that.offsets.push(this[0])\n that.targets.push(this[1])\n })\n }\n\n ScrollSpy.prototype.process = function () {\n var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n var scrollHeight = this.getScrollHeight()\n var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()\n var offsets = this.offsets\n var targets = this.targets\n var activeTarget = this.activeTarget\n var i\n\n if (this.scrollHeight != scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n }\n\n if (activeTarget && scrollTop < offsets[0]) {\n this.activeTarget = null\n return this.clear()\n }\n\n for (i = offsets.length; i--;) {\n activeTarget != targets[i]\n && scrollTop >= offsets[i]\n && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n && this.activate(targets[i])\n }\n }\n\n ScrollSpy.prototype.activate = function (target) {\n this.activeTarget = target\n\n this.clear()\n\n var selector = this.selector +\n '[data-target=\"' + target + '\"],' +\n this.selector + '[href=\"' + target + '\"]'\n\n var active = $(selector)\n .parents('li')\n .addClass('active')\n\n if (active.parent('.dropdown-menu').length) {\n active = active\n .closest('li.dropdown')\n .addClass('active')\n }\n\n active.trigger('activate.bs.scrollspy')\n }\n\n ScrollSpy.prototype.clear = function () {\n $(this.selector)\n .parentsUntil(this.options.target, '.active')\n .removeClass('active')\n }\n\n\n // SCROLLSPY PLUGIN DEFINITION\n // ===========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.scrollspy')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.scrollspy\n\n $.fn.scrollspy = Plugin\n $.fn.scrollspy.Constructor = ScrollSpy\n\n\n // SCROLLSPY NO CONFLICT\n // =====================\n\n $.fn.scrollspy.noConflict = function () {\n $.fn.scrollspy = old\n return this\n }\n\n\n // SCROLLSPY DATA-API\n // ==================\n\n $(window).on('load.bs.scrollspy.data-api', function () {\n $('[data-spy=\"scroll\"]').each(function () {\n var $spy = $(this)\n Plugin.call($spy, $spy.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.4\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TAB CLASS DEFINITION\n // ====================\n\n var Tab = function (element) {\n this.element = $(element)\n }\n\n Tab.VERSION = '3.3.4'\n\n Tab.TRANSITION_DURATION = 150\n\n Tab.prototype.show = function () {\n var $this = this.element\n var $ul = $this.closest('ul:not(.dropdown-menu)')\n var selector = $this.data('target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n if ($this.parent('li').hasClass('active')) return\n\n var $previous = $ul.find('.active:last a')\n var hideEvent = $.Event('hide.bs.tab', {\n relatedTarget: $this[0]\n })\n var showEvent = $.Event('show.bs.tab', {\n relatedTarget: $previous[0]\n })\n\n $previous.trigger(hideEvent)\n $this.trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n var $target = $(selector)\n\n this.activate($this.closest('li'), $ul)\n this.activate($target, $target.parent(), function () {\n $previous.trigger({\n type: 'hidden.bs.tab',\n relatedTarget: $this[0]\n })\n $this.trigger({\n type: 'shown.bs.tab',\n relatedTarget: $previous[0]\n })\n })\n }\n\n Tab.prototype.activate = function (element, container, callback) {\n var $active = container.find('> .active')\n var transition = callback\n && $.support.transition\n && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)\n\n function next() {\n $active\n .removeClass('active')\n .find('> .dropdown-menu > .active')\n .removeClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', false)\n\n element\n .addClass('active')\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n\n if (transition) {\n element[0].offsetWidth // reflow for transition\n element.addClass('in')\n } else {\n element.removeClass('fade')\n }\n\n if (element.parent('.dropdown-menu').length) {\n element\n .closest('li.dropdown')\n .addClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n }\n\n callback && callback()\n }\n\n $active.length && transition ?\n $active\n .one('bsTransitionEnd', next)\n .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n next()\n\n $active.removeClass('in')\n }\n\n\n // TAB PLUGIN DEFINITION\n // =====================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tab')\n\n if (!data) $this.data('bs.tab', (data = new Tab(this)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tab\n\n $.fn.tab = Plugin\n $.fn.tab.Constructor = Tab\n\n\n // TAB NO CONFLICT\n // ===============\n\n $.fn.tab.noConflict = function () {\n $.fn.tab = old\n return this\n }\n\n\n // TAB DATA-API\n // ============\n\n var clickHandler = function (e) {\n e.preventDefault()\n Plugin.call($(this), 'show')\n }\n\n $(document)\n .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.4\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // AFFIX CLASS DEFINITION\n // ======================\n\n var Affix = function (element, options) {\n this.options = $.extend({}, Affix.DEFAULTS, options)\n\n this.$target = $(this.options.target)\n .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))\n\n this.$element = $(element)\n this.affixed = null\n this.unpin = null\n this.pinnedOffset = null\n\n this.checkPosition()\n }\n\n Affix.VERSION = '3.3.4'\n\n Affix.RESET = 'affix affix-top affix-bottom'\n\n Affix.DEFAULTS = {\n offset: 0,\n target: window\n }\n\n Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n var targetHeight = this.$target.height()\n\n if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n if (this.affixed == 'bottom') {\n if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n }\n\n var initializing = this.affixed == null\n var colliderTop = initializing ? scrollTop : position.top\n var colliderHeight = initializing ? targetHeight : height\n\n if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n return false\n }\n\n Affix.prototype.getPinnedOffset = function () {\n if (this.pinnedOffset) return this.pinnedOffset\n this.$element.removeClass(Affix.RESET).addClass('affix')\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n return (this.pinnedOffset = position.top - scrollTop)\n }\n\n Affix.prototype.checkPositionWithEventLoop = function () {\n setTimeout($.proxy(this.checkPosition, this), 1)\n }\n\n Affix.prototype.checkPosition = function () {\n if (!this.$element.is(':visible')) return\n\n var height = this.$element.height()\n var offset = this.options.offset\n var offsetTop = offset.top\n var offsetBottom = offset.bottom\n var scrollHeight = $(document.body).height()\n\n if (typeof offset != 'object') offsetBottom = offsetTop = offset\n if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)\n if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n if (this.affixed != affix) {\n if (this.unpin != null) this.$element.css('top', '')\n\n var affixType = 'affix' + (affix ? '-' + affix : '')\n var e = $.Event(affixType + '.bs.affix')\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n this.affixed = affix\n this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n this.$element\n .removeClass(Affix.RESET)\n .addClass(affixType)\n .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n }\n\n if (affix == 'bottom') {\n this.$element.offset({\n top: scrollHeight - height - offsetBottom\n })\n }\n }\n\n\n // AFFIX PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.affix')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.affix\n\n $.fn.affix = Plugin\n $.fn.affix.Constructor = Affix\n\n\n // AFFIX NO CONFLICT\n // =================\n\n $.fn.affix.noConflict = function () {\n $.fn.affix = old\n return this\n }\n\n\n // AFFIX DATA-API\n // ==============\n\n $(window).on('load', function () {\n $('[data-spy=\"affix\"]').each(function () {\n var $spy = $(this)\n var data = $spy.data()\n\n data.offset = data.offset || {}\n\n if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n if (data.offsetTop != null) data.offset.top = data.offsetTop\n\n Plugin.call($spy, data)\n })\n })\n\n}(jQuery);\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2Jvb3RzdHJhcC1sZXNzL2pzL2Jvb3RzdHJhcC5qcz8wMGQyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qICovIFxuXCJmb3JtYXQgZ2xvYmFsXCI7XG5cImRlcHMganF1ZXJ5XCI7XG5cImV4cG9ydHMgJFwiO1xuLyohXG4gKiBCb290c3RyYXAgdjMuMy40IChodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbSlcbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqL1xuXG5pZiAodHlwZW9mIGpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdCb290c3RyYXBcXCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5Jylcbn1cblxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcbiAgdmFyIHZlcnNpb24gPSAkLmZuLmpxdWVyeS5zcGxpdCgnICcpWzBdLnNwbGl0KCcuJylcbiAgaWYgKCh2ZXJzaW9uWzBdIDwgMiAmJiB2ZXJzaW9uWzFdIDwgOSkgfHwgKHZlcnNpb25bMF0gPT0gMSAmJiB2ZXJzaW9uWzFdID09IDkgJiYgdmVyc2lvblsyXSA8IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCb290c3RyYXBcXCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5IHZlcnNpb24gMS45LjEgb3IgaGlnaGVyJylcbiAgfVxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogdHJhbnNpdGlvbi5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3RyYW5zaXRpb25zXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gQ1NTIFRSQU5TSVRJT04gU1VQUE9SVCAoU2hvdXRvdXQ6IGh0dHA6Ly93d3cubW9kZXJuaXpyLmNvbS8pXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoKSB7XG4gICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYm9vdHN0cmFwJylcblxuICAgIHZhciB0cmFuc0VuZEV2ZW50TmFtZXMgPSB7XG4gICAgICBXZWJraXRUcmFuc2l0aW9uIDogJ3dlYmtpdFRyYW5zaXRpb25FbmQnLFxuICAgICAgTW96VHJhbnNpdGlvbiAgICA6ICd0cmFuc2l0aW9uZW5kJyxcbiAgICAgIE9UcmFuc2l0aW9uICAgICAgOiAnb1RyYW5zaXRpb25FbmQgb3RyYW5zaXRpb25lbmQnLFxuICAgICAgdHJhbnNpdGlvbiAgICAgICA6ICd0cmFuc2l0aW9uZW5kJ1xuICAgIH1cblxuICAgIGZvciAodmFyIG5hbWUgaW4gdHJhbnNFbmRFdmVudE5hbWVzKSB7XG4gICAgICBpZiAoZWwuc3R5bGVbbmFtZV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4geyBlbmQ6IHRyYW5zRW5kRXZlbnROYW1lc1tuYW1lXSB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlIC8vIGV4cGxpY2l0IGZvciBpZTggKCAgLl8uKVxuICB9XG5cbiAgLy8gaHR0cDovL2Jsb2cuYWxleG1hY2Nhdy5jb20vY3NzLXRyYW5zaXRpb25zXG4gICQuZm4uZW11bGF0ZVRyYW5zaXRpb25FbmQgPSBmdW5jdGlvbiAoZHVyYXRpb24pIHtcbiAgICB2YXIgY2FsbGVkID0gZmFsc2VcbiAgICB2YXIgJGVsID0gdGhpc1xuICAgICQodGhpcykub25lKCdic1RyYW5zaXRpb25FbmQnLCBmdW5jdGlvbiAoKSB7IGNhbGxlZCA9IHRydWUgfSlcbiAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7IGlmICghY2FsbGVkKSAkKCRlbCkudHJpZ2dlcigkLnN1cHBvcnQudHJhbnNpdGlvbi5lbmQpIH1cbiAgICBzZXRUaW1lb3V0KGNhbGxiYWNrLCBkdXJhdGlvbilcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgJChmdW5jdGlvbiAoKSB7XG4gICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gPSB0cmFuc2l0aW9uRW5kKClcblxuICAgIGlmICghJC5zdXBwb3J0LnRyYW5zaXRpb24pIHJldHVyblxuXG4gICAgJC5ldmVudC5zcGVjaWFsLmJzVHJhbnNpdGlvbkVuZCA9IHtcbiAgICAgIGJpbmRUeXBlOiAkLnN1cHBvcnQudHJhbnNpdGlvbi5lbmQsXG4gICAgICBkZWxlZ2F0ZVR5cGU6ICQuc3VwcG9ydC50cmFuc2l0aW9uLmVuZCxcbiAgICAgIGhhbmRsZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKCQoZS50YXJnZXQpLmlzKHRoaXMpKSByZXR1cm4gZS5oYW5kbGVPYmouaGFuZGxlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG59KGpRdWVyeSk7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQm9vdHN0cmFwOiBhbGVydC5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI2FsZXJ0c1xuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIEFMRVJUIENMQVNTIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBkaXNtaXNzID0gJ1tkYXRhLWRpc21pc3M9XCJhbGVydFwiXSdcbiAgdmFyIEFsZXJ0ICAgPSBmdW5jdGlvbiAoZWwpIHtcbiAgICAkKGVsKS5vbignY2xpY2snLCBkaXNtaXNzLCB0aGlzLmNsb3NlKVxuICB9XG5cbiAgQWxlcnQuVkVSU0lPTiA9ICczLjMuNCdcblxuICBBbGVydC5UUkFOU0lUSU9OX0RVUkFUSU9OID0gMTUwXG5cbiAgQWxlcnQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgJHRoaXMgICAgPSAkKHRoaXMpXG4gICAgdmFyIHNlbGVjdG9yID0gJHRoaXMuYXR0cignZGF0YS10YXJnZXQnKVxuXG4gICAgaWYgKCFzZWxlY3Rvcikge1xuICAgICAgc2VsZWN0b3IgPSAkdGhpcy5hdHRyKCdocmVmJylcbiAgICAgIHNlbGVjdG9yID0gc2VsZWN0b3IgJiYgc2VsZWN0b3IucmVwbGFjZSgvLiooPz0jW15cXHNdKiQpLywgJycpIC8vIHN0cmlwIGZvciBpZTdcbiAgICB9XG5cbiAgICB2YXIgJHBhcmVudCA9ICQoc2VsZWN0b3IpXG5cbiAgICBpZiAoZSkgZS5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgICBpZiAoISRwYXJlbnQubGVuZ3RoKSB7XG4gICAgICAkcGFyZW50ID0gJHRoaXMuY2xvc2VzdCgnLmFsZXJ0JylcbiAgICB9XG5cbiAgICAkcGFyZW50LnRyaWdnZXIoZSA9ICQuRXZlbnQoJ2Nsb3NlLmJzLmFsZXJ0JykpXG5cbiAgICBpZiAoZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuXG5cbiAgICAkcGFyZW50LnJlbW92ZUNsYXNzKCdpbicpXG5cbiAgICBmdW5jdGlvbiByZW1vdmVFbGVtZW50KCkge1xuICAgICAgLy8gZGV0YWNoIGZyb20gcGFyZW50LCBmaXJlIGV2ZW50IHRoZW4gY2xlYW4gdXAgZGF0YVxuICAgICAgJHBhcmVudC5kZXRhY2goKS50cmlnZ2VyKCdjbG9zZWQuYnMuYWxlcnQnKS5yZW1vdmUoKVxuICAgIH1cblxuICAgICQuc3VwcG9ydC50cmFuc2l0aW9uICYmICRwYXJlbnQuaGFzQ2xhc3MoJ2ZhZGUnKSA/XG4gICAgICAkcGFyZW50XG4gICAgICAgIC5vbmUoJ2JzVHJhbnNpdGlvbkVuZCcsIHJlbW92ZUVsZW1lbnQpXG4gICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChBbGVydC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICByZW1vdmVFbGVtZW50KClcbiAgfVxuXG5cbiAgLy8gQUxFUlQgUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpXG4gICAgICB2YXIgZGF0YSAgPSAkdGhpcy5kYXRhKCdicy5hbGVydCcpXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuYWxlcnQnLCAoZGF0YSA9IG5ldyBBbGVydCh0aGlzKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dLmNhbGwoJHRoaXMpXG4gICAgfSlcbiAgfVxuXG4gIHZhciBvbGQgPSAkLmZuLmFsZXJ0XG5cbiAgJC5mbi5hbGVydCAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLmFsZXJ0LkNvbnN0cnVjdG9yID0gQWxlcnRcblxuXG4gIC8vIEFMRVJUIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09XG5cbiAgJC5mbi5hbGVydC5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4uYWxlcnQgPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBBTEVSVCBEQVRBLUFQSVxuICAvLyA9PT09PT09PT09PT09PVxuXG4gICQoZG9jdW1lbnQpLm9uKCdjbGljay5icy5hbGVydC5kYXRhLWFwaScsIGRpc21pc3MsIEFsZXJ0LnByb3RvdHlwZS5jbG9zZSlcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogYnV0dG9uLmpzIHYzLjMuNFxuICogaHR0cDovL2dldGJvb3RzdHJhcC5jb20vamF2YXNjcmlwdC8jYnV0dG9uc1xuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIEJVVFRPTiBQVUJMSUMgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICB2YXIgQnV0dG9uID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRlbGVtZW50ICA9ICQoZWxlbWVudClcbiAgICB0aGlzLm9wdGlvbnMgICA9ICQuZXh0ZW5kKHt9LCBCdXR0b24uREVGQVVMVFMsIG9wdGlvbnMpXG4gICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZVxuICB9XG5cbiAgQnV0dG9uLlZFUlNJT04gID0gJzMuMy40J1xuXG4gIEJ1dHRvbi5ERUZBVUxUUyA9IHtcbiAgICBsb2FkaW5nVGV4dDogJ2xvYWRpbmcuLi4nXG4gIH1cblxuICBCdXR0b24ucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgdmFyIGQgICAgPSAnZGlzYWJsZWQnXG4gICAgdmFyICRlbCAgPSB0aGlzLiRlbGVtZW50XG4gICAgdmFyIHZhbCAgPSAkZWwuaXMoJ2lucHV0JykgPyAndmFsJyA6ICdodG1sJ1xuICAgIHZhciBkYXRhID0gJGVsLmRhdGEoKVxuXG4gICAgc3RhdGUgPSBzdGF0ZSArICdUZXh0J1xuXG4gICAgaWYgKGRhdGEucmVzZXRUZXh0ID09IG51bGwpICRlbC5kYXRhKCdyZXNldFRleHQnLCAkZWxbdmFsXSgpKVxuXG4gICAgLy8gcHVzaCB0byBldmVudCBsb29wIHRvIGFsbG93IGZvcm1zIHRvIHN1Ym1pdFxuICAgIHNldFRpbWVvdXQoJC5wcm94eShmdW5jdGlvbiAoKSB7XG4gICAgICAkZWxbdmFsXShkYXRhW3N0YXRlXSA9PSBudWxsID8gdGhpcy5vcHRpb25zW3N0YXRlXSA6IGRhdGFbc3RhdGVdKVxuXG4gICAgICBpZiAoc3RhdGUgPT0gJ2xvYWRpbmdUZXh0Jykge1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWVcbiAgICAgICAgJGVsLmFkZENsYXNzKGQpLmF0dHIoZCwgZClcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0xvYWRpbmcpIHtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZVxuICAgICAgICAkZWwucmVtb3ZlQ2xhc3MoZCkucmVtb3ZlQXR0cihkKVxuICAgICAgfVxuICAgIH0sIHRoaXMpLCAwKVxuICB9XG5cbiAgQnV0dG9uLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNoYW5nZWQgPSB0cnVlXG4gICAgdmFyICRwYXJlbnQgPSB0aGlzLiRlbGVtZW50LmNsb3Nlc3QoJ1tkYXRhLXRvZ2dsZT1cImJ1dHRvbnNcIl0nKVxuXG4gICAgaWYgKCRwYXJlbnQubGVuZ3RoKSB7XG4gICAgICB2YXIgJGlucHV0ID0gdGhpcy4kZWxlbWVudC5maW5kKCdpbnB1dCcpXG4gICAgICBpZiAoJGlucHV0LnByb3AoJ3R5cGUnKSA9PSAncmFkaW8nKSB7XG4gICAgICAgIGlmICgkaW5wdXQucHJvcCgnY2hlY2tlZCcpICYmIHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3MoJ2FjdGl2ZScpKSBjaGFuZ2VkID0gZmFsc2VcbiAgICAgICAgZWxzZSAkcGFyZW50LmZpbmQoJy5hY3RpdmUnKS5yZW1vdmVDbGFzcygnYWN0aXZlJylcbiAgICAgIH1cbiAgICAgIGlmIChjaGFuZ2VkKSAkaW5wdXQucHJvcCgnY2hlY2tlZCcsICF0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdhY3RpdmUnKSkudHJpZ2dlcignY2hhbmdlJylcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy4kZWxlbWVudC5hdHRyKCdhcmlhLXByZXNzZWQnLCAhdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnYWN0aXZlJykpXG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZWQpIHRoaXMuJGVsZW1lbnQudG9nZ2xlQ2xhc3MoJ2FjdGl2ZScpXG4gIH1cblxuXG4gIC8vIEJVVFRPTiBQTFVHSU4gREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICAgID0gJHRoaXMuZGF0YSgnYnMuYnV0dG9uJylcbiAgICAgIHZhciBvcHRpb25zID0gdHlwZW9mIG9wdGlvbiA9PSAnb2JqZWN0JyAmJiBvcHRpb25cblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5idXR0b24nLCAoZGF0YSA9IG5ldyBCdXR0b24odGhpcywgb3B0aW9ucykpKVxuXG4gICAgICBpZiAob3B0aW9uID09ICd0b2dnbGUnKSBkYXRhLnRvZ2dsZSgpXG4gICAgICBlbHNlIGlmIChvcHRpb24pIGRhdGEuc2V0U3RhdGUob3B0aW9uKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi5idXR0b25cblxuICAkLmZuLmJ1dHRvbiAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLmJ1dHRvbi5Db25zdHJ1Y3RvciA9IEJ1dHRvblxuXG5cbiAgLy8gQlVUVE9OIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4uYnV0dG9uLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi5idXR0b24gPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBCVVRUT04gREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09PT09XG5cbiAgJChkb2N1bWVudClcbiAgICAub24oJ2NsaWNrLmJzLmJ1dHRvbi5kYXRhLWFwaScsICdbZGF0YS10b2dnbGVePVwiYnV0dG9uXCJdJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIHZhciAkYnRuID0gJChlLnRhcmdldClcbiAgICAgIGlmICghJGJ0bi5oYXNDbGFzcygnYnRuJykpICRidG4gPSAkYnRuLmNsb3Nlc3QoJy5idG4nKVxuICAgICAgUGx1Z2luLmNhbGwoJGJ0biwgJ3RvZ2dsZScpXG4gICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICB9KVxuICAgIC5vbignZm9jdXMuYnMuYnV0dG9uLmRhdGEtYXBpIGJsdXIuYnMuYnV0dG9uLmRhdGEtYXBpJywgJ1tkYXRhLXRvZ2dsZV49XCJidXR0b25cIl0nLCBmdW5jdGlvbiAoZSkge1xuICAgICAgJChlLnRhcmdldCkuY2xvc2VzdCgnLmJ0bicpLnRvZ2dsZUNsYXNzKCdmb2N1cycsIC9eZm9jdXMoaW4pPyQvLnRlc3QoZS50eXBlKSlcbiAgICB9KVxuXG59KGpRdWVyeSk7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQm9vdHN0cmFwOiBjYXJvdXNlbC5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI2Nhcm91c2VsXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gQ0FST1VTRUwgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIENhcm91c2VsID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRlbGVtZW50ICAgID0gJChlbGVtZW50KVxuICAgIHRoaXMuJGluZGljYXRvcnMgPSB0aGlzLiRlbGVtZW50LmZpbmQoJy5jYXJvdXNlbC1pbmRpY2F0b3JzJylcbiAgICB0aGlzLm9wdGlvbnMgICAgID0gb3B0aW9uc1xuICAgIHRoaXMucGF1c2VkICAgICAgPSBudWxsXG4gICAgdGhpcy5zbGlkaW5nICAgICA9IG51bGxcbiAgICB0aGlzLmludGVydmFsICAgID0gbnVsbFxuICAgIHRoaXMuJGFjdGl2ZSAgICAgPSBudWxsXG4gICAgdGhpcy4kaXRlbXMgICAgICA9IG51bGxcblxuICAgIHRoaXMub3B0aW9ucy5rZXlib2FyZCAmJiB0aGlzLiRlbGVtZW50Lm9uKCdrZXlkb3duLmJzLmNhcm91c2VsJywgJC5wcm94eSh0aGlzLmtleWRvd24sIHRoaXMpKVxuXG4gICAgdGhpcy5vcHRpb25zLnBhdXNlID09ICdob3ZlcicgJiYgISgnb250b3VjaHN0YXJ0JyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpICYmIHRoaXMuJGVsZW1lbnRcbiAgICAgIC5vbignbW91c2VlbnRlci5icy5jYXJvdXNlbCcsICQucHJveHkodGhpcy5wYXVzZSwgdGhpcykpXG4gICAgICAub24oJ21vdXNlbGVhdmUuYnMuY2Fyb3VzZWwnLCAkLnByb3h5KHRoaXMuY3ljbGUsIHRoaXMpKVxuICB9XG5cbiAgQ2Fyb3VzZWwuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgQ2Fyb3VzZWwuVFJBTlNJVElPTl9EVVJBVElPTiA9IDYwMFxuXG4gIENhcm91c2VsLkRFRkFVTFRTID0ge1xuICAgIGludGVydmFsOiA1MDAwLFxuICAgIHBhdXNlOiAnaG92ZXInLFxuICAgIHdyYXA6IHRydWUsXG4gICAga2V5Ym9hcmQ6IHRydWVcbiAgfVxuXG4gIENhcm91c2VsLnByb3RvdHlwZS5rZXlkb3duID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoL2lucHV0fHRleHRhcmVhL2kudGVzdChlLnRhcmdldC50YWdOYW1lKSkgcmV0dXJuXG4gICAgc3dpdGNoIChlLndoaWNoKSB7XG4gICAgICBjYXNlIDM3OiB0aGlzLnByZXYoKTsgYnJlYWtcbiAgICAgIGNhc2UgMzk6IHRoaXMubmV4dCgpOyBicmVha1xuICAgICAgZGVmYXVsdDogcmV0dXJuXG4gICAgfVxuXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gIH1cblxuICBDYXJvdXNlbC5wcm90b3R5cGUuY3ljbGUgPSBmdW5jdGlvbiAoZSkge1xuICAgIGUgfHwgKHRoaXMucGF1c2VkID0gZmFsc2UpXG5cbiAgICB0aGlzLmludGVydmFsICYmIGNsZWFySW50ZXJ2YWwodGhpcy5pbnRlcnZhbClcblxuICAgIHRoaXMub3B0aW9ucy5pbnRlcnZhbFxuICAgICAgJiYgIXRoaXMucGF1c2VkXG4gICAgICAmJiAodGhpcy5pbnRlcnZhbCA9IHNldEludGVydmFsKCQucHJveHkodGhpcy5uZXh0LCB0aGlzKSwgdGhpcy5vcHRpb25zLmludGVydmFsKSlcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBDYXJvdXNlbC5wcm90b3R5cGUuZ2V0SXRlbUluZGV4ID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICB0aGlzLiRpdGVtcyA9IGl0ZW0ucGFyZW50KCkuY2hpbGRyZW4oJy5pdGVtJylcbiAgICByZXR1cm4gdGhpcy4kaXRlbXMuaW5kZXgoaXRlbSB8fCB0aGlzLiRhY3RpdmUpXG4gIH1cblxuICBDYXJvdXNlbC5wcm90b3R5cGUuZ2V0SXRlbUZvckRpcmVjdGlvbiA9IGZ1bmN0aW9uIChkaXJlY3Rpb24sIGFjdGl2ZSkge1xuICAgIHZhciBhY3RpdmVJbmRleCA9IHRoaXMuZ2V0SXRlbUluZGV4KGFjdGl2ZSlcbiAgICB2YXIgd2lsbFdyYXAgPSAoZGlyZWN0aW9uID09ICdwcmV2JyAmJiBhY3RpdmVJbmRleCA9PT0gMClcbiAgICAgICAgICAgICAgICB8fCAoZGlyZWN0aW9uID09ICduZXh0JyAmJiBhY3RpdmVJbmRleCA9PSAodGhpcy4kaXRlbXMubGVuZ3RoIC0gMSkpXG4gICAgaWYgKHdpbGxXcmFwICYmICF0aGlzLm9wdGlvbnMud3JhcCkgcmV0dXJuIGFjdGl2ZVxuICAgIHZhciBkZWx0YSA9IGRpcmVjdGlvbiA9PSAncHJldicgPyAtMSA6IDFcbiAgICB2YXIgaXRlbUluZGV4ID0gKGFjdGl2ZUluZGV4ICsgZGVsdGEpICUgdGhpcy4kaXRlbXMubGVuZ3RoXG4gICAgcmV0dXJuIHRoaXMuJGl0ZW1zLmVxKGl0ZW1JbmRleClcbiAgfVxuXG4gIENhcm91c2VsLnByb3RvdHlwZS50byA9IGZ1bmN0aW9uIChwb3MpIHtcbiAgICB2YXIgdGhhdCAgICAgICAgPSB0aGlzXG4gICAgdmFyIGFjdGl2ZUluZGV4ID0gdGhpcy5nZXRJdGVtSW5kZXgodGhpcy4kYWN0aXZlID0gdGhpcy4kZWxlbWVudC5maW5kKCcuaXRlbS5hY3RpdmUnKSlcblxuICAgIGlmIChwb3MgPiAodGhpcy4kaXRlbXMubGVuZ3RoIC0gMSkgfHwgcG9zIDwgMCkgcmV0dXJuXG5cbiAgICBpZiAodGhpcy5zbGlkaW5nKSAgICAgICByZXR1cm4gdGhpcy4kZWxlbWVudC5vbmUoJ3NsaWQuYnMuY2Fyb3VzZWwnLCBmdW5jdGlvbiAoKSB7IHRoYXQudG8ocG9zKSB9KSAvLyB5ZXMsIFwic2xpZFwiXG4gICAgaWYgKGFjdGl2ZUluZGV4ID09IHBvcykgcmV0dXJuIHRoaXMucGF1c2UoKS5jeWNsZSgpXG5cbiAgICByZXR1cm4gdGhpcy5zbGlkZShwb3MgPiBhY3RpdmVJbmRleCA/ICduZXh0JyA6ICdwcmV2JywgdGhpcy4kaXRlbXMuZXEocG9zKSlcbiAgfVxuXG4gIENhcm91c2VsLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgZSB8fCAodGhpcy5wYXVzZWQgPSB0cnVlKVxuXG4gICAgaWYgKHRoaXMuJGVsZW1lbnQuZmluZCgnLm5leHQsIC5wcmV2JykubGVuZ3RoICYmICQuc3VwcG9ydC50cmFuc2l0aW9uKSB7XG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJC5zdXBwb3J0LnRyYW5zaXRpb24uZW5kKVxuICAgICAgdGhpcy5jeWNsZSh0cnVlKVxuICAgIH1cblxuICAgIHRoaXMuaW50ZXJ2YWwgPSBjbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWwpXG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgQ2Fyb3VzZWwucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuc2xpZGluZykgcmV0dXJuXG4gICAgcmV0dXJuIHRoaXMuc2xpZGUoJ25leHQnKVxuICB9XG5cbiAgQ2Fyb3VzZWwucHJvdG90eXBlLnByZXYgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuc2xpZGluZykgcmV0dXJuXG4gICAgcmV0dXJuIHRoaXMuc2xpZGUoJ3ByZXYnKVxuICB9XG5cbiAgQ2Fyb3VzZWwucHJvdG90eXBlLnNsaWRlID0gZnVuY3Rpb24gKHR5cGUsIG5leHQpIHtcbiAgICB2YXIgJGFjdGl2ZSAgID0gdGhpcy4kZWxlbWVudC5maW5kKCcuaXRlbS5hY3RpdmUnKVxuICAgIHZhciAkbmV4dCAgICAgPSBuZXh0IHx8IHRoaXMuZ2V0SXRlbUZvckRpcmVjdGlvbih0eXBlLCAkYWN0aXZlKVxuICAgIHZhciBpc0N5Y2xpbmcgPSB0aGlzLmludGVydmFsXG4gICAgdmFyIGRpcmVjdGlvbiA9IHR5cGUgPT0gJ25leHQnID8gJ2xlZnQnIDogJ3JpZ2h0J1xuICAgIHZhciB0aGF0ICAgICAgPSB0aGlzXG5cbiAgICBpZiAoJG5leHQuaGFzQ2xhc3MoJ2FjdGl2ZScpKSByZXR1cm4gKHRoaXMuc2xpZGluZyA9IGZhbHNlKVxuXG4gICAgdmFyIHJlbGF0ZWRUYXJnZXQgPSAkbmV4dFswXVxuICAgIHZhciBzbGlkZUV2ZW50ID0gJC5FdmVudCgnc2xpZGUuYnMuY2Fyb3VzZWwnLCB7XG4gICAgICByZWxhdGVkVGFyZ2V0OiByZWxhdGVkVGFyZ2V0LFxuICAgICAgZGlyZWN0aW9uOiBkaXJlY3Rpb25cbiAgICB9KVxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihzbGlkZUV2ZW50KVxuICAgIGlmIChzbGlkZUV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgIHRoaXMuc2xpZGluZyA9IHRydWVcblxuICAgIGlzQ3ljbGluZyAmJiB0aGlzLnBhdXNlKClcblxuICAgIGlmICh0aGlzLiRpbmRpY2F0b3JzLmxlbmd0aCkge1xuICAgICAgdGhpcy4kaW5kaWNhdG9ycy5maW5kKCcuYWN0aXZlJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICB2YXIgJG5leHRJbmRpY2F0b3IgPSAkKHRoaXMuJGluZGljYXRvcnMuY2hpbGRyZW4oKVt0aGlzLmdldEl0ZW1JbmRleCgkbmV4dCldKVxuICAgICAgJG5leHRJbmRpY2F0b3IgJiYgJG5leHRJbmRpY2F0b3IuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgfVxuXG4gICAgdmFyIHNsaWRFdmVudCA9ICQuRXZlbnQoJ3NsaWQuYnMuY2Fyb3VzZWwnLCB7IHJlbGF0ZWRUYXJnZXQ6IHJlbGF0ZWRUYXJnZXQsIGRpcmVjdGlvbjogZGlyZWN0aW9uIH0pIC8vIHllcywgXCJzbGlkXCJcbiAgICBpZiAoJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnc2xpZGUnKSkge1xuICAgICAgJG5leHQuYWRkQ2xhc3ModHlwZSlcbiAgICAgICRuZXh0WzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvd1xuICAgICAgJGFjdGl2ZS5hZGRDbGFzcyhkaXJlY3Rpb24pXG4gICAgICAkbmV4dC5hZGRDbGFzcyhkaXJlY3Rpb24pXG4gICAgICAkYWN0aXZlXG4gICAgICAgIC5vbmUoJ2JzVHJhbnNpdGlvbkVuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAkbmV4dC5yZW1vdmVDbGFzcyhbdHlwZSwgZGlyZWN0aW9uXS5qb2luKCcgJykpLmFkZENsYXNzKCdhY3RpdmUnKVxuICAgICAgICAgICRhY3RpdmUucmVtb3ZlQ2xhc3MoWydhY3RpdmUnLCBkaXJlY3Rpb25dLmpvaW4oJyAnKSlcbiAgICAgICAgICB0aGF0LnNsaWRpbmcgPSBmYWxzZVxuICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhhdC4kZWxlbWVudC50cmlnZ2VyKHNsaWRFdmVudClcbiAgICAgICAgICB9LCAwKVxuICAgICAgICB9KVxuICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoQ2Fyb3VzZWwuVFJBTlNJVElPTl9EVVJBVElPTilcbiAgICB9IGVsc2Uge1xuICAgICAgJGFjdGl2ZS5yZW1vdmVDbGFzcygnYWN0aXZlJylcbiAgICAgICRuZXh0LmFkZENsYXNzKCdhY3RpdmUnKVxuICAgICAgdGhpcy5zbGlkaW5nID0gZmFsc2VcbiAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihzbGlkRXZlbnQpXG4gICAgfVxuXG4gICAgaXNDeWNsaW5nICYmIHRoaXMuY3ljbGUoKVxuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gQ0FST1VTRUwgUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICAgID0gJHRoaXMuZGF0YSgnYnMuY2Fyb3VzZWwnKVxuICAgICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgQ2Fyb3VzZWwuREVGQVVMVFMsICR0aGlzLmRhdGEoKSwgdHlwZW9mIG9wdGlvbiA9PSAnb2JqZWN0JyAmJiBvcHRpb24pXG4gICAgICB2YXIgYWN0aW9uICA9IHR5cGVvZiBvcHRpb24gPT0gJ3N0cmluZycgPyBvcHRpb24gOiBvcHRpb25zLnNsaWRlXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuY2Fyb3VzZWwnLCAoZGF0YSA9IG5ldyBDYXJvdXNlbCh0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnbnVtYmVyJykgZGF0YS50byhvcHRpb24pXG4gICAgICBlbHNlIGlmIChhY3Rpb24pIGRhdGFbYWN0aW9uXSgpXG4gICAgICBlbHNlIGlmIChvcHRpb25zLmludGVydmFsKSBkYXRhLnBhdXNlKCkuY3ljbGUoKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi5jYXJvdXNlbFxuXG4gICQuZm4uY2Fyb3VzZWwgICAgICAgICAgICAgPSBQbHVnaW5cbiAgJC5mbi5jYXJvdXNlbC5Db25zdHJ1Y3RvciA9IENhcm91c2VsXG5cblxuICAvLyBDQVJPVVNFTCBOTyBDT05GTElDVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4uY2Fyb3VzZWwubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAkLmZuLmNhcm91c2VsID0gb2xkXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gQ0FST1VTRUwgREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICB2YXIgY2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgaHJlZlxuICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgIHZhciAkdGFyZ2V0ID0gJCgkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpIHx8IChocmVmID0gJHRoaXMuYXR0cignaHJlZicpKSAmJiBocmVmLnJlcGxhY2UoLy4qKD89I1teXFxzXSskKS8sICcnKSkgLy8gc3RyaXAgZm9yIGllN1xuICAgIGlmICghJHRhcmdldC5oYXNDbGFzcygnY2Fyb3VzZWwnKSkgcmV0dXJuXG4gICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgJHRhcmdldC5kYXRhKCksICR0aGlzLmRhdGEoKSlcbiAgICB2YXIgc2xpZGVJbmRleCA9ICR0aGlzLmF0dHIoJ2RhdGEtc2xpZGUtdG8nKVxuICAgIGlmIChzbGlkZUluZGV4KSBvcHRpb25zLmludGVydmFsID0gZmFsc2VcblxuICAgIFBsdWdpbi5jYWxsKCR0YXJnZXQsIG9wdGlvbnMpXG5cbiAgICBpZiAoc2xpZGVJbmRleCkge1xuICAgICAgJHRhcmdldC5kYXRhKCdicy5jYXJvdXNlbCcpLnRvKHNsaWRlSW5kZXgpXG4gICAgfVxuXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gIH1cblxuICAkKGRvY3VtZW50KVxuICAgIC5vbignY2xpY2suYnMuY2Fyb3VzZWwuZGF0YS1hcGknLCAnW2RhdGEtc2xpZGVdJywgY2xpY2tIYW5kbGVyKVxuICAgIC5vbignY2xpY2suYnMuY2Fyb3VzZWwuZGF0YS1hcGknLCAnW2RhdGEtc2xpZGUtdG9dJywgY2xpY2tIYW5kbGVyKVxuXG4gICQod2luZG93KS5vbignbG9hZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAkKCdbZGF0YS1yaWRlPVwiY2Fyb3VzZWxcIl0nKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkY2Fyb3VzZWwgPSAkKHRoaXMpXG4gICAgICBQbHVnaW4uY2FsbCgkY2Fyb3VzZWwsICRjYXJvdXNlbC5kYXRhKCkpXG4gICAgfSlcbiAgfSlcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogY29sbGFwc2UuanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyNjb2xsYXBzZVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIENPTExBUFNFIFBVQkxJQyBDTEFTUyBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIENvbGxhcHNlID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRlbGVtZW50ICAgICAgPSAkKGVsZW1lbnQpXG4gICAgdGhpcy5vcHRpb25zICAgICAgID0gJC5leHRlbmQoe30sIENvbGxhcHNlLkRFRkFVTFRTLCBvcHRpb25zKVxuICAgIHRoaXMuJHRyaWdnZXIgICAgICA9ICQoJ1tkYXRhLXRvZ2dsZT1cImNvbGxhcHNlXCJdW2hyZWY9XCIjJyArIGVsZW1lbnQuaWQgKyAnXCJdLCcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1tkYXRhLXRvZ2dsZT1cImNvbGxhcHNlXCJdW2RhdGEtdGFyZ2V0PVwiIycgKyBlbGVtZW50LmlkICsgJ1wiXScpXG4gICAgdGhpcy50cmFuc2l0aW9uaW5nID0gbnVsbFxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5wYXJlbnQpIHtcbiAgICAgIHRoaXMuJHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50KClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3ModGhpcy4kZWxlbWVudCwgdGhpcy4kdHJpZ2dlcilcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnRvZ2dsZSkgdGhpcy50b2dnbGUoKVxuICB9XG5cbiAgQ29sbGFwc2UuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgQ29sbGFwc2UuVFJBTlNJVElPTl9EVVJBVElPTiA9IDM1MFxuXG4gIENvbGxhcHNlLkRFRkFVTFRTID0ge1xuICAgIHRvZ2dsZTogdHJ1ZVxuICB9XG5cbiAgQ29sbGFwc2UucHJvdG90eXBlLmRpbWVuc2lvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFzV2lkdGggPSB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCd3aWR0aCcpXG4gICAgcmV0dXJuIGhhc1dpZHRoID8gJ3dpZHRoJyA6ICdoZWlnaHQnXG4gIH1cblxuICBDb2xsYXBzZS5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy50cmFuc2l0aW9uaW5nIHx8IHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3MoJ2luJykpIHJldHVyblxuXG4gICAgdmFyIGFjdGl2ZXNEYXRhXG4gICAgdmFyIGFjdGl2ZXMgPSB0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50LmNoaWxkcmVuKCcucGFuZWwnKS5jaGlsZHJlbignLmluLCAuY29sbGFwc2luZycpXG5cbiAgICBpZiAoYWN0aXZlcyAmJiBhY3RpdmVzLmxlbmd0aCkge1xuICAgICAgYWN0aXZlc0RhdGEgPSBhY3RpdmVzLmRhdGEoJ2JzLmNvbGxhcHNlJylcbiAgICAgIGlmIChhY3RpdmVzRGF0YSAmJiBhY3RpdmVzRGF0YS50cmFuc2l0aW9uaW5nKSByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgc3RhcnRFdmVudCA9ICQuRXZlbnQoJ3Nob3cuYnMuY29sbGFwc2UnKVxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihzdGFydEV2ZW50KVxuICAgIGlmIChzdGFydEV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgIGlmIChhY3RpdmVzICYmIGFjdGl2ZXMubGVuZ3RoKSB7XG4gICAgICBQbHVnaW4uY2FsbChhY3RpdmVzLCAnaGlkZScpXG4gICAgICBhY3RpdmVzRGF0YSB8fCBhY3RpdmVzLmRhdGEoJ2JzLmNvbGxhcHNlJywgbnVsbClcbiAgICB9XG5cbiAgICB2YXIgZGltZW5zaW9uID0gdGhpcy5kaW1lbnNpb24oKVxuXG4gICAgdGhpcy4kZWxlbWVudFxuICAgICAgLnJlbW92ZUNsYXNzKCdjb2xsYXBzZScpXG4gICAgICAuYWRkQ2xhc3MoJ2NvbGxhcHNpbmcnKVtkaW1lbnNpb25dKDApXG4gICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIHRydWUpXG5cbiAgICB0aGlzLiR0cmlnZ2VyXG4gICAgICAucmVtb3ZlQ2xhc3MoJ2NvbGxhcHNlZCcpXG4gICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIHRydWUpXG5cbiAgICB0aGlzLnRyYW5zaXRpb25pbmcgPSAxXG5cbiAgICB2YXIgY29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLiRlbGVtZW50XG4gICAgICAgIC5yZW1vdmVDbGFzcygnY29sbGFwc2luZycpXG4gICAgICAgIC5hZGRDbGFzcygnY29sbGFwc2UgaW4nKVtkaW1lbnNpb25dKCcnKVxuICAgICAgdGhpcy50cmFuc2l0aW9uaW5nID0gMFxuICAgICAgdGhpcy4kZWxlbWVudFxuICAgICAgICAudHJpZ2dlcignc2hvd24uYnMuY29sbGFwc2UnKVxuICAgIH1cblxuICAgIGlmICghJC5zdXBwb3J0LnRyYW5zaXRpb24pIHJldHVybiBjb21wbGV0ZS5jYWxsKHRoaXMpXG5cbiAgICB2YXIgc2Nyb2xsU2l6ZSA9ICQuY2FtZWxDYXNlKFsnc2Nyb2xsJywgZGltZW5zaW9uXS5qb2luKCctJykpXG5cbiAgICB0aGlzLiRlbGVtZW50XG4gICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCAkLnByb3h5KGNvbXBsZXRlLCB0aGlzKSlcbiAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChDb2xsYXBzZS5UUkFOU0lUSU9OX0RVUkFUSU9OKVtkaW1lbnNpb25dKHRoaXMuJGVsZW1lbnRbMF1bc2Nyb2xsU2l6ZV0pXG4gIH1cblxuICBDb2xsYXBzZS5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy50cmFuc2l0aW9uaW5nIHx8ICF0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdpbicpKSByZXR1cm5cblxuICAgIHZhciBzdGFydEV2ZW50ID0gJC5FdmVudCgnaGlkZS5icy5jb2xsYXBzZScpXG4gICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKHN0YXJ0RXZlbnQpXG4gICAgaWYgKHN0YXJ0RXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgdmFyIGRpbWVuc2lvbiA9IHRoaXMuZGltZW5zaW9uKClcblxuICAgIHRoaXMuJGVsZW1lbnRbZGltZW5zaW9uXSh0aGlzLiRlbGVtZW50W2RpbWVuc2lvbl0oKSlbMF0ub2Zmc2V0SGVpZ2h0XG5cbiAgICB0aGlzLiRlbGVtZW50XG4gICAgICAuYWRkQ2xhc3MoJ2NvbGxhcHNpbmcnKVxuICAgICAgLnJlbW92ZUNsYXNzKCdjb2xsYXBzZSBpbicpXG4gICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIGZhbHNlKVxuXG4gICAgdGhpcy4kdHJpZ2dlclxuICAgICAgLmFkZENsYXNzKCdjb2xsYXBzZWQnKVxuICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCBmYWxzZSlcblxuICAgIHRoaXMudHJhbnNpdGlvbmluZyA9IDFcblxuICAgIHZhciBjb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMudHJhbnNpdGlvbmluZyA9IDBcbiAgICAgIHRoaXMuJGVsZW1lbnRcbiAgICAgICAgLnJlbW92ZUNsYXNzKCdjb2xsYXBzaW5nJylcbiAgICAgICAgLmFkZENsYXNzKCdjb2xsYXBzZScpXG4gICAgICAgIC50cmlnZ2VyKCdoaWRkZW4uYnMuY29sbGFwc2UnKVxuICAgIH1cblxuICAgIGlmICghJC5zdXBwb3J0LnRyYW5zaXRpb24pIHJldHVybiBjb21wbGV0ZS5jYWxsKHRoaXMpXG5cbiAgICB0aGlzLiRlbGVtZW50XG4gICAgICBbZGltZW5zaW9uXSgwKVxuICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgJC5wcm94eShjb21wbGV0ZSwgdGhpcykpXG4gICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoQ29sbGFwc2UuVFJBTlNJVElPTl9EVVJBVElPTilcbiAgfVxuXG4gIENvbGxhcHNlLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpc1t0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdpbicpID8gJ2hpZGUnIDogJ3Nob3cnXSgpXG4gIH1cblxuICBDb2xsYXBzZS5wcm90b3R5cGUuZ2V0UGFyZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAkKHRoaXMub3B0aW9ucy5wYXJlbnQpXG4gICAgICAuZmluZCgnW2RhdGEtdG9nZ2xlPVwiY29sbGFwc2VcIl1bZGF0YS1wYXJlbnQ9XCInICsgdGhpcy5vcHRpb25zLnBhcmVudCArICdcIl0nKVxuICAgICAgLmVhY2goJC5wcm94eShmdW5jdGlvbiAoaSwgZWxlbWVudCkge1xuICAgICAgICB2YXIgJGVsZW1lbnQgPSAkKGVsZW1lbnQpXG4gICAgICAgIHRoaXMuYWRkQXJpYUFuZENvbGxhcHNlZENsYXNzKGdldFRhcmdldEZyb21UcmlnZ2VyKCRlbGVtZW50KSwgJGVsZW1lbnQpXG4gICAgICB9LCB0aGlzKSlcbiAgICAgIC5lbmQoKVxuICB9XG5cbiAgQ29sbGFwc2UucHJvdG90eXBlLmFkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyA9IGZ1bmN0aW9uICgkZWxlbWVudCwgJHRyaWdnZXIpIHtcbiAgICB2YXIgaXNPcGVuID0gJGVsZW1lbnQuaGFzQ2xhc3MoJ2luJylcblxuICAgICRlbGVtZW50LmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCBpc09wZW4pXG4gICAgJHRyaWdnZXJcbiAgICAgIC50b2dnbGVDbGFzcygnY29sbGFwc2VkJywgIWlzT3BlbilcbiAgICAgIC5hdHRyKCdhcmlhLWV4cGFuZGVkJywgaXNPcGVuKVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VGFyZ2V0RnJvbVRyaWdnZXIoJHRyaWdnZXIpIHtcbiAgICB2YXIgaHJlZlxuICAgIHZhciB0YXJnZXQgPSAkdHJpZ2dlci5hdHRyKCdkYXRhLXRhcmdldCcpXG4gICAgICB8fCAoaHJlZiA9ICR0cmlnZ2VyLmF0dHIoJ2hyZWYnKSkgJiYgaHJlZi5yZXBsYWNlKC8uKig/PSNbXlxcc10rJCkvLCAnJykgLy8gc3RyaXAgZm9yIGllN1xuXG4gICAgcmV0dXJuICQodGFyZ2V0KVxuICB9XG5cblxuICAvLyBDT0xMQVBTRSBQTFVHSU4gREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5jb2xsYXBzZScpXG4gICAgICB2YXIgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBDb2xsYXBzZS5ERUZBVUxUUywgJHRoaXMuZGF0YSgpLCB0eXBlb2Ygb3B0aW9uID09ICdvYmplY3QnICYmIG9wdGlvbilcblxuICAgICAgaWYgKCFkYXRhICYmIG9wdGlvbnMudG9nZ2xlICYmIC9zaG93fGhpZGUvLnRlc3Qob3B0aW9uKSkgb3B0aW9ucy50b2dnbGUgPSBmYWxzZVxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5jb2xsYXBzZScsIChkYXRhID0gbmV3IENvbGxhcHNlKHRoaXMsIG9wdGlvbnMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi5jb2xsYXBzZVxuXG4gICQuZm4uY29sbGFwc2UgICAgICAgICAgICAgPSBQbHVnaW5cbiAgJC5mbi5jb2xsYXBzZS5Db25zdHJ1Y3RvciA9IENvbGxhcHNlXG5cblxuICAvLyBDT0xMQVBTRSBOTyBDT05GTElDVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4uY29sbGFwc2Uubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAkLmZuLmNvbGxhcHNlID0gb2xkXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gQ09MTEFQU0UgREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICAkKGRvY3VtZW50KS5vbignY2xpY2suYnMuY29sbGFwc2UuZGF0YS1hcGknLCAnW2RhdGEtdG9nZ2xlPVwiY29sbGFwc2VcIl0nLCBmdW5jdGlvbiAoZSkge1xuICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuXG4gICAgaWYgKCEkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpKSBlLnByZXZlbnREZWZhdWx0KClcblxuICAgIHZhciAkdGFyZ2V0ID0gZ2V0VGFyZ2V0RnJvbVRyaWdnZXIoJHRoaXMpXG4gICAgdmFyIGRhdGEgICAgPSAkdGFyZ2V0LmRhdGEoJ2JzLmNvbGxhcHNlJylcbiAgICB2YXIgb3B0aW9uICA9IGRhdGEgPyAndG9nZ2xlJyA6ICR0aGlzLmRhdGEoKVxuXG4gICAgUGx1Z2luLmNhbGwoJHRhcmdldCwgb3B0aW9uKVxuICB9KVxuXG59KGpRdWVyeSk7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQm9vdHN0cmFwOiBkcm9wZG93bi5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI2Ryb3Bkb3duc1xuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIERST1BET1dOIENMQVNTIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBiYWNrZHJvcCA9ICcuZHJvcGRvd24tYmFja2Ryb3AnXG4gIHZhciB0b2dnbGUgICA9ICdbZGF0YS10b2dnbGU9XCJkcm9wZG93blwiXSdcbiAgdmFyIERyb3Bkb3duID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAkKGVsZW1lbnQpLm9uKCdjbGljay5icy5kcm9wZG93bicsIHRoaXMudG9nZ2xlKVxuICB9XG5cbiAgRHJvcGRvd24uVkVSU0lPTiA9ICczLjMuNCdcblxuICBEcm9wZG93bi5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgJHRoaXMgPSAkKHRoaXMpXG5cbiAgICBpZiAoJHRoaXMuaXMoJy5kaXNhYmxlZCwgOmRpc2FibGVkJykpIHJldHVyblxuXG4gICAgdmFyICRwYXJlbnQgID0gZ2V0UGFyZW50KCR0aGlzKVxuICAgIHZhciBpc0FjdGl2ZSA9ICRwYXJlbnQuaGFzQ2xhc3MoJ29wZW4nKVxuXG4gICAgY2xlYXJNZW51cygpXG5cbiAgICBpZiAoIWlzQWN0aXZlKSB7XG4gICAgICBpZiAoJ29udG91Y2hzdGFydCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmICEkcGFyZW50LmNsb3Nlc3QoJy5uYXZiYXItbmF2JykubGVuZ3RoKSB7XG4gICAgICAgIC8vIGlmIG1vYmlsZSB3ZSB1c2UgYSBiYWNrZHJvcCBiZWNhdXNlIGNsaWNrIGV2ZW50cyBkb24ndCBkZWxlZ2F0ZVxuICAgICAgICAkKCc8ZGl2IGNsYXNzPVwiZHJvcGRvd24tYmFja2Ryb3BcIi8+JykuaW5zZXJ0QWZ0ZXIoJCh0aGlzKSkub24oJ2NsaWNrJywgY2xlYXJNZW51cylcbiAgICAgIH1cblxuICAgICAgdmFyIHJlbGF0ZWRUYXJnZXQgPSB7IHJlbGF0ZWRUYXJnZXQ6IHRoaXMgfVxuICAgICAgJHBhcmVudC50cmlnZ2VyKGUgPSAkLkV2ZW50KCdzaG93LmJzLmRyb3Bkb3duJywgcmVsYXRlZFRhcmdldCkpXG5cbiAgICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgICAgJHRoaXNcbiAgICAgICAgLnRyaWdnZXIoJ2ZvY3VzJylcbiAgICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpXG5cbiAgICAgICRwYXJlbnRcbiAgICAgICAgLnRvZ2dsZUNsYXNzKCdvcGVuJylcbiAgICAgICAgLnRyaWdnZXIoJ3Nob3duLmJzLmRyb3Bkb3duJywgcmVsYXRlZFRhcmdldClcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIERyb3Bkb3duLnByb3RvdHlwZS5rZXlkb3duID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoIS8oMzh8NDB8Mjd8MzIpLy50ZXN0KGUud2hpY2gpIHx8IC9pbnB1dHx0ZXh0YXJlYS9pLnRlc3QoZS50YXJnZXQudGFnTmFtZSkpIHJldHVyblxuXG4gICAgdmFyICR0aGlzID0gJCh0aGlzKVxuXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgaWYgKCR0aGlzLmlzKCcuZGlzYWJsZWQsIDpkaXNhYmxlZCcpKSByZXR1cm5cblxuICAgIHZhciAkcGFyZW50ICA9IGdldFBhcmVudCgkdGhpcylcbiAgICB2YXIgaXNBY3RpdmUgPSAkcGFyZW50Lmhhc0NsYXNzKCdvcGVuJylcblxuICAgIGlmICgoIWlzQWN0aXZlICYmIGUud2hpY2ggIT0gMjcpIHx8IChpc0FjdGl2ZSAmJiBlLndoaWNoID09IDI3KSkge1xuICAgICAgaWYgKGUud2hpY2ggPT0gMjcpICRwYXJlbnQuZmluZCh0b2dnbGUpLnRyaWdnZXIoJ2ZvY3VzJylcbiAgICAgIHJldHVybiAkdGhpcy50cmlnZ2VyKCdjbGljaycpXG4gICAgfVxuXG4gICAgdmFyIGRlc2MgPSAnIGxpOm5vdCguZGlzYWJsZWQpOnZpc2libGUgYSdcbiAgICB2YXIgJGl0ZW1zID0gJHBhcmVudC5maW5kKCdbcm9sZT1cIm1lbnVcIl0nICsgZGVzYyArICcsIFtyb2xlPVwibGlzdGJveFwiXScgKyBkZXNjKVxuXG4gICAgaWYgKCEkaXRlbXMubGVuZ3RoKSByZXR1cm5cblxuICAgIHZhciBpbmRleCA9ICRpdGVtcy5pbmRleChlLnRhcmdldClcblxuICAgIGlmIChlLndoaWNoID09IDM4ICYmIGluZGV4ID4gMCkgICAgICAgICAgICAgICAgIGluZGV4LS0gICAgICAgICAgICAgICAgICAgICAgICAvLyB1cFxuICAgIGlmIChlLndoaWNoID09IDQwICYmIGluZGV4IDwgJGl0ZW1zLmxlbmd0aCAtIDEpIGluZGV4KysgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb3duXG4gICAgaWYgKCF+aW5kZXgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IDBcblxuICAgICRpdGVtcy5lcShpbmRleCkudHJpZ2dlcignZm9jdXMnKVxuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXJNZW51cyhlKSB7XG4gICAgaWYgKGUgJiYgZS53aGljaCA9PT0gMykgcmV0dXJuXG4gICAgJChiYWNrZHJvcCkucmVtb3ZlKClcbiAgICAkKHRvZ2dsZSkuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICAgICAgICA9ICQodGhpcylcbiAgICAgIHZhciAkcGFyZW50ICAgICAgID0gZ2V0UGFyZW50KCR0aGlzKVxuICAgICAgdmFyIHJlbGF0ZWRUYXJnZXQgPSB7IHJlbGF0ZWRUYXJnZXQ6IHRoaXMgfVxuXG4gICAgICBpZiAoISRwYXJlbnQuaGFzQ2xhc3MoJ29wZW4nKSkgcmV0dXJuXG5cbiAgICAgICRwYXJlbnQudHJpZ2dlcihlID0gJC5FdmVudCgnaGlkZS5icy5kcm9wZG93bicsIHJlbGF0ZWRUYXJnZXQpKVxuXG4gICAgICBpZiAoZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuXG5cbiAgICAgICR0aGlzLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKVxuICAgICAgJHBhcmVudC5yZW1vdmVDbGFzcygnb3BlbicpLnRyaWdnZXIoJ2hpZGRlbi5icy5kcm9wZG93bicsIHJlbGF0ZWRUYXJnZXQpXG4gICAgfSlcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFBhcmVudCgkdGhpcykge1xuICAgIHZhciBzZWxlY3RvciA9ICR0aGlzLmF0dHIoJ2RhdGEtdGFyZ2V0JylcblxuICAgIGlmICghc2VsZWN0b3IpIHtcbiAgICAgIHNlbGVjdG9yID0gJHRoaXMuYXR0cignaHJlZicpXG4gICAgICBzZWxlY3RvciA9IHNlbGVjdG9yICYmIC8jW0EtWmEtel0vLnRlc3Qoc2VsZWN0b3IpICYmIHNlbGVjdG9yLnJlcGxhY2UoLy4qKD89I1teXFxzXSokKS8sICcnKSAvLyBzdHJpcCBmb3IgaWU3XG4gICAgfVxuXG4gICAgdmFyICRwYXJlbnQgPSBzZWxlY3RvciAmJiAkKHNlbGVjdG9yKVxuXG4gICAgcmV0dXJuICRwYXJlbnQgJiYgJHBhcmVudC5sZW5ndGggPyAkcGFyZW50IDogJHRoaXMucGFyZW50KClcbiAgfVxuXG5cbiAgLy8gRFJPUERPV04gUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpXG4gICAgICB2YXIgZGF0YSAgPSAkdGhpcy5kYXRhKCdicy5kcm9wZG93bicpXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuZHJvcGRvd24nLCAoZGF0YSA9IG5ldyBEcm9wZG93bih0aGlzKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dLmNhbGwoJHRoaXMpXG4gICAgfSlcbiAgfVxuXG4gIHZhciBvbGQgPSAkLmZuLmRyb3Bkb3duXG5cbiAgJC5mbi5kcm9wZG93biAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLmRyb3Bkb3duLkNvbnN0cnVjdG9yID0gRHJvcGRvd25cblxuXG4gIC8vIERST1BET1dOIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09PT09XG5cbiAgJC5mbi5kcm9wZG93bi5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4uZHJvcGRvd24gPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBBUFBMWSBUTyBTVEFOREFSRCBEUk9QRE9XTiBFTEVNRU5UU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICQoZG9jdW1lbnQpXG4gICAgLm9uKCdjbGljay5icy5kcm9wZG93bi5kYXRhLWFwaScsIGNsZWFyTWVudXMpXG4gICAgLm9uKCdjbGljay5icy5kcm9wZG93bi5kYXRhLWFwaScsICcuZHJvcGRvd24gZm9ybScsIGZ1bmN0aW9uIChlKSB7IGUuc3RvcFByb3BhZ2F0aW9uKCkgfSlcbiAgICAub24oJ2NsaWNrLmJzLmRyb3Bkb3duLmRhdGEtYXBpJywgdG9nZ2xlLCBEcm9wZG93bi5wcm90b3R5cGUudG9nZ2xlKVxuICAgIC5vbigna2V5ZG93bi5icy5kcm9wZG93bi5kYXRhLWFwaScsIHRvZ2dsZSwgRHJvcGRvd24ucHJvdG90eXBlLmtleWRvd24pXG4gICAgLm9uKCdrZXlkb3duLmJzLmRyb3Bkb3duLmRhdGEtYXBpJywgJ1tyb2xlPVwibWVudVwiXScsIERyb3Bkb3duLnByb3RvdHlwZS5rZXlkb3duKVxuICAgIC5vbigna2V5ZG93bi5icy5kcm9wZG93bi5kYXRhLWFwaScsICdbcm9sZT1cImxpc3Rib3hcIl0nLCBEcm9wZG93bi5wcm90b3R5cGUua2V5ZG93bilcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogbW9kYWwuanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyNtb2RhbHNcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weXJpZ2h0IDIwMTEtMjAxNSBUd2l0dGVyLCBJbmMuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cblxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBNT0RBTCBDTEFTUyBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT1cblxuICB2YXIgTW9kYWwgPSBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyAgICAgICAgICAgICA9IG9wdGlvbnNcbiAgICB0aGlzLiRib2R5ICAgICAgICAgICAgICAgPSAkKGRvY3VtZW50LmJvZHkpXG4gICAgdGhpcy4kZWxlbWVudCAgICAgICAgICAgID0gJChlbGVtZW50KVxuICAgIHRoaXMuJGRpYWxvZyAgICAgICAgICAgICA9IHRoaXMuJGVsZW1lbnQuZmluZCgnLm1vZGFsLWRpYWxvZycpXG4gICAgdGhpcy4kYmFja2Ryb3AgICAgICAgICAgID0gbnVsbFxuICAgIHRoaXMuaXNTaG93biAgICAgICAgICAgICA9IG51bGxcbiAgICB0aGlzLm9yaWdpbmFsQm9keVBhZCAgICAgPSBudWxsXG4gICAgdGhpcy5zY3JvbGxiYXJXaWR0aCAgICAgID0gMFxuICAgIHRoaXMuaWdub3JlQmFja2Ryb3BDbGljayA9IGZhbHNlXG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnJlbW90ZSkge1xuICAgICAgdGhpcy4kZWxlbWVudFxuICAgICAgICAuZmluZCgnLm1vZGFsLWNvbnRlbnQnKVxuICAgICAgICAubG9hZCh0aGlzLm9wdGlvbnMucmVtb3RlLCAkLnByb3h5KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2xvYWRlZC5icy5tb2RhbCcpXG4gICAgICAgIH0sIHRoaXMpKVxuICAgIH1cbiAgfVxuXG4gIE1vZGFsLlZFUlNJT04gID0gJzMuMy40J1xuXG4gIE1vZGFsLlRSQU5TSVRJT05fRFVSQVRJT04gPSAzMDBcbiAgTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTiA9IDE1MFxuXG4gIE1vZGFsLkRFRkFVTFRTID0ge1xuICAgIGJhY2tkcm9wOiB0cnVlLFxuICAgIGtleWJvYXJkOiB0cnVlLFxuICAgIHNob3c6IHRydWVcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoX3JlbGF0ZWRUYXJnZXQpIHtcbiAgICByZXR1cm4gdGhpcy5pc1Nob3duID8gdGhpcy5oaWRlKCkgOiB0aGlzLnNob3coX3JlbGF0ZWRUYXJnZXQpXG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uIChfcmVsYXRlZFRhcmdldCkge1xuICAgIHZhciB0aGF0ID0gdGhpc1xuICAgIHZhciBlICAgID0gJC5FdmVudCgnc2hvdy5icy5tb2RhbCcsIHsgcmVsYXRlZFRhcmdldDogX3JlbGF0ZWRUYXJnZXQgfSlcblxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihlKVxuXG4gICAgaWYgKHRoaXMuaXNTaG93biB8fCBlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgIHRoaXMuaXNTaG93biA9IHRydWVcblxuICAgIHRoaXMuY2hlY2tTY3JvbGxiYXIoKVxuICAgIHRoaXMuc2V0U2Nyb2xsYmFyKClcbiAgICB0aGlzLiRib2R5LmFkZENsYXNzKCdtb2RhbC1vcGVuJylcblxuICAgIHRoaXMuZXNjYXBlKClcbiAgICB0aGlzLnJlc2l6ZSgpXG5cbiAgICB0aGlzLiRlbGVtZW50Lm9uKCdjbGljay5kaXNtaXNzLmJzLm1vZGFsJywgJ1tkYXRhLWRpc21pc3M9XCJtb2RhbFwiXScsICQucHJveHkodGhpcy5oaWRlLCB0aGlzKSlcblxuICAgIHRoaXMuJGRpYWxvZy5vbignbW91c2Vkb3duLmRpc21pc3MuYnMubW9kYWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGF0LiRlbGVtZW50Lm9uZSgnbW91c2V1cC5kaXNtaXNzLmJzLm1vZGFsJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKCQoZS50YXJnZXQpLmlzKHRoYXQuJGVsZW1lbnQpKSB0aGF0Lmlnbm9yZUJhY2tkcm9wQ2xpY2sgPSB0cnVlXG4gICAgICB9KVxuICAgIH0pXG5cbiAgICB0aGlzLmJhY2tkcm9wKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB0cmFuc2l0aW9uID0gJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhhdC4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpXG5cbiAgICAgIGlmICghdGhhdC4kZWxlbWVudC5wYXJlbnQoKS5sZW5ndGgpIHtcbiAgICAgICAgdGhhdC4kZWxlbWVudC5hcHBlbmRUbyh0aGF0LiRib2R5KSAvLyBkb24ndCBtb3ZlIG1vZGFscyBkb20gcG9zaXRpb25cbiAgICAgIH1cblxuICAgICAgdGhhdC4kZWxlbWVudFxuICAgICAgICAuc2hvdygpXG4gICAgICAgIC5zY3JvbGxUb3AoMClcblxuICAgICAgdGhhdC5hZGp1c3REaWFsb2coKVxuXG4gICAgICBpZiAodHJhbnNpdGlvbikge1xuICAgICAgICB0aGF0LiRlbGVtZW50WzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvd1xuICAgICAgfVxuXG4gICAgICB0aGF0LiRlbGVtZW50XG4gICAgICAgIC5hZGRDbGFzcygnaW4nKVxuICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCBmYWxzZSlcblxuICAgICAgdGhhdC5lbmZvcmNlRm9jdXMoKVxuXG4gICAgICB2YXIgZSA9ICQuRXZlbnQoJ3Nob3duLmJzLm1vZGFsJywgeyByZWxhdGVkVGFyZ2V0OiBfcmVsYXRlZFRhcmdldCB9KVxuXG4gICAgICB0cmFuc2l0aW9uID9cbiAgICAgICAgdGhhdC4kZGlhbG9nIC8vIHdhaXQgZm9yIG1vZGFsIHRvIHNsaWRlIGluXG4gICAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhhdC4kZWxlbWVudC50cmlnZ2VyKCdmb2N1cycpLnRyaWdnZXIoZSlcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignZm9jdXMnKS50cmlnZ2VyKGUpXG4gICAgfSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoZSkgZS5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgICBlID0gJC5FdmVudCgnaGlkZS5icy5tb2RhbCcpXG5cbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoZSlcblxuICAgIGlmICghdGhpcy5pc1Nob3duIHx8IGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgdGhpcy5pc1Nob3duID0gZmFsc2VcblxuICAgIHRoaXMuZXNjYXBlKClcbiAgICB0aGlzLnJlc2l6ZSgpXG5cbiAgICAkKGRvY3VtZW50KS5vZmYoJ2ZvY3VzaW4uYnMubW9kYWwnKVxuXG4gICAgdGhpcy4kZWxlbWVudFxuICAgICAgLnJlbW92ZUNsYXNzKCdpbicpXG4gICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCB0cnVlKVxuICAgICAgLm9mZignY2xpY2suZGlzbWlzcy5icy5tb2RhbCcpXG4gICAgICAub2ZmKCdtb3VzZXVwLmRpc21pc3MuYnMubW9kYWwnKVxuXG4gICAgdGhpcy4kZGlhbG9nLm9mZignbW91c2Vkb3duLmRpc21pc3MuYnMubW9kYWwnKVxuXG4gICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpID9cbiAgICAgIHRoaXMuJGVsZW1lbnRcbiAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgJC5wcm94eSh0aGlzLmhpZGVNb2RhbCwgdGhpcykpXG4gICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICB0aGlzLmhpZGVNb2RhbCgpXG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUuZW5mb3JjZUZvY3VzID0gZnVuY3Rpb24gKCkge1xuICAgICQoZG9jdW1lbnQpXG4gICAgICAub2ZmKCdmb2N1c2luLmJzLm1vZGFsJykgLy8gZ3VhcmQgYWdhaW5zdCBpbmZpbml0ZSBmb2N1cyBsb29wXG4gICAgICAub24oJ2ZvY3VzaW4uYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICh0aGlzLiRlbGVtZW50WzBdICE9PSBlLnRhcmdldCAmJiAhdGhpcy4kZWxlbWVudC5oYXMoZS50YXJnZXQpLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignZm9jdXMnKVxuICAgICAgICB9XG4gICAgICB9LCB0aGlzKSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5lc2NhcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuaXNTaG93biAmJiB0aGlzLm9wdGlvbnMua2V5Ym9hcmQpIHtcbiAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2tleWRvd24uZGlzbWlzcy5icy5tb2RhbCcsICQucHJveHkoZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS53aGljaCA9PSAyNyAmJiB0aGlzLmhpZGUoKVxuICAgICAgfSwgdGhpcykpXG4gICAgfSBlbHNlIGlmICghdGhpcy5pc1Nob3duKSB7XG4gICAgICB0aGlzLiRlbGVtZW50Lm9mZigna2V5ZG93bi5kaXNtaXNzLmJzLm1vZGFsJylcbiAgICB9XG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmlzU2hvd24pIHtcbiAgICAgICQod2luZG93KS5vbigncmVzaXplLmJzLm1vZGFsJywgJC5wcm94eSh0aGlzLmhhbmRsZVVwZGF0ZSwgdGhpcykpXG4gICAgfSBlbHNlIHtcbiAgICAgICQod2luZG93KS5vZmYoJ3Jlc2l6ZS5icy5tb2RhbCcpXG4gICAgfVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmhpZGVNb2RhbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXNcbiAgICB0aGlzLiRlbGVtZW50LmhpZGUoKVxuICAgIHRoaXMuYmFja2Ryb3AoZnVuY3Rpb24gKCkge1xuICAgICAgdGhhdC4kYm9keS5yZW1vdmVDbGFzcygnbW9kYWwtb3BlbicpXG4gICAgICB0aGF0LnJlc2V0QWRqdXN0bWVudHMoKVxuICAgICAgdGhhdC5yZXNldFNjcm9sbGJhcigpXG4gICAgICB0aGF0LiRlbGVtZW50LnRyaWdnZXIoJ2hpZGRlbi5icy5tb2RhbCcpXG4gICAgfSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5yZW1vdmVCYWNrZHJvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLiRiYWNrZHJvcCAmJiB0aGlzLiRiYWNrZHJvcC5yZW1vdmUoKVxuICAgIHRoaXMuJGJhY2tkcm9wID0gbnVsbFxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmJhY2tkcm9wID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgdmFyIGFuaW1hdGUgPSB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykgPyAnZmFkZScgOiAnJ1xuXG4gICAgaWYgKHRoaXMuaXNTaG93biAmJiB0aGlzLm9wdGlvbnMuYmFja2Ryb3ApIHtcbiAgICAgIHZhciBkb0FuaW1hdGUgPSAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiBhbmltYXRlXG5cbiAgICAgIHRoaXMuJGJhY2tkcm9wID0gJCgnPGRpdiBjbGFzcz1cIm1vZGFsLWJhY2tkcm9wICcgKyBhbmltYXRlICsgJ1wiIC8+JylcbiAgICAgICAgLmFwcGVuZFRvKHRoaXMuJGJvZHkpXG5cbiAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2NsaWNrLmRpc21pc3MuYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICh0aGlzLmlnbm9yZUJhY2tkcm9wQ2xpY2spIHtcbiAgICAgICAgICB0aGlzLmlnbm9yZUJhY2tkcm9wQ2xpY2sgPSBmYWxzZVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGlmIChlLnRhcmdldCAhPT0gZS5jdXJyZW50VGFyZ2V0KSByZXR1cm5cbiAgICAgICAgdGhpcy5vcHRpb25zLmJhY2tkcm9wID09ICdzdGF0aWMnXG4gICAgICAgICAgPyB0aGlzLiRlbGVtZW50WzBdLmZvY3VzKClcbiAgICAgICAgICA6IHRoaXMuaGlkZSgpXG4gICAgICB9LCB0aGlzKSlcblxuICAgICAgaWYgKGRvQW5pbWF0ZSkgdGhpcy4kYmFja2Ryb3BbMF0ub2Zmc2V0V2lkdGggLy8gZm9yY2UgcmVmbG93XG5cbiAgICAgIHRoaXMuJGJhY2tkcm9wLmFkZENsYXNzKCdpbicpXG5cbiAgICAgIGlmICghY2FsbGJhY2spIHJldHVyblxuXG4gICAgICBkb0FuaW1hdGUgP1xuICAgICAgICB0aGlzLiRiYWNrZHJvcFxuICAgICAgICAgIC5vbmUoJ2JzVHJhbnNpdGlvbkVuZCcsIGNhbGxiYWNrKVxuICAgICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5CQUNLRFJPUF9UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICAgIGNhbGxiYWNrKClcblxuICAgIH0gZWxzZSBpZiAoIXRoaXMuaXNTaG93biAmJiB0aGlzLiRiYWNrZHJvcCkge1xuICAgICAgdGhpcy4kYmFja2Ryb3AucmVtb3ZlQ2xhc3MoJ2luJylcblxuICAgICAgdmFyIGNhbGxiYWNrUmVtb3ZlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGF0LnJlbW92ZUJhY2tkcm9wKClcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgICAgfVxuICAgICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpID9cbiAgICAgICAgdGhpcy4kYmFja2Ryb3BcbiAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBjYWxsYmFja1JlbW92ZSlcbiAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTikgOlxuICAgICAgICBjYWxsYmFja1JlbW92ZSgpXG5cbiAgICB9IGVsc2UgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBjYWxsYmFjaygpXG4gICAgfVxuICB9XG5cbiAgLy8gdGhlc2UgZm9sbG93aW5nIG1ldGhvZHMgYXJlIHVzZWQgdG8gaGFuZGxlIG92ZXJmbG93aW5nIG1vZGFsc1xuXG4gIE1vZGFsLnByb3RvdHlwZS5oYW5kbGVVcGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5hZGp1c3REaWFsb2coKVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmFkanVzdERpYWxvZyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbW9kYWxJc092ZXJmbG93aW5nID0gdGhpcy4kZWxlbWVudFswXS5zY3JvbGxIZWlnaHQgPiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0XG5cbiAgICB0aGlzLiRlbGVtZW50LmNzcyh7XG4gICAgICBwYWRkaW5nTGVmdDogICF0aGlzLmJvZHlJc092ZXJmbG93aW5nICYmIG1vZGFsSXNPdmVyZmxvd2luZyA/IHRoaXMuc2Nyb2xsYmFyV2lkdGggOiAnJyxcbiAgICAgIHBhZGRpbmdSaWdodDogdGhpcy5ib2R5SXNPdmVyZmxvd2luZyAmJiAhbW9kYWxJc092ZXJmbG93aW5nID8gdGhpcy5zY3JvbGxiYXJXaWR0aCA6ICcnXG4gICAgfSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5yZXNldEFkanVzdG1lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuJGVsZW1lbnQuY3NzKHtcbiAgICAgIHBhZGRpbmdMZWZ0OiAnJyxcbiAgICAgIHBhZGRpbmdSaWdodDogJydcbiAgICB9KVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmNoZWNrU2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBmdWxsV2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aFxuICAgIGlmICghZnVsbFdpbmRvd1dpZHRoKSB7IC8vIHdvcmthcm91bmQgZm9yIG1pc3Npbmcgd2luZG93LmlubmVyV2lkdGggaW4gSUU4XG4gICAgICB2YXIgZG9jdW1lbnRFbGVtZW50UmVjdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgZnVsbFdpbmRvd1dpZHRoID0gZG9jdW1lbnRFbGVtZW50UmVjdC5yaWdodCAtIE1hdGguYWJzKGRvY3VtZW50RWxlbWVudFJlY3QubGVmdClcbiAgICB9XG4gICAgdGhpcy5ib2R5SXNPdmVyZmxvd2luZyA9IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGggPCBmdWxsV2luZG93V2lkdGhcbiAgICB0aGlzLnNjcm9sbGJhcldpZHRoID0gdGhpcy5tZWFzdXJlU2Nyb2xsYmFyKClcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5zZXRTY3JvbGxiYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGJvZHlQYWQgPSBwYXJzZUludCgodGhpcy4kYm9keS5jc3MoJ3BhZGRpbmctcmlnaHQnKSB8fCAwKSwgMTApXG4gICAgdGhpcy5vcmlnaW5hbEJvZHlQYWQgPSBkb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmdSaWdodCB8fCAnJ1xuICAgIGlmICh0aGlzLmJvZHlJc092ZXJmbG93aW5nKSB0aGlzLiRib2R5LmNzcygncGFkZGluZy1yaWdodCcsIGJvZHlQYWQgKyB0aGlzLnNjcm9sbGJhcldpZHRoKVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLnJlc2V0U2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0JywgdGhpcy5vcmlnaW5hbEJvZHlQYWQpXG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUubWVhc3VyZVNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsgLy8gdGh4IHdhbHNoXG4gICAgdmFyIHNjcm9sbERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgc2Nyb2xsRGl2LmNsYXNzTmFtZSA9ICdtb2RhbC1zY3JvbGxiYXItbWVhc3VyZSdcbiAgICB0aGlzLiRib2R5LmFwcGVuZChzY3JvbGxEaXYpXG4gICAgdmFyIHNjcm9sbGJhcldpZHRoID0gc2Nyb2xsRGl2Lm9mZnNldFdpZHRoIC0gc2Nyb2xsRGl2LmNsaWVudFdpZHRoXG4gICAgdGhpcy4kYm9keVswXS5yZW1vdmVDaGlsZChzY3JvbGxEaXYpXG4gICAgcmV0dXJuIHNjcm9sbGJhcldpZHRoXG4gIH1cblxuXG4gIC8vIE1PREFMIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gUGx1Z2luKG9wdGlvbiwgX3JlbGF0ZWRUYXJnZXQpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5tb2RhbCcpXG4gICAgICB2YXIgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBNb2RhbC5ERUZBVUxUUywgJHRoaXMuZGF0YSgpLCB0eXBlb2Ygb3B0aW9uID09ICdvYmplY3QnICYmIG9wdGlvbilcblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5tb2RhbCcsIChkYXRhID0gbmV3IE1vZGFsKHRoaXMsIG9wdGlvbnMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oX3JlbGF0ZWRUYXJnZXQpXG4gICAgICBlbHNlIGlmIChvcHRpb25zLnNob3cpIGRhdGEuc2hvdyhfcmVsYXRlZFRhcmdldClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4ubW9kYWxcblxuICAkLmZuLm1vZGFsICAgICAgICAgICAgID0gUGx1Z2luXG4gICQuZm4ubW9kYWwuQ29uc3RydWN0b3IgPSBNb2RhbFxuXG5cbiAgLy8gTU9EQUwgTk8gQ09ORkxJQ1RcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICAkLmZuLm1vZGFsLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi5tb2RhbCA9IG9sZFxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuXG4gIC8vIE1PREFMIERBVEEtQVBJXG4gIC8vID09PT09PT09PT09PT09XG5cbiAgJChkb2N1bWVudCkub24oJ2NsaWNrLmJzLm1vZGFsLmRhdGEtYXBpJywgJ1tkYXRhLXRvZ2dsZT1cIm1vZGFsXCJdJywgZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICB2YXIgaHJlZiAgICA9ICR0aGlzLmF0dHIoJ2hyZWYnKVxuICAgIHZhciAkdGFyZ2V0ID0gJCgkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpIHx8IChocmVmICYmIGhyZWYucmVwbGFjZSgvLiooPz0jW15cXHNdKyQpLywgJycpKSkgLy8gc3RyaXAgZm9yIGllN1xuICAgIHZhciBvcHRpb24gID0gJHRhcmdldC5kYXRhKCdicy5tb2RhbCcpID8gJ3RvZ2dsZScgOiAkLmV4dGVuZCh7IHJlbW90ZTogIS8jLy50ZXN0KGhyZWYpICYmIGhyZWYgfSwgJHRhcmdldC5kYXRhKCksICR0aGlzLmRhdGEoKSlcblxuICAgIGlmICgkdGhpcy5pcygnYScpKSBlLnByZXZlbnREZWZhdWx0KClcblxuICAgICR0YXJnZXQub25lKCdzaG93LmJzLm1vZGFsJywgZnVuY3Rpb24gKHNob3dFdmVudCkge1xuICAgICAgaWYgKHNob3dFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuIC8vIG9ubHkgcmVnaXN0ZXIgZm9jdXMgcmVzdG9yZXIgaWYgbW9kYWwgd2lsbCBhY3R1YWxseSBnZXQgc2hvd25cbiAgICAgICR0YXJnZXQub25lKCdoaWRkZW4uYnMubW9kYWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICR0aGlzLmlzKCc6dmlzaWJsZScpICYmICR0aGlzLnRyaWdnZXIoJ2ZvY3VzJylcbiAgICAgIH0pXG4gICAgfSlcbiAgICBQbHVnaW4uY2FsbCgkdGFyZ2V0LCBvcHRpb24sIHRoaXMpXG4gIH0pXG5cbn0oalF1ZXJ5KTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCb290c3RyYXA6IHRvb2x0aXAuanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyN0b29sdGlwXG4gKiBJbnNwaXJlZCBieSB0aGUgb3JpZ2luYWwgalF1ZXJ5LnRpcHN5IGJ5IEphc29uIEZyYW1lXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gVE9PTFRJUCBQVUJMSUMgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIFRvb2x0aXAgPSBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHRoaXMudHlwZSAgICAgICA9IG51bGxcbiAgICB0aGlzLm9wdGlvbnMgICAgPSBudWxsXG4gICAgdGhpcy5lbmFibGVkICAgID0gbnVsbFxuICAgIHRoaXMudGltZW91dCAgICA9IG51bGxcbiAgICB0aGlzLmhvdmVyU3RhdGUgPSBudWxsXG4gICAgdGhpcy4kZWxlbWVudCAgID0gbnVsbFxuXG4gICAgdGhpcy5pbml0KCd0b29sdGlwJywgZWxlbWVudCwgb3B0aW9ucylcbiAgfVxuXG4gIFRvb2x0aXAuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgVG9vbHRpcC5UUkFOU0lUSU9OX0RVUkFUSU9OID0gMTUwXG5cbiAgVG9vbHRpcC5ERUZBVUxUUyA9IHtcbiAgICBhbmltYXRpb246IHRydWUsXG4gICAgcGxhY2VtZW50OiAndG9wJyxcbiAgICBzZWxlY3RvcjogZmFsc2UsXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwidG9vbHRpcFwiIHJvbGU9XCJ0b29sdGlwXCI+PGRpdiBjbGFzcz1cInRvb2x0aXAtYXJyb3dcIj48L2Rpdj48ZGl2IGNsYXNzPVwidG9vbHRpcC1pbm5lclwiPjwvZGl2PjwvZGl2PicsXG4gICAgdHJpZ2dlcjogJ2hvdmVyIGZvY3VzJyxcbiAgICB0aXRsZTogJycsXG4gICAgZGVsYXk6IDAsXG4gICAgaHRtbDogZmFsc2UsXG4gICAgY29udGFpbmVyOiBmYWxzZSxcbiAgICB2aWV3cG9ydDoge1xuICAgICAgc2VsZWN0b3I6ICdib2R5JyxcbiAgICAgIHBhZGRpbmc6IDBcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKHR5cGUsIGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLmVuYWJsZWQgICA9IHRydWVcbiAgICB0aGlzLnR5cGUgICAgICA9IHR5cGVcbiAgICB0aGlzLiRlbGVtZW50ICA9ICQoZWxlbWVudClcbiAgICB0aGlzLm9wdGlvbnMgICA9IHRoaXMuZ2V0T3B0aW9ucyhvcHRpb25zKVxuICAgIHRoaXMuJHZpZXdwb3J0ID0gdGhpcy5vcHRpb25zLnZpZXdwb3J0ICYmICQodGhpcy5vcHRpb25zLnZpZXdwb3J0LnNlbGVjdG9yIHx8IHRoaXMub3B0aW9ucy52aWV3cG9ydClcblxuICAgIGlmICh0aGlzLiRlbGVtZW50WzBdIGluc3RhbmNlb2YgZG9jdW1lbnQuY29uc3RydWN0b3IgJiYgIXRoaXMub3B0aW9ucy5zZWxlY3Rvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdgc2VsZWN0b3JgIG9wdGlvbiBtdXN0IGJlIHNwZWNpZmllZCB3aGVuIGluaXRpYWxpemluZyAnICsgdGhpcy50eXBlICsgJyBvbiB0aGUgd2luZG93LmRvY3VtZW50IG9iamVjdCEnKVxuICAgIH1cblxuICAgIHZhciB0cmlnZ2VycyA9IHRoaXMub3B0aW9ucy50cmlnZ2VyLnNwbGl0KCcgJylcblxuICAgIGZvciAodmFyIGkgPSB0cmlnZ2Vycy5sZW5ndGg7IGktLTspIHtcbiAgICAgIHZhciB0cmlnZ2VyID0gdHJpZ2dlcnNbaV1cblxuICAgICAgaWYgKHRyaWdnZXIgPT0gJ2NsaWNrJykge1xuICAgICAgICB0aGlzLiRlbGVtZW50Lm9uKCdjbGljay4nICsgdGhpcy50eXBlLCB0aGlzLm9wdGlvbnMuc2VsZWN0b3IsICQucHJveHkodGhpcy50b2dnbGUsIHRoaXMpKVxuICAgICAgfSBlbHNlIGlmICh0cmlnZ2VyICE9ICdtYW51YWwnKSB7XG4gICAgICAgIHZhciBldmVudEluICA9IHRyaWdnZXIgPT0gJ2hvdmVyJyA/ICdtb3VzZWVudGVyJyA6ICdmb2N1c2luJ1xuICAgICAgICB2YXIgZXZlbnRPdXQgPSB0cmlnZ2VyID09ICdob3ZlcicgPyAnbW91c2VsZWF2ZScgOiAnZm9jdXNvdXQnXG5cbiAgICAgICAgdGhpcy4kZWxlbWVudC5vbihldmVudEluICArICcuJyArIHRoaXMudHlwZSwgdGhpcy5vcHRpb25zLnNlbGVjdG9yLCAkLnByb3h5KHRoaXMuZW50ZXIsIHRoaXMpKVxuICAgICAgICB0aGlzLiRlbGVtZW50Lm9uKGV2ZW50T3V0ICsgJy4nICsgdGhpcy50eXBlLCB0aGlzLm9wdGlvbnMuc2VsZWN0b3IsICQucHJveHkodGhpcy5sZWF2ZSwgdGhpcykpXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5vcHRpb25zLnNlbGVjdG9yID9cbiAgICAgICh0aGlzLl9vcHRpb25zID0gJC5leHRlbmQoe30sIHRoaXMub3B0aW9ucywgeyB0cmlnZ2VyOiAnbWFudWFsJywgc2VsZWN0b3I6ICcnIH0pKSA6XG4gICAgICB0aGlzLmZpeFRpdGxlKClcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldERlZmF1bHRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBUb29sdGlwLkRFRkFVTFRTXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5nZXRPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gJC5leHRlbmQoe30sIHRoaXMuZ2V0RGVmYXVsdHMoKSwgdGhpcy4kZWxlbWVudC5kYXRhKCksIG9wdGlvbnMpXG5cbiAgICBpZiAob3B0aW9ucy5kZWxheSAmJiB0eXBlb2Ygb3B0aW9ucy5kZWxheSA9PSAnbnVtYmVyJykge1xuICAgICAgb3B0aW9ucy5kZWxheSA9IHtcbiAgICAgICAgc2hvdzogb3B0aW9ucy5kZWxheSxcbiAgICAgICAgaGlkZTogb3B0aW9ucy5kZWxheVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvcHRpb25zXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5nZXREZWxlZ2F0ZU9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG9wdGlvbnMgID0ge31cbiAgICB2YXIgZGVmYXVsdHMgPSB0aGlzLmdldERlZmF1bHRzKClcblxuICAgIHRoaXMuX29wdGlvbnMgJiYgJC5lYWNoKHRoaXMuX29wdGlvbnMsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoZGVmYXVsdHNba2V5XSAhPSB2YWx1ZSkgb3B0aW9uc1trZXldID0gdmFsdWVcbiAgICB9KVxuXG4gICAgcmV0dXJuIG9wdGlvbnNcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmVudGVyID0gZnVuY3Rpb24gKG9iaikge1xuICAgIHZhciBzZWxmID0gb2JqIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3RvciA/XG4gICAgICBvYmogOiAkKG9iai5jdXJyZW50VGFyZ2V0KS5kYXRhKCdicy4nICsgdGhpcy50eXBlKVxuXG4gICAgaWYgKHNlbGYgJiYgc2VsZi4kdGlwICYmIHNlbGYuJHRpcC5pcygnOnZpc2libGUnKSkge1xuICAgICAgc2VsZi5ob3ZlclN0YXRlID0gJ2luJ1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKCFzZWxmKSB7XG4gICAgICBzZWxmID0gbmV3IHRoaXMuY29uc3RydWN0b3Iob2JqLmN1cnJlbnRUYXJnZXQsIHRoaXMuZ2V0RGVsZWdhdGVPcHRpb25zKCkpXG4gICAgICAkKG9iai5jdXJyZW50VGFyZ2V0KS5kYXRhKCdicy4nICsgdGhpcy50eXBlLCBzZWxmKVxuICAgIH1cblxuICAgIGNsZWFyVGltZW91dChzZWxmLnRpbWVvdXQpXG5cbiAgICBzZWxmLmhvdmVyU3RhdGUgPSAnaW4nXG5cbiAgICBpZiAoIXNlbGYub3B0aW9ucy5kZWxheSB8fCAhc2VsZi5vcHRpb25zLmRlbGF5LnNob3cpIHJldHVybiBzZWxmLnNob3coKVxuXG4gICAgc2VsZi50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5ob3ZlclN0YXRlID09ICdpbicpIHNlbGYuc2hvdygpXG4gICAgfSwgc2VsZi5vcHRpb25zLmRlbGF5LnNob3cpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5sZWF2ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIgc2VsZiA9IG9iaiBpbnN0YW5jZW9mIHRoaXMuY29uc3RydWN0b3IgP1xuICAgICAgb2JqIDogJChvYmouY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSlcblxuICAgIGlmICghc2VsZikge1xuICAgICAgc2VsZiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKG9iai5jdXJyZW50VGFyZ2V0LCB0aGlzLmdldERlbGVnYXRlT3B0aW9ucygpKVxuICAgICAgJChvYmouY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSwgc2VsZilcbiAgICB9XG5cbiAgICBjbGVhclRpbWVvdXQoc2VsZi50aW1lb3V0KVxuXG4gICAgc2VsZi5ob3ZlclN0YXRlID0gJ291dCdcblxuICAgIGlmICghc2VsZi5vcHRpb25zLmRlbGF5IHx8ICFzZWxmLm9wdGlvbnMuZGVsYXkuaGlkZSkgcmV0dXJuIHNlbGYuaGlkZSgpXG5cbiAgICBzZWxmLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmhvdmVyU3RhdGUgPT0gJ291dCcpIHNlbGYuaGlkZSgpXG4gICAgfSwgc2VsZi5vcHRpb25zLmRlbGF5LmhpZGUpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBlID0gJC5FdmVudCgnc2hvdy5icy4nICsgdGhpcy50eXBlKVxuXG4gICAgaWYgKHRoaXMuaGFzQ29udGVudCgpICYmIHRoaXMuZW5hYmxlZCkge1xuICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKGUpXG5cbiAgICAgIHZhciBpbkRvbSA9ICQuY29udGFpbnModGhpcy4kZWxlbWVudFswXS5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgdGhpcy4kZWxlbWVudFswXSlcbiAgICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpIHx8ICFpbkRvbSkgcmV0dXJuXG4gICAgICB2YXIgdGhhdCA9IHRoaXNcblxuICAgICAgdmFyICR0aXAgPSB0aGlzLnRpcCgpXG5cbiAgICAgIHZhciB0aXBJZCA9IHRoaXMuZ2V0VUlEKHRoaXMudHlwZSlcblxuICAgICAgdGhpcy5zZXRDb250ZW50KClcbiAgICAgICR0aXAuYXR0cignaWQnLCB0aXBJZClcbiAgICAgIHRoaXMuJGVsZW1lbnQuYXR0cignYXJpYS1kZXNjcmliZWRieScsIHRpcElkKVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmFuaW1hdGlvbikgJHRpcC5hZGRDbGFzcygnZmFkZScpXG5cbiAgICAgIHZhciBwbGFjZW1lbnQgPSB0eXBlb2YgdGhpcy5vcHRpb25zLnBsYWNlbWVudCA9PSAnZnVuY3Rpb24nID9cbiAgICAgICAgdGhpcy5vcHRpb25zLnBsYWNlbWVudC5jYWxsKHRoaXMsICR0aXBbMF0sIHRoaXMuJGVsZW1lbnRbMF0pIDpcbiAgICAgICAgdGhpcy5vcHRpb25zLnBsYWNlbWVudFxuXG4gICAgICB2YXIgYXV0b1Rva2VuID0gL1xccz9hdXRvP1xccz8vaVxuICAgICAgdmFyIGF1dG9QbGFjZSA9IGF1dG9Ub2tlbi50ZXN0KHBsYWNlbWVudClcbiAgICAgIGlmIChhdXRvUGxhY2UpIHBsYWNlbWVudCA9IHBsYWNlbWVudC5yZXBsYWNlKGF1dG9Ub2tlbiwgJycpIHx8ICd0b3AnXG5cbiAgICAgICR0aXBcbiAgICAgICAgLmRldGFjaCgpXG4gICAgICAgIC5jc3MoeyB0b3A6IDAsIGxlZnQ6IDAsIGRpc3BsYXk6ICdibG9jaycgfSlcbiAgICAgICAgLmFkZENsYXNzKHBsYWNlbWVudClcbiAgICAgICAgLmRhdGEoJ2JzLicgKyB0aGlzLnR5cGUsIHRoaXMpXG5cbiAgICAgIHRoaXMub3B0aW9ucy5jb250YWluZXIgPyAkdGlwLmFwcGVuZFRvKHRoaXMub3B0aW9ucy5jb250YWluZXIpIDogJHRpcC5pbnNlcnRBZnRlcih0aGlzLiRlbGVtZW50KVxuXG4gICAgICB2YXIgcG9zICAgICAgICAgID0gdGhpcy5nZXRQb3NpdGlvbigpXG4gICAgICB2YXIgYWN0dWFsV2lkdGggID0gJHRpcFswXS5vZmZzZXRXaWR0aFxuICAgICAgdmFyIGFjdHVhbEhlaWdodCA9ICR0aXBbMF0ub2Zmc2V0SGVpZ2h0XG5cbiAgICAgIGlmIChhdXRvUGxhY2UpIHtcbiAgICAgICAgdmFyIG9yZ1BsYWNlbWVudCA9IHBsYWNlbWVudFxuICAgICAgICB2YXIgJGNvbnRhaW5lciAgID0gdGhpcy5vcHRpb25zLmNvbnRhaW5lciA/ICQodGhpcy5vcHRpb25zLmNvbnRhaW5lcikgOiB0aGlzLiRlbGVtZW50LnBhcmVudCgpXG4gICAgICAgIHZhciBjb250YWluZXJEaW0gPSB0aGlzLmdldFBvc2l0aW9uKCRjb250YWluZXIpXG5cbiAgICAgICAgcGxhY2VtZW50ID0gcGxhY2VtZW50ID09ICdib3R0b20nICYmIHBvcy5ib3R0b20gKyBhY3R1YWxIZWlnaHQgPiBjb250YWluZXJEaW0uYm90dG9tID8gJ3RvcCcgICAgOlxuICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnQgPT0gJ3RvcCcgICAgJiYgcG9zLnRvcCAgICAtIGFjdHVhbEhlaWdodCA8IGNvbnRhaW5lckRpbS50b3AgICAgPyAnYm90dG9tJyA6XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlbWVudCA9PSAncmlnaHQnICAmJiBwb3MucmlnaHQgICsgYWN0dWFsV2lkdGggID4gY29udGFpbmVyRGltLndpZHRoICA/ICdsZWZ0JyAgIDpcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50ID09ICdsZWZ0JyAgICYmIHBvcy5sZWZ0ICAgLSBhY3R1YWxXaWR0aCAgPCBjb250YWluZXJEaW0ubGVmdCAgID8gJ3JpZ2h0JyAgOlxuICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnRcblxuICAgICAgICAkdGlwXG4gICAgICAgICAgLnJlbW92ZUNsYXNzKG9yZ1BsYWNlbWVudClcbiAgICAgICAgICAuYWRkQ2xhc3MocGxhY2VtZW50KVxuICAgICAgfVxuXG4gICAgICB2YXIgY2FsY3VsYXRlZE9mZnNldCA9IHRoaXMuZ2V0Q2FsY3VsYXRlZE9mZnNldChwbGFjZW1lbnQsIHBvcywgYWN0dWFsV2lkdGgsIGFjdHVhbEhlaWdodClcblxuICAgICAgdGhpcy5hcHBseVBsYWNlbWVudChjYWxjdWxhdGVkT2Zmc2V0LCBwbGFjZW1lbnQpXG5cbiAgICAgIHZhciBjb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByZXZIb3ZlclN0YXRlID0gdGhhdC5ob3ZlclN0YXRlXG4gICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignc2hvd24uYnMuJyArIHRoYXQudHlwZSlcbiAgICAgICAgdGhhdC5ob3ZlclN0YXRlID0gbnVsbFxuXG4gICAgICAgIGlmIChwcmV2SG92ZXJTdGF0ZSA9PSAnb3V0JykgdGhhdC5sZWF2ZSh0aGF0KVxuICAgICAgfVxuXG4gICAgICAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGlzLiR0aXAuaGFzQ2xhc3MoJ2ZhZGUnKSA/XG4gICAgICAgICR0aXBcbiAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBjb21wbGV0ZSlcbiAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoVG9vbHRpcC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICAgIGNvbXBsZXRlKClcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5hcHBseVBsYWNlbWVudCA9IGZ1bmN0aW9uIChvZmZzZXQsIHBsYWNlbWVudCkge1xuICAgIHZhciAkdGlwICAgPSB0aGlzLnRpcCgpXG4gICAgdmFyIHdpZHRoICA9ICR0aXBbMF0ub2Zmc2V0V2lkdGhcbiAgICB2YXIgaGVpZ2h0ID0gJHRpcFswXS5vZmZzZXRIZWlnaHRcblxuICAgIC8vIG1hbnVhbGx5IHJlYWQgbWFyZ2lucyBiZWNhdXNlIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBpbmNsdWRlcyBkaWZmZXJlbmNlXG4gICAgdmFyIG1hcmdpblRvcCA9IHBhcnNlSW50KCR0aXAuY3NzKCdtYXJnaW4tdG9wJyksIDEwKVxuICAgIHZhciBtYXJnaW5MZWZ0ID0gcGFyc2VJbnQoJHRpcC5jc3MoJ21hcmdpbi1sZWZ0JyksIDEwKVxuXG4gICAgLy8gd2UgbXVzdCBjaGVjayBmb3IgTmFOIGZvciBpZSA4LzlcbiAgICBpZiAoaXNOYU4obWFyZ2luVG9wKSkgIG1hcmdpblRvcCAgPSAwXG4gICAgaWYgKGlzTmFOKG1hcmdpbkxlZnQpKSBtYXJnaW5MZWZ0ID0gMFxuXG4gICAgb2Zmc2V0LnRvcCAgPSBvZmZzZXQudG9wICArIG1hcmdpblRvcFxuICAgIG9mZnNldC5sZWZ0ID0gb2Zmc2V0LmxlZnQgKyBtYXJnaW5MZWZ0XG5cbiAgICAvLyAkLmZuLm9mZnNldCBkb2Vzbid0IHJvdW5kIHBpeGVsIHZhbHVlc1xuICAgIC8vIHNvIHdlIHVzZSBzZXRPZmZzZXQgZGlyZWN0bHkgd2l0aCBvdXIgb3duIGZ1bmN0aW9uIEItMFxuICAgICQub2Zmc2V0LnNldE9mZnNldCgkdGlwWzBdLCAkLmV4dGVuZCh7XG4gICAgICB1c2luZzogZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgICR0aXAuY3NzKHtcbiAgICAgICAgICB0b3A6IE1hdGgucm91bmQocHJvcHMudG9wKSxcbiAgICAgICAgICBsZWZ0OiBNYXRoLnJvdW5kKHByb3BzLmxlZnQpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSwgb2Zmc2V0KSwgMClcblxuICAgICR0aXAuYWRkQ2xhc3MoJ2luJylcblxuICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBwbGFjaW5nIHRpcCBpbiBuZXcgb2Zmc2V0IGNhdXNlZCB0aGUgdGlwIHRvIHJlc2l6ZSBpdHNlbGZcbiAgICB2YXIgYWN0dWFsV2lkdGggID0gJHRpcFswXS5vZmZzZXRXaWR0aFxuICAgIHZhciBhY3R1YWxIZWlnaHQgPSAkdGlwWzBdLm9mZnNldEhlaWdodFxuXG4gICAgaWYgKHBsYWNlbWVudCA9PSAndG9wJyAmJiBhY3R1YWxIZWlnaHQgIT0gaGVpZ2h0KSB7XG4gICAgICBvZmZzZXQudG9wID0gb2Zmc2V0LnRvcCArIGhlaWdodCAtIGFjdHVhbEhlaWdodFxuICAgIH1cblxuICAgIHZhciBkZWx0YSA9IHRoaXMuZ2V0Vmlld3BvcnRBZGp1c3RlZERlbHRhKHBsYWNlbWVudCwgb2Zmc2V0LCBhY3R1YWxXaWR0aCwgYWN0dWFsSGVpZ2h0KVxuXG4gICAgaWYgKGRlbHRhLmxlZnQpIG9mZnNldC5sZWZ0ICs9IGRlbHRhLmxlZnRcbiAgICBlbHNlIG9mZnNldC50b3AgKz0gZGVsdGEudG9wXG5cbiAgICB2YXIgaXNWZXJ0aWNhbCAgICAgICAgICA9IC90b3B8Ym90dG9tLy50ZXN0KHBsYWNlbWVudClcbiAgICB2YXIgYXJyb3dEZWx0YSAgICAgICAgICA9IGlzVmVydGljYWwgPyBkZWx0YS5sZWZ0ICogMiAtIHdpZHRoICsgYWN0dWFsV2lkdGggOiBkZWx0YS50b3AgKiAyIC0gaGVpZ2h0ICsgYWN0dWFsSGVpZ2h0XG4gICAgdmFyIGFycm93T2Zmc2V0UG9zaXRpb24gPSBpc1ZlcnRpY2FsID8gJ29mZnNldFdpZHRoJyA6ICdvZmZzZXRIZWlnaHQnXG5cbiAgICAkdGlwLm9mZnNldChvZmZzZXQpXG4gICAgdGhpcy5yZXBsYWNlQXJyb3coYXJyb3dEZWx0YSwgJHRpcFswXVthcnJvd09mZnNldFBvc2l0aW9uXSwgaXNWZXJ0aWNhbClcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLnJlcGxhY2VBcnJvdyA9IGZ1bmN0aW9uIChkZWx0YSwgZGltZW5zaW9uLCBpc1ZlcnRpY2FsKSB7XG4gICAgdGhpcy5hcnJvdygpXG4gICAgICAuY3NzKGlzVmVydGljYWwgPyAnbGVmdCcgOiAndG9wJywgNTAgKiAoMSAtIGRlbHRhIC8gZGltZW5zaW9uKSArICclJylcbiAgICAgIC5jc3MoaXNWZXJ0aWNhbCA/ICd0b3AnIDogJ2xlZnQnLCAnJylcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLnNldENvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyICR0aXAgID0gdGhpcy50aXAoKVxuICAgIHZhciB0aXRsZSA9IHRoaXMuZ2V0VGl0bGUoKVxuXG4gICAgJHRpcC5maW5kKCcudG9vbHRpcC1pbm5lcicpW3RoaXMub3B0aW9ucy5odG1sID8gJ2h0bWwnIDogJ3RleHQnXSh0aXRsZSlcbiAgICAkdGlwLnJlbW92ZUNsYXNzKCdmYWRlIGluIHRvcCBib3R0b20gbGVmdCByaWdodCcpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgdmFyICR0aXAgPSAkKHRoaXMuJHRpcClcbiAgICB2YXIgZSAgICA9ICQuRXZlbnQoJ2hpZGUuYnMuJyArIHRoaXMudHlwZSlcblxuICAgIGZ1bmN0aW9uIGNvbXBsZXRlKCkge1xuICAgICAgaWYgKHRoYXQuaG92ZXJTdGF0ZSAhPSAnaW4nKSAkdGlwLmRldGFjaCgpXG4gICAgICB0aGF0LiRlbGVtZW50XG4gICAgICAgIC5yZW1vdmVBdHRyKCdhcmlhLWRlc2NyaWJlZGJ5JylcbiAgICAgICAgLnRyaWdnZXIoJ2hpZGRlbi5icy4nICsgdGhhdC50eXBlKVxuICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgIH1cblxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihlKVxuXG4gICAgaWYgKGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgJHRpcC5yZW1vdmVDbGFzcygnaW4nKVxuXG4gICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgJHRpcC5oYXNDbGFzcygnZmFkZScpID9cbiAgICAgICR0aXBcbiAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgY29tcGxldGUpXG4gICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChUb29sdGlwLlRSQU5TSVRJT05fRFVSQVRJT04pIDpcbiAgICAgIGNvbXBsZXRlKClcblxuICAgIHRoaXMuaG92ZXJTdGF0ZSA9IG51bGxcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5maXhUaXRsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJGUgPSB0aGlzLiRlbGVtZW50XG4gICAgaWYgKCRlLmF0dHIoJ3RpdGxlJykgfHwgdHlwZW9mICgkZS5hdHRyKCdkYXRhLW9yaWdpbmFsLXRpdGxlJykpICE9ICdzdHJpbmcnKSB7XG4gICAgICAkZS5hdHRyKCdkYXRhLW9yaWdpbmFsLXRpdGxlJywgJGUuYXR0cigndGl0bGUnKSB8fCAnJykuYXR0cigndGl0bGUnLCAnJylcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5oYXNDb250ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdldFRpdGxlKClcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKCRlbGVtZW50KSB7XG4gICAgJGVsZW1lbnQgICA9ICRlbGVtZW50IHx8IHRoaXMuJGVsZW1lbnRcblxuICAgIHZhciBlbCAgICAgPSAkZWxlbWVudFswXVxuICAgIHZhciBpc0JvZHkgPSBlbC50YWdOYW1lID09ICdCT0RZJ1xuXG4gICAgdmFyIGVsUmVjdCAgICA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgaWYgKGVsUmVjdC53aWR0aCA9PSBudWxsKSB7XG4gICAgICAvLyB3aWR0aCBhbmQgaGVpZ2h0IGFyZSBtaXNzaW5nIGluIElFOCwgc28gY29tcHV0ZSB0aGVtIG1hbnVhbGx5OyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2lzc3Vlcy8xNDA5M1xuICAgICAgZWxSZWN0ID0gJC5leHRlbmQoe30sIGVsUmVjdCwgeyB3aWR0aDogZWxSZWN0LnJpZ2h0IC0gZWxSZWN0LmxlZnQsIGhlaWdodDogZWxSZWN0LmJvdHRvbSAtIGVsUmVjdC50b3AgfSlcbiAgICB9XG4gICAgdmFyIGVsT2Zmc2V0ICA9IGlzQm9keSA/IHsgdG9wOiAwLCBsZWZ0OiAwIH0gOiAkZWxlbWVudC5vZmZzZXQoKVxuICAgIHZhciBzY3JvbGwgICAgPSB7IHNjcm9sbDogaXNCb2R5ID8gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCA6ICRlbGVtZW50LnNjcm9sbFRvcCgpIH1cbiAgICB2YXIgb3V0ZXJEaW1zID0gaXNCb2R5ID8geyB3aWR0aDogJCh3aW5kb3cpLndpZHRoKCksIGhlaWdodDogJCh3aW5kb3cpLmhlaWdodCgpIH0gOiBudWxsXG5cbiAgICByZXR1cm4gJC5leHRlbmQoe30sIGVsUmVjdCwgc2Nyb2xsLCBvdXRlckRpbXMsIGVsT2Zmc2V0KVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0Q2FsY3VsYXRlZE9mZnNldCA9IGZ1bmN0aW9uIChwbGFjZW1lbnQsIHBvcywgYWN0dWFsV2lkdGgsIGFjdHVhbEhlaWdodCkge1xuICAgIHJldHVybiBwbGFjZW1lbnQgPT0gJ2JvdHRvbScgPyB7IHRvcDogcG9zLnRvcCArIHBvcy5oZWlnaHQsICAgbGVmdDogcG9zLmxlZnQgKyBwb3Mud2lkdGggLyAyIC0gYWN0dWFsV2lkdGggLyAyIH0gOlxuICAgICAgICAgICBwbGFjZW1lbnQgPT0gJ3RvcCcgICAgPyB7IHRvcDogcG9zLnRvcCAtIGFjdHVhbEhlaWdodCwgbGVmdDogcG9zLmxlZnQgKyBwb3Mud2lkdGggLyAyIC0gYWN0dWFsV2lkdGggLyAyIH0gOlxuICAgICAgICAgICBwbGFjZW1lbnQgPT0gJ2xlZnQnICAgPyB7IHRvcDogcG9zLnRvcCArIHBvcy5oZWlnaHQgLyAyIC0gYWN0dWFsSGVpZ2h0IC8gMiwgbGVmdDogcG9zLmxlZnQgLSBhY3R1YWxXaWR0aCB9IDpcbiAgICAgICAgLyogcGxhY2VtZW50ID09ICdyaWdodCcgKi8geyB0b3A6IHBvcy50b3AgKyBwb3MuaGVpZ2h0IC8gMiAtIGFjdHVhbEhlaWdodCAvIDIsIGxlZnQ6IHBvcy5sZWZ0ICsgcG9zLndpZHRoIH1cblxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0Vmlld3BvcnRBZGp1c3RlZERlbHRhID0gZnVuY3Rpb24gKHBsYWNlbWVudCwgcG9zLCBhY3R1YWxXaWR0aCwgYWN0dWFsSGVpZ2h0KSB7XG4gICAgdmFyIGRlbHRhID0geyB0b3A6IDAsIGxlZnQ6IDAgfVxuICAgIGlmICghdGhpcy4kdmlld3BvcnQpIHJldHVybiBkZWx0YVxuXG4gICAgdmFyIHZpZXdwb3J0UGFkZGluZyA9IHRoaXMub3B0aW9ucy52aWV3cG9ydCAmJiB0aGlzLm9wdGlvbnMudmlld3BvcnQucGFkZGluZyB8fCAwXG4gICAgdmFyIHZpZXdwb3J0RGltZW5zaW9ucyA9IHRoaXMuZ2V0UG9zaXRpb24odGhpcy4kdmlld3BvcnQpXG5cbiAgICBpZiAoL3JpZ2h0fGxlZnQvLnRlc3QocGxhY2VtZW50KSkge1xuICAgICAgdmFyIHRvcEVkZ2VPZmZzZXQgICAgPSBwb3MudG9wIC0gdmlld3BvcnRQYWRkaW5nIC0gdmlld3BvcnREaW1lbnNpb25zLnNjcm9sbFxuICAgICAgdmFyIGJvdHRvbUVkZ2VPZmZzZXQgPSBwb3MudG9wICsgdmlld3BvcnRQYWRkaW5nIC0gdmlld3BvcnREaW1lbnNpb25zLnNjcm9sbCArIGFjdHVhbEhlaWdodFxuICAgICAgaWYgKHRvcEVkZ2VPZmZzZXQgPCB2aWV3cG9ydERpbWVuc2lvbnMudG9wKSB7IC8vIHRvcCBvdmVyZmxvd1xuICAgICAgICBkZWx0YS50b3AgPSB2aWV3cG9ydERpbWVuc2lvbnMudG9wIC0gdG9wRWRnZU9mZnNldFxuICAgICAgfSBlbHNlIGlmIChib3R0b21FZGdlT2Zmc2V0ID4gdmlld3BvcnREaW1lbnNpb25zLnRvcCArIHZpZXdwb3J0RGltZW5zaW9ucy5oZWlnaHQpIHsgLy8gYm90dG9tIG92ZXJmbG93XG4gICAgICAgIGRlbHRhLnRvcCA9IHZpZXdwb3J0RGltZW5zaW9ucy50b3AgKyB2aWV3cG9ydERpbWVuc2lvbnMuaGVpZ2h0IC0gYm90dG9tRWRnZU9mZnNldFxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbGVmdEVkZ2VPZmZzZXQgID0gcG9zLmxlZnQgLSB2aWV3cG9ydFBhZGRpbmdcbiAgICAgIHZhciByaWdodEVkZ2VPZmZzZXQgPSBwb3MubGVmdCArIHZpZXdwb3J0UGFkZGluZyArIGFjdHVhbFdpZHRoXG4gICAgICBpZiAobGVmdEVkZ2VPZmZzZXQgPCB2aWV3cG9ydERpbWVuc2lvbnMubGVmdCkgeyAvLyBsZWZ0IG92ZXJmbG93XG4gICAgICAgIGRlbHRhLmxlZnQgPSB2aWV3cG9ydERpbWVuc2lvbnMubGVmdCAtIGxlZnRFZGdlT2Zmc2V0XG4gICAgICB9IGVsc2UgaWYgKHJpZ2h0RWRnZU9mZnNldCA+IHZpZXdwb3J0RGltZW5zaW9ucy53aWR0aCkgeyAvLyByaWdodCBvdmVyZmxvd1xuICAgICAgICBkZWx0YS5sZWZ0ID0gdmlld3BvcnREaW1lbnNpb25zLmxlZnQgKyB2aWV3cG9ydERpbWVuc2lvbnMud2lkdGggLSByaWdodEVkZ2VPZmZzZXRcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGVsdGFcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldFRpdGxlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB0aXRsZVxuICAgIHZhciAkZSA9IHRoaXMuJGVsZW1lbnRcbiAgICB2YXIgbyAgPSB0aGlzLm9wdGlvbnNcblxuICAgIHRpdGxlID0gJGUuYXR0cignZGF0YS1vcmlnaW5hbC10aXRsZScpXG4gICAgICB8fCAodHlwZW9mIG8udGl0bGUgPT0gJ2Z1bmN0aW9uJyA/IG8udGl0bGUuY2FsbCgkZVswXSkgOiAgby50aXRsZSlcblxuICAgIHJldHVybiB0aXRsZVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0VUlEID0gZnVuY3Rpb24gKHByZWZpeCkge1xuICAgIGRvIHByZWZpeCArPSB+fihNYXRoLnJhbmRvbSgpICogMTAwMDAwMClcbiAgICB3aGlsZSAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocHJlZml4KSlcbiAgICByZXR1cm4gcHJlZml4XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS50aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLiR0aXAgPSB0aGlzLiR0aXAgfHwgJCh0aGlzLm9wdGlvbnMudGVtcGxhdGUpKVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuYXJyb3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLiRhcnJvdyA9IHRoaXMuJGFycm93IHx8IHRoaXMudGlwKCkuZmluZCgnLnRvb2x0aXAtYXJyb3cnKSlcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmVuYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmVuYWJsZWQgPSB0cnVlXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5kaXNhYmxlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZW5hYmxlZCA9IGZhbHNlXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS50b2dnbGVFbmFibGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZW5hYmxlZCA9ICF0aGlzLmVuYWJsZWRcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzXG4gICAgaWYgKGUpIHtcbiAgICAgIHNlbGYgPSAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSlcbiAgICAgIGlmICghc2VsZikge1xuICAgICAgICBzZWxmID0gbmV3IHRoaXMuY29uc3RydWN0b3IoZS5jdXJyZW50VGFyZ2V0LCB0aGlzLmdldERlbGVnYXRlT3B0aW9ucygpKVxuICAgICAgICAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSwgc2VsZilcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxmLnRpcCgpLmhhc0NsYXNzKCdpbicpID8gc2VsZi5sZWF2ZShzZWxmKSA6IHNlbGYuZW50ZXIoc2VsZilcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dClcbiAgICB0aGlzLmhpZGUoZnVuY3Rpb24gKCkge1xuICAgICAgdGhhdC4kZWxlbWVudC5vZmYoJy4nICsgdGhhdC50eXBlKS5yZW1vdmVEYXRhKCdicy4nICsgdGhhdC50eXBlKVxuICAgIH0pXG4gIH1cblxuXG4gIC8vIFRPT0xUSVAgUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy50b29sdGlwJylcbiAgICAgIHZhciBvcHRpb25zID0gdHlwZW9mIG9wdGlvbiA9PSAnb2JqZWN0JyAmJiBvcHRpb25cblxuICAgICAgaWYgKCFkYXRhICYmIC9kZXN0cm95fGhpZGUvLnRlc3Qob3B0aW9uKSkgcmV0dXJuXG4gICAgICBpZiAoIWRhdGEpICR0aGlzLmRhdGEoJ2JzLnRvb2x0aXAnLCAoZGF0YSA9IG5ldyBUb29sdGlwKHRoaXMsIG9wdGlvbnMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi50b29sdGlwXG5cbiAgJC5mbi50b29sdGlwICAgICAgICAgICAgID0gUGx1Z2luXG4gICQuZm4udG9vbHRpcC5Db25zdHJ1Y3RvciA9IFRvb2x0aXBcblxuXG4gIC8vIFRPT0xUSVAgTk8gQ09ORkxJQ1RcbiAgLy8gPT09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4udG9vbHRpcC5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4udG9vbHRpcCA9IG9sZFxuICAgIHJldHVybiB0aGlzXG4gIH1cblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogcG9wb3Zlci5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3BvcG92ZXJzXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gUE9QT1ZFUiBQVUJMSUMgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIFBvcG92ZXIgPSBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHRoaXMuaW5pdCgncG9wb3ZlcicsIGVsZW1lbnQsIG9wdGlvbnMpXG4gIH1cblxuICBpZiAoISQuZm4udG9vbHRpcCkgdGhyb3cgbmV3IEVycm9yKCdQb3BvdmVyIHJlcXVpcmVzIHRvb2x0aXAuanMnKVxuXG4gIFBvcG92ZXIuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgUG9wb3Zlci5ERUZBVUxUUyA9ICQuZXh0ZW5kKHt9LCAkLmZuLnRvb2x0aXAuQ29uc3RydWN0b3IuREVGQVVMVFMsIHtcbiAgICBwbGFjZW1lbnQ6ICdyaWdodCcsXG4gICAgdHJpZ2dlcjogJ2NsaWNrJyxcbiAgICBjb250ZW50OiAnJyxcbiAgICB0ZW1wbGF0ZTogJzxkaXYgY2xhc3M9XCJwb3BvdmVyXCIgcm9sZT1cInRvb2x0aXBcIj48ZGl2IGNsYXNzPVwiYXJyb3dcIj48L2Rpdj48aDMgY2xhc3M9XCJwb3BvdmVyLXRpdGxlXCI+PC9oMz48ZGl2IGNsYXNzPVwicG9wb3Zlci1jb250ZW50XCI+PC9kaXY+PC9kaXY+J1xuICB9KVxuXG5cbiAgLy8gTk9URTogUE9QT1ZFUiBFWFRFTkRTIHRvb2x0aXAuanNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBQb3BvdmVyLnByb3RvdHlwZSA9ICQuZXh0ZW5kKHt9LCAkLmZuLnRvb2x0aXAuQ29uc3RydWN0b3IucHJvdG90eXBlKVxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUG9wb3ZlclxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmdldERlZmF1bHRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBQb3BvdmVyLkRFRkFVTFRTXG4gIH1cblxuICBQb3BvdmVyLnByb3RvdHlwZS5zZXRDb250ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciAkdGlwICAgID0gdGhpcy50aXAoKVxuICAgIHZhciB0aXRsZSAgID0gdGhpcy5nZXRUaXRsZSgpXG4gICAgdmFyIGNvbnRlbnQgPSB0aGlzLmdldENvbnRlbnQoKVxuXG4gICAgJHRpcC5maW5kKCcucG9wb3Zlci10aXRsZScpW3RoaXMub3B0aW9ucy5odG1sID8gJ2h0bWwnIDogJ3RleHQnXSh0aXRsZSlcbiAgICAkdGlwLmZpbmQoJy5wb3BvdmVyLWNvbnRlbnQnKS5jaGlsZHJlbigpLmRldGFjaCgpLmVuZCgpWyAvLyB3ZSB1c2UgYXBwZW5kIGZvciBodG1sIG9iamVjdHMgdG8gbWFpbnRhaW4ganMgZXZlbnRzXG4gICAgICB0aGlzLm9wdGlvbnMuaHRtbCA/ICh0eXBlb2YgY29udGVudCA9PSAnc3RyaW5nJyA/ICdodG1sJyA6ICdhcHBlbmQnKSA6ICd0ZXh0J1xuICAgIF0oY29udGVudClcblxuICAgICR0aXAucmVtb3ZlQ2xhc3MoJ2ZhZGUgdG9wIGJvdHRvbSBsZWZ0IHJpZ2h0IGluJylcblxuICAgIC8vIElFOCBkb2Vzbid0IGFjY2VwdCBoaWRpbmcgdmlhIHRoZSBgOmVtcHR5YCBwc2V1ZG8gc2VsZWN0b3IsIHdlIGhhdmUgdG8gZG9cbiAgICAvLyB0aGlzIG1hbnVhbGx5IGJ5IGNoZWNraW5nIHRoZSBjb250ZW50cy5cbiAgICBpZiAoISR0aXAuZmluZCgnLnBvcG92ZXItdGl0bGUnKS5odG1sKCkpICR0aXAuZmluZCgnLnBvcG92ZXItdGl0bGUnKS5oaWRlKClcbiAgfVxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmhhc0NvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VGl0bGUoKSB8fCB0aGlzLmdldENvbnRlbnQoKVxuICB9XG5cbiAgUG9wb3Zlci5wcm90b3R5cGUuZ2V0Q29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJGUgPSB0aGlzLiRlbGVtZW50XG4gICAgdmFyIG8gID0gdGhpcy5vcHRpb25zXG5cbiAgICByZXR1cm4gJGUuYXR0cignZGF0YS1jb250ZW50JylcbiAgICAgIHx8ICh0eXBlb2Ygby5jb250ZW50ID09ICdmdW5jdGlvbicgP1xuICAgICAgICAgICAgby5jb250ZW50LmNhbGwoJGVbMF0pIDpcbiAgICAgICAgICAgIG8uY29udGVudClcbiAgfVxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmFycm93ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAodGhpcy4kYXJyb3cgPSB0aGlzLiRhcnJvdyB8fCB0aGlzLnRpcCgpLmZpbmQoJy5hcnJvdycpKVxuICB9XG5cblxuICAvLyBQT1BPVkVSIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICAgID0gJHRoaXMuZGF0YSgnYnMucG9wb3ZlcicpXG4gICAgICB2YXIgb3B0aW9ucyA9IHR5cGVvZiBvcHRpb24gPT0gJ29iamVjdCcgJiYgb3B0aW9uXG5cbiAgICAgIGlmICghZGF0YSAmJiAvZGVzdHJveXxoaWRlLy50ZXN0KG9wdGlvbikpIHJldHVyblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5wb3BvdmVyJywgKGRhdGEgPSBuZXcgUG9wb3Zlcih0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dKClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4ucG9wb3ZlclxuXG4gICQuZm4ucG9wb3ZlciAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLnBvcG92ZXIuQ29uc3RydWN0b3IgPSBQb3BvdmVyXG5cblxuICAvLyBQT1BPVkVSIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09PT1cblxuICAkLmZuLnBvcG92ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAkLmZuLnBvcG92ZXIgPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbn0oalF1ZXJ5KTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCb290c3RyYXA6IHNjcm9sbHNweS5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3Njcm9sbHNweVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIFNDUk9MTFNQWSBDTEFTUyBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gU2Nyb2xsU3B5KGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRib2R5ICAgICAgICAgID0gJChkb2N1bWVudC5ib2R5KVxuICAgIHRoaXMuJHNjcm9sbEVsZW1lbnQgPSAkKGVsZW1lbnQpLmlzKGRvY3VtZW50LmJvZHkpID8gJCh3aW5kb3cpIDogJChlbGVtZW50KVxuICAgIHRoaXMub3B0aW9ucyAgICAgICAgPSAkLmV4dGVuZCh7fSwgU2Nyb2xsU3B5LkRFRkFVTFRTLCBvcHRpb25zKVxuICAgIHRoaXMuc2VsZWN0b3IgICAgICAgPSAodGhpcy5vcHRpb25zLnRhcmdldCB8fCAnJykgKyAnIC5uYXYgbGkgPiBhJ1xuICAgIHRoaXMub2Zmc2V0cyAgICAgICAgPSBbXVxuICAgIHRoaXMudGFyZ2V0cyAgICAgICAgPSBbXVxuICAgIHRoaXMuYWN0aXZlVGFyZ2V0ICAgPSBudWxsXG4gICAgdGhpcy5zY3JvbGxIZWlnaHQgICA9IDBcblxuICAgIHRoaXMuJHNjcm9sbEVsZW1lbnQub24oJ3Njcm9sbC5icy5zY3JvbGxzcHknLCAkLnByb3h5KHRoaXMucHJvY2VzcywgdGhpcykpXG4gICAgdGhpcy5yZWZyZXNoKClcbiAgICB0aGlzLnByb2Nlc3MoKVxuICB9XG5cbiAgU2Nyb2xsU3B5LlZFUlNJT04gID0gJzMuMy40J1xuXG4gIFNjcm9sbFNweS5ERUZBVUxUUyA9IHtcbiAgICBvZmZzZXQ6IDEwXG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLmdldFNjcm9sbEhlaWdodCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy4kc2Nyb2xsRWxlbWVudFswXS5zY3JvbGxIZWlnaHQgfHwgTWF0aC5tYXgodGhpcy4kYm9keVswXS5zY3JvbGxIZWlnaHQsIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxIZWlnaHQpXG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRoYXQgICAgICAgICAgPSB0aGlzXG4gICAgdmFyIG9mZnNldE1ldGhvZCAgPSAnb2Zmc2V0J1xuICAgIHZhciBvZmZzZXRCYXNlICAgID0gMFxuXG4gICAgdGhpcy5vZmZzZXRzICAgICAgPSBbXVxuICAgIHRoaXMudGFyZ2V0cyAgICAgID0gW11cbiAgICB0aGlzLnNjcm9sbEhlaWdodCA9IHRoaXMuZ2V0U2Nyb2xsSGVpZ2h0KClcblxuICAgIGlmICghJC5pc1dpbmRvdyh0aGlzLiRzY3JvbGxFbGVtZW50WzBdKSkge1xuICAgICAgb2Zmc2V0TWV0aG9kID0gJ3Bvc2l0aW9uJ1xuICAgICAgb2Zmc2V0QmFzZSAgID0gdGhpcy4kc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AoKVxuICAgIH1cblxuICAgIHRoaXMuJGJvZHlcbiAgICAgIC5maW5kKHRoaXMuc2VsZWN0b3IpXG4gICAgICAubWFwKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyICRlbCAgID0gJCh0aGlzKVxuICAgICAgICB2YXIgaHJlZiAgPSAkZWwuZGF0YSgndGFyZ2V0JykgfHwgJGVsLmF0dHIoJ2hyZWYnKVxuICAgICAgICB2YXIgJGhyZWYgPSAvXiMuLy50ZXN0KGhyZWYpICYmICQoaHJlZilcblxuICAgICAgICByZXR1cm4gKCRocmVmXG4gICAgICAgICAgJiYgJGhyZWYubGVuZ3RoXG4gICAgICAgICAgJiYgJGhyZWYuaXMoJzp2aXNpYmxlJylcbiAgICAgICAgICAmJiBbWyRocmVmW29mZnNldE1ldGhvZF0oKS50b3AgKyBvZmZzZXRCYXNlLCBocmVmXV0pIHx8IG51bGxcbiAgICAgIH0pXG4gICAgICAuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYVswXSAtIGJbMF0gfSlcbiAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhhdC5vZmZzZXRzLnB1c2godGhpc1swXSlcbiAgICAgICAgdGhhdC50YXJnZXRzLnB1c2godGhpc1sxXSlcbiAgICAgIH0pXG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjcm9sbFRvcCAgICA9IHRoaXMuJHNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wKCkgKyB0aGlzLm9wdGlvbnMub2Zmc2V0XG4gICAgdmFyIHNjcm9sbEhlaWdodCA9IHRoaXMuZ2V0U2Nyb2xsSGVpZ2h0KClcbiAgICB2YXIgbWF4U2Nyb2xsICAgID0gdGhpcy5vcHRpb25zLm9mZnNldCArIHNjcm9sbEhlaWdodCAtIHRoaXMuJHNjcm9sbEVsZW1lbnQuaGVpZ2h0KClcbiAgICB2YXIgb2Zmc2V0cyAgICAgID0gdGhpcy5vZmZzZXRzXG4gICAgdmFyIHRhcmdldHMgICAgICA9IHRoaXMudGFyZ2V0c1xuICAgIHZhciBhY3RpdmVUYXJnZXQgPSB0aGlzLmFjdGl2ZVRhcmdldFxuICAgIHZhciBpXG5cbiAgICBpZiAodGhpcy5zY3JvbGxIZWlnaHQgIT0gc2Nyb2xsSGVpZ2h0KSB7XG4gICAgICB0aGlzLnJlZnJlc2goKVxuICAgIH1cblxuICAgIGlmIChzY3JvbGxUb3AgPj0gbWF4U2Nyb2xsKSB7XG4gICAgICByZXR1cm4gYWN0aXZlVGFyZ2V0ICE9IChpID0gdGFyZ2V0c1t0YXJnZXRzLmxlbmd0aCAtIDFdKSAmJiB0aGlzLmFjdGl2YXRlKGkpXG4gICAgfVxuXG4gICAgaWYgKGFjdGl2ZVRhcmdldCAmJiBzY3JvbGxUb3AgPCBvZmZzZXRzWzBdKSB7XG4gICAgICB0aGlzLmFjdGl2ZVRhcmdldCA9IG51bGxcbiAgICAgIHJldHVybiB0aGlzLmNsZWFyKClcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBvZmZzZXRzLmxlbmd0aDsgaS0tOykge1xuICAgICAgYWN0aXZlVGFyZ2V0ICE9IHRhcmdldHNbaV1cbiAgICAgICAgJiYgc2Nyb2xsVG9wID49IG9mZnNldHNbaV1cbiAgICAgICAgJiYgKG9mZnNldHNbaSArIDFdID09PSB1bmRlZmluZWQgfHwgc2Nyb2xsVG9wIDwgb2Zmc2V0c1tpICsgMV0pXG4gICAgICAgICYmIHRoaXMuYWN0aXZhdGUodGFyZ2V0c1tpXSlcbiAgICB9XG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLmFjdGl2YXRlID0gZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIHRoaXMuYWN0aXZlVGFyZ2V0ID0gdGFyZ2V0XG5cbiAgICB0aGlzLmNsZWFyKClcblxuICAgIHZhciBzZWxlY3RvciA9IHRoaXMuc2VsZWN0b3IgK1xuICAgICAgJ1tkYXRhLXRhcmdldD1cIicgKyB0YXJnZXQgKyAnXCJdLCcgK1xuICAgICAgdGhpcy5zZWxlY3RvciArICdbaHJlZj1cIicgKyB0YXJnZXQgKyAnXCJdJ1xuXG4gICAgdmFyIGFjdGl2ZSA9ICQoc2VsZWN0b3IpXG4gICAgICAucGFyZW50cygnbGknKVxuICAgICAgLmFkZENsYXNzKCdhY3RpdmUnKVxuXG4gICAgaWYgKGFjdGl2ZS5wYXJlbnQoJy5kcm9wZG93bi1tZW51JykubGVuZ3RoKSB7XG4gICAgICBhY3RpdmUgPSBhY3RpdmVcbiAgICAgICAgLmNsb3Nlc3QoJ2xpLmRyb3Bkb3duJylcbiAgICAgICAgLmFkZENsYXNzKCdhY3RpdmUnKVxuICAgIH1cblxuICAgIGFjdGl2ZS50cmlnZ2VyKCdhY3RpdmF0ZS5icy5zY3JvbGxzcHknKVxuICB9XG5cbiAgU2Nyb2xsU3B5LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAkKHRoaXMuc2VsZWN0b3IpXG4gICAgICAucGFyZW50c1VudGlsKHRoaXMub3B0aW9ucy50YXJnZXQsICcuYWN0aXZlJylcbiAgICAgIC5yZW1vdmVDbGFzcygnYWN0aXZlJylcbiAgfVxuXG5cbiAgLy8gU0NST0xMU1BZIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5zY3JvbGxzcHknKVxuICAgICAgdmFyIG9wdGlvbnMgPSB0eXBlb2Ygb3B0aW9uID09ICdvYmplY3QnICYmIG9wdGlvblxuXG4gICAgICBpZiAoIWRhdGEpICR0aGlzLmRhdGEoJ2JzLnNjcm9sbHNweScsIChkYXRhID0gbmV3IFNjcm9sbFNweSh0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dKClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4uc2Nyb2xsc3B5XG5cbiAgJC5mbi5zY3JvbGxzcHkgICAgICAgICAgICAgPSBQbHVnaW5cbiAgJC5mbi5zY3JvbGxzcHkuQ29uc3RydWN0b3IgPSBTY3JvbGxTcHlcblxuXG4gIC8vIFNDUk9MTFNQWSBOTyBDT05GTElDVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT1cblxuICAkLmZuLnNjcm9sbHNweS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4uc2Nyb2xsc3B5ID0gb2xkXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gU0NST0xMU1BZIERBVEEtQVBJXG4gIC8vID09PT09PT09PT09PT09PT09PVxuXG4gICQod2luZG93KS5vbignbG9hZC5icy5zY3JvbGxzcHkuZGF0YS1hcGknLCBmdW5jdGlvbiAoKSB7XG4gICAgJCgnW2RhdGEtc3B5PVwic2Nyb2xsXCJdJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHNweSA9ICQodGhpcylcbiAgICAgIFBsdWdpbi5jYWxsKCRzcHksICRzcHkuZGF0YSgpKVxuICAgIH0pXG4gIH0pXG5cbn0oalF1ZXJ5KTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCb290c3RyYXA6IHRhYi5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3RhYnNcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weXJpZ2h0IDIwMTEtMjAxNSBUd2l0dGVyLCBJbmMuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cblxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBUQUIgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBUYWIgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHRoaXMuZWxlbWVudCA9ICQoZWxlbWVudClcbiAgfVxuXG4gIFRhYi5WRVJTSU9OID0gJzMuMy40J1xuXG4gIFRhYi5UUkFOU0lUSU9OX0RVUkFUSU9OID0gMTUwXG5cbiAgVGFiLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciAkdGhpcyAgICA9IHRoaXMuZWxlbWVudFxuICAgIHZhciAkdWwgICAgICA9ICR0aGlzLmNsb3Nlc3QoJ3VsOm5vdCguZHJvcGRvd24tbWVudSknKVxuICAgIHZhciBzZWxlY3RvciA9ICR0aGlzLmRhdGEoJ3RhcmdldCcpXG5cbiAgICBpZiAoIXNlbGVjdG9yKSB7XG4gICAgICBzZWxlY3RvciA9ICR0aGlzLmF0dHIoJ2hyZWYnKVxuICAgICAgc2VsZWN0b3IgPSBzZWxlY3RvciAmJiBzZWxlY3Rvci5yZXBsYWNlKC8uKig/PSNbXlxcc10qJCkvLCAnJykgLy8gc3RyaXAgZm9yIGllN1xuICAgIH1cblxuICAgIGlmICgkdGhpcy5wYXJlbnQoJ2xpJykuaGFzQ2xhc3MoJ2FjdGl2ZScpKSByZXR1cm5cblxuICAgIHZhciAkcHJldmlvdXMgPSAkdWwuZmluZCgnLmFjdGl2ZTpsYXN0IGEnKVxuICAgIHZhciBoaWRlRXZlbnQgPSAkLkV2ZW50KCdoaWRlLmJzLnRhYicsIHtcbiAgICAgIHJlbGF0ZWRUYXJnZXQ6ICR0aGlzWzBdXG4gICAgfSlcbiAgICB2YXIgc2hvd0V2ZW50ID0gJC5FdmVudCgnc2hvdy5icy50YWInLCB7XG4gICAgICByZWxhdGVkVGFyZ2V0OiAkcHJldmlvdXNbMF1cbiAgICB9KVxuXG4gICAgJHByZXZpb3VzLnRyaWdnZXIoaGlkZUV2ZW50KVxuICAgICR0aGlzLnRyaWdnZXIoc2hvd0V2ZW50KVxuXG4gICAgaWYgKHNob3dFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSB8fCBoaWRlRXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgdmFyICR0YXJnZXQgPSAkKHNlbGVjdG9yKVxuXG4gICAgdGhpcy5hY3RpdmF0ZSgkdGhpcy5jbG9zZXN0KCdsaScpLCAkdWwpXG4gICAgdGhpcy5hY3RpdmF0ZSgkdGFyZ2V0LCAkdGFyZ2V0LnBhcmVudCgpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAkcHJldmlvdXMudHJpZ2dlcih7XG4gICAgICAgIHR5cGU6ICdoaWRkZW4uYnMudGFiJyxcbiAgICAgICAgcmVsYXRlZFRhcmdldDogJHRoaXNbMF1cbiAgICAgIH0pXG4gICAgICAkdGhpcy50cmlnZ2VyKHtcbiAgICAgICAgdHlwZTogJ3Nob3duLmJzLnRhYicsXG4gICAgICAgIHJlbGF0ZWRUYXJnZXQ6ICRwcmV2aW91c1swXVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgVGFiLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uIChlbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gICAgdmFyICRhY3RpdmUgICAgPSBjb250YWluZXIuZmluZCgnPiAuYWN0aXZlJylcbiAgICB2YXIgdHJhbnNpdGlvbiA9IGNhbGxiYWNrXG4gICAgICAmJiAkLnN1cHBvcnQudHJhbnNpdGlvblxuICAgICAgJiYgKCgkYWN0aXZlLmxlbmd0aCAmJiAkYWN0aXZlLmhhc0NsYXNzKCdmYWRlJykpIHx8ICEhY29udGFpbmVyLmZpbmQoJz4gLmZhZGUnKS5sZW5ndGgpXG5cbiAgICBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgJGFjdGl2ZVxuICAgICAgICAucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgIC5maW5kKCc+IC5kcm9wZG93bi1tZW51ID4gLmFjdGl2ZScpXG4gICAgICAgICAgLnJlbW92ZUNsYXNzKCdhY3RpdmUnKVxuICAgICAgICAuZW5kKClcbiAgICAgICAgLmZpbmQoJ1tkYXRhLXRvZ2dsZT1cInRhYlwiXScpXG4gICAgICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCBmYWxzZSlcblxuICAgICAgZWxlbWVudFxuICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgIC5maW5kKCdbZGF0YS10b2dnbGU9XCJ0YWJcIl0nKVxuICAgICAgICAgIC5hdHRyKCdhcmlhLWV4cGFuZGVkJywgdHJ1ZSlcblxuICAgICAgaWYgKHRyYW5zaXRpb24pIHtcbiAgICAgICAgZWxlbWVudFswXS5vZmZzZXRXaWR0aCAvLyByZWZsb3cgZm9yIHRyYW5zaXRpb25cbiAgICAgICAgZWxlbWVudC5hZGRDbGFzcygnaW4nKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVDbGFzcygnZmFkZScpXG4gICAgICB9XG5cbiAgICAgIGlmIChlbGVtZW50LnBhcmVudCgnLmRyb3Bkb3duLW1lbnUnKS5sZW5ndGgpIHtcbiAgICAgICAgZWxlbWVudFxuICAgICAgICAgIC5jbG9zZXN0KCdsaS5kcm9wZG93bicpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgICAgLmVuZCgpXG4gICAgICAgICAgLmZpbmQoJ1tkYXRhLXRvZ2dsZT1cInRhYlwiXScpXG4gICAgICAgICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIHRydWUpXG4gICAgICB9XG5cbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKClcbiAgICB9XG5cbiAgICAkYWN0aXZlLmxlbmd0aCAmJiB0cmFuc2l0aW9uID9cbiAgICAgICRhY3RpdmVcbiAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgbmV4dClcbiAgICAgICAgLmVtdWxhdGVUcmFuc2l0aW9uRW5kKFRhYi5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICBuZXh0KClcblxuICAgICRhY3RpdmUucmVtb3ZlQ2xhc3MoJ2luJylcbiAgfVxuXG5cbiAgLy8gVEFCIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICA9ICR0aGlzLmRhdGEoJ2JzLnRhYicpXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMudGFiJywgKGRhdGEgPSBuZXcgVGFiKHRoaXMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi50YWJcblxuICAkLmZuLnRhYiAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLnRhYi5Db25zdHJ1Y3RvciA9IFRhYlxuXG5cbiAgLy8gVEFCIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PVxuXG4gICQuZm4udGFiLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi50YWIgPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBUQUIgREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09XG5cbiAgdmFyIGNsaWNrSGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgUGx1Z2luLmNhbGwoJCh0aGlzKSwgJ3Nob3cnKVxuICB9XG5cbiAgJChkb2N1bWVudClcbiAgICAub24oJ2NsaWNrLmJzLnRhYi5kYXRhLWFwaScsICdbZGF0YS10b2dnbGU9XCJ0YWJcIl0nLCBjbGlja0hhbmRsZXIpXG4gICAgLm9uKCdjbGljay5icy50YWIuZGF0YS1hcGknLCAnW2RhdGEtdG9nZ2xlPVwicGlsbFwiXScsIGNsaWNrSGFuZGxlcilcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogYWZmaXguanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyNhZmZpeFxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIEFGRklYIENMQVNTIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBBZmZpeCA9IGZ1bmN0aW9uIChlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIEFmZml4LkRFRkFVTFRTLCBvcHRpb25zKVxuXG4gICAgdGhpcy4kdGFyZ2V0ID0gJCh0aGlzLm9wdGlvbnMudGFyZ2V0KVxuICAgICAgLm9uKCdzY3JvbGwuYnMuYWZmaXguZGF0YS1hcGknLCAkLnByb3h5KHRoaXMuY2hlY2tQb3NpdGlvbiwgdGhpcykpXG4gICAgICAub24oJ2NsaWNrLmJzLmFmZml4LmRhdGEtYXBpJywgICQucHJveHkodGhpcy5jaGVja1Bvc2l0aW9uV2l0aEV2ZW50TG9vcCwgdGhpcykpXG5cbiAgICB0aGlzLiRlbGVtZW50ICAgICA9ICQoZWxlbWVudClcbiAgICB0aGlzLmFmZml4ZWQgICAgICA9IG51bGxcbiAgICB0aGlzLnVucGluICAgICAgICA9IG51bGxcbiAgICB0aGlzLnBpbm5lZE9mZnNldCA9IG51bGxcblxuICAgIHRoaXMuY2hlY2tQb3NpdGlvbigpXG4gIH1cblxuICBBZmZpeC5WRVJTSU9OICA9ICczLjMuNCdcblxuICBBZmZpeC5SRVNFVCAgICA9ICdhZmZpeCBhZmZpeC10b3AgYWZmaXgtYm90dG9tJ1xuXG4gIEFmZml4LkRFRkFVTFRTID0ge1xuICAgIG9mZnNldDogMCxcbiAgICB0YXJnZXQ6IHdpbmRvd1xuICB9XG5cbiAgQWZmaXgucHJvdG90eXBlLmdldFN0YXRlID0gZnVuY3Rpb24gKHNjcm9sbEhlaWdodCwgaGVpZ2h0LCBvZmZzZXRUb3AsIG9mZnNldEJvdHRvbSkge1xuICAgIHZhciBzY3JvbGxUb3AgICAgPSB0aGlzLiR0YXJnZXQuc2Nyb2xsVG9wKClcbiAgICB2YXIgcG9zaXRpb24gICAgID0gdGhpcy4kZWxlbWVudC5vZmZzZXQoKVxuICAgIHZhciB0YXJnZXRIZWlnaHQgPSB0aGlzLiR0YXJnZXQuaGVpZ2h0KClcblxuICAgIGlmIChvZmZzZXRUb3AgIT0gbnVsbCAmJiB0aGlzLmFmZml4ZWQgPT0gJ3RvcCcpIHJldHVybiBzY3JvbGxUb3AgPCBvZmZzZXRUb3AgPyAndG9wJyA6IGZhbHNlXG5cbiAgICBpZiAodGhpcy5hZmZpeGVkID09ICdib3R0b20nKSB7XG4gICAgICBpZiAob2Zmc2V0VG9wICE9IG51bGwpIHJldHVybiAoc2Nyb2xsVG9wICsgdGhpcy51bnBpbiA8PSBwb3NpdGlvbi50b3ApID8gZmFsc2UgOiAnYm90dG9tJ1xuICAgICAgcmV0dXJuIChzY3JvbGxUb3AgKyB0YXJnZXRIZWlnaHQgPD0gc2Nyb2xsSGVpZ2h0IC0gb2Zmc2V0Qm90dG9tKSA/IGZhbHNlIDogJ2JvdHRvbSdcbiAgICB9XG5cbiAgICB2YXIgaW5pdGlhbGl6aW5nICAgPSB0aGlzLmFmZml4ZWQgPT0gbnVsbFxuICAgIHZhciBjb2xsaWRlclRvcCAgICA9IGluaXRpYWxpemluZyA/IHNjcm9sbFRvcCA6IHBvc2l0aW9uLnRvcFxuICAgIHZhciBjb2xsaWRlckhlaWdodCA9IGluaXRpYWxpemluZyA/IHRhcmdldEhlaWdodCA6IGhlaWdodFxuXG4gICAgaWYgKG9mZnNldFRvcCAhPSBudWxsICYmIHNjcm9sbFRvcCA8PSBvZmZzZXRUb3ApIHJldHVybiAndG9wJ1xuICAgIGlmIChvZmZzZXRCb3R0b20gIT0gbnVsbCAmJiAoY29sbGlkZXJUb3AgKyBjb2xsaWRlckhlaWdodCA+PSBzY3JvbGxIZWlnaHQgLSBvZmZzZXRCb3R0b20pKSByZXR1cm4gJ2JvdHRvbSdcblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgQWZmaXgucHJvdG90eXBlLmdldFBpbm5lZE9mZnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5waW5uZWRPZmZzZXQpIHJldHVybiB0aGlzLnBpbm5lZE9mZnNldFxuICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MoQWZmaXguUkVTRVQpLmFkZENsYXNzKCdhZmZpeCcpXG4gICAgdmFyIHNjcm9sbFRvcCA9IHRoaXMuJHRhcmdldC5zY3JvbGxUb3AoKVxuICAgIHZhciBwb3NpdGlvbiAgPSB0aGlzLiRlbGVtZW50Lm9mZnNldCgpXG4gICAgcmV0dXJuICh0aGlzLnBpbm5lZE9mZnNldCA9IHBvc2l0aW9uLnRvcCAtIHNjcm9sbFRvcClcbiAgfVxuXG4gIEFmZml4LnByb3RvdHlwZS5jaGVja1Bvc2l0aW9uV2l0aEV2ZW50TG9vcCA9IGZ1bmN0aW9uICgpIHtcbiAgICBzZXRUaW1lb3V0KCQucHJveHkodGhpcy5jaGVja1Bvc2l0aW9uLCB0aGlzKSwgMSlcbiAgfVxuXG4gIEFmZml4LnByb3RvdHlwZS5jaGVja1Bvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy4kZWxlbWVudC5pcygnOnZpc2libGUnKSkgcmV0dXJuXG5cbiAgICB2YXIgaGVpZ2h0ICAgICAgID0gdGhpcy4kZWxlbWVudC5oZWlnaHQoKVxuICAgIHZhciBvZmZzZXQgICAgICAgPSB0aGlzLm9wdGlvbnMub2Zmc2V0XG4gICAgdmFyIG9mZnNldFRvcCAgICA9IG9mZnNldC50b3BcbiAgICB2YXIgb2Zmc2V0Qm90dG9tID0gb2Zmc2V0LmJvdHRvbVxuICAgIHZhciBzY3JvbGxIZWlnaHQgPSAkKGRvY3VtZW50LmJvZHkpLmhlaWdodCgpXG5cbiAgICBpZiAodHlwZW9mIG9mZnNldCAhPSAnb2JqZWN0JykgICAgICAgICBvZmZzZXRCb3R0b20gPSBvZmZzZXRUb3AgPSBvZmZzZXRcbiAgICBpZiAodHlwZW9mIG9mZnNldFRvcCA9PSAnZnVuY3Rpb24nKSAgICBvZmZzZXRUb3AgICAgPSBvZmZzZXQudG9wKHRoaXMuJGVsZW1lbnQpXG4gICAgaWYgKHR5cGVvZiBvZmZzZXRCb3R0b20gPT0gJ2Z1bmN0aW9uJykgb2Zmc2V0Qm90dG9tID0gb2Zmc2V0LmJvdHRvbSh0aGlzLiRlbGVtZW50KVxuXG4gICAgdmFyIGFmZml4ID0gdGhpcy5nZXRTdGF0ZShzY3JvbGxIZWlnaHQsIGhlaWdodCwgb2Zmc2V0VG9wLCBvZmZzZXRCb3R0b20pXG5cbiAgICBpZiAodGhpcy5hZmZpeGVkICE9IGFmZml4KSB7XG4gICAgICBpZiAodGhpcy51bnBpbiAhPSBudWxsKSB0aGlzLiRlbGVtZW50LmNzcygndG9wJywgJycpXG5cbiAgICAgIHZhciBhZmZpeFR5cGUgPSAnYWZmaXgnICsgKGFmZml4ID8gJy0nICsgYWZmaXggOiAnJylcbiAgICAgIHZhciBlICAgICAgICAgPSAkLkV2ZW50KGFmZml4VHlwZSArICcuYnMuYWZmaXgnKVxuXG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoZSlcblxuICAgICAgaWYgKGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgICB0aGlzLmFmZml4ZWQgPSBhZmZpeFxuICAgICAgdGhpcy51bnBpbiA9IGFmZml4ID09ICdib3R0b20nID8gdGhpcy5nZXRQaW5uZWRPZmZzZXQoKSA6IG51bGxcblxuICAgICAgdGhpcy4kZWxlbWVudFxuICAgICAgICAucmVtb3ZlQ2xhc3MoQWZmaXguUkVTRVQpXG4gICAgICAgIC5hZGRDbGFzcyhhZmZpeFR5cGUpXG4gICAgICAgIC50cmlnZ2VyKGFmZml4VHlwZS5yZXBsYWNlKCdhZmZpeCcsICdhZmZpeGVkJykgKyAnLmJzLmFmZml4JylcbiAgICB9XG5cbiAgICBpZiAoYWZmaXggPT0gJ2JvdHRvbScpIHtcbiAgICAgIHRoaXMuJGVsZW1lbnQub2Zmc2V0KHtcbiAgICAgICAgdG9wOiBzY3JvbGxIZWlnaHQgLSBoZWlnaHQgLSBvZmZzZXRCb3R0b21cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cblxuICAvLyBBRkZJWCBQTFVHSU4gREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5hZmZpeCcpXG4gICAgICB2YXIgb3B0aW9ucyA9IHR5cGVvZiBvcHRpb24gPT0gJ29iamVjdCcgJiYgb3B0aW9uXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuYWZmaXgnLCAoZGF0YSA9IG5ldyBBZmZpeCh0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dKClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4uYWZmaXhcblxuICAkLmZuLmFmZml4ICAgICAgICAgICAgID0gUGx1Z2luXG4gICQuZm4uYWZmaXguQ29uc3RydWN0b3IgPSBBZmZpeFxuXG5cbiAgLy8gQUZGSVggTk8gQ09ORkxJQ1RcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICAkLmZuLmFmZml4Lm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi5hZmZpeCA9IG9sZFxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuXG4gIC8vIEFGRklYIERBVEEtQVBJXG4gIC8vID09PT09PT09PT09PT09XG5cbiAgJCh3aW5kb3cpLm9uKCdsb2FkJywgZnVuY3Rpb24gKCkge1xuICAgICQoJ1tkYXRhLXNweT1cImFmZml4XCJdJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHNweSA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhID0gJHNweS5kYXRhKClcblxuICAgICAgZGF0YS5vZmZzZXQgPSBkYXRhLm9mZnNldCB8fCB7fVxuXG4gICAgICBpZiAoZGF0YS5vZmZzZXRCb3R0b20gIT0gbnVsbCkgZGF0YS5vZmZzZXQuYm90dG9tID0gZGF0YS5vZmZzZXRCb3R0b21cbiAgICAgIGlmIChkYXRhLm9mZnNldFRvcCAgICAhPSBudWxsKSBkYXRhLm9mZnNldC50b3AgICAgPSBkYXRhLm9mZnNldFRvcFxuXG4gICAgICBQbHVnaW4uY2FsbCgkc3B5LCBkYXRhKVxuICAgIH0pXG4gIH0pXG5cbn0oalF1ZXJ5KTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9ib290c3RyYXAtbGVzcy9qcy9ib290c3RyYXAuanNcbi8vIG1vZHVsZSBpZCA9IDIwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0="); /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { -eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n\\n\", \"\", {\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\",\"file\":\"alert.vue\",\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvYWxlcnQudnVlPzIxNTgiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG5cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W10sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIlwiLFwiZmlsZVwiOlwiYWxlcnQudnVlXCIsXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi0zZWRlZjNiYVwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2FsZXJ0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.action-link[data-v-225778c2] {\\n cursor: pointer;\\n}\\n.m-b-none[data-v-225778c2] {\\n margin-bottom: 0;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/passport/PersonalAccessTokens.vue?5734f4e4\"],\"names\":[],\"mappings\":\";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA\",\"file\":\"PersonalAccessTokens.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlP2FkYzQiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4uYWN0aW9uLWxpbmtbZGF0YS12LTIyNTc3OGMyXSB7XFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLm0tYi1ub25lW2RhdGEtdi0yMjU3NzhjMl0ge1xcbiAgICBtYXJnaW4tYm90dG9tOiAwO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4uLy4uLy4uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWU/NTczNGY0ZTRcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsaUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxuICAgIC5hY3Rpb24tbGluayB7XFxuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XFxuICAgIH1cXG5cXG4gICAgLm0tYi1ub25lIHtcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICAgIH1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXY+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwgcGFuZWwtZGVmYXVsdFxcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsLWhlYWRpbmdcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cXFwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyBhbGlnbi1pdGVtczogY2VudGVyO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlcnNvbmFsIEFjY2VzcyBUb2tlbnNcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XFxcImFjdGlvbi1saW5rXFxcIiBAY2xpY2s9XFxcInNob3dDcmVhdGVUb2tlbkZvcm1cXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGUgTmV3IFRva2VuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1ib2R5XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTm8gVG9rZW5zIE5vdGljZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVxcXCJtLWItbm9uZVxcXCIgdi1pZj1cXFwidG9rZW5zLmxlbmd0aCA9PT0gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgWW91IGhhdmUgbm90IGNyZWF0ZWQgYW55IHBlcnNvbmFsIGFjY2VzcyB0b2tlbnMuXFxuICAgICAgICAgICAgICAgICAgICA8L3A+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8IS0tIFBlcnNvbmFsIEFjY2VzcyBUb2tlbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XFxcInRhYmxlIHRhYmxlLWJvcmRlcmxlc3MgbS1iLW5vbmVcXFwiIHYtaWY9XFxcInRva2Vucy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5OYW1lPC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD48L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgdi1mb3I9XFxcInRva2VuIGluIHRva2Vuc1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENsaWVudCBOYW1lIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdG9rZW4ubmFtZSB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRGVsZXRlIEJ1dHRvbiAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclxcXCIgQGNsaWNrPVxcXCJyZXZva2UodG9rZW4pXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgIDwhLS0gQ3JlYXRlIFRva2VuIE1vZGFsIC0tPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwgZmFkZVxcXCIgaWQ9XFxcIm1vZGFsLWNyZWF0ZS10b2tlblxcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIiByb2xlPVxcXCJkaWFsb2dcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvbiBcXFwiIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiPiZ0aW1lczs8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIFRva2VuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9oND5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtIEVycm9ycyAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhbGVydCBhbGVydC1kYW5nZXJcXFwiIHYtaWY9XFxcImZvcm0uZXJyb3JzLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD48c3Ryb25nPldob29wcyE8L3N0cm9uZz4gU29tZXRoaW5nIHdlbnQgd3JvbmchPC9wPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSB2LWZvcj1cXFwiZXJyb3IgaW4gZm9ybS5lcnJvcnNcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVycm9yIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRlIFRva2VuIEZvcm0gLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGZvcm0gY2xhc3M9XFxcImZvcm0taG9yaXpvbnRhbFxcXCIgcm9sZT1cXFwiZm9ybVxcXCIgQHN1Ym1pdC5wcmV2ZW50PVxcXCJzdG9yZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZm9ybS1ncm91cFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC00IGNvbnRyb2wtbGFiZWxcXFwiPk5hbWU8L2xhYmVsPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTZcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cXFwiY3JlYXRlLXRva2VuLW5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIG5hbWU9XFxcIm5hbWVcXFwiIHYtbW9kZWw9XFxcImZvcm0ubmFtZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gU2NvcGVzIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIiB2LWlmPVxcXCJzY29wZXMubGVuZ3RoID4gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC00IGNvbnRyb2wtbGFiZWxcXFwiPlNjb3BlczwvbGFiZWw+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNlxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiB2LWZvcj1cXFwic2NvcGUgaW4gc2NvcGVzXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY2hlY2tib3hcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVxcXCJjaGVja2JveFxcXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGNsaWNrPVxcXCJ0b2dnbGVTY29wZShzY29wZS5pZClcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDpjaGVja2VkPVxcXCJzY29wZUlzQXNzaWduZWQoc2NvcGUuaWQpXFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgc2NvcGUuaWQgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNb2RhbCBBY3Rpb25zIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtZm9vdGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tZGVmYXVsdFxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCI+Q2xvc2U8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tcHJpbWFyeVxcXCIgQGNsaWNrPVxcXCJzdG9yZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZVxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICA8IS0tIEFjY2VzcyBUb2tlbiBNb2RhbCAtLT5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsIGZhZGVcXFwiIGlkPVxcXCJtb2RhbC1hY2Nlc3MtdG9rZW5cXFwiIHRhYmluZGV4PVxcXCItMVxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIj5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1kaWFsb2dcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1jb250ZW50XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b24gXFxcIiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj4mdGltZXM7PC9idXR0b24+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVxcXCJtb2RhbC10aXRsZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlcnNvbmFsIEFjY2VzcyBUb2tlblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaDQ+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIZXJlIGlzIHlvdXIgbmV3IHBlcnNvbmFsIGFjY2VzcyB0b2tlbi4gVGhpcyBpcyB0aGUgb25seSB0aW1lIGl0IHdpbGwgYmUgc2hvd24gc28gZG9uJ3QgbG9zZSBpdCFcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWW91IG1heSBub3cgdXNlIHRoaXMgdG9rZW4gdG8gbWFrZSBBUEkgcmVxdWVzdHMuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwcmU+PGNvZGU+e3sgYWNjZXNzVG9rZW4gfX08L2NvZGU+PC9wcmU+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTW9kYWwgQWN0aW9ucyAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWZvb3RlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiPkNsb3NlPC9idXR0b24+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC90ZW1wbGF0ZT5cXG5cXG48c2NyaXB0PlxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgICAvKlxcbiAgICAgICAgICogVGhlIGNvbXBvbmVudCdzIGRhdGEuXFxuICAgICAgICAgKi9cXG4gICAgICAgIGRhdGEoKSB7XFxuICAgICAgICAgICAgcmV0dXJuIHtcXG4gICAgICAgICAgICAgICAgYWNjZXNzVG9rZW46IG51bGwsXFxuXFxuICAgICAgICAgICAgICAgIHRva2VuczogW10sXFxuICAgICAgICAgICAgICAgIHNjb3BlczogW10sXFxuXFxuICAgICAgICAgICAgICAgIGZvcm06IHtcXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICcnLFxcbiAgICAgICAgICAgICAgICAgICAgc2NvcGVzOiBbXSxcXG4gICAgICAgICAgICAgICAgICAgIGVycm9yczogW11cXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICByZWFkeSgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBwcmVwYXJlQ29tcG9uZW50KCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldFRva2VucygpO1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldFNjb3BlcygpO1xcblxcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLXRva2VuJykub24oJ3Nob3duLmJzLm1vZGFsJywgKCkgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgJCgnI2NyZWF0ZS10b2tlbi1uYW1lJykuZm9jdXMoKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBwZXJzb25hbCBhY2Nlc3MgdG9rZW5zIGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBnZXRUb2tlbnMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KCcvb2F1dGgvcGVyc29uYWwtYWNjZXNzLXRva2VucycpXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRva2VucyA9IHJlc3BvbnNlLmRhdGE7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBhdmFpbGFibGUgc2NvcGVzLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIGdldFNjb3BlcygpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9vYXV0aC9zY29wZXMnKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY29wZXMgPSByZXNwb25zZS5kYXRhO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogU2hvdyB0aGUgZm9ybSBmb3IgY3JlYXRpbmcgbmV3IHRva2Vucy5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzaG93Q3JlYXRlVG9rZW5Gb3JtKCkge1xcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLXRva2VuJykubW9kYWwoJ3Nob3cnKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIENyZWF0ZSBhIG5ldyBwZXJzb25hbCBhY2Nlc3MgdG9rZW4uXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgc3RvcmUoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSBudWxsO1xcblxcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gW107XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAucG9zdCgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMnLCB0aGlzLmZvcm0pXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0ubmFtZSA9ICcnO1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzID0gW107XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5lcnJvcnMgPSBbXTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2tlbnMucHVzaChyZXNwb25zZS5kYXRhLnRva2VuKTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93QWNjZXNzVG9rZW4ocmVzcG9uc2UuZGF0YS5hY2Nlc3NUb2tlbik7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2gocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc3BvbnNlLmRhdGEgPT09ICdvYmplY3QnKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gXy5mbGF0dGVuKF8udG9BcnJheShyZXNwb25zZS5kYXRhKSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGlyKHRoaXMuZm9ybSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gWydTb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSBhZ2Fpbi4nXTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogVG9nZ2xlIHRoZSBnaXZlbiBzY29wZSBpbiB0aGUgbGlzdCBvZiBhc3NpZ25lZCBzY29wZXMuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgdG9nZ2xlU2NvcGUoc2NvcGUpIHtcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2NvcGVJc0Fzc2lnbmVkKHNjb3BlKSkge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnNjb3BlcyA9IF8ucmVqZWN0KHRoaXMuZm9ybS5zY29wZXMsIHMgPT4gcyA9PSBzY29wZSk7XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzLnB1c2goc2NvcGUpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGdpdmVuIHNjb3BlIGhhcyBiZWVuIGFzc2lnbmVkIHRvIHRoZSB0b2tlbi5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzY29wZUlzQXNzaWduZWQoc2NvcGUpIHtcXG4gICAgICAgICAgICAgICAgcmV0dXJuIF8uaW5kZXhPZih0aGlzLmZvcm0uc2NvcGVzLCBzY29wZSkgPj0gMDtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFNob3cgdGhlIGdpdmVuIGFjY2VzcyB0b2tlbiB0byB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzaG93QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pIHtcXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWNyZWF0ZS10b2tlbicpLm1vZGFsKCdoaWRlJyk7XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSBhY2Nlc3NUb2tlbjtcXG5cXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWFjY2Vzcy10b2tlbicpLm1vZGFsKCdzaG93Jyk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBSZXZva2UgdGhlIGdpdmVuIHRva2VuLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHJldm9rZSh0b2tlbikge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmRlbGV0ZSgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMvJyArIHRva2VuLmlkKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIH1cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi0yMjU3NzhjMlwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 22 */ /***/ (function(module, exports, __webpack_require__) { -eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\ntd[data-v-5301a236] {\\n font-size: 13px;\\n}\\nth[data-v-5301a236] {\\n font-size: 13px;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/importer/importer.vue?376dfe74\"],\"names\":[],\"mappings\":\";AACA;IACA,gBAAA;CACA;AAEA;IACA,gBAAA;CACA\",\"file\":\"importer.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlP2RiMmUiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG50ZFtkYXRhLXYtNTMwMWEyMzZdIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG50aFtkYXRhLXYtNTMwMWEyMzZdIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4uLy4uLy4uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci52dWU/Mzc2ZGZlNzRcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsZ0JBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiaW1wb3J0ZXIudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxudGQge1xcbiAgICBmb250LXNpemU6IDEzcHg7XFxufVxcblxcbnRoIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG48L3N0eWxlPlxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdiBjbGFzcz1cXFwicm93XFxcIj5cXG4gICAgICAgIDxhbGVydCB2LXNob3c9XFxcImFsZXJ0LnZpc2libGVcXFwiIDphbGVydFR5cGU9XFxcImFsZXJ0LnR5cGVcXFwiIHYtb246aGlkZT1cXFwiYWxlcnQudmlzaWJsZSA9IGZhbHNlXFxcIj57eyBhbGVydC5tZXNzYWdlIH19PC9hbGVydD5cXG4gICAgICAgIDxlcnJvcnMgOmVycm9ycz1cXFwiaW1wb3J0RXJyb3JzXFxcIj48L2Vycm9ycz5cXG4gICAgICAgIDxtb2RhbCB2LW1vZGVsPVxcXCJkaXNwbGF5SW1wb3J0TW9kYWxcXFwiIGVmZmVjdD1cXFwiZmFkZVxcXCI+XFxuICAgICAgICAgICAgPGRpdiBzbG90PVxcXCJtb2RhbC1oZWFkZXJcXFwiIGNsYXNzPVxcXCJtb2RhbC1oZWFkZXJcXFwiPlxcbiAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5JbXBvcnQgRmlsZTo8L2g0PlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDxkaXYgc2xvdD1cXFwibW9kYWwtYm9keVxcXCIgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkeW5hbWljLWZvcm0tcm93XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC00IGNvbC14cy0xMlxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9XFxcImltcG9ydC10eXBlXFxcIj5JbXBvcnQgVHlwZTo8L2xhYmVsPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtOCBjb2wteHMtMTJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QyIDpvcHRpb25zPVxcXCJtb2RhbC5pbXBvcnRUeXBlc1xcXCIgdi1tb2RlbD1cXFwibW9kYWwuaW1wb3J0VHlwZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gZGlzYWJsZWQgdmFsdWU9XFxcIjBcXFwiPjwvb3B0aW9uPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0Mj5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImR5bmFtaWMtZm9ybS1yb3dcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTQgY29sLXhzLTEyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cXFwiaW1wb3J0LXVwZGF0ZVxcXCI+VXBkYXRlIEV4aXN0aW5nIFZhbHVlcz86PC9sYWJlbD5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTggY29sLXhzLTEyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cXFwiY2hlY2tib3hcXFwiIG5hbWU9XFxcImltcG9ydC11cGRhdGVcXFwiIHYtbW9kZWw9XFxcIm1vZGFsLnVwZGF0ZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1mb290ZXJcXFwiIHNsb3Q9XFxcIm1vZGFsLWZvb3RlclxcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImFsZXJ0IGFsZXJ0LXN1Y2Nlc3MgY29sLW1kLTUgY29sLW1kLW9mZnNldC0xXFxcIiBzdHlsZT1cXFwidGV4dC1hbGlnbjpsZWZ0XFxcIiB2LWlmPVxcXCJtb2RhbC5zdGF0dXNUZXh0XFxcIj57eyB0aGlzLm1vZGFsLnN0YXR1c1RleHQgfX08L2Rpdj5cXG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIEBjbGljaz1cXFwiZGlzcGxheUltcG9ydE1vZGFsID0gZmFsc2VcXFwiPkNhbmNlbDwvYnV0dG9uPlxcbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcInN1Ym1pdFxcXCIgY2xhc3M9XFxcImJ0biBidG4tcHJpbWFyeVxcXCIgQGNsaWNrPVxcXCJwb3N0U2F2ZVxcXCI+UHJvY2VzczwvYnV0dG9uPlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9tb2RhbD5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC0xMlxcXCI+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiYm94XFxcIj5cXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiYm94LWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicm93XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtM1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVGhlIGZpbGVpbnB1dC1idXR0b24gc3BhbiBpcyB1c2VkIHRvIHN0eWxlIHRoZSBmaWxlIGlucHV0IGZpZWxkIGFzIGJ1dHRvbiAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImJ0biBidG4taW5mbyBmaWxlaW5wdXQtYnV0dG9uXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlNlbGVjdCBJbXBvcnQgRmlsZS4uLjwvc3Bhbj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVGhlIGZpbGUgaW5wdXQgZmllbGQgdXNlZCBhcyB0YXJnZXQgZm9yIHRoZSBmaWxlIHVwbG9hZCB3aWRnZXQgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XFxcImZpbGV1cGxvYWRcXFwiIHR5cGU9XFxcImZpbGVcXFwiIG5hbWU9XFxcImZpbGVzW11cXFwiIGRhdGEtdXJsPVxcXCIvYXBpL3YxL2ltcG9ydHNcXFwiIGFjY2VwdD1cXFwidGV4dC9jc3ZcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTlcXFwiIHYtc2hvdz1cXFwicHJvZ3Jlc3MudmlzaWJsZVxcXCIgc3R5bGU9XFxcInBhZGRpbmctYm90dG9tOjIwcHhcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtMTFcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicHJvZ3Jlc3MgcHJvZ3Jlc3Mtc3RyaXBlZC1hY3RpdmVcXFwiIHN0eWxlPVxcXCJtYXJnaW4tdG9wOiA4cHhcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInByb2dyZXNzLWJhclxcXCIgOmNsYXNzPVxcXCJwcm9ncmVzcy5jdXJyZW50Q2xhc3NcXFwiIHJvbGU9XFxcInByb2dyZXNzYmFyXFxcIiA6c3R5bGU9XFxcInByb2dyZXNzV2lkdGhcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBwcm9ncmVzcy5zdGF0dXNUZXh0IH19PC9zcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJyb3dcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC0xMlxcXCIgc3R5bGU9XFxcInBhZGRpbmctdG9wOiAzMHB4O1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cXFwidGFibGUgdGFibGUtc3RyaXBlZFxcXCIgaWQ9XFxcInVwbG9hZC10YWJsZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkZpbGU8L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5DcmVhdGVkPC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+U2l6ZTwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPjwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ciB2LWZvcj1cXFwiZmlsZSBpbiBmaWxlc1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57eyBmaWxlLmZpbGVfcGF0aCB9fTwvdGQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57eyBmaWxlLmNyZWF0ZWRfYXQgfX0gPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPnt7IGZpbGUuZmlsZXNpemUgfX08L3RkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVxcXCJidG4gYnRuLXNtIGJ0bi1pbmZvXFxcIiBAY2xpY2s9XFxcInNob3dNb2RhbChmaWxlKVxcXCI+UHJvY2VzczwvYnV0dG9uPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cXFwiYnRuIGJ0bi1kYW5nZXJcXFwiIEBjbGljaz1cXFwiZGVsZXRlRmlsZShmaWxlKVxcXCI+PGkgY2xhc3M9XFxcImZhIGZhLXRyYXNoIGljb24td2hpdGVcXFwiPjwvaT48L2J1dHRvbj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICA8L2Rpdj5cXG48L3RlbXBsYXRlPlxcblxcbjxzY3JpcHQ+XFxuICAgIHJlcXVpcmUoJ2JsdWVpbXAtZmlsZS11cGxvYWQnKTtcXG4gICAgdmFyIG1vZGFsID0gcmVxdWlyZSgndnVlLXN0cmFwJykubW9kYWxcXG4gICAgZXhwb3J0IGRlZmF1bHQge1xcbiAgICAgICAgLypcXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxcbiAgICAgICAgICovXFxuICAgICAgICBkYXRhKCkge1xcbiAgICAgICAgICAgIHJldHVybiB7XFxuICAgICAgICAgICAgICAgIGZpbGVzOiBbXSxcXG4gICAgICAgICAgICAgICAgZGlzcGxheUltcG9ydE1vZGFsOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgYWN0aXZlRmlsZTogbnVsbCxcXG4gICAgICAgICAgICAgICAgYWxlcnQ6IHtcXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IG51bGwsXFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIG1vZGFsOiB7XFxuICAgICAgICAgICAgICAgICAgICBpbXBvcnRUeXBlOiAnYXNzZXQnLFxcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgICAgIGltcG9ydFR5cGVzOiBbXFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBpZDogJ2Fzc2V0JywgdGV4dDogJ0Fzc2V0cycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnYWNjZXNzb3J5JywgdGV4dDogJ0FjY2Vzc29yaWVzJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgaWQ6ICdjb25zdW1hYmxlJywgdGV4dDogJ0NvbnN1bWFibGUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBpZDogJ2NvbXBvbmVudCcsIHRleHQ6ICdDb21wb25lbnRzJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgaWQ6ICdsaWNlbnNlJywgdGV4dDogJ0xpY2Vuc2VzJyB9XFxuICAgICAgICAgICAgICAgICAgICBdLFxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzVGV4dDogbnVsbCxcXG4gICAgICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICAgICAgaW1wb3J0RXJyb3JzOiBudWxsLFxcbiAgICAgICAgICAgICAgICBwcm9ncmVzczoge1xcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudENsYXNzOiBcXFwicHJvZ3Jlc3MtYmFyLXdhcm5pbmdcXFwiLFxcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFBlcmNlbnQ6IFxcXCIwXFxcIixcXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1c1RleHQ6ICcnLFxcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2VcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAyLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICBtb3VudGVkKCkge1xcbiAgICAgICAgICAgIHRoaXMuZmV0Y2hGaWxlcygpO1xcbiAgICAgICAgICAgIGxldCB2bSA9IHRoaXM7XFxuICAgICAgICAgICAgJCgnI2ZpbGV1cGxvYWQnKS5maWxldXBsb2FkKHtcXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcXG4gICAgICAgICAgICAgICAgZG9uZShlLCBkYXRhKSB7XFxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy5jdXJyZW50Q2xhc3M9XFxcInByb2dyZXNzLWJhci1zdWNjZXNzXFxcIjtcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLnN0YXR1c1RleHQgPSBcXFwiU3VjY2VzcyFcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgdm0uZmlsZXMgPSBkYXRhLnJlc3VsdC5maWxlcy5jb25jYXQodm0uZmlsZXMpO1xcbiAgICAgICAgICAgICAgICB9LFxcbiAgICAgICAgICAgICAgICBhZGQoZSwgZGF0YSkge1xcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5oZWFkZXJzID0ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIFxcXCJYLVJlcXVlc3RlZC1XaXRoXFxcIjogJ1hNTEh0dHBSZXF1ZXN0JyxcXG4gICAgICAgICAgICAgICAgICAgICAgICBcXFwiWC1DU1JGLVRPS0VOXFxcIjogTGFyYXZlbC5jc3JmVG9rZW5cXG4gICAgICAgICAgICAgICAgICAgIH07XFxuICAgICAgICAgICAgICAgICAgICBkYXRhLnByb2Nlc3MoKS5kb25lKCAoKSA9PiB7ZGF0YS5zdWJtaXQoKTt9KTtcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLnZpc2libGU9dHJ1ZTtcXG4gICAgICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3MoZSwgZGF0YSkge1xcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb2dyZXNzID0gcGFyc2VJbnQoKGRhdGEubG9hZGVkIC8gZGF0YS50b3RhbCAqIDEwMCwgMTApKTtcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLmN1cnJlbnRQZXJjZW50ID0gcHJvZ3Jlc3M7XFxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy5zdGF0dXNUZXh0ID0gcHJvZ3Jlc3MrJyUgQ29tcGxldGUnO1xcbiAgICAgICAgICAgICAgICB9LFxcbiAgICAgICAgICAgICAgICBmYWlsKGUsIGRhdGEpIHtcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLmN1cnJlbnRDbGFzcyA9IFxcXCJwcm9ncmVzcy1iYXItZGFuZ2VyXFxcIjtcXG4gICAgICAgICAgICAgICAgICAgIC8vIERpc3BsYXkgYW55IGVycm9ycyByZXR1cm5lZCBmcm9tIHRoZSAkLmFqYXgoKVxcbiAgICAgICAgICAgICAgICAgICAgdm0ucHJvZ3Jlc3Muc3RhdHVzVGV4dCA9IGRhdGEuanFYSFIucmVzcG9uc2VKU09OLm1lc3NhZ2VzO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSlcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICBtZXRob2RzOiB7XFxuICAgICAgICAgICAgZmV0Y2hGaWxlcygpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9hcGkvdjEvaW1wb3J0cycpXFxuICAgICAgICAgICAgICAgIC50aGVuKCAoe2RhdGF9KSA9PiB0aGlzLmZpbGVzID0gZGF0YSwgLy8gU3VjY2Vzc1xcbiAgICAgICAgICAgICAgICAgICAgLy9GYWlsXFxuICAgICAgICAgICAgICAgIChyZXNwb25zZSkgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC50eXBlPVxcXCJkYW5nZXJcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC52aXNpYmxlPXRydWU7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0Lm1lc3NhZ2U9XFxcIlNvbWV0aGluZyB3ZW50IHdyb25nIGZldGNoaW5nIGZpbGVzLi4uXFxcIjtcXG4gICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBkZWxldGVGaWxlKGZpbGUsIGtleSkge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmRlbGV0ZShcXFwiL2FwaS92MS9pbXBvcnRzL1xcXCIrZmlsZS5pZClcXG4gICAgICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB0aGlzLmZpbGVzLnNwbGljZShrZXksIDEpLCAvLyBTdWNjZXNzXFxuICAgICAgICAgICAgICAgICAgICAocmVzcG9uc2UpID0+IHsvLyBGYWlsXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC50eXBlPVxcXCJkYW5nZXJcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQudmlzaWJsZT10cnVlO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQubWVzc2FnZT1yZXNwb25zZS5ib2R5Lm1lc3NhZ2VzO1xcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICApO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgc2hvd01vZGFsKGZpbGUpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVGaWxlID0gZmlsZTtcXG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5SW1wb3J0TW9kYWwgPSB0cnVlO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgcG9zdFNhdmUoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMubW9kYWwuc3RhdHVzVGV4dCA9IFxcXCJQcm9jZXNzaW5nLi4uXFxcIjtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5wb3N0KCcvYXBpL3YxL2ltcG9ydHMvcHJvY2Vzcy8nK3RoaXMuYWN0aXZlRmlsZS5pZCwge1xcbiAgICAgICAgICAgICAgICAgICAgJ2ltcG9ydC11cGRhdGUnOiB0aGlzLm1vZGFsLnVwZGF0ZSxcXG4gICAgICAgICAgICAgICAgICAgICdpbXBvcnQtdHlwZSc6IHRoaXMubW9kYWwuaW1wb3J0VHlwZVxcbiAgICAgICAgICAgICAgICB9KS50aGVuKCAocmVzcG9uc2UpID0+IHtcXG4gICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3NcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9kYWwuc3RhdHVzVGV4dCA9IFxcXCJTdWNjZXNzLi4uIFJlZGlyZWN0aW5nLlxcXCI7XFxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHJlc3BvbnNlLmJvZHkubWVzc2FnZXMucmVkaXJlY3RfdXJsO1xcbiAgICAgICAgICAgICAgICB9LCAocmVzcG9uc2UpID0+IHtcXG4gICAgICAgICAgICAgICAgICAgIC8vIEZhaWx1cmVcXG4gICAgICAgICAgICAgICAgICAgIGlmKHJlc3BvbnNlLmJvZHkuc3RhdHVzID09ICdpbXBvcnQtZXJyb3JzJykge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW1wb3J0RXJyb3JzID0gcmVzcG9uc2UuYm9keS5tZXNzYWdlcztcXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC5tZXNzYWdlPSByZXNwb25zZS5ib2R5Lm1lc3NhZ2VzO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQudHlwZT1cXFwiZGFuZ2VyXFxcIjtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0LnZpc2libGU9dHJ1ZTtcXG4gICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheUltcG9ydE1vZGFsPWZhbHNlO1xcbiAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9XFxuXFxuICAgICAgICB9LFxcblxcbiAgICAgICAgY29tcHV0ZWQ6IHtcXG4gICAgICAgICAgICBwcm9ncmVzc1dpZHRoKCkge1xcbiAgICAgICAgICAgICAgICByZXR1cm4gXFxcIndpZHRoOiBcXFwiK3RoaXMucHJvZ3Jlc3MuY3VycmVudFBlcmNlbnQqMTArJyUnO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH0sXFxuXFxuICAgICAgICBjb21wb25lbnRzOiB7XFxuICAgICAgICAgICAgbW9kYWwsXFxuICAgICAgICAgICAgZXJyb3JzOiByZXF1aXJlKCcuL2ltcG9ydGVyLWVycm9ycy52dWUnKSxcXG4gICAgICAgICAgICBhbGVydDogcmVxdWlyZSgnLi4vYWxlcnQudnVlJyksXFxuICAgICAgICAgICAgc2VsZWN0MjogcmVxdWlyZSgnLi4vc2VsZWN0Mi52dWUnKVxcbiAgICAgICAgfVxcbiAgICB9XFxuXFxuPC9zY3JpcHQ+XFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtNTMwMWEyMzZcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci52dWVcbi8vIG1vZHVsZSBpZCA9IDIyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0="); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n\\n\", \"\", {\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\",\"file\":\"alert.vue\",\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvYWxlcnQudnVlPzIxNTgiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG5cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W10sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIlwiLFwiZmlsZVwiOlwiYWxlcnQudnVlXCIsXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi0zZWRlZjNiYVwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2FsZXJ0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 23 */ /***/ (function(module, exports, __webpack_require__) { -eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n\\n\", \"\", {\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\",\"file\":\"importer-errors.vue\",\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZXJyb3JzLnZ1ZT84ZmRhIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJcIixcImZpbGVcIjpcImltcG9ydGVyLWVycm9ycy52dWVcIixcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LTU2NjdjMzEyXCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZXJyb3JzLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\ntd[data-v-5301a236] {\\n font-size: 13px;\\n}\\nth[data-v-5301a236] {\\n font-size: 13px;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/importer/importer.vue?61452aaa\"],\"names\":[],\"mappings\":\";AACA;IACA,gBAAA;CACA;AAEA;IACA,gBAAA;CACA\",\"file\":\"importer.vue\",\"sourcesContent\":[\"\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlP2RiMmUiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG50ZFtkYXRhLXYtNTMwMWEyMzZdIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG50aFtkYXRhLXYtNTMwMWEyMzZdIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4uLy4uLy4uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci52dWU/NjE0NTJhYWFcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsZ0JBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiaW1wb3J0ZXIudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxudGQge1xcbiAgICBmb250LXNpemU6IDEzcHg7XFxufVxcblxcbnRoIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG48L3N0eWxlPlxcblxcbjxzY3JpcHQ+XFxuICAgIHJlcXVpcmUoJ2JsdWVpbXAtZmlsZS11cGxvYWQnKTtcXG4gICAgZXhwb3J0IGRlZmF1bHQge1xcbiAgICAgICAgLypcXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxcbiAgICAgICAgICovXFxuICAgICAgICBkYXRhKCkge1xcbiAgICAgICAgICAgIHJldHVybiB7XFxuICAgICAgICAgICAgICAgIGZpbGVzOiBbXSxcXG4gICAgICAgICAgICAgICAgZGlzcGxheUltcG9ydE1vZGFsOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgYWN0aXZlRmlsZTogbnVsbCxcXG4gICAgICAgICAgICAgICAgYWxlcnQ6IHtcXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IG51bGwsXFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIGltcG9ydEVycm9yczogbnVsbCxcXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3M6IHtcXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzczogXFxcInByb2dyZXNzLWJhci13YXJuaW5nXFxcIixcXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQZXJjZW50OiBcXFwiMFxcXCIsXFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0OiAnJyxcXG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9O1xcbiAgICAgICAgfSxcXG5cXG4gICAgICAgIC8qKlxcbiAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50IChWdWUgMi54KS5cXG4gICAgICAgICAqL1xcbiAgICAgICAgbW91bnRlZCgpIHtcXG4gICAgICAgICAgICB3aW5kb3cuZXZlbnRIdWIuJG9uKCdpbXBvcnRFcnJvcnMnLCB0aGlzLnVwZGF0ZUltcG9ydEVycm9ycyk7XFxuICAgICAgICAgICAgdGhpcy5mZXRjaEZpbGVzKCk7XFxuICAgICAgICAgICAgbGV0IHZtID0gdGhpcztcXG4gICAgICAgICAgICAkKCcjZmlsZXVwbG9hZCcpLmZpbGV1cGxvYWQoe1xcbiAgICAgICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxcbiAgICAgICAgICAgICAgICBkb25lKGUsIGRhdGEpIHtcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLmN1cnJlbnRDbGFzcz1cXFwicHJvZ3Jlc3MtYmFyLXN1Y2Nlc3NcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgdm0ucHJvZ3Jlc3Muc3RhdHVzVGV4dCA9IFxcXCJTdWNjZXNzIVxcXCI7XFxuICAgICAgICAgICAgICAgICAgICB2bS5maWxlcyA9IGRhdGEucmVzdWx0LmZpbGVzLmNvbmNhdCh2bS5maWxlcyk7XFxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhkYXRhLnJlc3VsdC5oZWFkZXJfcm93KTtcXG4gICAgICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICAgICAgYWRkKGUsIGRhdGEpIHtcXG4gICAgICAgICAgICAgICAgICAgIGRhdGEuaGVhZGVycyA9IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICBcXFwiWC1SZXF1ZXN0ZWQtV2l0aFxcXCI6ICdYTUxIdHRwUmVxdWVzdCcsXFxuICAgICAgICAgICAgICAgICAgICAgICAgXFxcIlgtQ1NSRi1UT0tFTlxcXCI6IExhcmF2ZWwuY3NyZlRva2VuXFxuICAgICAgICAgICAgICAgICAgICB9O1xcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wcm9jZXNzKCkuZG9uZSggKCkgPT4ge2RhdGEuc3VibWl0KCk7fSk7XFxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy52aXNpYmxlPXRydWU7XFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIHByb2dyZXNzKGUsIGRhdGEpIHtcXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcm9ncmVzcyA9IHBhcnNlSW50KChkYXRhLmxvYWRlZCAvIGRhdGEudG90YWwgKiAxMDAsIDEwKSk7XFxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy5jdXJyZW50UGVyY2VudCA9IHByb2dyZXNzO1xcbiAgICAgICAgICAgICAgICAgICAgdm0ucHJvZ3Jlc3Muc3RhdHVzVGV4dCA9IHByb2dyZXNzKyclIENvbXBsZXRlJztcXG4gICAgICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICAgICAgZmFpbChlLCBkYXRhKSB7XFxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy5jdXJyZW50Q2xhc3MgPSBcXFwicHJvZ3Jlc3MtYmFyLWRhbmdlclxcXCI7XFxuICAgICAgICAgICAgICAgICAgICAvLyBEaXNwbGF5IGFueSBlcnJvcnMgcmV0dXJuZWQgZnJvbSB0aGUgJC5hamF4KClcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLnN0YXR1c1RleHQgPSBkYXRhLmpxWEhSLnJlc3BvbnNlSlNPTi5tZXNzYWdlcztcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH0pXFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIGZldGNoRmlsZXMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KCcvYXBpL3YxL2ltcG9ydHMnKVxcbiAgICAgICAgICAgICAgICAudGhlbiggKHtkYXRhfSkgPT4gdGhpcy5maWxlcyA9IGRhdGEsIC8vIFN1Y2Nlc3NcXG4gICAgICAgICAgICAgICAgICAgIC8vRmFpbFxcbiAgICAgICAgICAgICAgICAocmVzcG9uc2UpID0+IHtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQudHlwZT1cXFwiZGFuZ2VyXFxcIjtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQudmlzaWJsZT10cnVlO1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC5tZXNzYWdlPVxcXCJTb21ldGhpbmcgd2VudCB3cm9uZyBmZXRjaGluZyBmaWxlcy4uLlxcXCI7XFxuICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgZGVsZXRlRmlsZShmaWxlLCBrZXkpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5kZWxldGUoXFxcIi9hcGkvdjEvaW1wb3J0cy9cXFwiK2ZpbGUuaWQpXFxuICAgICAgICAgICAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gdGhpcy5maWxlcy5zcGxpY2Uoa2V5LCAxKSwgLy8gU3VjY2VzcywgcmVtb3ZlIGZpbGUgZnJvbSBhcnJheS5cXG4gICAgICAgICAgICAgICAgICAgIChyZXNwb25zZSkgPT4gey8vIEZhaWxcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0LnR5cGU9XFxcImRhbmdlclxcXCI7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC52aXNpYmxlPXRydWU7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC5tZXNzYWdlPXJlc3BvbnNlLmJvZHkubWVzc2FnZXM7XFxuICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB0b2dnbGVFdmVudChmaWxlSWQpIHtcXG4gICAgICAgICAgICAgICAgd2luZG93LmV2ZW50SHViLiRlbWl0KCdzaG93RGV0YWlscycsIGZpbGVJZClcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHVwZGF0ZUFsZXJ0KGFsZXJ0KSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQgPSBhbGVydDtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHVwZGF0ZUltcG9ydEVycm9ycyhlcnJvcnMpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5pbXBvcnRFcnJvcnMgPSBlcnJvcnM7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG5cXG4gICAgICAgIGNvbXB1dGVkOiB7XFxuICAgICAgICAgICAgcHJvZ3Jlc3NXaWR0aCgpIHtcXG4gICAgICAgICAgICAgICAgcmV0dXJuIFxcXCJ3aWR0aDogXFxcIit0aGlzLnByb2dyZXNzLmN1cnJlbnRQZXJjZW50KjEwKyclJztcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgY29tcG9uZW50czoge1xcbiAgICAgICAgICAgIGFsZXJ0OiByZXF1aXJlKCcuLi9hbGVydC52dWUnKSxcXG4gICAgICAgICAgICBlcnJvcnM6IHJlcXVpcmUoJy4vaW1wb3J0ZXItZXJyb3JzLnZ1ZScpLFxcbiAgICAgICAgICAgIGltcG9ydEZpbGU6IHJlcXVpcmUoJy4vaW1wb3J0ZXItZmlsZS52dWUnKSxcXG4gICAgICAgIH1cXG4gICAgfVxcblxcbjwvc2NyaXB0PlxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LTUzMDFhMjM2XCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlXG4vLyBtb2R1bGUgaWQgPSAyM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9"); /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { -eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.action-link[data-v-de0d0e4e] {\\n cursor: pointer;\\n}\\n.m-b-none[data-v-de0d0e4e] {\\n margin-bottom: 0;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/passport/AuthorizedClients.vue?a99076c0\"],\"names\":[],\"mappings\":\";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA\",\"file\":\"AuthorizedClients.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQXV0aG9yaXplZENsaWVudHMudnVlPzJhOTYiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4uYWN0aW9uLWxpbmtbZGF0YS12LWRlMGQwZTRlXSB7XFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLm0tYi1ub25lW2RhdGEtdi1kZTBkMGU0ZV0ge1xcbiAgICBtYXJnaW4tYm90dG9tOiAwO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4uLy4uLy4uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9BdXRob3JpemVkQ2xpZW50cy52dWU/YTk5MDc2YzBcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsaUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiQXV0aG9yaXplZENsaWVudHMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxuICAgIC5hY3Rpb24tbGluayB7XFxuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XFxuICAgIH1cXG5cXG4gICAgLm0tYi1ub25lIHtcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICAgIH1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXYgdi1pZj1cXFwidG9rZW5zLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsIHBhbmVsLWRlZmF1bHRcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1oZWFkaW5nXFxcIj5BdXRob3JpemVkIEFwcGxpY2F0aW9uczwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1ib2R5XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gQXV0aG9yaXplZCBUb2tlbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XFxcInRhYmxlIHRhYmxlLWJvcmRlcmxlc3MgbS1iLW5vbmVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPk5hbWU8L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPlNjb3BlczwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+PC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyIHYtZm9yPVxcXCJ0b2tlbiBpbiB0b2tlbnNcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBDbGllbnQgTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHRva2VuLmNsaWVudC5uYW1lIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTY29wZXMgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiB2LWlmPVxcXCJ0b2tlbi5zY29wZXMubGVuZ3RoID4gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHRva2VuLnNjb3Blcy5qb2luKCcsICcpIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmV2b2tlIEJ1dHRvbiAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclxcXCIgQGNsaWNrPVxcXCJyZXZva2UodG9rZW4pXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV2b2tlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC90ZW1wbGF0ZT5cXG5cXG48c2NyaXB0PlxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgICAvKlxcbiAgICAgICAgICogVGhlIGNvbXBvbmVudCdzIGRhdGEuXFxuICAgICAgICAgKi9cXG4gICAgICAgIGRhdGEoKSB7XFxuICAgICAgICAgICAgcmV0dXJuIHtcXG4gICAgICAgICAgICAgICAgdG9rZW5zOiBbXVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICByZWFkeSgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgcHJlcGFyZUNvbXBvbmVudCgpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIEdldCBhbGwgb2YgdGhlIGF1dGhvcml6ZWQgdG9rZW5zIGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBnZXRUb2tlbnMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KCcvb2F1dGgvdG9rZW5zJylcXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zID0gcmVzcG9uc2UuZGF0YTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFJldm9rZSB0aGUgZ2l2ZW4gdG9rZW4uXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgcmV2b2tlKHRva2VuKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZGVsZXRlKCcvb2F1dGgvdG9rZW5zLycgKyB0b2tlbi5pZClcXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0VG9rZW5zKCk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfVxcbiAgICB9XFxuPC9zY3JpcHQ+XFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtZGUwZDBlNGVcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9BdXRob3JpemVkQ2xpZW50cy52dWVcbi8vIG1vZHVsZSBpZCA9IDI0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0="); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n\\n\", \"\", {\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\",\"file\":\"importer-errors.vue\",\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZXJyb3JzLnZ1ZT84ZmRhIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJcIixcImZpbGVcIjpcImltcG9ydGVyLWVycm9ycy52dWVcIixcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LTU2NjdjMzEyXCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZXJyb3JzLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { -eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.action-link[data-v-e9c80318] {\\n cursor: pointer;\\n}\\n.m-b-none[data-v-e9c80318] {\\n margin-bottom: 0;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/passport/Clients.vue?35867ce4\"],\"names\":[],\"mappings\":\";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA\",\"file\":\"Clients.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQ2xpZW50cy52dWU/MGI2ZSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5hY3Rpb24tbGlua1tkYXRhLXYtZTljODAzMThdIHtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4ubS1iLW5vbmVbZGF0YS12LWU5YzgwMzE4XSB7XFxuICAgIG1hcmdpbi1ib3R0b206IDA7XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi4vLi4vLi4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlPzM1ODY3Y2U0XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFDQTtJQUNBLGdCQUFBO0NBQ0E7QUFFQTtJQUNBLGlCQUFBO0NBQ0FcIixcImZpbGVcIjpcIkNsaWVudHMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxuICAgIC5hY3Rpb24tbGluayB7XFxuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XFxuICAgIH1cXG5cXG4gICAgLm0tYi1ub25lIHtcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICAgIH1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsIHBhbmVsLWRlZmF1bHRcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsLWhlYWRpbmdcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVxcXCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIE9BdXRoIENsaWVudHNcXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGlua1xcXCIgQGNsaWNrPVxcXCJzaG93Q3JlYXRlQ2xpZW50Rm9ybVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIE5ldyBDbGllbnRcXG4gICAgICAgICAgICAgICAgICAgIDwvYT5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgIDwhLS0gQ3VycmVudCBDbGllbnRzIC0tPlxcbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cXFwibS1iLW5vbmVcXFwiIHYtaWY9XFxcImNsaWVudHMubGVuZ3RoID09PSAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIFlvdSBoYXZlIG5vdCBjcmVhdGVkIGFueSBPQXV0aCBjbGllbnRzLlxcbiAgICAgICAgICAgICAgICA8L3A+XFxuXFxuICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cXFwidGFibGUgdGFibGUtYm9yZGVybGVzcyBtLWItbm9uZVxcXCIgdi1pZj1cXFwiY2xpZW50cy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5DbGllbnQgSUQ8L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+TmFtZTwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5TZWNyZXQ8L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+PC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPjwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8dGJvZHk+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyIHYtZm9yPVxcXCJjbGllbnQgaW4gY2xpZW50c1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gSUQgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY2xpZW50LmlkIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjbGllbnQubmFtZSB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFNlY3JldCAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT57eyBjbGllbnQuc2VjcmV0IH19PC9jb2RlPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEVkaXQgQnV0dG9uIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGlua1xcXCIgQGNsaWNrPVxcXCJlZGl0KGNsaWVudClcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWxldGUgQnV0dG9uIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclxcXCIgQGNsaWNrPVxcXCJkZXN0cm95KGNsaWVudClcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XFxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgICAgICA8L3RhYmxlPlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICA8IS0tIENyZWF0ZSBDbGllbnQgTW9kYWwgLS0+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbCBmYWRlXFxcIiBpZD1cXFwibW9kYWwtY3JlYXRlLWNsaWVudFxcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIiByb2xlPVxcXCJkaWFsb2dcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvbiBcXFwiIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiPiZ0aW1lczs8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIENsaWVudFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaDQ+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRm9ybSBFcnJvcnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiYWxlcnQgYWxlcnQtZGFuZ2VyXFxcIiB2LWlmPVxcXCJjcmVhdGVGb3JtLmVycm9ycy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+PHN0cm9uZz5XaG9vcHMhPC9zdHJvbmc+IFNvbWV0aGluZyB3ZW50IHdyb25nITwvcD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgdi1mb3I9XFxcImVycm9yIGluIGNyZWF0ZUZvcm0uZXJyb3JzXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBlcnJvciB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENyZWF0ZSBDbGllbnQgRm9ybSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8Zm9ybSBjbGFzcz1cXFwiZm9ybS1ob3Jpem9udGFsXFxcIiByb2xlPVxcXCJmb3JtXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBOYW1lIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cXFwiY29sLW1kLTMgY29udHJvbC1sYWJlbFxcXCI+TmFtZTwvbGFiZWw+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtN1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPVxcXCJjcmVhdGUtY2xpZW50LW5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cXFwic3RvcmVcXFwiIHYtbW9kZWw9XFxcImNyZWF0ZUZvcm0ubmFtZVxcXCI+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImhlbHAtYmxvY2tcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21ldGhpbmcgeW91ciB1c2VycyB3aWxsIHJlY29nbml6ZSBhbmQgdHJ1c3QuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFJlZGlyZWN0IFVSTCAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZm9ybS1ncm91cFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC0zIGNvbnRyb2wtbGFiZWxcXFwiPlJlZGlyZWN0IFVSTDwvbGFiZWw+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtN1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIG5hbWU9XFxcInJlZGlyZWN0XFxcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAa2V5dXAuZW50ZXI9XFxcInN0b3JlXFxcIiB2LW1vZGVsPVxcXCJjcmVhdGVGb3JtLnJlZGlyZWN0XFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiaGVscC1ibG9ja1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlvdXIgYXBwbGljYXRpb24ncyBhdXRob3JpemF0aW9uIGNhbGxiYWNrIFVSTC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9mb3JtPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8IS0tIE1vZGFsIEFjdGlvbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1mb290ZXJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYnRuIGJ0bi1kZWZhdWx0XFxcIiBkYXRhLWRpc21pc3M9XFxcIm1vZGFsXFxcIj5DbG9zZTwvYnV0dG9uPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYnRuIGJ0bi1wcmltYXJ5XFxcIiBAY2xpY2s9XFxcInN0b3JlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgIDwhLS0gRWRpdCBDbGllbnQgTW9kYWwgLS0+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbCBmYWRlXFxcIiBpZD1cXFwibW9kYWwtZWRpdC1jbGllbnRcXFwiIHRhYmluZGV4PVxcXCItMVxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIj5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1kaWFsb2dcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1jb250ZW50XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b24gXFxcIiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj4mdGltZXM7PC9idXR0b24+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVxcXCJtb2RhbC10aXRsZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVkaXQgQ2xpZW50XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9oND5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtIEVycm9ycyAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhbGVydCBhbGVydC1kYW5nZXJcXFwiIHYtaWY9XFxcImVkaXRGb3JtLmVycm9ycy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+PHN0cm9uZz5XaG9vcHMhPC9zdHJvbmc+IFNvbWV0aGluZyB3ZW50IHdyb25nITwvcD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgdi1mb3I9XFxcImVycm9yIGluIGVkaXRGb3JtLmVycm9yc1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZXJyb3IgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFZGl0IENsaWVudCBGb3JtIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxmb3JtIGNsYXNzPVxcXCJmb3JtLWhvcml6b250YWxcXFwiIHJvbGU9XFxcImZvcm1cXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5hbWUgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVxcXCJjb2wtbWQtMyBjb250cm9sLWxhYmVsXFxcIj5OYW1lPC9sYWJlbD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC03XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XFxcImVkaXQtY2xpZW50LW5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cXFwidXBkYXRlXFxcIiB2LW1vZGVsPVxcXCJlZGl0Rm9ybS5uYW1lXFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiaGVscC1ibG9ja1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvbWV0aGluZyB5b3VyIHVzZXJzIHdpbGwgcmVjb2duaXplIGFuZCB0cnVzdC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmVkaXJlY3QgVVJMIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cXFwiY29sLW1kLTMgY29udHJvbC1sYWJlbFxcXCI+UmVkaXJlY3QgVVJMPC9sYWJlbD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC03XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cXFwidGV4dFxcXCIgY2xhc3M9XFxcImZvcm0tY29udHJvbFxcXCIgbmFtZT1cXFwicmVkaXJlY3RcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cXFwidXBkYXRlXFxcIiB2LW1vZGVsPVxcXCJlZGl0Rm9ybS5yZWRpcmVjdFxcXCI+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImhlbHAtYmxvY2tcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZb3VyIGFwcGxpY2F0aW9uJ3MgYXV0aG9yaXphdGlvbiBjYWxsYmFjayBVUkwuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNb2RhbCBBY3Rpb25zIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtZm9vdGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tZGVmYXVsdFxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCI+Q2xvc2U8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tcHJpbWFyeVxcXCIgQGNsaWNrPVxcXCJ1cGRhdGVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTYXZlIENoYW5nZXNcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICA8L2Rpdj5cXG48L3RlbXBsYXRlPlxcblxcbjxzY3JpcHQ+XFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXG4gICAgICAgIC8qXFxuICAgICAgICAgKiBUaGUgY29tcG9uZW50J3MgZGF0YS5cXG4gICAgICAgICAqL1xcbiAgICAgICAgZGF0YSgpIHtcXG4gICAgICAgICAgICByZXR1cm4ge1xcbiAgICAgICAgICAgICAgICBjbGllbnRzOiBbXSxcXG5cXG4gICAgICAgICAgICAgICAgY3JlYXRlRm9ybToge1xcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzOiBbXSxcXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICcnLFxcbiAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3Q6ICcnXFxuICAgICAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgICAgIGVkaXRGb3JtOiB7XFxuICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IFtdLFxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJycsXFxuICAgICAgICAgICAgICAgICAgICByZWRpcmVjdDogJydcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICByZWFkeSgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBwcmVwYXJlQ29tcG9uZW50KCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldENsaWVudHMoKTtcXG5cXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWNyZWF0ZS1jbGllbnQnKS5vbignc2hvd24uYnMubW9kYWwnLCAoKSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAkKCcjY3JlYXRlLWNsaWVudC1uYW1lJykuZm9jdXMoKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuXFxuICAgICAgICAgICAgICAgICQoJyNtb2RhbC1lZGl0LWNsaWVudCcpLm9uKCdzaG93bi5icy5tb2RhbCcsICgpID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICQoJyNlZGl0LWNsaWVudC1uYW1lJykuZm9jdXMoKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBPQXV0aCBjbGllbnRzIGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBnZXRDbGllbnRzKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmdldCgnL29hdXRoL2NsaWVudHMnKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGllbnRzID0gcmVzcG9uc2UuZGF0YTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFNob3cgdGhlIGZvcm0gZm9yIGNyZWF0aW5nIG5ldyBjbGllbnRzLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHNob3dDcmVhdGVDbGllbnRGb3JtKCkge1xcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLWNsaWVudCcpLm1vZGFsKCdzaG93Jyk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBDcmVhdGUgYSBuZXcgT0F1dGggY2xpZW50IGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzdG9yZSgpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5wZXJzaXN0Q2xpZW50KFxcbiAgICAgICAgICAgICAgICAgICAgJ3Bvc3QnLCAnL29hdXRoL2NsaWVudHMnLFxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVGb3JtLCAnI21vZGFsLWNyZWF0ZS1jbGllbnQnXFxuICAgICAgICAgICAgICAgICk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBFZGl0IHRoZSBnaXZlbiBjbGllbnQuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgZWRpdChjbGllbnQpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybS5pZCA9IGNsaWVudC5pZDtcXG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybS5uYW1lID0gY2xpZW50Lm5hbWU7XFxuICAgICAgICAgICAgICAgIHRoaXMuZWRpdEZvcm0ucmVkaXJlY3QgPSBjbGllbnQucmVkaXJlY3Q7XFxuXFxuICAgICAgICAgICAgICAgICQoJyNtb2RhbC1lZGl0LWNsaWVudCcpLm1vZGFsKCdzaG93Jyk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBVcGRhdGUgdGhlIGNsaWVudCBiZWluZyBlZGl0ZWQuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgdXBkYXRlKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLnBlcnNpc3RDbGllbnQoXFxuICAgICAgICAgICAgICAgICAgICAncHV0JywgJy9vYXV0aC9jbGllbnRzLycgKyB0aGlzLmVkaXRGb3JtLmlkLFxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybSwgJyNtb2RhbC1lZGl0LWNsaWVudCdcXG4gICAgICAgICAgICAgICAgKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFBlcnNpc3QgdGhlIGNsaWVudCB0byBzdG9yYWdlIHVzaW5nIHRoZSBnaXZlbiBmb3JtLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHBlcnNpc3RDbGllbnQobWV0aG9kLCB1cmksIGZvcm0sIG1vZGFsKSB7XFxuICAgICAgICAgICAgICAgIGZvcm0uZXJyb3JzID0gW107XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHBbbWV0aG9kXSh1cmksIGZvcm0pXFxuICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRDbGllbnRzKCk7XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5uYW1lID0gJyc7XFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5yZWRpcmVjdCA9ICcnO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm0uZXJyb3JzID0gW107XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgJChtb2RhbCkubW9kYWwoJ2hpZGUnKTtcXG4gICAgICAgICAgICAgICAgICAgIH0pXFxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2gocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzcG9uc2UuZGF0YSA9PT0gJ29iamVjdCcpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5lcnJvcnMgPSBfLmZsYXR0ZW4oXy50b0FycmF5KHJlc3BvbnNlLmRhdGEpKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtLmVycm9ycyA9IFsnU29tZXRoaW5nIHdlbnQgd3JvbmcuIFBsZWFzZSB0cnkgYWdhaW4uJ107XFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBEZXN0cm95IHRoZSBnaXZlbiBjbGllbnQuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgZGVzdHJveShjbGllbnQpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5kZWxldGUoJy9vYXV0aC9jbGllbnRzLycgKyBjbGllbnQuaWQpXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldENsaWVudHMoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIH1cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1lOWM4MDMxOFwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlXG4vLyBtb2R1bGUgaWQgPSAyNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9"); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\ntr {\\n padding-left:30px;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/importer/importer-file.vue?05e50752\"],\"names\":[],\"mappings\":\";AACA;IACA,kBAAA;CACA\",\"file\":\"importer-file.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZmlsZS52dWU/NjQyNCJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbnRyIHtcXG4gICAgcGFkZGluZy1sZWZ0OjMwcHg7XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi4vLi4vLi4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2ltcG9ydGVyL2ltcG9ydGVyLWZpbGUudnVlPzA1ZTUwNzUyXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFDQTtJQUNBLGtCQUFBO0NBQ0FcIixcImZpbGVcIjpcImltcG9ydGVyLWZpbGUudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZT5cXG50ciB7XFxuICAgIHBhZGRpbmctbGVmdDozMHB4O1xcbn1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPHRyIHYtc2hvdz1cXFwicHJvY2Vzc0RldGFpbFxcXCI+XFxuICAgICAgICA8dGQgY29sc3Bhbj1cXFwiM1xcXCI+XFxuICAgICAgICAgICAgPGg0IGNsYXNzPVxcXCJtb2RhbC10aXRsZVxcXCI+SW1wb3J0IEZpbGU6PC9oND5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkeW5hbWljLWZvcm0tcm93XFxcIj5cXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTQgY29sLXhzLTEyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9XFxcImltcG9ydC10eXBlXFxcIj5JbXBvcnQgVHlwZTo8L2xhYmVsPlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTQgY29sLXhzLTEyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QyIDpvcHRpb25zPVxcXCJvcHRpb25zLmltcG9ydFR5cGVzXFxcIiB2LW1vZGVsPVxcXCJvcHRpb25zLmltcG9ydFR5cGVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gZGlzYWJsZWQgdmFsdWU9XFxcIjBcXFwiPjwvb3B0aW9uPlxcbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3QyPlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkeW5hbWljLWZvcm0tcm93XFxcIj5cXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTQgY29sLXhzLTEyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9XFxcImltcG9ydC11cGRhdGVcXFwiPlVwZGF0ZSBFeGlzdGluZyBWYWx1ZXM/OjwvbGFiZWw+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNCBjb2wteHMtMTJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XFxcImNoZWNrYm94XFxcIiBuYW1lPVxcXCJpbXBvcnQtdXBkYXRlXFxcIiB2LW1vZGVsPVxcXCJvcHRpb25zLnVwZGF0ZVxcXCI+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC0xMlxcXCIgc3R5bGU9XFxcInBhZGRpbmctdG9wOiAzMHB4O1xcXCI+XFxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVxcXCJ0YWJsZVxcXCI+XFxuICAgICAgICAgICAgPHRoZWFkPlxcbiAgICAgICAgICAgICAgICA8dGg+SGVhZGVyIEZpZWxkPC90aD5cXG4gICAgICAgICAgICAgICAgPHRoPkltcG9ydCBGaWVsZDwvdGg+XFxuICAgICAgICAgICAgICAgIDx0aD5TYW1wbGUgVmFsdWU8L3RoPlxcbiAgICAgICAgICAgIDwvdGhlYWQ+XFxuICAgICAgICAgICAgPHRib2R5PlxcbiAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWZvcj1cXFwiKGhlYWRlciwgaW5kZXgpIGluIGZpbGUuaGVhZGVyX3Jvd1xcXCI+XFxuICAgICAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5cXG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCA6Zm9yPVxcXCJoZWFkZXJcXFwiIGNsYXNzPVxcXCJjb250cm9sbGFiZWxcXFwiPnt7IGhlYWRlciB9fTwvbGFiZWw+XFxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxcbiAgICAgICAgICAgICAgICAgICAgPHRkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgcmVxdWlyZWQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QyIDpvcHRpb25zPVxcXCJjb2x1bW5zXFxcIiB2LW1vZGVsPVxcXCJjb2x1bW5NYXBwaW5nc1toZWFkZXJdXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XFxcIjBcXFwiPkRvIE5vdCBJbXBvcnQ8L29wdGlvbj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3QyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pnt7IGFjdGl2ZUZpbGUuZmlyc3Rfcm93W2luZGV4XSB9fTwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgPC90ZW1wbGF0ZT5cXG4gICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgIDwvdGFibGU+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgPHRkPlxcbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYnRuIGJ0bi1kZWZhdWx0XFxcIiBAY2xpY2s9XFxcInByb2Nlc3NEZXRhaWwgPSBmYWxzZVxcXCI+Q2FuY2VsPC9idXR0b24+XFxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJzdWJtaXRcXFwiIGNsYXNzPVxcXCJidG4gYnRuLXByaW1hcnlcXFwiIEBjbGljaz1cXFwicG9zdFNhdmVcXFwiPkltcG9ydDwvYnV0dG9uPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImFsZXJ0IGFsZXJ0LXN1Y2Nlc3MgY29sLW1kLTUgY29sLW1kLW9mZnNldC0xXFxcIiBzdHlsZT1cXFwidGV4dC1hbGlnbjpsZWZ0XFxcIiB2LWlmPVxcXCJzdGF0dXNUZXh0XFxcIj57eyB0aGlzLnN0YXR1c1RleHQgfX08L2Rpdj5cXG4gICAgICAgIDwvdGQ+XFxuICAgIDwvdHI+XFxuPC90ZW1wbGF0ZT5cXG5cXG48c2NyaXB0PlxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgICBwcm9wczogWydmaWxlJ10sXFxuICAgICAgICBkYXRhKCkge1xcbiAgICAgICAgICAgIHJldHVybiB7XFxuICAgICAgICAgICAgICAgIGFjdGl2ZUZpbGU6IHRoaXMuZmlsZSxcXG4gICAgICAgICAgICAgICAgcHJvY2Vzc0RldGFpbDogZmFsc2UsXFxuICAgICAgICAgICAgICAgIHN0YXR1c1RleHQ6IG51bGwsXFxuICAgICAgICAgICAgICAgIG9wdGlvbnM6IHtcXG4gICAgICAgICAgICAgICAgICAgIGltcG9ydFR5cGU6IHRoaXMuZmlsZS5pbXBvcnRfdHlwZSxcXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZTogZmFsc2UsXFxuICAgICAgICAgICAgICAgICAgICBpbXBvcnRUeXBlczogW1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgaWQ6ICdhc3NldCcsIHRleHQ6ICdBc3NldHMnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBpZDogJ2FjY2Vzc29yeScsIHRleHQ6ICdBY2Nlc3NvcmllcycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnY29uc3VtYWJsZScsIHRleHQ6ICdDb25zdW1hYmxlcycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnY29tcG9uZW50JywgdGV4dDogJ0NvbXBvbmVudHMnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBpZDogJ2xpY2Vuc2UnLCB0ZXh0OiAnTGljZW5zZXMnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBpZDogJ3VzZXInLCB0ZXh0OiAnVXNlcnMnIH1cXG4gICAgICAgICAgICAgICAgICAgIF0sXFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0OiBudWxsLFxcbiAgICAgICAgICAgICAgICB9LFxcbiAgICAgICAgICAgICAgICBjb2x1bW5PcHRpb25zOiB7XFxuICAgICAgICAgICAgICAgICAgICBnZW5lcmFsOiBbXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnY2F0ZWdvcnknLCB0ZXh0OiAnQ2F0ZWdvcnknIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnY29tcGFueScsIHRleHQ6ICdDb21wYW55JyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2NoZWNrb3V0X3RvJywgdGV4dDogJ0NoZWNrZWQgb3V0IHRvJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2VtYWlsJywgdGV4dDogJ0VtYWlsJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2ZpcnN0X25hbWUnLCB0ZXh0OiAnRmlyc3QgTmFtZScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdpdGVtX25hbWUnLCB0ZXh0OiAnSXRlbSBOYW1lJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2xhc3RfbmFtZScsIHRleHQ6ICdMYXN0IE5hbWUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbG9jYXRpb24nLCB0ZXh0OiAnTG9jYXRpb24nIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbWFpbnRhaW5lZCcsIHRleHQ6ICdNYWludGFpbmVkJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ21hbnVmYWN0dXJlcicsIHRleHQ6ICdNYW51ZmFjdHVyZXInIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbm90ZXMnLCB0ZXh0OiAnTm90ZXMnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnb3JkZXJfbnVtYmVyJywgdGV4dDogJ09yZGVyIE51bWJlcicgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdwdXJjaGFzZV9jb3N0JywgdGV4dDogJ1B1cmNoYXNlIENvc3QnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncHVyY2hhc2VfZGF0ZScsIHRleHQ6ICdQdXJjaGFzZSBEYXRlJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3F1YW50aXR5JywgdGV4dDogJ1F1YW50aXR5JyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3JlcXVlc3RhYmxlJywgdGV4dDogJ1JlcXVlc3RhYmxlJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3NlcmlhbCcsIHRleHQ6ICdTZXJpYWwgTnVtYmVyJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3N1cHBsaWVyJywgdGV4dDogJ1N1cHBsaWVyJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3VzZXJuYW1lJywgdGV4dDogJ1VzZXJuYW1lJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgXSxcXG4gICAgICAgICAgICAgICAgICAgIGFzc2V0czogW1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2Fzc2V0X3RhZycsIHRleHQ6ICdBc3NldCBUYWcnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnYXNzZXRfbW9kZWwnLCB0ZXh0OiAnTW9kZWwgTmFtZScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdpbWFnZScsIHRleHQ6ICdJbWFnZSBGaWxlbmFtZScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdtb2RlbF9udW1iZXInLCB0ZXh0OiAnTW9kZWwgTnVtYmVyJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ25hbWUnLCB0ZXh0OiAnRnVsbCBOYW1lJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3N0YXR1cycsIHRleHQ6ICdTdGF0dXMnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnd2FycmFudHlfbW9udGhzJywgdGV4dDogJ1dhcnJhbnR5IE1vbnRocycgfSxcXG4gICAgICAgICAgICAgICAgICAgIF0sXFxuICAgICAgICAgICAgICAgICAgICBsaWNlbnNlczogW1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2V4cGlyYXRpb25fZGF0ZScsIHRleHQ6ICdFeHBpcmF0aW9uIERhdGUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbGljZW5zZV9lbWFpbCcsIHRleHQ6ICdMaWNlbnNlZCBUbyBFbWFpbCcgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdsaWNlbnNlX25hbWUnLCB0ZXh0OiAnTGljZW5zZWQgVG8gTmFtZScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdwdXJjaGFzZV9vcmRlcicsIHRleHQ6ICdQdXJjaGFzZSBPcmRlcicgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdyZWFzc2lnbmFibGUnLCB0ZXh0OiAnUmVhc3NpZ25hYmxlJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3NlYXRzJywgdGV4dDogJ1NlYXRzJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgXSxcXG4gICAgICAgICAgICAgICAgICAgIHVzZXJzOiBbXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnZW1wbG95ZWVfbnVtJywgdGV4dDogJ0VtcGxveWVlIE51bWJlcicgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdqb2J0aXRsZScsIHRleHQ6ICdKb2IgVGl0bGUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncGhvbmVfbnVtYmVyJywgdGV4dDogJ1Bob25lIE51bWJlcicgfSxcXG4gICAgICAgICAgICAgICAgICAgIF0sXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIGNvbHVtbk1hcHBpbmdzOiB0aGlzLmZpbGUuZmllbGRfbWFwIHx8IHt9LFxcbiAgICAgICAgICAgICAgICBhY3RpdmVDb2x1bW46IG51bGwsXFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG4gICAgICAgIGNyZWF0ZWQoKSB7XFxuICAgICAgICAgICAgd2luZG93LmV2ZW50SHViLiRvbignc2hvd0RldGFpbHMnLCB0aGlzLnRvZ2dsZUV4dGVuZGVkRGlzcGxheSlcXG4gICAgICAgICAgICB0aGlzLnBvcHVsYXRlU2VsZWN0MkFjdGl2ZUl0ZW1zKCk7XFxuICAgICAgICB9LFxcbiAgICAgICAgY29tcHV0ZWQ6IHtcXG4gICAgICAgICAgICBjb2x1bW5zKCkge1xcbiAgICAgICAgICAgICAgICBzd2l0Y2godGhpcy5vcHRpb25zLmltcG9ydFR5cGUpIHtcXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Fzc2V0JzpcXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5PcHRpb25zLmdlbmVyYWwuY29uY2F0KHRoaXMuY29sdW1uT3B0aW9ucy5hc3NldHMpO1xcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGljZW5zZSc6XFxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29sdW1uT3B0aW9ucy5nZW5lcmFsLmNvbmNhdCh0aGlzLmNvbHVtbk9wdGlvbnMubGljZW5zZXMpO1xcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndXNlcic6XFxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29sdW1uT3B0aW9ucy5nZW5lcmFsLmNvbmNhdCh0aGlzLmNvbHVtbk9wdGlvbnMudXNlcnMpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbHVtbk9wdGlvbnMuZ2VuZXJhbDtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9LFxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIHBvc3RTYXZlKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBcXFwiUHJvY2Vzc2luZy4uLlxcXCI7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAucG9zdCgnL2FwaS92MS9pbXBvcnRzL3Byb2Nlc3MvJyt0aGlzLmZpbGUuaWQsIHtcXG4gICAgICAgICAgICAgICAgICAgICdpbXBvcnQtdXBkYXRlJzogdGhpcy5vcHRpb25zLnVwZGF0ZSxcXG4gICAgICAgICAgICAgICAgICAgICdpbXBvcnQtdHlwZSc6IHRoaXMub3B0aW9ucy5pbXBvcnRUeXBlLFxcbiAgICAgICAgICAgICAgICAgICAgJ2NvbHVtbi1tYXBwaW5ncyc6IHRoaXMuY29sdW1uTWFwcGluZ3NcXG4gICAgICAgICAgICAgICAgfSkudGhlbiggKHJlc3BvbnNlKSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBcXFwiU3VjY2Vzcy4uLiBSZWRpcmVjdGluZy5cXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSByZXNwb25zZS5ib2R5Lm1lc3NhZ2VzLnJlZGlyZWN0X3VybDtcXG4gICAgICAgICAgICAgICAgfSwgKHJlc3BvbnNlKSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAvLyBGYWlsdXJlXFxuICAgICAgICAgICAgICAgICAgICBpZihyZXNwb25zZS5ib2R5LnN0YXR1cyA9PSAnaW1wb3J0LWVycm9ycycpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuZXZlbnRIdWIuJGVtaXQoJ2ltcG9ydEVycm9ycycsIHJlc3BvbnNlLmJvZHkubWVzc2FnZXMpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHVzVGV4dCA9IFxcXCJFcnJvclxcXCI7XFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoJ2FsZXJ0Jywge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiByZXNwb25zZS5ib2R5Lm1lc3NhZ2VzLFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcXFwiZGFuZ2VyXFxcIixcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5SW1wb3J0TW9kYWw9ZmFsc2U7XFxuICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgcG9wdWxhdGVTZWxlY3QyQWN0aXZlSXRlbXMoKSB7XFxuICAgICAgICAgICAgICAgIGlmKHRoaXMuZmlsZS5maWVsZF9tYXAgPT0gbnVsbCkge1xcbiAgICAgICAgICAgICAgICAgICAgLy8gQmVnaW4gYnkgcG9wdWxhdGluZyB0aGUgYWN0aXZlIHNlbGVjdGlvbiBpbiBkcm9wZG93bnMgd2l0aCBibGFuayB2YWx1ZXMuXFxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpPTA7IGkgPCB0aGlzLmZpbGUuaGVhZGVyX3Jvdy5sZW5ndGg7IGkrKykge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHNldCh0aGlzLmNvbHVtbk1hcHBpbmdzLCB0aGlzLmZpbGUuaGVhZGVyX3Jvd1tpXSwgbnVsbCk7XFxuICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGVuLCBmb3IgYW55IHZhbHVlcyB0aGF0IGhhdmUgYSBsaWtlbHkgbWF0Y2gsIHdlIG1ha2UgdGhhdCBhY3RpdmUuXFxuICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGo9MDsgaiA8IHRoaXMuY29sdW1ucy5sZW5ndGg7IGorKykge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb2x1bW4gPSB0aGlzLmNvbHVtbnNbal07XFxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5maWxlLmhlYWRlcl9yb3cuaW5kZXhPZihjb2x1bW4udGV4dClcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihpbmRleCAhPSAtMSkge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRzZXQodGhpcy5jb2x1bW5NYXBwaW5ncywgdGhpcy5maWxlLmhlYWRlcl9yb3dbaW5kZXhdLCBjb2x1bW4uaWQpXFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB0b2dnbGVFeHRlbmRlZERpc3BsYXkoZmlsZUlkKSB7XFxuICAgICAgICAgICAgICAgIGlmKGZpbGVJZCA9PSB0aGlzLmZpbGUuaWQpIHtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0RldGFpbCA9ICF0aGlzLnByb2Nlc3NEZXRhaWxcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgdXBkYXRlTW9kZWwoaGVhZGVyLCB2YWx1ZSkge1xcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhoZWFkZXIsIHZhbHVlKTtcXG4gICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5NYXBwaW5nc1toZWFkZXJdID0gdmFsdWU7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG4gICAgICAgIGNvbXBvbmVudHM6IHtcXG4gICAgICAgICAgICBzZWxlY3QyOiByZXF1aXJlKCcuLi9zZWxlY3QyLnZ1ZScpXFxuICAgICAgICB9XFxuICAgIH1cXG48L3NjcmlwdD5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi05MTYxOWYzYVwiLFwic2NvcGVkXCI6ZmFsc2UsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1maWxlLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 26 */ /***/ (function(module, exports, __webpack_require__) { -eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n\\n\", \"\", {\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\",\"file\":\"select2.vue\",\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvc2VsZWN0Mi52dWU/YzkyNSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcblxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiXCIsXCJmaWxlXCI6XCJzZWxlY3QyLnZ1ZVwiLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtZmY1NjRhODZcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.action-link[data-v-de0d0e4e] {\\n cursor: pointer;\\n}\\n.m-b-none[data-v-de0d0e4e] {\\n margin-bottom: 0;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/passport/AuthorizedClients.vue?a99076c0\"],\"names\":[],\"mappings\":\";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA\",\"file\":\"AuthorizedClients.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQXV0aG9yaXplZENsaWVudHMudnVlPzJhOTYiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4uYWN0aW9uLWxpbmtbZGF0YS12LWRlMGQwZTRlXSB7XFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLm0tYi1ub25lW2RhdGEtdi1kZTBkMGU0ZV0ge1xcbiAgICBtYXJnaW4tYm90dG9tOiAwO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4uLy4uLy4uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9BdXRob3JpemVkQ2xpZW50cy52dWU/YTk5MDc2YzBcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsaUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiQXV0aG9yaXplZENsaWVudHMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxuICAgIC5hY3Rpb24tbGluayB7XFxuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XFxuICAgIH1cXG5cXG4gICAgLm0tYi1ub25lIHtcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICAgIH1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXYgdi1pZj1cXFwidG9rZW5zLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsIHBhbmVsLWRlZmF1bHRcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1oZWFkaW5nXFxcIj5BdXRob3JpemVkIEFwcGxpY2F0aW9uczwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1ib2R5XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gQXV0aG9yaXplZCBUb2tlbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XFxcInRhYmxlIHRhYmxlLWJvcmRlcmxlc3MgbS1iLW5vbmVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPk5hbWU8L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPlNjb3BlczwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+PC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyIHYtZm9yPVxcXCJ0b2tlbiBpbiB0b2tlbnNcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBDbGllbnQgTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHRva2VuLmNsaWVudC5uYW1lIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTY29wZXMgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiB2LWlmPVxcXCJ0b2tlbi5zY29wZXMubGVuZ3RoID4gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHRva2VuLnNjb3Blcy5qb2luKCcsICcpIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmV2b2tlIEJ1dHRvbiAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclxcXCIgQGNsaWNrPVxcXCJyZXZva2UodG9rZW4pXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV2b2tlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC90ZW1wbGF0ZT5cXG5cXG48c2NyaXB0PlxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgICAvKlxcbiAgICAgICAgICogVGhlIGNvbXBvbmVudCdzIGRhdGEuXFxuICAgICAgICAgKi9cXG4gICAgICAgIGRhdGEoKSB7XFxuICAgICAgICAgICAgcmV0dXJuIHtcXG4gICAgICAgICAgICAgICAgdG9rZW5zOiBbXVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICByZWFkeSgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgcHJlcGFyZUNvbXBvbmVudCgpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIEdldCBhbGwgb2YgdGhlIGF1dGhvcml6ZWQgdG9rZW5zIGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBnZXRUb2tlbnMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KCcvb2F1dGgvdG9rZW5zJylcXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zID0gcmVzcG9uc2UuZGF0YTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFJldm9rZSB0aGUgZ2l2ZW4gdG9rZW4uXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgcmV2b2tlKHRva2VuKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZGVsZXRlKCcvb2F1dGgvdG9rZW5zLycgKyB0b2tlbi5pZClcXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0VG9rZW5zKCk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfVxcbiAgICB9XFxuPC9zY3JpcHQ+XFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtZGUwZDBlNGVcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9BdXRob3JpemVkQ2xpZW50cy52dWVcbi8vIG1vZHVsZSBpZCA9IDI2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0="); /***/ }), /* 27 */ /***/ (function(module, exports, __webpack_require__) { -eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {\n\tif ( true ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(3) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\n\n$.ui = $.ui || {};\n\nreturn $.ui.version = \"1.12.1\";\n\n} ) );\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2pxdWVyeS11aS91aS92ZXJzaW9uLmpzP2JkNDEiXSwic291cmNlc0NvbnRlbnQiOlsiKCBmdW5jdGlvbiggZmFjdG9yeSApIHtcblx0aWYgKCB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCApIHtcblxuXHRcdC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cblx0XHRkZWZpbmUoIFsgXCJqcXVlcnlcIiBdLCBmYWN0b3J5ICk7XG5cdH0gZWxzZSB7XG5cblx0XHQvLyBCcm93c2VyIGdsb2JhbHNcblx0XHRmYWN0b3J5KCBqUXVlcnkgKTtcblx0fVxufSAoIGZ1bmN0aW9uKCAkICkge1xuXG4kLnVpID0gJC51aSB8fCB7fTtcblxucmV0dXJuICQudWkudmVyc2lvbiA9IFwiMS4xMi4xXCI7XG5cbn0gKSApO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2pxdWVyeS11aS91aS92ZXJzaW9uLmpzXG4vLyBtb2R1bGUgaWQgPSAyN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9"); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.action-link[data-v-e9c80318] {\\n cursor: pointer;\\n}\\n.m-b-none[data-v-e9c80318] {\\n margin-bottom: 0;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/passport/Clients.vue?35867ce4\"],\"names\":[],\"mappings\":\";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA\",\"file\":\"Clients.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQ2xpZW50cy52dWU/MGI2ZSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5hY3Rpb24tbGlua1tkYXRhLXYtZTljODAzMThdIHtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4ubS1iLW5vbmVbZGF0YS12LWU5YzgwMzE4XSB7XFxuICAgIG1hcmdpbi1ib3R0b206IDA7XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi4vLi4vLi4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlPzM1ODY3Y2U0XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFDQTtJQUNBLGdCQUFBO0NBQ0E7QUFFQTtJQUNBLGlCQUFBO0NBQ0FcIixcImZpbGVcIjpcIkNsaWVudHMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxuICAgIC5hY3Rpb24tbGluayB7XFxuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XFxuICAgIH1cXG5cXG4gICAgLm0tYi1ub25lIHtcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICAgIH1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsIHBhbmVsLWRlZmF1bHRcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsLWhlYWRpbmdcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVxcXCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIE9BdXRoIENsaWVudHNcXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGlua1xcXCIgQGNsaWNrPVxcXCJzaG93Q3JlYXRlQ2xpZW50Rm9ybVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIE5ldyBDbGllbnRcXG4gICAgICAgICAgICAgICAgICAgIDwvYT5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgIDwhLS0gQ3VycmVudCBDbGllbnRzIC0tPlxcbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cXFwibS1iLW5vbmVcXFwiIHYtaWY9XFxcImNsaWVudHMubGVuZ3RoID09PSAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIFlvdSBoYXZlIG5vdCBjcmVhdGVkIGFueSBPQXV0aCBjbGllbnRzLlxcbiAgICAgICAgICAgICAgICA8L3A+XFxuXFxuICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cXFwidGFibGUgdGFibGUtYm9yZGVybGVzcyBtLWItbm9uZVxcXCIgdi1pZj1cXFwiY2xpZW50cy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5DbGllbnQgSUQ8L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+TmFtZTwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5TZWNyZXQ8L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+PC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPjwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8dGJvZHk+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyIHYtZm9yPVxcXCJjbGllbnQgaW4gY2xpZW50c1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gSUQgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY2xpZW50LmlkIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjbGllbnQubmFtZSB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFNlY3JldCAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT57eyBjbGllbnQuc2VjcmV0IH19PC9jb2RlPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEVkaXQgQnV0dG9uIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGlua1xcXCIgQGNsaWNrPVxcXCJlZGl0KGNsaWVudClcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWxldGUgQnV0dG9uIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclxcXCIgQGNsaWNrPVxcXCJkZXN0cm95KGNsaWVudClcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XFxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgICAgICA8L3RhYmxlPlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICA8IS0tIENyZWF0ZSBDbGllbnQgTW9kYWwgLS0+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbCBmYWRlXFxcIiBpZD1cXFwibW9kYWwtY3JlYXRlLWNsaWVudFxcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIiByb2xlPVxcXCJkaWFsb2dcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvbiBcXFwiIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiPiZ0aW1lczs8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIENsaWVudFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaDQ+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRm9ybSBFcnJvcnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiYWxlcnQgYWxlcnQtZGFuZ2VyXFxcIiB2LWlmPVxcXCJjcmVhdGVGb3JtLmVycm9ycy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+PHN0cm9uZz5XaG9vcHMhPC9zdHJvbmc+IFNvbWV0aGluZyB3ZW50IHdyb25nITwvcD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgdi1mb3I9XFxcImVycm9yIGluIGNyZWF0ZUZvcm0uZXJyb3JzXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBlcnJvciB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENyZWF0ZSBDbGllbnQgRm9ybSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8Zm9ybSBjbGFzcz1cXFwiZm9ybS1ob3Jpem9udGFsXFxcIiByb2xlPVxcXCJmb3JtXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBOYW1lIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cXFwiY29sLW1kLTMgY29udHJvbC1sYWJlbFxcXCI+TmFtZTwvbGFiZWw+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtN1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPVxcXCJjcmVhdGUtY2xpZW50LW5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cXFwic3RvcmVcXFwiIHYtbW9kZWw9XFxcImNyZWF0ZUZvcm0ubmFtZVxcXCI+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImhlbHAtYmxvY2tcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21ldGhpbmcgeW91ciB1c2VycyB3aWxsIHJlY29nbml6ZSBhbmQgdHJ1c3QuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFJlZGlyZWN0IFVSTCAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZm9ybS1ncm91cFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC0zIGNvbnRyb2wtbGFiZWxcXFwiPlJlZGlyZWN0IFVSTDwvbGFiZWw+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtN1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIG5hbWU9XFxcInJlZGlyZWN0XFxcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAa2V5dXAuZW50ZXI9XFxcInN0b3JlXFxcIiB2LW1vZGVsPVxcXCJjcmVhdGVGb3JtLnJlZGlyZWN0XFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiaGVscC1ibG9ja1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlvdXIgYXBwbGljYXRpb24ncyBhdXRob3JpemF0aW9uIGNhbGxiYWNrIFVSTC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9mb3JtPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8IS0tIE1vZGFsIEFjdGlvbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1mb290ZXJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYnRuIGJ0bi1kZWZhdWx0XFxcIiBkYXRhLWRpc21pc3M9XFxcIm1vZGFsXFxcIj5DbG9zZTwvYnV0dG9uPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYnRuIGJ0bi1wcmltYXJ5XFxcIiBAY2xpY2s9XFxcInN0b3JlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgIDwhLS0gRWRpdCBDbGllbnQgTW9kYWwgLS0+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbCBmYWRlXFxcIiBpZD1cXFwibW9kYWwtZWRpdC1jbGllbnRcXFwiIHRhYmluZGV4PVxcXCItMVxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIj5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1kaWFsb2dcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1jb250ZW50XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b24gXFxcIiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj4mdGltZXM7PC9idXR0b24+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVxcXCJtb2RhbC10aXRsZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVkaXQgQ2xpZW50XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9oND5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtIEVycm9ycyAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhbGVydCBhbGVydC1kYW5nZXJcXFwiIHYtaWY9XFxcImVkaXRGb3JtLmVycm9ycy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+PHN0cm9uZz5XaG9vcHMhPC9zdHJvbmc+IFNvbWV0aGluZyB3ZW50IHdyb25nITwvcD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgdi1mb3I9XFxcImVycm9yIGluIGVkaXRGb3JtLmVycm9yc1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZXJyb3IgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFZGl0IENsaWVudCBGb3JtIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxmb3JtIGNsYXNzPVxcXCJmb3JtLWhvcml6b250YWxcXFwiIHJvbGU9XFxcImZvcm1cXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5hbWUgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVxcXCJjb2wtbWQtMyBjb250cm9sLWxhYmVsXFxcIj5OYW1lPC9sYWJlbD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC03XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XFxcImVkaXQtY2xpZW50LW5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cXFwidXBkYXRlXFxcIiB2LW1vZGVsPVxcXCJlZGl0Rm9ybS5uYW1lXFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiaGVscC1ibG9ja1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvbWV0aGluZyB5b3VyIHVzZXJzIHdpbGwgcmVjb2duaXplIGFuZCB0cnVzdC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmVkaXJlY3QgVVJMIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cXFwiY29sLW1kLTMgY29udHJvbC1sYWJlbFxcXCI+UmVkaXJlY3QgVVJMPC9sYWJlbD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC03XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cXFwidGV4dFxcXCIgY2xhc3M9XFxcImZvcm0tY29udHJvbFxcXCIgbmFtZT1cXFwicmVkaXJlY3RcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cXFwidXBkYXRlXFxcIiB2LW1vZGVsPVxcXCJlZGl0Rm9ybS5yZWRpcmVjdFxcXCI+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImhlbHAtYmxvY2tcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZb3VyIGFwcGxpY2F0aW9uJ3MgYXV0aG9yaXphdGlvbiBjYWxsYmFjayBVUkwuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNb2RhbCBBY3Rpb25zIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtZm9vdGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tZGVmYXVsdFxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCI+Q2xvc2U8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tcHJpbWFyeVxcXCIgQGNsaWNrPVxcXCJ1cGRhdGVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTYXZlIENoYW5nZXNcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICA8L2Rpdj5cXG48L3RlbXBsYXRlPlxcblxcbjxzY3JpcHQ+XFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXG4gICAgICAgIC8qXFxuICAgICAgICAgKiBUaGUgY29tcG9uZW50J3MgZGF0YS5cXG4gICAgICAgICAqL1xcbiAgICAgICAgZGF0YSgpIHtcXG4gICAgICAgICAgICByZXR1cm4ge1xcbiAgICAgICAgICAgICAgICBjbGllbnRzOiBbXSxcXG5cXG4gICAgICAgICAgICAgICAgY3JlYXRlRm9ybToge1xcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzOiBbXSxcXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICcnLFxcbiAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3Q6ICcnXFxuICAgICAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgICAgIGVkaXRGb3JtOiB7XFxuICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IFtdLFxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJycsXFxuICAgICAgICAgICAgICAgICAgICByZWRpcmVjdDogJydcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICByZWFkeSgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBwcmVwYXJlQ29tcG9uZW50KCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldENsaWVudHMoKTtcXG5cXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWNyZWF0ZS1jbGllbnQnKS5vbignc2hvd24uYnMubW9kYWwnLCAoKSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAkKCcjY3JlYXRlLWNsaWVudC1uYW1lJykuZm9jdXMoKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuXFxuICAgICAgICAgICAgICAgICQoJyNtb2RhbC1lZGl0LWNsaWVudCcpLm9uKCdzaG93bi5icy5tb2RhbCcsICgpID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICQoJyNlZGl0LWNsaWVudC1uYW1lJykuZm9jdXMoKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBPQXV0aCBjbGllbnRzIGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBnZXRDbGllbnRzKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmdldCgnL29hdXRoL2NsaWVudHMnKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGllbnRzID0gcmVzcG9uc2UuZGF0YTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFNob3cgdGhlIGZvcm0gZm9yIGNyZWF0aW5nIG5ldyBjbGllbnRzLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHNob3dDcmVhdGVDbGllbnRGb3JtKCkge1xcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLWNsaWVudCcpLm1vZGFsKCdzaG93Jyk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBDcmVhdGUgYSBuZXcgT0F1dGggY2xpZW50IGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzdG9yZSgpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5wZXJzaXN0Q2xpZW50KFxcbiAgICAgICAgICAgICAgICAgICAgJ3Bvc3QnLCAnL29hdXRoL2NsaWVudHMnLFxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVGb3JtLCAnI21vZGFsLWNyZWF0ZS1jbGllbnQnXFxuICAgICAgICAgICAgICAgICk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBFZGl0IHRoZSBnaXZlbiBjbGllbnQuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgZWRpdChjbGllbnQpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybS5pZCA9IGNsaWVudC5pZDtcXG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybS5uYW1lID0gY2xpZW50Lm5hbWU7XFxuICAgICAgICAgICAgICAgIHRoaXMuZWRpdEZvcm0ucmVkaXJlY3QgPSBjbGllbnQucmVkaXJlY3Q7XFxuXFxuICAgICAgICAgICAgICAgICQoJyNtb2RhbC1lZGl0LWNsaWVudCcpLm1vZGFsKCdzaG93Jyk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBVcGRhdGUgdGhlIGNsaWVudCBiZWluZyBlZGl0ZWQuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgdXBkYXRlKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLnBlcnNpc3RDbGllbnQoXFxuICAgICAgICAgICAgICAgICAgICAncHV0JywgJy9vYXV0aC9jbGllbnRzLycgKyB0aGlzLmVkaXRGb3JtLmlkLFxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybSwgJyNtb2RhbC1lZGl0LWNsaWVudCdcXG4gICAgICAgICAgICAgICAgKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFBlcnNpc3QgdGhlIGNsaWVudCB0byBzdG9yYWdlIHVzaW5nIHRoZSBnaXZlbiBmb3JtLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHBlcnNpc3RDbGllbnQobWV0aG9kLCB1cmksIGZvcm0sIG1vZGFsKSB7XFxuICAgICAgICAgICAgICAgIGZvcm0uZXJyb3JzID0gW107XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHBbbWV0aG9kXSh1cmksIGZvcm0pXFxuICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRDbGllbnRzKCk7XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5uYW1lID0gJyc7XFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5yZWRpcmVjdCA9ICcnO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm0uZXJyb3JzID0gW107XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgJChtb2RhbCkubW9kYWwoJ2hpZGUnKTtcXG4gICAgICAgICAgICAgICAgICAgIH0pXFxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2gocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzcG9uc2UuZGF0YSA9PT0gJ29iamVjdCcpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5lcnJvcnMgPSBfLmZsYXR0ZW4oXy50b0FycmF5KHJlc3BvbnNlLmRhdGEpKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtLmVycm9ycyA9IFsnU29tZXRoaW5nIHdlbnQgd3JvbmcuIFBsZWFzZSB0cnkgYWdhaW4uJ107XFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBEZXN0cm95IHRoZSBnaXZlbiBjbGllbnQuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgZGVzdHJveShjbGllbnQpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5kZWxldGUoJy9vYXV0aC9jbGllbnRzLycgKyBjbGllbnQuaWQpXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldENsaWVudHMoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIH1cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1lOWM4MDMxOFwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlXG4vLyBtb2R1bGUgaWQgPSAyN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9"); /***/ }), /* 28 */ /***/ (function(module, exports, __webpack_require__) { -eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * jQuery UI Widget 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Widget\n//>>group: Core\n//>>description: Provides a factory for creating stateful widgets with a common API.\n//>>docs: http://api.jqueryui.com/jQuery.widget/\n//>>demos: http://jqueryui.com/widget/\n\n( function( factory ) {\n\tif ( true ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(3), __webpack_require__(27) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n\nvar widgetUuid = 0;\nvar widgetSlice = Array.prototype.slice;\n\n$.cleanData = ( function( orig ) {\n\treturn function( elems ) {\n\t\tvar events, elem, i;\n\t\tfor ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\ttry {\n\n\t\t\t\t// Only trigger remove when necessary to save time\n\t\t\t\tevents = $._data( elem, \"events\" );\n\t\t\t\tif ( events && events.remove ) {\n\t\t\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t\t\t}\n\n\t\t\t// Http://bugs.jquery.com/ticket/8235\n\t\t\t} catch ( e ) {}\n\t\t}\n\t\torig( elems );\n\t};\n} )( $.cleanData );\n\n$.widget = function( name, base, prototype ) {\n\tvar existingConstructor, constructor, basePrototype;\n\n\t// ProxiedPrototype allows the provided prototype to remain unmodified\n\t// so that it can be used as a mixin for multiple widgets (#8876)\n\tvar proxiedPrototype = {};\n\n\tvar namespace = name.split( \".\" )[ 0 ];\n\tname = name.split( \".\" )[ 1 ];\n\tvar fullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\tif ( $.isArray( prototype ) ) {\n\t\tprototype = $.extend.apply( null, [ {} ].concat( prototype ) );\n\t}\n\n\t// Create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\n\t\t// Allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// Allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\n\t// Extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\n\t\t// Copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\n\t\t// Track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t} );\n\n\tbasePrototype = new base();\n\n\t// We need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = ( function() {\n\t\t\tfunction _super() {\n\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t}\n\n\t\t\tfunction _superApply( args ) {\n\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t}\n\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super;\n\t\t\t\tvar __superApply = this._superApply;\n\t\t\t\tvar returnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t} )();\n\t} );\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t} );\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// Redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor,\n\t\t\t\tchild._proto );\n\t\t} );\n\n\t\t// Remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n\n\treturn constructor;\n};\n\n$.widget.extend = function( target ) {\n\tvar input = widgetSlice.call( arguments, 1 );\n\tvar inputIndex = 0;\n\tvar inputLength = input.length;\n\tvar key;\n\tvar value;\n\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\";\n\t\tvar args = widgetSlice.call( arguments, 1 );\n\t\tvar returnValue = this;\n\n\t\tif ( isMethodCall ) {\n\n\t\t\t// If this is an empty collection, we need to have the instance method\n\t\t\t// return undefined instead of the jQuery instance\n\t\t\tif ( !this.length && options === \"instance\" ) {\n\t\t\t\treturnValue = undefined;\n\t\t\t} else {\n\t\t\t\tthis.each( function() {\n\t\t\t\t\tvar methodValue;\n\t\t\t\t\tvar instance = $.data( this, fullName );\n\n\t\t\t\t\tif ( options === \"instance\" ) {\n\t\t\t\t\t\treturnValue = instance;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !instance ) {\n\t\t\t\t\t\treturn $.error( \"cannot call methods on \" + name +\n\t\t\t\t\t\t\t\" prior to initialization; \" +\n\t\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name +\n\t\t\t\t\t\t\t\" widget instance\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\n\t\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\t\tmethodValue;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// Allow multiple hashes to be passed on init\n\t\t\tif ( args.length ) {\n\t\t\t\toptions = $.widget.extend.apply( null, [ options ].concat( args ) );\n\t\t\t}\n\n\t\t\tthis.each( function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} );\n\t\t\t\t\tif ( instance._init ) {\n\t\t\t\t\t\tinstance._init();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"
\",\n\n\toptions: {\n\t\tclasses: {},\n\t\tdisabled: false,\n\n\t\t// Callbacks\n\t\tcreate: null\n\t},\n\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = widgetUuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\t\tthis.classesElementLookup = {};\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t\tthis.document = $( element.style ?\n\n\t\t\t\t// Element within the document\n\t\t\t\telement.ownerDocument :\n\n\t\t\t\t// Element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );\n\t\t}\n\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis._create();\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._setOptionDisabled( this.options.disabled );\n\t\t}\n\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\n\t_getCreateOptions: function() {\n\t\treturn {};\n\t},\n\n\t_getCreateEventData: $.noop,\n\n\t_create: $.noop,\n\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tvar that = this;\n\n\t\tthis._destroy();\n\t\t$.each( this.classesElementLookup, function( key, value ) {\n\t\t\tthat._removeClass( value, key );\n\t\t} );\n\n\t\t// We can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeData( this.widgetFullName );\n\t\tthis.widget()\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" );\n\n\t\t// Clean up events and states\n\t\tthis.bindings.off( this.eventNamespace );\n\t},\n\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key;\n\t\tvar parts;\n\t\tvar curOption;\n\t\tvar i;\n\n\t\tif ( arguments.length === 0 ) {\n\n\t\t\t// Don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\n\t\t\t// Handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"classes\" ) {\n\t\t\tthis._setOptionClasses( value );\n\t\t}\n\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis._setOptionDisabled( value );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOptionClasses: function( value ) {\n\t\tvar classKey, elements, currentElements;\n\n\t\tfor ( classKey in value ) {\n\t\t\tcurrentElements = this.classesElementLookup[ classKey ];\n\t\t\tif ( value[ classKey ] === this.options.classes[ classKey ] ||\n\t\t\t\t\t!currentElements ||\n\t\t\t\t\t!currentElements.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// We are doing this to create a new jQuery object because the _removeClass() call\n\t\t\t// on the next line is going to destroy the reference to the current elements being\n\t\t\t// tracked. We need to save a copy of this collection so that we can add the new classes\n\t\t\t// below.\n\t\t\telements = $( currentElements.get() );\n\t\t\tthis._removeClass( currentElements, classKey );\n\n\t\t\t// We don't use _addClass() here, because that uses this.options.classes\n\t\t\t// for generating the string of classes. We want to use the value passed in from\n\t\t\t// _setOption(), this is the new value of the classes option which was passed to\n\t\t\t// _setOption(). We pass this value directly to _classes().\n\t\t\telements.addClass( this._classes( {\n\t\t\t\telement: elements,\n\t\t\t\tkeys: classKey,\n\t\t\t\tclasses: value,\n\t\t\t\tadd: true\n\t\t\t} ) );\n\t\t}\n\t},\n\n\t_setOptionDisabled: function( value ) {\n\t\tthis._toggleClass( this.widget(), this.widgetFullName + \"-disabled\", null, !!value );\n\n\t\t// If the widget is becoming disabled, then nothing is interactive\n\t\tif ( value ) {\n\t\t\tthis._removeClass( this.hoverable, null, \"ui-state-hover\" );\n\t\t\tthis._removeClass( this.focusable, null, \"ui-state-focus\" );\n\t\t}\n\t},\n\n\tenable: function() {\n\t\treturn this._setOptions( { disabled: false } );\n\t},\n\n\tdisable: function() {\n\t\treturn this._setOptions( { disabled: true } );\n\t},\n\n\t_classes: function( options ) {\n\t\tvar full = [];\n\t\tvar that = this;\n\n\t\toptions = $.extend( {\n\t\t\telement: this.element,\n\t\t\tclasses: this.options.classes || {}\n\t\t}, options );\n\n\t\tfunction processClassString( classes, checkOption ) {\n\t\t\tvar current, i;\n\t\t\tfor ( i = 0; i < classes.length; i++ ) {\n\t\t\t\tcurrent = that.classesElementLookup[ classes[ i ] ] || $();\n\t\t\t\tif ( options.add ) {\n\t\t\t\t\tcurrent = $( $.unique( current.get().concat( options.element.get() ) ) );\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = $( current.not( options.element ).get() );\n\t\t\t\t}\n\t\t\t\tthat.classesElementLookup[ classes[ i ] ] = current;\n\t\t\t\tfull.push( classes[ i ] );\n\t\t\t\tif ( checkOption && options.classes[ classes[ i ] ] ) {\n\t\t\t\t\tfull.push( options.classes[ classes[ i ] ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._on( options.element, {\n\t\t\t\"remove\": \"_untrackClassesElement\"\n\t\t} );\n\n\t\tif ( options.keys ) {\n\t\t\tprocessClassString( options.keys.match( /\\S+/g ) || [], true );\n\t\t}\n\t\tif ( options.extra ) {\n\t\t\tprocessClassString( options.extra.match( /\\S+/g ) || [] );\n\t\t}\n\n\t\treturn full.join( \" \" );\n\t},\n\n\t_untrackClassesElement: function( event ) {\n\t\tvar that = this;\n\t\t$.each( that.classesElementLookup, function( key, value ) {\n\t\t\tif ( $.inArray( event.target, value ) !== -1 ) {\n\t\t\t\tthat.classesElementLookup[ key ] = $( value.not( event.target ).get() );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_removeClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, false );\n\t},\n\n\t_addClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, true );\n\t},\n\n\t_toggleClass: function( element, keys, extra, add ) {\n\t\tadd = ( typeof add === \"boolean\" ) ? add : extra;\n\t\tvar shift = ( typeof element === \"string\" || element === null ),\n\t\t\toptions = {\n\t\t\t\textra: shift ? keys : extra,\n\t\t\t\tkeys: shift ? element : keys,\n\t\t\t\telement: shift ? this.element : element,\n\t\t\t\tadd: add\n\t\t\t};\n\t\toptions.element.toggleClass( this._classes( options ), add );\n\t\treturn this;\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement;\n\t\tvar instance = this;\n\n\t\t// No suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// No element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\n\t\t\t\t// Allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// Copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^([\\w:-]*)\\s*(.*)$/ );\n\t\t\tvar eventName = match[ 1 ] + instance.eventNamespace;\n\t\t\tvar selector = match[ 2 ];\n\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.on( eventName, selector, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.on( eventName, handlerProxy );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = ( eventName || \"\" ).split( \" \" ).join( this.eventNamespace + \" \" ) +\n\t\t\tthis.eventNamespace;\n\t\telement.off( eventName ).off( eventName );\n\n\t\t// Clear the stack to avoid memory leaks (#10056)\n\t\tthis.bindings = $( this.bindings.not( element ).get() );\n\t\tthis.focusable = $( this.focusable.not( element ).get() );\n\t\tthis.hoverable = $( this.hoverable.not( element ).get() );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig;\n\t\tvar callback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\n\t\t// The original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// Copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\n\t\tvar hasOptions;\n\t\tvar effectName = !options ?\n\t\t\tmethod :\n\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\tdefaultEffect :\n\t\t\t\toptions.effect || defaultEffect;\n\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue( function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t} );\n\t\t}\n\t};\n} );\n\nreturn $.widget;\n\n} ) );\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjguanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2pxdWVyeS11aS91aS93aWRnZXQuanM/NDliZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIGpRdWVyeSBVSSBXaWRnZXQgMS4xMi4xXG4gKiBodHRwOi8vanF1ZXJ5dWkuY29tXG4gKlxuICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqL1xuXG4vLz4+bGFiZWw6IFdpZGdldFxuLy8+Pmdyb3VwOiBDb3JlXG4vLz4+ZGVzY3JpcHRpb246IFByb3ZpZGVzIGEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgc3RhdGVmdWwgd2lkZ2V0cyB3aXRoIGEgY29tbW9uIEFQSS5cbi8vPj5kb2NzOiBodHRwOi8vYXBpLmpxdWVyeXVpLmNvbS9qUXVlcnkud2lkZ2V0L1xuLy8+PmRlbW9zOiBodHRwOi8vanF1ZXJ5dWkuY29tL3dpZGdldC9cblxuKCBmdW5jdGlvbiggZmFjdG9yeSApIHtcblx0aWYgKCB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCApIHtcblxuXHRcdC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cblx0XHRkZWZpbmUoIFsgXCJqcXVlcnlcIiwgXCIuL3ZlcnNpb25cIiBdLCBmYWN0b3J5ICk7XG5cdH0gZWxzZSB7XG5cblx0XHQvLyBCcm93c2VyIGdsb2JhbHNcblx0XHRmYWN0b3J5KCBqUXVlcnkgKTtcblx0fVxufSggZnVuY3Rpb24oICQgKSB7XG5cbnZhciB3aWRnZXRVdWlkID0gMDtcbnZhciB3aWRnZXRTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcblxuJC5jbGVhbkRhdGEgPSAoIGZ1bmN0aW9uKCBvcmlnICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW1zICkge1xuXHRcdHZhciBldmVudHMsIGVsZW0sIGk7XG5cdFx0Zm9yICggaSA9IDA7ICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHR0cnkge1xuXG5cdFx0XHRcdC8vIE9ubHkgdHJpZ2dlciByZW1vdmUgd2hlbiBuZWNlc3NhcnkgdG8gc2F2ZSB0aW1lXG5cdFx0XHRcdGV2ZW50cyA9ICQuX2RhdGEoIGVsZW0sIFwiZXZlbnRzXCIgKTtcblx0XHRcdFx0aWYgKCBldmVudHMgJiYgZXZlbnRzLnJlbW92ZSApIHtcblx0XHRcdFx0XHQkKCBlbGVtICkudHJpZ2dlckhhbmRsZXIoIFwicmVtb3ZlXCIgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBIdHRwOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC84MjM1XG5cdFx0XHR9IGNhdGNoICggZSApIHt9XG5cdFx0fVxuXHRcdG9yaWcoIGVsZW1zICk7XG5cdH07XG59ICkoICQuY2xlYW5EYXRhICk7XG5cbiQud2lkZ2V0ID0gZnVuY3Rpb24oIG5hbWUsIGJhc2UsIHByb3RvdHlwZSApIHtcblx0dmFyIGV4aXN0aW5nQ29uc3RydWN0b3IsIGNvbnN0cnVjdG9yLCBiYXNlUHJvdG90eXBlO1xuXG5cdC8vIFByb3hpZWRQcm90b3R5cGUgYWxsb3dzIHRoZSBwcm92aWRlZCBwcm90b3R5cGUgdG8gcmVtYWluIHVubW9kaWZpZWRcblx0Ly8gc28gdGhhdCBpdCBjYW4gYmUgdXNlZCBhcyBhIG1peGluIGZvciBtdWx0aXBsZSB3aWRnZXRzICgjODg3Nilcblx0dmFyIHByb3hpZWRQcm90b3R5cGUgPSB7fTtcblxuXHR2YXIgbmFtZXNwYWNlID0gbmFtZS5zcGxpdCggXCIuXCIgKVsgMCBdO1xuXHRuYW1lID0gbmFtZS5zcGxpdCggXCIuXCIgKVsgMSBdO1xuXHR2YXIgZnVsbE5hbWUgPSBuYW1lc3BhY2UgKyBcIi1cIiArIG5hbWU7XG5cblx0aWYgKCAhcHJvdG90eXBlICkge1xuXHRcdHByb3RvdHlwZSA9IGJhc2U7XG5cdFx0YmFzZSA9ICQuV2lkZ2V0O1xuXHR9XG5cblx0aWYgKCAkLmlzQXJyYXkoIHByb3RvdHlwZSApICkge1xuXHRcdHByb3RvdHlwZSA9ICQuZXh0ZW5kLmFwcGx5KCBudWxsLCBbIHt9IF0uY29uY2F0KCBwcm90b3R5cGUgKSApO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIHNlbGVjdG9yIGZvciBwbHVnaW5cblx0JC5leHByWyBcIjpcIiBdWyBmdWxsTmFtZS50b0xvd2VyQ2FzZSgpIF0gPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gISEkLmRhdGEoIGVsZW0sIGZ1bGxOYW1lICk7XG5cdH07XG5cblx0JFsgbmFtZXNwYWNlIF0gPSAkWyBuYW1lc3BhY2UgXSB8fCB7fTtcblx0ZXhpc3RpbmdDb25zdHJ1Y3RvciA9ICRbIG5hbWVzcGFjZSBdWyBuYW1lIF07XG5cdGNvbnN0cnVjdG9yID0gJFsgbmFtZXNwYWNlIF1bIG5hbWUgXSA9IGZ1bmN0aW9uKCBvcHRpb25zLCBlbGVtZW50ICkge1xuXG5cdFx0Ly8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IFwibmV3XCIga2V5d29yZFxuXHRcdGlmICggIXRoaXMuX2NyZWF0ZVdpZGdldCApIHtcblx0XHRcdHJldHVybiBuZXcgY29uc3RydWN0b3IoIG9wdGlvbnMsIGVsZW1lbnQgKTtcblx0XHR9XG5cblx0XHQvLyBBbGxvdyBpbnN0YW50aWF0aW9uIHdpdGhvdXQgaW5pdGlhbGl6aW5nIGZvciBzaW1wbGUgaW5oZXJpdGFuY2Vcblx0XHQvLyBtdXN0IHVzZSBcIm5ld1wiIGtleXdvcmQgKHRoZSBjb2RlIGFib3ZlIGFsd2F5cyBwYXNzZXMgYXJncylcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHR0aGlzLl9jcmVhdGVXaWRnZXQoIG9wdGlvbnMsIGVsZW1lbnQgKTtcblx0XHR9XG5cdH07XG5cblx0Ly8gRXh0ZW5kIHdpdGggdGhlIGV4aXN0aW5nIGNvbnN0cnVjdG9yIHRvIGNhcnJ5IG92ZXIgYW55IHN0YXRpYyBwcm9wZXJ0aWVzXG5cdCQuZXh0ZW5kKCBjb25zdHJ1Y3RvciwgZXhpc3RpbmdDb25zdHJ1Y3Rvciwge1xuXHRcdHZlcnNpb246IHByb3RvdHlwZS52ZXJzaW9uLFxuXG5cdFx0Ly8gQ29weSB0aGUgb2JqZWN0IHVzZWQgdG8gY3JlYXRlIHRoZSBwcm90b3R5cGUgaW4gY2FzZSB3ZSBuZWVkIHRvXG5cdFx0Ly8gcmVkZWZpbmUgdGhlIHdpZGdldCBsYXRlclxuXHRcdF9wcm90bzogJC5leHRlbmQoIHt9LCBwcm90b3R5cGUgKSxcblxuXHRcdC8vIFRyYWNrIHdpZGdldHMgdGhhdCBpbmhlcml0IGZyb20gdGhpcyB3aWRnZXQgaW4gY2FzZSB0aGlzIHdpZGdldCBpc1xuXHRcdC8vIHJlZGVmaW5lZCBhZnRlciBhIHdpZGdldCBpbmhlcml0cyBmcm9tIGl0XG5cdFx0X2NoaWxkQ29uc3RydWN0b3JzOiBbXVxuXHR9ICk7XG5cblx0YmFzZVByb3RvdHlwZSA9IG5ldyBiYXNlKCk7XG5cblx0Ly8gV2UgbmVlZCB0byBtYWtlIHRoZSBvcHRpb25zIGhhc2ggYSBwcm9wZXJ0eSBkaXJlY3RseSBvbiB0aGUgbmV3IGluc3RhbmNlXG5cdC8vIG90aGVyd2lzZSB3ZSdsbCBtb2RpZnkgdGhlIG9wdGlvbnMgaGFzaCBvbiB0aGUgcHJvdG90eXBlIHRoYXQgd2UncmVcblx0Ly8gaW5oZXJpdGluZyBmcm9tXG5cdGJhc2VQcm90b3R5cGUub3B0aW9ucyA9ICQud2lkZ2V0LmV4dGVuZCgge30sIGJhc2VQcm90b3R5cGUub3B0aW9ucyApO1xuXHQkLmVhY2goIHByb3RvdHlwZSwgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkge1xuXHRcdGlmICggISQuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHByb3hpZWRQcm90b3R5cGVbIHByb3AgXSA9IHZhbHVlO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRwcm94aWVkUHJvdG90eXBlWyBwcm9wIF0gPSAoIGZ1bmN0aW9uKCkge1xuXHRcdFx0ZnVuY3Rpb24gX3N1cGVyKCkge1xuXHRcdFx0XHRyZXR1cm4gYmFzZS5wcm90b3R5cGVbIHByb3AgXS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHR9XG5cblx0XHRcdGZ1bmN0aW9uIF9zdXBlckFwcGx5KCBhcmdzICkge1xuXHRcdFx0XHRyZXR1cm4gYmFzZS5wcm90b3R5cGVbIHByb3AgXS5hcHBseSggdGhpcywgYXJncyApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBfX3N1cGVyID0gdGhpcy5fc3VwZXI7XG5cdFx0XHRcdHZhciBfX3N1cGVyQXBwbHkgPSB0aGlzLl9zdXBlckFwcGx5O1xuXHRcdFx0XHR2YXIgcmV0dXJuVmFsdWU7XG5cblx0XHRcdFx0dGhpcy5fc3VwZXIgPSBfc3VwZXI7XG5cdFx0XHRcdHRoaXMuX3N1cGVyQXBwbHkgPSBfc3VwZXJBcHBseTtcblxuXHRcdFx0XHRyZXR1cm5WYWx1ZSA9IHZhbHVlLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblxuXHRcdFx0XHR0aGlzLl9zdXBlciA9IF9fc3VwZXI7XG5cdFx0XHRcdHRoaXMuX3N1cGVyQXBwbHkgPSBfX3N1cGVyQXBwbHk7XG5cblx0XHRcdFx0cmV0dXJuIHJldHVyblZhbHVlO1xuXHRcdFx0fTtcblx0XHR9ICkoKTtcblx0fSApO1xuXHRjb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSAkLndpZGdldC5leHRlbmQoIGJhc2VQcm90b3R5cGUsIHtcblxuXHRcdC8vIFRPRE86IHJlbW92ZSBzdXBwb3J0IGZvciB3aWRnZXRFdmVudFByZWZpeFxuXHRcdC8vIGFsd2F5cyB1c2UgdGhlIG5hbWUgKyBhIGNvbG9uIGFzIHRoZSBwcmVmaXgsIGUuZy4sIGRyYWdnYWJsZTpzdGFydFxuXHRcdC8vIGRvbid0IHByZWZpeCBmb3Igd2lkZ2V0cyB0aGF0IGFyZW4ndCBET00tYmFzZWRcblx0XHR3aWRnZXRFdmVudFByZWZpeDogZXhpc3RpbmdDb25zdHJ1Y3RvciA/ICggYmFzZVByb3RvdHlwZS53aWRnZXRFdmVudFByZWZpeCB8fCBuYW1lICkgOiBuYW1lXG5cdH0sIHByb3hpZWRQcm90b3R5cGUsIHtcblx0XHRjb25zdHJ1Y3RvcjogY29uc3RydWN0b3IsXG5cdFx0bmFtZXNwYWNlOiBuYW1lc3BhY2UsXG5cdFx0d2lkZ2V0TmFtZTogbmFtZSxcblx0XHR3aWRnZXRGdWxsTmFtZTogZnVsbE5hbWVcblx0fSApO1xuXG5cdC8vIElmIHRoaXMgd2lkZ2V0IGlzIGJlaW5nIHJlZGVmaW5lZCB0aGVuIHdlIG5lZWQgdG8gZmluZCBhbGwgd2lkZ2V0cyB0aGF0XG5cdC8vIGFyZSBpbmhlcml0aW5nIGZyb20gaXQgYW5kIHJlZGVmaW5lIGFsbCBvZiB0aGVtIHNvIHRoYXQgdGhleSBpbmhlcml0IGZyb21cblx0Ly8gdGhlIG5ldyB2ZXJzaW9uIG9mIHRoaXMgd2lkZ2V0LiBXZSdyZSBlc3NlbnRpYWxseSB0cnlpbmcgdG8gcmVwbGFjZSBvbmVcblx0Ly8gbGV2ZWwgaW4gdGhlIHByb3RvdHlwZSBjaGFpbi5cblx0aWYgKCBleGlzdGluZ0NvbnN0cnVjdG9yICkge1xuXHRcdCQuZWFjaCggZXhpc3RpbmdDb25zdHJ1Y3Rvci5fY2hpbGRDb25zdHJ1Y3RvcnMsIGZ1bmN0aW9uKCBpLCBjaGlsZCApIHtcblx0XHRcdHZhciBjaGlsZFByb3RvdHlwZSA9IGNoaWxkLnByb3RvdHlwZTtcblxuXHRcdFx0Ly8gUmVkZWZpbmUgdGhlIGNoaWxkIHdpZGdldCB1c2luZyB0aGUgc2FtZSBwcm90b3R5cGUgdGhhdCB3YXNcblx0XHRcdC8vIG9yaWdpbmFsbHkgdXNlZCwgYnV0IGluaGVyaXQgZnJvbSB0aGUgbmV3IHZlcnNpb24gb2YgdGhlIGJhc2Vcblx0XHRcdCQud2lkZ2V0KCBjaGlsZFByb3RvdHlwZS5uYW1lc3BhY2UgKyBcIi5cIiArIGNoaWxkUHJvdG90eXBlLndpZGdldE5hbWUsIGNvbnN0cnVjdG9yLFxuXHRcdFx0XHRjaGlsZC5fcHJvdG8gKTtcblx0XHR9ICk7XG5cblx0XHQvLyBSZW1vdmUgdGhlIGxpc3Qgb2YgZXhpc3RpbmcgY2hpbGQgY29uc3RydWN0b3JzIGZyb20gdGhlIG9sZCBjb25zdHJ1Y3RvclxuXHRcdC8vIHNvIHRoZSBvbGQgY2hpbGQgY29uc3RydWN0b3JzIGNhbiBiZSBnYXJiYWdlIGNvbGxlY3RlZFxuXHRcdGRlbGV0ZSBleGlzdGluZ0NvbnN0cnVjdG9yLl9jaGlsZENvbnN0cnVjdG9ycztcblx0fSBlbHNlIHtcblx0XHRiYXNlLl9jaGlsZENvbnN0cnVjdG9ycy5wdXNoKCBjb25zdHJ1Y3RvciApO1xuXHR9XG5cblx0JC53aWRnZXQuYnJpZGdlKCBuYW1lLCBjb25zdHJ1Y3RvciApO1xuXG5cdHJldHVybiBjb25zdHJ1Y3Rvcjtcbn07XG5cbiQud2lkZ2V0LmV4dGVuZCA9IGZ1bmN0aW9uKCB0YXJnZXQgKSB7XG5cdHZhciBpbnB1dCA9IHdpZGdldFNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMSApO1xuXHR2YXIgaW5wdXRJbmRleCA9IDA7XG5cdHZhciBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aDtcblx0dmFyIGtleTtcblx0dmFyIHZhbHVlO1xuXG5cdGZvciAoIDsgaW5wdXRJbmRleCA8IGlucHV0TGVuZ3RoOyBpbnB1dEluZGV4KysgKSB7XG5cdFx0Zm9yICgga2V5IGluIGlucHV0WyBpbnB1dEluZGV4IF0gKSB7XG5cdFx0XHR2YWx1ZSA9IGlucHV0WyBpbnB1dEluZGV4IF1bIGtleSBdO1xuXHRcdFx0aWYgKCBpbnB1dFsgaW5wdXRJbmRleCBdLmhhc093blByb3BlcnR5KCBrZXkgKSAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdC8vIENsb25lIG9iamVjdHNcblx0XHRcdFx0aWYgKCAkLmlzUGxhaW5PYmplY3QoIHZhbHVlICkgKSB7XG5cdFx0XHRcdFx0dGFyZ2V0WyBrZXkgXSA9ICQuaXNQbGFpbk9iamVjdCggdGFyZ2V0WyBrZXkgXSApID9cblx0XHRcdFx0XHRcdCQud2lkZ2V0LmV4dGVuZCgge30sIHRhcmdldFsga2V5IF0sIHZhbHVlICkgOlxuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBleHRlbmQgc3RyaW5ncywgYXJyYXlzLCBldGMuIHdpdGggb2JqZWN0c1xuXHRcdFx0XHRcdFx0JC53aWRnZXQuZXh0ZW5kKCB7fSwgdmFsdWUgKTtcblxuXHRcdFx0XHQvLyBDb3B5IGV2ZXJ5dGhpbmcgZWxzZSBieSByZWZlcmVuY2Vcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0YXJnZXRbIGtleSBdID0gdmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIHRhcmdldDtcbn07XG5cbiQud2lkZ2V0LmJyaWRnZSA9IGZ1bmN0aW9uKCBuYW1lLCBvYmplY3QgKSB7XG5cdHZhciBmdWxsTmFtZSA9IG9iamVjdC5wcm90b3R5cGUud2lkZ2V0RnVsbE5hbWUgfHwgbmFtZTtcblx0JC5mblsgbmFtZSBdID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0dmFyIGlzTWV0aG9kQ2FsbCA9IHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiO1xuXHRcdHZhciBhcmdzID0gd2lkZ2V0U2xpY2UuY2FsbCggYXJndW1lbnRzLCAxICk7XG5cdFx0dmFyIHJldHVyblZhbHVlID0gdGhpcztcblxuXHRcdGlmICggaXNNZXRob2RDYWxsICkge1xuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGFuIGVtcHR5IGNvbGxlY3Rpb24sIHdlIG5lZWQgdG8gaGF2ZSB0aGUgaW5zdGFuY2UgbWV0aG9kXG5cdFx0XHQvLyByZXR1cm4gdW5kZWZpbmVkIGluc3RlYWQgb2YgdGhlIGpRdWVyeSBpbnN0YW5jZVxuXHRcdFx0aWYgKCAhdGhpcy5sZW5ndGggJiYgb3B0aW9ucyA9PT0gXCJpbnN0YW5jZVwiICkge1xuXHRcdFx0XHRyZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0dmFyIG1ldGhvZFZhbHVlO1xuXHRcdFx0XHRcdHZhciBpbnN0YW5jZSA9ICQuZGF0YSggdGhpcywgZnVsbE5hbWUgKTtcblxuXHRcdFx0XHRcdGlmICggb3B0aW9ucyA9PT0gXCJpbnN0YW5jZVwiICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuVmFsdWUgPSBpbnN0YW5jZTtcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoICFpbnN0YW5jZSApIHtcblx0XHRcdFx0XHRcdHJldHVybiAkLmVycm9yKCBcImNhbm5vdCBjYWxsIG1ldGhvZHMgb24gXCIgKyBuYW1lICtcblx0XHRcdFx0XHRcdFx0XCIgcHJpb3IgdG8gaW5pdGlhbGl6YXRpb247IFwiICtcblx0XHRcdFx0XHRcdFx0XCJhdHRlbXB0ZWQgdG8gY2FsbCBtZXRob2QgJ1wiICsgb3B0aW9ucyArIFwiJ1wiICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKCAhJC5pc0Z1bmN0aW9uKCBpbnN0YW5jZVsgb3B0aW9ucyBdICkgfHwgb3B0aW9ucy5jaGFyQXQoIDAgKSA9PT0gXCJfXCIgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gJC5lcnJvciggXCJubyBzdWNoIG1ldGhvZCAnXCIgKyBvcHRpb25zICsgXCInIGZvciBcIiArIG5hbWUgK1xuXHRcdFx0XHRcdFx0XHRcIiB3aWRnZXQgaW5zdGFuY2VcIiApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdG1ldGhvZFZhbHVlID0gaW5zdGFuY2VbIG9wdGlvbnMgXS5hcHBseSggaW5zdGFuY2UsIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggbWV0aG9kVmFsdWUgIT09IGluc3RhbmNlICYmIG1ldGhvZFZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IG1ldGhvZFZhbHVlICYmIG1ldGhvZFZhbHVlLmpxdWVyeSA/XG5cdFx0XHRcdFx0XHRcdHJldHVyblZhbHVlLnB1c2hTdGFjayggbWV0aG9kVmFsdWUuZ2V0KCkgKSA6XG5cdFx0XHRcdFx0XHRcdG1ldGhvZFZhbHVlO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIEFsbG93IG11bHRpcGxlIGhhc2hlcyB0byBiZSBwYXNzZWQgb24gaW5pdFxuXHRcdFx0aWYgKCBhcmdzLmxlbmd0aCApIHtcblx0XHRcdFx0b3B0aW9ucyA9ICQud2lkZ2V0LmV4dGVuZC5hcHBseSggbnVsbCwgWyBvcHRpb25zIF0uY29uY2F0KCBhcmdzICkgKTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGluc3RhbmNlID0gJC5kYXRhKCB0aGlzLCBmdWxsTmFtZSApO1xuXHRcdFx0XHRpZiAoIGluc3RhbmNlICkge1xuXHRcdFx0XHRcdGluc3RhbmNlLm9wdGlvbiggb3B0aW9ucyB8fCB7fSApO1xuXHRcdFx0XHRcdGlmICggaW5zdGFuY2UuX2luaXQgKSB7XG5cdFx0XHRcdFx0XHRpbnN0YW5jZS5faW5pdCgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQkLmRhdGEoIHRoaXMsIGZ1bGxOYW1lLCBuZXcgb2JqZWN0KCBvcHRpb25zLCB0aGlzICkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXR1cm5WYWx1ZTtcblx0fTtcbn07XG5cbiQuV2lkZ2V0ID0gZnVuY3Rpb24oIC8qIG9wdGlvbnMsIGVsZW1lbnQgKi8gKSB7fTtcbiQuV2lkZ2V0Ll9jaGlsZENvbnN0cnVjdG9ycyA9IFtdO1xuXG4kLldpZGdldC5wcm90b3R5cGUgPSB7XG5cdHdpZGdldE5hbWU6IFwid2lkZ2V0XCIsXG5cdHdpZGdldEV2ZW50UHJlZml4OiBcIlwiLFxuXHRkZWZhdWx0RWxlbWVudDogXCI8ZGl2PlwiLFxuXG5cdG9wdGlvbnM6IHtcblx0XHRjbGFzc2VzOiB7fSxcblx0XHRkaXNhYmxlZDogZmFsc2UsXG5cblx0XHQvLyBDYWxsYmFja3Ncblx0XHRjcmVhdGU6IG51bGxcblx0fSxcblxuXHRfY3JlYXRlV2lkZ2V0OiBmdW5jdGlvbiggb3B0aW9ucywgZWxlbWVudCApIHtcblx0XHRlbGVtZW50ID0gJCggZWxlbWVudCB8fCB0aGlzLmRlZmF1bHRFbGVtZW50IHx8IHRoaXMgKVsgMCBdO1xuXHRcdHRoaXMuZWxlbWVudCA9ICQoIGVsZW1lbnQgKTtcblx0XHR0aGlzLnV1aWQgPSB3aWRnZXRVdWlkKys7XG5cdFx0dGhpcy5ldmVudE5hbWVzcGFjZSA9IFwiLlwiICsgdGhpcy53aWRnZXROYW1lICsgdGhpcy51dWlkO1xuXG5cdFx0dGhpcy5iaW5kaW5ncyA9ICQoKTtcblx0XHR0aGlzLmhvdmVyYWJsZSA9ICQoKTtcblx0XHR0aGlzLmZvY3VzYWJsZSA9ICQoKTtcblx0XHR0aGlzLmNsYXNzZXNFbGVtZW50TG9va3VwID0ge307XG5cblx0XHRpZiAoIGVsZW1lbnQgIT09IHRoaXMgKSB7XG5cdFx0XHQkLmRhdGEoIGVsZW1lbnQsIHRoaXMud2lkZ2V0RnVsbE5hbWUsIHRoaXMgKTtcblx0XHRcdHRoaXMuX29uKCB0cnVlLCB0aGlzLmVsZW1lbnQsIHtcblx0XHRcdFx0cmVtb3ZlOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdFx0aWYgKCBldmVudC50YXJnZXQgPT09IGVsZW1lbnQgKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmRlc3Ryb3koKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHRcdHRoaXMuZG9jdW1lbnQgPSAkKCBlbGVtZW50LnN0eWxlID9cblxuXHRcdFx0XHQvLyBFbGVtZW50IHdpdGhpbiB0aGUgZG9jdW1lbnRcblx0XHRcdFx0ZWxlbWVudC5vd25lckRvY3VtZW50IDpcblxuXHRcdFx0XHQvLyBFbGVtZW50IGlzIHdpbmRvdyBvciBkb2N1bWVudFxuXHRcdFx0XHRlbGVtZW50LmRvY3VtZW50IHx8IGVsZW1lbnQgKTtcblx0XHRcdHRoaXMud2luZG93ID0gJCggdGhpcy5kb2N1bWVudFsgMCBdLmRlZmF1bHRWaWV3IHx8IHRoaXMuZG9jdW1lbnRbIDAgXS5wYXJlbnRXaW5kb3cgKTtcblx0XHR9XG5cblx0XHR0aGlzLm9wdGlvbnMgPSAkLndpZGdldC5leHRlbmQoIHt9LFxuXHRcdFx0dGhpcy5vcHRpb25zLFxuXHRcdFx0dGhpcy5fZ2V0Q3JlYXRlT3B0aW9ucygpLFxuXHRcdFx0b3B0aW9ucyApO1xuXG5cdFx0dGhpcy5fY3JlYXRlKCk7XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5kaXNhYmxlZCApIHtcblx0XHRcdHRoaXMuX3NldE9wdGlvbkRpc2FibGVkKCB0aGlzLm9wdGlvbnMuZGlzYWJsZWQgKTtcblx0XHR9XG5cblx0XHR0aGlzLl90cmlnZ2VyKCBcImNyZWF0ZVwiLCBudWxsLCB0aGlzLl9nZXRDcmVhdGVFdmVudERhdGEoKSApO1xuXHRcdHRoaXMuX2luaXQoKTtcblx0fSxcblxuXHRfZ2V0Q3JlYXRlT3B0aW9uczogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHt9O1xuXHR9LFxuXG5cdF9nZXRDcmVhdGVFdmVudERhdGE6ICQubm9vcCxcblxuXHRfY3JlYXRlOiAkLm5vb3AsXG5cblx0X2luaXQ6ICQubm9vcCxcblxuXHRkZXN0cm95OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgdGhhdCA9IHRoaXM7XG5cblx0XHR0aGlzLl9kZXN0cm95KCk7XG5cdFx0JC5lYWNoKCB0aGlzLmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHRcdHRoYXQuX3JlbW92ZUNsYXNzKCB2YWx1ZSwga2V5ICk7XG5cdFx0fSApO1xuXG5cdFx0Ly8gV2UgY2FuIHByb2JhYmx5IHJlbW92ZSB0aGUgdW5iaW5kIGNhbGxzIGluIDIuMFxuXHRcdC8vIGFsbCBldmVudCBiaW5kaW5ncyBzaG91bGQgZ28gdGhyb3VnaCB0aGlzLl9vbigpXG5cdFx0dGhpcy5lbGVtZW50XG5cdFx0XHQub2ZmKCB0aGlzLmV2ZW50TmFtZXNwYWNlIClcblx0XHRcdC5yZW1vdmVEYXRhKCB0aGlzLndpZGdldEZ1bGxOYW1lICk7XG5cdFx0dGhpcy53aWRnZXQoKVxuXHRcdFx0Lm9mZiggdGhpcy5ldmVudE5hbWVzcGFjZSApXG5cdFx0XHQucmVtb3ZlQXR0ciggXCJhcmlhLWRpc2FibGVkXCIgKTtcblxuXHRcdC8vIENsZWFuIHVwIGV2ZW50cyBhbmQgc3RhdGVzXG5cdFx0dGhpcy5iaW5kaW5ncy5vZmYoIHRoaXMuZXZlbnROYW1lc3BhY2UgKTtcblx0fSxcblxuXHRfZGVzdHJveTogJC5ub29wLFxuXG5cdHdpZGdldDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWxlbWVudDtcblx0fSxcblxuXHRvcHRpb246IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdHZhciBvcHRpb25zID0ga2V5O1xuXHRcdHZhciBwYXJ0cztcblx0XHR2YXIgY3VyT3B0aW9uO1xuXHRcdHZhciBpO1xuXG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAwICkge1xuXG5cdFx0XHQvLyBEb24ndCByZXR1cm4gYSByZWZlcmVuY2UgdG8gdGhlIGludGVybmFsIGhhc2hcblx0XHRcdHJldHVybiAkLndpZGdldC5leHRlbmQoIHt9LCB0aGlzLm9wdGlvbnMgKTtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGVvZiBrZXkgPT09IFwic3RyaW5nXCIgKSB7XG5cblx0XHRcdC8vIEhhbmRsZSBuZXN0ZWQga2V5cywgZS5nLiwgXCJmb28uYmFyXCIgPT4geyBmb286IHsgYmFyOiBfX18gfSB9XG5cdFx0XHRvcHRpb25zID0ge307XG5cdFx0XHRwYXJ0cyA9IGtleS5zcGxpdCggXCIuXCIgKTtcblx0XHRcdGtleSA9IHBhcnRzLnNoaWZ0KCk7XG5cdFx0XHRpZiAoIHBhcnRzLmxlbmd0aCApIHtcblx0XHRcdFx0Y3VyT3B0aW9uID0gb3B0aW9uc1sga2V5IF0gPSAkLndpZGdldC5leHRlbmQoIHt9LCB0aGlzLm9wdGlvbnNbIGtleSBdICk7XG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrICkge1xuXHRcdFx0XHRcdGN1ck9wdGlvblsgcGFydHNbIGkgXSBdID0gY3VyT3B0aW9uWyBwYXJ0c1sgaSBdIF0gfHwge307XG5cdFx0XHRcdFx0Y3VyT3B0aW9uID0gY3VyT3B0aW9uWyBwYXJ0c1sgaSBdIF07XG5cdFx0XHRcdH1cblx0XHRcdFx0a2V5ID0gcGFydHMucG9wKCk7XG5cdFx0XHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdFx0XHRyZXR1cm4gY3VyT3B0aW9uWyBrZXkgXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGN1ck9wdGlvblsga2V5IF07XG5cdFx0XHRcdH1cblx0XHRcdFx0Y3VyT3B0aW9uWyBrZXkgXSA9IHZhbHVlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAxICkge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLm9wdGlvbnNbIGtleSBdID09PSB1bmRlZmluZWQgPyBudWxsIDogdGhpcy5vcHRpb25zWyBrZXkgXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRvcHRpb25zWyBrZXkgXSA9IHZhbHVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuX3NldE9wdGlvbnMoIG9wdGlvbnMgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdF9zZXRPcHRpb25zOiBmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0XHR2YXIga2V5O1xuXG5cdFx0Zm9yICgga2V5IGluIG9wdGlvbnMgKSB7XG5cdFx0XHR0aGlzLl9zZXRPcHRpb24oIGtleSwgb3B0aW9uc1sga2V5IF0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRfc2V0T3B0aW9uOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHRpZiAoIGtleSA9PT0gXCJjbGFzc2VzXCIgKSB7XG5cdFx0XHR0aGlzLl9zZXRPcHRpb25DbGFzc2VzKCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdHRoaXMub3B0aW9uc1sga2V5IF0gPSB2YWx1ZTtcblxuXHRcdGlmICgga2V5ID09PSBcImRpc2FibGVkXCIgKSB7XG5cdFx0XHR0aGlzLl9zZXRPcHRpb25EaXNhYmxlZCggdmFsdWUgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRfc2V0T3B0aW9uQ2xhc3NlczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc0tleSwgZWxlbWVudHMsIGN1cnJlbnRFbGVtZW50cztcblxuXHRcdGZvciAoIGNsYXNzS2V5IGluIHZhbHVlICkge1xuXHRcdFx0Y3VycmVudEVsZW1lbnRzID0gdGhpcy5jbGFzc2VzRWxlbWVudExvb2t1cFsgY2xhc3NLZXkgXTtcblx0XHRcdGlmICggdmFsdWVbIGNsYXNzS2V5IF0gPT09IHRoaXMub3B0aW9ucy5jbGFzc2VzWyBjbGFzc0tleSBdIHx8XG5cdFx0XHRcdFx0IWN1cnJlbnRFbGVtZW50cyB8fFxuXHRcdFx0XHRcdCFjdXJyZW50RWxlbWVudHMubGVuZ3RoICkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gV2UgYXJlIGRvaW5nIHRoaXMgdG8gY3JlYXRlIGEgbmV3IGpRdWVyeSBvYmplY3QgYmVjYXVzZSB0aGUgX3JlbW92ZUNsYXNzKCkgY2FsbFxuXHRcdFx0Ly8gb24gdGhlIG5leHQgbGluZSBpcyBnb2luZyB0byBkZXN0cm95IHRoZSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgZWxlbWVudHMgYmVpbmdcblx0XHRcdC8vIHRyYWNrZWQuIFdlIG5lZWQgdG8gc2F2ZSBhIGNvcHkgb2YgdGhpcyBjb2xsZWN0aW9uIHNvIHRoYXQgd2UgY2FuIGFkZCB0aGUgbmV3IGNsYXNzZXNcblx0XHRcdC8vIGJlbG93LlxuXHRcdFx0ZWxlbWVudHMgPSAkKCBjdXJyZW50RWxlbWVudHMuZ2V0KCkgKTtcblx0XHRcdHRoaXMuX3JlbW92ZUNsYXNzKCBjdXJyZW50RWxlbWVudHMsIGNsYXNzS2V5ICk7XG5cblx0XHRcdC8vIFdlIGRvbid0IHVzZSBfYWRkQ2xhc3MoKSBoZXJlLCBiZWNhdXNlIHRoYXQgdXNlcyB0aGlzLm9wdGlvbnMuY2xhc3Nlc1xuXHRcdFx0Ly8gZm9yIGdlbmVyYXRpbmcgdGhlIHN0cmluZyBvZiBjbGFzc2VzLiBXZSB3YW50IHRvIHVzZSB0aGUgdmFsdWUgcGFzc2VkIGluIGZyb21cblx0XHRcdC8vIF9zZXRPcHRpb24oKSwgdGhpcyBpcyB0aGUgbmV3IHZhbHVlIG9mIHRoZSBjbGFzc2VzIG9wdGlvbiB3aGljaCB3YXMgcGFzc2VkIHRvXG5cdFx0XHQvLyBfc2V0T3B0aW9uKCkuIFdlIHBhc3MgdGhpcyB2YWx1ZSBkaXJlY3RseSB0byBfY2xhc3NlcygpLlxuXHRcdFx0ZWxlbWVudHMuYWRkQ2xhc3MoIHRoaXMuX2NsYXNzZXMoIHtcblx0XHRcdFx0ZWxlbWVudDogZWxlbWVudHMsXG5cdFx0XHRcdGtleXM6IGNsYXNzS2V5LFxuXHRcdFx0XHRjbGFzc2VzOiB2YWx1ZSxcblx0XHRcdFx0YWRkOiB0cnVlXG5cdFx0XHR9ICkgKTtcblx0XHR9XG5cdH0sXG5cblx0X3NldE9wdGlvbkRpc2FibGVkOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dGhpcy5fdG9nZ2xlQ2xhc3MoIHRoaXMud2lkZ2V0KCksIHRoaXMud2lkZ2V0RnVsbE5hbWUgKyBcIi1kaXNhYmxlZFwiLCBudWxsLCAhIXZhbHVlICk7XG5cblx0XHQvLyBJZiB0aGUgd2lkZ2V0IGlzIGJlY29taW5nIGRpc2FibGVkLCB0aGVuIG5vdGhpbmcgaXMgaW50ZXJhY3RpdmVcblx0XHRpZiAoIHZhbHVlICkge1xuXHRcdFx0dGhpcy5fcmVtb3ZlQ2xhc3MoIHRoaXMuaG92ZXJhYmxlLCBudWxsLCBcInVpLXN0YXRlLWhvdmVyXCIgKTtcblx0XHRcdHRoaXMuX3JlbW92ZUNsYXNzKCB0aGlzLmZvY3VzYWJsZSwgbnVsbCwgXCJ1aS1zdGF0ZS1mb2N1c1wiICk7XG5cdFx0fVxuXHR9LFxuXG5cdGVuYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoIHsgZGlzYWJsZWQ6IGZhbHNlIH0gKTtcblx0fSxcblxuXHRkaXNhYmxlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5fc2V0T3B0aW9ucyggeyBkaXNhYmxlZDogdHJ1ZSB9ICk7XG5cdH0sXG5cblx0X2NsYXNzZXM6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXHRcdHZhciBmdWxsID0gW107XG5cdFx0dmFyIHRoYXQgPSB0aGlzO1xuXG5cdFx0b3B0aW9ucyA9ICQuZXh0ZW5kKCB7XG5cdFx0XHRlbGVtZW50OiB0aGlzLmVsZW1lbnQsXG5cdFx0XHRjbGFzc2VzOiB0aGlzLm9wdGlvbnMuY2xhc3NlcyB8fCB7fVxuXHRcdH0sIG9wdGlvbnMgKTtcblxuXHRcdGZ1bmN0aW9uIHByb2Nlc3NDbGFzc1N0cmluZyggY2xhc3NlcywgY2hlY2tPcHRpb24gKSB7XG5cdFx0XHR2YXIgY3VycmVudCwgaTtcblx0XHRcdGZvciAoIGkgPSAwOyBpIDwgY2xhc3Nlcy5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0Y3VycmVudCA9IHRoYXQuY2xhc3Nlc0VsZW1lbnRMb29rdXBbIGNsYXNzZXNbIGkgXSBdIHx8ICQoKTtcblx0XHRcdFx0aWYgKCBvcHRpb25zLmFkZCApIHtcblx0XHRcdFx0XHRjdXJyZW50ID0gJCggJC51bmlxdWUoIGN1cnJlbnQuZ2V0KCkuY29uY2F0KCBvcHRpb25zLmVsZW1lbnQuZ2V0KCkgKSApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y3VycmVudCA9ICQoIGN1cnJlbnQubm90KCBvcHRpb25zLmVsZW1lbnQgKS5nZXQoKSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoYXQuY2xhc3Nlc0VsZW1lbnRMb29rdXBbIGNsYXNzZXNbIGkgXSBdID0gY3VycmVudDtcblx0XHRcdFx0ZnVsbC5wdXNoKCBjbGFzc2VzWyBpIF0gKTtcblx0XHRcdFx0aWYgKCBjaGVja09wdGlvbiAmJiBvcHRpb25zLmNsYXNzZXNbIGNsYXNzZXNbIGkgXSBdICkge1xuXHRcdFx0XHRcdGZ1bGwucHVzaCggb3B0aW9ucy5jbGFzc2VzWyBjbGFzc2VzWyBpIF0gXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5fb24oIG9wdGlvbnMuZWxlbWVudCwge1xuXHRcdFx0XCJyZW1vdmVcIjogXCJfdW50cmFja0NsYXNzZXNFbGVtZW50XCJcblx0XHR9ICk7XG5cblx0XHRpZiAoIG9wdGlvbnMua2V5cyApIHtcblx0XHRcdHByb2Nlc3NDbGFzc1N0cmluZyggb3B0aW9ucy5rZXlzLm1hdGNoKCAvXFxTKy9nICkgfHwgW10sIHRydWUgKTtcblx0XHR9XG5cdFx0aWYgKCBvcHRpb25zLmV4dHJhICkge1xuXHRcdFx0cHJvY2Vzc0NsYXNzU3RyaW5nKCBvcHRpb25zLmV4dHJhLm1hdGNoKCAvXFxTKy9nICkgfHwgW10gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZnVsbC5qb2luKCBcIiBcIiApO1xuXHR9LFxuXG5cdF91bnRyYWNrQ2xhc3Nlc0VsZW1lbnQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHR2YXIgdGhhdCA9IHRoaXM7XG5cdFx0JC5lYWNoKCB0aGF0LmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHRcdGlmICggJC5pbkFycmF5KCBldmVudC50YXJnZXQsIHZhbHVlICkgIT09IC0xICkge1xuXHRcdFx0XHR0aGF0LmNsYXNzZXNFbGVtZW50TG9va3VwWyBrZXkgXSA9ICQoIHZhbHVlLm5vdCggZXZlbnQudGFyZ2V0ICkuZ2V0KCkgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0X3JlbW92ZUNsYXNzOiBmdW5jdGlvbiggZWxlbWVudCwga2V5cywgZXh0cmEgKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3RvZ2dsZUNsYXNzKCBlbGVtZW50LCBrZXlzLCBleHRyYSwgZmFsc2UgKTtcblx0fSxcblxuXHRfYWRkQ2xhc3M6IGZ1bmN0aW9uKCBlbGVtZW50LCBrZXlzLCBleHRyYSApIHtcblx0XHRyZXR1cm4gdGhpcy5fdG9nZ2xlQ2xhc3MoIGVsZW1lbnQsIGtleXMsIGV4dHJhLCB0cnVlICk7XG5cdH0sXG5cblx0X3RvZ2dsZUNsYXNzOiBmdW5jdGlvbiggZWxlbWVudCwga2V5cywgZXh0cmEsIGFkZCApIHtcblx0XHRhZGQgPSAoIHR5cGVvZiBhZGQgPT09IFwiYm9vbGVhblwiICkgPyBhZGQgOiBleHRyYTtcblx0XHR2YXIgc2hpZnQgPSAoIHR5cGVvZiBlbGVtZW50ID09PSBcInN0cmluZ1wiIHx8IGVsZW1lbnQgPT09IG51bGwgKSxcblx0XHRcdG9wdGlvbnMgPSB7XG5cdFx0XHRcdGV4dHJhOiBzaGlmdCA/IGtleXMgOiBleHRyYSxcblx0XHRcdFx0a2V5czogc2hpZnQgPyBlbGVtZW50IDoga2V5cyxcblx0XHRcdFx0ZWxlbWVudDogc2hpZnQgPyB0aGlzLmVsZW1lbnQgOiBlbGVtZW50LFxuXHRcdFx0XHRhZGQ6IGFkZFxuXHRcdFx0fTtcblx0XHRvcHRpb25zLmVsZW1lbnQudG9nZ2xlQ2xhc3MoIHRoaXMuX2NsYXNzZXMoIG9wdGlvbnMgKSwgYWRkICk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0X29uOiBmdW5jdGlvbiggc3VwcHJlc3NEaXNhYmxlZENoZWNrLCBlbGVtZW50LCBoYW5kbGVycyApIHtcblx0XHR2YXIgZGVsZWdhdGVFbGVtZW50O1xuXHRcdHZhciBpbnN0YW5jZSA9IHRoaXM7XG5cblx0XHQvLyBObyBzdXBwcmVzc0Rpc2FibGVkQ2hlY2sgZmxhZywgc2h1ZmZsZSBhcmd1bWVudHNcblx0XHRpZiAoIHR5cGVvZiBzdXBwcmVzc0Rpc2FibGVkQ2hlY2sgIT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0aGFuZGxlcnMgPSBlbGVtZW50O1xuXHRcdFx0ZWxlbWVudCA9IHN1cHByZXNzRGlzYWJsZWRDaGVjaztcblx0XHRcdHN1cHByZXNzRGlzYWJsZWRDaGVjayA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIE5vIGVsZW1lbnQgYXJndW1lbnQsIHNodWZmbGUgYW5kIHVzZSB0aGlzLmVsZW1lbnRcblx0XHRpZiAoICFoYW5kbGVycyApIHtcblx0XHRcdGhhbmRsZXJzID0gZWxlbWVudDtcblx0XHRcdGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XG5cdFx0XHRkZWxlZ2F0ZUVsZW1lbnQgPSB0aGlzLndpZGdldCgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRlbGVtZW50ID0gZGVsZWdhdGVFbGVtZW50ID0gJCggZWxlbWVudCApO1xuXHRcdFx0dGhpcy5iaW5kaW5ncyA9IHRoaXMuYmluZGluZ3MuYWRkKCBlbGVtZW50ICk7XG5cdFx0fVxuXG5cdFx0JC5lYWNoKCBoYW5kbGVycywgZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVyICkge1xuXHRcdFx0ZnVuY3Rpb24gaGFuZGxlclByb3h5KCkge1xuXG5cdFx0XHRcdC8vIEFsbG93IHdpZGdldHMgdG8gY3VzdG9taXplIHRoZSBkaXNhYmxlZCBoYW5kbGluZ1xuXHRcdFx0XHQvLyAtIGRpc2FibGVkIGFzIGFuIGFycmF5IGluc3RlYWQgb2YgYm9vbGVhblxuXHRcdFx0XHQvLyAtIGRpc2FibGVkIGNsYXNzIGFzIG1ldGhvZCBmb3IgZGlzYWJsaW5nIGluZGl2aWR1YWwgcGFydHNcblx0XHRcdFx0aWYgKCAhc3VwcHJlc3NEaXNhYmxlZENoZWNrICYmXG5cdFx0XHRcdFx0XHQoIGluc3RhbmNlLm9wdGlvbnMuZGlzYWJsZWQgPT09IHRydWUgfHxcblx0XHRcdFx0XHRcdCQoIHRoaXMgKS5oYXNDbGFzcyggXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiICkgKSApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuICggdHlwZW9mIGhhbmRsZXIgPT09IFwic3RyaW5nXCIgPyBpbnN0YW5jZVsgaGFuZGxlciBdIDogaGFuZGxlciApXG5cdFx0XHRcdFx0LmFwcGx5KCBpbnN0YW5jZSwgYXJndW1lbnRzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvcHkgdGhlIGd1aWQgc28gZGlyZWN0IHVuYmluZGluZyB3b3Jrc1xuXHRcdFx0aWYgKCB0eXBlb2YgaGFuZGxlciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0aGFuZGxlclByb3h5Lmd1aWQgPSBoYW5kbGVyLmd1aWQgPVxuXHRcdFx0XHRcdGhhbmRsZXIuZ3VpZCB8fCBoYW5kbGVyUHJveHkuZ3VpZCB8fCAkLmd1aWQrKztcblx0XHRcdH1cblxuXHRcdFx0dmFyIG1hdGNoID0gZXZlbnQubWF0Y2goIC9eKFtcXHc6LV0qKVxccyooLiopJC8gKTtcblx0XHRcdHZhciBldmVudE5hbWUgPSBtYXRjaFsgMSBdICsgaW5zdGFuY2UuZXZlbnROYW1lc3BhY2U7XG5cdFx0XHR2YXIgc2VsZWN0b3IgPSBtYXRjaFsgMiBdO1xuXG5cdFx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0XHRkZWxlZ2F0ZUVsZW1lbnQub24oIGV2ZW50TmFtZSwgc2VsZWN0b3IsIGhhbmRsZXJQcm94eSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbWVudC5vbiggZXZlbnROYW1lLCBoYW5kbGVyUHJveHkgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0X29mZjogZnVuY3Rpb24oIGVsZW1lbnQsIGV2ZW50TmFtZSApIHtcblx0XHRldmVudE5hbWUgPSAoIGV2ZW50TmFtZSB8fCBcIlwiICkuc3BsaXQoIFwiIFwiICkuam9pbiggdGhpcy5ldmVudE5hbWVzcGFjZSArIFwiIFwiICkgK1xuXHRcdFx0dGhpcy5ldmVudE5hbWVzcGFjZTtcblx0XHRlbGVtZW50Lm9mZiggZXZlbnROYW1lICkub2ZmKCBldmVudE5hbWUgKTtcblxuXHRcdC8vIENsZWFyIHRoZSBzdGFjayB0byBhdm9pZCBtZW1vcnkgbGVha3MgKCMxMDA1Nilcblx0XHR0aGlzLmJpbmRpbmdzID0gJCggdGhpcy5iaW5kaW5ncy5ub3QoIGVsZW1lbnQgKS5nZXQoKSApO1xuXHRcdHRoaXMuZm9jdXNhYmxlID0gJCggdGhpcy5mb2N1c2FibGUubm90KCBlbGVtZW50ICkuZ2V0KCkgKTtcblx0XHR0aGlzLmhvdmVyYWJsZSA9ICQoIHRoaXMuaG92ZXJhYmxlLm5vdCggZWxlbWVudCApLmdldCgpICk7XG5cdH0sXG5cblx0X2RlbGF5OiBmdW5jdGlvbiggaGFuZGxlciwgZGVsYXkgKSB7XG5cdFx0ZnVuY3Rpb24gaGFuZGxlclByb3h5KCkge1xuXHRcdFx0cmV0dXJuICggdHlwZW9mIGhhbmRsZXIgPT09IFwic3RyaW5nXCIgPyBpbnN0YW5jZVsgaGFuZGxlciBdIDogaGFuZGxlciApXG5cdFx0XHRcdC5hcHBseSggaW5zdGFuY2UsIGFyZ3VtZW50cyApO1xuXHRcdH1cblx0XHR2YXIgaW5zdGFuY2UgPSB0aGlzO1xuXHRcdHJldHVybiBzZXRUaW1lb3V0KCBoYW5kbGVyUHJveHksIGRlbGF5IHx8IDAgKTtcblx0fSxcblxuXHRfaG92ZXJhYmxlOiBmdW5jdGlvbiggZWxlbWVudCApIHtcblx0XHR0aGlzLmhvdmVyYWJsZSA9IHRoaXMuaG92ZXJhYmxlLmFkZCggZWxlbWVudCApO1xuXHRcdHRoaXMuX29uKCBlbGVtZW50LCB7XG5cdFx0XHRtb3VzZWVudGVyOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdHRoaXMuX2FkZENsYXNzKCAkKCBldmVudC5jdXJyZW50VGFyZ2V0ICksIG51bGwsIFwidWktc3RhdGUtaG92ZXJcIiApO1xuXHRcdFx0fSxcblx0XHRcdG1vdXNlbGVhdmU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0dGhpcy5fcmVtb3ZlQ2xhc3MoICQoIGV2ZW50LmN1cnJlbnRUYXJnZXQgKSwgbnVsbCwgXCJ1aS1zdGF0ZS1ob3ZlclwiICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdF9mb2N1c2FibGU6IGZ1bmN0aW9uKCBlbGVtZW50ICkge1xuXHRcdHRoaXMuZm9jdXNhYmxlID0gdGhpcy5mb2N1c2FibGUuYWRkKCBlbGVtZW50ICk7XG5cdFx0dGhpcy5fb24oIGVsZW1lbnQsIHtcblx0XHRcdGZvY3VzaW46IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0dGhpcy5fYWRkQ2xhc3MoICQoIGV2ZW50LmN1cnJlbnRUYXJnZXQgKSwgbnVsbCwgXCJ1aS1zdGF0ZS1mb2N1c1wiICk7XG5cdFx0XHR9LFxuXHRcdFx0Zm9jdXNvdXQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0dGhpcy5fcmVtb3ZlQ2xhc3MoICQoIGV2ZW50LmN1cnJlbnRUYXJnZXQgKSwgbnVsbCwgXCJ1aS1zdGF0ZS1mb2N1c1wiICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdF90cmlnZ2VyOiBmdW5jdGlvbiggdHlwZSwgZXZlbnQsIGRhdGEgKSB7XG5cdFx0dmFyIHByb3AsIG9yaWc7XG5cdFx0dmFyIGNhbGxiYWNrID0gdGhpcy5vcHRpb25zWyB0eXBlIF07XG5cblx0XHRkYXRhID0gZGF0YSB8fCB7fTtcblx0XHRldmVudCA9ICQuRXZlbnQoIGV2ZW50ICk7XG5cdFx0ZXZlbnQudHlwZSA9ICggdHlwZSA9PT0gdGhpcy53aWRnZXRFdmVudFByZWZpeCA/XG5cdFx0XHR0eXBlIDpcblx0XHRcdHRoaXMud2lkZ2V0RXZlbnRQcmVmaXggKyB0eXBlICkudG9Mb3dlckNhc2UoKTtcblxuXHRcdC8vIFRoZSBvcmlnaW5hbCBldmVudCBtYXkgY29tZSBmcm9tIGFueSBlbGVtZW50XG5cdFx0Ly8gc28gd2UgbmVlZCB0byByZXNldCB0aGUgdGFyZ2V0IG9uIHRoZSBuZXcgZXZlbnRcblx0XHRldmVudC50YXJnZXQgPSB0aGlzLmVsZW1lbnRbIDAgXTtcblxuXHRcdC8vIENvcHkgb3JpZ2luYWwgZXZlbnQgcHJvcGVydGllcyBvdmVyIHRvIHRoZSBuZXcgZXZlbnRcblx0XHRvcmlnID0gZXZlbnQub3JpZ2luYWxFdmVudDtcblx0XHRpZiAoIG9yaWcgKSB7XG5cdFx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cdFx0XHRcdGlmICggISggcHJvcCBpbiBldmVudCApICkge1xuXHRcdFx0XHRcdGV2ZW50WyBwcm9wIF0gPSBvcmlnWyBwcm9wIF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLmVsZW1lbnQudHJpZ2dlciggZXZlbnQsIGRhdGEgKTtcblx0XHRyZXR1cm4gISggJC5pc0Z1bmN0aW9uKCBjYWxsYmFjayApICYmXG5cdFx0XHRjYWxsYmFjay5hcHBseSggdGhpcy5lbGVtZW50WyAwIF0sIFsgZXZlbnQgXS5jb25jYXQoIGRhdGEgKSApID09PSBmYWxzZSB8fFxuXHRcdFx0ZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkgKTtcblx0fVxufTtcblxuJC5lYWNoKCB7IHNob3c6IFwiZmFkZUluXCIsIGhpZGU6IFwiZmFkZU91dFwiIH0sIGZ1bmN0aW9uKCBtZXRob2QsIGRlZmF1bHRFZmZlY3QgKSB7XG5cdCQuV2lkZ2V0LnByb3RvdHlwZVsgXCJfXCIgKyBtZXRob2QgXSA9IGZ1bmN0aW9uKCBlbGVtZW50LCBvcHRpb25zLCBjYWxsYmFjayApIHtcblx0XHRpZiAoIHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0b3B0aW9ucyA9IHsgZWZmZWN0OiBvcHRpb25zIH07XG5cdFx0fVxuXG5cdFx0dmFyIGhhc09wdGlvbnM7XG5cdFx0dmFyIGVmZmVjdE5hbWUgPSAhb3B0aW9ucyA/XG5cdFx0XHRtZXRob2QgOlxuXHRcdFx0b3B0aW9ucyA9PT0gdHJ1ZSB8fCB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJudW1iZXJcIiA/XG5cdFx0XHRcdGRlZmF1bHRFZmZlY3QgOlxuXHRcdFx0XHRvcHRpb25zLmVmZmVjdCB8fCBkZWZhdWx0RWZmZWN0O1xuXG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdFx0aWYgKCB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJudW1iZXJcIiApIHtcblx0XHRcdG9wdGlvbnMgPSB7IGR1cmF0aW9uOiBvcHRpb25zIH07XG5cdFx0fVxuXG5cdFx0aGFzT3B0aW9ucyA9ICEkLmlzRW1wdHlPYmplY3QoIG9wdGlvbnMgKTtcblx0XHRvcHRpb25zLmNvbXBsZXRlID0gY2FsbGJhY2s7XG5cblx0XHRpZiAoIG9wdGlvbnMuZGVsYXkgKSB7XG5cdFx0XHRlbGVtZW50LmRlbGF5KCBvcHRpb25zLmRlbGF5ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBoYXNPcHRpb25zICYmICQuZWZmZWN0cyAmJiAkLmVmZmVjdHMuZWZmZWN0WyBlZmZlY3ROYW1lIF0gKSB7XG5cdFx0XHRlbGVtZW50WyBtZXRob2QgXSggb3B0aW9ucyApO1xuXHRcdH0gZWxzZSBpZiAoIGVmZmVjdE5hbWUgIT09IG1ldGhvZCAmJiBlbGVtZW50WyBlZmZlY3ROYW1lIF0gKSB7XG5cdFx0XHRlbGVtZW50WyBlZmZlY3ROYW1lIF0oIG9wdGlvbnMuZHVyYXRpb24sIG9wdGlvbnMuZWFzaW5nLCBjYWxsYmFjayApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRlbGVtZW50LnF1ZXVlKCBmdW5jdGlvbiggbmV4dCApIHtcblx0XHRcdFx0JCggdGhpcyApWyBtZXRob2QgXSgpO1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwoIGVsZW1lbnRbIDAgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG5leHQoKTtcblx0XHRcdH0gKTtcblx0XHR9XG5cdH07XG59ICk7XG5cbnJldHVybiAkLndpZGdldDtcblxufSApICk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vanF1ZXJ5LXVpL3VpL3dpZGdldC5qc1xuLy8gbW9kdWxlIGlkID0gMjhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0="); +eval("exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.select2-dropdown[data-v-ff564a86] {\\n z-index:9999;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/../../../resources/assets/js/components/select2.vue?5e14c42b\"],\"names\":[],\"mappings\":\";AAEA;IACA,aAAA;CACA\",\"file\":\"select2.vue\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjguanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvc2VsZWN0Mi52dWU/YzkyNSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5zZWxlY3QyLWRyb3Bkb3duW2RhdGEtdi1mZjU2NGE4Nl0ge1xcbiAgICB6LWluZGV4Ojk5OTk7XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi4vLi4vLi4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NlbGVjdDIudnVlPzVlMTRjNDJiXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFFQTtJQUNBLGFBQUE7Q0FDQVwiLFwiZmlsZVwiOlwic2VsZWN0Mi52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiXFxuPHN0eWxlIHNjb3BlZD5cXG4gICAgLnNlbGVjdDItZHJvcGRvd24ge1xcbiAgICAgICAgei1pbmRleDo5OTk5O1xcbiAgICB9XFxuPC9zdHlsZT5cXG5cXG48dGVtcGxhdGU+XFxuICAgICAgICA8c2VsZWN0IHN0eWxlPVxcXCJ3aWR0aDoxMDAlXFxcIj5cXG4gICAgICAgICAgICA8c2xvdD48L3Nsb3Q+XFxuICAgICAgICA8L3NlbGVjdD5cXG48L3RlbXBsYXRlPlxcblxcbjxzY3JpcHQ+XFxuICAgIHJlcXVpcmUoJ3NlbGVjdDInKTtcXG4gICAgZXhwb3J0IGRlZmF1bHQge1xcbiAgICAgICAgLypcXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxcbiAgICAgICAgICovXFxuICAgICAgICBwcm9wczogWydvcHRpb25zJywgJ3ZhbHVlJ10sXFxuXFxuICAgICAgICBtb3VudGVkKCkge1xcbiAgICAgICAgICAgIHZhciB2bSA9IHRoaXM7XFxuICAgICAgICAgICAgJCh0aGlzLiRlbClcXG4gICAgICAgICAgICAgICAgLnNlbGVjdDIoe1xcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogdGhpcy5vcHRpb25zXFxuICAgICAgICAgICAgICAgIH0pXFxuICAgICAgICAgICAgICAgIC5vbignY2hhbmdlJywgZnVuY3Rpb24oKSB7IHZtLiRlbWl0KCdpbnB1dCcsIHRoaXMudmFsdWUpIH0gKVxcbiAgICAgICAgICAgICAgICAudmFsKHRoaXMudmFsdWUpLnRyaWdnZXIoJ2NoYW5nZScpO1xcbiAgICAgICAgfSxcXG4gICAgICAgIHdhdGNoOiB7XFxuICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xcbiAgICAgICAgICAgICAgICAkKHRoaXMuJGVsKS52YWwodmFsdWUpXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBvcHRpb25zOiBmdW5jdGlvbiAob3B0aW9ucykge1xcbiAgICAgICAgICAgICAgICB2YXIgdm0gPSB0aGlzO1xcbiAgICAgICAgICAgICAgICAkKHRoaXMuJGVsKS5zZWxlY3QyKCdkZXN0cm95JykuZW1wdHkoKS5zZWxlY3QyKHtkYXRhOiBvcHRpb25zfSlcXG4gICAgICAgICAgICAgICAgLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHsgdm0uJGVtaXQoJ2lucHV0JywgdGhpcy52YWx1ZSkgfSApXFxuICAgICAgICAgICAgICAgIC52YWwodGhpcy52YWx1ZSkudHJpZ2dlcignY2hhbmdlJyk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBkZXN0cm95ZWQ6IGZ1bmN0aW9uKCkge1xcbiAgICAgICAgICAgICAgICAkKHRoaXMuJGVsKS5vZmYoKS5zZWxlY3QyKCdkZXN0cm95JylcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIH1cXG5cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1mZjU2NGE4NlwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NlbGVjdDIudnVlXG4vLyBtb2R1bGUgaWQgPSAyOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9"); /***/ }), /* 29 */ /***/ (function(module, exports, __webpack_require__) { -eval("/* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/**\n * @license\n * Lodash \n * Copyright JS Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n;(function() {\n\n /** Used as a safe reference for `undefined` in pre-ES5 environments. */\n var undefined;\n\n /** Used as the semantic version number. */\n var VERSION = '4.17.4';\n\n /** Used as the size to enable large array optimizations. */\n var LARGE_ARRAY_SIZE = 200;\n\n /** Error message constants. */\n var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',\n FUNC_ERROR_TEXT = 'Expected a function';\n\n /** Used to stand-in for `undefined` hash values. */\n var HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n /** Used as the maximum memoize cache size. */\n var MAX_MEMOIZE_SIZE = 500;\n\n /** Used as the internal argument placeholder. */\n var PLACEHOLDER = '__lodash_placeholder__';\n\n /** Used to compose bitmasks for cloning. */\n var CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n /** Used to compose bitmasks for value comparisons. */\n var COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n /** Used to compose bitmasks for function metadata. */\n var WRAP_BIND_FLAG = 1,\n WRAP_BIND_KEY_FLAG = 2,\n WRAP_CURRY_BOUND_FLAG = 4,\n WRAP_CURRY_FLAG = 8,\n WRAP_CURRY_RIGHT_FLAG = 16,\n WRAP_PARTIAL_FLAG = 32,\n WRAP_PARTIAL_RIGHT_FLAG = 64,\n WRAP_ARY_FLAG = 128,\n WRAP_REARG_FLAG = 256,\n WRAP_FLIP_FLAG = 512;\n\n /** Used as default options for `_.truncate`. */\n var DEFAULT_TRUNC_LENGTH = 30,\n DEFAULT_TRUNC_OMISSION = '...';\n\n /** Used to detect hot functions by number of calls within a span of milliseconds. */\n var HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n /** Used to indicate the type of lazy iteratees. */\n var LAZY_FILTER_FLAG = 1,\n LAZY_MAP_FLAG = 2,\n LAZY_WHILE_FLAG = 3;\n\n /** Used as references for various `Number` constants. */\n var INFINITY = 1 / 0,\n MAX_SAFE_INTEGER = 9007199254740991,\n MAX_INTEGER = 1.7976931348623157e+308,\n NAN = 0 / 0;\n\n /** Used as references for the maximum length and index of an array. */\n var MAX_ARRAY_LENGTH = 4294967295,\n MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,\n HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n /** Used to associate wrap methods with their bit flags. */\n var wrapFlags = [\n ['ary', WRAP_ARY_FLAG],\n ['bind', WRAP_BIND_FLAG],\n ['bindKey', WRAP_BIND_KEY_FLAG],\n ['curry', WRAP_CURRY_FLAG],\n ['curryRight', WRAP_CURRY_RIGHT_FLAG],\n ['flip', WRAP_FLIP_FLAG],\n ['partial', WRAP_PARTIAL_FLAG],\n ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],\n ['rearg', WRAP_REARG_FLAG]\n ];\n\n /** `Object#toString` result references. */\n var argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n asyncTag = '[object AsyncFunction]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n domExcTag = '[object DOMException]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n nullTag = '[object Null]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n proxyTag = '[object Proxy]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n undefinedTag = '[object Undefined]',\n weakMapTag = '[object WeakMap]',\n weakSetTag = '[object WeakSet]';\n\n var arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n /** Used to match empty string literals in compiled template source. */\n var reEmptyStringLeading = /\\b__p \\+= '';/g,\n reEmptyStringMiddle = /\\b(__p \\+=) '' \\+/g,\n reEmptyStringTrailing = /(__e\\(.*?\\)|\\b__t\\)) \\+\\n'';/g;\n\n /** Used to match HTML entities and HTML characters. */\n var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,\n reUnescapedHtml = /[&<>\"']/g,\n reHasEscapedHtml = RegExp(reEscapedHtml.source),\n reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n /** Used to match template delimiters. */\n var reEscape = /<%-([\\s\\S]+?)%>/g,\n reEvaluate = /<%([\\s\\S]+?)%>/g,\n reInterpolate = /<%=([\\s\\S]+?)%>/g;\n\n /** Used to match property names within property paths. */\n var reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/,\n reLeadingDot = /^\\./,\n rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n /**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\n var reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g,\n reHasRegExpChar = RegExp(reRegExpChar.source);\n\n /** Used to match leading and trailing whitespace. */\n var reTrim = /^\\s+|\\s+$/g,\n reTrimStart = /^\\s+/,\n reTrimEnd = /\\s+$/;\n\n /** Used to match wrap detail comments. */\n var reWrapComment = /\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/,\n reWrapDetails = /\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,\n reSplitDetails = /,? & /;\n\n /** Used to match words composed of alphanumeric characters. */\n var reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n /** Used to match backslashes in property paths. */\n var reEscapeChar = /\\\\(\\\\)?/g;\n\n /**\n * Used to match\n * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).\n */\n var reEsTemplate = /\\$\\{([^\\\\}]*(?:\\\\.[^\\\\}]*)*)\\}/g;\n\n /** Used to match `RegExp` flags from their coerced string values. */\n var reFlags = /\\w*$/;\n\n /** Used to detect bad signed hexadecimal string values. */\n var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n /** Used to detect binary string values. */\n var reIsBinary = /^0b[01]+$/i;\n\n /** Used to detect host constructors (Safari). */\n var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n /** Used to detect octal string values. */\n var reIsOctal = /^0o[0-7]+$/i;\n\n /** Used to detect unsigned integer values. */\n var reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n /** Used to match Latin Unicode letters (excluding mathematical operators). */\n var reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n /** Used to ensure capturing order of template delimiters. */\n var reNoMatch = /($^)/;\n\n /** Used to match unescaped characters in compiled string literals. */\n var reUnescapedString = /['\\n\\r\\u2028\\u2029\\\\]/g;\n\n /** Used to compose unicode character classes. */\n var rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsDingbatRange = '\\\\u2700-\\\\u27bf',\n rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n rsPunctuationRange = '\\\\u2000-\\\\u206f',\n rsSpaceRange = ' \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000',\n rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n rsVarRange = '\\\\ufe0e\\\\ufe0f',\n rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n /** Used to compose unicode capture groups. */\n var rsApos = \"['\\u2019]\",\n rsAstral = '[' + rsAstralRange + ']',\n rsBreak = '[' + rsBreakRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsDigits = '\\\\d+',\n rsDingbat = '[' + rsDingbatRange + ']',\n rsLower = '[' + rsLowerRange + ']',\n rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsUpper = '[' + rsUpperRange + ']',\n rsZWJ = '\\\\u200d';\n\n /** Used to compose unicode regexes. */\n var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',\n rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',\n rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsOrdLower = '\\\\d*(?:(?:1st|2nd|3rd|(?![123])\\\\dth)\\\\b)',\n rsOrdUpper = '\\\\d*(?:(?:1ST|2ND|3RD|(?![123])\\\\dTH)\\\\b)',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n /** Used to match apostrophes. */\n var reApos = RegExp(rsApos, 'g');\n\n /**\n * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n */\n var reComboMark = RegExp(rsCombo, 'g');\n\n /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\n var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n /** Used to match complex or compound words. */\n var reUnicodeWord = RegExp([\n rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',\n rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,\n rsUpper + '+' + rsOptContrUpper,\n rsOrdUpper,\n rsOrdLower,\n rsDigits,\n rsEmoji\n ].join('|'), 'g');\n\n /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\n var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n /** Used to detect strings that need a more robust regexp to match words. */\n var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n /** Used to assign default `context` object properties. */\n var contextProps = [\n 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',\n 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',\n 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',\n 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',\n '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'\n ];\n\n /** Used to make template sourceURLs easier to identify. */\n var templateCounter = -1;\n\n /** Used to identify `toStringTag` values of typed arrays. */\n var typedArrayTags = {};\n typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n typedArrayTags[uint32Tag] = true;\n typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n typedArrayTags[errorTag] = typedArrayTags[funcTag] =\n typedArrayTags[mapTag] = typedArrayTags[numberTag] =\n typedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n typedArrayTags[setTag] = typedArrayTags[stringTag] =\n typedArrayTags[weakMapTag] = false;\n\n /** Used to identify `toStringTag` values supported by `_.clone`. */\n var cloneableTags = {};\n cloneableTags[argsTag] = cloneableTags[arrayTag] =\n cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\n cloneableTags[boolTag] = cloneableTags[dateTag] =\n cloneableTags[float32Tag] = cloneableTags[float64Tag] =\n cloneableTags[int8Tag] = cloneableTags[int16Tag] =\n cloneableTags[int32Tag] = cloneableTags[mapTag] =\n cloneableTags[numberTag] = cloneableTags[objectTag] =\n cloneableTags[regexpTag] = cloneableTags[setTag] =\n cloneableTags[stringTag] = cloneableTags[symbolTag] =\n cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\n cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\n cloneableTags[errorTag] = cloneableTags[funcTag] =\n cloneableTags[weakMapTag] = false;\n\n /** Used to map Latin Unicode letters to basic Latin letters. */\n var deburredLetters = {\n // Latin-1 Supplement block.\n '\\xc0': 'A', '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n '\\xe0': 'a', '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n '\\xc7': 'C', '\\xe7': 'c',\n '\\xd0': 'D', '\\xf0': 'd',\n '\\xc8': 'E', '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n '\\xe8': 'e', '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n '\\xcc': 'I', '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n '\\xec': 'i', '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n '\\xd1': 'N', '\\xf1': 'n',\n '\\xd2': 'O', '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n '\\xf2': 'o', '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n '\\xd9': 'U', '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n '\\xf9': 'u', '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n '\\xdd': 'Y', '\\xfd': 'y', '\\xff': 'y',\n '\\xc6': 'Ae', '\\xe6': 'ae',\n '\\xde': 'Th', '\\xfe': 'th',\n '\\xdf': 'ss',\n // Latin Extended-A block.\n '\\u0100': 'A', '\\u0102': 'A', '\\u0104': 'A',\n '\\u0101': 'a', '\\u0103': 'a', '\\u0105': 'a',\n '\\u0106': 'C', '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n '\\u0107': 'c', '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n '\\u010e': 'D', '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n '\\u0112': 'E', '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n '\\u0113': 'e', '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n '\\u011c': 'G', '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n '\\u011d': 'g', '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n '\\u0124': 'H', '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n '\\u0128': 'I', '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n '\\u0129': 'i', '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n '\\u0134': 'J', '\\u0135': 'j',\n '\\u0136': 'K', '\\u0137': 'k', '\\u0138': 'k',\n '\\u0139': 'L', '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n '\\u013a': 'l', '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n '\\u0143': 'N', '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n '\\u0144': 'n', '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n '\\u014c': 'O', '\\u014e': 'O', '\\u0150': 'O',\n '\\u014d': 'o', '\\u014f': 'o', '\\u0151': 'o',\n '\\u0154': 'R', '\\u0156': 'R', '\\u0158': 'R',\n '\\u0155': 'r', '\\u0157': 'r', '\\u0159': 'r',\n '\\u015a': 'S', '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n '\\u015b': 's', '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n '\\u0162': 'T', '\\u0164': 'T', '\\u0166': 'T',\n '\\u0163': 't', '\\u0165': 't', '\\u0167': 't',\n '\\u0168': 'U', '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n '\\u0169': 'u', '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n '\\u0174': 'W', '\\u0175': 'w',\n '\\u0176': 'Y', '\\u0177': 'y', '\\u0178': 'Y',\n '\\u0179': 'Z', '\\u017b': 'Z', '\\u017d': 'Z',\n '\\u017a': 'z', '\\u017c': 'z', '\\u017e': 'z',\n '\\u0132': 'IJ', '\\u0133': 'ij',\n '\\u0152': 'Oe', '\\u0153': 'oe',\n '\\u0149': \"'n\", '\\u017f': 's'\n };\n\n /** Used to map characters to HTML entities. */\n var htmlEscapes = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n };\n\n /** Used to map HTML entities to characters. */\n var htmlUnescapes = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\"\n };\n\n /** Used to escape characters for inclusion in compiled string literals. */\n var stringEscapes = {\n '\\\\': '\\\\',\n \"'\": \"'\",\n '\\n': 'n',\n '\\r': 'r',\n '\\u2028': 'u2028',\n '\\u2029': 'u2029'\n };\n\n /** Built-in method references without a dependency on `root`. */\n var freeParseFloat = parseFloat,\n freeParseInt = parseInt;\n\n /** Detect free variable `global` from Node.js. */\n var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n /** Detect free variable `self`. */\n var freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n /** Used as a reference to the global object. */\n var root = freeGlobal || freeSelf || Function('return this')();\n\n /** Detect free variable `exports`. */\n var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n /** Detect free variable `module`. */\n var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n /** Detect the popular CommonJS extension `module.exports`. */\n var moduleExports = freeModule && freeModule.exports === freeExports;\n\n /** Detect free variable `process` from Node.js. */\n var freeProcess = moduleExports && freeGlobal.process;\n\n /** Used to access faster Node.js helpers. */\n var nodeUtil = (function() {\n try {\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n }());\n\n /* Node.js helper references. */\n var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,\n nodeIsDate = nodeUtil && nodeUtil.isDate,\n nodeIsMap = nodeUtil && nodeUtil.isMap,\n nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,\n nodeIsSet = nodeUtil && nodeUtil.isSet,\n nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n /*--------------------------------------------------------------------------*/\n\n /**\n * Adds the key-value `pair` to `map`.\n *\n * @private\n * @param {Object} map The map to modify.\n * @param {Array} pair The key-value pair to add.\n * @returns {Object} Returns `map`.\n */\n function addMapEntry(map, pair) {\n // Don't return `map.set` because it's not chainable in IE 11.\n map.set(pair[0], pair[1]);\n return map;\n }\n\n /**\n * Adds `value` to `set`.\n *\n * @private\n * @param {Object} set The set to modify.\n * @param {*} value The value to add.\n * @returns {Object} Returns `set`.\n */\n function addSetEntry(set, value) {\n // Don't return `set.add` because it's not chainable in IE 11.\n set.add(value);\n return set;\n }\n\n /**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\n function apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n }\n\n /**\n * A specialized version of `baseAggregator` for arrays.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\n function arrayAggregator(array, setter, iteratee, accumulator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n var value = array[index];\n setter(accumulator, value, iteratee(value), array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\n function arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n }\n\n /**\n * A specialized version of `_.forEachRight` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\n function arrayEachRight(array, iteratee) {\n var length = array == null ? 0 : array.length;\n\n while (length--) {\n if (iteratee(array[length], length, array) === false) {\n break;\n }\n }\n return array;\n }\n\n /**\n * A specialized version of `_.every` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`.\n */\n function arrayEvery(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (!predicate(array[index], index, array)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\n function arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `_.includes` for arrays without support for\n * specifying an index to search from.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\n function arrayIncludes(array, value) {\n var length = array == null ? 0 : array.length;\n return !!length && baseIndexOf(array, value, 0) > -1;\n }\n\n /**\n * This function is like `arrayIncludes` except that it accepts a comparator.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\n function arrayIncludesWith(array, value, comparator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (comparator(value, array[index])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\n function arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n }\n\n /**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\n function arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n }\n\n /**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\n function arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.reduceRight` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the last element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\n function arrayReduceRight(array, iteratee, accumulator, initAccum) {\n var length = array == null ? 0 : array.length;\n if (initAccum && length) {\n accumulator = array[--length];\n }\n while (length--) {\n accumulator = iteratee(accumulator, array[length], length, array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\n function arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Gets the size of an ASCII `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\n var asciiSize = baseProperty('length');\n\n /**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function asciiToArray(string) {\n return string.split('');\n }\n\n /**\n * Splits an ASCII `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\n function asciiWords(string) {\n return string.match(reAsciiWord) || [];\n }\n\n /**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\n function baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n }\n\n /**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseIndexOf(array, value, fromIndex) {\n return value === value\n ? strictIndexOf(array, value, fromIndex)\n : baseFindIndex(array, baseIsNaN, fromIndex);\n }\n\n /**\n * This function is like `baseIndexOf` except that it accepts a comparator.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseIndexOfWith(array, value, fromIndex, comparator) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (comparator(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\n function baseIsNaN(value) {\n return value !== value;\n }\n\n /**\n * The base implementation of `_.mean` and `_.meanBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the mean.\n */\n function baseMean(array, iteratee) {\n var length = array == null ? 0 : array.length;\n return length ? (baseSum(array, iteratee) / length) : NAN;\n }\n\n /**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\n function baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n }\n\n /**\n * The base implementation of `_.propertyOf` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Function} Returns the new accessor function.\n */\n function basePropertyOf(object) {\n return function(key) {\n return object == null ? undefined : object[key];\n };\n }\n\n /**\n * The base implementation of `_.reduce` and `_.reduceRight`, without support\n * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} accumulator The initial value.\n * @param {boolean} initAccum Specify using the first or last element of\n * `collection` as the initial value.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the accumulated value.\n */\n function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n eachFunc(collection, function(value, index, collection) {\n accumulator = initAccum\n ? (initAccum = false, value)\n : iteratee(accumulator, value, index, collection);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.sortBy` which uses `comparer` to define the\n * sort order of `array` and replaces criteria objects with their corresponding\n * values.\n *\n * @private\n * @param {Array} array The array to sort.\n * @param {Function} comparer The function to define sort order.\n * @returns {Array} Returns `array`.\n */\n function baseSortBy(array, comparer) {\n var length = array.length;\n\n array.sort(comparer);\n while (length--) {\n array[length] = array[length].value;\n }\n return array;\n }\n\n /**\n * The base implementation of `_.sum` and `_.sumBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the sum.\n */\n function baseSum(array, iteratee) {\n var result,\n index = -1,\n length = array.length;\n\n while (++index < length) {\n var current = iteratee(array[index]);\n if (current !== undefined) {\n result = result === undefined ? current : (result + current);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\n function baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n }\n\n /**\n * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array\n * of key-value pairs for `object` corresponding to the property names of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the key-value pairs.\n */\n function baseToPairs(object, props) {\n return arrayMap(props, function(key) {\n return [key, object[key]];\n });\n }\n\n /**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\n function baseUnary(func) {\n return function(value) {\n return func(value);\n };\n }\n\n /**\n * The base implementation of `_.values` and `_.valuesIn` which creates an\n * array of `object` property values corresponding to the property names\n * of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the array of property values.\n */\n function baseValues(object, props) {\n return arrayMap(props, function(key) {\n return object[key];\n });\n }\n\n /**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function cacheHas(cache, key) {\n return cache.has(key);\n }\n\n /**\n * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the first unmatched string symbol.\n */\n function charsStartIndex(strSymbols, chrSymbols) {\n var index = -1,\n length = strSymbols.length;\n\n while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n return index;\n }\n\n /**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the last unmatched string symbol.\n */\n function charsEndIndex(strSymbols, chrSymbols) {\n var index = strSymbols.length;\n\n while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n return index;\n }\n\n /**\n * Gets the number of `placeholder` occurrences in `array`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} placeholder The placeholder to search for.\n * @returns {number} Returns the placeholder count.\n */\n function countHolders(array, placeholder) {\n var length = array.length,\n result = 0;\n\n while (length--) {\n if (array[length] === placeholder) {\n ++result;\n }\n }\n return result;\n }\n\n /**\n * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n * letters to basic Latin letters.\n *\n * @private\n * @param {string} letter The matched letter to deburr.\n * @returns {string} Returns the deburred letter.\n */\n var deburrLetter = basePropertyOf(deburredLetters);\n\n /**\n * Used by `_.escape` to convert characters to HTML entities.\n *\n * @private\n * @param {string} chr The matched character to escape.\n * @returns {string} Returns the escaped character.\n */\n var escapeHtmlChar = basePropertyOf(htmlEscapes);\n\n /**\n * Used by `_.template` to escape characters for inclusion in compiled string literals.\n *\n * @private\n * @param {string} chr The matched character to escape.\n * @returns {string} Returns the escaped character.\n */\n function escapeStringChar(chr) {\n return '\\\\' + stringEscapes[chr];\n }\n\n /**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\n function getValue(object, key) {\n return object == null ? undefined : object[key];\n }\n\n /**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\n function hasUnicode(string) {\n return reHasUnicode.test(string);\n }\n\n /**\n * Checks if `string` contains a word composed of Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a word is found, else `false`.\n */\n function hasUnicodeWord(string) {\n return reHasUnicodeWord.test(string);\n }\n\n /**\n * Converts `iterator` to an array.\n *\n * @private\n * @param {Object} iterator The iterator to convert.\n * @returns {Array} Returns the converted array.\n */\n function iteratorToArray(iterator) {\n var data,\n result = [];\n\n while (!(data = iterator.next()).done) {\n result.push(data.value);\n }\n return result;\n }\n\n /**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\n function mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n }\n\n /**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\n function overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n }\n\n /**\n * Replaces all `placeholder` elements in `array` with an internal placeholder\n * and returns an array of their indexes.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {*} placeholder The placeholder to replace.\n * @returns {Array} Returns the new array of placeholder indexes.\n */\n function replaceHolders(array, placeholder) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (value === placeholder || value === PLACEHOLDER) {\n array[index] = PLACEHOLDER;\n result[resIndex++] = index;\n }\n }\n return result;\n }\n\n /**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\n function setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n }\n\n /**\n * Converts `set` to its value-value pairs.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the value-value pairs.\n */\n function setToPairs(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = [value, value];\n });\n return result;\n }\n\n /**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * A specialized version of `_.lastIndexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function strictLastIndexOf(array, value, fromIndex) {\n var index = fromIndex + 1;\n while (index--) {\n if (array[index] === value) {\n return index;\n }\n }\n return index;\n }\n\n /**\n * Gets the number of symbols in `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the string size.\n */\n function stringSize(string) {\n return hasUnicode(string)\n ? unicodeSize(string)\n : asciiSize(string);\n }\n\n /**\n * Converts `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function stringToArray(string) {\n return hasUnicode(string)\n ? unicodeToArray(string)\n : asciiToArray(string);\n }\n\n /**\n * Used by `_.unescape` to convert HTML entities to characters.\n *\n * @private\n * @param {string} chr The matched character to unescape.\n * @returns {string} Returns the unescaped character.\n */\n var unescapeHtmlChar = basePropertyOf(htmlUnescapes);\n\n /**\n * Gets the size of a Unicode `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\n function unicodeSize(string) {\n var result = reUnicode.lastIndex = 0;\n while (reUnicode.test(string)) {\n ++result;\n }\n return result;\n }\n\n /**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function unicodeToArray(string) {\n return string.match(reUnicode) || [];\n }\n\n /**\n * Splits a Unicode `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\n function unicodeWords(string) {\n return string.match(reUnicodeWord) || [];\n }\n\n /*--------------------------------------------------------------------------*/\n\n /**\n * Create a new pristine `lodash` function using the `context` object.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Util\n * @param {Object} [context=root] The context object.\n * @returns {Function} Returns a new `lodash` function.\n * @example\n *\n * _.mixin({ 'foo': _.constant('foo') });\n *\n * var lodash = _.runInContext();\n * lodash.mixin({ 'bar': lodash.constant('bar') });\n *\n * _.isFunction(_.foo);\n * // => true\n * _.isFunction(_.bar);\n * // => false\n *\n * lodash.isFunction(lodash.foo);\n * // => false\n * lodash.isFunction(lodash.bar);\n * // => true\n *\n * // Create a suped-up `defer` in Node.js.\n * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;\n */\n var runInContext = (function runInContext(context) {\n context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));\n\n /** Built-in constructor references. */\n var Array = context.Array,\n Date = context.Date,\n Error = context.Error,\n Function = context.Function,\n Math = context.Math,\n Object = context.Object,\n RegExp = context.RegExp,\n String = context.String,\n TypeError = context.TypeError;\n\n /** Used for built-in method references. */\n var arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n /** Used to detect overreaching core-js shims. */\n var coreJsData = context['__core-js_shared__'];\n\n /** Used to resolve the decompiled source of functions. */\n var funcToString = funcProto.toString;\n\n /** Used to check objects for own properties. */\n var hasOwnProperty = objectProto.hasOwnProperty;\n\n /** Used to generate unique IDs. */\n var idCounter = 0;\n\n /** Used to detect methods masquerading as native. */\n var maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n }());\n\n /**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\n var nativeObjectToString = objectProto.toString;\n\n /** Used to infer the `Object` constructor. */\n var objectCtorString = funcToString.call(Object);\n\n /** Used to restore the original `_` reference in `_.noConflict`. */\n var oldDash = root._;\n\n /** Used to detect if a method is native. */\n var reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n );\n\n /** Built-in value references. */\n var Buffer = moduleExports ? context.Buffer : undefined,\n Symbol = context.Symbol,\n Uint8Array = context.Uint8Array,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,\n getPrototype = overArg(Object.getPrototypeOf, Object),\n objectCreate = Object.create,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice,\n spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,\n symIterator = Symbol ? Symbol.iterator : undefined,\n symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n var defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n }());\n\n /** Mocked built-ins. */\n var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,\n ctxNow = Date && Date.now !== root.Date.now && Date.now,\n ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;\n\n /* Built-in method references for those with the same name as other `lodash` methods. */\n var nativeCeil = Math.ceil,\n nativeFloor = Math.floor,\n nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeIsFinite = context.isFinite,\n nativeJoin = arrayProto.join,\n nativeKeys = overArg(Object.keys, Object),\n nativeMax = Math.max,\n nativeMin = Math.min,\n nativeNow = Date.now,\n nativeParseInt = context.parseInt,\n nativeRandom = Math.random,\n nativeReverse = arrayProto.reverse;\n\n /* Built-in method references that are verified to be native. */\n var DataView = getNative(context, 'DataView'),\n Map = getNative(context, 'Map'),\n Promise = getNative(context, 'Promise'),\n Set = getNative(context, 'Set'),\n WeakMap = getNative(context, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n /** Used to store function metadata. */\n var metaMap = WeakMap && new WeakMap;\n\n /** Used to lookup unminified function names. */\n var realNames = {};\n\n /** Used to detect maps, sets, and weakmaps. */\n var dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n /** Used to convert symbols to primitives and strings. */\n var symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a `lodash` object which wraps `value` to enable implicit method\n * chain sequences. Methods that operate on and return arrays, collections,\n * and functions can be chained together. Methods that retrieve a single value\n * or may return a primitive value will automatically end the chain sequence\n * and return the unwrapped value. Otherwise, the value must be unwrapped\n * with `_#value`.\n *\n * Explicit chain sequences, which must be unwrapped with `_#value`, may be\n * enabled using `_.chain`.\n *\n * The execution of chained methods is lazy, that is, it's deferred until\n * `_#value` is implicitly or explicitly called.\n *\n * Lazy evaluation allows several methods to support shortcut fusion.\n * Shortcut fusion is an optimization to merge iteratee calls; this avoids\n * the creation of intermediate arrays and can greatly reduce the number of\n * iteratee executions. Sections of a chain sequence qualify for shortcut\n * fusion if the section is applied to an array and iteratees accept only\n * one argument. The heuristic for whether a section qualifies for shortcut\n * fusion is subject to change.\n *\n * Chaining is supported in custom builds as long as the `_#value` method is\n * directly or indirectly included in the build.\n *\n * In addition to lodash methods, wrappers have `Array` and `String` methods.\n *\n * The wrapper `Array` methods are:\n * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`\n *\n * The wrapper `String` methods are:\n * `replace` and `split`\n *\n * The wrapper methods that support shortcut fusion are:\n * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,\n * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,\n * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`\n *\n * The chainable wrapper methods are:\n * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,\n * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,\n * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,\n * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,\n * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,\n * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,\n * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,\n * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,\n * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,\n * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,\n * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,\n * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,\n * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,\n * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,\n * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,\n * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,\n * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,\n * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,\n * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,\n * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,\n * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,\n * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,\n * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,\n * `zipObject`, `zipObjectDeep`, and `zipWith`\n *\n * The wrapper methods that are **not** chainable by default are:\n * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,\n * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,\n * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,\n * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,\n * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,\n * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,\n * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,\n * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,\n * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,\n * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,\n * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,\n * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,\n * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,\n * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,\n * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,\n * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,\n * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,\n * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,\n * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,\n * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,\n * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,\n * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,\n * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,\n * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,\n * `upperFirst`, `value`, and `words`\n *\n * @name _\n * @constructor\n * @category Seq\n * @param {*} value The value to wrap in a `lodash` instance.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var wrapped = _([1, 2, 3]);\n *\n * // Returns an unwrapped value.\n * wrapped.reduce(_.add);\n * // => 6\n *\n * // Returns a wrapped value.\n * var squares = wrapped.map(square);\n *\n * _.isArray(squares);\n * // => false\n *\n * _.isArray(squares.value());\n * // => true\n */\n function lodash(value) {\n if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n if (value instanceof LodashWrapper) {\n return value;\n }\n if (hasOwnProperty.call(value, '__wrapped__')) {\n return wrapperClone(value);\n }\n }\n return new LodashWrapper(value);\n }\n\n /**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\n var baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n }());\n\n /**\n * The function whose prototype chain sequence wrappers inherit from.\n *\n * @private\n */\n function baseLodash() {\n // No operation performed.\n }\n\n /**\n * The base constructor for creating `lodash` wrapper objects.\n *\n * @private\n * @param {*} value The value to wrap.\n * @param {boolean} [chainAll] Enable explicit method chain sequences.\n */\n function LodashWrapper(value, chainAll) {\n this.__wrapped__ = value;\n this.__actions__ = [];\n this.__chain__ = !!chainAll;\n this.__index__ = 0;\n this.__values__ = undefined;\n }\n\n /**\n * By default, the template delimiters used by lodash are like those in\n * embedded Ruby (ERB) as well as ES2015 template strings. Change the\n * following template settings to use alternative delimiters.\n *\n * @static\n * @memberOf _\n * @type {Object}\n */\n lodash.templateSettings = {\n\n /**\n * Used to detect `data` property values to be HTML-escaped.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'escape': reEscape,\n\n /**\n * Used to detect code to be evaluated.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'evaluate': reEvaluate,\n\n /**\n * Used to detect `data` property values to inject.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'interpolate': reInterpolate,\n\n /**\n * Used to reference the data object in the template text.\n *\n * @memberOf _.templateSettings\n * @type {string}\n */\n 'variable': '',\n\n /**\n * Used to import variables into the compiled template.\n *\n * @memberOf _.templateSettings\n * @type {Object}\n */\n 'imports': {\n\n /**\n * A reference to the `lodash` function.\n *\n * @memberOf _.templateSettings.imports\n * @type {Function}\n */\n '_': lodash\n }\n };\n\n // Ensure wrappers are instances of `baseLodash`.\n lodash.prototype = baseLodash.prototype;\n lodash.prototype.constructor = lodash;\n\n LodashWrapper.prototype = baseCreate(baseLodash.prototype);\n LodashWrapper.prototype.constructor = LodashWrapper;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n *\n * @private\n * @constructor\n * @param {*} value The value to wrap.\n */\n function LazyWrapper(value) {\n this.__wrapped__ = value;\n this.__actions__ = [];\n this.__dir__ = 1;\n this.__filtered__ = false;\n this.__iteratees__ = [];\n this.__takeCount__ = MAX_ARRAY_LENGTH;\n this.__views__ = [];\n }\n\n /**\n * Creates a clone of the lazy wrapper object.\n *\n * @private\n * @name clone\n * @memberOf LazyWrapper\n * @returns {Object} Returns the cloned `LazyWrapper` object.\n */\n function lazyClone() {\n var result = new LazyWrapper(this.__wrapped__);\n result.__actions__ = copyArray(this.__actions__);\n result.__dir__ = this.__dir__;\n result.__filtered__ = this.__filtered__;\n result.__iteratees__ = copyArray(this.__iteratees__);\n result.__takeCount__ = this.__takeCount__;\n result.__views__ = copyArray(this.__views__);\n return result;\n }\n\n /**\n * Reverses the direction of lazy iteration.\n *\n * @private\n * @name reverse\n * @memberOf LazyWrapper\n * @returns {Object} Returns the new reversed `LazyWrapper` object.\n */\n function lazyReverse() {\n if (this.__filtered__) {\n var result = new LazyWrapper(this);\n result.__dir__ = -1;\n result.__filtered__ = true;\n } else {\n result = this.clone();\n result.__dir__ *= -1;\n }\n return result;\n }\n\n /**\n * Extracts the unwrapped value from its lazy wrapper.\n *\n * @private\n * @name value\n * @memberOf LazyWrapper\n * @returns {*} Returns the unwrapped value.\n */\n function lazyValue() {\n var array = this.__wrapped__.value(),\n dir = this.__dir__,\n isArr = isArray(array),\n isRight = dir < 0,\n arrLength = isArr ? array.length : 0,\n view = getView(0, arrLength, this.__views__),\n start = view.start,\n end = view.end,\n length = end - start,\n index = isRight ? end : (start - 1),\n iteratees = this.__iteratees__,\n iterLength = iteratees.length,\n resIndex = 0,\n takeCount = nativeMin(length, this.__takeCount__);\n\n if (!isArr || (!isRight && arrLength == length && takeCount == length)) {\n return baseWrapperValue(array, this.__actions__);\n }\n var result = [];\n\n outer:\n while (length-- && resIndex < takeCount) {\n index += dir;\n\n var iterIndex = -1,\n value = array[index];\n\n while (++iterIndex < iterLength) {\n var data = iteratees[iterIndex],\n iteratee = data.iteratee,\n type = data.type,\n computed = iteratee(value);\n\n if (type == LAZY_MAP_FLAG) {\n value = computed;\n } else if (!computed) {\n if (type == LAZY_FILTER_FLAG) {\n continue outer;\n } else {\n break outer;\n }\n }\n }\n result[resIndex++] = value;\n }\n return result;\n }\n\n // Ensure `LazyWrapper` is an instance of `baseLodash`.\n LazyWrapper.prototype = baseCreate(baseLodash.prototype);\n LazyWrapper.prototype.constructor = LazyWrapper;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\n function hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n }\n\n /**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n }\n\n /**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n }\n\n /**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\n function hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n }\n\n // Add methods to `Hash`.\n Hash.prototype.clear = hashClear;\n Hash.prototype['delete'] = hashDelete;\n Hash.prototype.get = hashGet;\n Hash.prototype.has = hashHas;\n Hash.prototype.set = hashSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\n function listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n }\n\n /**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n }\n\n /**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n }\n\n /**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\n function listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n }\n\n // Add methods to `ListCache`.\n ListCache.prototype.clear = listCacheClear;\n ListCache.prototype['delete'] = listCacheDelete;\n ListCache.prototype.get = listCacheGet;\n ListCache.prototype.has = listCacheHas;\n ListCache.prototype.set = listCacheSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\n function mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n }\n\n /**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n }\n\n /**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function mapCacheGet(key) {\n return getMapData(this, key).get(key);\n }\n\n /**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function mapCacheHas(key) {\n return getMapData(this, key).has(key);\n }\n\n /**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\n function mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n }\n\n // Add methods to `MapCache`.\n MapCache.prototype.clear = mapCacheClear;\n MapCache.prototype['delete'] = mapCacheDelete;\n MapCache.prototype.get = mapCacheGet;\n MapCache.prototype.has = mapCacheHas;\n MapCache.prototype.set = mapCacheSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\n function SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n }\n\n /**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\n function setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n }\n\n /**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\n function setCacheHas(value) {\n return this.__data__.has(value);\n }\n\n // Add methods to `SetCache`.\n SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n SetCache.prototype.has = setCacheHas;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n }\n\n /**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\n function stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n }\n\n /**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function stackGet(key) {\n return this.__data__.get(key);\n }\n\n /**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function stackHas(key) {\n return this.__data__.has(key);\n }\n\n /**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\n function stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n }\n\n // Add methods to `Stack`.\n Stack.prototype.clear = stackClear;\n Stack.prototype['delete'] = stackDelete;\n Stack.prototype.get = stackGet;\n Stack.prototype.has = stackHas;\n Stack.prototype.set = stackSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\n function arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `_.sample` for arrays.\n *\n * @private\n * @param {Array} array The array to sample.\n * @returns {*} Returns the random element.\n */\n function arraySample(array) {\n var length = array.length;\n return length ? array[baseRandom(0, length - 1)] : undefined;\n }\n\n /**\n * A specialized version of `_.sampleSize` for arrays.\n *\n * @private\n * @param {Array} array The array to sample.\n * @param {number} n The number of elements to sample.\n * @returns {Array} Returns the random elements.\n */\n function arraySampleSize(array, n) {\n return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));\n }\n\n /**\n * A specialized version of `_.shuffle` for arrays.\n *\n * @private\n * @param {Array} array The array to shuffle.\n * @returns {Array} Returns the new shuffled array.\n */\n function arrayShuffle(array) {\n return shuffleSelf(copyArray(array));\n }\n\n /**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n }\n\n /**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n }\n\n /**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n }\n\n /**\n * Aggregates elements of `collection` on `accumulator` with keys transformed\n * by `iteratee` and values set by `setter`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\n function baseAggregator(collection, setter, iteratee, accumulator) {\n baseEach(collection, function(value, key, collection) {\n setter(accumulator, value, iteratee(value), collection);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\n function baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n }\n\n /**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\n function baseAssignIn(object, source) {\n return object && copyObject(source, keysIn(source), object);\n }\n\n /**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n }\n\n /**\n * The base implementation of `_.at` without support for individual paths.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {string[]} paths The property paths to pick.\n * @returns {Array} Returns the picked elements.\n */\n function baseAt(object, paths) {\n var index = -1,\n length = paths.length,\n result = Array(length),\n skip = object == null;\n\n while (++index < length) {\n result[index] = skip ? undefined : get(object, paths[index]);\n }\n return result;\n }\n\n /**\n * The base implementation of `_.clamp` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n */\n function baseClamp(number, lower, upper) {\n if (number === number) {\n if (upper !== undefined) {\n number = number <= upper ? number : upper;\n }\n if (lower !== undefined) {\n number = number >= lower ? number : lower;\n }\n }\n return number;\n }\n\n /**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\n function baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, baseClone, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n }\n\n /**\n * The base implementation of `_.conforms` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property predicates to conform to.\n * @returns {Function} Returns the new spec function.\n */\n function baseConforms(source) {\n var props = keys(source);\n return function(object) {\n return baseConformsTo(object, source, props);\n };\n }\n\n /**\n * The base implementation of `_.conformsTo` which accepts `props` to check.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property predicates to conform to.\n * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n */\n function baseConformsTo(object, source, props) {\n var length = props.length;\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (length--) {\n var key = props[length],\n predicate = source[key],\n value = object[key];\n\n if ((value === undefined && !(key in object)) || !predicate(value)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * The base implementation of `_.delay` and `_.defer` which accepts `args`\n * to provide to `func`.\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {Array} args The arguments to provide to `func`.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\n function baseDelay(func, wait, args) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return setTimeout(function() { func.apply(undefined, args); }, wait);\n }\n\n /**\n * The base implementation of methods like `_.difference` without support\n * for excluding multiple arrays or iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Array} values The values to exclude.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n */\n function baseDifference(array, values, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n isCommon = true,\n length = array.length,\n result = [],\n valuesLength = values.length;\n\n if (!length) {\n return result;\n }\n if (iteratee) {\n values = arrayMap(values, baseUnary(iteratee));\n }\n if (comparator) {\n includes = arrayIncludesWith;\n isCommon = false;\n }\n else if (values.length >= LARGE_ARRAY_SIZE) {\n includes = cacheHas;\n isCommon = false;\n values = new SetCache(values);\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee == null ? value : iteratee(value);\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var valuesIndex = valuesLength;\n while (valuesIndex--) {\n if (values[valuesIndex] === computed) {\n continue outer;\n }\n }\n result.push(value);\n }\n else if (!includes(values, computed, comparator)) {\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.forEach` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\n var baseEach = createBaseEach(baseForOwn);\n\n /**\n * The base implementation of `_.forEachRight` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\n var baseEachRight = createBaseEach(baseForOwnRight, true);\n\n /**\n * The base implementation of `_.every` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`\n */\n function baseEvery(collection, predicate) {\n var result = true;\n baseEach(collection, function(value, index, collection) {\n result = !!predicate(value, index, collection);\n return result;\n });\n return result;\n }\n\n /**\n * The base implementation of methods like `_.max` and `_.min` which accepts a\n * `comparator` to determine the extremum value.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The iteratee invoked per iteration.\n * @param {Function} comparator The comparator used to compare values.\n * @returns {*} Returns the extremum value.\n */\n function baseExtremum(array, iteratee, comparator) {\n var index = -1,\n length = array.length;\n\n while (++index < length) {\n var value = array[index],\n current = iteratee(value);\n\n if (current != null && (computed === undefined\n ? (current === current && !isSymbol(current))\n : comparator(current, computed)\n )) {\n var computed = current,\n result = value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.fill` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n */\n function baseFill(array, value, start, end) {\n var length = array.length;\n\n start = toInteger(start);\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = (end === undefined || end > length) ? length : toInteger(end);\n if (end < 0) {\n end += length;\n }\n end = start > end ? 0 : toLength(end);\n while (start < end) {\n array[start++] = value;\n }\n return array;\n }\n\n /**\n * The base implementation of `_.filter` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\n function baseFilter(collection, predicate) {\n var result = [];\n baseEach(collection, function(value, index, collection) {\n if (predicate(value, index, collection)) {\n result.push(value);\n }\n });\n return result;\n }\n\n /**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\n function baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\n var baseFor = createBaseFor();\n\n /**\n * This function is like `baseFor` except that it iterates over properties\n * in the opposite order.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\n var baseForRight = createBaseFor(true);\n\n /**\n * The base implementation of `_.forOwn` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\n function baseForOwn(object, iteratee) {\n return object && baseFor(object, iteratee, keys);\n }\n\n /**\n * The base implementation of `_.forOwnRight` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\n function baseForOwnRight(object, iteratee) {\n return object && baseForRight(object, iteratee, keys);\n }\n\n /**\n * The base implementation of `_.functions` which creates an array of\n * `object` function property names filtered from `props`.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Array} props The property names to filter.\n * @returns {Array} Returns the function names.\n */\n function baseFunctions(object, props) {\n return arrayFilter(props, function(key) {\n return isFunction(object[key]);\n });\n }\n\n /**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\n function baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n }\n\n /**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n }\n\n /**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\n function baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n }\n\n /**\n * The base implementation of `_.gt` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than `other`,\n * else `false`.\n */\n function baseGt(value, other) {\n return value > other;\n }\n\n /**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\n function baseHas(object, key) {\n return object != null && hasOwnProperty.call(object, key);\n }\n\n /**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\n function baseHasIn(object, key) {\n return object != null && key in Object(object);\n }\n\n /**\n * The base implementation of `_.inRange` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to check.\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n */\n function baseInRange(number, start, end) {\n return number >= nativeMin(start, end) && number < nativeMax(start, end);\n }\n\n /**\n * The base implementation of methods like `_.intersection`, without support\n * for iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of shared values.\n */\n function baseIntersection(arrays, iteratee, comparator) {\n var includes = comparator ? arrayIncludesWith : arrayIncludes,\n length = arrays[0].length,\n othLength = arrays.length,\n othIndex = othLength,\n caches = Array(othLength),\n maxLength = Infinity,\n result = [];\n\n while (othIndex--) {\n var array = arrays[othIndex];\n if (othIndex && iteratee) {\n array = arrayMap(array, baseUnary(iteratee));\n }\n maxLength = nativeMin(array.length, maxLength);\n caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n ? new SetCache(othIndex && array)\n : undefined;\n }\n array = arrays[0];\n\n var index = -1,\n seen = caches[0];\n\n outer:\n while (++index < length && result.length < maxLength) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (!(seen\n ? cacheHas(seen, computed)\n : includes(result, computed, comparator)\n )) {\n othIndex = othLength;\n while (--othIndex) {\n var cache = caches[othIndex];\n if (!(cache\n ? cacheHas(cache, computed)\n : includes(arrays[othIndex], computed, comparator))\n ) {\n continue outer;\n }\n }\n if (seen) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.invert` and `_.invertBy` which inverts\n * `object` with values transformed by `iteratee` and set by `setter`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform values.\n * @param {Object} accumulator The initial inverted object.\n * @returns {Function} Returns `accumulator`.\n */\n function baseInverter(object, setter, iteratee, accumulator) {\n baseForOwn(object, function(value, key, object) {\n setter(accumulator, iteratee(value), key, object);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.invoke` without support for individual\n * method arguments.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {Array} args The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n */\n function baseInvoke(object, path, args) {\n path = castPath(path, object);\n object = parent(object, path);\n var func = object == null ? object : object[toKey(last(path))];\n return func == null ? undefined : apply(func, object, args);\n }\n\n /**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\n function baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n }\n\n /**\n * The base implementation of `_.isArrayBuffer` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n */\n function baseIsArrayBuffer(value) {\n return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;\n }\n\n /**\n * The base implementation of `_.isDate` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n */\n function baseIsDate(value) {\n return isObjectLike(value) && baseGetTag(value) == dateTag;\n }\n\n /**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\n function baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n }\n\n /**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n }\n\n /**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\n function baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n }\n\n /**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\n function baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\n function baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n }\n\n /**\n * The base implementation of `_.isRegExp` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n */\n function baseIsRegExp(value) {\n return isObjectLike(value) && baseGetTag(value) == regexpTag;\n }\n\n /**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\n function baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n }\n\n /**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\n function baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n }\n\n /**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\n function baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n }\n\n /**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.lt` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than `other`,\n * else `false`.\n */\n function baseLt(value, other) {\n return value < other;\n }\n\n /**\n * The base implementation of `_.map` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\n function baseMap(collection, iteratee) {\n var index = -1,\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value, key, collection) {\n result[++index] = iteratee(value, key, collection);\n });\n return result;\n }\n\n /**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\n function baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n }\n\n /**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\n function baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n }\n\n /**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\n function baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n if (isObject(srcValue)) {\n stack || (stack = new Stack);\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(object[key], srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n }\n\n /**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\n function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = object[key],\n srcValue = source[key],\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n }\n\n /**\n * The base implementation of `_.nth` which doesn't coerce arguments.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {number} n The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n */\n function baseNth(array, n) {\n var length = array.length;\n if (!length) {\n return;\n }\n n += n < 0 ? length : 0;\n return isIndex(n, length) ? array[n] : undefined;\n }\n\n /**\n * The base implementation of `_.orderBy` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n * @param {string[]} orders The sort orders of `iteratees`.\n * @returns {Array} Returns the new sorted array.\n */\n function baseOrderBy(collection, iteratees, orders) {\n var index = -1;\n iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));\n\n var result = baseMap(collection, function(value, key, collection) {\n var criteria = arrayMap(iteratees, function(iteratee) {\n return iteratee(value);\n });\n return { 'criteria': criteria, 'index': ++index, 'value': value };\n });\n\n return baseSortBy(result, function(object, other) {\n return compareMultiple(object, other, orders);\n });\n }\n\n /**\n * The base implementation of `_.pick` without support for individual\n * property identifiers.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @returns {Object} Returns the new object.\n */\n function basePick(object, paths) {\n return basePickBy(object, paths, function(value, path) {\n return hasIn(object, path);\n });\n }\n\n /**\n * The base implementation of `_.pickBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @param {Function} predicate The function invoked per property.\n * @returns {Object} Returns the new object.\n */\n function basePickBy(object, paths, predicate) {\n var index = -1,\n length = paths.length,\n result = {};\n\n while (++index < length) {\n var path = paths[index],\n value = baseGet(object, path);\n\n if (predicate(value, path)) {\n baseSet(result, castPath(path, object), value);\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\n function basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n }\n\n /**\n * The base implementation of `_.pullAllBy` without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n */\n function basePullAll(array, values, iteratee, comparator) {\n var indexOf = comparator ? baseIndexOfWith : baseIndexOf,\n index = -1,\n length = values.length,\n seen = array;\n\n if (array === values) {\n values = copyArray(values);\n }\n if (iteratee) {\n seen = arrayMap(array, baseUnary(iteratee));\n }\n while (++index < length) {\n var fromIndex = 0,\n value = values[index],\n computed = iteratee ? iteratee(value) : value;\n\n while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {\n if (seen !== array) {\n splice.call(seen, fromIndex, 1);\n }\n splice.call(array, fromIndex, 1);\n }\n }\n return array;\n }\n\n /**\n * The base implementation of `_.pullAt` without support for individual\n * indexes or capturing the removed elements.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {number[]} indexes The indexes of elements to remove.\n * @returns {Array} Returns `array`.\n */\n function basePullAt(array, indexes) {\n var length = array ? indexes.length : 0,\n lastIndex = length - 1;\n\n while (length--) {\n var index = indexes[length];\n if (length == lastIndex || index !== previous) {\n var previous = index;\n if (isIndex(index)) {\n splice.call(array, index, 1);\n } else {\n baseUnset(array, index);\n }\n }\n }\n return array;\n }\n\n /**\n * The base implementation of `_.random` without support for returning\n * floating-point numbers.\n *\n * @private\n * @param {number} lower The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the random number.\n */\n function baseRandom(lower, upper) {\n return lower + nativeFloor(nativeRandom() * (upper - lower + 1));\n }\n\n /**\n * The base implementation of `_.range` and `_.rangeRight` which doesn't\n * coerce arguments.\n *\n * @private\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @param {number} step The value to increment or decrement by.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the range of numbers.\n */\n function baseRange(start, end, step, fromRight) {\n var index = -1,\n length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n result = Array(length);\n\n while (length--) {\n result[fromRight ? length : ++index] = start;\n start += step;\n }\n return result;\n }\n\n /**\n * The base implementation of `_.repeat` which doesn't coerce arguments.\n *\n * @private\n * @param {string} string The string to repeat.\n * @param {number} n The number of times to repeat the string.\n * @returns {string} Returns the repeated string.\n */\n function baseRepeat(string, n) {\n var result = '';\n if (!string || n < 1 || n > MAX_SAFE_INTEGER) {\n return result;\n }\n // Leverage the exponentiation by squaring algorithm for a faster repeat.\n // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.\n do {\n if (n % 2) {\n result += string;\n }\n n = nativeFloor(n / 2);\n if (n) {\n string += string;\n }\n } while (n);\n\n return result;\n }\n\n /**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\n function baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n }\n\n /**\n * The base implementation of `_.sample`.\n *\n * @private\n * @param {Array|Object} collection The collection to sample.\n * @returns {*} Returns the random element.\n */\n function baseSample(collection) {\n return arraySample(values(collection));\n }\n\n /**\n * The base implementation of `_.sampleSize` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to sample.\n * @param {number} n The number of elements to sample.\n * @returns {Array} Returns the random elements.\n */\n function baseSampleSize(collection, n) {\n var array = values(collection);\n return shuffleSelf(array, baseClamp(n, 0, array.length));\n }\n\n /**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\n function baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n }\n\n /**\n * The base implementation of `setData` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\n var baseSetData = !metaMap ? identity : function(func, data) {\n metaMap.set(func, data);\n return func;\n };\n\n /**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\n var baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n };\n\n /**\n * The base implementation of `_.shuffle`.\n *\n * @private\n * @param {Array|Object} collection The collection to shuffle.\n * @returns {Array} Returns the new shuffled array.\n */\n function baseShuffle(collection) {\n return shuffleSelf(values(collection));\n }\n\n /**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\n function baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n }\n\n /**\n * The base implementation of `_.some` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\n function baseSome(collection, predicate) {\n var result;\n\n baseEach(collection, function(value, index, collection) {\n result = predicate(value, index, collection);\n return !result;\n });\n return !!result;\n }\n\n /**\n * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which\n * performs a binary search of `array` to determine the index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\n function baseSortedIndex(array, value, retHighest) {\n var low = 0,\n high = array == null ? low : array.length;\n\n if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n while (low < high) {\n var mid = (low + high) >>> 1,\n computed = array[mid];\n\n if (computed !== null && !isSymbol(computed) &&\n (retHighest ? (computed <= value) : (computed < value))) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return high;\n }\n return baseSortedIndexBy(array, value, identity, retHighest);\n }\n\n /**\n * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`\n * which invokes `iteratee` for `value` and each element of `array` to compute\n * their sort ranking. The iteratee is invoked with one argument; (value).\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} iteratee The iteratee invoked per element.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\n function baseSortedIndexBy(array, value, iteratee, retHighest) {\n value = iteratee(value);\n\n var low = 0,\n high = array == null ? 0 : array.length,\n valIsNaN = value !== value,\n valIsNull = value === null,\n valIsSymbol = isSymbol(value),\n valIsUndefined = value === undefined;\n\n while (low < high) {\n var mid = nativeFloor((low + high) / 2),\n computed = iteratee(array[mid]),\n othIsDefined = computed !== undefined,\n othIsNull = computed === null,\n othIsReflexive = computed === computed,\n othIsSymbol = isSymbol(computed);\n\n if (valIsNaN) {\n var setLow = retHighest || othIsReflexive;\n } else if (valIsUndefined) {\n setLow = othIsReflexive && (retHighest || othIsDefined);\n } else if (valIsNull) {\n setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);\n } else if (valIsSymbol) {\n setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);\n } else if (othIsNull || othIsSymbol) {\n setLow = false;\n } else {\n setLow = retHighest ? (computed <= value) : (computed < value);\n }\n if (setLow) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return nativeMin(high, MAX_ARRAY_INDEX);\n }\n\n /**\n * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\n function baseSortedUniq(array, iteratee) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n if (!index || !eq(computed, seen)) {\n var seen = computed;\n result[resIndex++] = value === 0 ? 0 : value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.toNumber` which doesn't ensure correct\n * conversions of binary, hexadecimal, or octal string values.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n */\n function baseToNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n return +value;\n }\n\n /**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\n function baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n }\n\n /**\n * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\n function baseUniq(array, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n length = array.length,\n isCommon = true,\n result = [],\n seen = result;\n\n if (comparator) {\n isCommon = false;\n includes = arrayIncludesWith;\n }\n else if (length >= LARGE_ARRAY_SIZE) {\n var set = iteratee ? null : createSet(array);\n if (set) {\n return setToArray(set);\n }\n isCommon = false;\n includes = cacheHas;\n seen = new SetCache;\n }\n else {\n seen = iteratee ? [] : result;\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var seenIndex = seen.length;\n while (seenIndex--) {\n if (seen[seenIndex] === computed) {\n continue outer;\n }\n }\n if (iteratee) {\n seen.push(computed);\n }\n result.push(value);\n }\n else if (!includes(seen, computed, comparator)) {\n if (seen !== result) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.unset`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The property path to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n */\n function baseUnset(object, path) {\n path = castPath(path, object);\n object = parent(object, path);\n return object == null || delete object[toKey(last(path))];\n }\n\n /**\n * The base implementation of `_.update`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to update.\n * @param {Function} updater The function to produce the updated value.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\n function baseUpdate(object, path, updater, customizer) {\n return baseSet(object, path, updater(baseGet(object, path)), customizer);\n }\n\n /**\n * The base implementation of methods like `_.dropWhile` and `_.takeWhile`\n * without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {Function} predicate The function invoked per iteration.\n * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the slice of `array`.\n */\n function baseWhile(array, predicate, isDrop, fromRight) {\n var length = array.length,\n index = fromRight ? length : -1;\n\n while ((fromRight ? index-- : ++index < length) &&\n predicate(array[index], index, array)) {}\n\n return isDrop\n ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n }\n\n /**\n * The base implementation of `wrapperValue` which returns the result of\n * performing a sequence of actions on the unwrapped `value`, where each\n * successive action is supplied the return value of the previous.\n *\n * @private\n * @param {*} value The unwrapped value.\n * @param {Array} actions Actions to perform to resolve the unwrapped value.\n * @returns {*} Returns the resolved value.\n */\n function baseWrapperValue(value, actions) {\n var result = value;\n if (result instanceof LazyWrapper) {\n result = result.value();\n }\n return arrayReduce(actions, function(result, action) {\n return action.func.apply(action.thisArg, arrayPush([result], action.args));\n }, result);\n }\n\n /**\n * The base implementation of methods like `_.xor`, without support for\n * iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of values.\n */\n function baseXor(arrays, iteratee, comparator) {\n var length = arrays.length;\n if (length < 2) {\n return length ? baseUniq(arrays[0]) : [];\n }\n var index = -1,\n result = Array(length);\n\n while (++index < length) {\n var array = arrays[index],\n othIndex = -1;\n\n while (++othIndex < length) {\n if (othIndex != index) {\n result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);\n }\n }\n }\n return baseUniq(baseFlatten(result, 1), iteratee, comparator);\n }\n\n /**\n * This base implementation of `_.zipObject` which assigns values using `assignFunc`.\n *\n * @private\n * @param {Array} props The property identifiers.\n * @param {Array} values The property values.\n * @param {Function} assignFunc The function to assign values.\n * @returns {Object} Returns the new object.\n */\n function baseZipObject(props, values, assignFunc) {\n var index = -1,\n length = props.length,\n valsLength = values.length,\n result = {};\n\n while (++index < length) {\n var value = index < valsLength ? values[index] : undefined;\n assignFunc(result, props[index], value);\n }\n return result;\n }\n\n /**\n * Casts `value` to an empty array if it's not an array like object.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Array|Object} Returns the cast array-like object.\n */\n function castArrayLikeObject(value) {\n return isArrayLikeObject(value) ? value : [];\n }\n\n /**\n * Casts `value` to `identity` if it's not a function.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Function} Returns cast function.\n */\n function castFunction(value) {\n return typeof value == 'function' ? value : identity;\n }\n\n /**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\n function castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n }\n\n /**\n * A `baseRest` alias which can be replaced with `identity` by module\n * replacement plugins.\n *\n * @private\n * @type {Function}\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\n var castRest = baseRest;\n\n /**\n * Casts `array` to a slice if it's needed.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {number} start The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the cast slice.\n */\n function castSlice(array, start, end) {\n var length = array.length;\n end = end === undefined ? length : end;\n return (!start && end >= length) ? array : baseSlice(array, start, end);\n }\n\n /**\n * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).\n *\n * @private\n * @param {number|Object} id The timer id or timeout object of the timer to clear.\n */\n var clearTimeout = ctxClearTimeout || function(id) {\n return root.clearTimeout(id);\n };\n\n /**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\n function cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n }\n\n /**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\n function cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n }\n\n /**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\n function cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n }\n\n /**\n * Creates a clone of `map`.\n *\n * @private\n * @param {Object} map The map to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned map.\n */\n function cloneMap(map, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);\n return arrayReduce(array, addMapEntry, new map.constructor);\n }\n\n /**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\n function cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n }\n\n /**\n * Creates a clone of `set`.\n *\n * @private\n * @param {Object} set The set to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned set.\n */\n function cloneSet(set, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);\n return arrayReduce(array, addSetEntry, new set.constructor);\n }\n\n /**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\n function cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n }\n\n /**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\n function cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n }\n\n /**\n * Compares values to sort them in ascending order.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {number} Returns the sort order indicator for `value`.\n */\n function compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined,\n valIsNull = value === null,\n valIsReflexive = value === value,\n valIsSymbol = isSymbol(value);\n\n var othIsDefined = other !== undefined,\n othIsNull = other === null,\n othIsReflexive = other === other,\n othIsSymbol = isSymbol(other);\n\n if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n (valIsNull && othIsDefined && othIsReflexive) ||\n (!valIsDefined && othIsReflexive) ||\n !valIsReflexive) {\n return 1;\n }\n if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n (othIsNull && valIsDefined && valIsReflexive) ||\n (!othIsDefined && valIsReflexive) ||\n !othIsReflexive) {\n return -1;\n }\n }\n return 0;\n }\n\n /**\n * Used by `_.orderBy` to compare multiple properties of a value to another\n * and stable sort them.\n *\n * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n * of corresponding values.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {boolean[]|string[]} orders The order to sort by for each property.\n * @returns {number} Returns the sort order indicator for `object`.\n */\n function compareMultiple(object, other, orders) {\n var index = -1,\n objCriteria = object.criteria,\n othCriteria = other.criteria,\n length = objCriteria.length,\n ordersLength = orders.length;\n\n while (++index < length) {\n var result = compareAscending(objCriteria[index], othCriteria[index]);\n if (result) {\n if (index >= ordersLength) {\n return result;\n }\n var order = orders[index];\n return result * (order == 'desc' ? -1 : 1);\n }\n }\n // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n // that causes it, under certain circumstances, to provide the same value for\n // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n // for more details.\n //\n // This also ensures a stable sort in V8 and other engines.\n // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n return object.index - other.index;\n }\n\n /**\n * Creates an array that is the composition of partially applied arguments,\n * placeholders, and provided arguments into a single array of arguments.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to prepend to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\n function composeArgs(args, partials, holders, isCurried) {\n var argsIndex = -1,\n argsLength = args.length,\n holdersLength = holders.length,\n leftIndex = -1,\n leftLength = partials.length,\n rangeLength = nativeMax(argsLength - holdersLength, 0),\n result = Array(leftLength + rangeLength),\n isUncurried = !isCurried;\n\n while (++leftIndex < leftLength) {\n result[leftIndex] = partials[leftIndex];\n }\n while (++argsIndex < holdersLength) {\n if (isUncurried || argsIndex < argsLength) {\n result[holders[argsIndex]] = args[argsIndex];\n }\n }\n while (rangeLength--) {\n result[leftIndex++] = args[argsIndex++];\n }\n return result;\n }\n\n /**\n * This function is like `composeArgs` except that the arguments composition\n * is tailored for `_.partialRight`.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to append to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\n function composeArgsRight(args, partials, holders, isCurried) {\n var argsIndex = -1,\n argsLength = args.length,\n holdersIndex = -1,\n holdersLength = holders.length,\n rightIndex = -1,\n rightLength = partials.length,\n rangeLength = nativeMax(argsLength - holdersLength, 0),\n result = Array(rangeLength + rightLength),\n isUncurried = !isCurried;\n\n while (++argsIndex < rangeLength) {\n result[argsIndex] = args[argsIndex];\n }\n var offset = argsIndex;\n while (++rightIndex < rightLength) {\n result[offset + rightIndex] = partials[rightIndex];\n }\n while (++holdersIndex < holdersLength) {\n if (isUncurried || argsIndex < argsLength) {\n result[offset + holders[holdersIndex]] = args[argsIndex++];\n }\n }\n return result;\n }\n\n /**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\n function copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n }\n\n /**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\n function copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n }\n\n /**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\n function copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n }\n\n /**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\n function copySymbolsIn(source, object) {\n return copyObject(source, getSymbolsIn(source), object);\n }\n\n /**\n * Creates a function like `_.groupBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} [initializer] The accumulator object initializer.\n * @returns {Function} Returns the new aggregator function.\n */\n function createAggregator(setter, initializer) {\n return function(collection, iteratee) {\n var func = isArray(collection) ? arrayAggregator : baseAggregator,\n accumulator = initializer ? initializer() : {};\n\n return func(collection, setter, getIteratee(iteratee, 2), accumulator);\n };\n }\n\n /**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\n function createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n }\n\n /**\n * Creates a `baseEach` or `baseEachRight` function.\n *\n * @private\n * @param {Function} eachFunc The function to iterate over a collection.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\n function createBaseEach(eachFunc, fromRight) {\n return function(collection, iteratee) {\n if (collection == null) {\n return collection;\n }\n if (!isArrayLike(collection)) {\n return eachFunc(collection, iteratee);\n }\n var length = collection.length,\n index = fromRight ? length : -1,\n iterable = Object(collection);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (iteratee(iterable[index], index, iterable) === false) {\n break;\n }\n }\n return collection;\n };\n }\n\n /**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\n function createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with the optional `this`\n * binding of `thisArg`.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createBind(func, bitmask, thisArg) {\n var isBind = bitmask & WRAP_BIND_FLAG,\n Ctor = createCtor(func);\n\n function wrapper() {\n var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n return fn.apply(isBind ? thisArg : this, arguments);\n }\n return wrapper;\n }\n\n /**\n * Creates a function like `_.lowerFirst`.\n *\n * @private\n * @param {string} methodName The name of the `String` case method to use.\n * @returns {Function} Returns the new case function.\n */\n function createCaseFirst(methodName) {\n return function(string) {\n string = toString(string);\n\n var strSymbols = hasUnicode(string)\n ? stringToArray(string)\n : undefined;\n\n var chr = strSymbols\n ? strSymbols[0]\n : string.charAt(0);\n\n var trailing = strSymbols\n ? castSlice(strSymbols, 1).join('')\n : string.slice(1);\n\n return chr[methodName]() + trailing;\n };\n }\n\n /**\n * Creates a function like `_.camelCase`.\n *\n * @private\n * @param {Function} callback The function to combine each word.\n * @returns {Function} Returns the new compounder function.\n */\n function createCompounder(callback) {\n return function(string) {\n return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n };\n }\n\n /**\n * Creates a function that produces an instance of `Ctor` regardless of\n * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n *\n * @private\n * @param {Function} Ctor The constructor to wrap.\n * @returns {Function} Returns the new wrapped function.\n */\n function createCtor(Ctor) {\n return function() {\n // Use a `switch` statement to work with class constructors. See\n // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n // for more details.\n var args = arguments;\n switch (args.length) {\n case 0: return new Ctor;\n case 1: return new Ctor(args[0]);\n case 2: return new Ctor(args[0], args[1]);\n case 3: return new Ctor(args[0], args[1], args[2]);\n case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n }\n var thisBinding = baseCreate(Ctor.prototype),\n result = Ctor.apply(thisBinding, args);\n\n // Mimic the constructor's `return` behavior.\n // See https://es5.github.io/#x13.2.2 for more details.\n return isObject(result) ? result : thisBinding;\n };\n }\n\n /**\n * Creates a function that wraps `func` to enable currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {number} arity The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createCurry(func, bitmask, arity) {\n var Ctor = createCtor(func);\n\n function wrapper() {\n var length = arguments.length,\n args = Array(length),\n index = length,\n placeholder = getHolder(wrapper);\n\n while (index--) {\n args[index] = arguments[index];\n }\n var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)\n ? []\n : replaceHolders(args, placeholder);\n\n length -= holders.length;\n if (length < arity) {\n return createRecurry(\n func, bitmask, createHybrid, wrapper.placeholder, undefined,\n args, holders, undefined, undefined, arity - length);\n }\n var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n return apply(fn, this, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\n function createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = getIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n }\n\n /**\n * Creates a `_.flow` or `_.flowRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new flow function.\n */\n function createFlow(fromRight) {\n return flatRest(function(funcs) {\n var length = funcs.length,\n index = length,\n prereq = LodashWrapper.prototype.thru;\n\n if (fromRight) {\n funcs.reverse();\n }\n while (index--) {\n var func = funcs[index];\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (prereq && !wrapper && getFuncName(func) == 'wrapper') {\n var wrapper = new LodashWrapper([], true);\n }\n }\n index = wrapper ? index : length;\n while (++index < length) {\n func = funcs[index];\n\n var funcName = getFuncName(func),\n data = funcName == 'wrapper' ? getData(func) : undefined;\n\n if (data && isLaziable(data[0]) &&\n data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&\n !data[4].length && data[9] == 1\n ) {\n wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n } else {\n wrapper = (func.length == 1 && isLaziable(func))\n ? wrapper[funcName]()\n : wrapper.thru(func);\n }\n }\n return function() {\n var args = arguments,\n value = args[0];\n\n if (wrapper && args.length == 1 && isArray(value)) {\n return wrapper.plant(value).value();\n }\n var index = 0,\n result = length ? funcs[index].apply(this, args) : value;\n\n while (++index < length) {\n result = funcs[index].call(this, result);\n }\n return result;\n };\n });\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with optional `this`\n * binding of `thisArg`, partial application, and currying.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n * the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [partialsRight] The arguments to append to those provided\n * to the new function.\n * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n var isAry = bitmask & WRAP_ARY_FLAG,\n isBind = bitmask & WRAP_BIND_FLAG,\n isBindKey = bitmask & WRAP_BIND_KEY_FLAG,\n isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),\n isFlip = bitmask & WRAP_FLIP_FLAG,\n Ctor = isBindKey ? undefined : createCtor(func);\n\n function wrapper() {\n var length = arguments.length,\n args = Array(length),\n index = length;\n\n while (index--) {\n args[index] = arguments[index];\n }\n if (isCurried) {\n var placeholder = getHolder(wrapper),\n holdersCount = countHolders(args, placeholder);\n }\n if (partials) {\n args = composeArgs(args, partials, holders, isCurried);\n }\n if (partialsRight) {\n args = composeArgsRight(args, partialsRight, holdersRight, isCurried);\n }\n length -= holdersCount;\n if (isCurried && length < arity) {\n var newHolders = replaceHolders(args, placeholder);\n return createRecurry(\n func, bitmask, createHybrid, wrapper.placeholder, thisArg,\n args, newHolders, argPos, ary, arity - length\n );\n }\n var thisBinding = isBind ? thisArg : this,\n fn = isBindKey ? thisBinding[func] : func;\n\n length = args.length;\n if (argPos) {\n args = reorder(args, argPos);\n } else if (isFlip && length > 1) {\n args.reverse();\n }\n if (isAry && ary < length) {\n args.length = ary;\n }\n if (this && this !== root && this instanceof wrapper) {\n fn = Ctor || createCtor(fn);\n }\n return fn.apply(thisBinding, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a function like `_.invertBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} toIteratee The function to resolve iteratees.\n * @returns {Function} Returns the new inverter function.\n */\n function createInverter(setter, toIteratee) {\n return function(object, iteratee) {\n return baseInverter(object, setter, toIteratee(iteratee), {});\n };\n }\n\n /**\n * Creates a function that performs a mathematical operation on two values.\n *\n * @private\n * @param {Function} operator The function to perform the operation.\n * @param {number} [defaultValue] The value used for `undefined` arguments.\n * @returns {Function} Returns the new mathematical operation function.\n */\n function createMathOperation(operator, defaultValue) {\n return function(value, other) {\n var result;\n if (value === undefined && other === undefined) {\n return defaultValue;\n }\n if (value !== undefined) {\n result = value;\n }\n if (other !== undefined) {\n if (result === undefined) {\n return other;\n }\n if (typeof value == 'string' || typeof other == 'string') {\n value = baseToString(value);\n other = baseToString(other);\n } else {\n value = baseToNumber(value);\n other = baseToNumber(other);\n }\n result = operator(value, other);\n }\n return result;\n };\n }\n\n /**\n * Creates a function like `_.over`.\n *\n * @private\n * @param {Function} arrayFunc The function to iterate over iteratees.\n * @returns {Function} Returns the new over function.\n */\n function createOver(arrayFunc) {\n return flatRest(function(iteratees) {\n iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n return baseRest(function(args) {\n var thisArg = this;\n return arrayFunc(iteratees, function(iteratee) {\n return apply(iteratee, thisArg, args);\n });\n });\n });\n }\n\n /**\n * Creates the padding for `string` based on `length`. The `chars` string\n * is truncated if the number of characters exceeds `length`.\n *\n * @private\n * @param {number} length The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padding for `string`.\n */\n function createPadding(length, chars) {\n chars = chars === undefined ? ' ' : baseToString(chars);\n\n var charsLength = chars.length;\n if (charsLength < 2) {\n return charsLength ? baseRepeat(chars, length) : chars;\n }\n var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));\n return hasUnicode(chars)\n ? castSlice(stringToArray(result), 0, length).join('')\n : result.slice(0, length);\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with the `this` binding\n * of `thisArg` and `partials` prepended to the arguments it receives.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} partials The arguments to prepend to those provided to\n * the new function.\n * @returns {Function} Returns the new wrapped function.\n */\n function createPartial(func, bitmask, thisArg, partials) {\n var isBind = bitmask & WRAP_BIND_FLAG,\n Ctor = createCtor(func);\n\n function wrapper() {\n var argsIndex = -1,\n argsLength = arguments.length,\n leftIndex = -1,\n leftLength = partials.length,\n args = Array(leftLength + argsLength),\n fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n\n while (++leftIndex < leftLength) {\n args[leftIndex] = partials[leftIndex];\n }\n while (argsLength--) {\n args[leftIndex++] = arguments[++argsIndex];\n }\n return apply(fn, isBind ? thisArg : this, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a `_.range` or `_.rangeRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new range function.\n */\n function createRange(fromRight) {\n return function(start, end, step) {\n if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n end = step = undefined;\n }\n // Ensure the sign of `-0` is preserved.\n start = toFinite(start);\n if (end === undefined) {\n end = start;\n start = 0;\n } else {\n end = toFinite(end);\n }\n step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n return baseRange(start, end, step, fromRight);\n };\n }\n\n /**\n * Creates a function that performs a relational operation on two values.\n *\n * @private\n * @param {Function} operator The function to perform the operation.\n * @returns {Function} Returns the new relational operation function.\n */\n function createRelationalOperation(operator) {\n return function(value, other) {\n if (!(typeof value == 'string' && typeof other == 'string')) {\n value = toNumber(value);\n other = toNumber(other);\n }\n return operator(value, other);\n };\n }\n\n /**\n * Creates a function that wraps `func` to continue currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {Function} wrapFunc The function to create the `func` wrapper.\n * @param {*} placeholder The placeholder value.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n * the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {\n var isCurry = bitmask & WRAP_CURRY_FLAG,\n newHolders = isCurry ? holders : undefined,\n newHoldersRight = isCurry ? undefined : holders,\n newPartials = isCurry ? partials : undefined,\n newPartialsRight = isCurry ? undefined : partials;\n\n bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);\n bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);\n\n if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {\n bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);\n }\n var newData = [\n func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,\n newHoldersRight, argPos, ary, arity\n ];\n\n var result = wrapFunc.apply(undefined, newData);\n if (isLaziable(func)) {\n setData(result, newData);\n }\n result.placeholder = placeholder;\n return setWrapToString(result, func, bitmask);\n }\n\n /**\n * Creates a function like `_.round`.\n *\n * @private\n * @param {string} methodName The name of the `Math` method to use when rounding.\n * @returns {Function} Returns the new round function.\n */\n function createRound(methodName) {\n var func = Math[methodName];\n return function(number, precision) {\n number = toNumber(number);\n precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);\n if (precision) {\n // Shift with exponential notation to avoid floating-point issues.\n // See [MDN](https://mdn.io/round#Examples) for more details.\n var pair = (toString(number) + 'e').split('e'),\n value = func(pair[0] + 'e' + (+pair[1] + precision));\n\n pair = (toString(value) + 'e').split('e');\n return +(pair[0] + 'e' + (+pair[1] - precision));\n }\n return func(number);\n };\n }\n\n /**\n * Creates a set object of `values`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\n var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n return new Set(values);\n };\n\n /**\n * Creates a `_.toPairs` or `_.toPairsIn` function.\n *\n * @private\n * @param {Function} keysFunc The function to get the keys of a given object.\n * @returns {Function} Returns the new pairs function.\n */\n function createToPairs(keysFunc) {\n return function(object) {\n var tag = getTag(object);\n if (tag == mapTag) {\n return mapToArray(object);\n }\n if (tag == setTag) {\n return setToPairs(object);\n }\n return baseToPairs(object, keysFunc(object));\n };\n }\n\n /**\n * Creates a function that either curries or invokes `func` with optional\n * `this` binding and partially applied arguments.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags.\n * 1 - `_.bind`\n * 2 - `_.bindKey`\n * 4 - `_.curry` or `_.curryRight` of a bound function\n * 8 - `_.curry`\n * 16 - `_.curryRight`\n * 32 - `_.partial`\n * 64 - `_.partialRight`\n * 128 - `_.rearg`\n * 256 - `_.ary`\n * 512 - `_.flip`\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to be partially applied.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;\n if (!isBindKey && typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var length = partials ? partials.length : 0;\n if (!length) {\n bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);\n partials = holders = undefined;\n }\n ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);\n arity = arity === undefined ? arity : toInteger(arity);\n length -= holders ? holders.length : 0;\n\n if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {\n var partialsRight = partials,\n holdersRight = holders;\n\n partials = holders = undefined;\n }\n var data = isBindKey ? undefined : getData(func);\n\n var newData = [\n func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,\n argPos, ary, arity\n ];\n\n if (data) {\n mergeData(newData, data);\n }\n func = newData[0];\n bitmask = newData[1];\n thisArg = newData[2];\n partials = newData[3];\n holders = newData[4];\n arity = newData[9] = newData[9] === undefined\n ? (isBindKey ? 0 : func.length)\n : nativeMax(newData[9] - length, 0);\n\n if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {\n bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);\n }\n if (!bitmask || bitmask == WRAP_BIND_FLAG) {\n var result = createBind(func, bitmask, thisArg);\n } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {\n result = createCurry(func, bitmask, arity);\n } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {\n result = createPartial(func, bitmask, thisArg, partials);\n } else {\n result = createHybrid.apply(undefined, newData);\n }\n var setter = data ? baseSetData : setData;\n return setWrapToString(setter(result, newData), func, bitmask);\n }\n\n /**\n * Used by `_.defaults` to customize its `_.assignIn` use to assign properties\n * of source objects to the destination object for all destination properties\n * that resolve to `undefined`.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to assign.\n * @param {Object} object The parent object of `objValue`.\n * @returns {*} Returns the value to assign.\n */\n function customDefaultsAssignIn(objValue, srcValue, key, object) {\n if (objValue === undefined ||\n (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n return srcValue;\n }\n return objValue;\n }\n\n /**\n * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n * objects into destination objects that are passed thru.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to merge.\n * @param {Object} object The parent object of `objValue`.\n * @param {Object} source The parent object of `srcValue`.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n * @returns {*} Returns the value to assign.\n */\n function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n if (isObject(objValue) && isObject(srcValue)) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, objValue);\n baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n stack['delete'](srcValue);\n }\n return objValue;\n }\n\n /**\n * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n * objects.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {string} key The key of the property to inspect.\n * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n */\n function customOmitClone(value) {\n return isPlainObject(value) ? undefined : value;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\n function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n }\n\n /**\n * A specialized version of `baseRest` which flattens the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\n function flatRest(func) {\n return setToString(overRest(func, undefined, flatten), func + '');\n }\n\n /**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n }\n\n /**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n }\n\n /**\n * Gets metadata for `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {*} Returns the metadata for `func`.\n */\n var getData = !metaMap ? noop : function(func) {\n return metaMap.get(func);\n };\n\n /**\n * Gets the name of `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {string} Returns the function name.\n */\n function getFuncName(func) {\n var result = (func.name + ''),\n array = realNames[result],\n length = hasOwnProperty.call(realNames, result) ? array.length : 0;\n\n while (length--) {\n var data = array[length],\n otherFunc = data.func;\n if (otherFunc == null || otherFunc == func) {\n return data.name;\n }\n }\n return result;\n }\n\n /**\n * Gets the argument placeholder value for `func`.\n *\n * @private\n * @param {Function} func The function to inspect.\n * @returns {*} Returns the placeholder value.\n */\n function getHolder(func) {\n var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;\n return object.placeholder;\n }\n\n /**\n * Gets the appropriate \"iteratee\" function. If `_.iteratee` is customized,\n * this function returns the custom method, otherwise it returns `baseIteratee`.\n * If arguments are provided, the chosen function is invoked with them and\n * its result is returned.\n *\n * @private\n * @param {*} [value] The value to convert to an iteratee.\n * @param {number} [arity] The arity of the created iteratee.\n * @returns {Function} Returns the chosen function or its result.\n */\n function getIteratee() {\n var result = lodash.iteratee || iteratee;\n result = result === iteratee ? baseIteratee : result;\n return arguments.length ? result(arguments[0], arguments[1]) : result;\n }\n\n /**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\n function getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n }\n\n /**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\n function getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n }\n\n /**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\n function getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n }\n\n /**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\n function getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n }\n\n /**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\n var getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n };\n\n /**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\n var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n };\n\n /**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\n var getTag = baseGetTag;\n\n // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\n if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n }\n\n /**\n * Gets the view, applying any `transforms` to the `start` and `end` positions.\n *\n * @private\n * @param {number} start The start of the view.\n * @param {number} end The end of the view.\n * @param {Array} transforms The transformations to apply to the view.\n * @returns {Object} Returns an object containing the `start` and `end`\n * positions of the view.\n */\n function getView(start, end, transforms) {\n var index = -1,\n length = transforms.length;\n\n while (++index < length) {\n var data = transforms[index],\n size = data.size;\n\n switch (data.type) {\n case 'drop': start += size; break;\n case 'dropRight': end -= size; break;\n case 'take': end = nativeMin(end, start + size); break;\n case 'takeRight': start = nativeMax(start, end - size); break;\n }\n }\n return { 'start': start, 'end': end };\n }\n\n /**\n * Extracts wrapper details from the `source` body comment.\n *\n * @private\n * @param {string} source The source to inspect.\n * @returns {Array} Returns the wrapper details.\n */\n function getWrapDetails(source) {\n var match = source.match(reWrapDetails);\n return match ? match[1].split(reSplitDetails) : [];\n }\n\n /**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\n function hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n }\n\n /**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\n function initCloneArray(array) {\n var length = array.length,\n result = array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n }\n\n /**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\n function initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n }\n\n /**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\n function initCloneByTag(object, tag, cloneFunc, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return cloneMap(object, isDeep, cloneFunc);\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return cloneSet(object, isDeep, cloneFunc);\n\n case symbolTag:\n return cloneSymbol(object);\n }\n }\n\n /**\n * Inserts wrapper `details` in a comment at the top of the `source` body.\n *\n * @private\n * @param {string} source The source to modify.\n * @returns {Array} details The details to insert.\n * @returns {string} Returns the modified source.\n */\n function insertWrapDetails(source, details) {\n var length = details.length;\n if (!length) {\n return source;\n }\n var lastIndex = length - 1;\n details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];\n details = details.join(length > 2 ? ', ' : ' ');\n return source.replace(reWrapComment, '{\\n/* [wrapped with ' + details + '] */\\n');\n }\n\n /**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\n function isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n }\n\n /**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\n function isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n }\n\n /**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\n function isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n }\n\n /**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\n function isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n }\n\n /**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\n function isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n }\n\n /**\n * Checks if `func` has a lazy counterpart.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` has a lazy counterpart,\n * else `false`.\n */\n function isLaziable(func) {\n var funcName = getFuncName(func),\n other = lodash[funcName];\n\n if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\n return false;\n }\n if (func === other) {\n return true;\n }\n var data = getData(other);\n return !!data && func === data[0];\n }\n\n /**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\n function isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n }\n\n /**\n * Checks if `func` is capable of being masked.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `func` is maskable, else `false`.\n */\n var isMaskable = coreJsData ? isFunction : stubFalse;\n\n /**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\n function isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n }\n\n /**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\n function isStrictComparable(value) {\n return value === value && !isObject(value);\n }\n\n /**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\n function matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n }\n\n /**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\n function memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n }\n\n /**\n * Merges the function metadata of `source` into `data`.\n *\n * Merging metadata reduces the number of wrappers used to invoke a function.\n * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n * may be applied regardless of execution order. Methods like `_.ary` and\n * `_.rearg` modify function arguments, making the order in which they are\n * executed important, preventing the merging of metadata. However, we make\n * an exception for a safe combined case where curried functions have `_.ary`\n * and or `_.rearg` applied.\n *\n * @private\n * @param {Array} data The destination metadata.\n * @param {Array} source The source metadata.\n * @returns {Array} Returns `data`.\n */\n function mergeData(data, source) {\n var bitmask = data[1],\n srcBitmask = source[1],\n newBitmask = bitmask | srcBitmask,\n isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);\n\n var isCombo =\n ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||\n ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||\n ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));\n\n // Exit early if metadata can't be merged.\n if (!(isCommon || isCombo)) {\n return data;\n }\n // Use source `thisArg` if available.\n if (srcBitmask & WRAP_BIND_FLAG) {\n data[2] = source[2];\n // Set when currying a bound function.\n newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;\n }\n // Compose partial arguments.\n var value = source[3];\n if (value) {\n var partials = data[3];\n data[3] = partials ? composeArgs(partials, value, source[4]) : value;\n data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];\n }\n // Compose partial right arguments.\n value = source[5];\n if (value) {\n partials = data[5];\n data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;\n data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];\n }\n // Use source `argPos` if available.\n value = source[7];\n if (value) {\n data[7] = value;\n }\n // Use source `ary` if it's smaller.\n if (srcBitmask & WRAP_ARY_FLAG) {\n data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n }\n // Use source `arity` if one is not provided.\n if (data[9] == null) {\n data[9] = source[9];\n }\n // Use source `func` and merge bitmasks.\n data[0] = source[0];\n data[1] = newBitmask;\n\n return data;\n }\n\n /**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\n function objectToString(value) {\n return nativeObjectToString.call(value);\n }\n\n /**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\n function overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n }\n\n /**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\n function parent(object, path) {\n return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n }\n\n /**\n * Reorder `array` according to the specified indexes where the element at\n * the first index is assigned as the first element, the element at\n * the second index is assigned as the second element, and so on.\n *\n * @private\n * @param {Array} array The array to reorder.\n * @param {Array} indexes The arranged array indexes.\n * @returns {Array} Returns `array`.\n */\n function reorder(array, indexes) {\n var arrLength = array.length,\n length = nativeMin(indexes.length, arrLength),\n oldArray = copyArray(array);\n\n while (length--) {\n var index = indexes[length];\n array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n }\n return array;\n }\n\n /**\n * Sets metadata for `func`.\n *\n * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n * period of time, it will trip its breaker and transition to an identity\n * function to avoid garbage collection pauses in V8. See\n * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)\n * for more details.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\n var setData = shortOut(baseSetData);\n\n /**\n * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\n var setTimeout = ctxSetTimeout || function(func, wait) {\n return root.setTimeout(func, wait);\n };\n\n /**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\n var setToString = shortOut(baseSetToString);\n\n /**\n * Sets the `toString` method of `wrapper` to mimic the source of `reference`\n * with wrapper details in a comment at the top of the source body.\n *\n * @private\n * @param {Function} wrapper The function to modify.\n * @param {Function} reference The reference function.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Function} Returns `wrapper`.\n */\n function setWrapToString(wrapper, reference, bitmask) {\n var source = (reference + '');\n return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));\n }\n\n /**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\n function shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n }\n\n /**\n * A specialized version of `_.shuffle` which mutates and sets the size of `array`.\n *\n * @private\n * @param {Array} array The array to shuffle.\n * @param {number} [size=array.length] The size of `array`.\n * @returns {Array} Returns `array`.\n */\n function shuffleSelf(array, size) {\n var index = -1,\n length = array.length,\n lastIndex = length - 1;\n\n size = size === undefined ? length : size;\n while (++index < size) {\n var rand = baseRandom(index, lastIndex),\n value = array[rand];\n\n array[rand] = array[index];\n array[index] = value;\n }\n array.length = size;\n return array;\n }\n\n /**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\n var stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (reLeadingDot.test(string)) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, string) {\n result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n });\n\n /**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\n function toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n }\n\n /**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\n function toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n }\n\n /**\n * Updates wrapper `details` based on `bitmask` flags.\n *\n * @private\n * @returns {Array} details The details to modify.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Array} Returns `details`.\n */\n function updateWrapDetails(details, bitmask) {\n arrayEach(wrapFlags, function(pair) {\n var value = '_.' + pair[0];\n if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {\n details.push(value);\n }\n });\n return details.sort();\n }\n\n /**\n * Creates a clone of `wrapper`.\n *\n * @private\n * @param {Object} wrapper The wrapper to clone.\n * @returns {Object} Returns the cloned wrapper.\n */\n function wrapperClone(wrapper) {\n if (wrapper instanceof LazyWrapper) {\n return wrapper.clone();\n }\n var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);\n result.__actions__ = copyArray(wrapper.__actions__);\n result.__index__ = wrapper.__index__;\n result.__values__ = wrapper.__values__;\n return result;\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an array of elements split into groups the length of `size`.\n * If `array` can't be split evenly, the final chunk will be the remaining\n * elements.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to process.\n * @param {number} [size=1] The length of each chunk\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the new array of chunks.\n * @example\n *\n * _.chunk(['a', 'b', 'c', 'd'], 2);\n * // => [['a', 'b'], ['c', 'd']]\n *\n * _.chunk(['a', 'b', 'c', 'd'], 3);\n * // => [['a', 'b', 'c'], ['d']]\n */\n function chunk(array, size, guard) {\n if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {\n size = 1;\n } else {\n size = nativeMax(toInteger(size), 0);\n }\n var length = array == null ? 0 : array.length;\n if (!length || size < 1) {\n return [];\n }\n var index = 0,\n resIndex = 0,\n result = Array(nativeCeil(length / size));\n\n while (index < length) {\n result[resIndex++] = baseSlice(array, index, (index += size));\n }\n return result;\n }\n\n /**\n * Creates an array with all falsey values removed. The values `false`, `null`,\n * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to compact.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.compact([0, 1, false, 2, '', 3]);\n * // => [1, 2, 3]\n */\n function compact(array) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (value) {\n result[resIndex++] = value;\n }\n }\n return result;\n }\n\n /**\n * Creates a new array concatenating `array` with any additional arrays\n * and/or values.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to concatenate.\n * @param {...*} [values] The values to concatenate.\n * @returns {Array} Returns the new concatenated array.\n * @example\n *\n * var array = [1];\n * var other = _.concat(array, 2, [3], [[4]]);\n *\n * console.log(other);\n * // => [1, 2, 3, [4]]\n *\n * console.log(array);\n * // => [1]\n */\n function concat() {\n var length = arguments.length;\n if (!length) {\n return [];\n }\n var args = Array(length - 1),\n array = arguments[0],\n index = length;\n\n while (index--) {\n args[index - 1] = arguments[index];\n }\n return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));\n }\n\n /**\n * Creates an array of `array` values not included in the other given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * **Note:** Unlike `_.pullAll`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.without, _.xor\n * @example\n *\n * _.difference([2, 1], [2, 3]);\n * // => [1]\n */\n var difference = baseRest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n : [];\n });\n\n /**\n * This method is like `_.difference` except that it accepts `iteratee` which\n * is invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. The order and references of result values are\n * determined by the first array. The iteratee is invoked with one argument:\n * (value).\n *\n * **Note:** Unlike `_.pullAllBy`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\n var differenceBy = baseRest(function(array, values) {\n var iteratee = last(values);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))\n : [];\n });\n\n /**\n * This method is like `_.difference` except that it accepts `comparator`\n * which is invoked to compare elements of `array` to `values`. The order and\n * references of result values are determined by the first array. The comparator\n * is invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n *\n * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }]\n */\n var differenceWith = baseRest(function(array, values) {\n var comparator = last(values);\n if (isArrayLikeObject(comparator)) {\n comparator = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n : [];\n });\n\n /**\n * Creates a slice of `array` with `n` elements dropped from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.drop([1, 2, 3]);\n * // => [2, 3]\n *\n * _.drop([1, 2, 3], 2);\n * // => [3]\n *\n * _.drop([1, 2, 3], 5);\n * // => []\n *\n * _.drop([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\n function drop(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, n < 0 ? 0 : n, length);\n }\n\n /**\n * Creates a slice of `array` with `n` elements dropped from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.dropRight([1, 2, 3]);\n * // => [1, 2]\n *\n * _.dropRight([1, 2, 3], 2);\n * // => [1]\n *\n * _.dropRight([1, 2, 3], 5);\n * // => []\n *\n * _.dropRight([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\n function dropRight(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, 0, n < 0 ? 0 : n);\n }\n\n /**\n * Creates a slice of `array` excluding elements dropped from the end.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.dropRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropRightWhile(users, ['active', false]);\n * // => objects for ['barney']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropRightWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\n function dropRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), true, true)\n : [];\n }\n\n /**\n * Creates a slice of `array` excluding elements dropped from the beginning.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.dropWhile(users, function(o) { return !o.active; });\n * // => objects for ['pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropWhile(users, ['active', false]);\n * // => objects for ['pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\n function dropWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), true)\n : [];\n }\n\n /**\n * Fills elements of `array` with `value` from `start` up to, but not\n * including, `end`.\n *\n * **Note:** This method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.2.0\n * @category Array\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.fill(array, 'a');\n * console.log(array);\n * // => ['a', 'a', 'a']\n *\n * _.fill(Array(3), 2);\n * // => [2, 2, 2]\n *\n * _.fill([4, 6, 8, 10], '*', 1, 3);\n * // => [4, '*', '*', 10]\n */\n function fill(array, value, start, end) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n start = 0;\n end = length;\n }\n return baseFill(array, value, start, end);\n }\n\n /**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\n function findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, getIteratee(predicate, 3), index);\n }\n\n /**\n * This method is like `_.findIndex` except that it iterates over elements\n * of `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=array.length-1] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });\n * // => 2\n *\n * // The `_.matches` iteratee shorthand.\n * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n * // => 0\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findLastIndex(users, ['active', false]);\n * // => 2\n *\n * // The `_.property` iteratee shorthand.\n * _.findLastIndex(users, 'active');\n * // => 0\n */\n function findLastIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = length - 1;\n if (fromIndex !== undefined) {\n index = toInteger(fromIndex);\n index = fromIndex < 0\n ? nativeMax(length + index, 0)\n : nativeMin(index, length - 1);\n }\n return baseFindIndex(array, getIteratee(predicate, 3), index, true);\n }\n\n /**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\n function flatten(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, 1) : [];\n }\n\n /**\n * Recursively flattens `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flattenDeep([1, [2, [3, [4]], 5]]);\n * // => [1, 2, 3, 4, 5]\n */\n function flattenDeep(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, INFINITY) : [];\n }\n\n /**\n * Recursively flatten `array` up to `depth` times.\n *\n * @static\n * @memberOf _\n * @since 4.4.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @param {number} [depth=1] The maximum recursion depth.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * var array = [1, [2, [3, [4]], 5]];\n *\n * _.flattenDepth(array, 1);\n * // => [1, 2, [3, [4]], 5]\n *\n * _.flattenDepth(array, 2);\n * // => [1, 2, 3, [4], 5]\n */\n function flattenDepth(array, depth) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n depth = depth === undefined ? 1 : toInteger(depth);\n return baseFlatten(array, depth);\n }\n\n /**\n * The inverse of `_.toPairs`; this method returns an object composed\n * from key-value `pairs`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} pairs The key-value pairs.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.fromPairs([['a', 1], ['b', 2]]);\n * // => { 'a': 1, 'b': 2 }\n */\n function fromPairs(pairs) {\n var index = -1,\n length = pairs == null ? 0 : pairs.length,\n result = {};\n\n while (++index < length) {\n var pair = pairs[index];\n result[pair[0]] = pair[1];\n }\n return result;\n }\n\n /**\n * Gets the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias first\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the first element of `array`.\n * @example\n *\n * _.head([1, 2, 3]);\n * // => 1\n *\n * _.head([]);\n * // => undefined\n */\n function head(array) {\n return (array && array.length) ? array[0] : undefined;\n }\n\n /**\n * Gets the index at which the first occurrence of `value` is found in `array`\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. If `fromIndex` is negative, it's used as the\n * offset from the end of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.indexOf([1, 2, 1, 2], 2);\n * // => 1\n *\n * // Search from the `fromIndex`.\n * _.indexOf([1, 2, 1, 2], 2, 2);\n * // => 3\n */\n function indexOf(array, value, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseIndexOf(array, value, index);\n }\n\n /**\n * Gets all but the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.initial([1, 2, 3]);\n * // => [1, 2]\n */\n function initial(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseSlice(array, 0, -1) : [];\n }\n\n /**\n * Creates an array of unique values that are included in all given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersection([2, 1], [2, 3]);\n * // => [2]\n */\n var intersection = baseRest(function(arrays) {\n var mapped = arrayMap(arrays, castArrayLikeObject);\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped)\n : [];\n });\n\n /**\n * This method is like `_.intersection` except that it accepts `iteratee`\n * which is invoked for each element of each `arrays` to generate the criterion\n * by which they're compared. The order and references of result values are\n * determined by the first array. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [2.1]\n *\n * // The `_.property` iteratee shorthand.\n * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }]\n */\n var intersectionBy = baseRest(function(arrays) {\n var iteratee = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n if (iteratee === last(mapped)) {\n iteratee = undefined;\n } else {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, getIteratee(iteratee, 2))\n : [];\n });\n\n /**\n * This method is like `_.intersection` except that it accepts `comparator`\n * which is invoked to compare elements of `arrays`. The order and references\n * of result values are determined by the first array. The comparator is\n * invoked with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.intersectionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }]\n */\n var intersectionWith = baseRest(function(arrays) {\n var comparator = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n comparator = typeof comparator == 'function' ? comparator : undefined;\n if (comparator) {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, undefined, comparator)\n : [];\n });\n\n /**\n * Converts all elements in `array` into a string separated by `separator`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to convert.\n * @param {string} [separator=','] The element separator.\n * @returns {string} Returns the joined string.\n * @example\n *\n * _.join(['a', 'b', 'c'], '~');\n * // => 'a~b~c'\n */\n function join(array, separator) {\n return array == null ? '' : nativeJoin.call(array, separator);\n }\n\n /**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\n function last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n }\n\n /**\n * This method is like `_.indexOf` except that it iterates over elements of\n * `array` from right to left.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=array.length-1] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.lastIndexOf([1, 2, 1, 2], 2);\n * // => 3\n *\n * // Search from the `fromIndex`.\n * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n * // => 1\n */\n function lastIndexOf(array, value, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = length;\n if (fromIndex !== undefined) {\n index = toInteger(fromIndex);\n index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);\n }\n return value === value\n ? strictLastIndexOf(array, value, index)\n : baseFindIndex(array, baseIsNaN, index, true);\n }\n\n /**\n * Gets the element at index `n` of `array`. If `n` is negative, the nth\n * element from the end is returned.\n *\n * @static\n * @memberOf _\n * @since 4.11.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=0] The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'd'];\n *\n * _.nth(array, 1);\n * // => 'b'\n *\n * _.nth(array, -2);\n * // => 'c';\n */\n function nth(array, n) {\n return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;\n }\n\n /**\n * Removes all given values from `array` using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`\n * to remove elements from an array by predicate.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...*} [values] The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n *\n * _.pull(array, 'a', 'c');\n * console.log(array);\n * // => ['b', 'b']\n */\n var pull = baseRest(pullAll);\n\n /**\n * This method is like `_.pull` except that it accepts an array of values to remove.\n *\n * **Note:** Unlike `_.difference`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n *\n * _.pullAll(array, ['a', 'c']);\n * console.log(array);\n * // => ['b', 'b']\n */\n function pullAll(array, values) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values)\n : array;\n }\n\n /**\n * This method is like `_.pullAll` except that it accepts `iteratee` which is\n * invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. The iteratee is invoked with one argument: (value).\n *\n * **Note:** Unlike `_.differenceBy`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];\n *\n * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');\n * console.log(array);\n * // => [{ 'x': 2 }]\n */\n function pullAllBy(array, values, iteratee) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, getIteratee(iteratee, 2))\n : array;\n }\n\n /**\n * This method is like `_.pullAll` except that it accepts `comparator` which\n * is invoked to compare elements of `array` to `values`. The comparator is\n * invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.differenceWith`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];\n *\n * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);\n * console.log(array);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]\n */\n function pullAllWith(array, values, comparator) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, undefined, comparator)\n : array;\n }\n\n /**\n * Removes elements from `array` corresponding to `indexes` and returns an\n * array of removed elements.\n *\n * **Note:** Unlike `_.at`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...(number|number[])} [indexes] The indexes of elements to remove.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = ['a', 'b', 'c', 'd'];\n * var pulled = _.pullAt(array, [1, 3]);\n *\n * console.log(array);\n * // => ['a', 'c']\n *\n * console.log(pulled);\n * // => ['b', 'd']\n */\n var pullAt = flatRest(function(array, indexes) {\n var length = array == null ? 0 : array.length,\n result = baseAt(array, indexes);\n\n basePullAt(array, arrayMap(indexes, function(index) {\n return isIndex(index, length) ? +index : index;\n }).sort(compareAscending));\n\n return result;\n });\n\n /**\n * Removes all elements from `array` that `predicate` returns truthy for\n * and returns an array of the removed elements. The predicate is invoked\n * with three arguments: (value, index, array).\n *\n * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n * to pull elements from an array by value.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = [1, 2, 3, 4];\n * var evens = _.remove(array, function(n) {\n * return n % 2 == 0;\n * });\n *\n * console.log(array);\n * // => [1, 3]\n *\n * console.log(evens);\n * // => [2, 4]\n */\n function remove(array, predicate) {\n var result = [];\n if (!(array && array.length)) {\n return result;\n }\n var index = -1,\n indexes = [],\n length = array.length;\n\n predicate = getIteratee(predicate, 3);\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result.push(value);\n indexes.push(index);\n }\n }\n basePullAt(array, indexes);\n return result;\n }\n\n /**\n * Reverses `array` so that the first element becomes the last, the second\n * element becomes the second to last, and so on.\n *\n * **Note:** This method mutates `array` and is based on\n * [`Array#reverse`](https://mdn.io/Array/reverse).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.reverse(array);\n * // => [3, 2, 1]\n *\n * console.log(array);\n * // => [3, 2, 1]\n */\n function reverse(array) {\n return array == null ? array : nativeReverse.call(array);\n }\n\n /**\n * Creates a slice of `array` from `start` up to, but not including, `end`.\n *\n * **Note:** This method is used instead of\n * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are\n * returned.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\n function slice(array, start, end) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n start = 0;\n end = length;\n }\n else {\n start = start == null ? 0 : toInteger(start);\n end = end === undefined ? length : toInteger(end);\n }\n return baseSlice(array, start, end);\n }\n\n /**\n * Uses a binary search to determine the lowest index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedIndex([30, 50], 40);\n * // => 1\n */\n function sortedIndex(array, value) {\n return baseSortedIndex(array, value);\n }\n\n /**\n * This method is like `_.sortedIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * var objects = [{ 'x': 4 }, { 'x': 5 }];\n *\n * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedIndexBy(objects, { 'x': 4 }, 'x');\n * // => 0\n */\n function sortedIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));\n }\n\n /**\n * This method is like `_.indexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedIndexOf([4, 5, 5, 5, 6], 5);\n * // => 1\n */\n function sortedIndexOf(array, value) {\n var length = array == null ? 0 : array.length;\n if (length) {\n var index = baseSortedIndex(array, value);\n if (index < length && eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * This method is like `_.sortedIndex` except that it returns the highest\n * index at which `value` should be inserted into `array` in order to\n * maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedLastIndex([4, 5, 5, 5, 6], 5);\n * // => 4\n */\n function sortedLastIndex(array, value) {\n return baseSortedIndex(array, value, true);\n }\n\n /**\n * This method is like `_.sortedLastIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * var objects = [{ 'x': 4 }, { 'x': 5 }];\n *\n * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n * // => 1\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');\n * // => 1\n */\n function sortedLastIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);\n }\n\n /**\n * This method is like `_.lastIndexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);\n * // => 3\n */\n function sortedLastIndexOf(array, value) {\n var length = array == null ? 0 : array.length;\n if (length) {\n var index = baseSortedIndex(array, value, true) - 1;\n if (eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * This method is like `_.uniq` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniq([1, 1, 2]);\n * // => [1, 2]\n */\n function sortedUniq(array) {\n return (array && array.length)\n ? baseSortedUniq(array)\n : [];\n }\n\n /**\n * This method is like `_.uniqBy` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);\n * // => [1.1, 2.3]\n */\n function sortedUniqBy(array, iteratee) {\n return (array && array.length)\n ? baseSortedUniq(array, getIteratee(iteratee, 2))\n : [];\n }\n\n /**\n * Gets all but the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.tail([1, 2, 3]);\n * // => [2, 3]\n */\n function tail(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseSlice(array, 1, length) : [];\n }\n\n /**\n * Creates a slice of `array` with `n` elements taken from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.take([1, 2, 3]);\n * // => [1]\n *\n * _.take([1, 2, 3], 2);\n * // => [1, 2]\n *\n * _.take([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.take([1, 2, 3], 0);\n * // => []\n */\n function take(array, n, guard) {\n if (!(array && array.length)) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, 0, n < 0 ? 0 : n);\n }\n\n /**\n * Creates a slice of `array` with `n` elements taken from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.takeRight([1, 2, 3]);\n * // => [3]\n *\n * _.takeRight([1, 2, 3], 2);\n * // => [2, 3]\n *\n * _.takeRight([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.takeRight([1, 2, 3], 0);\n * // => []\n */\n function takeRight(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, n < 0 ? 0 : n, length);\n }\n\n /**\n * Creates a slice of `array` with elements taken from the end. Elements are\n * taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.takeRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeRightWhile(users, ['active', false]);\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeRightWhile(users, 'active');\n * // => []\n */\n function takeRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), false, true)\n : [];\n }\n\n /**\n * Creates a slice of `array` with elements taken from the beginning. Elements\n * are taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.takeWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeWhile(users, ['active', false]);\n * // => objects for ['barney', 'fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeWhile(users, 'active');\n * // => []\n */\n function takeWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3))\n : [];\n }\n\n /**\n * Creates an array of unique values, in order, from all given arrays using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.union([2], [1, 2]);\n * // => [2, 1]\n */\n var union = baseRest(function(arrays) {\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n });\n\n /**\n * This method is like `_.union` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which uniqueness is computed. Result values are chosen from the first\n * array in which the value occurs. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.unionBy([2.1], [1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\n var unionBy = baseRest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));\n });\n\n /**\n * This method is like `_.union` except that it accepts `comparator` which\n * is invoked to compare elements of `arrays`. Result values are chosen from\n * the first array in which the value occurs. The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.unionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\n var unionWith = baseRest(function(arrays) {\n var comparator = last(arrays);\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);\n });\n\n /**\n * Creates a duplicate-free version of an array, using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons, in which only the first occurrence of each element\n * is kept. The order of result values is determined by the order they occur\n * in the array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniq([2, 1, 2]);\n * // => [2, 1]\n */\n function uniq(array) {\n return (array && array.length) ? baseUniq(array) : [];\n }\n\n /**\n * This method is like `_.uniq` except that it accepts `iteratee` which is\n * invoked for each element in `array` to generate the criterion by which\n * uniqueness is computed. The order of result values is determined by the\n * order they occur in the array. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\n function uniqBy(array, iteratee) {\n return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];\n }\n\n /**\n * This method is like `_.uniq` except that it accepts `comparator` which\n * is invoked to compare elements of `array`. The order of result values is\n * determined by the order they occur in the array.The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.uniqWith(objects, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n */\n function uniqWith(array, comparator) {\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n }\n\n /**\n * This method is like `_.zip` except that it accepts an array of grouped\n * elements and creates an array regrouping the elements to their pre-zip\n * configuration.\n *\n * @static\n * @memberOf _\n * @since 1.2.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);\n * // => [['a', 1, true], ['b', 2, false]]\n *\n * _.unzip(zipped);\n * // => [['a', 'b'], [1, 2], [true, false]]\n */\n function unzip(array) {\n if (!(array && array.length)) {\n return [];\n }\n var length = 0;\n array = arrayFilter(array, function(group) {\n if (isArrayLikeObject(group)) {\n length = nativeMax(group.length, length);\n return true;\n }\n });\n return baseTimes(length, function(index) {\n return arrayMap(array, baseProperty(index));\n });\n }\n\n /**\n * This method is like `_.unzip` except that it accepts `iteratee` to specify\n * how regrouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @param {Function} [iteratee=_.identity] The function to combine\n * regrouped values.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n * // => [[1, 10, 100], [2, 20, 200]]\n *\n * _.unzipWith(zipped, _.add);\n * // => [3, 30, 300]\n */\n function unzipWith(array, iteratee) {\n if (!(array && array.length)) {\n return [];\n }\n var result = unzip(array);\n if (iteratee == null) {\n return result;\n }\n return arrayMap(result, function(group) {\n return apply(iteratee, undefined, group);\n });\n }\n\n /**\n * Creates an array excluding all given values using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.pull`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...*} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.xor\n * @example\n *\n * _.without([2, 1, 2, 3], 1, 2);\n * // => [3]\n */\n var without = baseRest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, values)\n : [];\n });\n\n /**\n * Creates an array of unique values that is the\n * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n * of the given arrays. The order of result values is determined by the order\n * they occur in the arrays.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.without\n * @example\n *\n * _.xor([2, 1], [2, 3]);\n * // => [1, 3]\n */\n var xor = baseRest(function(arrays) {\n return baseXor(arrayFilter(arrays, isArrayLikeObject));\n });\n\n /**\n * This method is like `_.xor` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which by which they're compared. The order of result values is determined\n * by the order they occur in the arrays. The iteratee is invoked with one\n * argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [1.2, 3.4]\n *\n * // The `_.property` iteratee shorthand.\n * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\n var xorBy = baseRest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));\n });\n\n /**\n * This method is like `_.xor` except that it accepts `comparator` which is\n * invoked to compare elements of `arrays`. The order of result values is\n * determined by the order they occur in the arrays. The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.xorWith(objects, others, _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\n var xorWith = baseRest(function(arrays) {\n var comparator = last(arrays);\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);\n });\n\n /**\n * Creates an array of grouped elements, the first of which contains the\n * first elements of the given arrays, the second of which contains the\n * second elements of the given arrays, and so on.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zip(['a', 'b'], [1, 2], [true, false]);\n * // => [['a', 1, true], ['b', 2, false]]\n */\n var zip = baseRest(unzip);\n\n /**\n * This method is like `_.fromPairs` except that it accepts two arrays,\n * one of property identifiers and one of corresponding values.\n *\n * @static\n * @memberOf _\n * @since 0.4.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObject(['a', 'b'], [1, 2]);\n * // => { 'a': 1, 'b': 2 }\n */\n function zipObject(props, values) {\n return baseZipObject(props || [], values || [], assignValue);\n }\n\n /**\n * This method is like `_.zipObject` except that it supports property paths.\n *\n * @static\n * @memberOf _\n * @since 4.1.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);\n * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }\n */\n function zipObjectDeep(props, values) {\n return baseZipObject(props || [], values || [], baseSet);\n }\n\n /**\n * This method is like `_.zip` except that it accepts `iteratee` to specify\n * how grouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @param {Function} [iteratee=_.identity] The function to combine\n * grouped values.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {\n * return a + b + c;\n * });\n * // => [111, 222]\n */\n var zipWith = baseRest(function(arrays) {\n var length = arrays.length,\n iteratee = length > 1 ? arrays[length - 1] : undefined;\n\n iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;\n return unzipWith(arrays, iteratee);\n });\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a `lodash` wrapper instance that wraps `value` with explicit method\n * chain sequences enabled. The result of such sequences must be unwrapped\n * with `_#value`.\n *\n * @static\n * @memberOf _\n * @since 1.3.0\n * @category Seq\n * @param {*} value The value to wrap.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'pebbles', 'age': 1 }\n * ];\n *\n * var youngest = _\n * .chain(users)\n * .sortBy('age')\n * .map(function(o) {\n * return o.user + ' is ' + o.age;\n * })\n * .head()\n * .value();\n * // => 'pebbles is 1'\n */\n function chain(value) {\n var result = lodash(value);\n result.__chain__ = true;\n return result;\n }\n\n /**\n * This method invokes `interceptor` and returns `value`. The interceptor\n * is invoked with one argument; (value). The purpose of this method is to\n * \"tap into\" a method chain sequence in order to modify intermediate results.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @param {*} value The value to provide to `interceptor`.\n * @param {Function} interceptor The function to invoke.\n * @returns {*} Returns `value`.\n * @example\n *\n * _([1, 2, 3])\n * .tap(function(array) {\n * // Mutate input array.\n * array.pop();\n * })\n * .reverse()\n * .value();\n * // => [2, 1]\n */\n function tap(value, interceptor) {\n interceptor(value);\n return value;\n }\n\n /**\n * This method is like `_.tap` except that it returns the result of `interceptor`.\n * The purpose of this method is to \"pass thru\" values replacing intermediate\n * results in a method chain sequence.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Seq\n * @param {*} value The value to provide to `interceptor`.\n * @param {Function} interceptor The function to invoke.\n * @returns {*} Returns the result of `interceptor`.\n * @example\n *\n * _(' abc ')\n * .chain()\n * .trim()\n * .thru(function(value) {\n * return [value];\n * })\n * .value();\n * // => ['abc']\n */\n function thru(value, interceptor) {\n return interceptor(value);\n }\n\n /**\n * This method is the wrapper version of `_.at`.\n *\n * @name at\n * @memberOf _\n * @since 1.0.0\n * @category Seq\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n *\n * _(object).at(['a[0].b.c', 'a[1]']).value();\n * // => [3, 4]\n */\n var wrapperAt = flatRest(function(paths) {\n var length = paths.length,\n start = length ? paths[0] : 0,\n value = this.__wrapped__,\n interceptor = function(object) { return baseAt(object, paths); };\n\n if (length > 1 || this.__actions__.length ||\n !(value instanceof LazyWrapper) || !isIndex(start)) {\n return this.thru(interceptor);\n }\n value = value.slice(start, +start + (length ? 1 : 0));\n value.__actions__.push({\n 'func': thru,\n 'args': [interceptor],\n 'thisArg': undefined\n });\n return new LodashWrapper(value, this.__chain__).thru(function(array) {\n if (length && !array.length) {\n array.push(undefined);\n }\n return array;\n });\n });\n\n /**\n * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.\n *\n * @name chain\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 }\n * ];\n *\n * // A sequence without explicit chaining.\n * _(users).head();\n * // => { 'user': 'barney', 'age': 36 }\n *\n * // A sequence with explicit chaining.\n * _(users)\n * .chain()\n * .head()\n * .pick('user')\n * .value();\n * // => { 'user': 'barney' }\n */\n function wrapperChain() {\n return chain(this);\n }\n\n /**\n * Executes the chain sequence and returns the wrapped result.\n *\n * @name commit\n * @memberOf _\n * @since 3.2.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var array = [1, 2];\n * var wrapped = _(array).push(3);\n *\n * console.log(array);\n * // => [1, 2]\n *\n * wrapped = wrapped.commit();\n * console.log(array);\n * // => [1, 2, 3]\n *\n * wrapped.last();\n * // => 3\n *\n * console.log(array);\n * // => [1, 2, 3]\n */\n function wrapperCommit() {\n return new LodashWrapper(this.value(), this.__chain__);\n }\n\n /**\n * Gets the next value on a wrapped object following the\n * [iterator protocol](https://mdn.io/iteration_protocols#iterator).\n *\n * @name next\n * @memberOf _\n * @since 4.0.0\n * @category Seq\n * @returns {Object} Returns the next iterator value.\n * @example\n *\n * var wrapped = _([1, 2]);\n *\n * wrapped.next();\n * // => { 'done': false, 'value': 1 }\n *\n * wrapped.next();\n * // => { 'done': false, 'value': 2 }\n *\n * wrapped.next();\n * // => { 'done': true, 'value': undefined }\n */\n function wrapperNext() {\n if (this.__values__ === undefined) {\n this.__values__ = toArray(this.value());\n }\n var done = this.__index__ >= this.__values__.length,\n value = done ? undefined : this.__values__[this.__index__++];\n\n return { 'done': done, 'value': value };\n }\n\n /**\n * Enables the wrapper to be iterable.\n *\n * @name Symbol.iterator\n * @memberOf _\n * @since 4.0.0\n * @category Seq\n * @returns {Object} Returns the wrapper object.\n * @example\n *\n * var wrapped = _([1, 2]);\n *\n * wrapped[Symbol.iterator]() === wrapped;\n * // => true\n *\n * Array.from(wrapped);\n * // => [1, 2]\n */\n function wrapperToIterator() {\n return this;\n }\n\n /**\n * Creates a clone of the chain sequence planting `value` as the wrapped value.\n *\n * @name plant\n * @memberOf _\n * @since 3.2.0\n * @category Seq\n * @param {*} value The value to plant.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var wrapped = _([1, 2]).map(square);\n * var other = wrapped.plant([3, 4]);\n *\n * other.value();\n * // => [9, 16]\n *\n * wrapped.value();\n * // => [1, 4]\n */\n function wrapperPlant(value) {\n var result,\n parent = this;\n\n while (parent instanceof baseLodash) {\n var clone = wrapperClone(parent);\n clone.__index__ = 0;\n clone.__values__ = undefined;\n if (result) {\n previous.__wrapped__ = clone;\n } else {\n result = clone;\n }\n var previous = clone;\n parent = parent.__wrapped__;\n }\n previous.__wrapped__ = value;\n return result;\n }\n\n /**\n * This method is the wrapper version of `_.reverse`.\n *\n * **Note:** This method mutates the wrapped array.\n *\n * @name reverse\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _(array).reverse().value()\n * // => [3, 2, 1]\n *\n * console.log(array);\n * // => [3, 2, 1]\n */\n function wrapperReverse() {\n var value = this.__wrapped__;\n if (value instanceof LazyWrapper) {\n var wrapped = value;\n if (this.__actions__.length) {\n wrapped = new LazyWrapper(this);\n }\n wrapped = wrapped.reverse();\n wrapped.__actions__.push({\n 'func': thru,\n 'args': [reverse],\n 'thisArg': undefined\n });\n return new LodashWrapper(wrapped, this.__chain__);\n }\n return this.thru(reverse);\n }\n\n /**\n * Executes the chain sequence to resolve the unwrapped value.\n *\n * @name value\n * @memberOf _\n * @since 0.1.0\n * @alias toJSON, valueOf\n * @category Seq\n * @returns {*} Returns the resolved unwrapped value.\n * @example\n *\n * _([1, 2, 3]).value();\n * // => [1, 2, 3]\n */\n function wrapperValue() {\n return baseWrapperValue(this.__wrapped__, this.__actions__);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The corresponding value of\n * each key is the number of times the key was returned by `iteratee`. The\n * iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * _.countBy([6.1, 4.2, 6.3], Math.floor);\n * // => { '4': 1, '6': 2 }\n *\n * // The `_.property` iteratee shorthand.\n * _.countBy(['one', 'two', 'three'], 'length');\n * // => { '3': 2, '5': 1 }\n */\n var countBy = createAggregator(function(result, value, key) {\n if (hasOwnProperty.call(result, key)) {\n ++result[key];\n } else {\n baseAssignValue(result, key, 1);\n }\n });\n\n /**\n * Checks if `predicate` returns truthy for **all** elements of `collection`.\n * Iteration is stopped once `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * **Note:** This method returns `true` for\n * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n * elements of empty collections.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`.\n * @example\n *\n * _.every([true, 1, null, 'yes'], Boolean);\n * // => false\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.every(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.every(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.every(users, 'active');\n * // => false\n */\n function every(collection, predicate, guard) {\n var func = isArray(collection) ? arrayEvery : baseEvery;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Iterates over elements of `collection`, returning an array of all elements\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * **Note:** Unlike `_.remove`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.reject\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * _.filter(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.filter(users, { 'age': 36, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.filter(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.filter(users, 'active');\n * // => objects for ['barney']\n */\n function filter(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\n var find = createFind(findIndex);\n\n /**\n * This method is like `_.find` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=collection.length-1] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * _.findLast([1, 2, 3, 4], function(n) {\n * return n % 2 == 1;\n * });\n * // => 3\n */\n var findLast = createFind(findLastIndex);\n\n /**\n * Creates a flattened array of values by running each element in `collection`\n * thru `iteratee` and flattening the mapped results. The iteratee is invoked\n * with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [n, n];\n * }\n *\n * _.flatMap([1, 2], duplicate);\n * // => [1, 1, 2, 2]\n */\n function flatMap(collection, iteratee) {\n return baseFlatten(map(collection, iteratee), 1);\n }\n\n /**\n * This method is like `_.flatMap` except that it recursively flattens the\n * mapped results.\n *\n * @static\n * @memberOf _\n * @since 4.7.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [[[n, n]]];\n * }\n *\n * _.flatMapDeep([1, 2], duplicate);\n * // => [1, 1, 2, 2]\n */\n function flatMapDeep(collection, iteratee) {\n return baseFlatten(map(collection, iteratee), INFINITY);\n }\n\n /**\n * This method is like `_.flatMap` except that it recursively flattens the\n * mapped results up to `depth` times.\n *\n * @static\n * @memberOf _\n * @since 4.7.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {number} [depth=1] The maximum recursion depth.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [[[n, n]]];\n * }\n *\n * _.flatMapDepth([1, 2], duplicate, 2);\n * // => [[1, 1], [2, 2]]\n */\n function flatMapDepth(collection, iteratee, depth) {\n depth = depth === undefined ? 1 : toInteger(depth);\n return baseFlatten(map(collection, iteratee), depth);\n }\n\n /**\n * Iterates over elements of `collection` and invokes `iteratee` for each element.\n * The iteratee is invoked with three arguments: (value, index|key, collection).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n * property are iterated like arrays. To avoid this behavior use `_.forIn`\n * or `_.forOwn` for object iteration.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias each\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEachRight\n * @example\n *\n * _.forEach([1, 2], function(value) {\n * console.log(value);\n * });\n * // => Logs `1` then `2`.\n *\n * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\n function forEach(collection, iteratee) {\n var func = isArray(collection) ? arrayEach : baseEach;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.forEach` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @alias eachRight\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEach\n * @example\n *\n * _.forEachRight([1, 2], function(value) {\n * console.log(value);\n * });\n * // => Logs `2` then `1`.\n */\n function forEachRight(collection, iteratee) {\n var func = isArray(collection) ? arrayEachRight : baseEachRight;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The order of grouped values\n * is determined by the order they occur in `collection`. The corresponding\n * value of each key is an array of elements responsible for generating the\n * key. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * _.groupBy([6.1, 4.2, 6.3], Math.floor);\n * // => { '4': [4.2], '6': [6.1, 6.3] }\n *\n * // The `_.property` iteratee shorthand.\n * _.groupBy(['one', 'two', 'three'], 'length');\n * // => { '3': ['one', 'two'], '5': ['three'] }\n */\n var groupBy = createAggregator(function(result, value, key) {\n if (hasOwnProperty.call(result, key)) {\n result[key].push(value);\n } else {\n baseAssignValue(result, key, [value]);\n }\n });\n\n /**\n * Checks if `value` is in `collection`. If `collection` is a string, it's\n * checked for a substring of `value`, otherwise\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * is used for equality comparisons. If `fromIndex` is negative, it's used as\n * the offset from the end of `collection`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n * @returns {boolean} Returns `true` if `value` is found, else `false`.\n * @example\n *\n * _.includes([1, 2, 3], 1);\n * // => true\n *\n * _.includes([1, 2, 3], 1, 2);\n * // => false\n *\n * _.includes({ 'a': 1, 'b': 2 }, 1);\n * // => true\n *\n * _.includes('abcd', 'bc');\n * // => true\n */\n function includes(collection, value, fromIndex, guard) {\n collection = isArrayLike(collection) ? collection : values(collection);\n fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;\n\n var length = collection.length;\n if (fromIndex < 0) {\n fromIndex = nativeMax(length + fromIndex, 0);\n }\n return isString(collection)\n ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)\n : (!!length && baseIndexOf(collection, value, fromIndex) > -1);\n }\n\n /**\n * Invokes the method at `path` of each element in `collection`, returning\n * an array of the results of each invoked method. Any additional arguments\n * are provided to each invoked method. If `path` is a function, it's invoked\n * for, and `this` bound to, each element in `collection`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Array|Function|string} path The path of the method to invoke or\n * the function invoked per iteration.\n * @param {...*} [args] The arguments to invoke each method with.\n * @returns {Array} Returns the array of results.\n * @example\n *\n * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');\n * // => [[1, 5, 7], [1, 2, 3]]\n *\n * _.invokeMap([123, 456], String.prototype.split, '');\n * // => [['1', '2', '3'], ['4', '5', '6']]\n */\n var invokeMap = baseRest(function(collection, path, args) {\n var index = -1,\n isFunc = typeof path == 'function',\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value) {\n result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);\n });\n return result;\n });\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The corresponding value of\n * each key is the last element responsible for generating the key. The\n * iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * var array = [\n * { 'dir': 'left', 'code': 97 },\n * { 'dir': 'right', 'code': 100 }\n * ];\n *\n * _.keyBy(array, function(o) {\n * return String.fromCharCode(o.code);\n * });\n * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n *\n * _.keyBy(array, 'dir');\n * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n */\n var keyBy = createAggregator(function(result, value, key) {\n baseAssignValue(result, key, value);\n });\n\n /**\n * Creates an array of values by running each element in `collection` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n *\n * The guarded methods are:\n * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * _.map([4, 8], square);\n * // => [16, 64]\n *\n * _.map({ 'a': 4, 'b': 8 }, square);\n * // => [16, 64] (iteration order is not guaranteed)\n *\n * var users = [\n * { 'user': 'barney' },\n * { 'user': 'fred' }\n * ];\n *\n * // The `_.property` iteratee shorthand.\n * _.map(users, 'user');\n * // => ['barney', 'fred']\n */\n function map(collection, iteratee) {\n var func = isArray(collection) ? arrayMap : baseMap;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.sortBy` except that it allows specifying the sort\n * orders of the iteratees to sort by. If `orders` is unspecified, all values\n * are sorted in ascending order. Otherwise, specify an order of \"desc\" for\n * descending or \"asc\" for ascending sort order of corresponding values.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @param {string[]} [orders] The sort orders of `iteratees`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 34 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'barney', 'age': 36 }\n * ];\n *\n * // Sort by `user` in ascending order and by `age` in descending order.\n * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n */\n function orderBy(collection, iteratees, orders, guard) {\n if (collection == null) {\n return [];\n }\n if (!isArray(iteratees)) {\n iteratees = iteratees == null ? [] : [iteratees];\n }\n orders = guard ? undefined : orders;\n if (!isArray(orders)) {\n orders = orders == null ? [] : [orders];\n }\n return baseOrderBy(collection, iteratees, orders);\n }\n\n /**\n * Creates an array of elements split into two groups, the first of which\n * contains elements `predicate` returns truthy for, the second of which\n * contains elements `predicate` returns falsey for. The predicate is\n * invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the array of grouped elements.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': true },\n * { 'user': 'pebbles', 'age': 1, 'active': false }\n * ];\n *\n * _.partition(users, function(o) { return o.active; });\n * // => objects for [['fred'], ['barney', 'pebbles']]\n *\n * // The `_.matches` iteratee shorthand.\n * _.partition(users, { 'age': 1, 'active': false });\n * // => objects for [['pebbles'], ['barney', 'fred']]\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.partition(users, ['active', false]);\n * // => objects for [['barney', 'pebbles'], ['fred']]\n *\n * // The `_.property` iteratee shorthand.\n * _.partition(users, 'active');\n * // => objects for [['fred'], ['barney', 'pebbles']]\n */\n var partition = createAggregator(function(result, value, key) {\n result[key ? 0 : 1].push(value);\n }, function() { return [[], []]; });\n\n /**\n * Reduces `collection` to a value which is the accumulated result of running\n * each element in `collection` thru `iteratee`, where each successive\n * invocation is supplied the return value of the previous. If `accumulator`\n * is not given, the first element of `collection` is used as the initial\n * value. The iteratee is invoked with four arguments:\n * (accumulator, value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.reduce`, `_.reduceRight`, and `_.transform`.\n *\n * The guarded methods are:\n * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n * and `sortBy`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduceRight\n * @example\n *\n * _.reduce([1, 2], function(sum, n) {\n * return sum + n;\n * }, 0);\n * // => 3\n *\n * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n * (result[value] || (result[value] = [])).push(key);\n * return result;\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n */\n function reduce(collection, iteratee, accumulator) {\n var func = isArray(collection) ? arrayReduce : baseReduce,\n initAccum = arguments.length < 3;\n\n return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n }\n\n /**\n * This method is like `_.reduce` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduce\n * @example\n *\n * var array = [[0, 1], [2, 3], [4, 5]];\n *\n * _.reduceRight(array, function(flattened, other) {\n * return flattened.concat(other);\n * }, []);\n * // => [4, 5, 2, 3, 0, 1]\n */\n function reduceRight(collection, iteratee, accumulator) {\n var func = isArray(collection) ? arrayReduceRight : baseReduce,\n initAccum = arguments.length < 3;\n\n return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);\n }\n\n /**\n * The opposite of `_.filter`; this method returns the elements of `collection`\n * that `predicate` does **not** return truthy for.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.filter\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': true }\n * ];\n *\n * _.reject(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.reject(users, { 'age': 40, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.reject(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.reject(users, 'active');\n * // => objects for ['barney']\n */\n function reject(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, negate(getIteratee(predicate, 3)));\n }\n\n /**\n * Gets a random element from `collection`.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to sample.\n * @returns {*} Returns the random element.\n * @example\n *\n * _.sample([1, 2, 3, 4]);\n * // => 2\n */\n function sample(collection) {\n var func = isArray(collection) ? arraySample : baseSample;\n return func(collection);\n }\n\n /**\n * Gets `n` random elements at unique keys from `collection` up to the\n * size of `collection`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to sample.\n * @param {number} [n=1] The number of elements to sample.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the random elements.\n * @example\n *\n * _.sampleSize([1, 2, 3], 2);\n * // => [3, 1]\n *\n * _.sampleSize([1, 2, 3], 4);\n * // => [2, 3, 1]\n */\n function sampleSize(collection, n, guard) {\n if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {\n n = 1;\n } else {\n n = toInteger(n);\n }\n var func = isArray(collection) ? arraySampleSize : baseSampleSize;\n return func(collection, n);\n }\n\n /**\n * Creates an array of shuffled values, using a version of the\n * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to shuffle.\n * @returns {Array} Returns the new shuffled array.\n * @example\n *\n * _.shuffle([1, 2, 3, 4]);\n * // => [4, 1, 3, 2]\n */\n function shuffle(collection) {\n var func = isArray(collection) ? arrayShuffle : baseShuffle;\n return func(collection);\n }\n\n /**\n * Gets the size of `collection` by returning its length for array-like\n * values or the number of own enumerable string keyed properties for objects.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @returns {number} Returns the collection size.\n * @example\n *\n * _.size([1, 2, 3]);\n * // => 3\n *\n * _.size({ 'a': 1, 'b': 2 });\n * // => 2\n *\n * _.size('pebbles');\n * // => 7\n */\n function size(collection) {\n if (collection == null) {\n return 0;\n }\n if (isArrayLike(collection)) {\n return isString(collection) ? stringSize(collection) : collection.length;\n }\n var tag = getTag(collection);\n if (tag == mapTag || tag == setTag) {\n return collection.size;\n }\n return baseKeys(collection).length;\n }\n\n /**\n * Checks if `predicate` returns truthy for **any** element of `collection`.\n * Iteration is stopped once `predicate` returns truthy. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n * @example\n *\n * _.some([null, 0, 'yes', false], Boolean);\n * // => true\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.some(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.some(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.some(users, 'active');\n * // => true\n */\n function some(collection, predicate, guard) {\n var func = isArray(collection) ? arraySome : baseSome;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Creates an array of elements, sorted in ascending order by the results of\n * running each element in a collection thru each iteratee. This method\n * performs a stable sort, that is, it preserves the original sort order of\n * equal elements. The iteratees are invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {...(Function|Function[])} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'barney', 'age': 34 }\n * ];\n *\n * _.sortBy(users, [function(o) { return o.user; }]);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n *\n * _.sortBy(users, ['user', 'age']);\n * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]\n */\n var sortBy = baseRest(function(collection, iteratees) {\n if (collection == null) {\n return [];\n }\n var length = iteratees.length;\n if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n iteratees = [];\n } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n iteratees = [iteratees[0]];\n }\n return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n });\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\n var now = ctxNow || function() {\n return root.Date.now();\n };\n\n /*------------------------------------------------------------------------*/\n\n /**\n * The opposite of `_.before`; this method creates a function that invokes\n * `func` once it's called `n` or more times.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {number} n The number of calls before `func` is invoked.\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * var saves = ['profile', 'settings'];\n *\n * var done = _.after(saves.length, function() {\n * console.log('done saving!');\n * });\n *\n * _.forEach(saves, function(type) {\n * asyncSave({ 'type': type, 'complete': done });\n * });\n * // => Logs 'done saving!' after the two async saves have completed.\n */\n function after(n, func) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n n = toInteger(n);\n return function() {\n if (--n < 1) {\n return func.apply(this, arguments);\n }\n };\n }\n\n /**\n * Creates a function that invokes `func`, with up to `n` arguments,\n * ignoring any additional arguments.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to cap arguments for.\n * @param {number} [n=func.length] The arity cap.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new capped function.\n * @example\n *\n * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n * // => [6, 8, 10]\n */\n function ary(func, n, guard) {\n n = guard ? undefined : n;\n n = (func && n == null) ? func.length : n;\n return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);\n }\n\n /**\n * Creates a function that invokes `func`, with the `this` binding and arguments\n * of the created function, while it's called less than `n` times. Subsequent\n * calls to the created function return the result of the last `func` invocation.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {number} n The number of calls at which `func` is no longer invoked.\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * jQuery(element).on('click', _.before(5, addContactToList));\n * // => Allows adding up to 4 contacts to the list.\n */\n function before(n, func) {\n var result;\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n n = toInteger(n);\n return function() {\n if (--n > 0) {\n result = func.apply(this, arguments);\n }\n if (n <= 1) {\n func = undefined;\n }\n return result;\n };\n }\n\n /**\n * Creates a function that invokes `func` with the `this` binding of `thisArg`\n * and `partials` prepended to the arguments it receives.\n *\n * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\n * may be used as a placeholder for partially applied arguments.\n *\n * **Note:** Unlike native `Function#bind`, this method doesn't set the \"length\"\n * property of bound functions.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to bind.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new bound function.\n * @example\n *\n * function greet(greeting, punctuation) {\n * return greeting + ' ' + this.user + punctuation;\n * }\n *\n * var object = { 'user': 'fred' };\n *\n * var bound = _.bind(greet, object, 'hi');\n * bound('!');\n * // => 'hi fred!'\n *\n * // Bound with placeholders.\n * var bound = _.bind(greet, object, _, '!');\n * bound('hi');\n * // => 'hi fred!'\n */\n var bind = baseRest(function(func, thisArg, partials) {\n var bitmask = WRAP_BIND_FLAG;\n if (partials.length) {\n var holders = replaceHolders(partials, getHolder(bind));\n bitmask |= WRAP_PARTIAL_FLAG;\n }\n return createWrap(func, bitmask, thisArg, partials, holders);\n });\n\n /**\n * Creates a function that invokes the method at `object[key]` with `partials`\n * prepended to the arguments it receives.\n *\n * This method differs from `_.bind` by allowing bound functions to reference\n * methods that may be redefined or don't yet exist. See\n * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)\n * for more details.\n *\n * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Function\n * @param {Object} object The object to invoke the method on.\n * @param {string} key The key of the method.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new bound function.\n * @example\n *\n * var object = {\n * 'user': 'fred',\n * 'greet': function(greeting, punctuation) {\n * return greeting + ' ' + this.user + punctuation;\n * }\n * };\n *\n * var bound = _.bindKey(object, 'greet', 'hi');\n * bound('!');\n * // => 'hi fred!'\n *\n * object.greet = function(greeting, punctuation) {\n * return greeting + 'ya ' + this.user + punctuation;\n * };\n *\n * bound('!');\n * // => 'hiya fred!'\n *\n * // Bound with placeholders.\n * var bound = _.bindKey(object, 'greet', _, '!');\n * bound('hi');\n * // => 'hiya fred!'\n */\n var bindKey = baseRest(function(object, key, partials) {\n var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;\n if (partials.length) {\n var holders = replaceHolders(partials, getHolder(bindKey));\n bitmask |= WRAP_PARTIAL_FLAG;\n }\n return createWrap(key, bitmask, object, partials, holders);\n });\n\n /**\n * Creates a function that accepts arguments of `func` and either invokes\n * `func` returning its result, if at least `arity` number of arguments have\n * been provided, or returns a function that accepts the remaining `func`\n * arguments, and so on. The arity of `func` may be specified if `func.length`\n * is not sufficient.\n *\n * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n * may be used as a placeholder for provided arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of curried functions.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Function\n * @param {Function} func The function to curry.\n * @param {number} [arity=func.length] The arity of `func`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new curried function.\n * @example\n *\n * var abc = function(a, b, c) {\n * return [a, b, c];\n * };\n *\n * var curried = _.curry(abc);\n *\n * curried(1)(2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2, 3);\n * // => [1, 2, 3]\n *\n * // Curried with placeholders.\n * curried(1)(_, 3)(2);\n * // => [1, 2, 3]\n */\n function curry(func, arity, guard) {\n arity = guard ? undefined : arity;\n var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n result.placeholder = curry.placeholder;\n return result;\n }\n\n /**\n * This method is like `_.curry` except that arguments are applied to `func`\n * in the manner of `_.partialRight` instead of `_.partial`.\n *\n * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for provided arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of curried functions.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to curry.\n * @param {number} [arity=func.length] The arity of `func`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new curried function.\n * @example\n *\n * var abc = function(a, b, c) {\n * return [a, b, c];\n * };\n *\n * var curried = _.curryRight(abc);\n *\n * curried(3)(2)(1);\n * // => [1, 2, 3]\n *\n * curried(2, 3)(1);\n * // => [1, 2, 3]\n *\n * curried(1, 2, 3);\n * // => [1, 2, 3]\n *\n * // Curried with placeholders.\n * curried(3)(1, _)(2);\n * // => [1, 2, 3]\n */\n function curryRight(func, arity, guard) {\n arity = guard ? undefined : arity;\n var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n result.placeholder = curryRight.placeholder;\n return result;\n }\n\n /**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\n function debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n }\n\n /**\n * Defers invoking the `func` until the current call stack has cleared. Any\n * additional arguments are provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to defer.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.defer(function(text) {\n * console.log(text);\n * }, 'deferred');\n * // => Logs 'deferred' after one millisecond.\n */\n var defer = baseRest(function(func, args) {\n return baseDelay(func, 1, args);\n });\n\n /**\n * Invokes `func` after `wait` milliseconds. Any additional arguments are\n * provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.delay(function(text) {\n * console.log(text);\n * }, 1000, 'later');\n * // => Logs 'later' after one second.\n */\n var delay = baseRest(function(func, wait, args) {\n return baseDelay(func, toNumber(wait) || 0, args);\n });\n\n /**\n * Creates a function that invokes `func` with arguments reversed.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to flip arguments for.\n * @returns {Function} Returns the new flipped function.\n * @example\n *\n * var flipped = _.flip(function() {\n * return _.toArray(arguments);\n * });\n *\n * flipped('a', 'b', 'c', 'd');\n * // => ['d', 'c', 'b', 'a']\n */\n function flip(func) {\n return createWrap(func, WRAP_FLIP_FLAG);\n }\n\n /**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\n function memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n }\n\n // Expose `MapCache`.\n memoize.Cache = MapCache;\n\n /**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\n function negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n }\n\n /**\n * Creates a function that is restricted to invoking `func` once. Repeat calls\n * to the function return the value of the first invocation. The `func` is\n * invoked with the `this` binding and arguments of the created function.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * var initialize = _.once(createApplication);\n * initialize();\n * initialize();\n * // => `createApplication` is invoked once\n */\n function once(func) {\n return before(2, func);\n }\n\n /**\n * Creates a function that invokes `func` with its arguments transformed.\n *\n * @static\n * @since 4.0.0\n * @memberOf _\n * @category Function\n * @param {Function} func The function to wrap.\n * @param {...(Function|Function[])} [transforms=[_.identity]]\n * The argument transforms.\n * @returns {Function} Returns the new function.\n * @example\n *\n * function doubled(n) {\n * return n * 2;\n * }\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var func = _.overArgs(function(x, y) {\n * return [x, y];\n * }, [square, doubled]);\n *\n * func(9, 3);\n * // => [81, 6]\n *\n * func(10, 5);\n * // => [100, 10]\n */\n var overArgs = castRest(function(func, transforms) {\n transforms = (transforms.length == 1 && isArray(transforms[0]))\n ? arrayMap(transforms[0], baseUnary(getIteratee()))\n : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));\n\n var funcsLength = transforms.length;\n return baseRest(function(args) {\n var index = -1,\n length = nativeMin(args.length, funcsLength);\n\n while (++index < length) {\n args[index] = transforms[index].call(this, args[index]);\n }\n return apply(func, this, args);\n });\n });\n\n /**\n * Creates a function that invokes `func` with `partials` prepended to the\n * arguments it receives. This method is like `_.bind` except it does **not**\n * alter the `this` binding.\n *\n * The `_.partial.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of partially\n * applied functions.\n *\n * @static\n * @memberOf _\n * @since 0.2.0\n * @category Function\n * @param {Function} func The function to partially apply arguments to.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new partially applied function.\n * @example\n *\n * function greet(greeting, name) {\n * return greeting + ' ' + name;\n * }\n *\n * var sayHelloTo = _.partial(greet, 'hello');\n * sayHelloTo('fred');\n * // => 'hello fred'\n *\n * // Partially applied with placeholders.\n * var greetFred = _.partial(greet, _, 'fred');\n * greetFred('hi');\n * // => 'hi fred'\n */\n var partial = baseRest(function(func, partials) {\n var holders = replaceHolders(partials, getHolder(partial));\n return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);\n });\n\n /**\n * This method is like `_.partial` except that partially applied arguments\n * are appended to the arguments it receives.\n *\n * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of partially\n * applied functions.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Function\n * @param {Function} func The function to partially apply arguments to.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new partially applied function.\n * @example\n *\n * function greet(greeting, name) {\n * return greeting + ' ' + name;\n * }\n *\n * var greetFred = _.partialRight(greet, 'fred');\n * greetFred('hi');\n * // => 'hi fred'\n *\n * // Partially applied with placeholders.\n * var sayHelloTo = _.partialRight(greet, 'hello', _);\n * sayHelloTo('fred');\n * // => 'hello fred'\n */\n var partialRight = baseRest(function(func, partials) {\n var holders = replaceHolders(partials, getHolder(partialRight));\n return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);\n });\n\n /**\n * Creates a function that invokes `func` with arguments arranged according\n * to the specified `indexes` where the argument value at the first index is\n * provided as the first argument, the argument value at the second index is\n * provided as the second argument, and so on.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to rearrange arguments for.\n * @param {...(number|number[])} indexes The arranged argument indexes.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var rearged = _.rearg(function(a, b, c) {\n * return [a, b, c];\n * }, [2, 0, 1]);\n *\n * rearged('b', 'c', 'a')\n * // => ['a', 'b', 'c']\n */\n var rearg = flatRest(function(func, indexes) {\n return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);\n });\n\n /**\n * Creates a function that invokes `func` with the `this` binding of the\n * created function and arguments from `start` and beyond provided as\n * an array.\n *\n * **Note:** This method is based on the\n * [rest parameter](https://mdn.io/rest_parameters).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.rest(function(what, names) {\n * return what + ' ' + _.initial(names).join(', ') +\n * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n * });\n *\n * say('hello', 'fred', 'barney', 'pebbles');\n * // => 'hello fred, barney, & pebbles'\n */\n function rest(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = start === undefined ? start : toInteger(start);\n return baseRest(func, start);\n }\n\n /**\n * Creates a function that invokes `func` with the `this` binding of the\n * create function and an array of arguments much like\n * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).\n *\n * **Note:** This method is based on the\n * [spread operator](https://mdn.io/spread_operator).\n *\n * @static\n * @memberOf _\n * @since 3.2.0\n * @category Function\n * @param {Function} func The function to spread arguments over.\n * @param {number} [start=0] The start position of the spread.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.spread(function(who, what) {\n * return who + ' says ' + what;\n * });\n *\n * say(['fred', 'hello']);\n * // => 'fred says hello'\n *\n * var numbers = Promise.all([\n * Promise.resolve(40),\n * Promise.resolve(36)\n * ]);\n *\n * numbers.then(_.spread(function(x, y) {\n * return x + y;\n * }));\n * // => a Promise of 76\n */\n function spread(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = start == null ? 0 : nativeMax(toInteger(start), 0);\n return baseRest(function(args) {\n var array = args[start],\n otherArgs = castSlice(args, 0, start);\n\n if (array) {\n arrayPush(otherArgs, array);\n }\n return apply(func, this, otherArgs);\n });\n }\n\n /**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide `options` to indicate whether `func`\n * should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n * Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\n function throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n }\n\n /**\n * Creates a function that accepts up to one argument, ignoring any\n * additional arguments.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n * @example\n *\n * _.map(['6', '8', '10'], _.unary(parseInt));\n * // => [6, 8, 10]\n */\n function unary(func) {\n return ary(func, 1);\n }\n\n /**\n * Creates a function that provides `value` to `wrapper` as its first\n * argument. Any additional arguments provided to the function are appended\n * to those provided to the `wrapper`. The wrapper is invoked with the `this`\n * binding of the created function.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {*} value The value to wrap.\n * @param {Function} [wrapper=identity] The wrapper function.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var p = _.wrap(_.escape, function(func, text) {\n * return '

' + func(text) + '

';\n * });\n *\n * p('fred, barney, & pebbles');\n * // => '

fred, barney, & pebbles

'\n */\n function wrap(value, wrapper) {\n return partial(castFunction(wrapper), value);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Casts `value` as an array if it's not one.\n *\n * @static\n * @memberOf _\n * @since 4.4.0\n * @category Lang\n * @param {*} value The value to inspect.\n * @returns {Array} Returns the cast array.\n * @example\n *\n * _.castArray(1);\n * // => [1]\n *\n * _.castArray({ 'a': 1 });\n * // => [{ 'a': 1 }]\n *\n * _.castArray('abc');\n * // => ['abc']\n *\n * _.castArray(null);\n * // => [null]\n *\n * _.castArray(undefined);\n * // => [undefined]\n *\n * _.castArray();\n * // => []\n *\n * var array = [1, 2, 3];\n * console.log(_.castArray(array) === array);\n * // => true\n */\n function castArray() {\n if (!arguments.length) {\n return [];\n }\n var value = arguments[0];\n return isArray(value) ? value : [value];\n }\n\n /**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\n function clone(value) {\n return baseClone(value, CLONE_SYMBOLS_FLAG);\n }\n\n /**\n * This method is like `_.clone` except that it accepts `customizer` which\n * is invoked to produce the cloned value. If `customizer` returns `undefined`,\n * cloning is handled by the method instead. The `customizer` is invoked with\n * up to four arguments; (value [, index|key, object, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeepWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(false);\n * }\n * }\n *\n * var el = _.cloneWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 0\n */\n function cloneWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);\n }\n\n /**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\n function cloneDeep(value) {\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n }\n\n /**\n * This method is like `_.cloneWith` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the deep cloned value.\n * @see _.cloneWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(true);\n * }\n * }\n *\n * var el = _.cloneDeepWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 20\n */\n function cloneDeepWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n }\n\n /**\n * Checks if `object` conforms to `source` by invoking the predicate\n * properties of `source` with the corresponding property values of `object`.\n *\n * **Note:** This method is equivalent to `_.conforms` when `source` is\n * partially applied.\n *\n * @static\n * @memberOf _\n * @since 4.14.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property predicates to conform to.\n * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n *\n * _.conformsTo(object, { 'b': function(n) { return n > 1; } });\n * // => true\n *\n * _.conformsTo(object, { 'b': function(n) { return n > 2; } });\n * // => false\n */\n function conformsTo(object, source) {\n return source == null || baseConformsTo(object, source, keys(source));\n }\n\n /**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\n function eq(value, other) {\n return value === other || (value !== value && other !== other);\n }\n\n /**\n * Checks if `value` is greater than `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than `other`,\n * else `false`.\n * @see _.lt\n * @example\n *\n * _.gt(3, 1);\n * // => true\n *\n * _.gt(3, 3);\n * // => false\n *\n * _.gt(1, 3);\n * // => false\n */\n var gt = createRelationalOperation(baseGt);\n\n /**\n * Checks if `value` is greater than or equal to `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than or equal to\n * `other`, else `false`.\n * @see _.lte\n * @example\n *\n * _.gte(3, 1);\n * // => true\n *\n * _.gte(3, 3);\n * // => true\n *\n * _.gte(1, 3);\n * // => false\n */\n var gte = createRelationalOperation(function(value, other) {\n return value >= other;\n });\n\n /**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\n var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n };\n\n /**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\n var isArray = Array.isArray;\n\n /**\n * Checks if `value` is classified as an `ArrayBuffer` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n * @example\n *\n * _.isArrayBuffer(new ArrayBuffer(2));\n * // => true\n *\n * _.isArrayBuffer(new Array(2));\n * // => false\n */\n var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;\n\n /**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\n function isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n }\n\n /**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\n function isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n }\n\n /**\n * Checks if `value` is classified as a boolean primitive or object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.\n * @example\n *\n * _.isBoolean(false);\n * // => true\n *\n * _.isBoolean(null);\n * // => false\n */\n function isBoolean(value) {\n return value === true || value === false ||\n (isObjectLike(value) && baseGetTag(value) == boolTag);\n }\n\n /**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\n var isBuffer = nativeIsBuffer || stubFalse;\n\n /**\n * Checks if `value` is classified as a `Date` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n * @example\n *\n * _.isDate(new Date);\n * // => true\n *\n * _.isDate('Mon April 23 2012');\n * // => false\n */\n var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;\n\n /**\n * Checks if `value` is likely a DOM element.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n * @example\n *\n * _.isElement(document.body);\n * // => true\n *\n * _.isElement('');\n * // => false\n */\n function isElement(value) {\n return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n }\n\n /**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * Objects are considered empty if they have no own enumerable string keyed\n * properties.\n *\n * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n * jQuery-like collections are considered empty if they have a `length` of `0`.\n * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n * @example\n *\n * _.isEmpty(null);\n * // => true\n *\n * _.isEmpty(true);\n * // => true\n *\n * _.isEmpty(1);\n * // => true\n *\n * _.isEmpty([1, 2, 3]);\n * // => false\n *\n * _.isEmpty({ 'a': 1 });\n * // => false\n */\n function isEmpty(value) {\n if (value == null) {\n return true;\n }\n if (isArrayLike(value) &&\n (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n return !value.length;\n }\n var tag = getTag(value);\n if (tag == mapTag || tag == setTag) {\n return !value.size;\n }\n if (isPrototype(value)) {\n return !baseKeys(value).length;\n }\n for (var key in value) {\n if (hasOwnProperty.call(value, key)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\n function isEqual(value, other) {\n return baseIsEqual(value, other);\n }\n\n /**\n * This method is like `_.isEqual` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with up to\n * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, othValue) {\n * if (isGreeting(objValue) && isGreeting(othValue)) {\n * return true;\n * }\n * }\n *\n * var array = ['hello', 'goodbye'];\n * var other = ['hi', 'goodbye'];\n *\n * _.isEqualWith(array, other, customizer);\n * // => true\n */\n function isEqualWith(value, other, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n var result = customizer ? customizer(value, other) : undefined;\n return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n }\n\n /**\n * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n * `SyntaxError`, `TypeError`, or `URIError` object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n * @example\n *\n * _.isError(new Error);\n * // => true\n *\n * _.isError(Error);\n * // => false\n */\n function isError(value) {\n if (!isObjectLike(value)) {\n return false;\n }\n var tag = baseGetTag(value);\n return tag == errorTag || tag == domExcTag ||\n (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));\n }\n\n /**\n * Checks if `value` is a finite primitive number.\n *\n * **Note:** This method is based on\n * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n * @example\n *\n * _.isFinite(3);\n * // => true\n *\n * _.isFinite(Number.MIN_VALUE);\n * // => true\n *\n * _.isFinite(Infinity);\n * // => false\n *\n * _.isFinite('3');\n * // => false\n */\n function isFinite(value) {\n return typeof value == 'number' && nativeIsFinite(value);\n }\n\n /**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\n function isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n }\n\n /**\n * Checks if `value` is an integer.\n *\n * **Note:** This method is based on\n * [`Number.isInteger`](https://mdn.io/Number/isInteger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an integer, else `false`.\n * @example\n *\n * _.isInteger(3);\n * // => true\n *\n * _.isInteger(Number.MIN_VALUE);\n * // => false\n *\n * _.isInteger(Infinity);\n * // => false\n *\n * _.isInteger('3');\n * // => false\n */\n function isInteger(value) {\n return typeof value == 'number' && value == toInteger(value);\n }\n\n /**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\n function isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\n function isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n }\n\n /**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\n function isObjectLike(value) {\n return value != null && typeof value == 'object';\n }\n\n /**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\n var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\n /**\n * Performs a partial deep comparison between `object` and `source` to\n * determine if `object` contains equivalent property values.\n *\n * **Note:** This method is equivalent to `_.matches` when `source` is\n * partially applied.\n *\n * Partial comparisons will match empty array and empty object `source`\n * values against any array or object value, respectively. See `_.isEqual`\n * for a list of supported value comparisons.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n *\n * _.isMatch(object, { 'b': 2 });\n * // => true\n *\n * _.isMatch(object, { 'b': 1 });\n * // => false\n */\n function isMatch(object, source) {\n return object === source || baseIsMatch(object, source, getMatchData(source));\n }\n\n /**\n * This method is like `_.isMatch` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with five\n * arguments: (objValue, srcValue, index|key, object, source).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, srcValue) {\n * if (isGreeting(objValue) && isGreeting(srcValue)) {\n * return true;\n * }\n * }\n *\n * var object = { 'greeting': 'hello' };\n * var source = { 'greeting': 'hi' };\n *\n * _.isMatchWith(object, source, customizer);\n * // => true\n */\n function isMatchWith(object, source, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseIsMatch(object, source, getMatchData(source), customizer);\n }\n\n /**\n * Checks if `value` is `NaN`.\n *\n * **Note:** This method is based on\n * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as\n * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for\n * `undefined` and other non-number values.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n * @example\n *\n * _.isNaN(NaN);\n * // => true\n *\n * _.isNaN(new Number(NaN));\n * // => true\n *\n * isNaN(undefined);\n * // => true\n *\n * _.isNaN(undefined);\n * // => false\n */\n function isNaN(value) {\n // An `NaN` primitive is the only value that is not equal to itself.\n // Perform the `toStringTag` check first to avoid errors with some\n // ActiveX objects in IE.\n return isNumber(value) && value != +value;\n }\n\n /**\n * Checks if `value` is a pristine native function.\n *\n * **Note:** This method can't reliably detect native functions in the presence\n * of the core-js package because core-js circumvents this kind of detection.\n * Despite multiple requests, the core-js maintainer has made it clear: any\n * attempt to fix the detection will be obstructed. As a result, we're left\n * with little choice but to throw an error. Unfortunately, this also affects\n * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),\n * which rely on core-js.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\n function isNative(value) {\n if (isMaskable(value)) {\n throw new Error(CORE_ERROR_TEXT);\n }\n return baseIsNative(value);\n }\n\n /**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\n function isNull(value) {\n return value === null;\n }\n\n /**\n * Checks if `value` is `null` or `undefined`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n * @example\n *\n * _.isNil(null);\n * // => true\n *\n * _.isNil(void 0);\n * // => true\n *\n * _.isNil(NaN);\n * // => false\n */\n function isNil(value) {\n return value == null;\n }\n\n /**\n * Checks if `value` is classified as a `Number` primitive or object.\n *\n * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n * classified as numbers, use the `_.isFinite` method.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n * @example\n *\n * _.isNumber(3);\n * // => true\n *\n * _.isNumber(Number.MIN_VALUE);\n * // => true\n *\n * _.isNumber(Infinity);\n * // => true\n *\n * _.isNumber('3');\n * // => false\n */\n function isNumber(value) {\n return typeof value == 'number' ||\n (isObjectLike(value) && baseGetTag(value) == numberTag);\n }\n\n /**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\n function isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n }\n\n /**\n * Checks if `value` is classified as a `RegExp` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n * @example\n *\n * _.isRegExp(/abc/);\n * // => true\n *\n * _.isRegExp('/abc/');\n * // => false\n */\n var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;\n\n /**\n * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754\n * double precision number which isn't the result of a rounded unsafe integer.\n *\n * **Note:** This method is based on\n * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.\n * @example\n *\n * _.isSafeInteger(3);\n * // => true\n *\n * _.isSafeInteger(Number.MIN_VALUE);\n * // => false\n *\n * _.isSafeInteger(Infinity);\n * // => false\n *\n * _.isSafeInteger('3');\n * // => false\n */\n function isSafeInteger(value) {\n return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\n var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\n /**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\n function isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n }\n\n /**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\n function isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n }\n\n /**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\n var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n /**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\n function isUndefined(value) {\n return value === undefined;\n }\n\n /**\n * Checks if `value` is classified as a `WeakMap` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.\n * @example\n *\n * _.isWeakMap(new WeakMap);\n * // => true\n *\n * _.isWeakMap(new Map);\n * // => false\n */\n function isWeakMap(value) {\n return isObjectLike(value) && getTag(value) == weakMapTag;\n }\n\n /**\n * Checks if `value` is classified as a `WeakSet` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.\n * @example\n *\n * _.isWeakSet(new WeakSet);\n * // => true\n *\n * _.isWeakSet(new Set);\n * // => false\n */\n function isWeakSet(value) {\n return isObjectLike(value) && baseGetTag(value) == weakSetTag;\n }\n\n /**\n * Checks if `value` is less than `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than `other`,\n * else `false`.\n * @see _.gt\n * @example\n *\n * _.lt(1, 3);\n * // => true\n *\n * _.lt(3, 3);\n * // => false\n *\n * _.lt(3, 1);\n * // => false\n */\n var lt = createRelationalOperation(baseLt);\n\n /**\n * Checks if `value` is less than or equal to `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than or equal to\n * `other`, else `false`.\n * @see _.gte\n * @example\n *\n * _.lte(1, 3);\n * // => true\n *\n * _.lte(3, 3);\n * // => true\n *\n * _.lte(3, 1);\n * // => false\n */\n var lte = createRelationalOperation(function(value, other) {\n return value <= other;\n });\n\n /**\n * Converts `value` to an array.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Array} Returns the converted array.\n * @example\n *\n * _.toArray({ 'a': 1, 'b': 2 });\n * // => [1, 2]\n *\n * _.toArray('abc');\n * // => ['a', 'b', 'c']\n *\n * _.toArray(1);\n * // => []\n *\n * _.toArray(null);\n * // => []\n */\n function toArray(value) {\n if (!value) {\n return [];\n }\n if (isArrayLike(value)) {\n return isString(value) ? stringToArray(value) : copyArray(value);\n }\n if (symIterator && value[symIterator]) {\n return iteratorToArray(value[symIterator]());\n }\n var tag = getTag(value),\n func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);\n\n return func(value);\n }\n\n /**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\n function toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n }\n\n /**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\n function toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n }\n\n /**\n * Converts `value` to an integer suitable for use as the length of an\n * array-like object.\n *\n * **Note:** This method is based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toLength(3.2);\n * // => 3\n *\n * _.toLength(Number.MIN_VALUE);\n * // => 0\n *\n * _.toLength(Infinity);\n * // => 4294967295\n *\n * _.toLength('3.2');\n * // => 3\n */\n function toLength(value) {\n return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;\n }\n\n /**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\n function toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n }\n\n /**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\n function toPlainObject(value) {\n return copyObject(value, keysIn(value));\n }\n\n /**\n * Converts `value` to a safe integer. A safe integer can be compared and\n * represented correctly.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toSafeInteger(3.2);\n * // => 3\n *\n * _.toSafeInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toSafeInteger(Infinity);\n * // => 9007199254740991\n *\n * _.toSafeInteger('3.2');\n * // => 3\n */\n function toSafeInteger(value) {\n return value\n ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)\n : (value === 0 ? value : 0);\n }\n\n /**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\n function toString(value) {\n return value == null ? '' : baseToString(value);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\n var assign = createAssigner(function(object, source) {\n if (isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n });\n\n /**\n * This method is like `_.assign` except that it iterates over own and\n * inherited source properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extend\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assign\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n */\n var assignIn = createAssigner(function(object, source) {\n copyObject(source, keysIn(source), object);\n });\n\n /**\n * This method is like `_.assignIn` except that it accepts `customizer`\n * which is invoked to produce the assigned values. If `customizer` returns\n * `undefined`, assignment is handled by the method instead. The `customizer`\n * is invoked with five arguments: (objValue, srcValue, key, object, source).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extendWith\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @see _.assignWith\n * @example\n *\n * function customizer(objValue, srcValue) {\n * return _.isUndefined(objValue) ? srcValue : objValue;\n * }\n *\n * var defaults = _.partialRight(_.assignInWith, customizer);\n *\n * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {\n copyObject(source, keysIn(source), object, customizer);\n });\n\n /**\n * This method is like `_.assign` except that it accepts `customizer`\n * which is invoked to produce the assigned values. If `customizer` returns\n * `undefined`, assignment is handled by the method instead. The `customizer`\n * is invoked with five arguments: (objValue, srcValue, key, object, source).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @see _.assignInWith\n * @example\n *\n * function customizer(objValue, srcValue) {\n * return _.isUndefined(objValue) ? srcValue : objValue;\n * }\n *\n * var defaults = _.partialRight(_.assignWith, customizer);\n *\n * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var assignWith = createAssigner(function(object, source, srcIndex, customizer) {\n copyObject(source, keys(source), object, customizer);\n });\n\n /**\n * Creates an array of values corresponding to `paths` of `object`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Array} Returns the picked values.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n *\n * _.at(object, ['a[0].b.c', 'a[1]']);\n * // => [3, 4]\n */\n var at = flatRest(baseAt);\n\n /**\n * Creates an object that inherits from the `prototype` object. If a\n * `properties` object is given, its own enumerable string keyed properties\n * are assigned to the created object.\n *\n * @static\n * @memberOf _\n * @since 2.3.0\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n * this.x = 0;\n * this.y = 0;\n * }\n *\n * function Circle() {\n * Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n * 'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\n function create(prototype, properties) {\n var result = baseCreate(prototype);\n return properties == null ? result : baseAssign(result, properties);\n }\n\n /**\n * Assigns own and inherited enumerable string keyed properties of source\n * objects to the destination object for all destination properties that\n * resolve to `undefined`. Source objects are applied from left to right.\n * Once a property is set, additional values of the same property are ignored.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaultsDeep\n * @example\n *\n * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var defaults = baseRest(function(args) {\n args.push(undefined, customDefaultsAssignIn);\n return apply(assignInWith, undefined, args);\n });\n\n /**\n * This method is like `_.defaults` except that it recursively assigns\n * default properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaults\n * @example\n *\n * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n * // => { 'a': { 'b': 2, 'c': 3 } }\n */\n var defaultsDeep = baseRest(function(args) {\n args.push(undefined, customDefaultsMerge);\n return apply(mergeWith, undefined, args);\n });\n\n /**\n * This method is like `_.find` except that it returns the key of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {string|undefined} Returns the key of the matched element,\n * else `undefined`.\n * @example\n *\n * var users = {\n * 'barney': { 'age': 36, 'active': true },\n * 'fred': { 'age': 40, 'active': false },\n * 'pebbles': { 'age': 1, 'active': true }\n * };\n *\n * _.findKey(users, function(o) { return o.age < 40; });\n * // => 'barney' (iteration order is not guaranteed)\n *\n * // The `_.matches` iteratee shorthand.\n * _.findKey(users, { 'age': 1, 'active': true });\n * // => 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findKey(users, ['active', false]);\n * // => 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.findKey(users, 'active');\n * // => 'barney'\n */\n function findKey(object, predicate) {\n return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);\n }\n\n /**\n * This method is like `_.findKey` except that it iterates over elements of\n * a collection in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {string|undefined} Returns the key of the matched element,\n * else `undefined`.\n * @example\n *\n * var users = {\n * 'barney': { 'age': 36, 'active': true },\n * 'fred': { 'age': 40, 'active': false },\n * 'pebbles': { 'age': 1, 'active': true }\n * };\n *\n * _.findLastKey(users, function(o) { return o.age < 40; });\n * // => returns 'pebbles' assuming `_.findKey` returns 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.findLastKey(users, { 'age': 36, 'active': true });\n * // => 'barney'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findLastKey(users, ['active', false]);\n * // => 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.findLastKey(users, 'active');\n * // => 'pebbles'\n */\n function findLastKey(object, predicate) {\n return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);\n }\n\n /**\n * Iterates over own and inherited enumerable string keyed properties of an\n * object and invokes `iteratee` for each property. The iteratee is invoked\n * with three arguments: (value, key, object). Iteratee functions may exit\n * iteration early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 0.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forInRight\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forIn(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).\n */\n function forIn(object, iteratee) {\n return object == null\n ? object\n : baseFor(object, getIteratee(iteratee, 3), keysIn);\n }\n\n /**\n * This method is like `_.forIn` except that it iterates over properties of\n * `object` in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forInRight(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.\n */\n function forInRight(object, iteratee) {\n return object == null\n ? object\n : baseForRight(object, getIteratee(iteratee, 3), keysIn);\n }\n\n /**\n * Iterates over own enumerable string keyed properties of an object and\n * invokes `iteratee` for each property. The iteratee is invoked with three\n * arguments: (value, key, object). Iteratee functions may exit iteration\n * early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 0.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forOwnRight\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forOwn(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\n function forOwn(object, iteratee) {\n return object && baseForOwn(object, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.forOwn` except that it iterates over properties of\n * `object` in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forOwn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forOwnRight(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.\n */\n function forOwnRight(object, iteratee) {\n return object && baseForOwnRight(object, getIteratee(iteratee, 3));\n }\n\n /**\n * Creates an array of function property names from own enumerable properties\n * of `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to inspect.\n * @returns {Array} Returns the function names.\n * @see _.functionsIn\n * @example\n *\n * function Foo() {\n * this.a = _.constant('a');\n * this.b = _.constant('b');\n * }\n *\n * Foo.prototype.c = _.constant('c');\n *\n * _.functions(new Foo);\n * // => ['a', 'b']\n */\n function functions(object) {\n return object == null ? [] : baseFunctions(object, keys(object));\n }\n\n /**\n * Creates an array of function property names from own and inherited\n * enumerable properties of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @returns {Array} Returns the function names.\n * @see _.functions\n * @example\n *\n * function Foo() {\n * this.a = _.constant('a');\n * this.b = _.constant('b');\n * }\n *\n * Foo.prototype.c = _.constant('c');\n *\n * _.functionsIn(new Foo);\n * // => ['a', 'b', 'c']\n */\n function functionsIn(object) {\n return object == null ? [] : baseFunctions(object, keysIn(object));\n }\n\n /**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\n function get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n }\n\n /**\n * Checks if `path` is a direct property of `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = { 'a': { 'b': 2 } };\n * var other = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.has(object, 'a');\n * // => true\n *\n * _.has(object, 'a.b');\n * // => true\n *\n * _.has(object, ['a', 'b']);\n * // => true\n *\n * _.has(other, 'a');\n * // => false\n */\n function has(object, path) {\n return object != null && hasPath(object, path, baseHas);\n }\n\n /**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\n function hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n }\n\n /**\n * Creates an object composed of the inverted keys and values of `object`.\n * If `object` contains duplicate values, subsequent values overwrite\n * property assignments of previous values.\n *\n * @static\n * @memberOf _\n * @since 0.7.0\n * @category Object\n * @param {Object} object The object to invert.\n * @returns {Object} Returns the new inverted object.\n * @example\n *\n * var object = { 'a': 1, 'b': 2, 'c': 1 };\n *\n * _.invert(object);\n * // => { '1': 'c', '2': 'b' }\n */\n var invert = createInverter(function(result, value, key) {\n result[value] = key;\n }, constant(identity));\n\n /**\n * This method is like `_.invert` except that the inverted object is generated\n * from the results of running each element of `object` thru `iteratee`. The\n * corresponding inverted value of each inverted key is an array of keys\n * responsible for generating the inverted value. The iteratee is invoked\n * with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.1.0\n * @category Object\n * @param {Object} object The object to invert.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Object} Returns the new inverted object.\n * @example\n *\n * var object = { 'a': 1, 'b': 2, 'c': 1 };\n *\n * _.invertBy(object);\n * // => { '1': ['a', 'c'], '2': ['b'] }\n *\n * _.invertBy(object, function(value) {\n * return 'group' + value;\n * });\n * // => { 'group1': ['a', 'c'], 'group2': ['b'] }\n */\n var invertBy = createInverter(function(result, value, key) {\n if (hasOwnProperty.call(result, value)) {\n result[value].push(key);\n } else {\n result[value] = [key];\n }\n }, getIteratee);\n\n /**\n * Invokes the method at `path` of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {...*} [args] The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };\n *\n * _.invoke(object, 'a[0].b.c.slice', 1, 3);\n * // => [2, 3]\n */\n var invoke = baseRest(baseInvoke);\n\n /**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\n function keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n }\n\n /**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\n function keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n }\n\n /**\n * The opposite of `_.mapValues`; this method creates an object with the\n * same values as `object` and keys generated by running each own enumerable\n * string keyed property of `object` thru `iteratee`. The iteratee is invoked\n * with three arguments: (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapValues\n * @example\n *\n * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {\n * return key + value;\n * });\n * // => { 'a1': 1, 'b2': 2 }\n */\n function mapKeys(object, iteratee) {\n var result = {};\n iteratee = getIteratee(iteratee, 3);\n\n baseForOwn(object, function(value, key, object) {\n baseAssignValue(result, iteratee(value, key, object), value);\n });\n return result;\n }\n\n /**\n * Creates an object with the same keys as `object` and values generated\n * by running each own enumerable string keyed property of `object` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapKeys\n * @example\n *\n * var users = {\n * 'fred': { 'user': 'fred', 'age': 40 },\n * 'pebbles': { 'user': 'pebbles', 'age': 1 }\n * };\n *\n * _.mapValues(users, function(o) { return o.age; });\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n *\n * // The `_.property` iteratee shorthand.\n * _.mapValues(users, 'age');\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n */\n function mapValues(object, iteratee) {\n var result = {};\n iteratee = getIteratee(iteratee, 3);\n\n baseForOwn(object, function(value, key, object) {\n baseAssignValue(result, key, iteratee(value, key, object));\n });\n return result;\n }\n\n /**\n * This method is like `_.assign` except that it recursively merges own and\n * inherited enumerable string keyed properties of source objects into the\n * destination object. Source properties that resolve to `undefined` are\n * skipped if a destination value exists. Array and plain object properties\n * are merged recursively. Other objects and value types are overridden by\n * assignment. Source objects are applied from left to right. Subsequent\n * sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {\n * 'a': [{ 'b': 2 }, { 'd': 4 }]\n * };\n *\n * var other = {\n * 'a': [{ 'c': 3 }, { 'e': 5 }]\n * };\n *\n * _.merge(object, other);\n * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n */\n var merge = createAssigner(function(object, source, srcIndex) {\n baseMerge(object, source, srcIndex);\n });\n\n /**\n * This method is like `_.merge` except that it accepts `customizer` which\n * is invoked to produce the merged values of the destination and source\n * properties. If `customizer` returns `undefined`, merging is handled by the\n * method instead. The `customizer` is invoked with six arguments:\n * (objValue, srcValue, key, object, source, stack).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} customizer The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * function customizer(objValue, srcValue) {\n * if (_.isArray(objValue)) {\n * return objValue.concat(srcValue);\n * }\n * }\n *\n * var object = { 'a': [1], 'b': [2] };\n * var other = { 'a': [3], 'b': [4] };\n *\n * _.mergeWith(object, other, customizer);\n * // => { 'a': [1, 3], 'b': [2, 4] }\n */\n var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n baseMerge(object, source, srcIndex, customizer);\n });\n\n /**\n * The opposite of `_.pick`; this method creates an object composed of the\n * own and inherited enumerable property paths of `object` that are not omitted.\n *\n * **Note:** This method is considerably slower than `_.pick`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to omit.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omit(object, ['a', 'c']);\n * // => { 'b': '2' }\n */\n var omit = flatRest(function(object, paths) {\n var result = {};\n if (object == null) {\n return result;\n }\n var isDeep = false;\n paths = arrayMap(paths, function(path) {\n path = castPath(path, object);\n isDeep || (isDeep = path.length > 1);\n return path;\n });\n copyObject(object, getAllKeysIn(object), result);\n if (isDeep) {\n result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n }\n var length = paths.length;\n while (length--) {\n baseUnset(result, paths[length]);\n }\n return result;\n });\n\n /**\n * The opposite of `_.pickBy`; this method creates an object composed of\n * the own and inherited enumerable string keyed properties of `object` that\n * `predicate` doesn't return truthy for. The predicate is invoked with two\n * arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omitBy(object, _.isNumber);\n * // => { 'b': '2' }\n */\n function omitBy(object, predicate) {\n return pickBy(object, negate(getIteratee(predicate)));\n }\n\n /**\n * Creates an object composed of the picked `object` properties.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pick(object, ['a', 'c']);\n * // => { 'a': 1, 'c': 3 }\n */\n var pick = flatRest(function(object, paths) {\n return object == null ? {} : basePick(object, paths);\n });\n\n /**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pickBy(object, _.isNumber);\n * // => { 'a': 1, 'c': 3 }\n */\n function pickBy(object, predicate) {\n if (object == null) {\n return {};\n }\n var props = arrayMap(getAllKeysIn(object), function(prop) {\n return [prop];\n });\n predicate = getIteratee(predicate);\n return basePickBy(object, props, function(value, path) {\n return predicate(value, path[0]);\n });\n }\n\n /**\n * This method is like `_.get` except that if the resolved value is a\n * function it's invoked with the `this` binding of its parent object and\n * its result is returned.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to resolve.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n *\n * _.result(object, 'a[0].b.c1');\n * // => 3\n *\n * _.result(object, 'a[0].b.c2');\n * // => 4\n *\n * _.result(object, 'a[0].b.c3', 'default');\n * // => 'default'\n *\n * _.result(object, 'a[0].b.c3', _.constant('default'));\n * // => 'default'\n */\n function result(object, path, defaultValue) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length;\n\n // Ensure the loop is entered when path is empty.\n if (!length) {\n length = 1;\n object = undefined;\n }\n while (++index < length) {\n var value = object == null ? undefined : object[toKey(path[index])];\n if (value === undefined) {\n index = length;\n value = defaultValue;\n }\n object = isFunction(value) ? value.call(object) : value;\n }\n return object;\n }\n\n /**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\n function set(object, path, value) {\n return object == null ? object : baseSet(object, path, value);\n }\n\n /**\n * This method is like `_.set` except that it accepts `customizer` which is\n * invoked to produce the objects of `path`. If `customizer` returns `undefined`\n * path creation is handled by the method instead. The `customizer` is invoked\n * with three arguments: (nsValue, key, nsObject).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {};\n *\n * _.setWith(object, '[0][1]', 'a', Object);\n * // => { '0': { '1': 'a' } }\n */\n function setWith(object, path, value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return object == null ? object : baseSet(object, path, value, customizer);\n }\n\n /**\n * Creates an array of own enumerable string keyed-value pairs for `object`\n * which can be consumed by `_.fromPairs`. If `object` is a map or set, its\n * entries are returned.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias entries\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the key-value pairs.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.toPairs(new Foo);\n * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)\n */\n var toPairs = createToPairs(keys);\n\n /**\n * Creates an array of own and inherited enumerable string keyed-value pairs\n * for `object` which can be consumed by `_.fromPairs`. If `object` is a map\n * or set, its entries are returned.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias entriesIn\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the key-value pairs.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.toPairsIn(new Foo);\n * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)\n */\n var toPairsIn = createToPairs(keysIn);\n\n /**\n * An alternative to `_.reduce`; this method transforms `object` to a new\n * `accumulator` object which is the result of running each of its own\n * enumerable string keyed properties thru `iteratee`, with each invocation\n * potentially mutating the `accumulator` object. If `accumulator` is not\n * provided, a new object with the same `[[Prototype]]` will be used. The\n * iteratee is invoked with four arguments: (accumulator, value, key, object).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 1.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The custom accumulator value.\n * @returns {*} Returns the accumulated value.\n * @example\n *\n * _.transform([2, 3, 4], function(result, n) {\n * result.push(n *= n);\n * return n % 2 == 0;\n * }, []);\n * // => [4, 9]\n *\n * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n * (result[value] || (result[value] = [])).push(key);\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] }\n */\n function transform(object, iteratee, accumulator) {\n var isArr = isArray(object),\n isArrLike = isArr || isBuffer(object) || isTypedArray(object);\n\n iteratee = getIteratee(iteratee, 4);\n if (accumulator == null) {\n var Ctor = object && object.constructor;\n if (isArrLike) {\n accumulator = isArr ? new Ctor : [];\n }\n else if (isObject(object)) {\n accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};\n }\n else {\n accumulator = {};\n }\n }\n (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {\n return iteratee(accumulator, value, index, object);\n });\n return accumulator;\n }\n\n /**\n * Removes the property at `path` of `object`.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 7 } }] };\n * _.unset(object, 'a[0].b.c');\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n *\n * _.unset(object, ['a', '0', 'b', 'c']);\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n */\n function unset(object, path) {\n return object == null ? true : baseUnset(object, path);\n }\n\n /**\n * This method is like `_.set` except that accepts `updater` to produce the\n * value to set. Use `_.updateWith` to customize `path` creation. The `updater`\n * is invoked with one argument: (value).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {Function} updater The function to produce the updated value.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.update(object, 'a[0].b.c', function(n) { return n * n; });\n * console.log(object.a[0].b.c);\n * // => 9\n *\n * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });\n * console.log(object.x[0].y.z);\n * // => 0\n */\n function update(object, path, updater) {\n return object == null ? object : baseUpdate(object, path, castFunction(updater));\n }\n\n /**\n * This method is like `_.update` except that it accepts `customizer` which is\n * invoked to produce the objects of `path`. If `customizer` returns `undefined`\n * path creation is handled by the method instead. The `customizer` is invoked\n * with three arguments: (nsValue, key, nsObject).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {Function} updater The function to produce the updated value.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {};\n *\n * _.updateWith(object, '[0][1]', _.constant('a'), Object);\n * // => { '0': { '1': 'a' } }\n */\n function updateWith(object, path, updater, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);\n }\n\n /**\n * Creates an array of the own enumerable string keyed property values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.values(new Foo);\n * // => [1, 2] (iteration order is not guaranteed)\n *\n * _.values('hi');\n * // => ['h', 'i']\n */\n function values(object) {\n return object == null ? [] : baseValues(object, keys(object));\n }\n\n /**\n * Creates an array of the own and inherited enumerable string keyed property\n * values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.valuesIn(new Foo);\n * // => [1, 2, 3] (iteration order is not guaranteed)\n */\n function valuesIn(object) {\n return object == null ? [] : baseValues(object, keysIn(object));\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Clamps `number` within the inclusive `lower` and `upper` bounds.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Number\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n * @example\n *\n * _.clamp(-10, -5, 5);\n * // => -5\n *\n * _.clamp(10, -5, 5);\n * // => 5\n */\n function clamp(number, lower, upper) {\n if (upper === undefined) {\n upper = lower;\n lower = undefined;\n }\n if (upper !== undefined) {\n upper = toNumber(upper);\n upper = upper === upper ? upper : 0;\n }\n if (lower !== undefined) {\n lower = toNumber(lower);\n lower = lower === lower ? lower : 0;\n }\n return baseClamp(toNumber(number), lower, upper);\n }\n\n /**\n * Checks if `n` is between `start` and up to, but not including, `end`. If\n * `end` is not specified, it's set to `start` with `start` then set to `0`.\n * If `start` is greater than `end` the params are swapped to support\n * negative ranges.\n *\n * @static\n * @memberOf _\n * @since 3.3.0\n * @category Number\n * @param {number} number The number to check.\n * @param {number} [start=0] The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n * @see _.range, _.rangeRight\n * @example\n *\n * _.inRange(3, 2, 4);\n * // => true\n *\n * _.inRange(4, 8);\n * // => true\n *\n * _.inRange(4, 2);\n * // => false\n *\n * _.inRange(2, 2);\n * // => false\n *\n * _.inRange(1.2, 2);\n * // => true\n *\n * _.inRange(5.2, 4);\n * // => false\n *\n * _.inRange(-3, -2, -6);\n * // => true\n */\n function inRange(number, start, end) {\n start = toFinite(start);\n if (end === undefined) {\n end = start;\n start = 0;\n } else {\n end = toFinite(end);\n }\n number = toNumber(number);\n return baseInRange(number, start, end);\n }\n\n /**\n * Produces a random number between the inclusive `lower` and `upper` bounds.\n * If only one argument is provided a number between `0` and the given number\n * is returned. If `floating` is `true`, or either `lower` or `upper` are\n * floats, a floating-point number is returned instead of an integer.\n *\n * **Note:** JavaScript follows the IEEE-754 standard for resolving\n * floating-point values which can produce unexpected results.\n *\n * @static\n * @memberOf _\n * @since 0.7.0\n * @category Number\n * @param {number} [lower=0] The lower bound.\n * @param {number} [upper=1] The upper bound.\n * @param {boolean} [floating] Specify returning a floating-point number.\n * @returns {number} Returns the random number.\n * @example\n *\n * _.random(0, 5);\n * // => an integer between 0 and 5\n *\n * _.random(5);\n * // => also an integer between 0 and 5\n *\n * _.random(5, true);\n * // => a floating-point number between 0 and 5\n *\n * _.random(1.2, 5.2);\n * // => a floating-point number between 1.2 and 5.2\n */\n function random(lower, upper, floating) {\n if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {\n upper = floating = undefined;\n }\n if (floating === undefined) {\n if (typeof upper == 'boolean') {\n floating = upper;\n upper = undefined;\n }\n else if (typeof lower == 'boolean') {\n floating = lower;\n lower = undefined;\n }\n }\n if (lower === undefined && upper === undefined) {\n lower = 0;\n upper = 1;\n }\n else {\n lower = toFinite(lower);\n if (upper === undefined) {\n upper = lower;\n lower = 0;\n } else {\n upper = toFinite(upper);\n }\n }\n if (lower > upper) {\n var temp = lower;\n lower = upper;\n upper = temp;\n }\n if (floating || lower % 1 || upper % 1) {\n var rand = nativeRandom();\n return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);\n }\n return baseRandom(lower, upper);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the camel cased string.\n * @example\n *\n * _.camelCase('Foo Bar');\n * // => 'fooBar'\n *\n * _.camelCase('--foo-bar--');\n * // => 'fooBar'\n *\n * _.camelCase('__FOO_BAR__');\n * // => 'fooBar'\n */\n var camelCase = createCompounder(function(result, word, index) {\n word = word.toLowerCase();\n return result + (index ? capitalize(word) : word);\n });\n\n /**\n * Converts the first character of `string` to upper case and the remaining\n * to lower case.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to capitalize.\n * @returns {string} Returns the capitalized string.\n * @example\n *\n * _.capitalize('FRED');\n * // => 'Fred'\n */\n function capitalize(string) {\n return upperFirst(toString(string).toLowerCase());\n }\n\n /**\n * Deburrs `string` by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to deburr.\n * @returns {string} Returns the deburred string.\n * @example\n *\n * _.deburr('déjà vu');\n * // => 'deja vu'\n */\n function deburr(string) {\n string = toString(string);\n return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n }\n\n /**\n * Checks if `string` ends with the given target string.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {string} [target] The string to search for.\n * @param {number} [position=string.length] The position to search up to.\n * @returns {boolean} Returns `true` if `string` ends with `target`,\n * else `false`.\n * @example\n *\n * _.endsWith('abc', 'c');\n * // => true\n *\n * _.endsWith('abc', 'b');\n * // => false\n *\n * _.endsWith('abc', 'b', 2);\n * // => true\n */\n function endsWith(string, target, position) {\n string = toString(string);\n target = baseToString(target);\n\n var length = string.length;\n position = position === undefined\n ? length\n : baseClamp(toInteger(position), 0, length);\n\n var end = position;\n position -= target.length;\n return position >= 0 && string.slice(position, end) == target;\n }\n\n /**\n * Converts the characters \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n * corresponding HTML entities.\n *\n * **Note:** No other characters are escaped. To escape additional\n * characters use a third-party library like [_he_](https://mths.be/he).\n *\n * Though the \">\" character is escaped for symmetry, characters like\n * \">\" and \"/\" don't need escaping in HTML and have no special meaning\n * unless they're part of a tag or unquoted attribute value. See\n * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)\n * (under \"semi-related fun fact\") for more details.\n *\n * When working with HTML you should always\n * [quote attribute values](http://wonko.com/post/html-escaping) to reduce\n * XSS vectors.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category String\n * @param {string} [string=''] The string to escape.\n * @returns {string} Returns the escaped string.\n * @example\n *\n * _.escape('fred, barney, & pebbles');\n * // => 'fred, barney, & pebbles'\n */\n function escape(string) {\n string = toString(string);\n return (string && reHasUnescapedHtml.test(string))\n ? string.replace(reUnescapedHtml, escapeHtmlChar)\n : string;\n }\n\n /**\n * Escapes the `RegExp` special characters \"^\", \"$\", \"\\\", \".\", \"*\", \"+\",\n * \"?\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", and \"|\" in `string`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to escape.\n * @returns {string} Returns the escaped string.\n * @example\n *\n * _.escapeRegExp('[lodash](https://lodash.com/)');\n * // => '\\[lodash\\]\\(https://lodash\\.com/\\)'\n */\n function escapeRegExp(string) {\n string = toString(string);\n return (string && reHasRegExpChar.test(string))\n ? string.replace(reRegExpChar, '\\\\$&')\n : string;\n }\n\n /**\n * Converts `string` to\n * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the kebab cased string.\n * @example\n *\n * _.kebabCase('Foo Bar');\n * // => 'foo-bar'\n *\n * _.kebabCase('fooBar');\n * // => 'foo-bar'\n *\n * _.kebabCase('__FOO_BAR__');\n * // => 'foo-bar'\n */\n var kebabCase = createCompounder(function(result, word, index) {\n return result + (index ? '-' : '') + word.toLowerCase();\n });\n\n /**\n * Converts `string`, as space separated words, to lower case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the lower cased string.\n * @example\n *\n * _.lowerCase('--Foo-Bar--');\n * // => 'foo bar'\n *\n * _.lowerCase('fooBar');\n * // => 'foo bar'\n *\n * _.lowerCase('__FOO_BAR__');\n * // => 'foo bar'\n */\n var lowerCase = createCompounder(function(result, word, index) {\n return result + (index ? ' ' : '') + word.toLowerCase();\n });\n\n /**\n * Converts the first character of `string` to lower case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.lowerFirst('Fred');\n * // => 'fred'\n *\n * _.lowerFirst('FRED');\n * // => 'fRED'\n */\n var lowerFirst = createCaseFirst('toLowerCase');\n\n /**\n * Pads `string` on the left and right sides if it's shorter than `length`.\n * Padding characters are truncated if they can't be evenly divided by `length`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.pad('abc', 8);\n * // => ' abc '\n *\n * _.pad('abc', 8, '_-');\n * // => '_-abc_-_'\n *\n * _.pad('abc', 3);\n * // => 'abc'\n */\n function pad(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n if (!length || strLength >= length) {\n return string;\n }\n var mid = (length - strLength) / 2;\n return (\n createPadding(nativeFloor(mid), chars) +\n string +\n createPadding(nativeCeil(mid), chars)\n );\n }\n\n /**\n * Pads `string` on the right side if it's shorter than `length`. Padding\n * characters are truncated if they exceed `length`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.padEnd('abc', 6);\n * // => 'abc '\n *\n * _.padEnd('abc', 6, '_-');\n * // => 'abc_-_'\n *\n * _.padEnd('abc', 3);\n * // => 'abc'\n */\n function padEnd(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n return (length && strLength < length)\n ? (string + createPadding(length - strLength, chars))\n : string;\n }\n\n /**\n * Pads `string` on the left side if it's shorter than `length`. Padding\n * characters are truncated if they exceed `length`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.padStart('abc', 6);\n * // => ' abc'\n *\n * _.padStart('abc', 6, '_-');\n * // => '_-_abc'\n *\n * _.padStart('abc', 3);\n * // => 'abc'\n */\n function padStart(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n return (length && strLength < length)\n ? (createPadding(length - strLength, chars) + string)\n : string;\n }\n\n /**\n * Converts `string` to an integer of the specified radix. If `radix` is\n * `undefined` or `0`, a `radix` of `10` is used unless `value` is a\n * hexadecimal, in which case a `radix` of `16` is used.\n *\n * **Note:** This method aligns with the\n * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category String\n * @param {string} string The string to convert.\n * @param {number} [radix=10] The radix to interpret `value` by.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.parseInt('08');\n * // => 8\n *\n * _.map(['6', '08', '10'], _.parseInt);\n * // => [6, 8, 10]\n */\n function parseInt(string, radix, guard) {\n if (guard || radix == null) {\n radix = 0;\n } else if (radix) {\n radix = +radix;\n }\n return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);\n }\n\n /**\n * Repeats the given string `n` times.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to repeat.\n * @param {number} [n=1] The number of times to repeat the string.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {string} Returns the repeated string.\n * @example\n *\n * _.repeat('*', 3);\n * // => '***'\n *\n * _.repeat('abc', 2);\n * // => 'abcabc'\n *\n * _.repeat('abc', 0);\n * // => ''\n */\n function repeat(string, n, guard) {\n if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {\n n = 1;\n } else {\n n = toInteger(n);\n }\n return baseRepeat(toString(string), n);\n }\n\n /**\n * Replaces matches for `pattern` in `string` with `replacement`.\n *\n * **Note:** This method is based on\n * [`String#replace`](https://mdn.io/String/replace).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to modify.\n * @param {RegExp|string} pattern The pattern to replace.\n * @param {Function|string} replacement The match replacement.\n * @returns {string} Returns the modified string.\n * @example\n *\n * _.replace('Hi Fred', 'Fred', 'Barney');\n * // => 'Hi Barney'\n */\n function replace() {\n var args = arguments,\n string = toString(args[0]);\n\n return args.length < 3 ? string : string.replace(args[1], args[2]);\n }\n\n /**\n * Converts `string` to\n * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the snake cased string.\n * @example\n *\n * _.snakeCase('Foo Bar');\n * // => 'foo_bar'\n *\n * _.snakeCase('fooBar');\n * // => 'foo_bar'\n *\n * _.snakeCase('--FOO-BAR--');\n * // => 'foo_bar'\n */\n var snakeCase = createCompounder(function(result, word, index) {\n return result + (index ? '_' : '') + word.toLowerCase();\n });\n\n /**\n * Splits `string` by `separator`.\n *\n * **Note:** This method is based on\n * [`String#split`](https://mdn.io/String/split).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to split.\n * @param {RegExp|string} separator The separator pattern to split by.\n * @param {number} [limit] The length to truncate results to.\n * @returns {Array} Returns the string segments.\n * @example\n *\n * _.split('a-b-c', '-', 2);\n * // => ['a', 'b']\n */\n function split(string, separator, limit) {\n if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {\n separator = limit = undefined;\n }\n limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;\n if (!limit) {\n return [];\n }\n string = toString(string);\n if (string && (\n typeof separator == 'string' ||\n (separator != null && !isRegExp(separator))\n )) {\n separator = baseToString(separator);\n if (!separator && hasUnicode(string)) {\n return castSlice(stringToArray(string), 0, limit);\n }\n }\n return string.split(separator, limit);\n }\n\n /**\n * Converts `string` to\n * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n *\n * @static\n * @memberOf _\n * @since 3.1.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the start cased string.\n * @example\n *\n * _.startCase('--foo-bar--');\n * // => 'Foo Bar'\n *\n * _.startCase('fooBar');\n * // => 'Foo Bar'\n *\n * _.startCase('__FOO_BAR__');\n * // => 'FOO BAR'\n */\n var startCase = createCompounder(function(result, word, index) {\n return result + (index ? ' ' : '') + upperFirst(word);\n });\n\n /**\n * Checks if `string` starts with the given target string.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {string} [target] The string to search for.\n * @param {number} [position=0] The position to search from.\n * @returns {boolean} Returns `true` if `string` starts with `target`,\n * else `false`.\n * @example\n *\n * _.startsWith('abc', 'a');\n * // => true\n *\n * _.startsWith('abc', 'b');\n * // => false\n *\n * _.startsWith('abc', 'b', 1);\n * // => true\n */\n function startsWith(string, target, position) {\n string = toString(string);\n position = position == null\n ? 0\n : baseClamp(toInteger(position), 0, string.length);\n\n target = baseToString(target);\n return string.slice(position, position + target.length) == target;\n }\n\n /**\n * Creates a compiled template function that can interpolate data properties\n * in \"interpolate\" delimiters, HTML-escape interpolated data properties in\n * \"escape\" delimiters, and execute JavaScript in \"evaluate\" delimiters. Data\n * properties may be accessed as free variables in the template. If a setting\n * object is given, it takes precedence over `_.templateSettings` values.\n *\n * **Note:** In the development build `_.template` utilizes\n * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)\n * for easier debugging.\n *\n * For more information on precompiling templates see\n * [lodash's custom builds documentation](https://lodash.com/custom-builds).\n *\n * For more information on Chrome extension sandboxes see\n * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category String\n * @param {string} [string=''] The template string.\n * @param {Object} [options={}] The options object.\n * @param {RegExp} [options.escape=_.templateSettings.escape]\n * The HTML \"escape\" delimiter.\n * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]\n * The \"evaluate\" delimiter.\n * @param {Object} [options.imports=_.templateSettings.imports]\n * An object to import into the template as free variables.\n * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]\n * The \"interpolate\" delimiter.\n * @param {string} [options.sourceURL='lodash.templateSources[n]']\n * The sourceURL of the compiled template.\n * @param {string} [options.variable='obj']\n * The data object variable name.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the compiled template function.\n * @example\n *\n * // Use the \"interpolate\" delimiter to create a compiled template.\n * var compiled = _.template('hello <%= user %>!');\n * compiled({ 'user': 'fred' });\n * // => 'hello fred!'\n *\n * // Use the HTML \"escape\" delimiter to escape data property values.\n * var compiled = _.template('<%- value %>');\n * compiled({ 'value': '\\r\\n\\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 78 */\n/***/ function(module, exports) {\n\n\t/*\r\n\t\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\t\tAuthor Tobias Koppers @sokra\r\n\t*/\r\n\t// css base code, injected by the css-loader\r\n\tmodule.exports = function() {\r\n\t\tvar list = [];\r\n\t\r\n\t\t// return the list of modules as css string\r\n\t\tlist.toString = function toString() {\r\n\t\t\tvar result = [];\r\n\t\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\t\tvar item = this[i];\r\n\t\t\t\tif(item[2]) {\r\n\t\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t\t} else {\r\n\t\t\t\t\tresult.push(item[1]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result.join(\"\");\r\n\t\t};\r\n\t\r\n\t\t// import a list of modules into the list\r\n\t\tlist.i = function(modules, mediaQuery) {\r\n\t\t\tif(typeof modules === \"string\")\r\n\t\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\t\tvar alreadyImportedModules = {};\r\n\t\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\t\tvar id = this[i][0];\r\n\t\t\t\tif(typeof id === \"number\")\r\n\t\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t\t}\r\n\t\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\t\tvar item = modules[i];\r\n\t\t\t\t// skip already imported module\r\n\t\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlist.push(item);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\t\treturn list;\r\n\t};\r\n\n\n/***/ },\n/* 79 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/*\n\t\tMIT License http://www.opensource.org/licenses/mit-license.php\n\t\tAuthor Tobias Koppers @sokra\n\t*/\n\tvar stylesInDom = {},\n\t\tmemoize = function(fn) {\n\t\t\tvar memo;\n\t\t\treturn function () {\n\t\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\t\t\treturn memo;\n\t\t\t};\n\t\t},\n\t\tisOldIE = memoize(function() {\n\t\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\n\t\t}),\n\t\tgetHeadElement = memoize(function () {\n\t\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\n\t\t}),\n\t\tsingletonElement = null,\n\t\tsingletonCounter = 0,\n\t\tstyleElementsInsertedAtTop = [];\n\t\n\tmodule.exports = function(list, options) {\n\t\tif(false) {\n\t\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t\t}\n\t\n\t\toptions = options || {};\n\t\t// Force single-tag solution on IE6-9, which has a hard limit on the # of \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 85 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t header: { type: String },\n\t placement: { type: String, default: 'right' },\n\t show: { type: Boolean, required: true },\n\t width: { type: Number, default: 320 }\n\t },\n\t watch: {\n\t show: function show(val, old) {\n\t var _this = this;\n\t\n\t this.$emit('input', val);\n\t this.$emit(this.show ? 'open' : 'close');\n\t var body = document.body;\n\t var scrollBarWidth = (0, _utils.getScrollBarWidth)();\n\t if (val) {\n\t if (!this._backdrop) {\n\t this._backdrop = document.createElement('div');\n\t }\n\t this._backdrop.className = 'aside-backdrop';\n\t body.appendChild(this._backdrop);\n\t body.classList.add('modal-open');\n\t if (scrollBarWidth !== 0) {\n\t body.style.paddingRight = scrollBarWidth + 'px';\n\t }\n\t // request property that requires layout to force a layout\n\t var x = this._backdrop.clientHeight;\n\t this._backdrop.classList.add('in');\n\t (0, _NodeList2.default)(this._backdrop).on('click', function () {\n\t return _this.trigger_close();\n\t });\n\t } else {\n\t (0, _NodeList2.default)(this._backdrop).on('transitionend', function () {\n\t (0, _NodeList2.default)(_this._backdrop).off();\n\t try {\n\t body.classList.remove('modal-open');\n\t body.style.paddingRight = '0';\n\t body.removeChild(_this._backdrop);\n\t _this._backdrop = null;\n\t } catch (e) {}\n\t });\n\t this._backdrop.className = 'aside-backdrop';\n\t }\n\t }\n\t },\n\t methods: {\n\t trigger: function trigger() {\n\t var _this2 = this;\n\t\n\t return {\n\t close: function close() {\n\t return _this2.trigger_close();\n\t },\n\t open: function open() {\n\t return _this2.trigger_open();\n\t }\n\t };\n\t },\n\t trigger_close: function trigger_close() {\n\t this.$emit('close');\n\t },\n\t trigger_open: function trigger_open() {\n\t this.$emit('open');\n\t }\n\t },\n\t mounted: function mounted() {\n\t var _this3 = this;\n\t\n\t this.$emit('trigger', function () {\n\t return _this3.trigger;\n\t });\n\t }\n\t};\n\n/***/ },\n/* 86 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('transition', {\n\t attrs: {\n\t \"name\": 'slide' + _vm.placement\n\t }\n\t }, [(_vm.show) ? _vm._c('div', {\n\t staticClass: \"aside\",\n\t class: _vm.placement,\n\t style: ({\n\t width: _vm.width + 'px'\n\t })\n\t }, [_vm._c('div', {\n\t staticClass: \"aside-dialog\"\n\t }, [_vm._c('div', {\n\t staticClass: \"aside-content\"\n\t }, [_vm._c('div', {\n\t staticClass: \"aside-header\"\n\t }, [_vm._c('button', {\n\t staticClass: \"close\",\n\t attrs: {\n\t \"type\": \"button\"\n\t },\n\t on: {\n\t \"click\": _vm.trigger_close\n\t }\n\t }, [_vm._c('span', [_vm._v(\"×\")])]), _vm._v(\" \"), _vm._c('h4', {\n\t staticClass: \"aside-title\"\n\t }, [_vm._t(\"header\", [_vm._v(_vm._s(_vm.header))])], 2)]), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"aside-body\"\n\t }, [_vm._t(\"default\")], 2)])])]) : _vm._e()])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-3a4bde27\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 87 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(88)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(89)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\ButtonGroup.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-125eb0c8\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-125eb0c8\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] ButtonGroup.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 88 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t buttons: { type: Boolean, default: true },\n\t disabled: { type: Boolean, default: false },\n\t justified: { type: Boolean, default: false },\n\t type: { type: String, default: 'default' },\n\t value: { default: null },\n\t vertical: { type: Boolean, default: false }\n\t },\n\t computed: {\n\t btnGroup: function btnGroup() {\n\t return !this.disabled;\n\t }\n\t },\n\t data: function data() {\n\t return {\n\t val: this.value\n\t };\n\t },\n\t\n\t watch: {\n\t // this will update EXTERNAL v-model when our val changes\n\t val: function val(_val) {\n\t this.$emit('input', _val);\n\t },\n\t\n\t // this will update our INTERNAL val, when something external changes our v-model\n\t value: function value(val) {\n\t this.val = val;\n\t }\n\t }\n\t};\n\n/***/ },\n/* 89 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t class: {\n\t 'btn-group': _vm.buttons, 'btn-group-justified': _vm.justified, 'btn-group-vertical': _vm.vertical\n\t },\n\t attrs: {\n\t \"data-toggle\": _vm.buttons && 'buttons'\n\t }\n\t }, [_vm._t(\"default\")], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-125eb0c8\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 90 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(91)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(93)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(94)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Carousel.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t__vue_options__._scopeId = \"data-v-322dee41\"\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-322dee41\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-322dee41\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Carousel.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 91 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 93 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// let coerce = {\n\t// interval: 'number'\n\t// }\n\t\n\texports.default = {\n\t props: {\n\t indicators: {\n\t type: Boolean,\n\t default: true\n\t },\n\t controls: {\n\t type: Boolean,\n\t default: true\n\t },\n\t interval: {\n\t type: Number,\n\t default: 5000\n\t }\n\t },\n\t data: function data() {\n\t return {\n\t indicator_list: [],\n\t index: 0,\n\t isAnimating: false\n\t };\n\t },\n\t\n\t watch: {\n\t index: function index(newVal, oldVal) {\n\t this.slide(newVal > oldVal ? 'left' : 'right', newVal, oldVal);\n\t }\n\t },\n\t methods: {\n\t indicatorClick: function indicatorClick(index) {\n\t if (this.isAnimating || this.index === index) return false;\n\t this.isAnimating = true;\n\t this.index = index;\n\t },\n\t slide: function slide(direction, next, prev) {\n\t var _this = this;\n\t\n\t if (!this.$el) {\n\t return;\n\t }\n\t var $slider = (0, _NodeList2.default)('.item', this.$el);\n\t if (!$slider.length) {\n\t return;\n\t }\n\t var selected = $slider[next] || $slider[0];\n\t (0, _NodeList2.default)(selected).addClass(direction === 'left' ? 'next' : 'prev');\n\t // request property that requires layout to force a layout\n\t var x = selected.clientHeight;\n\t (0, _NodeList2.default)([$slider[prev], selected]).addClass(direction).on('transitionend', function () {\n\t $slider.off('transitionend').className = 'item';\n\t (0, _NodeList2.default)(selected).addClass('active');\n\t _this.isAnimating = false;\n\t });\n\t },\n\t next: function next() {\n\t if (!this.$el || this.isAnimating) {\n\t return false;\n\t }\n\t this.isAnimating = true;\n\t this.index + 1 < (0, _NodeList2.default)('.item', this.$el).length ? this.index += 1 : this.index = 0;\n\t },\n\t prev: function prev() {\n\t if (!this.$el || this.isAnimating) {\n\t return false;\n\t }\n\t this.isAnimating = true;\n\t this.index === 0 ? this.index = (0, _NodeList2.default)('.item', this.$el).length - 1 : this.index -= 1;\n\t },\n\t toggleInterval: function toggleInterval(val) {\n\t if (val === undefined) {\n\t val = this._intervalID;\n\t }\n\t if (this._intervalID) {\n\t clearInterval(this._intervalID);\n\t delete this._intervalID;\n\t }\n\t if (val && this.interval > 0) {\n\t this._intervalID = setInterval(this.next, this.interval);\n\t }\n\t }\n\t },\n\t mounted: function mounted() {\n\t var _this2 = this;\n\t\n\t this.toggleInterval(true);\n\t (0, _NodeList2.default)(this.$el).on('mouseenter', function () {\n\t return _this2.toggleInterval(false);\n\t }).on('mouseleave', function () {\n\t return _this2.toggleInterval(true);\n\t });\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t this.toggleInterval(false);\n\t (0, _NodeList2.default)(this.$el).off('mouseenter mouseleave');\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 94 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t staticClass: \"carousel slide\",\n\t attrs: {\n\t \"data-ride\": \"carousel\"\n\t }\n\t }, [_vm._c('ol', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.indicators),\n\t expression: \"indicators\"\n\t }],\n\t staticClass: \"carousel-indicators\"\n\t }, _vm._l((_vm.indicator_list), function(indicator, i) {\n\t return _vm._c('li', {\n\t class: {\n\t active: i === _vm.index\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.indicatorClick(i)\n\t }\n\t }\n\t }, [_vm._c('span')])\n\t })), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"carousel-inner\",\n\t attrs: {\n\t \"role\": \"listbox\"\n\t }\n\t }, [_vm._t(\"default\")], 2), _vm._v(\" \"), _vm._c('div', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.controls),\n\t expression: \"controls\"\n\t }],\n\t staticClass: \"carousel-controls hidden-xs\"\n\t }, [_vm._c('a', {\n\t staticClass: \"left carousel-control\",\n\t attrs: {\n\t \"role\": \"button\"\n\t },\n\t on: {\n\t \"click\": _vm.prev\n\t }\n\t }, [_vm._c('span', {\n\t staticClass: \"glyphicon glyphicon-chevron-left\",\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t }\n\t })]), _vm._v(\" \"), _vm._c('a', {\n\t staticClass: \"right carousel-control\",\n\t attrs: {\n\t \"role\": \"button\"\n\t },\n\t on: {\n\t \"click\": _vm.next\n\t }\n\t }, [_vm._c('span', {\n\t staticClass: \"glyphicon glyphicon-chevron-right\",\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t }\n\t })])])])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-322dee41\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 95 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(96)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(98)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(99)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Checkbox.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t__vue_options__._scopeId = \"data-v-6922bf24\"\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-6922bf24\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-6922bf24\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Checkbox.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 96 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 98 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t button: { type: Boolean, default: false },\n\t disabled: { type: Boolean, default: false },\n\t falseValue: { default: false },\n\t name: { type: String, default: null },\n\t readonly: { type: Boolean, default: false },\n\t trueValue: { default: true },\n\t type: { type: String, default: null },\n\t value: { default: false }\n\t },\n\t data: function data() {\n\t return {\n\t checked: this.value === this.trueValue\n\t };\n\t },\n\t\n\t computed: {\n\t inGroup: function inGroup() {\n\t return this.$parent && this.$parent.btnGroup && !this.$parent._radioGroup;\n\t },\n\t isButton: function isButton() {\n\t return this.button || this.$parent && this.$parent.btnGroup && this.$parent.buttons;\n\t },\n\t isFalse: function isFalse() {\n\t return this.value === this.falseValue;\n\t },\n\t isTrue: function isTrue() {\n\t return this.value === this.trueValue;\n\t },\n\t parentValue: function parentValue() {\n\t return this.$parent.val;\n\t },\n\t typeColor: function typeColor() {\n\t return this.type || this.$parent && this.$parent.type || 'default';\n\t }\n\t },\n\t watch: {\n\t checked: function checked(val, old) {\n\t var value = val ? this.trueValue : this.falseValue;\n\t this.$emit('checked', val);\n\t this.$emit('input', value);\n\t this.updateParent();\n\t },\n\t parentValue: function parentValue(val) {\n\t this.updateFromParent();\n\t },\n\t value: function value(val, old) {\n\t var checked = val === this.trueValue;\n\t if (this.checked !== checked) {\n\t this.checked = checked;\n\t }\n\t }\n\t },\n\t created: function created() {\n\t if (this.inGroup) {\n\t var parent = this.$parent;\n\t parent._checkboxGroup = true;\n\t if (!(parent.val instanceof Array)) {\n\t parent.val = [];\n\t }\n\t }\n\t },\n\t mounted: function mounted() {\n\t this.updateFromParent();\n\t },\n\t\n\t methods: {\n\t // called @ mounted(), or whenever $parent.val changes\n\t // sync our state with the $parent.val\n\t updateFromParent: function updateFromParent() {\n\t if (this.inGroup) {\n\t var index = this.$parent.val.indexOf(this.trueValue);\n\t this.checked = ~index;\n\t }\n\t },\n\t\n\t // called when our checked state changes\n\t updateParent: function updateParent() {\n\t if (this.inGroup) {\n\t var index = this.$parent.val.indexOf(this.trueValue);\n\t if (this.checked && !~index) this.$parent.val.push(this.trueValue);\n\t if (!this.checked && ~index) this.$parent.val.splice(index, 1);\n\t }\n\t },\n\t toggle: function toggle() {\n\t if (this.disabled || this.readonly) {\n\t return;\n\t }\n\t this.checked = !this.checked;\n\t }\n\t }\n\t};\n\n/***/ },\n/* 99 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c(_vm.isButton ? 'a' : 'label', {\n\t tag: \"a\",\n\t class: [_vm.isButton ? 'btn btn-' + _vm.typeColor : 'open checkbox ' + _vm.typeColor, {\n\t active: _vm.checked,\n\t disabled: _vm.disabled,\n\t readonly: _vm.readonly\n\t }],\n\t on: {\n\t \"click\": _vm.toggle\n\t }\n\t }, [(_vm.name) ? _vm._c('input', {\n\t attrs: {\n\t \"type\": \"hidden\",\n\t \"name\": _vm.name\n\t },\n\t domProps: {\n\t \"value\": _vm.checked ? _vm.trueValue : _vm.falseValue\n\t }\n\t }) : _vm._e(), _vm._v(\" \"), (!_vm.isButton) ? _vm._c('span', {\n\t staticClass: \"icon dropdown-toggle\",\n\t class: [_vm.checked ? 'btn-' + _vm.typeColor : '', {\n\t bg: _vm.typeColor === 'default'\n\t }]\n\t }) : _vm._e(), _vm._v(\" \"), (!_vm.isButton && _vm.checked && _vm.typeColor === 'default') ? _vm._c('span', {\n\t staticClass: \"icon\"\n\t }) : _vm._e(), _vm._v(\" \"), _vm._t(\"default\")], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-6922bf24\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 100 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(101)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(103)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(104)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Datepicker.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-477b8e5d\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-477b8e5d\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Datepicker.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 101 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 103 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\t// import $ from './utils/NodeList.js'\n\t\n\texports.default = {\n\t props: {\n\t value: { type: String },\n\t format: { default: 'MM/dd/yyyy' },\n\t disabledDaysOfWeek: { type: Array, default: function _default() {\n\t return [];\n\t }\n\t },\n\t width: { type: String },\n\t clearButton: { type: Boolean, default: false },\n\t lang: { type: String, default: navigator.language },\n\t placeholder: { type: String },\n\t iconsFont: { type: String, default: 'glyphicon' }\n\t },\n\t data: function data() {\n\t return {\n\t currDate: new Date(),\n\t dateRange: [],\n\t decadeRange: [],\n\t displayDayView: false,\n\t displayMonthView: false,\n\t displayYearView: false,\n\t val: this.value\n\t };\n\t },\n\t\n\t watch: {\n\t currDate: function currDate() {\n\t this.getDateRange();\n\t },\n\t format: function format() {\n\t this.val = this.stringify(this.currDate);\n\t },\n\t val: function val(_val, old) {\n\t this.$emit('input', _val);\n\t },\n\t value: function value(val) {\n\t if (this.val !== val) {\n\t this.val = val;\n\t }\n\t }\n\t },\n\t computed: {\n\t text: function text() {\n\t return (0, _utils.translations)(this.lang);\n\t },\n\t preBtnClasses: function preBtnClasses() {\n\t return 'datepicker-preBtn ' + this.iconsFont + ' ' + this.iconsFont + '-chevron-left';\n\t },\n\t nextBtnClasses: function nextBtnClasses() {\n\t return 'datepicker-nextBtn ' + this.iconsFont + ' ' + this.iconsFont + '-chevron-right';\n\t },\n\t disabledDaysArray: function disabledDaysArray() {\n\t return this.disabledDaysOfWeek.map(function (d) {\n\t return parseInt(d, 10);\n\t });\n\t }\n\t },\n\t methods: {\n\t close: function close() {\n\t this.displayDayView = this.displayMonthView = this.displayYearView = false;\n\t },\n\t inputClick: function inputClick() {\n\t this.currDate = this.parse(this.val) || this.parse(new Date());\n\t if (this.displayMonthView || this.displayYearView) {\n\t this.displayDayView = false;\n\t } else {\n\t this.displayDayView = !this.displayDayView;\n\t }\n\t },\n\t preNextDecadeClick: function preNextDecadeClick(flag) {\n\t var year = this.currDate.getFullYear();\n\t var months = this.currDate.getMonth();\n\t var date = this.currDate.getDate();\n\t\n\t if (flag === 0) {\n\t this.currDate = new Date(year - 10, months, date);\n\t } else {\n\t this.currDate = new Date(year + 10, months, date);\n\t }\n\t },\n\t preNextMonthClick: function preNextMonthClick(flag) {\n\t var year = this.currDate.getFullYear();\n\t var month = this.currDate.getMonth();\n\t var date = this.currDate.getDate();\n\t\n\t if (flag === 0) {\n\t var preMonth = this.getYearMonth(year, month - 1);\n\t this.currDate = new Date(preMonth.year, preMonth.month, date);\n\t } else {\n\t var nextMonth = this.getYearMonth(year, month + 1);\n\t this.currDate = new Date(nextMonth.year, nextMonth.month, date);\n\t }\n\t },\n\t preNextYearClick: function preNextYearClick(flag) {\n\t var year = this.currDate.getFullYear();\n\t var months = this.currDate.getMonth();\n\t var date = this.currDate.getDate();\n\t\n\t if (flag === 0) {\n\t this.currDate = new Date(year - 1, months, date);\n\t } else {\n\t this.currDate = new Date(year + 1, months, date);\n\t }\n\t },\n\t yearSelect: function yearSelect(year) {\n\t this.displayYearView = false;\n\t this.displayMonthView = true;\n\t this.currDate = new Date(year, this.currDate.getMonth(), this.currDate.getDate());\n\t },\n\t daySelect: function daySelect(day) {\n\t if (day.sclass === 'datepicker-item-disable') {\n\t return false;\n\t } else {\n\t this.currDate = day.date;\n\t this.val = this.stringify(this.currDate);\n\t this.displayDayView = false;\n\t }\n\t },\n\t switchMonthView: function switchMonthView() {\n\t this.displayDayView = false;\n\t this.displayMonthView = true;\n\t },\n\t switchDecadeView: function switchDecadeView() {\n\t this.displayMonthView = false;\n\t this.displayYearView = true;\n\t },\n\t monthSelect: function monthSelect(index) {\n\t this.displayMonthView = false;\n\t this.displayDayView = true;\n\t this.currDate = new Date(this.currDate.getFullYear(), index, this.currDate.getDate());\n\t },\n\t getYearMonth: function getYearMonth(year, month) {\n\t if (month > 11) {\n\t year++;\n\t month = 0;\n\t } else if (month < 0) {\n\t year--;\n\t month = 11;\n\t }\n\t return { year: year, month: month };\n\t },\n\t stringifyDecadeHeader: function stringifyDecadeHeader(date) {\n\t var yearStr = date.getFullYear().toString();\n\t var firstYearOfDecade = yearStr.substring(0, yearStr.length - 1) + 0;\n\t var lastYearOfDecade = parseInt(firstYearOfDecade, 10) + 10;\n\t return firstYearOfDecade + '-' + lastYearOfDecade;\n\t },\n\t stringifyDayHeader: function stringifyDayHeader(date) {\n\t return this.text.months[date.getMonth()] + ' ' + date.getFullYear();\n\t },\n\t parseMonth: function parseMonth(date) {\n\t return this.text.months[date.getMonth()];\n\t },\n\t stringifyYearHeader: function stringifyYearHeader(date) {\n\t return date.getFullYear();\n\t },\n\t stringify: function stringify(date) {\n\t var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.format;\n\t\n\t if (!date) date = this.parse();\n\t if (!date) return '';\n\t var year = date.getFullYear();\n\t var month = date.getMonth() + 1;\n\t var day = date.getDate();\n\t var monthName = this.parseMonth(date);\n\t return format.replace(/yyyy/g, year).replace(/yy/g, year).replace(/MMMM/g, monthName).replace(/MMM/g, monthName.substring(0, 3)).replace(/MM/g, ('0' + month).slice(-2)).replace(/M(?!a)/g, month).replace(/dd/g, ('0' + day).slice(-2)).replace(/d/g, day);\n\t },\n\t parse: function parse(str) {\n\t if (str === undefined || str === null) {\n\t str = this.val;\n\t }\n\t var date = str.length === 10 && (this.format === 'dd-MM-yyyy' || this.format === 'dd/MM/yyyy') ? new Date(str.substring(6, 10), str.substring(3, 5) - 1, str.substring(0, 2)) : new Date(str);\n\t return isNaN(date.getFullYear()) ? new Date() : date;\n\t },\n\t getDayCount: function getDayCount(year, month) {\n\t var dict = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\t if (month === 1) {\n\t if (year % 400 === 0 || year % 4 === 0 && year % 100 !== 0) {\n\t return 29;\n\t }\n\t }\n\t return dict[month];\n\t },\n\t getDateRange: function getDateRange() {\n\t this.dateRange = [];\n\t this.decadeRange = [];\n\t var time = {\n\t year: this.currDate.getFullYear(),\n\t month: this.currDate.getMonth(),\n\t day: this.currDate.getDate()\n\t };\n\t var yearStr = time.year.toString();\n\t var firstYearOfDecade = yearStr.substring(0, yearStr.length - 1) + 0 - 1;\n\t for (var i = 0; i < 12; i++) {\n\t this.decadeRange.push({\n\t text: firstYearOfDecade + i\n\t });\n\t }\n\t\n\t var currMonthFirstDay = new Date(time.year, time.month, 1);\n\t var firstDayWeek = currMonthFirstDay.getDay() + 1;\n\t if (firstDayWeek === 0) {\n\t firstDayWeek = 7;\n\t }\n\t var dayCount = this.getDayCount(time.year, time.month);\n\t if (firstDayWeek > 1) {\n\t var preMonth = this.getYearMonth(time.year, time.month - 1);\n\t var prevMonthDayCount = this.getDayCount(preMonth.year, preMonth.month);\n\t for (var _i = 1; _i < firstDayWeek; _i++) {\n\t var dayText = prevMonthDayCount - firstDayWeek + _i + 1;\n\t var date = new Date(preMonth.year, preMonth.month, dayText);\n\t var sclass = 'datepicker-item-gray';\n\t if (this.disabledDaysArray.indexOf(date.getDay()) > -1) {\n\t sclass = 'datepicker-item-disable';\n\t }\n\t this.dateRange.push({ text: dayText, date: date, sclass: sclass });\n\t }\n\t }\n\t\n\t for (var _i2 = 1; _i2 <= dayCount; _i2++) {\n\t var _date = new Date(time.year, time.month, _i2);\n\t var _sclass = '';\n\t if (this.disabledDaysArray.indexOf(_date.getDay()) > -1) {\n\t _sclass = 'datepicker-item-disable';\n\t }\n\t if (_i2 == time.day && _date.getFullYear() == time.year && _date.getMonth() == time.month) {\n\t _sclass = 'datepicker-dateRange-item-active';\n\t }\n\t this.dateRange.push({ text: _i2, date: _date, sclass: _sclass });\n\t }\n\t\n\t if (this.dateRange.length < 42) {\n\t var nextMonthNeed = 42 - this.dateRange.length;\n\t var nextMonth = this.getYearMonth(time.year, time.month + 1);\n\t\n\t for (var _i3 = 1; _i3 <= nextMonthNeed; _i3++) {\n\t var _date2 = new Date(nextMonth.year, nextMonth.month, _i3);\n\t var _sclass2 = 'datepicker-item-gray';\n\t if (this.disabledDaysArray.indexOf(_date2.getDay()) > -1) {\n\t _sclass2 = 'datepicker-item-disable';\n\t }\n\t this.dateRange.push({ text: _i3, date: _date2, sclass: _sclass2 });\n\t }\n\t }\n\t }\n\t },\n\t mounted: function mounted() {\n\t var _this = this;\n\t\n\t this.$emit('child-created', this);\n\t this.currDate = this.parse(this.val) || this.parse(new Date());\n\t this._blur = function (e) {\n\t if (!_this.$el.contains(e.target)) _this.close();\n\t };\n\t window.addEventListener('click', this._blur);\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t window.removeEventListener('click', this._blur);\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 104 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t staticClass: \"datepicker\"\n\t }, [_vm._c('input', {\n\t directives: [{\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.val),\n\t expression: \"val\"\n\t }],\n\t staticClass: \"form-control datepicker-input\",\n\t class: {\n\t 'with-reset-button': _vm.clearButton\n\t },\n\t style: ({\n\t width: _vm.width\n\t }),\n\t attrs: {\n\t \"type\": \"text\",\n\t \"placeholder\": _vm.placeholder\n\t },\n\t domProps: {\n\t \"value\": _vm._s(_vm.val)\n\t },\n\t on: {\n\t \"click\": _vm.inputClick,\n\t \"input\": function($event) {\n\t if ($event.target.composing) { return; }\n\t _vm.val = $event.target.value\n\t }\n\t }\n\t }), _vm._v(\" \"), (_vm.clearButton && _vm.val) ? _vm._c('button', {\n\t staticClass: \"close\",\n\t attrs: {\n\t \"type\": \"button\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.val = ''\n\t }\n\t }\n\t }, [_vm._c('span', [_vm._v(\"×\")])]) : _vm._e(), _vm._v(\" \"), _vm._c('div', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.displayDayView),\n\t expression: \"displayDayView\"\n\t }],\n\t staticClass: \"datepicker-popup\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-inner\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-body\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-ctrl\"\n\t }, [_vm._c('span', {\n\t class: _vm.preBtnClasses,\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.preNextMonthClick(0)\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t class: _vm.nextBtnClasses,\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.preNextMonthClick(1)\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('p', {\n\t on: {\n\t \"click\": _vm.switchMonthView\n\t }\n\t }, [_vm._v(_vm._s(_vm.stringifyDayHeader(_vm.currDate)))])]), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"datepicker-weekRange\"\n\t }, _vm._l((_vm.text.daysOfWeek), function(w) {\n\t return _vm._c('span', [_vm._v(_vm._s(w))])\n\t })), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"datepicker-dateRange\"\n\t }, _vm._l((_vm.dateRange), function(d) {\n\t return _vm._c('span', {\n\t class: d.sclass,\n\t on: {\n\t \"click\": function($event) {\n\t _vm.daySelect(d)\n\t }\n\t }\n\t }, [_vm._v(_vm._s(d.text))])\n\t }))])])]), _vm._v(\" \"), _vm._c('div', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.displayMonthView),\n\t expression: \"displayMonthView\"\n\t }],\n\t staticClass: \"datepicker-popup\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-inner\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-body\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-ctrl\"\n\t }, [_vm._c('span', {\n\t class: _vm.preBtnClasses,\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.preNextYearClick(0)\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t class: _vm.nextBtnClasses,\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.preNextYearClick(1)\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('p', {\n\t on: {\n\t \"click\": _vm.switchDecadeView\n\t }\n\t }, [_vm._v(_vm._s(_vm.stringifyYearHeader(_vm.currDate)))])]), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"datepicker-monthRange\"\n\t }, [_vm._l((_vm.text.months), function(m, index) {\n\t return [_vm._c('span', {\n\t class: {\n\t 'datepicker-dateRange-item-active':\n\t (_vm.text.months[_vm.parse(_vm.val).getMonth()] === m) &&\n\t _vm.currDate.getFullYear() === _vm.parse(_vm.val).getFullYear()\n\t },\n\t domProps: {\n\t \"textContent\": _vm._s(m.substr(0, 3))\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.monthSelect(index)\n\t }\n\t }\n\t })]\n\t })], 2)])])]), _vm._v(\" \"), _vm._c('div', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.displayYearView),\n\t expression: \"displayYearView\"\n\t }],\n\t staticClass: \"datepicker-popup\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-inner\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-body\"\n\t }, [_vm._c('div', {\n\t staticClass: \"datepicker-ctrl\"\n\t }, [_vm._c('span', {\n\t class: _vm.preBtnClasses,\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.preNextDecadeClick(0)\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t class: _vm.nextBtnClasses,\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.preNextDecadeClick(1)\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('p', [_vm._v(_vm._s(_vm.stringifyDecadeHeader(_vm.currDate)))])]), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"datepicker-monthRange decadeRange\"\n\t }, [_vm._l((_vm.decadeRange), function(decade) {\n\t return [_vm._c('span', {\n\t class: {\n\t 'datepicker-dateRange-item-active': _vm.parse(_vm.val).getFullYear() === decade.text\n\t },\n\t domProps: {\n\t \"textContent\": _vm._s(decade.text)\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t $event.stopPropagation();\n\t _vm.yearSelect(decade.text)\n\t }\n\t }\n\t })]\n\t })], 2)])])])])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-477b8e5d\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 105 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(106)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(107)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Dropdown.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-39be1072\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-39be1072\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Dropdown.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 106 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tvar _ClickOutside = __webpack_require__(66);\n\t\n\tvar _ClickOutside2 = _interopRequireDefault(_ClickOutside);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t directives: {\n\t ClickOutside: _ClickOutside2.default\n\t },\n\t props: {\n\t disabled: { type: Boolean, default: false },\n\t size: { type: String, default: null },\n\t text: { type: String, default: null },\n\t type: { type: String, default: 'default' },\n\t value: { type: Boolean, default: false }\n\t },\n\t data: function data() {\n\t var show = this.value;\n\t return { show: show };\n\t },\n\t\n\t watch: {\n\t show: function show(val) {\n\t this.$emit('input', val);\n\t },\n\t value: function value(val) {\n\t this.show = val;\n\t }\n\t },\n\t computed: {\n\t buttonSize: function buttonSize() {\n\t return ~['lg', 'sm', 'xs'].indexOf(this.size) ? 'btn-' + this.size : '';\n\t },\n\t inInput: function inInput() {\n\t return this.$parent._input;\n\t },\n\t isLi: function isLi() {\n\t return this.$parent._isTabs || this.$parent._navbar || this.$parent.menu;\n\t },\n\t menu: function menu() {\n\t return !this.$parent || this.$parent.navbar;\n\t },\n\t slots: function slots() {\n\t return this._slotContents;\n\t },\n\t submenu: function submenu() {\n\t return this.$parent && (this.$parent.menu || this.$parent.submenu);\n\t }\n\t },\n\t methods: {\n\t blur: function blur() {\n\t this.show = false;\n\t },\n\t toggle: function toggle() {\n\t if (!this.disabled) {\n\t this.show = !this.show;\n\t }\n\t }\n\t },\n\t mounted: function mounted() {\n\t var _this = this;\n\t\n\t (0, _NodeList2.default)('ul', this.$el).on('click', 'li>a', function (e) {\n\t _this.show = false;\n\t });\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t (0, _NodeList2.default)('ul', this.$el).off();\n\t }\n\t};\n\n/***/ },\n/* 107 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c(_vm.isLi ? 'li' : 'div', {\n\t directives: [{\n\t name: \"click-outside\",\n\t rawName: \"v-click-outside\",\n\t value: (_vm.blur),\n\t expression: \"blur\"\n\t }],\n\t tag: \"div\",\n\t class: [{\n\t open: _vm.show,\n\t disabled: _vm.disabled,\n\t dropdown: _vm.isLi,\n\t 'input-group-btn': _vm.inInput,\n\t 'btn-group': !_vm.isLi && !_vm.inInput\n\t }]\n\t }, [_vm._t(\"before\"), _vm._v(\" \"), (_vm.isLi) ? _vm._c('a', {\n\t class: ['dropdown-toggle', _vm.buttonSize, {\n\t disabled: _vm.disabled\n\t }],\n\t attrs: {\n\t \"role\": \"button\"\n\t },\n\t on: {\n\t \"keyup\": function($event) {\n\t if (_vm._k($event.keyCode, \"esc\", 27)) { return; }\n\t _vm.show = false\n\t },\n\t \"click\": function($event) {\n\t $event.preventDefault();\n\t _vm.toggle($event)\n\t }\n\t }\n\t }, [_vm._t(\"button\", [_vm._v(_vm._s(_vm.text))]), _vm._v(\" \"), _vm._c('span', {\n\t staticClass: \"caret\"\n\t })], 2) : _vm._c('button', {\n\t class: ['btn btn-' + _vm.type, _vm.buttonSize, 'dropdown-toggle'],\n\t attrs: {\n\t \"type\": \"button\",\n\t \"disabled\": _vm.disabled\n\t },\n\t on: {\n\t \"keyup\": function($event) {\n\t if (_vm._k($event.keyCode, \"esc\", 27)) { return; }\n\t _vm.show = false\n\t },\n\t \"click\": function($event) {\n\t $event.preventDefault();\n\t _vm.toggle($event)\n\t }\n\t }\n\t }, [_vm._t(\"button\", [_vm._v(_vm._s(_vm.text))]), _vm._v(\" \"), _vm._c('span', {\n\t staticClass: \"caret\"\n\t })], 2), _vm._v(\" \"), _vm._t(\"dropdown-menu\", [_vm._c('ul', {\n\t staticClass: \"dropdown-menu\"\n\t }, [_vm._t(\"default\")], 2)])], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-39be1072\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 108 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(109)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(110)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\FormGroup.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-79eb400a\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-79eb400a\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] FormGroup.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 109 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// let coerce = {\n\t// enterSubmit: 'boolean',\n\t// icon: 'boolean'\n\t// }\n\t\n\texports.default = {\n\t props: {\n\t enterSubmit: {\n\t type: Boolean,\n\t default: false\n\t },\n\t icon: {\n\t type: Boolean,\n\t default: false\n\t },\n\t lang: {\n\t type: String,\n\t default: navigator.language\n\t }\n\t },\n\t data: function data() {\n\t return {\n\t children: [],\n\t valid: null,\n\t timeout: null\n\t };\n\t },\n\t\n\t watch: {\n\t valid: function valid(val, old) {\n\t this.$emit('isvalid', val);\n\t this.$emit(!val ? 'invalid' : 'valid');\n\t if (val !== old && this._parent) this._parent.validate();\n\t }\n\t },\n\t methods: {\n\t validate: function validate() {\n\t var valid = true;\n\t this.children.some(function (el) {\n\t var v = el.validate ? el.validate() : el.valid !== undefined ? el.valid : el.required && !~['', null, undefined].indexOf(el.value);\n\t if (!v) valid = false;\n\t return !valid;\n\t });\n\t this.valid = valid;\n\t return valid === true;\n\t }\n\t },\n\t created: function created() {\n\t this._formGroup = true;\n\t var parent = this.$parent;\n\t while (parent && !parent._formGroup) {\n\t parent = parent.$parent;\n\t }\n\t if (parent && parent._formGroup) {\n\t parent.children.push(this);\n\t this._parent = parent;\n\t }\n\t },\n\t mounted: function mounted() {\n\t this.validate();\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t if (this._parent) {\n\t var index = this._parent.children.indexOf(this);\n\t this._parent.children.splice(index, 1);\n\t }\n\t }\n\t}; //\n\t//\n\n/***/ },\n/* 110 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('span', [_vm._t(\"default\")], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-79eb400a\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 111 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(112)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(113)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\FormValidator.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-b9f57c46\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-b9f57c46\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] FormValidator.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 112 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = {\n\t props: {\n\t enterSubmit: { type: Boolean, default: false },\n\t icon: { type: Boolean, default: false },\n\t lang: { type: String, default: navigator.language },\n\t value: null\n\t },\n\t data: function data() {\n\t return {\n\t children: [],\n\t valid: null,\n\t timeout: null\n\t };\n\t },\n\t\n\t watch: {\n\t valid: function valid(val, old) {\n\t this.$emit('isvalid', val);\n\t this.$emit('input', val);\n\t this.$emit(!val ? 'invalid' : 'valid');\n\t if (val !== old && this._parent) this._parent.validate();\n\t }\n\t },\n\t methods: {\n\t validate: function validate() {\n\t var invalid = !this.children.every(function (el) {\n\t return el.validate ? el.validate() : el.valid !== undefined ? el.valid : el.required && !~['', null, undefined].indexOf(el.value);\n\t });\n\t this.valid = !invalid;\n\t return !invalid;\n\t }\n\t },\n\t created: function created() {\n\t this._formValidator = true;\n\t var parent = this.$parent;\n\t while (parent && !parent._formValidator) {\n\t parent = parent.$parent;\n\t }\n\t if (parent && parent._formValidator) {\n\t parent.children.push(this);\n\t this._parent = parent;\n\t }\n\t },\n\t mounted: function mounted() {\n\t this.validate();\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t if (this._parent) {\n\t var index = this._parent.children.indexOf(this);\n\t this._parent.children.splice(index, 1);\n\t }\n\t }\n\t}; //\n\t//\n\n/***/ },\n/* 113 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('span', [_vm._t(\"default\")], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-b9f57c46\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 114 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(115)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(117)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(118)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Input.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t__vue_options__._scopeId = \"data-v-652ad7b9\"\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-652ad7b9\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-652ad7b9\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Input.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 115 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 117 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\tvar DELAY = 300;\n\t\n\texports.default = {\n\t props: {\n\t clearButton: { type: Boolean, default: false },\n\t cols: { type: Number, default: null },\n\t datalist: { type: Array, default: null },\n\t disabled: { type: Boolean, default: false },\n\t enterSubmit: { type: Boolean, default: false },\n\t error: { type: String, default: null },\n\t help: { type: String, default: null },\n\t hideHelp: { type: Boolean, default: true },\n\t icon: { type: Boolean, default: false },\n\t label: { type: String, default: null },\n\t lang: { type: String, default: navigator.language },\n\t mask: null,\n\t maskDelay: { type: Number, default: 100 },\n\t match: { type: String, default: null },\n\t max: { type: String, default: null },\n\t maxlength: { type: Number, default: null },\n\t min: { type: String, default: null },\n\t minlength: { type: Number, default: 0 },\n\t name: { type: String, default: null },\n\t pattern: { default: null },\n\t placeholder: { type: String, default: null },\n\t readonly: { type: Boolean, default: false },\n\t required: { type: Boolean, default: false },\n\t rows: { type: Number, default: 3 },\n\t step: { type: Number, default: null },\n\t type: { type: String, default: 'text' },\n\t url: { type: String, default: null },\n\t urlMap: { type: Function, default: null },\n\t validationDelay: { type: Number, default: 250 },\n\t value: { default: null }\n\t },\n\t data: function data() {\n\t var val = this.value;\n\t return {\n\t options: this.datalist,\n\t val: val,\n\t valid: null,\n\t timeout: null\n\t };\n\t },\n\t\n\t computed: {\n\t canValidate: function canValidate() {\n\t return !this.disabled && !this.readonly && (this.required || this.regex || this.nativeValidate || this.match !== null);\n\t },\n\t errorText: function errorText() {\n\t var value = this.value;\n\t var error = [this.error];\n\t if (!value && this.required) error.push('(' + this.text.required.toLowerCase() + ')');\n\t if (value && value.length < this.minlength) error.push('(' + this.text.minLength.toLowerCase() + ': ' + this.minlength + ')');\n\t return error.join(' ');\n\t },\n\t id_datalist: function id_datalist() {\n\t if (this.type !== 'textarea' && this.datalist instanceof Array) {\n\t if (!this._id_datalist) {\n\t if (!this.$root.id_datalist) {\n\t this.$root.id_datalist = 0;\n\t }\n\t this._id_datalist = 'input-datalist' + this.$root.id_datalist++;\n\t }\n\t return this._id_datalist;\n\t }\n\t return null;\n\t },\n\t input: function input() {\n\t return this.$refs.input;\n\t },\n\t nativeValidate: function nativeValidate() {\n\t return (this.input || {}).checkValidity && (~['url', 'email'].indexOf(this.type.toLowerCase()) || this.min || this.max);\n\t },\n\t regex: function regex() {\n\t return _utils.coerce.pattern(this.pattern);\n\t },\n\t showError: function showError() {\n\t return this.error && this.valid === false;\n\t },\n\t showHelp: function showHelp() {\n\t return this.help && (!this.showError || !this.hideHelp);\n\t },\n\t text: function text() {\n\t return (0, _utils.translations)(this.lang);\n\t },\n\t title: function title() {\n\t return this.errorText || this.help || '';\n\t }\n\t },\n\t watch: {\n\t datalist: function datalist(val, old) {\n\t if (val !== old && val instanceof Array) {\n\t this.options = val;\n\t }\n\t },\n\t match: function match(val) {\n\t this.eval();\n\t },\n\t options: function options(val, old) {\n\t if (val !== old) this.$emit('options', val);\n\t },\n\t url: function url(val) {\n\t this._url();\n\t },\n\t val: function val(_val, old) {\n\t var _this = this;\n\t\n\t this.$emit('input', _val);\n\t if (_val !== old) {\n\t if (this.mask instanceof Function) {\n\t _val = this.mask(_val || '');\n\t if (this.val !== _val) {\n\t if (this._timeout.mask) clearTimeout(this._timeout.mask);\n\t this._timeout.mask = setTimeout(function () {\n\t _this.val = _val;\n\t }, isNaN(this.maskDelay) ? 0 : this.maskDelay);\n\t }\n\t }\n\t this.eval();\n\t }\n\t },\n\t valid: function valid(val, old) {\n\t this.$emit('isvalid', val);\n\t this.$emit(!val ? 'invalid' : 'valid');\n\t if (this._parent) this._parent.validate();\n\t },\n\t value: function value(val) {\n\t if (this.val !== val) {\n\t this.val = val;\n\t }\n\t }\n\t },\n\t methods: {\n\t attr: function attr(value) {\n\t return ~['', null, undefined].indexOf(value) || value instanceof Function ? null : value;\n\t },\n\t emit: function emit(e) {\n\t this.$emit(e.type, e.type == 'input' ? e.target.value : e);\n\t if (e.type === 'blur' && this.canValidate) {\n\t this.valid = this.validate();\n\t }\n\t },\n\t eval: function _eval() {\n\t var _this2 = this;\n\t\n\t if (this._timeout.eval) clearTimeout(this._timeout.eval);\n\t if (!this.canValidate) {\n\t this.valid = true;\n\t } else {\n\t this._timeout.eval = setTimeout(function () {\n\t _this2.valid = _this2.validate();\n\t _this2._timeout.eval = null;\n\t }, this.validationDelay);\n\t }\n\t },\n\t focus: function focus() {\n\t this.input.focus();\n\t },\n\t submit: function submit() {\n\t if (this.$parent._formValidator) {\n\t return this.$parent.validate();\n\t }\n\t if (this.input.form) {\n\t var invalids = (0, _NodeList2.default)('.form-group.validate:not(.has-success)', this.input.form);\n\t if (invalids.length) {\n\t invalids.find('input,textarea,select')[0].focus();\n\t } else {\n\t this.input.form.submit();\n\t }\n\t }\n\t },\n\t validate: function validate() {\n\t if (!this.canValidate) {\n\t return true;\n\t }\n\t var value = (this.val || '').trim();\n\t if (!value) {\n\t return !this.required;\n\t }\n\t if (this.match !== null) {\n\t return this.match === value;\n\t }\n\t if (value.length < this.minlength) {\n\t return false;\n\t }\n\t if (this.nativeValidate && !this.input.checkValidity()) {\n\t return false;\n\t }\n\t if (this.regex) {\n\t if (!(this.regex instanceof Function ? this.regex(this.val) : this.regex.test(this.val))) {\n\t return false;\n\t }\n\t }\n\t return true;\n\t },\n\t reset: function reset() {\n\t this.value = '';\n\t this.valid = null;\n\t if (this._timeout.mask) clearTimeout(this._timeout.mask);\n\t if (this._timeout.eval) clearTimeout(this._timeout.eval);\n\t }\n\t },\n\t created: function created() {\n\t this._input = true;\n\t this._timeout = {};\n\t var parent = this.$parent;\n\t while (parent && !parent._formValidator) {\n\t parent = parent.$parent;\n\t }\n\t if (parent && parent._formValidator) {\n\t parent.children.push(this);\n\t this._parent = parent;\n\t }\n\t this._url = (0, _utils.delayer)(function () {\n\t var _this3 = this;\n\t\n\t if (!this.url || !this.$http || this._loading) {\n\t return;\n\t }\n\t this._loading = true;\n\t this.$http.get(this.url).then(function (response) {\n\t var data = response.data instanceof Array ? response.data : [];\n\t try {\n\t data = JSON.parse(data);\n\t } catch (e) {}\n\t if (_this3.urlMap) {\n\t data = data.map(_this3.urlMap);\n\t }\n\t _this3.options = data;\n\t _this3.loading = false;\n\t }, function (response) {\n\t _this3.loading = false;\n\t });\n\t }, DELAY);\n\t if (this.url) this._url();\n\t },\n\t mounted: function mounted() {\n\t // $(this.input).on('focus', e => { this.$emit('focus', e) }).on('blur', e => {\n\t // if (this.canValidate) { this.valid = this.validate() }\n\t // this.$emit('blur', e)\n\t // })\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t // $(this.input).off()\n\t if (this._parent) {\n\t var index = this._parent.children.indexOf(this);\n\t this._parent.children.splice(index, 1);\n\t }\n\t }\n\t};\n\n/***/ },\n/* 118 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t staticClass: \"form-group\",\n\t class: {\n\t validate: _vm.canValidate, 'has-feedback': _vm.icon, 'has-error': _vm.canValidate && _vm.valid === false, 'has-success': _vm.canValidate && _vm.valid\n\t }\n\t }, [_vm._t(\"label\", [(_vm.label) ? _vm._c('label', {\n\t staticClass: \"control-label\",\n\t on: {\n\t \"click\": _vm.focus\n\t }\n\t }, [_vm._v(_vm._s(_vm.label))]) : _vm._e()]), _vm._v(\" \"), (_vm.$slots.before || _vm.$slots.after) ? _vm._c('div', {\n\t staticClass: \"input-group\"\n\t }, [_vm._t(\"before\"), _vm._v(\" \"), _vm._c(_vm.type == 'textarea' ? _vm.type : 'input', {\n\t directives: [{\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.val),\n\t expression: \"val\"\n\t }],\n\t ref: \"input\",\n\t tag: \"textarea\",\n\t staticClass: \"form-control\",\n\t attrs: {\n\t \"cols\": _vm.cols,\n\t \"disabled\": _vm.disabled,\n\t \"list\": _vm.id_datalist,\n\t \"max\": _vm.attr(_vm.max),\n\t \"maxlength\": _vm.maxlength,\n\t \"min\": _vm.attr(_vm.min),\n\t \"name\": _vm.name,\n\t \"placeholder\": _vm.placeholder,\n\t \"readonly\": _vm.readonly,\n\t \"required\": _vm.required,\n\t \"rows\": _vm.rows,\n\t \"step\": _vm.step,\n\t \"title\": _vm.attr(_vm.title),\n\t \"type\": _vm.type == 'textarea' ? null : _vm.type\n\t },\n\t domProps: {\n\t \"value\": _vm._s(_vm.val)\n\t },\n\t on: {\n\t \"blur\": _vm.emit,\n\t \"focus\": _vm.emit,\n\t \"input\": [function($event) {\n\t if ($event.target.composing) { return; }\n\t _vm.val = $event.target.value\n\t }, _vm.emit],\n\t \"keyup\": function($event) {\n\t if (_vm._k($event.keyCode, \"enter\", 13)) { return; }\n\t _vm.type != 'textarea' && _vm.enterSubmit && _vm.submit()\n\t }\n\t }\n\t }), _vm._v(\" \"), (_vm.clearButton && _vm.value) ? _vm._c('div', {\n\t class: {\n\t icon: _vm.icon\n\t }\n\t }, [_vm._c('span', {\n\t staticClass: \"close\",\n\t on: {\n\t \"click\": function($event) {\n\t _vm.value = ''\n\t }\n\t }\n\t }, [_vm._v(\"×\")])]) : _vm._e(), _vm._v(\" \"), (_vm.icon) ? _vm._c('div', {\n\t staticClass: \"icon\"\n\t }, [(_vm.icon && _vm.valid !== null) ? _vm._c('span', {\n\t class: ['form-control-feedback glyphicon', 'glyphicon-' + (_vm.valid ? 'ok' : 'remove')],\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t }\n\t }) : _vm._e()]) : _vm._e(), _vm._v(\" \"), _vm._t(\"after\")], 2) : [_vm._c(_vm.type == 'textarea' ? _vm.type : 'input', {\n\t directives: [{\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.val),\n\t expression: \"val\"\n\t }],\n\t ref: \"input\",\n\t tag: \"textarea\",\n\t staticClass: \"form-control\",\n\t attrs: {\n\t \"cols\": _vm.cols,\n\t \"disabled\": _vm.disabled,\n\t \"list\": _vm.id_datalist,\n\t \"max\": _vm.attr(_vm.max),\n\t \"maxlength\": _vm.maxlength,\n\t \"min\": _vm.attr(_vm.min),\n\t \"name\": _vm.name,\n\t \"placeholder\": _vm.placeholder,\n\t \"readonly\": _vm.readonly,\n\t \"required\": _vm.required,\n\t \"rows\": _vm.rows,\n\t \"step\": _vm.step,\n\t \"title\": _vm.attr(_vm.title),\n\t \"type\": _vm.type == 'textarea' ? null : _vm.type\n\t },\n\t domProps: {\n\t \"value\": _vm._s(_vm.val)\n\t },\n\t on: {\n\t \"blur\": _vm.emit,\n\t \"focus\": _vm.emit,\n\t \"input\": [function($event) {\n\t if ($event.target.composing) { return; }\n\t _vm.val = $event.target.value\n\t }, _vm.emit],\n\t \"keyup\": function($event) {\n\t if (_vm._k($event.keyCode, \"enter\", 13)) { return; }\n\t _vm.type != 'textarea' && _vm.enterSubmit && _vm.submit()\n\t }\n\t }\n\t }), _vm._v(\" \"), (_vm.clearButton && _vm.val) ? _vm._c('span', {\n\t staticClass: \"close\",\n\t on: {\n\t \"click\": function($event) {\n\t _vm.val = ''\n\t }\n\t }\n\t }, [_vm._v(\"×\")]) : _vm._e(), _vm._v(\" \"), (_vm.icon && _vm.valid !== null) ? _vm._c('span', {\n\t class: ['form-control-feedback glyphicon', 'glyphicon-' + (_vm.valid ? 'ok' : 'remove')],\n\t attrs: {\n\t \"aria-hidden\": \"true\"\n\t }\n\t }) : _vm._e()], _vm._v(\" \"), (_vm.id_datalist) ? _vm._c('datalist', {\n\t attrs: {\n\t \"id\": _vm.id_datalist\n\t }\n\t }, _vm._l((_vm.options), function(opc) {\n\t return _vm._c('option', {\n\t domProps: {\n\t \"value\": opc\n\t }\n\t })\n\t })) : _vm._e(), _vm._v(\" \"), (_vm.showHelp) ? _vm._c('div', {\n\t staticClass: \"help-block\",\n\t on: {\n\t \"click\": _vm.focus\n\t }\n\t }, [_vm._v(_vm._s(_vm.help))]) : _vm._e(), _vm._v(\" \"), (_vm.showError) ? _vm._c('div', {\n\t staticClass: \"help-block with-errors\",\n\t on: {\n\t \"click\": _vm.focus\n\t }\n\t }, [_vm._v(_vm._s(_vm.errorText))]) : _vm._e()], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-652ad7b9\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 119 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(120)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(122)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(127)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Modal.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-fe7d5dc8\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-fe7d5dc8\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Modal.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 120 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 122 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _isInteger = __webpack_require__(123);\n\t\n\tvar _isInteger2 = _interopRequireDefault(_isInteger);\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = {\n\t props: {\n\t backdrop: { type: Boolean, default: true },\n\t callback: { type: Function, default: null },\n\t cancelText: { type: String, default: 'Close' },\n\t effect: { type: String, default: null },\n\t large: { type: Boolean, default: false },\n\t okText: { type: String, default: 'Save changes' },\n\t small: { type: Boolean, default: false },\n\t title: { type: String, default: '' },\n\t value: { type: Boolean, required: true },\n\t width: { default: null }\n\t },\n\t data: function data() {\n\t return {\n\t transition: false,\n\t val: null\n\t };\n\t },\n\t\n\t computed: {\n\t optionalWidth: function optionalWidth() {\n\t if (this.width === null) {\n\t return null;\n\t } else if ((0, _isInteger2.default)(this.width)) {\n\t return this.width + 'px';\n\t }\n\t return this.width;\n\t }\n\t },\n\t watch: {\n\t transition: function transition(val, old) {\n\t if (val === old) {\n\t return;\n\t }\n\t var el = this.$el;\n\t var body = document.body;\n\t if (val) {\n\t //starting\n\t if (this.val) {\n\t el.querySelector('.modal-content').focus();\n\t el.style.display = 'block';\n\t setTimeout(function () {\n\t return el.classList.add('in');\n\t }, 0);\n\t body.classList.add('modal-open');\n\t if ((0, _utils.getScrollBarWidth)() !== 0) {\n\t body.style.paddingRight = (0, _utils.getScrollBarWidth)() + 'px';\n\t }\n\t } else {\n\t el.classList.remove('in');\n\t }\n\t } else {\n\t //ending\n\t this.$emit(this.val ? 'opened' : 'closed');\n\t if (!this.val) {\n\t el.style.display = 'none';\n\t body.style.paddingRight = null;\n\t body.classList.remove('modal-open');\n\t }\n\t }\n\t },\n\t val: function val(_val, old) {\n\t this.$emit('input', _val);\n\t if (old === null ? _val === true : _val !== old) this.transition = true;\n\t },\n\t value: function value(val, old) {\n\t if (val !== old) this.val = val;\n\t }\n\t },\n\t methods: {\n\t action: function action(val, p) {\n\t if (val === null) {\n\t return;\n\t }\n\t if (val && this.callback instanceof Function) this.callback();\n\t this.$emit(val ? 'ok' : 'cancel', p);\n\t this.val = val || false;\n\t }\n\t },\n\t mounted: function mounted() {\n\t this.val = this.value;\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 123 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = { \"default\": __webpack_require__(124), __esModule: true };\n\n/***/ },\n/* 124 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(125);\n\tmodule.exports = __webpack_require__(7).Number.isInteger;\n\n/***/ },\n/* 125 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// 20.1.2.3 Number.isInteger(number)\n\tvar $export = __webpack_require__(5);\n\t\n\t$export($export.S, 'Number', {isInteger: __webpack_require__(126)});\n\n/***/ },\n/* 126 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// 20.1.2.3 Number.isInteger(number)\n\tvar isObject = __webpack_require__(13)\n\t , floor = Math.floor;\n\tmodule.exports = function isInteger(it){\n\t return !isObject(it) && isFinite(it) && floor(it) === it;\n\t};\n\n/***/ },\n/* 127 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t class: ['modal', _vm.effect],\n\t attrs: {\n\t \"role\": \"dialog\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.backdrop && _vm.action(false, 1)\n\t },\n\t \"transitionend\": function($event) {\n\t _vm.transition = false\n\t }\n\t }\n\t }, [_vm._c('div', {\n\t class: ['modal-dialog', {\n\t 'modal-lg': _vm.large,\n\t 'modal-sm': _vm.small\n\t }],\n\t style: ({\n\t width: _vm.optionalWidth\n\t }),\n\t attrs: {\n\t \"role\": \"document\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t $event.stopPropagation();\n\t _vm.action(null)\n\t }\n\t }\n\t }, [_vm._c('div', {\n\t staticClass: \"modal-content\"\n\t }, [_vm._t(\"modal-header\", [_vm._c('div', {\n\t staticClass: \"modal-header\"\n\t }, [_vm._c('button', {\n\t staticClass: \"close\",\n\t attrs: {\n\t \"type\": \"button\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.action(false, 2)\n\t }\n\t }\n\t }, [_vm._c('span', [_vm._v(\"×\")])]), _vm._v(\" \"), _vm._c('h4', {\n\t staticClass: \"modal-title\"\n\t }, [_vm._t(\"title\", [_vm._v(_vm._s(_vm.title))])], 2)])]), _vm._v(\" \"), _vm._t(\"modal-body\", [_vm._c('div', {\n\t staticClass: \"modal-body\"\n\t }, [_vm._t(\"default\")], 2)]), _vm._v(\" \"), _vm._t(\"modal-footer\", [_vm._c('div', {\n\t staticClass: \"modal-footer\"\n\t }, [_vm._c('button', {\n\t staticClass: \"btn btn-default\",\n\t attrs: {\n\t \"type\": \"button\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.action(false, 3)\n\t }\n\t }\n\t }, [_vm._v(_vm._s(_vm.cancelText))]), _vm._v(\" \"), _vm._c('button', {\n\t staticClass: \"btn btn-primary\",\n\t attrs: {\n\t \"type\": \"button\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.action(true, 4)\n\t }\n\t }\n\t }, [_vm._v(_vm._s(_vm.okText))])])])], 2)])])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-fe7d5dc8\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 128 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(129)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(130)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Navbar.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-38f0619e\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-38f0619e\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Navbar.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 129 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = {\n\t props: {\n\t type: { type: String, default: 'default' },\n\t placement: { type: String, default: '' },\n\t container: { type: String, default: '' }\n\t },\n\t data: function data() {\n\t return {\n\t id: 'bs-example-navbar-collapse-1',\n\t collapsed: true,\n\t styles: {}\n\t };\n\t },\n\t\n\t computed: {\n\t slots: function slots() {\n\t return this._slotContents;\n\t }\n\t },\n\t methods: {\n\t toggleCollapse: function toggleCollapse(e) {\n\t e && e.preventDefault();\n\t this.collapsed = !this.collapsed;\n\t }\n\t },\n\t created: function created() {\n\t this._navbar = true;\n\t },\n\t mounted: function mounted() {\n\t var _this = this;\n\t\n\t try {\n\t (function () {\n\t var $dropdown = (0, _NodeList2.default)('.dropdown>[data-toggle=\"dropdown\"]', _this.$el).parent();\n\t if ($dropdown) {\n\t $dropdown.on('click', '.dropdown-toggle', function (e) {\n\t e.preventDefault();\n\t $dropdown.each(function (content) {\n\t if (content.contains(e.target)) content.classList.toggle('open');\n\t });\n\t }).on('click', '.dropdown-menu>li>a', function (e) {\n\t $dropdown.each(function (content) {\n\t if (content.contains(e.target)) content.classList.remove('open');\n\t });\n\t }).onBlur(function (e) {\n\t $dropdown.each(function (content) {\n\t if (!content.contains(e.target)) content.classList.remove('open');\n\t });\n\t });\n\t }\n\t })();\n\t } catch (ex) {\n\t console.log('error finding dropdown');\n\t }\n\t\n\t (0, _NodeList2.default)(this.$el).on('click touchstart', 'li:not(.dropdown)>a', function (e) {\n\t setTimeout(function () {\n\t _this.collapsed = true;\n\t }, 200);\n\t }).onBlur(function (e) {\n\t if (!_this.$el.contains(e.target)) {\n\t _this.collapsed = true;\n\t }\n\t });\n\t var height = this.$el.offsetHeight;\n\t if (this.placement === 'top') {\n\t document.body.style.paddingTop = height + 'px';\n\t }\n\t if (this.placement === 'bottom') {\n\t document.body.style.paddingBottom = height + 'px';\n\t }\n\t if (this.$slots.collapse) (0, _NodeList2.default)('[data-toggle=\"collapse\"]', this.$el).on('click', function (e) {\n\t return _this.toggleCollapse(e);\n\t });\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t (0, _NodeList2.default)('.dropdown', this.$el).off('click').offBlur();\n\t if (this.$slots.collapse) (0, _NodeList2.default)('[data-toggle=\"collapse\"]', this.$el).off('click');\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 130 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('nav', {\n\t class: ['navbar', 'navbar-' + _vm.type, _vm.placement === 'static' ? 'navbar-static-top' : 'navbar-fixed-' + _vm.placement]\n\t }, [_vm._c('div', {\n\t class: _vm.container === 'fluid' ? 'container-fluid' : 'container'\n\t }, [_vm._c('div', {\n\t staticClass: \"navbar-header\"\n\t }, [(!_vm.$slots.collapse) ? _vm._c('button', {\n\t staticClass: \"navbar-toggle collapsed\",\n\t attrs: {\n\t \"type\": \"button\",\n\t \"aria-expanded\": \"false\"\n\t },\n\t on: {\n\t \"click\": _vm.toggleCollapse\n\t }\n\t }, [_vm._c('span', {\n\t staticClass: \"sr-only\"\n\t }, [_vm._v(\"Toggle navigation\")]), _vm._v(\" \"), _vm._c('span', {\n\t staticClass: \"icon-bar\"\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t staticClass: \"icon-bar\"\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t staticClass: \"icon-bar\"\n\t })]) : _vm._e(), _vm._v(\" \"), _vm._t(\"collapse\"), _vm._v(\" \"), _vm._t(\"brand\")], 2), _vm._v(\" \"), _vm._c('div', {\n\t class: ['navbar-collapse', {\n\t collapse: _vm.collapsed\n\t }]\n\t }, [_vm._c('ul', {\n\t staticClass: \"nav navbar-nav\"\n\t }, [_vm._t(\"default\")], 2), _vm._v(\" \"), (_vm.$slots.left) ? _vm._c('ul', {\n\t staticClass: \"nav navbar-nav navbar-left\"\n\t }, [_vm._t(\"left\")], 2) : _vm._e(), _vm._v(\" \"), (_vm.$slots.right) ? _vm._c('ul', {\n\t staticClass: \"nav navbar-nav navbar-right\"\n\t }, [_vm._t(\"right\")], 2) : _vm._e()])])])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-38f0619e\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 131 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(132)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(133)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Option.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-42088116\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-42088116\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Option.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 132 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t\n\texports.default = {\n\t props: { value: null },\n\t data: function data() {\n\t return { loading: true };\n\t },\n\t mounted: function mounted() {\n\t if (this.$parent._select) {\n\t if (!this.$parent.options) {\n\t this.$parent.options = [];\n\t }\n\t var el = {};\n\t el[this.$parent.optionsLabel] = this.$el.innerHTML;\n\t el[this.$parent.optionsValue] = this.value;\n\t this.$parent.options.push(el);\n\t this.loading = false;\n\t } else {\n\t console.warn('options only work inside a select component');\n\t }\n\t }\n\t};\n\n/***/ },\n/* 133 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return (_vm.loading) ? _vm._c('li', [_vm._t(\"default\")], 2) : _vm._e()\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-42088116\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 134 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(135)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(137)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(138)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Panel.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-b1e0461a\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-b1e0461a\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Panel.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 135 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 137 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t header: { type: String },\n\t isOpen: { type: Boolean, default: null },\n\t type: { type: String, default: null }\n\t },\n\t data: function data() {\n\t return {\n\t open: this.isOpen\n\t };\n\t },\n\t\n\t watch: {\n\t isOpen: function isOpen(val) {\n\t this.open = val;\n\t }\n\t },\n\t computed: {\n\t inAccordion: function inAccordion() {\n\t return this.$parent && this.$parent._isAccordion;\n\t },\n\t panelType: function panelType() {\n\t return 'panel-' + (this.type || this.$parent && this.$parent.type || 'default');\n\t }\n\t },\n\t methods: {\n\t toggle: function toggle() {\n\t this.open = !this.open;\n\t if (this.inAccordion) {\n\t this.$parent.openChild(this);\n\t }\n\t },\n\t enter: function enter(el) {\n\t el.style.height = 'auto';\n\t var endWidth = getComputedStyle(el).height;\n\t el.style.height = '0px';\n\t el.offsetHeight; // force repaint\n\t el.style.height = endWidth;\n\t },\n\t afterEnter: function afterEnter(el) {\n\t el.style.height = 'auto';\n\t },\n\t beforeLeave: function beforeLeave(el) {\n\t el.style.height = getComputedStyle(el).height;\n\t el.offsetHeight; // force repaint\n\t el.style.height = '0px';\n\t }\n\t },\n\t created: function created() {\n\t if (this.isOpen === null) {\n\t this.open = !this.inAccordion;\n\t }\n\t }\n\t};\n\n/***/ },\n/* 138 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t class: ['panel', _vm.panelType]\n\t }, [_vm._c('div', {\n\t class: ['panel-heading', {\n\t 'accordion-toggle': _vm.inAccordion\n\t }],\n\t on: {\n\t \"click\": function($event) {\n\t $event.preventDefault();\n\t _vm.inAccordion && _vm.toggle()\n\t }\n\t }\n\t }, [_vm._t(\"header\", [_vm._c('h4', {\n\t staticClass: \"panel-title\"\n\t }, [_vm._v(_vm._s(_vm.header))])])], 2), _vm._v(\" \"), _vm._c('transition', {\n\t attrs: {\n\t \"name\": \"collapse\"\n\t },\n\t on: {\n\t \"enter\": _vm.enter,\n\t \"after-enter\": _vm.afterEnter,\n\t \"before-leave\": _vm.beforeLeave\n\t }\n\t }, [(_vm.open) ? _vm._c('div', {\n\t staticClass: \"panel-collapse\"\n\t }, [_vm._c('div', {\n\t staticClass: \"panel-body\"\n\t }, [_vm._t(\"default\")], 2)]) : _vm._e()])], 1)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-b1e0461a\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 139 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(140)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(142)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(144)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Popover.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-2465bf54\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-2465bf54\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Popover.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 140 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 142 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _popoverMixins = __webpack_require__(143);\n\t\n\tvar _popoverMixins2 = _interopRequireDefault(_popoverMixins);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = {\n\t mixins: [_popoverMixins2.default],\n\t props: {\n\t trigger: { type: String, default: 'click' }\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 143 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _NodeList = __webpack_require__(1);\n\t\n\tvar _NodeList2 = _interopRequireDefault(_NodeList);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = {\n\t props: {\n\t content: { type: String },\n\t effect: { type: String, default: 'fade' },\n\t header: { type: Boolean, default: true },\n\t placement: { type: String, default: 'top' },\n\t title: { type: String },\n\t trigger: { type: String }\n\t },\n\t data: function data() {\n\t return {\n\t top: 0,\n\t left: 0,\n\t show: false\n\t };\n\t },\n\t\n\t computed: {\n\t events: function events() {\n\t return { contextmenu: ['contextmenu'], hover: ['mouseleave', 'mouseenter'], focus: ['blur', 'focus'] }[this.trigger] || ['click'];\n\t }\n\t },\n\t methods: {\n\t beforeEnter: function beforeEnter() {\n\t var _this = this;\n\t\n\t this.position();\n\t setTimeout(function () {\n\t return _this.position();\n\t }, 30);\n\t },\n\t position: function position() {\n\t var _this2 = this;\n\t\n\t this.$nextTick(function () {\n\t var popover = _this2.$refs.popover;\n\t var trigger = _this2.$refs.trigger.children[0];\n\t switch (_this2.placement) {\n\t case 'top':\n\t _this2.left = trigger.offsetLeft - popover.offsetWidth / 2 + trigger.offsetWidth / 2;\n\t _this2.top = trigger.offsetTop - popover.offsetHeight;\n\t break;\n\t case 'left':\n\t _this2.left = trigger.offsetLeft - popover.offsetWidth;\n\t _this2.top = trigger.offsetTop + trigger.offsetHeight / 2 - popover.offsetHeight / 2;\n\t break;\n\t case 'right':\n\t _this2.left = trigger.offsetLeft + trigger.offsetWidth;\n\t _this2.top = trigger.offsetTop + trigger.offsetHeight / 2 - popover.offsetHeight / 2;\n\t break;\n\t case 'bottom':\n\t _this2.left = trigger.offsetLeft - popover.offsetWidth / 2 + trigger.offsetWidth / 2;\n\t _this2.top = trigger.offsetTop + trigger.offsetHeight;\n\t break;\n\t default:\n\t console.warn('Wrong placement prop');\n\t }\n\t popover.style.top = _this2.top + 'px';\n\t popover.style.left = _this2.left + 'px';\n\t });\n\t },\n\t toggle: function toggle(e) {\n\t if (e && this.trigger === 'contextmenu') e.preventDefault();\n\t this.show = !this.show;\n\t if (this.show) this.beforeEnter();\n\t }\n\t },\n\t mounted: function mounted() {\n\t var _this3 = this;\n\t\n\t var trigger = this.$refs.trigger.children[0];\n\t if (!trigger) return console.error('Could not find trigger v-el in your component that uses popoverMixin.');\n\t\n\t if (this.trigger === 'focus' && !~trigger.tabIndex) {\n\t trigger = (0, _NodeList2.default)('a,input,select,textarea,button', trigger);\n\t if (!trigger.length) {\n\t return;\n\t }\n\t }\n\t this.events.forEach(function (event) {\n\t (0, _NodeList2.default)(trigger).on(event, _this3.toggle);\n\t });\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t if (this._trigger) (0, _NodeList2.default)(this._trigger).off();\n\t }\n\t};\n\n/***/ },\n/* 144 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('span', {\n\t ref: \"trigger\"\n\t }, [_vm._t(\"default\"), _vm._v(\" \"), _vm._c('transition', {\n\t attrs: {\n\t \"name\": _vm.effect\n\t }\n\t }, [(_vm.show) ? _vm._c('div', {\n\t ref: \"popover\",\n\t class: ['popover', _vm.placement]\n\t }, [_vm._c('div', {\n\t staticClass: \"arrow\"\n\t }), _vm._v(\" \"), (_vm.title) ? _vm._c('h3', {\n\t staticClass: \"popover-title\"\n\t }, [_vm._t(\"title\", [_vm._v(_vm._s(_vm.title))])], 2) : _vm._e(), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"popover-content\"\n\t }, [_vm._t(\"content\", [_vm._c('span', {\n\t domProps: {\n\t \"innerHTML\": _vm._s(_vm.content)\n\t }\n\t })])], 2)]) : _vm._e()])], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-2465bf54\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 145 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(146)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(147)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Progressbar.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-68aa3375\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-68aa3375\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Progressbar.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 146 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\texports.default = {\n\t props: {\n\t animated: { type: Boolean, default: false },\n\t label: { default: false },\n\t now: { required: true },\n\t striped: { type: Boolean, default: false },\n\t type: { type: String }\n\t },\n\t computed: {\n\t labelBool: function labelBool() {\n\t return _utils.coerce.boolean(this.label);\n\t },\n\t nowNum: function nowNum() {\n\t return _utils.coerce.number(this.now);\n\t }\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 147 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t class: ['progress-bar', 'progress-bar-' + _vm.type, {\n\t active: _vm.animated,\n\t 'progress-bar-striped': _vm.striped\n\t }],\n\t style: ({\n\t width: _vm.nowNum + '%'\n\t }),\n\t domProps: {\n\t \"textContent\": _vm._s(_vm.labelBool ? _vm.nowNum + '%' : null)\n\t }\n\t })\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-68aa3375\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 148 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(149)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(151)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(152)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Radio.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-74cfd92c\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-74cfd92c\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Radio.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 149 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 151 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t button: { type: Boolean, default: false },\n\t disabled: { type: Boolean, default: false },\n\t name: { type: String, default: null },\n\t readonly: { type: Boolean, default: false },\n\t selectedValue: { default: true },\n\t type: { type: String, default: null },\n\t value: { default: false }\n\t },\n\t data: function data() {\n\t return {\n\t check: this.value\n\t };\n\t },\n\t\n\t computed: {\n\t active: function active() {\n\t return this.check === this.selectedValue;\n\t },\n\t inGroup: function inGroup() {\n\t return this.$parent && this.$parent.btnGroup && !this.$parent._checkboxGroup;\n\t },\n\t parentValue: function parentValue() {\n\t return this.$parent.val;\n\t },\n\t buttonStyle: function buttonStyle() {\n\t return this.button || this.$parent && this.$parent.btnGroup && this.$parent.buttons;\n\t },\n\t typeColor: function typeColor() {\n\t return this.type || this.$parent && this.$parent.type || 'default';\n\t }\n\t },\n\t watch: {\n\t check: function check(val) {\n\t if (this.selectedValue === val) {\n\t this.$emit('input', val);\n\t this.$emit('checked', true);\n\t this.updateParent();\n\t }\n\t },\n\t parentValue: function parentValue(val) {\n\t this.updateFromParent();\n\t },\n\t value: function value(val) {\n\t if (this.selectedValue == val) {\n\t this.check = val;\n\t } else {\n\t this.check = false;\n\t }\n\t }\n\t },\n\t created: function created() {\n\t if (this.inGroup) {\n\t var parent = this.$parent;\n\t parent._radioGroup = true;\n\t this.updateFromParent();\n\t }\n\t },\n\t\n\t methods: {\n\t updateFromParent: function updateFromParent() {\n\t if (this.inGroup) {\n\t if (this.selectedValue == this.$parent.val) {\n\t this.check = this.selectedValue;\n\t } else {\n\t this.check = false;\n\t }\n\t }\n\t },\n\t updateParent: function updateParent() {\n\t if (this.inGroup) {\n\t if (this.selectedValue === this.check) {\n\t this.$parent.val = this.selectedValue;\n\t }\n\t }\n\t },\n\t focus: function focus() {\n\t this.$refs.input.focus();\n\t },\n\t toggle: function toggle() {\n\t if (this.disabled) {\n\t return;\n\t }\n\t this.focus();\n\t if (this.readonly) {\n\t return;\n\t }\n\t this.check = this.selectedValue;\n\t }\n\t }\n\t};\n\n/***/ },\n/* 152 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c(_vm.buttonStyle ? 'label' : 'div', {\n\t tag: \"div\",\n\t class: [(_vm.buttonStyle ? 'btn btn-' + _vm.typeColor : 'radio ' + _vm.typeColor), {\n\t active: _vm.active,\n\t disabled: _vm.disabled,\n\t readonly: _vm.readonly\n\t }],\n\t on: {\n\t \"click\": function($event) {\n\t $event.preventDefault();\n\t _vm.toggle($event)\n\t }\n\t }\n\t }, [(_vm.buttonStyle) ? [_vm._c('input', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (!_vm.readonly),\n\t expression: \"!readonly\"\n\t }, {\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.check),\n\t expression: \"check\"\n\t }],\n\t ref: \"input\",\n\t attrs: {\n\t \"type\": \"radio\",\n\t \"autocomplete\": \"off\",\n\t \"name\": _vm.name,\n\t \"readonly\": _vm.readonly,\n\t \"disabled\": _vm.disabled\n\t },\n\t domProps: {\n\t \"value\": _vm.selectedValue,\n\t \"checked\": _vm._q(_vm.check, _vm.selectedValue)\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.check = _vm.selectedValue\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._t(\"default\")] : _vm._c('label', {\n\t staticClass: \"open\"\n\t }, [_vm._c('input', {\n\t directives: [{\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.check),\n\t expression: \"check\"\n\t }],\n\t ref: \"input\",\n\t attrs: {\n\t \"type\": \"radio\",\n\t \"autocomplete\": \"off\",\n\t \"name\": _vm.name,\n\t \"readonly\": _vm.readonly,\n\t \"disabled\": _vm.disabled\n\t },\n\t domProps: {\n\t \"value\": _vm.selectedValue,\n\t \"checked\": _vm._q(_vm.check, _vm.selectedValue)\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t _vm.check = _vm.selectedValue\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t staticClass: \"icon dropdown-toggle\",\n\t class: [_vm.active ? 'btn-' + _vm.typeColor : '', {\n\t bg: _vm.typeColor === 'default'\n\t }]\n\t }), _vm._v(\" \"), (_vm.active && _vm.typeColor === 'default') ? _vm._c('span', {\n\t staticClass: \"icon\"\n\t }) : _vm._e(), _vm._v(\" \"), _vm._t(\"default\")], 2)], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-74cfd92c\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 153 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(154)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(156)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(157)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Select.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t__vue_options__._scopeId = \"data-v-e514dbc6\"\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-e514dbc6\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-e514dbc6\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Select.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 154 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 156 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\tvar _ClickOutside = __webpack_require__(66);\n\t\n\tvar _ClickOutside2 = _interopRequireDefault(_ClickOutside);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\tvar timeout = {};\n\texports.default = {\n\t directives: {\n\t ClickOutside: _ClickOutside2.default\n\t },\n\t props: {\n\t clearButton: { type: Boolean, default: false },\n\t closeOnSelect: { type: Boolean, default: false },\n\t disabled: { type: Boolean, default: false },\n\t lang: { type: String, default: navigator.language },\n\t limit: { type: Number, default: 1024 },\n\t minSearch: { type: Number, default: 0 },\n\t multiple: { type: Boolean, default: false },\n\t name: { type: String, default: null },\n\t options: { type: Array, default: function _default() {\n\t return [];\n\t }\n\t },\n\t optionsLabel: { type: String, default: 'label' },\n\t optionsValue: { type: String, default: 'value' },\n\t parent: { default: true },\n\t placeholder: { type: String, default: null },\n\t readonly: { type: Boolean, default: null },\n\t required: { type: Boolean, default: null },\n\t search: { type: Boolean, default: false },\n\t searchText: { type: String, default: null },\n\t countText: { type: String, default: null },\n\t showCount: { type: Boolean, default: false },\n\t url: { type: String, default: null },\n\t value: null\n\t },\n\t data: function data() {\n\t return {\n\t list: [],\n\t loading: null,\n\t searchValue: null,\n\t show: false,\n\t notify: false,\n\t val: null,\n\t valid: null\n\t };\n\t },\n\t\n\t computed: {\n\t canSearch: function canSearch() {\n\t return this.minSearch ? this.list.length >= this.minSearch : this.search;\n\t },\n\t classes: function classes() {\n\t return [{ open: this.show, disabled: this.disabled }, this.class, this.isLi ? 'dropdown' : this.inInput ? 'input-group-btn' : 'btn-group'];\n\t },\n\t filteredOptions: function filteredOptions() {\n\t var _this = this;\n\t\n\t var search = (this.searchValue || '').toLowerCase();\n\t return !search ? this.list : this.list.filter(function (el) {\n\t return ~el[_this.optionsLabel].toLowerCase().search(search);\n\t });\n\t },\n\t hasParent: function hasParent() {\n\t return this.parent instanceof Array ? this.parent.length : this.parent;\n\t },\n\t inInput: function inInput() {\n\t return this.$parent._input;\n\t },\n\t isLi: function isLi() {\n\t return this.$parent._navbar || this.$parent.menu || this.$parent._tabset;\n\t },\n\t limitText: function limitText() {\n\t return this.text.limit.replace('{{limit}}', this.limit);\n\t },\n\t selected: function selected() {\n\t var _this2 = this;\n\t\n\t if (this.list.length === 0) {\n\t return '';\n\t }\n\t var sel = this.values.map(function (val) {\n\t return (_this2.list.find(function (o) {\n\t return o[_this2.optionsValue] === val;\n\t }) || {})[_this2.optionsLabel];\n\t }).filter(function (val) {\n\t return val !== undefined;\n\t });\n\t this.$emit('selected', sel);\n\t return sel.join(', ');\n\t },\n\t selectedText: function selectedText() {\n\t return this.countText || this.text.selected.replace('{{count}}', this.values.length);\n\t },\n\t showPlaceholder: function showPlaceholder() {\n\t return this.values.length === 0 || !this.hasParent ? this.placeholder || this.text.notSelected : null;\n\t },\n\t text: function text() {\n\t return (0, _utils.translations)(this.lang);\n\t },\n\t values: function values() {\n\t return this.val instanceof Array ? this.val : ~[null, undefined].indexOf(this.val) ? [] : [this.val];\n\t },\n\t valOptions: function valOptions() {\n\t var _this3 = this;\n\t\n\t return this.list.map(function (el) {\n\t return el[_this3.optionsValue];\n\t });\n\t }\n\t },\n\t watch: {\n\t options: function options(_options) {\n\t if (_options instanceof Array) this.setOptions(_options);\n\t },\n\t show: function show(val) {\n\t if (val) {\n\t this.$refs.search ? this.$refs.search.focus() : this.$refs.btn.focus();\n\t // onBlur(this.$refs.select, e => { this.show = false })\n\t } else {\n\t // offBlur(this.$refs.select)\n\t }\n\t },\n\t url: function url() {\n\t this.urlChanged();\n\t },\n\t valid: function valid(val, old) {\n\t this.$emit('isvalid', val);\n\t this.$emit(!val ? 'invalid' : 'valid');\n\t if (val !== old && this._parent) this._parent.validate();\n\t },\n\t value: function value(val, old) {\n\t if (val !== old) {\n\t this.val = val;\n\t }\n\t },\n\t val: function val(_val, old) {\n\t var _this4 = this;\n\t\n\t if (_val === undefined) {\n\t this.val = _val = null;\n\t }\n\t if (_val !== old) {\n\t this.$emit('change', _val);\n\t this.$emit('input', _val);\n\t }\n\t if (_val instanceof Array && _val.length > this.limit) {\n\t this.val = _val.slice(0, this.limit);\n\t this.notify = true;\n\t if (timeout.limit) clearTimeout(timeout.limit);\n\t timeout.limit = setTimeout(function () {\n\t timeout.limit = false;\n\t _this4.notify = false;\n\t }, 1500);\n\t }\n\t this.valid = this.validate();\n\t }\n\t },\n\t methods: {\n\t close: function close() {\n\t this.show = false;\n\t },\n\t checkData: function checkData() {\n\t if (this.multiple) {\n\t if (this.limit < 1) {\n\t this.limit = 1;\n\t }\n\t if (!(this.val instanceof Array)) {\n\t this.val = this.val === null || this.val === undefined ? [] : [this.val];\n\t }\n\t var values = this.valOptions;\n\t this.val = this.val.filter(function (el) {\n\t return ~values.indexOf(el);\n\t });\n\t if (this.values.length > this.limit) {\n\t this.val = this.val.slice(0, this.limit);\n\t }\n\t } else {\n\t if (!~this.valOptions.indexOf(this.val)) {\n\t this.val = null;\n\t }\n\t }\n\t },\n\t clear: function clear() {\n\t if (this.disabled || this.readonly) {\n\t return;\n\t }\n\t this.val = this.val instanceof Array ? [] : null;\n\t this.toggle();\n\t },\n\t clearSearch: function clearSearch() {\n\t this.searchValue = '';\n\t this.$refs.search.focus();\n\t },\n\t isSelected: function isSelected(v) {\n\t return this.values.indexOf(v) > -1;\n\t },\n\t select: function select(v) {\n\t if (this.val instanceof Array) {\n\t var newVal = this.val.slice(0);\n\t if (~newVal.indexOf(v)) {\n\t newVal.splice(newVal.indexOf(v), 1);\n\t } else {\n\t newVal.push(v);\n\t }\n\t this.val = newVal;\n\t if (this.closeOnSelect) {\n\t this.toggle();\n\t }\n\t } else {\n\t this.val = v;\n\t this.toggle();\n\t }\n\t },\n\t setOptions: function setOptions(options) {\n\t var _this5 = this;\n\t\n\t this.list = options.map(function (el) {\n\t if (el instanceof Object) {\n\t return el;\n\t }\n\t var obj = {};\n\t obj[_this5.optionsLabel] = el;\n\t obj[_this5.optionsValue] = el;\n\t return obj;\n\t });\n\t this.$emit('options', this.list);\n\t },\n\t toggle: function toggle() {\n\t if (this.disabled && !this.show) return;\n\t this.show = !this.show;\n\t if (!this.show) this.$refs.btn.focus();\n\t },\n\t urlChanged: function urlChanged() {\n\t var _this6 = this;\n\t\n\t if (!this.url || !this.$http) {\n\t return;\n\t }\n\t this.loading = true;\n\t this.$http.get(this.url).then(function (response) {\n\t var data = response.data instanceof Array ? response.data : [];\n\t try {\n\t data = JSON.parse(data);\n\t } catch (e) {}\n\t _this6.setOptions(data);\n\t _this6.loading = false;\n\t _this6.checkData();\n\t }, function (response) {\n\t _this6.loading = false;\n\t });\n\t },\n\t validate: function validate() {\n\t return !this.required ? true : this.val instanceof Array ? this.val.length > 0 : this.val !== null;\n\t }\n\t },\n\t created: function created() {\n\t this.setOptions(this.options);\n\t this.val = this.value;\n\t this._select = true;\n\t if (this.val === undefined || !this.parent) {\n\t this.val = null;\n\t }\n\t if (!this.multiple && this.val instanceof Array) {\n\t this.val = this.val[0];\n\t }\n\t this.checkData();\n\t if (this.url) this.urlChanged();\n\t var parent = this.$parent;\n\t while (parent && !parent._formValidator) {\n\t parent = parent.$parent;\n\t }\n\t if (parent && parent._formValidator) {\n\t parent.children.push(this);\n\t this._parent = parent;\n\t }\n\t },\n\t mounted: function mounted() {\n\t if (this._parent) this._parent.children.push(this);\n\t this.setOptions(this.options);\n\t this.val = this.value;\n\t this.checkData();\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t if (this._parent) {\n\t var index = this._parent.children.indexOf(this);\n\t this._parent.children.splice(index, 1);\n\t }\n\t }\n\t};\n\n/***/ },\n/* 157 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t directives: [{\n\t name: \"click-outside\",\n\t rawName: \"v-click-outside\",\n\t value: (_vm.close),\n\t expression: \"close\"\n\t }],\n\t ref: \"select\",\n\t class: _vm.classes\n\t }, [_vm._c('div', {\n\t ref: \"btn\",\n\t staticClass: \"form-control dropdown-toggle\",\n\t attrs: {\n\t \"tabindex\": \"1\",\n\t \"disabled\": _vm.disabled || !_vm.hasParent,\n\t \"readonly\": _vm.readonly\n\t },\n\t on: {\n\t \"blur\": function($event) {\n\t _vm.canSearch ? null : _vm.close()\n\t },\n\t \"click\": function($event) {\n\t _vm.toggle()\n\t },\n\t \"keydown\": [function($event) {\n\t if (_vm._k($event.keyCode, \"esc\", 27)) { return; }\n\t $event.stopPropagation();\n\t $event.preventDefault();\n\t _vm.close($event)\n\t }, function($event) {\n\t if (_vm._k($event.keyCode, \"space\", 32)) { return; }\n\t $event.stopPropagation();\n\t $event.preventDefault();\n\t _vm.toggle($event)\n\t }, function($event) {\n\t if (_vm._k($event.keyCode, \"enter\", 13)) { return; }\n\t $event.stopPropagation();\n\t $event.preventDefault();\n\t _vm.toggle($event)\n\t }]\n\t }\n\t }, [_vm._c('span', {\n\t staticClass: \"btn-content\",\n\t domProps: {\n\t \"innerHTML\": _vm._s(_vm.loading ? _vm.text.loading : _vm.showPlaceholder || (_vm.multiple && _vm.showCount ? _vm.selectedText : _vm.selected))\n\t }\n\t }), _vm._v(\" \"), (_vm.clearButton && _vm.values.length) ? _vm._c('span', {\n\t staticClass: \"close\",\n\t on: {\n\t \"click\": function($event) {\n\t _vm.clear()\n\t }\n\t }\n\t }, [_vm._v(\"×\")]) : _vm._e()]), _vm._v(\" \"), _vm._c('select', {\n\t directives: [{\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.val),\n\t expression: \"val\"\n\t }],\n\t ref: \"sel\",\n\t staticClass: \"secret\",\n\t attrs: {\n\t \"name\": _vm.name,\n\t \"multiple\": _vm.multiple,\n\t \"required\": _vm.required,\n\t \"readonly\": _vm.readonly,\n\t \"disabled\": _vm.disabled\n\t },\n\t on: {\n\t \"change\": function($event) {\n\t _vm.val = Array.prototype.filter.call($event.target.options, function(o) {\n\t return o.selected\n\t }).map(function(o) {\n\t var val = \"_value\" in o ? o._value : o.value;\n\t return val\n\t })[0]\n\t }\n\t }\n\t }, [(_vm.required) ? _vm._c('option', {\n\t attrs: {\n\t \"value\": \"\"\n\t }\n\t }) : _vm._e(), _vm._v(\" \"), _vm._l((_vm.list), function(option) {\n\t return _vm._c('option', {\n\t domProps: {\n\t \"value\": option[_vm.optionsValue]\n\t }\n\t }, [_vm._v(_vm._s(option[_vm.optionsLabel]))])\n\t })], 2), _vm._v(\" \"), _vm._c('ul', {\n\t staticClass: \"dropdown-menu\"\n\t }, [(_vm.list.length) ? [(_vm.canSearch) ? _vm._c('li', {\n\t staticClass: \"bs-searchbox\"\n\t }, [_vm._c('input', {\n\t directives: [{\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.searchValue),\n\t expression: \"searchValue\"\n\t }],\n\t ref: \"search\",\n\t staticClass: \"form-control\",\n\t attrs: {\n\t \"type\": \"text\",\n\t \"placeholder\": _vm.searchText || _vm.text.search,\n\t \"autocomplete\": \"off\"\n\t },\n\t domProps: {\n\t \"value\": _vm._s(_vm.searchValue)\n\t },\n\t on: {\n\t \"keyup\": function($event) {\n\t if (_vm._k($event.keyCode, \"esc\", 27)) { return; }\n\t _vm.close($event)\n\t },\n\t \"input\": function($event) {\n\t if ($event.target.composing) { return; }\n\t _vm.searchValue = $event.target.value\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.searchValue),\n\t expression: \"searchValue\"\n\t }],\n\t staticClass: \"close\",\n\t on: {\n\t \"click\": _vm.clearSearch\n\t }\n\t }, [_vm._v(\"×\")])]) : _vm._e(), _vm._v(\" \"), (_vm.required && !_vm.clearButton) ? _vm._c('li', [_vm._c('a', {\n\t on: {\n\t \"mousedown\": function($event) {\n\t $event.preventDefault();\n\t _vm.clear() && _vm.close()\n\t }\n\t }\n\t }, [_vm._v(_vm._s(_vm.placeholder || _vm.text.notSelected))])]) : _vm._e(), _vm._v(\" \"), _vm._l((_vm.filteredOptions), function(option) {\n\t return _vm._c('li', {\n\t attrs: {\n\t \"id\": option[_vm.optionsValue]\n\t }\n\t }, [_vm._c('a', {\n\t on: {\n\t \"mousedown\": function($event) {\n\t $event.preventDefault();\n\t _vm.select(option[_vm.optionsValue])\n\t }\n\t }\n\t }, [_vm._c('span', {\n\t domProps: {\n\t \"innerHTML\": _vm._s(option[_vm.optionsLabel])\n\t }\n\t }), _vm._v(\" \"), _vm._c('span', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.isSelected(option[_vm.optionsValue])),\n\t expression: \"isSelected(option[optionsValue])\"\n\t }],\n\t staticClass: \"glyphicon glyphicon-ok check-mark\"\n\t })])])\n\t })] : _vm._e(), _vm._v(\" \"), _vm._t(\"default\"), _vm._v(\" \"), (_vm.notify && !_vm.closeOnSelect) ? _vm._c('transition', {\n\t attrs: {\n\t \"name\": \"fadein\"\n\t }\n\t }, [_vm._c('div', {\n\t staticClass: \"notify in\"\n\t }, [_vm._v(_vm._s(_vm.limitText))])]) : _vm._e()], 2), _vm._v(\" \"), (_vm.notify && _vm.closeOnSelect) ? _vm._c('transition', {\n\t attrs: {\n\t \"name\": \"fadein\"\n\t }\n\t }, [_vm._c('div', {\n\t staticClass: \"notify out\"\n\t }, [_vm._c('div', [_vm._v(_vm._s(_vm.limitText))])])]) : _vm._e()], 1)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-e514dbc6\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 158 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(159)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(160)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Slider.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-32185b82\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-32185b82\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Slider.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 159 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t//\n\t\n\texports.default = {\n\t computed: {\n\t index: function index() {\n\t return this.$parent.$children.indexOf(this);\n\t },\n\t show: function show() {\n\t return this.$parent.index === this.index;\n\t }\n\t },\n\t mounted: function mounted() {\n\t if (this.$parent.indicator_list) {\n\t this.$parent.indicator_list.push(this.index);\n\t }\n\t\n\t if (this.index === 0) {\n\t this.$el.classList.add('active');\n\t }\n\t }\n\t};\n\n/***/ },\n/* 160 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t staticClass: \"item\"\n\t }, [_vm._t(\"default\")], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-32185b82\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 161 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(162)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(164)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(165)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Spinner.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-8b298e70\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-8b298e70\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Spinner.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 162 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 164 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\tvar MIN_WAIT = 500; // in ms\n\t\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t fixed: { type: Boolean, default: false },\n\t global: { type: Boolean, default: false },\n\t size: { type: String, default: 'md' },\n\t text: { type: String, default: '' },\n\t value: { default: false }\n\t },\n\t data: function data() {\n\t return {\n\t active: this.value,\n\t locked: false\n\t };\n\t },\n\t\n\t computed: {\n\t spinnerSize: function spinnerSize() {\n\t return 'spinner-' + (this.size ? this.size : 'sm');\n\t }\n\t },\n\t watch: {\n\t active: function active(val, old) {\n\t if (val !== old) this.$emit('input', val);\n\t },\n\t value: function value(val, old) {\n\t if (val !== old) {\n\t this[val ? 'show' : 'hide']();\n\t }\n\t }\n\t },\n\t methods: {\n\t hide: function hide() {\n\t var delay = 0;\n\t this.active = false;\n\t },\n\t show: function show(options) {\n\t if (options) {\n\t if (options.text) {\n\t this.text = options.text;\n\t }\n\t if (options.size) {\n\t this.size = options.size;\n\t }\n\t if (options.fixed) {\n\t this.fixed = options.fixed;\n\t }\n\t }\n\t // block scrolling when spinner is on\n\t this._body.style.overflowY = 'hidden';\n\t // activate spinner\n\t this._started = new Date();\n\t this.active = true;\n\t this.locked = true;\n\t this._unlock();\n\t }\n\t },\n\t created: function created() {\n\t this._body = document.body;\n\t this._bodyOverflow = document.body.style.overflowY;\n\t this._unlock = (0, _utils.delayer)(function () {\n\t this.locked = false;\n\t this._body.style.overflowY = this._bodyOverflow;\n\t }, MIN_WAIT);\n\t if (this.global) {\n\t if (!this.$root._globalSpinner) {\n\t this.$root._globalSpinner = true;\n\t var self = this;\n\t this._global = {\n\t hide: function hide() {\n\t self.hide();\n\t },\n\t show: function show() {\n\t self.show();\n\t }\n\t };\n\t this.$root.$on('spinner::show', this._global.show);\n\t this.$root.$on('spinner::hide', this._global.hide);\n\t }\n\t }\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t if (this._global) {\n\t this.$root.$off('spinner::show', this._global.show);\n\t this.$root.$off('spinner::hide', this._global.hide);\n\t delete this.$root._globalSpinner;\n\t }\n\t clearTimeout(this._spinnerAnimation);\n\t this._body.style.overflowY = this._bodyOverflow;\n\t }\n\t};\n\n/***/ },\n/* 165 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t directives: [{\n\t name: \"show\",\n\t rawName: \"v-show\",\n\t value: (_vm.active || _vm.locked),\n\t expression: \"active||locked\"\n\t }],\n\t class: ['spinner spinner-gritcode', _vm.spinnerSize, {\n\t 'spinner-fixed': _vm.fixed\n\t }]\n\t }, [_vm._c('div', {\n\t staticClass: \"spinner-wrapper\"\n\t }, [_vm._c('div', {\n\t staticClass: \"spinner-circle\"\n\t }), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"spinner-text\"\n\t }, [_vm._v(_vm._s(_vm.text))])])])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-8b298e70\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 166 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(167)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(168)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Tab.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-0985e878\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-0985e878\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Tab.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 167 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t disabled: { type: Boolean, default: false },\n\t header: { type: String }\n\t },\n\t data: function data() {\n\t return {\n\t fadein: false\n\t };\n\t },\n\t\n\t computed: {\n\t active: function active() {\n\t var _this = this;\n\t\n\t var active = !this._tabs || this._tabs.show === this;\n\t this.fadein = false;\n\t if (active) {\n\t setTimeout(function () {\n\t _this.fadein = true;\n\t }, 0);\n\t }\n\t return active;\n\t },\n\t index: function index() {\n\t return this._tabs.tabs.indexOf(this);\n\t },\n\t transition: function transition() {\n\t return this._tabs ? this._tabs.effect : null;\n\t }\n\t },\n\t created: function created() {\n\t this._isTab = true;\n\t var tabs = this;\n\t while (!this._tabs && tabs.$parent) {\n\t if (tabs._isTabGroup) {\n\t tabs.tabs.push(this);\n\t this._tabGroup = tabs;\n\t }\n\t if (tabs._isTabs) {\n\t tabs.tabs.push(this);\n\t this._tabs = tabs;\n\t if (!this._tabGroup) tabs.headers.push(this);\n\t }\n\t tabs = tabs.$parent;\n\t }\n\t if (!this._tabs) throw Error('tab depend on tabs.');\n\t },\n\t beforeDestroy: function beforeDestroy() {\n\t var _this2 = this;\n\t\n\t if (this._tabGroup) {\n\t this._tabGroup.tabs = this._tabGroup.tabs.filter(function (el) {\n\t return el !== _this2;\n\t });\n\t }\n\t if (this._tabs) {\n\t this._tabs.tabs = this._tabs.tabs.filter(function (el) {\n\t return el !== _this2;\n\t });\n\t }\n\t if (this._tabs) {\n\t if (this._tabs.active === this.index) {\n\t this._tabs.index = 0;\n\t }\n\t if (this._ingroup) {\n\t var id = this.$parent.tabs.indexOf(this);\n\t if (~id) this.$parent.tabs.splice(id, 1);\n\t }\n\t }\n\t if (this._tabs) {\n\t var _id = this._tabs.tabs.indexOf(this);\n\t if (~_id) this._tabs.tabs.splice(_id, 1);\n\t }\n\t }\n\t};\n\n/***/ },\n/* 168 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t ref: \"panel\",\n\t class: ['tab-pane', {\n\t 'active fade': _vm.active,\n\t 'in': _vm.fadein\n\t }],\n\t attrs: {\n\t \"role\": \"tabpanel\"\n\t }\n\t }, [_vm._t(\"default\")], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-0985e878\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 169 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(170)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(172)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(173)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\TabGroup.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-55faf3cb\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-55faf3cb\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] TabGroup.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 170 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 172 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t disabled: { type: Boolean, default: false },\n\t header: { type: String }\n\t },\n\t data: function data() {\n\t return {\n\t show: false,\n\t tabs: []\n\t };\n\t },\n\t\n\t computed: {\n\t active: function active() {\n\t return ~this.tabs.indexOf(this._tabs.show);\n\t }\n\t },\n\t methods: {\n\t blur: function blur() {\n\t this.show = false;\n\t },\n\t toggle: function toggle() {\n\t this.show = !this.show;\n\t }\n\t },\n\t created: function created() {\n\t this._isTabGroup = true;\n\t if (this.$parent) {\n\t if (this.$parent._isTabGroup) throw Error('Can\\'t nest tab-groups.');\n\t if (!this.$parent._isTabs) throw Error('tab-group depend on tabs.');\n\t }\n\t this._tabs = this.$parent;\n\t this._tabs.headers.push(this);\n\t }\n\t};\n\n/***/ },\n/* 173 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('span', [_vm._t(\"default\")], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-55faf3cb\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 174 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(175)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(177)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(178)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Tabs.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-70100ddf\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-70100ddf\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Tabs.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 175 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 177 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\tvar _Dropdown = __webpack_require__(105);\n\t\n\tvar _Dropdown2 = _interopRequireDefault(_Dropdown);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t components: {\n\t dropdown: _Dropdown2.default\n\t },\n\t props: {\n\t // effect: {type: String, default: 'fadein'},\n\t justified: false,\n\t navStyle: { type: String, default: null },\n\t value: { type: Number, default: 0 }\n\t },\n\t data: function data() {\n\t var index = this.value || 0;\n\t return {\n\t index: index,\n\t headers: [],\n\t tabs: []\n\t };\n\t },\n\t\n\t watch: {\n\t index: function index(val) {\n\t this.$emit('active', val);\n\t this.$emit('input', val);\n\t },\n\t value: function value(val) {\n\t this.index = val;\n\t }\n\t },\n\t computed: {\n\t navStyleClass: function navStyleClass() {\n\t return ['nav', ~['pills', 'stacked'].indexOf(this.navStyle) ? 'nav-' + this.navStyle : 'nav-tabs', {\n\t 'nav-justified': _utils.coerce.boolean(this.justified),\n\t 'nav-pills': this.navStyle === 'stacked'\n\t }];\n\t },\n\t show: function show() {\n\t return this.tabs[this.index] || this.tabs[0];\n\t }\n\t },\n\t methods: {\n\t select: function select(tab) {\n\t if (!tab.disabled) {\n\t this.index = this.tabs.indexOf(tab);\n\t }\n\t }\n\t },\n\t created: function created() {\n\t this._isTabs = true;\n\t }\n\t};\n\n/***/ },\n/* 178 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t attrs: {\n\t \"tabs\": \"\"\n\t }\n\t }, [_vm._c('ul', {\n\t class: _vm.navStyleClass,\n\t attrs: {\n\t \"role\": \"tablist\"\n\t }\n\t }, [_vm._l((_vm.headers), function(header) {\n\t return [(header._isTab) ? _vm._c('li', {\n\t class: {\n\t active: header.active, disabled: header.disabled\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t $event.preventDefault();\n\t _vm.select(header)\n\t }\n\t }\n\t }, [_vm._t(\"header\", [_vm._c('a', {\n\t attrs: {\n\t \"href\": \"#\"\n\t },\n\t domProps: {\n\t \"innerHTML\": _vm._s(header.header)\n\t }\n\t })])], 2) : _vm._e(), _vm._v(\" \"), (header._isTabGroup) ? _vm._c('dropdown', {\n\t class: {\n\t active: header.active\n\t },\n\t attrs: {\n\t \"text\": header.header,\n\t \"disabled\": header.disabled\n\t }\n\t }, _vm._l((header.tabs), function(tab) {\n\t return _vm._c('li', {\n\t class: {\n\t disabled: tab.disabled\n\t }\n\t }, [_vm._c('a', {\n\t attrs: {\n\t \"href\": \"#\"\n\t },\n\t on: {\n\t \"click\": function($event) {\n\t $event.preventDefault();\n\t _vm.select(tab)\n\t }\n\t }\n\t }, [_vm._v(_vm._s(tab.header))])])\n\t })) : _vm._e()]\n\t })], 2), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"tab-content\"\n\t }, [_vm._t(\"default\")], 2)])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-70100ddf\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 179 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(180)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(181)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\ToggleButton.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-f034a5f2\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-f034a5f2\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] ToggleButton.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 180 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\texports.default = {\n\t props: {\n\t disabled: { default: null },\n\t falseType: { default: null },\n\t name: null,\n\t readonly: { default: null },\n\t trueType: { default: 'primary' },\n\t value: false\n\t },\n\t data: function data() {\n\t return {\n\t active: _utils.coerce.boolean(this.value),\n\t types: {\n\t danger: 'btn-danger',\n\t info: 'btn-info',\n\t primary: 'btn-primary',\n\t success: 'btn-success',\n\t warning: 'btn-warning'\n\t }\n\t };\n\t },\n\t\n\t watch: {\n\t active: function active(val, old) {\n\t if (val !== old) {\n\t this.$emit('changed', val);\n\t this.$emit(val ? 'enabled' : 'disabled');\n\t this.$emit('input', val);\n\t }\n\t },\n\t value: function value(val, old) {\n\t if (val !== old) {\n\t this.active = _utils.coerce.boolean(this.value);\n\t }\n\t }\n\t },\n\t computed: {\n\t boolDisabled: function boolDisabled() {\n\t return _utils.coerce.boolean(this.disabled);\n\t },\n\t boolReadonly: function boolReadonly() {\n\t return _utils.coerce.boolean(this.readonly);\n\t },\n\t type: function type() {\n\t return this.types[this.value ? this.trueType : this.falseType] || 'btn-default';\n\t }\n\t },\n\t methods: {\n\t toggle: function toggle() {\n\t if (this.boolDisabled || this.boolReadonly) {\n\t return;\n\t }\n\t this.active = !this.active;\n\t }\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 181 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('a', {\n\t class: ['btn', _vm.type, {\n\t readonly: _vm.boolReadonly\n\t }],\n\t attrs: {\n\t \"href\": \"javascript:void(0)\",\n\t \"disabled\": _vm.boolDisabled\n\t },\n\t on: {\n\t \"click\": _vm.toggle\n\t }\n\t }, [_vm._c('span', {\n\t class: ['glyphicon', 'glyphicon-' + (_vm.value ? 'ok' : 'remove')]\n\t }), _vm._v(\" \"), _vm._t(\"default\"), _vm._v(\" \"), (_vm.name) ? _vm._c('input', {\n\t attrs: {\n\t \"type\": \"hidden\",\n\t \"name\": _vm.name\n\t },\n\t domProps: {\n\t \"value\": _vm.active ? 1 : 0\n\t }\n\t }) : _vm._e()], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-f034a5f2\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 182 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(183)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(185)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(186)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Tooltip.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-48fb51b2\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-48fb51b2\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Tooltip.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 183 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 185 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _popoverMixins = __webpack_require__(143);\n\t\n\tvar _popoverMixins2 = _interopRequireDefault(_popoverMixins);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = {\n\t mixins: [_popoverMixins2.default],\n\t props: {\n\t effect: { type: String, default: 'scale' },\n\t trigger: { type: String, default: 'hover' }\n\t }\n\t}; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\n/***/ },\n/* 186 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('span', {\n\t ref: \"trigger\"\n\t }, [_vm._t(\"default\"), _vm._v(\" \"), _vm._c('transition', {\n\t attrs: {\n\t \"name\": _vm.effect\n\t }\n\t }, [(_vm.show) ? _vm._c('div', {\n\t ref: \"popover\",\n\t class: ['tooltip', _vm.placement]\n\t }, [_vm._c('div', {\n\t staticClass: \"tooltip-arrow\"\n\t }), _vm._v(\" \"), _vm._c('div', {\n\t staticClass: \"tooltip-inner\"\n\t }, [_vm._t(\"content\", [_vm._c('div', {\n\t domProps: {\n\t \"innerHTML\": _vm._s(_vm.content)\n\t }\n\t })])], 2)]) : _vm._e()])], 2)\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-48fb51b2\", module.exports)\n\t }\n\t}\n\n/***/ },\n/* 187 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_exports__, __vue_options__\n\tvar __vue_styles__ = {}\n\t\n\t/* styles */\n\t__webpack_require__(188)\n\t\n\t/* script */\n\t__vue_exports__ = __webpack_require__(190)\n\t\n\t/* template */\n\tvar __vue_template__ = __webpack_require__(206)\n\t__vue_options__ = __vue_exports__ = __vue_exports__ || {}\n\tif (\n\t typeof __vue_exports__.default === \"object\" ||\n\t typeof __vue_exports__.default === \"function\"\n\t) {\n\tif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n\t__vue_options__ = __vue_exports__ = __vue_exports__.default\n\t}\n\tif (typeof __vue_options__ === \"function\") {\n\t __vue_options__ = __vue_options__.options\n\t}\n\t__vue_options__.__file = \"C:\\\\laragon\\\\www\\\\vue-strap\\\\src\\\\Typeahead.vue\"\n\t__vue_options__.render = __vue_template__.render\n\t__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\t\n\t/* hot reload */\n\tif (false) {(function () {\n\t var hotAPI = require(\"vue-hot-reload-api\")\n\t hotAPI.install(require(\"vue\"), false)\n\t if (!hotAPI.compatible) return\n\t module.hot.accept()\n\t if (!module.hot.data) {\n\t hotAPI.createRecord(\"data-v-5b5f5e94\", __vue_options__)\n\t } else {\n\t hotAPI.reload(\"data-v-5b5f5e94\", __vue_options__)\n\t }\n\t})()}\n\tif (__vue_options__.functional) {console.error(\"[vue-loader] Typeahead.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\t\n\tmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 188 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// style-loader: Adds some css to the DOM by adding a \"],\"sourceRoot\":\"webpack://\"}]);\n\t\n\t// exports\n\n\n/***/ },\n/* 190 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _typeof2 = __webpack_require__(191);\n\t\n\tvar _typeof3 = _interopRequireDefault(_typeof2);\n\t\n\tvar _utils = __webpack_require__(65);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tvar DELAY = 300; //\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t//\n\t\n\texports.default = {\n\t props: {\n\t async: { type: String },\n\t data: { type: Array },\n\t delay: { type: Number, default: DELAY },\n\t asyncKey: { type: String, default: null },\n\t limit: { type: Number, default: 8 },\n\t matchCase: { type: Boolean, default: false },\n\t matchStart: { type: Boolean, default: false },\n\t onHit: {\n\t type: Function,\n\t default: function _default(item) {\n\t return item;\n\t }\n\t },\n\t placeholder: { type: String },\n\t template: { type: String },\n\t type: { type: String, default: 'text' },\n\t value: { type: String, default: '' }\n\t },\n\t data: function data() {\n\t return {\n\t asign: '',\n\t showDropdown: false,\n\t noResults: true,\n\t current: 0,\n\t items: [],\n\t val: this.value\n\t };\n\t },\n\t\n\t computed: {\n\t templateComp: function templateComp() {\n\t return {\n\t template: typeof this.template === 'string' ? '' + this.template + '' : '',\n\t props: { item: { default: null } }\n\t };\n\t }\n\t },\n\t watch: {\n\t val: function val(_val, old) {\n\t this.$emit('input', _val);\n\t if (_val !== old && _val !== this.asign) this.__update();\n\t },\n\t value: function value(val) {\n\t if (this.val !== val) {\n\t this.val = val;\n\t }\n\t }\n\t },\n\t methods: {\n\t setItems: function setItems(data) {\n\t var _this = this;\n\t\n\t if (this.async) {\n\t this.items = this.asyncKey ? data[this.asyncKey] : data;\n\t this.items = this.items.slice(0, this.limit);\n\t } else {\n\t this.items = (data || []).filter(function (value) {\n\t if ((typeof value === 'undefined' ? 'undefined' : (0, _typeof3.default)(value)) === 'object') {\n\t return true;\n\t }\n\t value = _this.matchCase ? value : value.toLowerCase();\n\t var query = _this.matchCase ? _this.val : _this.val.toLowerCase();\n\t return _this.matchStart ? value.indexOf(query) === 0 : value.indexOf(query) !== -1;\n\t }).slice(0, this.limit);\n\t }\n\t this.showDropdown = this.items.length > 0;\n\t },\n\t setValue: function setValue(value) {\n\t this.asign = value;\n\t this.val = value;\n\t this.items = [];\n\t this.loading = false;\n\t this.showDropdown = false;\n\t },\n\t reset: function reset() {\n\t this.setValue(null);\n\t },\n\t setActive: function setActive(index) {\n\t this.current = index;\n\t },\n\t isActive: function isActive(index) {\n\t return this.current === index;\n\t },\n\t hit: function hit(e) {\n\t e.preventDefault();\n\t this.setValue(this.onHit(this.items[this.current], this));\n\t },\n\t up: function up() {\n\t if (this.current > 0) {\n\t this.current--;\n\t } else {\n\t this.current = this.items.length - 1;\n\t }\n\t },\n\t down: function down() {\n\t if (this.current < this.items.length - 1) {\n\t this.current++;\n\t } else {\n\t this.current = 0;\n\t }\n\t }\n\t },\n\t created: function created() {\n\t this.__update = (0, _utils.delayer)(function () {\n\t var _this2 = this;\n\t\n\t if (!this.val) {\n\t this.reset();\n\t return;\n\t }\n\t this.asign = '';\n\t if (this.async) {\n\t (0, _utils.getJSON)(this.async + this.val).then(function (data) {\n\t _this2.setItems(data);\n\t });\n\t } else if (this.data) {\n\t this.setItems(this.data);\n\t }\n\t }, 'delay', DELAY);\n\t this.__update();\n\t }\n\t};\n\n/***/ },\n/* 191 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\texports.__esModule = true;\n\t\n\tvar _iterator = __webpack_require__(20);\n\t\n\tvar _iterator2 = _interopRequireDefault(_iterator);\n\t\n\tvar _symbol = __webpack_require__(192);\n\t\n\tvar _symbol2 = _interopRequireDefault(_symbol);\n\t\n\tvar _typeof = typeof _symbol2.default === \"function\" && typeof _iterator2.default === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof _symbol2.default === \"function\" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? \"symbol\" : typeof obj; };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = typeof _symbol2.default === \"function\" && _typeof(_iterator2.default) === \"symbol\" ? function (obj) {\n\t return typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj);\n\t} : function (obj) {\n\t return obj && typeof _symbol2.default === \"function\" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? \"symbol\" : typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj);\n\t};\n\n/***/ },\n/* 192 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = { \"default\": __webpack_require__(193), __esModule: true };\n\n/***/ },\n/* 193 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(194);\n\t__webpack_require__(203);\n\t__webpack_require__(204);\n\t__webpack_require__(205);\n\tmodule.exports = __webpack_require__(7).Symbol;\n\n/***/ },\n/* 194 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t// ECMAScript 6 symbols shim\n\tvar global = __webpack_require__(6)\n\t , has = __webpack_require__(29)\n\t , DESCRIPTORS = __webpack_require__(15)\n\t , $export = __webpack_require__(5)\n\t , redefine = __webpack_require__(28)\n\t , META = __webpack_require__(195).KEY\n\t , $fails = __webpack_require__(16)\n\t , shared = __webpack_require__(43)\n\t , setToStringTag = __webpack_require__(47)\n\t , uid = __webpack_require__(44)\n\t , wks = __webpack_require__(48)\n\t , wksExt = __webpack_require__(55)\n\t , wksDefine = __webpack_require__(196)\n\t , keyOf = __webpack_require__(197)\n\t , enumKeys = __webpack_require__(198)\n\t , isArray = __webpack_require__(201)\n\t , anObject = __webpack_require__(12)\n\t , toIObject = __webpack_require__(36)\n\t , toPrimitive = __webpack_require__(18)\n\t , createDesc = __webpack_require__(19)\n\t , _create = __webpack_require__(32)\n\t , gOPNExt = __webpack_require__(60)\n\t , $GOPD = __webpack_require__(202)\n\t , $DP = __webpack_require__(11)\n\t , $keys = __webpack_require__(34)\n\t , gOPD = $GOPD.f\n\t , dP = $DP.f\n\t , gOPN = gOPNExt.f\n\t , $Symbol = global.Symbol\n\t , $JSON = global.JSON\n\t , _stringify = $JSON && $JSON.stringify\n\t , PROTOTYPE = 'prototype'\n\t , HIDDEN = wks('_hidden')\n\t , TO_PRIMITIVE = wks('toPrimitive')\n\t , isEnum = {}.propertyIsEnumerable\n\t , SymbolRegistry = shared('symbol-registry')\n\t , AllSymbols = shared('symbols')\n\t , OPSymbols = shared('op-symbols')\n\t , ObjectProto = Object[PROTOTYPE]\n\t , USE_NATIVE = typeof $Symbol == 'function'\n\t , QObject = global.QObject;\n\t// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173\n\tvar setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;\n\t\n\t// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\n\tvar setSymbolDesc = DESCRIPTORS && $fails(function(){\n\t return _create(dP({}, 'a', {\n\t get: function(){ return dP(this, 'a', {value: 7}).a; }\n\t })).a != 7;\n\t}) ? function(it, key, D){\n\t var protoDesc = gOPD(ObjectProto, key);\n\t if(protoDesc)delete ObjectProto[key];\n\t dP(it, key, D);\n\t if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc);\n\t} : dP;\n\t\n\tvar wrap = function(tag){\n\t var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);\n\t sym._k = tag;\n\t return sym;\n\t};\n\t\n\tvar isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){\n\t return typeof it == 'symbol';\n\t} : function(it){\n\t return it instanceof $Symbol;\n\t};\n\t\n\tvar $defineProperty = function defineProperty(it, key, D){\n\t if(it === ObjectProto)$defineProperty(OPSymbols, key, D);\n\t anObject(it);\n\t key = toPrimitive(key, true);\n\t anObject(D);\n\t if(has(AllSymbols, key)){\n\t if(!D.enumerable){\n\t if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {}));\n\t it[HIDDEN][key] = true;\n\t } else {\n\t if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;\n\t D = _create(D, {enumerable: createDesc(0, false)});\n\t } return setSymbolDesc(it, key, D);\n\t } return dP(it, key, D);\n\t};\n\tvar $defineProperties = function defineProperties(it, P){\n\t anObject(it);\n\t var keys = enumKeys(P = toIObject(P))\n\t , i = 0\n\t , l = keys.length\n\t , key;\n\t while(l > i)$defineProperty(it, key = keys[i++], P[key]);\n\t return it;\n\t};\n\tvar $create = function create(it, P){\n\t return P === undefined ? _create(it) : $defineProperties(_create(it), P);\n\t};\n\tvar $propertyIsEnumerable = function propertyIsEnumerable(key){\n\t var E = isEnum.call(this, key = toPrimitive(key, true));\n\t if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false;\n\t return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;\n\t};\n\tvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){\n\t it = toIObject(it);\n\t key = toPrimitive(key, true);\n\t if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return;\n\t var D = gOPD(it, key);\n\t if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;\n\t return D;\n\t};\n\tvar $getOwnPropertyNames = function getOwnPropertyNames(it){\n\t var names = gOPN(toIObject(it))\n\t , result = []\n\t , i = 0\n\t , key;\n\t while(names.length > i){\n\t if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key);\n\t } return result;\n\t};\n\tvar $getOwnPropertySymbols = function getOwnPropertySymbols(it){\n\t var IS_OP = it === ObjectProto\n\t , names = gOPN(IS_OP ? OPSymbols : toIObject(it))\n\t , result = []\n\t , i = 0\n\t , key;\n\t while(names.length > i){\n\t if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]);\n\t } return result;\n\t};\n\t\n\t// 19.4.1.1 Symbol([description])\n\tif(!USE_NATIVE){\n\t $Symbol = function Symbol(){\n\t if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!');\n\t var tag = uid(arguments.length > 0 ? arguments[0] : undefined);\n\t var $set = function(value){\n\t if(this === ObjectProto)$set.call(OPSymbols, value);\n\t if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;\n\t setSymbolDesc(this, tag, createDesc(1, value));\n\t };\n\t if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set});\n\t return wrap(tag);\n\t };\n\t redefine($Symbol[PROTOTYPE], 'toString', function toString(){\n\t return this._k;\n\t });\n\t\n\t $GOPD.f = $getOwnPropertyDescriptor;\n\t $DP.f = $defineProperty;\n\t __webpack_require__(61).f = gOPNExt.f = $getOwnPropertyNames;\n\t __webpack_require__(200).f = $propertyIsEnumerable;\n\t __webpack_require__(199).f = $getOwnPropertySymbols;\n\t\n\t if(DESCRIPTORS && !__webpack_require__(27)){\n\t redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);\n\t }\n\t\n\t wksExt.f = function(name){\n\t return wrap(wks(name));\n\t }\n\t}\n\t\n\t$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol});\n\t\n\tfor(var symbols = (\n\t // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14\n\t 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'\n\t).split(','), i = 0; symbols.length > i; )wks(symbols[i++]);\n\t\n\tfor(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]);\n\t\n\t$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {\n\t // 19.4.2.1 Symbol.for(key)\n\t 'for': function(key){\n\t return has(SymbolRegistry, key += '')\n\t ? SymbolRegistry[key]\n\t : SymbolRegistry[key] = $Symbol(key);\n\t },\n\t // 19.4.2.5 Symbol.keyFor(sym)\n\t keyFor: function keyFor(key){\n\t if(isSymbol(key))return keyOf(SymbolRegistry, key);\n\t throw TypeError(key + ' is not a symbol!');\n\t },\n\t useSetter: function(){ setter = true; },\n\t useSimple: function(){ setter = false; }\n\t});\n\t\n\t$export($export.S + $export.F * !USE_NATIVE, 'Object', {\n\t // 19.1.2.2 Object.create(O [, Properties])\n\t create: $create,\n\t // 19.1.2.4 Object.defineProperty(O, P, Attributes)\n\t defineProperty: $defineProperty,\n\t // 19.1.2.3 Object.defineProperties(O, Properties)\n\t defineProperties: $defineProperties,\n\t // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\n\t getOwnPropertyDescriptor: $getOwnPropertyDescriptor,\n\t // 19.1.2.7 Object.getOwnPropertyNames(O)\n\t getOwnPropertyNames: $getOwnPropertyNames,\n\t // 19.1.2.8 Object.getOwnPropertySymbols(O)\n\t getOwnPropertySymbols: $getOwnPropertySymbols\n\t});\n\t\n\t// 24.3.2 JSON.stringify(value [, replacer [, space]])\n\t$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){\n\t var S = $Symbol();\n\t // MS Edge converts symbol values to JSON as {}\n\t // WebKit converts symbol values to JSON as null\n\t // V8 throws on boxed symbols\n\t return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';\n\t})), 'JSON', {\n\t stringify: function stringify(it){\n\t if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined\n\t var args = [it]\n\t , i = 1\n\t , replacer, $replacer;\n\t while(arguments.length > i)args.push(arguments[i++]);\n\t replacer = args[1];\n\t if(typeof replacer == 'function')$replacer = replacer;\n\t if($replacer || !isArray(replacer))replacer = function(key, value){\n\t if($replacer)value = $replacer.call(this, key, value);\n\t if(!isSymbol(value))return value;\n\t };\n\t args[1] = replacer;\n\t return _stringify.apply($JSON, args);\n\t }\n\t});\n\t\n\t// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)\n\t$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(10)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);\n\t// 19.4.3.5 Symbol.prototype[@@toStringTag]\n\tsetToStringTag($Symbol, 'Symbol');\n\t// 20.2.1.9 Math[@@toStringTag]\n\tsetToStringTag(Math, 'Math', true);\n\t// 24.3.3 JSON[@@toStringTag]\n\tsetToStringTag(global.JSON, 'JSON', true);\n\n/***/ },\n/* 195 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar META = __webpack_require__(44)('meta')\n\t , isObject = __webpack_require__(13)\n\t , has = __webpack_require__(29)\n\t , setDesc = __webpack_require__(11).f\n\t , id = 0;\n\tvar isExtensible = Object.isExtensible || function(){\n\t return true;\n\t};\n\tvar FREEZE = !__webpack_require__(16)(function(){\n\t return isExtensible(Object.preventExtensions({}));\n\t});\n\tvar setMeta = function(it){\n\t setDesc(it, META, {value: {\n\t i: 'O' + ++id, // object ID\n\t w: {} // weak collections IDs\n\t }});\n\t};\n\tvar fastKey = function(it, create){\n\t // return primitive with prefix\n\t if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n\t if(!has(it, META)){\n\t // can't set metadata to uncaught frozen object\n\t if(!isExtensible(it))return 'F';\n\t // not necessary to add metadata\n\t if(!create)return 'E';\n\t // add missing metadata\n\t setMeta(it);\n\t // return object ID\n\t } return it[META].i;\n\t};\n\tvar getWeak = function(it, create){\n\t if(!has(it, META)){\n\t // can't set metadata to uncaught frozen object\n\t if(!isExtensible(it))return true;\n\t // not necessary to add metadata\n\t if(!create)return false;\n\t // add missing metadata\n\t setMeta(it);\n\t // return hash weak collections IDs\n\t } return it[META].w;\n\t};\n\t// add metadata on freeze-family methods calling\n\tvar onFreeze = function(it){\n\t if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it);\n\t return it;\n\t};\n\tvar meta = module.exports = {\n\t KEY: META,\n\t NEED: false,\n\t fastKey: fastKey,\n\t getWeak: getWeak,\n\t onFreeze: onFreeze\n\t};\n\n/***/ },\n/* 196 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar global = __webpack_require__(6)\n\t , core = __webpack_require__(7)\n\t , LIBRARY = __webpack_require__(27)\n\t , wksExt = __webpack_require__(55)\n\t , defineProperty = __webpack_require__(11).f;\n\tmodule.exports = function(name){\n\t var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});\n\t if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)});\n\t};\n\n/***/ },\n/* 197 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar getKeys = __webpack_require__(34)\n\t , toIObject = __webpack_require__(36);\n\tmodule.exports = function(object, el){\n\t var O = toIObject(object)\n\t , keys = getKeys(O)\n\t , length = keys.length\n\t , index = 0\n\t , key;\n\t while(length > index)if(O[key = keys[index++]] === el)return key;\n\t};\n\n/***/ },\n/* 198 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// all enumerable object keys, includes symbols\n\tvar getKeys = __webpack_require__(34)\n\t , gOPS = __webpack_require__(199)\n\t , pIE = __webpack_require__(200);\n\tmodule.exports = function(it){\n\t var result = getKeys(it)\n\t , getSymbols = gOPS.f;\n\t if(getSymbols){\n\t var symbols = getSymbols(it)\n\t , isEnum = pIE.f\n\t , i = 0\n\t , key;\n\t while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key);\n\t } return result;\n\t};\n\n/***/ },\n/* 199 */\n/***/ function(module, exports) {\n\n\texports.f = Object.getOwnPropertySymbols;\n\n/***/ },\n/* 200 */\n/***/ function(module, exports) {\n\n\texports.f = {}.propertyIsEnumerable;\n\n/***/ },\n/* 201 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// 7.2.2 IsArray(argument)\n\tvar cof = __webpack_require__(38);\n\tmodule.exports = Array.isArray || function isArray(arg){\n\t return cof(arg) == 'Array';\n\t};\n\n/***/ },\n/* 202 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar pIE = __webpack_require__(200)\n\t , createDesc = __webpack_require__(19)\n\t , toIObject = __webpack_require__(36)\n\t , toPrimitive = __webpack_require__(18)\n\t , has = __webpack_require__(29)\n\t , IE8_DOM_DEFINE = __webpack_require__(14)\n\t , gOPD = Object.getOwnPropertyDescriptor;\n\t\n\texports.f = __webpack_require__(15) ? gOPD : function getOwnPropertyDescriptor(O, P){\n\t O = toIObject(O);\n\t P = toPrimitive(P, true);\n\t if(IE8_DOM_DEFINE)try {\n\t return gOPD(O, P);\n\t } catch(e){ /* empty */ }\n\t if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]);\n\t};\n\n/***/ },\n/* 203 */\n/***/ function(module, exports) {\n\n\n\n/***/ },\n/* 204 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(196)('asyncIterator');\n\n/***/ },\n/* 205 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(196)('observable');\n\n/***/ },\n/* 206 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;\n\t return _vm._c('div', {\n\t class: {\n\t open: _vm.showDropdown\n\t },\n\t staticStyle: {\n\t \"position\": \"relative\"\n\t }\n\t }, [_vm._c('input', {\n\t directives: [{\n\t name: \"model\",\n\t rawName: \"v-model\",\n\t value: (_vm.val),\n\t expression: \"val\"\n\t }],\n\t staticClass: \"form-control\",\n\t attrs: {\n\t \"autocomplete\": \"off\",\n\t \"placeholder\": _vm.placeholder,\n\t \"type\": _vm.type\n\t },\n\t domProps: {\n\t \"value\": _vm._s(_vm.val)\n\t },\n\t on: {\n\t \"blur\": function($event) {\n\t _vm.showDropdown = false\n\t },\n\t \"keydown\": [function($event) {\n\t if (_vm._k($event.keyCode, \"down\", 40)) { return; }\n\t $event.preventDefault();\n\t _vm.down($event)\n\t }, function($event) {\n\t if (_vm._k($event.keyCode, \"enter\", 13)) { return; }\n\t _vm.hit($event)\n\t }, function($event) {\n\t if (_vm._k($event.keyCode, \"esc\", 27)) { return; }\n\t _vm.reset($event)\n\t }, function($event) {\n\t if (_vm._k($event.keyCode, \"up\", 38)) { return; }\n\t $event.preventDefault();\n\t _vm.up($event)\n\t }],\n\t \"input\": function($event) {\n\t if ($event.target.composing) { return; }\n\t _vm.val = $event.target.value\n\t }\n\t }\n\t }), _vm._v(\" \"), _vm._c('ul', {\n\t ref: \"dropdown\",\n\t staticClass: \"dropdown-menu\"\n\t }, _vm._l((_vm.items), function(item, i) {\n\t return _vm._c('li', {\n\t class: {\n\t active: _vm.isActive(i)\n\t }\n\t }, [_vm._c('a', {\n\t on: {\n\t \"mousedown\": function($event) {\n\t $event.preventDefault();\n\t _vm.hit($event)\n\t },\n\t \"mousemove\": function($event) {\n\t _vm.setActive(i)\n\t }\n\t }\n\t }, [_vm._c(_vm.templateComp, {\n\t tag: \"component\",\n\t attrs: {\n\t \"item\": item\n\t }\n\t })], 1)])\n\t }))])\n\t},staticRenderFns: []}\n\tif (false) {\n\t module.hot.accept()\n\t if (module.hot.data) {\n\t require(\"vue-hot-reload-api\").rerender(\"data-v-5b5f5e94\", module.exports)\n\t }\n\t}\n\n/***/ }\n/******/ ])\n});\n;\n//# sourceMappingURL=vue-strap.js.map//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L3Z1ZS1zdHJhcC9kaXN0L3Z1ZS1zdHJhcC5qcz9lMTQ3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogdnVlLXN0cmFwIDIuMC4yXG4gKiBodHRwOi8vd2ZmcmFuY28uZ2l0aHViLmlvL3Z1ZS1zdHJhcC9cbiAqIENvbXBpbGVkIHVzaW5nIFZ1ZSAyLjEuMTBcbiAqL1xuKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiVnVlU3RyYXBcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wiVnVlU3RyYXBcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiAvKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4vKioqKioqLyBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4vKioqKioqLyBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbi8qKioqKiovIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4vKioqKioqLyBcdFx0XHRleHBvcnRzOiB7fSxcbi8qKioqKiovIFx0XHRcdGlkOiBtb2R1bGVJZCxcbi8qKioqKiovIFx0XHRcdGxvYWRlZDogZmFsc2Vcbi8qKioqKiovIFx0XHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbi8qKioqKiovIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuLyoqKioqKi8gXHRcdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuLyoqKioqKi8gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbi8qKioqKiovIFx0fVxuLyoqKioqKi9cbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLyoqKioqKi8gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcbi8qKioqKiovIH0pXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyoqKioqKi8gKFtcbi8qIDAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdHZhciBfTm9kZUxpc3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXHRcblx0dmFyIF9Ob2RlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Ob2RlTGlzdCk7XG5cdFxuXHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2NSk7XG5cdFxuXHR2YXIgX0NsaWNrT3V0c2lkZSA9IF9fd2VicGFja19yZXF1aXJlX18oNjYpO1xuXHRcblx0dmFyIF9DbGlja091dHNpZGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2xpY2tPdXRzaWRlKTtcblx0XG5cdHZhciBfU2Nyb2xsID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2OCk7XG5cdFxuXHR2YXIgX1Njcm9sbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TY3JvbGwpO1xuXHRcblx0dmFyIF9BY2NvcmRpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDY5KTtcblx0XG5cdHZhciBfQWNjb3JkaW9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FjY29yZGlvbik7XG5cdFxuXHR2YXIgX0FmZml4ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3Mik7XG5cdFxuXHR2YXIgX0FmZml4MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FmZml4KTtcblx0XG5cdHZhciBfQWxlcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc1KTtcblx0XG5cdHZhciBfQWxlcnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQWxlcnQpO1xuXHRcblx0dmFyIF9Bc2lkZSA9IF9fd2VicGFja19yZXF1aXJlX18oODIpO1xuXHRcblx0dmFyIF9Bc2lkZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Bc2lkZSk7XG5cdFxuXHR2YXIgX0J1dHRvbkdyb3VwID0gX193ZWJwYWNrX3JlcXVpcmVfXyg4Nyk7XG5cdFxuXHR2YXIgX0J1dHRvbkdyb3VwMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0J1dHRvbkdyb3VwKTtcblx0XG5cdHZhciBfQ2Fyb3VzZWwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDkwKTtcblx0XG5cdHZhciBfQ2Fyb3VzZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2Fyb3VzZWwpO1xuXHRcblx0dmFyIF9DaGVja2JveCA9IF9fd2VicGFja19yZXF1aXJlX18oOTUpO1xuXHRcblx0dmFyIF9DaGVja2JveDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGVja2JveCk7XG5cdFxuXHR2YXIgX0RhdGVwaWNrZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEwMCk7XG5cdFxuXHR2YXIgX0RhdGVwaWNrZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfRGF0ZXBpY2tlcik7XG5cdFxuXHR2YXIgX0Ryb3Bkb3duID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMDUpO1xuXHRcblx0dmFyIF9Ecm9wZG93bjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Ecm9wZG93bik7XG5cdFxuXHR2YXIgX0Zvcm1Hcm91cCA9IF9fd2VicGFja19yZXF1aXJlX18oMTA4KTtcblx0XG5cdHZhciBfRm9ybUdyb3VwMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0Zvcm1Hcm91cCk7XG5cdFxuXHR2YXIgX0Zvcm1WYWxpZGF0b3IgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDExMSk7XG5cdFxuXHR2YXIgX0Zvcm1WYWxpZGF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfRm9ybVZhbGlkYXRvcik7XG5cdFxuXHR2YXIgX0lucHV0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMTQpO1xuXHRcblx0dmFyIF9JbnB1dDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9JbnB1dCk7XG5cdFxuXHR2YXIgX01vZGFsID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMTkpO1xuXHRcblx0dmFyIF9Nb2RhbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Nb2RhbCk7XG5cdFxuXHR2YXIgX05hdmJhciA9IF9fd2VicGFja19yZXF1aXJlX18oMTI4KTtcblx0XG5cdHZhciBfTmF2YmFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX05hdmJhcik7XG5cdFxuXHR2YXIgX09wdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMTMxKTtcblx0XG5cdHZhciBfT3B0aW9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX09wdGlvbik7XG5cdFxuXHR2YXIgX1BhbmVsID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMzQpO1xuXHRcblx0dmFyIF9QYW5lbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9QYW5lbCk7XG5cdFxuXHR2YXIgX1BvcG92ZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzOSk7XG5cdFxuXHR2YXIgX1BvcG92ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUG9wb3Zlcik7XG5cdFxuXHR2YXIgX1Byb2dyZXNzYmFyID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNDUpO1xuXHRcblx0dmFyIF9Qcm9ncmVzc2JhcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Qcm9ncmVzc2Jhcik7XG5cdFxuXHR2YXIgX1JhZGlvID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNDgpO1xuXHRcblx0dmFyIF9SYWRpbzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9SYWRpbyk7XG5cdFxuXHR2YXIgX1NlbGVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oMTUzKTtcblx0XG5cdHZhciBfU2VsZWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NlbGVjdCk7XG5cdFxuXHR2YXIgX1NsaWRlciA9IF9fd2VicGFja19yZXF1aXJlX18oMTU4KTtcblx0XG5cdHZhciBfU2xpZGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NsaWRlcik7XG5cdFxuXHR2YXIgX1NwaW5uZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2MSk7XG5cdFxuXHR2YXIgX1NwaW5uZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU3Bpbm5lcik7XG5cdFxuXHR2YXIgX1RhYiA9IF9fd2VicGFja19yZXF1aXJlX18oMTY2KTtcblx0XG5cdHZhciBfVGFiMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1RhYik7XG5cdFxuXHR2YXIgX1RhYkdyb3VwID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNjkpO1xuXHRcblx0dmFyIF9UYWJHcm91cDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9UYWJHcm91cCk7XG5cdFxuXHR2YXIgX1RhYnMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE3NCk7XG5cdFxuXHR2YXIgX1RhYnMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVGFicyk7XG5cdFxuXHR2YXIgX1RvZ2dsZUJ1dHRvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMTc5KTtcblx0XG5cdHZhciBfVG9nZ2xlQnV0dG9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1RvZ2dsZUJ1dHRvbik7XG5cdFxuXHR2YXIgX1Rvb2x0aXAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE4Mik7XG5cdFxuXHR2YXIgX1Rvb2x0aXAyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVG9vbHRpcCk7XG5cdFxuXHR2YXIgX1R5cGVhaGVhZCA9IF9fd2VicGFja19yZXF1aXJlX18oMTg3KTtcblx0XG5cdHZhciBfVHlwZWFoZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1R5cGVhaGVhZCk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0Ly8gQ29tcG9uZW50c1xuXHRcblx0Ly8gRGlyZWN0aXZlc1xuXHQvLyBVdGlsc1xuXHR2YXIgVnVlU3RyYXAgPSB7XG5cdCAgZGlyZWN0aXZlczoge1xuXHQgICAgQ2xpY2tPdXRzaWRlOiBfQ2xpY2tPdXRzaWRlMi5kZWZhdWx0LFxuXHQgICAgU2Nyb2xsOiBfU2Nyb2xsMi5kZWZhdWx0XG5cdCAgfSxcblx0ICB1dGlsczoge1xuXHQgICAgJDogX05vZGVMaXN0Mi5kZWZhdWx0LFxuXHQgICAgY29lcmNlOiBfdXRpbHMuY29lcmNlXG5cdCAgfSxcblx0ICAvL2NvbXBvbmVudHNcblx0ICBhY2NvcmRpb246IF9BY2NvcmRpb24yLmRlZmF1bHQsXG5cdCAgYWZmaXg6IF9BZmZpeDIuZGVmYXVsdCxcblx0ICBhbGVydDogX0FsZXJ0Mi5kZWZhdWx0LFxuXHQgIGFzaWRlOiBfQXNpZGUyLmRlZmF1bHQsXG5cdCAgYnV0dG9uR3JvdXA6IF9CdXR0b25Hcm91cDIuZGVmYXVsdCxcblx0ICBjYXJvdXNlbDogX0Nhcm91c2VsMi5kZWZhdWx0LFxuXHQgIGNoZWNrYm94OiBfQ2hlY2tib3gyLmRlZmF1bHQsXG5cdCAgZGF0ZXBpY2tlcjogX0RhdGVwaWNrZXIyLmRlZmF1bHQsXG5cdCAgZHJvcGRvd246IF9Ecm9wZG93bjIuZGVmYXVsdCxcblx0ICBmb3JtR3JvdXA6IF9Gb3JtR3JvdXAyLmRlZmF1bHQsXG5cdCAgZm9ybVZhbGlkYXRvcjogX0Zvcm1WYWxpZGF0b3IyLmRlZmF1bHQsXG5cdCAgaW5wdXQ6IF9JbnB1dDIuZGVmYXVsdCxcblx0ICBtb2RhbDogX01vZGFsMi5kZWZhdWx0LFxuXHQgIG5hdmJhcjogX05hdmJhcjIuZGVmYXVsdCxcblx0ICBvcHRpb246IF9PcHRpb24yLmRlZmF1bHQsXG5cdCAgcGFuZWw6IF9QYW5lbDIuZGVmYXVsdCxcblx0ICBwb3BvdmVyOiBfUG9wb3ZlcjIuZGVmYXVsdCxcblx0ICBwcm9ncmVzc2JhcjogX1Byb2dyZXNzYmFyMi5kZWZhdWx0LFxuXHQgIHJhZGlvOiBfUmFkaW8yLmRlZmF1bHQsXG5cdCAgc2VsZWN0OiBfU2VsZWN0Mi5kZWZhdWx0LFxuXHQgIHNsaWRlcjogX1NsaWRlcjIuZGVmYXVsdCxcblx0ICBzcGlubmVyOiBfU3Bpbm5lcjIuZGVmYXVsdCxcblx0ICB0YWI6IF9UYWIyLmRlZmF1bHQsXG5cdCAgdGFiR3JvdXA6IF9UYWJHcm91cDIuZGVmYXVsdCxcblx0ICB0YWJzOiBfVGFiczIuZGVmYXVsdCxcblx0ICB0b2dnbGVCdXR0b246IF9Ub2dnbGVCdXR0b24yLmRlZmF1bHQsXG5cdCAgdG9vbHRpcDogX1Rvb2x0aXAyLmRlZmF1bHQsXG5cdCAgdHlwZWFoZWFkOiBfVHlwZWFoZWFkMi5kZWZhdWx0XG5cdH07XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IFZ1ZVN0cmFwO1xuXG4vKioqLyB9LFxuLyogMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdFxuXHR2YXIgX2RlZmluZVByb3BlcnR5ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKTtcblx0XG5cdHZhciBfZGVmaW5lUHJvcGVydHkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZGVmaW5lUHJvcGVydHkpO1xuXHRcblx0dmFyIF9pdGVyYXRvciA9IF9fd2VicGFja19yZXF1aXJlX18oMjApO1xuXHRcblx0dmFyIF9pdGVyYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pdGVyYXRvcik7XG5cdFxuXHR2YXIgX2dldE93blByb3BlcnR5TmFtZXMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDU2KTtcblx0XG5cdHZhciBfZ2V0T3duUHJvcGVydHlOYW1lczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9nZXRPd25Qcm9wZXJ0eU5hbWVzKTtcblx0XG5cdHZhciBfY2xhc3NDYWxsQ2hlY2syID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2Mik7XG5cdFxuXHR2YXIgX2NsYXNzQ2FsbENoZWNrMyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2NsYXNzQ2FsbENoZWNrMik7XG5cdFxuXHR2YXIgX2NyZWF0ZUNsYXNzMiA9IF9fd2VicGFja19yZXF1aXJlX18oNjMpO1xuXHRcblx0dmFyIF9jcmVhdGVDbGFzczMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jcmVhdGVDbGFzczIpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblx0XG5cdF9fd2VicGFja19yZXF1aXJlX18oNjQpO1xuXHRcblx0dmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cdHZhciBub2RlRXJyb3IgPSBuZXcgRXJyb3IoJ1Bhc3NlZCBhcmd1bWVudHMgbXVzdCBiZSBvZiBOb2RlJyk7XG5cdHZhciBibHVyRXZlbnQ7XG5cdHZhciBibHVyTGlzdCA9IFtdO1xuXHR2YXIgRXZlbnRzID0gW107XG5cdFxuXHRmdW5jdGlvbiBpc05vZGUodmFsKSB7XG5cdCAgcmV0dXJuIHZhbCBpbnN0YW5jZW9mIHdpbmRvdy5Ob2RlO1xuXHR9XG5cdGZ1bmN0aW9uIGlzTm9kZUxpc3QodmFsKSB7XG5cdCAgcmV0dXJuIHZhbCBpbnN0YW5jZW9mIHdpbmRvdy5Ob2RlTGlzdCB8fCB2YWwgaW5zdGFuY2VvZiBOb2RlTGlzdCB8fCB2YWwgaW5zdGFuY2VvZiB3aW5kb3cuSFRNTENvbGxlY3Rpb24gfHwgdmFsIGluc3RhbmNlb2YgQXJyYXk7XG5cdH1cblx0XG5cdHZhciBOb2RlTGlzdCA9IGZ1bmN0aW9uICgpIHtcblx0ICBmdW5jdGlvbiBOb2RlTGlzdChhcmdzKSB7XG5cdCAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMy5kZWZhdWx0KSh0aGlzLCBOb2RlTGlzdCk7XG5cdFxuXHQgICAgdmFyIG5vZGVzID0gYXJncztcblx0ICAgIGlmIChhcmdzWzBdID09PSB3aW5kb3cpIHtcblx0ICAgICAgbm9kZXMgPSBbd2luZG93XTtcblx0ICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgIG5vZGVzID0gKGFyZ3NbMV0gfHwgZG9jdW1lbnQpLnF1ZXJ5U2VsZWN0b3JBbGwoYXJnc1swXSk7XG5cdCAgICAgIGlmIChhcmdzWzFdKSB7XG5cdCAgICAgICAgdGhpcy5vd25lciA9IGFyZ3NbMV07XG5cdCAgICAgIH1cblx0ICAgIH0gZWxzZSBpZiAoMCBpbiBhcmdzICYmICFpc05vZGUoYXJnc1swXSkgJiYgYXJnc1swXSAmJiAnbGVuZ3RoJyBpbiBhcmdzWzBdKSB7XG5cdCAgICAgIG5vZGVzID0gYXJnc1swXTtcblx0ICAgICAgaWYgKGFyZ3NbMV0pIHtcblx0ICAgICAgICB0aGlzLm93bmVyID0gYXJnc1sxXTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgICAgaWYgKG5vZGVzKSB7XG5cdCAgICAgIGZvciAodmFyIGkgaW4gbm9kZXMpIHtcblx0ICAgICAgICB0aGlzW2ldID0gbm9kZXNbaV07XG5cdCAgICAgIH1cblx0ICAgICAgdGhpcy5sZW5ndGggPSBub2Rlcy5sZW5ndGg7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICB0aGlzLmxlbmd0aCA9IDA7XG5cdCAgICB9XG5cdCAgICB3aW5kb3cucHJ1ZWJhID0gdGhpcztcblx0ICB9XG5cdFxuXHQgICgwLCBfY3JlYXRlQ2xhc3MzLmRlZmF1bHQpKE5vZGVMaXN0LCBbe1xuXHQgICAga2V5OiAnY29uY2F0Jyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBjb25jYXQoKSB7XG5cdCAgICAgIHZhciBub2RlcyA9IEFycmF5UHJvdG8uc2xpY2UuY2FsbCh0aGlzKTtcblx0ICAgICAgZnVuY3Rpb24gZmxhdHRlbihhcnIpIHtcblx0ICAgICAgICBBcnJheVByb3RvLmZvckVhY2guY2FsbChhcnIsIGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgICAgaWYgKGlzTm9kZShlbCkpIHtcblx0ICAgICAgICAgICAgaWYgKCF+bm9kZXMuaW5kZXhPZihlbCkpIG5vZGVzLnB1c2goZWwpO1xuXHQgICAgICAgICAgfSBlbHNlIGlmIChpc05vZGVMaXN0KGVsKSkge1xuXHQgICAgICAgICAgICBmbGF0dGVuKGVsKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHRcblx0ICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcblx0ICAgICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICBBcnJheVByb3RvLmZvckVhY2guY2FsbChhcmdzLCBmdW5jdGlvbiAoYXJnKSB7XG5cdCAgICAgICAgaWYgKGlzTm9kZShhcmcpKSB7XG5cdCAgICAgICAgICBpZiAoIX5ub2Rlcy5pbmRleE9mKGFyZykpIG5vZGVzLnB1c2goYXJnKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKGlzTm9kZUxpc3QoYXJnKSkge1xuXHQgICAgICAgICAgZmxhdHRlbihhcmcpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aHJvdyBFcnJvcignQ29uY2F0IGFyZ3VtZW50cyBtdXN0IGJlIG9mIGEgTm9kZSwgTm9kZUxpc3QsIEhUTUxDb2xsZWN0aW9uLCBvciBBcnJheSBvZiAoTm9kZSwgTm9kZUxpc3QsIEhUTUxDb2xsZWN0aW9uLCBBcnJheSknKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0pO1xuXHQgICAgICByZXR1cm4gTm9kZUxpc3RKUyhub2RlcywgdGhpcyk7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAnZGVsZXRlJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBfZGVsZXRlKCkge1xuXHQgICAgICB2YXIgbm90UmVtb3ZlZCA9IGZsYXR0ZW4odGhpcykuZmlsdGVyKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgIGlmIChlbC5yZW1vdmUpIHtcblx0ICAgICAgICAgIGVsLnJlbW92ZSgpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoZWwucGFyZW50Tm9kZSkge1xuXHQgICAgICAgICAgZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBkb2N1bWVudC5ib2R5LmNvbnRhaW5zKGVsKTtcblx0ICAgICAgfSk7XG5cdCAgICAgIGlmIChub3RSZW1vdmVkLmxlbmd0aCkgY29uc29sZS53YXJuKCdOb2RlTGlzdDogU29tZSBub2RlcyBjb3VsZCBub3QgYmUgZGVsZXRlZC4nKTtcblx0ICAgICAgcmV0dXJuIG5vdFJlbW92ZWQ7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAnZWFjaCcsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZWFjaCgpIHtcblx0ICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbjIpLCBfa2V5MiA9IDA7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcblx0ICAgICAgICBhcmdzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIEFycmF5UHJvdG8uZm9yRWFjaC5hcHBseSh0aGlzLCBhcmdzKTtcblx0ICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAnZmlsdGVyJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmaWx0ZXIoKSB7XG5cdCAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4zKSwgX2tleTMgPSAwOyBfa2V5MyA8IF9sZW4zOyBfa2V5MysrKSB7XG5cdCAgICAgICAgYXJnc1tfa2V5M10gPSBhcmd1bWVudHNbX2tleTNdO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICByZXR1cm4gTm9kZUxpc3RKUyhBcnJheVByb3RvLmZpbHRlci5hcHBseSh0aGlzLCBhcmdzKSwgdGhpcyk7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAnZmluZCcsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZmluZChlbGVtZW50KSB7XG5cdCAgICAgIHZhciBub2RlcyA9IFtdO1xuXHQgICAgICBpZiAodHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnKSBmbGF0dGVuKHRoaXMpLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICBub2Rlcy5wdXNoKG5vZGUucXVlcnlTZWxlY3RvckFsbChlbGVtZW50KSk7XG5cdCAgICAgIH0pO1xuXHQgICAgICBpZiAoaXNOb2RlKGVsZW1lbnQpKSBmbGF0dGVuKHRoaXMpLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICBpZiAobm9kZSAhPT0gZWxlbWVudCAmJiBub2RlLmNvbnRhaW5zKGVsZW1lbnQpKSBub2Rlcy5wdXNoKGVsZW1lbnQpO1xuXHQgICAgICB9KTtcblx0ICAgICAgaWYgKGlzTm9kZUxpc3QoZWxlbWVudCkpIHtcblx0ICAgICAgICB2YXIgZWxzID0gZmxhdHRlbihlbGVtZW50KTtcblx0ICAgICAgICBmbGF0dGVuKHRoaXMpLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcblx0ICAgICAgICAgIGVscy5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgICAgICBpZiAobm9kZSAhPT0gZWwgJiYgbm9kZS5jb250YWlucyhlbCkpIG5vZGVzLnB1c2goZWwpO1xuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgICAgcmV0dXJuIGZsYXR0ZW4obm9kZXMsIHRoaXMub3duZXIpO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogJ2ZvckVhY2gnLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZvckVhY2goKSB7XG5cdCAgICAgIGZvciAodmFyIF9sZW40ID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW40KSwgX2tleTQgPSAwOyBfa2V5NCA8IF9sZW40OyBfa2V5NCsrKSB7XG5cdCAgICAgICAgYXJnc1tfa2V5NF0gPSBhcmd1bWVudHNbX2tleTRdO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICBBcnJheVByb3RvLmZvckVhY2guYXBwbHkodGhpcywgYXJncyk7XG5cdCAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogJ2luY2x1ZGVzJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBpbmNsdWRlcyhlbGVtZW50LCBpbmRleCkge1xuXHQgICAgICByZXR1cm4gfnRoaXMuaW5kZXhPZihlbGVtZW50LCBpbmRleCk7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAnbWFwJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBtYXAoKSB7XG5cdCAgICAgIGZvciAodmFyIF9sZW41ID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW41KSwgX2tleTUgPSAwOyBfa2V5NSA8IF9sZW41OyBfa2V5NSsrKSB7XG5cdCAgICAgICAgYXJnc1tfa2V5NV0gPSBhcmd1bWVudHNbX2tleTVdO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICB2YXIgbWFwcGVkID0gQXJyYXlQcm90by5tYXAuYXBwbHkodGhpcywgYXJncyk7XG5cdCAgICAgIHJldHVybiBtYXBwZWQuc29tZShmdW5jdGlvbiAoZWwpIHtcblx0ICAgICAgICByZXR1cm4gaXNOb2RlKGVsKSB8fCBpc05vZGVMaXN0KGVsKTtcblx0ICAgICAgfSkgPyBmbGF0dGVuKG1hcHBlZCwgdGhpcykgOiBtYXBwZWQ7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAncGFyZW50Jyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBwYXJlbnQoKSB7XG5cdCAgICAgIHJldHVybiBmbGF0dGVuKHRoaXMubWFwKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgIHJldHVybiBlbC5wYXJlbnROb2RlO1xuXHQgICAgICB9KSwgdGhpcyk7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAncG9wJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBwb3AoYW1vdW50KSB7XG5cdCAgICAgIGlmICh0eXBlb2YgYW1vdW50ICE9PSAnbnVtYmVyJykge1xuXHQgICAgICAgIGFtb3VudCA9IDE7XG5cdCAgICAgIH1cblx0ICAgICAgdmFyIG5vZGVzID0gW107XG5cdCAgICAgIHZhciBwb3AgPSBBcnJheVByb3RvLnBvcC5iaW5kKHRoaXMpO1xuXHQgICAgICB3aGlsZSAoYW1vdW50LS0pIHtcblx0ICAgICAgICBub2Rlcy5wdXNoKHBvcCgpKTtcblx0ICAgICAgfXJldHVybiBOb2RlTGlzdEpTKG5vZGVzLCB0aGlzKTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdwdXNoJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBwdXNoKCkge1xuXHQgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgZm9yICh2YXIgX2xlbjYgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbjYpLCBfa2V5NiA9IDA7IF9rZXk2IDwgX2xlbjY7IF9rZXk2KyspIHtcblx0ICAgICAgICBhcmdzW19rZXk2XSA9IGFyZ3VtZW50c1tfa2V5Nl07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIEFycmF5UHJvdG8uZm9yRWFjaC5jYWxsKGFyZ3MsIGZ1bmN0aW9uIChhcmcpIHtcblx0ICAgICAgICBpZiAoIWlzTm9kZShhcmcpKSB0aHJvdyBub2RlRXJyb3I7XG5cdCAgICAgICAgaWYgKCF+X3RoaXMuaW5kZXhPZihhcmcpKSBBcnJheVByb3RvLnB1c2guY2FsbChfdGhpcywgYXJnKTtcblx0ICAgICAgfSk7XG5cdCAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogJ3NoaWZ0Jyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBzaGlmdChhbW91bnQpIHtcblx0ICAgICAgaWYgKHR5cGVvZiBhbW91bnQgIT09ICdudW1iZXInKSB7XG5cdCAgICAgICAgYW1vdW50ID0gMTtcblx0ICAgICAgfVxuXHQgICAgICB2YXIgbm9kZXMgPSBbXTtcblx0ICAgICAgd2hpbGUgKGFtb3VudC0tKSB7XG5cdCAgICAgICAgbm9kZXMucHVzaChBcnJheVByb3RvLnNoaWZ0LmNhbGwodGhpcykpO1xuXHQgICAgICB9cmV0dXJuIG5vZGVzLmxlbmd0aCA9PSAxID8gbm9kZXNbMF0gOiBOb2RlTGlzdEpTKG5vZGVzLCB0aGlzKTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdzbGljZScsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gc2xpY2UoKSB7XG5cdCAgICAgIGZvciAodmFyIF9sZW43ID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW43KSwgX2tleTcgPSAwOyBfa2V5NyA8IF9sZW43OyBfa2V5NysrKSB7XG5cdCAgICAgICAgYXJnc1tfa2V5N10gPSBhcmd1bWVudHNbX2tleTddO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICByZXR1cm4gTm9kZUxpc3RKUyhBcnJheVByb3RvLnNsaWNlLmFwcGx5KHRoaXMsIGFyZ3MpLCB0aGlzKTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdzcGxpY2UnLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHNwbGljZSgpIHtcblx0ICAgICAgZm9yICh2YXIgX2xlbjggPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbjgpLCBfa2V5OCA9IDA7IF9rZXk4IDwgX2xlbjg7IF9rZXk4KyspIHtcblx0ICAgICAgICBhcmdzW19rZXk4XSA9IGFyZ3VtZW50c1tfa2V5OF07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIGZvciAodmFyIGkgPSAyLCBsID0gYXJncy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0ICAgICAgICBpZiAoIWlzTm9kZShhcmdzW2ldKSkgdGhyb3cgbm9kZUVycm9yO1xuXHQgICAgICB9XG5cdCAgICAgIEFycmF5UHJvdG8uc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHQgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICd1bnNoaWZ0Jyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB1bnNoaWZ0KCkge1xuXHQgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblx0XG5cdCAgICAgIHZhciB1bnNoaWZ0ID0gQXJyYXlQcm90by51bnNoaWZ0LmJpbmQodGhpcyk7XG5cdFxuXHQgICAgICBmb3IgKHZhciBfbGVuOSA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuOSksIF9rZXk5ID0gMDsgX2tleTkgPCBfbGVuOTsgX2tleTkrKykge1xuXHQgICAgICAgIGFyZ3NbX2tleTldID0gYXJndW1lbnRzW19rZXk5XTtcblx0ICAgICAgfVxuXHRcblx0ICAgICAgQXJyYXlQcm90by5mb3JFYWNoLmNhbGwoYXJncywgZnVuY3Rpb24gKGFyZykge1xuXHQgICAgICAgIGlmICghaXNOb2RlKGFyZykpIHRocm93IG5vZGVFcnJvcjtcblx0ICAgICAgICBpZiAoIX5fdGhpczIuaW5kZXhPZihhcmcpKSB1bnNoaWZ0KGFyZyk7XG5cdCAgICAgIH0pO1xuXHQgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdhZGRDbGFzcycsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gYWRkQ2xhc3MoY2xhc3Nlcykge1xuXHQgICAgICByZXR1cm4gdGhpcy50b2dnbGVDbGFzcyhjbGFzc2VzLCB0cnVlKTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdyZW1vdmVDbGFzcycsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gcmVtb3ZlQ2xhc3MoY2xhc3Nlcykge1xuXHQgICAgICByZXR1cm4gdGhpcy50b2dnbGVDbGFzcyhjbGFzc2VzLCBmYWxzZSk7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAndG9nZ2xlQ2xhc3MnLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvZ2dsZUNsYXNzKGNsYXNzZXMpIHtcblx0ICAgICAgdmFyIHZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBudWxsO1xuXHRcblx0ICAgICAgdmFyIG1ldGhvZCA9IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgPyAndG9nZ2xlJyA6IHZhbHVlID8gJ2FkZCcgOiAncmVtb3ZlJztcblx0ICAgICAgaWYgKHR5cGVvZiBjbGFzc2VzID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgIGNsYXNzZXMgPSBjbGFzc2VzLnRyaW0oKS5yZXBsYWNlKC9cXHMrLywgJyAnKS5zcGxpdCgnICcpO1xuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKGVsKSB7XG5cdCAgICAgICAgcmV0dXJuIGNsYXNzZXMuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuXHQgICAgICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdFttZXRob2RdKGMpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICB9KTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdnZXQnLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGdldChwcm9wKSB7XG5cdCAgICAgIHZhciBhcnIgPSBbXTtcblx0ICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgIGlmIChlbCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgZWwgPSBlbFtwcm9wXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgYXJyLnB1c2goZWwpO1xuXHQgICAgICB9KTtcblx0ICAgICAgcmV0dXJuIGZsYXR0ZW4oYXJyLCB0aGlzKTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdzZXQnLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHNldChwcm9wLCB2YWx1ZSkge1xuXHQgICAgICBpZiAocHJvcC5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KSB7XG5cdCAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgICAgaWYgKGVsKSB7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wKSB7XG5cdCAgICAgICAgICAgICAgaWYgKGtleSBpbiBlbCkge1xuXHQgICAgICAgICAgICAgICAgZWxba2V5XSA9IHByb3Bba2V5XTtcblx0ICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKGVsKSB7XG5cdCAgICAgICAgICBpZiAocHJvcCBpbiBlbCkge1xuXHQgICAgICAgICAgICBlbFtwcm9wXSA9IHZhbHVlO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogJ2NhbGwnLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGNhbGwoKSB7XG5cdCAgICAgIGZvciAodmFyIF9sZW4xMCA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuMTApLCBfa2V5MTAgPSAwOyBfa2V5MTAgPCBfbGVuMTA7IF9rZXkxMCsrKSB7XG5cdCAgICAgICAgYXJnc1tfa2V5MTBdID0gYXJndW1lbnRzW19rZXkxMF07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIHZhciBtZXRob2QgPSBBcnJheVByb3RvLnNoaWZ0LmNhbGwoYXJncyk7XG5cdCAgICAgIHZhciBhcnIgPSBbXTtcblx0ICAgICAgdmFyIHJldHVyblRoaXMgPSB0cnVlO1xuXHQgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKGVsKSB7XG5cdCAgICAgICAgaWYgKGVsICYmIGVsW21ldGhvZF0gaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuXHQgICAgICAgICAgZWwgPSBlbFttZXRob2RdLmFwcGx5KGVsLCBhcmdzKTtcblx0ICAgICAgICAgIGFyci5wdXNoKGVsKTtcblx0ICAgICAgICAgIGlmIChyZXR1cm5UaGlzICYmIGVsICE9PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuVGhpcyA9IGZhbHNlO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBhcnIucHVzaCh1bmRlZmluZWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSk7XG5cdCAgICAgIHJldHVybiByZXR1cm5UaGlzID8gdGhpcyA6IGZsYXR0ZW4oYXJyLCB0aGlzKTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdpdGVtJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBpdGVtKGluZGV4KSB7XG5cdCAgICAgIHJldHVybiBOb2RlTGlzdEpTKFt0aGlzW2luZGV4XV0sIHRoaXMpO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogJ29uJyxcblx0XG5cdFxuXHQgICAgLy8gZXZlbnQgaGFuZGxlcnNcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBvbihldmVudHMsIHNlbGVjdG9yLCBjYWxsYmFjaykge1xuXHQgICAgICBpZiAodHlwZW9mIGV2ZW50cyA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICBldmVudHMgPSBldmVudHMudHJpbSgpLnJlcGxhY2UoL1xccysvLCAnICcpLnNwbGl0KCcgJyk7XG5cdCAgICAgIH1cblx0ICAgICAgaWYgKCF0aGlzIHx8ICF0aGlzLmxlbmd0aCkgcmV0dXJuIHRoaXM7XG5cdCAgICAgIGlmIChjYWxsYmFjayA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgY2FsbGJhY2sgPSBzZWxlY3Rvcjtcblx0ICAgICAgICBzZWxlY3RvciA9IG51bGw7XG5cdCAgICAgIH1cblx0ICAgICAgaWYgKCFjYWxsYmFjaykgcmV0dXJuIHRoaXM7XG5cdCAgICAgIHZhciBmbiA9IGNhbGxiYWNrO1xuXHQgICAgICBjYWxsYmFjayA9IHNlbGVjdG9yID8gZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICB2YXIgZWxzID0gTm9kZUxpc3RKUyhzZWxlY3RvciwgdGhpcyk7XG5cdCAgICAgICAgaWYgKCFlbHMubGVuZ3RoKSB7XG5cdCAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVscy5zb21lKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgICAgdmFyIHRhcmdldCA9IGVsLmNvbnRhaW5zKGUudGFyZ2V0KTtcblx0ICAgICAgICAgIGlmICh0YXJnZXQpIGZuLmNhbGwoZWwsIGUsIGVsKTtcblx0ICAgICAgICAgIHJldHVybiB0YXJnZXQ7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH0gOiBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgIGZuLmFwcGx5KHRoaXMsIFtlLCB0aGlzXSk7XG5cdCAgICAgIH07XG5cdCAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoZWwpIHtcblx0ICAgICAgICBldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcblx0ICAgICAgICAgIGlmIChlbCA9PT0gd2luZG93IHx8IGlzTm9kZShlbCkpIHtcblx0ICAgICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgY2FsbGJhY2ssIGZhbHNlKTtcblx0ICAgICAgICAgICAgRXZlbnRzLnB1c2goe1xuXHQgICAgICAgICAgICAgIGVsOiBlbCxcblx0ICAgICAgICAgICAgICBldmVudDogZXZlbnQsXG5cdCAgICAgICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICB9KTtcblx0ICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAnb2ZmJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBvZmYoZXZlbnRzLCBjYWxsYmFjaykge1xuXHQgICAgICBpZiAoZXZlbnRzIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcblx0ICAgICAgICBjYWxsYmFjayA9IGV2ZW50cztcblx0ICAgICAgICBldmVudHMgPSBudWxsO1xuXHQgICAgICB9XG5cdCAgICAgIGV2ZW50cyA9IGV2ZW50cyBpbnN0YW5jZW9mIEFycmF5ID8gZXZlbnRzIDogdHlwZW9mIGV2ZW50cyA9PT0gJ3N0cmluZycgPyBldmVudHMudHJpbSgpLnJlcGxhY2UoL1xccysvLCAnICcpLnNwbGl0KCcgJykgOiBudWxsO1xuXHQgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKGVsKSB7XG5cdCAgICAgICAgRXZlbnRzID0gRXZlbnRzLmZpbHRlcihmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgaWYgKGUgJiYgZS5lbCA9PT0gZWwgJiYgKCFjYWxsYmFjayB8fCBjYWxsYmFjayA9PT0gZS5jYWxsYmFjaykgJiYgKCFldmVudHMgfHwgfmV2ZW50cy5pbmRleE9mKGUuZXZlbnQpKSkge1xuXHQgICAgICAgICAgICBlLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZS5ldmVudCwgZS5jYWxsYmFjayk7XG5cdCAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICB9KTtcblx0ICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiAnb25CbHVyJyxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBvbkJsdXIoY2FsbGJhY2spIHtcblx0ICAgICAgaWYgKCF0aGlzIHx8ICF0aGlzLmxlbmd0aCkgcmV0dXJuIHRoaXM7XG5cdCAgICAgIGlmICghY2FsbGJhY2spIHJldHVybiB0aGlzO1xuXHQgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKGVsKSB7XG5cdCAgICAgICAgYmx1ckxpc3QucHVzaCh7IGVsOiBlbCwgY2FsbGJhY2s6IGNhbGxiYWNrIH0pO1xuXHQgICAgICB9KTtcblx0ICAgICAgaWYgKCFibHVyRXZlbnQpIHtcblx0ICAgICAgICBibHVyRXZlbnQgPSBmdW5jdGlvbiBibHVyRXZlbnQoZSkge1xuXHQgICAgICAgICAgYmx1ckxpc3QuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuXHQgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gaXRlbS5lbC5jb250YWlucyhlLnRhcmdldCkgfHwgaXRlbS5lbCA9PT0gZS50YXJnZXQ7XG5cdCAgICAgICAgICAgIGlmICghdGFyZ2V0KSBpdGVtLmNhbGxiYWNrLmNhbGwoaXRlbS5lbCwgZSwgaXRlbS5lbCk7XG5cdCAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYmx1ckV2ZW50LCBmYWxzZSk7XG5cdCAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGJsdXJFdmVudCwgZmFsc2UpO1xuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogJ29mZkJsdXInLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIG9mZkJsdXIoY2FsbGJhY2spIHtcblx0ICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgIGJsdXJMaXN0ID0gYmx1ckxpc3QuZmlsdGVyKGZ1bmN0aW9uIChibHVyKSB7XG5cdCAgICAgICAgICBpZiAoYmx1ciAmJiBibHVyLmVsID09PSBlbCAmJiAoIWNhbGxiYWNrIHx8IGJsdXIuY2FsbGJhY2sgPT09IGNhbGxiYWNrKSkge1xuXHQgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgICByZXR1cm4gZWw7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH0pO1xuXHQgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6ICdhc0FycmF5Jyxcblx0ICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuXHQgICAgICByZXR1cm4gQXJyYXlQcm90by5zbGljZS5jYWxsKHRoaXMpO1xuXHQgICAgfVxuXHQgIH1dKTtcblx0ICByZXR1cm4gTm9kZUxpc3Q7XG5cdH0oKTtcblx0XG5cdHZhciBOTCA9IE5vZGVMaXN0LnByb3RvdHlwZTtcblx0XG5cdGZ1bmN0aW9uIGZsYXR0ZW4oYXJyLCBvd25lcikge1xuXHQgIHZhciBsaXN0ID0gW107XG5cdCAgQXJyYXlQcm90by5mb3JFYWNoLmNhbGwoYXJyLCBmdW5jdGlvbiAoZWwpIHtcblx0ICAgIGlmIChpc05vZGUoZWwpKSB7XG5cdCAgICAgIGlmICghfmxpc3QuaW5kZXhPZihlbCkpIGxpc3QucHVzaChlbCk7XG5cdCAgICB9IGVsc2UgaWYgKGlzTm9kZUxpc3QoZWwpKSB7XG5cdCAgICAgIGZvciAodmFyIGlkIGluIGVsKSB7XG5cdCAgICAgICAgaWYgKCF+bGlzdC5pbmRleE9mKGVsW2lkXSkpIGxpc3QucHVzaChlbFtpZF0pO1xuXHQgICAgICB9XG5cdCAgICB9IGVsc2UgaWYgKGVsICE9PSBudWxsKSB7XG5cdCAgICAgIGFyci5nZXQgPSBOTC5nZXQ7XG5cdCAgICAgIGFyci5zZXQgPSBOTC5zZXQ7XG5cdCAgICAgIGFyci5jYWxsID0gTkwuY2FsbDtcblx0ICAgICAgYXJyLm93bmVyID0gb3duZXI7XG5cdCAgICAgIHJldHVybiBhcnI7XG5cdCAgICB9XG5cdCAgfSk7XG5cdCAgcmV0dXJuIE5vZGVMaXN0SlMobGlzdCwgb3duZXIpO1xuXHR9XG5cdFxuXHR2YXIgZXhjZXB0aW9ucyA9IFsnam9pbicsICdjb3B5V2l0aGluJywgJ2ZpbGwnLCAnZmluZCcsICdmb3JFYWNoJ107XG5cdCgwLCBfZ2V0T3duUHJvcGVydHlOYW1lczIuZGVmYXVsdCkoQXJyYXlQcm90bykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG5cdCAgaWYgKCF+ZXhjZXB0aW9ucy5pbmRleE9mKGtleSkgJiYgTkxba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICBOTFtrZXldID0gQXJyYXlQcm90b1trZXldO1xuXHQgIH1cblx0fSk7XG5cdGlmICh3aW5kb3cuU3ltYm9sICYmIF9pdGVyYXRvcjIuZGVmYXVsdCkge1xuXHQgIE5MW19pdGVyYXRvcjIuZGVmYXVsdF0gPSBOTC52YWx1ZXMgPSBBcnJheVByb3RvW19pdGVyYXRvcjIuZGVmYXVsdF07XG5cdH1cblx0dmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRmdW5jdGlvbiBzZXR0ZXJHZXR0ZXIocHJvcCkge1xuXHQgIHZhciBfdGhpczMgPSB0aGlzO1xuXHRcblx0ICBpZiAoTkxbcHJvcF0pIHJldHVybjtcblx0ICBpZiAoZGl2W3Byb3BdIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcblx0ICAgIE5MW3Byb3BdID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICBmb3IgKHZhciBfbGVuMTEgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbjExKSwgX2tleTExID0gMDsgX2tleTExIDwgX2xlbjExOyBfa2V5MTErKykge1xuXHQgICAgICAgIGFyZ3NbX2tleTExXSA9IGFyZ3VtZW50c1tfa2V5MTFdO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICB2YXIgYXJyID0gW107XG5cdCAgICAgIHZhciByZXR1cm5UaGlzID0gdHJ1ZTtcblx0ICAgICAgZm9yICh2YXIgaSBpbiBOTCkge1xuXHQgICAgICAgIHZhciBlbCA9IE5MW2ldO1xuXHQgICAgICAgIGlmIChlbCAmJiBlbFtwcm9wXSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG5cdCAgICAgICAgICBlbCA9IGVsW3Byb3BdLmFwcGx5KGVsLCBhcmdzKTtcblx0ICAgICAgICAgIGFyci5wdXNoKGVsKTtcblx0ICAgICAgICAgIGlmIChyZXR1cm5UaGlzICYmIGVsICE9PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuVGhpcyA9IGZhbHNlO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBhcnIucHVzaCh1bmRlZmluZWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgICByZXR1cm4gcmV0dXJuVGhpcyA/IF90aGlzMyA6IGZsYXR0ZW4oYXJyLCBfdGhpczMpO1xuXHQgICAgfTtcblx0ICB9IGVsc2Uge1xuXHQgICAgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoTkwsIHByb3AsIHtcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG5cdCAgICAgICAgdmFyIGFyciA9IFtdO1xuXHQgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoZWwpIHtcblx0ICAgICAgICAgIGlmIChlbCAhPT0gbnVsbCkge1xuXHQgICAgICAgICAgICBlbCA9IGVsW3Byb3BdO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgYXJyLnB1c2goZWwpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBmbGF0dGVuKGFyciwgdGhpcyk7XG5cdCAgICAgIH0sXG5cdCAgICAgIHNldDogZnVuY3Rpb24gc2V0KHZhbHVlKSB7XG5cdCAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgICAgaWYgKGVsICYmIHByb3AgaW4gZWwpIHtcblx0ICAgICAgICAgICAgZWxbcHJvcF0gPSB2YWx1ZTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgICAgfVxuXHQgICAgfSk7XG5cdCAgfVxuXHR9XG5cdGZvciAodmFyIHByb3AgaW4gZGl2KSB7XG5cdCAgc2V0dGVyR2V0dGVyKHByb3ApO1xuXHR9ZnVuY3Rpb24gTm9kZUxpc3RKUygpIHtcblx0ICBmb3IgKHZhciBfbGVuMTIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbjEyKSwgX2tleTEyID0gMDsgX2tleTEyIDwgX2xlbjEyOyBfa2V5MTIrKykge1xuXHQgICAgYXJnc1tfa2V5MTJdID0gYXJndW1lbnRzW19rZXkxMl07XG5cdCAgfVxuXHRcblx0ICByZXR1cm4gbmV3IE5vZGVMaXN0KGFyZ3MpO1xuXHR9XG5cdHdpbmRvdy5OTCA9IE5vZGVMaXN0SlM7XG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSBOb2RlTGlzdEpTO1xuXG4vKioqLyB9LFxuLyogMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMpLCBfX2VzTW9kdWxlOiB0cnVlIH07XG5cbi8qKiovIH0sXG4vKiAzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHR2YXIgJE9iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oNykuT2JqZWN0O1xuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KGl0LCBrZXksIGRlc2Mpe1xuXHQgIHJldHVybiAkT2JqZWN0LmRlZmluZVByb3BlcnR5KGl0LCBrZXksIGRlc2MpO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogNCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpO1xuXHQvLyAxOS4xLjIuNCAvIDE1LjIuMy42IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKVxuXHQkZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFfX3dlYnBhY2tfcmVxdWlyZV9fKDE1KSwgJ09iamVjdCcsIHtkZWZpbmVQcm9wZXJ0eTogX193ZWJwYWNrX3JlcXVpcmVfXygxMSkuZn0pO1xuXG4vKioqLyB9LFxuLyogNSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIGdsb2JhbCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oNilcblx0ICAsIGNvcmUgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oNylcblx0ICAsIGN0eCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oOClcblx0ICAsIGhpZGUgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTApXG5cdCAgLCBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblx0XG5cdHZhciAkZXhwb3J0ID0gZnVuY3Rpb24odHlwZSwgbmFtZSwgc291cmNlKXtcblx0ICB2YXIgSVNfRk9SQ0VEID0gdHlwZSAmICRleHBvcnQuRlxuXHQgICAgLCBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HXG5cdCAgICAsIElTX1NUQVRJQyA9IHR5cGUgJiAkZXhwb3J0LlNcblx0ICAgICwgSVNfUFJPVE8gID0gdHlwZSAmICRleHBvcnQuUFxuXHQgICAgLCBJU19CSU5EICAgPSB0eXBlICYgJGV4cG9ydC5CXG5cdCAgICAsIElTX1dSQVAgICA9IHR5cGUgJiAkZXhwb3J0Lldcblx0ICAgICwgZXhwb3J0cyAgID0gSVNfR0xPQkFMID8gY29yZSA6IGNvcmVbbmFtZV0gfHwgKGNvcmVbbmFtZV0gPSB7fSlcblx0ICAgICwgZXhwUHJvdG8gID0gZXhwb3J0c1tQUk9UT1RZUEVdXG5cdCAgICAsIHRhcmdldCAgICA9IElTX0dMT0JBTCA/IGdsb2JhbCA6IElTX1NUQVRJQyA/IGdsb2JhbFtuYW1lXSA6IChnbG9iYWxbbmFtZV0gfHwge30pW1BST1RPVFlQRV1cblx0ICAgICwga2V5LCBvd24sIG91dDtcblx0ICBpZihJU19HTE9CQUwpc291cmNlID0gbmFtZTtcblx0ICBmb3Ioa2V5IGluIHNvdXJjZSl7XG5cdCAgICAvLyBjb250YWlucyBpbiBuYXRpdmVcblx0ICAgIG93biA9ICFJU19GT1JDRUQgJiYgdGFyZ2V0ICYmIHRhcmdldFtrZXldICE9PSB1bmRlZmluZWQ7XG5cdCAgICBpZihvd24gJiYga2V5IGluIGV4cG9ydHMpY29udGludWU7XG5cdCAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuXHQgICAgb3V0ID0gb3duID8gdGFyZ2V0W2tleV0gOiBzb3VyY2Vba2V5XTtcblx0ICAgIC8vIHByZXZlbnQgZ2xvYmFsIHBvbGx1dGlvbiBmb3IgbmFtZXNwYWNlc1xuXHQgICAgZXhwb3J0c1trZXldID0gSVNfR0xPQkFMICYmIHR5cGVvZiB0YXJnZXRba2V5XSAhPSAnZnVuY3Rpb24nID8gc291cmNlW2tleV1cblx0ICAgIC8vIGJpbmQgdGltZXJzIHRvIGdsb2JhbCBmb3IgY2FsbCBmcm9tIGV4cG9ydCBjb250ZXh0XG5cdCAgICA6IElTX0JJTkQgJiYgb3duID8gY3R4KG91dCwgZ2xvYmFsKVxuXHQgICAgLy8gd3JhcCBnbG9iYWwgY29uc3RydWN0b3JzIGZvciBwcmV2ZW50IGNoYW5nZSB0aGVtIGluIGxpYnJhcnlcblx0ICAgIDogSVNfV1JBUCAmJiB0YXJnZXRba2V5XSA9PSBvdXQgPyAoZnVuY3Rpb24oQyl7XG5cdCAgICAgIHZhciBGID0gZnVuY3Rpb24oYSwgYiwgYyl7XG5cdCAgICAgICAgaWYodGhpcyBpbnN0YW5jZW9mIEMpe1xuXHQgICAgICAgICAgc3dpdGNoKGFyZ3VtZW50cy5sZW5ndGgpe1xuXHQgICAgICAgICAgICBjYXNlIDA6IHJldHVybiBuZXcgQztcblx0ICAgICAgICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEMoYSk7XG5cdCAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDKGEsIGIpO1xuXHQgICAgICAgICAgfSByZXR1cm4gbmV3IEMoYSwgYiwgYyk7XG5cdCAgICAgICAgfSByZXR1cm4gQy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgICB9O1xuXHQgICAgICBGW1BST1RPVFlQRV0gPSBDW1BST1RPVFlQRV07XG5cdCAgICAgIHJldHVybiBGO1xuXHQgICAgLy8gbWFrZSBzdGF0aWMgdmVyc2lvbnMgZm9yIHByb3RvdHlwZSBtZXRob2RzXG5cdCAgICB9KShvdXQpIDogSVNfUFJPVE8gJiYgdHlwZW9mIG91dCA9PSAnZnVuY3Rpb24nID8gY3R4KEZ1bmN0aW9uLmNhbGwsIG91dCkgOiBvdXQ7XG5cdCAgICAvLyBleHBvcnQgcHJvdG8gbWV0aG9kcyB0byBjb3JlLiVDT05TVFJVQ1RPUiUubWV0aG9kcy4lTkFNRSVcblx0ICAgIGlmKElTX1BST1RPKXtcblx0ICAgICAgKGV4cG9ydHMudmlydHVhbCB8fCAoZXhwb3J0cy52aXJ0dWFsID0ge30pKVtrZXldID0gb3V0O1xuXHQgICAgICAvLyBleHBvcnQgcHJvdG8gbWV0aG9kcyB0byBjb3JlLiVDT05TVFJVQ1RPUiUucHJvdG90eXBlLiVOQU1FJVxuXHQgICAgICBpZih0eXBlICYgJGV4cG9ydC5SICYmIGV4cFByb3RvICYmICFleHBQcm90b1trZXldKWhpZGUoZXhwUHJvdG8sIGtleSwgb3V0KTtcblx0ICAgIH1cblx0ICB9XG5cdH07XG5cdC8vIHR5cGUgYml0bWFwXG5cdCRleHBvcnQuRiA9IDE7ICAgLy8gZm9yY2VkXG5cdCRleHBvcnQuRyA9IDI7ICAgLy8gZ2xvYmFsXG5cdCRleHBvcnQuUyA9IDQ7ICAgLy8gc3RhdGljXG5cdCRleHBvcnQuUCA9IDg7ICAgLy8gcHJvdG9cblx0JGV4cG9ydC5CID0gMTY7ICAvLyBiaW5kXG5cdCRleHBvcnQuVyA9IDMyOyAgLy8gd3JhcFxuXHQkZXhwb3J0LlUgPSA2NDsgIC8vIHNhZmVcblx0JGV4cG9ydC5SID0gMTI4OyAvLyByZWFsIHByb3RvIG1ldGhvZCBmb3IgYGxpYnJhcnlgIFxuXHRtb2R1bGUuZXhwb3J0cyA9ICRleHBvcnQ7XG5cbi8qKiovIH0sXG4vKiA2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHQvLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvODYjaXNzdWVjb21tZW50LTExNTc1OTAyOFxuXHR2YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcblx0ICA/IHdpbmRvdyA6IHR5cGVvZiBzZWxmICE9ICd1bmRlZmluZWQnICYmIHNlbGYuTWF0aCA9PSBNYXRoID8gc2VsZiA6IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cdGlmKHR5cGVvZiBfX2cgPT0gJ251bWJlcicpX19nID0gZ2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG5cbi8qKiovIH0sXG4vKiA3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHR2YXIgY29yZSA9IG1vZHVsZS5leHBvcnRzID0ge3ZlcnNpb246ICcyLjQuMCd9O1xuXHRpZih0eXBlb2YgX19lID09ICdudW1iZXInKV9fZSA9IGNvcmU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcblxuLyoqKi8gfSxcbi8qIDggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIG9wdGlvbmFsIC8gc2ltcGxlIGNvbnRleHQgYmluZGluZ1xuXHR2YXIgYUZ1bmN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXyg5KTtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbiwgdGhhdCwgbGVuZ3RoKXtcblx0ICBhRnVuY3Rpb24oZm4pO1xuXHQgIGlmKHRoYXQgPT09IHVuZGVmaW5lZClyZXR1cm4gZm47XG5cdCAgc3dpdGNoKGxlbmd0aCl7XG5cdCAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhKXtcblx0ICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSk7XG5cdCAgICB9O1xuXHQgICAgY2FzZSAyOiByZXR1cm4gZnVuY3Rpb24oYSwgYil7XG5cdCAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEsIGIpO1xuXHQgICAgfTtcblx0ICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKGEsIGIsIGMpe1xuXHQgICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiLCBjKTtcblx0ICAgIH07XG5cdCAgfVxuXHQgIHJldHVybiBmdW5jdGlvbigvKiAuLi5hcmdzICovKXtcblx0ICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuXHQgIH07XG5cdH07XG5cbi8qKiovIH0sXG4vKiA5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcblx0ICBpZih0eXBlb2YgaXQgIT0gJ2Z1bmN0aW9uJyl0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhIGZ1bmN0aW9uIScpO1xuXHQgIHJldHVybiBpdDtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDEwICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgZFAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTEpXG5cdCAgLCBjcmVhdGVEZXNjID0gX193ZWJwYWNrX3JlcXVpcmVfXygxOSk7XG5cdG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNSkgPyBmdW5jdGlvbihvYmplY3QsIGtleSwgdmFsdWUpe1xuXHQgIHJldHVybiBkUC5mKG9iamVjdCwga2V5LCBjcmVhdGVEZXNjKDEsIHZhbHVlKSk7XG5cdH0gOiBmdW5jdGlvbihvYmplY3QsIGtleSwgdmFsdWUpe1xuXHQgIG9iamVjdFtrZXldID0gdmFsdWU7XG5cdCAgcmV0dXJuIG9iamVjdDtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDExICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgYW5PYmplY3QgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEyKVxuXHQgICwgSUU4X0RPTV9ERUZJTkUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE0KVxuXHQgICwgdG9QcmltaXRpdmUgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE4KVxuXHQgICwgZFAgICAgICAgICAgICAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cdFxuXHRleHBvcnRzLmYgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE1KSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpe1xuXHQgIGFuT2JqZWN0KE8pO1xuXHQgIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcblx0ICBhbk9iamVjdChBdHRyaWJ1dGVzKTtcblx0ICBpZihJRThfRE9NX0RFRklORSl0cnkge1xuXHQgICAgcmV0dXJuIGRQKE8sIFAsIEF0dHJpYnV0ZXMpO1xuXHQgIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cblx0ICBpZignZ2V0JyBpbiBBdHRyaWJ1dGVzIHx8ICdzZXQnIGluIEF0dHJpYnV0ZXMpdGhyb3cgVHlwZUVycm9yKCdBY2Nlc3NvcnMgbm90IHN1cHBvcnRlZCEnKTtcblx0ICBpZigndmFsdWUnIGluIEF0dHJpYnV0ZXMpT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG5cdCAgcmV0dXJuIE87XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIGlzT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMyk7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuXHQgIGlmKCFpc09iamVjdChpdCkpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuXHQgIHJldHVybiBpdDtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDEzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcblx0ICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMTQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzID0gIV9fd2VicGFja19yZXF1aXJlX18oMTUpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fKDE2KShmdW5jdGlvbigpe1xuXHQgIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoX193ZWJwYWNrX3JlcXVpcmVfXygxNykoJ2RpdicpLCAnYScsIHtnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiA3OyB9fSkuYSAhPSA3O1xuXHR9KTtcblxuLyoqKi8gfSxcbi8qIDE1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBUaGFuaydzIElFOCBmb3IgaGlzIGZ1bm55IGRlZmluZVByb3BlcnR5XG5cdG1vZHVsZS5leHBvcnRzID0gIV9fd2VicGFja19yZXF1aXJlX18oMTYpKGZ1bmN0aW9uKCl7XG5cdCAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7Z2V0OiBmdW5jdGlvbigpeyByZXR1cm4gNzsgfX0pLmEgIT0gNztcblx0fSk7XG5cbi8qKiovIH0sXG4vKiAxNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihleGVjKXtcblx0ICB0cnkge1xuXHQgICAgcmV0dXJuICEhZXhlYygpO1xuXHQgIH0gY2F0Y2goZSl7XG5cdCAgICByZXR1cm4gdHJ1ZTtcblx0ICB9XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIGlzT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMylcblx0ICAsIGRvY3VtZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KS5kb2N1bWVudFxuXHQgIC8vIGluIG9sZCBJRSB0eXBlb2YgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBpcyAnb2JqZWN0J1xuXHQgICwgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuXHQgIHJldHVybiBpcyA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaXQpIDoge307XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG5cdHZhciBpc09iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oMTMpO1xuXHQvLyBpbnN0ZWFkIG9mIHRoZSBFUzYgc3BlYyB2ZXJzaW9uLCB3ZSBkaWRuJ3QgaW1wbGVtZW50IEBAdG9QcmltaXRpdmUgY2FzZVxuXHQvLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBTKXtcblx0ICBpZighaXNPYmplY3QoaXQpKXJldHVybiBpdDtcblx0ICB2YXIgZm4sIHZhbDtcblx0ICBpZihTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XG5cdCAgaWYodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSlyZXR1cm4gdmFsO1xuXHQgIGlmKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XG5cdCAgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY29udmVydCBvYmplY3QgdG8gcHJpbWl0aXZlIHZhbHVlXCIpO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMTkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYml0bWFwLCB2YWx1ZSl7XG5cdCAgcmV0dXJuIHtcblx0ICAgIGVudW1lcmFibGUgIDogIShiaXRtYXAgJiAxKSxcblx0ICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcblx0ICAgIHdyaXRhYmxlICAgIDogIShiaXRtYXAgJiA0KSxcblx0ICAgIHZhbHVlICAgICAgIDogdmFsdWVcblx0ICB9O1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMjAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzID0geyBcImRlZmF1bHRcIjogX193ZWJwYWNrX3JlcXVpcmVfXygyMSksIF9fZXNNb2R1bGU6IHRydWUgfTtcblxuLyoqKi8gfSxcbi8qIDIxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDIyKTtcblx0X193ZWJwYWNrX3JlcXVpcmVfXyg1MSk7XG5cdG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1NSkuZignaXRlcmF0b3InKTtcblxuLyoqKi8gfSxcbi8qIDIyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdHZhciAkYXQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygyMykodHJ1ZSk7XG5cdFxuXHQvLyAyMS4xLjMuMjcgU3RyaW5nLnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5cdF9fd2VicGFja19yZXF1aXJlX18oMjYpKFN0cmluZywgJ1N0cmluZycsIGZ1bmN0aW9uKGl0ZXJhdGVkKXtcblx0ICB0aGlzLl90ID0gU3RyaW5nKGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG5cdCAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcblx0Ly8gMjEuMS41LjIuMSAlU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlLm5leHQoKVxuXHR9LCBmdW5jdGlvbigpe1xuXHQgIHZhciBPICAgICA9IHRoaXMuX3Rcblx0ICAgICwgaW5kZXggPSB0aGlzLl9pXG5cdCAgICAsIHBvaW50O1xuXHQgIGlmKGluZGV4ID49IE8ubGVuZ3RoKXJldHVybiB7dmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZX07XG5cdCAgcG9pbnQgPSAkYXQoTywgaW5kZXgpO1xuXHQgIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuXHQgIHJldHVybiB7dmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZX07XG5cdH0pO1xuXG4vKioqLyB9LFxuLyogMjMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciB0b0ludGVnZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI0KVxuXHQgICwgZGVmaW5lZCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygyNSk7XG5cdC8vIHRydWUgIC0+IFN0cmluZyNhdFxuXHQvLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihUT19TVFJJTkcpe1xuXHQgIHJldHVybiBmdW5jdGlvbih0aGF0LCBwb3Mpe1xuXHQgICAgdmFyIHMgPSBTdHJpbmcoZGVmaW5lZCh0aGF0KSlcblx0ICAgICAgLCBpID0gdG9JbnRlZ2VyKHBvcylcblx0ICAgICAgLCBsID0gcy5sZW5ndGhcblx0ICAgICAgLCBhLCBiO1xuXHQgICAgaWYoaSA8IDAgfHwgaSA+PSBsKXJldHVybiBUT19TVFJJTkcgPyAnJyA6IHVuZGVmaW5lZDtcblx0ICAgIGEgPSBzLmNoYXJDb2RlQXQoaSk7XG5cdCAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxuXHQgICAgICA/IFRPX1NUUklORyA/IHMuY2hhckF0KGkpIDogYVxuXHQgICAgICA6IFRPX1NUUklORyA/IHMuc2xpY2UoaSwgaSArIDIpIDogKGEgLSAweGQ4MDAgPDwgMTApICsgKGIgLSAweGRjMDApICsgMHgxMDAwMDtcblx0ICB9O1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMjQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdC8vIDcuMS40IFRvSW50ZWdlclxuXHR2YXIgY2VpbCAgPSBNYXRoLmNlaWxcblx0ICAsIGZsb29yID0gTWF0aC5mbG9vcjtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG5cdCAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAyNSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0Ly8gNy4yLjEgUmVxdWlyZU9iamVjdENvZXJjaWJsZShhcmd1bWVudClcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG5cdCAgaWYoaXQgPT0gdW5kZWZpbmVkKXRocm93IFR5cGVFcnJvcihcIkNhbid0IGNhbGwgbWV0aG9kIG9uICBcIiArIGl0KTtcblx0ICByZXR1cm4gaXQ7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAyNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHR2YXIgTElCUkFSWSAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI3KVxuXHQgICwgJGV4cG9ydCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpXG5cdCAgLCByZWRlZmluZSAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMjgpXG5cdCAgLCBoaWRlICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTApXG5cdCAgLCBoYXMgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMjkpXG5cdCAgLCBJdGVyYXRvcnMgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzApXG5cdCAgLCAkaXRlckNyZWF0ZSAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzEpXG5cdCAgLCBzZXRUb1N0cmluZ1RhZyA9IF9fd2VicGFja19yZXF1aXJlX18oNDcpXG5cdCAgLCBnZXRQcm90b3R5cGVPZiA9IF9fd2VicGFja19yZXF1aXJlX18oNDkpXG5cdCAgLCBJVEVSQVRPUiAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oNDgpKCdpdGVyYXRvcicpXG5cdCAgLCBCVUdHWSAgICAgICAgICA9ICEoW10ua2V5cyAmJiAnbmV4dCcgaW4gW10ua2V5cygpKSAvLyBTYWZhcmkgaGFzIGJ1Z2d5IGl0ZXJhdG9ycyB3L28gYG5leHRgXG5cdCAgLCBGRl9JVEVSQVRPUiAgICA9ICdAQGl0ZXJhdG9yJ1xuXHQgICwgS0VZUyAgICAgICAgICAgPSAna2V5cydcblx0ICAsIFZBTFVFUyAgICAgICAgID0gJ3ZhbHVlcyc7XG5cdFxuXHR2YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9O1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihCYXNlLCBOQU1FLCBDb25zdHJ1Y3RvciwgbmV4dCwgREVGQVVMVCwgSVNfU0VULCBGT1JDRUQpe1xuXHQgICRpdGVyQ3JlYXRlKENvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KTtcblx0ICB2YXIgZ2V0TWV0aG9kID0gZnVuY3Rpb24oa2luZCl7XG5cdCAgICBpZighQlVHR1kgJiYga2luZCBpbiBwcm90bylyZXR1cm4gcHJvdG9ba2luZF07XG5cdCAgICBzd2l0Y2goa2luZCl7XG5cdCAgICAgIGNhc2UgS0VZUzogcmV0dXJuIGZ1bmN0aW9uIGtleXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcblx0ICAgICAgY2FzZSBWQUxVRVM6IHJldHVybiBmdW5jdGlvbiB2YWx1ZXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcblx0ICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcblx0ICB9O1xuXHQgIHZhciBUQUcgICAgICAgID0gTkFNRSArICcgSXRlcmF0b3InXG5cdCAgICAsIERFRl9WQUxVRVMgPSBERUZBVUxUID09IFZBTFVFU1xuXHQgICAgLCBWQUxVRVNfQlVHID0gZmFsc2Vcblx0ICAgICwgcHJvdG8gICAgICA9IEJhc2UucHJvdG90eXBlXG5cdCAgICAsICRuYXRpdmUgICAgPSBwcm90b1tJVEVSQVRPUl0gfHwgcHJvdG9bRkZfSVRFUkFUT1JdIHx8IERFRkFVTFQgJiYgcHJvdG9bREVGQVVMVF1cblx0ICAgICwgJGRlZmF1bHQgICA9ICRuYXRpdmUgfHwgZ2V0TWV0aG9kKERFRkFVTFQpXG5cdCAgICAsICRlbnRyaWVzICAgPSBERUZBVUxUID8gIURFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZCgnZW50cmllcycpIDogdW5kZWZpbmVkXG5cdCAgICAsICRhbnlOYXRpdmUgPSBOQU1FID09ICdBcnJheScgPyBwcm90by5lbnRyaWVzIHx8ICRuYXRpdmUgOiAkbmF0aXZlXG5cdCAgICAsIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG5cdCAgLy8gRml4IG5hdGl2ZVxuXHQgIGlmKCRhbnlOYXRpdmUpe1xuXHQgICAgSXRlcmF0b3JQcm90b3R5cGUgPSBnZXRQcm90b3R5cGVPZigkYW55TmF0aXZlLmNhbGwobmV3IEJhc2UpKTtcblx0ICAgIGlmKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlKXtcblx0ICAgICAgLy8gU2V0IEBAdG9TdHJpbmdUYWcgdG8gbmF0aXZlIGl0ZXJhdG9yc1xuXHQgICAgICBzZXRUb1N0cmluZ1RhZyhJdGVyYXRvclByb3RvdHlwZSwgVEFHLCB0cnVlKTtcblx0ICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG5cdCAgICAgIGlmKCFMSUJSQVJZICYmICFoYXMoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SKSloaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG5cdCAgICB9XG5cdCAgfVxuXHQgIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcblx0ICBpZihERUZfVkFMVUVTICYmICRuYXRpdmUgJiYgJG5hdGl2ZS5uYW1lICE9PSBWQUxVRVMpe1xuXHQgICAgVkFMVUVTX0JVRyA9IHRydWU7XG5cdCAgICAkZGVmYXVsdCA9IGZ1bmN0aW9uIHZhbHVlcygpeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuXHQgIH1cblx0ICAvLyBEZWZpbmUgaXRlcmF0b3Jcblx0ICBpZigoIUxJQlJBUlkgfHwgRk9SQ0VEKSAmJiAoQlVHR1kgfHwgVkFMVUVTX0JVRyB8fCAhcHJvdG9bSVRFUkFUT1JdKSl7XG5cdCAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuXHQgIH1cblx0ICAvLyBQbHVnIGZvciBsaWJyYXJ5XG5cdCAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG5cdCAgSXRlcmF0b3JzW1RBR10gID0gcmV0dXJuVGhpcztcblx0ICBpZihERUZBVUxUKXtcblx0ICAgIG1ldGhvZHMgPSB7XG5cdCAgICAgIHZhbHVlczogIERFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChWQUxVRVMpLFxuXHQgICAgICBrZXlzOiAgICBJU19TRVQgICAgID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoS0VZUyksXG5cdCAgICAgIGVudHJpZXM6ICRlbnRyaWVzXG5cdCAgICB9O1xuXHQgICAgaWYoRk9SQ0VEKWZvcihrZXkgaW4gbWV0aG9kcyl7XG5cdCAgICAgIGlmKCEoa2V5IGluIHByb3RvKSlyZWRlZmluZShwcm90bywga2V5LCBtZXRob2RzW2tleV0pO1xuXHQgICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcblx0ICB9XG5cdCAgcmV0dXJuIG1ldGhvZHM7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAyNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSB0cnVlO1xuXG4vKioqLyB9LFxuLyogMjggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMCk7XG5cbi8qKiovIH0sXG4vKiAyOSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0dmFyIGhhc093blByb3BlcnR5ID0ge30uaGFzT3duUHJvcGVydHk7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIGtleSl7XG5cdCAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAzMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLyoqKi8gfSxcbi8qIDMxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdHZhciBjcmVhdGUgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzIpXG5cdCAgLCBkZXNjcmlwdG9yICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTkpXG5cdCAgLCBzZXRUb1N0cmluZ1RhZyA9IF9fd2VicGFja19yZXF1aXJlX18oNDcpXG5cdCAgLCBJdGVyYXRvclByb3RvdHlwZSA9IHt9O1xuXHRcblx0Ly8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcblx0X193ZWJwYWNrX3JlcXVpcmVfXygxMCkoSXRlcmF0b3JQcm90b3R5cGUsIF9fd2VicGFja19yZXF1aXJlX18oNDgpKCdpdGVyYXRvcicpLCBmdW5jdGlvbigpeyByZXR1cm4gdGhpczsgfSk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKENvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KXtcblx0ICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBjcmVhdGUoSXRlcmF0b3JQcm90b3R5cGUsIHtuZXh0OiBkZXNjcmlwdG9yKDEsIG5leHQpfSk7XG5cdCAgc2V0VG9TdHJpbmdUYWcoQ29uc3RydWN0b3IsIE5BTUUgKyAnIEl0ZXJhdG9yJyk7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAzMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gMTkuMS4yLjIgLyAxNS4yLjMuNSBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXG5cdHZhciBhbk9iamVjdCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTIpXG5cdCAgLCBkUHMgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzMpXG5cdCAgLCBlbnVtQnVnS2V5cyA9IF9fd2VicGFja19yZXF1aXJlX18oNDUpXG5cdCAgLCBJRV9QUk9UTyAgICA9IF9fd2VicGFja19yZXF1aXJlX18oNDIpKCdJRV9QUk9UTycpXG5cdCAgLCBFbXB0eSAgICAgICA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH1cblx0ICAsIFBST1RPVFlQRSAgID0gJ3Byb3RvdHlwZSc7XG5cdFxuXHQvLyBDcmVhdGUgb2JqZWN0IHdpdGggZmFrZSBgbnVsbGAgcHJvdG90eXBlOiB1c2UgaWZyYW1lIE9iamVjdCB3aXRoIGNsZWFyZWQgcHJvdG90eXBlXG5cdHZhciBjcmVhdGVEaWN0ID0gZnVuY3Rpb24oKXtcblx0ICAvLyBUaHJhc2gsIHdhc3RlIGFuZCBzb2RvbXk6IElFIEdDIGJ1Z1xuXHQgIHZhciBpZnJhbWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE3KSgnaWZyYW1lJylcblx0ICAgICwgaSAgICAgID0gZW51bUJ1Z0tleXMubGVuZ3RoXG5cdCAgICAsIGx0ICAgICA9ICc8J1xuXHQgICAgLCBndCAgICAgPSAnPidcblx0ICAgICwgaWZyYW1lRG9jdW1lbnQ7XG5cdCAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdCAgX193ZWJwYWNrX3JlcXVpcmVfXyg0NikuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcblx0ICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG5cdCAgLy8gY3JlYXRlRGljdCA9IGlmcmFtZS5jb250ZW50V2luZG93Lk9iamVjdDtcblx0ICAvLyBodG1sLnJlbW92ZUNoaWxkKGlmcmFtZSk7XG5cdCAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcblx0ICBpZnJhbWVEb2N1bWVudC5vcGVuKCk7XG5cdCAgaWZyYW1lRG9jdW1lbnQud3JpdGUobHQgKyAnc2NyaXB0JyArIGd0ICsgJ2RvY3VtZW50LkY9T2JqZWN0JyArIGx0ICsgJy9zY3JpcHQnICsgZ3QpO1xuXHQgIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG5cdCAgY3JlYXRlRGljdCA9IGlmcmFtZURvY3VtZW50LkY7XG5cdCAgd2hpbGUoaS0tKWRlbGV0ZSBjcmVhdGVEaWN0W1BST1RPVFlQRV1bZW51bUJ1Z0tleXNbaV1dO1xuXHQgIHJldHVybiBjcmVhdGVEaWN0KCk7XG5cdH07XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gY3JlYXRlKE8sIFByb3BlcnRpZXMpe1xuXHQgIHZhciByZXN1bHQ7XG5cdCAgaWYoTyAhPT0gbnVsbCl7XG5cdCAgICBFbXB0eVtQUk9UT1RZUEVdID0gYW5PYmplY3QoTyk7XG5cdCAgICByZXN1bHQgPSBuZXcgRW1wdHk7XG5cdCAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcblx0ICAgIC8vIGFkZCBcIl9fcHJvdG9fX1wiIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YgcG9seWZpbGxcblx0ICAgIHJlc3VsdFtJRV9QUk9UT10gPSBPO1xuXHQgIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XG5cdCAgcmV0dXJuIFByb3BlcnRpZXMgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IGRQcyhyZXN1bHQsIFByb3BlcnRpZXMpO1xuXHR9O1xuXG5cbi8qKiovIH0sXG4vKiAzMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIGRQICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMSlcblx0ICAsIGFuT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMilcblx0ICAsIGdldEtleXMgID0gX193ZWJwYWNrX3JlcXVpcmVfXygzNCk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oMTUpID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpe1xuXHQgIGFuT2JqZWN0KE8pO1xuXHQgIHZhciBrZXlzICAgPSBnZXRLZXlzKFByb3BlcnRpZXMpXG5cdCAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXG5cdCAgICAsIGkgPSAwXG5cdCAgICAsIFA7XG5cdCAgd2hpbGUobGVuZ3RoID4gaSlkUC5mKE8sIFAgPSBrZXlzW2krK10sIFByb3BlcnRpZXNbUF0pO1xuXHQgIHJldHVybiBPO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMzQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIDE5LjEuMi4xNCAvIDE1LjIuMy4xNCBPYmplY3Qua2V5cyhPKVxuXHR2YXIgJGtleXMgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDM1KVxuXHQgICwgZW51bUJ1Z0tleXMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ1KTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyhPKXtcblx0ICByZXR1cm4gJGtleXMoTywgZW51bUJ1Z0tleXMpO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMzUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBoYXMgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI5KVxuXHQgICwgdG9JT2JqZWN0ICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygzNilcblx0ICAsIGFycmF5SW5kZXhPZiA9IF9fd2VicGFja19yZXF1aXJlX18oMzkpKGZhbHNlKVxuXHQgICwgSUVfUFJPVE8gICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0MikoJ0lFX1BST1RPJyk7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iamVjdCwgbmFtZXMpe1xuXHQgIHZhciBPICAgICAgPSB0b0lPYmplY3Qob2JqZWN0KVxuXHQgICAgLCBpICAgICAgPSAwXG5cdCAgICAsIHJlc3VsdCA9IFtdXG5cdCAgICAsIGtleTtcblx0ICBmb3Ioa2V5IGluIE8paWYoa2V5ICE9IElFX1BST1RPKWhhcyhPLCBrZXkpICYmIHJlc3VsdC5wdXNoKGtleSk7XG5cdCAgLy8gRG9uJ3QgZW51bSBidWcgJiBoaWRkZW4ga2V5c1xuXHQgIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpaWYoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKXtcblx0ICAgIH5hcnJheUluZGV4T2YocmVzdWx0LCBrZXkpIHx8IHJlc3VsdC5wdXNoKGtleSk7XG5cdCAgfVxuXHQgIHJldHVybiByZXN1bHQ7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAzNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG5cdHZhciBJT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygzNylcblx0ICAsIGRlZmluZWQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI1KTtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG5cdCAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMzcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgYW5kIG5vbi1lbnVtZXJhYmxlIG9sZCBWOCBzdHJpbmdzXG5cdHZhciBjb2YgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDM4KTtcblx0bW9kdWxlLmV4cG9ydHMgPSBPYmplY3QoJ3onKS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgwKSA/IE9iamVjdCA6IGZ1bmN0aW9uKGl0KXtcblx0ICByZXR1cm4gY29mKGl0KSA9PSAnU3RyaW5nJyA/IGl0LnNwbGl0KCcnKSA6IE9iamVjdChpdCk7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAzOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0dmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcblx0ICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMzkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIGZhbHNlIC0+IEFycmF5I2luZGV4T2Zcblx0Ly8gdHJ1ZSAgLT4gQXJyYXkjaW5jbHVkZXNcblx0dmFyIHRvSU9iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oMzYpXG5cdCAgLCB0b0xlbmd0aCAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQwKVxuXHQgICwgdG9JbmRleCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0MSk7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oSVNfSU5DTFVERVMpe1xuXHQgIHJldHVybiBmdW5jdGlvbigkdGhpcywgZWwsIGZyb21JbmRleCl7XG5cdCAgICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KCR0aGlzKVxuXHQgICAgICAsIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKVxuXHQgICAgICAsIGluZGV4ICA9IHRvSW5kZXgoZnJvbUluZGV4LCBsZW5ndGgpXG5cdCAgICAgICwgdmFsdWU7XG5cdCAgICAvLyBBcnJheSNpbmNsdWRlcyB1c2VzIFNhbWVWYWx1ZVplcm8gZXF1YWxpdHkgYWxnb3JpdGhtXG5cdCAgICBpZihJU19JTkNMVURFUyAmJiBlbCAhPSBlbCl3aGlsZShsZW5ndGggPiBpbmRleCl7XG5cdCAgICAgIHZhbHVlID0gT1tpbmRleCsrXTtcblx0ICAgICAgaWYodmFsdWUgIT0gdmFsdWUpcmV0dXJuIHRydWU7XG5cdCAgICAvLyBBcnJheSN0b0luZGV4IGlnbm9yZXMgaG9sZXMsIEFycmF5I2luY2x1ZGVzIC0gbm90XG5cdCAgICB9IGVsc2UgZm9yKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKylpZihJU19JTkNMVURFUyB8fCBpbmRleCBpbiBPKXtcblx0ICAgICAgaWYoT1tpbmRleF0gPT09IGVsKXJldHVybiBJU19JTkNMVURFUyB8fCBpbmRleCB8fCAwO1xuXHQgICAgfSByZXR1cm4gIUlTX0lOQ0xVREVTICYmIC0xO1xuXHQgIH07XG5cdH07XG5cbi8qKiovIH0sXG4vKiA0MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gNy4xLjE1IFRvTGVuZ3RoXG5cdHZhciB0b0ludGVnZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI0KVxuXHQgICwgbWluICAgICAgID0gTWF0aC5taW47XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuXHQgIHJldHVybiBpdCA+IDAgPyBtaW4odG9JbnRlZ2VyKGl0KSwgMHgxZmZmZmZmZmZmZmZmZikgOiAwOyAvLyBwb3coMiwgNTMpIC0gMSA9PSA5MDA3MTk5MjU0NzQwOTkxXG5cdH07XG5cbi8qKiovIH0sXG4vKiA0MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIHRvSW50ZWdlciA9IF9fd2VicGFja19yZXF1aXJlX18oMjQpXG5cdCAgLCBtYXggICAgICAgPSBNYXRoLm1heFxuXHQgICwgbWluICAgICAgID0gTWF0aC5taW47XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5kZXgsIGxlbmd0aCl7XG5cdCAgaW5kZXggPSB0b0ludGVnZXIoaW5kZXgpO1xuXHQgIHJldHVybiBpbmRleCA8IDAgPyBtYXgoaW5kZXggKyBsZW5ndGgsIDApIDogbWluKGluZGV4LCBsZW5ndGgpO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogNDIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBzaGFyZWQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQzKSgna2V5cycpXG5cdCAgLCB1aWQgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ0KTtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xuXHQgIHJldHVybiBzaGFyZWRba2V5XSB8fCAoc2hhcmVkW2tleV0gPSB1aWQoa2V5KSk7XG5cdH07XG5cbi8qKiovIH0sXG4vKiA0MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIGdsb2JhbCA9IF9fd2VicGFja19yZXF1aXJlX18oNilcblx0ICAsIFNIQVJFRCA9ICdfX2NvcmUtanNfc2hhcmVkX18nXG5cdCAgLCBzdG9yZSAgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcblx0ICByZXR1cm4gc3RvcmVba2V5XSB8fCAoc3RvcmVba2V5XSA9IHt9KTtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDQ0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHR2YXIgaWQgPSAwXG5cdCAgLCBweCA9IE1hdGgucmFuZG9tKCk7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcblx0ICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogNDUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdC8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcblx0bW9kdWxlLmV4cG9ydHMgPSAoXG5cdCAgJ2NvbnN0cnVjdG9yLGhhc093blByb3BlcnR5LGlzUHJvdG90eXBlT2YscHJvcGVydHlJc0VudW1lcmFibGUsdG9Mb2NhbGVTdHJpbmcsdG9TdHJpbmcsdmFsdWVPZidcblx0KS5zcGxpdCgnLCcpO1xuXG4vKioqLyB9LFxuLyogNDYgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KS5kb2N1bWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cbi8qKiovIH0sXG4vKiA0NyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIGRlZiA9IF9fd2VicGFja19yZXF1aXJlX18oMTEpLmZcblx0ICAsIGhhcyA9IF9fd2VicGFja19yZXF1aXJlX18oMjkpXG5cdCAgLCBUQUcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ4KSgndG9TdHJpbmdUYWcnKTtcblx0XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIHRhZywgc3RhdCl7XG5cdCAgaWYoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSlkZWYoaXQsIFRBRywge2NvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHRhZ30pO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogNDggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBzdG9yZSAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0MykoJ3drcycpXG5cdCAgLCB1aWQgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0NClcblx0ICAsIFN5bWJvbCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpLlN5bWJvbFxuXHQgICwgVVNFX1NZTUJPTCA9IHR5cGVvZiBTeW1ib2wgPT0gJ2Z1bmN0aW9uJztcblx0XG5cdHZhciAkZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obmFtZSl7XG5cdCAgcmV0dXJuIHN0b3JlW25hbWVdIHx8IChzdG9yZVtuYW1lXSA9XG5cdCAgICBVU0VfU1lNQk9MICYmIFN5bWJvbFtuYW1lXSB8fCAoVVNFX1NZTUJPTCA/IFN5bWJvbCA6IHVpZCkoJ1N5bWJvbC4nICsgbmFtZSkpO1xuXHR9O1xuXHRcblx0JGV4cG9ydHMuc3RvcmUgPSBzdG9yZTtcblxuLyoqKi8gfSxcbi8qIDQ5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyAxOS4xLjIuOSAvIDE1LjIuMy4yIE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxuXHR2YXIgaGFzICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI5KVxuXHQgICwgdG9PYmplY3QgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUwKVxuXHQgICwgSUVfUFJPVE8gICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQyKSgnSUVfUFJPVE8nKVxuXHQgICwgT2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24oTyl7XG5cdCAgTyA9IHRvT2JqZWN0KE8pO1xuXHQgIGlmKGhhcyhPLCBJRV9QUk9UTykpcmV0dXJuIE9bSUVfUFJPVE9dO1xuXHQgIGlmKHR5cGVvZiBPLmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgTyBpbnN0YW5jZW9mIE8uY29uc3RydWN0b3Ipe1xuXHQgICAgcmV0dXJuIE8uY29uc3RydWN0b3IucHJvdG90eXBlO1xuXHQgIH0gcmV0dXJuIE8gaW5zdGFuY2VvZiBPYmplY3QgPyBPYmplY3RQcm90byA6IG51bGw7XG5cdH07XG5cbi8qKiovIH0sXG4vKiA1MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gNy4xLjEzIFRvT2JqZWN0KGFyZ3VtZW50KVxuXHR2YXIgZGVmaW5lZCA9IF9fd2VicGFja19yZXF1aXJlX18oMjUpO1xuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcblx0ICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDUxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDUyKTtcblx0dmFyIGdsb2JhbCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpXG5cdCAgLCBoaWRlICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMClcblx0ICAsIEl0ZXJhdG9ycyAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDMwKVxuXHQgICwgVE9fU1RSSU5HX1RBRyA9IF9fd2VicGFja19yZXF1aXJlX18oNDgpKCd0b1N0cmluZ1RhZycpO1xuXHRcblx0Zm9yKHZhciBjb2xsZWN0aW9ucyA9IFsnTm9kZUxpc3QnLCAnRE9NVG9rZW5MaXN0JywgJ01lZGlhTGlzdCcsICdTdHlsZVNoZWV0TGlzdCcsICdDU1NSdWxlTGlzdCddLCBpID0gMDsgaSA8IDU7IGkrKyl7XG5cdCAgdmFyIE5BTUUgICAgICAgPSBjb2xsZWN0aW9uc1tpXVxuXHQgICAgLCBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdXG5cdCAgICAsIHByb3RvICAgICAgPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuXHQgIGlmKHByb3RvICYmICFwcm90b1tUT19TVFJJTkdfVEFHXSloaWRlKHByb3RvLCBUT19TVFJJTkdfVEFHLCBOQU1FKTtcblx0ICBJdGVyYXRvcnNbTkFNRV0gPSBJdGVyYXRvcnMuQXJyYXk7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDUyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdHZhciBhZGRUb1Vuc2NvcGFibGVzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1Mylcblx0ICAsIHN0ZXAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDU0KVxuXHQgICwgSXRlcmF0b3JzICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzApXG5cdCAgLCB0b0lPYmplY3QgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygzNik7XG5cdFxuXHQvLyAyMi4xLjMuNCBBcnJheS5wcm90b3R5cGUuZW50cmllcygpXG5cdC8vIDIyLjEuMy4xMyBBcnJheS5wcm90b3R5cGUua2V5cygpXG5cdC8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcblx0Ly8gMjIuMS4zLjMwIEFycmF5LnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5cdG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygyNikoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uKGl0ZXJhdGVkLCBraW5kKXtcblx0ICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG5cdCAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcblx0ICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgLy8ga2luZFxuXHQvLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcblx0fSwgZnVuY3Rpb24oKXtcblx0ICB2YXIgTyAgICAgPSB0aGlzLl90XG5cdCAgICAsIGtpbmQgID0gdGhpcy5fa1xuXHQgICAgLCBpbmRleCA9IHRoaXMuX2krKztcblx0ICBpZighTyB8fCBpbmRleCA+PSBPLmxlbmd0aCl7XG5cdCAgICB0aGlzLl90ID0gdW5kZWZpbmVkO1xuXHQgICAgcmV0dXJuIHN0ZXAoMSk7XG5cdCAgfVxuXHQgIGlmKGtpbmQgPT0gJ2tleXMnICApcmV0dXJuIHN0ZXAoMCwgaW5kZXgpO1xuXHQgIGlmKGtpbmQgPT0gJ3ZhbHVlcycpcmV0dXJuIHN0ZXAoMCwgT1tpbmRleF0pO1xuXHQgIHJldHVybiBzdGVwKDAsIFtpbmRleCwgT1tpbmRleF1dKTtcblx0fSwgJ3ZhbHVlcycpO1xuXHRcblx0Ly8gYXJndW1lbnRzTGlzdFtAQGl0ZXJhdG9yXSBpcyAlQXJyYXlQcm90b192YWx1ZXMlICg5LjQuNC42LCA5LjQuNC43KVxuXHRJdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXHRcblx0YWRkVG9VbnNjb3BhYmxlcygna2V5cycpO1xuXHRhZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcblx0YWRkVG9VbnNjb3BhYmxlcygnZW50cmllcycpO1xuXG4vKioqLyB9LFxuLyogNTMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKXsgLyogZW1wdHkgKi8gfTtcblxuLyoqKi8gfSxcbi8qIDU0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGRvbmUsIHZhbHVlKXtcblx0ICByZXR1cm4ge3ZhbHVlOiB2YWx1ZSwgZG9uZTogISFkb25lfTtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDU1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzLmYgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ4KTtcblxuLyoqKi8gfSxcbi8qIDU2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IF9fd2VicGFja19yZXF1aXJlX18oNTcpLCBfX2VzTW9kdWxlOiB0cnVlIH07XG5cbi8qKiovIH0sXG4vKiA1NyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0X193ZWJwYWNrX3JlcXVpcmVfXyg1OCk7XG5cdHZhciAkT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3KS5PYmplY3Q7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCl7XG5cdCAgcmV0dXJuICRPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhpdCk7XG5cdH07XG5cbi8qKiovIH0sXG4vKiA1OCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gMTkuMS4yLjcgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcblx0X193ZWJwYWNrX3JlcXVpcmVfXyg1OSkoJ2dldE93blByb3BlcnR5TmFtZXMnLCBmdW5jdGlvbigpe1xuXHQgIHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDYwKS5mO1xuXHR9KTtcblxuLyoqKi8gfSxcbi8qIDU5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBtb3N0IE9iamVjdCBtZXRob2RzIGJ5IEVTNiBzaG91bGQgYWNjZXB0IHByaW1pdGl2ZXNcblx0dmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpXG5cdCAgLCBjb3JlICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3KVxuXHQgICwgZmFpbHMgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTYpO1xuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKEtFWSwgZXhlYyl7XG5cdCAgdmFyIGZuICA9IChjb3JlLk9iamVjdCB8fCB7fSlbS0VZXSB8fCBPYmplY3RbS0VZXVxuXHQgICAgLCBleHAgPSB7fTtcblx0ICBleHBbS0VZXSA9IGV4ZWMoZm4pO1xuXHQgICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24oKXsgZm4oMSk7IH0pLCAnT2JqZWN0JywgZXhwKTtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDYwICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG5cdHZhciB0b0lPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDM2KVxuXHQgICwgZ09QTiAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2MSkuZlxuXHQgICwgdG9TdHJpbmcgID0ge30udG9TdHJpbmc7XG5cdFxuXHR2YXIgd2luZG93TmFtZXMgPSB0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnICYmIHdpbmRvdyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lc1xuXHQgID8gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMod2luZG93KSA6IFtdO1xuXHRcblx0dmFyIGdldFdpbmRvd05hbWVzID0gZnVuY3Rpb24oaXQpe1xuXHQgIHRyeSB7XG5cdCAgICByZXR1cm4gZ09QTihpdCk7XG5cdCAgfSBjYXRjaChlKXtcblx0ICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuXHQgIH1cblx0fTtcblx0XG5cdG1vZHVsZS5leHBvcnRzLmYgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKGl0KXtcblx0ICByZXR1cm4gd2luZG93TmFtZXMgJiYgdG9TdHJpbmcuY2FsbChpdCkgPT0gJ1tvYmplY3QgV2luZG93XScgPyBnZXRXaW5kb3dOYW1lcyhpdCkgOiBnT1BOKHRvSU9iamVjdChpdCkpO1xuXHR9O1xuXG5cbi8qKiovIH0sXG4vKiA2MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gMTkuMS4yLjcgLyAxNS4yLjMuNCBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxuXHR2YXIgJGtleXMgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzUpXG5cdCAgLCBoaWRkZW5LZXlzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0NSkuY29uY2F0KCdsZW5ndGgnLCAncHJvdG90eXBlJyk7XG5cdFxuXHRleHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB8fCBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKE8pe1xuXHQgIHJldHVybiAka2V5cyhPLCBoaWRkZW5LZXlzKTtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDYyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG5cdCAgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHtcblx0ICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogNjMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0ZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblx0XG5cdHZhciBfZGVmaW5lUHJvcGVydHkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpO1xuXHRcblx0dmFyIF9kZWZpbmVQcm9wZXJ0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9kZWZpbmVQcm9wZXJ0eSk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuXHQgIGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykge1xuXHQgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuXHQgICAgICBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7XG5cdCAgICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcblx0ICAgICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcblx0ICAgICAgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7XG5cdCAgICB9XG5cdCAgfVxuXHRcblx0ICByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuXHQgICAgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcblx0ICAgIGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuXHQgICAgcmV0dXJuIENvbnN0cnVjdG9yO1xuXHQgIH07XG5cdH0oKTtcblxuLyoqKi8gfSxcbi8qIDY0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHQvKipcclxuXHQgKiBBcnJheS5maW5kXHJcblx0ICovXG5cdGlmICghQXJyYXkucHJvdG90eXBlLmZpbmQpIHtcblx0ICBBcnJheS5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uIChwcmVkaWNhdGUpIHtcblx0ICAgICd1c2Ugc3RyaWN0Jztcblx0XG5cdCAgICBpZiAodGhpcyA9PSBudWxsKSB7XG5cdCAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5maW5kIGNhbGxlZCBvbiBudWxsIG9yIHVuZGVmaW5lZCcpO1xuXHQgICAgfVxuXHQgICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncHJlZGljYXRlIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHQgICAgfVxuXHQgICAgdmFyIGxpc3QgPSBPYmplY3QodGhpcyk7XG5cdCAgICB2YXIgbGVuZ3RoID0gbGlzdC5sZW5ndGggPj4+IDA7XG5cdCAgICB2YXIgdGhpc0FyZyA9IGFyZ3VtZW50c1sxXTtcblx0ICAgIHZhciB2YWx1ZTtcblx0XG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdCAgICAgIHZhbHVlID0gbGlzdFtpXTtcblx0ICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKHRoaXNBcmcsIHZhbHVlLCBpLCBsaXN0KSkge1xuXHQgICAgICAgIHJldHVybiB2YWx1ZTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgICAgcmV0dXJuIHVuZGVmaW5lZDtcblx0ICB9O1xuXHR9XG5cdFxuXHQvKlxyXG5cdCAqIGNsYXNzTGlzdC5qczogQ3Jvc3MtYnJvd3NlciBmdWxsIGVsZW1lbnQuY2xhc3NMaXN0IGltcGxlbWVudGF0aW9uLlxyXG5cdCAqIDEuMS4yMDE1MDMxMlxyXG5cdCAqXHJcblx0ICogQnkgRWxpIEdyZXksIGh0dHA6Ly9lbGlncmV5LmNvbVxyXG5cdCAqIExpY2Vuc2U6IERlZGljYXRlZCB0byB0aGUgcHVibGljIGRvbWFpbi5cclxuXHQgKiAgIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZWxpZ3JleS9jbGFzc0xpc3QuanMvYmxvYi9tYXN0ZXIvTElDRU5TRS5tZFxyXG5cdCAqL1xuXHQvKmdsb2JhbCBzZWxmLCBkb2N1bWVudCwgRE9NRXhjZXB0aW9uICovXG5cdC8qISBAc291cmNlIGh0dHA6Ly9wdXJsLmVsaWdyZXkuY29tL2dpdGh1Yi9jbGFzc0xpc3QuanMvYmxvYi9tYXN0ZXIvY2xhc3NMaXN0LmpzICovXG5cdGlmIChcImRvY3VtZW50XCIgaW4gc2VsZikge1xuXHQgIC8vIEZ1bGwgcG9seWZpbGwgZm9yIGJyb3dzZXJzIHdpdGggbm8gY2xhc3NMaXN0IHN1cHBvcnRcblx0ICAvLyBJbmNsdWRpbmcgSUUgPCBFZGdlIG1pc3NpbmcgU1ZHRWxlbWVudC5jbGFzc0xpc3Rcblx0ICBpZiAoIShcImNsYXNzTGlzdFwiIGluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJfXCIpKSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMgJiYgIShcImNsYXNzTGlzdFwiIGluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwiZ1wiKSkpIHtcblx0XG5cdCAgICAoZnVuY3Rpb24gKHZpZXcpIHtcblx0XG5cdCAgICAgIFwidXNlIHN0cmljdFwiO1xuXHRcblx0ICAgICAgaWYgKCEoJ0VsZW1lbnQnIGluIHZpZXcpKSByZXR1cm47XG5cdFxuXHQgICAgICB2YXIgY2xhc3NMaXN0UHJvcCA9IFwiY2xhc3NMaXN0XCIsXG5cdCAgICAgICAgICBwcm90b1Byb3AgPSBcInByb3RvdHlwZVwiLFxuXHQgICAgICAgICAgZWxlbUN0clByb3RvID0gdmlldy5FbGVtZW50W3Byb3RvUHJvcF0sXG5cdCAgICAgICAgICBvYmpDdHIgPSBPYmplY3QsXG5cdCAgICAgICAgICBzdHJUcmltID0gU3RyaW5nW3Byb3RvUHJvcF0udHJpbSB8fCBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgXCJcIik7XG5cdCAgICAgIH0sXG5cdCAgICAgICAgICBhcnJJbmRleE9mID0gQXJyYXlbcHJvdG9Qcm9wXS5pbmRleE9mIHx8IGZ1bmN0aW9uIChpdGVtKSB7XG5cdCAgICAgICAgdmFyIGkgPSAwLFxuXHQgICAgICAgICAgICBsZW4gPSB0aGlzLmxlbmd0aDtcblx0ICAgICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7XG5cdCAgICAgICAgICBpZiAoaSBpbiB0aGlzICYmIHRoaXNbaV0gPT09IGl0ZW0pIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiAtMTtcblx0ICAgICAgfVxuXHQgICAgICAvLyBWZW5kb3JzOiBwbGVhc2UgYWxsb3cgY29udGVudCBjb2RlIHRvIGluc3RhbnRpYXRlIERPTUV4Y2VwdGlvbnNcblx0ICAgICAgLFxuXHQgICAgICAgICAgRE9NRXggPSBmdW5jdGlvbiBET01FeCh0eXBlLCBtZXNzYWdlKSB7XG5cdCAgICAgICAgdGhpcy5uYW1lID0gdHlwZTtcblx0ICAgICAgICB0aGlzLmNvZGUgPSBET01FeGNlcHRpb25bdHlwZV07XG5cdCAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcblx0ICAgICAgfSxcblx0ICAgICAgICAgIGNoZWNrVG9rZW5BbmRHZXRJbmRleCA9IGZ1bmN0aW9uIGNoZWNrVG9rZW5BbmRHZXRJbmRleChjbGFzc0xpc3QsIHRva2VuKSB7XG5cdCAgICAgICAgaWYgKHRva2VuID09PSBcIlwiKSB7XG5cdCAgICAgICAgICB0aHJvdyBuZXcgRE9NRXgoXCJTWU5UQVhfRVJSXCIsIFwiQW4gaW52YWxpZCBvciBpbGxlZ2FsIHN0cmluZyB3YXMgc3BlY2lmaWVkXCIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoL1xccy8udGVzdCh0b2tlbikpIHtcblx0ICAgICAgICAgIHRocm93IG5ldyBET01FeChcIklOVkFMSURfQ0hBUkFDVEVSX0VSUlwiLCBcIlN0cmluZyBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3RlclwiKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGFyckluZGV4T2YuY2FsbChjbGFzc0xpc3QsIHRva2VuKTtcblx0ICAgICAgfSxcblx0ICAgICAgICAgIENsYXNzTGlzdCA9IGZ1bmN0aW9uIENsYXNzTGlzdChlbGVtKSB7XG5cdCAgICAgICAgdmFyIHRyaW1tZWRDbGFzc2VzID0gc3RyVHJpbS5jYWxsKGVsZW0uZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgfHwgXCJcIiksXG5cdCAgICAgICAgICAgIGNsYXNzZXMgPSB0cmltbWVkQ2xhc3NlcyA/IHRyaW1tZWRDbGFzc2VzLnNwbGl0KC9cXHMrLykgOiBbXSxcblx0ICAgICAgICAgICAgaSA9IDAsXG5cdCAgICAgICAgICAgIGxlbiA9IGNsYXNzZXMubGVuZ3RoO1xuXHQgICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspIHtcblx0ICAgICAgICAgIHRoaXMucHVzaChjbGFzc2VzW2ldKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5fdXBkYXRlQ2xhc3NOYW1lID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgZWxlbS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCB0aGlzLnRvU3RyaW5nKCkpO1xuXHQgICAgICAgIH07XG5cdCAgICAgIH0sXG5cdCAgICAgICAgICBjbGFzc0xpc3RQcm90byA9IENsYXNzTGlzdFtwcm90b1Byb3BdID0gW10sXG5cdCAgICAgICAgICBjbGFzc0xpc3RHZXR0ZXIgPSBmdW5jdGlvbiBjbGFzc0xpc3RHZXR0ZXIoKSB7XG5cdCAgICAgICAgcmV0dXJuIG5ldyBDbGFzc0xpc3QodGhpcyk7XG5cdCAgICAgIH07XG5cdCAgICAgIC8vIE1vc3QgRE9NRXhjZXB0aW9uIGltcGxlbWVudGF0aW9ucyBkb24ndCBhbGxvdyBjYWxsaW5nIERPTUV4Y2VwdGlvbidzIHRvU3RyaW5nKClcblx0ICAgICAgLy8gb24gbm9uLURPTUV4Y2VwdGlvbnMuIEVycm9yJ3MgdG9TdHJpbmcoKSBpcyBzdWZmaWNpZW50IGhlcmUuXG5cdCAgICAgIERPTUV4W3Byb3RvUHJvcF0gPSBFcnJvcltwcm90b1Byb3BdO1xuXHQgICAgICBjbGFzc0xpc3RQcm90by5pdGVtID0gZnVuY3Rpb24gKGkpIHtcblx0ICAgICAgICByZXR1cm4gdGhpc1tpXSB8fCBudWxsO1xuXHQgICAgICB9O1xuXHQgICAgICBjbGFzc0xpc3RQcm90by5jb250YWlucyA9IGZ1bmN0aW9uICh0b2tlbikge1xuXHQgICAgICAgIHRva2VuICs9IFwiXCI7XG5cdCAgICAgICAgcmV0dXJuIGNoZWNrVG9rZW5BbmRHZXRJbmRleCh0aGlzLCB0b2tlbikgIT09IC0xO1xuXHQgICAgICB9O1xuXHQgICAgICBjbGFzc0xpc3RQcm90by5hZGQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgdmFyIHRva2VucyA9IGFyZ3VtZW50cyxcblx0ICAgICAgICAgICAgaSA9IDAsXG5cdCAgICAgICAgICAgIGwgPSB0b2tlbnMubGVuZ3RoLFxuXHQgICAgICAgICAgICB0b2tlbixcblx0ICAgICAgICAgICAgdXBkYXRlZCA9IGZhbHNlO1xuXHQgICAgICAgIGRvIHtcblx0ICAgICAgICAgIHRva2VuID0gdG9rZW5zW2ldICsgXCJcIjtcblx0ICAgICAgICAgIGlmIChjaGVja1Rva2VuQW5kR2V0SW5kZXgodGhpcywgdG9rZW4pID09PSAtMSkge1xuXHQgICAgICAgICAgICB0aGlzLnB1c2godG9rZW4pO1xuXHQgICAgICAgICAgICB1cGRhdGVkID0gdHJ1ZTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9IHdoaWxlICgrK2kgPCBsKTtcblx0XG5cdCAgICAgICAgaWYgKHVwZGF0ZWQpIHtcblx0ICAgICAgICAgIHRoaXMuX3VwZGF0ZUNsYXNzTmFtZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfTtcblx0ICAgICAgY2xhc3NMaXN0UHJvdG8ucmVtb3ZlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciB0b2tlbnMgPSBhcmd1bWVudHMsXG5cdCAgICAgICAgICAgIGkgPSAwLFxuXHQgICAgICAgICAgICBsID0gdG9rZW5zLmxlbmd0aCxcblx0ICAgICAgICAgICAgdG9rZW4sXG5cdCAgICAgICAgICAgIHVwZGF0ZWQgPSBmYWxzZSxcblx0ICAgICAgICAgICAgaW5kZXg7XG5cdCAgICAgICAgZG8ge1xuXHQgICAgICAgICAgdG9rZW4gPSB0b2tlbnNbaV0gKyBcIlwiO1xuXHQgICAgICAgICAgaW5kZXggPSBjaGVja1Rva2VuQW5kR2V0SW5kZXgodGhpcywgdG9rZW4pO1xuXHQgICAgICAgICAgd2hpbGUgKGluZGV4ICE9PSAtMSkge1xuXHQgICAgICAgICAgICB0aGlzLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgICAgICAgIHVwZGF0ZWQgPSB0cnVlO1xuXHQgICAgICAgICAgICBpbmRleCA9IGNoZWNrVG9rZW5BbmRHZXRJbmRleCh0aGlzLCB0b2tlbik7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSB3aGlsZSAoKytpIDwgbCk7XG5cdFxuXHQgICAgICAgIGlmICh1cGRhdGVkKSB7XG5cdCAgICAgICAgICB0aGlzLl91cGRhdGVDbGFzc05hbWUoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH07XG5cdCAgICAgIGNsYXNzTGlzdFByb3RvLnRvZ2dsZSA9IGZ1bmN0aW9uICh0b2tlbiwgZm9yY2UpIHtcblx0ICAgICAgICB0b2tlbiArPSBcIlwiO1xuXHRcblx0ICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5jb250YWlucyh0b2tlbiksXG5cdCAgICAgICAgICAgIG1ldGhvZCA9IHJlc3VsdCA/IGZvcmNlICE9PSB0cnVlICYmIFwicmVtb3ZlXCIgOiBmb3JjZSAhPT0gZmFsc2UgJiYgXCJhZGRcIjtcblx0XG5cdCAgICAgICAgaWYgKG1ldGhvZCkge1xuXHQgICAgICAgICAgdGhpc1ttZXRob2RdKHRva2VuKTtcblx0ICAgICAgICB9XG5cdFxuXHQgICAgICAgIGlmIChmb3JjZSA9PT0gdHJ1ZSB8fCBmb3JjZSA9PT0gZmFsc2UpIHtcblx0ICAgICAgICAgIHJldHVybiBmb3JjZTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgcmV0dXJuICFyZXN1bHQ7XG5cdCAgICAgICAgfVxuXHQgICAgICB9O1xuXHQgICAgICBjbGFzc0xpc3RQcm90by50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5qb2luKFwiIFwiKTtcblx0ICAgICAgfTtcblx0XG5cdCAgICAgIGlmIChvYmpDdHIuZGVmaW5lUHJvcGVydHkpIHtcblx0ICAgICAgICB2YXIgY2xhc3NMaXN0UHJvcERlc2MgPSB7XG5cdCAgICAgICAgICBnZXQ6IGNsYXNzTGlzdEdldHRlcixcblx0ICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG5cdCAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICBvYmpDdHIuZGVmaW5lUHJvcGVydHkoZWxlbUN0clByb3RvLCBjbGFzc0xpc3RQcm9wLCBjbGFzc0xpc3RQcm9wRGVzYyk7XG5cdCAgICAgICAgfSBjYXRjaCAoZXgpIHtcblx0ICAgICAgICAgIC8vIElFIDggZG9lc24ndCBzdXBwb3J0IGVudW1lcmFibGU6dHJ1ZVxuXHQgICAgICAgICAgaWYgKGV4Lm51bWJlciA9PT0gLTB4N0ZGNUVDNTQpIHtcblx0ICAgICAgICAgICAgY2xhc3NMaXN0UHJvcERlc2MuZW51bWVyYWJsZSA9IGZhbHNlO1xuXHQgICAgICAgICAgICBvYmpDdHIuZGVmaW5lUHJvcGVydHkoZWxlbUN0clByb3RvLCBjbGFzc0xpc3RQcm9wLCBjbGFzc0xpc3RQcm9wRGVzYyk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2UgaWYgKG9iakN0cltwcm90b1Byb3BdLl9fZGVmaW5lR2V0dGVyX18pIHtcblx0ICAgICAgICBlbGVtQ3RyUHJvdG8uX19kZWZpbmVHZXR0ZXJfXyhjbGFzc0xpc3RQcm9wLCBjbGFzc0xpc3RHZXR0ZXIpO1xuXHQgICAgICB9XG5cdCAgICB9KShzZWxmKTtcblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gVGhlcmUgaXMgZnVsbCBvciBwYXJ0aWFsIG5hdGl2ZSBjbGFzc0xpc3Qgc3VwcG9ydCwgc28ganVzdCBjaGVjayBpZiB3ZSBuZWVkXG5cdCAgICAvLyB0byBub3JtYWxpemUgdGhlIGFkZC9yZW1vdmUgYW5kIHRvZ2dsZSBBUElzLlxuXHRcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgIFwidXNlIHN0cmljdFwiO1xuXHRcblx0ICAgICAgdmFyIHRlc3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIl9cIik7XG5cdFxuXHQgICAgICB0ZXN0RWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiYzFcIiwgXCJjMlwiKTtcblx0XG5cdCAgICAgIC8vIFBvbHlmaWxsIGZvciBJRSAxMC8xMSBhbmQgRmlyZWZveCA8MjYsIHdoZXJlIGNsYXNzTGlzdC5hZGQgYW5kXG5cdCAgICAgIC8vIGNsYXNzTGlzdC5yZW1vdmUgZXhpc3QgYnV0IHN1cHBvcnQgb25seSBvbmUgYXJndW1lbnQgYXQgYSB0aW1lLlxuXHQgICAgICBpZiAoIXRlc3RFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhcImMyXCIpKSB7XG5cdCAgICAgICAgdmFyIGNyZWF0ZU1ldGhvZCA9IGZ1bmN0aW9uIGNyZWF0ZU1ldGhvZChtZXRob2QpIHtcblx0ICAgICAgICAgIHZhciBvcmlnaW5hbCA9IERPTVRva2VuTGlzdC5wcm90b3R5cGVbbWV0aG9kXTtcblx0XG5cdCAgICAgICAgICBET01Ub2tlbkxpc3QucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbiAodG9rZW4pIHtcblx0ICAgICAgICAgICAgdmFyIGksXG5cdCAgICAgICAgICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXHRcblx0ICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgdG9rZW4gPSBhcmd1bWVudHNbaV07XG5cdCAgICAgICAgICAgICAgb3JpZ2luYWwuY2FsbCh0aGlzLCB0b2tlbik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH07XG5cdCAgICAgICAgfTtcblx0ICAgICAgICBjcmVhdGVNZXRob2QoJ2FkZCcpO1xuXHQgICAgICAgIGNyZWF0ZU1ldGhvZCgncmVtb3ZlJyk7XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIHRlc3RFbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoXCJjM1wiLCBmYWxzZSk7XG5cdFxuXHQgICAgICAvLyBQb2x5ZmlsbCBmb3IgSUUgMTAgYW5kIEZpcmVmb3ggPDI0LCB3aGVyZSBjbGFzc0xpc3QudG9nZ2xlIGRvZXMgbm90XG5cdCAgICAgIC8vIHN1cHBvcnQgdGhlIHNlY29uZCBhcmd1bWVudC5cblx0ICAgICAgaWYgKHRlc3RFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhcImMzXCIpKSB7XG5cdCAgICAgICAgdmFyIF90b2dnbGUgPSBET01Ub2tlbkxpc3QucHJvdG90eXBlLnRvZ2dsZTtcblx0XG5cdCAgICAgICAgRE9NVG9rZW5MaXN0LnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAodG9rZW4sIGZvcmNlKSB7XG5cdCAgICAgICAgICBpZiAoMSBpbiBhcmd1bWVudHMgJiYgIXRoaXMuY29udGFpbnModG9rZW4pID09PSAhZm9yY2UpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGZvcmNlO1xuXHQgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgcmV0dXJuIF90b2dnbGUuY2FsbCh0aGlzLCB0b2tlbik7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgICAgfVxuXHRcblx0ICAgICAgdGVzdEVsZW1lbnQgPSBudWxsO1xuXHQgICAgfSkoKTtcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDY1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0ZXhwb3J0cy5nZXRKU09OID0gZ2V0SlNPTjtcblx0ZXhwb3J0cy5nZXRTY3JvbGxCYXJXaWR0aCA9IGdldFNjcm9sbEJhcldpZHRoO1xuXHRleHBvcnRzLnRyYW5zbGF0aW9ucyA9IHRyYW5zbGF0aW9ucztcblx0ZXhwb3J0cy5kZWxheWVyID0gZGVsYXllcjtcblx0ZXhwb3J0cy5WdWVGaXhlciA9IFZ1ZUZpeGVyO1xuXHQvLyBjb2VyY2UgY29udmVydCBzb20gdHlwZXMgb2YgZGF0YSBpbnRvIGFub3RoZXIgdHlwZVxuXHR2YXIgY29lcmNlID0gZXhwb3J0cy5jb2VyY2UgPSB7XG5cdCAgLy8gQ29udmVydCBhIHN0cmluZyB0byBib29sZWFtLiBPdGhlcndpc2UsIHJldHVybiB0aGUgdmFsdWUgd2l0aG91dCBtb2RpZmljYXRpb24sIHNvIGlmIGlzIG5vdCBib29sZWFuLCBWdWUgdGhyb3cgYSB3YXJuaW5nLlxuXHQgIGJvb2xlYW46IGZ1bmN0aW9uIGJvb2xlYW4odmFsKSB7XG5cdCAgICByZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgPyB2YWwgPT09ICcnIHx8IHZhbCA9PT0gJ3RydWUnID8gdHJ1ZSA6IHZhbCA9PT0gJ2ZhbHNlJyB8fCB2YWwgPT09ICdudWxsJyB8fCB2YWwgPT09ICd1bmRlZmluZWQnID8gZmFsc2UgOiB2YWwgOiB2YWw7XG5cdCAgfSxcblx0ICAvLyBBdHRlbXB0IHRvIGNvbnZlcnQgYSBzdHJpbmcgdmFsdWUgdG8gYSBOdW1iZXIuIE90aGVyd2lzZSwgcmV0dXJuIDAuXG5cdCAgbnVtYmVyOiBmdW5jdGlvbiBudW1iZXIodmFsKSB7XG5cdCAgICB2YXIgYWx0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBudWxsO1xuXHQgICAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInID8gdmFsIDogdmFsID09PSB1bmRlZmluZWQgfHwgdmFsID09PSBudWxsIHx8IGlzTmFOKE51bWJlcih2YWwpKSA/IGFsdCA6IE51bWJlcih2YWwpO1xuXHQgIH0sXG5cdCAgLy8gQXR0ZW1wdCB0byBjb252ZXJ0IHRvIHN0cmluZyBhbnkgdmFsdWUsIGV4Y2VwdCBmb3IgbnVsbCBvciB1bmRlZmluZWQuXG5cdCAgc3RyaW5nOiBmdW5jdGlvbiBzdHJpbmcodmFsKSB7XG5cdCAgICByZXR1cm4gdmFsID09PSB1bmRlZmluZWQgfHwgdmFsID09PSBudWxsID8gJycgOiB2YWwgKyAnJztcblx0ICB9LFxuXHQgIC8vIFBhdHRlcm4gYWNjZXB0IFJlZ0V4cCwgZnVuY3Rpb24sIG9yIHN0cmluZyAoY29udmVydGVkIHRvIFJlZ0V4cCkuIE90aGVyd2lzZSByZXR1cm4gbnVsbC5cblx0ICBwYXR0ZXJuOiBmdW5jdGlvbiBwYXR0ZXJuKHZhbCkge1xuXHQgICAgcmV0dXJuIHZhbCBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IHZhbCBpbnN0YW5jZW9mIFJlZ0V4cCA/IHZhbCA6IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnID8gbmV3IFJlZ0V4cCh2YWwpIDogbnVsbDtcblx0ICB9XG5cdH07XG5cdFxuXHRmdW5jdGlvbiBnZXRKU09OKHVybCkge1xuXHQgIHZhciByZXF1ZXN0ID0gbmV3IHdpbmRvdy5YTUxIdHRwUmVxdWVzdCgpO1xuXHQgIHZhciBkYXRhID0ge307XG5cdCAgLy8gcCAoLXNpbXVsYXRlZC0gcHJvbWlzZSlcblx0ICB2YXIgcCA9IHtcblx0ICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4oZm4xLCBmbjIpIHtcblx0ICAgICAgcmV0dXJuIHAuZG9uZShmbjEpLmZhaWwoZm4yKTtcblx0ICAgIH0sXG5cdCAgICBjYXRjaDogZnVuY3Rpb24gX2NhdGNoKGZuKSB7XG5cdCAgICAgIHJldHVybiBwLmZhaWwoZm4pO1xuXHQgICAgfSxcblx0ICAgIGFsd2F5czogZnVuY3Rpb24gYWx3YXlzKGZuKSB7XG5cdCAgICAgIHJldHVybiBwLmRvbmUoZm4pLmZhaWwoZm4pO1xuXHQgICAgfVxuXHQgIH07XG5cdCAgWydkb25lJywgJ2ZhaWwnXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG5cdCAgICBkYXRhW25hbWVdID0gW107XG5cdCAgICBwW25hbWVdID0gZnVuY3Rpb24gKGZuKSB7XG5cdCAgICAgIGlmIChmbiBpbnN0YW5jZW9mIEZ1bmN0aW9uKSBkYXRhW25hbWVdLnB1c2goZm4pO1xuXHQgICAgICByZXR1cm4gcDtcblx0ICAgIH07XG5cdCAgfSk7XG5cdCAgcC5kb25lKEpTT04ucGFyc2UpO1xuXHQgIHJlcXVlc3Qub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuXHQgICAgaWYgKHJlcXVlc3QucmVhZHlTdGF0ZSA9PT0gNCkge1xuXHQgICAgICB2YXIgcmVzcG9uc2U7XG5cdCAgICAgIHZhciBpO1xuXHQgICAgICB2YXIgdmFsdWU7XG5cdFxuXHQgICAgICAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBlID0geyBzdGF0dXM6IHJlcXVlc3Quc3RhdHVzIH07XG5cdCAgICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAyMDApIHtcblx0ICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJlc3BvbnNlID0gcmVxdWVzdC5yZXNwb25zZVRleHQ7XG5cdFxuXHQgICAgICAgICAgICBmb3IgKGkgaW4gZGF0YS5kb25lKSB7XG5cdCAgICAgICAgICAgICAgdmFsdWUgPSBkYXRhLmRvbmVbaV0ocmVzcG9uc2UpO1xuXHRcblx0ICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSB2YWx1ZTtcblx0ICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuXHQgICAgICAgICAgICBkYXRhLmZhaWwuZm9yRWFjaChmdW5jdGlvbiAoZmFpbCkge1xuXHQgICAgICAgICAgICAgIHJldHVybiBmYWlsKGVycik7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBkYXRhLmZhaWwuZm9yRWFjaChmdW5jdGlvbiAoZmFpbCkge1xuXHQgICAgICAgICAgICByZXR1cm4gZmFpbChlKTtcblx0ICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSkoKTtcblx0ICAgIH1cblx0ICB9O1xuXHQgIHJlcXVlc3Qub3BlbignR0VUJywgdXJsKTtcblx0ICByZXF1ZXN0LnNldFJlcXVlc3RIZWFkZXIoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cdCAgcmVxdWVzdC5zZW5kKCk7XG5cdCAgcmV0dXJuIHA7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIGdldFNjcm9sbEJhcldpZHRoKCkge1xuXHQgIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsSGVpZ2h0IDw9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpIHtcblx0ICAgIHJldHVybiAwO1xuXHQgIH1cblx0ICB2YXIgaW5uZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJyk7XG5cdCAgaW5uZXIuc3R5bGUud2lkdGggPSAnMTAwJSc7XG5cdCAgaW5uZXIuc3R5bGUuaGVpZ2h0ID0gJzIwMHB4Jztcblx0XG5cdCAgdmFyIG91dGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdCAgb3V0ZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuXHQgIG91dGVyLnN0eWxlLnRvcCA9ICcwcHgnO1xuXHQgIG91dGVyLnN0eWxlLmxlZnQgPSAnMHB4Jztcblx0ICBvdXRlci5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG5cdCAgb3V0ZXIuc3R5bGUud2lkdGggPSAnMjAwcHgnO1xuXHQgIG91dGVyLnN0eWxlLmhlaWdodCA9ICcxNTBweCc7XG5cdCAgb3V0ZXIuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcblx0ICBvdXRlci5hcHBlbmRDaGlsZChpbm5lcik7XG5cdFxuXHQgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQob3V0ZXIpO1xuXHQgIHZhciB3MSA9IGlubmVyLm9mZnNldFdpZHRoO1xuXHQgIG91dGVyLnN0eWxlLm92ZXJmbG93ID0gJ3Njcm9sbCc7XG5cdCAgdmFyIHcyID0gaW5uZXIub2Zmc2V0V2lkdGg7XG5cdCAgaWYgKHcxID09PSB3MikgdzIgPSBvdXRlci5jbGllbnRXaWR0aDtcblx0XG5cdCAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChvdXRlcik7XG5cdFxuXHQgIHJldHVybiB3MSAtIHcyO1xuXHR9XG5cdFxuXHQvLyByZXR1cm4gYWxsIHRoZSB0cmFuc2xhdGlvbnMgb3IgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgKGVuZ2xpc2gpXG5cdGZ1bmN0aW9uIHRyYW5zbGF0aW9ucygpIHtcblx0ICB2YXIgbGFuZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJ2VuJztcblx0XG5cdCAgdmFyIHRleHQgPSB7XG5cdCAgICBkYXlzT2ZXZWVrOiBbJ1N1JywgJ01vJywgJ1R1JywgJ1dlJywgJ1RoJywgJ0ZyJywgJ1NhJ10sXG5cdCAgICBsaW1pdDogJ0xpbWl0IHJlYWNoZWQgKHt7bGltaXR9fSBpdGVtcyBtYXgpLicsXG5cdCAgICBsb2FkaW5nOiAnTG9hZGluZy4uLicsXG5cdCAgICBtaW5MZW5ndGg6ICdNaW4uIExlbmd0aCcsXG5cdCAgICBtb250aHM6IFsnSmFudWFyeScsICdGZWJydWFyeScsICdNYXJjaCcsICdBcHJpbCcsICdNYXknLCAnSnVuZScsICdKdWx5JywgJ0F1Z3VzdCcsICdTZXB0ZW1iZXInLCAnT2N0b2JlcicsICdOb3ZlbWJlcicsICdEZWNlbWJlciddLFxuXHQgICAgbm90U2VsZWN0ZWQ6ICdOb3RoaW5nIFNlbGVjdGVkJyxcblx0ICAgIHJlcXVpcmVkOiAnUmVxdWlyZWQnLFxuXHQgICAgc2VhcmNoOiAnU2VhcmNoJyxcblx0ICAgIHNlbGVjdGVkOiAne3tjb3VudH19IHNlbGVjdGVkJ1xuXHQgIH07XG5cdCAgcmV0dXJuIHdpbmRvdy5WdWVTdHJhcExhbmcgPyB3aW5kb3cuVnVlU3RyYXBMYW5nKGxhbmcpIDogdGV4dDtcblx0fVxuXHRcblx0Ly8gZGVsYXllcjogc2V0IGEgZnVuY3Rpb24gdGhhdCBleGVjdXRlIGFmdGVyIGEgZGVsYXlcblx0Ly8gQHBhcmFtcyAoZnVuY3Rpb24sIGRlbGF5X3Byb3Agb3IgdmFsdWUsIGRlZmF1bHRfdmFsdWUpXG5cdGZ1bmN0aW9uIGRlbGF5ZXIoZm4sIHZhclRpbWVyKSB7XG5cdCAgdmFyIGlmTmFOID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAxMDA7XG5cdFxuXHQgIGZ1bmN0aW9uIHRvSW50KGVsKSB7XG5cdCAgICByZXR1cm4gKC9eWzAtOV0rJC8udGVzdChlbCkgPyBOdW1iZXIoZWwpIHx8IDEgOiBudWxsXG5cdCAgICApO1xuXHQgIH1cblx0ICB2YXIgdGltZXJJZDtcblx0ICByZXR1cm4gZnVuY3Rpb24gKCkge1xuXHQgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuXHQgICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuXHQgICAgfVxuXHRcblx0ICAgIGlmICh0aW1lcklkKSBjbGVhclRpbWVvdXQodGltZXJJZCk7XG5cdCAgICB0aW1lcklkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgIGZuLmFwcGx5KF90aGlzLCBhcmdzKTtcblx0ICAgIH0sIHRvSW50KHZhclRpbWVyKSB8fCB0b0ludCh0aGlzW3ZhclRpbWVyXSkgfHwgaWZOYU4pO1xuXHQgIH07XG5cdH1cblx0XG5cdC8vIEZpeCBhIHZ1ZSBpbnN0YW5jZSBMaWZlY3ljbGUgdG8gdnVlIDEvMiAoanVzdCB0aGUgYmFzaWMgZWxlbWVudHMsIGlzIG5vdCBhIHJlYWwgcGFyc2VyLCBzbyB0aGlzIHdvcmsgb25seSBpZiB5b3VyIGNvZGUgaXMgY29tcGF0aWJsZSB3aXRoIGJvdGgpXG5cdC8vIChXYWl0aW5nIGZvciB0ZXN0aW5nKVxuXHRmdW5jdGlvbiBWdWVGaXhlcih2dWUpIHtcblx0ICB2YXIgdnVlMiA9ICF3aW5kb3cuVnVlIHx8ICF3aW5kb3cuVnVlLnBhcnRpYWw7XG5cdCAgdmFyIG1peGluID0ge1xuXHQgICAgY29tcHV0ZWQ6IHtcblx0ICAgICAgdnVlMjogZnVuY3Rpb24gdnVlMigpIHtcblx0ICAgICAgICByZXR1cm4gIXRoaXMuJGRpc3BhdGNoO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfTtcblx0ICBpZiAoIXZ1ZTIpIHtcblx0ICAgIC8vdHJhbnNsYXRlIHZ1ZTIgYXR0cmlidXRlcyB0byB2dWUxXG5cdCAgICBpZiAodnVlLmJlZm9yZUNyZWF0ZSkge1xuXHQgICAgICBtaXhpbi5jcmVhdGUgPSB2dWUuYmVmb3JlQ3JlYXRlO1xuXHQgICAgICBkZWxldGUgdnVlLmJlZm9yZUNyZWF0ZTtcblx0ICAgIH1cblx0ICAgIGlmICh2dWUuYmVmb3JlTW91bnQpIHtcblx0ICAgICAgdnVlLmJlZm9yZUNvbXBpbGUgPSB2dWUuYmVmb3JlTW91bnQ7XG5cdCAgICAgIGRlbGV0ZSB2dWUuYmVmb3JlTW91bnQ7XG5cdCAgICB9XG5cdCAgICBpZiAodnVlLm1vdW50ZWQpIHtcblx0ICAgICAgdnVlLnJlYWR5ID0gdnVlLm1vdW50ZWQ7XG5cdCAgICAgIGRlbGV0ZSB2dWUubW91bnRlZDtcblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgLy90cmFuc2xhdGUgdnVlMSBhdHRyaWJ1dGVzIHRvIHZ1ZTJcblx0ICAgIGlmICh2dWUuYmVmb3JlQ29tcGlsZSkge1xuXHQgICAgICB2dWUuYmVmb3JlTW91bnQgPSB2dWUuYmVmb3JlQ29tcGlsZTtcblx0ICAgICAgZGVsZXRlIHZ1ZS5iZWZvcmVDb21waWxlO1xuXHQgICAgfVxuXHQgICAgaWYgKHZ1ZS5jb21waWxlZCkge1xuXHQgICAgICBtaXhpbi5jb21waWxlZCA9IHZ1ZS5jb21waWxlZDtcblx0ICAgICAgZGVsZXRlIHZ1ZS5jb21waWxlZDtcblx0ICAgIH1cblx0ICAgIGlmICh2dWUucmVhZHkpIHtcblx0ICAgICAgdnVlLm1vdW50ZWQgPSB2dWUucmVhZHk7XG5cdCAgICAgIGRlbGV0ZSB2dWUucmVhZHk7XG5cdCAgICB9XG5cdCAgfVxuXHQgIGlmICghdnVlLm1peGlucykge1xuXHQgICAgdnVlLm1peGlucyA9IFtdO1xuXHQgIH1cblx0ICB2dWUubWl4aW5zLnVuc2hpZnQobWl4aW4pO1xuXHQgIHJldHVybiB2dWU7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDY2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24ocHJvY2Vzcykgeyd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHQvKipcclxuXHQgKiBDbGljayBvdXRzaWRlIGRpcmVjdGl2ZVxyXG5cdCAqL1xuXHR2YXIgYmluZGVkID0gW107XG5cdFxuXHRmdW5jdGlvbiBoYW5kbGVyKGUpIHtcblx0ICBiaW5kZWQuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcblx0ICAgIGlmICghZWwubm9kZS5jb250YWlucyhlLnRhcmdldCkpIGVsLmNhbGxiYWNrKGUpO1xuXHQgIH0pO1xuXHR9XG5cdFxuXHRmdW5jdGlvbiBhZGRMaXN0ZW5lcihub2RlLCBjYWxsYmFjaykge1xuXHQgIGlmICghYmluZGVkLmxlbmd0aCkgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVyLCBmYWxzZSk7XG5cdCAgYmluZGVkLnB1c2goeyBub2RlOiBub2RlLCBjYWxsYmFjazogY2FsbGJhY2sgfSk7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKG5vZGUsIGNhbGxiYWNrKSB7XG5cdCAgYmluZGVkID0gYmluZGVkLmZpbHRlcihmdW5jdGlvbiAoZWwpIHtcblx0ICAgIHJldHVybiBlbC5ub2RlICE9PSBub2RlID8gdHJ1ZSA6ICFjYWxsYmFjayA/IGZhbHNlIDogZWwuY2FsbGJhY2sgIT09IGNhbGxiYWNrO1xuXHQgIH0pO1xuXHQgIGlmICghYmluZGVkLmxlbmd0aCkgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVyLCBmYWxzZSk7XG5cdH1cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBiaW5kOiBmdW5jdGlvbiBiaW5kKGVsLCBiaW5kaW5nKSB7XG5cdCAgICByZW1vdmVMaXN0ZW5lcihlbCwgYmluZGluZy52YWx1ZSk7XG5cdCAgICBpZiAodHlwZW9mIGJpbmRpbmcudmFsdWUgIT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcblx0ICAgICAgICBWdWUudXRpbC53YXJuKCdDbGlja091dHNpZGUgb25seSB3b3JrIHdpdGggYSBmdW5jdGlvbiwgcmVjZWl2ZWQ6IHYtJyArIGJpbmRpbmcubmFtZSArICc9XCInICsgYmluZGluZy5leHByZXNzaW9uICsgJ1wiJyk7XG5cdCAgICAgIH1cblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIGFkZExpc3RlbmVyKGVsLCBiaW5kaW5nLnZhbHVlKTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKGVsLCBiaW5kaW5nKSB7XG5cdCAgICBpZiAoYmluZGluZy52YWx1ZSAhPT0gYmluZGluZy5vbGRWYWx1ZSkge1xuXHQgICAgICByZW1vdmVMaXN0ZW5lcihlbCwgYmluZGluZy5vbGRWYWx1ZSk7XG5cdCAgICAgIGFkZExpc3RlbmVyKGVsLCBiaW5kaW5nLnZhbHVlKTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIHVuYmluZDogZnVuY3Rpb24gdW5iaW5kKGVsLCBiaW5kaW5nKSB7XG5cdCAgICByZW1vdmVMaXN0ZW5lcihlbCwgYmluZGluZy52YWx1ZSk7XG5cdCAgfVxuXHR9O1xuXHQvKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwoZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyg2NykpKVxuXG4vKioqLyB9LFxuLyogNjcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdC8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXHR2YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cdFxuXHQvLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcblx0Ly8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG5cdC8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcblx0Ly8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblx0XG5cdHZhciBjYWNoZWRTZXRUaW1lb3V0O1xuXHR2YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXHRcblx0ZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xuXHR9XG5cdGZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuXHQgICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcblx0fVxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG5cdCAgICAgICAgfVxuXHQgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuXHQgICAgfVxuXHQgICAgdHJ5IHtcblx0ICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcblx0ICAgICAgICB9XG5cdCAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcblx0ICAgIH1cblx0fSAoKSlcblx0ZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcblx0ICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG5cdCAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG5cdCAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcblx0ICAgIH1cblx0ICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG5cdCAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcblx0ICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcblx0ICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuXHQgICAgfVxuXHQgICAgdHJ5IHtcblx0ICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG5cdCAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcblx0ICAgIH0gY2F0Y2goZSl7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG5cdCAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcblx0ICAgICAgICB9IGNhdGNoKGUpe1xuXHQgICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuXHQgICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHRcblx0XG5cdH1cblx0ZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuXHQgICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG5cdCAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG5cdCAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuXHQgICAgfVxuXHQgICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuXHQgICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG5cdCAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuXHQgICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcblx0ICAgIH1cblx0ICAgIHRyeSB7XG5cdCAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuXHQgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcblx0ICAgIH0gY2F0Y2ggKGUpe1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcblx0ICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG5cdCAgICAgICAgfSBjYXRjaCAoZSl7XG5cdCAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuXHQgICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG5cdCAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0XG5cdFxuXHRcblx0fVxuXHR2YXIgcXVldWUgPSBbXTtcblx0dmFyIGRyYWluaW5nID0gZmFsc2U7XG5cdHZhciBjdXJyZW50UXVldWU7XG5cdHZhciBxdWV1ZUluZGV4ID0gLTE7XG5cdFxuXHRmdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG5cdCAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICB9XG5cdCAgICBkcmFpbmluZyA9IGZhbHNlO1xuXHQgICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcblx0ICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG5cdCAgICB9XG5cdCAgICBpZiAocXVldWUubGVuZ3RoKSB7XG5cdCAgICAgICAgZHJhaW5RdWV1ZSgpO1xuXHQgICAgfVxuXHR9XG5cdFxuXHRmdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuXHQgICAgaWYgKGRyYWluaW5nKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgfVxuXHQgICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG5cdCAgICBkcmFpbmluZyA9IHRydWU7XG5cdFxuXHQgICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcblx0ICAgIHdoaWxlKGxlbikge1xuXHQgICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuXHQgICAgICAgIHF1ZXVlID0gW107XG5cdCAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuXHQgICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG5cdCAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuXHQgICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcblx0ICAgIH1cblx0ICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG5cdCAgICBkcmFpbmluZyA9IGZhbHNlO1xuXHQgICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXHR9XG5cdFxuXHRwcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuXHQgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuXHQgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcblx0ICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG5cdCAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcblx0ICAgIH1cblx0fTtcblx0XG5cdC8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcblx0ZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG5cdCAgICB0aGlzLmZ1biA9IGZ1bjtcblx0ICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcblx0fVxuXHRJdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG5cdCAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcblx0fTtcblx0cHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcblx0cHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcblx0cHJvY2Vzcy5lbnYgPSB7fTtcblx0cHJvY2Vzcy5hcmd2ID0gW107XG5cdHByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xuXHRwcm9jZXNzLnZlcnNpb25zID0ge307XG5cdFxuXHRmdW5jdGlvbiBub29wKCkge31cblx0XG5cdHByb2Nlc3Mub24gPSBub29wO1xuXHRwcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcblx0cHJvY2Vzcy5vbmNlID0gbm9vcDtcblx0cHJvY2Vzcy5vZmYgPSBub29wO1xuXHRwcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcblx0cHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xuXHRwcm9jZXNzLmVtaXQgPSBub29wO1xuXHRcblx0cHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcblx0fTtcblx0XG5cdHByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5cdHByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xuXHR9O1xuXHRwcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cbi8qKiovIH0sXG4vKiA2OCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0LyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovKGZ1bmN0aW9uKHByb2Nlc3MpIHsndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0LyoqXHJcblx0ICogQ2xpY2sgb3V0c2lkZSBkaXJlY3RpdmVcclxuXHQgKi9cblx0dmFyIEhBTkRMRVIgPSAnX3Z1ZV9zY3JvbGxfaGFuZGxlcic7XG5cdHZhciBldmVudHMgPSBbJ3Jlc2l6ZScsICdzY3JvbGwnXTtcblx0XG5cdGZ1bmN0aW9uIGJpbmQoZWwsIGJpbmRpbmcpIHtcblx0ICB1bmJpbmQoZWwpO1xuXHRcblx0ICB2YXIgY2FsbGJhY2sgPSBiaW5kaW5nLnZhbHVlO1xuXHQgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcblx0ICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG5cdCAgICAgIFZ1ZS51dGlsLndhcm4oJ0NsaWNrT3V0c2lkZSBvbmx5IHdvcmsgd2l0aCBhIGZ1bmN0aW9uIHZhbHVlLCByZWNlaXZlZDogdi0nICsgYmluZGluZy5uYW1lICsgJz1cIicgKyBiaW5kaW5nLmV4cHJlc3Npb24gKyAnXCInKTtcblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgZWxbSEFORExFUl0gPSBmdW5jdGlvbiAoZSkge1xuXHQgICAgICBjYWxsYmFjayhlKTtcblx0ICAgIH07XG5cdCAgICBldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuXHQgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihlLCBlbFtIQU5ETEVSXSwgZmFsc2UpO1xuXHQgICAgfSk7XG5cdCAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZWxbSEFORExFUl0sIGZhbHNlKTtcblx0ICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICBlbFtIQU5ETEVSXSgpO1xuXHQgICAgfSwgMCk7XG5cdCAgfVxuXHR9XG5cdFxuXHRmdW5jdGlvbiB1bmJpbmQoZWwpIHtcblx0ICBldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuXHQgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoZSwgZWxbSEFORExFUl0sIGZhbHNlKTtcblx0ICB9KTtcblx0ICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdsb2FkJywgZWxbSEFORExFUl0sIGZhbHNlKTtcblx0ICBkZWxldGUgZWxbSEFORExFUl07XG5cdH1cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBiaW5kOiBiaW5kLFxuXHQgIHVuYmluZDogdW5iaW5kLFxuXHQgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKGVsLCBiaW5kaW5nKSB7XG5cdCAgICBpZiAoYmluZGluZy52YWx1ZSAhPT0gYmluZGluZy5vbGRWYWx1ZSkgYmluZChlbCwgYmluZGluZyk7XG5cdCAgfVxuXHR9O1xuXHQvKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwoZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyg2NykpKVxuXG4vKioqLyB9LFxuLyogNjkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oNzApXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oNzEpXG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuXHRpZiAoXG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcblx0KSB7XG5cdGlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxuXHR9XG5cdGlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcblx0ICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xuXHR9XG5cdF9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIkM6XFxcXGxhcmFnb25cXFxcd3d3XFxcXHZ1ZS1zdHJhcFxcXFxzcmNcXFxcQWNjb3JkaW9uLnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0XG5cdC8qIGhvdCByZWxvYWQgKi9cblx0aWYgKGZhbHNlKSB7KGZ1bmN0aW9uICgpIHtcblx0ICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuXHQgIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuXHQgIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi1kNGI3NWE5MlwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfSBlbHNlIHtcblx0ICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtZDRiNzVhOTJcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH1cblx0fSkoKX1cblx0aWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBBY2NvcmRpb24udnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogNzAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdFxuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIHByb3BzOiB7XG5cdCAgICB0eXBlOiB7XG5cdCAgICAgIHR5cGU6IFN0cmluZyxcblx0ICAgICAgZGVmYXVsdDogbnVsbFxuXHQgICAgfSxcblx0ICAgIG9uZUF0QXRpbWU6IHtcblx0ICAgICAgdHlwZTogQm9vbGVhbixcblx0ICAgICAgZGVmYXVsdDogZmFsc2Vcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIG9wZW5DaGlsZDogZnVuY3Rpb24gb3BlbkNoaWxkKGNoaWxkKSB7XG5cdCAgICAgIGlmICh0aGlzLm9uZUF0QXRpbWUpIHtcblx0ICAgICAgICB0aGlzLiRjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG5cdCAgICAgICAgICBpZiAoY2hpbGQgIT09IGl0ZW0pIHtcblx0ICAgICAgICAgICAgaXRlbS5vcGVuID0gZmFsc2U7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LFxuXHQgIGNyZWF0ZWQ6IGZ1bmN0aW9uIGNyZWF0ZWQoKSB7XG5cdCAgICB0aGlzLl9pc0FjY29yZGlvbiA9IHRydWU7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogNzEgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwicGFuZWwtZ3JvdXBcIlxuXHQgIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMilcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtZDRiNzVhOTJcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiA3MiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3Mylcblx0XG5cdC8qIHRlbXBsYXRlICovXG5cdHZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3NClcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxBZmZpeC52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNWViZGRlYmZcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTVlYmRkZWJmXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gQWZmaXgudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogNzMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcblx0dmFyIF9TY3JvbGwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDY4KTtcblx0XG5cdHZhciBfU2Nyb2xsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1Njcm9sbCk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIGRpcmVjdGl2ZXM6IHtcblx0ICAgIFNjcm9sbDogX1Njcm9sbDIuZGVmYXVsdFxuXHQgIH0sXG5cdCAgcHJvcHM6IHtcblx0ICAgIG9mZnNldDoge1xuXHQgICAgICB0eXBlOiBOdW1iZXIsXG5cdCAgICAgIGRlZmF1bHQ6IDBcblx0ICAgIH1cblx0ICB9LFxuXHQgIGRhdGE6IGZ1bmN0aW9uIGRhdGEoKSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBhZmZpeGVkOiBmYWxzZVxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICBjb21wdXRlZDoge1xuXHQgICAgdG9wOiBmdW5jdGlvbiB0b3AoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLm9mZnNldCA+IDAgPyB0aGlzLm9mZnNldCArICdweCcgOiBudWxsO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbWV0aG9kczoge1xuXHQgICAgLy8gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYW50LWRlc2lnbi9hbnQtZGVzaWduL2Jsb2IvbWFzdGVyL2NvbXBvbmVudHMvYWZmaXgvaW5kZXguanN4I0wyMFxuXHQgICAgY2hlY2tTY3JvbGw6IGZ1bmN0aW9uIGNoZWNrU2Nyb2xsKCkge1xuXHQgICAgICAvLyBpZiBpcyBoaWRkZW4gZG9uJ3QgY2FsY3VsYXRlIGFueXRoaW5nXG5cdCAgICAgIGlmICghKHRoaXMuJGVsLm9mZnNldFdpZHRoIHx8IHRoaXMuJGVsLm9mZnNldEhlaWdodCB8fCB0aGlzLiRlbC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCkpIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICAgIH1cblx0ICAgICAgLy8gZ2V0IHdpbmRvdyBzY3JvbGwgYW5kIGVsZW1lbnQgcG9zaXRpb24gdG8gZGV0ZWN0IGlmIGhhdmUgdG8gYmUgbm9ybWFsIG9yIGFmZml4ZWRcblx0ICAgICAgdmFyIHNjcm9sbCA9IHt9O1xuXHQgICAgICB2YXIgZWxlbWVudCA9IHt9O1xuXHQgICAgICB2YXIgcmVjdCA9IHRoaXMuJGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHQgICAgICB2YXIgYm9keSA9IGRvY3VtZW50LmJvZHk7XG5cdCAgICAgIHZhciBfYXJyID0gWydUb3AnLCAnTGVmdCddO1xuXHQgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgX2Fyci5sZW5ndGg7IF9pKyspIHtcblx0ICAgICAgICB2YXIgdHlwZSA9IF9hcnJbX2ldO1xuXHQgICAgICAgIHZhciB0ID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuXHQgICAgICAgIHZhciByZXQgPSB3aW5kb3dbJ3BhZ2UnICsgKHR5cGUgPT09ICdUb3AnID8gJ1knIDogJ1gnKSArICdPZmZzZXQnXTtcblx0ICAgICAgICB2YXIgbWV0aG9kID0gJ3Njcm9sbCcgKyB0eXBlO1xuXHQgICAgICAgIGlmICh0eXBlb2YgcmV0ICE9PSAnbnVtYmVyJykge1xuXHQgICAgICAgICAgLy8gaWU2LDcsOCBzdGFuZGFyZCBtb2RlXG5cdCAgICAgICAgICByZXQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbbWV0aG9kXTtcblx0ICAgICAgICAgIGlmICh0eXBlb2YgcmV0ICE9PSAnbnVtYmVyJykge1xuXHQgICAgICAgICAgICAvLyBxdWlya3MgbW9kZVxuXHQgICAgICAgICAgICByZXQgPSBkb2N1bWVudC5ib2R5W21ldGhvZF07XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHNjcm9sbFt0XSA9IHJldDtcblx0ICAgICAgICBlbGVtZW50W3RdID0gc2Nyb2xsW3RdICsgcmVjdFt0XSAtICh0aGlzLiRlbFsnY2xpZW50JyArIHR5cGVdIHx8IGJvZHlbJ2NsaWVudCcgKyB0eXBlXSB8fCAwKTtcblx0ICAgICAgfVxuXHQgICAgICB2YXIgZml4ID0gc2Nyb2xsLnRvcCA+IGVsZW1lbnQudG9wIC0gdGhpcy5vZmZzZXQ7XG5cdCAgICAgIGlmICh0aGlzLmFmZml4ZWQgIT09IGZpeCkge1xuXHQgICAgICAgIHRoaXMuYWZmaXhlZCA9IGZpeDtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH1cblx0fTsgLy9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblxuLyoqKi8gfSxcbi8qIDc0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImhpZGRlbi1wcmludCBoaWRkZW4teHMgaGlkZGVuLXNtXCJcblx0ICB9LCBbX3ZtLl9jKCduYXYnLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcInNjcm9sbFwiLFxuXHQgICAgICByYXdOYW1lOiBcInYtc2Nyb2xsXCIsXG5cdCAgICAgIHZhbHVlOiAoX3ZtLmNoZWNrU2Nyb2xsKSxcblx0ICAgICAgZXhwcmVzc2lvbjogXCJjaGVja1Njcm9sbFwiXG5cdCAgICB9XSxcblx0ICAgIHN0YXRpY0NsYXNzOiBcImJzLWRvY3Mtc2lkZWJhclwiLFxuXHQgICAgY2xhc3M6IHtcblx0ICAgICAgYWZmaXg6IF92bS5hZmZpeGVkXG5cdCAgICB9LFxuXHQgICAgc3R5bGU6ICh7XG5cdCAgICAgIG1hcmdpblRvcDogX3ZtLnRvcFxuXHQgICAgfSlcblx0ICB9LCBbX3ZtLl90KFwiZGVmYXVsdFwiKV0sIDIpXSlcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtNWViZGRlYmZcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiA3NSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzdHlsZXMgKi9cblx0X193ZWJwYWNrX3JlcXVpcmVfXyg3Nilcblx0XG5cdC8qIHNjcmlwdCAqL1xuXHRfX3Z1ZV9leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDgwKVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDgxKVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXEFsZXJ0LnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0XG5cdC8qIGhvdCByZWxvYWQgKi9cblx0aWYgKGZhbHNlKSB7KGZ1bmN0aW9uICgpIHtcblx0ICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuXHQgIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuXHQgIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi1hZjdjMWY2YVwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfSBlbHNlIHtcblx0ICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtYWY3YzFmNmFcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH1cblx0fSkoKX1cblx0aWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBBbGVydC52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IF9fdnVlX2V4cG9ydHNfX1xuXG5cbi8qKiovIH0sXG4vKiA3NiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblx0XG5cdC8vIGxvYWQgdGhlIHN0eWxlc1xuXHR2YXIgY29udGVudCA9IF9fd2VicGFja19yZXF1aXJlX18oNzcpO1xuXHRpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcblx0Ly8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxuXHR2YXIgdXBkYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OSkoY29udGVudCwge30pO1xuXHRpZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcblx0Ly8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuXHRpZihmYWxzZSkge1xuXHRcdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWFmN2MxZjZhIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9BbGVydC52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWFmN2MxZjZhIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9BbGVydC52dWVcIik7XG5cdFx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xuXHR9XG5cbi8qKiovIH0sXG4vKiA3NyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0ZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OCkoKTtcblx0Ly8gaW1wb3J0c1xuXHRcblx0XG5cdC8vIG1vZHVsZVxuXHRleHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4uZmFkZS1lbnRlci1hY3RpdmUsXFxyXFxuLmZhZGUtbGVhdmUtYWN0aXZlIHtcXHJcXG4gIHRyYW5zaXRpb246IG9wYWNpdHkgLjNzIGVhc2U7XFxufVxcbi5mYWRlLWVudGVyLFxcclxcbi5mYWRlLWxlYXZlLWFjdGl2ZSB7XFxyXFxuICBoZWlnaHQ6IDA7XFxyXFxuICBvcGFjaXR5OiAwO1xcbn1cXG4uYWxlcnQudG9wIHtcXHJcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXHJcXG4gIHRvcDogMzBweDtcXHJcXG4gIG1hcmdpbjogMCBhdXRvO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIHJpZ2h0OiAwO1xcclxcbiAgei1pbmRleDogMTA1MDtcXG59XFxuLmFsZXJ0LnRvcC1yaWdodCB7XFxyXFxuICBwb3NpdGlvbjogZml4ZWQ7XFxyXFxuICB0b3A6IDMwcHg7XFxyXFxuICByaWdodDogNTBweDtcXHJcXG4gIHotaW5kZXg6IDEwNTA7XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvQWxlcnQudnVlPzcxYTkxYzFhXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFvREE7O0VBRUEsNkJBQUE7Q0FDQTtBQUNBOztFQUVBLFVBQUE7RUFDQSxXQUFBO0NBQ0E7QUFDQTtFQUNBLGdCQUFBO0VBQ0EsVUFBQTtFQUNBLGVBQUE7RUFDQSxRQUFBO0VBQ0EsU0FBQTtFQUNBLGNBQUE7Q0FDQTtBQUNBO0VBQ0EsZ0JBQUE7RUFDQSxVQUFBO0VBQ0EsWUFBQTtFQUNBLGNBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiQWxlcnQudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDx0cmFuc2l0aW9uIG5hbWU9XFxcImZhZGVcXFwiPlxcclxcbiAgICA8ZGl2IHYtc2hvdz1cXFwidmFsXFxcIiA6Y2xhc3M9XFxcIlsnYWxlcnQnLCAnYWxlcnQtJyt0eXBlLCBwbGFjZW1lbnRdXFxcIiA6c3R5bGU9XFxcInt3aWR0aDp3aWR0aH1cXFwiIHJvbGU9XFxcImFsZXJ0XFxcIj5cXHJcXG4gICAgICA8YnV0dG9uIHYtc2hvdz1cXFwiZGlzbWlzc2FibGVcXFwiIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImNsb3NlXFxcIiBAY2xpY2s9XFxcInZhbCA9IGZhbHNlXFxcIj5cXHJcXG4gICAgICAgIDxzcGFuPiZ0aW1lczs8L3NwYW4+XFxyXFxuICAgICAgPC9idXR0b24+XFxyXFxuICAgICAgPHNsb3Q+PC9zbG90PlxcclxcbiAgICA8L2Rpdj5cXHJcXG4gIDwvdHJhbnNpdGlvbj5cXHJcXG48L3RlbXBsYXRlPlxcclxcblxcclxcbjxzY3JpcHQ+XFxyXFxuaW1wb3J0IHtjb2VyY2UsIGRlbGF5ZXJ9IGZyb20gJy4vdXRpbHMvdXRpbHMuanMnXFxyXFxuXFxyXFxudmFyIERVUkFUSU9OID0gMFxcclxcbmV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gIHByb3BzOiB7XFxyXFxuICAgIGRpc21pc3NhYmxlOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBkdXJhdGlvbjoge2RlZmF1bHQ6IERVUkFUSU9OfSxcXHJcXG4gICAgcGxhY2VtZW50OiB7dHlwZTogU3RyaW5nfSxcXHJcXG4gICAgdHlwZToge3R5cGU6IFN0cmluZ30sXFxyXFxuICAgIHZhbHVlOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogdHJ1ZSB9LFxcclxcbiAgICB3aWR0aDoge3R5cGU6IFN0cmluZ31cXHJcXG4gIH0sXFxyXFxuICBkYXRhICgpIHtcXHJcXG4gICAgcmV0dXJuIHtcXHJcXG4gICAgICB2YWw6IHRoaXMudmFsdWVcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGNvbXB1dGVkOiB7XFxyXFxuICAgIGR1cmF0aW9uTnVtICgpIHsgcmV0dXJuIGNvZXJjZS5udW1iZXIodGhpcy5kdXJhdGlvbiwgRFVSQVRJT04pIH1cXHJcXG4gIH0sXFxyXFxuICB3YXRjaDoge1xcclxcbiAgICB2YWwgKHZhbCkge1xcclxcbiAgICAgIGlmICh2YWwgJiYgdGhpcy5kdXJhdGlvbk51bSA+IDApIHsgdGhpcy5fZGVsYXlDbG9zZSgpIH1cXHJcXG4gICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbClcXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsdWUgKHZhbCkge1xcclxcbiAgICAgIGlmICh0aGlzLnZhbCAhPT0gdmFsKSB7XFxyXFxuICAgICAgICB0aGlzLnZhbCA9IHZhbFxcclxcbiAgICAgIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGNyZWF0ZWQgKCkge1xcclxcbiAgICB0aGlzLl9kZWxheUNsb3NlID0gZGVsYXllcihmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgdGhpcy52YWwgPSBmYWxzZVxcclxcbiAgICB9LCAnZHVyYXRpb25OdW0nKVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGU+XFxyXFxuLmZhZGUtZW50ZXItYWN0aXZlLFxcclxcbi5mYWRlLWxlYXZlLWFjdGl2ZSB7XFxyXFxuICB0cmFuc2l0aW9uOiBvcGFjaXR5IC4zcyBlYXNlO1xcclxcbn1cXHJcXG4uZmFkZS1lbnRlcixcXHJcXG4uZmFkZS1sZWF2ZS1hY3RpdmUge1xcclxcbiAgaGVpZ2h0OiAwO1xcclxcbiAgb3BhY2l0eTogMDtcXHJcXG59XFxyXFxuLmFsZXJ0LnRvcCB7XFxyXFxuICBwb3NpdGlvbjogZml4ZWQ7XFxyXFxuICB0b3A6IDMwcHg7XFxyXFxuICBtYXJnaW46IDAgYXV0bztcXHJcXG4gIGxlZnQ6IDA7XFxyXFxuICByaWdodDogMDtcXHJcXG4gIHotaW5kZXg6IDEwNTA7XFxyXFxufVxcclxcbi5hbGVydC50b3AtcmlnaHQge1xcclxcbiAgcG9zaXRpb246IGZpeGVkO1xcclxcbiAgdG9wOiAzMHB4O1xcclxcbiAgcmlnaHQ6IDUwcHg7XFxyXFxuICB6LWluZGV4OiAxMDUwO1xcclxcbn1cXHJcXG48L3N0eWxlPlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogNzggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdC8qXHJcblx0XHRNSVQgTGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxyXG5cdFx0QXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxyXG5cdCovXHJcblx0Ly8gY3NzIGJhc2UgY29kZSwgaW5qZWN0ZWQgYnkgdGhlIGNzcy1sb2FkZXJcclxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGxpc3QgPSBbXTtcclxuXHRcclxuXHRcdC8vIHJldHVybiB0aGUgbGlzdCBvZiBtb2R1bGVzIGFzIGNzcyBzdHJpbmdcclxuXHRcdGxpc3QudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcclxuXHRcdFx0dmFyIHJlc3VsdCA9IFtdO1xyXG5cdFx0XHRmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRcdHZhciBpdGVtID0gdGhpc1tpXTtcclxuXHRcdFx0XHRpZihpdGVtWzJdKSB7XHJcblx0XHRcdFx0XHRyZXN1bHQucHVzaChcIkBtZWRpYSBcIiArIGl0ZW1bMl0gKyBcIntcIiArIGl0ZW1bMV0gKyBcIn1cIik7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHJlc3VsdC5wdXNoKGl0ZW1bMV0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gcmVzdWx0LmpvaW4oXCJcIik7XHJcblx0XHR9O1xyXG5cdFxyXG5cdFx0Ly8gaW1wb3J0IGEgbGlzdCBvZiBtb2R1bGVzIGludG8gdGhlIGxpc3RcclxuXHRcdGxpc3QuaSA9IGZ1bmN0aW9uKG1vZHVsZXMsIG1lZGlhUXVlcnkpIHtcclxuXHRcdFx0aWYodHlwZW9mIG1vZHVsZXMgPT09IFwic3RyaW5nXCIpXHJcblx0XHRcdFx0bW9kdWxlcyA9IFtbbnVsbCwgbW9kdWxlcywgXCJcIl1dO1xyXG5cdFx0XHR2YXIgYWxyZWFkeUltcG9ydGVkTW9kdWxlcyA9IHt9O1xyXG5cdFx0XHRmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRcdHZhciBpZCA9IHRoaXNbaV1bMF07XHJcblx0XHRcdFx0aWYodHlwZW9mIGlkID09PSBcIm51bWJlclwiKVxyXG5cdFx0XHRcdFx0YWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpZF0gPSB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHRcdGZvcihpID0gMDsgaSA8IG1vZHVsZXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0XHR2YXIgaXRlbSA9IG1vZHVsZXNbaV07XHJcblx0XHRcdFx0Ly8gc2tpcCBhbHJlYWR5IGltcG9ydGVkIG1vZHVsZVxyXG5cdFx0XHRcdC8vIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgbm90IDEwMCUgcGVyZmVjdCBmb3Igd2VpcmQgbWVkaWEgcXVlcnkgY29tYmluYXRpb25zXHJcblx0XHRcdFx0Ly8gIHdoZW4gYSBtb2R1bGUgaXMgaW1wb3J0ZWQgbXVsdGlwbGUgdGltZXMgd2l0aCBkaWZmZXJlbnQgbWVkaWEgcXVlcmllcy5cclxuXHRcdFx0XHQvLyAgSSBob3BlIHRoaXMgd2lsbCBuZXZlciBvY2N1ciAoSGV5IHRoaXMgd2F5IHdlIGhhdmUgc21hbGxlciBidW5kbGVzKVxyXG5cdFx0XHRcdGlmKHR5cGVvZiBpdGVtWzBdICE9PSBcIm51bWJlclwiIHx8ICFhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XHJcblx0XHRcdFx0XHRpZihtZWRpYVF1ZXJ5ICYmICFpdGVtWzJdKSB7XHJcblx0XHRcdFx0XHRcdGl0ZW1bMl0gPSBtZWRpYVF1ZXJ5O1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmKG1lZGlhUXVlcnkpIHtcclxuXHRcdFx0XHRcdFx0aXRlbVsyXSA9IFwiKFwiICsgaXRlbVsyXSArIFwiKSBhbmQgKFwiICsgbWVkaWFRdWVyeSArIFwiKVwiO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0bGlzdC5wdXNoKGl0ZW0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHRcdHJldHVybiBsaXN0O1xyXG5cdH07XHJcblxuXG4vKioqLyB9LFxuLyogNzkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8qXG5cdFx0TUlUIExpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcblx0XHRBdXRob3IgVG9iaWFzIEtvcHBlcnMgQHNva3JhXG5cdCovXG5cdHZhciBzdHlsZXNJbkRvbSA9IHt9LFxuXHRcdG1lbW9pemUgPSBmdW5jdGlvbihmbikge1xuXHRcdFx0dmFyIG1lbW87XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAodHlwZW9mIG1lbW8gPT09IFwidW5kZWZpbmVkXCIpIG1lbW8gPSBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHRcdFx0XHRyZXR1cm4gbWVtbztcblx0XHRcdH07XG5cdFx0fSxcblx0XHRpc09sZElFID0gbWVtb2l6ZShmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiAvbXNpZSBbNi05XVxcYi8udGVzdCh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpKTtcblx0XHR9KSxcblx0XHRnZXRIZWFkRWxlbWVudCA9IG1lbW9pemUoZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIGRvY3VtZW50LmhlYWQgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdO1xuXHRcdH0pLFxuXHRcdHNpbmdsZXRvbkVsZW1lbnQgPSBudWxsLFxuXHRcdHNpbmdsZXRvbkNvdW50ZXIgPSAwLFxuXHRcdHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wID0gW107XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGxpc3QsIG9wdGlvbnMpIHtcblx0XHRpZihmYWxzZSkge1xuXHRcdFx0aWYodHlwZW9mIGRvY3VtZW50ICE9PSBcIm9iamVjdFwiKSB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgc3R5bGUtbG9hZGVyIGNhbm5vdCBiZSB1c2VkIGluIGEgbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRcIik7XG5cdFx0fVxuXHRcblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblx0XHQvLyBGb3JjZSBzaW5nbGUtdGFnIHNvbHV0aW9uIG9uIElFNi05LCB3aGljaCBoYXMgYSBoYXJkIGxpbWl0IG9uIHRoZSAjIG9mIDxzdHlsZT5cblx0XHQvLyB0YWdzIGl0IHdpbGwgYWxsb3cgb24gYSBwYWdlXG5cdFx0aWYgKHR5cGVvZiBvcHRpb25zLnNpbmdsZXRvbiA9PT0gXCJ1bmRlZmluZWRcIikgb3B0aW9ucy5zaW5nbGV0b24gPSBpc09sZElFKCk7XG5cdFxuXHRcdC8vIEJ5IGRlZmF1bHQsIGFkZCA8c3R5bGU+IHRhZ3MgdG8gdGhlIGJvdHRvbSBvZiA8aGVhZD4uXG5cdFx0aWYgKHR5cGVvZiBvcHRpb25zLmluc2VydEF0ID09PSBcInVuZGVmaW5lZFwiKSBvcHRpb25zLmluc2VydEF0ID0gXCJib3R0b21cIjtcblx0XG5cdFx0dmFyIHN0eWxlcyA9IGxpc3RUb1N0eWxlcyhsaXN0KTtcblx0XHRhZGRTdHlsZXNUb0RvbShzdHlsZXMsIG9wdGlvbnMpO1xuXHRcblx0XHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlKG5ld0xpc3QpIHtcblx0XHRcdHZhciBtYXlSZW1vdmUgPSBbXTtcblx0XHRcdGZvcih2YXIgaSA9IDA7IGkgPCBzdHlsZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0dmFyIGl0ZW0gPSBzdHlsZXNbaV07XG5cdFx0XHRcdHZhciBkb21TdHlsZSA9IHN0eWxlc0luRG9tW2l0ZW0uaWRdO1xuXHRcdFx0XHRkb21TdHlsZS5yZWZzLS07XG5cdFx0XHRcdG1heVJlbW92ZS5wdXNoKGRvbVN0eWxlKTtcblx0XHRcdH1cblx0XHRcdGlmKG5ld0xpc3QpIHtcblx0XHRcdFx0dmFyIG5ld1N0eWxlcyA9IGxpc3RUb1N0eWxlcyhuZXdMaXN0KTtcblx0XHRcdFx0YWRkU3R5bGVzVG9Eb20obmV3U3R5bGVzLCBvcHRpb25zKTtcblx0XHRcdH1cblx0XHRcdGZvcih2YXIgaSA9IDA7IGkgPCBtYXlSZW1vdmUubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0dmFyIGRvbVN0eWxlID0gbWF5UmVtb3ZlW2ldO1xuXHRcdFx0XHRpZihkb21TdHlsZS5yZWZzID09PSAwKSB7XG5cdFx0XHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IGRvbVN0eWxlLnBhcnRzLmxlbmd0aDsgaisrKVxuXHRcdFx0XHRcdFx0ZG9tU3R5bGUucGFydHNbal0oKTtcblx0XHRcdFx0XHRkZWxldGUgc3R5bGVzSW5Eb21bZG9tU3R5bGUuaWRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXHRcblx0ZnVuY3Rpb24gYWRkU3R5bGVzVG9Eb20oc3R5bGVzLCBvcHRpb25zKSB7XG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGl0ZW0gPSBzdHlsZXNbaV07XG5cdFx0XHR2YXIgZG9tU3R5bGUgPSBzdHlsZXNJbkRvbVtpdGVtLmlkXTtcblx0XHRcdGlmKGRvbVN0eWxlKSB7XG5cdFx0XHRcdGRvbVN0eWxlLnJlZnMrKztcblx0XHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IGRvbVN0eWxlLnBhcnRzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdFx0ZG9tU3R5bGUucGFydHNbal0oaXRlbS5wYXJ0c1tqXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Zm9yKDsgaiA8IGl0ZW0ucGFydHMubGVuZ3RoOyBqKyspIHtcblx0XHRcdFx0XHRkb21TdHlsZS5wYXJ0cy5wdXNoKGFkZFN0eWxlKGl0ZW0ucGFydHNbal0sIG9wdGlvbnMpKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFyIHBhcnRzID0gW107XG5cdFx0XHRcdGZvcih2YXIgaiA9IDA7IGogPCBpdGVtLnBhcnRzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdFx0cGFydHMucHVzaChhZGRTdHlsZShpdGVtLnBhcnRzW2pdLCBvcHRpb25zKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3R5bGVzSW5Eb21baXRlbS5pZF0gPSB7aWQ6IGl0ZW0uaWQsIHJlZnM6IDEsIHBhcnRzOiBwYXJ0c307XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdFxuXHRmdW5jdGlvbiBsaXN0VG9TdHlsZXMobGlzdCkge1xuXHRcdHZhciBzdHlsZXMgPSBbXTtcblx0XHR2YXIgbmV3U3R5bGVzID0ge307XG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBpdGVtID0gbGlzdFtpXTtcblx0XHRcdHZhciBpZCA9IGl0ZW1bMF07XG5cdFx0XHR2YXIgY3NzID0gaXRlbVsxXTtcblx0XHRcdHZhciBtZWRpYSA9IGl0ZW1bMl07XG5cdFx0XHR2YXIgc291cmNlTWFwID0gaXRlbVszXTtcblx0XHRcdHZhciBwYXJ0ID0ge2NzczogY3NzLCBtZWRpYTogbWVkaWEsIHNvdXJjZU1hcDogc291cmNlTWFwfTtcblx0XHRcdGlmKCFuZXdTdHlsZXNbaWRdKVxuXHRcdFx0XHRzdHlsZXMucHVzaChuZXdTdHlsZXNbaWRdID0ge2lkOiBpZCwgcGFydHM6IFtwYXJ0XX0pO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRuZXdTdHlsZXNbaWRdLnBhcnRzLnB1c2gocGFydCk7XG5cdFx0fVxuXHRcdHJldHVybiBzdHlsZXM7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zLCBzdHlsZUVsZW1lbnQpIHtcblx0XHR2YXIgaGVhZCA9IGdldEhlYWRFbGVtZW50KCk7XG5cdFx0dmFyIGxhc3RTdHlsZUVsZW1lbnRJbnNlcnRlZEF0VG9wID0gc3R5bGVFbGVtZW50c0luc2VydGVkQXRUb3Bbc3R5bGVFbGVtZW50c0luc2VydGVkQXRUb3AubGVuZ3RoIC0gMV07XG5cdFx0aWYgKG9wdGlvbnMuaW5zZXJ0QXQgPT09IFwidG9wXCIpIHtcblx0XHRcdGlmKCFsYXN0U3R5bGVFbGVtZW50SW5zZXJ0ZWRBdFRvcCkge1xuXHRcdFx0XHRoZWFkLmluc2VydEJlZm9yZShzdHlsZUVsZW1lbnQsIGhlYWQuZmlyc3RDaGlsZCk7XG5cdFx0XHR9IGVsc2UgaWYobGFzdFN0eWxlRWxlbWVudEluc2VydGVkQXRUb3AubmV4dFNpYmxpbmcpIHtcblx0XHRcdFx0aGVhZC5pbnNlcnRCZWZvcmUoc3R5bGVFbGVtZW50LCBsYXN0U3R5bGVFbGVtZW50SW5zZXJ0ZWRBdFRvcC5uZXh0U2libGluZyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRoZWFkLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG5cdFx0XHR9XG5cdFx0XHRzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcC5wdXNoKHN0eWxlRWxlbWVudCk7XG5cdFx0fSBlbHNlIGlmIChvcHRpb25zLmluc2VydEF0ID09PSBcImJvdHRvbVwiKSB7XG5cdFx0XHRoZWFkLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdmFsdWUgZm9yIHBhcmFtZXRlciAnaW5zZXJ0QXQnLiBNdXN0IGJlICd0b3AnIG9yICdib3R0b20nLlwiKTtcblx0XHR9XG5cdH1cblx0XG5cdGZ1bmN0aW9uIHJlbW92ZVN0eWxlRWxlbWVudChzdHlsZUVsZW1lbnQpIHtcblx0XHRzdHlsZUVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzdHlsZUVsZW1lbnQpO1xuXHRcdHZhciBpZHggPSBzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcC5pbmRleE9mKHN0eWxlRWxlbWVudCk7XG5cdFx0aWYoaWR4ID49IDApIHtcblx0XHRcdHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wLnNwbGljZShpZHgsIDEpO1xuXHRcdH1cblx0fVxuXHRcblx0ZnVuY3Rpb24gY3JlYXRlU3R5bGVFbGVtZW50KG9wdGlvbnMpIHtcblx0XHR2YXIgc3R5bGVFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuXHRcdHN0eWxlRWxlbWVudC50eXBlID0gXCJ0ZXh0L2Nzc1wiO1xuXHRcdGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zLCBzdHlsZUVsZW1lbnQpO1xuXHRcdHJldHVybiBzdHlsZUVsZW1lbnQ7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIGFkZFN0eWxlKG9iaiwgb3B0aW9ucykge1xuXHRcdHZhciBzdHlsZUVsZW1lbnQsIHVwZGF0ZSwgcmVtb3ZlO1xuXHRcblx0XHRpZiAob3B0aW9ucy5zaW5nbGV0b24pIHtcblx0XHRcdHZhciBzdHlsZUluZGV4ID0gc2luZ2xldG9uQ291bnRlcisrO1xuXHRcdFx0c3R5bGVFbGVtZW50ID0gc2luZ2xldG9uRWxlbWVudCB8fCAoc2luZ2xldG9uRWxlbWVudCA9IGNyZWF0ZVN0eWxlRWxlbWVudChvcHRpb25zKSk7XG5cdFx0XHR1cGRhdGUgPSBhcHBseVRvU2luZ2xldG9uVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50LCBzdHlsZUluZGV4LCBmYWxzZSk7XG5cdFx0XHRyZW1vdmUgPSBhcHBseVRvU2luZ2xldG9uVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50LCBzdHlsZUluZGV4LCB0cnVlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0c3R5bGVFbGVtZW50ID0gY3JlYXRlU3R5bGVFbGVtZW50KG9wdGlvbnMpO1xuXHRcdFx0dXBkYXRlID0gYXBwbHlUb1RhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCk7XG5cdFx0XHRyZW1vdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmVtb3ZlU3R5bGVFbGVtZW50KHN0eWxlRWxlbWVudCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0XG5cdFx0dXBkYXRlKG9iaik7XG5cdFxuXHRcdHJldHVybiBmdW5jdGlvbiB1cGRhdGVTdHlsZShuZXdPYmopIHtcblx0XHRcdGlmKG5ld09iaikge1xuXHRcdFx0XHRpZihuZXdPYmouY3NzID09PSBvYmouY3NzICYmIG5ld09iai5tZWRpYSA9PT0gb2JqLm1lZGlhICYmIG5ld09iai5zb3VyY2VNYXAgPT09IG9iai5zb3VyY2VNYXApXG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR1cGRhdGUob2JqID0gbmV3T2JqKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJlbW92ZSgpO1xuXHRcdFx0fVxuXHRcdH07XG5cdH1cblx0XG5cdHZhciByZXBsYWNlVGV4dCA9IChmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHRleHRTdG9yZSA9IFtdO1xuXHRcblx0XHRyZXR1cm4gZnVuY3Rpb24gKGluZGV4LCByZXBsYWNlbWVudCkge1xuXHRcdFx0dGV4dFN0b3JlW2luZGV4XSA9IHJlcGxhY2VtZW50O1xuXHRcdFx0cmV0dXJuIHRleHRTdG9yZS5maWx0ZXIoQm9vbGVhbikuam9pbignXFxuJyk7XG5cdFx0fTtcblx0fSkoKTtcblx0XG5cdGZ1bmN0aW9uIGFwcGx5VG9TaW5nbGV0b25UYWcoc3R5bGVFbGVtZW50LCBpbmRleCwgcmVtb3ZlLCBvYmopIHtcblx0XHR2YXIgY3NzID0gcmVtb3ZlID8gXCJcIiA6IG9iai5jc3M7XG5cdFxuXHRcdGlmIChzdHlsZUVsZW1lbnQuc3R5bGVTaGVldCkge1xuXHRcdFx0c3R5bGVFbGVtZW50LnN0eWxlU2hlZXQuY3NzVGV4dCA9IHJlcGxhY2VUZXh0KGluZGV4LCBjc3MpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR2YXIgY3NzTm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcyk7XG5cdFx0XHR2YXIgY2hpbGROb2RlcyA9IHN0eWxlRWxlbWVudC5jaGlsZE5vZGVzO1xuXHRcdFx0aWYgKGNoaWxkTm9kZXNbaW5kZXhdKSBzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoY2hpbGROb2Rlc1tpbmRleF0pO1xuXHRcdFx0aWYgKGNoaWxkTm9kZXMubGVuZ3RoKSB7XG5cdFx0XHRcdHN0eWxlRWxlbWVudC5pbnNlcnRCZWZvcmUoY3NzTm9kZSwgY2hpbGROb2Rlc1tpbmRleF0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGNzc05vZGUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRcblx0ZnVuY3Rpb24gYXBwbHlUb1RhZyhzdHlsZUVsZW1lbnQsIG9iaikge1xuXHRcdHZhciBjc3MgPSBvYmouY3NzO1xuXHRcdHZhciBtZWRpYSA9IG9iai5tZWRpYTtcblx0XHR2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcblx0XG5cdFx0aWYgKG1lZGlhKSB7XG5cdFx0XHRzdHlsZUVsZW1lbnQuc2V0QXR0cmlidXRlKFwibWVkaWFcIiwgbWVkaWEpO1xuXHRcdH1cblx0XG5cdFx0aWYgKHNvdXJjZU1hcCkge1xuXHRcdFx0Ly8gaHR0cHM6Ly9kZXZlbG9wZXIuY2hyb21lLmNvbS9kZXZ0b29scy9kb2NzL2phdmFzY3JpcHQtZGVidWdnaW5nXG5cdFx0XHQvLyB0aGlzIG1ha2VzIHNvdXJjZSBtYXBzIGluc2lkZSBzdHlsZSB0YWdzIHdvcmsgcHJvcGVybHkgaW4gQ2hyb21lXG5cdFx0XHRjc3MgKz0gJ1xcbi8qIyBzb3VyY2VVUkw9JyArIHNvdXJjZU1hcC5zb3VyY2VzWzBdICsgJyAqLyc7XG5cdFx0XHQvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yNjYwMzg3NVxuXHRcdFx0Y3NzICs9IFwiXFxuLyojIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxcIiArIGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSkgKyBcIiAqL1wiO1xuXHRcdH1cblx0XG5cdFx0aWYgKHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0KSB7XG5cdFx0XHRzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR3aGlsZShzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCkge1xuXHRcdFx0XHRzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50LmZpcnN0Q2hpbGQpO1xuXHRcdFx0fVxuXHRcdFx0c3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xuXHRcdH1cblx0fVxuXG5cbi8qKiovIH0sXG4vKiA4MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdFxuXHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2NSk7XG5cdFxuXHR2YXIgRFVSQVRJT04gPSAwOyAvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIHByb3BzOiB7XG5cdCAgICBkaXNtaXNzYWJsZTogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgZHVyYXRpb246IHsgZGVmYXVsdDogRFVSQVRJT04gfSxcblx0ICAgIHBsYWNlbWVudDogeyB0eXBlOiBTdHJpbmcgfSxcblx0ICAgIHR5cGU6IHsgdHlwZTogU3RyaW5nIH0sXG5cdCAgICB2YWx1ZTogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiB0cnVlIH0sXG5cdCAgICB3aWR0aDogeyB0eXBlOiBTdHJpbmcgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIHZhbDogdGhpcy52YWx1ZVxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICBjb21wdXRlZDoge1xuXHQgICAgZHVyYXRpb25OdW06IGZ1bmN0aW9uIGR1cmF0aW9uTnVtKCkge1xuXHQgICAgICByZXR1cm4gX3V0aWxzLmNvZXJjZS5udW1iZXIodGhpcy5kdXJhdGlvbiwgRFVSQVRJT04pO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgd2F0Y2g6IHtcblx0ICAgIHZhbDogZnVuY3Rpb24gdmFsKF92YWwpIHtcblx0ICAgICAgaWYgKF92YWwgJiYgdGhpcy5kdXJhdGlvbk51bSA+IDApIHtcblx0ICAgICAgICB0aGlzLl9kZWxheUNsb3NlKCk7XG5cdCAgICAgIH1cblx0ICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCBfdmFsKTtcblx0ICAgIH0sXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUodmFsKSB7XG5cdCAgICAgIGlmICh0aGlzLnZhbCAhPT0gdmFsKSB7XG5cdCAgICAgICAgdGhpcy52YWwgPSB2YWw7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LFxuXHQgIGNyZWF0ZWQ6IGZ1bmN0aW9uIGNyZWF0ZWQoKSB7XG5cdCAgICB0aGlzLl9kZWxheUNsb3NlID0gKDAsIF91dGlscy5kZWxheWVyKShmdW5jdGlvbiAoKSB7XG5cdCAgICAgIHRoaXMudmFsID0gZmFsc2U7XG5cdCAgICB9LCAnZHVyYXRpb25OdW0nKTtcblx0ICB9XG5cdH07XG5cbi8qKiovIH0sXG4vKiA4MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDtcblx0ICByZXR1cm4gX3ZtLl9jKCd0cmFuc2l0aW9uJywge1xuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJuYW1lXCI6IFwiZmFkZVwiXG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJzaG93XCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1zaG93XCIsXG5cdCAgICAgIHZhbHVlOiAoX3ZtLnZhbCksXG5cdCAgICAgIGV4cHJlc3Npb246IFwidmFsXCJcblx0ICAgIH1dLFxuXHQgICAgY2xhc3M6IFsnYWxlcnQnLCAnYWxlcnQtJyArIF92bS50eXBlLCBfdm0ucGxhY2VtZW50XSxcblx0ICAgIHN0eWxlOiAoe1xuXHQgICAgICB3aWR0aDogX3ZtLndpZHRoXG5cdCAgICB9KSxcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwicm9sZVwiOiBcImFsZXJ0XCJcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdidXR0b24nLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcInNob3dcIixcblx0ICAgICAgcmF3TmFtZTogXCJ2LXNob3dcIixcblx0ICAgICAgdmFsdWU6IChfdm0uZGlzbWlzc2FibGUpLFxuXHQgICAgICBleHByZXNzaW9uOiBcImRpc21pc3NhYmxlXCJcblx0ICAgIH1dLFxuXHQgICAgc3RhdGljQ2xhc3M6IFwiY2xvc2VcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcImJ1dHRvblwiXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBfdm0udmFsID0gZmFsc2Vcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0sIFtfdm0uX2MoJ3NwYW4nLCBbX3ZtLl92KFwiw5dcIildKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMildKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1hZjdjMWY2YVwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDgyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgX192dWVfZXhwb3J0c19fLCBfX3Z1ZV9vcHRpb25zX19cblx0dmFyIF9fdnVlX3N0eWxlc19fID0ge31cblx0XG5cdC8qIHN0eWxlcyAqL1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDgzKVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oODUpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oODYpXG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuXHRpZiAoXG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcblx0KSB7XG5cdGlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxuXHR9XG5cdGlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcblx0ICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xuXHR9XG5cdF9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIkM6XFxcXGxhcmFnb25cXFxcd3d3XFxcXHZ1ZS1zdHJhcFxcXFxzcmNcXFxcQXNpZGUudnVlXCJcblx0X192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5cdF9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTNhNGJkZTI3XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi0zYTRiZGUyN1wiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIEFzaWRlLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDgzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg4NCk7XG5cdGlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuXHQvLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG5cdHZhciB1cGRhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc5KShjb250ZW50LCB7fSk7XG5cdGlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuXHQvLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5cdGlmKGZhbHNlKSB7XG5cdFx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtM2E0YmRlMjchLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0FzaWRlLnZ1ZVwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtM2E0YmRlMjchLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0FzaWRlLnZ1ZVwiKTtcblx0XHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDg0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc4KSgpO1xuXHQvLyBpbXBvcnRzXG5cdFxuXHRcblx0Ly8gbW9kdWxlXG5cdGV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5hc2lkZS1vcGVuIHtcXHJcXG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjNzO1xcbn1cXG4uYXNpZGUtb3Blbi5oYXMtcHVzaC1yaWdodCB7XFxyXFxuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTMwMHB4KTtcXG59XFxuLmFzaWRlIHtcXHJcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXHJcXG4gIHRvcDogMDtcXHJcXG4gIGJvdHRvbTogMDtcXHJcXG4gIHotaW5kZXg6IDEwNDk7XFxyXFxuICBvdmVyZmxvdzogYXV0bztcXHJcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxufVxcbi5hc2lkZS5sZWZ0IHtcXHJcXG4gIGxlZnQ6IDA7XFxyXFxuICByaWdodDogYXV0bztcXG59XFxuLmFzaWRlLnJpZ2h0IHtcXHJcXG4gIGxlZnQ6IGF1dG87XFxyXFxuICByaWdodDogMDtcXG59XFxuLnNsaWRlbGVmdC1lbnRlciB7XFxyXFxuICB0cmFuc2Zvcm06dHJhbnNsYXRlWCgtMTAwJSk7XFxufVxcbi5zbGlkZWxlZnQtZW50ZXItYWN0aXZlIHtcXHJcXG4gIGFuaW1hdGlvbjpzbGlkZWxlZnQtaW4gLjNzO1xcbn1cXG4uc2xpZGVsZWZ0LWxlYXZlLWFjdGl2ZSB7XFxyXFxuICBhbmltYXRpb246c2xpZGVsZWZ0LW91dCAuM3M7XFxufVxcbkBrZXlmcmFtZXMgc2xpZGVsZWZ0LWluIHtcXG4wJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtMTAwJSk7XFxyXFxuICAgIG9wYWNpdHk6IDA7XFxufVxcbjEwMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XFxyXFxuICAgIG9wYWNpdHk6IDE7XFxufVxcbn1cXG5Aa2V5ZnJhbWVzIHNsaWRlbGVmdC1vdXQge1xcbjAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xcclxcbiAgICBvcGFjaXR5OiAxO1xcbn1cXG4xMDAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC0xMDAlKTtcXHJcXG4gICAgb3BhY2l0eTogMDtcXG59XFxufVxcbi5zbGlkZXJpZ2h0LWVudGVyLWFjdGl2ZSB7XFxyXFxuICBhbmltYXRpb246c2xpZGVyaWdodC1pbiAuM3M7XFxufVxcbi5zbGlkZXJpZ2h0LWxlYXZlLWFjdGl2ZSB7XFxyXFxuICBhbmltYXRpb246c2xpZGVyaWdodC1vdXQgLjNzO1xcbn1cXG5Aa2V5ZnJhbWVzIHNsaWRlcmlnaHQtaW4ge1xcbjAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpO1xcclxcbiAgICBvcGFjaXR5OiAwO1xcbn1cXG4xMDAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xcclxcbiAgICBvcGFjaXR5OiAxO1xcbn1cXG59XFxuQGtleWZyYW1lcyBzbGlkZXJpZ2h0LW91dCB7XFxuMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XFxyXFxuICAgIG9wYWNpdHk6IDE7XFxufVxcbjEwMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSk7XFxyXFxuICAgIG9wYWNpdHk6IDA7XFxufVxcbn1cXG4uYXNpZGU6Zm9jdXMge1xcclxcbiAgICBvdXRsaW5lOiAwO1xcbn1cXG5AbWVkaWEgKG1heC13aWR0aDogOTkxcHgpIHtcXG4uYXNpZGUge1xcclxcbiAgICBtaW4td2lkdGg6IDI0MHB4O1xcbn1cXG59XFxuLmFzaWRlIC5hc2lkZS1kaWFsb2cgLmFzaWRlLWhlYWRlciB7XFxyXFxuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2U1ZTVlNTtcXHJcXG4gIG1pbi1oZWlnaHQ6IDE2LjQzcHg7XFxyXFxuICBwYWRkaW5nOiA2cHggMTVweDtcXHJcXG4gIGJhY2tncm91bmQ6ICMzMzdhYjc7XFxyXFxuICBjb2xvcjogI2ZmZjtcXG59XFxuLmFzaWRlIC5hc2lkZS1kaWFsb2cgLmFzaWRlLWhlYWRlciAuY2xvc2Uge1xcclxcbiAgbWFyZ2luLXJpZ2h0OiAtOHB4O1xcclxcbiAgcGFkZGluZzogNHB4IDhweDtcXHJcXG4gIGNvbG9yOiAjZmZmO1xcclxcbiAgZm9udC1zaXplOiAyNXB4O1xcclxcbiAgb3BhY2l0eTogLjg7XFxufVxcbi5hc2lkZSAuYXNpZGUtZGlhbG9nIC5hc2lkZS1ib2R5IHtcXHJcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gIHBhZGRpbmc6IDE1cHg7XFxufVxcbi5hc2lkZSAuYXNpZGUtZGlhbG9nIC5hc2lkZS1mb290ZXIge1xcclxcbiAgcGFkZGluZzogMTVweDtcXHJcXG4gIHRleHQtYWxpZ246IHJpZ2h0O1xcclxcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNlNWU1ZTU7XFxufVxcbi5hc2lkZSAuYXNpZGUtZGlhbG9nIC5hc2lkZS1mb290ZXIgLmJ0bisuYnRuIHtcXHJcXG4gIG1hcmdpbi1sZWZ0OiA1cHg7XFxyXFxuICBtYXJnaW4tYm90dG9tOiAwO1xcbn1cXG4uYXNpZGUgLmFzaWRlLWRpYWxvZyAuYXNpZGUtZm9vdGVyIC5idG4tZ3JvdXAgLmJ0bisuYnRuIHtcXHJcXG4gIG1hcmdpbi1sZWZ0OiAtMXB4O1xcbn1cXG4uYXNpZGUgLmFzaWRlLWRpYWxvZyAuYXNpZGUtZm9vdGVyIC5idG4tYmxvY2srLmJ0bi1ibG9jayB7XFxyXFxuICBtYXJnaW4tbGVmdDogMDtcXG59XFxuLmFzaWRlLWJhY2tkcm9wIHtcXHJcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXHJcXG4gIHRvcDogMDtcXHJcXG4gIHJpZ2h0OiAwO1xcclxcbiAgYm90dG9tOiAwO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIHotaW5kZXg6IDEwNDA7XFxyXFxuICBvcGFjaXR5OiAwO1xcclxcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSAuM3MgZWFzZTtcXHJcXG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XFxufVxcbi5hc2lkZS1iYWNrZHJvcC5pbiB7XFxyXFxuICBvcGFjaXR5OiAuNTtcXHJcXG4gIGZpbHRlcjogYWxwaGEob3BhY2l0eT01MCk7XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvQXNpZGUudnVlPzU3Mzk2MjFmXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFrRkE7RUFDQSwyQkFBQTtDQUNBO0FBQ0E7RUFDQSw4QkFBQTtDQUNBO0FBQ0E7RUFDQSxnQkFBQTtFQUNBLE9BQUE7RUFDQSxVQUFBO0VBQ0EsY0FBQTtFQUNBLGVBQUE7RUFDQSxpQkFBQTtDQUNBO0FBQ0E7RUFDQSxRQUFBO0VBQ0EsWUFBQTtDQUNBO0FBQ0E7RUFDQSxXQUFBO0VBQ0EsU0FBQTtDQUNBO0FBQ0E7RUFDQSw0QkFBQTtDQUNBO0FBQ0E7RUFDQSwyQkFBQTtDQUNBO0FBQ0E7RUFDQSw0QkFBQTtDQUNBO0FBQ0E7QUFDQTtJQUNBLDZCQUFBO0lBQ0EsV0FBQTtDQUNBO0FBQ0E7SUFDQSx5QkFBQTtJQUNBLFdBQUE7Q0FDQTtDQUNBO0FBQ0E7QUFDQTtJQUNBLHlCQUFBO0lBQ0EsV0FBQTtDQUNBO0FBQ0E7SUFDQSw2QkFBQTtJQUNBLFdBQUE7Q0FDQTtDQUNBO0FBQ0E7RUFDQSw0QkFBQTtDQUNBO0FBQ0E7RUFDQSw2QkFBQTtDQUNBO0FBQ0E7QUFDQTtJQUNBLDRCQUFBO0lBQ0EsV0FBQTtDQUNBO0FBQ0E7SUFDQSx5QkFBQTtJQUNBLFdBQUE7Q0FDQTtDQUNBO0FBQ0E7QUFDQTtJQUNBLHlCQUFBO0lBQ0EsV0FBQTtDQUNBO0FBQ0E7SUFDQSw0QkFBQTtJQUNBLFdBQUE7Q0FDQTtDQUNBO0FBQ0E7SUFDQSxXQUFBO0NBQ0E7QUFDQTtBQUNBO0lBQ0EsaUJBQUE7Q0FDQTtDQUNBO0FBQ0E7RUFDQSxpQ0FBQTtFQUNBLG9CQUFBO0VBQ0Esa0JBQUE7RUFDQSxvQkFBQTtFQUNBLFlBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxpQkFBQTtFQUNBLFlBQUE7RUFDQSxnQkFBQTtFQUNBLFlBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxjQUFBO0NBQ0E7QUFDQTtFQUNBLGNBQUE7RUFDQSxrQkFBQTtFQUNBLDhCQUFBO0NBQ0E7QUFDQTtFQUNBLGlCQUFBO0VBQ0EsaUJBQUE7Q0FDQTtBQUNBO0VBQ0Esa0JBQUE7Q0FDQTtBQUNBO0VBQ0EsZUFBQTtDQUNBO0FBQ0E7RUFDQSxnQkFBQTtFQUNBLE9BQUE7RUFDQSxTQUFBO0VBQ0EsVUFBQTtFQUNBLFFBQUE7RUFDQSxjQUFBO0VBQ0EsV0FBQTtFQUNBLDZCQUFBO0VBQ0EsdUJBQUE7Q0FDQTtBQUNBO0VBQ0EsWUFBQTtFQUNBLDBCQUFBO0NBQ0FcIixcImZpbGVcIjpcIkFzaWRlLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxyXFxuICA8dHJhbnNpdGlvbiA6bmFtZT1cXFwiJ3NsaWRlJyArIHBsYWNlbWVudFxcXCI+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcImFzaWRlXFxcIiB2LWlmPVxcXCJzaG93XFxcIiA6c3R5bGU9XFxcInt3aWR0aDp3aWR0aCsncHgnfVxcXCIgOmNsYXNzPVxcXCJwbGFjZW1lbnRcXFwiPlxcclxcbiAgICAgIDxkaXYgY2xhc3M9XFxcImFzaWRlLWRpYWxvZ1xcXCI+XFxyXFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhc2lkZS1jb250ZW50XFxcIj5cXHJcXG4gICAgICAgICAgPGRpdiBjbGFzcz1cXFwiYXNpZGUtaGVhZGVyXFxcIj5cXHJcXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImNsb3NlXFxcIiBAY2xpY2s9J3RyaWdnZXJfY2xvc2UnPjxzcGFuPiZ0aW1lczs8L3NwYW4+PC9idXR0b24+XFxyXFxuICAgICAgICAgICAgPGg0IGNsYXNzPVxcXCJhc2lkZS10aXRsZVxcXCI+PHNsb3QgbmFtZT1cXFwiaGVhZGVyXFxcIj57eyBoZWFkZXIgfX08L3Nsb3Q+PC9oND5cXHJcXG4gICAgICAgICAgPC9kaXY+XFxyXFxuICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImFzaWRlLWJvZHlcXFwiPjxzbG90Pjwvc2xvdD48L2Rpdj5cXHJcXG4gICAgICAgIDwvZGl2PlxcclxcbiAgICAgIDwvZGl2PlxcclxcbiAgICA8L2Rpdj5cXHJcXG4gIDwvdHJhbnNpdGlvbj5cXHJcXG48L3RlbXBsYXRlPlxcclxcblxcclxcbjxzY3JpcHQ+XFxyXFxuaW1wb3J0IHtnZXRTY3JvbGxCYXJXaWR0aH0gZnJvbSAnLi91dGlscy91dGlscy5qcydcXHJcXG5pbXBvcnQgJCBmcm9tICcuL3V0aWxzL05vZGVMaXN0LmpzJ1xcclxcblxcclxcbmV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gIHByb3BzOiB7XFxyXFxuICAgIGhlYWRlcjoge3R5cGU6IFN0cmluZ30sXFxyXFxuICAgIHBsYWNlbWVudDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogJ3JpZ2h0J30sXFxyXFxuICAgIHNob3c6IHt0eXBlOiBCb29sZWFuLCByZXF1aXJlZDogdHJ1ZX0sXFxyXFxuICAgIHdpZHRoOiB7dHlwZTogTnVtYmVyLCBkZWZhdWx0OiAzMjB9XFxyXFxuICB9LFxcclxcbiAgd2F0Y2g6IHtcXHJcXG4gICAgc2hvdyAodmFsLCBvbGQpIHtcXHJcXG4gICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbClcXHJcXG4gICAgICB0aGlzLiRlbWl0KHRoaXMuc2hvdyA/ICdvcGVuJyA6ICdjbG9zZScpXFxyXFxuICAgICAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHlcXHJcXG4gICAgICBjb25zdCBzY3JvbGxCYXJXaWR0aCA9IGdldFNjcm9sbEJhcldpZHRoKClcXHJcXG4gICAgICBpZiAodmFsKSB7XFxyXFxuICAgICAgICBpZiAoIXRoaXMuX2JhY2tkcm9wKSB7XFxyXFxuICAgICAgICAgIHRoaXMuX2JhY2tkcm9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcXHJcXG4gICAgICAgIH1cXHJcXG4gICAgICAgIHRoaXMuX2JhY2tkcm9wLmNsYXNzTmFtZSA9ICdhc2lkZS1iYWNrZHJvcCdcXHJcXG4gICAgICAgIGJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fYmFja2Ryb3ApXFxyXFxuICAgICAgICBib2R5LmNsYXNzTGlzdC5hZGQoJ21vZGFsLW9wZW4nKVxcclxcbiAgICAgICAgaWYgKHNjcm9sbEJhcldpZHRoICE9PSAwKSB7XFxyXFxuICAgICAgICAgIGJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0ID0gc2Nyb2xsQmFyV2lkdGggKyAncHgnXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgICAvLyByZXF1ZXN0IHByb3BlcnR5IHRoYXQgcmVxdWlyZXMgbGF5b3V0IHRvIGZvcmNlIGEgbGF5b3V0XFxyXFxuICAgICAgICB2YXIgeCA9IHRoaXMuX2JhY2tkcm9wLmNsaWVudEhlaWdodFxcclxcbiAgICAgICAgdGhpcy5fYmFja2Ryb3AuY2xhc3NMaXN0LmFkZCgnaW4nKVxcclxcbiAgICAgICAgJCh0aGlzLl9iYWNrZHJvcCkub24oJ2NsaWNrJywgKCkgPT4gdGhpcy50cmlnZ2VyX2Nsb3NlKCkpXFxyXFxuICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICQodGhpcy5fYmFja2Ryb3ApLm9uKCd0cmFuc2l0aW9uZW5kJywgKCkgPT4ge1xcclxcbiAgICAgICAgICAkKHRoaXMuX2JhY2tkcm9wKS5vZmYoKVxcclxcbiAgICAgICAgICB0cnkge1xcclxcbiAgICAgICAgICAgIGJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnbW9kYWwtb3BlbicpXFxyXFxuICAgICAgICAgICAgYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSAnMCdcXHJcXG4gICAgICAgICAgICBib2R5LnJlbW92ZUNoaWxkKHRoaXMuX2JhY2tkcm9wKVxcclxcbiAgICAgICAgICAgIHRoaXMuX2JhY2tkcm9wID0gbnVsbFxcclxcbiAgICAgICAgICB9IGNhdGNoIChlKSB7fVxcclxcbiAgICAgICAgfSlcXHJcXG4gICAgICAgIHRoaXMuX2JhY2tkcm9wLmNsYXNzTmFtZSA9ICdhc2lkZS1iYWNrZHJvcCdcXHJcXG4gICAgICB9XFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBtZXRob2RzOiB7XFxyXFxuICAgIHRyaWdnZXIgKCkge1xcclxcbiAgICAgIHJldHVybiB7XFxyXFxuICAgICAgICBjbG9zZTogKCkgPT4gdGhpcy50cmlnZ2VyX2Nsb3NlKCksXFxyXFxuICAgICAgICBvcGVuOiAoKSA9PiB0aGlzLnRyaWdnZXJfb3BlbigpXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICB0cmlnZ2VyX2Nsb3NlICgpIHtcXHJcXG4gICAgICB0aGlzLiRlbWl0KCAnY2xvc2UnIClcXHJcXG4gICAgfSxcXHJcXG4gICAgdHJpZ2dlcl9vcGVuKCkge1xcclxcbiAgICAgIHRoaXMuJGVtaXQoICdvcGVuJyApXFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBtb3VudGVkICgpIHtcXHJcXG4gICAgdGhpcy4kZW1pdCgndHJpZ2dlcicsICgpID0+IHRoaXMudHJpZ2dlcilcXHJcXG4gIH1cXHJcXG59XFxyXFxuPC9zY3JpcHQ+XFxyXFxuXFxyXFxuPHN0eWxlPlxcclxcbi5hc2lkZS1vcGVuIHtcXHJcXG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjNzO1xcclxcbn1cXHJcXG4uYXNpZGUtb3Blbi5oYXMtcHVzaC1yaWdodCB7XFxyXFxuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTMwMHB4KTtcXHJcXG59XFxyXFxuLmFzaWRlIHtcXHJcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXHJcXG4gIHRvcDogMDtcXHJcXG4gIGJvdHRvbTogMDtcXHJcXG4gIHotaW5kZXg6IDEwNDk7XFxyXFxuICBvdmVyZmxvdzogYXV0bztcXHJcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxyXFxufVxcclxcbi5hc2lkZS5sZWZ0IHtcXHJcXG4gIGxlZnQ6IDA7XFxyXFxuICByaWdodDogYXV0bztcXHJcXG59XFxyXFxuLmFzaWRlLnJpZ2h0IHtcXHJcXG4gIGxlZnQ6IGF1dG87XFxyXFxuICByaWdodDogMDtcXHJcXG59XFxyXFxuLnNsaWRlbGVmdC1lbnRlciB7XFxyXFxuICB0cmFuc2Zvcm06dHJhbnNsYXRlWCgtMTAwJSk7XFxyXFxufVxcclxcbi5zbGlkZWxlZnQtZW50ZXItYWN0aXZlIHtcXHJcXG4gIGFuaW1hdGlvbjpzbGlkZWxlZnQtaW4gLjNzO1xcclxcbn1cXHJcXG4uc2xpZGVsZWZ0LWxlYXZlLWFjdGl2ZSB7XFxyXFxuICBhbmltYXRpb246c2xpZGVsZWZ0LW91dCAuM3M7XFxyXFxufVxcclxcbkBrZXlmcmFtZXMgc2xpZGVsZWZ0LWluIHtcXHJcXG4gIDAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC0xMDAlKTtcXHJcXG4gICAgb3BhY2l0eTogMDtcXHJcXG4gIH1cXHJcXG4gIDEwMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XFxyXFxuICAgIG9wYWNpdHk6IDE7XFxyXFxuICB9XFxyXFxufVxcclxcbkBrZXlmcmFtZXMgc2xpZGVsZWZ0LW91dCB7XFxyXFxuICAwJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcXHJcXG4gICAgb3BhY2l0eTogMTtcXHJcXG4gIH1cXHJcXG4gIDEwMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwMCUpO1xcclxcbiAgICBvcGFjaXR5OiAwO1xcclxcbiAgfVxcclxcbn1cXHJcXG4uc2xpZGVyaWdodC1lbnRlci1hY3RpdmUge1xcclxcbiAgYW5pbWF0aW9uOnNsaWRlcmlnaHQtaW4gLjNzO1xcclxcbn1cXHJcXG4uc2xpZGVyaWdodC1sZWF2ZS1hY3RpdmUge1xcclxcbiAgYW5pbWF0aW9uOnNsaWRlcmlnaHQtb3V0IC4zcztcXHJcXG59XFxyXFxuQGtleWZyYW1lcyBzbGlkZXJpZ2h0LWluIHtcXHJcXG4gIDAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpO1xcclxcbiAgICBvcGFjaXR5OiAwO1xcclxcbiAgfVxcclxcbiAgMTAwJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcXHJcXG4gICAgb3BhY2l0eTogMTtcXHJcXG4gIH1cXHJcXG59XFxyXFxuQGtleWZyYW1lcyBzbGlkZXJpZ2h0LW91dCB7XFxyXFxuICAwJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcXHJcXG4gICAgb3BhY2l0eTogMTtcXHJcXG4gIH1cXHJcXG4gIDEwMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSk7XFxyXFxuICAgIG9wYWNpdHk6IDA7XFxyXFxuICB9XFxyXFxufVxcclxcbi5hc2lkZTpmb2N1cyB7XFxyXFxuICAgIG91dGxpbmU6IDA7XFxyXFxufVxcclxcbkBtZWRpYSAobWF4LXdpZHRoOiA5OTFweCkge1xcclxcbiAgLmFzaWRlIHtcXHJcXG4gICAgbWluLXdpZHRoOiAyNDBweDtcXHJcXG4gIH1cXHJcXG59XFxyXFxuLmFzaWRlIC5hc2lkZS1kaWFsb2cgLmFzaWRlLWhlYWRlciB7XFxyXFxuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2U1ZTVlNTtcXHJcXG4gIG1pbi1oZWlnaHQ6IDE2LjQzcHg7XFxyXFxuICBwYWRkaW5nOiA2cHggMTVweDtcXHJcXG4gIGJhY2tncm91bmQ6ICMzMzdhYjc7XFxyXFxuICBjb2xvcjogI2ZmZjtcXHJcXG59XFxyXFxuLmFzaWRlIC5hc2lkZS1kaWFsb2cgLmFzaWRlLWhlYWRlciAuY2xvc2Uge1xcclxcbiAgbWFyZ2luLXJpZ2h0OiAtOHB4O1xcclxcbiAgcGFkZGluZzogNHB4IDhweDtcXHJcXG4gIGNvbG9yOiAjZmZmO1xcclxcbiAgZm9udC1zaXplOiAyNXB4O1xcclxcbiAgb3BhY2l0eTogLjg7XFxyXFxufVxcclxcbi5hc2lkZSAuYXNpZGUtZGlhbG9nIC5hc2lkZS1ib2R5IHtcXHJcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gIHBhZGRpbmc6IDE1cHg7XFxyXFxufVxcclxcbi5hc2lkZSAuYXNpZGUtZGlhbG9nIC5hc2lkZS1mb290ZXIge1xcclxcbiAgcGFkZGluZzogMTVweDtcXHJcXG4gIHRleHQtYWxpZ246IHJpZ2h0O1xcclxcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNlNWU1ZTU7XFxyXFxufVxcclxcbi5hc2lkZSAuYXNpZGUtZGlhbG9nIC5hc2lkZS1mb290ZXIgLmJ0bisuYnRuIHtcXHJcXG4gIG1hcmdpbi1sZWZ0OiA1cHg7XFxyXFxuICBtYXJnaW4tYm90dG9tOiAwO1xcclxcbn1cXHJcXG4uYXNpZGUgLmFzaWRlLWRpYWxvZyAuYXNpZGUtZm9vdGVyIC5idG4tZ3JvdXAgLmJ0bisuYnRuIHtcXHJcXG4gIG1hcmdpbi1sZWZ0OiAtMXB4O1xcclxcbn1cXHJcXG4uYXNpZGUgLmFzaWRlLWRpYWxvZyAuYXNpZGUtZm9vdGVyIC5idG4tYmxvY2srLmJ0bi1ibG9jayB7XFxyXFxuICBtYXJnaW4tbGVmdDogMDtcXHJcXG59XFxyXFxuLmFzaWRlLWJhY2tkcm9wIHtcXHJcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXHJcXG4gIHRvcDogMDtcXHJcXG4gIHJpZ2h0OiAwO1xcclxcbiAgYm90dG9tOiAwO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIHotaW5kZXg6IDEwNDA7XFxyXFxuICBvcGFjaXR5OiAwO1xcclxcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSAuM3MgZWFzZTtcXHJcXG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XFxyXFxufVxcclxcbi5hc2lkZS1iYWNrZHJvcC5pbiB7XFxyXFxuICBvcGFjaXR5OiAuNTtcXHJcXG4gIGZpbHRlcjogYWxwaGEob3BhY2l0eT01MCk7XFxyXFxufVxcclxcbjwvc3R5bGU+XFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXHRcblx0Ly8gZXhwb3J0c1xuXG5cbi8qKiovIH0sXG4vKiA4NSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdFxuXHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2NSk7XG5cdFxuXHR2YXIgX05vZGVMaXN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblx0XG5cdHZhciBfTm9kZUxpc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTm9kZUxpc3QpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblx0XG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgcHJvcHM6IHtcblx0ICAgIGhlYWRlcjogeyB0eXBlOiBTdHJpbmcgfSxcblx0ICAgIHBsYWNlbWVudDogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICdyaWdodCcgfSxcblx0ICAgIHNob3c6IHsgdHlwZTogQm9vbGVhbiwgcmVxdWlyZWQ6IHRydWUgfSxcblx0ICAgIHdpZHRoOiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogMzIwIH1cblx0ICB9LFxuXHQgIHdhdGNoOiB7XG5cdCAgICBzaG93OiBmdW5jdGlvbiBzaG93KHZhbCwgb2xkKSB7XG5cdCAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbCk7XG5cdCAgICAgIHRoaXMuJGVtaXQodGhpcy5zaG93ID8gJ29wZW4nIDogJ2Nsb3NlJyk7XG5cdCAgICAgIHZhciBib2R5ID0gZG9jdW1lbnQuYm9keTtcblx0ICAgICAgdmFyIHNjcm9sbEJhcldpZHRoID0gKDAsIF91dGlscy5nZXRTY3JvbGxCYXJXaWR0aCkoKTtcblx0ICAgICAgaWYgKHZhbCkge1xuXHQgICAgICAgIGlmICghdGhpcy5fYmFja2Ryb3ApIHtcblx0ICAgICAgICAgIHRoaXMuX2JhY2tkcm9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuX2JhY2tkcm9wLmNsYXNzTmFtZSA9ICdhc2lkZS1iYWNrZHJvcCc7XG5cdCAgICAgICAgYm9keS5hcHBlbmRDaGlsZCh0aGlzLl9iYWNrZHJvcCk7XG5cdCAgICAgICAgYm9keS5jbGFzc0xpc3QuYWRkKCdtb2RhbC1vcGVuJyk7XG5cdCAgICAgICAgaWYgKHNjcm9sbEJhcldpZHRoICE9PSAwKSB7XG5cdCAgICAgICAgICBib2R5LnN0eWxlLnBhZGRpbmdSaWdodCA9IHNjcm9sbEJhcldpZHRoICsgJ3B4Jztcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy8gcmVxdWVzdCBwcm9wZXJ0eSB0aGF0IHJlcXVpcmVzIGxheW91dCB0byBmb3JjZSBhIGxheW91dFxuXHQgICAgICAgIHZhciB4ID0gdGhpcy5fYmFja2Ryb3AuY2xpZW50SGVpZ2h0O1xuXHQgICAgICAgIHRoaXMuX2JhY2tkcm9wLmNsYXNzTGlzdC5hZGQoJ2luJyk7XG5cdCAgICAgICAgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkodGhpcy5fYmFja2Ryb3ApLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgIHJldHVybiBfdGhpcy50cmlnZ2VyX2Nsb3NlKCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkodGhpcy5fYmFja2Ryb3ApLm9uKCd0cmFuc2l0aW9uZW5kJywgZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkoX3RoaXMuX2JhY2tkcm9wKS5vZmYoKTtcblx0ICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIGJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnbW9kYWwtb3BlbicpO1xuXHQgICAgICAgICAgICBib2R5LnN0eWxlLnBhZGRpbmdSaWdodCA9ICcwJztcblx0ICAgICAgICAgICAgYm9keS5yZW1vdmVDaGlsZChfdGhpcy5fYmFja2Ryb3ApO1xuXHQgICAgICAgICAgICBfdGhpcy5fYmFja2Ryb3AgPSBudWxsO1xuXHQgICAgICAgICAgfSBjYXRjaCAoZSkge31cblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0aGlzLl9iYWNrZHJvcC5jbGFzc05hbWUgPSAnYXNpZGUtYmFja2Ryb3AnO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtZXRob2RzOiB7XG5cdCAgICB0cmlnZ2VyOiBmdW5jdGlvbiB0cmlnZ2VyKCkge1xuXHQgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblx0XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgY2xvc2U6IGZ1bmN0aW9uIGNsb3NlKCkge1xuXHQgICAgICAgICAgcmV0dXJuIF90aGlzMi50cmlnZ2VyX2Nsb3NlKCk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBvcGVuOiBmdW5jdGlvbiBvcGVuKCkge1xuXHQgICAgICAgICAgcmV0dXJuIF90aGlzMi50cmlnZ2VyX29wZW4oKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH07XG5cdCAgICB9LFxuXHQgICAgdHJpZ2dlcl9jbG9zZTogZnVuY3Rpb24gdHJpZ2dlcl9jbG9zZSgpIHtcblx0ICAgICAgdGhpcy4kZW1pdCgnY2xvc2UnKTtcblx0ICAgIH0sXG5cdCAgICB0cmlnZ2VyX29wZW46IGZ1bmN0aW9uIHRyaWdnZXJfb3BlbigpIHtcblx0ICAgICAgdGhpcy4kZW1pdCgnb3BlbicpO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbW91bnRlZDogZnVuY3Rpb24gbW91bnRlZCgpIHtcblx0ICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXHRcblx0ICAgIHRoaXMuJGVtaXQoJ3RyaWdnZXInLCBmdW5jdGlvbiAoKSB7XG5cdCAgICAgIHJldHVybiBfdGhpczMudHJpZ2dlcjtcblx0ICAgIH0pO1xuXHQgIH1cblx0fTtcblxuLyoqKi8gfSxcbi8qIDg2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ3RyYW5zaXRpb24nLCB7XG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcIm5hbWVcIjogJ3NsaWRlJyArIF92bS5wbGFjZW1lbnRcblx0ICAgIH1cblx0ICB9LCBbKF92bS5zaG93KSA/IF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiYXNpZGVcIixcblx0ICAgIGNsYXNzOiBfdm0ucGxhY2VtZW50LFxuXHQgICAgc3R5bGU6ICh7XG5cdCAgICAgIHdpZHRoOiBfdm0ud2lkdGggKyAncHgnXG5cdCAgICB9KVxuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImFzaWRlLWRpYWxvZ1wiXG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiYXNpZGUtY29udGVudFwiXG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiYXNpZGUtaGVhZGVyXCJcblx0ICB9LCBbX3ZtLl9jKCdidXR0b24nLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJjbG9zZVwiLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJ0eXBlXCI6IFwiYnV0dG9uXCJcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IF92bS50cmlnZ2VyX2Nsb3NlXG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygnc3BhbicsIFtfdm0uX3YoXCLDl1wiKV0pXSksIF92bS5fdihcIiBcIiksIF92bS5fYygnaDQnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJhc2lkZS10aXRsZVwiXG5cdCAgfSwgW192bS5fdChcImhlYWRlclwiLCBbX3ZtLl92KF92bS5fcyhfdm0uaGVhZGVyKSldKV0sIDIpXSksIF92bS5fdihcIiBcIiksIF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiYXNpZGUtYm9keVwiXG5cdCAgfSwgW192bS5fdChcImRlZmF1bHRcIildLCAyKV0pXSldKSA6IF92bS5fZSgpXSlcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtM2E0YmRlMjdcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiA4NyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg4OClcblx0XG5cdC8qIHRlbXBsYXRlICovXG5cdHZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg4OSlcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxCdXR0b25Hcm91cC52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtMTI1ZWIwYzhcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTEyNWViMGM4XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gQnV0dG9uR3JvdXAudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogODggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIHByb3BzOiB7XG5cdCAgICBidXR0b25zOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IHRydWUgfSxcblx0ICAgIGRpc2FibGVkOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH0sXG5cdCAgICBqdXN0aWZpZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIHR5cGU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnZGVmYXVsdCcgfSxcblx0ICAgIHZhbHVlOiB7IGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIHZlcnRpY2FsOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH1cblx0ICB9LFxuXHQgIGNvbXB1dGVkOiB7XG5cdCAgICBidG5Hcm91cDogZnVuY3Rpb24gYnRuR3JvdXAoKSB7XG5cdCAgICAgIHJldHVybiAhdGhpcy5kaXNhYmxlZDtcblx0ICAgIH1cblx0ICB9LFxuXHQgIGRhdGE6IGZ1bmN0aW9uIGRhdGEoKSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICB2YWw6IHRoaXMudmFsdWVcblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgd2F0Y2g6IHtcblx0ICAgIC8vIHRoaXMgd2lsbCB1cGRhdGUgRVhURVJOQUwgdi1tb2RlbCB3aGVuIG91ciB2YWwgY2hhbmdlc1xuXHQgICAgdmFsOiBmdW5jdGlvbiB2YWwoX3ZhbCkge1xuXHQgICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIF92YWwpO1xuXHQgICAgfSxcblx0XG5cdCAgICAvLyB0aGlzIHdpbGwgdXBkYXRlIG91ciBJTlRFUk5BTCB2YWwsIHdoZW4gc29tZXRoaW5nIGV4dGVybmFsIGNoYW5nZXMgb3VyIHYtbW9kZWxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZSh2YWwpIHtcblx0ICAgICAgdGhpcy52YWwgPSB2YWw7XG5cdCAgICB9XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogODkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYygnZGl2Jywge1xuXHQgICAgY2xhc3M6IHtcblx0ICAgICAgJ2J0bi1ncm91cCc6IF92bS5idXR0b25zLCAnYnRuLWdyb3VwLWp1c3RpZmllZCc6IF92bS5qdXN0aWZpZWQsICdidG4tZ3JvdXAtdmVydGljYWwnOiBfdm0udmVydGljYWxcblx0ICAgIH0sXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImRhdGEtdG9nZ2xlXCI6IF92bS5idXR0b25zICYmICdidXR0b25zJ1xuXHQgICAgfVxuXHQgIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMilcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMTI1ZWIwYzhcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiA5MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzdHlsZXMgKi9cblx0X193ZWJwYWNrX3JlcXVpcmVfXyg5MSlcblx0XG5cdC8qIHNjcmlwdCAqL1xuXHRfX3Z1ZV9leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDkzKVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDk0KVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXENhcm91c2VsLnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0X192dWVfb3B0aW9uc19fLl9zY29wZUlkID0gXCJkYXRhLXYtMzIyZGVlNDFcIlxuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTMyMmRlZTQxXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi0zMjJkZWU0MVwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIENhcm91c2VsLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDkxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg5Mik7XG5cdGlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuXHQvLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG5cdHZhciB1cGRhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc5KShjb250ZW50LCB7fSk7XG5cdGlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuXHQvLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5cdGlmKGZhbHNlKSB7XG5cdFx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMzIyZGVlNDEmc2NvcGVkPXRydWUhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0Nhcm91c2VsLnZ1ZVwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMzIyZGVlNDEmc2NvcGVkPXRydWUhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0Nhcm91c2VsLnZ1ZVwiKTtcblx0XHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDkyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc4KSgpO1xuXHQvLyBpbXBvcnRzXG5cdFxuXHRcblx0Ly8gbW9kdWxlXG5cdGV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5jYXJvdXNlbC1jb250cm9sW2RhdGEtdi0zMjJkZWU0MV0ge1xcclxcbiAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXHJcXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL0Nhcm91c2VsLnZ1ZT8yZjQ0NjM0MlwiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiO0FBNEdBO0VBQ0EsZ0JBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiQ2Fyb3VzZWwudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG48ZGl2IGNsYXNzPVxcXCJjYXJvdXNlbCBzbGlkZVxcXCIgZGF0YS1yaWRlPVxcXCJjYXJvdXNlbFxcXCI+XFxyXFxuICA8IS0tIEluZGljYXRvcnMgLS0+XFxyXFxuICA8b2wgY2xhc3M9XFxcImNhcm91c2VsLWluZGljYXRvcnNcXFwiIHYtc2hvdz1cXFwiaW5kaWNhdG9yc1xcXCI+XFxyXFxuICAgIDxsaSB2LWZvcj1cXFwiKGluZGljYXRvcixpKSBpbiBpbmRpY2F0b3JfbGlzdFxcXCIgQGNsaWNrPVxcXCJpbmRpY2F0b3JDbGljayhpKVxcXCIgOmNsYXNzPVxcXCJ7YWN0aXZlOmkgPT09IGluZGV4fVxcXCI+PHNwYW4+PC9zcGFuPjwvbGk+XFxyXFxuICA8L29sPlxcclxcbiAgPCEtLSBXcmFwcGVyIGZvciBzbGlkZXMgLS0+XFxyXFxuICA8ZGl2IGNsYXNzPVxcXCJjYXJvdXNlbC1pbm5lclxcXCIgcm9sZT1cXFwibGlzdGJveFxcXCI+XFxyXFxuICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gIDwvZGl2PlxcclxcbiAgPCEtLSBDb250cm9scyAtLT5cXHJcXG4gIDxkaXYgdi1zaG93PVxcXCJjb250cm9sc1xcXCIgY2xhc3M9XFxcImNhcm91c2VsLWNvbnRyb2xzIGhpZGRlbi14c1xcXCI+XFxyXFxuICAgIDxhIGNsYXNzPVxcXCJsZWZ0IGNhcm91c2VsLWNvbnRyb2xcXFwiIHJvbGU9XFxcImJ1dHRvblxcXCIgQGNsaWNrPVxcXCJwcmV2XFxcIj5cXHJcXG4gICAgICA8c3BhbiBjbGFzcz1cXFwiZ2x5cGhpY29uIGdseXBoaWNvbi1jaGV2cm9uLWxlZnRcXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj48L3NwYW4+XFxyXFxuICAgIDwvYT5cXHJcXG4gICAgPGEgY2xhc3M9XFxcInJpZ2h0IGNhcm91c2VsLWNvbnRyb2xcXFwiIHJvbGU9XFxcImJ1dHRvblxcXCIgQGNsaWNrPVxcXCJuZXh0XFxcIj5cXHJcXG4gICAgICA8c3BhbiBjbGFzcz1cXFwiZ2x5cGhpY29uIGdseXBoaWNvbi1jaGV2cm9uLXJpZ2h0XFxcIiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCI+PC9zcGFuPlxcclxcbiAgICA8L2E+XFxyXFxuICA8L2Rpdj5cXHJcXG48L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcblxcclxcbjxzY3JpcHQ+XFxyXFxuaW1wb3J0ICQgZnJvbSAnLi91dGlscy9Ob2RlTGlzdC5qcydcXHJcXG4vLyBsZXQgY29lcmNlID0ge1xcclxcbi8vICAgaW50ZXJ2YWw6ICdudW1iZXInXFxyXFxuLy8gfVxcclxcblxcclxcbmV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gIHByb3BzOiB7XFxyXFxuICAgIGluZGljYXRvcnM6IHtcXHJcXG4gICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgfSxcXHJcXG4gICAgY29udHJvbHM6IHtcXHJcXG4gICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgfSxcXHJcXG4gICAgaW50ZXJ2YWw6IHtcXHJcXG4gICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgZGVmYXVsdDogNTAwMFxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgZGF0YSAoKSB7XFxyXFxuICAgIHJldHVybiB7XFxyXFxuICAgICAgaW5kaWNhdG9yX2xpc3Q6IFtdLFxcclxcbiAgICAgIGluZGV4OiAwLFxcclxcbiAgICAgIGlzQW5pbWF0aW5nOiBmYWxzZVxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgd2F0Y2g6IHtcXHJcXG4gICAgaW5kZXggKG5ld1ZhbCwgb2xkVmFsKSB7XFxyXFxuICAgICAgdGhpcy5zbGlkZShuZXdWYWwgPiBvbGRWYWwgPyAnbGVmdCcgOiAncmlnaHQnLCBuZXdWYWwsIG9sZFZhbClcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgaW5kaWNhdG9yQ2xpY2sgKGluZGV4KSB7XFxyXFxuICAgICAgaWYgKHRoaXMuaXNBbmltYXRpbmcgfHwgdGhpcy5pbmRleCA9PT0gaW5kZXgpIHJldHVybiBmYWxzZVxcclxcbiAgICAgIHRoaXMuaXNBbmltYXRpbmcgPSB0cnVlXFxyXFxuICAgICAgdGhpcy5pbmRleCA9IGluZGV4XFxyXFxuICAgIH0sXFxyXFxuICAgIHNsaWRlIChkaXJlY3Rpb24sIG5leHQsIHByZXYpIHtcXHJcXG4gICAgICBpZiAoIXRoaXMuJGVsKSB7IHJldHVybiB9XFxyXFxuICAgICAgY29uc3QgJHNsaWRlciA9ICQoJy5pdGVtJywgdGhpcy4kZWwpXFxyXFxuICAgICAgaWYgKCEkc2xpZGVyLmxlbmd0aCkgeyByZXR1cm4gfVxcclxcbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gJHNsaWRlcltuZXh0XSB8fCAkc2xpZGVyWzBdXFxyXFxuICAgICAgJChzZWxlY3RlZCkuYWRkQ2xhc3MoZGlyZWN0aW9uID09PSAnbGVmdCcgPyAnbmV4dCcgOiAncHJldicpXFxyXFxuICAgICAgLy8gcmVxdWVzdCBwcm9wZXJ0eSB0aGF0IHJlcXVpcmVzIGxheW91dCB0byBmb3JjZSBhIGxheW91dFxcclxcbiAgICAgIHZhciB4ID0gc2VsZWN0ZWQuY2xpZW50SGVpZ2h0XFxyXFxuICAgICAgJChbJHNsaWRlcltwcmV2XSwgc2VsZWN0ZWRdKS5hZGRDbGFzcyhkaXJlY3Rpb24pLm9uKCd0cmFuc2l0aW9uZW5kJywgKCkgPT4ge1xcclxcbiAgICAgICAgJHNsaWRlci5vZmYoJ3RyYW5zaXRpb25lbmQnKS5jbGFzc05hbWUgPSAnaXRlbSdcXHJcXG4gICAgICAgICQoc2VsZWN0ZWQpLmFkZENsYXNzKCdhY3RpdmUnKVxcclxcbiAgICAgICAgdGhpcy5pc0FuaW1hdGluZyA9IGZhbHNlXFxyXFxuICAgICAgfSlcXHJcXG4gICAgfSxcXHJcXG4gICAgbmV4dCAoKSB7XFxyXFxuICAgICAgaWYgKCF0aGlzLiRlbCB8fCB0aGlzLmlzQW5pbWF0aW5nKSB7IHJldHVybiBmYWxzZSB9XFxyXFxuICAgICAgdGhpcy5pc0FuaW1hdGluZyA9IHRydWVcXHJcXG4gICAgICB0aGlzLmluZGV4ICsgMSA8ICQoJy5pdGVtJywgdGhpcy4kZWwpLmxlbmd0aCA/IHRoaXMuaW5kZXggKz0gMSA6IHRoaXMuaW5kZXggPSAwXFxyXFxuICAgIH0sXFxyXFxuICAgIHByZXYgKCkge1xcclxcbiAgICAgIGlmICghdGhpcy4kZWwgfHwgdGhpcy5pc0FuaW1hdGluZykgeyByZXR1cm4gZmFsc2UgfVxcclxcbiAgICAgIHRoaXMuaXNBbmltYXRpbmcgPSB0cnVlXFxyXFxuICAgICAgdGhpcy5pbmRleCA9PT0gMCA/IHRoaXMuaW5kZXggPSAkKCcuaXRlbScsIHRoaXMuJGVsKS5sZW5ndGggLSAxIDogdGhpcy5pbmRleCAtPSAxXFxyXFxuICAgIH0sXFxyXFxuICAgIHRvZ2dsZUludGVydmFsICh2YWwpIHtcXHJcXG4gICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHsgdmFsID0gdGhpcy5faW50ZXJ2YWxJRCB9XFxyXFxuICAgICAgaWYodGhpcy5faW50ZXJ2YWxJRCkge1xcclxcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9pbnRlcnZhbElEKVxcclxcbiAgICAgICAgZGVsZXRlIHRoaXMuX2ludGVydmFsSURcXHJcXG4gICAgICB9XFxyXFxuICAgICAgaWYodmFsICYmIHRoaXMuaW50ZXJ2YWwgPiAwKSB7XFxyXFxuICAgICAgICB0aGlzLl9pbnRlcnZhbElEID0gc2V0SW50ZXJ2YWwodGhpcy5uZXh0LCB0aGlzLmludGVydmFsKVxcclxcbiAgICAgIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1vdW50ZWQgKCkge1xcclxcbiAgICB0aGlzLnRvZ2dsZUludGVydmFsKHRydWUpXFxyXFxuICAgICQodGhpcy4kZWwpLm9uKCdtb3VzZWVudGVyJywgKCkgPT4gdGhpcy50b2dnbGVJbnRlcnZhbChmYWxzZSkpLm9uKCdtb3VzZWxlYXZlJywgKCkgPT4gdGhpcy50b2dnbGVJbnRlcnZhbCh0cnVlKSlcXHJcXG4gIH0sXFxyXFxuICBiZWZvcmVEZXN0cm95ICgpIHtcXHJcXG4gICAgdGhpcy50b2dnbGVJbnRlcnZhbChmYWxzZSlcXHJcXG4gICAgJCh0aGlzLiRlbCkub2ZmKCdtb3VzZWVudGVyIG1vdXNlbGVhdmUnKVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGUgc2NvcGVkPlxcclxcbi5jYXJvdXNlbC1jb250cm9sIHtcXHJcXG4gIGN1cnNvcjogcG9pbnRlcjtcXHJcXG59XFxyXFxuPC9zdHlsZT5cXHJcXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cdFxuXHQvLyBleHBvcnRzXG5cblxuLyoqKi8gfSxcbi8qIDkzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfTm9kZUxpc3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXHRcblx0dmFyIF9Ob2RlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Ob2RlTGlzdCk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0Ly8gbGV0IGNvZXJjZSA9IHtcblx0Ly8gICBpbnRlcnZhbDogJ251bWJlcidcblx0Ly8gfVxuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIHByb3BzOiB7XG5cdCAgICBpbmRpY2F0b3JzOiB7XG5cdCAgICAgIHR5cGU6IEJvb2xlYW4sXG5cdCAgICAgIGRlZmF1bHQ6IHRydWVcblx0ICAgIH0sXG5cdCAgICBjb250cm9sczoge1xuXHQgICAgICB0eXBlOiBCb29sZWFuLFxuXHQgICAgICBkZWZhdWx0OiB0cnVlXG5cdCAgICB9LFxuXHQgICAgaW50ZXJ2YWw6IHtcblx0ICAgICAgdHlwZTogTnVtYmVyLFxuXHQgICAgICBkZWZhdWx0OiA1MDAwXG5cdCAgICB9XG5cdCAgfSxcblx0ICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgaW5kaWNhdG9yX2xpc3Q6IFtdLFxuXHQgICAgICBpbmRleDogMCxcblx0ICAgICAgaXNBbmltYXRpbmc6IGZhbHNlXG5cdCAgICB9O1xuXHQgIH0sXG5cdFxuXHQgIHdhdGNoOiB7XG5cdCAgICBpbmRleDogZnVuY3Rpb24gaW5kZXgobmV3VmFsLCBvbGRWYWwpIHtcblx0ICAgICAgdGhpcy5zbGlkZShuZXdWYWwgPiBvbGRWYWwgPyAnbGVmdCcgOiAncmlnaHQnLCBuZXdWYWwsIG9sZFZhbCk7XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtZXRob2RzOiB7XG5cdCAgICBpbmRpY2F0b3JDbGljazogZnVuY3Rpb24gaW5kaWNhdG9yQ2xpY2soaW5kZXgpIHtcblx0ICAgICAgaWYgKHRoaXMuaXNBbmltYXRpbmcgfHwgdGhpcy5pbmRleCA9PT0gaW5kZXgpIHJldHVybiBmYWxzZTtcblx0ICAgICAgdGhpcy5pc0FuaW1hdGluZyA9IHRydWU7XG5cdCAgICAgIHRoaXMuaW5kZXggPSBpbmRleDtcblx0ICAgIH0sXG5cdCAgICBzbGlkZTogZnVuY3Rpb24gc2xpZGUoZGlyZWN0aW9uLCBuZXh0LCBwcmV2KSB7XG5cdCAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICBpZiAoIXRoaXMuJGVsKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICAgIHZhciAkc2xpZGVyID0gKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkoJy5pdGVtJywgdGhpcy4kZWwpO1xuXHQgICAgICBpZiAoISRzbGlkZXIubGVuZ3RoKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICAgIHZhciBzZWxlY3RlZCA9ICRzbGlkZXJbbmV4dF0gfHwgJHNsaWRlclswXTtcblx0ICAgICAgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkoc2VsZWN0ZWQpLmFkZENsYXNzKGRpcmVjdGlvbiA9PT0gJ2xlZnQnID8gJ25leHQnIDogJ3ByZXYnKTtcblx0ICAgICAgLy8gcmVxdWVzdCBwcm9wZXJ0eSB0aGF0IHJlcXVpcmVzIGxheW91dCB0byBmb3JjZSBhIGxheW91dFxuXHQgICAgICB2YXIgeCA9IHNlbGVjdGVkLmNsaWVudEhlaWdodDtcblx0ICAgICAgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkoWyRzbGlkZXJbcHJldl0sIHNlbGVjdGVkXSkuYWRkQ2xhc3MoZGlyZWN0aW9uKS5vbigndHJhbnNpdGlvbmVuZCcsIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAkc2xpZGVyLm9mZigndHJhbnNpdGlvbmVuZCcpLmNsYXNzTmFtZSA9ICdpdGVtJztcblx0ICAgICAgICAoMCwgX05vZGVMaXN0Mi5kZWZhdWx0KShzZWxlY3RlZCkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuXHQgICAgICAgIF90aGlzLmlzQW5pbWF0aW5nID0gZmFsc2U7XG5cdCAgICAgIH0pO1xuXHQgICAgfSxcblx0ICAgIG5leHQ6IGZ1bmN0aW9uIG5leHQoKSB7XG5cdCAgICAgIGlmICghdGhpcy4kZWwgfHwgdGhpcy5pc0FuaW1hdGluZykge1xuXHQgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgfVxuXHQgICAgICB0aGlzLmlzQW5pbWF0aW5nID0gdHJ1ZTtcblx0ICAgICAgdGhpcy5pbmRleCArIDEgPCAoMCwgX05vZGVMaXN0Mi5kZWZhdWx0KSgnLml0ZW0nLCB0aGlzLiRlbCkubGVuZ3RoID8gdGhpcy5pbmRleCArPSAxIDogdGhpcy5pbmRleCA9IDA7XG5cdCAgICB9LFxuXHQgICAgcHJldjogZnVuY3Rpb24gcHJldigpIHtcblx0ICAgICAgaWYgKCF0aGlzLiRlbCB8fCB0aGlzLmlzQW5pbWF0aW5nKSB7XG5cdCAgICAgICAgcmV0dXJuIGZhbHNlO1xuXHQgICAgICB9XG5cdCAgICAgIHRoaXMuaXNBbmltYXRpbmcgPSB0cnVlO1xuXHQgICAgICB0aGlzLmluZGV4ID09PSAwID8gdGhpcy5pbmRleCA9ICgwLCBfTm9kZUxpc3QyLmRlZmF1bHQpKCcuaXRlbScsIHRoaXMuJGVsKS5sZW5ndGggLSAxIDogdGhpcy5pbmRleCAtPSAxO1xuXHQgICAgfSxcblx0ICAgIHRvZ2dsZUludGVydmFsOiBmdW5jdGlvbiB0b2dnbGVJbnRlcnZhbCh2YWwpIHtcblx0ICAgICAgaWYgKHZhbCA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgdmFsID0gdGhpcy5faW50ZXJ2YWxJRDtcblx0ICAgICAgfVxuXHQgICAgICBpZiAodGhpcy5faW50ZXJ2YWxJRCkge1xuXHQgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5faW50ZXJ2YWxJRCk7XG5cdCAgICAgICAgZGVsZXRlIHRoaXMuX2ludGVydmFsSUQ7XG5cdCAgICAgIH1cblx0ICAgICAgaWYgKHZhbCAmJiB0aGlzLmludGVydmFsID4gMCkge1xuXHQgICAgICAgIHRoaXMuX2ludGVydmFsSUQgPSBzZXRJbnRlcnZhbCh0aGlzLm5leHQsIHRoaXMuaW50ZXJ2YWwpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkKCkge1xuXHQgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cdFxuXHQgICAgdGhpcy50b2dnbGVJbnRlcnZhbCh0cnVlKTtcblx0ICAgICgwLCBfTm9kZUxpc3QyLmRlZmF1bHQpKHRoaXMuJGVsKS5vbignbW91c2VlbnRlcicsIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgcmV0dXJuIF90aGlzMi50b2dnbGVJbnRlcnZhbChmYWxzZSk7XG5cdCAgICB9KS5vbignbW91c2VsZWF2ZScsIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgcmV0dXJuIF90aGlzMi50b2dnbGVJbnRlcnZhbCh0cnVlKTtcblx0ICAgIH0pO1xuXHQgIH0sXG5cdCAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24gYmVmb3JlRGVzdHJveSgpIHtcblx0ICAgIHRoaXMudG9nZ2xlSW50ZXJ2YWwoZmFsc2UpO1xuXHQgICAgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkodGhpcy4kZWwpLm9mZignbW91c2VlbnRlciBtb3VzZWxlYXZlJyk7XG5cdCAgfVxuXHR9OyAvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXG4vKioqLyB9LFxuLyogOTQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiY2Fyb3VzZWwgc2xpZGVcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwiZGF0YS1yaWRlXCI6IFwiY2Fyb3VzZWxcIlxuXHQgICAgfVxuXHQgIH0sIFtfdm0uX2MoJ29sJywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJzaG93XCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1zaG93XCIsXG5cdCAgICAgIHZhbHVlOiAoX3ZtLmluZGljYXRvcnMpLFxuXHQgICAgICBleHByZXNzaW9uOiBcImluZGljYXRvcnNcIlxuXHQgICAgfV0sXG5cdCAgICBzdGF0aWNDbGFzczogXCJjYXJvdXNlbC1pbmRpY2F0b3JzXCJcblx0ICB9LCBfdm0uX2woKF92bS5pbmRpY2F0b3JfbGlzdCksIGZ1bmN0aW9uKGluZGljYXRvciwgaSkge1xuXHQgICAgcmV0dXJuIF92bS5fYygnbGknLCB7XG5cdCAgICAgIGNsYXNzOiB7XG5cdCAgICAgICAgYWN0aXZlOiBpID09PSBfdm0uaW5kZXhcblx0ICAgICAgfSxcblx0ICAgICAgb246IHtcblx0ICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICAgX3ZtLmluZGljYXRvckNsaWNrKGkpXG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LCBbX3ZtLl9jKCdzcGFuJyldKVxuXHQgIH0pKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJjYXJvdXNlbC1pbm5lclwiLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJyb2xlXCI6IFwibGlzdGJveFwiXG5cdCAgICB9XG5cdCAgfSwgW192bS5fdChcImRlZmF1bHRcIildLCAyKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcInNob3dcIixcblx0ICAgICAgcmF3TmFtZTogXCJ2LXNob3dcIixcblx0ICAgICAgdmFsdWU6IChfdm0uY29udHJvbHMpLFxuXHQgICAgICBleHByZXNzaW9uOiBcImNvbnRyb2xzXCJcblx0ICAgIH1dLFxuXHQgICAgc3RhdGljQ2xhc3M6IFwiY2Fyb3VzZWwtY29udHJvbHMgaGlkZGVuLXhzXCJcblx0ICB9LCBbX3ZtLl9jKCdhJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwibGVmdCBjYXJvdXNlbC1jb250cm9sXCIsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcInJvbGVcIjogXCJidXR0b25cIlxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogX3ZtLnByZXZcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZ2x5cGhpY29uIGdseXBoaWNvbi1jaGV2cm9uLWxlZnRcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwiYXJpYS1oaWRkZW5cIjogXCJ0cnVlXCJcblx0ICAgIH1cblx0ICB9KV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ2EnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJyaWdodCBjYXJvdXNlbC1jb250cm9sXCIsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcInJvbGVcIjogXCJidXR0b25cIlxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogX3ZtLm5leHRcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZ2x5cGhpY29uIGdseXBoaWNvbi1jaGV2cm9uLXJpZ2h0XCIsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImFyaWEtaGlkZGVuXCI6IFwidHJ1ZVwiXG5cdCAgICB9XG5cdCAgfSldKV0pXSlcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMzIyZGVlNDFcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiA5NSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzdHlsZXMgKi9cblx0X193ZWJwYWNrX3JlcXVpcmVfXyg5Nilcblx0XG5cdC8qIHNjcmlwdCAqL1xuXHRfX3Z1ZV9leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDk4KVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDk5KVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXENoZWNrYm94LnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0X192dWVfb3B0aW9uc19fLl9zY29wZUlkID0gXCJkYXRhLXYtNjkyMmJmMjRcIlxuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTY5MjJiZjI0XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi02OTIyYmYyNFwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIENoZWNrYm94LnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDk2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg5Nyk7XG5cdGlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuXHQvLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG5cdHZhciB1cGRhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc5KShjb250ZW50LCB7fSk7XG5cdGlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuXHQvLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5cdGlmKGZhbHNlKSB7XG5cdFx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNjkyMmJmMjQmc2NvcGVkPXRydWUhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0NoZWNrYm94LnZ1ZVwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNjkyMmJmMjQmc2NvcGVkPXRydWUhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0NoZWNrYm94LnZ1ZVwiKTtcblx0XHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDk3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc4KSgpO1xuXHQvLyBpbXBvcnRzXG5cdFxuXHRcblx0Ly8gbW9kdWxlXG5cdGV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbmxhYmVsLmNoZWNrYm94W2RhdGEtdi02OTIyYmYyNF0ge1xcclxcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcclxcbiAgcGFkZGluZy1sZWZ0OiAxOHB4O1xcbn1cXG5sYWJlbC5jaGVja2JveCA+IGlucHV0W2RhdGEtdi02OTIyYmYyNF0ge1xcclxcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHotaW5kZXg6IC0xO1xcclxcbiAgcGFkZGluZzogMDtcXHJcXG4gIG9wYWNpdHk6IDA7XFxyXFxuICBtYXJnaW46IDA7XFxufVxcbmxhYmVsLmNoZWNrYm94ID4gLmljb25bZGF0YS12LTY5MjJiZjI0XSB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IC4ycmVtO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIGRpc3BsYXk6IGJsb2NrO1xcclxcbiAgd2lkdGg6IDEuNHJlbTtcXHJcXG4gIGhlaWdodDogMS40cmVtO1xcclxcbiAgbGluZS1oZWlnaHQ6MXJlbTtcXHJcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG4gIHVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgYm9yZGVyLXJhZGl1czogLjM1cmVtO1xcclxcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXHJcXG4gIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlciBjZW50ZXI7XFxyXFxuICBiYWNrZ3JvdW5kLXNpemU6IDUwJSA1MCU7XFxufVxcbmxhYmVsLmNoZWNrYm94Om5vdCguYWN0aXZlKSA+IC5pY29uW2RhdGEtdi02OTIyYmYyNF0ge1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogI2RkZDtcXHJcXG4gIGJvcmRlcjogMXB4IHNvbGlkICNiYmI7XFxufVxcbmxhYmVsLmNoZWNrYm94ID4gaW5wdXQ6Zm9jdXMgfiAuaWNvbltkYXRhLXYtNjkyMmJmMjRdIHtcXHJcXG4gIG91dGxpbmU6IDA7XFxyXFxuICBib3JkZXI6IDFweCBzb2xpZCAjNjZhZmU5O1xcclxcbiAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggMXB4IHJnYmEoMCwwLDAsLjA3NSksMCAwIDhweCByZ2JhKDEwMiwxNzUsMjMzLC42KTtcXG59XFxubGFiZWwuY2hlY2tib3guYWN0aXZlID4gLmljb25bZGF0YS12LTY5MjJiZjI0XSB7XFxyXFxuICBiYWNrZ3JvdW5kLXNpemU6IDFyZW0gMXJlbTtcXHJcXG4gIGJhY2tncm91bmQtaW1hZ2U6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlkWFJtTFRnaVB6NE5Danh6ZG1jZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWlCM2FXUjBhRDBpTnlJZ2FHVnBaMmgwUFNJM0lqNDhjR0YwYUNCbWFXeHNQU0lqWm1abUlpQmtQU0p0TlM0M015d3dMalV5YkMwekxqRXlOREl5TERNdU16UXhOakZzTFRFdU16TTRPVFVzTFRFdU5ETXlNVEpzTFRFdU1qUTVOamtzTVM0ek16WTJOV3d5TGpVNE9EWXpMREl1TnpZNE56WnNOQzR6TnpNNUxDMDBMalkzT0RJMmJDMHhMakkwT1RZNUxDMHhMak16TmpZMWJEQXNNR3d3TGpBd01EQXlMREF1TURBd01ERjZJaTgrUEM5emRtYyspO1xcbn1cXG5sYWJlbC5jaGVja2JveC5hY3RpdmUgLmJ0bi1kZWZhdWx0W2RhdGEtdi02OTIyYmYyNF0geyBmaWx0ZXI6IGJyaWdodG5lc3MoNzUlKTtcXG59XFxubGFiZWwuY2hlY2tib3guZGlzYWJsZWRbZGF0YS12LTY5MjJiZjI0XSxcXHJcXG5sYWJlbC5jaGVja2JveC5yZWFkb25seVtkYXRhLXYtNjkyMmJmMjRdLFxcclxcbi5idG4ucmVhZG9ubHlbZGF0YS12LTY5MjJiZjI0XSB7XFxyXFxuICBmaWx0ZXI6IGFscGhhKG9wYWNpdHk9NjUpO1xcclxcbiAgYm94LXNoYWRvdzogbm9uZTtcXHJcXG4gIG9wYWNpdHk6IC42NTtcXG59XFxubGFiZWwuYnRuID4gaW5wdXRbdHlwZT1jaGVja2JveF1bZGF0YS12LTY5MjJiZjI0XSB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICBjbGlwOiByZWN0KDAsMCwwLDApO1xcclxcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvQ2hlY2tib3gudnVlPzU4YTFlNWM0XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUF1RkE7RUFDQSxtQkFBQTtFQUNBLG1CQUFBO0NBQ0E7QUFDQTtFQUNBLHVCQUFBO0VBQ0EsbUJBQUE7RUFDQSxZQUFBO0VBQ0EsV0FBQTtFQUNBLFdBQUE7RUFDQSxVQUFBO0NBQ0E7QUFDQTtFQUNBLG1CQUFBO0VBQ0EsV0FBQTtFQUNBLFFBQUE7RUFDQSxlQUFBO0VBQ0EsY0FBQTtFQUNBLGVBQUE7RUFDQSxpQkFBQTtFQUNBLG1CQUFBO0VBQ0Esa0JBQUE7RUFDQSxzQkFBQTtFQUNBLDZCQUFBO0VBQ0EsbUNBQUE7RUFDQSx5QkFBQTtDQUNBO0FBQ0E7RUFDQSx1QkFBQTtFQUNBLHVCQUFBO0NBQ0E7QUFDQTtFQUNBLFdBQUE7RUFDQSwwQkFBQTtFQUNBLDBFQUFBO0NBQ0E7QUFDQTtFQUNBLDJCQUFBO0VBQ0Esa1pBQUE7Q0FDQTtBQUNBLHNEQUFBLHdCQUFBO0NBQUE7QUFFQTs7O0VBR0EsMEJBQUE7RUFDQSxpQkFBQTtFQUNBLGFBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFQUNBLHFCQUFBO0NBQ0FcIixcImZpbGVcIjpcIkNoZWNrYm94LnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxyXFxuICA8YSA6aXM9XFxcImlzQnV0dG9uPydhJzonbGFiZWwnXFxcIiBAY2xpY2s9XFxcInRvZ2dsZVxcXCIgOmNsYXNzPVxcXCJbaXNCdXR0b24/J2J0biBidG4tJyt0eXBlQ29sb3I6J29wZW4gY2hlY2tib3ggJyt0eXBlQ29sb3Ise2FjdGl2ZTpjaGVja2VkLGRpc2FibGVkOmRpc2FibGVkLHJlYWRvbmx5OnJlYWRvbmx5fV1cXFwiPlxcclxcbiAgICA8aW5wdXQgdi1pZj1cXFwibmFtZVxcXCIgdHlwZT1cXFwiaGlkZGVuXFxcIiA6bmFtZT1cXFwibmFtZVxcXCIgOnZhbHVlPVxcXCJjaGVja2VkP3RydWVWYWx1ZTpmYWxzZVZhbHVlXFxcIiAvPlxcclxcbiAgICA8c3BhbiB2LWlmPVxcXCIhaXNCdXR0b25cXFwiIGNsYXNzPVxcXCJpY29uIGRyb3Bkb3duLXRvZ2dsZVxcXCIgOmNsYXNzPVxcXCJbY2hlY2tlZD8nYnRuLScrdHlwZUNvbG9yOicnLHtiZzp0eXBlQ29sb3I9PT0nZGVmYXVsdCd9XVxcXCI+PC9zcGFuPlxcclxcbiAgICA8c3BhbiB2LWlmPVxcXCIhaXNCdXR0b24mJmNoZWNrZWQmJnR5cGVDb2xvcj09PSdkZWZhdWx0J1xcXCIgY2xhc3M9XFxcImljb25cXFwiPjwvc3Bhbj5cXHJcXG4gICAgPHNsb3Q+PC9zbG90PlxcclxcbiAgPC9hPlxcclxcbjwvdGVtcGxhdGU+XFxyXFxuXFxyXFxuPHNjcmlwdD5cXHJcXG5leHBvcnQgZGVmYXVsdCB7XFxyXFxuICBwcm9wczoge1xcclxcbiAgICBidXR0b246IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIGRpc2FibGVkOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBmYWxzZVZhbHVlOiB7ZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBuYW1lOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgcmVhZG9ubHk6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIHRydWVWYWx1ZToge2RlZmF1bHQ6IHRydWV9LFxcclxcbiAgICB0eXBlOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgdmFsdWU6IHtkZWZhdWx0OiBmYWxzZX1cXHJcXG4gIH0sXFxyXFxuICBkYXRhICgpIHtcXHJcXG4gICAgcmV0dXJuIHtcXHJcXG4gICAgICBjaGVja2VkOiAodGhpcy52YWx1ZSA9PT0gdGhpcy50cnVlVmFsdWUpXFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBjb21wdXRlZDoge1xcclxcbiAgICBpbkdyb3VwICgpIHsgcmV0dXJuIHRoaXMuJHBhcmVudCAmJiB0aGlzLiRwYXJlbnQuYnRuR3JvdXAgJiYgIXRoaXMuJHBhcmVudC5fcmFkaW9Hcm91cCB9LFxcclxcbiAgICBpc0J1dHRvbiAoKSB7IHJldHVybiB0aGlzLmJ1dHRvbiB8fCAodGhpcy4kcGFyZW50ICYmIHRoaXMuJHBhcmVudC5idG5Hcm91cCAmJiB0aGlzLiRwYXJlbnQuYnV0dG9ucykgfSxcXHJcXG4gICAgaXNGYWxzZSAoKSB7IHJldHVybiB0aGlzLnZhbHVlID09PSB0aGlzLmZhbHNlVmFsdWUgfSxcXHJcXG4gICAgaXNUcnVlICgpIHsgcmV0dXJuIHRoaXMudmFsdWUgPT09IHRoaXMudHJ1ZVZhbHVlIH0sXFxyXFxuICAgIHBhcmVudFZhbHVlICgpIHsgcmV0dXJuIHRoaXMuJHBhcmVudC52YWwgfSxcXHJcXG4gICAgdHlwZUNvbG9yICgpIHsgcmV0dXJuICh0aGlzLnR5cGUgfHwgKHRoaXMuJHBhcmVudCAmJiB0aGlzLiRwYXJlbnQudHlwZSkpIHx8ICdkZWZhdWx0JyB9XFxyXFxuICB9LFxcclxcbiAgd2F0Y2g6IHtcXHJcXG4gICAgY2hlY2tlZCAodmFsLCBvbGQpIHtcXHJcXG4gICAgICB2YXIgdmFsdWUgPSB2YWwgPyB0aGlzLnRydWVWYWx1ZSA6IHRoaXMuZmFsc2VWYWx1ZVxcclxcbiAgICAgIHRoaXMuJGVtaXQoJ2NoZWNrZWQnLCB2YWwpXFxyXFxuICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCB2YWx1ZSk7XFxyXFxuICAgICAgdGhpcy51cGRhdGVQYXJlbnQoKVxcclxcbiAgICB9LFxcclxcbiAgICBwYXJlbnRWYWx1ZSAodmFsKSB7XFxyXFxuICAgICAgdGhpcy51cGRhdGVGcm9tUGFyZW50KCk7XFxyXFxuICAgIH0sXFxyXFxuICAgIHZhbHVlICh2YWwsIG9sZCkge1xcclxcbiAgICAgIHZhciBjaGVja2VkID0gdmFsID09PSB0aGlzLnRydWVWYWx1ZVxcclxcbiAgICAgIGlmICh0aGlzLmNoZWNrZWQgIT09IGNoZWNrZWQpIHtcXHJcXG4gICAgICAgIHRoaXMuY2hlY2tlZCA9IGNoZWNrZWRcXHJcXG4gICAgICB9XFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBjcmVhdGVkICgpIHtcXHJcXG4gICAgaWYgKHRoaXMuaW5Hcm91cCkge1xcclxcbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuJHBhcmVudFxcclxcbiAgICAgIHBhcmVudC5fY2hlY2tib3hHcm91cCA9IHRydWVcXHJcXG4gICAgICBpZiAoIShwYXJlbnQudmFsIGluc3RhbmNlb2YgQXJyYXkpKSB7IHBhcmVudC52YWwgPSBbXSB9XFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBtb3VudGVkICgpIHtcXHJcXG4gICAgdGhpcy51cGRhdGVGcm9tUGFyZW50KCk7XFxyXFxuICB9LFxcclxcbiAgbWV0aG9kczoge1xcclxcbiAgICAvLyBjYWxsZWQgQCBtb3VudGVkKCksIG9yIHdoZW5ldmVyICRwYXJlbnQudmFsIGNoYW5nZXNcXHJcXG4gICAgLy8gc3luYyBvdXIgc3RhdGUgd2l0aCB0aGUgJHBhcmVudC52YWxcXHJcXG4gICAgdXBkYXRlRnJvbVBhcmVudCgpIHtcXHJcXG4gICAgICBpZiAodGhpcy5pbkdyb3VwKSB7XFxyXFxuICAgICAgICB2YXIgaW5kZXggPSB0aGlzLiRwYXJlbnQudmFsLmluZGV4T2YodGhpcy50cnVlVmFsdWUpXFxyXFxuICAgICAgICB0aGlzLmNoZWNrZWQgPSB+aW5kZXhcXHJcXG4gICAgICB9XFxyXFxuICAgIH0sXFxyXFxuICAgIC8vIGNhbGxlZCB3aGVuIG91ciBjaGVja2VkIHN0YXRlIGNoYW5nZXNcXHJcXG4gICAgdXBkYXRlUGFyZW50KCkge1xcclxcbiAgICAgIGlmICh0aGlzLmluR3JvdXApIHtcXHJcXG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMuJHBhcmVudC52YWwuaW5kZXhPZih0aGlzLnRydWVWYWx1ZSlcXHJcXG4gICAgICAgIGlmICh0aGlzLmNoZWNrZWQgJiYgIX5pbmRleCkgdGhpcy4kcGFyZW50LnZhbC5wdXNoKHRoaXMudHJ1ZVZhbHVlKVxcclxcbiAgICAgICAgaWYgKCF0aGlzLmNoZWNrZWQgJiYgfmluZGV4KSB0aGlzLiRwYXJlbnQudmFsLnNwbGljZShpbmRleCwgMSlcXHJcXG4gICAgICB9XFxyXFxuICAgIH0sXFxyXFxuICAgIHRvZ2dsZSAoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5yZWFkb25seSkgeyByZXR1cm4gfVxcclxcbiAgICAgIHRoaXMuY2hlY2tlZCA9ICF0aGlzLmNoZWNrZWRcXHJcXG4gICAgfVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGUgc2NvcGVkPlxcclxcbmxhYmVsLmNoZWNrYm94IHtcXHJcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gIHBhZGRpbmctbGVmdDogMThweDtcXHJcXG59XFxyXFxubGFiZWwuY2hlY2tib3ggPiBpbnB1dCB7XFxyXFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcclxcbiAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgei1pbmRleDogLTE7XFxyXFxuICBwYWRkaW5nOiAwO1xcclxcbiAgb3BhY2l0eTogMDtcXHJcXG4gIG1hcmdpbjogMDtcXHJcXG59XFxyXFxubGFiZWwuY2hlY2tib3ggPiAuaWNvbiB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IC4ycmVtO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIGRpc3BsYXk6IGJsb2NrO1xcclxcbiAgd2lkdGg6IDEuNHJlbTtcXHJcXG4gIGhlaWdodDogMS40cmVtO1xcclxcbiAgbGluZS1oZWlnaHQ6MXJlbTtcXHJcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG4gIHVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgYm9yZGVyLXJhZGl1czogLjM1cmVtO1xcclxcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXHJcXG4gIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlciBjZW50ZXI7XFxyXFxuICBiYWNrZ3JvdW5kLXNpemU6IDUwJSA1MCU7XFxyXFxufVxcclxcbmxhYmVsLmNoZWNrYm94Om5vdCguYWN0aXZlKSA+IC5pY29uIHtcXHJcXG4gIGJhY2tncm91bmQtY29sb3I6ICNkZGQ7XFxyXFxuICBib3JkZXI6IDFweCBzb2xpZCAjYmJiO1xcclxcbn1cXHJcXG5sYWJlbC5jaGVja2JveCA+IGlucHV0OmZvY3VzIH4gLmljb24ge1xcclxcbiAgb3V0bGluZTogMDtcXHJcXG4gIGJvcmRlcjogMXB4IHNvbGlkICM2NmFmZTk7XFxyXFxuICBib3gtc2hhZG93OiBpbnNldCAwIDFweCAxcHggcmdiYSgwLDAsMCwuMDc1KSwwIDAgOHB4IHJnYmEoMTAyLDE3NSwyMzMsLjYpO1xcclxcbn1cXHJcXG5sYWJlbC5jaGVja2JveC5hY3RpdmUgPiAuaWNvbiB7XFxyXFxuICBiYWNrZ3JvdW5kLXNpemU6IDFyZW0gMXJlbTtcXHJcXG4gIGJhY2tncm91bmQtaW1hZ2U6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlkWFJtTFRnaVB6NE5Danh6ZG1jZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWlCM2FXUjBhRDBpTnlJZ2FHVnBaMmgwUFNJM0lqNDhjR0YwYUNCbWFXeHNQU0lqWm1abUlpQmtQU0p0TlM0M015d3dMalV5YkMwekxqRXlOREl5TERNdU16UXhOakZzTFRFdU16TTRPVFVzTFRFdU5ETXlNVEpzTFRFdU1qUTVOamtzTVM0ek16WTJOV3d5TGpVNE9EWXpMREl1TnpZNE56WnNOQzR6TnpNNUxDMDBMalkzT0RJMmJDMHhMakkwT1RZNUxDMHhMak16TmpZMWJEQXNNR3d3TGpBd01EQXlMREF1TURBd01ERjZJaTgrUEM5emRtYyspO1xcclxcbn1cXHJcXG5sYWJlbC5jaGVja2JveC5hY3RpdmUgLmJ0bi1kZWZhdWx0IHsgZmlsdGVyOiBicmlnaHRuZXNzKDc1JSk7IH1cXHJcXG5cXHJcXG5sYWJlbC5jaGVja2JveC5kaXNhYmxlZCxcXHJcXG5sYWJlbC5jaGVja2JveC5yZWFkb25seSxcXHJcXG4uYnRuLnJlYWRvbmx5IHtcXHJcXG4gIGZpbHRlcjogYWxwaGEob3BhY2l0eT02NSk7XFxyXFxuICBib3gtc2hhZG93OiBub25lO1xcclxcbiAgb3BhY2l0eTogLjY1O1xcclxcbn1cXHJcXG5sYWJlbC5idG4gPiBpbnB1dFt0eXBlPWNoZWNrYm94XSB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICBjbGlwOiByZWN0KDAsMCwwLDApO1xcclxcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxyXFxufVxcclxcbjwvc3R5bGU+XFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXHRcblx0Ly8gZXhwb3J0c1xuXG5cbi8qKiovIH0sXG4vKiA5OCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgcHJvcHM6IHtcblx0ICAgIGJ1dHRvbjogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgZGlzYWJsZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGZhbHNlVmFsdWU6IHsgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIG5hbWU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICByZWFkb25seTogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgdHJ1ZVZhbHVlOiB7IGRlZmF1bHQ6IHRydWUgfSxcblx0ICAgIHR5cGU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICB2YWx1ZTogeyBkZWZhdWx0OiBmYWxzZSB9XG5cdCAgfSxcblx0ICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgY2hlY2tlZDogdGhpcy52YWx1ZSA9PT0gdGhpcy50cnVlVmFsdWVcblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgY29tcHV0ZWQ6IHtcblx0ICAgIGluR3JvdXA6IGZ1bmN0aW9uIGluR3JvdXAoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50LmJ0bkdyb3VwICYmICF0aGlzLiRwYXJlbnQuX3JhZGlvR3JvdXA7XG5cdCAgICB9LFxuXHQgICAgaXNCdXR0b246IGZ1bmN0aW9uIGlzQnV0dG9uKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5idXR0b24gfHwgdGhpcy4kcGFyZW50ICYmIHRoaXMuJHBhcmVudC5idG5Hcm91cCAmJiB0aGlzLiRwYXJlbnQuYnV0dG9ucztcblx0ICAgIH0sXG5cdCAgICBpc0ZhbHNlOiBmdW5jdGlvbiBpc0ZhbHNlKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZSA9PT0gdGhpcy5mYWxzZVZhbHVlO1xuXHQgICAgfSxcblx0ICAgIGlzVHJ1ZTogZnVuY3Rpb24gaXNUcnVlKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZSA9PT0gdGhpcy50cnVlVmFsdWU7XG5cdCAgICB9LFxuXHQgICAgcGFyZW50VmFsdWU6IGZ1bmN0aW9uIHBhcmVudFZhbHVlKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy4kcGFyZW50LnZhbDtcblx0ICAgIH0sXG5cdCAgICB0eXBlQ29sb3I6IGZ1bmN0aW9uIHR5cGVDb2xvcigpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudHlwZSB8fCB0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50LnR5cGUgfHwgJ2RlZmF1bHQnO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgd2F0Y2g6IHtcblx0ICAgIGNoZWNrZWQ6IGZ1bmN0aW9uIGNoZWNrZWQodmFsLCBvbGQpIHtcblx0ICAgICAgdmFyIHZhbHVlID0gdmFsID8gdGhpcy50cnVlVmFsdWUgOiB0aGlzLmZhbHNlVmFsdWU7XG5cdCAgICAgIHRoaXMuJGVtaXQoJ2NoZWNrZWQnLCB2YWwpO1xuXHQgICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbHVlKTtcblx0ICAgICAgdGhpcy51cGRhdGVQYXJlbnQoKTtcblx0ICAgIH0sXG5cdCAgICBwYXJlbnRWYWx1ZTogZnVuY3Rpb24gcGFyZW50VmFsdWUodmFsKSB7XG5cdCAgICAgIHRoaXMudXBkYXRlRnJvbVBhcmVudCgpO1xuXHQgICAgfSxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZSh2YWwsIG9sZCkge1xuXHQgICAgICB2YXIgY2hlY2tlZCA9IHZhbCA9PT0gdGhpcy50cnVlVmFsdWU7XG5cdCAgICAgIGlmICh0aGlzLmNoZWNrZWQgIT09IGNoZWNrZWQpIHtcblx0ICAgICAgICB0aGlzLmNoZWNrZWQgPSBjaGVja2VkO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBjcmVhdGVkOiBmdW5jdGlvbiBjcmVhdGVkKCkge1xuXHQgICAgaWYgKHRoaXMuaW5Hcm91cCkge1xuXHQgICAgICB2YXIgcGFyZW50ID0gdGhpcy4kcGFyZW50O1xuXHQgICAgICBwYXJlbnQuX2NoZWNrYm94R3JvdXAgPSB0cnVlO1xuXHQgICAgICBpZiAoIShwYXJlbnQudmFsIGluc3RhbmNlb2YgQXJyYXkpKSB7XG5cdCAgICAgICAgcGFyZW50LnZhbCA9IFtdO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkKCkge1xuXHQgICAgdGhpcy51cGRhdGVGcm9tUGFyZW50KCk7XG5cdCAgfSxcblx0XG5cdCAgbWV0aG9kczoge1xuXHQgICAgLy8gY2FsbGVkIEAgbW91bnRlZCgpLCBvciB3aGVuZXZlciAkcGFyZW50LnZhbCBjaGFuZ2VzXG5cdCAgICAvLyBzeW5jIG91ciBzdGF0ZSB3aXRoIHRoZSAkcGFyZW50LnZhbFxuXHQgICAgdXBkYXRlRnJvbVBhcmVudDogZnVuY3Rpb24gdXBkYXRlRnJvbVBhcmVudCgpIHtcblx0ICAgICAgaWYgKHRoaXMuaW5Hcm91cCkge1xuXHQgICAgICAgIHZhciBpbmRleCA9IHRoaXMuJHBhcmVudC52YWwuaW5kZXhPZih0aGlzLnRydWVWYWx1ZSk7XG5cdCAgICAgICAgdGhpcy5jaGVja2VkID0gfmluZGV4O1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHRcblx0ICAgIC8vIGNhbGxlZCB3aGVuIG91ciBjaGVja2VkIHN0YXRlIGNoYW5nZXNcblx0ICAgIHVwZGF0ZVBhcmVudDogZnVuY3Rpb24gdXBkYXRlUGFyZW50KCkge1xuXHQgICAgICBpZiAodGhpcy5pbkdyb3VwKSB7XG5cdCAgICAgICAgdmFyIGluZGV4ID0gdGhpcy4kcGFyZW50LnZhbC5pbmRleE9mKHRoaXMudHJ1ZVZhbHVlKTtcblx0ICAgICAgICBpZiAodGhpcy5jaGVja2VkICYmICF+aW5kZXgpIHRoaXMuJHBhcmVudC52YWwucHVzaCh0aGlzLnRydWVWYWx1ZSk7XG5cdCAgICAgICAgaWYgKCF0aGlzLmNoZWNrZWQgJiYgfmluZGV4KSB0aGlzLiRwYXJlbnQudmFsLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB0b2dnbGU6IGZ1bmN0aW9uIHRvZ2dsZSgpIHtcblx0ICAgICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5yZWFkb25seSkge1xuXHQgICAgICAgIHJldHVybjtcblx0ICAgICAgfVxuXHQgICAgICB0aGlzLmNoZWNrZWQgPSAhdGhpcy5jaGVja2VkO1xuXHQgICAgfVxuXHQgIH1cblx0fTtcblxuLyoqKi8gfSxcbi8qIDk5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoX3ZtLmlzQnV0dG9uID8gJ2EnIDogJ2xhYmVsJywge1xuXHQgICAgdGFnOiBcImFcIixcblx0ICAgIGNsYXNzOiBbX3ZtLmlzQnV0dG9uID8gJ2J0biBidG4tJyArIF92bS50eXBlQ29sb3IgOiAnb3BlbiBjaGVja2JveCAnICsgX3ZtLnR5cGVDb2xvciwge1xuXHQgICAgICBhY3RpdmU6IF92bS5jaGVja2VkLFxuXHQgICAgICBkaXNhYmxlZDogX3ZtLmRpc2FibGVkLFxuXHQgICAgICByZWFkb25seTogX3ZtLnJlYWRvbmx5XG5cdCAgICB9XSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogX3ZtLnRvZ2dsZVxuXHQgICAgfVxuXHQgIH0sIFsoX3ZtLm5hbWUpID8gX3ZtLl9jKCdpbnB1dCcsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcImhpZGRlblwiLFxuXHQgICAgICBcIm5hbWVcIjogX3ZtLm5hbWVcblx0ICAgIH0sXG5cdCAgICBkb21Qcm9wczoge1xuXHQgICAgICBcInZhbHVlXCI6IF92bS5jaGVja2VkID8gX3ZtLnRydWVWYWx1ZSA6IF92bS5mYWxzZVZhbHVlXG5cdCAgICB9XG5cdCAgfSkgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgKCFfdm0uaXNCdXR0b24pID8gX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiaWNvbiBkcm9wZG93bi10b2dnbGVcIixcblx0ICAgIGNsYXNzOiBbX3ZtLmNoZWNrZWQgPyAnYnRuLScgKyBfdm0udHlwZUNvbG9yIDogJycsIHtcblx0ICAgICAgYmc6IF92bS50eXBlQ29sb3IgPT09ICdkZWZhdWx0J1xuXHQgICAgfV1cblx0ICB9KSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCAoIV92bS5pc0J1dHRvbiAmJiBfdm0uY2hlY2tlZCAmJiBfdm0udHlwZUNvbG9yID09PSAnZGVmYXVsdCcpID8gX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiaWNvblwiXG5cdCAgfSkgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl90KFwiZGVmYXVsdFwiKV0sIDIpXG5cdH0sc3RhdGljUmVuZGVyRm5zOiBbXX1cblx0aWYgKGZhbHNlKSB7XG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LTY5MjJiZjI0XCIsIG1vZHVsZS5leHBvcnRzKVxuXHQgIH1cblx0fVxuXG4vKioqLyB9LFxuLyogMTAwICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgX192dWVfZXhwb3J0c19fLCBfX3Z1ZV9vcHRpb25zX19cblx0dmFyIF9fdnVlX3N0eWxlc19fID0ge31cblx0XG5cdC8qIHN0eWxlcyAqL1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDEwMSlcblx0XG5cdC8qIHNjcmlwdCAqL1xuXHRfX3Z1ZV9leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEwMylcblx0XG5cdC8qIHRlbXBsYXRlICovXG5cdHZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMDQpXG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuXHRpZiAoXG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcblx0KSB7XG5cdGlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxuXHR9XG5cdGlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcblx0ICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xuXHR9XG5cdF9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIkM6XFxcXGxhcmFnb25cXFxcd3d3XFxcXHZ1ZS1zdHJhcFxcXFxzcmNcXFxcRGF0ZXBpY2tlci52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNDc3YjhlNWRcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTQ3N2I4ZTVkXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gRGF0ZXBpY2tlci52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IF9fdnVlX2V4cG9ydHNfX1xuXG5cbi8qKiovIH0sXG4vKiAxMDEgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cdFxuXHQvLyBsb2FkIHRoZSBzdHlsZXNcblx0dmFyIGNvbnRlbnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEwMik7XG5cdGlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuXHQvLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG5cdHZhciB1cGRhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc5KShjb250ZW50LCB7fSk7XG5cdGlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuXHQvLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5cdGlmKGZhbHNlKSB7XG5cdFx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNDc3YjhlNWQhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0RhdGVwaWNrZXIudnVlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi00NzdiOGU1ZCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vRGF0ZXBpY2tlci52dWVcIik7XG5cdFx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xuXHR9XG5cbi8qKiovIH0sXG4vKiAxMDIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oNzgpKCk7XG5cdC8vIGltcG9ydHNcblx0XG5cdFxuXHQvLyBtb2R1bGVcblx0ZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuLmRhdGVwaWNrZXIge1xcclxcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcclxcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcbn1cXG5pbnB1dC5kYXRlcGlja2VyLWlucHV0LndpdGgtcmVzZXQtYnV0dG9uIHtcXHJcXG4gIHBhZGRpbmctcmlnaHQ6IDI1cHg7XFxufVxcbi5kYXRlcGlja2VyID4gYnV0dG9uLmNsb3NlIHtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHRvcDogMDtcXHJcXG4gIHJpZ2h0OiAwO1xcclxcbiAgb3V0bGluZTogbm9uZTtcXHJcXG4gIHotaW5kZXg6IDI7XFxyXFxuICBkaXNwbGF5OiBibG9jaztcXHJcXG4gIHdpZHRoOiAzNHB4O1xcclxcbiAgaGVpZ2h0OiAzNHB4O1xcclxcbiAgbGluZS1oZWlnaHQ6IDM0cHg7XFxyXFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxufVxcbi5kYXRlcGlja2VyID4gYnV0dG9uLmNsb3NlOmZvY3VzIHtcXHJcXG4gIG9wYWNpdHk6IC4yO1xcbn1cXG4uZGF0ZXBpY2tlci1wb3B1cCB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICBib3JkZXI6IDFweCBzb2xpZCAjY2NjO1xcclxcbiAgYm9yZGVyLXJhZGl1czogNXB4O1xcclxcbiAgYmFja2dyb3VuZDogI2ZmZjtcXHJcXG4gIG1hcmdpbi10b3A6IDJweDtcXHJcXG4gIHotaW5kZXg6IDEwMDA7XFxyXFxuICBib3gtc2hhZG93OiAwIDZweCAxMnB4IHJnYmEoMCwwLDAsMC4xNzUpO1xcbn1cXG4uZGF0ZXBpY2tlci1pbm5lciB7XFxyXFxuICB3aWR0aDogMjE4cHg7XFxufVxcbi5kYXRlcGlja2VyLWJvZHkge1xcclxcbiAgcGFkZGluZzogMTBweCAxMHB4O1xcbn1cXG4uZGF0ZXBpY2tlci1jdHJsIHAsXFxyXFxuLmRhdGVwaWNrZXItY3RybCBzcGFuLFxcclxcbi5kYXRlcGlja2VyLWJvZHkgc3BhbiB7XFxyXFxuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuICB3aWR0aDogMjhweDtcXHJcXG4gIGxpbmUtaGVpZ2h0OiAyOHB4O1xcclxcbiAgaGVpZ2h0OiAyOHB4O1xcclxcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xcbn1cXG4uZGF0ZXBpY2tlci1jdHJsIHAge1xcclxcbiAgd2lkdGg6IDY1JTtcXG59XFxuLmRhdGVwaWNrZXItY3RybCBzcGFuIHtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG59XFxuLmRhdGVwaWNrZXItYm9keSBzcGFuIHtcXHJcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXG59XFxuLmRhdGVwaWNrZXItbW9udGhSYW5nZSBzcGFuIHtcXHJcXG4gIHdpZHRoOiA0OHB4O1xcclxcbiAgaGVpZ2h0OiA1MHB4O1xcclxcbiAgbGluZS1oZWlnaHQ6IDQ1cHg7XFxufVxcbi5kYXRlcGlja2VyLWl0ZW0tZGlzYWJsZSB7XFxyXFxuICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZSFpbXBvcnRhbnQ7XFxyXFxuICBjdXJzb3I6IG5vdC1hbGxvd2VkIWltcG9ydGFudDtcXG59XFxuLmRlY2FkZVJhbmdlIHNwYW46Zmlyc3QtY2hpbGQsXFxyXFxuLmRlY2FkZVJhbmdlIHNwYW46bGFzdC1jaGlsZCxcXHJcXG4uZGF0ZXBpY2tlci1pdGVtLWRpc2FibGUsXFxyXFxuLmRhdGVwaWNrZXItaXRlbS1ncmF5IHtcXHJcXG4gIGNvbG9yOiAjOTk5O1xcbn1cXG4uZGF0ZXBpY2tlci1kYXRlUmFuZ2UtaXRlbS1hY3RpdmU6aG92ZXIsXFxyXFxuLmRhdGVwaWNrZXItZGF0ZVJhbmdlLWl0ZW0tYWN0aXZlIHtcXHJcXG4gIGJhY2tncm91bmQ6IHJnYig1MCwgMTE4LCAxNzcpIWltcG9ydGFudDtcXHJcXG4gIGNvbG9yOiB3aGl0ZSFpbXBvcnRhbnQ7XFxufVxcbi5kYXRlcGlja2VyLW1vbnRoUmFuZ2Uge1xcclxcbiAgbWFyZ2luLXRvcDogMTBweFxcbn1cXG4uZGF0ZXBpY2tlci1tb250aFJhbmdlIHNwYW4sXFxyXFxuLmRhdGVwaWNrZXItY3RybCBzcGFuLFxcclxcbi5kYXRlcGlja2VyLWN0cmwgcCxcXHJcXG4uZGF0ZXBpY2tlci1kYXRlUmFuZ2Ugc3BhbiB7XFxyXFxuICBjdXJzb3I6IHBvaW50ZXI7XFxufVxcbi5kYXRlcGlja2VyLW1vbnRoUmFuZ2Ugc3Bhbjpob3ZlcixcXHJcXG4uZGF0ZXBpY2tlci1jdHJsIHA6aG92ZXIsXFxyXFxuLmRhdGVwaWNrZXItY3RybCBpOmhvdmVyLFxcclxcbi5kYXRlcGlja2VyLWRhdGVSYW5nZSBzcGFuOmhvdmVyLFxcclxcbi5kYXRlcGlja2VyLWRhdGVSYW5nZS1pdGVtLWhvdmVyIHtcXHJcXG4gIGJhY2tncm91bmQtY29sb3IgOiAjZWVlZWVlO1xcbn1cXG4uZGF0ZXBpY2tlci13ZWVrUmFuZ2Ugc3BhbiB7XFxyXFxuICBmb250LXdlaWdodDogYm9sZDtcXG59XFxuLmRhdGVwaWNrZXItbGFiZWwge1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogI2Y4ZjhmODtcXHJcXG4gIGZvbnQtd2VpZ2h0OiA3MDA7XFxyXFxuICBwYWRkaW5nOiA3cHggMDtcXHJcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXG59XFxuLmRhdGVwaWNrZXItY3RybCB7XFxyXFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICBoZWlnaHQ6IDMwcHg7XFxyXFxuICBsaW5lLWhlaWdodDogMzBweDtcXHJcXG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcbn1cXG4ubW9udGgtYnRuIHtcXHJcXG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xcclxcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDpub25lO1xcclxcbiAgLW1vei11c2VyLXNlbGVjdDpub25lO1xcclxcbiAgLW1zLXVzZXItc2VsZWN0Om5vbmU7XFxyXFxuICB1c2VyLXNlbGVjdDpub25lO1xcbn1cXG4uZGF0ZXBpY2tlci1wcmVCdG4ge1xcclxcbiAgbGVmdDogMnB4O1xcbn1cXG4uZGF0ZXBpY2tlci1uZXh0QnRuIHtcXHJcXG4gIHJpZ2h0OiAycHg7XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvRGF0ZXBpY2tlci52dWU/NTIwMDZmNmNcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQWlWQTtFQUNBLG1CQUFBO0VBQ0Esc0JBQUE7Q0FDQTtBQUNBO0VBQ0Esb0JBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxPQUFBO0VBQ0EsU0FBQTtFQUNBLGNBQUE7RUFDQSxXQUFBO0VBQ0EsZUFBQTtFQUNBLFlBQUE7RUFDQSxhQUFBO0VBQ0Esa0JBQUE7RUFDQSxtQkFBQTtDQUNBO0FBQ0E7RUFDQSxZQUFBO0NBQ0E7QUFDQTtFQUNBLG1CQUFBO0VBQ0EsdUJBQUE7RUFDQSxtQkFBQTtFQUNBLGlCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxjQUFBO0VBQ0EseUNBQUE7Q0FDQTtBQUNBO0VBQ0EsYUFBQTtDQUNBO0FBQ0E7RUFDQSxtQkFBQTtDQUNBO0FBQ0E7OztFQUdBLHNCQUFBO0VBQ0EsWUFBQTtFQUNBLGtCQUFBO0VBQ0EsYUFBQTtFQUNBLG1CQUFBO0NBQ0E7QUFDQTtFQUNBLFdBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7Q0FDQTtBQUNBO0VBQ0EsWUFBQTtFQUNBLGFBQUE7RUFDQSxrQkFBQTtDQUNBO0FBQ0E7RUFDQSxrQ0FBQTtFQUNBLDhCQUFBO0NBQ0E7QUFDQTs7OztFQUlBLFlBQUE7Q0FDQTtBQUVBOztFQUVBLHdDQUFBO0VBQ0EsdUJBQUE7Q0FDQTtBQUNBO0VBQ0EsZ0JBQUE7Q0FDQTtBQUNBOzs7O0VBSUEsZ0JBQUE7Q0FDQTtBQUNBOzs7OztFQUtBLDJCQUFBO0NBQ0E7QUFDQTtFQUNBLGtCQUFBO0NBQ0E7QUFDQTtFQUNBLDBCQUFBO0VBQ0EsaUJBQUE7RUFDQSxlQUFBO0VBQ0EsbUJBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxhQUFBO0VBQ0Esa0JBQUE7RUFDQSxrQkFBQTtFQUNBLG1CQUFBO0NBQ0E7QUFDQTtFQUNBLGtCQUFBO0VBQ0EseUJBQUE7RUFDQSxzQkFBQTtFQUNBLHFCQUFBO0VBQ0EsaUJBQUE7Q0FDQTtBQUNBO0VBQ0EsVUFBQTtDQUNBO0FBQ0E7RUFDQSxXQUFBO0NBQ0FcIixcImZpbGVcIjpcIkRhdGVwaWNrZXIudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxkaXYgY2xhc3M9XFxcImRhdGVwaWNrZXJcXFwiPlxcclxcbiAgICA8aW5wdXQgY2xhc3M9XFxcImZvcm0tY29udHJvbCBkYXRlcGlja2VyLWlucHV0XFxcIiB0eXBlPVxcXCJ0ZXh0XFxcIlxcclxcbiAgICAgIHYtbW9kZWw9XFxcInZhbFxcXCJcXHJcXG4gICAgICA6Y2xhc3M9XFxcInsnd2l0aC1yZXNldC1idXR0b24nOiBjbGVhckJ1dHRvbn1cXFwiXFxyXFxuICAgICAgOnBsYWNlaG9sZGVyPVxcXCJwbGFjZWhvbGRlclxcXCJcXHJcXG4gICAgICA6c3R5bGU9XFxcInt3aWR0aDp3aWR0aH1cXFwiXFxyXFxuICAgICAgQGNsaWNrPVxcXCJpbnB1dENsaWNrXFxcIlxcclxcbiAgICAvPlxcclxcbiAgICA8YnV0dG9uIHYtaWY9XFxcImNsZWFyQnV0dG9uJiZ2YWxcXFwiIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImNsb3NlXFxcIiBAY2xpY2s9XFxcInZhbCA9ICcnXFxcIj5cXHJcXG4gICAgICA8c3Bhbj4mdGltZXM7PC9zcGFuPlxcclxcbiAgICA8L2J1dHRvbj5cXHJcXG4gICAgPGRpdiBjbGFzcz1cXFwiZGF0ZXBpY2tlci1wb3B1cFxcXCIgdi1zaG93PVxcXCJkaXNwbGF5RGF5Vmlld1xcXCI+XFxyXFxuICAgICAgPGRpdiBjbGFzcz1cXFwiZGF0ZXBpY2tlci1pbm5lclxcXCI+XFxyXFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLWJvZHlcXFwiPlxcclxcbiAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLWN0cmxcXFwiPlxcclxcbiAgICAgICAgICAgIDxzcGFuIDpjbGFzcz1cXFwicHJlQnRuQ2xhc3Nlc1xcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiIEBjbGljaz1cXFwicHJlTmV4dE1vbnRoQ2xpY2soMClcXFwiPjwvc3Bhbj5cXHJcXG4gICAgICAgICAgICA8c3BhbiA6Y2xhc3M9XFxcIm5leHRCdG5DbGFzc2VzXFxcIiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCIgQGNsaWNrPVxcXCJwcmVOZXh0TW9udGhDbGljaygxKVxcXCI+PC9zcGFuPlxcclxcbiAgICAgICAgICAgIDxwIEBjbGljaz1cXFwic3dpdGNoTW9udGhWaWV3XFxcIj57e3N0cmluZ2lmeURheUhlYWRlcihjdXJyRGF0ZSl9fTwvcD5cXHJcXG4gICAgICAgICAgPC9kaXY+XFxyXFxuICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImRhdGVwaWNrZXItd2Vla1JhbmdlXFxcIj5cXHJcXG4gICAgICAgICAgICA8c3BhbiB2LWZvcj1cXFwidyBpbiB0ZXh0LmRheXNPZldlZWtcXFwiPnt7d319PC9zcGFuPlxcclxcbiAgICAgICAgICA8L2Rpdj5cXHJcXG4gICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZGF0ZXBpY2tlci1kYXRlUmFuZ2VcXFwiPlxcclxcbiAgICAgICAgICAgIDxzcGFuIHYtZm9yPVxcXCJkIGluIGRhdGVSYW5nZVxcXCIgOmNsYXNzPVxcXCJkLnNjbGFzc1xcXCIgQGNsaWNrPVxcXCJkYXlTZWxlY3QoZClcXFwiPnt7ZC50ZXh0fX08L3NwYW4+XFxyXFxuICAgICAgICAgIDwvZGl2PlxcclxcbiAgICAgICAgPC9kaXY+XFxyXFxuICAgICAgPC9kaXY+XFxyXFxuICAgIDwvZGl2PlxcclxcbiAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLXBvcHVwXFxcIiB2LXNob3c9XFxcImRpc3BsYXlNb250aFZpZXdcXFwiPlxcclxcbiAgICAgIDxkaXYgY2xhc3M9XFxcImRhdGVwaWNrZXItaW5uZXJcXFwiPlxcclxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwiZGF0ZXBpY2tlci1ib2R5XFxcIj5cXHJcXG4gICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZGF0ZXBpY2tlci1jdHJsXFxcIj5cXHJcXG4gICAgICAgICAgICA8c3BhbiA6Y2xhc3M9XFxcInByZUJ0bkNsYXNzZXNcXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIiBAY2xpY2s9XFxcInByZU5leHRZZWFyQ2xpY2soMClcXFwiPjwvc3Bhbj5cXHJcXG4gICAgICAgICAgICA8c3BhbiA6Y2xhc3M9XFxcIm5leHRCdG5DbGFzc2VzXFxcIiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCIgQGNsaWNrPVxcXCJwcmVOZXh0WWVhckNsaWNrKDEpXFxcIj48L3NwYW4+XFxyXFxuICAgICAgICAgICAgPHAgQGNsaWNrPVxcXCJzd2l0Y2hEZWNhZGVWaWV3XFxcIj57e3N0cmluZ2lmeVllYXJIZWFkZXIoY3VyckRhdGUpfX08L3A+XFxyXFxuICAgICAgICAgIDwvZGl2PlxcclxcbiAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLW1vbnRoUmFuZ2VcXFwiPlxcclxcbiAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWZvcj1cXFwiKG0sIGluZGV4KSBpbiB0ZXh0Lm1vbnRoc1xcXCI+XFxyXFxuICAgICAgICAgICAgICA8c3BhbiB2LXRleHQ9XFxcIm0uc3Vic3RyKDAsMylcXFwiXFxyXFxuICAgICAgICAgICAgICAgIDpjbGFzcz1cXFwieydkYXRlcGlja2VyLWRhdGVSYW5nZS1pdGVtLWFjdGl2ZSc6XFxyXFxuICAgICAgICAgICAgICAgICAgKHRleHQubW9udGhzW3BhcnNlKHZhbCkuZ2V0TW9udGgoKV0gPT09IG0pICYmXFxyXFxuICAgICAgICAgICAgICAgICAgY3VyckRhdGUuZ2V0RnVsbFllYXIoKSA9PT0gcGFyc2UodmFsKS5nZXRGdWxsWWVhcigpfVxcXCJcXHJcXG4gICAgICAgICAgICAgICAgQGNsaWNrPVxcXCJtb250aFNlbGVjdChpbmRleClcXFwiXFxyXFxuICAgICAgICAgICAgICA+PC9zcGFuPlxcclxcbiAgICAgICAgICAgIDwvdGVtcGxhdGU+XFxyXFxuICAgICAgICAgIDwvZGl2PlxcclxcbiAgICAgICAgPC9kaXY+XFxyXFxuICAgICAgPC9kaXY+XFxyXFxuICAgIDwvZGl2PlxcclxcbiAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLXBvcHVwXFxcIiB2LXNob3c9XFxcImRpc3BsYXlZZWFyVmlld1xcXCI+XFxyXFxuICAgICAgPGRpdiBjbGFzcz1cXFwiZGF0ZXBpY2tlci1pbm5lclxcXCI+XFxyXFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLWJvZHlcXFwiPlxcclxcbiAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLWN0cmxcXFwiPlxcclxcbiAgICAgICAgICAgIDxzcGFuIDpjbGFzcz1cXFwicHJlQnRuQ2xhc3Nlc1xcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiIEBjbGljaz1cXFwicHJlTmV4dERlY2FkZUNsaWNrKDApXFxcIj48L3NwYW4+XFxyXFxuICAgICAgICAgICAgPHNwYW4gOmNsYXNzPVxcXCJuZXh0QnRuQ2xhc3Nlc1xcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiIEBjbGljaz1cXFwicHJlTmV4dERlY2FkZUNsaWNrKDEpXFxcIj48L3NwYW4+XFxyXFxuICAgICAgICAgICAgPHA+e3tzdHJpbmdpZnlEZWNhZGVIZWFkZXIoY3VyckRhdGUpfX08L3A+XFxyXFxuICAgICAgICAgIDwvZGl2PlxcclxcbiAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJkYXRlcGlja2VyLW1vbnRoUmFuZ2UgZGVjYWRlUmFuZ2VcXFwiPlxcclxcbiAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWZvcj1cXFwiZGVjYWRlIGluIGRlY2FkZVJhbmdlXFxcIj5cXHJcXG4gICAgICAgICAgICAgIDxzcGFuIDpjbGFzcz1cXFwieydkYXRlcGlja2VyLWRhdGVSYW5nZS1pdGVtLWFjdGl2ZSc6cGFyc2UodmFsKS5nZXRGdWxsWWVhcigpID09PSBkZWNhZGUudGV4dH1cXFwiXFxyXFxuICAgICAgICAgICAgICAgIHYtdGV4dD1cXFwiZGVjYWRlLnRleHRcXFwiXFxyXFxuICAgICAgICAgICAgICAgIEBjbGljay5zdG9wPVxcXCJ5ZWFyU2VsZWN0KGRlY2FkZS50ZXh0KVxcXCJcXHJcXG4gICAgICAgICAgICAgID48L3NwYW4+XFxyXFxuICAgICAgICAgICAgPC90ZW1wbGF0ZT5cXHJcXG4gICAgICAgICAgPC9kaXY+XFxyXFxuICAgICAgICA8L2Rpdj5cXHJcXG4gICAgICA8L2Rpdj5cXHJcXG4gICAgPC9kaXY+XFxyXFxuICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcblxcclxcbjxzY3JpcHQ+XFxyXFxuaW1wb3J0IHt0cmFuc2xhdGlvbnN9IGZyb20gJy4vdXRpbHMvdXRpbHMuanMnXFxyXFxuLy8gaW1wb3J0ICQgZnJvbSAnLi91dGlscy9Ob2RlTGlzdC5qcydcXHJcXG5cXHJcXG5leHBvcnQgZGVmYXVsdCB7XFxyXFxuICBwcm9wczoge1xcclxcbiAgICB2YWx1ZToge3R5cGU6IFN0cmluZ30sXFxyXFxuICAgIGZvcm1hdDoge2RlZmF1bHQ6ICdNTS9kZC95eXl5J30sXFxyXFxuICAgIGRpc2FibGVkRGF5c09mV2Vlazoge3R5cGU6IEFycmF5LCBkZWZhdWx0ICgpIHsgcmV0dXJuIFtdIH19LFxcclxcbiAgICB3aWR0aDoge3R5cGU6IFN0cmluZ30sXFxyXFxuICAgIGNsZWFyQnV0dG9uOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBsYW5nOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBuYXZpZ2F0b3IubGFuZ3VhZ2V9LFxcclxcbiAgICBwbGFjZWhvbGRlcjoge3R5cGU6IFN0cmluZ30sXFxyXFxuICAgIGljb25zRm9udDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogJ2dseXBoaWNvbid9XFxyXFxuICB9LFxcclxcbiAgZGF0YSAoKSB7XFxyXFxuICAgIHJldHVybiB7XFxyXFxuICAgICAgY3VyckRhdGU6IG5ldyBEYXRlKCksXFxyXFxuICAgICAgZGF0ZVJhbmdlOiBbXSxcXHJcXG4gICAgICBkZWNhZGVSYW5nZTogW10sXFxyXFxuICAgICAgZGlzcGxheURheVZpZXc6IGZhbHNlLFxcclxcbiAgICAgIGRpc3BsYXlNb250aFZpZXc6IGZhbHNlLFxcclxcbiAgICAgIGRpc3BsYXlZZWFyVmlldzogZmFsc2UsXFxyXFxuICAgICAgdmFsOiB0aGlzLnZhbHVlXFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICB3YXRjaDoge1xcclxcbiAgICBjdXJyRGF0ZSAoKSB7XFxyXFxuICAgICAgdGhpcy5nZXREYXRlUmFuZ2UoKVxcclxcbiAgICB9LFxcclxcbiAgICBmb3JtYXQgKCkge1xcclxcbiAgICAgIHRoaXMudmFsID0gdGhpcy5zdHJpbmdpZnkodGhpcy5jdXJyRGF0ZSlcXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsICh2YWwsIG9sZCkge1xcclxcbiAgICAgIHRoaXMuJGVtaXQoJ2lucHV0JywgdmFsKVxcclxcbiAgICB9LFxcclxcbiAgICB2YWx1ZSAodmFsKSB7XFxyXFxuICAgICAgaWYgKHRoaXMudmFsICE9PSB2YWwpIHsgdGhpcy52YWwgPSB2YWwgfVxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgY29tcHV0ZWQ6IHtcXHJcXG4gICAgdGV4dCAoKSB7XFxyXFxuICAgICAgcmV0dXJuIHRyYW5zbGF0aW9ucyh0aGlzLmxhbmcpXFxyXFxuICAgIH0sXFxyXFxuICAgIHByZUJ0bkNsYXNzZXMgKCkge1xcclxcbiAgICAgIHJldHVybiBgZGF0ZXBpY2tlci1wcmVCdG4gJHt0aGlzLmljb25zRm9udH0gJHt0aGlzLmljb25zRm9udH0tY2hldnJvbi1sZWZ0YFxcclxcbiAgICB9LFxcclxcbiAgICBuZXh0QnRuQ2xhc3NlcyAoKSB7XFxyXFxuICAgICAgcmV0dXJuIGBkYXRlcGlja2VyLW5leHRCdG4gJHt0aGlzLmljb25zRm9udH0gJHt0aGlzLmljb25zRm9udH0tY2hldnJvbi1yaWdodGBcXHJcXG4gICAgfSxcXHJcXG4gICAgZGlzYWJsZWREYXlzQXJyYXkgKCkge1xcclxcbiAgICAgIHJldHVybiB0aGlzLmRpc2FibGVkRGF5c09mV2Vlay5tYXAoZCA9PiBwYXJzZUludChkLCAxMCkpXFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBtZXRob2RzOiB7XFxyXFxuICAgIGNsb3NlICgpIHtcXHJcXG4gICAgICB0aGlzLmRpc3BsYXlEYXlWaWV3ID0gdGhpcy5kaXNwbGF5TW9udGhWaWV3ID0gdGhpcy5kaXNwbGF5WWVhclZpZXcgPSBmYWxzZVxcclxcbiAgICB9LFxcclxcbiAgICBpbnB1dENsaWNrICgpIHtcXHJcXG4gICAgICB0aGlzLmN1cnJEYXRlID0gdGhpcy5wYXJzZSh0aGlzLnZhbCkgfHwgdGhpcy5wYXJzZShuZXcgRGF0ZSgpKVxcclxcbiAgICAgIGlmICh0aGlzLmRpc3BsYXlNb250aFZpZXcgfHwgdGhpcy5kaXNwbGF5WWVhclZpZXcpIHtcXHJcXG4gICAgICAgIHRoaXMuZGlzcGxheURheVZpZXcgPSBmYWxzZVxcclxcbiAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICB0aGlzLmRpc3BsYXlEYXlWaWV3ID0gIXRoaXMuZGlzcGxheURheVZpZXdcXHJcXG4gICAgICB9XFxyXFxuICAgIH0sXFxyXFxuICAgIHByZU5leHREZWNhZGVDbGljayAoZmxhZykge1xcclxcbiAgICAgIGNvbnN0IHllYXIgPSB0aGlzLmN1cnJEYXRlLmdldEZ1bGxZZWFyKClcXHJcXG4gICAgICBjb25zdCBtb250aHMgPSB0aGlzLmN1cnJEYXRlLmdldE1vbnRoKClcXHJcXG4gICAgICBjb25zdCBkYXRlID0gdGhpcy5jdXJyRGF0ZS5nZXREYXRlKClcXHJcXG5cXHJcXG4gICAgICBpZiAoZmxhZyA9PT0gMCkge1xcclxcbiAgICAgICAgdGhpcy5jdXJyRGF0ZSA9IG5ldyBEYXRlKHllYXIgLSAxMCwgbW9udGhzLCBkYXRlKVxcclxcbiAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICB0aGlzLmN1cnJEYXRlID0gbmV3IERhdGUoeWVhciArIDEwLCBtb250aHMsIGRhdGUpXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICBwcmVOZXh0TW9udGhDbGljayAoZmxhZykge1xcclxcbiAgICAgIGNvbnN0IHllYXIgPSB0aGlzLmN1cnJEYXRlLmdldEZ1bGxZZWFyKClcXHJcXG4gICAgICBjb25zdCBtb250aCA9IHRoaXMuY3VyckRhdGUuZ2V0TW9udGgoKVxcclxcbiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmN1cnJEYXRlLmdldERhdGUoKVxcclxcblxcclxcbiAgICAgIGlmIChmbGFnID09PSAwKSB7XFxyXFxuICAgICAgICBjb25zdCBwcmVNb250aCA9IHRoaXMuZ2V0WWVhck1vbnRoKHllYXIsIG1vbnRoIC0gMSlcXHJcXG4gICAgICAgIHRoaXMuY3VyckRhdGUgPSBuZXcgRGF0ZShwcmVNb250aC55ZWFyLCBwcmVNb250aC5tb250aCwgZGF0ZSlcXHJcXG4gICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgY29uc3QgbmV4dE1vbnRoID0gdGhpcy5nZXRZZWFyTW9udGgoeWVhciwgbW9udGggKyAxKVxcclxcbiAgICAgICAgdGhpcy5jdXJyRGF0ZSA9IG5ldyBEYXRlKG5leHRNb250aC55ZWFyLCBuZXh0TW9udGgubW9udGgsIGRhdGUpXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICBwcmVOZXh0WWVhckNsaWNrIChmbGFnKSB7XFxyXFxuICAgICAgY29uc3QgeWVhciA9IHRoaXMuY3VyckRhdGUuZ2V0RnVsbFllYXIoKVxcclxcbiAgICAgIGNvbnN0IG1vbnRocyA9IHRoaXMuY3VyckRhdGUuZ2V0TW9udGgoKVxcclxcbiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmN1cnJEYXRlLmdldERhdGUoKVxcclxcblxcclxcbiAgICAgIGlmIChmbGFnID09PSAwKSB7XFxyXFxuICAgICAgICB0aGlzLmN1cnJEYXRlID0gbmV3IERhdGUoeWVhciAtIDEsIG1vbnRocywgZGF0ZSlcXHJcXG4gICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgdGhpcy5jdXJyRGF0ZSA9IG5ldyBEYXRlKHllYXIgKyAxLCBtb250aHMsIGRhdGUpXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICB5ZWFyU2VsZWN0ICh5ZWFyKSB7XFxyXFxuICAgICAgdGhpcy5kaXNwbGF5WWVhclZpZXcgPSBmYWxzZVxcclxcbiAgICAgIHRoaXMuZGlzcGxheU1vbnRoVmlldyA9IHRydWVcXHJcXG4gICAgICB0aGlzLmN1cnJEYXRlID0gbmV3IERhdGUoeWVhciwgdGhpcy5jdXJyRGF0ZS5nZXRNb250aCgpLCB0aGlzLmN1cnJEYXRlLmdldERhdGUoKSlcXHJcXG4gICAgfSxcXHJcXG4gICAgZGF5U2VsZWN0IChkYXkpIHtcXHJcXG4gICAgICBpZiAoZGF5LnNjbGFzcyA9PT0gJ2RhdGVwaWNrZXItaXRlbS1kaXNhYmxlJykge1xcclxcbiAgICAgICAgcmV0dXJuIGZhbHNlXFxyXFxuICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgIHRoaXMuY3VyckRhdGUgPSBkYXkuZGF0ZVxcclxcbiAgICAgICAgdGhpcy52YWwgPSB0aGlzLnN0cmluZ2lmeSh0aGlzLmN1cnJEYXRlKVxcclxcbiAgICAgICAgdGhpcy5kaXNwbGF5RGF5VmlldyA9IGZhbHNlXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICBzd2l0Y2hNb250aFZpZXcgKCkge1xcclxcbiAgICAgIHRoaXMuZGlzcGxheURheVZpZXcgPSBmYWxzZVxcclxcbiAgICAgIHRoaXMuZGlzcGxheU1vbnRoVmlldyA9IHRydWVcXHJcXG4gICAgfSxcXHJcXG4gICAgc3dpdGNoRGVjYWRlVmlldyAoKSB7XFxyXFxuICAgICAgdGhpcy5kaXNwbGF5TW9udGhWaWV3ID0gZmFsc2VcXHJcXG4gICAgICB0aGlzLmRpc3BsYXlZZWFyVmlldyA9IHRydWVcXHJcXG4gICAgfSxcXHJcXG4gICAgbW9udGhTZWxlY3QgKGluZGV4KSB7XFxyXFxuICAgICAgdGhpcy5kaXNwbGF5TW9udGhWaWV3ID0gZmFsc2VcXHJcXG4gICAgICB0aGlzLmRpc3BsYXlEYXlWaWV3ID0gdHJ1ZVxcclxcbiAgICAgIHRoaXMuY3VyckRhdGUgPSBuZXcgRGF0ZSh0aGlzLmN1cnJEYXRlLmdldEZ1bGxZZWFyKCksIGluZGV4LCB0aGlzLmN1cnJEYXRlLmdldERhdGUoKSlcXHJcXG4gICAgfSxcXHJcXG4gICAgZ2V0WWVhck1vbnRoICh5ZWFyLCBtb250aCkge1xcclxcbiAgICAgIGlmIChtb250aCA+IDExKSB7XFxyXFxuICAgICAgICB5ZWFyKytcXHJcXG4gICAgICAgIG1vbnRoID0gMFxcclxcbiAgICAgIH0gZWxzZSBpZiAobW9udGggPCAwKSB7XFxyXFxuICAgICAgICB5ZWFyLS1cXHJcXG4gICAgICAgIG1vbnRoID0gMTFcXHJcXG4gICAgICB9XFxyXFxuICAgICAgcmV0dXJuIHt5ZWFyOiB5ZWFyLCBtb250aDogbW9udGh9XFxyXFxuICAgIH0sXFxyXFxuICAgIHN0cmluZ2lmeURlY2FkZUhlYWRlciAoZGF0ZSkge1xcclxcbiAgICAgIGNvbnN0IHllYXJTdHIgPSBkYXRlLmdldEZ1bGxZZWFyKCkudG9TdHJpbmcoKVxcclxcbiAgICAgIGNvbnN0IGZpcnN0WWVhck9mRGVjYWRlID0geWVhclN0ci5zdWJzdHJpbmcoMCwgeWVhclN0ci5sZW5ndGggLSAxKSArIDBcXHJcXG4gICAgICBjb25zdCBsYXN0WWVhck9mRGVjYWRlID0gcGFyc2VJbnQoZmlyc3RZZWFyT2ZEZWNhZGUsIDEwKSArIDEwXFxyXFxuICAgICAgcmV0dXJuIGZpcnN0WWVhck9mRGVjYWRlICsgJy0nICsgbGFzdFllYXJPZkRlY2FkZVxcclxcbiAgICB9LFxcclxcbiAgICBzdHJpbmdpZnlEYXlIZWFkZXIgKGRhdGUpIHtcXHJcXG4gICAgICByZXR1cm4gdGhpcy50ZXh0Lm1vbnRoc1tkYXRlLmdldE1vbnRoKCldICsgJyAnICsgZGF0ZS5nZXRGdWxsWWVhcigpXFxyXFxuICAgIH0sXFxyXFxuICAgIHBhcnNlTW9udGggKGRhdGUpIHtcXHJcXG4gICAgICByZXR1cm4gdGhpcy50ZXh0Lm1vbnRoc1tkYXRlLmdldE1vbnRoKCldXFxyXFxuICAgIH0sXFxyXFxuICAgIHN0cmluZ2lmeVllYXJIZWFkZXIgKGRhdGUpIHtcXHJcXG4gICAgICByZXR1cm4gZGF0ZS5nZXRGdWxsWWVhcigpXFxyXFxuICAgIH0sXFxyXFxuICAgIHN0cmluZ2lmeSAoZGF0ZSwgZm9ybWF0ID0gdGhpcy5mb3JtYXQpIHtcXHJcXG4gICAgICBpZiAoIWRhdGUpIGRhdGUgPSB0aGlzLnBhcnNlKClcXHJcXG4gICAgICBpZiAoIWRhdGUpIHJldHVybiAnJ1xcclxcbiAgICAgIGNvbnN0IHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKClcXHJcXG4gICAgICBjb25zdCBtb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIDFcXHJcXG4gICAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKVxcclxcbiAgICAgIGNvbnN0IG1vbnRoTmFtZSA9IHRoaXMucGFyc2VNb250aChkYXRlKVxcclxcbiAgICAgIHJldHVybiBmb3JtYXRcXHJcXG4gICAgICAgIC5yZXBsYWNlKC95eXl5L2csIHllYXIpXFxyXFxuICAgICAgICAucmVwbGFjZSgveXkvZywgeWVhcilcXHJcXG4gICAgICAgIC5yZXBsYWNlKC9NTU1NL2csIG1vbnRoTmFtZSlcXHJcXG4gICAgICAgIC5yZXBsYWNlKC9NTU0vZywgbW9udGhOYW1lLnN1YnN0cmluZygwLCAzKSlcXHJcXG4gICAgICAgIC5yZXBsYWNlKC9NTS9nLCAoJzAnICsgbW9udGgpLnNsaWNlKC0yKSlcXHJcXG4gICAgICAgIC5yZXBsYWNlKC9NKD8hYSkvZywgbW9udGgpXFxyXFxuICAgICAgICAucmVwbGFjZSgvZGQvZywgKCcwJyArIGRheSkuc2xpY2UoLTIpKVxcclxcbiAgICAgICAgLnJlcGxhY2UoL2QvZywgZGF5KVxcclxcbiAgICB9LFxcclxcbiAgICBwYXJzZSAoc3RyKSB7XFxyXFxuICAgICAgaWYgKHN0ciA9PT0gdW5kZWZpbmVkIHx8IHN0ciA9PT0gbnVsbCkgeyBzdHIgPSB0aGlzLnZhbCB9XFxyXFxuICAgICAgbGV0IGRhdGUgPSBzdHIubGVuZ3RoID09PSAxMCAmJiAodGhpcy5mb3JtYXQgPT09ICdkZC1NTS15eXl5JyB8fCB0aGlzLmZvcm1hdCA9PT0gJ2RkL01NL3l5eXknKSA/XFxyXFxuICAgICAgICBuZXcgRGF0ZShzdHIuc3Vic3RyaW5nKDYsIDEwKSwgc3RyLnN1YnN0cmluZygzLCA1KS0xLCBzdHIuc3Vic3RyaW5nKDAsIDIpKSA6XFxyXFxuICAgICAgICBuZXcgRGF0ZShzdHIpXFxyXFxuICAgICAgcmV0dXJuIGlzTmFOKGRhdGUuZ2V0RnVsbFllYXIoKSkgPyBuZXcgRGF0ZSgpIDogZGF0ZVxcclxcbiAgICB9LFxcclxcbiAgICBnZXREYXlDb3VudCAoeWVhciwgbW9udGgpIHtcXHJcXG4gICAgICBjb25zdCBkaWN0ID0gWzMxLCAyOCwgMzEsIDMwLCAzMSwgMzAsIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzFdXFxyXFxuICAgICAgaWYgKG1vbnRoID09PSAxKSB7XFxyXFxuICAgICAgICBpZiAoKHllYXIgJSA0MDAgPT09IDApIHx8ICh5ZWFyICUgNCA9PT0gMCAmJiB5ZWFyICUgMTAwICE9PSAwKSkge1xcclxcbiAgICAgICAgICByZXR1cm4gMjlcXHJcXG4gICAgICAgIH1cXHJcXG4gICAgICB9XFxyXFxuICAgICAgcmV0dXJuIGRpY3RbbW9udGhdXFxyXFxuICAgIH0sXFxyXFxuICAgIGdldERhdGVSYW5nZSAoKSB7XFxyXFxuICAgICAgdGhpcy5kYXRlUmFuZ2UgPSBbXVxcclxcbiAgICAgIHRoaXMuZGVjYWRlUmFuZ2UgPSBbXVxcclxcbiAgICAgIGNvbnN0IHRpbWUgPSB7XFxyXFxuICAgICAgICB5ZWFyOiB0aGlzLmN1cnJEYXRlLmdldEZ1bGxZZWFyKCksXFxyXFxuICAgICAgICBtb250aDogdGhpcy5jdXJyRGF0ZS5nZXRNb250aCgpLFxcclxcbiAgICAgICAgZGF5OiB0aGlzLmN1cnJEYXRlLmdldERhdGUoKVxcclxcbiAgICAgIH1cXHJcXG4gICAgICBjb25zdCB5ZWFyU3RyID0gdGltZS55ZWFyLnRvU3RyaW5nKClcXHJcXG4gICAgICBjb25zdCBmaXJzdFllYXJPZkRlY2FkZSA9ICh5ZWFyU3RyLnN1YnN0cmluZygwLCB5ZWFyU3RyLmxlbmd0aCAtIDEpICsgMCkgLSAxXFxyXFxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxMjsgaSsrKSB7XFxyXFxuICAgICAgICB0aGlzLmRlY2FkZVJhbmdlLnB1c2goe1xcclxcbiAgICAgICAgICB0ZXh0OiBmaXJzdFllYXJPZkRlY2FkZSArIGlcXHJcXG4gICAgICAgIH0pXFxyXFxuICAgICAgfVxcclxcblxcclxcbiAgICAgIGNvbnN0IGN1cnJNb250aEZpcnN0RGF5ID0gbmV3IERhdGUodGltZS55ZWFyLCB0aW1lLm1vbnRoLCAxKVxcclxcbiAgICAgIGxldCBmaXJzdERheVdlZWsgPSBjdXJyTW9udGhGaXJzdERheS5nZXREYXkoKSArIDFcXHJcXG4gICAgICBpZiAoZmlyc3REYXlXZWVrID09PSAwKSB7XFxyXFxuICAgICAgICBmaXJzdERheVdlZWsgPSA3XFxyXFxuICAgICAgfVxcclxcbiAgICAgIGNvbnN0IGRheUNvdW50ID0gdGhpcy5nZXREYXlDb3VudCh0aW1lLnllYXIsIHRpbWUubW9udGgpXFxyXFxuICAgICAgaWYgKGZpcnN0RGF5V2VlayA+IDEpIHtcXHJcXG4gICAgICAgIGNvbnN0IHByZU1vbnRoID0gdGhpcy5nZXRZZWFyTW9udGgodGltZS55ZWFyLCB0aW1lLm1vbnRoIC0gMSlcXHJcXG4gICAgICAgIGNvbnN0IHByZXZNb250aERheUNvdW50ID0gdGhpcy5nZXREYXlDb3VudChwcmVNb250aC55ZWFyLCBwcmVNb250aC5tb250aClcXHJcXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmlyc3REYXlXZWVrOyBpKyspIHtcXHJcXG4gICAgICAgICAgY29uc3QgZGF5VGV4dCA9IHByZXZNb250aERheUNvdW50IC0gZmlyc3REYXlXZWVrICsgaSArIDFcXHJcXG4gICAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHByZU1vbnRoLnllYXIsIHByZU1vbnRoLm1vbnRoLCBkYXlUZXh0KVxcclxcbiAgICAgICAgICBsZXQgc2NsYXNzID0gJ2RhdGVwaWNrZXItaXRlbS1ncmF5J1xcclxcbiAgICAgICAgICBpZiAodGhpcy5kaXNhYmxlZERheXNBcnJheS5pbmRleE9mKGRhdGUuZ2V0RGF5KCkpID4gLTEpIHtcXHJcXG4gICAgICAgICAgICBzY2xhc3MgPSAnZGF0ZXBpY2tlci1pdGVtLWRpc2FibGUnXFxyXFxuICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgdGhpcy5kYXRlUmFuZ2UucHVzaCh7dGV4dDogZGF5VGV4dCwgZGF0ZSwgc2NsYXNzIH0pXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgfVxcclxcblxcclxcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IGRheUNvdW50OyBpKyspIHtcXHJcXG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh0aW1lLnllYXIsIHRpbWUubW9udGgsIGkpXFxyXFxuICAgICAgICBsZXQgc2NsYXNzID0gJydcXHJcXG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkRGF5c0FycmF5LmluZGV4T2YoZGF0ZS5nZXREYXkoKSkgPiAtMSkge1xcclxcbiAgICAgICAgICBzY2xhc3MgPSAnZGF0ZXBpY2tlci1pdGVtLWRpc2FibGUnXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgICBpZiAoaSA9PSB0aW1lLmRheSAmJiBkYXRlLmdldEZ1bGxZZWFyKCkgPT0gdGltZS55ZWFyICYmIGRhdGUuZ2V0TW9udGgoKSA9PSB0aW1lLm1vbnRoKXtcXHJcXG4gICAgICAgICAgc2NsYXNzID0gJ2RhdGVwaWNrZXItZGF0ZVJhbmdlLWl0ZW0tYWN0aXZlJ1xcclxcbiAgICAgICAgfVxcclxcbiAgICAgICAgdGhpcy5kYXRlUmFuZ2UucHVzaCh7dGV4dDogaSwgZGF0ZSwgc2NsYXNzfSlcXHJcXG4gICAgICB9XFxyXFxuXFxyXFxuICAgICAgaWYgKHRoaXMuZGF0ZVJhbmdlLmxlbmd0aCA8IDQyKSB7XFxyXFxuICAgICAgICBjb25zdCBuZXh0TW9udGhOZWVkID0gNDIgLSB0aGlzLmRhdGVSYW5nZS5sZW5ndGhcXHJcXG4gICAgICAgIGNvbnN0IG5leHRNb250aCA9IHRoaXMuZ2V0WWVhck1vbnRoKHRpbWUueWVhciwgdGltZS5tb250aCArIDEpXFxyXFxuXFxyXFxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBuZXh0TW9udGhOZWVkOyBpKyspIHtcXHJcXG4gICAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKG5leHRNb250aC55ZWFyLCBuZXh0TW9udGgubW9udGgsIGkpXFxyXFxuICAgICAgICAgIGxldCBzY2xhc3MgPSAnZGF0ZXBpY2tlci1pdGVtLWdyYXknXFxyXFxuICAgICAgICAgIGlmICh0aGlzLmRpc2FibGVkRGF5c0FycmF5LmluZGV4T2YoZGF0ZS5nZXREYXkoKSkgPiAtMSkge1xcclxcbiAgICAgICAgICAgIHNjbGFzcyA9ICdkYXRlcGlja2VyLWl0ZW0tZGlzYWJsZSdcXHJcXG4gICAgICAgICAgfVxcclxcbiAgICAgICAgICB0aGlzLmRhdGVSYW5nZS5wdXNoKHt0ZXh0OiBpLCBkYXRlLCBzY2xhc3N9KVxcclxcbiAgICAgICAgfVxcclxcbiAgICAgIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1vdW50ZWQgKCkge1xcclxcbiAgICB0aGlzLiRlbWl0KCdjaGlsZC1jcmVhdGVkJywgdGhpcylcXHJcXG4gICAgdGhpcy5jdXJyRGF0ZSA9IHRoaXMucGFyc2UodGhpcy52YWwpIHx8IHRoaXMucGFyc2UobmV3IERhdGUoKSlcXHJcXG4gICAgdGhpcy5fYmx1ciA9IGUgPT4ge1xcclxcbiAgICAgIGlmICghdGhpcy4kZWwuY29udGFpbnMoZS50YXJnZXQpKVxcclxcbiAgICAgICAgdGhpcy5jbG9zZSgpXFxyXFxuICAgIH1cXHJcXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYmx1cik7XFxyXFxuICB9LFxcclxcbiAgYmVmb3JlRGVzdHJveSAoKSB7XFxyXFxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2JsdXIpXFxyXFxuICB9XFxyXFxufVxcclxcbjwvc2NyaXB0PlxcclxcblxcclxcbjxzdHlsZT5cXHJcXG4uZGF0ZXBpY2tlciB7XFxyXFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxufVxcclxcbmlucHV0LmRhdGVwaWNrZXItaW5wdXQud2l0aC1yZXNldC1idXR0b24ge1xcclxcbiAgcGFkZGluZy1yaWdodDogMjVweDtcXHJcXG59XFxyXFxuLmRhdGVwaWNrZXIgPiBidXR0b24uY2xvc2Uge1xcclxcbiAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgdG9wOiAwO1xcclxcbiAgcmlnaHQ6IDA7XFxyXFxuICBvdXRsaW5lOiBub25lO1xcclxcbiAgei1pbmRleDogMjtcXHJcXG4gIGRpc3BsYXk6IGJsb2NrO1xcclxcbiAgd2lkdGg6IDM0cHg7XFxyXFxuICBoZWlnaHQ6IDM0cHg7XFxyXFxuICBsaW5lLWhlaWdodDogMzRweDtcXHJcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG59XFxyXFxuLmRhdGVwaWNrZXIgPiBidXR0b24uY2xvc2U6Zm9jdXMge1xcclxcbiAgb3BhY2l0eTogLjI7XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLXBvcHVwIHtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIGJvcmRlcjogMXB4IHNvbGlkICNjY2M7XFxyXFxuICBib3JkZXItcmFkaXVzOiA1cHg7XFxyXFxuICBiYWNrZ3JvdW5kOiAjZmZmO1xcclxcbiAgbWFyZ2luLXRvcDogMnB4O1xcclxcbiAgei1pbmRleDogMTAwMDtcXHJcXG4gIGJveC1zaGFkb3c6IDAgNnB4IDEycHggcmdiYSgwLDAsMCwwLjE3NSk7XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLWlubmVyIHtcXHJcXG4gIHdpZHRoOiAyMThweDtcXHJcXG59XFxyXFxuLmRhdGVwaWNrZXItYm9keSB7XFxyXFxuICBwYWRkaW5nOiAxMHB4IDEwcHg7XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLWN0cmwgcCxcXHJcXG4uZGF0ZXBpY2tlci1jdHJsIHNwYW4sXFxyXFxuLmRhdGVwaWNrZXItYm9keSBzcGFuIHtcXHJcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG4gIHdpZHRoOiAyOHB4O1xcclxcbiAgbGluZS1oZWlnaHQ6IDI4cHg7XFxyXFxuICBoZWlnaHQ6IDI4cHg7XFxyXFxuICBib3JkZXItcmFkaXVzOiA0cHg7XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLWN0cmwgcCB7XFxyXFxuICB3aWR0aDogNjUlO1xcclxcbn1cXHJcXG4uZGF0ZXBpY2tlci1jdHJsIHNwYW4ge1xcclxcbiAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbn1cXHJcXG4uZGF0ZXBpY2tlci1ib2R5IHNwYW4ge1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbn1cXHJcXG4uZGF0ZXBpY2tlci1tb250aFJhbmdlIHNwYW4ge1xcclxcbiAgd2lkdGg6IDQ4cHg7XFxyXFxuICBoZWlnaHQ6IDUwcHg7XFxyXFxuICBsaW5lLWhlaWdodDogNDVweDtcXHJcXG59XFxyXFxuLmRhdGVwaWNrZXItaXRlbS1kaXNhYmxlIHtcXHJcXG4gIGJhY2tncm91bmQtY29sb3I6IHdoaXRlIWltcG9ydGFudDtcXHJcXG4gIGN1cnNvcjogbm90LWFsbG93ZWQhaW1wb3J0YW50O1xcclxcbn1cXHJcXG4uZGVjYWRlUmFuZ2Ugc3BhbjpmaXJzdC1jaGlsZCxcXHJcXG4uZGVjYWRlUmFuZ2Ugc3BhbjpsYXN0LWNoaWxkLFxcclxcbi5kYXRlcGlja2VyLWl0ZW0tZGlzYWJsZSxcXHJcXG4uZGF0ZXBpY2tlci1pdGVtLWdyYXkge1xcclxcbiAgY29sb3I6ICM5OTk7XFxyXFxufVxcclxcblxcclxcbi5kYXRlcGlja2VyLWRhdGVSYW5nZS1pdGVtLWFjdGl2ZTpob3ZlcixcXHJcXG4uZGF0ZXBpY2tlci1kYXRlUmFuZ2UtaXRlbS1hY3RpdmUge1xcclxcbiAgYmFja2dyb3VuZDogcmdiKDUwLCAxMTgsIDE3NykhaW1wb3J0YW50O1xcclxcbiAgY29sb3I6IHdoaXRlIWltcG9ydGFudDtcXHJcXG59XFxyXFxuLmRhdGVwaWNrZXItbW9udGhSYW5nZSB7XFxyXFxuICBtYXJnaW4tdG9wOiAxMHB4XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLW1vbnRoUmFuZ2Ugc3BhbixcXHJcXG4uZGF0ZXBpY2tlci1jdHJsIHNwYW4sXFxyXFxuLmRhdGVwaWNrZXItY3RybCBwLFxcclxcbi5kYXRlcGlja2VyLWRhdGVSYW5nZSBzcGFuIHtcXHJcXG4gIGN1cnNvcjogcG9pbnRlcjtcXHJcXG59XFxyXFxuLmRhdGVwaWNrZXItbW9udGhSYW5nZSBzcGFuOmhvdmVyLFxcclxcbi5kYXRlcGlja2VyLWN0cmwgcDpob3ZlcixcXHJcXG4uZGF0ZXBpY2tlci1jdHJsIGk6aG92ZXIsXFxyXFxuLmRhdGVwaWNrZXItZGF0ZVJhbmdlIHNwYW46aG92ZXIsXFxyXFxuLmRhdGVwaWNrZXItZGF0ZVJhbmdlLWl0ZW0taG92ZXIge1xcclxcbiAgYmFja2dyb3VuZC1jb2xvciA6ICNlZWVlZWU7XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLXdlZWtSYW5nZSBzcGFuIHtcXHJcXG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xcclxcbn1cXHJcXG4uZGF0ZXBpY2tlci1sYWJlbCB7XFxyXFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjhmOGY4O1xcclxcbiAgZm9udC13ZWlnaHQ6IDcwMDtcXHJcXG4gIHBhZGRpbmc6IDdweCAwO1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbn1cXHJcXG4uZGF0ZXBpY2tlci1jdHJsIHtcXHJcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gIGhlaWdodDogMzBweDtcXHJcXG4gIGxpbmUtaGVpZ2h0OiAzMHB4O1xcclxcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XFxyXFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcbi5tb250aC1idG4ge1xcclxcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XFxyXFxuICAtd2Via2l0LXVzZXItc2VsZWN0Om5vbmU7XFxyXFxuICAtbW96LXVzZXItc2VsZWN0Om5vbmU7XFxyXFxuICAtbXMtdXNlci1zZWxlY3Q6bm9uZTtcXHJcXG4gIHVzZXItc2VsZWN0Om5vbmU7XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLXByZUJ0biB7XFxyXFxuICBsZWZ0OiAycHg7XFxyXFxufVxcclxcbi5kYXRlcGlja2VyLW5leHRCdG4ge1xcclxcbiAgcmlnaHQ6IDJweDtcXHJcXG59XFxyXFxuPC9zdHlsZT5cXHJcXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cdFxuXHQvLyBleHBvcnRzXG5cblxuLyoqKi8gfSxcbi8qIDEwMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdFxuXHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2NSk7XG5cdFxuXHQvLyBpbXBvcnQgJCBmcm9tICcuL3V0aWxzL05vZGVMaXN0LmpzJ1xuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIHByb3BzOiB7XG5cdCAgICB2YWx1ZTogeyB0eXBlOiBTdHJpbmcgfSxcblx0ICAgIGZvcm1hdDogeyBkZWZhdWx0OiAnTU0vZGQveXl5eScgfSxcblx0ICAgIGRpc2FibGVkRGF5c09mV2VlazogeyB0eXBlOiBBcnJheSwgZGVmYXVsdDogZnVuY3Rpb24gX2RlZmF1bHQoKSB7XG5cdCAgICAgICAgcmV0dXJuIFtdO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgd2lkdGg6IHsgdHlwZTogU3RyaW5nIH0sXG5cdCAgICBjbGVhckJ1dHRvbjogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgbGFuZzogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG5hdmlnYXRvci5sYW5ndWFnZSB9LFxuXHQgICAgcGxhY2Vob2xkZXI6IHsgdHlwZTogU3RyaW5nIH0sXG5cdCAgICBpY29uc0ZvbnQ6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnZ2x5cGhpY29uJyB9XG5cdCAgfSxcblx0ICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgY3VyckRhdGU6IG5ldyBEYXRlKCksXG5cdCAgICAgIGRhdGVSYW5nZTogW10sXG5cdCAgICAgIGRlY2FkZVJhbmdlOiBbXSxcblx0ICAgICAgZGlzcGxheURheVZpZXc6IGZhbHNlLFxuXHQgICAgICBkaXNwbGF5TW9udGhWaWV3OiBmYWxzZSxcblx0ICAgICAgZGlzcGxheVllYXJWaWV3OiBmYWxzZSxcblx0ICAgICAgdmFsOiB0aGlzLnZhbHVlXG5cdCAgICB9O1xuXHQgIH0sXG5cdFxuXHQgIHdhdGNoOiB7XG5cdCAgICBjdXJyRGF0ZTogZnVuY3Rpb24gY3VyckRhdGUoKSB7XG5cdCAgICAgIHRoaXMuZ2V0RGF0ZVJhbmdlKCk7XG5cdCAgICB9LFxuXHQgICAgZm9ybWF0OiBmdW5jdGlvbiBmb3JtYXQoKSB7XG5cdCAgICAgIHRoaXMudmFsID0gdGhpcy5zdHJpbmdpZnkodGhpcy5jdXJyRGF0ZSk7XG5cdCAgICB9LFxuXHQgICAgdmFsOiBmdW5jdGlvbiB2YWwoX3ZhbCwgb2xkKSB7XG5cdCAgICAgIHRoaXMuJGVtaXQoJ2lucHV0JywgX3ZhbCk7XG5cdCAgICB9LFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKHZhbCkge1xuXHQgICAgICBpZiAodGhpcy52YWwgIT09IHZhbCkge1xuXHQgICAgICAgIHRoaXMudmFsID0gdmFsO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBjb21wdXRlZDoge1xuXHQgICAgdGV4dDogZnVuY3Rpb24gdGV4dCgpIHtcblx0ICAgICAgcmV0dXJuICgwLCBfdXRpbHMudHJhbnNsYXRpb25zKSh0aGlzLmxhbmcpO1xuXHQgICAgfSxcblx0ICAgIHByZUJ0bkNsYXNzZXM6IGZ1bmN0aW9uIHByZUJ0bkNsYXNzZXMoKSB7XG5cdCAgICAgIHJldHVybiAnZGF0ZXBpY2tlci1wcmVCdG4gJyArIHRoaXMuaWNvbnNGb250ICsgJyAnICsgdGhpcy5pY29uc0ZvbnQgKyAnLWNoZXZyb24tbGVmdCc7XG5cdCAgICB9LFxuXHQgICAgbmV4dEJ0bkNsYXNzZXM6IGZ1bmN0aW9uIG5leHRCdG5DbGFzc2VzKCkge1xuXHQgICAgICByZXR1cm4gJ2RhdGVwaWNrZXItbmV4dEJ0biAnICsgdGhpcy5pY29uc0ZvbnQgKyAnICcgKyB0aGlzLmljb25zRm9udCArICctY2hldnJvbi1yaWdodCc7XG5cdCAgICB9LFxuXHQgICAgZGlzYWJsZWREYXlzQXJyYXk6IGZ1bmN0aW9uIGRpc2FibGVkRGF5c0FycmF5KCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5kaXNhYmxlZERheXNPZldlZWsubWFwKGZ1bmN0aW9uIChkKSB7XG5cdCAgICAgICAgcmV0dXJuIHBhcnNlSW50KGQsIDEwKTtcblx0ICAgICAgfSk7XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtZXRob2RzOiB7XG5cdCAgICBjbG9zZTogZnVuY3Rpb24gY2xvc2UoKSB7XG5cdCAgICAgIHRoaXMuZGlzcGxheURheVZpZXcgPSB0aGlzLmRpc3BsYXlNb250aFZpZXcgPSB0aGlzLmRpc3BsYXlZZWFyVmlldyA9IGZhbHNlO1xuXHQgICAgfSxcblx0ICAgIGlucHV0Q2xpY2s6IGZ1bmN0aW9uIGlucHV0Q2xpY2soKSB7XG5cdCAgICAgIHRoaXMuY3VyckRhdGUgPSB0aGlzLnBhcnNlKHRoaXMudmFsKSB8fCB0aGlzLnBhcnNlKG5ldyBEYXRlKCkpO1xuXHQgICAgICBpZiAodGhpcy5kaXNwbGF5TW9udGhWaWV3IHx8IHRoaXMuZGlzcGxheVllYXJWaWV3KSB7XG5cdCAgICAgICAgdGhpcy5kaXNwbGF5RGF5VmlldyA9IGZhbHNlO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHRoaXMuZGlzcGxheURheVZpZXcgPSAhdGhpcy5kaXNwbGF5RGF5Vmlldztcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHByZU5leHREZWNhZGVDbGljazogZnVuY3Rpb24gcHJlTmV4dERlY2FkZUNsaWNrKGZsYWcpIHtcblx0ICAgICAgdmFyIHllYXIgPSB0aGlzLmN1cnJEYXRlLmdldEZ1bGxZZWFyKCk7XG5cdCAgICAgIHZhciBtb250aHMgPSB0aGlzLmN1cnJEYXRlLmdldE1vbnRoKCk7XG5cdCAgICAgIHZhciBkYXRlID0gdGhpcy5jdXJyRGF0ZS5nZXREYXRlKCk7XG5cdFxuXHQgICAgICBpZiAoZmxhZyA9PT0gMCkge1xuXHQgICAgICAgIHRoaXMuY3VyckRhdGUgPSBuZXcgRGF0ZSh5ZWFyIC0gMTAsIG1vbnRocywgZGF0ZSk7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgdGhpcy5jdXJyRGF0ZSA9IG5ldyBEYXRlKHllYXIgKyAxMCwgbW9udGhzLCBkYXRlKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHByZU5leHRNb250aENsaWNrOiBmdW5jdGlvbiBwcmVOZXh0TW9udGhDbGljayhmbGFnKSB7XG5cdCAgICAgIHZhciB5ZWFyID0gdGhpcy5jdXJyRGF0ZS5nZXRGdWxsWWVhcigpO1xuXHQgICAgICB2YXIgbW9udGggPSB0aGlzLmN1cnJEYXRlLmdldE1vbnRoKCk7XG5cdCAgICAgIHZhciBkYXRlID0gdGhpcy5jdXJyRGF0ZS5nZXREYXRlKCk7XG5cdFxuXHQgICAgICBpZiAoZmxhZyA9PT0gMCkge1xuXHQgICAgICAgIHZhciBwcmVNb250aCA9IHRoaXMuZ2V0WWVhck1vbnRoKHllYXIsIG1vbnRoIC0gMSk7XG5cdCAgICAgICAgdGhpcy5jdXJyRGF0ZSA9IG5ldyBEYXRlKHByZU1vbnRoLnllYXIsIHByZU1vbnRoLm1vbnRoLCBkYXRlKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB2YXIgbmV4dE1vbnRoID0gdGhpcy5nZXRZZWFyTW9udGgoeWVhciwgbW9udGggKyAxKTtcblx0ICAgICAgICB0aGlzLmN1cnJEYXRlID0gbmV3IERhdGUobmV4dE1vbnRoLnllYXIsIG5leHRNb250aC5tb250aCwgZGF0ZSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBwcmVOZXh0WWVhckNsaWNrOiBmdW5jdGlvbiBwcmVOZXh0WWVhckNsaWNrKGZsYWcpIHtcblx0ICAgICAgdmFyIHllYXIgPSB0aGlzLmN1cnJEYXRlLmdldEZ1bGxZZWFyKCk7XG5cdCAgICAgIHZhciBtb250aHMgPSB0aGlzLmN1cnJEYXRlLmdldE1vbnRoKCk7XG5cdCAgICAgIHZhciBkYXRlID0gdGhpcy5jdXJyRGF0ZS5nZXREYXRlKCk7XG5cdFxuXHQgICAgICBpZiAoZmxhZyA9PT0gMCkge1xuXHQgICAgICAgIHRoaXMuY3VyckRhdGUgPSBuZXcgRGF0ZSh5ZWFyIC0gMSwgbW9udGhzLCBkYXRlKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLmN1cnJEYXRlID0gbmV3IERhdGUoeWVhciArIDEsIG1vbnRocywgZGF0ZSk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB5ZWFyU2VsZWN0OiBmdW5jdGlvbiB5ZWFyU2VsZWN0KHllYXIpIHtcblx0ICAgICAgdGhpcy5kaXNwbGF5WWVhclZpZXcgPSBmYWxzZTtcblx0ICAgICAgdGhpcy5kaXNwbGF5TW9udGhWaWV3ID0gdHJ1ZTtcblx0ICAgICAgdGhpcy5jdXJyRGF0ZSA9IG5ldyBEYXRlKHllYXIsIHRoaXMuY3VyckRhdGUuZ2V0TW9udGgoKSwgdGhpcy5jdXJyRGF0ZS5nZXREYXRlKCkpO1xuXHQgICAgfSxcblx0ICAgIGRheVNlbGVjdDogZnVuY3Rpb24gZGF5U2VsZWN0KGRheSkge1xuXHQgICAgICBpZiAoZGF5LnNjbGFzcyA9PT0gJ2RhdGVwaWNrZXItaXRlbS1kaXNhYmxlJykge1xuXHQgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLmN1cnJEYXRlID0gZGF5LmRhdGU7XG5cdCAgICAgICAgdGhpcy52YWwgPSB0aGlzLnN0cmluZ2lmeSh0aGlzLmN1cnJEYXRlKTtcblx0ICAgICAgICB0aGlzLmRpc3BsYXlEYXlWaWV3ID0gZmFsc2U7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBzd2l0Y2hNb250aFZpZXc6IGZ1bmN0aW9uIHN3aXRjaE1vbnRoVmlldygpIHtcblx0ICAgICAgdGhpcy5kaXNwbGF5RGF5VmlldyA9IGZhbHNlO1xuXHQgICAgICB0aGlzLmRpc3BsYXlNb250aFZpZXcgPSB0cnVlO1xuXHQgICAgfSxcblx0ICAgIHN3aXRjaERlY2FkZVZpZXc6IGZ1bmN0aW9uIHN3aXRjaERlY2FkZVZpZXcoKSB7XG5cdCAgICAgIHRoaXMuZGlzcGxheU1vbnRoVmlldyA9IGZhbHNlO1xuXHQgICAgICB0aGlzLmRpc3BsYXlZZWFyVmlldyA9IHRydWU7XG5cdCAgICB9LFxuXHQgICAgbW9udGhTZWxlY3Q6IGZ1bmN0aW9uIG1vbnRoU2VsZWN0KGluZGV4KSB7XG5cdCAgICAgIHRoaXMuZGlzcGxheU1vbnRoVmlldyA9IGZhbHNlO1xuXHQgICAgICB0aGlzLmRpc3BsYXlEYXlWaWV3ID0gdHJ1ZTtcblx0ICAgICAgdGhpcy5jdXJyRGF0ZSA9IG5ldyBEYXRlKHRoaXMuY3VyckRhdGUuZ2V0RnVsbFllYXIoKSwgaW5kZXgsIHRoaXMuY3VyckRhdGUuZ2V0RGF0ZSgpKTtcblx0ICAgIH0sXG5cdCAgICBnZXRZZWFyTW9udGg6IGZ1bmN0aW9uIGdldFllYXJNb250aCh5ZWFyLCBtb250aCkge1xuXHQgICAgICBpZiAobW9udGggPiAxMSkge1xuXHQgICAgICAgIHllYXIrKztcblx0ICAgICAgICBtb250aCA9IDA7XG5cdCAgICAgIH0gZWxzZSBpZiAobW9udGggPCAwKSB7XG5cdCAgICAgICAgeWVhci0tO1xuXHQgICAgICAgIG1vbnRoID0gMTE7XG5cdCAgICAgIH1cblx0ICAgICAgcmV0dXJuIHsgeWVhcjogeWVhciwgbW9udGg6IG1vbnRoIH07XG5cdCAgICB9LFxuXHQgICAgc3RyaW5naWZ5RGVjYWRlSGVhZGVyOiBmdW5jdGlvbiBzdHJpbmdpZnlEZWNhZGVIZWFkZXIoZGF0ZSkge1xuXHQgICAgICB2YXIgeWVhclN0ciA9IGRhdGUuZ2V0RnVsbFllYXIoKS50b1N0cmluZygpO1xuXHQgICAgICB2YXIgZmlyc3RZZWFyT2ZEZWNhZGUgPSB5ZWFyU3RyLnN1YnN0cmluZygwLCB5ZWFyU3RyLmxlbmd0aCAtIDEpICsgMDtcblx0ICAgICAgdmFyIGxhc3RZZWFyT2ZEZWNhZGUgPSBwYXJzZUludChmaXJzdFllYXJPZkRlY2FkZSwgMTApICsgMTA7XG5cdCAgICAgIHJldHVybiBmaXJzdFllYXJPZkRlY2FkZSArICctJyArIGxhc3RZZWFyT2ZEZWNhZGU7XG5cdCAgICB9LFxuXHQgICAgc3RyaW5naWZ5RGF5SGVhZGVyOiBmdW5jdGlvbiBzdHJpbmdpZnlEYXlIZWFkZXIoZGF0ZSkge1xuXHQgICAgICByZXR1cm4gdGhpcy50ZXh0Lm1vbnRoc1tkYXRlLmdldE1vbnRoKCldICsgJyAnICsgZGF0ZS5nZXRGdWxsWWVhcigpO1xuXHQgICAgfSxcblx0ICAgIHBhcnNlTW9udGg6IGZ1bmN0aW9uIHBhcnNlTW9udGgoZGF0ZSkge1xuXHQgICAgICByZXR1cm4gdGhpcy50ZXh0Lm1vbnRoc1tkYXRlLmdldE1vbnRoKCldO1xuXHQgICAgfSxcblx0ICAgIHN0cmluZ2lmeVllYXJIZWFkZXI6IGZ1bmN0aW9uIHN0cmluZ2lmeVllYXJIZWFkZXIoZGF0ZSkge1xuXHQgICAgICByZXR1cm4gZGF0ZS5nZXRGdWxsWWVhcigpO1xuXHQgICAgfSxcblx0ICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gc3RyaW5naWZ5KGRhdGUpIHtcblx0ICAgICAgdmFyIGZvcm1hdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogdGhpcy5mb3JtYXQ7XG5cdFxuXHQgICAgICBpZiAoIWRhdGUpIGRhdGUgPSB0aGlzLnBhcnNlKCk7XG5cdCAgICAgIGlmICghZGF0ZSkgcmV0dXJuICcnO1xuXHQgICAgICB2YXIgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblx0ICAgICAgdmFyIG1vbnRoID0gZGF0ZS5nZXRNb250aCgpICsgMTtcblx0ICAgICAgdmFyIGRheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHQgICAgICB2YXIgbW9udGhOYW1lID0gdGhpcy5wYXJzZU1vbnRoKGRhdGUpO1xuXHQgICAgICByZXR1cm4gZm9ybWF0LnJlcGxhY2UoL3l5eXkvZywgeWVhcikucmVwbGFjZSgveXkvZywgeWVhcikucmVwbGFjZSgvTU1NTS9nLCBtb250aE5hbWUpLnJlcGxhY2UoL01NTS9nLCBtb250aE5hbWUuc3Vic3RyaW5nKDAsIDMpKS5yZXBsYWNlKC9NTS9nLCAoJzAnICsgbW9udGgpLnNsaWNlKC0yKSkucmVwbGFjZSgvTSg/IWEpL2csIG1vbnRoKS5yZXBsYWNlKC9kZC9nLCAoJzAnICsgZGF5KS5zbGljZSgtMikpLnJlcGxhY2UoL2QvZywgZGF5KTtcblx0ICAgIH0sXG5cdCAgICBwYXJzZTogZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG5cdCAgICAgIGlmIChzdHIgPT09IHVuZGVmaW5lZCB8fCBzdHIgPT09IG51bGwpIHtcblx0ICAgICAgICBzdHIgPSB0aGlzLnZhbDtcblx0ICAgICAgfVxuXHQgICAgICB2YXIgZGF0ZSA9IHN0ci5sZW5ndGggPT09IDEwICYmICh0aGlzLmZvcm1hdCA9PT0gJ2RkLU1NLXl5eXknIHx8IHRoaXMuZm9ybWF0ID09PSAnZGQvTU0veXl5eScpID8gbmV3IERhdGUoc3RyLnN1YnN0cmluZyg2LCAxMCksIHN0ci5zdWJzdHJpbmcoMywgNSkgLSAxLCBzdHIuc3Vic3RyaW5nKDAsIDIpKSA6IG5ldyBEYXRlKHN0cik7XG5cdCAgICAgIHJldHVybiBpc05hTihkYXRlLmdldEZ1bGxZZWFyKCkpID8gbmV3IERhdGUoKSA6IGRhdGU7XG5cdCAgICB9LFxuXHQgICAgZ2V0RGF5Q291bnQ6IGZ1bmN0aW9uIGdldERheUNvdW50KHllYXIsIG1vbnRoKSB7XG5cdCAgICAgIHZhciBkaWN0ID0gWzMxLCAyOCwgMzEsIDMwLCAzMSwgMzAsIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzFdO1xuXHQgICAgICBpZiAobW9udGggPT09IDEpIHtcblx0ICAgICAgICBpZiAoeWVhciAlIDQwMCA9PT0gMCB8fCB5ZWFyICUgNCA9PT0gMCAmJiB5ZWFyICUgMTAwICE9PSAwKSB7XG5cdCAgICAgICAgICByZXR1cm4gMjk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiBkaWN0W21vbnRoXTtcblx0ICAgIH0sXG5cdCAgICBnZXREYXRlUmFuZ2U6IGZ1bmN0aW9uIGdldERhdGVSYW5nZSgpIHtcblx0ICAgICAgdGhpcy5kYXRlUmFuZ2UgPSBbXTtcblx0ICAgICAgdGhpcy5kZWNhZGVSYW5nZSA9IFtdO1xuXHQgICAgICB2YXIgdGltZSA9IHtcblx0ICAgICAgICB5ZWFyOiB0aGlzLmN1cnJEYXRlLmdldEZ1bGxZZWFyKCksXG5cdCAgICAgICAgbW9udGg6IHRoaXMuY3VyckRhdGUuZ2V0TW9udGgoKSxcblx0ICAgICAgICBkYXk6IHRoaXMuY3VyckRhdGUuZ2V0RGF0ZSgpXG5cdCAgICAgIH07XG5cdCAgICAgIHZhciB5ZWFyU3RyID0gdGltZS55ZWFyLnRvU3RyaW5nKCk7XG5cdCAgICAgIHZhciBmaXJzdFllYXJPZkRlY2FkZSA9IHllYXJTdHIuc3Vic3RyaW5nKDAsIHllYXJTdHIubGVuZ3RoIC0gMSkgKyAwIC0gMTtcblx0ICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG5cdCAgICAgICAgdGhpcy5kZWNhZGVSYW5nZS5wdXNoKHtcblx0ICAgICAgICAgIHRleHQ6IGZpcnN0WWVhck9mRGVjYWRlICsgaVxuXHQgICAgICAgIH0pO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICB2YXIgY3Vyck1vbnRoRmlyc3REYXkgPSBuZXcgRGF0ZSh0aW1lLnllYXIsIHRpbWUubW9udGgsIDEpO1xuXHQgICAgICB2YXIgZmlyc3REYXlXZWVrID0gY3Vyck1vbnRoRmlyc3REYXkuZ2V0RGF5KCkgKyAxO1xuXHQgICAgICBpZiAoZmlyc3REYXlXZWVrID09PSAwKSB7XG5cdCAgICAgICAgZmlyc3REYXlXZWVrID0gNztcblx0ICAgICAgfVxuXHQgICAgICB2YXIgZGF5Q291bnQgPSB0aGlzLmdldERheUNvdW50KHRpbWUueWVhciwgdGltZS5tb250aCk7XG5cdCAgICAgIGlmIChmaXJzdERheVdlZWsgPiAxKSB7XG5cdCAgICAgICAgdmFyIHByZU1vbnRoID0gdGhpcy5nZXRZZWFyTW9udGgodGltZS55ZWFyLCB0aW1lLm1vbnRoIC0gMSk7XG5cdCAgICAgICAgdmFyIHByZXZNb250aERheUNvdW50ID0gdGhpcy5nZXREYXlDb3VudChwcmVNb250aC55ZWFyLCBwcmVNb250aC5tb250aCk7XG5cdCAgICAgICAgZm9yICh2YXIgX2kgPSAxOyBfaSA8IGZpcnN0RGF5V2VlazsgX2krKykge1xuXHQgICAgICAgICAgdmFyIGRheVRleHQgPSBwcmV2TW9udGhEYXlDb3VudCAtIGZpcnN0RGF5V2VlayArIF9pICsgMTtcblx0ICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUocHJlTW9udGgueWVhciwgcHJlTW9udGgubW9udGgsIGRheVRleHQpO1xuXHQgICAgICAgICAgdmFyIHNjbGFzcyA9ICdkYXRlcGlja2VyLWl0ZW0tZ3JheSc7XG5cdCAgICAgICAgICBpZiAodGhpcy5kaXNhYmxlZERheXNBcnJheS5pbmRleE9mKGRhdGUuZ2V0RGF5KCkpID4gLTEpIHtcblx0ICAgICAgICAgICAgc2NsYXNzID0gJ2RhdGVwaWNrZXItaXRlbS1kaXNhYmxlJztcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIHRoaXMuZGF0ZVJhbmdlLnB1c2goeyB0ZXh0OiBkYXlUZXh0LCBkYXRlOiBkYXRlLCBzY2xhc3M6IHNjbGFzcyB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIGZvciAodmFyIF9pMiA9IDE7IF9pMiA8PSBkYXlDb3VudDsgX2kyKyspIHtcblx0ICAgICAgICB2YXIgX2RhdGUgPSBuZXcgRGF0ZSh0aW1lLnllYXIsIHRpbWUubW9udGgsIF9pMik7XG5cdCAgICAgICAgdmFyIF9zY2xhc3MgPSAnJztcblx0ICAgICAgICBpZiAodGhpcy5kaXNhYmxlZERheXNBcnJheS5pbmRleE9mKF9kYXRlLmdldERheSgpKSA+IC0xKSB7XG5cdCAgICAgICAgICBfc2NsYXNzID0gJ2RhdGVwaWNrZXItaXRlbS1kaXNhYmxlJztcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKF9pMiA9PSB0aW1lLmRheSAmJiBfZGF0ZS5nZXRGdWxsWWVhcigpID09IHRpbWUueWVhciAmJiBfZGF0ZS5nZXRNb250aCgpID09IHRpbWUubW9udGgpIHtcblx0ICAgICAgICAgIF9zY2xhc3MgPSAnZGF0ZXBpY2tlci1kYXRlUmFuZ2UtaXRlbS1hY3RpdmUnO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB0aGlzLmRhdGVSYW5nZS5wdXNoKHsgdGV4dDogX2kyLCBkYXRlOiBfZGF0ZSwgc2NsYXNzOiBfc2NsYXNzIH0pO1xuXHQgICAgICB9XG5cdFxuXHQgICAgICBpZiAodGhpcy5kYXRlUmFuZ2UubGVuZ3RoIDwgNDIpIHtcblx0ICAgICAgICB2YXIgbmV4dE1vbnRoTmVlZCA9IDQyIC0gdGhpcy5kYXRlUmFuZ2UubGVuZ3RoO1xuXHQgICAgICAgIHZhciBuZXh0TW9udGggPSB0aGlzLmdldFllYXJNb250aCh0aW1lLnllYXIsIHRpbWUubW9udGggKyAxKTtcblx0XG5cdCAgICAgICAgZm9yICh2YXIgX2kzID0gMTsgX2kzIDw9IG5leHRNb250aE5lZWQ7IF9pMysrKSB7XG5cdCAgICAgICAgICB2YXIgX2RhdGUyID0gbmV3IERhdGUobmV4dE1vbnRoLnllYXIsIG5leHRNb250aC5tb250aCwgX2kzKTtcblx0ICAgICAgICAgIHZhciBfc2NsYXNzMiA9ICdkYXRlcGlja2VyLWl0ZW0tZ3JheSc7XG5cdCAgICAgICAgICBpZiAodGhpcy5kaXNhYmxlZERheXNBcnJheS5pbmRleE9mKF9kYXRlMi5nZXREYXkoKSkgPiAtMSkge1xuXHQgICAgICAgICAgICBfc2NsYXNzMiA9ICdkYXRlcGlja2VyLWl0ZW0tZGlzYWJsZSc7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgICB0aGlzLmRhdGVSYW5nZS5wdXNoKHsgdGV4dDogX2kzLCBkYXRlOiBfZGF0ZTIsIHNjbGFzczogX3NjbGFzczIgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkKCkge1xuXHQgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICB0aGlzLiRlbWl0KCdjaGlsZC1jcmVhdGVkJywgdGhpcyk7XG5cdCAgICB0aGlzLmN1cnJEYXRlID0gdGhpcy5wYXJzZSh0aGlzLnZhbCkgfHwgdGhpcy5wYXJzZShuZXcgRGF0ZSgpKTtcblx0ICAgIHRoaXMuX2JsdXIgPSBmdW5jdGlvbiAoZSkge1xuXHQgICAgICBpZiAoIV90aGlzLiRlbC5jb250YWlucyhlLnRhcmdldCkpIF90aGlzLmNsb3NlKCk7XG5cdCAgICB9O1xuXHQgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYmx1cik7XG5cdCAgfSxcblx0ICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbiBiZWZvcmVEZXN0cm95KCkge1xuXHQgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYmx1cik7XG5cdCAgfVxuXHR9OyAvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXG4vKioqLyB9LFxuLyogMTA0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXJcIlxuXHQgIH0sIFtfdm0uX2MoJ2lucHV0Jywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJtb2RlbFwiLFxuXHQgICAgICByYXdOYW1lOiBcInYtbW9kZWxcIixcblx0ICAgICAgdmFsdWU6IChfdm0udmFsKSxcblx0ICAgICAgZXhwcmVzc2lvbjogXCJ2YWxcIlxuXHQgICAgfV0sXG5cdCAgICBzdGF0aWNDbGFzczogXCJmb3JtLWNvbnRyb2wgZGF0ZXBpY2tlci1pbnB1dFwiLFxuXHQgICAgY2xhc3M6IHtcblx0ICAgICAgJ3dpdGgtcmVzZXQtYnV0dG9uJzogX3ZtLmNsZWFyQnV0dG9uXG5cdCAgICB9LFxuXHQgICAgc3R5bGU6ICh7XG5cdCAgICAgIHdpZHRoOiBfdm0ud2lkdGhcblx0ICAgIH0pLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJ0eXBlXCI6IFwidGV4dFwiLFxuXHQgICAgICBcInBsYWNlaG9sZGVyXCI6IF92bS5wbGFjZWhvbGRlclxuXHQgICAgfSxcblx0ICAgIGRvbVByb3BzOiB7XG5cdCAgICAgIFwidmFsdWVcIjogX3ZtLl9zKF92bS52YWwpXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBfdm0uaW5wdXRDbGljayxcblx0ICAgICAgXCJpbnB1dFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBpZiAoJGV2ZW50LnRhcmdldC5jb21wb3NpbmcpIHsgcmV0dXJuOyB9XG5cdCAgICAgICAgX3ZtLnZhbCA9ICRldmVudC50YXJnZXQudmFsdWVcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLmNsZWFyQnV0dG9uICYmIF92bS52YWwpID8gX3ZtLl9jKCdidXR0b24nLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJjbG9zZVwiLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJ0eXBlXCI6IFwiYnV0dG9uXCJcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIF92bS52YWwgPSAnJ1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygnc3BhbicsIFtfdm0uX3YoXCLDl1wiKV0pXSkgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcInNob3dcIixcblx0ICAgICAgcmF3TmFtZTogXCJ2LXNob3dcIixcblx0ICAgICAgdmFsdWU6IChfdm0uZGlzcGxheURheVZpZXcpLFxuXHQgICAgICBleHByZXNzaW9uOiBcImRpc3BsYXlEYXlWaWV3XCJcblx0ICAgIH1dLFxuXHQgICAgc3RhdGljQ2xhc3M6IFwiZGF0ZXBpY2tlci1wb3B1cFwiXG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZGF0ZXBpY2tlci1pbm5lclwiXG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZGF0ZXBpY2tlci1ib2R5XCJcblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJkYXRlcGlja2VyLWN0cmxcIlxuXHQgIH0sIFtfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBjbGFzczogX3ZtLnByZUJ0bkNsYXNzZXMsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImFyaWEtaGlkZGVuXCI6IFwidHJ1ZVwiXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBfdm0ucHJlTmV4dE1vbnRoQ2xpY2soMClcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBjbGFzczogX3ZtLm5leHRCdG5DbGFzc2VzLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJhcmlhLWhpZGRlblwiOiBcInRydWVcIlxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnByZU5leHRNb250aENsaWNrKDEpXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdwJywge1xuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBfdm0uc3dpdGNoTW9udGhWaWV3XG5cdCAgICB9XG5cdCAgfSwgW192bS5fdihfdm0uX3MoX3ZtLnN0cmluZ2lmeURheUhlYWRlcihfdm0uY3VyckRhdGUpKSldKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItd2Vla1JhbmdlXCJcblx0ICB9LCBfdm0uX2woKF92bS50ZXh0LmRheXNPZldlZWspLCBmdW5jdGlvbih3KSB7XG5cdCAgICByZXR1cm4gX3ZtLl9jKCdzcGFuJywgW192bS5fdihfdm0uX3ModykpXSlcblx0ICB9KSksIF92bS5fdihcIiBcIiksIF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZGF0ZXBpY2tlci1kYXRlUmFuZ2VcIlxuXHQgIH0sIF92bS5fbCgoX3ZtLmRhdGVSYW5nZSksIGZ1bmN0aW9uKGQpIHtcblx0ICAgIHJldHVybiBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICAgIGNsYXNzOiBkLnNjbGFzcyxcblx0ICAgICAgb246IHtcblx0ICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICAgX3ZtLmRheVNlbGVjdChkKVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSwgW192bS5fdihfdm0uX3MoZC50ZXh0KSldKVxuXHQgIH0pKV0pXSldKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcInNob3dcIixcblx0ICAgICAgcmF3TmFtZTogXCJ2LXNob3dcIixcblx0ICAgICAgdmFsdWU6IChfdm0uZGlzcGxheU1vbnRoVmlldyksXG5cdCAgICAgIGV4cHJlc3Npb246IFwiZGlzcGxheU1vbnRoVmlld1wiXG5cdCAgICB9XSxcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItcG9wdXBcIlxuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItaW5uZXJcIlxuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItYm9keVwiXG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZGF0ZXBpY2tlci1jdHJsXCJcblx0ICB9LCBbX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgY2xhc3M6IF92bS5wcmVCdG5DbGFzc2VzLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJhcmlhLWhpZGRlblwiOiBcInRydWVcIlxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnByZU5leHRZZWFyQ2xpY2soMClcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBjbGFzczogX3ZtLm5leHRCdG5DbGFzc2VzLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJhcmlhLWhpZGRlblwiOiBcInRydWVcIlxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnByZU5leHRZZWFyQ2xpY2soMSlcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ3AnLCB7XG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IF92bS5zd2l0Y2hEZWNhZGVWaWV3XG5cdCAgICB9XG5cdCAgfSwgW192bS5fdihfdm0uX3MoX3ZtLnN0cmluZ2lmeVllYXJIZWFkZXIoX3ZtLmN1cnJEYXRlKSkpXSldKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJkYXRlcGlja2VyLW1vbnRoUmFuZ2VcIlxuXHQgIH0sIFtfdm0uX2woKF92bS50ZXh0Lm1vbnRocyksIGZ1bmN0aW9uKG0sIGluZGV4KSB7XG5cdCAgICByZXR1cm4gW192bS5fYygnc3BhbicsIHtcblx0ICAgICAgY2xhc3M6IHtcblx0ICAgICAgICAnZGF0ZXBpY2tlci1kYXRlUmFuZ2UtaXRlbS1hY3RpdmUnOlxuXHQgICAgICAgIChfdm0udGV4dC5tb250aHNbX3ZtLnBhcnNlKF92bS52YWwpLmdldE1vbnRoKCldID09PSBtKSAmJlxuXHQgICAgICAgIF92bS5jdXJyRGF0ZS5nZXRGdWxsWWVhcigpID09PSBfdm0ucGFyc2UoX3ZtLnZhbCkuZ2V0RnVsbFllYXIoKVxuXHQgICAgICB9LFxuXHQgICAgICBkb21Qcm9wczoge1xuXHQgICAgICAgIFwidGV4dENvbnRlbnRcIjogX3ZtLl9zKG0uc3Vic3RyKDAsIDMpKVxuXHQgICAgICB9LFxuXHQgICAgICBvbjoge1xuXHQgICAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgICBfdm0ubW9udGhTZWxlY3QoaW5kZXgpXG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9KV1cblx0ICB9KV0sIDIpXSldKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIGRpcmVjdGl2ZXM6IFt7XG5cdCAgICAgIG5hbWU6IFwic2hvd1wiLFxuXHQgICAgICByYXdOYW1lOiBcInYtc2hvd1wiLFxuXHQgICAgICB2YWx1ZTogKF92bS5kaXNwbGF5WWVhclZpZXcpLFxuXHQgICAgICBleHByZXNzaW9uOiBcImRpc3BsYXlZZWFyVmlld1wiXG5cdCAgICB9XSxcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItcG9wdXBcIlxuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItaW5uZXJcIlxuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItYm9keVwiXG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZGF0ZXBpY2tlci1jdHJsXCJcblx0ICB9LCBbX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgY2xhc3M6IF92bS5wcmVCdG5DbGFzc2VzLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJhcmlhLWhpZGRlblwiOiBcInRydWVcIlxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnByZU5leHREZWNhZGVDbGljaygwKVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSksIF92bS5fdihcIiBcIiksIF92bS5fYygnc3BhbicsIHtcblx0ICAgIGNsYXNzOiBfdm0ubmV4dEJ0bkNsYXNzZXMsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImFyaWEtaGlkZGVuXCI6IFwidHJ1ZVwiXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBfdm0ucHJlTmV4dERlY2FkZUNsaWNrKDEpXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdwJywgW192bS5fdihfdm0uX3MoX3ZtLnN0cmluZ2lmeURlY2FkZUhlYWRlcihfdm0uY3VyckRhdGUpKSldKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImRhdGVwaWNrZXItbW9udGhSYW5nZSBkZWNhZGVSYW5nZVwiXG5cdCAgfSwgW192bS5fbCgoX3ZtLmRlY2FkZVJhbmdlKSwgZnVuY3Rpb24oZGVjYWRlKSB7XG5cdCAgICByZXR1cm4gW192bS5fYygnc3BhbicsIHtcblx0ICAgICAgY2xhc3M6IHtcblx0ICAgICAgICAnZGF0ZXBpY2tlci1kYXRlUmFuZ2UtaXRlbS1hY3RpdmUnOiBfdm0ucGFyc2UoX3ZtLnZhbCkuZ2V0RnVsbFllYXIoKSA9PT0gZGVjYWRlLnRleHRcblx0ICAgICAgfSxcblx0ICAgICAgZG9tUHJvcHM6IHtcblx0ICAgICAgICBcInRleHRDb250ZW50XCI6IF92bS5fcyhkZWNhZGUudGV4dClcblx0ICAgICAgfSxcblx0ICAgICAgb246IHtcblx0ICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHQgICAgICAgICAgX3ZtLnllYXJTZWxlY3QoZGVjYWRlLnRleHQpXG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9KV1cblx0ICB9KV0sIDIpXSldKV0pXSlcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtNDc3YjhlNWRcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxMDUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTA2KVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEwNylcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxEcm9wZG93bi52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtMzliZTEwNzJcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTM5YmUxMDcyXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gRHJvcGRvd24udnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTA2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfTm9kZUxpc3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXHRcblx0dmFyIF9Ob2RlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Ob2RlTGlzdCk7XG5cdFxuXHR2YXIgX0NsaWNrT3V0c2lkZSA9IF9fd2VicGFja19yZXF1aXJlX18oNjYpO1xuXHRcblx0dmFyIF9DbGlja091dHNpZGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2xpY2tPdXRzaWRlKTtcblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cdFxuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIGRpcmVjdGl2ZXM6IHtcblx0ICAgIENsaWNrT3V0c2lkZTogX0NsaWNrT3V0c2lkZTIuZGVmYXVsdFxuXHQgIH0sXG5cdCAgcHJvcHM6IHtcblx0ICAgIGRpc2FibGVkOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH0sXG5cdCAgICBzaXplOiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgdGV4dDogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIHR5cGU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnZGVmYXVsdCcgfSxcblx0ICAgIHZhbHVlOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH1cblx0ICB9LFxuXHQgIGRhdGE6IGZ1bmN0aW9uIGRhdGEoKSB7XG5cdCAgICB2YXIgc2hvdyA9IHRoaXMudmFsdWU7XG5cdCAgICByZXR1cm4geyBzaG93OiBzaG93IH07XG5cdCAgfSxcblx0XG5cdCAgd2F0Y2g6IHtcblx0ICAgIHNob3c6IGZ1bmN0aW9uIHNob3codmFsKSB7XG5cdCAgICAgIHRoaXMuJGVtaXQoJ2lucHV0JywgdmFsKTtcblx0ICAgIH0sXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUodmFsKSB7XG5cdCAgICAgIHRoaXMuc2hvdyA9IHZhbDtcblx0ICAgIH1cblx0ICB9LFxuXHQgIGNvbXB1dGVkOiB7XG5cdCAgICBidXR0b25TaXplOiBmdW5jdGlvbiBidXR0b25TaXplKCkge1xuXHQgICAgICByZXR1cm4gflsnbGcnLCAnc20nLCAneHMnXS5pbmRleE9mKHRoaXMuc2l6ZSkgPyAnYnRuLScgKyB0aGlzLnNpemUgOiAnJztcblx0ICAgIH0sXG5cdCAgICBpbklucHV0OiBmdW5jdGlvbiBpbklucHV0KCkge1xuXHQgICAgICByZXR1cm4gdGhpcy4kcGFyZW50Ll9pbnB1dDtcblx0ICAgIH0sXG5cdCAgICBpc0xpOiBmdW5jdGlvbiBpc0xpKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy4kcGFyZW50Ll9pc1RhYnMgfHwgdGhpcy4kcGFyZW50Ll9uYXZiYXIgfHwgdGhpcy4kcGFyZW50Lm1lbnU7XG5cdCAgICB9LFxuXHQgICAgbWVudTogZnVuY3Rpb24gbWVudSgpIHtcblx0ICAgICAgcmV0dXJuICF0aGlzLiRwYXJlbnQgfHwgdGhpcy4kcGFyZW50Lm5hdmJhcjtcblx0ICAgIH0sXG5cdCAgICBzbG90czogZnVuY3Rpb24gc2xvdHMoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLl9zbG90Q29udGVudHM7XG5cdCAgICB9LFxuXHQgICAgc3VibWVudTogZnVuY3Rpb24gc3VibWVudSgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuJHBhcmVudCAmJiAodGhpcy4kcGFyZW50Lm1lbnUgfHwgdGhpcy4kcGFyZW50LnN1Ym1lbnUpO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbWV0aG9kczoge1xuXHQgICAgYmx1cjogZnVuY3Rpb24gYmx1cigpIHtcblx0ICAgICAgdGhpcy5zaG93ID0gZmFsc2U7XG5cdCAgICB9LFxuXHQgICAgdG9nZ2xlOiBmdW5jdGlvbiB0b2dnbGUoKSB7XG5cdCAgICAgIGlmICghdGhpcy5kaXNhYmxlZCkge1xuXHQgICAgICAgIHRoaXMuc2hvdyA9ICF0aGlzLnNob3c7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LFxuXHQgIG1vdW50ZWQ6IGZ1bmN0aW9uIG1vdW50ZWQoKSB7XG5cdCAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICgwLCBfTm9kZUxpc3QyLmRlZmF1bHQpKCd1bCcsIHRoaXMuJGVsKS5vbignY2xpY2snLCAnbGk+YScsIGZ1bmN0aW9uIChlKSB7XG5cdCAgICAgIF90aGlzLnNob3cgPSBmYWxzZTtcblx0ICAgIH0pO1xuXHQgIH0sXG5cdCAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24gYmVmb3JlRGVzdHJveSgpIHtcblx0ICAgICgwLCBfTm9kZUxpc3QyLmRlZmF1bHQpKCd1bCcsIHRoaXMuJGVsKS5vZmYoKTtcblx0ICB9XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxMDcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYyhfdm0uaXNMaSA/ICdsaScgOiAnZGl2Jywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJjbGljay1vdXRzaWRlXCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1jbGljay1vdXRzaWRlXCIsXG5cdCAgICAgIHZhbHVlOiAoX3ZtLmJsdXIpLFxuXHQgICAgICBleHByZXNzaW9uOiBcImJsdXJcIlxuXHQgICAgfV0sXG5cdCAgICB0YWc6IFwiZGl2XCIsXG5cdCAgICBjbGFzczogW3tcblx0ICAgICAgb3BlbjogX3ZtLnNob3csXG5cdCAgICAgIGRpc2FibGVkOiBfdm0uZGlzYWJsZWQsXG5cdCAgICAgIGRyb3Bkb3duOiBfdm0uaXNMaSxcblx0ICAgICAgJ2lucHV0LWdyb3VwLWJ0bic6IF92bS5pbklucHV0LFxuXHQgICAgICAnYnRuLWdyb3VwJzogIV92bS5pc0xpICYmICFfdm0uaW5JbnB1dFxuXHQgICAgfV1cblx0ICB9LCBbX3ZtLl90KFwiYmVmb3JlXCIpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLmlzTGkpID8gX3ZtLl9jKCdhJywge1xuXHQgICAgY2xhc3M6IFsnZHJvcGRvd24tdG9nZ2xlJywgX3ZtLmJ1dHRvblNpemUsIHtcblx0ICAgICAgZGlzYWJsZWQ6IF92bS5kaXNhYmxlZFxuXHQgICAgfV0sXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcInJvbGVcIjogXCJidXR0b25cIlxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwia2V5dXBcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgaWYgKF92bS5faygkZXZlbnQua2V5Q29kZSwgXCJlc2NcIiwgMjcpKSB7IHJldHVybjsgfVxuXHQgICAgICAgIF92bS5zaG93ID0gZmFsc2Vcblx0ICAgICAgfSxcblx0ICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICBfdm0udG9nZ2xlKCRldmVudClcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0sIFtfdm0uX3QoXCJidXR0b25cIiwgW192bS5fdihfdm0uX3MoX3ZtLnRleHQpKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJjYXJldFwiXG5cdCAgfSldLCAyKSA6IF92bS5fYygnYnV0dG9uJywge1xuXHQgICAgY2xhc3M6IFsnYnRuIGJ0bi0nICsgX3ZtLnR5cGUsIF92bS5idXR0b25TaXplLCAnZHJvcGRvd24tdG9nZ2xlJ10sXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcInR5cGVcIjogXCJidXR0b25cIixcblx0ICAgICAgXCJkaXNhYmxlZFwiOiBfdm0uZGlzYWJsZWRcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImtleXVwXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIGlmIChfdm0uX2soJGV2ZW50LmtleUNvZGUsIFwiZXNjXCIsIDI3KSkgeyByZXR1cm47IH1cblx0ICAgICAgICBfdm0uc2hvdyA9IGZhbHNlXG5cdCAgICAgIH0sXG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgX3ZtLnRvZ2dsZSgkZXZlbnQpXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LCBbX3ZtLl90KFwiYnV0dG9uXCIsIFtfdm0uX3YoX3ZtLl9zKF92bS50ZXh0KSldKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiY2FyZXRcIlxuXHQgIH0pXSwgMiksIF92bS5fdihcIiBcIiksIF92bS5fdChcImRyb3Bkb3duLW1lbnVcIiwgW192bS5fYygndWwnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJkcm9wZG93bi1tZW51XCJcblx0ICB9LCBbX3ZtLl90KFwiZGVmYXVsdFwiKV0sIDIpXSldLCAyKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi0zOWJlMTA3MlwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDEwOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMDkpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTEwKVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXEZvcm1Hcm91cC52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNzllYjQwMGFcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTc5ZWI0MDBhXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gRm9ybUdyb3VwLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDEwOSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdFxuXHR2YXIgX05vZGVMaXN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblx0XG5cdHZhciBfTm9kZUxpc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTm9kZUxpc3QpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblx0XG5cdC8vIGxldCBjb2VyY2UgPSB7XG5cdC8vICAgICBlbnRlclN1Ym1pdDogJ2Jvb2xlYW4nLFxuXHQvLyAgICAgaWNvbjogJ2Jvb2xlYW4nXG5cdC8vIH1cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgZW50ZXJTdWJtaXQ6IHtcblx0ICAgICAgdHlwZTogQm9vbGVhbixcblx0ICAgICAgZGVmYXVsdDogZmFsc2Vcblx0ICAgIH0sXG5cdCAgICBpY29uOiB7XG5cdCAgICAgIHR5cGU6IEJvb2xlYW4sXG5cdCAgICAgIGRlZmF1bHQ6IGZhbHNlXG5cdCAgICB9LFxuXHQgICAgbGFuZzoge1xuXHQgICAgICB0eXBlOiBTdHJpbmcsXG5cdCAgICAgIGRlZmF1bHQ6IG5hdmlnYXRvci5sYW5ndWFnZVxuXHQgICAgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIGNoaWxkcmVuOiBbXSxcblx0ICAgICAgdmFsaWQ6IG51bGwsXG5cdCAgICAgIHRpbWVvdXQ6IG51bGxcblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgd2F0Y2g6IHtcblx0ICAgIHZhbGlkOiBmdW5jdGlvbiB2YWxpZCh2YWwsIG9sZCkge1xuXHQgICAgICB0aGlzLiRlbWl0KCdpc3ZhbGlkJywgdmFsKTtcblx0ICAgICAgdGhpcy4kZW1pdCghdmFsID8gJ2ludmFsaWQnIDogJ3ZhbGlkJyk7XG5cdCAgICAgIGlmICh2YWwgIT09IG9sZCAmJiB0aGlzLl9wYXJlbnQpIHRoaXMuX3BhcmVudC52YWxpZGF0ZSgpO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbWV0aG9kczoge1xuXHQgICAgdmFsaWRhdGU6IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuXHQgICAgICB2YXIgdmFsaWQgPSB0cnVlO1xuXHQgICAgICB0aGlzLmNoaWxkcmVuLnNvbWUoZnVuY3Rpb24gKGVsKSB7XG5cdCAgICAgICAgdmFyIHYgPSBlbC52YWxpZGF0ZSA/IGVsLnZhbGlkYXRlKCkgOiBlbC52YWxpZCAhPT0gdW5kZWZpbmVkID8gZWwudmFsaWQgOiBlbC5yZXF1aXJlZCAmJiAhflsnJywgbnVsbCwgdW5kZWZpbmVkXS5pbmRleE9mKGVsLnZhbHVlKTtcblx0ICAgICAgICBpZiAoIXYpIHZhbGlkID0gZmFsc2U7XG5cdCAgICAgICAgcmV0dXJuICF2YWxpZDtcblx0ICAgICAgfSk7XG5cdCAgICAgIHRoaXMudmFsaWQgPSB2YWxpZDtcblx0ICAgICAgcmV0dXJuIHZhbGlkID09PSB0cnVlO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIHRoaXMuX2Zvcm1Hcm91cCA9IHRydWU7XG5cdCAgICB2YXIgcGFyZW50ID0gdGhpcy4kcGFyZW50O1xuXHQgICAgd2hpbGUgKHBhcmVudCAmJiAhcGFyZW50Ll9mb3JtR3JvdXApIHtcblx0ICAgICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XG5cdCAgICB9XG5cdCAgICBpZiAocGFyZW50ICYmIHBhcmVudC5fZm9ybUdyb3VwKSB7XG5cdCAgICAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKHRoaXMpO1xuXHQgICAgICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkKCkge1xuXHQgICAgdGhpcy52YWxpZGF0ZSgpO1xuXHQgIH0sXG5cdCAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24gYmVmb3JlRGVzdHJveSgpIHtcblx0ICAgIGlmICh0aGlzLl9wYXJlbnQpIHtcblx0ICAgICAgdmFyIGluZGV4ID0gdGhpcy5fcGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcyk7XG5cdCAgICAgIHRoaXMuX3BhcmVudC5jaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDEpO1xuXHQgICAgfVxuXHQgIH1cblx0fTsgLy9cblx0Ly9cblxuLyoqKi8gfSxcbi8qIDExMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDtcblx0ICByZXR1cm4gX3ZtLl9jKCdzcGFuJywgW192bS5fdChcImRlZmF1bHRcIildLCAyKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi03OWViNDAwYVwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDExMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMTIpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTEzKVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXEZvcm1WYWxpZGF0b3IudnVlXCJcblx0X192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5cdF9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LWI5ZjU3YzQ2XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi1iOWY1N2M0NlwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIEZvcm1WYWxpZGF0b3IudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTEyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfTm9kZUxpc3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXHRcblx0dmFyIF9Ob2RlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Ob2RlTGlzdCk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIHByb3BzOiB7XG5cdCAgICBlbnRlclN1Ym1pdDogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgaWNvbjogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgbGFuZzogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG5hdmlnYXRvci5sYW5ndWFnZSB9LFxuXHQgICAgdmFsdWU6IG51bGxcblx0ICB9LFxuXHQgIGRhdGE6IGZ1bmN0aW9uIGRhdGEoKSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBjaGlsZHJlbjogW10sXG5cdCAgICAgIHZhbGlkOiBudWxsLFxuXHQgICAgICB0aW1lb3V0OiBudWxsXG5cdCAgICB9O1xuXHQgIH0sXG5cdFxuXHQgIHdhdGNoOiB7XG5cdCAgICB2YWxpZDogZnVuY3Rpb24gdmFsaWQodmFsLCBvbGQpIHtcblx0ICAgICAgdGhpcy4kZW1pdCgnaXN2YWxpZCcsIHZhbCk7XG5cdCAgICAgIHRoaXMuJGVtaXQoJ2lucHV0JywgdmFsKTtcblx0ICAgICAgdGhpcy4kZW1pdCghdmFsID8gJ2ludmFsaWQnIDogJ3ZhbGlkJyk7XG5cdCAgICAgIGlmICh2YWwgIT09IG9sZCAmJiB0aGlzLl9wYXJlbnQpIHRoaXMuX3BhcmVudC52YWxpZGF0ZSgpO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbWV0aG9kczoge1xuXHQgICAgdmFsaWRhdGU6IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuXHQgICAgICB2YXIgaW52YWxpZCA9ICF0aGlzLmNoaWxkcmVuLmV2ZXJ5KGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgIHJldHVybiBlbC52YWxpZGF0ZSA/IGVsLnZhbGlkYXRlKCkgOiBlbC52YWxpZCAhPT0gdW5kZWZpbmVkID8gZWwudmFsaWQgOiBlbC5yZXF1aXJlZCAmJiAhflsnJywgbnVsbCwgdW5kZWZpbmVkXS5pbmRleE9mKGVsLnZhbHVlKTtcblx0ICAgICAgfSk7XG5cdCAgICAgIHRoaXMudmFsaWQgPSAhaW52YWxpZDtcblx0ICAgICAgcmV0dXJuICFpbnZhbGlkO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIHRoaXMuX2Zvcm1WYWxpZGF0b3IgPSB0cnVlO1xuXHQgICAgdmFyIHBhcmVudCA9IHRoaXMuJHBhcmVudDtcblx0ICAgIHdoaWxlIChwYXJlbnQgJiYgIXBhcmVudC5fZm9ybVZhbGlkYXRvcikge1xuXHQgICAgICBwYXJlbnQgPSBwYXJlbnQuJHBhcmVudDtcblx0ICAgIH1cblx0ICAgIGlmIChwYXJlbnQgJiYgcGFyZW50Ll9mb3JtVmFsaWRhdG9yKSB7XG5cdCAgICAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKHRoaXMpO1xuXHQgICAgICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkKCkge1xuXHQgICAgdGhpcy52YWxpZGF0ZSgpO1xuXHQgIH0sXG5cdCAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24gYmVmb3JlRGVzdHJveSgpIHtcblx0ICAgIGlmICh0aGlzLl9wYXJlbnQpIHtcblx0ICAgICAgdmFyIGluZGV4ID0gdGhpcy5fcGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcyk7XG5cdCAgICAgIHRoaXMuX3BhcmVudC5jaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDEpO1xuXHQgICAgfVxuXHQgIH1cblx0fTsgLy9cblx0Ly9cblxuLyoqKi8gfSxcbi8qIDExMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDtcblx0ICByZXR1cm4gX3ZtLl9jKCdzcGFuJywgW192bS5fdChcImRlZmF1bHRcIildLCAyKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1iOWY1N2M0NlwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDExNCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzdHlsZXMgKi9cblx0X193ZWJwYWNrX3JlcXVpcmVfXygxMTUpXG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMTcpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTE4KVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXElucHV0LnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0X192dWVfb3B0aW9uc19fLl9zY29wZUlkID0gXCJkYXRhLXYtNjUyYWQ3YjlcIlxuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTY1MmFkN2I5XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi02NTJhZDdiOVwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIElucHV0LnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDExNSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblx0XG5cdC8vIGxvYWQgdGhlIHN0eWxlc1xuXHR2YXIgY29udGVudCA9IF9fd2VicGFja19yZXF1aXJlX18oMTE2KTtcblx0aWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG5cdC8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cblx0dmFyIHVwZGF0ZSA9IF9fd2VicGFja19yZXF1aXJlX18oNzkpKGNvbnRlbnQsIHt9KTtcblx0aWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG5cdC8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcblx0aWYoZmFsc2UpIHtcblx0XHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi02NTJhZDdiOSZzY29wZWQ9dHJ1ZSEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vSW5wdXQudnVlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi02NTJhZDdiOSZzY29wZWQ9dHJ1ZSEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vSW5wdXQudnVlXCIpO1xuXHRcdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcblx0fVxuXG4vKioqLyB9LFxuLyogMTE2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc4KSgpO1xuXHQvLyBpbXBvcnRzXG5cdFxuXHRcblx0Ly8gbW9kdWxlXG5cdGV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5mb3JtLWdyb3VwW2RhdGEtdi02NTJhZDdiOV0ge1xcclxcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbn1cXG5sYWJlbH4uY2xvc2VbZGF0YS12LTY1MmFkN2I5XSB7XFxyXFxuICB0b3A6IDI1cHg7XFxufVxcbi5pbnB1dC1ncm91cD4uaWNvbltkYXRhLXYtNjUyYWQ3YjldIHtcXHJcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gIGRpc3BsYXk6IHRhYmxlLWNlbGw7XFxyXFxuICB3aWR0aDowO1xcclxcbiAgei1pbmRleDogMztcXG59XFxuLmNsb3NlW2RhdGEtdi02NTJhZDdiOV0ge1xcclxcbiAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgdG9wOiAwO1xcclxcbiAgcmlnaHQ6IDA7XFxyXFxuICB6LWluZGV4OiAyO1xcclxcbiAgZGlzcGxheTogYmxvY2s7XFxyXFxuICB3aWR0aDogMzRweDtcXHJcXG4gIGhlaWdodDogMzRweDtcXHJcXG4gIGxpbmUtaGVpZ2h0OiAzNHB4O1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcbn1cXG4uaGFzLWZlZWRiYWNrIC5jbG9zZVtkYXRhLXYtNjUyYWQ3YjldIHtcXHJcXG4gIHJpZ2h0OiAyMHB4O1xcbn1cXHJcXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL0lucHV0LnZ1ZT81NmNlMTY5ZFwiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiO0FBMFFBO0VBQ0EsbUJBQUE7Q0FDQTtBQUNBO0VBQ0EsVUFBQTtDQUNBO0FBQ0E7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VBQ0EsUUFBQTtFQUNBLFdBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxPQUFBO0VBQ0EsU0FBQTtFQUNBLFdBQUE7RUFDQSxlQUFBO0VBQ0EsWUFBQTtFQUNBLGFBQUE7RUFDQSxrQkFBQTtFQUNBLG1CQUFBO0NBQ0E7QUFDQTtFQUNBLFlBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiSW5wdXQudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXBcXFwiIDpjbGFzcz1cXFwie3ZhbGlkYXRlOmNhblZhbGlkYXRlLCdoYXMtZmVlZGJhY2snOmljb24sJ2hhcy1lcnJvcic6Y2FuVmFsaWRhdGUmJnZhbGlkPT09ZmFsc2UsJ2hhcy1zdWNjZXNzJzpjYW5WYWxpZGF0ZSYmdmFsaWR9XFxcIj5cXHJcXG4gICAgPHNsb3QgbmFtZT1cXFwibGFiZWxcXFwiPjxsYWJlbCB2LWlmPVxcXCJsYWJlbFxcXCIgY2xhc3M9XFxcImNvbnRyb2wtbGFiZWxcXFwiIEBjbGljaz1cXFwiZm9jdXNcXFwiPnt7bGFiZWx9fTwvbGFiZWw+PC9zbG90PlxcclxcbiAgICA8ZGl2IHYtaWY9XFxcIiRzbG90cy5iZWZvcmV8fCRzbG90cy5hZnRlclxcXCIgY2xhc3M9XFxcImlucHV0LWdyb3VwXFxcIj5cXHJcXG4gICAgICA8c2xvdCBuYW1lPVxcXCJiZWZvcmVcXFwiPjwvc2xvdD5cXHJcXG4gICAgICA8dGV4dGFyZWEgOmlzPVxcXCJ0eXBlPT0ndGV4dGFyZWEnP3R5cGU6J2lucHV0J1xcXCIgY2xhc3M9XFxcImZvcm0tY29udHJvbFxcXCIgcmVmPVxcXCJpbnB1dFxcXCJcXHJcXG4gICAgICAgIDpjb2xzPVxcXCJjb2xzXFxcIlxcclxcbiAgICAgICAgOmRpc2FibGVkPVxcXCJkaXNhYmxlZFxcXCJcXHJcXG4gICAgICAgIDpsaXN0PVxcXCJpZF9kYXRhbGlzdFxcXCJcXHJcXG4gICAgICAgIDptYXg9XFxcImF0dHIobWF4KVxcXCJcXHJcXG4gICAgICAgIDptYXhsZW5ndGg9XFxcIm1heGxlbmd0aFxcXCJcXHJcXG4gICAgICAgIDptaW49XFxcImF0dHIobWluKVxcXCJcXHJcXG4gICAgICAgIDpuYW1lPVxcXCJuYW1lXFxcIlxcclxcbiAgICAgICAgOnBsYWNlaG9sZGVyPVxcXCJwbGFjZWhvbGRlclxcXCJcXHJcXG4gICAgICAgIDpyZWFkb25seT1cXFwicmVhZG9ubHlcXFwiXFxyXFxuICAgICAgICA6cmVxdWlyZWQ9XFxcInJlcXVpcmVkXFxcIlxcclxcbiAgICAgICAgOnJvd3M9XFxcInJvd3NcXFwiXFxyXFxuICAgICAgICA6c3RlcD1cXFwic3RlcFxcXCJcXHJcXG4gICAgICAgIDp0aXRsZT1cXFwiYXR0cih0aXRsZSlcXFwiXFxyXFxuICAgICAgICA6dHlwZT1cXFwidHlwZT09J3RleHRhcmVhJz9udWxsOnR5cGVcXFwiXFxyXFxuICAgICAgICB2LW1vZGVsPVxcXCJ2YWxcXFwiXFxyXFxuICAgICAgICBAYmx1cj1cXFwiZW1pdFxcXCIgQGZvY3VzPVxcXCJlbWl0XFxcIiBAaW5wdXQ9XFxcImVtaXRcXFwiXFxyXFxuICAgICAgICBAa2V5dXAuZW50ZXI9XFxcInR5cGUhPSd0ZXh0YXJlYScmJmVudGVyU3VibWl0JiZzdWJtaXQoKVxcXCJcXHJcXG4gICAgICA+PC90ZXh0YXJlYT5cXHJcXG4gICAgICA8ZGl2IHYtaWY9XFxcImNsZWFyQnV0dG9uICYmIHZhbHVlXFxcIiA6Y2xhc3M9XFxcIntpY29uOmljb259XFxcIj5cXHJcXG4gICAgICAgIDxzcGFuIGNsYXNzPVxcXCJjbG9zZVxcXCIgQGNsaWNrPVxcXCJ2YWx1ZSA9ICcnXFxcIj4mdGltZXM7PC9zcGFuPlxcclxcbiAgICAgIDwvZGl2PlxcclxcbiAgICAgIDxkaXYgdi1pZj1cXFwiaWNvblxcXCIgY2xhc3M9XFxcImljb25cXFwiPlxcclxcbiAgICAgICAgPHNwYW4gdi1pZj1cXFwiaWNvbiYmdmFsaWQhPT1udWxsXFxcIiA6Y2xhc3M9XFxcIlsnZm9ybS1jb250cm9sLWZlZWRiYWNrIGdseXBoaWNvbicsJ2dseXBoaWNvbi0nKyh2YWxpZD8nb2snOidyZW1vdmUnKV1cXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj48L3NwYW4+XFxyXFxuICAgICAgPC9kaXY+XFxyXFxuICAgICAgPHNsb3QgbmFtZT1cXFwiYWZ0ZXJcXFwiPjwvc2xvdD5cXHJcXG4gICAgPC9kaXY+XFxyXFxuICAgIDx0ZW1wbGF0ZSB2LWVsc2U+XFxyXFxuICAgICAgPHRleHRhcmVhIDppcz1cXFwidHlwZT09J3RleHRhcmVhJz90eXBlOidpbnB1dCdcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIHJlZj1cXFwiaW5wdXRcXFwiXFxyXFxuICAgICAgICA6Y29scz1cXFwiY29sc1xcXCJcXHJcXG4gICAgICAgIDpkaXNhYmxlZD1cXFwiZGlzYWJsZWRcXFwiXFxyXFxuICAgICAgICA6bGlzdD1cXFwiaWRfZGF0YWxpc3RcXFwiXFxyXFxuICAgICAgICA6bWF4PVxcXCJhdHRyKG1heClcXFwiXFxyXFxuICAgICAgICA6bWF4bGVuZ3RoPVxcXCJtYXhsZW5ndGhcXFwiXFxyXFxuICAgICAgICA6bWluPVxcXCJhdHRyKG1pbilcXFwiXFxyXFxuICAgICAgICA6bmFtZT1cXFwibmFtZVxcXCJcXHJcXG4gICAgICAgIDpwbGFjZWhvbGRlcj1cXFwicGxhY2Vob2xkZXJcXFwiXFxyXFxuICAgICAgICA6cmVhZG9ubHk9XFxcInJlYWRvbmx5XFxcIlxcclxcbiAgICAgICAgOnJlcXVpcmVkPVxcXCJyZXF1aXJlZFxcXCJcXHJcXG4gICAgICAgIDpyb3dzPVxcXCJyb3dzXFxcIlxcclxcbiAgICAgICAgOnN0ZXA9XFxcInN0ZXBcXFwiXFxyXFxuICAgICAgICA6dGl0bGU9XFxcImF0dHIodGl0bGUpXFxcIlxcclxcbiAgICAgICAgOnR5cGU9XFxcInR5cGU9PSd0ZXh0YXJlYSc/bnVsbDp0eXBlXFxcIlxcclxcbiAgICAgICAgdi1tb2RlbD1cXFwidmFsXFxcIlxcclxcbiAgICAgICAgQGJsdXI9XFxcImVtaXRcXFwiIEBmb2N1cz1cXFwiZW1pdFxcXCIgQGlucHV0PVxcXCJlbWl0XFxcIlxcclxcbiAgICAgICAgQGtleXVwLmVudGVyPVxcXCJ0eXBlIT0ndGV4dGFyZWEnJiZlbnRlclN1Ym1pdCYmc3VibWl0KClcXFwiXFxyXFxuICAgICAgPjwvdGV4dGFyZWE+XFxyXFxuICAgICAgPHNwYW4gdi1pZj1cXFwiY2xlYXJCdXR0b24gJiYgdmFsXFxcIiBjbGFzcz1cXFwiY2xvc2VcXFwiIEBjbGljaz1cXFwidmFsID0gJydcXFwiPiZ0aW1lczs8L3NwYW4+XFxyXFxuICAgICAgPHNwYW4gdi1pZj1cXFwiaWNvbiYmdmFsaWQhPT1udWxsXFxcIiA6Y2xhc3M9XFxcIlsnZm9ybS1jb250cm9sLWZlZWRiYWNrIGdseXBoaWNvbicsJ2dseXBoaWNvbi0nKyh2YWxpZD8nb2snOidyZW1vdmUnKV1cXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj48L3NwYW4+XFxyXFxuICAgIDwvdGVtcGxhdGU+XFxyXFxuICAgIDxkYXRhbGlzdCB2LWlmPVxcXCJpZF9kYXRhbGlzdFxcXCIgOmlkPVxcXCJpZF9kYXRhbGlzdFxcXCI+XFxyXFxuICAgICAgPG9wdGlvbiB2LWZvcj1cXFwib3BjIGluIG9wdGlvbnNcXFwiIDp2YWx1ZT1cXFwib3BjXFxcIj48L29wdGlvbj5cXHJcXG4gICAgPC9kYXRhbGlzdD5cXHJcXG4gICAgPGRpdiB2LWlmPVxcXCJzaG93SGVscFxcXCIgY2xhc3M9XFxcImhlbHAtYmxvY2tcXFwiIEBjbGljaz1cXFwiZm9jdXNcXFwiPnt7aGVscH19PC9kaXY+XFxyXFxuICAgIDxkaXYgdi1pZj1cXFwic2hvd0Vycm9yXFxcIiBjbGFzcz1cXFwiaGVscC1ibG9jayB3aXRoLWVycm9yc1xcXCIgQGNsaWNrPVxcXCJmb2N1c1xcXCI+e3tlcnJvclRleHR9fTwvZGl2PlxcclxcbiAgPC9kaXY+XFxyXFxuPC90ZW1wbGF0ZT5cXHJcXG5cXHJcXG48c2NyaXB0PlxcclxcbmltcG9ydCB7Y29lcmNlLCBkZWxheWVyLCB0cmFuc2xhdGlvbnN9IGZyb20gJy4vdXRpbHMvdXRpbHMuanMnXFxyXFxuaW1wb3J0ICQgZnJvbSAnLi91dGlscy9Ob2RlTGlzdC5qcydcXHJcXG5cXHJcXG52YXIgREVMQVkgPSAzMDBcXHJcXG5cXHJcXG5leHBvcnQgZGVmYXVsdCB7XFxyXFxuICBwcm9wczoge1xcclxcbiAgICBjbGVhckJ1dHRvbjoge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlfSxcXHJcXG4gICAgY29sczoge3R5cGU6IE51bWJlciwgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIGRhdGFsaXN0OiB7dHlwZTogQXJyYXksIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICBkaXNhYmxlZDoge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlfSxcXHJcXG4gICAgZW50ZXJTdWJtaXQ6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIGVycm9yOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgaGVscDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIGhpZGVIZWxwOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogdHJ1ZX0sXFxyXFxuICAgIGljb246IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIGxhYmVsOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgbGFuZzoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbmF2aWdhdG9yLmxhbmd1YWdlfSxcXHJcXG4gICAgbWFzazogbnVsbCxcXHJcXG4gICAgbWFza0RlbGF5OiB7dHlwZTogTnVtYmVyLCBkZWZhdWx0OiAxMDB9LFxcclxcbiAgICBtYXRjaDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIG1heDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIG1heGxlbmd0aDoge3R5cGU6IE51bWJlciwgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIG1pbjoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIG1pbmxlbmd0aDoge3R5cGU6IE51bWJlciwgZGVmYXVsdDogMH0sXFxyXFxuICAgIG5hbWU6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICBwYXR0ZXJuOiB7ZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIHBsYWNlaG9sZGVyOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgcmVhZG9ubHk6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIHJlcXVpcmVkOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICByb3dzOiB7dHlwZTogTnVtYmVyLCBkZWZhdWx0OiAzfSxcXHJcXG4gICAgc3RlcDoge3R5cGU6IE51bWJlciwgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIHR5cGU6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICd0ZXh0J30sXFxyXFxuICAgIHVybDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIHVybE1hcDoge3R5cGU6IEZ1bmN0aW9uLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgdmFsaWRhdGlvbkRlbGF5OiB7dHlwZTogTnVtYmVyLCBkZWZhdWx0OiAyNTB9LFxcclxcbiAgICB2YWx1ZToge2RlZmF1bHQ6IG51bGx9XFxyXFxuICB9LFxcclxcbiAgZGF0YSAoKSB7XFxyXFxuICAgIHZhciB2YWwgPSB0aGlzLnZhbHVlXFxyXFxuICAgIHJldHVybiB7XFxyXFxuICAgICAgb3B0aW9uczogdGhpcy5kYXRhbGlzdCxcXHJcXG4gICAgICB2YWwsXFxyXFxuICAgICAgdmFsaWQ6IG51bGwsXFxyXFxuICAgICAgdGltZW91dDogbnVsbFxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgY29tcHV0ZWQ6IHtcXHJcXG4gICAgY2FuVmFsaWRhdGUgKCkgeyByZXR1cm4gIXRoaXMuZGlzYWJsZWQgJiYgIXRoaXMucmVhZG9ubHkgJiYgKHRoaXMucmVxdWlyZWQgfHwgdGhpcy5yZWdleCB8fCB0aGlzLm5hdGl2ZVZhbGlkYXRlIHx8IHRoaXMubWF0Y2ggIT09IG51bGwpIH0sXFxyXFxuICAgIGVycm9yVGV4dCAoKSB7XFxyXFxuICAgICAgbGV0IHZhbHVlID0gdGhpcy52YWx1ZVxcclxcbiAgICAgIGxldCBlcnJvciA9IFt0aGlzLmVycm9yXVxcclxcbiAgICAgIGlmICghdmFsdWUgJiYgdGhpcy5yZXF1aXJlZCkgZXJyb3IucHVzaCgnKCcgKyB0aGlzLnRleHQucmVxdWlyZWQudG9Mb3dlckNhc2UoKSArICcpJylcXHJcXG4gICAgICBpZiAodmFsdWUgJiYgKHZhbHVlLmxlbmd0aCA8IHRoaXMubWlubGVuZ3RoKSkgZXJyb3IucHVzaCgnKCcgKyB0aGlzLnRleHQubWluTGVuZ3RoLnRvTG93ZXJDYXNlKCkgKyAnOiAnICsgdGhpcy5taW5sZW5ndGggKyAnKScpXFxyXFxuICAgICAgcmV0dXJuIGVycm9yLmpvaW4oJyAnKVxcclxcbiAgICB9LFxcclxcbiAgICBpZF9kYXRhbGlzdCAoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ3RleHRhcmVhJyAmJiB0aGlzLmRhdGFsaXN0IGluc3RhbmNlb2YgQXJyYXkpIHtcXHJcXG4gICAgICAgIGlmICghdGhpcy5faWRfZGF0YWxpc3QpIHtcXHJcXG4gICAgICAgICAgaWYgKCF0aGlzLiRyb290LmlkX2RhdGFsaXN0KSB7IHRoaXMuJHJvb3QuaWRfZGF0YWxpc3QgPSAwIH1cXHJcXG4gICAgICAgICAgdGhpcy5faWRfZGF0YWxpc3QgPSAnaW5wdXQtZGF0YWxpc3QnICsgdGhpcy4kcm9vdC5pZF9kYXRhbGlzdCsrXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgICByZXR1cm4gdGhpcy5faWRfZGF0YWxpc3RcXHJcXG4gICAgICB9XFxyXFxuICAgICAgcmV0dXJuIG51bGxcXHJcXG4gICAgfSxcXHJcXG4gICAgaW5wdXQgKCkgeyByZXR1cm4gdGhpcy4kcmVmcy5pbnB1dCB9LFxcclxcbiAgICBuYXRpdmVWYWxpZGF0ZSAoKSB7IHJldHVybiAodGhpcy5pbnB1dCB8fCB7fSkuY2hlY2tWYWxpZGl0eSAmJiAoflsndXJsJywgJ2VtYWlsJ10uaW5kZXhPZih0aGlzLnR5cGUudG9Mb3dlckNhc2UoKSkgfHwgdGhpcy5taW4gfHwgdGhpcy5tYXgpIH0sXFxyXFxuICAgIHJlZ2V4ICgpIHsgcmV0dXJuIGNvZXJjZS5wYXR0ZXJuKHRoaXMucGF0dGVybikgfSxcXHJcXG4gICAgc2hvd0Vycm9yICgpIHsgcmV0dXJuIHRoaXMuZXJyb3IgJiYgdGhpcy52YWxpZCA9PT0gZmFsc2UgfSxcXHJcXG4gICAgc2hvd0hlbHAgKCkgeyByZXR1cm4gdGhpcy5oZWxwICYmICghdGhpcy5zaG93RXJyb3IgfHwgIXRoaXMuaGlkZUhlbHApIH0sXFxyXFxuICAgIHRleHQgKCkgeyByZXR1cm4gdHJhbnNsYXRpb25zKHRoaXMubGFuZykgfSxcXHJcXG4gICAgdGl0bGUgKCkgeyByZXR1cm4gdGhpcy5lcnJvclRleHQgfHwgdGhpcy5oZWxwIHx8ICcnIH1cXHJcXG4gIH0sXFxyXFxuICB3YXRjaDoge1xcclxcbiAgICBkYXRhbGlzdCAodmFsLCBvbGQpIHtcXHJcXG4gICAgICBpZiAodmFsICE9PSBvbGQgJiYgdmFsIGluc3RhbmNlb2YgQXJyYXkpIHsgdGhpcy5vcHRpb25zID0gdmFsIH1cXHJcXG4gICAgfSxcXHJcXG4gICAgbWF0Y2ggKHZhbCkgeyB0aGlzLmV2YWwoKSB9LFxcclxcbiAgICBvcHRpb25zICh2YWwsIG9sZCkge1xcclxcbiAgICAgIGlmICh2YWwgIT09IG9sZCkgdGhpcy4kZW1pdCgnb3B0aW9ucycsIHZhbClcXHJcXG4gICAgfSxcXHJcXG4gICAgdXJsICh2YWwpIHtcXHJcXG4gICAgICB0aGlzLl91cmwoKVxcclxcbiAgICB9LFxcclxcbiAgICB2YWwgKHZhbCwgb2xkKSB7XFxyXFxuICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCB2YWwpXFxyXFxuICAgICAgaWYgKHZhbCAhPT0gb2xkKSB7XFxyXFxuICAgICAgICBpZiAodGhpcy5tYXNrIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcXHJcXG4gICAgICAgICAgdmFsID0gdGhpcy5tYXNrKHZhbCB8fCAnJylcXHJcXG4gICAgICAgICAgaWYgKHRoaXMudmFsICE9PSB2YWwpIHtcXHJcXG4gICAgICAgICAgICBpZiAodGhpcy5fdGltZW91dC5tYXNrKSBjbGVhclRpbWVvdXQodGhpcy5fdGltZW91dC5tYXNrKVxcclxcbiAgICAgICAgICAgIHRoaXMuX3RpbWVvdXQubWFzayA9IHNldFRpbWVvdXQoKCkgPT4ge1xcclxcbiAgICAgICAgICAgICAgdGhpcy52YWwgPSB2YWxcXHJcXG4gICAgICAgICAgICB9LCBpc05hTih0aGlzLm1hc2tEZWxheSkgPyAwIDogdGhpcy5tYXNrRGVsYXkpXFxyXFxuICAgICAgICAgIH1cXHJcXG4gICAgICAgIH1cXHJcXG4gICAgICAgIHRoaXMuZXZhbCgpXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICB2YWxpZCAodmFsLCBvbGQpIHtcXHJcXG4gICAgICB0aGlzLiRlbWl0KCdpc3ZhbGlkJywgdmFsKVxcclxcbiAgICAgIHRoaXMuJGVtaXQoIXZhbCA/ICdpbnZhbGlkJyA6ICd2YWxpZCcpXFxyXFxuICAgICAgaWYgKHRoaXMuX3BhcmVudCkgdGhpcy5fcGFyZW50LnZhbGlkYXRlKClcXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsdWUgKHZhbCkge1xcclxcbiAgICAgIGlmICh0aGlzLnZhbCAhPT0gdmFsKSB7IHRoaXMudmFsID0gdmFsIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgYXR0ciAodmFsdWUpIHtcXHJcXG4gICAgICByZXR1cm4gflsnJywgbnVsbCwgdW5kZWZpbmVkXS5pbmRleE9mKHZhbHVlKSB8fCB2YWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uID8gbnVsbCA6IHZhbHVlXFxyXFxuICAgIH0sXFxyXFxuICAgIGVtaXQgKGUpIHtcXHJcXG4gICAgICB0aGlzLiRlbWl0KGUudHlwZSwgZS50eXBlID09ICdpbnB1dCcgPyBlLnRhcmdldC52YWx1ZSA6IGUpXFxyXFxuICAgICAgaWYgKGUudHlwZSA9PT0gJ2JsdXInICYmIHRoaXMuY2FuVmFsaWRhdGUpIHsgdGhpcy52YWxpZCA9IHRoaXMudmFsaWRhdGUoKSB9XFxyXFxuICAgIH0sXFxyXFxuICAgIGV2YWwgKCkge1xcclxcbiAgICAgIGlmICh0aGlzLl90aW1lb3V0LmV2YWwpIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0LmV2YWwpXFxyXFxuICAgICAgaWYgKCF0aGlzLmNhblZhbGlkYXRlKSB7XFxyXFxuICAgICAgICB0aGlzLnZhbGlkID0gdHJ1ZVxcclxcbiAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICB0aGlzLl90aW1lb3V0LmV2YWwgPSBzZXRUaW1lb3V0KCgpID0+IHtcXHJcXG4gICAgICAgICAgdGhpcy52YWxpZCA9IHRoaXMudmFsaWRhdGUoKVxcclxcbiAgICAgICAgICB0aGlzLl90aW1lb3V0LmV2YWwgPSBudWxsXFxyXFxuICAgICAgICB9LCB0aGlzLnZhbGlkYXRpb25EZWxheSlcXHJcXG4gICAgICB9XFxyXFxuICAgIH0sXFxyXFxuICAgIGZvY3VzICgpIHsgdGhpcy5pbnB1dC5mb2N1cygpIH0sXFxyXFxuICAgIHN1Ym1pdCAoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMuJHBhcmVudC5fZm9ybVZhbGlkYXRvcikge1xcclxcbiAgICAgICAgcmV0dXJuIHRoaXMuJHBhcmVudC52YWxpZGF0ZSgpXFxyXFxuICAgICAgfVxcclxcbiAgICAgIGlmICh0aGlzLmlucHV0LmZvcm0pIHtcXHJcXG4gICAgICAgIGNvbnN0IGludmFsaWRzID0gJCgnLmZvcm0tZ3JvdXAudmFsaWRhdGU6bm90KC5oYXMtc3VjY2VzcyknLCB0aGlzLmlucHV0LmZvcm0pXFxyXFxuICAgICAgICBpZiAoaW52YWxpZHMubGVuZ3RoKSB7XFxyXFxuICAgICAgICAgIGludmFsaWRzLmZpbmQoJ2lucHV0LHRleHRhcmVhLHNlbGVjdCcpWzBdLmZvY3VzKClcXHJcXG4gICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgIHRoaXMuaW5wdXQuZm9ybS5zdWJtaXQoKVxcclxcbiAgICAgICAgfVxcclxcbiAgICAgIH1cXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsaWRhdGUgKCkge1xcclxcbiAgICAgIGlmICghdGhpcy5jYW5WYWxpZGF0ZSkgeyByZXR1cm4gdHJ1ZSB9XFxyXFxuICAgICAgbGV0IHZhbHVlID0gKHRoaXMudmFsIHx8ICcnKS50cmltKClcXHJcXG4gICAgICBpZiAoIXZhbHVlKSB7IHJldHVybiAhdGhpcy5yZXF1aXJlZCB9XFxyXFxuICAgICAgaWYgKHRoaXMubWF0Y2ggIT09IG51bGwpIHsgcmV0dXJuIHRoaXMubWF0Y2ggPT09IHZhbHVlIH1cXHJcXG4gICAgICBpZiAodmFsdWUubGVuZ3RoIDwgdGhpcy5taW5sZW5ndGgpIHsgcmV0dXJuIGZhbHNlIH1cXHJcXG4gICAgICBpZiAodGhpcy5uYXRpdmVWYWxpZGF0ZSAmJiAhdGhpcy5pbnB1dC5jaGVja1ZhbGlkaXR5KCkpIHsgcmV0dXJuIGZhbHNlIH1cXHJcXG4gICAgICBpZiAodGhpcy5yZWdleCkge1xcclxcbiAgICAgICAgaWYgKCEodGhpcy5yZWdleCBpbnN0YW5jZW9mIEZ1bmN0aW9uID8gdGhpcy5yZWdleCh0aGlzLnZhbCkgOiB0aGlzLnJlZ2V4LnRlc3QodGhpcy52YWwpKSkgeyByZXR1cm4gZmFsc2UgfVxcclxcbiAgICAgIH1cXHJcXG4gICAgICByZXR1cm4gdHJ1ZVxcclxcbiAgICB9LFxcclxcbiAgICByZXNldCgpIHtcXHJcXG4gICAgICB0aGlzLnZhbHVlID0gJydcXHJcXG4gICAgICB0aGlzLnZhbGlkID0gbnVsbFxcclxcbiAgICAgIGlmICh0aGlzLl90aW1lb3V0Lm1hc2spIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0Lm1hc2spXFxyXFxuICAgICAgaWYgKHRoaXMuX3RpbWVvdXQuZXZhbCkgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQuZXZhbClcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGNyZWF0ZWQgKCkge1xcclxcbiAgICB0aGlzLl9pbnB1dCA9IHRydWVcXHJcXG4gICAgdGhpcy5fdGltZW91dCA9IHt9XFxyXFxuICAgIGxldCBwYXJlbnQgPSB0aGlzLiRwYXJlbnRcXHJcXG4gICAgd2hpbGUgKHBhcmVudCAmJiAhcGFyZW50Ll9mb3JtVmFsaWRhdG9yKSB7IHBhcmVudCA9IHBhcmVudC4kcGFyZW50IH1cXHJcXG4gICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuX2Zvcm1WYWxpZGF0b3IpIHtcXHJcXG4gICAgICBwYXJlbnQuY2hpbGRyZW4ucHVzaCh0aGlzKVxcclxcbiAgICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudFxcclxcbiAgICB9XFxyXFxuICAgIHRoaXMuX3VybCA9IGRlbGF5ZXIoZnVuY3Rpb24gKCkge1xcclxcbiAgICAgIGlmICghdGhpcy51cmwgfHwgIXRoaXMuJGh0dHAgfHwgdGhpcy5fbG9hZGluZykgeyByZXR1cm4gfVxcclxcbiAgICAgIHRoaXMuX2xvYWRpbmcgPSB0cnVlXFxyXFxuICAgICAgdGhpcy4kaHR0cC5nZXQodGhpcy51cmwpLnRoZW4ocmVzcG9uc2UgPT4ge1xcclxcbiAgICAgICAgdmFyIGRhdGEgPSByZXNwb25zZS5kYXRhIGluc3RhbmNlb2YgQXJyYXkgPyByZXNwb25zZS5kYXRhIDogW11cXHJcXG4gICAgICAgIHRyeSB7IGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpIH0gY2F0Y2ggKGUpIHt9XFxyXFxuICAgICAgICBpZiAodGhpcy51cmxNYXApIHsgZGF0YSA9IGRhdGEubWFwKHRoaXMudXJsTWFwKSB9XFxyXFxuICAgICAgICB0aGlzLm9wdGlvbnMgPSBkYXRhXFxyXFxuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZVxcclxcbiAgICAgIH0sIHJlc3BvbnNlID0+IHtcXHJcXG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlXFxyXFxuICAgICAgfSlcXHJcXG4gICAgfSwgREVMQVkpXFxyXFxuICAgIGlmICh0aGlzLnVybCkgdGhpcy5fdXJsKClcXHJcXG4gIH0sXFxyXFxuICBtb3VudGVkICgpIHtcXHJcXG4gICAgLy8gJCh0aGlzLmlucHV0KS5vbignZm9jdXMnLCBlID0+IHsgdGhpcy4kZW1pdCgnZm9jdXMnLCBlKSB9KS5vbignYmx1cicsIGUgPT4ge1xcclxcbiAgICAvLyAgIGlmICh0aGlzLmNhblZhbGlkYXRlKSB7IHRoaXMudmFsaWQgPSB0aGlzLnZhbGlkYXRlKCkgfVxcclxcbiAgICAvLyAgIHRoaXMuJGVtaXQoJ2JsdXInLCBlKVxcclxcbiAgICAvLyB9KVxcclxcbiAgfSxcXHJcXG4gIGJlZm9yZURlc3Ryb3kgKCkge1xcclxcbiAgICAvLyAkKHRoaXMuaW5wdXQpLm9mZigpXFxyXFxuICAgIGlmICh0aGlzLl9wYXJlbnQpIHtcXHJcXG4gICAgICB2YXIgaW5kZXggPSB0aGlzLl9wYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKVxcclxcbiAgICAgIHRoaXMuX3BhcmVudC5jaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDEpXFxyXFxuICAgIH1cXHJcXG4gIH1cXHJcXG59XFxyXFxuPC9zY3JpcHQ+XFxyXFxuXFxyXFxuPHN0eWxlIHNjb3BlZD5cXHJcXG4uZm9ybS1ncm91cCB7XFxyXFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxufVxcclxcbmxhYmVsfi5jbG9zZSB7XFxyXFxuICB0b3A6IDI1cHg7XFxyXFxufVxcclxcbi5pbnB1dC1ncm91cD4uaWNvbiB7XFxyXFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICBkaXNwbGF5OiB0YWJsZS1jZWxsO1xcclxcbiAgd2lkdGg6MDtcXHJcXG4gIHotaW5kZXg6IDM7XFxyXFxufVxcclxcbi5jbG9zZSB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IDA7XFxyXFxuICByaWdodDogMDtcXHJcXG4gIHotaW5kZXg6IDI7XFxyXFxuICBkaXNwbGF5OiBibG9jaztcXHJcXG4gIHdpZHRoOiAzNHB4O1xcclxcbiAgaGVpZ2h0OiAzNHB4O1xcclxcbiAgbGluZS1oZWlnaHQ6IDM0cHg7XFxyXFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcbi5oYXMtZmVlZGJhY2sgLmNsb3NlIHtcXHJcXG4gIHJpZ2h0OiAyMHB4O1xcclxcbn1cXHJcXG48L3N0eWxlPlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogMTE3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDY1KTtcblx0XG5cdHZhciBfTm9kZUxpc3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXHRcblx0dmFyIF9Ob2RlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Ob2RlTGlzdCk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0XG5cdHZhciBERUxBWSA9IDMwMDtcblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgY2xlYXJCdXR0b246IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGNvbHM6IHsgdHlwZTogTnVtYmVyLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBkYXRhbGlzdDogeyB0eXBlOiBBcnJheSwgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgZGlzYWJsZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGVudGVyU3VibWl0OiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH0sXG5cdCAgICBlcnJvcjogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIGhlbHA6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBoaWRlSGVscDogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiB0cnVlIH0sXG5cdCAgICBpY29uOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH0sXG5cdCAgICBsYWJlbDogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIGxhbmc6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBuYXZpZ2F0b3IubGFuZ3VhZ2UgfSxcblx0ICAgIG1hc2s6IG51bGwsXG5cdCAgICBtYXNrRGVsYXk6IHsgdHlwZTogTnVtYmVyLCBkZWZhdWx0OiAxMDAgfSxcblx0ICAgIG1hdGNoOiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgbWF4OiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgbWF4bGVuZ3RoOiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgbWluOiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgbWlubGVuZ3RoOiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogMCB9LFxuXHQgICAgbmFtZTogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIHBhdHRlcm46IHsgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgcGxhY2Vob2xkZXI6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICByZWFkb25seTogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgcmVxdWlyZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIHJvd3M6IHsgdHlwZTogTnVtYmVyLCBkZWZhdWx0OiAzIH0sXG5cdCAgICBzdGVwOiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgdHlwZTogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICd0ZXh0JyB9LFxuXHQgICAgdXJsOiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgdXJsTWFwOiB7IHR5cGU6IEZ1bmN0aW9uLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICB2YWxpZGF0aW9uRGVsYXk6IHsgdHlwZTogTnVtYmVyLCBkZWZhdWx0OiAyNTAgfSxcblx0ICAgIHZhbHVlOiB7IGRlZmF1bHQ6IG51bGwgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHZhciB2YWwgPSB0aGlzLnZhbHVlO1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgb3B0aW9uczogdGhpcy5kYXRhbGlzdCxcblx0ICAgICAgdmFsOiB2YWwsXG5cdCAgICAgIHZhbGlkOiBudWxsLFxuXHQgICAgICB0aW1lb3V0OiBudWxsXG5cdCAgICB9O1xuXHQgIH0sXG5cdFxuXHQgIGNvbXB1dGVkOiB7XG5cdCAgICBjYW5WYWxpZGF0ZTogZnVuY3Rpb24gY2FuVmFsaWRhdGUoKSB7XG5cdCAgICAgIHJldHVybiAhdGhpcy5kaXNhYmxlZCAmJiAhdGhpcy5yZWFkb25seSAmJiAodGhpcy5yZXF1aXJlZCB8fCB0aGlzLnJlZ2V4IHx8IHRoaXMubmF0aXZlVmFsaWRhdGUgfHwgdGhpcy5tYXRjaCAhPT0gbnVsbCk7XG5cdCAgICB9LFxuXHQgICAgZXJyb3JUZXh0OiBmdW5jdGlvbiBlcnJvclRleHQoKSB7XG5cdCAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmFsdWU7XG5cdCAgICAgIHZhciBlcnJvciA9IFt0aGlzLmVycm9yXTtcblx0ICAgICAgaWYgKCF2YWx1ZSAmJiB0aGlzLnJlcXVpcmVkKSBlcnJvci5wdXNoKCcoJyArIHRoaXMudGV4dC5yZXF1aXJlZC50b0xvd2VyQ2FzZSgpICsgJyknKTtcblx0ICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLmxlbmd0aCA8IHRoaXMubWlubGVuZ3RoKSBlcnJvci5wdXNoKCcoJyArIHRoaXMudGV4dC5taW5MZW5ndGgudG9Mb3dlckNhc2UoKSArICc6ICcgKyB0aGlzLm1pbmxlbmd0aCArICcpJyk7XG5cdCAgICAgIHJldHVybiBlcnJvci5qb2luKCcgJyk7XG5cdCAgICB9LFxuXHQgICAgaWRfZGF0YWxpc3Q6IGZ1bmN0aW9uIGlkX2RhdGFsaXN0KCkge1xuXHQgICAgICBpZiAodGhpcy50eXBlICE9PSAndGV4dGFyZWEnICYmIHRoaXMuZGF0YWxpc3QgaW5zdGFuY2VvZiBBcnJheSkge1xuXHQgICAgICAgIGlmICghdGhpcy5faWRfZGF0YWxpc3QpIHtcblx0ICAgICAgICAgIGlmICghdGhpcy4kcm9vdC5pZF9kYXRhbGlzdCkge1xuXHQgICAgICAgICAgICB0aGlzLiRyb290LmlkX2RhdGFsaXN0ID0gMDtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICAgIHRoaXMuX2lkX2RhdGFsaXN0ID0gJ2lucHV0LWRhdGFsaXN0JyArIHRoaXMuJHJvb3QuaWRfZGF0YWxpc3QrKztcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2lkX2RhdGFsaXN0O1xuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiBudWxsO1xuXHQgICAgfSxcblx0ICAgIGlucHV0OiBmdW5jdGlvbiBpbnB1dCgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuJHJlZnMuaW5wdXQ7XG5cdCAgICB9LFxuXHQgICAgbmF0aXZlVmFsaWRhdGU6IGZ1bmN0aW9uIG5hdGl2ZVZhbGlkYXRlKCkge1xuXHQgICAgICByZXR1cm4gKHRoaXMuaW5wdXQgfHwge30pLmNoZWNrVmFsaWRpdHkgJiYgKH5bJ3VybCcsICdlbWFpbCddLmluZGV4T2YodGhpcy50eXBlLnRvTG93ZXJDYXNlKCkpIHx8IHRoaXMubWluIHx8IHRoaXMubWF4KTtcblx0ICAgIH0sXG5cdCAgICByZWdleDogZnVuY3Rpb24gcmVnZXgoKSB7XG5cdCAgICAgIHJldHVybiBfdXRpbHMuY29lcmNlLnBhdHRlcm4odGhpcy5wYXR0ZXJuKTtcblx0ICAgIH0sXG5cdCAgICBzaG93RXJyb3I6IGZ1bmN0aW9uIHNob3dFcnJvcigpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuZXJyb3IgJiYgdGhpcy52YWxpZCA9PT0gZmFsc2U7XG5cdCAgICB9LFxuXHQgICAgc2hvd0hlbHA6IGZ1bmN0aW9uIHNob3dIZWxwKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5oZWxwICYmICghdGhpcy5zaG93RXJyb3IgfHwgIXRoaXMuaGlkZUhlbHApO1xuXHQgICAgfSxcblx0ICAgIHRleHQ6IGZ1bmN0aW9uIHRleHQoKSB7XG5cdCAgICAgIHJldHVybiAoMCwgX3V0aWxzLnRyYW5zbGF0aW9ucykodGhpcy5sYW5nKTtcblx0ICAgIH0sXG5cdCAgICB0aXRsZTogZnVuY3Rpb24gdGl0bGUoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLmVycm9yVGV4dCB8fCB0aGlzLmhlbHAgfHwgJyc7XG5cdCAgICB9XG5cdCAgfSxcblx0ICB3YXRjaDoge1xuXHQgICAgZGF0YWxpc3Q6IGZ1bmN0aW9uIGRhdGFsaXN0KHZhbCwgb2xkKSB7XG5cdCAgICAgIGlmICh2YWwgIT09IG9sZCAmJiB2YWwgaW5zdGFuY2VvZiBBcnJheSkge1xuXHQgICAgICAgIHRoaXMub3B0aW9ucyA9IHZhbDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIG1hdGNoOiBmdW5jdGlvbiBtYXRjaCh2YWwpIHtcblx0ICAgICAgdGhpcy5ldmFsKCk7XG5cdCAgICB9LFxuXHQgICAgb3B0aW9uczogZnVuY3Rpb24gb3B0aW9ucyh2YWwsIG9sZCkge1xuXHQgICAgICBpZiAodmFsICE9PSBvbGQpIHRoaXMuJGVtaXQoJ29wdGlvbnMnLCB2YWwpO1xuXHQgICAgfSxcblx0ICAgIHVybDogZnVuY3Rpb24gdXJsKHZhbCkge1xuXHQgICAgICB0aGlzLl91cmwoKTtcblx0ICAgIH0sXG5cdCAgICB2YWw6IGZ1bmN0aW9uIHZhbChfdmFsLCBvbGQpIHtcblx0ICAgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICAgIHRoaXMuJGVtaXQoJ2lucHV0JywgX3ZhbCk7XG5cdCAgICAgIGlmIChfdmFsICE9PSBvbGQpIHtcblx0ICAgICAgICBpZiAodGhpcy5tYXNrIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcblx0ICAgICAgICAgIF92YWwgPSB0aGlzLm1hc2soX3ZhbCB8fCAnJyk7XG5cdCAgICAgICAgICBpZiAodGhpcy52YWwgIT09IF92YWwpIHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVvdXQubWFzaykgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQubWFzayk7XG5cdCAgICAgICAgICAgIHRoaXMuX3RpbWVvdXQubWFzayA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgIF90aGlzLnZhbCA9IF92YWw7XG5cdCAgICAgICAgICAgIH0sIGlzTmFOKHRoaXMubWFza0RlbGF5KSA/IDAgOiB0aGlzLm1hc2tEZWxheSk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMuZXZhbCgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdmFsaWQ6IGZ1bmN0aW9uIHZhbGlkKHZhbCwgb2xkKSB7XG5cdCAgICAgIHRoaXMuJGVtaXQoJ2lzdmFsaWQnLCB2YWwpO1xuXHQgICAgICB0aGlzLiRlbWl0KCF2YWwgPyAnaW52YWxpZCcgOiAndmFsaWQnKTtcblx0ICAgICAgaWYgKHRoaXMuX3BhcmVudCkgdGhpcy5fcGFyZW50LnZhbGlkYXRlKCk7XG5cdCAgICB9LFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKHZhbCkge1xuXHQgICAgICBpZiAodGhpcy52YWwgIT09IHZhbCkge1xuXHQgICAgICAgIHRoaXMudmFsID0gdmFsO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtZXRob2RzOiB7XG5cdCAgICBhdHRyOiBmdW5jdGlvbiBhdHRyKHZhbHVlKSB7XG5cdCAgICAgIHJldHVybiB+WycnLCBudWxsLCB1bmRlZmluZWRdLmluZGV4T2YodmFsdWUpIHx8IHZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24gPyBudWxsIDogdmFsdWU7XG5cdCAgICB9LFxuXHQgICAgZW1pdDogZnVuY3Rpb24gZW1pdChlKSB7XG5cdCAgICAgIHRoaXMuJGVtaXQoZS50eXBlLCBlLnR5cGUgPT0gJ2lucHV0JyA/IGUudGFyZ2V0LnZhbHVlIDogZSk7XG5cdCAgICAgIGlmIChlLnR5cGUgPT09ICdibHVyJyAmJiB0aGlzLmNhblZhbGlkYXRlKSB7XG5cdCAgICAgICAgdGhpcy52YWxpZCA9IHRoaXMudmFsaWRhdGUoKTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGV2YWw6IGZ1bmN0aW9uIF9ldmFsKCkge1xuXHQgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblx0XG5cdCAgICAgIGlmICh0aGlzLl90aW1lb3V0LmV2YWwpIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0LmV2YWwpO1xuXHQgICAgICBpZiAoIXRoaXMuY2FuVmFsaWRhdGUpIHtcblx0ICAgICAgICB0aGlzLnZhbGlkID0gdHJ1ZTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLl90aW1lb3V0LmV2YWwgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgIF90aGlzMi52YWxpZCA9IF90aGlzMi52YWxpZGF0ZSgpO1xuXHQgICAgICAgICAgX3RoaXMyLl90aW1lb3V0LmV2YWwgPSBudWxsO1xuXHQgICAgICAgIH0sIHRoaXMudmFsaWRhdGlvbkRlbGF5KTtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGZvY3VzOiBmdW5jdGlvbiBmb2N1cygpIHtcblx0ICAgICAgdGhpcy5pbnB1dC5mb2N1cygpO1xuXHQgICAgfSxcblx0ICAgIHN1Ym1pdDogZnVuY3Rpb24gc3VibWl0KCkge1xuXHQgICAgICBpZiAodGhpcy4kcGFyZW50Ll9mb3JtVmFsaWRhdG9yKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuJHBhcmVudC52YWxpZGF0ZSgpO1xuXHQgICAgICB9XG5cdCAgICAgIGlmICh0aGlzLmlucHV0LmZvcm0pIHtcblx0ICAgICAgICB2YXIgaW52YWxpZHMgPSAoMCwgX05vZGVMaXN0Mi5kZWZhdWx0KSgnLmZvcm0tZ3JvdXAudmFsaWRhdGU6bm90KC5oYXMtc3VjY2VzcyknLCB0aGlzLmlucHV0LmZvcm0pO1xuXHQgICAgICAgIGlmIChpbnZhbGlkcy5sZW5ndGgpIHtcblx0ICAgICAgICAgIGludmFsaWRzLmZpbmQoJ2lucHV0LHRleHRhcmVhLHNlbGVjdCcpWzBdLmZvY3VzKCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMuaW5wdXQuZm9ybS5zdWJtaXQoKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB2YWxpZGF0ZTogZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG5cdCAgICAgIGlmICghdGhpcy5jYW5WYWxpZGF0ZSkge1xuXHQgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgICB9XG5cdCAgICAgIHZhciB2YWx1ZSA9ICh0aGlzLnZhbCB8fCAnJykudHJpbSgpO1xuXHQgICAgICBpZiAoIXZhbHVlKSB7XG5cdCAgICAgICAgcmV0dXJuICF0aGlzLnJlcXVpcmVkO1xuXHQgICAgICB9XG5cdCAgICAgIGlmICh0aGlzLm1hdGNoICE9PSBudWxsKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2ggPT09IHZhbHVlO1xuXHQgICAgICB9XG5cdCAgICAgIGlmICh2YWx1ZS5sZW5ndGggPCB0aGlzLm1pbmxlbmd0aCkge1xuXHQgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgfVxuXHQgICAgICBpZiAodGhpcy5uYXRpdmVWYWxpZGF0ZSAmJiAhdGhpcy5pbnB1dC5jaGVja1ZhbGlkaXR5KCkpIHtcblx0ICAgICAgICByZXR1cm4gZmFsc2U7XG5cdCAgICAgIH1cblx0ICAgICAgaWYgKHRoaXMucmVnZXgpIHtcblx0ICAgICAgICBpZiAoISh0aGlzLnJlZ2V4IGluc3RhbmNlb2YgRnVuY3Rpb24gPyB0aGlzLnJlZ2V4KHRoaXMudmFsKSA6IHRoaXMucmVnZXgudGVzdCh0aGlzLnZhbCkpKSB7XG5cdCAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgfSxcblx0ICAgIHJlc2V0OiBmdW5jdGlvbiByZXNldCgpIHtcblx0ICAgICAgdGhpcy52YWx1ZSA9ICcnO1xuXHQgICAgICB0aGlzLnZhbGlkID0gbnVsbDtcblx0ICAgICAgaWYgKHRoaXMuX3RpbWVvdXQubWFzaykgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQubWFzayk7XG5cdCAgICAgIGlmICh0aGlzLl90aW1lb3V0LmV2YWwpIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0LmV2YWwpO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIHRoaXMuX2lucHV0ID0gdHJ1ZTtcblx0ICAgIHRoaXMuX3RpbWVvdXQgPSB7fTtcblx0ICAgIHZhciBwYXJlbnQgPSB0aGlzLiRwYXJlbnQ7XG5cdCAgICB3aGlsZSAocGFyZW50ICYmICFwYXJlbnQuX2Zvcm1WYWxpZGF0b3IpIHtcblx0ICAgICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XG5cdCAgICB9XG5cdCAgICBpZiAocGFyZW50ICYmIHBhcmVudC5fZm9ybVZhbGlkYXRvcikge1xuXHQgICAgICBwYXJlbnQuY2hpbGRyZW4ucHVzaCh0aGlzKTtcblx0ICAgICAgdGhpcy5fcGFyZW50ID0gcGFyZW50O1xuXHQgICAgfVxuXHQgICAgdGhpcy5fdXJsID0gKDAsIF91dGlscy5kZWxheWVyKShmdW5jdGlvbiAoKSB7XG5cdCAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXHRcblx0ICAgICAgaWYgKCF0aGlzLnVybCB8fCAhdGhpcy4kaHR0cCB8fCB0aGlzLl9sb2FkaW5nKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICAgIHRoaXMuX2xvYWRpbmcgPSB0cnVlO1xuXHQgICAgICB0aGlzLiRodHRwLmdldCh0aGlzLnVybCkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcblx0ICAgICAgICB2YXIgZGF0YSA9IHJlc3BvbnNlLmRhdGEgaW5zdGFuY2VvZiBBcnJheSA/IHJlc3BvbnNlLmRhdGEgOiBbXTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGF0YSk7XG5cdCAgICAgICAgfSBjYXRjaCAoZSkge31cblx0ICAgICAgICBpZiAoX3RoaXMzLnVybE1hcCkge1xuXHQgICAgICAgICAgZGF0YSA9IGRhdGEubWFwKF90aGlzMy51cmxNYXApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBfdGhpczMub3B0aW9ucyA9IGRhdGE7XG5cdCAgICAgICAgX3RoaXMzLmxvYWRpbmcgPSBmYWxzZTtcblx0ICAgICAgfSwgZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG5cdCAgICAgICAgX3RoaXMzLmxvYWRpbmcgPSBmYWxzZTtcblx0ICAgICAgfSk7XG5cdCAgICB9LCBERUxBWSk7XG5cdCAgICBpZiAodGhpcy51cmwpIHRoaXMuX3VybCgpO1xuXHQgIH0sXG5cdCAgbW91bnRlZDogZnVuY3Rpb24gbW91bnRlZCgpIHtcblx0ICAgIC8vICQodGhpcy5pbnB1dCkub24oJ2ZvY3VzJywgZSA9PiB7IHRoaXMuJGVtaXQoJ2ZvY3VzJywgZSkgfSkub24oJ2JsdXInLCBlID0+IHtcblx0ICAgIC8vICAgaWYgKHRoaXMuY2FuVmFsaWRhdGUpIHsgdGhpcy52YWxpZCA9IHRoaXMudmFsaWRhdGUoKSB9XG5cdCAgICAvLyAgIHRoaXMuJGVtaXQoJ2JsdXInLCBlKVxuXHQgICAgLy8gfSlcblx0ICB9LFxuXHQgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uIGJlZm9yZURlc3Ryb3koKSB7XG5cdCAgICAvLyAkKHRoaXMuaW5wdXQpLm9mZigpXG5cdCAgICBpZiAodGhpcy5fcGFyZW50KSB7XG5cdCAgICAgIHZhciBpbmRleCA9IHRoaXMuX3BhcmVudC5jaGlsZHJlbi5pbmRleE9mKHRoaXMpO1xuXHQgICAgICB0aGlzLl9wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKGluZGV4LCAxKTtcblx0ICAgIH1cblx0ICB9XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxMTggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiZm9ybS1ncm91cFwiLFxuXHQgICAgY2xhc3M6IHtcblx0ICAgICAgdmFsaWRhdGU6IF92bS5jYW5WYWxpZGF0ZSwgJ2hhcy1mZWVkYmFjayc6IF92bS5pY29uLCAnaGFzLWVycm9yJzogX3ZtLmNhblZhbGlkYXRlICYmIF92bS52YWxpZCA9PT0gZmFsc2UsICdoYXMtc3VjY2Vzcyc6IF92bS5jYW5WYWxpZGF0ZSAmJiBfdm0udmFsaWRcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl90KFwibGFiZWxcIiwgWyhfdm0ubGFiZWwpID8gX3ZtLl9jKCdsYWJlbCcsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImNvbnRyb2wtbGFiZWxcIixcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogX3ZtLmZvY3VzXG5cdCAgICB9XG5cdCAgfSwgW192bS5fdihfdm0uX3MoX3ZtLmxhYmVsKSldKSA6IF92bS5fZSgpXSksIF92bS5fdihcIiBcIiksIChfdm0uJHNsb3RzLmJlZm9yZSB8fCBfdm0uJHNsb3RzLmFmdGVyKSA/IF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiaW5wdXQtZ3JvdXBcIlxuXHQgIH0sIFtfdm0uX3QoXCJiZWZvcmVcIiksIF92bS5fdihcIiBcIiksIF92bS5fYyhfdm0udHlwZSA9PSAndGV4dGFyZWEnID8gX3ZtLnR5cGUgOiAnaW5wdXQnLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcIm1vZGVsXCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1tb2RlbFwiLFxuXHQgICAgICB2YWx1ZTogKF92bS52YWwpLFxuXHQgICAgICBleHByZXNzaW9uOiBcInZhbFwiXG5cdCAgICB9XSxcblx0ICAgIHJlZjogXCJpbnB1dFwiLFxuXHQgICAgdGFnOiBcInRleHRhcmVhXCIsXG5cdCAgICBzdGF0aWNDbGFzczogXCJmb3JtLWNvbnRyb2xcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwiY29sc1wiOiBfdm0uY29scyxcblx0ICAgICAgXCJkaXNhYmxlZFwiOiBfdm0uZGlzYWJsZWQsXG5cdCAgICAgIFwibGlzdFwiOiBfdm0uaWRfZGF0YWxpc3QsXG5cdCAgICAgIFwibWF4XCI6IF92bS5hdHRyKF92bS5tYXgpLFxuXHQgICAgICBcIm1heGxlbmd0aFwiOiBfdm0ubWF4bGVuZ3RoLFxuXHQgICAgICBcIm1pblwiOiBfdm0uYXR0cihfdm0ubWluKSxcblx0ICAgICAgXCJuYW1lXCI6IF92bS5uYW1lLFxuXHQgICAgICBcInBsYWNlaG9sZGVyXCI6IF92bS5wbGFjZWhvbGRlcixcblx0ICAgICAgXCJyZWFkb25seVwiOiBfdm0ucmVhZG9ubHksXG5cdCAgICAgIFwicmVxdWlyZWRcIjogX3ZtLnJlcXVpcmVkLFxuXHQgICAgICBcInJvd3NcIjogX3ZtLnJvd3MsXG5cdCAgICAgIFwic3RlcFwiOiBfdm0uc3RlcCxcblx0ICAgICAgXCJ0aXRsZVwiOiBfdm0uYXR0cihfdm0udGl0bGUpLFxuXHQgICAgICBcInR5cGVcIjogX3ZtLnR5cGUgPT0gJ3RleHRhcmVhJyA/IG51bGwgOiBfdm0udHlwZVxuXHQgICAgfSxcblx0ICAgIGRvbVByb3BzOiB7XG5cdCAgICAgIFwidmFsdWVcIjogX3ZtLl9zKF92bS52YWwpXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJibHVyXCI6IF92bS5lbWl0LFxuXHQgICAgICBcImZvY3VzXCI6IF92bS5lbWl0LFxuXHQgICAgICBcImlucHV0XCI6IFtmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBpZiAoJGV2ZW50LnRhcmdldC5jb21wb3NpbmcpIHsgcmV0dXJuOyB9XG5cdCAgICAgICAgX3ZtLnZhbCA9ICRldmVudC50YXJnZXQudmFsdWVcblx0ICAgICAgfSwgX3ZtLmVtaXRdLFxuXHQgICAgICBcImtleXVwXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIGlmIChfdm0uX2soJGV2ZW50LmtleUNvZGUsIFwiZW50ZXJcIiwgMTMpKSB7IHJldHVybjsgfVxuXHQgICAgICAgIF92bS50eXBlICE9ICd0ZXh0YXJlYScgJiYgX3ZtLmVudGVyU3VibWl0ICYmIF92bS5zdWJtaXQoKVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSksIF92bS5fdihcIiBcIiksIChfdm0uY2xlYXJCdXR0b24gJiYgX3ZtLnZhbHVlKSA/IF92bS5fYygnZGl2Jywge1xuXHQgICAgY2xhc3M6IHtcblx0ICAgICAgaWNvbjogX3ZtLmljb25cblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiY2xvc2VcIixcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnZhbHVlID0gJydcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0sIFtfdm0uX3YoXCLDl1wiKV0pXSkgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgKF92bS5pY29uKSA/IF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiaWNvblwiXG5cdCAgfSwgWyhfdm0uaWNvbiAmJiBfdm0udmFsaWQgIT09IG51bGwpID8gX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgY2xhc3M6IFsnZm9ybS1jb250cm9sLWZlZWRiYWNrIGdseXBoaWNvbicsICdnbHlwaGljb24tJyArIChfdm0udmFsaWQgPyAnb2snIDogJ3JlbW92ZScpXSxcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwiYXJpYS1oaWRkZW5cIjogXCJ0cnVlXCJcblx0ICAgIH1cblx0ICB9KSA6IF92bS5fZSgpXSkgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl90KFwiYWZ0ZXJcIildLCAyKSA6IFtfdm0uX2MoX3ZtLnR5cGUgPT0gJ3RleHRhcmVhJyA/IF92bS50eXBlIDogJ2lucHV0Jywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJtb2RlbFwiLFxuXHQgICAgICByYXdOYW1lOiBcInYtbW9kZWxcIixcblx0ICAgICAgdmFsdWU6IChfdm0udmFsKSxcblx0ICAgICAgZXhwcmVzc2lvbjogXCJ2YWxcIlxuXHQgICAgfV0sXG5cdCAgICByZWY6IFwiaW5wdXRcIixcblx0ICAgIHRhZzogXCJ0ZXh0YXJlYVwiLFxuXHQgICAgc3RhdGljQ2xhc3M6IFwiZm9ybS1jb250cm9sXCIsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImNvbHNcIjogX3ZtLmNvbHMsXG5cdCAgICAgIFwiZGlzYWJsZWRcIjogX3ZtLmRpc2FibGVkLFxuXHQgICAgICBcImxpc3RcIjogX3ZtLmlkX2RhdGFsaXN0LFxuXHQgICAgICBcIm1heFwiOiBfdm0uYXR0cihfdm0ubWF4KSxcblx0ICAgICAgXCJtYXhsZW5ndGhcIjogX3ZtLm1heGxlbmd0aCxcblx0ICAgICAgXCJtaW5cIjogX3ZtLmF0dHIoX3ZtLm1pbiksXG5cdCAgICAgIFwibmFtZVwiOiBfdm0ubmFtZSxcblx0ICAgICAgXCJwbGFjZWhvbGRlclwiOiBfdm0ucGxhY2Vob2xkZXIsXG5cdCAgICAgIFwicmVhZG9ubHlcIjogX3ZtLnJlYWRvbmx5LFxuXHQgICAgICBcInJlcXVpcmVkXCI6IF92bS5yZXF1aXJlZCxcblx0ICAgICAgXCJyb3dzXCI6IF92bS5yb3dzLFxuXHQgICAgICBcInN0ZXBcIjogX3ZtLnN0ZXAsXG5cdCAgICAgIFwidGl0bGVcIjogX3ZtLmF0dHIoX3ZtLnRpdGxlKSxcblx0ICAgICAgXCJ0eXBlXCI6IF92bS50eXBlID09ICd0ZXh0YXJlYScgPyBudWxsIDogX3ZtLnR5cGVcblx0ICAgIH0sXG5cdCAgICBkb21Qcm9wczoge1xuXHQgICAgICBcInZhbHVlXCI6IF92bS5fcyhfdm0udmFsKVxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiYmx1clwiOiBfdm0uZW1pdCxcblx0ICAgICAgXCJmb2N1c1wiOiBfdm0uZW1pdCxcblx0ICAgICAgXCJpbnB1dFwiOiBbZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgaWYgKCRldmVudC50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybjsgfVxuXHQgICAgICAgIF92bS52YWwgPSAkZXZlbnQudGFyZ2V0LnZhbHVlXG5cdCAgICAgIH0sIF92bS5lbWl0XSxcblx0ICAgICAgXCJrZXl1cFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBpZiAoX3ZtLl9rKCRldmVudC5rZXlDb2RlLCBcImVudGVyXCIsIDEzKSkgeyByZXR1cm47IH1cblx0ICAgICAgICBfdm0udHlwZSAhPSAndGV4dGFyZWEnICYmIF92bS5lbnRlclN1Ym1pdCAmJiBfdm0uc3VibWl0KClcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLmNsZWFyQnV0dG9uICYmIF92bS52YWwpID8gX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiY2xvc2VcIixcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnZhbCA9ICcnXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LCBbX3ZtLl92KFwiw5dcIildKSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLmljb24gJiYgX3ZtLnZhbGlkICE9PSBudWxsKSA/IF92bS5fYygnc3BhbicsIHtcblx0ICAgIGNsYXNzOiBbJ2Zvcm0tY29udHJvbC1mZWVkYmFjayBnbHlwaGljb24nLCAnZ2x5cGhpY29uLScgKyAoX3ZtLnZhbGlkID8gJ29rJyA6ICdyZW1vdmUnKV0sXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImFyaWEtaGlkZGVuXCI6IFwidHJ1ZVwiXG5cdCAgICB9XG5cdCAgfSkgOiBfdm0uX2UoKV0sIF92bS5fdihcIiBcIiksIChfdm0uaWRfZGF0YWxpc3QpID8gX3ZtLl9jKCdkYXRhbGlzdCcsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwiaWRcIjogX3ZtLmlkX2RhdGFsaXN0XG5cdCAgICB9XG5cdCAgfSwgX3ZtLl9sKChfdm0ub3B0aW9ucyksIGZ1bmN0aW9uKG9wYykge1xuXHQgICAgcmV0dXJuIF92bS5fYygnb3B0aW9uJywge1xuXHQgICAgICBkb21Qcm9wczoge1xuXHQgICAgICAgIFwidmFsdWVcIjogb3BjXG5cdCAgICAgIH1cblx0ICAgIH0pXG5cdCAgfSkpIDogX3ZtLl9lKCksIF92bS5fdihcIiBcIiksIChfdm0uc2hvd0hlbHApID8gX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJoZWxwLWJsb2NrXCIsXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IF92bS5mb2N1c1xuXHQgICAgfVxuXHQgIH0sIFtfdm0uX3YoX3ZtLl9zKF92bS5oZWxwKSldKSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLnNob3dFcnJvcikgPyBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImhlbHAtYmxvY2sgd2l0aC1lcnJvcnNcIixcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogX3ZtLmZvY3VzXG5cdCAgICB9XG5cdCAgfSwgW192bS5fdihfdm0uX3MoX3ZtLmVycm9yVGV4dCkpXSkgOiBfdm0uX2UoKV0sIDIpXG5cdH0sc3RhdGljUmVuZGVyRm5zOiBbXX1cblx0aWYgKGZhbHNlKSB7XG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LTY1MmFkN2I5XCIsIG1vZHVsZS5leHBvcnRzKVxuXHQgIH1cblx0fVxuXG4vKioqLyB9LFxuLyogMTE5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgX192dWVfZXhwb3J0c19fLCBfX3Z1ZV9vcHRpb25zX19cblx0dmFyIF9fdnVlX3N0eWxlc19fID0ge31cblx0XG5cdC8qIHN0eWxlcyAqL1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDEyMClcblx0XG5cdC8qIHNjcmlwdCAqL1xuXHRfX3Z1ZV9leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEyMilcblx0XG5cdC8qIHRlbXBsYXRlICovXG5cdHZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMjcpXG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuXHRpZiAoXG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcblx0KSB7XG5cdGlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxuXHR9XG5cdGlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcblx0ICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xuXHR9XG5cdF9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIkM6XFxcXGxhcmFnb25cXFxcd3d3XFxcXHZ1ZS1zdHJhcFxcXFxzcmNcXFxcTW9kYWwudnVlXCJcblx0X192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5cdF9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LWZlN2Q1ZGM4XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi1mZTdkNWRjOFwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIE1vZGFsLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDEyMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblx0XG5cdC8vIGxvYWQgdGhlIHN0eWxlc1xuXHR2YXIgY29udGVudCA9IF9fd2VicGFja19yZXF1aXJlX18oMTIxKTtcblx0aWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG5cdC8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cblx0dmFyIHVwZGF0ZSA9IF9fd2VicGFja19yZXF1aXJlX18oNzkpKGNvbnRlbnQsIHt9KTtcblx0aWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG5cdC8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcblx0aWYoZmFsc2UpIHtcblx0XHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi1mZTdkNWRjOCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vTW9kYWwudnVlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi1mZTdkNWRjOCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vTW9kYWwudnVlXCIpO1xuXHRcdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcblx0fVxuXG4vKioqLyB9LFxuLyogMTIxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc4KSgpO1xuXHQvLyBpbXBvcnRzXG5cdFxuXHRcblx0Ly8gbW9kdWxlXG5cdGV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5tb2RhbCB7XFxyXFxuICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBlYXNlO1xcbn1cXG4ubW9kYWwuaW4ge1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLDAsMCwwLjUpO1xcbn1cXG4ubW9kYWwuem9vbSAubW9kYWwtZGlhbG9nIHtcXHJcXG4gIC13ZWJraXQtdHJhbnNmb3JtOiBzY2FsZSgwLjEpO1xcclxcbiAgLW1vei10cmFuc2Zvcm06IHNjYWxlKDAuMSk7XFxyXFxuICAtbXMtdHJhbnNmb3JtOiBzY2FsZSgwLjEpO1xcclxcbiAgdHJhbnNmb3JtOiBzY2FsZSgwLjEpO1xcclxcbiAgdG9wOiAzMDBweDtcXHJcXG4gIG9wYWNpdHk6IDA7XFxyXFxuICAtd2Via2l0LXRyYW5zaXRpb246IGFsbCAwLjNzO1xcclxcbiAgLW1vei10cmFuc2l0aW9uOiBhbGwgMC4zcztcXHJcXG4gIHRyYW5zaXRpb246IGFsbCAwLjNzO1xcbn1cXG4ubW9kYWwuem9vbS5pbiAubW9kYWwtZGlhbG9nIHtcXHJcXG4gIC13ZWJraXQtdHJhbnNmb3JtOiBzY2FsZSgxKTtcXHJcXG4gIC1tb3otdHJhbnNmb3JtOiBzY2FsZSgxKTtcXHJcXG4gIC1tcy10cmFuc2Zvcm06IHNjYWxlKDEpO1xcclxcbiAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXHJcXG4gIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLCAtMzAwcHgsIDApO1xcclxcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLCAtMzAwcHgsIDApO1xcclxcbiAgb3BhY2l0eTogMTtcXG59XFxyXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9Nb2RhbC52dWU/MWZkZDYyNjBcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQXNHQTtFQUNBLDBCQUFBO0NBQ0E7QUFDQTtFQUNBLGtDQUFBO0NBQ0E7QUFDQTtFQUNBLDhCQUFBO0VBQ0EsMkJBQUE7RUFDQSwwQkFBQTtFQUNBLHNCQUFBO0VBQ0EsV0FBQTtFQUNBLFdBQUE7RUFDQSw2QkFBQTtFQUNBLDBCQUFBO0VBQ0EscUJBQUE7Q0FDQTtBQUNBO0VBQ0EsNEJBQUE7RUFDQSx5QkFBQTtFQUNBLHdCQUFBO0VBQ0Esb0JBQUE7RUFDQSw2Q0FBQTtFQUNBLHFDQUFBO0VBQ0EsV0FBQTtDQUNBXCIsXCJmaWxlXCI6XCJNb2RhbC52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHRlbXBsYXRlPlxcclxcbiAgPGRpdiByb2xlPVxcXCJkaWFsb2dcXFwiIDpjbGFzcz1cXFwiWydtb2RhbCcsZWZmZWN0XVxcXCIgQGNsaWNrPVxcXCJiYWNrZHJvcCYmYWN0aW9uKGZhbHNlLDEpXFxcIiBAdHJhbnNpdGlvbmVuZD1cXFwidHJhbnNpdGlvbiA9IGZhbHNlXFxcIj5cXHJcXG4gICAgPGRpdiA6Y2xhc3M9XFxcIlsnbW9kYWwtZGlhbG9nJyx7J21vZGFsLWxnJzpsYXJnZSwnbW9kYWwtc20nOnNtYWxsfV1cXFwiIHJvbGU9XFxcImRvY3VtZW50XFxcIiA6c3R5bGU9XFxcInt3aWR0aDogb3B0aW9uYWxXaWR0aH1cXFwiIEBjbGljay5zdG9wPVxcXCJhY3Rpb24obnVsbClcXFwiPlxcclxcbiAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiPlxcclxcbiAgICAgICAgPHNsb3QgbmFtZT1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXHJcXG4gICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXHJcXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImNsb3NlXFxcIiBAY2xpY2s9XFxcImFjdGlvbihmYWxzZSwyKVxcXCI+PHNwYW4+JnRpbWVzOzwvc3Bhbj48L2J1dHRvbj5cXHJcXG4gICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj48c2xvdCBuYW1lPVxcXCJ0aXRsZVxcXCI+e3t0aXRsZX19PC9zbG90PjwvaDQ+XFxyXFxuICAgICAgICAgIDwvZGl2PlxcclxcbiAgICAgICAgPC9zbG90PlxcclxcbiAgICAgICAgPHNsb3QgbmFtZT1cXFwibW9kYWwtYm9keVxcXCI+PGRpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCI+PHNsb3Q+PC9zbG90PjwvZGl2Pjwvc2xvdD5cXHJcXG4gICAgICAgIDxzbG90IG5hbWU9XFxcIm1vZGFsLWZvb3RlclxcXCI+XFxyXFxuICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWZvb3RlclxcXCI+XFxyXFxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIEBjbGljaz1cXFwiYWN0aW9uKGZhbHNlLDMpXFxcIj57eyBjYW5jZWxUZXh0IH19PC9idXR0b24+XFxyXFxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLXByaW1hcnlcXFwiIEBjbGljaz1cXFwiYWN0aW9uKHRydWUsNClcXFwiPnt7IG9rVGV4dCB9fTwvYnV0dG9uPlxcclxcbiAgICAgICAgICA8L2Rpdj5cXHJcXG4gICAgICAgIDwvc2xvdD5cXHJcXG4gICAgICA8L2Rpdj5cXHJcXG4gICAgPC9kaXY+XFxyXFxuICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcblxcclxcbjxzY3JpcHQ+XFxyXFxuaW1wb3J0IHtnZXRTY3JvbGxCYXJXaWR0aH0gZnJvbSAnLi91dGlscy91dGlscy5qcydcXHJcXG5cXHJcXG5leHBvcnQgZGVmYXVsdCB7XFxyXFxuICBwcm9wczoge1xcclxcbiAgICBiYWNrZHJvcDoge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IHRydWV9LFxcclxcbiAgICBjYWxsYmFjazoge3R5cGU6IEZ1bmN0aW9uLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgY2FuY2VsVGV4dDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogJ0Nsb3NlJ30sXFxyXFxuICAgIGVmZmVjdDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIGxhcmdlOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBva1RleHQ6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICdTYXZlIGNoYW5nZXMnfSxcXHJcXG4gICAgc21hbGw6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIHRpdGxlOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnJ30sXFxyXFxuICAgIHZhbHVlOiB7dHlwZTogQm9vbGVhbiwgcmVxdWlyZWQ6IHRydWV9LFxcclxcbiAgICB3aWR0aDoge2RlZmF1bHQ6IG51bGx9XFxyXFxuICB9LFxcclxcbiAgZGF0YSAoKSB7XFxyXFxuICAgIHJldHVybiB7XFxyXFxuICAgICAgdHJhbnNpdGlvbjogZmFsc2UsXFxyXFxuICAgICAgdmFsOiBudWxsXFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBjb21wdXRlZDoge1xcclxcbiAgICBvcHRpb25hbFdpZHRoICgpIHtcXHJcXG4gICAgICBpZiAodGhpcy53aWR0aCA9PT0gbnVsbCkge1xcclxcbiAgICAgICAgcmV0dXJuIG51bGxcXHJcXG4gICAgICB9IGVsc2UgaWYgKE51bWJlci5pc0ludGVnZXIodGhpcy53aWR0aCkpIHtcXHJcXG4gICAgICAgIHJldHVybiB0aGlzLndpZHRoICsgJ3B4J1xcclxcbiAgICAgIH1cXHJcXG4gICAgICByZXR1cm4gdGhpcy53aWR0aFxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgd2F0Y2g6IHtcXHJcXG4gICAgdHJhbnNpdGlvbiAodmFsLCBvbGQpIHtcXHJcXG4gICAgICBpZiAodmFsID09PSBvbGQpIHsgcmV0dXJuIH1cXHJcXG4gICAgICBjb25zdCBlbCA9IHRoaXMuJGVsXFxyXFxuICAgICAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHlcXHJcXG4gICAgICBpZiAodmFsKSB7Ly9zdGFydGluZ1xcclxcbiAgICAgICAgaWYgKHRoaXMudmFsKSB7XFxyXFxuICAgICAgICAgIGVsLnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbC1jb250ZW50JykuZm9jdXMoKVxcclxcbiAgICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJ1xcclxcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IGVsLmNsYXNzTGlzdC5hZGQoJ2luJyksIDApXFxyXFxuICAgICAgICAgIGJvZHkuY2xhc3NMaXN0LmFkZCgnbW9kYWwtb3BlbicpXFxyXFxuICAgICAgICAgIGlmIChnZXRTY3JvbGxCYXJXaWR0aCgpICE9PSAwKSB7XFxyXFxuICAgICAgICAgICAgYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSBnZXRTY3JvbGxCYXJXaWR0aCgpICsgJ3B4J1xcclxcbiAgICAgICAgICB9XFxyXFxuICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKCdpbicpXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgfSBlbHNlIHsvL2VuZGluZ1xcclxcbiAgICAgICAgdGhpcy4kZW1pdCh0aGlzLnZhbCA/ICdvcGVuZWQnIDogJ2Nsb3NlZCcpXFxyXFxuICAgICAgICBpZiAoIXRoaXMudmFsKSB7XFxyXFxuICAgICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSdcXHJcXG4gICAgICAgICAgYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSBudWxsXFxyXFxuICAgICAgICAgIGJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnbW9kYWwtb3BlbicpXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICB2YWwgKHZhbCwgb2xkKSB7XFxyXFxuICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCB2YWwpXFxyXFxuICAgICAgaWYgKG9sZCA9PT0gbnVsbCA/IHZhbCA9PT0gdHJ1ZSA6IHZhbCAhPT0gb2xkKSB0aGlzLnRyYW5zaXRpb24gPSB0cnVlXFxyXFxuICAgIH0sXFxyXFxuICAgIHZhbHVlICh2YWwsIG9sZCkge1xcclxcbiAgICAgIGlmICh2YWwgIT09IG9sZCkgdGhpcy52YWwgPSB2YWxcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgYWN0aW9uICh2YWwscCkge1xcclxcbiAgICAgIGlmICh2YWwgPT09IG51bGwpIHsgcmV0dXJuIH1cXHJcXG4gICAgICBpZiAodmFsICYmIHRoaXMuY2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvbikgdGhpcy5jYWxsYmFjaygpXFxyXFxuICAgICAgdGhpcy4kZW1pdCh2YWwgPyAnb2snIDogJ2NhbmNlbCcscClcXHJcXG4gICAgICB0aGlzLnZhbCA9IHZhbCB8fCBmYWxzZVxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgbW91bnRlZCAoKSB7XFxyXFxuICAgIHRoaXMudmFsID0gdGhpcy52YWx1ZVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG48c3R5bGU+XFxyXFxuLm1vZGFsIHtcXHJcXG4gIHRyYW5zaXRpb246IGFsbCAwLjNzIGVhc2U7XFxyXFxufVxcclxcbi5tb2RhbC5pbiB7XFxyXFxuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsMCwwLDAuNSk7XFxyXFxufVxcclxcbi5tb2RhbC56b29tIC5tb2RhbC1kaWFsb2cge1xcclxcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlKDAuMSk7XFxyXFxuICAtbW96LXRyYW5zZm9ybTogc2NhbGUoMC4xKTtcXHJcXG4gIC1tcy10cmFuc2Zvcm06IHNjYWxlKDAuMSk7XFxyXFxuICB0cmFuc2Zvcm06IHNjYWxlKDAuMSk7XFxyXFxuICB0b3A6IDMwMHB4O1xcclxcbiAgb3BhY2l0eTogMDtcXHJcXG4gIC13ZWJraXQtdHJhbnNpdGlvbjogYWxsIDAuM3M7XFxyXFxuICAtbW96LXRyYW5zaXRpb246IGFsbCAwLjNzO1xcclxcbiAgdHJhbnNpdGlvbjogYWxsIDAuM3M7XFxyXFxufVxcclxcbi5tb2RhbC56b29tLmluIC5tb2RhbC1kaWFsb2cge1xcclxcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlKDEpO1xcclxcbiAgLW1vei10cmFuc2Zvcm06IHNjYWxlKDEpO1xcclxcbiAgLW1zLXRyYW5zZm9ybTogc2NhbGUoMSk7XFxyXFxuICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xcclxcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsIC0zMDBweCwgMCk7XFxyXFxuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsIC0zMDBweCwgMCk7XFxyXFxuICBvcGFjaXR5OiAxO1xcclxcbn1cXHJcXG48L3N0eWxlPlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogMTIyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfaXNJbnRlZ2VyID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMjMpO1xuXHRcblx0dmFyIF9pc0ludGVnZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJbnRlZ2VyKTtcblx0XG5cdHZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDY1KTtcblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgcHJvcHM6IHtcblx0ICAgIGJhY2tkcm9wOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IHRydWUgfSxcblx0ICAgIGNhbGxiYWNrOiB7IHR5cGU6IEZ1bmN0aW9uLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBjYW5jZWxUZXh0OiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogJ0Nsb3NlJyB9LFxuXHQgICAgZWZmZWN0OiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgbGFyZ2U6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIG9rVGV4dDogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICdTYXZlIGNoYW5nZXMnIH0sXG5cdCAgICBzbWFsbDogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgdGl0bGU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnJyB9LFxuXHQgICAgdmFsdWU6IHsgdHlwZTogQm9vbGVhbiwgcmVxdWlyZWQ6IHRydWUgfSxcblx0ICAgIHdpZHRoOiB7IGRlZmF1bHQ6IG51bGwgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIHRyYW5zaXRpb246IGZhbHNlLFxuXHQgICAgICB2YWw6IG51bGxcblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgY29tcHV0ZWQ6IHtcblx0ICAgIG9wdGlvbmFsV2lkdGg6IGZ1bmN0aW9uIG9wdGlvbmFsV2lkdGgoKSB7XG5cdCAgICAgIGlmICh0aGlzLndpZHRoID09PSBudWxsKSB7XG5cdCAgICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICAgIH0gZWxzZSBpZiAoKDAsIF9pc0ludGVnZXIyLmRlZmF1bHQpKHRoaXMud2lkdGgpKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lkdGggKyAncHgnO1xuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiB0aGlzLndpZHRoO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgd2F0Y2g6IHtcblx0ICAgIHRyYW5zaXRpb246IGZ1bmN0aW9uIHRyYW5zaXRpb24odmFsLCBvbGQpIHtcblx0ICAgICAgaWYgKHZhbCA9PT0gb2xkKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICAgIHZhciBlbCA9IHRoaXMuJGVsO1xuXHQgICAgICB2YXIgYm9keSA9IGRvY3VtZW50LmJvZHk7XG5cdCAgICAgIGlmICh2YWwpIHtcblx0ICAgICAgICAvL3N0YXJ0aW5nXG5cdCAgICAgICAgaWYgKHRoaXMudmFsKSB7XG5cdCAgICAgICAgICBlbC5xdWVyeVNlbGVjdG9yKCcubW9kYWwtY29udGVudCcpLmZvY3VzKCk7XG5cdCAgICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblx0ICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gZWwuY2xhc3NMaXN0LmFkZCgnaW4nKTtcblx0ICAgICAgICAgIH0sIDApO1xuXHQgICAgICAgICAgYm9keS5jbGFzc0xpc3QuYWRkKCdtb2RhbC1vcGVuJyk7XG5cdCAgICAgICAgICBpZiAoKDAsIF91dGlscy5nZXRTY3JvbGxCYXJXaWR0aCkoKSAhPT0gMCkge1xuXHQgICAgICAgICAgICBib2R5LnN0eWxlLnBhZGRpbmdSaWdodCA9ICgwLCBfdXRpbHMuZ2V0U2Nyb2xsQmFyV2lkdGgpKCkgKyAncHgnO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKCdpbicpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAvL2VuZGluZ1xuXHQgICAgICAgIHRoaXMuJGVtaXQodGhpcy52YWwgPyAnb3BlbmVkJyA6ICdjbG9zZWQnKTtcblx0ICAgICAgICBpZiAoIXRoaXMudmFsKSB7XG5cdCAgICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHQgICAgICAgICAgYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSBudWxsO1xuXHQgICAgICAgICAgYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdtb2RhbC1vcGVuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdmFsOiBmdW5jdGlvbiB2YWwoX3ZhbCwgb2xkKSB7XG5cdCAgICAgIHRoaXMuJGVtaXQoJ2lucHV0JywgX3ZhbCk7XG5cdCAgICAgIGlmIChvbGQgPT09IG51bGwgPyBfdmFsID09PSB0cnVlIDogX3ZhbCAhPT0gb2xkKSB0aGlzLnRyYW5zaXRpb24gPSB0cnVlO1xuXHQgICAgfSxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZSh2YWwsIG9sZCkge1xuXHQgICAgICBpZiAodmFsICE9PSBvbGQpIHRoaXMudmFsID0gdmFsO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbWV0aG9kczoge1xuXHQgICAgYWN0aW9uOiBmdW5jdGlvbiBhY3Rpb24odmFsLCBwKSB7XG5cdCAgICAgIGlmICh2YWwgPT09IG51bGwpIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICAgIH1cblx0ICAgICAgaWYgKHZhbCAmJiB0aGlzLmNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24pIHRoaXMuY2FsbGJhY2soKTtcblx0ICAgICAgdGhpcy4kZW1pdCh2YWwgPyAnb2snIDogJ2NhbmNlbCcsIHApO1xuXHQgICAgICB0aGlzLnZhbCA9IHZhbCB8fCBmYWxzZTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1vdW50ZWQ6IGZ1bmN0aW9uIG1vdW50ZWQoKSB7XG5cdCAgICB0aGlzLnZhbCA9IHRoaXMudmFsdWU7XG5cdCAgfVxuXHR9OyAvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXG4vKioqLyB9LFxuLyogMTIzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IF9fd2VicGFja19yZXF1aXJlX18oMTI0KSwgX19lc01vZHVsZTogdHJ1ZSB9O1xuXG4vKioqLyB9LFxuLyogMTI0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDEyNSk7XG5cdG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3KS5OdW1iZXIuaXNJbnRlZ2VyO1xuXG4vKioqLyB9LFxuLyogMTI1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyAyMC4xLjIuMyBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlcilcblx0dmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpO1xuXHRcblx0JGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7aXNJbnRlZ2VyOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDEyNil9KTtcblxuLyoqKi8gfSxcbi8qIDEyNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gMjAuMS4yLjMgTnVtYmVyLmlzSW50ZWdlcihudW1iZXIpXG5cdHZhciBpc09iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oMTMpXG5cdCAgLCBmbG9vciAgICA9IE1hdGguZmxvb3I7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNJbnRlZ2VyKGl0KXtcblx0ICByZXR1cm4gIWlzT2JqZWN0KGl0KSAmJiBpc0Zpbml0ZShpdCkgJiYgZmxvb3IoaXQpID09PSBpdDtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDEyNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDtcblx0ICByZXR1cm4gX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBjbGFzczogWydtb2RhbCcsIF92bS5lZmZlY3RdLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJyb2xlXCI6IFwiZGlhbG9nXCJcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIF92bS5iYWNrZHJvcCAmJiBfdm0uYWN0aW9uKGZhbHNlLCAxKVxuXHQgICAgICB9LFxuXHQgICAgICBcInRyYW5zaXRpb25lbmRcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnRyYW5zaXRpb24gPSBmYWxzZVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgY2xhc3M6IFsnbW9kYWwtZGlhbG9nJywge1xuXHQgICAgICAnbW9kYWwtbGcnOiBfdm0ubGFyZ2UsXG5cdCAgICAgICdtb2RhbC1zbSc6IF92bS5zbWFsbFxuXHQgICAgfV0sXG5cdCAgICBzdHlsZTogKHtcblx0ICAgICAgd2lkdGg6IF92bS5vcHRpb25hbFdpZHRoXG5cdCAgICB9KSxcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwicm9sZVwiOiBcImRvY3VtZW50XCJcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICBfdm0uYWN0aW9uKG51bGwpXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJtb2RhbC1jb250ZW50XCJcblx0ICB9LCBbX3ZtLl90KFwibW9kYWwtaGVhZGVyXCIsIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWhlYWRlclwiXG5cdCAgfSwgW192bS5fYygnYnV0dG9uJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiY2xvc2VcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcImJ1dHRvblwiXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBfdm0uYWN0aW9uKGZhbHNlLCAyKVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygnc3BhbicsIFtfdm0uX3YoXCLDl1wiKV0pXSksIF92bS5fdihcIiBcIiksIF92bS5fYygnaDQnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJtb2RhbC10aXRsZVwiXG5cdCAgfSwgW192bS5fdChcInRpdGxlXCIsIFtfdm0uX3YoX3ZtLl9zKF92bS50aXRsZSkpXSldLCAyKV0pXSksIF92bS5fdihcIiBcIiksIF92bS5fdChcIm1vZGFsLWJvZHlcIiwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtYm9keVwiXG5cdCAgfSwgW192bS5fdChcImRlZmF1bHRcIildLCAyKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX3QoXCJtb2RhbC1mb290ZXJcIiwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtZm9vdGVyXCJcblx0ICB9LCBbX3ZtLl9jKCdidXR0b24nLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJidG4gYnRuLWRlZmF1bHRcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcImJ1dHRvblwiXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBfdm0uYWN0aW9uKGZhbHNlLCAzKVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSwgW192bS5fdihfdm0uX3MoX3ZtLmNhbmNlbFRleHQpKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ2J1dHRvbicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImJ0biBidG4tcHJpbWFyeVwiLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJ0eXBlXCI6IFwiYnV0dG9uXCJcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIF92bS5hY3Rpb24odHJ1ZSwgNClcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0sIFtfdm0uX3YoX3ZtLl9zKF92bS5va1RleHQpKV0pXSldKV0sIDIpXSldKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1mZTdkNWRjOFwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDEyOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMjkpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTMwKVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXE5hdmJhci52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtMzhmMDYxOWVcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTM4ZjA2MTllXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gTmF2YmFyLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDEyOSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdFxuXHR2YXIgX05vZGVMaXN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblx0XG5cdHZhciBfTm9kZUxpc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTm9kZUxpc3QpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgdHlwZTogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICdkZWZhdWx0JyB9LFxuXHQgICAgcGxhY2VtZW50OiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogJycgfSxcblx0ICAgIGNvbnRhaW5lcjogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICcnIH1cblx0ICB9LFxuXHQgIGRhdGE6IGZ1bmN0aW9uIGRhdGEoKSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBpZDogJ2JzLWV4YW1wbGUtbmF2YmFyLWNvbGxhcHNlLTEnLFxuXHQgICAgICBjb2xsYXBzZWQ6IHRydWUsXG5cdCAgICAgIHN0eWxlczoge31cblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgY29tcHV0ZWQ6IHtcblx0ICAgIHNsb3RzOiBmdW5jdGlvbiBzbG90cygpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuX3Nsb3RDb250ZW50cztcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIHRvZ2dsZUNvbGxhcHNlOiBmdW5jdGlvbiB0b2dnbGVDb2xsYXBzZShlKSB7XG5cdCAgICAgIGUgJiYgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICB0aGlzLmNvbGxhcHNlZCA9ICF0aGlzLmNvbGxhcHNlZDtcblx0ICAgIH1cblx0ICB9LFxuXHQgIGNyZWF0ZWQ6IGZ1bmN0aW9uIGNyZWF0ZWQoKSB7XG5cdCAgICB0aGlzLl9uYXZiYXIgPSB0cnVlO1xuXHQgIH0sXG5cdCAgbW91bnRlZDogZnVuY3Rpb24gbW91bnRlZCgpIHtcblx0ICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgdHJ5IHtcblx0ICAgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgJGRyb3Bkb3duID0gKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkoJy5kcm9wZG93bj5bZGF0YS10b2dnbGU9XCJkcm9wZG93blwiXScsIF90aGlzLiRlbCkucGFyZW50KCk7XG5cdCAgICAgICAgaWYgKCRkcm9wZG93bikge1xuXHQgICAgICAgICAgJGRyb3Bkb3duLm9uKCdjbGljaycsICcuZHJvcGRvd24tdG9nZ2xlJywgZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgICAgICAkZHJvcGRvd24uZWFjaChmdW5jdGlvbiAoY29udGVudCkge1xuXHQgICAgICAgICAgICAgIGlmIChjb250ZW50LmNvbnRhaW5zKGUudGFyZ2V0KSkgY29udGVudC5jbGFzc0xpc3QudG9nZ2xlKCdvcGVuJyk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgfSkub24oJ2NsaWNrJywgJy5kcm9wZG93bi1tZW51PmxpPmEnLCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgICAkZHJvcGRvd24uZWFjaChmdW5jdGlvbiAoY29udGVudCkge1xuXHQgICAgICAgICAgICAgIGlmIChjb250ZW50LmNvbnRhaW5zKGUudGFyZ2V0KSkgY29udGVudC5jbGFzc0xpc3QucmVtb3ZlKCdvcGVuJyk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgfSkub25CbHVyKGZ1bmN0aW9uIChlKSB7XG5cdCAgICAgICAgICAgICRkcm9wZG93bi5lYWNoKGZ1bmN0aW9uIChjb250ZW50KSB7XG5cdCAgICAgICAgICAgICAgaWYgKCFjb250ZW50LmNvbnRhaW5zKGUudGFyZ2V0KSkgY29udGVudC5jbGFzc0xpc3QucmVtb3ZlKCdvcGVuJyk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9KSgpO1xuXHQgICAgfSBjYXRjaCAoZXgpIHtcblx0ICAgICAgY29uc29sZS5sb2coJ2Vycm9yIGZpbmRpbmcgZHJvcGRvd24nKTtcblx0ICAgIH1cblx0XG5cdCAgICAoMCwgX05vZGVMaXN0Mi5kZWZhdWx0KSh0aGlzLiRlbCkub24oJ2NsaWNrIHRvdWNoc3RhcnQnLCAnbGk6bm90KC5kcm9wZG93bik+YScsIGZ1bmN0aW9uIChlKSB7XG5cdCAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIF90aGlzLmNvbGxhcHNlZCA9IHRydWU7XG5cdCAgICAgIH0sIDIwMCk7XG5cdCAgICB9KS5vbkJsdXIoZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgaWYgKCFfdGhpcy4kZWwuY29udGFpbnMoZS50YXJnZXQpKSB7XG5cdCAgICAgICAgX3RoaXMuY29sbGFwc2VkID0gdHJ1ZTtcblx0ICAgICAgfVxuXHQgICAgfSk7XG5cdCAgICB2YXIgaGVpZ2h0ID0gdGhpcy4kZWwub2Zmc2V0SGVpZ2h0O1xuXHQgICAgaWYgKHRoaXMucGxhY2VtZW50ID09PSAndG9wJykge1xuXHQgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmdUb3AgPSBoZWlnaHQgKyAncHgnO1xuXHQgICAgfVxuXHQgICAgaWYgKHRoaXMucGxhY2VtZW50ID09PSAnYm90dG9tJykge1xuXHQgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmdCb3R0b20gPSBoZWlnaHQgKyAncHgnO1xuXHQgICAgfVxuXHQgICAgaWYgKHRoaXMuJHNsb3RzLmNvbGxhcHNlKSAoMCwgX05vZGVMaXN0Mi5kZWZhdWx0KSgnW2RhdGEtdG9nZ2xlPVwiY29sbGFwc2VcIl0nLCB0aGlzLiRlbCkub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcblx0ICAgICAgcmV0dXJuIF90aGlzLnRvZ2dsZUNvbGxhcHNlKGUpO1xuXHQgICAgfSk7XG5cdCAgfSxcblx0ICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbiBiZWZvcmVEZXN0cm95KCkge1xuXHQgICAgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkoJy5kcm9wZG93bicsIHRoaXMuJGVsKS5vZmYoJ2NsaWNrJykub2ZmQmx1cigpO1xuXHQgICAgaWYgKHRoaXMuJHNsb3RzLmNvbGxhcHNlKSAoMCwgX05vZGVMaXN0Mi5kZWZhdWx0KSgnW2RhdGEtdG9nZ2xlPVwiY29sbGFwc2VcIl0nLCB0aGlzLiRlbCkub2ZmKCdjbGljaycpO1xuXHQgIH1cblx0fTsgLy9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblxuLyoqKi8gfSxcbi8qIDEzMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDtcblx0ICByZXR1cm4gX3ZtLl9jKCduYXYnLCB7XG5cdCAgICBjbGFzczogWyduYXZiYXInLCAnbmF2YmFyLScgKyBfdm0udHlwZSwgX3ZtLnBsYWNlbWVudCA9PT0gJ3N0YXRpYycgPyAnbmF2YmFyLXN0YXRpYy10b3AnIDogJ25hdmJhci1maXhlZC0nICsgX3ZtLnBsYWNlbWVudF1cblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBjbGFzczogX3ZtLmNvbnRhaW5lciA9PT0gJ2ZsdWlkJyA/ICdjb250YWluZXItZmx1aWQnIDogJ2NvbnRhaW5lcidcblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJuYXZiYXItaGVhZGVyXCJcblx0ICB9LCBbKCFfdm0uJHNsb3RzLmNvbGxhcHNlKSA/IF92bS5fYygnYnV0dG9uJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwibmF2YmFyLXRvZ2dsZSBjb2xsYXBzZWRcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcImJ1dHRvblwiLFxuXHQgICAgICBcImFyaWEtZXhwYW5kZWRcIjogXCJmYWxzZVwiXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBfdm0udG9nZ2xlQ29sbGFwc2Vcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwic3Itb25seVwiXG5cdCAgfSwgW192bS5fdihcIlRvZ2dsZSBuYXZpZ2F0aW9uXCIpXSksIF92bS5fdihcIiBcIiksIF92bS5fYygnc3BhbicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImljb24tYmFyXCJcblx0ICB9KSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiaWNvbi1iYXJcIlxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJpY29uLWJhclwiXG5cdCAgfSldKSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCBfdm0uX3QoXCJjb2xsYXBzZVwiKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl90KFwiYnJhbmRcIildLCAyKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBjbGFzczogWyduYXZiYXItY29sbGFwc2UnLCB7XG5cdCAgICAgIGNvbGxhcHNlOiBfdm0uY29sbGFwc2VkXG5cdCAgICB9XVxuXHQgIH0sIFtfdm0uX2MoJ3VsJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwibmF2IG5hdmJhci1uYXZcIlxuXHQgIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMiksIF92bS5fdihcIiBcIiksIChfdm0uJHNsb3RzLmxlZnQpID8gX3ZtLl9jKCd1bCcsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcIm5hdiBuYXZiYXItbmF2IG5hdmJhci1sZWZ0XCJcblx0ICB9LCBbX3ZtLl90KFwibGVmdFwiKV0sIDIpIDogX3ZtLl9lKCksIF92bS5fdihcIiBcIiksIChfdm0uJHNsb3RzLnJpZ2h0KSA/IF92bS5fYygndWwnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJuYXYgbmF2YmFyLW5hdiBuYXZiYXItcmlnaHRcIlxuXHQgIH0sIFtfdm0uX3QoXCJyaWdodFwiKV0sIDIpIDogX3ZtLl9lKCldKV0pXSlcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMzhmMDYxOWVcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxMzEgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTMyKVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzMylcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxPcHRpb24udnVlXCJcblx0X192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5cdF9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTQyMDg4MTE2XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi00MjA4ODExNlwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIE9wdGlvbi52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IF9fdnVlX2V4cG9ydHNfX1xuXG5cbi8qKiovIH0sXG4vKiAxMzIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHQvL1xuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIHByb3BzOiB7IHZhbHVlOiBudWxsIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7IGxvYWRpbmc6IHRydWUgfTtcblx0ICB9LFxuXHQgIG1vdW50ZWQ6IGZ1bmN0aW9uIG1vdW50ZWQoKSB7XG5cdCAgICBpZiAodGhpcy4kcGFyZW50Ll9zZWxlY3QpIHtcblx0ICAgICAgaWYgKCF0aGlzLiRwYXJlbnQub3B0aW9ucykge1xuXHQgICAgICAgIHRoaXMuJHBhcmVudC5vcHRpb25zID0gW107XG5cdCAgICAgIH1cblx0ICAgICAgdmFyIGVsID0ge307XG5cdCAgICAgIGVsW3RoaXMuJHBhcmVudC5vcHRpb25zTGFiZWxdID0gdGhpcy4kZWwuaW5uZXJIVE1MO1xuXHQgICAgICBlbFt0aGlzLiRwYXJlbnQub3B0aW9uc1ZhbHVlXSA9IHRoaXMudmFsdWU7XG5cdCAgICAgIHRoaXMuJHBhcmVudC5vcHRpb25zLnB1c2goZWwpO1xuXHQgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIGNvbnNvbGUud2Fybignb3B0aW9ucyBvbmx5IHdvcmsgaW5zaWRlIGEgc2VsZWN0IGNvbXBvbmVudCcpO1xuXHQgICAgfVxuXHQgIH1cblx0fTtcblxuLyoqKi8gfSxcbi8qIDEzMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDtcblx0ICByZXR1cm4gKF92bS5sb2FkaW5nKSA/IF92bS5fYygnbGknLCBbX3ZtLl90KFwiZGVmYXVsdFwiKV0sIDIpIDogX3ZtLl9lKClcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtNDIwODgxMTZcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxMzQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc3R5bGVzICovXG5cdF9fd2VicGFja19yZXF1aXJlX18oMTM1KVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTM3KVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzOClcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxQYW5lbC52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtYjFlMDQ2MWFcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LWIxZTA0NjFhXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gUGFuZWwudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTM1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMzYpO1xuXHRpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcblx0Ly8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxuXHR2YXIgdXBkYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OSkoY29udGVudCwge30pO1xuXHRpZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcblx0Ly8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuXHRpZihmYWxzZSkge1xuXHRcdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWIxZTA0NjFhIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9QYW5lbC52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWIxZTA0NjFhIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9QYW5lbC52dWVcIik7XG5cdFx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xuXHR9XG5cbi8qKiovIH0sXG4vKiAxMzYgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oNzgpKCk7XG5cdC8vIGltcG9ydHNcblx0XG5cdFxuXHQvLyBtb2R1bGVcblx0ZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuLmFjY29yZGlvbi10b2dnbGUge1xcclxcbiAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4uY29sbGFwc2UtZW50ZXItYWN0aXZlLFxcclxcbi5jb2xsYXBzZS1sZWF2ZS1hY3RpdmUge1xcclxcbiAgdHJhbnNpdGlvbjogYWxsIC41cyBlYXNlO1xcclxcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcXG59XFxuLmNvbGxhcHNlLWVudGVyLFxcclxcbi5jb2xsYXBzZS1sZWF2ZS1hY3RpdmUge1xcbn1cXHJcXG5cXHJcXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL1BhbmVsLnZ1ZT82MGU3OThlMlwiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiO0FBeUVBO0VBQ0EsZ0JBQUE7Q0FDQTtBQUNBOztFQUVBLHlCQUFBO0VBQ0EsaUJBQUE7Q0FDQTtBQUNBOztDQUdBXCIsXCJmaWxlXCI6XCJQYW5lbC52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHRlbXBsYXRlPlxcclxcbiAgPGRpdiA6Y2xhc3M9XFxcIlsncGFuZWwnLHBhbmVsVHlwZV1cXFwiPlxcclxcbiAgICA8ZGl2IDpjbGFzcz1cXFwiWydwYW5lbC1oZWFkaW5nJyx7J2FjY29yZGlvbi10b2dnbGUnOmluQWNjb3JkaW9ufV1cXFwiIEBjbGljay5wcmV2ZW50PVxcXCJpbkFjY29yZGlvbiYmdG9nZ2xlKClcXFwiPlxcclxcbiAgICAgIDxzbG90IG5hbWU9XFxcImhlYWRlclxcXCI+PGg0IGNsYXNzPVxcXCJwYW5lbC10aXRsZVxcXCI+e3sgaGVhZGVyIH19PC9oND48L3Nsb3Q+XFxyXFxuICAgIDwvZGl2PlxcclxcbiAgICA8dHJhbnNpdGlvblxcclxcbiAgICAgIG5hbWU9XFxcImNvbGxhcHNlXFxcIlxcclxcbiAgICAgIEBlbnRlcj1cXFwiZW50ZXJcXFwiXFxyXFxuICAgICAgQGFmdGVyLWVudGVyPVxcXCJhZnRlckVudGVyXFxcIlxcclxcbiAgICAgIEBiZWZvcmUtbGVhdmU9XFxcImJlZm9yZUxlYXZlXFxcIlxcclxcbiAgICA+XFxyXFxuICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwtY29sbGFwc2VcXFwiIHYtaWY9XFxcIm9wZW5cXFwiPlxcclxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwtYm9keVxcXCI+XFxyXFxuICAgICAgICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgICAgIDwvZGl2PlxcclxcbiAgICAgIDwvZGl2PlxcclxcbiAgICA8L3RyYW5zaXRpb24+XFxyXFxuICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcblxcclxcbjxzY3JpcHQ+XFxyXFxuZXhwb3J0IGRlZmF1bHQge1xcclxcbiAgcHJvcHM6IHtcXHJcXG4gICAgaGVhZGVyOiB7dHlwZTogU3RyaW5nfSxcXHJcXG4gICAgaXNPcGVuOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIHR5cGU6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQgOiBudWxsfVxcclxcbiAgfSxcXHJcXG4gIGRhdGEoKSB7XFxyXFxuICAgIHJldHVybiB7XFxyXFxuICAgICAgb3BlbjogdGhpcy5pc09wZW5cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIHdhdGNoOiB7XFxyXFxuICAgIGlzT3BlbiggdmFsICkge1xcclxcbiAgICAgIHRoaXMub3BlbiA9IHZhbFxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgY29tcHV0ZWQ6IHtcXHJcXG4gICAgaW5BY2NvcmRpb24gKCkgeyByZXR1cm4gdGhpcy4kcGFyZW50ICYmIHRoaXMuJHBhcmVudC5faXNBY2NvcmRpb24gfSxcXHJcXG4gICAgcGFuZWxUeXBlICgpIHsgcmV0dXJuICdwYW5lbC0nICsgKHRoaXMudHlwZSB8fCAodGhpcy4kcGFyZW50ICYmIHRoaXMuJHBhcmVudC50eXBlKSB8fCAnZGVmYXVsdCcpIH1cXHJcXG4gIH0sXFxyXFxuICBtZXRob2RzOiB7XFxyXFxuICAgIHRvZ2dsZSAoKSB7XFxyXFxuICAgICAgdGhpcy5vcGVuID0gIXRoaXMub3BlblxcclxcbiAgICAgIGlmICh0aGlzLmluQWNjb3JkaW9uKSB7XFxyXFxuICAgICAgICB0aGlzLiRwYXJlbnQub3BlbkNoaWxkKHRoaXMpXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICBlbnRlciAoZWwpIHtcXHJcXG4gICAgICBlbC5zdHlsZS5oZWlnaHQgPSAnYXV0bydcXHJcXG4gICAgICB2YXIgZW5kV2lkdGggPSBnZXRDb21wdXRlZFN0eWxlKGVsKS5oZWlnaHRcXHJcXG4gICAgICBlbC5zdHlsZS5oZWlnaHQgPSAnMHB4J1xcclxcbiAgICAgIGVsLm9mZnNldEhlaWdodCAvLyBmb3JjZSByZXBhaW50XFxyXFxuICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gZW5kV2lkdGg7XFxyXFxuICAgIH0sXFxyXFxuICAgIGFmdGVyRW50ZXIgKGVsKSB7XFxyXFxuICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nXFxyXFxuICAgIH0sXFxyXFxuICAgIGJlZm9yZUxlYXZlIChlbCkge1xcclxcbiAgICAgIGVsLnN0eWxlLmhlaWdodCA9IGdldENvbXB1dGVkU3R5bGUoZWwpLmhlaWdodFxcclxcbiAgICAgIGVsLm9mZnNldEhlaWdodCAvLyBmb3JjZSByZXBhaW50XFxyXFxuICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gJzBweCdcXHJcXG4gICAgfSxcXHJcXG4gIH0sXFxyXFxuICBjcmVhdGVkICgpIHtcXHJcXG4gICAgaWYgKHRoaXMuaXNPcGVuID09PSBudWxsKSB7XFxyXFxuICAgICAgdGhpcy5vcGVuID0gIXRoaXMuaW5BY2NvcmRpb25cXHJcXG4gICAgfVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGU+XFxyXFxuLmFjY29yZGlvbi10b2dnbGUge1xcclxcbiAgY3Vyc29yOiBwb2ludGVyO1xcclxcbn1cXHJcXG4uY29sbGFwc2UtZW50ZXItYWN0aXZlLFxcclxcbi5jb2xsYXBzZS1sZWF2ZS1hY3RpdmUge1xcclxcbiAgdHJhbnNpdGlvbjogYWxsIC41cyBlYXNlO1xcclxcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcXHJcXG59XFxyXFxuLmNvbGxhcHNlLWVudGVyLFxcclxcbi5jb2xsYXBzZS1sZWF2ZS1hY3RpdmUge1xcclxcblxcclxcbn1cXHJcXG5cXHJcXG48L3N0eWxlPlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogMTM3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgaGVhZGVyOiB7IHR5cGU6IFN0cmluZyB9LFxuXHQgICAgaXNPcGVuOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIHR5cGU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH1cblx0ICB9LFxuXHQgIGRhdGE6IGZ1bmN0aW9uIGRhdGEoKSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBvcGVuOiB0aGlzLmlzT3BlblxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICB3YXRjaDoge1xuXHQgICAgaXNPcGVuOiBmdW5jdGlvbiBpc09wZW4odmFsKSB7XG5cdCAgICAgIHRoaXMub3BlbiA9IHZhbDtcblx0ICAgIH1cblx0ICB9LFxuXHQgIGNvbXB1dGVkOiB7XG5cdCAgICBpbkFjY29yZGlvbjogZnVuY3Rpb24gaW5BY2NvcmRpb24oKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50Ll9pc0FjY29yZGlvbjtcblx0ICAgIH0sXG5cdCAgICBwYW5lbFR5cGU6IGZ1bmN0aW9uIHBhbmVsVHlwZSgpIHtcblx0ICAgICAgcmV0dXJuICdwYW5lbC0nICsgKHRoaXMudHlwZSB8fCB0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50LnR5cGUgfHwgJ2RlZmF1bHQnKTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIHRvZ2dsZTogZnVuY3Rpb24gdG9nZ2xlKCkge1xuXHQgICAgICB0aGlzLm9wZW4gPSAhdGhpcy5vcGVuO1xuXHQgICAgICBpZiAodGhpcy5pbkFjY29yZGlvbikge1xuXHQgICAgICAgIHRoaXMuJHBhcmVudC5vcGVuQ2hpbGQodGhpcyk7XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBlbnRlcjogZnVuY3Rpb24gZW50ZXIoZWwpIHtcblx0ICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nO1xuXHQgICAgICB2YXIgZW5kV2lkdGggPSBnZXRDb21wdXRlZFN0eWxlKGVsKS5oZWlnaHQ7XG5cdCAgICAgIGVsLnN0eWxlLmhlaWdodCA9ICcwcHgnO1xuXHQgICAgICBlbC5vZmZzZXRIZWlnaHQ7IC8vIGZvcmNlIHJlcGFpbnRcblx0ICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gZW5kV2lkdGg7XG5cdCAgICB9LFxuXHQgICAgYWZ0ZXJFbnRlcjogZnVuY3Rpb24gYWZ0ZXJFbnRlcihlbCkge1xuXHQgICAgICBlbC5zdHlsZS5oZWlnaHQgPSAnYXV0byc7XG5cdCAgICB9LFxuXHQgICAgYmVmb3JlTGVhdmU6IGZ1bmN0aW9uIGJlZm9yZUxlYXZlKGVsKSB7XG5cdCAgICAgIGVsLnN0eWxlLmhlaWdodCA9IGdldENvbXB1dGVkU3R5bGUoZWwpLmhlaWdodDtcblx0ICAgICAgZWwub2Zmc2V0SGVpZ2h0OyAvLyBmb3JjZSByZXBhaW50XG5cdCAgICAgIGVsLnN0eWxlLmhlaWdodCA9ICcwcHgnO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIGlmICh0aGlzLmlzT3BlbiA9PT0gbnVsbCkge1xuXHQgICAgICB0aGlzLm9wZW4gPSAhdGhpcy5pbkFjY29yZGlvbjtcblx0ICAgIH1cblx0ICB9XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxMzggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYygnZGl2Jywge1xuXHQgICAgY2xhc3M6IFsncGFuZWwnLCBfdm0ucGFuZWxUeXBlXVxuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIGNsYXNzOiBbJ3BhbmVsLWhlYWRpbmcnLCB7XG5cdCAgICAgICdhY2NvcmRpb24tdG9nZ2xlJzogX3ZtLmluQWNjb3JkaW9uXG5cdCAgICB9XSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgX3ZtLmluQWNjb3JkaW9uICYmIF92bS50b2dnbGUoKVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSwgW192bS5fdChcImhlYWRlclwiLCBbX3ZtLl9jKCdoNCcsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcInBhbmVsLXRpdGxlXCJcblx0ICB9LCBbX3ZtLl92KF92bS5fcyhfdm0uaGVhZGVyKSldKV0pXSwgMiksIF92bS5fdihcIiBcIiksIF92bS5fYygndHJhbnNpdGlvbicsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwibmFtZVwiOiBcImNvbGxhcHNlXCJcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImVudGVyXCI6IF92bS5lbnRlcixcblx0ICAgICAgXCJhZnRlci1lbnRlclwiOiBfdm0uYWZ0ZXJFbnRlcixcblx0ICAgICAgXCJiZWZvcmUtbGVhdmVcIjogX3ZtLmJlZm9yZUxlYXZlXG5cdCAgICB9XG5cdCAgfSwgWyhfdm0ub3BlbikgPyBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcInBhbmVsLWNvbGxhcHNlXCJcblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJwYW5lbC1ib2R5XCJcblx0ICB9LCBbX3ZtLl90KFwiZGVmYXVsdFwiKV0sIDIpXSkgOiBfdm0uX2UoKV0pXSwgMSlcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtYjFlMDQ2MWFcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxMzkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc3R5bGVzICovXG5cdF9fd2VicGFja19yZXF1aXJlX18oMTQwKVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTQyKVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE0NClcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxQb3BvdmVyLnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0XG5cdC8qIGhvdCByZWxvYWQgKi9cblx0aWYgKGZhbHNlKSB7KGZ1bmN0aW9uICgpIHtcblx0ICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuXHQgIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuXHQgIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi0yNDY1YmY1NFwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfSBlbHNlIHtcblx0ICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtMjQ2NWJmNTRcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH1cblx0fSkoKX1cblx0aWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBQb3BvdmVyLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDE0MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblx0XG5cdC8vIGxvYWQgdGhlIHN0eWxlc1xuXHR2YXIgY29udGVudCA9IF9fd2VicGFja19yZXF1aXJlX18oMTQxKTtcblx0aWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG5cdC8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cblx0dmFyIHVwZGF0ZSA9IF9fd2VicGFja19yZXF1aXJlX18oNzkpKGNvbnRlbnQsIHt9KTtcblx0aWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG5cdC8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcblx0aWYoZmFsc2UpIHtcblx0XHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0yNDY1YmY1NCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vUG9wb3Zlci52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTI0NjViZjU0IS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9Qb3BvdmVyLnZ1ZVwiKTtcblx0XHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDE0MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0ZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OCkoKTtcblx0Ly8gaW1wb3J0c1xuXHRcblx0XG5cdC8vIG1vZHVsZVxuXHRleHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4ucG9wb3Zlci50b3AsXFxyXFxuLnBvcG92ZXIubGVmdCxcXHJcXG4ucG9wb3Zlci5yaWdodCxcXHJcXG4ucG9wb3Zlci5ib3R0b20ge1xcclxcbiAgZGlzcGxheTogYmxvY2s7XFxufVxcbi5zY2FsZS1lbnRlciB7XFxyXFxuICBhbmltYXRpb246c2NhbGUtaW4gMC4xNXMgZWFzZS1pbjtcXG59XFxuLnNjYWxlLWxlYXZlLWFjdGl2ZSB7XFxyXFxuICBhbmltYXRpb246c2NhbGUtb3V0IDAuMTVzIGVhc2Utb3V0O1xcbn1cXG5Aa2V5ZnJhbWVzIHNjYWxlLWluIHtcXG4wJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCk7XFxyXFxuICAgIG9wYWNpdHk6IDA7XFxufVxcbjEwMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xcclxcbiAgICBvcGFjaXR5OiAxO1xcbn1cXG59XFxuQGtleWZyYW1lcyBzY2FsZS1vdXQge1xcbjAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXHJcXG4gICAgb3BhY2l0eTogMTtcXG59XFxuMTAwJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCk7XFxyXFxuICAgIG9wYWNpdHk6IDA7XFxufVxcbn1cXHJcXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL1BvcG92ZXIudnVlP2U2MTY5NjNhXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUF5QkE7Ozs7RUFJQSxlQUFBO0NBQ0E7QUFDQTtFQUNBLGlDQUFBO0NBQ0E7QUFDQTtFQUNBLG1DQUFBO0NBQ0E7QUFDQTtBQUNBO0lBQ0Esb0JBQUE7SUFDQSxXQUFBO0NBQ0E7QUFDQTtJQUNBLG9CQUFBO0lBQ0EsV0FBQTtDQUNBO0NBQ0E7QUFDQTtBQUNBO0lBQ0Esb0JBQUE7SUFDQSxXQUFBO0NBQ0E7QUFDQTtJQUNBLG9CQUFBO0lBQ0EsV0FBQTtDQUNBO0NBQ0FcIixcImZpbGVcIjpcIlBvcG92ZXIudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxzcGFuIHJlZj1cXFwidHJpZ2dlclxcXCI+XFxyXFxuICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgPHRyYW5zaXRpb24gOm5hbWU9XFxcImVmZmVjdFxcXCI+XFxyXFxuICAgICAgPGRpdiByZWY9XFxcInBvcG92ZXJcXFwiIHYtaWY9XFxcInNob3dcXFwiIDpjbGFzcz1cXFwiWydwb3BvdmVyJyxwbGFjZW1lbnRdXFxcIj5cXHJcXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImFycm93XFxcIj48L2Rpdj5cXHJcXG4gICAgICAgIDxoMyBjbGFzcz1cXFwicG9wb3Zlci10aXRsZVxcXCIgdi1pZj1cXFwidGl0bGVcXFwiPjxzbG90IG5hbWU9XFxcInRpdGxlXFxcIj57e3RpdGxlfX08L3Nsb3Q+PC9oMz5cXHJcXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcInBvcG92ZXItY29udGVudFxcXCI+PHNsb3QgbmFtZT1cXFwiY29udGVudFxcXCI+PHNwYW4gdi1odG1sPVxcXCJjb250ZW50XFxcIj48L3NwYW4+PC9zbG90PjwvZGl2PlxcclxcbiAgICAgIDwvZGl2PlxcclxcbiAgICA8L3RyYW5zaXRpb24+XFxyXFxuICA8L3NwYW4+XFxyXFxuPC90ZW1wbGF0ZT5cXHJcXG5cXHJcXG48c2NyaXB0PlxcclxcbmltcG9ydCBQb3BvdmVyTWl4aW4gZnJvbSAnLi91dGlscy9wb3BvdmVyTWl4aW5zLmpzJ1xcclxcblxcclxcbmV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gIG1peGluczogW1BvcG92ZXJNaXhpbl0sXFxyXFxuICBwcm9wczoge1xcclxcbiAgICB0cmlnZ2VyOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnY2xpY2snfVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGU+XFxyXFxuLnBvcG92ZXIudG9wLFxcclxcbi5wb3BvdmVyLmxlZnQsXFxyXFxuLnBvcG92ZXIucmlnaHQsXFxyXFxuLnBvcG92ZXIuYm90dG9tIHtcXHJcXG4gIGRpc3BsYXk6IGJsb2NrO1xcclxcbn1cXHJcXG4uc2NhbGUtZW50ZXIge1xcclxcbiAgYW5pbWF0aW9uOnNjYWxlLWluIDAuMTVzIGVhc2UtaW47XFxyXFxufVxcclxcbi5zY2FsZS1sZWF2ZS1hY3RpdmUge1xcclxcbiAgYW5pbWF0aW9uOnNjYWxlLW91dCAwLjE1cyBlYXNlLW91dDtcXHJcXG59XFxyXFxuQGtleWZyYW1lcyBzY2FsZS1pbiB7XFxyXFxuICAwJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCk7XFxyXFxuICAgIG9wYWNpdHk6IDA7XFxyXFxuICB9XFxyXFxuICAxMDAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXHJcXG4gICAgb3BhY2l0eTogMTtcXHJcXG4gIH1cXHJcXG59XFxyXFxuQGtleWZyYW1lcyBzY2FsZS1vdXQge1xcclxcbiAgMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xcclxcbiAgICBvcGFjaXR5OiAxO1xcclxcbiAgfVxcclxcbiAgMTAwJSB7XFxyXFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCk7XFxyXFxuICAgIG9wYWNpdHk6IDA7XFxyXFxuICB9XFxyXFxufVxcclxcbjwvc3R5bGU+XFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXHRcblx0Ly8gZXhwb3J0c1xuXG5cbi8qKiovIH0sXG4vKiAxNDIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcblx0dmFyIF9wb3BvdmVyTWl4aW5zID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNDMpO1xuXHRcblx0dmFyIF9wb3BvdmVyTWl4aW5zMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3BvcG92ZXJNaXhpbnMpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBtaXhpbnM6IFtfcG9wb3Zlck1peGluczIuZGVmYXVsdF0sXG5cdCAgcHJvcHM6IHtcblx0ICAgIHRyaWdnZXI6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnY2xpY2snIH1cblx0ICB9XG5cdH07IC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cbi8qKiovIH0sXG4vKiAxNDMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcblx0dmFyIF9Ob2RlTGlzdCA9IF9fd2VicGFja19yZXF1aXJlX18oMSk7XG5cdFxuXHR2YXIgX05vZGVMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX05vZGVMaXN0KTtcblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgcHJvcHM6IHtcblx0ICAgIGNvbnRlbnQ6IHsgdHlwZTogU3RyaW5nIH0sXG5cdCAgICBlZmZlY3Q6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnZmFkZScgfSxcblx0ICAgIGhlYWRlcjogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiB0cnVlIH0sXG5cdCAgICBwbGFjZW1lbnQ6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAndG9wJyB9LFxuXHQgICAgdGl0bGU6IHsgdHlwZTogU3RyaW5nIH0sXG5cdCAgICB0cmlnZ2VyOiB7IHR5cGU6IFN0cmluZyB9XG5cdCAgfSxcblx0ICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgdG9wOiAwLFxuXHQgICAgICBsZWZ0OiAwLFxuXHQgICAgICBzaG93OiBmYWxzZVxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICBjb21wdXRlZDoge1xuXHQgICAgZXZlbnRzOiBmdW5jdGlvbiBldmVudHMoKSB7XG5cdCAgICAgIHJldHVybiB7IGNvbnRleHRtZW51OiBbJ2NvbnRleHRtZW51J10sIGhvdmVyOiBbJ21vdXNlbGVhdmUnLCAnbW91c2VlbnRlciddLCBmb2N1czogWydibHVyJywgJ2ZvY3VzJ10gfVt0aGlzLnRyaWdnZXJdIHx8IFsnY2xpY2snXTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIGJlZm9yZUVudGVyOiBmdW5jdGlvbiBiZWZvcmVFbnRlcigpIHtcblx0ICAgICAgdmFyIF90aGlzID0gdGhpcztcblx0XG5cdCAgICAgIHRoaXMucG9zaXRpb24oKTtcblx0ICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIF90aGlzLnBvc2l0aW9uKCk7XG5cdCAgICAgIH0sIDMwKTtcblx0ICAgIH0sXG5cdCAgICBwb3NpdGlvbjogZnVuY3Rpb24gcG9zaXRpb24oKSB7XG5cdCAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXHRcblx0ICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBwb3BvdmVyID0gX3RoaXMyLiRyZWZzLnBvcG92ZXI7XG5cdCAgICAgICAgdmFyIHRyaWdnZXIgPSBfdGhpczIuJHJlZnMudHJpZ2dlci5jaGlsZHJlblswXTtcblx0ICAgICAgICBzd2l0Y2ggKF90aGlzMi5wbGFjZW1lbnQpIHtcblx0ICAgICAgICAgIGNhc2UgJ3RvcCc6XG5cdCAgICAgICAgICAgIF90aGlzMi5sZWZ0ID0gdHJpZ2dlci5vZmZzZXRMZWZ0IC0gcG9wb3Zlci5vZmZzZXRXaWR0aCAvIDIgKyB0cmlnZ2VyLm9mZnNldFdpZHRoIC8gMjtcblx0ICAgICAgICAgICAgX3RoaXMyLnRvcCA9IHRyaWdnZXIub2Zmc2V0VG9wIC0gcG9wb3Zlci5vZmZzZXRIZWlnaHQ7XG5cdCAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgY2FzZSAnbGVmdCc6XG5cdCAgICAgICAgICAgIF90aGlzMi5sZWZ0ID0gdHJpZ2dlci5vZmZzZXRMZWZ0IC0gcG9wb3Zlci5vZmZzZXRXaWR0aDtcblx0ICAgICAgICAgICAgX3RoaXMyLnRvcCA9IHRyaWdnZXIub2Zmc2V0VG9wICsgdHJpZ2dlci5vZmZzZXRIZWlnaHQgLyAyIC0gcG9wb3Zlci5vZmZzZXRIZWlnaHQgLyAyO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgIGNhc2UgJ3JpZ2h0Jzpcblx0ICAgICAgICAgICAgX3RoaXMyLmxlZnQgPSB0cmlnZ2VyLm9mZnNldExlZnQgKyB0cmlnZ2VyLm9mZnNldFdpZHRoO1xuXHQgICAgICAgICAgICBfdGhpczIudG9wID0gdHJpZ2dlci5vZmZzZXRUb3AgKyB0cmlnZ2VyLm9mZnNldEhlaWdodCAvIDIgLSBwb3BvdmVyLm9mZnNldEhlaWdodCAvIDI7XG5cdCAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgY2FzZSAnYm90dG9tJzpcblx0ICAgICAgICAgICAgX3RoaXMyLmxlZnQgPSB0cmlnZ2VyLm9mZnNldExlZnQgLSBwb3BvdmVyLm9mZnNldFdpZHRoIC8gMiArIHRyaWdnZXIub2Zmc2V0V2lkdGggLyAyO1xuXHQgICAgICAgICAgICBfdGhpczIudG9wID0gdHJpZ2dlci5vZmZzZXRUb3AgKyB0cmlnZ2VyLm9mZnNldEhlaWdodDtcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICBkZWZhdWx0OlxuXHQgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1dyb25nIHBsYWNlbWVudCBwcm9wJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHBvcG92ZXIuc3R5bGUudG9wID0gX3RoaXMyLnRvcCArICdweCc7XG5cdCAgICAgICAgcG9wb3Zlci5zdHlsZS5sZWZ0ID0gX3RoaXMyLmxlZnQgKyAncHgnO1xuXHQgICAgICB9KTtcblx0ICAgIH0sXG5cdCAgICB0b2dnbGU6IGZ1bmN0aW9uIHRvZ2dsZShlKSB7XG5cdCAgICAgIGlmIChlICYmIHRoaXMudHJpZ2dlciA9PT0gJ2NvbnRleHRtZW51JykgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICB0aGlzLnNob3cgPSAhdGhpcy5zaG93O1xuXHQgICAgICBpZiAodGhpcy5zaG93KSB0aGlzLmJlZm9yZUVudGVyKCk7XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkKCkge1xuXHQgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cdFxuXHQgICAgdmFyIHRyaWdnZXIgPSB0aGlzLiRyZWZzLnRyaWdnZXIuY2hpbGRyZW5bMF07XG5cdCAgICBpZiAoIXRyaWdnZXIpIHJldHVybiBjb25zb2xlLmVycm9yKCdDb3VsZCBub3QgZmluZCB0cmlnZ2VyIHYtZWwgaW4geW91ciBjb21wb25lbnQgdGhhdCB1c2VzIHBvcG92ZXJNaXhpbi4nKTtcblx0XG5cdCAgICBpZiAodGhpcy50cmlnZ2VyID09PSAnZm9jdXMnICYmICF+dHJpZ2dlci50YWJJbmRleCkge1xuXHQgICAgICB0cmlnZ2VyID0gKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkoJ2EsaW5wdXQsc2VsZWN0LHRleHRhcmVhLGJ1dHRvbicsIHRyaWdnZXIpO1xuXHQgICAgICBpZiAoIXRyaWdnZXIubGVuZ3RoKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgICB0aGlzLmV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuXHQgICAgICAoMCwgX05vZGVMaXN0Mi5kZWZhdWx0KSh0cmlnZ2VyKS5vbihldmVudCwgX3RoaXMzLnRvZ2dsZSk7XG5cdCAgICB9KTtcblx0ICB9LFxuXHQgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uIGJlZm9yZURlc3Ryb3koKSB7XG5cdCAgICBpZiAodGhpcy5fdHJpZ2dlcikgKDAsIF9Ob2RlTGlzdDIuZGVmYXVsdCkodGhpcy5fdHJpZ2dlcikub2ZmKCk7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTQ0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICByZWY6IFwidHJpZ2dlclwiXG5cdCAgfSwgW192bS5fdChcImRlZmF1bHRcIiksIF92bS5fdihcIiBcIiksIF92bS5fYygndHJhbnNpdGlvbicsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwibmFtZVwiOiBfdm0uZWZmZWN0XG5cdCAgICB9XG5cdCAgfSwgWyhfdm0uc2hvdykgPyBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHJlZjogXCJwb3BvdmVyXCIsXG5cdCAgICBjbGFzczogWydwb3BvdmVyJywgX3ZtLnBsYWNlbWVudF1cblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJhcnJvd1wiXG5cdCAgfSksIF92bS5fdihcIiBcIiksIChfdm0udGl0bGUpID8gX3ZtLl9jKCdoMycsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcInBvcG92ZXItdGl0bGVcIlxuXHQgIH0sIFtfdm0uX3QoXCJ0aXRsZVwiLCBbX3ZtLl92KF92bS5fcyhfdm0udGl0bGUpKV0pXSwgMikgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJwb3BvdmVyLWNvbnRlbnRcIlxuXHQgIH0sIFtfdm0uX3QoXCJjb250ZW50XCIsIFtfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBkb21Qcm9wczoge1xuXHQgICAgICBcImlubmVySFRNTFwiOiBfdm0uX3MoX3ZtLmNvbnRlbnQpXG5cdCAgICB9XG5cdCAgfSldKV0sIDIpXSkgOiBfdm0uX2UoKV0pXSwgMilcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMjQ2NWJmNTRcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxNDUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTQ2KVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE0Nylcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxQcm9ncmVzc2Jhci52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNjhhYTMzNzVcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTY4YWEzMzc1XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gUHJvZ3Jlc3NiYXIudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTQ2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDY1KTtcblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgYW5pbWF0ZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGxhYmVsOiB7IGRlZmF1bHQ6IGZhbHNlIH0sXG5cdCAgICBub3c6IHsgcmVxdWlyZWQ6IHRydWUgfSxcblx0ICAgIHN0cmlwZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIHR5cGU6IHsgdHlwZTogU3RyaW5nIH1cblx0ICB9LFxuXHQgIGNvbXB1dGVkOiB7XG5cdCAgICBsYWJlbEJvb2w6IGZ1bmN0aW9uIGxhYmVsQm9vbCgpIHtcblx0ICAgICAgcmV0dXJuIF91dGlscy5jb2VyY2UuYm9vbGVhbih0aGlzLmxhYmVsKTtcblx0ICAgIH0sXG5cdCAgICBub3dOdW06IGZ1bmN0aW9uIG5vd051bSgpIHtcblx0ICAgICAgcmV0dXJuIF91dGlscy5jb2VyY2UubnVtYmVyKHRoaXMubm93KTtcblx0ICAgIH1cblx0ICB9XG5cdH07IC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cbi8qKiovIH0sXG4vKiAxNDcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYygnZGl2Jywge1xuXHQgICAgY2xhc3M6IFsncHJvZ3Jlc3MtYmFyJywgJ3Byb2dyZXNzLWJhci0nICsgX3ZtLnR5cGUsIHtcblx0ICAgICAgYWN0aXZlOiBfdm0uYW5pbWF0ZWQsXG5cdCAgICAgICdwcm9ncmVzcy1iYXItc3RyaXBlZCc6IF92bS5zdHJpcGVkXG5cdCAgICB9XSxcblx0ICAgIHN0eWxlOiAoe1xuXHQgICAgICB3aWR0aDogX3ZtLm5vd051bSArICclJ1xuXHQgICAgfSksXG5cdCAgICBkb21Qcm9wczoge1xuXHQgICAgICBcInRleHRDb250ZW50XCI6IF92bS5fcyhfdm0ubGFiZWxCb29sID8gX3ZtLm5vd051bSArICclJyA6IG51bGwpXG5cdCAgICB9XG5cdCAgfSlcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtNjhhYTMzNzVcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxNDggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc3R5bGVzICovXG5cdF9fd2VicGFja19yZXF1aXJlX18oMTQ5KVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTUxKVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE1Milcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxSYWRpby52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNzRjZmQ5MmNcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTc0Y2ZkOTJjXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gUmFkaW8udnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTQ5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNTApO1xuXHRpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcblx0Ly8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxuXHR2YXIgdXBkYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OSkoY29udGVudCwge30pO1xuXHRpZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcblx0Ly8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuXHRpZihmYWxzZSkge1xuXHRcdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTc0Y2ZkOTJjIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9SYWRpby52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTc0Y2ZkOTJjIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9SYWRpby52dWVcIik7XG5cdFx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xuXHR9XG5cbi8qKiovIH0sXG4vKiAxNTAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oNzgpKCk7XG5cdC8vIGltcG9ydHNcblx0XG5cdFxuXHQvLyBtb2R1bGVcblx0ZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuLnJhZGlvIHsgcG9zaXRpb246IHJlbGF0aXZlO1xcbn1cXG4ucmFkaW8gPiBsYWJlbCA+IGlucHV0IHtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIG1hcmdpbjogMDtcXHJcXG4gIHBhZGRpbmc6IDA7XFxyXFxuICBvcGFjaXR5OiAwO1xcclxcbiAgei1pbmRleDogLTE7XFxyXFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbn1cXG4ucmFkaW8gPiBsYWJlbCA+IC5pY29uIHtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHRvcDogLjE1cmVtO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIGRpc3BsYXk6IGJsb2NrO1xcclxcbiAgd2lkdGg6IDEuNHJlbTtcXHJcXG4gIGhlaWdodDogMS40cmVtO1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XFxyXFxuICBib3JkZXItcmFkaXVzOiAuN3JlbTtcXHJcXG4gIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XFxyXFxuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXIgY2VudGVyO1xcclxcbiAgYmFja2dyb3VuZC1zaXplOiA1MCUgNTAlO1xcbn1cXG4ucmFkaW86bm90KC5hY3RpdmUpID4gbGFiZWwgPiAuaWNvbiB7XFxyXFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZGRkO1xcclxcbiAgYm9yZGVyOiAxcHggc29saWQgI2JiYjtcXG59XFxuLnJhZGlvID4gbGFiZWwgPiBpbnB1dDpmb2N1cyB+IC5pY29uIHtcXHJcXG4gIG91dGxpbmU6IDA7XFxyXFxuICBib3JkZXI6IDFweCBzb2xpZCAjNjZhZmU5O1xcclxcbiAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggMXB4IHJnYmEoMCwwLDAsLjA3NSksMCAwIDhweCByZ2JhKDEwMiwxNzUsMjMzLC42KTtcXG59XFxuLnJhZGlvLmFjdGl2ZSA+IGxhYmVsID4gLmljb24ge1xcclxcbiAgYmFja2dyb3VuZC1zaXplOiAxcmVtIDFyZW07XFxyXFxuICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpZFhSbUxUZ2lQejROQ2p4emRtY2dkbVZ5YzJsdmJqMGlNUzR4SWlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpUGp4amFYSmpiR1VnWTNnOUlqVWlJR041UFNJMUlpQnlQU0kwSWlCbWFXeHNQU0lqWm1abUlpOCtQQzl6ZG1jKyk7XFxufVxcbi5yYWRpby5hY3RpdmUgLmJ0bi1kZWZhdWx0IHsgZmlsdGVyOiBicmlnaHRuZXNzKDc1JSk7XFxufVxcbi5yYWRpby5kaXNhYmxlZCA+IGxhYmVsID4gLmljb24sXFxyXFxuLnJhZGlvLnJlYWRvbmx5ID4gbGFiZWwgPiAuaWNvbixcXHJcXG4uYnRuLnJlYWRvbmx5IHtcXHJcXG4gIGZpbHRlcjogYWxwaGEob3BhY2l0eT02NSk7XFxyXFxuICBib3gtc2hhZG93OiBub25lO1xcclxcbiAgb3BhY2l0eTogLjY1O1xcbn1cXG5sYWJlbC5idG4gPiBpbnB1dFt0eXBlPXJhZGlvXSB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICBjbGlwOiByZWN0KDAsMCwwLDApO1xcclxcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvUmFkaW8udnVlPzExNjI0YzQ4XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUE4R0EsU0FBQSxtQkFBQTtDQUFBO0FBQ0E7RUFDQSxtQkFBQTtFQUNBLFVBQUE7RUFDQSxXQUFBO0VBQ0EsV0FBQTtFQUNBLFlBQUE7RUFDQSx1QkFBQTtDQUNBO0FBQ0E7RUFDQSxtQkFBQTtFQUNBLFlBQUE7RUFDQSxRQUFBO0VBQ0EsZUFBQTtFQUNBLGNBQUE7RUFDQSxlQUFBO0VBQ0EsbUJBQUE7RUFDQSxrQkFBQTtFQUNBLHFCQUFBO0VBQ0EsNkJBQUE7RUFDQSxtQ0FBQTtFQUNBLHlCQUFBO0NBQ0E7QUFDQTtFQUNBLHVCQUFBO0VBQ0EsdUJBQUE7Q0FDQTtBQUNBO0VBQ0EsV0FBQTtFQUNBLDBCQUFBO0VBQ0EsMEVBQUE7Q0FDQTtBQUNBO0VBQ0EsMkJBQUE7RUFDQSw4T0FBQTtDQUNBO0FBQ0EsNkJBQUEsd0JBQUE7Q0FBQTtBQUVBOzs7RUFHQSwwQkFBQTtFQUNBLGlCQUFBO0VBQ0EsYUFBQTtDQUNBO0FBQ0E7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VBQ0EscUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiUmFkaW8udnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxkaXYgOmlzPVxcXCJidXR0b25TdHlsZT8nbGFiZWwnOidkaXYnXFxcIiBAY2xpY2sucHJldmVudD1cXFwidG9nZ2xlXFxcIlxcclxcbiAgICA6Y2xhc3M9XFxcIlsoYnV0dG9uU3R5bGU/J2J0biBidG4tJyt0eXBlQ29sb3I6J3JhZGlvICcrdHlwZUNvbG9yKSx7YWN0aXZlOmFjdGl2ZSxkaXNhYmxlZDpkaXNhYmxlZCxyZWFkb25seTpyZWFkb25seX1dXFxcIlxcclxcbiAgPlxcclxcbiAgICA8dGVtcGxhdGUgdi1pZj1cXFwiYnV0dG9uU3R5bGVcXFwiPlxcclxcbiAgICAgIDxpbnB1dCB0eXBlPVxcXCJyYWRpb1xcXCIgYXV0b2NvbXBsZXRlPVxcXCJvZmZcXFwiIHJlZj1cXFwiaW5wdXRcXFwiXFxyXFxuICAgICAgICB2LXNob3c9XFxcIiFyZWFkb25seVxcXCJcXHJcXG4gICAgICAgIHYtbW9kZWw9XFxcImNoZWNrXFxcIlxcclxcbiAgICAgICAgOnZhbHVlPVxcXCJzZWxlY3RlZFZhbHVlXFxcIlxcclxcbiAgICAgICAgOm5hbWU9XFxcIm5hbWVcXFwiXFxyXFxuICAgICAgICA6cmVhZG9ubHk9XFxcInJlYWRvbmx5XFxcIlxcclxcbiAgICAgICAgOmRpc2FibGVkPVxcXCJkaXNhYmxlZFxcXCJcXHJcXG4gICAgICAvPlxcclxcbiAgICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgPC90ZW1wbGF0ZT5cXHJcXG4gICAgPGxhYmVsIHYtZWxzZSBjbGFzcz1cXFwib3BlblxcXCI+XFxyXFxuICAgICAgPGlucHV0IHR5cGU9XFxcInJhZGlvXFxcIiBhdXRvY29tcGxldGU9XFxcIm9mZlxcXCIgcmVmPVxcXCJpbnB1dFxcXCJcXHJcXG4gICAgICAgIHYtbW9kZWw9XFxcImNoZWNrXFxcIlxcclxcbiAgICAgICAgOnZhbHVlPVxcXCJzZWxlY3RlZFZhbHVlXFxcIlxcclxcbiAgICAgICAgOm5hbWU9XFxcIm5hbWVcXFwiXFxyXFxuICAgICAgICA6cmVhZG9ubHk9XFxcInJlYWRvbmx5XFxcIlxcclxcbiAgICAgICAgOmRpc2FibGVkPVxcXCJkaXNhYmxlZFxcXCJcXHJcXG4gICAgICAvPlxcclxcbiAgICAgIDxzcGFuIGNsYXNzPVxcXCJpY29uIGRyb3Bkb3duLXRvZ2dsZVxcXCIgOmNsYXNzPVxcXCJbYWN0aXZlPydidG4tJyt0eXBlQ29sb3I6Jycse2JnOnR5cGVDb2xvcj09PSdkZWZhdWx0J31dXFxcIj48L3NwYW4+XFxyXFxuICAgICAgPHNwYW4gdi1pZj1cXFwiYWN0aXZlJiZ0eXBlQ29sb3I9PT0nZGVmYXVsdCdcXFwiIGNsYXNzPVxcXCJpY29uXFxcIj48L3NwYW4+XFxyXFxuICAgICAgPHNsb3Q+PC9zbG90PlxcclxcbiAgICA8L2xhYmVsPlxcclxcbiAgPC9kaXY+XFxyXFxuPC90ZW1wbGF0ZT5cXHJcXG5cXHJcXG48c2NyaXB0PlxcclxcbmV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gIHByb3BzOiB7XFxyXFxuICAgIGJ1dHRvbjoge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlfSxcXHJcXG4gICAgZGlzYWJsZWQ6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIG5hbWU6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICByZWFkb25seToge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlfSxcXHJcXG4gICAgc2VsZWN0ZWRWYWx1ZToge2RlZmF1bHQ6IHRydWV9LFxcclxcbiAgICB0eXBlOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgdmFsdWU6IHtkZWZhdWx0OiBmYWxzZX1cXHJcXG4gIH0sXFxyXFxuICBkYXRhICgpIHtcXHJcXG4gICAgcmV0dXJuIHtcXHJcXG4gICAgICBjaGVjazogdGhpcy52YWx1ZVxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgY29tcHV0ZWQ6IHtcXHJcXG4gICAgYWN0aXZlICgpIHsgcmV0dXJuIHRoaXMuY2hlY2sgPT09IHRoaXMuc2VsZWN0ZWRWYWx1ZSB9LFxcclxcbiAgICBpbkdyb3VwICgpIHsgcmV0dXJuIHRoaXMuJHBhcmVudCAmJiB0aGlzLiRwYXJlbnQuYnRuR3JvdXAgJiYgIXRoaXMuJHBhcmVudC5fY2hlY2tib3hHcm91cCB9LFxcclxcbiAgICBwYXJlbnRWYWx1ZSAoKSB7IHJldHVybiB0aGlzLiRwYXJlbnQudmFsIH0sXFxyXFxuICAgIGJ1dHRvblN0eWxlICgpIHsgcmV0dXJuIHRoaXMuYnV0dG9uIHx8ICh0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50LmJ0bkdyb3VwICYmIHRoaXMuJHBhcmVudC5idXR0b25zKSB9LFxcclxcbiAgICB0eXBlQ29sb3IgKCkgeyByZXR1cm4gKHRoaXMudHlwZSB8fCAodGhpcy4kcGFyZW50ICYmIHRoaXMuJHBhcmVudC50eXBlKSkgfHwgJ2RlZmF1bHQnIH1cXHJcXG4gIH0sXFxyXFxuICB3YXRjaDoge1xcclxcbiAgICBjaGVjayAodmFsKSB7XFxyXFxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRWYWx1ZSA9PT0gdmFsKSB7XFxyXFxuICAgICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbClcXHJcXG4gICAgICAgIHRoaXMuJGVtaXQoJ2NoZWNrZWQnLCB0cnVlKVxcclxcbiAgICAgICAgdGhpcy51cGRhdGVQYXJlbnQoKVxcclxcbiAgICAgIH1cXHJcXG4gICAgfSxcXHJcXG4gICAgcGFyZW50VmFsdWUgKHZhbCkge1xcclxcbiAgICAgIHRoaXMudXBkYXRlRnJvbVBhcmVudCgpXFxyXFxuICAgIH0sXFxyXFxuICAgIHZhbHVlICh2YWwpIHtcXHJcXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZFZhbHVlID09IHZhbCkge1xcclxcbiAgICAgICAgdGhpcy5jaGVjayA9IHZhbFxcclxcbiAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICB0aGlzLmNoZWNrID0gZmFsc2VcXHJcXG4gICAgICB9XFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBjcmVhdGVkICgpIHtcXHJcXG4gICAgaWYgKHRoaXMuaW5Hcm91cCkge1xcclxcbiAgICAgIHZhciBwYXJlbnQgPSB0aGlzLiRwYXJlbnRcXHJcXG4gICAgICBwYXJlbnQuX3JhZGlvR3JvdXAgPSB0cnVlXFxyXFxuICAgICAgdGhpcy51cGRhdGVGcm9tUGFyZW50KClcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgdXBkYXRlRnJvbVBhcmVudCgpIHtcXHJcXG4gICAgICBpZiAodGhpcy5pbkdyb3VwKSB7XFxyXFxuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZFZhbHVlID09IHRoaXMuJHBhcmVudC52YWwpIHtcXHJcXG4gICAgICAgICAgdGhpcy5jaGVjayA9IHRoaXMuc2VsZWN0ZWRWYWx1ZVxcclxcbiAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgdGhpcy5jaGVjayA9IGZhbHNlXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICB1cGRhdGVQYXJlbnQoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMuaW5Hcm91cCkge1xcclxcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRWYWx1ZSA9PT0gdGhpcy5jaGVjaykge1xcclxcbiAgICAgICAgICB0aGlzLiRwYXJlbnQudmFsID0gdGhpcy5zZWxlY3RlZFZhbHVlXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICBmb2N1cyAoKSB7XFxyXFxuICAgICAgdGhpcy4kcmVmcy5pbnB1dC5mb2N1cygpXFxyXFxuICAgIH0sXFxyXFxuICAgIHRvZ2dsZSAoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMuZGlzYWJsZWQpIHsgcmV0dXJuIH1cXHJcXG4gICAgICB0aGlzLmZvY3VzKClcXHJcXG4gICAgICBpZiAodGhpcy5yZWFkb25seSkgeyByZXR1cm4gfVxcclxcbiAgICAgIHRoaXMuY2hlY2sgPSB0aGlzLnNlbGVjdGVkVmFsdWVcXHJcXG4gICAgfVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGUgc2NvcGU+XFxyXFxuLnJhZGlvIHsgcG9zaXRpb246IHJlbGF0aXZlOyB9XFxyXFxuLnJhZGlvID4gbGFiZWwgPiBpbnB1dCB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICBtYXJnaW46IDA7XFxyXFxuICBwYWRkaW5nOiAwO1xcclxcbiAgb3BhY2l0eTogMDtcXHJcXG4gIHotaW5kZXg6IC0xO1xcclxcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXHJcXG59XFxyXFxuLnJhZGlvID4gbGFiZWwgPiAuaWNvbiB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IC4xNXJlbTtcXHJcXG4gIGxlZnQ6IDA7XFxyXFxuICBkaXNwbGF5OiBibG9jaztcXHJcXG4gIHdpZHRoOiAxLjRyZW07XFxyXFxuICBoZWlnaHQ6IDEuNHJlbTtcXHJcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG4gIHVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgYm9yZGVyLXJhZGl1czogLjdyZW07XFxyXFxuICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xcclxcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2VudGVyIGNlbnRlcjtcXHJcXG4gIGJhY2tncm91bmQtc2l6ZTogNTAlIDUwJTtcXHJcXG59XFxyXFxuLnJhZGlvOm5vdCguYWN0aXZlKSA+IGxhYmVsID4gLmljb24ge1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogI2RkZDtcXHJcXG4gIGJvcmRlcjogMXB4IHNvbGlkICNiYmI7XFxyXFxufVxcclxcbi5yYWRpbyA+IGxhYmVsID4gaW5wdXQ6Zm9jdXMgfiAuaWNvbiB7XFxyXFxuICBvdXRsaW5lOiAwO1xcclxcbiAgYm9yZGVyOiAxcHggc29saWQgIzY2YWZlOTtcXHJcXG4gIGJveC1zaGFkb3c6IGluc2V0IDAgMXB4IDFweCByZ2JhKDAsMCwwLC4wNzUpLDAgMCA4cHggcmdiYSgxMDIsMTc1LDIzMywuNik7XFxyXFxufVxcclxcbi5yYWRpby5hY3RpdmUgPiBsYWJlbCA+IC5pY29uIHtcXHJcXG4gIGJhY2tncm91bmQtc2l6ZTogMXJlbSAxcmVtO1xcclxcbiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCbGJtTnZaR2x1WnowaWRYUm1MVGdpUHo0TkNqeHpkbWNnZG1WeWMybHZiajBpTVM0eElpQjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaVBqeGphWEpqYkdVZ1kzZzlJalVpSUdONVBTSTFJaUJ5UFNJMElpQm1hV3hzUFNJalptWm1JaTgrUEM5emRtYyspO1xcclxcbn1cXHJcXG4ucmFkaW8uYWN0aXZlIC5idG4tZGVmYXVsdCB7IGZpbHRlcjogYnJpZ2h0bmVzcyg3NSUpOyB9XFxyXFxuXFxyXFxuLnJhZGlvLmRpc2FibGVkID4gbGFiZWwgPiAuaWNvbixcXHJcXG4ucmFkaW8ucmVhZG9ubHkgPiBsYWJlbCA+IC5pY29uLFxcclxcbi5idG4ucmVhZG9ubHkge1xcclxcbiAgZmlsdGVyOiBhbHBoYShvcGFjaXR5PTY1KTtcXHJcXG4gIGJveC1zaGFkb3c6IG5vbmU7XFxyXFxuICBvcGFjaXR5OiAuNjU7XFxyXFxufVxcclxcbmxhYmVsLmJ0biA+IGlucHV0W3R5cGU9cmFkaW9dIHtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIGNsaXA6IHJlY3QoMCwwLDAsMCk7XFxyXFxuICBwb2ludGVyLWV2ZW50czogbm9uZTtcXHJcXG59XFxyXFxuPC9zdHlsZT5cXHJcXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cdFxuXHQvLyBleHBvcnRzXG5cblxuLyoqKi8gfSxcbi8qIDE1MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdC8vXG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgcHJvcHM6IHtcblx0ICAgIGJ1dHRvbjogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgZGlzYWJsZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIG5hbWU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICByZWFkb25seTogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgc2VsZWN0ZWRWYWx1ZTogeyBkZWZhdWx0OiB0cnVlIH0sXG5cdCAgICB0eXBlOiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgdmFsdWU6IHsgZGVmYXVsdDogZmFsc2UgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIGNoZWNrOiB0aGlzLnZhbHVlXG5cdCAgICB9O1xuXHQgIH0sXG5cdFxuXHQgIGNvbXB1dGVkOiB7XG5cdCAgICBhY3RpdmU6IGZ1bmN0aW9uIGFjdGl2ZSgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuY2hlY2sgPT09IHRoaXMuc2VsZWN0ZWRWYWx1ZTtcblx0ICAgIH0sXG5cdCAgICBpbkdyb3VwOiBmdW5jdGlvbiBpbkdyb3VwKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy4kcGFyZW50ICYmIHRoaXMuJHBhcmVudC5idG5Hcm91cCAmJiAhdGhpcy4kcGFyZW50Ll9jaGVja2JveEdyb3VwO1xuXHQgICAgfSxcblx0ICAgIHBhcmVudFZhbHVlOiBmdW5jdGlvbiBwYXJlbnRWYWx1ZSgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuJHBhcmVudC52YWw7XG5cdCAgICB9LFxuXHQgICAgYnV0dG9uU3R5bGU6IGZ1bmN0aW9uIGJ1dHRvblN0eWxlKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5idXR0b24gfHwgdGhpcy4kcGFyZW50ICYmIHRoaXMuJHBhcmVudC5idG5Hcm91cCAmJiB0aGlzLiRwYXJlbnQuYnV0dG9ucztcblx0ICAgIH0sXG5cdCAgICB0eXBlQ29sb3I6IGZ1bmN0aW9uIHR5cGVDb2xvcigpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudHlwZSB8fCB0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50LnR5cGUgfHwgJ2RlZmF1bHQnO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgd2F0Y2g6IHtcblx0ICAgIGNoZWNrOiBmdW5jdGlvbiBjaGVjayh2YWwpIHtcblx0ICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRWYWx1ZSA9PT0gdmFsKSB7XG5cdCAgICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCB2YWwpO1xuXHQgICAgICAgIHRoaXMuJGVtaXQoJ2NoZWNrZWQnLCB0cnVlKTtcblx0ICAgICAgICB0aGlzLnVwZGF0ZVBhcmVudCgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcGFyZW50VmFsdWU6IGZ1bmN0aW9uIHBhcmVudFZhbHVlKHZhbCkge1xuXHQgICAgICB0aGlzLnVwZGF0ZUZyb21QYXJlbnQoKTtcblx0ICAgIH0sXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUodmFsKSB7XG5cdCAgICAgIGlmICh0aGlzLnNlbGVjdGVkVmFsdWUgPT0gdmFsKSB7XG5cdCAgICAgICAgdGhpcy5jaGVjayA9IHZhbDtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLmNoZWNrID0gZmFsc2U7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LFxuXHQgIGNyZWF0ZWQ6IGZ1bmN0aW9uIGNyZWF0ZWQoKSB7XG5cdCAgICBpZiAodGhpcy5pbkdyb3VwKSB7XG5cdCAgICAgIHZhciBwYXJlbnQgPSB0aGlzLiRwYXJlbnQ7XG5cdCAgICAgIHBhcmVudC5fcmFkaW9Hcm91cCA9IHRydWU7XG5cdCAgICAgIHRoaXMudXBkYXRlRnJvbVBhcmVudCgpO1xuXHQgICAgfVxuXHQgIH0sXG5cdFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIHVwZGF0ZUZyb21QYXJlbnQ6IGZ1bmN0aW9uIHVwZGF0ZUZyb21QYXJlbnQoKSB7XG5cdCAgICAgIGlmICh0aGlzLmluR3JvdXApIHtcblx0ICAgICAgICBpZiAodGhpcy5zZWxlY3RlZFZhbHVlID09IHRoaXMuJHBhcmVudC52YWwpIHtcblx0ICAgICAgICAgIHRoaXMuY2hlY2sgPSB0aGlzLnNlbGVjdGVkVmFsdWU7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRoaXMuY2hlY2sgPSBmYWxzZTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICB1cGRhdGVQYXJlbnQ6IGZ1bmN0aW9uIHVwZGF0ZVBhcmVudCgpIHtcblx0ICAgICAgaWYgKHRoaXMuaW5Hcm91cCkge1xuXHQgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkVmFsdWUgPT09IHRoaXMuY2hlY2spIHtcblx0ICAgICAgICAgIHRoaXMuJHBhcmVudC52YWwgPSB0aGlzLnNlbGVjdGVkVmFsdWU7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZm9jdXM6IGZ1bmN0aW9uIGZvY3VzKCkge1xuXHQgICAgICB0aGlzLiRyZWZzLmlucHV0LmZvY3VzKCk7XG5cdCAgICB9LFxuXHQgICAgdG9nZ2xlOiBmdW5jdGlvbiB0b2dnbGUoKSB7XG5cdCAgICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICAgIHRoaXMuZm9jdXMoKTtcblx0ICAgICAgaWYgKHRoaXMucmVhZG9ubHkpIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICAgIH1cblx0ICAgICAgdGhpcy5jaGVjayA9IHRoaXMuc2VsZWN0ZWRWYWx1ZTtcblx0ICAgIH1cblx0ICB9XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxNTIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYyhfdm0uYnV0dG9uU3R5bGUgPyAnbGFiZWwnIDogJ2RpdicsIHtcblx0ICAgIHRhZzogXCJkaXZcIixcblx0ICAgIGNsYXNzOiBbKF92bS5idXR0b25TdHlsZSA/ICdidG4gYnRuLScgKyBfdm0udHlwZUNvbG9yIDogJ3JhZGlvICcgKyBfdm0udHlwZUNvbG9yKSwge1xuXHQgICAgICBhY3RpdmU6IF92bS5hY3RpdmUsXG5cdCAgICAgIGRpc2FibGVkOiBfdm0uZGlzYWJsZWQsXG5cdCAgICAgIHJlYWRvbmx5OiBfdm0ucmVhZG9ubHlcblx0ICAgIH1dLFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICBfdm0udG9nZ2xlKCRldmVudClcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0sIFsoX3ZtLmJ1dHRvblN0eWxlKSA/IFtfdm0uX2MoJ2lucHV0Jywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJzaG93XCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1zaG93XCIsXG5cdCAgICAgIHZhbHVlOiAoIV92bS5yZWFkb25seSksXG5cdCAgICAgIGV4cHJlc3Npb246IFwiIXJlYWRvbmx5XCJcblx0ICAgIH0sIHtcblx0ICAgICAgbmFtZTogXCJtb2RlbFwiLFxuXHQgICAgICByYXdOYW1lOiBcInYtbW9kZWxcIixcblx0ICAgICAgdmFsdWU6IChfdm0uY2hlY2spLFxuXHQgICAgICBleHByZXNzaW9uOiBcImNoZWNrXCJcblx0ICAgIH1dLFxuXHQgICAgcmVmOiBcImlucHV0XCIsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcInR5cGVcIjogXCJyYWRpb1wiLFxuXHQgICAgICBcImF1dG9jb21wbGV0ZVwiOiBcIm9mZlwiLFxuXHQgICAgICBcIm5hbWVcIjogX3ZtLm5hbWUsXG5cdCAgICAgIFwicmVhZG9ubHlcIjogX3ZtLnJlYWRvbmx5LFxuXHQgICAgICBcImRpc2FibGVkXCI6IF92bS5kaXNhYmxlZFxuXHQgICAgfSxcblx0ICAgIGRvbVByb3BzOiB7XG5cdCAgICAgIFwidmFsdWVcIjogX3ZtLnNlbGVjdGVkVmFsdWUsXG5cdCAgICAgIFwiY2hlY2tlZFwiOiBfdm0uX3EoX3ZtLmNoZWNrLCBfdm0uc2VsZWN0ZWRWYWx1ZSlcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIF92bS5jaGVjayA9IF92bS5zZWxlY3RlZFZhbHVlXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl90KFwiZGVmYXVsdFwiKV0gOiBfdm0uX2MoJ2xhYmVsJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwib3BlblwiXG5cdCAgfSwgW192bS5fYygnaW5wdXQnLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcIm1vZGVsXCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1tb2RlbFwiLFxuXHQgICAgICB2YWx1ZTogKF92bS5jaGVjayksXG5cdCAgICAgIGV4cHJlc3Npb246IFwiY2hlY2tcIlxuXHQgICAgfV0sXG5cdCAgICByZWY6IFwiaW5wdXRcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcInJhZGlvXCIsXG5cdCAgICAgIFwiYXV0b2NvbXBsZXRlXCI6IFwib2ZmXCIsXG5cdCAgICAgIFwibmFtZVwiOiBfdm0ubmFtZSxcblx0ICAgICAgXCJyZWFkb25seVwiOiBfdm0ucmVhZG9ubHksXG5cdCAgICAgIFwiZGlzYWJsZWRcIjogX3ZtLmRpc2FibGVkXG5cdCAgICB9LFxuXHQgICAgZG9tUHJvcHM6IHtcblx0ICAgICAgXCJ2YWx1ZVwiOiBfdm0uc2VsZWN0ZWRWYWx1ZSxcblx0ICAgICAgXCJjaGVja2VkXCI6IF92bS5fcShfdm0uY2hlY2ssIF92bS5zZWxlY3RlZFZhbHVlKVxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLmNoZWNrID0gX3ZtLnNlbGVjdGVkVmFsdWVcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJpY29uIGRyb3Bkb3duLXRvZ2dsZVwiLFxuXHQgICAgY2xhc3M6IFtfdm0uYWN0aXZlID8gJ2J0bi0nICsgX3ZtLnR5cGVDb2xvciA6ICcnLCB7XG5cdCAgICAgIGJnOiBfdm0udHlwZUNvbG9yID09PSAnZGVmYXVsdCdcblx0ICAgIH1dXG5cdCAgfSksIF92bS5fdihcIiBcIiksIChfdm0uYWN0aXZlICYmIF92bS50eXBlQ29sb3IgPT09ICdkZWZhdWx0JykgPyBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJpY29uXCJcblx0ICB9KSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCBfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMildLCAyKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi03NGNmZDkyY1wiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDE1MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzdHlsZXMgKi9cblx0X193ZWJwYWNrX3JlcXVpcmVfXygxNTQpXG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNTYpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTU3KVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXFNlbGVjdC52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdF9fdnVlX29wdGlvbnNfXy5fc2NvcGVJZCA9IFwiZGF0YS12LWU1MTRkYmM2XCJcblx0XG5cdC8qIGhvdCByZWxvYWQgKi9cblx0aWYgKGZhbHNlKSB7KGZ1bmN0aW9uICgpIHtcblx0ICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuXHQgIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuXHQgIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi1lNTE0ZGJjNlwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfSBlbHNlIHtcblx0ICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtZTUxNGRiYzZcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH1cblx0fSkoKX1cblx0aWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBTZWxlY3QudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTU0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNTUpO1xuXHRpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcblx0Ly8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxuXHR2YXIgdXBkYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OSkoY29udGVudCwge30pO1xuXHRpZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcblx0Ly8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuXHRpZihmYWxzZSkge1xuXHRcdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWU1MTRkYmM2JnNjb3BlZD10cnVlIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9TZWxlY3QudnVlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi1lNTE0ZGJjNiZzY29wZWQ9dHJ1ZSEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vU2VsZWN0LnZ1ZVwiKTtcblx0XHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDE1NSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0ZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OCkoKTtcblx0Ly8gaW1wb3J0c1xuXHRcblx0XG5cdC8vIG1vZHVsZVxuXHRleHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4uZm9ybS1jb250cm9sLmRyb3Bkb3duLXRvZ2dsZVtkYXRhLXYtZTUxNGRiYzZde1xcclxcbiAgaGVpZ2h0OiBhdXRvO1xcclxcbiAgcGFkZGluZy1yaWdodDogMjRweDtcXG59XFxuLmZvcm0tY29udHJvbC5kcm9wZG93bi10b2dnbGVbZGF0YS12LWU1MTRkYmM2XTphZnRlcntcXHJcXG4gIGNvbnRlbnQ6ICcgJztcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHJpZ2h0OiAxM3B4O1xcclxcbiAgdG9wOiA1MCU7XFxyXFxuICBtYXJnaW46IC0xcHggMCAwO1xcclxcbiAgYm9yZGVyLXRvcDogNHB4IGRhc2hlZDtcXHJcXG4gIGJvcmRlci10b3A6IDRweCBzb2xpZCBcXFxcOTtcXHJcXG4gIGJvcmRlci1yaWdodDogNHB4IHNvbGlkIHRyYW5zcGFyZW50O1xcclxcbiAgYm9yZGVyLWxlZnQ6IDRweCBzb2xpZCB0cmFuc3BhcmVudDtcXG59XFxuLmJzLXNlYXJjaGJveFtkYXRhLXYtZTUxNGRiYzZdIHtcXHJcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gIG1hcmdpbjogNHB4IDhweDtcXG59XFxuLmJzLXNlYXJjaGJveCAuY2xvc2VbZGF0YS12LWU1MTRkYmM2XSB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IDA7XFxyXFxuICByaWdodDogMDtcXHJcXG4gIHotaW5kZXg6IDI7XFxyXFxuICBkaXNwbGF5OiBibG9jaztcXHJcXG4gIHdpZHRoOiAzNHB4O1xcclxcbiAgaGVpZ2h0OiAzNHB4O1xcclxcbiAgbGluZS1oZWlnaHQ6IDM0cHg7XFxyXFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxufVxcbi5icy1zZWFyY2hib3ggaW5wdXRbZGF0YS12LWU1MTRkYmM2XTpmb2N1cyxcXHJcXG4uZm9ybS1jb250cm9sLmRyb3Bkb3duLXRvZ2dsZVtkYXRhLXYtZTUxNGRiYzZdOmZvY3VzIHtcXHJcXG4gIG91dGxpbmU6IDA7XFxyXFxuICBib3JkZXItY29sb3I6ICM2NmFmZTkgIWltcG9ydGFudDtcXHJcXG4gIGJveC1zaGFkb3c6IGluc2V0IDAgMXB4IDFweCByZ2JhKDAsMCwwLC4wNzUpLDAgMCA4cHggcmdiYSgxMDIsMTc1LDIzMywuNik7XFxufVxcbi5zZWNyZXRbZGF0YS12LWU1MTRkYmM2XSB7XFxyXFxuICBib3JkZXI6IDA7XFxyXFxuICBjbGlwOiByZWN0KDAgMCAwIDApO1xcclxcbiAgaGVpZ2h0OiAxcHg7XFxyXFxuICBtYXJnaW46IC0xcHg7XFxyXFxuICBvdmVyZmxvdzogaGlkZGVuO1xcclxcbiAgcGFkZGluZzogMDtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHdpZHRoOiAxcHg7XFxufVxcbi5mb3JtLWNvbnRyb2wuZHJvcGRvd24tdG9nZ2xlPi5jbG9zZVtkYXRhLXYtZTUxNGRiYzZdIHsgbWFyZ2luLWxlZnQ6IDVweDtcXG59XFxuLm5vdGlmeS5vdXRbZGF0YS12LWU1MTRkYmM2XSB7IHBvc2l0aW9uOiByZWxhdGl2ZTtcXG59XFxuLm5vdGlmeS5pbltkYXRhLXYtZTUxNGRiYzZdLFxcclxcbi5ub3RpZnk+ZGl2W2RhdGEtdi1lNTE0ZGJjNl0ge1xcclxcbiAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgd2lkdGg6IDk2JTtcXHJcXG4gIG1hcmdpbjogMCAyJTtcXHJcXG4gIG1pbi1oZWlnaHQ6IDI2cHg7XFxyXFxuICBwYWRkaW5nOiAzcHggNXB4O1xcclxcbiAgYmFja2dyb3VuZDogI2Y1ZjVmNTtcXHJcXG4gIGJvcmRlcjogMXB4IHNvbGlkICNlM2UzZTM7XFxyXFxuICBib3gtc2hhZG93OiBpbnNldCAwIDFweCAxcHggcmdiYSgwLDAsMCwuMDUpO1xcclxcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxufVxcbi5ub3RpZnk+ZGl2W2RhdGEtdi1lNTE0ZGJjNl0ge1xcclxcbiAgdG9wOiA1cHg7XFxyXFxuICB6LWluZGV4OiAxO1xcbn1cXG4ubm90aWZ5LmluW2RhdGEtdi1lNTE0ZGJjNl0ge1xcclxcbiAgb3BhY2l0eTogLjk7XFxyXFxuICBib3R0b206IDVweDtcXG59XFxuLmJ0bi1ncm91cC1qdXN0aWZpZWQgLmRyb3Bkb3duLXRvZ2dsZT5zcGFuW2RhdGEtdi1lNTE0ZGJjNl06bm90KC5jbG9zZSkge1xcclxcbiAgd2lkdGg6IGNhbGMoMTAwJSAtIDE4cHgpO1xcclxcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcclxcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcXHJcXG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxyXFxuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcXHJcXG4gIG1hcmdpbi1ib3R0b206IC00cHg7XFxufVxcbi5idG4tZ3JvdXAtanVzdGlmaWVkIC5kcm9wZG93bi1tZW51W2RhdGEtdi1lNTE0ZGJjNl0geyB3aWR0aDogMTAwJTtcXG59XFxyXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9TZWxlY3QudnVlPzY4Mjk4YzEzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUF1UUE7RUFDQSxhQUFBO0VBQ0Esb0JBQUE7Q0FDQTtBQUNBO0VBQ0EsYUFBQTtFQUNBLG1CQUFBO0VBQ0EsWUFBQTtFQUNBLFNBQUE7RUFDQSxpQkFBQTtFQUNBLHVCQUFBO0VBQ0EseUJBQUE7RUFDQSxvQ0FBQTtFQUNBLG1DQUFBO0NBQ0E7QUFDQTtFQUNBLG1CQUFBO0VBQ0EsZ0JBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxPQUFBO0VBQ0EsU0FBQTtFQUNBLFdBQUE7RUFDQSxlQUFBO0VBQ0EsWUFBQTtFQUNBLGFBQUE7RUFDQSxrQkFBQTtFQUNBLG1CQUFBO0NBQ0E7QUFDQTs7RUFFQSxXQUFBO0VBQ0EsaUNBQUE7RUFDQSwwRUFBQTtDQUNBO0FBQ0E7RUFDQSxVQUFBO0VBQ0Esb0JBQUE7RUFDQSxZQUFBO0VBQ0EsYUFBQTtFQUNBLGlCQUFBO0VBQ0EsV0FBQTtFQUNBLG1CQUFBO0VBQ0EsV0FBQTtDQUNBO0FBQ0Esd0RBQUEsaUJBQUE7Q0FBQTtBQUNBLCtCQUFBLG1CQUFBO0NBQUE7QUFDQTs7RUFFQSxtQkFBQTtFQUNBLFdBQUE7RUFDQSxhQUFBO0VBQ0EsaUJBQUE7RUFDQSxpQkFBQTtFQUNBLG9CQUFBO0VBQ0EsMEJBQUE7RUFDQSw0Q0FBQTtFQUNBLHFCQUFBO0NBQ0E7QUFDQTtFQUNBLFNBQUE7RUFDQSxXQUFBO0NBQ0E7QUFDQTtFQUNBLFlBQUE7RUFDQSxZQUFBO0NBQ0E7QUFDQTtFQUNBLHlCQUFBO0VBQ0Esc0JBQUE7RUFDQSxpQkFBQTtFQUNBLG9CQUFBO0VBQ0Esd0JBQUE7RUFDQSxvQkFBQTtDQUNBO0FBQ0EsdURBQUEsWUFBQTtDQUFBXCIsXCJmaWxlXCI6XCJTZWxlY3QudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxkaXYgcmVmPVxcXCJzZWxlY3RcXFwiIDpjbGFzcz1cXFwiY2xhc3Nlc1xcXCIgdi1jbGljay1vdXRzaWRlPVxcXCJjbG9zZVxcXCI+XFxyXFxuICAgIDxkaXYgcmVmPVxcXCJidG5cXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2wgZHJvcGRvd24tdG9nZ2xlXFxcIiB0YWJpbmRleD1cXFwiMVxcXCIgOmRpc2FibGVkPVxcXCJkaXNhYmxlZCB8fCAhaGFzUGFyZW50XFxcIiA6cmVhZG9ubHk9XFxcInJlYWRvbmx5XFxcIlxcclxcbiAgICAgIEBibHVyPVxcXCJjYW5TZWFyY2ggPyBudWxsIDogY2xvc2UoKVxcXCJcXHJcXG4gICAgICBAY2xpY2s9XFxcInRvZ2dsZSgpXFxcIlxcclxcbiAgICAgIEBrZXlkb3duLmVzYy5zdG9wLnByZXZlbnQ9XFxcImNsb3NlXFxcIlxcclxcbiAgICAgIEBrZXlkb3duLnNwYWNlLnN0b3AucHJldmVudD1cXFwidG9nZ2xlXFxcIlxcclxcbiAgICAgIEBrZXlkb3duLmVudGVyLnN0b3AucHJldmVudD1cXFwidG9nZ2xlXFxcIlxcclxcbiAgICA+XFxyXFxuICAgICAgPHNwYW4gY2xhc3M9XFxcImJ0bi1jb250ZW50XFxcIiB2LWh0bWw9XFxcImxvYWRpbmcgPyB0ZXh0LmxvYWRpbmcgOiBzaG93UGxhY2Vob2xkZXIgfHwgKG11bHRpcGxlICYmIHNob3dDb3VudCA/IHNlbGVjdGVkVGV4dCA6IHNlbGVjdGVkKVxcXCI+PC9zcGFuPlxcclxcbiAgICAgIDxzcGFuIHYtaWY9XFxcImNsZWFyQnV0dG9uJiZ2YWx1ZXMubGVuZ3RoXFxcIiBjbGFzcz1cXFwiY2xvc2VcXFwiIEBjbGljaz1cXFwiY2xlYXIoKVxcXCI+JnRpbWVzOzwvc3Bhbj5cXHJcXG4gICAgPC9kaXY+XFxyXFxuICAgIDxzZWxlY3QgcmVmPVxcXCJzZWxcXFwiIHYtbW9kZWw9XFxcInZhbFxcXCIgOm5hbWU9XFxcIm5hbWVcXFwiIGNsYXNzPVxcXCJzZWNyZXRcXFwiIDptdWx0aXBsZT1cXFwibXVsdGlwbGVcXFwiIDpyZXF1aXJlZD1cXFwicmVxdWlyZWRcXFwiIDpyZWFkb25seT1cXFwicmVhZG9ubHlcXFwiIDpkaXNhYmxlZD1cXFwiZGlzYWJsZWRcXFwiPlxcclxcbiAgICAgIDxvcHRpb24gdi1pZj1cXFwicmVxdWlyZWRcXFwiIHZhbHVlPVxcXCJcXFwiPjwvb3B0aW9uPlxcclxcbiAgICAgIDxvcHRpb24gdi1mb3I9XFxcIm9wdGlvbiBpbiBsaXN0XFxcIiA6dmFsdWU9XFxcIm9wdGlvbltvcHRpb25zVmFsdWVdXFxcIj57eyBvcHRpb25bb3B0aW9uc0xhYmVsXSB9fTwvb3B0aW9uPlxcclxcbiAgICA8L3NlbGVjdD5cXHJcXG4gICAgPHVsIGNsYXNzPVxcXCJkcm9wZG93bi1tZW51XFxcIj5cXHJcXG4gICAgICA8dGVtcGxhdGUgdi1pZj1cXFwibGlzdC5sZW5ndGhcXFwiPlxcclxcbiAgICAgICAgPGxpIHYtaWY9XFxcImNhblNlYXJjaFxcXCIgY2xhc3M9XFxcImJzLXNlYXJjaGJveFxcXCI+XFxyXFxuICAgICAgICAgIDxpbnB1dCB0eXBlPVxcXCJ0ZXh0XFxcIiA6cGxhY2Vob2xkZXI9XFxcInNlYXJjaFRleHR8fHRleHQuc2VhcmNoXFxcIiBjbGFzcz1cXFwiZm9ybS1jb250cm9sXFxcIiBhdXRvY29tcGxldGU9XFxcIm9mZlxcXCIgcmVmPVxcXCJzZWFyY2hcXFwiXFxyXFxuICAgICAgICAgICAgdi1tb2RlbD1cXFwic2VhcmNoVmFsdWVcXFwiXFxyXFxuICAgICAgICAgICAgQGtleXVwLmVzYz1cXFwiY2xvc2VcXFwiXFxyXFxuICAgICAgICAgIC8+XFxyXFxuICAgICAgICAgIDxzcGFuIHYtc2hvdz1cXFwic2VhcmNoVmFsdWVcXFwiIGNsYXNzPVxcXCJjbG9zZVxcXCIgQGNsaWNrPVxcXCJjbGVhclNlYXJjaFxcXCI+JnRpbWVzOzwvc3Bhbj5cXHJcXG4gICAgICAgIDwvbGk+XFxyXFxuICAgICAgICA8bGkgdi1pZj1cXFwicmVxdWlyZWQmJiFjbGVhckJ1dHRvblxcXCI+PGEgQG1vdXNlZG93bi5wcmV2ZW50PVxcXCJjbGVhcigpICYmIGNsb3NlKClcXFwiPnt7IHBsYWNlaG9sZGVyIHx8IHRleHQubm90U2VsZWN0ZWQgfX08L2E+PC9saT5cXHJcXG4gICAgICAgIDxsaSB2LWZvcj1cXFwib3B0aW9uIGluIGZpbHRlcmVkT3B0aW9uc1xcXCIgOmlkPVxcXCJvcHRpb25bb3B0aW9uc1ZhbHVlXVxcXCI+XFxyXFxuICAgICAgICAgIDxhIEBtb3VzZWRvd24ucHJldmVudD1cXFwic2VsZWN0KG9wdGlvbltvcHRpb25zVmFsdWVdKVxcXCI+XFxyXFxuICAgICAgICAgICAgPHNwYW4gdi1odG1sPVxcXCJvcHRpb25bb3B0aW9uc0xhYmVsXVxcXCI+PC9zcGFuPlxcclxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJnbHlwaGljb24gZ2x5cGhpY29uLW9rIGNoZWNrLW1hcmtcXFwiIHYtc2hvdz1cXFwiaXNTZWxlY3RlZChvcHRpb25bb3B0aW9uc1ZhbHVlXSlcXFwiPjwvc3Bhbj5cXHJcXG4gICAgICAgICAgPC9hPlxcclxcbiAgICAgICAgPC9saT5cXHJcXG4gICAgICA8L3RlbXBsYXRlPlxcclxcbiAgICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgICA8dHJhbnNpdGlvbiB2LWlmPVxcXCJub3RpZnkgJiYgIWNsb3NlT25TZWxlY3RcXFwiIG5hbWU9XFxcImZhZGVpblxcXCI+PGRpdiBjbGFzcz1cXFwibm90aWZ5IGluXFxcIj57e2xpbWl0VGV4dH19PC9kaXY+PC90cmFuc2l0aW9uPlxcclxcbiAgICA8L3VsPlxcclxcbiAgICA8dHJhbnNpdGlvbiB2LWlmPVxcXCJub3RpZnkgJiYgY2xvc2VPblNlbGVjdFxcXCIgbmFtZT1cXFwiZmFkZWluXFxcIj48ZGl2IGNsYXNzPVxcXCJub3RpZnkgb3V0XFxcIj48ZGl2Pnt7bGltaXRUZXh0fX08L2Rpdj48L2Rpdj48L3RyYW5zaXRpb24+XFxyXFxuICAgIDwhLS0gPHByZT5PcHRpb25zOiB7e2xpc3R9fTwvcHJlPiAtLT5cXHJcXG4gIDwvZGl2PlxcclxcbjwvdGVtcGxhdGU+XFxyXFxuXFxyXFxuPHNjcmlwdD5cXHJcXG5pbXBvcnQge3RyYW5zbGF0aW9uc30gZnJvbSAnLi91dGlscy91dGlscy5qcydcXHJcXG5pbXBvcnQgQ2xpY2tPdXRzaWRlIGZyb20gJy4vZGlyZWN0aXZlcy9DbGlja091dHNpZGUuanMnXFxyXFxuXFxyXFxudmFyIHRpbWVvdXQgPSB7fVxcclxcbmV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gIGRpcmVjdGl2ZXM6IHtcXHJcXG4gICAgQ2xpY2tPdXRzaWRlXFxyXFxuICB9LFxcclxcbiAgcHJvcHM6IHtcXHJcXG4gICAgY2xlYXJCdXR0b246IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIGNsb3NlT25TZWxlY3Q6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIGRpc2FibGVkOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBsYW5nOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBuYXZpZ2F0b3IubGFuZ3VhZ2V9LFxcclxcbiAgICBsaW1pdDoge3R5cGU6IE51bWJlciwgZGVmYXVsdDogMTAyNH0sXFxyXFxuICAgIG1pblNlYXJjaDoge3R5cGU6IE51bWJlciwgZGVmYXVsdDogMH0sXFxyXFxuICAgIG11bHRpcGxlOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBuYW1lOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsfSxcXHJcXG4gICAgb3B0aW9uczoge3R5cGU6IEFycmF5LCBkZWZhdWx0ICgpIHsgcmV0dXJuIFtdIH19LFxcclxcbiAgICBvcHRpb25zTGFiZWw6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICdsYWJlbCd9LFxcclxcbiAgICBvcHRpb25zVmFsdWU6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICd2YWx1ZSd9LFxcclxcbiAgICBwYXJlbnQ6IHtkZWZhdWx0OiB0cnVlfSxcXHJcXG4gICAgcGxhY2Vob2xkZXI6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICByZWFkb25seToge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICByZXF1aXJlZDoge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICBzZWFyY2g6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIHNlYXJjaFRleHQ6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICBjb3VudFRleHQ6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGx9LFxcclxcbiAgICBzaG93Q291bnQ6IHt0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZX0sXFxyXFxuICAgIHVybDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIHZhbHVlOiBudWxsXFxyXFxuICB9LFxcclxcbiAgZGF0YSAoKSB7XFxyXFxuICAgIHJldHVybiB7XFxyXFxuICAgICAgbGlzdDogW10sXFxyXFxuICAgICAgbG9hZGluZzogbnVsbCxcXHJcXG4gICAgICBzZWFyY2hWYWx1ZTogbnVsbCxcXHJcXG4gICAgICBzaG93OiBmYWxzZSxcXHJcXG4gICAgICBub3RpZnk6IGZhbHNlLFxcclxcbiAgICAgIHZhbDogbnVsbCxcXHJcXG4gICAgICB2YWxpZDogbnVsbFxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgY29tcHV0ZWQ6IHtcXHJcXG4gICAgY2FuU2VhcmNoICgpIHsgcmV0dXJuIHRoaXMubWluU2VhcmNoID8gdGhpcy5saXN0Lmxlbmd0aCA+PSB0aGlzLm1pblNlYXJjaCA6IHRoaXMuc2VhcmNoIH0sXFxyXFxuICAgIGNsYXNzZXMgKCkgeyByZXR1cm4gW3tvcGVuOiB0aGlzLnNob3csIGRpc2FibGVkOiB0aGlzLmRpc2FibGVkfSwgdGhpcy5jbGFzcywgdGhpcy5pc0xpID8gJ2Ryb3Bkb3duJyA6IHRoaXMuaW5JbnB1dCA/ICdpbnB1dC1ncm91cC1idG4nIDogJ2J0bi1ncm91cCddIH0sXFxyXFxuICAgIGZpbHRlcmVkT3B0aW9ucyAoKSB7XFxyXFxuICAgICAgdmFyIHNlYXJjaCA9ICh0aGlzLnNlYXJjaFZhbHVlIHx8ICcnKS50b0xvd2VyQ2FzZSgpXFxyXFxuICAgICAgcmV0dXJuICFzZWFyY2ggPyB0aGlzLmxpc3QgOiB0aGlzLmxpc3QuZmlsdGVyKGVsID0+IHtcXHJcXG4gICAgICAgIHJldHVybiB+ZWxbdGhpcy5vcHRpb25zTGFiZWxdLnRvTG93ZXJDYXNlKCkuc2VhcmNoKHNlYXJjaClcXHJcXG4gICAgICB9KVxcclxcbiAgICB9LFxcclxcbiAgICBoYXNQYXJlbnQgKCkgeyByZXR1cm4gdGhpcy5wYXJlbnQgaW5zdGFuY2VvZiBBcnJheSA/IHRoaXMucGFyZW50Lmxlbmd0aCA6IHRoaXMucGFyZW50IH0sXFxyXFxuICAgIGluSW5wdXQgKCkgeyByZXR1cm4gdGhpcy4kcGFyZW50Ll9pbnB1dCB9LFxcclxcbiAgICBpc0xpICgpIHsgcmV0dXJuIHRoaXMuJHBhcmVudC5fbmF2YmFyIHx8IHRoaXMuJHBhcmVudC5tZW51IHx8IHRoaXMuJHBhcmVudC5fdGFic2V0IH0sXFxyXFxuICAgIGxpbWl0VGV4dCAoKSB7IHJldHVybiB0aGlzLnRleHQubGltaXQucmVwbGFjZSgne3tsaW1pdH19JywgdGhpcy5saW1pdCkgfSxcXHJcXG4gICAgc2VsZWN0ZWQgKCkge1xcclxcbiAgICAgIGlmICh0aGlzLmxpc3QubGVuZ3RoID09PSAwKSB7IHJldHVybiAnJyB9XFxyXFxuICAgICAgdmFyIHNlbCA9IHRoaXMudmFsdWVzLm1hcCh2YWwgPT4gKHRoaXMubGlzdC5maW5kKG8gPT4gb1t0aGlzLm9wdGlvbnNWYWx1ZV0gPT09IHZhbCkgfHwge30pW3RoaXMub3B0aW9uc0xhYmVsXSkuZmlsdGVyKHZhbCA9PiB2YWwgIT09IHVuZGVmaW5lZClcXHJcXG4gICAgICB0aGlzLiRlbWl0KCdzZWxlY3RlZCcsIHNlbClcXHJcXG4gICAgICByZXR1cm4gc2VsLmpvaW4oJywgJylcXHJcXG4gICAgfSxcXHJcXG4gICAgc2VsZWN0ZWRUZXh0ICgpIHsgcmV0dXJuIHRoaXMuY291bnRUZXh0IHx8IHRoaXMudGV4dC5zZWxlY3RlZC5yZXBsYWNlKCd7e2NvdW50fX0nLCB0aGlzLnZhbHVlcy5sZW5ndGgpIH0sXFxyXFxuICAgIHNob3dQbGFjZWhvbGRlciAoKSB7IHJldHVybiAodGhpcy52YWx1ZXMubGVuZ3RoID09PSAwIHx8ICF0aGlzLmhhc1BhcmVudCkgPyAodGhpcy5wbGFjZWhvbGRlciB8fCB0aGlzLnRleHQubm90U2VsZWN0ZWQpIDogbnVsbCB9LFxcclxcbiAgICB0ZXh0ICgpIHsgcmV0dXJuIHRyYW5zbGF0aW9ucyh0aGlzLmxhbmcpIH0sXFxyXFxuICAgIHZhbHVlcyAoKSB7IHJldHVybiB0aGlzLnZhbCBpbnN0YW5jZW9mIEFycmF5ID8gdGhpcy52YWwgOiB+W251bGwsIHVuZGVmaW5lZF0uaW5kZXhPZih0aGlzLnZhbCkgPyBbXSA6IFt0aGlzLnZhbF0gfSxcXHJcXG4gICAgdmFsT3B0aW9ucyAoKSB7IHJldHVybiB0aGlzLmxpc3QubWFwKGVsID0+IGVsW3RoaXMub3B0aW9uc1ZhbHVlXSkgfVxcclxcbiAgfSxcXHJcXG4gIHdhdGNoOiB7XFxyXFxuICAgIG9wdGlvbnMgKG9wdGlvbnMpIHtcXHJcXG4gICAgICBpZiAob3B0aW9ucyBpbnN0YW5jZW9mIEFycmF5KSB0aGlzLnNldE9wdGlvbnMob3B0aW9ucylcXHJcXG4gICAgfSxcXHJcXG4gICAgc2hvdyAodmFsKSB7XFxyXFxuICAgICAgaWYgKHZhbCkge1xcclxcbiAgICAgICAgdGhpcy4kcmVmcy5zZWFyY2ggPyB0aGlzLiRyZWZzLnNlYXJjaC5mb2N1cygpIDogdGhpcy4kcmVmcy5idG4uZm9jdXMoKVxcclxcbiAgICAgICAgLy8gb25CbHVyKHRoaXMuJHJlZnMuc2VsZWN0LCBlID0+IHsgdGhpcy5zaG93ID0gZmFsc2UgfSlcXHJcXG4gICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgLy8gb2ZmQmx1cih0aGlzLiRyZWZzLnNlbGVjdClcXHJcXG4gICAgICB9XFxyXFxuICAgIH0sXFxyXFxuICAgIHVybCAoKSB7XFxyXFxuICAgICAgdGhpcy51cmxDaGFuZ2VkKClcXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsaWQgKHZhbCwgb2xkKSB7XFxyXFxuICAgICAgdGhpcy4kZW1pdCgnaXN2YWxpZCcsIHZhbClcXHJcXG4gICAgICB0aGlzLiRlbWl0KCF2YWwgPyAnaW52YWxpZCcgOiAndmFsaWQnKVxcclxcbiAgICAgIGlmICh2YWwgIT09IG9sZCAmJiB0aGlzLl9wYXJlbnQpIHRoaXMuX3BhcmVudC52YWxpZGF0ZSgpXFxyXFxuICAgIH0sXFxyXFxuICAgIHZhbHVlICh2YWwsIG9sZCkge1xcclxcbiAgICAgIGlmICh2YWwgIT09IG9sZCkgeyB0aGlzLnZhbCA9IHZhbCB9XFxyXFxuICAgIH0sXFxyXFxuICAgIHZhbCAodmFsLCBvbGQpIHtcXHJcXG4gICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHsgdGhpcy52YWwgPSB2YWwgPSBudWxsIH1cXHJcXG4gICAgICBpZiAodmFsICE9PSBvbGQpIHtcXHJcXG4gICAgICAgIHRoaXMuJGVtaXQoJ2NoYW5nZScsIHZhbClcXHJcXG4gICAgICAgIHRoaXMuJGVtaXQoJ2lucHV0JywgdmFsKVxcclxcbiAgICAgIH1cXHJcXG4gICAgICBpZiAodmFsIGluc3RhbmNlb2YgQXJyYXkgJiYgdmFsLmxlbmd0aCA+IHRoaXMubGltaXQpIHtcXHJcXG4gICAgICAgIHRoaXMudmFsID0gdmFsLnNsaWNlKDAsIHRoaXMubGltaXQpXFxyXFxuICAgICAgICB0aGlzLm5vdGlmeSA9IHRydWVcXHJcXG4gICAgICAgIGlmICh0aW1lb3V0LmxpbWl0KSBjbGVhclRpbWVvdXQodGltZW91dC5saW1pdClcXHJcXG4gICAgICAgIHRpbWVvdXQubGltaXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcXHJcXG4gICAgICAgICAgdGltZW91dC5saW1pdCA9IGZhbHNlXFxyXFxuICAgICAgICAgIHRoaXMubm90aWZ5ID0gZmFsc2VcXHJcXG4gICAgICAgIH0sIDE1MDApXFxyXFxuICAgICAgfVxcclxcbiAgICAgIHRoaXMudmFsaWQgPSB0aGlzLnZhbGlkYXRlKClcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgY2xvc2UgKCkge1xcclxcbiAgICAgIHRoaXMuc2hvdyA9IGZhbHNlXFxyXFxuICAgIH0sXFxyXFxuICAgIGNoZWNrRGF0YSAoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcXHJcXG4gICAgICAgIGlmICh0aGlzLmxpbWl0IDwgMSkgeyB0aGlzLmxpbWl0ID0gMSB9XFxyXFxuICAgICAgICBpZiAoISh0aGlzLnZhbCBpbnN0YW5jZW9mIEFycmF5KSkge1xcclxcbiAgICAgICAgICB0aGlzLnZhbCA9ICh0aGlzLnZhbCA9PT0gbnVsbCB8fCB0aGlzLnZhbCA9PT0gdW5kZWZpbmVkKSA/IFtdIDogW3RoaXMudmFsXVxcclxcbiAgICAgICAgfVxcclxcbiAgICAgICAgdmFyIHZhbHVlcyA9IHRoaXMudmFsT3B0aW9uc1xcclxcbiAgICAgICAgdGhpcy52YWwgPSB0aGlzLnZhbC5maWx0ZXIoZWwgPT4gfnZhbHVlcy5pbmRleE9mKGVsKSlcXHJcXG4gICAgICAgIGlmICh0aGlzLnZhbHVlcy5sZW5ndGggPiB0aGlzLmxpbWl0KSB7XFxyXFxuICAgICAgICAgIHRoaXMudmFsID0gdGhpcy52YWwuc2xpY2UoMCwgdGhpcy5saW1pdClcXHJcXG4gICAgICAgIH1cXHJcXG4gICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgaWYgKCF+dGhpcy52YWxPcHRpb25zLmluZGV4T2YodGhpcy52YWwpKSB7IHRoaXMudmFsID0gbnVsbCB9XFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICBjbGVhciAoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5yZWFkb25seSkgeyByZXR1cm4gfVxcclxcbiAgICAgIHRoaXMudmFsID0gdGhpcy52YWwgaW5zdGFuY2VvZiBBcnJheSA/IFtdIDogbnVsbFxcclxcbiAgICAgIHRoaXMudG9nZ2xlKClcXHJcXG4gICAgfSxcXHJcXG4gICAgY2xlYXJTZWFyY2ggKCkge1xcclxcbiAgICAgIHRoaXMuc2VhcmNoVmFsdWUgPSAnJ1xcclxcbiAgICAgIHRoaXMuJHJlZnMuc2VhcmNoLmZvY3VzKClcXHJcXG4gICAgfSxcXHJcXG4gICAgaXNTZWxlY3RlZCAodikge1xcclxcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlcy5pbmRleE9mKHYpID4gLTFcXHJcXG4gICAgfSxcXHJcXG4gICAgc2VsZWN0ICh2KSB7XFxyXFxuICAgICAgaWYgKHRoaXMudmFsIGluc3RhbmNlb2YgQXJyYXkpIHtcXHJcXG4gICAgICAgIHZhciBuZXdWYWwgPSB0aGlzLnZhbC5zbGljZSgwKVxcclxcbiAgICAgICAgaWYgKH5uZXdWYWwuaW5kZXhPZih2KSkge1xcclxcbiAgICAgICAgICBuZXdWYWwuc3BsaWNlKG5ld1ZhbC5pbmRleE9mKHYpLCAxKVxcclxcbiAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgbmV3VmFsLnB1c2godilcXHJcXG4gICAgICAgIH1cXHJcXG4gICAgICAgIHRoaXMudmFsID0gbmV3VmFsXFxyXFxuICAgICAgICBpZiAodGhpcy5jbG9zZU9uU2VsZWN0KSB7XFxyXFxuICAgICAgICAgIHRoaXMudG9nZ2xlKClcXHJcXG4gICAgICAgIH1cXHJcXG4gICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgdGhpcy52YWwgPSB2XFxyXFxuICAgICAgICB0aGlzLnRvZ2dsZSgpXFxyXFxuICAgICAgfVxcclxcbiAgICB9LFxcclxcbiAgICBzZXRPcHRpb25zIChvcHRpb25zKSB7XFxyXFxuICAgICAgdGhpcy5saXN0ID0gb3B0aW9ucy5tYXAoZWwgPT4ge1xcclxcbiAgICAgICAgaWYgKGVsIGluc3RhbmNlb2YgT2JqZWN0KSB7IHJldHVybiBlbCB9XFxyXFxuICAgICAgICBsZXQgb2JqID0ge31cXHJcXG4gICAgICAgIG9ialt0aGlzLm9wdGlvbnNMYWJlbF0gPSBlbFxcclxcbiAgICAgICAgb2JqW3RoaXMub3B0aW9uc1ZhbHVlXSA9IGVsXFxyXFxuICAgICAgICByZXR1cm4gb2JqXFxyXFxuICAgICAgfSlcXHJcXG4gICAgICB0aGlzLiRlbWl0KCdvcHRpb25zJywgdGhpcy5saXN0KVxcclxcbiAgICB9LFxcclxcbiAgICB0b2dnbGUgKCkge1xcclxcbiAgICAgIGlmICh0aGlzLmRpc2FibGVkICYmICF0aGlzLnNob3cpIHJldHVybjtcXHJcXG4gICAgICB0aGlzLnNob3cgPSAhdGhpcy5zaG93XFxyXFxuICAgICAgaWYgKCF0aGlzLnNob3cpIHRoaXMuJHJlZnMuYnRuLmZvY3VzKClcXHJcXG4gICAgfSxcXHJcXG4gICAgdXJsQ2hhbmdlZCAoKSB7XFxyXFxuICAgICAgaWYgKCF0aGlzLnVybCB8fCAhdGhpcy4kaHR0cCkgeyByZXR1cm4gfVxcclxcbiAgICAgIHRoaXMubG9hZGluZyA9IHRydWVcXHJcXG4gICAgICB0aGlzLiRodHRwLmdldCh0aGlzLnVybCkudGhlbihyZXNwb25zZSA9PiB7XFxyXFxuICAgICAgICB2YXIgZGF0YSA9IHJlc3BvbnNlLmRhdGEgaW5zdGFuY2VvZiBBcnJheSA/IHJlc3BvbnNlLmRhdGEgOiBbXVxcclxcbiAgICAgICAgdHJ5IHsgZGF0YSA9IEpTT04ucGFyc2UoZGF0YSkgfSBjYXRjaCAoZSkge31cXHJcXG4gICAgICAgIHRoaXMuc2V0T3B0aW9ucyhkYXRhKVxcclxcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2VcXHJcXG4gICAgICAgIHRoaXMuY2hlY2tEYXRhKClcXHJcXG4gICAgICB9LCByZXNwb25zZSA9PiB7XFxyXFxuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZVxcclxcbiAgICAgIH0pXFxyXFxuICAgIH0sXFxyXFxuICAgIHZhbGlkYXRlICgpIHtcXHJcXG4gICAgICByZXR1cm4gIXRoaXMucmVxdWlyZWQgPyB0cnVlIDogdGhpcy52YWwgaW5zdGFuY2VvZiBBcnJheSA/IHRoaXMudmFsLmxlbmd0aCA+IDAgOiB0aGlzLnZhbCAhPT0gbnVsbFxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgY3JlYXRlZCAoKSB7XFxyXFxuICAgIHRoaXMuc2V0T3B0aW9ucyh0aGlzLm9wdGlvbnMpXFxyXFxuICAgIHRoaXMudmFsID0gdGhpcy52YWx1ZVxcclxcbiAgICB0aGlzLl9zZWxlY3QgPSB0cnVlXFxyXFxuICAgIGlmICh0aGlzLnZhbCA9PT0gdW5kZWZpbmVkIHx8ICF0aGlzLnBhcmVudCkgeyB0aGlzLnZhbCA9IG51bGwgfVxcclxcbiAgICBpZiAoIXRoaXMubXVsdGlwbGUgJiYgdGhpcy52YWwgaW5zdGFuY2VvZiBBcnJheSkge1xcclxcbiAgICAgIHRoaXMudmFsID0gdGhpcy52YWxbMF1cXHJcXG4gICAgfVxcclxcbiAgICB0aGlzLmNoZWNrRGF0YSgpXFxyXFxuICAgIGlmICh0aGlzLnVybCkgdGhpcy51cmxDaGFuZ2VkKClcXHJcXG4gICAgbGV0IHBhcmVudCA9IHRoaXMuJHBhcmVudFxcclxcbiAgICB3aGlsZSAocGFyZW50ICYmICFwYXJlbnQuX2Zvcm1WYWxpZGF0b3IpIHsgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQgfVxcclxcbiAgICBpZiAocGFyZW50ICYmIHBhcmVudC5fZm9ybVZhbGlkYXRvcikge1xcclxcbiAgICAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKHRoaXMpXFxyXFxuICAgICAgdGhpcy5fcGFyZW50ID0gcGFyZW50XFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBtb3VudGVkICgpIHtcXHJcXG4gICAgaWYgKHRoaXMuX3BhcmVudCkgdGhpcy5fcGFyZW50LmNoaWxkcmVuLnB1c2godGhpcylcXHJcXG4gICAgdGhpcy5zZXRPcHRpb25zKHRoaXMub3B0aW9ucylcXHJcXG4gICAgdGhpcy52YWwgPSB0aGlzLnZhbHVlXFxyXFxuICAgIHRoaXMuY2hlY2tEYXRhKClcXHJcXG4gIH0sXFxyXFxuICBiZWZvcmVEZXN0cm95ICgpIHtcXHJcXG4gICAgaWYgKHRoaXMuX3BhcmVudCkge1xcclxcbiAgICAgIHZhciBpbmRleCA9IHRoaXMuX3BhcmVudC5jaGlsZHJlbi5pbmRleE9mKHRoaXMpXFxyXFxuICAgICAgdGhpcy5fcGFyZW50LmNoaWxkcmVuLnNwbGljZShpbmRleCwgMSlcXHJcXG4gICAgfVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGUgc2NvcGVkPlxcclxcbi5mb3JtLWNvbnRyb2wuZHJvcGRvd24tdG9nZ2xle1xcclxcbiAgaGVpZ2h0OiBhdXRvO1xcclxcbiAgcGFkZGluZy1yaWdodDogMjRweDtcXHJcXG59XFxyXFxuLmZvcm0tY29udHJvbC5kcm9wZG93bi10b2dnbGU6YWZ0ZXJ7XFxyXFxuICBjb250ZW50OiAnICc7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICByaWdodDogMTNweDtcXHJcXG4gIHRvcDogNTAlO1xcclxcbiAgbWFyZ2luOiAtMXB4IDAgMDtcXHJcXG4gIGJvcmRlci10b3A6IDRweCBkYXNoZWQ7XFxyXFxuICBib3JkZXItdG9wOiA0cHggc29saWQgXFxcXDk7XFxyXFxuICBib3JkZXItcmlnaHQ6IDRweCBzb2xpZCB0cmFuc3BhcmVudDtcXHJcXG4gIGJvcmRlci1sZWZ0OiA0cHggc29saWQgdHJhbnNwYXJlbnQ7XFxyXFxufVxcclxcbi5icy1zZWFyY2hib3gge1xcclxcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcclxcbiAgbWFyZ2luOiA0cHggOHB4O1xcclxcbn1cXHJcXG4uYnMtc2VhcmNoYm94IC5jbG9zZSB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IDA7XFxyXFxuICByaWdodDogMDtcXHJcXG4gIHotaW5kZXg6IDI7XFxyXFxuICBkaXNwbGF5OiBibG9jaztcXHJcXG4gIHdpZHRoOiAzNHB4O1xcclxcbiAgaGVpZ2h0OiAzNHB4O1xcclxcbiAgbGluZS1oZWlnaHQ6IDM0cHg7XFxyXFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcbi5icy1zZWFyY2hib3ggaW5wdXQ6Zm9jdXMsXFxyXFxuLmZvcm0tY29udHJvbC5kcm9wZG93bi10b2dnbGU6Zm9jdXMge1xcclxcbiAgb3V0bGluZTogMDtcXHJcXG4gIGJvcmRlci1jb2xvcjogIzY2YWZlOSAhaW1wb3J0YW50O1xcclxcbiAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggMXB4IHJnYmEoMCwwLDAsLjA3NSksMCAwIDhweCByZ2JhKDEwMiwxNzUsMjMzLC42KTtcXHJcXG59XFxyXFxuLnNlY3JldCB7XFxyXFxuICBib3JkZXI6IDA7XFxyXFxuICBjbGlwOiByZWN0KDAgMCAwIDApO1xcclxcbiAgaGVpZ2h0OiAxcHg7XFxyXFxuICBtYXJnaW46IC0xcHg7XFxyXFxuICBvdmVyZmxvdzogaGlkZGVuO1xcclxcbiAgcGFkZGluZzogMDtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHdpZHRoOiAxcHg7XFxyXFxufVxcclxcbi5mb3JtLWNvbnRyb2wuZHJvcGRvd24tdG9nZ2xlPi5jbG9zZSB7IG1hcmdpbi1sZWZ0OiA1cHg7fVxcclxcbi5ub3RpZnkub3V0IHsgcG9zaXRpb246IHJlbGF0aXZlOyB9XFxyXFxuLm5vdGlmeS5pbixcXHJcXG4ubm90aWZ5PmRpdiB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB3aWR0aDogOTYlO1xcclxcbiAgbWFyZ2luOiAwIDIlO1xcclxcbiAgbWluLWhlaWdodDogMjZweDtcXHJcXG4gIHBhZGRpbmc6IDNweCA1cHg7XFxyXFxuICBiYWNrZ3JvdW5kOiAjZjVmNWY1O1xcclxcbiAgYm9yZGVyOiAxcHggc29saWQgI2UzZTNlMztcXHJcXG4gIGJveC1zaGFkb3c6IGluc2V0IDAgMXB4IDFweCByZ2JhKDAsMCwwLC4wNSk7XFxyXFxuICBwb2ludGVyLWV2ZW50czogbm9uZTtcXHJcXG59XFxyXFxuLm5vdGlmeT5kaXYge1xcclxcbiAgdG9wOiA1cHg7XFxyXFxuICB6LWluZGV4OiAxO1xcclxcbn1cXHJcXG4ubm90aWZ5LmluIHtcXHJcXG4gIG9wYWNpdHk6IC45O1xcclxcbiAgYm90dG9tOiA1cHg7XFxyXFxufVxcclxcbi5idG4tZ3JvdXAtanVzdGlmaWVkIC5kcm9wZG93bi10b2dnbGU+c3Bhbjpub3QoLmNsb3NlKSB7XFxyXFxuICB3aWR0aDogY2FsYygxMDAlIC0gMThweCk7XFxyXFxuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuICBvdmVyZmxvdzogaGlkZGVuO1xcclxcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcXHJcXG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xcclxcbiAgbWFyZ2luLWJvdHRvbTogLTRweDtcXHJcXG59XFxyXFxuLmJ0bi1ncm91cC1qdXN0aWZpZWQgLmRyb3Bkb3duLW1lbnUgeyB3aWR0aDogMTAwJTsgfVxcclxcbjwvc3R5bGU+XFxyXFxuXFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXHRcblx0Ly8gZXhwb3J0c1xuXG5cbi8qKiovIH0sXG4vKiAxNTYgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcblx0dmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNjUpO1xuXHRcblx0dmFyIF9DbGlja091dHNpZGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDY2KTtcblx0XG5cdHZhciBfQ2xpY2tPdXRzaWRlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0NsaWNrT3V0c2lkZSk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0XG5cdHZhciB0aW1lb3V0ID0ge307XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBkaXJlY3RpdmVzOiB7XG5cdCAgICBDbGlja091dHNpZGU6IF9DbGlja091dHNpZGUyLmRlZmF1bHRcblx0ICB9LFxuXHQgIHByb3BzOiB7XG5cdCAgICBjbGVhckJ1dHRvbjogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgY2xvc2VPblNlbGVjdDogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgZGlzYWJsZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGxhbmc6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBuYXZpZ2F0b3IubGFuZ3VhZ2UgfSxcblx0ICAgIGxpbWl0OiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogMTAyNCB9LFxuXHQgICAgbWluU2VhcmNoOiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogMCB9LFxuXHQgICAgbXVsdGlwbGU6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIG5hbWU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBvcHRpb25zOiB7IHR5cGU6IEFycmF5LCBkZWZhdWx0OiBmdW5jdGlvbiBfZGVmYXVsdCgpIHtcblx0ICAgICAgICByZXR1cm4gW107XG5cdCAgICAgIH1cblx0ICAgIH0sXG5cdCAgICBvcHRpb25zTGFiZWw6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnbGFiZWwnIH0sXG5cdCAgICBvcHRpb25zVmFsdWU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAndmFsdWUnIH0sXG5cdCAgICBwYXJlbnQ6IHsgZGVmYXVsdDogdHJ1ZSB9LFxuXHQgICAgcGxhY2Vob2xkZXI6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICByZWFkb25seTogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICByZXF1aXJlZDogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBzZWFyY2g6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIHNlYXJjaFRleHQ6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBjb3VudFRleHQ6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBzaG93Q291bnQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIHVybDogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIHZhbHVlOiBudWxsXG5cdCAgfSxcblx0ICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgbGlzdDogW10sXG5cdCAgICAgIGxvYWRpbmc6IG51bGwsXG5cdCAgICAgIHNlYXJjaFZhbHVlOiBudWxsLFxuXHQgICAgICBzaG93OiBmYWxzZSxcblx0ICAgICAgbm90aWZ5OiBmYWxzZSxcblx0ICAgICAgdmFsOiBudWxsLFxuXHQgICAgICB2YWxpZDogbnVsbFxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICBjb21wdXRlZDoge1xuXHQgICAgY2FuU2VhcmNoOiBmdW5jdGlvbiBjYW5TZWFyY2goKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLm1pblNlYXJjaCA/IHRoaXMubGlzdC5sZW5ndGggPj0gdGhpcy5taW5TZWFyY2ggOiB0aGlzLnNlYXJjaDtcblx0ICAgIH0sXG5cdCAgICBjbGFzc2VzOiBmdW5jdGlvbiBjbGFzc2VzKCkge1xuXHQgICAgICByZXR1cm4gW3sgb3BlbjogdGhpcy5zaG93LCBkaXNhYmxlZDogdGhpcy5kaXNhYmxlZCB9LCB0aGlzLmNsYXNzLCB0aGlzLmlzTGkgPyAnZHJvcGRvd24nIDogdGhpcy5pbklucHV0ID8gJ2lucHV0LWdyb3VwLWJ0bicgOiAnYnRuLWdyb3VwJ107XG5cdCAgICB9LFxuXHQgICAgZmlsdGVyZWRPcHRpb25zOiBmdW5jdGlvbiBmaWx0ZXJlZE9wdGlvbnMoKSB7XG5cdCAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHQgICAgICB2YXIgc2VhcmNoID0gKHRoaXMuc2VhcmNoVmFsdWUgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG5cdCAgICAgIHJldHVybiAhc2VhcmNoID8gdGhpcy5saXN0IDogdGhpcy5saXN0LmZpbHRlcihmdW5jdGlvbiAoZWwpIHtcblx0ICAgICAgICByZXR1cm4gfmVsW190aGlzLm9wdGlvbnNMYWJlbF0udG9Mb3dlckNhc2UoKS5zZWFyY2goc2VhcmNoKTtcblx0ICAgICAgfSk7XG5cdCAgICB9LFxuXHQgICAgaGFzUGFyZW50OiBmdW5jdGlvbiBoYXNQYXJlbnQoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnBhcmVudCBpbnN0YW5jZW9mIEFycmF5ID8gdGhpcy5wYXJlbnQubGVuZ3RoIDogdGhpcy5wYXJlbnQ7XG5cdCAgICB9LFxuXHQgICAgaW5JbnB1dDogZnVuY3Rpb24gaW5JbnB1dCgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuJHBhcmVudC5faW5wdXQ7XG5cdCAgICB9LFxuXHQgICAgaXNMaTogZnVuY3Rpb24gaXNMaSgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuJHBhcmVudC5fbmF2YmFyIHx8IHRoaXMuJHBhcmVudC5tZW51IHx8IHRoaXMuJHBhcmVudC5fdGFic2V0O1xuXHQgICAgfSxcblx0ICAgIGxpbWl0VGV4dDogZnVuY3Rpb24gbGltaXRUZXh0KCkge1xuXHQgICAgICByZXR1cm4gdGhpcy50ZXh0LmxpbWl0LnJlcGxhY2UoJ3t7bGltaXR9fScsIHRoaXMubGltaXQpO1xuXHQgICAgfSxcblx0ICAgIHNlbGVjdGVkOiBmdW5jdGlvbiBzZWxlY3RlZCgpIHtcblx0ICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cdFxuXHQgICAgICBpZiAodGhpcy5saXN0Lmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgIHJldHVybiAnJztcblx0ICAgICAgfVxuXHQgICAgICB2YXIgc2VsID0gdGhpcy52YWx1ZXMubWFwKGZ1bmN0aW9uICh2YWwpIHtcblx0ICAgICAgICByZXR1cm4gKF90aGlzMi5saXN0LmZpbmQoZnVuY3Rpb24gKG8pIHtcblx0ICAgICAgICAgIHJldHVybiBvW190aGlzMi5vcHRpb25zVmFsdWVdID09PSB2YWw7XG5cdCAgICAgICAgfSkgfHwge30pW190aGlzMi5vcHRpb25zTGFiZWxdO1xuXHQgICAgICB9KS5maWx0ZXIoZnVuY3Rpb24gKHZhbCkge1xuXHQgICAgICAgIHJldHVybiB2YWwgIT09IHVuZGVmaW5lZDtcblx0ICAgICAgfSk7XG5cdCAgICAgIHRoaXMuJGVtaXQoJ3NlbGVjdGVkJywgc2VsKTtcblx0ICAgICAgcmV0dXJuIHNlbC5qb2luKCcsICcpO1xuXHQgICAgfSxcblx0ICAgIHNlbGVjdGVkVGV4dDogZnVuY3Rpb24gc2VsZWN0ZWRUZXh0KCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5jb3VudFRleHQgfHwgdGhpcy50ZXh0LnNlbGVjdGVkLnJlcGxhY2UoJ3t7Y291bnR9fScsIHRoaXMudmFsdWVzLmxlbmd0aCk7XG5cdCAgICB9LFxuXHQgICAgc2hvd1BsYWNlaG9sZGVyOiBmdW5jdGlvbiBzaG93UGxhY2Vob2xkZXIoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnZhbHVlcy5sZW5ndGggPT09IDAgfHwgIXRoaXMuaGFzUGFyZW50ID8gdGhpcy5wbGFjZWhvbGRlciB8fCB0aGlzLnRleHQubm90U2VsZWN0ZWQgOiBudWxsO1xuXHQgICAgfSxcblx0ICAgIHRleHQ6IGZ1bmN0aW9uIHRleHQoKSB7XG5cdCAgICAgIHJldHVybiAoMCwgX3V0aWxzLnRyYW5zbGF0aW9ucykodGhpcy5sYW5nKTtcblx0ICAgIH0sXG5cdCAgICB2YWx1ZXM6IGZ1bmN0aW9uIHZhbHVlcygpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudmFsIGluc3RhbmNlb2YgQXJyYXkgPyB0aGlzLnZhbCA6IH5bbnVsbCwgdW5kZWZpbmVkXS5pbmRleE9mKHRoaXMudmFsKSA/IFtdIDogW3RoaXMudmFsXTtcblx0ICAgIH0sXG5cdCAgICB2YWxPcHRpb25zOiBmdW5jdGlvbiB2YWxPcHRpb25zKCkge1xuXHQgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblx0XG5cdCAgICAgIHJldHVybiB0aGlzLmxpc3QubWFwKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgIHJldHVybiBlbFtfdGhpczMub3B0aW9uc1ZhbHVlXTtcblx0ICAgICAgfSk7XG5cdCAgICB9XG5cdCAgfSxcblx0ICB3YXRjaDoge1xuXHQgICAgb3B0aW9uczogZnVuY3Rpb24gb3B0aW9ucyhfb3B0aW9ucykge1xuXHQgICAgICBpZiAoX29wdGlvbnMgaW5zdGFuY2VvZiBBcnJheSkgdGhpcy5zZXRPcHRpb25zKF9vcHRpb25zKTtcblx0ICAgIH0sXG5cdCAgICBzaG93OiBmdW5jdGlvbiBzaG93KHZhbCkge1xuXHQgICAgICBpZiAodmFsKSB7XG5cdCAgICAgICAgdGhpcy4kcmVmcy5zZWFyY2ggPyB0aGlzLiRyZWZzLnNlYXJjaC5mb2N1cygpIDogdGhpcy4kcmVmcy5idG4uZm9jdXMoKTtcblx0ICAgICAgICAvLyBvbkJsdXIodGhpcy4kcmVmcy5zZWxlY3QsIGUgPT4geyB0aGlzLnNob3cgPSBmYWxzZSB9KVxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgLy8gb2ZmQmx1cih0aGlzLiRyZWZzLnNlbGVjdClcblx0ICAgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdXJsOiBmdW5jdGlvbiB1cmwoKSB7XG5cdCAgICAgIHRoaXMudXJsQ2hhbmdlZCgpO1xuXHQgICAgfSxcblx0ICAgIHZhbGlkOiBmdW5jdGlvbiB2YWxpZCh2YWwsIG9sZCkge1xuXHQgICAgICB0aGlzLiRlbWl0KCdpc3ZhbGlkJywgdmFsKTtcblx0ICAgICAgdGhpcy4kZW1pdCghdmFsID8gJ2ludmFsaWQnIDogJ3ZhbGlkJyk7XG5cdCAgICAgIGlmICh2YWwgIT09IG9sZCAmJiB0aGlzLl9wYXJlbnQpIHRoaXMuX3BhcmVudC52YWxpZGF0ZSgpO1xuXHQgICAgfSxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZSh2YWwsIG9sZCkge1xuXHQgICAgICBpZiAodmFsICE9PSBvbGQpIHtcblx0ICAgICAgICB0aGlzLnZhbCA9IHZhbDtcblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHZhbDogZnVuY3Rpb24gdmFsKF92YWwsIG9sZCkge1xuXHQgICAgICB2YXIgX3RoaXM0ID0gdGhpcztcblx0XG5cdCAgICAgIGlmIChfdmFsID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICB0aGlzLnZhbCA9IF92YWwgPSBudWxsO1xuXHQgICAgICB9XG5cdCAgICAgIGlmIChfdmFsICE9PSBvbGQpIHtcblx0ICAgICAgICB0aGlzLiRlbWl0KCdjaGFuZ2UnLCBfdmFsKTtcblx0ICAgICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIF92YWwpO1xuXHQgICAgICB9XG5cdCAgICAgIGlmIChfdmFsIGluc3RhbmNlb2YgQXJyYXkgJiYgX3ZhbC5sZW5ndGggPiB0aGlzLmxpbWl0KSB7XG5cdCAgICAgICAgdGhpcy52YWwgPSBfdmFsLnNsaWNlKDAsIHRoaXMubGltaXQpO1xuXHQgICAgICAgIHRoaXMubm90aWZ5ID0gdHJ1ZTtcblx0ICAgICAgICBpZiAodGltZW91dC5saW1pdCkgY2xlYXJUaW1lb3V0KHRpbWVvdXQubGltaXQpO1xuXHQgICAgICAgIHRpbWVvdXQubGltaXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgIHRpbWVvdXQubGltaXQgPSBmYWxzZTtcblx0ICAgICAgICAgIF90aGlzNC5ub3RpZnkgPSBmYWxzZTtcblx0ICAgICAgICB9LCAxNTAwKTtcblx0ICAgICAgfVxuXHQgICAgICB0aGlzLnZhbGlkID0gdGhpcy52YWxpZGF0ZSgpO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbWV0aG9kczoge1xuXHQgICAgY2xvc2U6IGZ1bmN0aW9uIGNsb3NlKCkge1xuXHQgICAgICB0aGlzLnNob3cgPSBmYWxzZTtcblx0ICAgIH0sXG5cdCAgICBjaGVja0RhdGE6IGZ1bmN0aW9uIGNoZWNrRGF0YSgpIHtcblx0ICAgICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcblx0ICAgICAgICBpZiAodGhpcy5saW1pdCA8IDEpIHtcblx0ICAgICAgICAgIHRoaXMubGltaXQgPSAxO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoISh0aGlzLnZhbCBpbnN0YW5jZW9mIEFycmF5KSkge1xuXHQgICAgICAgICAgdGhpcy52YWwgPSB0aGlzLnZhbCA9PT0gbnVsbCB8fCB0aGlzLnZhbCA9PT0gdW5kZWZpbmVkID8gW10gOiBbdGhpcy52YWxdO1xuXHQgICAgICAgIH1cblx0ICAgICAgICB2YXIgdmFsdWVzID0gdGhpcy52YWxPcHRpb25zO1xuXHQgICAgICAgIHRoaXMudmFsID0gdGhpcy52YWwuZmlsdGVyKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgICAgcmV0dXJuIH52YWx1ZXMuaW5kZXhPZihlbCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHRoaXMudmFsdWVzLmxlbmd0aCA+IHRoaXMubGltaXQpIHtcblx0ICAgICAgICAgIHRoaXMudmFsID0gdGhpcy52YWwuc2xpY2UoMCwgdGhpcy5saW1pdCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIGlmICghfnRoaXMudmFsT3B0aW9ucy5pbmRleE9mKHRoaXMudmFsKSkge1xuXHQgICAgICAgICAgdGhpcy52YWwgPSBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSxcblx0ICAgIGNsZWFyOiBmdW5jdGlvbiBjbGVhcigpIHtcblx0ICAgICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5yZWFkb25seSkge1xuXHQgICAgICAgIHJldHVybjtcblx0ICAgICAgfVxuXHQgICAgICB0aGlzLnZhbCA9IHRoaXMudmFsIGluc3RhbmNlb2YgQXJyYXkgPyBbXSA6IG51bGw7XG5cdCAgICAgIHRoaXMudG9nZ2xlKCk7XG5cdCAgICB9LFxuXHQgICAgY2xlYXJTZWFyY2g6IGZ1bmN0aW9uIGNsZWFyU2VhcmNoKCkge1xuXHQgICAgICB0aGlzLnNlYXJjaFZhbHVlID0gJyc7XG5cdCAgICAgIHRoaXMuJHJlZnMuc2VhcmNoLmZvY3VzKCk7XG5cdCAgICB9LFxuXHQgICAgaXNTZWxlY3RlZDogZnVuY3Rpb24gaXNTZWxlY3RlZCh2KSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnZhbHVlcy5pbmRleE9mKHYpID4gLTE7XG5cdCAgICB9LFxuXHQgICAgc2VsZWN0OiBmdW5jdGlvbiBzZWxlY3Qodikge1xuXHQgICAgICBpZiAodGhpcy52YWwgaW5zdGFuY2VvZiBBcnJheSkge1xuXHQgICAgICAgIHZhciBuZXdWYWwgPSB0aGlzLnZhbC5zbGljZSgwKTtcblx0ICAgICAgICBpZiAofm5ld1ZhbC5pbmRleE9mKHYpKSB7XG5cdCAgICAgICAgICBuZXdWYWwuc3BsaWNlKG5ld1ZhbC5pbmRleE9mKHYpLCAxKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgbmV3VmFsLnB1c2godik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHRoaXMudmFsID0gbmV3VmFsO1xuXHQgICAgICAgIGlmICh0aGlzLmNsb3NlT25TZWxlY3QpIHtcblx0ICAgICAgICAgIHRoaXMudG9nZ2xlKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHRoaXMudmFsID0gdjtcblx0ICAgICAgICB0aGlzLnRvZ2dsZSgpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgc2V0T3B0aW9uczogZnVuY3Rpb24gc2V0T3B0aW9ucyhvcHRpb25zKSB7XG5cdCAgICAgIHZhciBfdGhpczUgPSB0aGlzO1xuXHRcblx0ICAgICAgdGhpcy5saXN0ID0gb3B0aW9ucy5tYXAoZnVuY3Rpb24gKGVsKSB7XG5cdCAgICAgICAgaWYgKGVsIGluc3RhbmNlb2YgT2JqZWN0KSB7XG5cdCAgICAgICAgICByZXR1cm4gZWw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHZhciBvYmogPSB7fTtcblx0ICAgICAgICBvYmpbX3RoaXM1Lm9wdGlvbnNMYWJlbF0gPSBlbDtcblx0ICAgICAgICBvYmpbX3RoaXM1Lm9wdGlvbnNWYWx1ZV0gPSBlbDtcblx0ICAgICAgICByZXR1cm4gb2JqO1xuXHQgICAgICB9KTtcblx0ICAgICAgdGhpcy4kZW1pdCgnb3B0aW9ucycsIHRoaXMubGlzdCk7XG5cdCAgICB9LFxuXHQgICAgdG9nZ2xlOiBmdW5jdGlvbiB0b2dnbGUoKSB7XG5cdCAgICAgIGlmICh0aGlzLmRpc2FibGVkICYmICF0aGlzLnNob3cpIHJldHVybjtcblx0ICAgICAgdGhpcy5zaG93ID0gIXRoaXMuc2hvdztcblx0ICAgICAgaWYgKCF0aGlzLnNob3cpIHRoaXMuJHJlZnMuYnRuLmZvY3VzKCk7XG5cdCAgICB9LFxuXHQgICAgdXJsQ2hhbmdlZDogZnVuY3Rpb24gdXJsQ2hhbmdlZCgpIHtcblx0ICAgICAgdmFyIF90aGlzNiA9IHRoaXM7XG5cdFxuXHQgICAgICBpZiAoIXRoaXMudXJsIHx8ICF0aGlzLiRodHRwKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG5cdCAgICAgIHRoaXMuJGh0dHAuZ2V0KHRoaXMudXJsKS50aGVuKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXHQgICAgICAgIHZhciBkYXRhID0gcmVzcG9uc2UuZGF0YSBpbnN0YW5jZW9mIEFycmF5ID8gcmVzcG9uc2UuZGF0YSA6IFtdO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcblx0ICAgICAgICB9IGNhdGNoIChlKSB7fVxuXHQgICAgICAgIF90aGlzNi5zZXRPcHRpb25zKGRhdGEpO1xuXHQgICAgICAgIF90aGlzNi5sb2FkaW5nID0gZmFsc2U7XG5cdCAgICAgICAgX3RoaXM2LmNoZWNrRGF0YSgpO1xuXHQgICAgICB9LCBmdW5jdGlvbiAocmVzcG9uc2UpIHtcblx0ICAgICAgICBfdGhpczYubG9hZGluZyA9IGZhbHNlO1xuXHQgICAgICB9KTtcblx0ICAgIH0sXG5cdCAgICB2YWxpZGF0ZTogZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG5cdCAgICAgIHJldHVybiAhdGhpcy5yZXF1aXJlZCA/IHRydWUgOiB0aGlzLnZhbCBpbnN0YW5jZW9mIEFycmF5ID8gdGhpcy52YWwubGVuZ3RoID4gMCA6IHRoaXMudmFsICE9PSBudWxsO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIHRoaXMuc2V0T3B0aW9ucyh0aGlzLm9wdGlvbnMpO1xuXHQgICAgdGhpcy52YWwgPSB0aGlzLnZhbHVlO1xuXHQgICAgdGhpcy5fc2VsZWN0ID0gdHJ1ZTtcblx0ICAgIGlmICh0aGlzLnZhbCA9PT0gdW5kZWZpbmVkIHx8ICF0aGlzLnBhcmVudCkge1xuXHQgICAgICB0aGlzLnZhbCA9IG51bGw7XG5cdCAgICB9XG5cdCAgICBpZiAoIXRoaXMubXVsdGlwbGUgJiYgdGhpcy52YWwgaW5zdGFuY2VvZiBBcnJheSkge1xuXHQgICAgICB0aGlzLnZhbCA9IHRoaXMudmFsWzBdO1xuXHQgICAgfVxuXHQgICAgdGhpcy5jaGVja0RhdGEoKTtcblx0ICAgIGlmICh0aGlzLnVybCkgdGhpcy51cmxDaGFuZ2VkKCk7XG5cdCAgICB2YXIgcGFyZW50ID0gdGhpcy4kcGFyZW50O1xuXHQgICAgd2hpbGUgKHBhcmVudCAmJiAhcGFyZW50Ll9mb3JtVmFsaWRhdG9yKSB7XG5cdCAgICAgIHBhcmVudCA9IHBhcmVudC4kcGFyZW50O1xuXHQgICAgfVxuXHQgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuX2Zvcm1WYWxpZGF0b3IpIHtcblx0ICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2godGhpcyk7XG5cdCAgICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1vdW50ZWQ6IGZ1bmN0aW9uIG1vdW50ZWQoKSB7XG5cdCAgICBpZiAodGhpcy5fcGFyZW50KSB0aGlzLl9wYXJlbnQuY2hpbGRyZW4ucHVzaCh0aGlzKTtcblx0ICAgIHRoaXMuc2V0T3B0aW9ucyh0aGlzLm9wdGlvbnMpO1xuXHQgICAgdGhpcy52YWwgPSB0aGlzLnZhbHVlO1xuXHQgICAgdGhpcy5jaGVja0RhdGEoKTtcblx0ICB9LFxuXHQgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uIGJlZm9yZURlc3Ryb3koKSB7XG5cdCAgICBpZiAodGhpcy5fcGFyZW50KSB7XG5cdCAgICAgIHZhciBpbmRleCA9IHRoaXMuX3BhcmVudC5jaGlsZHJlbi5pbmRleE9mKHRoaXMpO1xuXHQgICAgICB0aGlzLl9wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKGluZGV4LCAxKTtcblx0ICAgIH1cblx0ICB9XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxNTcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdG1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7XG5cdCAgcmV0dXJuIF92bS5fYygnZGl2Jywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJjbGljay1vdXRzaWRlXCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1jbGljay1vdXRzaWRlXCIsXG5cdCAgICAgIHZhbHVlOiAoX3ZtLmNsb3NlKSxcblx0ICAgICAgZXhwcmVzc2lvbjogXCJjbG9zZVwiXG5cdCAgICB9XSxcblx0ICAgIHJlZjogXCJzZWxlY3RcIixcblx0ICAgIGNsYXNzOiBfdm0uY2xhc3Nlc1xuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHJlZjogXCJidG5cIixcblx0ICAgIHN0YXRpY0NsYXNzOiBcImZvcm0tY29udHJvbCBkcm9wZG93bi10b2dnbGVcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidGFiaW5kZXhcIjogXCIxXCIsXG5cdCAgICAgIFwiZGlzYWJsZWRcIjogX3ZtLmRpc2FibGVkIHx8ICFfdm0uaGFzUGFyZW50LFxuXHQgICAgICBcInJlYWRvbmx5XCI6IF92bS5yZWFkb25seVxuXHQgICAgfSxcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwiYmx1clwiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBfdm0uY2FuU2VhcmNoID8gbnVsbCA6IF92bS5jbG9zZSgpXG5cdCAgICAgIH0sXG5cdCAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnRvZ2dsZSgpXG5cdCAgICAgIH0sXG5cdCAgICAgIFwia2V5ZG93blwiOiBbZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgaWYgKF92bS5faygkZXZlbnQua2V5Q29kZSwgXCJlc2NcIiwgMjcpKSB7IHJldHVybjsgfVxuXHQgICAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICBfdm0uY2xvc2UoJGV2ZW50KVxuXHQgICAgICB9LCBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBpZiAoX3ZtLl9rKCRldmVudC5rZXlDb2RlLCBcInNwYWNlXCIsIDMyKSkgeyByZXR1cm47IH1cblx0ICAgICAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdCAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgX3ZtLnRvZ2dsZSgkZXZlbnQpXG5cdCAgICAgIH0sIGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIGlmIChfdm0uX2soJGV2ZW50LmtleUNvZGUsIFwiZW50ZXJcIiwgMTMpKSB7IHJldHVybjsgfVxuXHQgICAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0ICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICBfdm0udG9nZ2xlKCRldmVudClcblx0ICAgICAgfV1cblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdzcGFuJywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwiYnRuLWNvbnRlbnRcIixcblx0ICAgIGRvbVByb3BzOiB7XG5cdCAgICAgIFwiaW5uZXJIVE1MXCI6IF92bS5fcyhfdm0ubG9hZGluZyA/IF92bS50ZXh0LmxvYWRpbmcgOiBfdm0uc2hvd1BsYWNlaG9sZGVyIHx8IChfdm0ubXVsdGlwbGUgJiYgX3ZtLnNob3dDb3VudCA/IF92bS5zZWxlY3RlZFRleHQgOiBfdm0uc2VsZWN0ZWQpKVxuXHQgICAgfVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLmNsZWFyQnV0dG9uICYmIF92bS52YWx1ZXMubGVuZ3RoKSA/IF92bS5fYygnc3BhbicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImNsb3NlXCIsXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIF92bS5jbGVhcigpXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LCBbX3ZtLl92KFwiw5dcIildKSA6IF92bS5fZSgpXSksIF92bS5fdihcIiBcIiksIF92bS5fYygnc2VsZWN0Jywge1xuXHQgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgbmFtZTogXCJtb2RlbFwiLFxuXHQgICAgICByYXdOYW1lOiBcInYtbW9kZWxcIixcblx0ICAgICAgdmFsdWU6IChfdm0udmFsKSxcblx0ICAgICAgZXhwcmVzc2lvbjogXCJ2YWxcIlxuXHQgICAgfV0sXG5cdCAgICByZWY6IFwic2VsXCIsXG5cdCAgICBzdGF0aWNDbGFzczogXCJzZWNyZXRcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwibmFtZVwiOiBfdm0ubmFtZSxcblx0ICAgICAgXCJtdWx0aXBsZVwiOiBfdm0ubXVsdGlwbGUsXG5cdCAgICAgIFwicmVxdWlyZWRcIjogX3ZtLnJlcXVpcmVkLFxuXHQgICAgICBcInJlYWRvbmx5XCI6IF92bS5yZWFkb25seSxcblx0ICAgICAgXCJkaXNhYmxlZFwiOiBfdm0uZGlzYWJsZWRcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImNoYW5nZVwiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBfdm0udmFsID0gQXJyYXkucHJvdG90eXBlLmZpbHRlci5jYWxsKCRldmVudC50YXJnZXQub3B0aW9ucywgZnVuY3Rpb24obykge1xuXHQgICAgICAgICAgcmV0dXJuIG8uc2VsZWN0ZWRcblx0ICAgICAgICB9KS5tYXAoZnVuY3Rpb24obykge1xuXHQgICAgICAgICAgdmFyIHZhbCA9IFwiX3ZhbHVlXCIgaW4gbyA/IG8uX3ZhbHVlIDogby52YWx1ZTtcblx0ICAgICAgICAgIHJldHVybiB2YWxcblx0ICAgICAgICB9KVswXVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSwgWyhfdm0ucmVxdWlyZWQpID8gX3ZtLl9jKCdvcHRpb24nLCB7XG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcInZhbHVlXCI6IFwiXCJcblx0ICAgIH1cblx0ICB9KSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2woKF92bS5saXN0KSwgZnVuY3Rpb24ob3B0aW9uKSB7XG5cdCAgICByZXR1cm4gX3ZtLl9jKCdvcHRpb24nLCB7XG5cdCAgICAgIGRvbVByb3BzOiB7XG5cdCAgICAgICAgXCJ2YWx1ZVwiOiBvcHRpb25bX3ZtLm9wdGlvbnNWYWx1ZV1cblx0ICAgICAgfVxuXHQgICAgfSwgW192bS5fdihfdm0uX3Mob3B0aW9uW192bS5vcHRpb25zTGFiZWxdKSldKVxuXHQgIH0pXSwgMiksIF92bS5fdihcIiBcIiksIF92bS5fYygndWwnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJkcm9wZG93bi1tZW51XCJcblx0ICB9LCBbKF92bS5saXN0Lmxlbmd0aCkgPyBbKF92bS5jYW5TZWFyY2gpID8gX3ZtLl9jKCdsaScsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcImJzLXNlYXJjaGJveFwiXG5cdCAgfSwgW192bS5fYygnaW5wdXQnLCB7XG5cdCAgICBkaXJlY3RpdmVzOiBbe1xuXHQgICAgICBuYW1lOiBcIm1vZGVsXCIsXG5cdCAgICAgIHJhd05hbWU6IFwidi1tb2RlbFwiLFxuXHQgICAgICB2YWx1ZTogKF92bS5zZWFyY2hWYWx1ZSksXG5cdCAgICAgIGV4cHJlc3Npb246IFwic2VhcmNoVmFsdWVcIlxuXHQgICAgfV0sXG5cdCAgICByZWY6IFwic2VhcmNoXCIsXG5cdCAgICBzdGF0aWNDbGFzczogXCJmb3JtLWNvbnRyb2xcIixcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcInRleHRcIixcblx0ICAgICAgXCJwbGFjZWhvbGRlclwiOiBfdm0uc2VhcmNoVGV4dCB8fCBfdm0udGV4dC5zZWFyY2gsXG5cdCAgICAgIFwiYXV0b2NvbXBsZXRlXCI6IFwib2ZmXCJcblx0ICAgIH0sXG5cdCAgICBkb21Qcm9wczoge1xuXHQgICAgICBcInZhbHVlXCI6IF92bS5fcyhfdm0uc2VhcmNoVmFsdWUpXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJrZXl1cFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBpZiAoX3ZtLl9rKCRldmVudC5rZXlDb2RlLCBcImVzY1wiLCAyNykpIHsgcmV0dXJuOyB9XG5cdCAgICAgICAgX3ZtLmNsb3NlKCRldmVudClcblx0ICAgICAgfSxcblx0ICAgICAgXCJpbnB1dFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBpZiAoJGV2ZW50LnRhcmdldC5jb21wb3NpbmcpIHsgcmV0dXJuOyB9XG5cdCAgICAgICAgX3ZtLnNlYXJjaFZhbHVlID0gJGV2ZW50LnRhcmdldC52YWx1ZVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSksIF92bS5fdihcIiBcIiksIF92bS5fYygnc3BhbicsIHtcblx0ICAgIGRpcmVjdGl2ZXM6IFt7XG5cdCAgICAgIG5hbWU6IFwic2hvd1wiLFxuXHQgICAgICByYXdOYW1lOiBcInYtc2hvd1wiLFxuXHQgICAgICB2YWx1ZTogKF92bS5zZWFyY2hWYWx1ZSksXG5cdCAgICAgIGV4cHJlc3Npb246IFwic2VhcmNoVmFsdWVcIlxuXHQgICAgfV0sXG5cdCAgICBzdGF0aWNDbGFzczogXCJjbG9zZVwiLFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBfdm0uY2xlYXJTZWFyY2hcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl92KFwiw5dcIildKV0pIDogX3ZtLl9lKCksIF92bS5fdihcIiBcIiksIChfdm0ucmVxdWlyZWQgJiYgIV92bS5jbGVhckJ1dHRvbikgPyBfdm0uX2MoJ2xpJywgW192bS5fYygnYScsIHtcblx0ICAgIG9uOiB7XG5cdCAgICAgIFwibW91c2Vkb3duXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgIF92bS5jbGVhcigpICYmIF92bS5jbG9zZSgpXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LCBbX3ZtLl92KF92bS5fcyhfdm0ucGxhY2Vob2xkZXIgfHwgX3ZtLnRleHQubm90U2VsZWN0ZWQpKV0pXSkgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9sKChfdm0uZmlsdGVyZWRPcHRpb25zKSwgZnVuY3Rpb24ob3B0aW9uKSB7XG5cdCAgICByZXR1cm4gX3ZtLl9jKCdsaScsIHtcblx0ICAgICAgYXR0cnM6IHtcblx0ICAgICAgICBcImlkXCI6IG9wdGlvbltfdm0ub3B0aW9uc1ZhbHVlXVxuXHQgICAgICB9XG5cdCAgICB9LCBbX3ZtLl9jKCdhJywge1xuXHQgICAgICBvbjoge1xuXHQgICAgICAgIFwibW91c2Vkb3duXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgICBfdm0uc2VsZWN0KG9wdGlvbltfdm0ub3B0aW9uc1ZhbHVlXSlcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0sIFtfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICAgIGRvbVByb3BzOiB7XG5cdCAgICAgICAgXCJpbm5lckhUTUxcIjogX3ZtLl9zKG9wdGlvbltfdm0ub3B0aW9uc0xhYmVsXSlcblx0ICAgICAgfVxuXHQgICAgfSksIF92bS5fdihcIiBcIiksIF92bS5fYygnc3BhbicsIHtcblx0ICAgICAgZGlyZWN0aXZlczogW3tcblx0ICAgICAgICBuYW1lOiBcInNob3dcIixcblx0ICAgICAgICByYXdOYW1lOiBcInYtc2hvd1wiLFxuXHQgICAgICAgIHZhbHVlOiAoX3ZtLmlzU2VsZWN0ZWQob3B0aW9uW192bS5vcHRpb25zVmFsdWVdKSksXG5cdCAgICAgICAgZXhwcmVzc2lvbjogXCJpc1NlbGVjdGVkKG9wdGlvbltvcHRpb25zVmFsdWVdKVwiXG5cdCAgICAgIH1dLFxuXHQgICAgICBzdGF0aWNDbGFzczogXCJnbHlwaGljb24gZ2x5cGhpY29uLW9rIGNoZWNrLW1hcmtcIlxuXHQgICAgfSldKV0pXG5cdCAgfSldIDogX3ZtLl9lKCksIF92bS5fdihcIiBcIiksIF92bS5fdChcImRlZmF1bHRcIiksIF92bS5fdihcIiBcIiksIChfdm0ubm90aWZ5ICYmICFfdm0uY2xvc2VPblNlbGVjdCkgPyBfdm0uX2MoJ3RyYW5zaXRpb24nLCB7XG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcIm5hbWVcIjogXCJmYWRlaW5cIlxuXHQgICAgfVxuXHQgIH0sIFtfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcIm5vdGlmeSBpblwiXG5cdCAgfSwgW192bS5fdihfdm0uX3MoX3ZtLmxpbWl0VGV4dCkpXSldKSA6IF92bS5fZSgpXSwgMiksIF92bS5fdihcIiBcIiksIChfdm0ubm90aWZ5ICYmIF92bS5jbG9zZU9uU2VsZWN0KSA/IF92bS5fYygndHJhbnNpdGlvbicsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwibmFtZVwiOiBcImZhZGVpblwiXG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwibm90aWZ5IG91dFwiXG5cdCAgfSwgW192bS5fYygnZGl2JywgW192bS5fdihfdm0uX3MoX3ZtLmxpbWl0VGV4dCkpXSldKV0pIDogX3ZtLl9lKCldLCAxKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1lNTE0ZGJjNlwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDE1OCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNTkpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTYwKVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXFNsaWRlci52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtMzIxODViODJcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTMyMTg1YjgyXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gU2xpZGVyLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDE1OSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdC8vXG5cdC8vXG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgY29tcHV0ZWQ6IHtcblx0ICAgIGluZGV4OiBmdW5jdGlvbiBpbmRleCgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuJHBhcmVudC4kY2hpbGRyZW4uaW5kZXhPZih0aGlzKTtcblx0ICAgIH0sXG5cdCAgICBzaG93OiBmdW5jdGlvbiBzaG93KCkge1xuXHQgICAgICByZXR1cm4gdGhpcy4kcGFyZW50LmluZGV4ID09PSB0aGlzLmluZGV4O1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgbW91bnRlZDogZnVuY3Rpb24gbW91bnRlZCgpIHtcblx0ICAgIGlmICh0aGlzLiRwYXJlbnQuaW5kaWNhdG9yX2xpc3QpIHtcblx0ICAgICAgdGhpcy4kcGFyZW50LmluZGljYXRvcl9saXN0LnB1c2godGhpcy5pbmRleCk7XG5cdCAgICB9XG5cdFxuXHQgICAgaWYgKHRoaXMuaW5kZXggPT09IDApIHtcblx0ICAgICAgdGhpcy4kZWwuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdCAgICB9XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTYwICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHN0YXRpY0NsYXNzOiBcIml0ZW1cIlxuXHQgIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMilcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMzIxODViODJcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxNjEgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc3R5bGVzICovXG5cdF9fd2VicGFja19yZXF1aXJlX18oMTYyKVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTY0KVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2NSlcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxTcGlubmVyLnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0XG5cdC8qIGhvdCByZWxvYWQgKi9cblx0aWYgKGZhbHNlKSB7KGZ1bmN0aW9uICgpIHtcblx0ICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuXHQgIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuXHQgIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi04YjI5OGU3MFwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfSBlbHNlIHtcblx0ICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtOGIyOThlNzBcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH1cblx0fSkoKX1cblx0aWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBTcGlubmVyLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDE2MiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0Ly8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblx0XG5cdC8vIGxvYWQgdGhlIHN0eWxlc1xuXHR2YXIgY29udGVudCA9IF9fd2VicGFja19yZXF1aXJlX18oMTYzKTtcblx0aWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG5cdC8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cblx0dmFyIHVwZGF0ZSA9IF9fd2VicGFja19yZXF1aXJlX18oNzkpKGNvbnRlbnQsIHt9KTtcblx0aWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG5cdC8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcblx0aWYoZmFsc2UpIHtcblx0XHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi04YjI5OGU3MCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vU3Bpbm5lci52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LThiMjk4ZTcwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9TcGlubmVyLnZ1ZVwiKTtcblx0XHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG5cdH1cblxuLyoqKi8gfSxcbi8qIDE2MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0ZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OCkoKTtcblx0Ly8gaW1wb3J0c1xuXHRcblx0XG5cdC8vIG1vZHVsZVxuXHRleHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG5Aa2V5ZnJhbWVzIHNwaW4ge1xcbjEwMCUge1xcclxcbiAgICB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpO1xcbn1cXG59XFxuLnNwaW5uZXItZ3JpdGNvZGUge1xcclxcbiAgdG9wOiAwO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIGJvdHRvbTogMDtcXHJcXG4gIHJpZ2h0OiAwO1xcclxcbiAgei1pbmRleDogOTk5ODtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHdpZHRoOiAxMDAlO1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbiAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjkpO1xcbn1cXG4uc3Bpbm5lci1ncml0Y29kZS5zcGlubmVyLWZpeGVkIHtcXHJcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG59XFxuLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItd3JhcHBlciB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IDUwJTtcXHJcXG4gIGxlZnQ6IDUwJTtcXHJcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcclxcbiAgLW1zLXRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcbn1cXG4uc3Bpbm5lci1ncml0Y29kZSAuc3Bpbm5lci1jaXJjbGUge1xcclxcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcclxcbiAgYm9yZGVyOiA0cHggc29saWQgI2NjYztcXHJcXG4gIGJvcmRlci1yaWdodC1jb2xvcjogIzMzN2FiNztcXHJcXG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcXHJcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG4gIGFuaW1hdGlvbjogc3BpbiAwLjZzIGxpbmVhcjtcXHJcXG4gIGFuaW1hdGlvbi1pdGVyYXRpb24tY291bnQ6IGluZmluaXRlO1xcclxcbiAgd2lkdGg6IDNlbTtcXHJcXG4gIGhlaWdodDogM2VtO1xcclxcbiAgei1pbmRleDogMjtcXG59XFxuLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItdGV4dCB7XFxyXFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxuICBtYXJnaW4tdG9wOiAwLjVlbTtcXHJcXG4gIHotaW5kZXg6IDI7XFxyXFxuICB3aWR0aDogMTAwJTtcXHJcXG4gIGZvbnQtc2l6ZTogOTUlO1xcclxcbiAgY29sb3I6ICMzMzdhYjc7XFxufVxcbi5zcGlubmVyLWdyaXRjb2RlLnNwaW5uZXItc20gLnNwaW5uZXItY2lyY2xlIHtcXHJcXG4gIHdpZHRoOiAxLjVlbTtcXHJcXG4gIGhlaWdodDogMS41ZW07XFxufVxcbi5zcGlubmVyLWdyaXRjb2RlLnNwaW5uZXItbWQgLnNwaW5uZXItY2lyY2xlIHtcXHJcXG4gIHdpZHRoOiAyZW07XFxyXFxuICBoZWlnaHQ6IDJlbTtcXG59XFxuLnNwaW5uZXItZ3JpdGNvZGUuc3Bpbm5lci1sZyAuc3Bpbm5lci1jaXJjbGUge1xcclxcbiAgd2lkdGg6IDIuNWVtO1xcclxcbiAgaGVpZ2h0OiAyLjVlbTtcXG59XFxuLnNwaW5uZXItZ3JpdGNvZGUuc3Bpbm5lci14bCAuc3Bpbm5lci1jaXJjbGUge1xcclxcbiAgd2lkdGg6IDMuNWVtO1xcclxcbiAgaGVpZ2h0OiAzLjVlbTtcXG59XFxuLmx0LWllMTAgLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItY2lyY2xlLFxcclxcbi5pZTkgLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItY2lyY2xlLFxcclxcbi5vbGRpZSAuc3Bpbm5lci1ncml0Y29kZSAuc3Bpbm5lci1jaXJjbGUsXFxyXFxuLm5vLWNzc3RyYW5zaXRpb25zIC5zcGlubmVyLWdyaXRjb2RlIC5zcGlubmVyLWNpcmNsZSxcXHJcXG4ubm8tY3NzdHJhbnNmb3JtczNkIC5zcGlubmVyLWdyaXRjb2RlIC5zcGlubmVyLWNpcmNsZSB7XFxyXFxuICBiYWNrZ3JvdW5kOiB1cmwoXFxcImh0dHA6Ly9pMi53cC5jb20vd3d3LnRoZWdyZWF0bm92ZWxpbmdhZHZlbnR1cmUuY29tL3dwLWNvbnRlbnQvcGx1Z2lucy93cC1wb2xscy9pbWFnZXMvbG9hZGluZy5naWZcXFwiKSBjZW50ZXIgY2VudGVyIG5vLXJlcGVhdDtcXHJcXG4gIGFuaW1hdGlvbjogbm9uZTtcXHJcXG4gIG1hcmdpbi1sZWZ0OiAwO1xcclxcbiAgbWFyZ2luLXRvcDogNXB4O1xcclxcbiAgYm9yZGVyOiBub25lO1xcclxcbiAgd2lkdGg6IDMycHg7XFxyXFxuICBoZWlnaHQ6IDMycHg7XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvU3Bpbm5lci52dWU/NjVmYzVhOGZcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQTJGQTtBQUNBO0lBQ0EsMEJBQUE7Q0FDQTtDQUNBO0FBQ0E7RUFDQSxPQUFBO0VBQ0EsUUFBQTtFQUNBLFVBQUE7RUFDQSxTQUFBO0VBQ0EsY0FBQTtFQUNBLG1CQUFBO0VBQ0EsWUFBQTtFQUNBLG1CQUFBO0VBQ0EscUNBQUE7Q0FDQTtBQUNBO0VBQ0EsZ0JBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxTQUFBO0VBQ0EsVUFBQTtFQUNBLGlDQUFBO0VBQ0EscUNBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSx1QkFBQTtFQUNBLDRCQUFBO0VBQ0EsbUJBQUE7RUFDQSxzQkFBQTtFQUNBLDRCQUFBO0VBQ0Esb0NBQUE7RUFDQSxXQUFBO0VBQ0EsWUFBQTtFQUNBLFdBQUE7Q0FDQTtBQUNBO0VBQ0EsbUJBQUE7RUFDQSxtQkFBQTtFQUNBLGtCQUFBO0VBQ0EsV0FBQTtFQUNBLFlBQUE7RUFDQSxlQUFBO0VBQ0EsZUFBQTtDQUNBO0FBQ0E7RUFDQSxhQUFBO0VBQ0EsY0FBQTtDQUNBO0FBQ0E7RUFDQSxXQUFBO0VBQ0EsWUFBQTtDQUNBO0FBQ0E7RUFDQSxhQUFBO0VBQ0EsY0FBQTtDQUNBO0FBQ0E7RUFDQSxhQUFBO0VBQ0EsY0FBQTtDQUNBO0FBQ0E7Ozs7O0VBS0EsNklBQUE7RUFDQSxnQkFBQTtFQUNBLGVBQUE7RUFDQSxnQkFBQTtFQUNBLGFBQUE7RUFDQSxZQUFBO0VBQ0EsYUFBQTtDQUNBXCIsXCJmaWxlXCI6XCJTcGlubmVyLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxyXFxuICA8ZGl2IDpjbGFzcz1cXFwiWydzcGlubmVyIHNwaW5uZXItZ3JpdGNvZGUnLHNwaW5uZXJTaXplLHsnc3Bpbm5lci1maXhlZCc6Zml4ZWR9XVxcXCIgdi1zaG93PVxcXCJhY3RpdmV8fGxvY2tlZFxcXCI+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcInNwaW5uZXItd3JhcHBlclxcXCI+XFxyXFxuICAgICAgPGRpdiBjbGFzcz1cXFwic3Bpbm5lci1jaXJjbGVcXFwiPjwvZGl2PlxcclxcbiAgICAgIDxkaXYgY2xhc3M9XFxcInNwaW5uZXItdGV4dFxcXCI+e3t0ZXh0fX08L2Rpdj5cXHJcXG4gICAgPC9kaXY+XFxyXFxuICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcblxcclxcbjxzY3JpcHQ+XFxyXFxuaW1wb3J0IHtjb2VyY2UsIGRlbGF5ZXJ9IGZyb20gJy4vdXRpbHMvdXRpbHMuanMnXFxyXFxuY29uc3QgTUlOX1dBSVQgPSA1MDAgLy8gaW4gbXNcXHJcXG5cXHJcXG5leHBvcnQgZGVmYXVsdCB7XFxyXFxuICBwcm9wczoge1xcclxcbiAgICBmaXhlZDoge3R5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlfSxcXHJcXG4gICAgZ2xvYmFsOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBzaXplOiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnbWQnfSxcXHJcXG4gICAgdGV4dDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogJyd9LFxcclxcbiAgICB2YWx1ZToge2RlZmF1bHQ6IGZhbHNlfVxcclxcbiAgfSxcXHJcXG4gIGRhdGEgKCkge1xcclxcbiAgICByZXR1cm4ge1xcclxcbiAgICAgIGFjdGl2ZTogdGhpcy52YWx1ZSxcXHJcXG4gICAgICBsb2NrZWQ6IGZhbHNlXFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBjb21wdXRlZDoge1xcclxcbiAgICBzcGlubmVyU2l6ZSAoKSB7IHJldHVybiAnc3Bpbm5lci0nICsgKHRoaXMuc2l6ZSA/IHRoaXMuc2l6ZSA6ICdzbScpIH1cXHJcXG4gIH0sXFxyXFxuICB3YXRjaDoge1xcclxcbiAgICBhY3RpdmUgKHZhbCwgb2xkKSB7XFxyXFxuICAgICAgaWYgKHZhbCAhPT0gb2xkKSB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbClcXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsdWUgKHZhbCwgb2xkKSB7XFxyXFxuICAgICAgaWYgKHZhbCAhPT0gb2xkKSB7IHRoaXNbdmFsID8gJ3Nob3cnIDogJ2hpZGUnXSgpIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgaGlkZSAoKSB7XFxyXFxuICAgICAgdmFyIGRlbGF5ID0gMFxcclxcbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2VcXHJcXG4gICAgfSxcXHJcXG4gICAgc2hvdyAob3B0aW9ucykge1xcclxcbiAgICAgIGlmIChvcHRpb25zKSB7XFxyXFxuICAgICAgICBpZiAob3B0aW9ucy50ZXh0KSB7IHRoaXMudGV4dCA9IG9wdGlvbnMudGV4dCB9XFxyXFxuICAgICAgICBpZiAob3B0aW9ucy5zaXplKSB7IHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZSB9XFxyXFxuICAgICAgICBpZiAob3B0aW9ucy5maXhlZCkgeyB0aGlzLmZpeGVkID0gb3B0aW9ucy5maXhlZCB9XFxyXFxuICAgICAgfVxcclxcbiAgICAgIC8vIGJsb2NrIHNjcm9sbGluZyB3aGVuIHNwaW5uZXIgaXMgb25cXHJcXG4gICAgICB0aGlzLl9ib2R5LnN0eWxlLm92ZXJmbG93WSA9ICdoaWRkZW4nXFxyXFxuICAgICAgLy8gYWN0aXZhdGUgc3Bpbm5lclxcclxcbiAgICAgIHRoaXMuX3N0YXJ0ZWQgPSBuZXcgRGF0ZSgpXFxyXFxuICAgICAgdGhpcy5hY3RpdmUgPSB0cnVlXFxyXFxuICAgICAgdGhpcy5sb2NrZWQgPSB0cnVlXFxyXFxuICAgICAgdGhpcy5fdW5sb2NrKClcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGNyZWF0ZWQgKCkge1xcclxcbiAgICB0aGlzLl9ib2R5ID0gZG9jdW1lbnQuYm9keVxcclxcbiAgICB0aGlzLl9ib2R5T3ZlcmZsb3cgPSBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93WVxcclxcbiAgICB0aGlzLl91bmxvY2sgPSBkZWxheWVyKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICB0aGlzLmxvY2tlZCA9IGZhbHNlXFxyXFxuICAgICAgdGhpcy5fYm9keS5zdHlsZS5vdmVyZmxvd1kgPSB0aGlzLl9ib2R5T3ZlcmZsb3dcXHJcXG4gICAgfSwgTUlOX1dBSVQpXFxyXFxuICAgIGlmICh0aGlzLmdsb2JhbCkge1xcclxcbiAgICAgIGlmICghdGhpcy4kcm9vdC5fZ2xvYmFsU3Bpbm5lcikge1xcclxcbiAgICAgICAgdGhpcy4kcm9vdC5fZ2xvYmFsU3Bpbm5lciA9IHRydWVcXHJcXG4gICAgICAgIHZhciBzZWxmID0gdGhpc1xcclxcbiAgICAgICAgdGhpcy5fZ2xvYmFsID0ge1xcclxcbiAgICAgICAgICBoaWRlICgpIHsgc2VsZi5oaWRlKCkgfSxcXHJcXG4gICAgICAgICAgc2hvdyAoKSB7IHNlbGYuc2hvdygpIH1cXHJcXG4gICAgICAgIH1cXHJcXG4gICAgICAgIHRoaXMuJHJvb3QuJG9uKCdzcGlubmVyOjpzaG93JywgdGhpcy5fZ2xvYmFsLnNob3cpXFxyXFxuICAgICAgICB0aGlzLiRyb290LiRvbignc3Bpbm5lcjo6aGlkZScsIHRoaXMuX2dsb2JhbC5oaWRlKVxcclxcbiAgICAgIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGJlZm9yZURlc3Ryb3kgKCkge1xcclxcbiAgICBpZiAodGhpcy5fZ2xvYmFsKSB7XFxyXFxuICAgICAgdGhpcy4kcm9vdC4kb2ZmKCdzcGlubmVyOjpzaG93JywgdGhpcy5fZ2xvYmFsLnNob3cpXFxyXFxuICAgICAgdGhpcy4kcm9vdC4kb2ZmKCdzcGlubmVyOjpoaWRlJywgdGhpcy5fZ2xvYmFsLmhpZGUpXFxyXFxuICAgICAgZGVsZXRlIHRoaXMuJHJvb3QuX2dsb2JhbFNwaW5uZXJcXHJcXG4gICAgfVxcclxcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fc3Bpbm5lckFuaW1hdGlvbilcXHJcXG4gICAgdGhpcy5fYm9keS5zdHlsZS5vdmVyZmxvd1kgPSB0aGlzLl9ib2R5T3ZlcmZsb3dcXHJcXG4gIH1cXHJcXG59XFxyXFxuPC9zY3JpcHQ+XFxyXFxuXFxyXFxuPHN0eWxlPlxcclxcbkBrZXlmcmFtZXMgc3BpbiB7XFxyXFxuICAxMDAlIHtcXHJcXG4gICAgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTtcXHJcXG4gIH1cXHJcXG59XFxyXFxuLnNwaW5uZXItZ3JpdGNvZGUge1xcclxcbiAgdG9wOiAwO1xcclxcbiAgbGVmdDogMDtcXHJcXG4gIGJvdHRvbTogMDtcXHJcXG4gIHJpZ2h0OiAwO1xcclxcbiAgei1pbmRleDogOTk5ODtcXHJcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gIHdpZHRoOiAxMDAlO1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbiAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjkpO1xcclxcbn1cXHJcXG4uc3Bpbm5lci1ncml0Y29kZS5zcGlubmVyLWZpeGVkIHtcXHJcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXHJcXG59XFxyXFxuLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItd3JhcHBlciB7XFxyXFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICB0b3A6IDUwJTtcXHJcXG4gIGxlZnQ6IDUwJTtcXHJcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcclxcbiAgLW1zLXRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcclxcbn1cXHJcXG4uc3Bpbm5lci1ncml0Y29kZSAuc3Bpbm5lci1jaXJjbGUge1xcclxcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcclxcbiAgYm9yZGVyOiA0cHggc29saWQgI2NjYztcXHJcXG4gIGJvcmRlci1yaWdodC1jb2xvcjogIzMzN2FiNztcXHJcXG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcXHJcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG4gIGFuaW1hdGlvbjogc3BpbiAwLjZzIGxpbmVhcjtcXHJcXG4gIGFuaW1hdGlvbi1pdGVyYXRpb24tY291bnQ6IGluZmluaXRlO1xcclxcbiAgd2lkdGg6IDNlbTtcXHJcXG4gIGhlaWdodDogM2VtO1xcclxcbiAgei1pbmRleDogMjtcXHJcXG59XFxyXFxuLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItdGV4dCB7XFxyXFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxuICBtYXJnaW4tdG9wOiAwLjVlbTtcXHJcXG4gIHotaW5kZXg6IDI7XFxyXFxuICB3aWR0aDogMTAwJTtcXHJcXG4gIGZvbnQtc2l6ZTogOTUlO1xcclxcbiAgY29sb3I6ICMzMzdhYjc7XFxyXFxufVxcclxcbi5zcGlubmVyLWdyaXRjb2RlLnNwaW5uZXItc20gLnNwaW5uZXItY2lyY2xlIHtcXHJcXG4gIHdpZHRoOiAxLjVlbTtcXHJcXG4gIGhlaWdodDogMS41ZW07XFxyXFxufVxcclxcbi5zcGlubmVyLWdyaXRjb2RlLnNwaW5uZXItbWQgLnNwaW5uZXItY2lyY2xlIHtcXHJcXG4gIHdpZHRoOiAyZW07XFxyXFxuICBoZWlnaHQ6IDJlbTtcXHJcXG59XFxyXFxuLnNwaW5uZXItZ3JpdGNvZGUuc3Bpbm5lci1sZyAuc3Bpbm5lci1jaXJjbGUge1xcclxcbiAgd2lkdGg6IDIuNWVtO1xcclxcbiAgaGVpZ2h0OiAyLjVlbTtcXHJcXG59XFxyXFxuLnNwaW5uZXItZ3JpdGNvZGUuc3Bpbm5lci14bCAuc3Bpbm5lci1jaXJjbGUge1xcclxcbiAgd2lkdGg6IDMuNWVtO1xcclxcbiAgaGVpZ2h0OiAzLjVlbTtcXHJcXG59XFxyXFxuLmx0LWllMTAgLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItY2lyY2xlLFxcclxcbi5pZTkgLnNwaW5uZXItZ3JpdGNvZGUgLnNwaW5uZXItY2lyY2xlLFxcclxcbi5vbGRpZSAuc3Bpbm5lci1ncml0Y29kZSAuc3Bpbm5lci1jaXJjbGUsXFxyXFxuLm5vLWNzc3RyYW5zaXRpb25zIC5zcGlubmVyLWdyaXRjb2RlIC5zcGlubmVyLWNpcmNsZSxcXHJcXG4ubm8tY3NzdHJhbnNmb3JtczNkIC5zcGlubmVyLWdyaXRjb2RlIC5zcGlubmVyLWNpcmNsZSB7XFxyXFxuICBiYWNrZ3JvdW5kOiB1cmwoXFxcImh0dHA6Ly9pMi53cC5jb20vd3d3LnRoZWdyZWF0bm92ZWxpbmdhZHZlbnR1cmUuY29tL3dwLWNvbnRlbnQvcGx1Z2lucy93cC1wb2xscy9pbWFnZXMvbG9hZGluZy5naWZcXFwiKSBjZW50ZXIgY2VudGVyIG5vLXJlcGVhdDtcXHJcXG4gIGFuaW1hdGlvbjogbm9uZTtcXHJcXG4gIG1hcmdpbi1sZWZ0OiAwO1xcclxcbiAgbWFyZ2luLXRvcDogNXB4O1xcclxcbiAgYm9yZGVyOiBub25lO1xcclxcbiAgd2lkdGg6IDMycHg7XFxyXFxuICBoZWlnaHQ6IDMycHg7XFxyXFxufVxcclxcbjwvc3R5bGU+XFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXHRcblx0Ly8gZXhwb3J0c1xuXG5cbi8qKiovIH0sXG4vKiAxNjQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRcblx0dmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNjUpO1xuXHRcblx0dmFyIE1JTl9XQUlUID0gNTAwOyAvLyBpbiBtc1xuXHRcblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgZml4ZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGdsb2JhbDogeyB0eXBlOiBCb29sZWFuLCBkZWZhdWx0OiBmYWxzZSB9LFxuXHQgICAgc2l6ZTogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICdtZCcgfSxcblx0ICAgIHRleHQ6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnJyB9LFxuXHQgICAgdmFsdWU6IHsgZGVmYXVsdDogZmFsc2UgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIGFjdGl2ZTogdGhpcy52YWx1ZSxcblx0ICAgICAgbG9ja2VkOiBmYWxzZVxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICBjb21wdXRlZDoge1xuXHQgICAgc3Bpbm5lclNpemU6IGZ1bmN0aW9uIHNwaW5uZXJTaXplKCkge1xuXHQgICAgICByZXR1cm4gJ3NwaW5uZXItJyArICh0aGlzLnNpemUgPyB0aGlzLnNpemUgOiAnc20nKTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIHdhdGNoOiB7XG5cdCAgICBhY3RpdmU6IGZ1bmN0aW9uIGFjdGl2ZSh2YWwsIG9sZCkge1xuXHQgICAgICBpZiAodmFsICE9PSBvbGQpIHRoaXMuJGVtaXQoJ2lucHV0JywgdmFsKTtcblx0ICAgIH0sXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUodmFsLCBvbGQpIHtcblx0ICAgICAgaWYgKHZhbCAhPT0gb2xkKSB7XG5cdCAgICAgICAgdGhpc1t2YWwgPyAnc2hvdycgOiAnaGlkZSddKCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIGhpZGU6IGZ1bmN0aW9uIGhpZGUoKSB7XG5cdCAgICAgIHZhciBkZWxheSA9IDA7XG5cdCAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG5cdCAgICB9LFxuXHQgICAgc2hvdzogZnVuY3Rpb24gc2hvdyhvcHRpb25zKSB7XG5cdCAgICAgIGlmIChvcHRpb25zKSB7XG5cdCAgICAgICAgaWYgKG9wdGlvbnMudGV4dCkge1xuXHQgICAgICAgICAgdGhpcy50ZXh0ID0gb3B0aW9ucy50ZXh0O1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAob3B0aW9ucy5zaXplKSB7XG5cdCAgICAgICAgICB0aGlzLnNpemUgPSBvcHRpb25zLnNpemU7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChvcHRpb25zLmZpeGVkKSB7XG5cdCAgICAgICAgICB0aGlzLmZpeGVkID0gb3B0aW9ucy5maXhlZDtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgICAgLy8gYmxvY2sgc2Nyb2xsaW5nIHdoZW4gc3Bpbm5lciBpcyBvblxuXHQgICAgICB0aGlzLl9ib2R5LnN0eWxlLm92ZXJmbG93WSA9ICdoaWRkZW4nO1xuXHQgICAgICAvLyBhY3RpdmF0ZSBzcGlubmVyXG5cdCAgICAgIHRoaXMuX3N0YXJ0ZWQgPSBuZXcgRGF0ZSgpO1xuXHQgICAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG5cdCAgICAgIHRoaXMubG9ja2VkID0gdHJ1ZTtcblx0ICAgICAgdGhpcy5fdW5sb2NrKCk7XG5cdCAgICB9XG5cdCAgfSxcblx0ICBjcmVhdGVkOiBmdW5jdGlvbiBjcmVhdGVkKCkge1xuXHQgICAgdGhpcy5fYm9keSA9IGRvY3VtZW50LmJvZHk7XG5cdCAgICB0aGlzLl9ib2R5T3ZlcmZsb3cgPSBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93WTtcblx0ICAgIHRoaXMuX3VubG9jayA9ICgwLCBfdXRpbHMuZGVsYXllcikoZnVuY3Rpb24gKCkge1xuXHQgICAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xuXHQgICAgICB0aGlzLl9ib2R5LnN0eWxlLm92ZXJmbG93WSA9IHRoaXMuX2JvZHlPdmVyZmxvdztcblx0ICAgIH0sIE1JTl9XQUlUKTtcblx0ICAgIGlmICh0aGlzLmdsb2JhbCkge1xuXHQgICAgICBpZiAoIXRoaXMuJHJvb3QuX2dsb2JhbFNwaW5uZXIpIHtcblx0ICAgICAgICB0aGlzLiRyb290Ll9nbG9iYWxTcGlubmVyID0gdHJ1ZTtcblx0ICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cdCAgICAgICAgdGhpcy5fZ2xvYmFsID0ge1xuXHQgICAgICAgICAgaGlkZTogZnVuY3Rpb24gaGlkZSgpIHtcblx0ICAgICAgICAgICAgc2VsZi5oaWRlKCk7XG5cdCAgICAgICAgICB9LFxuXHQgICAgICAgICAgc2hvdzogZnVuY3Rpb24gc2hvdygpIHtcblx0ICAgICAgICAgICAgc2VsZi5zaG93KCk7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgICAgICB0aGlzLiRyb290LiRvbignc3Bpbm5lcjo6c2hvdycsIHRoaXMuX2dsb2JhbC5zaG93KTtcblx0ICAgICAgICB0aGlzLiRyb290LiRvbignc3Bpbm5lcjo6aGlkZScsIHRoaXMuX2dsb2JhbC5oaWRlKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0sXG5cdCAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24gYmVmb3JlRGVzdHJveSgpIHtcblx0ICAgIGlmICh0aGlzLl9nbG9iYWwpIHtcblx0ICAgICAgdGhpcy4kcm9vdC4kb2ZmKCdzcGlubmVyOjpzaG93JywgdGhpcy5fZ2xvYmFsLnNob3cpO1xuXHQgICAgICB0aGlzLiRyb290LiRvZmYoJ3NwaW5uZXI6OmhpZGUnLCB0aGlzLl9nbG9iYWwuaGlkZSk7XG5cdCAgICAgIGRlbGV0ZSB0aGlzLiRyb290Ll9nbG9iYWxTcGlubmVyO1xuXHQgICAgfVxuXHQgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3NwaW5uZXJBbmltYXRpb24pO1xuXHQgICAgdGhpcy5fYm9keS5zdHlsZS5vdmVyZmxvd1kgPSB0aGlzLl9ib2R5T3ZlcmZsb3c7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTY1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIGRpcmVjdGl2ZXM6IFt7XG5cdCAgICAgIG5hbWU6IFwic2hvd1wiLFxuXHQgICAgICByYXdOYW1lOiBcInYtc2hvd1wiLFxuXHQgICAgICB2YWx1ZTogKF92bS5hY3RpdmUgfHwgX3ZtLmxvY2tlZCksXG5cdCAgICAgIGV4cHJlc3Npb246IFwiYWN0aXZlfHxsb2NrZWRcIlxuXHQgICAgfV0sXG5cdCAgICBjbGFzczogWydzcGlubmVyIHNwaW5uZXItZ3JpdGNvZGUnLCBfdm0uc3Bpbm5lclNpemUsIHtcblx0ICAgICAgJ3NwaW5uZXItZml4ZWQnOiBfdm0uZml4ZWRcblx0ICAgIH1dXG5cdCAgfSwgW192bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwic3Bpbm5lci13cmFwcGVyXCJcblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJzcGlubmVyLWNpcmNsZVwiXG5cdCAgfSksIF92bS5fdihcIiBcIiksIF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwic3Bpbm5lci10ZXh0XCJcblx0ICB9LCBbX3ZtLl92KF92bS5fcyhfdm0udGV4dCkpXSldKV0pXG5cdH0sc3RhdGljUmVuZGVyRm5zOiBbXX1cblx0aWYgKGZhbHNlKSB7XG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LThiMjk4ZTcwXCIsIG1vZHVsZS5leHBvcnRzKVxuXHQgIH1cblx0fVxuXG4vKioqLyB9LFxuLyogMTY2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgX192dWVfZXhwb3J0c19fLCBfX3Z1ZV9vcHRpb25zX19cblx0dmFyIF9fdnVlX3N0eWxlc19fID0ge31cblx0XG5cdC8qIHNjcmlwdCAqL1xuXHRfX3Z1ZV9leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2Nylcblx0XG5cdC8qIHRlbXBsYXRlICovXG5cdHZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNjgpXG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuXHRpZiAoXG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcblx0KSB7XG5cdGlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxuXHR9XG5cdGlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcblx0ICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xuXHR9XG5cdF9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIkM6XFxcXGxhcmFnb25cXFxcd3d3XFxcXHZ1ZS1zdHJhcFxcXFxzcmNcXFxcVGFiLnZ1ZVwiXG5cdF9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuXHRfX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblx0XG5cdC8qIGhvdCByZWxvYWQgKi9cblx0aWYgKGZhbHNlKSB7KGZ1bmN0aW9uICgpIHtcblx0ICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuXHQgIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuXHQgIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi0wOTg1ZTg3OFwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfSBlbHNlIHtcblx0ICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtMDk4NWU4NzhcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH1cblx0fSkoKX1cblx0aWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBUYWIudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTY3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgZGlzYWJsZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGhlYWRlcjogeyB0eXBlOiBTdHJpbmcgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIGZhZGVpbjogZmFsc2Vcblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgY29tcHV0ZWQ6IHtcblx0ICAgIGFjdGl2ZTogZnVuY3Rpb24gYWN0aXZlKCkge1xuXHQgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgdmFyIGFjdGl2ZSA9ICF0aGlzLl90YWJzIHx8IHRoaXMuX3RhYnMuc2hvdyA9PT0gdGhpcztcblx0ICAgICAgdGhpcy5mYWRlaW4gPSBmYWxzZTtcblx0ICAgICAgaWYgKGFjdGl2ZSkge1xuXHQgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgX3RoaXMuZmFkZWluID0gdHJ1ZTtcblx0ICAgICAgICB9LCAwKTtcblx0ICAgICAgfVxuXHQgICAgICByZXR1cm4gYWN0aXZlO1xuXHQgICAgfSxcblx0ICAgIGluZGV4OiBmdW5jdGlvbiBpbmRleCgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuX3RhYnMudGFicy5pbmRleE9mKHRoaXMpO1xuXHQgICAgfSxcblx0ICAgIHRyYW5zaXRpb246IGZ1bmN0aW9uIHRyYW5zaXRpb24oKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLl90YWJzID8gdGhpcy5fdGFicy5lZmZlY3QgOiBudWxsO1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIHRoaXMuX2lzVGFiID0gdHJ1ZTtcblx0ICAgIHZhciB0YWJzID0gdGhpcztcblx0ICAgIHdoaWxlICghdGhpcy5fdGFicyAmJiB0YWJzLiRwYXJlbnQpIHtcblx0ICAgICAgaWYgKHRhYnMuX2lzVGFiR3JvdXApIHtcblx0ICAgICAgICB0YWJzLnRhYnMucHVzaCh0aGlzKTtcblx0ICAgICAgICB0aGlzLl90YWJHcm91cCA9IHRhYnM7XG5cdCAgICAgIH1cblx0ICAgICAgaWYgKHRhYnMuX2lzVGFicykge1xuXHQgICAgICAgIHRhYnMudGFicy5wdXNoKHRoaXMpO1xuXHQgICAgICAgIHRoaXMuX3RhYnMgPSB0YWJzO1xuXHQgICAgICAgIGlmICghdGhpcy5fdGFiR3JvdXApIHRhYnMuaGVhZGVycy5wdXNoKHRoaXMpO1xuXHQgICAgICB9XG5cdCAgICAgIHRhYnMgPSB0YWJzLiRwYXJlbnQ7XG5cdCAgICB9XG5cdCAgICBpZiAoIXRoaXMuX3RhYnMpIHRocm93IEVycm9yKCd0YWIgZGVwZW5kIG9uIHRhYnMuJyk7XG5cdCAgfSxcblx0ICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbiBiZWZvcmVEZXN0cm95KCkge1xuXHQgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cdFxuXHQgICAgaWYgKHRoaXMuX3RhYkdyb3VwKSB7XG5cdCAgICAgIHRoaXMuX3RhYkdyb3VwLnRhYnMgPSB0aGlzLl90YWJHcm91cC50YWJzLmZpbHRlcihmdW5jdGlvbiAoZWwpIHtcblx0ICAgICAgICByZXR1cm4gZWwgIT09IF90aGlzMjtcblx0ICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBpZiAodGhpcy5fdGFicykge1xuXHQgICAgICB0aGlzLl90YWJzLnRhYnMgPSB0aGlzLl90YWJzLnRhYnMuZmlsdGVyKGZ1bmN0aW9uIChlbCkge1xuXHQgICAgICAgIHJldHVybiBlbCAhPT0gX3RoaXMyO1xuXHQgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIGlmICh0aGlzLl90YWJzKSB7XG5cdCAgICAgIGlmICh0aGlzLl90YWJzLmFjdGl2ZSA9PT0gdGhpcy5pbmRleCkge1xuXHQgICAgICAgIHRoaXMuX3RhYnMuaW5kZXggPSAwO1xuXHQgICAgICB9XG5cdCAgICAgIGlmICh0aGlzLl9pbmdyb3VwKSB7XG5cdCAgICAgICAgdmFyIGlkID0gdGhpcy4kcGFyZW50LnRhYnMuaW5kZXhPZih0aGlzKTtcblx0ICAgICAgICBpZiAofmlkKSB0aGlzLiRwYXJlbnQudGFicy5zcGxpY2UoaWQsIDEpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgICBpZiAodGhpcy5fdGFicykge1xuXHQgICAgICB2YXIgX2lkID0gdGhpcy5fdGFicy50YWJzLmluZGV4T2YodGhpcyk7XG5cdCAgICAgIGlmICh+X2lkKSB0aGlzLl90YWJzLnRhYnMuc3BsaWNlKF9pZCwgMSk7XG5cdCAgICB9XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTY4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHJlZjogXCJwYW5lbFwiLFxuXHQgICAgY2xhc3M6IFsndGFiLXBhbmUnLCB7XG5cdCAgICAgICdhY3RpdmUgZmFkZSc6IF92bS5hY3RpdmUsXG5cdCAgICAgICdpbic6IF92bS5mYWRlaW5cblx0ICAgIH1dLFxuXHQgICAgYXR0cnM6IHtcblx0ICAgICAgXCJyb2xlXCI6IFwidGFicGFuZWxcIlxuXHQgICAgfVxuXHQgIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMilcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMDk4NWU4NzhcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxNjkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc3R5bGVzICovXG5cdF9fd2VicGFja19yZXF1aXJlX18oMTcwKVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTcyKVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE3Mylcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxUYWJHcm91cC52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNTVmYWYzY2JcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTU1ZmFmM2NiXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gVGFiR3JvdXAudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTcwICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNzEpO1xuXHRpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcblx0Ly8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxuXHR2YXIgdXBkYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OSkoY29udGVudCwge30pO1xuXHRpZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcblx0Ly8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuXHRpZihmYWxzZSkge1xuXHRcdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTU1ZmFmM2NiIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9UYWJHcm91cC52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTU1ZmFmM2NiIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9UYWJHcm91cC52dWVcIik7XG5cdFx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xuXHR9XG5cbi8qKiovIH0sXG4vKiAxNzEgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oNzgpKCk7XG5cdC8vIGltcG9ydHNcblx0XG5cdFxuXHQvLyBtb2R1bGVcblx0ZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuLnRhYi1jb250ZW50IC50YWItcGFuZSB7IGRpc3BsYXk6IG5vbmU7XFxufVxcbi50YWItY29udGVudCAudGFiLXBhbmUuYWN0aXZlIHsgZGlzcGxheTogYmxvY2s7XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvVGFiR3JvdXAudnVlPzIyYWUxYzA4XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFrQ0EseUJBQUEsY0FBQTtDQUFBO0FBQ0EsZ0NBQUEsZUFBQTtDQUFBXCIsXCJmaWxlXCI6XCJUYWJHcm91cC52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHRlbXBsYXRlPjxzcGFuPjxzbG90Pjwvc2xvdD48L3NwYW4+PC90ZW1wbGF0ZT5cXHJcXG5cXHJcXG48c2NyaXB0PlxcclxcbmV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gIHByb3BzOiB7XFxyXFxuICAgIGRpc2FibGVkOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBoZWFkZXI6IHt0eXBlOiBTdHJpbmd9XFxyXFxuICB9LFxcclxcbiAgZGF0YSAoKSB7XFxyXFxuICAgIHJldHVybiB7XFxyXFxuICAgICAgc2hvdzogZmFsc2UsXFxyXFxuICAgICAgdGFiczogW11cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGNvbXB1dGVkOiB7XFxyXFxuICAgIGFjdGl2ZSAoKSB7IHJldHVybiB+dGhpcy50YWJzLmluZGV4T2YodGhpcy5fdGFicy5zaG93KSB9XFxyXFxuICB9LFxcclxcbiAgbWV0aG9kczoge1xcclxcbiAgICBibHVyICgpIHsgdGhpcy5zaG93ID0gZmFsc2UgfSxcXHJcXG4gICAgdG9nZ2xlICgpIHsgdGhpcy5zaG93ID0gIXRoaXMuc2hvdyB9XFxyXFxuICB9LFxcclxcbiAgY3JlYXRlZCAoKSB7XFxyXFxuICAgIHRoaXMuX2lzVGFiR3JvdXAgPSB0cnVlXFxyXFxuICAgIGlmICh0aGlzLiRwYXJlbnQpIHtcXHJcXG4gICAgICBpZiAodGhpcy4kcGFyZW50Ll9pc1RhYkdyb3VwKSB0aHJvdyBFcnJvcignQ2FuXFxcXCd0IG5lc3QgdGFiLWdyb3Vwcy4nKVxcclxcbiAgICAgIGlmICghdGhpcy4kcGFyZW50Ll9pc1RhYnMpIHRocm93IEVycm9yKCd0YWItZ3JvdXAgZGVwZW5kIG9uIHRhYnMuJylcXHJcXG4gICAgfVxcclxcbiAgICB0aGlzLl90YWJzID0gdGhpcy4kcGFyZW50XFxyXFxuICAgIHRoaXMuX3RhYnMuaGVhZGVycy5wdXNoKHRoaXMpXFxyXFxuICB9XFxyXFxufVxcclxcbjwvc2NyaXB0PlxcclxcblxcclxcbjxzdHlsZT5cXHJcXG4udGFiLWNvbnRlbnQgLnRhYi1wYW5lIHsgZGlzcGxheTogbm9uZTsgfVxcclxcbi50YWItY29udGVudCAudGFiLXBhbmUuYWN0aXZlIHsgZGlzcGxheTogYmxvY2s7IH1cXHJcXG48L3N0eWxlPlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogMTcyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0Ly9cblx0Ly9cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgZGlzYWJsZWQ6IHsgdHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2UgfSxcblx0ICAgIGhlYWRlcjogeyB0eXBlOiBTdHJpbmcgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIHNob3c6IGZhbHNlLFxuXHQgICAgICB0YWJzOiBbXVxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICBjb21wdXRlZDoge1xuXHQgICAgYWN0aXZlOiBmdW5jdGlvbiBhY3RpdmUoKSB7XG5cdCAgICAgIHJldHVybiB+dGhpcy50YWJzLmluZGV4T2YodGhpcy5fdGFicy5zaG93KTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIGJsdXI6IGZ1bmN0aW9uIGJsdXIoKSB7XG5cdCAgICAgIHRoaXMuc2hvdyA9IGZhbHNlO1xuXHQgICAgfSxcblx0ICAgIHRvZ2dsZTogZnVuY3Rpb24gdG9nZ2xlKCkge1xuXHQgICAgICB0aGlzLnNob3cgPSAhdGhpcy5zaG93O1xuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIHRoaXMuX2lzVGFiR3JvdXAgPSB0cnVlO1xuXHQgICAgaWYgKHRoaXMuJHBhcmVudCkge1xuXHQgICAgICBpZiAodGhpcy4kcGFyZW50Ll9pc1RhYkdyb3VwKSB0aHJvdyBFcnJvcignQ2FuXFwndCBuZXN0IHRhYi1ncm91cHMuJyk7XG5cdCAgICAgIGlmICghdGhpcy4kcGFyZW50Ll9pc1RhYnMpIHRocm93IEVycm9yKCd0YWItZ3JvdXAgZGVwZW5kIG9uIHRhYnMuJyk7XG5cdCAgICB9XG5cdCAgICB0aGlzLl90YWJzID0gdGhpcy4kcGFyZW50O1xuXHQgICAgdGhpcy5fdGFicy5oZWFkZXJzLnB1c2godGhpcyk7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTczICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ3NwYW4nLCBbX3ZtLl90KFwiZGVmYXVsdFwiKV0sIDIpXG5cdH0sc3RhdGljUmVuZGVyRm5zOiBbXX1cblx0aWYgKGZhbHNlKSB7XG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LTU1ZmFmM2NiXCIsIG1vZHVsZS5leHBvcnRzKVxuXHQgIH1cblx0fVxuXG4vKioqLyB9LFxuLyogMTc0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgX192dWVfZXhwb3J0c19fLCBfX3Z1ZV9vcHRpb25zX19cblx0dmFyIF9fdnVlX3N0eWxlc19fID0ge31cblx0XG5cdC8qIHN0eWxlcyAqL1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDE3NSlcblx0XG5cdC8qIHNjcmlwdCAqL1xuXHRfX3Z1ZV9leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE3Nylcblx0XG5cdC8qIHRlbXBsYXRlICovXG5cdHZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNzgpXG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuXHRpZiAoXG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG5cdCAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcblx0KSB7XG5cdGlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxuXHR9XG5cdGlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcblx0ICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xuXHR9XG5cdF9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIkM6XFxcXGxhcmFnb25cXFxcd3d3XFxcXHZ1ZS1zdHJhcFxcXFxzcmNcXFxcVGFicy52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNzAxMDBkZGZcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTcwMTAwZGRmXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gVGFicy52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IF9fdnVlX2V4cG9ydHNfX1xuXG5cbi8qKiovIH0sXG4vKiAxNzUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cdFxuXHQvLyBsb2FkIHRoZSBzdHlsZXNcblx0dmFyIGNvbnRlbnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE3Nik7XG5cdGlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuXHQvLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG5cdHZhciB1cGRhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc5KShjb250ZW50LCB7fSk7XG5cdGlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuXHQvLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5cdGlmKGZhbHNlKSB7XG5cdFx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNzAxMDBkZGYhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL1RhYnMudnVlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi03MDEwMGRkZiEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vVGFicy52dWVcIik7XG5cdFx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRcdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xuXHR9XG5cbi8qKiovIH0sXG4vKiAxNzYgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oNzgpKCk7XG5cdC8vIGltcG9ydHNcblx0XG5cdFxuXHQvLyBtb2R1bGVcblx0ZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuW3RhYnNdID4gLnRhYi1jb250ZW50IHtcXHJcXG4gIG1hcmdpbjogMTVweCAwO1xcbn1cXHJcXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL1RhYnMudnVlPzQzMTdiOWFmXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUEwRUE7RUFDQSxlQUFBO0NBQ0FcIixcImZpbGVcIjpcIlRhYnMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxkaXYgdGFicz5cXHJcXG4gICAgPHVsIDpjbGFzcz1cXFwibmF2U3R5bGVDbGFzc1xcXCIgcm9sZT1cXFwidGFibGlzdFxcXCI+XFxyXFxuICAgICAgPHRlbXBsYXRlIHYtZm9yPVxcXCJoZWFkZXIgaW4gaGVhZGVyc1xcXCI+XFxyXFxuICAgICAgICA8bGkgdi1pZj1cXFwiaGVhZGVyLl9pc1RhYlxcXCIgOmNsYXNzPVxcXCJ7YWN0aXZlOmhlYWRlci5hY3RpdmUsIGRpc2FibGVkOmhlYWRlci5kaXNhYmxlZH1cXFwiIEBjbGljay5wcmV2ZW50PVxcXCJzZWxlY3QoaGVhZGVyKVxcXCI+XFxyXFxuICAgICAgICAgIDxzbG90IG5hbWU9XFxcImhlYWRlclxcXCI+PGEgaHJlZj1cXFwiI1xcXCIgdi1odG1sPVxcXCJoZWFkZXIuaGVhZGVyXFxcIj48L2E+PC9zbG90PlxcclxcbiAgICAgICAgPC9saT5cXHJcXG4gICAgICAgIDxkcm9wZG93biB2LWlmPVxcXCJoZWFkZXIuX2lzVGFiR3JvdXBcXFwiIDp0ZXh0PVxcXCJoZWFkZXIuaGVhZGVyXFxcIiA6Y2xhc3M9XFxcInthY3RpdmU6aGVhZGVyLmFjdGl2ZX1cXFwiIDpkaXNhYmxlZD1cXFwiaGVhZGVyLmRpc2FibGVkXFxcIj5cXHJcXG4gICAgICAgICAgPGxpIHYtZm9yPVxcXCJ0YWIgaW4gaGVhZGVyLnRhYnNcXFwiIDpjbGFzcz1cXFwie2Rpc2FibGVkOnRhYi5kaXNhYmxlZH1cXFwiPjxhIGhyZWY9XFxcIiNcXFwiIEBjbGljay5wcmV2ZW50PVxcXCJzZWxlY3QodGFiKVxcXCI+e3t0YWIuaGVhZGVyfX08L2E+PC9saT5cXHJcXG4gICAgICAgIDwvZHJvcGRvd24+XFxyXFxuICAgICAgPC90ZW1wbGF0ZT5cXHJcXG4gICAgPC91bD5cXHJcXG4gICAgPGRpdiBjbGFzcz1cXFwidGFiLWNvbnRlbnRcXFwiPjxzbG90Pjwvc2xvdD48L2Rpdj5cXHJcXG4gIDwvZGl2PlxcclxcbjwvdGVtcGxhdGU+XFxyXFxuXFxyXFxuPHNjcmlwdD5cXHJcXG5pbXBvcnQge2NvZXJjZX0gZnJvbSAnLi91dGlscy91dGlscy5qcydcXHJcXG5pbXBvcnQgZHJvcGRvd24gZnJvbSAnLi9Ecm9wZG93bi52dWUnXFxyXFxuXFxyXFxuZXhwb3J0IGRlZmF1bHQge1xcclxcbiAgY29tcG9uZW50czoge1xcclxcbiAgICBkcm9wZG93blxcclxcbiAgfSxcXHJcXG4gIHByb3BzOiB7XFxyXFxuICAgIC8vIGVmZmVjdDoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogJ2ZhZGVpbid9LFxcclxcbiAgICBqdXN0aWZpZWQ6IGZhbHNlLFxcclxcbiAgICBuYXZTdHlsZToge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIHZhbHVlOiB7dHlwZTogTnVtYmVyLCBkZWZhdWx0OiAwfVxcclxcbiAgfSxcXHJcXG4gIGRhdGEgKCkge1xcclxcbiAgICB2YXIgaW5kZXggPSB0aGlzLnZhbHVlIHx8IDBcXHJcXG4gICAgcmV0dXJuIHtcXHJcXG4gICAgICBpbmRleCxcXHJcXG4gICAgICBoZWFkZXJzOiBbXSxcXHJcXG4gICAgICB0YWJzOiBbXVxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgd2F0Y2g6IHtcXHJcXG4gICAgaW5kZXggKHZhbCkge1xcclxcbiAgICAgIHRoaXMuJGVtaXQoJ2FjdGl2ZScsIHZhbClcXHJcXG4gICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbClcXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsdWUgKHZhbCkge1xcclxcbiAgICAgIHRoaXMuaW5kZXggPSB2YWxcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGNvbXB1dGVkOiB7XFxyXFxuICAgIG5hdlN0eWxlQ2xhc3MgKCkge1xcclxcbiAgICAgIHJldHVybiBbXFxyXFxuICAgICAgICAnbmF2JyxcXHJcXG4gICAgICAgIH5bJ3BpbGxzJywgJ3N0YWNrZWQnXS5pbmRleE9mKHRoaXMubmF2U3R5bGUpID8gJ25hdi0nICsgdGhpcy5uYXZTdHlsZSA6ICduYXYtdGFicycsXFxyXFxuICAgICAgICB7XFxyXFxuICAgICAgICAgICduYXYtanVzdGlmaWVkJzogY29lcmNlLmJvb2xlYW4odGhpcy5qdXN0aWZpZWQpLFxcclxcbiAgICAgICAgICAnbmF2LXBpbGxzJzogdGhpcy5uYXZTdHlsZSA9PT0gJ3N0YWNrZWQnXFxyXFxuICAgICAgICB9XFxyXFxuICAgICAgXVxcclxcbiAgICB9LFxcclxcbiAgICBzaG93ICgpIHsgcmV0dXJuIHRoaXMudGFic1t0aGlzLmluZGV4XSB8fCB0aGlzLnRhYnNbMF0gfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgc2VsZWN0ICh0YWIpIHtcXHJcXG4gICAgICBpZiAoIXRhYi5kaXNhYmxlZCkge1xcclxcbiAgICAgICAgdGhpcy5pbmRleCA9IHRoaXMudGFicy5pbmRleE9mKHRhYilcXHJcXG4gICAgICB9XFxyXFxuICAgIH1cXHJcXG4gIH0sXFxyXFxuICBjcmVhdGVkICgpIHtcXHJcXG4gICAgdGhpcy5faXNUYWJzID0gdHJ1ZVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGU+XFxyXFxuW3RhYnNdID4gLnRhYi1jb250ZW50IHtcXHJcXG4gIG1hcmdpbjogMTVweCAwO1xcclxcbn1cXHJcXG48L3N0eWxlPlwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogMTc3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDY1KTtcblx0XG5cdHZhciBfRHJvcGRvd24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEwNSk7XG5cdFxuXHR2YXIgX0Ryb3Bkb3duMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0Ryb3Bkb3duKTtcblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cdFxuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0ge1xuXHQgIGNvbXBvbmVudHM6IHtcblx0ICAgIGRyb3Bkb3duOiBfRHJvcGRvd24yLmRlZmF1bHRcblx0ICB9LFxuXHQgIHByb3BzOiB7XG5cdCAgICAvLyBlZmZlY3Q6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICdmYWRlaW4nfSxcblx0ICAgIGp1c3RpZmllZDogZmFsc2UsXG5cdCAgICBuYXZTdHlsZTogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIHZhbHVlOiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogMCB9XG5cdCAgfSxcblx0ICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuXHQgICAgdmFyIGluZGV4ID0gdGhpcy52YWx1ZSB8fCAwO1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgaW5kZXg6IGluZGV4LFxuXHQgICAgICBoZWFkZXJzOiBbXSxcblx0ICAgICAgdGFiczogW11cblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgd2F0Y2g6IHtcblx0ICAgIGluZGV4OiBmdW5jdGlvbiBpbmRleCh2YWwpIHtcblx0ICAgICAgdGhpcy4kZW1pdCgnYWN0aXZlJywgdmFsKTtcblx0ICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCB2YWwpO1xuXHQgICAgfSxcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZSh2YWwpIHtcblx0ICAgICAgdGhpcy5pbmRleCA9IHZhbDtcblx0ICAgIH1cblx0ICB9LFxuXHQgIGNvbXB1dGVkOiB7XG5cdCAgICBuYXZTdHlsZUNsYXNzOiBmdW5jdGlvbiBuYXZTdHlsZUNsYXNzKCkge1xuXHQgICAgICByZXR1cm4gWyduYXYnLCB+WydwaWxscycsICdzdGFja2VkJ10uaW5kZXhPZih0aGlzLm5hdlN0eWxlKSA/ICduYXYtJyArIHRoaXMubmF2U3R5bGUgOiAnbmF2LXRhYnMnLCB7XG5cdCAgICAgICAgJ25hdi1qdXN0aWZpZWQnOiBfdXRpbHMuY29lcmNlLmJvb2xlYW4odGhpcy5qdXN0aWZpZWQpLFxuXHQgICAgICAgICduYXYtcGlsbHMnOiB0aGlzLm5hdlN0eWxlID09PSAnc3RhY2tlZCdcblx0ICAgICAgfV07XG5cdCAgICB9LFxuXHQgICAgc2hvdzogZnVuY3Rpb24gc2hvdygpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudGFic1t0aGlzLmluZGV4XSB8fCB0aGlzLnRhYnNbMF07XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtZXRob2RzOiB7XG5cdCAgICBzZWxlY3Q6IGZ1bmN0aW9uIHNlbGVjdCh0YWIpIHtcblx0ICAgICAgaWYgKCF0YWIuZGlzYWJsZWQpIHtcblx0ICAgICAgICB0aGlzLmluZGV4ID0gdGhpcy50YWJzLmluZGV4T2YodGFiKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0sXG5cdCAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCgpIHtcblx0ICAgIHRoaXMuX2lzVGFicyA9IHRydWU7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTc4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidGFic1wiOiBcIlwiXG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygndWwnLCB7XG5cdCAgICBjbGFzczogX3ZtLm5hdlN0eWxlQ2xhc3MsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcInJvbGVcIjogXCJ0YWJsaXN0XCJcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9sKChfdm0uaGVhZGVycyksIGZ1bmN0aW9uKGhlYWRlcikge1xuXHQgICAgcmV0dXJuIFsoaGVhZGVyLl9pc1RhYikgPyBfdm0uX2MoJ2xpJywge1xuXHQgICAgICBjbGFzczoge1xuXHQgICAgICAgIGFjdGl2ZTogaGVhZGVyLmFjdGl2ZSwgZGlzYWJsZWQ6IGhlYWRlci5kaXNhYmxlZFxuXHQgICAgICB9LFxuXHQgICAgICBvbjoge1xuXHQgICAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICAgIF92bS5zZWxlY3QoaGVhZGVyKVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSwgW192bS5fdChcImhlYWRlclwiLCBbX3ZtLl9jKCdhJywge1xuXHQgICAgICBhdHRyczoge1xuXHQgICAgICAgIFwiaHJlZlwiOiBcIiNcIlxuXHQgICAgICB9LFxuXHQgICAgICBkb21Qcm9wczoge1xuXHQgICAgICAgIFwiaW5uZXJIVE1MXCI6IF92bS5fcyhoZWFkZXIuaGVhZGVyKVxuXHQgICAgICB9XG5cdCAgICB9KV0pXSwgMikgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgKGhlYWRlci5faXNUYWJHcm91cCkgPyBfdm0uX2MoJ2Ryb3Bkb3duJywge1xuXHQgICAgICBjbGFzczoge1xuXHQgICAgICAgIGFjdGl2ZTogaGVhZGVyLmFjdGl2ZVxuXHQgICAgICB9LFxuXHQgICAgICBhdHRyczoge1xuXHQgICAgICAgIFwidGV4dFwiOiBoZWFkZXIuaGVhZGVyLFxuXHQgICAgICAgIFwiZGlzYWJsZWRcIjogaGVhZGVyLmRpc2FibGVkXG5cdCAgICAgIH1cblx0ICAgIH0sIF92bS5fbCgoaGVhZGVyLnRhYnMpLCBmdW5jdGlvbih0YWIpIHtcblx0ICAgICAgcmV0dXJuIF92bS5fYygnbGknLCB7XG5cdCAgICAgICAgY2xhc3M6IHtcblx0ICAgICAgICAgIGRpc2FibGVkOiB0YWIuZGlzYWJsZWRcblx0ICAgICAgICB9XG5cdCAgICAgIH0sIFtfdm0uX2MoJ2EnLCB7XG5cdCAgICAgICAgYXR0cnM6IHtcblx0ICAgICAgICAgIFwiaHJlZlwiOiBcIiNcIlxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgb246IHtcblx0ICAgICAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICAgICAgICBfdm0uc2VsZWN0KHRhYilcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH0sIFtfdm0uX3YoX3ZtLl9zKHRhYi5oZWFkZXIpKV0pXSlcblx0ICAgIH0pKSA6IF92bS5fZSgpXVxuXHQgIH0pXSwgMiksIF92bS5fdihcIiBcIiksIF92bS5fYygnZGl2Jywge1xuXHQgICAgc3RhdGljQ2xhc3M6IFwidGFiLWNvbnRlbnRcIlxuXHQgIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMildKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi03MDEwMGRkZlwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDE3OSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxODApXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTgxKVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXFRvZ2dsZUJ1dHRvbi52dWVcIlxuXHRfX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcblx0X192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cdFxuXHQvKiBob3QgcmVsb2FkICovXG5cdGlmIChmYWxzZSkgeyhmdW5jdGlvbiAoKSB7XG5cdCAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcblx0ICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcblx0ICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcblx0ICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtZjAzNGE1ZjJcIiwgX192dWVfb3B0aW9uc19fKVxuXHQgIH0gZWxzZSB7XG5cdCAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LWYwMzRhNWYyXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9XG5cdH0pKCl9XG5cdGlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gVG9nZ2xlQnV0dG9uLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuLyoqKi8gfSxcbi8qIDE4MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG5cdCAgdmFsdWU6IHRydWVcblx0fSk7XG5cdFxuXHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2NSk7XG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgcHJvcHM6IHtcblx0ICAgIGRpc2FibGVkOiB7IGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIGZhbHNlVHlwZTogeyBkZWZhdWx0OiBudWxsIH0sXG5cdCAgICBuYW1lOiBudWxsLFxuXHQgICAgcmVhZG9ubHk6IHsgZGVmYXVsdDogbnVsbCB9LFxuXHQgICAgdHJ1ZVR5cGU6IHsgZGVmYXVsdDogJ3ByaW1hcnknIH0sXG5cdCAgICB2YWx1ZTogZmFsc2Vcblx0ICB9LFxuXHQgIGRhdGE6IGZ1bmN0aW9uIGRhdGEoKSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBhY3RpdmU6IF91dGlscy5jb2VyY2UuYm9vbGVhbih0aGlzLnZhbHVlKSxcblx0ICAgICAgdHlwZXM6IHtcblx0ICAgICAgICBkYW5nZXI6ICdidG4tZGFuZ2VyJyxcblx0ICAgICAgICBpbmZvOiAnYnRuLWluZm8nLFxuXHQgICAgICAgIHByaW1hcnk6ICdidG4tcHJpbWFyeScsXG5cdCAgICAgICAgc3VjY2VzczogJ2J0bi1zdWNjZXNzJyxcblx0ICAgICAgICB3YXJuaW5nOiAnYnRuLXdhcm5pbmcnXG5cdCAgICAgIH1cblx0ICAgIH07XG5cdCAgfSxcblx0XG5cdCAgd2F0Y2g6IHtcblx0ICAgIGFjdGl2ZTogZnVuY3Rpb24gYWN0aXZlKHZhbCwgb2xkKSB7XG5cdCAgICAgIGlmICh2YWwgIT09IG9sZCkge1xuXHQgICAgICAgIHRoaXMuJGVtaXQoJ2NoYW5nZWQnLCB2YWwpO1xuXHQgICAgICAgIHRoaXMuJGVtaXQodmFsID8gJ2VuYWJsZWQnIDogJ2Rpc2FibGVkJyk7XG5cdCAgICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCB2YWwpO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKHZhbCwgb2xkKSB7XG5cdCAgICAgIGlmICh2YWwgIT09IG9sZCkge1xuXHQgICAgICAgIHRoaXMuYWN0aXZlID0gX3V0aWxzLmNvZXJjZS5ib29sZWFuKHRoaXMudmFsdWUpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBjb21wdXRlZDoge1xuXHQgICAgYm9vbERpc2FibGVkOiBmdW5jdGlvbiBib29sRGlzYWJsZWQoKSB7XG5cdCAgICAgIHJldHVybiBfdXRpbHMuY29lcmNlLmJvb2xlYW4odGhpcy5kaXNhYmxlZCk7XG5cdCAgICB9LFxuXHQgICAgYm9vbFJlYWRvbmx5OiBmdW5jdGlvbiBib29sUmVhZG9ubHkoKSB7XG5cdCAgICAgIHJldHVybiBfdXRpbHMuY29lcmNlLmJvb2xlYW4odGhpcy5yZWFkb25seSk7XG5cdCAgICB9LFxuXHQgICAgdHlwZTogZnVuY3Rpb24gdHlwZSgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudHlwZXNbdGhpcy52YWx1ZSA/IHRoaXMudHJ1ZVR5cGUgOiB0aGlzLmZhbHNlVHlwZV0gfHwgJ2J0bi1kZWZhdWx0Jztcblx0ICAgIH1cblx0ICB9LFxuXHQgIG1ldGhvZHM6IHtcblx0ICAgIHRvZ2dsZTogZnVuY3Rpb24gdG9nZ2xlKCkge1xuXHQgICAgICBpZiAodGhpcy5ib29sRGlzYWJsZWQgfHwgdGhpcy5ib29sUmVhZG9ubHkpIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICAgIH1cblx0ICAgICAgdGhpcy5hY3RpdmUgPSAhdGhpcy5hY3RpdmU7XG5cdCAgICB9XG5cdCAgfVxuXHR9OyAvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXG4vKioqLyB9LFxuLyogMTgxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ2EnLCB7XG5cdCAgICBjbGFzczogWydidG4nLCBfdm0udHlwZSwge1xuXHQgICAgICByZWFkb25seTogX3ZtLmJvb2xSZWFkb25seVxuXHQgICAgfV0sXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImhyZWZcIjogXCJqYXZhc2NyaXB0OnZvaWQoMClcIixcblx0ICAgICAgXCJkaXNhYmxlZFwiOiBfdm0uYm9vbERpc2FibGVkXG5cdCAgICB9LFxuXHQgICAgb246IHtcblx0ICAgICAgXCJjbGlja1wiOiBfdm0udG9nZ2xlXG5cdCAgICB9XG5cdCAgfSwgW192bS5fYygnc3BhbicsIHtcblx0ICAgIGNsYXNzOiBbJ2dseXBoaWNvbicsICdnbHlwaGljb24tJyArIChfdm0udmFsdWUgPyAnb2snIDogJ3JlbW92ZScpXVxuXHQgIH0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX3QoXCJkZWZhdWx0XCIpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLm5hbWUpID8gX3ZtLl9jKCdpbnB1dCcsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwidHlwZVwiOiBcImhpZGRlblwiLFxuXHQgICAgICBcIm5hbWVcIjogX3ZtLm5hbWVcblx0ICAgIH0sXG5cdCAgICBkb21Qcm9wczoge1xuXHQgICAgICBcInZhbHVlXCI6IF92bS5hY3RpdmUgPyAxIDogMFxuXHQgICAgfVxuXHQgIH0pIDogX3ZtLl9lKCldLCAyKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1mMDM0YTVmMlwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfSxcbi8qIDE4MiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cdHZhciBfX3Z1ZV9zdHlsZXNfXyA9IHt9XG5cdFxuXHQvKiBzdHlsZXMgKi9cblx0X193ZWJwYWNrX3JlcXVpcmVfXygxODMpXG5cdFxuXHQvKiBzY3JpcHQgKi9cblx0X192dWVfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygxODUpXG5cdFxuXHQvKiB0ZW1wbGF0ZSAqL1xuXHR2YXIgX192dWVfdGVtcGxhdGVfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTg2KVxuXHRfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cblx0aWYgKFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuXHQgIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRpZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcblx0fVxuXHRpZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcblx0fVxuXHRfX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxsYXJhZ29uXFxcXHd3d1xcXFx2dWUtc3RyYXBcXFxcc3JjXFxcXFRvb2x0aXAudnVlXCJcblx0X192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5cdF9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTQ4ZmI1MWIyXCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi00OGZiNTFiMlwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIFRvb2x0aXAudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXHRcblx0bW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG4vKioqLyB9LFxuLyogMTgzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXHRcblx0Ly8gbG9hZCB0aGUgc3R5bGVzXG5cdHZhciBjb250ZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxODQpO1xuXHRpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcblx0Ly8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxuXHR2YXIgdXBkYXRlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3OSkoY29udGVudCwge30pO1xuXHRpZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcblx0Ly8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuXHRpZihmYWxzZSkge1xuXHRcdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdFx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTQ4ZmI1MWIyIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9Ub29sdGlwLnZ1ZVwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNDhmYjUxYjIhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL1Rvb2x0aXAudnVlXCIpO1xuXHRcdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcblx0fVxuXG4vKioqLyB9LFxuLyogMTg0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc4KSgpO1xuXHQvLyBpbXBvcnRzXG5cdFxuXHRcblx0Ly8gbW9kdWxlXG5cdGV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi50b29sdGlwLnRvcCxcXHJcXG4udG9vbHRpcC5sZWZ0LFxcclxcbi50b29sdGlwLnJpZ2h0LFxcclxcbi50b29sdGlwLmJvdHRvbSB7XFxyXFxuICBvcGFjaXR5OiAuOTtcXG59XFxuLmZhZGVpbi1lbnRlciB7XFxyXFxuICBhbmltYXRpb246ZmFkZWluLWluIDAuM3MgZWFzZS1pbjtcXG59XFxuLmZhZGVpbi1sZWF2ZS1hY3RpdmUge1xcclxcbiAgYW5pbWF0aW9uOmZhZGVpbi1vdXQgMC4zcyBlYXNlLW91dDtcXG59XFxuQGtleWZyYW1lcyBmYWRlaW4taW4ge1xcbjAlIHtcXHJcXG4gICAgb3BhY2l0eTogMDtcXG59XFxuMTAwJSB7XFxyXFxuICAgIG9wYWNpdHk6IC45O1xcbn1cXG59XFxuQGtleWZyYW1lcyBmYWRlaW4tb3V0IHtcXG4wJSB7XFxyXFxuICAgIG9wYWNpdHk6IC45O1xcbn1cXG4xMDAlIHtcXHJcXG4gICAgb3BhY2l0eTogMDtcXG59XFxufVxcclxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvVG9vbHRpcC52dWU/MzdkMTgzZWNcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQTJCQTs7OztFQUlBLFlBQUE7Q0FDQTtBQUNBO0VBQ0EsaUNBQUE7Q0FDQTtBQUNBO0VBQ0EsbUNBQUE7Q0FDQTtBQUNBO0FBQ0E7SUFDQSxXQUFBO0NBQ0E7QUFDQTtJQUNBLFlBQUE7Q0FDQTtDQUNBO0FBQ0E7QUFDQTtJQUNBLFlBQUE7Q0FDQTtBQUNBO0lBQ0EsV0FBQTtDQUNBO0NBQ0FcIixcImZpbGVcIjpcIlRvb2x0aXAudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxzcGFuIHJlZj1cXFwidHJpZ2dlclxcXCI+XFxyXFxuICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgPHRyYW5zaXRpb24gOm5hbWU9XFxcImVmZmVjdFxcXCI+XFxyXFxuICAgICAgPGRpdiByZWY9XFxcInBvcG92ZXJcXFwiIHYtaWY9XFxcInNob3dcXFwiIDpjbGFzcz1cXFwiWyd0b29sdGlwJyxwbGFjZW1lbnRdXFxcIj5cXHJcXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcInRvb2x0aXAtYXJyb3dcXFwiPjwvZGl2PlxcclxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwidG9vbHRpcC1pbm5lclxcXCI+XFxyXFxuICAgICAgICAgIDxzbG90IG5hbWU9XFxcImNvbnRlbnRcXFwiPjxkaXYgdi1odG1sPVxcXCJjb250ZW50XFxcIj48L2Rpdj48L3Nsb3Q+XFxyXFxuICAgICAgICA8L2Rpdj5cXHJcXG4gICAgICA8L2Rpdj5cXHJcXG4gICAgPC90cmFuc2l0aW9uPlxcclxcbiAgPC9zcGFuPlxcclxcbjwvdGVtcGxhdGU+XFxyXFxuXFxyXFxuPHNjcmlwdD5cXHJcXG5pbXBvcnQgUG9wb3Zlck1peGluIGZyb20gJy4vdXRpbHMvcG9wb3Zlck1peGlucy5qcydcXHJcXG5cXHJcXG5leHBvcnQgZGVmYXVsdCB7XFxyXFxuICBtaXhpbnM6IFtQb3BvdmVyTWl4aW5dLFxcclxcbiAgcHJvcHM6IHtcXHJcXG4gICAgZWZmZWN0OiB7dHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnc2NhbGUnfSxcXHJcXG4gICAgdHJpZ2dlcjoge3R5cGU6IFN0cmluZywgZGVmYXVsdDogJ2hvdmVyJ31cXHJcXG4gIH1cXHJcXG59XFxyXFxuPC9zY3JpcHQ+XFxyXFxuXFxyXFxuPHN0eWxlPlxcclxcbi50b29sdGlwLnRvcCxcXHJcXG4udG9vbHRpcC5sZWZ0LFxcclxcbi50b29sdGlwLnJpZ2h0LFxcclxcbi50b29sdGlwLmJvdHRvbSB7XFxyXFxuICBvcGFjaXR5OiAuOTtcXHJcXG59XFxyXFxuLmZhZGVpbi1lbnRlciB7XFxyXFxuICBhbmltYXRpb246ZmFkZWluLWluIDAuM3MgZWFzZS1pbjtcXHJcXG59XFxyXFxuLmZhZGVpbi1sZWF2ZS1hY3RpdmUge1xcclxcbiAgYW5pbWF0aW9uOmZhZGVpbi1vdXQgMC4zcyBlYXNlLW91dDtcXHJcXG59XFxyXFxuQGtleWZyYW1lcyBmYWRlaW4taW4ge1xcclxcbiAgMCUge1xcclxcbiAgICBvcGFjaXR5OiAwO1xcclxcbiAgfVxcclxcbiAgMTAwJSB7XFxyXFxuICAgIG9wYWNpdHk6IC45O1xcclxcbiAgfVxcclxcbn1cXHJcXG5Aa2V5ZnJhbWVzIGZhZGVpbi1vdXQge1xcclxcbiAgMCUge1xcclxcbiAgICBvcGFjaXR5OiAuOTtcXHJcXG4gIH1cXHJcXG4gIDEwMCUge1xcclxcbiAgICBvcGFjaXR5OiAwO1xcclxcbiAgfVxcclxcbn1cXHJcXG48L3N0eWxlPlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogMTg1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfcG9wb3Zlck1peGlucyA9IF9fd2VicGFja19yZXF1aXJlX18oMTQzKTtcblx0XG5cdHZhciBfcG9wb3Zlck1peGluczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9wb3BvdmVyTWl4aW5zKTtcblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cdFxuXHRleHBvcnRzLmRlZmF1bHQgPSB7XG5cdCAgbWl4aW5zOiBbX3BvcG92ZXJNaXhpbnMyLmRlZmF1bHRdLFxuXHQgIHByb3BzOiB7XG5cdCAgICBlZmZlY3Q6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnc2NhbGUnIH0sXG5cdCAgICB0cmlnZ2VyOiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogJ2hvdmVyJyB9XG5cdCAgfVxuXHR9OyAvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXHQvL1xuXG4vKioqLyB9LFxuLyogMTg2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O1xuXHQgIHJldHVybiBfdm0uX2MoJ3NwYW4nLCB7XG5cdCAgICByZWY6IFwidHJpZ2dlclwiXG5cdCAgfSwgW192bS5fdChcImRlZmF1bHRcIiksIF92bS5fdihcIiBcIiksIF92bS5fYygndHJhbnNpdGlvbicsIHtcblx0ICAgIGF0dHJzOiB7XG5cdCAgICAgIFwibmFtZVwiOiBfdm0uZWZmZWN0XG5cdCAgICB9XG5cdCAgfSwgWyhfdm0uc2hvdykgPyBfdm0uX2MoJ2RpdicsIHtcblx0ICAgIHJlZjogXCJwb3BvdmVyXCIsXG5cdCAgICBjbGFzczogWyd0b29sdGlwJywgX3ZtLnBsYWNlbWVudF1cblx0ICB9LCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJ0b29sdGlwLWFycm93XCJcblx0ICB9KSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBzdGF0aWNDbGFzczogXCJ0b29sdGlwLWlubmVyXCJcblx0ICB9LCBbX3ZtLl90KFwiY29udGVudFwiLCBbX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBkb21Qcm9wczoge1xuXHQgICAgICBcImlubmVySFRNTFwiOiBfdm0uX3MoX3ZtLmNvbnRlbnQpXG5cdCAgICB9XG5cdCAgfSldKV0sIDIpXSkgOiBfdm0uX2UoKV0pXSwgMilcblx0fSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxuXHRpZiAoZmFsc2UpIHtcblx0ICBtb2R1bGUuaG90LmFjY2VwdCgpXG5cdCAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuXHQgICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtNDhmYjUxYjJcIiwgbW9kdWxlLmV4cG9ydHMpXG5cdCAgfVxuXHR9XG5cbi8qKiovIH0sXG4vKiAxODcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXHR2YXIgX192dWVfc3R5bGVzX18gPSB7fVxuXHRcblx0Lyogc3R5bGVzICovXG5cdF9fd2VicGFja19yZXF1aXJlX18oMTg4KVxuXHRcblx0Lyogc2NyaXB0ICovXG5cdF9fdnVlX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oMTkwKVxuXHRcblx0LyogdGVtcGxhdGUgKi9cblx0dmFyIF9fdnVlX3RlbXBsYXRlX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIwNilcblx0X192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5cdGlmIChcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcblx0ICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuXHQpIHtcblx0aWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cdF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG5cdH1cblx0aWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuXHQgIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG5cdH1cblx0X192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiQzpcXFxcbGFyYWdvblxcXFx3d3dcXFxcdnVlLXN0cmFwXFxcXHNyY1xcXFxUeXBlYWhlYWQudnVlXCJcblx0X192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5cdF9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXHRcblx0LyogaG90IHJlbG9hZCAqL1xuXHRpZiAoZmFsc2UpIHsoZnVuY3Rpb24gKCkge1xuXHQgIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG5cdCAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG5cdCAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG5cdCAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuXHQgIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTViNWY1ZTk0XCIsIF9fdnVlX29wdGlvbnNfXylcblx0ICB9IGVsc2Uge1xuXHQgICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi01YjVmNWU5NFwiLCBfX3Z1ZV9vcHRpb25zX18pXG5cdCAgfVxuXHR9KSgpfVxuXHRpZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIFR5cGVhaGVhZC52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cdFxuXHRtb2R1bGUuZXhwb3J0cyA9IF9fdnVlX2V4cG9ydHNfX1xuXG5cbi8qKiovIH0sXG4vKiAxODggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cdFxuXHQvLyBsb2FkIHRoZSBzdHlsZXNcblx0dmFyIGNvbnRlbnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE4OSk7XG5cdGlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuXHQvLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG5cdHZhciB1cGRhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc5KShjb250ZW50LCB7fSk7XG5cdGlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuXHQvLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5cdGlmKGZhbHNlKSB7XG5cdFx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNWI1ZjVlOTQhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL1R5cGVhaGVhZC52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTViNWY1ZTk0IS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9UeXBlYWhlYWQudnVlXCIpO1xuXHRcdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0XHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcblx0fVxuXG4vKioqLyB9LFxuLyogMTg5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDc4KSgpO1xuXHQvLyBpbXBvcnRzXG5cdFxuXHRcblx0Ly8gbW9kdWxlXG5cdGV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5kcm9wZG93bi1tZW51ID4gbGkgPiBhIHtcXHJcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG59XFxyXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9UeXBlYWhlYWQudnVlPzczZmNkNGJlXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFrSUE7RUFDQSxnQkFBQTtDQUNBXCIsXCJmaWxlXCI6XCJUeXBlYWhlYWQudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjx0ZW1wbGF0ZT5cXHJcXG4gIDxkaXYgc3R5bGU9XFxcInBvc2l0aW9uOiByZWxhdGl2ZVxcXCIgOmNsYXNzPVxcXCJ7b3BlbjpzaG93RHJvcGRvd259XFxcIj5cXHJcXG4gICAgPGlucHV0IGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIGF1dG9jb21wbGV0ZT1cXFwib2ZmXFxcIlxcclxcbiAgICAgIHYtbW9kZWw9XFxcInZhbFxcXCJcXHJcXG4gICAgICA6cGxhY2Vob2xkZXI9XFxcInBsYWNlaG9sZGVyXFxcIlxcclxcbiAgICAgIDp0eXBlLm9uY2U9XFxcInR5cGVcXFwiXFxyXFxuICAgICAgQGJsdXI9XFxcInNob3dEcm9wZG93biA9IGZhbHNlXFxcIlxcclxcbiAgICAgIEBrZXlkb3duLmRvd24ucHJldmVudD1cXFwiZG93blxcXCJcXHJcXG4gICAgICBAa2V5ZG93bi5lbnRlcj1cXFwiaGl0XFxcIlxcclxcbiAgICAgIEBrZXlkb3duLmVzYz1cXFwicmVzZXRcXFwiXFxyXFxuICAgICAgQGtleWRvd24udXAucHJldmVudD1cXFwidXBcXFwiXFxyXFxuICAgIC8+XFxyXFxuICAgIDx1bCBjbGFzcz1cXFwiZHJvcGRvd24tbWVudVxcXCIgcmVmPVxcXCJkcm9wZG93blxcXCI+XFxyXFxuICAgICAgPGxpIHYtZm9yPVxcXCIoaXRlbSwgaSkgaW4gaXRlbXNcXFwiIDpjbGFzcz1cXFwie2FjdGl2ZTogaXNBY3RpdmUoaSl9XFxcIj5cXHJcXG4gICAgICAgIDxhIEBtb3VzZWRvd24ucHJldmVudD1cXFwiaGl0XFxcIiBAbW91c2Vtb3ZlPVxcXCJzZXRBY3RpdmUoaSlcXFwiPlxcclxcbiAgICAgICAgICA8Y29tcG9uZW50IDppcz1cXFwidGVtcGxhdGVDb21wXFxcIiA6aXRlbT1cXFwiaXRlbVxcXCI+PC9jb21wb25lbnQ+XFxyXFxuICAgICAgICA8L2E+XFxyXFxuICAgICAgPC9saT5cXHJcXG4gICAgPC91bD5cXHJcXG4gIDwvZGl2PlxcclxcbjwvdGVtcGxhdGU+XFxyXFxuXFxyXFxuPHNjcmlwdD5cXHJcXG5pbXBvcnQge2RlbGF5ZXIsIGdldEpTT059IGZyb20gJy4vdXRpbHMvdXRpbHMuanMnXFxyXFxudmFyIERFTEFZID0gMzAwXFxyXFxuXFxyXFxuZXhwb3J0IGRlZmF1bHQge1xcclxcbiAgcHJvcHM6IHtcXHJcXG4gICAgYXN5bmM6IHt0eXBlOiBTdHJpbmd9LFxcclxcbiAgICBkYXRhOiB7dHlwZTogQXJyYXl9LFxcclxcbiAgICBkZWxheToge3R5cGU6IE51bWJlciwgZGVmYXVsdDogREVMQVl9LFxcclxcbiAgICBhc3luY0tleToge3R5cGU6IFN0cmluZywgZGVmYXVsdDogbnVsbH0sXFxyXFxuICAgIGxpbWl0OiB7dHlwZTogTnVtYmVyLCBkZWZhdWx0OiA4fSxcXHJcXG4gICAgbWF0Y2hDYXNlOiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBtYXRjaFN0YXJ0OiB7dHlwZTogQm9vbGVhbiwgZGVmYXVsdDogZmFsc2V9LFxcclxcbiAgICBvbkhpdDoge1xcclxcbiAgICAgIHR5cGU6IEZ1bmN0aW9uLFxcclxcbiAgICAgIGRlZmF1bHQgKGl0ZW0pIHsgcmV0dXJuIGl0ZW0gfVxcclxcbiAgICB9LFxcclxcbiAgICBwbGFjZWhvbGRlcjoge3R5cGU6IFN0cmluZ30sXFxyXFxuICAgIHRlbXBsYXRlOiB7dHlwZTogU3RyaW5nfSxcXHJcXG4gICAgdHlwZToge3R5cGU6IFN0cmluZywgZGVmYXVsdDogJ3RleHQnfSxcXHJcXG4gICAgdmFsdWU6IHt0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6ICcnfVxcclxcbiAgfSxcXHJcXG4gIGRhdGEgKCkge1xcclxcbiAgICByZXR1cm4ge1xcclxcbiAgICAgIGFzaWduOiAnJyxcXHJcXG4gICAgICBzaG93RHJvcGRvd246IGZhbHNlLFxcclxcbiAgICAgIG5vUmVzdWx0czogdHJ1ZSxcXHJcXG4gICAgICBjdXJyZW50OiAwLFxcclxcbiAgICAgIGl0ZW1zOiBbXSxcXHJcXG4gICAgICB2YWw6IHRoaXMudmFsdWVcXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIGNvbXB1dGVkOiB7XFxyXFxuICAgIHRlbXBsYXRlQ29tcCAoKSB7XFxyXFxuICAgICAgcmV0dXJuIHtcXHJcXG4gICAgICAgIHRlbXBsYXRlOiB0eXBlb2YgdGhpcy50ZW1wbGF0ZSA9PT0gJ3N0cmluZycgPyAnPHNwYW4+JyArIHRoaXMudGVtcGxhdGUgKyAnPC9zcGFuPicgOiAnPHN0cm9uZyB2LWh0bWw9XFxcIml0ZW1cXFwiPjwvc3Ryb25nPicsXFxyXFxuICAgICAgICBwcm9wczogeyBpdGVtOiB7ZGVmYXVsdDogbnVsbH0gfVxcclxcbiAgICAgIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIHdhdGNoOiB7XFxyXFxuICAgIHZhbCAodmFsLCBvbGQpIHtcXHJcXG4gICAgICB0aGlzLiRlbWl0KCdpbnB1dCcsIHZhbClcXHJcXG4gICAgICBpZiAodmFsICE9PSBvbGQgJiYgdmFsICE9PSB0aGlzLmFzaWduKSB0aGlzLl9fdXBkYXRlKClcXHJcXG4gICAgfSxcXHJcXG4gICAgdmFsdWUgKHZhbCkge1xcclxcbiAgICAgIGlmICh0aGlzLnZhbCAhPT0gdmFsKSB7IHRoaXMudmFsID0gdmFsIH1cXHJcXG4gICAgfVxcclxcbiAgfSxcXHJcXG4gIG1ldGhvZHM6IHtcXHJcXG4gICAgc2V0SXRlbXMgKGRhdGEpIHtcXHJcXG4gICAgICBpZiAodGhpcy5hc3luYykge1xcclxcbiAgICAgICAgdGhpcy5pdGVtcyA9IHRoaXMuYXN5bmNLZXkgPyBkYXRhW3RoaXMuYXN5bmNLZXldIDogZGF0YVxcclxcbiAgICAgICAgdGhpcy5pdGVtcyA9IHRoaXMuaXRlbXMuc2xpY2UoMCwgdGhpcy5saW1pdClcXHJcXG4gICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgdGhpcy5pdGVtcyA9IChkYXRhIHx8IFtdKS5maWx0ZXIodmFsdWUgPT4ge1xcclxcbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgeyByZXR1cm4gdHJ1ZSB9XFxyXFxuICAgICAgICAgIHZhbHVlID0gdGhpcy5tYXRjaENhc2UgPyB2YWx1ZSA6IHZhbHVlLnRvTG93ZXJDYXNlKClcXHJcXG4gICAgICAgICAgdmFyIHF1ZXJ5ID0gdGhpcy5tYXRjaENhc2UgPyB0aGlzLnZhbCA6IHRoaXMudmFsLnRvTG93ZXJDYXNlKClcXHJcXG4gICAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hTdGFydCA/IHZhbHVlLmluZGV4T2YocXVlcnkpID09PSAwIDogdmFsdWUuaW5kZXhPZihxdWVyeSkgIT09IC0xXFxyXFxuICAgICAgICB9KS5zbGljZSgwLCB0aGlzLmxpbWl0KVxcclxcbiAgICAgIH1cXHJcXG4gICAgICB0aGlzLnNob3dEcm9wZG93biA9IHRoaXMuaXRlbXMubGVuZ3RoID4gMFxcclxcbiAgICB9LFxcclxcbiAgICBzZXRWYWx1ZSAodmFsdWUpIHtcXHJcXG4gICAgICB0aGlzLmFzaWduID0gdmFsdWVcXHJcXG4gICAgICB0aGlzLnZhbCA9IHZhbHVlXFxyXFxuICAgICAgdGhpcy5pdGVtcyA9IFtdXFxyXFxuICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2VcXHJcXG4gICAgICB0aGlzLnNob3dEcm9wZG93biA9IGZhbHNlXFxyXFxuICAgIH0sXFxyXFxuICAgIHJlc2V0ICgpIHsgdGhpcy5zZXRWYWx1ZShudWxsKSB9LFxcclxcbiAgICBzZXRBY3RpdmUgKGluZGV4KSB7IHRoaXMuY3VycmVudCA9IGluZGV4IH0sXFxyXFxuICAgIGlzQWN0aXZlIChpbmRleCkgeyByZXR1cm4gdGhpcy5jdXJyZW50ID09PSBpbmRleCB9LFxcclxcbiAgICBoaXQgKGUpIHtcXHJcXG4gICAgICBlLnByZXZlbnREZWZhdWx0KClcXHJcXG4gICAgICB0aGlzLnNldFZhbHVlKHRoaXMub25IaXQodGhpcy5pdGVtc1t0aGlzLmN1cnJlbnRdLCB0aGlzKSlcXHJcXG4gICAgfSxcXHJcXG4gICAgdXAgKCkge1xcclxcbiAgICAgIGlmICh0aGlzLmN1cnJlbnQgPiAwKSB7IHRoaXMuY3VycmVudC0tIH1cXHJcXG4gICAgICBlbHNlIHsgdGhpcy5jdXJyZW50ID0gdGhpcy5pdGVtcy5sZW5ndGggLSAxIH1cXHJcXG4gICAgfSxcXHJcXG4gICAgZG93biAoKSB7XFxyXFxuICAgICAgaWYgKHRoaXMuY3VycmVudCA8IHRoaXMuaXRlbXMubGVuZ3RoIC0gMSkgeyB0aGlzLmN1cnJlbnQrKyB9XFxyXFxuICAgICAgZWxzZSB7IHRoaXMuY3VycmVudCA9IDAgfVxcclxcbiAgICB9XFxyXFxuICB9LFxcclxcbiAgY3JlYXRlZCAoKSB7XFxyXFxuICAgIHRoaXMuX191cGRhdGUgPSBkZWxheWVyKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICBpZiAoIXRoaXMudmFsKSB7XFxyXFxuICAgICAgICB0aGlzLnJlc2V0KClcXHJcXG4gICAgICAgIHJldHVyblxcclxcbiAgICAgIH1cXHJcXG4gICAgICB0aGlzLmFzaWduID0gJydcXHJcXG4gICAgICBpZiAodGhpcy5hc3luYykge1xcclxcbiAgICAgICAgZ2V0SlNPTih0aGlzLmFzeW5jICsgdGhpcy52YWwpLnRoZW4oZGF0YSA9PiB7XFxyXFxuICAgICAgICAgIHRoaXMuc2V0SXRlbXMoZGF0YSlcXHJcXG4gICAgICAgIH0pXFxyXFxuICAgICAgfSBlbHNlIGlmICh0aGlzLmRhdGEpIHtcXHJcXG4gICAgICAgIHRoaXMuc2V0SXRlbXModGhpcy5kYXRhKVxcclxcbiAgICAgIH1cXHJcXG4gICAgfSwgJ2RlbGF5JywgREVMQVkpXFxyXFxuICAgIHRoaXMuX191cGRhdGUoKVxcclxcbiAgfVxcclxcbn1cXHJcXG48L3NjcmlwdD5cXHJcXG5cXHJcXG48c3R5bGU+XFxyXFxuLmRyb3Bkb3duLW1lbnUgPiBsaSA+IGEge1xcclxcbiAgY3Vyc29yOiBwb2ludGVyO1xcclxcbn1cXHJcXG48L3N0eWxlPlwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblx0XG5cdC8vIGV4cG9ydHNcblxuXG4vKioqLyB9LFxuLyogMTkwICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcblx0ICB2YWx1ZTogdHJ1ZVxuXHR9KTtcblx0XG5cdHZhciBfdHlwZW9mMiA9IF9fd2VicGFja19yZXF1aXJlX18oMTkxKTtcblx0XG5cdHZhciBfdHlwZW9mMyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3R5cGVvZjIpO1xuXHRcblx0dmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNjUpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblx0XG5cdHZhciBERUxBWSA9IDMwMDsgLy9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0Ly9cblx0XG5cdGV4cG9ydHMuZGVmYXVsdCA9IHtcblx0ICBwcm9wczoge1xuXHQgICAgYXN5bmM6IHsgdHlwZTogU3RyaW5nIH0sXG5cdCAgICBkYXRhOiB7IHR5cGU6IEFycmF5IH0sXG5cdCAgICBkZWxheTogeyB0eXBlOiBOdW1iZXIsIGRlZmF1bHQ6IERFTEFZIH0sXG5cdCAgICBhc3luY0tleTogeyB0eXBlOiBTdHJpbmcsIGRlZmF1bHQ6IG51bGwgfSxcblx0ICAgIGxpbWl0OiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogOCB9LFxuXHQgICAgbWF0Y2hDYXNlOiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH0sXG5cdCAgICBtYXRjaFN0YXJ0OiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH0sXG5cdCAgICBvbkhpdDoge1xuXHQgICAgICB0eXBlOiBGdW5jdGlvbixcblx0ICAgICAgZGVmYXVsdDogZnVuY3Rpb24gX2RlZmF1bHQoaXRlbSkge1xuXHQgICAgICAgIHJldHVybiBpdGVtO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgcGxhY2Vob2xkZXI6IHsgdHlwZTogU3RyaW5nIH0sXG5cdCAgICB0ZW1wbGF0ZTogeyB0eXBlOiBTdHJpbmcgfSxcblx0ICAgIHR5cGU6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAndGV4dCcgfSxcblx0ICAgIHZhbHVlOiB7IHR5cGU6IFN0cmluZywgZGVmYXVsdDogJycgfVxuXHQgIH0sXG5cdCAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgIGFzaWduOiAnJyxcblx0ICAgICAgc2hvd0Ryb3Bkb3duOiBmYWxzZSxcblx0ICAgICAgbm9SZXN1bHRzOiB0cnVlLFxuXHQgICAgICBjdXJyZW50OiAwLFxuXHQgICAgICBpdGVtczogW10sXG5cdCAgICAgIHZhbDogdGhpcy52YWx1ZVxuXHQgICAgfTtcblx0ICB9LFxuXHRcblx0ICBjb21wdXRlZDoge1xuXHQgICAgdGVtcGxhdGVDb21wOiBmdW5jdGlvbiB0ZW1wbGF0ZUNvbXAoKSB7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgdGVtcGxhdGU6IHR5cGVvZiB0aGlzLnRlbXBsYXRlID09PSAnc3RyaW5nJyA/ICc8c3Bhbj4nICsgdGhpcy50ZW1wbGF0ZSArICc8L3NwYW4+JyA6ICc8c3Ryb25nIHYtaHRtbD1cIml0ZW1cIj48L3N0cm9uZz4nLFxuXHQgICAgICAgIHByb3BzOiB7IGl0ZW06IHsgZGVmYXVsdDogbnVsbCB9IH1cblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICB9LFxuXHQgIHdhdGNoOiB7XG5cdCAgICB2YWw6IGZ1bmN0aW9uIHZhbChfdmFsLCBvbGQpIHtcblx0ICAgICAgdGhpcy4kZW1pdCgnaW5wdXQnLCBfdmFsKTtcblx0ICAgICAgaWYgKF92YWwgIT09IG9sZCAmJiBfdmFsICE9PSB0aGlzLmFzaWduKSB0aGlzLl9fdXBkYXRlKCk7XG5cdCAgICB9LFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKHZhbCkge1xuXHQgICAgICBpZiAodGhpcy52YWwgIT09IHZhbCkge1xuXHQgICAgICAgIHRoaXMudmFsID0gdmFsO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSxcblx0ICBtZXRob2RzOiB7XG5cdCAgICBzZXRJdGVtczogZnVuY3Rpb24gc2V0SXRlbXMoZGF0YSkge1xuXHQgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgICAgaWYgKHRoaXMuYXN5bmMpIHtcblx0ICAgICAgICB0aGlzLml0ZW1zID0gdGhpcy5hc3luY0tleSA/IGRhdGFbdGhpcy5hc3luY0tleV0gOiBkYXRhO1xuXHQgICAgICAgIHRoaXMuaXRlbXMgPSB0aGlzLml0ZW1zLnNsaWNlKDAsIHRoaXMubGltaXQpO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHRoaXMuaXRlbXMgPSAoZGF0YSB8fCBbXSkuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuXHQgICAgICAgICAgaWYgKCh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiAoMCwgX3R5cGVvZjMuZGVmYXVsdCkodmFsdWUpKSA9PT0gJ29iamVjdCcpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRydWU7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgICB2YWx1ZSA9IF90aGlzLm1hdGNoQ2FzZSA/IHZhbHVlIDogdmFsdWUudG9Mb3dlckNhc2UoKTtcblx0ICAgICAgICAgIHZhciBxdWVyeSA9IF90aGlzLm1hdGNoQ2FzZSA/IF90aGlzLnZhbCA6IF90aGlzLnZhbC50b0xvd2VyQ2FzZSgpO1xuXHQgICAgICAgICAgcmV0dXJuIF90aGlzLm1hdGNoU3RhcnQgPyB2YWx1ZS5pbmRleE9mKHF1ZXJ5KSA9PT0gMCA6IHZhbHVlLmluZGV4T2YocXVlcnkpICE9PSAtMTtcblx0ICAgICAgICB9KS5zbGljZSgwLCB0aGlzLmxpbWl0KTtcblx0ICAgICAgfVxuXHQgICAgICB0aGlzLnNob3dEcm9wZG93biA9IHRoaXMuaXRlbXMubGVuZ3RoID4gMDtcblx0ICAgIH0sXG5cdCAgICBzZXRWYWx1ZTogZnVuY3Rpb24gc2V0VmFsdWUodmFsdWUpIHtcblx0ICAgICAgdGhpcy5hc2lnbiA9IHZhbHVlO1xuXHQgICAgICB0aGlzLnZhbCA9IHZhbHVlO1xuXHQgICAgICB0aGlzLml0ZW1zID0gW107XG5cdCAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXHQgICAgICB0aGlzLnNob3dEcm9wZG93biA9IGZhbHNlO1xuXHQgICAgfSxcblx0ICAgIHJlc2V0OiBmdW5jdGlvbiByZXNldCgpIHtcblx0ICAgICAgdGhpcy5zZXRWYWx1ZShudWxsKTtcblx0ICAgIH0sXG5cdCAgICBzZXRBY3RpdmU6IGZ1bmN0aW9uIHNldEFjdGl2ZShpbmRleCkge1xuXHQgICAgICB0aGlzLmN1cnJlbnQgPSBpbmRleDtcblx0ICAgIH0sXG5cdCAgICBpc0FjdGl2ZTogZnVuY3Rpb24gaXNBY3RpdmUoaW5kZXgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuY3VycmVudCA9PT0gaW5kZXg7XG5cdCAgICB9LFxuXHQgICAgaGl0OiBmdW5jdGlvbiBoaXQoZSkge1xuXHQgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgIHRoaXMuc2V0VmFsdWUodGhpcy5vbkhpdCh0aGlzLml0ZW1zW3RoaXMuY3VycmVudF0sIHRoaXMpKTtcblx0ICAgIH0sXG5cdCAgICB1cDogZnVuY3Rpb24gdXAoKSB7XG5cdCAgICAgIGlmICh0aGlzLmN1cnJlbnQgPiAwKSB7XG5cdCAgICAgICAgdGhpcy5jdXJyZW50LS07XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgdGhpcy5jdXJyZW50ID0gdGhpcy5pdGVtcy5sZW5ndGggLSAxO1xuXHQgICAgICB9XG5cdCAgICB9LFxuXHQgICAgZG93bjogZnVuY3Rpb24gZG93bigpIHtcblx0ICAgICAgaWYgKHRoaXMuY3VycmVudCA8IHRoaXMuaXRlbXMubGVuZ3RoIC0gMSkge1xuXHQgICAgICAgIHRoaXMuY3VycmVudCsrO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHRoaXMuY3VycmVudCA9IDA7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9LFxuXHQgIGNyZWF0ZWQ6IGZ1bmN0aW9uIGNyZWF0ZWQoKSB7XG5cdCAgICB0aGlzLl9fdXBkYXRlID0gKDAsIF91dGlscy5kZWxheWVyKShmdW5jdGlvbiAoKSB7XG5cdCAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXHRcblx0ICAgICAgaWYgKCF0aGlzLnZhbCkge1xuXHQgICAgICAgIHRoaXMucmVzZXQoKTtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICAgIH1cblx0ICAgICAgdGhpcy5hc2lnbiA9ICcnO1xuXHQgICAgICBpZiAodGhpcy5hc3luYykge1xuXHQgICAgICAgICgwLCBfdXRpbHMuZ2V0SlNPTikodGhpcy5hc3luYyArIHRoaXMudmFsKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG5cdCAgICAgICAgICBfdGhpczIuc2V0SXRlbXMoZGF0YSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhKSB7XG5cdCAgICAgICAgdGhpcy5zZXRJdGVtcyh0aGlzLmRhdGEpO1xuXHQgICAgICB9XG5cdCAgICB9LCAnZGVsYXknLCBERUxBWSk7XG5cdCAgICB0aGlzLl9fdXBkYXRlKCk7XG5cdCAgfVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTkxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFxuXHR2YXIgX2l0ZXJhdG9yID0gX193ZWJwYWNrX3JlcXVpcmVfXygyMCk7XG5cdFxuXHR2YXIgX2l0ZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2l0ZXJhdG9yKTtcblx0XG5cdHZhciBfc3ltYm9sID0gX193ZWJwYWNrX3JlcXVpcmVfXygxOTIpO1xuXHRcblx0dmFyIF9zeW1ib2wyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc3ltYm9sKTtcblx0XG5cdHZhciBfdHlwZW9mID0gdHlwZW9mIF9zeW1ib2wyLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgX2l0ZXJhdG9yMi5kZWZhdWx0ID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgX3N5bWJvbDIuZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gX3N5bWJvbDIuZGVmYXVsdCAmJiBvYmogIT09IF9zeW1ib2wyLmRlZmF1bHQucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXHRcblx0ZXhwb3J0cy5kZWZhdWx0ID0gdHlwZW9mIF9zeW1ib2wyLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIiAmJiBfdHlwZW9mKF9pdGVyYXRvcjIuZGVmYXVsdCkgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7XG5cdCAgcmV0dXJuIHR5cGVvZiBvYmogPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihvYmopO1xuXHR9IDogZnVuY3Rpb24gKG9iaikge1xuXHQgIHJldHVybiBvYmogJiYgdHlwZW9mIF9zeW1ib2wyLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IF9zeW1ib2wyLmRlZmF1bHQgJiYgb2JqICE9PSBfc3ltYm9sMi5kZWZhdWx0LnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2Yob2JqKTtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDE5MiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDE5MyksIF9fZXNNb2R1bGU6IHRydWUgfTtcblxuLyoqKi8gfSxcbi8qIDE5MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0X193ZWJwYWNrX3JlcXVpcmVfXygxOTQpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDIwMyk7XG5cdF9fd2VicGFja19yZXF1aXJlX18oMjA0KTtcblx0X193ZWJwYWNrX3JlcXVpcmVfXygyMDUpO1xuXHRtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oNykuU3ltYm9sO1xuXG4vKioqLyB9LFxuLyogMTk0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdC8vIEVDTUFTY3JpcHQgNiBzeW1ib2xzIHNoaW1cblx0dmFyIGdsb2JhbCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KVxuXHQgICwgaGFzICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDI5KVxuXHQgICwgREVTQ1JJUFRPUlMgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE1KVxuXHQgICwgJGV4cG9ydCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpXG5cdCAgLCByZWRlZmluZSAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMjgpXG5cdCAgLCBNRVRBICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTk1KS5LRVlcblx0ICAsICRmYWlscyAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNilcblx0ICAsIHNoYXJlZCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0Mylcblx0ICAsIHNldFRvU3RyaW5nVGFnID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0Nylcblx0ICAsIHVpZCAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0NClcblx0ICAsIHdrcyAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0OClcblx0ICAsIHdrc0V4dCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1NSlcblx0ICAsIHdrc0RlZmluZSAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygxOTYpXG5cdCAgLCBrZXlPZiAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTk3KVxuXHQgICwgZW51bUtleXMgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE5OClcblx0ICAsIGlzQXJyYXkgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygyMDEpXG5cdCAgLCBhbk9iamVjdCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTIpXG5cdCAgLCB0b0lPYmplY3QgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzYpXG5cdCAgLCB0b1ByaW1pdGl2ZSAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTgpXG5cdCAgLCBjcmVhdGVEZXNjICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTkpXG5cdCAgLCBfY3JlYXRlICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzIpXG5cdCAgLCBnT1BORXh0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oNjApXG5cdCAgLCAkR09QRCAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMjAyKVxuXHQgICwgJERQICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDExKVxuXHQgICwgJGtleXMgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDM0KVxuXHQgICwgZ09QRCAgICAgICAgICAgPSAkR09QRC5mXG5cdCAgLCBkUCAgICAgICAgICAgICA9ICREUC5mXG5cdCAgLCBnT1BOICAgICAgICAgICA9IGdPUE5FeHQuZlxuXHQgICwgJFN5bWJvbCAgICAgICAgPSBnbG9iYWwuU3ltYm9sXG5cdCAgLCAkSlNPTiAgICAgICAgICA9IGdsb2JhbC5KU09OXG5cdCAgLCBfc3RyaW5naWZ5ICAgICA9ICRKU09OICYmICRKU09OLnN0cmluZ2lmeVxuXHQgICwgUFJPVE9UWVBFICAgICAgPSAncHJvdG90eXBlJ1xuXHQgICwgSElEREVOICAgICAgICAgPSB3a3MoJ19oaWRkZW4nKVxuXHQgICwgVE9fUFJJTUlUSVZFICAgPSB3a3MoJ3RvUHJpbWl0aXZlJylcblx0ICAsIGlzRW51bSAgICAgICAgID0ge30ucHJvcGVydHlJc0VudW1lcmFibGVcblx0ICAsIFN5bWJvbFJlZ2lzdHJ5ID0gc2hhcmVkKCdzeW1ib2wtcmVnaXN0cnknKVxuXHQgICwgQWxsU3ltYm9scyAgICAgPSBzaGFyZWQoJ3N5bWJvbHMnKVxuXHQgICwgT1BTeW1ib2xzICAgICAgPSBzaGFyZWQoJ29wLXN5bWJvbHMnKVxuXHQgICwgT2JqZWN0UHJvdG8gICAgPSBPYmplY3RbUFJPVE9UWVBFXVxuXHQgICwgVVNFX05BVElWRSAgICAgPSB0eXBlb2YgJFN5bWJvbCA9PSAnZnVuY3Rpb24nXG5cdCAgLCBRT2JqZWN0ICAgICAgICA9IGdsb2JhbC5RT2JqZWN0O1xuXHQvLyBEb24ndCB1c2Ugc2V0dGVycyBpbiBRdCBTY3JpcHQsIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8xNzNcblx0dmFyIHNldHRlciA9ICFRT2JqZWN0IHx8ICFRT2JqZWN0W1BST1RPVFlQRV0gfHwgIVFPYmplY3RbUFJPVE9UWVBFXS5maW5kQ2hpbGQ7XG5cdFxuXHQvLyBmYWxsYmFjayBmb3Igb2xkIEFuZHJvaWQsIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD02ODdcblx0dmFyIHNldFN5bWJvbERlc2MgPSBERVNDUklQVE9SUyAmJiAkZmFpbHMoZnVuY3Rpb24oKXtcblx0ICByZXR1cm4gX2NyZWF0ZShkUCh7fSwgJ2EnLCB7XG5cdCAgICBnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiBkUCh0aGlzLCAnYScsIHt2YWx1ZTogN30pLmE7IH1cblx0ICB9KSkuYSAhPSA3O1xuXHR9KSA/IGZ1bmN0aW9uKGl0LCBrZXksIEQpe1xuXHQgIHZhciBwcm90b0Rlc2MgPSBnT1BEKE9iamVjdFByb3RvLCBrZXkpO1xuXHQgIGlmKHByb3RvRGVzYylkZWxldGUgT2JqZWN0UHJvdG9ba2V5XTtcblx0ICBkUChpdCwga2V5LCBEKTtcblx0ICBpZihwcm90b0Rlc2MgJiYgaXQgIT09IE9iamVjdFByb3RvKWRQKE9iamVjdFByb3RvLCBrZXksIHByb3RvRGVzYyk7XG5cdH0gOiBkUDtcblx0XG5cdHZhciB3cmFwID0gZnVuY3Rpb24odGFnKXtcblx0ICB2YXIgc3ltID0gQWxsU3ltYm9sc1t0YWddID0gX2NyZWF0ZSgkU3ltYm9sW1BST1RPVFlQRV0pO1xuXHQgIHN5bS5fayA9IHRhZztcblx0ICByZXR1cm4gc3ltO1xuXHR9O1xuXHRcblx0dmFyIGlzU3ltYm9sID0gVVNFX05BVElWRSAmJiB0eXBlb2YgJFN5bWJvbC5pdGVyYXRvciA9PSAnc3ltYm9sJyA/IGZ1bmN0aW9uKGl0KXtcblx0ICByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnO1xuXHR9IDogZnVuY3Rpb24oaXQpe1xuXHQgIHJldHVybiBpdCBpbnN0YW5jZW9mICRTeW1ib2w7XG5cdH07XG5cdFxuXHR2YXIgJGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoaXQsIGtleSwgRCl7XG5cdCAgaWYoaXQgPT09IE9iamVjdFByb3RvKSRkZWZpbmVQcm9wZXJ0eShPUFN5bWJvbHMsIGtleSwgRCk7XG5cdCAgYW5PYmplY3QoaXQpO1xuXHQgIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG5cdCAgYW5PYmplY3QoRCk7XG5cdCAgaWYoaGFzKEFsbFN5bWJvbHMsIGtleSkpe1xuXHQgICAgaWYoIUQuZW51bWVyYWJsZSl7XG5cdCAgICAgIGlmKCFoYXMoaXQsIEhJRERFTikpZFAoaXQsIEhJRERFTiwgY3JlYXRlRGVzYygxLCB7fSkpO1xuXHQgICAgICBpdFtISURERU5dW2tleV0gPSB0cnVlO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgaWYoaGFzKGl0LCBISURERU4pICYmIGl0W0hJRERFTl1ba2V5XSlpdFtISURERU5dW2tleV0gPSBmYWxzZTtcblx0ICAgICAgRCA9IF9jcmVhdGUoRCwge2VudW1lcmFibGU6IGNyZWF0ZURlc2MoMCwgZmFsc2UpfSk7XG5cdCAgICB9IHJldHVybiBzZXRTeW1ib2xEZXNjKGl0LCBrZXksIEQpO1xuXHQgIH0gcmV0dXJuIGRQKGl0LCBrZXksIEQpO1xuXHR9O1xuXHR2YXIgJGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKGl0LCBQKXtcblx0ICBhbk9iamVjdChpdCk7XG5cdCAgdmFyIGtleXMgPSBlbnVtS2V5cyhQID0gdG9JT2JqZWN0KFApKVxuXHQgICAgLCBpICAgID0gMFxuXHQgICAgLCBsID0ga2V5cy5sZW5ndGhcblx0ICAgICwga2V5O1xuXHQgIHdoaWxlKGwgPiBpKSRkZWZpbmVQcm9wZXJ0eShpdCwga2V5ID0ga2V5c1tpKytdLCBQW2tleV0pO1xuXHQgIHJldHVybiBpdDtcblx0fTtcblx0dmFyICRjcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoaXQsIFApe1xuXHQgIHJldHVybiBQID09PSB1bmRlZmluZWQgPyBfY3JlYXRlKGl0KSA6ICRkZWZpbmVQcm9wZXJ0aWVzKF9jcmVhdGUoaXQpLCBQKTtcblx0fTtcblx0dmFyICRwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uIHByb3BlcnR5SXNFbnVtZXJhYmxlKGtleSl7XG5cdCAgdmFyIEUgPSBpc0VudW0uY2FsbCh0aGlzLCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKTtcblx0ICBpZih0aGlzID09PSBPYmplY3RQcm90byAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhaGFzKE9QU3ltYm9scywga2V5KSlyZXR1cm4gZmFsc2U7XG5cdCAgcmV0dXJuIEUgfHwgIWhhcyh0aGlzLCBrZXkpIHx8ICFoYXMoQWxsU3ltYm9scywga2V5KSB8fCBoYXModGhpcywgSElEREVOKSAmJiB0aGlzW0hJRERFTl1ba2V5XSA/IEUgOiB0cnVlO1xuXHR9O1xuXHR2YXIgJGdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihpdCwga2V5KXtcblx0ICBpdCAgPSB0b0lPYmplY3QoaXQpO1xuXHQgIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG5cdCAgaWYoaXQgPT09IE9iamVjdFByb3RvICYmIGhhcyhBbGxTeW1ib2xzLCBrZXkpICYmICFoYXMoT1BTeW1ib2xzLCBrZXkpKXJldHVybjtcblx0ICB2YXIgRCA9IGdPUEQoaXQsIGtleSk7XG5cdCAgaWYoRCAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0pKUQuZW51bWVyYWJsZSA9IHRydWU7XG5cdCAgcmV0dXJuIEQ7XG5cdH07XG5cdHZhciAkZ2V0T3duUHJvcGVydHlOYW1lcyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5TmFtZXMoaXQpe1xuXHQgIHZhciBuYW1lcyAgPSBnT1BOKHRvSU9iamVjdChpdCkpXG5cdCAgICAsIHJlc3VsdCA9IFtdXG5cdCAgICAsIGkgICAgICA9IDBcblx0ICAgICwga2V5O1xuXHQgIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpe1xuXHQgICAgaWYoIWhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiBrZXkgIT0gSElEREVOICYmIGtleSAhPSBNRVRBKXJlc3VsdC5wdXNoKGtleSk7XG5cdCAgfSByZXR1cm4gcmVzdWx0O1xuXHR9O1xuXHR2YXIgJGdldE93blByb3BlcnR5U3ltYm9scyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5U3ltYm9scyhpdCl7XG5cdCAgdmFyIElTX09QICA9IGl0ID09PSBPYmplY3RQcm90b1xuXHQgICAgLCBuYW1lcyAgPSBnT1BOKElTX09QID8gT1BTeW1ib2xzIDogdG9JT2JqZWN0KGl0KSlcblx0ICAgICwgcmVzdWx0ID0gW11cblx0ICAgICwgaSAgICAgID0gMFxuXHQgICAgLCBrZXk7XG5cdCAgd2hpbGUobmFtZXMubGVuZ3RoID4gaSl7XG5cdCAgICBpZihoYXMoQWxsU3ltYm9scywga2V5ID0gbmFtZXNbaSsrXSkgJiYgKElTX09QID8gaGFzKE9iamVjdFByb3RvLCBrZXkpIDogdHJ1ZSkpcmVzdWx0LnB1c2goQWxsU3ltYm9sc1trZXldKTtcblx0ICB9IHJldHVybiByZXN1bHQ7XG5cdH07XG5cdFxuXHQvLyAxOS40LjEuMSBTeW1ib2woW2Rlc2NyaXB0aW9uXSlcblx0aWYoIVVTRV9OQVRJVkUpe1xuXHQgICRTeW1ib2wgPSBmdW5jdGlvbiBTeW1ib2woKXtcblx0ICAgIGlmKHRoaXMgaW5zdGFuY2VvZiAkU3ltYm9sKXRocm93IFR5cGVFcnJvcignU3ltYm9sIGlzIG5vdCBhIGNvbnN0cnVjdG9yIScpO1xuXHQgICAgdmFyIHRhZyA9IHVpZChhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7XG5cdCAgICB2YXIgJHNldCA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0ICAgICAgaWYodGhpcyA9PT0gT2JqZWN0UHJvdG8pJHNldC5jYWxsKE9QU3ltYm9scywgdmFsdWUpO1xuXHQgICAgICBpZihoYXModGhpcywgSElEREVOKSAmJiBoYXModGhpc1tISURERU5dLCB0YWcpKXRoaXNbSElEREVOXVt0YWddID0gZmFsc2U7XG5cdCAgICAgIHNldFN5bWJvbERlc2ModGhpcywgdGFnLCBjcmVhdGVEZXNjKDEsIHZhbHVlKSk7XG5cdCAgICB9O1xuXHQgICAgaWYoREVTQ1JJUFRPUlMgJiYgc2V0dGVyKXNldFN5bWJvbERlc2MoT2JqZWN0UHJvdG8sIHRhZywge2NvbmZpZ3VyYWJsZTogdHJ1ZSwgc2V0OiAkc2V0fSk7XG5cdCAgICByZXR1cm4gd3JhcCh0YWcpO1xuXHQgIH07XG5cdCAgcmVkZWZpbmUoJFN5bWJvbFtQUk9UT1RZUEVdLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpe1xuXHQgICAgcmV0dXJuIHRoaXMuX2s7XG5cdCAgfSk7XG5cdFxuXHQgICRHT1BELmYgPSAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xuXHQgICREUC5mICAgPSAkZGVmaW5lUHJvcGVydHk7XG5cdCAgX193ZWJwYWNrX3JlcXVpcmVfXyg2MSkuZiA9IGdPUE5FeHQuZiA9ICRnZXRPd25Qcm9wZXJ0eU5hbWVzO1xuXHQgIF9fd2VicGFja19yZXF1aXJlX18oMjAwKS5mICA9ICRwcm9wZXJ0eUlzRW51bWVyYWJsZTtcblx0ICBfX3dlYnBhY2tfcmVxdWlyZV9fKDE5OSkuZiA9ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cdFxuXHQgIGlmKERFU0NSSVBUT1JTICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fKDI3KSl7XG5cdCAgICByZWRlZmluZShPYmplY3RQcm90bywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJywgJHByb3BlcnR5SXNFbnVtZXJhYmxlLCB0cnVlKTtcblx0ICB9XG5cdFxuXHQgIHdrc0V4dC5mID0gZnVuY3Rpb24obmFtZSl7XG5cdCAgICByZXR1cm4gd3JhcCh3a3MobmFtZSkpO1xuXHQgIH1cblx0fVxuXHRcblx0JGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwge1N5bWJvbDogJFN5bWJvbH0pO1xuXHRcblx0Zm9yKHZhciBzeW1ib2xzID0gKFxuXHQgIC8vIDE5LjQuMi4yLCAxOS40LjIuMywgMTkuNC4yLjQsIDE5LjQuMi42LCAxOS40LjIuOCwgMTkuNC4yLjksIDE5LjQuMi4xMCwgMTkuNC4yLjExLCAxOS40LjIuMTIsIDE5LjQuMi4xMywgMTkuNC4yLjE0XG5cdCAgJ2hhc0luc3RhbmNlLGlzQ29uY2F0U3ByZWFkYWJsZSxpdGVyYXRvcixtYXRjaCxyZXBsYWNlLHNlYXJjaCxzcGVjaWVzLHNwbGl0LHRvUHJpbWl0aXZlLHRvU3RyaW5nVGFnLHVuc2NvcGFibGVzJ1xuXHQpLnNwbGl0KCcsJyksIGkgPSAwOyBzeW1ib2xzLmxlbmd0aCA+IGk7ICl3a3Moc3ltYm9sc1tpKytdKTtcblx0XG5cdGZvcih2YXIgc3ltYm9scyA9ICRrZXlzKHdrcy5zdG9yZSksIGkgPSAwOyBzeW1ib2xzLmxlbmd0aCA+IGk7ICl3a3NEZWZpbmUoc3ltYm9sc1tpKytdKTtcblx0XG5cdCRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsICdTeW1ib2wnLCB7XG5cdCAgLy8gMTkuNC4yLjEgU3ltYm9sLmZvcihrZXkpXG5cdCAgJ2Zvcic6IGZ1bmN0aW9uKGtleSl7XG5cdCAgICByZXR1cm4gaGFzKFN5bWJvbFJlZ2lzdHJ5LCBrZXkgKz0gJycpXG5cdCAgICAgID8gU3ltYm9sUmVnaXN0cnlba2V5XVxuXHQgICAgICA6IFN5bWJvbFJlZ2lzdHJ5W2tleV0gPSAkU3ltYm9sKGtleSk7XG5cdCAgfSxcblx0ICAvLyAxOS40LjIuNSBTeW1ib2wua2V5Rm9yKHN5bSlcblx0ICBrZXlGb3I6IGZ1bmN0aW9uIGtleUZvcihrZXkpe1xuXHQgICAgaWYoaXNTeW1ib2woa2V5KSlyZXR1cm4ga2V5T2YoU3ltYm9sUmVnaXN0cnksIGtleSk7XG5cdCAgICB0aHJvdyBUeXBlRXJyb3Ioa2V5ICsgJyBpcyBub3QgYSBzeW1ib2whJyk7XG5cdCAgfSxcblx0ICB1c2VTZXR0ZXI6IGZ1bmN0aW9uKCl7IHNldHRlciA9IHRydWU7IH0sXG5cdCAgdXNlU2ltcGxlOiBmdW5jdGlvbigpeyBzZXR0ZXIgPSBmYWxzZTsgfVxuXHR9KTtcblx0XG5cdCRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsICdPYmplY3QnLCB7XG5cdCAgLy8gMTkuMS4yLjIgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxuXHQgIGNyZWF0ZTogJGNyZWF0ZSxcblx0ICAvLyAxOS4xLjIuNCBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcylcblx0ICBkZWZpbmVQcm9wZXJ0eTogJGRlZmluZVByb3BlcnR5LFxuXHQgIC8vIDE5LjEuMi4zIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpXG5cdCAgZGVmaW5lUHJvcGVydGllczogJGRlZmluZVByb3BlcnRpZXMsXG5cdCAgLy8gMTkuMS4yLjYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBQKVxuXHQgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogJGdldE93blByb3BlcnR5RGVzY3JpcHRvcixcblx0ICAvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxuXHQgIGdldE93blByb3BlcnR5TmFtZXM6ICRnZXRPd25Qcm9wZXJ0eU5hbWVzLFxuXHQgIC8vIDE5LjEuMi44IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoTylcblx0ICBnZXRPd25Qcm9wZXJ0eVN5bWJvbHM6ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHNcblx0fSk7XG5cdFxuXHQvLyAyNC4zLjIgSlNPTi5zdHJpbmdpZnkodmFsdWUgWywgcmVwbGFjZXIgWywgc3BhY2VdXSlcblx0JEpTT04gJiYgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoIVVTRV9OQVRJVkUgfHwgJGZhaWxzKGZ1bmN0aW9uKCl7XG5cdCAgdmFyIFMgPSAkU3ltYm9sKCk7XG5cdCAgLy8gTVMgRWRnZSBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMge31cblx0ICAvLyBXZWJLaXQgY29udmVydHMgc3ltYm9sIHZhbHVlcyB0byBKU09OIGFzIG51bGxcblx0ICAvLyBWOCB0aHJvd3Mgb24gYm94ZWQgc3ltYm9sc1xuXHQgIHJldHVybiBfc3RyaW5naWZ5KFtTXSkgIT0gJ1tudWxsXScgfHwgX3N0cmluZ2lmeSh7YTogU30pICE9ICd7fScgfHwgX3N0cmluZ2lmeShPYmplY3QoUykpICE9ICd7fSc7XG5cdH0pKSwgJ0pTT04nLCB7XG5cdCAgc3RyaW5naWZ5OiBmdW5jdGlvbiBzdHJpbmdpZnkoaXQpe1xuXHQgICAgaWYoaXQgPT09IHVuZGVmaW5lZCB8fCBpc1N5bWJvbChpdCkpcmV0dXJuOyAvLyBJRTggcmV0dXJucyBzdHJpbmcgb24gdW5kZWZpbmVkXG5cdCAgICB2YXIgYXJncyA9IFtpdF1cblx0ICAgICAgLCBpICAgID0gMVxuXHQgICAgICAsIHJlcGxhY2VyLCAkcmVwbGFjZXI7XG5cdCAgICB3aGlsZShhcmd1bWVudHMubGVuZ3RoID4gaSlhcmdzLnB1c2goYXJndW1lbnRzW2krK10pO1xuXHQgICAgcmVwbGFjZXIgPSBhcmdzWzFdO1xuXHQgICAgaWYodHlwZW9mIHJlcGxhY2VyID09ICdmdW5jdGlvbicpJHJlcGxhY2VyID0gcmVwbGFjZXI7XG5cdCAgICBpZigkcmVwbGFjZXIgfHwgIWlzQXJyYXkocmVwbGFjZXIpKXJlcGxhY2VyID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSl7XG5cdCAgICAgIGlmKCRyZXBsYWNlcil2YWx1ZSA9ICRyZXBsYWNlci5jYWxsKHRoaXMsIGtleSwgdmFsdWUpO1xuXHQgICAgICBpZighaXNTeW1ib2wodmFsdWUpKXJldHVybiB2YWx1ZTtcblx0ICAgIH07XG5cdCAgICBhcmdzWzFdID0gcmVwbGFjZXI7XG5cdCAgICByZXR1cm4gX3N0cmluZ2lmeS5hcHBseSgkSlNPTiwgYXJncyk7XG5cdCAgfVxuXHR9KTtcblx0XG5cdC8vIDE5LjQuMy40IFN5bWJvbC5wcm90b3R5cGVbQEB0b1ByaW1pdGl2ZV0oaGludClcblx0JFN5bWJvbFtQUk9UT1RZUEVdW1RPX1BSSU1JVElWRV0gfHwgX193ZWJwYWNrX3JlcXVpcmVfXygxMCkoJFN5bWJvbFtQUk9UT1RZUEVdLCBUT19QUklNSVRJVkUsICRTeW1ib2xbUFJPVE9UWVBFXS52YWx1ZU9mKTtcblx0Ly8gMTkuNC4zLjUgU3ltYm9sLnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXVxuXHRzZXRUb1N0cmluZ1RhZygkU3ltYm9sLCAnU3ltYm9sJyk7XG5cdC8vIDIwLjIuMS45IE1hdGhbQEB0b1N0cmluZ1RhZ11cblx0c2V0VG9TdHJpbmdUYWcoTWF0aCwgJ01hdGgnLCB0cnVlKTtcblx0Ly8gMjQuMy4zIEpTT05bQEB0b1N0cmluZ1RhZ11cblx0c2V0VG9TdHJpbmdUYWcoZ2xvYmFsLkpTT04sICdKU09OJywgdHJ1ZSk7XG5cbi8qKiovIH0sXG4vKiAxOTUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdHZhciBNRVRBICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oNDQpKCdtZXRhJylcblx0ICAsIGlzT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMylcblx0ICAsIGhhcyAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygyOSlcblx0ICAsIHNldERlc2MgID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMSkuZlxuXHQgICwgaWQgICAgICAgPSAwO1xuXHR2YXIgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZSB8fCBmdW5jdGlvbigpe1xuXHQgIHJldHVybiB0cnVlO1xuXHR9O1xuXHR2YXIgRlJFRVpFID0gIV9fd2VicGFja19yZXF1aXJlX18oMTYpKGZ1bmN0aW9uKCl7XG5cdCAgcmV0dXJuIGlzRXh0ZW5zaWJsZShPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pKTtcblx0fSk7XG5cdHZhciBzZXRNZXRhID0gZnVuY3Rpb24oaXQpe1xuXHQgIHNldERlc2MoaXQsIE1FVEEsIHt2YWx1ZToge1xuXHQgICAgaTogJ08nICsgKytpZCwgLy8gb2JqZWN0IElEXG5cdCAgICB3OiB7fSAgICAgICAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIElEc1xuXHQgIH19KTtcblx0fTtcblx0dmFyIGZhc3RLZXkgPSBmdW5jdGlvbihpdCwgY3JlYXRlKXtcblx0ICAvLyByZXR1cm4gcHJpbWl0aXZlIHdpdGggcHJlZml4XG5cdCAgaWYoIWlzT2JqZWN0KGl0KSlyZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnID8gaXQgOiAodHlwZW9mIGl0ID09ICdzdHJpbmcnID8gJ1MnIDogJ1AnKSArIGl0O1xuXHQgIGlmKCFoYXMoaXQsIE1FVEEpKXtcblx0ICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG5cdCAgICBpZighaXNFeHRlbnNpYmxlKGl0KSlyZXR1cm4gJ0YnO1xuXHQgICAgLy8gbm90IG5lY2Vzc2FyeSB0byBhZGQgbWV0YWRhdGFcblx0ICAgIGlmKCFjcmVhdGUpcmV0dXJuICdFJztcblx0ICAgIC8vIGFkZCBtaXNzaW5nIG1ldGFkYXRhXG5cdCAgICBzZXRNZXRhKGl0KTtcblx0ICAvLyByZXR1cm4gb2JqZWN0IElEXG5cdCAgfSByZXR1cm4gaXRbTUVUQV0uaTtcblx0fTtcblx0dmFyIGdldFdlYWsgPSBmdW5jdGlvbihpdCwgY3JlYXRlKXtcblx0ICBpZighaGFzKGl0LCBNRVRBKSl7XG5cdCAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuXHQgICAgaWYoIWlzRXh0ZW5zaWJsZShpdCkpcmV0dXJuIHRydWU7XG5cdCAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuXHQgICAgaWYoIWNyZWF0ZSlyZXR1cm4gZmFsc2U7XG5cdCAgICAvLyBhZGQgbWlzc2luZyBtZXRhZGF0YVxuXHQgICAgc2V0TWV0YShpdCk7XG5cdCAgLy8gcmV0dXJuIGhhc2ggd2VhayBjb2xsZWN0aW9ucyBJRHNcblx0ICB9IHJldHVybiBpdFtNRVRBXS53O1xuXHR9O1xuXHQvLyBhZGQgbWV0YWRhdGEgb24gZnJlZXplLWZhbWlseSBtZXRob2RzIGNhbGxpbmdcblx0dmFyIG9uRnJlZXplID0gZnVuY3Rpb24oaXQpe1xuXHQgIGlmKEZSRUVaRSAmJiBtZXRhLk5FRUQgJiYgaXNFeHRlbnNpYmxlKGl0KSAmJiAhaGFzKGl0LCBNRVRBKSlzZXRNZXRhKGl0KTtcblx0ICByZXR1cm4gaXQ7XG5cdH07XG5cdHZhciBtZXRhID0gbW9kdWxlLmV4cG9ydHMgPSB7XG5cdCAgS0VZOiAgICAgIE1FVEEsXG5cdCAgTkVFRDogICAgIGZhbHNlLFxuXHQgIGZhc3RLZXk6ICBmYXN0S2V5LFxuXHQgIGdldFdlYWs6ICBnZXRXZWFrLFxuXHQgIG9uRnJlZXplOiBvbkZyZWV6ZVxuXHR9O1xuXG4vKioqLyB9LFxuLyogMTk2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgZ2xvYmFsICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpXG5cdCAgLCBjb3JlICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oNylcblx0ICAsIExJQlJBUlkgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygyNylcblx0ICAsIHdrc0V4dCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1NSlcblx0ICAsIGRlZmluZVByb3BlcnR5ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMSkuZjtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihuYW1lKXtcblx0ICB2YXIgJFN5bWJvbCA9IGNvcmUuU3ltYm9sIHx8IChjb3JlLlN5bWJvbCA9IExJQlJBUlkgPyB7fSA6IGdsb2JhbC5TeW1ib2wgfHwge30pO1xuXHQgIGlmKG5hbWUuY2hhckF0KDApICE9ICdfJyAmJiAhKG5hbWUgaW4gJFN5bWJvbCkpZGVmaW5lUHJvcGVydHkoJFN5bWJvbCwgbmFtZSwge3ZhbHVlOiB3a3NFeHQuZihuYW1lKX0pO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMTk3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHR2YXIgZ2V0S2V5cyAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygzNClcblx0ICAsIHRvSU9iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oMzYpO1xuXHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iamVjdCwgZWwpe1xuXHQgIHZhciBPICAgICAgPSB0b0lPYmplY3Qob2JqZWN0KVxuXHQgICAgLCBrZXlzICAgPSBnZXRLZXlzKE8pXG5cdCAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXG5cdCAgICAsIGluZGV4ICA9IDBcblx0ICAgICwga2V5O1xuXHQgIHdoaWxlKGxlbmd0aCA+IGluZGV4KWlmKE9ba2V5ID0ga2V5c1tpbmRleCsrXV0gPT09IGVsKXJldHVybiBrZXk7XG5cdH07XG5cbi8qKiovIH0sXG4vKiAxOTggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIGFsbCBlbnVtZXJhYmxlIG9iamVjdCBrZXlzLCBpbmNsdWRlcyBzeW1ib2xzXG5cdHZhciBnZXRLZXlzID0gX193ZWJwYWNrX3JlcXVpcmVfXygzNClcblx0ICAsIGdPUFMgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE5OSlcblx0ICAsIHBJRSAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIwMCk7XG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuXHQgIHZhciByZXN1bHQgICAgID0gZ2V0S2V5cyhpdClcblx0ICAgICwgZ2V0U3ltYm9scyA9IGdPUFMuZjtcblx0ICBpZihnZXRTeW1ib2xzKXtcblx0ICAgIHZhciBzeW1ib2xzID0gZ2V0U3ltYm9scyhpdClcblx0ICAgICAgLCBpc0VudW0gID0gcElFLmZcblx0ICAgICAgLCBpICAgICAgID0gMFxuXHQgICAgICAsIGtleTtcblx0ICAgIHdoaWxlKHN5bWJvbHMubGVuZ3RoID4gaSlpZihpc0VudW0uY2FsbChpdCwga2V5ID0gc3ltYm9sc1tpKytdKSlyZXN1bHQucHVzaChrZXkpO1xuXHQgIH0gcmV0dXJuIHJlc3VsdDtcblx0fTtcblxuLyoqKi8gfSxcbi8qIDE5OSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0ZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcblxuLyoqKi8gfSxcbi8qIDIwMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0ZXhwb3J0cy5mID0ge30ucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbi8qKiovIH0sXG4vKiAyMDEgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdC8vIDcuMi4yIElzQXJyYXkoYXJndW1lbnQpXG5cdHZhciBjb2YgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDM4KTtcblx0bW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIGlzQXJyYXkoYXJnKXtcblx0ICByZXR1cm4gY29mKGFyZykgPT0gJ0FycmF5Jztcblx0fTtcblxuLyoqKi8gfSxcbi8qIDIwMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0dmFyIHBJRSAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygyMDApXG5cdCAgLCBjcmVhdGVEZXNjICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTkpXG5cdCAgLCB0b0lPYmplY3QgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMzYpXG5cdCAgLCB0b1ByaW1pdGl2ZSAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMTgpXG5cdCAgLCBoYXMgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oMjkpXG5cdCAgLCBJRThfRE9NX0RFRklORSA9IF9fd2VicGFja19yZXF1aXJlX18oMTQpXG5cdCAgLCBnT1BEICAgICAgICAgICA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cdFxuXHRleHBvcnRzLmYgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE1KSA/IGdPUEQgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCl7XG5cdCAgTyA9IHRvSU9iamVjdChPKTtcblx0ICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG5cdCAgaWYoSUU4X0RPTV9ERUZJTkUpdHJ5IHtcblx0ICAgIHJldHVybiBnT1BEKE8sIFApO1xuXHQgIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cblx0ICBpZihoYXMoTywgUCkpcmV0dXJuIGNyZWF0ZURlc2MoIXBJRS5mLmNhbGwoTywgUCksIE9bUF0pO1xuXHR9O1xuXG4vKioqLyB9LFxuLyogMjAzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXG5cbi8qKiovIH0sXG4vKiAyMDQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdF9fd2VicGFja19yZXF1aXJlX18oMTk2KSgnYXN5bmNJdGVyYXRvcicpO1xuXG4vKioqLyB9LFxuLyogMjA1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKDE5NikoJ29ic2VydmFibGUnKTtcblxuLyoqKi8gfSxcbi8qIDIwNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0bW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDtcblx0ICByZXR1cm4gX3ZtLl9jKCdkaXYnLCB7XG5cdCAgICBjbGFzczoge1xuXHQgICAgICBvcGVuOiBfdm0uc2hvd0Ryb3Bkb3duXG5cdCAgICB9LFxuXHQgICAgc3RhdGljU3R5bGU6IHtcblx0ICAgICAgXCJwb3NpdGlvblwiOiBcInJlbGF0aXZlXCJcblx0ICAgIH1cblx0ICB9LCBbX3ZtLl9jKCdpbnB1dCcsIHtcblx0ICAgIGRpcmVjdGl2ZXM6IFt7XG5cdCAgICAgIG5hbWU6IFwibW9kZWxcIixcblx0ICAgICAgcmF3TmFtZTogXCJ2LW1vZGVsXCIsXG5cdCAgICAgIHZhbHVlOiAoX3ZtLnZhbCksXG5cdCAgICAgIGV4cHJlc3Npb246IFwidmFsXCJcblx0ICAgIH1dLFxuXHQgICAgc3RhdGljQ2xhc3M6IFwiZm9ybS1jb250cm9sXCIsXG5cdCAgICBhdHRyczoge1xuXHQgICAgICBcImF1dG9jb21wbGV0ZVwiOiBcIm9mZlwiLFxuXHQgICAgICBcInBsYWNlaG9sZGVyXCI6IF92bS5wbGFjZWhvbGRlcixcblx0ICAgICAgXCJ0eXBlXCI6IF92bS50eXBlXG5cdCAgICB9LFxuXHQgICAgZG9tUHJvcHM6IHtcblx0ICAgICAgXCJ2YWx1ZVwiOiBfdm0uX3MoX3ZtLnZhbClcblx0ICAgIH0sXG5cdCAgICBvbjoge1xuXHQgICAgICBcImJsdXJcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgX3ZtLnNob3dEcm9wZG93biA9IGZhbHNlXG5cdCAgICAgIH0sXG5cdCAgICAgIFwia2V5ZG93blwiOiBbZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgaWYgKF92bS5faygkZXZlbnQua2V5Q29kZSwgXCJkb3duXCIsIDQwKSkgeyByZXR1cm47IH1cblx0ICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0ICAgICAgICBfdm0uZG93bigkZXZlbnQpXG5cdCAgICAgIH0sIGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgIGlmIChfdm0uX2soJGV2ZW50LmtleUNvZGUsIFwiZW50ZXJcIiwgMTMpKSB7IHJldHVybjsgfVxuXHQgICAgICAgIF92bS5oaXQoJGV2ZW50KVxuXHQgICAgICB9LCBmdW5jdGlvbigkZXZlbnQpIHtcblx0ICAgICAgICBpZiAoX3ZtLl9rKCRldmVudC5rZXlDb2RlLCBcImVzY1wiLCAyNykpIHsgcmV0dXJuOyB9XG5cdCAgICAgICAgX3ZtLnJlc2V0KCRldmVudClcblx0ICAgICAgfSwgZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgaWYgKF92bS5faygkZXZlbnQua2V5Q29kZSwgXCJ1cFwiLCAzOCkpIHsgcmV0dXJuOyB9XG5cdCAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgX3ZtLnVwKCRldmVudClcblx0ICAgICAgfV0sXG5cdCAgICAgIFwiaW5wdXRcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG5cdCAgICAgICAgaWYgKCRldmVudC50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybjsgfVxuXHQgICAgICAgIF92bS52YWwgPSAkZXZlbnQudGFyZ2V0LnZhbHVlXG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9KSwgX3ZtLl92KFwiIFwiKSwgX3ZtLl9jKCd1bCcsIHtcblx0ICAgIHJlZjogXCJkcm9wZG93blwiLFxuXHQgICAgc3RhdGljQ2xhc3M6IFwiZHJvcGRvd24tbWVudVwiXG5cdCAgfSwgX3ZtLl9sKChfdm0uaXRlbXMpLCBmdW5jdGlvbihpdGVtLCBpKSB7XG5cdCAgICByZXR1cm4gX3ZtLl9jKCdsaScsIHtcblx0ICAgICAgY2xhc3M6IHtcblx0ICAgICAgICBhY3RpdmU6IF92bS5pc0FjdGl2ZShpKVxuXHQgICAgICB9XG5cdCAgICB9LCBbX3ZtLl9jKCdhJywge1xuXHQgICAgICBvbjoge1xuXHQgICAgICAgIFwibW91c2Vkb3duXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdCAgICAgICAgICBfdm0uaGl0KCRldmVudClcblx0ICAgICAgICB9LFxuXHQgICAgICAgIFwibW91c2Vtb3ZlXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuXHQgICAgICAgICAgX3ZtLnNldEFjdGl2ZShpKVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSwgW192bS5fYyhfdm0udGVtcGxhdGVDb21wLCB7XG5cdCAgICAgIHRhZzogXCJjb21wb25lbnRcIixcblx0ICAgICAgYXR0cnM6IHtcblx0ICAgICAgICBcIml0ZW1cIjogaXRlbVxuXHQgICAgICB9XG5cdCAgICB9KV0sIDEpXSlcblx0ICB9KSldKVxuXHR9LHN0YXRpY1JlbmRlckZuczogW119XG5cdGlmIChmYWxzZSkge1xuXHQgIG1vZHVsZS5ob3QuYWNjZXB0KClcblx0ICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG5cdCAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi01YjVmNWU5NFwiLCBtb2R1bGUuZXhwb3J0cylcblx0ICB9XG5cdH1cblxuLyoqKi8gfVxuLyoqKioqKi8gXSlcbn0pO1xuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dnVlLXN0cmFwLmpzLm1hcFxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtc3RyYXAvZGlzdC92dWUtc3RyYXAuanNcbi8vIG1vZHVsZSBpZCA9IDU0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0="); +eval("// style-loader: Adds some css to the DOM by adding a + + + + \ No newline at end of file diff --git a/resources/assets/js/components/importer/importer.vue b/resources/assets/js/components/importer/importer.vue index 32ed8df983..33b19d502f 100644 --- a/resources/assets/js/components/importer/importer.vue +++ b/resources/assets/js/components/importer/importer.vue @@ -7,95 +7,9 @@ th { font-size: 13px; } - -@endsection diff --git a/resources/views/importer/fieldmapper.blade.php b/resources/views/importer/fieldmapper.blade.php deleted file mode 100644 index 72f614ccdb..0000000000 --- a/resources/views/importer/fieldmapper.blade.php +++ /dev/null @@ -1,233 +0,0 @@ -@extends('layouts.default') - -{{-- Page title --}} -@section('title') - Map Import Fields - @parent -@stop - -@section('header_right') - - {{ trans('general.back') }} -@stop - - - -{{-- Page content --}} - -@section('content') - -
-
-
-
-

- -

- @if (isset($helpText)) -
- -
- @endif -
- -
-
- - - {{ csrf_field() }} - -
-                            @php
-                            print_r($first_row);
-                            @endphp
-                        
- -
-

Standard Fields

-
-
- -
- -
- {!! Form::header_list($header_rows, 'user_name_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'username_header', Input::old('header_row'), 'select2') !!} -
-
- - -
- -
- {!! Form::header_list($header_rows, 'email_header', Input::old('header_row'), 'select2') !!} -
-
- - -
- -
- {!! Form::header_list($header_rows, 'item_name_header', Input::old('header_row'), 'select2') !!} -
-
- - -
- -
- {!! Form::header_list($header_rows, 'asset_tag_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'serial_number_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'model_name_header', Input::old('header_row'), 'select2') !!} -
-
- - -
- -
- {!! Form::header_list($header_rows, 'model_number_header', Input::old('header_row'), 'select2') !!} -
-
- - -
- -
- {!! Form::header_list($header_rows, 'category_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'manufacturer_header', Input::old('header_row'), 'select2') !!} -
-
- - -
- -
- {!! Form::header_list($header_rows, 'company_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'location_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'purchase_date_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'purchase_cost_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'status_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'notes_header', Input::old('header_row'), 'select2') !!} -
-
- -
- -
- {!! Form::header_list($header_rows, 'image_header', Input::old('header_row'), 'select2') !!} -
-
- - @if ($custom_fields->count() > 0) -
-

Custom Fields

-
-
- @foreach ($custom_fields as $custom_field) -
- -
- {!! Form::header_list($header_rows, 'image_header', Input::old('header_row'), 'select2') !!} -
-
- @endforeach - @endif - - - - - -
-
-
-
- - @if ((isset($helpText)) && (isset($helpTitle))) -
- × -

- {{ $helpTitle}} -

-

{{ $helpText }}

-
- @endif -
- -@stop - diff --git a/resources/views/importer/import.blade.php b/resources/views/importer/import.blade.php new file mode 100644 index 0000000000..e78547f884 --- /dev/null +++ b/resources/views/importer/import.blade.php @@ -0,0 +1,86 @@ +@extends('layouts/default') + + +{{-- Hide importer until vue has rendered it, if we continue using vue for other things we should move this higher in the style --}} + +{{-- Page title --}} +@section('title') +{{ trans('general.import') }} +@parent +@stop + +{{-- Page content --}} +@section('content') +
+ +
+ @{{ alert.message }} + +
+
+
+
+
+ + + Select Import File... + + + +
+
+
+
+
+ @{{ progress.statusText }} +
+
+
+
+
+
+
+ + + + + + + + + + +
FileCreatedSize
+
+
+
+
+
+
+
+
+@stop + +@section('moar_scripts') + +@endsection diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index 437e59d033..95b584c88d 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -473,8 +473,8 @@ @endcan @can('create', \App\Models\Asset::class) - - + + @lang('general.import') diff --git a/routes/web.php b/routes/web.php index 9654333508..1d40b316d4 100644 --- a/routes/web.php +++ b/routes/web.php @@ -171,7 +171,20 @@ Route::resource('groups', 'GroupsController', [ 'parameters' => ['group' => 'group_id'] ]); - +/* +|-------------------------------------------------------------------------- +| Importer Routes +|-------------------------------------------------------------------------- +| +| +| +*/ +Route::group([ 'prefix' => 'import', 'middleware' => ['auth']], function () { + Route::get('/', [ + 'as' => 'imports.index', + 'uses' => 'ImportsController@index' + ]); +}); /* diff --git a/routes/web/hardware.php b/routes/web/hardware.php index e26b739038..8a3453709a 100644 --- a/routes/web/hardware.php +++ b/routes/web/hardware.php @@ -79,23 +79,6 @@ Route::group( 'uses' => 'AssetsController@displayFile' ]); - Route::post( 'import/process/', [ 'as' => 'assets/import/process-file', - 'uses' => 'AssetsController@postProcessImportFile' - ]); - - Route::get( 'import/delete/{filename}', [ 'as' => 'assets/import/delete-file', - 'uses' => 'AssetsController@getDeleteImportFile' - ]); - - Route::get('import/map',[ - 'as' => 'import.map', - 'uses' => 'AssetsController@getImportMap' - ]); - - Route::get('import',[ - 'as' => 'assets/import', - 'uses' => 'AssetsController@getImportUpload' - ]); Route::post( 'bulkedit', diff --git a/sample_csvs/MOCK_USERS.csv b/sample_csvs/MOCK_USERS.csv new file mode 100644 index 0000000000..aae13a9dce --- /dev/null +++ b/sample_csvs/MOCK_USERS.csv @@ -0,0 +1,1001 @@ +First Name,Last Name,email,User name,Location,Phone Num,Job Title For User,Employee Number,Company +Blanche,O'Collopy,bocollopy0@livejournal.com,bocollopy0,Hinapalanan,63-(199)661-2186,Clinical Specialist,7080919053,Morar-Ward +Jessie,Primo,jprimo1@newsvine.com,jprimo1,Korenovsk,7-(885)578-0266,Paralegal,6284292031,Jast-Stiedemann +Nelia,Coughtrey,ncoughtrey2@geocities.com,ncoughtrey2,Zhexiao,86-(366)635-5884,Nurse Practicioner,7242692202,Goldner-Cremin +Pascale,Wimpeney,pwimpeney3@mtv.com,pwimpeney3,Kuče,385-(688)644-8322,Senior Sales Associate,9173736066,"Paucek, Schmitt and Hagenes" +Alec,Twidle,atwidle4@ovh.net,atwidle4,Shi’ao,86-(163)912-1915,Human Resources Manager,4692183691,Schimmel and Sons +Karalee,Carroll,kcarroll5@devhub.com,kcarroll5,Huaidian,86-(303)287-0739,Civil Engineer,1530903416,Schuster LLC +Danny,Yeiles,dyeiles6@wikipedia.org,dyeiles6,Koundara,224-(953)650-5363,Software Engineer II,7026212001,"Ebert, Windler and Hessel" +Taffy,Benson,tbenson7@mit.edu,tbenson7,Nanying,86-(152)931-1194,Dental Hygienist,4576525239,Jerde Inc +Hall,Tonepohl,htonepohl8@bandcamp.com,htonepohl8,Primorsko-Akhtarsk,7-(743)929-2565,Computer Systems Analyst III,6187297644,Kohler and Sons +Gus,Tomczykowski,gtomczykowski9@hostgator.com,gtomczykowski9,Arrah,225-(926)325-4040,Executive Secretary,9237527535,"Luettgen, Kshlerin and Carroll" +Casandra,Retchford,cretchforda@gizmodo.com,cretchforda,Lasi Dua,62-(813)604-3660,Teacher,0068486472,Rempel Inc +Judie,Fowler,jfowlerb@virginia.edu,jfowlerb,Ōgaki,81-(521)313-4757,Occupational Therapist,1692241737,Bins Inc +Willy,Walters,wwaltersc@cloudflare.com,wwaltersc,Mungkin,62-(114)187-7377,Electrical Engineer,1185027149,Toy-Hyatt +Trace,Tingly,ttinglyd@issuu.com,ttinglyd,Esigodini,263-(795)699-2623,Office Assistant II,9588821797,Satterfield LLC +Rustin,Withrington,rwithringtone@purevolume.com,rwithringtone,Xinjie,86-(703)213-0549,Marketing Manager,8707099886,O'Conner-Hoeger +Loria,McKendry,lmckendryf@imgur.com,lmckendryf,Eiriz,351-(660)417-9204,Administrative Assistant II,2622958684,Oberbrunner and Sons +Blancha,Carlesso,bcarlessog@bravesites.com,bcarlessog,Helsingborg,46-(218)729-2556,Account Representative I,1864046597,Stroman-Marks +Whitney,Olman,wolmanh@slashdot.org,wolmanh,Lisia Góra,48-(907)614-5768,Speech Pathologist,7143970867,Keebler-Wintheiser +Bond,McBain,bmcbaini@hc360.com,bmcbaini,Lesnoye,7-(515)172-7238,Social Worker,6816673581,Cassin LLC +Raeann,Kubach,rkubachj@a8.net,rkubachj,Saray,994-(690)524-2937,Electrical Engineer,1829082000,"Kiehn, Dicki and O'Reilly" +Feodor,Kersey,fkerseyk@hibu.com,fkerseyk,Salam,62-(530)992-3129,Financial Advisor,0027333248,Kassulke-Wuckert +Boyd,Delamere,bdelamerel@europa.eu,bdelamerel,Starigrad,385-(464)217-6673,Quality Control Specialist,7362162391,Marquardt Group +Terrijo,Spaducci,tspaduccim@yale.edu,tspaduccim,Pereiras,351-(169)619-5395,Health Coach II,9383160780,"Reynolds, Bins and Wunsch" +Brandtr,Rollings,brollingsn@java.com,brollingsn,Palencia,502-(601)904-4191,Assistant Professor,9604788698,Farrell LLC +Diane,Bernaciak,dbernaciako@senate.gov,dbernaciako,Bitin,63-(465)596-5888,Human Resources Assistant II,1297195655,Orn Inc +Bertie,Sreenan,bsreenanp@japanpost.jp,bsreenanp,Muzambinho,55-(991)980-2128,VP Accounting,9614791969,Wiza-Quitzon +Marylinda,Hanlon,mhanlonq@sourceforge.net,mhanlonq,San José de Río Tinto,504-(312)801-5239,Associate Professor,4247222201,Heller and Sons +Darrin,MacPhaden,dmacphadenr@berkeley.edu,dmacphadenr,Radlje ob Dravi,386-(696)423-3227,Community Outreach Specialist,8724422533,Bradtke and Sons +Kizzee,Pilmer,kpilmers@mlb.com,kpilmers,Soio,244-(244)226-8720,Software Engineer I,7351560250,"Hauck, Gottlieb and Roberts" +Murdoch,Heijne,mheijnet@unblog.fr,mheijnet,Pukë,355-(994)349-7229,Mechanical Systems Engineer,9123797894,"Bailey, Collier and Labadie" +Maryann,Labat,mlabatu@mozilla.com,mlabatu,Skhira,216-(174)936-3617,Human Resources Assistant III,7255325211,"Feil, Kozey and Goldner" +Carolus,Dombrell,cdombrellv@forbes.com,cdombrellv,Pāvilosta,371-(908)875-7818,Account Executive,2616418460,Hammes LLC +Sheena,Goede,sgoedew@samsung.com,sgoedew,Bitkine,235-(312)893-5822,Professor,9784543257,Wolf Inc +Dottie,Leare,dlearex@surveymonkey.com,dlearex,Pugeran,62-(693)693-0486,Analog Circuit Design manager,5256401955,"Cole, Fisher and Spinka" +Jess,Stammer,jstammery@bloglines.com,jstammery,Margherita,256-(648)534-6980,Account Representative I,3022569831,Keeling Group +Izabel,Wix,iwixz@latimes.com,iwixz,Shatian,86-(812)279-4898,Physical Therapy Assistant,5047185605,Feil-Gutkowski +Corrinne,Lowrie,clowrie10@noaa.gov,clowrie10,Dongyuan,86-(567)116-4092,Programmer I,4016980801,Dickens and Sons +Ralph,Brabbs,rbrabbs11@desdev.cn,rbrabbs11,Lokea,62-(733)726-2227,Staff Scientist,3126986722,Pouros LLC +Wally,Boanas,wboanas12@deviantart.com,wboanas12,Garhi Khairo,92-(983)138-6735,Senior Developer,9121792674,Bauch-Hodkiewicz +Willyt,Poxton,wpoxton13@eepurl.com,wpoxton13,Ciénaga,57-(530)166-8558,Account Coordinator,5226358938,Orn-Grady +Sanderson,Colledge,scolledge14@mozilla.com,scolledge14,Capalonga,63-(228)896-9731,Dental Hygienist,2367310122,"Kessler, Bechtelar and Fisher" +Marshal,Dillet,mdillet15@sakura.ne.jp,mdillet15,Camperdown,27-(887)538-9433,Social Worker,9119456573,Heller-Baumbach +Dario,Osler,dosler16@slideshare.net,dosler16,Fulong,86-(686)394-2367,Human Resources Assistant I,0834912236,Strosin Inc +Porter,Whitehall,pwhitehall17@economist.com,pwhitehall17,Alīpur,92-(345)545-1627,Programmer Analyst I,9907315249,Thiel-Schinner +Cyrille,Lough,clough18@foxnews.com,clough18,Jiukeng,86-(720)297-5199,Marketing Assistant,4745558287,Bailey-Hauck +Brina,Ashwell,bashwell19@cmu.edu,bashwell19,Três Pontas,55-(437)327-8074,VP Marketing,8645272598,Blick Group +Ki,Freeborn,kfreeborn1a@hhs.gov,kfreeborn1a,Pisz,48-(490)682-6629,Office Assistant I,6953353384,"Larson, Becker and Reinger" +Gaye,Hillam,ghillam1b@creativecommons.org,ghillam1b,Lazaro Cardenas,52-(744)187-7616,Senior Cost Accountant,5489719737,"Abernathy, Zulauf and Davis" +Herculie,Seage,hseage1c@photobucket.com,hseage1c,Careva Ćuprija,387-(372)396-4601,Environmental Tech,4880024112,"Wintheiser, Luettgen and Jerde" +Inessa,Baldack,ibaldack1d@marriott.com,ibaldack1d,Tirah,972-(148)288-3311,Environmental Tech,4012420682,"Carter, Hoppe and Mertz" +Sherline,Alliston,salliston1e@cnet.com,salliston1e,Prado Siongco,63-(641)703-7801,VP Sales,1648555802,Glover LLC +Kristin,Pitson,kpitson1f@sogou.com,kpitson1f,Las Flores,52-(755)660-4401,Financial Advisor,3629602851,Denesik-Schuster +Portia,Winspur,pwinspur1g@imdb.com,pwinspur1g,Cibolang,62-(194)231-7712,Engineer II,8827050418,"Osinski, Emard and Jast" +Benedict,Churchard,bchurchard1h@dell.com,bchurchard1h,Xinglong,86-(452)414-0407,Human Resources Assistant IV,1155598784,Hane and Sons +Mariya,Bahlmann,mbahlmann1i@npr.org,mbahlmann1i,Wuyanquan,86-(898)637-0482,GIS Technical Architect,1627870318,Abernathy Group +Harri,McAleese,hmcaleese1j@theglobeandmail.com,hmcaleese1j,Nularan,62-(717)480-2343,Accounting Assistant I,0181278391,Senger and Sons +Roda,McGriffin,rmcgriffin1k@symantec.com,rmcgriffin1k,Raduzhnyy,7-(513)767-6738,Sales Associate,7142006153,Mosciski Group +Carolyn,Jurges,cjurges1l@berkeley.edu,cjurges1l,Rotterdam,31-(827)912-2109,Senior Developer,8573938994,Terry and Sons +Darnell,Lettuce,dlettuce1m@google.com.au,dlettuce1m,Solnechnogorsk,7-(165)514-6628,Sales Associate,3973069883,Volkman-Abbott +Johan,Herche,jherche1n@w3.org,jherche1n,Krzeszów,48-(981)281-5260,Librarian,8066763190,Larkin-Emard +Ginelle,Digle,gdigle1o@4shared.com,gdigle1o,Alukama,62-(819)194-6623,Account Executive,0227839102,Sipes-Bauch +Bunny,Macconaghy,bmacconaghy1p@huffingtonpost.com,bmacconaghy1p,Huangqiao,86-(206)588-4549,Quality Engineer,6517079629,"Dach, Marquardt and Lubowitz" +Olivette,Tomczykiewicz,otomczykiewicz1q@eventbrite.com,otomczykiewicz1q,Sigayevo,7-(309)891-2091,Desktop Support Technician,3998906258,Schamberger Group +Kerwinn,Le Brom,klebrom1r@smh.com.au,klebrom1r,Lestijärvi,358-(747)269-4952,Compensation Analyst,1348822481,Kub Inc +Obidiah,Radke,oradke1s@imdb.com,oradke1s,Xinhua,86-(381)923-1757,Accounting Assistant II,1145530044,Prosacco Inc +Jermaine,Joire,jjoire1t@sun.com,jjoire1t,Huangpi,86-(814)411-4884,Developer IV,4849811027,"Schuppe, Jaskolski and Jones" +Bobine,Jessope,bjessope1u@sbwire.com,bjessope1u,Nàng Mau,84-(454)818-4039,Budget/Accounting Analyst I,3193701467,"Gislason, Batz and Kub" +Brinn,Calam,bcalam1v@dedecms.com,bcalam1v,Anan,81-(795)861-8389,Administrative Officer,2724742117,Shanahan Inc +Ax,Briiginshaw,abriiginshaw1w@shop-pro.jp,abriiginshaw1w,Bantay,63-(158)907-3803,Senior Sales Associate,1449794491,"Beer, Hoppe and Walsh" +Sher,Wylam,swylam1x@cisco.com,swylam1x,Dmitrov,7-(454)562-7954,Health Coach IV,1778479766,"Bogisich, Gerhold and Dooley" +Rodger,Mecco,rmecco1y@oakley.com,rmecco1y,Bulahblangaro,62-(698)245-6039,GIS Technical Architect,6679143640,Kulas Group +Gilly,Coggon,gcoggon1z@merriam-webster.com,gcoggon1z,Ramana,994-(225)981-5577,Statistician II,8663020252,Bogan-Swaniawski +Buffy,Kemsley,bkemsley20@discuz.net,bkemsley20,Tucupido,58-(595)308-1288,Dental Hygienist,9810617755,"Jacobi, Kuhn and Hills" +Tamra,Whether,twhether21@privacy.gov.au,twhether21,Dedenëvo,7-(568)725-8281,Librarian,0938798367,Doyle-Schowalter +Alleyn,Hedworth,ahedworth22@nbcnews.com,ahedworth22,Bweyogerere,256-(885)716-8723,Information Systems Manager,7806845402,Herman-Kuphal +Baldwin,Ruggieri,bruggieri23@acquirethisname.com,bruggieri23,Famões,351-(152)434-9871,Database Administrator I,6285015228,Rohan-Spinka +Edi,Womersley,ewomersley24@soundcloud.com,ewomersley24,Topolovgrad,359-(281)202-4851,VP Product Management,5480937758,Heaney Group +Vally,Condy,vcondy25@mediafire.com,vcondy25,Kovářská,420-(698)690-1129,Staff Accountant III,6354747148,Dach-Sporer +Addie,Kobisch,akobisch26@instagram.com,akobisch26,Ninove,32-(630)476-7548,Web Developer II,7289347471,MacGyver-Becker +Levi,Florey,lflorey27@umn.edu,lflorey27,Dębowa Łąka,48-(297)281-6919,Operator,1052832121,Wolf Group +Jolie,Niles,jniles28@goodreads.com,jniles28,Annopol,48-(783)717-5946,Quality Control Specialist,1756247129,"Batz, Spencer and Zemlak" +Gwynne,Blaydes,gblaydes29@seattletimes.com,gblaydes29,Chervone,380-(130)591-1017,Junior Executive,7514288414,Metz Group +Andee,Hazard,ahazard2a@usatoday.com,ahazard2a,Bringinanom,62-(752)996-9280,Business Systems Development Analyst,0463793501,O'Hara Group +Cristine,Cordero,ccordero2b@shop-pro.jp,ccordero2b,Cireundang,62-(647)231-1238,Associate Professor,0206916523,"Bradtke, Breitenberg and Konopelski" +Adelice,Sparhawk,asparhawk2c@google.fr,asparhawk2c,Barbacoas,58-(288)306-1967,Business Systems Development Analyst,4263563638,Reinger Group +Arnuad,Yirrell,ayirrell2d@indiatimes.com,ayirrell2d,Guanagazapa,502-(996)833-1054,Research Associate,4248670135,"Zemlak, Murphy and Altenwerth" +Etta,Manuelli,emanuelli2e@webeden.co.uk,emanuelli2e,Onzaga,57-(627)371-5859,GIS Technical Architect,5140237679,Wiza LLC +Anetta,Demann,ademann2f@nhs.uk,ademann2f,Songhu,86-(886)244-1201,Engineer III,7383594029,"Lind, Rodriguez and Luettgen" +Rivi,Geck,rgeck2g@wikia.com,rgeck2g,Santa Iria de Azóia,351-(351)837-4156,GIS Technical Architect,7680553459,"Kuhic, Boyle and Kozey" +Zsa zsa,Boynes,zboynes2h@upenn.edu,zboynes2h,Cerava,355-(375)816-3821,Occupational Therapist,5933003034,Weimann and Sons +Carlen,Minillo,cminillo2i@sohu.com,cminillo2i,Łącko,48-(206)819-7182,Engineer III,9864914502,"Brown, Carroll and Sporer" +Jae,McMinn,jmcminn2j@geocities.jp,jmcminn2j,Yandang,86-(754)609-9065,VP Marketing,9052957681,Parker Inc +Daune,Holberry,dholberry2k@imageshack.us,dholberry2k,Daleszyce,48-(780)132-9574,Software Engineer III,5828276875,"Bartell, Casper and Kerluke" +Thacher,Jahnisch,tjahnisch2l@nbcnews.com,tjahnisch2l,Ýpsonas,357-(881)407-6533,Research Associate,6648113243,Metz-Schimmel +Egon,Dumphy,edumphy2m@tiny.cc,edumphy2m,Gonābād,98-(873)558-8082,Nurse,1757406042,Von and Sons +Aridatha,Matessian,amatessian2n@salon.com,amatessian2n,Zhenziliang,86-(691)551-3380,Structural Engineer,8930185770,Reichel-Powlowski +Gabby,Margett,gmargett2o@yellowpages.com,gmargett2o,Wenfu,86-(602)463-0478,Financial Advisor,5815266353,Bosco Inc +Andrei,Dowle,adowle2p@slashdot.org,adowle2p,Zykovo,7-(567)311-6007,Graphic Designer,6594557408,Terry Inc +Zack,Balsellie,zbalsellie2q@alibaba.com,zbalsellie2q,Kiihtelysvaara,358-(789)977-9884,Data Coordiator,8470986120,Wiegand-Heathcote +Tanny,Liccardi,tliccardi2r@scientificamerican.com,tliccardi2r,Majāz al Bāb,216-(900)448-3810,Occupational Therapist,8509563896,Moore and Sons +Eda,Petren,epetren2s@go.com,epetren2s,Mina de São Domingos,351-(647)661-1537,Registered Nurse,1326684930,Hagenes-Franecki +Fifine,Appleby,fappleby2t@prlog.org,fappleby2t,Sokol’skoye,7-(897)976-5440,Nurse Practicioner,6949941218,"Hilll, Wiza and Connelly" +Suki,Quilligan,squilligan2u@virginia.edu,squilligan2u,Lenešice,420-(484)575-9887,Internal Auditor,1102845078,Eichmann and Sons +Brinn,Seldon,bseldon2v@dedecms.com,bseldon2v,Valerik,7-(364)838-7251,Environmental Specialist,5496253098,Schiller Inc +Cristie,Treadaway,ctreadaway2w@histats.com,ctreadaway2w,Vichuga,7-(809)167-3685,Dental Hygienist,0743112563,Bogisich LLC +Kendall,Vidgeon,kvidgeon2x@ted.com,kvidgeon2x,Şānūr,970-(462)447-8191,Analog Circuit Design manager,5299583540,Brekke-Ziemann +Osborn,Fritschel,ofritschel2y@kickstarter.com,ofritschel2y,Bayt Maqdūm,970-(366)314-6696,Quality Control Specialist,3107157244,"Schultz, Runolfsson and Hauck" +Olenolin,Spore,ospore2z@about.me,ospore2z,Kissimmee,1-(407)958-2939,Information Systems Manager,1377154629,"Bashirian, Eichmann and Bednar" +Sherlock,O'Carmody,socarmody30@flickr.com,socarmody30,Xuhang,86-(402)403-7851,VP Product Management,4691963855,Nikolaus-Homenick +Pincus,Stamps,pstamps31@dagondesign.com,pstamps31,Old City,970-(348)690-7659,Analog Circuit Design manager,9573629984,"Ullrich, Halvorson and Hammes" +Sallee,Clover,sclover32@google.it,sclover32,Tuymazy,7-(344)530-7082,Information Systems Manager,1064925987,O'Hara-Zulauf +Jillane,Moyes,jmoyes33@shutterfly.com,jmoyes33,Faratsiho,261-(956)463-6161,Information Systems Manager,1015767532,Ruecker LLC +Sully,Baugh,sbaugh34@about.com,sbaugh34,Xidajie,86-(864)668-1887,Administrative Officer,7779016676,Cormier-Zieme +Woodman,Filipczynski,wfilipczynski35@reference.com,wfilipczynski35,Chinú,57-(984)445-3303,Payment Adjustment Coordinator,8833195139,Abshire-Upton +Donia,Tayspell,dtayspell36@abc.net.au,dtayspell36,Jacarezinho,55-(631)500-4755,Cost Accountant,0515630330,"Von, Paucek and DuBuque" +Cordula,Gelling,cgelling37@berkeley.edu,cgelling37,Ipoh,60-(392)990-3252,Geologist III,0539485020,Walsh and Sons +Cory,Franciskiewicz,cfranciskiewicz38@indiatimes.com,cfranciskiewicz38,Grand Rapids,1-(616)238-1561,Software Test Engineer I,0739184717,O'Kon-Windler +Merrielle,Ringe,mringe39@xinhuanet.com,mringe39,Široki Brijeg,387-(905)648-3989,Actuary,1561596175,Lemke-Fay +Janka,Mahoney,jmahoney3a@newyorker.com,jmahoney3a,Lethem,592-(205)736-1572,Environmental Tech,1359840486,Hammes Group +Fleur,Arno,farno3b@thetimes.co.uk,farno3b,Santo Domingo,63-(244)461-5127,Research Nurse,2070821277,Baumbach LLC +Feliza,Kitchingman,fkitchingman3c@dailymotion.com,fkitchingman3c,Gunungbatu,62-(305)737-3215,Payment Adjustment Coordinator,3717140175,Crooks Inc +Brooks,Abrey,babrey3d@loc.gov,babrey3d,Nongba,86-(631)179-1441,Database Administrator III,1495770435,Ryan Inc +Domenico,Leeder,dleeder3e@toplist.cz,dleeder3e,Stobreč,385-(588)803-2783,Occupational Therapist,7517254553,Gislason-Dickens +Gracie,Leggs,gleggs3f@posterous.com,gleggs3f,Anchorage,1-(907)739-1009,Account Representative IV,9894304044,"Auer, Fay and Kutch" +Burton,Girodin,bgirodin3g@flavors.me,bgirodin3g,Tambo Grande,51-(473)237-9513,Teacher,2586053230,Swaniawski-O'Connell +Rutger,Fortnum,rfortnum3h@ucsd.edu,rfortnum3h,Zhen’an,86-(520)440-6913,Desktop Support Technician,9664475106,Stehr-Satterfield +Callie,Gaymar,cgaymar3i@yandex.ru,cgaymar3i,Cempaka,62-(632)111-7548,Software Consultant,9554343590,"Collins, Marvin and Predovic" +Roslyn,Giron,rgiron3j@mashable.com,rgiron3j,Cartagena,34-(478)145-7341,Operator,4796666060,Spencer-Altenwerth +Lindsey,Cabera,lcabera3k@upenn.edu,lcabera3k,Tostado,54-(284)861-1251,Paralegal,8728268571,"Schulist, Nitzsche and Hettinger" +Alfonse,Odom,aodom3l@technorati.com,aodom3l,Hägersten,46-(947)105-7610,Graphic Designer,4698060613,Windler and Sons +Chalmers,Carwithim,ccarwithim3m@livejournal.com,ccarwithim3m,Eslöv,46-(442)928-3035,Internal Auditor,2949190553,Fritsch Inc +Rosa,Totterdill,rtotterdill3n@jiathis.com,rtotterdill3n,Guoduwan,86-(359)340-9833,Legal Assistant,3214937413,Dibbert-Jacobs +Lionel,Tomlin,ltomlin3o@elpais.com,ltomlin3o,Montbéliard,33-(836)419-9346,Information Systems Manager,2638534692,"Greenfelder, Boyer and Pollich" +Mireielle,Edmands,medmands3p@washington.edu,medmands3p,Kafir Qala,93-(929)432-7754,Design Engineer,9816600269,Littel-Durgan +Maryellen,Cordrey,mcordrey3q@networksolutions.com,mcordrey3q,Aganan,63-(246)228-0609,Associate Professor,1918577528,Goldner Inc +Hilario,Wadforth,hwadforth3r@npr.org,hwadforth3r,Obninsk,7-(856)647-8958,Physical Therapy Assistant,3701886741,"Raynor, Larkin and Bergstrom" +Vanda,Gradley,vgradley3s@psu.edu,vgradley3s,København,45-(345)469-6826,Safety Technician II,2103662962,Dietrich Group +Portia,Guillond,pguillond3t@youtube.com,pguillond3t,Verbivka,380-(633)231-9128,General Manager,1175524999,Goodwin-O'Keefe +Amabel,Jestico,ajestico3u@samsung.com,ajestico3u,Palama,62-(610)896-0940,Editor,2152070887,McClure-Oberbrunner +Gillie,Cafferty,gcafferty3v@netvibes.com,gcafferty3v,Zátor,420-(663)207-1814,Programmer Analyst I,1345410255,"Schamberger, Cassin and Walsh" +Dorri,Artis,dartis3w@oakley.com,dartis3w,Sam Khok,66-(547)684-7107,Registered Nurse,8689941193,"Mayert, Huel and Kshlerin" +Gearard,Mills,gmills3x@quantcast.com,gmills3x,Iitti,358-(148)528-5126,Nurse Practicioner,2353507719,Smith-Conn +Brinna,Andrasch,bandrasch3y@icq.com,bandrasch3y,Karangtalun,62-(700)442-1707,Senior Quality Engineer,3147866394,"Larson, Renner and Goldner" +Mohammed,Garthshore,mgarthshore3z@washingtonpost.com,mgarthshore3z,Janas,351-(802)307-8630,Pharmacist,2137372886,McClure-Bruen +Alta,Jeacocke,ajeacocke40@reuters.com,ajeacocke40,Bcharré,961-(429)530-2191,Librarian,2747388336,"Weimann, Yundt and Jerde" +Denys,Fonzone,dfonzone41@fotki.com,dfonzone41,Kidodi,255-(569)842-8531,Programmer II,5530705758,Prohaska Inc +Kin,Godthaab,kgodthaab42@usatoday.com,kgodthaab42,Dongzhou,86-(738)848-9111,Developer IV,6520160466,Mueller LLC +Alida,Jallin,ajallin43@imageshack.us,ajallin43,Croix,33-(392)554-0240,Graphic Designer,6970422224,Donnelly Group +Domeniga,Pawling,dpawling44@economist.com,dpawling44,Cergy-Pontoise,33-(808)258-6123,Information Systems Manager,2752070268,Lakin and Sons +Teddie,Pund,tpund45@cnet.com,tpund45,Åkersberga,46-(594)668-9870,Sales Representative,3679850239,Gerlach-Kohler +Hubert,Staniland,hstaniland46@t-online.de,hstaniland46,Huanggang,86-(605)920-8337,Nurse,3003691309,Crooks and Sons +Valentijn,Doughton,vdoughton47@vk.com,vdoughton47,La Montañita,57-(547)938-5819,Community Outreach Specialist,5005398791,Gleichner-Ward +Dunstan,McTurk,dmcturk48@t-online.de,dmcturk48,Cereté,57-(431)362-8281,VP Sales,3378279060,"Kuhic, Crooks and Bergnaum" +Ervin,Tungay,etungay49@tripadvisor.com,etungay49,Monte,351-(118)918-9096,VP Quality Control,4816619569,"Homenick, Kihn and Sporer" +Nevil,Kelemen,nkelemen4a@mapy.cz,nkelemen4a,Cha-am,66-(292)424-3669,Programmer Analyst I,4729507800,"Armstrong, Bauch and Doyle" +Hildegarde,Joffe,hjoffe4b@squarespace.com,hjoffe4b,Sājir,966-(816)671-3309,Developer IV,5371857133,"Quitzon, Lakin and Koss" +Virgil,Latchmore,vlatchmore4c@europa.eu,vlatchmore4c,Bahorí,992-(626)965-2780,Electrical Engineer,4331295168,Hackett-Ortiz +Shurwood,Kennon,skennon4d@trellian.com,skennon4d,Shimen,86-(122)424-6837,Actuary,5908185647,Feil-Flatley +Coretta,Robe,crobe4e@huffingtonpost.com,crobe4e,Paltashaco,51-(430)483-8211,Help Desk Technician,3927212415,Ortiz Inc +Roddie,Frudd,rfrudd4f@dion.ne.jp,rfrudd4f,Khombole,221-(980)728-8902,Legal Assistant,6679829933,Turcotte-Aufderhar +Geraldine,Pershouse,gpershouse4g@4shared.com,gpershouse4g,Pinheiro,55-(810)396-6565,Account Representative II,9339033949,Bradtke and Sons +Rex,Winterburn,rwinterburn4h@earthlink.net,rwinterburn4h,Konibodom,992-(285)759-4482,Engineer I,4013574306,Harvey-Hirthe +Bride,MacCawley,bmaccawley4i@skype.com,bmaccawley4i,Głubczyce,48-(645)682-7840,Information Systems Manager,3136570391,"Swaniawski, Gerlach and Gibson" +Nikkie,Freund,nfreund4j@freewebs.com,nfreund4j,Gusang,86-(298)352-9050,Product Engineer,9725922840,"Purdy, Rice and Fahey" +Henrieta,Creavin,hcreavin4k@wired.com,hcreavin4k,Maoming,86-(203)885-7331,Quality Engineer,6377468806,"Weber, Tillman and Frami" +Freddie,Irce,firce4l@narod.ru,firce4l,Koszyce Wielkie,48-(793)133-0472,Professor,8965612748,Kunde Inc +Erin,Thomton,ethomton4m@com.com,ethomton4m,Punta Cana,1-(194)646-6108,Speech Pathologist,8529365445,"Pfannerstill, Berge and Keebler" +Stu,Grabiec,sgrabiec4n@desdev.cn,sgrabiec4n,Bagé,55-(658)679-1980,Senior Financial Analyst,9818636597,"Murray, Hessel and Considine" +Marlo,Hay,mhay4o@si.edu,mhay4o,Bojonglarang,62-(342)321-9267,Systems Administrator I,9669756170,Skiles-Mueller +Ruthe,Rainforth,rrainforth4p@lycos.com,rrainforth4p,Zhangcheng,86-(103)571-9123,Human Resources Manager,0110467094,Treutel-Schroeder +Nanette,Marvell,nmarvell4q@themeforest.net,nmarvell4q,Candelaria,63-(677)283-7853,Help Desk Operator,0831047453,Johnston-Hayes +Gwendolen,Kettleson,gkettleson4r@lycos.com,gkettleson4r,Curahkalak Tengah,62-(324)997-7422,Compensation Analyst,3942331365,Russel-Satterfield +Whittaker,Gregh,wgregh4s@behance.net,wgregh4s,Głowno,48-(285)750-6950,Automation Specialist II,0264496159,Hamill-Kemmer +Shay,Ramelet,sramelet4t@techcrunch.com,sramelet4t,San Pedro,54-(301)601-8361,Staff Accountant I,8224288722,Aufderhar LLC +Adrienne,Villar,avillar4u@list-manage.com,avillar4u,Shuangjie,86-(951)513-0325,Automation Specialist II,7072078703,"O'Keefe, Lowe and Stroman" +Alyda,Gillford,agillford4v@tinypic.com,agillford4v,Fengxian,86-(660)158-1836,Structural Engineer,6986236239,"Moen, Mraz and Heidenreich" +Biron,Rajchert,brajchert4w@e-recht24.de,brajchert4w,Niort,33-(207)497-8305,Quality Control Specialist,5556782318,Conn LLC +Drake,Foran,dforan4x@wisc.edu,dforan4x,Fort Pierce,1-(772)401-1527,Nurse Practicioner,2174876256,"Brakus, Schimmel and Turner" +Madella,Flew,mflew4y@amazon.de,mflew4y,Haodi,86-(156)758-1712,Structural Engineer,2630355349,Abbott Group +Jermain,Lintot,jlintot4z@linkedin.com,jlintot4z,Koszyce Wielkie,48-(712)513-8339,Electrical Engineer,5316574915,Bruen Inc +Malvina,Cherrison,mcherrison50@dell.com,mcherrison50,Belung Satu,62-(983)260-7407,Geologist III,0459539647,"Nader, Davis and Spinka" +Nesta,Darell,ndarell51@sina.com.cn,ndarell51,Vostochnyy,7-(216)191-7642,Dental Hygienist,9912630998,"Aufderhar, Krajcik and Lemke" +Valery,Sharpus,vsharpus52@cnn.com,vsharpus52,Checca,51-(325)577-5349,Budget/Accounting Analyst II,9257058077,"Koch, Keeling and Kihn" +Ramona,Cahill,rcahill53@networksolutions.com,rcahill53,Bailieborough,353-(653)588-5654,VP Marketing,6559784584,Welch-Gleason +Calv,Studdeard,cstuddeard54@dion.ne.jp,cstuddeard54,Babakan,62-(727)232-5040,Geological Engineer,3900347034,"Nitzsche, Mohr and Simonis" +Malia,Jacobssen,mjacobssen55@e-recht24.de,mjacobssen55,Aldeia do Bispo,351-(313)100-4305,Cost Accountant,3428666267,Mayer Group +Laural,Izon,lizon56@icq.com,lizon56,Gaoqiao,86-(275)782-1267,Assistant Media Planner,6392728392,Wintheiser Inc +Morgan,Caukill,mcaukill57@storify.com,mcaukill57,Torres Novas,351-(450)639-8416,Analog Circuit Design manager,2316388078,"Schiller, Kris and Farrell" +Marlane,Palek,mpalek58@miibeian.gov.cn,mpalek58,San Isidro de Lules,54-(873)665-9102,Design Engineer,1418632929,Lubowitz and Sons +Broderick,Ugo,bugo59@hud.gov,bugo59,Silodakon,62-(378)217-9779,Recruiter,4977155548,Steuber-Dietrich +Norry,Arzu,narzu5a@oakley.com,narzu5a,Timashëvsk,7-(943)185-9478,Paralegal,8088001102,"Hettinger, Gutkowski and Bechtelar" +Benedikta,Meininking,bmeininking5b@macromedia.com,bmeininking5b,Jiucheng,86-(218)617-0476,Legal Assistant,0611180774,Douglas Inc +Edan,Velasquez,evelasquez5c@sitemeter.com,evelasquez5c,Juncheng,86-(623)794-4358,Associate Professor,3556333899,"Marks, Jakubowski and Boyer" +Shea,Ernke,sernke5d@freewebs.com,sernke5d,Korniyivka,380-(988)667-0972,Senior Quality Engineer,3318216801,Huel Inc +Bekki,Fesby,bfesby5e@irs.gov,bfesby5e,Lille,33-(510)850-2554,Desktop Support Technician,2228160431,Ullrich LLC +Sean,Oda,soda5f@tinyurl.com,soda5f,Furukawa,81-(267)487-5524,Office Assistant I,2265020354,Spinka-Auer +Jerry,Bakster,jbakster5g@sina.com.cn,jbakster5g,Hołoby,380-(683)792-0125,Staff Scientist,2528271107,D'Amore and Sons +Wendi,Imlen,wimlen5h@amazon.co.uk,wimlen5h,Takatsuki,81-(641)449-9730,Internal Auditor,8591255291,Hermann-Reinger +Cristina,McCarry,cmccarry5i@weibo.com,cmccarry5i,Banturkrajan,62-(200)913-3412,Help Desk Technician,8664973989,"Skiles, Russel and Wisoky" +Viviana,Selman,vselman5j@360.cn,vselman5j,Huayan,86-(681)662-3285,Research Assistant III,6262769528,Wuckert Inc +Shanie,Uppett,suppett5k@webeden.co.uk,suppett5k,Lac du Bonnet,1-(543)646-5383,Operator,4572433119,Fadel Inc +Suzie,Bridgeman,sbridgeman5l@dmoz.org,sbridgeman5l,Kamo,81-(897)485-9748,Environmental Specialist,1977897401,"Denesik, Okuneva and Bernier" +Eudora,Casterot,ecasterot5m@psu.edu,ecasterot5m,Zonghan,86-(764)968-7549,Help Desk Operator,2008858634,"Jaskolski, Huels and Dibbert" +Penn,Viant,pviant5n@linkedin.com,pviant5n,Andir,62-(390)901-5564,Senior Sales Associate,2238319271,"Cummings, Beatty and Hudson" +Berne,Hannan,bhannan5o@shareasale.com,bhannan5o,Krajan Kerjo,62-(278)571-4046,Data Coordiator,7942202852,Auer-Bartoletti +Oralee,Malyj,omalyj5p@admin.ch,omalyj5p,Kotayk’,374-(542)956-6172,Engineer IV,4819135880,"Pacocha, Kertzmann and Rempel" +Fifi,Small,fsmall5q@amazon.de,fsmall5q,Voznesenskoye,7-(821)863-5914,Physical Therapy Assistant,6908304248,"Rippin, Reichel and White" +Loise,Pilger,lpilger5r@smh.com.au,lpilger5r,Hénin-Beaumont,33-(686)647-9059,Information Systems Manager,0967841968,Wiza and Sons +Derward,Dupoy,ddupoy5s@latimes.com,ddupoy5s,Itami,81-(903)990-0489,Quality Engineer,3564905782,Dare-Kautzer +Chelsea,Lergan,clergan5t@youtu.be,clergan5t,Jiagao,86-(320)644-8775,Research Assistant III,9361206621,Kirlin-Effertz +Rosene,Flitcroft,rflitcroft5u@free.fr,rflitcroft5u,Inírida,57-(248)911-2377,Clinical Specialist,9685341567,"Dietrich, Wyman and Shanahan" +Chariot,Barok,cbarok5v@blogspot.com,cbarok5v,Căuşeni,373-(632)605-6648,Speech Pathologist,4694900498,Legros LLC +Elita,von Nassau,evonnassau5w@digg.com,evonnassau5w,Kutacane,62-(213)303-2731,Executive Secretary,0347148085,Green Inc +Gael,Marjanovic,gmarjanovic5x@marriott.com,gmarjanovic5x,Huacapampa,51-(186)661-9148,Occupational Therapist,6726485387,"Stamm, Kris and Farrell" +Gaspard,Ummfrey,gummfrey5y@t.co,gummfrey5y,Buenavista,63-(497)452-5987,Speech Pathologist,4575944572,Bradtke-Hegmann +Bent,Trenam,btrenam5z@auda.org.au,btrenam5z,Cerrito,57-(251)296-9228,Payment Adjustment Coordinator,1352694905,Robel Inc +Allie,Cardo,acardo60@nba.com,acardo60,Sayama,81-(136)328-3578,Administrative Assistant II,1953155472,Franecki Inc +Kendricks,Lawes,klawes61@wikimedia.org,klawes61,Kýria,30-(629)572-9182,Automation Specialist III,3013335882,Cremin and Sons +Israel,Earwicker,iearwicker62@latimes.com,iearwicker62,Naga,63-(980)734-2130,Help Desk Technician,9262358857,Predovic Group +Olivie,Haskett,ohaskett63@biblegateway.com,ohaskett63,Sadská,420-(267)684-5843,General Manager,0341903078,"Ritchie, Thiel and Crona" +Lorette,Jupp,ljupp64@eventbrite.com,ljupp64,Kalety,48-(905)755-9085,Senior Financial Analyst,6902201358,"Larson, Mann and Denesik" +Huberto,Fieldsend,hfieldsend65@hibu.com,hfieldsend65,Rostokino,7-(885)545-7151,Sales Representative,7583497507,Buckridge-Crist +Galvan,Ruslen,gruslen66@biblegateway.com,gruslen66,Tomaszów Lubelski,48-(738)856-8800,Executive Secretary,7689061370,Marquardt Group +Lucine,Dillway,ldillway67@netlog.com,ldillway67,Nobres,55-(588)142-5888,Data Coordiator,3143583223,Morissette Group +Bogey,Lloyd,blloyd68@clickbank.net,blloyd68,Maskinongé,1-(480)421-6369,Recruiter,8019916377,Schmidt-Okuneva +Lana,Osorio,losorio69@theguardian.com,losorio69,Shuiyuesi,86-(368)799-2866,Financial Advisor,0845918354,Murazik-Spinka +April,Shrimpton,ashrimpton6a@yahoo.co.jp,ashrimpton6a,Jurh,86-(945)443-7757,Budget/Accounting Analyst I,6199988221,"Willms, Marquardt and Kautzer" +Thea,Brunelleschi,tbrunelleschi6b@boston.com,tbrunelleschi6b,Belovo,7-(379)764-3239,Speech Pathologist,3924467498,Feil Inc +Sunshine,Pymer,spymer6c@sakura.ne.jp,spymer6c,Tsibulev,380-(446)992-3711,Technical Writer,0673563766,Price-Kuhic +Neddie,Westoll,nwestoll6d@dailymail.co.uk,nwestoll6d,Tatebayashi,81-(379)112-1552,Software Consultant,5692786702,"Lind, Schoen and Harris" +Godfrey,Shiliton,gshiliton6e@economist.com,gshiliton6e,Caucaia,55-(324)521-2916,Assistant Media Planner,3640782380,"White, Sipes and Macejkovic" +Bonnibelle,Meys,bmeys6f@hud.gov,bmeys6f,Barengkok Hilir,62-(132)233-0164,VP Marketing,6576141343,Greenfelder and Sons +Biddie,Hazart,bhazart6g@privacy.gov.au,bhazart6g,Lyubimets,359-(539)214-9362,Research Nurse,2110251921,Beatty Inc +Mariette,Arnoud,marnoud6h@upenn.edu,marnoud6h,Chonglou,86-(367)745-8032,Chemical Engineer,6279421910,Bailey-Flatley +Ralph,Ronan,rronan6i@soup.io,rronan6i,Villa del Rosario,54-(472)473-2834,Media Manager III,0898611601,Conroy-Schultz +Kristopher,Byrth,kbyrth6j@ucoz.com,kbyrth6j,Vyselki,7-(553)161-3317,GIS Technical Architect,8368786673,"Feest, Cremin and Goodwin" +Juliette,Peckett,jpeckett6k@desdev.cn,jpeckett6k,Dublin,353-(547)169-7510,Registered Nurse,4289815278,Jakubowski-Lueilwitz +Lauretta,Edgeler,ledgeler6l@instagram.com,ledgeler6l,Tarragona,63-(650)302-6149,Biostatistician IV,6817860377,"Jakubowski, Steuber and Tillman" +Scot,Calvert,scalvert6m@blinklist.com,scalvert6m,Condong,62-(732)380-9120,Sales Associate,7437515962,Doyle-Breitenberg +Elyssa,Tibbles,etibbles6n@last.fm,etibbles6n,Neftobod,992-(777)638-8129,Analyst Programmer,9445635612,"Fahey, Champlin and Dietrich" +Brander,Harmer,bharmer6o@bloglovin.com,bharmer6o,Gardēz,93-(358)973-4287,Librarian,1276314027,"Hauck, Simonis and Rosenbaum" +Brennen,Springthorpe,bspringthorpe6p@salon.com,bspringthorpe6p,Mobaye,236-(308)628-4824,Safety Technician II,3086629398,Yundt-Ziemann +Bren,Kleynermans,bkleynermans6q@phpbb.com,bkleynermans6q,Weifang,86-(292)267-2145,Developer III,5400207502,"Treutel, Stoltenberg and Johnston" +Candy,Tooze,ctooze6r@friendfeed.com,ctooze6r,Vlachovo Březí,420-(676)807-2495,Nurse Practicioner,5388144038,"Russel, Blanda and Rogahn" +Fairleigh,Diamant,fdiamant6s@blinklist.com,fdiamant6s,Sainte-Anne-de-Bellevue,1-(568)570-3951,Quality Engineer,3663658481,Armstrong-Johns +Basil,Howsden,bhowsden6t@ovh.net,bhowsden6t,Xylotymbou,357-(214)824-3004,Tax Accountant,3403316513,"Langosh, Bartell and Stoltenberg" +Dora,Dobbin,ddobbin6u@amazon.co.jp,ddobbin6u,Lamovita,387-(768)310-0952,Office Assistant I,8679431729,Leannon-Kiehn +Demetra,Brownill,dbrownill6v@over-blog.com,dbrownill6v,Bagou,86-(713)477-6708,Sales Representative,5659782310,Johns-Kerluke +Dasi,Dumini,ddumini6w@patch.com,ddumini6w,Punta del Este,598-(886)595-6322,Human Resources Assistant II,1332065767,Schowalter-Altenwerth +Lenette,Geaveny,lgeaveny6x@pcworld.com,lgeaveny6x,Gaoqiao,86-(467)357-1181,Programmer IV,6397889467,"Will, Rath and Jenkins" +Colin,Treace,ctreace6y@wikimedia.org,ctreace6y,Nanjiao,86-(675)354-6909,Chief Design Engineer,7751575638,"Ferry, Runolfsdottir and Yost" +Corabelle,Clow,cclow6z@hexun.com,cclow6z,Sovetskaya Gavan’,7-(120)976-8309,Software Consultant,7813300394,Doyle Group +Linda,Sebborn,lsebborn70@ucoz.ru,lsebborn70,Knoxville,1-(865)117-5458,General Manager,9692754766,Reichert-O'Reilly +Hector,Halbeard,hhalbeard71@about.me,hhalbeard71,Batanovtsi,359-(442)822-8483,Physical Therapy Assistant,9078172762,Conn Group +Abbe,Mobberley,amobberley72@ucsd.edu,amobberley72,Kinna,46-(293)901-8731,Administrative Assistant II,9620491815,Hahn-Batz +Jasmina,Wickliffe,jwickliffe73@google.it,jwickliffe73,Mercier,1-(345)768-6426,Web Designer IV,9241731699,Wunsch Inc +Cissy,Saill,csaill74@google.ru,csaill74,Cifuentes,53-(247)403-7379,Analog Circuit Design manager,1682507572,Oberbrunner Group +Sharlene,Ozintsev,sozintsev75@google.com.br,sozintsev75,Gornji Milanovac,381-(814)830-4698,Associate Professor,2798596351,Lockman-Abbott +Padraic,Alyukin,palyukin76@chicagotribune.com,palyukin76,Ouricuri,55-(251)839-4014,Recruiter,6246014852,Weimann-Fay +Rowney,Bamblett,rbamblett77@shop-pro.jp,rbamblett77,Saint-Étienne,33-(689)956-1538,Director of Sales,2164832523,Gulgowski Inc +Ertha,Carayol,ecarayol78@aol.com,ecarayol78,Kanoni,256-(965)621-0576,Assistant Professor,7485417517,"Hoppe, Windler and Stiedemann" +Jodie,Ramsdell,jramsdell79@ezinearticles.com,jramsdell79,Xingxi,86-(209)444-2347,Geological Engineer,1645038890,Padberg LLC +Jessie,Febre,jfebre7a@lulu.com,jfebre7a,Glugur Krajan,62-(476)504-7372,Editor,7484180890,Dickinson Group +Xymenes,Rihanek,xrihanek7b@mapy.cz,xrihanek7b,Tiemen,86-(815)399-0300,Tax Accountant,7418639295,Rogahn Group +Ynes,Castagneri,ycastagneri7c@army.mil,ycastagneri7c,Majiang,86-(109)725-0679,Web Developer IV,9966232281,Veum-Block +Meade,Josovich,mjosovich7d@instagram.com,mjosovich7d,Dumalinao,63-(220)787-8879,Chief Design Engineer,9532892052,Dach LLC +Starla,Baglan,sbaglan7e@kickstarter.com,sbaglan7e,Tucson,1-(520)306-4486,Geological Engineer,3924286000,White LLC +Cecil,Ditchfield,cditchfield7f@merriam-webster.com,cditchfield7f,Bouillon,32-(153)814-1718,Safety Technician II,3049249757,Wehner-Schultz +Albina,Caile,acaile7g@sourceforge.net,acaile7g,Limanowa,48-(598)134-6137,Statistician IV,2887139231,Gleichner LLC +Myrtia,Topling,mtopling7h@timesonline.co.uk,mtopling7h,Weichanglu,86-(679)742-0020,Account Coordinator,8708521727,Skiles-Rempel +Jillian,Parnall,jparnall7i@plala.or.jp,jparnall7i,Lobito,244-(170)955-1350,Environmental Specialist,4004831083,McCullough-Gislason +Martita,Gallamore,mgallamore7j@fotki.com,mgallamore7j,Watubuku,62-(829)363-5055,Food Chemist,0332452107,Cummerata Group +Gareth,Bourchier,gbourchier7k@biblegateway.com,gbourchier7k,Benito Juarez,52-(692)902-9439,Senior Editor,2717344314,Mueller-McDermott +Cristine,Lydiard,clydiard7l@hubpages.com,clydiard7l,Puzi,86-(502)679-6404,Tax Accountant,2847297839,Rau-Gerhold +Tamar,Grishagin,tgrishagin7m@ft.com,tgrishagin7m,Singkup,62-(368)986-3322,Pharmacist,4974827138,Waters-Volkman +Kassandra,McGarva,kmcgarva7n@ucsd.edu,kmcgarva7n,Tunal,51-(683)835-8456,Statistician II,8446317222,Tremblay-Jacobi +Lulita,Millard,lmillard7o@biglobe.ne.jp,lmillard7o,Charlemagne,1-(334)407-8112,Software Engineer IV,7906208463,Nicolas-Harber +Deanna,Guly,dguly7p@cbslocal.com,dguly7p,Barda,994-(610)562-3650,Business Systems Development Analyst,3995952712,Bailey Group +Latia,Lerer,llerer7q@acquirethisname.com,llerer7q,Dykan’ka,380-(537)386-5412,Quality Control Specialist,1410485773,Daugherty and Sons +Jessika,Constantine,jconstantine7r@twitter.com,jconstantine7r,Parang,62-(598)114-0602,VP Marketing,1477207635,Schowalter-Becker +Fianna,Garz,fgarz7s@posterous.com,fgarz7s,Västerås,46-(169)490-0251,Paralegal,2065474785,"Osinski, Stark and Wisoky" +Georgina,McGown,gmcgown7t@va.gov,gmcgown7t,Lianghekou,86-(580)598-5939,Database Administrator IV,8574862584,Schmidt-Stark +Libbey,Hatto,lhatto7u@parallels.com,lhatto7u,Saint-Pierre,262-(621)379-5079,Compensation Analyst,3663439984,Wintheiser-Tromp +Melosa,Varvell,mvarvell7v@msu.edu,mvarvell7v,Canta,51-(384)731-8458,Executive Secretary,1754007481,Lind-Weissnat +Caspar,Cutbirth,ccutbirth7w@nifty.com,ccutbirth7w,Makoko,234-(315)758-3899,Senior Sales Associate,7648950596,"Kertzmann, Muller and McClure" +Ward,Pryor,wpryor7x@xinhuanet.com,wpryor7x,Pitangui,55-(228)519-9720,Research Assistant I,7596446612,Ondricka-Murray +Judon,Orhrt,jorhrt7y@friendfeed.com,jorhrt7y,Rancakuya,62-(835)959-6252,Senior Financial Analyst,0862524326,Ratke-Powlowski +Isa,Gudgin,igudgin7z@bizjournals.com,igudgin7z,Paojan,62-(130)105-8528,Administrative Assistant IV,6567173823,Hyatt and Sons +Jacquetta,Heinrici,jheinrici80@latimes.com,jheinrici80,Pitanga,55-(768)218-0323,Clinical Specialist,7383258630,McCullough LLC +Gris,Demonge,gdemonge81@eventbrite.com,gdemonge81,Sevsk,7-(385)990-5642,Software Consultant,7319470772,Prosacco Inc +Anna,Cordova,acordova82@vistaprint.com,acordova82,Horodnya,380-(403)720-3982,Research Associate,8382416985,Witting Inc +Garek,Paver,gpaver83@reddit.com,gpaver83,Baumata,62-(857)457-3277,Systems Administrator IV,5548424025,Homenick-Cummings +Lyndsey,Penrose,lpenrose84@amazonaws.com,lpenrose84,Xinning,86-(478)975-1877,Account Executive,2521617024,"Beier, Wolf and Rutherford" +Vivyanne,Garment,vgarment85@hc360.com,vgarment85,Abonnema,234-(630)147-0664,Compensation Analyst,3170876961,Gibson Inc +Diandra,Alfonso,dalfonso86@so-net.ne.jp,dalfonso86,São Joaquim da Barra,55-(958)915-7472,Recruiter,9244448580,"Walker, Ryan and Gutmann" +Germana,Filippi,gfilippi87@virginia.edu,gfilippi87,Bořitov,420-(677)675-6041,Quality Engineer,4733992351,Rice Group +Huntington,Jaffa,hjaffa88@jigsy.com,hjaffa88,Puerto Padre,53-(811)758-9909,Research Associate,3705515845,Kerluke-Durgan +Julius,Scrace,jscrace89@sohu.com,jscrace89,Vilnius,370-(437)863-9804,Senior Financial Analyst,8560462449,"Wunsch, Wilkinson and Bernier" +Orin,Donnersberg,odonnersberg8a@lycos.com,odonnersberg8a,Posadas,54-(799)614-8488,Assistant Manager,6525056810,"Barrows, Prohaska and Raynor" +Nicole,Alberts,nalberts8b@businessinsider.com,nalberts8b,Circa,51-(793)830-7780,Internal Auditor,6648971908,Kihn Inc +Noami,Coast,ncoast8c@blogs.com,ncoast8c,Bengga,62-(245)836-9414,VP Accounting,1384386025,"Reilly, Feest and Armstrong" +Trev,Coil,tcoil8d@nyu.edu,tcoil8d,Ol Kalou,254-(686)258-2913,Mechanical Systems Engineer,6873910341,Goyette Inc +Isiahi,Bingall,ibingall8e@histats.com,ibingall8e,Raleigh,1-(919)707-3481,Legal Assistant,7848853918,"Stark, Thompson and Wintheiser" +Dasi,Balsdon,dbalsdon8f@paginegialle.it,dbalsdon8f,Douala,237-(853)665-9676,Administrative Officer,5137205664,"Olson, Mayert and Renner" +Allx,Towl,atowl8g@wordpress.com,atowl8g,Kosti,249-(267)322-7346,Human Resources Assistant III,4848260302,Walker LLC +Mead,Bunton,mbunton8h@linkedin.com,mbunton8h,Zhukovskiy,7-(479)702-5593,General Manager,9816135388,Durgan-Steuber +Felipe,Cremen,fcremen8i@tinyurl.com,fcremen8i,Tualangcut,62-(457)527-3731,Software Consultant,0960922245,Glover-Vandervort +Maryanne,Bevir,mbevir8j@devhub.com,mbevir8j,Petrolina,55-(430)943-6831,Analog Circuit Design manager,8076246016,Schumm-Hoppe +Rice,Bangley,rbangley8k@tinyurl.com,rbangley8k,San Francisco,1-(415)451-6262,Legal Assistant,2931538566,Wisoky-Hettinger +Rockey,Jewell,rjewell8l@printfriendly.com,rjewell8l,Mistrató,57-(273)159-4757,Marketing Manager,2358326909,Kohler-Crooks +Andrei,Busk,abusk8m@trellian.com,abusk8m,Shevchenkove,380-(471)522-4941,Software Test Engineer III,5139581752,Kemmer Group +Boyce,Colwill,bcolwill8n@google.fr,bcolwill8n,Paço de Arcos,351-(169)576-4617,Database Administrator I,8239907938,"Carter, Connelly and Turcotte" +Rosalia,Kilcullen,rkilcullen8o@tmall.com,rkilcullen8o,Skellefteå,46-(497)227-6314,Research Nurse,7802328411,Marvin Inc +Wang,Howcroft,whowcroft8p@usa.gov,whowcroft8p,Seixo de Manhoses,351-(878)241-1916,Engineer I,4169975723,"Quitzon, Jacobson and Hoeger" +Pauletta,MacFadden,pmacfadden8q@yellowbook.com,pmacfadden8q,Guanabacoa,53-(414)148-3660,Senior Cost Accountant,4033591168,"Bernhard, Greenholt and Kovacek" +Anetta,Kikke,akikke8r@xrea.com,akikke8r,Pines,63-(455)105-7090,Staff Scientist,3797345658,"Upton, Walter and Champlin" +Doy,Von Oertzen,dvonoertzen8s@soundcloud.com,dvonoertzen8s,Trancas,54-(227)790-7863,Quality Control Specialist,7347709652,Rogahn-Robel +Evania,Ettery,eettery8t@woothemes.com,eettery8t,Batuidu,62-(958)487-1137,Environmental Tech,6712438047,"McCullough, Brown and White" +Dorothy,Burchfield,dburchfield8u@com.com,dburchfield8u,Buenos Aires,57-(104)461-3034,Structural Engineer,1232163627,"Bergnaum, Mann and Denesik" +Marnia,Pates,mpates8v@cdc.gov,mpates8v,Wanzu,86-(584)655-8767,Structural Analysis Engineer,9486437602,"Vandervort, Reilly and Torp" +Sherlocke,Sundin,ssundin8w@bloglovin.com,ssundin8w,Lubumbashi,242-(894)433-3030,Database Administrator I,8350287896,"Denesik, Prohaska and Jacobson" +Cathe,Perell,cperell8x@wordpress.com,cperell8x,Kruty,380-(115)837-1904,VP Sales,0042397316,"Wilkinson, Schulist and Macejkovic" +Pennie,Gerault,pgerault8y@geocities.jp,pgerault8y,Placencia,501-(575)329-0306,Social Worker,7431658591,"Torphy, Bailey and Reilly" +Mitchell,Crambie,mcrambie8z@privacy.gov.au,mcrambie8z,Xiamao,86-(265)196-0470,Nuclear Power Engineer,1526344351,Ritchie-Morissette +Melisent,Gosneye,mgosneye90@freewebs.com,mgosneye90,Yōkaichiba,81-(118)826-5920,VP Product Management,2373235900,Homenick and Sons +Jordain,Gheorghe,jgheorghe91@bandcamp.com,jgheorghe91,Ljungby,46-(108)213-7069,Pharmacist,2339386128,"Lubowitz, Witting and Trantow" +Ezekiel,Winpenny,ewinpenny92@aboutads.info,ewinpenny92,Uttaradit,66-(502)534-3772,Analyst Programmer,9863270415,"Satterfield, Yost and Cruickshank" +Alaric,Coal,acoal93@rambler.ru,acoal93,Piła,48-(110)978-3089,Senior Editor,1002792959,Schmeler Group +Sigvard,Durnill,sdurnill94@senate.gov,sdurnill94,Jiuzihe,86-(285)652-3541,Desktop Support Technician,6259022751,Hodkiewicz-Treutel +Pauletta,Jacob,pjacob95@blog.com,pjacob95,Lillehammer,47-(466)710-7316,Budget/Accounting Analyst IV,8012816342,Kub-Streich +Genevieve,Easson,geasson96@gmpg.org,geasson96,Litian,86-(690)700-3316,Chemical Engineer,9267475002,Krajcik-Berge +Chad,Wellings,cwellings97@geocities.com,cwellings97,Corozal,57-(599)397-8105,Technical Writer,1234875780,Lang Inc +Constantia,Andor,candor98@angelfire.com,candor98,Luxi,86-(981)190-7061,Tax Accountant,2171737387,Kunze-Cummerata +Nathanil,Kennett,nkennett99@salon.com,nkennett99,Kushnytsya,380-(964)412-7626,Operator,2201713081,Auer LLC +Marilyn,Lambden,mlambden9a@ca.gov,mlambden9a,Sūq al Khamīs,967-(606)751-1510,Social Worker,9824776443,"Kuhic, Wolf and Runte" +Sol,Trownson,strownson9b@t.co,strownson9b,Venado Tuerto,54-(387)454-8901,Paralegal,4748088125,Reichert-Nitzsche +Marybeth,Sturney,msturney9c@163.com,msturney9c,Agassiz,1-(357)754-2461,Data Coordiator,3593006383,Spinka-Ebert +Tyler,Kightly,tkightly9d@ed.gov,tkightly9d,Kunčice pod Ondřejníkem,420-(222)601-1668,General Manager,5778670230,Brown Group +Godart,Izakoff,gizakoff9e@jimdo.com,gizakoff9e,San Agustin,63-(658)848-5052,Junior Executive,3147182215,Schaden and Sons +Cherie,MacAndrew,cmacandrew9f@jigsy.com,cmacandrew9f,Topeka,1-(785)270-8606,Software Engineer IV,5443654527,Schuster-Windler +Giorgia,Cinderey,gcinderey9g@php.net,gcinderey9g,Setúbal,351-(730)743-5865,Account Representative I,6484043175,Johns Inc +Kasper,Deuss,kdeuss9h@myspace.com,kdeuss9h,Ostrogozhsk,7-(336)124-5046,Nurse,6142898304,"Smith, Hamill and Beatty" +Leroy,Foord,lfoord9i@timesonline.co.uk,lfoord9i,Kijang,82-(585)819-8722,Analog Circuit Design manager,4569642292,Leffler-Casper +Urson,Fludder,ufludder9j@mac.com,ufludder9j,Lumbardhi,383-(659)644-8699,Programmer II,2608105793,Wisoky-Lesch +Victoir,Sainer,vsainer9k@4shared.com,vsainer9k,Mocoa,57-(566)759-9576,Senior Cost Accountant,4891001224,Gerlach Inc +Nestor,Gray,ngray9l@paginegialle.it,ngray9l,Vallauris,33-(405)253-6375,Help Desk Operator,7391899399,Rutherford-Fisher +Benedetto,Sebrens,bsebrens9m@quantcast.com,bsebrens9m,Hüremt,976-(937)675-7706,Health Coach I,5492941666,Rosenbaum Inc +Alis,Crittal,acrittal9n@fema.gov,acrittal9n,Xia’ertai,86-(808)528-2343,Nurse,9616882783,Waters LLC +Tanitansy,Deighan,tdeighan9o@ovh.net,tdeighan9o,Ketitang Wetan,62-(807)439-9181,Account Coordinator,5918139109,Schultz-Quigley +Park,Allbon,pallbon9p@topsy.com,pallbon9p,Mértola,351-(457)676-3664,Recruiter,7432415315,Franecki-Lind +Bridget,Houlden,bhoulden9q@telegraph.co.uk,bhoulden9q,Busay,63-(327)378-8551,Teacher,5534661836,Kutch Inc +Timi,Winnett,twinnett9r@wiley.com,twinnett9r,Foros de Salvaterra,351-(750)913-7504,VP Marketing,0956508278,"Pagac, Wisozk and Powlowski" +Garey,Berends,gberends9s@nasa.gov,gberends9s,Villa Nueva,54-(466)900-2563,Community Outreach Specialist,2649689285,Cruickshank Group +Maurise,Sabathe,msabathe9t@umn.edu,msabathe9t,Porto Alto,351-(826)409-0224,Environmental Tech,4375179112,O'Kon and Sons +Waiter,Newport,wnewport9u@cdc.gov,wnewport9u,Balibago,63-(808)564-2341,Media Manager I,3383596125,Frami-Kassulke +Clarissa,Snuggs,csnuggs9v@moonfruit.com,csnuggs9v,Weitang,86-(376)106-1168,Account Representative IV,2195207272,Harris Inc +Florance,Littlejohns,flittlejohns9w@tumblr.com,flittlejohns9w,Bunigeulis,62-(587)466-3755,Legal Assistant,3318922927,Marquardt-Howe +Gail,Skechley,gskechley9x@prweb.com,gskechley9x,Meixi,86-(203)873-6865,Web Developer I,6076144513,Nolan-Dickinson +Skippy,Biss,sbiss9y@prweb.com,sbiss9y,Dongshi,86-(723)211-0742,Structural Analysis Engineer,6615870533,"Connelly, Durgan and Block" +Haskell,Ring,hring9z@bluehost.com,hring9z,Želiv,420-(641)544-3995,Financial Advisor,4876809534,"Lynch, Sipes and Rodriguez" +Germaine,Nugent,gnugenta0@netscape.com,gnugenta0,Żyrardów,48-(730)293-9054,Senior Editor,3174803845,"Schimmel, Zulauf and Koepp" +Karel,Lokier,klokiera1@ow.ly,klokiera1,Dolinsk,7-(925)530-5945,Safety Technician II,4154581473,"Hirthe, Lindgren and Aufderhar" +Helena,Jeeves,hjeevesa2@sphinn.com,hjeevesa2,Cimanggu,62-(941)630-4312,Product Engineer,7546527988,"Gusikowski, Leannon and Jacobs" +Alberik,Dillingstone,adillingstonea3@columbia.edu,adillingstonea3,Zelenoborskiy,7-(836)258-0010,Dental Hygienist,7362248229,Mosciski-Runte +Carly,Linnett,clinnetta4@exblog.jp,clinnetta4,Pringgabaya,62-(246)753-9319,Administrative Officer,8092146349,Bashirian-Lebsack +Mortimer,Brando,mbrandoa5@upenn.edu,mbrandoa5,Vestmannaeyjar,354-(926)712-7652,Account Executive,3018918487,Kreiger Group +Filbert,Ablett,fabletta6@ycombinator.com,fabletta6,Mýki,30-(705)811-5277,Tax Accountant,6539074042,"Ziemann, Welch and Farrell" +Faith,Braven,fbravena7@reuters.com,fbravena7,Thessaloníki,30-(722)343-0087,Electrical Engineer,9811784329,Daniel Inc +Frannie,Davidov,fdavidova8@themeforest.net,fdavidova8,Palayan City,63-(745)265-1044,Web Designer II,6579399848,Denesik and Sons +Lucien,Tabner,ltabnera9@xinhuanet.com,ltabnera9,Mulyosari,62-(239)594-7444,Librarian,1502298732,"Rosenbaum, Reichert and Kunze" +Wally,Enever,weneveraa@bloglines.com,weneveraa,Satrejan,62-(645)352-9402,Office Assistant III,3527730311,Grady-Koelpin +Nedda,Gorke,ngorkeab@networkadvertising.org,ngorkeab,Stanišić,381-(108)441-3898,Research Associate,3014819530,Turner LLC +Bobby,Froggatt,bfroggattac@soup.io,bfroggattac,Platičevo,381-(674)755-5107,Quality Control Specialist,0737880740,"Goodwin, Gislason and Deckow" +Stace,Acaster,sacasterad@discovery.com,sacasterad,Macia,258-(104)153-7107,Health Coach IV,6201062777,Jones-Pollich +Oswald,Moulder,omoulderae@goo.gl,omoulderae,Khvastovichi,7-(214)819-4396,Social Worker,0394690478,Nikolaus-Erdman +Wanda,Glossop,wglossopaf@infoseek.co.jp,wglossopaf,Pinyug,7-(114)659-2688,Internal Auditor,2523327775,"Frami, Leffler and Schulist" +Drucy,Le Count,dlecountag@1und1.de,dlecountag,Skalat,380-(388)706-1735,Accountant III,1408462974,"Zieme, Terry and Runolfsdottir" +Jaclyn,Dohrmann,jdohrmannah@is.gd,jdohrmannah,Dongshan,86-(100)568-9635,GIS Technical Architect,3924999996,McKenzie-Hermiston +Yvonne,Sansun,ysansunai@omniture.com,ysansunai,El Progreso,507-(224)379-6931,Staff Accountant IV,8276625738,Sporer-Trantow +Vonny,Skipp,vskippaj@sbwire.com,vskippaj,Paokmotong Utara,62-(835)335-0196,Payment Adjustment Coordinator,5895390900,"Treutel, Brown and Brekke" +Karyl,Wadman,kwadmanak@imgur.com,kwadmanak,Yanjiao,86-(360)378-3302,Staff Scientist,1910238406,"Hansen, Pagac and Deckow" +Kippie,Bradden,kbraddenal@marriott.com,kbraddenal,Jönköping,46-(543)587-0300,Staff Scientist,9176800180,Kirlin Inc +Paddy,Kettlesing,pkettlesingam@cornell.edu,pkettlesingam,Oslo,47-(849)145-5733,Structural Engineer,8705223008,Jaskolski-Harber +Kane,Wennington,kwenningtonan@ucsd.edu,kwenningtonan,Lukashin,374-(349)354-4479,Staff Scientist,7435531871,Schneider Inc +Sherill,Williamson,swilliamsonao@earthlink.net,swilliamsonao,Mafang,86-(496)852-1140,Accounting Assistant III,1506840779,Dooley-Olson +Audre,Inglish,ainglishap@ehow.com,ainglishap,Minian,62-(250)963-0003,Business Systems Development Analyst,4065598095,"Stoltenberg, Wisozk and Weimann" +Berri,Fedorski,bfedorskiaq@umich.edu,bfedorskiaq,Norcasia,57-(162)449-5682,Safety Technician IV,0098301586,Maggio LLC +Ursulina,Whitehurst,uwhitehurstar@wikipedia.org,uwhitehurstar,Solna,46-(377)784-6117,Operator,0650376811,Bogan Inc +Alidia,Torr,atorras@fastcompany.com,atorras,Sandaohezi,86-(949)545-6861,Account Executive,4811145070,Lehner LLC +Kaye,Beane,kbeaneat@economist.com,kbeaneat,Nglojo,62-(355)846-4503,Systems Administrator III,9744419083,Fay-Schultz +Clywd,Rentz,crentzau@howstuffworks.com,crentzau,Yuguan,86-(368)395-3026,Community Outreach Specialist,8482525794,"Daugherty, Hammes and Grant" +Loella,Golledge,lgolledgeav@xing.com,lgolledgeav,Sangba,86-(997)138-0005,Computer Systems Analyst IV,3818896577,Kassulke Group +Berty,Shankle,bshankleaw@blog.com,bshankleaw,Bailai,86-(811)447-2940,Web Designer IV,1381483984,"Rutherford, Weissnat and Stoltenberg" +Elysha,Wormell,ewormellax@cornell.edu,ewormellax,Heshi,86-(459)905-4935,Engineer II,6903217533,Reynolds and Sons +Emelda,Kienl,ekienlay@edublogs.org,ekienlay,Szelków,48-(150)608-0093,Civil Engineer,0403741254,Ryan-Braun +Nanete,Shatliffe,nshatliffeaz@wikipedia.org,nshatliffeaz,Wongsorejo,62-(801)201-7190,Social Worker,9561076268,Corkery-Davis +Krisha,Luddy,kluddyb0@about.me,kluddyb0,Pulau Pinang,60-(664)235-5600,Research Assistant IV,5908588660,"Beier, Daniel and Johns" +Aloin,Bagnal,abagnalb1@webnode.com,abagnalb1,Јегуновце,389-(396)343-8442,Software Engineer IV,1870806077,Konopelski-Graham +Elna,Cockburn,ecockburnb2@goodreads.com,ecockburnb2,Trần Văn Thời,84-(508)784-0206,Dental Hygienist,3976709638,Monahan-Greenholt +Cointon,Leggan,clegganb3@ox.ac.uk,clegganb3,Biryulëvo Zapadnoye,7-(592)382-0444,Electrical Engineer,2202518185,Dibbert and Sons +Danila,Goldsbrough,dgoldsbroughb4@marriott.com,dgoldsbroughb4,Dowsk,375-(360)424-7789,Account Executive,9726332923,Bartoletti Group +Gigi,Philimore,gphilimoreb5@typepad.com,gphilimoreb5,Changxingbao,86-(393)226-0359,Physical Therapy Assistant,5418292374,Mayert-Casper +Adolf,Vakhlov,avakhlovb6@indiegogo.com,avakhlovb6,Cárdenas,53-(723)559-5803,VP Sales,6257773652,"Hamill, Okuneva and Hettinger" +Rozelle,Ivanchenkov,rivanchenkovb7@moonfruit.com,rivanchenkovb7,Paris 12,33-(806)491-2642,Nuclear Power Engineer,8868636387,Mante-Wolf +Kai,Orr,korrb8@cisco.com,korrb8,Osby,46-(498)794-8561,Sales Associate,3395375684,Lemke-Bednar +Collie,Yakunin,cyakuninb9@edublogs.org,cyakuninb9,Nanpu,86-(352)102-7244,Health Coach I,6101887901,Medhurst-Langosh +Fae,Cahill,fcahillba@reuters.com,fcahillba,Krzeszów,48-(622)530-7313,Food Chemist,6503968477,"Friesen, Sanford and Mayer" +Cyndie,Aslet,casletbb@scientificamerican.com,casletbb,Saint-Constant,1-(771)528-2913,Cost Accountant,4843499684,"Hamill, Sauer and Torphy" +Patrizius,Twyford,ptwyfordbc@weather.com,ptwyfordbc,Lagoa,351-(291)253-5463,Business Systems Development Analyst,0994297475,Mosciski Inc +Mattias,Streight,mstreightbd@yahoo.co.jp,mstreightbd,Skutskär,46-(177)125-2012,Actuary,5440187510,"Farrell, Sanford and Corkery" +Carlene,Vanni,cvannibe@themeforest.net,cvannibe,Mahates,57-(796)357-4709,Food Chemist,2337222705,Roob Inc +Ron,Durrance,rdurrancebf@wp.com,rdurrancebf,Mapalacsiao,63-(369)788-7340,Analyst Programmer,5457066193,Mitchell LLC +Carina,Edwardes,cedwardesbg@mapquest.com,cedwardesbg,Valinhos,55-(577)612-0116,Recruiting Manager,5227826919,Mosciski Inc +Maddalena,Salerg,msalergbh@umich.edu,msalergbh,Novopodrezkovo,7-(697)647-8581,Health Coach I,1557006229,Brekke Group +Philippe,Packington,ppackingtonbi@hp.com,ppackingtonbi,Wenshao,86-(707)622-9285,Accounting Assistant II,6329239517,Pacocha-Blick +Izzy,Nias,iniasbj@soundcloud.com,iniasbj,Miami,1-(786)311-2515,Help Desk Operator,1152831127,"Block, Altenwerth and Stanton" +Merwin,Parsell,mparsellbk@nba.com,mparsellbk,Gayny,7-(547)203-8806,Staff Scientist,7479993129,"Reinger, Quitzon and Vandervort" +Jessi,Dunkerly,jdunkerlybl@umn.edu,jdunkerlybl,Gaizhou,86-(909)634-5462,Recruiter,2986553141,"O'Reilly, Dicki and Hahn" +Eldon,Farndon,efarndonbm@aboutads.info,efarndonbm,Wolbrom,48-(909)281-4054,Speech Pathologist,5184371176,"Emmerich, Lehner and Yundt" +Oates,Elham,oelhambn@mozilla.com,oelhambn,Grand Bank,1-(194)436-8497,Desktop Support Technician,1596660937,"Wehner, Abbott and O'Connell" +Fanechka,Whyler,fwhylerbo@adobe.com,fwhylerbo,Matelândia,55-(892)769-4322,Biostatistician IV,7668303200,"Donnelly, Gerhold and Schaefer" +Huntington,Fernant,hfernantbp@ask.com,hfernantbp,Karabas,7-(750)276-8060,Senior Developer,1332953263,Pfeffer-Hills +Gregorius,St. Ledger,gstledgerbq@wp.com,gstledgerbq,Vlycháda,30-(743)197-1226,Software Test Engineer III,0656158816,Schaden and Sons +Cheri,Sainteau,csainteaubr@blinklist.com,csainteaubr,Hengtanggang,86-(187)273-0898,Data Coordiator,5175657151,"Larkin, Weber and Heathcote" +Christophorus,Poone,cpoonebs@amazonaws.com,cpoonebs,Were Īlu,251-(931)591-8988,Analyst Programmer,8910813008,Flatley and Sons +Waite,Castelletto,wcastellettobt@adobe.com,wcastellettobt,Cajamarca,57-(693)677-0164,VP Quality Control,1291883037,Rohan-Goodwin +Garth,Legion,glegionbu@mozilla.com,glegionbu,Heihe,86-(941)380-5673,Human Resources Manager,2515034527,"Nitzsche, Pfeffer and Braun" +Esta,Kerwin,ekerwinbv@networkadvertising.org,ekerwinbv,Mirpur Khas,92-(117)950-2082,Project Manager,8928828589,Glover Inc +Chloris,Beare,cbearebw@hhs.gov,cbearebw,Willowmore,27-(985)824-0594,Desktop Support Technician,8563826506,Feil-Reichel +Randell,Cancellieri,rcancellieribx@prnewswire.com,rcancellieribx,Bekwai,233-(905)301-0573,Human Resources Assistant I,0730372995,Kutch Inc +Kip,Ramsdale,kramsdaleby@arstechnica.com,kramsdaleby,Somerset East,27-(218)205-0925,Senior Quality Engineer,0802215807,Stehr and Sons +Codi,Sutherley,csutherleybz@163.com,csutherleybz,Monaghan,353-(394)919-0981,Account Representative I,6776632693,Stroman and Sons +Ichabod,Softley,isoftleyc0@networksolutions.com,isoftleyc0,Gorshechnoye,7-(857)425-7927,Junior Executive,0503472247,"Huel, Kunze and Grant" +Darnall,Menicomb,dmenicombc1@dyndns.org,dmenicombc1,Pisão,351-(603)152-7936,Nuclear Power Engineer,0704521695,"Jenkins, Bins and Bosco" +Hermie,Tripony,htriponyc2@state.tx.us,htriponyc2,Dahe,86-(695)324-3438,Staff Scientist,1453231722,Sauer Group +Rouvin,Brahms,rbrahmsc3@flickr.com,rbrahmsc3,Hyesan-dong,850-(373)849-6582,Speech Pathologist,1399653598,"Schumm, Willms and Kovacek" +Eva,Ausiello,eausielloc4@ted.com,eausielloc4,Las Flores,52-(522)676-7887,VP Product Management,2984517733,Doyle-Hackett +Homerus,Benz,hbenzc5@scribd.com,hbenzc5,Karangboyo,62-(463)880-8699,Geological Engineer,9502247396,Pacocha-Rath +Orelia,Cardoo,ocardooc6@theatlantic.com,ocardooc6,Huai Mek,66-(562)635-6374,Administrative Officer,2407522354,Sawayn LLC +Andy,Whyke,awhykec7@marketwatch.com,awhykec7,Melaka,60-(619)443-9740,Cost Accountant,7266501369,Stiedemann Group +Wendell,Charlot,wcharlotc8@weibo.com,wcharlotc8,Shanmu,86-(399)817-3579,Legal Assistant,1929334834,Hudson and Sons +Zaria,Rickert,zrickertc9@phoca.cz,zrickertc9,Sukamulya,62-(489)801-0441,Actuary,6151868455,McClure-Cormier +Liane,Bugbird,lbugbirdca@soup.io,lbugbirdca,Jiuchenggong,86-(742)484-7736,Director of Sales,5015471092,Dickinson Group +Hailee,Jackalin,hjackalincb@t.co,hjackalincb,Baziqiao,86-(348)628-0372,Engineer I,9824969918,"Schuster, Balistreri and Kiehn" +Sarina,Gretton,sgrettoncc@youtu.be,sgrettoncc,Kafr ash Shaykh,20-(570)759-6531,Programmer III,0761625356,Ruecker-Cronin +Nedi,Raiman,nraimancd@dailymotion.com,nraimancd,Pohang,82-(100)445-2527,Geologist II,5896756089,Ratke Inc +Flossie,O'Keenan,fokeenance@shutterfly.com,fokeenance,Ryjewo,48-(120)425-5167,Software Consultant,4109493390,"Macejkovic, Ziemann and Medhurst" +Cosette,Bodiam,cbodiamcf@apple.com,cbodiamcf,Falkenberg,46-(660)179-8368,Administrative Officer,1051595991,"Jast, Johnson and Eichmann" +Wylma,Risbridger,wrisbridgercg@infoseek.co.jp,wrisbridgercg,Villa Paula de Sarmiento,54-(727)419-0510,Nurse,7423041831,"Kuphal, Lind and Smith" +Anabal,Shuard,ashuardch@hexun.com,ashuardch,Nglojo,62-(150)961-7237,Business Systems Development Analyst,4136441134,"Lemke, Walter and Torp" +Bill,Bortoluzzi,bbortoluzzici@drupal.org,bbortoluzzici,São Miguel da Carreira,351-(302)874-8797,Payment Adjustment Coordinator,4539837109,Trantow Group +Arlena,Rosenbarg,arosenbargcj@com.com,arosenbargcj,Ingarö,46-(337)343-6677,Teacher,7371988523,McDermott-Pollich +Kaye,Olsson,kolssonck@sciencedaily.com,kolssonck,Shawan,86-(420)204-5708,Sales Representative,7882023620,"Willms, Maggio and Ebert" +Brady,Esmead,besmeadcl@cbsnews.com,besmeadcl,Dhahi,967-(539)198-8938,Senior Financial Analyst,3305446706,"Senger, Rau and White" +Beulah,De Cruz,bdecruzcm@shareasale.com,bdecruzcm,Menghe,86-(695)441-1949,Budget/Accounting Analyst I,1010118013,"Stoltenberg, Gaylord and Kuhn" +Hart,Pignon,hpignoncn@so-net.ne.jp,hpignoncn,Xishan,86-(796)134-7259,Senior Sales Associate,3487451824,Eichmann LLC +Gaultiero,Yapp,gyappco@gov.uk,gyappco,Silveiros,351-(968)335-1115,Editor,8432845973,Torphy-Pfeffer +Leonora,Camier,lcamiercp@i2i.jp,lcamiercp,Niebylec,48-(837)941-0248,Payment Adjustment Coordinator,3362041817,Tremblay-Bogan +Elsy,Barhem,ebarhemcq@howstuffworks.com,ebarhemcq,Baimi,86-(478)746-4408,Geologist III,3636465074,"Kling, Rempel and Schuppe" +Ludovika,Freemantle,lfreemantlecr@biblegateway.com,lfreemantlecr,Saint Catherine,20-(525)822-1176,Computer Systems Analyst IV,2508567590,Bartell Group +Niki,Bartoszewski,nbartoszewskics@geocities.jp,nbartoszewskics,Toyós,504-(285)333-3663,VP Product Management,8170495997,"Labadie, Schuster and Bailey" +Jasper,Scardifield,jscardifieldct@wordpress.org,jscardifieldct,Botoh,62-(908)487-6165,Mechanical Systems Engineer,4706641020,"Lindgren, Miller and Reilly" +Blondie,Korda,bkordacu@jimdo.com,bkordacu,Sayama,81-(550)261-8768,Safety Technician II,3613863448,"Beier, Hodkiewicz and Labadie" +Mari,Wildey,mwildeycv@earthlink.net,mwildeycv,Las Vegas,1-(702)780-0013,Community Outreach Specialist,6081899675,Ritchie Group +Rania,Caulier,rcauliercw@google.es,rcauliercw,Hongqiao,86-(135)941-5093,Recruiting Manager,9767170790,Sipes Group +Carmita,Balk,cbalkcx@nydailynews.com,cbalkcx,Radenković,381-(489)896-5035,Assistant Media Planner,3192007451,Rau Group +Raye,Rodwell,rrodwellcy@redcross.org,rrodwellcy,Ibusuki,81-(371)210-6897,Programmer IV,7817437106,Halvorson-Considine +Jeanelle,Gaunt,jgauntcz@chicagotribune.com,jgauntcz,Guajará Mirim,55-(942)383-5866,Environmental Tech,5293445545,"Cummings, Rohan and Olson" +Marten,Achromov,machromovd0@google.com.br,machromovd0,Carapicuíba,55-(150)839-0871,Professor,5673414536,Grady and Sons +Zebadiah,Ashton,zashtond1@aboutads.info,zashtond1,Liangwangzhuang,86-(533)605-8366,Assistant Media Planner,5660743293,O'Kon Inc +Nikolos,Rominov,nrominovd2@livejournal.com,nrominovd2,Wulingyuan,86-(988)701-4303,Administrative Officer,9339583396,McCullough Group +Abel,Brockley,abrockleyd3@usgs.gov,abrockleyd3,Cortiços,351-(655)931-9613,Computer Systems Analyst IV,4253152929,Schiller Group +Flss,Totaro,ftotarod4@slashdot.org,ftotarod4,Kolaka,62-(103)182-1362,Chief Design Engineer,1468159798,Bruen-Torp +Shaine,Tellenbach,stellenbachd5@pen.io,stellenbachd5,Gllogjan,383-(183)169-1139,VP Quality Control,5580264399,"Conroy, Bradtke and Huel" +Vanni,Zuanazzi,vzuanazzid6@sitemeter.com,vzuanazzid6,Astypálaia,30-(580)574-2168,Account Representative I,9464258799,Lakin LLC +Courtney,Dimitrie,cdimitried7@google.co.uk,cdimitried7,Houmt Souk,216-(733)765-8980,Associate Professor,1685573266,Paucek LLC +Cymbre,Footitt,cfootittd8@tiny.cc,cfootittd8,Leuwayang,62-(318)778-1877,VP Quality Control,3946614353,Hermann and Sons +Kaye,Jessope,kjessoped9@flavors.me,kjessoped9,Kalety,48-(845)480-1707,Senior Quality Engineer,3355884294,"Cremin, Olson and Sawayn" +Cornie,Limmer,climmerda@state.tx.us,climmerda,Guisser,212-(384)879-2239,Automation Specialist III,7826225280,Balistreri-Wiegand +Brenden,Verma,bvermadb@disqus.com,bvermadb,Sulengwaseng,62-(138)357-9869,Web Designer I,6172390155,"Waters, Streich and Abbott" +Lem,Benedikt,lbenediktdc@wunderground.com,lbenediktdc,Katoro,255-(482)187-5657,Engineer IV,0497224445,"Little, Mohr and Wilderman" +Lowell,Sichardt,lsichardtdd@globo.com,lsichardtdd,Camachile,63-(706)673-3182,Biostatistician I,2575941288,"Lemke, Lesch and Leannon" +Reine,Delgardillo,rdelgardillode@microsoft.com,rdelgardillode,Neob,62-(936)764-5075,Desktop Support Technician,1513506838,Spencer LLC +Thane,Sarchwell,tsarchwelldf@instagram.com,tsarchwelldf,Porto Seguro,55-(660)356-9567,Human Resources Manager,3527153179,Runolfsdottir-Cartwright +Danika,Elnor,delnordg@state.tx.us,delnordg,Niimi,81-(547)958-0387,Senior Developer,5050722578,Parisian-Towne +Gasparo,Stranio,gstraniodh@diigo.com,gstraniodh,Lezhu,86-(206)787-4960,Financial Analyst,4348687307,Goldner-Schmitt +Garnette,Calyton,gcalytondi@vimeo.com,gcalytondi,Karang,62-(950)627-5151,Human Resources Manager,0641236301,Prosacco-Ankunding +Justinn,Feakins,jfeakinsdj@mozilla.org,jfeakinsdj,Kalampáka,30-(795)552-9647,Engineer IV,8626479360,Nolan LLC +Linoel,Kibard,lkibarddk@bravesites.com,lkibarddk,Langpas,63-(644)213-0258,Database Administrator III,3377644679,Langworth-Veum +Gan,Lowde,glowdedl@issuu.com,glowdedl,Henan’an,86-(900)591-4847,Actuary,1207495840,"Pagac, White and Stroman" +Fleurette,Wolland,fwollanddm@dagondesign.com,fwollanddm,Vellinge,46-(300)800-9559,Structural Analysis Engineer,0953978931,Kirlin-Kozey +Wye,Duplan,wduplandn@qq.com,wduplandn,Ponong,63-(313)355-0869,Project Manager,5336314064,Shanahan-Bradtke +Benn,Mayo,bmayodo@oracle.com,bmayodo,Valdivia,56-(963)663-9803,Biostatistician IV,8306385837,Gaylord LLC +Benedict,Mannock,bmannockdp@techcrunch.com,bmannockdp,Adorjan,381-(876)163-1457,Account Coordinator,5751702727,"Ernser, Runte and Keebler" +Eloise,Cleverly,ecleverlydq@4shared.com,ecleverlydq,Colima,506-(165)753-5527,Technical Writer,3792802872,Muller Inc +Francesco,Egalton,fegaltondr@woothemes.com,fegaltondr,Taboão da Serra,55-(809)764-2655,Civil Engineer,5044892408,"Crist, Davis and Hirthe" +Jannelle,Ruddy,jruddyds@barnesandnoble.com,jruddyds,Golden,1-(272)196-2918,Assistant Media Planner,1533733090,Tromp-Emard +Dill,Raubenheimers,draubenheimersdt@state.tx.us,draubenheimersdt,Koumac,687-(276)528-4767,Engineer IV,0221672184,"Cole, Stamm and Lynch" +Norine,Sex,nsexdu@angelfire.com,nsexdu,Saint-Eustache,1-(297)748-3708,Nuclear Power Engineer,8545476949,Tromp LLC +Fernandina,Loraine,florainedv@zdnet.com,florainedv,Pojok,62-(678)818-1034,Operator,5968941170,Stark and Sons +Lincoln,Headly,lheadlydw@pinterest.com,lheadlydw,Rukem,62-(721)761-5670,Desktop Support Technician,1353588335,Mohr Group +Sibylle,Duplan,sduplandx@cloudflare.com,sduplandx,Saronída,30-(898)200-2504,Engineer II,1318020735,Nitzsche Inc +Durante,Plews,dplewsdy@engadget.com,dplewsdy,Quintela,351-(400)772-1387,Editor,2706273801,Jerde-Johnson +Simmonds,Weadick,sweadickdz@bbb.org,sweadickdz,Clisson,33-(449)808-9903,Statistician II,1395682046,Koss and Sons +Jinny,Southcoat,jsouthcoate0@imgur.com,jsouthcoate0,Kontiolahti,358-(307)727-1150,Director of Sales,8612730686,Glover Group +Tobias,Jedrys,tjedryse1@nifty.com,tjedryse1,Coalaque,51-(352)815-4498,Assistant Media Planner,3241037983,"Daugherty, Lowe and MacGyver" +Lyndsey,Beasant,lbeasante2@usgs.gov,lbeasante2,Quiñota,51-(893)499-0636,Civil Engineer,1638165475,"Bosco, Farrell and Kuvalis" +Morganica,Insole,minsolee3@bloglines.com,minsolee3,Alarobia,261-(772)192-7435,Software Consultant,8608912546,"Hodkiewicz, Dare and Treutel" +Terza,Sangster,tsangstere4@sourceforge.net,tsangstere4,Jagistay,86-(384)596-5400,Editor,8754711339,"Gleason, Luettgen and Dietrich" +Russell,Crewther,rcrewthere5@webs.com,rcrewthere5,Khiwa,998-(651)198-4172,Tax Accountant,0566254271,"Grimes, Koelpin and Koepp" +Lizabeth,Edmeads,ledmeadse6@facebook.com,ledmeadse6,Tsinandali,995-(180)383-8027,Budget/Accounting Analyst I,9980383631,Bode LLC +Karee,O'Feeny,kofeenye7@microsoft.com,kofeenye7,Berezayka,7-(584)773-4095,Senior Sales Associate,2984805720,"Kirlin, Bosco and Jaskolski" +Adelbert,Ahrenius,aahreniuse8@businessweek.com,aahreniuse8,Trollhättan,46-(560)840-1787,Accountant II,6318469885,Grimes-Rippin +Imogene,Ahern,iaherne9@biblegateway.com,iaherne9,Binalbagan,63-(324)343-0387,Senior Cost Accountant,5597923358,"Kemmer, Wyman and Borer" +Bethanne,Olrenshaw,bolrenshawea@feedburner.com,bolrenshawea,Veiga,351-(737)841-1999,Marketing Manager,6637045683,Stiedemann-Nader +Morey,Rabjohns,mrabjohnseb@google.ru,mrabjohnseb,Buang,63-(598)261-6461,Analog Circuit Design manager,4124185693,Champlin LLC +Bert,Shiel,bshielec@examiner.com,bshielec,Pignon,509-(674)488-9175,Programmer Analyst II,7670176377,Frami-Senger +Justinian,Worters,jwortersed@hp.com,jwortersed,Shanjeev Home,94-(667)505-1821,Pharmacist,0380071401,Schmitt LLC +Isabeau,Bumpus,ibumpusee@reverbnation.com,ibumpusee,Åkersberga,46-(384)641-5637,Structural Engineer,3748433670,Casper Inc +Saunderson,Fucher,sfucheref@wikia.com,sfucheref,Tianchi,86-(579)480-2053,VP Marketing,1518810926,Grimes-Harber +Bernard,Nanni,bnannieg@taobao.com,bnannieg,Smimou,212-(309)174-5946,Nurse Practicioner,2559240513,Mueller-Kuhic +Vivie,Deerness,vdeernesseh@bbc.co.uk,vdeernesseh,Puerta de Corral Quemado,54-(623)114-6422,Systems Administrator I,6638453319,Crona LLC +Lyn,Portinari,lportinariei@wix.com,lportinariei,Amqui,1-(265)894-9823,Design Engineer,6404381532,Krajcik LLC +Netta,Tubble,ntubbleej@wikispaces.com,ntubbleej,Lentisqueira,351-(888)721-3359,Sales Associate,7584772129,"Fay, Smith and Boyle" +Kerrill,Coultous,kcoultousek@gizmodo.com,kcoultousek,Ḩarf al Musaytirah,963-(663)978-3503,Statistician III,2943721670,Haley-Eichmann +Linzy,Yglesias,lyglesiasel@bizjournals.com,lyglesiasel,Anse Boileau,248-(902)643-6897,Operator,2871357994,"Abernathy, Schuppe and Nienow" +Allison,Harden,ahardenem@jiathis.com,ahardenem,Cishangang,86-(457)230-2552,Research Associate,0614061776,Barrows Group +Carlos,Freemantle,cfreemantleen@techcrunch.com,cfreemantleen,Ylämaa,358-(714)766-2393,Professor,6268473329,Leuschke LLC +Annice,Roubottom,aroubottomeo@google.ca,aroubottomeo,Herceg-Novi,382-(172)374-0117,Help Desk Operator,3869023244,Herman and Sons +Madeleine,Joincey,mjoinceyep@businesswire.com,mjoinceyep,Mělník,420-(175)226-2829,Programmer II,3947098820,Osinski Inc +Berke,Rojas,brojaseq@webeden.co.uk,brojaseq,Oemollo,62-(656)492-8444,Analyst Programmer,3830440014,"Goyette, Farrell and Gleason" +Samuele,Tassaker,stassakerer@github.io,stassakerer,Vyksa,7-(544)516-7710,Media Manager III,5627912308,Howe Inc +Edy,Makeswell,emakeswelles@mapquest.com,emakeswelles,København,45-(567)897-5052,VP Sales,1349041246,Schultz and Sons +Zebulen,Lukovic,zlukovicet@independent.co.uk,zlukovicet,Garawati,62-(251)559-0462,General Manager,0684692104,Emard Group +Robby,Walles,rwalleseu@deliciousdays.com,rwalleseu,Dongfeng,86-(344)516-7422,Account Executive,1069939455,Klein and Sons +Priscilla,Rowthorn,prowthornev@yellowpages.com,prowthornev,Chodów,48-(766)379-8879,Developer I,2612438270,Cassin Group +Rutger,Heynen,rheynenew@ed.gov,rheynenew,Barbaza,63-(998)385-4724,Geological Engineer,0716980800,Conn Group +Silvano,Oloman,solomanex@who.int,solomanex,Wenping,86-(729)929-2019,Executive Secretary,6206962660,"Becker, Waelchi and Rowe" +Costanza,Flaune,cflauneey@ameblo.jp,cflauneey,Lianyun,86-(703)407-6420,Project Manager,8356088984,Runolfsdottir-Glover +Bronson,Espine,bespineez@ucla.edu,bespineez,Longonjo,244-(866)340-1198,Programmer IV,9275318654,"Langworth, Stracke and Littel" +Tessy,Warman,twarmanf0@un.org,twarmanf0,Kuala Terengganu,60-(979)185-5701,Structural Analysis Engineer,7047075690,O'Kon Group +Dewain,Gravestone,dgravestonef1@noaa.gov,dgravestonef1,Ludvika,46-(235)721-0297,Analog Circuit Design manager,0691001715,Nolan Inc +Rourke,Denty,rdentyf2@naver.com,rdentyf2,Molinos,51-(784)178-5510,Community Outreach Specialist,7734182216,Bartoletti-Durgan +Carmela,Say,csayf3@salon.com,csayf3,Zubtsov,7-(534)684-8554,Junior Executive,9517395299,"Rosenbaum, Jenkins and Zboncak" +Hurleigh,Strongitharm,hstrongitharmf4@google.com,hstrongitharmf4,Tver,7-(506)278-6475,Analyst Programmer,6615367807,Simonis-Swift +Bondon,Lambregts,blambregtsf5@g.co,blambregtsf5,Xingzhen,86-(440)798-6899,Staff Accountant II,4751010697,Okuneva-Kuhn +Isiahi,Beard,ibeardf6@wired.com,ibeardf6,Zhavoronki,7-(974)299-4320,Tax Accountant,2230870122,"Wiza, Pfannerstill and Hyatt" +Remy,Rzehorz,rrzehorzf7@pcworld.com,rrzehorzf7,Ketanggi,62-(750)848-8321,Research Assistant IV,1606199781,"Hegmann, Yundt and Schoen" +Charles,Vivash,cvivashf8@livejournal.com,cvivashf8,Hantai,86-(114)123-5243,VP Sales,5008348752,Langworth and Sons +Angel,Coda,acodaf9@webs.com,acodaf9,Hexi,86-(364)879-7511,Programmer III,1157097758,"O'Conner, Bartell and O'Reilly" +Althea,Threader,athreaderfa@blogger.com,athreaderfa,Sviblovo,7-(521)978-2163,Financial Analyst,0343346095,"Barton, Kling and Ullrich" +Auberta,MacKeever,amackeeverfb@com.com,amackeeverfb,Taldyqorghan,7-(663)142-7914,Administrative Officer,0191723436,Kertzmann LLC +Jerrie,Reucastle,jreucastlefc@eepurl.com,jreucastlefc,Ondoy,63-(160)870-2513,Biostatistician IV,2763802451,Koelpin Group +Maible,Youll,myoullfd@soup.io,myoullfd,Alivéri,30-(400)482-8650,Computer Systems Analyst IV,2572163950,Abshire Inc +Donica,Hamments,dhammentsfe@xrea.com,dhammentsfe,Nida,370-(354)730-7273,Biostatistician II,5210866432,Windler Group +Miquela,Worman,mwormanff@shareasale.com,mwormanff,Foso,233-(566)694-7353,Dental Hygienist,3549652224,Reichel-Zieme +Uriah,Surcomb,usurcombfg@blogger.com,usurcombfg,La Soledad,52-(603)246-8965,Accounting Assistant III,1599078163,"Sipes, Nader and Keeling" +Roddie,Esilmon,resilmonfh@ehow.com,resilmonfh,Palestina,57-(708)985-3162,Electrical Engineer,0363630694,O'Hara LLC +Corinna,Geffen,cgeffenfi@usnews.com,cgeffenfi,Jastrowie,48-(332)296-1446,Budget/Accounting Analyst II,5462938233,Dickens and Sons +Gonzales,Muckloe,gmuckloefj@cornell.edu,gmuckloefj,Fatumuti,62-(643)699-2477,Geologist II,7192127329,Marquardt Group +Sharon,Chidwick,schidwickfk@unc.edu,schidwickfk,Foxton,64-(588)279-0414,Biostatistician IV,3192402563,Reynolds Inc +Vern,LeEstut,vleestutfl@abc.net.au,vleestutfl,Las Palmas,52-(921)609-1168,Senior Financial Analyst,5113676810,Marvin and Sons +Bob,Hof,bhoffm@theglobeandmail.com,bhoffm,Rama,505-(907)179-2015,Geological Engineer,0120147319,"Willms, Kling and Hand" +Nobie,Gerbl,ngerblfn@cbc.ca,ngerblfn,Daugavgrīva,371-(698)955-4899,Desktop Support Technician,9420600106,Bahringer and Sons +Antons,Exrol,aexrolfo@china.com.cn,aexrolfo,Shizuishan,86-(784)172-4409,Help Desk Operator,8368132096,Ferry-Conn +Wye,Hayward,whaywardfp@phoca.cz,whaywardfp,Espinal,57-(245)501-5469,Accountant IV,2488307750,Hammes-Lubowitz +Son,Falconer-Taylor,sfalconertaylorfq@github.io,sfalconertaylorfq,‘Amrān,967-(212)195-4767,Product Engineer,6404706520,McDermott-Ledner +Pavlov,Reek,preekfr@typepad.com,preekfr,Thị Trấn Thất Khê,84-(333)510-3759,Desktop Support Technician,9682249406,"Ruecker, Lowe and Maggio" +Amabel,Iannazzi,aiannazzifs@shop-pro.jp,aiannazzifs,Karangpari,62-(156)856-7713,Environmental Tech,0594104572,Hodkiewicz Inc +Anselm,Pickworth,apickworthft@earthlink.net,apickworthft,Kukës,355-(384)728-4155,Professor,6571348071,Rowe Group +Hildegarde,Gleder,hglederfu@vistaprint.com,hglederfu,Pancheng,86-(840)213-5262,Geological Engineer,0195510852,Carroll Inc +Benita,Marvell,bmarvellfv@tripadvisor.com,bmarvellfv,Malakwāl,92-(801)819-9067,Account Coordinator,3394329107,Bernier and Sons +Willdon,Stanlack,wstanlackfw@ucoz.ru,wstanlackfw,Trảng Bàng,84-(463)410-2718,Project Manager,6933652521,"Labadie, Lehner and Gusikowski" +Almira,Bartens,abartensfx@who.int,abartensfx,Lac-Brome,1-(112)440-7909,VP Accounting,1810818982,"Hilll, Hane and Langworth" +Berenice,Broschke,bbroschkefy@about.me,bbroschkefy,Na Di,66-(281)869-0575,Senior Cost Accountant,2630118150,Schaden-Schaden +Melony,Rosenfelt,mrosenfeltfz@nih.gov,mrosenfeltfz,Huitang,86-(373)267-4793,Food Chemist,1356491731,"Langosh, Altenwerth and Johnson" +Matias,Casaccia,mcasacciag0@t.co,mcasacciag0,Astghadzor,374-(558)741-2748,Librarian,6078806653,Gulgowski and Sons +Godfrey,Dorran,gdorrang1@gnu.org,gdorrang1,Longde Chengguanzhen,86-(621)856-4764,Programmer III,5779767149,"Bosco, Moen and Bosco" +Ynes,Gonin,ygoning2@huffingtonpost.com,ygoning2,Jacksonville,1-(904)987-7870,Human Resources Assistant III,8997890921,Purdy Inc +Erasmus,Catterick,ecatterickg3@mozilla.com,ecatterickg3,Shanghu,86-(554)629-1624,Senior Financial Analyst,1930579853,Rohan-Romaguera +Alfred,Pickton,apicktong4@mapquest.com,apicktong4,Sŭedinenie,359-(979)995-4685,Professor,0814432573,Hayes-Windler +Stacia,Mordy,smordyg5@apple.com,smordyg5,Springfield,1-(217)733-3909,VP Sales,4240850924,Beier-Wisozk +Kimberli,Keymer,kkeymerg6@tuttocitta.it,kkeymerg6,Borås,46-(203)476-9733,Paralegal,1853533335,"Fahey, Hudson and Jones" +Vivienne,McGeoch,vmcgeochg7@chron.com,vmcgeochg7,Campraksanta,62-(302)790-3621,VP Product Management,2746698242,"Kassulke, Wilderman and Kassulke" +Ezmeralda,Gutteridge,egutteridgeg8@moonfruit.com,egutteridgeg8,Motema,232-(245)252-3308,Chief Design Engineer,4899196601,Graham-Emard +Beitris,Andino,bandinog9@disqus.com,bandinog9,Brailiv,380-(777)219-2795,Senior Cost Accountant,9458256909,Mosciski Group +Maury,Bonick,mbonickga@comcast.net,mbonickga,Ubrub,62-(119)279-1772,Recruiting Manager,5647159451,"D'Amore, Nitzsche and Leffler" +Verene,Leatherland,vleatherlandgb@miitbeian.gov.cn,vleatherlandgb,Jaroměřice nad Rokytnou,420-(156)711-3140,Internal Auditor,3971930999,"Pollich, Turner and Bergstrom" +Hewett,Dent,hdentgc@tripod.com,hdentgc,Gaoyi,86-(921)190-0405,Administrative Assistant III,4114980911,Marks and Sons +Rozina,Seeds,rseedsgd@ox.ac.uk,rseedsgd,Nàng Mau,84-(207)987-9555,Administrative Officer,5612798245,"Nicolas, Schamberger and Stoltenberg" +Emmalee,Billany,ebillanyge@elegantthemes.com,ebillanyge,Santo André,351-(578)791-9024,Account Executive,3066103560,Howe-Kuphal +Jeniffer,Salan,jsalangf@devhub.com,jsalangf,Sete Lagoas,55-(474)631-1789,Marketing Manager,1699081859,Schaden-Fadel +Welbie,Palmby,wpalmbygg@nymag.com,wpalmbygg,Payaman,62-(397)816-2725,Programmer Analyst II,9993174750,Price Group +Ossie,Machans,omachansgh@bravesites.com,omachansgh,Libas,63-(840)761-5683,Nuclear Power Engineer,1326272306,Sanford-Wolf +Cristobal,Binne,cbinnegi@jiathis.com,cbinnegi,Arcoverde,55-(521)304-2880,Desktop Support Technician,7531238543,McLaughlin-Stracke +Annissa,McLice,amclicegj@tinypic.com,amclicegj,Selce,389-(892)609-3070,Recruiting Manager,4860531817,"Swift, Koelpin and Mohr" +Kalle,Betty,kbettygk@earthlink.net,kbettygk,Yasenskaya,7-(832)933-4153,Executive Secretary,7077128954,Hartmann-Rempel +Sinclair,Cattrall,scattrallgl@aol.com,scattrallgl,Ipuh,62-(543)627-2201,Quality Engineer,8290193610,Dicki-Prohaska +Laure,Meatcher,lmeatchergm@bizjournals.com,lmeatchergm,Tarsouat,212-(795)252-4345,Chief Design Engineer,5305354692,"Farrell, Morissette and Armstrong" +Jacquelyn,Kidman,jkidmangn@youku.com,jkidmangn,Bwizibwera,256-(558)763-0287,Design Engineer,3633113959,Mann-Goyette +Marcos,Boulger,mboulgergo@nbcnews.com,mboulgergo,Kalinkavichy,375-(595)296-8756,Environmental Specialist,2167764766,"Parisian, Abernathy and Jakubowski" +Conchita,Brunnstein,cbrunnsteingp@nsw.gov.au,cbrunnsteingp,Iturama,55-(102)637-6336,Help Desk Operator,1423412257,"Kovacek, Pfeffer and Carter" +Moyra,Metcalfe,mmetcalfegq@facebook.com,mmetcalfegq,Huangmao,86-(656)348-7372,Professor,7600769646,"Sipes, Pollich and Maggio" +Nikolia,Eastope,neastopegr@1688.com,neastopegr,Viçosa,55-(184)114-8152,Nuclear Power Engineer,4776960494,"Lemke, Mayer and Fisher" +Gabey,Charteris,gcharterisgs@hugedomains.com,gcharterisgs,Sidi Yahya Ou Saad,212-(198)542-6078,VP Accounting,3560342406,Renner and Sons +Kirbie,Claxton,kclaxtongt@php.net,kclaxtongt,Gualán,502-(814)325-5193,Nurse,2826332090,Kiehn Group +Hinze,Snoddin,hsnoddingu@google.pl,hsnoddingu,Kastélli,30-(288)788-8171,Web Developer I,6651023586,"Padberg, Runolfsson and Torphy" +Costa,Rix,crixgv@taobao.com,crixgv,Pueblo Nuevo,504-(962)252-2773,Assistant Professor,8691814632,Cartwright Group +Abdul,Doodney,adoodneygw@icq.com,adoodneygw,San Esteban,63-(872)929-4757,Senior Financial Analyst,5370482837,"Strosin, Runolfsson and Steuber" +Martyn,Stanyland,mstanylandgx@moonfruit.com,mstanylandgx,Folques,351-(942)195-7146,Geological Engineer,9248462006,"Rice, Connelly and Murray" +Erda,Shewring,eshewringgy@php.net,eshewringgy,Gostivar,389-(117)756-5444,Paralegal,1798073269,Schamberger-Luettgen +Kerry,Yeaman,kyeamangz@elpais.com,kyeamangz,Gongju,82-(786)382-2951,Marketing Assistant,4905126673,"Schulist, Fadel and Emard" +Shirley,Wholesworth,swholesworthh0@opensource.org,swholesworthh0,Abuko,220-(724)675-0904,Software Consultant,0321418409,Heller and Sons +Ennis,Abrahmovici,eabrahmovicih1@wiley.com,eabrahmovicih1,Bambas,51-(472)197-9673,Developer IV,8962080176,Considine-Gibson +Sharla,Sutherley,ssutherleyh2@behance.net,ssutherleyh2,Tabuadelo,351-(811)635-6156,VP Quality Control,6808874077,Runolfsdottir LLC +Gunther,Brandsen,gbrandsenh3@i2i.jp,gbrandsenh3,Buayan,63-(375)213-4457,Paralegal,5717407505,"Hane, Gutmann and Franecki" +Kaylee,Enocksson,kenockssonh4@t-online.de,kenockssonh4,Qingshi,86-(192)784-2084,Environmental Specialist,2870295510,Hayes and Sons +Peyton,Dearnaly,pdearnalyh5@storify.com,pdearnalyh5,Mulyosari,62-(688)290-2297,Speech Pathologist,4872281845,"Champlin, Miller and Mueller" +Angelle,Kindread,akindreadh6@sciencedaily.com,akindreadh6,Gīdolē,251-(603)654-7849,Assistant Professor,0831351950,Gorczany-Hayes +Leonerd,Lardez,llardezh7@deliciousdays.com,llardezh7,Herāt,93-(513)328-2863,Tax Accountant,7061036621,"Renner, Schamberger and Ryan" +Louise,Veltman,lveltmanh8@elegantthemes.com,lveltmanh8,Kluki,48-(852)795-6465,General Manager,2227283882,Nolan-Labadie +Daryle,Peacey,dpeaceyh9@answers.com,dpeaceyh9,Lenart v Slov. Goricah,386-(848)241-2826,Nuclear Power Engineer,6994450376,Weissnat Inc +Petey,Atyeo,patyeoha@yahoo.com,patyeoha,Osa,7-(360)966-8784,Systems Administrator I,1033908479,Bartoletti Group +Ely,Jessope,ejessopehb@issuu.com,ejessopehb,Sidoaji,62-(919)917-3443,Internal Auditor,7107889222,"Padberg, Kshlerin and Skiles" +Susie,Wyleman,swylemanhc@feedburner.com,swylemanhc,Zaječí,420-(235)631-9169,Technical Writer,1491248297,Wisoky Inc +Shari,Byne,sbynehd@hao123.com,sbynehd,Portela,351-(260)826-4437,Quality Control Specialist,7458232994,"Hyatt, Ward and Collier" +Rosanna,Chasles,rchasleshe@elegantthemes.com,rchasleshe,Bombon,63-(602)353-2130,Health Coach III,1370246951,Dibbert-Wuckert +Trista,Twydell,ttwydellhf@sfgate.com,ttwydellhf,Magdug,63-(267)213-3595,Technical Writer,3196286061,Goodwin-Walsh +Alisun,Harvatt,aharvatthg@miibeian.gov.cn,aharvatthg,Hongcao,86-(527)384-1497,Editor,1503083594,Herzog-Koch +Corenda,Keijser,ckeijserhh@163.com,ckeijserhh,Laguna,55-(197)776-6176,Professor,9644133080,Crooks-Bergstrom +Osbourn,Kilmurry,okilmurryhi@icq.com,okilmurryhi,Horní Suchá,420-(955)543-1671,Analog Circuit Design manager,0179532030,Leffler-Towne +Laurel,Standell,lstandellhj@wired.com,lstandellhj,Lysyanka,380-(164)654-2407,Research Nurse,0063563037,"Lehner, Carroll and Miller" +Patrizius,Hayworth,phayworthhk@usgs.gov,phayworthhk,Khao Yoi,66-(417)147-7061,Research Associate,8831310038,"Lynch, Bergnaum and Breitenberg" +Mellie,Begent,mbegenthl@time.com,mbegenthl,Longtan,86-(227)445-3953,Senior Developer,4637997372,Bernhard and Sons +Genny,Belderfield,gbelderfieldhm@imgur.com,gbelderfieldhm,Kotaagung,62-(726)439-6434,Geological Engineer,1472967216,Lueilwitz and Sons +Kurt,Laminman,klaminmanhn@blogspot.com,klaminmanhn,Vellinge,46-(774)244-0032,Physical Therapy Assistant,8906345453,Mertz and Sons +Sherye,Hoff,shoffho@dyndns.org,shoffho,Jiang’an,86-(860)511-6274,Technical Writer,7175131356,"Stroman, Hermann and Boyle" +Lauren,Burroughes,lburrougheshp@tinyurl.com,lburrougheshp,Molchanovo,7-(213)371-4675,Senior Editor,4118331314,Lockman LLC +Arlin,Tatteshall,atatteshallhq@imdb.com,atatteshallhq,Nashville,1-(615)299-5360,Senior Quality Engineer,5243521639,"Stracke, Fadel and Emard" +Simon,McGruar,smcgruarhr@soup.io,smcgruarhr,Koroyo,62-(952)895-9075,Analyst Programmer,4293044027,Pagac and Sons +Butch,Spieght,bspieghths@51.la,bspieghths,Alupay,63-(195)738-7403,Senior Cost Accountant,3544033011,"Jones, Hudson and Strosin" +Ernestus,Wayte,ewayteht@pagesperso-orange.fr,ewayteht,Tmourghout,212-(185)849-2999,Community Outreach Specialist,4620300438,"Macejkovic, Luettgen and Hilll" +Melania,Danis,mdanishu@shinystat.com,mdanishu,Tubigan,63-(155)678-5743,Cost Accountant,0700955313,Smitham-Walter +Fanechka,Snookes,fsnookeshv@biglobe.ne.jp,fsnookeshv,Periyiáli,30-(948)845-5272,Engineer I,8597224908,"Zieme, Mante and Stokes" +Tasha,Perche,tperchehw@zimbio.com,tperchehw,"Coruña, A",34-(281)688-2390,Senior Developer,2704074135,"Volkman, Conn and Orn" +Devi,Jadczak,djadczakhx@statcounter.com,djadczakhx,Carrigtwohill,353-(169)296-6030,Data Coordiator,8972860239,Ferry Group +Giraldo,Klouz,gklouzhy@irs.gov,gklouzhy,Garešnica,385-(653)814-6119,Computer Systems Analyst IV,6329487731,Leannon-Becker +Kania,Camacke,kcamackehz@weebly.com,kcamackehz,Dingbao,86-(241)334-0377,Structural Engineer,2689561948,Witting-Vandervort +Arv,Neads,aneadsi0@so-net.ne.jp,aneadsi0,Ueno,81-(627)675-4358,Chemical Engineer,8213531027,Nitzsche Inc +Buck,Dumbar,bdumbari1@techcrunch.com,bdumbari1,Tawun,62-(229)591-2099,Internal Auditor,0884547655,Mraz and Sons +Britte,O'Downe,bodownei2@amazon.com,bodownei2,Hājīganj,880-(992)543-4663,Staff Accountant I,0305047736,Hickle-Hand +Vinson,Guislin,vguislini3@cbc.ca,vguislini3,Cernik,385-(362)625-9868,Software Consultant,2429844117,Bosco LLC +Clem,Foulcher,cfoulcheri4@who.int,cfoulcheri4,Kuala Lumpur,60-(583)708-9044,Design Engineer,5142570715,"Marvin, Hirthe and Buckridge" +Marijn,Doe,mdoei5@cmu.edu,mdoei5,Stetseva,380-(786)296-7914,Business Systems Development Analyst,2327586224,Borer Group +Franky,Harmar,fharmari6@eventbrite.com,fharmari6,Imperatriz,55-(402)985-2787,Research Nurse,2751212336,Hessel-Borer +Melanie,Lanston,mlanstoni7@lycos.com,mlanstoni7,Kebloran,62-(547)549-5683,Environmental Tech,6385884392,Weissnat-Torphy +Myrta,Clyburn,mclyburni8@networksolutions.com,mclyburni8,Rukunlima Bawah,62-(779)426-2396,Staff Scientist,5509025476,"McLaughlin, Osinski and Collier" +Morley,Daunter,mdaunteri9@wordpress.com,mdaunteri9,Luebo,242-(881)386-7556,Community Outreach Specialist,5450221975,Erdman-Lang +Sergei,McLachlan,smclachlania@mit.edu,smclachlania,Lipka,48-(694)410-6816,Dental Hygienist,4778154002,Stracke Group +Cris,Madner,cmadnerib@t.co,cmadnerib,Cibitungmasjid,62-(256)723-0358,Account Representative IV,0864545916,Altenwerth Group +Kare,Kusick,kkusickic@booking.com,kkusickic,Shaogongzhuang,86-(248)651-0611,Account Coordinator,9219229250,Koelpin Group +Pepi,Gibbie,pgibbieid@tripod.com,pgibbieid,Simeykyne,380-(307)793-5872,Operator,7579392461,"Kuvalis, Fadel and Grady" +Edgar,Howieson,ehowiesonie@princeton.edu,ehowiesonie,San Rafael,52-(867)635-2442,Mechanical Systems Engineer,4239028027,Kiehn and Sons +Athena,Rackstraw,arackstrawif@sina.com.cn,arackstrawif,Baoquan,86-(211)673-0672,Engineer IV,9897657584,Vandervort Inc +Caryn,McLaughlin,cmclaughlinig@example.com,cmclaughlinig,Menara,62-(517)611-9675,Media Manager II,5101719706,Baumbach and Sons +Erminie,MacVaugh,emacvaughih@about.me,emacvaughih,Wuying,86-(982)324-4880,Sales Representative,7268375182,Jaskolski-Hodkiewicz +Christian,O'Corhane,cocorhaneii@uiuc.edu,cocorhaneii,Lianghe,86-(280)250-8522,Professor,4233331798,Doyle-Rogahn +Adeline,McPeice,amcpeiceij@vinaora.com,amcpeiceij,Kilifarevo,359-(467)886-3465,Assistant Professor,9912656946,Abernathy-Ritchie +Gibby,Cable,gcableik@nydailynews.com,gcableik,Belsh,355-(430)161-7493,Compensation Analyst,4006105606,Brown and Sons +Jaime,Kilpin,jkilpinil@ihg.com,jkilpinil,Agbor,234-(550)573-5938,Quality Control Specialist,9442626183,"Gutmann, Gutmann and Hahn" +Melinda,Murkus,mmurkusim@telegraph.co.uk,mmurkusim,Pensacola,1-(850)183-4895,Media Manager II,1475423861,"Gutkowski, Bernhard and Hoppe" +Aharon,Gierhard,agierhardin@jugem.jp,agierhardin,Donnybrook,353-(865)934-3131,Compensation Analyst,3658785446,"Boyle, Rogahn and Orn" +Dulcia,Gilham,dgilhamio@slate.com,dgilhamio,Butere,254-(251)327-8937,Senior Editor,4146349249,"Sawayn, Paucek and Schroeder" +Lyman,Juniper,ljuniperip@ft.com,ljuniperip,Hässleholm,46-(383)546-4101,Automation Specialist III,0767169050,Yost Inc +Darbie,Fintoph,dfintophiq@lulu.com,dfintophiq,Hepu,86-(187)731-4385,Developer III,4370176271,"Schmeler, Cassin and Schoen" +Rufus,Ollerhead,rollerheadir@berkeley.edu,rollerheadir,Ban Mai,66-(642)265-2874,Community Outreach Specialist,3832984623,"Dietrich, Rice and Reichel" +Norby,Matthensen,nmatthensenis@google.com.au,nmatthensenis,Tranca,63-(890)438-0411,General Manager,5299514352,Morar Inc +Burch,Boys,bboysit@time.com,bboysit,Guomaying,86-(713)916-0654,Assistant Professor,3655303270,Zboncak-Padberg +Helge,Bexley,hbexleyiu@dedecms.com,hbexleyiu,Beiwenquan,86-(409)408-7860,Administrative Officer,8185761264,"Bergstrom, Wisozk and Runolfsson" +Michelle,Sommerlin,msommerliniv@cdbaby.com,msommerliniv,Jīsh,972-(622)160-0841,Structural Engineer,7599030719,Durgan-Rodriguez +Isabelita,Wolstenholme,iwolstenholmeiw@stumbleupon.com,iwolstenholmeiw,Azinhal,351-(223)866-1661,Director of Sales,7664763312,"Tromp, Dibbert and Zieme" +Krispin,O'Fergus,kofergusix@wikispaces.com,kofergusix,Banturkrajan,62-(483)542-1518,Physical Therapy Assistant,8741838637,"Strosin, Turner and Quigley" +Meredeth,Budd,mbuddiy@biblegateway.com,mbuddiy,Svetlogorsk,7-(415)890-6602,Project Manager,9331158890,"Rippin, Bartoletti and Hermann" +Babbette,Dunsleve,bdunsleveiz@thetimes.co.uk,bdunsleveiz,Maddela,63-(210)680-5698,Chemical Engineer,0144827441,Wilderman Inc +Bar,Reiners,breinersj0@sun.com,breinersj0,Caldas Novas,55-(971)994-8220,Quality Control Specialist,3672681563,McClure-Moen +Dalt,McKellar,dmckellarj1@163.com,dmckellarj1,Thị Trấn Hà Trung,84-(749)471-2636,Senior Quality Engineer,4697508440,Kautzer and Sons +Ronalda,Gentric,rgentricj2@umich.edu,rgentricj2,Bahe,86-(924)710-4685,Office Assistant II,6446558430,Pouros and Sons +Gill,Matthessen,gmatthessenj3@shop-pro.jp,gmatthessenj3,Nangka,63-(915)902-5478,Web Developer I,3664671848,Blick-Terry +Hailey,Danet,hdanetj4@bbb.org,hdanetj4,Xuebu,86-(655)642-0475,Dental Hygienist,7854730350,Moore Group +Donalt,Lynnett,dlynnettj5@ucla.edu,dlynnettj5,Pingshan,86-(712)618-8254,Community Outreach Specialist,3037055472,"Gleichner, Heathcote and McKenzie" +Oralla,Clausius,oclausiusj6@state.gov,oclausiusj6,Villa del Rosario,57-(671)722-4375,Director of Sales,5376445232,Kemmer Inc +Nance,Deware,ndewarej7@twitter.com,ndewarej7,Ibusuki,81-(617)941-4064,Software Engineer III,2028791357,"Yundt, Corwin and Quitzon" +Aloysia,Friman,afrimanj8@edublogs.org,afrimanj8,Gambalidio,63-(313)382-0374,General Manager,8838662975,"Rau, Wolff and Kovacek" +Elga,Starkey,estarkeyj9@salon.com,estarkeyj9,Gävle,46-(645)607-0229,Marketing Manager,7385675786,Hirthe-Thiel +Jeannine,Annett,jannettja@so-net.ne.jp,jannettja,Burayevo,7-(461)292-8366,Account Coordinator,7989157179,Rippin Group +Dulci,Sparkwell,dsparkwelljb@lulu.com,dsparkwelljb,Abóboda,351-(425)960-3179,Sales Associate,8042244673,"Will, Williamson and Bogisich" +Gisela,Skoughman,gskoughmanjc@hao123.com,gskoughmanjc,Huashixia,86-(933)889-2829,Actuary,3828915523,Langosh LLC +Cosme,Pryer,cpryerjd@amazon.com,cpryerjd,Belle-Anse,509-(582)842-9287,Tax Accountant,6487901008,Upton and Sons +Thurstan,Pringle,tpringleje@indiegogo.com,tpringleje,Dongchen,86-(943)729-3038,Account Coordinator,5562817837,"Satterfield, Mraz and Reichel" +Ebeneser,Longworthy,elongworthyjf@furl.net,elongworthyjf,Patquía,54-(789)253-7217,Registered Nurse,1170122795,Schulist-Braun +Johnette,Wildes,jwildesjg@answers.com,jwildesjg,Frederiksberg,45-(869)821-2650,Automation Specialist I,3643331975,"Effertz, Parisian and Bergnaum" +Allan,Raecroft,araecroftjh@hud.gov,araecroftjh,Sapele,234-(501)388-9974,Senior Developer,7938194387,"Dicki, White and Harber" +Appolonia,Aizikov,aaizikovji@marriott.com,aaizikovji,Toukh,20-(857)889-1761,Technical Writer,4754105559,Green LLC +Yevette,Songist,ysongistjj@google.it,ysongistjj,Dallas,1-(214)546-6784,Staff Accountant IV,0401661873,Erdman Group +Tandy,Abeau,tabeaujk@aboutads.info,tabeaujk,Denver,1-(720)737-3543,Librarian,8505630270,Bashirian-Koepp +Marsh,Pencost,mpencostjl@constantcontact.com,mpencostjl,Buenaventura,57-(263)213-3776,Analyst Programmer,0310343887,Hoeger LLC +Dan,Reignard,dreignardjm@squidoo.com,dreignardjm,Tanahedang,62-(883)790-2315,Financial Analyst,3648884352,"Parisian, Barrows and Osinski" +Nerta,Ruffler,nrufflerjn@wikispaces.com,nrufflerjn,Jincheng,886-(342)705-8378,Internal Auditor,8567561698,"Wintheiser, VonRueden and Lowe" +Zed,Bolsover,zbolsoverjo@omniture.com,zbolsoverjo,Matão,55-(339)205-0401,Recruiting Manager,4399340495,Crist-Will +Gonzalo,Paddington,gpaddingtonjp@phpbb.com,gpaddingtonjp,Montelíbano,57-(405)589-5804,Product Engineer,8554752384,"Lubowitz, Sanford and Lehner" +Lucas,Elington,lelingtonjq@utexas.edu,lelingtonjq,Anding,86-(960)550-4751,Web Designer III,2740694938,Davis Group +Leoine,Lovett,llovettjr@multiply.com,llovettjr,Pittsburgh,1-(412)586-0854,Electrical Engineer,8541351939,Hoppe-Romaguera +Kara,McGeagh,kmcgeaghjs@cyberchimps.com,kmcgeaghjs,Kubang,62-(768)313-0005,Software Engineer IV,0452302706,Huel-Zemlak +Jabez,Saylor,jsaylorjt@blogger.com,jsaylorjt,Luhans’ke,380-(559)819-5482,Food Chemist,7450835533,"Bergstrom, Stoltenberg and Satterfield" +Debor,Vautre,dvautreju@lycos.com,dvautreju,Zhuangbu,86-(936)413-2474,Teacher,3855224137,"Emmerich, Muller and Yundt" +Odille,Simonou,osimonoujv@blogtalkradio.com,osimonoujv,Łęki Szlacheckie,48-(989)791-3951,Senior Cost Accountant,0849963257,"Doyle, Abbott and Lind" +Abraham,Chalfont,achalfontjw@stumbleupon.com,achalfontjw,Bang Kaeo,66-(342)372-0269,Pharmacist,7010972532,Powlowski Group +Willy,Ives,wivesjx@squarespace.com,wivesjx,Cimenga,62-(444)941-8150,Analyst Programmer,1782184376,"Spencer, Oberbrunner and Daniel" +Reinald,Worley,rworleyjy@cnn.com,rworleyjy,Sumberpandan,62-(148)705-1796,Junior Executive,2076403906,Feeney-Cruickshank +Leone,Borris,lborrisjz@desdev.cn,lborrisjz,Tisco,51-(892)888-9517,Technical Writer,3611286087,Schumm-Christiansen +Jethro,Ede,jedek0@cbc.ca,jedek0,Auch,33-(947)670-3513,Senior Developer,5503574176,Senger Group +Netti,Hallford,nhallfordk1@bloomberg.com,nhallfordk1,Falāvarjān,98-(501)345-1506,Engineer IV,8529835794,"Bruen, Funk and Thompson" +Tiffi,Potapczuk,tpotapczukk2@xinhuanet.com,tpotapczukk2,Castanheira de Pêra,351-(462)484-6335,Tax Accountant,8392227476,Mertz-Runolfsdottir +Garald,Doddrell,gdoddrellk3@comcast.net,gdoddrellk3,Ketawang,62-(195)332-5729,Senior Financial Analyst,3328544089,Mohr-Jast +Haze,MacGillacolm,hmacgillacolmk4@123-reg.co.uk,hmacgillacolmk4,Langgen,62-(754)132-9274,Administrative Assistant IV,9044438050,"Brekke, Strosin and Berge" +Emili,Coon,ecoonk5@youtube.com,ecoonk5,Nzérékoré,224-(495)776-5371,Information Systems Manager,1695217985,O'Conner Inc +Padriac,Alvy,palvyk6@ted.com,palvyk6,Biryulëvo Zapadnoye,7-(421)373-0762,Graphic Designer,3669986006,"Schiller, Willms and Feeney" +Hamnet,Layman,hlaymank7@desdev.cn,hlaymank7,Ifon,234-(343)694-2565,Programmer Analyst II,6185480751,Hahn-Weber +Redd,Calvie,rcalviek8@google.cn,rcalviek8,Ambar,51-(774)884-7397,Senior Sales Associate,0185044085,Bashirian Inc +Kerrie,Kenrick,kkenrickk9@samsung.com,kkenrickk9,Al Manāqil,249-(655)472-4763,Software Consultant,9046610284,Wuckert-Farrell +Nara,Innwood,ninnwoodka@sbwire.com,ninnwoodka,Chadi,86-(547)693-2410,Budget/Accounting Analyst III,3718838753,"Kertzmann, Funk and Tremblay" +Bernice,Deftie,bdeftiekb@rediff.com,bdeftiekb,Charleston,1-(304)936-1410,Senior Developer,9632166434,Ward-Senger +Cletus,Minor,cminorkc@mapy.cz,cminorkc,Suraż,48-(241)331-0004,Junior Executive,4560795215,Wilderman Inc +Clerkclaude,Knighton,cknightonkd@bigcartel.com,cknightonkd,Haoyi,86-(660)290-9882,Account Executive,2632094100,Barton-Bechtelar +Burtie,Bowen,bbowenke@booking.com,bbowenke,Avallon,33-(509)681-5577,Structural Engineer,0588974048,"Hudson, Kautzer and Senger" +Cris,Cody,ccodykf@miibeian.gov.cn,ccodykf,Saskatoon,1-(865)113-1166,Analyst Programmer,2698386916,MacGyver-Kessler +Wainwright,Aylen,waylenkg@microsoft.com,waylenkg,San Martín de los Andes,54-(334)143-7746,Electrical Engineer,9984965074,Nicolas-Kassulke +Clare,Calbreath,ccalbreathkh@independent.co.uk,ccalbreathkh,Pará de Minas,55-(147)835-8826,Research Nurse,6199708253,"Runte, Stanton and Nitzsche" +Fenelia,Brewood,fbrewoodki@uiuc.edu,fbrewoodki,Agra,351-(684)979-6665,Data Coordiator,0051836793,"Schmidt, O'Connell and Treutel" +Hans,Chiese,hchiesekj@reference.com,hchiesekj,Kamieniec Wrocławski,48-(988)578-1699,Data Coordiator,4667259698,Gibson-Barrows +Tabina,Janauschek,tjanauschekkk@berkeley.edu,tjanauschekkk,Río Grande,1-(470)119-5478,Human Resources Assistant II,6083625874,Keebler Group +Bridgette,Nisuis,bnisuiskl@theatlantic.com,bnisuiskl,Baie-Saint-Paul,1-(702)724-5290,Geological Engineer,9705430446,Kihn Group +Syd,Leahair,sleahairkm@wiley.com,sleahairkm,Guarabira,55-(457)962-6675,Community Outreach Specialist,4844140248,Bernier and Sons +Gannie,Vennard,gvennardkn@macromedia.com,gvennardkn,Kayapa,63-(909)747-4808,Web Designer II,3698363402,"Schimmel, Friesen and Witting" +Avictor,Ligertwood,aligertwoodko@bigcartel.com,aligertwoodko,Ustrzyki Dolne,48-(416)290-1849,Nurse Practicioner,4174955700,Ernser-Kihn +Heidi,Castelijn,hcastelijnkp@apache.org,hcastelijnkp,Ilihan,63-(500)806-5161,Administrative Officer,1259802647,"Osinski, Sanford and Ritchie" +Ida,Barday,ibardaykq@spotify.com,ibardaykq,Tourcoing,33-(795)533-7343,Clinical Specialist,5206989193,"Jerde, Douglas and Rodriguez" +Melodee,Valek,mvalekkr@samsung.com,mvalekkr,Shichuan,86-(456)232-9420,Financial Analyst,4251707303,Lakin-Dooley +Mellie,Blois,mbloisks@vinaora.com,mbloisks,Cagliari,39-(810)963-1749,Recruiting Manager,3769720873,"Strosin, Wuckert and Mann" +Marabel,Chester,mchesterkt@delicious.com,mchesterkt,Si Bun Rueang,66-(161)732-1476,Geologist III,6339789307,Williamson-Witting +Gertrud,Keats,gkeatsku@tripadvisor.com,gkeatsku,Lam Plai Mat,66-(582)827-0005,Recruiter,0297472623,Farrell and Sons +Orsola,Adriaens,oadriaenskv@hibu.com,oadriaenskv,Shaguotun,86-(820)144-0827,Paralegal,5854900106,"Ledner, Murazik and McGlynn" +Kendricks,Livesley,klivesleykw@yelp.com,klivesleykw,Palilula,381-(321)472-2578,Junior Executive,7051295772,Robel and Sons +Randall,Denkel,rdenkelkx@about.me,rdenkelkx,Spånga,46-(892)234-6007,Recruiter,8622374491,"McDermott, Cartwright and Beatty" +Edythe,Boundey,eboundeyky@simplemachines.org,eboundeyky,Al Qaţīf,966-(760)484-2393,Editor,8633506122,Medhurst-Miller +Dillon,Piesing,dpiesingkz@bluehost.com,dpiesingkz,Qiucun,86-(543)608-4097,Account Coordinator,7448756443,"Kunze, Medhurst and Grant" +Constancia,Eagland,ceaglandl0@photobucket.com,ceaglandl0,Staryy Dobrotvir,380-(868)809-9720,Desktop Support Technician,6850975951,Zulauf Group +Tressa,Bourne,tbournel1@odnoklassniki.ru,tbournel1,Aulnay-sous-Bois,33-(523)199-1041,Programmer IV,7844943165,Hamill Group +Iolande,Tunnicliffe,itunnicliffel2@artisteer.com,itunnicliffel2,Síkinos,30-(238)211-8025,Associate Professor,4285351382,"Mills, Romaguera and Anderson" +Nalani,Bignall,nbignalll3@ftc.gov,nbignalll3,Itapipoca,55-(365)774-4231,GIS Technical Architect,7259801018,Dicki-Schroeder +Horatio,Vanner,hvannerl4@apple.com,hvannerl4,Laohugang,86-(312)980-2632,Marketing Assistant,0784848610,VonRueden-Feil +Felice,Jenken,fjenkenl5@fda.gov,fjenkenl5,San Francisco de Coray,504-(252)407-9161,Software Test Engineer III,7301006063,Stanton Inc +Fax,Critchard,fcritchardl6@posterous.com,fcritchardl6,Feilaixia,86-(530)993-0259,Research Assistant I,1837505667,"Halvorson, Rodriguez and Murray" +Eberto,Matzeitis,ematzeitisl7@tinypic.com,ematzeitisl7,Paris 08,33-(813)124-1255,Physical Therapy Assistant,3214003879,"Schimmel, Pouros and Yost" +Gamaliel,Yakebowitch,gyakebowitchl8@dyndns.org,gyakebowitchl8,Zhendeqiao,86-(902)945-5865,Health Coach IV,3858926728,Morissette-Hand +Flor,Boarer,fboarerl9@i2i.jp,fboarerl9,Laventure,230-(655)375-4043,Quality Control Specialist,3619658951,Casper Group +Deeanne,Burghill,dburghillla@smugmug.com,dburghillla,Safotu,685-(601)390-5584,Software Engineer I,3672399876,"Conroy, Kerluke and Steuber" +Brant,Greenstead,bgreensteadlb@toplist.cz,bgreensteadlb,Adelaide,61-(892)926-0595,Systems Administrator IV,6507194689,Stanton Group +Edita,Stanes,estaneslc@ning.com,estaneslc,Asikkala,358-(104)994-3852,Compensation Analyst,6256493079,Schaefer-Mayer +Audie,Suche,asucheld@ed.gov,asucheld,Xinjian,86-(928)968-5707,Community Outreach Specialist,7207127251,Heaney Group +Phelia,de Amaya,pdeamayale@ovh.net,pdeamayale,Comagascas,63-(548)192-2681,Tax Accountant,6804167333,Moen-Medhurst +Brodie,Capelow,bcapelowlf@google.es,bcapelowlf,San Miguel,52-(505)227-1532,Help Desk Operator,0321116399,"Block, Hirthe and Lemke" +Darelle,Hickin,dhickinlg@addtoany.com,dhickinlg,Tonghu,86-(429)741-1635,Recruiting Manager,9703631940,"Boyer, Ullrich and Hirthe" +Gabriell,Priestley,gpriestleylh@topsy.com,gpriestleylh,Szeged,36-(890)962-0345,Compensation Analyst,9074958451,Weber-Bins +Ainsley,Batchelar,abatchelarli@adobe.com,abatchelarli,Plast,7-(909)894-8943,Staff Accountant III,3774125082,"Parker, Bechtelar and Mosciski" +Carole,Hammett,chammettlj@deliciousdays.com,chammettlj,Shchukino,7-(234)811-0491,VP Marketing,7633646497,"Beer, Veum and Lowe" +Alfie,Duffett,aduffettlk@cam.ac.uk,aduffettlk,Krajan Dua Putukrejo,62-(959)919-5850,Project Manager,2080467263,Durgan-Fritsch +Arley,Gillman,agillmanll@cdbaby.com,agillmanll,Karangori,62-(707)970-1378,Financial Advisor,0893767778,Stamm Group +Khalil,Goodboddy,kgoodboddylm@zimbio.com,kgoodboddylm,Dijon,33-(369)847-3482,Geological Engineer,6558979381,Goyette and Sons +Halimeda,Gowman,hgowmanln@cam.ac.uk,hgowmanln,Krasni Okny,380-(937)249-4520,Senior Financial Analyst,1911763253,Howe Inc +Ardis,Benardet,abenardetlo@nytimes.com,abenardetlo,Concepción del Uruguay,54-(567)429-0565,Account Representative IV,4637416302,"Feil, Bartoletti and Adams" +Ivory,Lawlie,ilawlielp@thetimes.co.uk,ilawlielp,Schroeder,55-(878)697-6010,Senior Cost Accountant,9431774984,"King, Crona and Von" +Barb,Derisley,bderisleylq@mashable.com,bderisleylq,Tangyu,86-(708)194-0125,Marketing Assistant,6826292726,Deckow-Lemke +Malissia,Sharer,msharerlr@java.com,msharerlr,Jinghai,86-(252)422-3886,Human Resources Manager,8382713882,Grimes-Hansen +Jessamine,Lichfield,jlichfieldls@businesswire.com,jlichfieldls,Micoud,1-(934)806-6515,VP Product Management,6093340430,Kozey Inc +Rogerio,Tindall,rtindalllt@biblegateway.com,rtindalllt,Vistino,7-(527)696-9343,Actuary,2542803676,Ritchie-Marquardt +Averyl,Garratt,agarrattlu@instagram.com,agarrattlu,Lamovita,387-(200)844-4864,Senior Quality Engineer,1885568886,Ernser-Hartmann +Becki,Edelmann,bedelmannlv@gmpg.org,bedelmannlv,Mawlamyine,95-(718)995-2413,Actuary,2746351579,Schamberger LLC +Micky,Smitherman,msmithermanlw@chicagotribune.com,msmithermanlw,Belén,598-(243)420-8445,Civil Engineer,2781994006,"Ward, Harris and Nader" +Barbabra,Cork,bcorklx@nytimes.com,bcorklx,Tanzhesi,86-(229)632-7950,Research Associate,8772167009,Hane Group +Erastus,Cauldfield,ecauldfieldly@friendfeed.com,ecauldfieldly,Nglojo,62-(962)330-7466,Senior Developer,5790337376,"Leuschke, Jaskolski and Jaskolski" +Hube,Rowaszkiewicz,hrowaszkiewiczlz@tinypic.com,hrowaszkiewiczlz,Ventanas,593-(568)247-0181,Software Engineer IV,6793591614,Littel-Deckow +Justis,Ickov,jickovm0@tripod.com,jickovm0,Issy-les-Moulineaux,33-(574)130-0058,Software Test Engineer II,2573983161,Hintz Inc +Wilie,Mawditt,wmawdittm1@wordpress.org,wmawdittm1,Zlatar,385-(148)463-0786,Mechanical Systems Engineer,1825804036,Kerluke-O'Connell +Henriette,Early,hearlym2@cisco.com,hearlym2,Salcedo,63-(859)802-4167,Quality Engineer,9157866023,Rowe and Sons +Kaycee,Nattriss,knattrissm3@ning.com,knattrissm3,Pindangan Centro,63-(749)241-7828,Chemical Engineer,1628687517,Rutherford-Kihn +Hart,Petran,hpetranm4@cnbc.com,hpetranm4,Pampas,51-(195)539-5625,Information Systems Manager,1793147906,"McKenzie, Weimann and Crona" +Holt,Kernock,hkernockm5@hhs.gov,hkernockm5,Dasiping,86-(729)481-1150,Recruiting Manager,3841216129,Lindgren Inc +Friedrick,Yurchenko,fyurchenkom6@cyberchimps.com,fyurchenkom6,Uppsala,46-(881)710-7992,Quality Control Specialist,8282139564,"Durgan, Simonis and Hilll" +Maybelle,Tapenden,mtapendenm7@cafepress.com,mtapendenm7,Guadalupe,52-(698)116-6571,Professor,4954283094,Goodwin Inc +Francesco,Hyatt,fhyattm8@blog.com,fhyattm8,Vänersborg,46-(590)336-4962,Systems Administrator IV,0752649760,Dach LLC +Marlene,Shevlan,mshevlanm9@independent.co.uk,mshevlanm9,København,45-(461)205-7636,Tax Accountant,5683419905,Gleichner-Schoen +Ignatius,Seals,isealsma@4shared.com,isealsma,Chimboy Shahri,998-(740)447-9648,Analog Circuit Design manager,0331255189,Kovacek-Bednar +Jasmina,Huggins,jhugginsmb@harvard.edu,jhugginsmb,Kulotino,7-(439)872-4789,Programmer Analyst IV,5646721199,"Koss, Bode and Halvorson" +Arther,Bisseker,abissekermc@redcross.org,abissekermc,Ad Dimnah,967-(145)760-6372,Web Designer IV,0238046222,"Fay, Reynolds and Schultz" +Brita,Cleynman,bcleynmanmd@scribd.com,bcleynmanmd,Joliet,1-(815)856-8278,Mechanical Systems Engineer,2016930195,"Hickle, Hagenes and Bode" +Danita,Aubry,daubryme@fema.gov,daubryme,Somanda,255-(761)470-0112,Food Chemist,2405625261,Kuphal-Littel +Hilton,Kyrkeman,hkyrkemanmf@sphinn.com,hkyrkemanmf,Linxia Chengguanzhen,86-(933)120-9575,Chief Design Engineer,9953149593,Sanford-Kiehn +Blondie,Heinrich,bheinrichmg@harvard.edu,bheinrichmg,Ban Lam Luk Ka,66-(919)563-5992,Nurse Practicioner,8391355985,Farrell-Stroman +Nathalia,Bettleson,nbettlesonmh@lulu.com,nbettlesonmh,Weston,44-(284)766-3674,Assistant Media Planner,7451462927,Schumm Inc +Nap,Croxford,ncroxfordmi@mapy.cz,ncroxfordmi,Liugou,86-(814)399-2809,Mechanical Systems Engineer,1028596766,"Vandervort, Howe and Schulist" +Matthieu,Pitney,mpitneymj@sourceforge.net,mpitneymj,Lulindi,255-(965)744-8651,Senior Sales Associate,9954867694,Stehr-Stehr +Bernadina,Batiste,bbatistemk@theglobeandmail.com,bbatistemk,Jinping,86-(805)406-0826,Marketing Assistant,0681175303,"Kemmer, Bednar and Schmidt" +Jo,Vasin,jvasinml@yandex.ru,jvasinml,Suchań,48-(719)533-4494,Social Worker,0672565900,McKenzie Group +Isabeau,Josovich,ijosovichmm@shutterfly.com,ijosovichmm,Detroit,1-(313)728-3071,Quality Engineer,9522586072,Stark Group +Hyacinth,Streatley,hstreatleymn@va.gov,hstreatleymn,Hanam,82-(962)234-8098,Assistant Professor,4446717154,Littel-Wisozk +Margarita,Roller,mrollermo@php.net,mrollermo,Itapevi,55-(849)570-9451,Teacher,4015506529,Kuhic Inc +Gottfried,Mawdsley,gmawdsleymp@hatena.ne.jp,gmawdsleymp,Duraznopampa,51-(850)770-5042,Teacher,4615844786,Sauer Inc +Colline,Tanner,ctannermq@squarespace.com,ctannermq,Osilnica,386-(375)123-4522,Accounting Assistant IV,4307546075,"Heaney, Prohaska and Treutel" +Toiboid,Slyman,tslymanmr@geocities.jp,tslymanmr,Niort,33-(246)445-0387,Safety Technician II,0876852541,Marquardt Group +Franky,Willden,fwilldenms@mlb.com,fwilldenms,Nanyaojie,86-(772)392-4262,Web Developer III,4615626932,"Botsford, Mante and Lind" +Cory,Sexti,csextimt@ft.com,csextimt,Smiths Falls,1-(856)759-7718,Senior Developer,8931416504,"Herman, Buckridge and Wehner" +Nevsa,Paoloni,npaolonimu@ox.ac.uk,npaolonimu,Songjiang,86-(861)892-4735,Registered Nurse,9011403533,Mosciski-Dietrich +Rosabelle,Harkess,rharkessmv@hexun.com,rharkessmv,Tambo,51-(320)850-5323,Geological Engineer,3284443002,Howe LLC +Bibbye,Maleham,bmalehammw@ifeng.com,bmalehammw,Dakoro,227-(563)968-9242,Programmer Analyst IV,1459020774,"Kuhlman, Bogan and Kshlerin" +Marcela,Houlston,mhoulstonmx@ebay.co.uk,mhoulstonmx,Ngedhusuba,62-(645)344-7228,Social Worker,8322158963,"Trantow, Kassulke and Lebsack" +Allen,Trembley,atrembleymy@goodreads.com,atrembleymy,Mānānwāla,92-(715)605-9507,Design Engineer,5813315675,"Miller, Yost and Stamm" +Wallas,Stansfield,wstansfieldmz@networkadvertising.org,wstansfieldmz,Xiongguan,86-(361)169-6974,Structural Engineer,8350979879,Hills-Waters +Alasdair,Konerding,akonerdingn0@msu.edu,akonerdingn0,Rennes,33-(354)767-4981,Web Designer III,6590238693,Nitzsche LLC +Kendell,Garvan,kgarvann1@quantcast.com,kgarvann1,Yong’an,86-(763)605-1170,Senior Developer,8673840058,Harris-Smith +Sayre,Orthmann,sorthmannn2@linkedin.com,sorthmannn2,Yabuli,86-(956)184-5074,Sales Associate,3238931334,Kozey-Kulas +Holt,Francillo,hfrancillon3@sciencedirect.com,hfrancillon3,Jiangcheng,86-(517)345-2568,Software Consultant,8031543178,Runolfsdottir Group +Gusella,Kinig,gkinign4@xing.com,gkinign4,Fastiv,380-(645)966-9040,Account Representative II,0511641788,MacGyver-Treutel +Otis,Reinhard,oreinhardn5@answers.com,oreinhardn5,Qiancang,86-(285)544-2263,Environmental Specialist,3357295903,Jerde Group +Carlin,MacAne,cmacanen6@samsung.com,cmacanen6,Yahotyn,380-(892)306-8669,Desktop Support Technician,5175081594,Hackett LLC +Berny,Ferri,bferrin7@prnewswire.com,bferrin7,Jimenez,63-(103)580-5845,Junior Executive,4749556203,Kuhn-Ullrich +Warren,Fulks,wfulksn8@wufoo.com,wfulksn8,Jose Maria Morelos,52-(886)281-8268,Statistician IV,0434789003,"West, Kuphal and Hills" +Barnett,Bane,bbanen9@arizona.edu,bbanen9,Namerikawa,81-(412)158-7515,Administrative Assistant III,1843810425,Wiegand LLC +Arin,Trimming,atrimmingna@constantcontact.com,atrimmingna,Nārāyanganj,880-(506)140-6037,Mechanical Systems Engineer,6579691301,"Trantow, Franecki and Huel" +Vinnie,Bruce,vbrucenb@economist.com,vbrucenb,Los Frentones,54-(143)653-9690,Occupational Therapist,7266214238,"Collins, Parker and Volkman" +Leandra,Jerdon,ljerdonnc@barnesandnoble.com,ljerdonnc,Mqabba,356-(828)530-5167,Cost Accountant,2421177081,Schimmel and Sons +Maurise,McRuvie,mmcruviend@cisco.com,mmcruviend,Takeo,855-(719)155-4461,VP Marketing,1603639632,Cassin-Gislason +Galen,Clutterham,gclutterhamne@reddit.com,gclutterhamne,Tantu,86-(856)743-6023,Developer IV,6406520327,"Pagac, Abbott and Renner" +Orsa,Faulkener,ofaulkenernf@51.la,ofaulkenernf,Guoyuan,86-(353)293-0614,Nurse,2168428441,Schamberger-Moore +Chas,Gaylard,cgaylardng@msn.com,cgaylardng,Ambat,62-(316)304-0070,Speech Pathologist,0230204961,Rodriguez Inc +Erek,Kilius,ekiliusnh@mapy.cz,ekiliusnh,Karakol,996-(757)549-4010,Account Representative III,8914898016,Champlin-Parker +Torrence,Dallow,tdallowni@livejournal.com,tdallowni,Rumat Heib,972-(551)251-4133,Payment Adjustment Coordinator,7839003737,Macejkovic LLC +Son,Nowakowski,snowakowskinj@home.pl,snowakowskinj,Pasirpengarayan,62-(403)683-3142,Media Manager IV,9394032258,"Weissnat, Bergnaum and Paucek" +Osbert,Nuscha,onuschank@bluehost.com,onuschank,San Antonio de Los Altos,58-(278)228-1044,Statistician II,9263802645,Wolff-Hudson +Kaspar,Smullin,ksmullinnl@ebay.co.uk,ksmullinnl,Hihyā,20-(858)200-1173,Operator,1352488523,Boyer and Sons +Temp,Palk,tpalknm@irs.gov,tpalknm,Llorente,63-(559)417-0912,Safety Technician II,5716467989,Rutherford-Dare +Julie,Poad,jpoadnn@webeden.co.uk,jpoadnn,Lajeosa,351-(229)448-4862,Office Assistant IV,3869073314,Jones-Pollich +Blanche,Schonfeld,bschonfeldno@umn.edu,bschonfeldno,Fresno,1-(209)844-2209,Desktop Support Technician,4348050724,Hand LLC +Tremaine,Wicks,twicksnp@ted.com,twicksnp,Tiglauigan,63-(592)251-6057,Executive Secretary,9357962085,Hessel LLC +Jessamyn,Mauro,jmauronq@ucsd.edu,jmauronq,Shuangpu,86-(782)336-1634,Senior Developer,2073896022,"Tillman, Schowalter and Kertzmann" +Morris,Pedro,mpedronr@wunderground.com,mpedronr,Fort Worth,1-(682)403-1808,Human Resources Assistant I,2418447138,Wiza-Lynch +Rossie,Lindblom,rlindblomns@flavors.me,rlindblomns,Espera Feliz,55-(354)448-5176,Senior Developer,9846657803,"D'Amore, Morar and Lubowitz" +Kelcie,Woolner,kwoolnernt@histats.com,kwoolnernt,Sainyabuli,856-(703)619-9373,Senior Cost Accountant,9679866378,Farrell-Windler +Brittaney,O' Bee,bobeenu@linkedin.com,bobeenu,Mombaça,55-(107)230-7103,Information Systems Manager,4366497247,Stroman-Blick +Kassie,Questier,kquestiernv@imageshack.us,kquestiernv,Bielsk Podlaski,48-(127)626-9904,Web Developer I,7973903593,O'Keefe-Altenwerth +Wilhelmina,Baldacco,wbaldacconw@yahoo.co.jp,wbaldacconw,Dasha,86-(814)517-9700,Actuary,0898566878,"Grant, Pollich and O'Keefe" +Griz,Jagels,gjagelsnx@alexa.com,gjagelsnx,Druzhny,375-(873)367-3588,Cost Accountant,5688512105,Hoeger Inc +Nikolaos,Abrahamowitcz,nabrahamowitczny@google.ca,nabrahamowitczny,Wawrzeńczyce,48-(788)215-2200,Community Outreach Specialist,3376050767,Champlin and Sons +Cesare,Kelf,ckelfnz@friendfeed.com,ckelfnz,Lucaya,1-(362)126-9927,Business Systems Development Analyst,4434280716,Turner-Conn +Olympia,McCaughey,omccaugheyo0@toplist.cz,omccaugheyo0,Soio,244-(652)536-5008,Senior Editor,2665247380,Swaniawski-Kihn +Magdalen,Wadhams,mwadhamso1@patch.com,mwadhamso1,Köping,46-(202)987-2026,Automation Specialist II,7922502885,Fahey LLC +Laughton,Charrette,lcharretteo2@plala.or.jp,lcharretteo2,El Paso,1-(915)296-9008,Software Engineer II,3832140409,Ferry-Hettinger +Antonin,McGaughey,amcgaugheyo3@technorati.com,amcgaugheyo3,Guanyao,86-(385)294-7834,Graphic Designer,4413617177,"Stoltenberg, Anderson and Schroeder" +Douglas,Peploe,dpeploeo4@paypal.com,dpeploeo4,Bala Murghab,93-(552)750-0409,Compensation Analyst,6584465276,Will and Sons +Saloma,Halcro,shalcroo5@biglobe.ne.jp,shalcroo5,Yongjiu,86-(663)473-4515,Assistant Media Planner,5412294472,Upton and Sons +Genia,Dockree,gdockreeo6@ed.gov,gdockreeo6,K’ulashi,995-(693)621-4145,Sales Representative,6311406926,Murazik-Gerlach +Ulysses,Vigne,uvigneo7@wisc.edu,uvigneo7,Bosobolo,242-(869)770-6551,Payment Adjustment Coordinator,6121045191,"Kuphal, Smith and Becker" +Amaleta,Hellcat,ahellcato8@com.com,ahellcato8,Paamiut,299-(827)658-4181,VP Marketing,9930317341,Sanford Group +Marys,Stobo,mstoboo9@addthis.com,mstoboo9,Fraga,351-(646)681-5809,Programmer Analyst IV,8215542689,"Conroy, Luettgen and Haag" +Carmelia,Cantillion,ccantillionoa@prweb.com,ccantillionoa,Sumberpucung,62-(715)732-9346,Structural Analysis Engineer,5743542775,Marquardt LLC +Jenifer,Ondrus,jondrusob@vinaora.com,jondrusob,Banos,63-(887)517-5901,Accounting Assistant III,1196707006,"Bruen, Paucek and Fisher" +Gillian,Espadas,gespadasoc@microsoft.com,gespadasoc,Brejoeira,351-(160)844-3330,Research Associate,1027647391,Weissnat-Blick +Vonni,Corley,vcorleyod@feedburner.com,vcorleyod,Melaka,60-(193)177-1978,Civil Engineer,5905339317,Lubowitz-Morar +Phillip,Ivanchin,pivanchinoe@addthis.com,pivanchinoe,Sasaguri,81-(145)417-6376,Account Coordinator,3636969412,Turcotte-Wisozk +Klarrisa,Letessier,kletessierof@wordpress.com,kletessierof,Gostyń,48-(126)737-5592,VP Quality Control,1411646746,Ankunding-Pfannerstill +Gasparo,Agron,gagronog@etsy.com,gagronog,Nangka,63-(410)186-8167,Senior Sales Associate,5644040968,Rippin-Goyette +Joni,Burnard,jburnardoh@timesonline.co.uk,jburnardoh,Ilām,977-(207)827-4512,Analyst Programmer,5890418432,Krajcik Inc +Kim,Kytter,kkytteroi@weibo.com,kkytteroi,Mojokerto,62-(279)874-2608,Environmental Specialist,1343560179,"Schulist, Weber and Paucek" +Lora,Elms,lelmsoj@narod.ru,lelmsoj,Cầu Gồ,84-(800)294-5849,VP Marketing,1493946587,Schamberger Group +Arlena,Paullin,apaullinok@reddit.com,apaullinok,Örebro,46-(532)455-1043,Senior Editor,4085398636,Grant and Sons +Richard,Darcy,rdarcyol@seesaa.net,rdarcyol,Batarasa,63-(298)338-2430,Community Outreach Specialist,7860234254,Bahringer LLC +Felizio,Padginton,fpadgintonom@gmpg.org,fpadgintonom,Nanzhen,86-(584)560-0295,Research Assistant III,3766611003,Spencer Group +Antonina,Kilpin,akilpinon@alexa.com,akilpinon,Schieren,352-(152)223-8179,Chemical Engineer,8146664725,"Labadie, Goyette and Jacobson" +Erika,Geator,egeatoroo@bloglovin.com,egeatoroo,Retorta,351-(404)826-3743,Assistant Professor,4828740651,Lakin Group +Ali,Straffon,astraffonop@hexun.com,astraffonop,Babiak,48-(388)809-9155,Actuary,5262099386,Reichel-Hand +Amabel,Board,aboardoq@shareasale.com,aboardoq,Diancun,86-(214)304-0961,Information Systems Manager,6355389466,Upton-Jaskolski +Gabie,Bradwell,gbradwellor@yandex.ru,gbradwellor,Gobō,81-(496)451-0957,Analog Circuit Design manager,8680375713,Nienow-Hermiston +Claretta,Finlaison,cfinlaisonos@trellian.com,cfinlaisonos,Chatturat,66-(920)250-8360,Database Administrator III,4852140383,Wiza-Predovic +Kippie,Panting,kpantingot@geocities.jp,kpantingot,Tojeira,351-(648)874-8790,Recruiter,7921358802,"Kunze, Jaskolski and Stoltenberg" +Linell,Croysdale,lcroysdaleou@buzzfeed.com,lcroysdaleou,Orós,55-(435)669-9483,Help Desk Technician,1212044088,Ledner-Johnston +Vasilis,Goublier,vgoublierov@altervista.org,vgoublierov,Caujul,51-(101)425-0809,Structural Analysis Engineer,4372624972,Bayer-Heller +Brocky,Gianiello,bgianielloow@flickr.com,bgianielloow,Huoxian,86-(427)267-9428,Developer IV,6023283195,Witting-Howe +Roland,Blowes,rblowesox@apache.org,rblowesox,Padej,381-(688)750-4717,Business Systems Development Analyst,7378441384,Bashirian-Wiegand +Garv,Peerman,gpeermanoy@a8.net,gpeermanoy,Yolöten,993-(132)948-7743,Cost Accountant,8711924012,Quigley Group +Damaris,Amberson,dambersonoz@noaa.gov,dambersonoz,Uchaly,7-(891)257-7839,Social Worker,0871438763,Cummerata and Sons +Reba,Laudham,rlaudhamp0@uiuc.edu,rlaudhamp0,Mendefera,291-(385)541-4183,Cost Accountant,9459415148,Gleichner LLC +Dill,Teligin,dteliginp1@telegraph.co.uk,dteliginp1,Garango,226-(818)796-5422,Tax Accountant,2544502487,Abbott-Thiel +Greta,Lewsam,glewsamp2@psu.edu,glewsamp2,Rostov-na-Donu,7-(207)756-1434,Staff Accountant I,3029138410,Schmitt-Bogisich +Norah,Jeremaes,njeremaesp3@netvibes.com,njeremaesp3,Xiakouyi,86-(488)113-1826,Office Assistant III,6252335258,Rempel-Abshire +Datha,Lenahan,dlenahanp4@unicef.org,dlenahanp4,Kuzhu,86-(851)353-6927,Sales Representative,1680930990,Lubowitz and Sons +Sophey,Phlipon,sphliponp5@behance.net,sphliponp5,Jiaoziya,86-(315)182-8625,Account Coordinator,5389921747,Effertz Group +Alix,Schirach,aschirachp6@lulu.com,aschirachp6,San Marcos,503-(169)421-0329,Electrical Engineer,2023606950,"Herzog, Funk and Gottlieb" +Mignon,Paddington,mpaddingtonp7@sogou.com,mpaddingtonp7,Panikian,63-(636)557-0276,Legal Assistant,2892389844,Cormier-Hudson +Darn,Elfleet,delfleetp8@blogtalkradio.com,delfleetp8,Dubravica,387-(878)576-7012,Mechanical Systems Engineer,2839634538,Olson-Bogan +Monique,Harmon,mharmonp9@admin.ch,mharmonp9,Roissy Charles-de-Gaulle,33-(545)532-7958,Associate Professor,9092943010,Hickle LLC +Tull,Infante,tinfantepa@tinyurl.com,tinfantepa,Xiaoruo,86-(387)599-5542,Marketing Assistant,9863380032,"Sanford, Bradtke and Farrell" +Nyssa,Madoc-Jones,nmadocjonespb@epa.gov,nmadocjonespb,Puerto Quellón,56-(955)181-7227,Assistant Manager,1890626058,Littel-Toy +Florence,Solomon,fsolomonpc@bbc.co.uk,fsolomonpc,Blois,33-(767)315-1932,VP Quality Control,3079951077,Eichmann Inc +Vanya,Schermick,vschermickpd@berkeley.edu,vschermickpd,Kunvald,420-(153)357-8683,Staff Accountant I,0920565719,Quigley-Bergstrom +Danita,Juanico,djuanicope@ca.gov,djuanicope,Cluny,230-(619)594-7589,Human Resources Manager,3146677113,"Kassulke, Ruecker and Hane" +Shelagh,Shelley,sshelleypf@marriott.com,sshelleypf,Sabaneta,58-(196)295-4803,Paralegal,7166846496,"Koelpin, Cremin and Langosh" +Kerk,Dufer,kduferpg@google.com.au,kduferpg,Rukem,62-(346)971-3292,Executive Secretary,2386201910,"Simonis, Johnson and Fay" +Ab,Davidde,adaviddeph@prnewswire.com,adaviddeph,Daxing,86-(500)810-4696,Community Outreach Specialist,5805532379,Boyer and Sons +Billye,Betteson,bbettesonpi@redcross.org,bbettesonpi,Longos,351-(101)580-5428,Physical Therapy Assistant,1479316938,Frami-Lesch +Harley,Brewer,hbrewerpj@upenn.edu,hbrewerpj,Dadoupu,86-(480)441-7751,Community Outreach Specialist,0039146294,"Corkery, Schaefer and Marks" +Wynnie,Solano,wsolanopk@zdnet.com,wsolanopk,Laidian,86-(253)399-5610,Assistant Professor,2137078449,"McClure, Satterfield and Barton" +Darn,Haffard,dhaffardpl@ask.com,dhaffardpl,Horton,44-(564)751-3439,Financial Advisor,5938631068,Pollich-Hermann +Howey,Stallan,hstallanpm@uol.com.br,hstallanpm,Anhai,86-(567)926-3005,VP Sales,3450645838,"Lockman, Crona and Abernathy" +King,Cicculini,kcicculinipn@devhub.com,kcicculinipn,Bolekhiv,380-(723)375-7883,VP Sales,1728709016,"Murazik, Yundt and Hane" +Kaela,Crispe,kcrispepo@fc2.com,kcrispepo,Sundsvall,46-(597)539-5689,Actuary,3188646194,Gleichner-Lindgren +Stearne,Wardingley,swardingleypp@about.me,swardingleypp,Shirgjan,355-(356)611-0499,Librarian,2611445389,Schmidt LLC +Devan,Swait,dswaitpq@flavors.me,dswaitpq,Yilan,86-(426)167-0401,Nuclear Power Engineer,0436813416,"Prosacco, Muller and Gleason" +Arline,Cunradi,acunradipr@samsung.com,acunradipr,San Luis,63-(588)882-9972,Speech Pathologist,6075640940,Beatty-Watsica +Cordi,Barkway,cbarkwayps@g.co,cbarkwayps,Gävle,46-(676)140-3109,Budget/Accounting Analyst I,6375200660,Balistreri-Collier +Carma,Radcliffe,cradcliffept@mit.edu,cradcliffept,Mineralni Bani,359-(527)871-2652,Programmer Analyst II,8264713580,Quigley Inc +Camila,Capehorn,ccapehornpu@sfgate.com,ccapehornpu,Oguma,234-(989)667-0635,Statistician I,7343647008,Gutkowski-Ullrich +Gerri,Molen,gmolenpv@bloglines.com,gmolenpv,Zhoukou,86-(924)447-1128,Professor,0195842693,"Howe, Bogisich and Stroman" +Maurizio,Cacacie,mcacaciepw@mit.edu,mcacaciepw,Ostrogozhsk,7-(519)339-7578,Data Coordiator,9811795614,"Johnson, Schinner and Pagac" +Jerrine,Sancias,jsanciaspx@cpanel.net,jsanciaspx,Hayan Hudong,86-(285)373-2471,Graphic Designer,3440547981,Littel-Feeney +Willie,Worlock,wworlockpy@omniture.com,wworlockpy,Campina Grande,55-(796)613-7498,Staff Scientist,8176496995,"Walsh, Jakubowski and Ernser" +Page,Salvadori,psalvadoripz@netscape.com,psalvadoripz,Kota Kinabalu,60-(507)527-2407,Account Coordinator,9922888610,"Kertzmann, Funk and Jenkins" +Alvie,Howsan,ahowsanq0@omniture.com,ahowsanq0,Parion,63-(234)698-7388,Operator,8071753939,Thompson-Keebler +Emera,Stout,estoutq1@craigslist.org,estoutq1,Dahu,86-(284)198-0386,Quality Control Specialist,7804586396,"Muller, Murazik and Zieme" +Lois,Gladdifh,lgladdifhq2@instagram.com,lgladdifhq2,Lleida,34-(715)382-4713,Database Administrator II,3633654518,Schumm LLC +Doug,Lamerton,dlamertonq3@si.edu,dlamertonq3,Villa Alemana,56-(149)630-1570,Research Nurse,2253131156,Hilpert Group +Theda,Ebbing,tebbingq4@craigslist.org,tebbingq4,Alung,62-(738)502-4534,Analyst Programmer,4591819175,"Farrell, Murazik and Mayert" +Kassandra,Swalwel,kswalwelq5@amazon.co.jp,kswalwelq5,Sacapulas,502-(884)290-1622,Senior Editor,7185464110,Gibson-Leffler +Livvy,Burroughes,lburroughesq6@amazonaws.com,lburroughesq6,Bailianhe,86-(458)619-0316,Librarian,1535422378,O'Hara Inc +Temp,Wardington,twardingtonq7@craigslist.org,twardingtonq7,Ngozi,257-(217)180-8803,Junior Executive,0848046633,"Waelchi, Schamberger and Huels" +Rhetta,Petrishchev,rpetrishchevq8@irs.gov,rpetrishchevq8,Tsinandali,995-(430)243-4289,Statistician I,7791803836,Pacocha LLC +Anastassia,Edgar,aedgarq9@cmu.edu,aedgarq9,Labuhansumbawa,62-(644)719-6905,General Manager,1184092605,"Cartwright, Bergstrom and Monahan" +Giana,Giacobazzi,ggiacobazziqa@jimdo.com,ggiacobazziqa,Tambac,63-(579)835-6229,Quality Control Specialist,6363216184,"Kuhic, Monahan and McGlynn" +Teriann,Dafydd,tdafyddqb@vistaprint.com,tdafyddqb,Babakanloa,62-(482)920-2072,Human Resources Assistant III,5821778638,"Ritchie, Herman and Lindgren" +Willa,Tacker,wtackerqc@bigcartel.com,wtackerqc,Ḩurayḑah,967-(806)911-9319,Health Coach II,9135157542,Kunze-Bahringer +Lucila,Sabater,lsabaterqd@apache.org,lsabaterqd,Humen,86-(614)109-2198,Software Engineer I,5293367323,Dach Group +Dael,Ondrak,dondrakqe@stumbleupon.com,dondrakqe,Marxog,86-(260)249-8251,Health Coach II,4372560729,Daugherty-Weber +Wait,St Pierre,wstpierreqf@wordpress.com,wstpierreqf,Biru,86-(860)639-5320,Programmer Analyst III,8047175459,Gaylord-Ebert +Rasla,Godlonton,rgodlontonqg@altervista.org,rgodlontonqg,Balgatay,976-(232)485-2320,Programmer Analyst III,3673385615,Veum-Braun +Kristine,Heersema,kheersemaqh@ft.com,kheersemaqh,Choibalsan,976-(538)269-3674,Structural Analysis Engineer,8626952910,Hilpert LLC +Sly,Causnett,scausnettqi@mozilla.com,scausnettqi,Krajan Gebangan,62-(773)388-2291,Occupational Therapist,7422892277,"Tromp, Ziemann and Grant" +Cecilius,Sully,csullyqj@mysql.com,csullyqj,Meukek,62-(638)624-8698,Quality Control Specialist,6934177193,Doyle Inc +Adelaida,Stickford,astickfordqk@washingtonpost.com,astickfordqk,Khoa,856-(931)334-2132,Account Coordinator,7872285312,"Dicki, Bailey and Ratke" +Rochelle,Reynish,rreynishql@indiatimes.com,rreynishql,Fāryāb,98-(957)306-8416,Media Manager IV,1676544003,Lang Inc +Odie,Ianniello,oiannielloqm@independent.co.uk,oiannielloqm,La Cumbre,54-(979)726-7040,Account Representative III,7068196918,"Bernhard, Rau and Marvin" +Haskel,Ladloe,hladloeqn@timesonline.co.uk,hladloeqn,George Town,1-(687)711-7923,Quality Control Specialist,5936963217,"Ryan, Parisian and Swaniawski" +Olympie,Vassall,ovassallqo@samsung.com,ovassallqo,Vannes,33-(222)237-4683,Media Manager II,8854580236,Koepp-Boehm +Noll,Beech,nbeechqp@plala.or.jp,nbeechqp,Bloemfontein,27-(804)795-7592,Food Chemist,4394656052,Purdy and Sons +Konstanze,Thon,kthonqq@google.ru,kthonqq,Tīrān,98-(846)964-8726,Payment Adjustment Coordinator,1904564429,Simonis and Sons +Leonid,Kerford,lkerfordqr@un.org,lkerfordqr,Dzüünbulag,976-(101)272-5436,Administrative Officer,2082237710,"Swaniawski, Steuber and Runte" +Reeva,Dyka,rdykaqs@geocities.com,rdykaqs,Mstów,48-(190)592-9280,Environmental Specialist,9030963425,Rippin-Waters +Galvin,Lumbley,glumbleyqt@reuters.com,glumbleyqt,Feodosiya,380-(562)472-4251,Chemical Engineer,0083583572,"Hilpert, Satterfield and Walker" +Chet,Spinozzi,cspinozziqu@marriott.com,cspinozziqu,Det Udom,66-(457)173-1407,Data Coordiator,7957694462,Bashirian LLC +Ryann,Wimlett,rwimlettqv@free.fr,rwimlettqv,Paniówki,48-(203)574-3233,Actuary,6548690974,Nienow and Sons +Craggie,McCotter,cmccotterqw@feedburner.com,cmccotterqw,Portela,351-(482)524-3475,Pharmacist,4298812022,Abernathy-Kuhic +Ulberto,Heifer,uheiferqx@yandex.ru,uheiferqx,Omaha,1-(402)346-5913,Software Engineer I,0187278784,Yundt LLC +Billie,Franchi,bfranchiqy@etsy.com,bfranchiqy,Yinping,86-(788)959-3511,Web Designer I,4035720887,Nolan LLC +Norbie,Goundsy,ngoundsyqz@fda.gov,ngoundsyqz,São José dos Campos,55-(914)752-8310,Senior Editor,9192798357,Feeney LLC +Barde,Emlen,bemlenr0@infoseek.co.jp,bemlenr0,Pétange,352-(762)627-9841,Software Consultant,2432326261,"Rice, Eichmann and Will" +Shelagh,Zemler,szemlerr1@mayoclinic.com,szemlerr1,Filiátes,30-(866)635-4243,Geological Engineer,3958946542,"Hansen, Bernier and Goldner" +Isidro,Ciani,icianir2@yahoo.co.jp,icianir2,Serednye,380-(288)355-3486,Tax Accountant,1506003982,Torp-Bogisich +Vivia,Lapworth,vlapworthr3@joomla.org,vlapworthr3,Malino,63-(291)269-3418,Environmental Specialist,0157700771,Jast-Kuhlman +Roshelle,Churn,rchurnr4@berkeley.edu,rchurnr4,Lingqiao,86-(997)692-6158,Geological Engineer,2603479822,Marquardt and Sons +Bentley,Vanshin,bvanshinr5@ehow.com,bvanshinr5,Stockholm,46-(653)768-6050,Information Systems Manager,7297467227,"King, Tillman and Nicolas" +Lois,Mynett,lmynettr6@reuters.com,lmynettr6,Nantes,33-(554)638-9803,Speech Pathologist,1603340408,Veum LLC +Charity,Krzyzowski,ckrzyzowskir7@archive.org,ckrzyzowskir7,Masebewa,62-(958)826-5880,Staff Scientist,4975412993,"Brakus, Gusikowski and Padberg" +Clemente,Pottage,cpottager8@census.gov,cpottager8,Tenggun Dajah,62-(506)558-9919,Associate Professor,6455213033,"Purdy, Vandervort and Douglas" +Kurt,Cowap,kcowapr9@jugem.jp,kcowapr9,Kutao,86-(358)991-3144,Nurse,0616313527,White-Goyette +Chrissy,Finey,cfineyra@irs.gov,cfineyra,Ningzhong,86-(138)301-0438,Professor,9107665083,Davis and Sons +Clarinda,Hallgate,challgaterb@linkedin.com,challgaterb,Zinder,227-(332)911-9324,Product Engineer,7179109576,"Lesch, Balistreri and Morissette" +Carmelle,Chatelain,cchatelainrc@woothemes.com,cchatelainrc,Monte Branco,351-(468)889-1359,Tax Accountant,6018619938,Adams-Harris +Erskine,Bonin,eboninrd@redcross.org,eboninrd,Sabang,63-(956)745-4358,Actuary,1793329427,"Farrell, White and Bednar" +Linnet,Castelot,lcastelotre@1688.com,lcastelotre,Jintun,86-(448)985-9715,Senior Sales Associate,6843609481,Pagac and Sons +Aurthur,Thomke,athomkerf@whitehouse.gov,athomkerf,Głuchów,48-(339)416-4557,Engineer I,7088789183,"Roob, Runolfsdottir and Leffler" +Donni,Salomon,dsalomonrg@japanpost.jp,dsalomonrg,Forninho,351-(549)953-6906,Account Executive,4908221146,"Wisozk, Greenholt and Hamill" +Skip,Edensor,sedensorrh@alexa.com,sedensorrh,Victoria,503-(808)383-0356,Project Manager,0126141614,Mayer-Mante +Albrecht,Ellam,aellamri@businessweek.com,aellamri,La Roche-sur-Yon,33-(857)717-9828,Actuary,4743554497,Parisian-Ankunding +Loutitia,Simson,lsimsonrj@plala.or.jp,lsimsonrj,Tamontaka,63-(423)893-7361,Assistant Media Planner,6240594598,Schamberger LLC +Ariel,Cockarill,acockarillrk@amazonaws.com,acockarillrk,Santa Quitéria,55-(584)271-7334,VP Sales,9593299637,"Lang, Bednar and Mayer" +Nonie,Paulton,npaultonrl@cbslocal.com,npaultonrl,Kladno,420-(149)126-3944,Senior Developer,7724518181,"Bruen, Murray and Kunde" +Yasmin,Rilston,yrilstonrm@gizmodo.com,yrilstonrm,Petoa,504-(697)889-4705,Environmental Specialist,9003612854,McKenzie and Sons +Izaak,Gowthrop,igowthroprn@webmd.com,igowthroprn,Ancasti,54-(334)952-0828,Account Executive,9924782984,Cartwright LLC +Jelene,Badman,jbadmanro@shinystat.com,jbadmanro,Asunción,595-(802)109-9845,Electrical Engineer,3501920857,"Cremin, Heaney and Morissette" +Staffard,Clausius,sclausiusrp@yellowbook.com,sclausiusrp,Sampao,63-(733)481-2381,Junior Executive,6139413206,Herzog-Beer +Lilia,Dalliwatr,ldalliwatrrq@deviantart.com,ldalliwatrrq,Hengshan,86-(225)596-7008,Operator,2989513345,Mante-Funk +Karlotta,Altamirano,kaltamiranorr@vistaprint.com,kaltamiranorr,Ajax,1-(705)315-7495,Legal Assistant,1030691320,Carroll Group