Instapage WordPress Plugin - Version 3.2.11

Version Description

(2019-11-27) = - Bugfix: Custom experience display issues on WP Engine hosting - Bugfix: Removing a PHP notice generated during the landing page display path

Download this release

Release Info

Developer marek@instapage.com
Plugin Icon 128x128 Instapage WordPress Plugin
Version 3.2.11
Comparing to
See all releases

Version 3.2.11

Files changed (58) hide show
  1. AjaxController.php +547 -0
  2. InstapageCmsPluginAjaxController.php +528 -0
  3. InstapageCmsPluginHelper.php +544 -0
  4. InstapageHelper.php +392 -0
  5. README.md +150 -0
  6. README.txt +191 -0
  7. assets/css/general.css +200 -0
  8. assets/css/mrwhite-reset.css +95 -0
  9. assets/css/mrwhite-ui-kit.css +5670 -0
  10. assets/js/InstapageCmsPluginAjax.js +39 -0
  11. assets/js/InstapageCmsPluginLang.js +19 -0
  12. assets/js/download.js +168 -0
  13. assets/js/dropdowns.js +19 -0
  14. assets/js/expand-collapse.js +23 -0
  15. assets/js/input.js +13 -0
  16. assets/js/jq.hoverintent.js +9 -0
  17. assets/js/jquery.tmpl.min.js +10 -0
  18. assets/js/knockout-no-conflict.js +11 -0
  19. assets/js/mrwhite.js +317 -0
  20. assets/js/ripple.js +37 -0
  21. assets/js/select2.min.js +3 -0
  22. assets/js/snack-bars.js +13 -0
  23. assets/js/tabs.js +44 -0
  24. assets/js/ui-kit-scripts.js +33 -0
  25. assets/lang/en-GB.js +18 -0
  26. connectors/InstapageCmsPluginConnector.php +403 -0
  27. connectors/InstapageCmsPluginDrupal7Connector.php +919 -0
  28. connectors/InstapageCmsPluginDrupal8Connector.php +785 -0
  29. connectors/InstapageCmsPluginWPConnector.php +1112 -0
  30. instapage.php +45 -0
  31. knockout/core/knockout-3.4.0.js +123 -0
  32. knockout/core/knockout.simpleGrid.3.0.js +94 -0
  33. knockout/view_models/InstapageCmsPluginEditModel.js +217 -0
  34. knockout/view_models/InstapageCmsPluginMasterModel.js +114 -0
  35. knockout/view_models/InstapageCmsPluginMessagesModel.js +39 -0
  36. knockout/view_models/InstapageCmsPluginPagedGridModel.js +101 -0
  37. knockout/view_models/InstapageCmsPluginSettingsModel.js +344 -0
  38. knockout/view_models/InstapageCmsPluginToolbarModel.js +92 -0
  39. license.txt +374 -0
  40. models/InstapageCmsPluginAPIModel.php +109 -0
  41. models/InstapageCmsPluginDBModel.php +248 -0
  42. models/InstapageCmsPluginDebugLogModel.php +188 -0
  43. models/InstapageCmsPluginPageModel.php +589 -0
  44. models/InstapageCmsPluginServicesModel.php +115 -0
  45. models/InstapageCmsPluginSubaccountModel.php +187 -0
  46. models/InstapageCmsPluginViewModel.php +174 -0
  47. modules/lpAjaxLoader/InstapageCmsPluginLPAjaxLoaderController.php +53 -0
  48. modules/lpAjaxLoader/view.php +45 -0
  49. templates/log.php +148 -0
  50. templates/log_options.php +27 -0
  51. templates/log_plugins.php +29 -0
  52. views/base.php +15 -0
  53. views/edit.php +42 -0
  54. views/landingPageAjaxLoader.php +40 -0
  55. views/listing.php +78 -0
  56. views/messages.php +16 -0
  57. views/settings.php +178 -0
  58. views/toolbar.php +24 -0
AjaxController.php ADDED
@@ -0,0 +1,547 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class AjaxController
3
+ {
4
+ private static $ajaxController = null;
5
+
6
+ public static function getInstance()
7
+ {
8
+ if( self::$ajaxController === null )
9
+ {
10
+ self::$ajaxController = new AjaxController();
11
+ }
12
+
13
+ return self::$ajaxController;
14
+ }
15
+
16
+ public function doAction( $action, $data = null )
17
+ {
18
+ InstapageHelper::writeDiagnostics( $action, 'AJAX Action');
19
+
20
+ if( !Connector::currentUserCanManage() )
21
+ {
22
+ echo InstapageHelper::formatJsonMessage( Connector::lang( 'You don\'t have permission to perform that action.' ), 'ERROR' );
23
+ exit;
24
+ }
25
+
26
+ switch( $action )
27
+ {
28
+ case 'loginUser':
29
+ $this->loginUser();
30
+ break;
31
+
32
+ case 'getApiTokens':
33
+ $this->getApiTokens();
34
+ break;
35
+
36
+ case 'connectSubAccounts':
37
+ $subaccount = SubaccountModel::getInstance();
38
+ $subaccount->setSubAccountsStatus( 'connect' );
39
+ break;
40
+
41
+ case 'disconnectSubAccounts':
42
+ $subaccount = SubaccountModel::getInstance();
43
+ $subaccount->setSubAccountsStatus( 'disconnect' );
44
+ break;
45
+
46
+ case 'disconnectAccountBoundSubaccounts':
47
+ $subaccount = SubaccountModel::getInstance();
48
+ $subaccount->disconnectAccountBoundSubaccounts();
49
+ break;
50
+
51
+ case 'getAccountBoundSubAccounts':
52
+ $subaccount = SubaccountModel::getInstance();
53
+ $subaccount->getAccountBoundSubAccounts();
54
+ break;
55
+
56
+ case 'updateOptions':
57
+ if( InstapageHelper::updateOptions( $data ) !== false )
58
+ {
59
+ echo InstapageHelper::formatJsonMessage( Connector::lang( 'Configuration updated' ), 'OK' );
60
+ }
61
+ else
62
+ {
63
+ echo InstapageHelper::formatJsonMessage( Connector::lang( 'There was an error during configuration save' ), 'ERROR' );
64
+ }
65
+ break;
66
+
67
+ case 'getOptions':
68
+ echo json_encode( InstapageHelper::getOptions() );
69
+ break;
70
+
71
+ case 'getLog':
72
+ $this->getLog();
73
+ break;
74
+
75
+ case 'clearLog':
76
+ $log = DebugLogModel::getInstance();
77
+ $log->clear();
78
+ echo InstapageHelper::formatJsonMessage( Connector::lang( 'Log cleared' ), 'OK' );
79
+ break;
80
+
81
+ case 'getMasterToken':
82
+ $this->getMasterToken();
83
+ break;
84
+
85
+ case 'loadListPages':
86
+ $this->loadListPages();
87
+ break;
88
+
89
+ case 'loadEditPage':
90
+ $this->loadEditPage();
91
+ break;
92
+
93
+ case 'getLandingPages':
94
+ $this->getLandingPages();
95
+ break;
96
+
97
+ case 'getStats':
98
+ $this->getStats();
99
+ break;
100
+
101
+ case 'publishPage':
102
+ $this->publishPage();
103
+ break;
104
+
105
+ case 'deletePage':
106
+ $this->deletePage();
107
+ break;
108
+
109
+ case 'loadSettings':
110
+ echo json_encode( (object) array(
111
+ 'status' => 'OK',
112
+ 'html' => InstapageHelper::loadTemplate( 'settings', false ),
113
+ 'initialData' => InstapageHelper::getOptions()
114
+ ) );
115
+ break;
116
+
117
+ case 'getProhibitedSlugs':
118
+ $data = Connector::getSelectedConnector()->getProhibitedSlugs();
119
+ echo json_encode( (object) array(
120
+ 'status' => 'OK',
121
+ 'data' => $data
122
+ ) );
123
+ break;
124
+
125
+ case 'validateToken':
126
+ $this->validateToken();
127
+ break;
128
+
129
+ case 'migrateDeprecatedData':
130
+ $data = Connector::getSelectedConnector()->getDeprecatedData();
131
+ $page = PageModel::getInstance();
132
+ $raport = $page->migrateDeprecatedData( $data );
133
+ $raport_str = implode( '<br />', $raport );
134
+ echo InstapageHelper::formatJsonMessage( $raport_str );
135
+ break;
136
+
137
+ default:
138
+ echo InstapageHelper::formatJsonMessage( Connector::lang( 'Unsupported AjaxController action' ), 'ERROR' );
139
+ }
140
+ }
141
+
142
+ private function loginUser()
143
+ {
144
+ $api = APIModel::getInstance();
145
+ $post = InstapageHelper::getPostData();
146
+ $email = InstapageHelper::getVar( $post->data->email, '' );
147
+ $password = InstapageHelper::getVar( $post->data->password, '' );
148
+ $response = json_decode( $api->authorise( $email, $password ) );
149
+
150
+ if( !InstapageHelper::checkResponse( $response, null, false ) || !$response->success )
151
+ {
152
+ $message = InstapageHelper::getVar( $response->message, '' );
153
+ echo InstapageHelper::formatJsonMessage( $message, 'ERROR' );
154
+ return false;
155
+ }
156
+ else
157
+ {
158
+ echo json_encode( (object) array(
159
+ 'status' => 'OK',
160
+ 'data' => (object) $response->data
161
+ ) );
162
+ }
163
+ }
164
+
165
+ private function validateToken()
166
+ {
167
+ $api = APIModel::getInstance();
168
+ $post = InstapageHelper::getPostData();
169
+ $token = InstapageHelper::getVar($post->data->token, null);
170
+ $headers = array( 'accountkeys' => InstapageHelper::getAuthHeader( array( $token ) ) );
171
+ $response = json_decode( $api->apiCall( 'page/get-sub-accounts-list', null, $headers ) );
172
+ $sub_account = @InstapageHelper::getVar( $response->data, null );
173
+
174
+ if( !InstapageHelper::checkResponse( $response, null, false) || !$response->success || count( $sub_account ) == 0 )
175
+ {
176
+ echo json_encode( (object) array(
177
+ 'status' => 'OK',
178
+ 'valid' => false
179
+ ) );
180
+ }
181
+ else
182
+ {
183
+ echo json_encode( (object) array(
184
+ 'status' => 'OK',
185
+ 'valid' => true
186
+ ) );
187
+ }
188
+ }
189
+
190
+ private function getLog()
191
+ {
192
+ $log = DebugLogModel::getInstance();
193
+ $sitename_sanitized = Connector::getSitename( true ) ;
194
+ try
195
+ {
196
+ $data = $log->getLogHTML();
197
+ echo json_encode( (object) array(
198
+ 'status' => 'OK',
199
+ 'data' => $data,
200
+ 'sitename' => $sitename_sanitized
201
+ ) );
202
+ }
203
+ catch( Exception $e )
204
+ {
205
+ echo InstapageHelper::formatJsonMessage( $e->getMessage(), 'ERROR' );
206
+ }
207
+ }
208
+
209
+ private function getApiTokens()
210
+ {
211
+ $subaccount = SubaccountModel::getInstance();
212
+ $tokens = $subaccount->getAllTokens();
213
+ echo json_encode( (object) array(
214
+ 'status' => 'OK',
215
+ 'data' => $tokens
216
+ ) );
217
+ }
218
+
219
+ private function loadEditPage()
220
+ {
221
+ $api = APIModel::getInstance();
222
+ $subaccount = SubaccountModel::getInstance();
223
+ $post = InstapageHelper::getPostData();
224
+ InstapageHelper::writeDiagnostics( $post, 'Edit page POST');
225
+ $tokens = InstapageHelper::getVar( $post->apiTokens, false );
226
+
227
+ if( !$tokens )
228
+ {
229
+ $tokens = $subaccount->getAllTokens();
230
+ }
231
+
232
+ $page_data = null;
233
+ $sub_accounts = null;
234
+ $data = array();
235
+
236
+ if( isset( $post->data->id ) )
237
+ {
238
+ $page_data = $post->data;
239
+ $data[ 'pages' ] = array( $post->data->instapage_id );
240
+
241
+ }
242
+
243
+ $headers = array( 'accountkeys' => InstapageHelper::getAuthHeader( $tokens ) );
244
+ $response = json_decode( $api->apiCall( 'page/get-sub-accounts-list', $data, $headers ) );
245
+
246
+ if( InstapageHelper::checkResponse( $response ) )
247
+ {
248
+ $sub_accounts = $response->data;
249
+ }
250
+ else
251
+ {
252
+ return false;
253
+ }
254
+
255
+ $initialData = array( 'subAccounts' => $sub_accounts, 'page' => $page_data );
256
+ InstapageHelper::writeDiagnostics( $initialData, 'Edit page initialData');
257
+
258
+ echo json_encode( (object) array(
259
+ 'status' => 'OK',
260
+ 'html' => InstapageHelper::loadTemplate( 'edit', false ),
261
+ 'data' => (object) $initialData
262
+ ) );
263
+ }
264
+
265
+ private function loadListPages()
266
+ {
267
+ $request_limit = 300;
268
+ $post = InstapageHelper::getPostData();
269
+ $page = PageModel::getInstance();
270
+ InstapageHelper::writeDiagnostics( $post, 'List page POST');
271
+ $api = APIModel::getInstance();
272
+ $subaccount = SubaccountModel::getInstance();
273
+ $local_pages_array = $page->getAll( array( 'id', 'instapage_id', 'slug', 'type', 'stats_cache', 'enterprise_url' ) );
274
+
275
+ //WP Legacy code - automatic migration
276
+ $automatic_migration = InstapageHelper::getMetadata( 'automatic_migration', false );
277
+
278
+ if( empty( $automatic_migration ) && !count( $local_pages_array ) && Connector::isWP() && Connector::getSelectedConnector()->legacyArePagesPresent() )
279
+ {
280
+ $data = Connector::getSelectedConnector()->getDeprecatedData();
281
+ $page = PageModel::getInstance();
282
+ $page->migrateDeprecatedData( $data );
283
+ $local_pages_array = $page->getAll( array( 'id', 'instapage_id', 'slug', 'type', 'stats_cache', 'enterprise_url' ) );
284
+ InstapageHelper::updateMetadata( 'automatic_migration', time() );
285
+ }
286
+
287
+ $pages = array();
288
+
289
+ foreach( $local_pages_array as &$page_object )
290
+ {
291
+ $page_object->stats_cache = json_decode($page_object->stats_cache);
292
+ $pages[] = $page_object->instapage_id;
293
+ }
294
+
295
+ $tokens = InstapageHelper::getVar( $post->apiTokens, false );
296
+
297
+ if( !$tokens )
298
+ {
299
+ $tokens = $subaccount->getAllTokens();
300
+ }
301
+
302
+ if( !count( $tokens ) )
303
+ {
304
+ echo json_encode( (object) array(
305
+ 'status' => 'OK',
306
+ 'html' => InstapageHelper::loadTemplate( 'listing', false ),
307
+ 'initialData' => $local_pages_array
308
+ ) );
309
+
310
+ return true;
311
+ }
312
+
313
+
314
+ $headers = array( 'accountkeys' => InstapageHelper::getAuthHeader( $tokens ) );
315
+ $responses = array();
316
+ $success = true;
317
+
318
+ for( $i = 0; $i * $request_limit < count( $pages ); ++$i )
319
+ {
320
+ $data_slice = array_slice( $pages, $i * $request_limit, $request_limit );
321
+ $data = array( 'pages' => $data_slice );
322
+ $response_json = $api->apiCall( 'page/list', $data, $headers, 'GET' );
323
+ $response = json_decode( $response_json );
324
+
325
+ if( InstapageHelper::checkResponse( $response ) )
326
+ {
327
+ $responses[] = $response->data;
328
+ }
329
+ else
330
+ {
331
+ $success = false;
332
+ break;
333
+ }
334
+ }
335
+
336
+ if( $success )
337
+ {
338
+ $merged_response = array();
339
+
340
+ foreach( $responses as $r )
341
+ {
342
+ $merged_response = array_merge( $merged_response, $r );
343
+ }
344
+
345
+ $page->mergeListPagesResults( $local_pages_array, $merged_response );
346
+ InstapageHelper::writeDiagnostics( $local_pages_array, 'List page array');
347
+ echo json_encode( (object) array(
348
+ 'status' => 'OK',
349
+ 'html' => InstapageHelper::loadTemplate( 'listing', false ),
350
+ 'initialData' => $local_pages_array
351
+ ) );
352
+ }
353
+ else
354
+ {
355
+ return false;
356
+ }
357
+ }
358
+
359
+ private function getLandingPages()
360
+ {
361
+ $api = APIModel::getInstance();
362
+ $post = InstapageHelper::getPostData();
363
+ $tokens = array( $post->data->subAccountToken );
364
+ $headers = array( 'accountkeys' => InstapageHelper::getAuthHeader( $tokens ) );
365
+ $response_json = $api->apiCall( 'page/list', null, $headers );
366
+ $response =json_decode( $response_json );
367
+ $page = PageModel::getInstance();
368
+ $published_pages = $page->getAll( array( 'instapage_id' ) );
369
+ $self_instapage_id = @InstapageHelper::getVar( $post->data->selfInstapageId, null );
370
+
371
+ if( InstapageHelper::checkResponse( $response ) )
372
+ {
373
+ if( is_array( $response->data ) )
374
+ {
375
+ foreach( $response->data as $key => $returned_page )
376
+ {
377
+ foreach( $published_pages as $published_page )
378
+ {
379
+ if( $returned_page->id != $self_instapage_id && $returned_page->id == $published_page->instapage_id )
380
+ {
381
+ unset( $response->data[ $key ] );
382
+ break;
383
+ }
384
+ }
385
+ }
386
+
387
+ $response->data = array_values( $response->data );
388
+ }
389
+ else
390
+ {
391
+ $response->data = array();
392
+ }
393
+
394
+ echo json_encode( (object) array(
395
+ 'status' => 'OK',
396
+ 'data' => $response->data
397
+ ) );
398
+ }
399
+ else
400
+ {
401
+ return false;
402
+ }
403
+ }
404
+
405
+ private function getStats()
406
+ {
407
+ $post = InstapageHelper::getPostData();
408
+ $page = PageModel::getInstance();
409
+ $api = APIModel::getInstance();
410
+ $subaccount = SubaccountModel::getInstance();
411
+ $pages = InstapageHelper::getVar( $post->data->pages, array() );
412
+
413
+ if( !count( $pages ) )
414
+ {
415
+ InstapageHelper::writeDiagnostics( 'Stats cond', 'No pages in request' );
416
+ echo json_encode( (object) array(
417
+ 'status' => 'OK',
418
+ 'data' => array()
419
+ ) );
420
+
421
+ return true;
422
+ }
423
+
424
+ $cached_stats = $page->getPageStatsCache( $pages );
425
+ InstapageHelper::writeDiagnostics( $cached_stats, 'Cached stats');
426
+ $pages_without_stats = array();
427
+
428
+ foreach( $pages as $instapage_id )
429
+ {
430
+ if( !isset( $cached_stats[ $instapage_id ] ) )
431
+ {
432
+ $pages_without_stats[] = $instapage_id;
433
+ }
434
+ }
435
+
436
+ if( empty( $pages_without_stats ) )
437
+ {
438
+ echo json_encode( (object) array(
439
+ 'status' => 'OK',
440
+ 'data' => $cached_stats
441
+ ) );
442
+
443
+ return true;
444
+ }
445
+
446
+ $tokens = InstapageHelper::getVar( $post->apiTokens, false );
447
+
448
+ if( !$tokens )
449
+ {
450
+ $tokens = $subaccount->getAllTokens();
451
+ }
452
+
453
+ $headers = array( 'accountkeys' => InstapageHelper::getAuthHeader( $tokens ) );
454
+ $data = array( 'pages' => $pages_without_stats );
455
+ $response_json = $api->apiCall( 'page/stats', $data, $headers );
456
+ $response =json_decode( $response_json );
457
+
458
+ if( InstapageHelper::checkResponse( $response ) )
459
+ {
460
+ $stats = (array) InstapageHelper::getVar( $response->data, array() );
461
+ $page->savePageStatsCache( $stats );
462
+
463
+ if( count( $stats ) )
464
+ {
465
+ $stats = array_merge( $cached_stats, $stats );
466
+ }
467
+ else
468
+ {
469
+ $stats = $cached_stats;
470
+ }
471
+
472
+ echo json_encode( (object) array(
473
+ 'status' => 'OK',
474
+ 'data' => $stats
475
+ ) );
476
+ }
477
+ else
478
+ {
479
+ return false;
480
+ }
481
+ }
482
+
483
+ private function publishPage()
484
+ {
485
+ $page = PageModel::getInstance();
486
+ $post = InstapageHelper::getPostData();
487
+ $data = $post->data;
488
+
489
+ echo $page->publishPage( $data );
490
+ }
491
+
492
+ private function deletePage()
493
+ {
494
+ $page = PageModel::getInstance();
495
+ $api = APIModel::getInstance();
496
+ $subaccount = SubaccountModel::getInstance();
497
+ $post = InstapageHelper::getPostData();
498
+ $result = $page->get( $post->data->id, array( 'instapage_id' ) );
499
+ $instapage_id = $result->instapage_id;
500
+ $tokens = InstapageHelper::getVar( $post->apiTokens, false );
501
+
502
+ if( !$tokens )
503
+ {
504
+ $tokens = $subaccount->getAllTokens();
505
+ }
506
+
507
+ $data = array(
508
+ 'page' => $instapage_id,
509
+ 'url' => '',
510
+ 'publish' => 0
511
+ );
512
+ $headers = array( 'accountkeys' => InstapageHelper::getAuthHeader( $tokens ) );
513
+ $response = json_decode( $api->apiCall( 'page/edit', $data, $headers ) );
514
+
515
+ $message = '';
516
+
517
+ if( !InstapageHelper::checkResponse( $response, null, false) || !$response->success )
518
+ {
519
+ $message .= Connector::lang( 'Page that you are removing (Instapage ID: %s) doesn\'t exist in your Instapage application\'s dashboard. It could have been deleted from app or created by another user. Deleting this page won\'t affect Instapage application\'s dashboard.', $instapage_id );
520
+
521
+ if( isset( $response->message ) && $response->message !== '' )
522
+ {
523
+ $message .= Connector::lang( ' Instapage app response: ' . $response->message );
524
+ }
525
+ }
526
+
527
+ if( isset( $post->data->id ) && $page->delete( $post->data->id ) )
528
+ {
529
+ if( $message )
530
+ {
531
+ echo InstapageHelper::formatJsonMessage( $message );
532
+ }
533
+ else
534
+ {
535
+ echo InstapageHelper::formatJsonMessage( Connector::lang( 'Page deleted successfully.' ) );
536
+ }
537
+
538
+ return true;
539
+ }
540
+ else
541
+ {
542
+ echo InstapageHelper::formatJsonMessage( Connector::lang( 'There was a database error during page delete process.' ), 'ERROR' );
543
+
544
+ return false;
545
+ }
546
+ }
547
+ }
InstapageCmsPluginAjaxController.php ADDED
@@ -0,0 +1,528 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Main controller for AJAX actions. Results are returned as encoded JSON objects. Data for actions are stored in $_POST['data'] table.
5
+ */
6
+ class InstapageCmsPluginAjaxController {
7
+
8
+ /**
9
+ * @var object Controller object for Singleton implementation.
10
+ */
11
+ private static $ajaxController = null;
12
+
13
+ /**
14
+ * Gets an instance of the object.
15
+ */
16
+ public static function getInstance() {
17
+
18
+ if (self::$ajaxController === null) {
19
+ self::$ajaxController = new InstapageCmsPluginAjaxController();
20
+ }
21
+
22
+ return self::$ajaxController;
23
+ }
24
+
25
+ /**
26
+ * Executes an action set in the request.
27
+ *
28
+ * @param string $action Action to execute.
29
+ * @param mixed $data Data passed to action.
30
+ */
31
+ public function doAction($action, $data = null) {
32
+ InstapageCmsPluginHelper::writeDiagnostics($action, 'AJAX Action');
33
+
34
+ if (!InstapageCmsPluginConnector::currentUserCanManage()) {
35
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('You don\'t have permission to perform that action.'), 'ERROR');
36
+ exit;
37
+ }
38
+
39
+ switch ($action) {
40
+ case 'loginUser':
41
+ $this->loginUser();
42
+ break;
43
+
44
+ case 'getApiTokens':
45
+ $this->getApiTokens();
46
+ break;
47
+
48
+ case 'connectSubAccounts':
49
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
50
+ $subaccount->setSubAccountsStatus('connect');
51
+ break;
52
+
53
+ case 'disconnectSubAccounts':
54
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
55
+ $subaccount->setSubAccountsStatus('disconnect');
56
+ break;
57
+
58
+ case 'disconnectAccountBoundSubaccounts':
59
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
60
+ $subaccount->disconnectAccountBoundSubaccounts();
61
+ break;
62
+
63
+ case 'getAccountBoundSubAccounts':
64
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
65
+ $subaccount->getAccountBoundSubAccounts();
66
+ break;
67
+
68
+ case 'updateOptions':
69
+ if (InstapageCmsPluginHelper::updateOptions($data) !== false) {
70
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('Configuration updated'), 'OK');
71
+ } else {
72
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('There was an error during configuration save'), 'ERROR');
73
+ }
74
+ break;
75
+
76
+ case 'getOptions':
77
+ echo json_encode((object) array(
78
+ 'status' => 'OK',
79
+ 'data' => InstapageCmsPluginHelper::getOptions()
80
+ ));
81
+ break;
82
+
83
+ case 'getLog':
84
+ $this->getLog();
85
+ break;
86
+
87
+ case 'clearLog':
88
+ $log = InstapageCmsPluginDebugLogModel::getInstance();
89
+ $log->clear();
90
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('Log cleared'), 'OK');
91
+ break;
92
+
93
+ case 'getMasterToken':
94
+ $this->getMasterToken();
95
+ break;
96
+
97
+ case 'loadListPages':
98
+ $this->loadListPages();
99
+ break;
100
+
101
+ case 'loadEditPage':
102
+ $this->loadEditPage();
103
+ break;
104
+
105
+ case 'getLandingPages':
106
+ $this->getLandingPages();
107
+ break;
108
+
109
+ case 'getStats':
110
+ $this->getStats();
111
+ break;
112
+
113
+ case 'publishPage':
114
+ $this->publishPage();
115
+ break;
116
+
117
+ case 'deletePage':
118
+ $this->deletePage();
119
+ break;
120
+
121
+ case 'loadSettings':
122
+ echo json_encode((object) array(
123
+ 'status' => 'OK',
124
+ 'html' => InstapageCmsPluginHelper::loadTemplate('settings', false),
125
+ 'initialData' => InstapageCmsPluginHelper::getOptions()
126
+ ));
127
+ break;
128
+
129
+ case 'getProhibitedSlugs':
130
+ $data = InstapageCmsPluginConnector::getSelectedConnector()->getProhibitedSlugs();
131
+ echo json_encode((object) array(
132
+ 'status' => 'OK',
133
+ 'data' => $data
134
+ ));
135
+ break;
136
+
137
+ case 'isProhibitedSlug':
138
+ $data = InstapageCmsPluginConnector::getSelectedConnector()->isProhibitedSlug($data);
139
+ echo json_encode((object) array(
140
+ 'status' => 'OK',
141
+ 'data' => $data
142
+ ));
143
+ break;
144
+
145
+ case 'validateToken':
146
+ $this->validateToken();
147
+ break;
148
+
149
+ case 'migrateDeprecatedData':
150
+ $data = InstapageCmsPluginConnector::getSelectedConnector()->getDeprecatedData();
151
+ $page = InstapageCmsPluginPageModel::getInstance();
152
+ $raport = $page->migrateDeprecatedData($data);
153
+ $raportStr = implode('<br />', $raport);
154
+ echo InstapageCmsPluginHelper::formatJsonMessage($raportStr);
155
+ break;
156
+
157
+ default:
158
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('Unsupported InstapageCmsPluginAjaxController action'), 'ERROR');
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Performs login by email and password in Instapage APP.
164
+ */
165
+ private function loginUser() {
166
+ $api = InstapageCmsPluginAPIModel::getInstance();
167
+ $post = InstapageCmsPluginHelper::getPostData();
168
+ $email = urldecode(InstapageCmsPluginHelper::getVar($post->data->email, ''));
169
+ $password = urldecode(InstapageCmsPluginHelper::getVar($post->data->password, ''));
170
+ $response = json_decode($api->authorise($email, $password));
171
+
172
+ if (!InstapageCmsPluginHelper::checkResponse($response, null, false) || !$response->success) {
173
+ $message = InstapageCmsPluginHelper::getVar($response->message, '');
174
+ echo InstapageCmsPluginHelper::formatJsonMessage($message, 'ERROR');
175
+
176
+ return false;
177
+ } else {
178
+ echo json_encode((object) array(
179
+ 'status' => 'OK',
180
+ 'data' => (object) $response->data
181
+ ));
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Validates tokens stored in the DB.
187
+ */
188
+ private function validateToken() {
189
+ $api = InstapageCmsPluginAPIModel::getInstance();
190
+ $post = InstapageCmsPluginHelper::getPostData();
191
+ $token = InstapageCmsPluginHelper::getVar($post->data->token, null);
192
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader(array($token)));
193
+ $response = json_decode($api->apiCall('page/get-sub-accounts-list', null, $headers));
194
+ $subAccount = @InstapageCmsPluginHelper::getVar($response->data, null);
195
+
196
+ if (!InstapageCmsPluginHelper::checkResponse($response, null, false) || !$response->success || count($subAccount) == 0) {
197
+ echo json_encode((object) array(
198
+ 'status' => 'OK',
199
+ 'valid' => false
200
+ ));
201
+ } else {
202
+ echo json_encode((object) array(
203
+ 'status' => 'OK',
204
+ 'valid' => true
205
+ ));
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Gets the debug log stored in the DB.
211
+ */
212
+ private function getLog() {
213
+ $log = InstapageCmsPluginDebugLogModel::getInstance();
214
+ $sitenameSanitized = InstapageCmsPluginConnector::getSitename(true);
215
+
216
+ try {
217
+ $data = $log->getLogHTML();
218
+ echo json_encode((object) array(
219
+ 'status' => 'OK',
220
+ 'data' => $data,
221
+ 'sitename' => $sitenameSanitized
222
+ ));
223
+ } catch (Exception $e) {
224
+ echo InstapageCmsPluginHelper::formatJsonMessage($e->getMessage(), 'ERROR');
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Gets the API tokens stored in the DB.
230
+ */
231
+ private function getApiTokens() {
232
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
233
+ $tokens = $subaccount->getAllTokens();
234
+ echo json_encode((object) array(
235
+ 'status' => 'OK',
236
+ 'data' => $tokens
237
+ ));
238
+ }
239
+
240
+
241
+ /**
242
+ * Loads edit page.
243
+ */
244
+ private function loadEditPage() {
245
+ $api = InstapageCmsPluginAPIModel::getInstance();
246
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
247
+ $post = InstapageCmsPluginHelper::getPostData();
248
+ InstapageCmsPluginHelper::writeDiagnostics($post, 'Edit page POST');
249
+ $tokens = InstapageCmsPluginHelper::getVar($post->apiTokens, false);
250
+
251
+ if (!$tokens) {
252
+ $tokens = $subaccount->getAllTokens();
253
+ }
254
+
255
+ $pageData = null;
256
+ $subAccounts = null;
257
+ $data = array();
258
+
259
+ if (isset($post->data->id)) {
260
+ $pageData = $post->data;
261
+ $data['pages'] = array($post->data->instapage_id);
262
+ }
263
+
264
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
265
+ $response = json_decode($api->apiCall('page/get-sub-accounts-list', $data, $headers));
266
+
267
+ if (InstapageCmsPluginHelper::checkResponse($response)) {
268
+ $subAccounts = $response->data;
269
+ } else {
270
+ return false;
271
+ }
272
+
273
+ $initialData = array('subAccounts' => $subAccounts, 'page' => $pageData);
274
+ InstapageCmsPluginHelper::writeDiagnostics($initialData, 'Edit page initialData');
275
+
276
+ echo json_encode((object) array(
277
+ 'status' => 'OK',
278
+ 'html' => InstapageCmsPluginHelper::loadTemplate('edit', false),
279
+ 'data' => (object) $initialData
280
+ ));
281
+ }
282
+
283
+ /**
284
+ * Loads listing page.
285
+ */
286
+ private function loadListPages() {
287
+ $requestLimit = 100;
288
+ $post = InstapageCmsPluginHelper::getPostData();
289
+ $page = InstapageCmsPluginPageModel::getInstance();
290
+ InstapageCmsPluginHelper::writeDiagnostics($post, 'List page POST');
291
+ $api = InstapageCmsPluginAPIModel::getInstance();
292
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
293
+ $localPagesArray = $page->getAll(array('id', 'instapage_id', 'slug', 'type', 'stats_cache', 'enterprise_url'));
294
+
295
+ // WP Legacy code - automatic migration.
296
+ $automaticMigration = InstapageCmsPluginHelper::getMetadata('automatic_migration', false);
297
+
298
+ if (empty($automaticMigration) && !count($localPagesArray) && InstapageCmsPluginConnector::isWP() && InstapageCmsPluginConnector::getSelectedConnector()->legacyArePagesPresent()) {
299
+ $data = InstapageCmsPluginConnector::getSelectedConnector()->getDeprecatedData();
300
+ $page = InstapageCmsPluginPageModel::getInstance();
301
+ $page->migrateDeprecatedData($data);
302
+ $localPagesArray = $page->getAll(array('id', 'instapage_id', 'slug', 'type', 'stats_cache', 'enterprise_url'));
303
+ InstapageCmsPluginHelper::updateMetadata('automatic_migration', time());
304
+ }
305
+
306
+ $pages = array();
307
+
308
+ foreach ($localPagesArray as &$pageObject) {
309
+ $pageObject->stats_cache = json_decode($pageObject->stats_cache);
310
+ $pages[] = $pageObject->instapage_id;
311
+ }
312
+
313
+ $tokens = InstapageCmsPluginHelper::getVar($post->apiTokens, false);
314
+
315
+ if (!$tokens) {
316
+ $tokens = $subaccount->getAllTokens();
317
+ }
318
+
319
+ if (!count($tokens)) {
320
+ echo json_encode((object) array(
321
+ 'status' => 'OK',
322
+ 'html' => InstapageCmsPluginHelper::loadTemplate('listing', false),
323
+ 'initialData' => $localPagesArray
324
+ ));
325
+
326
+ return true;
327
+ }
328
+
329
+
330
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
331
+ $responses = array();
332
+
333
+ for ($i = 0; $i * $requestLimit < count($pages); ++$i) {
334
+ $dataSlice = array_slice($pages, $i * $requestLimit, $requestLimit);
335
+ $data = array('pages' => $dataSlice);
336
+ $responseJson = $api->apiCall('page/list', $data, $headers, 'GET');
337
+ $response = json_decode($responseJson);
338
+
339
+ if (InstapageCmsPluginHelper::checkResponse($response) && isset($response->data) && is_array($response->data)) {
340
+ $responses[] = $response->data;
341
+ } else {
342
+ return false;
343
+ }
344
+ }
345
+
346
+ $mergedResponse = array();
347
+
348
+ foreach ($responses as $r) {
349
+ $mergedResponse = array_merge($mergedResponse, $r);
350
+ }
351
+
352
+ $page->mergeListPagesResults($localPagesArray, $mergedResponse);
353
+ InstapageCmsPluginHelper::writeDiagnostics($localPagesArray, 'List page array');
354
+ echo json_encode((object) array(
355
+ 'status' => 'OK',
356
+ 'html' => InstapageCmsPluginHelper::loadTemplate('listing', false),
357
+ 'initialData' => $localPagesArray
358
+ ));
359
+ }
360
+
361
+ /**
362
+ * Gets the landing pages stored in the DB.
363
+ */
364
+ private function getLandingPages() {
365
+ $api = InstapageCmsPluginAPIModel::getInstance();
366
+ $post = InstapageCmsPluginHelper::getPostData();
367
+ $tokens = array($post->data->subAccountToken);
368
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
369
+ $responseJson = $api->apiCall('page/list', null, $headers);
370
+ $response = json_decode($responseJson);
371
+ $page = InstapageCmsPluginPageModel::getInstance();
372
+ $publishedPages = $page->getAll(array('instapage_id'));
373
+ $selfInstapageId = @InstapageCmsPluginHelper::getVar($post->data->selfInstapageId, null);
374
+
375
+ if (InstapageCmsPluginHelper::checkResponse($response)) {
376
+ if (is_array($response->data)) {
377
+ foreach ($response->data as $key => $returnedPage) {
378
+ foreach ($publishedPages as $published_page) {
379
+ if ($returnedPage->id != $selfInstapageId && $returnedPage->id == $published_page->instapage_id) {
380
+ unset($response->data[$key]);
381
+ break;
382
+ }
383
+ }
384
+ }
385
+
386
+ $response->data = array_values($response->data);
387
+ } else {
388
+ $response->data = array();
389
+ }
390
+
391
+ echo json_encode((object) array(
392
+ 'status' => 'OK',
393
+ 'data' => $response->data
394
+ ));
395
+ } else {
396
+ return false;
397
+ }
398
+ }
399
+
400
+ /**
401
+ * Gets the stats of landing pages from local cache or from app, if cache is not present / invalid.
402
+ */
403
+ private function getStats() {
404
+ $post = InstapageCmsPluginHelper::getPostData();
405
+ $page = InstapageCmsPluginPageModel::getInstance();
406
+ $api = InstapageCmsPluginAPIModel::getInstance();
407
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
408
+ $pages = InstapageCmsPluginHelper::getVar($post->data->pages, array());
409
+
410
+ if (!count($pages)) {
411
+ InstapageCmsPluginHelper::writeDiagnostics('Stats cond', 'No pages in request');
412
+ echo json_encode((object) array(
413
+ 'status' => 'OK',
414
+ 'data' => array()
415
+ ));
416
+
417
+ return true;
418
+ }
419
+
420
+ $cachedStats = $page->getPageStatsCache($pages);
421
+ InstapageCmsPluginHelper::writeDiagnostics($cachedStats, 'Cached stats');
422
+ $pagesWithoutStats = array();
423
+
424
+ foreach ($pages as $instapageId) {
425
+ if (!isset($cachedStats[$instapageId])) {
426
+ $pagesWithoutStats[] = $instapageId;
427
+ }
428
+ }
429
+
430
+ if (empty($pagesWithoutStats)) {
431
+ echo json_encode((object) array(
432
+ 'status' => 'OK',
433
+ 'data' => $cachedStats
434
+ ));
435
+
436
+ return true;
437
+ }
438
+
439
+ $tokens = InstapageCmsPluginHelper::getVar($post->apiTokens, false);
440
+
441
+ if (!$tokens) {
442
+ $tokens = $subaccount->getAllTokens();
443
+ }
444
+
445
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
446
+ $data = array('pages' => $pagesWithoutStats);
447
+ $responseJson = $api->apiCall('page/stats', $data, $headers);
448
+ $response = json_decode($responseJson);
449
+
450
+ if (InstapageCmsPluginHelper::checkResponse($response)) {
451
+ $stats = (array) InstapageCmsPluginHelper::getVar($response->data, array());
452
+ $page->savePageStatsCache($stats);
453
+
454
+ if (count($stats)) {
455
+ $stats = array_merge($cachedStats, $stats);
456
+ } else {
457
+ $stats = $cachedStats;
458
+ }
459
+
460
+ echo json_encode((object) array(
461
+ 'status' => 'OK',
462
+ 'data' => $stats
463
+ ));
464
+ } else {
465
+ return false;
466
+ }
467
+ }
468
+
469
+ /**
470
+ * Gathers data for 'publish' request.
471
+ */
472
+ private function publishPage() {
473
+ $page = InstapageCmsPluginPageModel::getInstance();
474
+ $post = InstapageCmsPluginHelper::getPostData();
475
+ $data = $post->data;
476
+
477
+ echo $page->publishPage($data);
478
+ }
479
+
480
+ /**
481
+ * Deletes a page from DB.
482
+ */
483
+ private function deletePage() {
484
+ $page = InstapageCmsPluginPageModel::getInstance();
485
+ $api = InstapageCmsPluginAPIModel::getInstance();
486
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
487
+ $post = InstapageCmsPluginHelper::getPostData();
488
+ $result = $page->get($post->data->id, array('instapage_id'));
489
+ $instapageId = $result->instapage_id;
490
+ $tokens = InstapageCmsPluginHelper::getVar($post->apiTokens, false);
491
+
492
+ if (!$tokens) {
493
+ $tokens = $subaccount->getAllTokens();
494
+ }
495
+
496
+ $data = array(
497
+ 'page' => $instapageId,
498
+ 'url' => '',
499
+ 'publish' => 0
500
+ );
501
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
502
+ $response = json_decode($api->apiCall('page/edit', $data, $headers));
503
+
504
+ $message = '';
505
+
506
+ if (!InstapageCmsPluginHelper::checkResponse($response, null, false) || !$response->success) {
507
+ $message .= InstapageCmsPluginConnector::lang('Page that you are removing (Instapage ID: %s) doesn\'t exist in your Instapage application\'s dashboard. It could have been deleted from app or created by another user. Deleting this page won\'t affect Instapage application\'s dashboard.', $instapageId);
508
+
509
+ if (isset($response->message) && $response->message !== '') {
510
+ $message .= InstapageCmsPluginConnector::lang(' Instapage app response: ' . $response->message);
511
+ }
512
+ }
513
+
514
+ if (isset($post->data->id) && $page->delete($post->data->id)) {
515
+ if ($message) {
516
+ echo InstapageCmsPluginHelper::formatJsonMessage($message);
517
+ } else {
518
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('Page deleted successfully.'));
519
+ }
520
+
521
+ return true;
522
+ } else {
523
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('There was a database error during page delete process.'), 'ERROR');
524
+
525
+ return false;
526
+ }
527
+ }
528
+ }
InstapageCmsPluginHelper.php ADDED
@@ -0,0 +1,544 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper containing commonly used static functions.
5
+ */
6
+ class InstapageCmsPluginHelper {
7
+
8
+ /**
9
+ * Loads content of a given template and prints it or returns it as a string.
10
+ *
11
+ * @param string $tmpl Name of the template to load.
12
+ * @param bool $print If set to true, content of the template will be printed to stdio. In other case it will be returned. Default: true.
13
+ *
14
+ * @throws \Exception if template file is not found.
15
+ *
16
+ * @return string|void Content of the template as a string or void, if print === true.
17
+ */
18
+ public static function loadTemplate($tmpl, $print = true) {
19
+ $templateFile = INSTAPAGE_PLUGIN_PATH . '/views/' . $tmpl . '.php';
20
+
21
+ if (file_exists($templateFile)) {
22
+ if (!$print) {
23
+ ob_start();
24
+ }
25
+
26
+ require($templateFile);
27
+
28
+ if (!$print) {
29
+ $contents = ob_get_contents();
30
+ ob_end_clean();
31
+
32
+ return $contents;
33
+ }
34
+ } else {
35
+ throw new Exception(InstapageCmsPluginConnector::lang('Template file (%s) not found', $templateFile));
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Loads 'messages' template to initiate a container for plugin system messages.
41
+ */
42
+ public static function initMessagesSystem() {
43
+ self::loadTemplate('messages');
44
+ }
45
+
46
+ /**
47
+ * Returns a string representation of Instapage icon in SVG format.
48
+ *
49
+ * @return string string representation of SVG icon
50
+ */
51
+ public static function getMenuIcon() {
52
+ return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTUiIGhlaWdodD0iMTUuOTY5IiB2aWV3Qm94PSIwIDAgMTUgMTUuOTY5Ij4NCiAgPGRlZnM+DQogICAgPHN0eWxlPg0KICAgICAgLmNscy0xIHsNCiAgICAgICAgZmlsbDogI2ZmZjsNCiAgICAgICAgZmlsbC1ydWxlOiBldmVub2RkOw0KICAgICAgfQ0KICAgIDwvc3R5bGU+DQogIDwvZGVmcz4NCiAgPHBhdGggaWQ9Il8xNi1sb2dvLnN2ZyIgZGF0YS1uYW1lPSIxNi1sb2dvLnN2ZyIgY2xhc3M9ImNscy0xIiBkPSJNMTIuMDEyLDkuMzE4YTAuODM5LDAuODM5LDAsMCwwLS45NTguODVWMjEuNjk0YTAuODM4LDAuODM4LDAsMCwwLC45ODcuODQ1bDAuMDkxLS4wMTlWOS4zMzdaTTkuOTU3LDEwLjU5M0EwLjgzOSwwLjgzOSwwLDAsMCw5LDExLjQ0M3Y5YTAuODM3LDAuODM3LDAsMCwwLC45ODcuODQ1bDAuMDkxLS4wMThWMTAuNjEyWk0yMy4yNjMsOS41MTNsLTkuMDgyLTEuNWEwLjg4OCwwLjg4OCwwLDAsMC0xLjAxNC45VjIzLjA4N2EwLjg4NywwLjg4NywwLDAsMCwxLjA0NC44OTRsOS4wODEtMS42OTRBMC45LDAuOSwwLDAsMCwyNCwyMS4zOTRWMTAuNDEzYTAuOSwwLjksMCwwLDAtLjczOC0wLjlNMjIuNDc2LDIwLjNhMC42NzcsMC42NzcsMCwwLDEtLjUuNjc5bC01Ljk1NiwxYTAuNjQyLDAuNjQyLDAsMCwxLS43MzctMC42NzlWMTAuNzM5QTAuNjQ1LDAuNjQ1LDAsMCwxLDE2LDEwLjA1NWw1Ljk1NiwwLjc4OWEwLjY3NCwwLjY3NCwwLDAsMSwuNTIxLjY4NFYyMC4zWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTkgLTgpIi8+DQo8L3N2Zz4=';
53
+ }
54
+
55
+ /**
56
+ * Sets an AJAX endpoint for Instapage plugin.
57
+ */
58
+ public static function initAjaxURL() {
59
+ echo '<script>var INSTAPAGE_AJAXURL = \'' . InstapageCmsPluginConnector::getAjaxURL() . '\';</script>';
60
+ }
61
+
62
+ /**
63
+ * Gets plugin's options stored in the database.
64
+ *
65
+ * @param bool $configOnly Return only configuration, ommit JSON options.
66
+ *
67
+ * @return object Options object.
68
+ */
69
+ public static function getOptions($configOnly = false) {
70
+ $db = InstapageCmsPluginDBModel::getInstance();
71
+
72
+ if ($configOnly) {
73
+ $sql = 'SELECT config FROM ' . $db->optionsTable;
74
+ $row = $db->getRow($sql);
75
+
76
+ if (isset($row->config)) {
77
+ return json_decode($row->config);
78
+ }
79
+
80
+ return new stdClass;
81
+ } else {
82
+ $sql = 'SELECT * FROM ' . $db->optionsTable;
83
+ $options = $db->getRow($sql);
84
+
85
+ if ($options === false) {
86
+ return new stdClass;
87
+ }
88
+
89
+ if (isset($options->config)) {
90
+ $options->config = json_decode($options->config);
91
+ }
92
+
93
+ return $options;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Gets a single value from plugin's options.
99
+ *
100
+ * @param string $name Option name.
101
+ * @param mixed $default Default value of the option. Defaulf: false.
102
+ *
103
+ * @uses \InstapageHelper::getOptions().
104
+ * @uses \InstapageHelper::getVar() to check the existence of the option.
105
+ *
106
+ * @return mixed Option value or default value passed to the function.
107
+ */
108
+ public static function getOption($name, $default = false) {
109
+ $options = self::getOptions();
110
+
111
+ if (in_array($name, array('plugin_hash', 'user_name', 'api_keys'))) {
112
+ return self::getVar($options->$name, $default);
113
+ } else {
114
+ return self::getVar($options->config->$name, $default);
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Udated the plugin's options in database.
120
+ *
121
+ * @param $data Options object with updated values.
122
+ *
123
+ * @uses \InstapageCmsPluginDBModel::query to update the database.
124
+ *
125
+ * @return mixed Query result of false on query of false on query error. Exception message is logged in standard error log.
126
+ */
127
+ public static function updateOptions($data) {
128
+ $userName = @self::getVar($data->userName, null);
129
+ $userToken = @self::getVar($data->userToken, null);
130
+
131
+ if ($userName === null) {
132
+ $userName = @self::getVar($data->user_name, null);
133
+ }
134
+
135
+ if ($userToken === null) {
136
+ $userToken = @self::getVar($data->plugin_hash, null);
137
+ }
138
+
139
+ $configJson = !empty($data->config) ? json_encode($data->config) : '';
140
+ $metadataJson = !empty($data->metadata) ? json_encode($data->metadata) : '';
141
+ $db = InstapageCmsPluginDBModel::getInstance();
142
+ $sql = 'INSERT INTO ' . $db->optionsTable . '(id, plugin_hash, api_keys, user_name, config, metadata) VALUES(1, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE plugin_hash = %s, api_keys = %s, user_name = %s, config = %s, metadata=%s';
143
+
144
+ return $db->query($sql, $userToken, '', $userName, $configJson, $metadataJson, $userToken, '', $userName, $configJson, $metadataJson);
145
+ }
146
+
147
+ /**
148
+ * Updates plugin's options, stored an JSON.
149
+ *
150
+ * @param string $key Name of the param to update.
151
+ * @param string $value Value of the param to update.
152
+ */
153
+ public static function updateMetadata($key, $value) {
154
+ $metadata = self::getMetadata();
155
+ $metadata[$key] = $value;
156
+ $db = InstapageCmsPluginDBModel::getInstance();
157
+ $sql = 'INSERT INTO ' . $db->optionsTable. '(id, metadata) VALUES(1, %s) ON DUPLICATE KEY UPDATE metadata = %s';
158
+ $metadataJson = !empty($metadata) ? json_encode($metadata) : '';
159
+
160
+ return $db->query($sql, $metadataJson, $metadataJson);
161
+ }
162
+
163
+ /**
164
+ * Gest an option value from plugin's metadata.
165
+ *
166
+ * @param string $key Name of the param to get.
167
+ * @param string $default Default value.
168
+ *
169
+ * @return mixed Option value.
170
+ */
171
+ public static function getMetadata($key = '', $default = null) {
172
+ $db = InstapageCmsPluginDBModel::getInstance();
173
+ $sql = 'SELECT metadata FROM ' . $db->optionsTable;
174
+ $row = $db->getRow($sql);
175
+ $metadata = array();
176
+
177
+ if (isset($row->metadata) && $row->metadata) {
178
+ $metadata = (array) json_decode($row->metadata);
179
+ }
180
+
181
+ if (!empty($key)) {
182
+ return isset($metadata[$key]) ? $metadata[$key] : $default;
183
+ }
184
+
185
+ return $metadata;
186
+ }
187
+
188
+ /**
189
+ * Gets API tokens stored in the DB.
190
+ *
191
+ * @return array Stored tokens.
192
+ */
193
+ public static function getTokens() {
194
+ $config = self::getOptions(true);
195
+ $tokens = array();
196
+
197
+ if (!isset($config->tokens) || !is_array($config->tokens)) {
198
+ return array();
199
+ }
200
+
201
+ foreach ($config->tokens as $token) {
202
+ $tokens[] = $token->value;
203
+ }
204
+
205
+ return $tokens;
206
+ }
207
+
208
+ /**
209
+ * Returns the given variable if it's set, or default value otherwise.
210
+ *
211
+ * @param mixed $value. Value to be checked.
212
+ * @param mixed $default. Default value. Default: false.
213
+ *
214
+ * @return mxed if value is set, returns the value. In other case returns default value or false.
215
+ */
216
+ public static function getVar(&$value, $default = false) {
217
+ return isset($value) ? $value : $default;
218
+ }
219
+
220
+ /**
221
+ * Checks if one of the custom params, stored in plugin's settings, are present in curent URL.
222
+ *
223
+ * @return boolean
224
+ */
225
+ public static function isCustomParamPresent() {
226
+ $slug = self::extractSlug(InstapageCmsPluginConnector::getHomeUrl());
227
+ $defaultExcludedParams = array
228
+ (
229
+ 's' => null,
230
+ 'post_type' => null,
231
+ 'preview' => 'true'
232
+ );
233
+
234
+ $customParamsOption = explode('|', stripslashes(self::getOption('customParams', '')));
235
+ $customParams = array();
236
+ $paramArr = null;
237
+ $key = null;
238
+ $value = null;
239
+
240
+ foreach ($customParamsOption as $param) {
241
+ $paramArr = explode('=', $param);
242
+ $key = isset($paramArr[0]) ? $paramArr[0] : null;
243
+ $value = isset($paramArr[1]) ? str_replace('"', '', $paramArr[1]) : null;
244
+ $customParams[$key] = $value;
245
+ }
246
+
247
+ if (count($customParams)) {
248
+ $excludedParams = array_merge($defaultExcludedParams, $customParams);
249
+ }
250
+
251
+ foreach ($excludedParams as $key => $value) {
252
+ $isDefaultParam = array_key_exists($key, $defaultExcludedParams) ? true : false;
253
+
254
+ if (
255
+ (!empty($key) && $value == null && (isset($_GET[$key]) || (!$isDefaultParam && strpos($slug, $key) !== false))) ||
256
+ (!empty($key) && $value !== null && isset($_GET[$key]) && $_GET[$key] == $value)
257
+ )
258
+ {
259
+ return true;
260
+ }
261
+ }
262
+
263
+ return false;
264
+ }
265
+
266
+ /**
267
+ * Cleans an URL for sedning to Instapage app.
268
+ *
269
+ * @param string $url URL to prepare.
270
+ *
271
+ * @return string Prepared URL.
272
+ */
273
+ public static function prepareUrlForUpdate($url) {
274
+ return trim(str_replace(array('http://', 'https://'), '', $url), '/');
275
+ }
276
+
277
+ /**
278
+ * Check if request uri has duplicated slashes.
279
+ *
280
+ * @return boolean True if requested uri has duplicated slashes, false if uri is ok
281
+ */
282
+ public static function checkIfRequestUriHasDuplicatedSlashes() {
283
+ $url = $_SERVER['REQUEST_URI'];
284
+ if (($pos = strpos($url, '?')) !== false) {
285
+ $url = substr($url, 0, $pos);
286
+ }
287
+
288
+ return strpos($url, '//') !== false;
289
+ }
290
+
291
+ /**
292
+ * Extracts a slug from current URL. Slug will be compared with values stored in plugin's database to find a landing page to display.
293
+ *
294
+ * @param string $homeUrl URL of the home page.
295
+ *
296
+ * @return string Trimmed slug, ready to compare with values stored in the DB.
297
+ */
298
+ public static function extractSlug($homeUrl) {
299
+ $uriSegments = explode('?', $_SERVER['REQUEST_URI']);
300
+ self::writeDiagnostics($uriSegments, 'checkCustomUrl: $uriSegments');
301
+ $path = trim(parse_url($homeUrl, PHP_URL_PATH), '/');
302
+ $segment = trim($uriSegments[0], '/');
303
+
304
+ if ($path) {
305
+ $pos = strpos($segment, $path );
306
+
307
+ if ($pos !== false) {
308
+ $segment = substr_replace($segment, '', $pos, strlen($path));
309
+ }
310
+ }
311
+
312
+ $slug = trim($segment, '/');
313
+ // removing duplicated slashes from obtained almost final slug form
314
+ $slug = preg_replace('~\/{2,}~', '/', $slug);
315
+ self::writeDiagnostics($slug, 'checkCustomUrl: $slug');
316
+
317
+ return $slug;
318
+ }
319
+
320
+ /**
321
+ * Decodes data passed as a JSON.
322
+ *
323
+ * @return object Object passed via POST method.
324
+ */
325
+ public static function getPostData() {
326
+ return isset($_POST['data']) ? json_decode(urldecode($_POST['data'])) : null;
327
+ }
328
+
329
+ /**
330
+ * Encodes a message as a JSON object.
331
+ *
332
+ * @param string $text Text of the message
333
+ * @param string $status. Status of a message. Typically 'OK' or 'ERROR'.
334
+ *
335
+ * @return string encoded JSON message object.
336
+ */
337
+ public static function formatJsonMessage($text, $status = 'OK') {
338
+ self::writeDiagnostics($text, 'Message');
339
+
340
+ return json_encode((object) array('status' => $status, 'message' => $text));
341
+ }
342
+
343
+ /**
344
+ * Checks Instapage API response.
345
+ *
346
+ * @param object $response Response object.
347
+ * @param string $message A message to store in debug log or display to user after checking.
348
+ * @param bool $print If message should be shown to user a a system message.
349
+ *
350
+ * @return bool Returns true on success, false on failure.
351
+ */
352
+ public static function checkResponse($response, $message = '', $print = true) {
353
+
354
+ if (is_null($response)) {
355
+ $msgText = InstapageCmsPluginConnector::lang('Can\'t decode API response. %s', $message);
356
+
357
+ if ($print) {
358
+ echo self::formatJsonMessage($msgText, 'ERROR');
359
+ } else {
360
+ self::writeDiagnostics($msgText, 'message');
361
+ }
362
+
363
+ return false;
364
+ }
365
+
366
+ if (!$response->success) {
367
+ $text = @self::getVar($response->message, '');
368
+
369
+ if ($print) {
370
+ if ($text) {
371
+ echo self::formatJsonMessage(InstapageCmsPluginConnector::lang($text), 'ERROR');
372
+ } else {
373
+ echo self::formatJsonMessage(InstapageCmsPluginConnector::lang('API returned an error. %s', $message), 'ERROR');
374
+ }
375
+ } else {
376
+ self::writeDiagnostics($text, 'message');
377
+ }
378
+
379
+ return false;
380
+ }
381
+
382
+ return true;
383
+ }
384
+
385
+ /**
386
+ * Writes an entry in debug log, if diagnostic mode is on.
387
+ *
388
+ * @param mixed $value Value to be stored.
389
+ * @param string $name Name of the value. Default: ''.
390
+ */
391
+ public static function writeDiagnostics($value, $name = '') {
392
+ $log = InstapageCmsPluginDebugLogModel::getInstance();
393
+
394
+ if ($log->isDiagnosticMode()) {
395
+ $log->write($value, $name);
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Writes an entry in debug log.
401
+ *
402
+ * @param mixed $value Value to be stored.
403
+ * @param string $name Name of the value. Default: ''.
404
+ */
405
+ public static function writeLog($value, $name = '') {
406
+ $log = InstapageCmsPluginDebugLogModel::getInstance();
407
+ $log->write($value);
408
+ }
409
+
410
+ /**
411
+ * Prepares an Auth header for API requests.
412
+ *
413
+ * @param array $tokens Tokens to encode in Auth header.
414
+ * @return string Encoded Auth header.
415
+ */
416
+ public static function getAuthHeader($tokens) {
417
+ self::writeDiagnostics($tokens, 'Decoded tokens');
418
+
419
+ return base64_encode(json_encode($tokens));
420
+ }
421
+
422
+ /**
423
+ * Gets a variant of a landing page to display.
424
+ *
425
+ * @param string $cookieString A cookie string.
426
+ *
427
+ * @return string|null A variant to display, or null if a variant is not present.
428
+ */
429
+ public static function getVariant($cookieString) {
430
+ $pattern = '/instapage-variant-\d*?=(.*?);/';
431
+ $matches = array();
432
+ preg_match($pattern, $cookieString, $matches);
433
+
434
+ return isset($matches[1]) ? $matches[1] : null;
435
+ }
436
+
437
+ /**
438
+ * Sets a proper header with response code.
439
+ *
440
+ * @param int $code HTTP Response Code. Default: 200.
441
+ */
442
+ public static function httpResponseCode($code = 200) {
443
+
444
+ if (function_exists('http_response_code')) {
445
+ http_response_code($code);
446
+
447
+ return;
448
+ }
449
+
450
+ if ($code === null) {
451
+ $code = 200;
452
+ }
453
+
454
+ switch ($code) {
455
+ case 100: $text = 'Continue'; break;
456
+ case 101: $text = 'Switching Protocols'; break;
457
+ case 200: $text = 'OK'; break;
458
+ case 201: $text = 'Created'; break;
459
+ case 202: $text = 'Accepted'; break;
460
+ case 203: $text = 'Non-Authoritative Information'; break;
461
+ case 204: $text = 'No Content'; break;
462
+ case 205: $text = 'Reset Content'; break;
463
+ case 206: $text = 'Partial Content'; break;
464
+ case 300: $text = 'Multiple Choices'; break;
465
+ case 301: $text = 'Moved Permanently'; break;
466
+ case 302: $text = 'Moved Temporarily'; break;
467
+ case 303: $text = 'See Other'; break;
468
+ case 304: $text = 'Not Modified'; break;
469
+ case 305: $text = 'Use Proxy'; break;
470
+ case 400: $text = 'Bad Request'; break;
471
+ case 401: $text = 'Unauthorized'; break;
472
+ case 402: $text = 'Payment Required'; break;
473
+ case 403: $text = 'Forbidden'; break;
474
+ case 404: $text = 'Not Found'; break;
475
+ case 405: $text = 'Method Not Allowed'; break;
476
+ case 406: $text = 'Not Acceptable'; break;
477
+ case 407: $text = 'Proxy Authentication Required'; break;
478
+ case 408: $text = 'Request Time-out'; break;
479
+ case 409: $text = 'Conflict'; break;
480
+ case 410: $text = 'Gone'; break;
481
+ case 411: $text = 'Length Required'; break;
482
+ case 412: $text = 'Precondition Failed'; break;
483
+ case 413: $text = 'Request Entity Too Large'; break;
484
+ case 414: $text = 'Request-URI Too Large'; break;
485
+ case 415: $text = 'Unsupported Media Type'; break;
486
+ case 500: $text = 'Internal Server Error'; break;
487
+ case 501: $text = 'Not Implemented'; break;
488
+ case 502: $text = 'Bad Gateway'; break;
489
+ case 503: $text = 'Service Unavailable'; break;
490
+ case 504: $text = 'Gateway Time-out'; break;
491
+ case 505: $text = 'HTTP Version not supported'; break;
492
+ default: $code = 200; $text = 'OK'; break;
493
+ }
494
+
495
+ $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1');
496
+
497
+ if (!headers_sent()) {
498
+ header($protocol . ' ' . $code . ' ' . $text);
499
+ }
500
+ $GLOBALS['http_response_code'] = $code;
501
+ }
502
+
503
+ /**
504
+ * Sets a proper headers to disable caching by browsers and CDNs.
505
+ */
506
+ public static function disableCaching() {
507
+ if (!headers_sent()) {
508
+ header('Cache-Control: no-cache, no-store, must-revalidate');
509
+ header('Pragma: no-cache');
510
+ header('Expires: 0');
511
+ setcookie('no-cache', 'true');
512
+ }
513
+ }
514
+
515
+ /**
516
+ * Returns true if given version number seems to be MariaDB
517
+ * @param string $version Version number from InstapageCmsPluginConnector::getMySQLVersion()
518
+ * @return bool
519
+ */
520
+ public static function isMariaDBMySQL($version) {
521
+ return (strpos($version, 'MariaDB') !== false);
522
+ }
523
+
524
+ /**
525
+ * Returns true if given version number seems to be regular MySQL
526
+ * @param string $version Version number from InstapageCmsPluginConnector::getMySQLVersion()
527
+ * @uses self::isMariaDBMySQL()
528
+ * @return bool
529
+ */
530
+ public static function isRegularMySQL($version) {
531
+ return !self::isMariaDBMySQL($version);
532
+ }
533
+
534
+ /**
535
+ * Returns only number of version string
536
+ * @param string $version Version number from InstapageCmsPluginConnector::getMySQLVersion()
537
+ * @uses self::isMariaDBMySQL()
538
+ * @return string
539
+ */
540
+ public static function getRawVersion($version) {
541
+ $data = explode('-', $version, 2);
542
+ return $data[0];
543
+ }
544
+ }
InstapageHelper.php ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class InstapageHelper
3
+ {
4
+ public static function loadTemplate( $tmpl, $print = true )
5
+ {
6
+ $template_file = INSTAPAGE_PLUGIN_PATH . '/views/' . $tmpl . '.php';
7
+
8
+ if( file_exists( $template_file ) )
9
+ {
10
+ if( !$print )
11
+ {
12
+ ob_start();
13
+ }
14
+
15
+ require( $template_file );
16
+
17
+ if( !$print )
18
+ {
19
+ $contents = ob_get_contents();
20
+ ob_end_clean();
21
+
22
+ return $contents;
23
+ }
24
+ }
25
+ else
26
+ {
27
+ throw new Exception( Connector::lang( 'Template file (%s) not found', $template_file ) );
28
+ }
29
+ }
30
+
31
+ public static function initMessagesSystem()
32
+ {
33
+ self::loadTemplate( 'messages' );
34
+ }
35
+
36
+ public static function getMenuIcon()
37
+ {
38
+ return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTUiIGhlaWdodD0iMTUuOTY5IiB2aWV3Qm94PSIwIDAgMTUgMTUuOTY5Ij4NCiAgPGRlZnM+DQogICAgPHN0eWxlPg0KICAgICAgLmNscy0xIHsNCiAgICAgICAgZmlsbDogI2ZmZjsNCiAgICAgICAgZmlsbC1ydWxlOiBldmVub2RkOw0KICAgICAgfQ0KICAgIDwvc3R5bGU+DQogIDwvZGVmcz4NCiAgPHBhdGggaWQ9Il8xNi1sb2dvLnN2ZyIgZGF0YS1uYW1lPSIxNi1sb2dvLnN2ZyIgY2xhc3M9ImNscy0xIiBkPSJNMTIuMDEyLDkuMzE4YTAuODM5LDAuODM5LDAsMCwwLS45NTguODVWMjEuNjk0YTAuODM4LDAuODM4LDAsMCwwLC45ODcuODQ1bDAuMDkxLS4wMTlWOS4zMzdaTTkuOTU3LDEwLjU5M0EwLjgzOSwwLjgzOSwwLDAsMCw5LDExLjQ0M3Y5YTAuODM3LDAuODM3LDAsMCwwLC45ODcuODQ1bDAuMDkxLS4wMThWMTAuNjEyWk0yMy4yNjMsOS41MTNsLTkuMDgyLTEuNWEwLjg4OCwwLjg4OCwwLDAsMC0xLjAxNC45VjIzLjA4N2EwLjg4NywwLjg4NywwLDAsMCwxLjA0NC44OTRsOS4wODEtMS42OTRBMC45LDAuOSwwLDAsMCwyNCwyMS4zOTRWMTAuNDEzYTAuOSwwLjksMCwwLDAtLjczOC0wLjlNMjIuNDc2LDIwLjNhMC42NzcsMC42NzcsMCwwLDEtLjUuNjc5bC01Ljk1NiwxYTAuNjQyLDAuNjQyLDAsMCwxLS43MzctMC42NzlWMTAuNzM5QTAuNjQ1LDAuNjQ1LDAsMCwxLDE2LDEwLjA1NWw1Ljk1NiwwLjc4OWEwLjY3NCwwLjY3NCwwLDAsMSwuNTIxLjY4NFYyMC4zWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTkgLTgpIi8+DQo8L3N2Zz4=';
39
+ }
40
+
41
+ public static function initAjaxURL()
42
+ {
43
+ echo '<script>var INSTAPAGE_AJAXURL = \'' . Connector::getAjaxURL() . '\';</script>';
44
+ }
45
+
46
+ public static function getOptions( $configOnly = false )
47
+ {
48
+ $db = DBModel::getInstance();
49
+
50
+ if( $configOnly )
51
+ {
52
+ $sql = 'SELECT config FROM ' . $db->optionsTable;
53
+ $row = $db->getRow( $sql );
54
+
55
+ if( isset( $row->config ) )
56
+ {
57
+ return json_decode( $row->config );
58
+ }
59
+
60
+ return new stdClass;
61
+ }
62
+ else
63
+ {
64
+ $sql = 'SELECT * FROM ' . $db->optionsTable;
65
+ $options = $db->getRow( $sql );
66
+
67
+ if( $options === false )
68
+ {
69
+ return new stdClass;
70
+ }
71
+
72
+ if( isset( $options->config ) )
73
+ {
74
+ $options->config = json_decode( $options->config );
75
+ }
76
+
77
+ return $options;
78
+ }
79
+ }
80
+
81
+ public static function getOption( $name, $default = false )
82
+ {
83
+ $options = self::getOptions();
84
+
85
+ if( in_array( $name, array( 'plugin_hash', 'user_name', 'api_keys' ) ) )
86
+ {
87
+ return self::getVar( $options->$name, $default );
88
+ }
89
+ else
90
+ {
91
+ return self::getVar( $options->config->$name, $default );
92
+ }
93
+ }
94
+
95
+ public static function updateOptions( $data )
96
+ {
97
+ $userName = @InstapageHelper::getVar( $data->userName, null );
98
+ $userToken = @InstapageHelper::getVar( $data->userToken, null );
99
+
100
+ if( $userName === null )
101
+ {
102
+ $userName = @InstapageHelper::getVar( $data->user_name, null );
103
+ }
104
+
105
+ if( $userToken === null )
106
+ {
107
+ $userToken = @InstapageHelper::getVar( $data->plugin_hash, null );
108
+ }
109
+
110
+ $configJson = !empty( $data->config ) ? json_encode( $data->config ) : '';
111
+ $metadataJson = !empty( $data->metadata ) ? json_encode( $data->metadata ) : '';
112
+ $db = DBModel::getInstance();
113
+ $sql = 'INSERT INTO ' . $db->optionsTable . '(id, plugin_hash, api_keys, user_name, config, metadata) VALUES(1, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE plugin_hash = %s, api_keys = %s, user_name = %s, config = %s, metadata=%s';
114
+
115
+ return $db->query( $sql, $userToken, '', $userName, $configJson, $metadataJson, $userToken, '', $userName, $configJson, $metadataJson );
116
+ }
117
+
118
+ public static function updateMetadata( $key, $value )
119
+ {
120
+ $metadata = self::getMetadata();
121
+ $metadata[ $key ] = $value;
122
+ $db = DBModel::getInstance();
123
+ $sql = 'INSERT INTO ' . $db->optionsTable. '(id, metadata) VALUES(1, %s) ON DUPLICATE KEY UPDATE metadata = %s';
124
+ $metadata_json = !empty( $metadata ) ? json_encode( $metadata ) : '';
125
+
126
+ return $db->query( $sql, $metadata_json, $metadata_json );
127
+ }
128
+
129
+ public static function getMetadata( $key = '', $default = null )
130
+ {
131
+ $db = DBModel::getInstance();
132
+ $sql = 'SELECT metadata FROM ' . $db->optionsTable;
133
+ $row = $db->getRow( $sql );
134
+ $metadata = array();
135
+
136
+ if( isset( $row->metadata ) && $row->metadata )
137
+ {
138
+ $metadata = (array) json_decode( $row->metadata );
139
+ }
140
+
141
+ if( !empty( $key ) )
142
+ {
143
+ return isset( $metadata[ $key ] ) ? $metadata[ $key ] : $default;
144
+ }
145
+
146
+ return $metadata;
147
+ }
148
+
149
+ public static function getTokens()
150
+ {
151
+ $config = self::getOptions( true );
152
+ $tokens = array();
153
+
154
+ if( !isset( $config->tokens ) || !is_array( $config->tokens ) )
155
+ {
156
+ return array();
157
+ }
158
+
159
+ foreach( $config->tokens as $token )
160
+ {
161
+ $tokens[] = $token->value;
162
+ }
163
+
164
+ return $tokens;
165
+ }
166
+
167
+ public static function getVar( &$value, $default = false )
168
+ {
169
+ return isset( $value ) ? $value : $default;
170
+ }
171
+
172
+ public static function isCustomParamPresent()
173
+ {
174
+ $slug = self::extractSlug( Connector::getHomeUrl() );
175
+ $default_excluded_params = array
176
+ (
177
+ 's' => null,
178
+ 'post_type' => null,
179
+ 'preview' => 'true'
180
+ );
181
+
182
+ $custom_params_option = explode( '|', stripslashes( self::getOption( 'customParams', '' ) ) );
183
+ $custom_params = array();
184
+ $param_arr = null;
185
+ $key = null;
186
+ $value = null;
187
+
188
+ foreach( $custom_params_option as $param )
189
+ {
190
+ $param_arr = explode( '=', $param );
191
+ $key = isset( $param_arr[ 0 ] ) ? $param_arr[ 0 ] : null;
192
+ $value = isset( $param_arr[ 1 ] ) ? str_replace( '"', '', $param_arr[ 1 ] ) : null;
193
+ $custom_params[ $key ] = $value;
194
+ }
195
+
196
+ if( count( $custom_params ) )
197
+ {
198
+ $excluded_params = array_merge( $default_excluded_params, $custom_params );
199
+ }
200
+
201
+ foreach( $excluded_params as $key => $value )
202
+ {
203
+ $is_default_param = array_key_exists( $key, $default_excluded_params ) ? true : false;
204
+
205
+ if(
206
+ ( !empty( $key ) && $value == null && ( isset( $_GET[ $key ] ) || ( !$is_default_param && strpos( $slug, $key ) !== false ) ) ) ||
207
+ ( !empty( $key ) && $value !== null && isset( $_GET[ $key ] ) && $_GET[ $key ] == $value )
208
+ )
209
+ {
210
+ return true;
211
+ }
212
+ }
213
+
214
+ return false;
215
+ }
216
+
217
+ public static function prepareUrlForUpdate( $url )
218
+ {
219
+ return trim( str_replace( array( 'http://', 'https://' ), '', $url ), '/' );
220
+ }
221
+
222
+ public static function extractSlug( $home_url )
223
+ {
224
+ $uri_segments = explode( '?', $_SERVER[ 'REQUEST_URI' ] );
225
+ self::writeDiagnostics( $uri_segments, 'checkCustomUrl: $uri_segments' );
226
+ $path = trim( parse_url( $home_url, PHP_URL_PATH ), '/' );
227
+ $segment = trim( $uri_segments[ 0 ], '/' );
228
+
229
+ if( $path )
230
+ {
231
+ $pos = strpos( $segment, $path );
232
+
233
+ if( $pos !== false )
234
+ {
235
+ $segment = substr_replace( $segment, '', $pos, strlen( $path ) );
236
+ }
237
+ }
238
+
239
+ $slug = trim( $segment, '/' );
240
+ self::writeDiagnostics( $slug, 'checkCustomUrl: $slug' );
241
+
242
+ return $slug;
243
+ }
244
+
245
+ public static function getPostData()
246
+ {
247
+ return isset( $_POST[ 'data' ] ) ? json_decode( urldecode( $_POST[ 'data' ] ) ) : null;
248
+ }
249
+
250
+ public static function formatJsonMessage( $text, $status = 'OK' )
251
+ {
252
+ self::writeDiagnostics( $text, 'Message' );
253
+
254
+ return json_encode( (object) array( 'status' => $status, 'message' => $text ) );
255
+ }
256
+
257
+ public static function checkResponse( $response, $message = '', $print = true )
258
+ {
259
+ if( is_null( $response ) )
260
+ {
261
+ $msgText = Connector::lang( 'Can\'t decode API response. %s', $message );
262
+ if( $print )
263
+ {
264
+ echo self::formatJsonMessage( $msgText, 'ERROR' );
265
+ }
266
+ else
267
+ {
268
+ InstapageHelper::writeDiagnostics( $msgText, 'message' );
269
+ }
270
+
271
+ return false;
272
+ }
273
+
274
+ if( !$response->success )
275
+ {
276
+ $text = @self::getVar( $response->message, '' );
277
+
278
+ if( $print )
279
+ {
280
+ if( $text )
281
+ {
282
+ echo self::formatJsonMessage( Connector::lang( $text ), 'ERROR' );
283
+ }
284
+ else
285
+ {
286
+ echo self::formatJsonMessage( Connector::lang( 'API returned an error. %s', $message ), 'ERROR' );
287
+ }
288
+ }
289
+ else
290
+ {
291
+ InstapageHelper::writeDiagnostics( $text, 'message' );
292
+ }
293
+
294
+ return false;
295
+ }
296
+
297
+ return true;
298
+ }
299
+
300
+ public static function writeDiagnostics( $value, $name = '' )
301
+ {
302
+ $log = DebugLogModel::getInstance();
303
+
304
+ if( $log->isDiagnosticMode() )
305
+ {
306
+ $log->write( $value, $name );
307
+ }
308
+ }
309
+
310
+ public static function writeLog( $value, $name = '' )
311
+ {
312
+ $log = DebugLogModel::getInstance();
313
+ $log->write( $value );
314
+ }
315
+
316
+ public static function getAuthHeader( $tokens )
317
+ {
318
+ self::writeDiagnostics( $tokens, 'Decoded tokens');
319
+
320
+ return base64_encode( json_encode( $tokens ) );
321
+ }
322
+
323
+ public static function getVariant( $cookie_string )
324
+ {
325
+ $pattern = '/instapage-variant-\d*?=(.*?);/';
326
+ $matches = array();
327
+ preg_match( $pattern, $cookie_string, $matches );
328
+
329
+ return isset( $matches[ 1 ] ) ? $matches[ 1 ] : null;
330
+ }
331
+
332
+ public static function httpResponseCode( $code = 200 )
333
+ {
334
+ if( function_exists( 'http_response_code' ) )
335
+ {
336
+ http_response_code( $code );
337
+
338
+ return;
339
+ }
340
+
341
+ if( $code === NULL )
342
+ {
343
+ $code = 200;
344
+ }
345
+
346
+ switch( $code )
347
+ {
348
+ case 100: $text = 'Continue'; break;
349
+ case 101: $text = 'Switching Protocols'; break;
350
+ case 200: $text = 'OK'; break;
351
+ case 201: $text = 'Created'; break;
352
+ case 202: $text = 'Accepted'; break;
353
+ case 203: $text = 'Non-Authoritative Information'; break;
354
+ case 204: $text = 'No Content'; break;
355
+ case 205: $text = 'Reset Content'; break;
356
+ case 206: $text = 'Partial Content'; break;
357
+ case 300: $text = 'Multiple Choices'; break;
358
+ case 301: $text = 'Moved Permanently'; break;
359
+ case 302: $text = 'Moved Temporarily'; break;
360
+ case 303: $text = 'See Other'; break;
361
+ case 304: $text = 'Not Modified'; break;
362
+ case 305: $text = 'Use Proxy'; break;
363
+ case 400: $text = 'Bad Request'; break;
364
+ case 401: $text = 'Unauthorized'; break;
365
+ case 402: $text = 'Payment Required'; break;
366
+ case 403: $text = 'Forbidden'; break;
367
+ case 404: $text = 'Not Found'; break;
368
+ case 405: $text = 'Method Not Allowed'; break;
369
+ case 406: $text = 'Not Acceptable'; break;
370
+ case 407: $text = 'Proxy Authentication Required'; break;
371
+ case 408: $text = 'Request Time-out'; break;
372
+ case 409: $text = 'Conflict'; break;
373
+ case 410: $text = 'Gone'; break;
374
+ case 411: $text = 'Length Required'; break;
375
+ case 412: $text = 'Precondition Failed'; break;
376
+ case 413: $text = 'Request Entity Too Large'; break;
377
+ case 414: $text = 'Request-URI Too Large'; break;
378
+ case 415: $text = 'Unsupported Media Type'; break;
379
+ case 500: $text = 'Internal Server Error'; break;
380
+ case 501: $text = 'Not Implemented'; break;
381
+ case 502: $text = 'Bad Gateway'; break;
382
+ case 503: $text = 'Service Unavailable'; break;
383
+ case 504: $text = 'Gateway Time-out'; break;
384
+ case 505: $text = 'HTTP Version not supported'; break;
385
+ default: $code = 200; $text = 'OK'; break;
386
+ }
387
+
388
+ $protocol = ( isset( $_SERVER[ 'SERVER_PROTOCOL' ] ) ? $_SERVER[ 'SERVER_PROTOCOL' ] : 'HTTP/1.1' );
389
+ header( $protocol . ' ' . $code . ' ' . $text );
390
+ $GLOBALS[ 'http_response_code' ] = $code;
391
+ }
392
+ }
README.md ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Description
2
+ -----------
3
+ Join the thousands of users who have downloaded the Instapage plugin for WordPress to seamlessly publish landing pages as a natural extension of your WordPress blog or website. All you have to do is select the 'Push to WordPress' publishing option within Instapage when you're finished with your landing page.
4
+
5
+ Instapage is the most powerful landing page platform on the market. Ideal for teams and agencies, Instapage has everything you need to build fully customizable, on-brand landing pages.
6
+
7
+ **No other landing page builder offers this level of precision with full design freedom**
8
+
9
+ Every promotion deserves a great page. One that you’re confident is pixel-perfect, exquisitely composed, professional and polished, whether it’s in desktop or mobile form. Our fully customizable builder is intuitive and powerful, so it’s easy to create on-brand, conversion-friendly landing pages.
10
+
11
+ Design without bounds by selecting from over 5,000 fonts and 33,000,000 images to work with. And, our new alignment, distribution and grouping features, ensure your work is perfect in desktop or mobile versions.
12
+
13
+ **Over 100+ Landing Page Templates to Get You Started**
14
+
15
+ **Save valuable time and money with our integrations**
16
+
17
+ Integrate with the most widely used marketing services, like Salesforce, Zapier, Drupal, Autopilot, MailChimp, Google Analytics, AWeber, GoToWebinar, to name just a few.
18
+
19
+ **Highest ranked support in the industry**
20
+
21
+ Join 250,000+ businesses who rely on Instapage.
22
+
23
+ Installation
24
+ ------------
25
+ **Instapage WordPress Plugin Instructions:**
26
+ 1. When publishing your landing page from Instapage, choose WordPress.
27
+ 2. Go to Plugins in your WordPress administration, click Add New, and search for “Instapage WordPress Plugin”.
28
+ 3. Now click at Install Now button.
29
+ 4. Click on Activate after upload has completed.
30
+ 5. Go to Settings and choose Instapage.
31
+ 6. Log into your Instapage account.
32
+ 7. Now you can Add a New Page.
33
+ 8. Select a Page from the dropdown that you want to create a URL for (only pages published to WordPress are available).
34
+ 9. Create a URL, hit publish, and you're ready to promote your landing page!
35
+
36
+ Features
37
+ --------
38
+
39
+ - 100+ fully customizable and optimized templates all designed to increase conversions
40
+ - Designer-friendly builder
41
+ - Fully mobile responsive landing pages
42
+ - 5000+ Customizable Fonts (Google and Typekit)
43
+ - Custom domains
44
+ - Unlimited domains
45
+ - Enterprise Level Infrastructure & Support
46
+
47
+ Integrations
48
+ ------------
49
+
50
+ - ActiveCampaign
51
+ - Autopilot
52
+ - AWeber
53
+ - Campaign Monitor
54
+ - Constant Contact
55
+ - Drupal
56
+ - E-goi
57
+ - Facebook
58
+ - Get Response
59
+ - Google Analytics
60
+ - GoToWebinar
61
+ - Infusionsoft
62
+ - Kissmetrics
63
+ - Mad Mimi
64
+ - SalesForce
65
+ - Webhooks
66
+ - WordPress
67
+ - Zapier
68
+ - Zoho CRM
69
+
70
+ Changelog
71
+ ---------
72
+ = 3.1.9 (2017-07-13) =
73
+ - Fixed a bug with wrong variation serving
74
+ - Fixed Drupal JS and CSS aggregation problem
75
+
76
+ = 3.1.8 (2017-05-31) =
77
+ - Updated 'Tested up to' field
78
+ - Sending additional request headers to prevent caching
79
+ - Alternative method of passing Host parameter added
80
+ - Additional warning in diagnostic mode
81
+
82
+ = 3.1.7 (2017-05-09) =
83
+ - Fixed slug validator issue
84
+ - Installation improvement
85
+ - Fixed inaccurate status code issue
86
+ - Fixed problem with detection connected subaccount
87
+ - Fixed problem with email input error in login form
88
+
89
+ = 3.1.6 (2017-02-13) =
90
+ - Improved dynamic text replacement
91
+
92
+ = 3.1.4 (2017-02-01) =
93
+ - Fixed javascript errors on plugin's settings page
94
+ - Improved plugin installation
95
+ - Changed coding style
96
+
97
+ = 3.1.2 (2016-12-16) =
98
+ - Improved signing in into plugin
99
+
100
+ = 3.1.1 (2016-12-15) =
101
+ - Improved installation on Drupal
102
+ - Changed workflow for unpublish page via plugin
103
+ - Changed page fetching endpoint
104
+
105
+ = 3.1.0 (2016-11-28) =
106
+ - Improved compatibility with plugins use knockout.js
107
+ - Improved handling big requests
108
+ - Improved displaying 404 page header status
109
+ - Changed fetch landing pages
110
+
111
+ = 3.0.9 (2016-11-14) =
112
+ - Fixed problem with broken dashboard
113
+ - Fixed problem with not displayed page listing
114
+ - Improved auto-migration
115
+ - Improved stability
116
+
117
+ = 3.0.8 (2016-11-08) =
118
+ - Improved compatibility with other plugins
119
+ - Workaround for displaying plugin's link in sidebar
120
+ - Increased max length request limit
121
+
122
+ = 3.0.7 (2016-11-04) =
123
+ - Improved fetching big requests
124
+
125
+ = 3.0.6 (2016-11-03) =
126
+ - Improved slug detection method
127
+
128
+ = 3.0.5 (2016-11-03) =
129
+ - Improved fetching more than 50 pages
130
+ - Improved URL parsing
131
+ - Improved token validation
132
+ - Fixed publish link on dashboard
133
+
134
+ = 3.0.4 (2016-11-01) =
135
+ - unnecessary scripts removed from dashboard
136
+
137
+ = 3.0.3 (2016-11-01) =
138
+ - Compatibility with PHP >= 4.3
139
+ - Getting all pages ready for push
140
+ - Better parsing URL for homepage and 404 pages
141
+
142
+ = 3.0.2 (2016-10-31) =
143
+ - Cross origin proxy value fix
144
+
145
+ = 3.0.1 (2016-10-31) =
146
+ - PHP 5 compatibility fix
147
+ - DB Datetime fix
148
+
149
+ = 3.0 (2016-10-31) =
150
+ - Stable version.
README.txt ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Instapage Wordpress Plugin ===
2
+ Contributors: marek@instapage
3
+ Tags: landing page, lead generation, a/b testing, Instapage, squeeze page, conversion rate optimization, splash page, WordPress landing page, landing page optimization, lead capture page, mobile app landing page, Facebook landing page, sales page
4
+ Requires at least: 3.4
5
+ Requires PHP: 5.2.4
6
+ Tested up to: 5.1.1
7
+ Stable tag: 3.0
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Instapage plugin - the best way for WordPress to seamlessly publish landing pages as a natural extension of your WordPress blog or website.
12
+
13
+ == Description ==
14
+ Join the thousands of users who have downloaded the Instapage plugin for WordPress to seamlessly publish landing pages as a natural extension of your WordPress blog or website. All you have to do is select the 'Push to WordPress' publishing option within Instapage when you're finished with your landing page. (Click the “Installation” tab for detailed upload instructions)
15
+
16
+ Instapage is the most powerful landing page platform on the market. Ideal for teams and agencies, Instapage has everything you need to build fully customizable, on-brand landing pages.
17
+
18
+ Instapage is the only platform that offers unlimited domains.
19
+
20
+ **No other landing page builder offers this level of precision with full design freedom**
21
+
22
+ Every promotion deserves a great page. One that you’re confident is pixel perfect, exquisitely composed, professional and polished, whether it’s in desktop or mobile form. Our fully customizable builder is intuitive and powerful, so it’s easy to create on-brand, conversion-friendly landing pages
23
+
24
+ Design without bounds by selecting from over 5,000 fonts and 33,000,000 images to work with. And, our new alignment, distribution and grouping features, ensure your work is perfect in desktop or mobile versions.
25
+
26
+ **Over 100+ Landing Page Templates to Get You Started**
27
+
28
+ **Save valuable time and money with our integrations**
29
+ Integrate with the most widely used marketing services, like Salesforce, Zapier, Drupal, Autopilot, MailChimp, Google Analytics, AWeber, GoToWebinar, to name just a few.
30
+
31
+ **Highest ranked support in the industry**
32
+
33
+ Join 250,000+ businesses who rely on Instapage.
34
+
35
+ == Installation ==
36
+ 1. When publishing your landing page from Instapage, choose **WordPress**.
37
+ 1. Go to Plugins in your WordPress administration, click **Add New**, and search for “**Instapage Wordpress Plugin**”.
38
+ 1. Now click at **Install Now** button.
39
+ 1. Click on **Activate** after upload has completed.
40
+ 1. Go to Settings and choose **Instapage**.
41
+ 1. Log into your Instapage account.
42
+ 1. Now you can **Add a New Page**.
43
+ 1. **Select a Page** from the dropdown that you want to create a URL for (only pages published to WordPress are available).
44
+ 1. Create a URL, hit publish, and you're ready to promote your landing page!
45
+
46
+ **Server requirements:**
47
+
48
+ * PHP Curl extension
49
+ * If you get *"Couldn't connect to host"* error during login process, contact your hosting provider and ask for increasing outgoing connection limits.
50
+
51
+ == Screenshots ==
52
+ 1. Plugin's dashboard.
53
+ 2. Add new page / Edit form.
54
+ 3. Plugin's settings.
55
+ 4. Instapage app's dashboard.
56
+
57
+ == Changelog ==
58
+ = 3.2.11 (2019-11-27) =
59
+ - Bugfix: Custom experience display issues on WP Engine hosting
60
+ - Bugfix: Removing a PHP notice generated during the landing page display path
61
+
62
+ = 3.2.10 (2019-06-18) =
63
+ - Bugfix: CORS issue on Pantheon hosting
64
+
65
+ = 3.2.9 (2019-06-18) =
66
+ - Bugfix: Not working experiences on Pantheon hosting
67
+
68
+ = 3.2.8 (2019-04-03) =
69
+ - Bugfix: SSL related problems leading to not working landing pages
70
+
71
+ = 3.2.7 (2019-03-14) =
72
+ - Safe endpoints for serving pages
73
+ - Better detection of not accessible API
74
+ - Adjusted request limit during page loading
75
+
76
+ = 3.2.6 (2018-07-31) =
77
+ - Pageserver cookie type error fix
78
+ - Block plugin activation unless plugin requirements are met
79
+ - Add plugin requirements in plugin description
80
+
81
+ = 3.2.5 (2018-06-09) =
82
+ - Debug log model PHP compatibility fix
83
+
84
+ = 3.2.4 (2018-05-22) =
85
+ - Display an error message on "couldn't connect to host" error
86
+ - Error reporting refactor
87
+
88
+ = 3.2.3 (2018-04-03) =
89
+ - Bugfix: SQL Errors in debug log
90
+ - Bugfix: CMS Plugins validaiton: Dots are not prohibited in slugs
91
+ - Bugfix: Long URI spreads the div over the screen
92
+
93
+ = 3.2.2 (2018-02-26) =
94
+ - Bugfix: CMS plugin loads the page even if additional dashes are in URL
95
+ - Bugfix: Drupal7/8 Double slash in domain URL on Edit page
96
+ - Bugfix: Error 500 when Drupal 7/8 is installed in subdirectory
97
+ - Bugfix: Typo in account disconnecting info
98
+
99
+ = 3.2.1 (2017-12-21) =
100
+ - Bugfix: Plugin multi-click publish & delete button issue
101
+ - CMS plugin slug validator optimization
102
+
103
+ = 3.1.11 (2017-12-07) =
104
+ - Plugin requirements & requirements check added
105
+ - CMS version added to debug log
106
+ - Bugfix: Drupal module does not load
107
+ - Bugfix: Drupal 8 Homepage & 404 Page does not load
108
+
109
+ = 3.1.10 (2017-09-14) =
110
+ - Plugin description updated
111
+ - 'Tested up to' field updated
112
+
113
+ = 3.1.9 (2017-07-13) =
114
+ - Fixed a bug with wrong variation serving
115
+ - Fixed Drupal JS and CSS aggregation problem
116
+
117
+ = 3.1.8 (2017-05-31) =
118
+ - Updated 'Tested up to' field
119
+ - Sending additional request headers to prevent caching
120
+ - Alternative method of passing Host parameter added
121
+ - Additional warning in diagnostic mode
122
+
123
+ = 3.1.7 (2017-05-09) =
124
+ - Fixed slug validator issue
125
+ - Installation improvement
126
+ - Fixed inaccurate status code issue
127
+ - Fixed problem with detection connected subaccount
128
+ - Fixed problem with email input error in login form
129
+
130
+ = 3.1.6 (2017-02-13) =
131
+ - Improved dynamic text replacement
132
+
133
+ = 3.1.4 (2017-02-01) =
134
+ - Fixed javascript errors on plugin's settings page
135
+ - Improved plugin installation
136
+ - Changed coding style
137
+
138
+ = 3.1.2 (2016-12-16) =
139
+ - Improved signing in into plugin
140
+
141
+ = 3.1.1 (2016-12-15) =
142
+ - Improved installation on Drupal
143
+ - Changed workflow for unpublish page via plugin
144
+ - Changed page fetching endpoint
145
+
146
+ = 3.1.0 (2016-11-28) =
147
+ - Improved compatibility with plugins use knockout.js
148
+ - Improved handling big requests
149
+ - Improved displaying 404 page header status
150
+ - Changed fetch landing pages
151
+
152
+ = 3.0.9 (2016-11-14) =
153
+ - Fixed problem with broken dashboard
154
+ - Fixed problem with not displayed page listing
155
+ - Improved auto-migration
156
+ - Improved stability
157
+
158
+ = 3.0.8 (2016-11-08) =
159
+ - Improved compatibility with other plugins
160
+ - Workaround for displaying plugin's link in sidebar
161
+ - Increased max length request limit
162
+
163
+ = 3.0.7 (2016-11-04) =
164
+ - Improved fetching big requests
165
+
166
+ = 3.0.6 (2016-11-03) =
167
+ - Improved slug detection method
168
+
169
+ = 3.0.5 (2016-11-03) =
170
+ - Improved fetching more than 50 pages
171
+ - Improved URL parsing
172
+ - Improved token validation
173
+ - Fixed publish link on dashboard
174
+
175
+ = 3.0.4 (2016-11-01) =
176
+ - unnecessary scripts removed from dashboard
177
+
178
+ = 3.0.3 (2016-11-01) =
179
+ - Compatibility with PHP >= 4.3
180
+ - Getting all pages ready for push
181
+ - Better parsing URL for homepage and 404 pages
182
+
183
+ = 3.0.2 (2016-10-31) =
184
+ - Cross origin proxy value fix
185
+
186
+ = 3.0.1 (2016-10-31) =
187
+ - PHP 5 compatibility fix
188
+ - DB Datetime fix
189
+
190
+ = 3.0 (2016-10-31) =
191
+ Stable version.
assets/css/general.css ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #instapage-toolbar.l-wrapper
2
+ {
3
+ margin-top: 50px;
4
+ margin-bottom: 50px;
5
+ }
6
+
7
+ #instapage-toolbar.l-wrapper > div
8
+ {
9
+ border: 1px solid #f0f0f0;
10
+ padding: 40px 0;
11
+ background-color: white;
12
+ }
13
+
14
+ .instapage-cms-plugin
15
+ {
16
+ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
17
+ color: #37475a;
18
+ font-size: 14px;
19
+ }
20
+
21
+ .instapage-cms-plugin .preview-image .cropper
22
+ {
23
+ max-height: 200px;
24
+ margin-bottom: 10px;
25
+ overflow: hidden;
26
+ }
27
+
28
+ .instapage-cms-plugin td .page-title
29
+ {
30
+ margin-top: 10px;
31
+ }
32
+
33
+ .instapage-cms-plugin td .page-actions
34
+ {
35
+ margin: 10px auto 15px;
36
+ }
37
+
38
+ .instapage-cms-plugin td .page-url
39
+ {
40
+ margin: 10px 0;
41
+ }
42
+
43
+ .instapage-cms-plugin td .page-url a
44
+ {
45
+ word-wrap: break-word;
46
+ word-break: break-all;
47
+ display: inline-block;
48
+ }
49
+
50
+ .instapage-cms-plugin td .variation
51
+ {
52
+ padding-bottom: 15px;
53
+ }
54
+
55
+ .instapage-cms-plugin td .variation:first-child
56
+ {
57
+ padding-top: 10px;
58
+ }
59
+
60
+ .instapage-cms-plugin td .variation div:first-of-type
61
+ {
62
+ padding-bottom: 5px;
63
+ display: inline-block;
64
+ }
65
+
66
+ .instapage-cms-plugin td .variation div:nth-of-type(2),
67
+ .instapage-cms-plugin td .variation div:nth-of-type(3)
68
+ {
69
+ background-color: #F2F7F9;
70
+ }
71
+
72
+ .instapage-cms-plugin .variation-conversion-rate
73
+ {
74
+ margin-top: 5px;
75
+ }
76
+
77
+ .instapage-cms-plugin .variation-stats
78
+ {
79
+ padding: 4px;
80
+ border-radius: 3px;
81
+ }
82
+
83
+ .instapage-cms-plugin .c-table__cell img
84
+ {
85
+ margin: 10px 0;
86
+ }
87
+
88
+ .instapage-cms-plugin h2
89
+ {
90
+ text-align: center;
91
+ border: none;
92
+ }
93
+
94
+ .instapage-cms-plugin .instapage-content input[type=password]
95
+ {
96
+ border: none;
97
+ box-shadow: none;
98
+ border-bottom: 1px solid #ddd;
99
+ }
100
+
101
+ .instapage-cms-plugin input[type=text],
102
+ .instapage-cms-plugin input[type=text]:focus
103
+ {
104
+ border: none;
105
+ box-shadow: none;
106
+ border-bottom: 1px solid #ddd;
107
+ background: none;
108
+ }
109
+
110
+ .instapage-cms-plugin .c-modal
111
+ {
112
+ line-height: 1.5;
113
+ width: 80%;
114
+ position: relative;
115
+ margin-bottom: 10px;
116
+ }
117
+
118
+ .instapage-cms-plugin label
119
+ {
120
+ cursor: default;
121
+ padding-left: 5px;
122
+ margin-bottom: 10px;
123
+ }
124
+
125
+ .instapage-cms-plugin select
126
+ {
127
+ box-shadow: none;
128
+ }
129
+
130
+ .instapage-cms-plugin .los-pollos.c-form-text-item
131
+ {
132
+ display: inline-flex;
133
+ flex-direction: row;
134
+ justify-content: flex-start;
135
+ align-items: flex-start;
136
+ margin-top: 20px;
137
+ }
138
+
139
+ .instapage-cms-plugin .los-pollos span.c-form-text-item__info
140
+ {
141
+ font-size: 14px;
142
+ width: 31%;
143
+ display: block;
144
+ position: initial;
145
+ text-align: right;
146
+ padding-top: 10px;
147
+ }
148
+
149
+ .instapage-cms-plugin .los-pollos span.c-form-text-item__info.slug
150
+ {
151
+ text-align: left;
152
+ padding-top: 0;
153
+ display: flex;
154
+ justify-content: space-between;
155
+ align-content: center;
156
+ width: 100%;
157
+ }
158
+
159
+ .instapage-cms-plugin .los-pollos > div
160
+ {
161
+ width: 68%;
162
+ display: block;
163
+ margin-left: 30px;
164
+ }
165
+
166
+ .instapage-cms-plugin .los-pollos > div > label
167
+ {
168
+ left: 340px;
169
+ }
170
+
171
+ .instapage-cms-plugin .tokens-container
172
+ {
173
+ padding-top: 15px;
174
+ }
175
+
176
+ .instapage-cms-plugin .tokens-container table tbody td
177
+ {
178
+ padding-top: 20px;
179
+ }
180
+
181
+ .instapage-cms-plugin .c-table__cell:first-child
182
+ {
183
+ padding-left: 15px;
184
+ }
185
+
186
+ .instapage-cms-plugin .c-table__cell:last-child
187
+ {
188
+ padding-right: 15px;
189
+ }
190
+
191
+ .instapage-cms-plugin .page-loader
192
+ {
193
+ text-align: center;
194
+ }
195
+
196
+ .instapage-cms-plugin .diagnostic-mode-on .diagnostic-mode-warning
197
+ {
198
+ font-weight: 600;
199
+ color: #cc0000;
200
+ }
assets/css/mrwhite-reset.css ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .instapage-cms-plugin .ui-title,
2
+ .instapage-cms-plugin .ui-subtitle {
3
+ display: inline-block;
4
+ width: 100%; }
5
+
6
+ .instapage-cms-plugin .ui-title {
7
+ font-size: 40px;
8
+ line-height: 180%;
9
+ border-bottom: 1px solid #dde4ea;
10
+ margin: 0 0 15px 0; }
11
+
12
+ .instapage-cms-plugin .ui-subtitle {
13
+ font-size: 22px;
14
+ line-height: 150%;
15
+ margin: 5px 0 10px 0;
16
+ padding: 0;
17
+ font-weight: normal; }
18
+
19
+ .instapage-cms-plugin .ui-section {
20
+ margin-bottom: 35px; }
21
+
22
+ .instapage-cms-plugin .ui-sub-section {
23
+ margin-bottom: 10px; }
24
+
25
+ .instapage-cms-plugin .ui-space {
26
+ padding: 20px; }
27
+
28
+ .instapage-cms-plugin .ui-paragraph {
29
+ margin-bottom: 30px; }
30
+
31
+ .instapage-cms-plugin .ui-code {
32
+ font-family: monospace;
33
+ background-color: #f4f4f4; }
34
+
35
+ .instapage-cms-plugin .ui-warning {
36
+ color: #c00; }
37
+
38
+ .instapage-cms-plugin .ui-sample-background {
39
+ background-color: #f4f4f4; }
40
+
41
+ .instapage-cms-plugin .ui-fixed-width-200 {
42
+ flex: 0 0 200px; }
43
+
44
+ .instapage-cms-plugin strong {
45
+ font-weight: bold; }
46
+
47
+ .instapage-cms-plugin .ui-grid--cell {
48
+ text-align: center;
49
+ line-height: 35px;
50
+ font-size: 11px; }
51
+
52
+ .instapage-cms-plugin input {
53
+ background: none; }
54
+
55
+ .instapage-cms-plugin input[readonly] {
56
+ background-color: #fff; }
57
+
58
+ .instapage-cms-plugin table,
59
+ .instapage-cms-plugin table tr,
60
+ .instapage-cms-plugin table tr th,
61
+ .instapage-cms-plugin table tr th:hover {
62
+ background-color: #fff;
63
+ color: #90a4ae;
64
+ font-weight: normal;
65
+ text-transform: none;
66
+ }
67
+
68
+ .instapage-cms-plugin table tr td,
69
+ .instapage-cms-plugin table tr td:hover {
70
+ color: #37475a; }
71
+
72
+ .instapage-cms-plugin select,
73
+ .instapage-cms-plugin select:hover,
74
+ .instapage-cms-plugin select:active,
75
+ .instapage-cms-plugin select:focus {
76
+ background: none;
77
+ appearance: normal;
78
+ -webkit-appearance: menulist;
79
+ -moz-appearance: menulist; }
80
+
81
+ .instapage-cms-plugin ul,
82
+ .block .instapage-cms-plugin ul,
83
+ .item-list .instapage-cms-plugin ul {
84
+ list-style-type: none;
85
+ list-style-image: none; }
86
+
87
+ .instapage-cms-plugin .notice-error,
88
+ .instapage-cms-plugin div.error,
89
+ .instapage-cms-plugin div.updated {
90
+ background: none;
91
+ border: none;
92
+ -webkit-box-shadow: none;
93
+ box-shadow: none;
94
+ padding-bottom: 30px;
95
+ }
assets/css/mrwhite-ui-kit.css ADDED
@@ -0,0 +1,5670 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*------------------------------------* Grid
2
+ \*------------------------------------*/
3
+ /*------------------------------------* Color Palette
4
+ \*------------------------------------*/
5
+ /*------------------------------------* Font Settings
6
+ \*------------------------------------*/
7
+ /*------------------------------------* Spacings
8
+ \*------------------------------------*/
9
+ /*------------------------------------* Box Shadows
10
+ \*------------------------------------*/
11
+ /*------------------------------------* Borders
12
+ \*------------------------------------*/
13
+ /*------------------------------------* Tranistions
14
+ \*------------------------------------*/
15
+ /*------------------------------------* Z-index
16
+ \*------------------------------------*/
17
+ /*------------------------------------* SVG
18
+ \*------------------------------------*/
19
+ /*
20
+ Used by buttons and pagination links
21
+ */
22
+ /*
23
+ Idea of this mixin is to output `border-radius` property for each corner separately.
24
+ If you want to target all corners it's better to use the standard CSS `border-radius` shorthand.
25
+
26
+ Note
27
+ If `$radius` parameter equals `null` it won't be generated.
28
+
29
+ Example 1
30
+ input `.clazz {@include radius( null, null, 0, 10px )}`
31
+ output `.clazz {border-bottom-right-radius: 0; border-bottom-left-radius: 10px;}`
32
+
33
+ Example 2
34
+ input `.clazz {@include radius( 10px, 1px )}`
35
+ output `.clazz {border-top-left-radius: 10px; border-top-right-radius: 1px;}`
36
+ */
37
+ /*
38
+ Used by buttons and pagination links
39
+ */
40
+ /*
41
+ Hides element from being displayed, but lets screen readers read it
42
+ */
43
+ /*------------------------------------* Reset
44
+ \*------------------------------------*/
45
+ /* http://meyerweb.com/eric/tools/css/reset/
46
+ v2.0 | 20110126
47
+ License: none (public domain)
48
+ */
49
+ html, body, div, span, applet, object, iframe,
50
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
51
+ a, abbr, acronym, address, big, cite, code,
52
+ del, dfn, em, img, ins, kbd, q, s, samp,
53
+ small, strike, strong, sub, sup, tt, var,
54
+ b, u, i, center,
55
+ dl, dt, dd, ol, ul, li,
56
+ fieldset, form, label, legend,
57
+ table, caption, tbody, tfoot, thead, tr, th, td,
58
+ article, aside, canvas, details, embed,
59
+ figure, figcaption, footer, header, hgroup,
60
+ menu, nav, output, ruby, section, summary,
61
+ time, mark, audio, video {
62
+ margin: 0;
63
+ padding: 0;
64
+ border: 0;
65
+ font-size: 100%;
66
+ font: inherit;
67
+ vertical-align: baseline; }
68
+
69
+ /* HTML5 display-role reset for older browsers */
70
+ article, aside, details, figcaption, figure,
71
+ footer, header, hgroup, menu, nav, section {
72
+ display: block; }
73
+
74
+ body {
75
+ line-height: 1; }
76
+
77
+ ol, ul {
78
+ list-style: none; }
79
+
80
+ blockquote, q {
81
+ quotes: none; }
82
+
83
+ blockquote:before, blockquote:after,
84
+ q:before, q:after {
85
+ content: '';
86
+ content: none; }
87
+
88
+ table {
89
+ border-collapse: collapse;
90
+ border-spacing: 0; }
91
+
92
+ /*------------------------------------* Global
93
+ \*------------------------------------*/
94
+ html {
95
+ -webkit-box-sizing: border-box;
96
+ -moz-box-sizing: border-box;
97
+ box-sizing: border-box; }
98
+
99
+ *,
100
+ *:before,
101
+ *:after {
102
+ -webkit-box-sizing: inherit;
103
+ -moz-box-sizing: inherit;
104
+ box-sizing: inherit; }
105
+
106
+ body {
107
+ font: 16px "Robotox", sans-serif;
108
+ line-height: 1.1;
109
+ color: #37475a; }
110
+
111
+ p + p {
112
+ padding-top: 10px; }
113
+
114
+ /*------------------------------------* Roboto (regular and medium variant)
115
+ \*------------------------------------*/
116
+ @font-face {
117
+ font-family: 'Robotox';
118
+ src: url("//storage.googleapis.com/instapage-app-assets/1468855493_roboto-regular-webfont.eot") format("embedded-opentype"), url("//storage.googleapis.com/instapage-app-assets/1468855553_roboto-regular-webfont.woff") format("woff"), url("//storage.googleapis.com/instapage-app-assets/1468855534_roboto-regular-webfont.ttf") format("truetype"), url("//storage.googleapis.com/instapage-app-assets/1468855517_roboto-regular-webfont.svg") format("svg");
119
+ font-weight: 400;
120
+ font-style: normal; }
121
+
122
+ @font-face {
123
+ font-family: 'Robotox';
124
+ src: url("//storage.googleapis.com/instapage-app-assets/1468855289_roboto-medium-webfont.eot") format("embedded-opentype"), url("//storage.googleapis.com/instapage-app-assets/1468855454_roboto-medium-webfont.woff") format("woff"), url("//storage.googleapis.com/instapage-app-assets/1468855423_roboto-medium-webfont.ttf") format("truetype"), url("//storage.googleapis.com/instapage-app-assets/1468855328_roboto-medium-webfont.svg") format("svg");
125
+ font-weight: 600;
126
+ font-style: normal; }
127
+
128
+ /*------------------------------------* Material Icons
129
+ \*------------------------------------*/
130
+ @font-face {
131
+ font-family: 'Material Icons';
132
+ src: url("//storage.googleapis.com/instapage-app-assets/1468855067_materialicons-regular.eot"), url("//storage.googleapis.com/instapage-app-assets/1468855237_materialicons-regular.woff2") format("woff2"), url("//storage.googleapis.com/instapage-app-assets/1468855192_materialicons-regular.woff") format("woff"), url("//storage.googleapis.com/instapage-app-assets/1468855151_materialicons-regular.ttf") format("truetype");
133
+ font-style: normal;
134
+ font-weight: 400; }
135
+
136
+ .material-icons {
137
+ font-family: 'Material Icons';
138
+ font-weight: normal;
139
+ font-style: normal;
140
+ font-size: 18px;
141
+ line-height: 1;
142
+ text-transform: none;
143
+ letter-spacing: normal;
144
+ word-wrap: normal;
145
+ white-space: nowrap;
146
+ display: inline-block;
147
+ direction: ltr;
148
+ -webkit-font-smoothing: antialiased;
149
+ text-rendering: optimizeLegibility;
150
+ -moz-osx-font-smoothing: grayscale;
151
+ -webkit-font-feature-settings: 'liga';
152
+ -moz-font-feature-settings: 'liga';
153
+ font-feature-settings: 'liga'; }
154
+
155
+ /*------------------------------------* #HEADING
156
+ \*------------------------------------*/
157
+ h1 {
158
+ font-size: 20px;
159
+ line-height: 28px; }
160
+
161
+ h2 {
162
+ font-size: 18px;
163
+ line-height: 26px; }
164
+
165
+ /*------------------------------------* #PARAGRAPH
166
+ \*------------------------------------*/
167
+ p {
168
+ line-height: 1.5; }
169
+
170
+ /*------------------------------------* #TEXT MODIFIERS
171
+ \*------------------------------------*/
172
+ strong {
173
+ font-weight: 600; }
174
+
175
+ /*------------------------------------* #LINK
176
+ \*------------------------------------*/
177
+ a {
178
+ color: #1e88e5;
179
+ text-decoration: none; }
180
+ a:hover {
181
+ text-decoration: underline; }
182
+
183
+ /*
184
+ http://colourgarden.net/avalanche/
185
+ http://flexboxgrid.com/
186
+
187
+ https://github.com/colourgarden/avalanche
188
+ https://github.com/kristoferjoseph/flexboxgrid
189
+
190
+ two solutions merged into one:
191
+ - mixinin, breakpoints, loops taken from avalanche
192
+ - flexbox solutions taken from flexboxgrid
193
+ */
194
+ /*------------------------------------* SETTINGS
195
+ \*------------------------------------*/
196
+ /*------------------------------------* LOGIC aka THE MAGIC
197
+ \*------------------------------------*/
198
+ /*------------------------------------* GRID LAYOUT
199
+ \*------------------------------------*/
200
+ .l-grid {
201
+ -webkit-box-sizing: border-box;
202
+ -moz-box-sizing: border-box;
203
+ box-sizing: border-box;
204
+ display: -webkit-box;
205
+ display: -webkit-flex;
206
+ display: -moz-box;
207
+ display: -ms-flexbox;
208
+ display: flex;
209
+ -webkit-box-flex: 0;
210
+ -webkit-flex: 0 1 auto;
211
+ -moz-box-flex: 0;
212
+ -ms-flex: 0 1 auto;
213
+ flex: 0 1 auto;
214
+ -webkit-box-orient: horizontal;
215
+ -webkit-box-direction: normal;
216
+ -webkit-flex-direction: row;
217
+ -moz-box-orient: horizontal;
218
+ -moz-box-direction: normal;
219
+ -ms-flex-direction: row;
220
+ flex-direction: row;
221
+ -webkit-flex-wrap: wrap;
222
+ -ms-flex-wrap: wrap;
223
+ flex-wrap: wrap;
224
+ margin-left: -30px; }
225
+
226
+ .l-grid__cell {
227
+ -webkit-box-flex: 1;
228
+ -webkit-flex-grow: 1;
229
+ -moz-box-flex: 1;
230
+ -ms-flex-positive: 1;
231
+ flex-grow: 1;
232
+ -webkit-flex-basis: 100%;
233
+ -ms-flex-preferred-size: 100%;
234
+ flex-basis: 100%;
235
+ max-width: 100%;
236
+ padding-left: 30px; }
237
+
238
+ /*------------------------------------*GRID MODIFIERS
239
+ \*------------------------------------*/
240
+ /*------------------------------------* GRID
241
+ \*------------------------------------*/
242
+ .l-grid__cell--1\/2, .l-grid__cell--2\/4, .l-grid__cell--3\/6, .l-grid__cell--4\/8, .l-grid__cell--5\/10, .l-grid__cell--6\/12, .l-grid__cell--7\/14, .l-grid__cell--8\/16 {
243
+ max-width: 50%;
244
+ -webkit-box-flex: 0;
245
+ -webkit-flex: 0 0 50%;
246
+ -moz-box-flex: 0;
247
+ -ms-flex: 0 0 50%;
248
+ flex: 0 0 50%; }
249
+
250
+ .l-grid__cell--1\/3, .l-grid__cell--2\/6, .l-grid__cell--4\/12 {
251
+ max-width: 33.33333%;
252
+ -webkit-box-flex: 0;
253
+ -webkit-flex: 0 0 33.33333%;
254
+ -moz-box-flex: 0;
255
+ -ms-flex: 0 0 33.33333%;
256
+ flex: 0 0 33.33333%; }
257
+
258
+ .l-grid__cell--2\/3, .l-grid__cell--4\/6, .l-grid__cell--8\/12 {
259
+ max-width: 66.66667%;
260
+ -webkit-box-flex: 0;
261
+ -webkit-flex: 0 0 66.66667%;
262
+ -moz-box-flex: 0;
263
+ -ms-flex: 0 0 66.66667%;
264
+ flex: 0 0 66.66667%; }
265
+
266
+ .l-grid__cell--1\/4, .l-grid__cell--2\/8, .l-grid__cell--3\/12, .l-grid__cell--4\/16 {
267
+ max-width: 25%;
268
+ -webkit-box-flex: 0;
269
+ -webkit-flex: 0 0 25%;
270
+ -moz-box-flex: 0;
271
+ -ms-flex: 0 0 25%;
272
+ flex: 0 0 25%; }
273
+
274
+ .l-grid__cell--3\/4, .l-grid__cell--6\/8, .l-grid__cell--9\/12, .l-grid__cell--12\/16 {
275
+ max-width: 75%;
276
+ -webkit-box-flex: 0;
277
+ -webkit-flex: 0 0 75%;
278
+ -moz-box-flex: 0;
279
+ -ms-flex: 0 0 75%;
280
+ flex: 0 0 75%; }
281
+
282
+ .l-grid__cell--1\/5, .l-grid__cell--2\/10 {
283
+ max-width: 20%;
284
+ -webkit-box-flex: 0;
285
+ -webkit-flex: 0 0 20%;
286
+ -moz-box-flex: 0;
287
+ -ms-flex: 0 0 20%;
288
+ flex: 0 0 20%; }
289
+
290
+ .l-grid__cell--2\/5, .l-grid__cell--4\/10 {
291
+ max-width: 40%;
292
+ -webkit-box-flex: 0;
293
+ -webkit-flex: 0 0 40%;
294
+ -moz-box-flex: 0;
295
+ -ms-flex: 0 0 40%;
296
+ flex: 0 0 40%; }
297
+
298
+ .l-grid__cell--3\/5, .l-grid__cell--6\/10 {
299
+ max-width: 60%;
300
+ -webkit-box-flex: 0;
301
+ -webkit-flex: 0 0 60%;
302
+ -moz-box-flex: 0;
303
+ -ms-flex: 0 0 60%;
304
+ flex: 0 0 60%; }
305
+
306
+ .l-grid__cell--4\/5, .l-grid__cell--8\/10 {
307
+ max-width: 80%;
308
+ -webkit-box-flex: 0;
309
+ -webkit-flex: 0 0 80%;
310
+ -moz-box-flex: 0;
311
+ -ms-flex: 0 0 80%;
312
+ flex: 0 0 80%; }
313
+
314
+ .l-grid__cell--1\/6, .l-grid__cell--2\/12 {
315
+ max-width: 16.66667%;
316
+ -webkit-box-flex: 0;
317
+ -webkit-flex: 0 0 16.66667%;
318
+ -moz-box-flex: 0;
319
+ -ms-flex: 0 0 16.66667%;
320
+ flex: 0 0 16.66667%; }
321
+
322
+ .l-grid__cell--5\/6, .l-grid__cell--10\/12 {
323
+ max-width: 83.33333%;
324
+ -webkit-box-flex: 0;
325
+ -webkit-flex: 0 0 83.33333%;
326
+ -moz-box-flex: 0;
327
+ -ms-flex: 0 0 83.33333%;
328
+ flex: 0 0 83.33333%; }
329
+
330
+ .l-grid__cell--1\/8, .l-grid__cell--2\/16 {
331
+ max-width: 12.5%;
332
+ -webkit-box-flex: 0;
333
+ -webkit-flex: 0 0 12.5%;
334
+ -moz-box-flex: 0;
335
+ -ms-flex: 0 0 12.5%;
336
+ flex: 0 0 12.5%; }
337
+
338
+ .l-grid__cell--3\/8, .l-grid__cell--6\/16 {
339
+ max-width: 37.5%;
340
+ -webkit-box-flex: 0;
341
+ -webkit-flex: 0 0 37.5%;
342
+ -moz-box-flex: 0;
343
+ -ms-flex: 0 0 37.5%;
344
+ flex: 0 0 37.5%; }
345
+
346
+ .l-grid__cell--5\/8, .l-grid__cell--10\/16 {
347
+ max-width: 62.5%;
348
+ -webkit-box-flex: 0;
349
+ -webkit-flex: 0 0 62.5%;
350
+ -moz-box-flex: 0;
351
+ -ms-flex: 0 0 62.5%;
352
+ flex: 0 0 62.5%; }
353
+
354
+ .l-grid__cell--7\/8, .l-grid__cell--14\/16 {
355
+ max-width: 87.5%;
356
+ -webkit-box-flex: 0;
357
+ -webkit-flex: 0 0 87.5%;
358
+ -moz-box-flex: 0;
359
+ -ms-flex: 0 0 87.5%;
360
+ flex: 0 0 87.5%; }
361
+
362
+ .l-grid__cell--1\/10 {
363
+ max-width: 10%;
364
+ -webkit-box-flex: 0;
365
+ -webkit-flex: 0 0 10%;
366
+ -moz-box-flex: 0;
367
+ -ms-flex: 0 0 10%;
368
+ flex: 0 0 10%; }
369
+
370
+ .l-grid__cell--3\/10 {
371
+ max-width: 30%;
372
+ -webkit-box-flex: 0;
373
+ -webkit-flex: 0 0 30%;
374
+ -moz-box-flex: 0;
375
+ -ms-flex: 0 0 30%;
376
+ flex: 0 0 30%; }
377
+
378
+ .l-grid__cell--7\/10 {
379
+ max-width: 70%;
380
+ -webkit-box-flex: 0;
381
+ -webkit-flex: 0 0 70%;
382
+ -moz-box-flex: 0;
383
+ -ms-flex: 0 0 70%;
384
+ flex: 0 0 70%; }
385
+
386
+ .l-grid__cell--9\/10 {
387
+ max-width: 90%;
388
+ -webkit-box-flex: 0;
389
+ -webkit-flex: 0 0 90%;
390
+ -moz-box-flex: 0;
391
+ -ms-flex: 0 0 90%;
392
+ flex: 0 0 90%; }
393
+
394
+ .l-grid__cell--1\/12 {
395
+ max-width: 8.33333%;
396
+ -webkit-box-flex: 0;
397
+ -webkit-flex: 0 0 8.33333%;
398
+ -moz-box-flex: 0;
399
+ -ms-flex: 0 0 8.33333%;
400
+ flex: 0 0 8.33333%; }
401
+
402
+ .l-grid__cell--5\/12 {
403
+ max-width: 41.66667%;
404
+ -webkit-box-flex: 0;
405
+ -webkit-flex: 0 0 41.66667%;
406
+ -moz-box-flex: 0;
407
+ -ms-flex: 0 0 41.66667%;
408
+ flex: 0 0 41.66667%; }
409
+
410
+ .l-grid__cell--7\/12 {
411
+ max-width: 58.33333%;
412
+ -webkit-box-flex: 0;
413
+ -webkit-flex: 0 0 58.33333%;
414
+ -moz-box-flex: 0;
415
+ -ms-flex: 0 0 58.33333%;
416
+ flex: 0 0 58.33333%; }
417
+
418
+ .l-grid__cell--11\/12 {
419
+ max-width: 91.66667%;
420
+ -webkit-box-flex: 0;
421
+ -webkit-flex: 0 0 91.66667%;
422
+ -moz-box-flex: 0;
423
+ -ms-flex: 0 0 91.66667%;
424
+ flex: 0 0 91.66667%; }
425
+
426
+ .l-grid__cell--1\/14 {
427
+ max-width: 7.14286%;
428
+ -webkit-box-flex: 0;
429
+ -webkit-flex: 0 0 7.14286%;
430
+ -moz-box-flex: 0;
431
+ -ms-flex: 0 0 7.14286%;
432
+ flex: 0 0 7.14286%; }
433
+
434
+ .l-grid__cell--2\/14 {
435
+ max-width: 14.28571%;
436
+ -webkit-box-flex: 0;
437
+ -webkit-flex: 0 0 14.28571%;
438
+ -moz-box-flex: 0;
439
+ -ms-flex: 0 0 14.28571%;
440
+ flex: 0 0 14.28571%; }
441
+
442
+ .l-grid__cell--3\/14 {
443
+ max-width: 21.42857%;
444
+ -webkit-box-flex: 0;
445
+ -webkit-flex: 0 0 21.42857%;
446
+ -moz-box-flex: 0;
447
+ -ms-flex: 0 0 21.42857%;
448
+ flex: 0 0 21.42857%; }
449
+
450
+ .l-grid__cell--4\/14 {
451
+ max-width: 28.57143%;
452
+ -webkit-box-flex: 0;
453
+ -webkit-flex: 0 0 28.57143%;
454
+ -moz-box-flex: 0;
455
+ -ms-flex: 0 0 28.57143%;
456
+ flex: 0 0 28.57143%; }
457
+
458
+ .l-grid__cell--5\/14 {
459
+ max-width: 35.71429%;
460
+ -webkit-box-flex: 0;
461
+ -webkit-flex: 0 0 35.71429%;
462
+ -moz-box-flex: 0;
463
+ -ms-flex: 0 0 35.71429%;
464
+ flex: 0 0 35.71429%; }
465
+
466
+ .l-grid__cell--6\/14 {
467
+ max-width: 42.85714%;
468
+ -webkit-box-flex: 0;
469
+ -webkit-flex: 0 0 42.85714%;
470
+ -moz-box-flex: 0;
471
+ -ms-flex: 0 0 42.85714%;
472
+ flex: 0 0 42.85714%; }
473
+
474
+ .l-grid__cell--8\/14 {
475
+ max-width: 57.14286%;
476
+ -webkit-box-flex: 0;
477
+ -webkit-flex: 0 0 57.14286%;
478
+ -moz-box-flex: 0;
479
+ -ms-flex: 0 0 57.14286%;
480
+ flex: 0 0 57.14286%; }
481
+
482
+ .l-grid__cell--9\/14 {
483
+ max-width: 64.28571%;
484
+ -webkit-box-flex: 0;
485
+ -webkit-flex: 0 0 64.28571%;
486
+ -moz-box-flex: 0;
487
+ -ms-flex: 0 0 64.28571%;
488
+ flex: 0 0 64.28571%; }
489
+
490
+ .l-grid__cell--10\/14 {
491
+ max-width: 71.42857%;
492
+ -webkit-box-flex: 0;
493
+ -webkit-flex: 0 0 71.42857%;
494
+ -moz-box-flex: 0;
495
+ -ms-flex: 0 0 71.42857%;
496
+ flex: 0 0 71.42857%; }
497
+
498
+ .l-grid__cell--11\/14 {
499
+ max-width: 78.57143%;
500
+ -webkit-box-flex: 0;
501
+ -webkit-flex: 0 0 78.57143%;
502
+ -moz-box-flex: 0;
503
+ -ms-flex: 0 0 78.57143%;
504
+ flex: 0 0 78.57143%; }
505
+
506
+ .l-grid__cell--12\/14 {
507
+ max-width: 85.71429%;
508
+ -webkit-box-flex: 0;
509
+ -webkit-flex: 0 0 85.71429%;
510
+ -moz-box-flex: 0;
511
+ -ms-flex: 0 0 85.71429%;
512
+ flex: 0 0 85.71429%; }
513
+
514
+ .l-grid__cell--13\/14 {
515
+ max-width: 92.85714%;
516
+ -webkit-box-flex: 0;
517
+ -webkit-flex: 0 0 92.85714%;
518
+ -moz-box-flex: 0;
519
+ -ms-flex: 0 0 92.85714%;
520
+ flex: 0 0 92.85714%; }
521
+
522
+ .l-grid__cell--1\/16 {
523
+ max-width: 6.25%;
524
+ -webkit-box-flex: 0;
525
+ -webkit-flex: 0 0 6.25%;
526
+ -moz-box-flex: 0;
527
+ -ms-flex: 0 0 6.25%;
528
+ flex: 0 0 6.25%; }
529
+
530
+ .l-grid__cell--3\/16 {
531
+ max-width: 18.75%;
532
+ -webkit-box-flex: 0;
533
+ -webkit-flex: 0 0 18.75%;
534
+ -moz-box-flex: 0;
535
+ -ms-flex: 0 0 18.75%;
536
+ flex: 0 0 18.75%; }
537
+
538
+ .l-grid__cell--5\/16 {
539
+ max-width: 31.25%;
540
+ -webkit-box-flex: 0;
541
+ -webkit-flex: 0 0 31.25%;
542
+ -moz-box-flex: 0;
543
+ -ms-flex: 0 0 31.25%;
544
+ flex: 0 0 31.25%; }
545
+
546
+ .l-grid__cell--7\/16 {
547
+ max-width: 43.75%;
548
+ -webkit-box-flex: 0;
549
+ -webkit-flex: 0 0 43.75%;
550
+ -moz-box-flex: 0;
551
+ -ms-flex: 0 0 43.75%;
552
+ flex: 0 0 43.75%; }
553
+
554
+ .l-grid__cell--9\/16 {
555
+ max-width: 56.25%;
556
+ -webkit-box-flex: 0;
557
+ -webkit-flex: 0 0 56.25%;
558
+ -moz-box-flex: 0;
559
+ -ms-flex: 0 0 56.25%;
560
+ flex: 0 0 56.25%; }
561
+
562
+ .l-grid__cell--11\/16 {
563
+ max-width: 68.75%;
564
+ -webkit-box-flex: 0;
565
+ -webkit-flex: 0 0 68.75%;
566
+ -moz-box-flex: 0;
567
+ -ms-flex: 0 0 68.75%;
568
+ flex: 0 0 68.75%; }
569
+
570
+ .l-grid__cell--13\/16 {
571
+ max-width: 81.25%;
572
+ -webkit-box-flex: 0;
573
+ -webkit-flex: 0 0 81.25%;
574
+ -moz-box-flex: 0;
575
+ -ms-flex: 0 0 81.25%;
576
+ flex: 0 0 81.25%; }
577
+
578
+ .l-grid__cell--15\/16 {
579
+ max-width: 93.75%;
580
+ -webkit-box-flex: 0;
581
+ -webkit-flex: 0 0 93.75%;
582
+ -moz-box-flex: 0;
583
+ -ms-flex: 0 0 93.75%;
584
+ flex: 0 0 93.75%; }
585
+
586
+ .l-grid--hor-center {
587
+ -webkit-box-pack: center;
588
+ -webkit-justify-content: center;
589
+ -moz-box-pack: center;
590
+ -ms-flex-pack: center;
591
+ justify-content: center; }
592
+
593
+ .l-grid--hor-right {
594
+ -webkit-box-pack: end;
595
+ -webkit-justify-content: flex-end;
596
+ -moz-box-pack: end;
597
+ -ms-flex-pack: end;
598
+ justify-content: flex-end; }
599
+
600
+ .l-grid--ver-center {
601
+ -webkit-box-align: center;
602
+ -webkit-align-items: center;
603
+ -moz-box-align: center;
604
+ -ms-flex-align: center;
605
+ align-items: center; }
606
+
607
+ .l-grid--ver-bottom {
608
+ -webkit-box-align: end;
609
+ -webkit-align-items: flex-end;
610
+ -moz-box-align: end;
611
+ -ms-flex-align: end;
612
+ align-items: flex-end; }
613
+
614
+ .l-grid--auto > .l-grid__cell {
615
+ -webkit-flex-basis: 0;
616
+ -ms-flex-preferred-size: 0;
617
+ flex-basis: 0; }
618
+
619
+ @media screen and (max-width: 800px) {
620
+ .l-grid__cell--1\/2--handheld, .l-grid__cell--2\/4--handheld, .l-grid__cell--3\/6--handheld, .l-grid__cell--4\/8--handheld, .l-grid__cell--5\/10--handheld, .l-grid__cell--6\/12--handheld, .l-grid__cell--7\/14--handheld, .l-grid__cell--8\/16--handheld {
621
+ max-width: 50%;
622
+ -webkit-box-flex: 0;
623
+ -webkit-flex: 0 0 50%;
624
+ -moz-box-flex: 0;
625
+ -ms-flex: 0 0 50%;
626
+ flex: 0 0 50%; }
627
+ .l-grid__cell--1\/3--handheld, .l-grid__cell--2\/6--handheld, .l-grid__cell--4\/12--handheld {
628
+ max-width: 33.33333%;
629
+ -webkit-box-flex: 0;
630
+ -webkit-flex: 0 0 33.33333%;
631
+ -moz-box-flex: 0;
632
+ -ms-flex: 0 0 33.33333%;
633
+ flex: 0 0 33.33333%; }
634
+ .l-grid__cell--2\/3--handheld, .l-grid__cell--4\/6--handheld, .l-grid__cell--8\/12--handheld {
635
+ max-width: 66.66667%;
636
+ -webkit-box-flex: 0;
637
+ -webkit-flex: 0 0 66.66667%;
638
+ -moz-box-flex: 0;
639
+ -ms-flex: 0 0 66.66667%;
640
+ flex: 0 0 66.66667%; }
641
+ .l-grid__cell--1\/4--handheld, .l-grid__cell--2\/8--handheld, .l-grid__cell--3\/12--handheld, .l-grid__cell--4\/16--handheld {
642
+ max-width: 25%;
643
+ -webkit-box-flex: 0;
644
+ -webkit-flex: 0 0 25%;
645
+ -moz-box-flex: 0;
646
+ -ms-flex: 0 0 25%;
647
+ flex: 0 0 25%; }
648
+ .l-grid__cell--3\/4--handheld, .l-grid__cell--6\/8--handheld, .l-grid__cell--9\/12--handheld, .l-grid__cell--12\/16--handheld {
649
+ max-width: 75%;
650
+ -webkit-box-flex: 0;
651
+ -webkit-flex: 0 0 75%;
652
+ -moz-box-flex: 0;
653
+ -ms-flex: 0 0 75%;
654
+ flex: 0 0 75%; }
655
+ .l-grid__cell--1\/5--handheld, .l-grid__cell--2\/10--handheld {
656
+ max-width: 20%;
657
+ -webkit-box-flex: 0;
658
+ -webkit-flex: 0 0 20%;
659
+ -moz-box-flex: 0;
660
+ -ms-flex: 0 0 20%;
661
+ flex: 0 0 20%; }
662
+ .l-grid__cell--2\/5--handheld, .l-grid__cell--4\/10--handheld {
663
+ max-width: 40%;
664
+ -webkit-box-flex: 0;
665
+ -webkit-flex: 0 0 40%;
666
+ -moz-box-flex: 0;
667
+ -ms-flex: 0 0 40%;
668
+ flex: 0 0 40%; }
669
+ .l-grid__cell--3\/5--handheld, .l-grid__cell--6\/10--handheld {
670
+ max-width: 60%;
671
+ -webkit-box-flex: 0;
672
+ -webkit-flex: 0 0 60%;
673
+ -moz-box-flex: 0;
674
+ -ms-flex: 0 0 60%;
675
+ flex: 0 0 60%; }
676
+ .l-grid__cell--4\/5--handheld, .l-grid__cell--8\/10--handheld {
677
+ max-width: 80%;
678
+ -webkit-box-flex: 0;
679
+ -webkit-flex: 0 0 80%;
680
+ -moz-box-flex: 0;
681
+ -ms-flex: 0 0 80%;
682
+ flex: 0 0 80%; }
683
+ .l-grid__cell--1\/6--handheld, .l-grid__cell--2\/12--handheld {
684
+ max-width: 16.66667%;
685
+ -webkit-box-flex: 0;
686
+ -webkit-flex: 0 0 16.66667%;
687
+ -moz-box-flex: 0;
688
+ -ms-flex: 0 0 16.66667%;
689
+ flex: 0 0 16.66667%; }
690
+ .l-grid__cell--5\/6--handheld, .l-grid__cell--10\/12--handheld {
691
+ max-width: 83.33333%;
692
+ -webkit-box-flex: 0;
693
+ -webkit-flex: 0 0 83.33333%;
694
+ -moz-box-flex: 0;
695
+ -ms-flex: 0 0 83.33333%;
696
+ flex: 0 0 83.33333%; }
697
+ .l-grid__cell--1\/8--handheld, .l-grid__cell--2\/16--handheld {
698
+ max-width: 12.5%;
699
+ -webkit-box-flex: 0;
700
+ -webkit-flex: 0 0 12.5%;
701
+ -moz-box-flex: 0;
702
+ -ms-flex: 0 0 12.5%;
703
+ flex: 0 0 12.5%; }
704
+ .l-grid__cell--3\/8--handheld, .l-grid__cell--6\/16--handheld {
705
+ max-width: 37.5%;
706
+ -webkit-box-flex: 0;
707
+ -webkit-flex: 0 0 37.5%;
708
+ -moz-box-flex: 0;
709
+ -ms-flex: 0 0 37.5%;
710
+ flex: 0 0 37.5%; }
711
+ .l-grid__cell--5\/8--handheld, .l-grid__cell--10\/16--handheld {
712
+ max-width: 62.5%;
713
+ -webkit-box-flex: 0;
714
+ -webkit-flex: 0 0 62.5%;
715
+ -moz-box-flex: 0;
716
+ -ms-flex: 0 0 62.5%;
717
+ flex: 0 0 62.5%; }
718
+ .l-grid__cell--7\/8--handheld, .l-grid__cell--14\/16--handheld {
719
+ max-width: 87.5%;
720
+ -webkit-box-flex: 0;
721
+ -webkit-flex: 0 0 87.5%;
722
+ -moz-box-flex: 0;
723
+ -ms-flex: 0 0 87.5%;
724
+ flex: 0 0 87.5%; }
725
+ .l-grid__cell--1\/10--handheld {
726
+ max-width: 10%;
727
+ -webkit-box-flex: 0;
728
+ -webkit-flex: 0 0 10%;
729
+ -moz-box-flex: 0;
730
+ -ms-flex: 0 0 10%;
731
+ flex: 0 0 10%; }
732
+ .l-grid__cell--3\/10--handheld {
733
+ max-width: 30%;
734
+ -webkit-box-flex: 0;
735
+ -webkit-flex: 0 0 30%;
736
+ -moz-box-flex: 0;
737
+ -ms-flex: 0 0 30%;
738
+ flex: 0 0 30%; }
739
+ .l-grid__cell--7\/10--handheld {
740
+ max-width: 70%;
741
+ -webkit-box-flex: 0;
742
+ -webkit-flex: 0 0 70%;
743
+ -moz-box-flex: 0;
744
+ -ms-flex: 0 0 70%;
745
+ flex: 0 0 70%; }
746
+ .l-grid__cell--9\/10--handheld {
747
+ max-width: 90%;
748
+ -webkit-box-flex: 0;
749
+ -webkit-flex: 0 0 90%;
750
+ -moz-box-flex: 0;
751
+ -ms-flex: 0 0 90%;
752
+ flex: 0 0 90%; }
753
+ .l-grid__cell--1\/12--handheld {
754
+ max-width: 8.33333%;
755
+ -webkit-box-flex: 0;
756
+ -webkit-flex: 0 0 8.33333%;
757
+ -moz-box-flex: 0;
758
+ -ms-flex: 0 0 8.33333%;
759
+ flex: 0 0 8.33333%; }
760
+ .l-grid__cell--5\/12--handheld {
761
+ max-width: 41.66667%;
762
+ -webkit-box-flex: 0;
763
+ -webkit-flex: 0 0 41.66667%;
764
+ -moz-box-flex: 0;
765
+ -ms-flex: 0 0 41.66667%;
766
+ flex: 0 0 41.66667%; }
767
+ .l-grid__cell--7\/12--handheld {
768
+ max-width: 58.33333%;
769
+ -webkit-box-flex: 0;
770
+ -webkit-flex: 0 0 58.33333%;
771
+ -moz-box-flex: 0;
772
+ -ms-flex: 0 0 58.33333%;
773
+ flex: 0 0 58.33333%; }
774
+ .l-grid__cell--11\/12--handheld {
775
+ max-width: 91.66667%;
776
+ -webkit-box-flex: 0;
777
+ -webkit-flex: 0 0 91.66667%;
778
+ -moz-box-flex: 0;
779
+ -ms-flex: 0 0 91.66667%;
780
+ flex: 0 0 91.66667%; }
781
+ .l-grid__cell--1\/14--handheld {
782
+ max-width: 7.14286%;
783
+ -webkit-box-flex: 0;
784
+ -webkit-flex: 0 0 7.14286%;
785
+ -moz-box-flex: 0;
786
+ -ms-flex: 0 0 7.14286%;
787
+ flex: 0 0 7.14286%; }
788
+ .l-grid__cell--2\/14--handheld {
789
+ max-width: 14.28571%;
790
+ -webkit-box-flex: 0;
791
+ -webkit-flex: 0 0 14.28571%;
792
+ -moz-box-flex: 0;
793
+ -ms-flex: 0 0 14.28571%;
794
+ flex: 0 0 14.28571%; }
795
+ .l-grid__cell--3\/14--handheld {
796
+ max-width: 21.42857%;
797
+ -webkit-box-flex: 0;
798
+ -webkit-flex: 0 0 21.42857%;
799
+ -moz-box-flex: 0;
800
+ -ms-flex: 0 0 21.42857%;
801
+ flex: 0 0 21.42857%; }
802
+ .l-grid__cell--4\/14--handheld {
803
+ max-width: 28.57143%;
804
+ -webkit-box-flex: 0;
805
+ -webkit-flex: 0 0 28.57143%;
806
+ -moz-box-flex: 0;
807
+ -ms-flex: 0 0 28.57143%;
808
+ flex: 0 0 28.57143%; }
809
+ .l-grid__cell--5\/14--handheld {
810
+ max-width: 35.71429%;
811
+ -webkit-box-flex: 0;
812
+ -webkit-flex: 0 0 35.71429%;
813
+ -moz-box-flex: 0;
814
+ -ms-flex: 0 0 35.71429%;
815
+ flex: 0 0 35.71429%; }
816
+ .l-grid__cell--6\/14--handheld {
817
+ max-width: 42.85714%;
818
+ -webkit-box-flex: 0;
819
+ -webkit-flex: 0 0 42.85714%;
820
+ -moz-box-flex: 0;
821
+ -ms-flex: 0 0 42.85714%;
822
+ flex: 0 0 42.85714%; }
823
+ .l-grid__cell--8\/14--handheld {
824
+ max-width: 57.14286%;
825
+ -webkit-box-flex: 0;
826
+ -webkit-flex: 0 0 57.14286%;
827
+ -moz-box-flex: 0;
828
+ -ms-flex: 0 0 57.14286%;
829
+ flex: 0 0 57.14286%; }
830
+ .l-grid__cell--9\/14--handheld {
831
+ max-width: 64.28571%;
832
+ -webkit-box-flex: 0;
833
+ -webkit-flex: 0 0 64.28571%;
834
+ -moz-box-flex: 0;
835
+ -ms-flex: 0 0 64.28571%;
836
+ flex: 0 0 64.28571%; }
837
+ .l-grid__cell--10\/14--handheld {
838
+ max-width: 71.42857%;
839
+ -webkit-box-flex: 0;
840
+ -webkit-flex: 0 0 71.42857%;
841
+ -moz-box-flex: 0;
842
+ -ms-flex: 0 0 71.42857%;
843
+ flex: 0 0 71.42857%; }
844
+ .l-grid__cell--11\/14--handheld {
845
+ max-width: 78.57143%;
846
+ -webkit-box-flex: 0;
847
+ -webkit-flex: 0 0 78.57143%;
848
+ -moz-box-flex: 0;
849
+ -ms-flex: 0 0 78.57143%;
850
+ flex: 0 0 78.57143%; }
851
+ .l-grid__cell--12\/14--handheld {
852
+ max-width: 85.71429%;
853
+ -webkit-box-flex: 0;
854
+ -webkit-flex: 0 0 85.71429%;
855
+ -moz-box-flex: 0;
856
+ -ms-flex: 0 0 85.71429%;
857
+ flex: 0 0 85.71429%; }
858
+ .l-grid__cell--13\/14--handheld {
859
+ max-width: 92.85714%;
860
+ -webkit-box-flex: 0;
861
+ -webkit-flex: 0 0 92.85714%;
862
+ -moz-box-flex: 0;
863
+ -ms-flex: 0 0 92.85714%;
864
+ flex: 0 0 92.85714%; }
865
+ .l-grid__cell--1\/16--handheld {
866
+ max-width: 6.25%;
867
+ -webkit-box-flex: 0;
868
+ -webkit-flex: 0 0 6.25%;
869
+ -moz-box-flex: 0;
870
+ -ms-flex: 0 0 6.25%;
871
+ flex: 0 0 6.25%; }
872
+ .l-grid__cell--3\/16--handheld {
873
+ max-width: 18.75%;
874
+ -webkit-box-flex: 0;
875
+ -webkit-flex: 0 0 18.75%;
876
+ -moz-box-flex: 0;
877
+ -ms-flex: 0 0 18.75%;
878
+ flex: 0 0 18.75%; }
879
+ .l-grid__cell--5\/16--handheld {
880
+ max-width: 31.25%;
881
+ -webkit-box-flex: 0;
882
+ -webkit-flex: 0 0 31.25%;
883
+ -moz-box-flex: 0;
884
+ -ms-flex: 0 0 31.25%;
885
+ flex: 0 0 31.25%; }
886
+ .l-grid__cell--7\/16--handheld {
887
+ max-width: 43.75%;
888
+ -webkit-box-flex: 0;
889
+ -webkit-flex: 0 0 43.75%;
890
+ -moz-box-flex: 0;
891
+ -ms-flex: 0 0 43.75%;
892
+ flex: 0 0 43.75%; }
893
+ .l-grid__cell--9\/16--handheld {
894
+ max-width: 56.25%;
895
+ -webkit-box-flex: 0;
896
+ -webkit-flex: 0 0 56.25%;
897
+ -moz-box-flex: 0;
898
+ -ms-flex: 0 0 56.25%;
899
+ flex: 0 0 56.25%; }
900
+ .l-grid__cell--11\/16--handheld {
901
+ max-width: 68.75%;
902
+ -webkit-box-flex: 0;
903
+ -webkit-flex: 0 0 68.75%;
904
+ -moz-box-flex: 0;
905
+ -ms-flex: 0 0 68.75%;
906
+ flex: 0 0 68.75%; }
907
+ .l-grid__cell--13\/16--handheld {
908
+ max-width: 81.25%;
909
+ -webkit-box-flex: 0;
910
+ -webkit-flex: 0 0 81.25%;
911
+ -moz-box-flex: 0;
912
+ -ms-flex: 0 0 81.25%;
913
+ flex: 0 0 81.25%; }
914
+ .l-grid__cell--15\/16--handheld {
915
+ max-width: 93.75%;
916
+ -webkit-box-flex: 0;
917
+ -webkit-flex: 0 0 93.75%;
918
+ -moz-box-flex: 0;
919
+ -ms-flex: 0 0 93.75%;
920
+ flex: 0 0 93.75%; }
921
+ .l-grid--hor-center--handheld {
922
+ -webkit-box-pack: center;
923
+ -webkit-justify-content: center;
924
+ -moz-box-pack: center;
925
+ -ms-flex-pack: center;
926
+ justify-content: center; }
927
+ .l-grid--hor-right--handheld {
928
+ -webkit-box-pack: end;
929
+ -webkit-justify-content: flex-end;
930
+ -moz-box-pack: end;
931
+ -ms-flex-pack: end;
932
+ justify-content: flex-end; }
933
+ .l-grid--ver-center--handheld {
934
+ -webkit-box-align: center;
935
+ -webkit-align-items: center;
936
+ -moz-box-align: center;
937
+ -ms-flex-align: center;
938
+ align-items: center; }
939
+ .l-grid--ver-bottom--handheld {
940
+ -webkit-box-align: end;
941
+ -webkit-align-items: flex-end;
942
+ -moz-box-align: end;
943
+ -ms-flex-align: end;
944
+ align-items: flex-end; }
945
+ .l-grid--auto--handheld > .l-grid__cell {
946
+ -webkit-flex-basis: 0;
947
+ -ms-flex-preferred-size: 0;
948
+ flex-basis: 0; } }
949
+
950
+ @media screen and (min-width: 801px) {
951
+ .l-grid__cell--1\/2--lap, .l-grid__cell--2\/4--lap, .l-grid__cell--3\/6--lap, .l-grid__cell--4\/8--lap, .l-grid__cell--5\/10--lap, .l-grid__cell--6\/12--lap, .l-grid__cell--7\/14--lap, .l-grid__cell--8\/16--lap {
952
+ max-width: 50%;
953
+ -webkit-box-flex: 0;
954
+ -webkit-flex: 0 0 50%;
955
+ -moz-box-flex: 0;
956
+ -ms-flex: 0 0 50%;
957
+ flex: 0 0 50%; }
958
+ .l-grid__cell--1\/3--lap, .l-grid__cell--2\/6--lap, .l-grid__cell--4\/12--lap {
959
+ max-width: 33.33333%;
960
+ -webkit-box-flex: 0;
961
+ -webkit-flex: 0 0 33.33333%;
962
+ -moz-box-flex: 0;
963
+ -ms-flex: 0 0 33.33333%;
964
+ flex: 0 0 33.33333%; }
965
+ .l-grid__cell--2\/3--lap, .l-grid__cell--4\/6--lap, .l-grid__cell--8\/12--lap {
966
+ max-width: 66.66667%;
967
+ -webkit-box-flex: 0;
968
+ -webkit-flex: 0 0 66.66667%;
969
+ -moz-box-flex: 0;
970
+ -ms-flex: 0 0 66.66667%;
971
+ flex: 0 0 66.66667%; }
972
+ .l-grid__cell--1\/4--lap, .l-grid__cell--2\/8--lap, .l-grid__cell--3\/12--lap, .l-grid__cell--4\/16--lap {
973
+ max-width: 25%;
974
+ -webkit-box-flex: 0;
975
+ -webkit-flex: 0 0 25%;
976
+ -moz-box-flex: 0;
977
+ -ms-flex: 0 0 25%;
978
+ flex: 0 0 25%; }
979
+ .l-grid__cell--3\/4--lap, .l-grid__cell--6\/8--lap, .l-grid__cell--9\/12--lap, .l-grid__cell--12\/16--lap {
980
+ max-width: 75%;
981
+ -webkit-box-flex: 0;
982
+ -webkit-flex: 0 0 75%;
983
+ -moz-box-flex: 0;
984
+ -ms-flex: 0 0 75%;
985
+ flex: 0 0 75%; }
986
+ .l-grid__cell--1\/5--lap, .l-grid__cell--2\/10--lap {
987
+ max-width: 20%;
988
+ -webkit-box-flex: 0;
989
+ -webkit-flex: 0 0 20%;
990
+ -moz-box-flex: 0;
991
+ -ms-flex: 0 0 20%;
992
+ flex: 0 0 20%; }
993
+ .l-grid__cell--2\/5--lap, .l-grid__cell--4\/10--lap {
994
+ max-width: 40%;
995
+ -webkit-box-flex: 0;
996
+ -webkit-flex: 0 0 40%;
997
+ -moz-box-flex: 0;
998
+ -ms-flex: 0 0 40%;
999
+ flex: 0 0 40%; }
1000
+ .l-grid__cell--3\/5--lap, .l-grid__cell--6\/10--lap {
1001
+ max-width: 60%;
1002
+ -webkit-box-flex: 0;
1003
+ -webkit-flex: 0 0 60%;
1004
+ -moz-box-flex: 0;
1005
+ -ms-flex: 0 0 60%;
1006
+ flex: 0 0 60%; }
1007
+ .l-grid__cell--4\/5--lap, .l-grid__cell--8\/10--lap {
1008
+ max-width: 80%;
1009
+ -webkit-box-flex: 0;
1010
+ -webkit-flex: 0 0 80%;
1011
+ -moz-box-flex: 0;
1012
+ -ms-flex: 0 0 80%;
1013
+ flex: 0 0 80%; }
1014
+ .l-grid__cell--1\/6--lap, .l-grid__cell--2\/12--lap {
1015
+ max-width: 16.66667%;
1016
+ -webkit-box-flex: 0;
1017
+ -webkit-flex: 0 0 16.66667%;
1018
+ -moz-box-flex: 0;
1019
+ -ms-flex: 0 0 16.66667%;
1020
+ flex: 0 0 16.66667%; }
1021
+ .l-grid__cell--5\/6--lap, .l-grid__cell--10\/12--lap {
1022
+ max-width: 83.33333%;
1023
+ -webkit-box-flex: 0;
1024
+ -webkit-flex: 0 0 83.33333%;
1025
+ -moz-box-flex: 0;
1026
+ -ms-flex: 0 0 83.33333%;
1027
+ flex: 0 0 83.33333%; }
1028
+ .l-grid__cell--1\/8--lap, .l-grid__cell--2\/16--lap {
1029
+ max-width: 12.5%;
1030
+ -webkit-box-flex: 0;
1031
+ -webkit-flex: 0 0 12.5%;
1032
+ -moz-box-flex: 0;
1033
+ -ms-flex: 0 0 12.5%;
1034
+ flex: 0 0 12.5%; }
1035
+ .l-grid__cell--3\/8--lap, .l-grid__cell--6\/16--lap {
1036
+ max-width: 37.5%;
1037
+ -webkit-box-flex: 0;
1038
+ -webkit-flex: 0 0 37.5%;
1039
+ -moz-box-flex: 0;
1040
+ -ms-flex: 0 0 37.5%;
1041
+ flex: 0 0 37.5%; }
1042
+ .l-grid__cell--5\/8--lap, .l-grid__cell--10\/16--lap {
1043
+ max-width: 62.5%;
1044
+ -webkit-box-flex: 0;
1045
+ -webkit-flex: 0 0 62.5%;
1046
+ -moz-box-flex: 0;
1047
+ -ms-flex: 0 0 62.5%;
1048
+ flex: 0 0 62.5%; }
1049
+ .l-grid__cell--7\/8--lap, .l-grid__cell--14\/16--lap {
1050
+ max-width: 87.5%;
1051
+ -webkit-box-flex: 0;
1052
+ -webkit-flex: 0 0 87.5%;
1053
+ -moz-box-flex: 0;
1054
+ -ms-flex: 0 0 87.5%;
1055
+ flex: 0 0 87.5%; }
1056
+ .l-grid__cell--1\/10--lap {
1057
+ max-width: 10%;
1058
+ -webkit-box-flex: 0;
1059
+ -webkit-flex: 0 0 10%;
1060
+ -moz-box-flex: 0;
1061
+ -ms-flex: 0 0 10%;
1062
+ flex: 0 0 10%; }
1063
+ .l-grid__cell--3\/10--lap {
1064
+ max-width: 30%;
1065
+ -webkit-box-flex: 0;
1066
+ -webkit-flex: 0 0 30%;
1067
+ -moz-box-flex: 0;
1068
+ -ms-flex: 0 0 30%;
1069
+ flex: 0 0 30%; }
1070
+ .l-grid__cell--7\/10--lap {
1071
+ max-width: 70%;
1072
+ -webkit-box-flex: 0;
1073
+ -webkit-flex: 0 0 70%;
1074
+ -moz-box-flex: 0;
1075
+ -ms-flex: 0 0 70%;
1076
+ flex: 0 0 70%; }
1077
+ .l-grid__cell--9\/10--lap {
1078
+ max-width: 90%;
1079
+ -webkit-box-flex: 0;
1080
+ -webkit-flex: 0 0 90%;
1081
+ -moz-box-flex: 0;
1082
+ -ms-flex: 0 0 90%;
1083
+ flex: 0 0 90%; }
1084
+ .l-grid__cell--1\/12--lap {
1085
+ max-width: 8.33333%;
1086
+ -webkit-box-flex: 0;
1087
+ -webkit-flex: 0 0 8.33333%;
1088
+ -moz-box-flex: 0;
1089
+ -ms-flex: 0 0 8.33333%;
1090
+ flex: 0 0 8.33333%; }
1091
+ .l-grid__cell--5\/12--lap {
1092
+ max-width: 41.66667%;
1093
+ -webkit-box-flex: 0;
1094
+ -webkit-flex: 0 0 41.66667%;
1095
+ -moz-box-flex: 0;
1096
+ -ms-flex: 0 0 41.66667%;
1097
+ flex: 0 0 41.66667%; }
1098
+ .l-grid__cell--7\/12--lap {
1099
+ max-width: 58.33333%;
1100
+ -webkit-box-flex: 0;
1101
+ -webkit-flex: 0 0 58.33333%;
1102
+ -moz-box-flex: 0;
1103
+ -ms-flex: 0 0 58.33333%;
1104
+ flex: 0 0 58.33333%; }
1105
+ .l-grid__cell--11\/12--lap {
1106
+ max-width: 91.66667%;
1107
+ -webkit-box-flex: 0;
1108
+ -webkit-flex: 0 0 91.66667%;
1109
+ -moz-box-flex: 0;
1110
+ -ms-flex: 0 0 91.66667%;
1111
+ flex: 0 0 91.66667%; }
1112
+ .l-grid__cell--1\/14--lap {
1113
+ max-width: 7.14286%;
1114
+ -webkit-box-flex: 0;
1115
+ -webkit-flex: 0 0 7.14286%;
1116
+ -moz-box-flex: 0;
1117
+ -ms-flex: 0 0 7.14286%;
1118
+ flex: 0 0 7.14286%; }
1119
+ .l-grid__cell--2\/14--lap {
1120
+ max-width: 14.28571%;
1121
+ -webkit-box-flex: 0;
1122
+ -webkit-flex: 0 0 14.28571%;
1123
+ -moz-box-flex: 0;
1124
+ -ms-flex: 0 0 14.28571%;
1125
+ flex: 0 0 14.28571%; }
1126
+ .l-grid__cell--3\/14--lap {
1127
+ max-width: 21.42857%;
1128
+ -webkit-box-flex: 0;
1129
+ -webkit-flex: 0 0 21.42857%;
1130
+ -moz-box-flex: 0;
1131
+ -ms-flex: 0 0 21.42857%;
1132
+ flex: 0 0 21.42857%; }
1133
+ .l-grid__cell--4\/14--lap {
1134
+ max-width: 28.57143%;
1135
+ -webkit-box-flex: 0;
1136
+ -webkit-flex: 0 0 28.57143%;
1137
+ -moz-box-flex: 0;
1138
+ -ms-flex: 0 0 28.57143%;
1139
+ flex: 0 0 28.57143%; }
1140
+ .l-grid__cell--5\/14--lap {
1141
+ max-width: 35.71429%;
1142
+ -webkit-box-flex: 0;
1143
+ -webkit-flex: 0 0 35.71429%;
1144
+ -moz-box-flex: 0;
1145
+ -ms-flex: 0 0 35.71429%;
1146
+ flex: 0 0 35.71429%; }
1147
+ .l-grid__cell--6\/14--lap {
1148
+ max-width: 42.85714%;
1149
+ -webkit-box-flex: 0;
1150
+ -webkit-flex: 0 0 42.85714%;
1151
+ -moz-box-flex: 0;
1152
+ -ms-flex: 0 0 42.85714%;
1153
+ flex: 0 0 42.85714%; }
1154
+ .l-grid__cell--8\/14--lap {
1155
+ max-width: 57.14286%;
1156
+ -webkit-box-flex: 0;
1157
+ -webkit-flex: 0 0 57.14286%;
1158
+ -moz-box-flex: 0;
1159
+ -ms-flex: 0 0 57.14286%;
1160
+ flex: 0 0 57.14286%; }
1161
+ .l-grid__cell--9\/14--lap {
1162
+ max-width: 64.28571%;
1163
+ -webkit-box-flex: 0;
1164
+ -webkit-flex: 0 0 64.28571%;
1165
+ -moz-box-flex: 0;
1166
+ -ms-flex: 0 0 64.28571%;
1167
+ flex: 0 0 64.28571%; }
1168
+ .l-grid__cell--10\/14--lap {
1169
+ max-width: 71.42857%;
1170
+ -webkit-box-flex: 0;
1171
+ -webkit-flex: 0 0 71.42857%;
1172
+ -moz-box-flex: 0;
1173
+ -ms-flex: 0 0 71.42857%;
1174
+ flex: 0 0 71.42857%; }
1175
+ .l-grid__cell--11\/14--lap {
1176
+ max-width: 78.57143%;
1177
+ -webkit-box-flex: 0;
1178
+ -webkit-flex: 0 0 78.57143%;
1179
+ -moz-box-flex: 0;
1180
+ -ms-flex: 0 0 78.57143%;
1181
+ flex: 0 0 78.57143%; }
1182
+ .l-grid__cell--12\/14--lap {
1183
+ max-width: 85.71429%;
1184
+ -webkit-box-flex: 0;
1185
+ -webkit-flex: 0 0 85.71429%;
1186
+ -moz-box-flex: 0;
1187
+ -ms-flex: 0 0 85.71429%;
1188
+ flex: 0 0 85.71429%; }
1189
+ .l-grid__cell--13\/14--lap {
1190
+ max-width: 92.85714%;
1191
+ -webkit-box-flex: 0;
1192
+ -webkit-flex: 0 0 92.85714%;
1193
+ -moz-box-flex: 0;
1194
+ -ms-flex: 0 0 92.85714%;
1195
+ flex: 0 0 92.85714%; }
1196
+ .l-grid__cell--1\/16--lap {
1197
+ max-width: 6.25%;
1198
+ -webkit-box-flex: 0;
1199
+ -webkit-flex: 0 0 6.25%;
1200
+ -moz-box-flex: 0;
1201
+ -ms-flex: 0 0 6.25%;
1202
+ flex: 0 0 6.25%; }
1203
+ .l-grid__cell--3\/16--lap {
1204
+ max-width: 18.75%;
1205
+ -webkit-box-flex: 0;
1206
+ -webkit-flex: 0 0 18.75%;
1207
+ -moz-box-flex: 0;
1208
+ -ms-flex: 0 0 18.75%;
1209
+ flex: 0 0 18.75%; }
1210
+ .l-grid__cell--5\/16--lap {
1211
+ max-width: 31.25%;
1212
+ -webkit-box-flex: 0;
1213
+ -webkit-flex: 0 0 31.25%;
1214
+ -moz-box-flex: 0;
1215
+ -ms-flex: 0 0 31.25%;
1216
+ flex: 0 0 31.25%; }
1217
+ .l-grid__cell--7\/16--lap {
1218
+ max-width: 43.75%;
1219
+ -webkit-box-flex: 0;
1220
+ -webkit-flex: 0 0 43.75%;
1221
+ -moz-box-flex: 0;
1222
+ -ms-flex: 0 0 43.75%;
1223
+ flex: 0 0 43.75%; }
1224
+ .l-grid__cell--9\/16--lap {
1225
+ max-width: 56.25%;
1226
+ -webkit-box-flex: 0;
1227
+ -webkit-flex: 0 0 56.25%;
1228
+ -moz-box-flex: 0;
1229
+ -ms-flex: 0 0 56.25%;
1230
+ flex: 0 0 56.25%; }
1231
+ .l-grid__cell--11\/16--lap {
1232
+ max-width: 68.75%;
1233
+ -webkit-box-flex: 0;
1234
+ -webkit-flex: 0 0 68.75%;
1235
+ -moz-box-flex: 0;
1236
+ -ms-flex: 0 0 68.75%;
1237
+ flex: 0 0 68.75%; }
1238
+ .l-grid__cell--13\/16--lap {
1239
+ max-width: 81.25%;
1240
+ -webkit-box-flex: 0;
1241
+ -webkit-flex: 0 0 81.25%;
1242
+ -moz-box-flex: 0;
1243
+ -ms-flex: 0 0 81.25%;
1244
+ flex: 0 0 81.25%; }
1245
+ .l-grid__cell--15\/16--lap {
1246
+ max-width: 93.75%;
1247
+ -webkit-box-flex: 0;
1248
+ -webkit-flex: 0 0 93.75%;
1249
+ -moz-box-flex: 0;
1250
+ -ms-flex: 0 0 93.75%;
1251
+ flex: 0 0 93.75%; }
1252
+ .l-grid--hor-center--lap {
1253
+ -webkit-box-pack: center;
1254
+ -webkit-justify-content: center;
1255
+ -moz-box-pack: center;
1256
+ -ms-flex-pack: center;
1257
+ justify-content: center; }
1258
+ .l-grid--hor-right--lap {
1259
+ -webkit-box-pack: end;
1260
+ -webkit-justify-content: flex-end;
1261
+ -moz-box-pack: end;
1262
+ -ms-flex-pack: end;
1263
+ justify-content: flex-end; }
1264
+ .l-grid--ver-center--lap {
1265
+ -webkit-box-align: center;
1266
+ -webkit-align-items: center;
1267
+ -moz-box-align: center;
1268
+ -ms-flex-align: center;
1269
+ align-items: center; }
1270
+ .l-grid--ver-bottom--lap {
1271
+ -webkit-box-align: end;
1272
+ -webkit-align-items: flex-end;
1273
+ -moz-box-align: end;
1274
+ -ms-flex-align: end;
1275
+ align-items: flex-end; }
1276
+ .l-grid--auto--lap > .l-grid__cell {
1277
+ -webkit-flex-basis: 0;
1278
+ -ms-flex-preferred-size: 0;
1279
+ flex-basis: 0; } }
1280
+
1281
+ @media screen and (min-width: 1070px) {
1282
+ .l-grid__cell--1\/2--desk, .l-grid__cell--2\/4--desk, .l-grid__cell--3\/6--desk, .l-grid__cell--4\/8--desk, .l-grid__cell--5\/10--desk, .l-grid__cell--6\/12--desk, .l-grid__cell--7\/14--desk, .l-grid__cell--8\/16--desk {
1283
+ max-width: 50%;
1284
+ -webkit-box-flex: 0;
1285
+ -webkit-flex: 0 0 50%;
1286
+ -moz-box-flex: 0;
1287
+ -ms-flex: 0 0 50%;
1288
+ flex: 0 0 50%; }
1289
+ .l-grid__cell--1\/3--desk, .l-grid__cell--2\/6--desk, .l-grid__cell--4\/12--desk {
1290
+ max-width: 33.33333%;
1291
+ -webkit-box-flex: 0;
1292
+ -webkit-flex: 0 0 33.33333%;
1293
+ -moz-box-flex: 0;
1294
+ -ms-flex: 0 0 33.33333%;
1295
+ flex: 0 0 33.33333%; }
1296
+ .l-grid__cell--2\/3--desk, .l-grid__cell--4\/6--desk, .l-grid__cell--8\/12--desk {
1297
+ max-width: 66.66667%;
1298
+ -webkit-box-flex: 0;
1299
+ -webkit-flex: 0 0 66.66667%;
1300
+ -moz-box-flex: 0;
1301
+ -ms-flex: 0 0 66.66667%;
1302
+ flex: 0 0 66.66667%; }
1303
+ .l-grid__cell--1\/4--desk, .l-grid__cell--2\/8--desk, .l-grid__cell--3\/12--desk, .l-grid__cell--4\/16--desk {
1304
+ max-width: 25%;
1305
+ -webkit-box-flex: 0;
1306
+ -webkit-flex: 0 0 25%;
1307
+ -moz-box-flex: 0;
1308
+ -ms-flex: 0 0 25%;
1309
+ flex: 0 0 25%; }
1310
+ .l-grid__cell--3\/4--desk, .l-grid__cell--6\/8--desk, .l-grid__cell--9\/12--desk, .l-grid__cell--12\/16--desk {
1311
+ max-width: 75%;
1312
+ -webkit-box-flex: 0;
1313
+ -webkit-flex: 0 0 75%;
1314
+ -moz-box-flex: 0;
1315
+ -ms-flex: 0 0 75%;
1316
+ flex: 0 0 75%; }
1317
+ .l-grid__cell--1\/5--desk, .l-grid__cell--2\/10--desk {
1318
+ max-width: 20%;
1319
+ -webkit-box-flex: 0;
1320
+ -webkit-flex: 0 0 20%;
1321
+ -moz-box-flex: 0;
1322
+ -ms-flex: 0 0 20%;
1323
+ flex: 0 0 20%; }
1324
+ .l-grid__cell--2\/5--desk, .l-grid__cell--4\/10--desk {
1325
+ max-width: 40%;
1326
+ -webkit-box-flex: 0;
1327
+ -webkit-flex: 0 0 40%;
1328
+ -moz-box-flex: 0;
1329
+ -ms-flex: 0 0 40%;
1330
+ flex: 0 0 40%; }
1331
+ .l-grid__cell--3\/5--desk, .l-grid__cell--6\/10--desk {
1332
+ max-width: 60%;
1333
+ -webkit-box-flex: 0;
1334
+ -webkit-flex: 0 0 60%;
1335
+ -moz-box-flex: 0;
1336
+ -ms-flex: 0 0 60%;
1337
+ flex: 0 0 60%; }
1338
+ .l-grid__cell--4\/5--desk, .l-grid__cell--8\/10--desk {
1339
+ max-width: 80%;
1340
+ -webkit-box-flex: 0;
1341
+ -webkit-flex: 0 0 80%;
1342
+ -moz-box-flex: 0;
1343
+ -ms-flex: 0 0 80%;
1344
+ flex: 0 0 80%; }
1345
+ .l-grid__cell--1\/6--desk, .l-grid__cell--2\/12--desk {
1346
+ max-width: 16.66667%;
1347
+ -webkit-box-flex: 0;
1348
+ -webkit-flex: 0 0 16.66667%;
1349
+ -moz-box-flex: 0;
1350
+ -ms-flex: 0 0 16.66667%;
1351
+ flex: 0 0 16.66667%; }
1352
+ .l-grid__cell--5\/6--desk, .l-grid__cell--10\/12--desk {
1353
+ max-width: 83.33333%;
1354
+ -webkit-box-flex: 0;
1355
+ -webkit-flex: 0 0 83.33333%;
1356
+ -moz-box-flex: 0;
1357
+ -ms-flex: 0 0 83.33333%;
1358
+ flex: 0 0 83.33333%; }
1359
+ .l-grid__cell--1\/8--desk, .l-grid__cell--2\/16--desk {
1360
+ max-width: 12.5%;
1361
+ -webkit-box-flex: 0;
1362
+ -webkit-flex: 0 0 12.5%;
1363
+ -moz-box-flex: 0;
1364
+ -ms-flex: 0 0 12.5%;
1365
+ flex: 0 0 12.5%; }
1366
+ .l-grid__cell--3\/8--desk, .l-grid__cell--6\/16--desk {
1367
+ max-width: 37.5%;
1368
+ -webkit-box-flex: 0;
1369
+ -webkit-flex: 0 0 37.5%;
1370
+ -moz-box-flex: 0;
1371
+ -ms-flex: 0 0 37.5%;
1372
+ flex: 0 0 37.5%; }
1373
+ .l-grid__cell--5\/8--desk, .l-grid__cell--10\/16--desk {
1374
+ max-width: 62.5%;
1375
+ -webkit-box-flex: 0;
1376
+ -webkit-flex: 0 0 62.5%;
1377
+ -moz-box-flex: 0;
1378
+ -ms-flex: 0 0 62.5%;
1379
+ flex: 0 0 62.5%; }
1380
+ .l-grid__cell--7\/8--desk, .l-grid__cell--14\/16--desk {
1381
+ max-width: 87.5%;
1382
+ -webkit-box-flex: 0;
1383
+ -webkit-flex: 0 0 87.5%;
1384
+ -moz-box-flex: 0;
1385
+ -ms-flex: 0 0 87.5%;
1386
+ flex: 0 0 87.5%; }
1387
+ .l-grid__cell--1\/10--desk {
1388
+ max-width: 10%;
1389
+ -webkit-box-flex: 0;
1390
+ -webkit-flex: 0 0 10%;
1391
+ -moz-box-flex: 0;
1392
+ -ms-flex: 0 0 10%;
1393
+ flex: 0 0 10%; }
1394
+ .l-grid__cell--3\/10--desk {
1395
+ max-width: 30%;
1396
+ -webkit-box-flex: 0;
1397
+ -webkit-flex: 0 0 30%;
1398
+ -moz-box-flex: 0;
1399
+ -ms-flex: 0 0 30%;
1400
+ flex: 0 0 30%; }
1401
+ .l-grid__cell--7\/10--desk {
1402
+ max-width: 70%;
1403
+ -webkit-box-flex: 0;
1404
+ -webkit-flex: 0 0 70%;
1405
+ -moz-box-flex: 0;
1406
+ -ms-flex: 0 0 70%;
1407
+ flex: 0 0 70%; }
1408
+ .l-grid__cell--9\/10--desk {
1409
+ max-width: 90%;
1410
+ -webkit-box-flex: 0;
1411
+ -webkit-flex: 0 0 90%;
1412
+ -moz-box-flex: 0;
1413
+ -ms-flex: 0 0 90%;
1414
+ flex: 0 0 90%; }
1415
+ .l-grid__cell--1\/12--desk {
1416
+ max-width: 8.33333%;
1417
+ -webkit-box-flex: 0;
1418
+ -webkit-flex: 0 0 8.33333%;
1419
+ -moz-box-flex: 0;
1420
+ -ms-flex: 0 0 8.33333%;
1421
+ flex: 0 0 8.33333%; }
1422
+ .l-grid__cell--5\/12--desk {
1423
+ max-width: 41.66667%;
1424
+ -webkit-box-flex: 0;
1425
+ -webkit-flex: 0 0 41.66667%;
1426
+ -moz-box-flex: 0;
1427
+ -ms-flex: 0 0 41.66667%;
1428
+ flex: 0 0 41.66667%; }
1429
+ .l-grid__cell--7\/12--desk {
1430
+ max-width: 58.33333%;
1431
+ -webkit-box-flex: 0;
1432
+ -webkit-flex: 0 0 58.33333%;
1433
+ -moz-box-flex: 0;
1434
+ -ms-flex: 0 0 58.33333%;
1435
+ flex: 0 0 58.33333%; }
1436
+ .l-grid__cell--11\/12--desk {
1437
+ max-width: 91.66667%;
1438
+ -webkit-box-flex: 0;
1439
+ -webkit-flex: 0 0 91.66667%;
1440
+ -moz-box-flex: 0;
1441
+ -ms-flex: 0 0 91.66667%;
1442
+ flex: 0 0 91.66667%; }
1443
+ .l-grid__cell--1\/14--desk {
1444
+ max-width: 7.14286%;
1445
+ -webkit-box-flex: 0;
1446
+ -webkit-flex: 0 0 7.14286%;
1447
+ -moz-box-flex: 0;
1448
+ -ms-flex: 0 0 7.14286%;
1449
+ flex: 0 0 7.14286%; }
1450
+ .l-grid__cell--2\/14--desk {
1451
+ max-width: 14.28571%;
1452
+ -webkit-box-flex: 0;
1453
+ -webkit-flex: 0 0 14.28571%;
1454
+ -moz-box-flex: 0;
1455
+ -ms-flex: 0 0 14.28571%;
1456
+ flex: 0 0 14.28571%; }
1457
+ .l-grid__cell--3\/14--desk {
1458
+ max-width: 21.42857%;
1459
+ -webkit-box-flex: 0;
1460
+ -webkit-flex: 0 0 21.42857%;
1461
+ -moz-box-flex: 0;
1462
+ -ms-flex: 0 0 21.42857%;
1463
+ flex: 0 0 21.42857%; }
1464
+ .l-grid__cell--4\/14--desk {
1465
+ max-width: 28.57143%;
1466
+ -webkit-box-flex: 0;
1467
+ -webkit-flex: 0 0 28.57143%;
1468
+ -moz-box-flex: 0;
1469
+ -ms-flex: 0 0 28.57143%;
1470
+ flex: 0 0 28.57143%; }
1471
+ .l-grid__cell--5\/14--desk {
1472
+ max-width: 35.71429%;
1473
+ -webkit-box-flex: 0;
1474
+ -webkit-flex: 0 0 35.71429%;
1475
+ -moz-box-flex: 0;
1476
+ -ms-flex: 0 0 35.71429%;
1477
+ flex: 0 0 35.71429%; }
1478
+ .l-grid__cell--6\/14--desk {
1479
+ max-width: 42.85714%;
1480
+ -webkit-box-flex: 0;
1481
+ -webkit-flex: 0 0 42.85714%;
1482
+ -moz-box-flex: 0;
1483
+ -ms-flex: 0 0 42.85714%;
1484
+ flex: 0 0 42.85714%; }
1485
+ .l-grid__cell--8\/14--desk {
1486
+ max-width: 57.14286%;
1487
+ -webkit-box-flex: 0;
1488
+ -webkit-flex: 0 0 57.14286%;
1489
+ -moz-box-flex: 0;
1490
+ -ms-flex: 0 0 57.14286%;
1491
+ flex: 0 0 57.14286%; }
1492
+ .l-grid__cell--9\/14--desk {
1493
+ max-width: 64.28571%;
1494
+ -webkit-box-flex: 0;
1495
+ -webkit-flex: 0 0 64.28571%;
1496
+ -moz-box-flex: 0;
1497
+ -ms-flex: 0 0 64.28571%;
1498
+ flex: 0 0 64.28571%; }
1499
+ .l-grid__cell--10\/14--desk {
1500
+ max-width: 71.42857%;
1501
+ -webkit-box-flex: 0;
1502
+ -webkit-flex: 0 0 71.42857%;
1503
+ -moz-box-flex: 0;
1504
+ -ms-flex: 0 0 71.42857%;
1505
+ flex: 0 0 71.42857%; }
1506
+ .l-grid__cell--11\/14--desk {
1507
+ max-width: 78.57143%;
1508
+ -webkit-box-flex: 0;
1509
+ -webkit-flex: 0 0 78.57143%;
1510
+ -moz-box-flex: 0;
1511
+ -ms-flex: 0 0 78.57143%;
1512
+ flex: 0 0 78.57143%; }
1513
+ .l-grid__cell--12\/14--desk {
1514
+ max-width: 85.71429%;
1515
+ -webkit-box-flex: 0;
1516
+ -webkit-flex: 0 0 85.71429%;
1517
+ -moz-box-flex: 0;
1518
+ -ms-flex: 0 0 85.71429%;
1519
+ flex: 0 0 85.71429%; }
1520
+ .l-grid__cell--13\/14--desk {
1521
+ max-width: 92.85714%;
1522
+ -webkit-box-flex: 0;
1523
+ -webkit-flex: 0 0 92.85714%;
1524
+ -moz-box-flex: 0;
1525
+ -ms-flex: 0 0 92.85714%;
1526
+ flex: 0 0 92.85714%; }
1527
+ .l-grid__cell--1\/16--desk {
1528
+ max-width: 6.25%;
1529
+ -webkit-box-flex: 0;
1530
+ -webkit-flex: 0 0 6.25%;
1531
+ -moz-box-flex: 0;
1532
+ -ms-flex: 0 0 6.25%;
1533
+ flex: 0 0 6.25%; }
1534
+ .l-grid__cell--3\/16--desk {
1535
+ max-width: 18.75%;
1536
+ -webkit-box-flex: 0;
1537
+ -webkit-flex: 0 0 18.75%;
1538
+ -moz-box-flex: 0;
1539
+ -ms-flex: 0 0 18.75%;
1540
+ flex: 0 0 18.75%; }
1541
+ .l-grid__cell--5\/16--desk {
1542
+ max-width: 31.25%;
1543
+ -webkit-box-flex: 0;
1544
+ -webkit-flex: 0 0 31.25%;
1545
+ -moz-box-flex: 0;
1546
+ -ms-flex: 0 0 31.25%;
1547
+ flex: 0 0 31.25%; }
1548
+ .l-grid__cell--7\/16--desk {
1549
+ max-width: 43.75%;
1550
+ -webkit-box-flex: 0;
1551
+ -webkit-flex: 0 0 43.75%;
1552
+ -moz-box-flex: 0;
1553
+ -ms-flex: 0 0 43.75%;
1554
+ flex: 0 0 43.75%; }
1555
+ .l-grid__cell--9\/16--desk {
1556
+ max-width: 56.25%;
1557
+ -webkit-box-flex: 0;
1558
+ -webkit-flex: 0 0 56.25%;
1559
+ -moz-box-flex: 0;
1560
+ -ms-flex: 0 0 56.25%;
1561
+ flex: 0 0 56.25%; }
1562
+ .l-grid__cell--11\/16--desk {
1563
+ max-width: 68.75%;
1564
+ -webkit-box-flex: 0;
1565
+ -webkit-flex: 0 0 68.75%;
1566
+ -moz-box-flex: 0;
1567
+ -ms-flex: 0 0 68.75%;
1568
+ flex: 0 0 68.75%; }
1569
+ .l-grid__cell--13\/16--desk {
1570
+ max-width: 81.25%;
1571
+ -webkit-box-flex: 0;
1572
+ -webkit-flex: 0 0 81.25%;
1573
+ -moz-box-flex: 0;
1574
+ -ms-flex: 0 0 81.25%;
1575
+ flex: 0 0 81.25%; }
1576
+ .l-grid__cell--15\/16--desk {
1577
+ max-width: 93.75%;
1578
+ -webkit-box-flex: 0;
1579
+ -webkit-flex: 0 0 93.75%;
1580
+ -moz-box-flex: 0;
1581
+ -ms-flex: 0 0 93.75%;
1582
+ flex: 0 0 93.75%; }
1583
+ .l-grid--hor-center--desk {
1584
+ -webkit-box-pack: center;
1585
+ -webkit-justify-content: center;
1586
+ -moz-box-pack: center;
1587
+ -ms-flex-pack: center;
1588
+ justify-content: center; }
1589
+ .l-grid--hor-right--desk {
1590
+ -webkit-box-pack: end;
1591
+ -webkit-justify-content: flex-end;
1592
+ -moz-box-pack: end;
1593
+ -ms-flex-pack: end;
1594
+ justify-content: flex-end; }
1595
+ .l-grid--ver-center--desk {
1596
+ -webkit-box-align: center;
1597
+ -webkit-align-items: center;
1598
+ -moz-box-align: center;
1599
+ -ms-flex-align: center;
1600
+ align-items: center; }
1601
+ .l-grid--ver-bottom--desk {
1602
+ -webkit-box-align: end;
1603
+ -webkit-align-items: flex-end;
1604
+ -moz-box-align: end;
1605
+ -ms-flex-align: end;
1606
+ align-items: flex-end; }
1607
+ .l-grid--auto--desk > .l-grid__cell {
1608
+ -webkit-flex-basis: 0;
1609
+ -ms-flex-preferred-size: 0;
1610
+ flex-basis: 0; } }
1611
+
1612
+ @media screen and (min-width: 1680px) {
1613
+ .l-grid__cell--1\/2--widescreen, .l-grid__cell--2\/4--widescreen, .l-grid__cell--3\/6--widescreen, .l-grid__cell--4\/8--widescreen, .l-grid__cell--5\/10--widescreen, .l-grid__cell--6\/12--widescreen, .l-grid__cell--7\/14--widescreen, .l-grid__cell--8\/16--widescreen {
1614
+ max-width: 50%;
1615
+ -webkit-box-flex: 0;
1616
+ -webkit-flex: 0 0 50%;
1617
+ -moz-box-flex: 0;
1618
+ -ms-flex: 0 0 50%;
1619
+ flex: 0 0 50%; }
1620
+ .l-grid__cell--1\/3--widescreen, .l-grid__cell--2\/6--widescreen, .l-grid__cell--4\/12--widescreen {
1621
+ max-width: 33.33333%;
1622
+ -webkit-box-flex: 0;
1623
+ -webkit-flex: 0 0 33.33333%;
1624
+ -moz-box-flex: 0;
1625
+ -ms-flex: 0 0 33.33333%;
1626
+ flex: 0 0 33.33333%; }
1627
+ .l-grid__cell--2\/3--widescreen, .l-grid__cell--4\/6--widescreen, .l-grid__cell--8\/12--widescreen {
1628
+ max-width: 66.66667%;
1629
+ -webkit-box-flex: 0;
1630
+ -webkit-flex: 0 0 66.66667%;
1631
+ -moz-box-flex: 0;
1632
+ -ms-flex: 0 0 66.66667%;
1633
+ flex: 0 0 66.66667%; }
1634
+ .l-grid__cell--1\/4--widescreen, .l-grid__cell--2\/8--widescreen, .l-grid__cell--3\/12--widescreen, .l-grid__cell--4\/16--widescreen {
1635
+ max-width: 25%;
1636
+ -webkit-box-flex: 0;
1637
+ -webkit-flex: 0 0 25%;
1638
+ -moz-box-flex: 0;
1639
+ -ms-flex: 0 0 25%;
1640
+ flex: 0 0 25%; }
1641
+ .l-grid__cell--3\/4--widescreen, .l-grid__cell--6\/8--widescreen, .l-grid__cell--9\/12--widescreen, .l-grid__cell--12\/16--widescreen {
1642
+ max-width: 75%;
1643
+ -webkit-box-flex: 0;
1644
+ -webkit-flex: 0 0 75%;
1645
+ -moz-box-flex: 0;
1646
+ -ms-flex: 0 0 75%;
1647
+ flex: 0 0 75%; }
1648
+ .l-grid__cell--1\/5--widescreen, .l-grid__cell--2\/10--widescreen {
1649
+ max-width: 20%;
1650
+ -webkit-box-flex: 0;
1651
+ -webkit-flex: 0 0 20%;
1652
+ -moz-box-flex: 0;
1653
+ -ms-flex: 0 0 20%;
1654
+ flex: 0 0 20%; }
1655
+ .l-grid__cell--2\/5--widescreen, .l-grid__cell--4\/10--widescreen {
1656
+ max-width: 40%;
1657
+ -webkit-box-flex: 0;
1658
+ -webkit-flex: 0 0 40%;
1659
+ -moz-box-flex: 0;
1660
+ -ms-flex: 0 0 40%;
1661
+ flex: 0 0 40%; }
1662
+ .l-grid__cell--3\/5--widescreen, .l-grid__cell--6\/10--widescreen {
1663
+ max-width: 60%;
1664
+ -webkit-box-flex: 0;
1665
+ -webkit-flex: 0 0 60%;
1666
+ -moz-box-flex: 0;
1667
+ -ms-flex: 0 0 60%;
1668
+ flex: 0 0 60%; }
1669
+ .l-grid__cell--4\/5--widescreen, .l-grid__cell--8\/10--widescreen {
1670
+ max-width: 80%;
1671
+ -webkit-box-flex: 0;
1672
+ -webkit-flex: 0 0 80%;
1673
+ -moz-box-flex: 0;
1674
+ -ms-flex: 0 0 80%;
1675
+ flex: 0 0 80%; }
1676
+ .l-grid__cell--1\/6--widescreen, .l-grid__cell--2\/12--widescreen {
1677
+ max-width: 16.66667%;
1678
+ -webkit-box-flex: 0;
1679
+ -webkit-flex: 0 0 16.66667%;
1680
+ -moz-box-flex: 0;
1681
+ -ms-flex: 0 0 16.66667%;
1682
+ flex: 0 0 16.66667%; }
1683
+ .l-grid__cell--5\/6--widescreen, .l-grid__cell--10\/12--widescreen {
1684
+ max-width: 83.33333%;
1685
+ -webkit-box-flex: 0;
1686
+ -webkit-flex: 0 0 83.33333%;
1687
+ -moz-box-flex: 0;
1688
+ -ms-flex: 0 0 83.33333%;
1689
+ flex: 0 0 83.33333%; }
1690
+ .l-grid__cell--1\/8--widescreen, .l-grid__cell--2\/16--widescreen {
1691
+ max-width: 12.5%;
1692
+ -webkit-box-flex: 0;
1693
+ -webkit-flex: 0 0 12.5%;
1694
+ -moz-box-flex: 0;
1695
+ -ms-flex: 0 0 12.5%;
1696
+ flex: 0 0 12.5%; }
1697
+ .l-grid__cell--3\/8--widescreen, .l-grid__cell--6\/16--widescreen {
1698
+ max-width: 37.5%;
1699
+ -webkit-box-flex: 0;
1700
+ -webkit-flex: 0 0 37.5%;
1701
+ -moz-box-flex: 0;
1702
+ -ms-flex: 0 0 37.5%;
1703
+ flex: 0 0 37.5%; }
1704
+ .l-grid__cell--5\/8--widescreen, .l-grid__cell--10\/16--widescreen {
1705
+ max-width: 62.5%;
1706
+ -webkit-box-flex: 0;
1707
+ -webkit-flex: 0 0 62.5%;
1708
+ -moz-box-flex: 0;
1709
+ -ms-flex: 0 0 62.5%;
1710
+ flex: 0 0 62.5%; }
1711
+ .l-grid__cell--7\/8--widescreen, .l-grid__cell--14\/16--widescreen {
1712
+ max-width: 87.5%;
1713
+ -webkit-box-flex: 0;
1714
+ -webkit-flex: 0 0 87.5%;
1715
+ -moz-box-flex: 0;
1716
+ -ms-flex: 0 0 87.5%;
1717
+ flex: 0 0 87.5%; }
1718
+ .l-grid__cell--1\/10--widescreen {
1719
+ max-width: 10%;
1720
+ -webkit-box-flex: 0;
1721
+ -webkit-flex: 0 0 10%;
1722
+ -moz-box-flex: 0;
1723
+ -ms-flex: 0 0 10%;
1724
+ flex: 0 0 10%; }
1725
+ .l-grid__cell--3\/10--widescreen {
1726
+ max-width: 30%;
1727
+ -webkit-box-flex: 0;
1728
+ -webkit-flex: 0 0 30%;
1729
+ -moz-box-flex: 0;
1730
+ -ms-flex: 0 0 30%;
1731
+ flex: 0 0 30%; }
1732
+ .l-grid__cell--7\/10--widescreen {
1733
+ max-width: 70%;
1734
+ -webkit-box-flex: 0;
1735
+ -webkit-flex: 0 0 70%;
1736
+ -moz-box-flex: 0;
1737
+ -ms-flex: 0 0 70%;
1738
+ flex: 0 0 70%; }
1739
+ .l-grid__cell--9\/10--widescreen {
1740
+ max-width: 90%;
1741
+ -webkit-box-flex: 0;
1742
+ -webkit-flex: 0 0 90%;
1743
+ -moz-box-flex: 0;
1744
+ -ms-flex: 0 0 90%;
1745
+ flex: 0 0 90%; }
1746
+ .l-grid__cell--1\/12--widescreen {
1747
+ max-width: 8.33333%;
1748
+ -webkit-box-flex: 0;
1749
+ -webkit-flex: 0 0 8.33333%;
1750
+ -moz-box-flex: 0;
1751
+ -ms-flex: 0 0 8.33333%;
1752
+ flex: 0 0 8.33333%; }
1753
+ .l-grid__cell--5\/12--widescreen {
1754
+ max-width: 41.66667%;
1755
+ -webkit-box-flex: 0;
1756
+ -webkit-flex: 0 0 41.66667%;
1757
+ -moz-box-flex: 0;
1758
+ -ms-flex: 0 0 41.66667%;
1759
+ flex: 0 0 41.66667%; }
1760
+ .l-grid__cell--7\/12--widescreen {
1761
+ max-width: 58.33333%;
1762
+ -webkit-box-flex: 0;
1763
+ -webkit-flex: 0 0 58.33333%;
1764
+ -moz-box-flex: 0;
1765
+ -ms-flex: 0 0 58.33333%;
1766
+ flex: 0 0 58.33333%; }
1767
+ .l-grid__cell--11\/12--widescreen {
1768
+ max-width: 91.66667%;
1769
+ -webkit-box-flex: 0;
1770
+ -webkit-flex: 0 0 91.66667%;
1771
+ -moz-box-flex: 0;
1772
+ -ms-flex: 0 0 91.66667%;
1773
+ flex: 0 0 91.66667%; }
1774
+ .l-grid__cell--1\/14--widescreen {
1775
+ max-width: 7.14286%;
1776
+ -webkit-box-flex: 0;
1777
+ -webkit-flex: 0 0 7.14286%;
1778
+ -moz-box-flex: 0;
1779
+ -ms-flex: 0 0 7.14286%;
1780
+ flex: 0 0 7.14286%; }
1781
+ .l-grid__cell--2\/14--widescreen {
1782
+ max-width: 14.28571%;
1783
+ -webkit-box-flex: 0;
1784
+ -webkit-flex: 0 0 14.28571%;
1785
+ -moz-box-flex: 0;
1786
+ -ms-flex: 0 0 14.28571%;
1787
+ flex: 0 0 14.28571%; }
1788
+ .l-grid__cell--3\/14--widescreen {
1789
+ max-width: 21.42857%;
1790
+ -webkit-box-flex: 0;
1791
+ -webkit-flex: 0 0 21.42857%;
1792
+ -moz-box-flex: 0;
1793
+ -ms-flex: 0 0 21.42857%;
1794
+ flex: 0 0 21.42857%; }
1795
+ .l-grid__cell--4\/14--widescreen {
1796
+ max-width: 28.57143%;
1797
+ -webkit-box-flex: 0;
1798
+ -webkit-flex: 0 0 28.57143%;
1799
+ -moz-box-flex: 0;
1800
+ -ms-flex: 0 0 28.57143%;
1801
+ flex: 0 0 28.57143%; }
1802
+ .l-grid__cell--5\/14--widescreen {
1803
+ max-width: 35.71429%;
1804
+ -webkit-box-flex: 0;
1805
+ -webkit-flex: 0 0 35.71429%;
1806
+ -moz-box-flex: 0;
1807
+ -ms-flex: 0 0 35.71429%;
1808
+ flex: 0 0 35.71429%; }
1809
+ .l-grid__cell--6\/14--widescreen {
1810
+ max-width: 42.85714%;
1811
+ -webkit-box-flex: 0;
1812
+ -webkit-flex: 0 0 42.85714%;
1813
+ -moz-box-flex: 0;
1814
+ -ms-flex: 0 0 42.85714%;
1815
+ flex: 0 0 42.85714%; }
1816
+ .l-grid__cell--8\/14--widescreen {
1817
+ max-width: 57.14286%;
1818
+ -webkit-box-flex: 0;
1819
+ -webkit-flex: 0 0 57.14286%;
1820
+ -moz-box-flex: 0;
1821
+ -ms-flex: 0 0 57.14286%;
1822
+ flex: 0 0 57.14286%; }
1823
+ .l-grid__cell--9\/14--widescreen {
1824
+ max-width: 64.28571%;
1825
+ -webkit-box-flex: 0;
1826
+ -webkit-flex: 0 0 64.28571%;
1827
+ -moz-box-flex: 0;
1828
+ -ms-flex: 0 0 64.28571%;
1829
+ flex: 0 0 64.28571%; }
1830
+ .l-grid__cell--10\/14--widescreen {
1831
+ max-width: 71.42857%;
1832
+ -webkit-box-flex: 0;
1833
+ -webkit-flex: 0 0 71.42857%;
1834
+ -moz-box-flex: 0;
1835
+ -ms-flex: 0 0 71.42857%;
1836
+ flex: 0 0 71.42857%; }
1837
+ .l-grid__cell--11\/14--widescreen {
1838
+ max-width: 78.57143%;
1839
+ -webkit-box-flex: 0;
1840
+ -webkit-flex: 0 0 78.57143%;
1841
+ -moz-box-flex: 0;
1842
+ -ms-flex: 0 0 78.57143%;
1843
+ flex: 0 0 78.57143%; }
1844
+ .l-grid__cell--12\/14--widescreen {
1845
+ max-width: 85.71429%;
1846
+ -webkit-box-flex: 0;
1847
+ -webkit-flex: 0 0 85.71429%;
1848
+ -moz-box-flex: 0;
1849
+ -ms-flex: 0 0 85.71429%;
1850
+ flex: 0 0 85.71429%; }
1851
+ .l-grid__cell--13\/14--widescreen {
1852
+ max-width: 92.85714%;
1853
+ -webkit-box-flex: 0;
1854
+ -webkit-flex: 0 0 92.85714%;
1855
+ -moz-box-flex: 0;
1856
+ -ms-flex: 0 0 92.85714%;
1857
+ flex: 0 0 92.85714%; }
1858
+ .l-grid__cell--1\/16--widescreen {
1859
+ max-width: 6.25%;
1860
+ -webkit-box-flex: 0;
1861
+ -webkit-flex: 0 0 6.25%;
1862
+ -moz-box-flex: 0;
1863
+ -ms-flex: 0 0 6.25%;
1864
+ flex: 0 0 6.25%; }
1865
+ .l-grid__cell--3\/16--widescreen {
1866
+ max-width: 18.75%;
1867
+ -webkit-box-flex: 0;
1868
+ -webkit-flex: 0 0 18.75%;
1869
+ -moz-box-flex: 0;
1870
+ -ms-flex: 0 0 18.75%;
1871
+ flex: 0 0 18.75%; }
1872
+ .l-grid__cell--5\/16--widescreen {
1873
+ max-width: 31.25%;
1874
+ -webkit-box-flex: 0;
1875
+ -webkit-flex: 0 0 31.25%;
1876
+ -moz-box-flex: 0;
1877
+ -ms-flex: 0 0 31.25%;
1878
+ flex: 0 0 31.25%; }
1879
+ .l-grid__cell--7\/16--widescreen {
1880
+ max-width: 43.75%;
1881
+ -webkit-box-flex: 0;
1882
+ -webkit-flex: 0 0 43.75%;
1883
+ -moz-box-flex: 0;
1884
+ -ms-flex: 0 0 43.75%;
1885
+ flex: 0 0 43.75%; }
1886
+ .l-grid__cell--9\/16--widescreen {
1887
+ max-width: 56.25%;
1888
+ -webkit-box-flex: 0;
1889
+ -webkit-flex: 0 0 56.25%;
1890
+ -moz-box-flex: 0;
1891
+ -ms-flex: 0 0 56.25%;
1892
+ flex: 0 0 56.25%; }
1893
+ .l-grid__cell--11\/16--widescreen {
1894
+ max-width: 68.75%;
1895
+ -webkit-box-flex: 0;
1896
+ -webkit-flex: 0 0 68.75%;
1897
+ -moz-box-flex: 0;
1898
+ -ms-flex: 0 0 68.75%;
1899
+ flex: 0 0 68.75%; }
1900
+ .l-grid__cell--13\/16--widescreen {
1901
+ max-width: 81.25%;
1902
+ -webkit-box-flex: 0;
1903
+ -webkit-flex: 0 0 81.25%;
1904
+ -moz-box-flex: 0;
1905
+ -ms-flex: 0 0 81.25%;
1906
+ flex: 0 0 81.25%; }
1907
+ .l-grid__cell--15\/16--widescreen {
1908
+ max-width: 93.75%;
1909
+ -webkit-box-flex: 0;
1910
+ -webkit-flex: 0 0 93.75%;
1911
+ -moz-box-flex: 0;
1912
+ -ms-flex: 0 0 93.75%;
1913
+ flex: 0 0 93.75%; }
1914
+ .l-grid--hor-center--widescreen {
1915
+ -webkit-box-pack: center;
1916
+ -webkit-justify-content: center;
1917
+ -moz-box-pack: center;
1918
+ -ms-flex-pack: center;
1919
+ justify-content: center; }
1920
+ .l-grid--hor-right--widescreen {
1921
+ -webkit-box-pack: end;
1922
+ -webkit-justify-content: flex-end;
1923
+ -moz-box-pack: end;
1924
+ -ms-flex-pack: end;
1925
+ justify-content: flex-end; }
1926
+ .l-grid--ver-center--widescreen {
1927
+ -webkit-box-align: center;
1928
+ -webkit-align-items: center;
1929
+ -moz-box-align: center;
1930
+ -ms-flex-align: center;
1931
+ align-items: center; }
1932
+ .l-grid--ver-bottom--widescreen {
1933
+ -webkit-box-align: end;
1934
+ -webkit-align-items: flex-end;
1935
+ -moz-box-align: end;
1936
+ -ms-flex-align: end;
1937
+ align-items: flex-end; }
1938
+ .l-grid--auto--widescreen > .l-grid__cell {
1939
+ -webkit-flex-basis: 0;
1940
+ -ms-flex-preferred-size: 0;
1941
+ flex-basis: 0; } }
1942
+
1943
+ @media screen and (-webkit-min-device-pixel-ratio: 2), screen and (min-resolution: 192dpi), screen and (min-resolution: 2dppx) {
1944
+ .l-grid__cell--1\/2--retina, .l-grid__cell--2\/4--retina, .l-grid__cell--3\/6--retina, .l-grid__cell--4\/8--retina, .l-grid__cell--5\/10--retina, .l-grid__cell--6\/12--retina, .l-grid__cell--7\/14--retina, .l-grid__cell--8\/16--retina {
1945
+ max-width: 50%;
1946
+ -webkit-box-flex: 0;
1947
+ -webkit-flex: 0 0 50%;
1948
+ -moz-box-flex: 0;
1949
+ -ms-flex: 0 0 50%;
1950
+ flex: 0 0 50%; }
1951
+ .l-grid__cell--1\/3--retina, .l-grid__cell--2\/6--retina, .l-grid__cell--4\/12--retina {
1952
+ max-width: 33.33333%;
1953
+ -webkit-box-flex: 0;
1954
+ -webkit-flex: 0 0 33.33333%;
1955
+ -moz-box-flex: 0;
1956
+ -ms-flex: 0 0 33.33333%;
1957
+ flex: 0 0 33.33333%; }
1958
+ .l-grid__cell--2\/3--retina, .l-grid__cell--4\/6--retina, .l-grid__cell--8\/12--retina {
1959
+ max-width: 66.66667%;
1960
+ -webkit-box-flex: 0;
1961
+ -webkit-flex: 0 0 66.66667%;
1962
+ -moz-box-flex: 0;
1963
+ -ms-flex: 0 0 66.66667%;
1964
+ flex: 0 0 66.66667%; }
1965
+ .l-grid__cell--1\/4--retina, .l-grid__cell--2\/8--retina, .l-grid__cell--3\/12--retina, .l-grid__cell--4\/16--retina {
1966
+ max-width: 25%;
1967
+ -webkit-box-flex: 0;
1968
+ -webkit-flex: 0 0 25%;
1969
+ -moz-box-flex: 0;
1970
+ -ms-flex: 0 0 25%;
1971
+ flex: 0 0 25%; }
1972
+ .l-grid__cell--3\/4--retina, .l-grid__cell--6\/8--retina, .l-grid__cell--9\/12--retina, .l-grid__cell--12\/16--retina {
1973
+ max-width: 75%;
1974
+ -webkit-box-flex: 0;
1975
+ -webkit-flex: 0 0 75%;
1976
+ -moz-box-flex: 0;
1977
+ -ms-flex: 0 0 75%;
1978
+ flex: 0 0 75%; }
1979
+ .l-grid__cell--1\/5--retina, .l-grid__cell--2\/10--retina {
1980
+ max-width: 20%;
1981
+ -webkit-box-flex: 0;
1982
+ -webkit-flex: 0 0 20%;
1983
+ -moz-box-flex: 0;
1984
+ -ms-flex: 0 0 20%;
1985
+ flex: 0 0 20%; }
1986
+ .l-grid__cell--2\/5--retina, .l-grid__cell--4\/10--retina {
1987
+ max-width: 40%;
1988
+ -webkit-box-flex: 0;
1989
+ -webkit-flex: 0 0 40%;
1990
+ -moz-box-flex: 0;
1991
+ -ms-flex: 0 0 40%;
1992
+ flex: 0 0 40%; }
1993
+ .l-grid__cell--3\/5--retina, .l-grid__cell--6\/10--retina {
1994
+ max-width: 60%;
1995
+ -webkit-box-flex: 0;
1996
+ -webkit-flex: 0 0 60%;
1997
+ -moz-box-flex: 0;
1998
+ -ms-flex: 0 0 60%;
1999
+ flex: 0 0 60%; }
2000
+ .l-grid__cell--4\/5--retina, .l-grid__cell--8\/10--retina {
2001
+ max-width: 80%;
2002
+ -webkit-box-flex: 0;
2003
+ -webkit-flex: 0 0 80%;
2004
+ -moz-box-flex: 0;
2005
+ -ms-flex: 0 0 80%;
2006
+ flex: 0 0 80%; }
2007
+ .l-grid__cell--1\/6--retina, .l-grid__cell--2\/12--retina {
2008
+ max-width: 16.66667%;
2009
+ -webkit-box-flex: 0;
2010
+ -webkit-flex: 0 0 16.66667%;
2011
+ -moz-box-flex: 0;
2012
+ -ms-flex: 0 0 16.66667%;
2013
+ flex: 0 0 16.66667%; }
2014
+ .l-grid__cell--5\/6--retina, .l-grid__cell--10\/12--retina {
2015
+ max-width: 83.33333%;
2016
+ -webkit-box-flex: 0;
2017
+ -webkit-flex: 0 0 83.33333%;
2018
+ -moz-box-flex: 0;
2019
+ -ms-flex: 0 0 83.33333%;
2020
+ flex: 0 0 83.33333%; }
2021
+ .l-grid__cell--1\/8--retina, .l-grid__cell--2\/16--retina {
2022
+ max-width: 12.5%;
2023
+ -webkit-box-flex: 0;
2024
+ -webkit-flex: 0 0 12.5%;
2025
+ -moz-box-flex: 0;
2026
+ -ms-flex: 0 0 12.5%;
2027
+ flex: 0 0 12.5%; }
2028
+ .l-grid__cell--3\/8--retina, .l-grid__cell--6\/16--retina {
2029
+ max-width: 37.5%;
2030
+ -webkit-box-flex: 0;
2031
+ -webkit-flex: 0 0 37.5%;
2032
+ -moz-box-flex: 0;
2033
+ -ms-flex: 0 0 37.5%;
2034
+ flex: 0 0 37.5%; }
2035
+ .l-grid__cell--5\/8--retina, .l-grid__cell--10\/16--retina {
2036
+ max-width: 62.5%;
2037
+ -webkit-box-flex: 0;
2038
+ -webkit-flex: 0 0 62.5%;
2039
+ -moz-box-flex: 0;
2040
+ -ms-flex: 0 0 62.5%;
2041
+ flex: 0 0 62.5%; }
2042
+ .l-grid__cell--7\/8--retina, .l-grid__cell--14\/16--retina {
2043
+ max-width: 87.5%;
2044
+ -webkit-box-flex: 0;
2045
+ -webkit-flex: 0 0 87.5%;
2046
+ -moz-box-flex: 0;
2047
+ -ms-flex: 0 0 87.5%;
2048
+ flex: 0 0 87.5%; }
2049
+ .l-grid__cell--1\/10--retina {
2050
+ max-width: 10%;
2051
+ -webkit-box-flex: 0;
2052
+ -webkit-flex: 0 0 10%;
2053
+ -moz-box-flex: 0;
2054
+ -ms-flex: 0 0 10%;
2055
+ flex: 0 0 10%; }
2056
+ .l-grid__cell--3\/10--retina {
2057
+ max-width: 30%;
2058
+ -webkit-box-flex: 0;
2059
+ -webkit-flex: 0 0 30%;
2060
+ -moz-box-flex: 0;
2061
+ -ms-flex: 0 0 30%;
2062
+ flex: 0 0 30%; }
2063
+ .l-grid__cell--7\/10--retina {
2064
+ max-width: 70%;
2065
+ -webkit-box-flex: 0;
2066
+ -webkit-flex: 0 0 70%;
2067
+ -moz-box-flex: 0;
2068
+ -ms-flex: 0 0 70%;
2069
+ flex: 0 0 70%; }
2070
+ .l-grid__cell--9\/10--retina {
2071
+ max-width: 90%;
2072
+ -webkit-box-flex: 0;
2073
+ -webkit-flex: 0 0 90%;
2074
+ -moz-box-flex: 0;
2075
+ -ms-flex: 0 0 90%;
2076
+ flex: 0 0 90%; }
2077
+ .l-grid__cell--1\/12--retina {
2078
+ max-width: 8.33333%;
2079
+ -webkit-box-flex: 0;
2080
+ -webkit-flex: 0 0 8.33333%;
2081
+ -moz-box-flex: 0;
2082
+ -ms-flex: 0 0 8.33333%;
2083
+ flex: 0 0 8.33333%; }
2084
+ .l-grid__cell--5\/12--retina {
2085
+ max-width: 41.66667%;
2086
+ -webkit-box-flex: 0;
2087
+ -webkit-flex: 0 0 41.66667%;
2088
+ -moz-box-flex: 0;
2089
+ -ms-flex: 0 0 41.66667%;
2090
+ flex: 0 0 41.66667%; }
2091
+ .l-grid__cell--7\/12--retina {
2092
+ max-width: 58.33333%;
2093
+ -webkit-box-flex: 0;
2094
+ -webkit-flex: 0 0 58.33333%;
2095
+ -moz-box-flex: 0;
2096
+ -ms-flex: 0 0 58.33333%;
2097
+ flex: 0 0 58.33333%; }
2098
+ .l-grid__cell--11\/12--retina {
2099
+ max-width: 91.66667%;
2100
+ -webkit-box-flex: 0;
2101
+ -webkit-flex: 0 0 91.66667%;
2102
+ -moz-box-flex: 0;
2103
+ -ms-flex: 0 0 91.66667%;
2104
+ flex: 0 0 91.66667%; }
2105
+ .l-grid__cell--1\/14--retina {
2106
+ max-width: 7.14286%;
2107
+ -webkit-box-flex: 0;
2108
+ -webkit-flex: 0 0 7.14286%;
2109
+ -moz-box-flex: 0;
2110
+ -ms-flex: 0 0 7.14286%;
2111
+ flex: 0 0 7.14286%; }
2112
+ .l-grid__cell--2\/14--retina {
2113
+ max-width: 14.28571%;
2114
+ -webkit-box-flex: 0;
2115
+ -webkit-flex: 0 0 14.28571%;
2116
+ -moz-box-flex: 0;
2117
+ -ms-flex: 0 0 14.28571%;
2118
+ flex: 0 0 14.28571%; }
2119
+ .l-grid__cell--3\/14--retina {
2120
+ max-width: 21.42857%;
2121
+ -webkit-box-flex: 0;
2122
+ -webkit-flex: 0 0 21.42857%;
2123
+ -moz-box-flex: 0;
2124
+ -ms-flex: 0 0 21.42857%;
2125
+ flex: 0 0 21.42857%; }
2126
+ .l-grid__cell--4\/14--retina {
2127
+ max-width: 28.57143%;
2128
+ -webkit-box-flex: 0;
2129
+ -webkit-flex: 0 0 28.57143%;
2130
+ -moz-box-flex: 0;
2131
+ -ms-flex: 0 0 28.57143%;
2132
+ flex: 0 0 28.57143%; }
2133
+ .l-grid__cell--5\/14--retina {
2134
+ max-width: 35.71429%;
2135
+ -webkit-box-flex: 0;
2136
+ -webkit-flex: 0 0 35.71429%;
2137
+ -moz-box-flex: 0;
2138
+ -ms-flex: 0 0 35.71429%;
2139
+ flex: 0 0 35.71429%; }
2140
+ .l-grid__cell--6\/14--retina {
2141
+ max-width: 42.85714%;
2142
+ -webkit-box-flex: 0;
2143
+ -webkit-flex: 0 0 42.85714%;
2144
+ -moz-box-flex: 0;
2145
+ -ms-flex: 0 0 42.85714%;
2146
+ flex: 0 0 42.85714%; }
2147
+ .l-grid__cell--8\/14--retina {
2148
+ max-width: 57.14286%;
2149
+ -webkit-box-flex: 0;
2150
+ -webkit-flex: 0 0 57.14286%;
2151
+ -moz-box-flex: 0;
2152
+ -ms-flex: 0 0 57.14286%;
2153
+ flex: 0 0 57.14286%; }
2154
+ .l-grid__cell--9\/14--retina {
2155
+ max-width: 64.28571%;
2156
+ -webkit-box-flex: 0;
2157
+ -webkit-flex: 0 0 64.28571%;
2158
+ -moz-box-flex: 0;
2159
+ -ms-flex: 0 0 64.28571%;
2160
+ flex: 0 0 64.28571%; }
2161
+ .l-grid__cell--10\/14--retina {
2162
+ max-width: 71.42857%;
2163
+ -webkit-box-flex: 0;
2164
+ -webkit-flex: 0 0 71.42857%;
2165
+ -moz-box-flex: 0;
2166
+ -ms-flex: 0 0 71.42857%;
2167
+ flex: 0 0 71.42857%; }
2168
+ .l-grid__cell--11\/14--retina {
2169
+ max-width: 78.57143%;
2170
+ -webkit-box-flex: 0;
2171
+ -webkit-flex: 0 0 78.57143%;
2172
+ -moz-box-flex: 0;
2173
+ -ms-flex: 0 0 78.57143%;
2174
+ flex: 0 0 78.57143%; }
2175
+ .l-grid__cell--12\/14--retina {
2176
+ max-width: 85.71429%;
2177
+ -webkit-box-flex: 0;
2178
+ -webkit-flex: 0 0 85.71429%;
2179
+ -moz-box-flex: 0;
2180
+ -ms-flex: 0 0 85.71429%;
2181
+ flex: 0 0 85.71429%; }
2182
+ .l-grid__cell--13\/14--retina {
2183
+ max-width: 92.85714%;
2184
+ -webkit-box-flex: 0;
2185
+ -webkit-flex: 0 0 92.85714%;
2186
+ -moz-box-flex: 0;
2187
+ -ms-flex: 0 0 92.85714%;
2188
+ flex: 0 0 92.85714%; }
2189
+ .l-grid__cell--1\/16--retina {
2190
+ max-width: 6.25%;
2191
+ -webkit-box-flex: 0;
2192
+ -webkit-flex: 0 0 6.25%;
2193
+ -moz-box-flex: 0;
2194
+ -ms-flex: 0 0 6.25%;
2195
+ flex: 0 0 6.25%; }
2196
+ .l-grid__cell--3\/16--retina {
2197
+ max-width: 18.75%;
2198
+ -webkit-box-flex: 0;
2199
+ -webkit-flex: 0 0 18.75%;
2200
+ -moz-box-flex: 0;
2201
+ -ms-flex: 0 0 18.75%;
2202
+ flex: 0 0 18.75%; }
2203
+ .l-grid__cell--5\/16--retina {
2204
+ max-width: 31.25%;
2205
+ -webkit-box-flex: 0;
2206
+ -webkit-flex: 0 0 31.25%;
2207
+ -moz-box-flex: 0;
2208
+ -ms-flex: 0 0 31.25%;
2209
+ flex: 0 0 31.25%; }
2210
+ .l-grid__cell--7\/16--retina {
2211
+ max-width: 43.75%;
2212
+ -webkit-box-flex: 0;
2213
+ -webkit-flex: 0 0 43.75%;
2214
+ -moz-box-flex: 0;
2215
+ -ms-flex: 0 0 43.75%;
2216
+ flex: 0 0 43.75%; }
2217
+ .l-grid__cell--9\/16--retina {
2218
+ max-width: 56.25%;
2219
+ -webkit-box-flex: 0;
2220
+ -webkit-flex: 0 0 56.25%;
2221
+ -moz-box-flex: 0;
2222
+ -ms-flex: 0 0 56.25%;
2223
+ flex: 0 0 56.25%; }
2224
+ .l-grid__cell--11\/16--retina {
2225
+ max-width: 68.75%;
2226
+ -webkit-box-flex: 0;
2227
+ -webkit-flex: 0 0 68.75%;
2228
+ -moz-box-flex: 0;
2229
+ -ms-flex: 0 0 68.75%;
2230
+ flex: 0 0 68.75%; }
2231
+ .l-grid__cell--13\/16--retina {
2232
+ max-width: 81.25%;
2233
+ -webkit-box-flex: 0;
2234
+ -webkit-flex: 0 0 81.25%;
2235
+ -moz-box-flex: 0;
2236
+ -ms-flex: 0 0 81.25%;
2237
+ flex: 0 0 81.25%; }
2238
+ .l-grid__cell--15\/16--retina {
2239
+ max-width: 93.75%;
2240
+ -webkit-box-flex: 0;
2241
+ -webkit-flex: 0 0 93.75%;
2242
+ -moz-box-flex: 0;
2243
+ -ms-flex: 0 0 93.75%;
2244
+ flex: 0 0 93.75%; }
2245
+ .l-grid--hor-center--retina {
2246
+ -webkit-box-pack: center;
2247
+ -webkit-justify-content: center;
2248
+ -moz-box-pack: center;
2249
+ -ms-flex-pack: center;
2250
+ justify-content: center; }
2251
+ .l-grid--hor-right--retina {
2252
+ -webkit-box-pack: end;
2253
+ -webkit-justify-content: flex-end;
2254
+ -moz-box-pack: end;
2255
+ -ms-flex-pack: end;
2256
+ justify-content: flex-end; }
2257
+ .l-grid--ver-center--retina {
2258
+ -webkit-box-align: center;
2259
+ -webkit-align-items: center;
2260
+ -moz-box-align: center;
2261
+ -ms-flex-align: center;
2262
+ align-items: center; }
2263
+ .l-grid--ver-bottom--retina {
2264
+ -webkit-box-align: end;
2265
+ -webkit-align-items: flex-end;
2266
+ -moz-box-align: end;
2267
+ -ms-flex-align: end;
2268
+ align-items: flex-end; }
2269
+ .l-grid--auto--retina > .l-grid__cell {
2270
+ -webkit-flex-basis: 0;
2271
+ -ms-flex-preferred-size: 0;
2272
+ flex-basis: 0; } }
2273
+
2274
+ /*------------------------------------* #GROUP
2275
+
2276
+ Base:
2277
+ .l-group
2278
+ .l-group__item
2279
+
2280
+
2281
+ L_GROUP MODIFIERS:
2282
+
2283
+ Display modifiers:
2284
+ .l-group--block
2285
+
2286
+ Horizontal alignment modifiers:
2287
+ .l-group--hor-center
2288
+ .l-group--hor-right
2289
+ .l-group--hor-space-between
2290
+
2291
+ Vertical alignment modifiers:
2292
+ .l-group--ver-center
2293
+ .l-group--ver-bottom
2294
+ .l-group--ver-stretch
2295
+
2296
+ Spacing modifiers:
2297
+ .l-group--secondary
2298
+ .l-group--tertiary
2299
+ .l-group--quaternary
2300
+
2301
+
2302
+ L_GROUP__ITEM MODIFIERS:
2303
+
2304
+ Vertical alignment modifiers:
2305
+ .l-group__item--bottom
2306
+ .l-group__item--center
2307
+ .l-group__item--top
2308
+
2309
+ Horizontal alignment modifiers:
2310
+ .l-group__item--left
2311
+ .l-group__item--right
2312
+
2313
+ Size modifiers:
2314
+ .l-group__item--grow
2315
+
2316
+ \*------------------------------------*/
2317
+ /*------------------------------------* .l-group
2318
+ \*------------------------------------*/
2319
+ .l-group {
2320
+ display: -webkit-inline-box;
2321
+ display: -webkit-inline-flex;
2322
+ display: -moz-inline-box;
2323
+ display: -ms-inline-flexbox;
2324
+ display: inline-flex;
2325
+ -webkit-box-align: start;
2326
+ -webkit-align-items: flex-start;
2327
+ -moz-box-align: start;
2328
+ -ms-flex-align: start;
2329
+ align-items: flex-start;
2330
+ -webkit-box-pack: start;
2331
+ -webkit-justify-content: flex-start;
2332
+ -moz-box-pack: start;
2333
+ -ms-flex-pack: start;
2334
+ justify-content: flex-start; }
2335
+
2336
+ .l-group--block {
2337
+ display: -webkit-box;
2338
+ display: -webkit-flex;
2339
+ display: -moz-box;
2340
+ display: -ms-flexbox;
2341
+ display: flex;
2342
+ width: 100%; }
2343
+
2344
+ .l-group--hor-center {
2345
+ -webkit-box-pack: center;
2346
+ -webkit-justify-content: center;
2347
+ -moz-box-pack: center;
2348
+ -ms-flex-pack: center;
2349
+ justify-content: center; }
2350
+
2351
+ .l-group--hor-right {
2352
+ -webkit-box-pack: end;
2353
+ -webkit-justify-content: flex-end;
2354
+ -moz-box-pack: end;
2355
+ -ms-flex-pack: end;
2356
+ justify-content: flex-end; }
2357
+
2358
+ .l-group--ver-center {
2359
+ -webkit-box-align: center;
2360
+ -webkit-align-items: center;
2361
+ -moz-box-align: center;
2362
+ -ms-flex-align: center;
2363
+ align-items: center; }
2364
+
2365
+ .l-group--ver-bottom {
2366
+ -webkit-box-align: end;
2367
+ -webkit-align-items: flex-end;
2368
+ -moz-box-align: end;
2369
+ -ms-flex-align: end;
2370
+ align-items: flex-end; }
2371
+
2372
+ .l-group--ver-stretch {
2373
+ -webkit-box-align: stretch;
2374
+ -webkit-align-items: stretch;
2375
+ -moz-box-align: stretch;
2376
+ -ms-flex-align: stretch;
2377
+ align-items: stretch; }
2378
+
2379
+ .l-group--hor-space-between {
2380
+ -webkit-box-pack: justify;
2381
+ -webkit-justify-content: space-between;
2382
+ -moz-box-pack: justify;
2383
+ -ms-flex-pack: justify;
2384
+ justify-content: space-between; }
2385
+
2386
+ /*------------------------------------* .l-group__item
2387
+ \*------------------------------------*/
2388
+ .l-group__item + .l-group__item {
2389
+ margin-left: 10px; }
2390
+ .l-group--no-space > .l-group__item + .l-group__item {
2391
+ margin-left: 0; }
2392
+ .l-group--secondary > .l-group__item + .l-group__item {
2393
+ margin-left: 15px; }
2394
+ .l-group--tertiary > .l-group__item + .l-group__item {
2395
+ margin-left: 20px; }
2396
+ .l-group--quaternary > .l-group__item + .l-group__item {
2397
+ margin-left: 30px; }
2398
+
2399
+ .l-group__item--bottom {
2400
+ -webkit-align-self: flex-end;
2401
+ -ms-flex-item-align: end;
2402
+ align-self: flex-end; }
2403
+
2404
+ .l-group__item--center {
2405
+ -webkit-align-self: center;
2406
+ -ms-flex-item-align: center;
2407
+ align-self: center; }
2408
+
2409
+ .l-group__item--top {
2410
+ -webkit-align-self: flex-start;
2411
+ -ms-flex-item-align: start;
2412
+ align-self: flex-start; }
2413
+
2414
+ .l-group__item--left {
2415
+ margin-right: auto; }
2416
+ .l-group__item + .l-group__item--left {
2417
+ margin-right: auto; }
2418
+
2419
+ .l-group__item--right {
2420
+ margin-left: auto; }
2421
+ .l-group__item + .l-group__item--right {
2422
+ margin-left: auto; }
2423
+
2424
+ .l-group__item--grow {
2425
+ -webkit-box-flex: 1;
2426
+ -webkit-flex-grow: 1;
2427
+ -moz-box-flex: 1;
2428
+ -ms-flex-positive: 1;
2429
+ flex-grow: 1; }
2430
+
2431
+ /*------------------------------------* #OVERLAY
2432
+ \*------------------------------------*/
2433
+ .l-overlay {
2434
+ position: fixed;
2435
+ width: 100%;
2436
+ height: 100%;
2437
+ z-index: 20000;
2438
+ top: 0;
2439
+ left: 0; }
2440
+
2441
+ /*------------------------------------* #SPACE
2442
+
2443
+ .l-space-primary
2444
+ .l-space-secondary
2445
+ .l-space-tertiary
2446
+ .l-space-quaternary
2447
+
2448
+ .l-space-ver-primary
2449
+ .l-space-ver-secondary
2450
+ .l-space-ver-tertiary
2451
+ .l-space-ver-quaternary
2452
+
2453
+ .l-space-hor-primary
2454
+ .l-space-hor-secondary
2455
+ .l-space-hor-tertiary
2456
+ .l-space-hor-quaternary
2457
+
2458
+ .l-space-top-primary
2459
+ .l-space-top-secondary
2460
+ .l-space-top-tertiary
2461
+ .l-space-top-quaternary
2462
+
2463
+ .l-space-right-primary
2464
+ .l-space-right-secondary
2465
+ .l-space-right-tertiary
2466
+ .l-space-right-quaternary
2467
+
2468
+ .l-space-bottom-primary
2469
+ .l-space-bottom-secondary
2470
+ .l-space-bottom-tertiary
2471
+ .l-space-bottom-quaternary
2472
+
2473
+ .l-space-left-primary
2474
+ .l-space-left-secondary
2475
+ .l-space-left-tertiary
2476
+ .l-space-left-quaternary
2477
+ \*------------------------------------*/
2478
+ /*------------------------------------* .l-space
2479
+ \*------------------------------------*/
2480
+ .l-space-primary {
2481
+ padding: 10px; }
2482
+
2483
+ .l-space-secondary {
2484
+ padding: 15px; }
2485
+
2486
+ .l-space-tertiary {
2487
+ padding: 20px; }
2488
+
2489
+ .l-space-quaternary {
2490
+ padding: 30px; }
2491
+
2492
+ /*------------------------------------* .l-space-ver
2493
+ \*------------------------------------*/
2494
+ .l-space-ver-primary {
2495
+ padding-top: 10px;
2496
+ padding-bottom: 10px; }
2497
+
2498
+ .l-space-ver-secondary {
2499
+ padding-top: 15px;
2500
+ padding-bottom: 15px; }
2501
+
2502
+ .l-space-ver-tertiary {
2503
+ padding-top: 20px;
2504
+ padding-bottom: 20px; }
2505
+
2506
+ .l-space-ver-quaternary {
2507
+ padding-top: 30px;
2508
+ padding-bottom: 30px; }
2509
+
2510
+ /*------------------------------------* .l-space-hor
2511
+ \*------------------------------------*/
2512
+ .l-space-hor-primary {
2513
+ padding-left: 10px;
2514
+ padding-right: 10px; }
2515
+
2516
+ .l-space-hor-secondary {
2517
+ padding-left: 15px;
2518
+ padding-right: 15px; }
2519
+
2520
+ .l-space-hor-tertiary {
2521
+ padding-left: 20px;
2522
+ padding-right: 20px; }
2523
+
2524
+ .l-space-hor-quaternary {
2525
+ padding-left: 30px;
2526
+ padding-right: 30px; }
2527
+
2528
+ /*------------------------------------* .l-space-top
2529
+ \*------------------------------------*/
2530
+ .l-space-top-primary {
2531
+ padding-top: 10px; }
2532
+
2533
+ .l-space-top-secondary {
2534
+ padding-top: 15px; }
2535
+
2536
+ .l-space-top-tertiary {
2537
+ padding-top: 20px; }
2538
+
2539
+ .l-space-top-quaternary {
2540
+ padding-top: 30px; }
2541
+
2542
+ /*------------------------------------* .l-space-right
2543
+ \*------------------------------------*/
2544
+ .l-space-right-primary {
2545
+ padding-right: 10px; }
2546
+
2547
+ .l-space-right-secondary {
2548
+ padding-right: 15px; }
2549
+
2550
+ .l-space-right-tertiary {
2551
+ padding-right: 20px; }
2552
+
2553
+ .l-space-right-quaternary {
2554
+ padding-right: 30px; }
2555
+
2556
+ /*------------------------------------* .l-space-bottom
2557
+ \*------------------------------------*/
2558
+ .l-space-bottom-primary {
2559
+ padding-bottom: 10px; }
2560
+
2561
+ .l-space-bottom-secondary {
2562
+ padding-bottom: 15px; }
2563
+
2564
+ .l-space-bottom-tertiary {
2565
+ padding-bottom: 20px; }
2566
+
2567
+ .l-space-bottom-quaternary {
2568
+ padding-bottom: 30px; }
2569
+
2570
+ /*------------------------------------* .l-space-left
2571
+ \*------------------------------------*/
2572
+ .l-space-left-primary {
2573
+ padding-left: 10px; }
2574
+
2575
+ .l-space-left-secondary {
2576
+ padding-left: 15px; }
2577
+
2578
+ .l-space-left-tertiary {
2579
+ padding-left: 20px; }
2580
+
2581
+ .l-space-left-quaternary {
2582
+ padding-left: 30px; }
2583
+
2584
+ /*------------------------------------* #WRAPPER
2585
+
2586
+ Base:
2587
+ .l-wrapper
2588
+ \*------------------------------------*/
2589
+ .l-wrapper {
2590
+ margin: 0 auto; }
2591
+ @media screen and (min-width: 1070px) {
2592
+ .l-wrapper {
2593
+ width: 1070px; } }
2594
+
2595
+ /*------------------------------------* #BADGE
2596
+
2597
+ Base:
2598
+ .c-badge
2599
+
2600
+ Variant with text:
2601
+ .c-badge--has-text
2602
+
2603
+ Color modifiers:
2604
+ .c-badge--action
2605
+ .c-badge--danger
2606
+ .c-badge--inactive
2607
+ .c-badge--success
2608
+ .c-badge--warning
2609
+
2610
+ Position modifiers:
2611
+ .c-badge--for-button
2612
+ .c-badge--for-tab
2613
+ \*------------------------------------*/
2614
+ /*------------------------------------* .c-badge (default: circle)
2615
+ \*------------------------------------*/
2616
+ .c-badge {
2617
+ display: block;
2618
+ text-align: center;
2619
+ color: #ffffff;
2620
+ min-width: 8px;
2621
+ min-height: 8px;
2622
+ -webkit-border-radius: 8px;
2623
+ -moz-border-radius: 8px;
2624
+ border-radius: 8px;
2625
+ line-height: 8px; }
2626
+
2627
+ /*------------------------------------* variant with text
2628
+ \*------------------------------------*/
2629
+ .c-badge--has-text {
2630
+ font-size: 10px;
2631
+ padding: 0 6px;
2632
+ min-width: 17px;
2633
+ min-height: 17px;
2634
+ -webkit-border-radius: 17px;
2635
+ -moz-border-radius: 17px;
2636
+ border-radius: 17px;
2637
+ line-height: 17px; }
2638
+
2639
+ /*------------------------------------* colors
2640
+ \*------------------------------------*/
2641
+ .c-badge--action {
2642
+ background-color: #1e88e5; }
2643
+
2644
+ .c-badge--danger {
2645
+ background-color: #f44336; }
2646
+
2647
+ .c-badge--inactive {
2648
+ background-color: #a6b6be; }
2649
+
2650
+ .c-badge--success {
2651
+ background-color: #4caf50; }
2652
+
2653
+ .c-badge--warning {
2654
+ background-color: #ffc107; }
2655
+
2656
+ /*------------------------------------* position
2657
+ \*------------------------------------*/
2658
+ .c-badge--for-button {
2659
+ position: absolute;
2660
+ top: 0;
2661
+ left: 19px; }
2662
+
2663
+ .c-badge--for-tab {
2664
+ position: absolute;
2665
+ top: 14px;
2666
+ right: 7px; }
2667
+
2668
+ /*------------------------------------* #BUTTON
2669
+
2670
+ Base:
2671
+ .c-button
2672
+ .c-button__icon
2673
+ .c-button__text
2674
+
2675
+ Shape modifiers:
2676
+ .c-button--regular
2677
+ .c-button--floating
2678
+ .c-button--flat
2679
+ .c-button--toggle
2680
+ .c-button--clean
2681
+
2682
+ Color modifiers:
2683
+ .c-button--action
2684
+ .c-button--warning
2685
+ .c-button--danger
2686
+ .c-button--success
2687
+
2688
+ .c-button--twitter
2689
+ .c-button--google
2690
+ .c-button--facebook
2691
+ .c-button--drupal
2692
+ .c-button--wordpress
2693
+
2694
+ Size modifiers:
2695
+ .c-button--small
2696
+ .c-button--large
2697
+ .c-button--x-large
2698
+
2699
+ .c-button--block
2700
+
2701
+ State modifiers:
2702
+ .c-button.is-disabled / .c-button:disabled
2703
+ .c-button.is-active
2704
+ \*------------------------------------*/
2705
+ /*------------------------------------* .c-button__icon,
2706
+ .c-button__text
2707
+ \*------------------------------------*/
2708
+ .c-button__icon {
2709
+ line-height: inherit; }
2710
+
2711
+ .c-button__icon,
2712
+ .c-button__text {
2713
+ display: inline-block;
2714
+ vertical-align: top; }
2715
+
2716
+ .c-button__icon + .c-button__text,
2717
+ .c-button__text + .c-button__icon {
2718
+ margin-left: 10px; }
2719
+
2720
+ .c-button__icon.fa + .c-button__text,
2721
+ .c-button__text + .c-button__icon.fa {
2722
+ margin-left: 8px; }
2723
+
2724
+ /*------------------------------------* .c-button
2725
+ \*------------------------------------*/
2726
+ .c-button {
2727
+ outline: 0;
2728
+ border: 0;
2729
+ margin: 0;
2730
+ padding: 0;
2731
+ cursor: pointer;
2732
+ vertical-align: middle;
2733
+ display: inline-block;
2734
+ -webkit-transition: all 0.2s ease-in-out;
2735
+ -moz-transition: all 0.2s ease-in-out;
2736
+ transition: all 0.2s ease-in-out;
2737
+ font-family: inherit;
2738
+ font-size: 14px;
2739
+ text-align: center;
2740
+ text-transform: uppercase;
2741
+ text-decoration: none;
2742
+ -webkit-user-select: none;
2743
+ -moz-user-select: none;
2744
+ -ms-user-select: none;
2745
+ user-select: none;
2746
+ background-color: #ffffff; }
2747
+ .c-button:hover {
2748
+ text-decoration: none; }
2749
+ .c-button.is-disabled, .c-button:disabled {
2750
+ background-color: #dde4ea;
2751
+ color: #ffffff;
2752
+ cursor: not-allowed;
2753
+ -webkit-box-shadow: none;
2754
+ -moz-box-shadow: none;
2755
+ box-shadow: none;
2756
+ pointer-events: none; }
2757
+ .c-button.c-button--block {
2758
+ display: block;
2759
+ width: 100%; }
2760
+
2761
+ .c-button::-moz-focus-inner {
2762
+ border: 0;
2763
+ padding: 0; }
2764
+
2765
+ /*------------------------------------* .c-button--regular
2766
+ \*------------------------------------*/
2767
+ .c-button--regular {
2768
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
2769
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
2770
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
2771
+ padding: 0 20px;
2772
+ -webkit-border-radius: 3px;
2773
+ -moz-border-radius: 3px;
2774
+ border-radius: 3px;
2775
+ height: 40px;
2776
+ line-height: 40px; }
2777
+ .c-button--regular:hover, .c-button--regular.is-active {
2778
+ -webkit-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
2779
+ -moz-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
2780
+ box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23); }
2781
+ .c-button--regular.c-button--small {
2782
+ height: 30px;
2783
+ line-height: 30px;
2784
+ padding: 0 15px;
2785
+ font-size: 12px; }
2786
+ .c-button--regular.c-button--small .c-button__icon {
2787
+ font-size: 14px; }
2788
+ .c-button--regular.c-button--large {
2789
+ height: 50px;
2790
+ line-height: 50px;
2791
+ padding: 0 25px; }
2792
+ .c-button--regular.c-button--x-large {
2793
+ height: 60px;
2794
+ line-height: 60px;
2795
+ padding: 0 40px; }
2796
+
2797
+ /*------------------------------------* .c-button--floating
2798
+ \*------------------------------------*/
2799
+ .c-button--floating {
2800
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
2801
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
2802
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
2803
+ width: 42px;
2804
+ height: 42px;
2805
+ -webkit-border-radius: 50%;
2806
+ -moz-border-radius: 50%;
2807
+ border-radius: 50%;
2808
+ color: #a6b6be; }
2809
+ .c-button--floating:hover, .c-button--floating.is-active {
2810
+ -webkit-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
2811
+ -moz-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
2812
+ box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23); }
2813
+ .c-button--floating .c-button__icon {
2814
+ line-height: 42px; }
2815
+ .c-button--floating.c-button--small {
2816
+ width: 34px;
2817
+ height: 34px; }
2818
+ .c-button--floating.c-button--small .c-button__icon {
2819
+ line-height: 34px;
2820
+ font-size: 12px; }
2821
+ .c-button--floating.c-button--large {
2822
+ width: 80px;
2823
+ height: 80px; }
2824
+ .c-button--floating.c-button--large .c-button__icon {
2825
+ line-height: 80px; }
2826
+ .c-button--floating.c-button--x-large {
2827
+ width: 100px;
2828
+ height: 100px; }
2829
+ .c-button--floating.c-button--x-large .c-button__icon {
2830
+ line-height: 100px; }
2831
+
2832
+ /*------------------------------------* .c-button--flat
2833
+ \*------------------------------------*/
2834
+ .c-button--flat {
2835
+ padding: 0 10px;
2836
+ height: 30px;
2837
+ line-height: 30px;
2838
+ -webkit-box-shadow: none;
2839
+ -moz-box-shadow: none;
2840
+ box-shadow: none; }
2841
+ .c-button--flat.c-button--flat {
2842
+ background-color: transparent; }
2843
+ .c-button--flat.c-button--flat:hover, .c-button--flat.c-button--flat.is-active {
2844
+ background-color: #f4f4f4;
2845
+ color: #37475a;
2846
+ -webkit-box-shadow: none;
2847
+ -moz-box-shadow: none;
2848
+ box-shadow: none; }
2849
+ .c-button--flat.c-button--flat.is-disabled, .c-button--flat.c-button--flat:disabled {
2850
+ color: #dde4ea; }
2851
+ .c-button--flat.c-button--action {
2852
+ color: #1e88e5; }
2853
+ .c-button--flat.c-button--warning {
2854
+ color: #ffc107; }
2855
+ .c-button--flat.c-button--danger {
2856
+ color: #f44336; }
2857
+ .c-button--flat.c-button--success {
2858
+ color: #4caf50; }
2859
+ .c-button--flat.c-button--facebook {
2860
+ color: #3a6ace; }
2861
+ .c-button--flat.c-button--twitter {
2862
+ color: #20a8e2; }
2863
+ .c-button--flat.c-button--google {
2864
+ color: #dc363c; }
2865
+ .c-button--flat.c-button--drupal {
2866
+ color: #02b2ec; }
2867
+ .c-button--flat.c-button--wordpress {
2868
+ color: #00bcd4; }
2869
+ .c-button--flat.c-button--small {
2870
+ height: 19px;
2871
+ line-height: 19px;
2872
+ padding: 0 5px;
2873
+ font-size: 12px; }
2874
+ .c-button--flat.c-button--large {
2875
+ height: 41px;
2876
+ line-height: 41px;
2877
+ padding: 0 20px, 5; }
2878
+ .c-button--flat.c-button--x-large {
2879
+ height: 52px;
2880
+ line-height: 52px;
2881
+ padding: 0 40px; }
2882
+
2883
+ /*------------------------------------* .c-button--toggle
2884
+ \*------------------------------------*/
2885
+ .c-button--toggle {
2886
+ width: 34px;
2887
+ height: 34px;
2888
+ -webkit-border-radius: 3px;
2889
+ -moz-border-radius: 3px;
2890
+ border-radius: 3px;
2891
+ color: #a6b6be;
2892
+ background-color: transparent; }
2893
+ .c-button--toggle.is-active, .c-button--toggle:hover {
2894
+ color: #37475a;
2895
+ -webkit-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
2896
+ -moz-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
2897
+ box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23); }
2898
+ .c-button--toggle.is-disabled, .c-button--toggle:disabled {
2899
+ color: #dde4ea;
2900
+ background-color: transparent; }
2901
+ .c-button--toggle.is-active {
2902
+ background-color: #f4f4f4; }
2903
+ .c-button--toggle .c-button__icon {
2904
+ line-height: 34px; }
2905
+ .c-button--toggle.c-button--action:hover, .c-button--toggle.c-button--action.is-active, .c-button--toggle.c-button--warning:hover, .c-button--toggle.c-button--warning.is-active, .c-button--toggle.c-button--danger:hover, .c-button--toggle.c-button--danger.is-active, .c-button--toggle.c-button--success:hover, .c-button--toggle.c-button--success.is-active, .c-button--toggle.c-button--facebook:hover, .c-button--toggle.c-button--facebook.is-active, .c-button--toggle.c-button--twitter:hover, .c-button--toggle.c-button--twitter.is-active, .c-button--toggle.c-button--google:hover, .c-button--toggle.c-button--google.is-active, .c-button--toggle.c-button--drupal:hover, .c-button--toggle.c-button--drupal.is-active, .c-button--toggle.c-button--wordpress:hover, .c-button--toggle.c-button--wordpress.is-active {
2906
+ color: #ffffff; }
2907
+ .c-button--toggle.c-button--small {
2908
+ width: 26px;
2909
+ height: 26px; }
2910
+ .c-button--toggle.c-button--small .c-button__icon {
2911
+ line-height: 26px;
2912
+ font-size: 12px; }
2913
+ .c-button--toggle.c-button--large {
2914
+ width: 46px;
2915
+ height: 46px; }
2916
+ .c-button--toggle.c-button--large .c-button__icon {
2917
+ line-height: 46px; }
2918
+ .c-button--toggle.c-button--x-large {
2919
+ width: 58px;
2920
+ height: 58px; }
2921
+ .c-button--toggle.c-button--x-large .c-button__icon {
2922
+ line-height: 58px; }
2923
+
2924
+ /*------------------------------------* .c-button--clean
2925
+ \*------------------------------------*/
2926
+ .c-button--clean {
2927
+ color: #a6b6be;
2928
+ background-color: transparent;
2929
+ line-height: 18px; }
2930
+ .c-button--clean:hover {
2931
+ color: #37475a; }
2932
+ .c-button--clean .c-button__icon + .c-button__text,
2933
+ .c-button--clean .c-button__text + .c-button__icon {
2934
+ margin-left: 0; }
2935
+ .c-button--clean .c-button__icon {
2936
+ font-size: 18px;
2937
+ width: 18px;
2938
+ height: 18px; }
2939
+ .c-button--clean.c-button--small {
2940
+ line-height: 12px;
2941
+ font-size: 12px; }
2942
+ .c-button--clean.c-button--small .c-button__icon {
2943
+ width: 12px;
2944
+ height: 12px;
2945
+ font-size: 12px; }
2946
+ .c-button--clean.c-button--large {
2947
+ line-height: 24px; }
2948
+ .c-button--clean.c-button--large .c-button__icon {
2949
+ width: 24px;
2950
+ height: 24px;
2951
+ font-size: 24px; }
2952
+ .c-button--clean.c-button--x-large {
2953
+ line-height: 30px; }
2954
+ .c-button--clean.c-button--x-large .c-button__icon {
2955
+ width: 30px;
2956
+ height: 30px;
2957
+ font-size: 30px; }
2958
+
2959
+ /*------------------------------------* .c-button--simple
2960
+ \*------------------------------------*/
2961
+ .c-button--simple {
2962
+ text-transform: none;
2963
+ background-color: transparent;
2964
+ line-height: 24px; }
2965
+ .c-button--simple .c-button__icon + .c-button__text,
2966
+ .c-button--simple .c-button__text + .c-button__icon {
2967
+ margin-left: 3px; }
2968
+ .c-button--simple .c-button__icon {
2969
+ font-size: 24px;
2970
+ width: 24px;
2971
+ height: 24px; }
2972
+ .c-button--simple.c-button--small {
2973
+ line-height: 18px;
2974
+ font-size: 12px; }
2975
+ .c-button--simple.c-button--small .c-button__icon {
2976
+ width: 18px;
2977
+ height: 18px;
2978
+ font-size: 18px; }
2979
+ .c-button--simple.c-button--large {
2980
+ line-height: 30px;
2981
+ font-size: 16px; }
2982
+ .c-button--simple.c-button--large .c-button__icon {
2983
+ width: 30px;
2984
+ height: 30px;
2985
+ font-size: 30px; }
2986
+ .c-button--simple.c-button--x-large {
2987
+ line-height: 36px;
2988
+ font-size: 16px; }
2989
+ .c-button--simple.c-button--x-large .c-button__icon {
2990
+ width: 36px;
2991
+ height: 36px;
2992
+ font-size: 36px; }
2993
+
2994
+ /*------------------------------------* .c-button color modifiers
2995
+ \*------------------------------------*/
2996
+ .c-button--action {
2997
+ background-color: #1e88e5;
2998
+ color: #ffffff; }
2999
+ .c-button--action:hover, .c-button--action.is-active {
3000
+ background-color: #1778cd; }
3001
+
3002
+ .c-button--warning {
3003
+ background-color: #ffc107;
3004
+ color: #ffffff; }
3005
+ .c-button--warning:hover, .c-button--warning.is-active {
3006
+ background-color: #f5b207; }
3007
+
3008
+ .c-button--danger {
3009
+ background-color: #f44336;
3010
+ color: #ffffff; }
3011
+ .c-button--danger:hover, .c-button--danger.is-active {
3012
+ background-color: #e83e32; }
3013
+
3014
+ .c-button--success {
3015
+ background-color: #4caf50;
3016
+ color: #ffffff; }
3017
+ .c-button--success:hover, .c-button--success.is-active {
3018
+ background-color: #42a146; }
3019
+
3020
+ .c-button--google {
3021
+ background-color: #dc363c;
3022
+ color: #ffffff; }
3023
+ .c-button--google:hover, .c-button--google.is-active {
3024
+ background-color: #d0343a; }
3025
+
3026
+ .c-button--facebook {
3027
+ background-color: #3a6ace;
3028
+ color: #ffffff; }
3029
+ .c-button--facebook:hover, .c-button--facebook.is-active {
3030
+ background-color: #335fbb; }
3031
+
3032
+ .c-button--twitter {
3033
+ background-color: #20a8e2;
3034
+ color: #ffffff; }
3035
+ .c-button--twitter:hover, .c-button--twitter.is-active {
3036
+ background-color: #1697cc; }
3037
+
3038
+ .c-button--drupal {
3039
+ background-color: #02b2ec;
3040
+ color: #ffffff; }
3041
+ .c-button--drupal:hover, .c-button--drupal.is-active {
3042
+ background-color: #029fd3; }
3043
+
3044
+ .c-button--wordpress {
3045
+ background-color: #00bcd4;
3046
+ color: #ffffff; }
3047
+ .c-button--wordpress:hover, .c-button--wordpress.is-active {
3048
+ background-color: #00a5bb; }
3049
+
3050
+ /*------------------------------------* #COLLECTION
3051
+
3052
+ Base:
3053
+ .c-collection
3054
+ .c-collection-item
3055
+ .c-collection-item__content
3056
+ .c-collection-item__content-additional (optional)
3057
+
3058
+ COLLECTION MODIFIERS:
3059
+ Collection type modifiers:
3060
+ .c-collection--simple
3061
+ .c-collection--with-shadow
3062
+
3063
+ COLLECTION ITEM MODIFIERS:
3064
+ Size modifiers:
3065
+ .c-collection-item--large
3066
+ .c-collection-item--small
3067
+
3068
+ Type modifiers:
3069
+ .c-collection-item--heading
3070
+ .c-collection-item--placeholder
3071
+
3072
+ Status modifiers:
3073
+ .c-collection-item.is-disabled
3074
+ .c-collection-item.is-draggable
3075
+ .c-collection-item.is-deleted
3076
+ \*------------------------------------*/
3077
+ /*------------------------------------* .c-collection
3078
+ \*------------------------------------*/
3079
+ .c-collection {
3080
+ font-size: 14px; }
3081
+
3082
+ .c-collection--simple {
3083
+ border-bottom: none; }
3084
+ .c-collection--simple .c-collection-item:last-child {
3085
+ border-bottom: 0; }
3086
+
3087
+ .c-collection--with-shadow {
3088
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
3089
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
3090
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
3091
+ -webkit-border-radius: 3px;
3092
+ -moz-border-radius: 3px;
3093
+ border-radius: 3px;
3094
+ border-bottom: none; }
3095
+
3096
+ /*------------------------------------* .c-collection-item
3097
+ \*------------------------------------*/
3098
+ .c-collection-item {
3099
+ -webkit-transition: all 0.2s ease-in-out;
3100
+ -moz-transition: all 0.2s ease-in-out;
3101
+ transition: all 0.2s ease-in-out;
3102
+ background-color: #ffffff; }
3103
+ .c-collection-item.is-disabled {
3104
+ background-color: #dde4ea; }
3105
+ .c-collection-item.is-draggable {
3106
+ -webkit-box-shadow: 0 0 3px rgba(13, 26, 43, 0.16), 0 15px 18px rgba(13, 26, 43, 0.24);
3107
+ -moz-box-shadow: 0 0 3px rgba(13, 26, 43, 0.16), 0 15px 18px rgba(13, 26, 43, 0.24);
3108
+ box-shadow: 0 0 3px rgba(13, 26, 43, 0.16), 0 15px 18px rgba(13, 26, 43, 0.24);
3109
+ position: absolute;
3110
+ cursor: move; }
3111
+ .c-collection-item + .c-collection-item.is-draggable {
3112
+ border-top: none; }
3113
+ .c-collection-item.is-deleted {
3114
+ background-color: transparent;
3115
+ color: #90a4ae;
3116
+ text-decoration: line-through; }
3117
+ .c-collection-item + .c-collection-item {
3118
+ border-top: 1px solid #dde4ea; }
3119
+ .c-collection--simple .c-collection-item + .c-collection-item {
3120
+ border-top: none; }
3121
+ .c-collection-item:last-child {
3122
+ border-bottom: 1px solid #dde4ea; }
3123
+ .c-collection-item .c-collection-item:last-child {
3124
+ border-bottom: 0; }
3125
+ .c-collection--with-shadow .c-collection-item:first-child {
3126
+ -webkit-border-top-left-radius: 3px;
3127
+ -moz-border-radius-topleft: 3px;
3128
+ border-top-left-radius: 3px;
3129
+ -webkit-border-top-right-radius: 3px;
3130
+ -moz-border-radius-topright: 3px;
3131
+ border-top-right-radius: 3px; }
3132
+ .c-collection--with-shadow .c-collection-item:last-child {
3133
+ -webkit-border-bottom-left-radius: 3px;
3134
+ -moz-border-radius-bottomleft: 3px;
3135
+ border-bottom-left-radius: 3px;
3136
+ -webkit-border-bottom-right-radius: 3px;
3137
+ -moz-border-radius-bottomright: 3px;
3138
+ border-bottom-right-radius: 3px; }
3139
+
3140
+ .c-collection-item--heading {
3141
+ color: #90a4ae;
3142
+ font-size: 14px;
3143
+ line-height: 1.4; }
3144
+
3145
+ .c-collection-item--placeholder {
3146
+ background-color: transparent; }
3147
+
3148
+ /*------------------------------------* .c-collection-item__content
3149
+ \*------------------------------------*/
3150
+ .c-collection-item__content {
3151
+ height: 50px;
3152
+ padding-left: 30px;
3153
+ padding-right: 30px;
3154
+ display: -webkit-box;
3155
+ display: -webkit-flex;
3156
+ display: -moz-box;
3157
+ display: -ms-flexbox;
3158
+ display: flex;
3159
+ -webkit-box-align: center;
3160
+ -webkit-align-items: center;
3161
+ -moz-box-align: center;
3162
+ -ms-flex-align: center;
3163
+ align-items: center; }
3164
+ .c-collection-item--large > .c-collection-item__content {
3165
+ height: 80px; }
3166
+ .c-collection-item--small > .c-collection-item__content {
3167
+ height: 40px; }
3168
+ .c-collection-item__content .l-grid {
3169
+ -webkit-box-flex: 1;
3170
+ -webkit-flex-grow: 1;
3171
+ -moz-box-flex: 1;
3172
+ -ms-flex-positive: 1;
3173
+ flex-grow: 1; }
3174
+
3175
+ /*------------------------------------* #DROPDOWN
3176
+
3177
+ Base:
3178
+ .c-dropdown
3179
+ .c-dropdown__trigger
3180
+ .c-dropdown__content
3181
+
3182
+ Display modifiers:
3183
+ .c-dropdown--right-corner
3184
+
3185
+ State modifiers:
3186
+ .c-dropdown.is-open
3187
+ \*------------------------------------*/
3188
+ .c-dropdown {
3189
+ position: relative; }
3190
+
3191
+ .c-dropdown__content {
3192
+ white-space: nowrap;
3193
+ display: none;
3194
+ background-color: #ffffff;
3195
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
3196
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
3197
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
3198
+ -webkit-border-radius: 3px;
3199
+ -moz-border-radius: 3px;
3200
+ border-radius: 3px;
3201
+ position: absolute;
3202
+ z-index: 1000;
3203
+ top: 0; }
3204
+ .is-open > .c-dropdown__content {
3205
+ display: block;
3206
+ -webkit-animation: fadeIn .3s;
3207
+ -moz-animation: fadeIn .3s;
3208
+ animation: fadeIn .3s; }
3209
+ .c-dropdown--right-corner .c-dropdown__content {
3210
+ right: 0; }
3211
+
3212
+ /*------------------------------------* #RIPPLE EFFECT
3213
+ \*------------------------------------*/
3214
+ @-webkit-keyframes ripple {
3215
+ 100% {
3216
+ opacity: 0;
3217
+ -webkit-transform: scale(2.5);
3218
+ transform: scale(2.5); } }
3219
+ @-moz-keyframes ripple {
3220
+ 100% {
3221
+ opacity: 0;
3222
+ -moz-transform: scale(2.5);
3223
+ transform: scale(2.5); } }
3224
+ @keyframes ripple {
3225
+ 100% {
3226
+ opacity: 0;
3227
+ -webkit-transform: scale(2.5);
3228
+ -moz-transform: scale(2.5);
3229
+ transform: scale(2.5); } }
3230
+
3231
+ .fx-ripple-effect {
3232
+ position: relative;
3233
+ overflow: hidden;
3234
+ -webkit-transform: translate3d(0, 0, 0);
3235
+ -moz-transform: translate3d(0, 0, 0);
3236
+ transform: translate3d(0, 0, 0); }
3237
+
3238
+ .fx-ink {
3239
+ display: block;
3240
+ position: absolute;
3241
+ pointer-events: none;
3242
+ -webkit-border-radius: 50%;
3243
+ -moz-border-radius: 50%;
3244
+ border-radius: 50%;
3245
+ -webkit-transform: scale(0);
3246
+ -moz-transform: scale(0);
3247
+ -ms-transform: scale(0);
3248
+ transform: scale(0);
3249
+ background-color: rgba(33, 51, 72, 0.15);
3250
+ opacity: 1; }
3251
+ .fx-ink.fx-animate {
3252
+ -webkit-animation: ripple .5s linear;
3253
+ -moz-animation: ripple .5s linear;
3254
+ animation: ripple .5s linear; }
3255
+
3256
+ /*------------------------------------* #FADE IN ANIMATION
3257
+ \*------------------------------------*/
3258
+ @-webkit-keyframes fadeIn {
3259
+ from {
3260
+ opacity: 0; }
3261
+ to {
3262
+ opacity: 1; } }
3263
+ @-moz-keyframes fadeIn {
3264
+ from {
3265
+ opacity: 0; }
3266
+ to {
3267
+ opacity: 1; } }
3268
+ @keyframes fadeIn {
3269
+ from {
3270
+ opacity: 0; }
3271
+ to {
3272
+ opacity: 1; } }
3273
+
3274
+ /*------------------------------------* #DIM EFFECT
3275
+ \*------------------------------------*/
3276
+ .fx-dim-effect {
3277
+ background-color: rgba(33, 51, 72, 0.8); }
3278
+
3279
+ /*------------------------------------* #BLUR EFFECT
3280
+ \*------------------------------------*/
3281
+ .fx-blur-effect {
3282
+ -webkit-filter: blur(3px);
3283
+ filter: blur(3px); }
3284
+
3285
+ /*------------------------------------* #EXPANDABLE-ITEM
3286
+
3287
+ Base:
3288
+ .c-expandable-item
3289
+ .c-expandable-item__trigger
3290
+ .c-expandable-item__icon (optional)
3291
+ .c-expandable-item__wrapper
3292
+ .c-expandable-item__content
3293
+
3294
+ State modifiers:
3295
+ .c-expandable-item.is-expanded
3296
+ \*------------------------------------*/
3297
+ .c-expandable-item__trigger {
3298
+ cursor: pointer; }
3299
+
3300
+ .c-expandable-item__icon {
3301
+ -webkit-transition: all 0.2s ease-in-out;
3302
+ -moz-transition: all 0.2s ease-in-out;
3303
+ transition: all 0.2s ease-in-out; }
3304
+ .c-expandable-item.is-expanded .c-expandable-item__icon {
3305
+ -webkit-transform: rotate(-180deg);
3306
+ -moz-transform: rotate(-180deg);
3307
+ -ms-transform: rotate(-180deg);
3308
+ transform: rotate(-180deg); }
3309
+
3310
+ .c-expandable-item__wrapper {
3311
+ height: 0;
3312
+ overflow: hidden;
3313
+ -webkit-transition: all 0.2s ease-in-out;
3314
+ -moz-transition: all 0.2s ease-in-out;
3315
+ transition: all 0.2s ease-in-out; }
3316
+
3317
+ /*------------------------------------* #ILLUSTRATION
3318
+
3319
+ Base:
3320
+ .c-illustration
3321
+ .c-illustration__icon - used together with .c-illustration--details
3322
+
3323
+ State modifiers:
3324
+ .c-illustration--empty
3325
+ .c-illustration--details - bg color on :hover + icon
3326
+
3327
+ Illustration modifiers:
3328
+ .c-illustration--user
3329
+ .c-illustration--world
3330
+ .c-illustration--wordpress
3331
+ .c-illustration--drupal
3332
+ .c-illustration--facebook
3333
+ .c-illustration--demopage
3334
+ .c-illustration--template
3335
+
3336
+ Size modifiers:
3337
+ .c-illustration--large
3338
+ .c-illustration--x-large
3339
+ \*------------------------------------*/
3340
+ .c-illustration {
3341
+ -webkit-border-radius: 50%;
3342
+ -moz-border-radius: 50%;
3343
+ border-radius: 50%;
3344
+ width: 42px;
3345
+ height: 42px;
3346
+ display: inline-block;
3347
+ -moz-background-size: cover;
3348
+ background-size: cover;
3349
+ background-repeat: no-repeat;
3350
+ background-position: center; }
3351
+ .c-button .c-illustration {
3352
+ border: 0;
3353
+ -webkit-border-radius: 0;
3354
+ -moz-border-radius: 0;
3355
+ border-radius: 0;
3356
+ width: inherit;
3357
+ height: inherit; }
3358
+
3359
+ .c-illustration--empty {
3360
+ border: 1px solid #dde4ea; }
3361
+
3362
+ .c-illustration--large {
3363
+ width: 80px;
3364
+ height: 80px; }
3365
+
3366
+ .c-illustration--x-large {
3367
+ width: 100px;
3368
+ height: 100px; }
3369
+
3370
+ /*------------------------------------* .c-illustration--details
3371
+ .c-illustration__icon
3372
+ \*------------------------------------*/
3373
+ .c-illustration--details {
3374
+ display: -webkit-box;
3375
+ display: -webkit-flex;
3376
+ display: -moz-box;
3377
+ display: -ms-flexbox;
3378
+ display: flex;
3379
+ -webkit-box-align: center;
3380
+ -webkit-align-items: center;
3381
+ -moz-box-align: center;
3382
+ -ms-flex-align: center;
3383
+ align-items: center;
3384
+ -webkit-box-pack: center;
3385
+ -webkit-justify-content: center;
3386
+ -moz-box-pack: center;
3387
+ -ms-flex-pack: center;
3388
+ justify-content: center;
3389
+ position: relative; }
3390
+ .c-illustration--details::before {
3391
+ background-color: rgba(33, 51, 72, 0.5);
3392
+ -webkit-transition: all 0.2s ease-in-out;
3393
+ -moz-transition: all 0.2s ease-in-out;
3394
+ transition: all 0.2s ease-in-out;
3395
+ -webkit-transform: scale(0);
3396
+ -moz-transform: scale(0);
3397
+ -ms-transform: scale(0);
3398
+ transform: scale(0);
3399
+ -webkit-transform-origin: center;
3400
+ -moz-transform-origin: center;
3401
+ -ms-transform-origin: center;
3402
+ transform-origin: center;
3403
+ content: '';
3404
+ display: block;
3405
+ -webkit-border-radius: 50%;
3406
+ -moz-border-radius: 50%;
3407
+ border-radius: 50%;
3408
+ position: absolute;
3409
+ height: -webkit-calc(100% + 2px);
3410
+ height: -moz-calc(100% + 2px);
3411
+ height: calc(100% + 2px);
3412
+ width: -webkit-calc(100% + 2px);
3413
+ width: -moz-calc(100% + 2px);
3414
+ width: calc(100% + 2px);
3415
+ left: -1px;
3416
+ top: -1px; }
3417
+
3418
+ .c-illustration__icon {
3419
+ color: #ffffff;
3420
+ -webkit-transition: all 0.2s ease-in-out;
3421
+ -moz-transition: all 0.2s ease-in-out;
3422
+ transition: all 0.2s ease-in-out;
3423
+ -webkit-transform: scale(0);
3424
+ -moz-transform: scale(0);
3425
+ -ms-transform: scale(0);
3426
+ transform: scale(0);
3427
+ -webkit-transform-origin: center;
3428
+ -moz-transform-origin: center;
3429
+ -ms-transform-origin: center;
3430
+ transform-origin: center; }
3431
+
3432
+ .c-button:hover .c-illustration__icon,
3433
+ .c-button:hover .c-illustration--details::before,
3434
+ .c-illustration--details:hover .c-illustration__icon,
3435
+ .c-illustration--details:hover .c-illustration--details::before {
3436
+ -webkit-transform: scale(1);
3437
+ -moz-transform: scale(1);
3438
+ -ms-transform: scale(1);
3439
+ transform: scale(1); }
3440
+
3441
+ /*------------------------------------* Illustration modifiers
3442
+ \*------------------------------------*/
3443
+ .c-illustration--user {
3444
+ background-image: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI0IiBmaWxsPSIjYzFkMmRmIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTIgMTJjMi4yMSAwIDQtMS43OSA0LTRzLTEuNzktNC00LTQtNCAxLjc5LTQgNCAxLjc5IDQgNCA0em0wIDJjLTIuNjcgMC04IDEuMzQtOCA0djJoMTZ2LTJjMC0yLjY2LTUuMzMtNC04LTR6Ii8+PHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==");
3445
+ background-position: center 15%;
3446
+ -moz-background-size: 128%;
3447
+ background-size: 128%; }
3448
+
3449
+ .c-illustration--world {
3450
+ background-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0id29ybGQuc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MCIgaGVpZ2h0PSI4MCIgdmlld0JveD0iMCAwIDgwIDgwIj48ZGVmcz48c3R5bGU+LmNscy0yLCAuY2xzLTMgeyBmaWxsLXJ1bGU6IGV2ZW5vZGQ7IH0gLmNscy0yIHsgb3BhY2l0eTogMC4xNTsgfSAuY2xzLTMgeyBmaWxsOiAjZmZmOyB9PC9zdHlsZT48L2RlZnM+PHBhdGggaWQ9IkVsbGlwc2VfNzA2X2NvcHlfNyIgZGF0YS1uYW1lPSJFbGxpcHNlIDcwNiBjb3B5IDciIGNsYXNzPSJjbHMtMiIgZD0iTTQ2LjgzIDc5LjQwN0wyMi40NzcgNTUuMDUzbC4yMy0uMjNhMjMuNDggMjMuNDggMCAwIDEgMzMuMTE2LTMzLjExNmwuMDM1LS4wMzUuNzQyLjczN3EuNTEzLjQ4MiAxIDFsMjIuMDIyIDIyLjAyNmE0MC4wMTMgNDAuMDEzIDAgMCAxLTMyLjc5MiAzMy45N3oiLz48cGF0aCBpZD0iU2hhcGVfNzE1X2NvcHlfMiIgZGF0YS1uYW1lPSJTaGFwZSA3MTUgY29weSAyIiBjbGFzcz0iY2xzLTMiIGQ9Ik00MC41IDU0Ljc1NVY2M2MtLjQwNSAwLS44MS0uMDEtMS4yMS0uMDMtLjAwNiAwLS4wMDYtLjAwNS0uMDEyIDBhLjAzNS4wMzUgMCAwIDAtLjAyMy0uMDA1Yy0uMTQtLjAwNS0uMjg4LS4wMTctLjQzLS4wMjNxLS4zNzgtLjAyNi0uNzU3LS4wN2MtLjI1My0uMDIzLS41LS4wNTItLjc1Mi0uMDg3cy0uNDk0LS4wNy0uNzQtLjExYy0uNzU4LS4xMy0xLjUxLS4yOTMtMi4yNDQtLjQ5Mi0uMTgyLS4wNDYtLjM2NC0uMS0uNTQtLjE1Mi0uMS0uMDI4LS4yLS4wNTctLjMtLjA5Mi0uMTc3LS4wNDYtLjM0OC0uMTA1LS41MjQtLjE2M2wtLjU0Ni0uMTkzYy0uMjIzLS4wODItLjQ0Ni0uMTctLjY3LS4yNTdzLS40NC0uMTgtLjY1OC0uMjc0Yy0uNDM1LS4xODYtLjg3LS4zOS0xLjI5My0uNjA1LS4xNjQtLjA4OC0uMzM0LS4xNzYtLjUtLjI2My0uMjM0LS4xMy0uNDc1LS4yNTctLjctLjM5Mi0uNTU3LS4zMjYtMS4xLS42NzctMS42Mi0xLjA0NC0uMTgzLS4xMjItLjM2LS4yNS0uNTM2LS4zODRsLS40NDctLjM0Yy0uNTU4LS40My0xLjA5My0uODktMS42LTEuMzctLjE3LS4xNjMtLjM0LS4zMjYtLjUwNS0uNDlzLS4zMjMtLjMyNi0uNDgyLS40OWMtLjQ3Ni0uNS0uOTI4LTEuMDItMS4zNTctMS41NTgtLjI0Ny0uMzEtLjQ4Mi0uNjI0LS43MS0uOTQ1LS4xMDctLjE1My0uMjE4LS4zLS4zMjQtLjQ2MnMtLjIyLS4zMDgtLjMyLS40NjhsLS4zLS40NzNxLS4zLS40ODItLjU2NC0uOThjLS4wODgtLjE2NC0uMTc2LS4zMzMtLjI2NC0uNXMtLjE3LS4zNC0uMjUzLS41MDgtLjE2Ni0uMzQ1LS4yNDItLjUxNWMtLjA4OC0uMTg3LS4xNy0uMzYtLjI0Ny0uNTQ4LS4xNC0uMzQtLjI3NS0uNjg0LS40MDQtMS4wMjgtLjA3LS4xODgtLjE0LS4zOC0uMi0uNTY3LS4wNi0uMTYzLS4xMTItLjMyNi0uMTYtLjQ5LS4wNjQtLjE5My0uMTIyLS4zODUtLjE3NS0uNTc3cy0uMTA1LS4zNzMtLjE1Mi0uNTZjLS4wNy0uMjgtLjE0LS41Ni0uMi0uODRzLS4xMjMtLjU3Mi0uMTctLjg1OGEuOTc0Ljk3NCAwIDAgMS0uMDIzLS4xMjhjLS4wNDctLjI0Ni0uMDgyLS40OS0uMTE4LS43MzUtLjA0LS4yOTItLjA3Ni0uNTg0LS4xMDYtLjg4Mi0uMDIzLS4yLS4wNC0uNC0uMDUyLS41ODhhLjIuMiAwIDAgMS0uMDA2LS4wNmMtLjAxNy0uMjU1LS4wMzUtLjUwNi0uMDQtLjc2M2EuOTkuOTkgMCAwIDEtLjAwNy0uMTM0Yy0uMDEtLjI4LS4wMTUtLjU2Mi0uMDE1LS44NCAwLS40Mi4wMTItLjg0Mi4wMzUtMS4yNTYuMDEyLS4yMzQuMDIzLS40NjcuMDQ3LS42OTUuMDEyLS4xNDYuMDIzLS4yOS4wNC0uNDM4LjA1NC0uNTY2LjEzNi0xLjEyNi4yMy0xLjY3NS4wMzUtLjE5My4wNy0uMzczLjExMi0uNTY3YS4xNjMuMTYzIDAgMCAxIC4wMTItLjA1N2MuMDUzLS4yOS4xMTctLjU3Ny4xODgtLjg1Ny4xNjQtLjY2Ni4zNTgtMS4zMTguNTc2LTEuOTU1bDIuODUgMi44MjRhMS4xMzYgMS4xMzYgMCAwIDEgLjE4IDEuNCA1LjU3NyA1LjU3NyAwIDAgMCAuNTcgNi4zNyAxLjQxIDEuNDEgMCAwIDAgLjI2NS4yNjMgNS42OCA1LjY4IDAgMCAwIDYuNDE2LjU2NiAxLjE1NSAxLjE1NSAwIDAgMSAxLjQxLjE4MmwzLjUwOCAzLjQ4My4xODIuMThhMy40NzYgMy40NzYgMCAwIDAgLjM3NiAyLjkgMS4wNzUgMS4wNzUgMCAwIDAgLjQ1OC40NTcgMy44MjUgMy44MjUgMCAwIDAgMi4zNS41MTMgMS4yMTMgMS4yMTMgMCAwIDEgMS4wMzQuMzJsMi4zMTUgMi4zYTEuMTY4IDEuMTY4IDAgMCAxIC4zNDcuODN6TTY0IDM5LjY2N2EyMy4wNTYgMjMuMDU2IDAgMCAxLTEuMzE2IDcuN2wtNi45NS02LjlhMS4xNyAxLjE3IDAgMCAwLTEuNjU3LjAwNWwtNy44OSA3LjgzNmExLjE3MyAxLjE3MyAwIDAgMS0xLjY2MyAwbC0yLjA4LTIuMDY1YTEuMTU2IDEuMTU2IDAgMCAxIDAtMS42NDVsMi41LTIuNDhhMS4xNTggMS4xNTggMCAwIDAgMC0xLjY0NWwtNy4wNjgtNy4wMThhMS4xNTcgMS4xNTcgMCAwIDEgMC0xLjY0NWwzLjc0Mi0zLjcxN2ExLjE1NyAxLjE1NyAwIDAgMCAwLTEuNjQ1bC0xLjY3LTEuNjU4YTEuMTU2IDEuMTU2IDAgMCAxIDAtMS42NDVsNi4xODYtNi4xMzhBMjMuMzgyIDIzLjM4MiAwIDAgMSA2NCAzOS42Njd6Ii8+PC9zdmc+"); }
3451
+
3452
+ .c-illustration--wordpress {
3453
+ background-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0id29yZHByZXNzLnN2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCI+PGRlZnM+PHN0eWxlPi5jbHMtMiwgLmNscy0zIHsgZmlsbC1ydWxlOiBldmVub2RkOyB9IC5jbHMtMiB7IG9wYWNpdHk6IDAuMTU7IH0gLmNscy0zIHsgZmlsbDogI2ZmZjsgfTwvc3R5bGU+PC9kZWZzPjxwYXRoIGlkPSJFbGxpcHNlXzcwNl9jb3B5XzgiIGRhdGEtbmFtZT0iRWxsaXBzZSA3MDYgY29weSA4IiBjbGFzcz0iY2xzLTIiIGQ9Ik00Ni41NzUgNzkuNDUzTDIyIDU1cy03LjQ5NC0xOC4wMjctMi43MzYtMjUuNEMyNi41OTQgMTguMjUgNDcuODgyIDIwLjg4IDQ4IDIxYTUuOTQ4IDUuOTQ4IDAgMCAxIDYuMjA1IDEuNTU1bDI1LjA2MiAyNS4wNjJhNDAuMDI2IDQwLjAyNiAwIDAgMS0zMi42OTIgMzEuODM2eiIvPjxwYXRoIGlkPSJTaGFwZV83MTRfY29weV8yIiBkYXRhLW5hbWU9IlNoYXBlIDcxNCBjb3B5IDIiIGNsYXNzPSJjbHMtMyIgZD0iTTE5LjYgMjguODEyQTIyLjkwNyAyMi45MDcgMCAwIDEgNDAgMTdhMjMuMzQgMjMuMzQgMCAwIDEgMTUuMDIgNS44OSA1LjM0IDUuMzQgMCAwIDAtMy42NzUuNzUgNS4xNTQgNS4xNTQgMCAwIDAtLjA5IDguOTA4YzIuNCAxLjUgMy4yNTUgNS4yNDUgMy4xNzUgNy41MzNzLTUuNTggMTIuODI1LTUuNTggMTIuODI1bC01LjM1Ni0xOC4zNTJzLS4xODUtMS4yODctLjE4NS0xLjY2YTIuMjMzIDIuMjMzIDAgMCAxIC40NDMtMS4zNyAxLjU0IDEuNTQgMCAwIDEgLjg2NC0uNjc0aDIuNTM4VjI4LjgxaC0xMy44djIuMDRoLjQyNkEyLjY3OCAyLjY3OCAwIDAgMSAzNS4xIDMxLjljLjUuNTE3IDEuMTM4IDIuNDcgMS45MDcgNC41bDIuMDA3IDYuNi00LjMyNiA5Ljk3Mi00Ljc0My0xOS45M2E0LjE2OCA0LjE2OCAwIDAgMSAuNDI2LTEuNiAxLjU3MiAxLjU3MiAwIDAgMSAuODA3LS41ODJoLjEzdi0yLjA0OEgxOS42em0yLjcwNiAzLjQ2NGEzLjc0IDMuNzQgMCAwIDAtMi4zLTEuNDI0aC0xLjJhMjMuMiAyMy4yIDAgMCAwLTEuOCA5LjExNSAyMi43NzYgMjIuNzc2IDAgMCAwIDE0LjA3IDIwLjk5MnptMzcuNDktMy42NDZhMTQuNzIzIDE0LjcyMyAwIDAgMS0uNTA2IDcuMzQyYy0yLjIyNCA3LjE4NS03LjczIDIwLjExLTkuODYgMjUuMDM0QTIyLjc2NyAyMi43NjcgMCAwIDAgNjMgNDAuMjNhMjIuNTE1IDIyLjUxNSAwIDAgMC0zLjIwNy0xMS42em0tMTkuMzMgMTkuNGwtNS44OCAxNC4zMzVhMjMuMjYzIDIzLjI2MyAwIDAgMCAxMS4wMTctLjA0MnptMCAwIi8+PC9zdmc+"); }
3454
+
3455
+ .c-illustration--drupal {
3456
+ background-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZHJ1cGFsLnN2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCI+PGRlZnM+PHN0eWxlPi5jbHMtMiwgLmNscy0zIHsgZmlsbC1ydWxlOiBldmVub2RkOyB9IC5jbHMtMiB7IG9wYWNpdHk6IDAuMTU7IH0gLmNscy0zIHsgZmlsbDogI2ZmZjsgfTwvc3R5bGU+PC9kZWZzPjxwYXRoIGlkPSJFbGxpcHNlXzcwNl9jb3B5XzkiIGRhdGEtbmFtZT0iRWxsaXBzZSA3MDYgY29weSA5IiBjbGFzcz0iY2xzLTIiIGQ9Ik03OS40NDIgNDYuNjMzQTQwLjAyIDQwLjAyIDAgMCAxIDQ2LjkyNiA3OS4zOUwyMi42IDU3czEyLjUxMyAyLjMxMiAzLjk0LTUuMzRjLTkuMTkyLTguMjA4LTMuNS04LjU5My0uNTM3LTE0LjY2IDQuNDM0LTkuMDc0IDMwLjItMTMuNjA1IDMwLjItMTMuNjA1eiIvPjxwYXRoIGlkPSJGb3JtYV8xX2NvcHlfMiIgZGF0YS1uYW1lPSJGb3JtYSAxIGNvcHkgMiIgY2xhc3M9ImNscy0zIiBkPSJNNTIuMTEyIDIwLjk4N2MtMi43NS0xLjcwOC01LjMzNS0yLjM3Ni03LjkzNi00LjA4Ni0xLjYxLTEuMDg2LTMuODQ0LTMuNjc3LTUuNzIyLTUuOS0uMzQ0IDMuNTktMS40MjQgNS4wNjItMi42NjYgNi4xMDhhMzguMTc2IDM4LjE3NiAwIDAgMS02LjU1NyAzLjk3OGMtMS45IDEtMTIuMyA3LjI3Ny0xMi4yMzIgMjAuNzE0LjA0NyAxMy40MjMgMTEuMzIgMjMuMjcgMjMuOCAyMy4yIDEyLjQ3My0uMDQ3IDIzLjI1Ni05LjIxMiAyMy4yLTIyLjk4YTI0LjQ3NSAyNC40NzUgMCAwIDAtMTEuODg2LTIxLjAzM3ptLjM2OCAzOC43MmExMS4yIDExLjIgMCAwIDEtNS40MjQgMi4yMTJjLTIuOC4yNzYtNi41OC40My04Ljg1Ny0xLjY0YS43MzguNzM4IDAgMCAxLS4wMTQtMS4wOCAxLjE3MiAxLjE3MiAwIDAgMSAuNzc0LS4zNzIuNDYyLjQ2MiAwIDAgMSAuNDE3LjFjMS4wNDcuODMyIDIuNTk1IDEuNDkyIDUuOSAxLjQ4M2ExMS41NSAxMS41NSAwIDAgMCA2LjY4NC0xLjc1Yy40NjUtLjM1LjY2LS4wNS43MzMuMTY0YS44Mi44MiAwIDAgMS0uMjEzLjg4MnptLTguOTkzLTQuMzQyYTkuMzU4IDkuMzU4IDAgMCAxIDIuMzg1LTEuNzI0IDQuNSA0LjUgMCAwIDEgMi4xNjMtLjMyNyA0LjI5NCA0LjI5NCAwIDAgMSAyLjM0LjQ2MyAzLjk1IDMuOTUgMCAwIDEgMS4xOTIgMS44NTguNzQ2Ljc0NiAwIDAgMS0uNDA4IDEuMDU1Yy0uMzYzLjItLjQxNC4xLS43ODItLjU4Mi0uMzQ2LS42NjQtLjY2Ny0xLjM1LTIuNDg1LTEuMzQ2YTQuMjI3IDQuMjI3IDAgMCAwLTMuMjYgMS4zOGMtLjg3Mi43MzMtMS4xOTMuOTgtMS40ODUuNTYyLS4zMi0uNDA0LS4yMjYtLjgyNC4zNC0xLjM0em0xOC42NC0xMGExMi41NyAxMi41NyAwIDAgMS0xLjcyMyA2LjM0N2MtMS4yMzIgMS44MzgtMi4wMSAyLjUyNS0zLjQ3IDIuNDA3LTEuODUtLjE0Ni01LjYxMi01Ljk0NS03Ljk5My02LjA0LTMtLjA5My05LjUgNi4zMzgtMTQuNjIgNi4zNS0zLjExNS4wMS00LjA0LS40NTgtNS4wODctMS4xMmE1LjYgNS42IDAgMCAxLTIuMy01LjA0MmMuMDQtNC4wNjYgMy44LTcuODcgOC41NjUtNy45NSA2LjA1NC0uMDYyIDEwLjI3NiA2IDEzLjMzNiA1LjkzIDIuNTg0LS4wNTUgNy41NC01LjE5IDkuOTY4LTUuMTkzIDIuNTg4LS4wMDYgMy4zMjIgMi42ODggMy4zMjQgNC4zMXoiLz48L3N2Zz4="); }
3457
+
3458
+ .c-illustration--facebook {
3459
+ background-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZmIuc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MCIgaGVpZ2h0PSI4MCIgdmlld0JveD0iMCAwIDgwIDgwIj48ZGVmcz48c3R5bGU+LmNscy0yLCAuY2xzLTMgeyBmaWxsLXJ1bGU6IGV2ZW5vZGQ7IH0gLmNscy0yIHsgb3BhY2l0eTogMC4xNTsgfSAuY2xzLTMgeyBmaWxsOiAjZmZmOyB9PC9zdHlsZT48L2RlZnM+PHBhdGggaWQ9IkVsbGlwc2VfNzA2X2NvcHlfMTAiIGRhdGEtbmFtZT0iRWxsaXBzZSA3MDYgY29weSAxMCIgY2xhc3M9ImNscy0yIiBkPSJNNzkuMjcyIDQ3LjU4OGE0MC4wMzUgNDAuMDM1IDAgMCAxLTMwLjA0IDMxLjMzTDMzLjA1NyA2Mi43NCAzNCAzN2wxNC40LTIwLjI4eiIvPjxwYXRoIGlkPSJGb3JtYV8xX2NvcHlfMiIgZGF0YS1uYW1lPSJGb3JtYSAxIGNvcHkgMiIgY2xhc3M9ImNscy0zIiBkPSJNNDIgMzJsLS4wMjctMy44OTNhOC44NDMgOC44NDMgMCAwIDEgLjA4Mi0xLjM4IDIuNzI1IDIuNzI1IDAgMCAxIC4zNy0uOTY0IDEuNTE2IDEuNTE2IDAgMCAxIC45My0uNjU2QTYuNDYgNi40NiAwIDAgMSA0NSAyNWg0di04aC02LjI2cS01LjM5IDAtNy43NCAyLjYxYy0xLjU2OCAxLjc0LTIgNC4wMDUtMiA3LjM5M3Y1aC01djhoNVY2M2g4Ljk3MlY0MEg0OGwxLThoLTd6Ii8+PC9zdmc+"); }
3460
+
3461
+ .c-illustration--demopage {
3462
+ background-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iaW5zdGFwYWdlLnN2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCI+PGRlZnM+PHN0eWxlPi5jbHMtMSB7IGZpbGw6ICMxZTg4ZTU7IH0gLmNscy0yLCAuY2xzLTMgeyBmaWxsLXJ1bGU6IGV2ZW5vZGQ7IH0gLmNscy0yIHsgb3BhY2l0eTogMC4xNTsgZmlsdGVyOiB1cmwoI2ZpbHRlcik7IH0gLmNscy0zIHsgZmlsbDogI2ZmZjsgfTwvc3R5bGU+PGZpbHRlciBpZD0iZmlsdGVyIiB4PSI1MzYiIHk9IjE4IiB3aWR0aD0iNjgiIGhlaWdodD0iNjciIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGZlT2Zmc2V0IHJlc3VsdD0ib2Zmc2V0IiBkeT0iMSIgaW49IlNvdXJjZUFscGhhIi8+PGZlR2F1c3NpYW5CbHVyIHJlc3VsdD0iYmx1ciIgc3RkRGV2aWF0aW9uPSIyIi8+PGZlRmxvb2QgcmVzdWx0PSJmbG9vZCIgZmxvb2QtY29sb3I9IiMwZDFhMmMiIGZsb29kLW9wYWNpdHk9Ii4yMyIvPjxmZUNvbXBvc2l0ZSByZXN1bHQ9ImNvbXBvc2l0ZSIgb3BlcmF0b3I9ImluIiBpbjI9ImJsdXIiLz48ZmVCbGVuZCByZXN1bHQ9ImJsZW5kIiBpbj0iU291cmNlR3JhcGhpYyIvPjwvZmlsdGVyPjwvZGVmcz48cGF0aCBpZD0iRWxsaXBzZV83MDZfY29weV8xMSIgZGF0YS1uYW1lPSJFbGxpcHNlIDcwNiBjb3B5IDExIiBjbGFzcz0iY2xzLTIiIGQ9Ik02MDAsMzkuOTg3VjQwYTM5Ljk5NCwzOS45OTQsMCwwLDEtMzcuMTIyLDM5Ljg4Nkw1MzksNTZsNC0zMSw3LTVoNmwyNS45NzYsMS45NjRaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTIwKSIvPjxwYXRoIGlkPSJ3aGl0ZV9jb3B5XzMiIGRhdGEtbmFtZT0id2hpdGUgY29weSAzIiBjbGFzcz0iY2xzLTMiIGQ9Ik01NDkuMDksNTguMjMyVjIxLjM3YTAuNjg5LDAuNjg5LDAsMCwwLS41OS0wLjY3OEw1NDYsMjBhMS4xNjgsMS4xNjgsMCwwLDAtMSwxVjU5YzAsMC40MTkuODYxLDAuMywxLjI3OSwwLjIzNmwyLjIyLS4zMjVBMC42ODgsMC42ODgsMCwwLDAsNTQ5LjA5LDU4LjIzMlptLTYuNDg3LTMuNDZWMjQuNjY2YTAuNjg4LDAuNjg4LDAsMCwwLS42MTktMC42ODJsLTIuMjItLjIzYTAuNjg5LDAuNjg5LDAsMCwwLS43NjQuNjgyVjU1LjAyYTAuNjksMC42OSwwLDAsMCwuNzcyLjY4MmwyLjIyLS4yNDlBMC42ODgsMC42ODgsMCwwLDAsNTQyLjYsNTQuNzcyWk01ODEuNDIxLDIxLjY2bC0yOC42NDQtNC42NTFhMC42OSwwLjY5LDAsMCwwLS44LjY3N1Y2Mi4zMzJhMC42OSwwLjY5LDAsMCwwLC44MTMuNjc1bDI4LjY0My01LjAyNkEwLjY4NywwLjY4NywwLDAsMCw1ODIsNTcuM1YyMi4zMzdBMC42ODgsMC42ODgsMCwwLDAsNTgxLjQyMSwyMS42NlptLTMuMDUsMzIuNDU2YTAuNjg2LDAuNjg2LDAsMCwxLS41OTQuNjc5bC0yMC4yMiwyLjg2YTAuNjksMC42OSwwLDAsMS0uNzg5LTAuNjc5VjIzLjQ4NGEwLjY5LDAuNjksMCwwLDEsLjc3OC0wLjY4MWwyMC4yMTksMi41MTRhMC42ODgsMC42ODgsMCwwLDEsLjYwNi42OFY1NC4xMTVaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTIwKSIvPjwvc3ZnPg=="); }
3463
+
3464
+ .c-illustration--template {
3465
+ background-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0idGVtcGxhdGV2My5zdmciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmNscy0yIHsgb3BhY2l0eTogMC4xNTsgfSAuY2xzLTIsIC5jbHMtMyB7IGZpbGwtcnVsZTogZXZlbm9kZDsgfSAuY2xzLTMgeyBmaWxsOiAjZmZmOyB9PC9zdHlsZT48L2RlZnM+PHBhdGggaWQ9IkVsbGlwc2VfNzA2X2NvcHlfMTEiIGRhdGEtbmFtZT0iRWxsaXBzZSA3MDYgY29weSAxMSIgY2xhc3M9ImNscy0yIiBkPSJNOTkuOTc1IDQ5LjAxYy4wMDYuMzMuMDI1LjY2LjAyNS45OWE1MCA1MCAwIDAgMS01MCA1MGMtMS40IDAtMi43NzgtLjA3LTQuMTQ2LS4xOEwyMi44MyA3Ni43OSA3NSA3N2wuNzkzLTUyLjE3eiIvPjxwYXRoIGlkPSJSZWN0YW5nbGVfNl9jb3B5XzciIGRhdGEtbmFtZT0iUmVjdGFuZ2xlIDYgY29weSA3IiBjbGFzcz0iY2xzLTMiIGQ9Ik0yNSAyNGg0OWEyIDIgMCAwIDEgMiAydjUwYTIgMiAwIDAgMS0yIDJIMjVhMiAyIDAgMCAxLTItMlYyNmEyIDIgMCAwIDEgMi0yem0yMCA1aDI2djNINDV2LTN6TTI4IDYwaDQzdjNIMjh2LTN6bTUtMzFoM3YzaC0zdi0zem01IDBoM3YzaC0zdi0zem0tMTAgMGgzdjNoLTN2LTN6bTAgOGg0M3YxOEgyOFYzN3ptMTQgN2gxNXY2SDQydi02em0wIDIzaDE1djZINDJ2LTZ6Ii8+PC9zdmc+"); }
3466
+
3467
+ /*------------------------------------* #INPUT (Including standard input[type="text"] and textarea)
3468
+
3469
+ Base:
3470
+ .c-form-text
3471
+
3472
+ .c-form-text-item
3473
+ .c-form-text-item__field
3474
+ .c-form-text-item__label
3475
+ .c-form-text-item__bar
3476
+ .c-form-text-item__info
3477
+ .c-form-text-item__button
3478
+ .c-form-text-item__icon
3479
+
3480
+ Size modifiers:
3481
+ .c-form-text-item--small
3482
+ .c-form-text-item--x-small
3483
+ .c-form-text-item--no-info
3484
+ .c-form-text-item--no-label
3485
+
3486
+ .c-form-text-item__button.c-form-text-item__button--small
3487
+
3488
+ Field modifiers:
3489
+ .c-form-text-item__field--with-icon
3490
+
3491
+ State modifiers:
3492
+ .c-form-text-item__field.is-not-empty
3493
+ .c-form-text-item__field:focus
3494
+
3495
+ .c-form-text-item.has-action
3496
+ .c-form-text-item.has-danger
3497
+ .c-form-text-item.has-success
3498
+ .c-form-text-item.has-warning
3499
+ \*------------------------------------*/
3500
+ .c-form-text,
3501
+ .c-form-text-item__field {
3502
+ line-height: 22px; }
3503
+
3504
+ .c-form-text-item {
3505
+ position: relative;
3506
+ display: inline-block;
3507
+ z-index: 0;
3508
+ width: 100%;
3509
+ padding: 17px 0 22px; }
3510
+ .c-form-text-item + .c-form-text-item {
3511
+ margin-top: 15px; }
3512
+ .c-form-text-item.c-form-text-item--no-label {
3513
+ padding-top: 0; }
3514
+ .c-form-text-item.c-form-text-item--no-info {
3515
+ padding-bottom: 0; }
3516
+
3517
+ .c-form-text-item__field {
3518
+ background: none;
3519
+ border: none;
3520
+ padding: 0 0 3px;
3521
+ border-bottom: 1px solid #dde4ea;
3522
+ outline: none;
3523
+ width: 100%;
3524
+ font-size: inherit;
3525
+ color: inherit;
3526
+ -webkit-transition: all 0.2s ease-in-out;
3527
+ -moz-transition: all 0.2s ease-in-out;
3528
+ transition: all 0.2s ease-in-out; }
3529
+ .c-form-text-item--small .c-form-text-item__field,
3530
+ .c-form-text-item--x-small .c-form-text-item__field {
3531
+ padding-bottom: 2px; }
3532
+ .c-form-text-item--small .c-form-text-item__field {
3533
+ font-size: 14px; }
3534
+ .c-form-text-item--x-small .c-form-text-item__field {
3535
+ font-size: 12px; }
3536
+ .c-form-text-item__field::-webkit-input-placeholder {
3537
+ font-weight: normal;
3538
+ color: #90a4ae; }
3539
+ .c-form-text-item__field:-moz-placeholder {
3540
+ font-weight: normal;
3541
+ color: #90a4ae; }
3542
+ .c-form-text-item__field::-moz-placeholder {
3543
+ font-weight: normal;
3544
+ color: #90a4ae; }
3545
+ .c-form-text-item__field:-ms-input-placeholder {
3546
+ font-weight: normal;
3547
+ color: #90a4ae; }
3548
+ .c-form-text-item__field::placeholder {
3549
+ font-weight: normal;
3550
+ color: #90a4ae; }
3551
+ .c-form-text-item.has-danger .c-form-text-item__field,
3552
+ .c-form-text-item.has-warning .c-form-text-item__field,
3553
+ .c-form-text-item.has-action .c-form-text-item__field,
3554
+ .c-form-text-item.has-success .c-form-text-item__field, .c-form-text-item__field:focus {
3555
+ border-color: transparent; }
3556
+
3557
+ .c-form-text-item__field--with-icon {
3558
+ padding-right: 30px; }
3559
+ .c-form-text-item--small .c-form-text-item__field--with-icon {
3560
+ padding-right: 10px; }
3561
+
3562
+ textarea.c-form-text-item__field {
3563
+ height: 92px;
3564
+ line-height: 1.8;
3565
+ font-family: inherit;
3566
+ vertical-align: top;
3567
+ resize: vertical; }
3568
+
3569
+ .c-form-text-item__label {
3570
+ position: absolute;
3571
+ left: 0;
3572
+ top: 20px;
3573
+ z-index: -1;
3574
+ -webkit-transition: all 0.2s ease-in-out;
3575
+ -moz-transition: all 0.2s ease-in-out;
3576
+ transition: all 0.2s ease-in-out;
3577
+ color: #90a4ae; }
3578
+ .c-form-text-item--small .c-form-text-item__label {
3579
+ font-size: 14px; }
3580
+ .c-form-text-item--x-small .c-form-text-item__label {
3581
+ font-size: 12px; }
3582
+ .c-form-text-item__field.is-not-empty ~ .c-form-text-item__label,
3583
+ .c-form-text-item__field:focus ~ .c-form-text-item__label {
3584
+ font-size: 12px;
3585
+ top: 0; }
3586
+
3587
+ .c-form-text-item__bar {
3588
+ position: relative; }
3589
+ .c-form-text-item__bar::after, .c-form-text-item__bar::before {
3590
+ content: '';
3591
+ position: absolute;
3592
+ width: 0;
3593
+ height: 2px;
3594
+ bottom: 0;
3595
+ -webkit-transition: all 0.2s ease-in-out;
3596
+ -moz-transition: all 0.2s ease-in-out;
3597
+ transition: all 0.2s ease-in-out;
3598
+ background-color: #1e88e5; }
3599
+ .c-form-text-item__bar::after {
3600
+ right: 50%; }
3601
+ .c-form-text-item__bar::before {
3602
+ left: 50%; }
3603
+ .has-action .c-form-text-item__bar::after, .has-action .c-form-text-item__bar::before,
3604
+ .has-warning .c-form-text-item__bar::after,
3605
+ .has-warning .c-form-text-item__bar::before,
3606
+ .has-danger .c-form-text-item__bar::after,
3607
+ .has-danger .c-form-text-item__bar::before,
3608
+ .has-error .c-form-text-item__bar::after,
3609
+ .has-error .c-form-text-item__bar::before,
3610
+ .has-success .c-form-text-item__bar::after,
3611
+ .has-success .c-form-text-item__bar::before {
3612
+ width: 50%; }
3613
+ .has-success .c-form-text-item__bar::after, .has-success .c-form-text-item__bar::before {
3614
+ background-color: #4caf50; }
3615
+ .has-action .c-form-text-item__bar::after, .has-action .c-form-text-item__bar::before {
3616
+ background-color: #1e88e5; }
3617
+ .has-warning .c-form-text-item__bar::after, .has-warning .c-form-text-item__bar::before {
3618
+ background-color: #ffc107; }
3619
+ .has-danger .c-form-text-item__bar::after, .has-danger .c-form-text-item__bar::before {
3620
+ background-color: #f44336; }
3621
+ .c-form-text-item__field:focus ~ .c-form-text-item__bar::after, .c-form-text-item__field:focus ~ .c-form-text-item__bar::before, .select2-container--open ~ .c-form-text-item__bar::after, .select2-container--open ~ .c-form-text-item__bar::before {
3622
+ width: 50%; }
3623
+
3624
+ .c-form-text-item__button,
3625
+ .c-form-text-item__icon {
3626
+ position: absolute;
3627
+ right: 0;
3628
+ top: 17px;
3629
+ z-index: -1; }
3630
+ .c-form-text-item--no-label .c-form-text-item__button, .c-form-text-item--no-label
3631
+ .c-form-text-item__icon {
3632
+ top: 0; }
3633
+
3634
+ .c-form-text-item__button--small {
3635
+ top: 21px; }
3636
+ .c-form-text-item--no-label .c-form-text-item__button--small {
3637
+ top: 5px; }
3638
+
3639
+ .c-form-text-item__icon {
3640
+ line-height: 18px;
3641
+ width: 18px;
3642
+ font-size: 18px;
3643
+ color: #a6b6be;
3644
+ text-align: right; }
3645
+
3646
+ .c-form-text-item__info {
3647
+ font-size: 12px;
3648
+ position: absolute;
3649
+ left: 0;
3650
+ top: -webkit-calc(100% - 17px);
3651
+ top: -moz-calc(100% - 17px);
3652
+ top: calc(100% - 17px);
3653
+ width: 100%;
3654
+ display: -webkit-box;
3655
+ display: -webkit-flex;
3656
+ display: -moz-box;
3657
+ display: -ms-flexbox;
3658
+ display: flex;
3659
+ -webkit-box-align: center;
3660
+ -webkit-align-items: center;
3661
+ -moz-box-align: center;
3662
+ -ms-flex-align: center;
3663
+ align-items: center;
3664
+ min-height: 18px;
3665
+ -webkit-box-pack: justify;
3666
+ -webkit-justify-content: space-between;
3667
+ -moz-box-pack: justify;
3668
+ -ms-flex-pack: justify;
3669
+ justify-content: space-between; }
3670
+ .c-form-text-item.has-danger .c-form-text-item__info {
3671
+ color: #f44336; }
3672
+ .c-form-text-item.has-warning .c-form-text-item__info {
3673
+ color: #ffc107; }
3674
+ .c-form-text-item.has-success .c-form-text-item__info {
3675
+ color: #4caf50; }
3676
+ .c-form-text-item.has-action .c-form-text-item__info {
3677
+ color: #1e88e5; }
3678
+
3679
+ .c-form-text-item__info-icon {
3680
+ font-size: 18px;
3681
+ -webkit-align-self: flex-start;
3682
+ -ms-flex-item-align: start;
3683
+ align-self: flex-start;
3684
+ -webkit-flex-shrink: 0;
3685
+ -ms-flex-negative: 0;
3686
+ flex-shrink: 0; }
3687
+
3688
+ /*------------------------------------* #LIST
3689
+
3690
+ Base:
3691
+ .c-list
3692
+ .c-list-item
3693
+ .c-list-item__icon
3694
+ .c-list-item__content
3695
+
3696
+ Padding modifiers:
3697
+ .c-list--spacing-primary
3698
+ .c-list--spacing-secondary
3699
+ .c-list--spacing-tertiary
3700
+ .c-list--spacing-quaternary
3701
+
3702
+ Hover effect modifiers:
3703
+ .c-list--hover-primary
3704
+ .c-list--hover-secondary
3705
+
3706
+ Single item modifiers:
3707
+ .c-list-item__content--no-hover
3708
+ .c-list-item__content--title
3709
+
3710
+ State modifiers:
3711
+ .c-list-item__content.is-active
3712
+ .c-list-item__content.is-disabled
3713
+ \*------------------------------------*/
3714
+ .c-list {
3715
+ font-size: 14px;
3716
+ line-height: 150%;
3717
+ width: 100%; }
3718
+ .c-list + .c-list {
3719
+ border-top: 1px solid #dde4ea; }
3720
+
3721
+ .c-list-item__content {
3722
+ display: -webkit-box;
3723
+ display: -webkit-flex;
3724
+ display: -moz-box;
3725
+ display: -ms-flexbox;
3726
+ display: flex;
3727
+ -webkit-box-align: center;
3728
+ -webkit-align-items: center;
3729
+ -moz-box-align: center;
3730
+ -ms-flex-align: center;
3731
+ align-items: center;
3732
+ padding-top: 10px;
3733
+ padding-bottom: 10px;
3734
+ cursor: pointer; }
3735
+ .c-list--spacing-primary .c-list-item__content {
3736
+ padding-right: 10px;
3737
+ padding-left: 10px; }
3738
+ .c-list--spacing-secondary .c-list-item__content {
3739
+ padding-right: 15px;
3740
+ padding-left: 15px; }
3741
+ .c-list--spacing-tertiary .c-list-item__content {
3742
+ padding-right: 20px;
3743
+ padding-left: 20px; }
3744
+ .c-list--spacing-quaternary .c-list-item__content {
3745
+ padding-right: 30px;
3746
+ padding-left: 30px; }
3747
+ .c-list--hover-primary .c-list-item__content:hover {
3748
+ background-color: #f4f4f4; }
3749
+ .c-list--hover-secondary .c-list-item__content:hover {
3750
+ background-color: #1e88e5;
3751
+ color: #ffffff; }
3752
+ .c-list-item__content.c-list-item__content--no-hover:hover {
3753
+ background-color: inherit;
3754
+ color: inherit; }
3755
+ .c-list-item__content.is-active {
3756
+ color: #1e88e5; }
3757
+ .c-list-item__content.is-disabled {
3758
+ color: #a6b6be;
3759
+ cursor: default; }
3760
+ .c-list--multiline .c-list-item__content {
3761
+ -webkit-box-orient: vertical;
3762
+ -webkit-box-direction: normal;
3763
+ -webkit-flex-direction: column;
3764
+ -moz-box-orient: vertical;
3765
+ -moz-box-direction: normal;
3766
+ -ms-flex-direction: column;
3767
+ flex-direction: column;
3768
+ -webkit-box-align: start;
3769
+ -webkit-align-items: flex-start;
3770
+ -moz-box-align: start;
3771
+ -ms-flex-align: start;
3772
+ align-items: flex-start; }
3773
+ .c-dropdown .c-list-item__content {
3774
+ padding-right: 40px; }
3775
+
3776
+ .c-list-item__title {
3777
+ font-size: 16px;
3778
+ font-weight: 600; }
3779
+
3780
+ .c-list-item__icon {
3781
+ margin-right: 15px; }
3782
+
3783
+ /*------------------------------------* #LOADER
3784
+ \*------------------------------------*/
3785
+ .c-loader {
3786
+ display: inline-block;
3787
+ background-repeat: no-repeat;
3788
+ background-position: center;
3789
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOTAiIGhlaWdodD0iMTkwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiIGNsYXNzPSJ1aWwtcmluZyI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6IiBjbGFzcz0iYmsiLz48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0NSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZGRlNGVhIiBzdHJva2Utd2lkdGg9IjEwIiBzdHJva2UtZGFzaGFycmF5PSIxODMuNzgzMTcwMjM1MDAyOSA5OC45NjAxNjg1ODgwNzg0OSI+PGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHZhbHVlcz0iMCA1MCA1MDsxODAgNTAgNTA7MzYwIDUwIDUwOyIga2V5VGltZXM9IjA7MC41OzEiIGR1cj0iMXMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBiZWdpbj0iMHMiLz48L2NpcmNsZT48L3N2Zz4=");
3790
+ width: 40px;
3791
+ height: 40px;
3792
+ -moz-background-size: cover;
3793
+ background-size: cover; }
3794
+ .c-button .c-loader {
3795
+ vertical-align: middle; }
3796
+
3797
+ .c-loader--small {
3798
+ width: 18px;
3799
+ height: 18px; }
3800
+
3801
+ .c-loader--large {
3802
+ width: 80px;
3803
+ height: 80px; }
3804
+
3805
+ .c-loader--x-large {
3806
+ width: 100px;
3807
+ height: 100px; }
3808
+
3809
+ /*
3810
+ #MARK
3811
+
3812
+ Base:
3813
+ .c-mark
3814
+ .c-mark__input - hidden from screen
3815
+ .c-mark__icon
3816
+ .c-mark__label
3817
+
3818
+ Type modifiers:
3819
+ .c-mark__icon--checkbox
3820
+ .c-mark__icon--radio
3821
+
3822
+ Size modifiers:
3823
+ .c-mark__icon--small
3824
+ .c-mark__icon--large
3825
+ .c-mark__icon--x-large
3826
+
3827
+ Color modifiers:
3828
+ .c-mark__icon--1
3829
+ .c-mark__icon--2
3830
+ .c-mark__icon--3
3831
+ .c-mark__icon--4
3832
+ .c-mark__icon--5
3833
+ .c-mark__icon--6
3834
+ .c-mark__icon--7
3835
+ .c-mark__icon--8
3836
+ .c-mark__icon--9
3837
+ .c-mark__icon--10
3838
+
3839
+ State modifiers:
3840
+ .c-mark__input:disabled
3841
+ .c-mark__input:checked
3842
+ .c-mark__input:disabled:checked
3843
+ */
3844
+ .c-mark {
3845
+ margin: 0;
3846
+ padding: 0;
3847
+ display: -webkit-box;
3848
+ display: -webkit-flex;
3849
+ display: -moz-box;
3850
+ display: -ms-flexbox;
3851
+ display: flex;
3852
+ line-height: 100%;
3853
+ -webkit-box-align: center;
3854
+ -webkit-align-items: center;
3855
+ -moz-box-align: center;
3856
+ -ms-flex-align: center;
3857
+ align-items: center;
3858
+ -webkit-user-select: none;
3859
+ -moz-user-select: none;
3860
+ -ms-user-select: none;
3861
+ user-select: none;
3862
+ outline: 0; }
3863
+
3864
+ .c-mark__input {
3865
+ position: absolute;
3866
+ overflow: hidden;
3867
+ clip: rect(0 0 0 0);
3868
+ height: 1px;
3869
+ width: 1px;
3870
+ margin: -1px;
3871
+ padding: 0;
3872
+ border: 0; }
3873
+
3874
+ .c-mark__icon {
3875
+ border: #90a4ae 2px solid;
3876
+ background-color: #ffffff;
3877
+ display: -webkit-box;
3878
+ display: -webkit-flex;
3879
+ display: -moz-box;
3880
+ display: -ms-flexbox;
3881
+ display: flex;
3882
+ -webkit-box-align: center;
3883
+ -webkit-align-items: center;
3884
+ -moz-box-align: center;
3885
+ -ms-flex-align: center;
3886
+ align-items: center;
3887
+ -webkit-box-pack: center;
3888
+ -webkit-justify-content: center;
3889
+ -moz-box-pack: center;
3890
+ -ms-flex-pack: center;
3891
+ justify-content: center;
3892
+ width: 16px;
3893
+ height: 16px; }
3894
+ .c-mark__icon:active {
3895
+ -webkit-box-shadow: 0 0 0 8px rgba(30, 136, 229, 0.2);
3896
+ -moz-box-shadow: 0 0 0 8px rgba(30, 136, 229, 0.2);
3897
+ box-shadow: 0 0 0 8px rgba(30, 136, 229, 0.2); }
3898
+ .c-mark__icon--small {
3899
+ width: 14px;
3900
+ height: 14px; }
3901
+ .c-mark__icon--large {
3902
+ width: 20px;
3903
+ height: 20px; }
3904
+ .c-mark__icon--x-large {
3905
+ width: 24px;
3906
+ height: 24px; }
3907
+ .c-mark__icon.c-mark__icon--1:active {
3908
+ -webkit-box-shadow: 0 0 0 8px rgba(116, 193, 119, 0.2);
3909
+ -moz-box-shadow: 0 0 0 8px rgba(116, 193, 119, 0.2);
3910
+ box-shadow: 0 0 0 8px rgba(116, 193, 119, 0.2); }
3911
+ .c-mark__icon.c-mark__icon--2:active {
3912
+ -webkit-box-shadow: 0 0 0 8px rgba(251, 140, 0, 0.2);
3913
+ -moz-box-shadow: 0 0 0 8px rgba(251, 140, 0, 0.2);
3914
+ box-shadow: 0 0 0 8px rgba(251, 140, 0, 0.2); }
3915
+ .c-mark__icon.c-mark__icon--3:active {
3916
+ -webkit-box-shadow: 0 0 0 8px rgba(244, 67, 54, 0.2);
3917
+ -moz-box-shadow: 0 0 0 8px rgba(244, 67, 54, 0.2);
3918
+ box-shadow: 0 0 0 8px rgba(244, 67, 54, 0.2); }
3919
+ .c-mark__icon.c-mark__icon--4:active {
3920
+ -webkit-box-shadow: 0 0 0 8px rgba(33, 150, 243, 0.2);
3921
+ -moz-box-shadow: 0 0 0 8px rgba(33, 150, 243, 0.2);
3922
+ box-shadow: 0 0 0 8px rgba(33, 150, 243, 0.2); }
3923
+ .c-mark__icon.c-mark__icon--5:active {
3924
+ -webkit-box-shadow: 0 0 0 8px rgba(103, 58, 183, 0.2);
3925
+ -moz-box-shadow: 0 0 0 8px rgba(103, 58, 183, 0.2);
3926
+ box-shadow: 0 0 0 8px rgba(103, 58, 183, 0.2); }
3927
+ .c-mark__icon.c-mark__icon--6:active {
3928
+ -webkit-box-shadow: 0 0 0 8px rgba(0, 188, 212, 0.2);
3929
+ -moz-box-shadow: 0 0 0 8px rgba(0, 188, 212, 0.2);
3930
+ box-shadow: 0 0 0 8px rgba(0, 188, 212, 0.2); }
3931
+ .c-mark__icon.c-mark__icon--7:active {
3932
+ -webkit-box-shadow: 0 0 0 8px rgba(192, 202, 51, 0.2);
3933
+ -moz-box-shadow: 0 0 0 8px rgba(192, 202, 51, 0.2);
3934
+ box-shadow: 0 0 0 8px rgba(192, 202, 51, 0.2); }
3935
+ .c-mark__icon.c-mark__icon--8:active {
3936
+ -webkit-box-shadow: 0 0 0 8px rgba(255, 193, 7, 0.2);
3937
+ -moz-box-shadow: 0 0 0 8px rgba(255, 193, 7, 0.2);
3938
+ box-shadow: 0 0 0 8px rgba(255, 193, 7, 0.2); }
3939
+ .c-mark__icon.c-mark__icon--9:active {
3940
+ -webkit-box-shadow: 0 0 0 8px rgba(121, 85, 72, 0.2);
3941
+ -moz-box-shadow: 0 0 0 8px rgba(121, 85, 72, 0.2);
3942
+ box-shadow: 0 0 0 8px rgba(121, 85, 72, 0.2); }
3943
+ .c-mark__icon.c-mark__icon--10:active {
3944
+ -webkit-box-shadow: 0 0 0 8px rgba(63, 81, 181, 0.2);
3945
+ -moz-box-shadow: 0 0 0 8px rgba(63, 81, 181, 0.2);
3946
+ box-shadow: 0 0 0 8px rgba(63, 81, 181, 0.2); }
3947
+
3948
+ .c-mark__icon,
3949
+ .c-mark__label {
3950
+ cursor: pointer; }
3951
+
3952
+ .c-mark__icon + .c-mark__label,
3953
+ .c-mark__label + .c-mark__icon {
3954
+ padding-left: 10px; }
3955
+
3956
+ /*------------------------------------* .c-mark__icon--radio
3957
+ \*------------------------------------*/
3958
+ .c-mark__icon--radio {
3959
+ -webkit-border-radius: 50%;
3960
+ -moz-border-radius: 50%;
3961
+ border-radius: 50%; }
3962
+ .c-mark__icon--radio::before {
3963
+ background-color: #1e88e5;
3964
+ -webkit-border-radius: 50%;
3965
+ -moz-border-radius: 50%;
3966
+ border-radius: 50%;
3967
+ width: 0;
3968
+ height: 0;
3969
+ content: '';
3970
+ width: 6px;
3971
+ height: 6px;
3972
+ -webkit-transition: all 0.2s ease-in-out;
3973
+ -moz-transition: all 0.2s ease-in-out;
3974
+ transition: all 0.2s ease-in-out;
3975
+ -webkit-transform: scale(0);
3976
+ -moz-transform: scale(0);
3977
+ -ms-transform: scale(0);
3978
+ transform: scale(0);
3979
+ -webkit-transform-origin: center;
3980
+ -moz-transform-origin: center;
3981
+ -ms-transform-origin: center;
3982
+ transform-origin: center; }
3983
+
3984
+ /*------------------------------------* .c-mark__icon--checkbox
3985
+ \*------------------------------------*/
3986
+ .c-mark__icon--checkbox {
3987
+ -webkit-border-radius: 3px;
3988
+ -moz-border-radius: 3px;
3989
+ border-radius: 3px;
3990
+ -webkit-transition: all 0.2s ease-in-out;
3991
+ -moz-transition: all 0.2s ease-in-out;
3992
+ transition: all 0.2s ease-in-out;
3993
+ color: transparent;
3994
+ font-size: 0; }
3995
+
3996
+ /*------------------------------------* .c-mark__input:checked .c-mark__icon--checkbox
3997
+ .c-mark__input:checked .c-mark__icon--radio
3998
+ \*------------------------------------*/
3999
+ .c-mark__input:checked ~ .c-mark__icon--radio {
4000
+ border-color: #1e88e5; }
4001
+ .c-mark__input:checked ~ .c-mark__icon--radio::before {
4002
+ -webkit-transform: scale(1);
4003
+ -moz-transform: scale(1);
4004
+ -ms-transform: scale(1);
4005
+ transform: scale(1); }
4006
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--small::before {
4007
+ width: 4px;
4008
+ height: 4px; }
4009
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--large::before {
4010
+ width: 10px;
4011
+ height: 10px; }
4012
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--x-large::before {
4013
+ width: 14px;
4014
+ height: 14px; }
4015
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--1 {
4016
+ border-color: #74c177; }
4017
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--1::before {
4018
+ background-color: #74c177; }
4019
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--2 {
4020
+ border-color: #fb8c00; }
4021
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--2::before {
4022
+ background-color: #fb8c00; }
4023
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--3 {
4024
+ border-color: #f44336; }
4025
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--3::before {
4026
+ background-color: #f44336; }
4027
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--4 {
4028
+ border-color: #2196f3; }
4029
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--4::before {
4030
+ background-color: #2196f3; }
4031
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--5 {
4032
+ border-color: #673ab7; }
4033
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--5::before {
4034
+ background-color: #673ab7; }
4035
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--6 {
4036
+ border-color: #00bcd4; }
4037
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--6::before {
4038
+ background-color: #00bcd4; }
4039
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--7 {
4040
+ border-color: #c0ca33; }
4041
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--7::before {
4042
+ background-color: #c0ca33; }
4043
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--8 {
4044
+ border-color: #ffc107; }
4045
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--8::before {
4046
+ background-color: #ffc107; }
4047
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--9 {
4048
+ border-color: #795548; }
4049
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--9::before {
4050
+ background-color: #795548; }
4051
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--10 {
4052
+ border-color: #3f51b5; }
4053
+ .c-mark__input:checked ~ .c-mark__icon--radio.c-mark__icon--10::before {
4054
+ background-color: #3f51b5; }
4055
+
4056
+ .c-mark__input:checked ~ .c-mark__icon--checkbox {
4057
+ background-color: #1e88e5;
4058
+ border-color: transparent;
4059
+ color: #ffffff;
4060
+ font-size: 16px; }
4061
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--small {
4062
+ font-size: 14px; }
4063
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--large {
4064
+ font-size: 20px; }
4065
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--x-large {
4066
+ font-size: 24px; }
4067
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--1 {
4068
+ background-color: #74c177; }
4069
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--2 {
4070
+ background-color: #fb8c00; }
4071
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--3 {
4072
+ background-color: #f44336; }
4073
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--4 {
4074
+ background-color: #2196f3; }
4075
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--5 {
4076
+ background-color: #673ab7; }
4077
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--6 {
4078
+ background-color: #00bcd4; }
4079
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--7 {
4080
+ background-color: #c0ca33; }
4081
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--8 {
4082
+ background-color: #ffc107; }
4083
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--9 {
4084
+ background-color: #795548; }
4085
+ .c-mark__input:checked ~ .c-mark__icon--checkbox.c-mark__icon--10 {
4086
+ background-color: #3f51b5; }
4087
+
4088
+ /*------------------------------------* .c-mark__input:disabled .c-mark__icon
4089
+ .c-mark__input:disabled .c-mark__label
4090
+ \*------------------------------------*/
4091
+ .c-mark__input:disabled ~ .c-mark__icon,
4092
+ .c-mark__input:disabled ~ .c-mark__label {
4093
+ pointer-events: none; }
4094
+
4095
+ .c-mark__input:disabled ~ .c-mark__icon {
4096
+ border-color: #dde4ea; }
4097
+
4098
+ /*------------------------------------*.c-mark__input:disabled:checked .c-mark__icon--checkbox
4099
+ .c-mark__input:disabled:checked .c-mark__icon--radio
4100
+ \*------------------------------------*/
4101
+ .c-mark__input:disabled:checked ~ .c-mark__icon--radio::before, .c-mark__input:disabled:checked ~ .c-mark__icon--checkbox {
4102
+ background-color: #dde4ea; }
4103
+
4104
+ /*
4105
+ #MODAL
4106
+
4107
+ Base:
4108
+ .c-modal
4109
+ .c-modal__close
4110
+ .c-modal__head - padding [top right left] by default
4111
+ .c-modal__title
4112
+ .c-modal__body - padding [bottom right left] by default
4113
+
4114
+ .c-modal__arrow
4115
+
4116
+ Type modifiers:
4117
+ .c-modal--simple
4118
+ .c-modal--popover
4119
+
4120
+ Size (width) modifiers:
4121
+ .c-modal--x-small
4122
+ .c-modal--small
4123
+ .c-modal--large
4124
+ .c-modal--x-large
4125
+
4126
+ Arrow modifiers:
4127
+ .c-modal__arrow---top
4128
+ .c-modal__arrow---top-right
4129
+ .c-modal__arrow---top-left
4130
+ .c-modal__arrow---right
4131
+ .c-modal__arrow---right-top
4132
+ .c-modal__arrow---right-bottom
4133
+ .c-modal__arrow---bottom
4134
+ .c-modal__arrow---bottom-right
4135
+ .c-modal__arrow---bottom-left
4136
+ .c-modal__arrow---left
4137
+ .c-modal__arrow---left-top
4138
+ .c-modal__arrow---left-bottom
4139
+ */
4140
+ /*------------------------------------* .c-modal
4141
+ \*------------------------------------*/
4142
+ .c-modal {
4143
+ -webkit-box-shadow: 0 0 3px rgba(13, 26, 43, 0.16), 0 15px 18px rgba(13, 26, 43, 0.24);
4144
+ -moz-box-shadow: 0 0 3px rgba(13, 26, 43, 0.16), 0 15px 18px rgba(13, 26, 43, 0.24);
4145
+ box-shadow: 0 0 3px rgba(13, 26, 43, 0.16), 0 15px 18px rgba(13, 26, 43, 0.24);
4146
+ -webkit-border-radius: 3px;
4147
+ -moz-border-radius: 3px;
4148
+ border-radius: 3px;
4149
+ display: inline-block;
4150
+ width: 100%;
4151
+ position: fixed;
4152
+ z-index: 50000;
4153
+ cursor: default;
4154
+ background-color: #ffffff; }
4155
+
4156
+ /*------------------------------------* .c-modal
4157
+ \*------------------------------------*/
4158
+ .c-modal__head {
4159
+ padding: 30px; }
4160
+
4161
+ .c-modal__title {
4162
+ margin: 0;
4163
+ line-height: 1;
4164
+ padding: 0; }
4165
+
4166
+ .c-modal__body {
4167
+ padding-left: 30px;
4168
+ padding-right: 30px;
4169
+ padding-bottom: 30px; }
4170
+
4171
+ .c-modal__close {
4172
+ position: absolute;
4173
+ top: 30px;
4174
+ right: 30px; }
4175
+
4176
+ /*------------------------------------* .c-modal--simple
4177
+ \*------------------------------------*/
4178
+ .c-modal--simple .c-modal__body {
4179
+ padding-bottom: 18px;
4180
+ padding-right: 18px; }
4181
+
4182
+ /*------------------------------------* .c-modal--popover
4183
+ \*------------------------------------*/
4184
+ .c-modal--popover .c-modal__body {
4185
+ padding-top: 30px;
4186
+ padding-right: 50px; }
4187
+
4188
+ /*------------------------------------* .c-modal size modifiers
4189
+ \*------------------------------------*/
4190
+ .c-modal--x-small {
4191
+ max-width: 355px; }
4192
+
4193
+ .c-modal--small {
4194
+ max-width: 420px; }
4195
+
4196
+ .c-modal--large {
4197
+ max-width: 550px; }
4198
+
4199
+ .c-modal--x-large {
4200
+ max-width: 680px; }
4201
+
4202
+ /*------------------------------------* .c-modal__arrow
4203
+ \*------------------------------------*/
4204
+ .c-modal__arrow, .c-modal__arrow:after {
4205
+ position: absolute; }
4206
+
4207
+ .c-modal__arrow--top,
4208
+ .c-modal__arrow--bottom {
4209
+ left: 50%; }
4210
+ .c-modal__arrow--top, .c-modal__arrow--top:after,
4211
+ .c-modal__arrow--bottom,
4212
+ .c-modal__arrow--bottom:after {
4213
+ margin-left: -10px; }
4214
+ .c-modal__arrow--top-left,
4215
+ .c-modal__arrow--bottom-left {
4216
+ left: 30px; }
4217
+ .c-modal__arrow--top-right,
4218
+ .c-modal__arrow--bottom-right {
4219
+ left: auto;
4220
+ right: 30px; }
4221
+
4222
+ .c-modal__arrow--top {
4223
+ top: -10px; }
4224
+ .c-modal__arrow--top, .c-modal__arrow--top:after {
4225
+ content: '';
4226
+ display: block;
4227
+ width: 0;
4228
+ height: 0;
4229
+ border-style: solid;
4230
+ border-width: 10px;
4231
+ border-left-color: transparent;
4232
+ border-right-color: transparent;
4233
+ border-bottom-color: rgba(144, 164, 174, 0.3);
4234
+ border-top-color: transparent;
4235
+ border-top-width: 0; }
4236
+ .c-modal__arrow--top:after {
4237
+ top: 1px;
4238
+ border-bottom-color: #ffffff; }
4239
+
4240
+ .c-modal__arrow--bottom {
4241
+ bottom: -10px; }
4242
+ .c-modal__arrow--bottom, .c-modal__arrow--bottom:after {
4243
+ content: '';
4244
+ display: block;
4245
+ width: 0;
4246
+ height: 0;
4247
+ border-style: solid;
4248
+ border-width: 10px;
4249
+ border-left-color: transparent;
4250
+ border-right-color: transparent;
4251
+ border-bottom-color: transparent;
4252
+ border-top-color: #90a4ae;
4253
+ border-bottom-width: 0; }
4254
+ .c-modal__arrow--bottom:after {
4255
+ bottom: 1px;
4256
+ border-top-color: #ffffff; }
4257
+
4258
+ .c-modal__arrow--left,
4259
+ .c-modal__arrow--right {
4260
+ top: 50%; }
4261
+ .c-modal__arrow--left, .c-modal__arrow--left:after,
4262
+ .c-modal__arrow--right,
4263
+ .c-modal__arrow--right:after {
4264
+ margin-top: -10px; }
4265
+ .c-modal__arrow--left-top,
4266
+ .c-modal__arrow--right-top {
4267
+ top: 30px; }
4268
+ .c-modal__arrow--left-bottom,
4269
+ .c-modal__arrow--right-bottom {
4270
+ top: auto;
4271
+ bottom: 30px; }
4272
+
4273
+ .c-modal__arrow--left {
4274
+ left: -10px; }
4275
+ .c-modal__arrow--left, .c-modal__arrow--left:after {
4276
+ content: '';
4277
+ display: block;
4278
+ width: 0;
4279
+ height: 0;
4280
+ border-style: solid;
4281
+ border-width: 10px;
4282
+ border-left-color: transparent;
4283
+ border-right-color: rgba(144, 164, 174, 0.3);
4284
+ border-bottom-color: transparent;
4285
+ border-top-color: transparent;
4286
+ border-left-width: 0; }
4287
+ .c-modal__arrow--left:after {
4288
+ left: 1px;
4289
+ border-right-color: #ffffff; }
4290
+
4291
+ .c-modal__arrow--right {
4292
+ right: -10px; }
4293
+ .c-modal__arrow--right, .c-modal__arrow--right:after {
4294
+ content: '';
4295
+ display: block;
4296
+ width: 0;
4297
+ height: 0;
4298
+ border-style: solid;
4299
+ border-width: 10px;
4300
+ border-left-color: rgba(144, 164, 174, 0.3);
4301
+ border-right-color: transparent;
4302
+ border-bottom-color: transparent;
4303
+ border-top-color: transparent;
4304
+ border-right-width: 0; }
4305
+ .c-modal__arrow--right:after {
4306
+ right: 1px;
4307
+ border-left-color: #ffffff; }
4308
+
4309
+ /*------------------------------------* #NOTIFICATION
4310
+
4311
+ Base:
4312
+ .c-notification
4313
+ .c-notification__title
4314
+ .c-notification__close
4315
+ \*------------------------------------*/
4316
+ .c-notification {
4317
+ color: #ffffff;
4318
+ background-color: #37475a; }
4319
+
4320
+ .c-notification__title {
4321
+ font-weight: 600; }
4322
+
4323
+ .c-notification__close {
4324
+ font-size: 24px;
4325
+ color: #a6b6be;
4326
+ cursor: pointer; }
4327
+
4328
+ /*------------------------------------* #PAGINATION
4329
+
4330
+ Base:
4331
+ .c-pagination
4332
+ .c-pagination__list
4333
+ .c-pagination__item
4334
+ .c-pagination__page
4335
+ .c-pagination__icon
4336
+ .c-pagination__separator
4337
+
4338
+
4339
+ Display modifiers:
4340
+ .c-pagination--left
4341
+ .c-pagination--right
4342
+
4343
+ State modifiers for .c-pagination__page:
4344
+ .is-disabled
4345
+ .is-active
4346
+ \*------------------------------------*/
4347
+ .c-pagination {
4348
+ display: -webkit-box;
4349
+ display: -webkit-flex;
4350
+ display: -moz-box;
4351
+ display: -ms-flexbox;
4352
+ display: flex;
4353
+ -webkit-box-pack: center;
4354
+ -webkit-justify-content: center;
4355
+ -moz-box-pack: center;
4356
+ -ms-flex-pack: center;
4357
+ justify-content: center; }
4358
+
4359
+ .c-pagination--left {
4360
+ -webkit-box-pack: start;
4361
+ -webkit-justify-content: flex-start;
4362
+ -moz-box-pack: start;
4363
+ -ms-flex-pack: start;
4364
+ justify-content: flex-start; }
4365
+
4366
+ .c-pagination--right {
4367
+ -webkit-box-pack: end;
4368
+ -webkit-justify-content: flex-end;
4369
+ -moz-box-pack: end;
4370
+ -ms-flex-pack: end;
4371
+ justify-content: flex-end; }
4372
+
4373
+ .c-pagination__list {
4374
+ display: -webkit-inline-box;
4375
+ display: -webkit-inline-flex;
4376
+ display: -moz-inline-box;
4377
+ display: -ms-inline-flexbox;
4378
+ display: inline-flex;
4379
+ -webkit-box-align: center;
4380
+ -webkit-align-items: center;
4381
+ -moz-box-align: center;
4382
+ -ms-flex-align: center;
4383
+ align-items: center;
4384
+ font-size: 14px;
4385
+ -webkit-box-pack: center;
4386
+ -webkit-justify-content: center;
4387
+ -moz-box-pack: center;
4388
+ -ms-flex-pack: center;
4389
+ justify-content: center;
4390
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4391
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4392
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24); }
4393
+
4394
+ .c-pagination__page,
4395
+ .c-pagination__separator {
4396
+ display: -webkit-box;
4397
+ display: -webkit-flex;
4398
+ display: -moz-box;
4399
+ display: -ms-flexbox;
4400
+ display: flex;
4401
+ -webkit-box-align: center;
4402
+ -webkit-align-items: center;
4403
+ -moz-box-align: center;
4404
+ -ms-flex-align: center;
4405
+ align-items: center;
4406
+ -webkit-justify-content: space-around;
4407
+ -ms-flex-pack: distribute;
4408
+ justify-content: space-around;
4409
+ line-height: 34px;
4410
+ height: 34px;
4411
+ width: 34px;
4412
+ background-color: #ffffff;
4413
+ color: #37475a;
4414
+ text-decoration: none; }
4415
+
4416
+ .c-pagination__page {
4417
+ -webkit-transition: all 0.2s ease-in-out;
4418
+ -moz-transition: all 0.2s ease-in-out;
4419
+ transition: all 0.2s ease-in-out; }
4420
+ .c-pagination__page:hover {
4421
+ text-decoration: none; }
4422
+ .c-pagination__page:hover, .c-pagination__page.is-active {
4423
+ background-color: #f4f4f4; }
4424
+ .c-pagination__page.is-active, .c-pagination__page.is-disabled {
4425
+ pointer-events: none; }
4426
+ .c-pagination__page.is-disabled {
4427
+ color: #dde4ea; }
4428
+
4429
+ .c-pagination__separator {
4430
+ pointer-events: none; }
4431
+
4432
+ .c-pagination__icon {
4433
+ font-size: 24px;
4434
+ color: #37475a; }
4435
+ .c-pagination__page.is-disabled .c-pagination__icon {
4436
+ color: #dde4ea; }
4437
+
4438
+ /*------------------------------------* #RIBBON
4439
+
4440
+ Base:
4441
+ .c-ribbon
4442
+ .c-ribbon__text
4443
+ \*------------------------------------*/
4444
+ .c-ribbon {
4445
+ position: absolute;
4446
+ right: -2px;
4447
+ top: -2px;
4448
+ z-index: 50;
4449
+ overflow: hidden;
4450
+ width: 84px;
4451
+ height: 84px;
4452
+ text-transform: uppercase; }
4453
+
4454
+ .c-ribbon__text {
4455
+ position: absolute;
4456
+ top: 18px;
4457
+ right: -26px;
4458
+ display: block;
4459
+ width: 115px;
4460
+ font-size: 14px;
4461
+ line-height: 190%;
4462
+ color: #ffffff;
4463
+ text-transform: uppercase;
4464
+ text-align: center;
4465
+ -webkit-transform: rotate(45deg);
4466
+ -moz-transform: rotate(45deg);
4467
+ -ms-transform: rotate(45deg);
4468
+ transform: rotate(45deg);
4469
+ white-space: nowrap;
4470
+ background-color: #1e88e5;
4471
+ -webkit-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
4472
+ -moz-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
4473
+ box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23); }
4474
+
4475
+ /*------------------------------------* #SECTION
4476
+
4477
+ Base:
4478
+ .c-section
4479
+
4480
+ \*------------------------------------*/
4481
+ .c-section {
4482
+ background-color: #ffffff;
4483
+ -webkit-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
4484
+ -moz-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
4485
+ box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
4486
+ -webkit-border-radius: 3px;
4487
+ -moz-border-radius: 3px;
4488
+ border-radius: 3px; }
4489
+
4490
+ /*------------------------------------* #SELECT
4491
+ Select2 plugin - https://select2.github.io/
4492
+
4493
+ Base:
4494
+ .select2-container
4495
+ .select2-selection
4496
+ .select2-selection__rendered
4497
+ .select2-selection__arrow
4498
+ .select2-selection__placeholder
4499
+ .select2-selection__clear
4500
+ .select2-selection__choice
4501
+ .select2-selection__choice__remove
4502
+
4503
+ .select2-dropdown
4504
+ .select2-search
4505
+ .select2-search__field
4506
+ .select2-results
4507
+ .select2-results__options
4508
+ .select2-results__option
4509
+ .select2-results__group
4510
+
4511
+ Type modifiers:
4512
+ .select2-container--default
4513
+
4514
+ .select2-selection--single
4515
+ .select2-selection--multiple
4516
+
4517
+ .select2-search--inline
4518
+ .select2-search--dropdown
4519
+
4520
+ State modifiers:
4521
+ .select2-container--focus
4522
+ .select2-container--disabled
4523
+ \*------------------------------------*/
4524
+ .select2-container {
4525
+ display: inline-block;
4526
+ position: relative;
4527
+ vertical-align: middle;
4528
+ font-size: 14px;
4529
+ border-bottom: 1px solid #dde4ea; }
4530
+
4531
+ .select2-container--focus .select2-selection--multiple {
4532
+ outline: 0; }
4533
+
4534
+ .select2-container--disabled .select2-selection--multiple {
4535
+ background-color: #dde4ea;
4536
+ cursor: default; }
4537
+
4538
+ .select2-container--disabled .select2-selection__choice__remove {
4539
+ display: none; }
4540
+
4541
+ .select2-container--open .select2-dropdown {
4542
+ left: 0; }
4543
+
4544
+ .select2-container--disabled .select2-selection--single {
4545
+ background-color: #dde4ea;
4546
+ cursor: default; }
4547
+ .select2-container--disabled .select2-selection--single .select2-selection__clear {
4548
+ display: none; }
4549
+
4550
+ .select2-container--default .select2-search--inline .select2-search__field {
4551
+ background: transparent;
4552
+ border: 0;
4553
+ outline: 0;
4554
+ -webkit-box-shadow: none;
4555
+ -moz-box-shadow: none;
4556
+ box-shadow: none;
4557
+ -webkit-appearance: textfield; }
4558
+
4559
+ .select2-container--default .select2-results > .select2-results__options {
4560
+ max-height: 250px;
4561
+ overflow-y: auto; }
4562
+
4563
+ .select2-container--default .select2-results__option[role=group] {
4564
+ padding: 0; }
4565
+
4566
+ .select2-container--default .select2-results__option[aria-disabled=true] {
4567
+ color: #dde4ea; }
4568
+
4569
+ .select2-container--default .select2-results__option[aria-selected=true] {
4570
+ color: #1e88e5; }
4571
+
4572
+ .select2-container--default .select2-results__option .select2-results__option {
4573
+ padding-left: 30px; }
4574
+
4575
+ .select2-container--default .select2-results__option--highlighted[aria-selected] {
4576
+ background-color: #f4f4f4; }
4577
+
4578
+ .select2-container--default .select2-results__group {
4579
+ cursor: default;
4580
+ padding: 10px 20px;
4581
+ display: block;
4582
+ white-space: nowrap;
4583
+ overflow: hidden;
4584
+ text-overflow: ellipsis;
4585
+ max-width: 100%; }
4586
+
4587
+ .select2-close-mask {
4588
+ border: 0;
4589
+ margin: 0;
4590
+ padding: 0;
4591
+ display: block;
4592
+ position: fixed;
4593
+ left: 0;
4594
+ top: 0;
4595
+ min-height: 100%;
4596
+ min-width: 100%;
4597
+ height: auto;
4598
+ width: auto;
4599
+ opacity: 0;
4600
+ z-index: 99; }
4601
+
4602
+ .select2-hidden-accessible {
4603
+ position: absolute;
4604
+ overflow: hidden;
4605
+ clip: rect(0 0 0 0);
4606
+ height: 1px;
4607
+ width: 1px;
4608
+ margin: -1px;
4609
+ padding: 0;
4610
+ border: 0; }
4611
+
4612
+ .select2-selection--single {
4613
+ cursor: pointer;
4614
+ display: block;
4615
+ -moz-user-select: none;
4616
+ -ms-user-select: none;
4617
+ user-select: none;
4618
+ -webkit-user-select: none;
4619
+ outline: 0; }
4620
+ .select2-selection--single .select2-selection__rendered {
4621
+ display: block;
4622
+ white-space: nowrap;
4623
+ overflow: hidden;
4624
+ text-overflow: ellipsis;
4625
+ max-width: 100%;
4626
+ line-height: 2.1; }
4627
+ .select2-selection--single .select2-selection__clear {
4628
+ position: relative;
4629
+ cursor: pointer;
4630
+ float: right;
4631
+ font-weight: 600; }
4632
+ .select2-selection--single .select2-selection__placeholder {
4633
+ color: #90a4ae; }
4634
+ .select2-selection--single .select2-selection__arrow {
4635
+ position: absolute;
4636
+ top: 0;
4637
+ right: 14px;
4638
+ height: 100%; }
4639
+ .select2-selection--single .select2-selection__arrow b {
4640
+ content: '';
4641
+ display: block;
4642
+ width: 0;
4643
+ height: 0;
4644
+ border-style: solid;
4645
+ border-width: 5px;
4646
+ border-left-color: transparent;
4647
+ border-right-color: transparent;
4648
+ border-bottom-color: transparent;
4649
+ border-top-color: #90a4ae;
4650
+ position: absolute;
4651
+ left: 50%;
4652
+ top: 50%; }
4653
+
4654
+ .select2-selection--multiple {
4655
+ cursor: pointer;
4656
+ display: block;
4657
+ -moz-user-select: none;
4658
+ -ms-user-select: none;
4659
+ user-select: none;
4660
+ -webkit-user-select: none; }
4661
+ .select2-selection--multiple .select2-selection__rendered {
4662
+ display: inline-block;
4663
+ white-space: nowrap;
4664
+ overflow: hidden;
4665
+ text-overflow: ellipsis;
4666
+ max-width: 100%; }
4667
+
4668
+ .select2-search--inline {
4669
+ float: left; }
4670
+ .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
4671
+ -webkit-appearance: none; }
4672
+
4673
+ .select2-dropdown {
4674
+ background-color: #ffffff;
4675
+ display: block;
4676
+ position: absolute;
4677
+ left: -100000px;
4678
+ width: 100%;
4679
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4680
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4681
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4682
+ z-index: 1000; }
4683
+
4684
+ .select2-results {
4685
+ display: block; }
4686
+
4687
+ .select2-results__options {
4688
+ list-style: none; }
4689
+
4690
+ .select2-results__option {
4691
+ padding: 10px 40px 10px 20px;
4692
+ -moz-user-select: none;
4693
+ -ms-user-select: none;
4694
+ user-select: none;
4695
+ -webkit-user-select: none;
4696
+ -webkit-transition: all 0.2s ease-in-out;
4697
+ -moz-transition: all 0.2s ease-in-out;
4698
+ transition: all 0.2s ease-in-out; }
4699
+ .select2-results__option[aria-selected] {
4700
+ cursor: pointer; }
4701
+
4702
+ .select2-search {
4703
+ position: relative;
4704
+ margin: 5px 20px 10px; }
4705
+ .select2-search::after, .select2-search::before {
4706
+ content: '';
4707
+ position: absolute;
4708
+ width: 0;
4709
+ height: 2px;
4710
+ bottom: 0;
4711
+ -webkit-transition: all 0.2s ease-in-out;
4712
+ -moz-transition: all 0.2s ease-in-out;
4713
+ transition: all 0.2s ease-in-out;
4714
+ background-color: #1e88e5; }
4715
+ .select2-search::after {
4716
+ right: 50%; }
4717
+ .select2-search::before {
4718
+ left: 50%; }
4719
+ .has-action .select2-search::after, .has-action .select2-search::before,
4720
+ .has-warning .select2-search::after,
4721
+ .has-warning .select2-search::before,
4722
+ .has-danger .select2-search::after,
4723
+ .has-danger .select2-search::before,
4724
+ .has-error .select2-search::after,
4725
+ .has-error .select2-search::before,
4726
+ .has-success .select2-search::after,
4727
+ .has-success .select2-search::before {
4728
+ width: 50%; }
4729
+ .has-success .select2-search::after, .has-success .select2-search::before {
4730
+ background-color: #4caf50; }
4731
+ .has-action .select2-search::after, .has-action .select2-search::before {
4732
+ background-color: #1e88e5; }
4733
+ .has-warning .select2-search::after, .has-warning .select2-search::before {
4734
+ background-color: #ffc107; }
4735
+ .has-danger .select2-search::after, .has-danger .select2-search::before {
4736
+ background-color: #f44336; }
4737
+ .select2-container--open .select2-search::after, .select2-container--open .select2-search::before {
4738
+ width: 50%; }
4739
+
4740
+ .select2-search--dropdown {
4741
+ display: block; }
4742
+ .select2-search--dropdown .select2-search__field {
4743
+ width: 100%;
4744
+ padding: 10px 0;
4745
+ font-size: 14px;
4746
+ outline: 0;
4747
+ border: 0;
4748
+ background: url("//storage.googleapis.com/instapage-app-assets/1471520975_icon-search.png") right center no-repeat; }
4749
+ .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
4750
+ -webkit-appearance: none; }
4751
+ .select2-search--dropdown.select2-search--hide {
4752
+ display: none; }
4753
+
4754
+ .select2-selection--multiple {
4755
+ background-color: #ffffff;
4756
+ cursor: text; }
4757
+ .select2-selection--multiple .select2-selection__rendered {
4758
+ list-style: none;
4759
+ width: 100%; }
4760
+ .select2-selection--multiple .select2-selection__rendered li {
4761
+ list-style: none; }
4762
+ .select2-selection--multiple .select2-selection__placeholder {
4763
+ color: #90a4ae;
4764
+ margin-top: 5px;
4765
+ float: left; }
4766
+ .select2-selection--multiple .select2-selection__clear {
4767
+ cursor: pointer;
4768
+ float: right;
4769
+ font-weight: 600;
4770
+ margin-top: 5px;
4771
+ margin-right: 10px; }
4772
+ .select2-selection--multiple .select2-selection__choice {
4773
+ cursor: default;
4774
+ float: left; }
4775
+ .select2-selection--multiple .select2-selection__choice__remove {
4776
+ cursor: pointer;
4777
+ display: inline-block;
4778
+ font-weight: 600; }
4779
+
4780
+ /*------------------------------------* #SNACKBAR
4781
+
4782
+ Base:
4783
+ .c-snack-bar
4784
+ .c-snack-bar__text
4785
+
4786
+ Color modifiers:
4787
+ .c-snack-bar__text--regular
4788
+ .c-snack-bar__text--danger
4789
+ .c-snack-bar__text--warning
4790
+ .c-snack-bar__text--success
4791
+
4792
+ State modifiers:
4793
+ .c-snack-bar.is-animated
4794
+ \*------------------------------------*/
4795
+ .c-snack-bar {
4796
+ position: fixed;
4797
+ bottom: -275px;
4798
+ left: 0;
4799
+ width: 100%;
4800
+ text-align: center;
4801
+ -webkit-transition: all 0.8s ease-in-out;
4802
+ -moz-transition: all 0.8s ease-in-out;
4803
+ transition: all 0.8s ease-in-out;
4804
+ pointer-events: none;
4805
+ z-index: 30000; }
4806
+ .c-snack-bar.is-animated {
4807
+ -webkit-transform: translateY(-295px);
4808
+ -moz-transform: translateY(-295px);
4809
+ -ms-transform: translateY(-295px);
4810
+ transform: translateY(-295px); }
4811
+
4812
+ .c-snack-bar__text {
4813
+ display: inline-block;
4814
+ color: #ffffff;
4815
+ padding: 15px 30px;
4816
+ max-width: 900px; }
4817
+
4818
+ .c-snack-bar__text--regular {
4819
+ background-color: #37475a; }
4820
+
4821
+ .c-snack-bar__text--danger {
4822
+ background-color: #f44336; }
4823
+
4824
+ .c-snack-bar__text--warning {
4825
+ background-color: #ffc107; }
4826
+
4827
+ .c-snack-bar__text--success {
4828
+ background-color: #4caf50; }
4829
+
4830
+ /*------------------------------------* #SWITCH
4831
+
4832
+ Base:
4833
+ .c-switch
4834
+ .c-switch__input
4835
+ .c-switch__text
4836
+ .c-switch__handle
4837
+ \*------------------------------------*/
4838
+ /*------------------------------------*.c-switch
4839
+ \*------------------------------------*/
4840
+ .c-switch {
4841
+ display: -webkit-inline-box;
4842
+ display: -webkit-inline-flex;
4843
+ display: -moz-inline-box;
4844
+ display: -ms-inline-flexbox;
4845
+ display: inline-flex;
4846
+ -webkit-box-align: center;
4847
+ -webkit-align-items: center;
4848
+ -moz-box-align: center;
4849
+ -ms-flex-align: center;
4850
+ align-items: center;
4851
+ -webkit-box-pack: start;
4852
+ -webkit-justify-content: flex-start;
4853
+ -moz-box-pack: start;
4854
+ -ms-flex-pack: start;
4855
+ justify-content: flex-start; }
4856
+
4857
+ /*------------------------------------*.c-switch__input
4858
+ \*------------------------------------*/
4859
+ .c-switch__input {
4860
+ position: absolute;
4861
+ overflow: hidden;
4862
+ clip: rect(0 0 0 0);
4863
+ height: 1px;
4864
+ width: 1px;
4865
+ margin: -1px;
4866
+ padding: 0;
4867
+ border: 0; }
4868
+
4869
+ /*------------------------------------*.c-switch__text
4870
+ \*------------------------------------*/
4871
+ .c-switch__text {
4872
+ color: #37475a;
4873
+ cursor: pointer; }
4874
+
4875
+ /*------------------------------------*.c-switch__handle
4876
+ \*------------------------------------*/
4877
+ .c-switch__handle {
4878
+ display: inline-block;
4879
+ position: relative;
4880
+ width: 36px;
4881
+ height: 14px;
4882
+ -webkit-border-radius: 14px;
4883
+ -moz-border-radius: 14px;
4884
+ border-radius: 14px;
4885
+ background-color: #dde4ea;
4886
+ cursor: pointer;
4887
+ outline: 0;
4888
+ -webkit-user-select: none;
4889
+ -moz-user-select: none;
4890
+ -ms-user-select: none;
4891
+ user-select: none;
4892
+ /*------------------------------------* .c-switch__handle::before (circle)
4893
+ \*------------------------------------*/ }
4894
+ .c-switch__input ~ .c-switch__handle::before {
4895
+ display: block;
4896
+ content: '';
4897
+ position: absolute;
4898
+ top: -3px;
4899
+ width: 20px;
4900
+ height: 20px;
4901
+ -webkit-border-radius: 50%;
4902
+ -moz-border-radius: 50%;
4903
+ border-radius: 50%;
4904
+ background-color: #ffffff;
4905
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4906
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4907
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4908
+ -webkit-transition: all 0.2s ease-in-out;
4909
+ -moz-transition: all 0.2s ease-in-out;
4910
+ transition: all 0.2s ease-in-out;
4911
+ -webkit-transform: translate(0, 0);
4912
+ -moz-transform: translate(0, 0);
4913
+ -ms-transform: translate(0, 0);
4914
+ transform: translate(0, 0); }
4915
+ .c-switch__input:checked ~ .c-switch__handle::before {
4916
+ background-color: #1e88e5;
4917
+ -webkit-transform: translate(16px, 0);
4918
+ -moz-transform: translate(16px, 0);
4919
+ -ms-transform: translate(16px, 0);
4920
+ transform: translate(16px, 0); }
4921
+ .c-switch__input:disabled ~ .c-switch__handle::before {
4922
+ background-color: #dde4ea; }
4923
+ .c-switch__input ~ .c-switch__handle:active::before {
4924
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24), 0 0 0 8px rgba(30, 136, 229, 0.2);
4925
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24), 0 0 0 8px rgba(30, 136, 229, 0.2);
4926
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24), 0 0 0 8px rgba(30, 136, 229, 0.2); }
4927
+
4928
+ /*------------------------------------*.c-switch__handle,
4929
+ .c-switch__text
4930
+ \*------------------------------------*/
4931
+ .c-switch__text ~ .c-switch__handle,
4932
+ .c-switch__handle ~ .c-switch__text {
4933
+ margin-left: 10px; }
4934
+
4935
+ .c-switch__input:disabled ~ .c-switch__handle,
4936
+ .c-switch__input:disabled ~ .c-switch__text {
4937
+ pointer-events: none; }
4938
+
4939
+ /*------------------------------------* #TABLE
4940
+
4941
+ Base:
4942
+ .c-table
4943
+ .c-table__caption
4944
+ .c-table__caption-row
4945
+ .c-table__caption-cell
4946
+ .c-table__head
4947
+ .c-table__body
4948
+ .c-table__footer
4949
+
4950
+ .c-table__cell
4951
+ \*------------------------------------*/
4952
+ .c-table {
4953
+ width: 100%;
4954
+ font-size: 14px;
4955
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4956
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4957
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4958
+ background-color: #ffffff;
4959
+ -webkit-border-radius: 3px;
4960
+ -moz-border-radius: 3px;
4961
+ border-radius: 3px; }
4962
+
4963
+ .c-table__caption {
4964
+ text-align: left;
4965
+ -webkit-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4966
+ -moz-box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4967
+ box-shadow: 0 0 2px rgba(13, 26, 43, 0.12), 0 1px 1px rgba(13, 26, 43, 0.24);
4968
+ -webkit-border-top-left-radius: 3px;
4969
+ -moz-border-radius-topleft: 3px;
4970
+ border-top-left-radius: 3px;
4971
+ -webkit-border-top-right-radius: 3px;
4972
+ -moz-border-radius-topright: 3px;
4973
+ border-top-right-radius: 3px;
4974
+ background-color: inherit;
4975
+ border-bottom: 1px solid #dde4ea;
4976
+ position: relative; }
4977
+ .c-table__caption::after {
4978
+ content: '';
4979
+ display: block;
4980
+ height: 2px;
4981
+ background-color: #ffffff;
4982
+ position: absolute;
4983
+ bottom: -3px;
4984
+ width: 100%; }
4985
+
4986
+ .c-table__caption-row {
4987
+ height: 100%;
4988
+ padding: 0 30px; }
4989
+
4990
+ .c-table__caption-title {
4991
+ font-size: 20px; }
4992
+
4993
+ .c-table__caption,
4994
+ .c-table__cell {
4995
+ height: 50px;
4996
+ vertical-align: middle; }
4997
+
4998
+ .c-table__head {
4999
+ color: #90a4ae;
5000
+ background-color: inherit; }
5001
+ .c-table__head .c-table__cell:first-child {
5002
+ -webkit-border-top-left-radius: 3px;
5003
+ -moz-border-radius-topleft: 3px;
5004
+ border-top-left-radius: 3px; }
5005
+ .c-table__head .c-table__cell:last-child {
5006
+ -webkit-border-top-right-radius: 3px;
5007
+ -moz-border-radius-topright: 3px;
5008
+ border-top-right-radius: 3px; }
5009
+ .c-table__caption + .c-table__head .c-table__cell:first-child {
5010
+ -webkit-border-top-left-radius: 0;
5011
+ -moz-border-radius-topleft: 0;
5012
+ border-top-left-radius: 0; }
5013
+ .c-table__caption + .c-table__head .c-table__cell:last-child {
5014
+ -webkit-border-top-right-radius: 0;
5015
+ -moz-border-radius-topright: 0;
5016
+ border-top-right-radius: 0; }
5017
+
5018
+ .c-table__footer {
5019
+ background-color: #f4f4f4; }
5020
+ .c-table__footer .c-table__cell {
5021
+ border-bottom: none; }
5022
+ .c-table__footer .c-table__cell:first-child {
5023
+ -webkit-border-bottom-left-radius: 3px;
5024
+ -moz-border-radius-bottomleft: 3px;
5025
+ border-bottom-left-radius: 3px; }
5026
+ .c-table__footer .c-table__cell:last-child {
5027
+ -webkit-border-bottom-right-radius: 3px;
5028
+ -moz-border-radius-bottomright: 3px;
5029
+ border-bottom-right-radius: 3px; }
5030
+
5031
+ .c-table__cell {
5032
+ text-align: center;
5033
+ padding: 0 15px;
5034
+ border-bottom: 1px solid #dde4ea; }
5035
+ .c-table__cell:first-child {
5036
+ padding-left: 30px; }
5037
+ .c-table__cell:last-child {
5038
+ padding-right: 30px; }
5039
+
5040
+ .c-table__cell--left {
5041
+ text-align: left; }
5042
+
5043
+ /*------------------------------------* #TABS
5044
+
5045
+ Base:
5046
+ .c-tabs
5047
+ .c-tabs__list
5048
+ .c-tab
5049
+ .c-tab__text
5050
+ .c-tabs__slider
5051
+
5052
+
5053
+ Display modifiers:
5054
+ .c-tabs--full-width
5055
+ .c-tabs--with-shadow
5056
+
5057
+ State modifiers for .c-tab:
5058
+ .is-active
5059
+ \*------------------------------------*/
5060
+ .c-tabs {
5061
+ position: relative; }
5062
+
5063
+ .c-tabs--with-shadow {
5064
+ -webkit-box-shadow: 0 3px 3px -1px rgba(13, 26, 43, 0.16), 0 5px 4px -4px rgba(13, 26, 43, 0.23);
5065
+ -moz-box-shadow: 0 3px 3px -1px rgba(13, 26, 43, 0.16), 0 5px 4px -4px rgba(13, 26, 43, 0.23);
5066
+ box-shadow: 0 3px 3px -1px rgba(13, 26, 43, 0.16), 0 5px 4px -4px rgba(13, 26, 43, 0.23); }
5067
+
5068
+ .c-tabs__list {
5069
+ display: -webkit-box;
5070
+ display: -webkit-flex;
5071
+ display: -moz-box;
5072
+ display: -ms-flexbox;
5073
+ display: flex;
5074
+ background-color: #ffffff; }
5075
+
5076
+ .c-tabs--full-width .c-tab {
5077
+ width: 0;
5078
+ -webkit-box-flex: 1;
5079
+ -webkit-flex: 1 1 auto;
5080
+ -moz-box-flex: 1;
5081
+ -ms-flex: 1 1 auto;
5082
+ flex: 1 1 auto; }
5083
+
5084
+ .c-tab__text {
5085
+ color: #90a4ae;
5086
+ font-size: 14px;
5087
+ text-align: center;
5088
+ text-decoration: none;
5089
+ line-height: 54px;
5090
+ padding-left: 20px;
5091
+ padding-right: 20px;
5092
+ -webkit-transition: all 0.2s ease-in-out;
5093
+ -moz-transition: all 0.2s ease-in-out;
5094
+ transition: all 0.2s ease-in-out;
5095
+ display: block;
5096
+ white-space: nowrap;
5097
+ overflow: hidden;
5098
+ text-overflow: ellipsis;
5099
+ max-width: 200px; }
5100
+ .c-tab__text:hover {
5101
+ color: #37475a;
5102
+ cursor: pointer;
5103
+ text-decoration: none; }
5104
+ .c-tab.is-active .c-tab__text {
5105
+ color: #1e88e5; }
5106
+ .c-tabs--full-width .c-tab__text {
5107
+ max-width: none; }
5108
+
5109
+ .c-tabs__slider {
5110
+ position: absolute;
5111
+ bottom: 0;
5112
+ height: 2px;
5113
+ background-color: #1e88e5;
5114
+ -webkit-transition: all 0.2s ease-in-out;
5115
+ -moz-transition: all 0.2s ease-in-out;
5116
+ transition: all 0.2s ease-in-out; }
5117
+
5118
+ /*------------------------------------* #TEXT LINE
5119
+
5120
+ Base:
5121
+ .c-text-line
5122
+
5123
+ Line side modifiers:
5124
+ .c-text-line--left
5125
+ .c-text-line--right
5126
+ \*------------------------------------*/
5127
+ .c-text-line {
5128
+ display: -webkit-box;
5129
+ display: -webkit-flex;
5130
+ display: -moz-box;
5131
+ display: -ms-flexbox;
5132
+ display: flex;
5133
+ -webkit-box-pack: center;
5134
+ -webkit-justify-content: center;
5135
+ -moz-box-pack: center;
5136
+ -ms-flex-pack: center;
5137
+ justify-content: center;
5138
+ -webkit-box-align: center;
5139
+ -webkit-align-items: center;
5140
+ -moz-box-align: center;
5141
+ -ms-flex-align: center;
5142
+ align-items: center; }
5143
+ .c-text-line::before, .c-text-line::after {
5144
+ height: 1px;
5145
+ display: block;
5146
+ background-color: #dde4ea;
5147
+ content: '';
5148
+ -webkit-box-flex: 1;
5149
+ -webkit-flex-grow: 1;
5150
+ -moz-box-flex: 1;
5151
+ -ms-flex-positive: 1;
5152
+ flex-grow: 1; }
5153
+ .c-text-line::before {
5154
+ margin-right: 5px; }
5155
+ .c-text-line::after {
5156
+ margin-left: 5px; }
5157
+
5158
+ .c-text-line--left::before {
5159
+ display: none; }
5160
+
5161
+ .c-text-line--right::after {
5162
+ display: none; }
5163
+
5164
+ /*------------------------------------* #TOGGLE
5165
+
5166
+ Base:
5167
+ .c-toggle
5168
+ .c-toggle__item
5169
+ .c-toggle__input - hidden from screen
5170
+ .c-toggle__content
5171
+
5172
+ State modifiers:
5173
+ .c-toggle__input:checked
5174
+ .c-toggle__input:disabled
5175
+
5176
+ \*------------------------------------*/
5177
+ /*------------------------------------* .c-toggle
5178
+ \*------------------------------------*/
5179
+ .c-toggle {
5180
+ display: -webkit-box;
5181
+ display: -webkit-flex;
5182
+ display: -moz-box;
5183
+ display: -ms-flexbox;
5184
+ display: flex;
5185
+ color: #90a4ae;
5186
+ font-size: 12px;
5187
+ text-transform: uppercase;
5188
+ -webkit-user-select: none;
5189
+ -moz-user-select: none;
5190
+ -ms-user-select: none;
5191
+ user-select: none; }
5192
+
5193
+ .c-toggle__input {
5194
+ position: absolute;
5195
+ overflow: hidden;
5196
+ clip: rect(0 0 0 0);
5197
+ height: 1px;
5198
+ width: 1px;
5199
+ margin: -1px;
5200
+ padding: 0;
5201
+ border: 0; }
5202
+
5203
+ .c-toggle__item {
5204
+ min-width: 0; }
5205
+
5206
+ .c-toggle__content {
5207
+ padding: 0 20px;
5208
+ display: inline-block;
5209
+ -webkit-transition: all 0.2s ease-in-out;
5210
+ -moz-transition: all 0.2s ease-in-out;
5211
+ transition: all 0.2s ease-in-out;
5212
+ border-top: #dde4ea 1px solid;
5213
+ border-bottom: #dde4ea 1px solid;
5214
+ line-height: 31px;
5215
+ text-align: center;
5216
+ display: block;
5217
+ white-space: nowrap;
5218
+ overflow: hidden;
5219
+ text-overflow: ellipsis;
5220
+ max-width: 100%; }
5221
+ @media screen and (max-width: 800px) {
5222
+ .c-toggle__content {
5223
+ -webkit-box-flex: 1;
5224
+ -webkit-flex: 1;
5225
+ -moz-box-flex: 1;
5226
+ -ms-flex: 1;
5227
+ flex: 1; } }
5228
+ .c-toggle__content:hover {
5229
+ background-color: #f4f4f4;
5230
+ color: #37475a;
5231
+ cursor: pointer; }
5232
+ .c-toggle__item:first-child .c-toggle__content {
5233
+ border-left: #dde4ea 1px solid;
5234
+ -webkit-border-top-left-radius: 3px;
5235
+ -moz-border-radius-topleft: 3px;
5236
+ border-top-left-radius: 3px;
5237
+ -webkit-border-bottom-left-radius: 3px;
5238
+ -moz-border-radius-bottomleft: 3px;
5239
+ border-bottom-left-radius: 3px; }
5240
+ .c-toggle__item:last-child .c-toggle__content {
5241
+ border-right: #dde4ea 1px solid;
5242
+ -webkit-border-top-right-radius: 3px;
5243
+ -moz-border-radius-topright: 3px;
5244
+ border-top-right-radius: 3px;
5245
+ -webkit-border-bottom-right-radius: 3px;
5246
+ -moz-border-radius-bottomright: 3px;
5247
+ border-bottom-right-radius: 3px; }
5248
+ .c-toggle__input:checked ~ .c-toggle__content {
5249
+ background-color: #1e88e5;
5250
+ border-color: #1e88e5;
5251
+ pointer-events: none;
5252
+ color: #ffffff; }
5253
+ .c-toggle__input:disabled ~ .c-toggle__content {
5254
+ pointer-events: none;
5255
+ color: #dde4ea; }
5256
+
5257
+ .c-toggle__icon {
5258
+ line-height: 31px;
5259
+ vertical-align: top;
5260
+ width: 18px; }
5261
+
5262
+ /*
5263
+ Tooltip
5264
+
5265
+ Base:
5266
+ .c-tooltip
5267
+
5268
+ Tooltip arrow modifiers:
5269
+ .c-tooltip--top
5270
+ .c-tooltip--bottom
5271
+ .c-tooltip--left
5272
+ .c-tooltip--right
5273
+
5274
+ State modifiers:
5275
+ .c-tooltip--show
5276
+ .c-tooltip--hide
5277
+ */
5278
+ /*------------------------------------* .c-tooltip
5279
+ \*------------------------------------*/
5280
+ .c-tooltip {
5281
+ display: inline-block;
5282
+ min-height: 26px;
5283
+ z-index: 60000;
5284
+ text-align: center;
5285
+ background-color: #37475a;
5286
+ font-size: 12px;
5287
+ line-height: 1.2;
5288
+ color: #ffffff;
5289
+ white-space: pre-wrap;
5290
+ word-wrap: break-word;
5291
+ position: absolute;
5292
+ padding: 5px 10px 6px;
5293
+ -webkit-border-radius: 3px;
5294
+ -moz-border-radius: 3px;
5295
+ border-radius: 3px;
5296
+ will-change: transform, opacity;
5297
+ max-width: 250px; }
5298
+ .c-tooltip::before {
5299
+ position: absolute;
5300
+ content: '';
5301
+ display: block;
5302
+ width: 0;
5303
+ height: 0;
5304
+ border-style: solid; }
5305
+
5306
+ /*------------------------------------* .c-tooltip--show animations
5307
+ \*------------------------------------*/
5308
+ @-webkit-keyframes show-tooltip {
5309
+ 0% {
5310
+ opacity: 0; }
5311
+ 80% {
5312
+ opacity: 1; }
5313
+ 100% {
5314
+ -webkit-transform: translate3d(0, 0, 0);
5315
+ transform: translate3d(0, 0, 0); } }
5316
+ @-moz-keyframes show-tooltip {
5317
+ 0% {
5318
+ opacity: 0; }
5319
+ 80% {
5320
+ opacity: 1; }
5321
+ 100% {
5322
+ -moz-transform: translate3d(0, 0, 0);
5323
+ transform: translate3d(0, 0, 0); } }
5324
+ @keyframes show-tooltip {
5325
+ 0% {
5326
+ opacity: 0; }
5327
+ 80% {
5328
+ opacity: 1; }
5329
+ 100% {
5330
+ -webkit-transform: translate3d(0, 0, 0);
5331
+ -moz-transform: translate3d(0, 0, 0);
5332
+ transform: translate3d(0, 0, 0); } }
5333
+
5334
+ @-webkit-keyframes show-tooltip-bottom {
5335
+ 0% {
5336
+ -webkit-transform: translate3d(0, -40%, 0);
5337
+ transform: translate3d(0, -40%, 0); } }
5338
+
5339
+ @-moz-keyframes show-tooltip-bottom {
5340
+ 0% {
5341
+ -moz-transform: translate3d(0, -40%, 0);
5342
+ transform: translate3d(0, -40%, 0); } }
5343
+
5344
+ @keyframes show-tooltip-bottom {
5345
+ 0% {
5346
+ -webkit-transform: translate3d(0, -40%, 0);
5347
+ -moz-transform: translate3d(0, -40%, 0);
5348
+ transform: translate3d(0, -40%, 0); } }
5349
+
5350
+ @-webkit-keyframes show-tooltip-top {
5351
+ 0% {
5352
+ -webkit-transform: translate3d(0, 40%, 0);
5353
+ transform: translate3d(0, 40%, 0); } }
5354
+
5355
+ @-moz-keyframes show-tooltip-top {
5356
+ 0% {
5357
+ -moz-transform: translate3d(0, 40%, 0);
5358
+ transform: translate3d(0, 40%, 0); } }
5359
+
5360
+ @keyframes show-tooltip-top {
5361
+ 0% {
5362
+ -webkit-transform: translate3d(0, 40%, 0);
5363
+ -moz-transform: translate3d(0, 40%, 0);
5364
+ transform: translate3d(0, 40%, 0); } }
5365
+
5366
+ @-webkit-keyframes show-tooltip-left {
5367
+ 0% {
5368
+ -webkit-transform: translate3d(30%, 0, 0);
5369
+ transform: translate3d(30%, 0, 0); } }
5370
+
5371
+ @-moz-keyframes show-tooltip-left {
5372
+ 0% {
5373
+ -moz-transform: translate3d(30%, 0, 0);
5374
+ transform: translate3d(30%, 0, 0); } }
5375
+
5376
+ @keyframes show-tooltip-left {
5377
+ 0% {
5378
+ -webkit-transform: translate3d(30%, 0, 0);
5379
+ -moz-transform: translate3d(30%, 0, 0);
5380
+ transform: translate3d(30%, 0, 0); } }
5381
+
5382
+ @-webkit-keyframes show-tooltip-right {
5383
+ 0% {
5384
+ -webkit-transform: translate3d(-30%, 0, 0);
5385
+ transform: translate3d(-30%, 0, 0); } }
5386
+
5387
+ @-moz-keyframes show-tooltip-right {
5388
+ 0% {
5389
+ -moz-transform: translate3d(-30%, 0, 0);
5390
+ transform: translate3d(-30%, 0, 0); } }
5391
+
5392
+ @keyframes show-tooltip-right {
5393
+ 0% {
5394
+ -webkit-transform: translate3d(-30%, 0, 0);
5395
+ -moz-transform: translate3d(-30%, 0, 0);
5396
+ transform: translate3d(-30%, 0, 0); } }
5397
+
5398
+ /*------------------------------------* .c-tooltip--hide animations
5399
+ \*------------------------------------*/
5400
+ @-webkit-keyframes hide-tooltip {
5401
+ 100% {
5402
+ opacity: 0; } }
5403
+ @-moz-keyframes hide-tooltip {
5404
+ 100% {
5405
+ opacity: 0; } }
5406
+ @keyframes hide-tooltip {
5407
+ 100% {
5408
+ opacity: 0; } }
5409
+
5410
+ @-webkit-keyframes hide-tooltip-bottom {
5411
+ 100% {
5412
+ -webkit-transform: translate3d(0, -40%, 0);
5413
+ transform: translate3d(0, -40%, 0); } }
5414
+
5415
+ @-moz-keyframes hide-tooltip-bottom {
5416
+ 100% {
5417
+ -moz-transform: translate3d(0, -40%, 0);
5418
+ transform: translate3d(0, -40%, 0); } }
5419
+
5420
+ @keyframes hide-tooltip-bottom {
5421
+ 100% {
5422
+ -webkit-transform: translate3d(0, -40%, 0);
5423
+ -moz-transform: translate3d(0, -40%, 0);
5424
+ transform: translate3d(0, -40%, 0); } }
5425
+
5426
+ @-webkit-keyframes hide-tooltip-top {
5427
+ 100% {
5428
+ -webkit-transform: translate3d(0, 40%, 0);
5429
+ transform: translate3d(0, 40%, 0); } }
5430
+
5431
+ @-moz-keyframes hide-tooltip-top {
5432
+ 100% {
5433
+ -moz-transform: translate3d(0, 40%, 0);
5434
+ transform: translate3d(0, 40%, 0); } }
5435
+
5436
+ @keyframes hide-tooltip-top {
5437
+ 100% {
5438
+ -webkit-transform: translate3d(0, 40%, 0);
5439
+ -moz-transform: translate3d(0, 40%, 0);
5440
+ transform: translate3d(0, 40%, 0); } }
5441
+
5442
+ @-webkit-keyframes hide-tooltip-left {
5443
+ 100% {
5444
+ -webkit-transform: translate3d(30%, 0, 0);
5445
+ transform: translate3d(30%, 0, 0); } }
5446
+
5447
+ @-moz-keyframes hide-tooltip-left {
5448
+ 100% {
5449
+ -moz-transform: translate3d(30%, 0, 0);
5450
+ transform: translate3d(30%, 0, 0); } }
5451
+
5452
+ @keyframes hide-tooltip-left {
5453
+ 100% {
5454
+ -webkit-transform: translate3d(30%, 0, 0);
5455
+ -moz-transform: translate3d(30%, 0, 0);
5456
+ transform: translate3d(30%, 0, 0); } }
5457
+
5458
+ @-webkit-keyframes hide-tooltip-right {
5459
+ 100% {
5460
+ -webkit-transform: translate3d(-30%, 0, 0);
5461
+ transform: translate3d(-30%, 0, 0); } }
5462
+
5463
+ @-moz-keyframes hide-tooltip-right {
5464
+ 100% {
5465
+ -moz-transform: translate3d(-30%, 0, 0);
5466
+ transform: translate3d(-30%, 0, 0); } }
5467
+
5468
+ @keyframes hide-tooltip-right {
5469
+ 100% {
5470
+ -webkit-transform: translate3d(-30%, 0, 0);
5471
+ -moz-transform: translate3d(-30%, 0, 0);
5472
+ transform: translate3d(-30%, 0, 0); } }
5473
+
5474
+ /*------------------------------------* .c-tooltip--show,
5475
+ .c-tooltip--hide
5476
+ \*------------------------------------*/
5477
+ .c-tooltip--show,
5478
+ .c-tooltip--hide {
5479
+ -webkit-animation-timing-function: cubic-bezier(0.05, 0.45, 0.34, 0.94);
5480
+ -moz-animation-timing-function: cubic-bezier(0.05, 0.45, 0.34, 0.94);
5481
+ animation-timing-function: cubic-bezier(0.05, 0.45, 0.34, 0.94);
5482
+ -webkit-animation-fill-mode: forwards;
5483
+ -moz-animation-fill-mode: forwards;
5484
+ animation-fill-mode: forwards; }
5485
+
5486
+ .c-tooltip--show {
5487
+ -webkit-animation-duration: .15s;
5488
+ -moz-animation-duration: .15s;
5489
+ animation-duration: .15s; }
5490
+ .c-tooltip--show.c-tooltip--bottom {
5491
+ -webkit-animation-name: show-tooltip, show-tooltip-bottom;
5492
+ -moz-animation-name: show-tooltip, show-tooltip-bottom;
5493
+ animation-name: show-tooltip, show-tooltip-bottom; }
5494
+ .c-tooltip--show.c-tooltip--top {
5495
+ -webkit-animation-name: show-tooltip, show-tooltip-top;
5496
+ -moz-animation-name: show-tooltip, show-tooltip-top;
5497
+ animation-name: show-tooltip, show-tooltip-top; }
5498
+ .c-tooltip--show.c-tooltip--left {
5499
+ -webkit-animation-name: show-tooltip, show-tooltip-left;
5500
+ -moz-animation-name: show-tooltip, show-tooltip-left;
5501
+ animation-name: show-tooltip, show-tooltip-left; }
5502
+ .c-tooltip--show.c-tooltip--right {
5503
+ -webkit-animation-name: show-tooltip, show-tooltip-right;
5504
+ -moz-animation-name: show-tooltip, show-tooltip-right;
5505
+ animation-name: show-tooltip, show-tooltip-right; }
5506
+
5507
+ .c-tooltip--hide {
5508
+ -webkit-animation-duration: .2s;
5509
+ -moz-animation-duration: .2s;
5510
+ animation-duration: .2s; }
5511
+ .c-tooltip--hide.c-tooltip--bottom {
5512
+ -webkit-animation-name: hide-tooltip, hide-tooltip-bottom;
5513
+ -moz-animation-name: hide-tooltip, hide-tooltip-bottom;
5514
+ animation-name: hide-tooltip, hide-tooltip-bottom; }
5515
+ .c-tooltip--hide.c-tooltip--top {
5516
+ -webkit-animation-name: hide-tooltip, hide-tooltip-top;
5517
+ -moz-animation-name: hide-tooltip, hide-tooltip-top;
5518
+ animation-name: hide-tooltip, hide-tooltip-top; }
5519
+ .c-tooltip--hide.c-tooltip--left {
5520
+ -webkit-animation-name: hide-tooltip, hide-tooltip-left;
5521
+ -moz-animation-name: hide-tooltip, hide-tooltip-left;
5522
+ animation-name: hide-tooltip, hide-tooltip-left; }
5523
+ .c-tooltip--hide.c-tooltip--right {
5524
+ -webkit-animation-name: hide-tooltip, hide-tooltip-right;
5525
+ -moz-animation-name: hide-tooltip, hide-tooltip-right;
5526
+ animation-name: hide-tooltip, hide-tooltip-right; }
5527
+
5528
+ /*------------------------------------* .c-tooltip--top,
5529
+ .c-tooltip--bottom
5530
+ \*------------------------------------*/
5531
+ .c-tooltip--top::before,
5532
+ .c-tooltip--bottom::before {
5533
+ left: 50%;
5534
+ margin-left: -5px; }
5535
+
5536
+ .c-tooltip--top::before {
5537
+ bottom: -5px;
5538
+ border-width: 5px 5px 0 5px;
5539
+ border-color: #37475a transparent transparent transparent; }
5540
+
5541
+ .c-tooltip--bottom::before {
5542
+ top: -5px;
5543
+ border-width: 0 5px 5px 5px;
5544
+ border-color: transparent transparent #37475a transparent; }
5545
+
5546
+ /*------------------------------------* .c-tooltip--right,
5547
+ .c-tooltip--left
5548
+ \*------------------------------------*/
5549
+ .c-tooltip--right::before,
5550
+ .c-tooltip--left::before {
5551
+ top: 50%;
5552
+ margin-top: -5px; }
5553
+
5554
+ .c-tooltip--right::before {
5555
+ left: -5px;
5556
+ border-width: 5px 5px 5px 0;
5557
+ border-color: transparent #37475a transparent transparent; }
5558
+
5559
+ .c-tooltip--left::before {
5560
+ right: -5px;
5561
+ border-width: 5px 0 5px 5px;
5562
+ border-color: transparent transparent transparent #37475a; }
5563
+
5564
+ body {
5565
+ background-color: #f4f4f4; }
5566
+
5567
+ .header {
5568
+ -webkit-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
5569
+ -moz-box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
5570
+ box-shadow: 0 2px 3px rgba(13, 26, 43, 0.16), 0 1px 4px rgba(13, 26, 43, 0.23);
5571
+ background-color: #ffffff; }
5572
+
5573
+ .header__top {
5574
+ min-height: 65px; }
5575
+
5576
+ .header__logo {
5577
+ display: block;
5578
+ width: 130px;
5579
+ height: 26px; }
5580
+
5581
+ .footer {
5582
+ font-size: 14px;
5583
+ margin-top: 60px;
5584
+ margin-bottom: 60px; }
5585
+
5586
+ .u-ellipsis {
5587
+ display: block;
5588
+ white-space: nowrap;
5589
+ overflow: hidden;
5590
+ text-overflow: ellipsis;
5591
+ max-width: 100%; }
5592
+
5593
+ /*------------------------------------* #FONT SIZE
5594
+ \*------------------------------------*/
5595
+ .u-text--small {
5596
+ font-size: 14px !important; }
5597
+
5598
+ .u-text--x-small {
5599
+ font-size: 12px !important; }
5600
+
5601
+ /*------------------------------------* #FONT COLOR
5602
+ \*------------------------------------*/
5603
+ .u-text--danger {
5604
+ color: #f44336 !important; }
5605
+
5606
+ .u-text--warning {
5607
+ color: #ffc107 !important; }
5608
+
5609
+ .u-text--success {
5610
+ color: #4caf50 !important; }
5611
+
5612
+ .u-text--action {
5613
+ color: #1e88e5 !important; }
5614
+
5615
+ .u-text--inactive {
5616
+ color: #90a4ae !important; }
5617
+
5618
+ .u-text--less-important {
5619
+ color: #a6b6be !important; }
5620
+
5621
+ .u-text--facebook {
5622
+ color: #3a6ace !important; }
5623
+
5624
+ .u-text--wordpress {
5625
+ color: #00bcd4 !important; }
5626
+
5627
+ .u-text--drupal {
5628
+ color: #02b2ec !important; }
5629
+
5630
+ /*------------------------------------* #TEXT TRANSFORM
5631
+ \*------------------------------------*/
5632
+ .u-text--upper {
5633
+ text-transform: uppercase !important; }
5634
+
5635
+ .u-text--center {
5636
+ text-align: center !important; }
5637
+
5638
+ .u-text--right {
5639
+ text-align: right !important; }
5640
+
5641
+ /*------------------------------------* #ICON
5642
+ \*------------------------------------*/
5643
+ .u-icon--large {
5644
+ font-size: 24px !important; }
5645
+
5646
+ /*------------------------------------* #POSITION
5647
+ \*------------------------------------*/
5648
+ .u-relative {
5649
+ position: relative !important; }
5650
+
5651
+ /*------------------------------------*#SPACE
5652
+ \*------------------------------------*/
5653
+ .u-space-top-none {
5654
+ padding-top: 0 !important; }
5655
+
5656
+ .u-space-right-none {
5657
+ padding-right: 0 !important; }
5658
+
5659
+ .u-space-bottom-none {
5660
+ padding-bottom: 0 !important; }
5661
+
5662
+ .u-space-left-none {
5663
+ padding-left: 0 !important; }
5664
+
5665
+ /*------------------------------------* #DISPLAY
5666
+ \*------------------------------------*/
5667
+ .u-hidden {
5668
+ display: none !important; }
5669
+
5670
+ /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1yd2hpdGUvc2V0dGluZ3MvX3ZhcmlhYmxlcy5zY3NzIiwibXJ3aGl0ZS90b29scy9taXhpbnMvX2VsZW1lbnRfc3RhdGVzLnNjc3MiLCJtcndoaXRlL3Rvb2xzL21peGlucy9fcmFkaXVzLnNjc3MiLCJtcndoaXRlL3Rvb2xzL21peGlucy9fc2hhZG93LnNjc3MiLCJtcndoaXRlL3Rvb2xzL21peGlucy9fdmlzdWFsbHlfaGlkZGVuLnNjc3MiLCJtcndoaXRlL2dlbmVyaWMvX3Jlc2V0LnNjc3MiLCJtcndoaXRlL2dlbmVyaWMvX2dsb2JhbC5zY3NzIiwibXJ3aGl0ZS9nZW5lcmljL19mb250cy5zY3NzIiwibXJ3aGl0ZS9iYXNlL190eXBvZ3JhcGh5LnNjc3MiLCJtcndoaXRlL2xheW91dC9fZ3JpZC5zY3NzIiwibXJ3aGl0ZS9sYXlvdXQvX2dyb3VwLnNjc3MiLCJtcndoaXRlL2xheW91dC9fb3ZlcmxheS5zY3NzIiwibXJ3aGl0ZS9sYXlvdXQvX3NwYWNlLnNjc3MiLCJtcndoaXRlL2xheW91dC9fd3JhcHBlci5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL19iYWRnZS5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL19idXR0b24uc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9fY29sbGVjdGlvbi5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL19kcm9wZG93bi5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL19lZmZlY3Quc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9fZXhwYW5kYWJsZS1pdGVtLnNjc3MiLCJtcndoaXRlL2NvbXBvbmVudHMvX2lsbHVzdHJhdGlvbnMuc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9faW5wdXQuc2NzcyIsIm1yd2hpdGUvdG9vbHMvbWl4aW5zL19mb3JtX2l0ZW1fdW5kZXJsaW5lX2VmZmVjdC5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL19saXN0LnNjc3MiLCJtcndoaXRlL2NvbXBvbmVudHMvX2xvYWRlci5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL19tYXJrLnNjc3MiLCJtcndoaXRlL2NvbXBvbmVudHMvX21vZGFsLnNjc3MiLCJtcndoaXRlL3Rvb2xzL21peGlucy9fdHJpYW5nbGUuc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9fbm90aWZpY2F0aW9uLnNjc3MiLCJtcndoaXRlL2NvbXBvbmVudHMvX3BhZ2luYXRpb24uc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9fcmliYm9uLnNjc3MiLCJtcndoaXRlL2NvbXBvbmVudHMvX3NlY3Rpb24uc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9fc2VsZWN0LnNjc3MiLCJtcndoaXRlL3Rvb2xzL21peGlucy9fZWxsaXBzaXMuc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9fc25hY2stYmFyLnNjc3MiLCJtcndoaXRlL2NvbXBvbmVudHMvX3N3aXRjaC5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL190YWJsZS5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL190YWJzLnNjc3MiLCJtcndoaXRlL2NvbXBvbmVudHMvX3RleHRfbGluZS5zY3NzIiwibXJ3aGl0ZS9jb21wb25lbnRzL190b2dnbGUuc2NzcyIsIm1yd2hpdGUvY29tcG9uZW50cy9fdG9vbHRpcC5zY3NzIiwiYXBwcy9kYXNoYm9hcmQvX2dsb2JhbC5zY3NzIiwiYXBwcy9kYXNoYm9hcmQvX2hlYWRlci5zY3NzIiwiYXBwcy9kYXNoYm9hcmQvX2Zvb3Rlci5zY3NzIiwibXJ3aGl0ZS90cnVtcHMvX2hlbHBlcnMuc2NzcyIsIm1yd2hpdGUvdHJ1bXBzL191dGlsaXR5LnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7d0NBRXdDO0FBbUN4Qzt3Q0FFd0M7QUE0Q3hDO3dDQUV3QztBQWlCeEM7d0NBRXdDO0FBU3hDO3dDQUV3QztBQTZDeEM7d0NBRXdDO0FBS3hDO3dDQUV3QztBQU14Qzt3Q0FFd0M7QUFheEM7d0NBRXdDO0FDaE14Qzs7RUFFRTtBQ1dGOzs7Ozs7Ozs7Ozs7OztFQWNF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TUkscUJBWm9CO0lBYXBCLG9CQWJvQjtJQWFwQiw0QkFib0I7SUFhcEIsaUJBYm9CO0lBYXBCLHdCQWJvQjtJQWFwQixvQkFib0IsRUFldkI7RUFURDtJQU1JLHFCQVpvQjtJQWFwQixvQkFib0I7SUFhcEIsNEJBYm9CO0lBYXBCLGlCQWJvQjtJQWFwQix3QkFib0I7SUFhcEIsb0JBYm9CLEVBZXZCO0VBVEQ7SUFNSSxxQkFab0I7SUFhcEIsb0JBYm9CO0lBYXBCLDRCQWJvQjtJQWFwQixpQkFib0I7SUFhcEIsd0JBYm9CO0lBYXBCLG9CQWJvQixFQWV2QjtFQVREO0lBTUkscUJBWm9CO0lBYXBCLG9CQWJvQjtJQWFwQiw0QkFib0I7SUFhcEIsaUJBYm9CO0lBYXBCLHdCQWJvQjtJQWFwQixvQkFib0IsRUFldkI7RUFURDtJQU1JLHFCQVpvQjtJQWFwQixvQkFib0I7SUFhcEIsNEJBYm9CO0lBYXBCLGlCQWJvQjtJQWFwQix3QkFib0I7SUFhcEIsb0JBYm9CLEVBZXZCO0VBVEQ7SUFNSSxxQkFab0I7SUFhcEIsb0JBYm9CO0lBYXBCLDRCQWJvQjtJQWFwQixpQkFib0I7SUFhcEIsd0JBYm9CO0lBYXBCLG9CQWJvQixFQWV2QjtFQVREO0lBTUkscUJBWm9CO0lBYXBCLG9CQWJvQjtJQWFwQiw0QkFib0I7SUFhcEIsaUJBYm9CO0lBYXBCLHdCQWJvQjtJQWFwQixvQkFib0IsRUFldkI7RUFURDtJQU1JLHFCQVpvQjtJQWFwQixvQkFib0I7SUFhcEIsNEJBYm9CO0lBYXBCLGlCQWJvQjtJQWFwQix3QkFib0I7SUFhcEIsb0JBYm9CLEVBZXZCO0VBVEQ7SUFNSSxxQkFab0I7SUFhcEIsb0JBYm9CO0lBYXBCLDRCQWJvQjtJQWFwQixpQkFib0I7SUFhcEIsd0JBYm9CO0lBYXBCLG9CQWJvQixFQWV2QjtFQVREO0lBTUkscUJBWm9CO0lBYXBCLG9CQWJvQjtJQWFwQiw0QkFib0I7SUFhcEIsaUJBYm9CO0lBYXBCLHdCQWJvQjtJQWFwQixvQkFib0IsRUFldkI7RUFURDtJQU1JLHFCQVpvQjtJQWFwQixvQkFi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RUFDRSxjWnVEMEIsRVl0RDNCOztBQUVEO0VBQ0UsY1pvRDRCLEVZbkQ3Qjs7QUFJRDt3Q0FFd0M7QUFFeEM7RUFDRSxrQlp1Q3lCO0VZdEN6QixxQlpzQ3lCLEVZckMxQjs7QUFFRDtFQUNFLGtCWm1DMkI7RVlsQzNCLHFCWmtDMkIsRVlqQzVCOztBQUVEO0VBQ0Usa0JaK0IwQjtFWTlCMUIscUJaOEIwQixFWTdCM0I7O0FBRUQ7RUFDRSxrQloyQjRCO0VZMUI1QixxQlowQjRCLEVZekI3Qjs7QUFHRDt3Q0FFd0M7QUFFeEM7RUFDRSxtQlpjeUI7RVliekIsb0JaYXlCLEVZWjFCOztBQUVEO0VBQ0UsbUJaVTJCO0VZVDNCLG9CWlMyQixFWVI1Qjs7QUFFRDtFQUNFLG1CWk0wQjtFWUwxQixvQlpLMEIsRVlKM0I7O0FBRUQ7RUFDRSxtQlpFNEI7RVlENUIsb0JaQzRCLEVZQTdCOztBQUdEO3dDQUV3QztBQUV4QztFQUNFLGtCWlh5QixFWVkxQjs7QUFFRDtFQUNFLGtCWmQyQixFWWU1Qjs7QUFFRDtFQUNFLGtCWmpCMEIsRVlrQjNCOztBQUVEO0VBQ0Usa0JacEI0QixFWXFCN0I7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0Usb0JaaEN5QixFWWlDMUI7O0FBRUQ7RUFDRSxvQlpuQzJCLEVZb0M1Qjs7QUFFRDtFQUNFLG9CWnRDMEIsRVl1QzNCOztBQUVEO0VBQ0Usb0JaekM0QixFWTBDN0I7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0UscUJackR5QixFWXNEMUI7O0FBRUQ7RUFDRSxxQlp4RDJCLEVZeUQ1Qjs7QUFFRDtFQUNFLHFCWjNEMEIsRVk0RDNCOztBQUVEO0VBQ0UscUJaOUQ0QixFWStEN0I7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0UsbUJaMUV5QixFWTJFMUI7O0FBRUQ7RUFDRSxtQlo3RTJCLEVZOEU1Qjs7QUFFRDtFQUNFLG1CWmhGMEIsRVlpRjNCOztBQUVEO0VBQ0UsbUJabkY0QixFWW9GN0I7O0FDak1EOzs7O3dDQUt3QztBQUd4QztFQUNFLGVBQWUsRUFPaEI7RUpzSUc7SUk5SUo7TUFL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MEJmaGV3QixFZWllekI7O0FBR0g7RUFDRSwwQmZuZXVCO0Vlb2V2QixlZmhnQnFCLEVlc2dCdEI7RUFSRDtJQU1JLDBCZnZlMkIsRWV3ZTVCOztBQ3hqQkg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O3dDQTJCd0M7QUFPeEM7d0NBRXdDO0FBRXhDO0VBRUUsZ0JoQm9Ed0IsRWdCbkR6Qjs7QUFFRDtFQUNFLG9CQUFvQixFQUtyQjtFQUhtQjtJQUNoQixpQkFBaUIsRUFDbEI7O0FBR0g7RUFDRSxxRmhCWW9CO0VnQlpwQixrRmhCWW9CO0VnQlpwQiw2RWhCWW9CO0VnQlhwQiwyQmhCK0d5QjtFZ0IvR3pCLHdCaEIrR3lCO0VnQi9HekIsbUJoQitHeUI7RWdCOUd6QixvQkFBb0IsRUFDckI7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0UseUNoQjRHc0M7RWdCNUd0QyxzQ2hCNEdzQztFZ0I1R3RDLGlDaEI0R3NDO0VnQjNHdEMsMEJoQmJxQixFZ0IrRHRCO0VBcEREO0lBS0ksMEJoQmxCb0IsRWdCbUJyQjtFQU5IO0lBU0ksdUZoQlBrQjtJZ0JPbEIsb0ZoQlBrQjtJZ0JPbEIsK0VoQlBrQjtJZ0JRbEIsbUJBQW1CO0lBQ25CLGFBQWEsRUFNZDtJQWpCSDtNQWNNLGlCQUFpQixFQUNsQjtFQWZMO0lBb0JJLDhCQUE4QjtJQUM5QixlaEJyQ21CO0lnQnNDbkIsOEJBQThCLEVBQy9CO0VBdkJIO0lBMEJJLDhCaEJ2Q29CLEVnQjZDckI7SUFKQztNQUNFLGlCQUFpQixFQUNsQjtFQTlCTDtJQW1DSSxpQ2hCaERvQixFZ0JpRHJCO0VBRW1CO0lBQ2xCLGlCQUFpQixFQUNsQjtFQXhDSDtJQTJDSSxvQ2hCMkR1QjtJZ0IzRHZCLGdDaEIyRHVCO0lnQjNEdkIsNEJoQjJEdUI7SWdCMUR2QixxQ2hCMER1QjtJZ0IxRHZCLGlDaEIwRHVCO0lnQjFEdkIsNkJoQjBEdUIsRWdCekR4QjtFQTdDSDtJQWdESSx1Q2hCc0R1QjtJZ0J0RHZCLG1DaEJzRHVCO0lnQnREdkIsK0JoQnNEdUI7SWdCckR2Qix3Q2hCcUR1QjtJZ0JyRHZCLG9DaEJxRHVCO0lnQnJEdkIsZ0NoQnFEdUIsRWdCcER4Qjs7QUFJSDtFQUNFLGVoQnZFcUI7RWdCd0VyQixnQmhCMUJ3QjtFZ0IyQnhCLGlCQUFpQixFQUNsQjs7QUFFRDtFQUNFLDhCQUE4QixFQUMvQjs7QUFHRDt3Q0FFd0M7QUFDeEM7RUFDRSxhQXRHb0M7RUF1R3BDLG1CaEJ2QjRCO0VnQndCNUIsb0JoQnhCNEI7RWdCeUI1QixxQkFBYztFQUFkLHNCQUFjO0VBQWQsa0JBQWM7RUFBZCxxQkFBYztFQUFkLGNBQWM7RUFDZCwwQkFBb0I7RUFBcEIsNEJBQW9CO0VBQXBCLHVCQUFvQjtFQUFwQix1QkFBb0I7RUFBcEIsb0JBQW9CLEVBY3JCO0VBWkM7SUFDRSxhQTVHb0MsRUE2R3JDO0VBVEg7SUFZSSxhQS9HbUMsRUFnSHBDO0VBYkg7SUFnQkksb0JBQWE7SUFBYixxQkFBYTtJQUFiLGlCQUFhO0lBQWIscUJBQWE7SUFBYixhQUFhLEVBQ2Q7O0FDbkpIOzs7Ozs7Ozs7Ozs7d0NBYXdDO0FBRXhDO0VBQ0UsbUJBQW1CLEVBQ3BCOztBQUVEO0VBQ0Usb0JBQW9CO0VBQ3BCLGNBQWM7RUFDZCwwQmpCNkJxQjtFaUI1QnJCLHFGakJ5Q29CO0VpQnpDcEIsa0ZqQnlDb0I7RWlCekNwQiw2RWpCeUNvQjtFaUJ4Q3BCLDJCakI0SXlCO0VpQjVJekIsd0JqQjRJeUI7RWlCNUl6QixtQmpCNEl5QjtFaUIzSXpCLG1CQUFtQjtFQUNuQixjakI0SmM7RWlCM0pkLE9BQU8sRUFXUjtFQVRDO0lBQ0UsZUFBZTtJQUNmLDhCQUFzQjtJQUF0QiwyQkFBc0I7SUFBdEIsc0JBQXNCLEVBQ3ZCO0VBYkg7SUFnQkksU0FBUyxFQUNWOztBQ3BDSDt3Q0FFd0M7QUFFeEM7RUFDRTtJQUNFLFdBQVc7SUFDWCw4QkFBZ0I7SUFBaEIsc0JBQWdCLEVBQUEsRUFBQTtBQUhwQjtFQUNFO0lBQ0UsV0FBVztJQUNYLDJCQUFnQjtJQUFoQixzQkFBZ0IsRUFBQSxFQUFBO0FBSHBCO0VBQ0U7SUFDRSxXQUFXO0lBQ1gsOEJBQWdCO0lBQWhCLDJCQUFnQjtJQUFoQixzQkFBZ0IsRUFBQSxFQUFBOztBQUlwQjtFQUNFLG1CQUFtQjtFQUNuQixpQkFBaUI7RUFDakIsd0NBQXNCO0VBQXRCLHFDQUFzQjtFQUF0QixnQ0FBc0IsRUFDdkI7O0FBRUQ7RUFDRSxlQUFlO0VBQ2YsbUJBQW1CO0VBQ25CLHFCQUFxQjtFQUNyQiwyQkFBbUI7RUFBbkIsd0JBQW1CO0VBQW5CLG1CQUFtQjtFQUNuQiw0QkFBZ0I7RUFBaEIseUJBQWdCO0VBQWhCLHdCQUFnQjtFQUFoQixvQkFBZ0I7RUFDaEIseUNsQnFCbUI7RWtCcEJuQixXQUFXLEVBS1o7RUFaRDtJQVVNLHFDQUE2QjtJQUE3QixrQ0FBNkI7SUFBN0IsNkJBQTZCLEVBQzlCOztBQUlMO3dDQUV3QztBQUV4QztFQUNFO0lBQ0UsV0FBVyxFQUFBO0VBR2I7SUFDRSxXQUFXLEVBQUEsRUFBQTtBQU5mO0VBQ0U7SUFDRSxXQUFXLEVBQUE7RUFHYjtJQUNFLFdBQVcsRUFBQSxFQUFBO0FBTmY7RUFDRTtJQUNFLFdBQVcsRUFBQTtFQUdiO0lBQ0UsV0FBVyxFQUFBLEVBQUE7O0FBS2Y7d0NBRXdDO0FBRXhDO0VBQ0Usd0NsQlJtQixFa0JTcEI7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0UsMEJBQVk7RUFBWixrQkFBWSxFQUNiOztBQzlERDs7Ozs7Ozs7Ozs7d0NBWXdDO0FBRXhDO0VBQ0UsZ0JBQWdCLEVBQ2pCOztBQUVEO0VBQ0UseUNuQndKc0M7RW1CeEp0QyxzQ25Cd0pzQztFbUJ4SnRDLGlDbkJ3SnNDLEVtQmxKdkM7RUFKQztJQUNFLG1DQUFpQjtJQUFqQixnQ0FBaUI7SUFBakIsK0JBQWlCO0lBQWpCLDJCQUFpQixFQUNsQjs7QUFJSDtFQUNFLFVBQVU7RUFDVixpQkFBaUI7RUFDakIseUNuQjZJc0M7RW1CN0l0QyxzQ25CNklzQztFbUI3SXRDLGlDbkI2SXNDLEVtQjVJdkM7O0FDL0JEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O3dDQXVCd0M7QUFReEM7RUFDRSwyQkFBbUI7RUFBbkIsd0JBQW1CO0VBQW5CLG1CQUFtQjtFQUNuQixZQVJ1QjtFQVN2QixhQVR1QjtFQVV2QixzQkFBc0I7RUFDdEIsNEJBQXVCO0VBQXZCLHVCQUF1QjtFQUN2Qiw2QkFBNkI7RUFDN0IsNEJBQTRCLEVBUzdCO0VBaEJEO0lBV0ksVUFBVTtJQUNWLHlCQUFpQjtJQUFqQixzQkFBaUI7SUFBakIsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixnQkFBZ0IsRUFDakI7O0FBR0g7RUFDRSwwQnBCRHNCLEVvQkV2Qjs7QUFFRDtFQUNFLFlBNUI2QjtFQTZCN0IsYUE3QjZCLEVBOEI5Qjs7QUFFRDtFQUNFLGFBaENnQztFQWlDaEMsY0FqQ2dDLEVBa0NqQzs7QUFHRDs7d0NBR3dDO0FBRXhDO0VBQ0UscUJBQWM7RUFBZCxzQkFBYztFQUFkLGtCQUFjO0VBQWQscUJBQWM7RUFBZCxjQUFjO0VBQ2QsMEJBQW9CO0VBQXBCLDRCQUFvQjtFQUFwQix1QkFBb0I7RUFBcEIsdUJBQW9CO0VBQXBCLG9CQUFvQjtFQUNwQix5QkFBd0I7RUFBeEIsZ0NBQXdCO0VBQXhCLHNCQUF3QjtFQUF4QixzQkFBd0I7RUFBeEIsd0JBQXdCO0VBQ3hCLG1CQUFtQixFQWlCcEI7RUFyQkQ7SUFPSSx3Q3BCaENpQjtJb0JpQ2pCLHlDcEI4Rm9DO0lvQjlGcEMsc0NwQjhGb0M7SW9COUZwQyxpQ3BCOEZvQztJb0I3RnBDLDRCQUFnQjtJQUFoQix5QkFBZ0I7SUFBaEIsd0JBQWdCO0lBQWhCLG9CQUFnQjtJQUNoQixpQ0FBeUI7SUFBekIsOEJBQXlCO0lBQXpCLDZCQUF5QjtJQUF6Qix5QkFBeUI7SUFDekIsWUFBWTtJQUNaLGVBQWU7SUFDZiwyQkFBbUI7SUFBbkIsd0JBQW1CO0lBQW5CLG1CQUFtQjtJQUNuQixtQkFBbUI7SUFFbkIsaUNBQVk7SUFBWiw4QkFBWTtJQUFaLHlCQUFZO0lBQ1osZ0NBQVc7SUFBWCw2QkFBVztJQUFYLHdCQUFXO0lBQ1gsV0EzRDRCO0lBNEQ1QixVQTVENEIsRUE2RDdCOztBQUdIO0VBQ0UsZXBCMUNxQjtFb0IyQ3JCLHlDcEI2RXNDO0VvQjdFdEMsc0NwQjZFc0M7RW9CN0V0QyxpQ3BCNkVzQztFb0I1RXRDLDRCQUFnQjtFQUFoQix5QkFBZ0I7RUFBaEIsd0JBQWdCO0VBQWhCLG9CQUFnQjtFQUNoQixpQ0FBeUI7RUFBekIsOEJBQXlCO0VBQXpCLDZCQUF5QjtFQUF6Qix5QkFBeUIsRUFDMUI7O0FBSUM7Ozs7RUFFRSw0QkFBZ0I7RUFBaEIseUJBQWdCO0VBQWhCLHdCQUFnQjtFQUFoQixvQkFBZ0IsRUFDakI7O0FBSUg7d0NBRXdDO0FBRXhDO0VBQ0Usb1pBQXFCO0VBQ3JCLGdDQUFnQztFQUNoQywyQkFBc0I7RUFBdEIsc0JBQXNCLEVBQ3ZCOztBQUVEO0VBQ0UsNDZHQUFxQixFQUN0Qjs7QUFFRDtFQUNFLHd2REFBcUIsRUFDdEI7O0FBRUQ7RUFDRSxndUVBQXFCLEVBQ3RCOztBQUVEO0VBQ0UsbzZCQUFxQixFQUN0Qjs7QUFFRDtFQUNFLGdsRUFBcUIsRUFDdEI7O0FBRUQ7RUFDRSx3K0JBQXFCLEVBQ3RCOztBQzVJRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7d0NBaUN3QztBQU14Qzs7RUFFRSxrQkFMMEIsRUFNM0I7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsc0JBQXNCO0VBQ3RCLFdBQVc7RUFDWCxZQUFZO0VBQ1oscUJBYjBCLEVBMkIzQjtFQVpLO0lBQ0YsaUJyQnVEeUIsRXFCdEQxQjtFQVRIO0lBWUksZUFBZSxFQUNoQjtFQWJIO0lBZ0JJLGtCQUFrQixFQUNuQjs7QUFJSDtFQUNFLGlCQUFpQjtFQUNqQixhQUFhO0VBQ2IsaUJBQWlCO0VBQ2pCLGlDckJwQnNCO0VxQnFCdEIsY0FBYztFQUNkLFlBQVk7RUFDWixtQkFBbUI7RUFDbkIsZUFBZTtFQUNmLHlDckJpR3NDO0VxQmpHdEMsc0NyQmlHc0M7RXFCakd0QyxpQ3JCaUdzQyxFcUJyRXZDO0VBMUJDOztJQUVFLG9CQUFvQixFQUNyQjtFQUVEO0lBQ0UsZ0JyQlVzQixFcUJUdkI7RUFFRDtJQUNFLGdCckJPcUIsRXFCTnRCO0VBdEJIO0lBeUJJLG9CQUFvQjtJQUNwQixlckI3Q21CLEVxQjhDcEI7RUEzQkg7SUF5Qkksb0JBQW9CO0lBQ3BCLGVyQjdDbUIsRXFCOENwQjtFQTNCSDtJQXlCSSxvQkFBb0I7SUFDcEIsZXJCN0NtQixFcUI4Q3BCO0VBM0JIO0lBeUJJLG9CQUFvQjtJQUNwQixlckI3Q21CLEVxQjhDcEI7RUEzQkg7SUF5Qkksb0JBQW9CO0lBQ3BCLGVyQjdDbUIsRXFCOENwQjtFQTNCSDs7OztJQWtDSSwwQkFBMEIsRUFDM0I7O0FBSUg7RUFDRSxvQnJCSTRCLEVxQkM3QjtFQU5EO0lBSUksb0JyQkZ1QixFcUJHeEI7O0FBR0g7RUFDRSxhQUFhO0VBQ2IsaUJBQWlCO0VBQ2pCLHFCQUFxQjtFQUNyQixvQkFBb0I7RUFDcEIsaUJBQWlCLEVBQ2xCOztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFFBQVE7RUFDUixVQUF5QjtFQUN6QixZQUFZO0VBQ1oseUNyQjhDc0M7RXFCOUN0QyxzQ3JCOENzQztFcUI5Q3RDLGlDckI4Q3NDO0VxQjdDdEMsZXJCaEZxQixFcUJnR3RCO0VBZEM7SUFDRSxnQnJCckNzQixFcUJzQ3ZCO0VBRUQ7SUFDRSxnQnJCeENxQixFcUJ5Q3RCO0VBRUQ7O0lBRUUsZ0JyQjdDcUI7SXFCOENyQixPQUFPLEVBQ1I7O0FBSUg7RUM1SUUsbUJBQW1CLEVEOElwQjtFQUZEO0lDeElJLFlBQVk7SUFDWixtQkFBbUI7SUFDbkIsU0FBUztJQUNULFlBQVk7SUFDWixVQUFVO0lBQ1YseUN0QjhKb0M7SXNCOUpwQyxzQ3RCOEpvQztJc0I5SnBDLGlDdEI4Sm9DO0lzQjdKcEMsMEJ0QjRCbUIsRXNCM0JwQjtFRGlJSDtJQzlISSxXQUFXLEVBQ1o7RUQ2SEg7SUMxSEksVUFBVSxFQUNYO0VEeUhIOzs7Ozs7Ozs7SUNuSE0sV0FBVyxFQUNaO0VBSUg7SUFJSSwwQnRCbUJpQixFc0JsQmxCO0VEeUdMO0lDakdNLDBCdEJMaUIsRXNCTWxCO0VBSUg7SUFJSSwwQnRCRmlCLEVzQkdsQjtFRHVGTDtJQy9FTSwwQnRCTGdCLEVzQk1qQjtFQUlIO0lBSUksV0FBVyxFQUNaOztBRHlFTDs7RUFFRSxtQkFBbUI7RUFDbkIsU0FBUztFQUNULFVBckh3QjtFQXNIeEIsWUFBWSxFQU1iO0VBSkM7O0lBQ0UsT0FBTyxFQUNSOztBQUlIO0VBQ0UsVUFBeUIsRUFNMUI7RUFQRDtJQUlJLFNBQVMsRUFDVjs7QUFJSDtFQUNFLGtCckI1RXNCO0VxQjZFdEIsWXJCN0VzQjtFcUI4RXRCLGdCckI5RXNCO0VxQitFdEIsZXJCL0hxQjtFcUJnSXJCLGtCQUFrQixFQUNuQjs7QUFFRDtFQUNFLGdCckJ0RnVCO0VxQnVGdkIsbUJBQW1CO0VBQ25CLFFBQVE7RUFFUiwrQkFBUztFQUFULDRCQUFTO0VBQVQsdUJBQVM7RUFDVCxZQUFZO0VBQ1oscUJBQWM7RUFBZCxzQkFBYztFQUFkLGtCQUFjO0VBQWQscUJBQWM7RUFBZCxjQUFjO0VBQ2QsMEJBQW9CO0VBQXBCLDRCQUFvQjtFQUFwQix1QkFBb0I7RUFBcEIsdUJBQW9CO0VBQXBCLG9CQUFvQjtFQUNwQixpQnJCNUZzQjtFcUI2RnRCLDBCQUErQjtFQUEvQix1Q0FBK0I7RUFBL0IsdUJBQStCO0VBQS9CLHVCQUErQjtFQUEvQiwrQkFBK0IsRUFrQmhDO0VBNUJEO0lBYUksZXJCbklrQixFcUJvSW5CO0VBZEg7SUFpQkksZXJCN0ltQixFcUI4SXBCO0VBRUQ7SUFDRSxlckI5SW1CLEVxQitJcEI7RUF0Qkg7SUF5QkksZXJCakttQixFcUJrS3BCOztBQUlIO0VBQ0UsZ0JBQWdCO0VBQ2hCLCtCQUF1QjtFQUF2QiwyQkFBdUI7RUFBdkIsdUJBQXVCO0VBQ3ZCLHVCQUFlO0VBQWYscUJBQWU7RUFBZixlQUFlLEVBQ2hCOztBRXBORDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozt3Q0EwQndDO0FBR3hDO0VBQ0UsZ0J2QjhEd0I7RXVCN0R4QixrQkFBa0I7RUFDbEIsWUFBWSxFQU1iO0VBVEQ7SUFNSSw4QnZCY29CLEV1QmJyQjs7QUFJSDtFQUNFLHFCQUFjO0VBQWQsc0JBQWM7RUFBZCxrQkFBYztFQUFkLHFCQUFjO0VBQWQsY0FBYztFQUNkLDBCQUFvQjtFQUFwQiw0QkFBb0I7RUFBcEIsdUJBQW9CO0VBQXBCLHVCQUFvQjtFQUFwQixvQkFBb0I7RUFDcEIsa0J2QitEeUI7RXVCOUR6QixxQnZCOER5QjtFdUI3RHpCLGdCQUFnQixFQTREakI7RUF6REM7SUFDRSxvQnZCeUR1QjtJdUJ4RHZCLG1CdkJ3RHVCLEV1QnZEeEI7RUFYSDtJQWNJLG9CdkJxRHlCO0l1QnBEekIsbUJ2Qm9EeUIsRXVCbkQxQjtFQWhCSDtJQW1CSSxvQnZCaUR3QjtJdUJoRHhCLG1CdkJnRHdCLEV1Qi9DekI7RUFFRDtJQUNFLG9CdkI2QzBCO0l1QjVDMUIsbUJ2QjRDMEIsRXVCM0MzQjtFQUdEO0lBQ0UsMEJ2QnBCa0IsRXVCcUJuQjtFQS9CSDtJQWtDSSwwQnZCaENtQjtJdUJpQ25CLGV2QnhCbUIsRXVCeUJwQjtFQXBDSDtJQXdDSSwwQkFBMEI7SUFDMUIsZUFBZSxFQUNoQjtFQTFDSDtJQThDSSxldkI1Q21CLEV1QjZDcEI7RUEvQ0g7SUFrREksZXZCM0NtQjtJdUI0Q25CLGdCQUFnQixFQUNqQjtFQXBESDtJQXdESSw2QkFBdUI7SUFBdkIsOEJBQXVCO0lBQXZCLCtCQUF1QjtJQUF2QiwwQkFBdUI7SUFBdkIsMkJBQXVCO0lBQXZCLDJCQUF1QjtJQUF2Qix1QkFBdUI7SUFDdkIseUJBQXdCO0lBQXhCLGdDQUF3QjtJQUF4QixzQkFBd0I7SUFBeEIsc0JBQXdCO0lBQXhCLHdCQUF3QixFQUN6QjtFQTFESDtJQThESSxvQnZCUXVCLEV1QlB4Qjs7QUFJSDtFQUNFLGdCdkJqQnNCO0V1QmtCdEIsaUJ2QlZzQixFdUJXdkI7O0FBR0Q7RUFDRSxtQnZCUDJCLEV1QlE1Qjs7QUNuSEQ7d0NBRXdDO0FBTXhDO0VBQ0Usc0JBQXNCO0VBQ3RCLDZCQUE2QjtFQUM3Qiw0QkFBNEI7RUFDNUIsd3NCQUFxQjtFQUNyQixZQVRpQjtFQVVqQixhQVZpQjtFQVdqQiw0QkFBdUI7RUFBdkIsdUJBQXVCLEVBTXhCO0VBSEM7SUFDRSx1QkFBdUIsRUFDeEI7O0FBR0g7RUFDRSxZeEJ1RXNCO0V3QnRFdEIsYXhCc0VzQixFd0JyRXZCOztBQUVEO0VBQ0UsWUF4QnVCO0VBeUJ2QixhQXpCdUIsRUEwQnhCOztBQUVEO0VBQ0UsYUE1QjBCO0VBNkIxQixjQTdCMEIsRUE4QjNCOztBQ3BDRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQWtDRTtBQXlCRjtFQUNFLFVBQVU7RUFDVixXQUFXO0VBQ1gscUJBQWM7RUFBZCxzQkFBYztFQUFkLGtCQUFjO0VBQWQscUJBQWM7RUFBZCxjQUFjO0VBQ2Qsa0JBQWtCO0VBQ2xCLDBCQUFvQjtFQUFwQiw0QkFBb0I7RUFBcEIsdUJBQW9CO0VBQXBCLHVCQUFvQjtFQUFwQixvQkFBb0I7RUFDcEIsMEJBQWtCO0VBQWxCLHVCQUFrQjtFQUFsQixzQkFBa0I7RUFBbEIsa0JBQWtCO0VBQ2xCLFdBQVcsRUFDWjs7QUFFRDtFckJoRUUsbUJBQW1CO0VBQ25CLGlCQUFpQjtFQUNqQixvQkFBVTtFQUNWLFlBQVk7RUFDWixXQUFXO0VBQ1gsYUFBYTtFQUNiLFdBQVc7RUFDWCxVQUFVLEVxQjJEWDs7QUFFRDtFQUNFLDBCQUFnRDtFQUNoRCwwQnpCeEJxQjtFeUJ5QnJCLHFCQUFjO0VBQWQsc0JBQWM7RUFBZCxrQkFBYztFQUFkLHFCQUFjO0VBQWQsY0FBYztFQUNkLDBCQUFvQjtFQUFwQiw0QkFBb0I7RUFBcEIsdUJBQW9CO0VBQXBCLHVCQUFvQjtFQUFwQixvQkFBb0I7RUFDcEIseUJBQXdCO0VBQXhCLGdDQUF3QjtFQUF4QixzQkFBd0I7RUFBeEIsc0JBQXdCO0VBQXhCLHdCQUF3QjtFQUN4QixZQTNDZTtFQTRDZixhQTVDZSxFQThEaEI7RUF6QkQ7SUFVSSxzRHpCekNtQjtJeUJ5Q25CLG1EekJ6Q21CO0l5QnlDbkIsOEN6QnpDbUIsRXlCMENwQjtFQVhIO0lBZU0sWUFBa0I7SUFDbEIsYUFBbUIsRUFDcEI7RUFqQkw7SUFlTSxZQUFrQjtJQUNsQixhQUFtQixFQUNwQjtFQWpCTDtJQWVNLFlBQWtCO0lBQ2xCLGFBQW1CLEVBQ3BCO0VBakJMO0lBc0JNLHVEQXRETTtJQXNETixvREF0RE07SUFzRE4sK0NBdERNLEVBdURQO0VBdkJMO0lBc0JNLHFEQXJETTtJQXFETixrREFyRE07SUFxRE4sNkNBckRNLEVBc0RQO0VBdkJMO0lBc0JNLHFEQXBETTtJQW9ETixrREFwRE07SUFvRE4sNkNBcERNLEVBcURQO0VBdkJMO0lBc0JNLHNEQW5ETTtJQW1ETixtREFuRE07SUFtRE4sOENBbkRNLEVBb0RQO0VBdkJMO0lBc0JNLHNEQWxETTtJQWtETixtREFsRE07SUFrRE4sOENBbERNLEVBbURQO0VBdkJMO0lBc0JNLHFEQWpETTtJQWlETixrREFqRE07SUFpRE4sNkNBakRNLEVBa0RQO0VBdkJMO0lBc0JNLHNEQWhETTtJQWdETixtREFoRE07SUFnRE4sOENBaERNLEVBaURQO0VBdkJMO0lBc0JNLHFEQS9DTTtJQStDTixrREEvQ007SUErQ04sNkNBL0NNLEVBZ0RQO0VBdkJMO0lBc0JNLHFEQTlDTTtJQThDTixrREE5Q007SUE4Q04sNkNBOUNNLEVBK0NQO0VBdkJMO0lBc0JNLHFEQTdDTztJQTZDUCxrREE3Q087SUE2Q1AsNkNBN0NPLEVBOENSOztBQUlMOztFQUVFLGdCQUFnQixFQUNqQjs7QUFFRDs7RUFFRSxtQnpCRHlCLEV5QkUxQjs7QUFHRDt3Q0FFd0M7QUFFeEM7RUFDRSwyQkFBbUI7RUFBbkIsd0JBQW1CO0VBQW5CLG1CQUFtQixFQWNwQjtFQWZEO0lBSUksMEJ6QjdFbUI7SXlCOEVuQiwyQkFBbUI7SUFBbkIsd0JBQW1CO0lBQW5CLG1CQUFtQjtJQUNuQixTQUFTO0lBQ1QsVUFBVTtJQUNWLFlBQVk7SUFDWixXQUFrQjtJQUNsQixZQUFtQjtJQUNuQix5Q3pCNkNvQztJeUI3Q3BDLHNDekI2Q29DO0l5QjdDcEMsaUN6QjZDb0M7SXlCNUNwQyw0QkFBZ0I7SUFBaEIseUJBQWdCO0lBQWhCLHdCQUFnQjtJQUFoQixvQkFBZ0I7SUFDaEIsaUNBQXlCO0lBQXpCLDhCQUF5QjtJQUF6Qiw2QkFBeUI7SUFBekIseUJBQXlCLEVBQzFCOztBQUlIO3dDQUV3QztBQUV4QztFQUNFLDJCekIwQnlCO0V5QjFCekIsd0J6QjBCeUI7RXlCMUJ6QixtQnpCMEJ5QjtFeUJ6QnpCLHlDekJnQ3NDO0V5QmhDdEMsc0N6QmdDc0M7RXlCaEN0QyxpQ3pCZ0NzQztFeUIvQnRDLG1CQUFtQjtFQUNuQixhQUFhLEVBQ2Q7O0FBR0Q7O3dDQUd3QztBQUV4QztFQUVJLHNCekI5R21CLEV5Qm9JcEI7RUF4QnNCO0lBS25CLDRCQUFnQjtJQUFoQix5QkFBZ0I7SUFBaEIsd0JBQWdCO0lBQWhCLG9CQUFnQixFQUNqQjtFQU5MO0lBVVEsV0FBa0I7SUFDbEIsWUFBbUIsRUFDcEI7RUFaa0I7SUFVakIsWUFBa0I7SUFDbEIsYUFBbUIsRUFDcEI7RUFaa0I7SUFVakIsWUFBa0I7SUFDbEIsYUFBbUIsRUFDcEI7RUFaa0I7SUFpQmpCLHNCQTlISSxFQW1JTDtJQXRCUDtNQW9CVSwwQkFqSUUsRUFrSUg7RUFyQlQ7SUFpQlEsc0JBN0hJLEVBa0lMO0lBdEJrQjtNQW9CZiwwQkFoSUUsRUFpSUg7RUFyQlQ7SUFpQlEsc0JBNUhJLEVBaUlMO0lBdEJrQjtNQW9CZiwwQkEvSEUsRUFnSUg7RUFyQmdCO0lBaUJqQixzQkEzSEksRUFnSUw7SUF0QlA7TUFvQlUsMEJBOUhFLEVBK0hIO0VBckJUO0lBaUJRLHNCQTFISSxFQStITDtJQXRCa0I7TUFvQmYsMEJBN0hFLEVBOEhIO0VBckJnQjtJQWlCakIsc0JBekhJLEVBOEhMO0lBdEJQO01Bb0JVLDBCQTVIRSxFQTZISDtFQXJCVDtJQWlCUSxzQkF4SEksRUE2SEw7SUF0QlA7TUFvQlUsMEJBM0hFLEVBNEhIO0VBckJnQjtJQWlCakIsc0JBdkhJLEVBNEhMO0lBdEJrQjtNQW9CZiwwQkExSEUsRUEySEg7RUFyQlQ7SUFpQlEsc0JBdEhJLEVBMkhMO0lBdEJQO01Bb0JVLDBCQXpIRSxFQTBISDtFQXJCZ0I7SUFpQmpCLHNCQXJISyxFQTBITjtJQXRCUDtNQW9CVSwwQkF4SEcsRUF5SEo7O0FBckJnQjtFQTJCckIsMEJ6QnZJbUI7RXlCd0luQiwwQkFBMEI7RUFDMUIsZXpCaEltQjtFeUJpSW5CLGdCQWhKYSxFQTZKZDtFQTNDSDtJQWtDUSxnQkFBc0IsRUFDdkI7RUFuQ2tCO0lBa0NqQixnQkFBc0IsRUFDdkI7RUFuQ2tCO0lBa0NqQixnQkFBc0IsRUFDdkI7RUFuQ1A7SUF3Q1EsMEJBckpJLEVBc0pMO0VBekNQO0lBd0NRLDBCQXBKSSxFQXFKTDtFQXpDa0I7SUF3Q2pCLDBCQW5KSSxFQW9KTDtFQXpDUDtJQXdDUSwwQkFsSkksRUFtSkw7RUF6Q2tCO0lBd0NqQiwwQkFqSkksRUFrSkw7RUF6Q2tCO0lBd0NqQiwwQkFoSkksRUFpSkw7RUF6Q1A7SUF3Q1EsMEJBL0lJLEVBZ0pMO0VBekNQO0lBd0NRLDBCQTlJSSxFQStJTDtFQXpDUDtJQXdDUSwwQkE3SUksRUE4SUw7RUF6Q1A7SUF3Q1EsMEJBNUlLLEVBNklOOztBQU1QOzt3Q0FHd0M7QUFFeEM7O0VBR0kscUJBQXFCLEVBQ3RCOztBQUVHO0VBQ0Ysc0J6QmhLb0IsRXlCaUtyQjs7QUFJSDs7d0NBR3dDO0FBRXhDO0VBR0ksMEJ6QjdLb0IsRXlCOEtyQjs7QUMvTkg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBbUNFO0FBUUY7d0NBRXdDO0FBRXhDO0VBRUUsdUYxQmVvQjtFMEJmcEIsb0YxQmVvQjtFMEJmcEIsK0UxQmVvQjtFMEJkcEIsMkIxQmtIeUI7RTBCbEh6Qix3QjFCa0h5QjtFMEJsSHpCLG1CMUJrSHlCO0UwQmpIekIsc0JBQXNCO0VBQ3RCLFlBQVk7RUFDWixnQkFBZ0I7RUFDaEIsZTFCbUlZO0UwQmxJWixnQkFBZ0I7RUFDaEIsMEIxQkxxQixFMEJNdEI7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0UsYzFCNEM0QixFMEIzQzdCOztBQUVEO0VBRUUsVUFBVTtFQUNWLGVBQWU7RUFDZixXQUFXLEVBQ1o7O0FBRUQ7RUFDRSxtQjFCaUM0QjtFMEJoQzVCLG9CMUJnQzRCO0UwQi9CNUIscUIxQitCNEIsRTBCOUI3Qjs7QUFHRDtFQUNFLG1CQUFtQjtFQUNuQixVQTdDbUM7RUE4Q25DLFlBOUNtQyxFQStDcEM7O0FBR0Q7d0NBRXdDO0FBR3RDO0VBRUUscUJBQXFCO0VBQ3JCLG9CQUFvQixFQUNyQjs7QUFJSDt3Q0FFd0M7QUFFeEM7RUFHSSxrQjFCQTBCO0UwQkMxQixvQkFBcUMsRUFDdEM7O0FBSUg7d0NBRXdDO0FBRXhDO0VBQ0UsaUJBQWlCLEVBQ2xCOztBQUVEO0VBQ0UsaUJBQWlCLEVBQ2xCOztBQUVEO0VBQ0UsaUJBQWlCLEVBQ2xCOztBQUVEO0VBQ0UsaUJBQWlCLEVBQ2xCOztBQUdEO3dDQUV3QztBQUV4QztFQUdJLG1CQUFtQixFQUNwQjs7QUFHSDs7RUFFRSxVQUFVLEVBZVg7RUFqQkQ7OztJQU1JLG1CQXBIb0IsRUFxSHJCO0VBUEg7O0lBVUksV0F0SGlDLEVBdUhsQztFQVhIOztJQWNJLFdBQVc7SUFDWCxZQTNIaUMsRUE0SGxDOztBQUdIO0VBQ0UsV0FsSXNCLEVBOEl2QjtFQWJEO0lDaEtFLFlBQVk7SUFDWixlQUFlO0lBQ2YsU0FBUztJQUNULFVBQVU7SUFDVixvQkFBb0I7SUFDcEIsbUJEMEJzQjtJQ3pCdEIsK0JBQW1CO0lBQ25CLGdDQUFvQjtJQUNwQiw4Q0FBcUI7SUFDckIsOEJBQWtCO0lENkpoQixvQkFBb0IsRUFDckI7RUFQSDtJQVVJLFNBMUlxQjtJQTJJckIsNkIxQjlIbUIsRTBCK0hwQjs7QUFHSDtFQUNFLGNBakpzQixFQTZKdkI7RUFiRDtJQy9LRSxZQUFZO0lBQ1osZUFBZTtJQUNmLFNBQVM7SUFDVCxVQUFVO0lBQ1Ysb0JBQW9CO0lBQ3BCLG1CRDBCc0I7SUN6QnRCLCtCQUFtQjtJQUNuQixnQ0FBb0I7SUFDcEIsaUNBQXFCO0lBQ3JCLDBCQUFrQjtJRDRLaEIsdUJBQXVCLEVBQ3hCO0VBUEg7SUFVSSxZQXpKcUI7SUEwSnJCLDBCMUI3SW1CLEUwQjhJcEI7O0FBR0g7O0VBRUUsU0FBUyxFQWVWO0VBakJEOzs7SUFNSSxrQkFyS29CLEVBc0tyQjtFQVBIOztJQVVJLFVBdktpQyxFQXdLbEM7RUFYSDs7SUFjSSxVQUFVO0lBQ1YsYUE1S2lDLEVBNktsQzs7QUFHSDtFQUNFLFlBbkxzQixFQStMdkI7RUFiRDtJQ2pORSxZQUFZO0lBQ1osZUFBZTtJQUNmLFNBQVM7SUFDVCxVQUFVO0lBQ1Ysb0JBQW9CO0lBQ3BCLG1CRDBCc0I7SUN6QnRCLCtCQUFtQjtJQUNuQiw2Q0FBb0I7SUFDcEIsaUNBQXFCO0lBQ3JCLDhCQUFrQjtJRDhNaEIscUJBQXFCLEVBQ3RCO0VBUEg7SUFVSSxVQTNMcUI7SUE0THJCLDRCMUIvS21CLEUwQmdMcEI7O0FBR0g7RUFDRSxhQWxNc0IsRUE4TXZCO0VBYkQ7SUNoT0UsWUFBWTtJQUNaLGVBQWU7SUFDZixTQUFTO0lBQ1QsVUFBVTtJQUNWLG9CQUFvQjtJQUNwQixtQkQwQnNCO0lDekJ0Qiw0Q0FBbUI7SUFDbkIsZ0NBQW9CO0lBQ3BCLGlDQUFxQjtJQUNyQiw4QkFBa0I7SUQ2TmhCLHNCQUFzQixFQUN2QjtFQVBIO0lBVUksV0ExTXFCO0lBMk1yQiwyQjFCOUxtQixFMEIrTHBCOztBRWxQSDs7Ozs7O3dDQU93QztBQUV4QztFQUNFLGU1QnlDcUI7RTRCeENyQiwwQjVCa0NrQixFNEJqQ25COztBQUVEO0VBQ0UsaUI1Qm9Gc0IsRTRCbkZ2Qjs7QUFFRDtFQUNFLGdCNUI2RXdCO0U0QjVFeEIsZTVCMkJxQjtFNEIxQnJCLGdCQUFnQixFQUNqQjs7QUN0QkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozt3Q0FtQndDO0FBSXhDO0VBQ0UscUJBQWM7RUFBZCxzQkFBYztFQUFkLGtCQUFjO0VBQWQscUJBQWM7RUFBZCxjQUFjO0VBQ2QseUJBQXdCO0VBQXhCLGdDQUF3QjtFQUF4QixzQkFBd0I7RUFBeEIsc0JBQXdCO0VBQXhCLHdCQUF3QixFQUN6Qjs7QUFFRDtFQUNFLHdCQUE0QjtFQUE1QixvQ0FBNEI7RUFBNUIscUJBQTRCO0VBQTVCLHFCQUE0QjtFQUE1Qiw0QkFBNEIsRUFDN0I7O0FBRUQ7RUFDRSxzQkFBMEI7RUFBMUIsa0NBQTBCO0VBQTFCLG1CQUEwQjtFQUExQixtQkFBMEI7RUFBMUIsMEJBQTBCLEVBQzNCOztBQUdEO0VBQ0UsNEJBQXFCO0VBQXJCLDZCQUFxQjtFQUFyQix5QkFBcUI7RUFBckIsNEJBQXFCO0VBQXJCLHFCQUFxQjtFQUNyQiwwQkFBb0I7RUFBcEIsNEJBQW9CO0VBQXBCLHVCQUFvQjtFQUFwQix1QkFBb0I7RUFBcEIsb0JBQW9CO0VBQ3BCLGdCN0JvRHdCO0U2Qm5EeEIseUJBQXdCO0VBQXhCLGdDQUF3QjtFQUF4QixzQkFBd0I7RUFBeEIsc0JBQXdCO0VBQXhCLHdCQUF3QjtFQUN4QixxRjdCc0JvQjtFNkJ0QnBCLGtGN0JzQm9CO0U2QnRCcEIsNkU3QnNCb0IsRTZCckJyQjs7QUFHRDs7RUFFRSxxQkFBYztFQUFkLHNCQUFjO0VBQWQsa0JBQWM7RUFBZCxxQkFBYztFQUFkLGNBQWM7RUFDZCwwQkFBb0I7RUFBcEIsNEJBQW9CO0VBQXBCLHVCQUFvQjtFQUFwQix1QkFBb0I7RUFBcEIsb0JBQW9CO0VBQ3BCLHNDQUE4QjtFQUE5QiwwQkFBOEI7RUFBOUIsOEJBQThCO0VBQzlCLGtCQTlCMEI7RUErQjFCLGFBL0IwQjtFQWdDMUIsWUFoQzBCO0VBaUMxQiwwQjdCSHFCO0U2QklyQixlN0JWa0I7RTZCV2xCLHNCQUFzQixFQUN2Qjs7QUFFRDtFQUNFLHlDN0IrR3NDO0U2Qi9HdEMsc0M3QitHc0M7RTZCL0d0QyxpQzdCK0dzQyxFNkI1RnZDO0VBcEJEO0lBSUksc0JBQXNCLEVBQ3ZCO0VBTEg7SUFTSSwwQjdCbEJrQixFNkJtQm5CO0VBVkg7SUFjSSxxQkFBcUIsRUFDdEI7RUFmSDtJQWtCSSxlN0I1Qm9CLEU2QjZCckI7O0FBR0g7RUFDRSxxQkFBcUIsRUFDdEI7O0FBR0Q7RUFDRSxnQjdCU3dCO0U2QlJ4QixlN0IzQ2tCLEU2QmlEbkI7RUFSRDtJQUtJLGU3QjFDb0IsRTZCMkNyQjs7QUM1Rkg7Ozs7O3dDQU13QztBQUV4QztFQUNFLG1CQUFtQjtFQUNuQixZQUFZO0VBQ1osVUFBVTtFQUNWLFk5QnlLVTtFOEJ4S1YsaUJBQWlCO0VBQ2pCLFlBQVk7RUFDWixhQUFhO0VBQ2IsMEJBQTBCLEVBQzNCOztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFVBQVU7RUFDVixhQUFhO0VBQ2IsZUFBZTtFQUNmLGFBQWE7RUFDYixnQjlCbUV3QjtFOEJsRXhCLGtCQUFrQjtFQUNsQixlOUJ3QnFCO0U4QnZCckIsMEJBQTBCO0VBQzFCLG1CQUFtQjtFQUNuQixpQ0FBaUI7RUFBakIsOEJBQWlCO0VBQWpCLDZCQUFpQjtFQUFqQix5QkFBaUI7RUFDakIsb0JBQW9CO0VBQ3BCLDBCOUJVcUI7RThCVHJCLHVGOUIrQm9CO0U4Qi9CcEIsb0Y5QitCb0I7RThCL0JwQiwrRTlCK0JvQixFOEI5QnJCOztBQ2xDRDs7Ozs7d0NBTXdDO0FBRXhDO0VBQ0UsMEIvQjBDcUI7RStCekNyQix1Ri9Cc0RvQjtFK0J0RHBCLG9GL0JzRG9CO0UrQnREcEIsK0UvQnNEb0I7RStCckRwQiwyQi9CeUp5QjtFK0J6SnpCLHdCL0J5SnlCO0UrQnpKekIsbUIvQnlKeUIsRStCeEoxQjs7QUNaRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O3dDQWtDd0M7QUFFeEM7RUFDRSxzQkFBc0I7RUFDdEIsbUJBQW1CO0VBQ25CLHVCQUF1QjtFQUN2QixnQmhDb0R3QjtFZ0NuRHhCLGlDaENRc0IsRWdDUHZCOztBQUVEO0VBR0ksV0FBVyxFQUNaOztBQUlIO0VBR0ksMEJoQ05vQjtFZ0NPcEIsZ0JBQWdCLEVBQ2pCOztBQUxIO0VBUUksY0FBYyxFQUNmOztBQUlzQjtFQUN2QixRQUFRLEVBQ1Q7O0FBRUQ7RUFHSSwwQmhDdkJvQjtFZ0N3QnBCLGdCQUFnQixFQU1qQjtFQVZIO0lBT00sY0FBYyxFQUNmOztBQVVEO0VBQ0Usd0JBQXdCO0VBQ3hCLFVBQVU7RUFDVixXQUFXO0VBQ1gseUJBQWlCO0VBQWpCLHNCQUFpQjtFQUFqQixpQkFBaUI7RUFDakIsOEJBQThCLEVBQy9COztBQUlnQjtFQUNqQixrQkFBa0I7RUFDbEIsaUJBQWlCLEVBQ2xCOztBQWpCSDtFQXNCTSxXQUFXLEVBQ1o7O0FBdkJMO0VBMEJNLGVoQzVEa0IsRWdDNkRuQjs7QUFSSDtFQVdJLGVoQ3ZFaUIsRWdDd0VsQjs7QUFFRDtFQUNFLG1CaENSd0IsRWdDU3pCOztBQW5DTDtFQXdDSSwwQmhDekVrQixFZ0MwRW5COztBQUVEO0VBQ0UsZ0JBQWdCO0VBQ2hCLG1CaENwQndCO0VpQ3JHMUIsZUFIZTtFQUlmLG9CQUFvQjtFQUNwQixpQkFBaUI7RUFDakIsd0JBQXdCO0VBQ3hCLGdCQVJnQixFRCtIZjs7QUFJSDtFQUNFLFVBQVU7RUFDVixVQUFVO0VBQ1YsV0FBVztFQUNYLGVBQWU7RUFDZixnQkFBZ0I7RUFDaEIsUUFBUTtFQUNSLE9BQU87RUFDUCxpQkFBaUI7RUFDakIsZ0JBQWdCO0VBQ2hCLGFBQWE7RUFDYixZQUFZO0VBQ1osV0FBVztFQUNYLFlBQVksRUFDYjs7QUFFRDtFNUJqSkUsbUJBQW1CO0VBQ25CLGlCQUFpQjtFQUNqQixvQkFBVTtFQUNWLFlBQVk7RUFDWixXQUFXO0VBQ1gsYUFBYTtFQUNiLFdBQVc7RUFDWCxVQUFVLEU0QjRJWDs7QUFFRDtFQUNFLGdCQUFnQjtFQUNoQixlQUFlO0VBQ2YsdUJBQWtCO0VBQWxCLHNCQUFrQjtFQUFsQixrQkFBa0I7RUFDbEIsMEJBQTBCO0VBQzFCLFdBQVcsRUFpQ1o7RUEvQkM7SUMxSkEsZUFIZTtJQUlmLG9CQUFvQjtJQUNwQixpQkFBaUI7SUFDakIsd0JBQXdCO0lBQ3hCLGdCQVJnQjtJRGdLZCxpQkFBaUIsRUFDbEI7RUFWSDtJQWFJLG1CQUFtQjtJQUNuQixnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLGlCaEN2RW9CLEVnQ3dFckI7RUFqQkg7SUFvQkksZWhDaEltQixFZ0NpSXBCO0VBckJIO0lBd0JJLG1CQUFtQjtJQUNuQixPQUFPO0lBQ1AsWUFBWTtJQUNaLGFBQWEsRUFTZDtJQVBDO01MakxGLFlBQVk7TUFDWixlQUFlO01BQ2YsU0FBUztNQUNULFVBQVU7TUFDVixvQkFBb0I7TUFDcEIsa0JLNktpQztNTDVLakMsK0JBQW1CO01BQ25CLGdDQUFvQjtNQUNwQixpQ0FBcUI7TUFDckIsMEJBQWtCO01LMEtkLG1CQUFtQjtNQUNuQixVQUFVO01BQ1YsU0FBUyxFQUNWOztBQU1MO0VBQ0UsZ0JBQWdCO0VBQ2hCLGVBQWU7RUFDZix1QkFBa0I7RUFBbEIsc0JBQWtCO0VBQWxCLGtCQUFrQjtFQUNsQiwwQkFBMEIsRUFNM0I7RUFWRDtJQzNMRSxzQkRrTTBDO0lDak0xQyxvQkFBb0I7SUFDcEIsaUJBQWlCO0lBQ2pCLHdCQUF3QjtJQUN4QixnQkFSZ0IsRUR1TWY7O0FBSUg7RUFDRSxZQUFZLEVBVWI7RUFSQztJQUdJLHlCQUF5QixFQUMxQjs7QUFNTDtFQUNFLDBCaEN6S3FCO0VnQzBLckIsZUFBZTtFQUNmLG1CQUFtQjtFQUNuQixnQkFBZ0I7RUFDaEIsWUFBWTtFQUNaLHFGaENqS29CO0VnQ2lLcEIsa0ZoQ2pLb0I7RWdDaUtwQiw2RWhDaktvQjtFZ0NrS3BCLGNoQzVDYyxFZ0M2Q2Y7O0FBRUQ7RUFDRSxlQUFlLEVBQ2hCOztBQUVEO0VBQ0UsaUJBQWlCLEVBQ2xCOztBQUVEO0VBQ0UsNkJoQ2xJMEI7RWdDbUkxQix1QkFBa0I7RUFBbEIsc0JBQWtCO0VBQWxCLGtCQUFrQjtFQUNsQiwwQkFBMEI7RUFDMUIseUNoQ3RFc0M7RWdDc0V0QyxzQ2hDdEVzQztFZ0NzRXRDLGlDaEN0RXNDLEVnQzRFdkM7RUFWRDtJQU9JLGdCQUFnQixFQUNqQjs7QUFJSDtFVnJQRSxtQkFBbUI7RVV3UG5CLHNCaENsSnlCLEVnQ21KMUI7RUFKRDtJVmpQSSxZQUFZO0lBQ1osbUJBQW1CO0lBQ25CLFNBQVM7SUFDVCxZQUFZO0lBQ1osVUFBVTtJQUNWLHlDdEI4Sm9DO0lzQjlKcEMsc0N0QjhKb0M7SXNCOUpwQyxpQ3RCOEpvQztJc0I3SnBDLDBCdEI0Qm1CLEVzQjNCcEI7RVUwT0g7SVZ2T0ksV0FBVyxFQUNaO0VVc09IO0lWbk9JLFVBQVUsRUFDWDtFVWtPSDs7Ozs7Ozs7O0lWNU5NLFdBQVcsRUFDWjtFQUlIO0lBSUksMEJ0Qm1CaUIsRXNCbEJsQjtFQUlIO0lBSUksMEJ0QkxpQixFc0JNbEI7RUFJSDtJQUlJLDBCdEJGaUIsRXNCR2xCO0VBSUg7SUFJSSwwQnRCTGdCLEVzQk1qQjtFQUlIO0lBSUksV0FBVyxFQUNaOztBVW9MTDtFQUNFLGVBQWUsRUFvQmhCO0VBckJEO0lBSUksWUFBWTtJQUNaLGdCQUFnQztJQUNoQyxnQmhDektzQjtJZ0MwS3RCLFdBQVc7SUFDWCxVQUFVO0lBQ1YsbUhBQWtILEVBTW5IO0lBZkg7TUFZTSx5QkFBeUIsRUFDMUI7RUFiTDtJQWtCSSxjQUFjLEVBQ2Y7O0FBSUg7RUFDRSwwQmhDcE9xQjtFZ0NxT3JCLGFBQWEsRUFxQ2Q7RUFuQ0M7SUFDRSxpQkFBaUI7SUFDakIsWUFBWSxFQU1iO0lBSkM7TUFDRSxpQkFBaUIsRUFDbEI7RUFWTDtJQWVJLGVoQ3ZQbUI7SWdDd1BuQixnQkFBZ0I7SUFDaEIsWUFBWSxFQUNiO0VBbEJIO0lBcUJJLGdCQUFnQjtJQUNoQixhQUFhO0lBQ2IsaUJoQzFNb0I7SWdDMk1wQixnQkFBZ0I7SUFDaEIsbUJoQ3JNdUIsRWdDc014QjtFQUVEO0lBQ0UsZ0JBQWdCO0lBQ2hCLFlBQVksRUFDYjtFQS9CSDtJQWtDSSxnQkFBZ0I7SUFDaEIsc0JBQXNCO0lBQ3RCLGlCaEN2Tm9CLEVnQ3dOckI7O0FFM1RIOzs7Ozs7Ozs7Ozs7Ozt3Q0Fld0M7QUFFeEM7RUFDRSxnQkFBZ0I7RUFDaEIsZUFBZTtFQUNmLFFBQVE7RUFDUixZQUFZO0VBQ1osbUJBQW1CO0VBQ25CLHlDbENxSndDO0VrQ3JKeEMsc0NsQ3FKd0M7RWtDckp4QyxpQ2xDcUp3QztFa0NwSnhDLHFCQUFxQjtFQUNyQixlbEMrSmUsRWtDMUpoQjtFQWJEO0lBV0ksc0NBQXFCO0lBQXJCLG1DQUFxQjtJQUFyQixrQ0FBcUI7SUFBckIsOEJBQXFCLEVBQ3RCOztBQUdIO0VBQ0Usc0JBQXNCO0VBQ3RCLGVsQ2lCcUI7RWtDaEJyQixtQmxDMEU0QjtFa0N6RTVCLGlCQUFpQixFQUNsQjs7QUFFRDtFQUNFLDBCbENLa0IsRWtDSm5COztBQUVEO0VBQ0UsMEJsQ2dCb0IsRWtDZnJCOztBQUVEO0VBQ0UsMEJsQ01xQixFa0NMdEI7O0FBRUQ7RUFDRSwwQmxDS3FCLEVrQ0p0Qjs7QUNyREQ7Ozs7Ozs7d0NBUXdDO0FBT3hDO3dDQUV3QztBQUV4QztFQUNFLDRCQUFxQjtFQUFyQiw2QkFBcUI7RUFBckIseUJBQXFCO0VBQXJCLDRCQUFxQjtFQUFyQixxQkFBcUI7RUFDckIsMEJBQW9CO0VBQXBCLDRCQUFvQjtFQUFwQix1QkFBb0I7RUFBcEIsdUJBQW9CO0VBQXBCLG9CQUFvQjtFQUNwQix3QkFBNEI7RUFBNUIsb0NBQTRCO0VBQTVCLHFCQUE0QjtFQUE1QixxQkFBNEI7RUFBNUIsNEJBQTRCLEVBQzdCOztBQUdEO3dDQUV3QztBQUV4QztFL0J6QkUsbUJBQW1CO0VBQ25CLGlCQUFpQjtFQUNqQixvQkFBVTtFQUNWLFlBQVk7RUFDWixXQUFXO0VBQ1gsYUFBYTtFQUNiLFdBQVc7RUFDWCxVQUFVLEUrQm9CWDs7QUFHRDt3Q0FFd0M7QUFFeEM7RUFDRSxlbkNLa0I7RW1DSmxCLGdCQUFnQixFQUNqQjs7QUFHRDt3Q0FFd0M7QUFFeEM7RUFDRSxzQkFBc0I7RUFDdEIsbUJBQW1CO0VBQ25CLFlBekN5QjtFQTBDekIsYUF6QzBCO0VBMEMxQiw0QkExQzBCO0VBMEMxQix5QkExQzBCO0VBMEMxQixvQkExQzBCO0VBMkMxQiwwQm5DTnNCO0VtQ090QixnQkFBZ0I7RUFDaEIsV0FBVztFQUNYLDBCQUFrQjtFQUFsQix1QkFBa0I7RUFBbEIsc0JBQWtCO0VBQWxCLGtCQUFrQjtFQUVsQjswQ0FFd0MsRUE2QnpDO0VBM0JDO0lBQ0UsZUFBZTtJQUNmLFlBQVk7SUFDWixtQkFBbUI7SUFDbkIsVUFBNEI7SUFDNUIsWUEzRHNCO0lBNER0QixhQTVEc0I7SUE2RHRCLDJCQUFtQjtJQUFuQix3QkFBbUI7SUFBbkIsbUJBQW1CO0lBQ25CLDBCbkNyQm1CO0ltQ3NCbkIscUZuQ1RrQjtJbUNTbEIsa0ZuQ1RrQjtJbUNTbEIsNkVuQ1RrQjtJbUNVbEIseUNuQ2lHb0M7SW1DakdwQyxzQ25DaUdvQztJbUNqR3BDLGlDbkNpR29DO0ltQ2hHcEMsbUNBQW9CO0lBQXBCLGdDQUFvQjtJQUFwQiwrQkFBb0I7SUFBcEIsMkJBQW9CLEVBQ3JCO0VBM0JIO0lBOEJJLDBCbkNyQ21CO0ltQ3NDbkIsc0NBQW9CO0lBQXBCLG1DQUFvQjtJQUFwQixrQ0FBb0I7SUFBcEIsOEJBQW9CLEVBQ3JCO0VBRUQ7SUFDRSwwQm5DbkNvQixFbUNvQ3JCO0VBRUQ7SUFDRSx3SG5DOUNtQjtJbUM4Q25CLHFIbkM5Q21CO0ltQzhDbkIsZ0huQzlDbUIsRW1DK0NwQjs7QUFLSDs7d0NBR3dDO0FBRXRCOztFQUVoQixrQm5DS3lCLEVtQ0oxQjs7QUFFMkI7O0VBRTFCLHFCQUFxQixFQUN0Qjs7QUMzR0Q7Ozs7Ozs7Ozs7Ozt3Q0Fhd0M7QUFHeEM7RUFDRSxZQUFZO0VBQ1osZ0JwQzBFd0I7RW9DekV4QixxRnBDNkNvQjtFb0M3Q3BCLGtGcEM2Q29CO0VvQzdDcEIsNkVwQzZDb0I7RW9DNUNwQiwwQnBDK0JxQjtFb0M5QnJCLDJCcEMrSXlCO0VvQy9JekIsd0JwQytJeUI7RW9DL0l6QixtQnBDK0l5QixFb0M5STFCOztBQUVEO0VBQ0UsaUJBQWlCO0VBQ2pCLHFGcENzQ29CO0VvQ3RDcEIsa0ZwQ3NDb0I7RW9DdENwQiw2RXBDc0NvQjtFRTVCbEIsb0NGZ0l1QjtFRWhJdkIsZ0NGZ0l1QjtFRWhJdkIsNEJGZ0l1QjtFRTVIdkIscUNGNEh1QjtFRTVIdkIsaUNGNEh1QjtFRTVIdkIsNkJGNEh1QjtFb0N4SXpCLDBCQUEwQjtFQUMxQixpQ3BDb0JzQjtFb0NuQnRCLG1CQUFtQixFQVlwQjtFQWxCRDtJQVVJLFlBQVk7SUFDWixlQUFlO0lBQ2YsWUFBWTtJQUNaLDBCcENjbUI7SW9DYm5CLG1CQUFtQjtJQUNuQixhQUFhO0lBQ2IsWUFBWSxFQUNiOztBQUdIO0VBQ0UsYUFBYTtFQUNiLGdCcEMrRDRCLEVvQzlEN0I7O0FBRUQ7RUFDRSxnQkFBZ0IsRUFDakI7O0FBRUQ7O0VBRUUsYUFBYTtFQUNiLHVCQUF1QixFQUN4Qjs7QUFFRDtFQUNFLGVwQ2RxQjtFb0NlckIsMEJBQTBCLEVBb0IzQjtFQXRCRDtJbEN2Qkksb0NGZ0l1QjtJRWhJdkIsZ0NGZ0l1QjtJRWhJdkIsNEJGZ0l1QixFb0NuR3hCO0VBTkg7SWxDbkJJLHFDRjRIdUI7SUU1SHZCLGlDRjRIdUI7SUU1SHZCLDZCRjRIdUIsRW9DL0Z4QjtFQUllO0lsQ3JDZCxrQ2tDc0NtQjtJbEN0Q25CLDhCa0NzQ21CO0lsQ3RDbkIsMEJrQ3NDbUIsRUFDbEI7RUFISDtJbENoQ0UsbUNrQ3NDeUI7SWxDdEN6QiwrQmtDc0N5QjtJbEN0Q3pCLDJCa0NzQ3lCLEVBQ3hCOztBQUlMO0VBQ0UsMEJwQ2xDb0IsRW9DK0NyQjtFQWREO0lBSUksb0JBQW9CLEVBQ3JCO0VBTEg7SWxDbkNJLHVDRm9IdUI7SUVwSHZCLG1DRm9IdUI7SUVwSHZCLCtCRm9IdUIsRW9DeEV4QjtFQUVhO0lsQ2xEWix3Q0Z3SHVCO0lFeEh2QixvQ0Z3SHVCO0lFeEh2QixnQ0Z3SHVCLEVvQ3BFeEI7O0FBR0g7RUFDRSxtQkFBbUI7RUFDbkIsZ0JwQ00yQjtFb0NMM0IsaUNwQ3JEc0IsRW9DOER2QjtFQVpEO0lBTUksbUJwQ0kwQixFb0NIM0I7RUFQSDtJQVVJLG9CcENBMEIsRW9DQzNCOztBQUdIO0VBQ0UsaUJBQWlCLEVBQ2xCOztBQ25IRDs7Ozs7Ozs7Ozs7Ozs7Ozt3Q0FpQndDO0FBRXhDO0VBQ0UsbUJBQW1CLEVBQ3BCOztBQUVEO0VBQ0UsaUdyQ3dIbUI7RXFDeEhuQiw4RnJDd0htQjtFcUN4SG5CLHlGckN3SG1CLEVxQ3ZIcEI7O0FBRUQ7RUFDRSxxQkFBYztFQUFkLHNCQUFjO0VBQWQsa0JBQWM7RUFBZCxxQkFBYztFQUFkLGNBQWM7RUFDZCwwQnJDc0JxQixFcUNyQnRCOztBQUlDO0VBQ0UsU0FBUztFQUNULG9CQUFlO0VBQWYsdUJBQWU7RUFBZixpQkFBZTtFQUFmLG1CQUFlO0VBQWYsZUFBZSxFQUNoQjs7QUFJSDtFQUNFLGVyQ0lxQjtFcUNIckIsZ0JyQ2lEd0I7RXFDaER4QixtQkFBbUI7RUFDbkIsc0JBQXNCO0VBQ3RCLGtCQUFrQjtFQUNsQixtQkFBbUI7RUFDbkIsb0JBQW9CO0VBQ3BCLHlDckMwSHNDO0VxQzFIdEMsc0NyQzBIc0M7RXFDMUh0QyxpQ3JDMEhzQztFaUNwS3RDLGVBSGU7RUFJZixvQkFBb0I7RUFDcEIsaUJBQWlCO0VBQ2pCLHdCQUF3QjtFQUN4QixpQkl1Q3VCLEVBZ0J4QjtFQXpCRDtJQVlJLGVyQ1JnQjtJcUNTaEIsZ0JBQWdCO0lBQ2hCLHNCQUFzQixFQUN2QjtFQWZIO0lBa0JJLGVyQ2pCbUIsRXFDa0JwQjtFQUVEO0lBQ0UsZ0JBQWdCLEVBQ2pCOztBQUlIO0VBQ0UsbUJBQW1CO0VBQ25CLFVBQVU7RUFDVixZQUFZO0VBQ1osMEJyQzlCcUI7RXFDK0JyQix5Q3JDa0dzQztFcUNsR3RDLHNDckNrR3NDO0VxQ2xHdEMsaUNyQ2tHc0MsRXFDakd2Qzs7QUMxRUQ7Ozs7Ozs7O3dDQVN3QztBQUV4QztFQUNFLHFCQUFjO0VBQWQsc0JBQWM7RUFBZCxrQkFBYztFQUFkLHFCQUFjO0VBQWQsY0FBYztFQUNkLHlCQUF3QjtFQUF4QixnQ0FBd0I7RUFBeEIsc0JBQXdCO0VBQXhCLHNCQUF3QjtFQUF4Qix3QkFBd0I7RUFDeEIsMEJBQW9CO0VBQXBCLDRCQUFvQjtFQUFwQix1QkFBb0I7RUFBcEIsdUJBQW9CO0VBQXBCLG9CQUFvQixFQWtCckI7RUFyQkQ7SUFPSSxZQUFZO0lBQ1osZUFBZTtJQUNmLDBCdEM2Qm9CO0lzQzVCcEIsWUFBWTtJQUNaLG9CQUFhO0lBQWIscUJBQWE7SUFBYixpQkFBYTtJQUFiLHFCQUFhO0lBQWIsYUFBYSxFQUNkO0VBWkg7SUFlSSxrQkFBbUMsRUFDcEM7RUFoQkg7SUFtQkksaUJBQWtDLEVBQ25DOztBQUdIO0VBRUksY0FBYyxFQUNmOztBQUdIO0VBRUksY0FBYyxFQUNmOztBQzNDSDs7Ozs7Ozs7Ozs7O3dDQWF3QztBQU14Qzt3Q0FFd0M7QUFFeEM7RUFDRSxxQkFBYztFQUFkLHNCQUFjO0VBQWQsa0JBQWM7RUFBZCxxQkFBYztFQUFkLGNBQWM7RUFDZCxldkNxQnFCO0V1Q3BCckIsZ0J2Q21FdUI7RXVDbEV2QiwwQkFBMEI7RUFDMUIsMEJBQWtCO0VBQWxCLHVCQUFrQjtFQUFsQixzQkFBa0I7RUFBbEIsa0JBQWtCLEVBQ25COztBQUVEO0VuQzFCRSxtQkFBbUI7RUFDbkIsaUJBQWlCO0VBQ2pCLG9CQUFVO0VBQ1YsWUFBWTtFQUNaLFdBQVc7RUFDWCxhQUFhO0VBQ2IsV0FBVztFQUNYLFVBQVUsRW1DcUJYOztBQUVEO0VBQ0UsYUFBYSxFQUNkOztBQUVEO0VBQ0UsZ0J2Q29FMEI7RXVDbkUxQixzQkFBc0I7RUFDdEIseUN2Q2lJc0M7RXVDakl0QyxzQ3ZDaUlzQztFdUNqSXRDLGlDdkNpSXNDO0V1Q2hJdEMsOEJBQXVEO0VBQ3ZELGlDQUEwRDtFQUMxRCxrQkE5QndCO0VBK0J4QixtQkFBbUI7RU52Q25CLGVBSGU7RUFJZixvQkFBb0I7RUFDcEIsaUJBQWlCO0VBQ2pCLHdCQUF3QjtFQUN4QixnQk1vQ3NCLEVBcUN2QjtFOUJrRUc7SThCL0dKO01BY00sb0JBQVE7TUFBUixnQkFBUTtNQUFSLGlCQUFRO01BQVIsWUFBUTtNQUFSLFFBQVEsRUFDVCxFQUFBO0VBZkw7SUFtQkksMEJ2Q1JrQjtJdUNTbEIsZXZDZGdCO0l1Q2VoQixnQkFBZ0IsRUFDakI7RUF0Qkg7SUF5QkksK0JBQXdEO0lyQzVCeEQsb0NGZ0l1QjtJRWhJdkIsZ0NGZ0l1QjtJRWhJdkIsNEJGZ0l1QjtJRXBIdkIsdUNGb0h1QjtJRXBIdkIsbUNGb0h1QjtJRXBIdkIsK0JGb0h1QixFdUNsR3hCO0VBM0JIO0lBOEJJLGdDQUF5RDtJckM3QnpELHFDRjRIdUI7SUU1SHZCLGlDRjRIdUI7SUU1SHZCLDZCRjRIdUI7SUV4SHZCLHdDRndIdUI7SUV4SHZCLG9DRndIdUI7SUV4SHZCLGdDRndIdUIsRXVDN0Z4QjtFQWhDSDtJQW1DSSwwQnZDaENtQjtJdUNpQ25CLHNCdkNqQ21CO0l1Q2tDbkIscUJBQXFCO0lBQ3JCLGV2QzFCbUIsRXVDMkJwQjtFQUVEO0lBQ0UscUJBQXFCO0lBQ3JCLGV2Q2pDb0IsRXVDa0NyQjs7QUFHSDtFQUNFLGtCQXhFd0I7RUF5RXhCLG9CQUFvQjtFQUNwQixZdkNNc0IsRXVDTHZCOztBQzFGRDs7Ozs7Ozs7Ozs7Ozs7O0VBZUU7QUFRRjt3Q0FFd0M7QUFFeEM7RUFDRSxzQkFBc0I7RUFDdEIsaUJBWG9CO0VBWXBCLGV4QzRKYztFd0MzSmQsbUJBQW1CO0VBQ25CLDBCeENha0I7RXdDWmxCLGdCeEM0RHVCO0V3QzNEdkIsaUJBQWlCO0VBQ2pCLGV4Q2dCcUI7RXdDZnJCLHNCQUFzQjtFQUN0QixzQkFBc0I7RUFDdEIsbUJBQW1CO0VBQ25CLHNCQUFzQztFQUN0QywyQnhDNEh5QjtFd0M1SHpCLHdCeEM0SHlCO0V3QzVIekIsbUJ4QzRIeUI7RXdDM0h6QixnQ0FBZ0M7RUFDaEMsaUJBQWlCLEVBVWxCO0VBekJEO0lBa0JJLG1CQUFtQjtJQUNuQixZQUFZO0lBQ1osZUFBZTtJQUNmLFNBQVM7SUFDVCxVQUFVO0lBQ1Ysb0JBQW9CLEVBQ3JCOztBQUlIO3dDQUV3QztBQUV4QztFQUNFO0lBQ0UsV0FBVyxFQUFBO0VBR2I7SUFDRSxXQUFXLEVBQUE7RUFHYjtJQUNFLHdDQUFzQjtJQUF0QixnQ0FBc0IsRUFBQSxFQUFBO0FBVjFCO0VBQ0U7SUFDRSxXQUFXLEVBQUE7RUFHYjtJQUNFLFdBQVcsRUFBQTtFQUdiO0lBQ0UscUNBQXNCO0lBQXRCLGdDQUFzQixFQUFBLEVBQUE7QUFWMUI7RUFDRTtJQUNFLFdBQVcsRUFBQTtFQUdiO0lBQ0UsV0FBVyxFQUFBO0VBR2I7SUFDRSx3Q0FBc0I7SUFBdEIscUNBQXNCO0lBQXRCLGdDQUFzQixFQUFBLEVBQUE7O0FBSTFCO0VBQ0U7SUFDRSwyQ0FBc0I7SUFBdEIsbUNBQXNCLEVBQUEsRUFBQTs7QUFGMUI7RUFDRTtJQUNFLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUYxQjtFQUNFO0lBQ0UsMkNBQXNCO0lBQXRCLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUkxQjtFQUNFO0lBQ0UsMENBQXNCO0lBQXRCLGtDQUFzQixFQUFBLEVBQUE7O0FBRjFCO0VBQ0U7SUFDRSx1Q0FBc0I7SUFBdEIsa0NBQXNCLEVBQUEsRUFBQTs7QUFGMUI7RUFDRTtJQUNFLDBDQUFzQjtJQUF0Qix1Q0FBc0I7SUFBdEIsa0NBQXNCLEVBQUEsRUFBQTs7QUFJMUI7RUFDRTtJQUNFLDBDQUFzQjtJQUF0QixrQ0FBc0IsRUFBQSxFQUFBOztBQUYxQjtFQUNFO0lBQ0UsdUNBQXNCO0lBQXRCLGtDQUFzQixFQUFBLEVBQUE7O0FBRjFCO0VBQ0U7SUFDRSwwQ0FBc0I7SUFBdEIsdUNBQXNCO0lBQXRCLGtDQUFzQixFQUFBLEVBQUE7O0FBSTFCO0VBQ0U7SUFDRSwyQ0FBc0I7SUFBdEIsbUNBQXNCLEVBQUEsRUFBQTs7QUFGMUI7RUFDRTtJQUNFLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUYxQjtFQUNFO0lBQ0UsMkNBQXNCO0lBQXRCLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUsxQjt3Q0FFd0M7QUFFeEM7RUFDRTtJQUNFLFdBQVcsRUFBQSxFQUFBO0FBRmY7RUFDRTtJQUNFLFdBQVcsRUFBQSxFQUFBO0FBRmY7RUFDRTtJQUNFLFdBQVcsRUFBQSxFQUFBOztBQUlmO0VBQ0U7SUFDRSwyQ0FBc0I7SUFBdEIsbUNBQXNCLEVBQUEsRUFBQTs7QUFGMUI7RUFDRTtJQUNFLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUYxQjtFQUNFO0lBQ0UsMkNBQXNCO0lBQXRCLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUkxQjtFQUNFO0lBQ0UsMENBQXNCO0lBQXRCLGtDQUFzQixFQUFBLEVBQUE7O0FBRjFCO0VBQ0U7SUFDRSx1Q0FBc0I7SUFBdEIsa0NBQXNCLEVBQUEsRUFBQTs7QUFGMUI7RUFDRTtJQUNFLDBDQUFzQjtJQUF0Qix1Q0FBc0I7SUFBdEIsa0NBQXNCLEVBQUEsRUFBQTs7QUFHMUI7RUFDRTtJQUNFLDBDQUFzQjtJQUF0QixrQ0FBc0IsRUFBQSxFQUFBOztBQUYxQjtFQUNFO0lBQ0UsdUNBQXNCO0lBQXRCLGtDQUFzQixFQUFBLEVBQUE7O0FBRjFCO0VBQ0U7SUFDRSwwQ0FBc0I7SUFBdEIsdUNBQXNCO0lBQXRCLGtDQUFzQixFQUFBLEVBQUE7O0FBSTFCO0VBQ0U7SUFDRSwyQ0FBc0I7SUFBdEIsbUNBQXNCLEVBQUEsRUFBQTs7QUFGMUI7RUFDRTtJQUNFLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUYxQjtFQUNFO0lBQ0UsMkNBQXNCO0lBQXRCLHdDQUFzQjtJQUF0QixtQ0FBc0IsRUFBQSxFQUFBOztBQUsxQjs7d0NBR3dDO0FBRXhDOztFQUVFLHdFQUF1QztFQUF2QyxxRUFBdUM7RUFBdkMsZ0VBQXVDO0VBQ3ZDLHNDQUE4QjtFQUE5QixtQ0FBOEI7RUFBOUIsOEJBQThCLEVBQy9COztBQUVEO0VBQ0UsaUNBQXlCO0VBQXpCLDhCQUF5QjtFQUF6Qix5QkFBeUIsRUFpQjFCO0VBbEJEO0lBSUksMERBQWtEO0lBQWxELHVEQUFrRDtJQUFsRCxrREFBa0QsRUFDbkQ7RUFMSDtJQVFJLHVEQUErQztJQUEvQyxvREFBK0M7SUFBL0MsK0NBQStDLEVBQ2hEO0VBVEg7SUFZSSx3REFBZ0Q7SUFBaEQscURBQWdEO0lBQWhELGdEQUFnRCxFQUNqRDtFQWJIO0lBZ0JJLHlEQUFpRDtJQUFqRCxzREFBaUQ7SUFBakQsaURBQWlELEVBQ2xEOztBQUdIO0VBQ0UsZ0NBQXdCO0VBQXhCLDZCQUF3QjtFQUF4Qix3QkFBd0IsRUFpQnpCO0VBbEJEO0lBSUksMERBQWtEO0lBQWxELHVEQUFrRDtJQUFsRCxrREFBa0QsRUFDbkQ7RUFMSDtJQVFJLHVEQUErQztJQUEvQyxvREFBK0M7SUFBL0MsK0NBQStDLEVBQ2hEO0VBVEg7SUFZSSx3REFBZ0Q7SUFBaEQscURBQWdEO0lBQWhELGdEQUFnRCxFQUNqRDtFQWJIO0lBZ0JJLHlEQUFpRDtJQUFqRCxzREFBaUQ7SUFBakQsaURBQWlELEVBQ2xEOztBQUlIOzt3Q0FHd0M7QUFFeEM7O0VBR0ksVUFBVTtFQUNWLGtCQWhMcUIsRUFpTHBCOztBQUdMO0VBRUksYUF0THFCO0VBdUxyQiw0QkF2THFCO0VBd0xyQiwwREFBNkQsRUFDOUQ7O0FBR0g7RUFFSSxVQTlMcUI7RUErTHJCLDRCQS9McUI7RUFnTXJCLDBEQUE2RCxFQUM5RDs7QUFJSDs7d0NBR3dDO0FBRXhDOztFQUdJLFNBQVM7RUFDVCxpQkE5TXFCLEVBK010Qjs7QUFHSDtFQUVJLFdBcE5xQjtFQXFOckIsNEJBQThFO0VBQzlFLDBEQUE2RCxFQUM5RDs7QUFHSDtFQUVJLFlBNU5xQjtFQTZOckIsNEJBN05xQjtFQThOckIsMER4Q2xNZ0IsRXdDbU1qQjs7QUNoUEg7RUFDRSwwQnpDaURvQixFeUNoRHJCOztBQ0ZEO0VBQ0UsdUYxQytEb0I7RTBDL0RwQixvRjFDK0RvQjtFMEMvRHBCLCtFMUMrRG9CO0UwQzlEcEIsMEIxQ2lEcUIsRTBDaER0Qjs7QUFFRDtFQUNFLGlCQUFpQixFQUNsQjs7QUFFRDtFQUNFLGVBQWU7RUFDZixhQUFhO0VBQ2IsYUFBYSxFQUNkOztBQ2JEO0VBQ0UsZ0IzQzJGd0I7RTJDMUZ4QixpQjNDNkd3QjtFMkM1R3hCLG9CM0M0R3dCLEUyQzNHekI7O0FDSkQ7RVhPRSxlQUhlO0VBSWYsb0JBQW9CO0VBQ3BCLGlCQUFpQjtFQUNqQix3QkFBd0I7RUFDeEIsZ0JBUmdCLEVXRGpCOztBQ0ZEO3dDQUV3QztBQUV4QztFQUNFLDJCQUEwQyxFQUMzQzs7QUFFRDtFQUNFLDJCQUF5QyxFQUMxQzs7QUFHRDt3Q0FFd0M7QUFFeEM7RUFDRSwwQkFBK0IsRUFDaEM7O0FBRUQ7RUFDRSwwQkFBZ0MsRUFDakM7O0FBRUQ7RUFDRSwwQkFBZ0MsRUFDakM7O0FBRUQ7RUFDRSwwQkFBZ0MsRUFDakM7O0FBRUQ7RUFDRSwwQkFBZ0MsRUFDakM7O0FBRUQ7RUFDRSwwQkFBZ0MsRUFDakM7O0FBRUQ7RUFDRSwwQkFBaUMsRUFDbEM7O0FBRUQ7RUFDRSwwQkFBa0MsRUFDbkM7O0FBRUQ7RUFDRSwwQkFBK0IsRUFDaEM7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0UscUNBQXFDLEVBQ3RDOztBQUdEO0VBQ0UsOEJBQThCLEVBQy9COztBQUVEO0VBQ0UsNkJBQTZCLEVBQzlCOztBQUdEO3dDQUV3QztBQUV4QztFQUNFLDJCQUEwQyxFQUMzQzs7QUFHRDt3Q0FFd0M7QUFFeEM7RUFDRSw4QkFBOEIsRUFDL0I7O0FBR0Q7d0NBRXdDO0FBRXhDO0VBQ0UsMEJBQTBCLEVBQzNCOztBQUVEO0VBQ0UsNEJBQTRCLEVBQzdCOztBQUVEO0VBQ0UsNkJBQTZCLEVBQzlCOztBQUVEO0VBQ0UsMkJBQTJCLEVBQzVCOztBQUdEO3dDQUV3QztBQUV4QztFQUNFLHlCQUF5QixFQUMxQiIsImZpbGUiOiJkYXNoYm9hcmQtdWkuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgR3JpZFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuJGdyaWRfd2lkdGg6IDEwNzBweDtcbiRncmlkX2d1dHRlcjogMzBweDtcbiRncmlkX3VuaXRfd2lkdGg6IDM1cHg7XG4kZ3JpZF9tYXhfY29sczogMTY7XG5cblxuLy8gb3ZlcnJpZGluZyBkZWZhdWx0IHZhcmlhYmxlc1xuXG4kYXYtbmFtZXNwYWNlOiAnbC1ncmlkJztcbiRhdi1ndXR0ZXI6ICRncmlkX2d1dHRlcjtcbiRhdi13aWR0aC1jbGFzcy1uYW1lc3BhY2U6ICdsLWdyaWRfX2NlbGwtLSc7XG4kYXYtd2lkdGhzOiAoXG4gIDIsXG4gIDMsXG4gIDQsXG4gIDUsXG4gIDYsXG4gIDgsXG4gIDEwLFxuICAxMixcbiAgMTQsXG4gIDE2XG4pO1xuXG4kYXYtYnJlYWtwb2ludHM6ICAoXG4gIFwiaGFuZGhlbGRcIjogICAgICAgICBcInNjcmVlbiBhbmQgKG1heC13aWR0aDogODAwcHgpXCIsXG4gIFwibGFwXCI6ICAgICAgICAgICAgICBcInNjcmVlbiBhbmQgKG1pbi13aWR0aDogODAxcHgpXCIsXG4gIFwiZGVza1wiOiAgICAgICAgICAgICBcInNjcmVlbiBhbmQgKG1pbi13aWR0aDogMTA3MHB4KVwiLFxuICBcIndpZGVzY3JlZW5cIjogICAgICAgXCJzY3JlZW4gYW5kIChtaW4td2lkdGg6IDE2ODBweClcIixcbiAgXCJyZXRpbmFcIjogICAgICAgICAgIFwic2NyZWVuIGFuZCAoLXdlYmtpdC1taW4tZGV2aWNlLXBpeGVsLXJhdGlvOiAyKSwgc2NyZWVuIGFuZCAobWluLXJlc29sdXRpb246IDE5MmRwaSksIHNjcmVlbiBhbmQgKG1pbi1yZXNvbHV0aW9uOiAyZHBweClcIlxuKTtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICBDb2xvciBQYWxldHRlXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vLyBNYWluIGNvbG9yc1xuJGNvbG9yX2NyeXN0YWw6ICMxZTg4ZTUgIWRlZmF1bHQ7XG4kY29sb3JfY3J5c3RhbF9hY3RpdmU6ICMxNzc4Y2QgIWRlZmF1bHQ7XG4kY29sb3JfamVzc2U6ICMyMTMzNDggIWRlZmF1bHQ7XG4kY29sb3JfdHVjbzogIzM3NDc1YSAhZGVmYXVsdDtcbiRjb2xvcl9ndXN0YXZvOiAjOTBhNGFlICFkZWZhdWx0O1xuJGNvbG9yX2dvb2RtYW46ICNhNmI2YmUgIWRlZmF1bHQ7XG4kY29sb3JfaGFuazogIzU2NmQ4OCAhZGVmYXVsdDtcbiRjb2xvcl9oZXJtYW5vczogI2RkZTRlYSAhZGVmYXVsdDtcbiRjb2xvcl9za3lsZXI6ICNmNGY0ZjQgIWRlZmF1bHQ7XG4kY29sb3JfbXJ3aGl0ZTogI2ZmZmZmZiAhZGVmYXVsdDtcblxuLy8gU3RhdHVzIGNvbG9yc1xuJGNvbG9yX3dhcm5pbmc6ICNmZmMxMDcgIWRlZmF1bHQ7XG4kY29sb3Jfd2FybmluZ19hY3RpdmU6ICNmNWIyMDcgIWRlZmF1bHQ7XG5cbiRjb2xvcl9zdWNjZXNzOiAjNGNhZjUwICFkZWZhdWx0O1xuJGNvbG9yX3N1Y2Nlc3NfYWN0aXZlOiAjNDJhMTQ2ICFkZWZhdWx0O1xuXG4kY29sb3JfZGFuZ2VyOiAjZjQ0MzM2ICFkZWZhdWx0O1xuJGNvbG9yX2Rhbmdlcl9hY3RpdmU6ICNlODNlMzIgIWRlZmF1bHQ7XG5cbi8vIFNoYWRvdyBjb2xvcnNcbiRjb2xvcl9zaGFkb3c6ICMwZDFhMmIgIWRlZmF1bHQ7XG5cbi8vIFNvY2lhbCBjb2xvcnNcbiRjb2xvcl9mYWNlYm9vazogIzNhNmFjZSAhZGVmYXVsdDtcbiRjb2xvcl9mYWNlYm9va19hY3RpdmU6ICMzMzVmYmIgIWRlZmF1bHQ7XG5cbiRjb2xvcl90d2l0dGVyOiAjMjBhOGUyICFkZWZhdWx0O1xuJGNvbG9yX3R3aXR0ZXJfYWN0aXZlOiAjMTY5N2NjICFkZWZhdWx0O1xuXG4kY29sb3JfZ29vZ2xlOiAjZGMzNjNjICFkZWZhdWx0O1xuJGNvbG9yX2dvb2dsZV9hY3RpdmU6ICNkMDM0M2EgIWRlZmF1bHQ7XG5cbiRjb2xvcl9kcnVwYWw6ICMwMmIyZWMgIWRlZmF1bHQ7XG4kY29sb3JfZHJ1cGFsX2FjdGl2ZTogZGFya2VuKCMwMmIyZWMsIDUlKSAhZGVmYXVsdDtcblxuJGNvbG9yX3dvcmRwcmVzczogIzAwYmNkNCAhZGVmYXVsdDtcbiRjb2xvcl93b3JkcHJlc3NfYWN0aXZlOiBkYXJrZW4oIzAwYmNkNCwgNSUpICFkZWZhdWx0O1xuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIEZvbnQgU2V0dGluZ3NcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi8vIEZvbnQgRmFtaWx5XG4kZm9udF9mYW1pbHlfcHJpbWFyeTogJ1JvYm90b3gnLCBzYW5zLXNlcmlmICFkZWZhdWx0O1xuXG4vLyBGb250IHNpemVcbiRmb250X3NpemVfcHJpbWFyeTogMTZweCAhZGVmYXVsdDtcbiRmb250X3NpemVfc2Vjb25kYXJ5OiAxNHB4ICFkZWZhdWx0O1xuJGZvbnRfc2l6ZV90ZXJ0aWFyeTogMTJweCAhZGVmYXVsdDtcblxuJGljb25fc2l6ZV9wcmltYXJ5OiAxOHB4ICFkZWZhdWx0O1xuJGljb25fc2l6ZV9zZWNvbmRhcnk6IDI0cHggIWRlZmF1bHQ7XG5cbi8vIEZvbnQgd2VpZ2h0XG4kZm9udF93ZWlnaHRfbWVkaXVtOiA2MDAgIWRlZmF1bHQ7XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgU3BhY2luZ3NcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRzcGFjaW5nX3VuaXRfcHJpbWFyeTogMTBweCAhZGVmYXVsdDtcbiRzcGFjaW5nX3VuaXRfc2Vjb25kYXJ5OiAxNXB4ICFkZWZhdWx0O1xuJHNwYWNpbmdfdW5pdF90ZXJ0aWFyeTogMjBweCAhZGVmYXVsdDtcbiRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTogMzBweCAhZGVmYXVsdDtcbiRzcGFjaW5nX3VuaXRfcXVpbmFyeTogNDBweCAhZGVmYXVsdDtcbiRzcGFjaW5nX3VuaXRfc2VuYXJ5OiA2MHB4ICFkZWZhdWx0O1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICBCb3ggU2hhZG93c1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuJGJveF9zaGFkb3dfcHJpbWFyeTpcblx0MCAwIDJweCByZ2JhKCRjb2xvcl9zaGFkb3csIDAuMTIpLFxuXHQwIDFweCAxcHggcmdiYSgkY29sb3Jfc2hhZG93LCAwLjI0KVxuXHQhZGVmYXVsdDtcbiRib3hfc2hhZG93X3NlY29uZGFyeTpcblx0MCAycHggM3B4IHJnYmEoJGNvbG9yX3NoYWRvdywgMC4xNiksXG5cdDAgMXB4IDRweCByZ2JhKCRjb2xvcl9zaGFkb3csIDAuMjMpXG5cdCFkZWZhdWx0O1xuJGJveF9zaGFkb3dfdGVydGlhcnk6XG5cdDAgMnB4IDNweCByZ2JhKCRjb2xvcl9zaGFkb3csIDAuMTYpLFxuXHQwIDVweCA2cHggcmdiYSgkY29sb3Jfc2hhZG93LCAwLjIpXG5cdCFkZWZhdWx0O1xuJGJveF9zaGFkb3dfcXVhdGVybmFyeTpcblx0MCAycHggM3B4IHJnYmEoJGNvbG9yX3NoYWRvdywgMC4xNiksXG5cdDAgMTBweCAxMHB4IHJnYmEoJGNvbG9yX3NoYWRvdywgMC4yMylcblx0IWRlZmF1bHQ7XG4kYm94X3NoYWRvd19xdWluYXJ5OlxuXHQwIDAgM3B4IHJnYmEoJGNvbG9yX3NoYWRvdywgMC4xNiksXG5cdDAgMTVweCAxOHB4IHJnYmEoJGNvbG9yX3NoYWRvdywgMC4yNClcblx0IWRlZmF1bHQ7XG5cbiRib3hfc2hhZG93X2JvdHRvbV9wcmltYXJ5OlxuICAwcHggMXB4IDJweCAtMXB4IHJnYmEoMTMsIDI2LCA0MywgMC4xMiksXG4gIDAgMnB4IDFweCAtMXB4IHJnYmEoMTMsIDI2LCA0MywgMC4yNClcbiAgIWRlZmF1bHQ7XG4kYm94X3NoYWRvd19ib3R0b21fc2Vjb25kYXJ5OlxuICAwIDNweCAzcHggLTFweCByZ2JhKDEzLCAyNiwgNDMsIDAuMTYpLFxuICAwIDVweCA0cHggLTRweCByZ2JhKDEzLCAyNiwgNDMsIDAuMjMpXG4gICFkZWZhdWx0O1xuJGJveF9zaGFkb3dfYm90dG9tX3RlcnRpYXJ5OlxuICAwIDJweCAzcHggcmdiYSgkY29sb3Jfc2hhZG93LCAwLjE2KSxcbiAgMCA1cHggNnB4IHJnYmEoJGNvbG9yX3NoYWRvdywgMC4yKVxuICAhZGVmYXVsdDtcbiRib3hfc2hhZG93X2JvdHRvbV9xdWF0ZXJuYXJ5OlxuICAwIDJweCAzcHggcmdiYSgkY29sb3Jfc2hhZG93LCAwLjE2KSxcbiAgMCAxMHB4IDEwcHggcmdiYSgkY29sb3Jfc2hhZG93LCAwLjIzKVxuICAhZGVmYXVsdDtcbiRib3hfc2hhZG93X2JvdHRvbV9xdWluYXJ5OlxuICAwIDFweCAzcHggLTFweCByZ2JhKCRjb2xvcl9zaGFkb3csIDAuMTYpLFxuICAwIDE1cHggMThweCByZ2JhKCRjb2xvcl9zaGFkb3csIDAuMjQpXG4gICFkZWZhdWx0O1xuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIEJvcmRlcnNcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRib3JkZXJfcmFkaXVzX3ByaW1hcnk6IDNweCAhZGVmYXVsdDtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICBUcmFuaXN0aW9uc1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuJHRyYW5zaXRpb25fcHJpbWFyeTogYWxsIC4ycyBlYXNlLWluLW91dCAhZGVmYXVsdDtcbiR0cmFuc2l0aW9uX3NlY29uZGFyeTogYWxsIC44cyBlYXNlLWluLW91dCAhZGVmYXVsdDtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICBaLWluZGV4XG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4kel9pbmRleDogKFxuICBiYXNlOiAwLFxuICByaWJib246IDUwLFxuICBkcm9wZG93bjogMTAwMCxcbiAgb3ZlcmxheTogMjAwMDAsXG4gIHNuYWNrYmFyOiAzMDAwMCxcbiAgbW9kYWw6IDUwMDAwLFxuICB0b29sdGlwOiA2MDAwMFxuKSAhZGVmYXVsdDtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICBTVkdcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRzdmdfdXNlcjogJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5Qm9aV2xuYUhROUlqSTBJaUJtYVd4c1BTSWpZekZrTW1SbUlpQjJhV1YzUW05NFBTSXdJREFnTWpRZ01qUWlJSGRwWkhSb1BTSXlOQ0lnZUcxc2JuTTlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TURBdmMzWm5JajQ4Y0dGMGFDQmtQU0pOTVRJZ01USmpNaTR5TVNBd0lEUXRNUzQzT1NBMExUUnpMVEV1TnprdE5DMDBMVFF0TkNBeExqYzVMVFFnTkNBeExqYzVJRFFnTkNBMGVtMHdJREpqTFRJdU5qY2dNQzA0SURFdU16UXRPQ0EwZGpKb01UWjJMVEpqTUMweUxqWTJMVFV1TXpNdE5DMDRMVFI2SWk4K1BIQmhkR2dnWkQwaVRUQWdNR2d5TkhZeU5FZ3dlaUlnWm1sc2JEMGlibTl1WlNJdlBqd3ZjM1puUGc9PSc7XG4kc3ZnX3dvcmxkOiAnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCcFpEMGlkMjl5YkdRdWMzWm5JaUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGRwWkhSb1BTSTRNQ0lnYUdWcFoyaDBQU0k0TUNJZ2RtbGxkMEp2ZUQwaU1DQXdJRGd3SURnd0lqNDhaR1ZtY3o0OGMzUjViR1UrTG1Oc2N5MHlMQ0F1WTJ4ekxUTWdleUJtYVd4c0xYSjFiR1U2SUdWMlpXNXZaR1E3SUgwZ0xtTnNjeTB5SUhzZ2IzQmhZMmwwZVRvZ01DNHhOVHNnZlNBdVkyeHpMVE1nZXlCbWFXeHNPaUFqWm1abU95QjlQQzl6ZEhsc1pUNDhMMlJsWm5NK1BIQmhkR2dnYVdROUlrVnNiR2x3YzJWZk56QTJYMk52Y0hsZk55SWdaR0YwWVMxdVlXMWxQU0pGYkd4cGNITmxJRGN3TmlCamIzQjVJRGNpSUdOc1lYTnpQU0pqYkhNdE1pSWdaRDBpVFRRMkxqZ3pJRGM1TGpRd04wd3lNaTQwTnpjZ05UVXVNRFV6YkM0eU15MHVNak5oTWpNdU5EZ2dNak11TkRnZ01DQXdJREVnTXpNdU1URTJMVE16TGpFeE5td3VNRE0xTFM0d016VXVOelF5TGpjek4zRXVOVEV6TGpRNE1pQXhJREZzTWpJdU1ESXlJREl5TGpBeU5tRTBNQzR3TVRNZ05EQXVNREV6SURBZ01DQXhMVE15TGpjNU1pQXpNeTQ1TjNvaUx6NDhjR0YwYUNCcFpEMGlVMmhoY0dWZk56RTFYMk52Y0hsZk1pSWdaR0YwWVMxdVlXMWxQU0pUYUdGd1pTQTNNVFVnWTI5d2VTQXlJaUJqYkdGemN6MGlZMnh6TFRNaUlHUTlJazAwTUM0MUlEVTBMamMxTlZZMk0yTXRMalF3TlNBd0xTNDRNUzB1TURFdE1TNHlNUzB1TURNdExqQXdOaUF3TFM0d01EWXRMakF3TlMwdU1ERXlJREJoTGpBek5TNHdNelVnTUNBd0lEQXRMakF5TXkwdU1EQTFZeTB1TVRRdExqQXdOUzB1TWpnNExTNHdNVGN0TGpRekxTNHdNak54TFM0ek56Z3RMakF5TmkwdU56VTNMUzR3TjJNdExqSTFNeTB1TURJekxTNDFMUzR3TlRJdExqYzFNaTB1TURnM2N5MHVORGswTFM0d055MHVOelF0TGpFeFl5MHVOelU0TFM0eE15MHhMalV4TFM0eU9UTXRNaTR5TkRRdExqUTVNaTB1TVRneUxTNHdORFl0TGpNMk5DMHVNUzB1TlRRdExqRTFNaTB1TVMwdU1ESTRMUzR5TFM0d05UY3RMak10TGpBNU1pMHVNVGMzTFM0d05EWXRMak0wT0MwdU1UQTFMUzQxTWpRdExqRTJNMnd0TGpVME5pMHVNVGt6WXkwdU1qSXpMUzR3T0RJdExqUTBOaTB1TVRjdExqWTNMUzR5TlRkekxTNDBOQzB1TVRndExqWTFPQzB1TWpjMFl5MHVORE0xTFM0eE9EWXRMamczTFM0ek9TMHhMakk1TXkwdU5qQTFMUzR4TmpRdExqQTRPQzB1TXpNMExTNHhOell0TGpVdExqSTJNeTB1TWpNMExTNHhNeTB1TkRjMUxTNHlOVGN0TGpjdExqTTVNaTB1TlRVM0xTNHpNall0TVM0eExTNDJOemN0TVM0Mk1pMHhMakEwTkMwdU1UZ3pMUzR4TWpJdExqTTJMUzR5TlMwdU5UTTJMUzR6T0RSc0xTNDBORGN0TGpNMFl5MHVOVFU0TFM0ME15MHhMakE1TXkwdU9Ea3RNUzQyTFRFdU16Y3RMakUzTFM0eE5qTXRMak0wTFM0ek1qWXRMalV3TlMwdU5EbHpMUzR6TWpNdExqTXlOaTB1TkRneUxTNDBPV010TGpRM05pMHVOUzB1T1RJNExURXVNREl0TVM0ek5UY3RNUzQxTlRndExqSTBOeTB1TXpFdExqUTRNaTB1TmpJMExTNDNNUzB1T1RRMUxTNHhNRGN0TGpFMU15MHVNakU0TFM0ekxTNHpNalF0TGpRMk1uTXRMakl5TFM0ek1EZ3RMak15TFM0ME5qaHNMUzR6TFM0ME56TnhMUzR6TFM0ME9ESXRMalUyTkMwdU9UaGpMUzR3T0RndExqRTJOQzB1TVRjMkxTNHpNek10TGpJMk5DMHVOWE10TGpFM0xTNHpOQzB1TWpVekxTNDFNRGd0TGpFMk5pMHVNelExTFM0eU5ESXRMalV4TldNdExqQTRPQzB1TVRnM0xTNHhOeTB1TXpZdExqSTBOeTB1TlRRNExTNHhOQzB1TXpRdExqSTNOUzB1TmpnMExTNDBNRFF0TVM0d01qZ3RMakEzTFM0eE9EZ3RMakUwTFM0ek9DMHVNaTB1TlRZM0xTNHdOaTB1TVRZekxTNHhNVEl0TGpNeU5pMHVNVFl0TGpRNUxTNHdOalF0TGpFNU15MHVNVEl5TFM0ek9EVXRMakUzTlMwdU5UYzNjeTB1TVRBMUxTNHpOek10TGpFMU1pMHVOVFpqTFM0d055MHVNamd0TGpFMExTNDFOaTB1TWkwdU9EUnpMUzR4TWpNdExqVTNNaTB1TVRjdExqZzFPR0V1T1RjMExqazNOQ0F3SURBZ01TMHVNREl6TFM0eE1qaGpMUzR3TkRjdExqSTBOaTB1TURneUxTNDBPUzB1TVRFNExTNDNNelV0TGpBMExTNHlPVEl0TGpBM05pMHVOVGcwTFM0eE1EWXRMamc0TWkwdU1ESXpMUzR5TFM0d05DMHVOQzB1TURVeUxTNDFPRGhoTGpJdU1pQXdJREFnTVMwdU1EQTJMUzR3Tm1NdExqQXhOeTB1TWpVMUxTNHdNelV0TGpVd05pMHVNRFF0TGpjMk0yRXVPVGt1T1RrZ01DQXdJREV0TGpBd055MHVNVE0wWXkwdU1ERXRMakk0TFM0d01UVXRMalUyTWkwdU1ERTFMUzQ0TkNBd0xTNDBNaTR3TVRJdExqZzBNaTR3TXpVdE1TNHlOVFl1TURFeUxTNHlNelF1TURJekxTNDBOamN1TURRM0xTNDJPVFV1TURFeUxTNHhORFl1TURJekxTNHlPUzR3TkMwdU5ETTRMakExTkMwdU5UWTJMakV6TmkweExqRXlOaTR5TXkweExqWTNOUzR3TXpVdExqRTVNeTR3TnkwdU16Y3pMakV4TWkwdU5UWTNZUzR4TmpNdU1UWXpJREFnTUNBeElDNHdNVEl0TGpBMU4yTXVNRFV6TFM0eU9TNHhNVGN0TGpVM055NHhPRGd0TGpnMU55NHhOalF0TGpZMk5pNHpOVGd0TVM0ek1UZ3VOVGMyTFRFdU9UVTFiREl1T0RVZ01pNDRNalJoTVM0eE16WWdNUzR4TXpZZ01DQXdJREVnTGpFNElERXVOQ0ExTGpVM055QTFMalUzTnlBd0lEQWdNQ0F1TlRjZ05pNHpOeUF4TGpReElERXVOREVnTUNBd0lEQWdMakkyTlM0eU5qTWdOUzQyT0NBMUxqWTRJREFnTUNBd0lEWXVOREUyTGpVMk5pQXhMakUxTlNBeExqRTFOU0F3SURBZ01TQXhMalF4TGpFNE1td3pMalV3T0NBekxqUTRNeTR4T0RJdU1UaGhNeTQwTnpZZ015NDBOellnTUNBd0lEQWdMak0zTmlBeUxqa2dNUzR3TnpVZ01TNHdOelVnTUNBd0lEQWdMalExT0M0ME5UY2dNeTQ0TWpVZ015NDRNalVnTUNBd0lEQWdNaTR6TlM0MU1UTWdNUzR5TVRNZ01TNHlNVE1nTUNBd0lERWdNUzR3TXpRdU16SnNNaTR6TVRVZ01pNHpZVEV1TVRZNElERXVNVFk0SURBZ01DQXhJQzR6TkRjdU9ETjZUVFkwSURNNUxqWTJOMkV5TXk0d05UWWdNak11TURVMklEQWdNQ0F4TFRFdU16RTJJRGN1TjJ3dE5pNDVOUzAyTGpsaE1TNHhOeUF4TGpFM0lEQWdNQ0F3TFRFdU5qVTNMakF3Tld3dE55NDRPU0EzTGpnek5tRXhMakUzTXlBeExqRTNNeUF3SURBZ01TMHhMalkyTXlBd2JDMHlMakE0TFRJdU1EWTFZVEV1TVRVMklERXVNVFUySURBZ01DQXhJREF0TVM0Mk5EVnNNaTQxTFRJdU5EaGhNUzR4TlRnZ01TNHhOVGdnTUNBd0lEQWdNQzB4TGpZME5Xd3ROeTR3TmpndE55NHdNVGhoTVM0eE5UY2dNUzR4TlRjZ01DQXdJREVnTUMweExqWTBOV3d6TGpjME1pMHpMamN4TjJFeExqRTFOeUF4TGpFMU55QXdJREFnTUNBd0xURXVOalExYkMweExqWTNMVEV1TmpVNFlURXVNVFUySURFdU1UVTJJREFnTUNBeElEQXRNUzQyTkRWc05pNHhPRFl0Tmk0eE16aEJNak11TXpneUlESXpMak00TWlBd0lEQWdNU0EyTkNBek9TNDJOamQ2SWk4K1BDOXpkbWMrJztcbiRzdmdfd29yZHByZXNzOiAnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCcFpEMGlkMjl5WkhCeVpYTnpMbk4yWnlJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWlCM2FXUjBhRDBpT0RBaUlHaGxhV2RvZEQwaU9EQWlJSFpwWlhkQ2IzZzlJakFnTUNBNE1DQTRNQ0krUEdSbFpuTStQSE4wZVd4bFBpNWpiSE10TWl3Z0xtTnNjeTB6SUhzZ1ptbHNiQzF5ZFd4bE9pQmxkbVZ1YjJSa095QjlJQzVqYkhNdE1pQjdJRzl3WVdOcGRIazZJREF1TVRVN0lIMGdMbU5zY3kweklIc2dabWxzYkRvZ0kyWm1aanNnZlR3dmMzUjViR1UrUEM5a1pXWnpQanh3WVhSb0lHbGtQU0pGYkd4cGNITmxYemN3Tmw5amIzQjVYemdpSUdSaGRHRXRibUZ0WlQwaVJXeHNhWEJ6WlNBM01EWWdZMjl3ZVNBNElpQmpiR0Z6Y3owaVkyeHpMVElpSUdROUlrMDBOaTQxTnpVZ056a3VORFV6VERJeUlEVTFjeTAzTGpRNU5DMHhPQzR3TWpjdE1pNDNNell0TWpVdU5FTXlOaTQxT1RRZ01UZ3VNalVnTkRjdU9EZ3lJREl3TGpnNElEUTRJREl4WVRVdU9UUTRJRFV1T1RRNElEQWdNQ0F4SURZdU1qQTFJREV1TlRVMWJESTFMakEyTWlBeU5TNHdOakpoTkRBdU1ESTJJRFF3TGpBeU5pQXdJREFnTVMwek1pNDJPVElnTXpFdU9ETTJlaUl2UGp4d1lYUm9JR2xrUFNKVGFHRndaVjgzTVRSZlkyOXdlVjh5SWlCa1lYUmhMVzVoYldVOUlsTm9ZWEJsSURjeE5DQmpiM0I1SURJaUlHTnNZWE56UFNKamJITXRNeUlnWkQwaVRURTVMallnTWpndU9ERXlRVEl5TGprd055QXlNaTQ1TURjZ01DQXdJREVnTkRBZ01UZGhNak11TXpRZ01qTXVNelFnTUNBd0lERWdNVFV1TURJZ05TNDRPU0ExTGpNMElEVXVNelFnTUNBd0lEQXRNeTQyTnpVdU56VWdOUzR4TlRRZ05TNHhOVFFnTUNBd0lEQXRMakE1SURndU9UQTRZekl1TkNBeExqVWdNeTR5TlRVZ05TNHlORFVnTXk0eE56VWdOeTQxTXpOekxUVXVOVGdnTVRJdU9ESTFMVFV1TlRnZ01USXVPREkxYkMwMUxqTTFOaTB4T0M0ek5USnpMUzR4T0RVdE1TNHlPRGN0TGpFNE5TMHhMalkyWVRJdU1qTXpJREl1TWpNeklEQWdNQ0F4SUM0ME5ETXRNUzR6TnlBeExqVTBJREV1TlRRZ01DQXdJREVnTGpnMk5DMHVOamMwYURJdU5UTTRWakk0TGpneGFDMHhNeTQ0ZGpJdU1EUm9MalF5TmtFeUxqWTNPQ0F5TGpZM09DQXdJREFnTVNBek5TNHhJRE14TGpsakxqVXVOVEUzSURFdU1UTTRJREl1TkRjZ01TNDVNRGNnTkM0MWJESXVNREEzSURZdU5pMDBMak15TmlBNUxqazNNaTAwTGpjME15MHhPUzQ1TTJFMExqRTJPQ0EwTGpFMk9DQXdJREFnTVNBdU5ESTJMVEV1TmlBeExqVTNNaUF4TGpVM01pQXdJREFnTVNBdU9EQTNMUzQxT0RKb0xqRXpkaTB5TGpBME9FZ3hPUzQyZW0weUxqY3dOaUF6TGpRMk5HRXpMamMwSURNdU56UWdNQ0F3SURBdE1pNHpMVEV1TkRJMGFDMHhMakpoTWpNdU1pQXlNeTR5SURBZ01DQXdMVEV1T0NBNUxqRXhOU0F5TWk0M056WWdNakl1TnpjMklEQWdNQ0F3SURFMExqQTNJREl3TGprNU1ucHRNemN1TkRrdE15NDJORFpoTVRRdU56SXpJREUwTGpjeU15QXdJREFnTVMwdU5UQTJJRGN1TXpReVl5MHlMakl5TkNBM0xqRTROUzAzTGpjeklESXdMakV4TFRrdU9EWWdNalV1TURNMFFUSXlMamMyTnlBeU1pNDNOamNnTUNBd0lEQWdOak1nTkRBdU1qTmhNakl1TlRFMUlESXlMalV4TlNBd0lEQWdNQzB6TGpJd055MHhNUzQyZW0wdE1Ua3VNek1nTVRrdU5Hd3ROUzQ0T0NBeE5DNHpNelZoTWpNdU1qWXpJREl6TGpJMk15QXdJREFnTUNBeE1TNHdNVGN0TGpBME1ucHRNQ0F3SWk4K1BDOXpkbWMrJztcbiRzdmdfZHJ1cGFsOiAnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCcFpEMGlaSEoxY0dGc0xuTjJaeUlnZUcxc2JuTTlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TURBdmMzWm5JaUIzYVdSMGFEMGlPREFpSUdobGFXZG9kRDBpT0RBaUlIWnBaWGRDYjNnOUlqQWdNQ0E0TUNBNE1DSStQR1JsWm5NK1BITjBlV3hsUGk1amJITXRNaXdnTG1Oc2N5MHpJSHNnWm1sc2JDMXlkV3hsT2lCbGRtVnViMlJrT3lCOUlDNWpiSE10TWlCN0lHOXdZV05wZEhrNklEQXVNVFU3SUgwZ0xtTnNjeTB6SUhzZ1ptbHNiRG9nSTJabVpqc2dmVHd2YzNSNWJHVStQQzlrWldaelBqeHdZWFJvSUdsa1BTSkZiR3hwY0hObFh6Y3dObDlqYjNCNVh6a2lJR1JoZEdFdGJtRnRaVDBpUld4c2FYQnpaU0EzTURZZ1kyOXdlU0E1SWlCamJHRnpjejBpWTJ4ekxUSWlJR1E5SWswM09TNDBORElnTkRZdU5qTXpRVFF3TGpBeUlEUXdMakF5SURBZ01DQXhJRFEyTGpreU5pQTNPUzR6T1V3eU1pNDJJRFUzY3pFeUxqVXhNeUF5TGpNeE1pQXpMamswTFRVdU16UmpMVGt1TVRreUxUZ3VNakE0TFRNdU5TMDRMalU1TXkwdU5UTTNMVEUwTGpZMklEUXVORE0wTFRrdU1EYzBJRE13TGpJdE1UTXVOakExSURNd0xqSXRNVE11TmpBMWVpSXZQanh3WVhSb0lHbGtQU0pHYjNKdFlWOHhYMk52Y0hsZk1pSWdaR0YwWVMxdVlXMWxQU0pHYjNKdFlTQXhJR052Y0hrZ01pSWdZMnhoYzNNOUltTnNjeTB6SWlCa1BTSk5OVEl1TVRFeUlESXdMams0TjJNdE1pNDNOUzB4TGpjd09DMDFMak16TlMweUxqTTNOaTAzTGprek5pMDBMakE0TmkweExqWXhMVEV1TURnMkxUTXVPRFEwTFRNdU5qYzNMVFV1TnpJeUxUVXVPUzB1TXpRMElETXVOVGt0TVM0ME1qUWdOUzR3TmpJdE1pNDJOallnTmk0eE1EaGhNemd1TVRjMklETTRMakUzTmlBd0lEQWdNUzAyTGpVMU55QXpMamszT0dNdE1TNDVJREV0TVRJdU15QTNMakkzTnkweE1pNHlNeklnTWpBdU56RTBMakEwTnlBeE15NDBNak1nTVRFdU16SWdNak11TWpjZ01qTXVPQ0F5TXk0eUlERXlMalEzTXkwdU1EUTNJREl6TGpJMU5pMDVMakl4TWlBeU15NHlMVEl5TGprNFlUSTBMalEzTlNBeU5DNDBOelVnTUNBd0lEQXRNVEV1T0RnMkxUSXhMakF6TTNwdExqTTJPQ0F6T0M0M01tRXhNUzR5SURFeExqSWdNQ0F3SURFdE5TNDBNalFnTWk0eU1USmpMVEl1T0M0eU56WXROaTQxT0M0ME15MDRMamcxTnkweExqWTBZUzQzTXpndU56TTRJREFnTUNBeExTNHdNVFF0TVM0d09DQXhMakUzTWlBeExqRTNNaUF3SURBZ01TQXVOemMwTFM0ek56SXVORFl5TGpRMk1pQXdJREFnTVNBdU5ERTNMakZqTVM0d05EY3VPRE15SURJdU5UazFJREV1TkRreUlEVXVPU0F4TGpRNE0yRXhNUzQxTlNBeE1TNDFOU0F3SURBZ01DQTJMalk0TkMweExqYzFZeTQwTmpVdExqTTFMalkyTFM0d05TNDNNek11TVRZMFlTNDRNaTQ0TWlBd0lEQWdNUzB1TWpFekxqZzRNbnB0TFRndU9Ua3pMVFF1TXpReVlUa3VNelU0SURrdU16VTRJREFnTUNBeElESXVNemcxTFRFdU56STBJRFF1TlNBMExqVWdNQ0F3SURFZ01pNHhOak10TGpNeU55QTBMakk1TkNBMExqSTVOQ0F3SURBZ01TQXlMak0wTGpRMk15QXpMamsxSURNdU9UVWdNQ0F3SURFZ01TNHhPVElnTVM0NE5UZ3VOelEyTGpjME5pQXdJREFnTVMwdU5EQTRJREV1TURVMVl5MHVNell6TGpJdExqUXhOQzR4TFM0M09ESXRMalU0TWkwdU16UTJMUzQyTmpRdExqWTJOeTB4TGpNMUxUSXVORGcxTFRFdU16UTJZVFF1TWpJM0lEUXVNakkzSURBZ01DQXdMVE11TWpZZ01TNHpPR010TGpnM01pNDNNek10TVM0eE9UTXVPVGd0TVM0ME9EVXVOVFl5TFM0ek1pMHVOREEwTFM0eU1qWXRMamd5TkM0ek5DMHhMak0wZW0weE9DNDJOQzB4TUdFeE1pNDFOeUF4TWk0MU55QXdJREFnTVMweExqY3lNeUEyTGpNME4yTXRNUzR5TXpJZ01TNDRNemd0TWk0d01TQXlMalV5TlMwekxqUTNJREl1TkRBM0xURXVPRFV0TGpFME5pMDFMall4TWkwMUxqazBOUzAzTGprNU15MDJMakEwTFRNdExqQTVNeTA1TGpVZ05pNHpNemd0TVRRdU5qSWdOaTR6TlMwekxqRXhOUzR3TVMwMExqQTBMUzQwTlRndE5TNHdPRGN0TVM0eE1tRTFMallnTlM0MklEQWdNQ0F4TFRJdU15MDFMakEwTW1NdU1EUXROQzR3TmpZZ015NDRMVGN1T0RjZ09DNDFOalV0Tnk0NU5TQTJMakExTkMwdU1EWXlJREV3TGpJM05pQTJJREV6TGpNek5pQTFMamt6SURJdU5UZzBMUzR3TlRVZ055NDFOQzAxTGpFNUlEa3VPVFk0TFRVdU1Ua3pJREl1TlRnNExTNHdNRFlnTXk0ek1qSWdNaTQyT0RnZ015NHpNalFnTkM0ek1Yb2lMejQ4TDNOMlp6ND0nO1xuJHN2Z19mYWNlYm9vazogJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QnBaRDBpWm1JdWMzWm5JaUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGRwWkhSb1BTSTRNQ0lnYUdWcFoyaDBQU0k0TUNJZ2RtbGxkMEp2ZUQwaU1DQXdJRGd3SURnd0lqNDhaR1ZtY3o0OGMzUjViR1UrTG1Oc2N5MHlMQ0F1WTJ4ekxUTWdleUJtYVd4c0xYSjFiR1U2SUdWMlpXNXZaR1E3SUgwZ0xtTnNjeTB5SUhzZ2IzQmhZMmwwZVRvZ01DNHhOVHNnZlNBdVkyeHpMVE1nZXlCbWFXeHNPaUFqWm1abU95QjlQQzl6ZEhsc1pUNDhMMlJsWm5NK1BIQmhkR2dnYVdROUlrVnNiR2x3YzJWZk56QTJYMk52Y0hsZk1UQWlJR1JoZEdFdGJtRnRaVDBpUld4c2FYQnpaU0EzTURZZ1kyOXdlU0F4TUNJZ1kyeGhjM005SW1Oc2N5MHlJaUJrUFNKTk56a3VNamN5SURRM0xqVTRPR0UwTUM0d016VWdOREF1TURNMUlEQWdNQ0F4TFRNd0xqQTBJRE14TGpNelRETXpMakExTnlBMk1pNDNOQ0F6TkNBek4yd3hOQzQwTFRJd0xqSTRlaUl2UGp4d1lYUm9JR2xrUFNKR2IzSnRZVjh4WDJOdmNIbGZNaUlnWkdGMFlTMXVZVzFsUFNKR2IzSnRZU0F4SUdOdmNIa2dNaUlnWTJ4aGMzTTlJbU5zY3kweklpQmtQU0pOTkRJZ016SnNMUzR3TWpjdE15NDRPVE5oT0M0NE5ETWdPQzQ0TkRNZ01DQXdJREVnTGpBNE1pMHhMak00SURJdU56STFJREl1TnpJMUlEQWdNQ0F4SUM0ek55MHVPVFkwSURFdU5URTJJREV1TlRFMklEQWdNQ0F4SUM0NU15MHVOalUyUVRZdU5EWWdOaTQwTmlBd0lEQWdNU0EwTlNBeU5XZzBkaTA0YUMwMkxqSTJjUzAxTGpNNUlEQXROeTQzTkNBeUxqWXhZeTB4TGpVMk9DQXhMamMwTFRJZ05DNHdNRFV0TWlBM0xqTTVNM1kxYUMwMWRqaG9OVlkyTTJnNExqazNNbFkwTUVnME9Hd3hMVGhvTFRkNklpOCtQQzl6ZG1jKyc7XG4kc3ZnX2RlbW9wYWdlOiAnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCcFpEMGlhVzV6ZEdGd1lXZGxMbk4yWnlJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWlCM2FXUjBhRDBpT0RBaUlHaGxhV2RvZEQwaU9EQWlJSFpwWlhkQ2IzZzlJakFnTUNBNE1DQTRNQ0krUEdSbFpuTStQSE4wZVd4bFBpNWpiSE10TVNCN0lHWnBiR3c2SUNNeFpUZzRaVFU3SUgwZ0xtTnNjeTB5TENBdVkyeHpMVE1nZXlCbWFXeHNMWEoxYkdVNklHVjJaVzV2WkdRN0lIMGdMbU5zY3kweUlIc2diM0JoWTJsMGVUb2dNQzR4TlRzZ1ptbHNkR1Z5T2lCMWNtd29JMlpwYkhSbGNpazdJSDBnTG1Oc2N5MHpJSHNnWm1sc2JEb2dJMlptWmpzZ2ZUd3ZjM1I1YkdVK1BHWnBiSFJsY2lCcFpEMGlabWxzZEdWeUlpQjRQU0kxTXpZaUlIazlJakU0SWlCM2FXUjBhRDBpTmpnaUlHaGxhV2RvZEQwaU5qY2lJR1pwYkhSbGNsVnVhWFJ6UFNKMWMyVnlVM0JoWTJWUGJsVnpaU0krUEdabFQyWm1jMlYwSUhKbGMzVnNkRDBpYjJabWMyVjBJaUJrZVQwaU1TSWdhVzQ5SWxOdmRYSmpaVUZzY0doaElpOCtQR1psUjJGMWMzTnBZVzVDYkhWeUlISmxjM1ZzZEQwaVlteDFjaUlnYzNSa1JHVjJhV0YwYVc5dVBTSXlJaTgrUEdabFJteHZiMlFnY21WemRXeDBQU0ptYkc5dlpDSWdabXh2YjJRdFkyOXNiM0k5SWlNd1pERmhNbU1pSUdac2IyOWtMVzl3WVdOcGRIazlJaTR5TXlJdlBqeG1aVU52YlhCdmMybDBaU0J5WlhOMWJIUTlJbU52YlhCdmMybDBaU0lnYjNCbGNtRjBiM0k5SW1sdUlpQnBiakk5SW1Kc2RYSWlMejQ4Wm1WQ2JHVnVaQ0J5WlhOMWJIUTlJbUpzWlc1a0lpQnBiajBpVTI5MWNtTmxSM0poY0docFl5SXZQand2Wm1sc2RHVnlQand2WkdWbWN6NDhjR0YwYUNCcFpEMGlSV3hzYVhCelpWODNNRFpmWTI5d2VWOHhNU0lnWkdGMFlTMXVZVzFsUFNKRmJHeHBjSE5sSURjd05pQmpiM0I1SURFeElpQmpiR0Z6Y3owaVkyeHpMVElpSUdROUlrMDJNREFzTXprdU9UZzNWalF3WVRNNUxqazVOQ3d6T1M0NU9UUXNNQ3d3TERFdE16Y3VNVEl5TERNNUxqZzROa3cxTXprc05UWnNOQzB6TVN3M0xUVm9ObXd5TlM0NU56WXNNUzQ1TmpSYUlpQjBjbUZ1YzJadmNtMDlJblJ5WVc1emJHRjBaU2d0TlRJd0tTSXZQanh3WVhSb0lHbGtQU0ozYUdsMFpWOWpiM0I1WHpNaUlHUmhkR0V0Ym1GdFpUMGlkMmhwZEdVZ1kyOXdlU0F6SWlCamJHRnpjejBpWTJ4ekxUTWlJR1E5SWswMU5Ea3VNRGtzTlRndU1qTXlWakl4TGpNM1lUQXVOamc1TERBdU5qZzVMREFzTUN3d0xTNDFPUzB3TGpZM09FdzFORFlzTWpCaE1TNHhOamdzTVM0eE5qZ3NNQ3d3TERBdE1Td3hWalU1WXpBc01DNDBNVGt1T0RZeExEQXVNeXd4TGpJM09Td3dMakl6Tm13eUxqSXlMUzR6TWpWQk1DNDJPRGdzTUM0Mk9EZ3NNQ3d3TERBc05UUTVMakE1TERVNExqSXpNbHB0TFRZdU5EZzNMVE11TkRaV01qUXVOalkyWVRBdU5qZzRMREF1TmpnNExEQXNNQ3d3TFM0Mk1Ua3RNQzQyT0RKc0xUSXVNakl0TGpJellUQXVOamc1TERBdU5qZzVMREFzTUN3d0xTNDNOalF1TmpneVZqVTFMakF5WVRBdU5qa3NNQzQyT1N3d0xEQXNNQ3d1TnpjeUxqWTRNbXd5TGpJeUxTNHlORGxCTUM0Mk9EZ3NNQzQyT0Rnc01Dd3dMREFzTlRReUxqWXNOVFF1TnpjeVdrMDFPREV1TkRJeExESXhMalkyYkMweU9DNDJORFF0TkM0Mk5URmhNQzQyT1N3d0xqWTVMREFzTUN3d0xTNDRMalkzTjFZMk1pNHpNekpoTUM0Mk9Td3dMalk1TERBc01Dd3dMQzQ0TVRNdU5qYzFiREk0TGpZME15MDFMakF5TmtFd0xqWTROeXd3TGpZNE55d3dMREFzTUN3MU9ESXNOVGN1TTFZeU1pNHpNemRCTUM0Mk9EZ3NNQzQyT0Rnc01Dd3dMREFzTlRneExqUXlNU3d5TVM0Mk5scHRMVE11TURVc016SXVORFUyWVRBdU5qZzJMREF1TmpnMkxEQXNNQ3d4TFM0MU9UUXVOamM1YkMweU1DNHlNaXd5TGpnMllUQXVOamtzTUM0Mk9Td3dMREFzTVMwdU56ZzVMVEF1TmpjNVZqSXpMalE0TkdFd0xqWTVMREF1Tmprc01Dd3dMREVzTGpjM09DMHdMalk0TVd3eU1DNHlNVGtzTWk0MU1UUmhNQzQyT0Rnc01DNDJPRGdzTUN3d0xERXNMall3Tmk0Mk9GWTFOQzR4TVRWYUlpQjBjbUZ1YzJadmNtMDlJblJ5WVc1emJHRjBaU2d0TlRJd0tTSXZQand2YzNablBnPT0nO1xuJHN2Z190ZW1wbGF0ZTogJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QnBaRDBpZEdWdGNHeGhkR1YyTXk1emRtY2lJSGh0Ykc1elBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHlNREF3TDNOMlp5SWdkMmxrZEdnOUlqRXdNQ0lnYUdWcFoyaDBQU0l4TURBaUlIWnBaWGRDYjNnOUlqQWdNQ0F4TURBZ01UQXdJajQ4WkdWbWN6NDhjM1I1YkdVK0xtTnNjeTB5SUhzZ2IzQmhZMmwwZVRvZ01DNHhOVHNnZlNBdVkyeHpMVElzSUM1amJITXRNeUI3SUdacGJHd3RjblZzWlRvZ1pYWmxibTlrWkRzZ2ZTQXVZMnh6TFRNZ2V5Qm1hV3hzT2lBalptWm1PeUI5UEM5emRIbHNaVDQ4TDJSbFpuTStQSEJoZEdnZ2FXUTlJa1ZzYkdsd2MyVmZOekEyWDJOdmNIbGZNVEVpSUdSaGRHRXRibUZ0WlQwaVJXeHNhWEJ6WlNBM01EWWdZMjl3ZVNBeE1TSWdZMnhoYzNNOUltTnNjeTB5SWlCa1BTSk5PVGt1T1RjMUlEUTVMakF4WXk0d01EWXVNek11TURJMUxqWTJMakF5TlM0NU9XRTFNQ0ExTUNBd0lEQWdNUzAxTUNBMU1HTXRNUzQwSURBdE1pNDNOemd0TGpBM0xUUXVNVFEyTFM0eE9Fd3lNaTQ0TXlBM05pNDNPU0EzTlNBM04yd3VOemt6TFRVeUxqRTNlaUl2UGp4d1lYUm9JR2xrUFNKU1pXTjBZVzVuYkdWZk5sOWpiM0I1WHpjaUlHUmhkR0V0Ym1GdFpUMGlVbVZqZEdGdVoyeGxJRFlnWTI5d2VTQTNJaUJqYkdGemN6MGlZMnh6TFRNaUlHUTlJazB5TlNBeU5HZzBPV0V5SURJZ01DQXdJREVnTWlBeWRqVXdZVElnTWlBd0lEQWdNUzB5SURKSU1qVmhNaUF5SURBZ01DQXhMVEl0TWxZeU5tRXlJRElnTUNBd0lERWdNaTB5ZW0weU1DQTFhREkyZGpOSU5EVjJMVE42VFRJNElEWXdhRFF6ZGpOSU1qaDJMVE42YlRVdE16Rm9NM1l6YUMwemRpMHplbTAxSURCb00zWXphQzB6ZGkwemVtMHRNVEFnTUdnemRqTm9MVE4yTFRONmJUQWdPR2cwTTNZeE9FZ3lPRll6TjNwdE1UUWdOMmd4TlhZMlNEUXlkaTAyZW0wd0lESXphREUxZGpaSU5ESjJMVFo2SWk4K1BDOXpkbWMrJztcbiRzdmdfbG9hZGVyOiAnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhkcFpIUm9QU0l4T1RBaUlHaGxhV2RvZEQwaU1Ua3dJaUIyYVdWM1FtOTRQU0l3SURBZ01UQXdJREV3TUNJZ2NISmxjMlZ5ZG1WQmMzQmxZM1JTWVhScGJ6MGllRTFwWkZsTmFXUWlJR05zWVhOelBTSjFhV3d0Y21sdVp5SStQSEJoZEdnZ1ptbHNiRDBpYm05dVpTSWdaRDBpVFRBZ01HZ3hNREIyTVRBd1NEQjZJaUJqYkdGemN6MGlZbXNpTHo0OFkybHlZMnhsSUdONFBTSTFNQ0lnWTNrOUlqVXdJaUJ5UFNJME5TSWdabWxzYkQwaWJtOXVaU0lnYzNSeWIydGxQU0lqWkdSbE5HVmhJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqRXdJaUJ6ZEhKdmEyVXRaR0Z6YUdGeWNtRjVQU0l4T0RNdU56Z3pNVGN3TWpNMU1EQXlPU0E1T0M0NU5qQXhOamcxT0Rnd056ZzBPU0krUEdGdWFXMWhkR1ZVY21GdWMyWnZjbTBnWVhSMGNtbGlkWFJsVG1GdFpUMGlkSEpoYm5ObWIzSnRJaUIwZVhCbFBTSnliM1JoZEdVaUlIWmhiSFZsY3owaU1DQTFNQ0ExTURzeE9EQWdOVEFnTlRBN016WXdJRFV3SURVd095SWdhMlY1VkdsdFpYTTlJakE3TUM0MU96RWlJR1IxY2owaU1YTWlJSEpsY0dWaGRFTnZkVzUwUFNKcGJtUmxabWx1YVhSbElpQmlaV2RwYmowaU1ITWlMejQ4TDJOcGNtTnNaVDQ4TDNOMlp6ND0nO1xuIiwiLypcbiAgVXNlZCBieSBidXR0b25zIGFuZCBwYWdpbmF0aW9uIGxpbmtzXG4qL1xuQG1peGluIGJ1dHRvbl9kaXNhYmxlZFxue1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfaGVybWFub3M7XG4gIGNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbiAgYm94LXNoYWRvdzogbm9uZTtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG4iLCJAZnVuY3Rpb24gY2hlY2tfcmFkaXVzKCRyYWRpdXMpIHtcbiAgQGlmIHR5cGUtb2YoJHJhZGl1cykgIT0gXCJudW1iZXJcIiBhbmQgJHJhZGl1cyAhPSBudWxsIHtcbiAgICBAd2FybiBcImAjeyRyYWRpdXN9YCBtdXN0IGJlIGEgbnVtYmVyIG9yIG51bGwuXCI7XG4gICAgQHJldHVybiBmYWxzZTtcbiAgfVxuICBAZWxzZSBpZiAkcmFkaXVzID09IG51bGwge1xuICAgIEByZXR1cm4gZmFsc2U7XG4gIH1cbiAgQGVsc2Uge1xuICAgIEByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vKlxuICBJZGVhIG9mIHRoaXMgbWl4aW4gaXMgdG8gb3V0cHV0IGBib3JkZXItcmFkaXVzYCBwcm9wZXJ0eSBmb3IgZWFjaCBjb3JuZXIgc2VwZXJhdGVseS5cbiAgSWYgeW91IHdhbnQgdG8gdGFyZ2V0IGFsbCBjb3JuZXJzIGl0J3MgYmV0dGVyIHRvIHVzZSB0aGUgc3RhbmRhcmQgQ1NTIGBib3JkZXItcmFkaXVzYCBzaG9ydGhhbmQuXG5cbiAgTm90ZVxuICAgIElmIGAkcmFkaXVzYCBwYXJhbWV0ZXIgZXF1YWxzIGBudWxsYCBpdCB3b24ndCBiZSBnZW5lcmF0ZWQuXG5cbiAgRXhhbXBsZSAxXG4gICAgaW5wdXQgYC5jbGF6eiB7QGluY2x1ZGUgcmFkaXVzKCBudWxsLCBudWxsLCAwLCAxMHB4ICl9YFxuICAgIG91dHB1dCBgLmNsYXp6IHtib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czogMDsgIGJvcmRlci1ib3R0b20tbGVmdC1yYWRpdXM6IDEwcHg7fWBcblxuICBFeGFtcGxlIDJcbiAgICBpbnB1dCBgLmNsYXp6IHtAaW5jbHVkZSByYWRpdXMoIDEwcHgsIDFweCApfWBcbiAgICBvdXRwdXQgYC5jbGF6eiB7Ym9yZGVyLXRvcC1sZWZ0LXJhZGl1czogMTBweDsgIGJvcmRlci10b3AtcmlnaHQtcmFkaXVzOiAxcHg7fWBcbiovXG5cbkBtaXhpbiByYWRpdXMgKFxuICAkdG9wX2xlZnQ6IG51bGwsXG4gICR0b3BfcmlnaHQ6IG51bGwsXG4gICRib3R0b21fcmlnaHQ6IG51bGwsXG4gICRib3R0b21fbGVmdDogbnVsbFxuKSB7XG4gIEBpZiBjaGVja19yYWRpdXMoJHRvcF9sZWZ0KSB7XG4gICAgYm9yZGVyLXRvcC1sZWZ0LXJhZGl1czogJHRvcF9sZWZ0O1xuICB9XG5cbiAgQGlmIGNoZWNrX3JhZGl1cygkdG9wX3JpZ2h0KSB7XG4gICAgYm9yZGVyLXRvcC1yaWdodC1yYWRpdXM6ICR0b3BfcmlnaHQ7XG4gIH1cblxuICBAaWYgY2hlY2tfcmFkaXVzKCRib3R0b21fcmlnaHQpIHtcbiAgICBib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czogJGJvdHRvbV9yaWdodDtcbiAgfVxuXG4gIEBpZiBjaGVja19yYWRpdXMoJGJvdHRvbV9sZWZ0KSB7XG4gICAgYm9yZGVyLWJvdHRvbS1sZWZ0LXJhZGl1czogJGJvdHRvbV9sZWZ0O1xuICB9XG59XG4iLCIvKlxuICBVc2VkIGJ5IGJ1dHRvbnMgYW5kIHBhZ2luYXRpb24gbGlua3NcbiovXG5cbkBtaXhpbiBidXR0b25fc2hhZG93IHtcbiAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfcHJpbWFyeTtcblxuICAmOmhvdmVyLFxuICAmLmlzLWFjdGl2ZSB7XG4gICAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfc2Vjb25kYXJ5O1xuICB9XG59XG4iLCIvKlxuICBIaWRlcyBlbGVtZW50IGZyb20gYmVlaW5nIGRpc3BsYXllZCwgYnV0IGxldHMgc2NyZWVuIHJlYWRlcnMgcmVhZCBpdFxuKi9cblxuQG1peGluIHZpc3VhbGx5X2hpZGRlbiB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgY2xpcDogcmVjdCgwIDAgMCAwKTtcbiAgaGVpZ2h0OiAxcHg7XG4gIHdpZHRoOiAxcHg7XG4gIG1hcmdpbjogLTFweDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyOiAwO1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgUmVzZXRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi8qIGh0dHA6Ly9tZXllcndlYi5jb20vZXJpYy90b29scy9jc3MvcmVzZXQvXG4gICB2Mi4wIHwgMjAxMTAxMjZcbiAgIExpY2Vuc2U6IG5vbmUgKHB1YmxpYyBkb21haW4pXG4qL1xuXG5odG1sLCBib2R5LCBkaXYsIHNwYW4sIGFwcGxldCwgb2JqZWN0LCBpZnJhbWUsXG5oMSwgaDIsIGgzLCBoNCwgaDUsIGg2LCBwLCBibG9ja3F1b3RlLCBwcmUsXG5hLCBhYmJyLCBhY3JvbnltLCBhZGRyZXNzLCBiaWcsIGNpdGUsIGNvZGUsXG5kZWwsIGRmbiwgZW0sIGltZywgaW5zLCBrYmQsIHEsIHMsIHNhbXAsXG5zbWFsbCwgc3RyaWtlLCBzdHJvbmcsIHN1Yiwgc3VwLCB0dCwgdmFyLFxuYiwgdSwgaSwgY2VudGVyLFxuZGwsIGR0LCBkZCwgb2wsIHVsLCBsaSxcbmZpZWxkc2V0LCBmb3JtLCBsYWJlbCwgbGVnZW5kLFxudGFibGUsIGNhcHRpb24sIHRib2R5LCB0Zm9vdCwgdGhlYWQsIHRyLCB0aCwgdGQsXG5hcnRpY2xlLCBhc2lkZSwgY2FudmFzLCBkZXRhaWxzLCBlbWJlZCxcbmZpZ3VyZSwgZmlnY2FwdGlvbiwgZm9vdGVyLCBoZWFkZXIsIGhncm91cCxcbm1lbnUsIG5hdiwgb3V0cHV0LCBydWJ5LCBzZWN0aW9uLCBzdW1tYXJ5LFxudGltZSwgbWFyaywgYXVkaW8sIHZpZGVvIHtcblx0bWFyZ2luOiAwO1xuXHRwYWRkaW5nOiAwO1xuXHRib3JkZXI6IDA7XG5cdGZvbnQtc2l6ZTogMTAwJTtcblx0Zm9udDogaW5oZXJpdDtcblx0dmVydGljYWwtYWxpZ246IGJhc2VsaW5lO1xufVxuXG4vKiBIVE1MNSBkaXNwbGF5LXJvbGUgcmVzZXQgZm9yIG9sZGVyIGJyb3dzZXJzICovXG5hcnRpY2xlLCBhc2lkZSwgZGV0YWlscywgZmlnY2FwdGlvbiwgZmlndXJlLFxuZm9vdGVyLCBoZWFkZXIsIGhncm91cCwgbWVudSwgbmF2LCBzZWN0aW9uIHtcblx0ZGlzcGxheTogYmxvY2s7XG59XG5cbmJvZHkge1xuXHRsaW5lLWhlaWdodDogMTtcbn1cblxub2wsIHVsIHtcblx0bGlzdC1zdHlsZTogbm9uZTtcbn1cblxuYmxvY2txdW90ZSwgcSB7XG5cdHF1b3Rlczogbm9uZTtcbn1cblxuYmxvY2txdW90ZTpiZWZvcmUsIGJsb2NrcXVvdGU6YWZ0ZXIsXG5xOmJlZm9yZSwgcTphZnRlciB7XG5cdGNvbnRlbnQ6ICcnO1xuXHRjb250ZW50OiBub25lO1xufVxuXG50YWJsZSB7XG5cdGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7XG5cdGJvcmRlci1zcGFjaW5nOiAwO1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgR2xvYmFsXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vLyBodHRwczovL2Nzcy10cmlja3MuY29tL2luaGVyaXRpbmctYm94LXNpemluZy1wcm9iYWJseS1zbGlnaHRseS1iZXR0ZXItYmVzdC1wcmFjdGljZS9cblxuaHRtbCB7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG59XG5cbiosXG4qOmJlZm9yZSxcbio6YWZ0ZXIge1xuICBib3gtc2l6aW5nOiBpbmhlcml0O1xufVxuXG5ib2R5IHtcblx0Zm9udDogJGZvbnRfc2l6ZV9wcmltYXJ5ICRmb250X2ZhbWlseV9wcmltYXJ5O1xuXHRsaW5lLWhlaWdodDogMS4xO1xuXHRjb2xvcjogJGNvbG9yX3R1Y287XG59XG5cbnAgKyBwIHtcbiAgcGFkZGluZy10b3A6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIFJvYm90byAocmVndWxhciBhbmQgbWVkaXVtIHZhcmlhbnQpXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnUm9ib3RveCc7XG4gIHNyYzogdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTQ5M19yb2JvdG8tcmVndWxhci13ZWJmb250LmVvdCcpIGZvcm1hdCgnZW1iZWRkZWQtb3BlbnR5cGUnKSwgdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTU1M19yb2JvdG8tcmVndWxhci13ZWJmb250LndvZmYnKSBmb3JtYXQoJ3dvZmYnKSwgdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTUzNF9yb2JvdG8tcmVndWxhci13ZWJmb250LnR0ZicpIGZvcm1hdCgndHJ1ZXR5cGUnKSwgdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTUxN19yb2JvdG8tcmVndWxhci13ZWJmb250LnN2ZycpIGZvcm1hdCgnc3ZnJyk7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcbn1cblxuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnUm9ib3RveCc7XG4gIHNyYzogdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTI4OV9yb2JvdG8tbWVkaXVtLXdlYmZvbnQuZW90JykgZm9ybWF0KCdlbWJlZGRlZC1vcGVudHlwZScpLCB1cmwoJy8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9pbnN0YXBhZ2UtYXBwLWFzc2V0cy8xNDY4ODU1NDU0X3JvYm90by1tZWRpdW0td2ViZm9udC53b2ZmJykgZm9ybWF0KCd3b2ZmJyksIHVybCgnLy9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2luc3RhcGFnZS1hcHAtYXNzZXRzLzE0Njg4NTU0MjNfcm9ib3RvLW1lZGl1bS13ZWJmb250LnR0ZicpIGZvcm1hdCgndHJ1ZXR5cGUnKSwgdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTMyOF9yb2JvdG8tbWVkaXVtLXdlYmZvbnQuc3ZnJykgZm9ybWF0KCdzdmcnKTtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xufVxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICBNYXRlcmlhbCBJY29uc1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbkBmb250LWZhY2Uge1xuICBmb250LWZhbWlseTogJ01hdGVyaWFsIEljb25zJztcbiAgc3JjOiB1cmwoJy8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9pbnN0YXBhZ2UtYXBwLWFzc2V0cy8xNDY4ODU1MDY3X21hdGVyaWFsaWNvbnMtcmVndWxhci5lb3QnKSwgdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTIzN19tYXRlcmlhbGljb25zLXJlZ3VsYXIud29mZjInKSBmb3JtYXQoJ3dvZmYyJyksIHVybCgnLy9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2luc3RhcGFnZS1hcHAtYXNzZXRzLzE0Njg4NTUxOTJfbWF0ZXJpYWxpY29ucy1yZWd1bGFyLndvZmYnKSBmb3JtYXQoJ3dvZmYnKSwgdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ2ODg1NTE1MV9tYXRlcmlhbGljb25zLXJlZ3VsYXIudHRmJykgZm9ybWF0KCd0cnVldHlwZScpO1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG59XG5cbi5tYXRlcmlhbC1pY29ucyB7XG4gIGZvbnQtZmFtaWx5OiAnTWF0ZXJpYWwgSWNvbnMnO1xuICBmb250LXdlaWdodDogbm9ybWFsO1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIGZvbnQtc2l6ZTogJGljb25fc2l6ZV9wcmltYXJ5O1xuICBsaW5lLWhlaWdodDogMTtcbiAgdGV4dC10cmFuc2Zvcm06IG5vbmU7XG4gIGxldHRlci1zcGFjaW5nOiBub3JtYWw7XG4gIHdvcmQtd3JhcDogbm9ybWFsO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGRpcmVjdGlvbjogbHRyO1xuICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcbiAgdGV4dC1yZW5kZXJpbmc6IG9wdGltaXplTGVnaWJpbGl0eTtcbiAgLW1vei1vc3gtZm9udC1zbW9vdGhpbmc6IGdyYXlzY2FsZTtcbiAgZm9udC1mZWF0dXJlLXNldHRpbmdzOiAnbGlnYSc7XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjSEVBRElOR1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuaDEge1xuICBmb250LXNpemU6IDIwcHg7XG4gIGxpbmUtaGVpZ2h0OiAyOHB4O1xufVxuXG5oMiB7XG4gIGZvbnQtc2l6ZTogMThweDtcbiAgbGluZS1oZWlnaHQ6IDI2cHg7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI1BBUkFHUkFQSFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxucCB7XG4gIGxpbmUtaGVpZ2h0OiAxLjU7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI1RFWFQgTU9ESUZJRVJTXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5zdHJvbmcge1xuICBmb250LXdlaWdodDogJGZvbnRfd2VpZ2h0X21lZGl1bTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjTElOS1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuYSB7XG4gIGNvbG9yOiAkY29sb3JfY3J5c3RhbDtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuXG4gICY6aG92ZXIge1xuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xuICB9XG59XG4iLCIvKlxuICBodHRwOi8vY29sb3VyZ2FyZGVuLm5ldC9hdmFsYW5jaGUvXG4gIGh0dHA6Ly9mbGV4Ym94Z3JpZC5jb20vXG5cbiAgaHR0cHM6Ly9naXRodWIuY29tL2NvbG91cmdhcmRlbi9hdmFsYW5jaGVcbiAgaHR0cHM6Ly9naXRodWIuY29tL2tyaXN0b2Zlcmpvc2VwaC9mbGV4Ym94Z3JpZFxuXG4gIHR3byBzb2x1dGlvbnMgbWVyZ2VkIGludG8gb25lOlxuICAgIC0gbWl4aW5pbiwgYnJlYWtwb2ludHMsIGxvb3BzIHRha2VuIGZyb20gYXZhbGFuY2hlXG4gICAgLSBmbGV4Ym94IHNvbHV0aW9ucyB0YWtlbiBmcm9tIGZsZXhib3hncmlkXG4qL1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAgIFNFVFRJTkdTXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4kYXYtbmFtZXNwYWNlOiAgJ2dyaWQnICFkZWZhdWx0OyAgLy8gUHJlZml4IG5hbWVzcGFjZSBmb3IgZ3JpZCBsYXlvdXQgYW5kIGNlbGxzXG4kYXYtZ3V0dGVyOiAgICAgMjBweCAhZGVmYXVsdDsgICAgLy8gR3V0dGVyIGJldHdlZW4gZ3JpZCBjZWxsc1xuXG4kYXYtd2lkdGgtY2xhc3MtbmFtZXNwYWNlOiAgJycgIWRlZmF1bHQ7ICAgICAgICAgIC8vIFByZWZpeCBuYW1lc3BhY2UgZm9yIHdpZHRoIGNsYXNzZXMuIEZvciBleGFtcGxlOyAnY29sLSdcbiRhdi13aWR0aC1jbGFzcy1zdHlsZTogICAgICAnZnJhY3Rpb24nICFkZWZhdWx0OyAgLy8gV2lkdGggY2xhc3MgbmFtaW5nIHN0eWxlLiBDYW4gYmUgJ2ZyYWN0aW9uJywgJ3BlcmNlbnRhZ2UnIG9yICdmcmFnbWVudCdcbiRhdi13aWR0aHM6IChcbiAgMixcbiAgMyxcbiAgNFxuKSAhZGVmYXVsdDsgLy8gV2lkdGggZGVub21pbmF0b3IgdmFsdWVzLiAyID0gMS8yLCAzID0gMS8zIGV0Yy4gQWRkL3JlbW92ZSBhcyBhcHByb3ByaWF0ZVxuXG4kYXYtZW5hYmxlLXJlc3BvbnNpdmU6ICB0cnVlICFkZWZhdWx0O1xuXG4kYXYtYnJlYWtwb2ludHM6ICAoXG4gIFwidGh1bWJcIjogICAgICAgICAgICBcInNjcmVlbiBhbmQgKG1heC13aWR0aDogNDk5cHgpXCIsXG4gIFwiaGFuZGhlbGRcIjogICAgICAgICBcInNjcmVlbiBhbmQgKG1pbi13aWR0aDogNTAwcHgpIGFuZCAobWF4LXdpZHRoOiA4MDBweClcIixcbiAgXCJoYW5kaGVsZC1hbmQtdXBcIjogIFwic2NyZWVuIGFuZCAobWluLXdpZHRoOiA1MDBweClcIixcbiAgXCJwb2NrZXRcIjogICAgICAgICAgIFwic2NyZWVuIGFuZCAobWF4LXdpZHRoOiA4MDBweClcIixcbiAgXCJsYXBcIjogICAgICAgICAgICAgIFwic2NyZWVuIGFuZCAobWluLXdpZHRoOiA4MDFweCkgYW5kIChtYXgtd2lkdGg6IDEwMjRweClcIixcbiAgXCJsYXAtYW5kLXVwXCI6ICAgICAgIFwic2NyZWVuIGFuZCAobWluLXdpZHRoOiA4MDFweClcIixcbiAgXCJwb3J0YWJsZVwiOiAgICAgICAgIFwic2NyZWVuIGFuZCAobWF4LXdpZHRoOiAxMDI0cHgpXCIsXG4gIFwiZGVza1wiOiAgICAgICAgICAgICBcInNjcmVlbiBhbmQgKG1pbi13aWR0aDogMTAyNXB4KVwiLFxuICBcIndpZGVzY3JlZW5cIjogICAgICAgXCJzY3JlZW4gYW5kIChtaW4td2lkdGg6IDExNjBweClcIixcbiAgXCJyZXRpbmFcIjogICAgICAgICAgIFwic2NyZWVuIGFuZCAoLXdlYmtpdC1taW4tZGV2aWNlLXBpeGVsLXJhdGlvOiAyKSwgc2NyZWVuIGFuZCAobWluLXJlc29sdXRpb246IDE5MmRwaSksIHNjcmVlbiBhbmQgKG1pbi1yZXNvbHV0aW9uOiAyZHBweClcIlxuKSAhZGVmYXVsdDsgLy8gUmVzcG9uc2l2ZSBicmVha3BvaW50cy4gQWRkL3JlbW92ZSBhcyBhcHByb3ByaWF0ZVxuXG4vLyBFbmFibGUvZGlzYWJsZSBncmlkIGxheW91dHNcblxuJGF2LWVuYWJsZS1ob3ItY2VudGVyOiAgICAgICB0cnVlICFkZWZhdWx0O1xuJGF2LWVuYWJsZS1ob3ItcmlnaHQ6ICAgICAgICB0cnVlICFkZWZhdWx0O1xuXG4kYXYtZW5hYmxlLXZlci1taWRkbGU6ICAgICAgIHRydWUgIWRlZmF1bHQ7XG4kYXYtZW5hYmxlLXZlci1ib3R0b206ICAgICAgIHRydWUgIWRlZmF1bHQ7XG5cbiRhdi1lbmFibGUtZ3JpZC1hdXRvOiAgICAgICAgIHRydWUgIWRlZmF1bHQ7XG4kYXYtZW5hYmxlLWdyaWQtcmV2OiAgICAgICAgICBmYWxzZSAhZGVmYXVsdDtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAgIExPR0lDIGFrYSBUSEUgTUFHSUNcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbkBmdW5jdGlvbiBlc2NhcGVOdW1lcmF0b3IoJG51bWVyYXRvciwgJG5hbWVzcGFjZTogJycpe1xuICBAaWYoJG5hbWVzcGFjZSA9PSAnJyl7XG4gICAgJG51bWVyYXRvci1hcy1zdHJpbmc6IGluc3BlY3QoJG51bWVyYXRvcik7XG4gICAgJGVzY2FwZWQtbnVtZXJhdG9yOiAnJztcblxuICAgIC8vIExvb3AgdGhyb3VnaCBhbGwgZGlnaXRzIGluIHRoZSBudW1lcmF0b3IgYW5kIGVzY2FwZSBpbmRpdmlkdWFsbHlcbiAgICBAZm9yICRpIGZyb20gMSB0aHJvdWdoIHN0ci1sZW5ndGgoJG51bWVyYXRvci1hcy1zdHJpbmcpe1xuICAgICAgJGRpZ2l0OiBzdHItc2xpY2UoJG51bWVyYXRvci1hcy1zdHJpbmcsICRpLCAkaSk7XG4gICAgICAkZXNjYXBlZC1udW1lcmF0b3I6ICRlc2NhcGVkLW51bWVyYXRvcitcXDMrJGRpZ2l0O1xuICAgIH1cblxuICAgIEByZXR1cm4gJGVzY2FwZWQtbnVtZXJhdG9yO1xuICB9IEBlbHNlIHtcbiAgICBAcmV0dXJuICRudW1lcmF0b3I7XG4gIH1cbn1cblxuQGZ1bmN0aW9uIGF2Q3JlYXRlQ2xhc3NOYW1lKCRzdHlsZSwgJG51bWVyYXRvciwgJGRlbm9taW5hdG9yLCAkYnJlYWtwb2ludC1hbGlhcyl7XG5cbiAgJGNsYXNzLW5hbWU6IG51bGw7XG5cbiAgQGlmICRzdHlsZSA9PSAnZnJhY3Rpb24nIG9yICRzdHlsZSA9PSAnZnJhZ21lbnQne1xuICAgIC8vIFNldCBkZWxpbWl0ZXIgYXMgc2xhc2ggb3IgdGV4dFxuICAgICRkZWxpbWl0ZXI6IGlmKCRzdHlsZSA9PSAnZnJhY3Rpb24nLCBcXC8sIC1vZi0pO1xuICAgICRjbGFzcy1uYW1lOiAjeyRhdi13aWR0aC1jbGFzcy1uYW1lc3BhY2V9I3tlc2NhcGVOdW1lcmF0b3IoJG51bWVyYXRvciwgJGF2LXdpZHRoLWNsYXNzLW5hbWVzcGFjZSl9I3skZGVsaW1pdGVyfSN7JGRlbm9taW5hdG9yfSN7JGJyZWFrcG9pbnQtYWxpYXN9O1xuICB9IEBlbHNle1xuICAgIEBpZiAkYXYtd2lkdGgtY2xhc3MtbmFtZXNwYWNlID09ICcne1xuICAgICAgQGVycm9yIFwiUGVyY2VudGFnZSB2YWx1ZSBjbGFzcyBuYW1lcyByZXF1aXJlIGEgbmFtZXNwYWNlIHRvIGJlIHNldCAoc2VlICRhdi13aWR0aC1jbGFzcy1uYW1lc3BhY2UpLiBTZWxlY3RpdmUgZXNjYXBpbmcgKGUuZy4gdGhlIDUgb2YgNTApIGNhbm5vdCBiZSBkb25lLlwiO1xuICAgIH1cbiAgICAkY2xhc3Mtd2lkdGg6IGZsb29yKCgkbnVtZXJhdG9yIC8gJGRlbm9taW5hdG9yKSAqIDEwMCk7XG4gICAgJGNsYXNzLW5hbWU6ICN7JGF2LXdpZHRoLWNsYXNzLW5hbWVzcGFjZX0jeyRjbGFzcy13aWR0aH0jeyRicmVha3BvaW50LWFsaWFzfTtcbiAgfVxuXG4gIEByZXR1cm4gJGNsYXNzLW5hbWU7XG59XG5cbkBtaXhpbiBhdi1jcmVhdGUtd2lkdGhzKCR3aWR0aHMsICRicmVha3BvaW50LWFsaWFzOiBudWxsKXtcblxuICAvLyBJbml0aWFsaXNlIGFuIGVtcHR5IHV0aWxpdHkgbWFwIHRoYXQgd2lsbCBldmVudHVhbGx5IGNvbnRhaW4gYWxsIG91ciBjbGFzc2VzXG4gICRwc2V1ZG8tY2xhc3MtbWFwOiAoKTtcblxuICAvLyBMb29wIHdpZHRoc1xuICBAZWFjaCAkZGVub21pbmF0b3IgaW4gJHdpZHRoc3tcblxuICAgIC8vIElmIDE9MSwgMj0yLCAzPTM7IEBmb3Igd2lsbCBza2lwIG92ZXIgc28gY3JlYXRlIDEvMSBjbGFzcyBtYW51YWxseVxuICAgIEBpZiAoJGRlbm9taW5hdG9yID09IDEpIHtcblxuICAgICAgLy8gQ3JlYXRlIDEvMSBjbGFzc1xuICAgICAgJGNsYXNzLW5hbWU6IGF2Q3JlYXRlQ2xhc3NOYW1lKCRhdi13aWR0aC1jbGFzcy1zdHlsZSwgMSwgMSwgJGJyZWFrcG9pbnQtYWxpYXMpO1xuICAgICAgLiN7JGNsYXNzLW5hbWV9e1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgIH1cblxuICAgIH0gQGVsc2Uge1xuXG4gICAgICAvLyBMb29wIHdpZHRocyBhcyBmcmFjdGlvbnNcbiAgICAgIEBmb3IgJG51bWVyYXRvciBmcm9tIDEgdG8gJGRlbm9taW5hdG9ye1xuXG4gICAgICAgIC8vIENyZWF0ZSBjbGFzcyBuYW1lIGFuZCBzZXQgd2lkdGggdmFsdWVcbiAgICAgICAgJGNsYXNzLW5hbWU6IGF2Q3JlYXRlQ2xhc3NOYW1lKCRhdi13aWR0aC1jbGFzcy1zdHlsZSwgJG51bWVyYXRvciwkZGVub21pbmF0b3IsICRicmVha3BvaW50LWFsaWFzKTtcbiAgICAgICAgJHdpZHRoLXZhbHVlOiBwZXJjZW50YWdlKCRudW1lcmF0b3IgLyAkZGVub21pbmF0b3IpO1xuXG4gICAgICAgIC8vIElzIHRoaXMgd2lkdGggYWxyZWFkeSBpbiBvdXIgdXRpbGl0eSBtYXA/XG4gICAgICAgICRkdXBsaWNhdGU6IG1hcC1nZXQoJHBzZXVkby1jbGFzcy1tYXAsICR3aWR0aC12YWx1ZSk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIHdpZHRoIGNsYXNzXG4gICAgICAgIC4jeyRjbGFzcy1uYW1lfXtcblxuICAgICAgICAgIC8vIElmIHRoaXMgd2lkdGggaXMgaW4gdXRpbGl0eSBtYXAsIEBleHRlbmQgdGhlIGR1cGxpY2F0ZSwgZWxzZSBjcmVhdGUgYSBuZXcgb25lXG4gICAgICAgICAgQGlmICRkdXBsaWNhdGV7XG4gICAgICAgICAgICBAZXh0ZW5kIC4jeyRkdXBsaWNhdGV9O1xuICAgICAgICAgIH0gQGVsc2V7XG4gICAgICAgICAgICBtYXgtd2lkdGg6ICR3aWR0aC12YWx1ZTtcbiAgICAgICAgICAgIGZsZXg6IDAgMCAkd2lkdGgtdmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHRoaXMgY2xhc3MgdG8gdXRpbGl0eSBtYXBcbiAgICAgICAgJGFkZC1jbGFzczogKCR3aWR0aC12YWx1ZTogJGNsYXNzLW5hbWUpO1xuICAgICAgICAkcHNldWRvLWNsYXNzLW1hcDogbWFwLW1lcmdlKCRwc2V1ZG8tY2xhc3MtbWFwLCAkYWRkLWNsYXNzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuQG1peGluIGF2LW1xKCRhbGlhcyl7XG5cbiAgLy8gU2VhcmNoIGJyZWFrcG9pbnQgbWFwIGZvciBhbGlhc1xuICAkcXVlcnk6IG1hcC1nZXQoJGF2LWJyZWFrcG9pbnRzLCAkYWxpYXMpO1xuXG4gIC8vIElmIGFsaWFzIGV4aXN0cywgcHJpbnQgb3V0IG1lZGlhIHF1ZXJ5XG4gIEBpZiAkcXVlcnl7XG4gICAgQG1lZGlhICN7JHF1ZXJ5fXtcbiAgICAgIEBjb250ZW50O1xuICAgIH1cbiAgfSBAZWxzZXtcbiAgICBAZXJyb3IgXCJObyBicmVha3BvaW50IGZvdW5kIGZvciAjeyRhbGlhc31cIjtcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICAgR1JJRCBMQVlPVVRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi4jeyRhdi1uYW1lc3BhY2V9e1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4OiAwIDEgYXV0bztcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgZmxleC13cmFwOiB3cmFwO1xuICBtYXJnaW4tbGVmdDogLSgkYXYtZ3V0dGVyKTtcbn1cblxuLiN7JGF2LW5hbWVzcGFjZX1fX2NlbGx7XG4gIGZsZXgtZ3JvdzogMTtcbiAgZmxleC1iYXNpczogMTAwJTtcbiAgbWF4LXdpZHRoOiAxMDAlO1xuICBwYWRkaW5nLWxlZnQ6ICRhdi1ndXR0ZXI7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbkdSSUQgTU9ESUZJRVJTXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5AbWl4aW4gZ3JpZF9tb2RpZmllcnMoJGJyZWFrcG9pbnQtYWxpYXM6IG51bGwpe1xuXG4gIC8vIEhPUklaT05UQUwgTU9ESUZJRVJTXG5cbiAgQGlmICRhdi1lbmFibGUtaG9yLWNlbnRlcntcbiAgICAuI3skYXYtbmFtZXNwYWNlfS0taG9yLWNlbnRlciN7JGJyZWFrcG9pbnQtYWxpYXN9e1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgfVxuICB9XG5cbiAgQGlmICRhdi1lbmFibGUtaG9yLXJpZ2h0e1xuICAgIC4jeyRhdi1uYW1lc3BhY2V9LS1ob3ItcmlnaHQjeyRicmVha3BvaW50LWFsaWFzfXtcbiAgICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gICAgfVxuICB9XG5cbiAgLy8gVkVSVElDQUwgTU9ESUZJRVJTXG4gIEBpZiAkYXYtZW5hYmxlLXZlci1taWRkbGV7XG4gICAgLiN7JGF2LW5hbWVzcGFjZX0tLXZlci1jZW50ZXIjeyRicmVha3BvaW50LWFsaWFzfXtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgfVxuICB9XG5cbiAgQGlmICRhdi1lbmFibGUtdmVyLWJvdHRvbXtcbiAgICAuI3skYXYtbmFtZXNwYWNlfS0tdmVyLWJvdHRvbSN7JGJyZWFrcG9pbnQtYWxpYXN9e1xuICAgICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICAgIH1cbiAgfVxuXG4gIC8vIE9USEVSIE1PRElGSUVSU1xuICBAaWYgJGF2LWVuYWJsZS1ncmlkLWF1dG97XG4gICAgLiN7JGF2LW5hbWVzcGFjZX0tLWF1dG8jeyRicmVha3BvaW50LWFsaWFzfXtcbiAgICAgID4gLiN7JGF2LW5hbWVzcGFjZX1fX2NlbGx7XG4gICAgICAgIGZsZXgtYmFzaXM6IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgQGlmICRhdi1lbmFibGUtZ3JpZC1yZXZ7XG4gICAgLiN7JGF2LW5hbWVzcGFjZX0tLXJldiN7JGJyZWFrcG9pbnQtYWxpYXN9e1xuICAgICAgZmxleC1kaXJlY3Rpb246IHJvdy1yZXZlcnNlO1xuICAgIH1cbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICAgR1JJRFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLy8gTG9vcCBkZWZhdWx0IHdpZHRoc1xuQGluY2x1ZGUgYXYtY3JlYXRlLXdpZHRocygkYXYtd2lkdGhzKTtcbkBpbmNsdWRlIGdyaWRfbW9kaWZpZXJzKCk7XG4vLyBJZiByZXNwb25zaXZlIGZsYWcgZW5hYmxlZCwgbG9vcCBicmVha3BvaW50IHdpZHRoc1xuQGlmICRhdi1lbmFibGUtcmVzcG9uc2l2ZXtcblxuICBAZWFjaCAkYWxpYXMsICRxdWVyeSBpbiAkYXYtYnJlYWtwb2ludHN7XG5cbiAgICAvLyBDcmVhdGUgZWFjaCBtZWRpYSBxdWVyeVxuICAgIEBtZWRpYSAjeyRxdWVyeX17XG4gICAgICAvLyB3aWR0aHNcbiAgICAgIEBpbmNsdWRlIGF2LWNyZWF0ZS13aWR0aHMoJGF2LXdpZHRocywgLS0jeyRhbGlhc30pO1xuICAgICAgLy8gbW9kaWZpZXJzXG4gICAgICBAaW5jbHVkZSBncmlkX21vZGlmaWVycygtLSN7JGFsaWFzfSk7XG4gICAgfVxuICB9XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjR1JPVVBcblxuICAgQmFzZTpcbiAgICAgLmwtZ3JvdXBcbiAgICAgICAubC1ncm91cF9faXRlbVxuXG5cbiAgTF9HUk9VUCBNT0RJRklFUlM6XG5cbiAgICBEaXNwbGF5IG1vZGlmaWVyczpcbiAgICAgIC5sLWdyb3VwLS1ibG9ja1xuXG4gICAgSG9yaXpvbnRhbCBhbGlnbm1lbnQgbW9kaWZpZXJzOlxuICAgICAgLmwtZ3JvdXAtLWhvci1jZW50ZXJcbiAgICAgIC5sLWdyb3VwLS1ob3ItcmlnaHRcbiAgICAgIC5sLWdyb3VwLS1ob3Itc3BhY2UtYmV0d2VlblxuXG4gICAgVmVydGljYWwgYWxpZ25tZW50IG1vZGlmaWVyczpcbiAgICAgIC5sLWdyb3VwLS12ZXItY2VudGVyXG4gICAgICAubC1ncm91cC0tdmVyLWJvdHRvbVxuICAgICAgLmwtZ3JvdXAtLXZlci1zdHJldGNoXG5cbiAgICBTcGFjaW5nIG1vZGlmaWVyczpcbiAgICAgIC5sLWdyb3VwLS1zZWNvbmRhcnlcbiAgICAgIC5sLWdyb3VwLS10ZXJ0aWFyeVxuICAgICAgLmwtZ3JvdXAtLXF1YXRlcm5hcnlcblxuXG4gIExfR1JPVVBfX0lURU0gTU9ESUZJRVJTOlxuXG4gICAgVmVydGljYWwgYWxpZ25tZW50IG1vZGlmaWVyczpcbiAgICAgIC5sLWdyb3VwX19pdGVtLS1ib3R0b21cbiAgICAgIC5sLWdyb3VwX19pdGVtLS1jZW50ZXJcbiAgICAgIC5sLWdyb3VwX19pdGVtLS10b3BcblxuICAgIEhvcml6b250YWwgYWxpZ25tZW50IG1vZGlmaWVyczpcbiAgICAgIC5sLWdyb3VwX19pdGVtLS1sZWZ0XG4gICAgICAubC1ncm91cF9faXRlbS0tcmlnaHRcblxuICAgIFNpemUgbW9kaWZpZXJzOlxuICAgICAgLmwtZ3JvdXBfX2l0ZW0tLWdyb3dcblxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAubC1ncm91cFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmwtZ3JvdXAge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGZsZXgtc3RhcnQ7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbn1cblxuXG4ubC1ncm91cC0tYmxvY2sge1xuICBkaXNwbGF5OiBmbGV4O1xuICB3aWR0aDogMTAwJTtcbn1cblxuXG4ubC1ncm91cC0taG9yLWNlbnRlciB7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xufVxuXG4ubC1ncm91cC0taG9yLXJpZ2h0IHtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbn1cblxuXG4ubC1ncm91cC0tdmVyLWNlbnRlciB7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi5sLWdyb3VwLS12ZXItYm90dG9tIHtcbiAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xufVxuXG4ubC1ncm91cC0tdmVyLXN0cmV0Y2gge1xuICBhbGlnbi1pdGVtczogc3RyZXRjaDtcbn1cblxuLmwtZ3JvdXAtLWhvci1zcGFjZS1iZXR3ZWVuIHtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5sLWdyb3VwX19pdGVtXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4ubC1ncm91cF9faXRlbSB7XG5cbiAgJiArICYge1xuICAgIG1hcmdpbi1sZWZ0OiAkc3BhY2luZ191bml0X3ByaW1hcnk7XG5cbiAgICAubC1ncm91cC0tbm8tc3BhY2UgPiAmIHtcbiAgICAgIG1hcmdpbi1sZWZ0OiAwO1xuICAgIH1cblxuICAgIC5sLWdyb3VwLS1zZWNvbmRhcnkgPiAmIHtcbiAgICAgIG1hcmdpbi1sZWZ0OiAkc3BhY2luZ191bml0X3NlY29uZGFyeTtcbiAgICB9XG5cbiAgICAubC1ncm91cC0tdGVydGlhcnkgPiAmIHtcbiAgICAgIG1hcmdpbi1sZWZ0OiAkc3BhY2luZ191bml0X3RlcnRpYXJ5O1xuICAgIH1cblxuICAgIC5sLWdyb3VwLS1xdWF0ZXJuYXJ5ID4gJiB7XG4gICAgICBtYXJnaW4tbGVmdDogJHNwYWNpbmdfdW5pdF9xdWF0ZXJuYXJ5O1xuICAgIH1cblxuICB9XG5cbn1cblxuLmwtZ3JvdXBfX2l0ZW0tLWJvdHRvbSB7XG4gIGFsaWduLXNlbGY6IGZsZXgtZW5kO1xufVxuXG4ubC1ncm91cF9faXRlbS0tY2VudGVyIHtcbiAgYWxpZ24tc2VsZjogY2VudGVyO1xufVxuXG4ubC1ncm91cF9faXRlbS0tdG9wIHtcbiAgYWxpZ24tc2VsZjogZmxleC1zdGFydDtcbn1cblxuLmwtZ3JvdXBfX2l0ZW0tLWxlZnQge1xuICBtYXJnaW4tcmlnaHQ6IGF1dG87XG5cbiAgLmwtZ3JvdXBfX2l0ZW0gKyAmIHtcbiAgICBtYXJnaW4tcmlnaHQ6IGF1dG87XG4gIH1cblxufVxuXG4ubC1ncm91cF9faXRlbS0tcmlnaHQge1xuICBtYXJnaW4tbGVmdDogYXV0bztcblxuICAubC1ncm91cF9faXRlbSArICYge1xuICAgIG1hcmdpbi1sZWZ0OiBhdXRvO1xuICB9XG5cbn1cblxuLmwtZ3JvdXBfX2l0ZW0tLWdyb3cge1xuICBmbGV4LWdyb3c6IDE7XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjT1ZFUkxBWVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmwtb3ZlcmxheSB7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbiAgei1pbmRleDogbWFwLWdldCgkel9pbmRleCwgb3ZlcmxheSk7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNTUEFDRVxuXG4gIC5sLXNwYWNlLXByaW1hcnlcbiAgLmwtc3BhY2Utc2Vjb25kYXJ5XG4gIC5sLXNwYWNlLXRlcnRpYXJ5XG4gIC5sLXNwYWNlLXF1YXRlcm5hcnlcblxuICAubC1zcGFjZS12ZXItcHJpbWFyeVxuICAubC1zcGFjZS12ZXItc2Vjb25kYXJ5XG4gIC5sLXNwYWNlLXZlci10ZXJ0aWFyeVxuICAubC1zcGFjZS12ZXItcXVhdGVybmFyeVxuXG4gIC5sLXNwYWNlLWhvci1wcmltYXJ5XG4gIC5sLXNwYWNlLWhvci1zZWNvbmRhcnlcbiAgLmwtc3BhY2UtaG9yLXRlcnRpYXJ5XG4gIC5sLXNwYWNlLWhvci1xdWF0ZXJuYXJ5XG5cbiAgLmwtc3BhY2UtdG9wLXByaW1hcnlcbiAgLmwtc3BhY2UtdG9wLXNlY29uZGFyeVxuICAubC1zcGFjZS10b3AtdGVydGlhcnlcbiAgLmwtc3BhY2UtdG9wLXF1YXRlcm5hcnlcblxuICAubC1zcGFjZS1yaWdodC1wcmltYXJ5XG4gIC5sLXNwYWNlLXJpZ2h0LXNlY29uZGFyeVxuICAubC1zcGFjZS1yaWdodC10ZXJ0aWFyeVxuICAubC1zcGFjZS1yaWdodC1xdWF0ZXJuYXJ5XG5cbiAgLmwtc3BhY2UtYm90dG9tLXByaW1hcnlcbiAgLmwtc3BhY2UtYm90dG9tLXNlY29uZGFyeVxuICAubC1zcGFjZS1ib3R0b20tdGVydGlhcnlcbiAgLmwtc3BhY2UtYm90dG9tLXF1YXRlcm5hcnlcblxuICAubC1zcGFjZS1sZWZ0LXByaW1hcnlcbiAgLmwtc3BhY2UtbGVmdC1zZWNvbmRhcnlcbiAgLmwtc3BhY2UtbGVmdC10ZXJ0aWFyeVxuICAubC1zcGFjZS1sZWZ0LXF1YXRlcm5hcnlcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmwtc3BhY2VcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5sLXNwYWNlLXByaW1hcnkge1xuICBwYWRkaW5nOiAkc3BhY2luZ191bml0X3ByaW1hcnk7XG59XG5cbi5sLXNwYWNlLXNlY29uZGFyeSB7XG4gIHBhZGRpbmc6ICRzcGFjaW5nX3VuaXRfc2Vjb25kYXJ5O1xufVxuXG4ubC1zcGFjZS10ZXJ0aWFyeSB7XG4gIHBhZGRpbmc6ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG59XG5cbi5sLXNwYWNlLXF1YXRlcm5hcnkge1xuICBwYWRkaW5nOiAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG59XG5cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAubC1zcGFjZS12ZXJcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5sLXNwYWNlLXZlci1wcmltYXJ5IHtcbiAgcGFkZGluZy10b3A6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbiAgcGFkZGluZy1ib3R0b206ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLmwtc3BhY2UtdmVyLXNlY29uZGFyeSB7XG4gIHBhZGRpbmctdG9wOiAkc3BhY2luZ191bml0X3NlY29uZGFyeTtcbiAgcGFkZGluZy1ib3R0b206ICRzcGFjaW5nX3VuaXRfc2Vjb25kYXJ5O1xufVxuXG4ubC1zcGFjZS12ZXItdGVydGlhcnkge1xuICBwYWRkaW5nLXRvcDogJHNwYWNpbmdfdW5pdF90ZXJ0aWFyeTtcbiAgcGFkZGluZy1ib3R0b206ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG59XG5cbi5sLXNwYWNlLXZlci1xdWF0ZXJuYXJ5IHtcbiAgcGFkZGluZy10b3A6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbiAgcGFkZGluZy1ib3R0b206ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAubC1zcGFjZS1ob3JcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5sLXNwYWNlLWhvci1wcmltYXJ5IHtcbiAgcGFkZGluZy1sZWZ0OiAkc3BhY2luZ191bml0X3ByaW1hcnk7XG4gIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLmwtc3BhY2UtaG9yLXNlY29uZGFyeSB7XG4gIHBhZGRpbmctbGVmdDogJHNwYWNpbmdfdW5pdF9zZWNvbmRhcnk7XG4gIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfc2Vjb25kYXJ5O1xufVxuXG4ubC1zcGFjZS1ob3ItdGVydGlhcnkge1xuICBwYWRkaW5nLWxlZnQ6ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG4gIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG59XG5cbi5sLXNwYWNlLWhvci1xdWF0ZXJuYXJ5IHtcbiAgcGFkZGluZy1sZWZ0OiAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG4gIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAubC1zcGFjZS10b3BcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5sLXNwYWNlLXRvcC1wcmltYXJ5IHtcbiAgcGFkZGluZy10b3A6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLmwtc3BhY2UtdG9wLXNlY29uZGFyeSB7XG4gIHBhZGRpbmctdG9wOiAkc3BhY2luZ191bml0X3NlY29uZGFyeTtcbn1cblxuLmwtc3BhY2UtdG9wLXRlcnRpYXJ5IHtcbiAgcGFkZGluZy10b3A6ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG59XG5cbi5sLXNwYWNlLXRvcC1xdWF0ZXJuYXJ5IHtcbiAgcGFkZGluZy10b3A6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAubC1zcGFjZS1yaWdodFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmwtc3BhY2UtcmlnaHQtcHJpbWFyeSB7XG4gIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLmwtc3BhY2UtcmlnaHQtc2Vjb25kYXJ5IHtcbiAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF9zZWNvbmRhcnk7XG59XG5cbi5sLXNwYWNlLXJpZ2h0LXRlcnRpYXJ5IHtcbiAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF90ZXJ0aWFyeTtcbn1cblxuLmwtc3BhY2UtcmlnaHQtcXVhdGVybmFyeSB7XG4gIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAubC1zcGFjZS1ib3R0b21cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5sLXNwYWNlLWJvdHRvbS1wcmltYXJ5IHtcbiAgcGFkZGluZy1ib3R0b206ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLmwtc3BhY2UtYm90dG9tLXNlY29uZGFyeSB7XG4gIHBhZGRpbmctYm90dG9tOiAkc3BhY2luZ191bml0X3NlY29uZGFyeTtcbn1cblxuLmwtc3BhY2UtYm90dG9tLXRlcnRpYXJ5IHtcbiAgcGFkZGluZy1ib3R0b206ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG59XG5cbi5sLXNwYWNlLWJvdHRvbS1xdWF0ZXJuYXJ5IHtcbiAgcGFkZGluZy1ib3R0b206ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAubC1zcGFjZS1sZWZ0XG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4ubC1zcGFjZS1sZWZ0LXByaW1hcnkge1xuICBwYWRkaW5nLWxlZnQ6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLmwtc3BhY2UtbGVmdC1zZWNvbmRhcnkge1xuICBwYWRkaW5nLWxlZnQ6ICRzcGFjaW5nX3VuaXRfc2Vjb25kYXJ5O1xufVxuXG4ubC1zcGFjZS1sZWZ0LXRlcnRpYXJ5IHtcbiAgcGFkZGluZy1sZWZ0OiAkc3BhY2luZ191bml0X3RlcnRpYXJ5O1xufVxuXG4ubC1zcGFjZS1sZWZ0LXF1YXRlcm5hcnkge1xuICBwYWRkaW5nLWxlZnQ6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNXUkFQUEVSXG5cbiAgQmFzZTpcbiAgICAubC13cmFwcGVyXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cbi5sLXdyYXBwZXIge1xuICBtYXJnaW46IDAgYXV0bztcblxuICBAaW5jbHVkZSBhdi1tcShkZXNrKSB7XG4gICAgJiB7XG4gICAgICB3aWR0aDogJGdyaWRfd2lkdGg7XG4gICAgfVxuICB9XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjQkFER0VcblxuICBCYXNlOlxuICAgIC5jLWJhZGdlXG5cbiAgVmFyaWFudCB3aXRoIHRleHQ6XG4gICAgLmMtYmFkZ2UtLWhhcy10ZXh0XG5cbiAgQ29sb3IgbW9kaWZpZXJzOlxuICAgIC5jLWJhZGdlLS1hY3Rpb25cbiAgICAuYy1iYWRnZS0tZGFuZ2VyXG4gICAgLmMtYmFkZ2UtLWluYWN0aXZlXG4gICAgLmMtYmFkZ2UtLXN1Y2Nlc3NcbiAgICAuYy1iYWRnZS0td2FybmluZ1xuXG4gIFBvc2l0aW9uIG1vZGlmaWVyczpcbiAgICAuYy1iYWRnZS0tZm9yLWJ1dHRvblxuICAgIC5jLWJhZGdlLS1mb3ItdGFiXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4kX2JhZGdlX3NpemU6IDhweDtcbiRfYmFkZ2VfZmlsbGVkX3NpemU6IDE3cHg7XG4kX2JhZGdlX2ZvbnRfc2l6ZTogMTBweDtcblxuQG1peGluIF9iYWRnZV9jb250YWluZXIoJHNpemUpIHtcbiAgbWluLXdpZHRoOiAkc2l6ZTtcbiAgbWluLWhlaWdodDogJHNpemU7XG4gIGJvcmRlci1yYWRpdXM6ICRzaXplO1xuICBsaW5lLWhlaWdodDogJHNpemU7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtYmFkZ2UgKGRlZmF1bHQ6IGNpcmNsZSlcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJhZGdlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICBAaW5jbHVkZSBfYmFkZ2VfY29udGFpbmVyKCRfYmFkZ2Vfc2l6ZSk7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgdmFyaWFudCB3aXRoIHRleHRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJhZGdlLS1oYXMtdGV4dCB7XG4gIGZvbnQtc2l6ZTogJF9iYWRnZV9mb250X3NpemU7XG4gIHBhZGRpbmc6IDAgNnB4O1xuICBAaW5jbHVkZSBfYmFkZ2VfY29udGFpbmVyKCRfYmFkZ2VfZmlsbGVkX3NpemUpO1xufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIGNvbG9yc1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtYmFkZ2UtLWFjdGlvbiB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9jcnlzdGFsO1xufVxuXG4uYy1iYWRnZS0tZGFuZ2VyIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2Rhbmdlcjtcbn1cblxuLmMtYmFkZ2UtLWluYWN0aXZlIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2dvb2RtYW47XG59XG5cbi5jLWJhZGdlLS1zdWNjZXNzIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3N1Y2Nlc3M7XG59XG5cbi5jLWJhZGdlLS13YXJuaW5nIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3dhcm5pbmc7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgcG9zaXRpb25cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJhZGdlLS1mb3ItYnV0dG9uIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDE5cHg7XG59XG5cbi5jLWJhZGdlLS1mb3ItdGFiIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDE0cHg7XG4gIHJpZ2h0OiA3cHg7XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjQlVUVE9OXG5cbiAgQmFzZTpcbiAgICAuYy1idXR0b25cbiAgICAgIC5jLWJ1dHRvbl9faWNvblxuICAgICAgLmMtYnV0dG9uX190ZXh0XG5cbiAgU2hhcGUgbW9kaWZpZXJzOlxuICAgIC5jLWJ1dHRvbi0tcmVndWxhclxuICAgIC5jLWJ1dHRvbi0tZmxvYXRpbmdcbiAgICAuYy1idXR0b24tLWZsYXRcbiAgICAuYy1idXR0b24tLXRvZ2dsZVxuICAgIC5jLWJ1dHRvbi0tY2xlYW5cblxuICBDb2xvciBtb2RpZmllcnM6XG4gICAgLmMtYnV0dG9uLS1hY3Rpb25cbiAgICAuYy1idXR0b24tLXdhcm5pbmdcbiAgICAuYy1idXR0b24tLWRhbmdlclxuICAgIC5jLWJ1dHRvbi0tc3VjY2Vzc1xuXG4gICAgLmMtYnV0dG9uLS10d2l0dGVyXG4gICAgLmMtYnV0dG9uLS1nb29nbGVcbiAgICAuYy1idXR0b24tLWZhY2Vib29rXG4gICAgLmMtYnV0dG9uLS1kcnVwYWxcbiAgICAuYy1idXR0b24tLXdvcmRwcmVzc1xuXG4gIFNpemUgbW9kaWZpZXJzOlxuICAgIC5jLWJ1dHRvbi0tc21hbGxcbiAgICAuYy1idXR0b24tLWxhcmdlXG4gICAgLmMtYnV0dG9uLS14LWxhcmdlXG5cbiAgICAuYy1idXR0b24tLWJsb2NrXG5cbiAgU3RhdGUgbW9kaWZpZXJzOlxuICAgIC5jLWJ1dHRvbi5pcy1kaXNhYmxlZCAvIC5jLWJ1dHRvbjpkaXNhYmxlZFxuICAgIC5jLWJ1dHRvbi5pcy1hY3RpdmVcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRfYnV0dG9uX3JlZ3VsYXJfc2l6aW5nOiA0MHB4ICFkZWZhdWx0O1xuJF9idXR0b25fcmVndWxhcl9wYWRkaW5nOiAyMHB4ICFkZWZhdWx0O1xuXG4kX2J1dHRvbl9mbG9hdGluZ19zaXppbmc6IDQycHggIWRlZmF1bHQ7XG4kX2J1dHRvbl9mbG9hdGluZ19zaXppbmdfbGFyZ2U6IDgwcHggIWRlZmF1bHQ7XG4kX2J1dHRvbl9mbG9hdGluZ19zaXppbmdfeF9sYXJnZTogMTAwcHggIWRlZmF1bHQ7XG5cbiRfYnV0dG9uX2ZsYXRfc2l6aW5nOiAzMHB4ICFkZWZhdWx0O1xuJF9idXR0b25fZmxhdF9wYWRkaW5nOiAxMHB4ICFkZWZhdWx0O1xuXG4kX2J1dHRvbl90b2dnbGVfc2l6aW5nOiAzNHB4ICFkZWZhdWx0O1xuXG4kX2J1dHRvbl9jbGVhbl9zaXppbmc6IDE4cHggIWRlZmF1bHQ7XG5cbiRfYnV0dG9uX3NpbXBsZV9zaXppbmc6IDI0cHggIWRlZmF1bHQ7XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtYnV0dG9uX19pY29uLFxuICAuYy1idXR0b25fX3RleHRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJ1dHRvbl9faWNvbiB7XG4gIGxpbmUtaGVpZ2h0OiBpbmhlcml0O1xufVxuXG4uYy1idXR0b25fX2ljb24sXG4uYy1idXR0b25fX3RleHQge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIHZlcnRpY2FsLWFsaWduOiB0b3A7XG59XG5cbi5jLWJ1dHRvbl9faWNvbiArIC5jLWJ1dHRvbl9fdGV4dCxcbi5jLWJ1dHRvbl9fdGV4dCArIC5jLWJ1dHRvbl9faWNvbiB7XG4gIG1hcmdpbi1sZWZ0OiAkc3BhY2luZ191bml0X3ByaW1hcnk7XG59XG5cbi5jLWJ1dHRvbl9faWNvbi5mYSArIC5jLWJ1dHRvbl9fdGV4dCxcbi5jLWJ1dHRvbl9fdGV4dCArIC5jLWJ1dHRvbl9faWNvbi5mYSB7XG4gIG1hcmdpbi1sZWZ0OiAkc3BhY2luZ191bml0X3ByaW1hcnkgLSAyOyAvLyBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIGZvbnQgYXdlc29tZSByZW5kZXJpbmdcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1idXR0b25cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJ1dHRvbiB7XG4gIG91dGxpbmU6IDA7XG4gIGJvcmRlcjogMDtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nOiAwO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgdHJhbnNpdGlvbjogJHRyYW5zaXRpb25fcHJpbWFyeTtcbiAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9zZWNvbmRhcnk7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX21yd2hpdGU7XG5cbiAgJjpob3ZlciB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICB9XG5cbiAgJi5pcy1kaXNhYmxlZCxcbiAgJjpkaXNhYmxlZCB7XG4gICAgQGluY2x1ZGUgYnV0dG9uX2Rpc2FibGVkO1xuICB9XG5cbiAgJi5jLWJ1dHRvbi0tYmxvY2tcbiAge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHdpZHRoOiAxMDAlO1xuICB9XG59XG5cbi8vIEZGIGJ1dHRvbiBmaXgvcmVzZXRcbi5jLWJ1dHRvbjo6LW1vei1mb2N1cy1pbm5lciB7XG4gIGJvcmRlcjogMDtcbiAgcGFkZGluZzogMDtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1idXR0b24tLXJlZ3VsYXJcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJ1dHRvbi0tcmVndWxhciB7XG4gIEBpbmNsdWRlIGJ1dHRvbl9zaGFkb3c7XG4gIHBhZGRpbmc6IDAgJF9idXR0b25fcmVndWxhcl9wYWRkaW5nO1xuICBib3JkZXItcmFkaXVzOiAkYm9yZGVyX3JhZGl1c19wcmltYXJ5O1xuICBoZWlnaHQ6ICRfYnV0dG9uX3JlZ3VsYXJfc2l6aW5nO1xuICBsaW5lLWhlaWdodDogJF9idXR0b25fcmVndWxhcl9zaXppbmc7XG5cbiAgJi5jLWJ1dHRvbi0tc21hbGwge1xuICAgIGhlaWdodDogJF9idXR0b25fcmVndWxhcl9zaXppbmcgLSAxMDtcbiAgICBsaW5lLWhlaWdodDogJF9idXR0b25fcmVndWxhcl9zaXppbmcgLSAxMDtcbiAgICBwYWRkaW5nOiAwICRfYnV0dG9uX3JlZ3VsYXJfcGFkZGluZyAtIDU7XG4gICAgZm9udC1zaXplOiAkZm9udF9zaXplX3NlY29uZGFyeSAtIDI7XG5cbiAgICAuYy1idXR0b25fX2ljb24ge1xuICAgICAgZm9udC1zaXplOiAkaWNvbl9zaXplX3ByaW1hcnkgLSA0O1xuICAgIH1cbiAgfVxuXG4gICYuYy1idXR0b24tLWxhcmdlIHtcbiAgICBoZWlnaHQ6ICRfYnV0dG9uX3JlZ3VsYXJfc2l6aW5nICsgMTA7XG4gICAgbGluZS1oZWlnaHQ6ICRfYnV0dG9uX3JlZ3VsYXJfc2l6aW5nICsgMTA7XG4gICAgcGFkZGluZzogMCAkX2J1dHRvbl9yZWd1bGFyX3BhZGRpbmcgKyA1O1xuICB9XG5cbiAgJi5jLWJ1dHRvbi0teC1sYXJnZSB7XG4gICAgaGVpZ2h0OiAkX2J1dHRvbl9yZWd1bGFyX3NpemluZyArIDIwO1xuICAgIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl9yZWd1bGFyX3NpemluZyArIDIwO1xuICAgIHBhZGRpbmc6IDAgJF9idXR0b25fcmVndWxhcl9wYWRkaW5nICogMjtcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLWJ1dHRvbi0tZmxvYXRpbmdcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJ1dHRvbi0tZmxvYXRpbmcge1xuICBAaW5jbHVkZSBidXR0b25fc2hhZG93O1xuICB3aWR0aDogJF9idXR0b25fZmxvYXRpbmdfc2l6aW5nO1xuICBoZWlnaHQ6ICRfYnV0dG9uX2Zsb2F0aW5nX3NpemluZztcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xuICBjb2xvcjogJGNvbG9yX2dvb2RtYW47XG5cbiAgLmMtYnV0dG9uX19pY29uIHtcbiAgICBsaW5lLWhlaWdodDogJF9idXR0b25fZmxvYXRpbmdfc2l6aW5nO1xuICB9XG5cbiAgJi5jLWJ1dHRvbi0tc21hbGwge1xuICAgIHdpZHRoOiAkX2J1dHRvbl9mbG9hdGluZ19zaXppbmcgLSA4O1xuICAgIGhlaWdodDogJF9idXR0b25fZmxvYXRpbmdfc2l6aW5nIC0gODtcblxuICAgIC5jLWJ1dHRvbl9faWNvbiB7XG4gICAgICBsaW5lLWhlaWdodDogJF9idXR0b25fZmxvYXRpbmdfc2l6aW5nIC0gODtcbiAgICAgIGZvbnQtc2l6ZTogJGljb25fc2l6ZV9wcmltYXJ5IC0gNjtcbiAgICB9XG4gIH1cblxuICAmLmMtYnV0dG9uLS1sYXJnZSB7XG4gICAgd2lkdGg6ICRfYnV0dG9uX2Zsb2F0aW5nX3NpemluZ19sYXJnZTtcbiAgICBoZWlnaHQ6ICRfYnV0dG9uX2Zsb2F0aW5nX3NpemluZ19sYXJnZTtcblxuICAgIC5jLWJ1dHRvbl9faWNvbiB7XG4gICAgICBsaW5lLWhlaWdodDogJF9idXR0b25fZmxvYXRpbmdfc2l6aW5nX2xhcmdlO1xuICAgIH1cbiAgfVxuXG4gICYuYy1idXR0b24tLXgtbGFyZ2Uge1xuICAgIHdpZHRoOiAkX2J1dHRvbl9mbG9hdGluZ19zaXppbmdfeF9sYXJnZTtcbiAgICBoZWlnaHQ6ICRfYnV0dG9uX2Zsb2F0aW5nX3NpemluZ194X2xhcmdlO1xuXG4gICAgLmMtYnV0dG9uX19pY29uIHtcbiAgICAgIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl9mbG9hdGluZ19zaXppbmdfeF9sYXJnZTtcbiAgICB9XG4gIH1cbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1idXR0b24tLWZsYXRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJ1dHRvbi0tZmxhdCB7XG4gIHBhZGRpbmc6IDAgJF9idXR0b25fZmxhdF9wYWRkaW5nO1xuICBoZWlnaHQ6ICRfYnV0dG9uX2ZsYXRfc2l6aW5nO1xuICBsaW5lLWhlaWdodDogJF9idXR0b25fZmxhdF9zaXppbmc7XG4gIGJveC1zaGFkb3c6IG5vbmU7XG5cbiAgLy8gaW5jcmVhc2VkIHNwZWNpZml0eSBzbyBpdCBvdmVyd3JpdGVzIGFsbCBtb2RpZmljYXRvcnMgbGlrZSAuYy1idXR0b24tLWFjdGlvbiwgLmMtYnV0dG9uLS13YXJuaW5nIGV0Yy4gaW4gb25lIHBsYWNlXG4gICYuYy1idXR0b24tLWZsYXQge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuXG4gICAgJjpob3ZlcixcbiAgICAmLmlzLWFjdGl2ZSB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3Jfc2t5bGVyO1xuICAgICAgY29sb3I6ICRjb2xvcl90dWNvO1xuICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICB9XG5cbiAgICAmLmlzLWRpc2FibGVkLFxuICAgICY6ZGlzYWJsZWQge1xuICAgICAgY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgICB9XG4gIH1cblxuICAmLmMtYnV0dG9uLS1hY3Rpb24ge1xuICAgIGNvbG9yOiAkY29sb3JfY3J5c3RhbDtcbiAgfVxuXG4gICYuYy1idXR0b24tLXdhcm5pbmcge1xuICAgIGNvbG9yOiAkY29sb3Jfd2FybmluZztcbiAgfVxuXG4gICYuYy1idXR0b24tLWRhbmdlciB7XG4gICAgY29sb3I6ICRjb2xvcl9kYW5nZXI7XG4gIH1cblxuICAmLmMtYnV0dG9uLS1zdWNjZXNzIHtcbiAgICBjb2xvcjogJGNvbG9yX3N1Y2Nlc3M7XG4gIH1cblxuICAmLmMtYnV0dG9uLS1mYWNlYm9vayB7XG4gICAgY29sb3I6ICRjb2xvcl9mYWNlYm9vaztcbiAgfVxuXG4gICYuYy1idXR0b24tLXR3aXR0ZXIge1xuICAgIGNvbG9yOiAkY29sb3JfdHdpdHRlcjtcbiAgfVxuXG4gICYuYy1idXR0b24tLWdvb2dsZSB7XG4gICAgY29sb3I6ICRjb2xvcl9nb29nbGU7XG4gIH1cblxuICAmLmMtYnV0dG9uLS1kcnVwYWwge1xuICAgIGNvbG9yOiAkY29sb3JfZHJ1cGFsO1xuICB9XG5cbiAgJi5jLWJ1dHRvbi0td29yZHByZXNzIHtcbiAgICBjb2xvcjogJGNvbG9yX3dvcmRwcmVzcztcbiAgfVxuXG4gICYuYy1idXR0b24tLXNtYWxsIHtcbiAgICBoZWlnaHQ6ICRfYnV0dG9uX2ZsYXRfc2l6aW5nIC0gMTE7XG4gICAgbGluZS1oZWlnaHQ6ICRfYnV0dG9uX2ZsYXRfc2l6aW5nIC0gMTE7XG4gICAgcGFkZGluZzogMCAkX2J1dHRvbl9mbGF0X3BhZGRpbmcgLSA1O1xuICAgIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9zZWNvbmRhcnkgLSAyO1xuICB9XG5cbiAgJi5jLWJ1dHRvbi0tbGFyZ2Uge1xuICAgIGhlaWdodDogJF9idXR0b25fZmxhdF9zaXppbmcgKyAxMTtcbiAgICBsaW5lLWhlaWdodDogJF9idXR0b25fZmxhdF9zaXppbmcgKyAxMTtcbiAgICBwYWRkaW5nOiAwICRfYnV0dG9uX2ZsYXRfcGFkZGluZyAqIDIsNTtcbiAgfVxuXG4gICYuYy1idXR0b24tLXgtbGFyZ2Uge1xuICAgIGhlaWdodDogJF9idXR0b25fZmxhdF9zaXppbmcgKyAyMjtcbiAgICBsaW5lLWhlaWdodDogJF9idXR0b25fZmxhdF9zaXppbmcgKyAyMjtcbiAgICBwYWRkaW5nOiAwICRfYnV0dG9uX2ZsYXRfcGFkZGluZyAqIDQ7XG4gIH1cbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1idXR0b24tLXRvZ2dsZVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtYnV0dG9uLS10b2dnbGUge1xuICB3aWR0aDogJF9idXR0b25fdG9nZ2xlX3NpemluZztcbiAgaGVpZ2h0OiAkX2J1dHRvbl90b2dnbGVfc2l6aW5nO1xuICBib3JkZXItcmFkaXVzOiAkYm9yZGVyX3JhZGl1c19wcmltYXJ5O1xuICBjb2xvcjogJGNvbG9yX2dvb2RtYW47XG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuXG4gICYuaXMtYWN0aXZlLFxuICAmOmhvdmVyIHtcbiAgICBjb2xvcjogJGNvbG9yX3R1Y287XG4gICAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfc2Vjb25kYXJ5O1xuICB9XG5cbiAgJi5pcy1kaXNhYmxlZCxcbiAgJjpkaXNhYmxlZCB7XG4gICAgY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgfVxuXG4gICYuaXMtYWN0aXZlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3Jfc2t5bGVyO1xuICB9XG5cbiAgLmMtYnV0dG9uX19pY29uIHtcbiAgICBsaW5lLWhlaWdodDogJF9idXR0b25fdG9nZ2xlX3NpemluZztcbiAgfVxuXG4gICYuYy1idXR0b24tLWFjdGlvbixcbiAgJi5jLWJ1dHRvbi0td2FybmluZyxcbiAgJi5jLWJ1dHRvbi0tZGFuZ2VyLFxuICAmLmMtYnV0dG9uLS1zdWNjZXNzLFxuICAmLmMtYnV0dG9uLS1mYWNlYm9vayxcbiAgJi5jLWJ1dHRvbi0tdHdpdHRlcixcbiAgJi5jLWJ1dHRvbi0tZ29vZ2xlLFxuICAmLmMtYnV0dG9uLS1kcnVwYWwsXG4gICYuYy1idXR0b24tLXdvcmRwcmVzcyB7XG4gICAgJjpob3ZlcixcbiAgICAmLmlzLWFjdGl2ZSB7XG4gICAgICBjb2xvcjogJGNvbG9yX21yd2hpdGU7XG4gICAgfVxuICB9XG5cbiAgJi5jLWJ1dHRvbi0tc21hbGwge1xuICAgIHdpZHRoOiAkX2J1dHRvbl90b2dnbGVfc2l6aW5nIC0gODtcbiAgICBoZWlnaHQ6ICRfYnV0dG9uX3RvZ2dsZV9zaXppbmcgLSA4O1xuXG4gICAgLmMtYnV0dG9uX19pY29uIHtcbiAgICAgIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl90b2dnbGVfc2l6aW5nIC0gODtcbiAgICAgIGZvbnQtc2l6ZTogJGljb25fc2l6ZV9wcmltYXJ5IC0gNjtcbiAgICB9XG4gIH1cblxuICAmLmMtYnV0dG9uLS1sYXJnZSB7XG4gICAgd2lkdGg6ICRfYnV0dG9uX3RvZ2dsZV9zaXppbmcgKyAxMjtcbiAgICBoZWlnaHQ6ICRfYnV0dG9uX3RvZ2dsZV9zaXppbmcgKyAxMjtcblxuICAgIC5jLWJ1dHRvbl9faWNvbiB7XG4gICAgICBsaW5lLWhlaWdodDogJF9idXR0b25fdG9nZ2xlX3NpemluZyArIDEyO1xuICAgIH1cbiAgfVxuXG4gICYuYy1idXR0b24tLXgtbGFyZ2Uge1xuICAgIHdpZHRoOiAkX2J1dHRvbl90b2dnbGVfc2l6aW5nICsgMjQ7XG4gICAgaGVpZ2h0OiAkX2J1dHRvbl90b2dnbGVfc2l6aW5nICsgMjQ7XG5cbiAgICAuYy1idXR0b25fX2ljb24ge1xuICAgICAgbGluZS1oZWlnaHQ6ICRfYnV0dG9uX3RvZ2dsZV9zaXppbmcgKyAyNDtcbiAgICB9XG4gIH1cbn1cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtYnV0dG9uLS1jbGVhblxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtYnV0dG9uLS1jbGVhbiB7XG4gIGNvbG9yOiAkY29sb3JfZ29vZG1hbjtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl9jbGVhbl9zaXppbmc7XG5cbiAgJjpob3ZlciB7XG4gICAgY29sb3I6ICRjb2xvcl90dWNvO1xuICB9XG5cbiAgLmMtYnV0dG9uX19pY29uICsgLmMtYnV0dG9uX190ZXh0LFxuICAuYy1idXR0b25fX3RleHQgKyAuYy1idXR0b25fX2ljb24ge1xuICAgIG1hcmdpbi1sZWZ0OiAwO1xuICB9XG5cbiAgLmMtYnV0dG9uX19pY29uIHtcbiAgICBmb250LXNpemU6ICRfYnV0dG9uX2NsZWFuX3NpemluZztcbiAgICB3aWR0aDogJF9idXR0b25fY2xlYW5fc2l6aW5nO1xuICAgIGhlaWdodDogJF9idXR0b25fY2xlYW5fc2l6aW5nO1xuICB9XG5cbiAgJi5jLWJ1dHRvbi0tc21hbGwge1xuICAgIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl9jbGVhbl9zaXppbmcgLSA2O1xuICAgIGZvbnQtc2l6ZTogJF9idXR0b25fY2xlYW5fc2l6aW5nIC0gNjtcblxuICAgIC5jLWJ1dHRvbl9faWNvbiB7XG4gICAgICB3aWR0aDogJF9idXR0b25fY2xlYW5fc2l6aW5nIC0gNjtcbiAgICAgIGhlaWdodDogJF9idXR0b25fY2xlYW5fc2l6aW5nIC0gNjtcbiAgICAgIGZvbnQtc2l6ZTogJF9idXR0b25fY2xlYW5fc2l6aW5nIC0gNjtcbiAgICB9XG4gIH1cblxuICAmLmMtYnV0dG9uLS1sYXJnZSB7XG4gICAgbGluZS1oZWlnaHQ6ICRfYnV0dG9uX2NsZWFuX3NpemluZyArIDY7XG5cbiAgICAuYy1idXR0b25fX2ljb24ge1xuICAgICAgd2lkdGg6ICRfYnV0dG9uX2NsZWFuX3NpemluZyArIDY7XG4gICAgICBoZWlnaHQ6ICRfYnV0dG9uX2NsZWFuX3NpemluZyArIDY7XG4gICAgICBmb250LXNpemU6ICRfYnV0dG9uX2NsZWFuX3NpemluZyArIDY7XG4gICAgfVxuICB9XG5cbiAgJi5jLWJ1dHRvbi0teC1sYXJnZSB7XG4gICAgbGluZS1oZWlnaHQ6ICRfYnV0dG9uX2NsZWFuX3NpemluZyArIDEyO1xuXG4gICAgLmMtYnV0dG9uX19pY29uIHtcbiAgICAgIHdpZHRoOiAkX2J1dHRvbl9jbGVhbl9zaXppbmcgKyAxMjtcbiAgICAgIGhlaWdodDogJF9idXR0b25fY2xlYW5fc2l6aW5nICsgMTI7XG4gICAgICBmb250LXNpemU6ICRfYnV0dG9uX2NsZWFuX3NpemluZyArIDEyO1xuICAgIH1cbiAgfVxufVxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1idXR0b24tLXNpbXBsZVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtYnV0dG9uLS1zaW1wbGUge1xuICB0ZXh0LXRyYW5zZm9ybTogbm9uZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl9zaW1wbGVfc2l6aW5nO1xuXG4gIC5jLWJ1dHRvbl9faWNvbiArIC5jLWJ1dHRvbl9fdGV4dCxcbiAgLmMtYnV0dG9uX190ZXh0ICsgLmMtYnV0dG9uX19pY29uIHtcbiAgICBtYXJnaW4tbGVmdDogM3B4O1xuICB9XG5cbiAgLmMtYnV0dG9uX19pY29uIHtcbiAgICBmb250LXNpemU6ICRfYnV0dG9uX3NpbXBsZV9zaXppbmc7XG4gICAgd2lkdGg6ICRfYnV0dG9uX3NpbXBsZV9zaXppbmc7XG4gICAgaGVpZ2h0OiAkX2J1dHRvbl9zaW1wbGVfc2l6aW5nO1xuICB9XG5cbiAgJi5jLWJ1dHRvbi0tc21hbGwge1xuICAgIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl9zaW1wbGVfc2l6aW5nIC0gNjtcbiAgICBmb250LXNpemU6ICRmb250X3NpemVfdGVydGlhcnk7XG5cbiAgICAuYy1idXR0b25fX2ljb24ge1xuICAgICAgd2lkdGg6ICRfYnV0dG9uX3NpbXBsZV9zaXppbmcgLSA2O1xuICAgICAgaGVpZ2h0OiAkX2J1dHRvbl9zaW1wbGVfc2l6aW5nIC0gNjtcbiAgICAgIGZvbnQtc2l6ZTogJF9idXR0b25fc2ltcGxlX3NpemluZyAtIDY7XG4gICAgfVxuICB9XG5cbiAgJi5jLWJ1dHRvbi0tbGFyZ2Uge1xuICAgIGxpbmUtaGVpZ2h0OiAkX2J1dHRvbl9zaW1wbGVfc2l6aW5nICsgNjtcbiAgICBmb250LXNpemU6ICRmb250X3NpemVfcHJpbWFyeTtcblxuICAgIC5jLWJ1dHRvbl9faWNvbiB7XG4gICAgICB3aWR0aDogJF9idXR0b25fc2ltcGxlX3NpemluZyArIDY7XG4gICAgICBoZWlnaHQ6ICRfYnV0dG9uX3NpbXBsZV9zaXppbmcgKyA2O1xuICAgICAgZm9udC1zaXplOiAkX2J1dHRvbl9zaW1wbGVfc2l6aW5nICsgNjtcbiAgICB9XG4gIH1cblxuICAmLmMtYnV0dG9uLS14LWxhcmdlIHtcbiAgICBsaW5lLWhlaWdodDogJF9idXR0b25fc2ltcGxlX3NpemluZyArIDEyO1xuICAgIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9wcmltYXJ5O1xuXG4gICAgLmMtYnV0dG9uX19pY29uIHtcbiAgICAgIHdpZHRoOiAkX2J1dHRvbl9zaW1wbGVfc2l6aW5nICsgMTI7XG4gICAgICBoZWlnaHQ6ICRfYnV0dG9uX3NpbXBsZV9zaXppbmcgKyAxMjtcbiAgICAgIGZvbnQtc2l6ZTogJF9idXR0b25fc2ltcGxlX3NpemluZyArIDEyO1xuICAgIH1cbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLWJ1dHRvbiBjb2xvciBtb2RpZmllcnNcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWJ1dHRvbi0tYWN0aW9uIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gIGNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcblxuICAmOmhvdmVyLFxuICAmLmlzLWFjdGl2ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2NyeXN0YWxfYWN0aXZlO1xuICB9XG59XG5cbi5jLWJ1dHRvbi0td2FybmluZyB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl93YXJuaW5nO1xuICBjb2xvcjogJGNvbG9yX21yd2hpdGU7XG5cbiAgJjpob3ZlcixcbiAgJi5pcy1hY3RpdmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl93YXJuaW5nX2FjdGl2ZTtcbiAgfVxufVxuXG4uYy1idXR0b24tLWRhbmdlciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9kYW5nZXI7XG4gIGNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcblxuICAmOmhvdmVyLFxuICAmLmlzLWFjdGl2ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2Rhbmdlcl9hY3RpdmU7XG4gIH1cbn1cblxuLmMtYnV0dG9uLS1zdWNjZXNzIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3N1Y2Nlc3M7XG4gIGNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcblxuICAmOmhvdmVyLFxuICAmLmlzLWFjdGl2ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3N1Y2Nlc3NfYWN0aXZlO1xuICB9XG59XG5cbi5jLWJ1dHRvbi0tZ29vZ2xlIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2dvb2dsZTtcbiAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuXG4gICY6aG92ZXIsXG4gICYuaXMtYWN0aXZlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfZ29vZ2xlX2FjdGl2ZTtcbiAgfVxufVxuXG4uYy1idXR0b24tLWZhY2Vib29rIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2ZhY2Vib29rO1xuICBjb2xvcjogJGNvbG9yX21yd2hpdGU7XG5cbiAgJjpob3ZlcixcbiAgJi5pcy1hY3RpdmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9mYWNlYm9va19hY3RpdmU7XG4gIH1cbn1cblxuLmMtYnV0dG9uLS10d2l0dGVyIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3R3aXR0ZXI7XG4gIGNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcblxuICAmOmhvdmVyLFxuICAmLmlzLWFjdGl2ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3R3aXR0ZXJfYWN0aXZlO1xuICB9XG59XG5cbi5jLWJ1dHRvbi0tZHJ1cGFsIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2RydXBhbDtcbiAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuXG4gICY6aG92ZXIsXG4gICYuaXMtYWN0aXZlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfZHJ1cGFsX2FjdGl2ZTtcbiAgfVxufVxuXG4uYy1idXR0b24tLXdvcmRwcmVzcyB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl93b3JkcHJlc3M7XG4gIGNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcblxuICAmOmhvdmVyLFxuICAmLmlzLWFjdGl2ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3dvcmRwcmVzc19hY3RpdmU7XG4gIH1cbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNDT0xMRUNUSU9OXG5cbiAgQmFzZTpcbiAgICAuYy1jb2xsZWN0aW9uXG4gICAgICAuYy1jb2xsZWN0aW9uLWl0ZW1cbiAgICAgICAgLmMtY29sbGVjdGlvbi1pdGVtX19jb250ZW50XG4gICAgICAgIC5jLWNvbGxlY3Rpb24taXRlbV9fY29udGVudC1hZGRpdGlvbmFsIChvcHRpb25hbClcblxuICBDT0xMRUNUSU9OIE1PRElGSUVSUzpcbiAgICBDb2xsZWN0aW9uIHR5cGUgbW9kaWZpZXJzOlxuICAgICAgLmMtY29sbGVjdGlvbi0tc2ltcGxlXG4gICAgICAuYy1jb2xsZWN0aW9uLS13aXRoLXNoYWRvd1xuXG4gIENPTExFQ1RJT04gSVRFTSBNT0RJRklFUlM6XG4gICAgU2l6ZSBtb2RpZmllcnM6XG4gICAgICAuYy1jb2xsZWN0aW9uLWl0ZW0tLWxhcmdlXG4gICAgICAuYy1jb2xsZWN0aW9uLWl0ZW0tLXNtYWxsXG5cbiAgICBUeXBlIG1vZGlmaWVyczpcbiAgICAgIC5jLWNvbGxlY3Rpb24taXRlbS0taGVhZGluZ1xuICAgICAgLmMtY29sbGVjdGlvbi1pdGVtLS1wbGFjZWhvbGRlclxuXG4gICAgU3RhdHVzIG1vZGlmaWVyczpcbiAgICAgIC5jLWNvbGxlY3Rpb24taXRlbS5pcy1kaXNhYmxlZFxuICAgICAgLmMtY29sbGVjdGlvbi1pdGVtLmlzLWRyYWdnYWJsZVxuICAgICAgLmMtY29sbGVjdGlvbi1pdGVtLmlzLWRlbGV0ZWRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRfY29sbGVjdGlvbl9pdGVtX2hlaWdodF9wcmltYXJ5OiA1MHB4O1xuJF9jb2xsZWN0aW9uX2l0ZW1faGVpZ2h0X3NlY29uZGFyeTogODBweDtcbiRfY29sbGVjdGlvbl9pdGVtX2hlaWdodF90ZXJ0aWFyeTogNDBweDtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1jb2xsZWN0aW9uXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1jb2xsZWN0aW9uIHtcblxuICBmb250LXNpemU6ICRmb250X3NpemVfc2Vjb25kYXJ5O1xufVxuXG4uYy1jb2xsZWN0aW9uLS1zaW1wbGUge1xuICBib3JkZXItYm90dG9tOiBub25lO1xuXG4gIC5jLWNvbGxlY3Rpb24taXRlbTpsYXN0LWNoaWxkIHtcbiAgICBib3JkZXItYm90dG9tOiAwO1xuICB9XG59XG5cbi5jLWNvbGxlY3Rpb24tLXdpdGgtc2hhZG93IHtcbiAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfcHJpbWFyeTtcbiAgYm9yZGVyLXJhZGl1czogJGJvcmRlcl9yYWRpdXNfcHJpbWFyeTtcbiAgYm9yZGVyLWJvdHRvbTogbm9uZTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1jb2xsZWN0aW9uLWl0ZW1cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWNvbGxlY3Rpb24taXRlbSB7XG4gIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uX3ByaW1hcnk7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuXG4gICYuaXMtZGlzYWJsZWQge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgfVxuXG4gICYuaXMtZHJhZ2dhYmxlIHtcbiAgICBib3gtc2hhZG93OiAkYm94X3NoYWRvd19xdWluYXJ5O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBjdXJzb3I6IG1vdmU7XG5cbiAgICAuYy1jb2xsZWN0aW9uLWl0ZW0gKyAmIHtcbiAgICAgIGJvcmRlci10b3A6IG5vbmU7XG4gICAgfVxuXG4gIH1cblxuICAmLmlzLWRlbGV0ZWQge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIGNvbG9yOiAkY29sb3JfZ3VzdGF2bztcbiAgICB0ZXh0LWRlY29yYXRpb246IGxpbmUtdGhyb3VnaDtcbiAgfVxuXG4gICYgICsgLmMtY29sbGVjdGlvbi1pdGVtICB7XG4gICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICRjb2xvcl9oZXJtYW5vcztcblxuICAgIC5jLWNvbGxlY3Rpb24tLXNpbXBsZSAmIHtcbiAgICAgIGJvcmRlci10b3A6IG5vbmU7XG4gICAgfVxuXG4gIH1cblxuICAmOmxhc3QtY2hpbGQge1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAkY29sb3JfaGVybWFub3M7XG4gIH1cblxuICAmIC5jLWNvbGxlY3Rpb24taXRlbTpsYXN0LWNoaWxkIHtcbiAgICBib3JkZXItYm90dG9tOiAwO1xuICB9XG5cbiAgLmMtY29sbGVjdGlvbi0td2l0aC1zaGFkb3cgJjpmaXJzdC1jaGlsZCB7XG4gICAgYm9yZGVyLXRvcC1sZWZ0LXJhZGl1czogJGJvcmRlcl9yYWRpdXNfcHJpbWFyeTtcbiAgICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogJGJvcmRlcl9yYWRpdXNfcHJpbWFyeTtcbiAgfVxuXG4gIC5jLWNvbGxlY3Rpb24tLXdpdGgtc2hhZG93ICY6bGFzdC1jaGlsZCB7XG4gICAgYm9yZGVyLWJvdHRvbS1sZWZ0LXJhZGl1czogJGJvcmRlcl9yYWRpdXNfcHJpbWFyeTtcbiAgICBib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czogJGJvcmRlcl9yYWRpdXNfcHJpbWFyeTtcbiAgfVxuXG59XG5cbi5jLWNvbGxlY3Rpb24taXRlbS0taGVhZGluZyB7XG4gIGNvbG9yOiAkY29sb3JfZ3VzdGF2bztcbiAgZm9udC1zaXplOiAkZm9udF9zaXplX3NlY29uZGFyeTtcbiAgbGluZS1oZWlnaHQ6IDEuNDtcbn1cblxuLmMtY29sbGVjdGlvbi1pdGVtLS1wbGFjZWhvbGRlciB7XG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLWNvbGxlY3Rpb24taXRlbV9fY29udGVudFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbi5jLWNvbGxlY3Rpb24taXRlbV9fY29udGVudCB7XG4gIGhlaWdodDogJF9jb2xsZWN0aW9uX2l0ZW1faGVpZ2h0X3ByaW1hcnk7XG4gIHBhZGRpbmctbGVmdDogJHNwYWNpbmdfdW5pdF9xdWF0ZXJuYXJ5O1xuICBwYWRkaW5nLXJpZ2h0OiAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG5cbiAgLmMtY29sbGVjdGlvbi1pdGVtLS1sYXJnZSA+ICYge1xuICAgIGhlaWdodDogJF9jb2xsZWN0aW9uX2l0ZW1faGVpZ2h0X3NlY29uZGFyeTtcbiAgfVxuXG4gIC5jLWNvbGxlY3Rpb24taXRlbS0tc21hbGwgPiAmIHtcbiAgICBoZWlnaHQ6ICRfY29sbGVjdGlvbl9pdGVtX2hlaWdodF90ZXJ0aWFyeTtcbiAgfVxuXG4gIC5sLWdyaWQge1xuICAgIGZsZXgtZ3JvdzogMTtcbiAgfVxuXG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjRFJPUERPV05cblxuICBCYXNlOlxuICAgIC5jLWRyb3Bkb3duXG4gICAgICAuYy1kcm9wZG93bl9fdHJpZ2dlclxuICAgICAgLmMtZHJvcGRvd25fX2NvbnRlbnRcblxuICBEaXNwbGF5IG1vZGlmaWVyczpcbiAgICAuYy1kcm9wZG93bi0tcmlnaHQtY29ybmVyXG5cbiAgU3RhdGUgbW9kaWZpZXJzOlxuICAgIC5jLWRyb3Bkb3duLmlzLW9wZW5cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWRyb3Bkb3duIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4uYy1kcm9wZG93bl9fY29udGVudCB7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIGRpc3BsYXk6IG5vbmU7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICBib3gtc2hhZG93OiAkYm94X3NoYWRvd19wcmltYXJ5O1xuICBib3JkZXItcmFkaXVzOiAkYm9yZGVyX3JhZGl1c19wcmltYXJ5O1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHotaW5kZXg6IG1hcC1nZXQoJHpfaW5kZXgsIGRyb3Bkb3duKTtcbiAgdG9wOiAwO1xuXG4gIC5pcy1vcGVuID4gJiB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgYW5pbWF0aW9uOiBmYWRlSW4gLjNzO1xuICB9XG5cbiAgLmMtZHJvcGRvd24tLXJpZ2h0LWNvcm5lciAmIHtcbiAgICByaWdodDogMDtcbiAgfVxuXG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjUklQUExFIEVGRkVDVFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuQGtleWZyYW1lcyByaXBwbGUge1xuICAxMDAlIHtcbiAgICBvcGFjaXR5OiAwO1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMi41KTtcbiAgfVxufVxuXG4uZngtcmlwcGxlLWVmZmVjdCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDAsMCk7XG59XG5cbi5meC1pbmsge1xuICBkaXNwbGF5OiBibG9jaztcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xuICB0cmFuc2Zvcm06IHNjYWxlKDApO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCRjb2xvcl9qZXNzZSwgLjE1KTtcbiAgb3BhY2l0eTogMTtcblxuICAgICYuZngtYW5pbWF0ZSB7XG4gICAgICBhbmltYXRpb246IHJpcHBsZSAuNXMgbGluZWFyO1xuICAgIH1cbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjRkFERSBJTiBBTklNQVRJT05cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbkBrZXlmcmFtZXMgZmFkZUluIHtcbiAgZnJvbSB7XG4gICAgb3BhY2l0eTogMDtcbiAgfVxuXG4gIHRvIHtcbiAgICBvcGFjaXR5OiAxO1xuICB9XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI0RJTSBFRkZFQ1RcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5meC1kaW0tZWZmZWN0IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgkY29sb3JfamVzc2UsIC44KTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjQkxVUiBFRkZFQ1RcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5meC1ibHVyLWVmZmVjdCB7XG4gIGZpbHRlcjogYmx1cigzcHgpO1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI0VYUEFOREFCTEUtSVRFTVxuXG4gIEJhc2U6XG4gICAgLmMtZXhwYW5kYWJsZS1pdGVtXG4gICAgICAuYy1leHBhbmRhYmxlLWl0ZW1fX3RyaWdnZXJcbiAgICAgICAgLmMtZXhwYW5kYWJsZS1pdGVtX19pY29uIChvcHRpb25hbClcbiAgICAgIC5jLWV4cGFuZGFibGUtaXRlbV9fd3JhcHBlclxuICAgICAgICAuYy1leHBhbmRhYmxlLWl0ZW1fX2NvbnRlbnRcblxuICBTdGF0ZSBtb2RpZmllcnM6XG4gICAgLmMtZXhwYW5kYWJsZS1pdGVtLmlzLWV4cGFuZGVkXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1leHBhbmRhYmxlLWl0ZW1fX3RyaWdnZXIge1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5jLWV4cGFuZGFibGUtaXRlbV9faWNvbiB7XG4gIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uX3ByaW1hcnk7XG5cbiAgLmMtZXhwYW5kYWJsZS1pdGVtLmlzLWV4cGFuZGVkICYge1xuICAgIHRyYW5zZm9ybTogcm90YXRlKC0xODBkZWcpO1xuICB9XG5cbn1cblxuLmMtZXhwYW5kYWJsZS1pdGVtX193cmFwcGVyIHtcbiAgaGVpZ2h0OiAwO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0cmFuc2l0aW9uOiAkdHJhbnNpdGlvbl9wcmltYXJ5O1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI0lMTFVTVFJBVElPTlxuXG4gIEJhc2U6XG4gICAgLmMtaWxsdXN0cmF0aW9uXG4gICAgICAuYy1pbGx1c3RyYXRpb25fX2ljb24gLSB1c2VkIHRvZ2V0aGVyIHdpdGggLmMtaWxsdXN0cmF0aW9uLS1kZXRhaWxzXG5cbiAgU3RhdGUgbW9kaWZpZXJzOlxuICAgIC5jLWlsbHVzdHJhdGlvbi0tZW1wdHlcbiAgICAuYy1pbGx1c3RyYXRpb24tLWRldGFpbHMgLSBiZyBjb2xvciBvbiA6aG92ZXIgKyBpY29uXG5cbiAgSWxsdXN0cmF0aW9uIG1vZGlmaWVyczpcbiAgICAuYy1pbGx1c3RyYXRpb24tLXVzZXJcbiAgICAuYy1pbGx1c3RyYXRpb24tLXdvcmxkXG4gICAgLmMtaWxsdXN0cmF0aW9uLS13b3JkcHJlc3NcbiAgICAuYy1pbGx1c3RyYXRpb24tLWRydXBhbFxuICAgIC5jLWlsbHVzdHJhdGlvbi0tZmFjZWJvb2tcbiAgICAuYy1pbGx1c3RyYXRpb24tLWRlbW9wYWdlXG4gICAgLmMtaWxsdXN0cmF0aW9uLS10ZW1wbGF0ZVxuXG4gIFNpemUgbW9kaWZpZXJzOlxuICAgIC5jLWlsbHVzdHJhdGlvbi0tbGFyZ2VcbiAgICAuYy1pbGx1c3RyYXRpb24tLXgtbGFyZ2VcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRfaWxsdXN0cmF0aW9uX3NpemU6IDQycHggIWRlZmF1bHQ7XG4kX2lsbHVzdHJhdGlvbl9zaXplX2xhcmdlOiA4MHB4ICFkZWZhdWx0O1xuJF9pbGx1c3RyYXRpb25fc2l6ZV94X2xhcmdlOiAxMDBweCAhZGVmYXVsdDtcbiRfaWxsdXN0cmF0aW9uX2JvcmRlcl93aWR0aDogMXB4ICFkZWZhdWx0O1xuXG5cbi5jLWlsbHVzdHJhdGlvbiB7XG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgd2lkdGg6ICRfaWxsdXN0cmF0aW9uX3NpemU7XG4gIGhlaWdodDogJF9pbGx1c3RyYXRpb25fc2l6ZTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBiYWNrZ3JvdW5kLXNpemU6IGNvdmVyO1xuICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG5cbiAgLy8gb3ZlcnJpZGluZyBzb21lIHByb3BlcnRpZXMgd2hlbiBuZXN0ZWQgaW5zaWRlIGJ1dHRvblxuICAuYy1idXR0b24gJiB7XG4gICAgYm9yZGVyOiAwO1xuICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgd2lkdGg6IGluaGVyaXQ7XG4gICAgaGVpZ2h0OiBpbmhlcml0O1xuICB9XG59XG5cbi5jLWlsbHVzdHJhdGlvbi0tZW1wdHkge1xuICBib3JkZXI6ICRfaWxsdXN0cmF0aW9uX2JvcmRlcl93aWR0aCBzb2xpZCAkY29sb3JfaGVybWFub3M7XG59XG5cbi5jLWlsbHVzdHJhdGlvbi0tbGFyZ2Uge1xuICB3aWR0aDogJF9pbGx1c3RyYXRpb25fc2l6ZV9sYXJnZTtcbiAgaGVpZ2h0OiAkX2lsbHVzdHJhdGlvbl9zaXplX2xhcmdlO1xufVxuXG4uYy1pbGx1c3RyYXRpb24tLXgtbGFyZ2Uge1xuICB3aWR0aDogJF9pbGx1c3RyYXRpb25fc2l6ZV94X2xhcmdlO1xuICBoZWlnaHQ6ICRfaWxsdXN0cmF0aW9uX3NpemVfeF9sYXJnZTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1pbGx1c3RyYXRpb24tLWRldGFpbHNcbiAgLmMtaWxsdXN0cmF0aW9uX19pY29uXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1pbGx1c3RyYXRpb24tLWRldGFpbHMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gICY6OmJlZm9yZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgkY29sb3JfamVzc2UsIC41KTtcbiAgICB0cmFuc2l0aW9uOiAkdHJhbnNpdGlvbl9wcmltYXJ5O1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMCk7XG4gICAgdHJhbnNmb3JtLW9yaWdpbjogY2VudGVyO1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgLy8gbXVzdCBiZSBhIGJpdCBiaWdnZXIgdGhhbiBwYXJlbnQgc28gdGhlIGVkZ2UgbGluZSBpcyBzbW9vdGhlclxuICAgIGhlaWdodDogY2FsYygxMDAlICsgI3skX2lsbHVzdHJhdGlvbl9ib3JkZXJfd2lkdGggKiAyfSk7XG4gICAgd2lkdGg6IGNhbGMoMTAwJSArICN7JF9pbGx1c3RyYXRpb25fYm9yZGVyX3dpZHRoICogMn0pO1xuICAgIGxlZnQ6IC0oJF9pbGx1c3RyYXRpb25fYm9yZGVyX3dpZHRoKTtcbiAgICB0b3A6IC0oJF9pbGx1c3RyYXRpb25fYm9yZGVyX3dpZHRoKTtcbiAgfVxufVxuXG4uYy1pbGx1c3RyYXRpb25fX2ljb24ge1xuICBjb2xvcjogJGNvbG9yX21yd2hpdGU7XG4gIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uX3ByaW1hcnk7XG4gIHRyYW5zZm9ybTogc2NhbGUoMCk7XG4gIHRyYW5zZm9ybS1vcmlnaW46IGNlbnRlcjtcbn1cblxuLmMtYnV0dG9uOmhvdmVyLCAvLyBGaXJlZm94IGZpeCAtIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTg0MzAwM1xuLmMtaWxsdXN0cmF0aW9uLS1kZXRhaWxzOmhvdmVyIHtcbiAgLmMtaWxsdXN0cmF0aW9uX19pY29uLFxuICAuYy1pbGx1c3RyYXRpb24tLWRldGFpbHM6OmJlZm9yZSB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIElsbHVzdHJhdGlvbiBtb2RpZmllcnNcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLWlsbHVzdHJhdGlvbi0tdXNlciB7XG4gIGJhY2tncm91bmQtaW1hZ2U6IHVybCgkc3ZnX3VzZXIpO1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXIgMTUlO1xuICBiYWNrZ3JvdW5kLXNpemU6IDEyOCU7XG59XG5cbi5jLWlsbHVzdHJhdGlvbi0td29ybGQge1xuICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJHN2Z193b3JsZCk7XG59XG5cbi5jLWlsbHVzdHJhdGlvbi0td29yZHByZXNzIHtcbiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCRzdmdfd29yZHByZXNzKTtcbn1cblxuLmMtaWxsdXN0cmF0aW9uLS1kcnVwYWwge1xuICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJHN2Z19kcnVwYWwpO1xufVxuXG4uYy1pbGx1c3RyYXRpb24tLWZhY2Vib29rIHtcbiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCRzdmdfZmFjZWJvb2spO1xufVxuXG4uYy1pbGx1c3RyYXRpb24tLWRlbW9wYWdlIHtcbiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCRzdmdfZGVtb3BhZ2UpO1xufVxuXG4uYy1pbGx1c3RyYXRpb24tLXRlbXBsYXRlIHtcbiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCRzdmdfdGVtcGxhdGUpO1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI0lOUFVUIChJbmNsdWRpbmcgc3RhbmRhcmQgaW5wdXRbdHlwZT1cInRleHRcIl0gYW5kIHRleHRhcmVhKVxuXG4gIEJhc2U6XG4gICAgLmMtZm9ybS10ZXh0XG5cbiAgICAuYy1mb3JtLXRleHQtaXRlbVxuICAgICAgLmMtZm9ybS10ZXh0LWl0ZW1fX2ZpZWxkXG4gICAgICAuYy1mb3JtLXRleHQtaXRlbV9fbGFiZWxcbiAgICAgIC5jLWZvcm0tdGV4dC1pdGVtX19iYXJcbiAgICAgIC5jLWZvcm0tdGV4dC1pdGVtX19pbmZvXG4gICAgICAuYy1mb3JtLXRleHQtaXRlbV9fYnV0dG9uXG4gICAgICAuYy1mb3JtLXRleHQtaXRlbV9faWNvblxuXG4gIFNpemUgbW9kaWZpZXJzOlxuICAgIC5jLWZvcm0tdGV4dC1pdGVtLS1zbWFsbFxuICAgIC5jLWZvcm0tdGV4dC1pdGVtLS14LXNtYWxsXG4gICAgLmMtZm9ybS10ZXh0LWl0ZW0tLW5vLWluZm9cbiAgICAuYy1mb3JtLXRleHQtaXRlbS0tbm8tbGFiZWxcbiAgICBcbiAgICAuYy1mb3JtLXRleHQtaXRlbV9fYnV0dG9uLmMtZm9ybS10ZXh0LWl0ZW1fX2J1dHRvbi0tc21hbGxcblxuICBGaWVsZCBtb2RpZmllcnM6XG4gICAgLmMtZm9ybS10ZXh0LWl0ZW1fX2ZpZWxkLS13aXRoLWljb25cblxuICBTdGF0ZSBtb2RpZmllcnM6XG4gICAgLmMtZm9ybS10ZXh0LWl0ZW1fX2ZpZWxkLmlzLW5vdC1lbXB0eVxuICAgIC5jLWZvcm0tdGV4dC1pdGVtX19maWVsZDpmb2N1c1xuXG4gICAgLmMtZm9ybS10ZXh0LWl0ZW0uaGFzLWFjdGlvblxuICAgIC5jLWZvcm0tdGV4dC1pdGVtLmhhcy1kYW5nZXJcbiAgICAuYy1mb3JtLXRleHQtaXRlbS5oYXMtc3VjY2Vzc1xuICAgIC5jLWZvcm0tdGV4dC1pdGVtLmhhcy13YXJuaW5nXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4kX2ZpZWxkX3NpemVfcHJpbWFyeTogMTdweDtcbiRfZmllbGRfc2l6ZV9zZWNvbmRhcnk6IDIycHg7XG4kX2ZpZWxkX2Jhcl9oZWlnaHQ6IDJweDtcblxuLmMtZm9ybS10ZXh0LFxuLmMtZm9ybS10ZXh0LWl0ZW1fX2ZpZWxkICB7XG4gIGxpbmUtaGVpZ2h0OiAkX2ZpZWxkX3NpemVfc2Vjb25kYXJ5O1xufVxuXG4uYy1mb3JtLXRleHQtaXRlbSB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB6LWluZGV4OiAwOyAvLyBhZGRlZCBzbyBsYWJlbCBzdGF5cyB2aXNpYmxlXG4gIHdpZHRoOiAxMDAlO1xuICBwYWRkaW5nOiAkX2ZpZWxkX3NpemVfcHJpbWFyeSAwICRfZmllbGRfc2l6ZV9zZWNvbmRhcnk7IC8vIHdlIG5lZWQgc29tZSBzcGFjZSBmb3IgcG9zaXRpb25pbmcgYWJzb2x1dGUgLmMtZm9ybS10ZXh0LWl0ZW1fX2xhYmVsIGFuZCAuYy1mb3JtLXRleHQtaXRlbV9faW5mb1xuXG4gICYgKyAuYy1mb3JtLXRleHQtaXRlbSB7XG4gICAgbWFyZ2luLXRvcDogJHNwYWNpbmdfdW5pdF9zZWNvbmRhcnk7XG4gIH1cblxuICAmLmMtZm9ybS10ZXh0LWl0ZW0tLW5vLWxhYmVsIHtcbiAgICBwYWRkaW5nLXRvcDogMDtcbiAgfVxuXG4gICYuYy1mb3JtLXRleHQtaXRlbS0tbm8taW5mbyB7XG4gICAgcGFkZGluZy1ib3R0b206IDA7XG4gIH1cblxufVxuXG4uYy1mb3JtLXRleHQtaXRlbV9fZmllbGQge1xuICBiYWNrZ3JvdW5kOiBub25lO1xuICBib3JkZXI6IG5vbmU7XG4gIHBhZGRpbmc6IDAgMCAzcHg7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAkY29sb3JfaGVybWFub3M7XG4gIG91dGxpbmU6IG5vbmU7XG4gIHdpZHRoOiAxMDAlO1xuICBmb250LXNpemU6IGluaGVyaXQ7XG4gIGNvbG9yOiBpbmhlcml0O1xuICB0cmFuc2l0aW9uOiAkdHJhbnNpdGlvbl9wcmltYXJ5O1xuXG4gIC5jLWZvcm0tdGV4dC1pdGVtLS1zbWFsbCAmLFxuICAuYy1mb3JtLXRleHQtaXRlbS0teC1zbWFsbCAgJiB7XG4gICAgcGFkZGluZy1ib3R0b206IDJweDtcbiAgfVxuXG4gIC5jLWZvcm0tdGV4dC1pdGVtLS1zbWFsbCAmIHtcbiAgICBmb250LXNpemU6ICRmb250X3NpemVfc2Vjb25kYXJ5O1xuICB9XG5cbiAgLmMtZm9ybS10ZXh0LWl0ZW0tLXgtc21hbGwgJiB7XG4gICAgZm9udC1zaXplOiAkZm9udF9zaXplX3RlcnRpYXJ5O1xuICB9XG5cbiAgJjo6cGxhY2Vob2xkZXIge1xuICAgIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gICAgY29sb3I6ICRjb2xvcl9ndXN0YXZvO1xuICB9XG5cbiAgLmMtZm9ybS10ZXh0LWl0ZW0uaGFzLWRhbmdlciAmLFxuICAuYy1mb3JtLXRleHQtaXRlbS5oYXMtd2FybmluZyAmLFxuICAuYy1mb3JtLXRleHQtaXRlbS5oYXMtYWN0aW9uICYsXG4gIC5jLWZvcm0tdGV4dC1pdGVtLmhhcy1zdWNjZXNzICYsXG4gICY6Zm9jdXMge1xuICAgIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gIH1cblxufVxuXG4uYy1mb3JtLXRleHQtaXRlbV9fZmllbGQtLXdpdGgtaWNvbiB7XG4gIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcblxuICAuYy1mb3JtLXRleHQtaXRlbS0tc21hbGwgJiB7XG4gICAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF9wcmltYXJ5O1xuICB9XG59XG5cbnRleHRhcmVhLmMtZm9ybS10ZXh0LWl0ZW1fX2ZpZWxkIHtcbiAgaGVpZ2h0OiA5MnB4O1xuICBsaW5lLWhlaWdodDogMS44O1xuICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgdmVydGljYWwtYWxpZ246IHRvcDtcbiAgcmVzaXplOiB2ZXJ0aWNhbDtcbn1cblxuLmMtZm9ybS10ZXh0LWl0ZW1fX2xhYmVsIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiAwO1xuICB0b3A6ICRfZmllbGRfc2l6ZV9wcmltYXJ5ICsgMztcbiAgei1pbmRleDogLTE7IC8vIGFkZGVkIHNvIGlucHV0IHN0YXlzIGNsaWNrYWJsZVxuICB0cmFuc2l0aW9uOiAkdHJhbnNpdGlvbl9wcmltYXJ5O1xuICBjb2xvcjogJGNvbG9yX2d1c3Rhdm87XG5cbiAgLmMtZm9ybS10ZXh0LWl0ZW0tLXNtYWxsICYge1xuICAgIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9zZWNvbmRhcnk7XG4gIH1cblxuICAuYy1mb3JtLXRleHQtaXRlbS0teC1zbWFsbCAmIHtcbiAgICBmb250LXNpemU6ICRmb250X3NpemVfdGVydGlhcnk7XG4gIH1cblxuICAuYy1mb3JtLXRleHQtaXRlbV9fZmllbGQuaXMtbm90LWVtcHR5IH4gJixcbiAgLmMtZm9ybS10ZXh0LWl0ZW1fX2ZpZWxkOmZvY3VzIH4gJiB7XG4gICAgZm9udC1zaXplOiAkZm9udF9zaXplX3RlcnRpYXJ5O1xuICAgIHRvcDogMDtcbiAgfVxuXG59XG5cbi5jLWZvcm0tdGV4dC1pdGVtX19iYXIge1xuICBAaW5jbHVkZSBmb3JtX2l0ZW1fdW5kZXJsaW5lX2VmZmVjdCgnLmMtZm9ybS10ZXh0LWl0ZW1fX2ZpZWxkOmZvY3VzIH4gJiwgLnNlbGVjdDItY29udGFpbmVyLS1vcGVuIH4gJicpO1xufVxuXG4uYy1mb3JtLXRleHQtaXRlbV9fYnV0dG9uLFxuLmMtZm9ybS10ZXh0LWl0ZW1fX2ljb24ge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHJpZ2h0OiAwO1xuICB0b3A6ICRfZmllbGRfc2l6ZV9wcmltYXJ5O1xuICB6LWluZGV4OiAtMTtcblxuICAuYy1mb3JtLXRleHQtaXRlbS0tbm8tbGFiZWwgJiB7XG4gICAgdG9wOiAwO1xuICB9XG5cbn1cblxuLmMtZm9ybS10ZXh0LWl0ZW1fX2J1dHRvbi0tc21hbGwge1xuICB0b3A6ICRfZmllbGRfc2l6ZV9wcmltYXJ5ICsgNDtcblxuICAuYy1mb3JtLXRleHQtaXRlbS0tbm8tbGFiZWwgJiB7XG4gICAgdG9wOiA1cHg7XG4gIH1cblxufVxuXG4uYy1mb3JtLXRleHQtaXRlbV9faWNvbiB7XG4gIGxpbmUtaGVpZ2h0OiAkaWNvbl9zaXplX3ByaW1hcnk7XG4gIHdpZHRoOiAkaWNvbl9zaXplX3ByaW1hcnk7XG4gIGZvbnQtc2l6ZTogJGljb25fc2l6ZV9wcmltYXJ5O1xuICBjb2xvcjogJGNvbG9yX2dvb2RtYW47XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xufVxuXG4uYy1mb3JtLXRleHQtaXRlbV9faW5mbyB7XG4gIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV90ZXJ0aWFyeTtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiAwO1xuICAvLyBpbmZvIGJhciBpcyBwbGFjZWQgMTAwJSBmcm9tIHRvcCBvZiB0aGUgZmllbGQgKHdoaXRoIG9yIHdpdGhvdXQgbGFiZWwpIG1pbnVzIGZpZWxkJ3MgYm90dG9tIHBhZGRpbmdcbiAgdG9wOiBjYWxjKDEwMCUgLSAjeyRfZmllbGRfc2l6ZV9wcmltYXJ5fSk7XG4gIHdpZHRoOiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBtaW4taGVpZ2h0OiAkaWNvbl9zaXplX3ByaW1hcnk7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcblxuICAuYy1mb3JtLXRleHQtaXRlbS5oYXMtZGFuZ2VyICYge1xuICAgIGNvbG9yOiAkY29sb3JfZGFuZ2VyO1xuICB9XG5cbiAgLmMtZm9ybS10ZXh0LWl0ZW0uaGFzLXdhcm5pbmcgJiB7XG4gICAgY29sb3I6ICRjb2xvcl93YXJuaW5nO1xuICB9XG5cbiAgLmMtZm9ybS10ZXh0LWl0ZW0uaGFzLXN1Y2Nlc3MgJiB7XG4gICAgY29sb3I6ICRjb2xvcl9zdWNjZXNzO1xuICB9XG5cbiAgLmMtZm9ybS10ZXh0LWl0ZW0uaGFzLWFjdGlvbiAmIHtcbiAgICBjb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gIH1cbiAgXG59XG5cbi5jLWZvcm0tdGV4dC1pdGVtX19pbmZvLWljb24ge1xuICBmb250LXNpemU6IDE4cHg7XG4gIGFsaWduLXNlbGY6IGZsZXgtc3RhcnQ7XG4gIGZsZXgtc2hyaW5rOiAwOyAvLyBzbyBkb2Vzbid0IGdldCBzaHJpbmtlZCBvbiBTYWZhcmlcbn1cbiIsIkBtaXhpbiBmb3JtX2l0ZW1fdW5kZXJsaW5lX2VmZmVjdCAoXG4gICR0cmlnZ2VyX3NlbGVjdG9yOiBudWxsLFxuICAkc3RhdGVfc2VsZWN0b3I6IG51bGxcbikge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG5cbiAgJjo6YWZ0ZXIsXG4gICY6OmJlZm9yZSB7XG4gICAgY29udGVudDogJyc7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHdpZHRoOiAwO1xuICAgIGhlaWdodDogMnB4O1xuICAgIGJvdHRvbTogMDtcbiAgICB0cmFuc2l0aW9uOiAkdHJhbnNpdGlvbl9wcmltYXJ5O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9jcnlzdGFsO1xuICB9XG5cbiAgJjo6YWZ0ZXIge1xuICAgIHJpZ2h0OiA1MCU7XG4gIH1cblxuICAmOjpiZWZvcmUge1xuICAgIGxlZnQ6IDUwJTtcbiAgfVxuXG4gICN7JHN0YXRlX3NlbGVjdG9yfS5oYXMtYWN0aW9uICYsXG4gICN7JHN0YXRlX3NlbGVjdG9yfS5oYXMtd2FybmluZyAmLFxuICAjeyRzdGF0ZV9zZWxlY3Rvcn0uaGFzLWRhbmdlciAmLFxuICAjeyRzdGF0ZV9zZWxlY3Rvcn0uaGFzLWVycm9yICYsXG4gICN7JHN0YXRlX3NlbGVjdG9yfS5oYXMtc3VjY2VzcyAmIHtcblxuICAgICY6OmFmdGVyLFxuICAgICY6OmJlZm9yZSB7XG4gICAgICB3aWR0aDogNTAlO1xuICAgIH1cblxuICB9XG5cbiAgI3skc3RhdGVfc2VsZWN0b3J9Lmhhcy1zdWNjZXNzICYge1xuXG4gICAgJjo6YWZ0ZXIsXG4gICAgJjo6YmVmb3JlIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9zdWNjZXNzO1xuICAgIH1cblxuICB9XG5cbiAgI3skc3RhdGVfc2VsZWN0b3J9Lmhhcy1hY3Rpb24gJiB7XG5cbiAgICAmOjphZnRlcixcbiAgICAmOjpiZWZvcmUge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gICAgfVxuXG4gIH1cblxuICAjeyRzdGF0ZV9zZWxlY3Rvcn0uaGFzLXdhcm5pbmcgJiB7XG5cbiAgICAmOjphZnRlcixcbiAgICAmOjpiZWZvcmUge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3dhcm5pbmc7XG4gICAgfVxuXG4gIH1cblxuICAjeyRzdGF0ZV9zZWxlY3Rvcn0uaGFzLWRhbmdlciAmIHtcblxuICAgICY6OmFmdGVyLFxuICAgICY6OmJlZm9yZSB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfZGFuZ2VyO1xuICAgIH1cblxuICB9XG5cbiAgI3skdHJpZ2dlcl9zZWxlY3Rvcn0ge1xuXG4gICAgJjo6YWZ0ZXIsXG4gICAgJjo6YmVmb3JlIHtcbiAgICAgIHdpZHRoOiA1MCU7XG4gICAgfVxuICAgIFxuICB9XG4gIFxufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNMSVNUXG5cbiAgQmFzZTpcbiAgICAuYy1saXN0XG4gICAgICAuYy1saXN0LWl0ZW1cbiAgICAgICAgLmMtbGlzdC1pdGVtX19pY29uXG4gICAgICAgIC5jLWxpc3QtaXRlbV9fY29udGVudFxuXG4gIFBhZGRpbmcgbW9kaWZpZXJzOlxuICAgIC5jLWxpc3QtLXNwYWNpbmctcHJpbWFyeVxuICAgIC5jLWxpc3QtLXNwYWNpbmctc2Vjb25kYXJ5XG4gICAgLmMtbGlzdC0tc3BhY2luZy10ZXJ0aWFyeVxuICAgIC5jLWxpc3QtLXNwYWNpbmctcXVhdGVybmFyeVxuXG4gIEhvdmVyIGVmZmVjdCBtb2RpZmllcnM6XG4gICAgLmMtbGlzdC0taG92ZXItcHJpbWFyeVxuICAgIC5jLWxpc3QtLWhvdmVyLXNlY29uZGFyeVxuXG4gIFNpbmdsZSBpdGVtIG1vZGlmaWVyczpcbiAgICAuYy1saXN0LWl0ZW1fX2NvbnRlbnQtLW5vLWhvdmVyXG4gICAgLmMtbGlzdC1pdGVtX19jb250ZW50LS10aXRsZVxuXG4gIFN0YXRlIG1vZGlmaWVyczpcbiAgICAuYy1saXN0LWl0ZW1fX2NvbnRlbnQuaXMtYWN0aXZlXG4gICAgLmMtbGlzdC1pdGVtX19jb250ZW50LmlzLWRpc2FibGVkXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cbi5jLWxpc3Qge1xuICBmb250LXNpemU6ICRmb250X3NpemVfc2Vjb25kYXJ5O1xuICBsaW5lLWhlaWdodDogMTUwJTtcbiAgd2lkdGg6IDEwMCU7XG5cbiAgJiArIC5jLWxpc3Qge1xuICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCAkY29sb3JfaGVybWFub3M7XG4gIH1cblxufVxuXG4uYy1saXN0LWl0ZW1fX2NvbnRlbnQge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBwYWRkaW5nLXRvcDogJHNwYWNpbmdfdW5pdF9wcmltYXJ5O1xuICBwYWRkaW5nLWJvdHRvbTogJHNwYWNpbmdfdW5pdF9wcmltYXJ5O1xuICBjdXJzb3I6IHBvaW50ZXI7XG5cbiAgLy8gbGVmdCBwYWRkaW5nIG1vZGlmaWVyc1xuICAuYy1saXN0LS1zcGFjaW5nLXByaW1hcnkgJiB7XG4gICAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF9wcmltYXJ5O1xuICAgIHBhZGRpbmctbGVmdDogJHNwYWNpbmdfdW5pdF9wcmltYXJ5O1xuICB9XG5cbiAgLmMtbGlzdC0tc3BhY2luZy1zZWNvbmRhcnkgJiB7XG4gICAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF9zZWNvbmRhcnk7XG4gICAgcGFkZGluZy1sZWZ0OiAkc3BhY2luZ191bml0X3NlY29uZGFyeTtcbiAgfVxuXG4gIC5jLWxpc3QtLXNwYWNpbmctdGVydGlhcnkgJiB7XG4gICAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF90ZXJ0aWFyeTtcbiAgICBwYWRkaW5nLWxlZnQ6ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG4gIH1cblxuICAuYy1saXN0LS1zcGFjaW5nLXF1YXRlcm5hcnkgJiB7XG4gICAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF9xdWF0ZXJuYXJ5O1xuICAgIHBhZGRpbmctbGVmdDogJHNwYWNpbmdfdW5pdF9xdWF0ZXJuYXJ5O1xuICB9XG5cbiAgIC8vIGhvdmVyIG1vZGlmaWVyc1xuICAuYy1saXN0LS1ob3Zlci1wcmltYXJ5ICY6aG92ZXIge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9za3lsZXI7XG4gIH1cblxuICAuYy1saXN0LS1ob3Zlci1zZWNvbmRhcnkgJjpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gICAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICB9XG5cbiAgLy8gd2UgY2FuIHJlbW92ZSBob3ZlciBlZmZlY3QgZm9yIGEgc2luZ2xlIGl0ZW0gaWYgbmVlZGVkXG4gICYuYy1saXN0LWl0ZW1fX2NvbnRlbnQtLW5vLWhvdmVyOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBpbmhlcml0O1xuICAgIGNvbG9yOiBpbmhlcml0O1xuICB9XG5cbiAgLy8gU3RhdGVzXG4gICYuaXMtYWN0aXZlIHtcbiAgICBjb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gIH1cblxuICAmLmlzLWRpc2FibGVkIHtcbiAgICBjb2xvcjogJGNvbG9yX2dvb2RtYW47XG4gICAgY3Vyc29yOiBkZWZhdWx0O1xuICB9XG5cbiAgLy8gbXVsdGlsaW5lc1xuICAuYy1saXN0LS1tdWx0aWxpbmUgJiB7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcbiAgfVxuXG4gIC8vIHN0eWxpbmcgZm9yIGRyb3Bkb3duc1xuICAuYy1kcm9wZG93biAmIHtcbiAgICBwYWRkaW5nLXJpZ2h0OiAkc3BhY2luZ191bml0X3F1aW5hcnk7XG4gIH1cblxufVxuXG4uYy1saXN0LWl0ZW1fX3RpdGxlIHtcbiAgZm9udC1zaXplOiAkZm9udF9zaXplX3ByaW1hcnk7XG4gIGZvbnQtd2VpZ2h0OiAkZm9udF93ZWlnaHRfbWVkaXVtO1xufVxuXG4vLyBpY29uc1xuLmMtbGlzdC1pdGVtX19pY29uIHtcbiAgbWFyZ2luLXJpZ2h0OiAkc3BhY2luZ191bml0X3NlY29uZGFyeTtcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNMT0FERVJcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRfbG9hZGVyX3NpemU6IDQwcHg7XG4kX2xvYWRlcl9zaXplX2xhcmdlOiA4MHB4O1xuJF9sb2FkZXJfc2l6ZV94X2xhcmdlOiAxMDBweDtcblxuLmMtbG9hZGVyIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG4gIGJhY2tncm91bmQtaW1hZ2U6IHVybCgkc3ZnX2xvYWRlcik7XG4gIHdpZHRoOiAkX2xvYWRlcl9zaXplO1xuICBoZWlnaHQ6ICRfbG9hZGVyX3NpemU7XG4gIGJhY2tncm91bmQtc2l6ZTogY292ZXI7XG5cbiAgLy8gb3ZlcnJpZGluZyB3aGVuIG5lc3RlZCBpbnNpZGUgYSBidXR0b25cbiAgLmMtYnV0dG9uICYge1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIH1cbn1cblxuLmMtbG9hZGVyLS1zbWFsbCB7XG4gIHdpZHRoOiAkaWNvbl9zaXplX3ByaW1hcnk7XG4gIGhlaWdodDogJGljb25fc2l6ZV9wcmltYXJ5O1xufVxuXG4uYy1sb2FkZXItLWxhcmdlIHtcbiAgd2lkdGg6ICRfbG9hZGVyX3NpemVfbGFyZ2U7XG4gIGhlaWdodDogJF9sb2FkZXJfc2l6ZV9sYXJnZTtcbn1cblxuLmMtbG9hZGVyLS14LWxhcmdlIHtcbiAgd2lkdGg6ICRfbG9hZGVyX3NpemVfeF9sYXJnZTtcbiAgaGVpZ2h0OiAkX2xvYWRlcl9zaXplX3hfbGFyZ2U7XG59XG4iLCIvKlxuICAjTUFSS1xuXG4gIEJhc2U6XG4gICAgLmMtbWFya1xuICAgIC5jLW1hcmtfX2lucHV0IC0gaGlkZGVuIGZyb20gc2NyZWVuXG4gICAgLmMtbWFya19faWNvblxuICAgIC5jLW1hcmtfX2xhYmVsXG5cbiAgVHlwZSBtb2RpZmllcnM6XG4gICAgLmMtbWFya19faWNvbi0tY2hlY2tib3hcbiAgICAuYy1tYXJrX19pY29uLS1yYWRpb1xuXG4gIFNpemUgbW9kaWZpZXJzOlxuICAgIC5jLW1hcmtfX2ljb24tLXNtYWxsXG4gICAgLmMtbWFya19faWNvbi0tbGFyZ2VcbiAgICAuYy1tYXJrX19pY29uLS14LWxhcmdlXG5cbiAgQ29sb3IgbW9kaWZpZXJzOlxuICAgIC5jLW1hcmtfX2ljb24tLTFcbiAgICAuYy1tYXJrX19pY29uLS0yXG4gICAgLmMtbWFya19faWNvbi0tM1xuICAgIC5jLW1hcmtfX2ljb24tLTRcbiAgICAuYy1tYXJrX19pY29uLS01XG4gICAgLmMtbWFya19faWNvbi0tNlxuICAgIC5jLW1hcmtfX2ljb24tLTdcbiAgICAuYy1tYXJrX19pY29uLS04XG4gICAgLmMtbWFya19faWNvbi0tOVxuICAgIC5jLW1hcmtfX2ljb24tLTEwXG5cbiAgU3RhdGUgbW9kaWZpZXJzOlxuICAgIC5jLW1hcmtfX2lucHV0OmRpc2FibGVkXG4gICAgLmMtbWFya19faW5wdXQ6Y2hlY2tlZFxuICAgIC5jLW1hcmtfX2lucHV0OmRpc2FibGVkOmNoZWNrZWRcbiovXG5cbiRfbWFya19zaXplOiAxNnB4ICFkZWZhdWx0O1xuJF9tYXJrX2JvcmRlcl93aWR0aDogMnB4ICFkZWZhdWx0O1xuJF9tYXJrX2RpZmY6IDEwcHggIWRlZmF1bHQ7XG5cbiRfbWFya19jb2xvcl9tZGZyczogKFxuICAxOiAjNzRjMTc3LFxuICAyOiAjZmI4YzAwLFxuICAzOiAjZjQ0MzM2LFxuICA0OiAjMjE5NmYzLFxuICA1OiAjNjczYWI3LFxuICA2OiAjMDBiY2Q0LFxuICA3OiAjYzBjYTMzLFxuICA4OiAjZmZjMTA3LFxuICA5OiAjNzk1NTQ4LFxuICAxMDogIzNmNTFiNVxuKSAhZGVmYXVsdDtcblxuJF9tYXJrX3NpemVfbWRmcnM6IChcbiAgJy0tc21hbGwnOiAtMixcbiAgJy0tbGFyZ2UnOiA0LFxuICAnLS14LWxhcmdlJzogOFxuKSAhZGVmYXVsdDtcblxuLmMtbWFyayB7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMDtcbiAgZGlzcGxheTogZmxleDtcbiAgbGluZS1oZWlnaHQ6IDEwMCU7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIHVzZXItc2VsZWN0OiBub25lO1xuICBvdXRsaW5lOiAwO1xufVxuXG4uYy1tYXJrX19pbnB1dCB7XG4gIEBpbmNsdWRlIHZpc3VhbGx5X2hpZGRlbjtcbn1cblxuLmMtbWFya19faWNvbiB7XG4gIGJvcmRlcjogJGNvbG9yX2d1c3Rhdm8gJF9tYXJrX2JvcmRlcl93aWR0aCBzb2xpZDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX21yd2hpdGU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICB3aWR0aDogJF9tYXJrX3NpemU7XG4gIGhlaWdodDogJF9tYXJrX3NpemU7XG5cbiAgJjphY3RpdmUge1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDhweCByZ2JhKCRjb2xvcl9jcnlzdGFsLCAwLjIpO1xuICB9XG5cbiAgQGVhY2ggJG1hcmssICRtYXJrX21kZnIgaW4gJF9tYXJrX3NpemVfbWRmcnMge1xuICAgICYjeyRtYXJrfSB7XG4gICAgICB3aWR0aDogJF9tYXJrX3NpemUgKyAkbWFya19tZGZyO1xuICAgICAgaGVpZ2h0OiAkX21hcmtfc2l6ZSArICRtYXJrX21kZnI7XG4gICAgfVxuICB9XG5cbiAgQGVhY2ggJG1hcmtfdmFyaWF0aW9uLCAkbWFya192YXJpYXRpb25fYmdfY29sb3IgaW4gJF9tYXJrX2NvbG9yX21kZnJzIHtcbiAgICAmLmMtbWFya19faWNvbi0tI3skbWFya192YXJpYXRpb259OmFjdGl2ZSB7XG4gICAgICBib3gtc2hhZG93OiAwIDAgMCA4cHggcmdiYSgkbWFya192YXJpYXRpb25fYmdfY29sb3IsIDAuMik7XG4gICAgfVxuICB9XG59XG5cbi5jLW1hcmtfX2ljb24sXG4uYy1tYXJrX19sYWJlbCB7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLmMtbWFya19faWNvbiArIC5jLW1hcmtfX2xhYmVsLFxuLmMtbWFya19fbGFiZWwgKyAuYy1tYXJrX19pY29uIHtcbiAgcGFkZGluZy1sZWZ0OiAkc3BhY2luZ191bml0X3ByaW1hcnk7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtbWFya19faWNvbi0tcmFkaW9cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLW1hcmtfX2ljb24tLXJhZGlvIHtcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xuXG4gICY6OmJlZm9yZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIHdpZHRoOiAwO1xuICAgIGhlaWdodDogMDtcbiAgICBjb250ZW50OiAnJztcbiAgICB3aWR0aDogJF9tYXJrX3NpemUgLSAkX21hcmtfZGlmZjtcbiAgICBoZWlnaHQ6ICRfbWFya19zaXplIC0gJF9tYXJrX2RpZmY7XG4gICAgdHJhbnNpdGlvbjogJHRyYW5zaXRpb25fcHJpbWFyeTtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDApO1xuICAgIHRyYW5zZm9ybS1vcmlnaW46IGNlbnRlcjtcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLW1hcmtfX2ljb24tLWNoZWNrYm94XG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1tYXJrX19pY29uLS1jaGVja2JveCB7XG4gIGJvcmRlci1yYWRpdXM6ICRib3JkZXJfcmFkaXVzX3ByaW1hcnk7XG4gIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uX3ByaW1hcnk7XG4gIGNvbG9yOiB0cmFuc3BhcmVudDtcbiAgZm9udC1zaXplOiAwO1xufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLW1hcmtfX2lucHV0OmNoZWNrZWQgLmMtbWFya19faWNvbi0tY2hlY2tib3hcbiAgLmMtbWFya19faW5wdXQ6Y2hlY2tlZCAuYy1tYXJrX19pY29uLS1yYWRpb1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtbWFya19faW5wdXQ6Y2hlY2tlZCB+IC5jLW1hcmtfX2ljb24ge1xuICAmLS1yYWRpbyB7XG4gICAgYm9yZGVyLWNvbG9yOiAkY29sb3JfY3J5c3RhbDtcblxuICAgICY6OmJlZm9yZSB7XG4gICAgICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xuICAgIH1cblxuICAgIEBlYWNoICRtYXJrLCAkbWFya19tZGZyIGluICRfbWFya19zaXplX21kZnJzIHtcbiAgICAgICYuYy1tYXJrX19pY29uI3skbWFya306OmJlZm9yZSB7XG4gICAgICAgIHdpZHRoOiAkX21hcmtfc2l6ZSAtICRfbWFya19kaWZmICsgJG1hcmtfbWRmcjtcbiAgICAgICAgaGVpZ2h0OiAkX21hcmtfc2l6ZSAtICRfbWFya19kaWZmICsgJG1hcmtfbWRmcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBAZWFjaCAkbWFya192YXJpYXRpb24sICRtYXJrX3ZhcmlhdGlvbl9ib3JkZXJfY29sb3IgaW4gJF9tYXJrX2NvbG9yX21kZnJzIHtcbiAgICAgICYuYy1tYXJrX19pY29uLS0jeyRtYXJrX3ZhcmlhdGlvbn0ge1xuICAgICAgICBib3JkZXItY29sb3I6ICRtYXJrX3ZhcmlhdGlvbl9ib3JkZXJfY29sb3I7XG5cbiAgICAgICAgJjo6YmVmb3JlIHtcbiAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWFya192YXJpYXRpb25fYm9yZGVyX2NvbG9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgJi0tY2hlY2tib3gge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9jcnlzdGFsO1xuICAgIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICAgIGZvbnQtc2l6ZTogJF9tYXJrX3NpemU7XG5cbiAgICBAZWFjaCAkbWFyaywgJG1hcmtfbWRmciBpbiAkX21hcmtfc2l6ZV9tZGZycyB7XG4gICAgICAmLmMtbWFya19faWNvbiN7JG1hcmt9IHtcbiAgICAgICAgZm9udC1zaXplOiAkX21hcmtfc2l6ZSArICRtYXJrX21kZnI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgQGVhY2ggJG1hcmtfdmFyaWF0aW9uLCAkbWFya192YXJpYXRpb25fYmdfY29sb3IgaW4gJF9tYXJrX2NvbG9yX21kZnJzIHtcbiAgICAgICYuYy1tYXJrX19pY29uLS0jeyRtYXJrX3ZhcmlhdGlvbn0ge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWFya192YXJpYXRpb25fYmdfY29sb3I7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtbWFya19faW5wdXQ6ZGlzYWJsZWQgLmMtbWFya19faWNvblxuICAuYy1tYXJrX19pbnB1dDpkaXNhYmxlZCAuYy1tYXJrX19sYWJlbFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtbWFya19faW5wdXQ6ZGlzYWJsZWQge1xuICAmIH4gLmMtbWFya19faWNvbixcbiAgJiB+IC5jLW1hcmtfX2xhYmVsIHtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgfVxuXG4gICYgfiAuYy1tYXJrX19pY29uIHtcbiAgICBib3JkZXItY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4uYy1tYXJrX19pbnB1dDpkaXNhYmxlZDpjaGVja2VkIC5jLW1hcmtfX2ljb24tLWNoZWNrYm94XG4uYy1tYXJrX19pbnB1dDpkaXNhYmxlZDpjaGVja2VkIC5jLW1hcmtfX2ljb24tLXJhZGlvXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1tYXJrX19pbnB1dDpkaXNhYmxlZDpjaGVja2VkIH4gLmMtbWFya19faWNvbiB7XG4gICYtLXJhZGlvOjpiZWZvcmUsXG4gICYtLWNoZWNrYm94IHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfaGVybWFub3M7XG4gIH1cbn1cbiIsIi8qXG4gICNNT0RBTFxuXG4gIEJhc2U6XG4gICAgLmMtbW9kYWxcbiAgICAgIC5jLW1vZGFsX19jbG9zZVxuICAgICAgLmMtbW9kYWxfX2hlYWQgLSBwYWRkaW5nIFt0b3AgcmlnaHQgbGVmdF0gYnkgZGVmYXVsdFxuICAgICAgICAuYy1tb2RhbF9fdGl0bGVcbiAgICAgIC5jLW1vZGFsX19ib2R5IC0gcGFkZGluZyBbYm90dG9tIHJpZ2h0IGxlZnRdIGJ5IGRlZmF1bHRcblxuICAgICAgLmMtbW9kYWxfX2Fycm93XG5cbiAgVHlwZSBtb2RpZmllcnM6XG4gICAgLmMtbW9kYWwtLXNpbXBsZVxuICAgIC5jLW1vZGFsLS1wb3BvdmVyXG5cbiAgU2l6ZSAod2lkdGgpIG1vZGlmaWVyczpcbiAgICAuYy1tb2RhbC0teC1zbWFsbFxuICAgIC5jLW1vZGFsLS1zbWFsbFxuICAgIC5jLW1vZGFsLS1sYXJnZVxuICAgIC5jLW1vZGFsLS14LWxhcmdlXG5cbiAgQXJyb3cgbW9kaWZpZXJzOlxuICAgIC5jLW1vZGFsX19hcnJvdy0tLXRvcFxuICAgIC5jLW1vZGFsX19hcnJvdy0tLXRvcC1yaWdodFxuICAgIC5jLW1vZGFsX19hcnJvdy0tLXRvcC1sZWZ0XG4gICAgLmMtbW9kYWxfX2Fycm93LS0tcmlnaHRcbiAgICAuYy1tb2RhbF9fYXJyb3ctLS1yaWdodC10b3BcbiAgICAuYy1tb2RhbF9fYXJyb3ctLS1yaWdodC1ib3R0b21cbiAgICAuYy1tb2RhbF9fYXJyb3ctLS1ib3R0b21cbiAgICAuYy1tb2RhbF9fYXJyb3ctLS1ib3R0b20tcmlnaHRcbiAgICAuYy1tb2RhbF9fYXJyb3ctLS1ib3R0b20tbGVmdFxuICAgIC5jLW1vZGFsX19hcnJvdy0tLWxlZnRcbiAgICAuYy1tb2RhbF9fYXJyb3ctLS1sZWZ0LXRvcFxuICAgIC5jLW1vZGFsX19hcnJvdy0tLWxlZnQtYm90dG9tXG4qL1xuXG4kX21vZGFsX2Fycm93X3NpemU6IDEwcHggIWRlZmF1bHQ7XG4kX21vZGFsX2JvcmRlcl93aWR0aDogMXB4ICFkZWZhdWx0O1xuJF9tb2RhbF9zZWN0aW9uX3NwYWNpbmdfcHJpbWFyeTogMzBweCAhZGVmYXVsdDtcbiRfbW9kYWxfc2VjdGlvbl9zcGFjaW5nX3NlY29uZGFyeTogNTBweCAhZGVmYXVsdDtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1tb2RhbFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtbW9kYWwge1xuICAvL0BpbmNsdWRlIGxpbmVfd3JhcDtcbiAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfcXVpbmFyeTtcbiAgYm9yZGVyLXJhZGl1czogJGJvcmRlcl9yYWRpdXNfcHJpbWFyeTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB3aWR0aDogMTAwJTtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB6LWluZGV4OiBtYXAtZ2V0KCR6X2luZGV4LCBtb2RhbCk7XG4gIGN1cnNvcjogZGVmYXVsdDsgLy8gb3ZlcndyaXRpbmcgLnVpLWRyYWdnYWJsZSBzdHlsZXNcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX21yd2hpdGU7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtbW9kYWxcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLW1vZGFsX19oZWFkIHtcbiAgcGFkZGluZzogJHNwYWNpbmdfdW5pdF9xdWF0ZXJuYXJ5O1xufVxuXG4uYy1tb2RhbF9fdGl0bGVcbntcbiAgbWFyZ2luOiAwOyAvLyByZXNldHRpbmcgZGVmYXVsdHNcbiAgbGluZS1oZWlnaHQ6IDE7IC8vIHJlc2V0dGluZyBkZWZhdWx0c1xuICBwYWRkaW5nOiAwOyAvLyByZXNldHRpbmcgZGVmYXVsdHNcbn1cblxuLmMtbW9kYWxfX2JvZHkge1xuICBwYWRkaW5nLWxlZnQ6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbiAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF9xdWF0ZXJuYXJ5O1xuICBwYWRkaW5nLWJvdHRvbTogJHNwYWNpbmdfdW5pdF9xdWF0ZXJuYXJ5O1xufVxuXG5cbi5jLW1vZGFsX19jbG9zZSB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAkX21vZGFsX3NlY3Rpb25fc3BhY2luZ19wcmltYXJ5O1xuICByaWdodDogJF9tb2RhbF9zZWN0aW9uX3NwYWNpbmdfcHJpbWFyeTtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1tb2RhbC0tc2ltcGxlXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1tb2RhbC0tc2ltcGxlIHtcbiAgLmMtbW9kYWxfX2JvZHlcbiAge1xuICAgIHBhZGRpbmctYm90dG9tOiAxOHB4OyAvLyBuZWVkIHRvIGRlY3JlYXNlIGRlZmF1bHQgc3BhY2luZyBhcyAuYy1idXR0b24tLWZsYXQgaGFzIHNvbWUgZXh0cmEgcGFkZGluZ3MgYXJvdW5kXG4gICAgcGFkZGluZy1yaWdodDogMThweDsgLy8gbmVlZCB0byBkZWNyZWFzZSBkZWZhdWx0IHNwYWNpbmcgYXMgLmMtYnV0dG9uLS1mbGF0IGhhcyBzb21lIGV4dHJhIHBhZGRpbmdzIGFyb3VuZFxuICB9XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtbW9kYWwtLXBvcG92ZXJcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLW1vZGFsLS1wb3BvdmVyIHtcbiAgLmMtbW9kYWxfX2JvZHlcbiAge1xuICAgIHBhZGRpbmctdG9wOiAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG4gICAgcGFkZGluZy1yaWdodDogJHNwYWNpbmdfdW5pdF90ZXJ0aWFyeSArICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLW1vZGFsIHNpemUgbW9kaWZpZXJzXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1tb2RhbC0teC1zbWFsbCB7XG4gIG1heC13aWR0aDogMzU1cHg7XG59XG5cbi5jLW1vZGFsLS1zbWFsbCB7XG4gIG1heC13aWR0aDogNDIwcHg7XG59XG5cbi5jLW1vZGFsLS1sYXJnZSB7XG4gIG1heC13aWR0aDogNTUwcHg7XG59XG5cbi5jLW1vZGFsLS14LWxhcmdlIHtcbiAgbWF4LXdpZHRoOiA2ODBweDtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1tb2RhbF9fYXJyb3dcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLW1vZGFsX19hcnJvdyB7XG4gICYsXG4gICY6YWZ0ZXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgfVxufVxuXG4uYy1tb2RhbF9fYXJyb3ctLXRvcCxcbi5jLW1vZGFsX19hcnJvdy0tYm90dG9tIHtcbiAgbGVmdDogNTAlO1xuXG4gICYsXG4gICY6YWZ0ZXIge1xuICAgIG1hcmdpbi1sZWZ0OiAtJF9tb2RhbF9hcnJvd19zaXplO1xuICB9XG5cbiAgJi1sZWZ0IHtcbiAgICBsZWZ0OiAkX21vZGFsX3NlY3Rpb25fc3BhY2luZ19wcmltYXJ5O1xuICB9XG5cbiAgJi1yaWdodCB7XG4gICAgbGVmdDogYXV0bztcbiAgICByaWdodDogJF9tb2RhbF9zZWN0aW9uX3NwYWNpbmdfcHJpbWFyeTtcbiAgfVxufVxuXG4uYy1tb2RhbF9fYXJyb3ctLXRvcCB7XG4gIHRvcDogLSRfbW9kYWxfYXJyb3dfc2l6ZTtcblxuICAmLFxuICAmOmFmdGVyIHtcbiAgICBAaW5jbHVkZSB0cmlhbmdsZSgndXAnLCAkX21vZGFsX2Fycm93X3NpemUsIHJnYmEoJGNvbG9yX2d1c3Rhdm8sIC4zKSk7XG4gICAgYm9yZGVyLXRvcC13aWR0aDogMDtcbiAgfVxuXG4gICY6YWZ0ZXIge1xuICAgIHRvcDogJF9tb2RhbF9ib3JkZXJfd2lkdGg7XG4gICAgYm9yZGVyLWJvdHRvbS1jb2xvcjogJGNvbG9yX21yd2hpdGU7XG4gIH1cbn1cblxuLmMtbW9kYWxfX2Fycm93LS1ib3R0b20ge1xuICBib3R0b206IC0kX21vZGFsX2Fycm93X3NpemU7XG5cbiAgJixcbiAgJjphZnRlclx0e1xuICAgIEBpbmNsdWRlIHRyaWFuZ2xlKCdkb3duJywgJF9tb2RhbF9hcnJvd19zaXplLCAkY29sb3JfZ3VzdGF2byk7XG4gICAgYm9yZGVyLWJvdHRvbS13aWR0aDogMDtcbiAgfVxuXG4gICY6YWZ0ZXIge1xuICAgIGJvdHRvbTogJF9tb2RhbF9ib3JkZXJfd2lkdGg7XG4gICAgYm9yZGVyLXRvcC1jb2xvcjogJGNvbG9yX21yd2hpdGU7XG4gIH1cbn1cblxuLmMtbW9kYWxfX2Fycm93LS1sZWZ0LFxuLmMtbW9kYWxfX2Fycm93LS1yaWdodCB7XG4gIHRvcDogNTAlO1xuXG4gICYsXG4gICY6YWZ0ZXIge1xuICAgIG1hcmdpbi10b3A6IC0kX21vZGFsX2Fycm93X3NpemU7XG4gIH1cblxuICAmLXRvcCB7XG4gICAgdG9wOiAkX21vZGFsX3NlY3Rpb25fc3BhY2luZ19wcmltYXJ5O1xuICB9XG5cbiAgJi1ib3R0b20ge1xuICAgIHRvcDogYXV0bztcbiAgICBib3R0b206ICRfbW9kYWxfc2VjdGlvbl9zcGFjaW5nX3ByaW1hcnk7XG4gIH1cbn1cblxuLmMtbW9kYWxfX2Fycm93LS1sZWZ0IHtcbiAgbGVmdDogLSRfbW9kYWxfYXJyb3dfc2l6ZTtcblxuICAmLFxuICAmOmFmdGVyIHtcbiAgICBAaW5jbHVkZSB0cmlhbmdsZSgnbGVmdCcsICRfbW9kYWxfYXJyb3dfc2l6ZSwgcmdiYSgkY29sb3JfZ3VzdGF2bywgLjMpKTtcbiAgICBib3JkZXItbGVmdC13aWR0aDogMDtcbiAgfVxuXG4gICY6YWZ0ZXIge1xuICAgIGxlZnQ6ICRfbW9kYWxfYm9yZGVyX3dpZHRoO1xuICAgIGJvcmRlci1yaWdodC1jb2xvcjogJGNvbG9yX21yd2hpdGU7O1xuICB9XG59XG5cbi5jLW1vZGFsX19hcnJvdy0tcmlnaHQge1xuICByaWdodDogLSRfbW9kYWxfYXJyb3dfc2l6ZTtcblxuICAmLFxuICAmOmFmdGVyXHR7XG4gICAgQGluY2x1ZGUgdHJpYW5nbGUoJ3JpZ2h0JywgJF9tb2RhbF9hcnJvd19zaXplLCByZ2JhKCRjb2xvcl9ndXN0YXZvLCAuMykpO1xuICAgIGJvcmRlci1yaWdodC13aWR0aDogMDtcbiAgfVxuXG4gICY6YWZ0ZXJcdHtcbiAgICByaWdodDogJF9tb2RhbF9ib3JkZXJfd2lkdGg7XG4gICAgYm9yZGVyLWxlZnQtY29sb3I6ICRjb2xvcl9tcndoaXRlOztcbiAgfVxufVxuIiwiQG1peGluIHRyaWFuZ2xlXG4oXG4gICRkaXJlY3Rpb246IFwidXBcIixcbiAgJHNpemU6IDEwcHgsXG4gICRjb2xvcjogIzAwMFxuKSB7XG4gIGNvbnRlbnQ6ICcnO1xuICBkaXNwbGF5OiBibG9jaztcbiAgd2lkdGg6IDA7XG4gIGhlaWdodDogMDtcbiAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcbiAgYm9yZGVyLXdpZHRoOiAkc2l6ZTtcbiAgYm9yZGVyLWxlZnQtY29sb3I6ICN7c2V0X3RyaWFuZ2xlX2NvbG9yKCRkaXJlY3Rpb24sIFwibGVmdFwiLCAkY29sb3IpfTtcbiAgYm9yZGVyLXJpZ2h0LWNvbG9yOiAje3NldF90cmlhbmdsZV9jb2xvcigkZGlyZWN0aW9uLCBcInJpZ2h0XCIsICRjb2xvcil9O1xuICBib3JkZXItYm90dG9tLWNvbG9yOiAje3NldF90cmlhbmdsZV9jb2xvcigkZGlyZWN0aW9uLCBcImJvdHRvbVwiLCAkY29sb3IpfTtcbiAgYm9yZGVyLXRvcC1jb2xvcjogI3tzZXRfdHJpYW5nbGVfY29sb3IoJGRpcmVjdGlvbiwgXCJ0b3BcIiwgJGNvbG9yKX07XG59XG5cbkBmdW5jdGlvbiBzZXRfdHJpYW5nbGVfY29sb3IoICRkaXJlY3Rpb24sICRzaWRlLCAkY29sb3IgKSB7XG4gIEBpZlxuICAkZGlyZWN0aW9uID09IFwibGVmdFwiIGFuZCAkc2lkZSA9PSBcInJpZ2h0XCJcbiAgb3JcbiAgJGRpcmVjdGlvbiA9PSBcInJpZ2h0XCIgYW5kICRzaWRlID09IFwibGVmdFwiXG4gIG9yXG4gICRkaXJlY3Rpb24gPT0gXCJkb3duXCIgYW5kICRzaWRlID09IFwidG9wXCJcbiAgb3JcbiAgJGRpcmVjdGlvbiA9PSBcInVwXCIgYW5kICRzaWRlID09IFwiYm90dG9tXCIge1xuICAgIEByZXR1cm4gJGNvbG9yXG4gIH1cbiAgQGVsc2Uge1xuICAgIEByZXR1cm4gXCJ0cmFuc3BhcmVudFwiO1xuICB9XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjTk9USUZJQ0FUSU9OXG5cbiAgQmFzZTpcbiAgICAuYy1ub3RpZmljYXRpb25cbiAgICAgIC5jLW5vdGlmaWNhdGlvbl9fdGl0bGVcbiAgICAgIC5jLW5vdGlmaWNhdGlvbl9fY2xvc2VcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLW5vdGlmaWNhdGlvbiB7XG4gIGNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3R1Y287XG59XG5cbi5jLW5vdGlmaWNhdGlvbl9fdGl0bGUge1xuICBmb250LXdlaWdodDogJGZvbnRfd2VpZ2h0X21lZGl1bTtcbn1cblxuLmMtbm90aWZpY2F0aW9uX19jbG9zZSB7XG4gIGZvbnQtc2l6ZTogJGljb25fc2l6ZV9zZWNvbmRhcnk7XG4gIGNvbG9yOiAkY29sb3JfZ29vZG1hbjtcbiAgY3Vyc29yOiBwb2ludGVyO1xufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNQQUdJTkFUSU9OXG5cbiAgQmFzZTpcbiAgICAuYy1wYWdpbmF0aW9uXG4gICAgICAuYy1wYWdpbmF0aW9uX19saXN0XG4gICAgICAgIC5jLXBhZ2luYXRpb25fX2l0ZW1cbiAgICAgICAgICAuYy1wYWdpbmF0aW9uX19wYWdlXG4gICAgICAgICAgICAuYy1wYWdpbmF0aW9uX19pY29uXG4gICAgICAgICAgLmMtcGFnaW5hdGlvbl9fc2VwYXJhdG9yXG5cblxuICBEaXNwbGF5IG1vZGlmaWVyczpcbiAgICAuYy1wYWdpbmF0aW9uLS1sZWZ0XG4gICAgLmMtcGFnaW5hdGlvbi0tcmlnaHRcblxuICBTdGF0ZSBtb2RpZmllcnMgZm9yIC5jLXBhZ2luYXRpb25fX3BhZ2U6XG4gICAgLmlzLWRpc2FibGVkXG4gICAgLmlzLWFjdGl2ZVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuJF9wYWdpbmF0aW9uX2l0ZW1fc2l6ZTogMzRweDtcblxuLmMtcGFnaW5hdGlvbiB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xufVxuXG4uYy1wYWdpbmF0aW9uLS1sZWZ0IHtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xufVxuXG4uYy1wYWdpbmF0aW9uLS1yaWdodCB7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG59XG5cblxuLmMtcGFnaW5hdGlvbl9fbGlzdCB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmb250LXNpemU6ICRmb250X3NpemVfc2Vjb25kYXJ5O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfcHJpbWFyeTtcbn1cblxuXG4uYy1wYWdpbmF0aW9uX19wYWdlLFxuLmMtcGFnaW5hdGlvbl9fc2VwYXJhdG9yIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1hcm91bmQ7XG4gIGxpbmUtaGVpZ2h0OiAkX3BhZ2luYXRpb25faXRlbV9zaXplO1xuICBoZWlnaHQ6ICRfcGFnaW5hdGlvbl9pdGVtX3NpemU7XG4gIHdpZHRoOiAkX3BhZ2luYXRpb25faXRlbV9zaXplO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcbiAgY29sb3I6ICRjb2xvcl90dWNvO1xuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG59XG5cbi5jLXBhZ2luYXRpb25fX3BhZ2Uge1xuICB0cmFuc2l0aW9uOiAkdHJhbnNpdGlvbl9wcmltYXJ5O1xuXG4gICY6aG92ZXIge1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgfVxuXG4gICY6aG92ZXIsXG4gICYuaXMtYWN0aXZlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3Jfc2t5bGVyO1xuICB9XG5cbiAgJi5pcy1hY3RpdmUsXG4gICYuaXMtZGlzYWJsZWQge1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICB9XG5cbiAgJi5pcy1kaXNhYmxlZCB7XG4gICAgY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgfVxufVxuXG4uYy1wYWdpbmF0aW9uX19zZXBhcmF0b3Ige1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuXG4uYy1wYWdpbmF0aW9uX19pY29uIHtcbiAgZm9udC1zaXplOiAkaWNvbl9zaXplX3NlY29uZGFyeTtcbiAgY29sb3I6ICRjb2xvcl90dWNvO1xuXG4gIC5jLXBhZ2luYXRpb25fX3BhZ2UuaXMtZGlzYWJsZWQgJiB7XG4gICAgY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgfVxuXG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjUklCQk9OXG5cbiAgQmFzZTpcbiAgICAuYy1yaWJib25cbiAgICAgIC5jLXJpYmJvbl9fdGV4dFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtcmliYm9uIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICByaWdodDogLTJweDtcbiAgdG9wOiAtMnB4O1xuICB6LWluZGV4OiBtYXAtZ2V0KCR6X2luZGV4LCByaWJib24pO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB3aWR0aDogODRweDtcbiAgaGVpZ2h0OiA4NHB4O1xuICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xufVxuXG4uYy1yaWJib25fX3RleHQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMThweDtcbiAgcmlnaHQ6IC0yNnB4O1xuICBkaXNwbGF5OiBibG9jaztcbiAgd2lkdGg6IDExNXB4O1xuICBmb250LXNpemU6ICRmb250X3NpemVfc2Vjb25kYXJ5O1xuICBsaW5lLWhlaWdodDogMTkwJTtcbiAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIHRyYW5zZm9ybTogcm90YXRlKDQ1ZGVnKTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gIGJveC1zaGFkb3c6ICRib3hfc2hhZG93X3NlY29uZGFyeTtcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNTRUNUSU9OXG5cbiAgQmFzZTpcbiAgICAuYy1zZWN0aW9uXG5cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLXNlY3Rpb24ge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcbiAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfc2Vjb25kYXJ5O1xuICBib3JkZXItcmFkaXVzOiAkYm9yZGVyX3JhZGl1c19wcmltYXJ5O1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI1NFTEVDVFxuICBTZWxlY3QyIHBsdWdpbiAtIGh0dHBzOi8vc2VsZWN0Mi5naXRodWIuaW8vXG5cbiAgQmFzZTpcbiAgICAuc2VsZWN0Mi1jb250YWluZXJcbiAgICAgIC5zZWxlY3QyLXNlbGVjdGlvblxuICAgICAgICAuc2VsZWN0Mi1zZWxlY3Rpb25fX3JlbmRlcmVkXG4gICAgICAgIC5zZWxlY3QyLXNlbGVjdGlvbl9fYXJyb3dcbiAgICAgICAgLnNlbGVjdDItc2VsZWN0aW9uX19wbGFjZWhvbGRlclxuICAgICAgICAuc2VsZWN0Mi1zZWxlY3Rpb25fX2NsZWFyXG4gICAgICAgIC5zZWxlY3QyLXNlbGVjdGlvbl9fY2hvaWNlXG4gICAgICAgICAgLnNlbGVjdDItc2VsZWN0aW9uX19jaG9pY2VfX3JlbW92ZVxuXG4gICAgICAuc2VsZWN0Mi1kcm9wZG93blxuICAgICAgICAuc2VsZWN0Mi1zZWFyY2hcbiAgICAgICAgICAuc2VsZWN0Mi1zZWFyY2hfX2ZpZWxkXG4gICAgICAgIC5zZWxlY3QyLXJlc3VsdHNcbiAgICAgICAgICAuc2VsZWN0Mi1yZXN1bHRzX19vcHRpb25zXG4gICAgICAgICAgICAuc2VsZWN0Mi1yZXN1bHRzX19vcHRpb25cbiAgICAgICAgICAuc2VsZWN0Mi1yZXN1bHRzX19ncm91cFxuXG4gIFR5cGUgbW9kaWZpZXJzOlxuICAgIC5zZWxlY3QyLWNvbnRhaW5lci0tZGVmYXVsdFxuXG4gICAgLnNlbGVjdDItc2VsZWN0aW9uLS1zaW5nbGVcbiAgICAuc2VsZWN0Mi1zZWxlY3Rpb24tLW11bHRpcGxlXG5cbiAgICAuc2VsZWN0Mi1zZWFyY2gtLWlubGluZVxuICAgIC5zZWxlY3QyLXNlYXJjaC0tZHJvcGRvd25cblxuICBTdGF0ZSBtb2RpZmllcnM6XG4gICAgLnNlbGVjdDItY29udGFpbmVyLS1mb2N1c1xuICAgIC5zZWxlY3QyLWNvbnRhaW5lci0tZGlzYWJsZWRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5zZWxlY3QyLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICBmb250LXNpemU6ICRmb250X3NpemVfc2Vjb25kYXJ5O1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgJGNvbG9yX2hlcm1hbm9zO1xufVxuXG4uc2VsZWN0Mi1jb250YWluZXItLWZvY3VzIHtcblxuICAuc2VsZWN0Mi1zZWxlY3Rpb24tLW11bHRpcGxlIHtcbiAgICBvdXRsaW5lOiAwO1xuICB9XG5cbn1cblxuLnNlbGVjdDItY29udGFpbmVyLS1kaXNhYmxlZCB7XG5cbiAgLnNlbGVjdDItc2VsZWN0aW9uLS1tdWx0aXBsZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2hlcm1hbm9zO1xuICAgIGN1cnNvcjogZGVmYXVsdDtcbiAgfVxuXG4gIC5zZWxlY3QyLXNlbGVjdGlvbl9fY2hvaWNlX19yZW1vdmUge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxufVxuXG4uc2VsZWN0Mi1jb250YWluZXItLW9wZW4gLnNlbGVjdDItZHJvcGRvd24ge1xuICBsZWZ0OiAwO1xufVxuXG4uc2VsZWN0Mi1jb250YWluZXItLWRpc2FibGVkIHtcblxuICAuc2VsZWN0Mi1zZWxlY3Rpb24tLXNpbmdsZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2hlcm1hbm9zO1xuICAgIGN1cnNvcjogZGVmYXVsdDtcblxuICAgIC5zZWxlY3QyLXNlbGVjdGlvbl9fY2xlYXIge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG5cbiAgfVxuXG59XG5cbi5zZWxlY3QyLWNvbnRhaW5lci0tZGVmYXVsdCB7XG5cbiAgLnNlbGVjdDItc2VhcmNoLS1pbmxpbmUge1xuXG4gICAgLnNlbGVjdDItc2VhcmNoX19maWVsZCB7XG4gICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgIGJvcmRlcjogMDtcbiAgICAgIG91dGxpbmU6IDA7XG4gICAgICBib3gtc2hhZG93OiBub25lO1xuICAgICAgLXdlYmtpdC1hcHBlYXJhbmNlOiB0ZXh0ZmllbGQ7XG4gICAgfVxuXG4gIH1cblxuICAuc2VsZWN0Mi1yZXN1bHRzID4gLnNlbGVjdDItcmVzdWx0c19fb3B0aW9ucyB7XG4gICAgbWF4LWhlaWdodDogMjUwcHg7XG4gICAgb3ZlcmZsb3cteTogYXV0bztcbiAgfVxuXG4gIC5zZWxlY3QyLXJlc3VsdHNfX29wdGlvbiB7XG5cbiAgICAmW3JvbGU9Z3JvdXBdIHtcbiAgICAgIHBhZGRpbmc6IDA7XG4gICAgfVxuXG4gICAgJlthcmlhLWRpc2FibGVkPXRydWVdIHtcbiAgICAgIGNvbG9yOiAkY29sb3JfaGVybWFub3M7XG4gICAgfVxuXG4gICAgJlthcmlhLXNlbGVjdGVkPXRydWVdIHtcbiAgICAgIGNvbG9yOiAkY29sb3JfY3J5c3RhbDtcbiAgICB9XG5cbiAgICAuc2VsZWN0Mi1yZXN1bHRzX19vcHRpb24ge1xuICAgICAgcGFkZGluZy1sZWZ0OiAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG4gICAgfVxuXG4gIH1cblxuICAuc2VsZWN0Mi1yZXN1bHRzX19vcHRpb24tLWhpZ2hsaWdodGVkW2FyaWEtc2VsZWN0ZWRdIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3Jfc2t5bGVyO1xuICB9XG5cbiAgLnNlbGVjdDItcmVzdWx0c19fZ3JvdXAge1xuICAgIGN1cnNvcjogZGVmYXVsdDtcbiAgICBwYWRkaW5nOiAkc3BhY2luZ191bml0X3ByaW1hcnkgJHNwYWNpbmdfdW5pdF90ZXJ0aWFyeTtcbiAgICBAaW5jbHVkZSBlbGxpcHNpcygpO1xuICB9XG5cbn1cblxuLnNlbGVjdDItY2xvc2UtbWFzayB7XG4gIGJvcmRlcjogMDtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nOiAwO1xuICBkaXNwbGF5OiBibG9jaztcbiAgcG9zaXRpb246IGZpeGVkO1xuICBsZWZ0OiAwO1xuICB0b3A6IDA7XG4gIG1pbi1oZWlnaHQ6IDEwMCU7XG4gIG1pbi13aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiBhdXRvO1xuICB3aWR0aDogYXV0bztcbiAgb3BhY2l0eTogMDtcbiAgei1pbmRleDogOTk7XG59XG5cbi5zZWxlY3QyLWhpZGRlbi1hY2Nlc3NpYmxlIHtcbiAgQGluY2x1ZGUgdmlzdWFsbHlfaGlkZGVuO1xufVxuXG4uc2VsZWN0Mi1zZWxlY3Rpb24tLXNpbmdsZSB7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHVzZXItc2VsZWN0OiBub25lO1xuICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xuICBvdXRsaW5lOiAwO1xuXG4gIC5zZWxlY3QyLXNlbGVjdGlvbl9fcmVuZGVyZWQge1xuICAgIEBpbmNsdWRlIGVsbGlwc2lzKCk7XG4gICAgbGluZS1oZWlnaHQ6IDIuMTtcbiAgfVxuXG4gIC5zZWxlY3QyLXNlbGVjdGlvbl9fY2xlYXIge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgZmxvYXQ6IHJpZ2h0O1xuICAgIGZvbnQtd2VpZ2h0OiAkZm9udF93ZWlnaHRfbWVkaXVtO1xuICB9XG5cbiAgLnNlbGVjdDItc2VsZWN0aW9uX19wbGFjZWhvbGRlciB7XG4gICAgY29sb3I6ICRjb2xvcl9ndXN0YXZvO1xuICB9XG5cbiAgLnNlbGVjdDItc2VsZWN0aW9uX19hcnJvdyB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMDtcbiAgICByaWdodDogMTRweDtcbiAgICBoZWlnaHQ6IDEwMCU7XG5cbiAgICBiIHtcbiAgICAgIEBpbmNsdWRlIHRyaWFuZ2xlKCdkb3duJywgNXB4LCAkY29sb3JfZ3VzdGF2byk7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICBsZWZ0OiA1MCU7XG4gICAgICB0b3A6IDUwJTtcbiAgICB9XG5cbiAgfVxuXG59XG5cbi5zZWxlY3QyLXNlbGVjdGlvbi0tbXVsdGlwbGUge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcblxuICAuc2VsZWN0Mi1zZWxlY3Rpb25fX3JlbmRlcmVkIHtcbiAgICBAaW5jbHVkZSBlbGxpcHNpcygkZGlzcGxheTogaW5saW5lLWJsb2NrKTtcbiAgfVxuXG59XG5cbi5zZWxlY3QyLXNlYXJjaC0taW5saW5lIHtcbiAgZmxvYXQ6IGxlZnQ7XG5cbiAgLnNlbGVjdDItc2VhcmNoX19maWVsZCB7XG4gICAgXG4gICAgJjo6LXdlYmtpdC1zZWFyY2gtY2FuY2VsLWJ1dHRvbiB7XG4gICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgfVxuXG4gIH1cblxufVxuXG4uc2VsZWN0Mi1kcm9wZG93biB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICBkaXNwbGF5OiBibG9jaztcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiAtMTAwMDAwcHg7XG4gIHdpZHRoOiAxMDAlO1xuICBib3gtc2hhZG93OiAkYm94X3NoYWRvd19wcmltYXJ5O1xuICB6LWluZGV4OiBtYXAtZ2V0KCR6X2luZGV4LCBkcm9wZG93bik7XG59XG5cbi5zZWxlY3QyLXJlc3VsdHMge1xuICBkaXNwbGF5OiBibG9jaztcbn1cblxuLnNlbGVjdDItcmVzdWx0c19fb3B0aW9ucyB7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7XG59XG5cbi5zZWxlY3QyLXJlc3VsdHNfX29wdGlvbiB7XG4gIHBhZGRpbmc6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeSAkc3BhY2luZ191bml0X3F1aW5hcnkgJHNwYWNpbmdfdW5pdF9wcmltYXJ5ICRzcGFjaW5nX3VuaXRfdGVydGlhcnk7XG4gIHVzZXItc2VsZWN0OiBub25lO1xuICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xuICB0cmFuc2l0aW9uOiAkdHJhbnNpdGlvbl9wcmltYXJ5O1xuXG4gICZbYXJpYS1zZWxlY3RlZF0ge1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgfVxuXG59XG5cbi5zZWxlY3QyLXNlYXJjaCB7XG4gIC8vIE9ubHkgZm9yIHNlbGVjdCB3aXRoIHNlYXJjaCBmaWVsZCAtIG5lZWQgc29tZSBhZGRpdGlvbmFsIEhUTUwgdGFncyBzbyB3ZSBjYW4gcmVtb3ZlIG1peGluIGhlcmUuXG4gIEBpbmNsdWRlIGZvcm1faXRlbV91bmRlcmxpbmVfZWZmZWN0KCcuc2VsZWN0Mi1jb250YWluZXItLW9wZW4gJicpO1xuICBtYXJnaW46IDVweCAkc3BhY2luZ191bml0X3RlcnRpYXJ5ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLnNlbGVjdDItc2VhcmNoLS1kcm9wZG93biB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuXG4gIC5zZWxlY3QyLXNlYXJjaF9fZmllbGQge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBhZGRpbmc6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeSAwO1xuICAgIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9zZWNvbmRhcnk7XG4gICAgb3V0bGluZTogMDtcbiAgICBib3JkZXI6IDA7XG4gICAgYmFja2dyb3VuZDogdXJsKCcvL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vaW5zdGFwYWdlLWFwcC1hc3NldHMvMTQ3MTUyMDk3NV9pY29uLXNlYXJjaC5wbmcnKSByaWdodCBjZW50ZXIgbm8tcmVwZWF0O1xuXG4gICAgJjo6LXdlYmtpdC1zZWFyY2gtY2FuY2VsLWJ1dHRvbiB7XG4gICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgfVxuXG4gIH1cblxuICAmLnNlbGVjdDItc2VhcmNoLS1oaWRlIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG5cbn1cblxuLnNlbGVjdDItc2VsZWN0aW9uLS1tdWx0aXBsZSB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICBjdXJzb3I6IHRleHQ7XG5cbiAgLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCB7XG4gICAgbGlzdC1zdHlsZTogbm9uZTtcbiAgICB3aWR0aDogMTAwJTtcblxuICAgIGxpIHtcbiAgICAgIGxpc3Qtc3R5bGU6IG5vbmU7XG4gICAgfVxuXG4gIH1cblxuICAuc2VsZWN0Mi1zZWxlY3Rpb25fX3BsYWNlaG9sZGVyIHtcbiAgICBjb2xvcjogJGNvbG9yX2d1c3Rhdm87XG4gICAgbWFyZ2luLXRvcDogNXB4O1xuICAgIGZsb2F0OiBsZWZ0O1xuICB9XG5cbiAgLnNlbGVjdDItc2VsZWN0aW9uX19jbGVhciB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGZsb2F0OiByaWdodDtcbiAgICBmb250LXdlaWdodDogJGZvbnRfd2VpZ2h0X21lZGl1bTtcbiAgICBtYXJnaW4tdG9wOiA1cHg7XG4gICAgbWFyZ2luLXJpZ2h0OiAkc3BhY2luZ191bml0X3ByaW1hcnk7XG4gIH1cblxuICAuc2VsZWN0Mi1zZWxlY3Rpb25fX2Nob2ljZSB7XG4gICAgY3Vyc29yOiBkZWZhdWx0O1xuICAgIGZsb2F0OiBsZWZ0O1xuICB9XG5cbiAgLnNlbGVjdDItc2VsZWN0aW9uX19jaG9pY2VfX3JlbW92ZSB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBmb250LXdlaWdodDogJGZvbnRfd2VpZ2h0X21lZGl1bTtcbiAgfVxuICBcbn1cbiIsIi8vLyB0ZXh0IGVsbGlwc2lzXG5cbkBtaXhpbiBlbGxpcHNpcyAoXG4gICRtYXgtd2lkdGg6IDEwMCUsXG4gICRkaXNwbGF5OiBibG9ja1xuKVxue1xuICBkaXNwbGF5OiAkZGlzcGxheTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIG1heC13aWR0aDogJG1heC13aWR0aDtcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNTTkFDS0JBUlxuXG4gIEJhc2U6XG4gICAgLmMtc25hY2stYmFyXG4gICAgICAuYy1zbmFjay1iYXJfX3RleHRcblxuICBDb2xvciBtb2RpZmllcnM6XG4gICAgLmMtc25hY2stYmFyX190ZXh0LS1yZWd1bGFyXG4gICAgLmMtc25hY2stYmFyX190ZXh0LS1kYW5nZXJcbiAgICAuYy1zbmFjay1iYXJfX3RleHQtLXdhcm5pbmdcbiAgICAuYy1zbmFjay1iYXJfX3RleHQtLXN1Y2Nlc3NcblxuICBTdGF0ZSBtb2RpZmllcnM6XG4gICAgLmMtc25hY2stYmFyLmlzLWFuaW1hdGVkXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1zbmFjay1iYXIge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIGJvdHRvbTogLTI3NXB4OyAvLyBuZWVkIHRvIGhpZGUgY29udGVudCBhdCB0aGUgYmVnZ2luaW5nIG9mIGFuaW1hdGlvbi4gLTI3NXB4IGhpZGVzIDQgbGluZXMgdGV4dC5cbiAgbGVmdDogMDtcbiAgd2lkdGg6IDEwMCU7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgdHJhbnNpdGlvbjogJHRyYW5zaXRpb25fc2Vjb25kYXJ5O1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgei1pbmRleDogbWFwLWdldCgkel9pbmRleCwgc25hY2tiYXIpO1xuXG4gICYuaXMtYW5pbWF0ZWQge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMjk1cHgpO1xuICB9XG59XG5cbi5jLXNuYWNrLWJhcl9fdGV4dCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICBwYWRkaW5nOiAkc3BhY2luZ191bml0X3NlY29uZGFyeSAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG4gIG1heC13aWR0aDogOTAwcHg7XG59XG5cbi5jLXNuYWNrLWJhcl9fdGV4dC0tcmVndWxhciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl90dWNvO1xufVxuXG4uYy1zbmFjay1iYXJfX3RleHQtLWRhbmdlciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9kYW5nZXI7XG59XG5cbi5jLXNuYWNrLWJhcl9fdGV4dC0td2FybmluZyB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl93YXJuaW5nO1xufVxuXG4uYy1zbmFjay1iYXJfX3RleHQtLXN1Y2Nlc3Mge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3Jfc3VjY2Vzcztcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNTV0lUQ0hcblxuICBCYXNlOlxuICAgIC5jLXN3aXRjaFxuICAgICAgLmMtc3dpdGNoX19pbnB1dFxuICAgICAgLmMtc3dpdGNoX190ZXh0XG4gICAgICAuYy1zd2l0Y2hfX2hhbmRsZVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuJF9zd2l0Y2hfY2lyY2xlX3NpemU6IDIwcHg7XG4kX3N3aXRjaF9oYW5kbGVfd2lkdGg6IDM2cHg7XG4kX3N3aXRjaF9oYW5kbGVfaGVpZ2h0OiAxNHB4O1xuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4uYy1zd2l0Y2hcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLXN3aXRjaCB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbi5jLXN3aXRjaF9faW5wdXRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLXN3aXRjaF9faW5wdXQge1xuICBAaW5jbHVkZSB2aXN1YWxseV9oaWRkZW47XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbi5jLXN3aXRjaF9fdGV4dFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtc3dpdGNoX190ZXh0IHtcbiAgY29sb3I6ICRjb2xvcl90dWNvO1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbi5jLXN3aXRjaF9faGFuZGxlXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1zd2l0Y2hfX2hhbmRsZSB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB3aWR0aDogJF9zd2l0Y2hfaGFuZGxlX3dpZHRoO1xuICBoZWlnaHQ6ICRfc3dpdGNoX2hhbmRsZV9oZWlnaHQ7XG4gIGJvcmRlci1yYWRpdXM6ICRfc3dpdGNoX2hhbmRsZV9oZWlnaHQ7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBvdXRsaW5lOiAwO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy1zd2l0Y2hfX2hhbmRsZTo6YmVmb3JlIChjaXJjbGUpXG4gIFxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLmMtc3dpdGNoX19pbnB1dCB+ICY6OmJlZm9yZSB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgY29udGVudDogJyc7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogKCRfc3dpdGNoX2hhbmRsZV9oZWlnaHQgLSAkX3N3aXRjaF9jaXJjbGVfc2l6ZSkgLyAyO1xuICAgIHdpZHRoOiAkX3N3aXRjaF9jaXJjbGVfc2l6ZTtcbiAgICBoZWlnaHQ6ICRfc3dpdGNoX2NpcmNsZV9zaXplO1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcbiAgICBib3gtc2hhZG93OiAkYm94X3NoYWRvd19wcmltYXJ5O1xuICAgIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uX3ByaW1hcnk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gIH1cblxuICAuYy1zd2l0Y2hfX2lucHV0OmNoZWNrZWQgfiAmOjpiZWZvcmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9jcnlzdGFsO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKCRfc3dpdGNoX2hhbmRsZV93aWR0aCAtICRfc3dpdGNoX2NpcmNsZV9zaXplLCAwKTtcbiAgfVxuXG4gIC5jLXN3aXRjaF9faW5wdXQ6ZGlzYWJsZWQgfiAmOjpiZWZvcmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgfVxuXG4gIC5jLXN3aXRjaF9faW5wdXQgfiAmOmFjdGl2ZTo6YmVmb3JlIHtcbiAgICBib3gtc2hhZG93OiAkYm94X3NoYWRvd19wcmltYXJ5LCAwIDAgMCA4cHggcmdiYSgkY29sb3JfY3J5c3RhbCwgMC4yKTtcbiAgfVxuXG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbi5jLXN3aXRjaF9faGFuZGxlLFxuLmMtc3dpdGNoX190ZXh0XG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy1zd2l0Y2hfX3RleHQgfiAuYy1zd2l0Y2hfX2hhbmRsZSxcbi5jLXN3aXRjaF9faGFuZGxlIH4gLmMtc3dpdGNoX190ZXh0IHtcbiAgbWFyZ2luLWxlZnQ6ICRzcGFjaW5nX3VuaXRfcHJpbWFyeTtcbn1cblxuLmMtc3dpdGNoX19pbnB1dDpkaXNhYmxlZCB+IC5jLXN3aXRjaF9faGFuZGxlLFxuLmMtc3dpdGNoX19pbnB1dDpkaXNhYmxlZCB+IC5jLXN3aXRjaF9fdGV4dCB7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI1RBQkxFXG5cbiAgQmFzZTpcbiAgICAuYy10YWJsZVxuICAgICAgLmMtdGFibGVfX2NhcHRpb25cbiAgICAgICAgLmMtdGFibGVfX2NhcHRpb24tcm93XG4gICAgICAgIC5jLXRhYmxlX19jYXB0aW9uLWNlbGxcbiAgICAgIC5jLXRhYmxlX19oZWFkXG4gICAgICAuYy10YWJsZV9fYm9keVxuICAgICAgLmMtdGFibGVfX2Zvb3RlclxuXG4gICAgICAgIC5jLXRhYmxlX19jZWxsXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cbi5jLXRhYmxlIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9zZWNvbmRhcnk7XG4gIGJveC1zaGFkb3c6ICRib3hfc2hhZG93X3ByaW1hcnk7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICBib3JkZXItcmFkaXVzOiAkYm9yZGVyX3JhZGl1c19wcmltYXJ5O1xufVxuXG4uYy10YWJsZV9fY2FwdGlvbiB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIGJveC1zaGFkb3c6ICRib3hfc2hhZG93X3ByaW1hcnk7XG4gIEBpbmNsdWRlIHJhZGl1cygkYm9yZGVyX3JhZGl1c19wcmltYXJ5LCAkYm9yZGVyX3JhZGl1c19wcmltYXJ5KTtcbiAgYmFja2dyb3VuZC1jb2xvcjogaW5oZXJpdDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICRjb2xvcl9oZXJtYW5vcztcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gIC8vIGZpeGVzIGNhcHRpb24gYm90dG9tIHNoYWRvdyBwcm9ibGVtXG4gICY6OmFmdGVyIHtcbiAgICBjb250ZW50OiAnJztcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBoZWlnaHQ6IDJweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfbXJ3aGl0ZTtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgYm90dG9tOiAtM3B4O1xuICAgIHdpZHRoOiAxMDAlO1xuICB9XG59XG5cbi5jLXRhYmxlX19jYXB0aW9uLXJvdyB7XG4gIGhlaWdodDogMTAwJTtcbiAgcGFkZGluZzogMCAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG59XG5cbi5jLXRhYmxlX19jYXB0aW9uLXRpdGxlIHtcbiAgZm9udC1zaXplOiAyMHB4O1xufVxuXG4uYy10YWJsZV9fY2FwdGlvbixcbi5jLXRhYmxlX19jZWxsIHtcbiAgaGVpZ2h0OiA1MHB4O1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xufVxuXG4uYy10YWJsZV9faGVhZCB7XG4gIGNvbG9yOiAkY29sb3JfZ3VzdGF2bztcbiAgYmFja2dyb3VuZC1jb2xvcjogaW5oZXJpdDtcblxuICAuYy10YWJsZV9fY2VsbDpmaXJzdC1jaGlsZCB7XG4gICAgQGluY2x1ZGUgcmFkaXVzKCRib3JkZXJfcmFkaXVzX3ByaW1hcnkpO1xuICB9XG5cbiAgLmMtdGFibGVfX2NlbGw6bGFzdC1jaGlsZCB7XG4gICAgQGluY2x1ZGUgcmFkaXVzKG51bGwsICRib3JkZXJfcmFkaXVzX3ByaW1hcnkpO1xuICB9XG5cbiAgLy8gbmVlZCB0byByZXNldCBib3JkZXIgcmFkaXVzIHdoZW4gcHJlY2VkZWQgd2l0aCBjYXB0aW9uXG4gIC5jLXRhYmxlX19jYXB0aW9uICsgJiB7XG4gICAgLmMtdGFibGVfX2NlbGw6Zmlyc3QtY2hpbGQge1xuICAgICAgQGluY2x1ZGUgcmFkaXVzKDApO1xuICAgIH1cblxuICAgIC5jLXRhYmxlX19jZWxsOmxhc3QtY2hpbGQge1xuICAgICAgQGluY2x1ZGUgcmFkaXVzKG51bGwsIDApO1xuICAgIH1cbiAgfVxufVxuXG4uYy10YWJsZV9fZm9vdGVyIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3NreWxlcjtcblxuICAuYy10YWJsZV9fY2VsbCB7XG4gICAgYm9yZGVyLWJvdHRvbTogbm9uZTtcbiAgfVxuXG4gIC5jLXRhYmxlX19jZWxsOmZpcnN0LWNoaWxkIHtcbiAgICBAaW5jbHVkZSByYWRpdXMobnVsbCwgbnVsbCwgbnVsbCwgJGJvcmRlcl9yYWRpdXNfcHJpbWFyeSk7XG4gIH1cblxuICAuYy10YWJsZV9fY2VsbDpsYXN0LWNoaWxkIHtcbiAgICBAaW5jbHVkZSByYWRpdXMobnVsbCwgbnVsbCwgJGJvcmRlcl9yYWRpdXNfcHJpbWFyeSk7XG4gIH1cbn1cblxuLmMtdGFibGVfX2NlbGwge1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIHBhZGRpbmc6IDAgJHNwYWNpbmdfdW5pdF9zZWNvbmRhcnk7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAkY29sb3JfaGVybWFub3M7XG5cbiAgJjpmaXJzdC1jaGlsZCB7XG4gICAgcGFkZGluZy1sZWZ0OiAkc3BhY2luZ191bml0X3F1YXRlcm5hcnk7XG4gIH1cblxuICAmOmxhc3QtY2hpbGQge1xuICAgIHBhZGRpbmctcmlnaHQ6ICRzcGFjaW5nX3VuaXRfcXVhdGVybmFyeTtcbiAgfVxufVxuXG4uYy10YWJsZV9fY2VsbC0tbGVmdCB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59IiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI1RBQlNcblxuICBCYXNlOlxuICAgIC5jLXRhYnNcbiAgICAgIC5jLXRhYnNfX2xpc3RcbiAgICAgICAgLmMtdGFiXG4gICAgICAgICAgLmMtdGFiX190ZXh0XG4gICAgICAuYy10YWJzX19zbGlkZXJcblxuXG4gIERpc3BsYXkgbW9kaWZpZXJzOlxuICAgIC5jLXRhYnMtLWZ1bGwtd2lkdGhcbiAgICAuYy10YWJzLS13aXRoLXNoYWRvd1xuXG4gIFN0YXRlIG1vZGlmaWVycyBmb3IgLmMtdGFiOlxuICAgIC5pcy1hY3RpdmVcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLXRhYnMge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5jLXRhYnMtLXdpdGgtc2hhZG93IHtcbiAgYm94LXNoYWRvdzogJGJveF9zaGFkb3dfYm90dG9tX3NlY29uZGFyeTtcbn1cblxuLmMtdGFic19fbGlzdCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9tcndoaXRlO1xufVxuXG4uYy10YWIge1xuXG4gIC5jLXRhYnMtLWZ1bGwtd2lkdGggJiB7XG4gICAgd2lkdGg6IDA7IC8vIGp1c3QgYSBoYWNrIHRvIGVuYWJsZSBlbGxpcHNpcyBhbmQgZXF1YWwgdGFicyB3aWR0aFxuICAgIGZsZXg6IDEgMSBhdXRvO1xuICB9XG5cbn1cblxuLmMtdGFiX190ZXh0IHtcbiAgY29sb3I6ICRjb2xvcl9ndXN0YXZvO1xuICBmb250LXNpemU6ICRmb250X3NpemVfc2Vjb25kYXJ5O1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgbGluZS1oZWlnaHQ6IDU0cHg7XG4gIHBhZGRpbmctbGVmdDogMjBweDtcbiAgcGFkZGluZy1yaWdodDogMjBweDtcbiAgdHJhbnNpdGlvbjogJHRyYW5zaXRpb25fcHJpbWFyeTtcbiAgQGluY2x1ZGUgZWxsaXBzaXMoMjAwcHgpO1xuXG4gICY6aG92ZXIge1xuICAgIGNvbG9yOiAkY29sb3JfdHVjbztcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICB9XG5cbiAgLmMtdGFiLmlzLWFjdGl2ZSAmIHtcbiAgICBjb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gIH1cblxuICAuYy10YWJzLS1mdWxsLXdpZHRoICYge1xuICAgIG1heC13aWR0aDogbm9uZTtcbiAgfVxuXG59XG5cbi5jLXRhYnNfX3NsaWRlciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgYm90dG9tOiAwO1xuICBoZWlnaHQ6IDJweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uX3ByaW1hcnk7XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjVEVYVCBMSU5FXG5cbiAgQmFzZTpcbiAgICAuYy10ZXh0LWxpbmVcblxuICBMaW5lIHNpZGUgbW9kaWZpZXJzOlxuICAgIC5jLXRleHQtbGluZS0tbGVmdFxuICAgIC5jLXRleHQtbGluZS0tcmlnaHRcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi5jLXRleHQtbGluZSB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuXG4gICY6OmJlZm9yZSxcbiAgJjo6YWZ0ZXIge1xuICAgIGhlaWdodDogMXB4O1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9oZXJtYW5vcztcbiAgICBjb250ZW50OiAnJztcbiAgICBmbGV4LWdyb3c6IDE7XG4gIH1cblxuICAmOjpiZWZvcmUge1xuICAgIG1hcmdpbi1yaWdodDogJHNwYWNpbmdfdW5pdF9wcmltYXJ5IC8gMjtcbiAgfVxuXG4gICY6OmFmdGVyIHtcbiAgICBtYXJnaW4tbGVmdDogJHNwYWNpbmdfdW5pdF9wcmltYXJ5IC8gMjtcbiAgfVxufVxuXG4uYy10ZXh0LWxpbmUtLWxlZnQge1xuICAmOjpiZWZvcmUge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cbn1cblxuLmMtdGV4dC1saW5lLS1yaWdodCB7XG4gICY6OmFmdGVyIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjVE9HR0xFXG5cbiAgQmFzZTpcbiAgICAuYy10b2dnbGVcbiAgICAgIC5jLXRvZ2dsZV9faXRlbVxuICAgICAgICAuYy10b2dnbGVfX2lucHV0IC0gaGlkZGVuIGZyb20gc2NyZWVuXG4gICAgICAgIC5jLXRvZ2dsZV9fY29udGVudFxuXG4gIFN0YXRlIG1vZGlmaWVyczpcbiAgICAuYy10b2dnbGVfX2lucHV0OmNoZWNrZWRcbiAgICAuYy10b2dnbGVfX2lucHV0OmRpc2FibGVkXG5cblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiRfdG9nZ2xlX2xpbmVfaGVpZ2h0OiAzMXB4ICFkZWZhdWx0O1xuJF90b2dnbGVfYm9yZGVyX3dpZHRoOiAxcHggIWRlZmF1bHQ7XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtdG9nZ2xlXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy10b2dnbGUge1xuICBkaXNwbGF5OiBmbGV4O1xuICBjb2xvcjogJGNvbG9yX2d1c3Rhdm87XG4gIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV90ZXJ0aWFyeTtcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbi5jLXRvZ2dsZV9faW5wdXQge1xuICBAaW5jbHVkZSB2aXN1YWxseV9oaWRkZW47XG59XG5cbi5jLXRvZ2dsZV9faXRlbSB7XG4gIG1pbi13aWR0aDogMDtcbn1cblxuLmMtdG9nZ2xlX19jb250ZW50IHtcbiAgcGFkZGluZzogMCAkc3BhY2luZ191bml0X3RlcnRpYXJ5O1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uX3ByaW1hcnk7XG4gIGJvcmRlci10b3A6ICRjb2xvcl9oZXJtYW5vcyAkX3RvZ2dsZV9ib3JkZXJfd2lkdGggc29saWQ7XG4gIGJvcmRlci1ib3R0b206ICRjb2xvcl9oZXJtYW5vcyAkX3RvZ2dsZV9ib3JkZXJfd2lkdGggc29saWQ7XG4gIGxpbmUtaGVpZ2h0OiAkX3RvZ2dsZV9saW5lX2hlaWdodDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBAaW5jbHVkZSBlbGxpcHNpcygxMDAlKTtcblxuICAvL2h0dHBzOi8vY3NzLXRyaWNrcy5jb20vZmxleGJveC10cnVuY2F0ZWQtdGV4dC9cbiAgLy9mb3IgbW9iaWxlIGJyZWFrcG9pbnQgb25seVxuICBAaW5jbHVkZSBhdi1tcShoYW5kaGVsZCkge1xuICAgICYge1xuICAgICAgZmxleDogMTtcbiAgICB9XG4gIH1cblxuICAmOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3Jfc2t5bGVyO1xuICAgIGNvbG9yOiAkY29sb3JfdHVjbztcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cblxuICAuYy10b2dnbGVfX2l0ZW06Zmlyc3QtY2hpbGQgJiB7XG4gICAgYm9yZGVyLWxlZnQ6ICRjb2xvcl9oZXJtYW5vcyAkX3RvZ2dsZV9ib3JkZXJfd2lkdGggc29saWQ7XG4gICAgQGluY2x1ZGUgcmFkaXVzKCRib3JkZXJfcmFkaXVzX3ByaW1hcnksIG51bGwsIG51bGwsICRib3JkZXJfcmFkaXVzX3ByaW1hcnkpO1xuICB9XG5cbiAgLmMtdG9nZ2xlX19pdGVtOmxhc3QtY2hpbGQgJiB7XG4gICAgYm9yZGVyLXJpZ2h0OiAkY29sb3JfaGVybWFub3MgJF90b2dnbGVfYm9yZGVyX3dpZHRoIHNvbGlkO1xuICAgIEBpbmNsdWRlIHJhZGl1cyhudWxsLCAkYm9yZGVyX3JhZGl1c19wcmltYXJ5LCAkYm9yZGVyX3JhZGl1c19wcmltYXJ5KTtcbiAgfVxuXG4gIC5jLXRvZ2dsZV9faW5wdXQ6Y2hlY2tlZCB+ICYge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9jcnlzdGFsO1xuICAgIGJvcmRlci1jb2xvcjogJGNvbG9yX2NyeXN0YWw7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgY29sb3I6ICRjb2xvcl9tcndoaXRlO1xuICB9XG5cbiAgLmMtdG9nZ2xlX19pbnB1dDpkaXNhYmxlZCB+ICYge1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIGNvbG9yOiAkY29sb3JfaGVybWFub3M7XG4gIH1cbn1cblxuLmMtdG9nZ2xlX19pY29uIHtcbiAgbGluZS1oZWlnaHQ6ICRfdG9nZ2xlX2xpbmVfaGVpZ2h0O1xuICB2ZXJ0aWNhbC1hbGlnbjogdG9wO1xuICB3aWR0aDogJGljb25fc2l6ZV9wcmltYXJ5O1xufVxuIiwiLypcbiAgVG9vbHRpcFxuXG4gIEJhc2U6XG4gICAgLmMtdG9vbHRpcFxuXG4gIFRvb2x0aXAgYXJyb3cgbW9kaWZpZXJzOlxuICAgIC5jLXRvb2x0aXAtLXRvcFxuICAgIC5jLXRvb2x0aXAtLWJvdHRvbVxuICAgIC5jLXRvb2x0aXAtLWxlZnRcbiAgICAuYy10b29sdGlwLS1yaWdodFxuXG4gIFN0YXRlIG1vZGlmaWVyczpcbiAgICAuYy10b29sdGlwLS1zaG93XG4gICAgLmMtdG9vbHRpcC0taGlkZVxuKi9cblxuJF90b29sdGlwX3NpemVfcGFyYW06IDVweCAhZGVmYXVsdDtcbiRfdG9vbHRpcF9oZWlnaHQ6IDI2cHggIWRlZmF1bHQ7XG4kX3Rvb2x0aXBfb2ZmX3ZlcnRpY2FsOiA0MCUgIWRlZmF1bHQ7XG4kX3Rvb2x0aXBfb2ZmX2hvcml6b250YWw6IDMwJSAhZGVmYXVsdDtcblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy10b29sdGlwXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy10b29sdGlwIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBtaW4taGVpZ2h0OiAkX3Rvb2x0aXBfaGVpZ2h0O1xuICB6LWluZGV4OiBtYXAtZ2V0KCR6X2luZGV4LCB0b29sdGlwKTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3JfdHVjbztcbiAgZm9udC1zaXplOiAkZm9udF9zaXplX3RlcnRpYXJ5O1xuICBsaW5lLWhlaWdodDogMS4yO1xuICBjb2xvcjogJGNvbG9yX21yd2hpdGU7XG4gIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDtcbiAgd29yZC13cmFwOiBicmVhay13b3JkO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHBhZGRpbmc6IDVweCAkc3BhY2luZ191bml0X3ByaW1hcnkgNnB4O1xuICBib3JkZXItcmFkaXVzOiAkYm9yZGVyX3JhZGl1c19wcmltYXJ5O1xuICB3aWxsLWNoYW5nZTogdHJhbnNmb3JtLCBvcGFjaXR5O1xuICBtYXgtd2lkdGg6IDI1MHB4O1xuXG4gICY6OmJlZm9yZSB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHdpZHRoOiAwO1xuICAgIGhlaWdodDogMDtcbiAgICBib3JkZXItc3R5bGU6IHNvbGlkO1xuICB9XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtdG9vbHRpcC0tc2hvdyBhbmltYXRpb25zXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5Aa2V5ZnJhbWVzIHNob3ctdG9vbHRpcCB7XG4gIDAlIHtcbiAgICBvcGFjaXR5OiAwO1xuICB9XG5cbiAgODAlIHtcbiAgICBvcGFjaXR5OiAxO1xuICB9XG5cbiAgMTAwJSB7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLCAwLCAwKTtcbiAgfVxufVxuXG5Aa2V5ZnJhbWVzIHNob3ctdG9vbHRpcC1ib3R0b20ge1xuICAwJSB7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLCAtI3skX3Rvb2x0aXBfb2ZmX3ZlcnRpY2FsfSwgMCk7XG4gIH1cbn1cblxuQGtleWZyYW1lcyBzaG93LXRvb2x0aXAtdG9wIHtcbiAgMCUge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwgI3skX3Rvb2x0aXBfb2ZmX3ZlcnRpY2FsfSwgMCk7XG4gIH1cbn1cblxuQGtleWZyYW1lcyBzaG93LXRvb2x0aXAtbGVmdCB7XG4gIDAlIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCN7JF90b29sdGlwX29mZl9ob3Jpem9udGFsfSwgMCwgMCk7XG4gIH1cbn1cblxuQGtleWZyYW1lcyBzaG93LXRvb2x0aXAtcmlnaHQge1xuICAwJSB7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgtI3skX3Rvb2x0aXBfb2ZmX2hvcml6b250YWx9LCAwLCAwKTtcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLXRvb2x0aXAtLWhpZGUgYW5pbWF0aW9uc1xuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuQGtleWZyYW1lcyBoaWRlLXRvb2x0aXAge1xuICAxMDAlIHtcbiAgICBvcGFjaXR5OiAwO1xuICB9XG59XG5cbkBrZXlmcmFtZXMgaGlkZS10b29sdGlwLWJvdHRvbSB7XG4gIDEwMCUge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwgLSN7JF90b29sdGlwX29mZl92ZXJ0aWNhbH0sIDApO1xuICB9XG59XG5cbkBrZXlmcmFtZXMgaGlkZS10b29sdGlwLXRvcCB7XG4gIDEwMCUge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwgI3skX3Rvb2x0aXBfb2ZmX3ZlcnRpY2FsfSwgMCk7XG4gIH1cbn1cbkBrZXlmcmFtZXMgaGlkZS10b29sdGlwLWxlZnQge1xuICAxMDAlIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCN7JF90b29sdGlwX29mZl9ob3Jpem9udGFsfSwgMCwgMCk7XG4gIH1cbn1cblxuQGtleWZyYW1lcyBoaWRlLXRvb2x0aXAtcmlnaHQge1xuICAxMDAlIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKC0jeyRfdG9vbHRpcF9vZmZfaG9yaXpvbnRhbH0sIDAsIDApO1xuICB9XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgLmMtdG9vbHRpcC0tc2hvdyxcbiAgLmMtdG9vbHRpcC0taGlkZVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtdG9vbHRpcC0tc2hvdyxcbi5jLXRvb2x0aXAtLWhpZGUge1xuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoLjA1LCAuNDUsIC4zNCwgLjk0KTtcbiAgYW5pbWF0aW9uLWZpbGwtbW9kZTogZm9yd2FyZHM7XG59XG5cbi5jLXRvb2x0aXAtLXNob3cge1xuICBhbmltYXRpb24tZHVyYXRpb246IC4xNXM7XG5cbiAgJi5jLXRvb2x0aXAtLWJvdHRvbSB7XG4gICAgYW5pbWF0aW9uLW5hbWU6IHNob3ctdG9vbHRpcCwgc2hvdy10b29sdGlwLWJvdHRvbTtcbiAgfVxuXG4gICYuYy10b29sdGlwLS10b3Age1xuICAgIGFuaW1hdGlvbi1uYW1lOiBzaG93LXRvb2x0aXAsIHNob3ctdG9vbHRpcC10b3A7XG4gIH1cblxuICAmLmMtdG9vbHRpcC0tbGVmdCB7XG4gICAgYW5pbWF0aW9uLW5hbWU6IHNob3ctdG9vbHRpcCwgc2hvdy10b29sdGlwLWxlZnQ7XG4gIH1cblxuICAmLmMtdG9vbHRpcC0tcmlnaHQge1xuICAgIGFuaW1hdGlvbi1uYW1lOiBzaG93LXRvb2x0aXAsIHNob3ctdG9vbHRpcC1yaWdodDtcbiAgfVxufVxuXG4uYy10b29sdGlwLS1oaWRlIHtcbiAgYW5pbWF0aW9uLWR1cmF0aW9uOiAuMnM7XG5cbiAgJi5jLXRvb2x0aXAtLWJvdHRvbSB7XG4gICAgYW5pbWF0aW9uLW5hbWU6IGhpZGUtdG9vbHRpcCwgaGlkZS10b29sdGlwLWJvdHRvbTtcbiAgfVxuXG4gICYuYy10b29sdGlwLS10b3Age1xuICAgIGFuaW1hdGlvbi1uYW1lOiBoaWRlLXRvb2x0aXAsIGhpZGUtdG9vbHRpcC10b3A7XG4gIH1cblxuICAmLmMtdG9vbHRpcC0tbGVmdCB7XG4gICAgYW5pbWF0aW9uLW5hbWU6IGhpZGUtdG9vbHRpcCwgaGlkZS10b29sdGlwLWxlZnQ7XG4gIH1cblxuICAmLmMtdG9vbHRpcC0tcmlnaHQge1xuICAgIGFuaW1hdGlvbi1uYW1lOiBoaWRlLXRvb2x0aXAsIGhpZGUtdG9vbHRpcC1yaWdodDtcbiAgfVxufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gIC5jLXRvb2x0aXAtLXRvcCxcbiAgLmMtdG9vbHRpcC0tYm90dG9tXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4uYy10b29sdGlwLS10b3AsXG4uYy10b29sdGlwLS1ib3R0b20ge1xuICAmOjpiZWZvcmUge1xuICAgIGxlZnQ6IDUwJTtcbiAgICBtYXJnaW4tbGVmdDogLSRfdG9vbHRpcF9zaXplX3BhcmFtO1xuICAgIH1cbiAgfVxuXG4uYy10b29sdGlwLS10b3Age1xuICAmOjpiZWZvcmUge1xuICAgIGJvdHRvbTogLSRfdG9vbHRpcF9zaXplX3BhcmFtO1xuICAgIGJvcmRlci13aWR0aDogJF90b29sdGlwX3NpemVfcGFyYW0gJF90b29sdGlwX3NpemVfcGFyYW0gMCAkX3Rvb2x0aXBfc2l6ZV9wYXJhbTtcbiAgICBib3JkZXItY29sb3I6ICRjb2xvcl90dWNvIHRyYW5zcGFyZW50IHRyYW5zcGFyZW50IHRyYW5zcGFyZW50O1xuICB9XG59XG5cbi5jLXRvb2x0aXAtLWJvdHRvbSB7XG4gICY6OmJlZm9yZSB7XG4gICAgdG9wOiAtJF90b29sdGlwX3NpemVfcGFyYW07XG4gICAgYm9yZGVyLXdpZHRoOiAwICRfdG9vbHRpcF9zaXplX3BhcmFtICRfdG9vbHRpcF9zaXplX3BhcmFtICRfdG9vbHRpcF9zaXplX3BhcmFtO1xuICAgIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQgdHJhbnNwYXJlbnQgJGNvbG9yX3R1Y28gdHJhbnNwYXJlbnQ7XG4gIH1cbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAuYy10b29sdGlwLS1yaWdodCxcbiAgLmMtdG9vbHRpcC0tbGVmdFxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLmMtdG9vbHRpcC0tcmlnaHQsXG4uYy10b29sdGlwLS1sZWZ0IHtcbiAgJjo6YmVmb3JlIHtcbiAgICB0b3A6IDUwJTtcbiAgICBtYXJnaW4tdG9wOiAtJF90b29sdGlwX3NpemVfcGFyYW07XG4gIH1cbn1cblxuLmMtdG9vbHRpcC0tcmlnaHQge1xuICAmOjpiZWZvcmUge1xuICAgIGxlZnQ6IC0kX3Rvb2x0aXBfc2l6ZV9wYXJhbTtcbiAgICBib3JkZXItd2lkdGg6ICRfdG9vbHRpcF9zaXplX3BhcmFtICRfdG9vbHRpcF9zaXplX3BhcmFtICRfdG9vbHRpcF9zaXplX3BhcmFtIDA7XG4gICAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudCAkY29sb3JfdHVjbyB0cmFuc3BhcmVudCB0cmFuc3BhcmVudDtcbiAgfVxufVxuXG4uYy10b29sdGlwLS1sZWZ0IHtcbiAgJjo6YmVmb3JlIHtcbiAgICByaWdodDogLSRfdG9vbHRpcF9zaXplX3BhcmFtO1xuICAgIGJvcmRlci13aWR0aDogJF90b29sdGlwX3NpemVfcGFyYW0gMCAkX3Rvb2x0aXBfc2l6ZV9wYXJhbSAkX3Rvb2x0aXBfc2l6ZV9wYXJhbTtcbiAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50IHRyYW5zcGFyZW50IHRyYW5zcGFyZW50ICRjb2xvcl90dWNvO1xuICB9XG59XG4iLCJib2R5IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yX3NreWxlcjtcbn1cbiIsIi5oZWFkZXIge1xuICBib3gtc2hhZG93OiAkYm94X3NoYWRvd19zZWNvbmRhcnk7XG4gIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl9tcndoaXRlO1xufVxuXG4uaGVhZGVyX190b3Age1xuICBtaW4taGVpZ2h0OiA2NXB4O1xufVxuXG4uaGVhZGVyX19sb2dvIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHdpZHRoOiAxMzBweDtcbiAgaGVpZ2h0OiAyNnB4O1xufVxuIiwiLmZvb3RlciB7XG4gIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9zZWNvbmRhcnk7XG4gIG1hcmdpbi10b3A6ICRzcGFjaW5nX3VuaXRfc2VuYXJ5O1xuICBtYXJnaW4tYm90dG9tOiAkc3BhY2luZ191bml0X3NlbmFyeTtcbn1cbiIsIi51LWVsbGlwc2lzIHtcbiAgQGluY2x1ZGUgZWxsaXBzaXM7XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjRk9OVCBTSVpFXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4udS10ZXh0LS1zbWFsbCB7XG4gIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV9zZWNvbmRhcnkgIWltcG9ydGFudDtcbn1cblxuLnUtdGV4dC0teC1zbWFsbCB7XG4gIGZvbnQtc2l6ZTogJGZvbnRfc2l6ZV90ZXJ0aWFyeSAhaW1wb3J0YW50O1xufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNGT05UIENPTE9SXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4udS10ZXh0LS1kYW5nZXIge1xuICBjb2xvcjogJGNvbG9yX2RhbmdlciAhaW1wb3J0YW50O1xufVxuXG4udS10ZXh0LS13YXJuaW5nIHtcbiAgY29sb3I6ICRjb2xvcl93YXJuaW5nICFpbXBvcnRhbnQ7XG59XG5cbi51LXRleHQtLXN1Y2Nlc3Mge1xuICBjb2xvcjogJGNvbG9yX3N1Y2Nlc3MgIWltcG9ydGFudDtcbn1cblxuLnUtdGV4dC0tYWN0aW9uIHtcbiAgY29sb3I6ICRjb2xvcl9jcnlzdGFsICFpbXBvcnRhbnQ7XG59XG5cbi51LXRleHQtLWluYWN0aXZlIHtcbiAgY29sb3I6ICRjb2xvcl9ndXN0YXZvICFpbXBvcnRhbnQ7XG59XG5cbi51LXRleHQtLWxlc3MtaW1wb3J0YW50IHtcbiAgY29sb3I6ICRjb2xvcl9nb29kbWFuICFpbXBvcnRhbnQ7XG59XG5cbi51LXRleHQtLWZhY2Vib29rIHtcbiAgY29sb3I6ICRjb2xvcl9mYWNlYm9vayAhaW1wb3J0YW50O1xufVxuXG4udS10ZXh0LS13b3JkcHJlc3Mge1xuICBjb2xvcjogJGNvbG9yX3dvcmRwcmVzcyAhaW1wb3J0YW50O1xufVxuXG4udS10ZXh0LS1kcnVwYWwge1xuICBjb2xvcjogJGNvbG9yX2RydXBhbCAhaW1wb3J0YW50O1xufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4gICNURVhUIFRSQU5TRk9STVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLnUtdGV4dC0tdXBwZXIge1xuICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlICFpbXBvcnRhbnQ7XG59XG5cblxuLnUtdGV4dC0tY2VudGVyIHtcbiAgdGV4dC1hbGlnbjogY2VudGVyICFpbXBvcnRhbnQ7XG59XG5cbi51LXRleHQtLXJpZ2h0IHtcbiAgdGV4dC1hbGlnbjogcmlnaHQgIWltcG9ydGFudDtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjSUNPTlxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLnUtaWNvbi0tbGFyZ2Uge1xuICBmb250LXNpemU6ICRpY29uX3NpemVfc2Vjb25kYXJ5ICFpbXBvcnRhbnQ7XG59XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qXFxcbiAgI1BPU0lUSU9OXG5cXCotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4udS1yZWxhdGl2ZSB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZSAhaW1wb3J0YW50O1xufVxuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKlxcXG4jU1BBQ0VcblxcKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi51LXNwYWNlLXRvcC1ub25lIHtcbiAgcGFkZGluZy10b3A6IDAgIWltcG9ydGFudDtcbn1cblxuLnUtc3BhY2UtcmlnaHQtbm9uZSB7XG4gIHBhZGRpbmctcmlnaHQ6IDAgIWltcG9ydGFudDtcbn1cblxuLnUtc3BhY2UtYm90dG9tLW5vbmUge1xuICBwYWRkaW5nLWJvdHRvbTogMCAhaW1wb3J0YW50O1xufVxuXG4udS1zcGFjZS1sZWZ0LW5vbmUge1xuICBwYWRkaW5nLWxlZnQ6IDAgIWltcG9ydGFudDtcbn1cblxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSpcXFxuICAjRElTUExBWVxuXFwqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuLnUtaGlkZGVuIHtcbiAgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1xufVxuIl0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9 */
assets/js/InstapageCmsPluginAjax.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ActiveXObject */
2
+ var InstapageCmsPluginAjax = function InstapageCmsPluginAjax() {
3
+ var self = this;
4
+
5
+ self.call = function call(method, url, data, callbackFunction, async) {
6
+ var async = (typeof async === 'undefined') ? true : async;
7
+ var xmlhttp = null;
8
+ var urlAppendix = (url.match(/\?/) === null ? '?' : '&') + (new Date()).getTime();
9
+
10
+ if (window.XMLHttpRequest) {
11
+ xmlhttp = new XMLHttpRequest();
12
+ } else {
13
+ xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
14
+ }
15
+
16
+ xmlhttp.onreadystatechange = function onreadystatechange() {
17
+ if (xmlhttp.readyState === 4 && typeof callbackFunction === 'function') {
18
+ callbackFunction(xmlhttp.response);
19
+ }
20
+ };
21
+
22
+ xmlhttp.open(method, url + urlAppendix, async);
23
+
24
+ if (method === 'POST') {
25
+ var formData = new FormData();
26
+ formData.append('data', encodeURI(JSON.stringify(data)));
27
+ xmlhttp.send(formData);
28
+ } else {
29
+ xmlhttp.send();
30
+ }
31
+ };
32
+
33
+ self.post = function post(url, data, callbackFunction, async) {
34
+ self.call('POST', url, data, callbackFunction, async);
35
+ };
36
+ };
37
+
38
+ var iAjax = new InstapageCmsPluginAjax();
39
+ window.iAjax = iAjax;
assets/js/InstapageCmsPluginLang.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals InstapageDictionary */
2
+ var InstapageCmsPluginLang = function InstapageCmsPluginLang() {
3
+ var self = this;
4
+
5
+ self.lang = InstapageDictionary;
6
+
7
+ self.get = function get(format) {
8
+ var result = self.lang[arguments[0]];
9
+
10
+ for (var i = 1; i < arguments.length; i++) {
11
+ result = result.replace(/%s/, arguments[i]);
12
+ }
13
+
14
+ return result;
15
+ };
16
+ };
17
+
18
+ var iLang = new InstapageCmsPluginLang();
19
+ window.iLang = iLang;
assets/js/download.js ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //download.js v4.2, by dandavis; 2008-2016. [CCBY2] see http://danml.com/download.html for tests/usage
2
+ // v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
3
+ // v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
4
+ // v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.
5
+ // v4 adds AMD/UMD, commonJS, and plain browser support
6
+ // v4.1 adds url download capability via solo URL argument (same domain/CORS only)
7
+ // v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors
8
+ // https://github.com/rndme/download
9
+
10
+ (function (root, factory) {
11
+ if (typeof define === 'function' && define.amd) {
12
+ // AMD. Register as an anonymous module.
13
+ define([], factory);
14
+ } else if (typeof exports === 'object') {
15
+ // Node. Does not work with strict CommonJS, but
16
+ // only CommonJS-like environments that support module.exports,
17
+ // like Node.
18
+ module.exports = factory();
19
+ } else {
20
+ // Browser globals (root is window)
21
+ root.download = factory();
22
+ }
23
+ } (this, function () {
24
+
25
+ return function download(data, strFileName, strMimeType) {
26
+
27
+ var self = window, // this script is only for browsers anyway...
28
+ defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads
29
+ mimeType = strMimeType || defaultMime,
30
+ payload = data,
31
+ url =! strFileName && !strMimeType && payload,
32
+ anchor = document.createElement("a"),
33
+ toString = function(a){return String(a);},
34
+ myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString),
35
+ fileName = strFileName || "download",
36
+ blob,
37
+ reader;
38
+ myBlob = myBlob.call ? myBlob.bind(self) : Blob ;
39
+
40
+ if (String(this) === "true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
41
+ payload = [payload, mimeType];
42
+ mimeType = payload[0];
43
+ payload = payload[1];
44
+ }
45
+
46
+
47
+ if (url && url.length < 2048) { // if no filename and no mime, assume a url was passed as the only argument
48
+ fileName = url.split("/").pop().split("?")[0];
49
+ anchor.href = url; // assign href prop to temp anchor
50
+
51
+ if (anchor.href.indexOf(url) !== -1) { // if the browser determines that it's a potentially valid url path:
52
+ var ajax = new XMLHttpRequest();
53
+ ajax.open( "GET", url, true);
54
+ ajax.responseType = 'blob';
55
+ ajax.onload = function(e) {
56
+ download(e.target.response, fileName, defaultMime);
57
+ };
58
+ setTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return:
59
+
60
+ return ajax;
61
+ } // end if valid url?
62
+ } // end if url?
63
+
64
+
65
+ //go ahead and download dataURLs right away
66
+ if (/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)){
67
+
68
+ if (payload.length > (1024*1024*1.999) && myBlob !== toString ){
69
+ payload=dataUrlToBlob(payload);
70
+ mimeType=payload.type || defaultMime;
71
+ }else{
72
+ return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs:
73
+ navigator.msSaveBlob(dataUrlToBlob(payload), fileName) :
74
+ saver(payload) ; // everyone else can save dataURLs un-processed
75
+ }
76
+
77
+ }//end if dataURL passed?
78
+
79
+ blob = payload instanceof myBlob ? payload : new myBlob([payload], {type: mimeType}) ;
80
+
81
+ function dataUrlToBlob(strUrl) {
82
+ var parts = strUrl.split(/[:;,]/),
83
+ type = parts[1],
84
+ decoder = parts[2] == "base64" ? atob : decodeURIComponent,
85
+ binData = decoder(parts.pop()),
86
+ mx = binData.length,
87
+ i = 0,
88
+ uiArr = new Uint8Array(mx);
89
+
90
+ for (i; i < mx; ++i) {
91
+ uiArr[i]= binData.charCodeAt(i);
92
+ }
93
+
94
+ return new myBlob([uiArr], {type: type});
95
+ }
96
+
97
+ function saver(url, winMode){
98
+
99
+ if ('download' in anchor) { //html5 A[download]
100
+ anchor.href = url;
101
+ anchor.setAttribute("download", fileName);
102
+ anchor.className = "download-js-link";
103
+ anchor.innerHTML = "downloading...";
104
+ anchor.style.display = "none";
105
+ document.body.appendChild(anchor);
106
+ setTimeout(function() {
107
+ anchor.click();
108
+ document.body.removeChild(anchor);
109
+ if (winMode === true) {
110
+ setTimeout(function(){ self.URL.revokeObjectURL(anchor.href);}, 250 );
111
+ }
112
+ }, 66);
113
+ return true;
114
+ }
115
+
116
+ // handle non-a[download] safari as best we can:
117
+ if (/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
118
+ url=url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
119
+
120
+ if (!window.open(url)) { // popup blocked, offer direct download:
121
+ if (confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")) {
122
+ location.href=url;
123
+ }
124
+ }
125
+
126
+ return true;
127
+ }
128
+
129
+ //do iframe dataURL download (old ch+FF):
130
+ var f = document.createElement("iframe");
131
+ document.body.appendChild(f);
132
+
133
+ if (!winMode) { // force a mime that will download:
134
+ url="data:"+url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
135
+ }
136
+ f.src=url;
137
+ setTimeout(function () {
138
+ document.body.removeChild(f);
139
+ }, 333);
140
+
141
+ }//end saver
142
+
143
+ if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
144
+ return navigator.msSaveBlob(blob, fileName);
145
+ }
146
+
147
+ if (self.URL) { // simple fast and modern way using Blob and URL:
148
+ saver(self.URL.createObjectURL(blob), true);
149
+ } else {
150
+ // handle non-Blob()+non-URL browsers:
151
+ if (typeof blob === "string" || blob.constructor===toString) {
152
+ try {
153
+ return saver("data:" + mimeType + ";base64," + self.btoa(blob));
154
+ } catch (y) {
155
+ return saver("data:" + mimeType + "," + encodeURIComponent(blob));
156
+ }
157
+ }
158
+
159
+ // Blob but not URL support:
160
+ reader = new FileReader();
161
+ reader.onload = function(e) {
162
+ saver(this.result);
163
+ };
164
+ reader.readAsDataURL(blob);
165
+ }
166
+ return true;
167
+ };
168
+ }));
assets/js/dropdowns.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ $(document).ready(function () {
3
+ $(document).off('click', '.c-dropdown__trigger')
4
+ .on('click', '.c-dropdown__trigger', function (e) {
5
+ e.stopPropagation();
6
+ $(this).parent().toggleClass('is-open');
7
+ });
8
+
9
+ $(document).off('click', '.c-dropdown__content')
10
+ .on('click', '.c-dropdown__content', function (e) {
11
+ e.stopPropagation();
12
+ });
13
+
14
+ $(document).off('click', 'body')
15
+ .on('click', 'body', function () {
16
+ $('.c-dropdown').removeClass('is-open');
17
+ });
18
+ });
19
+ })(jQuery);
assets/js/expand-collapse.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ function switchExpandableContent(trigger) {
3
+ var expandableContainer = trigger.closest($('.c-expandable-item'));
4
+ var expandableWrapper = $(expandableContainer).find('.c-expandable-item__wrapper');
5
+ var expandableContent = $(expandableContainer).find('.c-expandable-item__content');
6
+
7
+ if (expandableContainer.hasClass('is-expanded')) {
8
+ expandableContainer.removeClass('is-expanded');
9
+ expandableWrapper.height(0);
10
+ } else {
11
+ expandableContainer.addClass('is-expanded');
12
+ expandableWrapper.height(expandableContent.outerHeight(true));
13
+ }
14
+ }
15
+
16
+ $(document).ready(function () {
17
+ $(document).off('click', '.js-expand-trigger')
18
+ .on('click', '.js-expand-trigger', function (e) {
19
+ e.preventDefault();
20
+ switchExpandableContent($(this));
21
+ });
22
+ });
23
+ })(jQuery);
assets/js/input.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ $(document).ready(function () {
3
+ $(document).off('blur','.c-form-text-item__field')
4
+ .on('blur', '.c-form-text-item__field', function () {
5
+
6
+ if ($(this).val()) {
7
+ $(this).addClass('is-not-empty');
8
+ } else {
9
+ $(this).removeClass('is-not-empty');
10
+ }
11
+ });
12
+ });
13
+ })(jQuery);
assets/js/jq.hoverintent.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * hoverIntent r6 // 2011.02.26 // jQuery 1.5.1+
3
+ * <http://cherne.net/brian/resources/jquery.hoverIntent.html>
4
+ *
5
+ * @param f onMouseOver function || An object with configuration options
6
+ * @param g onMouseOut function || Nothing (use configuration options object)
7
+ * @author Brian Cherne brian(at)cherne(dot)net
8
+ */
9
+ (function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if(e.type=="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.bind('mouseenter',handleHover).bind('mouseleave',handleHover)}})(jQuery);
assets/js/jquery.tmpl.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery Templates Plugin 1.0.0pre
3
+ * http://github.com/jquery/jquery-tmpl
4
+ * Requires jQuery 1.4.2
5
+ *
6
+ * Copyright 2011, Software Freedom Conservancy, Inc.
7
+ * Dual licensed under the MIT or GPL Version 2 licenses.
8
+ * http://jquery.org/license
9
+ */
10
+ (function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if(h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if(d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if(f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=k(c).concat(b);if(d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if(!j)throw"Unknown template tag: "+k;i=j._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for(e=0,p=o.length;e<p;e++){if((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for(h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if(m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if(p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if(e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);
assets/js/knockout-no-conflict.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ko */
2
+ var instapageKO = ko;
3
+
4
+ instapageKO.observable.fn.setBusy = function setBusy(value) {
5
+ this.busy = value;
6
+ }
7
+ instapageKO.observable.fn.isBusy = function isBusy() {
8
+ return (typeof this.busy === 'undefined') ? false : this.busy;
9
+ }
10
+
11
+ window.instapageKO = instapageKO;
assets/js/mrwhite.js ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * hoverIntent r6 // 2011.02.26 // jQuery 1.5.1+
3
+ * <http://cherne.net/brian/resources/jquery.hoverIntent.html>
4
+ *
5
+ * @param f onMouseOver function || An object with configuration options
6
+ * @param g onMouseOut function || Nothing (use configuration options object)
7
+ * @author Brian Cherne brian(at)cherne(dot)net
8
+ */
9
+ (function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if ((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=jQuery.extend({},e);var ob=this;if (ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if (e.type=="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if (ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).unbind("mousemove",track);if (ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.bind('mouseenter',handleHover).bind('mouseleave',handleHover)}})(jQuery);
10
+
11
+ /*
12
+ * jQuery Templates Plugin 1.0.0pre
13
+ * http://github.com/jquery/jquery-tmpl
14
+ * Requires jQuery 1.4.2
15
+ *
16
+ * Copyright 2011, Software Freedom Conservancy, Inc.
17
+ * Dual licensed under the MIT or GPL Version 2 licenses.
18
+ * http://jquery.org/license
19
+ */
20
+ (function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if (h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if (j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for (h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if (d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if (f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if (k){c=p;d=a.template[d]||a.template(null,d);f={}}else if (!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if (!d)return[];if (typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if (b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if (b){if (typeof b==="string")b=o(b);else if (b instanceof a)b=b[0]||{};if (b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if ($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if ($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if (($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if (($notnull_1) && $1a){"},html:{open:"if ($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if ($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if (g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if (c)b=k(c).concat(b);if (d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if (!j)throw"Unknown template tag: "+k;i=j._default||[];if (c&&!/\w$/.test(b)){b+=c;c=""}if (b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for (e=0,p=o.length;e<p;e++){if ((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for (h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if (m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if (p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if (!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if (c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if (e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if (!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);
21
+
22
+
23
+ (function($) {
24
+ $.fn.ipTooltips = function(opts) {
25
+ var tip_trigger = $(this);
26
+ var config = $.extend({}, {
27
+ inner: tip_trigger.data('inner') || 'Dear developer, please set the proper tooltip text.',
28
+ placement : tip_trigger.data('placement') || 'bottom',
29
+ width: tip_trigger.data('width'),
30
+ height: tip_trigger.data('height'),
31
+ css_class: tip_trigger.data('class'),
32
+ tip_size_param: tip_trigger.data('offset') || 10,
33
+ ellipsis_mode: tip_trigger.data('ellipsis') || false
34
+ }, opts);
35
+
36
+ var tip_position = {};
37
+ var tool_tip;
38
+
39
+ tip_trigger.hoverIntent({
40
+ over: init,
41
+ out: destroy
42
+ });
43
+
44
+ function init() {
45
+ if (tip_trigger[0].dataset.inner !== config.inner) {
46
+ config.inner = tip_trigger[0].dataset.inner;
47
+ alert(config.inner)
48
+ }
49
+
50
+ if (tip_trigger[0].dataset.class !== config.css_class) {
51
+ config.css_class = tip_trigger[0].dataset.class;
52
+ alert(config.inner)
53
+ }
54
+
55
+ tool_tip = $('#tooltip').tmpl({
56
+ inner: config.inner,
57
+ placement: config.placement.split('-')[0],
58
+ cssClass: config.css_class
59
+ });
60
+
61
+ if (config.ellipsis_mode === false || hasEllipsisActivated()) {
62
+ $('body').append(tool_tip);
63
+ tip_position = getTipPosition();
64
+ show();
65
+ }
66
+ }
67
+
68
+ function getTipPosition() {
69
+ var tip_trigger_width = tip_trigger.outerWidth();
70
+ var tip_trigger_height = tip_trigger.outerHeight();
71
+ var tip_offset = tip_trigger.offset();
72
+ var tip_size_param = config.tip_size_param;
73
+ var tip_width;
74
+ var tip_height;
75
+
76
+ tip_width = config.width || Math.ceil(tool_tip[0].getBoundingClientRect().width);
77
+ tool_tip.css({
78
+ width: tip_width
79
+ });
80
+
81
+ tip_height = config.height || Math.ceil(tool_tip[0].getBoundingClientRect().height);
82
+ tool_tip.css({
83
+ height: tip_height
84
+ });
85
+
86
+ return {
87
+ 'top': {
88
+ left: parseInt((tip_offset.left + tip_trigger_width / 2 - tip_width / 2 ), 10),
89
+ top: parseInt((tip_offset.top - tip_height - tip_size_param), 10 )
90
+ },
91
+ 'top-left': {
92
+ left: parseInt((tip_offset.left) + parseInt(tip_trigger.css('border-left-width') ), 10),
93
+ top: parseInt((tip_offset.top - tip_height - tip_size_param), 10 )
94
+ },
95
+ 'bottom': {
96
+ left: parseInt((tip_offset.left + tip_trigger_width / 2 - tip_width / 2 ), 10),
97
+ top: parseInt((tip_offset.top + tip_trigger_height + tip_size_param), 10 )
98
+ },
99
+ 'bottom-left': {
100
+ left: parseInt((tip_offset.left) + parseInt(tip_trigger.css('border-left-width') ), 10),
101
+ top: parseInt((tip_offset.top + tip_trigger_height + tip_size_param), 10 )
102
+ },
103
+ 'left': {
104
+ left: parseInt((tip_offset.left - tip_size_param - tip_width ), 10),
105
+ top: parseInt((tip_offset.top + tip_trigger_height / 2 - tip_height / 2), 10 )
106
+ },
107
+ 'right': {
108
+ left: parseInt((tip_offset.left + tip_size_param + tip_trigger_width ), 10),
109
+ top: parseInt((tip_offset.top + tip_trigger_height / 2 - tip_height / 2), 10 )
110
+ }
111
+ };
112
+ }
113
+
114
+ function show() {
115
+ tool_tip
116
+ .css({
117
+ left: tip_position[config.placement].left,
118
+ top: tip_position[config.placement].top
119
+ })
120
+ .addClass('c-tooltip--show');
121
+ }
122
+
123
+ function destroy() {
124
+ tip_position = {};
125
+
126
+ tool_tip.removeClass('c-tooltip--show').addClass('c-tooltip--hide');
127
+
128
+ setTimeout(function() {
129
+ tool_tip.remove();
130
+ }, 210);
131
+ }
132
+
133
+ tip_trigger.data('ipTooltips-initialized', true);
134
+
135
+ return this;
136
+ };
137
+
138
+ $(function() {
139
+ $(document).on('mouseenter', '[data-toggle="tooltip"]', function() {
140
+ if (!$(this).data('ipTooltips-initialized')) {
141
+ $(this).ipTooltips();
142
+ $(this).trigger('mouseenter');
143
+ }
144
+ });
145
+
146
+ document.addEventListener('click', function(e) {
147
+ if ($(e.target).data('toggle') === 'tooltip') {
148
+ return false;
149
+ }
150
+
151
+ Array.prototype.forEach.call(document.querySelectorAll('.c-tooltip'), function(element) {
152
+ var node = false;
153
+ var found = false;
154
+
155
+ for (node = e.target; !found && node; node = node.parentNode) {
156
+ if (node === element) {
157
+ found = true;
158
+ }
159
+ }
160
+
161
+ if (!found) {
162
+ $(element).remove();
163
+ }
164
+ });
165
+ }, false);
166
+ });
167
+
168
+ })(jQuery);
169
+
170
+ (function($) {
171
+ // This script is based on this pen other http://codepen.io/zavoloklom/pen/Gubja
172
+ $(document).ready(function() {
173
+ $(".fx-ripple-effect").off('click').on('click', function(e) {
174
+ var rippler = $(this);
175
+
176
+ // create .ink element if it doesn't exist
177
+ if (rippler.find(".fx-ink").length == 0) {
178
+ rippler.append("<span class='fx-ink'></span>");
179
+ }
180
+
181
+ var ink = rippler.find(".fx-ink");
182
+
183
+ // prevent quick double clicks
184
+ ink.removeClass("fx-animate");
185
+
186
+ // set .ink diametr
187
+ if (!ink.height() && !ink.width()) {
188
+ var d = Math.max(rippler.outerWidth(), rippler.outerHeight());
189
+ ink.css({
190
+ height: d,
191
+ width: d
192
+ });
193
+ }
194
+
195
+ // get click coordinates
196
+ var x = e.pageX - rippler.offset().left - ink.width() / 2;
197
+ var y = e.pageY - rippler.offset().top - ink.height() / 2;
198
+
199
+ // set .ink position and add class .animate
200
+ ink.css({
201
+ top: y + 'px',
202
+ left: x + 'px'
203
+ }).addClass("fx-animate");
204
+ });
205
+
206
+ });
207
+
208
+ /*------------------------------------*\
209
+ EXPAND - COLLAPSE
210
+ \*------------------------------------*/
211
+
212
+ function switchExpandableContent(trigger) {
213
+ var expandableContainer = trigger.closest($('.c-expandable-item'));
214
+ var expandableWrapper = $(expandableContainer).find('.c-expandable-item__wrapper');
215
+ var expandableContent = $(expandableContainer).find('.c-expandable-item__content');
216
+
217
+ if (expandableContainer.hasClass('is-expanded')) {
218
+ expandableContainer.removeClass('is-expanded');
219
+ expandableWrapper.height(0);
220
+ } else {
221
+ expandableContainer.addClass('is-expanded');
222
+ expandableWrapper.height(expandableContent.outerHeight(true));
223
+ }
224
+ }
225
+
226
+ // document.ready
227
+ $(document).ready(function() {
228
+ $('.js-expand-trigger').on('click',function(e) {
229
+ e.preventDefault();
230
+ switchExpandableContent($(this));
231
+ });
232
+ });
233
+
234
+ /*------------------------------------*\
235
+ TABS
236
+ \*------------------------------------*/
237
+
238
+ // activate tabs
239
+ function initTabs() {
240
+ $.each($('.c-tabs'), function(index, item) {
241
+ setTabSliderPosition(item);
242
+ });
243
+ }
244
+
245
+ // set tab slider position
246
+ function setTabSliderPosition(tabsContainer) {
247
+ var activeTab = $(tabsContainer).find('.c-tab.is-active');
248
+ $(tabsContainer).find('.c-tabs__slider').css({
249
+ left: activeTab.position().left,
250
+ width: activeTab.outerWidth()
251
+ });
252
+ }
253
+
254
+ // switch active tab
255
+ function switchActiveTab(newActiveTab) {
256
+ var tabsContainer = newActiveTab.closest($('.c-tabs'));
257
+ $(tabsContainer).find('.c-tab.is-active').removeClass('is-active');
258
+ newActiveTab.addClass('is-active');
259
+ setTabSliderPosition(tabsContainer);
260
+ }
261
+
262
+ // document.ready
263
+ $(document).ready(function() {
264
+ initTabs();
265
+ $('.c-tab').on('click', function(e) {
266
+ e.preventDefault();
267
+ var activeTab = switchActiveTab($(this));
268
+ });
269
+ });
270
+
271
+
272
+ /*------------------------------------*\
273
+ INPUT
274
+ \*------------------------------------*/
275
+ $(document).ready(function() {
276
+ $('.c-form-text-item__field').blur(function() {
277
+ if ($(this).val()) {
278
+ $(this).addClass('is-not-empty');
279
+ } else {
280
+ $(this).removeClass('is-not-empty');
281
+ }
282
+ });
283
+ });
284
+
285
+
286
+ /*------------------------------------*\
287
+ SNACK BARS
288
+ \*------------------------------------*/
289
+ $(document).ready(function() {
290
+ $('.snack-bar-trigger').on('click', function() {
291
+ $('.c-snack-bar').removeClass('is-animated');
292
+ var status = $(this).data('status');
293
+ $('.c-snack-bar[data-status="'+status+'"]').addClass('is-animated');
294
+ setTimeout(function() {
295
+ $('.c-snack-bar[data-status="'+status+'"]').removeClass('is-animated');
296
+ }, 3000);
297
+ });
298
+ });
299
+
300
+ /*------------------------------------*\
301
+ DROPDOWNS
302
+ \*------------------------------------*/
303
+ $(document).ready(function() {
304
+ $('.c-dropdown__trigger').on('click',function(e) {
305
+ e.stopPropagation();
306
+ $(this).parent().toggleClass('is-open');
307
+ });
308
+
309
+ $('.c-dropdown__content').on('click',function(e) {
310
+ e.stopPropagation();
311
+ });
312
+
313
+ $('body').click(function() {
314
+ $('.c-dropdown').removeClass('is-open');
315
+ });
316
+ });
317
+ })(jQuery);
assets/js/ripple.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ $(document).ready(function() {
3
+ $(document).off('click', '.fx-ripple-effect')
4
+ .on('click', '.fx-ripple-effect', function(e) {
5
+ var rippler = $(this);
6
+
7
+ // create .ink element if it doesn't exist
8
+ if (rippler.find(".fx-ink").length == 0) {
9
+ rippler.append("<span class='fx-ink'></span>");
10
+ }
11
+
12
+ var ink = rippler.find(".fx-ink");
13
+
14
+ // prevent quick double clicks
15
+ ink.removeClass("fx-animate");
16
+
17
+ // set .ink diametr
18
+ if (!ink.height() && !ink.width()) {
19
+ var d = Math.max(rippler.outerWidth(), rippler.outerHeight());
20
+ ink.css({
21
+ height: d,
22
+ width: d
23
+ });
24
+ }
25
+
26
+ // get click coordinates
27
+ var x = e.pageX - rippler.offset().left - ink.width() / 2;
28
+ var y = e.pageY - rippler.offset().top - ink.height() / 2;
29
+
30
+ // set .ink position and add class .animate
31
+ ink.css({
32
+ top: y + 'px',
33
+ left: x + 'px'
34
+ }).addClass("fx-animate");
35
+ });
36
+ });
37
+ })(jQuery);
assets/js/select2.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.slice(0,n.length-1).concat(a),k=0;k<a.length;k+=1)if(m=a[k],"."===m)a.splice(k,1),k-=1;else if(".."===m){if(1===k&&(".."===a[2]||".."===a[0]))break;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=v.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),n.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n<c.length;n+=1)if(m=o(c[n],f),k=m.f,"require"===k)u[n]=p.require(a);else if("exports"===k)u[n]=p.exports(a),s=!0;else if("module"===k)h=u[n]=p.module(a);else if(e(q,k)||e(r,k)||e(t,k))u[n]=j(k);else{if(!m.p)throw new Error(a+" missing "+k);m.p.load(m.n,g(f,!0),i(k),{}),u[n]=q[k]}l=d?d.apply(q[a],u):void 0,a&&(h&&h.exports!==b&&h.exports!==q[a]?q[a]=h.exports:l===b&&s||(q[a]=l))}else a&&(q[a]=d)},a=c=n=function(a,c,d,e,f){if("string"==typeof a)return p[a]?p[a](c):j(o(a,c).f);if(!a.splice){if(s=a,s.deps&&n(s.deps,s.callback),!c)return;c.splice?(a=c,c=d,d=null):a=b}return c=c||function(){},"function"==typeof d&&(d=e,e=f),e?m(b,a,c,d):setTimeout(function(){m(b,a,c,d)},4),n},n.config=function(a){return n(a)},a._defined=q,d=function(a,b,c){if("string"!=typeof a)throw new Error("See almond README: incorrect module build, no module name");b.splice||(c=b,b=[]),e(q,a)||e(r,a)||(r[a]=[a,b,c])},d.amd={jQuery:!0}}(),b.requirejs=a,b.require=c,b.define=d}}(),b.define("almond",function(){}),b.define("jquery",[],function(){var b=a||$;return null==b&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),b}),b.define("select2/utils",["jquery"],function(a){function b(a){var b=a.prototype,c=[];for(var d in b){var e=b[d];"function"==typeof e&&"constructor"!==d&&c.push(d)}return c}var c={};c.Extend=function(a,b){function c(){this.constructor=a}var d={}.hasOwnProperty;for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},c.Decorate=function(a,c){function d(){var b=Array.prototype.unshift,d=c.prototype.constructor.length,e=a.prototype.constructor;d>0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h<g.length;h++){var i=g[h];d.prototype[i]=a.prototype[i]}for(var j=(function(a){var b=function(){};a in d.prototype&&(b=d.prototype[a]);var e=c.prototype[a];return function(){var a=Array.prototype.unshift;return a.call(arguments,b),e.apply(this,arguments)}}),k=0;k<f.length;k++){var l=f[k];d.prototype[l]=j(l)}return d};var d=function(){this.listeners={}};return d.prototype.on=function(a,b){this.listeners=this.listeners||{},a in this.listeners?this.listeners[a].push(b):this.listeners[a]=[b]},d.prototype.trigger=function(a){var b=Array.prototype.slice,c=b.call(arguments,1);this.listeners=this.listeners||{},null==c&&(c=[]),0===c.length&&c.push({}),c[0]._type=a,a in this.listeners&&this.invoke(this.listeners[a],b.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},d.prototype.invoke=function(a,b){for(var c=0,d=a.length;d>c;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e<c.length;e++){var f=c[e];f=f.substring(0,1).toLowerCase()+f.substring(1),f in d||(d[f]={}),e==c.length-1&&(d[f]=a[b]),d=d[f]}delete a[b]}}return a},c.hasScroll=function(b,c){var d=a(c),e=c.style.overflowX,f=c.style.overflowY;return e!==f||"hidden"!==f&&"visible"!==f?"scroll"===e||"scroll"===f?!0:d.innerHeight()<c.scrollHeight||d.innerWidth()<c.scrollWidth:!1},c.escapeMarkup=function(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<ul class="select2-results__options" role="tree"></ul>');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('<li role="treeitem" aria-live="assertive" class="select2-results__option"></li>'),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c<a.results.length;c++){var d=a.results[c],e=this.option(d);b.push(e)}this.$results.append(b)},c.prototype.position=function(a,b){var c=b.find(".select2-results");c.append(a)},c.prototype.sort=function(a){var b=this.options.get("sorter");return b(a)},c.prototype.highlightFirstItem=function(){var a=this.$results.find(".select2-results__option[aria-selected]"),b=a.filter("[aria-selected=true]");b.length>0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j<b.children.length;j++){var k=b.children[j],l=this.option(k);i.push(l)}var m=a("<ul></ul>",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):0>h-g&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var c=a(this),e=c.data("data");return"true"===c.attr("aria-selected")?void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{})):void d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('<span class="select2-selection" role="combobox" aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},e.prototype.selectionContainer=function(){return a("<span></span>")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('<ul class="select2-selection__rendered"></ul>'),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},d.prototype.selectionContainer=function(){var b=a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d<a.length;d++){var e=a[d],f=this.selectionContainer(),g=this.display(e,f);f.append(g),f.prop("title",e.title||e.text),f.data("data",e),b.push(f)}var h=this.$selection.find(".select2-selection__rendered");c.appendMany(h,b)}},d}),b.define("select2/selection/placeholder",["../utils"],function(a){function b(a,b,c){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c)}return b.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},b.prototype.createPlaceholder=function(a,b){var c=this.selectionContainer();return c.html(this.display(b)),c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),c},b.prototype.update=function(a,b){var c=1==b.length&&b[0].id!=this.placeholder.id,d=b.length>1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e<d.length;e++){var f={data:d[e]};if(this.trigger("unselect",f),f.prevented)return}this.$element.val(this.placeholder.id).trigger("change"),this.trigger("toggle",{})}}},c.prototype._handleKeyboardClear=function(a,c,d){d.isOpen()||(c.which==b.DELETE||c.which==b.BACKSPACE)&&this._handleClear(c)},c.prototype.update=function(b,c){if(b.call(this,c),!(this.$selection.find(".select2-selection__placeholder").length>0||0===c.length)){var d=a('<span class="select2-selection__clear">&times;</span>');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" aria-autocomplete="list" /></li>');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}});var f=document.documentMode,g=f&&11>=f;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){return g?void e.$selection.off("input.search input.searchcheck"):void e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");
2
+ if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f<a.length;f++){var g=a[f].id;-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")});else{var d=a.id;this.$element.val(d),this.$element.trigger("change")}},d.prototype.unselect=function(a){var b=this;if(this.$element.prop("multiple"))return a.selected=!1,c(a.element).is("option")?(a.element.selected=!1,void this.$element.trigger("change")):void this.current(function(d){for(var e=[],f=0;f<d.length;f++){var g=d[f].id;g!==a.id&&-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")})},d.prototype.bind=function(a,b){var c=this;this.container=a,a.on("select",function(a){c.select(a.data)}),a.on("unselect",function(a){c.unselect(a.data)})},d.prototype.destroy=function(){this.$element.find("*").each(function(){c.removeData(this,"data")})},d.prototype.query=function(a,b){var d=[],e=this,f=this.$element.children();f.each(function(){var b=c(this);if(b.is("option")||b.is("optgroup")){var f=e.item(b),g=e.matches(a,f);null!==g&&d.push(g)}}),b({results:d})},d.prototype.addOptions=function(a){b.appendMany(this.$element,a)},d.prototype.option=function(a){var b;a.children?(b=document.createElement("optgroup"),b.label=a.text):(b=document.createElement("option"),void 0!==b.textContent?b.textContent=a.text:b.innerText=a.text),a.id&&(b.value=a.id),a.disabled&&(b.disabled=!0),a.selected&&(b.selected=!0),a.title&&(b.title=a.title);var d=c(b),e=this._normalizeItem(a);return e.element=b,c.data(b,"data",e),d},d.prototype.item=function(a){var b={};if(b=c.data(a[0],"data"),null!=b)return b;if(a.is("option"))b={id:a.val(),text:a.text(),disabled:a.prop("disabled"),selected:a.prop("selected"),title:a.prop("title")};else if(a.is("optgroup")){b={text:a.prop("label"),children:[],title:a.prop("title")};for(var d=a.children("option"),e=[],f=0;f<d.length;f++){var g=c(d[f]),h=this.item(g);e.push(h)}b.children=e}return b=this._normalizeItem(b),b.element=a[0],c.data(a[0],"data",b),b},d.prototype._normalizeItem=function(a){c.isPlainObject(a)||(a={id:a,text:a}),a=c.extend({},{text:""},a);var b={selected:!1,disabled:!1};return null!=a.id&&(a.id=a.id.toString()),null!=a.text&&(a.text=a.text.toString()),null==a._resultId&&a.id&&null!=this.container&&(a._resultId=this.generateResultId(this.container,a)),c.extend({},b,a)},d.prototype.matches=function(a,b){var c=this.options.get("matcher");return c(a,b)},d}),b.define("select2/data/array",["./select","../utils","jquery"],function(a,b,c){function d(a,b){var c=b.get("data")||[];d.__super__.constructor.call(this,a,b),this.addOptions(this.convertToOptions(c))}return b.Extend(d,a),d.prototype.select=function(a){var b=this.$element.find("option").filter(function(b,c){return c.value==a.id.toString()});0===b.length&&(b=this.option(a),this.addOptions(b)),d.__super__.select.call(this,a)},d.prototype.convertToOptions=function(a){function d(a){return function(){return c(this).val()==a.id}}for(var e=this,f=this.$element.find("option"),g=f.map(function(){return e.item(c(this)).id}).get(),h=[],i=0;i<a.length;i++){var j=this._normalizeItem(a[i]);if(c.inArray(j.id,g)>=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h<e.length;h++){var i=e[h],j=this._normalizeItem(i),k=this.option(j);this.$element.append(k)}}return b.prototype.query=function(a,b,c){function d(a,f){for(var g=a.results,h=0;h<g.length;h++){var i=g[h],j=null!=i.children&&!d({results:i.children},!0),k=i.text===b.term;if(k||j)return f?!1:(a.data=g,void c(a))}if(f)return!0;var l=e.createTag(b);if(null!=l){var m=e.option(l);m.attr("data-select2-tag",!0),e.addOptions([m]),e.insertTag(g,l)}a.results=g,c(a)}var e=this;return this._removeOldTags(),null==b.term||null!=b.page?void a.call(this,b,c):void a.call(this,b,d)},b.prototype.createTag=function(b,c){var d=a.trim(c.term);return""===d?null:{id:d,text:d}},b.prototype.insertTag=function(a,b,c){b.unshift(c)},b.prototype._removeOldTags=function(b){var c=(this._lastTag,this.$element.find("option[data-select2-tag]"));c.each(function(){this.selected||a(this).remove()})},b}),b.define("select2/data/tokenizer",["jquery"],function(a){function b(a,b,c){var d=c.get("tokenizer");void 0!==d&&(this.tokenizer=d),a.call(this,b,c)}return b.prototype.bind=function(a,b,c){a.call(this,b,c),this.$search=b.dropdown.$search||b.selection.$search||c.find(".select2-search__field")},b.prototype.query=function(b,c,d){function e(b){var c=g._normalizeItem(b),d=g.$element.find("option").filter(function(){return a(this).val()===c.id});if(!d.length){var e=g.option(c);e.attr("data-select2-tag",!0),g._removeOldTags(),g.addOptions([e])}f(c)}function f(a){g.trigger("select",{data:a})}var g=this;c.term=c.term||"";var h=this.tokenizer(c,this.options,e);h.term!==c.term&&(this.$search.length&&(this.$search.val(h.term),this.$search.focus()),c.term=h.term),b.call(this,c,d)},b.prototype.tokenizer=function(b,c,d,e){for(var f=d.get("tokenSeparators")||[],g=c.term,h=0,i=this.createTag||function(a){return{id:a.term,text:a.term}};h<g.length;){var j=g[h];if(-1!==a.inArray(j,f)){var k=g.substr(0,h),l=a.extend({},c,{term:k}),m=i(l);null!=m?(e(m),g=g.substr(h+1)||"",h=0):h++}else h++}return{term:g}},b}),b.define("select2/data/minimumInputLength",[],function(){function a(a,b,c){this.minimumInputLength=c.get("minimumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",b.term.length<this.minimumInputLength?void this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumInputLength",[],function(){function a(a,b,c){this.maximumInputLength=c.get("maximumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",this.maximumInputLength>0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<span class="select2-dropdown"><span class="select2-results"></span></span>');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></span>');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('<li class="select2-results__option select2-results__option--load-more"role="treeitem" aria-disabled="true"></li>'),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a("<span></span>"),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id,h=this.$container.parents().filter(b.hasScroll);h.off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.top<f.top-h.height,k=i.bottom>f.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d<b.length;d++){var e=b[d];e.children?c+=a(e.children):c++}return c}function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return a(c.data.results)<this.minimumResultsForSearch?!1:b.call(this,c)},b}),b.define("select2/dropdown/selectOnClose",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("close",function(a){d._handleSelectOnClose(a)})},a.prototype._handleSelectOnClose=function(a,b){if(b&&null!=b.originalSelect2Event){var c=b.originalSelect2Event;if("select"===c._type||"unselect"===c._type)return}var d=this.getHighlightedResults();if(!(d.length<1)){var e=d.data("data");null!=e.element&&e.element.selected||null==e.element&&e.selected||this.trigger("select",{data:e})}},a}),b.define("select2/dropdown/closeOnSelect",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("select",function(a){d._selectTriggered(a)}),b.on("unselect",function(a){d._selectTriggered(a)})},a.prototype._selectTriggered=function(a,b){var c=b.originalEvent;c&&c.ctrlKey||this.trigger("close",{originalEvent:c,originalSelect2Event:b})},a}),b.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(a){var b=a.input.length-a.maximum,c="Please delete "+b+" character";return 1!=b&&(c+="s"),c},inputTooShort:function(a){var b=a.minimum-a.input.length,c="Please enter "+b+" or more characters";return c},loadingMore:function(){return"Loading more results…"},maximumSelected:function(a){var b="You can only select "+a.maximum+" item";return 1!=a.maximum&&(b+="s"),b},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),b.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C){function D(){this.reset()}D.prototype.apply=function(l){if(l=a.extend(!0,{},this.defaults,l),null==l.dataAdapter){if(null!=l.ajax?l.dataAdapter=o:null!=l.data?l.dataAdapter=n:l.dataAdapter=m,l.minimumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L<K.length;L++){var M=K[L],N={};try{N=k.loadPath(M)}catch(O){try{M=this.defaults.amdLanguageBase+M,N=k.loadPath(M)}catch(P){l.debug&&window.console&&console.warn&&console.warn('Select2: The language file for "'+M+'" could not be automatically loaded. A fallback will be used instead.');continue}}J.extend(N)}l.translations=J}else{var Q=k.loadPath(this.defaults.amdLanguageBase+"en"),R=new k(l.language);R.extend(Q),l.translations=R}return l},D.prototype.reset=function(){function b(a){function b(a){return l[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function c(d,e){if(""===a.trim(d.term))return e;if(e.children&&e.children.length>0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e<b.addedNodes.length;e++){var f=b.addedNodes[e];f.selected&&(c=!0)}else b.removedNodes&&b.removedNodes.length>0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null;
3
+ },e.prototype.render=function(){var b=a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
assets/js/snack-bars.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ $(document).ready(function() {
3
+ $(document).off('click', '.snack-bar-trigger')
4
+ .on('click', '.snack-bar-trigger', function () {
5
+ $('.c-snack-bar').removeClass('is-animated');
6
+ var status = $(this).data('status');
7
+ $('.c-snack-bar[data-status="' + status + '"]').addClass('is-animated');
8
+ setTimeout(function() {
9
+ $('.c-snack-bar[data-status="' + status + '"]').removeClass('is-animated');
10
+ }, 3000);
11
+ });
12
+ });
13
+ })(jQuery);
assets/js/tabs.js ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ // activate tabs
3
+ function initTabs(tabs) {
4
+ $.each(tabs, function (index, item) {
5
+ setTabSliderPosition(item);
6
+ });
7
+ }
8
+
9
+ // set tab slider position
10
+ function setTabSliderPosition(tabsContainer) {
11
+ var activeTab = $(tabsContainer).find('.c-tab.is-active');
12
+ $(tabsContainer).find('.c-tabs__slider').css({
13
+ left: activeTab.position().left,
14
+ width: activeTab.outerWidth()
15
+ });
16
+ }
17
+
18
+ // switch active tab
19
+ function switchActiveTab(newActiveTab) {
20
+ var tabsContainer = newActiveTab.closest($('.c-tabs'));
21
+ $(tabsContainer).find('.c-tab.is-active').removeClass('is-active');
22
+ newActiveTab.addClass('is-active');
23
+ setTabSliderPosition(tabsContainer);
24
+ }
25
+
26
+ function whitekitTabsInit() {
27
+ var tabs = $('.c-tabs');
28
+
29
+ if (tabs) {
30
+ initTabs(tabs);
31
+ $('.c-tab').on('click', function (e) {
32
+ e.preventDefault();
33
+ switchActiveTab($(this));
34
+ });
35
+ }
36
+ }
37
+
38
+ document.whitekitTabsInit = whitekitTabsInit;
39
+
40
+ // document.ready
41
+ $(document).ready(function () {
42
+ whitekitTabsInit();
43
+ });
44
+ })(jQuery);
assets/js/ui-kit-scripts.js ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ $(document).ready(function() {
3
+ // uikit menu
4
+ var titles = $('main > .ui-section .ui-title');
5
+ var uiMenu = $('#ui-menu');
6
+ var uiMenuContent = '';
7
+ var title;
8
+ var toggle_menu = $('#show-menu');
9
+
10
+ titles.each(function(i, e){
11
+ uiMenuContent += '<li data-id="'+i+'">' + (i+1) + '. ' + $(e).text() + '</li>';
12
+ });
13
+
14
+ uiMenu.append(uiMenuContent);
15
+
16
+ title = uiMenu.find('li');
17
+
18
+ title.on('click', function(){
19
+ var thiz = $(this);
20
+ var thizSection = thiz.data('id');
21
+
22
+ title.removeClass('is-active');
23
+ thiz.addClass('is-active');
24
+
25
+ $('html, body').animate({scrollTop: $('#sections > li').eq(thizSection).offset().top});
26
+ });
27
+
28
+ $('.ui-toggle-menu').on('click', function(){
29
+ uiMenu.toggleClass('is-active');
30
+ title.removeClass('is-active');
31
+ });
32
+ });
33
+ })(jQuery);
assets/lang/en-GB.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var InstapageDictionary = {};
2
+ InstapageDictionary['ALL'] = 'All';
3
+ InstapageDictionary['LOGIN_OR_ADD_TOKEN_FIRST'] = 'No pages are available for publishing. You have to:<br />- log in or<br />- add a valid sub-account token in settings or<br />- publish some pages in Instapage app dashboard.';
4
+ InstapageDictionary['SLUG_CANNOT_BE_EMPTY'] = 'Slug cannot be empty.';
5
+ InstapageDictionary['SLUG_IS_USED_BY_CMS'] = 'Selected slug is invalid because there is a CMS item with the same slug. Change landing page slug or %s in CMS.';
6
+ InstapageDictionary['SLUG_IS_USED_BY_PLUGIN'] = 'Selected slug is invalid, it\'s used by another landing page.';
7
+ InstapageDictionary['HOMEPAGE_ALREADY_DEFINED'] = 'There is a landing page defined as a homepage. You cannot add another one.';
8
+ InstapageDictionary['404_ALREADY_DEFINED'] = 'There is a landing page defined as a 404 page. You cannot add another one.';
9
+ InstapageDictionary['USER_LOGGED_IN'] = 'You have been logged in.';
10
+ InstapageDictionary['USER_LOGGED_OUT'] = 'You have been logged out.';
11
+ InstapageDictionary['EMAIL_OR_PASSWORD_INCORRECT'] = 'E-mail address or password is incorrect.';
12
+ InstapageDictionary['ERROR_WHILE_CONNECTING_SUBACCOUNTS'] = 'There was an error, selected subaccounts are not properly connected to app. Try to connect subaccounts again.';
13
+ InstapageDictionary['ERROR_WHILE_DISCONNECTING_SUBACCOUNTS'] = 'There was an error, selected subaccounts are not properly disconnected from app. Try to disconnect subaccounts again.';
14
+ InstapageDictionary['NO_DEPRECATED_PAGES_MIGRATED'] = 'No pages migrated.';
15
+ InstapageDictionary['COULDNT_PARSE_RESPONSE'] = 'Couldn\'t parse response.';
16
+ InstapageDictionary['TOKEN_ALREADY_IN_USE'] = 'This token is already in use.';
17
+ InstapageDictionary['DIAGNOSTIC_IS_ON_WARNING'] = '<strong>Diagnostic mode is ON</strong>. Be sure to turn it off right after generating the diagnostic log. Diagnostic mode is very resource consuming and can increase your page loading time significantly!';
18
+
connectors/InstapageCmsPluginConnector.php ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Main connector class, used to integrate with PHP-based CMSes. It's job is to detect a CMS that executes the code and select proper CMS Connector.
5
+ */
6
+ class InstapageCmsPluginConnector {
7
+
8
+ /**
9
+ * @var object $selectedConnector Proper connector for current CMS.
10
+ */
11
+ private static $selectedConnector = null;
12
+
13
+ /**
14
+ * @var string $selectedLanguage Language of current CMS. Currently only english is supported.
15
+ */
16
+ private static $selectedLanguage = 'en-GB';
17
+
18
+ /**
19
+ * @var array $languageArray An array with proper dictionary.
20
+ */
21
+ private static $languageArray = null;
22
+
23
+ /**
24
+ * Gets selected language.
25
+ */
26
+ public static function getSelectedLanguage() {
27
+ return self::$selectedLanguage;
28
+ }
29
+
30
+ /**
31
+ * Checks if WordPress is a currently used CMS.
32
+ *
33
+ * @return boolean
34
+ */
35
+ public static function isWP() {
36
+
37
+ if (defined('ABSPATH') && defined('WPINC') && defined('WP_CONTENT_DIR')) {
38
+ return true;
39
+ }
40
+
41
+ return false;
42
+ }
43
+
44
+ /**
45
+ * Checks if Drupal 8 is a currently used CMS.
46
+ *
47
+ * @return boolean
48
+ */
49
+ public static function isDrupal8() {
50
+
51
+ if (class_exists('\Drupal\Core\DrupalKernel')) {
52
+ return true;
53
+ }
54
+
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * Checks if Drupal 7 is a currently used CMS.
60
+ *
61
+ * @return boolean
62
+ */
63
+ public static function isDrupal7() {
64
+
65
+ if (defined('VERSION') && VERSION > 7.0 && VERSION < 8.0) {
66
+ return true;
67
+ }
68
+
69
+ return false;
70
+ }
71
+
72
+ /**
73
+ * Selects a proper connector based on currently used CMS.
74
+ *
75
+ * @return object Selected connector.
76
+ */
77
+ public static function getSelectedConnector() {
78
+
79
+ if (self::$selectedConnector === null) {
80
+
81
+ switch (true) {
82
+ case self::isWP():
83
+ require_once(INSTAPAGE_PLUGIN_PATH . '/connectors/InstapageCmsPluginWPConnector.php');
84
+ self::$selectedConnector = new InstapageCmsPluginWPConnector();
85
+ break;
86
+
87
+ case self::isDrupal7():
88
+ require_once(INSTAPAGE_PLUGIN_PATH . '/connectors/InstapageCmsPluginDrupal7Connector.php');
89
+ self::$selectedConnector = new InstapageCmsPluginDrupal7Connector();
90
+ break;
91
+
92
+ case self::isDrupal8():
93
+ require_once(INSTAPAGE_PLUGIN_PATH . '/connectors/InstapageCmsPluginDrupal8Connector.php');
94
+ self::$selectedConnector = new InstapageCmsPluginDrupal8Connector();
95
+ break;
96
+
97
+ default:
98
+ die('Unsupported CMS');
99
+ }
100
+ }
101
+
102
+ return self::$selectedConnector;
103
+ }
104
+
105
+ /**
106
+ * Gets the plugin's directory name in current CMS.
107
+ *
108
+ * @return string Directory name.
109
+ */
110
+ public static function getPluginDirectoryName() {
111
+ return self::getSelectedConnector()->getPluginDirectoryName();
112
+ }
113
+
114
+ /**
115
+ * Gets the current user access rights to the Instapage plugin.
116
+ *
117
+ * @return bool Returns true if user can manage the Instapage plugin.
118
+ */
119
+ public static function currentUserCanManage() {
120
+ return self::getSelectedConnector()->currentUserCanManage();
121
+ }
122
+
123
+ /**
124
+ * Gets the value of language variable.
125
+ */
126
+ public static function lang() {
127
+ return self::getSelectedConnector()->lang(func_get_args());
128
+ }
129
+
130
+ /**
131
+ * Gets the sitemane.
132
+ *
133
+ * @param bool $sanitized If the name should be sanitized.
134
+ *
135
+ * @return string Sitename, sanitized or not.
136
+ */
137
+ public static function getSitename($sanitized = false) {
138
+ return self::getSelectedConnector()->getSitename($sanitized);
139
+ }
140
+
141
+ /**
142
+ * Gets the site base URL.
143
+ *
144
+ * @param bool $protocol Value returned with protocol or not.
145
+ *
146
+ * @return string Site base URL. With protocol or not.
147
+ */
148
+ public static function getSiteURL($protocol = true) {
149
+ return self::getSelectedConnector()->getSiteURL($protocol);
150
+ }
151
+
152
+ /**
153
+ * Gets the site home URL.
154
+ *
155
+ * @param bool $protocol Value returned with protocol or not.
156
+ *
157
+ * @return string Site home URL. With protocol or not.
158
+ */
159
+ public static function getHomeURL($protocol = true) {
160
+ return self::getSelectedConnector()->getHomeURL($protocol);
161
+ }
162
+
163
+ /**
164
+ * Gets the currently used CMS name.
165
+ *
166
+ * @return string CMS name.
167
+ */
168
+ public static function getCMSName() {
169
+ return self::getSelectedConnector()->getCMSName();
170
+ }
171
+
172
+ /**
173
+ * Gets the currently used CMS version.
174
+ * @uses self::getSelectedConnector()
175
+ * @return string CMS version.
176
+ */
177
+ public static function getCMSVersion() {
178
+ return self::getSelectedConnector()->getCMSVersion();
179
+ }
180
+
181
+ /**
182
+ * Gets the currently used MySQL version.
183
+ * @uses self::getSelectedConnector()
184
+ * @return string MySQL version.
185
+ */
186
+ public static function getMySQLVersion() {
187
+ $sql = 'SELECT VERSION() as version';
188
+ $result = self::getSelectedConnector()->getRow($sql);
189
+
190
+ return $result->version;
191
+ }
192
+
193
+ /**
194
+ * Checks if API is accessible
195
+ * @uses self::getSelectedConnector()
196
+ * @return bool
197
+ */
198
+ public static function isAPIAccessible() {
199
+ return self::getSelectedConnector()->isAPIAccessible();
200
+ }
201
+
202
+ /**
203
+ * Checks if SEO friendly urls are enabled
204
+ * @uses self::getSelectedConnector()
205
+ * @return bool
206
+ */
207
+ public static function areSEOFriendlyUrlsEnabled() {
208
+ return self::getSelectedConnector()->areSEOFriendlyUrlsEnabled();
209
+ }
210
+
211
+ /**
212
+ * Sends an e-mail using CMS native email sending method.
213
+ *
214
+ * @param string $to Receiver address.
215
+ * @param string $subject A subject.
216
+ * @param string $message A message.
217
+ * @param string $headers Message headers. Default: ''.
218
+ * @param aray $attachments Attachments.
219
+ *
220
+ * @return bool True on success.
221
+ */
222
+ public static function mail($to, $subject, $message, $headers = '', $attachments = array()) {
223
+ return self::getSelectedConnector()->mail($to, $subject, $message, $headers, $attachments);
224
+ }
225
+
226
+ /**
227
+ * Gets the AJAX URL for currently used CMS.
228
+ *
229
+ * @return string AJAX URL.
230
+ */
231
+ public static function getAjaxURL() {
232
+ return self::getSelectedConnector()->getAjaxURL();
233
+ }
234
+
235
+ /**
236
+ * Adds a declaration of JS to Instapage plugin's dashboard in admin panel.
237
+ *
238
+ * @param string $handle Name of the script.
239
+ * @param string $file Path to JS file.
240
+ * @param bool $inFooter Can the file be loaded in the footer?
241
+ */
242
+ public static function addAdminJS($handle, $file, $inFooter = false) {
243
+ return self::getSelectedConnector()->addAdminJSaddAdminJS($handle, $file, $inFooter);
244
+ }
245
+
246
+ /**
247
+ * Adds a declaration of CSS to Instapage plugin's dashboard in admin panel.
248
+ *
249
+ * @param string $handle Name of the script.
250
+ * @param string $file Path to CSS file.
251
+ */
252
+ public static function addAdminCSS($handle, $file) {
253
+ return self::getSelectedConnector()->addAdminCSS($handle, $file);
254
+ }
255
+
256
+ /**
257
+ * Properly escapes the HTML.
258
+ *
259
+ * @param string $html HTML to escape.
260
+ * @return string Escaped HTML.
261
+ */
262
+ public static function escapeHTML($html) {
263
+ return self::getSelectedConnector()->escapeHTML($html);
264
+ }
265
+
266
+ /**
267
+ * Checks (and displays) if a landing page should be displayed instead of normal content served by CMS.
268
+ *
269
+ * @param string $type Type of page to check ('page', 'home' or '404').
270
+ * @param string $slug Slug to check. Default: ''.
271
+ */
272
+ public static function checkPage($type, $slug = '') {
273
+ return self::getSelectedConnector()->checkPage($type, $slug);
274
+ }
275
+
276
+ /**
277
+ * Checks if there is a need to replace content of CMS with a landing page. Prevents content replacement on admin/login pages.
278
+ *
279
+ * @return bool True if replace is possible.
280
+ */
281
+ public static function isHtmlReplaceNecessary() {
282
+ return self::getSelectedConnector()->isHtmlReplaceNecessary();
283
+ }
284
+
285
+ /**
286
+ * Initiates Instapage plugin's DB structure and loads plugin's classes and selected connector.
287
+ */
288
+ public static function initPlugin() {
289
+ $db = InstapageCmsPluginDBModel::getInstance();
290
+ $db->initPluginTables();
291
+ self::getSelectedConnector()->initPlugin();
292
+ }
293
+
294
+ /**
295
+ * Removes the plugin.
296
+ */
297
+ public static function removePlugin() {
298
+ return self::getSelectedConnector()->removePlugin();
299
+ }
300
+
301
+ /**
302
+ * Gets the slugs of all landing pages stored in the plugin's DB.
303
+ * @deprecated
304
+ * @return array Stored slugs.
305
+ */
306
+ public static function getLandingPageSlugs() {
307
+ $db = InstapageCmsPluginDBModel::getInstance();
308
+ $sql = 'SELECT id, slug, \'\' AS editUrl FROM ' . $db->pagesTable . ' WHERE type = \'page\' AND slug <> \'\'';
309
+ $results = $db->getResults($sql);
310
+
311
+ return $results;
312
+ }
313
+
314
+ /**
315
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
316
+ * @param string $slug Slug to be checked
317
+ * @uses InstapageCmsPluginDBModel::$pagesTable
318
+ * @uses InstapageCmsPluginDBModel::getInstance()
319
+ * @uses InstapageCmsPluginDBModel::getResults()
320
+ * @return bool|array
321
+ */
322
+ public static function isProhibitedLandingPageSlug($slug) {
323
+ $db = InstapageCmsPluginDBModel::getInstance();
324
+ $sql = 'SELECT id, slug, \'\' AS editUrl FROM ' . $db->pagesTable . ' WHERE type = \'page\' AND slug = \'%s\' LIMIT 1';
325
+ $results = $db->getResults($sql, $slug);
326
+
327
+ return $results;
328
+ }
329
+
330
+ /**
331
+ * Executes an action requested via AJAX.
332
+ */
333
+ public static function ajaxCallback() {
334
+ ini_set('display_errors',0);
335
+ header('Content-Type: application/json');
336
+ $post = isset($_POST['data']) ? json_decode(urldecode($_POST['data'])) : array();
337
+ $post->data = isset($post->data) ? $post->data : null;
338
+
339
+ if (!empty($post->action)) {
340
+ InstapageCmsPluginAjaxController::getInstance()->doAction($post->action, $post->data);
341
+ }
342
+
343
+ die();
344
+ }
345
+
346
+ /**
347
+ * Gets the settings module, a CMS-dependant part of the Settings page.
348
+ *
349
+ * @return string HTML form with settings for currently used CMS only.
350
+ */
351
+ public static function getSettingsModule() {
352
+ return self::getSelectedConnector()->getSettingsModule();
353
+ }
354
+
355
+ /**
356
+ * Gets requirements section for settings module
357
+ * @param array $features
358
+ * @uses self::getMySQLVersion()
359
+ * @uses self::isAPIAccessible()
360
+ * @uses self::areSEOFriendlyUrlsEnabled()
361
+ * @uses self::lang()
362
+ * @uses InstapageCmsPluginHelper::getRawVersion()
363
+ * @uses InstapageCmsPluginHelper::isRegularMySQL()
364
+ * @uses InstapageCmsPluginHelper::isMariaDBMySQL()
365
+ * @return string HTML
366
+ */
367
+ public static function getPluginRequirements($features) {
368
+ $dbVersion = InstapageCmsPluginConnector::getMySQLVersion();
369
+ $commonFeatures = array(
370
+ array('label' => InstapageCmsPluginConnector::lang('PHP 5.5+'), 'condition' => version_compare(phpversion(), '5.5.0', '>=')),
371
+ array('label' => InstapageCmsPluginConnector::lang('MySQL 5.5.3+ / MariaDB 5.5+'), 'condition' => (
372
+ (InstapageCmsPluginHelper::isRegularMySQL($dbVersion) && version_compare(InstapageCmsPluginHelper::getRawVersion($dbVersion), '5.5.3', '>=')) ||
373
+ (InstapageCmsPluginHelper::isMariaDBMySQL($dbVersion) && version_compare(InstapageCmsPluginHelper::getRawVersion($dbVersion), '5.5.0', '>='))
374
+ )
375
+ ),
376
+ array('label' => InstapageCmsPluginConnector::lang('PHP Curl extension or another way to make remote requests'), 'condition' => InstapageCmsPluginConnector::isAPIAccessible()),
377
+ array('label' => InstapageCmsPluginConnector::lang('Enabled clean / SEO friendly URLs'), 'condition' => InstapageCmsPluginConnector::areSEOFriendlyUrlsEnabled()),
378
+ array('label' => InstapageCmsPluginConnector::lang('Every request for landing page requires a request to our page server (http://pageserve.co) and this URL has to be accessible.'), 'condition' => InstapageCmsPluginConnector::isAPIAccessible())
379
+ );
380
+ $features = array_merge($features, $commonFeatures);
381
+
382
+ ob_start();
383
+ ?>
384
+ <div class="custom-params-form ui-section">
385
+ <h3 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Plugin requirements'); ?></h3>
386
+ <p class="l-space-bottom-primary"><?php echo InstapageCmsPluginConnector::lang('Instapage plugin requires following settings to work correctly:'); ?></p>
387
+ <ul class="c-list">
388
+ <?php foreach ($features as $feature): ?>
389
+ <li class="c-list-item">
390
+ &ndash; <span class="<?php echo ($feature['condition']) ? 'u-text--success' : 'u-text--danger'; ?>">
391
+ <?php echo $feature['label']; ?>
392
+ </span>
393
+ </li>
394
+ <?php endforeach; ?>
395
+ </ul>
396
+ </div>
397
+ <?php
398
+ $html = ob_get_contents();
399
+ ob_end_clean();
400
+
401
+ return $html;
402
+ }
403
+ }
connectors/InstapageCmsPluginDrupal7Connector.php ADDED
@@ -0,0 +1,919 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Drupal 7 hook, registers the plugin permissions.
5
+ *
6
+ * @return array Drupal 7 specific permission array.
7
+ */
8
+ function instapage_cms_plugin_permission() {
9
+ return array(
10
+ 'administer instapage_cms_plugin settings' => array(
11
+ 'title' => t('Administer Instapage settings'),
12
+ 'description' => t('Allow users to administer Instapage settings.'),
13
+ )
14
+ );
15
+ }
16
+
17
+ /**
18
+ * Drupal 7 hook. Adds a link to admin menu.
19
+ *
20
+ * @return array Array with new menu items.
21
+ */
22
+ function instapage_cms_plugin_menu() {
23
+
24
+ $items = array();
25
+ $items['admin/structure/instapage_cms_plugin'] = array(
26
+ 'title' => 'Instapage Plugin',
27
+ 'description' => 'The best way for Drupal to seamlessly publish landing pages as a natural extension of your website.',
28
+ 'page callback' => 'load_instapage_cms_plugin_dashboard',
29
+ 'access arguments' => array('administer instapage_cms_plugin settings'),
30
+ 'type' => MENU_NORMAL_ITEM
31
+ );
32
+
33
+ return $items;
34
+ }
35
+
36
+ /**
37
+ * Drupal 7 hook. Function called to initiate Instapage plugin.
38
+ */
39
+ function instapage_cms_plugin_init() {
40
+ if (!menu_get_item($_GET['q'])) {
41
+ InstapageCmsPluginConnector::getSelectedConnector()->check404();
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Drupal 7 hook. Function called when plugin is installed.
47
+ */
48
+ function instapage_cms_plugin_install() {
49
+ user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('administer instapage_cms_plugin settings'));
50
+ }
51
+
52
+ /**
53
+ * Drupal 7 hook. Function called when plugin is uninstalled.
54
+ */
55
+ function instapage_cms_plugin_uninstall() {
56
+ InstapageCmsPluginConnector::getSelectedConnector()->removePlugin();
57
+ }
58
+
59
+ /**
60
+ * Drupal 7 hook. Function called to load plugin's dashboard.
61
+ */
62
+ function load_instapage_cms_plugin_dashboard() {
63
+ $jsDir = base_path() . drupal_get_path('module', InstapageCmsPluginConnector::getPluginDirectoryName()) . '/core/assets/js';
64
+ $knockoutDir = base_path() . drupal_get_path('module', InstapageCmsPluginConnector::getPluginDirectoryName()) . '/core/knockout';
65
+ $languageFile = base_path() . drupal_get_path('module', InstapageCmsPluginConnector::getPluginDirectoryName()) . '/core/assets/lang/' . InstapageCmsPluginConnector::getSelectedLanguage() . '.js';
66
+ $options = array(
67
+ 'scope' => 'footer',
68
+ 'group' => JS_LIBRARY,
69
+ 'weight' => 1,
70
+ 'cache' => false,
71
+ 'defer' => false,
72
+ 'preprocess' => false
73
+ );
74
+ drupal_add_js('var INSTAPAGE_AJAXURL = \'' . InstapageCmsPluginConnector::getAjaxURL() . '\';', array('type' => 'inline', 'scope' => 'header'));
75
+ $options['weight']++;
76
+ drupal_add_js($languageFile, $options);
77
+ $options['weight']++;
78
+ drupal_add_js($jsDir . '/InstapageCmsPluginLang.js', $options);
79
+ $options['weight']++;
80
+ drupal_add_js($knockoutDir . '/core/knockout-3.4.0.js', $options);
81
+ $options['weight']++;
82
+ drupal_add_js($jsDir . '/knockout-no-conflict.js', $options);
83
+ $options['weight']++;
84
+ drupal_add_js($knockoutDir . '/core/knockout.simpleGrid.3.0.js', $options);
85
+ $options['weight']++;
86
+ drupal_add_js($jsDir . '/download.js', $options);
87
+ $options['weight']++;
88
+ drupal_add_js($jsDir . '/InstapageCmsPluginAjax.js', $options);
89
+ $options['weight']++;
90
+ drupal_add_js($knockoutDir . '/view_models/InstapageCmsPluginPagedGridModel.js', $options);
91
+ $options['weight']++;
92
+ drupal_add_js($knockoutDir . '/view_models/InstapageCmsPluginEditModel.js', $options);
93
+ $options['weight']++;
94
+ drupal_add_js($knockoutDir . '/view_models/InstapageCmsPluginSettingsModel.js', $options);
95
+ $options['weight']++;
96
+ drupal_add_js($knockoutDir . '/view_models/InstapageCmsPluginMessagesModel.js', $options);
97
+ $options['weight']++;
98
+ drupal_add_js($knockoutDir . '/view_models/InstapageCmsPluginToolbarModel.js', $options);
99
+ $options['weight']++;
100
+ drupal_add_js($knockoutDir . '/view_models/InstapageCmsPluginMasterModel.js', $options);
101
+ $options['weight']++;
102
+
103
+ // UI KIT
104
+ drupal_add_js('https://code.jquery.com/jquery-2.2.4.min.js', $options);
105
+ $options['weight']++;
106
+ drupal_add_js($jsDir . '/mrwhite.js', $options);
107
+ $options['weight']++;
108
+ drupal_add_js($jsDir . '/dropdowns.js', $options);
109
+ $options['weight']++;
110
+ drupal_add_js($jsDir . '/expand-collapse.js', $options);
111
+ $options['weight']++;
112
+ drupal_add_js($jsDir . '/input.js', $options);
113
+ $options['weight']++;
114
+ drupal_add_js($jsDir . '/jq.hoverintent.js', $options);
115
+ $options['weight']++;
116
+ drupal_add_js($jsDir . '/jquery.tmpl.min.js', $options);
117
+ $options['weight']++;
118
+ drupal_add_js($jsDir . '/ripple.js', $options);
119
+ $options['weight']++;
120
+ drupal_add_js($jsDir . '/select2.min.js', $options);
121
+ $options['weight']++;
122
+ drupal_add_js($jsDir . '/snack-bars.js', $options);
123
+ $options['weight']++;
124
+ drupal_add_js($jsDir . '/tabs.js', $options);
125
+
126
+ $options = array('preprocess' => 'false');
127
+ $cssDir = drupal_get_path('module', InstapageCmsPluginConnector::getPluginDirectoryName()) . '/core/assets/css';
128
+ drupal_add_css($cssDir . '/mrwhite-reset.css', $options);
129
+ drupal_add_css($cssDir . '/mrwhite-ui-kit.css', $options);
130
+ drupal_add_css($cssDir . '/general.css', $options);
131
+
132
+ ob_start();
133
+ InstapageCmsPluginConnector::getSelectedConnector()->loadPluginDashboard();
134
+ $contents = ob_get_contents();
135
+ ob_end_clean();
136
+
137
+ return $contents;
138
+ }
139
+
140
+ /**
141
+ * Class that utilizes native Drupal 7 functions to perform actions like remote requests and DB operations.
142
+ */
143
+ class InstapageCmsPluginDrupal7Connector {
144
+
145
+ /**
146
+ * @var string Name of the CMS.
147
+ */
148
+ public $name = 'drupal';
149
+
150
+ /**
151
+ * Gets the plugin directory name.
152
+ *
153
+ * @return string Plugin's directory name.
154
+ */
155
+ public function getPluginDirectoryName() {
156
+ return 'instapage_cms_plugin';
157
+ }
158
+
159
+ /**
160
+ * Gets the CMS name.
161
+ *
162
+ * @return string CMS name.
163
+ */
164
+ public function getCMSName() {
165
+ return 'Drupal';
166
+ }
167
+
168
+ /**
169
+ * Gets the currently used CMS version.
170
+ * @return string CMS version.
171
+ */
172
+ public function getCMSVersion() {
173
+ return VERSION;
174
+ }
175
+
176
+ /**
177
+ * Checks if API is accessible
178
+ * @uses self::remoteGet()
179
+ * @return bool
180
+ */
181
+ public function isAPIAccessible() {
182
+ $response = $this->remoteGet(INSTAPAGE_ENTERPRISE_ENDPOINT, array());
183
+
184
+ $body = is_string($response['body']) && is_object(json_decode($response['body'])) ? json_decode($response['body']) : null ;
185
+
186
+ return (
187
+ is_object($body) &&
188
+ isset($body->status) && $body->status === 'ERROR' &&
189
+ isset($body->message) && stripos($body->message, 'Request failed') !== false
190
+ );
191
+ }
192
+
193
+ /**
194
+ * Checks if SEO friendly urls are enabled. Note: Type checking is loosened on purpose
195
+ * @uses self::getRow()
196
+ * @return bool
197
+ */
198
+ public function areSEOFriendlyUrlsEnabled() {
199
+ $sql = "SELECT value FROM variable WHERE name = '%s' LIMIT 1";
200
+ $row = $this->getRow($sql, 'clean_url');
201
+ return (unserialize($row->value) == 1);
202
+ }
203
+
204
+ /**
205
+ * Checks if current user can manage the plugin's dashboard.
206
+ *
207
+ * @return bool Tru is current user has the permissions.
208
+ */
209
+ public function currentUserCanManage() {
210
+ return true;
211
+ }
212
+
213
+ /**
214
+ * Prepares the function arguments returned by func_get_args function.
215
+ *
216
+ * @param array $args Arguments to prepare, Default: array().
217
+ *
218
+ * @return array Array of function parameters.
219
+ */
220
+ private function prepareFunctionArgs($args = array()) {
221
+ if (isset($args[0]) && is_array($args[0])) {
222
+ $args = $args[0];
223
+ }
224
+
225
+ return $args;
226
+ }
227
+
228
+ /**
229
+ * Prepares the basic query with proper metadata/tags and base fields.
230
+ *
231
+ * @param string $sql SQL query. %s can be used to output pre-formatted values.
232
+ *
233
+ * @return string SQL query ready to execute in Drupal 7.
234
+ */
235
+ private function prepare($sql) {
236
+ $sql = str_replace(array('\'%s\'', '%s'), '?', $sql);
237
+
238
+ return $sql;
239
+ }
240
+
241
+ /**
242
+ * Executes a SQL query.
243
+ *
244
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
245
+ *
246
+ * @uses InstapageCmsPluginDrupal7Connector::prepare() to change '%s' to '?'.
247
+ *
248
+ * @return bool True if the query is successful. DB error is logged and false if returned otherwise.
249
+ */
250
+ public function query($sql) {
251
+ $args = func_get_args();
252
+ array_shift($args);
253
+ $args = $this->prepareFunctionArgs($args);
254
+ $sql = $this->prepare($sql);
255
+
256
+ try {
257
+ db_query($sql, $args);
258
+
259
+ return true;
260
+ } catch (Exception $e) {
261
+ $this->logDbError($e, $sql);
262
+
263
+ return false;
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Gets the last ID of an insert query.
269
+ *
270
+ * @return integer|boolean Last insert ID of false on error.
271
+ */
272
+ public function lastInsertId() {
273
+ $sql = 'SELECT LAST_INSERT_ID() as last_insert_id';
274
+ $result = $this->getRow($sql);
275
+
276
+ return isset($result->last_insert_id) ? $result->last_insert_id : false;
277
+ }
278
+
279
+ /**
280
+ * Executes the query and returns the first row.
281
+ *
282
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
283
+ *
284
+ * @return mixed first row of results of the query.
285
+ */
286
+ public function getRow($sql) {
287
+ $args = func_get_args();
288
+ array_shift($args);
289
+ $args = $this->prepareFunctionArgs($args);
290
+ $sql = $this->prepare($sql);
291
+
292
+ try {
293
+ $result = db_query($sql, $args);
294
+
295
+ return $result->fetchObject();
296
+ } catch (Exception $e) {
297
+ $this->logDbError($e, $sql);
298
+
299
+ return false;
300
+ }
301
+ }
302
+
303
+ /**
304
+ * Executes the query and returns a list of results.
305
+ *
306
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
307
+ *
308
+ * @return mixed Array of results, false on error.
309
+ */
310
+ public function getResults($sql) {
311
+ $args = func_get_args();
312
+ array_shift($args);
313
+ $args = $this->prepareFunctionArgs($args);
314
+ $sql = $this->prepare($sql);
315
+
316
+ try {
317
+ $result = db_query($sql, $args);
318
+ $resultArray = $result->fetchAll(PDO::FETCH_OBJ);
319
+
320
+ if (!is_array($resultArray)) {
321
+ return array();
322
+ }
323
+
324
+ return $resultArray;
325
+ } catch (Exception $e) {
326
+ $this->logDbError($e, $sql);
327
+
328
+ return false;
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Gets the DB prefix from CMS configuration.
334
+ *
335
+ * @return string DB prefix.
336
+ */
337
+ public function getDBPrefix() {
338
+ global $databases;
339
+
340
+ $connectionKey = Database::getConnection()->getKey();
341
+ $settings = isset($databases[$connectionKey]) ? $databases[$connectionKey] : null;
342
+
343
+ if (!$settings) {
344
+ return null;
345
+ }
346
+
347
+ if (!isset($settings['prefix']) && is_array($settings)) {
348
+ $settings = array_pop($settings);
349
+ }
350
+
351
+ if (isset($settings['prefix']) && is_array($settings['prefix'])) {
352
+ $settings['prefix'] = array_pop($settings['prefix']);
353
+ }
354
+
355
+ return isset($settings['prefix']) ? $settings['prefix'] : '';
356
+ }
357
+
358
+ /**
359
+ * Gets charset collation from CMS configuration.
360
+ *
361
+ * @return string Database charset collation.
362
+ */
363
+ public function getCharsetCollate() {
364
+ global $databases;
365
+
366
+ $connectionKey = Database::getConnection()->getKey();
367
+ $settings = isset($databases[$connectionKey]) ? $databases[$connectionKey] : null;
368
+
369
+ if (!$settings) {
370
+ return null;
371
+ }
372
+
373
+ if (!isset($settings['collation']) && is_array($settings)) {
374
+ $settings = array_pop($settings);
375
+ }
376
+
377
+ if (isset($settings['collation']) && is_array($settings['collation'])) {
378
+ $settings['collation'] = array_pop($settings['collation']);
379
+ }
380
+
381
+ $collation = isset($settings['collation']) ? $settings['collation'] : 'utf8mb4_general_ci';
382
+
383
+ return 'COLLATE ' . $collation;
384
+ }
385
+
386
+ /**
387
+ * Performs remote request in a way specific for Drupal 7.
388
+ *
389
+ * @param string $url URL for the request.
390
+ * @param array $data Data that will be passed in the request.
391
+ * @param array $headers Headers for the request.
392
+ * @param string $method Method of the request. 'POST' or 'GET'.
393
+ *
394
+ * @return array Request result in a form of associative array.
395
+ */
396
+ public function remoteRequest($url, $data, $headers = array(), $method = 'POST') {
397
+ $dataString = '';
398
+
399
+ if (!isset($headers['Content-type'])) {
400
+ $headers['Content-Type'] = 'application/x-www-form-urlencoded';
401
+ InstapageCmsPluginHelper::writeDiagnostics($data, 'Request (' . $method . ') data empty. Ping added.');
402
+ }
403
+
404
+ if ($method == 'POST' && (!is_array($data) || !count($data))) {
405
+ $data = array('ping' => true);
406
+ }
407
+
408
+ $dataString = http_build_query($data, '', '&');
409
+
410
+ if ($method == 'GET') {
411
+ $url .= '?' . urldecode($dataString);
412
+ $dataString = '';
413
+ }
414
+
415
+ $cookies = @InstapageCmsPluginHelper::getVar($data['cookies'], array());
416
+ $cookieString = '';
417
+
418
+ foreach ($cookies as $key => $cookie) {
419
+ $cookieString .= $key . '=' . urlencode($cookie) . ';';
420
+ }
421
+
422
+ if ($cookieString) {
423
+ $headers['Cookie'] = $cookieString;
424
+ }
425
+
426
+ $options = array(
427
+ 'headers' => $headers,
428
+ 'method' => $method,
429
+ 'data' => $dataString,
430
+ 'max_redirects' => 5,
431
+ 'timeout' => 45
432
+ );
433
+
434
+ $request = drupal_http_request($url, $options);
435
+
436
+ if (isset($request->code) && $request->code == 200) {
437
+ return $this->prepareResponse($request);
438
+ } else {
439
+ return [
440
+ 'body' => json_encode([
441
+ 'status' => 'ERROR',
442
+ 'message' => InstapageCmsPluginConnector::lang('Request failed with status %s.', $request->code)
443
+ ])
444
+ ];
445
+ }
446
+ }
447
+
448
+ /**
449
+ * Performs remote POST request.
450
+ *
451
+ * @uses InstapageCmsPluginDrupal7Connector::remoteRequest().
452
+ *
453
+ * @param string $url URL for the request.
454
+ * @param array $data Data that will be passed in the request.
455
+ * @param array $headers Headers for the request.
456
+ *
457
+ * @return array Request result in a form of associative array.
458
+ */
459
+ public function remotePost($url, $data, $headers = array()) {
460
+ return $this->remoteRequest($url, $data, $headers, 'POST');
461
+ }
462
+
463
+ /**
464
+ * Performs remote GET request.
465
+ *
466
+ * @uses InstapageCmsPluginDrupal7Connector::remoteRequest().
467
+ *
468
+ * @param string $url URL for the request.
469
+ * @param array $data Data that will be passed in the request.
470
+ * @param array $headers Headers for the request.
471
+ *
472
+ * @return array Request result in a form of associative array.
473
+ */
474
+ public function remoteGet($url, $data, $headers = array()) {
475
+ return $this->remoteRequest($url, $data, $headers, 'GET');
476
+ }
477
+
478
+ /**
479
+ * Gets the site base URL.
480
+ *
481
+ * @param bool $protocol Value returned with protocol or not.
482
+ *
483
+ * @return string Site base URL. With protocol or not.
484
+ */
485
+ public function getSiteURL($protocol = true) {
486
+ $url = $_SERVER['HTTP_HOST'];
487
+
488
+ if ($protocol) {
489
+ if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on')) {
490
+ $url = 'https://' . $url;
491
+ } else {
492
+ $url = 'http://' . $url;
493
+ }
494
+ }
495
+
496
+ if (isset($_SERVER['PHP_SELF'])) {
497
+ $directory = ltrim(dirname($_SERVER['PHP_SELF']), DIRECTORY_SEPARATOR);
498
+ if (!empty($directory)) {
499
+ $url .= $directory;
500
+ }
501
+ }
502
+
503
+ return $url;
504
+ }
505
+
506
+ /**
507
+ * Gets the site home URL.
508
+ *
509
+ * @param bool $protocol Value returned with protocol or not.
510
+ *
511
+ * @return string Site home URL. With protocol or not.
512
+ */
513
+ public function getHomeURL($protocol = true) {
514
+ $url = $this->getSiteURL($protocol);
515
+
516
+ return $url;
517
+ }
518
+
519
+ /**
520
+ * Gets the AJAX URL.
521
+ *
522
+ * @return string AJAX URL.
523
+ */
524
+ public function getAjaxURL() {
525
+ return $this->getSiteURL() . '/?action=instapage_ajax_call';
526
+ }
527
+
528
+ /**
529
+ * Gets the value of language variable.
530
+ */
531
+ public function lang() {
532
+ $arguments = func_get_arg(0);
533
+
534
+ if (!count($arguments)) {
535
+ return null;
536
+ }
537
+
538
+ $text = $arguments[0];
539
+ $variables = array_slice($arguments, 1);
540
+
541
+ if (!count($variables)) {
542
+ return $text;
543
+ }
544
+
545
+ return vsprintf($text, $variables);
546
+ }
547
+
548
+ /**
549
+ * Initiates Instapage plugin's DB structure and loads plugin's classes.
550
+ */
551
+ public function initPlugin() {
552
+ $action = InstapageCmsPluginHelper::getVar($_GET['action'], '');
553
+
554
+ if ($action == 'instapage_ajax_call') {
555
+ $this->ajaxCallback();
556
+ } else {
557
+ InstapageCmsPluginHelper::writeDiagnostics($_SERVER['REQUEST_URI'], 'Instapage plugin initiated. REQUEST_URI');
558
+ InstapageCmsPluginHelper::writeDiagnostics($this->getCMSName() . ' ' . $this->getCMSVersion(), 'CMS name/version');
559
+ $this->checkProxy();
560
+ $this->checkHomepage();
561
+ $this->checkCustomUrl();
562
+ }
563
+ }
564
+
565
+ /**
566
+ * Removes the plugin.
567
+ */
568
+ public function removePlugin() {
569
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
570
+ $db = InstapageCmsPluginDBModel::getInstance();
571
+ $subaccount->disconnectAccountBoundSubaccounts(true);
572
+ $db->removePluginTables();
573
+ }
574
+
575
+ /**
576
+ * Loads the plugin dashboard.
577
+ */
578
+ public function loadPluginDashboard() {
579
+ InstapageCmsPluginHelper::loadTemplate('messages');
580
+ InstapageCmsPluginHelper::loadTemplate('toolbar');
581
+ InstapageCmsPluginHelper::loadTemplate('base');
582
+ }
583
+
584
+ /**
585
+ * Executes an action requested via AJAX.
586
+ */
587
+ public function ajaxCallback() {
588
+ InstapageCmsPluginConnector::ajaxCallback();
589
+ }
590
+
591
+ /**
592
+ * Checks if current URL is login page.
593
+ *
594
+ * @return bool True if current URL is login page.
595
+ */
596
+ public function isLoginPage() {
597
+ $requestUrl = $_SERVER['REQUEST_URI'];
598
+
599
+ if (strpos($requestUrl, '/user') === 0 || $_GET['q'] == 'user') {
600
+ return true;
601
+ }
602
+
603
+ return false;
604
+ }
605
+
606
+ /**
607
+ * Checks if current URL is admin page.
608
+ *
609
+ * @return bool True if current URL is admin page.
610
+ */
611
+ public function isAdmin() {
612
+ $requestUrl = $_SERVER['REQUEST_URI'];
613
+
614
+ if (strpos($requestUrl, '/admin') === 0 || $_GET['q'] == 'admin') {
615
+ return true;
616
+ }
617
+
618
+ return false;
619
+ }
620
+
621
+ /**
622
+ * Checks (and displays) if a landing page should be displayed instead of normal content served by CMS.
623
+ *
624
+ * @param string $type Type of page to check ('page', 'home' or '404').
625
+ * @param string $slug Slug to check. Default: ''.
626
+ */
627
+ public function checkPage($type, $slug = '') {
628
+ $page = InstapageCmsPluginPageModel::getInstance();
629
+ $result = $page->check($type, $slug);
630
+
631
+ if (!$result) {
632
+ return;
633
+ }
634
+
635
+ if ($type == '404') {
636
+ $page->display($result, 404);
637
+ } else {
638
+ $page->display($result);
639
+ }
640
+ }
641
+
642
+ /**
643
+ * Checks (and displays) if a landing page marked as homepage should be displayed instead of normal CMS homepage.
644
+ *
645
+ * @uses InstapageCmsPluginDrupal7Connector::checkPage()
646
+ */
647
+ public function checkHomepage() {
648
+ $homeUrl = str_replace(array('http://', 'https://'), '', rtrim($this->getHomeURL(), '/'));
649
+ $homeUrlSegments = explode('/', $homeUrl);
650
+ $uriSegments = explode('?', $_SERVER['REQUEST_URI']);
651
+ $uriSegments = explode('/', rtrim($uriSegments[0], '/'));
652
+
653
+ if (
654
+ (count($uriSegments) !== count($homeUrlSegments)) ||
655
+ (count($homeUrlSegments) > 1 && $homeUrlSegments[1] != $uriSegments[1])
656
+ ) {
657
+ return false;
658
+ }
659
+
660
+ $this->checkPage('home');
661
+
662
+ return true;
663
+ }
664
+
665
+ /**
666
+ * Checks (and displays) if a landing page marked as 404 should be displayed instead of normal CMS 404 page.
667
+ *
668
+ * @uses InstapageCmsPluginDrupal7Connector::checkPage()
669
+ */
670
+ public function check404() {
671
+ $this->checkPage('404');
672
+ }
673
+
674
+ /**
675
+ * Checks (and displays) if a landing page hould be displayed instead of normal CMS page under current URL.
676
+ *
677
+ * @uses InstapageCmsPluginDrupal7Connector::checkPage()
678
+ */
679
+ public function checkCustomUrl() {
680
+ $slug = InstapageCmsPluginHelper::extractSlug($this->getHomeURL());
681
+
682
+ if ($slug) {
683
+ $this->checkPage('page', $slug);
684
+ }
685
+
686
+ return true;
687
+ }
688
+
689
+ /**
690
+ * Checks (and processes it) if a lcurrent request should be processes by plugin's proxy.
691
+ */
692
+ public function checkProxy() {
693
+ $services = InstapageCmsPluginServicesModel::getInstance();
694
+
695
+ if ($services->isServicesRequest()) {
696
+ try {
697
+ $services->processProxyServices();
698
+
699
+ return;
700
+ } catch (Exception $e) {
701
+ echo $e->getMessage();
702
+ }
703
+ }
704
+ }
705
+
706
+ /**
707
+ * get list of slugs that can't be used to publish a landing page.
708
+ * @deprecated
709
+ * @return array List of prohibitted slugs.
710
+ */
711
+ public function getProhibitedSlugs() {
712
+ $result = array_merge($this->getPostSlugs(), InstapageCmsPluginConnector::getLandingPageSlugs());
713
+
714
+ return $result;
715
+ }
716
+
717
+ /**
718
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
719
+ * @param string $slug Slug to be checked
720
+ * @uses self::isProhibitedPostSlug()
721
+ * @uses InstapageCmsPluginConnector::isProhibitedLandingPageSlug()
722
+ * @return bool|array
723
+ */
724
+ public function isProhibitedSlug($slug) {
725
+ $postSlug = $this->isProhibitedPostSlug($slug);
726
+ if ($postSlug) {
727
+ return $postSlug;
728
+ }
729
+
730
+ $landingPageSlug = InstapageCmsPluginConnector::isProhibitedLandingPageSlug($slug);
731
+ if ($landingPageSlug) {
732
+ return $landingPageSlug;
733
+ }
734
+
735
+ return false;
736
+ }
737
+
738
+ /**
739
+ * Gets the HTML for CMS options.
740
+ *
741
+ * @return string HTML to include in the debug log.
742
+ */
743
+ public function getOptionsDebugHTML() {
744
+ return '';
745
+ }
746
+
747
+ /**
748
+ * Gets the HTML for CMS plugins/modules.
749
+ *
750
+ * @return string HTML to include in the debug log.
751
+ */
752
+ public function getPluginsDebugHTML() {
753
+ return '';
754
+ }
755
+
756
+ /**
757
+ * Gets the sitename from CMS config.
758
+ *
759
+ * @return string Sitename.
760
+ */
761
+ public function getSitename($sanitized = false) {
762
+ $sitename = variable_get('site_name');
763
+
764
+ if ($sanitized) {
765
+ return mb_strtolower(str_replace(' ', '-', $sitename));
766
+ }
767
+
768
+ return $sitename;
769
+ }
770
+
771
+ /**
772
+ * Sends an e-mail using CMS native email sending method.
773
+ *
774
+ * @param string $to Receiver address.
775
+ * @param string $subject A subject.
776
+ * @param string $message A message.
777
+ * @param string $headers Message headers. Default: ''.
778
+ * @param aray $attachments Attachments.
779
+ *
780
+ * @return bool True on success.
781
+ */
782
+ public function mail($to, $subject, $message, $headers = '', $attachments = array()) {
783
+ global $language_object;
784
+
785
+ $module = 'instapage_cms_plugin';
786
+ $key = 'custom_email';
787
+ $params['message'] = $message;
788
+ $params['subject'] = $subject;
789
+ $langcode = $language_object->language;
790
+ $send = true;
791
+
792
+ return drupal_mail($module, $key, $to, $langcode, $params, NULL, $send);
793
+ }
794
+
795
+ /**
796
+ * Gets the landing pages saved in legacy DB structure.
797
+ *
798
+ * @return array List of landing pages from legacy DB structure.
799
+ */
800
+ public function getDeprecatedData() {
801
+ $pages = variable_get('instapage_pages', NULL);
802
+ $results = array();
803
+
804
+ foreach ($pages as $key => $slug) {
805
+ $pageObj = new stdClass;
806
+ $pageObj->id = 0;
807
+ $pageObj->landingPageId = $key;
808
+ $pageObj->slug = $slug;
809
+ $pageObj->type = 'page';
810
+ $pageObj->enterprise_url = $pageObj->slug ? InstapageCmsPluginConnector::getHomeURL() . '/' . $pageObj->slug : Connector::getHomeURL();
811
+ $results[] = $pageObj;
812
+ }
813
+
814
+ return $results;
815
+ }
816
+
817
+ /**
818
+ * Properly escapes the HTML.
819
+ *
820
+ * @param string $html HTML to escape.
821
+ *
822
+ * @return string Escaped HTML.
823
+ */
824
+ public function escapeHTML($html) {
825
+ return htmlspecialchars($html);
826
+ }
827
+
828
+ /**
829
+ * Checks if there is a need to replace content of CMS with a landing page. Prevents content replacement on admin/login pages.
830
+ *
831
+ * @return bool True if replace is possible.
832
+ */
833
+ public function isHtmlReplaceNecessary() {
834
+ if ($this->isAdmin() || $this->isLoginPage() || InstapageCmsPluginHelper::isCustomParamPresent()) {
835
+ InstapageCmsPluginHelper::writeDiagnostics('is_admin || isLoginPage || isCustomParamPresent', 'HTML Replace is not necessary');
836
+
837
+ return false;
838
+ }
839
+
840
+ return true;
841
+ }
842
+
843
+ /**
844
+ * Gets the settings module, a CMS-dependant part of the Settings page.
845
+ * @uses InstapageCmsPluginConnector::getCmsVersion()
846
+ * @uses InstapageCmsPluginConnector::getPluginRequirements()
847
+ * @return string HTML form with settings for currently used CMS only.
848
+ */
849
+ public function getSettingsModule() {
850
+ return InstapageCmsPluginConnector::getPluginRequirements(array(array('label' => InstapageCmsPluginConnector::lang('Drupal 7.x+'), 'condition' => version_compare(InstapageCmsPluginConnector::getCMSVersion(), '7.0', '>='))));
851
+ }
852
+
853
+ /**
854
+ * Logs DB errors.
855
+ *
856
+ * @param object $e Exception object
857
+ * @param string $sql SQL query.
858
+ */
859
+ private function logDbError($e, $sql) {
860
+ $db = InstapageCmsPluginDBModel::getInstance();
861
+ $errorMessage = $e->getMessage();
862
+
863
+ if (strpos($sql, $db->debugTable) === false && $errorMessage !== '') {
864
+ $messages = array(
865
+ 'Query: ' . $sql,
866
+ 'Error: ' . $errorMessage
867
+ );
868
+
869
+ InstapageCmsPluginHelper::writeDiagnostics(implode("\n", $messages), 'DB Error');
870
+ }
871
+ }
872
+
873
+ /**
874
+ * Gets the list of slugs used by Drupal 7 posts.
875
+ * @deprecated
876
+ * @return array List of slugs used by posts.
877
+ */
878
+ private function getPostSlugs() {
879
+ $editUrl = $this->getSiteURL();
880
+ $dbPrefix = $this->getDBPrefix();
881
+ $sql = 'SELECT pid AS id, SUBSTRING(alias, 2) AS slug, CONCAT(\'' . $editUrl . '\', source, \'/edit\') AS editUrl FROM ' . $dbPrefix . 'url_alias';
882
+ $results = $this->getResults($sql);
883
+
884
+ return $results;
885
+ }
886
+
887
+ /**
888
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
889
+ * @param string $slug Slug to be checked
890
+ * @uses self::getSiteURL()
891
+ * @uses self::getDBPrefix()
892
+ * @uses self::getResults()
893
+ * @return bool|array
894
+ */
895
+ private function isProhibitedPostSlug($slug) {
896
+ $editUrl = $this->getSiteURL();
897
+ $dbPrefix = $this->getDBPrefix();
898
+ $sql = 'SELECT pid AS id, SUBSTRING(alias, 2) AS slug, CONCAT(\'' . $editUrl . '\', source, \'/edit\') AS editUrl FROM ' . $dbPrefix . 'url_alias WHERE SUBSTRING(alias, 2) = \'%s\' LIMIT 1';
899
+ $results = $this->getResults($sql, $slug);
900
+
901
+ return $results;
902
+ }
903
+
904
+ /**
905
+ * Prepares the remote request response to unify response object in all integrated CMSes.
906
+ *
907
+ * @param object $request Request result.
908
+ *
909
+ * @return array Standard Instapage plugin request response array.
910
+ */
911
+ private function prepareResponse($request) {
912
+ return array(
913
+ 'body' => (string) isset($request->data) ? $request->data : '',
914
+ 'status' => (string) isset($request->status_message) ? $request->status_message : '',
915
+ 'code' => isset($request->code) ? $request->code : '0',
916
+ 'headers' => isset($request->headers) ? $request->headers : ''
917
+ );
918
+ }
919
+ }
connectors/InstapageCmsPluginDrupal8Connector.php ADDED
@@ -0,0 +1,785 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Drupal\Core\Database\Database as Database;
4
+
5
+ /**
6
+ * Class that utilizes native Drupal 8 functions to perform actions like remote requests and DB operations.
7
+ */
8
+ class InstapageCmsPluginDrupal8Connector {
9
+
10
+ /**
11
+ * @var string $name Name of the CMS.
12
+ */
13
+ public $name = 'drupal';
14
+
15
+ /**
16
+ * Gets the plugin directory name.
17
+ *
18
+ * @return string Plugin's directory name.
19
+ */
20
+ public function getPluginDirectoryName() {
21
+ return 'instapage_cms_plugin';
22
+ }
23
+
24
+ /**
25
+ * Gets the CMS name.
26
+ *
27
+ * @return string CMS name.
28
+ */
29
+ public function getCMSName() {
30
+ return 'Drupal';
31
+ }
32
+
33
+ /**
34
+ * Gets the currently used CMS version.
35
+ * @return string CMS version.
36
+ */
37
+ public function getCMSVersion() {
38
+ return Drupal::VERSION;
39
+ }
40
+
41
+ /**
42
+ * Checks if API is accessible
43
+ * @uses self::remoteGet()
44
+ * @return bool
45
+ */
46
+ public function isAPIAccessible() {
47
+ $response = $this->remoteGet(INSTAPAGE_ENTERPRISE_ENDPOINT, array());
48
+
49
+ $body = is_string($response['body']) && is_object(json_decode($response['body'])) ? json_decode($response['body']) : null ;
50
+
51
+ return (
52
+ is_object($body) &&
53
+ isset($body->status) && $body->status === 'ERROR' &&
54
+ isset($body->message) && stripos($body->message, 'Request failed') !== false
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Checks if SEO friendly urls are enabled
60
+ * @return bool
61
+ */
62
+ public function areSEOFriendlyUrlsEnabled() {
63
+ return true;
64
+ }
65
+
66
+ /**
67
+ * Checks if current user can manage the plugin's dashboard.
68
+ *
69
+ * @return bool Tru is current user has the permissions.
70
+ */
71
+ public function currentUserCanManage() {
72
+ return true;
73
+ }
74
+
75
+ /**
76
+ * Prepares the function arguments returned by func_get_args function.
77
+ *
78
+ * @param array $args Arguments to prepare, Default: array().
79
+ *
80
+ * @return array Array of function parameters.
81
+ */
82
+ private function prepareFunctionArgs($args = array()) {
83
+ if (isset($args[0]) && is_array($args[0])) {
84
+ $args = $args[0];
85
+ }
86
+
87
+ return $args;
88
+ }
89
+
90
+ /**
91
+ * Executes a SQL query.
92
+ *
93
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
94
+ *
95
+ * @uses InstapageCmsPluginDrupal7Connector::prepare() to change '%s' to '?'.
96
+ *
97
+ * @return bool True if the query is successful. DB error is logged and false if returned otherwise.
98
+ */
99
+ public function query($sql) {
100
+ $args = func_get_args();
101
+ array_shift($args);
102
+ $args = $this->prepareFunctionArgs($args);
103
+
104
+ try {
105
+ $statement = $this->prepare($sql);
106
+
107
+ if (count($args)) {
108
+ return $statement->execute($args);
109
+ } else {
110
+ return $statement->execute();
111
+ }
112
+
113
+ } catch (Exception $e) {
114
+ $this->logDbError($e, $sql);
115
+
116
+ return false;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Gets the last ID of an insert query.
122
+ *
123
+ * @return integer|boolean Last insert ID of false on error.
124
+ */
125
+ public function lastInsertId() {
126
+ $sql = 'SELECT LAST_INSERT_ID() as last_insert_id';
127
+ $result = $this->getRow($sql);
128
+
129
+ return isset($result->last_insert_id) ? $result->last_insert_id : false;
130
+ }
131
+
132
+ /**
133
+ * Prepares the basic query with proper metadata/tags and base fields.
134
+ *
135
+ * @param string $sql SQL query. %s can be used to output pre-formatted values.
136
+ *
137
+ * @return string SQL query ready to execute in Drupal 8.
138
+ */
139
+ public function prepare($sql) {
140
+ $sql = str_replace(array('\'%s\'', '%s'), '?', $sql);
141
+ $connection = Database::getConnection();
142
+
143
+ return $connection->prepare($sql);
144
+ }
145
+
146
+ /**
147
+ * Executes the query and returns the first row.
148
+ *
149
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
150
+ *
151
+ * @return mixed first row of results of the query.
152
+ */
153
+ public function getRow($sql) {
154
+ $args = func_get_args();
155
+ array_shift($args);
156
+ $args = $this->prepareFunctionArgs($args);
157
+
158
+ try {
159
+ $statement = $this->prepare($sql);
160
+
161
+ if (count($args)) {
162
+ $statement->execute($args);
163
+ } else {
164
+ $statement->execute();
165
+ }
166
+
167
+ return $statement->fetch(PDO::FETCH_OBJ);
168
+ } catch (Exception $e) {
169
+ $this->logDbError($e, $sql);
170
+
171
+ return false;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Executes the query and returns a list of results.
177
+ *
178
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
179
+ *
180
+ * @return mixed Array of results, false on error.
181
+ */
182
+ public function getResults($sql) {
183
+ $args = func_get_args();
184
+ array_shift($args);
185
+ $args = $this->prepareFunctionArgs($args);
186
+
187
+ try {
188
+ $statement = $this->prepare($sql);
189
+
190
+ if (count($args)) {
191
+ $statement->execute($args);
192
+ } else {
193
+ $statement->execute();
194
+ }
195
+
196
+ return $statement->fetchAll(PDO::FETCH_OBJ);
197
+ } catch (Exception $e) {
198
+ $this->logDbError($e, $sql);
199
+
200
+ return false;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Gets the DB prefix from CMS configuration.
206
+ *
207
+ * @return string DB prefix.
208
+ */
209
+ public function getDBPrefix() {
210
+ $connectionKey = Database::getConnection()->getKey();
211
+ $settings = Database::getConnectionInfo($connectionKey);
212
+
213
+ if (!isset($settings['prefix']) && is_array($settings)) {
214
+ $settings = array_pop($settings);
215
+ }
216
+
217
+ if (isset($settings['prefix']) && is_array($settings['prefix'])) {
218
+ $settings['prefix'] = array_pop($settings['prefix']);
219
+ }
220
+
221
+ return isset($settings['prefix']) ? $settings['prefix'] : '';
222
+ }
223
+
224
+ /**
225
+ * Gets charset collation.
226
+ *
227
+ * @return string Database charset collation.
228
+ */
229
+ public function getCharsetCollate() {
230
+ return 'COLLATE utf8mb4_general_ci';
231
+ }
232
+
233
+ /**
234
+ * Performsremote request in a way specific for Drupal 7.
235
+ *
236
+ * @param string $url URL for the request.
237
+ * @param array $data Data that will be passed in the request.
238
+ * @param array $headers Headers for the request.
239
+ * @param string $method Method of the request. 'POST' or 'GET'.
240
+ *
241
+ * @return array Request result in a form of associative array.
242
+ */
243
+ public function remoteRequest($url, $data, $headers = array(), $method = 'POST') {
244
+ try {
245
+ if ($method == 'POST' && (!is_array($data) || !count($data))) {
246
+ $data = array('ping' => true);
247
+ InstapageCmsPluginHelper::writeDiagnostics($data, 'Request (' . $method . ') data empty. Ping added.');
248
+ }
249
+
250
+ $formParams = $data;
251
+
252
+ if ($method == 'GET' && is_array($data)) {
253
+ $dataString = http_build_query($data, '', '&');
254
+ $url .= '?' . urldecode($dataString);
255
+ $formParams = array();
256
+ }
257
+
258
+ $cookies = @InstapageCmsPluginHelper::getVar($data['cookies'], array());
259
+ $cookieJar = false;
260
+
261
+ if (!empty($cookies)) {
262
+ $domain = parse_url($url, PHP_URL_HOST);
263
+ $cookieJar = \GuzzleHttp\Cookie\CookieJar::fromArray($cookies, $domain);
264
+ }
265
+
266
+ $client = \Drupal::httpClient();
267
+ $request = $client->request(
268
+ $method,
269
+ $url,
270
+ array(
271
+ 'allow_redirects' => array(
272
+ 'max' => 5
273
+ ),
274
+ 'connect_timeout' => 45,
275
+ 'synchronous' => true,
276
+ 'cookies' => $cookieJar,
277
+ 'version' => '1.0',
278
+ 'form_params' => $formParams,
279
+ 'headers' => $headers
280
+ )
281
+ );
282
+
283
+ if ($request->getStatusCode() === 200) {
284
+ return $this->prepareResponse($request);
285
+ } else {
286
+ return [
287
+ 'body' => json_encode([
288
+ 'status' => 'ERROR',
289
+ 'message' => InstapageCmsPluginConnector::lang('Request failed with status %s.', $request->getStatusCode())
290
+ ])
291
+ ];
292
+ }
293
+ } catch (Exception $e) {
294
+ return [
295
+ 'body' => json_encode([
296
+ 'status' => 'ERROR',
297
+ 'message' => InstapageCmsPluginConnector::lang('Request failed. ') .
298
+ $e->getMessage()
299
+ ])
300
+ ];
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Performs remote POST request.
306
+ *
307
+ * @uses InstapageCmsPluginDrupal8Connector::remoteRequest().
308
+ * @param string $url URL for the request.
309
+ * @param array $data Data that will be passed in the request.
310
+ * @param array $headers Headers for the request.
311
+ *
312
+ * @return array Request result in a form of associative array.
313
+ */
314
+ public function remotePost($url, $data, $headers = array()) {
315
+ return $this->remoteRequest($url, $data, $headers, 'POST');
316
+ }
317
+
318
+ /**
319
+ * Performs remote GET request.
320
+ *
321
+ * @uses InstapageCmsPluginDrupal8Connector::remoteRequest().
322
+ *
323
+ * @param string $url URL for the request.
324
+ * @param array $data Data that will be passed in the request.
325
+ * @param array $headers Headers for the request.
326
+ *
327
+ * @return array Request result in a form of associative array.
328
+ */
329
+ public function remoteGet($url, $data, $headers = array()) {
330
+ return $this->remoteRequest($url, $data, $headers, 'GET');
331
+ }
332
+
333
+
334
+ /**
335
+ * Prepares the remote request response to unify response object in all integrated CMSes.
336
+ *
337
+ * @param object $request Request result.
338
+ *
339
+ * @return array Standard Instapage plugin request response array.
340
+ */
341
+ private function prepareResponse($request) {
342
+ $headers = $request->getHeaders();
343
+ $headers['set-cookie'] = @InstapageCmsPluginHelper::getVar($headers['Set-Cookie'][0], '');
344
+
345
+ return array(
346
+ 'body' => (string) $request->getBody(),
347
+ 'status' => $request->getReasonPhrase(),
348
+ 'code' => $request->getStatusCode(),
349
+ 'headers' => $headers
350
+ );
351
+ }
352
+
353
+ /**
354
+ * Gets the site base URL.
355
+ *
356
+ * @param bool $protocol Value returned with protocol or not.
357
+ *
358
+ * @return string Site base URL. With protocol or not.
359
+ */
360
+ public function getSiteURL($protocol = true) {
361
+ $url = $_SERVER['HTTP_HOST'];
362
+
363
+ if ($protocol) {
364
+ if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on')) {
365
+ $url = 'https://' . $url;
366
+ } else {
367
+ $url = 'http://' . $url;
368
+ }
369
+ }
370
+
371
+ if (isset($_SERVER['PHP_SELF'])) {
372
+ $directory = ltrim(dirname($_SERVER['PHP_SELF']), DIRECTORY_SEPARATOR);
373
+ if (!empty($directory)) {
374
+ $url .= $directory;
375
+ }
376
+ }
377
+
378
+ return $url;
379
+ }
380
+
381
+ /**
382
+ * Gets the site home URL.
383
+ *
384
+ * @param bool $protocol Value returned with protocol or not.
385
+ *
386
+ * @return string Site home URL. With protocol or not.
387
+ */
388
+ public function getHomeURL($protocol = true) {
389
+
390
+ $url = $this->getSiteURL($protocol);
391
+
392
+ return $url;
393
+ }
394
+
395
+ /**
396
+ * Gets the AJAX URL.
397
+ *
398
+ * @return string AJAX URL.
399
+ */
400
+ public function getAjaxURL() {
401
+ return $this->getSiteURL() . '/index.php?action=instapage_ajax_call';
402
+ }
403
+
404
+ /**
405
+ * Gets the value of language variable.
406
+ */
407
+ public function lang() {
408
+ $arguments = func_get_arg(0);
409
+
410
+ if (!count($arguments)) {
411
+ return null;
412
+ }
413
+
414
+ $text = $arguments[0];
415
+ $variables = array_slice($arguments, 1);
416
+
417
+ if (!count($variables)) {
418
+ return $text;
419
+ }
420
+
421
+ return vsprintf($text, $variables);
422
+ }
423
+
424
+ /**
425
+ * Initiates Instapage plugin's DB structure and loads plugin's classes.
426
+ */
427
+ public function initPlugin() {
428
+ $action = InstapageCmsPluginHelper::getVar($_GET['action'], '');
429
+
430
+ if ($action == 'instapage_ajax_call') {
431
+ $this->ajaxCallback();
432
+ } else {
433
+ InstapageCmsPluginHelper::writeDiagnostics($_SERVER['REQUEST_URI'], 'Instapage plugin initiated. REQUEST_URI');
434
+ InstapageCmsPluginHelper::writeDiagnostics($this->getCMSName() . ' ' . $this->getCMSVersion(), 'CMS name/version');
435
+ $this->checkProxy();
436
+ $this->checkHomepage();
437
+ $this->checkCustomUrl();
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Removes the plugin.
443
+ */
444
+ public function removePlugin() {
445
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
446
+ $db = InstapageCmsPluginDBModel::getInstance();
447
+ $subaccount->disconnectAccountBoundSubaccounts(true);
448
+ $db->removePluginTables();
449
+ }
450
+
451
+ /**
452
+ * Loads the plugin dashboard.
453
+ */
454
+ public function loadPluginDashboard() {
455
+ InstapageCmsPluginHelper::loadTemplate('messages');
456
+ InstapageCmsPluginHelper::loadTemplate('toolbar');
457
+ InstapageCmsPluginHelper::loadTemplate('base');
458
+ }
459
+
460
+ /**
461
+ * Executes an action requested via AJAX.
462
+ */
463
+ public function ajaxCallback() {
464
+ InstapageCmsPluginConnector::ajaxCallback();
465
+ }
466
+
467
+ /**
468
+ * Checks if current URL is login page.
469
+ *
470
+ * @return bool True if current URL is login page.
471
+ */
472
+ public function isLoginPage() {
473
+ $requestUrl = $_SERVER['REQUEST_URI'];
474
+
475
+ if (strpos($requestUrl, '/user') === 0 || (isset($_GET['q']) && $_GET['q'] == 'user')) {
476
+ return true;
477
+ }
478
+
479
+ return false;
480
+ }
481
+
482
+ /**
483
+ * Checks if current URL is admin page.
484
+ *
485
+ * @return bool True if current URL is admin page.
486
+ */
487
+ public function isAdmin() {
488
+ $requestUrl = $_SERVER['REQUEST_URI'];
489
+
490
+ if (strpos($requestUrl, '/admin') === 0 || (isset($_GET['q']) && $_GET['q'] == 'admin')) {
491
+ return true;
492
+ }
493
+
494
+ return false;
495
+ }
496
+
497
+ /**
498
+ * Checks (and displays) if a landing page should be displayed instead of normal content served by CMS.
499
+ *
500
+ * @param string $type Type of page to check ('page', 'home' or '404').
501
+ * @param string $slug Slug to check. Default: ''.
502
+ */
503
+ public function checkPage($type, $slug = '') {
504
+ $page = InstapageCmsPluginPageModel::getInstance();
505
+ $result = $page->check($type, $slug);
506
+
507
+ if (!$result) {
508
+ return;
509
+ }
510
+
511
+ if ($type === '404') {
512
+ $page->display($result, '404 Not Found');
513
+ } else {
514
+ $page->display($result);
515
+ }
516
+ }
517
+
518
+ /**
519
+ * Checks (and displays) if a landing page marked as homepage should be displayed instead of normal CMS homepage.
520
+ *
521
+ * @uses InstapageCmsPluginDrupal8Connector::checkPage()
522
+ */
523
+ public function checkHomepage() {
524
+ $homeUrl = str_replace(array('http://', 'https://'), '', rtrim($this->getHomeURL(), '/'));
525
+ $homeUrlSegments = explode('/', $homeUrl);
526
+ $uriSegments = explode('?', $_SERVER['REQUEST_URI']);
527
+ $uriSegments = explode('/', rtrim($uriSegments[0], '/'));
528
+
529
+ if (
530
+ (count($uriSegments) !== count($homeUrlSegments)) ||
531
+ (count($homeUrlSegments) > 1 && $homeUrlSegments[1] != $uriSegments[1])
532
+ ) {
533
+ return false;
534
+ }
535
+
536
+ $this->checkPage('home');
537
+
538
+ return true;
539
+ }
540
+
541
+ /**
542
+ * Checks (and displays) if a landing page marked as 404 should be displayed instead of normal CMS 404 page.
543
+ *
544
+ * @uses InstapageCmsPluginDrupal8Connector::checkPage()
545
+ */
546
+ public function check404() {
547
+ if (is_404()) {
548
+ $this->checkPage('404');
549
+
550
+ return true;
551
+ }
552
+
553
+ return false;
554
+ }
555
+
556
+ /**
557
+ * Checks (and displays) if a landing page hould be displayed instead of normal CMS page under current URL.
558
+ *
559
+ * @uses InstapageCmsPluginDrupal8Connector::checkPage()
560
+ */
561
+ public function checkCustomUrl() {
562
+ $slug = InstapageCmsPluginHelper::extractSlug($this->getHomeURL());
563
+
564
+ if ($slug) {
565
+ $this->checkPage('page', $slug);
566
+ }
567
+
568
+ return true;
569
+ }
570
+
571
+ /**
572
+ * Checks (and processes it) if a lcurrent request should be processes by plugin's proxy.
573
+ */
574
+ public function checkProxy() {
575
+ $services = InstapageCmsPluginServicesModel::getInstance();
576
+
577
+ if ($services->isServicesRequest()) {
578
+ try {
579
+ $services->processProxyServices();
580
+
581
+ return;
582
+ } catch (Exception $e) {
583
+ echo $e->getMessage();
584
+ }
585
+ }
586
+ }
587
+
588
+ /**
589
+ * Geta a list of slugs that can't be used to publish a landing page.
590
+ * @deprecated
591
+ * @return array List of prohibitted slugs.
592
+ */
593
+ public function getProhibitedSlugs() {
594
+ $result = array_merge($this->getPostSlugs(), InstapageCmsPluginConnector::getLandingPageSlugs());
595
+
596
+ return $result;
597
+ }
598
+
599
+ /**
600
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
601
+ * @param string $slug Slug to be checked
602
+ * @uses self::isProhibitedPostSlug()
603
+ * @uses InstapageCmsPluginConnector::isProhibitedLandingPageSlug()
604
+ * @return bool|array
605
+ */
606
+ public function isProhibitedSlug($slug) {
607
+ $postSlug = $this->isProhibitedPostSlug($slug);
608
+ if ($postSlug) {
609
+ return $postSlug;
610
+ }
611
+
612
+ $landingPageSlug = InstapageCmsPluginConnector::isProhibitedLandingPageSlug($slug);
613
+ if ($landingPageSlug) {
614
+ return $landingPageSlug;
615
+ }
616
+
617
+ return false;
618
+ }
619
+
620
+ /**
621
+ * Gets the HTML for CMS options.
622
+ *
623
+ * @return string HTML to include in the debug log.
624
+ */
625
+ public function getOptionsDebugHTML() {
626
+ return '';
627
+ }
628
+
629
+ /**
630
+ * Gets the HTML for CMS plugins/modules.
631
+ *
632
+ * @return string HTML to include in the debug log.
633
+ */
634
+ public function getPluginsDebugHTML() {
635
+ return '';
636
+ }
637
+
638
+ /**
639
+ * Gets the sitename from CMS config.
640
+ *
641
+ * @return string Sitename.
642
+ */
643
+ public function getSitename($sanitized = false) {
644
+ $sitename = \Drupal::config('system.site')->get('name');
645
+
646
+ if ($sanitized) {
647
+ return mb_strtolower(str_replace(' ', '-', $sitename));
648
+ }
649
+
650
+ return $sitename;
651
+ }
652
+
653
+ /**
654
+ * Sends an e-mail using CMS native email sending method.
655
+ *
656
+ * @param string $to Receiver address.
657
+ * @param string $subject A subject.
658
+ * @param string $message A message.
659
+ * @param string $headers Message headers. Default: ''.
660
+ * @param aray $attachments Attachments.
661
+ *
662
+ * @return bool True on success.
663
+ */
664
+ public function mail($to, $subject, $message, $headers = '', $attachments = array()) {
665
+ $mailManager = \Drupal::service('plugin.manager.mail');
666
+ $module = 'instapage_cms_plugin';
667
+ $key = 'custom_email';
668
+ $params['message'] = $message;
669
+ $params['subject'] = $subject;
670
+ $langcode = \Drupal::currentUser()->getPreferredLangcode();
671
+ $send = true;
672
+
673
+ return $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
674
+ }
675
+
676
+ /**
677
+ * Gets the landing pages saved in legacy DB structure.
678
+ *
679
+ * @return array List of landing pages from legacy DB structure.
680
+ */
681
+ public function getDeprecatedData() {
682
+ $config = \Drupal::config('instapage.pages');
683
+ $pages = $config->get('instapage_pages');
684
+ $results = array();
685
+
686
+ foreach ($pages as $key => $slug) {
687
+ $pageObj = new stdClass;
688
+ $pageObj->id = 0;
689
+ $pageObj->landingPageId = $key;
690
+ $pageObj->slug = $slug;
691
+ $pageObj->type = 'page';
692
+ $pageObj->enterprise_url = $pageObj->slug ? InstapageCmsPluginConnector::getHomeURL() . '/' . $pageObj->slug : InstapageCmsPluginConnector::getHomeURL();
693
+ $results[] = $pageObj;
694
+ }
695
+
696
+ return $results;
697
+ }
698
+
699
+ /**
700
+ * Properly escapes the HTML.
701
+ *
702
+ * @param string $html HTML to escape.
703
+ *
704
+ * @return string Escaped HTML.
705
+ */
706
+ public function escapeHTML($html) {
707
+ return \Drupal\Component\Utility\Html::escape($html);
708
+ }
709
+
710
+ /**
711
+ * Checks if there is a need to replace content of CMS with a landing page. Prevents content replacement on admin/login pages.
712
+ *
713
+ * @return bool True if replace is possible.
714
+ */
715
+ public function isHtmlReplaceNecessary() {
716
+ if ($this->isAdmin() || $this->isLoginPage() || InstapageCmsPluginHelper::isCustomParamPresent()) {
717
+ InstapageCmsPluginHelper::writeDiagnostics('isAdmin || isLoginPage || isCustomParamPresent', 'HTML Replace is not necessary');
718
+
719
+ return false;
720
+ }
721
+
722
+ return true;
723
+ }
724
+
725
+ /**
726
+ * Gets the settings module, a CMS-dependant part of the Settings page.
727
+ * @uses InstapageCmsPluginConnector::getCmsVersion()
728
+ * @uses InstapageCmsPluginConnector::getPluginRequirements()
729
+ * @return string HTML form with settings for currently used CMS only.
730
+ */
731
+ public function getSettingsModule() {
732
+ return InstapageCmsPluginConnector::getPluginRequirements(array(array('label' => InstapageCmsPluginConnector::lang('Drupal 7.x+'), 'condition' => version_compare(InstapageCmsPluginConnector::getCMSVersion(), '8.0', '>='))));
733
+ }
734
+
735
+ /**
736
+ * Logs DB errors.
737
+ *
738
+ * @param object $e Exception object
739
+ * @param string $sql SQL query.
740
+ */
741
+ private function logDbError($e, $sql) {
742
+ $db = InstapageCmsPluginDBModel::getInstance();
743
+ $errorMessage = $e->getMessage();
744
+
745
+ if (strpos($sql, $db->debugTable) === false && $errorMessage !== '') {
746
+ $messages = array(
747
+ 'Query: ' . $sql,
748
+ 'Error: ' . $errorMessage
749
+ );
750
+
751
+ InstapageCmsPluginHelper::writeDiagnostics(implode("\n", $messages), 'DB Error');
752
+ }
753
+ }
754
+
755
+ /**
756
+ * Gets the list of slugs used by Drupal 8 posts.
757
+ * @deprecated
758
+ * @return array List of slugs used by posts.
759
+ */
760
+ private function getPostSlugs() {
761
+ $editUrl = $this->getSiteURL();
762
+ $dbPrefix = $this->getDBPrefix();
763
+ $sql = 'SELECT pid AS id, SUBSTRING(alias, 2) AS slug, CONCAT(\'' . $editUrl . '\', source, \'/edit\') AS editUrl FROM ' . $dbPrefix . 'url_alias';
764
+ $results = $this->getResults($sql);
765
+
766
+ return $results;
767
+ }
768
+
769
+ /**
770
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
771
+ * @param string $slug Slug to be checked
772
+ * @uses self::getSiteURL()
773
+ * @uses self::getDBPrefix()
774
+ * @uses self::getResults()
775
+ * @return bool|array
776
+ */
777
+ private function isProhibitedPostSlug($slug) {
778
+ $editUrl = $this->getSiteURL();
779
+ $dbPrefix = $this->getDBPrefix();
780
+ $sql = 'SELECT pid AS id, SUBSTRING(alias, 2) AS slug, CONCAT(\'' . $editUrl . '\', source, \'/edit\') AS editUrl FROM ' . $dbPrefix . 'url_alias WHERE SUBSTRING(alias, 2) = \'%s\' LIMIT 1';
781
+ $results = $this->getResults($sql, $slug);
782
+
783
+ return $results;
784
+ }
785
+ }
connectors/InstapageCmsPluginWPConnector.php ADDED
@@ -0,0 +1,1112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class that utilizes native WordPress functions to perform actions like remote requests and DB operations.
5
+ */
6
+ class InstapageCmsPluginWPConnector {
7
+
8
+ /**
9
+ * @var string $name Name of the CMS.
10
+ */
11
+ public $name = 'wordpress';
12
+
13
+ /**
14
+ * Gets plugin directory name.
15
+ *
16
+ * @return string Plugin's directory name.
17
+ */
18
+ public function getPluginDirectoryName() {
19
+ return 'instapage';
20
+ }
21
+
22
+ /**
23
+ * Gets the CMS name.
24
+ *
25
+ * @return string CMS name.
26
+ */
27
+ public function getCMSName() {
28
+ return 'WordPress';
29
+ }
30
+
31
+ /**
32
+ * Gets the currently used CMS version.
33
+ * @return string CMS version.
34
+ */
35
+ public function getCMSVersion() {
36
+ return get_bloginfo('version');
37
+ }
38
+
39
+ /**
40
+ * Checks if API is accessible
41
+ * @uses self::remoteGet()
42
+ * @return bool
43
+ */
44
+ public function isAPIAccessible() {
45
+ $response = $this->remoteGet(INSTAPAGE_ENTERPRISE_ENDPOINT, array());
46
+
47
+ return (
48
+ (is_array($response)) &&
49
+ (isset($response['code'])) && ($response['code'] === 404) &&
50
+ (isset($response['body'])) && (stripos($response['body'], 'instapage') !== false)
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Checks if SEO friendly urls are enabled
56
+ * @uses self::getSelectedConnector()
57
+ * @return bool
58
+ */
59
+ public function areSEOFriendlyUrlsEnabled() {
60
+ global $wpdb;
61
+
62
+ $sql = "SELECT {$wpdb->options}.option_value FROM {$wpdb->options} WHERE {$wpdb->options}.option_name = '%s' LIMIT 1";
63
+ $row = $this->getRow($sql, 'permalink_structure');
64
+
65
+ return !empty($row->option_value);
66
+ }
67
+
68
+ /**
69
+ * Checks if current user can manage the plugin's dashboard.
70
+ *
71
+ * @return bool Tru is current user has the permissions.
72
+ */
73
+ public function currentUserCanManage() {
74
+ return current_user_can('manage_options');
75
+ }
76
+
77
+ /**
78
+ * Executes a SQL query.
79
+ *
80
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
81
+ *
82
+ * @uses InstapageCmsPluginDrupal7Connector::prepare() to change '%s' to '?'.
83
+ *
84
+ * @return bool True if the query is successful. DB error is logged and false if returned otherwise.
85
+ */
86
+ public function query($sql) {
87
+ global $wpdb;
88
+
89
+ $args = func_get_args();
90
+ array_shift($args);
91
+ $sql = $this->prepare($sql, $args);
92
+ $result = $wpdb->query($sql);
93
+ $this->checkLastQuery();
94
+
95
+ return $result;
96
+ }
97
+
98
+ /**
99
+ * Gets the last ID of an insert query.
100
+ *
101
+ * @return integer|boolean Last insert ID of false on error.
102
+ */
103
+ public function lastInsertId() {
104
+ global $wpdb;
105
+
106
+ return $wpdb->insert_id;
107
+ }
108
+
109
+ /**
110
+ * Prepares the basic query with proper metadata/tags and base fields.
111
+ *
112
+ * @param string $sql SQL query. %s can be used to output pre-formatted values.
113
+ *
114
+ * @return string SQL query ready to execute in Drupal 8.
115
+ */
116
+ public function prepare($sql, $args = array()) {
117
+ global $wpdb;
118
+
119
+ if (isset($args[0]) && is_array($args[0])) {
120
+ $args = $args[0];
121
+ }
122
+
123
+ if (count($args)) {
124
+ return $wpdb->prepare($sql, $args);
125
+ } else {
126
+ return $sql;
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Executes the query and returns the first row.
132
+ *
133
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
134
+ *
135
+ * @return mixed first row of results of the query.
136
+ */
137
+ public function getRow($sql) {
138
+ global $wpdb;
139
+
140
+ $args = func_get_args();
141
+ array_shift($args);
142
+ $sql = $this->prepare($sql, $args);
143
+ $result = $wpdb->get_row($sql, 'OBJECT');
144
+ $this->checkLastQuery();
145
+
146
+ return $result;
147
+ }
148
+
149
+ /**
150
+ * Executes the query and returns a list of results.
151
+ *
152
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
153
+ *
154
+ * @return mixed Array of results, false on error.
155
+ */
156
+ public function getResults($sql) {
157
+ global $wpdb;
158
+
159
+ $args = func_get_args();
160
+ array_shift($args);
161
+ $sql = $this->prepare($sql, $args);
162
+ $result = $wpdb->get_results($sql, 'OBJECT');
163
+ $this->checkLastQuery();
164
+
165
+ return $result;
166
+ }
167
+
168
+ /**
169
+ * Gets the DB prefix from CMS configuration.
170
+ *
171
+ * @return string DB prefix.
172
+ */
173
+ public function getDBPrefix() {
174
+ global $wpdb;
175
+
176
+ return $wpdb->prefix;
177
+ }
178
+
179
+ /**
180
+ * Gets charset collation.
181
+ *
182
+ * @return string Database charset collation.
183
+ */
184
+ public function getCharsetCollate() {
185
+ global $wpdb;
186
+
187
+ return $wpdb->get_charset_collate();
188
+ }
189
+
190
+ /**
191
+ * Performs remote request in a way specific for WordPress.
192
+ *
193
+ * @param string $url URL for the request.
194
+ * @param array $data Data that will be passed in the request.
195
+ * @param array $headers Headers for the request.
196
+ * @param string $method Method of the request. 'POST' or 'GET'.
197
+ *
198
+ * @return array Request result in a form of associative array.
199
+ */
200
+ public function remoteRequest($url, $data, $headers = array(), $method = 'POST') {
201
+ $body = is_array($data) ? $data : (array) $data;
202
+
203
+ if ($method == 'POST' && (!is_array($body) || !count($body))) {
204
+ $body = array('ping' => true);
205
+ InstapageCmsPluginHelper::writeDiagnostics($body, 'Request (' . $method . ') data empty. Ping added.');
206
+ }
207
+
208
+ if ($method == 'GET' && is_array($data)) {
209
+ $dataString = http_build_query($body, '', '&');
210
+ $url .= '?' . urldecode($dataString);
211
+ $body = null;
212
+ InstapageCmsPluginHelper::writeDiagnostics($url, 'GET Request URL');
213
+ }
214
+
215
+ $cookies = @InstapageCmsPluginHelper::getVar($data['cookies'], array());
216
+
217
+ $args = array(
218
+ 'method' => $method,
219
+ 'timeout' => 45,
220
+ 'redirection' => 5,
221
+ 'httpversion' => '1.0',
222
+ 'sslverify' => false,
223
+ 'blocking' => true,
224
+ 'headers' => $headers,
225
+ 'body' => $body,
226
+ 'cookies' => $cookies
227
+ );
228
+
229
+ switch($method) {
230
+ case 'POST':
231
+ $response = wp_remote_post($url, $args);
232
+ break;
233
+
234
+ case 'GET':
235
+ $response = wp_remote_get($url, $args);
236
+ break;
237
+
238
+ default:
239
+ $response = null;
240
+ }
241
+
242
+ if (is_wp_error($response)) {
243
+ return array(
244
+ 'body' => json_encode([
245
+ 'status' => 'ERROR',
246
+ 'message' => $response->get_error_message()
247
+ ])
248
+ );
249
+ } else {
250
+ return $this->prepareResponse($response);
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Performs remote POST request.
256
+ *
257
+ * @uses InstapageCmsPluginWPConnector::remoteRequest().
258
+ *
259
+ * @param string $url URL for the request.
260
+ * @param array $data Data that will be passed in the request.
261
+ * @param array $headers Headers for the request.
262
+ *
263
+ * @return array Request result in a form of associative array.
264
+ */
265
+ public function remotePost($url, $data, $headers = array()) {
266
+ return $this->remoteRequest($url, $data, $headers, 'POST');
267
+ }
268
+
269
+ /**
270
+ * Performs remote GET request.
271
+ *
272
+ * @uses InstapageCmsPluginWPConnector::remoteRequest().
273
+ *
274
+ * @param string $url URL for the request.
275
+ * @param array $data Data that will be passed in the request.
276
+ * @param array $headers Headers for the request.
277
+ *
278
+ * @return array Request result in a form of associative array.
279
+ */
280
+ public function remoteGet($url, $data, $headers = array()) {
281
+ return $this->remoteRequest($url, $data, $headers, 'GET');
282
+ }
283
+
284
+ /**
285
+ * Gets the site base URL.
286
+ *
287
+ * @param bool $protocol Value returned with protocol or not.
288
+ *
289
+ * @return string Site base URL. With protocol or not.
290
+ */
291
+ public function getSiteURL($protocol = true) {
292
+ $url = get_site_url();
293
+
294
+ if (!$protocol) {
295
+ $url = str_replace(array('http://', 'https://'), '', $url);
296
+ }
297
+
298
+ return $url;
299
+ }
300
+
301
+ /**
302
+ * Gets the site home URL.
303
+ *
304
+ * @param bool $protocol Value returned with protocol or not.
305
+ *
306
+ * @return string Site home URL. With protocol or not.
307
+ */
308
+ public function getHomeURL($protocol = true) {
309
+ $url = get_home_url();
310
+
311
+ if (!$protocol) {
312
+ $url = str_replace(array('http://', 'https://'), '', $url);
313
+ }
314
+
315
+ return $url;
316
+ }
317
+
318
+ /**
319
+ * Gets the AJAX URL.
320
+ *
321
+ * @return string AJAX URL.
322
+ */
323
+ public function getAjaxURL() {
324
+ return admin_url('admin-ajax.php') . '?action=instapage_ajax_call';
325
+ }
326
+
327
+ /**
328
+ * Gets the value of language variable.
329
+ */
330
+ public function lang() {
331
+ $arguments = func_get_arg(0);
332
+
333
+ if (!count($arguments)) {
334
+ return null;
335
+ }
336
+
337
+ $text = $arguments[0];
338
+ $variables = array_slice($arguments, 1);
339
+
340
+ if (!count($variables)) {
341
+ return __($text);
342
+ }
343
+
344
+ return vsprintf(__($text), $variables);
345
+ }
346
+
347
+
348
+ /**
349
+ * Initiates Instapage plugin's DB structure and loads plugin's classes.
350
+ */
351
+ public function initPlugin() {
352
+ InstapageCmsPluginHelper::writeDiagnostics($_SERVER['REQUEST_URI'], 'Instapage plugin initiated. REQUEST_URI');
353
+ InstapageCmsPluginHelper::writeDiagnostics($this->getCMSName() . ' ' . $this->getCMSVersion(), 'CMS name/version');
354
+
355
+ if ($this->isInstapagePluginDashboard()) {
356
+ add_action('admin_enqueue_scripts', array($this, 'addAdminJS'));
357
+ add_action('admin_enqueue_scripts', array($this, 'addAdminCSS'));
358
+ }
359
+
360
+ register_activation_hook(INSTAPAGE_PLUGIN_PATH . '/instapage.php', array($this, 'checkPluginRequirementsOnActivation'));
361
+ add_action('admin_menu', array($this, 'addInstapageMenu'), 5);
362
+ add_filter('plugin_action_links_' . plugin_basename(INSTAPAGE_PLUGIN_FILE), array($this, 'addActionLink'));
363
+ add_action('wp_ajax_instapage_ajax_call', array($this, 'ajaxCallback'));
364
+ add_action('wp_ajax_nopriv_instapage_ajax_call', array($this, 'ajaxCallback'));
365
+ add_action('init', array($this, 'checkProxy'), 1);
366
+ add_action('wp', array($this, 'checkHomepage'), 1);
367
+ add_action('wp', array($this, 'checkCustomUrl'), 1);
368
+ add_action('template_redirect', array($this, 'check404'), 1);
369
+ register_uninstall_hook(INSTAPAGE_PLUGIN_FILE, array('InstapageCmsPluginWPConnector', 'removePlugin'));
370
+ add_filter('https_ssl_verify', '__return_false');
371
+ }
372
+
373
+ function checkPluginRequirementsOnActivation() {
374
+ if (version_compare(PHP_VERSION, MINIUM_PHP_VERSION, '<')) {
375
+ deactivate_plugins(INSTAPAGE_PLUGIN_PATH . '/instapage.php');
376
+ wp_die(
377
+ '<h2>Outdated PHP version</h2>' .
378
+ '<p>'. __('Our Instapage plugin requires PHP ') . MINIUM_PHP_VERSION . __(' or newer. ') .
379
+ __('Your current PHP version is: ') . PHP_VERSION . '.' .
380
+ '</p>',
381
+ 'Outdated PHP version',
382
+ array('response'=>200, 'back_link'=>TRUE)
383
+ );
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Removes the plugin.
389
+ */
390
+ public function removePlugin() {
391
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
392
+ $db = InstapageCmsPluginDBModel::getInstance();
393
+ $subaccount->disconnectAccountBoundSubaccounts(true);
394
+ $db->removePluginTables();
395
+ }
396
+
397
+ /**
398
+ * Adds a link to WP admin sidebar.
399
+ */
400
+ public function addInstapageMenu() {
401
+ $iconSvg = InstapageCmsPluginHelper::getMenuIcon();
402
+
403
+ add_menu_page(
404
+ __('Instapage: General settings'),
405
+ __('Instapage'),
406
+ 'manage_options',
407
+ 'instapage_dashboard',
408
+ array($this, 'loadPluginDashboard'),
409
+ $iconSvg,
410
+ 30
411
+ );
412
+ }
413
+
414
+ /**
415
+ * WP filter. Adds a link to Instapage plugin's dashboard in WP plugin list.
416
+ *
417
+ * @param array $links List of links admin dashboard.
418
+ */
419
+ public function addActionLink($links) {
420
+ $links[] = '<a href="' . admin_url('admin.php?page=instapage_dashboard') . '">' . InstapageCmsPluginConnector::lang('Instapage dashboard') . '</a>';
421
+
422
+ return $links;
423
+ }
424
+
425
+ /**
426
+ * Adds JS necessary to for plugin's dashboard.
427
+ */
428
+ public function addAdminJS() {
429
+ $jsDir = plugins_url('assets/js', INSTAPAGE_PLUGIN_FILE);
430
+ $knockoutDir = plugins_url('knockout', INSTAPAGE_PLUGIN_FILE);
431
+ $languageFile = plugins_url('assets/lang/' . InstapageCmsPluginConnector::getSelectedLanguage() . '.js', INSTAPAGE_PLUGIN_FILE);
432
+
433
+ wp_register_script('instapage-dictionry', $languageFile, null, false, true);
434
+ wp_register_script('instapage-lang', $jsDir . '/InstapageCmsPluginLang.js', null, false, true);
435
+ wp_register_script('instapage-knokout', $knockoutDir . '/core/knockout-3.4.0.js', null, false, true);
436
+ wp_register_script('instapage-knokout-no-conflict', $jsDir . '/knockout-no-conflict.js', null, false, true);
437
+ wp_register_script('instapage-knokout-simple-grid', $knockoutDir . '/core/knockout.simpleGrid.3.0.js', null, false, true);
438
+ wp_register_script('instapage-download', $jsDir . '/download.js', null, false, true);
439
+ wp_register_script('instapage-ajax', $jsDir . '/InstapageCmsPluginAjax.js', null, false, true);
440
+ wp_register_script('instapage-paged-grid-model', $knockoutDir . '/view_models/InstapageCmsPluginPagedGridModel.js', null, false, true);
441
+ wp_register_script('instapage-edit-model', $knockoutDir . '/view_models/InstapageCmsPluginEditModel.js', null, false, true);
442
+ wp_register_script('instapage-settings-model', $knockoutDir . '/view_models/InstapageCmsPluginSettingsModel.js', null, false, true);
443
+ wp_register_script('instapage-messages-model', $knockoutDir . '/view_models/InstapageCmsPluginMessagesModel.js', null, false, true);
444
+ wp_register_script('instapage-toolbar-model', $knockoutDir . '/view_models/InstapageCmsPluginToolbarModel.js', null, false, true);
445
+ wp_register_script('instapage-master-model', $knockoutDir . '/view_models/InstapageCmsPluginMasterModel.js', null, false, true);
446
+
447
+ wp_enqueue_script('instapage-dictionry');
448
+ wp_enqueue_script('instapage-lang');
449
+ wp_enqueue_script('instapage-knokout');
450
+ wp_enqueue_script('instapage-knokout-no-conflict');
451
+ wp_enqueue_script('instapage-knokout-simple-grid');
452
+ wp_enqueue_script('instapage-ajax');
453
+ wp_enqueue_script('instapage-download');
454
+ wp_enqueue_script('instapage-paged-grid-model');
455
+ wp_enqueue_script('instapage-edit-model');
456
+ wp_enqueue_script('instapage-settings-model');
457
+ wp_enqueue_script('instapage-messages-model');
458
+ wp_enqueue_script('instapage-toolbar-model');
459
+ wp_enqueue_script('instapage-master-model');
460
+
461
+ // UI KIT.
462
+ wp_register_script('instapage-mrwhite', $jsDir . '/mrwhite.js', null, false, true);
463
+ wp_register_script('instapage-dropdowns', $jsDir . '/dropdowns.js', null, false, true);
464
+ wp_register_script('instapage-expand-collapse', $jsDir . '/expand-collapse.js', null, false, true);
465
+ wp_register_script('instapage-input', $jsDir . '/input.js', null, false, true);
466
+ wp_register_script('instapage-jq-hoverintent', $jsDir . '/jq.hoverintent.js', null, false, true);
467
+ wp_register_script('instapage-jquery-tmpl-min', $jsDir . '/jquery.tmpl.min.js', null, false, true);
468
+ wp_register_script('instapage-ripple', $jsDir . '/ripple.js', null, false, true);
469
+ wp_register_script('instapage-select2-min', $jsDir . '/select2.min.js', null, false, true);
470
+ wp_register_script('instapage-snack-bars', $jsDir . '/snack-bars.js', null, false, true);
471
+ wp_register_script('instapage-tabs', $jsDir . '/tabs.js', null, false, true);
472
+
473
+ wp_enqueue_script('jquery');
474
+ wp_enqueue_script('instapage-mrwhite');
475
+ wp_enqueue_script('instapage-dropdowns');
476
+ wp_enqueue_script('instapage-expand-collapse');
477
+ wp_enqueue_script('instapage-input');
478
+ wp_enqueue_script('instapage-jq-hoverintent');
479
+ wp_enqueue_script('instapage-jquery-tmpl-min');
480
+ wp_enqueue_script('instapage-ripple');
481
+ wp_enqueue_script('instapage-select2-min');
482
+ wp_enqueue_script('instapage-snack-bars');
483
+ wp_enqueue_script('instapage-tabs');
484
+ }
485
+
486
+ /**
487
+ * Adds necessary CSS for plugin's dashboard.
488
+ */
489
+ public function addAdminCSS() {
490
+ $cssDir = plugins_url('assets/css', INSTAPAGE_PLUGIN_FILE);
491
+ wp_enqueue_style('instapage-mrwhite-reset', $cssDir . '/mrwhite-reset.css');
492
+ wp_enqueue_style('instapage-mrwhite-ui-kit', $cssDir . '/mrwhite-ui-kit.css');
493
+ wp_enqueue_style('instapage-general', $cssDir . '/general.css');
494
+ }
495
+
496
+ /**
497
+ * Loads the plugin dashboard.
498
+ */
499
+ public function loadPluginDashboard() {
500
+ InstapageCmsPluginHelper::initAjaxURL();
501
+ InstapageCmsPluginHelper::loadTemplate('messages');
502
+ InstapageCmsPluginHelper::loadTemplate('toolbar');
503
+ InstapageCmsPluginHelper::loadTemplate('base');
504
+ }
505
+
506
+ /**
507
+ * Executes an action requested via AJAX.
508
+ */
509
+ public function ajaxCallback() {
510
+ InstapageCmsPluginConnector::ajaxCallback();
511
+ }
512
+
513
+ /**
514
+ * Checks if current URL is login page.
515
+ *
516
+ * @return bool True if current URL is login page.
517
+ */
518
+ public function isLoginPage() {
519
+ $pagenow = InstapageCmsPluginHelper::getVar($GLOBALS['pagenowfff'], 'undefined');
520
+
521
+ return in_array($pagenow, array('wp-login.php', 'wp-register.php'));
522
+ }
523
+
524
+ /**
525
+ * Checks (and displays) if a landing page should be displayed instead of normal content served by CMS.
526
+ *
527
+ * @param string $type Type of page to check ('page', 'home' or '404').
528
+ * @param string $slug Slug to check. Default: ''.
529
+ */
530
+ public function checkPage($type, $slug = '') {
531
+ $page = InstapageCmsPluginPageModel::getInstance();
532
+ $result = $page->check($type, $slug);
533
+ $supportLegacy = InstapageCmsPluginHelper::getMetadata('supportLegacy', true);
534
+
535
+ if (!$result && $supportLegacy && $this->legacyArePagesPresent()) {
536
+ $result = $this->legacyGetPage($slug);
537
+ }
538
+
539
+ if (isset($result->instapage_id) && $result->instapage_id) {
540
+ // we have landing page for given slug,
541
+ // but if in url there are duplicated slashes show 404 page instead
542
+ if (InstaPageCmsPluginHelper::checkIfRequestUriHasDuplicatedSlashes()) {
543
+ self::return404();
544
+ return false;
545
+ }
546
+
547
+ if ($type == '404') {
548
+ $page->display($result, 404);
549
+ } else {
550
+ $page->display($result);
551
+ }
552
+ }
553
+ }
554
+
555
+ /**
556
+ * Checks (and displays) if a landing page marked as homepage should be displayed instead of normal CMS homepage.
557
+ *
558
+ * @uses InstapageCmsPluginWPConnector::checkPage()
559
+ */
560
+ public function checkHomepage() {
561
+ $homeUrl = str_replace(array('http://', 'https://'), '', rtrim($this->getHomeURL(), '/'));
562
+ $homeUrlSegments = explode('/', $homeUrl);
563
+ $uriSegments = explode('?', $_SERVER['REQUEST_URI']);
564
+ $uriSegments = explode('/', rtrim($uriSegments[0], '/'));
565
+
566
+ if (
567
+ (count($uriSegments) !== count($homeUrlSegments)) ||
568
+ (count($homeUrlSegments) > 1 && $homeUrlSegments[1] != $uriSegments[1])
569
+ ) {
570
+ return false;
571
+ }
572
+
573
+ $this->checkPage('home');
574
+
575
+ return true;
576
+ }
577
+
578
+ /**
579
+ * Checks (and displays) if a landing page marked as 404 should be displayed instead of normal CMS 404 page.
580
+ *
581
+ * @uses InstapageCmsPluginWPConnector::checkPage()
582
+ */
583
+ public function check404() {
584
+ if (is_404()) {
585
+ $this->checkPage('404');
586
+
587
+ return true;
588
+ }
589
+
590
+ return false;
591
+ }
592
+
593
+ /**
594
+ * Return 404 page using native wordpress method.
595
+ *
596
+ * Return 404 page using native wordpress method and
597
+ * prevent from any 301 redirection like removing duplicated slashes
598
+ * guessing url etc. Those 301 redirects are native wordpress functionality.
599
+ */
600
+ public static function return404() {
601
+ global $wp_query;
602
+
603
+ // remove redirections
604
+ remove_filter('template_redirect', 'redirect_canonical');
605
+
606
+ // Guess it's time to 404.
607
+ $wp_query->set_404();
608
+ }
609
+
610
+ /**
611
+ * Checks (and displays) if a landing page hould be displayed instead of normal CMS page under current URL.
612
+ *
613
+ * @uses InstapageCmsPluginWPConnector::checkPage()
614
+ */
615
+ public function checkCustomUrl() {
616
+ $slug = InstapageCmsPluginHelper::extractSlug($this->getHomeURL());
617
+
618
+ if ($slug) {
619
+ $this->checkPage('page', $slug);
620
+ }
621
+
622
+ return true;
623
+ }
624
+
625
+ /**
626
+ * Checks (and processes it) if a lcurrent request should be processes by plugin's proxy.
627
+ */
628
+ public function checkProxy() {
629
+ $services = InstapageCmsPluginServicesModel::getInstance();
630
+
631
+ if ($services->isServicesRequest()) {
632
+ try {
633
+ $services->processProxyServices();
634
+
635
+ return;
636
+ } catch (Exception $e) {
637
+ echo $e->getMessage();
638
+ }
639
+ }
640
+ }
641
+
642
+ /**
643
+ * get list of slugs that can't be used to publish a landing page.
644
+ * @deprecated
645
+ * @return array List of prohibitted slugs.
646
+ */
647
+ public function getProhibitedSlugs() {
648
+ $result = array_merge($this->getPostSlugs(), $this->getTermSlugs(), $this->getPageSlugs(), InstapageCmsPluginConnector::getLandingPageSlugs());
649
+ return $result;
650
+ }
651
+
652
+ /**
653
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
654
+ * @param string $slug Slug to be checked
655
+ * @uses self::isProhibitedPostSlug()
656
+ * @uses self::isProhibitedTermSlug()
657
+ * @uses self::isProhibitedPageSlug()
658
+ * @uses InstapageCmsPluginConnector::isProhibitedLandingPageSlug()
659
+ * @return bool|array
660
+ */
661
+ public function isProhibitedSlug($slug) {
662
+ $postSlug = $this->isProhibitedPostSlug($slug);
663
+ if ($postSlug) {
664
+ return $postSlug;
665
+ }
666
+
667
+ $termSlug = $this->isProhibitedTermSlug($slug);
668
+ if ($termSlug) {
669
+ return $termSlug;
670
+ }
671
+
672
+ $pageSlug = $this->isProhibitedPageSlug($slug);
673
+ if ($pageSlug) {
674
+ return $pageSlug;
675
+ }
676
+
677
+ $landingPageSlug = InstapageCmsPluginConnector::isProhibitedLandingPageSlug($slug);
678
+ if ($landingPageSlug) {
679
+ return $landingPageSlug;
680
+ }
681
+
682
+ return false;
683
+ }
684
+
685
+ /**
686
+ * Gets the HTML for CMS options.
687
+ *
688
+ * @return string HTML to include in the debug log.
689
+ */
690
+ public function getOptionsDebugHTML() {
691
+ $necessaryOptions = array(
692
+ 'siteurl',
693
+ 'home',
694
+ 'permalink_structure',
695
+ 'blog_charset',
696
+ 'template',
697
+ 'db_version',
698
+ 'initial_db_version'
699
+ );
700
+
701
+ foreach ($necessaryOptions as $opt) {
702
+ $options[$opt] = get_option($opt, 'n/a');
703
+ }
704
+
705
+ $view = InstapageCmsPluginViewModel::getInstance();
706
+ $view->init(INSTAPAGE_PLUGIN_PATH .'/templates/log_options.php');
707
+ $view->rows = $options;
708
+
709
+ return $view->fetch();
710
+ }
711
+
712
+ /**
713
+ * Gets the HTML for CMS plugins/modules.
714
+ *
715
+ * @return string HTML to include in the debug log.
716
+ */
717
+ public function getPluginsDebugHTML() {
718
+ $allPlugins = get_plugins();
719
+ $view = InstapageCmsPluginViewModel::getInstance();
720
+ $view->init(INSTAPAGE_PLUGIN_PATH . '/templates/log_plugins.php');
721
+ $view->rows = $allPlugins;
722
+
723
+ return $view->fetch();
724
+ }
725
+
726
+ /**
727
+ * Gets the sitename from CMS config.
728
+ *
729
+ * @return string Sitename.
730
+ */
731
+ public function getSitename($sanitized = false) {
732
+ $sitename = get_bloginfo('name');
733
+
734
+ return ($sanitized) ? sanitize_title($sitename) : $sitename;
735
+ }
736
+
737
+ /**
738
+ * Sends an e-mail using CMS native email sending method.
739
+ *
740
+ * @param string $to Receiver address.
741
+ * @param string $subject A subject.
742
+ * @param string $message A message.
743
+ * @param string $headers Message headers. Default: ''.
744
+ * @param aray $attachments Attachments.
745
+ *
746
+ * @return bool True on success.
747
+ */
748
+ public function mail($to, $subject, $message, $headers = '', $attachments = array()) {
749
+ return wp_mail($to, $subject, $message, $headers, $attachments);
750
+ }
751
+
752
+ /**
753
+ * Gets the landing pages saved in legacy DB structure.
754
+ *
755
+ * @return array List of landing pages from legacy DB structure.
756
+ */
757
+ public function getDeprecatedData() {
758
+ global $wpdb;
759
+
760
+ $sql = "SELECT {$wpdb->posts}.ID, {$wpdb->postmeta}.meta_key, {$wpdb->postmeta}.meta_value FROM {$wpdb->posts} INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id) WHERE ({$wpdb->posts}.post_type = %s) AND ({$wpdb->posts}.post_status = 'publish') AND ({$wpdb->postmeta}.meta_key IN ('instapage_my_selected_page', 'instapage_name', 'instapage_my_selected_page', 'instapage_slug'))";
761
+
762
+ $rows = $this->getResults($sql, 'instapage_post');
763
+ $posts = array();
764
+
765
+ foreach ($rows as $row) {
766
+ if (!array_key_exists($row->ID, $posts)) {
767
+ $posts[$row->ID] = array();
768
+ }
769
+
770
+ $posts[$row->ID][$row->meta_key] = $row->meta_value;
771
+ }
772
+
773
+ $results = array();
774
+
775
+ foreach ($posts as $post) {
776
+ $pageObj = new stdClass;
777
+ $pageObj->id = 0;
778
+ $pageObj->landingPageId = $post['instapage_my_selected_page'];
779
+ $pageObj->slug = $post['instapage_slug'];
780
+ $pageObj->type = 'page';
781
+ $pageObj->enterprise_url = $pageObj->slug ? InstapageCmsPluginConnector::getHomeURL() . '/' . $pageObj->slug : InstapageCmsPluginConnector::getHomeURL();
782
+ $results[] = $pageObj;
783
+ }
784
+
785
+ $frontPageId = get_option('instapage_front_page_id', false);
786
+
787
+ if ($frontPageId) {
788
+ $pageObj = new stdClass;
789
+ $pageObj->id = 0;
790
+ $pageObj->landingPageId = $frontPageId;
791
+ $pageObj->slug = '';
792
+ $pageObj->type = 'home';
793
+ $pageObj->enterprise_url = InstapageCmsPluginConnector::getHomeURL();
794
+ $results[] = $pageObj;
795
+ }
796
+
797
+ $notFoundId = get_option('instapage_404_page_id', false);
798
+
799
+ if ($notFoundId) {
800
+ $page = InstapageCmsPluginPageModel::getInstance();
801
+ $pageObj = new stdClass;
802
+ $pageObj->id = 0;
803
+ $pageObj->landingPageId = $notFoundId;
804
+ $pageObj->slug = $page->getRandomSlug();
805
+ $pageObj->type = '404';
806
+ $pageObj->enterprise_url = InstapageCmsPluginConnector::getHomeURL() . '/' . $pageObj->slug;
807
+ $results[] = $pageObj;
808
+ }
809
+
810
+ return $results;
811
+ }
812
+
813
+ /**
814
+ * Properly escapes the HTML.
815
+ *
816
+ * @param string $html HTML to escape.
817
+ *
818
+ * @return string Escaped HTML.
819
+ */
820
+ public function escapeHTML($html) {
821
+ return esc_html($html);
822
+ }
823
+
824
+ /**
825
+ * Checks if any landing page is present in legacy DB structure.
826
+ *
827
+ * @return bool True if there are pages in legacy DB structure.
828
+ */
829
+ public function legacyArePagesPresent() {
830
+ global $wpdb;
831
+
832
+ $sql = "SELECT COUNT({$wpdb->posts}.ID) AS page_count FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_type = %s AND {$wpdb->posts}.post_status = 'publish'";
833
+ $row = $wpdb->get_row($wpdb->prepare($sql, 'instapage_post'));
834
+
835
+ if (isset($row->page_count) && $row->page_count > 0) {
836
+ return true;
837
+ }
838
+
839
+ return false;
840
+ }
841
+
842
+ /**
843
+ * Checks if there is a need to replace content of CMS with a landing page. Prevents content replacement on admin/login pages.
844
+ *
845
+ * @return bool True if replace is possible.
846
+ */
847
+ public function isHtmlReplaceNecessary() {
848
+ if (is_admin() || $this->isLoginPage() || InstapageCmsPluginHelper::isCustomParamPresent()) {
849
+ InstapageCmsPluginHelper::writeDiagnostics('is_admin || isLoginPage || isCustomParamPresent', 'HTML Replace is not necessary');
850
+
851
+ return false;
852
+ }
853
+
854
+ return true;
855
+ }
856
+
857
+ /**
858
+ * Pulls the data from legacy DB structure.
859
+ *
860
+ * @param string $slug Slug of a page, that we want to pull.
861
+ *
862
+ * @return object Landing page object.
863
+ */
864
+ public function legacyGetPage($slug) {
865
+ global $wpdb;
866
+ $result = new stdClass;
867
+ $result->slug = $slug;
868
+ $result->enterprise_url = $slug ? InstapageCmsPluginConnector::getHomeURL() . '/' . $slug : InstapageCmsPluginConnector::getHomeURL();
869
+
870
+ $sql = "SELECT {$wpdb->posts}.ID, {$wpdb->postmeta}.meta_key, {$wpdb->postmeta}.meta_value FROM {$wpdb->posts} INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id) WHERE ({$wpdb->posts}.post_type = %s) AND ({$wpdb->posts}.post_status = 'publish') AND ({$wpdb->postmeta}.meta_key IN ('instapage_my_selected_page', 'instapage_name', 'instapage_my_selected_page', 'instapage_slug'))";
871
+
872
+ $rows = $wpdb->get_results($wpdb->prepare($sql, 'instapage_post'));
873
+ $posts = array();
874
+
875
+ foreach ($rows as $row) {
876
+ if (!array_key_exists($row->ID, $posts)) {
877
+ $posts[$row->ID] = array();
878
+ }
879
+
880
+ $posts[$row->ID][$row->meta_key] = $row->meta_value;
881
+ }
882
+
883
+ foreach ($posts as $post) {
884
+ if (isset($post['instapage_slug']) && $post['instapage_slug'] == $slug) {
885
+ $result->instapage_id = isset($post['instapage_my_selected_page']) ? $post['instapage_my_selected_page'] : 0;
886
+
887
+ return $result;
888
+ }
889
+ }
890
+
891
+ $result->instapage_id = 0;
892
+
893
+ return $result;
894
+ }
895
+
896
+ /**
897
+ * Gets the settings module, a CMS-dependant part of the Settings page.
898
+ * @uses InstapageCmsPluginConnector::getCmsVersion()
899
+ * @uses InstapageCmsPluginConnector::lang()
900
+ * @uses InstapageCmsPluginConnector::getPluginRequirements()
901
+ * @return string HTML form with settings for currently used CMS only.
902
+ */
903
+ public function getSettingsModule() {
904
+ ob_start();
905
+ ?>
906
+ <div class="custom-params-form ui-section">
907
+ <h3 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Support legacy pages'); ?></h3>
908
+ <p class="l-space-bottom-primary"><?php echo InstapageCmsPluginConnector::lang('Instapage plugin will search for landing pages in old database structure (before 3.0 update). After successful migration this option should not be used.'); ?></p>
909
+ <label class="c-mark">
910
+ <input class="c-mark__input" data-bind="checked: supportLegacy, click: autoSaveMetadata" type="checkbox" >
911
+ <i class="c-mark__icon c-mark__icon--checkbox material-icons">check</i>
912
+ <span class="c-mark__label"><?php echo InstapageCmsPluginConnector::lang('Turn on legacy support.'); ?></span>
913
+ </label>
914
+ </div>
915
+ <?php
916
+ $html = ob_get_contents();
917
+ $html .= InstapageCmsPluginConnector::getPluginRequirements(array(array('label' => InstapageCmsPluginConnector::lang('Wordpress 3.4+'), 'condition' => version_compare(InstapageCmsPluginConnector::getCMSVersion(), '3.4.0', '>='))));
918
+ ob_end_clean();
919
+
920
+ return $html;
921
+ }
922
+
923
+ /**
924
+ * Checks if last executed query resulted in an SQL error. Error is saved in the debug log.
925
+ *
926
+ * @return bool True if there was an SQL error.
927
+ */
928
+ private function checkLastQuery() {
929
+ global $wpdb;
930
+ $db = InstapageCmsPluginDBModel::getInstance();
931
+
932
+ if (strpos($wpdb->last_query, $db->debugTable) === false && $wpdb->last_error !== '') {
933
+ $messages = array(
934
+ 'Query: ' . $wpdb->last_query,
935
+ 'Error: ' . $wpdb->last_error
936
+ );
937
+
938
+ InstapageCmsPluginHelper::writeDiagnostics(implode("\n", $messages), 'DB Error');
939
+
940
+ return false;
941
+ }
942
+
943
+ return true;
944
+ }
945
+
946
+ /**
947
+ * Gets the list of slugs used by WP posts.
948
+ * @deprecated
949
+ * @return array List of slugs used by posts.
950
+ */
951
+ private function getPostSlugs() {
952
+ $postPrefix = '';
953
+ $editUrl = $this->getSiteURL() . '/wp-admin/post.php?action=edit&post=';
954
+ $dbPrefix = $this->getDBPrefix();
955
+ $sql = 'SELECT ID AS id, CONCAT(\'' . $editUrl . '\', ID) AS editUrl FROM ' . $dbPrefix . 'posts WHERE post_type = \'post\' AND post_name <> \'\'';
956
+ $results = $this->getResults($sql);
957
+
958
+ if (is_array($results) && !empty($results)) {
959
+ $siteUrl = get_home_url() . '/';
960
+
961
+ foreach ($results as &$result) {
962
+ $result->slug = trim(str_replace($siteUrl, '', get_permalink($result->id)), '/');
963
+ }
964
+ }
965
+
966
+ return $results;
967
+ }
968
+
969
+ /**
970
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
971
+ * @param string $slug Slug to be checked
972
+ * @uses self::getSiteURL()
973
+ * @uses self::getDBPrefix()
974
+ * @uses self::getResults()
975
+ * @return bool|array
976
+ */
977
+ private function isProhibitedPostSlug($slug) {
978
+ $postPrefix = '';
979
+ $editUrl = $this->getSiteURL() . '/wp-admin/post.php?action=edit&post=';
980
+ $dbPrefix = $this->getDBPrefix();
981
+ $sql = 'SELECT ID AS id, CONCAT(\'' . $editUrl . '\', ID) AS editUrl FROM ' . $dbPrefix . 'posts WHERE post_type = \'post\' AND post_name = \'%s\' LIMIT 1';
982
+ $results = $this->getResults($sql, $slug);
983
+
984
+ if (is_array($results) && !empty($results)) {
985
+ $siteUrl = get_home_url() . '/';
986
+
987
+ foreach ($results as &$result) {
988
+ $result->slug = trim(str_replace($siteUrl, '', get_permalink($result->id)), '/');
989
+ }
990
+ }
991
+
992
+ return $results;
993
+ }
994
+
995
+
996
+ /**
997
+ * Gets the list of slugs used by WP terms.
998
+ * @deprecated
999
+ * @return array List of slugs used by terms.
1000
+ */
1001
+ private function getTermSlugs() {
1002
+ $editUrl1 = $this->getSiteURL() . '/wp-admin/edit-tags.php?action=edit&post_type=post&taxonomy=';
1003
+ $editUrl2 = '&tag_ID=';
1004
+ $dbPrefix = $this->getDBPrefix();
1005
+ $sql = 'SELECT t.term_id AS id, t.slug AS slug, CONCAT(\'' . $editUrl1 . '\', tt.taxonomy, \'' . $editUrl2 . '\', t.term_id) AS editUrl ' .
1006
+ 'FROM ' . $dbPrefix . 'terms t LEFT JOIN ' . $dbPrefix . 'term_taxonomy tt ON t.term_id = tt.term_id ' .
1007
+ 'WHERE (tt.taxonomy = \'category\' OR tt.taxonomy = \'post_tag\')' .
1008
+ 'AND t.slug <> \'\'';
1009
+ $results = $this->getResults($sql);
1010
+
1011
+ return $results;
1012
+ }
1013
+
1014
+ /**
1015
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
1016
+ * @param string $slug Slug to be checked
1017
+ * @uses self::getSiteURL()
1018
+ * @uses self::getDBPrefix()
1019
+ * @uses self::getResults()
1020
+ * @return bool|array
1021
+ */
1022
+ private function isProhibitedTermSlug($slug) {
1023
+ $editUrl1 = $this->getSiteURL() . '/wp-admin/edit-tags.php?action=edit&post_type=post&taxonomy=';
1024
+ $editUrl2 = '&tag_ID=';
1025
+ $dbPrefix = $this->getDBPrefix();
1026
+ $sql = 'SELECT t.term_id AS id, t.slug AS slug, CONCAT(\'' . $editUrl1 . '\', tt.taxonomy, \'' . $editUrl2 . '\', t.term_id) AS editUrl ' .
1027
+ 'FROM ' . $dbPrefix . 'terms t LEFT JOIN ' . $dbPrefix . 'term_taxonomy tt ON t.term_id = tt.term_id ' .
1028
+ 'WHERE (tt.taxonomy = \'category\' OR tt.taxonomy = \'post_tag\')' .
1029
+ 'AND t.slug = \'%s\' LIMIT 1';
1030
+ $results = $this->getResults($sql, $slug);
1031
+
1032
+ return $results;
1033
+ }
1034
+
1035
+ /**
1036
+ * Pulls slugs used by WordPress pages.
1037
+ * @deprecated
1038
+ * @return array List of slugs used by pages.
1039
+ */
1040
+ private function getPageSlugs() {
1041
+ $editUrl = $this->getSiteURL() . '/wp-admin/post.php?action=edit&post=';
1042
+ $dbPrefix = $this->getDBPrefix();
1043
+ $sql = 'SELECT ID AS id, post_name AS slug, CONCAT(\'' . $editUrl . '\', ID) AS editUrl FROM ' . $dbPrefix . 'posts WHERE post_type = \'page\' AND post_name <> \'\' ';
1044
+ $results = $this->getResults($sql);
1045
+
1046
+ return $results;
1047
+ }
1048
+
1049
+ /**
1050
+ * Checks if given slug is prohibited in terms of publishing a landing page. If it's free - will return false. Otherwise an array with slug details will be returned
1051
+ * @param string $slug Slug to be checked
1052
+ * @uses self::getSiteURL()
1053
+ * @uses self::getDBPrefix()
1054
+ * @uses self::getResults()
1055
+ * @return bool|array
1056
+ */
1057
+ private function isProhibitedPageSlug($slug) {
1058
+ $editUrl = $this->getSiteURL() . '/wp-admin/post.php?action=edit&post=';
1059
+ $dbPrefix = $this->getDBPrefix();
1060
+ $sql = 'SELECT ID AS id, post_name AS slug, CONCAT(\'' . $editUrl . '\', ID) AS editUrl FROM ' . $dbPrefix . 'posts WHERE post_type = \'page\' AND post_name = \'%s\' LIMIT 1';
1061
+ $results = $this->getResults($sql, $slug);
1062
+
1063
+ return $results;
1064
+ }
1065
+
1066
+ /**
1067
+ * Checks if current URL is plugin's dashboard.
1068
+ *
1069
+ * @return boolean
1070
+ */
1071
+ private function isInstapagePluginDashboard() {
1072
+ if (isset($_REQUEST['page']) && $_REQUEST['page'] == 'instapage_dashboard') {
1073
+ return true;
1074
+ }
1075
+
1076
+ return false;
1077
+ }
1078
+
1079
+ /**
1080
+ * Prepares the remote request response to unify response object in all integrated CMSes.
1081
+ *
1082
+ * @param object $request Request result.
1083
+ *
1084
+ * @return array Standard Instapage plugin request response array.
1085
+ */
1086
+ private function prepareResponse($request) {
1087
+ $headers = @InstapageCmsPluginHelper::getVar($request['headers'], null);
1088
+
1089
+ if (is_object($headers) && get_class($headers) == 'Requests_Utility_CaseInsensitiveDictionary') {
1090
+ $headers = $headers->getAll();
1091
+ }
1092
+
1093
+ $responseCode = @InstapageCmsPluginHelper::getVar($request['status_code'], 0);
1094
+
1095
+ if (!$responseCode) {
1096
+ $responseCode = @InstapageCmsPluginHelper::getVar($request['response']['code'], 200);
1097
+ }
1098
+
1099
+ $status = @InstapageCmsPluginHelper::getVar($request['status'], '');
1100
+
1101
+ if (!$status) {
1102
+ $status = @InstapageCmsPluginHelper::getVar($request['response']['message'], '');
1103
+ }
1104
+
1105
+ return array(
1106
+ 'body' => @InstapageCmsPluginHelper::getVar($request['body'], ''),
1107
+ 'status' => $status,
1108
+ 'code' => $responseCode,
1109
+ 'headers' => $headers
1110
+ );
1111
+ }
1112
+ }
instapage.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Plugin Name: Instapage Plugin
5
+ Description: The best way for WordPress to seamlessly publish landing pages as a natural extension of your website.
6
+ Version: 3.2.11
7
+ Requires PHP: 5.2.4
8
+ Plugin URI: https://instapage.com/
9
+ Author: Instapage
10
+ Author URI: https://instapage.com/
11
+ License: GPLv2
12
+ */
13
+
14
+ define('INSTAPAGE_PLUGIN_PATH', dirname(__FILE__));
15
+ define('INSTAPAGE_PLUGIN_FILE', __FILE__);
16
+ define('INSTAPAGE_SUPPORT_EMAIL', 'help@instapage.com');
17
+ define('MINIUM_PHP_VERSION', '5.2.4');
18
+
19
+ /**
20
+ * @var array $consts Holds constant names to be defined with their default values - if not already defined or found in `$_ENV`
21
+ */
22
+ $consts = array(
23
+ 'INSTAPAGE_ENTERPRISE_ENDPOINT' => 'http://pageserve.co',
24
+ 'INSTAPAGE_PROXY_ENDPOINT' => 'http://app.instapage.com',
25
+ 'INSTAPAGE_APP_ENDPOINT' => 'http://app.instapage.com/api/plugin'
26
+ );
27
+
28
+ foreach ($consts as $key => $value) {
29
+ if (!defined($key)) {
30
+ define($key, (isset($_ENV[$key]) && !empty($_ENV[$key])) ? $_ENV[$key] : $value);
31
+ }
32
+ }
33
+
34
+ require_once(INSTAPAGE_PLUGIN_PATH . '/connectors/InstapageCmsPluginConnector.php');
35
+ require_once(INSTAPAGE_PLUGIN_PATH . '/InstapageCmsPluginHelper.php');
36
+ require_once(INSTAPAGE_PLUGIN_PATH . '/models/InstapageCmsPluginDBModel.php');
37
+ require_once(INSTAPAGE_PLUGIN_PATH . '/models/InstapageCmsPluginAPIModel.php');
38
+ require_once(INSTAPAGE_PLUGIN_PATH . '/models/InstapageCmsPluginPageModel.php');
39
+ require_once(INSTAPAGE_PLUGIN_PATH . '/models/InstapageCmsPluginServicesModel.php');
40
+ require_once(INSTAPAGE_PLUGIN_PATH . '/models/InstapageCmsPluginDebugLogModel.php');
41
+ require_once(INSTAPAGE_PLUGIN_PATH . '/models/InstapageCmsPluginViewModel.php');
42
+ require_once(INSTAPAGE_PLUGIN_PATH . '/models/InstapageCmsPluginSubaccountModel.php');
43
+ require_once(INSTAPAGE_PLUGIN_PATH . '/InstapageCmsPluginAjaxController.php');
44
+
45
+ InstapageCmsPluginConnector::initPlugin();
knockout/core/knockout-3.4.0.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Knockout JavaScript library v3.4.0
3
+ * (c) Steven Sanderson - http://knockoutjs.com/
4
+ * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
+ */
6
+
7
+ (function() {(function(n){var x=this||(0,eval)("this"),u=x.document,M=x.navigator,v=x.jQuery,F=x.JSON;(function(n){"function"===typeof define&&define.amd?define(["exports","require"],n):"object"===typeof exports&&"object"===typeof module?n(module.exports||exports):n(x.ko={})})(function(N,O){function J(a,c){return null===a||typeof a in T?a===c:!1}function U(b,c){var d;return function(){d||(d=a.a.setTimeout(function(){d=n;b()},c))}}function V(b,c){var d;return function(){clearTimeout(d);d=a.a.setTimeout(b,c)}}function W(a,
8
+ c){c&&c!==I?"beforeChange"===c?this.Kb(a):this.Ha(a,c):this.Lb(a)}function X(a,c){null!==c&&c.k&&c.k()}function Y(a,c){var d=this.Hc,e=d[s];e.R||(this.lb&&this.Ma[c]?(d.Pb(c,a,this.Ma[c]),this.Ma[c]=null,--this.lb):e.r[c]||d.Pb(c,a,e.s?{ia:a}:d.uc(a)))}function K(b,c,d,e){a.d[b]={init:function(b,g,k,l,m){var h,r;a.m(function(){var q=a.a.c(g()),p=!d!==!q,A=!r;if(A||c||p!==h)A&&a.va.Aa()&&(r=a.a.ua(a.f.childNodes(b),!0)),p?(A||a.f.da(b,a.a.ua(r)),a.eb(e?e(m,q):m,b)):a.f.xa(b),h=p},null,{i:b});return{controlsDescendantBindings:!0}}};
9
+ a.h.ta[b]=!1;a.f.Z[b]=!0}var a="undefined"!==typeof N?N:{};a.b=function(b,c){for(var d=b.split("."),e=a,f=0;f<d.length-1;f++)e=e[d[f]];e[d[d.length-1]]=c};a.G=function(a,c,d){a[c]=d};a.version="3.4.0";a.b("version",a.version);a.options={deferUpdates:!1,useOnlyNativeEvents:!1};a.a=function(){function b(a,b){for(var c in a)a.hasOwnProperty(c)&&b(c,a[c])}function c(a,b){if(b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function d(a,b){a.__proto__=b;return a}function e(b,c,d,e){var h=b[c].match(r)||
10
+ [];a.a.q(d.match(r),function(b){a.a.pa(h,b,e)});b[c]=h.join(" ")}var f={__proto__:[]}instanceof Array,g="function"===typeof Symbol,k={},l={};k[M&&/Firefox\/2/i.test(M.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];k.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" ");b(k,function(a,b){if(b.length)for(var c=0,d=b.length;c<d;c++)l[b[c]]=a});var m={propertychange:!0},h=u&&function(){for(var a=3,b=u.createElement("div"),c=
11
+ b.getElementsByTagName("i");b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e",c[0];);return 4<a?a:n}(),r=/\S+/g;return{cc:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],q:function(a,b){for(var c=0,d=a.length;c<d;c++)b(a[c],c)},o:function(a,b){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,b);for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},Sb:function(a,b,c){for(var d=0,e=a.length;d<e;d++)if(b.call(c,a[d],d))return a[d];
12
+ return null},La:function(b,c){var d=a.a.o(b,c);0<d?b.splice(d,1):0===d&&b.shift()},Tb:function(b){b=b||[];for(var c=[],d=0,e=b.length;d<e;d++)0>a.a.o(c,b[d])&&c.push(b[d]);return c},fb:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)c.push(b(a[d],d));return c},Ka:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)b(a[d],d)&&c.push(a[d]);return c},ra:function(a,b){if(b instanceof Array)a.push.apply(a,b);else for(var c=0,d=b.length;c<d;c++)a.push(b[c]);return a},pa:function(b,c,d){var e=
13
+ a.a.o(a.a.zb(b),c);0>e?d&&b.push(c):d||b.splice(e,1)},ka:f,extend:c,Xa:d,Ya:f?d:c,D:b,Ca:function(a,b){if(!a)return a;var c={},d;for(d in a)a.hasOwnProperty(d)&&(c[d]=b(a[d],d,a));return c},ob:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},jc:function(b){b=a.a.V(b);for(var c=(b[0]&&b[0].ownerDocument||u).createElement("div"),d=0,e=b.length;d<e;d++)c.appendChild(a.$(b[d]));return c},ua:function(b,c){for(var d=0,e=b.length,h=[];d<e;d++){var m=b[d].cloneNode(!0);h.push(c?a.$(m):m)}return h},
14
+ da:function(b,c){a.a.ob(b);if(c)for(var d=0,e=c.length;d<e;d++)b.appendChild(c[d])},qc:function(b,c){var d=b.nodeType?[b]:b;if(0<d.length){for(var e=d[0],h=e.parentNode,m=0,l=c.length;m<l;m++)h.insertBefore(c[m],e);m=0;for(l=d.length;m<l;m++)a.removeNode(d[m])}},za:function(a,b){if(a.length){for(b=8===b.nodeType&&b.parentNode||b;a.length&&a[0].parentNode!==b;)a.splice(0,1);for(;1<a.length&&a[a.length-1].parentNode!==b;)a.length--;if(1<a.length){var c=a[0],d=a[a.length-1];for(a.length=0;c!==d;)a.push(c),
15
+ c=c.nextSibling;a.push(d)}}return a},sc:function(a,b){7>h?a.setAttribute("selected",b):a.selected=b},$a:function(a){return null===a||a===n?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},nd:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},Mc:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=
16
+ b;)a=a.parentNode;return!!a},nb:function(b){return a.a.Mc(b,b.ownerDocument.documentElement)},Qb:function(b){return!!a.a.Sb(b,a.a.nb)},A:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},Wb:function(b){return a.onError?function(){try{return b.apply(this,arguments)}catch(c){throw a.onError&&a.onError(c),c;}}:b},setTimeout:function(b,c){return setTimeout(a.a.Wb(b),c)},$b:function(b){setTimeout(function(){a.onError&&a.onError(b);throw b;},0)},p:function(b,c,d){var e=a.a.Wb(d);d=h&&m[c];if(a.options.useOnlyNativeEvents||
17
+ d||!v)if(d||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var l=function(a){e.call(b,a)},f="on"+c;b.attachEvent(f,l);a.a.F.oa(b,function(){b.detachEvent(f,l)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,e,!1);else v(b).bind(c,e)},Da:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var d;"input"===a.a.A(b)&&b.type&&"click"==c.toLowerCase()?(d=b.type,d="checkbox"==
18
+ d||"radio"==d):d=!1;if(a.options.useOnlyNativeEvents||!v||d)if("function"==typeof u.createEvent)if("function"==typeof b.dispatchEvent)d=u.createEvent(l[c]||"HTMLEvents"),d.initEvent(c,!0,!0,x,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(d);else throw Error("The supplied element doesn't support dispatchEvent");else if(d&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");else v(b).trigger(c)},c:function(b){return a.H(b)?
19
+ b():b},zb:function(b){return a.H(b)?b.t():b},bb:function(b,c,d){var h;c&&("object"===typeof b.classList?(h=b.classList[d?"add":"remove"],a.a.q(c.match(r),function(a){h.call(b.classList,a)})):"string"===typeof b.className.baseVal?e(b.className,"baseVal",c,d):e(b,"className",c,d))},Za:function(b,c){var d=a.a.c(c);if(null===d||d===n)d="";var e=a.f.firstChild(b);!e||3!=e.nodeType||a.f.nextSibling(e)?a.f.da(b,[b.ownerDocument.createTextNode(d)]):e.data=d;a.a.Rc(b)},rc:function(a,b){a.name=b;if(7>=h)try{a.mergeAttributes(u.createElement("<input name='"+
20
+ a.name+"'/>"),!1)}catch(c){}},Rc:function(a){9<=h&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},Nc:function(a){if(h){var b=a.style.width;a.style.width=0;a.style.width=b}},hd:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var d=[],e=b;e<=c;e++)d.push(e);return d},V:function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push(a[c]);return b},Yb:function(a){return g?Symbol(a):a},rd:6===h,sd:7===h,C:h,ec:function(b,c){for(var d=a.a.V(b.getElementsByTagName("input")).concat(a.a.V(b.getElementsByTagName("textarea"))),
21
+ e="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},h=[],m=d.length-1;0<=m;m--)e(d[m])&&h.push(d[m]);return h},ed:function(b){return"string"==typeof b&&(b=a.a.$a(b))?F&&F.parse?F.parse(b):(new Function("return "+b))():null},Eb:function(b,c,d){if(!F||!F.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
22
+ return F.stringify(a.a.c(b),c,d)},fd:function(c,d,e){e=e||{};var h=e.params||{},m=e.includeFields||this.cc,l=c;if("object"==typeof c&&"form"===a.a.A(c))for(var l=c.action,f=m.length-1;0<=f;f--)for(var g=a.a.ec(c,m[f]),k=g.length-1;0<=k;k--)h[g[k].name]=g[k].value;d=a.a.c(d);var r=u.createElement("form");r.style.display="none";r.action=l;r.method="post";for(var n in d)c=u.createElement("input"),c.type="hidden",c.name=n,c.value=a.a.Eb(a.a.c(d[n])),r.appendChild(c);b(h,function(a,b){var c=u.createElement("input");
23
+ c.type="hidden";c.name=a;c.value=b;r.appendChild(c)});u.body.appendChild(r);e.submitter?e.submitter(r):r.submit();setTimeout(function(){r.parentNode.removeChild(r)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.q);a.b("utils.arrayFirst",a.a.Sb);a.b("utils.arrayFilter",a.a.Ka);a.b("utils.arrayGetDistinctValues",a.a.Tb);a.b("utils.arrayIndexOf",a.a.o);a.b("utils.arrayMap",a.a.fb);a.b("utils.arrayPushAll",a.a.ra);a.b("utils.arrayRemoveItem",a.a.La);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost",
24
+ a.a.cc);a.b("utils.getFormFields",a.a.ec);a.b("utils.peekObservable",a.a.zb);a.b("utils.postJson",a.a.fd);a.b("utils.parseJson",a.a.ed);a.b("utils.registerEventHandler",a.a.p);a.b("utils.stringifyJson",a.a.Eb);a.b("utils.range",a.a.hd);a.b("utils.toggleDomNodeCssClass",a.a.bb);a.b("utils.triggerEvent",a.a.Da);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.D);a.b("utils.addOrRemoveItem",a.a.pa);a.b("utils.setTextContent",a.a.Za);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=
25
+ function(a){var c=this;if(1===arguments.length)return function(){return c.apply(a,arguments)};var d=Array.prototype.slice.call(arguments,1);return function(){var e=d.slice(0);e.push.apply(e,arguments);return c.apply(a,e)}});a.a.e=new function(){function a(b,g){var k=b[d];if(!k||"null"===k||!e[k]){if(!g)return n;k=b[d]="ko"+c++;e[k]={}}return e[k]}var c=0,d="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===n?n:e[d]},set:function(c,d,e){if(e!==n||a(c,!1)!==n)a(c,!0)[d]=
26
+ e},clear:function(a){var b=a[d];return b?(delete e[b],a[d]=null,!0):!1},I:function(){return c++ +d}}};a.b("utils.domData",a.a.e);a.b("utils.domData.clear",a.a.e.clear);a.a.F=new function(){function b(b,c){var e=a.a.e.get(b,d);e===n&&c&&(e=[],a.a.e.set(b,d,e));return e}function c(d){var e=b(d,!1);if(e)for(var e=e.slice(0),l=0;l<e.length;l++)e[l](d);a.a.e.clear(d);a.a.F.cleanExternalData(d);if(f[d.nodeType])for(e=d.firstChild;d=e;)e=d.nextSibling,8===d.nodeType&&c(d)}var d=a.a.e.I(),e={1:!0,8:!0,9:!0},
27
+ f={1:!0,9:!0};return{oa:function(a,c){if("function"!=typeof c)throw Error("Callback must be a function");b(a,!0).push(c)},pc:function(c,e){var l=b(c,!1);l&&(a.a.La(l,e),0==l.length&&a.a.e.set(c,d,n))},$:function(b){if(e[b.nodeType]&&(c(b),f[b.nodeType])){var d=[];a.a.ra(d,b.getElementsByTagName("*"));for(var l=0,m=d.length;l<m;l++)c(d[l])}return b},removeNode:function(b){a.$(b);b.parentNode&&b.parentNode.removeChild(b)},cleanExternalData:function(a){v&&"function"==typeof v.cleanData&&v.cleanData([a])}}};
28
+ a.$=a.a.F.$;a.removeNode=a.a.F.removeNode;a.b("cleanNode",a.$);a.b("removeNode",a.removeNode);a.b("utils.domNodeDisposal",a.a.F);a.b("utils.domNodeDisposal.addDisposeCallback",a.a.F.oa);a.b("utils.domNodeDisposal.removeDisposeCallback",a.a.F.pc);(function(){var b=[0,"",""],c=[1,"<table>","</table>"],d=[3,"<table><tbody><tr>","</tr></tbody></table>"],e=[1,"<select multiple='multiple'>","</select>"],f={thead:c,tbody:c,tfoot:c,tr:[2,"<table><tbody>","</tbody></table>"],td:d,th:d,option:e,optgroup:e},
29
+ g=8>=a.a.C;a.a.ma=function(c,d){var e;if(v)if(v.parseHTML)e=v.parseHTML(c,d)||[];else{if((e=v.clean([c],d))&&e[0]){for(var h=e[0];h.parentNode&&11!==h.parentNode.nodeType;)h=h.parentNode;h.parentNode&&h.parentNode.removeChild(h)}}else{(e=d)||(e=u);var h=e.parentWindow||e.defaultView||x,r=a.a.$a(c).toLowerCase(),q=e.createElement("div"),p;p=(r=r.match(/^<([a-z]+)[ >]/))&&f[r[1]]||b;r=p[0];p="ignored<div>"+p[1]+c+p[2]+"</div>";"function"==typeof h.innerShiv?q.appendChild(h.innerShiv(p)):(g&&e.appendChild(q),
30
+ q.innerHTML=p,g&&q.parentNode.removeChild(q));for(;r--;)q=q.lastChild;e=a.a.V(q.lastChild.childNodes)}return e};a.a.Cb=function(b,c){a.a.ob(b);c=a.a.c(c);if(null!==c&&c!==n)if("string"!=typeof c&&(c=c.toString()),v)v(b).html(c);else for(var d=a.a.ma(c,b.ownerDocument),e=0;e<d.length;e++)b.appendChild(d[e])}})();a.b("utils.parseHtmlFragment",a.a.ma);a.b("utils.setHtml",a.a.Cb);a.M=function(){function b(c,e){if(c)if(8==c.nodeType){var f=a.M.lc(c.nodeValue);null!=f&&e.push({Lc:c,cd:f})}else if(1==c.nodeType)for(var f=
31
+ 0,g=c.childNodes,k=g.length;f<k;f++)b(g[f],e)}var c={};return{wb:function(a){if("function"!=typeof a)throw Error("You can only pass a function to ko.memoization.memoize()");var b=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);c[b]=a;return"\x3c!--[ko_memo:"+b+"]--\x3e"},xc:function(a,b){var f=c[a];if(f===n)throw Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized.");try{return f.apply(null,b||[]),
32
+ !0}finally{delete c[a]}},yc:function(c,e){var f=[];b(c,f);for(var g=0,k=f.length;g<k;g++){var l=f[g].Lc,m=[l];e&&a.a.ra(m,e);a.M.xc(f[g].cd,m);l.nodeValue="";l.parentNode&&l.parentNode.removeChild(l)}},lc:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:null}}}();a.b("memoization",a.M);a.b("memoization.memoize",a.M.wb);a.b("memoization.unmemoize",a.M.xc);a.b("memoization.parseMemoText",a.M.lc);a.b("memoization.unmemoizeDomNodeAndDescendants",a.M.yc);a.Y=function(){function b(){if(e)for(var b=
33
+ e,c=0,m;g<e;)if(m=d[g++]){if(g>b){if(5E3<=++c){g=e;a.a.$b(Error("'Too much recursion' after processing "+c+" task groups."));break}b=e}try{m()}catch(h){a.a.$b(h)}}}function c(){b();g=e=d.length=0}var d=[],e=0,f=1,g=0;return{scheduler:x.MutationObserver?function(a){var b=u.createElement("div");(new MutationObserver(a)).observe(b,{attributes:!0});return function(){b.classList.toggle("foo")}}(c):u&&"onreadystatechange"in u.createElement("script")?function(a){var b=u.createElement("script");b.onreadystatechange=
34
+ function(){b.onreadystatechange=null;u.documentElement.removeChild(b);b=null;a()};u.documentElement.appendChild(b)}:function(a){setTimeout(a,0)},Wa:function(b){e||a.Y.scheduler(c);d[e++]=b;return f++},cancel:function(a){a-=f-e;a>=g&&a<e&&(d[a]=null)},resetForTesting:function(){var a=e-g;g=e=d.length=0;return a},md:b}}();a.b("tasks",a.Y);a.b("tasks.schedule",a.Y.Wa);a.b("tasks.runEarly",a.Y.md);a.ya={throttle:function(b,c){b.throttleEvaluation=c;var d=null;return a.B({read:b,write:function(e){clearTimeout(d);
35
+ d=a.a.setTimeout(function(){b(e)},c)}})},rateLimit:function(a,c){var d,e,f;"number"==typeof c?d=c:(d=c.timeout,e=c.method);a.cb=!1;f="notifyWhenChangesStop"==e?V:U;a.Ta(function(a){return f(a,d)})},deferred:function(b,c){if(!0!==c)throw Error("The 'deferred' extender only accepts the value 'true', because it is not supported to turn deferral off once enabled.");b.cb||(b.cb=!0,b.Ta(function(c){var e;return function(){a.Y.cancel(e);e=a.Y.Wa(c);b.notifySubscribers(n,"dirty")}}))},notify:function(a,c){a.equalityComparer=
36
+ "always"==c?null:J}};var T={undefined:1,"boolean":1,number:1,string:1};a.b("extenders",a.ya);a.vc=function(b,c,d){this.ia=b;this.gb=c;this.Kc=d;this.R=!1;a.G(this,"dispose",this.k)};a.vc.prototype.k=function(){this.R=!0;this.Kc()};a.J=function(){a.a.Ya(this,D);D.rb(this)};var I="change",D={rb:function(a){a.K={};a.Nb=1},X:function(b,c,d){var e=this;d=d||I;var f=new a.vc(e,c?b.bind(c):b,function(){a.a.La(e.K[d],f);e.Ia&&e.Ia(d)});e.sa&&e.sa(d);e.K[d]||(e.K[d]=[]);e.K[d].push(f);return f},notifySubscribers:function(b,
37
+ c){c=c||I;c===I&&this.zc();if(this.Pa(c))try{a.l.Ub();for(var d=this.K[c].slice(0),e=0,f;f=d[e];++e)f.R||f.gb(b)}finally{a.l.end()}},Na:function(){return this.Nb},Uc:function(a){return this.Na()!==a},zc:function(){++this.Nb},Ta:function(b){var c=this,d=a.H(c),e,f,g;c.Ha||(c.Ha=c.notifySubscribers,c.notifySubscribers=W);var k=b(function(){c.Mb=!1;d&&g===c&&(g=c());e=!1;c.tb(f,g)&&c.Ha(f=g)});c.Lb=function(a){c.Mb=e=!0;g=a;k()};c.Kb=function(a){e||(f=a,c.Ha(a,"beforeChange"))}},Pa:function(a){return this.K[a]&&
38
+ this.K[a].length},Sc:function(b){if(b)return this.K[b]&&this.K[b].length||0;var c=0;a.a.D(this.K,function(a,b){"dirty"!==a&&(c+=b.length)});return c},tb:function(a,c){return!this.equalityComparer||!this.equalityComparer(a,c)},extend:function(b){var c=this;b&&a.a.D(b,function(b,e){var f=a.ya[b];"function"==typeof f&&(c=f(c,e)||c)});return c}};a.G(D,"subscribe",D.X);a.G(D,"extend",D.extend);a.G(D,"getSubscriptionsCount",D.Sc);a.a.ka&&a.a.Xa(D,Function.prototype);a.J.fn=D;a.hc=function(a){return null!=
39
+ a&&"function"==typeof a.X&&"function"==typeof a.notifySubscribers};a.b("subscribable",a.J);a.b("isSubscribable",a.hc);a.va=a.l=function(){function b(a){d.push(e);e=a}function c(){e=d.pop()}var d=[],e,f=0;return{Ub:b,end:c,oc:function(b){if(e){if(!a.hc(b))throw Error("Only subscribable things can act as dependencies");e.gb.call(e.Gc,b,b.Cc||(b.Cc=++f))}},w:function(a,d,e){try{return b(),a.apply(d,e||[])}finally{c()}},Aa:function(){if(e)return e.m.Aa()},Sa:function(){if(e)return e.Sa}}}();a.b("computedContext",
40
+ a.va);a.b("computedContext.getDependenciesCount",a.va.Aa);a.b("computedContext.isInitial",a.va.Sa);a.b("ignoreDependencies",a.qd=a.l.w);var E=a.a.Yb("_latestValue");a.N=function(b){function c(){if(0<arguments.length)return c.tb(c[E],arguments[0])&&(c.ga(),c[E]=arguments[0],c.fa()),this;a.l.oc(c);return c[E]}c[E]=b;a.a.ka||a.a.extend(c,a.J.fn);a.J.fn.rb(c);a.a.Ya(c,B);a.options.deferUpdates&&a.ya.deferred(c,!0);return c};var B={equalityComparer:J,t:function(){return this[E]},fa:function(){this.notifySubscribers(this[E])},
41
+ ga:function(){this.notifySubscribers(this[E],"beforeChange")}};a.a.ka&&a.a.Xa(B,a.J.fn);var H=a.N.gd="__ko_proto__";B[H]=a.N;a.Oa=function(b,c){return null===b||b===n||b[H]===n?!1:b[H]===c?!0:a.Oa(b[H],c)};a.H=function(b){return a.Oa(b,a.N)};a.Ba=function(b){return"function"==typeof b&&b[H]===a.N||"function"==typeof b&&b[H]===a.B&&b.Vc?!0:!1};a.b("observable",a.N);a.b("isObservable",a.H);a.b("isWriteableObservable",a.Ba);a.b("isWritableObservable",a.Ba);a.b("observable.fn",B);a.G(B,"peek",B.t);a.G(B,
42
+ "valueHasMutated",B.fa);a.G(B,"valueWillMutate",B.ga);a.la=function(b){b=b||[];if("object"!=typeof b||!("length"in b))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");b=a.N(b);a.a.Ya(b,a.la.fn);return b.extend({trackArrayChanges:!0})};a.la.fn={remove:function(b){for(var c=this.t(),d=[],e="function"!=typeof b||a.H(b)?function(a){return a===b}:b,f=0;f<c.length;f++){var g=c[f];e(g)&&(0===d.length&&this.ga(),d.push(g),c.splice(f,1),f--)}d.length&&
43
+ this.fa();return d},removeAll:function(b){if(b===n){var c=this.t(),d=c.slice(0);this.ga();c.splice(0,c.length);this.fa();return d}return b?this.remove(function(c){return 0<=a.a.o(b,c)}):[]},destroy:function(b){var c=this.t(),d="function"!=typeof b||a.H(b)?function(a){return a===b}:b;this.ga();for(var e=c.length-1;0<=e;e--)d(c[e])&&(c[e]._destroy=!0);this.fa()},destroyAll:function(b){return b===n?this.destroy(function(){return!0}):b?this.destroy(function(c){return 0<=a.a.o(b,c)}):[]},indexOf:function(b){var c=
44
+ this();return a.a.o(c,b)},replace:function(a,c){var d=this.indexOf(a);0<=d&&(this.ga(),this.t()[d]=c,this.fa())}};a.a.ka&&a.a.Xa(a.la.fn,a.N.fn);a.a.q("pop push reverse shift sort splice unshift".split(" "),function(b){a.la.fn[b]=function(){var a=this.t();this.ga();this.Vb(a,b,arguments);var d=a[b].apply(a,arguments);this.fa();return d===a?this:d}});a.a.q(["slice"],function(b){a.la.fn[b]=function(){var a=this();return a[b].apply(a,arguments)}});a.b("observableArray",a.la);a.ya.trackArrayChanges=function(b,
45
+ c){function d(){if(!e){e=!0;var c=b.notifySubscribers;b.notifySubscribers=function(a,b){b&&b!==I||++k;return c.apply(this,arguments)};var d=[].concat(b.t()||[]);f=null;g=b.X(function(c){c=[].concat(c||[]);if(b.Pa("arrayChange")){var e;if(!f||1<k)f=a.a.ib(d,c,b.hb);e=f}d=c;f=null;k=0;e&&e.length&&b.notifySubscribers(e,"arrayChange")})}}b.hb={};c&&"object"==typeof c&&a.a.extend(b.hb,c);b.hb.sparse=!0;if(!b.Vb){var e=!1,f=null,g,k=0,l=b.sa,m=b.Ia;b.sa=function(a){l&&l.call(b,a);"arrayChange"===a&&d()};
46
+ b.Ia=function(a){m&&m.call(b,a);"arrayChange"!==a||b.Pa("arrayChange")||(g.k(),e=!1)};b.Vb=function(b,c,d){function m(a,b,c){return l[l.length]={status:a,value:b,index:c}}if(e&&!k){var l=[],g=b.length,t=d.length,G=0;switch(c){case "push":G=g;case "unshift":for(c=0;c<t;c++)m("added",d[c],G+c);break;case "pop":G=g-1;case "shift":g&&m("deleted",b[G],G);break;case "splice":c=Math.min(Math.max(0,0>d[0]?g+d[0]:d[0]),g);for(var g=1===t?g:Math.min(c+(d[1]||0),g),t=c+t-2,G=Math.max(g,t),P=[],n=[],Q=2;c<G;++c,
47
+ ++Q)c<g&&n.push(m("deleted",b[c],c)),c<t&&P.push(m("added",d[Q],c));a.a.dc(n,P);break;default:return}f=l}}}};var s=a.a.Yb("_state");a.m=a.B=function(b,c,d){function e(){if(0<arguments.length){if("function"===typeof f)f.apply(g.pb,arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");return this}a.l.oc(e);(g.S||g.s&&e.Qa())&&e.aa();return g.T}"object"===typeof b?d=b:(d=d||{},b&&(d.read=
48
+ b));if("function"!=typeof d.read)throw Error("Pass a function that returns the value of the ko.computed");var f=d.write,g={T:n,S:!0,Ra:!1,Fb:!1,R:!1,Va:!1,s:!1,jd:d.read,pb:c||d.owner,i:d.disposeWhenNodeIsRemoved||d.i||null,wa:d.disposeWhen||d.wa,mb:null,r:{},L:0,bc:null};e[s]=g;e.Vc="function"===typeof f;a.a.ka||a.a.extend(e,a.J.fn);a.J.fn.rb(e);a.a.Ya(e,z);d.pure?(g.Va=!0,g.s=!0,a.a.extend(e,$)):d.deferEvaluation&&a.a.extend(e,aa);a.options.deferUpdates&&a.ya.deferred(e,!0);g.i&&(g.Fb=!0,g.i.nodeType||
49
+ (g.i=null));g.s||d.deferEvaluation||e.aa();g.i&&e.ba()&&a.a.F.oa(g.i,g.mb=function(){e.k()});return e};var z={equalityComparer:J,Aa:function(){return this[s].L},Pb:function(a,c,d){if(this[s].Va&&c===this)throw Error("A 'pure' computed must not be called recursively");this[s].r[a]=d;d.Ga=this[s].L++;d.na=c.Na()},Qa:function(){var a,c,d=this[s].r;for(a in d)if(d.hasOwnProperty(a)&&(c=d[a],c.ia.Uc(c.na)))return!0},bd:function(){this.Fa&&!this[s].Ra&&this.Fa()},ba:function(){return this[s].S||0<this[s].L},
50
+ ld:function(){this.Mb||this.ac()},uc:function(a){if(a.cb&&!this[s].i){var c=a.X(this.bd,this,"dirty"),d=a.X(this.ld,this);return{ia:a,k:function(){c.k();d.k()}}}return a.X(this.ac,this)},ac:function(){var b=this,c=b.throttleEvaluation;c&&0<=c?(clearTimeout(this[s].bc),this[s].bc=a.a.setTimeout(function(){b.aa(!0)},c)):b.Fa?b.Fa():b.aa(!0)},aa:function(b){var c=this[s],d=c.wa;if(!c.Ra&&!c.R){if(c.i&&!a.a.nb(c.i)||d&&d()){if(!c.Fb){this.k();return}}else c.Fb=!1;c.Ra=!0;try{this.Qc(b)}finally{c.Ra=!1}c.L||
51
+ this.k()}},Qc:function(b){var c=this[s],d=c.Va?n:!c.L,e={Hc:this,Ma:c.r,lb:c.L};a.l.Ub({Gc:e,gb:Y,m:this,Sa:d});c.r={};c.L=0;e=this.Pc(c,e);this.tb(c.T,e)&&(c.s||this.notifySubscribers(c.T,"beforeChange"),c.T=e,c.s?this.zc():b&&this.notifySubscribers(c.T));d&&this.notifySubscribers(c.T,"awake")},Pc:function(b,c){try{var d=b.jd;return b.pb?d.call(b.pb):d()}finally{a.l.end(),c.lb&&!b.s&&a.a.D(c.Ma,X),b.S=!1}},t:function(){var a=this[s];(a.S&&!a.L||a.s&&this.Qa())&&this.aa();return a.T},Ta:function(b){a.J.fn.Ta.call(this,
52
+ b);this.Fa=function(){this.Kb(this[s].T);this[s].S=!0;this.Lb(this)}},k:function(){var b=this[s];!b.s&&b.r&&a.a.D(b.r,function(a,b){b.k&&b.k()});b.i&&b.mb&&a.a.F.pc(b.i,b.mb);b.r=null;b.L=0;b.R=!0;b.S=!1;b.s=!1;b.i=null}},$={sa:function(b){var c=this,d=c[s];if(!d.R&&d.s&&"change"==b){d.s=!1;if(d.S||c.Qa())d.r=null,d.L=0,d.S=!0,c.aa();else{var e=[];a.a.D(d.r,function(a,b){e[b.Ga]=a});a.a.q(e,function(a,b){var e=d.r[a],l=c.uc(e.ia);l.Ga=b;l.na=e.na;d.r[a]=l})}d.R||c.notifySubscribers(d.T,"awake")}},
53
+ Ia:function(b){var c=this[s];c.R||"change"!=b||this.Pa("change")||(a.a.D(c.r,function(a,b){b.k&&(c.r[a]={ia:b.ia,Ga:b.Ga,na:b.na},b.k())}),c.s=!0,this.notifySubscribers(n,"asleep"))},Na:function(){var b=this[s];b.s&&(b.S||this.Qa())&&this.aa();return a.J.fn.Na.call(this)}},aa={sa:function(a){"change"!=a&&"beforeChange"!=a||this.t()}};a.a.ka&&a.a.Xa(z,a.J.fn);var R=a.N.gd;a.m[R]=a.N;z[R]=a.m;a.Xc=function(b){return a.Oa(b,a.m)};a.Yc=function(b){return a.Oa(b,a.m)&&b[s]&&b[s].Va};a.b("computed",a.m);
54
+ a.b("dependentObservable",a.m);a.b("isComputed",a.Xc);a.b("isPureComputed",a.Yc);a.b("computed.fn",z);a.G(z,"peek",z.t);a.G(z,"dispose",z.k);a.G(z,"isActive",z.ba);a.G(z,"getDependenciesCount",z.Aa);a.nc=function(b,c){if("function"===typeof b)return a.m(b,c,{pure:!0});b=a.a.extend({},b);b.pure=!0;return a.m(b,c)};a.b("pureComputed",a.nc);(function(){function b(a,f,g){g=g||new d;a=f(a);if("object"!=typeof a||null===a||a===n||a instanceof RegExp||a instanceof Date||a instanceof String||a instanceof
55
+ Number||a instanceof Boolean)return a;var k=a instanceof Array?[]:{};g.save(a,k);c(a,function(c){var d=f(a[c]);switch(typeof d){case "boolean":case "number":case "string":case "function":k[c]=d;break;case "object":case "undefined":var h=g.get(d);k[c]=h!==n?h:b(d,f,g)}});return k}function c(a,b){if(a instanceof Array){for(var c=0;c<a.length;c++)b(c);"function"==typeof a.toJSON&&b("toJSON")}else for(c in a)b(c)}function d(){this.keys=[];this.Ib=[]}a.wc=function(c){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");
56
+ return b(c,function(b){for(var c=0;a.H(b)&&10>c;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.wc(b);return a.a.Eb(b,c,d)};d.prototype={save:function(b,c){var d=a.a.o(this.keys,b);0<=d?this.Ib[d]=c:(this.keys.push(b),this.Ib.push(c))},get:function(b){b=a.a.o(this.keys,b);return 0<=b?this.Ib[b]:n}}})();a.b("toJS",a.wc);a.b("toJSON",a.toJSON);(function(){a.j={u:function(b){switch(a.a.A(b)){case "option":return!0===b.__ko__hasDomDataOptionValue__?a.a.e.get(b,a.d.options.xb):7>=a.a.C?b.getAttributeNode("value")&&
57
+ b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.j.u(b.options[b.selectedIndex]):n;default:return b.value}},ha:function(b,c,d){switch(a.a.A(b)){case "option":switch(typeof c){case "string":a.a.e.set(b,a.d.options.xb,n);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.e.set(b,a.d.options.xb,c),b.__ko__hasDomDataOptionValue__=!0,b.value="number"===typeof c?c:""}break;case "select":if(""===c||
58
+ null===c)c=n;for(var e=-1,f=0,g=b.options.length,k;f<g;++f)if(k=a.j.u(b.options[f]),k==c||""==k&&c===n){e=f;break}if(d||0<=e||c===n&&1<b.size)b.selectedIndex=e;break;default:if(null===c||c===n)c="";b.value=c}}}})();a.b("selectExtensions",a.j);a.b("selectExtensions.readValue",a.j.u);a.b("selectExtensions.writeValue",a.j.ha);a.h=function(){function b(b){b=a.a.$a(b);123===b.charCodeAt(0)&&(b=b.slice(1,-1));var c=[],d=b.match(e),r,k=[],p=0;if(d){d.push(",");for(var A=0,y;y=d[A];++A){var t=y.charCodeAt(0);
59
+ if(44===t){if(0>=p){c.push(r&&k.length?{key:r,value:k.join("")}:{unknown:r||k.join("")});r=p=0;k=[];continue}}else if(58===t){if(!p&&!r&&1===k.length){r=k.pop();continue}}else 47===t&&A&&1<y.length?(t=d[A-1].match(f))&&!g[t[0]]&&(b=b.substr(b.indexOf(y)+1),d=b.match(e),d.push(","),A=-1,y="/"):40===t||123===t||91===t?++p:41===t||125===t||93===t?--p:r||k.length||34!==t&&39!==t||(y=y.slice(1,-1));k.push(y)}}return c}var c=["true","false","null","undefined"],d=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,
60
+ e=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),f=/[\])"'A-Za-z0-9_$]+$/,g={"in":1,"return":1,"typeof":1},k={};return{ta:[],ea:k,yb:b,Ua:function(e,m){function h(b,e){var m;if(!A){var l=a.getBindingHandler(b);if(l&&l.preprocess&&!(e=l.preprocess(e,b,h)))return;if(l=k[b])m=e,0<=a.a.o(c,m)?m=!1:(l=m.match(d),m=null===l?!1:l[1]?"Object("+l[1]+")"+l[2]:m),l=m;l&&g.push("'"+b+"':function(_z){"+m+"=_z}")}p&&(e=
61
+ "function(){return "+e+" }");f.push("'"+b+"':"+e)}m=m||{};var f=[],g=[],p=m.valueAccessors,A=m.bindingParams,y="string"===typeof e?b(e):e;a.a.q(y,function(a){h(a.key||a.unknown,a.value)});g.length&&h("_ko_property_writers","{"+g.join(",")+" }");return f.join(",")},ad:function(a,b){for(var c=0;c<a.length;c++)if(a[c].key==b)return!0;return!1},Ea:function(b,c,d,e,f){if(b&&a.H(b))!a.Ba(b)||f&&b.t()===e||b(e);else if((b=c.get("_ko_property_writers"))&&b[d])b[d](e)}}}();a.b("expressionRewriting",a.h);a.b("expressionRewriting.bindingRewriteValidators",
62
+ a.h.ta);a.b("expressionRewriting.parseObjectLiteral",a.h.yb);a.b("expressionRewriting.preProcessBindings",a.h.Ua);a.b("expressionRewriting._twoWayBindings",a.h.ea);a.b("jsonExpressionRewriting",a.h);a.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",a.h.Ua);(function(){function b(a){return 8==a.nodeType&&g.test(f?a.text:a.nodeValue)}function c(a){return 8==a.nodeType&&k.test(f?a.text:a.nodeValue)}function d(a,d){for(var e=a,f=1,l=[];e=e.nextSibling;){if(c(e)&&(f--,0===f))return l;l.push(e);
63
+ b(e)&&f++}if(!d)throw Error("Cannot find closing comment tag to match: "+a.nodeValue);return null}function e(a,b){var c=d(a,b);return c?0<c.length?c[c.length-1].nextSibling:a.nextSibling:null}var f=u&&"\x3c!--test--\x3e"===u.createComment("test").text,g=f?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,k=f?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,l={ul:!0,ol:!0};a.f={Z:{},childNodes:function(a){return b(a)?d(a):a.childNodes},xa:function(c){if(b(c)){c=a.f.childNodes(c);for(var d=
64
+ 0,e=c.length;d<e;d++)a.removeNode(c[d])}else a.a.ob(c)},da:function(c,d){if(b(c)){a.f.xa(c);for(var e=c.nextSibling,f=0,l=d.length;f<l;f++)e.parentNode.insertBefore(d[f],e)}else a.a.da(c,d)},mc:function(a,c){b(a)?a.parentNode.insertBefore(c,a.nextSibling):a.firstChild?a.insertBefore(c,a.firstChild):a.appendChild(c)},gc:function(c,d,e){e?b(c)?c.parentNode.insertBefore(d,e.nextSibling):e.nextSibling?c.insertBefore(d,e.nextSibling):c.appendChild(d):a.f.mc(c,d)},firstChild:function(a){return b(a)?!a.nextSibling||
65
+ c(a.nextSibling)?null:a.nextSibling:a.firstChild},nextSibling:function(a){b(a)&&(a=e(a));return a.nextSibling&&c(a.nextSibling)?null:a.nextSibling},Tc:b,pd:function(a){return(a=(f?a.text:a.nodeValue).match(g))?a[1]:null},kc:function(d){if(l[a.a.A(d)]){var h=d.firstChild;if(h){do if(1===h.nodeType){var f;f=h.firstChild;var g=null;if(f){do if(g)g.push(f);else if(b(f)){var k=e(f,!0);k?f=k:g=[f]}else c(f)&&(g=[f]);while(f=f.nextSibling)}if(f=g)for(g=h.nextSibling,k=0;k<f.length;k++)g?d.insertBefore(f[k],
66
+ g):d.appendChild(f[k])}while(h=h.nextSibling)}}}}})();a.b("virtualElements",a.f);a.b("virtualElements.allowedBindings",a.f.Z);a.b("virtualElements.emptyNode",a.f.xa);a.b("virtualElements.insertAfter",a.f.gc);a.b("virtualElements.prepend",a.f.mc);a.b("virtualElements.setDomNodeChildren",a.f.da);(function(){a.Q=function(){this.Fc={}};a.a.extend(a.Q.prototype,{nodeHasBindings:function(b){switch(b.nodeType){case 1:return null!=b.getAttribute("data-bind")||a.g.getComponentNameForNode(b);case 8:return a.f.Tc(b);
67
+ default:return!1}},getBindings:function(b,c){var d=this.getBindingsString(b,c),d=d?this.parseBindingsString(d,c,b):null;return a.g.Ob(d,b,c,!1)},getBindingAccessors:function(b,c){var d=this.getBindingsString(b,c),d=d?this.parseBindingsString(d,c,b,{valueAccessors:!0}):null;return a.g.Ob(d,b,c,!0)},getBindingsString:function(b){switch(b.nodeType){case 1:return b.getAttribute("data-bind");case 8:return a.f.pd(b);default:return null}},parseBindingsString:function(b,c,d,e){try{var f=this.Fc,g=b+(e&&e.valueAccessors||
68
+ ""),k;if(!(k=f[g])){var l,m="with($context){with($data||{}){return{"+a.h.Ua(b,e)+"}}}";l=new Function("$context","$element",m);k=f[g]=l}return k(c,d)}catch(h){throw h.message="Unable to parse bindings.\nBindings value: "+b+"\nMessage: "+h.message,h;}}});a.Q.instance=new a.Q})();a.b("bindingProvider",a.Q);(function(){function b(a){return function(){return a}}function c(a){return a()}function d(b){return a.a.Ca(a.l.w(b),function(a,c){return function(){return b()[c]}})}function e(c,e,h){return"function"===
69
+ typeof c?d(c.bind(null,e,h)):a.a.Ca(c,b)}function f(a,b){return d(this.getBindings.bind(this,a,b))}function g(b,c,d){var e,h=a.f.firstChild(c),f=a.Q.instance,m=f.preprocessNode;if(m){for(;e=h;)h=a.f.nextSibling(e),m.call(f,e);h=a.f.firstChild(c)}for(;e=h;)h=a.f.nextSibling(e),k(b,e,d)}function k(b,c,d){var e=!0,h=1===c.nodeType;h&&a.f.kc(c);if(h&&d||a.Q.instance.nodeHasBindings(c))e=m(c,null,b,d).shouldBindDescendants;e&&!r[a.a.A(c)]&&g(b,c,!h)}function l(b){var c=[],d={},e=[];a.a.D(b,function Z(h){if(!d[h]){var f=
70
+ a.getBindingHandler(h);f&&(f.after&&(e.push(h),a.a.q(f.after,function(c){if(b[c]){if(-1!==a.a.o(e,c))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+e.join(", "));Z(c)}}),e.length--),c.push({key:h,fc:f}));d[h]=!0}});return c}function m(b,d,e,h){var m=a.a.e.get(b,q);if(!d){if(m)throw Error("You cannot apply bindings multiple times to the same element.");a.a.e.set(b,q,!0)}!m&&h&&a.tc(b,e);var g;if(d&&"function"!==typeof d)g=d;else{var k=a.Q.instance,r=k.getBindingAccessors||
71
+ f,p=a.B(function(){(g=d?d(e,b):r.call(k,b,e))&&e.P&&e.P();return g},null,{i:b});g&&p.ba()||(p=null)}var u;if(g){var v=p?function(a){return function(){return c(p()[a])}}:function(a){return g[a]},s=function(){return a.a.Ca(p?p():g,c)};s.get=function(a){return g[a]&&c(v(a))};s.has=function(a){return a in g};h=l(g);a.a.q(h,function(c){var d=c.fc.init,h=c.fc.update,f=c.key;if(8===b.nodeType&&!a.f.Z[f])throw Error("The binding '"+f+"' cannot be used with virtual elements");try{"function"==typeof d&&a.l.w(function(){var a=
72
+ d(b,v(f),s,e.$data,e);if(a&&a.controlsDescendantBindings){if(u!==n)throw Error("Multiple bindings ("+u+" and "+f+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");u=f}}),"function"==typeof h&&a.B(function(){h(b,v(f),s,e.$data,e)},null,{i:b})}catch(m){throw m.message='Unable to process binding "'+f+": "+g[f]+'"\nMessage: '+m.message,m;}})}return{shouldBindDescendants:u===n}}function h(b){return b&&b instanceof a.U?b:new a.U(b)}
73
+ a.d={};var r={script:!0,textarea:!0,template:!0};a.getBindingHandler=function(b){return a.d[b]};a.U=function(b,c,d,e){var h=this,f="function"==typeof b&&!a.H(b),m,g=a.B(function(){var m=f?b():b,l=a.a.c(m);c?(c.P&&c.P(),a.a.extend(h,c),g&&(h.P=g)):(h.$parents=[],h.$root=l,h.ko=a);h.$rawData=m;h.$data=l;d&&(h[d]=l);e&&e(h,c,l);return h.$data},null,{wa:function(){return m&&!a.a.Qb(m)},i:!0});g.ba()&&(h.P=g,g.equalityComparer=null,m=[],g.Ac=function(b){m.push(b);a.a.F.oa(b,function(b){a.a.La(m,b);m.length||
74
+ (g.k(),h.P=g=n)})})};a.U.prototype.createChildContext=function(b,c,d){return new a.U(b,this,c,function(a,b){a.$parentContext=b;a.$parent=b.$data;a.$parents=(b.$parents||[]).slice(0);a.$parents.unshift(a.$parent);d&&d(a)})};a.U.prototype.extend=function(b){return new a.U(this.P||this.$data,this,null,function(c,d){c.$rawData=d.$rawData;a.a.extend(c,"function"==typeof b?b():b)})};var q=a.a.e.I(),p=a.a.e.I();a.tc=function(b,c){if(2==arguments.length)a.a.e.set(b,p,c),c.P&&c.P.Ac(b);else return a.a.e.get(b,
75
+ p)};a.Ja=function(b,c,d){1===b.nodeType&&a.f.kc(b);return m(b,c,h(d),!0)};a.Dc=function(b,c,d){d=h(d);return a.Ja(b,e(c,d,b),d)};a.eb=function(a,b){1!==b.nodeType&&8!==b.nodeType||g(h(a),b,!0)};a.Rb=function(a,b){!v&&x.jQuery&&(v=x.jQuery);if(b&&1!==b.nodeType&&8!==b.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");b=b||x.document.body;k(h(a),b,!0)};a.kb=function(b){switch(b.nodeType){case 1:case 8:var c=a.tc(b);if(c)return c;
76
+ if(b.parentNode)return a.kb(b.parentNode)}return n};a.Jc=function(b){return(b=a.kb(b))?b.$data:n};a.b("bindingHandlers",a.d);a.b("applyBindings",a.Rb);a.b("applyBindingsToDescendants",a.eb);a.b("applyBindingAccessorsToNode",a.Ja);a.b("applyBindingsToNode",a.Dc);a.b("contextFor",a.kb);a.b("dataFor",a.Jc)})();(function(b){function c(c,e){var m=f.hasOwnProperty(c)?f[c]:b,h;m?m.X(e):(m=f[c]=new a.J,m.X(e),d(c,function(b,d){var e=!(!d||!d.synchronous);g[c]={definition:b,Zc:e};delete f[c];h||e?m.notifySubscribers(b):
77
+ a.Y.Wa(function(){m.notifySubscribers(b)})}),h=!0)}function d(a,b){e("getConfig",[a],function(c){c?e("loadComponent",[a,c],function(a){b(a,c)}):b(null,null)})}function e(c,d,f,h){h||(h=a.g.loaders.slice(0));var g=h.shift();if(g){var q=g[c];if(q){var p=!1;if(q.apply(g,d.concat(function(a){p?f(null):null!==a?f(a):e(c,d,f,h)}))!==b&&(p=!0,!g.suppressLoaderExceptions))throw Error("Component loaders must supply values by invoking the callback, not by returning values synchronously.");}else e(c,d,f,h)}else f(null)}
78
+ var f={},g={};a.g={get:function(d,e){var f=g.hasOwnProperty(d)?g[d]:b;f?f.Zc?a.l.w(function(){e(f.definition)}):a.Y.Wa(function(){e(f.definition)}):c(d,e)},Xb:function(a){delete g[a]},Jb:e};a.g.loaders=[];a.b("components",a.g);a.b("components.get",a.g.get);a.b("components.clearCachedDefinition",a.g.Xb)})();(function(){function b(b,c,d,e){function g(){0===--y&&e(k)}var k={},y=2,t=d.template;d=d.viewModel;t?f(c,t,function(c){a.g.Jb("loadTemplate",[b,c],function(a){k.template=a;g()})}):g();d?f(c,d,function(c){a.g.Jb("loadViewModel",
79
+ [b,c],function(a){k[l]=a;g()})}):g()}function c(a,b,d){if("function"===typeof b)d(function(a){return new b(a)});else if("function"===typeof b[l])d(b[l]);else if("instance"in b){var e=b.instance;d(function(){return e})}else"viewModel"in b?c(a,b.viewModel,d):a("Unknown viewModel value: "+b)}function d(b){switch(a.a.A(b)){case "script":return a.a.ma(b.text);case "textarea":return a.a.ma(b.value);case "template":if(e(b.content))return a.a.ua(b.content.childNodes)}return a.a.ua(b.childNodes)}function e(a){return x.DocumentFragment?
80
+ a instanceof DocumentFragment:a&&11===a.nodeType}function f(a,b,c){"string"===typeof b.require?O||x.require?(O||x.require)([b.require],c):a("Uses require, but no AMD loader is present"):c(b)}function g(a){return function(b){throw Error("Component '"+a+"': "+b);}}var k={};a.g.register=function(b,c){if(!c)throw Error("Invalid configuration for "+b);if(a.g.ub(b))throw Error("Component "+b+" is already registered");k[b]=c};a.g.ub=function(a){return k.hasOwnProperty(a)};a.g.od=function(b){delete k[b];
81
+ a.g.Xb(b)};a.g.Zb={getConfig:function(a,b){b(k.hasOwnProperty(a)?k[a]:null)},loadComponent:function(a,c,d){var e=g(a);f(e,c,function(c){b(a,e,c,d)})},loadTemplate:function(b,c,f){b=g(b);if("string"===typeof c)f(a.a.ma(c));else if(c instanceof Array)f(c);else if(e(c))f(a.a.V(c.childNodes));else if(c.element)if(c=c.element,x.HTMLElement?c instanceof HTMLElement:c&&c.tagName&&1===c.nodeType)f(d(c));else if("string"===typeof c){var l=u.getElementById(c);l?f(d(l)):b("Cannot find element with ID "+c)}else b("Unknown element type: "+
82
+ c);else b("Unknown template value: "+c)},loadViewModel:function(a,b,d){c(g(a),b,d)}};var l="createViewModel";a.b("components.register",a.g.register);a.b("components.isRegistered",a.g.ub);a.b("components.unregister",a.g.od);a.b("components.defaultLoader",a.g.Zb);a.g.loaders.push(a.g.Zb);a.g.Bc=k})();(function(){function b(b,e){var f=b.getAttribute("params");if(f){var f=c.parseBindingsString(f,e,b,{valueAccessors:!0,bindingParams:!0}),f=a.a.Ca(f,function(c){return a.m(c,null,{i:b})}),g=a.a.Ca(f,function(c){var e=
83
+ c.t();return c.ba()?a.m({read:function(){return a.a.c(c())},write:a.Ba(e)&&function(a){c()(a)},i:b}):e});g.hasOwnProperty("$raw")||(g.$raw=f);return g}return{$raw:{}}}a.g.getComponentNameForNode=function(b){var c=a.a.A(b);if(a.g.ub(c)&&(-1!=c.indexOf("-")||"[object HTMLUnknownElement]"==""+b||8>=a.a.C&&b.tagName===c))return c};a.g.Ob=function(c,e,f,g){if(1===e.nodeType){var k=a.g.getComponentNameForNode(e);if(k){c=c||{};if(c.component)throw Error('Cannot use the "component" binding on a custom element matching a component');
84
+ var l={name:k,params:b(e,f)};c.component=g?function(){return l}:l}}return c};var c=new a.Q;9>a.a.C&&(a.g.register=function(a){return function(b){u.createElement(b);return a.apply(this,arguments)}}(a.g.register),u.createDocumentFragment=function(b){return function(){var c=b(),f=a.g.Bc,g;for(g in f)f.hasOwnProperty(g)&&c.createElement(g);return c}}(u.createDocumentFragment))})();(function(b){function c(b,c,d){c=c.template;if(!c)throw Error("Component '"+b+"' has no template");b=a.a.ua(c);a.f.da(d,b)}
85
+ function d(a,b,c,d){var e=a.createViewModel;return e?e.call(a,d,{element:b,templateNodes:c}):d}var e=0;a.d.component={init:function(f,g,k,l,m){function h(){var a=r&&r.dispose;"function"===typeof a&&a.call(r);q=r=null}var r,q,p=a.a.V(a.f.childNodes(f));a.a.F.oa(f,h);a.m(function(){var l=a.a.c(g()),k,t;"string"===typeof l?k=l:(k=a.a.c(l.name),t=a.a.c(l.params));if(!k)throw Error("No component name specified");var n=q=++e;a.g.get(k,function(e){if(q===n){h();if(!e)throw Error("Unknown component '"+k+
86
+ "'");c(k,e,f);var g=d(e,f,p,t);e=m.createChildContext(g,b,function(a){a.$component=g;a.$componentTemplateNodes=p});r=g;a.eb(e,f)}})},null,{i:f});return{controlsDescendantBindings:!0}}};a.f.Z.component=!0})();var S={"class":"className","for":"htmlFor"};a.d.attr={update:function(b,c){var d=a.a.c(c())||{};a.a.D(d,function(c,d){d=a.a.c(d);var g=!1===d||null===d||d===n;g&&b.removeAttribute(c);8>=a.a.C&&c in S?(c=S[c],g?b.removeAttribute(c):b[c]=d):g||b.setAttribute(c,d.toString());"name"===c&&a.a.rc(b,
87
+ g?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,c,d){function e(){var e=b.checked,f=p?g():e;if(!a.va.Sa()&&(!l||e)){var m=a.l.w(c);if(h){var k=r?m.t():m;q!==f?(e&&(a.a.pa(k,f,!0),a.a.pa(k,q,!1)),q=f):a.a.pa(k,f,e);r&&a.Ba(m)&&m(k)}else a.h.Ea(m,d,"checked",f,!0)}}function f(){var d=a.a.c(c());b.checked=h?0<=a.a.o(d,g()):k?d:g()===d}var g=a.nc(function(){return d.has("checkedValue")?a.a.c(d.get("checkedValue")):d.has("value")?a.a.c(d.get("value")):b.value}),k=
88
+ "checkbox"==b.type,l="radio"==b.type;if(k||l){var m=c(),h=k&&a.a.c(m)instanceof Array,r=!(h&&m.push&&m.splice),q=h?g():n,p=l||h;l&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.m(e,null,{i:b});a.a.p(b,"click",e);a.m(f,null,{i:b});m=n}}};a.h.ea.checked=!0;a.d.checkedValue={update:function(b,c){b.value=a.a.c(c())}}})();a.d.css={update:function(b,c){var d=a.a.c(c());null!==d&&"object"==typeof d?a.a.D(d,function(c,d){d=a.a.c(d);a.a.bb(b,c,d)}):(d=a.a.$a(String(d||"")),a.a.bb(b,b.__ko__cssValue,
89
+ !1),b.__ko__cssValue=d,a.a.bb(b,d,!0))}};a.d.enable={update:function(b,c){var d=a.a.c(c());d&&b.disabled?b.removeAttribute("disabled"):d||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,c){a.d.enable.update(b,function(){return!a.a.c(c())})}};a.d.event={init:function(b,c,d,e,f){var g=c()||{};a.a.D(g,function(g){"string"==typeof g&&a.a.p(b,g,function(b){var m,h=c()[g];if(h){try{var r=a.a.V(arguments);e=f.$data;r.unshift(e);m=h.apply(e,r)}finally{!0!==m&&(b.preventDefault?b.preventDefault():
90
+ b.returnValue=!1)}!1===d.get(g+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.d.foreach={ic:function(b){return function(){var c=b(),d=a.a.zb(c);if(!d||"number"==typeof d.length)return{foreach:c,templateEngine:a.W.sb};a.a.c(c);return{foreach:d.data,as:d.as,includeDestroyed:d.includeDestroyed,afterAdd:d.afterAdd,beforeRemove:d.beforeRemove,afterRender:d.afterRender,beforeMove:d.beforeMove,afterMove:d.afterMove,templateEngine:a.W.sb}}},init:function(b,c){return a.d.template.init(b,
91
+ a.d.foreach.ic(c))},update:function(b,c,d,e,f){return a.d.template.update(b,a.d.foreach.ic(c),d,e,f)}};a.h.ta.foreach=!1;a.f.Z.foreach=!0;a.d.hasfocus={init:function(b,c,d){function e(e){b.__ko_hasfocusUpdating=!0;var f=b.ownerDocument;if("activeElement"in f){var g;try{g=f.activeElement}catch(h){g=f.body}e=g===b}f=c();a.h.Ea(f,d,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var f=e.bind(null,!0),g=e.bind(null,!1);a.a.p(b,"focus",f);a.a.p(b,"focusin",f);a.a.p(b,"blur",g);a.a.p(b,
92
+ "focusout",g)},update:function(b,c){var d=!!a.a.c(c());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===d||(d?b.focus():b.blur(),!d&&b.__ko_hasfocusLastValue&&b.ownerDocument.body.focus(),a.l.w(a.a.Da,null,[b,d?"focusin":"focusout"]))}};a.h.ea.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.h.ea.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Cb(b,c())}};K("if");K("ifnot",!1,!0);K("with",!0,!1,function(a,c){return a.createChildContext(c)});var L={};
93
+ a.d.options={init:function(b){if("select"!==a.a.A(b))throw Error("options binding applies only to SELECT elements");for(;0<b.length;)b.remove(0);return{controlsDescendantBindings:!0}},update:function(b,c,d){function e(){return a.a.Ka(b.options,function(a){return a.selected})}function f(a,b,c){var d=typeof b;return"function"==d?b(a):"string"==d?a[b]:c}function g(c,e){if(A&&h)a.j.ha(b,a.a.c(d.get("value")),!0);else if(p.length){var f=0<=a.a.o(p,a.j.u(e[0]));a.a.sc(e[0],f);A&&!f&&a.l.w(a.a.Da,null,[b,
94
+ "change"])}}var k=b.multiple,l=0!=b.length&&k?b.scrollTop:null,m=a.a.c(c()),h=d.get("valueAllowUnset")&&d.has("value"),r=d.get("optionsIncludeDestroyed");c={};var q,p=[];h||(k?p=a.a.fb(e(),a.j.u):0<=b.selectedIndex&&p.push(a.j.u(b.options[b.selectedIndex])));m&&("undefined"==typeof m.length&&(m=[m]),q=a.a.Ka(m,function(b){return r||b===n||null===b||!a.a.c(b._destroy)}),d.has("optionsCaption")&&(m=a.a.c(d.get("optionsCaption")),null!==m&&m!==n&&q.unshift(L)));var A=!1;c.beforeRemove=function(a){b.removeChild(a)};
95
+ m=g;d.has("optionsAfterRender")&&"function"==typeof d.get("optionsAfterRender")&&(m=function(b,c){g(0,c);a.l.w(d.get("optionsAfterRender"),null,[c[0],b!==L?b:n])});a.a.Bb(b,q,function(c,e,g){g.length&&(p=!h&&g[0].selected?[a.j.u(g[0])]:[],A=!0);e=b.ownerDocument.createElement("option");c===L?(a.a.Za(e,d.get("optionsCaption")),a.j.ha(e,n)):(g=f(c,d.get("optionsValue"),c),a.j.ha(e,a.a.c(g)),c=f(c,d.get("optionsText"),g),a.a.Za(e,c));return[e]},c,m);a.l.w(function(){h?a.j.ha(b,a.a.c(d.get("value")),
96
+ !0):(k?p.length&&e().length<p.length:p.length&&0<=b.selectedIndex?a.j.u(b.options[b.selectedIndex])!==p[0]:p.length||0<=b.selectedIndex)&&a.a.Da(b,"change")});a.a.Nc(b);l&&20<Math.abs(l-b.scrollTop)&&(b.scrollTop=l)}};a.d.options.xb=a.a.e.I();a.d.selectedOptions={after:["options","foreach"],init:function(b,c,d){a.a.p(b,"change",function(){var e=c(),f=[];a.a.q(b.getElementsByTagName("option"),function(b){b.selected&&f.push(a.j.u(b))});a.h.Ea(e,d,"selectedOptions",f)})},update:function(b,c){if("select"!=
97
+ a.a.A(b))throw Error("values binding applies only to SELECT elements");var d=a.a.c(c()),e=b.scrollTop;d&&"number"==typeof d.length&&a.a.q(b.getElementsByTagName("option"),function(b){var c=0<=a.a.o(d,a.j.u(b));b.selected!=c&&a.a.sc(b,c)});b.scrollTop=e}};a.h.ea.selectedOptions=!0;a.d.style={update:function(b,c){var d=a.a.c(c()||{});a.a.D(d,function(c,d){d=a.a.c(d);if(null===d||d===n||!1===d)d="";b.style[c]=d})}};a.d.submit={init:function(b,c,d,e,f){if("function"!=typeof c())throw Error("The value for a submit binding must be a function");
98
+ a.a.p(b,"submit",function(a){var d,e=c();try{d=e.call(f.$data,b)}finally{!0!==d&&(a.preventDefault?a.preventDefault():a.returnValue=!1)}})}};a.d.text={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Za(b,c())}};a.f.Z.text=!0;(function(){if(x&&x.navigator)var b=function(a){if(a)return parseFloat(a[1])},c=x.opera&&x.opera.version&&parseInt(x.opera.version()),d=x.navigator.userAgent,e=b(d.match(/^(?:(?!chrome).)*version\/([^ ]*) safari/i)),f=b(d.match(/Firefox\/([^ ]*)/));
99
+ if(10>a.a.C)var g=a.a.e.I(),k=a.a.e.I(),l=function(b){var c=this.activeElement;(c=c&&a.a.e.get(c,k))&&c(b)},m=function(b,c){var d=b.ownerDocument;a.a.e.get(d,g)||(a.a.e.set(d,g,!0),a.a.p(d,"selectionchange",l));a.a.e.set(b,k,c)};a.d.textInput={init:function(b,d,g){function l(c,d){a.a.p(b,c,d)}function k(){var c=a.a.c(d());if(null===c||c===n)c="";v!==n&&c===v?a.a.setTimeout(k,4):b.value!==c&&(u=c,b.value=c)}function y(){s||(v=b.value,s=a.a.setTimeout(t,4))}function t(){clearTimeout(s);v=s=n;var c=
100
+ b.value;u!==c&&(u=c,a.h.Ea(d(),g,"textInput",c))}var u=b.value,s,v,x=9==a.a.C?y:t;10>a.a.C?(l("propertychange",function(a){"value"===a.propertyName&&x(a)}),8==a.a.C&&(l("keyup",t),l("keydown",t)),8<=a.a.C&&(m(b,x),l("dragend",y))):(l("input",t),5>e&&"textarea"===a.a.A(b)?(l("keydown",y),l("paste",y),l("cut",y)):11>c?l("keydown",y):4>f&&(l("DOMAutoComplete",t),l("dragdrop",t),l("drop",t)));l("change",t);a.m(k,null,{i:b})}};a.h.ea.textInput=!0;a.d.textinput={preprocess:function(a,b,c){c("textInput",
101
+ a)}}})();a.d.uniqueName={init:function(b,c){if(c()){var d="ko_unique_"+ ++a.d.uniqueName.Ic;a.a.rc(b,d)}}};a.d.uniqueName.Ic=0;a.d.value={after:["options","foreach"],init:function(b,c,d){if("input"!=b.tagName.toLowerCase()||"checkbox"!=b.type&&"radio"!=b.type){var e=["change"],f=d.get("valueUpdate"),g=!1,k=null;f&&("string"==typeof f&&(f=[f]),a.a.ra(e,f),e=a.a.Tb(e));var l=function(){k=null;g=!1;var e=c(),f=a.j.u(b);a.h.Ea(e,d,"value",f)};!a.a.C||"input"!=b.tagName.toLowerCase()||"text"!=b.type||
102
+ "off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||-1!=a.a.o(e,"propertychange")||(a.a.p(b,"propertychange",function(){g=!0}),a.a.p(b,"focus",function(){g=!1}),a.a.p(b,"blur",function(){g&&l()}));a.a.q(e,function(c){var d=l;a.a.nd(c,"after")&&(d=function(){k=a.j.u(b);a.a.setTimeout(l,0)},c=c.substring(5));a.a.p(b,c,d)});var m=function(){var e=a.a.c(c()),f=a.j.u(b);if(null!==k&&e===k)a.a.setTimeout(m,0);else if(e!==f)if("select"===a.a.A(b)){var g=d.get("valueAllowUnset"),f=function(){a.j.ha(b,
103
+ e,g)};f();g||e===a.j.u(b)?a.a.setTimeout(f,0):a.l.w(a.a.Da,null,[b,"change"])}else a.j.ha(b,e)};a.m(m,null,{i:b})}else a.Ja(b,{checkedValue:c})},update:function(){}};a.h.ea.value=!0;a.d.visible={update:function(b,c){var d=a.a.c(c()),e="none"!=b.style.display;d&&!e?b.style.display="":!d&&e&&(b.style.display="none")}};(function(b){a.d[b]={init:function(c,d,e,f,g){return a.d.event.init.call(this,c,function(){var a={};a[b]=d();return a},e,f,g)}}})("click");a.O=function(){};a.O.prototype.renderTemplateSource=
104
+ function(){throw Error("Override renderTemplateSource");};a.O.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.O.prototype.makeTemplateSource=function(b,c){if("string"==typeof b){c=c||u;var d=c.getElementById(b);if(!d)throw Error("Cannot find template with ID "+b);return new a.v.n(d)}if(1==b.nodeType||8==b.nodeType)return new a.v.qa(b);throw Error("Unknown template type: "+b);};a.O.prototype.renderTemplate=function(a,c,d,e){a=this.makeTemplateSource(a,
105
+ e);return this.renderTemplateSource(a,c,d,e)};a.O.prototype.isTemplateRewritten=function(a,c){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,c).data("isRewritten")};a.O.prototype.rewriteTemplate=function(a,c,d){a=this.makeTemplateSource(a,d);c=c(a.text());a.text(c);a.data("isRewritten",!0)};a.b("templateEngine",a.O);a.Gb=function(){function b(b,c,d,k){b=a.h.yb(b);for(var l=a.h.ta,m=0;m<b.length;m++){var h=b[m].key;if(l.hasOwnProperty(h)){var r=l[h];if("function"===typeof r){if(h=
106
+ r(b[m].value))throw Error(h);}else if(!r)throw Error("This template engine does not support the '"+h+"' binding within its templates");}}d="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+a.h.Ua(b,{valueAccessors:!0})+" } })()},'"+d.toLowerCase()+"')";return k.createJavaScriptEvaluatorBlock(d)+c}var c=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'|[^>]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,d=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{Oc:function(b,
107
+ c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.Gb.dd(b,c)},d)},dd:function(a,f){return a.replace(c,function(a,c,d,e,h){return b(h,c,d,f)}).replace(d,function(a,c){return b(c,"\x3c!-- ko --\x3e","#comment",f)})},Ec:function(b,c){return a.M.wb(function(d,k){var l=d.nextSibling;l&&l.nodeName.toLowerCase()===c&&a.Ja(l,b,k)})}}}();a.b("__tr_ambtns",a.Gb.Ec);(function(){a.v={};a.v.n=function(b){if(this.n=b){var c=a.a.A(b);this.ab="script"===c?1:"textarea"===c?2:"template"==c&&
108
+ b.content&&11===b.content.nodeType?3:4}};a.v.n.prototype.text=function(){var b=1===this.ab?"text":2===this.ab?"value":"innerHTML";if(0==arguments.length)return this.n[b];var c=arguments[0];"innerHTML"===b?a.a.Cb(this.n,c):this.n[b]=c};var b=a.a.e.I()+"_";a.v.n.prototype.data=function(c){if(1===arguments.length)return a.a.e.get(this.n,b+c);a.a.e.set(this.n,b+c,arguments[1])};var c=a.a.e.I();a.v.n.prototype.nodes=function(){var b=this.n;if(0==arguments.length)return(a.a.e.get(b,c)||{}).jb||(3===this.ab?
109
+ b.content:4===this.ab?b:n);a.a.e.set(b,c,{jb:arguments[0]})};a.v.qa=function(a){this.n=a};a.v.qa.prototype=new a.v.n;a.v.qa.prototype.text=function(){if(0==arguments.length){var b=a.a.e.get(this.n,c)||{};b.Hb===n&&b.jb&&(b.Hb=b.jb.innerHTML);return b.Hb}a.a.e.set(this.n,c,{Hb:arguments[0]})};a.b("templateSources",a.v);a.b("templateSources.domElement",a.v.n);a.b("templateSources.anonymousTemplate",a.v.qa)})();(function(){function b(b,c,d){var e;for(c=a.f.nextSibling(c);b&&(e=b)!==c;)b=a.f.nextSibling(e),
110
+ d(e,b)}function c(c,d){if(c.length){var e=c[0],f=c[c.length-1],g=e.parentNode,k=a.Q.instance,n=k.preprocessNode;if(n){b(e,f,function(a,b){var c=a.previousSibling,d=n.call(k,a);d&&(a===e&&(e=d[0]||b),a===f&&(f=d[d.length-1]||c))});c.length=0;if(!e)return;e===f?c.push(e):(c.push(e,f),a.a.za(c,g))}b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.Rb(d,b)});b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.M.yc(b,[d])});a.a.za(c,g)}}function d(a){return a.nodeType?a:0<a.length?a[0]:null}function e(b,
111
+ e,f,k,q){q=q||{};var p=(b&&d(b)||f||{}).ownerDocument,n=q.templateEngine||g;a.Gb.Oc(f,n,p);f=n.renderTemplate(f,k,q,p);if("number"!=typeof f.length||0<f.length&&"number"!=typeof f[0].nodeType)throw Error("Template engine must return an array of DOM nodes");p=!1;switch(e){case "replaceChildren":a.f.da(b,f);p=!0;break;case "replaceNode":a.a.qc(b,f);p=!0;break;case "ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+e);}p&&(c(f,k),q.afterRender&&a.l.w(q.afterRender,null,[f,k.$data]));
112
+ return f}function f(b,c,d){return a.H(b)?b():"function"===typeof b?b(c,d):b}var g;a.Db=function(b){if(b!=n&&!(b instanceof a.O))throw Error("templateEngine must inherit from ko.templateEngine");g=b};a.Ab=function(b,c,h,k,q){h=h||{};if((h.templateEngine||g)==n)throw Error("Set a template engine before calling renderTemplate");q=q||"replaceChildren";if(k){var p=d(k);return a.B(function(){var g=c&&c instanceof a.U?c:new a.U(a.a.c(c)),n=f(b,g.$data,g),g=e(k,q,n,g,h);"replaceNode"==q&&(k=g,p=d(k))},null,
113
+ {wa:function(){return!p||!a.a.nb(p)},i:p&&"replaceNode"==q?p.parentNode:p})}return a.M.wb(function(d){a.Ab(b,c,h,d,"replaceNode")})};a.kd=function(b,d,g,k,q){function p(a,b){c(b,s);g.afterRender&&g.afterRender(b,a);s=null}function u(a,c){s=q.createChildContext(a,g.as,function(a){a.$index=c});var d=f(b,a,s);return e(null,"ignoreTargetNode",d,s,g)}var s;return a.B(function(){var b=a.a.c(d)||[];"undefined"==typeof b.length&&(b=[b]);b=a.a.Ka(b,function(b){return g.includeDestroyed||b===n||null===b||!a.a.c(b._destroy)});
114
+ a.l.w(a.a.Bb,null,[k,b,u,g,p])},null,{i:k})};var k=a.a.e.I();a.d.template={init:function(b,c){var d=a.a.c(c());if("string"==typeof d||d.name)a.f.xa(b);else{if("nodes"in d){if(d=d.nodes||[],a.H(d))throw Error('The "nodes" option must be a plain, non-observable array.');}else d=a.f.childNodes(b);d=a.a.jc(d);(new a.v.qa(b)).nodes(d)}return{controlsDescendantBindings:!0}},update:function(b,c,d,e,f){var g=c(),s;c=a.a.c(g);d=!0;e=null;"string"==typeof c?c={}:(g=c.name,"if"in c&&(d=a.a.c(c["if"])),d&&"ifnot"in
115
+ c&&(d=!a.a.c(c.ifnot)),s=a.a.c(c.data));"foreach"in c?e=a.kd(g||b,d&&c.foreach||[],c,b,f):d?(f="data"in c?f.createChildContext(s,c.as):f,e=a.Ab(g||b,f,c,b)):a.f.xa(b);f=e;(s=a.a.e.get(b,k))&&"function"==typeof s.k&&s.k();a.a.e.set(b,k,f&&f.ba()?f:n)}};a.h.ta.template=function(b){b=a.h.yb(b);return 1==b.length&&b[0].unknown||a.h.ad(b,"name")?null:"This template engine does not support anonymous templates nested within its templates"};a.f.Z.template=!0})();a.b("setTemplateEngine",a.Db);a.b("renderTemplate",
116
+ a.Ab);a.a.dc=function(a,c,d){if(a.length&&c.length){var e,f,g,k,l;for(e=f=0;(!d||e<d)&&(k=a[f]);++f){for(g=0;l=c[g];++g)if(k.value===l.value){k.moved=l.index;l.moved=k.index;c.splice(g,1);e=g=0;break}e+=g}}};a.a.ib=function(){function b(b,d,e,f,g){var k=Math.min,l=Math.max,m=[],h,n=b.length,q,p=d.length,s=p-n||1,u=n+p+1,t,v,x;for(h=0;h<=n;h++)for(v=t,m.push(t=[]),x=k(p,h+s),q=l(0,h-1);q<=x;q++)t[q]=q?h?b[h-1]===d[q-1]?v[q-1]:k(v[q]||u,t[q-1]||u)+1:q+1:h+1;k=[];l=[];s=[];h=n;for(q=p;h||q;)p=m[h][q]-
117
+ 1,q&&p===m[h][q-1]?l.push(k[k.length]={status:e,value:d[--q],index:q}):h&&p===m[h-1][q]?s.push(k[k.length]={status:f,value:b[--h],index:h}):(--q,--h,g.sparse||k.push({status:"retained",value:d[q]}));a.a.dc(s,l,!g.dontLimitMoves&&10*n);return k.reverse()}return function(a,d,e){e="boolean"===typeof e?{dontLimitMoves:e}:e||{};a=a||[];d=d||[];return a.length<d.length?b(a,d,"added","deleted",e):b(d,a,"deleted","added",e)}}();a.b("utils.compareArrays",a.a.ib);(function(){function b(b,c,d,k,l){var m=[],
118
+ h=a.B(function(){var h=c(d,l,a.a.za(m,b))||[];0<m.length&&(a.a.qc(m,h),k&&a.l.w(k,null,[d,h,l]));m.length=0;a.a.ra(m,h)},null,{i:b,wa:function(){return!a.a.Qb(m)}});return{ca:m,B:h.ba()?h:n}}var c=a.a.e.I(),d=a.a.e.I();a.a.Bb=function(e,f,g,k,l){function m(b,c){w=q[c];v!==c&&(D[b]=w);w.qb(v++);a.a.za(w.ca,e);u.push(w);z.push(w)}function h(b,c){if(b)for(var d=0,e=c.length;d<e;d++)c[d]&&a.a.q(c[d].ca,function(a){b(a,d,c[d].ja)})}f=f||[];k=k||{};var r=a.a.e.get(e,c)===n,q=a.a.e.get(e,c)||[],p=a.a.fb(q,
119
+ function(a){return a.ja}),s=a.a.ib(p,f,k.dontLimitMoves),u=[],t=0,v=0,x=[],z=[];f=[];for(var D=[],p=[],w,C=0,B,E;B=s[C];C++)switch(E=B.moved,B.status){case "deleted":E===n&&(w=q[t],w.B&&(w.B.k(),w.B=n),a.a.za(w.ca,e).length&&(k.beforeRemove&&(u.push(w),z.push(w),w.ja===d?w=null:f[C]=w),w&&x.push.apply(x,w.ca)));t++;break;case "retained":m(C,t++);break;case "added":E!==n?m(C,E):(w={ja:B.value,qb:a.N(v++)},u.push(w),z.push(w),r||(p[C]=w))}a.a.e.set(e,c,u);h(k.beforeMove,D);a.a.q(x,k.beforeRemove?a.$:
120
+ a.removeNode);for(var C=0,r=a.f.firstChild(e),F;w=z[C];C++){w.ca||a.a.extend(w,b(e,g,w.ja,l,w.qb));for(t=0;s=w.ca[t];r=s.nextSibling,F=s,t++)s!==r&&a.f.gc(e,s,F);!w.Wc&&l&&(l(w.ja,w.ca,w.qb),w.Wc=!0)}h(k.beforeRemove,f);for(C=0;C<f.length;++C)f[C]&&(f[C].ja=d);h(k.afterMove,D);h(k.afterAdd,p)}})();a.b("utils.setDomNodeChildrenFromArrayMapping",a.a.Bb);a.W=function(){this.allowTemplateRewriting=!1};a.W.prototype=new a.O;a.W.prototype.renderTemplateSource=function(b,c,d,e){if(c=(9>a.a.C?0:b.nodes)?
121
+ b.nodes():null)return a.a.V(c.cloneNode(!0).childNodes);b=b.text();return a.a.ma(b,e)};a.W.sb=new a.W;a.Db(a.W.sb);a.b("nativeTemplateEngine",a.W);(function(){a.vb=function(){var a=this.$c=function(){if(!v||!v.tmpl)return 0;try{if(0<=v.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,e,f,g){g=g||u;f=f||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var k=b.data("precompiled");
122
+ k||(k=b.text()||"",k=v.template(null,"{{ko_with $item.koBindingContext}}"+k+"{{/ko_with}}"),b.data("precompiled",k));b=[e.$data];e=v.extend({koBindingContext:e},f.templateOptions);e=v.tmpl(k,b,e);e.appendTo(g.createElement("div"));v.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){u.write("<script type='text/html' id='"+a+"'>"+b+"\x3c/script>")};0<a&&(v.tmpl.tag.ko_code={open:"__.push($1 || '');"},
123
+ v.tmpl.tag.ko_with={open:"with($1) {",close:"} "})};a.vb.prototype=new a.O;var b=new a.vb;0<b.$c&&a.Db(b);a.b("jqueryTmplTemplateEngine",a.vb)})()})})();})();
knockout/core/knockout.simpleGrid.3.0.js ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function () {
2
+ // Private function
3
+ function getColumnsForScaffolding(data) {
4
+ if ((typeof data.length !== 'number') || data.length === 0) {
5
+ return [];
6
+ }
7
+ var columns = [];
8
+ for (var propertyName in data[0]) {
9
+ columns.push({ headerText: propertyName, rowText: propertyName });
10
+ }
11
+ return columns;
12
+ }
13
+
14
+ instapageKO.simpleGrid = {
15
+ // Defines a view model class you can use to populate a grid
16
+ viewModel: function (configuration) {
17
+ this.data = configuration.data;
18
+ this.currentPageIndex = instapageKO.observable(0);
19
+ this.pageSize = configuration.pageSize || 5;
20
+
21
+ // If you don't specify columns configuration, we'll use scaffolding
22
+ this.columns = configuration.columns || getColumnsForScaffolding(instapageKO.unwrap(this.data));
23
+ this.itemsOnCurrentPage = instapageKO.computed(function () {
24
+ var startIndex = this.pageSize * this.currentPageIndex();
25
+ return instapageKO.unwrap(this.data).slice(startIndex, startIndex + this.pageSize);
26
+ }, this);
27
+
28
+ this.maxPageIndex = instapageKO.computed(function () {
29
+ return Math.ceil(instapageKO.unwrap(this.data).length / this.pageSize) - 1;
30
+ }, this);
31
+ }
32
+ };
33
+
34
+ // Templates used to render the grid
35
+ var templateEngine = new instapageKO.nativeTemplateEngine();
36
+
37
+ templateEngine.addTemplate = function(templateName, templateMarkup) {
38
+ document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
39
+ };
40
+
41
+ templateEngine.addTemplate("ko_simpleGrid_grid", "\
42
+ <table class=\"ko-grid c-table\" cellspacing=\"0\">\
43
+ <thead class=\"c-table__head\">\
44
+ <tr>\
45
+ <th class=\"c-table__cell c-table__cell--left\">Preview</th>\
46
+ <th class=\"c-table__cell c-table__cell--left\">Title</th>\
47
+ <th class=\"c-table__cell c-table__cell--left\">Type</th>\
48
+ <th class=\"c-table__cell c-table__cell--left\">Var. Testing Stats</th>\
49
+ <th class=\"c-table__cell c-table__cell--left\">Visits</th>\
50
+ <th class=\"c-table__cell c-table__cell--left\">Conv.</th>\
51
+ <th class=\"c-table__cell c-table__cell--left\">Conv. Rate</th>\
52
+ </tr>\
53
+ </thead>\
54
+ <tbody class=\"c-table__body\" data-bind=\"template: {name: 'page-row-template', foreach: itemsOnCurrentPage}\">\
55
+ </tbody>\
56
+ </table>");
57
+ templateEngine.addTemplate("ko_simpleGrid_pageLinks", "\
58
+ <div class=\"ko-grid-pageLinks c-pagination\" data-bind=\"visible: maxPageIndex() > 0\">\
59
+ <ul class=\"c-pagination__list\">\
60
+ <!-- ko foreach: instapageKO.utils.range(0, maxPageIndex) -->\
61
+ <li class=\"c-pagination__item\">\
62
+ <a class=\"c-pagination__page fx-ripple-effect\" href=\"#\" data-bind=\"text: $data + 1, click: function() { $root.currentPageIndex($data) }, css: { selected: $data == $root.currentPageIndex() }\"></a>\
63
+ </li>\
64
+ <!-- /ko -->\
65
+ </ul>\
66
+ </div>");
67
+
68
+ // The "simpleGrid" binding
69
+ instapageKO.bindingHandlers.simpleGrid = {
70
+ init: function() {
71
+ return { 'controlsDescendantBindings': true };
72
+ },
73
+ // This method is called to initialize the node, and will also be called again if you change what the grid is bound to
74
+ update: function (element, viewModelAccessor, allBindings) {
75
+ var viewModel = viewModelAccessor();
76
+
77
+ // Empty the element
78
+ while(element.firstChild)
79
+ instapageKO.removeNode(element.firstChild);
80
+
81
+ // Allow the default templates to be overridden
82
+ var gridTemplateName = allBindings.get('simpleGridTemplate') || "ko_simpleGrid_grid",
83
+ pageLinksTemplateName = allBindings.get('simpleGridPagerTemplate') || "ko_simpleGrid_pageLinks";
84
+
85
+ // Render the main grid
86
+ var gridContainer = element.appendChild(document.createElement("DIV"));
87
+ instapageKO.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, gridContainer, "replaceNode");
88
+
89
+ // Render the page links
90
+ var pageLinksContainer = element.appendChild(document.createElement("DIV"));
91
+ instapageKO.renderTemplate(pageLinksTemplateName, viewModel, { templateEngine: templateEngine }, pageLinksContainer, "replaceNode");
92
+ }
93
+ };
94
+ })();
knockout/view_models/InstapageCmsPluginEditModel.js ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ko, instapageKO, iAjax, iLang, INSTAPAGE_AJAXURL, masterModel */
2
+
3
+ var InstapageCmsPluginEditModel = function InstapageCmsPluginEditModel(data) {
4
+ var self = this;
5
+
6
+ self.randomPrefix = 'random-url-';
7
+ self.randomSufixSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
8
+ self.randomSufixLength = 10;
9
+ self.id = data && data.page ? instapageKO.observable(data.page.id) : instapageKO.observable(0);
10
+ self.instapageId = data && data.page ? data.page.instapage_id : null;
11
+ self.publishThrottle = instapageKO.observable(true);
12
+
13
+ if (data && data.subAccounts && data.subAccounts.length) {
14
+ self.subAccounts = instapageKO.observableArray(data.subAccounts);
15
+ self.choosenSubAccount = data.page ? instapageKO.observable(data.page.subaccount) : instapageKO.observable(data.subAccounts[0].id);
16
+ } else {
17
+ self.subAccounts = instapageKO.observableArray();
18
+ self.choosenSubAccount = instapageKO.observable();
19
+ masterModel.messagesModel.addMessage(iLang.get('LOGIN_OR_ADD_TOKEN_FIRST'));
20
+ }
21
+
22
+ self.choosenLandingPage = data && data.page ? instapageKO.observable(data.page.instapage_id) : instapageKO.observable();
23
+ self.choosenLandingPageType = data && data.page ? instapageKO.observable(data.page.type) : instapageKO.observable();
24
+ self.slug = data && data.page ? instapageKO.observable(data.page.slug) : instapageKO.observable('');
25
+ self.isSlugValid = instapageKO.observable(true);
26
+ self.isTypeValid = instapageKO.observable(true);
27
+ self.landingPages = instapageKO.observableArray();
28
+ self.pageTypes = instapageKO.observableArray([new LandingPageType('page', 'Landing Page'), new LandingPageType('home', 'Home Page'), new LandingPageType('404', '404 Page')]);
29
+
30
+ self.choosenSubAccount.subscribe(function choosenSubAccountCallback() {self.loadLandingPages();});
31
+
32
+ self.choosenLandingPageType.subscribe(function choosenLandingPageTypeCallback() {
33
+ if (self.choosenLandingPageType() === '404') {
34
+ self.slug(self.generateRandomSlug());
35
+ } else {
36
+ self.slug('');
37
+ }
38
+ });
39
+
40
+ self.publishPage = function publishPage() {
41
+ if (self.publishThrottle.isBusy()) {
42
+ return;
43
+ }
44
+
45
+ self.publishThrottle.setBusy(true);
46
+ masterModel.messagesModel.clear();
47
+
48
+ if (!self.validateSlug() || !self.validateLandingPageType()) {
49
+ return false;
50
+ }
51
+
52
+ var post = {action: 'publishPage', apiTokens: masterModel.apiTokens, data: {
53
+ id: self.id(),
54
+ landingPageId: self.choosenLandingPage(),
55
+ type: self.choosenLandingPageType(),
56
+ slug: self.slug()
57
+ }};
58
+
59
+ iAjax.post(INSTAPAGE_AJAXURL, post, function publishPageCallback(responseJson) {
60
+ var response = masterModel.parseResponse(responseJson);
61
+ masterModel.messagesModel.addMessage(response.message, response.status);
62
+
63
+ if (response.status === 'OK') {
64
+ if (typeof response.updatedId !== 'undefined') {
65
+ self.id(response.updatedId);
66
+ }
67
+ masterModel.pagedGridModel.originalItems.push({type: self.choosenLandingPageType()});
68
+ masterModel.toolbarModel.loadListPages();
69
+ }
70
+
71
+ masterModel.messagesModel.addMessage(response.message, response.status);
72
+ self.publishThrottle.setBusy(false);
73
+ });
74
+
75
+ return true;
76
+ };
77
+
78
+ self.validateSlug = function validateSlug() {
79
+ var message = '';
80
+ var result = {};
81
+
82
+ self.isSlugValid(true);
83
+ // removing dots, spaces, slashes from begining and the end of slug
84
+ self.slug(self.slug().trim().replace(/ |^(\/)+|(\/)+$|\./g, ''));
85
+ // replacing duplicated slashes in slug
86
+ self.slug(self.slug().replace(/\/{2,}/g, '/'));
87
+ self.isProhibitedSlug(self.slug());
88
+ if (self.choosenLandingPageType() === 'page') {
89
+ if (self.slug() === '') {
90
+ masterModel.messagesModel.addMessage(iLang.get('SLUG_CANNOT_BE_EMPTY'), 'ERROR');
91
+ self.isSlugValid(false);
92
+ return false;
93
+ }
94
+
95
+ if ((masterModel.prohibitedSlugs !== null) && (masterModel.prohibitedSlugs.some(self.isSlugProhibited, result))) {
96
+ if (result.conflictElement) {
97
+ message = '';
98
+
99
+ if (result.conflictElement.editUrl) {
100
+ var editHtml = '<a href="' + result.conflictElement.editUrl + '" target="_blank">Edit item</a>';
101
+ message = iLang.get('SLUG_IS_USED_BY_CMS', editHtml);
102
+ } else {
103
+ message = iLang.get('SLUG_IS_USED_BY_PLUGIN');
104
+ }
105
+ masterModel.messagesModel.addMessage(message, 'ERROR');
106
+ }
107
+
108
+ self.isSlugValid(false);
109
+ return false;
110
+ }
111
+ }
112
+
113
+ return true;
114
+ };
115
+
116
+ self.validateLandingPageType = function validateLandingPageType() {
117
+ var message = '';
118
+
119
+ self.isTypeValid(true);
120
+
121
+ if (self.choosenLandingPageType() === 'home') {
122
+ if (masterModel.pagedGridModel.items().some(self.isHomepage)) {
123
+ message = iLang.get('HOMEPAGE_ALREADY_DEFINED');
124
+ masterModel.messagesModel.addMessage(message, 'ERROR');
125
+ self.isTypeValid(false);
126
+ return false;
127
+ }
128
+ } else if (self.choosenLandingPageType() === '404') {
129
+ if (masterModel.pagedGridModel.items().some(self.is404)) {
130
+ message = iLang.get('404_ALREADY_DEFINED');
131
+ masterModel.messagesModel.addMessage(message, 'ERROR');
132
+ self.isTypeValid(false);
133
+ return false;
134
+ }
135
+ }
136
+
137
+ return true;
138
+ };
139
+
140
+ self.isSlugProhibited = function isSlugProhibited(element) {
141
+ if (element.slug === self.slug().trim() && parseInt(element.id, 10) !== parseInt(self.id(), 10)) {
142
+ this.conflictElement = element;
143
+ return true;
144
+ }
145
+
146
+ return false;
147
+ };
148
+
149
+ self.isHomepage = function isHomepage(element) {
150
+ return element.type === 'home' && parseInt(element.id, 10) !== parseInt(self.id(), 10);
151
+ };
152
+
153
+ self.is404 = function is404(element) {
154
+ return element.type === '404' && parseInt(element.id, 10) !== parseInt(self.id(), 10);
155
+ };
156
+
157
+ self.generateRandomSlug = function generateRandomSlug() {
158
+ var randomString = '';
159
+
160
+ for (var index = 0; index < self.randomSufixLength; index++) {
161
+ randomString += self.randomSufixSet[ Math.floor(Math.random() * self.randomSufixSet.length) ];
162
+ }
163
+
164
+ return self.randomPrefix + randomString;
165
+ };
166
+
167
+ self.loadLandingPages = function loadLandingPages() {
168
+ var post = {action: 'getLandingPages', apiTokens: masterModel.apiTokens, data: {subAccountToken: self.getSubAccountToken(), selfInstapageId: self.instapageId}};
169
+ var selectedLandingPage = self.choosenLandingPage();
170
+
171
+ iAjax.post(INSTAPAGE_AJAXURL, post, function getLandingPagesCallback(responseJson) {
172
+ var response = masterModel.parseResponse(responseJson);
173
+
174
+ if (response.status === 'OK') {
175
+ self.landingPages(response.data);
176
+
177
+ if (selectedLandingPage) {
178
+ self.choosenLandingPage(selectedLandingPage);
179
+ }
180
+ }
181
+ });
182
+ };
183
+
184
+ self.isProhibitedSlug = function isProhibitedSlug(slug) {
185
+ var post = {action: 'isProhibitedSlug', data: slug};
186
+
187
+ iAjax.post(INSTAPAGE_AJAXURL, post, function isProhibitedSlugCallback(responseJson) {
188
+ var response = masterModel.parseResponse(responseJson);
189
+
190
+ if (response.status === 'OK') {
191
+ masterModel.prohibitedSlugs = (response.data === false) ? null : response.data;
192
+ }
193
+ }, false);
194
+ };
195
+
196
+ self.getSubAccountToken = function getSubAccountToken() {
197
+ var result = {};
198
+
199
+ self.subAccounts().some(function getSubAccountTokenById(element) {
200
+ if (element.id === self.choosenSubAccount()) {
201
+ result = element.accountkey;
202
+ }
203
+ }, result);
204
+
205
+ return result;
206
+ };
207
+
208
+ self.loadLandingPages();
209
+ };
210
+
211
+
212
+ var LandingPageType = function LandingPageType(name, title) {
213
+ var self = this;
214
+
215
+ self.name = name;
216
+ self.title = title;
217
+ };
knockout/view_models/InstapageCmsPluginMasterModel.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ko, iLang, instapageKO, iAjax, INSTAPAGE_AJAXURL, InstapageCmsPluginSettingsModel, InstapageCmsPluginMessagesModel, InstapageCmsPluginToolbarModel, InstapageCmsPluginPagedGridModel, optionsInitialData */
2
+
3
+ var InstapageCmsPluginMasterModel = function InstapageCmsPluginMasterModel() {
4
+ var self = this;
5
+
6
+ self.settingsModel = null;
7
+ self.editModel = null;
8
+ self.messagesModel = new InstapageCmsPluginMessagesModel();
9
+ self.toolbarModel = new InstapageCmsPluginToolbarModel();
10
+ self.apiTokens = null;
11
+ self.prohibitedSlugs = null;
12
+
13
+ self.updateApiTokens = function updateApiTokens(onSuccessFunction, onFailureFunction) {
14
+ var post = {action: 'getApiTokens'};
15
+ iAjax.post(INSTAPAGE_AJAXURL, post, function updateApiTokensCallback(responseJson) {
16
+ var response = masterModel.parseResponse(responseJson);
17
+
18
+ if (response.status === 'OK') {
19
+ self.apiTokens = response.data;
20
+
21
+ if (typeof onSuccessFunction === 'function') {
22
+ onSuccessFunction();
23
+ }
24
+ } else {
25
+ self.apiTokens = [];
26
+
27
+ if (typeof onSuccessFunction === 'function') {
28
+ onFailureFunction();
29
+ }
30
+ }
31
+ });
32
+ };
33
+
34
+ self.prepareInitialData = function prepareInitialData(obj) {
35
+ obj.initialData.forEach(function prepareInitialSats(element) {
36
+ element.stats_cache = instapageKO.observableArray();
37
+ element.totalStats = instapageKO.observable({
38
+ visits: 0,
39
+ conversions: 0,
40
+ conversionRate: 0
41
+ });
42
+ element.statsLoaded = instapageKO.observable(false);
43
+ element.toDelete = instapageKO.observable(false);
44
+ });
45
+
46
+ return obj;
47
+ };
48
+
49
+ self.parseResponse = function parseResponse(responseJson) {
50
+ try {
51
+ var response = JSON.parse(responseJson);
52
+
53
+ return response;
54
+ } catch (e) {
55
+ return {status: 'ERROR', message: iLang.get('COULDNT_PARSE_RESPONSE')};
56
+ }
57
+ };
58
+
59
+ self.getOptions = function getOptions(onSuccessFunction) {
60
+ if (masterModel.settingsModel) {
61
+ onSuccessFunction(masterModel.settingsModel.getConfig());
62
+ return;
63
+ }
64
+
65
+ iAjax.post(INSTAPAGE_AJAXURL, {action: 'getOptions'}, function getOptionsCallback(responseJson) {
66
+ var response = masterModel.parseResponse(responseJson);
67
+
68
+ if (response.status === 'OK' && response.data && response.data.config) {
69
+ onSuccessFunction(response.data.config);
70
+ return;
71
+ }
72
+ });
73
+ };
74
+
75
+ self.addDiagnosticsWarning = function addDiagnosticsWarning(config) {
76
+ if (config.diagnostics) {
77
+ self.messagesModel.addMessage(iLang.get('DIAGNOSTIC_IS_ON_WARNING'));
78
+ }
79
+ }
80
+
81
+ instapageKO.applyBindings(self.messagesModel, document.getElementById('messages-container'));
82
+ instapageKO.applyBindings(self.toolbarModel, document.getElementById('instapage-toolbar'));
83
+ };
84
+
85
+ var loadPageList = function loadPageList() {
86
+ var post = {
87
+ action: 'loadListPages',
88
+ apiTokens: masterModel.apiTokens
89
+ };
90
+
91
+ iAjax.post(INSTAPAGE_AJAXURL, post, function loadPageListCallback(responseJson) {
92
+ var response = masterModel.parseResponse(responseJson);
93
+ var element = document.getElementById('instapage-container');
94
+
95
+ if (response.status === 'OK') {
96
+ instapageKO.cleanNode(element);
97
+ element.innerHTML = response.html;
98
+
99
+ if (Array.isArray(response.initialData)) {
100
+ response = masterModel.prepareInitialData(response);
101
+ }
102
+
103
+ masterModel.pagedGridModel = new InstapageCmsPluginPagedGridModel(response.initialData);
104
+ instapageKO.applyBindings(masterModel.pagedGridModel, element);
105
+ } else {
106
+ masterModel.messagesModel.addMessage(response.message, response.status);
107
+ element.innerHTML = '';
108
+ }
109
+ });
110
+ };
111
+
112
+ var masterModel = new InstapageCmsPluginMasterModel();
113
+ masterModel.updateApiTokens(loadPageList, loadPageList);
114
+ masterModel.getOptions(masterModel.addDiagnosticsWarning);
knockout/view_models/InstapageCmsPluginMessagesModel.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ko, instapageKO, iAjax, INSTAPAGE_AJAXURL */
2
+
3
+ var InstapageCmsPluginMessagesModel = function InstapageCmsPluginMessagesModel() {
4
+ var self = this;
5
+
6
+ self.options = {
7
+ autoRemove: false,
8
+ messageDuration: 5000
9
+ };
10
+ self.messages = instapageKO.observableArray();
11
+ self.addMessage = function addMessage(text, type) {
12
+ text = self.cURLMessagesFilter(text);
13
+ self.messages.push(new Message(text, type));
14
+
15
+ if (self.options.autoRemove) {
16
+ setTimeout(self.removeOldestMessage, self.options.messageDuration);
17
+ }
18
+ };
19
+
20
+ self.cURLMessagesFilter = function cURLMessagesFilte(text) {
21
+ if(text.search('cURL') > -1) {
22
+ text = "cURL request ended with: \"" +
23
+ text +
24
+ "\" Please contact your server administrator to solve this issue.";
25
+ }
26
+ return text;
27
+ };
28
+
29
+ self.removeOldestMessage = function removeOldestMessage() {self.messages.shift();};
30
+ self.removeMessage = function removeMessage(message) {self.messages.remove(message);};
31
+ self.clear = function clear() {self.messages([]);};
32
+ };
33
+
34
+ var Message = function Message(text, type) {
35
+ var self = this;
36
+
37
+ self.text = text;
38
+ self.type = type;
39
+ };
knockout/view_models/InstapageCmsPluginPagedGridModel.js ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ko, iLang, instapageKO, iAjax, INSTAPAGE_AJAXURL, masterModel */
2
+
3
+ var InstapageCmsPluginPagedGridModel = function InstapageCmsPluginPagedGridModel(items) {
4
+ var self = this;
5
+ var GridViewModel = instapageKO.simpleGrid.viewModel;
6
+ self.deleteThrottle = instapageKO.observable(true);
7
+ self.originalItems = items ? instapageKO.observableArray(items) : instapageKO.observableArray();
8
+ self.query = instapageKO.observable('');
9
+ self.items = instapageKO.computed(function filterItems() {
10
+ var search = self.query().toLowerCase();
11
+
12
+ return instapageKO.utils.arrayFilter(self.originalItems(), function checkItem(item) {
13
+ return ((typeof item.slug !== 'undefined' && item.slug.toLowerCase().indexOf(search) >= 0) || (typeof item.title !== 'undefined' && String(item.title).toLowerCase().indexOf(search) >= 0));
14
+ });
15
+ }, self);
16
+
17
+ self.gridViewModel = new GridViewModel({
18
+ data: self.items,
19
+ pageSize: 10
20
+ });
21
+ self.getStats = function getstats() {
22
+ var pages = [];
23
+
24
+ self.gridViewModel.itemsOnCurrentPage().forEach(function getPageId(element) {
25
+ this.push(element.instapage_id);
26
+ }, pages);
27
+
28
+ var post = {action: 'getStats', apiTokens: masterModel.apiTokens, data: {pages: pages}};
29
+ iAjax.post(INSTAPAGE_AJAXURL, post, function getStatsCallback(responseJson) {
30
+ var response = masterModel.parseResponse(responseJson);
31
+
32
+ if (response.status === 'OK' && response.data) {
33
+ self.gridViewModel.itemsOnCurrentPage().forEach( function updateStats(element) {
34
+ element.stats_cache(response.data[element.instapage_id]);
35
+ element.totalStats(self.getTotalStats(element.stats_cache()));
36
+ element.statsLoaded(true);
37
+ });
38
+ }
39
+ });
40
+ };
41
+
42
+ self.gridViewModel.itemsOnCurrentPage.subscribe(self.getStats);
43
+
44
+ self.askForDeleteConfirmation = function askForDeleteConfirmation(item) {
45
+ item.toDelete(true);
46
+ };
47
+
48
+ self.cancelDelete = function cancelDelete(item) {
49
+ item.toDelete(false);
50
+ };
51
+
52
+ self.deletePage = function deletePage(item) {
53
+ if (self.deleteThrottle.isBusy()) {
54
+ return;
55
+ }
56
+
57
+ self.deleteThrottle.setBusy(true);
58
+ var post = {action: 'deletePage', apiTokens: masterModel.apiTokens, data: {id: item.id}};
59
+
60
+ iAjax.post(INSTAPAGE_AJAXURL, post, function loadEditPageCallback(responseJson) {
61
+ var response = masterModel.parseResponse(responseJson);
62
+ var removeIndex = null;
63
+
64
+ masterModel.messagesModel.addMessage(response.message, response.status);
65
+ self.originalItems.remove(item);
66
+
67
+ if (masterModel.prohibitedSlugs !== null) {
68
+ masterModel.prohibitedSlugs.forEach( function findItemToRemove(arrayItem, index) {
69
+ if (item.slug === arrayItem.slug) {
70
+ removeIndex = index;
71
+ }
72
+ });
73
+
74
+ if (removeIndex !== null) {
75
+ masterModel.prohibitedSlugs.splice(removeIndex, 1);
76
+ }
77
+ }
78
+
79
+ self.deleteThrottle.setBusy(false);
80
+ });
81
+ };
82
+
83
+ self.getTotalStats = function getTotalStats(variations) {
84
+ var stats = {visits: 0, conversions: 0};
85
+ var precision = 100;
86
+
87
+ if (typeof variations !== 'undefined') {
88
+ variations.forEach( function getTotals(element) {
89
+ this.visits += element.visits;
90
+ this.conversions += element.conversions;
91
+ }, stats);
92
+ }
93
+
94
+ stats.conversionRate = stats.visits ? stats.conversions / stats.visits * 100 : 0;
95
+ stats.conversionRate = Math.round(stats.conversionRate * precision) / precision;
96
+
97
+ return stats;
98
+ };
99
+
100
+ self.getStats();
101
+ };
knockout/view_models/InstapageCmsPluginSettingsModel.js ADDED
@@ -0,0 +1,344 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ko, instapageKO, iAjax, iLang, masterModel, INSTAPAGE_AJAXURL, download */
2
+
3
+ var InstapageCmsPluginSettingsModel = function InstapageCmsPluginSettingsModel(data) {
4
+ var self = this;
5
+
6
+ self.email = (data && data.user_name) ? instapageKO.observable(decodeURIComponent(data.user_name)) : instapageKO.observable();
7
+ self.userToken = (data && data.plugin_hash) ? instapageKO.observable(data.plugin_hash) : instapageKO.observable();
8
+ self.password = instapageKO.observable();
9
+ self.clearLog = instapageKO.observable();
10
+ self.tokenToAdd = instapageKO.observable('');
11
+ self.isTokenToAddValid = instapageKO.observable(true);
12
+ self.config = (data && data.config) ? new PluginConfig(data.config) : new PluginConfig();
13
+ self.isLoginAndPasswordValid = instapageKO.observable(true);
14
+ self.connectedTokens = instapageKO.observableArray();
15
+ self.hideConnectedTokens = instapageKO.observable(true);
16
+ self.metadata = (data && data.metadata) ? JSON.parse(data.metadata) : {};
17
+ self.supportLegacy = (typeof self.metadata.supportLegacy !== 'undefined') ? instapageKO.observable(self.metadata.supportLegacy) : instapageKO.observable(true);
18
+
19
+ self.loginUser = function loginUser() {
20
+ var post = {action: 'loginUser', data: {email: encodeURIComponent(self.email()), password: encodeURIComponent(self.password())}};
21
+ iAjax.post(INSTAPAGE_AJAXURL, post, function loginUserCallback(responseJson) {
22
+ var response = masterModel.parseResponse(responseJson);
23
+
24
+ if (response.status === 'OK') {
25
+ self.email(response.data.email);
26
+ self.userToken(response.data.usertoken);
27
+ self.saveConfig(iLang.get('USER_LOGGED_IN'), function getAccountBoundSubAccountsWrapper() {
28
+ post = {action: 'getAccountBoundSubAccounts'};
29
+ iAjax.post(INSTAPAGE_AJAXURL, post, function getAccountBoundSubAccountsCallback(loginResponseJson) {
30
+ var loginResponse = JSON.parse(loginResponseJson);
31
+
32
+ if (loginResponse.status === 'OK' && loginResponse.data) {
33
+ var listItems = [{
34
+ id: 0,
35
+ name: iLang.get('ALL')
36
+ }];
37
+ listItems = listItems.concat(loginResponse.data);
38
+ listItems.forEach(function addCheckedAttribute(element) {
39
+ element.checked = instapageKO.observable(false);
40
+ });
41
+ self.connectedTokens(listItems);
42
+ self.hideConnectedTokens(false);
43
+ }
44
+ });
45
+ });
46
+ self.isLoginAndPasswordValid(true);
47
+ } else {
48
+ var message = response.message ? response.message : iLang.get('EMAIL_OR_PASSWORD_INCORRECT');
49
+ self.isLoginAndPasswordValid(false);
50
+ masterModel.messagesModel.addMessage(message, response.status);
51
+ }
52
+ });
53
+ };
54
+
55
+ self.disconnectAndLogout = function disconnectAndLogout() {
56
+ self.disconnectAccountBoundSubaccounts(self.logoutUser, self.logoutUser);
57
+ };
58
+
59
+ self.logoutUser = function logoutUser() {
60
+ self.email('');
61
+ self.userToken('');
62
+ self.password('');
63
+ self.saveConfig(iLang.get('USER_LOGGED_OUT'));
64
+ self.hideConnectedTokens(true);
65
+ };
66
+
67
+ self.getConfig = function getConfig() {
68
+ return {crossOrigin: self.config.crossOrigin(), diagnostics: self.config.diagnostics(), customParams: self.config.customParams()};
69
+ };
70
+
71
+ self.addToken = function addToken() {
72
+
73
+ if (self.tokenToAdd.isBusy()) {
74
+ return;
75
+ }
76
+
77
+ self.tokenToAdd.setBusy(true);
78
+
79
+ if (self.tokenToAdd) {
80
+ var newToken = new Token(self.tokenToAdd());
81
+ self.validateToken(
82
+ newToken,
83
+ function validationOnSuccess() {
84
+ self.connectSubAccounts([newToken.value()]);
85
+ self.config.tokens.push(newToken);
86
+ self.tokenToAdd('');
87
+ self.isTokenToAddValid(true);
88
+ self.saveConfig(false);
89
+ self.tokenToAdd.setBusy(false);
90
+ },
91
+ function validationOnFailure() {
92
+ self.isTokenToAddValid(false);
93
+ self.tokenToAdd.setBusy(false);
94
+ }
95
+ );
96
+ }
97
+ };
98
+
99
+ self.removeToken = function removeToken(token) {
100
+ if (token.valid() > 0) {
101
+ self.disconnectSubAccounts([token.value()]);
102
+ }
103
+ self.config.tokens.remove(token);
104
+ self.saveConfig(false);
105
+ };
106
+
107
+ self.saveConfig = function saveConfig(message, onSuccessFunction) {
108
+ var configObj = instapageKO.toJS(self.config);
109
+ var metadataObj = instapageKO.toJS(self.metadata);
110
+ var email = (typeof self.email() !== 'undefined') ? self.email() : '';
111
+ var post = {action: 'updateOptions', data: {config: configObj, metadata: metadataObj, userName: encodeURIComponent(email), userToken: self.userToken()}};
112
+
113
+ iAjax.post(INSTAPAGE_AJAXURL, post, function saveConfigCallback(responseJson) {
114
+ var response = masterModel.parseResponse(responseJson);
115
+
116
+ if (response.status === 'OK') {
117
+ if (typeof message === 'string') {
118
+ masterModel.messagesModel.addMessage(message, response.status);
119
+ } else if (message !== false) {
120
+ masterModel.messagesModel.addMessage(response.message, response.status);
121
+ }
122
+
123
+ if (typeof onSuccessFunction === 'function') {
124
+ onSuccessFunction();
125
+ }
126
+ } else {
127
+ masterModel.messagesModel.addMessage(response.message, response.status);
128
+ }
129
+
130
+ masterModel.updateApiTokens();
131
+ });
132
+ };
133
+
134
+ self.migrateDeprecatedData = function migrateDeprecatedData() {
135
+ var post = {action: 'migrateDeprecatedData'};
136
+
137
+ iAjax.post(INSTAPAGE_AJAXURL, post, function migrateDeprecatedDataCallback(responseJson) {
138
+ var response = masterModel.parseResponse(responseJson);
139
+
140
+ if (response.status === 'OK' && response.message) {
141
+ masterModel.messagesModel.addMessage(response.message, response.status);
142
+ } else {
143
+ masterModel.messagesModel.addMessage(iLang.get('NO_DEPRECATED_PAGES_MIGRATED'));
144
+ }
145
+ });
146
+ };
147
+
148
+ self.clearLog = function clearLog() {
149
+ iAjax.post(INSTAPAGE_AJAXURL, {action: 'clearLog'}, function clearLogCallback(responseJson) {
150
+ var response = masterModel.parseResponse(responseJson);
151
+
152
+ masterModel.messagesModel.addMessage(response.message, response.status);
153
+ });
154
+ };
155
+
156
+ self.downloadLog = function downloadLog() {
157
+ iAjax.post(INSTAPAGE_AJAXURL, {action: 'getLog'}, function getLogHTMLCallback(responseJson) {
158
+ var response = masterModel.parseResponse(responseJson);
159
+
160
+ if (response.status === 'OK' && response.data) {
161
+ var date = new Date();
162
+ var dateStr = date.getFullYear() +
163
+ ('0' + (date.getMonth() + 1)).slice(-2) +
164
+ ('0' + date.getDate()).slice(-2) + '-' +
165
+ ('0' + date.getHours()).slice(-2) +
166
+ ('0' + date.getMinutes()).slice(-2) +
167
+ ('0' + date.getSeconds()).slice(-2);
168
+ var filename = response.sitename + '-instapage-diagnostics-' + dateStr + '.html';
169
+
170
+ download( response.data, filename, 'text/html' );
171
+ } else {
172
+ masterModel.messagesModel.addMessage(response.message, response.status);
173
+ }
174
+ });
175
+ };
176
+
177
+ self.validateToken = function validateToken(token, onSuccessFunction, onFailureFunction) {
178
+ if (self.config.tokens().find(
179
+ function checkIfTokenExists(item) {
180
+ return (item !== token && item.value().trim() === token.value().trim());
181
+ })
182
+ ) {
183
+ token.valid(-1);
184
+ masterModel.messagesModel.addMessage(iLang.get('TOKEN_ALREADY_IN_USE'), 'error' );
185
+
186
+ if (typeof onFailureFunction === 'function') {
187
+ onFailureFunction();
188
+ }
189
+
190
+ return;
191
+ }
192
+
193
+ var post = {action: 'validateToken', data: {token: token.value()}};
194
+
195
+ iAjax.post(INSTAPAGE_AJAXURL, post, function saveConfigCallback(responseJson) {
196
+ var response = masterModel.parseResponse(responseJson);
197
+
198
+ if (response.status === 'OK' && response.valid === true) {
199
+ token.valid(1);
200
+
201
+ if (typeof onSuccessFunction === 'function') {
202
+ onSuccessFunction();
203
+ }
204
+ } else {
205
+ token.valid(-1);
206
+
207
+ if (typeof onFailureFunction === 'function') {
208
+ onFailureFunction();
209
+ }
210
+ }
211
+ });
212
+ };
213
+
214
+ self.validateAllTokens = function validateAllTokens() {
215
+ self.config.tokens().forEach( function validateAllTokensCallback(item) {
216
+ self.validateToken(item);
217
+ });
218
+ };
219
+
220
+ self.closeConnectionSection = function closeConnectionSection() {
221
+ self.hideConnectedTokens(true);
222
+ };
223
+
224
+ self.connectSubAccounts = function connectSubAccounts(tokens, onSuccessFunction) {
225
+ var post = {action: 'connectSubAccounts', data: {tokens: tokens}};
226
+
227
+ iAjax.post(INSTAPAGE_AJAXURL, post, function connectSelectedSubAccountCallback(responseJson) {
228
+ var response = masterModel.parseResponse(responseJson);
229
+
230
+ if (response.status === 'OK') {
231
+ masterModel.messagesModel.addMessage(response.message, response.status);
232
+
233
+ if (typeof onSuccessFunction === 'function') {
234
+ onSuccessFunction();
235
+ }
236
+ } else {
237
+ masterModel.messagesModel.addMessage(iLang.get('ERROR_WHILE_CONNECTING_SUBACCOUNTS'), 'error' );
238
+ }
239
+ });
240
+ };
241
+
242
+ self.disconnectSubAccounts = function disconnectSubAccounts(tokens, onSuccessFunction) {
243
+ var post = {action: 'disconnectSubAccounts', data: {tokens: tokens}};
244
+
245
+ iAjax.post(INSTAPAGE_AJAXURL, post, function disconnectSubAccountsCallback(responseJson) {
246
+ var response = masterModel.parseResponse(responseJson);
247
+
248
+ if (response.status === 'OK') {
249
+ masterModel.messagesModel.addMessage(response.message, response.status);
250
+
251
+ if (typeof onSuccessFunction === 'function') {
252
+ onSuccessFunction();
253
+ }
254
+ } else {
255
+ masterModel.messagesModel.addMessage(iLang.get('ERROR_WHILE_DISCONNECTING_SUBACCOUNTS'), 'error' );
256
+ }
257
+ });
258
+ };
259
+
260
+ self.disconnectAccountBoundSubaccounts = function disconnectAccountBoundSubaccounts(onSuccessFunction, onFailureFunction) {
261
+ var post = {action: 'disconnectAccountBoundSubaccounts'};
262
+
263
+ iAjax.post(INSTAPAGE_AJAXURL, post, function disconnectAccountBoundSubaccountsCallback(responseJson) {
264
+ var response = masterModel.parseResponse(responseJson);
265
+
266
+ if (response.status === 'OK') {
267
+ masterModel.messagesModel.addMessage(response.message, response.status);
268
+
269
+ if (typeof onSuccessFunction === 'function') {
270
+ onSuccessFunction();
271
+ }
272
+ } else {
273
+ masterModel.messagesModel.addMessage(iLang.get('ERROR_WHILE_DISCONNECTING_SUBACCOUNTS'), 'error' );
274
+
275
+ if (typeof onFailureFunction === 'function') {
276
+ onFailureFunction();
277
+ }
278
+ }
279
+ });
280
+ };
281
+
282
+ self.connectSelectedSubAccounts = function connectSelectedSubAccounts() {
283
+ var subAccountToConnect = [];
284
+ self.connectedTokens().forEach(function gatherSubAccountToConnect(element) {
285
+ if (element.id !== 0 && element.checked()) {
286
+ this.push(element.accountkey);
287
+ }
288
+ }, subAccountToConnect);
289
+ self.connectSubAccounts(subAccountToConnect, function hideConnectedTokensWrapper() {
290
+ self.hideConnectedTokens(true);
291
+ });
292
+ };
293
+
294
+ self.toggleAllSubaccounts = function toggleAllSubaccounts(checkbox) {
295
+ if (checkbox.id === 0) {
296
+ var checkedValue = false;
297
+
298
+ if (checkbox.checked()) {
299
+ checkedValue = true;
300
+ }
301
+
302
+ self.connectedTokens().forEach(function toggleConnectedTokent(element) {
303
+ element.checked(checkedValue);
304
+ });
305
+ }
306
+
307
+ return true;
308
+ };
309
+
310
+ self.autoSaveConfig = function autoSaveConfig() {
311
+ self.saveConfig(false);
312
+
313
+ return true;
314
+ };
315
+
316
+ self.autoSaveMetadata = function autosaveMetadata() {
317
+ self.metadata.supportLegacy = self.supportLegacy();
318
+ self.saveConfig(false);
319
+
320
+ return true;
321
+ };
322
+ };
323
+
324
+ var PluginConfig = function PluginConfig(data) {
325
+ var self = this;
326
+
327
+ self.crossOrigin = data ? instapageKO.observable(data.crossOrigin) : instapageKO.observable(false);
328
+ self.diagnostics = data ? instapageKO.observable(data.diagnostics) : instapageKO.observable(false);
329
+ self.customParams = data ? instapageKO.observable(data.customParams) : instapageKO.observable('');
330
+ self.tokens = instapageKO.observableArray();
331
+
332
+ if ( data && data.tokens && Array.isArray(data.tokens) ) {
333
+ data.tokens.forEach( function prepareTokens(element) {
334
+ self.tokens.push(new Token(element.value, element.valid));
335
+ });
336
+ }
337
+ };
338
+
339
+ var Token = function Token(value, valid) {
340
+ var self = this;
341
+
342
+ self.value = instapageKO.observable(value);
343
+ self.valid = typeof valid !== 'undefined' ? instapageKO.observable(valid) : instapageKO.observable(0);
344
+ };
knockout/view_models/InstapageCmsPluginToolbarModel.js ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals ko, iLang, instapageKO, iAjax, masterModel, InstapageCmsPluginPagedGridModel, InstapageCmsPluginSettingsModel, InstapageCmsPluginEditModel, INSTAPAGE_AJAXURL */
2
+ var InstapageCmsPluginToolbarModel = function InstapageCmsPluginToolbarModel() {
3
+ var self = this;
4
+
5
+ self.loadListPages = function loadListPages() {
6
+ var element = document.getElementById('instapage-container');
7
+
8
+ masterModel.messagesModel.clear();
9
+ element.innerHTML = self.getLoader();
10
+
11
+ loadPageList();
12
+ self.setActiveTab('listing-view');
13
+ };
14
+
15
+ self.loadEditPage = function loadEditPage(item) {
16
+ var post = null;
17
+ var element = document.getElementById('instapage-container');
18
+
19
+ masterModel.messagesModel.clear();
20
+ element.innerHTML = self.getLoader();
21
+
22
+ if (typeof item.id !== 'undefined') {
23
+ post = {action: 'loadEditPage', apiTokens: masterModel.apiTokens, data: item};
24
+ } else {
25
+ post = {action: 'loadEditPage', apiTokens: masterModel.apiTokens};
26
+ }
27
+
28
+ iAjax.post(INSTAPAGE_AJAXURL, post, function loadEditPageCallback(responseJson) {
29
+ var response = masterModel.parseResponse(responseJson);
30
+
31
+ if (response.status === 'OK') {
32
+ instapageKO.cleanNode(element);
33
+ element.innerHTML = response.html;
34
+ masterModel.editModel = new InstapageCmsPluginEditModel(response.data);
35
+ instapageKO.applyBindings(masterModel.editModel, element);
36
+ self.setActiveTab('edit-view');
37
+ } else {
38
+ element.innerHTML = ''; // remove loader on fail
39
+ masterModel.messagesModel.addMessage(response.message, response.status);
40
+ }
41
+ });
42
+ };
43
+
44
+ self.loadSettings = function loadSettings() {
45
+ var element = document.getElementById('instapage-container');
46
+
47
+ masterModel.messagesModel.clear();
48
+ element.innerHTML = self.getLoader();
49
+
50
+ iAjax.post(INSTAPAGE_AJAXURL, {action: 'loadSettings', apiTokens: masterModel.apiTokens}, function clearLogCallback(responseJson) {
51
+ var response = masterModel.parseResponse(responseJson);
52
+
53
+ if (response.status === 'OK') {
54
+ instapageKO.cleanNode(element);
55
+ element.innerHTML = response.html;
56
+ masterModel.settingsModel = new InstapageCmsPluginSettingsModel(response.initialData);
57
+ instapageKO.applyBindings(masterModel.settingsModel, element);
58
+ self.setActiveTab('settings-view');
59
+ masterModel.settingsModel.validateAllTokens();
60
+ } else {
61
+ masterModel.messagesModel.addMessage(response.message, response.status);
62
+ }
63
+ });
64
+ };
65
+
66
+ self.getLoader = function getLoader() {
67
+ var html = '<div class="l-group__item page-loader">' +
68
+ '<span class="c-loader c-loader--x-large"></span>' +
69
+ '</div>';
70
+
71
+ return html;
72
+ };
73
+
74
+ self.setActiveTab = function setActiveTab(tabClassName) {
75
+ var tabs = document.getElementById('instapage-toolbar').getElementsByClassName('c-tab');
76
+ var tabToChange = document.getElementById('instapage-toolbar').getElementsByClassName('c-tab ' + tabClassName);
77
+
78
+ if (tabToChange.length) {
79
+ tabToChange = tabToChange[0];
80
+ } else {
81
+ return;
82
+ }
83
+
84
+ for (var i = 0; i < tabs.length; ++i) {
85
+ tabs[i].classList.remove('is-active');
86
+ }
87
+
88
+ tabToChange.classList.add('is-active');
89
+ document.whitekitTabsInit();
90
+ masterModel.getOptions(masterModel.addDiagnosticsWarning);
91
+ };
92
+ };
license.txt ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Instapage Wordpress Plugin
2
+
3
+ Copyright 2013 instapage.com
4
+
5
+ This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+
19
+ This program incorporates work covered by the following copyright and
20
+ permission notices:
21
+
22
+ Wherever third party code has been used, credit has been given in the code's
23
+ comments.
24
+
25
+ and
26
+
27
+ Instapage Wordpress Plugin
28
+
29
+ Copyright 2010-2013 Instapage
30
+
31
+ Instapage Wordpress Plugin is released under the GPL
32
+
33
+ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
34
+
35
+ GNU GENERAL PUBLIC LICENSE
36
+ Version 2, June 1991
37
+
38
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
39
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
40
+ Everyone is permitted to copy and distribute verbatim copies
41
+ of this license document, but changing it is not allowed.
42
+
43
+ Preamble
44
+
45
+ The licenses for most software are designed to take away your
46
+ freedom to share and change it. By contrast, the GNU General Public
47
+ License is intended to guarantee your freedom to share and change free
48
+ software--to make sure the software is free for all its users. This
49
+ General Public License applies to most of the Free Software
50
+ Foundation's software and to any other program whose authors commit to
51
+ using it. (Some other Free Software Foundation software is covered by
52
+ the GNU Lesser General Public License instead.) You can apply it to
53
+ your programs, too.
54
+
55
+ When we speak of free software, we are referring to freedom, not
56
+ price. Our General Public Licenses are designed to make sure that you
57
+ have the freedom to distribute copies of free software (and charge for
58
+ this service if you wish), that you receive source code or can get it
59
+ if you want it, that you can change the software or use pieces of it
60
+ in new free programs; and that you know you can do these things.
61
+
62
+ To protect your rights, we need to make restrictions that forbid
63
+ anyone to deny you these rights or to ask you to surrender the rights.
64
+ These restrictions translate to certain responsibilities for you if you
65
+ distribute copies of the software, or if you modify it.
66
+
67
+ For example, if you distribute copies of such a program, whether
68
+ gratis or for a fee, you must give the recipients all the rights that
69
+ you have. You must make sure that they, too, receive or can get the
70
+ source code. And you must show them these terms so they know their
71
+ rights.
72
+
73
+ We protect your rights with two steps: (1) copyright the software, and
74
+ (2) offer you this license which gives you legal permission to copy,
75
+ distribute and/or modify the software.
76
+
77
+ Also, for each author's protection and ours, we want to make certain
78
+ that everyone understands that there is no warranty for this free
79
+ software. If the software is modified by someone else and passed on, we
80
+ want its recipients to know that what they have is not the original, so
81
+ that any problems introduced by others will not reflect on the original
82
+ authors' reputations.
83
+
84
+ Finally, any free program is threatened constantly by software
85
+ patents. We wish to avoid the danger that redistributors of a free
86
+ program will individually obtain patent licenses, in effect making the
87
+ program proprietary. To prevent this, we have made it clear that any
88
+ patent must be licensed for everyone's free use or not licensed at all.
89
+
90
+ The precise terms and conditions for copying, distribution and
91
+ modification follow.
92
+
93
+ GNU GENERAL PUBLIC LICENSE
94
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
95
+
96
+ 0. This License applies to any program or other work which contains
97
+ a notice placed by the copyright holder saying it may be distributed
98
+ under the terms of this General Public License. The "Program", below,
99
+ refers to any such program or work, and a "work based on the Program"
100
+ means either the Program or any derivative work under copyright law:
101
+ that is to say, a work containing the Program or a portion of it,
102
+ either verbatim or with modifications and/or translated into another
103
+ language. (Hereinafter, translation is included without limitation in
104
+ the term "modification".) Each licensee is addressed as "you".
105
+
106
+ Activities other than copying, distribution and modification are not
107
+ covered by this License; they are outside its scope. The act of
108
+ running the Program is not restricted, and the output from the Program
109
+ is covered only if its contents constitute a work based on the
110
+ Program (independent of having been made by running the Program).
111
+ Whether that is true depends on what the Program does.
112
+
113
+ 1. You may copy and distribute verbatim copies of the Program's
114
+ source code as you receive it, in any medium, provided that you
115
+ conspicuously and appropriately publish on each copy an appropriate
116
+ copyright notice and disclaimer of warranty; keep intact all the
117
+ notices that refer to this License and to the absence of any warranty;
118
+ and give any other recipients of the Program a copy of this License
119
+ along with the Program.
120
+
121
+ You may charge a fee for the physical act of transferring a copy, and
122
+ you may at your option offer warranty protection in exchange for a fee.
123
+
124
+ 2. You may modify your copy or copies of the Program or any portion
125
+ of it, thus forming a work based on the Program, and copy and
126
+ distribute such modifications or work under the terms of Section 1
127
+ above, provided that you also meet all of these conditions:
128
+
129
+ a) You must cause the modified files to carry prominent notices
130
+ stating that you changed the files and the date of any change.
131
+
132
+ b) You must cause any work that you distribute or publish, that in
133
+ whole or in part contains or is derived from the Program or any
134
+ part thereof, to be licensed as a whole at no charge to all third
135
+ parties under the terms of this License.
136
+
137
+ c) If the modified program normally reads commands interactively
138
+ when run, you must cause it, when started running for such
139
+ interactive use in the most ordinary way, to print or display an
140
+ announcement including an appropriate copyright notice and a
141
+ notice that there is no warranty (or else, saying that you provide
142
+ a warranty) and that users may redistribute the program under
143
+ these conditions, and telling the user how to view a copy of this
144
+ License. (Exception: if the Program itself is interactive but
145
+ does not normally print such an announcement, your work based on
146
+ the Program is not required to print an announcement.)
147
+
148
+ These requirements apply to the modified work as a whole. If
149
+ identifiable sections of that work are not derived from the Program,
150
+ and can be reasonably considered independent and separate works in
151
+ themselves, then this License, and its terms, do not apply to those
152
+ sections when you distribute them as separate works. But when you
153
+ distribute the same sections as part of a whole which is a work based
154
+ on the Program, the distribution of the whole must be on the terms of
155
+ this License, whose permissions for other licensees extend to the
156
+ entire whole, and thus to each and every part regardless of who wrote it.
157
+
158
+ Thus, it is not the intent of this section to claim rights or contest
159
+ your rights to work written entirely by you; rather, the intent is to
160
+ exercise the right to control the distribution of derivative or
161
+ collective works based on the Program.
162
+
163
+ In addition, mere aggregation of another work not based on the Program
164
+ with the Program (or with a work based on the Program) on a volume of
165
+ a storage or distribution medium does not bring the other work under
166
+ the scope of this License.
167
+
168
+ 3. You may copy and distribute the Program (or a work based on it,
169
+ under Section 2) in object code or executable form under the terms of
170
+ Sections 1 and 2 above provided that you also do one of the following:
171
+
172
+ a) Accompany it with the complete corresponding machine-readable
173
+ source code, which must be distributed under the terms of Sections
174
+ 1 and 2 above on a medium customarily used for software interchange; or,
175
+
176
+ b) Accompany it with a written offer, valid for at least three
177
+ years, to give any third party, for a charge no more than your
178
+ cost of physically performing source distribution, a complete
179
+ machine-readable copy of the corresponding source code, to be
180
+ distributed under the terms of Sections 1 and 2 above on a medium
181
+ customarily used for software interchange; or,
182
+
183
+ c) Accompany it with the information you received as to the offer
184
+ to distribute corresponding source code. (This alternative is
185
+ allowed only for noncommercial distribution and only if you
186
+ received the program in object code or executable form with such
187
+ an offer, in accord with Subsection b above.)
188
+
189
+ The source code for a work means the preferred form of the work for
190
+ making modifications to it. For an executable work, complete source
191
+ code means all the source code for all modules it contains, plus any
192
+ associated interface definition files, plus the scripts used to
193
+ control compilation and installation of the executable. However, as a
194
+ special exception, the source code distributed need not include
195
+ anything that is normally distributed (in either source or binary
196
+ form) with the major components (compiler, kernel, and so on) of the
197
+ operating system on which the executable runs, unless that component
198
+ itself accompanies the executable.
199
+
200
+ If distribution of executable or object code is made by offering
201
+ access to copy from a designated place, then offering equivalent
202
+ access to copy the source code from the same place counts as
203
+ distribution of the source code, even though third parties are not
204
+ compelled to copy the source along with the object code.
205
+
206
+ 4. You may not copy, modify, sublicense, or distribute the Program
207
+ except as expressly provided under this License. Any attempt
208
+ otherwise to copy, modify, sublicense or distribute the Program is
209
+ void, and will automatically terminate your rights under this License.
210
+ However, parties who have received copies, or rights, from you under
211
+ this License will not have their licenses terminated so long as such
212
+ parties remain in full compliance.
213
+
214
+ 5. You are not required to accept this License, since you have not
215
+ signed it. However, nothing else grants you permission to modify or
216
+ distribute the Program or its derivative works. These actions are
217
+ prohibited by law if you do not accept this License. Therefore, by
218
+ modifying or distributing the Program (or any work based on the
219
+ Program), you indicate your acceptance of this License to do so, and
220
+ all its terms and conditions for copying, distributing or modifying
221
+ the Program or works based on it.
222
+
223
+ 6. Each time you redistribute the Program (or any work based on the
224
+ Program), the recipient automatically receives a license from the
225
+ original licensor to copy, distribute or modify the Program subject to
226
+ these terms and conditions. You may not impose any further
227
+ restrictions on the recipients' exercise of the rights granted herein.
228
+ You are not responsible for enforcing compliance by third parties to
229
+ this License.
230
+
231
+ 7. If, as a consequence of a court judgment or allegation of patent
232
+ infringement or for any other reason (not limited to patent issues),
233
+ conditions are imposed on you (whether by court order, agreement or
234
+ otherwise) that contradict the conditions of this License, they do not
235
+ excuse you from the conditions of this License. If you cannot
236
+ distribute so as to satisfy simultaneously your obligations under this
237
+ License and any other pertinent obligations, then as a consequence you
238
+ may not distribute the Program at all. For example, if a patent
239
+ license would not permit royalty-free redistribution of the Program by
240
+ all those who receive copies directly or indirectly through you, then
241
+ the only way you could satisfy both it and this License would be to
242
+ refrain entirely from distribution of the Program.
243
+
244
+ If any portion of this section is held invalid or unenforceable under
245
+ any particular circumstance, the balance of the section is intended to
246
+ apply and the section as a whole is intended to apply in other
247
+ circumstances.
248
+
249
+ It is not the purpose of this section to induce you to infringe any
250
+ patents or other property right claims or to contest validity of any
251
+ such claims; this section has the sole purpose of protecting the
252
+ integrity of the free software distribution system, which is
253
+ implemented by public license practices. Many people have made
254
+ generous contributions to the wide range of software distributed
255
+ through that system in reliance on consistent application of that
256
+ system; it is up to the author/donor to decide if he or she is willing
257
+ to distribute software through any other system and a licensee cannot
258
+ impose that choice.
259
+
260
+ This section is intended to make thoroughly clear what is believed to
261
+ be a consequence of the rest of this License.
262
+
263
+ 8. If the distribution and/or use of the Program is restricted in
264
+ certain countries either by patents or by copyrighted interfaces, the
265
+ original copyright holder who places the Program under this License
266
+ may add an explicit geographical distribution limitation excluding
267
+ those countries, so that distribution is permitted only in or among
268
+ countries not thus excluded. In such case, this License incorporates
269
+ the limitation as if written in the body of this License.
270
+
271
+ 9. The Free Software Foundation may publish revised and/or new versions
272
+ of the General Public License from time to time. Such new versions will
273
+ be similar in spirit to the present version, but may differ in detail to
274
+ address new problems or concerns.
275
+
276
+ Each version is given a distinguishing version number. If the Program
277
+ specifies a version number of this License which applies to it and "any
278
+ later version", you have the option of following the terms and conditions
279
+ either of that version or of any later version published by the Free
280
+ Software Foundation. If the Program does not specify a version number of
281
+ this License, you may choose any version ever published by the Free Software
282
+ Foundation.
283
+
284
+ 10. If you wish to incorporate parts of the Program into other free
285
+ programs whose distribution conditions are different, write to the author
286
+ to ask for permission. For software which is copyrighted by the Free
287
+ Software Foundation, write to the Free Software Foundation; we sometimes
288
+ make exceptions for this. Our decision will be guided by the two goals
289
+ of preserving the free status of all derivatives of our free software and
290
+ of promoting the sharing and reuse of software generally.
291
+
292
+ NO WARRANTY
293
+
294
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
295
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
296
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
297
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
298
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
299
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
300
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
301
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
302
+ REPAIR OR CORRECTION.
303
+
304
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
305
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
306
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
307
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
308
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
309
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
310
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
311
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
312
+ POSSIBILITY OF SUCH DAMAGES.
313
+
314
+ END OF TERMS AND CONDITIONS
315
+
316
+ How to Apply These Terms to Your New Programs
317
+
318
+ If you develop a new program, and you want it to be of the greatest
319
+ possible use to the public, the best way to achieve this is to make it
320
+ free software which everyone can redistribute and change under these terms.
321
+
322
+ To do so, attach the following notices to the program. It is safest
323
+ to attach them to the start of each source file to most effectively
324
+ convey the exclusion of warranty; and each file should have at least
325
+ the "copyright" line and a pointer to where the full notice is found.
326
+
327
+ <one line to give the program's name and a brief idea of what it does.>
328
+ Copyright (C) <year> <name of author>
329
+
330
+ This program is free software; you can redistribute it and/or modify
331
+ it under the terms of the GNU General Public License as published by
332
+ the Free Software Foundation; either version 2 of the License, or
333
+ (at your option) any later version.
334
+
335
+ This program is distributed in the hope that it will be useful,
336
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
337
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
338
+ GNU General Public License for more details.
339
+
340
+ You should have received a copy of the GNU General Public License along
341
+ with this program; if not, write to the Free Software Foundation, Inc.,
342
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
343
+
344
+ Also add information on how to contact you by electronic and paper mail.
345
+
346
+ If the program is interactive, make it output a short notice like this
347
+ when it starts in an interactive mode:
348
+
349
+ Gnomovision version 69, Copyright (C) year name of author
350
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
351
+ This is free software, and you are welcome to redistribute it
352
+ under certain conditions; type `show c' for details.
353
+
354
+ The hypothetical commands `show w' and `show c' should show the appropriate
355
+ parts of the General Public License. Of course, the commands you use may
356
+ be called something other than `show w' and `show c'; they could even be
357
+ mouse-clicks or menu items--whatever suits your program.
358
+
359
+ You should also get your employer (if you work as a programmer) or your
360
+ school, if any, to sign a "copyright disclaimer" for the program, if
361
+ necessary. Here is a sample; alter the names:
362
+
363
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
364
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
365
+
366
+ <signature of Ty Coon>, 1 April 1989
367
+ Ty Coon, President of Vice
368
+
369
+ This General Public License does not permit incorporating your program into
370
+ proprietary programs. If your program is a subroutine library, you may
371
+ consider it more useful to permit linking proprietary applications with the
372
+ library. If this is what you want to do, use the GNU Lesser General
373
+ Public License instead of this License.
374
+
models/InstapageCmsPluginAPIModel.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class responsible for communication with Instapage app via API.
5
+ */
6
+ class InstapageCmsPluginAPIModel {
7
+
8
+ /**
9
+ * @var object API model instance.
10
+ */
11
+ private static $apiModel = null;
12
+
13
+ /**
14
+ * Gets the class instance.
15
+ *
16
+ * @return object Class instance.
17
+ */
18
+ public static function getInstance() {
19
+ if (self::$apiModel === null) {
20
+ self::$apiModel = new InstapageCmsPluginAPIModel();
21
+ }
22
+
23
+ return self::$apiModel;
24
+ }
25
+
26
+ /**
27
+ * Performs the remote post based on selected CMS.
28
+ *
29
+ * @return object Result of the request in unified form.
30
+ */
31
+ public function remotePost($url, $data = array(), $headers = array()) {
32
+ return InstapageCmsPluginConnector::getSelectedConnector()->remotePost($url, $data, $headers);
33
+ }
34
+
35
+ /**
36
+ * Performs the request to Instapage pageserver.
37
+ *
38
+ * @param string $url URL of the request.
39
+ * @param string $host Host of the request. It will be used for request header.
40
+ * @param array $cookies Cookie array.
41
+ *
42
+ * @return object $response Request response.
43
+ */
44
+ public function enterpriseCall($url, $host = '', $cookies = false) {
45
+ $data = array();
46
+ $headers = array();
47
+ $host = $host ? $host : $_SERVER['HTTP_HOST'];
48
+ $integration = InstapageCmsPluginConnector::getSelectedConnector()->name;
49
+ $data['integration'] = $integration;
50
+ $data['useragent'] = $_SERVER['HTTP_USER_AGENT'];
51
+ $data['ip'] = $_SERVER['REMOTE_ADDR'];
52
+ $data['cookies'] = $cookies;
53
+ $data['custom'] = @InstapageCmsPluginHelper::getVar($_GET['custom'], null);
54
+ $data['variant'] = @InstapageCmsPluginHelper::getVar($_GET['variant'], null);
55
+ $data['requestHost'] = $host;
56
+ $headers['integration'] = $integration;
57
+ $headers['host'] = $host;
58
+ $response = InstapageCmsPluginConnector::getSelectedConnector()->remoteRequest($url, $data, $headers, 'POST');
59
+
60
+ InstapageCmsPluginHelper::writeDiagnostics($url, 'Enterprise call URL');
61
+ InstapageCmsPluginHelper::writeDiagnostics($host, 'Enterprise call host');
62
+ InstapageCmsPluginHelper::writeDiagnostics($headers, 'Enterprise call headers');
63
+ InstapageCmsPluginHelper::writeDiagnostics($data, 'Enterprise call data');
64
+ InstapageCmsPluginHelper::writeDiagnostics($response, 'Enterprise call response');
65
+
66
+ return $response;
67
+ }
68
+
69
+ /**
70
+ * Performs the request to Instapage app.
71
+ *
72
+ * @param string $action API action.
73
+ * @param array $data Data to be passed in the request.
74
+ * @param array $headers Headers for the request.
75
+ * @param string $method Request type. 'POST' ang 'GET' are allowed. Default: 'POST'.
76
+ *
77
+ * @return object $response Request response.
78
+ */
79
+ public function apiCall($action, $data = array(), $headers = array(), $method = 'POST') {
80
+ $integration = InstapageCmsPluginConnector::getSelectedConnector()->name;
81
+ $url = INSTAPAGE_APP_ENDPOINT . '/' . $action;
82
+ $headers['integration'] = $integration;
83
+ $response = InstapageCmsPluginConnector::getSelectedConnector()->remoteRequest($url, $data, $headers, $method);
84
+
85
+ InstapageCmsPluginHelper::writeDiagnostics($method . ' : ' . $url, 'API ' . $action . ' URL');
86
+ InstapageCmsPluginHelper::writeDiagnostics($data, 'API ' . $action . ' data');
87
+ InstapageCmsPluginHelper::writeDiagnostics($headers, 'API ' . $action . ' headers');
88
+ InstapageCmsPluginHelper::writeDiagnostics($response, 'API ' . $action . ' response');
89
+
90
+ return (is_array($response) && isset($response['body'])) ? $response['body'] : null;
91
+ }
92
+
93
+ /**
94
+ * Authorizes the user based on email and password.
95
+ *
96
+ * @param string $email Email address.
97
+ * @param string password Password.
98
+ *
99
+ * @uses InstapageCmsPluginAPIModel::apiCall() to communicate with Instapage app.
100
+ *
101
+ * @return object App response.
102
+ */
103
+ public function authorise($email, $password) {
104
+ $data = array('email' => $email, 'password' => $password);
105
+ $response = $this->apiCall('page', $data);
106
+
107
+ return $response;
108
+ }
109
+ }
models/InstapageCmsPluginDBModel.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class responsible for communication with DB.
5
+ */
6
+ class InstapageCmsPluginDBModel {
7
+
8
+ /**
9
+ * @var object Class instance.
10
+ */
11
+ private static $dbModel = null;
12
+
13
+ /**
14
+ * @var string DB prefix.
15
+ */
16
+ public $prefix = null;
17
+
18
+ /**
19
+ * @var string Charset collatation.
20
+ */
21
+ public $charsetCollate = null;
22
+
23
+ /**
24
+ * @var string Options table name.
25
+ */
26
+ public $optionsTable = null;
27
+
28
+ /**
29
+ * @var string Pages table name.
30
+ */
31
+ public $pagesTable = null;
32
+
33
+ /**
34
+ * @var Debug log table name.
35
+ */
36
+ public $debugTable = null;
37
+
38
+ /**
39
+ * Class constructor. Sets the properties based on current CMS settings.
40
+ */
41
+ function __construct() {
42
+ $this->prefix = InstapageCmsPluginConnector::getSelectedConnector()->getDBPrefix();
43
+ $this->charsetCollate = InstapageCmsPluginConnector::getSelectedConnector()->getCharsetCollate();
44
+ $this->optionsTable = $this->prefix . 'instapage_options';
45
+ $this->pagesTable = $this->prefix . 'instapage_pages';
46
+ $this->debugTable = $this->prefix . 'instapage_debug';
47
+ }
48
+
49
+ /**
50
+ * Gets the class instance.
51
+ *
52
+ * @return object Class instance.
53
+ */
54
+ public static function getInstance() {
55
+ if (self::$dbModel === null) {
56
+ self::$dbModel = new InstapageCmsPluginDBModel();
57
+ }
58
+
59
+ return self::$dbModel;
60
+ }
61
+
62
+ /**
63
+ * Executes a SQL query.
64
+ *
65
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
66
+ * @return bool True if the query is successful. DB error is logged and false if returned otherwise.
67
+ */
68
+ public function query($sql) {
69
+ $args = func_get_args();
70
+ array_shift($args);
71
+
72
+ if (isset($args[0]) && is_array($args[0]) ) {
73
+ $args = $args[0];
74
+ }
75
+
76
+ return InstapageCmsPluginConnector::getSelectedConnector()->query($sql, $args);
77
+ }
78
+
79
+ /**
80
+ * Gets the last ID of an insert query.
81
+ *
82
+ * @return integer|boolean Last insert ID of false on error.
83
+ */
84
+ public function lastInsertId() {
85
+ return InstapageCmsPluginConnector::getSelectedConnector()->lastInsertId();
86
+ }
87
+
88
+ /**
89
+ * Executes the query and returns the first row.
90
+ *
91
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
92
+ * @return mixed first row of results of the query.
93
+ */
94
+ public function getRow($sql) {
95
+ $args = func_get_args();
96
+ array_shift($args);
97
+
98
+ if (isset($args[0]) && is_array($args[0]) ) {
99
+ $args = $args[0];
100
+ }
101
+
102
+ return InstapageCmsPluginConnector::getSelectedConnector()->getRow($sql, $args);
103
+ }
104
+
105
+ /**
106
+ * Executes the query and returns a list of results.
107
+ *
108
+ * @param string $sql SQL to execute. %s can be used to output pre-formatted values. Values for %s can be passed as arguments for this function.
109
+ * @return mixed first row of results of the query.
110
+ */
111
+ public static function getResults($sql) {
112
+ $args = func_get_args();
113
+ array_shift($args);
114
+
115
+ if (isset($args[0]) && is_array($args[0]) ) {
116
+ $args = $args[0];
117
+ }
118
+
119
+ return InstapageCmsPluginConnector::getSelectedConnector()->getResults($sql, $args);
120
+ }
121
+
122
+ /**
123
+ * Initiates Instapage plugin's DB structure.
124
+ */
125
+ public function initPluginTables() {
126
+ $this->initOptionsTable();
127
+ $this->initPagesTable();
128
+ $this->initDebugTable();
129
+ $this->updateDB();
130
+ }
131
+
132
+ /**
133
+ * Initiates Instapage plugin's DB structure for options table.
134
+ */
135
+ private function initOptionsTable() {
136
+ $sql = sprintf('SHOW TABLES LIKE \'%s\'', $this->optionsTable);
137
+ $result = $this->getRow($sql);
138
+
139
+ if ($result) {
140
+ return true;
141
+ }
142
+
143
+ $sql = sprintf('CREATE TABLE IF NOT EXISTS %s(' .
144
+ 'id MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT, ' .
145
+ 'plugin_hash VARCHAR(255) DEFAULT \'\', ' .
146
+ 'api_keys TEXT NULL, ' .
147
+ 'user_name VARCHAR(255) DEFAULT \'\', ' .
148
+ 'config TEXT NULL, ' .
149
+ 'metadata TEXT NULL, ' .
150
+ 'UNIQUE KEY id (id)) %s', $this->optionsTable, $this->charsetCollate);
151
+
152
+ $this->query($sql);
153
+ }
154
+
155
+ /**
156
+ * Initiates Instapage plugin's DB structure for pages table.
157
+ */
158
+ private function initPagesTable() {
159
+ $sql = sprintf('SHOW TABLES LIKE \'%s\'', $this->pagesTable);
160
+ $result = $this->getRow($sql);
161
+
162
+ if ($result) {
163
+ return true;
164
+ }
165
+
166
+ $sql = sprintf('CREATE TABLE IF NOT EXISTS %s(' .
167
+ 'id MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT, ' .
168
+ 'instapage_id INT UNSIGNED NOT NULL, ' .
169
+ 'slug VARCHAR(255) DEFAULT \'\' NOT NULL, ' .
170
+ 'type VARCHAR(4) DEFAULT \'page\' NOT NULL, ' .
171
+ 'time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, ' .
172
+ 'stats_cache TEXT NULL, ' .
173
+ 'stats_cache_expires INT UNSIGNED, ' .
174
+ 'enterprise_url VARCHAR(255) DEFAULT \'\' NOT NULL, ' .
175
+ 'UNIQUE KEY id (id)) %s', $this->pagesTable, $this->charsetCollate );
176
+
177
+ $this->query($sql);
178
+ }
179
+
180
+ /**
181
+ * Initiates Instapage plugin's DB structure for debug table.
182
+ */
183
+ private function initDebugTable() {
184
+ $sql = sprintf('SHOW TABLES LIKE \'%s\'', $this->debugTable);
185
+ $result = $this->getRow($sql);
186
+
187
+ if ($result) {
188
+ return true;
189
+ }
190
+
191
+ $sql = sprintf('CREATE TABLE IF NOT EXISTS %s(' .
192
+ 'id MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT, ' .
193
+ 'time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, ' .
194
+ 'text TEXT NULL, ' .
195
+ 'caller VARCHAR(255) DEFAULT \'\' NOT NULL, ' .
196
+ 'name VARCHAR(255) DEFAULT \'\' NOT NULL, ' .
197
+ 'UNIQUE KEY id (id)) %s', $this->debugTable, $this->charsetCollate );
198
+
199
+ $this->query($sql);
200
+ }
201
+
202
+ /**
203
+ * Check current DB structure version and updates it if necessary.
204
+ */
205
+ private function updateDB() {
206
+ $db_version = intval(InstapageCmsPluginHelper::getMetadata('db_version', 0), 10);
207
+
208
+ if ($db_version < 300000010) {
209
+ InstapageCmsPluginHelper::writeDiagnostics($db_version, 'Current db version. Doing update.');
210
+ $sql = 'SHOW COLUMNS FROM ' . $this->optionsTable . ' LIKE %s';
211
+ $metadata_exists = $this->getRow($sql, 'metadata');
212
+ $sql = 'SHOW COLUMNS FROM ' . $this->pagesTable . ' LIKE %s';
213
+ $enterprise_url_exists = $this->getRow($sql, 'enterprise_url');
214
+
215
+ if (!$metadata_exists) {
216
+ $sql = sprintf('ALTER TABLE %s ADD metadata TEXT NULL', $this->optionsTable);
217
+ $this->query($sql);
218
+ }
219
+
220
+ if (!$enterprise_url_exists) {
221
+ $sql = sprintf('ALTER TABLE %s ADD enterprise_url VARCHAR(255) DEFAULT \'\' NOT NULL', $this->pagesTable);
222
+ $this->query($sql);
223
+ }
224
+
225
+ $sql = sprintf('ALTER TABLE %s MODIFY api_keys TEXT NULL', $this->optionsTable);
226
+ $this->query($sql);
227
+ $sql = sprintf('ALTER TABLE %s MODIFY config TEXT NULL', $this->optionsTable);
228
+ $this->query($sql);
229
+ $sql = sprintf('ALTER TABLE %s MODIFY slug VARCHAR(255) DEFAULT \'\' NOT NULL', $this->pagesTable);
230
+ $this->query($sql);
231
+ $sql = sprintf('ALTER TABLE %s MODIFY time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL', $this->pagesTable);
232
+ $this->query($sql);
233
+ $sql = sprintf('ALTER TABLE %s MODIFY time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL', $this->debugTable);
234
+ $this->query($sql);
235
+
236
+ InstapageCmsPluginHelper::updateMetadata('db_version', 300000010);
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Initiates Instapage plugin's DB tables.
242
+ */
243
+ public function removePluginTables() {
244
+ $this->query('DROP TABLE IF EXISTS ' . $this->optionsTable);
245
+ $this->query('DROP TABLE IF EXISTS ' . $this->pagesTable);
246
+ $this->query('DROP TABLE IF EXISTS ' . $this->debugTable);
247
+ }
248
+ }
models/InstapageCmsPluginDebugLogModel.php ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class responsible for storing the data in debug log.
5
+ */
6
+ class InstapageCmsPluginDebugLogModel {
7
+
8
+ /**
9
+ * @var object Class instance.
10
+ */
11
+ private static $debugLogModel = null;
12
+
13
+ /**
14
+ * Gets the class instance.
15
+ *
16
+ * @return object Class instance.
17
+ */
18
+ public static function getInstance() {
19
+ if (self::$debugLogModel === null) {
20
+ self::$debugLogModel = new InstapageCmsPluginDebugLogModel();
21
+ }
22
+
23
+ return self::$debugLogModel;
24
+ }
25
+
26
+ /**
27
+ * Checks if Diagnostic mode is on.
28
+ *
29
+ * @return bool True if Diagnostic mode is on.
30
+ */
31
+ public function isDiagnosticMode() {
32
+ return InstapageCmsPluginHelper::getOption('diagnostics', false);
33
+ }
34
+
35
+ /**
36
+ * Wtites an entry in the debug log.
37
+ *
38
+ * @param string $value Message to be written in the log.
39
+ * @param string $name Additional name for the written value. Default: ''.
40
+ * @param bool $addCaller Do you want to include the stack trace to an antry? Default: true.
41
+ */
42
+ public function write($value, $name = '', $addCaller = true) {
43
+ try {
44
+ if (is_array($value) || is_object($value)) {
45
+ $value = print_r($value, true);
46
+ }
47
+
48
+ $caller = '';
49
+
50
+ if ($addCaller) {
51
+ $trace = debug_backtrace();
52
+ $traceLength = 3;
53
+ $callerArr = array();
54
+
55
+ for ($i = 1; $i <= $traceLength; ++$i) {
56
+ $caller = isset($trace[$i]) ? $trace[$i] : null;
57
+ $callerFunction = isset($caller['function']) ? $caller['function'] : null;
58
+
59
+ if ($callerFunction == 'writeLog' || $callerFunction == 'writeDiagnostics') {
60
+ $traceLength = 4;
61
+
62
+ continue;
63
+ }
64
+
65
+ $callerClass = isset($caller['class']) ? $caller['class'] . ' :: ' : null;
66
+
67
+ if ($caller === null) {
68
+ break;
69
+ }
70
+
71
+ $callerArr[] = $callerClass . $callerFunction;
72
+ }
73
+ }
74
+
75
+ $caller = implode("\r\n", $callerArr);
76
+ $db = InstapageCmsPluginDBModel::getInstance();
77
+ $sql = 'INSERT INTO ' . $db->debugTable . ' VALUES(NULL, %s, %s, %s, %s)';
78
+ $db->query($sql, date('Y-m-d H:i:s'), $value, $caller, $name);
79
+ } catch (Exception $e) {
80
+ echo $e->getMessage();
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Clears the debug log.
86
+ */
87
+ public function clear() {
88
+ $db = InstapageCmsPluginDBModel::getInstance();
89
+ $sql = 'DELETE FROM ' . $db->debugTable;
90
+ $db->query($sql);
91
+ }
92
+
93
+ /**
94
+ * Gets the entries from debug log.
95
+ *
96
+ * @return array List of entries.
97
+ */
98
+ public function read() {
99
+ $db = InstapageCmsPluginDBModel::getInstance();
100
+ $sql = 'SELECT * FROM ' . $db->debugTable;
101
+ $results = $db->getResults($sql);
102
+
103
+ return $results;
104
+ }
105
+
106
+ /**
107
+ * Gets the HTML with debug log. Template for th og is in /templates/log.php file.
108
+ *
109
+ * @return string Log in HTML format.
110
+ */
111
+ public function getLogHTML() {
112
+ if (InstapageCmsPluginConnector::currentUserCanManage() && $this->isDiagnosticMode()) {
113
+ try {
114
+ $pluginsHtml = InstapageCmsPluginConnector::getSelectedConnector()->getPluginsDebugHTML();
115
+ $optionsHtml = InstapageCmsPluginConnector::getSelectedConnector()->getOptionsDebugHTML();
116
+ $phpinfoHtml = $this->getPhpInfoHTML();
117
+ $rows = $this->read();
118
+ $view = InstapageCmsPluginViewModel::getInstance();
119
+ $view->init(INSTAPAGE_PLUGIN_PATH . '/templates/log.php');
120
+ $view->rows = $rows;
121
+ $view->currentDate = date("Ymd_His");
122
+ $view->dbStructure = $this->getDbStructure();
123
+ $view->pluginsHtml = $pluginsHtml;
124
+ $view->optionsHtml = $optionsHtml;
125
+ $view->phpinfoHtml = $phpinfoHtml;
126
+ $html = $view->fetch();
127
+
128
+ return $html;
129
+
130
+ } catch (Exception $e) {
131
+ throw $e;
132
+ }
133
+ } else {
134
+ throw new Exception(__('Instapage log can be downloaded only in diagnostic mode.'));
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Gets phpinfo and formats it.
140
+ *
141
+ * @return string Info about PHP in HTML format.
142
+ */
143
+ private function getPhpInfoHTML() {
144
+ ob_start();
145
+ phpinfo(INFO_GENERAL | INFO_CREDITS | INFO_CONFIGURATION | INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES);
146
+ $contents = ob_get_contents();
147
+ ob_end_clean();
148
+
149
+ $pattern = '/<style.*?style>/s';
150
+ $contents = preg_replace($pattern, '', $contents);
151
+ $contents = '<div class="phpinfo">' . $contents . '</div>';
152
+
153
+ return $contents;
154
+ }
155
+
156
+ /**
157
+ * Gets database structure
158
+ *
159
+ * @uses InstapageCmsPluginDBModel::getInstance()
160
+ *
161
+ * @return array Array of table structure descriptions
162
+ */
163
+ protected function getDbStructure() {
164
+ $db = InstapageCmsPluginDBModel::getInstance();
165
+ $tablesDescriptions = array();
166
+
167
+ // get description of tables
168
+ $sql = 'DESCRIBE ' . $db->pagesTable;
169
+ $tablesDescriptions[] = [
170
+ 'tableName' => $db->pagesTable,
171
+ 'description' => $db->getResults($sql)
172
+ ];
173
+
174
+ $sql = 'DESCRIBE ' . $db->optionsTable;
175
+ $tablesDescriptions[] = [
176
+ 'tableName' => $db->optionsTable,
177
+ 'description' => $db->getResults($sql)
178
+ ];
179
+
180
+ $sql = 'DESCRIBE ' . $db->debugTable;
181
+ $tablesDescriptions[] = [
182
+ 'tableName' => $db->debugTable,
183
+ 'description' => $db->getResults($sql)
184
+ ];
185
+
186
+ return $tablesDescriptions;
187
+ }
188
+ }
models/InstapageCmsPluginPageModel.php ADDED
@@ -0,0 +1,589 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class responsible for managing the landing pages.
5
+ */
6
+ class InstapageCmsPluginPageModel {
7
+
8
+ /**
9
+ * @var object Class instance.
10
+ */
11
+ private static $pageModel = null;
12
+
13
+ /**
14
+ * @var int Page statistics cache duration in minutes.
15
+ */
16
+ private static $statCacheDuration = 15;
17
+
18
+ /**
19
+ * Gets the class instance.
20
+ *
21
+ * @return object Class instance.
22
+ */
23
+ public static function getInstance() {
24
+ if (self::$pageModel === null) {
25
+ self::$pageModel = new InstapageCmsPluginPageModel();
26
+ }
27
+
28
+ return self::$pageModel;
29
+ }
30
+
31
+ /**
32
+ * Updates the page baset on passed $data object.
33
+ *
34
+ * @param object $data Data object.
35
+ *
36
+ * @return integer|boolean Insert ID of false on error.
37
+ */
38
+ public function update($data) {
39
+ $id = InstapageCmsPluginHelper::getVar($data->id, 0);
40
+ $instapageId = InstapageCmsPluginHelper::getVar($data->landingPageId, null);
41
+ $type = InstapageCmsPluginHelper::getVar($data->type);
42
+ $slug = InstapageCmsPluginHelper::getVar($data->slug);
43
+ $enterpriseUrl = InstapageCmsPluginConnector::getHomeURL();
44
+
45
+ if ($slug) {
46
+ $enterpriseUrl .= '/' . $slug;
47
+ }
48
+
49
+ $db = InstapageCmsPluginDBModel::getInstance();
50
+ $sql = 'INSERT INTO ' . $db->pagesTable . ' VALUES(%s, %s, %s, %s, NOW(), \'\', NULL, %s) ON DUPLICATE KEY UPDATE instapage_id = %s, slug = %s, type = %s, time = NOW(), stats_cache = \'\', stats_cache_expires = NULL, enterprise_url = %s';
51
+
52
+ if ($db->query($sql, $id, $instapageId, $slug, $type, $enterpriseUrl, $instapageId, $slug, $type, $enterpriseUrl)) {
53
+ return ($id == 0) ? $db->lastInsertId() : $id;
54
+ } else {
55
+ return false;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Gets all the stored pages.
61
+ *
62
+ * @param array $fields Fields to retrieve. Default: array('*').
63
+ * @param array $conditions. List of conditions. Logical operator between conditions: AND.
64
+ *
65
+ * @return array Lst of results.
66
+ */
67
+ public function getAll($fields = array('*'), $conditions = array()) {
68
+ $db = InstapageCmsPluginDBModel::getInstance();
69
+ $sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable;
70
+
71
+ if (count($conditions)) {
72
+ $sql .= ' WHERE ' . implode(' AND ', $conditions);
73
+ }
74
+
75
+ return $db->getResults($sql);
76
+ }
77
+
78
+ /**
79
+ * Gest the single page based on ID.
80
+ *
81
+ * @param int $id ID of the page.
82
+ * @param array $fields List of fields to retrieve. Default: array('*').
83
+ *
84
+ * @return object Page object.
85
+ */
86
+ public function get($id, $fields = array('*')) {
87
+ $db = InstapageCmsPluginDBModel::getInstance();
88
+ $sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE id = \'' . $id . '\'';
89
+
90
+ return $db->getRow($sql);
91
+ }
92
+
93
+ /**
94
+ * Gest the single page based on slug.
95
+ *
96
+ * @param string $slug Slug of the page.
97
+ * @param array $fields List of fields to retrieve. Default: array('*').
98
+ *
99
+ * @return object Page object.
100
+ */
101
+ public function getBySlug($slug, $fields = array('*')) {
102
+ $db = InstapageCmsPluginDBModel::getInstance();
103
+ $sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE slug = %s AND type=\'page\'';
104
+
105
+ return $db->getRow($sql, $slug);
106
+ }
107
+
108
+ /**
109
+ * Gest the single page based on type and slug.
110
+ *
111
+ * @param string $type Type of the page. ('page'|'home'|'404').
112
+ * @param string $slug Slug of the page.
113
+ * @param array $fields List of fields to retrieve. Default: array('*').
114
+ *
115
+ * @return object Page object.
116
+ */
117
+ public function getByType($type, $slug = '', $fields = array('*')) {
118
+ $db = InstapageCmsPluginDBModel::getInstance();
119
+ $sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE type = %s';
120
+
121
+ if ($slug) {
122
+ $sql = $sql . ' AND slug = %s';
123
+
124
+ return $db->getRow($sql, $type, $slug);
125
+ }
126
+ else {
127
+ return $db->getRow($sql, $type);
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Gest the single page based on ID in Instapage app.
133
+ *
134
+ * @param int $instapageId ID in Instapage app.
135
+ * @param array $fields List of fields to retrieve. Default: array('*').
136
+ *
137
+ * @return array List of page objects.
138
+ */
139
+ public function getByInstapageId($instapageId, $fields = array('*')) {
140
+ $db = InstapageCmsPluginDBModel::getInstance();
141
+ $sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE instapage_id = ' . $instapageId;
142
+
143
+ return $db->getResults($sql);
144
+ }
145
+
146
+ /**
147
+ * Gets the cached statistics for pages.
148
+ *
149
+ * @param array $ids List of page IDs.
150
+ *
151
+ * @return array List of objects with stats cache informations.
152
+ */
153
+ public function getPageStatsCache($ids) {
154
+ if (!is_array($ids) || !count($ids)) {
155
+ return null;
156
+ }
157
+
158
+ $db = InstapageCmsPluginDBModel::getInstance();
159
+
160
+ foreach ($ids as &$item) {
161
+ $item = intval($item);
162
+ }
163
+
164
+ $idsSet = implode(', ', $ids);
165
+ $expireInSeconds = self::$statCacheDuration * 60;
166
+ $sql = 'SELECT instapage_id, stats_cache FROM ' . $db->pagesTable . ' WHERE instapage_id IN(' . $idsSet . ') AND stats_cache_expires + ' . $expireInSeconds . ' > ' . time();
167
+ $results = $db->getResults($sql);
168
+ $stats = array();
169
+
170
+ if ($results) {
171
+ foreach ($results as &$item) {
172
+ $stats[$item->instapage_id] = json_decode($item->stats_cache);
173
+ }
174
+
175
+ return $stats;
176
+ }
177
+
178
+ return array();
179
+ }
180
+
181
+ /**
182
+ * Sends a request to publish a page in Instapage app.
183
+ *
184
+ * @param object $data Page object.
185
+ *
186
+ * @return string JSON object with API response.
187
+ */
188
+ public function publishPage($data) {
189
+ $api = InstapageCmsPluginAPIModel::getInstance();
190
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
191
+ $url = $data->slug ? InstapageCmsPluginConnector::getHomeURL() . '/' . $data->slug : InstapageCmsPluginConnector::getHomeURL();
192
+ $url = InstapageCmsPluginHelper::prepareUrlForUpdate($url);
193
+ $tokens = InstapageCmsPluginHelper::getVar($data->apiTokens, false);
194
+ $success = true;
195
+
196
+ if (!$tokens) {
197
+ $tokens = $subaccount->getAllTokens();
198
+ }
199
+
200
+ $oldPageId = InstapageCmsPluginHelper::getVar($data->id, null);
201
+ $newInstapageId = InstapageCmsPluginHelper::getVar($data->landingPageId, null);
202
+
203
+ if ($oldPageId) {
204
+ $oldPage = $this->get($oldPageId, array('instapage_id'));
205
+
206
+ if ($oldPage->instapage_id != $newInstapageId) {
207
+ $apiData = array(
208
+ 'page' => $oldPage->instapage_id,
209
+ 'url' => '',
210
+ 'publish' => 0
211
+ );
212
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
213
+ $responseJson = $api->apiCall('page/edit', $apiData, $headers);
214
+ $response = json_decode($responseJson);
215
+
216
+ if (!InstapageCmsPluginHelper::checkResponse($response, null, false) || !$response->success) {
217
+ $success = false;
218
+ }
219
+ }
220
+ }
221
+
222
+ if ($success) {
223
+ $apiData = array(
224
+ 'page' => $data->landingPageId,
225
+ 'url' => $url,
226
+ 'publish' => 1
227
+ );
228
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
229
+ $responseJson = $api->apiCall('page/edit', $apiData, $headers);
230
+ $response = json_decode($responseJson);
231
+ }
232
+
233
+ if (!$success || !InstapageCmsPluginHelper::checkResponse($response, null, false) || !$response->success) {
234
+ if (isset($response->message) && $response->message !== '') {
235
+ return InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang($response->message), 'ERROR');
236
+ }
237
+ else {
238
+ return InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('There was an error during page update process.'), 'ERROR');
239
+ }
240
+
241
+ return false;
242
+ }
243
+
244
+ $updatedId = $this->update($data);
245
+
246
+ if ($updatedId) {
247
+ return json_encode((object) array(
248
+ 'status' => 'OK',
249
+ 'message' => InstapageCmsPluginConnector::lang('Page updated successfully.'),
250
+ 'updatedId' => $updatedId
251
+ ));
252
+ }
253
+ else {
254
+ return InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('There was a database error during page update process.'), 'ERROR');
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Migrates the depracated pages to current DB structure.
260
+ *
261
+ * @param array $data List of pages to migrate.
262
+ *
263
+ * @return array List of messages to display as a migration raport.
264
+ */
265
+ public function migrateDeprecatedData($data) {
266
+ InstapageCmsPluginHelper::writeDiagnostics($data, 'Migration data');
267
+ $raport = array();
268
+
269
+ if (!is_array($data) || !count($data)) {
270
+ return $raport;
271
+ }
272
+
273
+ foreach ($data as $deprecatedPage) {
274
+ if ($deprecatedPage->type == 'home') {
275
+ $deprecatedPage->slug = '';
276
+ }
277
+
278
+ $landingPagesById = $this->getByInstapageId($deprecatedPage->landingPageId);
279
+ $landingPagesBySlug = null;
280
+ $landingPagesByType = null;
281
+
282
+ if (count($landingPagesById)) {
283
+ $newLandingPage = array_pop($landingPagesById);
284
+ $raport[] = InstapageCmsPluginConnector::lang('Old version of page (slug: %s, Instapage ID: %s) is present in new database (slug: %s) and won\'t be migrated.', $deprecatedPage->slug, $deprecatedPage->landingPageId, $newLandingPage->slug);
285
+
286
+ continue;
287
+ }
288
+
289
+ if ($deprecatedPage->slug && $deprecatedPage->type == 'page') {
290
+ $landingPagesBySlug = $this->getBySlug($deprecatedPage->slug);
291
+ }
292
+
293
+ if ($landingPagesBySlug) {
294
+ $newLandingPage = $landingPagesBySlug;
295
+ $raport[] = InstapageCmsPluginConnector::lang('Slug: %s is already taken in new database. Old page (slug: %s, Instapage ID: %s) won\'t be migrated.', $deprecatedPage->slug, $deprecatedPage->slug, $deprecatedPage->landingPageId);
296
+
297
+ continue;
298
+ }
299
+
300
+ if ($deprecatedPage->type !== 'page') {
301
+ $landingPagesByType = $this->getByType($deprecatedPage->type);
302
+ }
303
+
304
+ if ($landingPagesByType) {
305
+ $newLandingPage = $landingPagesByType;
306
+ $raport[] = InstapageCmsPluginConnector::lang('One %s page already exists in new database. Old page (slug: %s, Instapage ID: %s) won\'t be migrated.', $deprecatedPage->type, $deprecatedPage->slug, $deprecatedPage->landingPageId);
307
+
308
+ continue;
309
+ }
310
+
311
+ if ($this->update($deprecatedPage)) {
312
+ $raport[] = InstapageCmsPluginConnector::lang('Old version of page (slug: %s, Instapage ID: %s) successfully migrated.', $deprecatedPage->slug, $deprecatedPage->landingPageId);
313
+ }
314
+ else {
315
+ $raport[] = InstapageCmsPluginConnector::lang('Old version of page (slug: %s, Instapage ID: %s) cannot be migrated due to database error.', $deprecatedPage->slug, $deprecatedPage->landingPageId);
316
+ }
317
+ }
318
+
319
+ InstapageCmsPluginHelper::writeDiagnostics($raport, 'Migration raport');
320
+
321
+ return $raport;
322
+ }
323
+
324
+ /**
325
+ * Saves the statistics of the page as a cache.
326
+ *
327
+ * @param array $data Lst of elements to save.
328
+ */
329
+ public function savePageStatsCache($data) {
330
+ $db = InstapageCmsPluginDBModel::getInstance();
331
+
332
+ foreach ($data as $key => $item) {
333
+ $sql = 'UPDATE ' . $db->pagesTable . ' SET stats_cache = %s, stats_cache_expires = ' . time() . ' WHERE instapage_id = %s';
334
+ $db->query($sql, json_encode($item), $key );
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Gets a landing page saved as a homepage.
340
+ *
341
+ * @param array $fields List of fields to retrieve. Default: array('*').
342
+ *
343
+ * @return object Page object.
344
+ */
345
+ public function getHomepage($fields = array('*')) {
346
+ $db = InstapageCmsPluginDBModel::getInstance();
347
+ $sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE type=\'home\'';
348
+
349
+ return $db->getRow($sql);
350
+ }
351
+
352
+ /**
353
+ * Gets a landing page saved as a 404 page.
354
+ *
355
+ * @param array $fields List of fields to retrieve. Default: array('*').
356
+ *
357
+ * @return object Page object.
358
+ */
359
+ public function get404($fields = array('*')) {
360
+ $db = InstapageCmsPluginDBModel::getInstance();
361
+ $sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE type=\'404\'';
362
+
363
+ return $db->getRow($sql);
364
+ }
365
+
366
+ /**
367
+ * Gets the data about landing pages stores in local database and completes them with data from Instapage app.
368
+ *
369
+ * @param array localData List of pages stored locally. Data will be changed during the process.
370
+ *
371
+ * @param array $appData List of information from the Instapage app.
372
+ */
373
+ public function mergeListPagesResults(&$localData, $appData) {
374
+ foreach ($localData as &$localItem) {
375
+ $instapageId = $localItem->instapage_id;
376
+ $appItem = $this->getPageFromArray($instapageId, $appData);
377
+
378
+ if (!is_null($appItem)) {
379
+ $localItem->screenshot = $appItem->screenshot;
380
+ $localItem->title = $appItem->title;
381
+ $localItem->subaccount = $appItem->subaccount;
382
+ }
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Checks (and returns) if a landing page should be displayed instead of normal content served by CMS.
388
+ *
389
+ * @param string $type Type of page to check ('page', 'home' or '404').
390
+ * @param string $slug Slug to check. Default: ''.
391
+ *
392
+ * @return string HTML to display.
393
+ */
394
+ public function check($type, $slug = '') {
395
+ if (!InstapageCmsPluginConnector::isHtmlReplaceNecessary()) {
396
+ return;
397
+ }
398
+
399
+ $result = $this->getByType($type, $slug, array('instapage_id', 'slug', 'enterprise_url'));
400
+
401
+ if (!$result) {
402
+ return;
403
+ }
404
+
405
+ $result->slug = $result->slug ? $result->slug : $slug;
406
+ $result->enterprise_url = $result->enterprise_url ? $result->enterprise_url : InstapageCmsPluginConnector::getHomeURL() . '/' . $result->slug;
407
+ $result->enterprise_url = rtrim($result->enterprise_url, '/');
408
+
409
+ return $result;
410
+ }
411
+
412
+ /**
413
+ * Displays the landing page.
414
+ *
415
+ * @param object $page Landing page to display.
416
+ * @param int $forcedStatus Status to be set as a header. Default: null.
417
+ */
418
+ public function display($page, $forcedStatus = null)
419
+ {
420
+ require_once(__DIR__ . '/../modules/lpAjaxLoader/InstapageCmsPluginLPAjaxLoaderController.php');
421
+ $lpAjaxLoaderController = new InstapageCmsPluginLPAjaxLoaderController();
422
+ $instapageId = $page->instapage_id;
423
+ $slug = $page->slug;
424
+ $host = parse_url($page->enterprise_url, PHP_URL_HOST);
425
+ InstapageCmsPluginHelper::writeDiagnostics($slug . ' : ' . $instapageId, 'slug : instapage_id');
426
+
427
+ $api = InstapageCmsPluginAPIModel::getInstance();
428
+ $querySufix = '';
429
+ $cookies = $_COOKIE;
430
+
431
+ if (!empty($_GET)) {
432
+ if ($lpAjaxLoaderController->shouldDecodeQuery()) {
433
+ $querySufix = '?' . base64_decode($_GET['b64']);
434
+ } else {
435
+ $querySufix = '?' . http_build_query($_GET);
436
+ }
437
+ } elseif (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {
438
+ $querySufix = '?' . $_SERVER['QUERY_STRING'];
439
+ }
440
+
441
+ if (is_array($cookies) && count($cookies)) {
442
+ $cookiesWeNeed = array("instapage-variant-{$instapageId}");
443
+
444
+ foreach ($cookies as $key => $value) {
445
+ if (!in_array($key, $cookiesWeNeed)) {
446
+ unset($cookies[$key]);
447
+ }
448
+ }
449
+ }
450
+
451
+ $url = preg_replace('/https?:\/\/' . $host . '/', INSTAPAGE_ENTERPRISE_ENDPOINT, $page->enterprise_url);
452
+ $url .= $querySufix;
453
+
454
+ if ($lpAjaxLoaderController->shouldBeUsed($url)) {
455
+ $html = $lpAjaxLoaderController->getView();
456
+ $result['code'] = 200;
457
+ } else {
458
+ $result = $api->enterpriseCall($url, $host, $cookies);
459
+ $pageserverCookie = isset($result['headers']['set-cookie']) ? $result['headers']['set-cookie'] : '';
460
+
461
+ if (is_array($pageserverCookie)) {
462
+ $pageserverCookie = array_pop($pageserverCookie);
463
+ }
464
+
465
+ $instapageVariant = InstapageCmsPluginHelper::getVariant((string)$pageserverCookie);
466
+
467
+ if (!empty($instapageVariant)) {
468
+ setcookie(
469
+ "instapage-variant-{$instapageId}",
470
+ $instapageVariant,
471
+ strtotime('+12 month')
472
+ );
473
+ }
474
+
475
+ $html = InstapageCmsPluginHelper::getVar($result['body']);
476
+ $html = $this->disableCloudFlareScriptReplace($html);
477
+ $html = $this->fixHtmlHead($html);
478
+ }
479
+
480
+ if ($forcedStatus) {
481
+ $status = $forcedStatus;
482
+ } else {
483
+ $status = InstapageCmsPluginHelper::getVar($result['code'], 200);
484
+ }
485
+
486
+ if ($html) {
487
+ ob_start();
488
+ InstapageCmsPluginHelper::disableCaching();
489
+ InstapageCmsPluginHelper::httpResponseCode($status);
490
+ print $html;
491
+ ob_end_flush();
492
+ die();
493
+ } else {
494
+ return false;
495
+ }
496
+ }
497
+
498
+ /**
499
+ * Deletes a page from local DB.
500
+ *
501
+ * @param int $id ID of a page to be deleted.
502
+ */
503
+ public function delete($id) {
504
+
505
+ $db = InstapageCmsPluginDBModel::getInstance();
506
+ $sql = 'DELETE FROM ' . $db->pagesTable . ' WHERE id = %s';
507
+
508
+ return $db->query($sql, $id);
509
+ }
510
+
511
+ /**
512
+ * Gets the page object from an array of page objects.
513
+ *
514
+ * @param int $id ID of a page.
515
+ * @param array $array List of page objects.
516
+ *
517
+ * @return object|null Page object or null if no pages found.
518
+ */
519
+ private function getPageFromArray($id, $array) {
520
+ if (is_array($array)) {
521
+ foreach ($array as $item) {
522
+ if ($item->id == $id) {
523
+ return $item;
524
+ }
525
+ }
526
+ }
527
+
528
+ return null;
529
+ }
530
+
531
+ /**
532
+ * Composes a random slug.
533
+ *
534
+ * @param bool $prefix Do you want to add a prefix?
535
+ *
536
+ * @return string Random slug.
537
+ */
538
+ public function getRandomSlug($prefix = true) {
539
+ $randomPrefix = 'random-url-';
540
+ $randomSufixSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
541
+ $randomSufixLength = 10;
542
+ $randomString = '';
543
+
544
+ for ($i = 0; $i < $randomSufixLength; $i++) {
545
+ $randomString .= $randomSufixSet[rand(0, strlen($randomSufixSet) - 1)];
546
+ }
547
+
548
+ return $prefix ? $randomPrefix . $randomString : $randomString;
549
+ }
550
+
551
+ /**
552
+ * Removes the CloudFlare JS from a landing page content.
553
+ *
554
+ * @param string $html HTML of a landing page.
555
+ *
556
+ * @return string HTML without CloudFlare script.
557
+ */
558
+ private function disableCloudFlareScriptReplace($html) {
559
+ $pattern = '/(<script)(type="text\/javascript")?(.*?)>/';
560
+
561
+ return preg_replace($pattern, "$1$2 data-cfasync=\"false\" $3>", $html);
562
+ }
563
+
564
+ /**
565
+ * Sets up the proper URL for Instapage proxy, if it is enabled.
566
+ *
567
+ * @param string $html HTML to be fixed.
568
+ *
569
+ * @return string HTML with propely set proxy URLs.
570
+ */
571
+ public function fixHtmlHead($html) {
572
+ $useProxy = InstapageCmsPluginHelper::getOption('crossOrigin', false);
573
+
574
+ if ($useProxy) {
575
+ $html = str_replace('PROXY_SERVICES', str_replace(array('http://', 'https://'), array('//', '//'), InstapageCmsPluginConnector::getHomeURL()) ."/instapage-proxy-services?url=", $html);
576
+ }
577
+
578
+ $searchArray = array(
579
+ '<meta name="iy453p9485yheisruhs5" content="" />',
580
+ '<meta name="robots" content="noindex, nofollow" />'
581
+ );
582
+
583
+ if (strpos($html, $searchArray[0]) !== false) {
584
+ $html = str_replace($searchArray, '', $html);
585
+ }
586
+
587
+ return $html;
588
+ }
589
+ }
models/InstapageCmsPluginServicesModel.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class responsible for managing the landing pages.
5
+ */
6
+ class InstapageCmsPluginServicesModel {
7
+
8
+ /**
9
+ * @var object Class instance.
10
+ */
11
+ private static $servicesModel = null;
12
+
13
+ /**
14
+ * Gets the class instance.
15
+ *
16
+ * @return object Class instance.
17
+ */
18
+ public static function getInstance() {
19
+ if (self::$servicesModel === null) {
20
+ self::$servicesModel = new InstapageCmsPluginServicesModel();
21
+ }
22
+
23
+ return self::$servicesModel;
24
+ }
25
+
26
+ /**
27
+ * Checks if current request should be processed by a proxy service.
28
+ *
29
+ * @return boolean
30
+ */
31
+ public function isServicesRequest() {
32
+ if (strpos($_SERVER['REQUEST_URI'], 'instapage-proxy-services') !== false) {
33
+ InstapageCmsPluginHelper::writeDiagnostics($_SERVER['REQUEST_URI'], 'Proxy services URL');
34
+
35
+ return true;
36
+ }
37
+
38
+ return false;
39
+ }
40
+
41
+ /**
42
+ * Strips the slashes.
43
+ *
44
+ * @param string &$$value Value to strip slashes from.
45
+ */
46
+ public function stripSlashesGpc(&$value) {
47
+ $value = stripslashes($value);
48
+ }
49
+
50
+ /**
51
+ * Processes the proxy request.
52
+ */
53
+ public function processProxyServices() {
54
+ $api = InstapageCmsPluginAPIModel::getInstance();
55
+ $url = @InstapageCmsPluginHelper::getVar($_GET['url'], '');
56
+
57
+ if (strpos($url, 'ajax/pageserver/email') === false) {
58
+ throw new Exception('Unsupported endpoint: ' . $url);
59
+ }
60
+
61
+ $url = INSTAPAGE_PROXY_ENDPOINT . $url;
62
+
63
+ array_walk_recursive($_POST, array($this, 'stripSlashesGpc'));
64
+
65
+ if (isset($_POST) && !empty($_POST)) {
66
+ $_POST['user_ip'] = $_SERVER['REMOTE_ADDR'];
67
+ }
68
+
69
+ $data = $_POST;
70
+ $data['ajax'] = 1;
71
+ $response = $api->remotePost($url, $data);
72
+
73
+ if (isset($response['response']['code']) && $response['response']['code'] !== 200) {
74
+ $this->disableCrossOriginProxy();
75
+ $matches = array();
76
+ $pattern = '/email\/(\d*)/';
77
+ preg_match($pattern, $url, $matches);
78
+ }
79
+
80
+ InstapageCmsPluginHelper::writeDiagnostics($url, 'Proxy services URL');
81
+ InstapageCmsPluginHelper::writeDiagnostics($data, 'Proxy data');
82
+ InstapageCmsPluginHelper::writeDiagnostics($response, 'Proxy response');
83
+
84
+ $status = @InstapageCmsPluginHelper::getVar($response->status);
85
+ $responseCode = @InstapageCmsPluginHelper::getVar($response['response']['code'], 200);
86
+
87
+ if ($status === 'ERROR') {
88
+ $errorMessage = @InstapageCmsPluginHelper::getVar($response->message);
89
+
90
+ if (!empty($errorMessage)) {
91
+ throw new Exception($errorMessage);
92
+ }
93
+ else {
94
+ throw new Exception('500 Internal Server Error');
95
+ }
96
+ }
97
+
98
+ ob_start();
99
+ ob_end_clean();
100
+ header('Content-Type: text/json; charset=UTF-8');
101
+ echo trim(@InstapageCmsPluginHelper::getVar($response['body'], ''));
102
+ status_header($responseCode);
103
+
104
+ exit;
105
+ }
106
+
107
+ /**
108
+ * Disables the Cross Origin Proxy option in plugin's settings.
109
+ */
110
+ private function disableCrossOriginProxy() {
111
+ $options = InstapageCmsPluginHelper::getOptions();
112
+ $options->config->crossOrigin = 0;
113
+ InstapageCmsPluginHelper::updateOptions($options);
114
+ }
115
+ }
models/InstapageCmsPluginSubaccountModel.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class responsible for managing the subaccounts in Instapage app.
5
+ */
6
+ class InstapageCmsPluginSubaccountModel {
7
+
8
+ /**
9
+ * @var object Class instance.
10
+ */
11
+ private static $subaccountModel = null;
12
+
13
+ /**
14
+ * @var array List of subaccount tokens.
15
+ */
16
+ private $subaccountTokens = null;
17
+
18
+ /**
19
+ * Gets the class instance.
20
+ *
21
+ * @return object Class instance.
22
+ */
23
+ public static function getInstance() {
24
+ if (self::$subaccountModel === null) {
25
+ self::$subaccountModel = new InstapageCmsPluginSubaccountModel();
26
+ }
27
+
28
+ return self::$subaccountModel;
29
+ }
30
+
31
+ /**
32
+ * Gets all the tokens - stored in plugin's settings and bound to currently used app user account.
33
+ *
34
+ * @return array List of tokens.
35
+ */
36
+ public function getAllTokens() {
37
+ if ($this->subaccountTokens === null) {
38
+ $tokens = InstapageCmsPluginHelper::getTokens();
39
+ $accountKeys = $this->getAccountBoundTokens();
40
+ $this->subaccountTokens = array_merge($tokens, $accountKeys);
41
+ }
42
+
43
+ return $this->subaccountTokens;
44
+ }
45
+
46
+ /**
47
+ * Gets the list of tokens bound to subaccount. User has to be logged in via email and password.
48
+ *
49
+ * @return array List of tokens bound to an account.
50
+ */
51
+ public function getAccountBoundTokens() {
52
+ $api = InstapageCmsPluginAPIModel::getInstance();
53
+ $userToken = InstapageCmsPluginHelper::getOption('plugin_hash');
54
+ $accountKeys = array();
55
+
56
+ if ($userToken) {
57
+ $headers = array('usertoken' => $userToken);
58
+ $responseJson = $api->apiCall('page/get-account-keys', null, $headers);
59
+ $response = json_decode($responseJson);
60
+
61
+ if (!is_null($response) && $response->success) {
62
+ $accountKeys = $response->data->accountkeys;
63
+ }
64
+ }
65
+
66
+ return $accountKeys;
67
+ }
68
+
69
+ /**
70
+ * Gets the list of subaccounts of currently logged in user.
71
+ *
72
+ * @param string $format Format for the response. Default: 'json'.
73
+ *
74
+ * @return (string|array) List of subaccounts as a JSON string or an array.
75
+ */
76
+ public function getAccountBoundSubAccounts($format = 'json') {
77
+ $api = InstapageCmsPluginAPIModel::getInstance();
78
+ $tokens = $this->getAccountBoundTokens();
79
+ $subAccounts = array();
80
+
81
+ if (is_array($tokens) && count($tokens)) {
82
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
83
+ $response = json_decode($api->apiCall('page/get-sub-accounts-list', null, $headers));
84
+ $subAccounts = @InstapageCmsPluginHelper::getVar($response->data, null);
85
+ }
86
+
87
+ if ($format == 'json') {
88
+ echo json_encode((object) array(
89
+ 'status' => 'OK',
90
+ 'data' => $subAccounts
91
+ ));
92
+ } else {
93
+ return $subAccounts;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Sets the status of subaccount in Instapage app. Subaccount can be connected to or disconnected from a CMS.
99
+ *
100
+ * @param string $status Status to be set. Default: 'connect'. 'disconnect' is another option.
101
+ * @param array $tokens List of tokens, that are meant to be connected of disconnected.
102
+ * @param bool $silent Do you want a message to appear?
103
+ */
104
+ public function setSubAccountsStatus($status = 'connect', $tokens = null, $silent = false) {
105
+ $api = InstapageCmsPluginAPIModel::getInstance();
106
+ $subaccount = InstapageCmsPluginSubaccountModel::getInstance();
107
+ $post = InstapageCmsPluginHelper::getPostData();
108
+
109
+ if ($tokens !== null) {
110
+ $selectedSubaccounts = $tokens;
111
+ } else {
112
+ $selectedSubaccounts = InstapageCmsPluginHelper::getVar($post->data->tokens, array());
113
+ }
114
+
115
+ if (count($selectedSubaccounts)) {
116
+ $tokens = $subaccount->getAllTokens();
117
+ $headers = array('accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens));
118
+ $data = array(
119
+ 'accountkeys' => base64_encode(json_encode($selectedSubaccounts)),
120
+ 'status' => $status,
121
+ 'domain' => InstapageCmsPluginConnector::getHomeURL(false)
122
+ );
123
+
124
+ $response = json_decode($api->apiCall('page/connection-status', $data, $headers));
125
+
126
+ if ($silent) {
127
+ return;
128
+ }
129
+
130
+ if (
131
+ !InstapageCmsPluginHelper::checkResponse($response, null, false) ||
132
+ !$response->success ||
133
+ !isset($response->data->changed) ||
134
+ $response->data->changed != count($selectedSubaccounts)
135
+ ) {
136
+ $action = array();
137
+ $action[0] = $status == 'connect' ? 'connected to' : 'disconnected from';
138
+ $action[1] = $status == 'connect' ? 'connect' : 'disconnect';
139
+
140
+ if (count($selectedSubaccounts) > 1) {
141
+ $message = InstapageCmsPluginHelper::getVar($response->message, InstapageCmsPluginConnector::lang('There was an error, selected subaccounts are not properly %s app. Try to %s subaccounts again.', $action[0], $action[1]));
142
+ } else {
143
+ $message = InstapageCmsPluginHelper::getVar($response->message, InstapageCmsPluginConnector::lang('There was an error, selected subaccount is not properly %s app. Try to %s subaccounts again.', $action[0], $action[1]));
144
+ }
145
+
146
+ echo InstapageCmsPluginHelper::formatJsonMessage($message, 'ERROR');
147
+ } else {
148
+ $action = array();
149
+ $action[0] = $status == 'connect' ? 'Selected subaccounts' : 'Subaccounts bound to your account';
150
+ $action[1] = $status == 'connect' ? 'connected' : 'disconnected';
151
+
152
+ if (count($selectedSubaccounts) > 1) {
153
+ $message = InstapageCmsPluginHelper::getVar($response->message, InstapageCmsPluginConnector::lang('%s are %s.', $action[0], $action[1]));
154
+ } else {
155
+ $message = InstapageCmsPluginHelper::getVar($response->message, InstapageCmsPluginConnector::lang('Selected subaccount is %s.', $action[1]));
156
+ }
157
+
158
+ echo InstapageCmsPluginHelper::formatJsonMessage($message);
159
+ }
160
+ } else {
161
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('No subaccounts were connected.'));
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Disconnects all subaccount bound to an account. User has to be looged in via email and password.
167
+ *
168
+ * @param bool $silent Do you want a message to appear? Default: false.
169
+ */
170
+ public function disconnectAccountBoundSubaccounts($silent = false) {
171
+ $subAccounts = $this->getAccountBoundSubAccounts('array');
172
+
173
+ if (count($subAccounts)) {
174
+ $tokens = array();
175
+
176
+ foreach ($subAccounts as $item) {
177
+ $tokens[] = InstapageCmsPluginHelper::getVar($item->accountkey, '');
178
+ }
179
+
180
+ $this->setSubAccountsStatus('disconnect', $tokens, $silent);
181
+ } else {
182
+ if (!$silent) {
183
+ echo InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('Subaccounts bound to your account are disconnected'));
184
+ }
185
+ }
186
+ }
187
+ }
models/InstapageCmsPluginViewModel.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class responsible for displaying a template files.
5
+ */
6
+ class InstapageCmsPluginViewModel {
7
+
8
+ /**
9
+ * @var object Class instance.
10
+ */
11
+ private static $viewModel = null;
12
+
13
+ /**
14
+ * @var array Data that can be used inside of a template.
15
+ */
16
+ protected $templateData = array();
17
+
18
+ /**
19
+ * @var array Templates to fetch.
20
+ */
21
+ protected $templates = null;
22
+
23
+ /**
24
+ * Gets the class instance.
25
+ */
26
+ public static function getInstance() {
27
+
28
+ if (self::$viewModel === null) {
29
+ self::$viewModel = new InstapageCmsPluginViewModel();
30
+ }
31
+
32
+ return self::$viewModel;
33
+ }
34
+
35
+ /**
36
+ * Class constructor.
37
+ *
38
+ * @param array $templates Templates to fetch.
39
+ * @param array $attributes Attributes to pass to the templates.
40
+ */
41
+ public function __construct($templates = null, $attributes = null) {
42
+ if ($attributes) {
43
+ foreach ($attributes as $key => $value) {
44
+ $this->templateData[$key] = $value;
45
+ }
46
+ }
47
+
48
+ $this->templates = $templates;
49
+ }
50
+
51
+ /**
52
+ * Initiates the templates. Sets the templates attributes.
53
+ *
54
+ * @param array $templates Templates to initiate.
55
+ * @param array $attributes Attributes to pass to the templates.
56
+ */
57
+ public function init($templates = null, $attributes = null) {
58
+ if ($attributes) {
59
+ foreach ($attributes as $key => $value) {
60
+ $this->templateData[$key] = $value;
61
+ }
62
+ }
63
+
64
+ $this->templates = $templates;
65
+ }
66
+
67
+ /**
68
+ * Magic method to set up a template attribute.
69
+ *
70
+ * @param string $name Name of the attribute.
71
+ * @param mixed $value Value of the attribute.
72
+ */
73
+ public function __set($name, $value) {
74
+ $this->templateData[$name] = $value;
75
+ }
76
+
77
+ /**
78
+ * Information to the user how to fetch a template properly.
79
+ *
80
+ * @return string A message to the class user.
81
+ */
82
+ public function __toString() {
83
+ return 'use $view->fetch() instead';
84
+ }
85
+
86
+ /**
87
+ * Assigns a value as a template attribute.
88
+ *
89
+ * @param string $key Name of the attribute.
90
+ * @param mixed $value Value of the attribute.
91
+ *
92
+ * @return object Template object.
93
+ */
94
+ public function assign($key, $value) {
95
+ $this->templateData[$key] = $value;
96
+
97
+ return $this;
98
+ }
99
+
100
+ /**
101
+ * Renders the templates.
102
+ *
103
+ * @param array $templates. List of templates to render. If it's null, last user template will be rendered.
104
+ *
105
+ * @throws Excetion If $templates is null and no templates were used before.
106
+ * @throws Exception If no template file is found.
107
+ *
108
+ * @return string Rendered template content.
109
+ */
110
+ public function fetch($templates = null) {
111
+ $templates = $templates ? $templates : $this->templates;
112
+
113
+ if (!$templates || empty($templates)) {
114
+ throw new Exception("Templates can not be null.");
115
+ }
116
+
117
+ if (!is_array($templates)) {
118
+ $templates = array($templates);
119
+ }
120
+
121
+ foreach ($templates as $template) {
122
+ if (!file_exists($template)) {
123
+ throw new Exception("Template {$template} not found.");
124
+ }
125
+
126
+ if ($this->templateData) {
127
+ foreach ($this->templateData as $variableName => $variableValue) {
128
+ $$variableName = $variableValue;
129
+ unset($variableName);
130
+ unset($variableValue);
131
+ }
132
+ }
133
+
134
+ ob_start();
135
+ include($template);
136
+ $contents = ob_get_contents();
137
+ ob_end_clean();
138
+ }
139
+
140
+ return $contents;
141
+ }
142
+
143
+ /**
144
+ * Sets variables for the selected template and renders it.
145
+ *
146
+ * @param string $template Template to render.
147
+ * @param array $variables Variables to be set as template attributes.
148
+ *
149
+ * @return string Rendered template content.
150
+ */
151
+ public static function get($template, $variables = null) {
152
+ $view = new View($template);
153
+
154
+ if ($variables) {
155
+ foreach ($variables as $key => $value) {
156
+ $view->$key = $value;
157
+ }
158
+ }
159
+
160
+ return $view->fetch();
161
+ }
162
+
163
+ /**
164
+ * Gets the template variable.
165
+ *
166
+ * @param string $template Template name.
167
+ * @param array $variables Variables to get.
168
+ *
169
+ * @return array Template variables.
170
+ */
171
+ public static function _($template, $variables = null) {
172
+ return self::get($template, $variables);
173
+ }
174
+ }
modules/lpAjaxLoader/InstapageCmsPluginLPAjaxLoaderController.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class InstapageCmsPluginLPAjaxLoaderController
5
+ *
6
+ * This controller solves problem that on some hostings `utm_` params are stripped,
7
+ * so we passed them endoded with base64 to backend of plugin by JS Ajax Loader
8
+ */
9
+ class InstapageCmsPluginLPAjaxLoaderController
10
+ {
11
+ const AJAX_REQUEST_FLAG_NAME = 'landingPageAjaxLoaderRequest';
12
+ const PANTHEON_STRIPPED = 'PANTHEON_STRIPPED';
13
+
14
+ /**
15
+ * Check if it is pantheon hosting platform and check if utm_ variables are replaced
16
+ * Also Check if it is WP Engine hosting and if it is not already request from Ajax Loader JS
17
+ *
18
+ * @param string $url URL of landing page that plugin tries to load
19
+ * @return bool
20
+ */
21
+ public function shouldBeUsed($url)
22
+ {
23
+ return (isset($_ENV['PANTHEON_ENVIRONMENT'])
24
+ && strpos($url, self::PANTHEON_STRIPPED) !== false)
25
+ || (isset($_ENV['WPENGINE_ACCOUNT'])
26
+ && strpos($url, self::AJAX_REQUEST_FLAG_NAME) === false);
27
+ }
28
+
29
+ /**
30
+ * Check if query should be decoded
31
+ * Query can contains b64 param and it needs to be decode to be used
32
+ *
33
+ * @return bool
34
+ */
35
+ public function shouldDecodeQuery()
36
+ {
37
+ return
38
+ (isset($_ENV['PANTHEON_ENVIRONMENT']) || isset($_ENV['WPENGINE_ACCOUNT']))
39
+ && isset($_GET['b64']);
40
+ }
41
+
42
+ /**
43
+ * Get view containing Ajax loader
44
+ *
45
+ * @return false|string
46
+ */
47
+ public function getView()
48
+ {
49
+ ob_start();
50
+ include(__DIR__ . '/view.php');
51
+ return ob_get_clean();
52
+ }
53
+ }
modules/lpAjaxLoader/view.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * For pantheon hosting platform (https://pantheon.io/) we need to get content by ajax
4
+ * because pantheon replace UTM_ variables value to 'PANTHEON_STRIPPED' and redirect the page.
5
+ * Thanks to this solution all UTM_ variable are sent to instapage api.platform
6
+ */
7
+ ?>
8
+
9
+ <html>
10
+ <script id='b64-replace' type="text/javascript">
11
+ (function () {
12
+ var query = [];
13
+ var searchArray = document.location.search.replace('?', '').split('&');
14
+ var url = document.location.origin + document.location.pathname + '?b64=';
15
+ var i;
16
+
17
+ for (i = 0; i < searchArray.length; i++) {
18
+ if (searchArray[i].indexOf("PANTHEON_STRIPPED") === -1) {
19
+ query.push(searchArray[i]);
20
+ }
21
+ }
22
+
23
+ query.push(
24
+ '<?php echo InstapageCmsPluginLPAjaxLoaderController::AJAX_REQUEST_FLAG_NAME ?>=true'
25
+ );
26
+
27
+ if (window.XMLHttpRequest) {
28
+ var xhReq = new XMLHttpRequest();
29
+ } else {
30
+ var xhReq = new ActiveXObject("Microsoft.XMLHTTP");
31
+ }
32
+
33
+ xhReq.open('GET', url + window.btoa(query.join('&')), false);
34
+ xhReq.setRequestHeader("X-Requested-With", "XMLHttpRequest");
35
+ xhReq.send();
36
+
37
+ document.open();
38
+ document.write(xhReq.responseText);
39
+ document.close();
40
+ document.getElementById("b64-replace").remove();
41
+ })();
42
+ </script>
43
+ <body>
44
+ </body>
45
+ </html>
templates/log.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * log.php is a template file. It's meant to be included in other php files. To work properly variables need to be set before file inclusion:
5
+ *
6
+ * @param string $currentDate Current date in readable format
7
+ * @param array $rows Log entries as objects with properties:
8
+ * string $row->time - time of log entry creation in readable format
9
+ * string $row->name - name of the entry
10
+ * string $row->text - description of the entry
11
+ * string $row->caller - function that added the entry
12
+ * @param string $pluginsHtml HTML containing a list of other installed plugins or modules
13
+ * @param string $optionsHtml HTML containing options of the CMS
14
+ * @param string $phpinfoHtml HTML containing phpinfo() output
15
+ */
16
+ ?>
17
+ <!DOCTYPE html>
18
+ <html>
19
+ <head>
20
+ <title><?php echo InstapageCmsPluginConnector::lang('Instapage Log') . ' ' . $currentDate; ?></title>
21
+ <style>
22
+ body
23
+ {
24
+ background: #EFEFEF;
25
+ font-family: "Courier New", "Courier", "Lucida Sans Typewriter", "Lucida Typewriter", "monospace";
26
+ font-size: 12px;
27
+ }
28
+
29
+ h2
30
+ {
31
+ font-size: 28px;
32
+ padding: 35px 0px;
33
+ }
34
+
35
+ table
36
+ {
37
+ border-collapse: collapse;
38
+ width: 100%;
39
+ }
40
+
41
+ table,
42
+ th,
43
+ td
44
+ {
45
+ border: 1px solid #CECECE;
46
+ cursor: pointer;
47
+ }
48
+
49
+ td,
50
+ th
51
+ {
52
+ padding: 15px;
53
+ overflow: hidden;
54
+ text-overflow: ellipsis;
55
+ white-space: nowrap;
56
+ max-width: 0;
57
+ }
58
+
59
+ td:hover {
60
+ text-overflow: initial;
61
+ white-space: pre-wrap;
62
+ word-wrap: break-word;
63
+ overflow: auto;
64
+ }
65
+
66
+ th
67
+ {
68
+ background: #7F7F7F;
69
+ font-weight: bold;
70
+ color: #EDEDED;
71
+ }
72
+
73
+ tr:nth-child(even)
74
+ {
75
+ background: #F7F7F7;
76
+ }
77
+
78
+ tr:hover
79
+ {
80
+ background: #FFF;
81
+ }
82
+ section h3 {
83
+ margin-top: 50px;
84
+ }
85
+ </style>
86
+ </head>
87
+ <body>
88
+ <?php if (is_array($rows) && !empty($rows)): ?>
89
+ <h2><?php echo InstapageCmsPluginConnector::lang('Log entries'); ?></h2>
90
+ <table>
91
+ <thead>
92
+ <tr>
93
+ <th width="2%"><?php echo InstapageCmsPluginConnector::lang('#'); ?></th>
94
+ <th width="10%"><?php echo InstapageCmsPluginConnector::lang('Date'); ?></th>
95
+ <th width="10%"><?php echo InstapageCmsPluginConnector::lang('Name'); ?></th>
96
+ <th><?php echo InstapageCmsPluginConnector::lang('Text'); ?></th>
97
+ <th width="15%"><?php echo InstapageCmsPluginConnector::lang('Caller'); ?></th>
98
+ </tr>
99
+ </thead>
100
+ <tbody>
101
+ <?php foreach ($rows as $index => $row): ?>
102
+ <tr>
103
+ <td><?php echo $index + 1 ?></td>
104
+ <td><?php echo $row->time ?></td>
105
+ <td><?php echo $row->name ?></td>
106
+ <td><?php echo InstapageCmsPluginConnector::escapeHTML($row->text); ?></td>
107
+ <td><?php echo $row->caller ?></td>
108
+ </tr>
109
+ <?php endforeach; ?>
110
+ </tbody>
111
+ </table>
112
+ <?php else: ?>
113
+ <p><?php echo InstapageCmsPluginConnector::lang('Log is empty.'); ?></p>
114
+ <?php endif; ?>
115
+ <section class="db-structure">
116
+ <h2><?php echo InstapageCmsPluginConnector::lang('Database structure'); ?></h2>
117
+ <?php foreach ($dbStructure as $tableStructure): ?>
118
+ <h3><?= $tableStructure['tableName'] ?></h3>
119
+ <table>
120
+ <tr>
121
+ <th>Field name</th>
122
+ <th>Field type</th>
123
+ <th>Nullable?</th>
124
+ <th>Key?</th>
125
+ <th>Default value</th>
126
+ <th>Extra info</th>
127
+ </tr>
128
+ <?php foreach ($tableStructure['description'] as $columnStructure):?>
129
+ <tr>
130
+ <td><?= $columnStructure->Field ?></td>
131
+ <td><?= $columnStructure->Type ?></td>
132
+ <td><?= $columnStructure->Null ?></td>
133
+ <td><?= $columnStructure->Key ?></td>
134
+ <td><?= $columnStructure->Default ?></td>
135
+ <td><?= $columnStructure->Extra ?></td>
136
+ </tr>
137
+ <?php endforeach; ?>
138
+ </table>
139
+ <?php endforeach; ?>
140
+ </seciton>
141
+ <h2><?php echo InstapageCmsPluginConnector::lang('Installed plugins'); ?></h2>
142
+ <?php echo $pluginsHtml; ?>
143
+ <h2><?php echo InstapageCmsPluginConnector::lang('CMS options'); ?></h2>
144
+ <?php echo $optionsHtml; ?>
145
+ <h2><?php echo InstapageCmsPluginConnector::lang('PHP Info'); ?></h2>
146
+ <?php echo $phpinfoHtml; ?>
147
+ </body>
148
+ </html>
templates/log_options.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * log_options.php is a template file. It's meant to be included in other php files. To work properly variables need to be set before file inclusion:
5
+ * @param array $rows - options as an associative array. Key is the option name and value if option's value.
6
+ */
7
+ ?>
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <th><?php echo InstapageCmsPluginConnector::lang('#'); ?></th>
12
+ <th><?php echo InstapageCmsPluginConnector::lang('Key'); ?></th>
13
+ <th><?php echo InstapageCmsPluginConnector::lang('Value'); ?></th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <?php $index = 1; ?>
18
+ <?php foreach ($rows as $key => $value): ?>
19
+ <tr>
20
+ <td><?php echo $index ?></td>
21
+ <td><?php echo $key ?></td>
22
+ <td><?php echo $value ?></td>
23
+ </tr>
24
+ <?php $index++; ?>
25
+ <?php endforeach; ?>
26
+ </tbody>
27
+ </table>
templates/log_plugins.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * log_plugins.php is a template file. It's meant to be included in other php files. To work properly variables need to be set before file inclusion:
5
+ * @param array $rows List of plugins or modules as an associative array.
6
+ * @param string $row['Name'] Plugin's / Module's name
7
+ * @param string $row['Version'] - Plugin's / Module's version
8
+ */
9
+ ?>
10
+ <table>
11
+ <thead>
12
+ <tr>
13
+ <th><?php echo InstapageCmsPluginConnector::lang('#'); ?></th>
14
+ <th><?php echo InstapageCmsPluginConnector::lang('Name'); ?></th>
15
+ <th><?php echo InstapageCmsPluginConnector::lang('Version'); ?></th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <?php $index = 1; ?>
20
+ <?php foreach ($rows as $key => $row): ?>
21
+ <tr>
22
+ <td><?php echo $index ?></td>
23
+ <td><?php echo $row['Name'] ?></td>
24
+ <td><?php echo $row['Version'] ?></td>
25
+ </tr>
26
+ <?php $index++; ?>
27
+ <?php endforeach; ?>
28
+ </tbody>
29
+ </table>
views/base.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Base container for Instapage plugin dashboard.
5
+ */
6
+ ?>
7
+ <div class="l-wrapper">
8
+ <div class="ui-section">
9
+ <div id="instapage-container" class="ui-sub-section instapage-cms-plugin">
10
+ <div class="l-group__item page-loader">
11
+ <span class="c-loader c-loader--x-large"></span>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </div>
views/edit.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Template for Edit page tab in Instapage plugin dashboard.
5
+ */
6
+ ?>
7
+ <h2 class="ui-subtitle" data-bind="text: id() ? '<?php echo InstapageCmsPluginConnector::lang('Edit page'); ?>' : '<?php echo InstapageCmsPluginConnector::lang('Add page'); ?>' "></h2>
8
+ <form class="c-section l-space-tertiary" data-bind="visible: subAccounts().length">
9
+ <div class="ui-sub-section">
10
+ <div class="l-grid l-space-top-primary">
11
+ <div class="l-grid__cell l-grid__cell--1/3">
12
+ <label><?php echo InstapageCmsPluginConnector::lang('Sub-account'); ?></label>
13
+ <select class="c-form-text-item__field is-not-empty" data-bind="options: subAccounts, optionsText: 'name', optionsValue: 'id', value: choosenSubAccount"></select>
14
+ </div>
15
+ <div class="l-grid__cell l-grid__cell--1/3">
16
+ <label><?php echo InstapageCmsPluginConnector::lang('Landing Page'); ?></label>
17
+ <select class="c-form-text-item__field is-not-empty" data-bind="options: landingPages, optionsText: 'title', optionsValue:'id', value: choosenLandingPage"></select>
18
+ </div>
19
+ <div class="l-grid__cell l-grid__cell--1/3" data-bind="css: {'has-danger': !isTypeValid()}">
20
+ <label><?php echo InstapageCmsPluginConnector::lang('Page Type'); ?></label>
21
+ <select class="c-form-text-item__field is-not-empty" data-bind="options: pageTypes, optionsText: 'title', optionsValue:'name', value: choosenLandingPageType"></select>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div class="los-pollos c-form-text-item" data-bind="visible: choosenLandingPageType() === 'page', css: {'has-danger': !isSlugValid()}">
26
+ <span class="c-form-text-item__info"><?php echo InstapageCmsPluginConnector::getHomeURL() . '/'; ?></span>
27
+ <div>
28
+ <input class="c-form-text-item__field" data-bind="value: slug, event: {change: validateSlug}, css: {'is-not-empty': slug()}" type="textbox" />
29
+ <label class="c-form-text-item__label"><?php echo InstapageCmsPluginConnector::lang('URL for this page'); ?></label>
30
+ <div class="c-form-text-item__bar"></div>
31
+ <span class="c-form-text-item__info slug" data-bind="visible: !isSlugValid()">
32
+ <span><?php echo InstapageCmsPluginConnector::lang('Slug is invalid.'); ?></span>
33
+ <i class="material-icons c-form-text-item__info-icon"><?php echo InstapageCmsPluginConnector::lang('error'); ?></i>
34
+ </span>
35
+ </div>
36
+ </div>
37
+
38
+ <div class="ui-sub-section" style="margin-top: 20px;">
39
+ <button class="fx-ripple-effect c-button c-button--regular c-button--action" data-bind="click: publishPage" type="button" ><?php echo InstapageCmsPluginConnector::lang('Publish'); ?></button>
40
+ <button class="fx-ripple-effect c-button c-button--regular" data-bind="click: masterModel.toolbarModel.loadListPages"><span class="c-button__text"><?php echo InstapageCmsPluginConnector::lang('Back'); ?></span></button>
41
+ </div>
42
+ </form>
views/landingPageAjaxLoader.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * For pantheon hosting platform (https://pantheon.io/) we need to get content by ajax
4
+ * because pantheon replace UTM_ variables value to 'PANTHEON_STRIPPED' and redirect the page.
5
+ * Thanks to this solution all UTM_ variable are sent to instapage api.platform
6
+ */
7
+ ?>
8
+
9
+ <html>
10
+ <script id='b64-replace' type="text/javascript">
11
+ (function () {
12
+ var query = [];
13
+ var searchArray = document.location.search.replace('?', '').split('&');
14
+ var url = document.location.origin + document.location.pathname + '?b64=';
15
+ var i;
16
+
17
+ for (i = 0; i < searchArray.length; i++) {
18
+ if (searchArray[i].indexOf("PANTHEON_STRIPPED") === -1) {
19
+ query.push(searchArray[i]);
20
+ }
21
+ }
22
+ if (window.XMLHttpRequest) {
23
+ var xhReq = new XMLHttpRequest();
24
+ } else {
25
+ var xhReq = new ActiveXObject("Microsoft.XMLHTTP");
26
+ }
27
+
28
+ xhReq.open('GET', url + window.btoa(query.join('&')), false);
29
+ xhReq.setRequestHeader("X-Requested-With", "XMLHttpRequest");
30
+ xhReq.send();
31
+
32
+ document.open();
33
+ document.write(xhReq.responseText);
34
+ document.close();
35
+ document.getElementById("b64-replace").remove();
36
+ })();
37
+ </script>
38
+ <body>
39
+ </body>
40
+ </html>
views/listing.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Template for Listing page tab in Instapage plugin dashboard.
5
+ */
6
+ ?>
7
+ <div class="c-form-text-item c-form-text-item--no-label">
8
+ <input type="text" class="c-form-text-item__field c-form-text-item__field--with-icon" placeholder="<?php echo InstapageCmsPluginConnector::lang('Search query'); ?>" data-bind="value: query, valueUpdate: 'keyup'">
9
+ <div class="c-form-text-item__bar"></div>
10
+ <button class="c-button c-button--clean c-button--large c-form-text-item__button">
11
+ <i class="material-icons c-button__icon"><?php echo InstapageCmsPluginConnector::lang('search'); ?></i>
12
+ </button>
13
+ <span class="c-form-text-item__info">
14
+ <span><?php echo InstapageCmsPluginConnector::lang('Search for page title or URL'); ?></span>
15
+ </span>
16
+ </div>
17
+ <h2 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Page listing'); ?></h2>
18
+ <div data-bind='simpleGrid: gridViewModel'> </div>
19
+
20
+ <script type="text/html" id="page-row-template">
21
+ <tr>
22
+ <td class="preview-image c-table__cell" data-bind="html: (typeof $data.screenshot !== 'undefined' && $data.screenshot !== null) ? '<div class=\'cropper\'><img src=\'' + $data.screenshot + '\' /></div>' : ''"></td>
23
+ <td class="c-table__cell">
24
+ <div class="page-title" data-bind="text: $data.title, click: masterModel.toolbarModel.loadEditPage"></div>
25
+ <div class="page-url" data-bind="html: 'URL: <a href=\'<?php echo InstapageCmsPluginConnector::getHomeUrl();?>/' + $data.slug + '\' target=\'_blank\'/><?php echo InstapageCmsPluginConnector::getHomeUrl();?>/' + $data.slug + '</a>'"></div>
26
+ <div class="page-actions">
27
+ <div class="before-delete" data-bind="visible: !toDelete()">
28
+ <button class="fx-ripple-effect c-button c-button--flat c-button--small" data-bind="click:masterModel.toolbarModel.loadEditPage"><?php echo InstapageCmsPluginConnector::lang('Edit'); ?></button>
29
+ <button class="fx-ripple-effect c-button c-button--flat c-button--danger c-button--small" data-bind="click:masterModel.pagedGridModel.askForDeleteConfirmation"><?php echo InstapageCmsPluginConnector::lang('Delete'); ?></button>
30
+ </div>
31
+ <div class="after-delete" data-bind="visible: toDelete()">
32
+ <button class="fx-ripple-effect c-button c-button--flat c-button--small" data-bind="click:masterModel.pagedGridModel.cancelDelete"><?php echo InstapageCmsPluginConnector::lang('Cancel'); ?></button>
33
+ <button class="fx-ripple-effect c-button c-button--flat c-button--danger c-button--small" data-bind="click:masterModel.pagedGridModel.deletePage"><?php echo InstapageCmsPluginConnector::lang('Confirm delete'); ?></button>
34
+ </div>
35
+ </div>
36
+ </td>
37
+ <td data-bind="text: $data.type" class="c-table__cell c-table__cell--left"></td>
38
+ <td data-bind="visible: !statsLoaded()" class="c-table__cell c-table__cell--left">
39
+ <div class="l-group__item">
40
+ <span class="c-loader"></span>
41
+ </div>
42
+ </td>
43
+ <td data-bind="visible: statsLoaded() && typeof stats_cache() !== 'undefined' , template: {name: 'page-row-stats-template', foreach: stats_cache}" class="c-table__cell"></td>
44
+ <td data-bind="visible: statsLoaded() && typeof stats_cache() === 'undefined'" class="c-table__cell">
45
+ <?php echo InstapageCmsPluginConnector::lang('Stats are unavailable at the moment.'); ?>
46
+ </td>
47
+ <td data-bind="visible: !statsLoaded()" class="c-table__cell">
48
+ <div class="l-group__item">
49
+ <span class="c-loader"></span>
50
+ </div>
51
+ </td>
52
+ <td data-bind="visible: !statsLoaded()" class="c-table__cell">
53
+ <div class="l-group__item">
54
+ <span class="c-loader"></span>
55
+ </div>
56
+ </td>
57
+ <td data-bind="visible: !statsLoaded()" class="c-table__cell">
58
+ <div class="l-group__item">
59
+ <span class="c-loader"></span>
60
+ </div>
61
+ </td>
62
+ <td data-bind="visible: statsLoaded(), text: totalStats() ? totalStats().visits : 0" class="c-table__cell"></td>
63
+ <td data-bind="visible: statsLoaded(), text: totalStats() ? totalStats().conversions : 0" class="c-table__cell"></td>
64
+ <td data-bind="visible: statsLoaded(), text: totalStats() ? totalStats().conversionRate + '%' : '0%'" class="c-table__cell"></td>
65
+ </tr>
66
+ </script>
67
+
68
+ <script type="text/html" id="page-row-stats-template">
69
+ <div class="variation">
70
+ <div>
71
+ <span data-bind="text: variation" class="variation-name c-badge c-badge--action c-badge--has-text"></span>
72
+ </div>
73
+ <div data-bind="text: visits + ' visits with ' + conversions + ' conversions'" class="variation-stats"></div>
74
+ <div>
75
+ <span data-bind="text: conversions_rate + '%'" class="variation-conversion-rate c-badge c-badge--success c-badge--has-text"></span>
76
+ </div>
77
+ </div>
78
+ </script>
views/messages.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Template for messages displayed by Instapage plugin.
5
+ */
6
+ ?>
7
+ <div class="l-grid">
8
+ <div id="messages-container" class="instapage-cms-plugin l-grid__cell l-grid__cell--1/2" data-bind="foreach: messages">
9
+ <div class="message-wrapper c-modal c-modal--popover">
10
+ <div class="message c-modal__body" data-bind="html: text, css: type"></div>
11
+ <div class="c-button c-button--clean c-modal__close c-button--large" data-bind="click: $root.removeMessage">
12
+ <i class="delete-message material-icons c-button__icon"><?php echo InstapageCmsPluginConnector::lang('close'); ?></i>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </div>
views/settings.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Template for Settings page tab in Instapage plugin dashboard.
5
+ */
6
+ ?>
7
+ <h2 class="ui-subtitle" data-bind="click:getConfig"><?php echo InstapageCmsPluginConnector::lang('Instapage Plugin Settings'); ?></h2>
8
+ <div class="instapage-content ui-sub-section">
9
+ <div class="login-form c-section l-space-tertiary">
10
+ <h3 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Please log into your Instapage account'); ?></h3>
11
+ <form>
12
+ <div data-bind="visible: !userToken()">
13
+ <div class="l-grid">
14
+ <div class="l-grid__cell l-grid__cell--1/3">
15
+ <div class="c-form-text-item" data-bind="css: {'has-danger': !isLoginAndPasswordValid()}">
16
+ <input class="c-form-text-item__field" data-bind="value: email" type="textbox" />
17
+ <label class="c-form-text-item__label"><?php echo InstapageCmsPluginConnector::lang('Instapage User Email'); ?></label>
18
+ <div class="c-form-text-item__bar"></div>
19
+ </div>
20
+ </div>
21
+ <div class="l-grid__cell l-grid__cell--1/3">
22
+ <div class="c-form-text-item" data-bind="css: {'has-danger': !isLoginAndPasswordValid()}">
23
+ <input class="c-form-text-item__field" data-bind="value: password" type="password" />
24
+ <label class="c-form-text-item__label"><?php echo InstapageCmsPluginConnector::lang('Instapage Password'); ?></label>
25
+ <div class="c-form-text-item__bar"></div>
26
+ </div>
27
+ </div>
28
+ <div class="l-grid__cell l-grid__cell--1/3">
29
+ <button class="fx-ripple-effect c-button c-button--regular c-button--action" data-bind='click: loginUser'><?php echo InstapageCmsPluginConnector::lang('Login'); ?></button>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ <div data-bind="visible: userToken()">
35
+ <div>
36
+ <?php echo InstapageCmsPluginConnector::lang('You are logged in as'); ?>
37
+ <span data-bind="text: email"></span>
38
+ </div>
39
+ <div class="l-space-ver-tertiary">
40
+ <button class="fx-ripple-effect c-button c-button--regular c-button--action l-space-top-tertiary" data-bind='click: disconnectAndLogout'><?php echo InstapageCmsPluginConnector::lang('Logout'); ?></button>
41
+ </div>
42
+ </div>
43
+ <div data-bind="visible: !hideConnectedTokens() && connectedTokens().length">
44
+ <h3><?php echo InstapageCmsPluginConnector::lang('Select which subaccounts you would like to connect with %s site.', InstapageCmsPluginConnector::getCMSName()); ?></h3>
45
+ <ul class="c-list" data-bind="template: {name: 'subaccounts-connection-template', foreach: connectedTokens}">
46
+ </ul>
47
+ <button class="fx-ripple-effect c-button c-button--regular c-button--action c-button--small" data-bind="click: connectSelectedSubAccounts">
48
+ <span class="c-button__text"><?php echo InstapageCmsPluginConnector::lang('Connect to %s', InstapageCmsPluginConnector::getCMSName()); ?></span>
49
+ </button>
50
+ <button class="fx-ripple-effect c-button c-button--regular c-button--small" data-bind="click: closeConnectionSection">
51
+ <span class="c-button__text"><?php echo InstapageCmsPluginConnector::lang('Close'); ?></span>
52
+ </button>
53
+ </div>
54
+
55
+ <div class="tokens-container">
56
+ <h4 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Client tokens'); ?></h4>
57
+ <div class="l-grid">
58
+ <div class="l-grid__cell l-grid__cell--2/3">
59
+ <div class="c-form-text-item" data-bind="css: {'has-danger': !isTokenToAddValid()}">
60
+ <input class="c-form-text-item__field" data-bind="value:tokenToAdd, valueUpdate: 'input'" type="textbox" />
61
+ <label class="c-form-text-item__label"><?php echo InstapageCmsPluginConnector::lang('Add token'); ?></label>
62
+ <div class="c-form-text-item__bar"></div>
63
+ <span class="c-form-text-item__info" data-bind="visible: !isTokenToAddValid()" >
64
+ <span><?php echo InstapageCmsPluginConnector::lang('This token is invalid.'); ?></span>
65
+ <i class="material-icons c-form-text-item__info-icon"><?php echo InstapageCmsPluginConnector::lang('error'); ?></i>
66
+ </span>
67
+ </div>
68
+ </div>
69
+ <div class="l-grid__cell l-grid__cell--1/3">
70
+ <button class="fx-ripple-effect c-button c-button--regular c-button--action" data-bind="enable: tokenToAdd().length > 0, click: addToken" type="button" ><?php echo InstapageCmsPluginConnector::lang('Add token'); ?></button>
71
+ </div>
72
+ </div>
73
+
74
+ <table class="c-table">
75
+ <caption class="c-table__caption">
76
+ <div class="l-group l-group--block l-group--ver-center l-group--hor-space-between c-table__caption-row">
77
+ <div class="l-group__item c-table__caption-cell">
78
+ <span class="c-table__caption-title"><?php echo InstapageCmsPluginConnector::lang('Tokens'); ?></span>
79
+ </div>
80
+ </div>
81
+ </caption>
82
+
83
+ <thead class="c-table__head">
84
+ <tr>
85
+ <th class="c-table__cell c-table__cell--left"><?php echo InstapageCmsPluginConnector::lang('Token'); ?></th>
86
+ <th class="c-table__cell c-table__cell--right"><?php echo InstapageCmsPluginConnector::lang('Remove'); ?></th>
87
+ </tr>
88
+ </thead>
89
+
90
+ <tbody class="c-table__body" data-bind="foreach: config.tokens">
91
+ <tr>
92
+ <td class="c-table__cell c-table__cell--left">
93
+ <div class="c-form-text-item" data-bind="css: {'has-danger': valid() < 0, 'has-success': valid() > 0}">
94
+ <input class="c-form-text-item__field" data-bind="value: value, valueUpdate: 'input', css: {'is-not-empty': value}" type="textbox" size="50" readonly="readonly"/>
95
+ <label class="c-form-text-item__label"><?php echo InstapageCmsPluginConnector::lang('Add token'); ?></label>
96
+ <div class="c-form-text-item__bar"></div>
97
+ <span class="c-form-text-item__info" data-bind="visible: valid() < 0" >
98
+ <span><?php echo InstapageCmsPluginConnector::lang('This token is invalid.'); ?></span>
99
+ <i class="material-icons c-form-text-item__info-icon"><?php echo InstapageCmsPluginConnector::lang('error'); ?></i>
100
+ </span>
101
+ </div>
102
+ </td>
103
+ <td class="c-table__cell c-table__cell--right">
104
+ <button class="fx-ripple-effect c-button c-button--regular c-button--action" data-bind="click: $root.removeToken"><?php echo InstapageCmsPluginConnector::lang('Remove token'); ?></button>
105
+ </td>
106
+ </tr>
107
+ </tbody>
108
+
109
+ </table>
110
+ </div>
111
+ </form>
112
+ </div>
113
+
114
+ <form class="c-section l-space-tertiary">
115
+ <div class="cross-origin-form ui-section ">
116
+ <h3 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Cross-origin proxy services'); ?></h3>
117
+ <label class="c-mark">
118
+ <input class="c-mark__input" data-bind="checked: config.crossOrigin, click: autoSaveConfig" type="checkbox" >
119
+ <i class="c-mark__icon c-mark__icon--checkbox material-icons"><?php echo InstapageCmsPluginConnector::lang('check'); ?></i>
120
+ <span class="c-mark__label"><?php echo InstapageCmsPluginConnector::lang('Uncheck this if you have problems with sending submissions from landing page'); ?></span>
121
+ </label>
122
+ </div>
123
+
124
+ <div class="diagnostic-form ui-section">
125
+ <h3 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Diagnostics'); ?></h3>
126
+ <p class="l-space-bottom-tertiary" data-bind="css: {'diagnostic-mode-on': config.diagnostics}">
127
+ <?php echo InstapageCmsPluginConnector::lang('The diagnostic tool helps our customer support and developers to track and eliminate some most problematic issues.'); ?>
128
+ <br />
129
+ <span class="diagnostic-mode-warning"><?php echo InstapageCmsPluginConnector::lang('Do not turn this option on if unnecessary, it\'s very resource consuming and can increase your page loading time significantly!'); ?></span>
130
+ </p>
131
+ <label class="c-mark">
132
+ <input class="c-mark__input" data-bind="checked: config.diagnostics, click: autoSaveConfig" type="checkbox" >
133
+ <i class="c-mark__icon c-mark__icon--checkbox material-icons"><?php echo InstapageCmsPluginConnector::lang('check'); ?></i>
134
+ <span class="c-mark__label"><?php echo InstapageCmsPluginConnector::lang('Turn on diagnostics.'); ?></span>
135
+ </label>
136
+
137
+ <div class="l-space-ver-tertiary" data-bind="visible: config.diagnostics">
138
+ <p><?php echo InstapageCmsPluginConnector::lang('Current number of entries in Instapage log: '); ?></p>
139
+ </div>
140
+ <button class="fx-ripple-effect c-button c-button--regular c-button--small c-button--action" data-bind="click: downloadLog">
141
+ <span class="c-button__text"><?php echo InstapageCmsPluginConnector::lang('Download diagnostic data'); ?></span>
142
+ </button>
143
+ <button class="fx-ripple-effect c-button c-button--regular c-button--small c-button--action" data-bind="click: clearLog"><?php echo InstapageCmsPluginConnector::lang('Clear log'); ?>
144
+ </button>
145
+ </div>
146
+ <div class="custom-params-form ui-section">
147
+ <h3 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Custom parameters'); ?></h3>
148
+ <p class='l-space-bottom-primary'><?php echo InstapageCmsPluginConnector::lang('Instapage plugin won\'t display a landing page if one of given parameters is present in URL.'); ?></p>
149
+ <div class="c-form-text-item">
150
+ <input class="c-form-text-item__field" data-bind="value: config.customParams, valueUpdate: 'input', css: {'is-not-empty': config.customParams}, event: {blur: autoSaveConfig}" type="textbox" size="90">
151
+ <label class="c-form-text-item__label"><?php echo InstapageCmsPluginConnector::lang('Add parameters'); ?></label>
152
+ <div class="c-form-text-item__bar"></div>
153
+ </div>
154
+ <br>
155
+ <span><?php echo InstapageCmsPluginConnector::lang('List of custom parameters, separated by "|", e.g. post_type=movie|page_id|keyword'); ?></span>
156
+ </div>
157
+ <div class="custom-params-form ui-section">
158
+ <h3 class="ui-subtitle"><?php echo InstapageCmsPluginConnector::lang('Landing page migration'); ?></h3>
159
+ <p class='l-space-bottom-primary'><?php echo InstapageCmsPluginConnector::lang('Click "Migrate" button to migrate your landing pages from old version of our plugin. Old plugin does not have to be activated.'); ?></p>
160
+ <button class="fx-ripple-effect c-button c-button--regular c-button--small c-button--action" data-bind="click: migrateDeprecatedData">
161
+ <span class="c-button__text"><?php echo InstapageCmsPluginConnector::lang('Migrate'); ?></span>
162
+ </button>
163
+ </div>
164
+ <?php echo InstapageCmsPluginConnector::getSettingsModule(); ?>
165
+ </form>
166
+ </div>
167
+
168
+ <script type="text/html" id="subaccounts-connection-template">
169
+ <li class="c-list-item">
170
+ <span class="c-list-item__content">
171
+ <label class="c-mark">
172
+ <input type="checkbox" class="c-mark__input" data-bind="checked: checked, click: $root.toggleAllSubaccounts">
173
+ <i class="c-mark__icon c-mark__icon--checkbox material-icons"><?php echo InstapageCmsPluginConnector::lang('check'); ?></i>
174
+ <span class="c-mark__label" data-bind="text: name"></span>
175
+ </label>
176
+ </span>
177
+ </li>
178
+ </script>
views/toolbar.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Template for toolbar ofInstapage plugin.
5
+ */
6
+ ?>
7
+ <div id="instapage-toolbar" class="l-wrapper instapage-cms-plugin">
8
+ <div>
9
+ <div class="c-tabs c-tabs--full-width c-tabs--with-shadow">
10
+ <ul class="c-tabs__list">
11
+ <li class="c-tab listing-view is-active">
12
+ <a class="c-tab__text" data-bind="click: loadListPages"><?php echo InstapageCmsPluginConnector::lang('List pages'); ?></a>
13
+ </li>
14
+ <li class="c-tab edit-view">
15
+ <a class="c-tab__text" data-bind="click: loadEditPage"><?php echo InstapageCmsPluginConnector::lang('Add page'); ?></a>
16
+ </li>
17
+ <li class="c-tab settings-view">
18
+ <a class="c-tab__text" data-bind="click: loadSettings"><?php echo InstapageCmsPluginConnector::lang('Settings'); ?></a>
19
+ </li>
20
+ </ul>
21
+ <div class="c-tabs__slider"></div>
22
+ </div>
23
+ </div>
24
+ </div>