WordPress Page Builder – Beaver Builder - Version 2.1.1.2

Version Description

Download this release

Release Info

Developer pross
Plugin Icon 128x128 WordPress Page Builder – Beaver Builder
Version 2.1.1.2
Comparing to
See all releases

Code changes from version 2.0.6.4 to 2.1.1.2

Files changed (107) hide show
  1. changelog.txt +370 -173
  2. classes/class-fl-builder-admin-pointers.php +94 -0
  3. classes/class-fl-builder-admin-posts.php +28 -5
  4. classes/class-fl-builder-admin-settings.php +10 -4
  5. classes/class-fl-builder-ajax-layout.php +47 -13
  6. classes/class-fl-builder-ajax.php +1 -0
  7. classes/class-fl-builder-debug.php +37 -4
  8. classes/class-fl-builder-filesystem.php +14 -3
  9. classes/class-fl-builder-fonts.php +4 -4
  10. classes/class-fl-builder-icons.php +48 -9
  11. classes/class-fl-builder-iframe-preview.php +12 -2
  12. classes/class-fl-builder-importer.php +2 -2
  13. classes/class-fl-builder-loader.php +14 -4
  14. classes/class-fl-builder-loop.php +25 -11
  15. classes/class-fl-builder-model.php +304 -52
  16. classes/class-fl-builder-notifications.php +174 -0
  17. classes/class-fl-builder-service-activecampaign.php +2 -3
  18. classes/class-fl-builder-service-aweber.php +2 -3
  19. classes/class-fl-builder-service-campaign-monitor.php +1 -2
  20. classes/class-fl-builder-service-campayn.php +2 -3
  21. classes/class-fl-builder-service-constant-contact.php +3 -5
  22. classes/class-fl-builder-service-convertkit.php +1 -2
  23. classes/class-fl-builder-service-drip.php +2 -3
  24. classes/class-fl-builder-service-email-address.php +1 -2
  25. classes/class-fl-builder-service-enormail.php +2 -4
  26. classes/class-fl-builder-service-getresponse.php +23 -10
  27. classes/class-fl-builder-service-godaddy-email-marketing.php +1 -2
  28. classes/class-fl-builder-service-hatchbuck.php +4 -6
  29. classes/class-fl-builder-service-icontact-pro.php +2 -3
  30. classes/class-fl-builder-service-icontact.php +2 -3
  31. classes/class-fl-builder-service-infusionsoft.php +3 -4
  32. classes/class-fl-builder-service-madmimi.php +1 -2
  33. classes/class-fl-builder-service-mailchimp.php +82 -89
  34. classes/class-fl-builder-service-mailerlite.php +5 -6
  35. classes/class-fl-builder-service-mailpoet.php +2 -2
  36. classes/class-fl-builder-service-mailrelay.php +1 -2
  37. classes/class-fl-builder-service-mautic.php +2 -2
  38. classes/class-fl-builder-service-sendinblue.php +1 -2
  39. classes/class-fl-builder-service-sendy.php +1 -2
  40. classes/class-fl-builder-services.php +2 -4
  41. classes/class-fl-builder-shortcodes.php +6 -0
  42. classes/class-fl-builder-ui-content-panel.php +32 -3
  43. classes/class-fl-builder-ui-settings-forms.php +145 -10
  44. classes/class-fl-builder-update.php +8 -4
  45. classes/class-fl-builder-usage.php +455 -0
  46. classes/class-fl-builder-user-access.php +19 -7
  47. classes/class-fl-builder-utils.php +34 -0
  48. classes/class-fl-builder-wp-blocks-layout.php +167 -0
  49. classes/class-fl-builder-wp-blocks.php +96 -0
  50. classes/class-fl-builder-wpcli-command.php +56 -2
  51. classes/class-fl-builder.php +169 -84
  52. classes/class-fl-jsmin.php +4 -4
  53. css/build/builder.bundle.css +162 -0
  54. css/build/builder.bundle.min.css +1 -0
  55. css/build/wp-editor.bundle.css +24 -0
  56. css/build/wp-editor.bundle.min.css +1 -0
  57. css/fl-builder-admin-posts.css +6 -5
  58. css/fl-builder-admin-settings.css +3 -3
  59. css/fl-builder-admin-usage.css +27 -0
  60. css/fl-builder-layout-responsive.css +25 -24
  61. css/fl-builder-layout.css +3 -0
  62. css/fl-builder.css +58 -10
  63. css/fl-builder.min.css +1 -1
  64. css/fl-icon-selector.css +2 -2
  65. fl-builder.php +1 -1
  66. img/screenshot-getting-started.jpg +0 -0
  67. img/screenshot-getting-started.png +0 -0
  68. img/svg/bell-active.svg +6 -0
  69. img/svg/bell.svg +5 -0
  70. includes/admin-posts.php +6 -0
  71. includes/admin-settings-tools.php +29 -1
  72. includes/admin-settings-welcome.php +8 -9
  73. includes/column-css.php +2 -2
  74. includes/compatibility.php +106 -4
  75. includes/export.php +4 -5
  76. includes/row-css.php +1 -1
  77. includes/row-video.php +5 -0
  78. includes/ui-extras.php +2 -0
  79. includes/ui-field-ordering.php +1 -1
  80. includes/ui-field-video.php +3 -0
  81. includes/ui-field.php +1 -1
  82. includes/ui-js-config.php +189 -177
  83. includes/ui-js-templates.php +48 -29
  84. includes/ui-legacy-custom-field.php +2 -2
  85. includes/ui-loop-settings.php +11 -0
  86. includes/ui-settings-config.php +4 -1
  87. includes/ui-settings-form-row.php +3 -3
  88. includes/updater-config.php +1 -1
  89. includes/updater/classes/class-fl-updater.php +34 -20
  90. includes/vendor/getresponse/getresponse.php +400 -570
  91. includes/vendor/mailchimp/Mailchimp/Campaigns.php +0 -378
  92. includes/vendor/mailchimp/Mailchimp/Conversations.php +0 -80
  93. includes/vendor/mailchimp/Mailchimp/Ecomm.php +0 -86
  94. includes/vendor/mailchimp/Mailchimp/Exceptions.php +0 -471
  95. includes/vendor/mailchimp/Mailchimp/Folders.php +0 -62
  96. includes/vendor/mailchimp/Mailchimp/Gallery.php +0 -106
  97. includes/vendor/mailchimp/Mailchimp/Goal.php +0 -49
  98. includes/vendor/mailchimp/Mailchimp/Helper.php +0 -237
  99. includes/vendor/mailchimp/Mailchimp/Lists.php +0 -904
  100. includes/vendor/mailchimp/Mailchimp/Mobile.php +0 -10
  101. includes/vendor/mailchimp/Mailchimp/Neapolitan.php +0 -10
  102. includes/vendor/mailchimp/Mailchimp/Reports.php +0 -459
  103. includes/vendor/mailchimp/Mailchimp/Templates.php +0 -114
  104. includes/vendor/mailchimp/Mailchimp/Users.php +0 -105
  105. includes/vendor/mailchimp/Mailchimp/Vip.php +0 -111
  106. includes/vendor/mailchimp/mailchimp.php +528 -221
  107. js/build/builder.bundle.js +5216 -0
changelog.txt CHANGED
@@ -1,7 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <h4>2.0.6.4 - 03/27/2018</h4>
2
  <p><strong>Enhancements</strong></p>
3
  <ul>
4
- <li>Added optional Terms and Conditions to Contact and Subcribe Modules to comply with GDPR.</li>
5
  </ul>
6
  <p><strong>Bug Fixes</strong></p>
7
  <ul>
@@ -21,6 +217,7 @@
21
  <li>Fixed links not being clickable in modules that use bxslider with Firefox 59.</li>
22
  <li>Fixed incorrect links in Social Buttons Module when added in Themer.</li>
23
  <li>Added <code>$id</code> and <code>$type</code> to <code>fl_builder_render_module_css_settings</code> filter variables.</li>
 
24
  </ul>
25
 
26
  <h4>2.0.6.2 - 03/13/2018</h4>
@@ -232,179 +429,179 @@
232
  <li>Fixed GeneratePress Premium plugin Blog option overrules the Post modules excerpt setting.</li>
233
  </ul>
234
 
235
- <h4>2.0.2.2 - 12/06/2017</h4>
236
  <p>Beaver Builder 2.0 is now available for remote update!</p>
237
 
238
- <h4>2.0.2.1 - 11/27/2017</h4>
239
- <p><strong>Bug Fixes</strong></p>
240
- <ul>
241
- <li>Fixed responsive editing mode not working correctly.</li>
242
- <li>Fixed white labeling not working correctly on the updates page.</li>
243
  </ul>
244
 
245
  <h4>2.0.2 - 11/16/2017</h4>
246
- <p><strong>Enhancements</strong></p>
247
- <ul>
248
- <li>Added <code>fl_builder_cache_cleared</code> action.</li>
249
- </ul>
250
- <p><strong>Bug Fixes</strong></p>
251
- <ul>
252
- <li>Fixed settings config not loading when query strings are removed from script URLs.</li>
253
- <li>Fixed widgets not showing when site language is not in English.</li>
254
- <li>Fixed error when using namespaced widgets.</li>
255
- <li>Fixed JS errors in IE.</li>
256
- <li>Fixed keyboard shortcut formatting in IE.</li>
257
- <li>Fixed capitalization issues with translations.</li>
258
- <li>Fixed character encoding issues with strtolower.</li>
259
- </ul>
260
-
261
- <h4>2.0.1.1 - 11/07/2017</h4>
262
- <p><strong>Bug Fixes</strong></p>
263
- <ul>
264
- <li>Hotfix for a change in 2.0.1 that broke loading of the settings for the Subscribe Form module.</li>
265
- </ul>
266
-
267
- <h4>2.0.1 - 11/06/2017</h4>
268
- <p><strong>Bug Fixes</strong></p>
269
- <ul>
270
- <li>Fixed errors caused by settings config not completely loading on certain server setups.</li>
271
- <li>Fixed PHP warnings when attachment meta doesn't have a width or height set.</li>
272
- </ul>
273
-
274
- <h4>2.0 - 11/01/2017</h4>
275
  <p><strong>Beaver Builder 2.0 is here!</strong></p>
276
  <p>Please note that 2.0 is currently only available from your My Account page or via remote update if you already have 2.0 installed. We'll be releasing remote updates for older versions of Beaver Builder within the next few weeks.</p>
277
 
278
- <h4>2.0-beta.3 - 10/31/2017</h4>
279
- <p><strong>Enhancements</strong></p>
280
- <ul>
281
- <li>Updated the help video for 2.0.</li>
282
- <li>Added fl_row_resize_settings filter.</li>
283
- </ul>
284
- <p><strong>Bug Fixes</strong></p>
285
- <ul>
286
- <li>Fixed various UI styling issues.</li>
287
- <li>Fixed editing global rows not working properly.</li>
288
- <li>Fixed template override settings not working on multisite.</li>
289
- <li>Fixed repeater fields in nested forms not working.</li>
290
- <li>Fixed stylesheets in the body tag not being parsed for responsive preview.</li>
291
- <li>Fixed content panel showing during preview or unpinning during preview when not expected.</li>
292
- <li>Fixed anchor links in the layout causing the builder to launch again after publish.</li>
293
- </ul>
294
-
295
- <h4>2.0-beta.2 - 10/12/2017</h4>
296
- <p><strong>Enhancements</strong></p>
297
- <ul>
298
- <li>Publish button now says 'Submit for Review' if a user doesn't have permission to publish.</li>
299
- <li>Pinned settings are now responsive for smaller devices.</li>
300
- <li>Moved WordPress widgets into their own group.</li>
301
- <li>Moved Themer modules into their own group (coming in Themer 1.0.3).</li>
302
- </ul>
303
- <p><strong>Bug Fixes</strong></p>
304
- <ul>
305
- <li>Fixed row actions being covered by modules when the row has no padding.</li>
306
- <li>Fixed values in text inputs not being escaped which breaks the markup.</li>
307
- <li>Fixed settings being dragged or resized so you can't access the drag handle anymore.</li>
308
- <li>Fixed browser zoom triggering the action overflow menu when it shouldn't.</li>
309
- <li>Fixed multiple issues with saving new templates.</li>
310
- <li>Fixed styling issues with dark mode.</li>
311
- <li>Fixed module aliases not showing in the content panel.</li>
312
- <li>Fixed widgets not showing in the content panel.</li>
313
- </ul>
314
-
315
- <h4>2.0-beta.1 - 10/04/2017</h4>
316
- <p><strong>Enhancements</strong></p>
317
- <ul>
318
- <li>Added keyboard shortcut UI to the builder menu.</li>
319
- <li>Reworked keyboard shortcut system to support displaying shortcuts with labels and modifier key symbols.</li>
320
- </ul>
321
- <p><strong>Bug Fixes</strong></p>
322
- <ul>
323
- <li>Fixed various styling issues.</li>
324
- <li>Fixed photo and video fields that aren't in node settings not showing saved data when opened again after the page is refreshed.</li>
325
- <li>Fixed error when saving a template with no category set.</li>
326
- <li>Fixed saved values for medium and responsive in dimension fields not showing when going back to edit a node.</li>
327
- <li>Fixed module templates not showing in the content panel.</li>
328
- <li>Fixed issue with module hover in the content panel being covered by siblings.</li>
329
- <li>Fixed a major issue with secondary loops triggering the builder's content filter when they shouldn't. This caused a number of issues including an infinite loop in Themer and the incorrect posts being displayed on standard builder pages.</li>
330
- <li>Fixed FLBuilder::render_query so it doesn't have to override $wp_query which was causing incorrect connection data for Themer layouts.</li>
331
- </ul>
332
-
333
- <h4>2.0-alpha.7 - 09/21/2017</h4>
334
- <p><strong>Enhancements</strong></p>
335
- <ul>
336
- <li>Added the ability to match posts in the loop settings by related taxonomy terms.</li>
337
- </ul>
338
- <p><strong>Bug Fixes</strong></p>
339
- <ul>
340
- <li>Fixed page scrolling breaking when opening the main menu.</li>
341
- <li>Fixed field connections not rendering in nested settings forms.</li>
342
- </ul>
343
-
344
- <h4>2.0-alpha.6.1 - 09/19/2017</h4>
345
- <p><strong>Bug Fixes</strong></p>
346
- <ul>
347
- <li>Fixed a bug with the option labels in select option groups not showing.</li>
348
- </ul>
349
-
350
- <h4>2.0-alpha.6 - 09/19/2017</h4>
351
- <p><strong>Bug Fixes</strong></p>
352
- <ul>
353
- <li>Fixed a bug breaking the Pods integration.</li>
354
- <li>Fixed an issue causing the builder UI to break on SiteGround servers.</li>
355
- </ul>
356
-
357
- <h4>2.0-alpha.5 - 09/06/2017</h4>
358
- <p><strong>Enhancements</strong></p>
359
- <ul>
360
- <li>Settings panel tabs no longer become a drop-down menu when slim. Tabs that cannot fit into the available space are pushed into a menu.</li>
361
- <li>You can now move between settings tabs with the keyboard shortcuts "CMD + Left Arrow" or "CMD + Right Arrow" (CTRL on Windows).</li>
362
- <li>You can now reset row or column widths from the module overlay.</li>
363
- <li>"CMD + i" (CTRL on Windows) shortcut will take you directly to module search.</li>
364
- <li>Module search is now case-insensitive.</li>
365
- <li>Duplicated items that appear off screen will now scroll into view.</li>
366
- </ul>
367
- <p><strong>Bug Fixes</strong></p>
368
- <ul>
369
- <li>Fixed scrolling not working when hovering over the content panel and then back into the layout.</li>
370
- <li>Hovering over the content panel should no longer cause screen jitter in Windows browsers.</li>
371
- <li>Icon selector search/filter has been restored.</li>
372
- <li>J, K, L, and ; keys now show content panel tabs even when the panel has been collapsed.</li>
373
- <li>Dropping a row template into the layout immediately loads fonts.</li>
374
- <li>Overriding core templates now works again when applying a template.<li>
375
- <li>Fixed ACE editor resize causing incorrect cursor position.</li>
376
- <li>Fixed multiple issues with pinning in Safari and Firefox.</li>
377
- </ul>
378
-
379
- <h4>2.0-alpha.4 - 08/29/2017</h4>
380
- <ul>
381
- <li>A new slimmer version of the settings panels now opens when clicking to edit content.</li>
382
- <li>Settings panels can now be resized to any size that you desire.</li>
383
- <li>We'll remember the size and position you set for the settings panels even after reloading the page.</li>
384
- <li>The content panel and settings can now be pinned together on either the left or right side of the screen. You can resize the pinned sidebar when you need a little more room.</li>
385
- <li>You can now work with the toolbar or in the layout even when settings are open.</li>
386
- <li>If settings are open and you take action anywhere else in the builder, we'll save and close them for you. This means you can edit one module and click to edit another without ever needing to click save in between.</li>
387
- <li>Module search has been moved into the modules tab for more intuitive access.</li>
388
- </ul>
389
-
390
- <h4>2.0-alpha.3 - 08/07/2017</h4>
391
- <ul>
392
- <li>Settings forms now load instantly! We've completely rewritten the settings forms in JavaScript so they dont need to be loaded from the server anymore. The only time something needs to load is if youre using a third party add-on that introduces legacy PHP fields. Well have docs on the new JavaScript settings APIs when 2.0 is released and hope that all major add-on authors will convert their fields to JavaScript so everything loads instantly! :)</li>
393
- <li>Added an initial set of core row templates.</li>
394
- <li>Various bug fixes and style tweaks.</li>
395
- </ul>
396
-
397
- <h4>2.0-alpha.2 - 07/24/2017</h4>
398
- <ul>
399
- <li>Added the ability to duplicate columns.</li>
400
- <li>Increased contrast to light and dark UI modes.</li>
401
- <li>Added module icons.</li>
402
- <li>Restyled content group selector.</li>
403
- <li>Reworked how group labels are displayed in search results.</li>
404
- <li>Style hardening for GeneratePress theme.</li>
405
- <li>Publishing out of the builder now moves the history state and updates the url. Re-entering will move back.</li>
406
- </ul>
407
-
408
  <h4>1.11.1 11/29/17</h4>
409
  <p><strong>Hot Fix</strong></p>
410
  <ul>
@@ -596,8 +793,8 @@
596
  </ul>
597
  <p><strong>Bug Fixes</strong></p>
598
  <ul>
599
- <li>Removed the new core media widgets from the builder since they dont work in the builder and we have modules that do the same thing.</li>
600
- <li>Fixed the core text widget form in the builder so the legacy form loads since the new form in 4.8 doesnt. The text widget is also removed from the module list in favor of the Text Editor and HTML modules. Sites previously using the text widget will still render and they can still be edited, they just wont be able to add new text widgets.</li>
601
  <li>Fixed Slideshow module not showing in the Tabs module.</li>
602
  <li>Fixed JS error in Row > Background > Slideshow on touch-enabled devices.</li>
603
  <li>Increased the video ratio to 16:9 to fix the top/bottom black border on responsive layout.</li>
@@ -747,15 +944,15 @@
747
  </ul>
748
  <p><strong>Post Module Enhancements</strong></p>
749
  <ul>
750
- <li>Added columns layout to the layout setting.</li>
751
  <li>Added more layout and styling settings.</li>
752
- <li>The no results message is now shown when no posts are found.</li>
753
  <li>Added a setting to show a search form if no posts are found.</li>
754
  <li>Added the ability to exclude posts in the content filter for the query.</li>
755
  </ul>
756
  <p><strong>Menu Module Enhancements</strong></p>
757
  <ul>
758
- <li>Added below row" option for mobile menu position.</li>
759
  <li>Added font family setting.</li>
760
  <li>Misc CSS improvements.</li>
761
  </ul>
@@ -799,7 +996,7 @@
799
  <h4>1.9.5.1 - 3/21/2017</h4>
800
  <p><strong>Bug Fixes</strong></p>
801
  <ul>
802
- <li>Rolled back change in 1.9.5 that fixed some photos not going full width on mobile. That was causing all photos to go full width on mobile even when not intended. Well revisit that fix in 1.10.</li>
803
  </ul>
804
 
805
  <h4>1.9.5 - 3/20/2017</h4>
@@ -2535,5 +2732,5 @@
2535
  <h4>0.8.2</h4>
2536
  <p>Responsive module margins now only reset if negative or greater than the default.</p>
2537
 
2538
- <h4>0.8.1</h4>
2539
  <p>Initial beta release.</p>
1
+ <h4>2.1.1.2 - 05/07/2018</h4>
2
+ <p><strong>Enhancements</strong></p>
3
+ <ul>
4
+ <li>Added <code>fl_code_checking_enabled</code> filter to disable all code checking.</li>
5
+ <li>Added <code>fl_builder_get_layout_metadata</code> filter for filtering layout data when it comes out of the database.</li>
6
+ <li>Disabled notifications in restricted editing mode.</li>
7
+ <li>Updated Font Awesome to 5.0.12.</li>
8
+ </ul>
9
+ <p><strong>Bug Fixes</strong></p>
10
+ <ul>
11
+ <li>Fixed characters being encoded in text inputs when using inline editing.</li>
12
+ <li>Fixed invalid code errors preventing saving of code fields.</li>
13
+ <li>Fixed a fatal error with corrupted global rows.</li>
14
+ </ul>
15
+
16
+ <h4>2.1.1.1 - 05/02/2018</h4>
17
+ <p><strong>Enhancements</strong></p>
18
+ <ul>
19
+ <li>Font Awesome PRO support added! See <code>https://kb.wpbeaverbuilder.com/article/645-font-awesome-5-icons</code> for instructions.</li>
20
+ </ul>
21
+
22
+ <h4>2.1.1 - 05/02/2018</h4>
23
+ <p><strong>Enhancements</strong></p>
24
+ <ul>
25
+ <li>New filter <code>fl_inline_editing_enabled</code> to disable inline editing.</li>
26
+ <li>Removed obsolete Event Espresso code now covered by their official addon found at <code>https://github.com/eventespresso/eea-beaver-builder</code></li>
27
+ </ul>
28
+ <p><strong>Bug Fixes</strong></p>
29
+ <ul>
30
+ <li>Fixed JS error when canceling out of a settings form during responsive preview.</li>
31
+ <li>Fixed various icon issues and added a compatibility function to make sure css files are loaded in right order.</li>
32
+ </ul>
33
+
34
+ <h4>2.1.0.2 - 04/27/2018</h4>
35
+ <p><strong>Hot Fix</strong></p>
36
+ <ul>
37
+ <li>Fixed more compression issues with loading the settings JS.</li>
38
+ <li>Fixed a branding issue with Agency package, you can now use 'Page Builder' again.</li>
39
+ <li>Fixed issue with YouTube row backgrounds not looping.</li>
40
+ </ul>
41
+ <h4>2.1.0.1 - 04/26/2018</h4>
42
+ <p><strong>Hot Fix</strong></p>
43
+ <ul>
44
+ <li>Fixed compression issues with loading the settings JS.</li>
45
+ <li>Fixed CSS/JS assets returning a 404 after the builder has launched.</li>
46
+ <li>Fixed the button module not accepting 0 for style settings.</li>
47
+ <li>Fixed translation issues.</li>
48
+ <li>Fixed Font Awesome not loading for some modules.</li>
49
+ </ul>
50
+
51
+ <h4>2.1 - 04/25/2018</h4>
52
+ <p>Beaver Builder 2.1 "Redridge" is here! Check out the <a href="https://www.wpbeaverbuilder.com/beaver-builder-2-1-redridge/">blog post</a> for more info.</p>
53
+ <p><strong>Enhancements</strong></p>
54
+ <ul>
55
+ <li>You can now pin the settings panel in restricted editing mode and when editing module templates.</li>
56
+ <li>Changed default button settings so they can be customized via the Customizer in the next theme update.</li>
57
+ <li>Added featured image support for templates in all versions.</li>
58
+ <li>Update translations.</li>
59
+ </ul>
60
+ <p><strong>Bug Fixes</strong></p>
61
+ <ul>
62
+ <li>Fixed caching issues with the iframe layout preview.</li>
63
+ </ul>
64
+
65
+ <h4>2.1-beta.4 - 04/20/2018</h4>
66
+ <p><strong>Enhancements</strong></p>
67
+ <ul>
68
+ <li>Update UI icons to use Font Awesome 5</li>
69
+ <li>New filter <code>fl_disable_notifications</code> added to disable notifications.</li>
70
+ <li>Debug info will now show htaccess content.</li>
71
+ <li>Waypoints offset added to js config.</li>
72
+ </ul>
73
+ <p><strong>Bug Fixes</strong></p>
74
+ <ul>
75
+ <li>Fixed fatal errors in GetResonse and Mailerlite api.</li>
76
+ <li>Fixed background YouTube and Vimeo videos not using fallback image.</li>
77
+ <li>Fixed AJAX shortcode issue with Ninjaforms.</li>
78
+ <li>Fixed percent not working for the preview unit.</li>
79
+ <li>Fixed contact form field connections not working when sending email because connections aren't connected when wp_ajax runs.</li>
80
+ </ul>
81
+
82
+ <h4>2.1-beta.3 - 04/06/2018</h4>
83
+ <p><strong>Bug Fixes</strong></p>
84
+ <ul>
85
+ <li>Fixed broken links on the plugins page.</li>
86
+ </ul>
87
+
88
+ <h4>2.1-beta.2 - 04/05/2018</h4>
89
+ <p><strong>Bug Fixes</strong></p>
90
+ <ul>
91
+ <li>Fixed white labeling issues.</li>
92
+ <li>Fixed usage stats admin message redirecting to the dashboard.</li>
93
+ <li>Fixed WPML translations not linking when creating new templates in wp-admin.</li>
94
+ <li>Fixed WPML issue with the builder launching for the default language instead of the current translation.</li>
95
+ </ul>
96
+
97
+ <h4>2.1-beta.1 - 04/04/2018</h4>
98
+ <p><strong>Enhancements</strong></p>
99
+ <ul>
100
+ <li>Added support for enabling Font Awesome 5 in the icon settings. Note: you can't have 4 and 5 active at the same time as they are not compatible with each other.</li>
101
+ <li>Added underline to the inline editing formatting tools.</li>
102
+ <li>Added setting to exclude the current post in the posts module.</li>
103
+ <li>Add support for rendering layout CSS and JS inline on the page instead of enqueuing using the <code>fl_builder_render_assets_inline</code> filter.</li>
104
+ </ul>
105
+ <p><strong>Bug Fixes</strong></p>
106
+ <ul>
107
+ <li>Fixed multiple issues with inline editing.</li>
108
+ <li>Fixed usage stats opt-in not working on multisite.</li>
109
+ <li>Fixed JS settings config not fully loading on some servers with response size limits.</li>
110
+ </ul>
111
+
112
+ <h4>2.1-alpha.6 - 03/13/2018</h4>
113
+ <p><strong>Enhancements</strong></p>
114
+ <ul>
115
+ <li>Added the ability to save standard and global column templates.</li>
116
+ </ul>
117
+
118
+ <h4>2.1-alpha.5 - 03/07/2018</h4>
119
+ <ul>
120
+ <li>Reworked Beaver Builder for Gutenberg block to support API changes in Gutenberg 2.3.0.</li>
121
+ <li>Updated wording in warning when switching from Beaver Builder to Gutenberg.</li>
122
+ <li>Fixed inline editing not working in Safari.</li>
123
+ </ul>
124
+
125
+ <h4>2.1-alpha.4 - 02/22/2018</h4>
126
+ <p><strong>Enhancements</strong></p>
127
+ <ul>
128
+ <li>Add title tags when present to images in various modules.</li>
129
+ <li>Added the option to show category meta to Posts module.</li>
130
+ <li>Added improved RTL support to the Posts module.</li>
131
+ <li>Added YouTube video background support for start position and looping parameters.</li>
132
+ <li>Added video field parameter for enabling the remove button.</li>
133
+ <li>Added mobile background color option to all layouts in the Menu module.</li>
134
+ <li>Added option to disable autoplay on hover to the Content Slider module.</li>
135
+ <li>Added default change callback to trigger preview refresh on fields that don't have a preview defined.</li>
136
+ <li>Disable auto play and hide the pager if there's only one slide in the Testimonials module.</li>
137
+ <li>Updated GetResponse library to version 3.</li>
138
+ </ul>
139
+ <p><strong>Bug Fixes</strong></p>
140
+ <ul>
141
+ <li>Fixed video background alignment in older browsers that require vendor prefixes for CSS transforms.</li>
142
+ <li>Fixed repeater fields not working in row and column settings.</li>
143
+ <li>Fixed submenus in the menu module's vertical layout going off the page.</li>
144
+ <li>Fixed menu module smooth scrolling issues when clicking an anchor link.</li>
145
+ <li>Fixed issues with duplicating rows that contain another row inserted via shortcode.</li>
146
+ <li>Fixed issue with inactive tabs showing when resizing the browser.</li>
147
+ <li>Fixed various issues with row and column colors overriding module text colors.</li>
148
+ <li>Fixed layout shortcode rendering on search result pages.</li>
149
+ <li>Fixed videos not playing in the content slider.</li>
150
+ </ul>
151
+
152
+ <h4>2.1-alpha.3 - 02/20/2018</h4>
153
+ <ul>
154
+ <li>Reworked Beaver Builder for Gutenberg block to support API changes in Gutenberg 2.2.0.</li>
155
+ <li>Updated opt-in usage stats with theme info.</li>
156
+ </ul>
157
+
158
+ <h4>2.1-alpha.2 - 02/16/2018</h4>
159
+ <p><strong>Bug Fixes</strong></p>
160
+ <ul>
161
+ <li>Fixed inline editing breaking when you have more than one layout on the same page.</li>
162
+ <li>Fixed white labeling issues.</li>
163
+ </ul>
164
+
165
+ <h4>2.1-alpha.1 - 02/15/2018</h4>
166
+ <p><strong>Enhancements</strong></p>
167
+ <ul>
168
+ <li>Added inline text editing to all modules (core and 3rd party) that support live text preview.</li>
169
+ <li>Added support for Gutenberg via the new Beaver Builder block.</li>
170
+ <li>Added a new user access setting for restricting all builder access for certain roles.</li>
171
+ <li>Added a notification center within the builder (disabled when white labeled).</li>
172
+ <li>Added opt-in usage tracking for things like PHP version, settings and module usage.</li>
173
+ <li>Added validation check for all code fields to prevent bad code from breaking the builder.</li>
174
+ <li>Added WPML support for global nodes.</li>
175
+ <li>Added the ability to add your license key via WP-CLI.</li>
176
+ <li>Added filtering for Theme Layouts, Templates, Saved Rows and Saved Modules on the admin list screen.</li>
177
+ <li>Added text padding options to the Content Slider module.</li>
178
+ <li>Added `fl_contact_form_from` filter to allow users to filter the from header.</li>
179
+ <li>Added logic for registering admin pointers.</li>
180
+ <li>Upgrade MailChimp API to v3.</li>
181
+ </ul>
182
+ <p><strong>Bug Fixes</strong></p>
183
+ <ul>
184
+ <li>Fixed builder not working if both Event Espresso and Beaver Themer are active.</li>
185
+ <li>Fixed Posts module columns padding going outside of the module container on mobile.</li>
186
+ <li>Fixed Posts module first page of numbered pagination missing the trailing slash in URL.</li>
187
+ <li>Fixed video background proportions by removing potential max-width styles.</li>
188
+ <li>Fixed images with captions going out of the container when reverse stacking is enabled.</li>
189
+ <li>Fixed current menu class not being applied to the menu module when inserted via shortcode.</li>
190
+ <li>Fixed RTL issues with the Posts Carousel.</li>
191
+ <li>Fixed Content Slider module top/bottom margins not working when text background height is 100%.</li>
192
+ <li>Fixed sliders not displaying properly when inserted via shortcode in Tab/Accordion modules.</li>
193
+ <li>Now using a custom sort function instead of create_function which is deprecated in php 7.2.</li>
194
+ <li>Removed WPML language switcher widget from the content panel since it requires being in a registered sidebar to work.</li>
195
+ </ul>
196
+
197
  <h4>2.0.6.4 - 03/27/2018</h4>
198
  <p><strong>Enhancements</strong></p>
199
  <ul>
200
+ <li>Added optional Terms and Conditions to Contact and Subscribe Modules to comply with GDPR.</li>
201
  </ul>
202
  <p><strong>Bug Fixes</strong></p>
203
  <ul>
217
  <li>Fixed links not being clickable in modules that use bxslider with Firefox 59.</li>
218
  <li>Fixed incorrect links in Social Buttons Module when added in Themer.</li>
219
  <li>Added <code>$id</code> and <code>$type</code> to <code>fl_builder_render_module_css_settings</code> filter variables.</li>
220
+ >>>>>>> master
221
  </ul>
222
 
223
  <h4>2.0.6.2 - 03/13/2018</h4>
429
  <li>Fixed GeneratePress Premium plugin Blog option overrules the Post modules excerpt setting.</li>
430
  </ul>
431
 
432
+ <h4>2.0.2.2 - 12/06/2017</h4>
433
  <p>Beaver Builder 2.0 is now available for remote update!</p>
434
 
435
+ <h4>2.0.2.1 - 11/27/2017</h4>
436
+ <p><strong>Bug Fixes</strong></p>
437
+ <ul>
438
+ <li>Fixed responsive editing mode not working correctly.</li>
439
+ <li>Fixed white labeling not working correctly on the updates page.</li>
440
  </ul>
441
 
442
  <h4>2.0.2 - 11/16/2017</h4>
443
+ <p><strong>Enhancements</strong></p>
444
+ <ul>
445
+ <li>Added <code>fl_builder_cache_cleared</code> action.</li>
446
+ </ul>
447
+ <p><strong>Bug Fixes</strong></p>
448
+ <ul>
449
+ <li>Fixed settings config not loading when query strings are removed from script URLs.</li>
450
+ <li>Fixed widgets not showing when site language is not in English.</li>
451
+ <li>Fixed error when using namespaced widgets.</li>
452
+ <li>Fixed JS errors in IE.</li>
453
+ <li>Fixed keyboard shortcut formatting in IE.</li>
454
+ <li>Fixed capitalization issues with translations.</li>
455
+ <li>Fixed character encoding issues with strtolower.</li>
456
+ </ul>
457
+
458
+ <h4>2.0.1.1 - 11/07/2017</h4>
459
+ <p><strong>Bug Fixes</strong></p>
460
+ <ul>
461
+ <li>Hotfix for a change in 2.0.1 that broke loading of the settings for the Subscribe Form module.</li>
462
+ </ul>
463
+
464
+ <h4>2.0.1 - 11/06/2017</h4>
465
+ <p><strong>Bug Fixes</strong></p>
466
+ <ul>
467
+ <li>Fixed errors caused by settings config not completely loading on certain server setups.</li>
468
+ <li>Fixed PHP warnings when attachment meta doesn't have a width or height set.</li>
469
+ </ul>
470
+
471
+ <h4>2.0 - 11/01/2017</h4>
472
  <p><strong>Beaver Builder 2.0 is here!</strong></p>
473
  <p>Please note that 2.0 is currently only available from your My Account page or via remote update if you already have 2.0 installed. We'll be releasing remote updates for older versions of Beaver Builder within the next few weeks.</p>
474
 
475
+ <h4>2.0-beta.3 - 10/31/2017</h4>
476
+ <p><strong>Enhancements</strong></p>
477
+ <ul>
478
+ <li>Updated the help video for 2.0.</li>
479
+ <li>Added fl_row_resize_settings filter.</li>
480
+ </ul>
481
+ <p><strong>Bug Fixes</strong></p>
482
+ <ul>
483
+ <li>Fixed various UI styling issues.</li>
484
+ <li>Fixed editing global rows not working properly.</li>
485
+ <li>Fixed template override settings not working on multisite.</li>
486
+ <li>Fixed repeater fields in nested forms not working.</li>
487
+ <li>Fixed stylesheets in the body tag not being parsed for responsive preview.</li>
488
+ <li>Fixed content panel showing during preview or unpinning during preview when not expected.</li>
489
+ <li>Fixed anchor links in the layout causing the builder to launch again after publish.</li>
490
+ </ul>
491
+
492
+ <h4>2.0-beta.2 - 10/12/2017</h4>
493
+ <p><strong>Enhancements</strong></p>
494
+ <ul>
495
+ <li>Publish button now says 'Submit for Review' if a user doesn't have permission to publish.</li>
496
+ <li>Pinned settings are now responsive for smaller devices.</li>
497
+ <li>Moved WordPress widgets into their own group.</li>
498
+ <li>Moved Themer modules into their own group (coming in Themer 1.0.3).</li>
499
+ </ul>
500
+ <p><strong>Bug Fixes</strong></p>
501
+ <ul>
502
+ <li>Fixed row actions being covered by modules when the row has no padding.</li>
503
+ <li>Fixed values in text inputs not being escaped which breaks the markup.</li>
504
+ <li>Fixed settings being dragged or resized so you can't access the drag handle anymore.</li>
505
+ <li>Fixed browser zoom triggering the action overflow menu when it shouldn't.</li>
506
+ <li>Fixed multiple issues with saving new templates.</li>
507
+ <li>Fixed styling issues with dark mode.</li>
508
+ <li>Fixed module aliases not showing in the content panel.</li>
509
+ <li>Fixed widgets not showing in the content panel.</li>
510
+ </ul>
511
+
512
+ <h4>2.0-beta.1 - 10/04/2017</h4>
513
+ <p><strong>Enhancements</strong></p>
514
+ <ul>
515
+ <li>Added keyboard shortcut UI to the builder menu.</li>
516
+ <li>Reworked keyboard shortcut system to support displaying shortcuts with labels and modifier key symbols.</li>
517
+ </ul>
518
+ <p><strong>Bug Fixes</strong></p>
519
+ <ul>
520
+ <li>Fixed various styling issues.</li>
521
+ <li>Fixed photo and video fields that aren't in node settings not showing saved data when opened again after the page is refreshed.</li>
522
+ <li>Fixed error when saving a template with no category set.</li>
523
+ <li>Fixed saved values for medium and responsive in dimension fields not showing when going back to edit a node.</li>
524
+ <li>Fixed module templates not showing in the content panel.</li>
525
+ <li>Fixed issue with module hover in the content panel being covered by siblings.</li>
526
+ <li>Fixed a major issue with secondary loops triggering the builder's content filter when they shouldn't. This caused a number of issues including an infinite loop in Themer and the incorrect posts being displayed on standard builder pages.</li>
527
+ <li>Fixed FLBuilder::render_query so it doesn't have to override $wp_query which was causing incorrect connection data for Themer layouts.</li>
528
+ </ul>
529
+
530
+ <h4>2.0-alpha.7 - 09/21/2017</h4>
531
+ <p><strong>Enhancements</strong></p>
532
+ <ul>
533
+ <li>Added the ability to match posts in the loop settings by related taxonomy terms.</li>
534
+ </ul>
535
+ <p><strong>Bug Fixes</strong></p>
536
+ <ul>
537
+ <li>Fixed page scrolling breaking when opening the main menu.</li>
538
+ <li>Fixed field connections not rendering in nested settings forms.</li>
539
+ </ul>
540
+
541
+ <h4>2.0-alpha.6.1 - 09/19/2017</h4>
542
+ <p><strong>Bug Fixes</strong></p>
543
+ <ul>
544
+ <li>Fixed a bug with the option labels in select option groups not showing.</li>
545
+ </ul>
546
+
547
+ <h4>2.0-alpha.6 - 09/19/2017</h4>
548
+ <p><strong>Bug Fixes</strong></p>
549
+ <ul>
550
+ <li>Fixed a bug breaking the Pods integration.</li>
551
+ <li>Fixed an issue causing the builder UI to break on SiteGround servers.</li>
552
+ </ul>
553
+
554
+ <h4>2.0-alpha.5 - 09/06/2017</h4>
555
+ <p><strong>Enhancements</strong></p>
556
+ <ul>
557
+ <li>Settings panel tabs no longer become a drop-down menu when slim. Tabs that cannot fit into the available space are pushed into a menu.</li>
558
+ <li>You can now move between settings tabs with the keyboard shortcuts "CMD + Left Arrow" or "CMD + Right Arrow" (CTRL on Windows).</li>
559
+ <li>You can now reset row or column widths from the module overlay.</li>
560
+ <li>"CMD + i" (CTRL on Windows) shortcut will take you directly to module search.</li>
561
+ <li>Module search is now case-insensitive.</li>
562
+ <li>Duplicated items that appear off screen will now scroll into view.</li>
563
+ </ul>
564
+ <p><strong>Bug Fixes</strong></p>
565
+ <ul>
566
+ <li>Fixed scrolling not working when hovering over the content panel and then back into the layout.</li>
567
+ <li>Hovering over the content panel should no longer cause screen jitter in Windows browsers.</li>
568
+ <li>Icon selector search/filter has been restored.</li>
569
+ <li>J, K, L, and ; keys now show content panel tabs even when the panel has been collapsed.</li>
570
+ <li>Dropping a row template into the layout immediately loads fonts.</li>
571
+ <li>Overriding core templates now works again when applying a template.<li>
572
+ <li>Fixed ACE editor resize causing incorrect cursor position.</li>
573
+ <li>Fixed multiple issues with pinning in Safari and Firefox.</li>
574
+ </ul>
575
+
576
+ <h4>2.0-alpha.4 - 08/29/2017</h4>
577
+ <ul>
578
+ <li>A new slimmer version of the settings panels now opens when clicking to edit content.</li>
579
+ <li>Settings panels can now be resized to any size that you desire.</li>
580
+ <li>We'll remember the size and position you set for the settings panels even after reloading the page.</li>
581
+ <li>The content panel and settings can now be pinned together on either the left or right side of the screen. You can resize the pinned sidebar when you need a little more room.</li>
582
+ <li>You can now work with the toolbar or in the layout even when settings are open.</li>
583
+ <li>If settings are open and you take action anywhere else in the builder, we'll save and close them for you. This means you can edit one module and click to edit another without ever needing to click save in between.</li>
584
+ <li>Module search has been moved into the modules tab for more intuitive access.</li>
585
+ </ul>
586
+
587
+ <h4>2.0-alpha.3 - 08/07/2017</h4>
588
+ <ul>
589
+ <li>Settings forms now load instantly! We've completely rewritten the settings forms in JavaScript so they don’t need to be loaded from the server anymore. The only time something needs to load is if you’re using a third party add-on that introduces legacy PHP fields. We’ll have docs on the new JavaScript settings APIs when 2.0 is released and hope that all major add-on authors will convert their fields to JavaScript so everything loads instantly! :)</li>
590
+ <li>Added an initial set of core row templates.</li>
591
+ <li>Various bug fixes and style tweaks.</li>
592
+ </ul>
593
+
594
+ <h4>2.0-alpha.2 - 07/24/2017</h4>
595
+ <ul>
596
+ <li>Added the ability to duplicate columns.</li>
597
+ <li>Increased contrast to light and dark UI modes.</li>
598
+ <li>Added module icons.</li>
599
+ <li>Restyled content group selector.</li>
600
+ <li>Reworked how group labels are displayed in search results.</li>
601
+ <li>Style hardening for GeneratePress theme.</li>
602
+ <li>Publishing out of the builder now moves the history state and updates the url. Re-entering will move back.</li>
603
+ </ul>
604
+
605
  <h4>1.11.1 11/29/17</h4>
606
  <p><strong>Hot Fix</strong></p>
607
  <ul>
793
  </ul>
794
  <p><strong>Bug Fixes</strong></p>
795
  <ul>
796
+ <li>Removed the new core media widgets from the builder since they don’t work in the builder and we have modules that do the same thing.</li>
797
+ <li>Fixed the core text widget form in the builder so the legacy form loads since the new form in 4.8 doesn’t. The text widget is also removed from the module list in favor of the Text Editor and HTML modules. Sites previously using the text widget will still render and they can still be edited, they just won’t be able to add new text widgets.</li>
798
  <li>Fixed Slideshow module not showing in the Tabs module.</li>
799
  <li>Fixed JS error in Row > Background > Slideshow on touch-enabled devices.</li>
800
  <li>Increased the video ratio to 16:9 to fix the top/bottom black border on responsive layout.</li>
944
  </ul>
945
  <p><strong>Post Module Enhancements</strong></p>
946
  <ul>
947
+ <li>Added “columns” layout to the layout setting.</li>
948
  <li>Added more layout and styling settings.</li>
949
+ <li>The “no results” message is now shown when no posts are found.</li>
950
  <li>Added a setting to show a search form if no posts are found.</li>
951
  <li>Added the ability to exclude posts in the content filter for the query.</li>
952
  </ul>
953
  <p><strong>Menu Module Enhancements</strong></p>
954
  <ul>
955
+ <li>Added “below row" option for mobile menu position.</li>
956
  <li>Added font family setting.</li>
957
  <li>Misc CSS improvements.</li>
958
  </ul>
996
  <h4>1.9.5.1 - 3/21/2017</h4>
997
  <p><strong>Bug Fixes</strong></p>
998
  <ul>
999
+ <li>Rolled back change in 1.9.5 that fixed some photos not going full width on mobile. That was causing all photos to go full width on mobile even when not intended. We’ll revisit that fix in 1.10.</li>
1000
  </ul>
1001
 
1002
  <h4>1.9.5 - 3/20/2017</h4>
2732
  <h4>0.8.2</h4>
2733
  <p>Responsive module margins now only reset if negative or greater than the default.</p>
2734
 
2735
+ <h4>0.8.1</h4>
2736
  <p>Initial beta release.</p>
classes/class-fl-builder-admin-pointers.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class that handles showing admin pointers.
5
+ *
6
+ * @since 1.10.3
7
+ */
8
+ final class FLBuilderAdminPointers {
9
+
10
+ /**
11
+ * @since 1.10.3
12
+ * @var array $pointers
13
+ */
14
+ static private $pointers = array();
15
+
16
+ /**
17
+ * Initialize.
18
+ *
19
+ * @since 1.10.3
20
+ * @return void
21
+ */
22
+ static public function init() {
23
+
24
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::enqueue_scripts' );
25
+ }
26
+
27
+ /**
28
+ * Register a pointer.
29
+ *
30
+ * @since 1.10.3
31
+ * @param array $pointer
32
+ * @return void
33
+ */
34
+ static public function register_pointer( $pointer ) {
35
+
36
+ self::$pointers[] = $pointer;
37
+ }
38
+
39
+ /**
40
+ * Enqueue scripts for showing pointers.
41
+ *
42
+ * @since 1.10.3
43
+ * @return void
44
+ */
45
+ static public function enqueue_scripts() {
46
+
47
+ $pointers = array();
48
+
49
+ foreach ( self::$pointers as $pointer ) {
50
+
51
+ if ( ! current_user_can( $pointer['cap'] ) || self::is_dismissed( $pointer['id'] ) ) {
52
+ continue;
53
+ }
54
+
55
+ $pointers[] = $pointer;
56
+ }
57
+
58
+ if ( empty( $pointers ) ) {
59
+ return;
60
+ }
61
+
62
+ wp_enqueue_style( 'wp-pointer' );
63
+ wp_enqueue_script( 'wp-pointer' );
64
+
65
+ wp_enqueue_script(
66
+ 'fl-builder-admin-pointers',
67
+ FL_BUILDER_URL . '/js/fl-builder-admin-pointers.js',
68
+ array( 'jquery', 'wp-pointer' ),
69
+ FL_BUILDER_VERSION,
70
+ true
71
+ );
72
+
73
+ wp_localize_script( 'fl-builder-admin-pointers', 'FLBuilderAdminPointersConfig', array(
74
+ 'pointers' => $pointers,
75
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
76
+ ) );
77
+ }
78
+
79
+ /**
80
+ * Check if a pointer has been dismissed by the current user.
81
+ *
82
+ * @since 1.10.3
83
+ * @param string $pointer_id
84
+ * @return bool
85
+ */
86
+ static private function is_dismissed( $pointer_id ) {
87
+
88
+ $dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
89
+
90
+ return in_array( $pointer_id, $dismissed );
91
+ }
92
+ }
93
+
94
+ FLBuilderAdminPointers::init();
classes/class-fl-builder-admin-posts.php CHANGED
@@ -23,6 +23,30 @@ final class FLBuilderAdminPosts {
23
  add_filter( 'post_row_actions', __CLASS__ . '::render_row_actions_link' );
24
  }
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  /**
27
  * Sets the body class, loads assets and renders the UI
28
  * if we are on a post type that supports the builder.
@@ -37,9 +61,8 @@ final class FLBuilderAdminPosts {
37
 
38
  $render_ui = apply_filters( 'fl_builder_render_admin_edit_ui', true );
39
  $post_types = FLBuilderModel::get_post_types();
40
- $screen = get_current_screen();
41
 
42
- if ( $render_ui && in_array( $screen->post_type, $post_types ) ) {
43
  add_filter( 'admin_body_class', __CLASS__ . '::body_class', 99 );
44
  add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
45
  add_action( 'edit_form_after_title', __CLASS__ . '::render' );
@@ -121,10 +144,10 @@ final class FLBuilderAdminPosts {
121
  if ( 'trash' != $post->post_status && current_user_can( 'edit_post', $post->ID ) && wp_check_post_lock( $post->ID ) === false ) {
122
 
123
  $is_post_editable = (bool) apply_filters( 'fl_builder_is_post_editable', true, $post );
124
-
125
  $post_types = FLBuilderModel::get_post_types();
126
 
127
- if ( in_array( $post->post_type, $post_types ) && $is_post_editable ) {
128
  $enabled = get_post_meta( $post->ID, '_fl_builder_enabled', true );
129
  $dot = ' <span style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px;">&bull;</span>';
130
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . $dot . '</a>';
@@ -143,7 +166,7 @@ final class FLBuilderAdminPosts {
143
  */
144
  static public function redirect_post_location( $location ) {
145
  if ( isset( $_POST['fl-builder-redirect'] ) ) {
146
- $location = $_POST['fl-builder-redirect'];
147
  }
148
 
149
  return $location;
23
  add_filter( 'post_row_actions', __CLASS__ . '::render_row_actions_link' );
24
  }
25
 
26
+ /**
27
+ * WordPress doesn't have a "right way" to get the current
28
+ * post type being edited and the new editor doesn't make
29
+ * this any easier. This method attempts to fix that.
30
+ *
31
+ * @since 2.1
32
+ * @return void
33
+ */
34
+ static public function get_post_type() {
35
+ global $post, $typenow, $current_screen;
36
+
37
+ if ( is_object( $post ) && $post->post_type ) {
38
+ return $post->post_type;
39
+ } elseif ( $typenow ) {
40
+ return $typenow;
41
+ } elseif ( is_object( $current_screen ) && $current_screen->post_type ) {
42
+ return $current_screen->post_type;
43
+ } elseif ( isset( $_REQUEST['post_type'] ) ) {
44
+ return sanitize_key( $_REQUEST['post_type'] );
45
+ }
46
+
47
+ return null;
48
+ }
49
+
50
  /**
51
  * Sets the body class, loads assets and renders the UI
52
  * if we are on a post type that supports the builder.
61
 
62
  $render_ui = apply_filters( 'fl_builder_render_admin_edit_ui', true );
63
  $post_types = FLBuilderModel::get_post_types();
 
64
 
65
+ if ( $render_ui && in_array( self::get_post_type(), $post_types ) ) {
66
  add_filter( 'admin_body_class', __CLASS__ . '::body_class', 99 );
67
  add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
68
  add_action( 'edit_form_after_title', __CLASS__ . '::render' );
144
  if ( 'trash' != $post->post_status && current_user_can( 'edit_post', $post->ID ) && wp_check_post_lock( $post->ID ) === false ) {
145
 
146
  $is_post_editable = (bool) apply_filters( 'fl_builder_is_post_editable', true, $post );
147
+ $user_access = FLBuilderUserAccess::current_user_can( 'builder_access' );
148
  $post_types = FLBuilderModel::get_post_types();
149
 
150
+ if ( in_array( $post->post_type, $post_types ) && $is_post_editable && $user_access ) {
151
  $enabled = get_post_meta( $post->ID, '_fl_builder_enabled', true );
152
  $dot = ' <span style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px;">&bull;</span>';
153
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . $dot . '</a>';
166
  */
167
  static public function redirect_post_location( $location ) {
168
  if ( isset( $_POST['fl-builder-redirect'] ) ) {
169
+ $location = FLBuilderModel::get_edit_url( absint( $_POST['fl-builder-redirect'] ) );
170
  }
171
 
172
  return $location;
classes/class-fl-builder-admin-settings.php CHANGED
@@ -155,7 +155,7 @@ final class FLBuilderAdminSettings {
155
  $item_data = apply_filters( 'fl_builder_admin_settings_nav_items', array(
156
  'welcome' => array(
157
  'title' => __( 'Welcome', 'fl-builder' ),
158
- 'show' => FLBuilderModel::get_branding() == __( 'Page Builder', 'fl-builder' ) && ( is_network_admin() || ! self::multisite_support() ),
159
  'priority' => 50,
160
  ),
161
  'license' => array(
@@ -219,7 +219,7 @@ final class FLBuilderAdminSettings {
219
  */
220
  static public function render_forms() {
221
  // Welcome
222
- if ( FLBuilderModel::get_branding() == __( 'Page Builder', 'fl-builder' ) && ( is_network_admin() || ! self::multisite_support() ) ) {
223
  self::render_form( 'welcome' );
224
  }
225
 
@@ -421,6 +421,12 @@ final class FLBuilderAdminSettings {
421
  $enabled_icons = array_map( 'sanitize_text_field', $_POST['fl-enabled-icons'] );
422
  }
423
 
 
 
 
 
 
 
424
  // Update the enabled sets.
425
  self::update_enabled_icons( $enabled_icons );
426
 
@@ -507,11 +513,11 @@ final class FLBuilderAdminSettings {
507
  $key = FLBuilderIcons::get_key_from_path( $new_path );
508
  $enabled_icons[] = $key;
509
  }
510
- }// End if().
511
 
512
  // Update the enabled sets again in case they have changed.
513
  self::update_enabled_icons( $enabled_icons );
514
- }// End if().
515
  }
516
 
517
  /**
155
  $item_data = apply_filters( 'fl_builder_admin_settings_nav_items', array(
156
  'welcome' => array(
157
  'title' => __( 'Welcome', 'fl-builder' ),
158
+ 'show' => ! FLBuilderModel::is_white_labeled() && ( is_network_admin() || ! self::multisite_support() ),
159
  'priority' => 50,
160
  ),
161
  'license' => array(
219
  */
220
  static public function render_forms() {
221
  // Welcome
222
+ if ( ! FLBuilderModel::is_white_labeled() && ( is_network_admin() || ! self::multisite_support() ) ) {
223
  self::render_form( 'welcome' );
224
  }
225
 
421
  $enabled_icons = array_map( 'sanitize_text_field', $_POST['fl-enabled-icons'] );
422
  }
423
 
424
+ // we cant have fa4 and fa5 active at same time.
425
+ if ( in_array( 'font-awesome', $enabled_icons ) && (bool) array_intersect( array( 'font-awesome-5-brands', 'font-awesome-5-regular', 'font-awesome-5-solid' ), $enabled_icons ) ) {
426
+ self::add_error( __( 'Use either Font Awesome 4 or Font Awesome 5. They are not compatible. Modules already in use will continue to use Font Awesome 4 regardless of your choice here.', 'fl-builder' ) );
427
+ return;
428
+ }
429
+
430
  // Update the enabled sets.
431
  self::update_enabled_icons( $enabled_icons );
432
 
513
  $key = FLBuilderIcons::get_key_from_path( $new_path );
514
  $enabled_icons[] = $key;
515
  }
516
+ }
517
 
518
  // Update the enabled sets again in case they have changed.
519
  self::update_enabled_icons( $enabled_icons );
520
+ }
521
  }
522
 
523
  /**
classes/class-fl-builder-ajax-layout.php CHANGED
@@ -53,7 +53,7 @@ final class FLBuilderAJAXLayout {
53
  do_action( 'fl_builder_after_render_ajax_layout' );
54
 
55
  // Return the response.
56
- return array(
57
  'partial' => $partial_refresh_data['is_partial_refresh'],
58
  'nodeId' => $partial_refresh_data['node_id'],
59
  'nodeType' => $partial_refresh_data['node_type'],
@@ -62,7 +62,7 @@ final class FLBuilderAJAXLayout {
62
  'scriptsStyles' => $scripts_styles,
63
  'css' => $assets['css'],
64
  'js' => $assets['js'],
65
- );
66
  }
67
 
68
  /**
@@ -91,8 +91,7 @@ final class FLBuilderAJAXLayout {
91
  'layout' => self::render( $row->node ),
92
  'config' => FLBuilderUISettingsForms::get_node_js_config(),
93
  );
94
- } // End if().
95
- else {
96
 
97
  // Add the row.
98
  $row = FLBuilderModel::add_row( $cols, $position );
@@ -180,6 +179,44 @@ final class FLBuilderAJAXLayout {
180
  return self::render( $group->node );
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  /**
184
  * Renders the layout data for a copied column.
185
  *
@@ -217,8 +254,7 @@ final class FLBuilderAJAXLayout {
217
  } else {
218
  $module = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position );
219
  }
220
- } // End if().
221
- else {
222
  $defaults = FLBuilderModel::get_module_alias_settings( $alias );
223
  $module = FLBuilderModel::add_default_module( $parent_id, $type, $position, $defaults );
224
  }
@@ -297,8 +333,7 @@ final class FLBuilderAJAXLayout {
297
  $node = FLBuilderModel::get_module( $node_id );
298
  $node_type = 'module';
299
  $partial_refresh = $node->partial_refresh;
300
- } // End if().
301
- elseif ( $node ) {
302
  $node_type = $node->type;
303
  $partial_refresh = self::node_modules_support_partial_refresh( $node );
304
  }
@@ -315,7 +350,7 @@ final class FLBuilderAJAXLayout {
315
  'node' => $node,
316
  'node_type' => $node_type,
317
  );
318
- }// End if().
319
 
320
  // Return the data.
321
  return self::$partial_refresh_data;
@@ -371,7 +406,7 @@ final class FLBuilderAJAXLayout {
371
  }
372
  }
373
  }
374
- }// End if().
375
 
376
  return true;
377
  }
@@ -413,8 +448,7 @@ final class FLBuilderAJAXLayout {
413
  FLBuilder::render_module( $partial_refresh_data['node'] );
414
  break;
415
  }
416
- } // End if().
417
- else {
418
  FLBuilder::render_nodes();
419
  }
420
 
@@ -489,7 +523,7 @@ final class FLBuilderAJAXLayout {
489
  } else {
490
  FLBuilder::render_js();
491
  $assets['js'] = $asset_info['js_url'] . '?ver=' . $asset_ver;
492
- }// End if().
493
 
494
  // Render the CSS.
495
  FLBuilder::render_css();
53
  do_action( 'fl_builder_after_render_ajax_layout' );
54
 
55
  // Return the response.
56
+ return apply_filters( 'fl_builder_ajax_layout_response', array(
57
  'partial' => $partial_refresh_data['is_partial_refresh'],
58
  'nodeId' => $partial_refresh_data['node_id'],
59
  'nodeType' => $partial_refresh_data['node_type'],
62
  'scriptsStyles' => $scripts_styles,
63
  'css' => $assets['css'],
64
  'js' => $assets['js'],
65
+ ) );
66
  }
67
 
68
  /**
91
  'layout' => self::render( $row->node ),
92
  'config' => FLBuilderUISettingsForms::get_node_js_config(),
93
  );
94
+ } else {
 
95
 
96
  // Add the row.
97
  $row = FLBuilderModel::add_row( $cols, $position );
179
  return self::render( $group->node );
180
  }
181
 
182
+ /**
183
+ * Renders a new column template.
184
+ *
185
+ * @since 2.1
186
+ * @param string $template_id The ID of a column template to render.
187
+ * @param string $parent_id A column node ID.
188
+ * @param int $position The new column position.
189
+ * @param string $template_type The type of template. Either "user" or "core".
190
+ * @return array
191
+ */
192
+ static public function render_new_col_template( $template_id, $parent_id = null, $position = false, $template_type = 'user' ) {
193
+ if ( 'core' == $template_type ) {
194
+ $template = FLBuilderModel::get_template( $template_id, 'column' );
195
+ $column = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position, $template );
196
+ } else {
197
+ $column = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position );
198
+ }
199
+
200
+ // Get the new column parent.
201
+ $parent = ! $parent_id ? null : FLBuilderModel::get_node( $parent_id );
202
+
203
+ // Get the node to render.
204
+ if ( ! $parent ) {
205
+ $row = FLBuilderModel::get_col_parent( 'row', $column );
206
+ $render_id = $row->node;
207
+ } elseif ( 'row' == $parent->type ) {
208
+ $group = FLBuilderModel::get_col_parent( 'column-group', $column );
209
+ $render_id = $group->node;
210
+ } elseif ( 'column-group' == $parent->type ) {
211
+ $render_id = $parent->node;
212
+ } else {
213
+ $render_id = $column->node;
214
+ }
215
+
216
+ // Return the response.
217
+ return self::render( $render_id );
218
+ }
219
+
220
  /**
221
  * Renders the layout data for a copied column.
222
  *
254
  } else {
255
  $module = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position );
256
  }
257
+ } else {
 
258
  $defaults = FLBuilderModel::get_module_alias_settings( $alias );
259
  $module = FLBuilderModel::add_default_module( $parent_id, $type, $position, $defaults );
260
  }
333
  $node = FLBuilderModel::get_module( $node_id );
334
  $node_type = 'module';
335
  $partial_refresh = $node->partial_refresh;
336
+ } elseif ( $node ) {
 
337
  $node_type = $node->type;
338
  $partial_refresh = self::node_modules_support_partial_refresh( $node );
339
  }
350
  'node' => $node,
351
  'node_type' => $node_type,
352
  );
353
+ }
354
 
355
  // Return the data.
356
  return self::$partial_refresh_data;
406
  }
407
  }
408
  }
409
+ }
410
 
411
  return true;
412
  }
448
  FLBuilder::render_module( $partial_refresh_data['node'] );
449
  break;
450
  }
451
+ } else {
 
452
  FLBuilder::render_nodes();
453
  }
454
 
523
  } else {
524
  FLBuilder::render_js();
525
  $assets['js'] = $asset_info['js_url'] . '?ver=' . $asset_ver;
526
+ }
527
 
528
  // Render the CSS.
529
  FLBuilder::render_css();
classes/class-fl-builder-ajax.php CHANGED
@@ -113,6 +113,7 @@ final class FLBuilderAJAX {
113
  self::add_action( 'copy_row', 'FLBuilderAJAXLayout::copy_row', array( 'node_id', 'settings', 'settings_id' ) );
114
  self::add_action( 'render_new_column_group', 'FLBuilderAJAXLayout::render_new_column_group', array( 'node_id', 'cols', 'position' ) );
115
  self::add_action( 'render_new_columns', 'FLBuilderAJAXLayout::render_new_columns', array( 'node_id', 'insert', 'type', 'nested' ) );
 
116
  self::add_action( 'copy_col', 'FLBuilderAJAXLayout::copy_col', array( 'node_id', 'settings', 'settings_id' ) );
117
  self::add_action( 'render_new_module', 'FLBuilderAJAXLayout::render_new_module', array( 'parent_id', 'position', 'type', 'alias', 'template_id', 'template_type' ) );
118
  self::add_action( 'copy_module', 'FLBuilderAJAXLayout::copy_module', array( 'node_id', 'settings' ) );
113
  self::add_action( 'copy_row', 'FLBuilderAJAXLayout::copy_row', array( 'node_id', 'settings', 'settings_id' ) );
114
  self::add_action( 'render_new_column_group', 'FLBuilderAJAXLayout::render_new_column_group', array( 'node_id', 'cols', 'position' ) );
115
  self::add_action( 'render_new_columns', 'FLBuilderAJAXLayout::render_new_columns', array( 'node_id', 'insert', 'type', 'nested' ) );
116
+ self::add_action( 'render_new_col_template', 'FLBuilderAJAXLayout::render_new_col_template', array( 'template_id', 'parent_id', 'position', 'template_type' ) );
117
  self::add_action( 'copy_col', 'FLBuilderAJAXLayout::copy_col', array( 'node_id', 'settings', 'settings_id' ) );
118
  self::add_action( 'render_new_module', 'FLBuilderAJAXLayout::render_new_module', array( 'parent_id', 'position', 'type', 'alias', 'template_id', 'template_type' ) );
119
  self::add_action( 'copy_module', 'FLBuilderAJAXLayout::copy_module', array( 'node_id', 'settings' ) );
classes/class-fl-builder-debug.php CHANGED
@@ -6,8 +6,7 @@ final class FL_Debug {
6
 
7
  public static function init() {
8
  if ( isset( $_GET['fldebug'] ) && get_option( 'fl_debug_mode', false ) === $_GET['fldebug'] ) {
9
- self::prepare_tests();
10
- self::display_tests();
11
  }
12
 
13
  if ( get_option( 'fl_debug_mode', false ) ) {
@@ -21,7 +20,9 @@ final class FL_Debug {
21
  @error_reporting( E_ALL ); // @codingStandardsIgnoreLine
22
  }
23
 
24
- private static function display_tests() {
 
 
25
 
26
  header( 'Content-Type:text/plain' );
27
 
@@ -337,7 +338,7 @@ final class FL_Debug {
337
  );
338
  self::register( 'bb_sub_lite', $args );
339
 
340
- } else {
341
  $subscription = FLUpdater::get_subscription_info();
342
  $args = array(
343
  'name' => 'Beaver Builder License',
@@ -379,6 +380,38 @@ final class FL_Debug {
379
  'data' => $_SERVER['SERVER_SOFTWARE'],
380
  );
381
  self::register( 'server', $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
  }
383
  }
384
  add_action( 'plugins_loaded', array( 'FL_Debug', 'init' ) );
6
 
7
  public static function init() {
8
  if ( isset( $_GET['fldebug'] ) && get_option( 'fl_debug_mode', false ) === $_GET['fldebug'] ) {
9
+ add_action( 'init', array( 'FL_Debug', 'display_tests' ) );
 
10
  }
11
 
12
  if ( get_option( 'fl_debug_mode', false ) ) {
20
  @error_reporting( E_ALL ); // @codingStandardsIgnoreLine
21
  }
22
 
23
+ public static function display_tests() {
24
+
25
+ self::prepare_tests();
26
 
27
  header( 'Content-Type:text/plain' );
28
 
338
  );
339
  self::register( 'bb_sub_lite', $args );
340
 
341
+ } elseif ( class_exists( 'FLUpdater' ) ) {
342
  $subscription = FLUpdater::get_subscription_info();
343
  $args = array(
344
  'name' => 'Beaver Builder License',
380
  'data' => $_SERVER['SERVER_SOFTWARE'],
381
  );
382
  self::register( 'server', $args );
383
+
384
+ $args = array(
385
+ 'name' => 'htaccess files',
386
+ 'data' => self::divider(),
387
+ );
388
+ self::register( 'up_htaccess', $args );
389
+
390
+ // detect uploads folder .htaccess file and display it if found.
391
+ $uploads = wp_upload_dir();
392
+ $uploads_htaccess = trailingslashit( $uploads['basedir'] ) . '.htaccess';
393
+ $root_htaccess = trailingslashit( ABSPATH ) . '.htaccess';
394
+
395
+ if ( file_exists( $root_htaccess ) ) {
396
+ ob_start();
397
+ readfile( $root_htaccess );
398
+ $htaccess = ob_get_clean();
399
+ $args = array(
400
+ 'name' => $root_htaccess . "\n",
401
+ 'data' => $htaccess,
402
+ );
403
+ self::register( 'up_htaccess_root', $args );
404
+ }
405
+ if ( file_exists( $uploads_htaccess ) ) {
406
+ ob_start();
407
+ readfile( $uploads_htaccess );
408
+ $htaccess = ob_get_clean();
409
+ $args = array(
410
+ 'name' => $uploads_htaccess . "\n",
411
+ 'data' => $htaccess,
412
+ );
413
+ self::register( 'up_htaccess_uploads', $args );
414
+ }
415
  }
416
  }
417
  add_action( 'plugins_loaded', array( 'FL_Debug', 'init' ) );
classes/class-fl-builder-filesystem.php CHANGED
@@ -9,7 +9,8 @@ class FL_Filesystem {
9
 
10
  public static function instance() {
11
  if ( is_null( self::$_instance ) ) {
12
- self::$_instance = new self();
 
13
  }
14
  return self::$_instance;
15
  }
@@ -98,7 +99,8 @@ class FL_Filesystem {
98
  * @since 2.0.6
99
  */
100
  function file_exists( $path ) {
101
- return file_exists( $path );
 
102
  }
103
 
104
  /**
@@ -106,7 +108,8 @@ class FL_Filesystem {
106
  * @since 2.0.6
107
  */
108
  function filesize( $path ) {
109
- return filesize( $path );
 
110
  }
111
 
112
  /**
@@ -131,6 +134,14 @@ class FL_Filesystem {
131
  remove_filter( 'request_filesystem_credentials', array( $this, 'FLBuilderUtils::request_filesystem_credentials' ) );
132
  }
133
 
 
 
 
 
 
 
 
 
134
  return $wp_filesystem;
135
  }
136
 
9
 
10
  public static function instance() {
11
  if ( is_null( self::$_instance ) ) {
12
+ $filtered = apply_filters( 'fl_filesystem_instance', null );
13
+ self::$_instance = $filtered instanceof FL_Filesystem ? $filtered : new self();
14
  }
15
  return self::$_instance;
16
  }
99
  * @since 2.0.6
100
  */
101
  function file_exists( $path ) {
102
+ $wp_filesystem = $this->get_filesystem();
103
+ return $wp_filesystem->exists( $path );
104
  }
105
 
106
  /**
108
  * @since 2.0.6
109
  */
110
  function filesize( $path ) {
111
+ $wp_filesystem = $this->get_filesystem();
112
+ return $wp_filesystem->size( $path );
113
  }
114
 
115
  /**
134
  remove_filter( 'request_filesystem_credentials', array( $this, 'FLBuilderUtils::request_filesystem_credentials' ) );
135
  }
136
 
137
+ // Set the permission constants if not already set.
138
+ if ( ! defined( 'FS_CHMOD_DIR' ) ) {
139
+ define( 'FS_CHMOD_DIR', 0755 );
140
+ }
141
+ if ( ! defined( 'FS_CHMOD_FILE' ) ) {
142
+ define( 'FS_CHMOD_FILE', 0644 );
143
+ }
144
+
145
  return $wp_filesystem;
146
  }
147
 
classes/class-fl-builder-fonts.php CHANGED
@@ -319,9 +319,9 @@ final class FLBuilderFonts {
319
  }
320
  }
321
  }
322
- }// End if().
323
- }// End if().
324
- }// End foreach().
325
 
326
  // Start combining all enqueued google fonts
327
  if ( count( $enqueued_google_fonts ) > 0 ) {
@@ -355,7 +355,7 @@ final class FLBuilderFonts {
355
  $enqueued_google_fonts = array();
356
  }
357
  }
358
- }// End if().
359
  }
360
 
361
  }
319
  }
320
  }
321
  }
322
+ }
323
+ }
324
+ }
325
 
326
  // Start combining all enqueued google fonts
327
  if ( count( $enqueued_google_fonts ) > 0 ) {
355
  $enqueued_google_fonts = array();
356
  }
357
  }
358
+ }
359
  }
360
 
361
  }
classes/class-fl-builder-icons.php CHANGED
@@ -128,9 +128,25 @@ final class FLBuilderIcons {
128
  $enabled_icons = FLBuilderModel::get_enabled_icons();
129
  $core_sets = apply_filters( 'fl_builder_core_icon_sets', array(
130
  'font-awesome' => array(
131
- 'name' => 'Font Awesome',
132
  'prefix' => 'fa',
133
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  'foundation-icons' => array(
135
  'name' => 'Foundation Icons',
136
  'prefix' => '',
@@ -141,6 +157,10 @@ final class FLBuilderIcons {
141
  ),
142
  ) );
143
 
 
 
 
 
144
  // Add the core sets.
145
  foreach ( $core_sets as $set_key => $set_data ) {
146
  if ( is_admin() || in_array( $set_key, $enabled_icons ) ) {
@@ -160,7 +180,26 @@ final class FLBuilderIcons {
160
  // Loop through core sets and add icons.
161
  foreach ( self::$sets as $set_key => $set_data ) {
162
  if ( 'core' == $set_data['type'] ) {
163
- $config_path = apply_filters( 'fl_builder_core_icon_set_config', FL_BUILDER_DIR . 'json/' . $set_key . '.json', $set_data );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
  $icons = json_decode( file_get_contents( $config_path ) );
166
  self::$sets[ $set_key ]['icons'] = $icons;
@@ -233,8 +272,7 @@ final class FLBuilderIcons {
233
  }
234
  }
235
  }
236
- } // End if().
237
- elseif ( fl_builder_filesystem()->file_exists( $folder . 'config.json' ) ) {
238
 
239
  $data = json_decode( fl_builder_filesystem()->file_get_contents( $folder . 'config.json' ) );
240
  $key = basename( $folder );
@@ -275,7 +313,7 @@ final class FLBuilderIcons {
275
  }
276
  }
277
  }
278
- }// End foreach().
279
  }
280
 
281
  /**
@@ -287,7 +325,7 @@ final class FLBuilderIcons {
287
  static public function enqueue_all_custom_icons_styles() {
288
  $sets = self::get_sets();
289
 
290
- foreach ( $sets as $key => $data ) {
291
 
292
  // Don't enqueue core icons.
293
  if ( 'core' == $data['type'] ) {
@@ -357,14 +395,15 @@ final class FLBuilderIcons {
357
  do_action( 'fl_builder_enqueue_styles_for_icon', $icon );
358
 
359
  // Is this a core icon?
360
- if ( stristr( $icon, 'fa-' ) ) {
361
  wp_enqueue_style( 'font-awesome' );
 
 
362
  } elseif ( stristr( $icon, 'fi-' ) ) {
363
  wp_enqueue_style( 'foundation-icons' );
364
  } elseif ( stristr( $icon, 'dashicon' ) ) {
365
  wp_enqueue_style( 'dashicons' );
366
- } // End if().
367
- else {
368
 
369
  $sets = self::get_sets();
370
 
128
  $enabled_icons = FLBuilderModel::get_enabled_icons();
129
  $core_sets = apply_filters( 'fl_builder_core_icon_sets', array(
130
  'font-awesome' => array(
131
+ 'name' => 'Font Awesome 4',
132
  'prefix' => 'fa',
133
  ),
134
+ 'font-awesome-5-solid' => array(
135
+ 'name' => 'Font Awesome 5 Solid',
136
+ 'prefix' => 'fas',
137
+ ),
138
+ 'font-awesome-5-regular' => array(
139
+ 'name' => 'Font Awesome 5 Regular',
140
+ 'prefix' => 'far',
141
+ ),
142
+ 'font-awesome-5-light' => array(
143
+ 'name' => 'Font Awesome 5 Light (pro only)',
144
+ 'prefix' => 'fal',
145
+ ),
146
+ 'font-awesome-5-brands' => array(
147
+ 'name' => 'Font Awesome 5 Brands',
148
+ 'prefix' => 'fab',
149
+ ),
150
  'foundation-icons' => array(
151
  'name' => 'Foundation Icons',
152
  'prefix' => '',
157
  ),
158
  ) );
159
 
160
+ if ( ! apply_filters( 'fl_enable_fa5_pro', false ) ) {
161
+ unset( $core_sets['font-awesome-5-light'] );
162
+ }
163
+
164
  // Add the core sets.
165
  foreach ( $core_sets as $set_key => $set_data ) {
166
  if ( is_admin() || in_array( $set_key, $enabled_icons ) ) {
180
  // Loop through core sets and add icons.
181
  foreach ( self::$sets as $set_key => $set_data ) {
182
  if ( 'core' == $set_data['type'] ) {
183
+
184
+ $key = $set_key;
185
+
186
+ if ( apply_filters( 'fl_enable_fa5_pro', false ) ) {
187
+ switch ( $set_key ) {
188
+ case 'font-awesome-5-light' :
189
+ $key = 'font-awesome-5-light-pro';
190
+ break;
191
+
192
+ case 'font-awesome-5-regular' :
193
+ $key = 'font-awesome-5-regular-pro';
194
+ break;
195
+
196
+ case 'font-awesome-5-solid' :
197
+ $key = 'font-awesome-5-solid-pro';
198
+ break;
199
+ }
200
+ }
201
+
202
+ $config_path = apply_filters( 'fl_builder_core_icon_set_config', FL_BUILDER_DIR . 'json/' . $key . '.json', $set_data );
203
 
204
  $icons = json_decode( file_get_contents( $config_path ) );
205
  self::$sets[ $set_key ]['icons'] = $icons;
272
  }
273
  }
274
  }
275
+ } elseif ( fl_builder_filesystem()->file_exists( $folder . 'config.json' ) ) {
 
276
 
277
  $data = json_decode( fl_builder_filesystem()->file_get_contents( $folder . 'config.json' ) );
278
  $key = basename( $folder );
313
  }
314
  }
315
  }
316
+ }
317
  }
318
 
319
  /**
325
  static public function enqueue_all_custom_icons_styles() {
326
  $sets = self::get_sets();
327
 
328
+ foreach ( (array) $sets as $key => $data ) {
329
 
330
  // Don't enqueue core icons.
331
  if ( 'core' == $data['type'] ) {
395
  do_action( 'fl_builder_enqueue_styles_for_icon', $icon );
396
 
397
  // Is this a core icon?
398
+ if ( stristr( $icon, 'fa fa-' ) ) {
399
  wp_enqueue_style( 'font-awesome' );
400
+ } elseif ( stristr( $icon, 'far fa-' ) || stristr( $icon, 'fas fa-' ) || stristr( $icon, 'fab fa-' ) || stristr( $icon, 'fal fa-' ) ) {
401
+ wp_enqueue_style( 'font-awesome-5' );
402
  } elseif ( stristr( $icon, 'fi-' ) ) {
403
  wp_enqueue_style( 'foundation-icons' );
404
  } elseif ( stristr( $icon, 'dashicon' ) ) {
405
  wp_enqueue_style( 'dashicons' );
406
+ } else {
 
407
 
408
  $sets = self::get_sets();
409
 
classes/class-fl-builder-iframe-preview.php CHANGED
@@ -8,13 +8,23 @@
8
  final class FLBuilderIframePreview {
9
 
10
  /**
11
- * Initialize hooks.
12
  *
13
  * @since 2.0.6
14
  * @return void
15
  */
16
  static public function init() {
17
- if ( ! isset( $_GET['fl_builder_preview'] ) ) {
 
 
 
 
 
 
 
 
 
 
18
  return;
19
  }
20
 
8
  final class FLBuilderIframePreview {
9
 
10
  /**
11
+ * Initialize on plugins loaded.
12
  *
13
  * @since 2.0.6
14
  * @return void
15
  */
16
  static public function init() {
17
+ add_action( 'plugins_loaded', __CLASS__ . '::hook' );
18
+ }
19
+
20
+ /**
21
+ * Setup hooks.
22
+ *
23
+ * @since 2.1
24
+ * @return void
25
+ */
26
+ static public function hook() {
27
+ if ( ! FLBuilderModel::is_builder_draft_preview() ) {
28
  return;
29
  }
30
 
classes/class-fl-builder-importer.php CHANGED
@@ -98,7 +98,7 @@ class FLBuilderImportParserRegex extends WXR_Parser_Regex {
98
  if ( $in_post ) {
99
  $post .= $importline;
100
  }
101
- }// End while().
102
 
103
  $this->fclose( $fp );
104
 
@@ -113,7 +113,7 @@ class FLBuilderImportParserRegex extends WXR_Parser_Regex {
113
  }
114
  }
115
  }
116
- }// End if().
117
 
118
  if ( ! $wxr_version ) {
119
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'fl-builder' ) );
98
  if ( $in_post ) {
99
  $post .= $importline;
100
  }
101
+ }
102
 
103
  $this->fclose( $fp );
104
 
113
  }
114
  }
115
  }
116
+ }
117
 
118
  if ( ! $wxr_version ) {
119
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'fl-builder' ) );
classes/class-fl-builder-loader.php CHANGED
@@ -46,7 +46,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
46
  * @return void
47
  */
48
  static private function define_constants() {
49
- define( 'FL_BUILDER_VERSION', '2.0.6.4' );
50
  define( 'FL_BUILDER_FILE', trailingslashit( dirname( dirname( __FILE__ ) ) ) . 'fl-builder.php' );
51
  define( 'FL_BUILDER_DIR', plugin_dir_path( FL_BUILDER_FILE ) );
52
  define( 'FL_BUILDER_URL', plugins_url( '/', FL_BUILDER_FILE ) );
@@ -70,6 +70,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
70
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-filesystem.php';
71
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder.php';
72
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin.php';
 
73
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-posts.php';
74
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-settings.php';
75
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ajax.php';
@@ -80,6 +81,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
80
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-extensions.php';
81
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-fonts.php';
82
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-debug.php';
 
83
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-icons.php';
84
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-iframe-preview.php';
85
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-import.php';
@@ -93,6 +95,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
93
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-timezones.php';
94
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ui-content-panel.php';
95
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ui-settings-forms.php';
 
96
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-update.php';
97
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-user-access.php';
98
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-user-settings.php';
@@ -101,12 +104,19 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
101
 
102
  /* WP CLI Commands */
103
  if ( defined( 'WP_CLI' ) ) {
104
- require __DIR__ . '/class-fl-builder-wpcli-command.php';
105
  }
106
 
 
 
 
107
  /* Includes */
108
  require_once FL_BUILDER_DIR . 'includes/compatibility.php';
109
- require_once FL_BUILDER_DIR . 'includes/updater/updater.php';
 
 
 
 
110
  }
111
 
112
  /**
@@ -178,6 +188,6 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
178
  echo '</div>';
179
  }
180
  }
181
- }// End if().
182
 
183
  FLBuilderLoader::init();
46
  * @return void
47
  */
48
  static private function define_constants() {
49
+ define( 'FL_BUILDER_VERSION', '2.1.1.2' );
50
  define( 'FL_BUILDER_FILE', trailingslashit( dirname( dirname( __FILE__ ) ) ) . 'fl-builder.php' );
51
  define( 'FL_BUILDER_DIR', plugin_dir_path( FL_BUILDER_FILE ) );
52
  define( 'FL_BUILDER_URL', plugins_url( '/', FL_BUILDER_FILE ) );
70
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-filesystem.php';
71
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder.php';
72
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin.php';
73
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-pointers.php';
74
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-posts.php';
75
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin-settings.php';
76
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ajax.php';
81
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-extensions.php';
82
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-fonts.php';
83
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-debug.php';
84
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-usage.php';
85
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-icons.php';
86
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-iframe-preview.php';
87
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-import.php';
95
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-timezones.php';
96
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ui-content-panel.php';
97
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-ui-settings-forms.php';
98
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-notifications.php';
99
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-update.php';
100
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-user-access.php';
101
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-user-settings.php';
104
 
105
  /* WP CLI Commands */
106
  if ( defined( 'WP_CLI' ) ) {
107
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-wpcli-command.php';
108
  }
109
 
110
+ /* WP Blocks Support */
111
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-wp-blocks.php';
112
+
113
  /* Includes */
114
  require_once FL_BUILDER_DIR . 'includes/compatibility.php';
115
+
116
+ /* Updater */
117
+ if ( file_exists( FL_BUILDER_DIR . 'includes/updater/updater.php' ) ) {
118
+ require_once FL_BUILDER_DIR . 'includes/updater/updater.php';
119
+ }
120
  }
121
 
122
  /**
188
  echo '</div>';
189
  }
190
  }
191
+ }
192
 
193
  FLBuilderLoader::init();
classes/class-fl-builder-loop.php CHANGED
@@ -140,12 +140,17 @@ final class FLBuilderLoop {
140
  * @return object A WP_Query instance.
141
  */
142
  static public function custom_query( $settings ) {
 
143
  $posts_per_page = empty( $settings->posts_per_page ) ? 10 : $settings->posts_per_page;
144
- $post_type = empty( $settings->post_type ) ? 'post' : $settings->post_type;
145
- $order_by = empty( $settings->order_by ) ? 'date' : $settings->order_by;
146
- $order = empty( $settings->order ) ? 'DESC' : $settings->order;
147
- $users = empty( $settings->users ) ? '' : $settings->users;
148
- $fields = empty( $settings->fields ) ? '' : $settings->fields;
 
 
 
 
149
 
150
  $paged = self::get_paged();
151
 
@@ -271,7 +276,7 @@ final class FLBuilderLoop {
271
  $term_ids = $related;
272
  }
273
  }
274
- }// End if().
275
 
276
  if ( ! empty( $term_ids ) ) {
277
 
@@ -282,7 +287,7 @@ final class FLBuilderLoop {
282
  'operator' => $operator,
283
  );
284
  }
285
- }// End foreach().
286
 
287
  // Post in/not in query.
288
  if ( isset( $settings->{'posts_' . $post_type} ) ) {
@@ -303,6 +308,10 @@ final class FLBuilderLoop {
303
  }
304
  }
305
 
 
 
 
 
306
  $args = apply_filters( 'fl_builder_loop_query_args', $args );
307
 
308
  // Build the query.
@@ -695,7 +704,7 @@ final class FLBuilderLoop {
695
  $total_pages = $query->max_num_pages;
696
  $permalink_structure = get_option( 'permalink_structure' );
697
  $paged = self::get_paged();
698
- $base = untrailingslashit( html_entity_decode( get_pagenum_link() ) );
699
 
700
  if ( $total_pages > 1 ) {
701
 
@@ -773,8 +782,12 @@ final class FLBuilderLoop {
773
  $base = strtok( $base, '?' );
774
  }
775
 
776
- $base = untrailingslashit( $base );
777
-
 
 
 
 
778
  } else {
779
  $url_params = wp_parse_url( $base, PHP_URL_QUERY );
780
 
@@ -802,7 +815,8 @@ final class FLBuilderLoop {
802
  }
803
 
804
  if ( ! empty( $permalink_structure ) ) {
805
- $format = ! empty( $page_prefix ) ? '/' . $page_prefix . '/' : '/';
 
806
  $format .= '%#%';
807
  $format .= substr( $permalink_structure, -1 ) == '/' ? '/' : '';
808
  } elseif ( empty( $permalink_structure ) || is_search() ) {
140
  * @return object A WP_Query instance.
141
  */
142
  static public function custom_query( $settings ) {
143
+ global $post;
144
  $posts_per_page = empty( $settings->posts_per_page ) ? 10 : $settings->posts_per_page;
145
+ $post_type = empty( $settings->post_type ) ? 'post' : $settings->post_type;
146
+ $order_by = empty( $settings->order_by ) ? 'date' : $settings->order_by;
147
+ $order = empty( $settings->order ) ? 'DESC' : $settings->order;
148
+ $users = empty( $settings->users ) ? '' : $settings->users;
149
+ $fields = empty( $settings->fields ) ? '' : $settings->fields;
150
+ $exclude_self = '';
151
+ if ( isset( $settings->exclude_self ) && 'yes' == $settings->exclude_self ) {
152
+ $exclude_self = $post->ID;
153
+ }
154
 
155
  $paged = self::get_paged();
156
 
276
  $term_ids = $related;
277
  }
278
  }
279
+ }
280
 
281
  if ( ! empty( $term_ids ) ) {
282
 
287
  'operator' => $operator,
288
  );
289
  }
290
+ }
291
 
292
  // Post in/not in query.
293
  if ( isset( $settings->{'posts_' . $post_type} ) ) {
308
  }
309
  }
310
 
311
+ if ( $exclude_self ) {
312
+ $args['post__not_in'][] = $exclude_self;
313
+ }
314
+
315
  $args = apply_filters( 'fl_builder_loop_query_args', $args );
316
 
317
  // Build the query.
704
  $total_pages = $query->max_num_pages;
705
  $permalink_structure = get_option( 'permalink_structure' );
706
  $paged = self::get_paged();
707
+ $base = html_entity_decode( get_pagenum_link() );
708
 
709
  if ( $total_pages > 1 ) {
710
 
782
  $base = strtok( $base, '?' );
783
  }
784
 
785
+ // Add trailing slash when necessary.
786
+ if ( '/' == substr( $permalink_structure, -1 ) ) {
787
+ $base = trailingslashit( $base );
788
+ } else {
789
+ $base = untrailingslashit( $base );
790
+ }
791
  } else {
792
  $url_params = wp_parse_url( $base, PHP_URL_QUERY );
793
 
815
  }
816
 
817
  if ( ! empty( $permalink_structure ) ) {
818
+ $format = substr( $base, -1 ) != '/' ? '/' : '';
819
+ $format .= $page_prefix . '/';
820
  $format .= '%#%';
821
  $format .= substr( $permalink_structure, -1 ) == '/' ? '/' : '';
822
  } elseif ( empty( $permalink_structure ) || is_search() ) {
classes/class-fl-builder-model.php CHANGED
@@ -433,11 +433,12 @@ final class FLBuilderModel {
433
 
434
  if ( is_singular() && isset( $wp_the_query->post ) ) {
435
 
436
- $post = $wp_the_query->post;
437
- $post_types = self::get_post_types();
438
- $user_can = current_user_can( 'edit_post', $post->ID );
 
439
 
440
- if ( in_array( $post->post_type, $post_types ) && $user_can ) {
441
  $editable = true;
442
  }
443
  }
@@ -473,7 +474,7 @@ final class FLBuilderModel {
473
  global $wp_the_query;
474
 
475
  // If in iframe preview return true as the post might not be a draft yet.
476
- if ( isset( $_GET['fl_builder_preview'] ) ) {
477
  return true;
478
  }
479
 
@@ -524,6 +525,16 @@ final class FLBuilderModel {
524
  return self::$active;
525
  }
526
 
 
 
 
 
 
 
 
 
 
 
527
  /**
528
  * Checks to see if this is the first time
529
  * a user has launched the builder.
@@ -593,15 +604,16 @@ final class FLBuilderModel {
593
  $post = $wp_the_query->post;
594
  $published = self::get_layout_data( 'published' );
595
  $draft = self::get_layout_data( 'draft' );
 
596
 
597
  // Migrate existing post content to the builder?
598
- if ( empty( $published ) && empty( $draft ) && ! empty( $post->post_content ) ) {
599
 
600
  $row = self::add_row();
601
  $cols = self::get_nodes( 'column' );
602
  $col = array_shift( $cols );
603
  $settings = self::get_module_defaults( 'rich-text' );
604
- $settings->text = apply_filters( 'fl_builder_migrated_post_content', wpautop( $post->post_content ) );
605
 
606
  self::add_module( 'rich-text', $settings, $col->node );
607
  } elseif ( empty( $draft ) ) {
@@ -709,8 +721,9 @@ final class FLBuilderModel {
709
  static public function get_asset_version() {
710
  $post_id = self::get_post_id();
711
  $active = self::is_builder_active();
 
712
 
713
- if ( $active ) {
714
  return md5( uniqid() );
715
  } else {
716
  return md5( get_post_modified_time( 'U', false, $post_id ) );
@@ -728,10 +741,12 @@ final class FLBuilderModel {
728
  $post_data = self::get_post_data();
729
  $post_id = self::get_post_id();
730
  $cache_dir = self::get_cache_dir();
 
 
731
 
732
  if ( isset( $post_data['node_preview'] ) ) {
733
  $suffix = '-layout-preview';
734
- } elseif ( self::is_builder_active() ) {
735
  $suffix = '-layout-draft';
736
  } else {
737
  $suffix = '-layout';
@@ -1170,6 +1185,37 @@ final class FLBuilderModel {
1170
 
1171
  if ( self::is_post_user_template( 'module' ) ) {
1172
  $nodes['modules'] = self::get_all_modules();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1173
  } else {
1174
  $rows = self::get_nodes( 'row' );
1175
 
@@ -1214,9 +1260,9 @@ final class FLBuilderModel {
1214
  }
1215
  }
1216
  }
1217
- }// End foreach().
1218
- }// End foreach().
1219
- }// End if().
1220
 
1221
  return $nodes;
1222
  }
@@ -1236,10 +1282,25 @@ final class FLBuilderModel {
1236
 
1237
  // Get the node settings for a node template's root node?
1238
  if ( self::is_node_template_root( $node ) && ! self::is_post_node_template() ) {
1239
- $template_post_id = self::get_node_template_post_id( $node->template_id );
1240
- $template_data = self::get_layout_data( 'published', $template_post_id );
1241
- $template_node = $template_data[ $node->template_node_id ];
1242
- $node->settings = $template_node->settings;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1243
  }
1244
 
1245
  // Get either the preview settings or saved node settings merged with the defaults.
@@ -1259,6 +1320,10 @@ final class FLBuilderModel {
1259
 
1260
  if ( 'module' == $node->type ) {
1261
  $settings = self::merge_nested_module_defaults( $node->settings->type, $settings );
 
 
 
 
1262
  }
1263
  }
1264
 
@@ -1572,6 +1637,7 @@ final class FLBuilderModel {
1572
  $new_row_id = self::generate_node_id();
1573
  $col_groups = self::get_nodes( 'column-group', $row );
1574
  $new_nodes = array();
 
1575
 
1576
  // Add the new row.
1577
  $layout_data[ $new_row_id ] = clone $row;
@@ -1621,7 +1687,7 @@ final class FLBuilderModel {
1621
  }
1622
  }
1623
  }
1624
- }// End foreach().
1625
 
1626
  // Apply settings that were passed if we have them.
1627
  if ( $settings && $settings_id ) {
@@ -1637,11 +1703,21 @@ final class FLBuilderModel {
1637
 
1638
  // Set col group parent ids to the new row id and unset template data.
1639
  foreach ( $new_nodes as $child_node_id => $child ) {
 
 
 
 
 
1640
  if ( 'column-group' == $child->type ) {
1641
  if ( $child->parent == $row->node || ( isset( $row->template_node_id ) && $child->parent == $row->template_node_id ) ) {
1642
  $new_nodes[ $child_node_id ]->parent = $new_row_id;
1643
  }
 
 
 
 
1644
  }
 
1645
  if ( isset( $new_nodes[ $child_node_id ]->template_id ) ) {
1646
  unset( $new_nodes[ $child_node_id ]->template_id );
1647
  unset( $new_nodes[ $child_node_id ]->template_node_id );
@@ -1668,7 +1744,9 @@ final class FLBuilderModel {
1668
  * @return object
1669
  */
1670
  static public function get_row_defaults() {
1671
- return self::get_settings_form_defaults( 'row' );
 
 
1672
  }
1673
 
1674
  /**
@@ -1896,7 +1974,7 @@ final class FLBuilderModel {
1896
  $data[ $col_node_id ]->template_node_id = $col_node_id;
1897
  }
1898
  }
1899
- } else {
1900
 
1901
  $old_group = $data[ $cols ]->parent;
1902
  $siblings = self::get_nodes( 'column', $old_group );
@@ -1920,7 +1998,7 @@ final class FLBuilderModel {
1920
  $data[ $sibling->node ]->position = $sibling_pos;
1921
  $sibling_pos++;
1922
  }
1923
- }// End if().
1924
 
1925
  // Update the layout data.
1926
  self::update_layout_data( $data );
@@ -2349,6 +2427,66 @@ final class FLBuilderModel {
2349
  return $parent;
2350
  }
2351
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2352
  /**
2353
  * Copys a column and adds it to the current layout.
2354
  *
@@ -2374,8 +2512,14 @@ final class FLBuilderModel {
2374
  // Unset column template data.
2375
  if ( isset( $layout_data[ $new_col_id ]->template_id ) ) {
2376
 
 
 
 
 
 
2377
  // Check if parent is a global node.
2378
  if ( self::is_node_global( $parent ) ) {
 
2379
  $layout_data[ $new_col_id ]->template_node_id = $new_col_id;
2380
  } else {
2381
  unset( $layout_data[ $new_col_id ]->template_id );
@@ -2429,7 +2573,8 @@ final class FLBuilderModel {
2429
  }
2430
  if ( isset( $new_nodes[ $child_node_id ]->template_id ) ) {
2431
  // Check if the column is global.
2432
- if ( $layout_data[ $new_col_id ]->template_node_id ) {
 
2433
  $new_nodes[ $child_node_id ]->template_node_id = $child_node_id;
2434
  } else {
2435
  unset( $new_nodes[ $child_node_id ]->template_id );
@@ -2461,7 +2606,9 @@ final class FLBuilderModel {
2461
  * @return object
2462
  */
2463
  static public function get_col_defaults() {
2464
- return self::get_settings_form_defaults( 'col' );
 
 
2465
  }
2466
 
2467
  /**
@@ -2588,6 +2735,30 @@ final class FLBuilderModel {
2588
  return isset( self::$modules[ $type ] );
2589
  }
2590
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2591
  /**
2592
  * Returns an array of all modules that are enabled.
2593
  *
@@ -2595,10 +2766,16 @@ final class FLBuilderModel {
2595
  * @return array
2596
  */
2597
  static public function get_enabled_modules() {
2598
- $default = array_keys( self::$modules );
2599
- $default[] = 'all';
2600
- $setting = self::get_admin_settings_option( '_fl_builder_enabled_modules', true );
2601
- $setting = ( ! $setting || in_array( 'all', $setting ) ) ? $default : $setting;
 
 
 
 
 
 
2602
 
2603
  foreach ( self::$modules as $module_slug => $module ) {
2604
  if ( ! $module->enabled && in_array( $module_slug, $setting ) ) {
@@ -3497,7 +3674,7 @@ final class FLBuilderModel {
3497
  * Merges the default settings for nested forms.
3498
  *
3499
  * @since 1.10.8
3500
- * @param string $type The type of form.
3501
  * @param string $form The form ID.
3502
  * @param object $settings The module settings object.
3503
  * @return object
@@ -3884,14 +4061,16 @@ final class FLBuilderModel {
3884
  $data = self::$published_layout_data[ $post_id ];
3885
  } else {
3886
  $data = get_metadata( 'post', $post_id, '_fl_builder_data', true );
3887
- self::$published_layout_data[ $post_id ] = self::clean_layout_data( $data );
 
3888
  }
3889
  } elseif ( 'draft' == $status ) {
3890
  if ( isset( self::$draft_layout_data[ $post_id ] ) ) {
3891
  $data = self::$draft_layout_data[ $post_id ];
3892
  } else {
3893
  $data = get_metadata( 'post', $post_id, '_fl_builder_draft', true );
3894
- self::$draft_layout_data[ $post_id ] = self::clean_layout_data( $data );
 
3895
  }
3896
  }
3897
 
@@ -4501,7 +4680,7 @@ final class FLBuilderModel {
4501
 
4502
  $post = $template_id ? get_post( $template_id ) : FLBuilderModel::get_post();
4503
 
4504
- if ( 'fl-builder-template' != $post->post_type ) {
4505
  return '';
4506
  } else {
4507
 
@@ -4587,8 +4766,8 @@ final class FLBuilderModel {
4587
  // Delete old asset cache.
4588
  self::delete_asset_cache();
4589
 
4590
- }// End if().
4591
- }// End if().
4592
 
4593
  // Return the layout.
4594
  return array(
@@ -4634,7 +4813,7 @@ final class FLBuilderModel {
4634
 
4635
  $saved_type = self::get_user_template_type( $post->ID );
4636
 
4637
- if ( in_array( $saved_type, array( 'row', 'module' ) ) ) {
4638
  return true;
4639
  }
4640
  }
@@ -4712,8 +4891,7 @@ final class FLBuilderModel {
4712
  $is_visible = false;
4713
  }
4714
  }
4715
- } // End if().
4716
- elseif ( 0 == $node->settings->visibility_display ) {
4717
  $is_visible = false;
4718
  } else {
4719
  $is_visible = false;
@@ -4780,8 +4958,18 @@ final class FLBuilderModel {
4780
  * @return object
4781
  */
4782
  static public function get_node_template_root( $type = '', $nodes = array() ) {
 
 
 
 
4783
  foreach ( $nodes as $node ) {
4784
  if ( $type == $node->type ) {
 
 
 
 
 
 
4785
  return $node;
4786
  }
4787
  }
@@ -4901,6 +5089,12 @@ final class FLBuilderModel {
4901
  // Reset the root node's position.
4902
  $root_node->position = 0;
4903
 
 
 
 
 
 
 
4904
  // Add the root node to the nodes array.
4905
  $nodes[ $root_node->node ] = $root_node;
4906
 
@@ -5212,6 +5406,7 @@ final class FLBuilderModel {
5212
  static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null ) {
5213
  $parent = ( 0 == $parent_id ) ? null : self::get_node( $parent_id );
5214
  $template_post_id = self::get_node_template_post_id( $template_id );
 
5215
 
5216
  // Allow extensions to hook into applying a node template.
5217
  $override = apply_filters( 'fl_builder_override_apply_node_template', false, array(
@@ -5246,18 +5441,25 @@ final class FLBuilderModel {
5246
  // Get the root node from the template data.
5247
  $root_node = self::get_node_template_root( $type, $template_data );
5248
 
5249
- // Handle module templates.
5250
- if ( 'module' == $root_node->type ) {
5251
 
5252
- // Add a new parent for module node templates if needed.
5253
  if ( ! $parent || 'row' == $parent->type || 'column-group' == $parent->type ) {
5254
- $parent_id = self::add_module_parent( $parent_id, $position );
5255
- $parent = self::get_node( $parent_id );
5256
- $position = null;
 
 
 
 
 
 
 
5257
  }
5258
 
5259
- // Set the module's template data if the parent is a global node.
5260
- if ( self::is_node_global( $parent ) ) {
5261
  $template_data[ $root_node->node ]->template_id = $parent->template_id;
5262
  $template_data[ $root_node->node ]->template_node_id = $root_node->node;
5263
  unset( $template_data[ $root_node->node ]->template_root_node );
@@ -5299,6 +5501,11 @@ final class FLBuilderModel {
5299
  self::reorder_node( $root_node->node, $position );
5300
  }
5301
 
 
 
 
 
 
5302
  // Delete old asset cache.
5303
  self::delete_asset_cache();
5304
 
@@ -5535,9 +5742,9 @@ final class FLBuilderModel {
5535
 
5536
  self::$template_data[ $template_type ] = array_merge( self::$template_data[ $template_type ], $template_data );
5537
  }
5538
- }// End foreach().
5539
- }// End foreach().
5540
- }// End if().
5541
 
5542
  $templates = isset( self::$template_data[ $type ] ) ? self::$template_data[ $type ] : array();
5543
 
@@ -5556,7 +5763,7 @@ final class FLBuilderModel {
5556
 
5557
  /**
5558
  * Returns template data needed for the template selector.
5559
- * Can also return data for row and module templates if
5560
  * a template type is passed.
5561
  *
5562
  * @since 1.5.7
@@ -5603,7 +5810,7 @@ final class FLBuilderModel {
5603
  'group' => $template->group,
5604
  'type' => 'core',
5605
  'kind' => 'template',
5606
- 'content' => ! in_array( $type, array( 'row', 'module' ) ) ? 'layout' : $type,
5607
  ), $template );
5608
  }
5609
 
@@ -5677,7 +5884,7 @@ final class FLBuilderModel {
5677
  }
5678
 
5679
  $templates[ $i ] = $template;
5680
- }// End foreach().
5681
 
5682
  // Return both the templates and categorized templates array.
5683
  return apply_filters( 'fl_builder_template_selector_data', array(
@@ -5697,6 +5904,16 @@ final class FLBuilderModel {
5697
  return apply_filters( 'fl_builder_row_templates_data', self::get_template_selector_data( 'row' ) );
5698
  }
5699
 
 
 
 
 
 
 
 
 
 
 
5700
  /**
5701
  * Returns data for module templates to be shown in the UI panel.
5702
  *
@@ -5730,6 +5947,40 @@ final class FLBuilderModel {
5730
  return update_option( '_fl_builder_color_presets', $presets );
5731
  }
5732
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5733
  /**
5734
  * Returns the custom branding string.
5735
  *
@@ -5741,7 +5992,7 @@ final class FLBuilderModel {
5741
  return FLBuilderWhiteLabel::get_branding();
5742
  }
5743
 
5744
- return __( 'Page Builder', 'fl-builder' );
5745
  }
5746
 
5747
  /**
@@ -5767,7 +6018,7 @@ final class FLBuilderModel {
5767
  static public function get_enabled_icons() {
5768
  $value = self::get_admin_settings_option( '_fl_builder_enabled_icons', true );
5769
 
5770
- return ! $value ? array( 'font-awesome', 'foundation-icons', 'dashicons' ) : $value;
5771
  }
5772
 
5773
  /**
@@ -6030,6 +6281,7 @@ final class FLBuilderModel {
6030
  delete_option( '_fl_builder_enabled_templates' );
6031
  delete_option( '_fl_builder_templates_override' );
6032
  delete_option( '_fl_builder_templates_override_rows' );
 
6033
  delete_option( '_fl_builder_templates_override_modules' );
6034
  delete_option( '_fl_builder_post_types' );
6035
  delete_option( '_fl_builder_enabled_icons' );
@@ -6058,7 +6310,7 @@ final class FLBuilderModel {
6058
  wp_redirect( admin_url( 'plugins.php?deleted=true&plugin_status=all&paged=1&s=' ) );
6059
 
6060
  exit;
6061
- }// End if().
6062
  }
6063
 
6064
  /**
433
 
434
  if ( is_singular() && isset( $wp_the_query->post ) ) {
435
 
436
+ $post = $wp_the_query->post;
437
+ $post_types = self::get_post_types();
438
+ $user_can = current_user_can( 'edit_post', $post->ID );
439
+ $user_access = FLBuilderUserAccess::current_user_can( 'builder_access' );
440
 
441
+ if ( in_array( $post->post_type, $post_types ) && $user_can && $user_access ) {
442
  $editable = true;
443
  }
444
  }
474
  global $wp_the_query;
475
 
476
  // If in iframe preview return true as the post might not be a draft yet.
477
+ if ( self::is_builder_draft_preview() ) {
478
  return true;
479
  }
480
 
525
  return self::$active;
526
  }
527
 
528
+ /**
529
+ * Returns if this is a draft layout preview or not.
530
+ *
531
+ * @since 2.1
532
+ * @return bool
533
+ */
534
+ static public function is_builder_draft_preview() {
535
+ return is_user_logged_in() && isset( $_GET['fl_builder_preview'] );
536
+ }
537
+
538
  /**
539
  * Checks to see if this is the first time
540
  * a user has launched the builder.
604
  $post = $wp_the_query->post;
605
  $published = self::get_layout_data( 'published' );
606
  $draft = self::get_layout_data( 'draft' );
607
+ $content = apply_filters( 'fl_builder_migrated_post_content', $post->post_content );
608
 
609
  // Migrate existing post content to the builder?
610
+ if ( empty( $published ) && empty( $draft ) && ! empty( $content ) ) {
611
 
612
  $row = self::add_row();
613
  $cols = self::get_nodes( 'column' );
614
  $col = array_shift( $cols );
615
  $settings = self::get_module_defaults( 'rich-text' );
616
+ $settings->text = $content;
617
 
618
  self::add_module( 'rich-text', $settings, $col->node );
619
  } elseif ( empty( $draft ) ) {
721
  static public function get_asset_version() {
722
  $post_id = self::get_post_id();
723
  $active = self::is_builder_active();
724
+ $preview = self::is_builder_draft_preview();
725
 
726
+ if ( $active || $preview ) {
727
  return md5( uniqid() );
728
  } else {
729
  return md5( get_post_modified_time( 'U', false, $post_id ) );
741
  $post_data = self::get_post_data();
742
  $post_id = self::get_post_id();
743
  $cache_dir = self::get_cache_dir();
744
+ $active = self::is_builder_active();
745
+ $preview = self::is_builder_draft_preview();
746
 
747
  if ( isset( $post_data['node_preview'] ) ) {
748
  $suffix = '-layout-preview';
749
+ } elseif ( $active || $preview ) {
750
  $suffix = '-layout-draft';
751
  } else {
752
  $suffix = '-layout';
1185
 
1186
  if ( self::is_post_user_template( 'module' ) ) {
1187
  $nodes['modules'] = self::get_all_modules();
1188
+ } elseif ( self::is_post_user_template( 'column' ) ) {
1189
+ $root_col = self::get_node_template_root( 'column' );
1190
+
1191
+ $nodes['columns'][ $root_col->node ] = $root_col;
1192
+ $col_children = self::get_nodes( null, $root_col );
1193
+
1194
+ foreach ( $col_children as $col_child ) {
1195
+
1196
+ if ( 'module' == $col_child->type ) {
1197
+
1198
+ $module = self::get_module( $col_child );
1199
+
1200
+ if ( $module ) {
1201
+ $nodes['modules'][ $col_child->node ] = $module;
1202
+ }
1203
+ } elseif ( 'column-group' == $col_child->type ) {
1204
+
1205
+ $nodes['groups'][ $col_child->node ] = $col_child;
1206
+ $group_cols = self::get_nodes( 'column', $col_child );
1207
+
1208
+ foreach ( $group_cols as $group_col ) {
1209
+
1210
+ $nodes['columns'][ $group_col->node ] = $group_col;
1211
+ $modules = self::get_modules( $group_col );
1212
+
1213
+ foreach ( $modules as $module ) {
1214
+ $nodes['modules'][ $module->node ] = $module;
1215
+ }
1216
+ }
1217
+ }
1218
+ }
1219
  } else {
1220
  $rows = self::get_nodes( 'row' );
1221
 
1260
  }
1261
  }
1262
  }
1263
+ }
1264
+ }
1265
+ }
1266
 
1267
  return $nodes;
1268
  }
1282
 
1283
  // Get the node settings for a node template's root node?
1284
  if ( self::is_node_template_root( $node ) && ! self::is_post_node_template() ) {
1285
+ $template_post_id = self::get_node_template_post_id( $node->template_id );
1286
+ $template_data = self::get_layout_data( 'published', $template_post_id );
1287
+
1288
+ // Fallback to draft data if we don't have published data.
1289
+ if ( ! isset( $template_data[ $node->template_node_id ] ) ) {
1290
+ $template_data = self::get_layout_data( 'draft', $template_post_id );
1291
+ }
1292
+
1293
+ // Set the node settings to the template node settings.
1294
+ if ( isset( $template_data[ $node->template_node_id ] ) ) {
1295
+ $template_node = $template_data[ $node->template_node_id ];
1296
+ $template_settings = clone $template_node->settings;
1297
+
1298
+ if ( 'column' == $node->type ) {
1299
+ $template_settings->size = $node->settings->size;
1300
+ }
1301
+
1302
+ $node->settings = $template_settings;
1303
+ }
1304
  }
1305
 
1306
  // Get either the preview settings or saved node settings merged with the defaults.
1320
 
1321
  if ( 'module' == $node->type ) {
1322
  $settings = self::merge_nested_module_defaults( $node->settings->type, $settings );
1323
+ } elseif ( 'column' == $node->type ) {
1324
+ $settings = self::merge_nested_form_defaults( 'general', 'col', $settings );
1325
+ } elseif ( 'row' == $node->type ) {
1326
+ $settings = self::merge_nested_form_defaults( 'general', 'row', $settings );
1327
  }
1328
  }
1329
 
1637
  $new_row_id = self::generate_node_id();
1638
  $col_groups = self::get_nodes( 'column-group', $row );
1639
  $new_nodes = array();
1640
+ $template_cols = array();
1641
 
1642
  // Add the new row.
1643
  $layout_data[ $new_row_id ] = clone $row;
1687
  }
1688
  }
1689
  }
1690
+ }
1691
 
1692
  // Apply settings that were passed if we have them.
1693
  if ( $settings && $settings_id ) {
1703
 
1704
  // Set col group parent ids to the new row id and unset template data.
1705
  foreach ( $new_nodes as $child_node_id => $child ) {
1706
+ // Check for column template's new node id.
1707
+ if ( isset( $child->template_node_id ) ) {
1708
+ $template_cols[ $child->template_node_id ] = $child_node_id;
1709
+ }
1710
+
1711
  if ( 'column-group' == $child->type ) {
1712
  if ( $child->parent == $row->node || ( isset( $row->template_node_id ) && $child->parent == $row->template_node_id ) ) {
1713
  $new_nodes[ $child_node_id ]->parent = $new_row_id;
1714
  }
1715
+ } elseif ( 'module' == $child->type ) {
1716
+ if ( isset( $template_cols[ $child->parent ] ) ) {
1717
+ $new_nodes[ $child_node_id ]->parent = $template_cols[ $child->parent ];
1718
+ }
1719
  }
1720
+
1721
  if ( isset( $new_nodes[ $child_node_id ]->template_id ) ) {
1722
  unset( $new_nodes[ $child_node_id ]->template_id );
1723
  unset( $new_nodes[ $child_node_id ]->template_node_id );
1744
  * @return object
1745
  */
1746
  static public function get_row_defaults() {
1747
+ $settings = self::get_settings_form_defaults( 'row' );
1748
+ $settings = self::merge_nested_form_defaults( 'general', 'row', $settings );
1749
+ return $settings;
1750
  }
1751
 
1752
  /**
1974
  $data[ $col_node_id ]->template_node_id = $col_node_id;
1975
  }
1976
  }
1977
+ } elseif ( isset( $data[ $cols ] ) ) {
1978
 
1979
  $old_group = $data[ $cols ]->parent;
1980
  $siblings = self::get_nodes( 'column', $old_group );
1998
  $data[ $sibling->node ]->position = $sibling_pos;
1999
  $sibling_pos++;
2000
  }
2001
+ }
2002
 
2003
  // Update the layout data.
2004
  self::update_layout_data( $data );
2427
  return $parent;
2428
  }
2429
 
2430
+ /**
2431
+ * Adds a parent node for a column if a parent with the supplied
2432
+ * parent ID doesn't exist.
2433
+ *
2434
+ * @since 2.1
2435
+ * @param string $parent_id The node ID of the parent to look for.
2436
+ * @param int $position The position of the parent.
2437
+ * @return string|null The new parent ID or null if none exists.
2438
+ */
2439
+ static public function add_col_parent( $parent_id = null, $position = null ) {
2440
+ $data = self::get_layout_data();
2441
+ $parent = ! $parent_id ? null : self::get_node( $parent_id );
2442
+
2443
+ if ( ! $parent ) {
2444
+ // Add a new row if we don't have a parent, but don't add column.
2445
+ $row = self::add_row( null, $position );
2446
+ $col_groups = self::get_nodes( 'column-group', $row->node );
2447
+ $col_group = array_shift( $col_groups );
2448
+ $parent_id = $col_group->node;
2449
+ } elseif ( 'row' == $parent->type ) {
2450
+ // Add a new column group if the parent is a row, but don't add column.
2451
+ $col_group = self::add_col_group( $parent->node, null, $position );
2452
+ $parent_id = $col_group->node;
2453
+ }
2454
+
2455
+ return $parent_id;
2456
+ }
2457
+
2458
+ /**
2459
+ * Returns a column's parent node of the specified type.
2460
+ *
2461
+ * @since 2.1
2462
+ * @param string $type The type of parent to return.
2463
+ * @param string|object $column_id The columns's node ID. Can also be a column object.
2464
+ * @return object The parent node.
2465
+ */
2466
+ static public function get_col_parent( $type, $column_id ) {
2467
+ $column = is_object( $column_id ) ? $column_id : self::get_node( $column_id );
2468
+ $nodes = self::get_categorized_nodes();
2469
+
2470
+ foreach ( $nodes['groups'] as $group ) {
2471
+
2472
+ if ( $group->node == $column->parent ) {
2473
+
2474
+ if ( 'column-group' == $type ) {
2475
+ return $group;
2476
+ }
2477
+
2478
+ foreach ( $nodes['rows'] as $row ) {
2479
+
2480
+ if ( $row->node == $group->parent ) {
2481
+ return $row;
2482
+ }
2483
+ }
2484
+ }
2485
+ }
2486
+
2487
+ return null;
2488
+ }
2489
+
2490
  /**
2491
  * Copys a column and adds it to the current layout.
2492
  *
2512
  // Unset column template data.
2513
  if ( isset( $layout_data[ $new_col_id ]->template_id ) ) {
2514
 
2515
+ // Get the column root parent on a page.
2516
+ if ( isset( $layout_data[ $new_col_id ]->template_root_node ) ) {
2517
+ $parent = self::get_node( $layout_data[ $new_col_id ]->parent );
2518
+ }
2519
+
2520
  // Check if parent is a global node.
2521
  if ( self::is_node_global( $parent ) ) {
2522
+ $layout_data[ $new_col_id ]->template_id = $parent->template_id;
2523
  $layout_data[ $new_col_id ]->template_node_id = $new_col_id;
2524
  } else {
2525
  unset( $layout_data[ $new_col_id ]->template_id );
2573
  }
2574
  if ( isset( $new_nodes[ $child_node_id ]->template_id ) ) {
2575
  // Check if the column is global.
2576
+ if ( isset( $layout_data[ $new_col_id ]->template_node_id ) ) {
2577
+ $new_nodes[ $child_node_id ]->template_id = $parent->template_id;
2578
  $new_nodes[ $child_node_id ]->template_node_id = $child_node_id;
2579
  } else {
2580
  unset( $new_nodes[ $child_node_id ]->template_id );
2606
  * @return object
2607
  */
2608
  static public function get_col_defaults() {
2609
+ $settings = self::get_settings_form_defaults( 'col' );
2610
+ $settings = self::merge_nested_form_defaults( 'general', 'col', $settings );
2611
+ return $settings;
2612
  }
2613
 
2614
  /**
2735
  return isset( self::$modules[ $type ] );
2736
  }
2737
 
2738
+ /**
2739
+ * Returns an array of modules that are enabled by default.
2740
+ *
2741
+ * @since 2.1
2742
+ * @return array
2743
+ */
2744
+ static public function get_default_enabled_modules() {
2745
+ $default = array_keys( self::$modules );
2746
+
2747
+ // These modules are deprecated and disabled by default.
2748
+ $deprecated = array(
2749
+ 'social-buttons',
2750
+ );
2751
+
2752
+ // Remove deprecated modules from the defaults.
2753
+ foreach ( $default as $key => $slug ) {
2754
+ if ( in_array( $slug, $deprecated ) ) {
2755
+ unset( $default[ $key ] );
2756
+ }
2757
+ }
2758
+
2759
+ return array_values( $default );
2760
+ }
2761
+
2762
  /**
2763
  * Returns an array of all modules that are enabled.
2764
  *
2766
  * @return array
2767
  */
2768
  static public function get_enabled_modules() {
2769
+ $setting = self::get_admin_settings_option( '_fl_builder_enabled_modules', true );
2770
+
2771
+ if ( ! $setting ) {
2772
+ // Fallback to the defaults if no saved setting.
2773
+ $setting = self::get_default_enabled_modules();
2774
+ } elseif ( in_array( 'all', $setting ) ) {
2775
+ // Redefine $setting in case new modules have been installed since the last save.
2776
+ $setting = array_keys( self::$modules );
2777
+ $setting[] = 'all';
2778
+ }
2779
 
2780
  foreach ( self::$modules as $module_slug => $module ) {
2781
  if ( ! $module->enabled && in_array( $module_slug, $setting ) ) {
3674
  * Merges the default settings for nested forms.
3675
  *
3676
  * @since 1.10.8
3677
+ * @param string $type The type of form. Either general or module.
3678
  * @param string $form The form ID.
3679
  * @param object $settings The module settings object.
3680
  * @return object
4061
  $data = self::$published_layout_data[ $post_id ];
4062
  } else {
4063
  $data = get_metadata( 'post', $post_id, '_fl_builder_data', true );
4064
+ $data = self::clean_layout_data( $data );
4065
+ self::$published_layout_data[ $post_id ] = apply_filters( 'fl_builder_get_layout_metadata', $data, $status, $post_id );
4066
  }
4067
  } elseif ( 'draft' == $status ) {
4068
  if ( isset( self::$draft_layout_data[ $post_id ] ) ) {
4069
  $data = self::$draft_layout_data[ $post_id ];
4070
  } else {
4071
  $data = get_metadata( 'post', $post_id, '_fl_builder_draft', true );
4072
+ $data = self::clean_layout_data( $data );
4073
+ self::$draft_layout_data[ $post_id ] = apply_filters( 'fl_builder_get_layout_metadata', $data, $status, $post_id );
4074
  }
4075
  }
4076
 
4680
 
4681
  $post = $template_id ? get_post( $template_id ) : FLBuilderModel::get_post();
4682
 
4683
+ if ( ! is_object( $post ) || 'fl-builder-template' != $post->post_type ) {
4684
  return '';
4685
  } else {
4686
 
4766
  // Delete old asset cache.
4767
  self::delete_asset_cache();
4768
 
4769
+ }
4770
+ }
4771
 
4772
  // Return the layout.
4773
  return array(
4813
 
4814
  $saved_type = self::get_user_template_type( $post->ID );
4815
 
4816
+ if ( in_array( $saved_type, array( 'row', 'column', 'module' ) ) ) {
4817
  return true;
4818
  }
4819
  }
4891
  $is_visible = false;
4892
  }
4893
  }
4894
+ } elseif ( 0 == $node->settings->visibility_display ) {
 
4895
  $is_visible = false;
4896
  } else {
4897
  $is_visible = false;
4958
  * @return object
4959
  */
4960
  static public function get_node_template_root( $type = '', $nodes = array() ) {
4961
+ if ( '' != $type ) {
4962
+ $nodes = count( $nodes ) > 0 ? $nodes : self::get_nodes( $type );
4963
+ }
4964
+
4965
  foreach ( $nodes as $node ) {
4966
  if ( $type == $node->type ) {
4967
+
4968
+ // Root parent for column template should be null.
4969
+ if ( 'column' == $type && $node->parent ) {
4970
+ continue;
4971
+ }
4972
+
4973
  return $node;
4974
  }
4975
  }
5089
  // Reset the root node's position.
5090
  $root_node->position = 0;
5091
 
5092
+ // Remove root parent for column template.
5093
+ if ( 'column' == $root_node->type ) {
5094
+ $root_node->parent = null;
5095
+ $root_node->settings->size = 100;
5096
+ }
5097
+
5098
  // Add the root node to the nodes array.
5099
  $nodes[ $root_node->node ] = $root_node;
5100
 
5406
  static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null ) {
5407
  $parent = ( 0 == $parent_id ) ? null : self::get_node( $parent_id );
5408
  $template_post_id = self::get_node_template_post_id( $template_id );
5409
+ $is_col_template = false;
5410
 
5411
  // Allow extensions to hook into applying a node template.
5412
  $override = apply_filters( 'fl_builder_override_apply_node_template', false, array(
5441
  // Get the root node from the template data.
5442
  $root_node = self::get_node_template_root( $type, $template_data );
5443
 
5444
+ // Handle module and column templates.
5445
+ if ( 'module' == $root_node->type || 'column' == $root_node->type ) {
5446
 
5447
+ // Add a new parent for module or column node templates if needed.
5448
  if ( ! $parent || 'row' == $parent->type || 'column-group' == $parent->type ) {
5449
+
5450
+ if ( 'module' == $root_node->type ) {
5451
+ $parent_id = self::add_module_parent( $parent_id, $position );
5452
+ $position = null;
5453
+ } elseif ( 'column' == $root_node->type ) {
5454
+ $parent_id = self::add_col_parent( $parent_id, $position );
5455
+ $is_col_template = self::is_node_global( $root_node );
5456
+ }
5457
+
5458
+ $parent = self::get_node( $parent_id );
5459
  }
5460
 
5461
+ // Set the node's template data if the parent is a global node.
5462
+ if ( self::is_node_global( $parent ) && ! $is_col_template ) {
5463
  $template_data[ $root_node->node ]->template_id = $parent->template_id;
5464
  $template_data[ $root_node->node ]->template_node_id = $root_node->node;
5465
  unset( $template_data[ $root_node->node ]->template_root_node );
5501
  self::reorder_node( $root_node->node, $position );
5502
  }
5503
 
5504
+ // Re-size column widths
5505
+ if ( 'column' == $root_node->type && 'column-group' == $parent->type ) {
5506
+ self::reset_col_widths( $parent_id );
5507
+ }
5508
+
5509
  // Delete old asset cache.
5510
  self::delete_asset_cache();
5511
 
5742
 
5743
  self::$template_data[ $template_type ] = array_merge( self::$template_data[ $template_type ], $template_data );
5744
  }
5745
+ }
5746
+ }
5747
+ }
5748
 
5749
  $templates = isset( self::$template_data[ $type ] ) ? self::$template_data[ $type ] : array();
5750
 
5763
 
5764
  /**
5765
  * Returns template data needed for the template selector.
5766
+ * Can also return data for row, column and module templates if
5767
  * a template type is passed.
5768
  *
5769
  * @since 1.5.7
5810
  'group' => $template->group,
5811
  'type' => 'core',
5812
  'kind' => 'template',
5813
+ 'content' => ! in_array( $type, array( 'row', 'column', 'module' ) ) ? 'layout' : $type,
5814
  ), $template );
5815
  }
5816
 
5884
  }
5885
 
5886
  $templates[ $i ] = $template;
5887
+ }
5888
 
5889
  // Return both the templates and categorized templates array.
5890
  return apply_filters( 'fl_builder_template_selector_data', array(
5904
  return apply_filters( 'fl_builder_row_templates_data', self::get_template_selector_data( 'row' ) );
5905
  }
5906
 
5907
+ /**
5908
+ * Returns data for column templates to be shown in the UI panel.
5909
+ *
5910
+ * @since 2.1
5911
+ * @return array
5912
+ */
5913
+ static public function get_column_templates_data() {
5914
+ return apply_filters( 'fl_builder_column_templates_data', self::get_template_selector_data( 'column' ) );
5915
+ }
5916
+
5917
  /**
5918
  * Returns data for module templates to be shown in the UI panel.
5919
  *
5947
  return update_option( '_fl_builder_color_presets', $presets );
5948
  }
5949
 
5950
+ /**
5951
+ * Returns whether the UI has been white labeled or not.
5952
+ *
5953
+ * @since 2.1
5954
+ * @return bool
5955
+ */
5956
+ static public function is_white_labeled() {
5957
+ if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5958
+ return FLBuilderWhiteLabel::is_white_labeled();
5959
+ }
5960
+
5961
+ return false;
5962
+ }
5963
+
5964
+ /**
5965
+ * Returns whether the inline editing is enabled.
5966
+ *
5967
+ * @since 2.1
5968
+ * @return bool
5969
+ */
5970
+ static public function is_inline_enabled() {
5971
+ return apply_filters( 'fl_inline_editing_enabled', true );
5972
+ }
5973
+
5974
+ /**
5975
+ * Returns whether the Ace Editor error checking is enabled.
5976
+ *
5977
+ * @since 2.1
5978
+ * @return bool
5979
+ */
5980
+ static public function is_codechecking_enabled() {
5981
+ return apply_filters( 'fl_code_checking_enabled', true );
5982
+ }
5983
+
5984
  /**
5985
  * Returns the custom branding string.
5986
  *
5992
  return FLBuilderWhiteLabel::get_branding();
5993
  }
5994
 
5995
+ return __( 'Beaver Builder', 'fl-builder' );
5996
  }
5997
 
5998
  /**
6018
  static public function get_enabled_icons() {
6019
  $value = self::get_admin_settings_option( '_fl_builder_enabled_icons', true );
6020
 
6021
+ return ! $value ? array( 'font-awesome-5-regular', 'font-awesome-5-solid', 'font-awesome-5-brands', 'foundation-icons', 'dashicons' ) : $value;
6022
  }
6023
 
6024
  /**
6281
  delete_option( '_fl_builder_enabled_templates' );
6282
  delete_option( '_fl_builder_templates_override' );
6283
  delete_option( '_fl_builder_templates_override_rows' );
6284
+ delete_option( '_fl_builder_templates_override_columns' );
6285
  delete_option( '_fl_builder_templates_override_modules' );
6286
  delete_option( '_fl_builder_post_types' );
6287
  delete_option( '_fl_builder_enabled_icons' );
6310
  wp_redirect( admin_url( 'plugins.php?deleted=true&plugin_status=all&paged=1&s=' ) );
6311
 
6312
  exit;
6313
+ }
6314
  }
6315
 
6316
  /**
classes/class-fl-builder-notifications.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notifications
4
+ * @since 2.1
5
+ */
6
+ final class FLBuilderNotifications {
7
+
8
+ static $url = 'https://www.wpbeaverbuilder.com/wp-json/wp/v2/fl_notification';
9
+
10
+ static $option = 'fl_notifications';
11
+
12
+ public static function init() {
13
+
14
+ if ( FLBuilderModel::is_white_labeled() || true == apply_filters( 'fl_disable_notifications', false ) ) {
15
+ return false;
16
+ }
17
+ add_action( 'pre_set_site_transient_update_plugins', array( 'FLBuilderNotifications', 'fetch_notifications_trigger' ) );
18
+ add_action( 'fl_fetch_notifications', array( 'FLBuilderNotifications', 'fetch_notifications' ) );
19
+ FLBuilderAJAX::add_action( 'fl_builder_notifications', array( 'FLBuilderNotifications', 'notications_ajax' ), array( 'read' ) );
20
+ }
21
+
22
+ /**
23
+ * Transient is passed by reference here, lets not mess with it and just trigger our fetch.
24
+ */
25
+ public static function fetch_notifications_trigger( $transient ) {
26
+ if ( ! did_action( 'fl_fetch_notifications' ) ) {
27
+ do_action( 'fl_fetch_notifications' );
28
+ }
29
+ return $transient;
30
+ }
31
+
32
+ /**
33
+ * Notification AJAX callback.
34
+ *
35
+ * @since 2.1
36
+ */
37
+ public static function notications_ajax( $read ) {
38
+
39
+ if ( $read ) {
40
+ self::update_state( true );
41
+ } else {
42
+ self::update_state( false );
43
+ }
44
+ wp_send_json_success();
45
+ }
46
+
47
+ /**
48
+ * Fetch notifications from remote.
49
+ *
50
+ * @since 2.1
51
+ */
52
+ public static function fetch_notifications() {
53
+
54
+ $defaults = array(
55
+ 'read' => false,
56
+ 'checksum' => '',
57
+ 'data' => '{}',
58
+ );
59
+
60
+ $url = ( isset( $_GET['force-check'] ) ) ? self::$url . '/?a=' . rand() : self::$url;
61
+ $stored_data = get_option( self::$option, $defaults );
62
+ $response = wp_remote_get( $url );
63
+
64
+ $response_code = wp_remote_retrieve_response_code( $response );
65
+ $body = wp_remote_retrieve_body( $response );
66
+
67
+ if ( 200 === $response_code ) {
68
+
69
+ $body = json_decode( $body );
70
+
71
+ // No post 0
72
+ if ( ! isset( $body[0] ) || ! isset( $body[0]->date ) ) {
73
+ return $stored_data;
74
+ }
75
+
76
+ // Generate checksum data
77
+ $latest_checksum = self::get_checksum( $body );
78
+ $stored_checksum = $stored_data['checksum'];
79
+
80
+ // check if we have any unread posts by comparing checksums
81
+ $unread = self::compare_checksums( $stored_checksum, $latest_checksum );
82
+
83
+ $stored_data = array(
84
+ 'read' => true,
85
+ 'checksum' => $latest_checksum,
86
+ 'data' => wp_json_encode( $body ),
87
+ );
88
+
89
+ if ( $unread ) {
90
+ $stored_data['read'] = false;
91
+ }
92
+
93
+ update_option( self::$option, $stored_data );
94
+
95
+ } else {
96
+ error_log( 'respose was not a 200' );
97
+ }
98
+ return $stored_data;
99
+
100
+ }
101
+
102
+ /**
103
+ * Compare locally stored checksums against new data.
104
+ * @since 2.1
105
+ * @return bool true if new posts detected
106
+ */
107
+ public static function compare_checksums( $stored_checksum, $latest_checksum ) {
108
+
109
+ if ( ! is_array( $stored_checksum ) ) {
110
+ return true;
111
+ }
112
+
113
+ foreach ( $stored_checksum as $id => $date ) {
114
+
115
+ // if a post has been deleted, then remove it from local checksum
116
+ if ( ! isset( $latest_checksum[ $id ] ) ) {
117
+ unset( $stored_checksum[ $id ] );
118
+ }
119
+ }
120
+
121
+ $diff = array_diff_assoc( $latest_checksum, $stored_checksum );
122
+ return ( ! empty( $diff ) ) ? true : false;
123
+ }
124
+
125
+ /**
126
+ * Prepare checksum array from rest data.
127
+ *
128
+ * @since 2.1
129
+ */
130
+ public static function get_checksum( $body ) {
131
+ $checksum = array();
132
+ foreach ( $body as $post ) {
133
+ $checksum[ $post->id ] = crc32( $post->content->rendered );
134
+ }
135
+ return (array) $checksum;
136
+ }
137
+
138
+ /**
139
+ * Return notications from the db or fetch from remote
140
+ *
141
+ * @since 2.1
142
+ */
143
+ public static function get_notifications() {
144
+
145
+ $defaults = array(
146
+ 'read' => false,
147
+ 'checksum' => '',
148
+ 'data' => '{}',
149
+ );
150
+ $notifications = get_option( self::$option, $defaults );
151
+
152
+ if ( '{}' == $notifications['data'] ) {
153
+ return self::fetch_notifications();
154
+ }
155
+ return $notifications;
156
+ }
157
+
158
+ /**
159
+ * Mark notifications read/unread
160
+ *
161
+ * @since 2.1
162
+ */
163
+ public static function update_state( $state ) {
164
+ $defaults = array(
165
+ 'read' => false,
166
+ 'checksum' => '',
167
+ 'data' => '{}',
168
+ );
169
+ $notifications = get_option( self::$option, $defaults );
170
+ $notifications['read'] = $state;
171
+ update_option( self::$option, $notifications );
172
+ }
173
+ }
174
+ FLBuilderNotifications::init();
classes/class-fl-builder-service-activecampaign.php CHANGED
@@ -65,8 +65,7 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
65
  // Make sure we have an API url.
66
  if ( ! isset( $fields['api_url'] ) || empty( $fields['api_url'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API URL.', 'fl-builder' );
68
- } // End if().
69
- elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
70
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
71
  } // Try to connect and store the connection data.
72
  else {
@@ -353,7 +352,7 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
353
  $response['error'] = $result->error;
354
  }
355
  }
356
- }// End if().
357
 
358
  return $response;
359
  }
65
  // Make sure we have an API url.
66
  if ( ! isset( $fields['api_url'] ) || empty( $fields['api_url'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API URL.', 'fl-builder' );
68
+ } elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
69
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
70
  } // Try to connect and store the connection data.
71
  else {
352
  $response['error'] = $result->error;
353
  }
354
  }
355
+ }
356
 
357
  return $response;
358
  }
classes/class-fl-builder-service-aweber.php CHANGED
@@ -68,8 +68,7 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
68
  // Make sure we have an authorization code.
69
  if ( ! isset( $fields['auth_code'] ) || empty( $fields['auth_code'] ) ) {
70
  $response['error'] = __( 'Error: You must provide an Authorization Code.', 'fl-builder' );
71
- } // End if().
72
- elseif ( 6 != count( explode( '|', $fields['auth_code'] ) ) ) {
73
  $response['error'] = __( 'Error: Please enter a valid Authorization Code.', 'fl-builder' );
74
  } // Try to connect and store the connection data.
75
  else {
@@ -270,7 +269,7 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
270
  $e->getMessage()
271
  );
272
  }
273
- }// End if().
274
 
275
  return $response;
276
  }
68
  // Make sure we have an authorization code.
69
  if ( ! isset( $fields['auth_code'] ) || empty( $fields['auth_code'] ) ) {
70
  $response['error'] = __( 'Error: You must provide an Authorization Code.', 'fl-builder' );
71
+ } elseif ( 6 != count( explode( '|', $fields['auth_code'] ) ) ) {
 
72
  $response['error'] = __( 'Error: Please enter a valid Authorization Code.', 'fl-builder' );
73
  } // Try to connect and store the connection data.
74
  else {
269
  $e->getMessage()
270
  );
271
  }
272
+ }
273
 
274
  return $response;
275
  }
classes/class-fl-builder-service-campaign-monitor.php CHANGED
@@ -51,8 +51,7 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
51
  // Make sure we have an API key.
52
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
53
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
54
- } // End if().
55
- else {
56
 
57
  $api = new CS_REST_General( array(
58
  'api_key' => $fields['api_key'],
51
  // Make sure we have an API key.
52
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
53
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
54
+ } else {
 
55
 
56
  $api = new CS_REST_General( array(
57
  'api_key' => $fields['api_key'],
classes/class-fl-builder-service-campayn.php CHANGED
@@ -96,8 +96,7 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
96
  // Make sure we have the Host.
97
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
98
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
99
- } // End if().
100
- elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
101
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
102
  } // Try to connect and store the connection data.
103
  else {
@@ -282,7 +281,7 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
282
  if ( isset( $result['error'] ) ) {
283
  $response['error'] = sprintf( __( 'There was an error subscribing to Campayn. %s', 'fl-builder' ), $result['error'] );
284
  }
285
- }// End if().
286
 
287
  return $response;
288
  }
96
  // Make sure we have the Host.
97
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
98
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
99
+ } elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
100
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
101
  } // Try to connect and store the connection data.
102
  else {
281
  if ( isset( $result['error'] ) ) {
282
  $response['error'] = sprintf( __( 'There was an error subscribing to Campayn. %s', 'fl-builder' ), $result['error'] );
283
  }
284
+ }
285
 
286
  return $response;
287
  }
classes/class-fl-builder-service-constant-contact.php CHANGED
@@ -45,8 +45,7 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
45
  // Make sure we have an API key.
46
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
47
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
48
- } // End if().
49
- elseif ( ! isset( $fields['access_token'] ) || empty( $fields['access_token'] ) ) {
50
  $response['error'] = __( 'Error: You must provide an access token.', 'fl-builder' );
51
  } // Try to connect and store the connection data.
52
  else {
@@ -237,8 +236,7 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
237
  if ( isset( $res->error_key ) ) {
238
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $res->error_key );
239
  }
240
- } // End if().
241
- else {
242
  // @codingStandardsIgnoreLine
243
  $args = $data = array();
244
  $data['email_addresses'] = array();
@@ -271,7 +269,7 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
271
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $create->error_key );
272
  }
273
  }
274
- }// End if().
275
 
276
  return $response;
277
  }
45
  // Make sure we have an API key.
46
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
47
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
48
+ } elseif ( ! isset( $fields['access_token'] ) || empty( $fields['access_token'] ) ) {
 
49
  $response['error'] = __( 'Error: You must provide an access token.', 'fl-builder' );
50
  } // Try to connect and store the connection data.
51
  else {
236
  if ( isset( $res->error_key ) ) {
237
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $res->error_key );
238
  }
239
+ } else {
 
240
  // @codingStandardsIgnoreLine
241
  $args = $data = array();
242
  $data['email_addresses'] = array();
269
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $create->error_key );
270
  }
271
  }
272
+ }
273
 
274
  return $response;
275
  }
classes/class-fl-builder-service-convertkit.php CHANGED
@@ -63,8 +63,7 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
- } // End if().
67
- else {
68
 
69
  $api = $this->get_api( $fields['api_key'] );
70
 
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
+ } else {
 
67
 
68
  $api = $this->get_api( $fields['api_key'] );
69
 
classes/class-fl-builder-service-drip.php CHANGED
@@ -63,8 +63,7 @@ final class FLBuilderServiceDrip extends FLBuilderService {
63
  // Make sure we have an API token.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
66
- } // End if().
67
- elseif ( ! isset( $fields['api_account_id'] ) || empty( $fields['api_account_id'] ) ) {
68
  $response['error'] = __( 'Error: You must provide an Account ID.', 'fl-builder' );
69
  } // Try to connect and store the connection data.
70
  else {
@@ -293,7 +292,7 @@ final class FLBuilderServiceDrip extends FLBuilderService {
293
  $e->getMessage()
294
  );
295
  }
296
- }// End if().
297
 
298
  return $response;
299
  }
63
  // Make sure we have an API token.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
66
+ } elseif ( ! isset( $fields['api_account_id'] ) || empty( $fields['api_account_id'] ) ) {
 
67
  $response['error'] = __( 'Error: You must provide an Account ID.', 'fl-builder' );
68
  } // Try to connect and store the connection data.
69
  else {
292
  $e->getMessage()
293
  );
294
  }
295
+ }
296
 
297
  return $response;
298
  }
classes/class-fl-builder-service-email-address.php CHANGED
@@ -36,8 +36,7 @@ final class FLBuilderServiceEmailAddress extends FLBuilderService {
36
  // Make sure we have an email address.
37
  if ( ! isset( $fields['email'] ) || empty( $fields['email'] ) ) {
38
  $response['error'] = __( 'Error: You must provide an email address.', 'fl-builder' );
39
- } // End if().
40
- else {
41
  $response['data'] = array(
42
  'email' => $fields['email'],
43
  );
36
  // Make sure we have an email address.
37
  if ( ! isset( $fields['email'] ) || empty( $fields['email'] ) ) {
38
  $response['error'] = __( 'Error: You must provide an email address.', 'fl-builder' );
39
+ } else {
 
40
  $response['data'] = array(
41
  'email' => $fields['email'],
42
  );
classes/class-fl-builder-service-enormail.php CHANGED
@@ -65,8 +65,7 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
65
  // Make sure we have an API key.
66
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
- } // End if().
69
- else {
70
 
71
  $api = $this->get_api( $fields['api_key'] );
72
 
@@ -209,8 +208,7 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
209
  // Add if not exists
210
  if ( -1 == $contact->code ) {
211
  $result = $api->contacts->add( $settings->list_id, $name, $email );
212
- } // End if().
213
- else {
214
  $result = $api->contacts->update( $settings->list_id, $name, $email );
215
  }
216
 
65
  // Make sure we have an API key.
66
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
+ } else {
 
69
 
70
  $api = $this->get_api( $fields['api_key'] );
71
 
208
  // Add if not exists
209
  if ( -1 == $contact->code ) {
210
  $result = $api->contacts->add( $settings->list_id, $name, $email );
211
+ } else {
 
212
  $result = $api->contacts->update( $settings->list_id, $name, $email );
213
  }
214
 
classes/class-fl-builder-service-getresponse.php CHANGED
@@ -63,8 +63,7 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
- } // End if().
67
- else {
68
 
69
  $api = $this->get_api( $fields['api_key'] );
70
  $ping = $api->ping();
@@ -95,7 +94,7 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
95
  'class' => 'fl-builder-service-connect-input',
96
  'type' => 'text',
97
  'label' => __( 'API Key', 'fl-builder' ),
98
- 'help' => __( 'Your API key can be found in your GetResponse account under My Account > GetResponse API.', 'fl-builder' ),
99
  'preview' => array(
100
  'type' => 'none',
101
  ),
@@ -150,7 +149,8 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
150
  );
151
 
152
  foreach ( $lists as $id => $data ) {
153
- $options[ $id ] = $data->name;
 
154
  }
155
 
156
  FLBuilder::render_settings_field( 'list_id', array(
@@ -198,20 +198,33 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
198
  $name = $names[0];
199
  }
200
 
 
 
 
 
 
 
 
 
201
  // Check if email exists
202
- $get_contact = $api->getContactsByEmail( $email );
 
 
 
 
 
 
203
 
204
  // @codingStandardsIgnoreLine
205
  if ( $contact = (array) $get_contact ) {
206
  reset( $contact );
207
- $contact_id = key( $contact );
208
 
209
- $result = $api->setContactName( $contact_id, $name );
210
- $api->setContactCampaign( $contact_id, $settings->list_id );
211
 
212
  // New contact
213
  } else {
214
- $result = $api->addContact( $settings->list_id, $name, $email );
215
  }
216
  } catch ( Exception $e ) {
217
  $response['error'] = sprintf(
@@ -219,7 +232,7 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
219
  $e->getMessage()
220
  );
221
  }
222
- }// End if().
223
 
224
  return $response;
225
  }
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
+ } else {
 
67
 
68
  $api = $this->get_api( $fields['api_key'] );
69
  $ping = $api->ping();
94
  'class' => 'fl-builder-service-connect-input',
95
  'type' => 'text',
96
  'label' => __( 'API Key', 'fl-builder' ),
97
+ 'help' => __( 'Your API key can be found in your GetResponse account under My Account > API & OAuth.', 'fl-builder' ),
98
  'preview' => array(
99
  'type' => 'none',
100
  ),
149
  );
150
 
151
  foreach ( $lists as $id => $data ) {
152
+ // @codingStandardsIgnoreLine
153
+ $options[ $data->campaignId ] = $data->name;
154
  }
155
 
156
  FLBuilder::render_settings_field( 'list_id', array(
198
  $name = $names[0];
199
  }
200
 
201
+ $data = array(
202
+ 'email' => $email,
203
+ 'name' => $name,
204
+ 'campaign' => array(
205
+ 'campaignId' => $settings->list_id,
206
+ ),
207
+ );
208
+
209
  // Check if email exists
210
+ $get_contact = $api->getContacts(array(
211
+ 'query' => array(
212
+ 'email' => $email,
213
+ 'campaignId' => $settings->list_id,
214
+ ),
215
+ 'fields' => 'name, email',
216
+ ));
217
 
218
  // @codingStandardsIgnoreLine
219
  if ( $contact = (array) $get_contact ) {
220
  reset( $contact );
221
+ $contact_id = $contact[0]->contactId;
222
 
223
+ $result = $api->updateContact( $contact_id, $data );
 
224
 
225
  // New contact
226
  } else {
227
+ $result = $api->addContact( $data );
228
  }
229
  } catch ( Exception $e ) {
230
  $response['error'] = sprintf(
232
  $e->getMessage()
233
  );
234
  }
235
+ }
236
 
237
  return $response;
238
  }
classes/class-fl-builder-service-godaddy-email-marketing.php CHANGED
@@ -65,8 +65,7 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
65
  // Make sure we have an email address.
66
  if ( ! isset( $fields['api_username'] ) || empty( $fields['api_username'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API username.', 'fl-builder' );
68
- } // End if().
69
- elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
70
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
71
  } // Try to connect and store the connection data.
72
  else {
65
  // Make sure we have an email address.
66
  if ( ! isset( $fields['api_username'] ) || empty( $fields['api_username'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API username.', 'fl-builder' );
68
+ } elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
69
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
70
  } // Try to connect and store the connection data.
71
  else {
classes/class-fl-builder-service-hatchbuck.php CHANGED
@@ -45,8 +45,7 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
45
  // Make sure we have an API key.
46
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
47
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
48
- } // End if().
49
- else {
50
 
51
  $result = wp_remote_post( $this->api_url . 'search?api_key=' . $fields['api_key'], array(
52
  'method' => 'POST',
@@ -185,8 +184,7 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
185
  if ( 401 == $result['response']['code'] ) {
186
  $response['error'] = __( 'There was an error subscribing to Hatchbuck. The API key is invalid.', 'fl-builder' );
187
  return $response; // Invalid API key.
188
- } // End if().
189
- elseif ( 200 == $result['response']['code'] ) {
190
  $result_data = json_decode( $result['body'] );
191
  $contact_id = $result_data[0]->contactId;
192
  } // Generic error. Contact not found should be 400.
@@ -231,7 +229,7 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
231
  $result_data = json_decode( $result['body'] );
232
  // @codingStandardsIgnoreLine
233
  $contact_id = $result_data->contactId;
234
- }// End if().
235
 
236
  // Add the tag to the contact.
237
  $result = wp_remote_post( $this->api_url . $contact_id . '/Tags?api_key=' . $account_data['api_key'], array(
@@ -246,7 +244,7 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
246
  ),
247
  ) ),
248
  ) );
249
- }// End if().
250
 
251
  return $response;
252
  }
45
  // Make sure we have an API key.
46
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
47
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
48
+ } else {
 
49
 
50
  $result = wp_remote_post( $this->api_url . 'search?api_key=' . $fields['api_key'], array(
51
  'method' => 'POST',
184
  if ( 401 == $result['response']['code'] ) {
185
  $response['error'] = __( 'There was an error subscribing to Hatchbuck. The API key is invalid.', 'fl-builder' );
186
  return $response; // Invalid API key.
187
+ } elseif ( 200 == $result['response']['code'] ) {
 
188
  $result_data = json_decode( $result['body'] );
189
  $contact_id = $result_data[0]->contactId;
190
  } // Generic error. Contact not found should be 400.
229
  $result_data = json_decode( $result['body'] );
230
  // @codingStandardsIgnoreLine
231
  $contact_id = $result_data->contactId;
232
+ }
233
 
234
  // Add the tag to the contact.
235
  $result = wp_remote_post( $this->api_url . $contact_id . '/Tags?api_key=' . $account_data['api_key'], array(
244
  ),
245
  ) ),
246
  ) );
247
+ }
248
 
249
  return $response;
250
  }
classes/class-fl-builder-service-icontact-pro.php CHANGED
@@ -75,8 +75,7 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
75
  // Make sure we have a username.
76
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
77
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
78
- } // End if().
79
- elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
80
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
81
  } // Make sure we have an app password.
82
  elseif ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
@@ -312,7 +311,7 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
312
  $errors = $api->getErrors();
313
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact Pro. %s', 'fl-builder' ), $errors[0] );
314
  }
315
- }// End if().
316
 
317
  return $response;
318
  }
75
  // Make sure we have a username.
76
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
77
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
78
+ } elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
 
79
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
80
  } // Make sure we have an app password.
81
  elseif ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
311
  $errors = $api->getErrors();
312
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact Pro. %s', 'fl-builder' ), $errors[0] );
313
  }
314
+ }
315
 
316
  return $response;
317
  }
classes/class-fl-builder-service-icontact.php CHANGED
@@ -71,8 +71,7 @@ final class FLBuilderServiceIContact extends FLBuilderService {
71
  // Make sure we have a username.
72
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
73
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
74
- } // End if().
75
- elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
76
  $response['error'] = __( 'Error: You must provide a app ID.', 'fl-builder' );
77
  } // Make sure we have an app password.
78
  elseif ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
@@ -273,7 +272,7 @@ final class FLBuilderServiceIContact extends FLBuilderService {
273
  $errors = $api->getErrors();
274
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact. %s', 'fl-builder' ), $errors[0] );
275
  }
276
- }// End if().
277
 
278
  return $response;
279
  }
71
  // Make sure we have a username.
72
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
73
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
74
+ } elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
 
75
  $response['error'] = __( 'Error: You must provide a app ID.', 'fl-builder' );
76
  } // Make sure we have an app password.
77
  elseif ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
272
  $errors = $api->getErrors();
273
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact. %s', 'fl-builder' ), $errors[0] );
274
  }
275
+ }
276
 
277
  return $response;
278
  }
classes/class-fl-builder-service-infusionsoft.php CHANGED
@@ -74,8 +74,7 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
74
  // Make sure we have an API key.
75
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
76
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
77
- } // End if().
78
- elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
79
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
80
  } // Try to connect and store the connection data.
81
  else {
@@ -283,8 +282,8 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
283
  $e->getMessage()
284
  );
285
  }
286
- }// End if().
287
- }// End if().
288
 
289
  return $response;
290
  }
74
  // Make sure we have an API key.
75
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
76
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
77
+ } elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
 
78
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
79
  } // Try to connect and store the connection data.
80
  else {
282
  $e->getMessage()
283
  );
284
  }
285
+ }
286
+ }
287
 
288
  return $response;
289
  }
classes/class-fl-builder-service-madmimi.php CHANGED
@@ -65,8 +65,7 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
65
  // Make sure we have an email address.
66
  if ( ! isset( $fields['api_email'] ) || empty( $fields['api_email'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an email address.', 'fl-builder' );
68
- } // End if().
69
- elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
70
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
71
  } // Try to connect and store the connection data.
72
  else {
65
  // Make sure we have an email address.
66
  if ( ! isset( $fields['api_email'] ) || empty( $fields['api_email'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an email address.', 'fl-builder' );
68
+ } elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
69
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
70
  } // Try to connect and store the connection data.
71
  else {
classes/class-fl-builder-service-mailchimp.php CHANGED
@@ -63,17 +63,20 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
- } // End if().
67
- else {
68
-
69
- $api = $this->get_api( $fields['api_key'] );
70
 
71
  try {
72
- $api->helper->ping();
73
- $response['data'] = array(
74
- 'api_key' => $fields['api_key'],
75
- );
76
- } catch ( Mailchimp_Invalid_ApiKey $e ) {
 
 
 
 
 
 
77
  $response['error'] = $e->getMessage();
78
  }
79
  }
@@ -118,7 +121,6 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
118
  public function render_fields( $account, $settings ) {
119
  $post_data = FLBuilderModel::get_post_data();
120
  $account_data = $this->get_account_data( $account );
121
- $api = $this->get_api( $account_data['api_key'] );
122
  $response = array(
123
  'error' => false,
124
  'html' => '',
@@ -126,12 +128,13 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
126
 
127
  // Lists field
128
  try {
 
129
 
130
  if ( ! isset( $post_data['list_id'] ) ) {
131
- $lists = $api->lists->getList();
132
  $response['html'] .= $this->render_list_field( $lists, $settings );
133
  }
134
- } catch ( Mailchimp_Error $e ) {
135
  $response['error'] = $e->getMessage();
136
  }
137
 
@@ -146,10 +149,10 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
146
  $list_id = $settings->list_id;
147
  }
148
 
149
- $groups = $api->lists->interestGroupings( $list_id );
150
  $response['html'] .= $this->render_groups_field( $list_id, $groups, $settings );
151
  }
152
- } catch ( Mailchimp_Error $e ) {}
153
 
154
  return $response;
155
  }
@@ -170,8 +173,10 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
170
  '' => __( 'Choose...', 'fl-builder' ),
171
  );
172
 
173
- foreach ( $lists['data'] as $list ) {
174
- $options[ $list['id'] ] = $list['name'];
 
 
175
  }
176
 
177
  FLBuilder::render_settings_field( 'list_id', array(
@@ -211,7 +216,7 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
211
 
212
  foreach ( $groups as $group ) {
213
  foreach ( $group['groups'] as $subgroup ) {
214
- $options[ $list_id . '_' . $group['id'] . '_' . $subgroup['id'] ] = $group['name'] . ' - ' . $subgroup['name'];
215
  }
216
  }
217
 
@@ -251,103 +256,91 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
251
  $response['error'] = __( 'There was an error subscribing to MailChimp. The account is no longer connected.', 'fl-builder' );
252
  } else {
253
 
254
- $api = $this->get_api( $account_data['api_key'] );
255
- $double = apply_filters( 'fl_builder_mailchimp_double_option', false );
256
- $welcome = apply_filters( 'fl_builder_mailchimp_welcome', true );
257
- $email = array(
258
- 'email' => $email,
259
- );
260
- $data = array();
261
 
262
- // Name
263
- if ( $name ) {
264
 
265
- $names = explode( ' ', $name );
266
 
267
- if ( isset( $names[0] ) ) {
268
- $data['FNAME'] = $names[0];
269
- }
270
- if ( isset( $names[1] ) ) {
271
- $data['LNAME'] = $names[1];
 
272
  }
273
- }
274
 
275
- // Groups
276
- if ( isset( $settings->groups ) && is_array( $settings->groups ) ) {
277
 
278
- $groups = array();
279
 
280
- // Build the array of saved group data.
281
- for ( $i = 0; $i < count( $settings->groups ); $i++ ) {
282
 
283
- if ( empty( $settings->groups[ $i ] ) ) {
284
- continue;
285
- }
286
-
287
- $group_data = explode( '_', $settings->groups[ $i ] );
288
 
289
- if ( $group_data[0] != $settings->list_id ) {
290
- continue;
291
- }
292
- if ( ! isset( $groups[ $group_data[1] ] ) ) {
293
- $groups[ $group_data[1] ] = array();
294
- }
295
 
296
- $groups[ $group_data[1] ][] = $group_data[2];
297
- }
 
 
 
 
298
 
299
- // Get the subgroup names from the API and add to the $data array.
300
- if ( count( $groups ) > 0 ) {
301
 
302
- $groups_result = $api->lists->interestGroupings( $settings->list_id );
 
303
 
304
- if ( is_array( $groups_result ) && count( $groups_result ) > 0 ) {
 
305
 
306
- foreach ( $groups_result as $group ) {
307
 
308
- if ( ! isset( $groups[ $group['id'] ] ) ) {
309
- continue;
310
- }
311
 
312
- $subgroup_names = array();
 
 
313
 
314
- foreach ( $group['groups'] as $subgroup ) {
315
 
316
- if ( in_array( $subgroup['id'], $groups[ $group['id'] ] ) ) {
317
- $subgroup_names[] = $subgroup['name'];
 
318
  }
319
  }
320
-
321
- if ( 0 === count( $subgroup_names ) ) {
322
- unset( $groups[ $group['id'] ] );
323
- } else {
324
- $groups[ $group['id'] ] = $subgroup_names;
325
- }
326
  }
327
 
328
- $i = 0;
329
 
330
- foreach ( $groups as $group_id => $subgroups ) {
331
- $data['groupings'][ $i ]['id'] = $group_id;
332
- $data['groupings'][ $i ]['groups'] = $subgroups;
333
- $i++;
334
- }
335
  }
336
- }// End if().
337
- }// End if().
338
 
339
- // Subscribe
340
- try {
341
- $api->lists->subscribe( $settings->list_id, $email, $data, 'html', (bool) $double, true, false, (bool) $welcome );
342
- } catch ( Mailchimp_List_AlreadySubscribed $e ) {
343
- return $response;
344
- } catch ( Mailchimp_Error $e ) {
345
- $response['error'] = sprintf(
346
- __( 'There was an error subscribing to MailChimp. %s', 'fl-builder' ),
347
- $e->getMessage()
348
- );
349
- }
350
- }// End if().
351
 
352
  return $response;
353
  }
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
+ } else {
 
 
 
67
 
68
  try {
69
+ $api = $this->get_api( $fields['api_key'] );
70
+
71
+ $ping = $api->get( 'ping' );
72
+ if ( ! isset( $ping['health_status'] ) && isset( $ping['title'] ) ) {
73
+ $response['error'] = $ping['title'];
74
+ } else {
75
+ $response['data'] = array(
76
+ 'api_key' => $fields['api_key'],
77
+ );
78
+ }
79
+ } catch ( Exception $e ) {
80
  $response['error'] = $e->getMessage();
81
  }
82
  }
121
  public function render_fields( $account, $settings ) {
122
  $post_data = FLBuilderModel::get_post_data();
123
  $account_data = $this->get_account_data( $account );
 
124
  $response = array(
125
  'error' => false,
126
  'html' => '',
128
 
129
  // Lists field
130
  try {
131
+ $api = $this->get_api( $account_data['api_key'] );
132
 
133
  if ( ! isset( $post_data['list_id'] ) ) {
134
+ $lists = $api->getLists();
135
  $response['html'] .= $this->render_list_field( $lists, $settings );
136
  }
137
+ } catch ( Exception $e ) {
138
  $response['error'] = $e->getMessage();
139
  }
140
 
149
  $list_id = $settings->list_id;
150
  }
151
 
152
+ $groups = $api->interestGroupings( $list_id );
153
  $response['html'] .= $this->render_groups_field( $list_id, $groups, $settings );
154
  }
155
+ } catch ( Exception $e ) {}
156
 
157
  return $response;
158
  }
173
  '' => __( 'Choose...', 'fl-builder' ),
174
  );
175
 
176
+ if ( is_array( $lists ) && count( $lists ) > 0 ) {
177
+ foreach ( $lists as $list ) {
178
+ $options[ $list['id'] ] = $list['name'];
179
+ }
180
  }
181
 
182
  FLBuilder::render_settings_field( 'list_id', array(
216
 
217
  foreach ( $groups as $group ) {
218
  foreach ( $group['groups'] as $subgroup ) {
219
+ $options[ $list_id . '_' . $group['id'] . '_' . $subgroup['id'] ] = $group['title'] . ' - ' . $subgroup['name'];
220
  }
221
  }
222
 
256
  $response['error'] = __( 'There was an error subscribing to MailChimp. The account is no longer connected.', 'fl-builder' );
257
  } else {
258
 
259
+ try {
260
+ $api = $this->get_api( $account_data['api_key'] );
261
+ $double = apply_filters( 'fl_builder_mailchimp_double_option', false );
262
+ $data = array(
263
+ 'email' => $email,
264
+ 'double_optin' => (bool) $double,
265
+ );
266
 
267
+ // Name
268
+ if ( $name ) {
269
 
270
+ $names = explode( ' ', $name );
271
 
272
+ if ( isset( $names[0] ) ) {
273
+ $data['FNAME'] = $names[0];
274
+ }
275
+ if ( isset( $names[1] ) ) {
276
+ $data['LNAME'] = $names[1];
277
+ }
278
  }
 
279
 
280
+ // Groups
281
+ if ( isset( $settings->groups ) && is_array( $settings->groups ) ) {
282
 
283
+ $groups = array();
284
 
285
+ // Build the array of saved group data.
286
+ for ( $i = 0; $i < count( $settings->groups ); $i++ ) {
287
 
288
+ if ( empty( $settings->groups[ $i ] ) ) {
289
+ continue;
290
+ }
 
 
291
 
292
+ $group_data = explode( '_', $settings->groups[ $i ] );
 
 
 
 
 
293
 
294
+ if ( $group_data[0] != $settings->list_id ) {
295
+ continue;
296
+ }
297
+ if ( ! isset( $groups[ $group_data[1] ] ) ) {
298
+ $groups[ $group_data[1] ] = array();
299
+ }
300
 
301
+ $groups[ $group_data[1] ][] = $group_data[2];
302
+ }
303
 
304
+ // Get the subgroup names from the API and add to the $data array.
305
+ if ( count( $groups ) > 0 ) {
306
 
307
+ $subgroup_ids = array();
308
+ $groups_result = $api->interestGroupings( $settings->list_id );
309
 
310
+ if ( is_array( $groups_result ) && count( $groups_result ) > 0 ) {
311
 
312
+ foreach ( $groups_result as $group ) {
 
 
313
 
314
+ if ( ! isset( $groups[ $group['id'] ] ) ) {
315
+ continue;
316
+ }
317
 
318
+ foreach ( $group['groups'] as $subgroup ) {
319
 
320
+ if ( in_array( $subgroup['id'], $groups[ $group['id'] ] ) ) {
321
+ $subgroup_ids[ $subgroup['id'] ] = true;
322
+ }
323
  }
324
  }
 
 
 
 
 
 
325
  }
326
 
327
+ $data['groups'] = $subgroup_ids;
328
 
 
 
 
 
 
329
  }
330
+ }
 
331
 
332
+ $api->subscribe( $settings->list_id, $data );
333
+
334
+ if ( $api->getLastError() ) {
335
+ $response['error'] = sprintf(
336
+ __( 'There was an error subscribing to MailChimp. %s', 'fl-builder' ),
337
+ $api->getLastError()
338
+ );
339
+ }
340
+ } catch ( Exception $e ) {
341
+ $response['error'] = $e->getMessage();
342
+ }// Try catch().
343
+ }
344
 
345
  return $response;
346
  }
classes/class-fl-builder-service-mailerlite.php CHANGED
@@ -72,8 +72,7 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
72
  // Make sure we have an API token.
73
  if ( ! isset( $fields['api_key'] ) ) {
74
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
75
- } // End if().
76
- else {
77
 
78
  $api = $this->get_api( $fields['api_key'] );
79
  $api->setPath( 'groups' );
@@ -233,12 +232,12 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
233
  // Add new
234
  $api->setPath( 'groups/' . $settings->list_id . '/subscribers' );
235
  $api->add( $data );
236
- $response = $api->getResponseInfo();
237
 
238
- if ( 200 !== $response['http_code'] ) {
239
- $response['error'] = sprintf( __( 'There was an error subscribing to MailerLite. Code: %s', 'fl-builder' ), $response['http_code'] );
240
  }
241
- }// End if().
242
 
243
  return $response;
244
  }
72
  // Make sure we have an API token.
73
  if ( ! isset( $fields['api_key'] ) ) {
74
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
75
+ } else {
 
76
 
77
  $api = $this->get_api( $fields['api_key'] );
78
  $api->setPath( 'groups' );
232
  // Add new
233
  $api->setPath( 'groups/' . $settings->list_id . '/subscribers' );
234
  $api->add( $data );
235
+ $result = $api->getResponseInfo();
236
 
237
+ if ( 200 !== $result['http_code'] ) {
238
+ $response['error'] = sprintf( __( 'There was an error subscribing to MailerLite. Code: %s', 'fl-builder' ), $result['http_code'] );
239
  }
240
+ }
241
 
242
  return $response;
243
  }
classes/class-fl-builder-service-mailpoet.php CHANGED
@@ -193,8 +193,8 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
193
  if ( false !== $errors ) {
194
  $response['error'] = sprintf( __( 'There was an error subscribing to MailPoet. %s', 'fl-builder' ), $errors[0] );
195
  }
196
- }// End if().
197
- }// End if().
198
 
199
  return $response;
200
  }
193
  if ( false !== $errors ) {
194
  $response['error'] = sprintf( __( 'There was an error subscribing to MailPoet. %s', 'fl-builder' ), $errors[0] );
195
  }
196
+ }
197
+ }
198
 
199
  return $response;
200
  }
classes/class-fl-builder-service-mailrelay.php CHANGED
@@ -75,8 +75,7 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
75
  // Make sure we have the Host.
76
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
77
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
78
- } // End if().
79
- elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
80
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
81
  } // Try to connect and store the connection data.
82
  else {
75
  // Make sure we have the Host.
76
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
77
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
78
+ } elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
79
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
80
  } // Try to connect and store the connection data.
81
  else {
classes/class-fl-builder-service-mautic.php CHANGED
@@ -74,7 +74,7 @@ final class FLBuilderServiceMautic extends FLBuilderService {
74
  }
75
  // Make sure we have a username
76
  if ( ! isset( $fields['api_username'] ) || empty( $fields['api_username'] ) ) {
77
- $response['error'] = __( 'Error: You must provide you Mautic app username.', 'fl-builder' );
78
  }
79
  // Make sure we have password
80
  if ( ! isset( $fields['api_password'] ) || empty( $fields['api_password'] ) ) {
@@ -140,7 +140,7 @@ final class FLBuilderServiceMautic extends FLBuilderService {
140
  'class' => 'fl-builder-service-connect-input',
141
  'type' => 'text',
142
  'label' => __( 'Mautic Username', 'fl-builder' ),
143
- 'help' => __( 'Username from your Mautic application. Make sure it has `Full system access`. Best practise would be to set up a new user for each external site.', 'fl-builder' ),
144
  'preview' => array(
145
  'type' => 'none',
146
  ),
74
  }
75
  // Make sure we have a username
76
  if ( ! isset( $fields['api_username'] ) || empty( $fields['api_username'] ) ) {
77
+ $response['error'] = __( 'Error: You must provide your Mautic app username.', 'fl-builder' );
78
  }
79
  // Make sure we have password
80
  if ( ! isset( $fields['api_password'] ) || empty( $fields['api_password'] ) ) {
140
  'class' => 'fl-builder-service-connect-input',
141
  'type' => 'text',
142
  'label' => __( 'Mautic Username', 'fl-builder' ),
143
+ 'help' => __( 'Username from your Mautic application. Make sure it has `Full system access`. Best practice would be to set up a new user for each external site.', 'fl-builder' ),
144
  'preview' => array(
145
  'type' => 'none',
146
  ),
classes/class-fl-builder-service-sendinblue.php CHANGED
@@ -63,8 +63,7 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
63
  // Make sure we have an access key.
64
  if ( ! isset( $fields['access_key'] ) || empty( $fields['access_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an Access Key.', 'fl-builder' );
66
- } // End if().
67
- else {
68
 
69
  $api = $this->get_api( $fields['access_key'] );
70
  $result = $api->get_account();
63
  // Make sure we have an access key.
64
  if ( ! isset( $fields['access_key'] ) || empty( $fields['access_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an Access Key.', 'fl-builder' );
66
+ } else {
 
67
 
68
  $api = $this->get_api( $fields['access_key'] );
69
  $result = $api->get_account();
classes/class-fl-builder-service-sendy.php CHANGED
@@ -72,8 +72,7 @@ final class FLBuilderServiceSendy extends FLBuilderService {
72
  // Make sure we have the list ID.
73
  if ( ! isset( $fields['list_id'] ) || empty( $fields['list_id'] ) ) {
74
  $response['error'] = __( 'Error: You must provide a list ID.', 'fl-builder' );
75
- } // End if().
76
- else {
77
 
78
  $api = $this->get_api( array(
79
  'installation_url' => $fields['api_host'],
72
  // Make sure we have the list ID.
73
  if ( ! isset( $fields['list_id'] ) || empty( $fields['list_id'] ) ) {
74
  $response['error'] = __( 'Error: You must provide a list ID.', 'fl-builder' );
75
+ } else {
 
76
 
77
  $api = $this->get_api( array(
78
  'installation_url' => $fields['api_host'],
classes/class-fl-builder-services.php CHANGED
@@ -147,8 +147,7 @@ final class FLBuilderServices {
147
  // Return all services.
148
  if ( ! $type ) {
149
  $services = self::$services_data;
150
- } // End if().
151
- else {
152
 
153
  foreach ( self::$services_data as $key => $service ) {
154
  if ( $service['type'] == $type ) {
@@ -279,8 +278,7 @@ final class FLBuilderServices {
279
  // Render the settings to connect a new account.
280
  if ( isset( $post_data['add_new'] ) || ! isset( $saved_services[ $service ] ) ) {
281
  $response['html'] = self::render_connect_settings( $service );
282
- } // End if().
283
- else {
284
  $account = isset( $settings->service_account ) ? $settings->service_account : '';
285
  $response['html'] = self::render_account_settings( $service, $account );
286
  }
147
  // Return all services.
148
  if ( ! $type ) {
149
  $services = self::$services_data;
150
+ } else {
 
151
 
152
  foreach ( self::$services_data as $key => $service ) {
153
  if ( $service['type'] == $type ) {
278
  // Render the settings to connect a new account.
279
  if ( isset( $post_data['add_new'] ) || ! isset( $saved_services[ $service ] ) ) {
280
  $response['html'] = self::render_connect_settings( $service );
281
+ } else {
 
282
  $account = isset( $settings->service_account ) ? $settings->service_account : '';
283
  $response['html'] = self::render_account_settings( $service, $account );
284
  }
classes/class-fl-builder-shortcodes.php CHANGED
@@ -52,6 +52,12 @@ final class FLBuilderShortcodes {
52
  return;
53
  }
54
 
 
 
 
 
 
 
55
  // Render and return the layout.
56
  ob_start();
57
 
52
  return;
53
  }
54
 
55
+ $render = apply_filters( 'fl_builder_insert_layout_render', true, $attrs, $args );
56
+
57
+ if ( ! $render ) {
58
+ return;
59
+ }
60
+
61
  // Render and return the layout.
62
  ob_start();
63
 
classes/class-fl-builder-ui-content-panel.php CHANGED
@@ -142,11 +142,32 @@ class FLBuilderUIContentPanel {
142
  'templateName' => 'fl-content-panel-col-groups-view',
143
  );
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  // Row Templates View
146
  $templates = FLBuilderModel::get_row_templates_data();
147
  $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
148
 
149
- if ( ! $is_row_template && isset( $templates['groups'] ) && ! empty( $templates['groups'] ) ) {
150
 
151
  $data['views'][] = array(
152
  'type' => 'separator',
@@ -186,7 +207,7 @@ class FLBuilderUIContentPanel {
186
  );
187
  }
188
  }
189
- }// End if().
190
 
191
  return $data;
192
  }
@@ -201,9 +222,10 @@ class FLBuilderUIContentPanel {
201
  private static function get_templates_tab_data() {
202
  $enabled = FLBuilderModel::get_enabled_templates();
203
  $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
 
204
  $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
205
  $data = array(
206
- 'should_display' => ( ! $is_module_template && ! $is_row_template && 'disabled' !== $enabled ),
207
  'views' => array(),
208
  );
209
 
@@ -287,6 +309,13 @@ class FLBuilderUIContentPanel {
287
  $data['template'][] = $template;
288
  }
289
 
 
 
 
 
 
 
 
290
  $static_rows = FLBuilderModel::get_row_templates_data();
291
  $row_templates = $static_rows['templates'];
292
 
142
  'templateName' => 'fl-content-panel-col-groups-view',
143
  );
144
 
145
+ $is_column_template = FLBuilderModel::is_post_user_template( 'column' );
146
+
147
+ if ( ! $is_column_template ) {
148
+ $data['views'][] = array(
149
+ 'type' => 'separator',
150
+ );
151
+
152
+ // Columns View
153
+ $data['views'][] = array(
154
+ 'handle' => 'savedColumns',
155
+ 'name' => __( 'Saved Columns', 'fl-builder' ),
156
+ 'query' => array(
157
+ 'kind' => 'template',
158
+ 'type' => 'user',
159
+ 'content' => 'column',
160
+ 'categorized' => true,
161
+ ),
162
+ 'templateName' => 'fl-content-panel-saved-columns',
163
+ );
164
+ }
165
+
166
  // Row Templates View
167
  $templates = FLBuilderModel::get_row_templates_data();
168
  $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
169
 
170
+ if ( ! $is_row_template && ! $is_column_template && isset( $templates['groups'] ) && ! empty( $templates['groups'] ) ) {
171
 
172
  $data['views'][] = array(
173
  'type' => 'separator',
207
  );
208
  }
209
  }
210
+ }
211
 
212
  return $data;
213
  }
222
  private static function get_templates_tab_data() {
223
  $enabled = FLBuilderModel::get_enabled_templates();
224
  $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
225
+ $is_column_template = FLBuilderModel::is_post_user_template( 'column' );
226
  $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
227
  $data = array(
228
+ 'should_display' => ( ! $is_module_template && ! $is_column_template && ! $is_row_template && 'disabled' !== $enabled ),
229
  'views' => array(),
230
  );
231
 
309
  $data['template'][] = $template;
310
  }
311
 
312
+ $static_columns = FLBuilderModel::get_column_templates_data();
313
+ $column_templates = $static_columns['templates'];
314
+
315
+ foreach ( $column_templates as $template ) {
316
+ $data['template'][] = $template;
317
+ }
318
+
319
  $static_rows = FLBuilderModel::get_row_templates_data();
320
  $row_templates = $static_rows['templates'];
321
 
classes/class-fl-builder-ui-settings-forms.php CHANGED
@@ -21,10 +21,84 @@ class FLBuilderUISettingsForms {
21
  * @return void
22
  */
23
  static public function init() {
 
 
24
  add_action( 'wp_footer', __CLASS__ . '::init_js_config', 1 );
25
  add_action( 'wp_footer', __CLASS__ . '::render_js_templates', 11 );
26
  }
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /**
29
  * Initializes the JS config by calling the get method early on
30
  * wp_footer (before the UI renders). This needs to be done so
@@ -37,10 +111,12 @@ class FLBuilderUISettingsForms {
37
  */
38
  static public function init_js_config() {
39
  self::get_js_config();
 
40
  }
41
 
42
  /**
43
- * Returns _all_ JS config for settings forms.
 
44
  *
45
  * @since 2.0
46
  * @return array
@@ -48,7 +124,7 @@ class FLBuilderUISettingsForms {
48
  static public function get_js_config() {
49
  return array(
50
  'forms' => self::prep_forms_for_js_config( FLBuilderModel::$settings_forms ),
51
- 'modules' => self::prep_module_forms_for_js_config(),
52
  'nodes' => self::prep_node_settings_for_js_config(),
53
  'attachments' => self::prep_attachments_for_js_config(),
54
  'settings' => array(
@@ -64,6 +140,18 @@ class FLBuilderUISettingsForms {
64
  );
65
  }
66
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  /**
68
  * Returns only the node JS config for settings forms.
69
  *
@@ -145,7 +233,7 @@ class FLBuilderUISettingsForms {
145
  }
146
  }
147
  }
148
- }// End foreach().
149
 
150
  return $forms;
151
  }
@@ -209,6 +297,53 @@ class FLBuilderUISettingsForms {
209
  return self::prep_forms_for_js_config( $module_forms );
210
  }
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  /**
213
  * Gathers and prepares node settings for the JS config.
214
  *
@@ -288,7 +423,7 @@ class FLBuilderUISettingsForms {
288
  }
289
  }
290
  }
291
- }// End foreach().
292
 
293
  return $attachments;
294
  }
@@ -688,9 +823,9 @@ class FLBuilderUISettingsForms {
688
  echo '<tr class="fl-builder-field-multiple" data-field="' . $arr_name . '">';
689
  include FL_BUILDER_DIR . 'includes/ui-legacy-custom-field.php';
690
  echo '<td class="fl-builder-field-actions">';
691
- echo '<i class="fl-builder-field-move fa fa-arrows"></i>';
692
- echo '<i class="fl-builder-field-copy fa fa-copy"></i>';
693
- echo '<i class="fl-builder-field-delete fa fa-times"></i>';
694
  echo '</td>';
695
  echo '</tr>';
696
  }
@@ -711,9 +846,9 @@ class FLBuilderUISettingsForms {
711
  echo '<tr id="fl-field-' . $name . '" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
712
  include FL_BUILDER_DIR . 'includes/ui-legacy-custom-field.php';
713
  echo '</tr>';
714
- }// End if().
715
- }// End if().
716
- }// End if().
717
 
718
  /**
719
  * Renders the markup for the icon selector.
21
  * @return void
22
  */
23
  static public function init() {
24
+ add_action( 'wp', __CLASS__ . '::render_settings_config' );
25
+ add_action( 'wp_enqueue_scripts', __CLASS__ . '::enqueue_settings_config', 11 );
26
  add_action( 'wp_footer', __CLASS__ . '::init_js_config', 1 );
27
  add_action( 'wp_footer', __CLASS__ . '::render_js_templates', 11 );
28
  }
29
 
30
+ /**
31
+ * Adds an inline script for general settings config and
32
+ * one for module settings config.
33
+ *
34
+ * @since 2.0.7
35
+ * @return void
36
+ */
37
+ static public function enqueue_settings_config() {
38
+ global $wp_the_query;
39
+
40
+ if ( FLBuilderModel::is_builder_active() ) {
41
+
42
+ $url = FLBuilderModel::get_edit_url( $wp_the_query->post->ID ) . '&fl_builder_load_settings_config';
43
+ $script = 'var s = document.createElement("script");s.type = "text/javascript";s.src = "%s";document.head.appendChild(s);';
44
+ $config = sprintf( $script, $url );
45
+ $modules = sprintf( $script, $url . '=modules' );
46
+
47
+ wp_add_inline_script( 'fl-builder', $config );
48
+ wp_add_inline_script( 'fl-builder-min', $config );
49
+ wp_add_inline_script( 'fl-builder', $modules );
50
+ wp_add_inline_script( 'fl-builder-min', $modules );
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Renders the JS config for settings forms for the current page if requested
56
+ * and dies early so it can be loaded from a script tag.
57
+ *
58
+ * @since 2.0.7
59
+ * @return void
60
+ */
61
+ static public function render_settings_config() {
62
+ if ( FLBuilderModel::is_builder_active() && isset( $_GET['fl_builder_load_settings_config'] ) ) {
63
+
64
+ $type = sanitize_key( $_GET['fl_builder_load_settings_config'] );
65
+ $handler = 'FLBuilderUISettingsForms::compress_settings_config';
66
+
67
+ if ( 'modules' === $type ) {
68
+ $settings = FLBuilderUISettingsForms::get_modules_js_config();
69
+ } else {
70
+ $settings = FLBuilderUISettingsForms::get_js_config();
71
+ }
72
+
73
+ if ( @ini_get( 'zlib.output_compression' ) ) { // @codingStandardsIgnoreLine
74
+ @ini_set( 'zlib.output_compression', 'Off' ); // @codingStandardsIgnoreLine
75
+ $handler = null;
76
+ }
77
+ header( 'Content-Type: application/javascript' );
78
+
79
+ ob_start( $handler );
80
+ include FL_BUILDER_DIR . 'includes/ui-settings-config.php';
81
+ ob_end_flush();
82
+
83
+ die();
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Attempts to use the output buffer gzip handler to compress
89
+ * the settings config. We have to do it this way to prevent
90
+ * errors we were running into on some hosts.
91
+ *
92
+ * @since 2.1.0.2
93
+ * @param string $buffer
94
+ * @return string
95
+ */
96
+
97
+ static public function compress_settings_config( $buffer ) {
98
+ @ob_gzhandler( $buffer ); // @codingStandardsIgnoreLine
99
+ return $buffer;
100
+ }
101
+
102
  /**
103
  * Initializes the JS config by calling the get method early on
104
  * wp_footer (before the UI renders). This needs to be done so
111
  */
112
  static public function init_js_config() {
113
  self::get_js_config();
114
+ self::get_modules_js_config();
115
  }
116
 
117
  /**
118
+ * Returns the JS config for all settings forms except
119
+ * modules which are loaded in a separate request.
120
  *
121
  * @since 2.0
122
  * @return array
124
  static public function get_js_config() {
125
  return array(
126
  'forms' => self::prep_forms_for_js_config( FLBuilderModel::$settings_forms ),
127
+ 'editables' => self::prep_editables_for_js_config(),
128
  'nodes' => self::prep_node_settings_for_js_config(),
129
  'attachments' => self::prep_attachments_for_js_config(),
130
  'settings' => array(
140
  );
141
  }
142
 
143
+ /**
144
+ * Returns the JS config for all modules.
145
+ *
146
+ * @since 2.0.7
147
+ * @return array
148
+ */
149
+ static public function get_modules_js_config() {
150
+ return array(
151
+ 'modules' => self::prep_module_forms_for_js_config(),
152
+ );
153
+ }
154
+
155
  /**
156
  * Returns only the node JS config for settings forms.
157
  *
233
  }
234
  }
235
  }
236
+ }
237
 
238
  return $forms;
239
  }
297
  return self::prep_forms_for_js_config( $module_forms );
298
  }
299
 
300
+ /**
301
+ * Gathers and prepares inline module editing data for the JS config.
302
+ *
303
+ * @since 2.1
304
+ * @return array
305
+ */
306
+ static public function prep_editables_for_js_config() {
307
+ $editables = array();
308
+
309
+ foreach ( FLBuilderModel::$modules as $module ) {
310
+ $fields = FLBuilderModel::get_settings_form_fields( $module->form );
311
+
312
+ foreach ( $fields as $key => $field ) {
313
+
314
+ if ( 'code' === $field['type'] ) {
315
+ continue;
316
+ }
317
+
318
+ if ( ! isset( $field['preview'] ) ) {
319
+ continue;
320
+ }
321
+
322
+ if ( ! isset( $field['preview']['type'] ) || 'text' !== $field['preview']['type'] ) {
323
+ continue;
324
+ }
325
+
326
+ if ( ! isset( $field['preview']['selector'] ) ) {
327
+ continue;
328
+ }
329
+
330
+ if ( ! isset( $editables[ $module->slug ] ) ) {
331
+ $editables[ $module->slug ] = array();
332
+ }
333
+
334
+ $editables[ $module->slug ][ $key ] = array(
335
+ 'selector' => $field['preview']['selector'],
336
+ 'field' => array(
337
+ 'name' => $key,
338
+ 'type' => $field['type'],
339
+ ),
340
+ );
341
+ }
342
+ }
343
+
344
+ return $editables;
345
+ }
346
+
347
  /**
348
  * Gathers and prepares node settings for the JS config.
349
  *
423
  }
424
  }
425
  }
426
+ }
427
 
428
  return $attachments;
429
  }
823
  echo '<tr class="fl-builder-field-multiple" data-field="' . $arr_name . '">';
824
  include FL_BUILDER_DIR . 'includes/ui-legacy-custom-field.php';
825
  echo '<td class="fl-builder-field-actions">';
826
+ echo '<i class="fl-builder-field-move fas fa-arrows-alt"></i>';
827
+ echo '<i class="fl-builder-field-copy far fa-copy"></i>';
828
+ echo '<i class="fl-builder-field-delete fas fa-times"></i>';
829
  echo '</td>';
830
  echo '</tr>';
831
  }
846
  echo '<tr id="fl-field-' . $name . '" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
847
  include FL_BUILDER_DIR . 'includes/ui-legacy-custom-field.php';
848
  echo '</tr>';
849
+ }
850
+ }
851
+ }
852
 
853
  /**
854
  * Renders the markup for the icon selector.
classes/class-fl-builder-update.php CHANGED
@@ -43,8 +43,7 @@ final class FLBuilderUpdate {
43
  if ( ! $saved_version ) {
44
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
45
  return;
46
- } // End if().
47
- elseif ( ! version_compare( $saved_version, FL_BUILDER_VERSION, '=' ) ) {
48
 
49
  if ( is_multisite() ) {
50
  self::run_multisite( $saved_version );
@@ -53,6 +52,11 @@ final class FLBuilderUpdate {
53
  }
54
 
55
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
 
 
 
 
 
56
  }
57
  }
58
 
@@ -242,7 +246,7 @@ final class FLBuilderUpdate {
242
  update_post_meta( $meta->post_id, '_fl_builder_layout', $meta->meta_value );
243
  }
244
  }
245
- }// End if().
246
  }
247
 
248
  /**
@@ -306,7 +310,7 @@ final class FLBuilderUpdate {
306
  if ( is_array( $js ) ) {
307
  array_map( array( fl_builder_filesystem(), 'unlink' ), $js );
308
  }
309
- }// End if().
310
  }
311
 
312
  /**
43
  if ( ! $saved_version ) {
44
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
45
  return;
46
+ } elseif ( ! version_compare( $saved_version, FL_BUILDER_VERSION, '=' ) ) {
 
47
 
48
  if ( is_multisite() ) {
49
  self::run_multisite( $saved_version );
52
  }
53
 
54
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
55
+
56
+ update_site_option( '_fl_builder_update_info', array(
57
+ 'from' => $saved_version,
58
+ 'to' => FL_BUILDER_VERSION,
59
+ ) );
60
  }
61
  }
62
 
246
  update_post_meta( $meta->post_id, '_fl_builder_layout', $meta->meta_value );
247
  }
248
  }
249
+ }
250
  }
251
 
252
  /**
310
  if ( is_array( $js ) ) {
311
  array_map( array( fl_builder_filesystem(), 'unlink' ), $js );
312
  }
313
+ }
314
  }
315
 
316
  /**
classes/class-fl-builder-usage.php ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sends opt-in usage data
4
+ * @since 2.1
5
+ */
6
+ final class FLBuilderUsage {
7
+
8
+ protected static $url = 'http://stats.wpbeaverbuilder.com/';
9
+
10
+ protected static $seconds = 604800;
11
+
12
+ public static function init() {
13
+
14
+ $hook = is_network_admin() ? 'network_admin_notices' : 'admin_notices';
15
+
16
+ add_action( 'admin_init', array( 'FLBuilderUsage', 'enable_disable' ) );
17
+ add_action( 'init', array( 'FLBuilderUsage', 'set_schedule' ) );
18
+ add_action( $hook, array( 'FLBuilderUsage', 'render_notification' ) );
19
+ add_action( 'admin_enqueue_scripts', array( 'FLBuilderUsage', 'scripts' ) );
20
+ add_action( 'fl_builder_usage_event', array( 'FLBuilderUsage', 'send_stats' ) );
21
+ add_action( 'wp_ajax_fl_usage_toggle', array( 'FLBuilderUsage', 'callback' ) );
22
+ }
23
+
24
+ public static function callback() {
25
+
26
+ $enable = intval( $_POST['enable'] );
27
+
28
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'fl-usage' ) ) {
29
+ update_site_option( 'fl_builder_usage_enabled', $enable );
30
+ }
31
+
32
+ wp_die();
33
+ }
34
+
35
+ public static function scripts() {
36
+
37
+ wp_enqueue_style( 'fl-builder-admin-usage', FL_BUILDER_URL . 'css/fl-builder-admin-usage.css', array(), FL_BUILDER_VERSION );
38
+ wp_enqueue_script( 'fl-builder-admin-usage', FL_BUILDER_URL . 'js/fl-builder-admin-usage.js', array( 'jquery' ), FL_BUILDER_VERSION );
39
+ }
40
+
41
+ /**
42
+ * Add scheduled event
43
+ * @since 2.1
44
+ */
45
+ public static function set_schedule() {
46
+
47
+ if ( '1' == get_site_option( 'fl_builder_usage_enabled', false ) ) {
48
+ if ( ! wp_next_scheduled( 'fl_builder_usage_event' ) ) {
49
+ wp_schedule_single_event( time() + self::$seconds, 'fl_builder_usage_event' );
50
+ }
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Send stats callback
56
+ * @since 2.1
57
+ */
58
+ public static function send_stats() {
59
+
60
+ if ( ! get_site_option( 'fl_builder_usage_enabled', false ) ) {
61
+ return false;
62
+ }
63
+ $request = wp_remote_post( self::$url, array(
64
+ 'body' => json_encode( self::get_data() ),
65
+ ) );
66
+ }
67
+
68
+ /**
69
+ * Enable/disable
70
+ * @since 2.1
71
+ */
72
+ public static function enable_disable() {
73
+
74
+ if ( isset( $_GET['fl_usage'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'stats_enable' ) ) {
75
+ update_site_option( 'fl_builder_usage_enabled', $_GET['fl_usage'] );
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Render admin admin notice
81
+ * @since 2.1
82
+ */
83
+ public static function render_notification() {
84
+
85
+ if ( ! self::notification_enabled() ) {
86
+ return false;
87
+ }
88
+
89
+ wp_enqueue_script( 'jquery' );
90
+
91
+ $btn = sprintf( '<div class="buttons"><span class="button button-primary enable-stats">%s</span>&nbsp;<span class="button disable-stats">%s</span>%s</div>',
92
+ __( "Sure, I'll help", 'fl-builder' ),
93
+ __( 'No, Thank You', 'fl-builder' ),
94
+ wp_nonce_field( 'fl-usage', '_wpnonce', false )
95
+ );
96
+
97
+ $message = sprintf(
98
+ __( 'Would you like to help us improve %s by sending anonymous usage data?', 'fl-builder' ),
99
+ FLBuilderModel::get_branding()
100
+ );
101
+
102
+ echo '<div class="notice notice-info">';
103
+
104
+ echo '<div class="fl-usage">';
105
+
106
+ echo '<p>';
107
+
108
+ printf( '%s %s', $message, $btn );
109
+
110
+ echo '</p>';
111
+
112
+ printf( '</div>%s</div>', FLBuilderUsage::data_demo() );
113
+
114
+ }
115
+
116
+ /**
117
+ * Whether to show the stats settings in bb admin.
118
+ */
119
+ public static function show_settings() {
120
+
121
+ // super admin and network settings
122
+ if ( is_multisite() && is_super_admin() && is_network_admin() ) {
123
+ return true;
124
+ }
125
+
126
+ // single site admin
127
+ if ( ! is_multisite() && is_super_admin() ) {
128
+ return true;
129
+ }
130
+
131
+ return false;
132
+ }
133
+
134
+ /**
135
+ * Is notification enabled
136
+ * @since 2.1
137
+ * @return bool
138
+ */
139
+ private static function notification_enabled() {
140
+
141
+ global $pagenow;
142
+ $screen = get_current_screen();
143
+ $show = false;
144
+
145
+ if ( 'fl-builder-template' == $screen->post_type ) {
146
+ $show = true;
147
+ }
148
+
149
+ if ( 'fl-theme-layout' == $screen->post_type ) {
150
+ $show = true;
151
+ }
152
+
153
+ if ( 'options-general.php' == $pagenow && isset( $_GET['page'] ) && 'fl-builder-settings' == $_GET['page'] ) {
154
+ $show = true;
155
+ }
156
+
157
+ if ( 'dashboard-network' == $screen->id ) {
158
+ $show = true;
159
+ }
160
+
161
+ if ( '0' === get_site_option( 'fl_builder_usage_enabled' ) ) {
162
+ $show = false;
163
+ }
164
+
165
+ if ( ! is_super_admin() ) {
166
+ $show = false;
167
+ }
168
+
169
+ return ( $show && ! get_site_option( 'fl_builder_usage_enabled' ) ) ? true : false;
170
+ }
171
+
172
+ /**
173
+ * Show a user what kind of data we are collecting.
174
+ * @since 2.1
175
+ * @return string
176
+ */
177
+ public static function data_demo() {
178
+
179
+ $data = self::get_data( true );
180
+ $output = '';
181
+ $txt = '';
182
+ $settings = array(
183
+ 'server' => array(
184
+ 'name' => __( 'Server Type', 'fl-builder' ),
185
+ 'data' => $data['data']['server'],
186
+ ),
187
+ 'php' => array(
188
+ 'name' => __( 'PHP Version', 'fl-builder' ),
189
+ 'data' => $data['data']['php'],
190
+ ),
191
+ 'wp' => array(
192
+ 'name' => __( 'WP Version', 'fl-builder' ),
193
+ 'data' => $data['data']['wp'],
194
+ ),
195
+ 'mu' => array(
196
+ 'name' => __( 'WP Multisite', 'fl-builder' ),
197
+ 'data' => ( $data['data']['multisite'] ) ? 'Yes' : 'No',
198
+ ),
199
+ 'locale' => array(
200
+ 'name' => __( 'Locale', 'fl-builder' ),
201
+ 'data' => $data['data']['locale'],
202
+ ),
203
+ 'plugins' => array(
204
+ 'name' => __( 'Plugins Count', 'fl-builder' ),
205
+ 'data' => $data['data']['plugins'],
206
+ ),
207
+ 'modules' => array(
208
+ 'name' => __( 'Modules Used', 'fl-builder' ),
209
+ 'data' => __( 'Which modules are used and how many times.', 'fl-builder' ),
210
+ ),
211
+ 'settings' => array(
212
+ 'name' => __( 'Builder Settings', 'fl-builder' ),
213
+ 'data' => __( 'UI theme, pinned settings etc.' ),
214
+ ),
215
+ );
216
+
217
+ foreach ( $settings as $k => $data ) {
218
+ $txt .= sprintf( '<span class="usage-demo-left">%s</span><span class="usage-demo-right">: %s</span><br />', $data['name'], $data['data'] );
219
+ }
220
+
221
+ $output = sprintf( '<div class="usage-demo"><a class="stats-info" href="#">%s</a><div class="stats-info-data"><p>%s</p><p><em>%s</em></p></div></div>',
222
+ __( 'What kind of info will we collect?', 'fl-builder' ),
223
+ $txt,
224
+ __( 'We will never collect any private data such as IP, email addresses or usernames.', 'fl-builder' )
225
+ );
226
+
227
+ return $output;
228
+ }
229
+
230
+ /**
231
+ * Gather stats to send
232
+ * @since 2.1
233
+ * @return array
234
+ */
235
+ public static function get_data( $demo = false ) {
236
+
237
+ global $wp_version, $wpdb;
238
+
239
+ if ( ! function_exists( 'get_plugins' ) ) {
240
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
241
+ }
242
+
243
+ $data = array(
244
+ 'modules' => array(),
245
+ 'license' => array(),
246
+ 'themer' => array(
247
+ 'header' => 0,
248
+ 'footer' => 0,
249
+ 'part' => 0,
250
+ '404' => 0,
251
+ 'singular' => 0,
252
+ ),
253
+ 'pinned' => array(
254
+ 'left' => 0,
255
+ 'right' => 0,
256
+ 'unpinned' => 0,
257
+ ),
258
+ );
259
+ $users = count_users();
260
+ $plugins_data = get_plugins();
261
+ $data['plugins'] = count( $plugins_data );
262
+ $data['plugins_active'] = 0;
263
+
264
+ foreach ( (array) $plugins_data as $plugin_slug => $plugin ) {
265
+ if ( is_plugin_active( $plugin_slug ) ) {
266
+ $data['plugins_active'] ++;
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Setup an array of post types to query
272
+ */
273
+ $post_types = get_post_types( array(
274
+ 'public' => true,
275
+ '_builtin' => true,
276
+ ) );
277
+
278
+ if ( isset( $post_types['attachment'] ) ) {
279
+ unset( $post_types['attachment'] );
280
+ }
281
+ // $post_types['fl-builder-template'] = 'fl-builder-template';
282
+
283
+ /**
284
+ * Get a count of all posts/pages that are *not* builder enabled.
285
+ */
286
+ $args = array(
287
+ 'post_type' => $post_types,
288
+ 'post_status' => 'publish',
289
+ 'meta_query' => array(
290
+ 'key' => '_fl_builder_enabled',
291
+ 'value' => '1',
292
+ 'compare' => '!=',
293
+ ),
294
+ 'posts_per_page' => -1,
295
+ );
296
+ $query = new WP_Query( $args );
297
+ $data['not-enabled'] = count( $query->posts );
298
+
299
+ /**
300
+ * Get a count of all posts pages that are using the builder.
301
+ */
302
+ $args = array(
303
+ 'post_type' => $post_types,
304
+ 'post_status' => 'publish',
305
+ 'meta_key' => '_fl_builder_enabled',
306
+ 'meta_value' => '1',
307
+ 'posts_per_page' => -1,
308
+ );
309
+
310
+ $query = new WP_Query( $args );
311
+ $data['enabled'] = count( $query->posts );
312
+
313
+ /**
314
+ * Using the array of pages/posts using builder get a list of all used modules
315
+ */
316
+ if ( is_array( $query->posts ) && ! empty( $query->posts ) ) {
317
+ foreach ( $query->posts as $post ) {
318
+ $meta = get_post_meta( $post->ID, '_fl_builder_data', true );
319
+ foreach ( (array) $meta as $node_id => $node ) {
320
+ if ( @isset( $node->type ) && 'module' == $node->type ) { // @codingStandardsIgnoreLine
321
+ if ( ! isset( $data['modules'][ $node->settings->type ] ) ) {
322
+ $data['modules'][ $node->settings->type ] = 1;
323
+ } else {
324
+ $data['modules'][ $node->settings->type ] ++;
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+
331
+ // themer settings.
332
+ $args = array(
333
+ 'post_type' => 'fl-theme-layout',
334
+ 'post_status' => 'publish',
335
+ 'meta_key' => '_fl_builder_enabled',
336
+ 'meta_value' => '1',
337
+ 'posts_per_page' => -1,
338
+ );
339
+ $query = new WP_Query( $args );
340
+ $data['themer']['total'] = count( $query->posts );
341
+ if ( is_array( $query->posts ) && ! empty( $query->posts ) ) {
342
+ foreach ( $query->posts as $post ) {
343
+ $meta = get_post_meta( $post->ID );
344
+ if ( isset( $meta['_fl_theme_layout_type'] ) ) {
345
+ if ( ! isset( $data['themer'][ $meta['_fl_theme_layout_type'][0] ] ) ) {
346
+ $data['themer'][ $meta['_fl_theme_layout_type'][0] ] = 1;
347
+ } else {
348
+ $data['themer'][ $meta['_fl_theme_layout_type'][0] ] ++;
349
+ }
350
+ }
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Find all users that are using the builder.
356
+ */
357
+ $args = array(
358
+ 'meta_key' => 'fl_builder_user_settings',
359
+ 'meta_value' => 'null',
360
+ 'meta_compare' => '!=',
361
+ );
362
+ $query = new WP_User_Query( $args );
363
+
364
+ /**
365
+ * Using array of users collect their builder settings, pinned, skin etc.
366
+ */
367
+ if ( ! empty( $query->results ) ) {
368
+ foreach ( $query->results as $user ) {
369
+ $meta = get_user_meta( $user->ID, 'fl_builder_user_settings', true );
370
+ if ( isset( $meta['skin'] ) ) {
371
+ if ( ! isset( $data['skin'][ $meta['skin'] ] ) ) {
372
+ $data['skin'][ $meta['skin'] ] = 1;
373
+ } else {
374
+ $data['skin'][ $meta['skin'] ] ++;
375
+ }
376
+ }
377
+ if ( isset( $meta['pinned']['position'] ) ) {
378
+ if ( '' == $meta['pinned']['position'] ) {
379
+ if ( ! isset( $data['pinned']['unpinned'] ) ) {
380
+ $data['pinned']['unpinned'] = 1;
381
+ } else {
382
+ $data['pinned']['unpinned'] ++;
383
+ }
384
+ } else {
385
+ if ( ! isset( $data['pinned'][ $meta['pinned']['position'] ] ) ) {
386
+ $data['pinned'][ $meta['pinned']['position'] ] = 1;
387
+ } else {
388
+ $data['pinned'][ $meta['pinned']['position'] ] ++;
389
+ }
390
+ }
391
+ }
392
+ }
393
+ }
394
+
395
+ /**
396
+ * General data
397
+ */
398
+ $data['server'] = $_SERVER['SERVER_SOFTWARE'];
399
+ $data['database'] = ( ! empty( $wpdb->is_mysql ) ? $wpdb->db_version() : 'Unknown' );
400
+ $data['multisite'] = is_multisite() ? 'yes' : 'no';
401
+ $data['subsites'] = is_multisite() ? get_blog_count() : '';
402
+ $data['locale'] = get_locale();
403
+ $data['users'] = $users['total_users'];
404
+ $data['php'] = phpversion();
405
+ $data['wp'] = $wp_version;
406
+
407
+ $settings_orig = FLBuilderModel::get_global_settings();
408
+
409
+ $settings = clone $settings_orig;
410
+
411
+ // we dont need these
412
+ unset( $settings->js );
413
+ unset( $settings->css );
414
+
415
+ foreach ( $settings as $k => $setting ) {
416
+ $data['settings'][ $k ] = $setting;
417
+ }
418
+
419
+ $theme = wp_get_theme();
420
+ if ( $theme->get( 'Template' ) ) {
421
+ $parent = wp_get_theme( $theme->get( 'Template' ) );
422
+ $data['theme'] = $parent->get( 'Name' );
423
+ $data['theme_child'] = $theme->get( 'Name' );
424
+ } else {
425
+ $data['theme'] = $theme->get( 'Name' );
426
+ }
427
+
428
+ if ( class_exists( 'FLUpdater' ) && false == $demo ) {
429
+
430
+ $subscription = FLUpdater::get_subscription_info();
431
+
432
+ if ( ! $subscription->active ) {
433
+ $data['license'][] = 'none';
434
+ } else {
435
+ foreach ( (array) $subscription->subscriptions as $subscription ) {
436
+ if ( false !== strpos( $subscription->name, 'Beaver Builder' ) ) {
437
+ $data['license']['bb-plugin'] = $subscription->name;
438
+ }
439
+ if ( 'Beaver Themer Plugin' == $subscription->name ) {
440
+ $data['license']['bb-themer'] = $subscription->name;
441
+ }
442
+ }
443
+ }
444
+ } else {
445
+ $data['license'][] = 'none';
446
+ }
447
+
448
+ $output = array(
449
+ 'id' => md5( get_bloginfo( 'url' ) . get_bloginfo( 'admin_email' ) ),
450
+ 'data' => $data,
451
+ );
452
+ return $output;
453
+ }
454
+ }
455
+ FLBuilderUsage::init();
classes/class-fl-builder-user-access.php CHANGED
@@ -76,11 +76,7 @@ final class FLBuilderUserAccess {
76
  $groups = array();
77
  $settings = self::$registered_settings;
78
 
79
- /**
80
- * Sort the groups based on priority.
81
- * TODO update when were 5.3+ in PHP.
82
- */
83
- uasort( $settings, create_function( '$a,$b', 'return $a["order"] > $b["order"];' ) );
84
 
85
  foreach ( $settings as $key => $data ) {
86
 
@@ -92,6 +88,14 @@ final class FLBuilderUserAccess {
92
  return $groups;
93
  }
94
 
 
 
 
 
 
 
 
 
95
  /**
96
  * Returns the saved user access settings and merges in
97
  * any default roles that haven't been saved.
@@ -272,12 +276,20 @@ final class FLBuilderUserAccess {
272
  * @return void
273
  */
274
  static function register_default_settings() {
 
 
 
 
 
 
 
 
275
  self::register_setting( 'unrestricted_editing', array(
276
  'default' => 'all',
277
  'group' => __( 'Frontend', 'fl-builder' ),
278
  'label' => __( 'Unrestricted Editing', 'fl-builder' ),
279
- 'description' => __( 'The selected roles will have unrestricted access to all editing features.', 'fl-builder' ),
280
- 'order' => '1',
281
  ) );
282
  }
283
  }
76
  $groups = array();
77
  $settings = self::$registered_settings;
78
 
79
+ uasort( $settings, array( __CLASS__, 'sort' ) );
 
 
 
 
80
 
81
  foreach ( $settings as $key => $data ) {
82
 
88
  return $groups;
89
  }
90
 
91
+ /**
92
+ * Custom sort function instead of create_function which is deprecated in php 7.2
93
+ * @since 1.11
94
+ */
95
+ private static function sort( $a, $b ) {
96
+ return $a['order'] > $b['order'];
97
+ }
98
+
99
  /**
100
  * Returns the saved user access settings and merges in
101
  * any default roles that haven't been saved.
276
  * @return void
277
  */
278
  static function register_default_settings() {
279
+ self::register_setting( 'builder_access', array(
280
+ 'default' => 'all',
281
+ 'group' => __( 'Frontend', 'fl-builder' ),
282
+ 'label' => __( 'Builder Access', 'fl-builder' ),
283
+ 'description' => __( 'The selected roles will have access to the builder for editing posts, pages, and CPTs.', 'fl-builder' ),
284
+ 'order' => '1',
285
+ ) );
286
+
287
  self::register_setting( 'unrestricted_editing', array(
288
  'default' => 'all',
289
  'group' => __( 'Frontend', 'fl-builder' ),
290
  'label' => __( 'Unrestricted Editing', 'fl-builder' ),
291
+ 'description' => __( 'The selected roles will have unrestricted access to all editing features within the builder.', 'fl-builder' ),
292
+ 'order' => '2',
293
  ) );
294
  }
295
  }
classes/class-fl-builder-utils.php CHANGED
@@ -174,6 +174,40 @@ final class FLBuilderUtils {
174
  if ( isset( $yt_matches[1] ) ) {
175
  $video_data['type'] = 'youtube';
176
  $video_data['video_id'] = $yt_matches[1];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  } elseif ( isset( $vm_matches[1] ) ) {
178
  $video_data['type'] = 'vimeo';
179
  $video_data['video_id'] = $vm_matches[1];
174
  if ( isset( $yt_matches[1] ) ) {
175
  $video_data['type'] = 'youtube';
176
  $video_data['video_id'] = $yt_matches[1];
177
+
178
+ parse_str( parse_url( $url, PHP_URL_QUERY ), $yt_params );
179
+ if ( ! empty( $yt_params ) ) {
180
+
181
+ // If start time is specified, make sure to convert it into seconds.
182
+ if ( isset( $yt_params['t'] ) ) {
183
+ $minutes = 0;
184
+ $seconds = 0;
185
+ $time_in_seconds = 0;
186
+
187
+ // Check for minutes.
188
+ if ( strpos( $yt_params['t'], 'm' ) !== false ) {
189
+ $start_mins = preg_split( '([0-9]+[s])', $yt_params['t'] );
190
+ if ( $start_mins ) {
191
+ $minutes = (int) substr( $start_mins[0], 0, -1 ) * 60;
192
+ }
193
+ }
194
+
195
+ if ( strpos( $yt_params['t'], 's' ) !== false ) {
196
+ $start_secs = preg_split( '([0-9]+[m])', $yt_params['t'] );
197
+
198
+ if ( $start_secs ) {
199
+ $seconds = substr( $start_secs[1], 0, -1 );
200
+ }
201
+ }
202
+
203
+ $time_in_seconds = $minutes + $seconds;
204
+ if ( $time_in_seconds > 0 ) {
205
+ $yt_params['t'] = $time_in_seconds;
206
+ }
207
+ }
208
+
209
+ $video_data['params'] = $yt_params;
210
+ }
211
  } elseif ( isset( $vm_matches[1] ) ) {
212
  $video_data['type'] = 'vimeo';
213
  $video_data['video_id'] = $vm_matches[1];
classes/class-fl-builder-wp-blocks-layout.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Beaver Builder layout block for the new editor.
5
+ *
6
+ * @since 2.1
7
+ */
8
+ final class FLBuilderWPBlocksLayout {
9
+
10
+ /**
11
+ * @since 2.1
12
+ * @return void
13
+ */
14
+ static public function init() {
15
+ // Actions
16
+ add_action( 'current_screen', __CLASS__ . '::init_template' );
17
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::update_legacy_post', 1 );
18
+ add_action( 'pre_post_update', __CLASS__ . '::disable_builder_on_post_update', 10, 2 );
19
+
20
+ // Filters
21
+ add_filter( 'fl_builder_editor_content', __CLASS__ . '::filter_editor_content' );
22
+ add_filter( 'fl_builder_migrated_post_content', __CLASS__ . '::filter_migrated_post_content' );
23
+ }
24
+
25
+ /**
26
+ * Initialize a template for empty posts that have
27
+ * the builder enabled for them.
28
+ *
29
+ * @since 2.1
30
+ * @return void
31
+ */
32
+ static public function init_template() {
33
+ global $pagenow;
34
+
35
+ if ( in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) ) {
36
+ $post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : null;
37
+ $render_ui = apply_filters( 'fl_builder_render_admin_edit_ui', true );
38
+ $post_types = FLBuilderModel::get_post_types();
39
+ $screen = get_current_screen();
40
+ $enabled = ! $post_id ? false : FLBuilderModel::is_builder_enabled( $post_id );
41
+ $user_access = FLBuilderUserAccess::current_user_can( 'builder_access' );
42
+ $unrestricted = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
43
+
44
+ if ( $render_ui && in_array( $screen->post_type, $post_types ) ) {
45
+ $post_type = get_post_type_object( $screen->post_type );
46
+
47
+ if ( $post_type && ( $enabled || ( $user_access && $unrestricted ) ) ) {
48
+ $post_type->template = array(
49
+ array( 'fl-builder/layout' ),
50
+ );
51
+
52
+ if ( ! $user_access || ! $unrestricted ) {
53
+ $post_type->template_lock = 'all';
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Updates posts being edited in the admin that we're built
62
+ * using Beaver Builder before WordPress blocks existed.
63
+ *
64
+ * @since 2.1
65
+ * @return void
66
+ */
67
+ static public function update_legacy_post() {
68
+ global $pagenow, $post;
69
+
70
+ if ( 'post.php' !== $pagenow || ! is_object( $post ) ) {
71
+ return;
72
+ } else {
73
+ $enabled = FLBuilderModel::is_builder_enabled( $post->ID );
74
+ $blocks = preg_match( '/<!-- wp:(.*) \/?-->/', $post->post_content );
75
+
76
+ if ( $enabled && ! $blocks ) {
77
+ $block = '<!-- wp:fl-builder/layout -->';
78
+ $block .= self::remove_broken_p_tags( $post->post_content );
79
+ $block .= '<!-- /wp:fl-builder/layout -->';
80
+
81
+ $post->post_content = $block;
82
+
83
+ wp_update_post( array(
84
+ 'ID' => $post->ID,
85
+ 'post_content' => $block,
86
+ ) );
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Disable the builder if old post content has a l
93
+ * ayout block but the new post content doesn't.
94
+ *
95
+ * @since 2.1
96
+ * @return void
97
+ */
98
+ static public function disable_builder_on_post_update( $post_id, $new_post ) {
99
+ $new_post = (object) $new_post;
100
+ $old_post = get_post( $post_id );
101
+ $post_types = FLBuilderModel::get_post_types();
102
+
103
+ if ( ! $old_post || ! in_array( $old_post->post_type, $post_types ) ) {
104
+ return;
105
+ }
106
+
107
+ $old_layout = preg_match( '/<!-- wp:fl-builder\/layout \/?-->/', $old_post->post_content );
108
+ $new_layout = preg_match( '/<!-- wp:fl-builder\/layout \/?-->/', $new_post->post_content );
109
+
110
+ if ( $old_layout && ! $new_layout ) {
111
+ update_post_meta( $post_id, '_fl_builder_enabled', false );
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Filters the content saved back to the post editor when a builder
117
+ * layout is published and wraps it in our layout block. If our block
118
+ * exists in the post content then it will be replaced with this block.
119
+ * Otherwise, the entire post content will be replaced.
120
+ *
121
+ * @since 2.1
122
+ * @param string $content
123
+ * @return string
124
+ */
125
+ static public function filter_editor_content( $content ) {
126
+ $post_id = FLBuilderModel::get_post_id();
127
+ $post = get_post( $post_id );
128
+
129
+ $block = '<!-- wp:fl-builder/layout -->';
130
+ $block .= self::remove_broken_p_tags( $content );
131
+ $block .= '<!-- /wp:fl-builder/layout -->';
132
+
133
+ return $block;
134
+ }
135
+
136
+ /**
137
+ * Removes the builder layout block from migrated post content.
138
+ *
139
+ * @since 2.1
140
+ * @param string $content
141
+ * @return string
142
+ */
143
+ static public function filter_migrated_post_content( $content ) {
144
+ $content = preg_replace( '/<!-- \/?wp:fl-builder\/layout \/?-->/', '', $content );
145
+ return $content;
146
+ }
147
+
148
+ /**
149
+ * Removes unclosed or unopened paragraph tags caused by a bug
150
+ * in wpautop. If we don't remove those here, Gutenberg will
151
+ * think our layout block has an error.
152
+ *
153
+ * See: https://core.trac.wordpress.org/ticket/43100
154
+ *
155
+ * @since 2.1
156
+ * @param string $content
157
+ * @return string
158
+ */
159
+ static public function remove_broken_p_tags( $content ) {
160
+ $content = preg_replace( '/<p>(.*)<\/p>/i', '<fl-p-placeholder>$1</fl-p-placeholder>', $content );
161
+ $content = preg_replace( '/<\/?p[^>]*\>/i', '', $content );
162
+ $content = preg_replace( '/fl-p-placeholder/i', 'p', $content );
163
+ return $content;
164
+ }
165
+ }
166
+
167
+ FLBuilderWPBlocksLayout::init();
classes/class-fl-builder-wp-blocks.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Beaver Builder support for WordPress blocks.
5
+ *
6
+ * @since 2.1
7
+ */
8
+ final class FLBuilderWPBlocks {
9
+
10
+ /**
11
+ * @since 2.1
12
+ * @return void
13
+ */
14
+ static public function init() {
15
+ add_action( 'init', __CLASS__ . '::setup' );
16
+ }
17
+
18
+ /**
19
+ * @since 2.1
20
+ * @return void
21
+ */
22
+ static public function setup() {
23
+ if ( ! function_exists( 'register_block_type' ) ) {
24
+ return;
25
+ }
26
+
27
+ // Actions
28
+ add_action( 'enqueue_block_editor_assets', __CLASS__ . '::enqueue_block_editor_assets' );
29
+
30
+ // Block Files
31
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-wp-blocks-layout.php';
32
+ }
33
+
34
+ /**
35
+ * Enqueues scripts and styles for the block editor.
36
+ *
37
+ * @since 2.1
38
+ * @return void
39
+ */
40
+ static public function enqueue_block_editor_assets() {
41
+ global $post;
42
+
43
+ if ( ! is_object( $post ) ) {
44
+ return;
45
+ } elseif ( ! in_array( $post->post_type, FLBuilderModel::get_post_types() ) ) {
46
+ return;
47
+ }
48
+
49
+ $branding = FLBuilderModel::get_branding();
50
+ $post_type_object = get_post_type_object( $post->post_type );
51
+ $post_type_name = $post_type_object->labels->singular_name;
52
+ $min = ( ! FLBuilder::is_debug() ) ? '.min' : '';
53
+
54
+ wp_enqueue_style(
55
+ 'fl-builder-wp-editor',
56
+ FL_BUILDER_URL . 'css/build/wp-editor.bundle' . $min . '.css',
57
+ array(),
58
+ FL_BUILDER_VERSION
59
+ );
60
+
61
+ wp_enqueue_script(
62
+ 'fl-builder-wp-editor',
63
+ FL_BUILDER_URL . 'js/build/wp-editor.bundle' . $min . '.js',
64
+ array( 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-utils' ),
65
+ FL_BUILDER_VERSION
66
+ );
67
+
68
+ wp_localize_script( 'fl-builder-wp-editor', 'FLBuilderConfig', array(
69
+ 'builder' => array(
70
+ 'access' => FLBuilderUserAccess::current_user_can( 'builder_access' ),
71
+ 'enabled' => FLBuilderModel::is_builder_enabled( $post->ID ),
72
+ 'nonce' => wp_create_nonce( 'fl_ajax_update' ),
73
+ 'unrestricted' => FLBuilderUserAccess::current_user_can( 'unrestricted_editing' ),
74
+ ),
75
+ 'post' => array(
76
+ 'id' => $post->ID,
77
+ ),
78
+ 'strings' => array(
79
+ 'active' => sprintf( _x( '%1$s is currently active for this %2$s.', '%1$s branded builder name. %2$s post type name.', 'fl-builder' ), $branding, strtolower( $post_type_name ) ),
80
+ 'convert' => sprintf( _x( 'Convert to %s', '%s branded builder name.', 'fl-builder' ), $branding ),
81
+ 'description' => sprintf( _x( '%s lets you drag and drop your layout on the frontend.', '%s branded builder name.', 'fl-builder' ), $branding ),
82
+ 'editor' => __( 'Use Standard Editor', 'fl-builder' ),
83
+ 'launch' => sprintf( _x( 'Launch %s', '%s branded builder name.', 'fl-builder' ), $branding ),
84
+ 'title' => $branding,
85
+ 'view' => sprintf( _x( 'View %s', '%s post type name.', 'fl-builder' ), $post_type_name ),
86
+ 'warning' => __( 'Switching to the native WordPress editor will disable your Beaver Builder layout until it is enabled again. Any edits made in the WordPress editor will not be converted to your Page Builded layout. Do you want to continue?', 'fl-builder' ),
87
+ ),
88
+ 'urls' => array(
89
+ 'edit' => FLBuilderModel::get_edit_url( $post->ID ),
90
+ 'view' => get_permalink( $post->ID ),
91
+ ),
92
+ ) );
93
+ }
94
+ }
95
+
96
+ FLBuilderWPBlocks::init();
classes/class-fl-builder-wpcli-command.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * WP Cli commands for page builder.
5
  */
6
  class FLbuilder_WPCLI_Command extends WP_CLI_Command {
7
 
@@ -78,7 +78,61 @@ class FLbuilder_WPCLI_Command extends WP_CLI_Command {
78
  }
79
  }
80
  do_action( 'fl_builder_cache_cleared' );
81
- }// End if().
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
  }
84
 
1
  <?php
2
 
3
  /**
4
+ * WP Cli commands for Beaver Builder.
5
  */
6
  class FLbuilder_WPCLI_Command extends WP_CLI_Command {
7
 
78
  }
79
  }
80
  do_action( 'fl_builder_cache_cleared' );
81
+ }
82
+ }
83
+
84
+
85
+ /**
86
+ * Activate domain using Beaver Builder license key.
87
+ *
88
+ * ## OPTIONS
89
+ *
90
+ * [--deactivate]
91
+ * Deactivate this domain and remove license.
92
+ *
93
+ * [--license]
94
+ * License key to use.
95
+ *
96
+ * ## EXAMPLES
97
+ *
98
+ * 1. wp beaver register --license=01234567890
99
+ * - Register this domain using license 01234567890
100
+ * 2. wp beaver register --deactivate
101
+ * - Removes domain from domain manager and clears saved license info.
102
+ * 3. wp beaver register
103
+ * - If license is defined in wp-config.php using FL_LICENSE_KEY global.
104
+ */
105
+ public function register( $args, $assoc_args ) {
106
+
107
+ $license = '';
108
+
109
+ if ( isset( $assoc_args['deactivate'] ) ) {
110
+ FLUpdater::save_subscription_license( '' );
111
+ WP_CLI::success( 'deactivated' );
112
+ return false;
113
+ }
114
+
115
+ if ( defined( 'FL_LICENSE_KEY' ) ) {
116
+ $license = FL_LICENSE_KEY;
117
+ WP_CLI::log( 'Found license using FL_LICENSE_KEY global.' );
118
+ }
119
+ if ( isset( $assoc_args['license'] ) && '' != $assoc_args['license'] ) {
120
+ $license = $assoc_args['license'];
121
+ }
122
+
123
+ if ( ! $license ) {
124
+ WP_CLI::error( 'No license info found.' );
125
+ }
126
+
127
+ WP_CLI::log( sprintf( 'Using license [ %s ] to register %s', $license, network_home_url() ) );
128
+
129
+ $response = FLUpdater::save_subscription_license( $license );
130
+
131
+ if ( is_object( $response ) && isset( $response->error ) ) {
132
+ WP_CLI::error( $response->error );
133
+ } else {
134
+ WP_CLI::success( $response->success );
135
+ }
136
  }
137
  }
138
 
classes/class-fl-builder.php CHANGED
@@ -48,6 +48,22 @@ final class FLBuilder {
48
  */
49
  static private $enqueued_global_assets = array();
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * Initializes hooks.
53
  *
@@ -58,7 +74,6 @@ final class FLBuilder {
58
  /* Actions */
59
  add_action( 'plugins_loaded', __CLASS__ . '::load_plugin_textdomain' );
60
  add_action( 'send_headers', __CLASS__ . '::no_cache_headers' );
61
- add_action( 'wp', __CLASS__ . '::render_settings_config', 11 );
62
  add_action( 'wp', __CLASS__ . '::init_ui', 11 );
63
  add_action( 'wp', __CLASS__ . '::rich_edit' );
64
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::register_layout_styles_scripts' );
@@ -362,14 +377,17 @@ final class FLBuilder {
362
  $js_url = plugins_url( '/js/', FL_BUILDER_FILE );
363
  $min = ( self::is_debug() ) ? '' : '.min';
364
 
 
 
365
  // Register additional CSS
366
  wp_register_style( 'fl-slideshow', $css_url . 'fl-slideshow.css', array( 'yui3' ), $ver );
367
  wp_register_style( 'jquery-bxslider', $css_url . 'jquery.bxslider.css', array(), $ver );
368
  wp_register_style( 'jquery-magnificpopup', $css_url . 'jquery.magnificpopup.css', array(), $ver );
369
- wp_register_style( 'yui3', $css_url . 'yui3.css', array(), $ver );
370
 
371
  // Register icon CDN CSS
372
- wp_register_style( 'font-awesome', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', array(), $ver );
 
373
  wp_register_style( 'foundation-icons', 'https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.css', array(), $ver );
374
 
375
  // Register additional JS
@@ -490,7 +508,7 @@ final class FLBuilder {
490
 
491
  // Enqueue layout JS
492
  self::enqueue_layout_cached_asset( 'js', $rerender );
493
- }// End if().
494
  }
495
 
496
  /**
@@ -520,6 +538,11 @@ final class FLBuilder {
520
  $post_id = FLBuilderModel::get_post_id();
521
  $asset_info = FLBuilderModel::get_asset_info();
522
  $asset_ver = FLBuilderModel::get_asset_version();
 
 
 
 
 
523
 
524
  // Enqueue with the global code included?
525
  if ( in_array( 'global-' . $type, self::$enqueued_global_assets ) ) {
@@ -533,27 +556,57 @@ final class FLBuilder {
533
  self::$enqueued_global_assets[] = 'global-' . $type;
534
  }
535
 
536
- // Render if the file doesn't exist.
537
- if ( ! in_array( $path, self::$rendered_assets ) && ( ! fl_builder_filesystem()->file_exists( $path ) || $rerender || self::is_debug() ) ) {
538
- call_user_func_array( array( 'FLBuilder', 'render_' . $type ), array( $global ) );
539
- self::$rendered_assets[] = $path;
540
- }
541
 
542
- // Don't enqueue if we don't have a file after trying to render.
543
- if ( ! fl_builder_filesystem()->file_exists( $path ) || 0 === fl_builder_filesystem()->filesize( $path ) ) {
544
- return;
545
- }
546
 
547
- // Enqueue.
548
- if ( 'css' == $type ) {
549
- $deps = apply_filters( 'fl_builder_layout_style_dependencies', array() );
550
- $media = apply_filters( 'fl_builder_layout_style_media', 'all' );
551
- wp_enqueue_style( 'fl-builder-layout-' . $post_id, $url, $deps, $asset_ver, $media );
552
- } elseif ( 'js' == $type ) {
553
- wp_enqueue_script( 'fl-builder-layout-' . $post_id, $url, array( 'jquery' ), $asset_ver, true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554
  }
555
  }
556
 
 
 
 
 
 
 
 
 
 
 
557
  /**
558
  * Clears the enqueued global assets cache to ensure new asset
559
  * renders include global node assets.
@@ -584,7 +637,16 @@ final class FLBuilder {
584
 
585
  /* Frontend builder styles */
586
  wp_enqueue_style( 'dashicons' );
587
- wp_enqueue_style( 'font-awesome' );
 
 
 
 
 
 
 
 
 
588
  wp_enqueue_style( 'foundation-icons' );
589
  wp_enqueue_style( 'jquery-nanoscroller', $css_url . 'jquery.nanoscroller.css', array(), $ver );
590
  wp_enqueue_style( 'jquery-autosuggest', $css_url . 'jquery.autoSuggest.min.css', array(), $ver );
@@ -600,8 +662,11 @@ final class FLBuilder {
600
 
601
  // skins need to come after default ui styles
602
  wp_enqueue_style( 'fl-builder-ui-skin-dark', $css_url . 'fl-builder-ui-skin-dark.css', array(), $ver );
 
 
603
  } else {
604
  wp_enqueue_style( 'fl-builder-min', $css_url . 'fl-builder.min.css', array(), $ver );
 
605
  }
606
 
607
  /* Custom Icons */
@@ -632,17 +697,17 @@ final class FLBuilder {
632
 
633
  do_action( 'fl_before_sortable_enqueue' );
634
 
635
- wp_enqueue_script( 'jquery-ui-sortable', $js_url . 'jquery.ui.sortable.js', array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse' ), $ver );
636
- wp_enqueue_script( 'jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver );
637
- wp_enqueue_script( 'jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver );
638
- wp_enqueue_script( 'jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver );
639
- wp_enqueue_script( 'jquery-showhideevents', $js_url . 'jquery.showhideevents.js', array(), $ver );
640
- wp_enqueue_script( 'jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver );
641
- wp_enqueue_script( 'jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver );
642
- wp_enqueue_script( 'bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver );
643
- wp_enqueue_script( 'ace', $js_url . 'ace/ace.js', array(), $ver );
644
- wp_enqueue_script( 'ace-language-tools', $js_url . 'ace/ext-language_tools.js', array(), $ver );
645
- wp_enqueue_script( 'mousetrap', $js_url . 'mousetrap-custom.js', array(), $ver );
646
 
647
  // Enqueue individual builder scripts if WP_DEBUG is on.
648
  if ( self::is_debug() ) {
@@ -666,18 +731,12 @@ final class FLBuilder {
666
  wp_enqueue_script( 'fl-builder-revisions', $js_url . 'fl-builder-revisions.js', array(), $ver );
667
  wp_enqueue_script( 'fl-builder-search', $js_url . 'fl-builder-search.js', array( 'jquery' ), $ver );
668
  wp_enqueue_script( 'fl-builder-save-manager', $js_url . 'fl-builder-save-manager.js', array( 'jquery' ), $ver );
 
669
  } else {
670
  wp_enqueue_script( 'fl-builder-min', $js_url . 'fl-builder.min.js', array( 'jquery', 'mousetrap' ), $ver );
 
671
  }
672
 
673
- // Dynamically generated settings config for the current page.
674
- // Add to <head> via js.
675
- $url = FLBuilderModel::get_edit_url( $wp_the_query->post->ID ) . '&fl_builder_load_settings_config';
676
- $script = sprintf( 'var s = document.createElement("script");s.type = "text/javascript";s.src = "%s";document.head.appendChild(s);', $url );
677
-
678
- wp_add_inline_script( 'fl-builder', $script );
679
- wp_add_inline_script( 'fl-builder-min', $script );
680
-
681
  /* Additional module styles and scripts */
682
  foreach ( FLBuilderModel::$modules as $module ) {
683
 
@@ -690,23 +749,8 @@ final class FLBuilder {
690
  wp_enqueue_script( $handle, $props[0], $props[1], $props[2], $props[3] );
691
  }
692
  }
693
- }// End if().
694
- wp_add_inline_style( 'admin-bar', '#wp-admin-bar-fl-builder-frontend-edit-link .ab-icon:before { content: "\f116" !important; top: 2px; margin-right: 3px; }' );
695
- }
696
-
697
- /**
698
- * Renders the JS config for settings forms for the current page if requested
699
- * and dies early so it can be loaded from a script tag.
700
- *
701
- * @since 2.0.1
702
- * @return void
703
- */
704
- static public function render_settings_config() {
705
- if ( FLBuilderModel::is_builder_active() && isset( $_GET['fl_builder_load_settings_config'] ) ) {
706
- header( 'Content-Type: application/javascript' );
707
- include FL_BUILDER_DIR . 'includes/ui-settings-config.php';
708
- die();
709
  }
 
710
  }
711
 
712
  /**
@@ -731,6 +775,8 @@ final class FLBuilder {
731
  */
732
  static public function body_class( $classes ) {
733
  $do_render = apply_filters( 'fl_builder_do_render_content', true, FLBuilderModel::get_post_id() );
 
 
734
 
735
  if ( $do_render && FLBuilderModel::is_builder_enabled() && ! is_archive() ) {
736
  $classes[] = 'fl-builder';
@@ -738,26 +784,42 @@ final class FLBuilder {
738
  if ( FLBuilderModel::is_builder_active() ) {
739
  $classes[] = 'fl-builder-edit';
740
 
 
741
  if ( true === FL_BUILDER_LITE ) {
742
  $classes[] = 'fl-builder-lite';
743
  }
744
 
745
- if ( ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' ) ) {
 
746
  $classes[] = 'fl-builder-simple';
747
  }
748
 
 
 
 
 
 
 
749
  $user_settings = FLBuilderUserSettings::get();
750
  $classes[] = 'fl-builder-ui-skin--' . $user_settings['skin'];
751
 
 
752
  if ( FLBuilderModel::layout_has_drafted_changes() ) {
753
  $classes[] = 'fl-builder--layout-has-drafted-changes';
754
  }
755
 
 
756
  if ( is_rtl() ) {
757
  $classes[] = 'fl-builder-direction-rtl';
758
  } else {
759
  $classes[] = 'fl-builder-direction-ltr';
760
  }
 
 
 
 
 
 
761
  }
762
 
763
  return $classes;
@@ -1074,7 +1136,7 @@ final class FLBuilder {
1074
  }
1075
 
1076
  $views['help'] = wp_parse_args( $help_view, $default_view );
1077
- }// End if().
1078
 
1079
  return apply_filters( 'fl_builder_main_menu', $views );
1080
  }
@@ -1206,7 +1268,7 @@ final class FLBuilder {
1206
 
1207
  $args['keyLabel'] = $code;
1208
  $data[ $hook ] = $args;
1209
- } // End foreach().
1210
 
1211
  return $data;
1212
  }
@@ -1251,13 +1313,15 @@ final class FLBuilder {
1251
 
1252
  $add_btn_svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="24" height="24"><rect x="0" fill="none" width="24" height="24" /><g><path d="M17 9v2h-6v6H9v-6H3V9h6V3h2v6h6z"/></g></svg>';
1253
 
 
 
1254
  $buttons = apply_filters( 'fl_builder_ui_bar_buttons', array(
1255
  'upgrade' => array(
1256
- 'label' => __( 'Upgrade Today <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
1257
  'show' => true === FL_BUILDER_LITE,
1258
  ),
1259
  'buy' => array(
1260
- 'label' => __( 'Buy Now <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
1261
  'show' => stristr( home_url(), 'demo.wpbeaverbuilder.com' ),
1262
  ),
1263
  'done' => array(
@@ -1298,16 +1362,14 @@ final class FLBuilder {
1298
  $i++;
1299
  }
1300
 
1301
- /*
1302
- if ( $should_display_search ) {
1303
 
1304
- echo '<span class="fl-builder--search fl-builder-button">';
1305
- echo '<input type="text" id="fl-builder-search-input" placeholder="' . __( 'Search', 'fl-builder' ) . '">';
1306
- echo '<span class="search-clear">' . __( 'Clear', 'fl-builder' ) . '</span>';
1307
- echo '</span>';
 
1308
  }
1309
- */
1310
- echo '<span class="fl-builder--saving-indicator"></span>';
1311
  echo '</div>';
1312
  }
1313
 
@@ -1626,21 +1688,24 @@ final class FLBuilder {
1626
  }
1627
  }
1628
  }
1629
- }// End if().
1630
- }// End foreach().
1631
- }// End foreach().
1632
- }// End foreach().
1633
- }// End foreach().
1634
 
1635
  // Get the content.
1636
  $content = ob_get_clean();
1637
 
1638
- // Remove unnecessary tags.
1639
  $content = preg_replace( '/<\/?div[^>]*\>/i', '', $content );
1640
  $content = preg_replace( '/<\/?span[^>]*\>/i', '', $content );
1641
  $content = preg_replace( '#<script(.*?)>(.*?)</script>#is', '', $content );
 
 
1642
  $content = preg_replace( '/<i [^>]*><\\/i[^>]*>/', '', $content );
1643
  $content = preg_replace( '/ class=".*?"/', '', $content );
 
1644
 
1645
  // Remove empty lines.
1646
  $content = preg_replace( '/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content );
@@ -2167,9 +2232,10 @@ final class FLBuilder {
2167
  *
2168
  * @since 1.0
2169
  * @param bool $include_global
 
2170
  * @return string
2171
  */
2172
- static public function render_css( $include_global = true ) {
2173
  // Get info on the new file.
2174
  $nodes = FLBuilderModel::get_categorized_nodes();
2175
  $node_status = FLBuilderModel::get_node_status();
@@ -2267,7 +2333,7 @@ final class FLBuilder {
2267
  if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
2268
  $css .= self::render_responsive_module_margins( $module );
2269
  }
2270
- }// End foreach().
2271
 
2272
  // Custom Global CSS (included here for proper specificity)
2273
  if ( 'published' == $node_status && $include_global ) {
@@ -2282,15 +2348,19 @@ final class FLBuilder {
2282
  $css .= FLBuilderModel::get_layout_settings()->css;
2283
  }
2284
 
2285
- // Save the css
2286
  $css = apply_filters( 'fl_builder_render_css', $css, $nodes, $global_settings, $include_global );
2287
 
 
2288
  if ( ! self::is_debug() ) {
2289
  $css = preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css );
2290
  $css = str_replace( array( "\r\n", "\r", "\n", "\t", ' ', ' ', ' ' ), '', $css );
2291
  }
2292
 
2293
- fl_builder_filesystem()->file_put_contents( $path, $css );
 
 
 
2294
 
2295
  do_action( 'fl_builder_after_render_css' );
2296
 
@@ -2383,7 +2453,7 @@ final class FLBuilder {
2383
  }
2384
 
2385
  $css .= ' }';
2386
- }// End if().
2387
 
2388
  // Default page heading
2389
  if ( FLBuilderModel::is_builder_enabled() ) {
@@ -2525,7 +2595,7 @@ final class FLBuilder {
2525
 
2526
  $css .= $breakpoint_css;
2527
  }
2528
- }// End foreach().
2529
 
2530
  return $css;
2531
  }
@@ -2664,9 +2734,10 @@ final class FLBuilder {
2664
  *
2665
  * @since 1.0
2666
  * @param bool $include_global
 
2667
  * @return string
2668
  */
2669
- static public function render_js( $include_global = true ) {
2670
  // Get info on the new file.
2671
  $nodes = FLBuilderModel::get_categorized_nodes();
2672
  $global_settings = FLBuilderModel::get_global_settings();
@@ -2710,9 +2781,10 @@ final class FLBuilder {
2710
  // Filter the JS.
2711
  $js = apply_filters( 'fl_builder_render_js', $js, $nodes, $global_settings, $include_global );
2712
 
2713
- // Save the JS.
2714
  if ( ! empty( $js ) ) {
2715
 
 
2716
  if ( ! self::is_debug() ) {
2717
  try {
2718
  $min = FLJSMin::minify( $js );
@@ -2723,7 +2795,10 @@ final class FLBuilder {
2723
  }
2724
  }
2725
 
2726
- fl_builder_filesystem()->file_put_contents( $path, $js );
 
 
 
2727
 
2728
  do_action( 'fl_builder_after_render_js' );
2729
  }
@@ -3120,6 +3195,16 @@ final class FLBuilder {
3120
  static public function render_module_settings( $node_id = null, $type = null, $parent_id = null, $render_state = true ) {
3121
  _deprecated_function( __METHOD__, '2.0' );
3122
  }
 
 
 
 
 
 
 
 
 
 
3123
  }
3124
 
3125
  FLBuilder::init();
48
  */
49
  static private $enqueued_global_assets = array();
50
 
51
+ /**
52
+ * Used to store JS that is to be rendered inline on the wp_footer
53
+ * action when the fl_builder_render_assets_inline filter is true.
54
+ *
55
+ * @since 2.1
56
+ * @var string $inline_js
57
+ */
58
+ static private $inline_js = '';
59
+
60
+ /**
61
+ * Font awesome urls.
62
+ * @since 2.1
63
+ */
64
+ static public $fa4_url = 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css';
65
+ static public $fa5_url = 'https://use.fontawesome.com/releases/v5.0.12/css/all.css';
66
+
67
  /**
68
  * Initializes hooks.
69
  *
74
  /* Actions */
75
  add_action( 'plugins_loaded', __CLASS__ . '::load_plugin_textdomain' );
76
  add_action( 'send_headers', __CLASS__ . '::no_cache_headers' );
 
77
  add_action( 'wp', __CLASS__ . '::init_ui', 11 );
78
  add_action( 'wp', __CLASS__ . '::rich_edit' );
79
  add_action( 'wp_enqueue_scripts', __CLASS__ . '::register_layout_styles_scripts' );
377
  $js_url = plugins_url( '/js/', FL_BUILDER_FILE );
378
  $min = ( self::is_debug() ) ? '' : '.min';
379
 
380
+ $fa5_url = ( apply_filters( 'fl_enable_fa5_pro', false ) ) ? str_replace( 'use', 'pro', self::$fa5_url ) : self::$fa5_url;
381
+
382
  // Register additional CSS
383
  wp_register_style( 'fl-slideshow', $css_url . 'fl-slideshow.css', array( 'yui3' ), $ver );
384
  wp_register_style( 'jquery-bxslider', $css_url . 'jquery.bxslider.css', array(), $ver );
385
  wp_register_style( 'jquery-magnificpopup', $css_url . 'jquery.magnificpopup.css', array(), $ver );
386
+ wp_register_style( 'yui3', $css_url . 'yui3.css', array(), $ver );
387
 
388
  // Register icon CDN CSS
389
+ wp_register_style( 'font-awesome', self::$fa4_url, array(), $ver );
390
+ wp_register_style( 'font-awesome-5', $fa5_url, array(), $ver );
391
  wp_register_style( 'foundation-icons', 'https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.css', array(), $ver );
392
 
393
  // Register additional JS
508
 
509
  // Enqueue layout JS
510
  self::enqueue_layout_cached_asset( 'js', $rerender );
511
+ }
512
  }
513
 
514
  /**
538
  $post_id = FLBuilderModel::get_post_id();
539
  $asset_info = FLBuilderModel::get_asset_info();
540
  $asset_ver = FLBuilderModel::get_asset_version();
541
+ $active = FLBuilderModel::is_builder_active();
542
+ $preview = FLBuilderModel::is_builder_draft_preview();
543
+ $handle = 'fl-builder-layout-' . $post_id;
544
+ $css_deps = apply_filters( 'fl_builder_layout_style_dependencies', array() );
545
+ $css_media = apply_filters( 'fl_builder_layout_style_media', 'all' );
546
 
547
  // Enqueue with the global code included?
548
  if ( in_array( 'global-' . $type, self::$enqueued_global_assets ) ) {
556
  self::$enqueued_global_assets[] = 'global-' . $type;
557
  }
558
 
559
+ // Render the asset inline instead of enqueuing the file?
560
+ if ( ! $active && apply_filters( 'fl_builder_render_assets_inline', false ) ) {
 
 
 
561
 
562
+ // Bail if we've already rendered this.
563
+ if ( in_array( $path, self::$rendered_assets ) ) {
564
+ return;
565
+ }
566
 
567
+ // Enqueue inline.
568
+ if ( 'css' === $type ) {
569
+ wp_register_style( $handle, false, $css_deps, $asset_ver, $css_media );
570
+ wp_enqueue_style( $handle );
571
+ wp_add_inline_style( $handle, self::render_css( $global, false ) );
572
+ } else {
573
+ self::$inline_js .= self::render_js( $global, false );
574
+ if ( ! has_action( 'wp_footer', __CLASS__ . '::render_inline_js' ) ) {
575
+ add_action( 'wp_footer', __CLASS__ . '::render_inline_js', PHP_INT_MAX );
576
+ }
577
+ }
578
+ } else {
579
+
580
+ // Render if the file doesn't exist.
581
+ if ( ! in_array( $path, self::$rendered_assets ) && ( ! fl_builder_filesystem()->file_exists( $path ) || $rerender || $preview || self::is_debug() ) ) {
582
+ call_user_func_array( array( 'FLBuilder', 'render_' . $type ), array( $global ) );
583
+ self::$rendered_assets[] = $path;
584
+ }
585
+
586
+ // Don't enqueue if we don't have a file after trying to render.
587
+ if ( ! fl_builder_filesystem()->file_exists( $path ) || 0 === fl_builder_filesystem()->filesize( $path ) ) {
588
+ return;
589
+ }
590
+
591
+ // Enqueue.
592
+ if ( 'css' == $type ) {
593
+ wp_enqueue_style( $handle, $url, $css_deps, $asset_ver, $css_media );
594
+ } elseif ( 'js' == $type ) {
595
+ wp_enqueue_script( $handle, $url, array( 'jquery' ), $asset_ver, true );
596
+ }
597
  }
598
  }
599
 
600
+ /**
601
+ *
602
+ *
603
+ * @since 2.1
604
+ * @return void
605
+ */
606
+ static public function render_inline_js() {
607
+ echo '<script>' . self::$inline_js . '</script>';
608
+ }
609
+
610
  /**
611
  * Clears the enqueued global assets cache to ensure new asset
612
  * renders include global node assets.
637
 
638
  /* Frontend builder styles */
639
  wp_enqueue_style( 'dashicons' );
640
+
641
+ /**
642
+ * FA4 css and FA5 css do not mix well and actually break some of the icvons in the selector.
643
+ */
644
+ if ( in_array( 'font-awesome', FLBuilderModel::get_enabled_icons() ) ) {
645
+ wp_enqueue_style( 'font-awesome' );
646
+ } else {
647
+ wp_enqueue_style( 'font-awesome-5' );
648
+ }
649
+
650
  wp_enqueue_style( 'foundation-icons' );
651
  wp_enqueue_style( 'jquery-nanoscroller', $css_url . 'jquery.nanoscroller.css', array(), $ver );
652
  wp_enqueue_style( 'jquery-autosuggest', $css_url . 'jquery.autoSuggest.min.css', array(), $ver );
662
 
663
  // skins need to come after default ui styles
664
  wp_enqueue_style( 'fl-builder-ui-skin-dark', $css_url . 'fl-builder-ui-skin-dark.css', array(), $ver );
665
+
666
+ wp_enqueue_style( 'fl-builder-bundle', $css_url . 'build/builder.bundle.css', array(), $ver );
667
  } else {
668
  wp_enqueue_style( 'fl-builder-min', $css_url . 'fl-builder.min.css', array(), $ver );
669
+ wp_enqueue_style( 'fl-builder-bundle', $css_url . 'build/builder.bundle.min.css', array(), $ver );
670
  }
671
 
672
  /* Custom Icons */
697
 
698
  do_action( 'fl_before_sortable_enqueue' );
699
 
700
+ wp_enqueue_script( 'jquery-ui-sortable', $js_url . 'jquery.ui.sortable.js', array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse' ), $ver );
701
+ wp_enqueue_script( 'jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver );
702
+ wp_enqueue_script( 'jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver );
703
+ wp_enqueue_script( 'jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver );
704
+ wp_enqueue_script( 'jquery-showhideevents', $js_url . 'jquery.showhideevents.js', array(), $ver );
705
+ wp_enqueue_script( 'jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver );
706
+ wp_enqueue_script( 'jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver );
707
+ wp_enqueue_script( 'bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver );
708
+ wp_enqueue_script( 'ace', $js_url . 'ace/ace.js', array(), $ver );
709
+ wp_enqueue_script( 'ace-language-tools', $js_url . 'ace/ext-language_tools.js', array(), $ver );
710
+ wp_enqueue_script( 'mousetrap', $js_url . 'mousetrap-custom.js', array(), $ver );
711
 
712
  // Enqueue individual builder scripts if WP_DEBUG is on.
713
  if ( self::is_debug() ) {
731
  wp_enqueue_script( 'fl-builder-revisions', $js_url . 'fl-builder-revisions.js', array(), $ver );
732
  wp_enqueue_script( 'fl-builder-search', $js_url . 'fl-builder-search.js', array( 'jquery' ), $ver );
733
  wp_enqueue_script( 'fl-builder-save-manager', $js_url . 'fl-builder-save-manager.js', array( 'jquery' ), $ver );
734
+ wp_enqueue_script( 'fl-builder-bundle', $js_url . 'build/builder.bundle.js', array(), $ver, true );
735
  } else {
736
  wp_enqueue_script( 'fl-builder-min', $js_url . 'fl-builder.min.js', array( 'jquery', 'mousetrap' ), $ver );
737
+ wp_enqueue_script( 'fl-builder-bundle', $js_url . 'build/builder.bundle.min.js', array(), $ver, true );
738
  }
739
 
 
 
 
 
 
 
 
 
740
  /* Additional module styles and scripts */
741
  foreach ( FLBuilderModel::$modules as $module ) {
742
 
749
  wp_enqueue_script( $handle, $props[0], $props[1], $props[2], $props[3] );
750
  }
751
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
752
  }
753
+ wp_add_inline_style( 'admin-bar', '#wp-admin-bar-fl-builder-frontend-edit-link .ab-icon:before { content: "\f116" !important; top: 2px; margin-right: 3px; }' );
754
  }
755
 
756
  /**
775
  */
776
  static public function body_class( $classes ) {
777
  $do_render = apply_filters( 'fl_builder_do_render_content', true, FLBuilderModel::get_post_id() );
778
+ $simple_ui = ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
779
+ $template_type = FLBuilderModel::get_user_template_type();
780
 
781
  if ( $do_render && FLBuilderModel::is_builder_enabled() && ! is_archive() ) {
782
  $classes[] = 'fl-builder';
784
  if ( FLBuilderModel::is_builder_active() ) {
785
  $classes[] = 'fl-builder-edit';
786
 
787
+ // Lite version
788
  if ( true === FL_BUILDER_LITE ) {
789
  $classes[] = 'fl-builder-lite';
790
  }
791
 
792
+ // Simple UI
793
+ if ( $simple_ui ) {
794
  $classes[] = 'fl-builder-simple';
795
  }
796
 
797
+ // Simple pinned UI
798
+ if ( $simple_ui || 'module' === $template_type ) {
799
+ $classes[] = 'fl-builder-simple-pinned';
800
+ }
801
+
802
+ // Skin
803
  $user_settings = FLBuilderUserSettings::get();
804
  $classes[] = 'fl-builder-ui-skin--' . $user_settings['skin'];
805
 
806
+ // Draft changes
807
  if ( FLBuilderModel::layout_has_drafted_changes() ) {
808
  $classes[] = 'fl-builder--layout-has-drafted-changes';
809
  }
810
 
811
+ // RTL
812
  if ( is_rtl() ) {
813
  $classes[] = 'fl-builder-direction-rtl';
814
  } else {
815
  $classes[] = 'fl-builder-direction-ltr';
816
  }
817
+
818
+ // Has notifications
819
+ $has_new_notifications = FLBuilderNotifications::get_notifications();
820
+ if ( ! $has_new_notifications['read'] ) {
821
+ $classes[] = 'fl-builder-has-new-notifications';
822
+ }
823
  }
824
 
825
  return $classes;
1136
  }
1137
 
1138
  $views['help'] = wp_parse_args( $help_view, $default_view );
1139
+ }
1140
 
1141
  return apply_filters( 'fl_builder_main_menu', $views );
1142
  }
1268
 
1269
  $args['keyLabel'] = $code;
1270
  $data[ $hook ] = $args;
1271
+ }
1272
 
1273
  return $data;
1274
  }
1313
 
1314
  $add_btn_svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="24" height="24"><rect x="0" fill="none" width="24" height="24" /><g><path d="M17 9v2h-6v6H9v-6H3V9h6V3h2v6h6z"/></g></svg>';
1315
 
1316
+ $notifications = FLBuilderNotifications::get_notifications();
1317
+
1318
  $buttons = apply_filters( 'fl_builder_ui_bar_buttons', array(
1319
  'upgrade' => array(
1320
+ 'label' => __( 'Upgrade Today', 'fl-builder' ) . ' <i class="fas fa-external-link-alt"></i>',
1321
  'show' => true === FL_BUILDER_LITE,
1322
  ),
1323
  'buy' => array(
1324
+ 'label' => __( 'Buy Now', 'fl-builder' ) . ' <i class="fas fa-external-link-alt"></i>',
1325
  'show' => stristr( home_url(), 'demo.wpbeaverbuilder.com' ),
1326
  ),
1327
  'done' => array(
1362
  $i++;
1363
  }
1364
 
1365
+ echo '<span class="fl-builder--saving-indicator"></span>';
 
1366
 
1367
+ if ( ! $simple_ui && ! FLBuilderModel::is_white_labeled() && $notifications['data'] && '{}' !== $notifications['data'] && ! apply_filters( 'fl_disable_notifications', false ) ) {
1368
+ echo '<span class="fl-builder-bar-spacer"></span>';
1369
+ echo '<button id="fl-builder-toggle-notifications" class="fl-builder-button fl-builder-button-silent">';
1370
+ include FL_BUILDER_DIR . 'img/svg/bell-active.svg';
1371
+ echo '</button>';
1372
  }
 
 
1373
  echo '</div>';
1374
  }
1375
 
1688
  }
1689
  }
1690
  }
1691
+ }
1692
+ }
1693
+ }
1694
+ }
1695
+ }
1696
 
1697
  // Get the content.
1698
  $content = ob_get_clean();
1699
 
1700
+ // Remove unnecessary tags and attributes.
1701
  $content = preg_replace( '/<\/?div[^>]*\>/i', '', $content );
1702
  $content = preg_replace( '/<\/?span[^>]*\>/i', '', $content );
1703
  $content = preg_replace( '#<script(.*?)>(.*?)</script>#is', '', $content );
1704
+ $content = preg_replace( '/<\/?noscript[^>]*\>/i', '', $content );
1705
+ $content = preg_replace( '#<svg(.*?)>(.*?)</svg>#is', '', $content );
1706
  $content = preg_replace( '/<i [^>]*><\\/i[^>]*>/', '', $content );
1707
  $content = preg_replace( '/ class=".*?"/', '', $content );
1708
+ $content = preg_replace( '/ style=".*?"/', '', $content );
1709
 
1710
  // Remove empty lines.
1711
  $content = preg_replace( '/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content );
2232
  *
2233
  * @since 1.0
2234
  * @param bool $include_global
2235
+ * @param bool $save
2236
  * @return string
2237
  */
2238
+ static public function render_css( $include_global = true, $save = true ) {
2239
  // Get info on the new file.
2240
  $nodes = FLBuilderModel::get_categorized_nodes();
2241
  $node_status = FLBuilderModel::get_node_status();
2333
  if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
2334
  $css .= self::render_responsive_module_margins( $module );
2335
  }
2336
+ }
2337
 
2338
  // Custom Global CSS (included here for proper specificity)
2339
  if ( 'published' == $node_status && $include_global ) {
2348
  $css .= FLBuilderModel::get_layout_settings()->css;
2349
  }
2350
 
2351
+ // Filter the CSS.
2352
  $css = apply_filters( 'fl_builder_render_css', $css, $nodes, $global_settings, $include_global );
2353
 
2354
+ // Minify the CSS.
2355
  if ( ! self::is_debug() ) {
2356
  $css = preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css );
2357
  $css = str_replace( array( "\r\n", "\r", "\n", "\t", ' ', ' ', ' ' ), '', $css );
2358
  }
2359
 
2360
+ // Save the CSS.
2361
+ if ( $save ) {
2362
+ fl_builder_filesystem()->file_put_contents( $path, $css );
2363
+ }
2364
 
2365
  do_action( 'fl_builder_after_render_css' );
2366
 
2453
  }
2454
 
2455
  $css .= ' }';
2456
+ }
2457
 
2458
  // Default page heading
2459
  if ( FLBuilderModel::is_builder_enabled() ) {
2595
 
2596
  $css .= $breakpoint_css;
2597
  }
2598
+ }
2599
 
2600
  return $css;
2601
  }
2734
  *
2735
  * @since 1.0
2736
  * @param bool $include_global
2737
+ * @param bool $save
2738
  * @return string
2739
  */
2740
+ static public function render_js( $include_global = true, $save = true ) {
2741
  // Get info on the new file.
2742
  $nodes = FLBuilderModel::get_categorized_nodes();
2743
  $global_settings = FLBuilderModel::get_global_settings();
2781
  // Filter the JS.
2782
  $js = apply_filters( 'fl_builder_render_js', $js, $nodes, $global_settings, $include_global );
2783
 
2784
+ // Only proceed if we have JS.
2785
  if ( ! empty( $js ) ) {
2786
 
2787
+ // Minify the JS.
2788
  if ( ! self::is_debug() ) {
2789
  try {
2790
  $min = FLJSMin::minify( $js );
2795
  }
2796
  }
2797
 
2798
+ // Save the JS.
2799
+ if ( $save ) {
2800
+ fl_builder_filesystem()->file_put_contents( $path, $js );
2801
+ }
2802
 
2803
  do_action( 'fl_builder_after_render_js' );
2804
  }
3195
  static public function render_module_settings( $node_id = null, $type = null, $parent_id = null, $render_state = true ) {
3196
  _deprecated_function( __METHOD__, '2.0' );
3197
  }
3198
+
3199
+ /**
3200
+ * @since 2.0.1
3201
+ * @deprecated 2.0.7
3202
+ */
3203
+ static public function render_settings_config() {
3204
+ _deprecated_function( __METHOD__, '2.0.7', 'FLBuilderUISettingsForms::render_settings_config()' );
3205
+
3206
+ FLBuilderUISettingsForms::render_settings_config();
3207
+ }
3208
  }
3209
 
3210
  FLBuilder::init();
classes/class-fl-jsmin.php CHANGED
@@ -131,7 +131,7 @@ class FLJSMin {
131
 
132
  $this->b = $this->next();
133
  }
134
- }// End switch().
135
  }
136
 
137
  protected function get() {
@@ -234,9 +234,9 @@ class FLJSMin {
234
  default:
235
  $this->action( 1 );
236
  break;
237
- }// End switch().
238
- }// End switch().
239
- }// End while().
240
 
241
  return $this->output;
242
  }
131
 
132
  $this->b = $this->next();
133
  }
134
+ }
135
  }
136
 
137
  protected function get() {
234
  default:
235
  $this->action( 1 );
236
  break;
237
+ }
238
+ }
239
+ }
240
 
241
  return $this->output;
242
  }
css/build/builder.bundle.css ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .fl-editable {
2
+ position: relative;
3
+ -webkit-user-select: text; }
4
+ .fl-editable.fl-module {
5
+ cursor: pointer; }
6
+ .fl-editable .fl-block-overlay {
7
+ pointer-events: none; }
8
+ .fl-editable .fl-block-overlay-actions,
9
+ .fl-editable .fl-block-col-resize {
10
+ pointer-events: auto; }
11
+ .fl-editable .mce-content-body {
12
+ cursor: text; }
13
+ .fl-editable .mce-content-body * {
14
+ cursor: text; }
15
+ .fl-editable .mce-content-body:not(.mce-edit-focus) [data-mce-selected] {
16
+ background: none; }
17
+ .fl-editable .mce-edit-body,
18
+ .fl-editable .mce-edit-focus {
19
+ outline: none !important; }
20
+
21
+ .fl-inline-editor {
22
+ border: 2px solid #00A0D2;
23
+ border-radius: 4px;
24
+ display: none;
25
+ overflow: hidden;
26
+ pointer-events: none;
27
+ position: absolute;
28
+ top: -32px;
29
+ right: 4px;
30
+ bottom: 4px;
31
+ left: 4px;
32
+ z-index: 100008;
33
+ /* Toolbar wrappers */
34
+ /* Toolbar buttons */ }
35
+ .fl-inline-editor.fl-inline-editor-no-toolbar {
36
+ top: 4px; }
37
+ .fl-inline-editor.fl-inline-editor-no-toolbar > .mce-tinymce {
38
+ display: none; }
39
+ .fl-inline-editor > .mce-tinymce {
40
+ background: transparent;
41
+ border: none !important;
42
+ overflow: hidden;
43
+ pointer-events: auto;
44
+ position: absolute;
45
+ top: -2px !important;
46
+ right: -2px !important;
47
+ left: -2px !important;
48
+ width: auto !important; }
49
+ .fl-inline-editor .mce-tinymce,
50
+ .fl-inline-editor .mce-container-body,
51
+ .fl-inline-editor .mce-toolbar-grp {
52
+ height: 32px !important;
53
+ width: auto !important; }
54
+ .fl-inline-editor .mce-container-body {
55
+ padding: 0; }
56
+ .fl-inline-editor .mce-toolbar-grp {
57
+ background: #00A0D2;
58
+ border: none;
59
+ border-top-left-radius: 4px;
60
+ border-bottom-right-radius: 4px;
61
+ width: auto !important;
62
+ display: inline-block; }
63
+ .fl-inline-editor .mce-tinymce-inline .mce-flow-layout {
64
+ white-space: normal; }
65
+ .fl-inline-editor .mce-btn-group {
66
+ padding: 0 3px; }
67
+ .fl-inline-editor .mce-btn-group:not(:first-child) {
68
+ border-color: rgba(255, 255, 255, 0.3); }
69
+ .fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn:focus,
70
+ .fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn:hover,
71
+ .fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn:active,
72
+ .fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn.mce-active,
73
+ .fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn.mce-active:focus,
74
+ .fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn.mce-active:hover {
75
+ background: rgba(255, 255, 255, 0.2);
76
+ border-color: rgba(255, 255, 255, 0.4);
77
+ box-shadow: none; }
78
+ .fl-inline-editor .mce-toolbar .mce-btn button {
79
+ padding: 1px; }
80
+ .fl-inline-editor .mce-toolbar .mce-btn .mce-ico {
81
+ color: rgba(255, 255, 255, 0.8) !important; }
82
+ .fl-inline-editor .mce-toolbar .mce-btn:hover .mce-ico {
83
+ color: #fff !important; }
84
+ .fl-inline-editor .mce-panel .mce-btn i.mce-caret {
85
+ border-top-color: rgba(255, 255, 255, 0.8) !important;
86
+ border-bottom-color: rgba(255, 255, 255, 0.8) !important; }
87
+ .fl-inline-editor .mce-panel .mce-btn:hover i.mce-caret {
88
+ border-top-color: #fff !important; }
89
+
90
+ /* Make heading text display:block so input can start anywhere in the module. */
91
+ .fl-heading-text.mce-content-body {
92
+ display: block; }
93
+
94
+ /* Tooltips are currently getting in the way of mouse events. */
95
+ .mce-tooltip {
96
+ display: none !important; }
97
+ .fl-notifications-panel {
98
+ position: fixed;
99
+ top: 48px;
100
+ left: 0;
101
+ bottom: 0;
102
+ width: 380px;
103
+ background: #F5F7F9;
104
+ color: #555555;
105
+ border-right: 2px solid #d5dadd;
106
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
107
+ font-size: 14px;
108
+ z-index: 999999;
109
+ display: flex;
110
+ flex-direction: column; }
111
+ .fl-notifications-panel .fl-nanoscroller .fl-nanoscroller-content {
112
+ padding: 0 15px; }
113
+ .fl-notifications-panel .fl-panel-title {
114
+ flex: 0 0 auto;
115
+ padding: 15px 30px;
116
+ font-size: 18px; }
117
+ .fl-notifications-panel .fl-builder-ui-post {
118
+ flex: 0 0 auto;
119
+ display: flex;
120
+ display: block;
121
+ padding: 15px;
122
+ margin: 15px 0;
123
+ border-radius: 4px;
124
+ text-decoration: none;
125
+ color: inherit; }
126
+ .fl-notifications-panel .fl-builder-ui-post:first-child {
127
+ margin-top: 0; }
128
+ .fl-notifications-panel .fl-builder-ui-post:hover {
129
+ text-decoration: none;
130
+ background: white;
131
+ color: black; }
132
+ .fl-notifications-panel .fl-builder-ui-post .fl-builder-ui-post-title {
133
+ font-size: 17px;
134
+ line-height: 1.4;
135
+ margin-bottom: 10px;
136
+ color: #0089b4; }
137
+ .fl-notifications-panel .fl-builder-ui-post .fl-builder-ui-post-date {
138
+ text-transform: uppercase;
139
+ font-size: 12px;
140
+ font-weight: bold;
141
+ margin-bottom: 10px; }
142
+ .fl-notifications-panel .fl-panel-loading-message {
143
+ padding: 0 15px;
144
+ align-items: center;
145
+ justify-content: center;
146
+ display: flex;
147
+ height: 100%; }
148
+
149
+ /* Toolbar Button */
150
+ .fl-builder-bar-spacer {
151
+ flex: 1 1 100%; }
152
+
153
+ #bell-active-dot {
154
+ visibility: hidden; }
155
+
156
+ .fl-builder-has-new-notifications #bell-active-dot {
157
+ visibility: visible; }
158
+ /**
159
+ * This file is just here for demonstration purposes while we get
160
+ * our Webpack workflow going. In the future styles should probably
161
+ * be written on a per-component basis.
162
+ */
css/build/builder.bundle.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .fl-editable{position:relative;-webkit-user-select:text}.fl-editable.fl-module{cursor:pointer}.fl-editable .fl-block-overlay{pointer-events:none}.fl-editable .fl-block-col-resize,.fl-editable .fl-block-overlay-actions{pointer-events:auto}.fl-editable .mce-content-body,.fl-editable .mce-content-body *{cursor:text}.fl-editable .mce-content-body:not(.mce-edit-focus) [data-mce-selected]{background:none}.fl-editable .mce-edit-body,.fl-editable .mce-edit-focus{outline:none!important}.fl-inline-editor{border:2px solid #00a0d2;border-radius:4px;display:none;overflow:hidden;pointer-events:none;position:absolute;top:-32px;right:4px;bottom:4px;left:4px;z-index:100008}.fl-inline-editor.fl-inline-editor-no-toolbar{top:4px}.fl-inline-editor.fl-inline-editor-no-toolbar>.mce-tinymce{display:none}.fl-inline-editor>.mce-tinymce{background:transparent;border:none!important;overflow:hidden;pointer-events:auto;position:absolute;top:-2px!important;right:-2px!important;left:-2px!important;width:auto!important}.fl-inline-editor .mce-container-body,.fl-inline-editor .mce-tinymce,.fl-inline-editor .mce-toolbar-grp{height:32px!important;width:auto!important}.fl-inline-editor .mce-container-body{padding:0}.fl-inline-editor .mce-toolbar-grp{background:#00a0d2;border:none;border-top-left-radius:4px;border-bottom-right-radius:4px;width:auto!important;display:inline-block}.fl-inline-editor .mce-tinymce-inline .mce-flow-layout{white-space:normal}.fl-inline-editor .mce-btn-group{padding:0 3px}.fl-inline-editor .mce-btn-group:not(:first-child){border-color:hsla(0,0%,100%,.3)}.fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn.mce-active,.fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn.mce-active:focus,.fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn.mce-active:hover,.fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn:active,.fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn:focus,.fl-inline-editor .mce-toolbar .mce-btn-group .mce-btn:hover{background:hsla(0,0%,100%,.2);border-color:hsla(0,0%,100%,.4);box-shadow:none}.fl-inline-editor .mce-toolbar .mce-btn button{padding:1px}.fl-inline-editor .mce-toolbar .mce-btn .mce-ico{color:hsla(0,0%,100%,.8)!important}.fl-inline-editor .mce-toolbar .mce-btn:hover .mce-ico{color:#fff!important}.fl-inline-editor .mce-panel .mce-btn i.mce-caret{border-top-color:hsla(0,0%,100%,.8)!important;border-bottom-color:hsla(0,0%,100%,.8)!important}.fl-inline-editor .mce-panel .mce-btn:hover i.mce-caret{border-top-color:#fff!important}.fl-heading-text.mce-content-body{display:block}.mce-tooltip{display:none!important}.fl-notifications-panel{position:fixed;top:48px;left:0;bottom:0;width:380px;background:#f5f7f9;color:#555;border-right:2px solid #d5dadd;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif!important;font-size:14px;z-index:999999;display:flex;flex-direction:column}.fl-notifications-panel .fl-nanoscroller .fl-nanoscroller-content{padding:0 15px}.fl-notifications-panel .fl-panel-title{flex:0 0 auto;padding:15px 30px;font-size:18px}.fl-notifications-panel .fl-builder-ui-post{flex:0 0 auto;display:flex;display:block;padding:15px;margin:15px 0;border-radius:4px;text-decoration:none;color:inherit}.fl-notifications-panel .fl-builder-ui-post:first-child{margin-top:0}.fl-notifications-panel .fl-builder-ui-post:hover{text-decoration:none;background:#fff;color:#000}.fl-notifications-panel .fl-builder-ui-post .fl-builder-ui-post-title{font-size:17px;line-height:1.4;margin-bottom:10px;color:#0089b4}.fl-notifications-panel .fl-builder-ui-post .fl-builder-ui-post-date{text-transform:uppercase;font-size:12px;font-weight:700;margin-bottom:10px}.fl-notifications-panel .fl-panel-loading-message{padding:0 15px;align-items:center;justify-content:center;display:flex;height:100%}.fl-builder-bar-spacer{flex:1 1 100%}#bell-active-dot{visibility:hidden}.fl-builder-has-new-notifications #bell-active-dot{visibility:visible}
css/build/wp-editor.bundle.css ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Lock down the block editor when the layout block is active.
3
+ */
4
+ .fl-builder-layout-enabled .editor-inserter,
5
+ .fl-builder-layout-enabled .editor-visual-editor__inserter,
6
+ .fl-builder-layout-enabled .editor-block-settings-menu,
7
+ .fl-builder-layout-enabled .editor-block-mover,
8
+ .fl-builder-layout-enabled .editor-block-list__block:not([data-type="fl-builder/layout"]) {
9
+ display: none !important; }
10
+
11
+ /**
12
+ * Launch View
13
+ */
14
+ .fl-builder-layout-launch-view .components-button {
15
+ margin: 0 5px; }
16
+
17
+ .fl-builder-layout-launch-view .components-placeholder__fieldset {
18
+ max-width: none; }
19
+
20
+ /**
21
+ * Loading View
22
+ */
23
+ .fl-builder-layout-loading-view .spinner {
24
+ float: left; }
css/build/wp-editor.bundle.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .fl-builder-layout-enabled .editor-block-list__block:not([data-type="fl-builder/layout"]),.fl-builder-layout-enabled .editor-block-mover,.fl-builder-layout-enabled .editor-block-settings-menu,.fl-builder-layout-enabled .editor-inserter,.fl-builder-layout-enabled .editor-visual-editor__inserter{display:none!important}.fl-builder-layout-launch-view .components-button{margin:0 5px}.fl-builder-layout-launch-view .components-placeholder__fieldset{max-width:none}.fl-builder-layout-loading-view .spinner{float:left}
css/fl-builder-admin-posts.css CHANGED
@@ -3,21 +3,22 @@
3
 
4
  .fl-builder-admin {
5
  position: relative;
 
6
  }
7
 
8
  /* Enabled/Disabled States
9
  ------------------------------------------------------ */
10
 
11
- .fl-builder-enabled .fl-builder-admin-tabs {
12
- border: none;
13
- margin: 10px 0 0;
14
- }
15
  .fl-builder-admin-ui {
16
  display: none;
17
  }
18
  .fl-builder-enabled .fl-builder-admin-ui {
19
  display: block;
20
  }
 
 
 
 
21
  .fl-builder-enabled #postdivrich {
22
  display: none;
23
  }
@@ -122,4 +123,4 @@
122
  }
123
  #newfl-builder-template-category_parent {
124
  display: none;
125
- }
3
 
4
  .fl-builder-admin {
5
  position: relative;
6
+ padding: 10px 0 0;
7
  }
8
 
9
  /* Enabled/Disabled States
10
  ------------------------------------------------------ */
11
 
 
 
 
 
12
  .fl-builder-admin-ui {
13
  display: none;
14
  }
15
  .fl-builder-enabled .fl-builder-admin-ui {
16
  display: block;
17
  }
18
+ .fl-builder-enabled .fl-builder-admin-tabs {
19
+ border: none;
20
+ margin: 0;
21
+ }
22
  .fl-builder-enabled #postdivrich {
23
  display: none;
24
  }
123
  }
124
  #newfl-builder-template-category_parent {
125
  display: none;
126
+ }
css/fl-builder-admin-settings.css CHANGED
@@ -138,7 +138,7 @@ body .ms-options-wrap > .ms-options > ul input[type="checkbox"] {
138
  position: static;
139
  }
140
 
141
- /* TipTip
142
  ------------------------------------------------------*/
143
 
144
  #tiptip_arrow_inner {
@@ -273,10 +273,10 @@ body .ms-options-wrap > .ms-options > ul input[type="checkbox"] {
273
  .fl-settings-content .fl-settings-save .button-primary {
274
  width: 100%;
275
  }
276
-
277
  /* User Access
278
  ----------------------------------------------------------- */
279
-
280
  .fl-user-access-setting {
281
  float: none;
282
  width: 100%;
138
  position: static;
139
  }
140
 
141
+ /* TipTip
142
  ------------------------------------------------------*/
143
 
144
  #tiptip_arrow_inner {
273
  .fl-settings-content .fl-settings-save .button-primary {
274
  width: 100%;
275
  }
276
+
277
  /* User Access
278
  ----------------------------------------------------------- */
279
+
280
  .fl-user-access-setting {
281
  float: none;
282
  width: 100%;
css/fl-builder-admin-usage.css ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .fl-usage {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ }
6
+
7
+ .fl-usage > .buttons {
8
+ margin-left:auto;
9
+ padding-top:15px;
10
+ }
11
+
12
+ .fl-usage > .buttons a{
13
+ margin-left: 10px;
14
+ }
15
+
16
+ .usage-demo {
17
+ padding-bottom:15px;
18
+ }
19
+
20
+ .stats-info-data {
21
+ display: none;
22
+ }
23
+
24
+ .stats-info-data .usage-demo-left {
25
+ display: inline-block;
26
+ min-width: 25%;
27
+ }
css/fl-builder-layout-responsive.css CHANGED
@@ -59,90 +59,91 @@
59
  -webkit-flex: 0 0 100%;
60
  -ms-flex: 0 0 100%;
61
  flex: 0 0 100%;
 
62
  }
63
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(1) {
64
  -webkit-box-ordinal-group: 12; /* OLD - iOS 6-, Safari 3.1-6 */
65
  -moz-box-ordinal-group: 12; /* OLD - Firefox 19- */
66
  -ms-flex-order: 12; /* TWEENER - IE 10 */
67
  -webkit-order: 12; /* NEW - Chrome */
68
- order: 12;
69
  }
70
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(2) {
71
  -webkit-box-ordinal-group: 11;
72
  -moz-box-ordinal-group: 11;
73
  -ms-flex-order: 11;
74
  -webkit-order: 11;
75
- order: 11;
76
  }
77
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(3) {
78
  -webkit-box-ordinal-group: 10;
79
  -moz-box-ordinal-group: 10;
80
  -ms-flex-order: 10;
81
  -webkit-order: 10;
82
- order: 10;
83
  }
84
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(4) {
85
  -webkit-box-ordinal-group: 9;
86
  -moz-box-ordinal-group: 9;
87
  -ms-flex-order: 9;
88
  -webkit-order: 9;
89
- order: 9;
90
  }
91
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(5) {
92
  -webkit-box-ordinal-group: 8;
93
  -moz-box-ordinal-group: 8;
94
  -ms-flex-order: 8;
95
  -webkit-order: 8;
96
- order: 8;
97
  }
98
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(6) {
99
  -webkit-box-ordinal-group: 7;
100
  -moz-box-ordinal-group: 7;
101
  -ms-flex-order: 7;
102
  -webkit-order: 7;
103
- order: 7;
104
  }
105
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(7) {
106
  -webkit-box-ordinal-group: 6;
107
  -moz-box-ordinal-group: 6;
108
  -ms-flex-order: 6;
109
  -webkit-order: 6;
110
- order: 6;
111
  }
112
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(8) {
113
  -webkit-box-ordinal-group: 5;
114
  -moz-box-ordinal-group: 5;
115
  -ms-flex-order: 5;
116
  -webkit-order: 5;
117
- order: 5;
118
  }
119
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(9) {
120
  -webkit-box-ordinal-group: 4;
121
  -moz-box-ordinal-group: 4;
122
  -ms-flex-order: 4;
123
  -webkit-order: 4;
124
- order: 4;
125
  }
126
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(10) {
127
  -webkit-box-ordinal-group: 3;
128
  -moz-box-ordinal-group: 3;
129
  -ms-flex-order: 3;
130
  -webkit-order: 3;
131
- order: 3;
132
  }
133
- .fl-col-group-responsive-reversed .fl-col:nth-of-type(11) {
134
  -webkit-box-ordinal-group: 2;
135
  -moz-box-ordinal-group: 2;
136
  -ms-flex-order: 2;
137
  -webkit-order: 2;
138
- order: 2;
139
  }
140
  .fl-col-group-responsive-reversed .fl-col:nth-of-type(12) {
141
  -webkit-box-ordinal-group: 1;
142
  -moz-box-ordinal-group: 1;
143
  -ms-flex-order: 1;
144
  -webkit-order: 1;
145
- order: 1;
146
  }
147
 
148
  /* Columns
@@ -160,4 +161,4 @@
160
  }
161
  .fl-block-col-resize {
162
  display:none;
163
- }
59
  -webkit-flex: 0 0 100%;
60
  -ms-flex: 0 0 100%;
61
  flex: 0 0 100%;
62
+ max-width: 100%;
63
  }
64
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(1) {
65
  -webkit-box-ordinal-group: 12; /* OLD - iOS 6-, Safari 3.1-6 */
66
  -moz-box-ordinal-group: 12; /* OLD - Firefox 19- */
67
  -ms-flex-order: 12; /* TWEENER - IE 10 */
68
  -webkit-order: 12; /* NEW - Chrome */
69
+ order: 12;
70
  }
71
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(2) {
72
  -webkit-box-ordinal-group: 11;
73
  -moz-box-ordinal-group: 11;
74
  -ms-flex-order: 11;
75
  -webkit-order: 11;
76
+ order: 11;
77
  }
78
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(3) {
79
  -webkit-box-ordinal-group: 10;
80
  -moz-box-ordinal-group: 10;
81
  -ms-flex-order: 10;
82
  -webkit-order: 10;
83
+ order: 10;
84
  }
85
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(4) {
86
  -webkit-box-ordinal-group: 9;
87
  -moz-box-ordinal-group: 9;
88
  -ms-flex-order: 9;
89
  -webkit-order: 9;
90
+ order: 9;
91
  }
92
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(5) {
93
  -webkit-box-ordinal-group: 8;
94
  -moz-box-ordinal-group: 8;
95
  -ms-flex-order: 8;
96
  -webkit-order: 8;
97
+ order: 8;
98
  }
99
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(6) {
100
  -webkit-box-ordinal-group: 7;
101
  -moz-box-ordinal-group: 7;
102
  -ms-flex-order: 7;
103
  -webkit-order: 7;
104
+ order: 7;
105
  }
106
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(7) {
107
  -webkit-box-ordinal-group: 6;
108
  -moz-box-ordinal-group: 6;
109
  -ms-flex-order: 6;
110
  -webkit-order: 6;
111
+ order: 6;
112
  }
113
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(8) {
114
  -webkit-box-ordinal-group: 5;
115
  -moz-box-ordinal-group: 5;
116
  -ms-flex-order: 5;
117
  -webkit-order: 5;
118
+ order: 5;
119
  }
120
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(9) {
121
  -webkit-box-ordinal-group: 4;
122
  -moz-box-ordinal-group: 4;
123
  -ms-flex-order: 4;
124
  -webkit-order: 4;
125
+ order: 4;
126
  }
127
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(10) {
128
  -webkit-box-ordinal-group: 3;
129
  -moz-box-ordinal-group: 3;
130
  -ms-flex-order: 3;
131
  -webkit-order: 3;
132
+ order: 3;
133
  }
134
+ .fl-col-group-responsive-reversed .fl-col:nth-of-type(11) {
135
  -webkit-box-ordinal-group: 2;
136
  -moz-box-ordinal-group: 2;
137
  -ms-flex-order: 2;
138
  -webkit-order: 2;
139
+ order: 2;
140
  }
141
  .fl-col-group-responsive-reversed .fl-col:nth-of-type(12) {
142
  -webkit-box-ordinal-group: 1;
143
  -moz-box-ordinal-group: 1;
144
  -ms-flex-order: 1;
145
  -webkit-order: 1;
146
+ order: 1;
147
  }
148
 
149
  /* Columns
161
  }
162
  .fl-block-col-resize {
163
  display:none;
164
+ }
css/fl-builder-layout.css CHANGED
@@ -103,6 +103,7 @@
103
  .fl-row-bg-video .fl-bg-video video {
104
  bottom: 0;
105
  left: 0px;
 
106
  position: absolute;
107
  right: 0;
108
  top: 0px;
@@ -118,6 +119,8 @@
118
  top: 50%;
119
  left: 50%;
120
  transform: translate(-50%, -50%);
 
 
121
  }
122
  .fl-bg-video-fallback {
123
  background-position: 50% 50%;
103
  .fl-row-bg-video .fl-bg-video video {
104
  bottom: 0;
105
  left: 0px;
106
+ max-width: none;
107
  position: absolute;
108
  right: 0;
109
  top: 0px;
119
  top: 50%;
120
  left: 50%;
121
  transform: translate(-50%, -50%);
122
+ -ms-transform: translate(-50%, -50%); /* IE 9 */
123
+ -webkit-transform: translate(-50%, -50%); /* Chrome, Safari, Opera */
124
  }
125
  .fl-bg-video-fallback {
126
  background-position: 50% 50%;
css/fl-builder.css CHANGED
@@ -646,6 +646,10 @@ body .fl-theme-builder-preview-select-item-child:hover {
646
  font-size: 1em;
647
  font-style:italic;
648
  color: #676f7a;
 
 
 
 
649
  }
650
  .fl-builder--saving-indicator:hover {
651
  color: #676f7a;
@@ -662,8 +666,8 @@ body .fl-theme-builder-preview-select-item-child:hover {
662
  color: #fff !important;
663
  text-decoration: none;
664
  }
665
- .fl-builder-buy-button i.fa-external-link-square,
666
- .fl-builder-upgrade-button i.fa-external-link-square {
667
  color: #FFC733;
668
  margin: 0 0 0 6px;
669
  }
@@ -982,6 +986,37 @@ body .fl-theme-builder-preview-select-item-child:hover {
982
  pointer-events: none;
983
  }
984
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
985
  /* @endgroup Pinned UI */
986
 
987
  /* @group Content Panel
@@ -1269,12 +1304,14 @@ body.fl-builder-draggable-is-dragging .fl-builder--panel-arrow {
1269
  height:84px;
1270
  }
1271
  .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail,
 
1272
  .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,
1273
  .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,
1274
  .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail {
1275
  padding:10px;
1276
  }
1277
  .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail,
 
1278
  .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,
1279
  .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,
1280
  .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail {
@@ -1306,6 +1343,7 @@ body.fl-builder-draggable-is-dragging .fl-builder--panel-arrow {
1306
  }
1307
 
1308
  .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail .fl-builder-block-content,
 
1309
  .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail .fl-builder-block-content,
1310
  .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail .fl-builder-block-content,
1311
  .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail .fl-builder-block-content {
@@ -1353,6 +1391,8 @@ body.fl-builder-draggable-is-dragging .fl-builder--panel-arrow {
1353
 
1354
  .fl-builder-block-saved-module.fl-builder-block-global .fl-builder-block-title,
1355
  .fl-builder-block-saved-module:hover .fl-builder-block-title,
 
 
1356
  .fl-builder-block-saved-row.fl-builder-block-global .fl-builder-block-title,
1357
  .fl-builder-block-saved-row:hover .fl-builder-block-title {
1358
  margin-right: 70px;
@@ -2005,6 +2045,7 @@ button.fl-builder-button.fl-builder-bar-title-caret:focus {
2005
  padding: 0 20px;
2006
  }
2007
  .fl-builder-block-saved-row.fl-builder-block-drag-helper:hover .fl-builder-block-content,
 
2008
  .fl-builder-block-saved-module.fl-builder-block-drag-helper:hover .fl-builder-block-content {
2009
  padding: 14px 20px;
2010
  }
@@ -2309,7 +2350,7 @@ button.fl-builder-button.fl-builder-bar-title-caret:focus {
2309
  float: left;
2310
  font-size: 16px !important;
2311
  height: 28px !important;
2312
- font-weight: 100 !important;
2313
  line-height: 28px !important;
2314
  opacity: 0.8;
2315
  filter: alpha(opacity = 80);
@@ -2476,7 +2517,8 @@ button.fl-builder-button.fl-builder-bar-title-caret:focus {
2476
  }
2477
 
2478
  /* Disabled Overlays */
2479
- .fl-node-disabled .fl-row-content-wrap {
 
2480
  opacity: 0.3;
2481
  }
2482
 
@@ -2599,7 +2641,9 @@ button.fl-builder-button.fl-builder-bar-title-caret:focus {
2599
  }
2600
 
2601
  /* Nested Submenus */
2602
- .fl-builder-has-submenu .fl-builder-submenu .fa {
 
 
2603
  float: right;
2604
  height: 12px !important;
2605
  line-height: 12px !important;
@@ -2636,12 +2680,15 @@ button.fl-builder-button.fl-builder-bar-title-caret:focus {
2636
  }
2637
 
2638
  /* Submenu Move Icons */
2639
- .fl-builder-submenu .fa-arrows {
2640
  cursor: move;
2641
  display: none !important;
2642
  }
2643
- .fl-builder-submenu a:hover .fa-arrows {
2644
  display: block !important;
 
 
 
2645
  }
2646
 
2647
  /* Global Submenus */
@@ -3822,7 +3869,8 @@ span.select2-container.select2-container--open {
3822
  font-weight: bold;
3823
  margin: 7px 0 5px 11px;
3824
  }
3825
- .fl-video-field .fl-video-replace {
 
3826
  margin: 0 0 0 11px;
3827
  }
3828
 
@@ -4008,7 +4056,7 @@ span.select2-container.select2-container--open {
4008
  .fl-help-tooltip-icon {
4009
  color: #999 !important;
4010
  cursor: pointer;
4011
- font-family: FontAwesome;
4012
  font-size: 15px !important;
4013
  padding: 5px;
4014
  vertical-align: middle;
@@ -4457,7 +4505,7 @@ body > .fl-builder-tour-dimmed {
4457
  align-items: center;
4458
  justify-content: center;
4459
  content: "\f002";
4460
- font: normal normal normal 14px/1 FontAwesome;
4461
  text-align: center;
4462
  width: 100%;
4463
  height:100%;
646
  font-size: 1em;
647
  font-style:italic;
648
  color: #676f7a;
649
+ align-items: center;
650
+ line-height: 1.2;
651
+ min-width: 180px;
652
+ justify-content: flex-end;
653
  }
654
  .fl-builder--saving-indicator:hover {
655
  color: #676f7a;
666
  color: #fff !important;
667
  text-decoration: none;
668
  }
669
+ .fl-builder-buy-button i.fa-external-link-alt,
670
+ .fl-builder-upgrade-button i.fa-external-link-alt {
671
  color: #FFC733;
672
  margin: 0 0 0 6px;
673
  }
986
  pointer-events: none;
987
  }
988
 
989
+ /* Pinned - Simple UI */
990
+ .fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--panel-header {
991
+ background: transparent;
992
+ border: none;
993
+ z-index: 10;
994
+ }
995
+ .fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--tab-wrap,
996
+ .fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--panel-controls,
997
+ .fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--panel-content {
998
+ display: none;
999
+ }
1000
+ .fl-builder-simple-pinned .fl-builder--content-library-panel .fl-lightbox-wrap {
1001
+ top: 0;
1002
+ }
1003
+ .fl-builder-simple-pinned .fl-builder--content-library-panel .fl-lightbox-header h1 {
1004
+ padding: 14px 28px 15px !important;
1005
+ }
1006
+ .fl-builder--panel-no-settings {
1007
+ display: none;
1008
+ }
1009
+ .fl-builder-simple-pinned .fl-builder--panel-no-settings {
1010
+ display: flex;
1011
+ align-items: center;
1012
+ justify-content: center;
1013
+ position: absolute;
1014
+ top: 0;
1015
+ left: 0;
1016
+ right: 0;
1017
+ bottom: 0;
1018
+ }
1019
+
1020
  /* @endgroup Pinned UI */
1021
 
1022
  /* @group Content Panel
1304
  height:84px;
1305
  }
1306
  .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail,
1307
+ .fl-builder-block.fl-builder-block-saved-column.fl-builder-block-has-thumbnail,
1308
  .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,
1309
  .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,
1310
  .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail {
1311
  padding:10px;
1312
  }
1313
  .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail,
1314
+ .fl-builder-block.fl-builder-block-saved-column.fl-builder-block-has-thumbnail,
1315
  .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,
1316
  .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,
1317
  .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail {
1343
  }
1344
 
1345
  .fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail .fl-builder-block-content,
1346
+ .fl-builder-block.fl-builder-block-saved-column.fl-builder-block-has-thumbnail .fl-builder-block-content,
1347
  .fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail .fl-builder-block-content,
1348
  .fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail .fl-builder-block-content,
1349
  .fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail .fl-builder-block-content {
1391
 
1392
  .fl-builder-block-saved-module.fl-builder-block-global .fl-builder-block-title,
1393
  .fl-builder-block-saved-module:hover .fl-builder-block-title,
1394
+ .fl-builder-block-saved-column.fl-builder-block-global .fl-builder-block-title,
1395
+ .fl-builder-block-saved-column:hover .fl-builder-block-title,
1396
  .fl-builder-block-saved-row.fl-builder-block-global .fl-builder-block-title,
1397
  .fl-builder-block-saved-row:hover .fl-builder-block-title {
1398
  margin-right: 70px;
2045
  padding: 0 20px;
2046
  }
2047
  .fl-builder-block-saved-row.fl-builder-block-drag-helper:hover .fl-builder-block-content,
2048
+ .fl-builder-block-saved-column.fl-builder-block-drag-helper:hover .fl-builder-block-content,
2049
  .fl-builder-block-saved-module.fl-builder-block-drag-helper:hover .fl-builder-block-content {
2050
  padding: 14px 20px;
2051
  }
2350
  float: left;
2351
  font-size: 16px !important;
2352
  height: 28px !important;
2353
+ /* font-weight: 100 !important; */
2354
  line-height: 28px !important;
2355
  opacity: 0.8;
2356
  filter: alpha(opacity = 80);
2517
  }
2518
 
2519
  /* Disabled Overlays */
2520
+ .fl-node-disabled .fl-row-content-wrap,
2521
+ .fl-node-disabled > .fl-col-content {
2522
  opacity: 0.3;
2523
  }
2524
 
2641
  }
2642
 
2643
  /* Nested Submenus */
2644
+ .fl-builder-has-submenu .fl-builder-submenu .fa,
2645
+ .fl-builder-has-submenu .fl-builder-submenu .fas,
2646
+ .fl-builder-has-submenu .fl-builder-submenu .far {
2647
  float: right;
2648
  height: 12px !important;
2649
  line-height: 12px !important;
2680
  }
2681
 
2682
  /* Submenu Move Icons */
2683
+ .fl-builder-submenu .fa-arrows-alt {
2684
  cursor: move;
2685
  display: none !important;
2686
  }
2687
+ .fl-builder-submenu a:hover .fa-arrows-alt {
2688
  display: block !important;
2689
+ float:right;
2690
+ line-height: 12px !important;
2691
+ height: 12px !important;
2692
  }
2693
 
2694
  /* Global Submenus */
3869
  font-weight: bold;
3870
  margin: 7px 0 5px 11px;
3871
  }
3872
+ .fl-video-field .fl-video-replace,
3873
+ .fl-video-field .fl-video-remove {
3874
  margin: 0 0 0 11px;
3875
  }
3876
 
4056
  .fl-help-tooltip-icon {
4057
  color: #999 !important;
4058
  cursor: pointer;
4059
+ /* font-family: Font Awesome\ 5 Free; */
4060
  font-size: 15px !important;
4061
  padding: 5px;
4062
  vertical-align: middle;
4505
  align-items: center;
4506
  justify-content: center;
4507
  content: "\f002";
4508
+ font: normal normal normal 14px/1 Font Awesome\ 5 Free;
4509
  text-align: center;
4510
  width: 100%;
4511
  height:100%;
css/fl-builder.min.css CHANGED
@@ -1 +1 @@
1
- #wpadminbar,html{transition-duration:.35s}.fl-builder-badge,.fl-builder-bar-title span{vertical-align:middle}.fl-theme-builder-preview-select-title i:before,body .fl-theme-builder-preview-select .fa-caret-down i:before,body .fl-theme-builder-preview-select-item-title i:before{content:"\f078"}.fl-builder-edit .media-frame,.fl-lightbox-wrap{-webkit-backface-visibility:hidden}html{transition-property:margin}html.fl-builder-is-showing-toolbar{margin-top:46px!important}.fl-builder-edit body{position:static!important}.fl-builder-edit:after,.fl-builder-edit:before{z-index:0!important}.fl-builder-edit .fl-builder-content{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none}.fl-builder-bar,.fl-builder-button{-webkit-user-select:none;-moz-user-select:none;-webkit-touch-callout:none}#wpadminbar{transition-property:transform,opacity;transform-origin:bottom;transform-style:preserve-3d;transform:rotateX(89deg) translateY(46px);opacity:0;pointer-events:none;will-change:transform}html.fl-builder-show-admin-bar{margin-top:32px}html.fl-builder-show-admin-bar #wpadminbar{transform:rotateX(0) translateY(0);pointer-events:auto;opacity:1}@media screen and (max-width:782px){html.fl-builder-show-admin-bar{margin-top:46px}}.fl-clear{clear:both}.screen-reader-text{position:absolute;left:-1000em;top:-1000em;height:1px;width:1px;overflow:hidden}.fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(240,240,240,.8);bottom:0;display:none;left:0;position:fixed;right:0;text-align:center;top:0;z-index:12000000}.fl-builder-settings .fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(255,255,255,.8);display:block;position:absolute}.fl-field-loader{color:#B3B3B3!important;font-style:italic}.fl-builder-node-loading{opacity:.35}.fl-builder-node-loading-placeholder{background:url(../img/ajax-loader.svg) center center no-repeat;height:50px}.fl-col-group-has-child-loading{display:-ms-flexbox;display:flex}.fl-col-group-has-child-loading>.fl-builder-node-loading-placeholder{width:50px}html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-desktop,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-desktop-medium,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-medium,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-medium-mobile,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-mobile{display:block!important}.fl-responsive-preview-mask{background:#F7F7F7;bottom:0;left:0;position:fixed;right:0;top:0;z-index:99999}.fl-responsive-preview{bottom:0;left:0;position:absolute;right:0;top:0;margin-top:50px;z-index:100000}#fl-builder-preview-frame,#fl-builder-preview-mask{bottom:0;height:100%;position:fixed;top:0;width:100%;right:0}.fl-builder-preview .fl-responsive-preview{margin:0!important}.fl-responsive-preview-content{background:#F5F7F9;padding:20px 20px 45px}.fl-responsive-preview-message{color:#b3b3b3;font-family:Helvetica,Arial,Verdana,sans-serif;font-size:14px;font-weight:400;padding:0 20px 20px;text-align:center}.fl-builder-button,body .fl-builder-bar .fl-builder-bar-content{display:-ms-flexbox;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important}.fl-responsive-preview-message i{cursor:pointer;margin-left:3px}.fl-responsive-preview .fl-builder-content{box-shadow:0 0 8px rgba(0,0,0,.2);margin-left:auto;margin-right:auto;max-width:100%}#fl-builder-preview-mask{background:url(../img/ajax-loader.svg) center center no-repeat #F7F7F7;left:0;z-index:99999}#fl-builder-preview-frame{left:50%;transform:translateX(-50%);-moz-transform:translateX(-50%);-webkit-transform:translateX(-50%);z-index:100000}.fl-builder-button{color:#676F7A!important;fill:#676F7A!important;background:#E4E7EA;-ms-flex-align:center;align-items:center;display:flex;text-decoration:none;font-size:14px!important;font-weight:500!important;line-height:1!important;height:33px;margin:0;padding:0 12px;cursor:pointer;-webkit-border-radius:3px;-webkit-appearance:none;border:2px solid transparent;border-radius:3px;letter-spacing:normal!important;white-space:nowrap;box-sizing:border-box!important;transition-property:background-color,width;transition-duration:.2s;-ms-user-select:none;user-select:none}.fl-builder-button:hover{background:#dadfe5;color:#222;border:2px solid transparent!important}.fl-builder-button:active{background:#DCDCDC}button.fl-builder-button:focus{position:static;top:auto;outline:0;background:#E4E7EA;border:2px solid #00A0D0!important}.fl-builder-bar .fl-builder-button{height:auto}.fl-builder-button-primary,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button{background:#00A0D2;color:#fff!important;text-decoration:none;border:2px solid transparent!important}.fl-builder-button.fl-builder-button-primary:focus,body.fl-builder--layout-has-drafted-changes .fl-builder-button.fl-builder-done-button:focus{background:#00A0D2;border:2px solid #ffc217!important}.fl-builder-button-primary:hover,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:hover{background:#0197C6;color:#fff!important}.fl-builder-button-primary:active,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:active{background:#0484AC}.fl-builder-button-large{height:30px}.fl-builder-button-small{font-size:11px!important;line-height:1!important}.fl-builder-help-button{color:#b3b3b3;font-size:16px!important}.fl-builder-help-button i{position:relative;top:-1px}.fl-builder-help-button:hover{color:#666}.fl-builder-publish-button{line-height:45px!important}.fl-builder-content-panel-button,.fl-builder-content-panel-button:hover{fill:#00A0D2!important;font-size:30px!important;padding-bottom:4px}.fl-builder-button-silent,.fl-builder-button-silent:hover{padding:0 12px;background:0 0!important;border:2px solid transparent!important;box-shadow:none!important}.fl-builder-done-button,.fl-builder-done-button:hover{font-weight:600}.fl-field .fl-builder-button{display:inline-block;height:auto;padding:11px 12px;vertical-align:middle;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)}.fl-builder-badge{background:#333;border-radius:2px;color:#fff!important;display:inline;font-size:11px!important;font-weight:400;letter-spacing:1px;margin-left:2px;padding:2px 4px}.fl-builder-badge-global{background:#ff9600;transform:translateY(0);transition-duration:.25s;transition-property:transform}.fl-builder-blocks-node-template .fl-builder-badge-global{position:absolute;right:0;top:0}.fl-builder-block:hover .fl-builder-badge-global{display:none}.fl-builder-bar{left:0;position:fixed;right:0;top:0;z-index:999999;-ms-user-select:none;user-select:none;transition-property:transform opacity;transition-duration:.35s;transform-style:preserve-3d;perspective:1100px}.fl-builder-bar.is-hidden{pointer-events:none}.fl-builder-bar.is-hidden .fl-builder-bar-content{transform:translateY(-100%) rotateX(90deg)}.fl-builder--category-select.is-showing .fl-builder-bar-title-caret i,.fl-builder-bar-title.is-showing-menu .fl-builder-bar-title-caret>svg{transform:rotate(180deg)}body .fl-builder-bar .fl-builder-bar-content{display:flex;box-sizing:border-box;background:#fff;border-bottom:2px solid #D5DADD;color:#999;font-size:14px!important;height:48px;transition-property:background-color,opacity,transform;transition-duration:.35s;pointer-events:auto}.fl-builder-draggable-is-dragging .fl-builder-content,.fl-builder-draggable-is-dragging .fl-builder-panel .fl-lightbox,.fl-builder-resizable-is-resizing .fl-builder-content,.fl-builder-resizable-is-resizing .fl-builder-panel .fl-lightbox,body .fl-builder-bar .fl-builder-bar-content.is-muted{pointer-events:none}body .fl-builder-bar .fl-builder-bar-content.is-muted>:not(.fl-builder-publish-actions){-webkit-filter:saturate(20%) blur(1px);filter:saturate(20%) blur(1px);opacity:.4}.fl-builder-bar-title{box-sizing:border-box;color:#333;display:-ms-flexbox;display:flex;-ms-flex:0 0 380px;flex:0 0 380px;max-width:380px;border-right:2px solid #D5DADD;cursor:pointer}.fl-builder-bar-title:hover{background:#fff}.fl-builder-simple .fl-builder-bar-title{cursor:auto}.fl-builder-simple .fl-builder-bar-title:hover{cursor:auto;background:0 0}.fl-builder-bar-title-icon{box-sizing:border-box;background:0 0;-ms-flex:0 0 46px;flex:0 0 46px;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:4px}.fl-builder-bar-title-icon img{max-width:100%!important;height:auto!important}.fl-builder-bar-title.fl-builder-bar-title-no-icon{padding-left:12px}.fl-builder-bar-title-area{box-sizing:border-box;-ms-flex:1 1 100%;flex:1 1 100%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;overflow:hidden;padding:4px}.fl-builder-layout-title,.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{font-size:17px;font-weight:400;line-height:1.3;color:#161B20;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.fl-builder-bar-title-caret,.fl-builder-layout-pretitle,.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{font-size:12px;font-weight:500;line-height:1.3;color:#656d77;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.fl-builder-bar-title-caret i,.fl-theme-builder-preview-select-title i{color:inherit!important;font-size:14px}.fl-builder-bar-title-caret{margin-left:auto!important;-ms-flex:0 0 46px;flex:0 0 46px}.fl-theme-builder-preview-select-title i{padding:12px}.fl-theme-builder-preview-select.fl-builder-button{position:relative;border-radius:0;background:0 0;min-width:0;display:-ms-flexbox;display:flex;-ms-flex:0 0 360px;flex:0 0 360px;max-width:360px;margin:0!important;padding:4px 10px;border:none!important;border-right:2px solid #d5dadd!important;box-shadow:none}.fl-theme-builder-preview-select.fl-builder-button:hover{border:none!important;border-right:2px solid #d5dadd!important}.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-pack:end;justify-content:flex-end;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.fl-theme-builder-preview-select-title div{-ms-flex:1;flex:1}.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{display:block}.fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items{position:absolute;top:calc(48px + 10px);left:10px;width:calc(100% - 20px)!important;background:#fff;border-radius:4px;border:2px solid #D5DADD;border-top:3px solid #00a0d2;box-shadow:0 15px 45px 8px rgba(0,0,0,.04);margin:0!important;padding:0;z-index:-1;font-size:16px;overflow:visible;height:auto!important;max-height:calc(100vh - 66px);min-height:300px;display:-ms-flexbox!important;display:flex!important;-ms-flex-direction:column;flex-direction:column}.fl-theme-builder-preview-select-item{padding:4px 0!important;border-bottom:none!important;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.fl-theme-builder-preview-select-item:hover{text-decoration:none;color:#111;background:0 0!important}body .fl-theme-builder-preview-select .fa-caret-down{float:none}body .fl-theme-builder-preview-select-item-title{padding:10px 15px;color:#222;font-size:14px}body .fl-theme-builder-preview-select-item-children{overflow:auto}body .fl-theme-builder-preview-select-item-child{overflow:hidden;text-overflow:ellipsis;line-height:1.1;margin:0 10px;border:2px solid transparent;border-radius:4px;padding:8px 10px 10px;font-size:14px;font-weight:400;color:#222}body .fl-theme-builder-preview-select-item-child:hover{background:#e6eaed!important}.fl-theme-builder-preview-select-item .fa-caret-down{color:#606D77}.fl-builder-bar-actions{display:-ms-flexbox;display:flex;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex:1 1 100%;flex:1 1 100%;padding:4px}.fl-builder-bar .fl-builder-button{margin:0 0 0 4px}.fl-builder-bar-actions .fl-builder-button:last-child{margin:0}.fl-builder-bar-actions:after{clear:both}.fl-builder-bar .fl-builder-content-panel-button{-ms-flex-align:baseline!important;align-items:baseline!important;padding-top:1px;font-weight:400}.fl-builder-content-panel-button svg{transition-property:transform;transition-duration:.25s;transform:rotate(0) scale(1);transform-origin:center}.fl-builder-content-panel-is-showing .fl-builder-content-panel-button svg{transform:rotate(135deg) scale(1.1) translate(.5px,-.5px)}.fl-builder--saving-indicator{cursor:pointer;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;padding:0 16px;font-size:1em;font-style:italic;color:#676f7a}.fl-builder--saving-indicator:hover{color:#676f7a}.fl-builder--saving-indicator .fa-question-circle{font-size:13px;margin:3px 0 3px 8px}.fl-builder-buy-button,.fl-builder-upgrade-button{background:#F7A407;color:#fff!important;text-decoration:none}.fl-builder-buy-button i.fa-external-link-square,.fl-builder-upgrade-button i.fa-external-link-square{color:#FFC733;margin:0 0 0 6px}.fl-builder-buy-button:hover,.fl-builder-upgrade-button:hover{background:#EE8E0D;color:#fff!important}@media (max-width:980px){.fl-builder--main-menu-panel{width:calc(100% - 20px)!important}.fl-builder--main-menu-panel:before{right:auto;left:20px}.fl-builder-bar-title,.fl-theme-builder-preview-select{-ms-flex:1 .5 380px!important;flex:1 .5 380px!important}}@media (max-width:620px){.fl-theme-builder-preview-select.fl-builder-button{display:none}}@media (max-width:500px){.fl-builder--main-menu-panel:before,.fl-builder-bar-title-area,.fl-builder-panel-drag-handle,.fl-builder-panel:before{display:none}.fl-builder--main-menu-panel,.fl-builder-panel{width:auto!important;top:44px!important;left:0!important;right:0!important;bottom:0!important;border-radius:0!important;box-shadow:none!important}.fl-builder--main-menu-panel{border-left:transparent!important;border-right:transparent!important;border-bottom:transparent!important;max-height:calc(100% - 44px)!important}.fl-builder-bar-title{-ms-flex:0 0 100px!important;flex:0 0 100px!important}.fl-builder--panel-header{border-radius:0!important;cursor:default!important}.fl-builder--panel-header .fl-builder--tabs{cursor:default!important}.fl-builder-publish-actions{width:100%!important}.fl-builder-bar-actions .fl-builder-button{padding:0 8px!important}}.fl-builder--preview-actions{display:none;position:fixed;top:4px;left:4px;z-index:100008;padding:4px;-ms-flex-pack:center;justify-content:center;background:#fff;border-radius:4px}.fl-builder-preview .fl-builder--preview-actions{display:-ms-flexbox;display:flex}.fl-builder--preview-actions .device-icons{color:#555;background:#e4e4e4;border:none!important;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;text-decoration:none;font-size:14px!important;line-height:1!important;margin:0 4px 0 0;padding:0 6px;cursor:pointer;-webkit-border-radius:3px;-webkit-appearance:none;border-radius:3px}.fl-builder--preview-actions .device-icons i{margin:0 6px}@keyframes fl-builder-ui-pin-zone-pulse{0%,100%{opacity:1;filter:alpha( opacity=1 )}50%{opacity:.5;filter:alpha( opacity=35 )}}.fl-builder-ui-pin-zone{animation:fl-builder-ui-pin-zone-pulse 2s infinite;transition:width .3s ease;background:rgba(0,160,210,.5);bottom:0;top:0;position:fixed;width:35px;z-index:100001}.fl-builder-ui-show-pin-zone-left .fl-builder-ui-pin-zone-left,.fl-builder-ui-show-pin-zone-right .fl-builder-ui-pin-zone-right{width:75px}.fl-builder-ui-pin-zone-left{left:0}.fl-builder-ui-pin-zone-right{right:0}.fl-builder-content-panel-pin-zone .fl-builder-content-panel-button{display:-ms-flexbox!important;display:flex!important;background:rgba(0,160,210,.5)!important;padding:2px 4px;width:80px;animation:fl-builder-ui-pin-zone-pulse 2s infinite}.fl-builder-content-panel-pin-zone .fl-builder-content-panel-button svg{display:none}.fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button{width:120px}.fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button svg{display:none!important;width:100%;transform:none!important;fill:#00A0D2!important;border-radius:3px}.fl-builder-ui-is-pinned .fl-builder-content-panel-button,.fl-builder-ui-pinned-container .fl-lightbox-controls{display:none}.fl-builder-content-panel-pin-zone .fl-builder-done-button{-webkit-filter:grayscale(100%);filter:grayscale(100%)}.fl-builder-panel.fl-builder-ui-pinned{top:48px!important;bottom:0!important;height:auto!important;border-radius:0;border:none;box-shadow:none;animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s;z-index:9}.fl-builder-panel.fl-builder-ui-pinned-right{left:auto!important;right:0;border-left:2px solid #d5dadd}.fl-builder-panel.fl-builder-ui-pinned-left{left:0;right:auto;border-right:2px solid #d5dadd}.fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header{border-radius:0!important}.fl-builder-ui-pinned-container .fl-lightbox-wrap{position:absolute;z-index:9}.fl-builder-ui-pinned-container .fl-lightbox{position:absolute;top:0;bottom:0;left:0;right:0;width:auto!important;height:auto;border-radius:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s}.fl-builder-ui-pinned-container .fl-lightbox-header-wrap{border-radius:0}.fl-builder-ui-pinned-container .fl-lightbox.ui-draggable .fl-lightbox-header{cursor:auto}.fl-builder-ui-pinned-container .fl-lightbox-header h1{padding:12px 20px 10px!important}.fl-builder-ui-pinned-content-transform{transform:scale(1);transform-origin:center top 0}.fl-builder-ui-pinned-collapse{cursor:pointer;display:none;position:absolute!important;bottom:2px;padding:5px;border:2px solid transparent;background:0 0;width:36px;height:36px;border-radius:4px;fill:#778794;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:center;justify-content:center}.fl-builder-ui-pinned-collapse:focus,.fl-builder-ui-pinned-collapse:hover{top:auto!important;background:0 0;border:2px solid transparent;outline:0;fill:#00A0D2}.fl-builder-ui-pinned-collapse:focus{background:#E4E7EA}.fl-builder-ui-pinned-collapse>*{margin:auto;line-height:1}.fl-builder-ui-pinned-collapse svg g{fill:inherit}.fl-builder-ui-is-pinned-right .fl-builder-ui-pinned-right-collapse{display:-ms-flexbox;display:flex;left:-40px}.fl-builder-ui-is-pinned-left .fl-builder-ui-pinned-left-collapse{display:-ms-flexbox;display:flex;right:-40px}.fl-builder-ui-pinned-collapse i[data-toggle=show],.fl-builder-ui-pinned-is-collapsed i[data-toggle=hide]{display:none}.fl-builder-ui-pinned-is-collapsed i[data-toggle=show]{display:block}.fl-builder-ui-is-pinned-left [data-toggle=hide],.fl-builder-ui-is-pinned-right [data-toggle=show]{transform:rotateY(180deg)}.fl-builder-ui-pinned-is-collapsed .fl-lightbox{box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}.fl-builder-ui-pinned-is-collapsed .fl-builder--panel-header{display:none}@keyframes fl-builder-show-panel{from{transform:scale(.8)}to{transform:scale(1)}}.fl-builder--search-results-panel,.fl-builder-panel{box-sizing:border-box;position:fixed!important;right:20px;top:calc(48px + 10px);width:380px;bottom:20px;background:#F5F7F9;color:#676F7A;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:14px;border-radius:4px;box-shadow:0 8px 40px 4px rgba(0,0,0,.3);z-index:10000007;will-change:transform;display:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fl-builder-panel{transform-origin:top right;animation-name:fl-builder-show-panel;animation-duration:.15s;animation-fill-mode:both}.fl-builder--search-results-panel{position:absolute;right:0;top:93px;left:0;bottom:0;width:auto!important;border:none;border-radius:0;box-shadow:none;min-height:100px;max-height:calc(100vh - 54px);overflow:auto;z-index:1}.fl-builder-content-panel-is-showing .fl-builder-panel,.fl-builder-search-results-panel-is-showing .fl-builder--search-results-panel{display:block}.fl-builder-panel .fl-lightbox .fl-builder-panel-drag-handle,.fl-builder-ui-is-pinned .fl-builder--panel-arrow,.fl-lightbox-width-full .fl-builder-panel-drag-handle,body.fl-builder-draggable-is-dragging .fl-builder--panel-arrow{display:none}.fl-builder-content-panel-is-showing .fl-builder-panel.fl-builder--current-view-templates{width:520px}.fl-builder--search-results-panel .fl-builder--no-results{text-align:center;padding:50px 20px}.fl-builder--panel-arrow{position:absolute;top:-13px;right:10px}.fl-builder--panel-arrow polygon{fill:#00a0d2}.fl-builder--panel-header{background:#fff;border-top:3px solid #00a0d2;border-bottom:2px solid #e6eaed;border-top-right-radius:4px;border-top-left-radius:4px}.fl-builder-ui-is-pinned .fl-builder--panel-header{border-top-color:transparent}.fl-builder-panel-drag-handle{position:absolute;top:7px;left:10px;fill:#ccd4da;width:6px}.fl-builder-ui-is-pinned-left .fl-builder-panel-drag-handle{left:auto;right:10px}.fl-builder--panel-header .fl-builder--panel-controls{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;position:relative}.fl-builder--panel-header .fl-builder--panel-controls .fl-builder-content-group-select{-ms-flex:1 1;flex:1 1}.fl-builder--panel-header .fl-builder--panel-controls .fl-builder-panel-search{-ms-flex:0 0;flex:0 0;padding:0 10px 6px 0;margin-left:-4px}.fl-builder--panel-controls .fl-builder-panel-search button{width:38px;background:0 0!important;border:2px solid transparent!important;font-size:inherit;height:38px;padding:0}.fl-builder--panel-controls .fl-builder-panel-search button:active,.fl-builder--panel-controls .fl-builder-panel-search button:focus{top:0;outline:0}.fl-builder-panel-search button svg{height:auto;width:20px}.fl-builder-panel-search button.fl-builder-dismiss-panel-search svg{width:16px}.fl-builder-panel-search button svg .filled-shape{fill:#000}.fl-builder--panel-controls .fl-builder-panel-search button:active svg .filled-shape,.fl-builder--panel-controls .fl-builder-panel-search button:focus svg .filled-shape{fill:#00A0D2}.fl-builder-panel-search .fl-builder-panel-search-input{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background:#fff}.fl-builder-panel-search.is-showing-input .fl-builder-panel-search-input{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;padding:0 10px 6px}.fl-builder-panel-search-input input{-ms-flex:1 1 100%;flex:1 1 100%;border:2px solid #e6eaed;background:#fff;border-radius:4px;margin-right:4px;padding:10px;color:#333}.fl-builder-panel-search-input input:focus{border-color:#0197C6;outline:0}.fl-builder-panel-search-input button{-ms-flex:0 0 38px;flex:0 0 38px}.fl-builder-panel-content-wrap{bottom:0;height:auto;left:0;overflow:hidden;position:absolute;right:0;top:43px}.fl-builder-panel-content{padding-bottom:60px}.fl-builder-blocks-section{border-top:2px solid #e6eaed}.fl-builder--panel-view .fl-builder-blocks-section:first-child{border-top:none}.fl-builder-blocks-group:first-child{padding:20px 0 0}.fl-builder-blocks-group .fl-builder-blocks-section-group-name{display:block;padding:0 30px 15px;color:#000;font-size:20px;font-weight:600;line-height:1.4}.fl-builder-blocks-section .fl-builder-block,.fl-builder-blocks-section .fl-builder-blocks-section-title{display:block;line-height:1.1;padding:15px 20px}.fl-builder--template-collection-section-name,.fl-builder-blocks-section .fl-builder-blocks-section-title{display:inline-block;font-weight:700;font-size:12px;line-height:1.2;text-transform:uppercase;color:#333;padding:4px 10px 4px 15px;margin:0!important;background:#e6eaed;border-bottom-right-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top}.fl-builder-blocks-section .fl-builder-blocks-section-title i{color:#bfbfbf;float:right}.fl-builder-blocks-section-content{overflow:auto;padding:10px 10px 20px}.fl-builder-blocks-section-content:after{float:none;clear:both}.fl-builder-blocks-section-content.fl-builder-modules,.fl-builder-blocks-section-content.fl-builder-rows,.fl-builder-blocks-section-content.fl-builder-widgets{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.fl-builder-blocks-section-content .fl-builder-block-module,.fl-builder-blocks-section-content .fl-builder-block-row{-ms-flex:1 1 50%;flex:1 1 50%;width:50%;box-sizing:border-box}.fl-builder--search-results-panel .fl-builder-blocks-section-content .fl-builder-block-module{-ms-flex:1 1 100%;flex:1 1 100%;width:100%}.fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content{display:block}.fl-builder-blocks-section-content .fl-builder-block{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;font-size:14px;line-height:1.1;font-weight:500;color:#727272}.fl-builder-block{position:relative;height:47px}.fl-builder-block.fl-builder-block-col-group{height:84px}.fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail{padding:10px;height:auto}.fl-builder-block:hover{overflow:visible;z-index:1}.fl-builder-block:hover .fl-builder-block-content{display:block;box-sizing:border-box;position:absolute;top:0;left:0;width:100%;padding:15px 20px;border-radius:4px;background:#fff;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);text-decoration:none;color:#111;cursor:move;overflow:hidden}.fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-blocks-node-template .fl-builder-block,.fl-builder-blocks-section-content .fl-builder-block .fl-builder-block-details{position:relative}.fl-builder-block-module:hover .fl-builder-block-content{width:auto;min-width:100%}.fl-builder-block .fl-builder-block-content .fl-builder-block-visual{display:block;margin-bottom:7px}.fl-builder-block-drag-helper .fl-builder-block-content .fl-builder-block-visual{display:none!important}.fl-builder-block .fl-builder-block-content .fl-builder-block-visual.fl-cols-visual{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;height:30px}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{-ms-flex:1 100%;flex:1 100%;background:#464a4c;height:30px;margin:0 2px;border-radius:2px}.fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{background:#000}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:first-child{margin-left:0!important}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:last-child{margin-right:0!important}.fl-cols-visual.left-right-sidebar .fl-cols-visual-col:first-child,.fl-cols-visual.left-right-sidebar .fl-cols-visual-col:last-child,.fl-cols-visual.left-sidebar .fl-cols-visual-col:first-child,.fl-cols-visual.right-sidebar .fl-cols-visual-col:last-child{-ms-flex-preferred-size:60px;flex-basis:60px}.fl-builder-block-saved-module.fl-builder-block-global .fl-builder-block-title,.fl-builder-block-saved-module:hover .fl-builder-block-title,.fl-builder-block-saved-row.fl-builder-block-global .fl-builder-block-title,.fl-builder-block-saved-row:hover .fl-builder-block-title{margin-right:70px}.fl-builder-block-module:nth-child(even):hover .fl-builder-block-content{left:auto;right:0}.fl-builder-block-thumbnail{border-radius:4px;background-size:contain;background-repeat:no-repeat;background-position:center;background-color:rgba(0,0,0,.06);margin-bottom:10px;transform-origin:bottom;transition-property:transform,box-shadow;transition-duration:.15s}.fl-builder-block:hover .fl-builder-block-thumbnail{transform:scale(1.05);box-shadow:0 20px 40px rgba(0,0,0,.08)}.fl-builder-block .fl-builder-block-icon{margin-right:7px;fill:#000;display:inline-block;width:20px;height:20px;vertical-align:middle}.fl-builder-block-thumbnail:before{content:"";display:block;padding-top:50%}.fl-builder-block-thumbnail img{max-width:100%;max-height:160px;margin:0;-o-object-fit:cover;object-fit:cover}.fl-builder-blocks-section-content .fl-builder-block{box-shadow:0 0 0 transparent;transition-property:box-shadow;transition-duration:.15s}.fl-builder-blocks-section-content .fl-builder-block i,.fl-user-template-actions i{color:#000;margin-right:10px}.fl-builder-blocks-separator{background:#f1f1f1;height:6px}.fl-builder-block:hover .fl-builder-badge{background:#2ea2cc}.ui-sortable-helper .fl-builder-badge{display:none!important}.fl-builder-modules-cta a{color:#999!important;display:block!important;font-size:12px!important;font-style:italic!important;padding:15px 20px!important;line-height:16px!important}.fl-builder-modules-cta a:hover{background:#e5e5e5!important;color:#666!important;text-decoration:none!important}.fl-builder-modules-cta a:focus{text-decoration:none!important}.fl-builder-modules-cta .fa{float:right!important;font-size:14px!important;margin:3px 0 0 9px!important}.fl-builder--panel-message{text-align:center;padding:40px 20px;font-size:16px}.fl-builder--panel-message .fl-builder-button{display:inline-block;padding:10px}.fl-builder--panel-cta{padding:20px 30px;font-size:16px;text-align:center}.fl-builder--panel-cta a{color:inherit;text-decoration:none}.fl-builder--panel-cta a:hover{text-decoration:none}.fl-builder-block-template-image{margin:5px 0 10px;max-width:100%;border:1px solid #dfdfdf}.fl-builder-block .fl-builder-block-title{overflow:hidden;text-overflow:ellipsis;vertical-align:middle;line-height:1.3}.ui-sortable-helper .fl-builder-block-template-image{display:none!important}@keyframes fl-builder-template-item-enter{from{transform:translateY(100px) scale(.3);opacity:0}to{transform:scale(1);opacity:1}}.fl-builder--template-collection{clear:both;padding:10px 0}.fl-builder--template-collection-section-content{padding:0 10px}.fl-builder--template-collection-item{box-sizing:border-box;width:50%;float:left;padding:10px;cursor:pointer;font-size:13px;transform-origin:center;opacity:1}.fl-builder--template-thumbnail{background-size:cover;background-clip:content-box;background-position:center top;background-color:#fff;border:2px solid transparent;transform-origin:bottom;transition-property:transform,box-shadow;transition-duration:.15s}.fl-builder--template-collection-item[data-id="0"] .fl-builder--template-thumbnail,.fl-user-template .fl-builder--template-thumbnail{border-color:#e4e7ea}.fl-builder--template-thumbnail:before{display:block;content:"";padding-top:120%}.fl-builder--template-thumbnail:hover{transform:scale(1.05);box-shadow:0 20px 40px rgba(0,0,0,.08)}.fl-builder--template-name{text-align:center;padding:4px 0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fl-builder--template-collection-section{padding-bottom:10px;border-bottom:1px solid #dfdfdf}.fl-builder--template-collection-section:after,.fl-builder--template-collection-section:before{content:"";display:block;clear:both}.fl-builder--template-collection-section-name{padding:15px 10px 10px}span.fl-builder-block-no-node-templates{display:block;padding:15px 20px;text-align:center}span.fl-builder-block-no-node-templates:hover{cursor:default}.fl-builder-blocks-section-content .fl-builder-node-template-actions{bottom:0;cursor:default;display:none;position:absolute;right:0;top:0}.fl-builder-blocks-section-content .fl-builder-node-template-delete,.fl-builder-blocks-section-content .fl-builder-node-template-edit{display:inline;cursor:pointer;margin:0;padding:15px 10px;text-align:center;width:30px}.fl-builder-block-details .fl-builder-node-template-delete,.fl-builder-block-details .fl-builder-node-template-edit{padding-top:0!important}.fl-builder-blocks-section-content .fl-builder-node-template-delete i,.fl-builder-blocks-section-content .fl-builder-node-template-edit i{margin:0}.fl-builder-blocks-section-content .fl-builder-node-template-delete:hover i,.fl-builder-blocks-section-content .fl-builder-node-template-edit:hover i{color:#444}.fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-node-template-actions{display:block}.ui-sortable-helper .fl-builder-node-template-delete,.ui-sortable-helper .fl-builder-node-template-edit{display:none!important}.fl-builder--tabs{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;position:relative;-ms-flex-pack:start;justify-content:flex-start;-ms-flex-align:center;align-items:center}.fl-builder-panel .fl-builder--panel-header{cursor:move;position:absolute;top:0;left:0;right:0;z-index:9}.fl-builder-panel .fl-builder--tabs{-ms-flex-pack:distribute;justify-content:space-around;padding:0 24px;min-height:46px;cursor:pointer}.fl-builder--tab-wrap{-ms-flex:1 1 100%;flex:1 1 100%;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:stretch;align-items:stretch;-ms-flex-pack:justify;justify-content:space-between}.fl-builder--tabs button,.fl-builder--tabs button:active,.fl-builder--tabs button:focus,.fl-builder--tabs button:hover{-ms-flex:1 1 100%;flex:1 1 100%;display:inline-block;text-decoration:none;color:inherit;text-align:center;letter-spacing:normal!important;padding:5px;cursor:pointer;font-size:14px!important;font-weight:600!important;line-height:1.4!important;background:0 0!important;outline:0!important;border:2px solid transparent;border-radius:4px;margin:7px 0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important;top:0;transition-property:background,color;transition-duration:.25s}.fl-builder--current-view-name,.fl-builder-drop-zone{text-align:left;text-overflow:ellipsis;white-space:nowrap}.fl-builder--tabs button:focus{background:#e6eaed!important}.fl-builder--tabs button.is-showing{color:#0086b0}.fl-builder--panel-view{display:none;overflow:hidden}.fl-builder--panel-view.is-showing{display:block}.fl-builder--content-library-panel .fl-builder--panel-view.is-showing{position:absolute;top:96px;bottom:0;left:0;right:0;width:auto;height:auto}.fl-builder--content-library-panel.single-view .fl-builder--panel-view.is-showing{top:52px}.fl-builder--content-library-panel.ui-draggable-dragging{height:500px!important}.fl-builder--content-library-panel .fl-builder-drop-zone{display:none!important}.fl-builder--panel-header .fl-builder--tabs{cursor:move}.fl-builder--category-select{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;position:relative}.fl-builder--selector-display{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;position:relative;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center;color:#161B20;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;cursor:pointer;font-size:13px;font-weight:700;line-height:16px;border-radius:4px}.fl-builder--selector-display-label{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;font-size:inherit;line-height:inherit;width:100%;padding:0!important;color:#6D6D6D;background:0 0;border:2px solid #e4e7ea;border-radius:4px;font-family:inherit}.fl-builder--selector-display-label:active,.fl-builder--selector-display-label:hover{top:0;color:inherit;background:0 0;border:2px solid #e4e7ea;border-radius:4px}.fl-builder--selector-display-label:focus{top:0;color:inherit;background:0 0;border:2px solid #00A0D2;outline:0}.fl-builder--group-label{color:inherit;-ms-flex:0 0 0%;flex:0 0 0%;padding:9px 12px 9px 10px;background:#e6eaed;border-top-left-radius:2px;border-bottom-left-radius:2px}.fl-builder--current-view-name{-ms-flex:1 1 100%;flex:1 1 100%;color:inherit;overflow:hidden;font-weight:600;padding:9px 10px}.fl-builder--selector-menu{display:none;color:#293138;position:absolute;top:46px;left:0;width:100%;background:#fff;border-radius:4px;box-shadow:0 0 20px 2px rgba(0,0,0,.2);overflow:visible}.fl-builder--selector-menu:before{bottom:100%;right:8px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}.fl-builder--category-select.is-showing .fl-builder--selector-menu{display:-ms-flexbox;display:flex;max-height:calc(100vh - 150px)}.fl-builder--category-select.is-showing .fl-builder--selector-menu .fl-builder--menu{margin:10px 0;-ms-flex:1 100%;flex:1 100%;overflow:auto}button.fl-builder-button.fl-builder-bar-title-caret{margin:4px}button.fl-builder-button.fl-builder-bar-title-caret:focus{background-color:#e6eaed!important;border-color:transparent!important}.fl-builder--menu{margin-bottom:2px}.fl-builder--menu>a,.fl-builder--menu>button,.fl-builder--menu>span{display:block;padding:8px 10px 10px;border-radius:4px;color:inherit;text-decoration:none;background:0 0!important;border:2px solid transparent!important;font-weight:400;font-family:inherit}.fl-builder--menu>a:active,.fl-builder--menu>a:focus,.fl-builder--menu>a:hover,.fl-builder--menu>button:active,.fl-builder--menu>button:focus,.fl-builder--menu>button:hover{background:#e6eaed!important;border:2px solid transparent!important;top:0}.fl-block-col-resize-feedback,.fl-block-overlay-title,.fl-builder-block-drag-helper,.fl-builder-block.ui-draggable-dragging,.fl-builder-drop-zone,.fl-builder-empty,.fl-builder-has-submenu>ul.fl-builder-submenu li a{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}.fl-builder--menu>a:focus,.fl-builder--menu>button:focus{outline:0;color:inherit;text-decoration:none}.fl-builder--menu .fl-inset{padding-left:35px;font-size:14px;line-height:1.25}.fl-builder--menu a.fl-template-collection{color:#161B20}.fl-builder--menu>:after{clear:both}.fl-builder--menu * .fl-builder--menu-item-accessory{float:right;color:#000;text-transform:uppercase;text-align:center;min-width:20px;letter-spacing:2px}.fl-builder--menu * .fl-builder--menu-item-accessory i{font-size:1em;margin-top:2px}.fl-builder--menu .fl-builder-video-wrap iframe{display:block;margin:4px 0;width:100%}.fl-builder-publish-actions{display:-ms-flexbox;display:flex;box-sizing:border-box;position:absolute;top:0;right:0;width:380px;max-width:100%;height:46px;padding:4px;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:end;justify-content:flex-end;opacity:1;pointer-events:auto;transform:scaleX(1) translateX(0);transform-origin:right;transition-property:transform,opacity;transition-duration:.15s}.fl-builder-publish-actions.is-hidden{transform:scaleX(.23) translateX(68px);opacity:0;pointer-events:none}.fl-builder-bar .fl-builder-button-group{display:-ms-flexbox;display:flex;-ms-flex-preferred-size:100%;flex-basis:100%}.fl-builder-bar .fl-builder-button-group>.fl-builder-button{border-radius:0;margin-left:0;-ms-flex-preferred-size:100%;flex-basis:100%;text-align:center;-ms-flex-pack:distribute;justify-content:space-around;box-shadow:none}.fl-builder-bar .fl-builder-button-group>.fl-builder-button:first-child{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.fl-builder-bar .fl-builder-button-group>.fl-builder-button:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.fl-builder-publish-actions-click-away-mask{display:none;position:fixed;top:0;left:0;right:0;height:100vh;background:0 0}.fl-builder-dragging .fl-builder-content:not(.fl-builder-empty){padding:16px 0}.fl-builder-empty{display:none;border:2px dashed #969696;border-radius:8px;color:#909090;font-size:20px;font-weight:700;margin:10px;padding:250px 20px;position:relative;text-align:center;text-transform:uppercase}.fl-builder-edit .fl-builder-empty{display:block}.fl-builder-block-drag-helper,.fl-builder-block.ui-draggable-dragging{background:rgba(255,255,255,.95)!important;border:2px solid #000;border-radius:4px;box-shadow:0 0 8px rgba(0,0,0,.2);-moz-box-shadow:0 0 8px rgba(0,0,0,.2);-webkit-box-shadow:0 0 8px rgba(0,0,0,.2);color:#333!important;font-size:13px!important;height:47px!important;line-height:40px!important;overflow:hidden;padding:0 20px;position:fixed!important;text-overflow:ellipsis;white-space:nowrap;width:180px!important;z-index:100010!important;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-line-pack:center;align-content:center;-ms-flex-pack:start;justify-content:flex-start}.fl-builder-block.fl-builder-block-drag-helper:hover{padding:0;box-shadow:none}.fl-builder-block-drag-helper:hover .fl-builder-block-content{position:static;padding:0 20px}.fl-col-has-highlight-guide .fl-col-content,.fl-col-highlight,.fl-row-highlight .fl-col-group{position:relative}.fl-builder-block-saved-module.fl-builder-block-drag-helper:hover .fl-builder-block-content,.fl-builder-block-saved-row.fl-builder-block-drag-helper:hover .fl-builder-block-content{padding:14px 20px}.fl-builder-block-drag-helper .fl-builder-block-icon{fill:#000;margin-top:-10px}.fl-builder-drop-zone{animation:fl-builder-drop-zone-pulse 2s infinite;background:#00A2D7;border-radius:4px;color:#fff!important;display:block;font-weight:400;font-size:12px;letter-spacing:1px;line-height:14px;margin:10px;padding:6px 8px 5px;position:relative;text-shadow:none;text-transform:none;overflow:hidden;z-index:10}@keyframes fl-builder-drop-zone-pulse{0%,100%{background-color:#00A2D7}50%{background-color:#79DEFF}}.fl-builder-drop-zone-global{animation:fl-builder-drop-zone-global-pulse 2s infinite;background:#ff9600}.fl-field,.fl-lightbox{animation-duration:.25s}@keyframes fl-builder-drop-zone-global-pulse{0%,100%{background-color:#FFBC5C}50%{background-color:#ff9600}}.fl-builder-content>.fl-builder-drop-zone{margin:10px 20px}.fl-row-content>.fl-builder-drop-zone{margin:3px 7px}.fl-col-has-cols>.fl-col-content>.fl-builder-drop-zone{margin:3px 10px}.fl-sortable-disabled>.fl-builder-drop-zone{display:none!important}.fl-col-group-equal-height.fl-col-group-align-center .fl-col-content>.fl-builder-drop-zone{width:100%}.fl-row-highlight{padding:16px 0}.fl-row-highlight .fl-row-content{border:2px dashed rgba(203,205,206,.5);padding:8px;border-radius:6px}.fl-row-highlight.fl-node-global .fl-row-content{border-color:#ff9600}.fl-col-highlight{padding:8px}.fl-col-highlight .fl-col-content{border-style:dashed!important;border-color:#00a0d2!important;border-radius:4px;min-height:100px;overflow-x:hidden;width:100%;border-width:2px!important}.fl-col-has-cols.fl-col-highlight>.fl-col-content{padding:8px}.fl-col-highlight.fl-node-global .fl-col-content{border-color:#ff9600!important}.fl-builder-simple .fl-col-highlight .fl-col-content{border:none!important}.fl-col-highlight-guide{background:rgba(0,160,210,.05);border:2px solid #00A0D2;border-radius:4px;bottom:4px;left:4px;position:absolute;right:4px;top:4px;z-index:1}.fl-node-global .fl-col-highlight-guide{border-color:#ff9600!important;background-color:rgba(255,150,0,.06)!important}.fl-col-has-highlight-guide .fl-block-overlay{background:0 0;border-color:transparent}.fl-col-has-highlight-guide .fl-block-col-resize{display:none}.fl-col-has-highlight-guide .fl-col-highlight .fl-col-content{border-color:transparent!important}.fl-col-drop-target{bottom:8px;display:none;left:-9px;position:absolute;top:8px;width:18px;z-index:1}.fl-col-highlight .fl-col-drop-target{display:block}.fl-col-drop-target-last{left:auto;right:-9px}.fl-col-drop-target .fl-builder-drop-zone{bottom:0;left:2px;margin:0;padding:0;position:absolute;right:2px;top:0}.fl-col-group-drop-target{display:none;left:8px;height:18px;position:absolute;right:8px;top:-9px;z-index:1}.fl-row-highlight .fl-col-group-drop-target{display:block}.fl-col-group-drop-target-last{top:auto;bottom:-9px}.fl-col-group-drop-target .fl-builder-drop-zone{bottom:2px;left:0;margin:0;padding:0;position:absolute;right:0;top:2px}.fl-row-content>.fl-col-group-drop-target{position:static}.fl-row-content>.fl-col-group-drop-target .fl-builder-drop-zone{height:18px;position:static}.fl-row-drop-target{display:none;left:0;height:24px;margin-top:-28px;position:absolute;right:0;z-index:1}.fl-row-highlight .fl-row-drop-target{display:block}.fl-row-drop-target-last{margin-top:4px}.fl-row .fl-row-drop-target .fl-builder-drop-zone{bottom:0;left:4px;margin:0;position:absolute;right:4px;top:0}.fl-builder-content>.fl-row-drop-target{margin:0;position:static}.fl-builder-dragging .fl-builder-content.fl-builder-empty>.fl-row-drop-target{bottom:10px;display:block;height:auto;left:0;position:absolute;right:0;top:10px}.fl-builder-content .fl-row-drop-target .fl-builder-drop-zone{margin-bottom:0;margin-top:0}.fl-col-group:focus,.fl-col:focus,.fl-module:focus,.fl-row:focus{outline:0}.fl-sortable-proxy{display:none}.fl-block-overlay,.fl-block-overlay *{text-shadow:none;-webkit-touch-callout:none}.fl-block-overlay-active{position:relative}.fl-block-overlay-actions{background:#00A0D2;float:left;height:30px;margin:-1px -1px 0;padding:0 4px;text-shadow:none;border-bottom-right-radius:5px;border-top-left-radius:3px}.fl-row-overlay-header-bottom .fl-block-overlay-actions{border-radius:0 5px 0 3px}.fl-builder-col-resizing .fl-block-overlay-actions,.fl-builder-row-resizing .fl-block-overlay-actions{overflow:hidden}.fl-block-overlay-actions>span{display:block;float:left}.fl-block-overlay-actions i{color:#fff!important;cursor:pointer;display:block!important;float:left;font-size:16px!important;height:28px!important;font-weight:100!important;line-height:28px!important;opacity:.8;filter:alpha(opacity=80);text-align:center;width:32px!important}.fl-block-overlay-actions i:hover{opacity:1;filter:alpha(opacity=100)}.fl-block-overlay-actions>i:first-child{padding-left:4px}.fl-block-overlay-actions>i:last-child{padding-right:2px}.fl-block-overlay-actions .fl-block-move{cursor:move}.fl-block-overlay-title{color:#fff!important;float:left;font-size:14px;height:30px;line-height:29px;margin-right:2px;padding:0 12px 0 8px}.fl-col-overlay,.fl-module-overlay,.fl-row-overlay{background:rgba(190,239,255,0);color:#fff}.fl-row-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:0;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;left:0;position:absolute;top:-33px;right:0;z-index:100006}.fl-row-overlay.fl-row-menu-active,.fl-row-overlay.fl-row-menu-active.fl-block-overlay.fl-block-overlay-global{z-index:100007}.fl-row-full-width .fl-row-overlay{left:2px;right:2px;bottom:2px}.fl-row-overlay-header-bottom{bottom:-32px!important;top:0}.fl-row-overlay-header-bottom .fl-block-overlay-header{position:absolute;bottom:0}.fl-block-overlay-active .fl-row-content-wrap{position:relative}.fl-block-overlay-active .fl-row-content{position:relative;z-index:100007!important}.fl-builder-row-resizing .fl-col.fl-block-overlay-active,.fl-builder-row-resizing .fl-module.fl-block-overlay-active{position:static}.fl-col-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:8px;cursor:pointer;left:8px;position:absolute;right:8px;top:8px;z-index:100008}.fl-module-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:4px;cursor:pointer;left:4px;min-height:32px;position:absolute;right:4px;top:4px;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-module-overlay{cursor:default}.fl-module-adjust-height{padding-bottom:15px;padding-top:15px}.fl-block-overlay-global{background:rgba(255,150,0,0);border:2px solid #F7A407;border-radius:4px}.fl-block-overlay-global .fl-block-overlay-actions{background:#F7A407}.fl-block-overlay-title-global{background:#fff;color:#ff9600!important;font-size:11px;letter-spacing:1px;margin-left:4px;padding:2px 4px;vertical-align:top}.fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,0);cursor:pointer;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-row-overlay{cursor:default}.fl-builder-row-template .fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,0);cursor:default;z-index:100006}.fl-block-overlay-global.fl-row-overlay .fl-block-col-resize{display:none}.fl-block-overlay-muted .fl-row-overlay{background:rgba(85,93,102,0);border:2px solid #555D66}.fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions{background:#555D66}.fl-block-overlay-muted .fl-row-overlay .fl-block-col-resize{display:none}.fl-node-disabled .fl-row-content-wrap{opacity:.3}.fl-block-col-resize{bottom:0!important;position:absolute;top:0!important;width:6px}.fl-block-col-resize-e{cursor:ew-resize;left:auto!important;right:-2px!important}.fl-block-col-resize-w{cursor:ew-resize;left:-7px!important}.fl-block-col-resize-handle-wrap{margin:-4px 0 0 -5px;padding:0 5px;position:absolute;top:50%!important}.fl-block-col-resize-e .fl-block-col-resize-handle-wrap{margin-left:-6px}.fl-block-col-resize-handle{background:#fff;border:2px solid #00A0D2;border-radius:50%;height:12px;width:12px}.fl-node-global .fl-block-col-resize-handle{border-color:#ff9600}.fl-block-col-resize-feedback{color:#333!important;display:none;font-size:11px!important;position:absolute}.fl-block-col-resize-feedback-left,.fl-block-col-resize-feedback-right{background:#fff;border:1px solid #3ba0ff;padding:2px 4px}.fl-block-col-resize-feedback-left{right:20px;top:-7px}.fl-block-col-resize-feedback-right{left:20px;top:-7px}.fl-builder-has-submenu{position:relative}.fl-builder-has-submenu>ul.fl-builder-submenu{background:#00A0D2;box-shadow:0 0 20px rgba(0,0,0,.2);border-radius:0 4px 4px;display:none;left:0;list-style:none;margin:0;padding:6px 0;position:absolute;text-align:left;top:100%;width:165px;z-index:100008}.fl-builder-has-submenu>ul.fl-builder-submenu li{list-style:none;margin:0;padding:0}.fl-builder-submenu-right ul.fl-builder-submenu{left:auto;right:0}.fl-builder-has-submenu.fl-builder-submenu-open>ul.fl-builder-submenu{display:block}.fl-builder-has-submenu>ul.fl-builder-submenu li a{border-bottom:0 none;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#fff!important;display:block;line-height:13px;font-size:13px;font-weight:400;opacity:.8;filter:alpha(opacity=80);overflow:hidden;padding:6px 12px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.fl-builder-has-submenu>ul.fl-builder-submenu li a:hover{background:#0197C6;color:#fff;opacity:1;filter:alpha(opacity=100);text-decoration:none}.fl-builder-actions-title,.fl-builder-alert-lightbox .fl-lightbox-message{color:#333!important;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:16px!important}.fl-builder-has-submenu .fl-builder-submenu .fa{float:right;height:12px!important;line-height:12px!important;position:relative;right:-5px;width:14px!important}.fl-builder-has-submenu .fl-builder-has-submenu .fl-builder-submenu{display:none;left:100%;top:0}.fl-builder-has-submenu .fl-builder-submenu-right.fl-builder-has-submenu .fl-builder-submenu{left:auto;right:100%}.fl-builder-has-submenu .fl-builder-has-submenu:hover .fl-builder-submenu{display:block}.fl-builder-submenu-sep{padding:7px 0!important}.fl-builder-submenu-sep div{border-bottom:1px solid rgba(255,255,255,.4)}.fl-block-col-move,.fl-block-col-move-parent{cursor:move;position:relative}.fl-builder-submenu .fa-arrows{cursor:move;display:none!important}.fl-builder-submenu a:hover .fa-arrows{display:block!important}.fl-block-overlay-global ul.fl-builder-submenu{background:#ff9600!important}.fl-block-overlay-global ul.fl-builder-submenu li a:hover{background:#fa3}.fl-builder-actions-lightbox .fl-lightbox{display:block;width:300px;border-radius:4px}.fl-builder-actions-lightbox .fl-lightbox-content-wrap{display:block}.fl-builder-actions-lightbox .fl-builder-actions{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:25px;text-align:center}.fl-builder-actions-title{display:block;margin-bottom:20px}.fl-builder-actions .fl-builder-button{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;margin-bottom:7px;min-height:36px}.fl-builder-alert-lightbox{padding:20px;z-index:30000000;top:0;pointer-events:auto}.fl-builder-alert-lightbox .fl-lightbox{max-width:440px;width:auto}.fl-builder-alert-lightbox .fl-lightbox-content-wrap{display:block}.fl-builder-alert-lightbox .fl-lightbox-message{line-height:24px;padding:30px}@keyframes fl-builder-content-section-entry{from{transform:translateY(150px) translateX(100px) scale(.3);opacity:0}to{transform:translateY(0) translateX(0) scale(1);opacity:1}}.fl-template-category-select{width:180px!important}.fl-template-selector .fl-builder-settings-section{margin:0 0 10px}.fl-template-selector .fl-builder-settings-fields{height:470px}.fl-template-selector .fl-builder-settings-tab{width:560px}.fl-template-selector .fl-builder-settings-tab-description{font-size:15px!important;margin:0!important;padding:10px 0 25px;text-align:center}.fl-template-preview{float:left;margin:0 25px 30px 0;position:relative;text-align:center;width:170px}.fl-template-preview.fl-last{margin-right:0}.fl-template-image{border:1px solid #d9d9d9;cursor:pointer;margin-bottom:12px;height:164px;overflow:hidden}.fl-template-image:hover{border-color:red}.fl-template-image img{max-height:none;width:100%}.fl-template-preview span{display:block;text-align:center}.fl-user-template-category-name{background:#f2f2f2;border-bottom:3px solid #dfdfdf;border-top:2px solid #dfdfdf;font-weight:700;padding:8px 15px}.fl-user-templates{border-bottom:1px solid #dfdfdf;padding:10px 0 20px}.fl-builder--user-templates-section-content{border-bottom:2px solid #e6eaed;padding:10px}.fl-builder--user-templates-section-content:first-child{padding-top:0}.fl-builder--user-templates-section-content:last-child,.fl-user-templates:last-child{border-bottom:none}.fl-builder--user-templates-section-name{font-weight:700;font-size:16px;color:#333;z-index:9999;padding:15px 10px;margin:0 10px}@keyframes fl-list-item-entry{from{opacity:0;transform:scale(.5) translateY(100px)}to{opacity:1;transform:scale(1) translateY(0)}}.fl-builder--save-new-user-template,.fl-user-template{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;font-size:16px;font-weight:200;line-height:1.1;padding:10px 20px;color:#6d6d6d}.fl-user-template:hover{cursor:pointer;background:#fff;box-shadow:0 6px 20px rgba(0,0,0,.08);text-decoration:none;color:#111;padding-right:68px}.fl-user-template-name{overflow:hidden;text-overflow:ellipsis;-ms-flex:1;flex:1}.fl-user-template-actions{display:none;bottom:0;position:absolute;right:0;top:0}.fl-user-template:hover .fl-user-template-actions{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center}.fl-user-template-actions a{display:inline-block;padding:15px 0;width:30px}.fl-user-template:hover a:hover i{color:#444!important}.fl-user-templates-message{display:none}.fl-user-template-thumbnail{-ms-flex:0;flex:0;margin-right:20px}.fl-user-template-thumbnail .fl-builder--template-thumbnail{background-size:cover;background-position:center top;width:45px}.fl-user-template-thumbnail .fl-builder--template-thumbnail:hover{box-shadow:none;transform:scale(1);transition-property:none}.fl-builder--save-new-user-template .fl-user-template-thumbnail .fl-builder--template-thumbnail{border-style:dashed;border-width:2px;border-color:#ccd4da}.fl-builder--save-new-user-template .fl-save-control{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex:1;flex:1}.fl-builder--save-new-user-template .fl-save-control input{background:0 0;border:none!important;-ms-flex:1;flex:1;font-size:16px;margin-right:10px;margin-left:-12px;color:#000}.fl-builder--save-new-user-template .fl-save-control input::-webkit-input-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input::-moz-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input:-ms-input-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input:-moz-placeholder{color:#777}@keyframes fl-slide-in-right{from{transform:translateX(50px)}to{transform:translateX(0)}}.fl-builder--save-new-user-template .fl-save-control button{display:none;animation-name:fl-slide-in-right;animation-duration:.25s;background-color:#00a0d2;border:none;padding:0 15px}.fl-save-control-mask{display:none;background:0 0;position:absolute;top:-50px;left:0;bottom:0;right:0;z-index:-1;min-height:80vh}.fl-builder-templates-cta{margin-bottom:20px}.fl-builder-templates-cta p{display:inline-block!important;width:75%!important;font-size:14px!important;line-height:1.5!important;margin-bottom:0!important}.fl-builder-templates-cta .fl-builder-upgrade-button{font-size:13px!important;line-height:13px!important;position:relative;top:8px;left:15px;padding:1px 12px}.fl-builder-settings-message,.fl-builder-settings-message *{font-size:15px!important;line-height:23px!important}.single-fl-builder-template .fl-content{width:100%!important}form.fl-builder-settings{height:100%;margin:0;padding:0;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.fl-builder-settings-message{padding:20px 25px!important;background:#f2f2f2!important}.fl-builder-preview-loader{position:relative;top:-2px;margin-left:3px}.fl-lightbox-header .fl-builder-preview-loader{margin:0;position:absolute;right:40px;top:15px}@keyframes fl-grab-attention{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}.fl-lightbox-width-slim .fl-form-table{margin:20px 25px 10px 15px!important;width:calc(100% - 60px)}.fl-lightbox-width-slim .fl-form-table th{display:block;padding:10px 0 0 12px!important}.fl-lightbox-width-slim .fl-form-table td{display:block}.fl-lightbox-width-slim .fl-form-table td:first-child{padding-left:10px!important}.fl-lightbox-width-slim .fl-form-table .fl-field[data-type=editor] td:first-child{padding-left:0!important}.fl-field-label .fl-field-responsive-toggle,.fl-lightbox-width-slim .fl-field-control-wrapper .fl-field-responsive-toggle{display:none}.fl-lightbox-width-slim .fl-field-label .fl-field-responsive-toggle{display:inline-block;padding:0 5px!important}.fl-lightbox-width-slim .fl-builder-settings-fields select{width:100%}.fl-lightbox-width-slim .fl-color-picker{display:-ms-flexbox;display:flex;width:auto}.fl-lightbox-width-slim .fl-color-picker-clear{-ms-flex:0 0 50px;flex:0 0 50px}.fl-lightbox-width-slim .mce-menubtn.mce-fixed-width button{width:28px!important}.fl-lightbox-width-slim .mce-btn[aria-label=Blockquote],.fl-lightbox-width-slim .mce-btn[aria-label=Fullscreen]{display:none}.fl-lightbox-width-slim .fl-builder-field-multiple{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;position:relative}.fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-control,.fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-label{width:100%!important}.fl-lightbox-width-slim .fl-builder-field-multiple .fl-builder-field-actions{position:absolute!important;top:0;right:0;width:70px}.fl-lightbox-width-slim .fl-field[data-type=time] select{width:auto}.fl-builder-settings-tabs{margin:6px;border:2px solid #e6eaed;border-radius:4px;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;overflow:hidden}.fl-builder-content-group-select{padding:0 10px 6px;display:none}.fl-builder-content-group-select select{display:block;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;padding:8px 10px;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;border:2px solid #e4e7ea;color:#161B20}select:focus{border-width:2px!important;border-style:solid!important;border-color:#00a0d2!important;outline:0!important}.fl-legacy-settings-tab{background:url(../img/ajax-loader.svg) center center no-repeat;height:100px}.fl-builder-settings-tab:first-child .fl-legacy-settings-tab{background:0 0;height:auto}body .fl-builder-settings-tabs>*{box-sizing:border-box;color:#676F7A!important;fill:#676F7A!important;background:0 0;border:2px solid transparent;border-radius:0;margin:0;outline:0;padding:6px 15px;text-decoration:none!important;font-size:14px;font-weight:400!important;-ms-flex:0 0 auto;flex:0 0 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;text-align:center}.fl-builder-settings-tabs-more g,.fl-builder-settings-tabs-more path,.fl-builder-settings-tabs-more svg,.fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon path{fill:inherit}body .fl-builder-settings-tabs>:first-child{border-top-left-radius:3px;border-bottom-left-radius:3px}body .fl-builder-settings-tabs>:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}body .fl-lightbox-width-slim .fl-builder-settings-tabs>*{-ms-flex:1 1 auto;flex:1 1 auto;padding:6px 8px}body .fl-builder-settings-tabs>.fl-builder-settings-tabs-more{-ms-flex:0 0 60px;flex:0 0 60px;display:none;margin-left:auto;-ms-flex-pack:center;justify-content:center}.fl-builder-settings-tabs-more svg{width:16px;height:auto;margin:auto}body .fl-lightbox-has-tab-overflow .fl-builder-settings-tabs-more{display:-ms-flexbox;display:flex}.fl-builder-settings-tabs>:active,.fl-builder-settings-tabs>:hover{top:0;color:#333;background:0 0;border:2px solid transparent}.fl-builder-settings-tabs>:focus{top:0;outline:0;border:2px solid transparent;background:0 0;color:#0086b0;fill:#0086b0}.fl-builder-settings-tabs .fl-active,.fl-builder-settings-tabs-more.fl-contains-active,.fl-builder-settings-tabs-overflow-menu .fl-active{color:#0086b0!important;fill:#0086b0!important;position:relative;background:#e6eaed}.fl-builder-settings-tabs .fl-active.fl-overflowed,.fl-builder-settings-tabs .fl-overflowed{display:none!important}.fl-builder-settings-tabs .error{color:#d03436;padding-right:10px}.fl-builder-settings-tabs .error .fl-error-icon,.fl-builder-settings-tabs-overflow-menu .error .fl-error-icon{background:url(../img/sprite.png) -148px -5px no-repeat;display:inline-block;height:16px;margin-left:7px;position:relative;top:3px;width:16px}.fl-builder-settings-tabs-more.fl-contains-errors{fill:#d03436!important}.fl-builder-settings-tab{display:none;width:auto!important}.fl-builder-settings-tab.fl-active{display:block}.fl-builder-settings-tab-description{background:#e4e7ea;padding:10px 15px;border-radius:4px;margin:20px}.fl-builder-settings-tab-description a{text-decoration:underline!important}.fl-builder-settings-tab-description a:hover{color:#333}.fl-builder-settings-tabs-overflow-menu{display:none;position:absolute;left:0;right:0;border:2px solid #e6eaed;border-top:3px solid #00a0d2;border-radius:4px;background:#fff;z-index:9999;margin:0 6px;padding:10px;-ms-flex-direction:column;flex-direction:column;box-shadow:0 0 20px 2px rgba(0,0,0,.2)}.fl-builder-settings-tabs-overflow-menu:before{bottom:100%;right:20px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#00a0d2;border-width:10px;margin-left:-10px}.fl-builder-settings-tabs-overflow-menu>a{display:block;padding:10px 15px;font-size:14px;font-weight:600!important;border:2px solid transparent;border-radius:4px;outline:0}.fl-builder-settings-tabs-overflow-menu>a:hover{background:#e6eaed;text-decoration:none}.fl-builder-settings-tabs-overflow-click-mask{display:none;position:fixed;top:0;bottom:0;left:0;right:0;background:0 0;z-index:9}.fl-form-table{background:none;border:none;width:calc(100% - 35px)}.fl-form-table tbody{border:none}.fl-form-table tr,.fl-form-table tr:nth-child(even){background:0 0}.fl-form-table td,.fl-form-table th{background:0 0!important;border:none!important;font-weight:400!important;text-align:left!important}.fl-form-table th{padding:10px 10px 10px 30px!important;vertical-align:top!important;width:200px!important}.fl-form-table td:first-child{padding-left:30px!important}.fl-form-table th label{color:#333;width:auto;max-width:100%}.fl-photo-field .fl-photo-preview-img img,.fl-video-field .fl-video-preview-img img{max-width:60px}.fl-form-table td{padding:8px 10px}.fl-lightbox-width-slim .fl-form-table td{padding:4px 0 10px}.fl-builder-settings-fields{margin:0;overflow:hidden;position:relative;-ms-flex:1 100%;flex:1 100%;visibility:hidden}.fl-lightbox-header .fl-builder-settings-fields{height:auto;margin:0;position:absolute;right:10px;top:10px}.fl-builder-settings-fields .fl-nanoscroller-content{padding:0}.fl-builder-settings-fields .fl-field-control-wrapper{position:relative}.fl-field{animation-delay:.1s}.fl-builder-settings-fields input[type=email],.fl-builder-settings-fields input[type=file],.fl-builder-settings-fields input[type=number],.fl-builder-settings-fields input[type=password],.fl-builder-settings-fields input[type=search],.fl-builder-settings-fields input[type=tel],.fl-builder-settings-fields input[type=text],.fl-builder-settings-fields input[type=url],.fl-builder-settings-fields select,.fl-builder-settings-fields textarea{background:#fff!important;border-color:transparent!important;border-style:solid;border-width:2px;border-radius:4px!important;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);color:#333!important;display:inline;font-size:13px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px 9px;width:auto;box-sizing:border-box}.fl-builder-settings-fields input[type=email],.fl-builder-settings-fields input[type=file],.fl-builder-settings-fields input[type=number],.fl-builder-settings-fields input[type=password],.fl-builder-settings-fields input[type=search],.fl-builder-settings-fields input[type=tel],.fl-builder-settings-fields input[type=text],.fl-builder-settings-fields input[type=url],.fl-builder-settings-fields select{height:36px!important}.fl-builder-settings-fields input[type=number]{width:70px}.fl-builder-lightbox .fl-builder-settings-fields input[type=email]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=file]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=number]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=password]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=search]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=tel]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=text]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=url]:focus,.fl-builder-lightbox .fl-builder-settings-fields select:focus,.fl-builder-lightbox .fl-builder-settings-fields textarea:focus{border-width:2px!important;border-style:solid!important;border-color:#00a0d2!important;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)!important}.fl-builder-settings-fields ::-webkit-input-placeholder{color:#999!important;font-size:13px}.fl-builder-settings-fields input:-moz-placeholder{color:#999;font-size:13px}.fl-builder-settings-fields ::-moz-placeholder{color:#999!important;font-size:13px}.fl-builder-settings-fields input:-ms-input-placeholder{color:#999;font-size:13px}.fl-builder-settings-fields label{display:inline-block;font-weight:400;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin-bottom:3px}.fl-builder-settings-fields select{-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;color:#000;margin:0 0 2px;padding:2px 10px;padding-right:30px!important;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important}.fl-builder-settings-fields select[multiple]{height:60px;background-image:none!important}.fl-builder-custom-field select,.fl-photo-field select{-webkit-box-shadow:none;border-color:#e6eaed!important}.fl-font-field .fl-font-field-font{margin-bottom:4px;width:calc(70% - 5px)!important}.fl-font-field .fl-font-field-weight{width:30%!important}.fl-lightbox-width-slim input.text-full+.fl-field-description,.fl-lightbox-width-slim select+.fl-field-description{display:block;padding:8px 10px;margin:0}.fl-field[data-type=dimension] .fl-field-control-wrapper{display:-ms-flexbox;display:flex}.fl-field[data-type=dimension] .fl-field-description{padding-top:9px}.fl-field[data-type=dimension] .fl-field-responsive-toggle{padding:9px 9px 0 0}.fl-dimension-field-units{display:-ms-flexbox;display:flex}.fl-dimension-field-unit{padding-right:5px}.fl-dimension-field-unit input{max-width:60px;width:auto!important}.fl-dimension-field-unit label{padding:5px 0 0;font-size:12px;color:inherit!important;display:block;text-align:center}.fl-link-field-search input{box-shadow:none!important;width:100%!important;padding:3px 9px!important}.fl-link-field-search #as-original-link-search{width:100%}.fl-builder-settings-section{border-top:2px solid #E6EAED}.fl-builder-settings-section:first-child{border-top:none!important}.fl-custom-query .fl-builder-settings-section{border-top:2px solid #E6EAED!important}.fl-builder-settings-description{padding:0 10px 10px;margin:0;font-style:italic;opacity:.75}.fl-builder-settings-fields table{margin:20px 0}.fl-builder-settings-fields h3.fl-builder-settings-title{display:inline-block;background:#E6EAED;padding:4px 10px 4px 15px;margin:0;text-transform:uppercase!important;border-bottom-right-radius:4px;font-size:12px!important;font-weight:700;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.wp-core-ui h1,.wp-core-ui h2,.wp-core-ui h3,.wp-core-ui h4,.wp-core-ui h5,.wp-core-ui h6{color:#333}.wp-core-ui .submitbox .submitdelete{color:#a00}.wp-core-ui button{font-weight:400}.wp-core-ui input[type=email],.wp-core-ui input[type=file],.wp-core-ui input[type=number],.wp-core-ui input[type=password],.wp-core-ui input[type=search],.wp-core-ui input[type=tel],.wp-core-ui input[type=text],.wp-core-ui input[type=url],.wp-core-ui select,.wp-core-ui textarea{background-color:#fff;border-color:#dfdfdf;border-style:solid;border-width:1px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#333;font-weight:400}.wp-core-ui input[type=email]:focus,.wp-core-ui input[type=file]:focus,.wp-core-ui input[type=number]:focus,.wp-core-ui input[type=password]:focus,.wp-core-ui input[type=search]:focus,.wp-core-ui input[type=tel]:focus,.wp-core-ui input[type=text]:focus,.wp-core-ui input[type=url]:focus,.wp-core-ui select:focus,.wp-core-ui textarea:focus{background:0 0;border-color:#aaa}.wp-core-ui input[type=search]{background-image:none;padding:6px}.fl-field-responsive-setting{display:inline-block}.fl-field-responsive-setting-medium,.fl-field-responsive-setting-responsive{display:none}i.fl-field-responsive-toggle{color:grey;cursor:pointer;display:inline-block;font-size:15px!important;height:auto;line-height:18px!important;text-align:left;vertical-align:middle;width:20px}i.fl-field-responsive-toggle:hover{color:#000}.fl-builder-settings-fields input.text-full,.fl-builder-settings-fields textarea{width:100%}.fl-color-picker{cursor:pointer}.fl-color-picker .fl-color-picker-clear{box-sizing:border-box}.fl-color-picker .fl-color-picker-clear:hover{background-color:#ededed}.colorpicker input{padding:0!important;font-size:11px!important;color:#fff!important;width:29px!important;height:auto!important;background:0 0!important;border:none!important}.colorpicker .colorpicker_hex input{width:45px!important}.fl-builder-custom-field{background:#fff;border:2px solid transparent;border-radius:4px;padding:7px 10px;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);min-height:36px;box-sizing:border-box}.fl-builder-field-multiple .fl-builder-custom-field{cursor:move}.fl-builder-custom-field a{color:#21759b!important;text-decoration:underline!important}.fl-builder-custom-field a:hover{color:#d54e21!important}.fl-builder-custom-field label.error{margin-top:5px}.fl-photo-field .fl-photo-preview{display:-ms-flexbox;display:flex}.fl-photo-field .fl-photo-select,.fl-photo-field.fl-photo-empty .fl-photo-preview{display:none}.fl-photo-field.fl-photo-empty .fl-photo-select{display:block}.fl-photo-field .fl-photo-preview-img{line-height:0;margin:5px 0}.fl-photo-field .fl-photo-preview select{margin:8px 0 8px 10px;width:200px}.fl-photo-field.fl-photo-no-attachment .fl-photo-preview select{display:none}.fl-photo-field .fl-photo-preview-filename{display:none;font-size:14px;font-weight:700;margin:7px 0 5px 11px}.fl-photo-field.fl-photo-no-attachment .fl-photo-preview-filename{display:inline-block;word-break:break-all}.fl-multiple-photos-field .fl-multiple-photos-select,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-add,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-count,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-edit,.fl-multiple-photos-lightbox .gallery-settings,.fl-photo-field.fl-photo-no-attachment .fl-photo-edit{display:none}.fl-photo-field .fl-photo-edit{margin:0 0 0 11px}.fl-multiple-photos-field .fl-multiple-photos-add,.fl-photo-field .fl-photo-remove,.fl-photo-field .fl-photo-replace{margin:0 0 0 8px}.fl-builder-edit .media-modal{z-index:9999991}.fl-builder-edit .media-modal-backdrop{z-index:999999}.fl-builder-edit .media-modal-content h1{font-family:inherit}.fl-builder-edit .media-modal-content .thumbnail{padding:0;border:none;border-radius:0}.fl-builder-edit button.button-link.media-modal-close{position:absolute;box-shadow:none;-webkit-box-shadow:none}.fl-builder-edit .media-frame.hide-menu{visibility:visible}span.select2-container.select2-container--open{z-index:9999999}.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-select{display:inline}.fl-multiple-photos-count{font-weight:700;margin-bottom:3px}.fl-video-field .fl-video-select,.fl-video-field.fl-video-empty .fl-video-preview{display:none}.fl-video-field.fl-video-empty .fl-video-select{display:block}.fl-video-field .fl-video-preview-img{float:left;line-height:0;margin:5px 0}.fl-video-field .fl-video-preview-img .dashicons.dashicons-media-video{display:block;font-size:60px;height:60px;line-height:60px;width:60px}.fl-video-field .fl-video-preview-filename{display:inline-block;font-size:14px;font-weight:700;margin:7px 0 5px 11px}.fl-video-field .fl-video-replace{margin:0 0 0 11px}.fl-multiple-audios-field .fl-multiple-audios-select,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-add,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-edit{display:none}.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-select{display:block}.fl-multiple-audios-field .fl-multiple-audios-add{margin:0 0 0 8px}.fl-icon-field .fl-icon-select,.fl-icon-field.fl-icon-empty .fl-icon-preview{display:none}.fl-icon-field.fl-icon-empty .fl-icon-select{display:block}.fl-icon-field .fl-icon-preview i{display:inline-block;font-size:28px;margin:10px 10px 9px;vertical-align:middle}.fl-icon-field .fl-icon-remove{margin:0 0 0 8px}.fl-builder-hidden-editor{display:none}.fl-builder-settings .wp-switch-editor{background:#ebebeb;border:1px solid #e5e5e5;border-radius:0;color:#333}.fl-builder-settings .wp-editor-container{border:1px solid #e5e5e5}.fl-builder-settings .mce-toolbar .mce-btn-group .mce-btn{margin:2px 0}.fl-builder-settings .mce-menubtn.mce-fixed-width button{width:100px}.fl-builder-settings .mce-menubtn.mce-fixed-width span{width:100%}.mce-close:active,.mce-close:hover,.mce-toolbar .mce-btn button:active,.mce-toolbar .mce-btn button:hover,.mce-window .mce-btn button:active,.mce-window .mce-btn button:hover{background:0 0;border:none}.mce-ico{font-family:tinymce,Arial!important}.mce-toolbar i.mce-ico{font:400 20px/1 dashicons!important}.fl-builder-edit form#wp-link,.popover[class*=tour-],ul.as-list{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}.wp-core-ui .quicktags-toolbar input.button.button-small{margin:1px!important}.wp-editor-container textarea.wp-editor-area{background:0 0;border:none;padding:10px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.fl-builder-edit form#wp-link{color:#000;font-size:13px}.fl-builder-edit form#wp-link #link-options label{display:block;margin-bottom:2px}.fl-builder-edit form#wp-link #link-options label span{padding-right:10px;vertical-align:middle}.fl-builder-edit form#wp-link #link-options input[type=text]{display:inline-block;height:auto;margin:5px 0 0;padding:3px 5px;width:80%}.fl-builder-edit form#wp-link .query-results{top:225px}.fl-code-field{border:1px solid #E6E6E6;border-left:none}.ace_editor,.ace_editor *{font-family:Monaco,Menlo,"Ubuntu Mono","Droid Sans Mono",Consolas,monospace!important;font-size:12px!important;font-weight:400!important;letter-spacing:0!important}.fl-layout-field-option{border:2px solid #d9d9d9;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;cursor:pointer;float:left;line-height:0;max-width:23%;margin:0 1% 2%;padding:5px}.fl-layout-field-option-selected,.fl-layout-field-option:hover{border-color:red}.fl-layout-field-option img{max-width:100%}.fl-link-field .fl-link-field-input-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row}.fl-link-field-input{width:auto!important;-ms-flex:1 1 100%;flex:1 1 100%}.fl-link-field .fl-link-field-input-wrap button{-ms-flex:0 0 0%;flex:0 0 0%;margin-left:5px}.fl-link-field-search{display:none;border:2px solid #e6eaed;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;margin:4px 0 0;padding:10px}.fl-link-field-search-title{display:block;margin:0 0 3px 2px}.fl-link-field-search-cancel{margin-top:6px}.fl-help-tooltip{display:inline-block;position:relative}.fl-help-tooltip-icon{color:#999!important;cursor:pointer;font-family:FontAwesome;font-size:15px!important;padding:5px;vertical-align:middle}.fl-help-tooltip-text{background:#fff;border:1px solid #ccc;box-shadow:0 0 5px #ccc;-moz-box-shadow:0 0 5px #ccc;-webkit-box-shadow:0 0 5px #ccc;display:none;font-weight:400;left:23px;padding:10px 13px;position:absolute;top:-6px;width:250px;z-index:1000;border-radius:4px}.fl-lightbox-width-slim .fl-help-tooltip-text{top:26px;left:-30px}.fl-field-control .fl-form-field{margin-bottom:0}.fl-form-field-preview-text i{display:inline-block;font-size:18px;line-height:22px;margin-bottom:5px}.fl-builder-field-actions{padding-left:0!important;padding-right:0!important;text-align:center;width:85px}.fl-builder-field-actions i{color:#999!important;cursor:pointer;font-size:13px!important;line-height:29px!important;width:16px}.fl-builder-field-actions i:hover{color:#000!important}.fl-builder-field-actions i.fl-builder-field-copy,.fl-builder-field-actions i.fl-builder-field-delete{margin-left:5px}.fl-builder-field-actions i.fl-builder-field-move{cursor:move}.fl-builder-field-dd-helper{background:#ccc;height:30px!important;float:left;width:130px!important}.fl-builder-field-dd-zone{border:1px dashed #ccc;height:30px}.fl-builder-field-actions-single .fl-builder-field-delete,.fl-builder-field-actions-single .fl-builder-field-move{display:none!important}.fl-lightbox-width-slim .fl-builder-field-actions-single .fl-builder-field-copy{float:right!important}.fl-builder-field-multiple .fl-builder-field-actions,.fl-builder-field-multiple .fl-field-control,.fl-builder-field-multiple .fl-field-label{padding-top:2px!important;padding-bottom:2px!important}.fl-builder-field-multiple .fl-builder-field-actions{min-width:70px!important}.fl-builder-field-multiple[data-field=icons] .fl-builder-field-actions{width:70px!important}.fl-builder-field-multiple.ui-sortable-helper .fl-field-control{width:60%}.fl-builder-field-multiple.ui-sortable-helper .fl-builder-field-actions{display:none}.fl-builder-widget-settings input{display:inline-block!important;margin:5px 10px 8px!important}.fl-builder-lightbox-loading{background:url(../img/ajax-loader.svg) center center no-repeat;height:100px}.fl-builder-settings .error,.fl-builder-settings input.error{color:#d03436!important}.fl-builder-settings label.error,.fl-builder-settings p.error{color:#d03436;display:block;margin-top:5px}.fl-builder-settings .fl-form-table .fl-field-description{color:#464646;font-style:normal;margin-left:2px}.fl-lightbox .fl-field-connection{right:-1px}.fl-lightbox .fl-field-connection-content{border:2px solid transparent!important;background:#e4e7ea!important}.fl-field-connection-content .fl-field-connection-label{color:#676f7a!important}ul.as-selections{background-color:#fff;border:none;border-radius:4px;box-shadow:none;color:#333;font-size:12px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px;width:auto}ul.as-selections.loading{background:url(../img/ajax-loader-small.svg) 98% center no-repeat}ul.as-selections li.as-selection-item{background:#d4eaf6;border:none;font-size:11px;line-height:14px;padding:8px 15px;border-radius:4px;margin:2px}ul.as-selections li.as-selection-item.blur{background:#f4f4f4}ul.as-selections li.as-selection-item a.as-close{line-height:12px}ul.as-selections li.as-original{margin:0}ul.as-selections li.as-original input{height:auto;font-size:12px;margin:0;padding:0;box-shadow:none}ul.as-list{margin:0;font-size:13px;color:#000;background-color:#fff;background-color:rgba(255,255,255,.95);z-index:2;box-shadow:0 0 10px rgba(0,0,0,.1);border:none;border:1px solid #dfdfdf;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px}li.as-message,li.as-result-item{border:none}li.as-result-item.active{background:#e5e5e5;border-radius:0;color:#333;text-shadow:none}li.as-result-item em{background:0 0!important;color:#333!important;font-size:12px;padding:0!important;font-weight:700}.fl-custom-query-filter{display:none}.fl-custom-query .fl-field[data-type=suggest] select{margin-bottom:5px;width:100%}.fl-builder-service-settings{position:relative}.fl-builder-service-error{color:red!important;padding:15px 0 0}.fl-builder-service-account-delete{color:red!important;margin-left:10px;position:relative;top:2px}#fl-field-visibility_user_capability .fl-field-description,.fl-builder-service-connect-row .fl-field-description{background:#f0f0f0;color:#333!important;display:block;float:none;margin:10px 0 0;padding:10px}#fl-field-visibility_user_capability .fl-field-description a,.fl-builder-service-connect-row .fl-field-description a{color:#21759b!important;text-decoration:underline!important}.fl-ordering-field-option{background:#fff;border:1px solid #dfdfdf;border-radius:3px;cursor:move;margin-bottom:5px;padding:5px 10px}.fl-ordering-field-option .fa{color:#ccc;float:right;line-height:16px}#tiptip_holder{z-index:1000000}#tiptip_holder.tip_top #tiptip_arrow_inner{border-top-color:#333}#tiptip_holder.tip_bottom #tiptip_arrow_inner{border-bottom-color:#333}#tiptip_holder.tip_right #tiptip_arrow_inner{border-right-color:#333}#tiptip_holder.tip_left #tiptip_arrow_inner{border-left-color:#333}#tiptip_content{background:#333;box-shadow:none}.fl-builder-getting-started-video{line-height:0!important;padding:10px}.fl-builder-getting-started-video iframe{border:none;height:326px;width:100%}.fl-builder-tour-actions .fl-builder-actions-title{font-size:14px!important;line-height:19px}.fl-builder-tour-mask{bottom:0;left:0;position:fixed;right:0;top:0;z-index:100000000}.fl-builder-tour-dimmed{background:rgba(0,0,0,.7);bottom:0;left:0;position:absolute;right:0;top:0}body>.fl-builder-tour-dimmed{position:fixed}.tour-backdrop{z-index:110000}.popover[class*=tour-]{border:1px solid #ccc;border-radius:0;box-shadow:0 0 40px rgba(0,0,0,.3);color:#666;font-size:13px;font-weight:400;line-height:18px;max-width:none;padding:0;width:300px;z-index:100000001}.popover[class*=tour-].bottom>.arrow{border-bottom-color:#ccc}.popover[class*=tour-].bottom>.arrow:after{border-bottom-color:#f7f7f7}.popover[class*=tour-] .popover-title{border-radius:0;color:#333;letter-spacing:normal;text-transform:none}.popover[class*=tour-] .fa-times{color:#b3b3b3;cursor:pointer;font-size:16px;padding:5px;position:absolute;right:3px;top:2px}.popover[class*=tour-] .fa-times:hover{color:#666}.popover[class*=tour-] .popover-content{border-bottom:1px solid #d9d9d9;padding:13px 15px}.popover[class*=tour-] .fl-builder-tour-next{display:block;float:none;width:100%}.popover-navigation button{min-height:36px}.fl-builder-shortcode-mask-wrap{position:relative}.fl-builder-shortcode-mask{bottom:-1px;left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fl-builder--search{border:2px solid transparent;position:relative;padding:0;width:54px;transition-property:width;transition-delay:.1s;transition-duration:.15s}.fl-builder--search.is-expanded{border:2px solid #00A0D0}.fl-builder--search input[type=text],.fl-builder--search input[type=text]:focus{background-color:transparent;border:none!important;box-sizing:border-box;width:100%;font-size:16px;text-align:center}.fl-builder--search:before{display:-ms-flexbox;display:flex;top:0;left:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;content:"\f002";font:normal normal normal 14px/1 FontAwesome;text-align:center;width:100%;height:100%;position:absolute;pointer-events:none;color:rgba(128,128,128,.6);font-size:17px;opacity:1;transition-property:opacity;transition-duration:.15s}.fl-builder--main-menu-panel,.fl-builder-ui-keyboard-shortcuts{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important}.fl-builder--search.has-text:before,.fl-builder--search.is-expanded:before{opacity:0}.fl-builder--search input::-webkit-input-placeholder{color:rgba(128,128,128,0)!important;transition:color .25s}.fl-builder--search input:focus::-webkit-input-placeholder{color:rgba(128,128,128,.4)!important}.fl-builder--search .search-label{cursor:text}.fl-builder--search .search-clear{display:none;padding:10px 10px 10px 30px;color:#a7a7a7;font-size:12px;position:absolute;right:0;top:0;background-color:#eff1f2;background:linear-gradient(to left,#e4e7ea,#e4e7ea 75%,rgba(228,231,234,0))}.fl-builder--search.has-text .search-clear,.fl-builder--search.is-expanded input{display:inline-block}.fl-builder--search:hover .search-clear{color:#888;background-color:#eff1f2;background:linear-gradient(to left,#dadfe5,#dadfe5 75%,rgba(218,223,229,0))}.fl-builder--search.is-expanded{width:246px}@keyframes fl-builder-show-menu-item{from{transform:translateY(10px) scale(.8);opacity:0}to{transform:translateX(0) translateY(0) scale(1);opacity:1}}.fl-builder--main-menu-panel{display:none;box-sizing:border-box;position:fixed;top:calc(48px + 10px);left:10px;width:360px;color:#222;max-height:calc(100% - 66px);border-radius:4px;background:#fff;border:2px solid #D5DADD;border-top:3px solid #00a0d2;box-shadow:0 15px 45px 8px rgba(0,0,0,.04);font-size:14px!important;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:10000009;pointer-events:auto}.fl-builder--main-menu-panel.is-showing{display:-ms-flexbox;display:flex}.fl-builder--main-menu-panel:before,.fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items:before{bottom:100%;right:6px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#00a0d2;border-width:13px;margin-left:-13px}.fl-builder--main-menu-panel-views{-ms-flex:1 1 100%;flex:1 1 100%;overflow:auto}.fl-builder--main-menu-panel-mask{display:none;position:fixed;top:0;left:0;right:0;bottom:0;z-index:1000119}.fl-builder--main-menu-panel .fl-builder--tabs{padding-left:20px;padding-top:15px}.fl-builder--main-menu-panel-view{display:none}.fl-builder--main-menu-panel-view.is-showing{display:block}.fl-builder--main-menu-panel-view-title{font-size:24px;font-weight:600;padding:25px 22px 0;line-height:1;white-space:nowrap}.fl-builder--main-menu-panel-view-title .title-accessory{float:right;color:#b1b1b1}.fl-builder--main-menu-panel-view-title .title-accessory>i{font-size:20px!important;width:25px!important}.fl-builder--main-menu-panel-view-title .title-accessory>i:hover{color:#222}.fl-builder--main-menu-panel-view-title .pop-view{padding:10px;margin-left:-10px;opacity:.5;font-size:25px;font-weight:400;cursor:pointer;background:0 0;outline:0;border:none;color:inherit}.fl-builder--main-menu-panel-view-title .pop-view:focus{outline:0;top:0;background:#E5EAED!important}.fl-builder--menu-item:before{display:block;content:"";float:none;clear:both}.fl-builder--menu-item{color:inherit;text-align:left;box-sizing:border-box;display:block;padding:10px 15px;margin:0 10px;width:calc(100% - 20px);background:0 0;border:none;border-radius:4px;font-size:14px;line-height:1.1;cursor:pointer;opacity:1}.fl-builder--menu-item:hover{background:#eaf1f8;border:none;text-decoration:none;color:#000}.fl-builder--selector-menu .fl-builder--menu-item:hover{background:#fff}.fl-builder--menu-item-accessory{float:right;text-align:center;display:inline-block;min-width:40px;font-size:14px}.fl-builder--menu-item-accessory.view-arrow{font-size:18px}.fl-builder--menu{padding:0;margin:20px 0}.fl-builder--menu hr{margin:8px 0;background-color:#e6eaed!important;height:2px;border:none}.fl-builder--menu .fl-builder-video-wrap{padding:0 10px 10px}.fl-revision-list-item{display:-ms-flexbox;display:flex}.fl-revision-list-item-text{padding-left:15px}.fl-revision-list-item-date{padding-bottom:5px}.fl-builder--revision-actions{display:none;position:fixed;top:4px;left:4px;z-index:100008;padding:4px 4px 6px;-ms-flex-pack:center;justify-content:center;background:#fff;border-radius:4px}.fl-builder--revision-actions *{margin-right:5px}.fl-builder--revision-actions :last-child{margin:0}.fl-builder--menu-item[data-event=noRevisionsMessage]:hover{background:0 0;box-shadow:none;cursor:default}.fl-no-revisions-message-title{font-weight:700;margin-bottom:10px}.fl-no-revisions-message-text{line-height:22px}.fl-builder-module-placeholder-message{border:1px dashed #ccc;overflow:hidden;padding:20px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.fl-field-connections-menu{z-index:999999}.fl-field-connections-toggle{right:-30px!important}.fl-builder-add-ultimate-presets-button,.fl-builder-add-ultimate-rows-button,.fl-builder-pp-add-template-button,.pp-preview-button,.uabb-live-preview-button{display:none!important}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;background:0 0;transition-property:background;transition-duration:.15s}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-ne,.ui-resizable-nw,.ui-resizable-se,.ui-resizable-sw{width:12px;height:12px}.ui-resizable-se{cursor:se-resize;right:-4px;bottom:-4px}.ui-resizable-sw{cursor:sw-resize;left:-4px;bottom:-4px}.ui-resizable-nw{cursor:nw-resize;left:-4px;top:-4px}.ui-resizable-ne{cursor:ne-resize;right:-4px;top:-4px}.fl-builder-resizable-iframe-fix{position:absolute;top:0;right:0;bottom:0;left:0;z-index:100000000}.fl-builder-panel .ui-resizable-handle:active,.fl-builder-panel .ui-resizable-handle:hover,.fl-lightbox .ui-resizable-handle:active,.fl-lightbox .ui-resizable-handle:hover{background:#00a0d2}.fl-builder-panel .ui-resizable-n,.fl-builder-panel .ui-resizable-s,.fl-lightbox .ui-resizable-n,.fl-lightbox .ui-resizable-s{height:6px}.fl-builder-panel .ui-resizable-n,.fl-lightbox .ui-resizable-n{top:-3px}.fl-builder-panel .ui-resizable-s,.fl-lightbox .ui-resizable-s{bottom:-3px}.fl-builder-panel .ui-resizable-e,.fl-builder-panel .ui-resizable-w,.fl-lightbox .ui-resizable-e,.fl-lightbox .ui-resizable-w{width:6px}.fl-builder-panel .ui-resizable-e,.fl-lightbox .ui-resizable-e{right:-3px}.fl-builder-panel .ui-resizable-w,.fl-lightbox .ui-resizable-w{left:-3px}.fl-lightbox .ui-resizable-ne,.fl-lightbox .ui-resizable-nw,.fl-lightbox .ui-resizable-se,.fl-lightbox .ui-resizable-sw{background:0 0;border:6px solid transparent}.fl-lightbox .ui-resizable-ne:active,.fl-lightbox .ui-resizable-ne:hover,.fl-lightbox .ui-resizable-nw:active,.fl-lightbox .ui-resizable-nw:hover,.fl-lightbox .ui-resizable-se:active,.fl-lightbox .ui-resizable-se:hover,.fl-lightbox .ui-resizable-sw:active,.fl-lightbox .ui-resizable-sw:hover{background:0 0;border-color:#00a0d2}.fl-lightbox .ui-resizable-ne{border-bottom:none;border-left:none;border-top-right-radius:4px}.fl-lightbox .ui-resizable-nw{border-bottom:none;border-right:none;border-top-left-radius:4px}.fl-lightbox .ui-resizable-se{border-top:none;border-left:none;border-bottom-right-radius:4px}.fl-lightbox .ui-resizable-sw{border-top:none;border-right:none;border-bottom-left-radius:4px}.fl-builder-ui-keyboard-shortcuts{display:none;position:fixed;top:0;left:0;bottom:0;right:0;z-index:999999;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;background:rgba(50,50,50,.88);font-size:15px;line-height:1.3;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fl-builder-ui-keyboard-shortcuts.is-showing{display:-ms-flexbox;display:flex}.fl-builder-ui-keyboard-shortcuts-content{box-sizing:border-box;width:500px;background:#f5f7f9;border-radius:4px;padding:30px 0 0;box-shadow:0 10px 30px rgba(0,0,0,.15)}.fl-builder-ui-keyboard-shortcut-item{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;padding:12px 40px}.fl-builder-ui-keyboard-shortcut-item:nth-child(even){background:#eef2f5}.fl-builder-ui-shortcut-keycode{margin-left:auto;text-transform:uppercase;letter-spacing:2px}.fl-builder-ui-keyboard-shortcust-footer{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:center;justify-content:center;padding:10px}.dismiss-shortcut-ui{padding:10px;border-radius:4px;background:#fff;color:#000;font-size:14px;border:2px solid #fff}.dismiss-shortcut-ui:focus,.dismiss-shortcut-ui:hover{top:0;color:#000;background:#eef2f5;border:2px solid #eef2f5}.fl-color-picker-ui{width:300px}.fl-color-picker-ui.fl-color-alpha-enabled{width:238px}.fl-color-picker-ui .iris-picker{float:left;width:100%;height:224px;display:block;position:relative;border-top:1px solid rgba(0,0,0,.1)}.fl-color-picker-ui .iris-picker .iris-square-inner,.fl-color-picker-ui .iris-picker-inner{position:absolute;left:0;top:0;bottom:0;right:0}.fl-color-picker-ui .iris-picker,.iris-picker *{box-sizing:content-box}.fl-color-picker-ui .iris-error{background-color:#ffafaf}.fl-color-picker-ui .iris-picker .iris-square{width:300px;height:200px}.fl-color-picker-ui .iris-picker .iris-palette,.fl-color-picker-ui .iris-picker .iris-slider,.fl-color-picker-ui .iris-picker .iris-square-inner{height:100%;width:12.5%}.fl-color-picker-ui .iris-picker .iris-placeholder,.fl-color-picker-ui .iris-picker .iris-square{position:relative}.fl-color-picker-ui .iris-picker .iris-square-inner{width:auto;margin:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square,.fl-color-picker-ui .iris-ie-9 .iris-square-inner{box-shadow:none;border-radius:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square{outline:rgba(0,0,0,.1) solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-palette,.fl-color-picker-ui .iris-ie-lt9 .iris-slider,.fl-color-picker-ui .iris-ie-lt9 .iris-square,.fl-color-picker-ui .iris-ie-lt9 .iris-square-inner{outline:#999 solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-square .ui-slider-handle{outline:#999 solid 1px;background-color:#fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"}.fl-color-picker-ui .iris-ie-lt9 .iris-square .iris-square-handle{background:0 0;border:3px solid #fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"}.fl-color-picker-ui .iris-picker .iris-strip{box-sizing:border-box;width:calc(300px - 12px);margin:5px 6px 6px;border-radius:4px;position:relative;height:22px;transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle{width:6px;position:absolute;right:0;top:-2px;bottom:-2px;margin:0;border-radius:3px;background:#fff;box-shadow:0 0 2px rgba(0,0,0,.5);z-index:5;cursor:ew-resize}.fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle:focus{outline:#00a0d2 solid 2px}.fl-color-picker-ui .iris-picker .iris-slider-offset{position:absolute;top:0;left:6px;right:0;bottom:0;width:auto;height:auto;background:0 0;border:none;border-radius:0;transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-square-handle{background:0 0;border:5px solid #999;border-radius:50%;border-color:rgba(128,128,128,.5);box-shadow:none;width:12px;height:12px;position:absolute;left:-10px;top:-10px;cursor:move;opacity:1;z-index:10}.fl-color-picker-ui .iris-picker .ui-state-focus .iris-square-handle{opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover{border-color:#999}.fl-color-picker-ui .iris-picker .iris-square-value:focus .iris-square-handle{box-shadow:0 0 2px rgba(0,0,0,.75);opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover::after{border-color:#fff}.fl-color-picker-ui .iris-picker .iris-square-handle::after{position:absolute;bottom:-4px;right:-4px;left:-4px;top:-4px;border:3px solid #f9f9f9;border-color:rgba(255,255,255,.8);border-radius:50%;content:" "}.fl-color-picker-ui .iris-picker .iris-square-value{width:8px;height:8px;position:absolute}.iris-ie-lt9 .iris-square-value,.iris-mozilla .iris-square-value{width:1px;height:1px}.fl-color-picker-wrapper{position:relative;width:48px;height:32px}.fl-color-picker{box-shadow:0 2px 4px 0 rgba(0,0,0,.12);background:#fff;border-radius:4px;width:120px;height:36px;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row}.fl-color-picker-color{-ms-flex:1 1 100%;flex:1 1 100%;box-sizing:border-box!important;position:relative;border-radius:4px;background-color:transparent;cursor:pointer;border:2px solid transparent;border-right:2px solid rgba(0,0,0,.1);padding:0;-ms-flex-pack:center;justify-content:center;display:-ms-flexbox;display:flex}.fl-color-picker-clear:hover,.fl-color-picker-color:hover{background:0 0;border:2px solid transparent}.fl-color-picker-clear:focus,.fl-color-picker-color.fl-color-picker-empty:focus,.fl-color-picker-color:focus{outline:0;top:0;border:2px solid #00a0d2;background:0 0}.fl-color-picker.fl-color-picker-has-reset .fl-color-picker-color:not(.fl-color-picker-empty){border-top-right-radius:0;border-bottom-right-radius:0}.fl-color-picker-icon{display:none;margin:auto}.fl-color-picker-color.fl-color-picker-empty{border-color:transparent}.fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon{display:block}.fl-color-picker-clear{box-sizing:border-box;position:relative;display:-ms-flexbox;display:flex;-ms-flex:0 0 36px;flex:0 0 36px;-ms-flex-pack:center;justify-content:center;padding:0;border:2px solid transparent;border-top-right-radius:4px;border-bottom-right-radius:4px;background-color:#fff;cursor:pointer}.fl-color-picker-color.fl-color-picker-empty+.fl-color-picker-clear{display:none}.fl-color-picker-ui{display:inline-block;font-family:Helvetica,Verdana,sans-serif;z-index:999999;position:fixed;overflow:hidden;padding-bottom:45px;border:1px solid rgba(0,0,0,.1);color:#999;background-color:#FAFAFA;border-radius:3px;box-shadow:0 9px 20px rgba(0,0,0,.17);transition:opacity .2s,visibility .2s;visibility:hidden;opacity:0;-webkit-transform:translate3d(0,0,0)}.fl-color-picker-ui.fl-color-picker-active{visibility:visible;opacity:1}.fl-color-picker-ui .fl-color-picker-input,.fl-color-picker-ui .fl-color-picker-input:focus{width:100%;height:30px;border:none!important;font-size:14px!important;padding:0 8px;vertical-align:middle;color:#656c6e;background-color:#fff;border-radius:0;box-shadow:none}.fl-color-picker-ui .iris-square-value{transition:none}.fl-color-picker-preset-add{position:absolute;top:8px;right:8px;width:14px;height:14px;background-color:#656c6e;border-radius:50%;cursor:pointer;transition:all .2s}.fl-color-picker-preset-add:hover{background-color:#333}.fl-color-picker-preset-add:after,.fl-color-picker-preset-add:before{content:'';display:block;position:relative;background-color:#fff}.fl-color-picker-preset-add:before{top:6px;left:3px;width:8px;height:2px}.fl-color-picker-preset-add:after{left:6px;top:1px;width:2px;height:8px}.fl-color-picker-presets{position:absolute;left:0;bottom:0;width:100%;z-index:15;overflow:auto;border-top:1px solid rgba(0,0,0,.1);background-color:#FAFAFA}.fl-color-picker-presets-list .fl-color-picker-preset:hover,.fl-color-picker-presets-toggle:hover{background-color:#EDEDED}.fl-color-picker-presets-toggle{position:relative;overflow:hidden;width:100%;height:35px;text-align:center;line-height:35px;font-size:12px;font-weight:700;cursor:pointer;transition:all .1s}.fl-color-picker-presets-close-label,.fl-color-picker-presets-open-label{position:absolute;top:50%;left:50%;visibility:hidden;color:#999;transition:all .5s;transform:translate(-50%,-50%);opacity:0;width:100%}.fl-color-picker-presets-close-label.fl-color-picker-active,.fl-color-picker-presets-open-label.fl-color-picker-active{color:#656c6e;visibility:visible;opacity:1}.fl-color-picker-presets-list{width:100%;list-style:none;margin:0;padding:0;overflow:auto}.fl-color-picker-presets-list .fl-color-picker-no-preset,.fl-color-picker-presets-list .fl-color-picker-preset{position:relative;padding:5px;font-size:12px;border-top:1px solid rgba(0,0,0,.1);transition:all .1s}.fl-color-picker-presets-list .fl-color-picker-no-preset{padding:18px 5px;text-align:center}.fl-color-picker-presets-list .fl-color-picker-preset-color{display:inline-block;width:40px;height:20px;margin-right:3px;vertical-align:middle;border:1px solid rgba(0,0,0,.1);border-radius:2px;cursor:pointer}.fl-color-picker-presets-list .fl-color-picker-preset-label{vertical-align:middle;color:#333;cursor:pointer}.fl-color-picker-presets-list .fl-color-picker-preset-remove{position:absolute;top:50%;cursor:pointer;transform:translateY(-50%)}.fl-color-picker-clear .fl-color-picker-icon-remove{right:auto;top:auto;margin:auto}.fl-color-picker-presets-list .fl-color-picker-preset-remove{right:5px}.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:after,.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:before{background-color:#333}.fl-color-picker-added{position:absolute;width:100%;top:0;left:0;right:0;bottom:35px;z-index:10;color:#fff;text-align:center;background-color:rgba(0,0,0,.8)}.fl-color-picker-added-text{position:absolute;top:50%;left:50%;width:80%;font-size:14px;color:#fff!important;transform:translate(-50%,-50%)}.fl-color-picker-icon-check{position:relative;width:50px;height:50px;margin:5px auto}.fl-color-picker-icon-check:before{content:'';display:block;position:relative;width:15px;height:30px;margin-left:14px;border:7px solid #fff;border-left:none;border-top:none;transform:rotate(45deg)}.fl-color-picker-icon-arrow-down,.fl-color-picker-icon-arrow-up{display:inline-block;position:relative;width:10px;height:10px;margin-left:5px}.fl-color-picker-icon-arrow-down:before,.fl-color-picker-icon-arrow-up:before{content:'';display:block;position:relative;width:6px;height:6px;border:2px solid #999;border-left:none;border-top:none;transform:rotate(45deg)}.fl-color-picker-icon-arrow-up{top:2px;transform:rotate(180deg)}.fl-color-picker-icon-remove{width:15px;height:15px}.fl-color-picker-icon-remove:after,.fl-color-picker-icon-remove:before{content:'';display:block;position:relative;background-color:#6f7881}.fl-color-picker-icon-remove:before{left:6px;width:2px;height:10px;margin-top:3px;transform:rotate(-45deg)}.fl-color-picker-icon-remove:after{left:6px;width:2px;height:10px;margin-top:-10px;transform:rotate(45deg)}.fl-alpha-wrap{position:absolute;width:35px;height:215px;padding:0 5px;right:4px;border-top:none}.fl-alpha-slider{height:190px;position:absolute;top:12px;width:28px}.fl-alpha-slider .ui-slider-handle{background:rgba(0,0,0,0);border-color:#aaa;border-radius:4px;border-style:solid;border-width:4px;box-shadow:0 1px 2px rgba(0,0,0,.2);-moz-box-shadow:0 1px 2px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.2);cursor:ns-resize;height:12px;left:0;opacity:.9;position:absolute;right:0;width:30px;z-index:14}.fl-alpha-slider .ui-slider-handle:before{content:" ";position:absolute;left:-2px;right:-2px;top:-3px;bottom:-3px;border:2px solid #fff;border-radius:3px}.fl-alpha-slider-offset{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAASCAYAAAAe/ZHXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NkNEQUQ0ODM4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NkNEQUQ0ODQ4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2Q0RBRDQ4MThFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2Q0RBRDQ4MjhFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/r/N8AAAWYSURBVHjarFvvR3VBEN45JZGIPkREHyIiIhJJf3qUSERE9CGiDxERkcg9z9u92uucvTszz5z7xnHPj93Z2d359cxscn5+jpTS+EoiMr3/+51cZ2dn4+e29i2/u7y8RKf/pO3vc+o+n5ycoNK31+f6+jrfZ37yuG2mf3R01H3fa5N/b29vU6dP5qft0G4PDg5MGuPr/v4+jz1t27mfvN/b21P75+fHx8eZfiV/Ozs7rUJnSu/5+RlFv+m6ZJpbW1s1PnrvXl9fZ/qX89zY2LB4mfy+v7/nsdV1XltbK/dr5vnz87OcV5bJabuVlRVLBifjfX9/l/xkGtM+S0tLNXnu0szfU/P3IMn/k0678h6ddqjQFGccVL6hoCsVfsq+NZ5QtCv5rfFS41sq37W+UPhMyhxEWTetvce3NR8oewqD39qalXuGAK/WPltjajIC4x2c9Ye1f43SGcqGwRBeTZjhMNntL4pCWZMQYhE05RVl02EovRgC4RkCbUNSQAGhGB/GsKG4h6FQoigDa2i8fRBy3uLMXYIG3Vr3aZvRaCRdBYlYIMZywhBGCVhgzzOlgRuUSOvC0GMEWxOM/+EtQFh1OIIXtfwg1tRaayGjg5px0jyZKEaTle3e+AsLCygVRAh3FlEgKbReE3oYGj9EgIR00QiEgKw3ZBQbRGjBeAMtDETQmHiKDsezJNLgCTFGItZXlAgCSiQggblP+9c8SDI0lXWlFv5g3K63KZ51FOcZzthQ3LomoNHwJmKIQISI3vqzSpwIQ8liSjGMFQjDpoVgaQ6cWgvLhOC7qiAwiHrWbEg4JMSmeUrBuHoYwioOQNXmhmAcrs096s1gJCGi3hSEVU8DQxYElYHhKwUUGAa+NqOBMsSSAQJuhQhCAH4vxozExsxiihPuaIrjCVYKWlYEsjSM52G8Kxxryngl5j0j+EyGTIiED4s1Itm0ZGWxMFCLJaBAcEI6OBkmFgNBoc8Cait2ZnENE/6wQN8LJSJeSMNAjKVm+LUMAIt3PR5AQgIGp1Z5zxhE8PtXUYReYeXi4mKmOPNXBMzt2tPT07LIUtJqr66uusXEbkFnWiQ6Pj72ikrtzc1NKopuvbbj58PDwxqNHp27u7tuYWumUDV+v7+/Xyu6pc59+/DwUCsC9ujt7u6qRbt8//T01C3elbyN70fb29uZ/1FSincvLy/lPGb42tzc9IqJeHt7q61Pr2C6vr7u7tfHx8fMPhV0sLq6WhZtU0n36+uru8elPE7aLi8v1wqJPXn++fmZKYgX8ozFxcXJb0NaQTHClZT8+gBjsYdaFc+zWcUkGTCWENY66ta92oSVzo3WI6IZKGtukeyfBLFKBNAj6bUOBgaoe9wE4n04IBNkLMoC7+Skj630ZlTJMYdyMsU2T8AwpzALkVFilZgJcT2l9PCWDDSAMBSjVlJgZNk0lE1AIby0qCiCnBQNj6aBGQslZIZJ5hB6D/AzQHto5Z9Nk8tARdN4q2ExBnsyIJ311EymShyjan2rKk0zh1Ay1oQVWAZQRnkUA8RFw7TahjBnmNgMVMQrsCGZJezRtGlU0cUZ1zuaxGZPpbhApM+ZpFQqQ6xadoMtBrEKpBVo4GRXvNSxpaRixKiR+TChCYhsDwZkfFj8IkErjAHejcUI0XQrgwehhNSMHAz21E0wZ23FcCAmj8Sd/PXy2xLYLAuwRw4IMsqjFaWYOpMEhDySAPFCWyFkgAHrEcA+BNeJ4UE8HCzJPpCrerUmQIx1pWJkjqxJD8EikUo2c5aI8ZYgsAkM4WQtnHd0ns0ORgVTBghy5ISy928SGsbTMqYg523RUY8oNYG4FIYiyRyZCnFCJC87IoRAIMVOqQ7BKexxCS2hYVl9JhvlpYjnAe4MhmRPMWhhvLfXINaI9WKM0Zu0+SfAAFLE1EgfVSv7AAAAAElFTkSuQmCC) center;box-shadow:0 0 5px rgba(0,0,0,.4) inset;-moz-box-shadow:0 0 5px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 5px rgba(0,0,0,.4) inset;width:200px;height:22px;transform:rotate(-90deg);bottom:48%;left:-80px;position:absolute}.fl-alpha-text{width:30px;font-size:12px;text-align:center;color:#999;position:absolute;bottom:-5px}.fl-lightbox-wrap.fl-icon-selector{z-index:1000111}.fl-icon-selector .fl-lightbox{height:100%}.fl-icons-filter{height:auto!important;margin:0!important;position:absolute!important;right:0;top:0;padding:10px 16px;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row}.fl-icons-filter select{vertical-align:middle;width:160px;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;color:#000;border:2px solid #e4e7ea!important;border-right:none!important;margin:0;padding:2px 10px;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;-ms-flex:1 1 160px;flex:1 1 160px;border-radius:0}.fl-icons-filter input[type=text]{line-height:18px;vertical-align:middle;width:160px;-ms-flex:1 1 160px;flex:1 1 160px;border:2px solid #e4e7ea!important;border-radius:0!important;padding:2px 10px!important}.fl-icons-filter input[type=text]:focus,.fl-icons-filter select:focus{border:2px solid #00A0D2!important}.fl-icons-list{bottom:52px;left:0;overflow:auto;padding:20px;position:absolute;right:0;top:48px}.fl-icons-list::-webkit-scrollbar{background-color:#ccc;-webkit-appearance:none;width:10px}.fl-icons-list::-webkit-scrollbar-thumb{background-color:#666;border:1px solid #ccc}.fl-icons-section{text-align:center}.fl-icons-section h2{border-bottom:1px solid #dfdfdf;color:#333!important;font-family:Helvetica,Verdana,sans-serif!important;font-size:16px!important;font-weight:700!important;margin:0 0 20px!important;padding:0 0 10px!important;text-align:left}.fl-icons-list i,.fl-icons-list i:before{cursor:pointer;display:inline-block;font-size:40px;height:100px;line-height:100px;width:100px;background:0 0}.fl-icons-list i:hover{background:#fff;box-shadow:0 10px 20px rgba(0,0,0,.15);border-radius:4px}.fl-icon-selector-footer{bottom:0;left:0;position:absolute;right:0}.fl-lightbox-mask,.fl-lightbox-wrap{bottom:0;left:0;position:fixed;right:0;z-index:100010}@keyframes fl-lightbox-zoom{from{transform:scale(.4)}to{transform:scale(1)}}.fl-lightbox-wrap{display:none;overflow:auto;padding:4px;top:46px;-webkit-transform:translateZ(0);pointer-events:none}.fl-builder-draggable-is-dragging .fl-lightbox-wrap,.fl-builder-resizable-is-resizing .fl-lightbox-wrap,.fl-lightbox,.fl-lightbox-mask{pointer-events:auto}.fl-lightbox-mask{background:#000;opacity:.7;filter:alpha(opacity=70);top:0}.fl-lightbox{background:#F5F7F9;border-radius:4px;box-shadow:rgba(0,0,0,1) 0 4px 30px;-moz-box-shadow:rgba(0,0,0,1) 0 4px 30px;-webkit-box-shadow:rgba(0,0,0,1) 0 4px 30px;position:relative;display:-ms-flexbox;display:flex;z-index:100011;transform-origin:center;animation-name:fl-lightbox-zoom}.fl-lightbox.fl-lightbox-prevent-animation{animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s}.fl-lightbox :not(i){color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:13px;line-height:16px;text-decoration:none;text-transform:none}.fl-lightbox *,.fl-lightbox :after,.fl-lightbox :before{box-sizing:content-box}.fl-lightbox .fl-nanoscroller-pane{bottom:4px;right:4px;width:8px}.fl-lightbox .fa{font-family:FontAwesome}.fl-lightbox .dashicons{font-family:dashicons}.fl-lightbox.ui-draggable{box-shadow:rgba(0,0,0,.2) 0 7px 30px;-moz-box-shadow:rgba(0,0,0,.2) 0 7px 30px;-webkit-box-shadow:rgba(0,0,0,.2) 0 7px 30px}.fl-lightbox-resizable{height:500px;width:380px}@media (max-width:500px){.fl-lightbox-resizable{left:0!important;right:0!important;top:0!important;height:100%!important;width:100%!important}.fl-lightbox-resizable .ui-resizable-handle{display:none!important}.fl-lightbox.ui-draggable .fl-lightbox-header{cursor:default!important}.fl-lightbox-controls{display:none}}.fl-lightbox-width-full{left:0!important;right:0!important;top:0!important;height:100%!important;width:100%!important}.fl-lightbox-width-full .fl-lightbox-header{cursor:inherit!important}.fl-lightbox-controls{position:absolute;right:10px;top:10px;z-index:5}.fl-lightbox-controls .fa{color:#bdbdbd;font-size:14px;padding:5px}.fl-lightbox-controls .fa:hover{color:#aaa;cursor:pointer}.fl-lightbox-header-wrap{background:#fff;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:2px solid #eaeaea}.fl-lightbox-header{position:relative}.fl-lightbox-header h1{color:#333!important;font-size:20px!important;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important;font-weight:600!important;margin:0!important;padding:14px 34px 15px 28px!important;text-align:left!important;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;line-height:1.1}.fl-lightbox.ui-draggable .fl-lightbox-header{cursor:move}.fl-lightbox-header h1 .fl-builder-badge{margin-left:10px}.fl-lightbox-content,.fl-lightbox-content-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex:1 100%;flex:1 100%;height:100%;max-width:100%}.fl-lightbox-footer{box-sizing:border-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:end;justify-content:flex-end;-ms-flex:0 0;flex:0 0;-ms-flex-preferred-size:44px;flex-basis:44px;padding:4px;text-align:right}.fl-lightbox-footer .fl-builder-button{height:36px;margin-left:5px!important;-ms-flex:0 0 0%;flex:0 0 0%;-ms-flex-pack:center;justify-content:center}.fl-lightbox-width-slim .fl-lightbox-footer{-ms-flex-pack:stretch;justify-content:stretch;padding:4px 5px}.fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button{-ms-flex:1 1 100%;flex:1 1 100%;display:block;text-align:center}.fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button:first-child{margin-left:0!important}.fl-lightbox table,.fl-lightbox td,.fl-lightbox th,.fl-lightbox tr{border:none}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel,.fl-builder-ui-skin--dark .fl-builder--preview-actions,.fl-builder-ui-skin--dark .fl-builder--search-results-panel,.fl-builder-ui-skin--dark .fl-builder-panel,.fl-builder-ui-skin--dark .fl-lightbox,body.fl-builder-ui-skin--dark .fl-builder-bar .fl-builder-bar-content{background:#23282d;color:#b4b9be;border-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder--panel-header{background:#1d2227;color:#b4b9be;border-bottom-color:#1d1d1d;border-top-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header{border-top-color:#1d2227}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel:before{border-bottom-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder--panel-arrow polygon{fill:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder-panel-search .fl-builder-panel-search-input{background:#1e2228}.fl-builder-ui-skin--dark .fl-responsive-preview-content{background:#131619}.fl-builder-ui-skin--dark .fl-form-table th{background:#23282d!important;color:#7d8690}.fl-builder-ui-skin--dark .fl-builder--preview-actions .device-icons,.fl-builder-ui-skin--dark .fl-builder-button{background:#383f46}.fl-builder-ui-skin--dark .fl-builder-button:focus{background:#131a22}.fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-primary{color:#fff!important;fill:#fff!important;background:#00A0D2}.fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-silent:focus{border:2px solid #00a0d2!important}.fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover,.fl-builder-ui-skin--dark .fl-builder-content-panel-button{color:#00A0D2!important}.fl-builder-ui-skin--dark .fl-builder--menu>a:hover,.fl-builder-ui-skin--dark .fl-builder--menu>button:hover{background:#101215!important}.fl-builder-ui-skin--dark .fl-builder--menu>a:focus,.fl-builder-ui-skin--dark .fl-builder--menu>button:focus{background:#101215!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder-bar-title{border-color:#101215}.fl-builder-ui-skin--dark .fl-builder-bar-title:hover{background-color:#181b1f}.fl-builder-simple.fl-builder-ui-skin--dark .fl-builder-bar-title:hover{background-color:transparent}.fl-builder-ui-skin--dark .fl-builder-layout-title{color:#c6cdd6}.fl-builder-ui-skin--dark .fl-builder-bar-title-caret i,.fl-builder-ui-skin--dark .fl-builder-layout-pretitle,.fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{color:#7d8690}.fl-builder-ui-skin--dark button.fl-builder-button.fl-builder-bar-title-caret:focus{background-color:#101215!important}.fl-builder-ui-skin--dark .fl-builder--search:before{color:rgba(162,173,184,.73)}.fl-builder-ui-skin--dark .fl-builder--search input:focus::-webkit-input-placeholder{color:rgba(162,173,184,.73)!important}.fl-builder-ui-skin--dark .fl-builder--search .search-clear{color:rgba(162,173,184,.5);background-color:#e4e4e4;background:linear-gradient(to left,#383f46,#383f46 75%,rgba(56,63,70,0))}.fl-builder-ui-skin--dark .fl-builder--menu hr{background-color:#23282d!important;border:none}.fl-builder-ui-skin--dark .fl-builder--tabs{border-color:#383f46!important}.fl-builder-ui-skin--dark .fl-builder--tabs>.is-showing,.fl-builder-ui-skin--dark .fl-builder-settings-tabs a.fl-active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-more.fl-contains-active{color:#fff!important;fill:#fff!important;background:#383f46}.fl-builder-ui-skin--dark .fl-builder--tabs>:focus{background-color:#101215!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder--tabs>.is-showing:focus{color:#00a0d2!important}.fl-builder-ui-skin--dark .fl-builder--menu-item:hover{background:#383f46;color:#a8b3bf}.fl-builder-ui-skin--dark .fl-builder--menu * .fl-builder--menu-item-accessory,.fl-builder-ui-skin--dark .fl-builder-blocks-section-group-name{color:#7d8690}.fl-builder-ui-skin--dark .fl-builder--category-select{background:#171b1f}.fl-builder-ui-skin--dark .fl-builder--selector-display{color:#c6cdd6;background:url(../img/svg/select-arrow-down-alt2-light.svg) center right 10px no-repeat #171b1f!important}.fl-builder-ui-skin--dark .fl-builder--selector-display-label,.fl-builder-ui-skin--dark .fl-builder-panel-search-input input{border-color:#5b656f;color:#b5becb}.fl-builder-ui-skin--dark .fl-builder-panel-search-input input{background:#171b1f!important}.fl-builder-ui-skin--dark .fl-builder--selector-display-label:focus,.fl-builder-ui-skin--dark .fl-builder-panel-search-input input:focus{border-color:#00a0d2}.fl-builder-ui-skin--dark .fl-builder--group-label{color:#171b1f!important;background:#5b656f}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu{border-color:#101215!important;color:#7c858e;background-color:#101215}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu:before{border-bottom-color:#101215}.fl-builder-ui-skin--dark .fl-builder--menu>a,.fl-builder-ui-skin--dark .fl-builder--menu>button,.fl-builder-ui-skin--dark .fl-builder--menu>span{color:#a1adb9}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:hover{background:#23282d!important;color:#a1adb9}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:focus{background:#23282d!important;color:#00a0d2!important}.fl-builder-ui-skin--dark .fl-builder-panel-drag-handle{fill:#5b656f}.fl-builder-ui-skin--dark .fl-builder--template-collection-section-name,.fl-builder-ui-skin--dark .fl-builder--user-templates-section-name,.fl-builder-ui-skin--dark .fl-builder-blocks-section .fl-builder-blocks-section-title{color:#969ea7;background:#171b1f}.fl-builder-ui-skin--dark .fl-builder-blocks-section-content .fl-builder-block,.fl-builder-ui-skin--dark .fl-user-template{color:#b8c2ce}.fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-content,.fl-builder-ui-skin--dark .fl-user-template:hover{background:#171b1f;color:#fff}.fl-builder-ui-skin--dark .fl-builder-block:hover i,.fl-builder-ui-skin--dark .fl-user-template:hover i{color:#6d7782!important}.fl-builder-ui-skin--dark .fl-builder-block:hover a:hover i,.fl-builder-ui-skin--dark .fl-user-template:hover a:hover i{color:#9eacbb!important}.fl-builder-ui-skin--dark .fl-builder-block .fl-builder-block-icon{fill:#b5becb}.fl-builder-ui-skin--dark .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col,.fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{background:#7d8690}.fl-builder-ui-skin--dark .fl-builder-blocks-section,.fl-builder-ui-skin--dark .fl-builder-settings-section{border-top:2px solid #171b1f}.fl-builder-ui-skin--dark .fl-user-templates{border-color:#101215}.fl-builder-ui-skin--dark .fl-builder--template-thumbnail{border-color:#393f44}.fl-builder-ui-skin--dark .fl-builder--menu a.fl-template-collection{color:#a8b3bf}.fl-builder-ui-skin--dark .fl-lightbox-header-wrap{background:#1d2227;border-bottom-color:#131a22}.fl-builder-ui-skin--dark .fl-lightbox .fl-lightbox-header h1{color:#fff!important}.fl-builder-ui-skin--dark .fl-form-table th label{color:#a8b3bf!important}.fl-builder-ui-skin--dark .fl-builder-settings-tabs{border-color:#383f46!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields h3.fl-builder-settings-title{background:#1b2025}.fl-builder-ui-skin--dark h3.fl-builder-settings-title .fl-builder-settings-title-text-wrap{color:#a8b3bf;background-color:#1b2025}.fl-builder-ui-skin--dark .fl-lightbox :not(i){color:#7d8690!important}.fl-builder-ui-skin--dark .fl-builder-button{color:#c6cdd6!important;fill:#c6cdd6!important}.fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover,.fl-builder-ui-skin--dark .fl-builder-content-panel-button{fill:#00A0D2!important}.fl-builder-ui-skin--dark .fl-lightbox .fl-builder-button.fl-builder-button-primary{color:#fff!important}.fl-builder-ui-skin--dark .fl-color-picker{background:#131a22}.fl-color-picker-color.fl-color-picker-empty .fl-color-picker-icon{fill:#6f7881}.fl-builder-ui-skin--dark .fl-color-picker-clear{background-color:#191d21}.fl-builder-ui-skin--dark .fl-color-picker-clear:hover{background-color:#373f46}.fl-builder-ui-skin--dark span.fl-builder-block-no-node-templates:hover{background:#1d2025}.fl-builder-ui-skin--dark .fl-builder-settings-tab-description{background:#1d2227}.fl-builder-ui-skin--dark .fl-builder-panel-search button svg .filled-shape{fill:#b5becb}.fl-builder-ui-skin--dark .fl-builder-custom-field,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url],.fl-builder-ui-skin--dark .fl-builder-settings-fields select,.fl-builder-ui-skin--dark .fl-builder-settings-fields textarea{background-color:#131a22!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields select:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields textarea:focus{border-color:#00a0d2!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields select{background-image:url(../img/svg/select-arrow-down-alt2-light.svg)!important}.fl-builder-ui-skin--dark .fl-builder-custom-field select,.fl-builder-ui-skin--dark .fl-photo-field select{border-color:#7d8690!important}.fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle{color:#6b747d}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel-view-title,.fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle:hover{color:#a8b3bf}.fl-builder-ui-skin--dark .fl-builder--saving-indicator{color:#858f99}.fl-builder-ui-skin--dark .fl-icons-list i:hover{background-color:#16191d;color:#fff}.fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:after,.fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:before{background:#6f7881}.fl-builder-ui-skin--dark .fl-builder--user-templates-section-content{border-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button{background:0 0;border-right-color:#101215!important}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button:hover{background:#181b1f}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{color:#c6cdd6}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu{background:#131a22;border-color:#353c43 #131a22 #131a22}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu:before{border-bottom-color:#353c43}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:focus,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:hover{background:#383f46}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a.fl-active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:hover.fl-active{color:#fff!important;background:#383f46}.fl-builder-ui-skin--dark ul.as-selections{background-color:#121a23}.fl-builder-ui-skin--dark .fl-custom-query .fl-builder-settings-section{border-top:2px solid #1b2026!important}.fl-builder-ui-skin--dark .pp-preview-button{background:#23282d;border:2px solid #101215}.fl-builder-ui-skin--dark .pp-preview-button .pp-preview-button-wrap .fa{color:#b8bfc7}
1
+ #wpadminbar,html{transition-duration:.35s}.fl-builder-badge,.fl-builder-bar-title span{vertical-align:middle}.fl-theme-builder-preview-select-title i:before,body .fl-theme-builder-preview-select .fa-caret-down i:before,body .fl-theme-builder-preview-select-item-title i:before{content:"\f078"}html{transition-property:margin}html.fl-builder-is-showing-toolbar{margin-top:46px!important}.fl-builder-edit body{position:static!important}.fl-builder-edit:after,.fl-builder-edit:before{z-index:0!important}.fl-builder-edit .fl-builder-content{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none}.fl-builder-bar,.fl-builder-button{-webkit-user-select:none;-moz-user-select:none;-webkit-touch-callout:none}#wpadminbar{transition-property:transform,opacity;transform-origin:bottom;transform-style:preserve-3d;transform:rotateX(89deg) translateY(46px);opacity:0;pointer-events:none;will-change:transform}html.fl-builder-show-admin-bar{margin-top:32px}html.fl-builder-show-admin-bar #wpadminbar{transform:rotateX(0) translateY(0);pointer-events:auto;opacity:1}@media screen and (max-width:782px){html.fl-builder-show-admin-bar{margin-top:46px}}.fl-clear{clear:both}.screen-reader-text{position:absolute;left:-1000em;top:-1000em;height:1px;width:1px;overflow:hidden}.fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(240,240,240,.8);bottom:0;display:none;left:0;position:fixed;right:0;text-align:center;top:0;z-index:12000000}.fl-builder-settings .fl-builder-loading{background:url(../img/ajax-loader.svg) center center no-repeat rgba(255,255,255,.8);display:block;position:absolute}.fl-field-loader{color:#B3B3B3!important;font-style:italic}.fl-builder-node-loading{opacity:.35}.fl-builder-node-loading-placeholder{background:url(../img/ajax-loader.svg) center center no-repeat;height:50px}.fl-col-group-has-child-loading{display:-ms-flexbox;display:flex}.fl-col-group-has-child-loading>.fl-builder-node-loading-placeholder{width:50px}html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-desktop,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-desktop-medium,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-medium,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-medium-mobile,html:not(.fl-responsive-preview-enabled) .fl-builder-content-editing .fl-visible-mobile{display:block!important}.fl-responsive-preview-mask{background:#F7F7F7;bottom:0;left:0;position:fixed;right:0;top:0;z-index:99999}.fl-responsive-preview{bottom:0;left:0;position:absolute;right:0;top:0;margin-top:50px;z-index:100000}#fl-builder-preview-frame,#fl-builder-preview-mask{bottom:0;height:100%;position:fixed;top:0;width:100%;right:0}.fl-builder-preview .fl-responsive-preview{margin:0!important}.fl-responsive-preview-content{background:#F5F7F9;padding:20px 20px 45px}.fl-responsive-preview-message{color:#b3b3b3;font-family:Helvetica,Arial,Verdana,sans-serif;font-size:14px;font-weight:400;padding:0 20px 20px;text-align:center}.fl-builder-button,body .fl-builder-bar .fl-builder-bar-content{display:-ms-flexbox;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important}.fl-responsive-preview-message i{cursor:pointer;margin-left:3px}.fl-responsive-preview .fl-builder-content{box-shadow:0 0 8px rgba(0,0,0,.2);margin-left:auto;margin-right:auto;max-width:100%}#fl-builder-preview-mask{background:url(../img/ajax-loader.svg) center center no-repeat #F7F7F7;left:0;z-index:99999}#fl-builder-preview-frame{left:50%;transform:translateX(-50%);-moz-transform:translateX(-50%);-webkit-transform:translateX(-50%);z-index:100000}.fl-builder-button{color:#676F7A!important;fill:#676F7A!important;background:#E4E7EA;-ms-flex-align:center;align-items:center;display:flex;text-decoration:none;font-size:14px!important;font-weight:500!important;line-height:1!important;height:33px;margin:0;padding:0 12px;cursor:pointer;-webkit-border-radius:3px;-webkit-appearance:none;border:2px solid transparent;border-radius:3px;letter-spacing:normal!important;white-space:nowrap;box-sizing:border-box!important;transition-property:background-color,width;transition-duration:.2s;-ms-user-select:none;user-select:none}.fl-builder-button:hover{background:#dadfe5;color:#222;border:2px solid transparent!important}.fl-builder-button:active{background:#DCDCDC}button.fl-builder-button:focus{position:static;top:auto;outline:0;background:#E4E7EA;border:2px solid #00A0D0!important}.fl-builder-bar .fl-builder-button{height:auto}.fl-builder-button-primary,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button{background:#00A0D2;color:#fff!important;text-decoration:none;border:2px solid transparent!important}.fl-builder-button.fl-builder-button-primary:focus,body.fl-builder--layout-has-drafted-changes .fl-builder-button.fl-builder-done-button:focus{background:#00A0D2;border:2px solid #ffc217!important}.fl-builder-button-primary:hover,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:hover{background:#0197C6;color:#fff!important}.fl-builder-button-primary:active,body.fl-builder--layout-has-drafted-changes .fl-builder-done-button:active{background:#0484AC}.fl-builder-button-large{height:30px}.fl-builder-button-small{font-size:11px!important;line-height:1!important}.fl-builder-help-button{color:#b3b3b3;font-size:16px!important}.fl-builder-help-button i{position:relative;top:-1px}.fl-builder-help-button:hover{color:#666}.fl-builder-publish-button{line-height:45px!important}.fl-builder-content-panel-button,.fl-builder-content-panel-button:hover{fill:#00A0D2!important;font-size:30px!important;padding-bottom:4px}.fl-builder-button-silent,.fl-builder-button-silent:hover{padding:0 12px;background:0 0!important;border:2px solid transparent!important;box-shadow:none!important}.fl-builder-done-button,.fl-builder-done-button:hover{font-weight:600}.fl-field .fl-builder-button{display:inline-block;height:auto;padding:11px 12px;vertical-align:middle;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)}.fl-builder-badge{background:#333;border-radius:2px;color:#fff!important;display:inline;font-size:11px!important;font-weight:400;letter-spacing:1px;margin-left:2px;padding:2px 4px}.fl-builder-badge-global{background:#ff9600;transform:translateY(0);transition-duration:.25s;transition-property:transform}.fl-builder-blocks-node-template .fl-builder-badge-global{position:absolute;right:0;top:0}.fl-builder-block:hover .fl-builder-badge-global{display:none}.fl-builder-bar{left:0;position:fixed;right:0;top:0;z-index:999999;-ms-user-select:none;user-select:none;transition-property:transform opacity;transition-duration:.35s;transform-style:preserve-3d;perspective:1100px}.fl-builder-bar.is-hidden{pointer-events:none}.fl-builder-bar.is-hidden .fl-builder-bar-content{transform:translateY(-100%) rotateX(90deg)}body .fl-builder-bar .fl-builder-bar-content{display:flex;box-sizing:border-box;background:#fff;border-bottom:2px solid #D5DADD;color:#999;font-size:14px!important;height:48px;transition-property:background-color,opacity,transform;transition-duration:.35s;pointer-events:auto}.fl-builder-draggable-is-dragging .fl-builder-content,.fl-builder-draggable-is-dragging .fl-builder-panel .fl-lightbox,.fl-builder-resizable-is-resizing .fl-builder-content,.fl-builder-resizable-is-resizing .fl-builder-panel .fl-lightbox,body .fl-builder-bar .fl-builder-bar-content.is-muted{pointer-events:none}body .fl-builder-bar .fl-builder-bar-content.is-muted>:not(.fl-builder-publish-actions){-webkit-filter:saturate(20%) blur(1px);filter:saturate(20%) blur(1px);opacity:.4}.fl-builder-bar-title{box-sizing:border-box;color:#333;display:-ms-flexbox;display:flex;-ms-flex:0 0 380px;flex:0 0 380px;max-width:380px;border-right:2px solid #D5DADD;cursor:pointer}.fl-builder-bar-title:hover{background:#fff}.fl-builder-bar-title.is-showing-menu .fl-builder-bar-title-caret>svg{transform:rotate(180deg)}.fl-builder-simple .fl-builder-bar-title{cursor:auto}.fl-builder-simple .fl-builder-bar-title:hover{cursor:auto;background:0 0}.fl-builder-bar-title-icon{box-sizing:border-box;background:0 0;-ms-flex:0 0 46px;flex:0 0 46px;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:4px}.fl-builder-bar-title-icon img{max-width:100%!important;height:auto!important}.fl-builder-bar-title.fl-builder-bar-title-no-icon{padding-left:12px}.fl-builder-bar-title-area{box-sizing:border-box;-ms-flex:1 1 100%;flex:1 1 100%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;overflow:hidden;padding:4px}.fl-builder-layout-title,.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{font-size:17px;font-weight:400;line-height:1.3;color:#161B20;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.fl-builder-bar-title-caret,.fl-builder-layout-pretitle,.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{font-size:12px;font-weight:500;line-height:1.3;color:#656d77;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.fl-builder-bar-title-caret i,.fl-theme-builder-preview-select-title i{color:inherit!important;font-size:14px}.fl-builder-bar-title-caret{margin-left:auto!important;-ms-flex:0 0 46px;flex:0 0 46px}.fl-theme-builder-preview-select-title i{padding:12px}.fl-theme-builder-preview-select.fl-builder-button{position:relative;border-radius:0;background:0 0;min-width:0;display:-ms-flexbox;display:flex;-ms-flex:0 0 360px;flex:0 0 360px;max-width:360px;margin:0!important;padding:4px 10px;border:none!important;border-right:2px solid #d5dadd!important;box-shadow:none}.fl-theme-builder-preview-select.fl-builder-button:hover{border:none!important;border-right:2px solid #d5dadd!important}.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-pack:end;justify-content:flex-end;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.fl-theme-builder-preview-select-title div{-ms-flex:1;flex:1}.fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{display:block}.fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items{position:absolute;top:calc(48px + 10px);left:10px;width:calc(100% - 20px)!important;background:#fff;border-radius:4px;border:2px solid #D5DADD;border-top:3px solid #00a0d2;box-shadow:0 15px 45px 8px rgba(0,0,0,.04);margin:0!important;padding:0;z-index:-1;font-size:16px;overflow:visible;height:auto!important;max-height:calc(100vh - 66px);min-height:300px;display:-ms-flexbox!important;display:flex!important;-ms-flex-direction:column;flex-direction:column}.fl-theme-builder-preview-select-item{padding:4px 0!important;border-bottom:none!important;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.fl-theme-builder-preview-select-item:hover{text-decoration:none;color:#111;background:0 0!important}body .fl-theme-builder-preview-select .fa-caret-down{float:none}body .fl-theme-builder-preview-select-item-title{padding:10px 15px;color:#222;font-size:14px}body .fl-theme-builder-preview-select-item-children{overflow:auto}body .fl-theme-builder-preview-select-item-child{overflow:hidden;text-overflow:ellipsis;line-height:1.1;margin:0 10px;border:2px solid transparent;border-radius:4px;padding:8px 10px 10px;font-size:14px;font-weight:400;color:#222}body .fl-theme-builder-preview-select-item-child:hover{background:#e6eaed!important}.fl-theme-builder-preview-select-item .fa-caret-down{color:#606D77}.fl-builder-bar-actions{display:-ms-flexbox;display:flex;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex:1 1 100%;flex:1 1 100%;padding:4px}.fl-builder-bar .fl-builder-button{margin:0 0 0 4px}.fl-builder-bar-actions .fl-builder-button:last-child{margin:0}.fl-builder-bar-actions:after{clear:both}.fl-builder-bar .fl-builder-content-panel-button{-ms-flex-align:baseline!important;align-items:baseline!important;padding-top:1px;font-weight:400}.fl-builder-content-panel-button svg{transition-property:transform;transition-duration:.25s;transform:rotate(0) scale(1);transform-origin:center}.fl-builder-content-panel-is-showing .fl-builder-content-panel-button svg{transform:rotate(135deg) scale(1.1) translate(.5px,-.5px)}.fl-builder--saving-indicator{cursor:pointer;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;padding:0 16px;font-size:1em;font-style:italic;color:#676f7a;-ms-flex-align:center;align-items:center;line-height:1.2;min-width:180px;-ms-flex-pack:end;justify-content:flex-end}.fl-builder--saving-indicator:hover{color:#676f7a}.fl-builder--saving-indicator .fa-question-circle{font-size:13px;margin:3px 0 3px 8px}.fl-builder-buy-button,.fl-builder-upgrade-button{background:#F7A407;color:#fff!important;text-decoration:none}.fl-builder-buy-button i.fa-external-link-alt,.fl-builder-upgrade-button i.fa-external-link-alt{color:#FFC733;margin:0 0 0 6px}.fl-builder-buy-button:hover,.fl-builder-upgrade-button:hover{background:#EE8E0D;color:#fff!important}@media (max-width:980px){.fl-builder--main-menu-panel{width:calc(100% - 20px)!important}.fl-builder--main-menu-panel:before{right:auto;left:20px}.fl-builder-bar-title,.fl-theme-builder-preview-select{-ms-flex:1 .5 380px!important;flex:1 .5 380px!important}}@media (max-width:620px){.fl-theme-builder-preview-select.fl-builder-button{display:none}}@media (max-width:500px){.fl-builder--main-menu-panel:before,.fl-builder-bar-title-area,.fl-builder-panel-drag-handle,.fl-builder-panel:before{display:none}.fl-builder--main-menu-panel,.fl-builder-panel{width:auto!important;top:44px!important;left:0!important;right:0!important;bottom:0!important;border-radius:0!important;box-shadow:none!important}.fl-builder--main-menu-panel{border-left:transparent!important;border-right:transparent!important;border-bottom:transparent!important;max-height:calc(100% - 44px)!important}.fl-builder-bar-title{-ms-flex:0 0 100px!important;flex:0 0 100px!important}.fl-builder--panel-header{border-radius:0!important;cursor:default!important}.fl-builder--panel-header .fl-builder--tabs{cursor:default!important}.fl-builder-publish-actions{width:100%!important}.fl-builder-bar-actions .fl-builder-button{padding:0 8px!important}}.fl-builder--preview-actions{display:none;position:fixed;top:4px;left:4px;z-index:100008;padding:4px;-ms-flex-pack:center;justify-content:center;background:#fff;border-radius:4px}.fl-builder-preview .fl-builder--preview-actions{display:-ms-flexbox;display:flex}.fl-builder--preview-actions .device-icons{color:#555;background:#e4e4e4;border:none!important;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;text-decoration:none;font-size:14px!important;line-height:1!important;margin:0 4px 0 0;padding:0 6px;cursor:pointer;-webkit-border-radius:3px;-webkit-appearance:none;border-radius:3px}.fl-builder--preview-actions .device-icons i{margin:0 6px}@keyframes fl-builder-ui-pin-zone-pulse{0%,100%{opacity:1;filter:alpha( opacity=1 )}50%{opacity:.5;filter:alpha( opacity=35 )}}.fl-builder-ui-pin-zone{animation:fl-builder-ui-pin-zone-pulse 2s infinite;transition:width .3s ease;background:rgba(0,160,210,.5);bottom:0;top:0;position:fixed;width:35px;z-index:100001}.fl-builder-ui-show-pin-zone-left .fl-builder-ui-pin-zone-left,.fl-builder-ui-show-pin-zone-right .fl-builder-ui-pin-zone-right{width:75px}.fl-builder-ui-pin-zone-left{left:0}.fl-builder-ui-pin-zone-right{right:0}.fl-builder-content-panel-pin-zone .fl-builder-content-panel-button{display:-ms-flexbox!important;display:flex!important;background:rgba(0,160,210,.5)!important;padding:2px 4px;width:80px;animation:fl-builder-ui-pin-zone-pulse 2s infinite}.fl-builder-content-panel-pin-zone .fl-builder-content-panel-button svg{display:none}.fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button{width:120px}.fl-builder-content-panel-pin-zone-hover .fl-builder-content-panel-button svg{display:none!important;width:100%;transform:none!important;fill:#00A0D2!important;border-radius:3px}.fl-builder-ui-is-pinned .fl-builder-content-panel-button,.fl-builder-ui-pinned-container .fl-lightbox-controls{display:none}.fl-builder-content-panel-pin-zone .fl-builder-done-button{-webkit-filter:grayscale(100%);filter:grayscale(100%)}.fl-builder-panel.fl-builder-ui-pinned{top:48px!important;bottom:0!important;height:auto!important;border-radius:0;border:none;box-shadow:none;animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s;z-index:9}.fl-builder-panel.fl-builder-ui-pinned-right{left:auto!important;right:0;border-left:2px solid #d5dadd}.fl-builder-panel.fl-builder-ui-pinned-left{left:0;right:auto;border-right:2px solid #d5dadd}.fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header{border-radius:0!important}.fl-builder-ui-pinned-container .fl-lightbox-wrap{position:absolute;z-index:9}.fl-builder-ui-pinned-container .fl-lightbox{position:absolute;top:0;bottom:0;left:0;right:0;width:auto!important;height:auto;border-radius:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s}.fl-builder-ui-pinned-container .fl-lightbox-header-wrap{border-radius:0}.fl-builder-ui-pinned-container .fl-lightbox.ui-draggable .fl-lightbox-header{cursor:auto}.fl-builder-ui-pinned-container .fl-lightbox-header h1{padding:12px 20px 10px!important}.fl-builder-ui-pinned-content-transform{transform:scale(1);transform-origin:center top 0}.fl-builder-ui-pinned-collapse{cursor:pointer;display:none;position:absolute!important;bottom:2px;padding:5px;border:2px solid transparent;background:0 0;width:36px;height:36px;border-radius:4px;fill:#778794;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:center;justify-content:center}.fl-builder-ui-pinned-collapse:focus,.fl-builder-ui-pinned-collapse:hover{top:auto!important;background:0 0;border:2px solid transparent;outline:0;fill:#00A0D2}.fl-builder-ui-pinned-collapse:focus{background:#E4E7EA}.fl-builder-ui-pinned-collapse>*{margin:auto;line-height:1}.fl-builder-ui-pinned-collapse svg g{fill:inherit}.fl-builder-ui-is-pinned-right .fl-builder-ui-pinned-right-collapse{display:-ms-flexbox;display:flex;left:-40px}.fl-builder-ui-is-pinned-left .fl-builder-ui-pinned-left-collapse{display:-ms-flexbox;display:flex;right:-40px}.fl-builder-ui-pinned-collapse i[data-toggle=show],.fl-builder-ui-pinned-is-collapsed i[data-toggle=hide]{display:none}.fl-builder-ui-pinned-is-collapsed i[data-toggle=show]{display:block}.fl-builder--panel-no-settings,.fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--panel-content,.fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--panel-controls,.fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--tab-wrap,.fl-builder-ui-pinned-is-collapsed .fl-builder--panel-header{display:none}.fl-builder-ui-is-pinned-left [data-toggle=hide],.fl-builder-ui-is-pinned-right [data-toggle=show]{transform:rotateY(180deg)}.fl-builder-ui-pinned-is-collapsed .fl-lightbox{box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}.fl-builder-simple-pinned .fl-builder--content-library-panel .fl-builder--panel-header{background:0 0;border:none;z-index:10}.fl-builder-simple-pinned .fl-builder--content-library-panel .fl-lightbox-wrap{top:0}.fl-builder-simple-pinned .fl-builder--content-library-panel .fl-lightbox-header h1{padding:14px 28px 15px!important}.fl-builder-simple-pinned .fl-builder--panel-no-settings{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;position:absolute;top:0;left:0;right:0;bottom:0}@keyframes fl-builder-show-panel{from{transform:scale(.8)}to{transform:scale(1)}}.fl-builder--search-results-panel,.fl-builder-panel{box-sizing:border-box;position:fixed!important;right:20px;top:calc(48px + 10px);width:380px;bottom:20px;background:#F5F7F9;color:#676F7A;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:14px;border-radius:4px;box-shadow:0 8px 40px 4px rgba(0,0,0,.3);z-index:10000007;will-change:transform;display:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fl-builder-panel{transform-origin:top right;animation-name:fl-builder-show-panel;animation-duration:.15s;animation-fill-mode:both}.fl-builder--search-results-panel{position:absolute;right:0;top:93px;left:0;bottom:0;width:auto!important;border:none;border-radius:0;box-shadow:none;min-height:100px;max-height:calc(100vh - 54px);overflow:auto;z-index:1}.fl-builder-content-panel-is-showing .fl-builder-panel,.fl-builder-search-results-panel-is-showing .fl-builder--search-results-panel{display:block}.fl-builder-panel .fl-lightbox .fl-builder-panel-drag-handle,.fl-builder-ui-is-pinned .fl-builder--panel-arrow,.fl-lightbox-width-full .fl-builder-panel-drag-handle,body.fl-builder-draggable-is-dragging .fl-builder--panel-arrow{display:none}.fl-builder-content-panel-is-showing .fl-builder-panel.fl-builder--current-view-templates{width:520px}.fl-builder--search-results-panel .fl-builder--no-results{text-align:center;padding:50px 20px}.fl-builder--panel-arrow{position:absolute;top:-13px;right:10px}.fl-builder--panel-arrow polygon{fill:#00a0d2}.fl-builder--panel-header{background:#fff;border-top:3px solid #00a0d2;border-bottom:2px solid #e6eaed;border-top-right-radius:4px;border-top-left-radius:4px}.fl-builder-ui-is-pinned .fl-builder--panel-header{border-top-color:transparent}.fl-builder-panel-drag-handle{position:absolute;top:7px;left:10px;fill:#ccd4da;width:6px}.fl-builder-ui-is-pinned-left .fl-builder-panel-drag-handle{left:auto;right:10px}.fl-builder--panel-header .fl-builder--panel-controls{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;position:relative}.fl-builder--panel-header .fl-builder--panel-controls .fl-builder-content-group-select{-ms-flex:1 1;flex:1 1}.fl-builder--panel-header .fl-builder--panel-controls .fl-builder-panel-search{-ms-flex:0 0;flex:0 0;padding:0 10px 6px 0;margin-left:-4px}.fl-builder--panel-controls .fl-builder-panel-search button{width:38px;background:0 0!important;border:2px solid transparent!important;font-size:inherit;height:38px;padding:0}.fl-builder--panel-controls .fl-builder-panel-search button:active,.fl-builder--panel-controls .fl-builder-panel-search button:focus{top:0;outline:0}.fl-builder-panel-search button svg{height:auto;width:20px}.fl-builder-panel-search button.fl-builder-dismiss-panel-search svg{width:16px}.fl-builder-panel-search button svg .filled-shape{fill:#000}.fl-builder--panel-controls .fl-builder-panel-search button:active svg .filled-shape,.fl-builder--panel-controls .fl-builder-panel-search button:focus svg .filled-shape{fill:#00A0D2}.fl-builder-panel-search .fl-builder-panel-search-input{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background:#fff}.fl-builder-panel-search.is-showing-input .fl-builder-panel-search-input{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;padding:0 10px 6px}.fl-builder-panel-search-input input{-ms-flex:1 1 100%;flex:1 1 100%;border:2px solid #e6eaed;background:#fff;border-radius:4px;margin-right:4px;padding:10px;color:#333}.fl-builder-panel-search-input input:focus{border-color:#0197C6;outline:0}.fl-builder-panel-search-input button{-ms-flex:0 0 38px;flex:0 0 38px}.fl-builder-panel-content-wrap{bottom:0;height:auto;left:0;overflow:hidden;position:absolute;right:0;top:43px}.fl-builder-panel-content{padding-bottom:60px}.fl-builder-blocks-section{border-top:2px solid #e6eaed}.fl-builder--panel-view .fl-builder-blocks-section:first-child{border-top:none}.fl-builder-blocks-group:first-child{padding:20px 0 0}.fl-builder-blocks-group .fl-builder-blocks-section-group-name{display:block;padding:0 30px 15px;color:#000;font-size:20px;font-weight:600;line-height:1.4}.fl-builder-blocks-section .fl-builder-block,.fl-builder-blocks-section .fl-builder-blocks-section-title{display:block;line-height:1.1;padding:15px 20px}.fl-builder--template-collection-section-name,.fl-builder-blocks-section .fl-builder-blocks-section-title{display:inline-block;font-weight:700;font-size:12px;line-height:1.2;text-transform:uppercase;color:#333;padding:4px 10px 4px 15px;margin:0!important;background:#e6eaed;border-bottom-right-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top}.fl-builder-blocks-section .fl-builder-blocks-section-title i{color:#bfbfbf;float:right}.fl-builder-blocks-section-content{overflow:auto;padding:10px 10px 20px}.fl-builder-blocks-section-content:after{float:none;clear:both}.fl-builder-blocks-section-content.fl-builder-modules,.fl-builder-blocks-section-content.fl-builder-rows,.fl-builder-blocks-section-content.fl-builder-widgets{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.fl-builder-blocks-section-content .fl-builder-block-module,.fl-builder-blocks-section-content .fl-builder-block-row{-ms-flex:1 1 50%;flex:1 1 50%;width:50%;box-sizing:border-box}.fl-builder--search-results-panel .fl-builder-blocks-section-content .fl-builder-block-module{-ms-flex:1 1 100%;flex:1 1 100%;width:100%}.fl-builder-blocks-section.fl-active .fl-builder-blocks-section-content{display:block}.fl-builder-blocks-section-content .fl-builder-block{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;font-size:14px;line-height:1.1;font-weight:500;color:#727272}.fl-builder-block{position:relative;height:47px}.fl-builder-block.fl-builder-block-col-group{height:84px}.fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-saved-column.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail,.fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail{padding:10px;height:auto}.fl-builder-block:hover{overflow:visible;z-index:1}.fl-builder-block:hover .fl-builder-block-content{display:block;box-sizing:border-box;position:absolute;top:0;left:0;width:100%;padding:15px 20px;border-radius:4px;background:#fff;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);text-decoration:none;color:#111;cursor:move;overflow:hidden}.fl-builder-block.fl-builder-block-module-template.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-row-template.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-saved-column.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-saved-module.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-block.fl-builder-block-saved-row.fl-builder-block-has-thumbnail .fl-builder-block-content,.fl-builder-blocks-node-template .fl-builder-block,.fl-builder-blocks-section-content .fl-builder-block .fl-builder-block-details{position:relative}.fl-builder-block-module:hover .fl-builder-block-content{width:auto;min-width:100%}.fl-builder-block .fl-builder-block-content .fl-builder-block-visual{display:block;margin-bottom:7px}.fl-builder-block-drag-helper .fl-builder-block-content .fl-builder-block-visual{display:none!important}.fl-builder-block .fl-builder-block-content .fl-builder-block-visual.fl-cols-visual{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;height:30px}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{-ms-flex:1 100%;flex:1 100%;background:#464a4c;height:30px;margin:0 2px;border-radius:2px}.fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{background:#000}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:first-child{margin-left:0!important}.fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col:last-child{margin-right:0!important}.fl-cols-visual.left-right-sidebar .fl-cols-visual-col:first-child,.fl-cols-visual.left-right-sidebar .fl-cols-visual-col:last-child,.fl-cols-visual.left-sidebar .fl-cols-visual-col:first-child,.fl-cols-visual.right-sidebar .fl-cols-visual-col:last-child{-ms-flex-preferred-size:60px;flex-basis:60px}.fl-builder-block-saved-column.fl-builder-block-global .fl-builder-block-title,.fl-builder-block-saved-column:hover .fl-builder-block-title,.fl-builder-block-saved-module.fl-builder-block-global .fl-builder-block-title,.fl-builder-block-saved-module:hover .fl-builder-block-title,.fl-builder-block-saved-row.fl-builder-block-global .fl-builder-block-title,.fl-builder-block-saved-row:hover .fl-builder-block-title{margin-right:70px}.fl-builder-block-module:nth-child(even):hover .fl-builder-block-content{left:auto;right:0}.fl-builder-block-thumbnail{border-radius:4px;background-size:contain;background-repeat:no-repeat;background-position:center;background-color:rgba(0,0,0,.06);margin-bottom:10px;transform-origin:bottom;transition-property:transform,box-shadow;transition-duration:.15s}.fl-builder-block:hover .fl-builder-block-thumbnail{transform:scale(1.05);box-shadow:0 20px 40px rgba(0,0,0,.08)}.fl-builder-block .fl-builder-block-icon{margin-right:7px;fill:#000;display:inline-block;width:20px;height:20px;vertical-align:middle}.fl-builder-block-thumbnail:before{content:"";display:block;padding-top:50%}.fl-builder-block-thumbnail img{max-width:100%;max-height:160px;margin:0;-o-object-fit:cover;object-fit:cover}.fl-builder-blocks-section-content .fl-builder-block{box-shadow:0 0 0 transparent;transition-property:box-shadow;transition-duration:.15s}.fl-builder-blocks-section-content .fl-builder-block i,.fl-user-template-actions i{color:#000;margin-right:10px}.fl-builder-blocks-separator{background:#f1f1f1;height:6px}.fl-builder-block:hover .fl-builder-badge{background:#2ea2cc}.ui-sortable-helper .fl-builder-badge{display:none!important}.fl-builder-modules-cta a{color:#999!important;display:block!important;font-size:12px!important;font-style:italic!important;padding:15px 20px!important;line-height:16px!important}.fl-builder-modules-cta a:hover{background:#e5e5e5!important;color:#666!important;text-decoration:none!important}.fl-builder-modules-cta a:focus{text-decoration:none!important}.fl-builder-modules-cta .fa{float:right!important;font-size:14px!important;margin:3px 0 0 9px!important}.fl-builder--panel-message{text-align:center;padding:40px 20px;font-size:16px}.fl-builder--panel-message .fl-builder-button{display:inline-block;padding:10px}.fl-builder--panel-cta{padding:20px 30px;font-size:16px;text-align:center}.fl-builder--panel-cta a{color:inherit;text-decoration:none}.fl-builder--panel-cta a:hover{text-decoration:none}.fl-builder-block-template-image{margin:5px 0 10px;max-width:100%;border:1px solid #dfdfdf}.fl-builder-block .fl-builder-block-title{overflow:hidden;text-overflow:ellipsis;vertical-align:middle;line-height:1.3}.ui-sortable-helper .fl-builder-block-template-image{display:none!important}@keyframes fl-builder-template-item-enter{from{transform:translateY(100px) scale(.3);opacity:0}to{transform:scale(1);opacity:1}}.fl-builder--template-collection{clear:both;padding:10px 0}.fl-builder--template-collection-section-content{padding:0 10px}.fl-builder--template-collection-item{box-sizing:border-box;width:50%;float:left;padding:10px;cursor:pointer;font-size:13px;transform-origin:center;opacity:1}.fl-builder--template-thumbnail{background-size:cover;background-clip:content-box;background-position:center top;background-color:#fff;border:2px solid transparent;transform-origin:bottom;transition-property:transform,box-shadow;transition-duration:.15s}.fl-builder--template-collection-item[data-id="0"] .fl-builder--template-thumbnail,.fl-user-template .fl-builder--template-thumbnail{border-color:#e4e7ea}.fl-builder--template-thumbnail:before{display:block;content:"";padding-top:120%}.fl-builder--template-thumbnail:hover{transform:scale(1.05);box-shadow:0 20px 40px rgba(0,0,0,.08)}.fl-builder--template-name{text-align:center;padding:4px 0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fl-builder--template-collection-section{padding-bottom:10px;border-bottom:1px solid #dfdfdf}.fl-builder--template-collection-section:after,.fl-builder--template-collection-section:before{content:"";display:block;clear:both}.fl-builder--template-collection-section-name{padding:15px 10px 10px}span.fl-builder-block-no-node-templates{display:block;padding:15px 20px;text-align:center}span.fl-builder-block-no-node-templates:hover{cursor:default}.fl-builder-blocks-section-content .fl-builder-node-template-actions{bottom:0;cursor:default;display:none;position:absolute;right:0;top:0}.fl-builder-blocks-section-content .fl-builder-node-template-delete,.fl-builder-blocks-section-content .fl-builder-node-template-edit{display:inline;cursor:pointer;margin:0;padding:15px 10px;text-align:center;width:30px}.fl-builder-block-details .fl-builder-node-template-delete,.fl-builder-block-details .fl-builder-node-template-edit{padding-top:0!important}.fl-builder-blocks-section-content .fl-builder-node-template-delete i,.fl-builder-blocks-section-content .fl-builder-node-template-edit i{margin:0}.fl-builder-blocks-section-content .fl-builder-node-template-delete:hover i,.fl-builder-blocks-section-content .fl-builder-node-template-edit:hover i{color:#444}.fl-builder-blocks-node-template .fl-builder-block:hover .fl-builder-node-template-actions{display:block}.ui-sortable-helper .fl-builder-node-template-delete,.ui-sortable-helper .fl-builder-node-template-edit{display:none!important}.fl-builder--tabs{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;position:relative;-ms-flex-pack:start;justify-content:flex-start;-ms-flex-align:center;align-items:center}.fl-builder-panel .fl-builder--panel-header{cursor:move;position:absolute;top:0;left:0;right:0;z-index:9}.fl-builder-panel .fl-builder--tabs{-ms-flex-pack:distribute;justify-content:space-around;padding:0 24px;min-height:46px;cursor:pointer}.fl-builder--tab-wrap{-ms-flex:1 1 100%;flex:1 1 100%;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:stretch;align-items:stretch;-ms-flex-pack:justify;justify-content:space-between}.fl-builder--tabs button,.fl-builder--tabs button:active,.fl-builder--tabs button:focus,.fl-builder--tabs button:hover{-ms-flex:1 1 100%;flex:1 1 100%;display:inline-block;text-decoration:none;color:inherit;text-align:center;letter-spacing:normal!important;padding:5px;cursor:pointer;font-size:14px!important;font-weight:600!important;line-height:1.4!important;background:0 0!important;outline:0!important;border:2px solid transparent;border-radius:4px;margin:7px 0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important;top:0;transition-property:background,color;transition-duration:.25s}.fl-builder--current-view-name,.fl-builder-drop-zone{text-align:left;text-overflow:ellipsis;white-space:nowrap}.fl-builder--tabs button:focus{background:#e6eaed!important}.fl-builder--tabs button.is-showing{color:#0086b0}.fl-builder--panel-view{display:none;overflow:hidden}.fl-builder--panel-view.is-showing{display:block}.fl-builder--content-library-panel .fl-builder--panel-view.is-showing{position:absolute;top:96px;bottom:0;left:0;right:0;width:auto;height:auto}.fl-builder--content-library-panel.single-view .fl-builder--panel-view.is-showing{top:52px}.fl-builder--content-library-panel.ui-draggable-dragging{height:500px!important}.fl-builder--content-library-panel .fl-builder-drop-zone{display:none!important}.fl-builder--panel-header .fl-builder--tabs{cursor:move}.fl-builder--category-select{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;position:relative}.fl-builder--selector-display{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;position:relative;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center;color:#161B20;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;cursor:pointer;font-size:13px;font-weight:700;line-height:16px;border-radius:4px}.fl-builder--selector-display-label{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;font-size:inherit;line-height:inherit;width:100%;padding:0!important;color:#6D6D6D;background:0 0;border:2px solid #e4e7ea;border-radius:4px;font-family:inherit}.fl-builder--selector-display-label:active,.fl-builder--selector-display-label:hover{top:0;color:inherit;background:0 0;border:2px solid #e4e7ea;border-radius:4px}.fl-builder--selector-display-label:focus{top:0;color:inherit;background:0 0;border:2px solid #00A0D2;outline:0}.fl-builder--group-label{color:inherit;-ms-flex:0 0 0%;flex:0 0 0%;padding:9px 12px 9px 10px;background:#e6eaed;border-top-left-radius:2px;border-bottom-left-radius:2px}.fl-builder--current-view-name{-ms-flex:1 1 100%;flex:1 1 100%;color:inherit;overflow:hidden;font-weight:600;padding:9px 10px}.fl-builder--selector-menu{display:none;color:#293138;position:absolute;top:46px;left:0;width:100%;background:#fff;border-radius:4px;box-shadow:0 0 20px 2px rgba(0,0,0,.2);overflow:visible}.fl-builder--selector-menu:before{bottom:100%;right:8px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}.fl-builder--category-select.is-showing .fl-builder--selector-menu{display:-ms-flexbox;display:flex;max-height:calc(100vh - 150px)}.fl-builder--category-select.is-showing .fl-builder--selector-menu .fl-builder--menu{margin:10px 0;-ms-flex:1 100%;flex:1 100%;overflow:auto}button.fl-builder-button.fl-builder-bar-title-caret{margin:4px}button.fl-builder-button.fl-builder-bar-title-caret:focus{background-color:#e6eaed!important;border-color:transparent!important}.fl-builder--category-select.is-showing .fl-builder-bar-title-caret i{transform:rotate(180deg)}.fl-builder--menu{margin-bottom:2px}.fl-builder--menu>a,.fl-builder--menu>button,.fl-builder--menu>span{display:block;padding:8px 10px 10px;border-radius:4px;color:inherit;text-decoration:none;background:0 0!important;border:2px solid transparent!important;font-weight:400;font-family:inherit}.fl-builder--menu>a:active,.fl-builder--menu>a:focus,.fl-builder--menu>a:hover,.fl-builder--menu>button:active,.fl-builder--menu>button:focus,.fl-builder--menu>button:hover{background:#e6eaed!important;border:2px solid transparent!important;top:0}.fl-block-col-resize-feedback,.fl-block-overlay-title,.fl-builder-block-drag-helper,.fl-builder-block.ui-draggable-dragging,.fl-builder-drop-zone,.fl-builder-empty,.fl-builder-has-submenu>ul.fl-builder-submenu li a{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}.fl-builder--menu>a:focus,.fl-builder--menu>button:focus{outline:0;color:inherit;text-decoration:none}.fl-builder--menu .fl-inset{padding-left:35px;font-size:14px;line-height:1.25}.fl-builder--menu a.fl-template-collection{color:#161B20}.fl-builder--menu>:after{clear:both}.fl-builder--menu * .fl-builder--menu-item-accessory{float:right;color:#000;text-transform:uppercase;text-align:center;min-width:20px;letter-spacing:2px}.fl-builder--menu * .fl-builder--menu-item-accessory i{font-size:1em;margin-top:2px}.fl-builder--menu .fl-builder-video-wrap iframe{display:block;margin:4px 0;width:100%}.fl-builder-publish-actions{display:-ms-flexbox;display:flex;box-sizing:border-box;position:absolute;top:0;right:0;width:380px;max-width:100%;height:46px;padding:4px;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:end;justify-content:flex-end;opacity:1;pointer-events:auto;transform:scaleX(1) translateX(0);transform-origin:right;transition-property:transform,opacity;transition-duration:.15s}.fl-builder-publish-actions.is-hidden{transform:scaleX(.23) translateX(68px);opacity:0;pointer-events:none}.fl-builder-bar .fl-builder-button-group{display:-ms-flexbox;display:flex;-ms-flex-preferred-size:100%;flex-basis:100%}.fl-builder-bar .fl-builder-button-group>.fl-builder-button{border-radius:0;margin-left:0;-ms-flex-preferred-size:100%;flex-basis:100%;text-align:center;-ms-flex-pack:distribute;justify-content:space-around;box-shadow:none}.fl-builder-bar .fl-builder-button-group>.fl-builder-button:first-child{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.fl-builder-bar .fl-builder-button-group>.fl-builder-button:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.fl-builder-publish-actions-click-away-mask{display:none;position:fixed;top:0;left:0;right:0;height:100vh;background:0 0}.fl-builder-dragging .fl-builder-content:not(.fl-builder-empty){padding:16px 0}.fl-builder-empty{display:none;border:2px dashed #969696;border-radius:8px;color:#909090;font-size:20px;font-weight:700;margin:10px;padding:250px 20px;position:relative;text-align:center;text-transform:uppercase}.fl-builder-edit .fl-builder-empty{display:block}.fl-builder-block-drag-helper,.fl-builder-block.ui-draggable-dragging{background:rgba(255,255,255,.95)!important;border:2px solid #000;border-radius:4px;box-shadow:0 0 8px rgba(0,0,0,.2);-moz-box-shadow:0 0 8px rgba(0,0,0,.2);-webkit-box-shadow:0 0 8px rgba(0,0,0,.2);color:#333!important;font-size:13px!important;height:47px!important;line-height:40px!important;overflow:hidden;padding:0 20px;position:fixed!important;text-overflow:ellipsis;white-space:nowrap;width:180px!important;z-index:100010!important;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-line-pack:center;align-content:center;-ms-flex-pack:start;justify-content:flex-start}.fl-builder-block.fl-builder-block-drag-helper:hover{padding:0;box-shadow:none}.fl-builder-block-drag-helper:hover .fl-builder-block-content{position:static;padding:0 20px}.fl-col-has-highlight-guide .fl-col-content,.fl-col-highlight,.fl-row-highlight .fl-col-group{position:relative}.fl-builder-block-saved-column.fl-builder-block-drag-helper:hover .fl-builder-block-content,.fl-builder-block-saved-module.fl-builder-block-drag-helper:hover .fl-builder-block-content,.fl-builder-block-saved-row.fl-builder-block-drag-helper:hover .fl-builder-block-content{padding:14px 20px}.fl-builder-block-drag-helper .fl-builder-block-icon{fill:#000;margin-top:-10px}.fl-builder-drop-zone{animation:fl-builder-drop-zone-pulse 2s infinite;background:#00A2D7;border-radius:4px;color:#fff!important;display:block;font-weight:400;font-size:12px;letter-spacing:1px;line-height:14px;margin:10px;padding:6px 8px 5px;position:relative;text-shadow:none;text-transform:none;overflow:hidden;z-index:10}@keyframes fl-builder-drop-zone-pulse{0%,100%{background-color:#00A2D7}50%{background-color:#79DEFF}}.fl-builder-drop-zone-global{animation:fl-builder-drop-zone-global-pulse 2s infinite;background:#ff9600}.fl-field,.fl-lightbox{animation-duration:.25s}@keyframes fl-builder-drop-zone-global-pulse{0%,100%{background-color:#FFBC5C}50%{background-color:#ff9600}}.fl-builder-content>.fl-builder-drop-zone{margin:10px 20px}.fl-row-content>.fl-builder-drop-zone{margin:3px 7px}.fl-col-has-cols>.fl-col-content>.fl-builder-drop-zone{margin:3px 10px}.fl-sortable-disabled>.fl-builder-drop-zone{display:none!important}.fl-col-group-equal-height.fl-col-group-align-center .fl-col-content>.fl-builder-drop-zone{width:100%}.fl-row-highlight{padding:16px 0}.fl-row-highlight .fl-row-content{border:2px dashed rgba(203,205,206,.5);padding:8px;border-radius:6px}.fl-row-highlight.fl-node-global .fl-row-content{border-color:#ff9600}.fl-col-highlight{padding:8px}.fl-col-highlight .fl-col-content{border-style:dashed!important;border-color:#00a0d2!important;border-radius:4px;min-height:100px;overflow-x:hidden;width:100%;border-width:2px!important}.fl-col-has-cols.fl-col-highlight>.fl-col-content{padding:8px}.fl-col-highlight.fl-node-global .fl-col-content{border-color:#ff9600!important}.fl-builder-simple .fl-col-highlight .fl-col-content{border:none!important}.fl-col-highlight-guide{background:rgba(0,160,210,.05);border:2px solid #00A0D2;border-radius:4px;bottom:4px;left:4px;position:absolute;right:4px;top:4px;z-index:1}.fl-node-global .fl-col-highlight-guide{border-color:#ff9600!important;background-color:rgba(255,150,0,.06)!important}.fl-col-has-highlight-guide .fl-block-overlay{background:0 0;border-color:transparent}.fl-col-has-highlight-guide .fl-block-col-resize{display:none}.fl-col-has-highlight-guide .fl-col-highlight .fl-col-content{border-color:transparent!important}.fl-col-drop-target{bottom:8px;display:none;left:-9px;position:absolute;top:8px;width:18px;z-index:1}.fl-col-highlight .fl-col-drop-target{display:block}.fl-col-drop-target-last{left:auto;right:-9px}.fl-col-drop-target .fl-builder-drop-zone{bottom:0;left:2px;margin:0;padding:0;position:absolute;right:2px;top:0}.fl-col-group-drop-target{display:none;left:8px;height:18px;position:absolute;right:8px;top:-9px;z-index:1}.fl-row-highlight .fl-col-group-drop-target{display:block}.fl-col-group-drop-target-last{top:auto;bottom:-9px}.fl-col-group-drop-target .fl-builder-drop-zone{bottom:2px;left:0;margin:0;padding:0;position:absolute;right:0;top:2px}.fl-row-content>.fl-col-group-drop-target{position:static}.fl-row-content>.fl-col-group-drop-target .fl-builder-drop-zone{height:18px;position:static}.fl-row-drop-target{display:none;left:0;height:24px;margin-top:-28px;position:absolute;right:0;z-index:1}.fl-row-highlight .fl-row-drop-target{display:block}.fl-row-drop-target-last{margin-top:4px}.fl-row .fl-row-drop-target .fl-builder-drop-zone{bottom:0;left:4px;margin:0;position:absolute;right:4px;top:0}.fl-builder-content>.fl-row-drop-target{margin:0;position:static}.fl-builder-dragging .fl-builder-content.fl-builder-empty>.fl-row-drop-target{bottom:10px;display:block;height:auto;left:0;position:absolute;right:0;top:10px}.fl-builder-content .fl-row-drop-target .fl-builder-drop-zone{margin-bottom:0;margin-top:0}.fl-col-group:focus,.fl-col:focus,.fl-module:focus,.fl-row:focus{outline:0}.fl-sortable-proxy{display:none}.fl-block-overlay,.fl-block-overlay *{text-shadow:none;-webkit-touch-callout:none}.fl-block-overlay-active{position:relative}.fl-block-overlay-actions{background:#00A0D2;float:left;height:30px;margin:-1px -1px 0;padding:0 4px;text-shadow:none;border-bottom-right-radius:5px;border-top-left-radius:3px}.fl-row-overlay-header-bottom .fl-block-overlay-actions{border-radius:0 5px 0 3px}.fl-builder-col-resizing .fl-block-overlay-actions,.fl-builder-row-resizing .fl-block-overlay-actions{overflow:hidden}.fl-block-overlay-actions>span{display:block;float:left}.fl-block-overlay-actions i{color:#fff!important;cursor:pointer;display:block!important;float:left;font-size:16px!important;height:28px!important;line-height:28px!important;opacity:.8;filter:alpha(opacity=80);text-align:center;width:32px!important}.fl-block-overlay-actions i:hover{opacity:1;filter:alpha(opacity=100)}.fl-block-overlay-actions>i:first-child{padding-left:4px}.fl-block-overlay-actions>i:last-child{padding-right:2px}.fl-block-overlay-actions .fl-block-move{cursor:move}.fl-block-overlay-title{color:#fff!important;float:left;font-size:14px;height:30px;line-height:29px;margin-right:2px;padding:0 12px 0 8px}.fl-col-overlay,.fl-module-overlay,.fl-row-overlay{background:rgba(190,239,255,0);color:#fff}.fl-row-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:0;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;left:0;position:absolute;top:-33px;right:0;z-index:100006}.fl-row-overlay.fl-row-menu-active,.fl-row-overlay.fl-row-menu-active.fl-block-overlay.fl-block-overlay-global{z-index:100007}.fl-row-full-width .fl-row-overlay{left:2px;right:2px;bottom:2px}.fl-row-overlay-header-bottom{bottom:-32px!important;top:0}.fl-row-overlay-header-bottom .fl-block-overlay-header{position:absolute;bottom:0}.fl-block-overlay-active .fl-row-content-wrap{position:relative}.fl-block-overlay-active .fl-row-content{position:relative;z-index:100007!important}.fl-builder-row-resizing .fl-col.fl-block-overlay-active,.fl-builder-row-resizing .fl-module.fl-block-overlay-active{position:static}.fl-col-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:8px;cursor:pointer;left:8px;position:absolute;right:8px;top:8px;z-index:100008}.fl-module-overlay{border:2px solid #00A0D2;border-radius:4px;bottom:4px;cursor:pointer;left:4px;min-height:32px;position:absolute;right:4px;top:4px;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-module-overlay{cursor:default}.fl-module-adjust-height{padding-bottom:15px;padding-top:15px}.fl-block-overlay-global{background:rgba(255,150,0,0);border:2px solid #F7A407;border-radius:4px}.fl-block-overlay-global .fl-block-overlay-actions{background:#F7A407}.fl-block-overlay-title-global{background:#fff;color:#ff9600!important;font-size:11px;letter-spacing:1px;margin-left:4px;padding:2px 4px;vertical-align:top}.fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,0);cursor:pointer;z-index:100007}.fl-builder-global-templates-locked .fl-block-overlay-global.fl-row-overlay{cursor:default}.fl-builder-row-template .fl-block-overlay-global.fl-row-overlay{background:rgba(255,150,0,0);cursor:default;z-index:100006}.fl-block-overlay-global.fl-row-overlay .fl-block-col-resize{display:none}.fl-block-overlay-muted .fl-row-overlay{background:rgba(85,93,102,0);border:2px solid #555D66}.fl-block-overlay-muted .fl-row-overlay .fl-block-overlay-actions{background:#555D66}.fl-block-overlay-muted .fl-row-overlay .fl-block-col-resize{display:none}.fl-node-disabled .fl-row-content-wrap,.fl-node-disabled>.fl-col-content{opacity:.3}.fl-block-col-resize{bottom:0!important;position:absolute;top:0!important;width:6px}.fl-block-col-resize-e{cursor:ew-resize;left:auto!important;right:-2px!important}.fl-block-col-resize-w{cursor:ew-resize;left:-7px!important}.fl-block-col-resize-handle-wrap{margin:-4px 0 0 -5px;padding:0 5px;position:absolute;top:50%!important}.fl-block-col-resize-e .fl-block-col-resize-handle-wrap{margin-left:-6px}.fl-block-col-resize-handle{background:#fff;border:2px solid #00A0D2;border-radius:50%;height:12px;width:12px}.fl-node-global .fl-block-col-resize-handle{border-color:#ff9600}.fl-block-col-resize-feedback{color:#333!important;display:none;font-size:11px!important;position:absolute}.fl-block-col-resize-feedback-left,.fl-block-col-resize-feedback-right{background:#fff;border:1px solid #3ba0ff;padding:2px 4px}.fl-block-col-resize-feedback-left{right:20px;top:-7px}.fl-block-col-resize-feedback-right{left:20px;top:-7px}.fl-builder-has-submenu{position:relative}.fl-builder-has-submenu>ul.fl-builder-submenu{background:#00A0D2;box-shadow:0 0 20px rgba(0,0,0,.2);border-radius:0 4px 4px;display:none;left:0;list-style:none;margin:0;padding:6px 0;position:absolute;text-align:left;top:100%;width:165px;z-index:100008}.fl-builder-has-submenu>ul.fl-builder-submenu li{list-style:none;margin:0;padding:0}.fl-builder-submenu-right ul.fl-builder-submenu{left:auto;right:0}.fl-builder-has-submenu.fl-builder-submenu-open>ul.fl-builder-submenu{display:block}.fl-builder-has-submenu>ul.fl-builder-submenu li a{border-bottom:0 none;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#fff!important;display:block;line-height:13px;font-size:13px;font-weight:400;opacity:.8;filter:alpha(opacity=80);overflow:hidden;padding:6px 12px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.fl-builder-has-submenu>ul.fl-builder-submenu li a:hover{background:#0197C6;color:#fff;opacity:1;filter:alpha(opacity=100);text-decoration:none}.fl-builder-actions-title,.fl-builder-alert-lightbox .fl-lightbox-message{color:#333!important;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:16px!important}.fl-builder-has-submenu .fl-builder-submenu .fa,.fl-builder-has-submenu .fl-builder-submenu .far,.fl-builder-has-submenu .fl-builder-submenu .fas{float:right;height:12px!important;line-height:12px!important;position:relative;right:-5px;width:14px!important}.fl-builder-has-submenu .fl-builder-has-submenu .fl-builder-submenu{display:none;left:100%;top:0}.fl-builder-has-submenu .fl-builder-submenu-right.fl-builder-has-submenu .fl-builder-submenu{left:auto;right:100%}.fl-builder-has-submenu .fl-builder-has-submenu:hover .fl-builder-submenu{display:block}.fl-builder-submenu-sep{padding:7px 0!important}.fl-builder-submenu-sep div{border-bottom:1px solid rgba(255,255,255,.4)}.fl-block-col-move,.fl-block-col-move-parent{cursor:move;position:relative}.fl-builder-submenu .fa-arrows-alt{cursor:move;display:none!important}.fl-builder-submenu a:hover .fa-arrows-alt{display:block!important;float:right;line-height:12px!important;height:12px!important}.fl-block-overlay-global ul.fl-builder-submenu{background:#ff9600!important}.fl-block-overlay-global ul.fl-builder-submenu li a:hover{background:#fa3}.fl-builder-actions-lightbox .fl-lightbox{display:block;width:300px;border-radius:4px}.fl-builder-actions-lightbox .fl-lightbox-content-wrap{display:block}.fl-builder-actions-lightbox .fl-builder-actions{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:25px;text-align:center}.fl-builder-actions-title{display:block;margin-bottom:20px}.fl-builder-actions .fl-builder-button{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;margin-bottom:7px;min-height:36px}.fl-builder-alert-lightbox{padding:20px;z-index:30000000;top:0;pointer-events:auto}.fl-builder-alert-lightbox .fl-lightbox{max-width:440px;width:auto}.fl-builder-alert-lightbox .fl-lightbox-content-wrap{display:block}.fl-builder-alert-lightbox .fl-lightbox-message{line-height:24px;padding:30px}@keyframes fl-builder-content-section-entry{from{transform:translateY(150px) translateX(100px) scale(.3);opacity:0}to{transform:translateY(0) translateX(0) scale(1);opacity:1}}.fl-template-category-select{width:180px!important}.fl-template-selector .fl-builder-settings-section{margin:0 0 10px}.fl-template-selector .fl-builder-settings-fields{height:470px}.fl-template-selector .fl-builder-settings-tab{width:560px}.fl-template-selector .fl-builder-settings-tab-description{font-size:15px!important;margin:0!important;padding:10px 0 25px;text-align:center}.fl-template-preview{float:left;margin:0 25px 30px 0;position:relative;text-align:center;width:170px}.fl-template-preview.fl-last{margin-right:0}.fl-template-image{border:1px solid #d9d9d9;cursor:pointer;margin-bottom:12px;height:164px;overflow:hidden}.fl-template-image:hover{border-color:red}.fl-template-image img{max-height:none;width:100%}.fl-template-preview span{display:block;text-align:center}.fl-user-template-category-name{background:#f2f2f2;border-bottom:3px solid #dfdfdf;border-top:2px solid #dfdfdf;font-weight:700;padding:8px 15px}.fl-user-templates{border-bottom:1px solid #dfdfdf;padding:10px 0 20px}.fl-builder--user-templates-section-content{border-bottom:2px solid #e6eaed;padding:10px}.fl-builder--user-templates-section-content:first-child{padding-top:0}.fl-builder--user-templates-section-content:last-child,.fl-user-templates:last-child{border-bottom:none}.fl-builder--user-templates-section-name{font-weight:700;font-size:16px;color:#333;z-index:9999;padding:15px 10px;margin:0 10px}@keyframes fl-list-item-entry{from{opacity:0;transform:scale(.5) translateY(100px)}to{opacity:1;transform:scale(1) translateY(0)}}.fl-builder--save-new-user-template,.fl-user-template{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;font-size:16px;font-weight:200;line-height:1.1;padding:10px 20px;color:#6d6d6d}.fl-user-template:hover{cursor:pointer;background:#fff;box-shadow:0 6px 20px rgba(0,0,0,.08);text-decoration:none;color:#111;padding-right:68px}.fl-user-template-name{overflow:hidden;text-overflow:ellipsis;-ms-flex:1;flex:1}.fl-user-template-actions{display:none;bottom:0;position:absolute;right:0;top:0}.fl-user-template:hover .fl-user-template-actions{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center}.fl-user-template-actions a{display:inline-block;padding:15px 0;width:30px}.fl-user-template:hover a:hover i{color:#444!important}.fl-user-templates-message{display:none}.fl-user-template-thumbnail{-ms-flex:0;flex:0;margin-right:20px}.fl-user-template-thumbnail .fl-builder--template-thumbnail{background-size:cover;background-position:center top;width:45px}.fl-user-template-thumbnail .fl-builder--template-thumbnail:hover{box-shadow:none;transform:scale(1);transition-property:none}.fl-builder--save-new-user-template .fl-user-template-thumbnail .fl-builder--template-thumbnail{border-style:dashed;border-width:2px;border-color:#ccd4da}.fl-builder--save-new-user-template .fl-save-control{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex:1;flex:1}.fl-builder--save-new-user-template .fl-save-control input{background:0 0;border:none!important;-ms-flex:1;flex:1;font-size:16px;margin-right:10px;margin-left:-12px;color:#000}.fl-builder--save-new-user-template .fl-save-control input::-webkit-input-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input::-moz-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input:-ms-input-placeholder{color:#777}.fl-builder--save-new-user-template .fl-save-control input:-moz-placeholder{color:#777}@keyframes fl-slide-in-right{from{transform:translateX(50px)}to{transform:translateX(0)}}.fl-builder--save-new-user-template .fl-save-control button{display:none;animation-name:fl-slide-in-right;animation-duration:.25s;background-color:#00a0d2;border:none;padding:0 15px}.fl-save-control-mask{display:none;background:0 0;position:absolute;top:-50px;left:0;bottom:0;right:0;z-index:-1;min-height:80vh}.fl-builder-templates-cta{margin-bottom:20px}.fl-builder-templates-cta p{display:inline-block!important;width:75%!important;font-size:14px!important;line-height:1.5!important;margin-bottom:0!important}.fl-builder-templates-cta .fl-builder-upgrade-button{font-size:13px!important;line-height:13px!important;position:relative;top:8px;left:15px;padding:1px 12px}.fl-builder-settings-message,.fl-builder-settings-message *{font-size:15px!important;line-height:23px!important}.single-fl-builder-template .fl-content{width:100%!important}form.fl-builder-settings{height:100%;margin:0;padding:0;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.fl-builder-settings-message{padding:20px 25px!important;background:#f2f2f2!important}.fl-builder-preview-loader{position:relative;top:-2px;margin-left:3px}.fl-lightbox-header .fl-builder-preview-loader{margin:0;position:absolute;right:40px;top:15px}@keyframes fl-grab-attention{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}.fl-lightbox-width-slim .fl-form-table{margin:20px 25px 10px 15px!important;width:calc(100% - 60px)}.fl-lightbox-width-slim .fl-form-table th{display:block;padding:10px 0 0 12px!important}.fl-lightbox-width-slim .fl-form-table td{display:block}.fl-lightbox-width-slim .fl-form-table td:first-child{padding-left:10px!important}.fl-lightbox-width-slim .fl-form-table .fl-field[data-type=editor] td:first-child{padding-left:0!important}.fl-field-label .fl-field-responsive-toggle,.fl-lightbox-width-slim .fl-field-control-wrapper .fl-field-responsive-toggle{display:none}.fl-lightbox-width-slim .fl-field-label .fl-field-responsive-toggle{display:inline-block;padding:0 5px!important}.fl-lightbox-width-slim .fl-builder-settings-fields select{width:100%}.fl-lightbox-width-slim .fl-color-picker{display:-ms-flexbox;display:flex;width:auto}.fl-lightbox-width-slim .fl-color-picker-clear{-ms-flex:0 0 50px;flex:0 0 50px}.fl-lightbox-width-slim .mce-menubtn.mce-fixed-width button{width:28px!important}.fl-lightbox-width-slim .mce-btn[aria-label=Blockquote],.fl-lightbox-width-slim .mce-btn[aria-label=Fullscreen]{display:none}.fl-lightbox-width-slim .fl-builder-field-multiple{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;position:relative}.fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-control,.fl-lightbox-width-slim .fl-builder-field-multiple .fl-field-label{width:100%!important}.fl-lightbox-width-slim .fl-builder-field-multiple .fl-builder-field-actions{position:absolute!important;top:0;right:0;width:70px}.fl-lightbox-width-slim .fl-field[data-type=time] select{width:auto}.fl-builder-settings-tabs{margin:6px;border:2px solid #e6eaed;border-radius:4px;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;overflow:hidden}.fl-builder-content-group-select{padding:0 10px 6px;display:none}.fl-builder-content-group-select select{display:block;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;padding:8px 10px;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;border:2px solid #e4e7ea;color:#161B20}select:focus{border-width:2px!important;border-style:solid!important;border-color:#00a0d2!important;outline:0!important}.fl-legacy-settings-tab{background:url(../img/ajax-loader.svg) center center no-repeat;height:100px}.fl-builder-settings-tab:first-child .fl-legacy-settings-tab{background:0 0;height:auto}body .fl-builder-settings-tabs>*{box-sizing:border-box;color:#676F7A!important;fill:#676F7A!important;background:0 0;border:2px solid transparent;border-radius:0;margin:0;outline:0;padding:6px 15px;text-decoration:none!important;font-size:14px;font-weight:400!important;-ms-flex:0 0 auto;flex:0 0 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;text-align:center}.fl-builder-settings-tabs-more g,.fl-builder-settings-tabs-more path,.fl-builder-settings-tabs-more svg,.fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon path{fill:inherit}body .fl-builder-settings-tabs>:first-child{border-top-left-radius:3px;border-bottom-left-radius:3px}body .fl-builder-settings-tabs>:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}body .fl-lightbox-width-slim .fl-builder-settings-tabs>*{-ms-flex:1 1 auto;flex:1 1 auto;padding:6px 8px}body .fl-builder-settings-tabs>.fl-builder-settings-tabs-more{-ms-flex:0 0 60px;flex:0 0 60px;display:none;margin-left:auto;-ms-flex-pack:center;justify-content:center}.fl-builder-settings-tabs-more svg{width:16px;height:auto;margin:auto}body .fl-lightbox-has-tab-overflow .fl-builder-settings-tabs-more{display:-ms-flexbox;display:flex}.fl-builder-settings-tabs>:active,.fl-builder-settings-tabs>:hover{top:0;color:#333;background:0 0;border:2px solid transparent}.fl-builder-settings-tabs>:focus{top:0;outline:0;border:2px solid transparent;background:0 0;color:#0086b0;fill:#0086b0}.fl-builder-settings-tabs .fl-active,.fl-builder-settings-tabs-more.fl-contains-active,.fl-builder-settings-tabs-overflow-menu .fl-active{color:#0086b0!important;fill:#0086b0!important;position:relative;background:#e6eaed}.fl-builder-settings-tabs .fl-active.fl-overflowed,.fl-builder-settings-tabs .fl-overflowed{display:none!important}.fl-builder-settings-tabs .error{color:#d03436;padding-right:10px}.fl-builder-settings-tabs .error .fl-error-icon,.fl-builder-settings-tabs-overflow-menu .error .fl-error-icon{background:url(../img/sprite.png) -148px -5px no-repeat;display:inline-block;height:16px;margin-left:7px;position:relative;top:3px;width:16px}.fl-builder-settings-tabs-more.fl-contains-errors{fill:#d03436!important}.fl-builder-settings-tab{display:none;width:auto!important}.fl-builder-settings-tab.fl-active{display:block}.fl-builder-settings-tab-description{background:#e4e7ea;padding:10px 15px;border-radius:4px;margin:20px}.fl-builder-settings-tab-description a{text-decoration:underline!important}.fl-builder-settings-tab-description a:hover{color:#333}.fl-builder-settings-tabs-overflow-menu{display:none;position:absolute;left:0;right:0;border:2px solid #e6eaed;border-top:3px solid #00a0d2;border-radius:4px;background:#fff;z-index:9999;margin:0 6px;padding:10px;-ms-flex-direction:column;flex-direction:column;box-shadow:0 0 20px 2px rgba(0,0,0,.2)}.fl-builder-settings-tabs-overflow-menu:before{bottom:100%;right:20px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#00a0d2;border-width:10px;margin-left:-10px}.fl-builder-settings-tabs-overflow-menu>a{display:block;padding:10px 15px;font-size:14px;font-weight:600!important;border:2px solid transparent;border-radius:4px;outline:0}.fl-builder-settings-tabs-overflow-menu>a:hover{background:#e6eaed;text-decoration:none}.fl-builder-settings-tabs-overflow-click-mask{display:none;position:fixed;top:0;bottom:0;left:0;right:0;background:0 0;z-index:9}.fl-form-table{background:none;border:none;width:calc(100% - 35px)}.fl-form-table tbody{border:none}.fl-form-table tr,.fl-form-table tr:nth-child(even){background:0 0}.fl-form-table td,.fl-form-table th{background:0 0!important;border:none!important;font-weight:400!important;text-align:left!important}.fl-form-table th{padding:10px 10px 10px 30px!important;vertical-align:top!important;width:200px!important}.fl-form-table td:first-child{padding-left:30px!important}.fl-form-table th label{color:#333;width:auto;max-width:100%}.fl-photo-field .fl-photo-preview-img img,.fl-video-field .fl-video-preview-img img{max-width:60px}.fl-form-table td{padding:8px 10px}.fl-lightbox-width-slim .fl-form-table td{padding:4px 0 10px}.fl-builder-settings-fields{margin:0;overflow:hidden;position:relative;-ms-flex:1 100%;flex:1 100%;visibility:hidden}.fl-lightbox-header .fl-builder-settings-fields{height:auto;margin:0;position:absolute;right:10px;top:10px}.fl-builder-settings-fields .fl-nanoscroller-content{padding:0}.fl-builder-settings-fields .fl-field-control-wrapper{position:relative}.fl-field{animation-delay:.1s}.fl-builder-settings-fields input[type=email],.fl-builder-settings-fields input[type=file],.fl-builder-settings-fields input[type=number],.fl-builder-settings-fields input[type=password],.fl-builder-settings-fields input[type=search],.fl-builder-settings-fields input[type=tel],.fl-builder-settings-fields input[type=text],.fl-builder-settings-fields input[type=url],.fl-builder-settings-fields select,.fl-builder-settings-fields textarea{background:#fff!important;border-color:transparent!important;border-style:solid;border-width:2px;border-radius:4px!important;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);color:#333!important;display:inline;font-size:13px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px 9px;width:auto;box-sizing:border-box}.fl-builder-settings-fields input[type=email],.fl-builder-settings-fields input[type=file],.fl-builder-settings-fields input[type=number],.fl-builder-settings-fields input[type=password],.fl-builder-settings-fields input[type=search],.fl-builder-settings-fields input[type=tel],.fl-builder-settings-fields input[type=text],.fl-builder-settings-fields input[type=url],.fl-builder-settings-fields select{height:36px!important}.fl-builder-settings-fields input[type=number]{width:70px}.fl-builder-lightbox .fl-builder-settings-fields input[type=email]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=file]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=number]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=password]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=search]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=tel]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=text]:focus,.fl-builder-lightbox .fl-builder-settings-fields input[type=url]:focus,.fl-builder-lightbox .fl-builder-settings-fields select:focus,.fl-builder-lightbox .fl-builder-settings-fields textarea:focus{border-width:2px!important;border-style:solid!important;border-color:#00a0d2!important;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)!important}.fl-builder-settings-fields ::-webkit-input-placeholder{color:#999!important;font-size:13px}.fl-builder-settings-fields input:-moz-placeholder{color:#999;font-size:13px}.fl-builder-settings-fields ::-moz-placeholder{color:#999!important;font-size:13px}.fl-builder-settings-fields input:-ms-input-placeholder{color:#999;font-size:13px}.fl-builder-settings-fields label{display:inline-block;font-weight:400;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin-bottom:3px}.fl-builder-settings-fields select{-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;color:#000;margin:0 0 2px;padding:2px 10px;padding-right:30px!important;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important}.fl-builder-settings-fields select[multiple]{height:60px;background-image:none!important}.fl-builder-custom-field select,.fl-photo-field select{-webkit-box-shadow:none;border-color:#e6eaed!important}.fl-font-field .fl-font-field-font{margin-bottom:4px;width:calc(70% - 5px)!important}.fl-font-field .fl-font-field-weight{width:30%!important}.fl-lightbox-width-slim input.text-full+.fl-field-description,.fl-lightbox-width-slim select+.fl-field-description{display:block;padding:8px 10px;margin:0}.fl-field[data-type=dimension] .fl-field-control-wrapper{display:-ms-flexbox;display:flex}.fl-field[data-type=dimension] .fl-field-description{padding-top:9px}.fl-field[data-type=dimension] .fl-field-responsive-toggle{padding:9px 9px 0 0}.fl-dimension-field-units{display:-ms-flexbox;display:flex}.fl-dimension-field-unit{padding-right:5px}.fl-dimension-field-unit input{max-width:60px;width:auto!important}.fl-dimension-field-unit label{padding:5px 0 0;font-size:12px;color:inherit!important;display:block;text-align:center}.fl-link-field-search input{box-shadow:none!important;width:100%!important;padding:3px 9px!important}.fl-link-field-search #as-original-link-search{width:100%}.fl-builder-settings-section{border-top:2px solid #E6EAED}.fl-builder-settings-section:first-child{border-top:none!important}.fl-custom-query .fl-builder-settings-section{border-top:2px solid #E6EAED!important}.fl-builder-settings-description{padding:0 10px 10px;margin:0;font-style:italic;opacity:.75}.fl-builder-settings-fields table{margin:20px 0}.fl-builder-settings-fields h3.fl-builder-settings-title{display:inline-block;background:#E6EAED;padding:4px 10px 4px 15px;margin:0;text-transform:uppercase!important;border-bottom-right-radius:4px;font-size:12px!important;font-weight:700;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.wp-core-ui h1,.wp-core-ui h2,.wp-core-ui h3,.wp-core-ui h4,.wp-core-ui h5,.wp-core-ui h6{color:#333}.wp-core-ui .submitbox .submitdelete{color:#a00}.wp-core-ui button{font-weight:400}.wp-core-ui input[type=email],.wp-core-ui input[type=file],.wp-core-ui input[type=number],.wp-core-ui input[type=password],.wp-core-ui input[type=search],.wp-core-ui input[type=tel],.wp-core-ui input[type=text],.wp-core-ui input[type=url],.wp-core-ui select,.wp-core-ui textarea{background-color:#fff;border-color:#dfdfdf;border-style:solid;border-width:1px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;color:#333;font-weight:400}.wp-core-ui input[type=email]:focus,.wp-core-ui input[type=file]:focus,.wp-core-ui input[type=number]:focus,.wp-core-ui input[type=password]:focus,.wp-core-ui input[type=search]:focus,.wp-core-ui input[type=tel]:focus,.wp-core-ui input[type=text]:focus,.wp-core-ui input[type=url]:focus,.wp-core-ui select:focus,.wp-core-ui textarea:focus{background:0 0;border-color:#aaa}.wp-core-ui input[type=search]{background-image:none;padding:6px}.fl-field-responsive-setting{display:inline-block}.fl-field-responsive-setting-medium,.fl-field-responsive-setting-responsive{display:none}i.fl-field-responsive-toggle{color:grey;cursor:pointer;display:inline-block;font-size:15px!important;height:auto;line-height:18px!important;text-align:left;vertical-align:middle;width:20px}i.fl-field-responsive-toggle:hover{color:#000}.fl-builder-settings-fields input.text-full,.fl-builder-settings-fields textarea{width:100%}.fl-color-picker{cursor:pointer}.fl-color-picker .fl-color-picker-clear{box-sizing:border-box}.fl-color-picker .fl-color-picker-clear:hover{background-color:#ededed}.colorpicker input{padding:0!important;font-size:11px!important;color:#fff!important;width:29px!important;height:auto!important;background:0 0!important;border:none!important}.colorpicker .colorpicker_hex input{width:45px!important}.fl-builder-custom-field{background:#fff;border:2px solid transparent;border-radius:4px;padding:7px 10px;box-shadow:0 2px 4px 0 rgba(0,0,0,.12);min-height:36px;box-sizing:border-box}.fl-builder-field-multiple .fl-builder-custom-field{cursor:move}.fl-builder-custom-field a{color:#21759b!important;text-decoration:underline!important}.fl-builder-custom-field a:hover{color:#d54e21!important}.fl-builder-custom-field label.error{margin-top:5px}.fl-photo-field .fl-photo-preview{display:-ms-flexbox;display:flex}.fl-photo-field .fl-photo-select,.fl-photo-field.fl-photo-empty .fl-photo-preview{display:none}.fl-photo-field.fl-photo-empty .fl-photo-select{display:block}.fl-photo-field .fl-photo-preview-img{line-height:0;margin:5px 0}.fl-photo-field .fl-photo-preview select{margin:8px 0 8px 10px;width:200px}.fl-photo-field.fl-photo-no-attachment .fl-photo-preview select{display:none}.fl-photo-field .fl-photo-preview-filename{display:none;font-size:14px;font-weight:700;margin:7px 0 5px 11px}.fl-photo-field.fl-photo-no-attachment .fl-photo-preview-filename{display:inline-block;word-break:break-all}.fl-multiple-photos-field .fl-multiple-photos-select,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-add,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-count,.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-edit,.fl-multiple-photos-lightbox .gallery-settings,.fl-photo-field.fl-photo-no-attachment .fl-photo-edit{display:none}.fl-photo-field .fl-photo-edit{margin:0 0 0 11px}.fl-multiple-photos-field .fl-multiple-photos-add,.fl-photo-field .fl-photo-remove,.fl-photo-field .fl-photo-replace{margin:0 0 0 8px}.fl-builder-edit .media-modal{z-index:9999991}.fl-builder-edit .media-modal-backdrop{z-index:999999}.fl-builder-edit .media-frame{-webkit-backface-visibility:hidden}.fl-builder-edit .media-modal-content h1{font-family:inherit}.fl-builder-edit .media-modal-content .thumbnail{padding:0;border:none;border-radius:0}.fl-builder-edit button.button-link.media-modal-close{position:absolute;box-shadow:none;-webkit-box-shadow:none}.fl-builder-edit .media-frame.hide-menu{visibility:visible}span.select2-container.select2-container--open{z-index:9999999}.fl-multiple-photos-field.fl-multiple-photos-empty .fl-multiple-photos-select{display:inline}.fl-multiple-photos-count{font-weight:700;margin-bottom:3px}.fl-video-field .fl-video-select,.fl-video-field.fl-video-empty .fl-video-preview{display:none}.fl-video-field.fl-video-empty .fl-video-select{display:block}.fl-video-field .fl-video-preview-img{float:left;line-height:0;margin:5px 0}.fl-video-field .fl-video-preview-img .dashicons.dashicons-media-video{display:block;font-size:60px;height:60px;line-height:60px;width:60px}.fl-video-field .fl-video-preview-filename{display:inline-block;font-size:14px;font-weight:700;margin:7px 0 5px 11px}.fl-video-field .fl-video-remove,.fl-video-field .fl-video-replace{margin:0 0 0 11px}.fl-multiple-audios-field .fl-multiple-audios-select,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-add,.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-edit{display:none}.fl-multiple-audios-field.fl-multiple-audios-empty .fl-multiple-audios-select{display:block}.fl-multiple-audios-field .fl-multiple-audios-add{margin:0 0 0 8px}.fl-icon-field .fl-icon-select,.fl-icon-field.fl-icon-empty .fl-icon-preview{display:none}.fl-icon-field.fl-icon-empty .fl-icon-select{display:block}.fl-icon-field .fl-icon-preview i{display:inline-block;font-size:28px;margin:10px 10px 9px;vertical-align:middle}.fl-icon-field .fl-icon-remove{margin:0 0 0 8px}.fl-builder-hidden-editor{display:none}.fl-builder-settings .wp-switch-editor{background:#ebebeb;border:1px solid #e5e5e5;border-radius:0;color:#333}.fl-builder-settings .wp-editor-container{border:1px solid #e5e5e5}.fl-builder-settings .mce-toolbar .mce-btn-group .mce-btn{margin:2px 0}.fl-builder-settings .mce-menubtn.mce-fixed-width button{width:100px}.fl-builder-settings .mce-menubtn.mce-fixed-width span{width:100%}.mce-close:active,.mce-close:hover,.mce-toolbar .mce-btn button:active,.mce-toolbar .mce-btn button:hover,.mce-window .mce-btn button:active,.mce-window .mce-btn button:hover{background:0 0;border:none}.mce-ico{font-family:tinymce,Arial!important}.mce-toolbar i.mce-ico{font:400 20px/1 dashicons!important}.fl-builder-edit form#wp-link,.popover[class*=tour-],ul.as-list{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}.wp-core-ui .quicktags-toolbar input.button.button-small{margin:1px!important}.wp-editor-container textarea.wp-editor-area{background:0 0;border:none;padding:10px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.fl-builder-edit form#wp-link{color:#000;font-size:13px}.fl-builder-edit form#wp-link #link-options label{display:block;margin-bottom:2px}.fl-builder-edit form#wp-link #link-options label span{padding-right:10px;vertical-align:middle}.fl-builder-edit form#wp-link #link-options input[type=text]{display:inline-block;height:auto;margin:5px 0 0;padding:3px 5px;width:80%}.fl-builder-edit form#wp-link .query-results{top:225px}.fl-code-field{border:1px solid #E6E6E6;border-left:none}.ace_editor,.ace_editor *{font-family:Monaco,Menlo,"Ubuntu Mono","Droid Sans Mono",Consolas,monospace!important;font-size:12px!important;font-weight:400!important;letter-spacing:0!important}.fl-layout-field-option{border:2px solid #d9d9d9;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-sizing:border-box!important;-moz-box-sizing:border-box!important;-webkit-box-sizing:border-box!important;cursor:pointer;float:left;line-height:0;max-width:23%;margin:0 1% 2%;padding:5px}.fl-layout-field-option-selected,.fl-layout-field-option:hover{border-color:red}.fl-layout-field-option img{max-width:100%}.fl-link-field .fl-link-field-input-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row}.fl-link-field-input{width:auto!important;-ms-flex:1 1 100%;flex:1 1 100%}.fl-link-field .fl-link-field-input-wrap button{-ms-flex:0 0 0%;flex:0 0 0%;margin-left:5px}.fl-link-field-search{display:none;border:2px solid #e6eaed;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;margin:4px 0 0;padding:10px}.fl-link-field-search-title{display:block;margin:0 0 3px 2px}.fl-link-field-search-cancel{margin-top:6px}.fl-help-tooltip{display:inline-block;position:relative}.fl-help-tooltip-icon{color:#999!important;cursor:pointer;font-size:15px!important;padding:5px;vertical-align:middle}.fl-help-tooltip-text{background:#fff;border:1px solid #ccc;box-shadow:0 0 5px #ccc;-moz-box-shadow:0 0 5px #ccc;-webkit-box-shadow:0 0 5px #ccc;display:none;font-weight:400;left:23px;padding:10px 13px;position:absolute;top:-6px;width:250px;z-index:1000;border-radius:4px}.fl-lightbox-width-slim .fl-help-tooltip-text{top:26px;left:-30px}.fl-field-control .fl-form-field{margin-bottom:0}.fl-form-field-preview-text i{display:inline-block;font-size:18px;line-height:22px;margin-bottom:5px}.fl-builder-field-actions{padding-left:0!important;padding-right:0!important;text-align:center;width:85px}.fl-builder-field-actions i{color:#999!important;cursor:pointer;font-size:13px!important;line-height:29px!important;width:16px}.fl-builder-field-actions i:hover{color:#000!important}.fl-builder-field-actions i.fl-builder-field-copy,.fl-builder-field-actions i.fl-builder-field-delete{margin-left:5px}.fl-builder-field-actions i.fl-builder-field-move{cursor:move}.fl-builder-field-dd-helper{background:#ccc;height:30px!important;float:left;width:130px!important}.fl-builder-field-dd-zone{border:1px dashed #ccc;height:30px}.fl-builder-field-actions-single .fl-builder-field-delete,.fl-builder-field-actions-single .fl-builder-field-move{display:none!important}.fl-lightbox-width-slim .fl-builder-field-actions-single .fl-builder-field-copy{float:right!important}.fl-builder-field-multiple .fl-builder-field-actions,.fl-builder-field-multiple .fl-field-control,.fl-builder-field-multiple .fl-field-label{padding-top:2px!important;padding-bottom:2px!important}.fl-builder-field-multiple .fl-builder-field-actions{min-width:70px!important}.fl-builder-field-multiple[data-field=icons] .fl-builder-field-actions{width:70px!important}.fl-builder-field-multiple.ui-sortable-helper .fl-field-control{width:60%}.fl-builder-field-multiple.ui-sortable-helper .fl-builder-field-actions{display:none}.fl-builder-widget-settings input{display:inline-block!important;margin:5px 10px 8px!important}.fl-builder-lightbox-loading{background:url(../img/ajax-loader.svg) center center no-repeat;height:100px}.fl-builder-settings .error,.fl-builder-settings input.error{color:#d03436!important}.fl-builder-settings label.error,.fl-builder-settings p.error{color:#d03436;display:block;margin-top:5px}.fl-builder-settings .fl-form-table .fl-field-description{color:#464646;font-style:normal;margin-left:2px}.fl-lightbox .fl-field-connection{right:-1px}.fl-lightbox .fl-field-connection-content{border:2px solid transparent!important;background:#e4e7ea!important}.fl-field-connection-content .fl-field-connection-label{color:#676f7a!important}ul.as-selections{background-color:#fff;border:none;border-radius:4px;box-shadow:none;color:#333;font-size:12px;height:auto;line-height:15px;margin:1px;outline:0;padding:3px;width:auto}ul.as-selections.loading{background:url(../img/ajax-loader-small.svg) 98% center no-repeat}ul.as-selections li.as-selection-item{background:#d4eaf6;border:none;font-size:11px;line-height:14px;padding:8px 15px;border-radius:4px;margin:2px}ul.as-selections li.as-selection-item.blur{background:#f4f4f4}ul.as-selections li.as-selection-item a.as-close{line-height:12px}ul.as-selections li.as-original{margin:0}ul.as-selections li.as-original input{height:auto;font-size:12px;margin:0;padding:0;box-shadow:none}ul.as-list{margin:0;font-size:13px;color:#000;background-color:#fff;background-color:rgba(255,255,255,.95);z-index:2;box-shadow:0 0 10px rgba(0,0,0,.1);border:none;border:1px solid #dfdfdf;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px}li.as-message,li.as-result-item{border:none}li.as-result-item.active{background:#e5e5e5;border-radius:0;color:#333;text-shadow:none}li.as-result-item em{background:0 0!important;color:#333!important;font-size:12px;padding:0!important;font-weight:700}.fl-custom-query-filter{display:none}.fl-custom-query .fl-field[data-type=suggest] select{margin-bottom:5px;width:100%}.fl-builder-service-settings{position:relative}.fl-builder-service-error{color:red!important;padding:15px 0 0}.fl-builder-service-account-delete{color:red!important;margin-left:10px;position:relative;top:2px}#fl-field-visibility_user_capability .fl-field-description,.fl-builder-service-connect-row .fl-field-description{background:#f0f0f0;color:#333!important;display:block;float:none;margin:10px 0 0;padding:10px}#fl-field-visibility_user_capability .fl-field-description a,.fl-builder-service-connect-row .fl-field-description a{color:#21759b!important;text-decoration:underline!important}.fl-ordering-field-option{background:#fff;border:1px solid #dfdfdf;border-radius:3px;cursor:move;margin-bottom:5px;padding:5px 10px}.fl-ordering-field-option .fa{color:#ccc;float:right;line-height:16px}#tiptip_holder{z-index:1000000}#tiptip_holder.tip_top #tiptip_arrow_inner{border-top-color:#333}#tiptip_holder.tip_bottom #tiptip_arrow_inner{border-bottom-color:#333}#tiptip_holder.tip_right #tiptip_arrow_inner{border-right-color:#333}#tiptip_holder.tip_left #tiptip_arrow_inner{border-left-color:#333}#tiptip_content{background:#333;box-shadow:none}.fl-builder-getting-started-video{line-height:0!important;padding:10px}.fl-builder-getting-started-video iframe{border:none;height:326px;width:100%}.fl-builder-tour-actions .fl-builder-actions-title{font-size:14px!important;line-height:19px}.fl-builder-tour-mask{bottom:0;left:0;position:fixed;right:0;top:0;z-index:100000000}.fl-builder-tour-dimmed{background:rgba(0,0,0,.7);bottom:0;left:0;position:absolute;right:0;top:0}body>.fl-builder-tour-dimmed{position:fixed}.tour-backdrop{z-index:110000}.popover[class*=tour-]{border:1px solid #ccc;border-radius:0;box-shadow:0 0 40px rgba(0,0,0,.3);color:#666;font-size:13px;font-weight:400;line-height:18px;max-width:none;padding:0;width:300px;z-index:100000001}.popover[class*=tour-].bottom>.arrow{border-bottom-color:#ccc}.popover[class*=tour-].bottom>.arrow:after{border-bottom-color:#f7f7f7}.popover[class*=tour-] .popover-title{border-radius:0;color:#333;letter-spacing:normal;text-transform:none}.popover[class*=tour-] .fa-times{color:#b3b3b3;cursor:pointer;font-size:16px;padding:5px;position:absolute;right:3px;top:2px}.popover[class*=tour-] .fa-times:hover{color:#666}.popover[class*=tour-] .popover-content{border-bottom:1px solid #d9d9d9;padding:13px 15px}.popover[class*=tour-] .fl-builder-tour-next{display:block;float:none;width:100%}.popover-navigation button{min-height:36px}.fl-builder-shortcode-mask-wrap{position:relative}.fl-builder-shortcode-mask{bottom:-1px;left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fl-builder--search{border:2px solid transparent;position:relative;padding:0;width:54px;transition-property:width;transition-delay:.1s;transition-duration:.15s}.fl-builder--search.is-expanded{border:2px solid #00A0D0}.fl-builder--search input[type=text],.fl-builder--search input[type=text]:focus{background-color:transparent;border:none!important;box-sizing:border-box;width:100%;font-size:16px;text-align:center}.fl-builder--search:before{display:-ms-flexbox;display:flex;top:0;left:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;content:"\f002";font:normal normal normal 14px/1 Font Awesome\ 5 Free;text-align:center;width:100%;height:100%;position:absolute;pointer-events:none;color:rgba(128,128,128,.6);font-size:17px;opacity:1;transition-property:opacity;transition-duration:.15s}.fl-builder--main-menu-panel,.fl-builder-ui-keyboard-shortcuts{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important}.fl-builder--search.has-text:before,.fl-builder--search.is-expanded:before{opacity:0}.fl-builder--search input::-webkit-input-placeholder{color:rgba(128,128,128,0)!important;transition:color .25s}.fl-builder--search input:focus::-webkit-input-placeholder{color:rgba(128,128,128,.4)!important}.fl-builder--search .search-label{cursor:text}.fl-builder--search .search-clear{display:none;padding:10px 10px 10px 30px;color:#a7a7a7;font-size:12px;position:absolute;right:0;top:0;background-color:#eff1f2;background:linear-gradient(to left,#e4e7ea,#e4e7ea 75%,rgba(228,231,234,0))}.fl-builder--search.has-text .search-clear,.fl-builder--search.is-expanded input{display:inline-block}.fl-builder--search:hover .search-clear{color:#888;background-color:#eff1f2;background:linear-gradient(to left,#dadfe5,#dadfe5 75%,rgba(218,223,229,0))}.fl-builder--search.is-expanded{width:246px}@keyframes fl-builder-show-menu-item{from{transform:translateY(10px) scale(.8);opacity:0}to{transform:translateX(0) translateY(0) scale(1);opacity:1}}.fl-builder--main-menu-panel{display:none;box-sizing:border-box;position:fixed;top:calc(48px + 10px);left:10px;width:360px;color:#222;max-height:calc(100% - 66px);border-radius:4px;background:#fff;border:2px solid #D5DADD;border-top:3px solid #00a0d2;box-shadow:0 15px 45px 8px rgba(0,0,0,.04);font-size:14px!important;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:10000009;pointer-events:auto}.fl-builder--main-menu-panel.is-showing{display:-ms-flexbox;display:flex}.fl-builder--main-menu-panel:before,.fl-theme-builder-preview-select-open .fl-theme-builder-preview-select-items:before{bottom:100%;right:6px;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:solid;border-color:rgba(255,255,255,0);border-bottom-color:#00a0d2;border-width:13px;margin-left:-13px}.fl-builder--main-menu-panel-views{-ms-flex:1 1 100%;flex:1 1 100%;overflow:auto}.fl-builder--main-menu-panel-mask{display:none;position:fixed;top:0;left:0;right:0;bottom:0;z-index:1000119}.fl-builder--main-menu-panel .fl-builder--tabs{padding-left:20px;padding-top:15px}.fl-builder--main-menu-panel-view{display:none}.fl-builder--main-menu-panel-view.is-showing{display:block}.fl-builder--main-menu-panel-view-title{font-size:24px;font-weight:600;padding:25px 22px 0;line-height:1;white-space:nowrap}.fl-builder--main-menu-panel-view-title .title-accessory{float:right;color:#b1b1b1}.fl-builder--main-menu-panel-view-title .title-accessory>i{font-size:20px!important;width:25px!important}.fl-builder--main-menu-panel-view-title .title-accessory>i:hover{color:#222}.fl-builder--main-menu-panel-view-title .pop-view{padding:10px;margin-left:-10px;opacity:.5;font-size:25px;font-weight:400;cursor:pointer;background:0 0;outline:0;border:none;color:inherit}.fl-builder--main-menu-panel-view-title .pop-view:focus{outline:0;top:0;background:#E5EAED!important}.fl-builder--menu-item:before{display:block;content:"";float:none;clear:both}.fl-builder--menu-item{color:inherit;text-align:left;box-sizing:border-box;display:block;padding:10px 15px;margin:0 10px;width:calc(100% - 20px);background:0 0;border:none;border-radius:4px;font-size:14px;line-height:1.1;cursor:pointer;opacity:1}.fl-builder--menu-item:hover{background:#eaf1f8;border:none;text-decoration:none;color:#000}.fl-builder--selector-menu .fl-builder--menu-item:hover{background:#fff}.fl-builder--menu-item-accessory{float:right;text-align:center;display:inline-block;min-width:40px;font-size:14px}.fl-builder--menu-item-accessory.view-arrow{font-size:18px}.fl-builder--menu{padding:0;margin:20px 0}.fl-builder--menu hr{margin:8px 0;background-color:#e6eaed!important;height:2px;border:none}.fl-builder--menu .fl-builder-video-wrap{padding:0 10px 10px}.fl-revision-list-item{display:-ms-flexbox;display:flex}.fl-revision-list-item-text{padding-left:15px}.fl-revision-list-item-date{padding-bottom:5px}.fl-builder--revision-actions{display:none;position:fixed;top:4px;left:4px;z-index:100008;padding:4px 4px 6px;-ms-flex-pack:center;justify-content:center;background:#fff;border-radius:4px}.fl-builder--revision-actions *{margin-right:5px}.fl-builder--revision-actions :last-child{margin:0}.fl-builder--menu-item[data-event=noRevisionsMessage]:hover{background:0 0;box-shadow:none;cursor:default}.fl-no-revisions-message-title{font-weight:700;margin-bottom:10px}.fl-no-revisions-message-text{line-height:22px}.fl-builder-module-placeholder-message{border:1px dashed #ccc;overflow:hidden;padding:20px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.fl-field-connections-menu{z-index:999999}.fl-field-connections-toggle{right:-30px!important}.fl-builder-add-ultimate-presets-button,.fl-builder-add-ultimate-rows-button,.fl-builder-pp-add-template-button,.pp-preview-button,.uabb-live-preview-button{display:none!important}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;background:0 0;transition-property:background;transition-duration:.15s}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-ne,.ui-resizable-nw,.ui-resizable-se,.ui-resizable-sw{width:12px;height:12px}.ui-resizable-se{cursor:se-resize;right:-4px;bottom:-4px}.ui-resizable-sw{cursor:sw-resize;left:-4px;bottom:-4px}.ui-resizable-nw{cursor:nw-resize;left:-4px;top:-4px}.ui-resizable-ne{cursor:ne-resize;right:-4px;top:-4px}.fl-builder-resizable-iframe-fix{position:absolute;top:0;right:0;bottom:0;left:0;z-index:100000000}.fl-builder-panel .ui-resizable-handle:active,.fl-builder-panel .ui-resizable-handle:hover,.fl-lightbox .ui-resizable-handle:active,.fl-lightbox .ui-resizable-handle:hover{background:#00a0d2}.fl-builder-panel .ui-resizable-n,.fl-builder-panel .ui-resizable-s,.fl-lightbox .ui-resizable-n,.fl-lightbox .ui-resizable-s{height:6px}.fl-builder-panel .ui-resizable-n,.fl-lightbox .ui-resizable-n{top:-3px}.fl-builder-panel .ui-resizable-s,.fl-lightbox .ui-resizable-s{bottom:-3px}.fl-builder-panel .ui-resizable-e,.fl-builder-panel .ui-resizable-w,.fl-lightbox .ui-resizable-e,.fl-lightbox .ui-resizable-w{width:6px}.fl-builder-panel .ui-resizable-e,.fl-lightbox .ui-resizable-e{right:-3px}.fl-builder-panel .ui-resizable-w,.fl-lightbox .ui-resizable-w{left:-3px}.fl-lightbox .ui-resizable-ne,.fl-lightbox .ui-resizable-nw,.fl-lightbox .ui-resizable-se,.fl-lightbox .ui-resizable-sw{background:0 0;border:6px solid transparent}.fl-lightbox .ui-resizable-ne:active,.fl-lightbox .ui-resizable-ne:hover,.fl-lightbox .ui-resizable-nw:active,.fl-lightbox .ui-resizable-nw:hover,.fl-lightbox .ui-resizable-se:active,.fl-lightbox .ui-resizable-se:hover,.fl-lightbox .ui-resizable-sw:active,.fl-lightbox .ui-resizable-sw:hover{background:0 0;border-color:#00a0d2}.fl-lightbox .ui-resizable-ne{border-bottom:none;border-left:none;border-top-right-radius:4px}.fl-lightbox .ui-resizable-nw{border-bottom:none;border-right:none;border-top-left-radius:4px}.fl-lightbox .ui-resizable-se{border-top:none;border-left:none;border-bottom-right-radius:4px}.fl-lightbox .ui-resizable-sw{border-top:none;border-right:none;border-bottom-left-radius:4px}.fl-builder-ui-keyboard-shortcuts{display:none;position:fixed;top:0;left:0;bottom:0;right:0;z-index:999999;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;background:rgba(50,50,50,.88);font-size:15px;line-height:1.3;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fl-builder-ui-keyboard-shortcuts.is-showing{display:-ms-flexbox;display:flex}.fl-builder-ui-keyboard-shortcuts-content{box-sizing:border-box;width:500px;background:#f5f7f9;border-radius:4px;padding:30px 0 0;box-shadow:0 10px 30px rgba(0,0,0,.15)}.fl-builder-ui-keyboard-shortcut-item{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;padding:12px 40px}.fl-builder-ui-keyboard-shortcut-item:nth-child(even){background:#eef2f5}.fl-builder-ui-shortcut-keycode{margin-left:auto;text-transform:uppercase;letter-spacing:2px}.fl-builder-ui-keyboard-shortcust-footer{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:center;justify-content:center;padding:10px}.dismiss-shortcut-ui{padding:10px;border-radius:4px;background:#fff;color:#000;font-size:14px;border:2px solid #fff}.dismiss-shortcut-ui:focus,.dismiss-shortcut-ui:hover{top:0;color:#000;background:#eef2f5;border:2px solid #eef2f5}.fl-color-picker-ui{width:300px}.fl-color-picker-ui.fl-color-alpha-enabled{width:238px}.fl-color-picker-ui .iris-picker{float:left;width:100%;height:224px;display:block;position:relative;border-top:1px solid rgba(0,0,0,.1)}.fl-color-picker-ui .iris-picker .iris-square-inner,.fl-color-picker-ui .iris-picker-inner{position:absolute;left:0;top:0;bottom:0;right:0}.fl-color-picker-ui .iris-picker,.iris-picker *{box-sizing:content-box}.fl-color-picker-ui .iris-error{background-color:#ffafaf}.fl-color-picker-ui .iris-picker .iris-square{width:300px;height:200px}.fl-color-picker-ui .iris-picker .iris-palette,.fl-color-picker-ui .iris-picker .iris-slider,.fl-color-picker-ui .iris-picker .iris-square-inner{height:100%;width:12.5%}.fl-color-picker-ui .iris-picker .iris-placeholder,.fl-color-picker-ui .iris-picker .iris-square{position:relative}.fl-color-picker-ui .iris-picker .iris-square-inner{width:auto;margin:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square,.fl-color-picker-ui .iris-ie-9 .iris-square-inner{box-shadow:none;border-radius:0}.fl-color-picker-ui .iris-ie-9 .iris-palette,.fl-color-picker-ui .iris-ie-9 .iris-slider,.fl-color-picker-ui .iris-ie-9 .iris-square{outline:rgba(0,0,0,.1) solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-palette,.fl-color-picker-ui .iris-ie-lt9 .iris-slider,.fl-color-picker-ui .iris-ie-lt9 .iris-square,.fl-color-picker-ui .iris-ie-lt9 .iris-square-inner{outline:#999 solid 1px}.fl-color-picker-ui .iris-ie-lt9 .iris-square .ui-slider-handle{outline:#999 solid 1px;background-color:#fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"}.fl-color-picker-ui .iris-ie-lt9 .iris-square .iris-square-handle{background:0 0;border:3px solid #fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"}.fl-color-picker-ui .iris-picker .iris-strip{box-sizing:border-box;width:calc(300px - 12px);margin:5px 6px 6px;border-radius:4px;position:relative;height:22px;transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle{width:6px;position:absolute;right:0;top:-2px;bottom:-2px;margin:0;border-radius:3px;background:#fff;box-shadow:0 0 2px rgba(0,0,0,.5);z-index:5;cursor:ew-resize}.fl-color-picker-ui .iris-picker .iris-strip .ui-slider-handle:focus{outline:#00a0d2 solid 2px}.fl-color-picker-ui .iris-picker .iris-slider-offset{position:absolute;top:0;left:6px;right:0;bottom:0;width:auto;height:auto;background:0 0;border:none;border-radius:0;transform:rotate(180deg)}.fl-color-picker-ui .iris-picker .iris-square-handle{background:0 0;border:5px solid #999;border-radius:50%;border-color:rgba(128,128,128,.5);box-shadow:none;width:12px;height:12px;position:absolute;left:-10px;top:-10px;cursor:move;opacity:1;z-index:10}.fl-color-picker-ui .iris-picker .ui-state-focus .iris-square-handle{opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover{border-color:#999}.fl-color-picker-ui .iris-picker .iris-square-value:focus .iris-square-handle{box-shadow:0 0 2px rgba(0,0,0,.75);opacity:.8}.fl-color-picker-ui .iris-picker .iris-square-handle:hover::after{border-color:#fff}.fl-color-picker-ui .iris-picker .iris-square-handle::after{position:absolute;bottom:-4px;right:-4px;left:-4px;top:-4px;border:3px solid #f9f9f9;border-color:rgba(255,255,255,.8);border-radius:50%;content:" "}.fl-color-picker-ui .iris-picker .iris-square-value{width:8px;height:8px;position:absolute}.iris-ie-lt9 .iris-square-value,.iris-mozilla .iris-square-value{width:1px;height:1px}.fl-color-picker-wrapper{position:relative;width:48px;height:32px}.fl-color-picker{box-shadow:0 2px 4px 0 rgba(0,0,0,.12);background:#fff;border-radius:4px;width:120px;height:36px;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row}.fl-color-picker-color{-ms-flex:1 1 100%;flex:1 1 100%;box-sizing:border-box!important;position:relative;border-radius:4px;background-color:transparent;cursor:pointer;border:2px solid transparent;border-right:2px solid rgba(0,0,0,.1);padding:0;-ms-flex-pack:center;justify-content:center;display:-ms-flexbox;display:flex}.fl-color-picker-clear:hover,.fl-color-picker-color:hover{background:0 0;border:2px solid transparent}.fl-color-picker-clear:focus,.fl-color-picker-color.fl-color-picker-empty:focus,.fl-color-picker-color:focus{outline:0;top:0;border:2px solid #00a0d2;background:0 0}.fl-color-picker.fl-color-picker-has-reset .fl-color-picker-color:not(.fl-color-picker-empty){border-top-right-radius:0;border-bottom-right-radius:0}.fl-color-picker-icon{display:none;margin:auto}.fl-color-picker-color.fl-color-picker-empty{border-color:transparent}.fl-color-picker-color.fl-color-picker-empty svg.fl-color-picker-icon{display:block}.fl-color-picker-clear{box-sizing:border-box;position:relative;display:-ms-flexbox;display:flex;-ms-flex:0 0 36px;flex:0 0 36px;-ms-flex-pack:center;justify-content:center;padding:0;border:2px solid transparent;border-top-right-radius:4px;border-bottom-right-radius:4px;background-color:#fff;cursor:pointer}.fl-color-picker-color.fl-color-picker-empty+.fl-color-picker-clear{display:none}.fl-color-picker-ui{display:inline-block;font-family:Helvetica,Verdana,sans-serif;z-index:999999;position:fixed;overflow:hidden;padding-bottom:45px;border:1px solid rgba(0,0,0,.1);color:#999;background-color:#FAFAFA;border-radius:3px;box-shadow:0 9px 20px rgba(0,0,0,.17);transition:opacity .2s,visibility .2s;visibility:hidden;opacity:0;-webkit-transform:translate3d(0,0,0)}.fl-color-picker-ui.fl-color-picker-active{visibility:visible;opacity:1}.fl-color-picker-ui .fl-color-picker-input,.fl-color-picker-ui .fl-color-picker-input:focus{width:100%;height:30px;border:none!important;font-size:14px!important;padding:0 8px;vertical-align:middle;color:#656c6e;background-color:#fff;border-radius:0;box-shadow:none}.fl-color-picker-ui .iris-square-value{transition:none}.fl-color-picker-preset-add{position:absolute;top:8px;right:8px;width:14px;height:14px;background-color:#656c6e;border-radius:50%;cursor:pointer;transition:all .2s}.fl-color-picker-preset-add:hover{background-color:#333}.fl-color-picker-preset-add:after,.fl-color-picker-preset-add:before{content:'';display:block;position:relative;background-color:#fff}.fl-color-picker-preset-add:before{top:6px;left:3px;width:8px;height:2px}.fl-color-picker-preset-add:after{left:6px;top:1px;width:2px;height:8px}.fl-color-picker-presets{position:absolute;left:0;bottom:0;width:100%;z-index:15;overflow:auto;border-top:1px solid rgba(0,0,0,.1);background-color:#FAFAFA}.fl-color-picker-presets-list .fl-color-picker-preset:hover,.fl-color-picker-presets-toggle:hover{background-color:#EDEDED}.fl-color-picker-presets-toggle{position:relative;overflow:hidden;width:100%;height:35px;text-align:center;line-height:35px;font-size:12px;font-weight:700;cursor:pointer;transition:all .1s}.fl-color-picker-presets-close-label,.fl-color-picker-presets-open-label{position:absolute;top:50%;left:50%;visibility:hidden;color:#999;transition:all .5s;transform:translate(-50%,-50%);opacity:0;width:100%}.fl-color-picker-presets-close-label.fl-color-picker-active,.fl-color-picker-presets-open-label.fl-color-picker-active{color:#656c6e;visibility:visible;opacity:1}.fl-color-picker-presets-list{width:100%;list-style:none;margin:0;padding:0;overflow:auto}.fl-color-picker-presets-list .fl-color-picker-no-preset,.fl-color-picker-presets-list .fl-color-picker-preset{position:relative;padding:5px;font-size:12px;border-top:1px solid rgba(0,0,0,.1);transition:all .1s}.fl-color-picker-presets-list .fl-color-picker-no-preset{padding:18px 5px;text-align:center}.fl-color-picker-presets-list .fl-color-picker-preset-color{display:inline-block;width:40px;height:20px;margin-right:3px;vertical-align:middle;border:1px solid rgba(0,0,0,.1);border-radius:2px;cursor:pointer}.fl-color-picker-presets-list .fl-color-picker-preset-label{vertical-align:middle;color:#333;cursor:pointer}.fl-color-picker-presets-list .fl-color-picker-preset-remove{position:absolute;top:50%;cursor:pointer;transform:translateY(-50%)}.fl-color-picker-clear .fl-color-picker-icon-remove{right:auto;top:auto;margin:auto}.fl-color-picker-presets-list .fl-color-picker-preset-remove{right:5px}.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:after,.fl-color-picker-presets-list .fl-color-picker-preset-remove:hover:before{background-color:#333}.fl-color-picker-added{position:absolute;width:100%;top:0;left:0;right:0;bottom:35px;z-index:10;color:#fff;text-align:center;background-color:rgba(0,0,0,.8)}.fl-color-picker-added-text{position:absolute;top:50%;left:50%;width:80%;font-size:14px;color:#fff!important;transform:translate(-50%,-50%)}.fl-color-picker-icon-check{position:relative;width:50px;height:50px;margin:5px auto}.fl-color-picker-icon-check:before{content:'';display:block;position:relative;width:15px;height:30px;margin-left:14px;border:7px solid #fff;border-left:none;border-top:none;transform:rotate(45deg)}.fl-color-picker-icon-arrow-down,.fl-color-picker-icon-arrow-up{display:inline-block;position:relative;width:10px;height:10px;margin-left:5px}.fl-color-picker-icon-arrow-down:before,.fl-color-picker-icon-arrow-up:before{content:'';display:block;position:relative;width:6px;height:6px;border:2px solid #999;border-left:none;border-top:none;transform:rotate(45deg)}.fl-color-picker-icon-arrow-up{top:2px;transform:rotate(180deg)}.fl-color-picker-icon-remove{width:15px;height:15px}.fl-color-picker-icon-remove:after,.fl-color-picker-icon-remove:before{content:'';display:block;position:relative;background-color:#6f7881}.fl-color-picker-icon-remove:before{left:6px;width:2px;height:10px;margin-top:3px;transform:rotate(-45deg)}.fl-color-picker-icon-remove:after{left:6px;width:2px;height:10px;margin-top:-10px;transform:rotate(45deg)}.fl-alpha-wrap{position:absolute;width:35px;height:215px;padding:0 5px;right:4px;border-top:none}.fl-alpha-slider{height:190px;position:absolute;top:12px;width:28px}.fl-alpha-slider .ui-slider-handle{background:rgba(0,0,0,0);border-color:#aaa;border-radius:4px;border-style:solid;border-width:4px;box-shadow:0 1px 2px rgba(0,0,0,.2);-moz-box-shadow:0 1px 2px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.2);cursor:ns-resize;height:12px;left:0;opacity:.9;position:absolute;right:0;width:30px;z-index:14}.fl-alpha-slider .ui-slider-handle:before{content:" ";position:absolute;left:-2px;right:-2px;top:-3px;bottom:-3px;border:2px solid #fff;border-radius:3px}.fl-alpha-slider-offset{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAASCAYAAAAe/ZHXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NkNEQUQ0ODM4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NkNEQUQ0ODQ4RUE0MTFFNEExOEJFN0E5M0VFOTg0QUQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2Q0RBRDQ4MThFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2Q0RBRDQ4MjhFQTQxMUU0QTE4QkU3QTkzRUU5ODRBRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/r/N8AAAWYSURBVHjarFvvR3VBEN45JZGIPkREHyIiIhJJf3qUSERE9CGiDxERkcg9z9u92uucvTszz5z7xnHPj93Z2d359cxscn5+jpTS+EoiMr3/+51cZ2dn4+e29i2/u7y8RKf/pO3vc+o+n5ycoNK31+f6+jrfZ37yuG2mf3R01H3fa5N/b29vU6dP5qft0G4PDg5MGuPr/v4+jz1t27mfvN/b21P75+fHx8eZfiV/Ozs7rUJnSu/5+RlFv+m6ZJpbW1s1PnrvXl9fZ/qX89zY2LB4mfy+v7/nsdV1XltbK/dr5vnz87OcV5bJabuVlRVLBifjfX9/l/xkGtM+S0tLNXnu0szfU/P3IMn/k0678h6ddqjQFGccVL6hoCsVfsq+NZ5QtCv5rfFS41sq37W+UPhMyhxEWTetvce3NR8oewqD39qalXuGAK/WPltjajIC4x2c9Ye1f43SGcqGwRBeTZjhMNntL4pCWZMQYhE05RVl02EovRgC4RkCbUNSQAGhGB/GsKG4h6FQoigDa2i8fRBy3uLMXYIG3Vr3aZvRaCRdBYlYIMZywhBGCVhgzzOlgRuUSOvC0GMEWxOM/+EtQFh1OIIXtfwg1tRaayGjg5px0jyZKEaTle3e+AsLCygVRAh3FlEgKbReE3oYGj9EgIR00QiEgKw3ZBQbRGjBeAMtDETQmHiKDsezJNLgCTFGItZXlAgCSiQggblP+9c8SDI0lXWlFv5g3K63KZ51FOcZzthQ3LomoNHwJmKIQISI3vqzSpwIQ8liSjGMFQjDpoVgaQ6cWgvLhOC7qiAwiHrWbEg4JMSmeUrBuHoYwioOQNXmhmAcrs096s1gJCGi3hSEVU8DQxYElYHhKwUUGAa+NqOBMsSSAQJuhQhCAH4vxozExsxiihPuaIrjCVYKWlYEsjSM52G8Kxxryngl5j0j+EyGTIiED4s1Itm0ZGWxMFCLJaBAcEI6OBkmFgNBoc8Cait2ZnENE/6wQN8LJSJeSMNAjKVm+LUMAIt3PR5AQgIGp1Z5zxhE8PtXUYReYeXi4mKmOPNXBMzt2tPT07LIUtJqr66uusXEbkFnWiQ6Pj72ikrtzc1NKopuvbbj58PDwxqNHp27u7tuYWumUDV+v7+/Xyu6pc59+/DwUCsC9ujt7u6qRbt8//T01C3elbyN70fb29uZ/1FSincvLy/lPGb42tzc9IqJeHt7q61Pr2C6vr7u7tfHx8fMPhV0sLq6WhZtU0n36+uru8elPE7aLi8v1wqJPXn++fmZKYgX8ozFxcXJb0NaQTHClZT8+gBjsYdaFc+zWcUkGTCWENY66ta92oSVzo3WI6IZKGtukeyfBLFKBNAj6bUOBgaoe9wE4n04IBNkLMoC7+Skj630ZlTJMYdyMsU2T8AwpzALkVFilZgJcT2l9PCWDDSAMBSjVlJgZNk0lE1AIby0qCiCnBQNj6aBGQslZIZJ5hB6D/AzQHto5Z9Nk8tARdN4q2ExBnsyIJ311EymShyjan2rKk0zh1Ay1oQVWAZQRnkUA8RFw7TahjBnmNgMVMQrsCGZJezRtGlU0cUZ1zuaxGZPpbhApM+ZpFQqQ6xadoMtBrEKpBVo4GRXvNSxpaRixKiR+TChCYhsDwZkfFj8IkErjAHejcUI0XQrgwehhNSMHAz21E0wZ23FcCAmj8Sd/PXy2xLYLAuwRw4IMsqjFaWYOpMEhDySAPFCWyFkgAHrEcA+BNeJ4UE8HCzJPpCrerUmQIx1pWJkjqxJD8EikUo2c5aI8ZYgsAkM4WQtnHd0ns0ORgVTBghy5ISy928SGsbTMqYg523RUY8oNYG4FIYiyRyZCnFCJC87IoRAIMVOqQ7BKexxCS2hYVl9JhvlpYjnAe4MhmRPMWhhvLfXINaI9WKM0Zu0+SfAAFLE1EgfVSv7AAAAAElFTkSuQmCC) center;box-shadow:0 0 5px rgba(0,0,0,.4) inset;-moz-box-shadow:0 0 5px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 5px rgba(0,0,0,.4) inset;width:200px;height:22px;transform:rotate(-90deg);bottom:48%;left:-80px;position:absolute}.fl-alpha-text{width:30px;font-size:12px;text-align:center;color:#999;position:absolute;bottom:-5px}.fl-lightbox-wrap.fl-icon-selector{z-index:1000111}.fl-icon-selector .fl-lightbox{height:100%}.fl-icons-filter{height:auto!important;margin:0!important;position:absolute!important;right:0;top:0;padding:10px 16px;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row}.fl-icons-filter select{vertical-align:middle;width:195px;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;color:#000;border:2px solid #e4e7ea!important;border-right:none!important;margin:0;padding:2px 10px;background:url(../img/svg/select-arrow-down-alt2.svg) center right 10px no-repeat #fff!important;-ms-flex:1 1 195px;flex:1 1 195px;border-radius:0}.fl-icons-filter input[type=text]{line-height:18px;vertical-align:middle;width:160px;-ms-flex:1 1 160px;flex:1 1 160px;border:2px solid #e4e7ea!important;border-radius:0!important;padding:2px 10px!important}.fl-icons-filter input[type=text]:focus,.fl-icons-filter select:focus{border:2px solid #00A0D2!important}.fl-icons-list{bottom:52px;left:0;overflow:auto;padding:20px;position:absolute;right:0;top:48px}.fl-icons-list::-webkit-scrollbar{background-color:#ccc;-webkit-appearance:none;width:10px}.fl-icons-list::-webkit-scrollbar-thumb{background-color:#666;border:1px solid #ccc}.fl-icons-section{text-align:center}.fl-icons-section h2{border-bottom:1px solid #dfdfdf;color:#333!important;font-family:Helvetica,Verdana,sans-serif!important;font-size:16px!important;font-weight:700!important;margin:0 0 20px!important;padding:0 0 10px!important;text-align:left}.fl-icons-list i,.fl-icons-list i:before{cursor:pointer;display:inline-block;font-size:40px;height:100px;line-height:100px;width:100px;background:0 0}.fl-icons-list i:hover{background:#fff;box-shadow:0 10px 20px rgba(0,0,0,.15);border-radius:4px}.fl-icon-selector-footer{bottom:0;left:0;position:absolute;right:0}.fl-lightbox-mask,.fl-lightbox-wrap{bottom:0;left:0;position:fixed;right:0;z-index:100010}@keyframes fl-lightbox-zoom{from{transform:scale(.4)}to{transform:scale(1)}}.fl-lightbox-wrap{display:none;overflow:auto;padding:4px;top:46px;-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0);pointer-events:none}.fl-builder-draggable-is-dragging .fl-lightbox-wrap,.fl-builder-resizable-is-resizing .fl-lightbox-wrap,.fl-lightbox,.fl-lightbox-mask{pointer-events:auto}.fl-lightbox-mask{background:#000;opacity:.7;filter:alpha(opacity=70);top:0}.fl-lightbox{background:#F5F7F9;border-radius:4px;box-shadow:rgba(0,0,0,1) 0 4px 30px;-moz-box-shadow:rgba(0,0,0,1) 0 4px 30px;-webkit-box-shadow:rgba(0,0,0,1) 0 4px 30px;position:relative;display:-ms-flexbox;display:flex;z-index:100011;transform-origin:center;animation-name:fl-lightbox-zoom}.fl-lightbox.fl-lightbox-prevent-animation{animation-duration:0s;-moz-animation-duration:0s;-webkit-animation-duration:0s;-o-animation-duration:0s}.fl-lightbox :not(i){color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:13px;line-height:16px;text-decoration:none;text-transform:none}.fl-lightbox *,.fl-lightbox :after,.fl-lightbox :before{box-sizing:content-box}.fl-lightbox .fl-nanoscroller-pane{bottom:4px;right:4px;width:8px}.fl-lightbox .fa{font-family:FontAwesome}.fl-lightbox .dashicons{font-family:dashicons}.fl-lightbox.ui-draggable{box-shadow:rgba(0,0,0,.2) 0 7px 30px;-moz-box-shadow:rgba(0,0,0,.2) 0 7px 30px;-webkit-box-shadow:rgba(0,0,0,.2) 0 7px 30px}.fl-lightbox-resizable{height:500px;width:380px}@media (max-width:500px){.fl-lightbox-resizable{left:0!important;right:0!important;top:0!important;height:100%!important;width:100%!important}.fl-lightbox-resizable .ui-resizable-handle{display:none!important}.fl-lightbox.ui-draggable .fl-lightbox-header{cursor:default!important}.fl-lightbox-controls{display:none}}.fl-lightbox-width-full{left:0!important;right:0!important;top:0!important;height:100%!important;width:100%!important}.fl-lightbox-width-full .fl-lightbox-header{cursor:inherit!important}.fl-lightbox-controls{position:absolute;right:10px;top:10px;z-index:5}.fl-lightbox-controls .fa{color:#bdbdbd;font-size:14px;padding:5px}.fl-lightbox-controls .fa:hover{color:#aaa;cursor:pointer}.fl-lightbox-header-wrap{background:#fff;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:2px solid #eaeaea}.fl-lightbox-header{position:relative}.fl-lightbox-header h1{color:#333!important;font-size:20px!important;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif!important;font-weight:600!important;margin:0!important;padding:14px 34px 15px 28px!important;text-align:left!important;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;line-height:1.1}.fl-lightbox.ui-draggable .fl-lightbox-header{cursor:move}.fl-lightbox-header h1 .fl-builder-badge{margin-left:10px}.fl-lightbox-content,.fl-lightbox-content-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex:1 100%;flex:1 100%;height:100%;max-width:100%}.fl-lightbox-footer{box-sizing:border-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:end;justify-content:flex-end;-ms-flex:0 0;flex:0 0;-ms-flex-preferred-size:44px;flex-basis:44px;padding:4px;text-align:right}.fl-lightbox-footer .fl-builder-button{height:36px;margin-left:5px!important;-ms-flex:0 0 0%;flex:0 0 0%;-ms-flex-pack:center;justify-content:center}.fl-lightbox-width-slim .fl-lightbox-footer{-ms-flex-pack:stretch;justify-content:stretch;padding:4px 5px}.fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button{-ms-flex:1 1 100%;flex:1 1 100%;display:block;text-align:center}.fl-lightbox-width-slim .fl-lightbox-footer .fl-builder-button:first-child{margin-left:0!important}.fl-lightbox table,.fl-lightbox td,.fl-lightbox th,.fl-lightbox tr{border:none}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel,.fl-builder-ui-skin--dark .fl-builder--preview-actions,.fl-builder-ui-skin--dark .fl-builder--search-results-panel,.fl-builder-ui-skin--dark .fl-builder-panel,.fl-builder-ui-skin--dark .fl-lightbox,body.fl-builder-ui-skin--dark .fl-builder-bar .fl-builder-bar-content{background:#23282d;color:#b4b9be;border-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder--panel-header{background:#1d2227;color:#b4b9be;border-bottom-color:#1d1d1d;border-top-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder-panel.fl-builder-ui-pinned .fl-builder--panel-header{border-top-color:#1d2227}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel:before{border-bottom-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder--panel-arrow polygon{fill:#1d1d1d}.fl-builder-ui-skin--dark .fl-builder-panel-search .fl-builder-panel-search-input{background:#1e2228}.fl-builder-ui-skin--dark .fl-responsive-preview-content{background:#131619}.fl-builder-ui-skin--dark .fl-form-table th{background:#23282d!important;color:#7d8690}.fl-builder-ui-skin--dark .fl-builder--preview-actions .device-icons,.fl-builder-ui-skin--dark .fl-builder-button{background:#383f46}.fl-builder-ui-skin--dark .fl-builder-button:focus{background:#131a22}.fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-primary{color:#fff!important;fill:#fff!important;background:#00A0D2}.fl-builder-ui-skin--dark .fl-builder-button.fl-builder-button-silent:focus{border:2px solid #00a0d2!important}.fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover,.fl-builder-ui-skin--dark .fl-builder-content-panel-button{color:#00A0D2!important}.fl-builder-ui-skin--dark .fl-builder--menu>a:hover,.fl-builder-ui-skin--dark .fl-builder--menu>button:hover{background:#101215!important}.fl-builder-ui-skin--dark .fl-builder--menu>a:focus,.fl-builder-ui-skin--dark .fl-builder--menu>button:focus{background:#101215!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder-bar-title{border-color:#101215}.fl-builder-ui-skin--dark .fl-builder-bar-title:hover{background-color:#181b1f}.fl-builder-simple.fl-builder-ui-skin--dark .fl-builder-bar-title:hover{background-color:transparent}.fl-builder-ui-skin--dark .fl-builder-layout-title{color:#c6cdd6}.fl-builder-ui-skin--dark .fl-builder-bar-title-caret i,.fl-builder-ui-skin--dark .fl-builder-layout-pretitle,.fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title{color:#7d8690}.fl-builder-ui-skin--dark button.fl-builder-button.fl-builder-bar-title-caret:focus{background-color:#101215!important}.fl-builder-ui-skin--dark .fl-builder--search:before{color:rgba(162,173,184,.73)}.fl-builder-ui-skin--dark .fl-builder--search input:focus::-webkit-input-placeholder{color:rgba(162,173,184,.73)!important}.fl-builder-ui-skin--dark .fl-builder--search .search-clear{color:rgba(162,173,184,.5);background-color:#e4e4e4;background:linear-gradient(to left,#383f46,#383f46 75%,rgba(56,63,70,0))}.fl-builder-ui-skin--dark .fl-builder--menu hr{background-color:#23282d!important;border:none}.fl-builder-ui-skin--dark .fl-builder--tabs{border-color:#383f46!important}.fl-builder-ui-skin--dark .fl-builder--tabs>.is-showing,.fl-builder-ui-skin--dark .fl-builder-settings-tabs a.fl-active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-more.fl-contains-active{color:#fff!important;fill:#fff!important;background:#383f46}.fl-builder-ui-skin--dark .fl-builder--tabs>:focus{background-color:#101215!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder--tabs>.is-showing:focus{color:#00a0d2!important}.fl-builder-ui-skin--dark .fl-builder--menu-item:hover{background:#383f46;color:#a8b3bf}.fl-builder-ui-skin--dark .fl-builder--menu * .fl-builder--menu-item-accessory,.fl-builder-ui-skin--dark .fl-builder-blocks-section-group-name{color:#7d8690}.fl-builder-ui-skin--dark .fl-builder--category-select{background:#171b1f}.fl-builder-ui-skin--dark .fl-builder--selector-display{color:#c6cdd6;background:url(../img/svg/select-arrow-down-alt2-light.svg) center right 10px no-repeat #171b1f!important}.fl-builder-ui-skin--dark .fl-builder--selector-display-label,.fl-builder-ui-skin--dark .fl-builder-panel-search-input input{border-color:#5b656f;color:#b5becb}.fl-builder-ui-skin--dark .fl-builder-panel-search-input input{background:#171b1f!important}.fl-builder-ui-skin--dark .fl-builder--selector-display-label:focus,.fl-builder-ui-skin--dark .fl-builder-panel-search-input input:focus{border-color:#00a0d2}.fl-builder-ui-skin--dark .fl-builder--group-label{color:#171b1f!important;background:#5b656f}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu{border-color:#101215!important;color:#7c858e;background-color:#101215}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu:before{border-bottom-color:#101215}.fl-builder-ui-skin--dark .fl-builder--menu>a,.fl-builder-ui-skin--dark .fl-builder--menu>button,.fl-builder-ui-skin--dark .fl-builder--menu>span{color:#a1adb9}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:hover{background:#23282d!important;color:#a1adb9}.fl-builder-ui-skin--dark .fl-builder--category-select .fl-builder--selector-menu .fl-builder--menu-item:focus{background:#23282d!important;color:#00a0d2!important}.fl-builder-ui-skin--dark .fl-builder-panel-drag-handle{fill:#5b656f}.fl-builder-ui-skin--dark .fl-builder--template-collection-section-name,.fl-builder-ui-skin--dark .fl-builder--user-templates-section-name,.fl-builder-ui-skin--dark .fl-builder-blocks-section .fl-builder-blocks-section-title{color:#969ea7;background:#171b1f}.fl-builder-ui-skin--dark .fl-builder-blocks-section-content .fl-builder-block,.fl-builder-ui-skin--dark .fl-user-template{color:#b8c2ce}.fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-content,.fl-builder-ui-skin--dark .fl-user-template:hover{background:#171b1f;color:#fff}.fl-builder-ui-skin--dark .fl-builder-block:hover i,.fl-builder-ui-skin--dark .fl-user-template:hover i{color:#6d7782!important}.fl-builder-ui-skin--dark .fl-builder-block:hover a:hover i,.fl-builder-ui-skin--dark .fl-user-template:hover a:hover i{color:#9eacbb!important}.fl-builder-ui-skin--dark .fl-builder-block .fl-builder-block-icon{fill:#b5becb}.fl-builder-ui-skin--dark .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col,.fl-builder-ui-skin--dark .fl-builder-block:hover .fl-builder-block-visual.fl-cols-visual .fl-cols-visual-col{background:#7d8690}.fl-builder-ui-skin--dark .fl-builder-blocks-section,.fl-builder-ui-skin--dark .fl-builder-settings-section{border-top:2px solid #171b1f}.fl-builder-ui-skin--dark .fl-user-templates{border-color:#101215}.fl-builder-ui-skin--dark .fl-builder--template-thumbnail{border-color:#393f44}.fl-builder-ui-skin--dark .fl-builder--menu a.fl-template-collection{color:#a8b3bf}.fl-builder-ui-skin--dark .fl-lightbox-header-wrap{background:#1d2227;border-bottom-color:#131a22}.fl-builder-ui-skin--dark .fl-lightbox .fl-lightbox-header h1{color:#fff!important}.fl-builder-ui-skin--dark .fl-form-table th label{color:#a8b3bf!important}.fl-builder-ui-skin--dark .fl-builder-settings-tabs{border-color:#383f46!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields h3.fl-builder-settings-title{background:#1b2025}.fl-builder-ui-skin--dark h3.fl-builder-settings-title .fl-builder-settings-title-text-wrap{color:#a8b3bf;background-color:#1b2025}.fl-builder-ui-skin--dark .fl-lightbox :not(i){color:#7d8690!important}.fl-builder-ui-skin--dark .fl-builder-button{color:#c6cdd6!important;fill:#c6cdd6!important}.fl-builder-ui-skin--dark .fl-builder-content-panel--button:hover,.fl-builder-ui-skin--dark .fl-builder-content-panel-button{fill:#00A0D2!important}.fl-builder-ui-skin--dark .fl-lightbox .fl-builder-button.fl-builder-button-primary{color:#fff!important}.fl-builder-ui-skin--dark .fl-color-picker{background:#131a22}.fl-color-picker-color.fl-color-picker-empty .fl-color-picker-icon{fill:#6f7881}.fl-builder-ui-skin--dark .fl-color-picker-clear{background-color:#191d21}.fl-builder-ui-skin--dark .fl-color-picker-clear:hover{background-color:#373f46}.fl-builder-ui-skin--dark span.fl-builder-block-no-node-templates:hover{background:#1d2025}.fl-builder-ui-skin--dark .fl-builder-settings-tab-description{background:#1d2227}.fl-builder-ui-skin--dark .fl-builder-panel-search button svg .filled-shape{fill:#b5becb}.fl-builder-ui-skin--dark .fl-builder-custom-field,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text],.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url],.fl-builder-ui-skin--dark .fl-builder-settings-fields select,.fl-builder-ui-skin--dark .fl-builder-settings-fields textarea{background-color:#131a22!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=email]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=file]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=number]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=password]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=search]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=tel]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=text]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields input[type=url]:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields select:focus,.fl-builder-ui-skin--dark .fl-builder-settings-fields textarea:focus{border-color:#00a0d2!important;color:#fff!important}.fl-builder-ui-skin--dark .fl-builder-settings-fields select{background-image:url(../img/svg/select-arrow-down-alt2-light.svg)!important}.fl-builder-ui-skin--dark .fl-builder-custom-field select,.fl-builder-ui-skin--dark .fl-photo-field select{border-color:#7d8690!important}.fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle{color:#6b747d}.fl-builder-ui-skin--dark .fl-builder--main-menu-panel-view-title,.fl-builder-ui-skin--dark .fl-field i.fl-field-responsive-toggle:hover{color:#a8b3bf}.fl-builder-ui-skin--dark .fl-builder--saving-indicator{color:#858f99}.fl-builder-ui-skin--dark .fl-icons-list i:hover{background-color:#16191d;color:#fff}.fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:after,.fl-builder-ui-skin--dark .fl-color-picker-clear .fl-color-picker-icon-remove:before{background:#6f7881}.fl-builder-ui-skin--dark .fl-builder--user-templates-section-content{border-color:#1d1d1d}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button{background:0 0;border-right-color:#101215!important}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select.fl-builder-button:hover{background:#181b1f}.fl-builder-ui-skin--dark .fl-theme-builder-preview-select .fl-theme-builder-preview-select-title span{color:#c6cdd6}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu{background:#131a22;border-color:#353c43 #131a22 #131a22}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu:before{border-bottom-color:#353c43}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:focus,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:hover{background:#383f46}.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a.fl-active,.fl-builder-ui-skin--dark .fl-builder-settings-tabs-overflow-menu>a:hover.fl-active{color:#fff!important;background:#383f46}.fl-builder-ui-skin--dark ul.as-selections{background-color:#121a23}.fl-builder-ui-skin--dark .fl-custom-query .fl-builder-settings-section{border-top:2px solid #1b2026!important}.fl-builder-ui-skin--dark .pp-preview-button{background:#23282d;border:2px solid #101215}.fl-builder-ui-skin--dark .pp-preview-button .pp-preview-button-wrap .fa{color:#b8bfc7}
css/fl-icon-selector.css CHANGED
@@ -16,7 +16,7 @@
16
  }
17
  .fl-icons-filter select {
18
  vertical-align: middle;
19
- width: 160px;
20
  -webkit-appearance: none;
21
  -moz-appearance: none;
22
  appearance: none;
@@ -27,7 +27,7 @@
27
  margin: 0;
28
  padding: 2px 10px;
29
  background: white url("../img/svg/select-arrow-down-alt2.svg") no-repeat center right 10px !important;
30
- flex: 1 1 160px;
31
  border-radius:0px;
32
  }
33
  .fl-icons-filter input[type="text"] {
16
  }
17
  .fl-icons-filter select {
18
  vertical-align: middle;
19
+ width: 195px;
20
  -webkit-appearance: none;
21
  -moz-appearance: none;
22
  appearance: none;
27
  margin: 0;
28
  padding: 2px 10px;
29
  background: white url("../img/svg/select-arrow-down-alt2.svg") no-repeat center right 10px !important;
30
+ flex: 1 1 195px;
31
  border-radius:0px;
32
  }
33
  .fl-icons-filter input[type="text"] {
fl-builder.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-uri
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
- * Version: 2.0.6.4
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-author
9
  * Copyright: (c) 2014 Beaver Builder
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-uri
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
+ * Version: 2.1.1.2
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-author
9
  * Copyright: (c) 2014 Beaver Builder
img/screenshot-getting-started.jpg DELETED
Binary file
img/screenshot-getting-started.png ADDED
Binary file
img/svg/bell-active.svg ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <svg className={classes} width="20px" height="19px" viewBox="0 0 20 19" version="1.1">
2
+ <g transform="translate(-319.000000, -53.000000)">
3
+ <path d="M327,72 C328.04,72 328.882353,71.1945 328.882353,70.2 L325.117647,70.2 C325.117647,71.1945 325.96,72 327,72 Z M332.976668,66.0590357 L332.976668,61.65 C332.976668,58.8825 331.108235,56.574 328.411765,55.962 L328.411765,55.0911483 C328.411765,54.3441483 327.781176,54 327,54 C326.218824,54 325.588235,54.3441483 325.588235,55.0911483 L325.588235,55.962 C322.891765,56.574 320.98235,58.8825 320.98235,61.65 L320.98235,66.0590357 L319,67.0215302 L319,68.9750312 L335,68.9750312 L335,67.0215302 L332.976668,66.0590357 Z M331.056143,67.0382342 L322.940315,67.0382342 L322.940315,61.65 C322.940315,59.4135 324.661176,57.6 327,57.6 C329.338824,57.6 331.056143,59.4135 331.056143,61.65 L331.056143,67.0382342 Z"></path>
4
+ <circle id="bell-active-dot" fill="#E10000" cx="336.5" cy="55.5" r="2.5"></circle>
5
+ </g>
6
+ </svg>
img/svg/bell.svg ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <svg width="20px" height="19px" viewBox="0 0 16 18">
2
+ <g transform="translate(-253.000000, -54.000000)">
3
+ <path d="M261,72 C262.04,72 262.882353,71.1945 262.882353,70.2 L259.117647,70.2 C259.117647,71.1945 259.96,72 261,72 Z M266.976668,66.0590357 L266.976668,61.65 C266.976668,58.8825 265.108235,56.574 262.411765,55.962 L262.411765,55.0911483 C262.411765,54.3441483 261.781176,54 261,54 C260.218824,54 259.588235,54.3441483 259.588235,55.0911483 L259.588235,55.962 C256.891765,56.574 254.98235,58.8825 254.98235,61.65 L254.98235,66.0590357 L253,67.0215302 L253,68.9750312 L269,68.9750312 L269,67.0215302 L266.976668,66.0590357 Z M265.056143,67.0382342 L256.940315,67.0382342 L256.940315,61.65 C256.940315,59.4135 258.661176,57.6 261,57.6 C263.338824,57.6 265.056143,59.4135 265.056143,61.65 L265.056143,67.0382342 Z"></path>
4
+ </g>
5
+ </svg>
includes/admin-posts.php CHANGED
@@ -1,11 +1,17 @@
1
  <div class="fl-builder-admin">
 
2
  <div class="fl-builder-admin-tabs">
3
  <a href="javascript:void(0);" onclick="return false;" class="fl-enable-editor<?php if ( ! $enabled ) { echo ' fl-active';} ?>"><?php _e( 'Text Editor', 'fl-builder' ); ?></a>
4
  <a href="javascript:void(0);" onclick="return false;" class="fl-enable-builder<?php if ( $enabled ) { echo ' fl-active';} ?>"><?php echo FLBuilderModel::get_branding(); ?></a>
5
  </div>
 
6
  <div class="fl-builder-admin-ui">
7
  <h3><?php printf( _x( '%1$s is currently active for this %2$s.', 'The first %s stands for custom branded "Page Builder" name. The second %s stands for the post type name.', 'fl-builder' ), FLBuilderModel::get_branding(), $post_type_name ); ?></h3>
 
8
  <a href="<?php echo FLBuilderModel::get_edit_url(); ?>" class="fl-launch-builder button button-primary button-large"><?php printf( _x( 'Launch %s', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ); ?></a>
 
 
 
9
  </div>
10
  <div class="fl-builder-loading"></div>
11
  </div>
1
  <div class="fl-builder-admin">
2
+ <?php if ( FLBuilderUserAccess::current_user_can( 'builder_access' ) ) : ?>
3
  <div class="fl-builder-admin-tabs">
4
  <a href="javascript:void(0);" onclick="return false;" class="fl-enable-editor<?php if ( ! $enabled ) { echo ' fl-active';} ?>"><?php _e( 'Text Editor', 'fl-builder' ); ?></a>
5
  <a href="javascript:void(0);" onclick="return false;" class="fl-enable-builder<?php if ( $enabled ) { echo ' fl-active';} ?>"><?php echo FLBuilderModel::get_branding(); ?></a>
6
  </div>
7
+ <?php endif; ?>
8
  <div class="fl-builder-admin-ui">
9
  <h3><?php printf( _x( '%1$s is currently active for this %2$s.', 'The first %s stands for custom branded "Page Builder" name. The second %s stands for the post type name.', 'fl-builder' ), FLBuilderModel::get_branding(), $post_type_name ); ?></h3>
10
+ <?php if ( FLBuilderUserAccess::current_user_can( 'builder_access' ) ) : ?>
11
  <a href="<?php echo FLBuilderModel::get_edit_url(); ?>" class="fl-launch-builder button button-primary button-large"><?php printf( _x( 'Launch %s', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ); ?></a>
12
+ <?php else : ?>
13
+ <a href="<?php echo get_permalink(); ?>" class="button button-large"><?php printf( _x( 'View %s', '%s stands the post type name.', 'fl-builder' ), $post_type_name ); ?></a>
14
+ <?php endif; ?>
15
  </div>
16
  <div class="fl-builder-loading"></div>
17
  </div>
includes/admin-settings-tools.php CHANGED
@@ -28,7 +28,7 @@
28
  <?php if ( ! $debug ) : ?>
29
  <p><?php _e( 'Enable debug mode to generate a unique support url.', 'fl-builder' ); ?></p>
30
  <?php else : ?>
31
- <p><?php _e( 'Copy this unique support URL and send it to Support as directed.', 'fl-builder' ); ?></p>
32
  <?php endif; ?>
33
  <?php if ( $debug ) :
34
  $url = add_query_arg( array(
@@ -45,6 +45,34 @@
45
  </p>
46
  </form>
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  <?php if ( is_network_admin() || ! self::multisite_support() ) : ?>
49
 
50
  <hr />
28
  <?php if ( ! $debug ) : ?>
29
  <p><?php _e( 'Enable debug mode to generate a unique support url.', 'fl-builder' ); ?></p>
30
  <?php else : ?>
31
+ <p><?php _e( 'Copy this unique URL and send it to support as directed.', 'fl-builder' ); ?></p>
32
  <?php endif; ?>
33
  <?php if ( $debug ) :
34
  $url = add_query_arg( array(
45
  </p>
46
  </form>
47
 
48
+ <?php
49
+ if ( FLBuilderUsage::show_settings() ) {
50
+ $usage = get_site_option( 'fl_builder_usage_enabled', false );
51
+
52
+ $endpoint = is_network_admin() ? 'settings.php?page=fl-builder-multisite-settings#tools' : 'options-general.php?page=fl-builder-settings#tools';
53
+ $url = wp_nonce_url( network_admin_url( $endpoint ), 'stats_enable' );
54
+ if ( '1' == $usage ) {
55
+ $text = __( 'Disable', 'fl-builder' );
56
+ $url = add_query_arg( array(
57
+ 'fl_usage' => 0,
58
+ ), $url );
59
+ } else {
60
+ $text = __( 'Enable', 'fl-builder' );
61
+ $url = add_query_arg( array(
62
+ 'fl_usage' => 1,
63
+ ), $url );
64
+ }
65
+ $btn = sprintf( '<a class="button button-primary" href="%s">%s</a>', $url, $text ); ?>
66
+ <hr />
67
+ <h3 class="fl-settings-form-header"><?php echo __( 'Send Usage Data', 'fl-builder' ) ?></h3>
68
+
69
+ <p><?php _e( 'If enabled we will send anonymous usage stats to help improve the plugin.', 'fl-builder' ); ?></p>
70
+
71
+ <p><?php echo $btn; ?></p>
72
+
73
+ <?php echo FLBuilderUsage::data_demo(); ?>
74
+ <?php } ?>
75
+
76
  <?php if ( is_network_admin() || ! self::multisite_support() ) : ?>
77
 
78
  <hr />
includes/admin-settings-welcome.php CHANGED
@@ -8,7 +8,7 @@ function fl_welcome_utm( $campaign ) {
8
  );
9
  }
10
 
11
- $blog_post_url = FLBuilderModel::get_store_url( 'beaver-builder-2-0-hoover', fl_welcome_utm( 'settings-welcome-blog-post' ) );
12
  $change_logs_url = FLBuilderModel::get_store_url( 'change-logs', fl_welcome_utm( 'settings-welcome-change-logs' ) );
13
  $upgrade_url = FLBuilderModel::get_upgrade_url( fl_welcome_utm( 'settings-welcome-upgrade' ) );
14
  $support_url = FLBuilderModel::get_store_url( 'beaver-builder-support', fl_welcome_utm( 'settings-welcome-support' ) );
@@ -58,7 +58,7 @@ $fb_url = 'https://www.facebook.com/groups/beaverbuilders/';
58
  </div>
59
 
60
  <div class="fl-welcome-col">
61
- <img class="fl-welcome-img" src="<?php echo FL_BUILDER_URL; ?>img/screenshot-getting-started.jpg" alt="">
62
  </div>
63
 
64
  </div>
@@ -69,16 +69,15 @@ $fb_url = 'https://www.facebook.com/groups/beaverbuilders/';
69
 
70
  <div class="fl-welcome-col">
71
 
72
- <h4><?php _e( 'What\'s New in Beaver Builder 2.0 Hoover', 'fl-builder' ); ?></h4>
73
 
74
- <p><?php _e( 'Were thrilled to announce Beaver Builder 2.0, Hoover. Beaver Builder 2.0 looks better, feels better, it\'s faster, and we\'re introducing new customization options and tons of workflow improvements.', 'fl-builder' ); ?></p>
75
 
76
  <ul>
77
- <li><?php _e( 'A sleek and modern visual refresh.', 'fl-builder' ); ?></li>
78
- <li><?php _e( 'A centralized main menu.', 'fl-builder' ); ?></li>
79
- <li><?php _e( 'Keyboard shortcuts.', 'fl-builder' ); ?></li>
80
- <li><?php _e( 'Major performance improvements.', 'fl-builder' ); ?></li>
81
- <li><?php _e( 'Customizable and dockable settings panels.', 'fl-builder' ); ?></li>
82
  </ul>
83
 
84
  <p><?php printf( __( 'There\'s a whole lot more, too! Read about everything else on our <a href="%1$s" target="_blank">update post</a> or <a href="%2$s" target="_blank">change logs</a>.', 'fl-builder' ), $blog_post_url, $change_logs_url ); ?></p>
8
  );
9
  }
10
 
11
+ $blog_post_url = FLBuilderModel::get_store_url( 'beaver-builder-2-1-redridge', fl_welcome_utm( 'settings-welcome-blog-post' ) );
12
  $change_logs_url = FLBuilderModel::get_store_url( 'change-logs', fl_welcome_utm( 'settings-welcome-change-logs' ) );
13
  $upgrade_url = FLBuilderModel::get_upgrade_url( fl_welcome_utm( 'settings-welcome-upgrade' ) );
14
  $support_url = FLBuilderModel::get_store_url( 'beaver-builder-support', fl_welcome_utm( 'settings-welcome-support' ) );
58
  </div>
59
 
60
  <div class="fl-welcome-col">
61
+ <img class="fl-welcome-img" src="<?php echo FL_BUILDER_URL; ?>img/screenshot-getting-started.png" alt="">
62
  </div>
63
 
64
  </div>
69
 
70
  <div class="fl-welcome-col">
71
 
72
+ <h4><?php printf( __( 'What\'s New in Beaver Builder %s', 'fl-builder' ), '2.1 "Redridge"' ); ?></h4>
73
 
74
+ <p><?php _e( 'We\'re thrilled to announce Beaver Builder 2.1 "Redridge". Beaver Builder 2.1 brings Gutenberg support and a major enhancement to the building experience with inline editing.', 'fl-builder' ); ?></p>
75
 
76
  <ul>
77
+ <li><?php _e( 'Keep up with news & updates in the notification center.', 'fl-builder' ); ?></li>
78
+ <li><?php _e( 'Edit text directly on-page with inline editing.', 'fl-builder' ); ?></li>
79
+ <li><?php _e( 'Initial support for Gutenberg blocks and transitioning between editors has been added.', 'fl-builder' ); ?></li>
80
+ <li><?php _e( 'Prevent clients from accessing Page Builder by user role.', 'fl-builder' ); ?></li>
 
81
  </ul>
82
 
83
  <p><?php printf( __( 'There\'s a whole lot more, too! Read about everything else on our <a href="%1$s" target="_blank">update post</a> or <a href="%2$s" target="_blank">change logs</a>.', 'fl-builder' ), $blog_post_url, $change_logs_url ); ?></p>
includes/column-css.php CHANGED
@@ -6,8 +6,8 @@
6
  .fl-node-<?php echo $col->node; ?> {
7
  color: #<?php echo $col->settings->text_color; ?>;
8
  }
9
- .fl-builder-content .fl-node-<?php echo $col->node; ?> *:not(input):not(textarea):not(select):not(a):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(.fl-heading-text):not(.fl-menu-mobile-toggle) {
10
- color: inherit;
11
  }
12
  <?php endif; ?>
13
 
6
  .fl-node-<?php echo $col->node; ?> {
7
  color: #<?php echo $col->settings->text_color; ?>;
8
  }
9
+ .fl-builder-content .fl-node-<?php echo $col->node; ?> *:not(input):not(textarea):not(select):not(a):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(.fl-menu-mobile-toggle) {
10
+ color: #<?php echo $col->settings->text_color; ?>;
11
  }
12
  <?php endif; ?>
13
 
includes/compatibility.php CHANGED
@@ -42,8 +42,7 @@ function fl_builder_wc_memberships_support() {
42
  // check if user has access to restricted content
43
  if ( ! current_user_can( 'wc_memberships_view_restricted_post_content', $post_id ) ) {
44
  $do_render = false;
45
- } // End if().
46
- elseif ( ! current_user_can( 'wc_memberships_view_delayed_post_content', $post_id ) ) {
47
  $do_render = false;
48
  }
49
  }
@@ -274,9 +273,57 @@ function fl_autoptimize_filter_noptimize_filter( $args ) {
274
  add_filter( 'autoptimize_filter_noptimize', 'fl_autoptimize_filter_noptimize_filter' );
275
 
276
  /**
277
- * Plugin Enjoy Instagram loads its js and css on all frontend pages breaking the builder.
278
- * @since 2.0.1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  */
 
 
 
 
 
 
 
 
 
 
280
  add_action( 'template_redirect', 'fix_aggiungi_script_instafeed_owl', 1000 );
281
  function fix_aggiungi_script_instafeed_owl() {
282
  if ( FLBuilderModel::is_builder_active() ) {
@@ -323,6 +370,11 @@ function fl_fix_nextgen_gallery() {
323
  define( 'NGG_DISABLE_RESOURCE_MANAGER', true );
324
  }
325
  }
 
 
 
 
 
326
  add_action( 'template_redirect', 'fl_fix_tasty_recipes' );
327
  function fl_fix_tasty_recipes() {
328
  if ( FLBuilderModel::is_builder_active() ) {
@@ -330,3 +382,53 @@ function fl_fix_tasty_recipes() {
330
  remove_action( 'media_buttons', array( 'Tasty_Recipes\Editor', 'action_media_buttons' ) );
331
  }
332
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  // check if user has access to restricted content
43
  if ( ! current_user_can( 'wc_memberships_view_restricted_post_content', $post_id ) ) {
44
  $do_render = false;
45
+ } elseif ( ! current_user_can( 'wc_memberships_view_delayed_post_content', $post_id ) ) {
 
46
  $do_render = false;
47
  }
48
  }
273
  add_filter( 'autoptimize_filter_noptimize', 'fl_autoptimize_filter_noptimize_filter' );
274
 
275
  /**
276
+ * Fixes an issue on search archives if one of the results contains same shortcode
277
+ * as is currently trying to render.
278
+ *
279
+ * @since 1.10.9
280
+ * @param bool $render Render shortcode.
281
+ * @param array $attrs Shortcode attributes.
282
+ * @param array $args Passed to FLBuilder::render_query
283
+ * @return bool
284
+ */
285
+ function fl_builder_insert_layout_render_search( $render, $attrs, $args ) {
286
+ global $post, $wp_query;
287
+
288
+ if ( is_search() && is_object( $post ) && is_array( $wp_query->posts ) ) {
289
+ foreach ( $wp_query->posts as $queried_post ) {
290
+ if ( $post->ID === $queried_post->ID ) {
291
+ preg_match( '#(?<=fl_builder_insert_layout).*[id|slug]=[\'"]?([0-9a-z-]+)#', $post->post_content, $matches );
292
+ if ( isset( $matches[1] ) ) {
293
+ return false;
294
+ }
295
+ }
296
+ }
297
+ }
298
+ return $render;
299
+ }
300
+ add_action( 'fl_builder_insert_layout_render', 'fl_builder_insert_layout_render_search', 10, 3 );
301
+
302
+ /**
303
+ * Fixes ajax issues with Event Espresso plugin when builder is open.
304
+ * @since 2.1
305
+ */
306
+ function fl_ee_suppress_notices() {
307
+ if ( FLBuilderModel::is_builder_active() ) {
308
+ add_filter( 'FHEE__EE_Front_Controller__display_errors', '__return_false' );
309
+ }
310
+ }
311
+ add_action( 'wp', 'fl_ee_suppress_notices' );
312
+
313
+ /**
314
+ * Stops ee from outputting HTML into our ajax responses.
315
+ * @since 2.1
316
  */
317
+ function fl_ee_before_ajax() {
318
+ add_filter( 'FHEE__EE_Front_Controller__display_errors', '__return_false' );
319
+ }
320
+ add_action( 'fl_ajax_before_call_action', 'fl_ee_before_ajax' );
321
+
322
+
323
+ /**
324
+ * Plugin Enjoy Instagram loads its js and css on all frontend pages breaking the builder.
325
+ * @since 2.0.1
326
+ */
327
  add_action( 'template_redirect', 'fix_aggiungi_script_instafeed_owl', 1000 );
328
  function fix_aggiungi_script_instafeed_owl() {
329
  if ( FLBuilderModel::is_builder_active() ) {
370
  define( 'NGG_DISABLE_RESOURCE_MANAGER', true );
371
  }
372
  }
373
+
374
+ /**
375
+ * Fix Tasty Recipes compatibility issues with the builder.
376
+ * @since 2.0.6
377
+ */
378
  add_action( 'template_redirect', 'fl_fix_tasty_recipes' );
379
  function fl_fix_tasty_recipes() {
380
  if ( FLBuilderModel::is_builder_active() ) {
382
  remove_action( 'media_buttons', array( 'Tasty_Recipes\Editor', 'action_media_buttons' ) );
383
  }
384
  }
385
+
386
+ /**
387
+ * Dequeue GeneratePress fa5 js when builder is open.
388
+ * @since 2.1
389
+ */
390
+ add_action( 'template_redirect', 'fl_fix_generatepress_fa5' );
391
+ function fl_fix_generatepress_fa5() {
392
+ if ( FLBuilderModel::is_builder_active() ) {
393
+ add_filter( 'generate_fontawesome_essentials', '__return_true' );
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Try to render Ninja Forms JS templates when rendering an AJAX layout
399
+ * in case the layout includes one of their shortcodes. This won't do
400
+ * anything if no templates need to be rendered.
401
+ * @since 2.1
402
+ */
403
+ add_filter( 'fl_builder_ajax_layout_response', 'fl_render_ninja_forms_js' );
404
+ function fl_render_ninja_forms_js( $response ) {
405
+ if ( class_exists( 'NF_Display_Render' ) ) {
406
+ ob_start();
407
+ NF_Display_Render::output_templates();
408
+ $response['html'] .= ob_get_clean();
409
+ }
410
+ return $response;
411
+ }
412
+
413
+ /**
414
+ * Reorder font awesome css.
415
+ * If font-awesome-4 and font-awesome-5 are both in the styles queue font-awesome-5
416
+ * must load first.
417
+ */
418
+ function fl_builder_fa_fix() {
419
+
420
+ global $wp_styles;
421
+
422
+ $queue = $wp_styles->queue;
423
+
424
+ $fa4 = array_search( 'font-awesome', $queue );
425
+ $fa5 = array_search( 'font-awesome-5', $queue );
426
+
427
+ if ( $fa4 && $fa5 && $fa4 < $fa5 ) {
428
+ wp_dequeue_style( 'font-awesome' );
429
+ wp_dequeue_style( 'font-awesome-5' );
430
+ wp_deregister_style( 'font-awesome' );
431
+ wp_enqueue_style( 'font-awesome', FLBuilder::$fa4_url, array( 'font-awesome-5' ) );
432
+ }
433
+ }
434
+ add_action( 'wp_enqueue_scripts', 'fl_builder_fa_fix', 11 );
includes/export.php CHANGED
@@ -74,8 +74,7 @@ function fl_export_wp( $post_ids = array() ) {
74
  // Multisite: the base URL.
75
  if ( is_multisite() ) {
76
  return network_home_url();
77
- } // End if().
78
- else { return get_bloginfo_rss( 'url' );
79
  }
80
  }
81
 
@@ -444,9 +443,9 @@ foreach ( $c_meta as $meta ) :
444
  <?php endforeach; ?>
445
  </item>
446
  <?php
447
- }// End foreach().
448
- }// End while().
449
- }// End if().
450
  ?>
451
  </channel>
452
  </rss>
74
  // Multisite: the base URL.
75
  if ( is_multisite() ) {
76
  return network_home_url();
77
+ } else { return get_bloginfo_rss( 'url' );
 
78
  }
79
  }
80
 
443
  <?php endforeach; ?>
444
  </item>
445
  <?php
446
+ }
447
+ }
448
+ }
449
  ?>
450
  </channel>
451
  </rss>
includes/row-css.php CHANGED
@@ -2,7 +2,7 @@
2
  .fl-node-<?php echo $row->node; ?> {
3
  color: #<?php echo $row->settings->text_color; ?>;
4
  }
5
- .fl-builder-content .fl-node-<?php echo $row->node; ?> *:not(input):not(textarea):not(select):not(a):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(.fl-heading-text):not(.fl-menu-mobile-toggle) {
6
  color: inherit;
7
  }
8
  <?php endif; ?>
2
  .fl-node-<?php echo $row->node; ?> {
3
  color: #<?php echo $row->settings->text_color; ?>;
4
  }
5
+ .fl-builder-content .fl-node-<?php echo $row->node; ?> *:not(input):not(textarea):not(select):not(a):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(.fl-menu-mobile-toggle) {
6
  color: inherit;
7
  }
8
  <?php endif; ?>
includes/row-video.php CHANGED
@@ -40,6 +40,11 @@ data-fallback="<?php if ( isset( $row->settings->bg_video_fallback_src ) ) { ech
40
  data-<?php echo $video_data['type']; ?>="<?php echo $row->settings->bg_video_service_url; ?>"
41
  data-video-id="<?php echo $video_data['video_id']; ?>"
42
  data-enable-audio="<?php echo $row->settings->bg_video_audio; ?>"
 
 
 
 
 
43
  <?php endif; ?>>
44
  <div class="fl-bg-video-player"></div>
45
  </div>
40
  data-<?php echo $video_data['type']; ?>="<?php echo $row->settings->bg_video_service_url; ?>"
41
  data-video-id="<?php echo $video_data['video_id']; ?>"
42
  data-enable-audio="<?php echo $row->settings->bg_video_audio; ?>"
43
+ <?php if ( isset( $video_data['params'] ) ) : ?>
44
+ <?php foreach ( $video_data['params'] as $key => $val ) : ?>
45
+ data-<?php echo $key . '="' . $val . '"'; ?>
46
+ <?php endforeach; ?>
47
+ <?php endif; ?>
48
  <?php endif; ?>>
49
  <div class="fl-bg-video-player"></div>
50
  </div>
includes/ui-extras.php CHANGED
@@ -4,3 +4,5 @@
4
  <div class="fl-builder-hidden-editor fl-editor-field" data-name="text" data-wpautop="1" data-buttons="1" data-rows="16">
5
  <textarea></textarea>
6
  </div>
 
 
4
  <div class="fl-builder-hidden-editor fl-editor-field" data-name="text" data-wpautop="1" data-buttons="1" data-rows="16">
5
  <textarea></textarea>
6
  </div>
7
+ <?php // react root ?>
8
+ <div id="fl-ui-root"></div>
includes/ui-field-ordering.php CHANGED
@@ -27,7 +27,7 @@ var encodedValue = JSON.stringify( data.value );
27
  #>
28
  <div class="fl-ordering-field-options<# if ( data.field.className ) { #> {{data.field.className}}<# } #>">
29
  <# for ( var i in data.value ) { #>
30
- <div class="fl-ordering-field-option" data-key="{{data.value[ i ]}}">{{data.field.options[ data.value[ i ] ]}}<i class="fa fa-arrows"></i></div>
31
  <# } #>
32
  </div>
33
  <input type="hidden" name="{{data.name}}" value='{{{encodedValue}}}' />
27
  #>
28
  <div class="fl-ordering-field-options<# if ( data.field.className ) { #> {{data.field.className}}<# } #>">
29
  <# for ( var i in data.value ) { #>
30
+ <div class="fl-ordering-field-option" data-key="{{data.value[ i ]}}">{{data.field.options[ data.value[ i ] ]}}<i class="fas fa-arrows-alt"></i></div>
31
  <# } #>
32
  </div>
33
  <input type="hidden" name="{{data.name}}" value='{{{encodedValue}}}' />
includes/ui-field-video.php CHANGED
@@ -35,6 +35,9 @@ if ( ! data.value || ! video ) {
35
  <# } #>
36
  <br />
37
  <a class="fl-video-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace Video', 'fl-builder' ); ?></a>
 
 
 
38
  <div class="fl-clear"></div>
39
  </div>
40
  <input name="{{data.name}}" type="hidden" value='{{{data.value}}}' />
35
  <# } #>
36
  <br />
37
  <a class="fl-video-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace Video', 'fl-builder' ); ?></a>
38
+ <# if ( data.field.show_remove ) { #>
39
+ <a class="fl-video-remove" href="javascript:void(0);" onclick="return false;"><?php _e( 'Remove Video', 'fl-builder' ); ?></a>
40
+ <# } #>
41
  <div class="fl-clear"></div>
42
  </div>
43
  <input name="{{data.name}}" type="hidden" value='{{{data.value}}}' />
includes/ui-field.php CHANGED
@@ -21,7 +21,7 @@
21
 
22
  <# if ( data.field.help ) { #>
23
  <span class="fl-help-tooltip">
24
- <i class="fl-help-tooltip-icon fa fa-question-circle"></i>
25
  <span class="fl-help-tooltip-text">{{{data.field.help}}}</span>
26
  </span>
27
  <# } #>
21
 
22
  <# if ( data.field.help ) { #>
23
  <span class="fl-help-tooltip">
24
+ <i class="fl-help-tooltip-icon fas fa-question-circle"></i>
25
  <span class="fl-help-tooltip-text">{{{data.field.help}}}</span>
26
  </span>
27
  <# } #>
includes/ui-js-config.php CHANGED
@@ -1,34 +1,34 @@
1
  <script>
2
  <?php
3
 
4
- echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config', array(
5
- 'adminUrl' => admin_url(),
6
- 'ajaxNonce' => wp_create_nonce( 'fl_ajax_update' ),
7
- 'builderEnabled' => get_post_meta( $post_id, '_fl_builder_enabled', true ) ? true : false,
8
- 'colorPresets' => FLBuilderModel::get_color_presets(),
9
- 'customImageSizeTitles' => apply_filters( 'image_size_names_choose', array() ),
10
- 'debug' => FLBuilder::is_debug(),
11
- 'enabledTemplates' => 'core',
12
- 'global' => $global_settings,
13
- 'help' => FLBuilderModel::get_help_button_settings(),
14
- 'homeUrl' => home_url(),
15
- 'isRtl' => is_rtl(),
16
- 'isUserTemplate' => false,
17
- 'lite' => true === FL_BUILDER_LITE,
18
- 'modSecFix' => ( defined( 'FL_BUILDER_MODSEC_FIX' ) && FL_BUILDER_MODSEC_FIX ),
19
- 'moduleGroups' => FLBuilderModel::get_module_groups(),
20
- 'nestedColumns' => ( ! defined( 'FL_BUILDER_NESTED_COLUMNS' ) || FL_BUILDER_NESTED_COLUMNS ),
21
- 'newUser' => FLBuilderModel::is_new_user(),
22
- 'pluginUrl' => FL_BUILDER_URL,
23
- 'postId' => $post_id,
24
- 'postStatus' => get_post_status(),
25
- 'postType' => get_post_type(),
26
- 'services' => FLBuilderServices::get_services_data(),
27
- 'simpleUi' => $simple_ui ? true : false,
28
- 'upgradeUrl' => FLBuilderModel::get_upgrade_url( array(
29
- 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-demo' ),
30
- 'utm_source' => 'builder-ui',
31
- 'utm_campaign' => ( true === FL_BUILDER_LITE ? 'top-panel-cta' : 'demo-cta' ),
32
  ) ),
33
  'userCanEditGlobalTemplates' => FLBuilderUserAccess::current_user_can( 'global_node_editing' ),
34
  'userCanPublish' => current_user_can( 'publish_posts' ),
@@ -49,165 +49,177 @@ echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config'
49
  'googleFontsUrl' => apply_filters( 'fl_builder_google_fonts_domain', '//fonts.googleapis.com/' ) . 'css?family=',
50
  'wp_editor' => FLBuilder::get_wp_editor(),
51
  'rowResize' => FLBuilderModel::get_row_resize_settings(),
 
 
 
 
 
52
  ) ) ) . ';';
53
 
54
- echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_strings', array(
55
- 'actionsLightboxTitle' => esc_attr__( 'What would you like to do?', 'fl-builder' ),
56
- 'addField' => esc_attr_x( 'Add %s', 'Field name to add.', 'fl-builder' ),
57
- 'alreadySaved' => esc_attr_x( '%s is already a saved preset.', '%s is the preset hex color code.', 'fl-builder' ),
58
- 'audioSelected' => esc_attr__( 'Audio File Selected', 'fl-builder' ),
59
- 'audioSelectedNum' => esc_attr__( '%d Audio File Selected', 'fl-builder' ),
60
- 'audiosSelected' => esc_attr__( 'Audio Files Selected', 'fl-builder' ),
61
- 'audiosSelectedNum' => esc_attr__( '%d Audio Files Selected', 'fl-builder' ),
62
- 'blank' => esc_attr__( 'Blank', 'fl-builder' ),
63
- 'cancel' => esc_attr__( 'Cancel', 'fl-builder' ),
64
- 'changeTemplate' => esc_attr__( 'Change Template', 'fl-builder' ),
65
- 'changeTemplateMessage' => esc_attr__( 'Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder' ),
66
- 'colorPresets' => esc_attr__( 'Color Presets', 'fl-builder' ),
67
- 'colorPicker' => esc_attr__( 'Color Picker', 'fl-builder' ),
68
- 'column' => esc_attr__( 'Column', 'fl-builder' ),
69
- 'contentSliderSelectLayout' => esc_attr__( 'Please select either a background layout or content layout before submitting.', 'fl-builder' ),
70
- 'countdownDateisInThePast' => esc_attr__( 'Error! Please enter a date that is in the future.', 'fl-builder' ),
71
- 'deleteAccount' => esc_attr__( 'Remove Account', 'fl-builder' ),
72
- 'deleteAccountWarning' => esc_attr__( 'Are you sure you want to remove this account? Other modules that are connected to it will be affected.', 'fl-builder' ),
73
- 'deleteColumnMessage' => esc_attr__( 'Do you really want to delete this column?', 'fl-builder' ),
74
- 'deleteFieldMessage' => esc_attr__( 'Do you really want to delete this item?', 'fl-builder' ),
75
- 'deleteModuleMessage' => esc_attr__( 'Do you really want to delete this module?', 'fl-builder' ),
76
- 'deleteRowMessage' => esc_attr__( 'Do you really want to delete this row?', 'fl-builder' ),
77
- 'deleteTemplate' => esc_attr__( 'Do you really want to delete this template?', 'fl-builder' ),
78
- 'deleteGlobalTemplate' => esc_attr__( 'WARNING! You are about to delete a global template that may be linked to other pages. Do you really want to delete this template and unlink it?', 'fl-builder' ),
79
- 'discard' => esc_attr__( 'Discard Changes and Exit', 'fl-builder' ),
80
- 'discardMessage' => esc_attr__( 'Do you really want to discard these changes? All of your changes that are not published will be lost.', 'fl-builder' ),
81
- 'done' => esc_attr__( 'Done', 'fl-builder' ),
82
- 'draft' => esc_attr__( 'Save Changes and Exit', 'fl-builder' ),
83
- 'duplicate' => esc_attr__( 'Duplicate', 'fl-builder' ),
84
- 'duplicateLayout' => esc_attr_x( 'Duplicate Layout', 'Duplicate page/post action label.', 'fl-builder' ),
85
- 'editFormField' => esc_attr_x( 'Edit %s', '%s stands for form field label.', 'fl-builder' ),
86
- 'editGlobalSettings' => esc_attr__( 'Global Settings', 'fl-builder' ),
87
- 'editLayoutSettings' => esc_attr__( 'Layout CSS / Javascript', 'fl-builder' ),
88
- 'emptyMessage' => esc_attr__( 'Drop a row layout or module to get started!', 'fl-builder' ),
89
- 'enterValidDay' => esc_attr__( 'Error! Please enter a valid day.', 'fl-builder' ),
90
- 'enterValidMonth' => esc_attr__( 'Error! Please enter a valid month.', 'fl-builder' ),
91
- 'enterValidYear' => esc_attr__( 'Error! Please enter a valid year.', 'fl-builder' ),
92
- 'errorMessage' => esc_attr__( 'Beaver Builder caught the following JavaScript error. If Beaver Builder is not functioning as expected the cause is most likely this error. Please help us by disabling all plugins and testing Beaver Builder while reactivating each to determine if the issue is related to a third party plugin.', 'fl-builder' ),
93
- 'fieldLoading' => esc_attr__( 'Field Loading...', 'fl-builder' ),
94
- 'fullSize' => esc_attr__( 'Full Size', 'fl-builder' ),
95
- 'getHelp' => esc_attr__( 'Get Help', 'fl-builder' ),
96
- 'global' => esc_attr_x( 'Global', 'Indicator for global node templates.', 'fl-builder' ),
97
- 'globalErrorMessage' => __( '"{message}" on line {line} of {file}.', 'fl-builder' ),
98
- 'insert' => esc_attr__( 'Insert', 'fl-builder' ),
99
- 'large' => esc_attr__( 'Large', 'fl-builder' ),
100
- 'manageTemplates' => esc_attr__( 'Manage Templates', 'fl-builder' ),
101
- 'medium' => esc_attr__( 'Medium', 'fl-builder' ),
102
- 'module' => esc_attr__( 'Module', 'fl-builder' ),
103
- 'moduleTemplateSaved' => esc_attr__( 'Module Saved!', 'fl-builder' ),
104
- 'move' => esc_attr__( 'Move', 'fl-builder' ),
105
- 'newColumn' => esc_attr__( 'New Column', 'fl-builder' ),
106
- 'newRow' => esc_attr__( 'New Row', 'fl-builder' ),
107
- 'noneColorSelected' => esc_attr__( 'Please enter a color first.', 'fl-builder' ),
108
- 'noPresets' => esc_attr__( 'Add a color preset first.', 'fl-builder' ),
109
- 'noResultsFound' => esc_attr__( 'No results found.', 'fl-builder' ),
110
- 'noSavedRows' => esc_attr__( 'No saved rows found.', 'fl-builder' ),
111
- 'noSavedModules' => esc_attr__( 'No saved modules found.', 'fl-builder' ),
112
- 'ok' => esc_attr__( 'OK', 'fl-builder' ),
113
- 'photoPage' => esc_attr__( 'Photo Page', 'fl-builder' ),
114
- 'photoSelected' => esc_attr__( 'Photo Selected', 'fl-builder' ),
115
- 'photoSelectedNum' => esc_attr__( '%d Photo Selected', 'fl-builder' ),
116
- 'photosSelected' => esc_attr__( 'Photos Selected', 'fl-builder' ),
117
- 'photosSelectedNum' => esc_attr__( '%d Photos Selected', 'fl-builder' ),
118
- 'placeholder' => esc_attr__( 'Paste color here...', 'fl-builder' ),
119
- 'pleaseWait' => esc_attr__( 'Please Wait...', 'fl-builder' ),
120
- 'presetAdded' => esc_attr_x( '%s added to presets!', '%s is the preset hex color code.', 'fl-builder' ),
121
- 'publish' => esc_attr__( 'Publish Changes', 'fl-builder' ),
122
- 'remove' => esc_attr__( 'Remove', 'fl-builder' ),
123
- 'removePresetConfirm' => esc_attr__( 'Are you sure?', 'fl-builder' ),
124
- 'revisionDate' => esc_attr_x( '%s ago', '%s is a time diff such as 1 day or 2 weeks.', 'fl-builder' ),
125
- 'revisionAuthor' => esc_attr_x( 'By %s', '%s is the author name.', 'fl-builder' ),
126
- 'row' => esc_attr__( 'Row', 'fl-builder' ),
127
- 'rowSettings' => esc_attr__( 'Row Settings', 'fl-builder' ),
128
- 'rowTemplateSaved' => esc_attr__( 'Row Saved!', 'fl-builder' ),
129
- 'saveCoreTemplate' => esc_attr__( 'Save Core Template', 'fl-builder' ),
130
- 'save' => esc_attr__( 'Save', 'fl-builder' ),
131
- 'saveAs' => esc_attr__( 'Save As...', 'fl-builder' ),
132
- 'saveModule' => esc_attr__( 'Save Module', 'fl-builder' ),
133
- 'saveRow' => esc_attr__( 'Save Row', 'fl-builder' ),
134
- 'saveTemplate' => esc_attr__( 'Save Template', 'fl-builder' ),
135
- 'selectAudio' => esc_attr__( 'Select Audio', 'fl-builder' ),
136
- 'selectPhoto' => esc_attr__( 'Select Photo', 'fl-builder' ),
137
- 'selectPhotos' => esc_attr__( 'Select Photos', 'fl-builder' ),
138
- 'selectVideo' => esc_attr__( 'Select Video', 'fl-builder' ),
139
- 'settingsHaveErrors' => esc_attr__( 'These settings have errors. Please correct them before continuing.', 'fl-builder' ),
140
- 'submitForReview' => esc_attr__( 'Submit for Review', 'fl-builder' ),
 
 
141
  'subscriptionModuleAccountError' => esc_attr__( 'Please select an account before saving.', 'fl-builder' ),
142
  'subscriptionModuleConnectError' => esc_attr__( 'Please connect an account before saving.', 'fl-builder' ),
143
- 'subscriptionModuleListError' => esc_attr__( 'Please select a list before saving.', 'fl-builder' ),
144
- 'subscriptionModuleTagsError' => esc_attr__( 'Please enter at least one tag before saving.', 'fl-builder' ),
145
- 'takeHelpTour' => esc_attr__( 'Take a Tour', 'fl-builder' ),
146
- 'templateAppend' => esc_attr__( 'Append New Layout', 'fl-builder' ),
147
- 'templateReplace' => esc_attr__( 'Replace Existing Layout', 'fl-builder' ),
148
- 'templateSaved' => esc_attr__( 'Template Saved!', 'fl-builder' ),
149
- 'thumbnail' => esc_attr__( 'Thumbnail', 'fl-builder' ),
150
- 'tourNext' => esc_attr__( 'Next', 'fl-builder' ),
151
- 'tourEnd' => esc_attr__( 'Get Started', 'fl-builder' ),
152
- 'tourTemplatesTitle' => esc_attr__( 'Choose a Template', 'fl-builder' ),
153
- 'tourTemplates' => esc_attr__( 'Get started by choosing a layout template to customize, or build a page from scratch by selecting the blank layout template.', 'fl-builder' ),
154
- 'tourAddRowsTitle' => esc_attr__( 'Add Rows', 'fl-builder' ),
155
- 'tourAddRows' => esc_attr__( 'Add multi-column rows, adjust spacing, add backgrounds and more by dragging and dropping row layouts onto the page.', 'fl-builder' ),
156
- 'tourAddContentTitle' => esc_attr__( 'Add Content', 'fl-builder' ),
157
- 'tourAddContent' => esc_attr__( 'Add new content by dragging and dropping modules or widgets into your row layouts or to create a new row layout.', 'fl-builder' ),
158
- 'tourEditContentTitle' => esc_attr__( 'Edit Content', 'fl-builder' ),
159
- 'tourEditContent' => esc_attr__( 'Move your mouse over rows, columns or modules to edit and interact with them.', 'fl-builder' ),
160
- 'tourEditContent2' => esc_attr__( 'Use the action buttons to perform actions such as moving, editing, duplicating or deleting rows, columns and modules.', 'fl-builder' ),
161
- 'tourAddContentButtonTitle' => esc_attr__( 'Add More Content', 'fl-builder' ),
162
- 'tourAddContentButton' => esc_attr__( 'Use the Add Content button to open the content panel and add new row layouts, modules or widgets.', 'fl-builder' ),
163
- 'tourTemplatesButtonTitle' => esc_attr__( 'Change Templates', 'fl-builder' ),
164
- 'tourTemplatesButton' => esc_attr__( 'Use the Templates button to pick a new template or append one to your layout. Appending will insert a new template at the end of your existing page content.', 'fl-builder' ),
165
- 'tourToolsButtonTitle' => esc_attr__( 'Helpful Tools', 'fl-builder' ),
166
- 'tourToolsButton' => esc_attr__( 'The Tools button lets you save a template, duplicate a layout, edit the settings for a layout or edit the global settings.', 'fl-builder' ),
167
- 'tourDoneButtonTitle' => esc_attr__( 'Publish Your Changes', 'fl-builder' ),
168
- 'tourDoneButton' => esc_attr__( "Once you're finished, click the Done button to publish your changes, save a draft or revert back to the last published state.", 'fl-builder' ),
169
- 'tourFinishedTitle' => esc_attr__( "Let's Get Building!", 'fl-builder' ),
170
- 'tourFinished' => esc_attr__( "Now that you know the basics, you're ready to start building! If at any time you need help, click the help icon in the upper right corner to access the help menu. Happy building!", 'fl-builder' ),
171
- 'unloadWarning' => esc_attr__( 'The settings you are currently editing will not be saved if you navigate away from this page.', 'fl-builder' ),
172
- 'viewKnowledgeBase' => esc_attr__( 'View the Knowledge Base', 'fl-builder' ),
173
- 'validateRequiredMessage' => esc_attr__( 'This field is required.', 'fl-builder' ),
174
- 'visitForums' => esc_attr__( 'Contact Support', 'fl-builder' ),
175
- 'watchHelpVideo' => esc_attr__( 'Watch the Video', 'fl-builder' ),
176
- 'welcomeMessage' => esc_attr__( 'Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder' ),
177
- 'uncategorized' => esc_attr__( 'Uncategorized', 'fl-builder' ),
178
- 'yesPlease' => esc_attr__( 'Yes Please!', 'fl-builder' ),
179
- 'savedStatus' => array(
180
- 'saving' => esc_attr__( 'Saving...', 'fl-builder' ),
181
- 'savingTooltip' => esc_attr__( 'The layout is currently being saved', 'fl-builder' ),
182
- 'saved' => esc_attr__( 'Saved', 'fl-builder' ),
183
- 'savedTooltip' => esc_attr__( 'The layout is saved', 'fl-builder' ),
184
- 'edited' => esc_attr__( 'Edited', 'fl-builder' ),
185
- 'editedTooltip' => esc_attr__( 'This layout has unpublished changes', 'fl-builder' ),
186
- 'editedWarning' => esc_attr__( 'This layout has unpublished changes. If you discard this draft all of your previously unpublished changes will be lost.', 'fl-builder' ),
187
- 'editedWarningDismiss' => esc_attr__( 'Ok, got it!', 'fl-builder' ),
188
- 'noChanges' => esc_attr__( 'Nothing new to publish', 'fl-builder' ),
189
- 'publishing' => esc_attr__( 'Publishing Changes', 'fl-builder' ),
190
- 'publishingTooltip' => esc_attr__( 'Changes being published', 'fl-builder' ),
191
- 'nothingToSave' => esc_attr__( 'No new changes to save', 'fl-builder' ),
192
- 'hasAlreadySaved' => esc_attr__( 'Your changes are saved', 'fl-builder' ),
193
 
194
  ),
195
- 'widgetsCategoryTitle' => esc_attr__( 'WordPress Widgets', 'fl-builder' ),
196
- 'typeLabels' => array(
197
- 'template' => esc_attr__( 'Template', 'fl-builder' ),
198
- 'module' => esc_attr__( 'Module', 'fl-builder' ),
199
- 'row' => esc_attr__( 'Row', 'fl-builder' ),
200
- 'colGroup' => esc_attr__( 'Column Group', 'fl-builder' ),
201
- 'widget' => esc_attr__( 'Widget', 'fl-builder' ),
202
  ),
203
- 'categoryMeta' => array(
204
- 'landing' => array(
205
- 'name' => esc_attr__( 'Landing Pages', 'fl-builder' ),
206
  ),
207
- 'company' => array(
208
- 'name' => esc_attr__( 'Content Pages', 'fl-builder' ),
209
  ),
210
  ),
 
 
 
 
 
211
  ) ) ) . ';';
212
 
213
  FLBuilderFonts::js();
1
  <script>
2
  <?php
3
 
4
+ echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config', array(
5
+ 'adminUrl' => admin_url(),
6
+ 'ajaxNonce' => wp_create_nonce( 'fl_ajax_update' ),
7
+ 'builderEnabled' => get_post_meta( $post_id, '_fl_builder_enabled', true ) ? true : false,
8
+ 'colorPresets' => FLBuilderModel::get_color_presets(),
9
+ 'customImageSizeTitles' => apply_filters( 'image_size_names_choose', array() ),
10
+ 'debug' => FLBuilder::is_debug(),
11
+ 'enabledTemplates' => 'core',
12
+ 'global' => $global_settings,
13
+ 'help' => FLBuilderModel::get_help_button_settings(),
14
+ 'homeUrl' => home_url(),
15
+ 'isRtl' => is_rtl(),
16
+ 'isUserTemplate' => false,
17
+ 'lite' => true === FL_BUILDER_LITE,
18
+ 'modSecFix' => ( defined( 'FL_BUILDER_MODSEC_FIX' ) && FL_BUILDER_MODSEC_FIX ),
19
+ 'moduleGroups' => FLBuilderModel::get_module_groups(),
20
+ 'nestedColumns' => ( ! defined( 'FL_BUILDER_NESTED_COLUMNS' ) || FL_BUILDER_NESTED_COLUMNS ),
21
+ 'newUser' => FLBuilderModel::is_new_user(),
22
+ 'pluginUrl' => FL_BUILDER_URL,
23
+ 'postId' => $post_id,
24
+ 'postStatus' => get_post_status(),
25
+ 'postType' => get_post_type(),
26
+ 'services' => FLBuilderServices::get_services_data(),
27
+ 'simpleUi' => $simple_ui ? true : false,
28
+ 'upgradeUrl' => FLBuilderModel::get_upgrade_url( array(
29
+ 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-demo' ),
30
+ 'utm_source' => 'builder-ui',
31
+ 'utm_campaign' => ( true === FL_BUILDER_LITE ? 'top-panel-cta' : 'demo-cta' ),
32
  ) ),
33
  'userCanEditGlobalTemplates' => FLBuilderUserAccess::current_user_can( 'global_node_editing' ),
34
  'userCanPublish' => current_user_can( 'publish_posts' ),
49
  'googleFontsUrl' => apply_filters( 'fl_builder_google_fonts_domain', '//fonts.googleapis.com/' ) . 'css?family=',
50
  'wp_editor' => FLBuilder::get_wp_editor(),
51
  'rowResize' => FLBuilderModel::get_row_resize_settings(),
52
+ 'notifications' => FLBuilderNotifications::get_notifications(),
53
+ 'isWhiteLabeled' => FLBuilderModel::is_white_labeled(),
54
+ 'inlineEnabled' => FLBuilderModel::is_inline_enabled(),
55
+ 'CheckCodeErrors' => FLBuilderModel::is_codechecking_enabled(),
56
+
57
  ) ) ) . ';';
58
 
59
+ echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_strings', array(
60
+ 'actionsLightboxTitle' => esc_attr__( 'What would you like to do?', 'fl-builder' ),
61
+ 'addField' => esc_attr_x( 'Add %s', 'Field name to add.', 'fl-builder' ),
62
+ 'alreadySaved' => esc_attr_x( '%s is already a saved preset.', '%s is the preset hex color code.', 'fl-builder' ),
63
+ 'audioSelected' => esc_attr__( 'Audio File Selected', 'fl-builder' ),
64
+ 'audioSelectedNum' => esc_attr__( '%d Audio File Selected', 'fl-builder' ),
65
+ 'audiosSelected' => esc_attr__( 'Audio Files Selected', 'fl-builder' ),
66
+ 'audiosSelectedNum' => esc_attr__( '%d Audio Files Selected', 'fl-builder' ),
67
+ 'blank' => esc_attr__( 'Blank', 'fl-builder' ),
68
+ 'cancel' => esc_attr__( 'Cancel', 'fl-builder' ),
69
+ 'changeTemplate' => esc_attr__( 'Change Template', 'fl-builder' ),
70
+ 'changeTemplateMessage' => esc_attr__( 'Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder' ),
71
+ 'colorPresets' => esc_attr__( 'Color Presets', 'fl-builder' ),
72
+ 'colorPicker' => esc_attr__( 'Color Picker', 'fl-builder' ),
73
+ 'codeError' => esc_attr__( 'Please fix all code errors before saving.', 'fl-builder' ),
74
+ 'column' => esc_attr__( 'Column', 'fl-builder' ),
75
+ 'contentSliderSelectLayout' => esc_attr__( 'Please select either a background layout or content layout before submitting.', 'fl-builder' ),
76
+ 'countdownDateisInThePast' => esc_attr__( 'Error! Please enter a date that is in the future.', 'fl-builder' ),
77
+ 'deleteAccount' => esc_attr__( 'Remove Account', 'fl-builder' ),
78
+ 'deleteAccountWarning' => esc_attr__( 'Are you sure you want to remove this account? Other modules that are connected to it will be affected.', 'fl-builder' ),
79
+ 'deleteColumnMessage' => esc_attr__( 'Do you really want to delete this column?', 'fl-builder' ),
80
+ 'deleteFieldMessage' => esc_attr__( 'Do you really want to delete this item?', 'fl-builder' ),
81
+ 'deleteModuleMessage' => esc_attr__( 'Do you really want to delete this module?', 'fl-builder' ),
82
+ 'deleteRowMessage' => esc_attr__( 'Do you really want to delete this row?', 'fl-builder' ),
83
+ 'deleteTemplate' => esc_attr__( 'Do you really want to delete this template?', 'fl-builder' ),
84
+ 'deleteGlobalTemplate' => esc_attr__( 'WARNING! You are about to delete a global template that may be linked to other pages. Do you really want to delete this template and unlink it?', 'fl-builder' ),
85
+ 'discard' => esc_attr__( 'Discard Changes and Exit', 'fl-builder' ),
86
+ 'discardMessage' => esc_attr__( 'Do you really want to discard these changes? All of your changes that are not published will be lost.', 'fl-builder' ),
87
+ 'done' => esc_attr__( 'Done', 'fl-builder' ),
88
+ 'draft' => esc_attr__( 'Save Changes and Exit', 'fl-builder' ),
89
+ 'duplicate' => esc_attr__( 'Duplicate', 'fl-builder' ),
90
+ 'duplicateLayout' => esc_attr_x( 'Duplicate Layout', 'Duplicate page/post action label.', 'fl-builder' ),
91
+ 'editFormField' => esc_attr_x( 'Edit %s', '%s stands for form field label.', 'fl-builder' ),
92
+ 'editGlobalSettings' => esc_attr__( 'Global Settings', 'fl-builder' ),
93
+ 'editLayoutSettings' => esc_attr__( 'Layout CSS / Javascript', 'fl-builder' ),
94
+ 'emptyMessage' => esc_attr__( 'Drop a row layout or module to get started!', 'fl-builder' ),
95
+ 'enterValidDay' => esc_attr__( 'Error! Please enter a valid day.', 'fl-builder' ),
96
+ 'enterValidMonth' => esc_attr__( 'Error! Please enter a valid month.', 'fl-builder' ),
97
+ 'enterValidYear' => esc_attr__( 'Error! Please enter a valid year.', 'fl-builder' ),
98
+ 'errorMessage' => esc_attr__( 'Beaver Builder caught the following JavaScript error. If Beaver Builder is not functioning as expected the cause is most likely this error. Please help us by disabling all plugins and testing Beaver Builder while reactivating each to determine if the issue is related to a third party plugin.', 'fl-builder' ),
99
+ 'fieldLoading' => esc_attr__( 'Field Loading...', 'fl-builder' ),
100
+ 'fullSize' => esc_attr__( 'Full Size', 'fl-builder' ),
101
+ 'getHelp' => esc_attr__( 'Get Help', 'fl-builder' ),
102
+ 'global' => esc_attr_x( 'Global', 'Indicator for global node templates.', 'fl-builder' ),
103
+ 'globalErrorMessage' => __( '"{message}" on line {line} of {file}.', 'fl-builder' ),
104
+ 'insert' => esc_attr__( 'Insert', 'fl-builder' ),
105
+ 'large' => esc_attr__( 'Large', 'fl-builder' ),
106
+ 'manageTemplates' => esc_attr__( 'Manage Templates', 'fl-builder' ),
107
+ 'medium' => esc_attr__( 'Medium', 'fl-builder' ),
108
+ 'module' => esc_attr__( 'Module', 'fl-builder' ),
109
+ 'moduleTemplateSaved' => esc_attr__( 'Module Saved!', 'fl-builder' ),
110
+ 'move' => esc_attr__( 'Move', 'fl-builder' ),
111
+ 'newColumn' => esc_attr__( 'New Column', 'fl-builder' ),
112
+ 'newRow' => esc_attr__( 'New Row', 'fl-builder' ),
113
+ 'noneColorSelected' => esc_attr__( 'Please enter a color first.', 'fl-builder' ),
114
+ 'noPresets' => esc_attr__( 'Add a color preset first.', 'fl-builder' ),
115
+ 'noResultsFound' => esc_attr__( 'No results found.', 'fl-builder' ),
116
+ 'noSavedRows' => esc_attr__( 'No saved rows found.', 'fl-builder' ),
117
+ 'noSavedModules' => esc_attr__( 'No saved modules found.', 'fl-builder' ),
118
+ 'ok' => esc_attr__( 'OK', 'fl-builder' ),
119
+ 'photoPage' => esc_attr__( 'Photo Page', 'fl-builder' ),
120
+ 'photoSelected' => esc_attr__( 'Photo Selected', 'fl-builder' ),
121
+ 'photoSelectedNum' => esc_attr__( '%d Photo Selected', 'fl-builder' ),
122
+ 'photosSelected' => esc_attr__( 'Photos Selected', 'fl-builder' ),
123
+ 'photosSelectedNum' => esc_attr__( '%d Photos Selected', 'fl-builder' ),
124
+ 'placeholder' => esc_attr__( 'Paste color here...', 'fl-builder' ),
125
+ 'pleaseWait' => esc_attr__( 'Please Wait...', 'fl-builder' ),
126
+ 'presetAdded' => esc_attr_x( '%s added to presets!', '%s is the preset hex color code.', 'fl-builder' ),
127
+ 'publish' => esc_attr__( 'Publish Changes', 'fl-builder' ),
128
+ 'remove' => esc_attr__( 'Remove', 'fl-builder' ),
129
+ 'removePresetConfirm' => esc_attr__( 'Are you sure?', 'fl-builder' ),
130
+ 'revisionDate' => esc_attr_x( '%s ago', '%s is a time diff such as 1 day or 2 weeks.', 'fl-builder' ),
131
+ 'revisionAuthor' => esc_attr_x( 'By %s', '%s is the author name.', 'fl-builder' ),
132
+ 'row' => esc_attr__( 'Row', 'fl-builder' ),
133
+ 'rowSettings' => esc_attr__( 'Row Settings', 'fl-builder' ),
134
+ 'rowTemplateSaved' => esc_attr__( 'Row Saved!', 'fl-builder' ),
135
+ 'saveCoreTemplate' => esc_attr__( 'Save Core Template', 'fl-builder' ),
136
+ 'save' => esc_attr__( 'Save', 'fl-builder' ),
137
+ 'saveAs' => esc_attr__( 'Save As...', 'fl-builder' ),
138
+ 'saveColumn' => esc_attr__( 'Save Column', 'fl-builder' ),
139
+ 'saveModule' => esc_attr__( 'Save Module', 'fl-builder' ),
140
+ 'saveRow' => esc_attr__( 'Save Row', 'fl-builder' ),
141
+ 'saveTemplate' => esc_attr__( 'Save Template', 'fl-builder' ),
142
+ 'selectAudio' => esc_attr__( 'Select Audio', 'fl-builder' ),
143
+ 'selectPhoto' => esc_attr__( 'Select Photo', 'fl-builder' ),
144
+ 'selectPhotos' => esc_attr__( 'Select Photos', 'fl-builder' ),
145
+ 'selectVideo' => esc_attr__( 'Select Video', 'fl-builder' ),
146
+ 'settingsHaveErrors' => esc_attr__( 'These settings have errors. Please correct them before continuing.', 'fl-builder' ),
147
+ 'submitForReview' => esc_attr__( 'Submit for Review', 'fl-builder' ),
148
  'subscriptionModuleAccountError' => esc_attr__( 'Please select an account before saving.', 'fl-builder' ),
149
  'subscriptionModuleConnectError' => esc_attr__( 'Please connect an account before saving.', 'fl-builder' ),
150
+ 'subscriptionModuleListError' => esc_attr__( 'Please select a list before saving.', 'fl-builder' ),
151
+ 'subscriptionModuleTagsError' => esc_attr__( 'Please enter at least one tag before saving.', 'fl-builder' ),
152
+ 'takeHelpTour' => esc_attr__( 'Take a Tour', 'fl-builder' ),
153
+ 'templateAppend' => esc_attr__( 'Append New Layout', 'fl-builder' ),
154
+ 'templateReplace' => esc_attr__( 'Replace Existing Layout', 'fl-builder' ),
155
+ 'templateSaved' => esc_attr__( 'Template Saved!', 'fl-builder' ),
156
+ 'thumbnail' => esc_attr__( 'Thumbnail', 'fl-builder' ),
157
+ 'tourNext' => esc_attr__( 'Next', 'fl-builder' ),
158
+ 'tourEnd' => esc_attr__( 'Get Started', 'fl-builder' ),
159
+ 'tourTemplatesTitle' => esc_attr__( 'Choose a Template', 'fl-builder' ),
160
+ 'tourTemplates' => esc_attr__( 'Get started by choosing a layout template to customize, or build a page from scratch by selecting the blank layout template.', 'fl-builder' ),
161
+ 'tourAddRowsTitle' => esc_attr__( 'Add Rows', 'fl-builder' ),
162
+ 'tourAddRows' => esc_attr__( 'Add multi-column rows, adjust spacing, add backgrounds and more by dragging and dropping row layouts onto the page.', 'fl-builder' ),
163
+ 'tourAddContentTitle' => esc_attr__( 'Add Content', 'fl-builder' ),
164
+ 'tourAddContent' => esc_attr__( 'Add new content by dragging and dropping modules or widgets into your row layouts or to create a new row layout.', 'fl-builder' ),
165
+ 'tourEditContentTitle' => esc_attr__( 'Edit Content', 'fl-builder' ),
166
+ 'tourEditContent' => esc_attr__( 'Move your mouse over rows, columns or modules to edit and interact with them.', 'fl-builder' ),
167
+ 'tourEditContent2' => esc_attr__( 'Use the action buttons to perform actions such as moving, editing, duplicating or deleting rows, columns and modules.', 'fl-builder' ),
168
+ 'tourAddContentButtonTitle' => esc_attr__( 'Add More Content', 'fl-builder' ),
169
+ 'tourAddContentButton' => esc_attr__( 'Use the Add Content button to open the content panel and add new row layouts, modules or widgets.', 'fl-builder' ),
170
+ 'tourTemplatesButtonTitle' => esc_attr__( 'Change Templates', 'fl-builder' ),
171
+ 'tourTemplatesButton' => esc_attr__( 'Use the Templates button to pick a new template or append one to your layout. Appending will insert a new template at the end of your existing page content.', 'fl-builder' ),
172
+ 'tourToolsButtonTitle' => esc_attr__( 'Helpful Tools', 'fl-builder' ),
173
+ 'tourToolsButton' => esc_attr__( 'The Tools button lets you save a template, duplicate a layout, edit the settings for a layout or edit the global settings.', 'fl-builder' ),
174
+ 'tourDoneButtonTitle' => esc_attr__( 'Publish Your Changes', 'fl-builder' ),
175
+ 'tourDoneButton' => esc_attr__( "Once you're finished, click the Done button to publish your changes, save a draft or revert back to the last published state.", 'fl-builder' ),
176
+ 'tourFinishedTitle' => esc_attr__( "Let's Get Building!", 'fl-builder' ),
177
+ 'tourFinished' => esc_attr__( "Now that you know the basics, you're ready to start building! If at any time you need help, click the help icon in the upper right corner to access the help menu. Happy building!", 'fl-builder' ),
178
+ 'unloadWarning' => esc_attr__( 'The settings you are currently editing will not be saved if you navigate away from this page.', 'fl-builder' ),
179
+ 'viewKnowledgeBase' => esc_attr__( 'View the Knowledge Base', 'fl-builder' ),
180
+ 'validateRequiredMessage' => esc_attr__( 'This field is required.', 'fl-builder' ),
181
+ 'visitForums' => esc_attr__( 'Contact Support', 'fl-builder' ),
182
+ 'watchHelpVideo' => esc_attr__( 'Watch the Video', 'fl-builder' ),
183
+ 'welcomeMessage' => esc_attr__( 'Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder' ),
184
+ 'uncategorized' => esc_attr__( 'Uncategorized', 'fl-builder' ),
185
+ 'yesPlease' => esc_attr__( 'Yes Please!', 'fl-builder' ),
186
+ 'savedStatus' => array(
187
+ 'saving' => esc_attr__( 'Saving...', 'fl-builder' ),
188
+ 'savingTooltip' => esc_attr__( 'The layout is currently being saved', 'fl-builder' ),
189
+ 'saved' => esc_attr__( 'Saved', 'fl-builder' ),
190
+ 'savedTooltip' => esc_attr__( 'The layout is saved', 'fl-builder' ),
191
+ 'edited' => esc_attr__( 'Edited', 'fl-builder' ),
192
+ 'editedTooltip' => esc_attr__( 'This layout has unpublished changes', 'fl-builder' ),
193
+ 'editedWarning' => esc_attr__( 'This layout has unpublished changes. If you discard this draft all of your previously unpublished changes will be lost.', 'fl-builder' ),
194
+ 'editedWarningDismiss' => esc_attr__( 'Ok, got it!', 'fl-builder' ),
195
+ 'noChanges' => esc_attr__( 'Nothing new to publish', 'fl-builder' ),
196
+ 'publishing' => esc_attr__( 'Publishing Changes', 'fl-builder' ),
197
+ 'publishingTooltip' => esc_attr__( 'Changes being published', 'fl-builder' ),
198
+ 'nothingToSave' => esc_attr__( 'No new changes to save', 'fl-builder' ),
199
+ 'hasAlreadySaved' => esc_attr__( 'Your changes are saved', 'fl-builder' ),
200
 
201
  ),
202
+ 'widgetsCategoryTitle' => esc_attr__( 'WordPress Widgets', 'fl-builder' ),
203
+ 'typeLabels' => array(
204
+ 'template' => esc_attr__( 'Template', 'fl-builder' ),
205
+ 'module' => esc_attr__( 'Module', 'fl-builder' ),
206
+ 'row' => esc_attr__( 'Row', 'fl-builder' ),
207
+ 'colGroup' => esc_attr__( 'Column Group', 'fl-builder' ),
208
+ 'widget' => esc_attr__( 'Widget', 'fl-builder' ),
209
  ),
210
+ 'categoryMeta' => array(
211
+ 'landing' => array(
212
+ 'name' => esc_attr__( 'Landing Pages', 'fl-builder' ),
213
  ),
214
+ 'company' => array(
215
+ 'name' => esc_attr__( 'Content Pages', 'fl-builder' ),
216
  ),
217
  ),
218
+ 'notifications' => array(
219
+ 'title' => esc_attr__( 'Notifications', 'fl-builder' ),
220
+ 'loading' => esc_attr__( 'Loading...', 'fl-builder' ),
221
+ 'none' => esc_attr__( 'No Notifications.', 'fl-builder' ),
222
+ ),
223
  ) ) ) . ';';
224
 
225
  FLBuilderFonts::js();
includes/ui-js-templates.php CHANGED
@@ -3,19 +3,19 @@
3
  <div class="fl-block-overlay-header">
4
  <div class="fl-block-overlay-actions">
5
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
6
- <i class="fa fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
7
  <# } else { #>
8
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
9
- <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
10
  <?php endif; ?>
11
- <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php _e( 'Row Settings', 'fl-builder' ); ?>"></i>
12
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
13
- <i class="fl-block-copy fa fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
14
  <?php endif; ?>
15
  <?php if ( ! $simple_ui ) : ?>
16
  <# if ( ! data.global || ( data.global && 'row' == FLBuilderConfig.userTemplateType ) ) { #>
17
  <span class="fl-builder-has-submenu">
18
- <i class="fl-block-col-settings fa fa-bars fl-tip" title="<?php _e( 'Row Actions', 'fl-builder' ); ?>"></i>
19
  <ul class="fl-builder-submenu fl-block-col-submenu">
20
  <li><a class="fl-block-col-reset" href="javascript:void(0);"><?php _e( 'Reset Column Widths', 'fl-builder' ); ?></a></li>
21
  <li><a class="fl-block-row-reset" href="javascript:void(0);"><?php _e( 'Reset Row Width', 'fl-builder' ); ?></a></li>
@@ -24,7 +24,7 @@
24
  <# } #>
25
  <?php endif; ?>
26
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
27
- <i class="fl-block-remove fa fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
28
  <?php endif; ?>
29
  <# } #>
30
  </div>
@@ -38,13 +38,19 @@
38
  <div class="fl-col-overlay fl-block-overlay<# if ( data.global ) { #> fl-block-overlay-global<# } #>">
39
  <div class="fl-block-overlay-header">
40
  <div class="fl-block-overlay-actions">
 
 
 
41
  <?php if ( ! $simple_ui ) : ?>
42
- <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
43
- <# if ( ( ! data.hasParentCol && data.numCols < 12 ) || ( data.hasParentCol && data.numCols < 4 ) ) { #>
44
- <i class="fl-block-copy fl-block-col-copy fa fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
 
 
45
  <# } #>
46
  <span class="fl-builder-has-submenu">
47
- <i class="fl-block-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
 
48
  <ul class="fl-builder-submenu fl-block-col-submenu">
49
  <li><a class="fl-block-col-edit" href="javascript:void(0);"><?php _e( 'Column Settings', 'fl-builder' ); ?></a></li>
50
  <# if ( data.numCols > 1 || ( data.hasParentCol && data.numParentCols > 1 ) ) { #>
@@ -55,13 +61,19 @@
55
  <# } #>
56
  <# if ( data.hasParentCol ) { #>
57
  <li class="fl-builder-submenu-sep"><div></div></li>
58
- <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
 
 
59
  <li><a class="fl-block-col-edit-parent" href="javascript:void(0);"><?php _e( 'Parent Settings', 'fl-builder' ); ?></a></li>
60
  <# } #>
61
  </ul>
 
62
  </span>
63
- <i class="fl-block-remove fa fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
 
 
64
  <?php endif; ?>
 
65
  </div>
66
  <div class="fl-clear"></div>
67
  </div>
@@ -116,18 +128,19 @@
116
  <div class="fl-block-overlay-header">
117
  <div class="fl-block-overlay-actions">
118
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
119
- <i class="fa fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
120
  <# } else { #>
121
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
122
- <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
123
  <?php endif; ?>
124
- <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php printf( __( '%s Settings', 'fl-builder' ), '{{data.moduleName}}' ); ?>"></i>
125
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
126
- <i class="fl-block-copy fa fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
127
  <span class="fl-builder-has-submenu">
128
- <i class="fl-block-col-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
 
129
  <ul class="fl-builder-submenu fl-block-col-submenu">
130
- <li><a class="fl-block-col-move" href="javascript:void(0);"><?php _e( 'Move Column', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
131
  <li><a class="fl-block-col-edit" href="javascript:void(0);"><?php _e( 'Column Settings', 'fl-builder' ); ?></a></li>
132
  <# if ( ( ! data.hasParentCol && data.numCols < 12 ) || ( data.hasParentCol && data.numCols < 4 ) ) { #>
133
  <li><a class="fl-block-col-copy" href="javascript:void(0);"><?php _e( 'Duplicate Column', 'fl-builder' ); ?></a></li>
@@ -141,19 +154,22 @@
141
  <# } #>
142
  <# if ( data.hasParentCol ) { #>
143
  <li class="fl-builder-submenu-sep"><div></div></li>
144
- <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fa fa-arrows"></i></a></li>
 
 
145
  <li><a class="fl-block-col-edit-parent" href="javascript:void(0);"><?php _e( 'Parent Settings', 'fl-builder' ); ?></a></li>
146
  <# } #>
147
  </ul>
 
148
  </span>
149
- <i class="fl-block-remove fa fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
150
  <?php endif; ?>
151
  <# } #>
152
  </div>
153
  <div class="fl-clear"></div>
154
  </div>
155
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
156
- <# if ( ! data.groupLoading ) { #>
157
  <# if ( ( ! data.colFirst && data.contentWidth > 40 ) || ( data.hasParentCol && data.colFirst && ! data.parentFirst ) ) { #>
158
  <div class="fl-block-col-resize fl-block-col-resize-w<# if ( data.hasParentCol && data.colFirst && ! data.parentFirst ) { #> fl-block-col-resize-parent<# } #>">
159
  <div class="fl-block-col-resize-handle-wrap">
@@ -200,15 +216,15 @@
200
 
201
  <script type="text/html" id="tmpl-fl-overlay-overflow-menu">
202
  <span class="fl-builder-has-submenu">
203
- <i class="fl-block-overflow-menu fa fa-bars fl-tip" title="<?php _e( 'More', 'fl-builder' ); ?>"></i>
204
  <ul class="fl-builder-submenu">
205
  <# for( var i = 0; i < data.length; i++ ) { #>
206
  <# if ( 'submenu' == data[ i ].type ) { #>
207
- <li class="fl-builder-has-submenu"><a href="javascript:void(0);">{{data[ i ].label}}<i class="fa fa-caret-right"></i></a>
208
  {{{data[ i ].submenu}}}
209
  </li>
210
  <# } else { #>
211
- <li><a class="{{data[ i ].className}}" href="javascript:void(0);">{{data[ i ].label}}<# if ( data[ i ].className.indexOf( 'fl-block-move' ) > -1 ) { #><i class="fa fa-arrows"></i><# } #></a>
212
  <# } #>
213
  <# } #>
214
  </ul>
@@ -377,7 +393,7 @@
377
  break;
378
  case "link":
379
  #>
380
- <a class="fl-builder--menu-item" href="{{{item.url}}}" data-type="link" target="_blank">{{item.label}} <span class="fl-builder--menu-item-accessory"><i class="fa fa-external-link"></i></span></a>
381
  <#
382
  break;
383
  case "view":
@@ -524,6 +540,9 @@
524
  </svg>
525
  </i>
526
  </button>
 
 
 
527
  </div>
528
  </script>
529
  <!-- #tmpl-fl-content-panel-base -->
@@ -663,7 +682,7 @@
663
  }
664
  }
665
  if (FLBuilderConfig.lite) { #>
666
- <div class="fl-builder--panel-cta"><a href="https://www.wpbeaverbuilder.com/?utm_medium=bb-lite&amp;utm_source=builder-ui&amp;utm_campaign=modules-panel-cta" target="_blank"><i class="fa fa-external-link-square"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ) ?></a></div>
667
  <# } #>
668
  </script>
669
  <!-- #tmpl-fl-content-panel-modules-view -->
@@ -696,7 +715,7 @@
696
  <# } #>
697
 
698
  <# if (FLBuilderConfig.lite) { #>
699
- <div class="fl-builder--panel-cta"><a href="https://www.wpbeaverbuilder.com/?utm_medium=bb-lite&amp;utm_source=builder-ui&amp;utm_campaign=modules-panel-cta" target="_blank"><i class="fa fa-external-link-square"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ) ?></a></div>
700
  <# } #>
701
  </div>
702
  </script>
@@ -706,7 +725,7 @@
706
  <# if (FLBuilderConfig.lite) { #>
707
  <div class="fl-builder--panel-message">
708
  <p><?php _ex( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'Upgrade message that displays in the templates tab in lite installs.', 'fl-builder' ) ?></p>
709
- <a class="fl-builder-upgrade-button fl-builder-button" href="{{FLBuilderConfig.upgradeUrl}}" target="_blank"><?php _ex( 'Learn More', 'Link to learn more about premium page builder', 'fl-builder' )?> <i class="fa fa-external-link-square"></i></a>
710
  </div>
711
  <# } #>
712
  <#
@@ -884,7 +903,7 @@
884
  <script type="text/html" id="tmpl-fl-content-lite-templates-upgrade-view">
885
  <div class="fl-builder--panel-message">
886
  <p><?php _ex( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'Upgrade message that displays in the templates tab in lite installs.', 'fl-builder' ) ?></p>
887
- <a class="fl-builder-upgrade-button fl-builder-button" href="{{FLBuilderConfig.upgradeUrl}}" target="_blank"><?php _ex( 'Learn More', 'Link to learn more about premium page builder', 'fl-builder' )?> <i class="fa fa-external-link-square"></i></a>
888
  </div>
889
  </script>
890
  <!-- #tmpl-fl-content-lite-templates-upgrade-view -->
3
  <div class="fl-block-overlay-header">
4
  <div class="fl-block-overlay-actions">
5
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
6
+ <i class="fas fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
7
  <# } else { #>
8
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
9
+ <i class="fl-block-move fas fa-arrows-alt fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
10
  <?php endif; ?>
11
+ <i class="fl-block-settings fas fa-wrench fl-tip" title="<?php _e( 'Row Settings', 'fl-builder' ); ?>"></i>
12
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
13
+ <i class="fl-block-copy far fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
14
  <?php endif; ?>
15
  <?php if ( ! $simple_ui ) : ?>
16
  <# if ( ! data.global || ( data.global && 'row' == FLBuilderConfig.userTemplateType ) ) { #>
17
  <span class="fl-builder-has-submenu">
18
+ <i class="fl-block-col-settings fas fa-bars fl-tip" title="<?php _e( 'Row Actions', 'fl-builder' ); ?>"></i>
19
  <ul class="fl-builder-submenu fl-block-col-submenu">
20
  <li><a class="fl-block-col-reset" href="javascript:void(0);"><?php _e( 'Reset Column Widths', 'fl-builder' ); ?></a></li>
21
  <li><a class="fl-block-row-reset" href="javascript:void(0);"><?php _e( 'Reset Row Width', 'fl-builder' ); ?></a></li>
24
  <# } #>
25
  <?php endif; ?>
26
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
27
+ <i class="fl-block-remove fas fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
28
  <?php endif; ?>
29
  <# } #>
30
  </div>
38
  <div class="fl-col-overlay fl-block-overlay<# if ( data.global ) { #> fl-block-overlay-global<# } #>">
39
  <div class="fl-block-overlay-header">
40
  <div class="fl-block-overlay-actions">
41
+ <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
42
+ <i class="fas fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
43
+ <# } else { #>
44
  <?php if ( ! $simple_ui ) : ?>
45
+ <# if ( ! data.isRootCol ) { #>
46
+ <i class="fl-block-move fas fa-arrows-alt fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
47
+ <# if ( ( ! data.hasParentCol && data.numCols < 12 ) || ( data.hasParentCol && data.numCols < 4 ) ) { #>
48
+ <i class="fl-block-copy fl-block-col-copy far fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
49
+ <# } #>
50
  <# } #>
51
  <span class="fl-builder-has-submenu">
52
+ <i class="fl-block-settings fas fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
53
+ <# if ( ! data.global || ( data.global && FLBuilderConfig.userTemplateType ) ) { #>
54
  <ul class="fl-builder-submenu fl-block-col-submenu">
55
  <li><a class="fl-block-col-edit" href="javascript:void(0);"><?php _e( 'Column Settings', 'fl-builder' ); ?></a></li>
56
  <# if ( data.numCols > 1 || ( data.hasParentCol && data.numParentCols > 1 ) ) { #>
61
  <# } #>
62
  <# if ( data.hasParentCol ) { #>
63
  <li class="fl-builder-submenu-sep"><div></div></li>
64
+ <# if ( 'column' != FLBuilderConfig.userTemplateType ) { #>
65
+ <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fas fa-arrows-alt"></i></a></li>
66
+ <# } #>
67
  <li><a class="fl-block-col-edit-parent" href="javascript:void(0);"><?php _e( 'Parent Settings', 'fl-builder' ); ?></a></li>
68
  <# } #>
69
  </ul>
70
+ <# } #>
71
  </span>
72
+ <# if ( ! data.isRootCol ) { #>
73
+ <i class="fl-block-remove fas fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
74
+ <# } #>
75
  <?php endif; ?>
76
+ <# } #>
77
  </div>
78
  <div class="fl-clear"></div>
79
  </div>
128
  <div class="fl-block-overlay-header">
129
  <div class="fl-block-overlay-actions">
130
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
131
+ <i class="fas fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
132
  <# } else { #>
133
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
134
+ <i class="fl-block-move fas fa-arrows-alt fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
135
  <?php endif; ?>
136
+ <i class="fl-block-settings fas fa-wrench fl-tip" title="<?php printf( __( '%s Settings', 'fl-builder' ), '{{data.moduleName}}' ); ?>"></i>
137
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
138
+ <i class="fl-block-copy far fa-clone fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
139
  <span class="fl-builder-has-submenu">
140
+ <i class="fl-block-col-settings fas fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
141
+ <# if ( ! data.isRootCol ) { #>
142
  <ul class="fl-builder-submenu fl-block-col-submenu">
143
+ <li><a class="fl-block-col-move" href="javascript:void(0);"><?php _e( 'Move Column', 'fl-builder' ); ?><i class="fas fa-arrows-alt"></i></a></li>
144
  <li><a class="fl-block-col-edit" href="javascript:void(0);"><?php _e( 'Column Settings', 'fl-builder' ); ?></a></li>
145
  <# if ( ( ! data.hasParentCol && data.numCols < 12 ) || ( data.hasParentCol && data.numCols < 4 ) ) { #>
146
  <li><a class="fl-block-col-copy" href="javascript:void(0);"><?php _e( 'Duplicate Column', 'fl-builder' ); ?></a></li>
154
  <# } #>
155
  <# if ( data.hasParentCol ) { #>
156
  <li class="fl-builder-submenu-sep"><div></div></li>
157
+ <# if ( 'column' != FLBuilderConfig.userTemplateType ) { #>
158
+ <li><a class="fl-block-col-move-parent" href="javascript:void(0);"><?php _e( 'Move Parent', 'fl-builder' ); ?><i class="fas fa-arrows-alt"></i></a></li>
159
+ <# } #>
160
  <li><a class="fl-block-col-edit-parent" href="javascript:void(0);"><?php _e( 'Parent Settings', 'fl-builder' ); ?></a></li>
161
  <# } #>
162
  </ul>
163
+ <# } #>
164
  </span>
165
+ <i class="fl-block-remove fas fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
166
  <?php endif; ?>
167
  <# } #>
168
  </div>
169
  <div class="fl-clear"></div>
170
  </div>
171
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
172
+ <# if ( ! data.groupLoading && ! data.isRootCol ) { #>
173
  <# if ( ( ! data.colFirst && data.contentWidth > 40 ) || ( data.hasParentCol && data.colFirst && ! data.parentFirst ) ) { #>
174
  <div class="fl-block-col-resize fl-block-col-resize-w<# if ( data.hasParentCol && data.colFirst && ! data.parentFirst ) { #> fl-block-col-resize-parent<# } #>">
175
  <div class="fl-block-col-resize-handle-wrap">
216
 
217
  <script type="text/html" id="tmpl-fl-overlay-overflow-menu">
218
  <span class="fl-builder-has-submenu">
219
+ <i class="fl-block-overflow-menu fas fa-bars fl-tip" title="<?php _e( 'More', 'fl-builder' ); ?>"></i>
220
  <ul class="fl-builder-submenu">
221
  <# for( var i = 0; i < data.length; i++ ) { #>
222
  <# if ( 'submenu' == data[ i ].type ) { #>
223
+ <li class="fl-builder-has-submenu"><a href="javascript:void(0);">{{data[ i ].label}}<i class="fas fa-caret-right"></i></a>
224
  {{{data[ i ].submenu}}}
225
  </li>
226
  <# } else { #>
227
+ <li><a class="{{data[ i ].className}}" href="javascript:void(0);">{{data[ i ].label}}<# if ( data[ i ].className.indexOf( 'fl-block-move' ) > -1 ) { #><i class="fas fa-arrows-alt"></i><# } #></a>
228
  <# } #>
229
  <# } #>
230
  </ul>
393
  break;
394
  case "link":
395
  #>
396
+ <a class="fl-builder--menu-item" href="{{{item.url}}}" data-type="link" target="_blank">{{item.label}} <span class="fl-builder--menu-item-accessory"><i class="fas fa-external-link-alt"></i></span></a>
397
  <#
398
  break;
399
  case "view":
540
  </svg>
541
  </i>
542
  </button>
543
+ <div class="fl-builder--panel-no-settings">
544
+ <div><?php _e( 'No settings selected.', 'fl-builder' ); ?></div>
545
+ </div>
546
  </div>
547
  </script>
548
  <!-- #tmpl-fl-content-panel-base -->
682
  }
683
  }
684
  if (FLBuilderConfig.lite) { #>
685
+ <div class="fl-builder--panel-cta"><a href="https://www.wpbeaverbuilder.com/?utm_medium=bb-lite&amp;utm_source=builder-ui&amp;utm_campaign=modules-panel-cta" target="_blank"><i class="fas fa-external-link-alt"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ) ?></a></div>
686
  <# } #>
687
  </script>
688
  <!-- #tmpl-fl-content-panel-modules-view -->
715
  <# } #>
716
 
717
  <# if (FLBuilderConfig.lite) { #>
718
+ <div class="fl-builder--panel-cta"><a href="https://www.wpbeaverbuilder.com/?utm_medium=bb-lite&amp;utm_source=builder-ui&amp;utm_campaign=modules-panel-cta" target="_blank"><i class="fas fa-external-link-alt"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ) ?></a></div>
719
  <# } #>
720
  </div>
721
  </script>
725
  <# if (FLBuilderConfig.lite) { #>
726
  <div class="fl-builder--panel-message">
727
  <p><?php _ex( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'Upgrade message that displays in the templates tab in lite installs.', 'fl-builder' ) ?></p>
728
+ <a class="fl-builder-upgrade-button fl-builder-button" href="{{FLBuilderConfig.upgradeUrl}}" target="_blank"><?php _ex( 'Learn More', 'Link to learn more about premium page builder', 'fl-builder' )?> <i class="fas fa-external-link-alt"></i></a>
729
  </div>
730
  <# } #>
731
  <#
903
  <script type="text/html" id="tmpl-fl-content-lite-templates-upgrade-view">
904
  <div class="fl-builder--panel-message">
905
  <p><?php _ex( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'Upgrade message that displays in the templates tab in lite installs.', 'fl-builder' ) ?></p>
906
+ <a class="fl-builder-upgrade-button fl-builder-button" href="{{FLBuilderConfig.upgradeUrl}}" target="_blank"><?php _ex( 'Learn More', 'Link to learn more about premium page builder', 'fl-builder' )?> <i class="fas fa-external-link-alt"></i></a>
907
  </div>
908
  </script>
909
  <!-- #tmpl-fl-content-lite-templates-upgrade-view -->
includes/ui-legacy-custom-field.php CHANGED
@@ -29,7 +29,7 @@
29
  ?>
30
  <?php if ( isset( $field['help'] ) ) : ?>
31
  <span class="fl-help-tooltip">
32
- <i class="fl-help-tooltip-icon fa fa-question-circle"></i>
33
  <span class="fl-help-tooltip-text"><?php echo $field['help']; ?></span>
34
  </span>
35
  <?php endif; ?>
@@ -74,7 +74,7 @@
74
  if ( $responsive ) {
75
  echo '</div>';
76
  }
77
- }// End foreach().
78
 
79
  ?>
80
  <?php if ( isset( $field['description'] ) ) : ?>
29
  ?>
30
  <?php if ( isset( $field['help'] ) ) : ?>
31
  <span class="fl-help-tooltip">
32
+ <i class="fl-help-tooltip-icon fas fa-question-circle"></i>
33
  <span class="fl-help-tooltip-text"><?php echo $field['help']; ?></span>
34
  </span>
35
  <?php endif; ?>
74
  if ( $responsive ) {
75
  echo '</div>';
76
  }
77
+ }
78
 
79
  ?>
80
  <?php if ( isset( $field['description'] ) ) : ?>
includes/ui-loop-settings.php CHANGED
@@ -105,6 +105,17 @@ do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custo
105
  'help' => __( 'Skip this many posts that match the specified criteria.', 'fl-builder' ),
106
  ), $settings);
107
 
 
 
 
 
 
 
 
 
 
 
 
108
  ?>
109
  </table>
110
  </div>
105
  'help' => __( 'Skip this many posts that match the specified criteria.', 'fl-builder' ),
106
  ), $settings);
107
 
108
+ FLBuilder::render_settings_field('exclude_self', array(
109
+ 'type' => 'select',
110
+ 'label' => __( 'Exclude Current Post', 'fl-builder' ),
111
+ 'default' => 'no',
112
+ 'help' => __( 'Exclude the current post from the query.' ),
113
+ 'options' => array(
114
+ 'yes' => __( 'Yes', 'fl-builder' ),
115
+ 'no' => __( 'No', 'fl-builder' ),
116
+ ),
117
+ ), $settings);
118
+
119
  ?>
120
  </table>
121
  </div>
includes/ui-settings-config.php CHANGED
@@ -1,4 +1,7 @@
1
  ( function( $ ) {
2
  FLBuilderSettingsConfig = 'undefined' === typeof FLBuilderSettingsConfig ? {} : FLBuilderSettingsConfig;
3
- $.extend( FLBuilderSettingsConfig, <?php echo json_encode( FLBuilderUISettingsForms::get_js_config() ); ?> );
 
 
 
4
  } )( jQuery );
1
  ( function( $ ) {
2
  FLBuilderSettingsConfig = 'undefined' === typeof FLBuilderSettingsConfig ? {} : FLBuilderSettingsConfig;
3
+ $.extend( FLBuilderSettingsConfig, <?php echo json_encode( $settings ); ?> );
4
+ if ( 'undefined' !== typeof FLBuilder ) {
5
+ FLBuilder.triggerHook( 'settingsConfigLoaded' );
6
+ }
7
  } )( jQuery );
includes/ui-settings-form-row.php CHANGED
@@ -15,9 +15,9 @@
15
  <# var field = FLBuilderSettingsForms.renderField( data ); #>
16
  {{{field}}}
17
  <td class="fl-builder-field-actions">
18
- <i class="fl-builder-field-move fa fa-arrows"></i>
19
- <i class="fl-builder-field-copy fa fa-copy"></i>
20
- <i class="fl-builder-field-delete fa fa-times"></i>
21
  </td>
22
  </tr>
23
  <# } #>
15
  <# var field = FLBuilderSettingsForms.renderField( data ); #>
16
  {{{field}}}
17
  <td class="fl-builder-field-actions">
18
+ <i class="fl-builder-field-move fas fa-arrows-alt"></i>
19
+ <i class="fl-builder-field-copy far fa-copy"></i>
20
+ <i class="fl-builder-field-delete fas fa-times"></i>
21
  </td>
22
  </tr>
23
  <# } #>
includes/updater-config.php CHANGED
@@ -3,7 +3,7 @@
3
  if ( class_exists( 'FLUpdater' ) ) {
4
  FLUpdater::add_product(array(
5
  'name' => 'Beaver Builder Plugin (Lite Version)',
6
- 'version' => '2.0.6.4',
7
  'slug' => 'bb-plugin',
8
  'type' => 'plugin',
9
  ));
3
  if ( class_exists( 'FLUpdater' ) ) {
4
  FLUpdater::add_product(array(
5
  'name' => 'Beaver Builder Plugin (Lite Version)',
6
+ 'version' => '2.1.1.2',
7
  'slug' => 'bb-plugin',
8
  'type' => 'plugin',
9
  ));
includes/updater/classes/class-fl-updater.php CHANGED
@@ -150,7 +150,7 @@ final class FLUpdater {
150
  );
151
  }
152
  }
153
- }// End if().
154
 
155
  return $transient;
156
  }
@@ -284,11 +284,7 @@ final class FLUpdater {
284
  if ( isset( $subscription->error ) || ! $subscription->active || ! $subscription->domain->active || ! isset( $subscription->downloads ) ) {
285
  return;
286
  }
287
-
288
- $default = __( 'Page Builder', 'fl-builder' );
289
- $branding = FLBuilderModel::get_branding();
290
-
291
- if ( $default == $branding ) {
292
  include FL_UPDATER_DIR . 'includes/subscriptions.php';
293
  }
294
  }
@@ -310,17 +306,17 @@ final class FLUpdater {
310
  *
311
  * @since 1.0
312
  * @param string $license The new license key.
313
- * @return void
314
  */
315
  static public function save_subscription_license( $license ) {
316
- FLUpdater::api_request(self::$_updates_api_url, array(
317
  'fl-api-method' => 'activate_domain',
318
  'license' => $license,
319
  'domain' => network_home_url(),
320
  'products' => json_encode( self::$_products ),
321
  ));
322
-
323
  update_site_option( 'fl_themes_subscription_email', $license );
 
324
  }
325
 
326
  /**
@@ -346,18 +342,36 @@ final class FLUpdater {
346
  * @return string
347
  */
348
  static private function get_update_error_message( $plugin_data = null ) {
349
- $message = '';
350
- $message .= '<span style="display:block;padding:10px 20px;margin:10px 0; background: #d54e21; color: #fff;">';
351
- $message .= __( '<strong>UPDATE UNAVAILABLE!</strong>', 'fl-builder' );
352
- $message .= '&nbsp;&nbsp;&nbsp;';
353
- $message .= __( 'Please subscribe to enable automatic updates for this plugin.', 'fl-builder' );
354
-
355
- if ( $plugin_data && isset( $plugin_data['PluginURI'] ) ) {
356
- $message .= ' <a href="' . $plugin_data['PluginURI'] . '" target="_blank" style="color: #fff; text-decoration: underline;">';
357
- $message .= __( 'Subscribe Now', 'fl-builder' );
358
- $message .= ' &raquo;</a>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  }
360
- $message .= '</span>';
361
  return $message;
362
  }
363
 
150
  );
151
  }
152
  }
153
+ }
154
 
155
  return $transient;
156
  }
284
  if ( isset( $subscription->error ) || ! $subscription->active || ! $subscription->domain->active || ! isset( $subscription->downloads ) ) {
285
  return;
286
  }
287
+ if ( ! FLBuilderModel::is_white_labeled() ) {
 
 
 
 
288
  include FL_UPDATER_DIR . 'includes/subscriptions.php';
289
  }
290
  }
306
  *
307
  * @since 1.0
308
  * @param string $license The new license key.
309
+ * @return $response mixed
310
  */
311
  static public function save_subscription_license( $license ) {
312
+ $response = FLUpdater::api_request(self::$_updates_api_url, array(
313
  'fl-api-method' => 'activate_domain',
314
  'license' => $license,
315
  'domain' => network_home_url(),
316
  'products' => json_encode( self::$_products ),
317
  ));
 
318
  update_site_option( 'fl_themes_subscription_email', $license );
319
+ return $response;
320
  }
321
 
322
  /**
342
  * @return string
343
  */
344
  static private function get_update_error_message( $plugin_data = null ) {
345
+
346
+ $subscription = FLUpdater::get_subscription_info();
347
+ $license = get_site_option( 'fl_themes_subscription_email' );
348
+ $message = '';
349
+
350
+ // updates-core.php
351
+ if ( ! $plugin_data ) {
352
+
353
+ if ( ! $license ) {
354
+ $message = __( 'Please enter a valid license key to enable automatic updates.', 'fl-builder' );
355
+
356
+ } else {
357
+ $message = __( 'Please subscribe to enable automatic updates for this plugin.', 'fl-builder' );
358
+ }
359
+ } else { // plugins.php
360
+
361
+ if ( ! $license ) {
362
+ $link = sprintf( '<a href="%s" target="_blank" style="color: #fff; text-decoration: underline;">%s &raquo;</a>', admin_url( '/options-general.php?page=fl-builder-settings#license' ), __( 'Enter License Key', 'fl-builder' ) );
363
+ $text = sprintf( __( 'Please enter a valid license key to enable automatic updates. %s', 'fl-builder' ), $link );
364
+ } else {
365
+ $link = sprintf( '<a href="%s" target="_blank" style="color: #fff; text-decoration: underline;">%s &raquo;</a>', $plugin_data['PluginURI'], __( 'Subscribe Now', 'fl-builder' ) );
366
+ $text = sprintf( __( 'Please subscribe to enable automatic updates for this plugin. %s', 'fl-builder' ), $link );
367
+ }
368
+
369
+ $message .= '<span style="display:block;padding:10px 20px;margin:10px 0; background: #d54e21; color: #fff;">';
370
+ $message .= __( '<strong>UPDATE UNAVAILABLE!</strong>', 'fl-builder' );
371
+ $message .= '&nbsp;&nbsp;&nbsp;';
372
+ $message .= $text;
373
+ $message .= '</span>';
374
  }
 
375
  return $message;
376
  }
377
 
includes/vendor/getresponse/getresponse.php CHANGED
@@ -1,576 +1,406 @@
1
  <?php
2
 
3
  /**
4
- * GetResponsePHP is a PHP5 implementation of the GetResponse API
5
- * @internal This wrapper is incomplete and subject to change.
6
- * @authors Ben Tadiar <ben@bentadiar.co.uk>, Robert Staddon <robert@abundantdesigns.com>
7
- * @copyright Copyright (c) 2010 Assembly Studios
8
- * @link http://www.assemblystudios.co.uk
9
- * @package GetResponsePHP
10
- * @version 0.1.1
11
- */
12
-
13
- /**
14
- * GetResponse Class
15
- * @package GetResponsePHP
16
  */
17
  class GetResponse
18
- {
19
- /**
20
- * GetResponse API key
21
- * http://www.getresponse.com/my_api_key.html
22
- * @var string
23
- */
24
- public $apiKey = 'PASS_API_KEY_WHEN_INSTANTIATING_CLASS';
25
-
26
- /**
27
- * GetResponse API URL
28
- * @var string
29
- * @access private
30
- */
31
- private $apiURL = 'http://api2.getresponse.com';
32
-
33
- /**
34
- * Text comparison operators used to filter results
35
- * @var array
36
- * @access private
37
- */
38
- private $textOperators = array('EQUALS', 'NOT_EQUALS', 'CONTAINS', 'NOT_CONTAINS', 'MATCHES');
39
-
40
- /**
41
- * Check cURL extension is loaded and that an API key has been passed
42
- * @param string $apiKey GetResponse API key
43
- * @return void
44
- */
45
- public function __construct($apiKey = null)
46
- {
47
- if(!extension_loaded('curl')) trigger_error('GetResponsePHP requires PHP cURL', E_USER_ERROR);
48
- if(is_null($apiKey)) trigger_error('API key must be supplied', E_USER_ERROR);
49
- $this->apiKey = $apiKey;
50
- }
51
-
52
- /**
53
- * Test connection to the API, returns "pong" on success
54
- * @return string
55
- */
56
- public function ping()
57
- {
58
- $request = $this->prepRequest('ping');
59
- $response = $this->execute($request);
60
- return $response->ping;
61
- }
62
-
63
- /**
64
- * Get basic user account information
65
- * @return object
66
- */
67
- public function getAccountInfo()
68
- {
69
- $request = $this->prepRequest('get_account_info');
70
- $response = $this->execute($request);
71
- return $response;
72
- }
73
-
74
- /**
75
- * Get list of email addresses assigned to account
76
- * @return object
77
- */
78
- public function getAccountFromFields()
79
- {
80
- $request = $this->prepRequest('get_account_from_fields');
81
- $response = $this->execute($request);
82
- return $response;
83
- }
84
-
85
- /**
86
- * Get single email address assigned to an account using the account From Field ID
87
- * @param string $id
88
- * @return object
89
- */
90
- public function getAccountFromFieldByID($id)
91
- {
92
- $request = $this->prepRequest('get_account_from_field', array('account_from_field' => $id));
93
- $response = $this->execute($request);
94
- return $response;
95
- }
96
-
97
- /**
98
- * Get single email address assigned to an account using an email address
99
- * @param string $email
100
- * @return object
101
- */
102
- public function getAccountFromFieldsByEmail($email)
103
- {
104
- $request = $this->prepRequest('get_account_from_fields');
105
- $response = $this->execute($request);
106
- foreach($response as $key => $account) if($account->email!=$email) unset($response->$key);
107
- return $response;
108
- }
109
-
110
- /**
111
- * Get a list of active campaigns, optionally filtered
112
- * @param string $operator Comparison operator
113
- * @param string $comparison Text/expression to compare against
114
- * @return object
115
- */
116
- public function getCampaigns($operator = 'CONTAINS', $comparison = '%')
117
- {
118
- $params = null;
119
- if(in_array($operator, $this->textOperators)) $params = array('name' => array($operator => $comparison));
120
- $request = $this->prepRequest('get_campaigns', $params);
121
- $response = $this->execute($request);
122
- return $response;
123
- }
124
-
125
- /**
126
- * Return a campaign by ID
127
- * @param string $id Campaign ID
128
- * @return object
129
- */
130
- public function getCampaignByID($id)
131
- {
132
- $request = $this->prepRequest('get_campaign', array('campaign' => $id));
133
- $response = $this->execute($request);
134
- return $response;
135
- }
136
-
137
- /**
138
- * Return a campaign ID by name
139
- * @param string $name Campaign Name
140
- * @return string Campaign ID
141
- */
142
- public function getCampaignByName($name)
143
- {
144
- $request = $this->prepRequest('get_campaigns', array('name' => array('EQUALS' => $name)));
145
- $response = $this->execute($request);
146
- return key($response);
147
- }
148
-
149
- /**
150
- * Return a list of messages, optionally filtered by multiple conditions
151
- * @todo Implement all conditions, this is unfinished
152
- * @param array|null $campaigns Optional argument to narrow results by campaign ID
153
- * @param string|null $type Optional argument to narrow results by "newsletter", "autoresponder", or "draft"
154
- * @param string $operator
155
- * @param string $comparison
156
- * @return object
157
- */
158
- public function getMessages($campaigns = null, $type = null, $operator = 'CONTAINS', $comparison = '%')
159
- {
160
- $params = null;
161
- if(is_array($campaigns)) $params['campaigns'] = $campaigns;
162
- if(is_string($type)) $params['type'] = $type;
163
- $request = $this->prepRequest('get_messages', $params);
164
- $response = $this->execute($request);
165
- return $response;
166
- }
167
-
168
- /**
169
- * Return a message by ID
170
- * @param string $id Message ID
171
- * @return object
172
- */
173
- public function getMessageByID($id)
174
- {
175
- $request = $this->prepRequest('get_message', array('message' => $id));
176
- $response = $this->execute($request);
177
- return $response;
178
- }
179
-
180
- /**
181
- * Return an autoresponder message from a campaign by Cycle Day
182
- * @param string $campaign Campaign ID
183
- * @param string $cycle_day Cycle Day
184
- * @return object
185
- */
186
- public function getMessageByCycleDay($campaign, $cycle_day)
187
- {
188
- $params['campaigns'] = array($campaign);
189
- $params['type'] = "autoresponder";
190
- $request = $this->prepRequest('get_messages', $params);
191
- $response = $this->execute($request);
192
- foreach($response as $key => $message) if($message->day_of_cycle!=$cycle_day) unset($response->$key);
193
- return $response;
194
- }
195
-
196
- /**
197
- * Return message contents by ID
198
- * @param string $id Message ID
199
- * @return object
200
- */
201
- public function getMessageContents($id)
202
- {
203
- $request = $this->prepRequest('get_message_contents', array('message' => $id));
204
- $response = $this->execute($request);
205
- return $response;
206
- }
207
-
208
- /**
209
- * Return message statistics
210
- * @param string $message Message ID
211
- * @param string $grouping grouping
212
- * @return object|null
213
- */
214
- public function getMessageStats($message, $grouping = "yearly")
215
- {
216
- $params['message'] = $message;
217
- $params['grouping'] = $grouping;
218
- $request = $this->prepRequest('get_message_stats', $params);
219
- $response = $this->execute($request);
220
- return $response;
221
- }
222
-
223
- /**
224
- * Return autoresponder message contents by Cycle Day
225
- * @param string $campaign Campaign ID
226
- * @param string $cycle_day Cycle Day
227
- * @return object|null
228
- */
229
- public function getMessageContentsByCycleDay($campaign, $cycle_day)
230
- {
231
- $params['campaigns'] = array($campaign);
232
- $params['type'] = "autoresponder";
233
- $request = $this->prepRequest('get_messages', $params);
234
- $response = $this->execute($request);
235
- foreach($response as $key => $message) if($message->day_of_cycle==$cycle_day) return $this->getMessageContents($key);
236
- return null;
237
- }
238
-
239
- /**
240
- * Add autoresponder to a campaign at a specific day of cycle
241
- * @param string $campaign Campaign ID
242
- * @param string $subject Subject of message
243
- * @param array $contents Allowed keys are "plain" and "html", at least one is mandatory
244
- * @param int $cycle_day
245
- * @param string $from_field From Field ID obtained through getAccountFromFields()
246
- * @param array $flags Enables extra functionality for a message: "clicktrack", "subscription_reminder", "openrate", "google_analytics"
247
- * @return object
248
- */
249
- public function addAutoresponder($campaign, $subject, $cycle_day, $html = null, $plain = null, $from_field = null, $flags = null)
250
- {
251
- $params = array('campaign' => $campaign, 'subject' => $subject, 'day_of_cycle' => $cycle_day);
252
- if(is_string($html)) $params['contents']['html'] = $html;
253
- if(is_string($plain)) $params['contents']['plain'] = $plain;
254
- if(is_string($from_field)) $params['from_field'] = $from_field;
255
- if(is_array($flags)) $params['flags'] = $flags;
256
- $request = $this->prepRequest('add_autoresponder', $params);
257
- $response = $this->execute($request);
258
- return $response;
259
- }
260
-
261
- /**
262
- * Delete an autoresponder
263
- * @param string $id
264
- * @return object
265
- */
266
- public function deleteAutoresponder($id)
267
- {
268
- $request = $this->prepRequest('delete_autoresponder', array('message' => $id));
269
- $response = $this->execute($request);
270
- return $response;
271
- }
272
-
273
- /**
274
- * Return a list of contacts, optionally filtered by multiple conditions
275
- * @todo Implement all conditions, this is unfinished
276
- * @param array|null $campaigns Optional argument to narrow results by campaign ID
277
- * @param string $operator Optional argument to change operator (default is 'CONTAINS')
278
- * See https://github.com/GetResponse/DevZone/tree/master/API#operators for additional operator options
279
- * @param string $comparison
280
- * @param array $fields (an associative array, the keys of which should enable/disable comparing name or email)
281
- * @return object
282
- */
283
- public function getContacts($campaigns = null, $operator = 'CONTAINS', $comparison = '%', $fields = array('name' => true, 'email' => false))
284
- {
285
- $params = null;
286
- if(is_array($campaigns)) $params['campaigns'] = $campaigns;
287
- if($fields['name']) $params['name'] = $this->prepTextOp($operator, $comparison);
288
- if($fields['email']) $params['email'] = $this->prepTextOp($operator, $comparison);
289
- $request = $this->prepRequest('get_contacts', $params);
290
- $response = $this->execute($request);
291
- return $response;
292
- }
293
-
294
- /**
295
- * Return a list of contacts by email address (optionally narrowed by campaign)
296
- * @param string $email Email Address of Contact (or a string contained in the email address)
297
- * @param array|null $campaigns Optional argument to narrow results by campaign ID
298
- * @param string $operator Optional argument to change operator (default is 'CONTAINS')
299
- * See https://github.com/GetResponse/DevZone/tree/master/API#operators for additional operator options
300
- * @return object
301
- */
302
- public function getContactsByEmail($email, $campaigns = null, $operator = 'CONTAINS')
303
- {
304
- $params = null;
305
- $params['email'] = $this->prepTextOp($operator, $email);
306
- if(is_array($campaigns)) $params['campaigns'] = $campaigns;
307
- $request = $this->prepRequest('get_contacts', $params);
308
- $response = $this->execute($request);
309
- return $response;
310
- }
311
-
312
- /**
313
- * Return a list of contacts filtered by custom contact information
314
- * $customs is an associative arrays, the keys of which should correspond to the
315
- * custom field names of the customers you wish to retrieve.
316
- * @param array|null $campaigns Optional argument to narrow results by campaign ID
317
- * @param string $operator
318
- * @param array $customs
319
- * @param string $comparison
320
- * @return object
321
- */
322
- public function getContactsByCustoms($campaigns = null, $customs, $operator = 'EQUALS')
323
- {
324
- $params = null;
325
- if(is_array($campaigns)) $params['campaigns'] = $campaigns;
326
- if(!is_array($customs)) trigger_error('Second argument must be an array', E_USER_ERROR);
327
- foreach($customs as $key => $val) $params['customs'][] = array('name' => $key, 'content' => $this->prepTextOp($operator, $val));
328
- $request = $this->prepRequest('get_contacts', $params);
329
- $response = $this->execute($request);
330
- return $response;
331
- }
332
-
333
- /**
334
- * Return a contact by ID
335
- * @param string $id User ID
336
- * @return object
337
- */
338
- public function getContactByID($id)
339
- {
340
- $request = $this->prepRequest('get_contact', array('contact' => $id));
341
- $response = $this->execute($request);
342
- return $response;
343
- }
344
-
345
-
346
- /**
347
- * Set a contact name
348
- * @param string $id User ID
349
- * @return object
350
- */
351
- public function setContactName($id, $name)
352
- {
353
- $request = $this->prepRequest('set_contact_name', array('contact' => $id, 'name' => $name));
354
- $response = $this->execute($request);
355
- return $response;
356
- }
357
-
358
- /**
359
- * Set a contact cycle
360
- * @param string $id User ID
361
- * @param int $cycle_day Cycle Day
362
- * @return object
363
- */
364
- public function setContactCycle($id, $cycle_day)
365
- {
366
- $request = $this->prepRequest('set_contact_cycle', array('contact' => $id, 'cycle_day' => $cycle_day));
367
- $response = $this->execute($request);
368
- return $response;
369
- }
370
-
371
- /**
372
- * Set a contact campaign
373
- * @param string $id User ID
374
- * @param string $campaign Campaign ID
375
- * @return object
376
- */
377
- public function setContactCampaign($id, $campaign)
378
- {
379
- $request = $this->prepRequest('move_contact', array('contact' => $id, 'campaign' => $campaign));
380
- $response = $this->execute($request);
381
- return $response;
382
- }
383
-
384
- /**
385
- * Return a contacts custom information
386
- * @param string $id User ID
387
- * @return object
388
- */
389
- public function getContactCustoms($id)
390
- {
391
- $request = $this->prepRequest('get_contact_customs', array('contact' => $id));
392
- $response = $this->execute($request);
393
- return $response;
394
- }
395
-
396
-
397
- /**
398
- * Set custom contact information
399
- * $customs is an associative array, the keys of which should correspond to the
400
- * custom field name you wish to add/modify/remove.
401
- * Actions: added if not present, updated if present, removed if value is null
402
- * @todo Implement multivalue customs.
403
- * @param string $id User ID
404
- * @param array $customs
405
- * @return object
406
- */
407
- public function setContactCustoms($id, $customs)
408
- {
409
- if(!is_array($customs)) trigger_error('Second argument must be an array', E_USER_ERROR);
410
- foreach($customs as $key => $val) $params[] = array('name' => $key, 'content' => $val);
411
- $request = $this->prepRequest('set_contact_customs', array('contact' => $id, 'customs' => $params));
412
- $response = $this->execute($request);
413
- return $response;
414
- }
415
-
416
- /**
417
- * Return a contacts GeoIP
418
- * @param string $id User ID
419
- * @return object
420
- */
421
- public function getContactGeoIP($id)
422
- {
423
- $request = $this->prepRequest('get_contact_geoip', array('contact' => $id));
424
- $response = $this->execute($request);
425
- return $response;
426
- }
427
-
428
- /**
429
- * List dates when the messages were opened by contacts
430
- * @param string $id User ID
431
- * @return object
432
- */
433
- public function getContactOpens($id)
434
- {
435
- $request = $this->prepRequest('get_contact_opens', array('contact' => $id));
436
- $response = $this->execute($request);
437
- return $response;
438
- }
439
-
440
- /**
441
- * List dates when the links in messages were clicked by contacts
442
- * @param string $id User ID
443
- * @return object
444
- */
445
- public function getContactClicks($id)
446
- {
447
- $request = $this->prepRequest('get_contact_clicks', array('contact' => $id));
448
- $response = $this->execute($request);
449
- return $response;
450
- }
451
-
452
- /**
453
- * Add contact to the specified list (Requires email verification by contact)
454
- * The return value of this function will be "queued", and on subsequent
455
- * submission of the same email address will be "duplicated".
456
- * @param string $campaign Campaign ID
457
- * @param string $name Name of contact
458
- * @param string $email Email address of contact
459
- * @param string $action Standard, insert or update
460
- * @param int $cycle_day
461
- * @param array $customs
462
- * @return object
463
- */
464
- public function addContact($campaign, $name, $email, $action = 'standard', $cycle_day = 0, $customs = array())
465
- {
466
- $params = array('campaign' => $campaign, 'action' => $action, 'name' => $name,
467
- 'email' => $email, 'cycle_day' => $cycle_day, 'ip' => $_SERVER['REMOTE_ADDR']);
468
- if(!empty($customs)) {
469
- foreach($customs as $key => $val) $c[] = array('name' => $key, 'content' => $val);
470
- $params['customs'] = $c;
471
- }
472
- $request = $this->prepRequest('add_contact', $params);
473
- $response = $this->execute($request);
474
- return $response;
475
- }
476
-
477
- /**
478
- * Delete a contact
479
- * @param string $id
480
- * @return object
481
- */
482
- public function deleteContact($id)
483
- {
484
- $request = $this->prepRequest('delete_contact', array('contact' => $id));
485
- $response = $this->execute($request);
486
- return $response;
487
- }
488
-
489
- /**
490
- * Get blacklist masks on account level
491
- * Account is determined by API key
492
- * @return object
493
- */
494
- public function getAccountBlacklist()
495
- {
496
- $request = $this->prepRequest('get_account_blacklist');
497
- $response = $this->execute($request);
498
- return $response;
499
- }
500
-
501
- /**
502
- * Adds blacklist mask on account level
503
- * @param string $mask
504
- * @return object
505
- */
506
- public function addAccountBlacklist($mask)
507
- {
508
- $request = $this->prepRequest('add_account_blacklist', array('mask' => $mask));
509
- $response = $this->execute($request);
510
- return $response;
511
- }
512
-
513
- /**
514
- * Delete blacklist mask on account level
515
- * @param string $mask
516
- * @return object
517
- */
518
- public function deleteAccountBlacklist($mask)
519
- {
520
- $request = $this->prepRequest('delete_account_blacklist', array('mask' => $mask));
521
- $response = $this->execute($request);
522
- return $response;
523
- }
524
-
525
- /**
526
- * Return a key => value array for text comparison
527
- * @param string $operator
528
- * @param mixed $comparison
529
- * @return array
530
- * @access private
531
- */
532
- private function prepTextOp($operator, $comparison)
533
- {
534
- if(!in_array($operator, $this->textOperators)) trigger_error('Invalid text operator', E_USER_ERROR);
535
- if($operator === 'CONTAINS') $comparison = '%'.$comparison.'%';
536
- return array($operator => $comparison);
537
- }
538
-
539
- /**
540
- * Return array as a JSON encoded string
541
- * @param string $method API method to call
542
- * @param array $params Array of parameters
543
- * @return string JSON encoded string
544
- * @access private
545
- */
546
- private function prepRequest($method, $params = null, $id = null)
547
- {
548
- $array = array($this->apiKey);
549
- if(!is_null($params)) $array[1] = $params;
550
- $request = json_encode(array('method' => $method, 'params' => $array, 'id' => $id));
551
- return $request;
552
- }
553
-
554
- /**
555
- * Executes an API call
556
- * @param string $request JSON encoded array
557
- * @return object
558
- * @access private
559
- */
560
- private function execute($request)
561
- {
562
- $handle = curl_init($this->apiURL);
563
- curl_setopt($handle, CURLOPT_POST, 1);
564
- curl_setopt($handle, CURLOPT_POSTFIELDS, $request);
565
- curl_setopt($handle, CURLOPT_HEADER, 'Content-type: application/json');
566
- curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
567
- $response = json_decode(curl_exec($handle));
568
- if(curl_error($handle)) trigger_error(curl_error($handle), E_USER_ERROR);
569
- $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
570
- if(!(($httpCode == '200') || ($httpCode == '204'))) trigger_error('API call failed. Server returned status code '.$httpCode, E_USER_ERROR);
571
- curl_close($handle);
572
- if(!$response->error) return $response->result;
573
- }
574
- }
575
 
576
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
  /**
4
+ * GetResponse API v3 client library
5
+ *
6
+ * @author Pawel Maslak <pawel.maslak@getresponse.com>
7
+ * @author Grzegorz Struczynski <grzegorz.struczynski@implix.com>
8
+ *
9
+ * @see http://apidocs.getresponse.com/en/v3/resources
10
+ * @see https://github.com/GetResponse/getresponse-api-php
 
 
 
 
 
11
  */
12
  class GetResponse
13
+ {
14
+
15
+ private $api_key;
16
+ private $api_url = 'https://api.getresponse.com/v3';
17
+ private $timeout = 8;
18
+ public $http_status;
19
+
20
+ /**
21
+ * X-Domain header value if empty header will be not provided
22
+ * @var string|null
23
+ */
24
+ private $enterprise_domain = null;
25
+
26
+ /**
27
+ * X-APP-ID header value if empty header will be not provided
28
+ * @var string|null
29
+ */
30
+ private $app_id = null;
31
+
32
+ /**
33
+ * Set api key and optionally API endpoint
34
+ * @param $api_key
35
+ * @param null $api_url
36
+ */
37
+ public function __construct($api_key, $api_url = null)
38
+ {
39
+ $this->api_key = $api_key;
40
+
41
+ if (!empty($api_url)) {
42
+ $this->api_url = $api_url;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * We can modify internal settings
48
+ * @param $key
49
+ * @param $value
50
+ */
51
+ function __set($key, $value)
52
+ {
53
+ $this->{$key} = $value;
54
+ }
55
+
56
+ /**
57
+ * get account details
58
+ *
59
+ * @return mixed
60
+ */
61
+ public function accounts()
62
+ {
63
+ return $this->call('accounts');
64
+ }
65
+
66
+ /**
67
+ * @return mixed
68
+ */
69
+ public function ping()
70
+ {
71
+ return $this->accounts();
72
+ }
73
+
74
+ /**
75
+ * Return all campaigns
76
+ * @return mixed
77
+ */
78
+ public function getCampaigns()
79
+ {
80
+ return $this->call('campaigns');
81
+ }
82
+
83
+ /**
84
+ * get single campaign
85
+ * @param string $campaign_id retrieved using API
86
+ * @return mixed
87
+ */
88
+ public function getCampaign($campaign_id)
89
+ {
90
+ return $this->call('campaigns/' . $campaign_id);
91
+ }
92
+
93
+ /**
94
+ * adding campaign
95
+ * @param $params
96
+ * @return mixed
97
+ */
98
+ public function createCampaign($params)
99
+ {
100
+ return $this->call('campaigns', 'POST', $params);
101
+ }
102
+
103
+ /**
104
+ * list all RSS newsletters
105
+ * @return mixed
106
+ */
107
+ public function getRSSNewsletters()
108
+ {
109
+ $this->call('rss-newsletters', 'GET', null);
110
+ }
111
+
112
+ /**
113
+ * send one newsletter
114
+ *
115
+ * @param $params
116
+ * @return mixed
117
+ */
118
+ public function sendNewsletter($params)
119
+ {
120
+ return $this->call('newsletters', 'POST', $params);
121
+ }
122
+
123
+ /**
124
+ * @param $params
125
+ * @return mixed
126
+ */
127
+ public function sendDraftNewsletter($params)
128
+ {
129
+ return $this->call('newsletters/send-draft', 'POST', $params);
130
+ }
131
+
132
+ /**
133
+ * add single contact into your campaign
134
+ *
135
+ * @param $params
136
+ * @return mixed
137
+ */
138
+ public function addContact($params)
139
+ {
140
+ return $this->call('contacts', 'POST', $params);
141
+ }
142
+
143
+ /**
144
+ * retrieving contact by id
145
+ *
146
+ * @param string $contact_id - contact id obtained by API
147
+ * @return mixed
148
+ */
149
+ public function getContact($contact_id)
150
+ {
151
+ return $this->call('contacts/' . $contact_id);
152
+ }
153
+
154
+
155
+ /**
156
+ * search contacts
157
+ *
158
+ * @param $params
159
+ * @return mixed
160
+ */
161
+ public function searchContacts($params = null)
162
+ {
163
+ return $this->call('search-contacts?' . $this->setParams($params));
164
+ }
165
+
166
+ /**
167
+ * retrieve segment
168
+ *
169
+ * @param $id
170
+ * @return mixed
171
+ */
172
+ public function getContactsSearch($id)
173
+ {
174
+ return $this->call('search-contacts/' . $id);
175
+ }
176
+
177
+ /**
178
+ * add contacts search
179
+ *
180
+ * @param $params
181
+ * @return mixed
182
+ */
183
+ public function addContactsSearch($params)
184
+ {
185
+ return $this->call('search-contacts/', 'POST', $params);
186
+ }
187
+
188
+ /**
189
+ * add contacts search
190
+ *
191
+ * @param $id
192
+ * @return mixed
193
+ */
194
+ public function deleteContactsSearch($id)
195
+ {
196
+ return $this->call('search-contacts/' . $id, 'DELETE');
197
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
+ /**
200
+ * get contact activities
201
+ * @param $contact_id
202
+ * @return mixed
203
+ */
204
+ public function getContactActivities($contact_id)
205
+ {
206
+ return $this->call('contacts/' . $contact_id . '/activities');
207
+ }
208
+
209
+ /**
210
+ * retrieving contact by params
211
+ * @param array $params
212
+ *
213
+ * @return mixed
214
+ */
215
+ public function getContacts($params = array())
216
+ {
217
+ return $this->call('contacts?' . $this->setParams($params));
218
+ }
219
+
220
+ /**
221
+ * updating any fields of your subscriber (without email of course)
222
+ * @param $contact_id
223
+ * @param array $params
224
+ *
225
+ * @return mixed
226
+ */
227
+ public function updateContact($contact_id, $params = array())
228
+ {
229
+ return $this->call('contacts/' . $contact_id, 'POST', $params);
230
+ }
231
+
232
+ /**
233
+ * drop single user by ID
234
+ *
235
+ * @param string $contact_id - obtained by API
236
+ * @return mixed
237
+ */
238
+ public function deleteContact($contact_id)
239
+ {
240
+ return $this->call('contacts/' . $contact_id, 'DELETE');
241
+ }
242
+
243
+ /**
244
+ * retrieve account custom fields
245
+ * @param array $params
246
+ *
247
+ * @return mixed
248
+ */
249
+ public function getCustomFields($params = array())
250
+ {
251
+ return $this->call('custom-fields?' . $this->setParams($params));
252
+ }
253
+
254
+ /**
255
+ * add custom field
256
+ *
257
+ * @param $params
258
+ * @return mixed
259
+ */
260
+ public function setCustomField($params)
261
+ {
262
+ return $this->call('custom-fields', 'POST', $params);
263
+ }
264
+
265
+ /**
266
+ * retrieve single custom field
267
+ *
268
+ * @param string $cs_id obtained by API
269
+ * @return mixed
270
+ */
271
+ public function getCustomField($custom_id)
272
+ {
273
+ return $this->call('custom-fields/' . $custom_id, 'GET');
274
+ }
275
+
276
+ /**
277
+ * retrieving billing information
278
+ *
279
+ * @return mixed
280
+ */
281
+ public function getBillingInfo()
282
+ {
283
+ return $this->call('accounts/billing');
284
+ }
285
+
286
+ /**
287
+ * get single web form
288
+ *
289
+ * @param int $w_id
290
+ * @return mixed
291
+ */
292
+ public function getWebForm($w_id)
293
+ {
294
+ return $this->call('webforms/' . $w_id);
295
+ }
296
+
297
+ /**
298
+ * retrieve all webforms
299
+ * @param array $params
300
+ *
301
+ * @return mixed
302
+ */
303
+ public function getWebForms($params = array())
304
+ {
305
+ return $this->call('webforms?' . $this->setParams($params));
306
+ }
307
+
308
+ /**
309
+ * get single form
310
+ *
311
+ * @param int $form_id
312
+ * @return mixed
313
+ */
314
+ public function getForm($form_id)
315
+ {
316
+ return $this->call('forms/' . $form_id);
317
+ }
318
+
319
+ /**
320
+ * retrieve all forms
321
+ * @param array $params
322
+ *
323
+ * @return mixed
324
+ */
325
+ public function getForms($params = array())
326
+ {
327
+ return $this->call('forms?' . $this->setParams($params));
328
+ }
329
+
330
+ /**
331
+ * Curl run request
332
+ *
333
+ * @param null $api_method
334
+ * @param string $http_method
335
+ * @param array $params
336
+ * @return mixed
337
+ * @throws Exception
338
+ */
339
+ private function call($api_method = null, $http_method = 'GET', $params = array())
340
+ {
341
+ if (empty($api_method)) {
342
+ return (object)array(
343
+ 'httpStatus' => '400',
344
+ 'code' => '1010',
345
+ 'codeDescription' => 'Error in external resources',
346
+ 'message' => 'Invalid api method'
347
+ );
348
+ }
349
+
350
+ $params = json_encode($params);
351
+ $url = $this->api_url . '/' . $api_method;
352
+
353
+ $options = array(
354
+ CURLOPT_URL => $url,
355
+ CURLOPT_ENCODING => 'gzip,deflate',
356
+ CURLOPT_FRESH_CONNECT => 1,
357
+ CURLOPT_RETURNTRANSFER => 1,
358
+ CURLOPT_TIMEOUT => $this->timeout,
359
+ CURLOPT_HEADER => false,
360
+ CURLOPT_USERAGENT => 'PHP GetResponse client 0.0.2',
361
+ CURLOPT_HTTPHEADER => array('X-Auth-Token: api-key ' . $this->api_key, 'Content-Type: application/json'),
362
+ );
363
+
364
+ if (!empty($this->enterprise_domain)) {
365
+ $options[CURLOPT_HTTPHEADER][] = 'X-Domain: ' . $this->enterprise_domain;
366
+ }
367
+
368
+ if (!empty($this->app_id)) {
369
+ $options[CURLOPT_HTTPHEADER][] = 'X-APP-ID: ' . $this->app_id;
370
+ }
371
+
372
+ if ($http_method == 'POST') {
373
+ $options[CURLOPT_POST] = 1;
374
+ $options[CURLOPT_POSTFIELDS] = $params;
375
+ } else if ($http_method == 'DELETE') {
376
+ $options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
377
+ }
378
+
379
+ $curl = curl_init();
380
+ curl_setopt_array($curl, $options);
381
+
382
+ $response = json_decode(curl_exec($curl));
383
+
384
+ $this->http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
385
+
386
+ curl_close($curl);
387
+ return (object)$response;
388
+ }
389
+
390
+ /**
391
+ * @param array $params
392
+ *
393
+ * @return string
394
+ */
395
+ private function setParams($params = array())
396
+ {
397
+ $result = array();
398
+ if (is_array($params)) {
399
+ foreach ($params as $key => $value) {
400
+ $result[$key] = $value;
401
+ }
402
+ }
403
+ return http_build_query($result);
404
+ }
405
+
406
+ }
includes/vendor/mailchimp/Mailchimp/Campaigns.php DELETED
@@ -1,378 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Campaigns {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Get the content (both html and text) for a campaign either as it would appear in the campaign archive or as the raw, original content
10
- * @param string $cid
11
- * @param associative_array $options
12
- * - view string optional one of "archive" (default), "preview" (like our popup-preview) or "raw"
13
- * - email associative_array optional if provided, view is "archive" or "preview", the campaign's list still exists, and the requested record is subscribed to the list. the returned content will be populated with member data populated. a struct with one of the following keys - failing to provide anything will produce an error relating to the email address. If multiple keys are provided, the first one from the following list that we find will be used, the rest will be ignored.
14
- * - email string an email address
15
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
16
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
17
- * @return associative_array containing all content for the campaign
18
- * - html string The HTML content used for the campaign with merge tags intact
19
- * - text string The Text content used for the campaign with merge tags intact
20
- */
21
- public function content($cid, $options=array()) {
22
- $_params = array("cid" => $cid, "options" => $options);
23
- return $this->master->call('campaigns/content', $_params);
24
- }
25
-
26
- /**
27
- * Create a new draft campaign to send. You <strong>can not</strong> have more than 32,000 campaigns in your account.
28
- * @param string $type
29
- * @param associative_array $options
30
- * - list_id string the list to send this campaign to- get lists using lists/list()
31
- * - subject string the subject line for your campaign message
32
- * - from_email string the From: email address for your campaign message
33
- * - from_name string the From: name for your campaign message (not an email address)
34
- * - to_name string the To: name recipients will see (not email address)
35
- * - template_id int optional - use this user-created template to generate the HTML content of the campaign (takes precendence over other template options)
36
- * - gallery_template_id int optional - use a template from the public gallery to generate the HTML content of the campaign (takes precendence over base template options)
37
- * - base_template_id int optional - use this a base/start-from-scratch template to generate the HTML content of the campaign
38
- * - folder_id int optional - automatically file the new campaign in the folder_id passed. Get using folders/list() - note that Campaigns and Autoresponders have separate folder setups
39
- * - tracking associative_array optional - set which recipient actions will be tracked. Click tracking can not be disabled for Free accounts.
40
- * - opens bool whether to track opens, defaults to true
41
- * - html_clicks bool whether to track clicks in HTML content, defaults to true
42
- * - text_clicks bool whether to track clicks in Text content, defaults to false
43
- * - title string optional - an internal name to use for this campaign. By default, the campaign subject will be used.
44
- * - authenticate boolean optional - set to true to enable SenderID, DomainKeys, and DKIM authentication, defaults to false.
45
- * - analytics associative_array optional - one or more of these keys set to the tag to use - that can be any custom text (up to 50 bytes)
46
- * - google string for Google Analytics tracking
47
- * - clicktale string for ClickTale tracking
48
- * - gooal string for Goal tracking (the extra 'o' in the param name is not a typo)
49
- * - auto_footer boolean optional Whether or not we should auto-generate the footer for your content. Mostly useful for content from URLs or Imports
50
- * - inline_css boolean optional Whether or not css should be automatically inlined when this campaign is sent, defaults to false.
51
- * - generate_text boolean optional Whether of not to auto-generate your Text content from the HTML content. Note that this will be ignored if the Text part of the content passed is not empty, defaults to false.
52
- * - auto_tweet boolean optional If set, this campaign will be auto-tweeted when it is sent - defaults to false. Note that if a Twitter account isn't linked, this will be silently ignored.
53
- * - auto_fb_post array optional If set, this campaign will be auto-posted to the page_ids contained in the array. If a Facebook account isn't linked or the account does not have permission to post to the page_ids requested, those failures will be silently ignored.
54
- * - fb_comments boolean optional If true, the Facebook comments (and thus the <a href="http://kb.mailchimp.com/article/i-dont-want-an-archiave-of-my-campaign-can-i-turn-it-off/" target="_blank">archive bar</a> will be displayed. If false, Facebook comments will not be enabled (does not imply no archive bar, see previous link). Defaults to "true".
55
- * - timewarp boolean optional If set, this campaign must be scheduled 24 hours in advance of sending - default to false. Only valid for "regular" campaigns and "absplit" campaigns that split on schedule_time.
56
- * - ecomm360 boolean optional If set, our <a href="http://www.mailchimp.com/blog/ecommerce-tracking-plugin/" target="_blank">Ecommerce360 tracking</a> will be enabled for links in the campaign
57
- * - crm_tracking array optional If set, an array of structs to enable CRM tracking for:
58
- * - salesforce associative_array optional Enable SalesForce push back
59
- * - campaign bool optional - if true, create a Campaign object and update it with aggregate stats
60
- * - notes bool optional - if true, attempt to update Contact notes based on email address
61
- * - highrise associative_array optional Enable Highrise push back
62
- * - campaign bool optional - if true, create a Kase object and update it with aggregate stats
63
- * - notes bool optional - if true, attempt to update Contact notes based on email address
64
- * - capsule associative_array optional Enable Capsule push back (only notes are supported)
65
- * - notes bool optional - if true, attempt to update Contact notes based on email address
66
- * @param associative_array $content
67
- * - html string for raw/pasted HTML content
68
- * - sections associative_array when using a template instead of raw HTML, each key should be the unique mc:edit area name from the template.
69
- * - text string for the plain-text version
70
- * - url string to have us pull in content from a URL. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
71
- * - archive string to send a Base64 encoded archive file for us to import all media from. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
72
- * - archive_type string optional - only necessary for the "archive" option. Supported formats are: zip, tar.gz, tar.bz2, tar, tgz, tbz . If not included, we will default to zip
73
- * @param associative_array $segment_opts
74
- * @param associative_array $type_opts
75
- * - rss associative_array For RSS Campaigns this, struct should contain:
76
- * - url string the URL to pull RSS content from - it will be verified and must exist
77
- * - schedule string optional one of "daily", "weekly", "monthly" - defaults to "daily"
78
- * - schedule_hour string optional an hour between 0 and 24 - default to 4 (4am <em>local time</em>) - applies to all schedule types
79
- * - schedule_weekday string optional for "weekly" only, a number specifying the day of the week to send: 0 (Sunday) - 6 (Saturday) - defaults to 1 (Monday)
80
- * - schedule_monthday string optional for "monthly" only, a number specifying the day of the month to send (1 - 28) or "last" for the last day of a given month. Defaults to the 1st day of the month
81
- * - days associative_array optional used for "daily" schedules only, an array of the <a href="http://en.wikipedia.org/wiki/ISO-8601#Week_dates" target="_blank">ISO-8601 weekday numbers</a> to send on
82
- * - 1 bool optional Monday, defaults to true
83
- * - 2 bool optional Tuesday, defaults to true
84
- * - 3 bool optional Wednesday, defaults to true
85
- * - 4 bool optional Thursday, defaults to true
86
- * - 5 bool optional Friday, defaults to true
87
- * - 6 bool optional Saturday, defaults to true
88
- * - 7 bool optional Sunday, defaults to true
89
- * - absplit associative_array For A/B Split campaigns, this struct should contain:
90
- * - split_test string The values to segment based on. Currently, one of: "subject", "from_name", "schedule". NOTE, for "schedule", you will need to call campaigns/schedule() separately!
91
- * - pick_winner string How the winner will be picked, one of: "opens" (by the open_rate), "clicks" (by the click rate), "manual" (you pick manually)
92
- * - wait_units int optional the default time unit to wait before auto-selecting a winner - use "3600" for hours, "86400" for days. Defaults to 86400.
93
- * - wait_time int optional the number of units to wait before auto-selecting a winner - defaults to 1, so if not set, a winner will be selected after 1 Day.
94
- * - split_size int optional this is a percentage of what size the Campaign's List plus any segmentation options results in. "schedule" type forces 50%, all others default to 10%
95
- * - from_name_a string optional sort of, required when split_test is "from_name"
96
- * - from_name_b string optional sort of, required when split_test is "from_name"
97
- * - from_email_a string optional sort of, required when split_test is "from_name"
98
- * - from_email_b string optional sort of, required when split_test is "from_name"
99
- * - subject_a string optional sort of, required when split_test is "subject"
100
- * - subject_b string optional sort of, required when split_test is "subject"
101
- * - auto associative_array For AutoResponder campaigns, this struct should contain:
102
- * - offset-units string one of "hourly", "day", "week", "month", "year" - required
103
- * - offset-time string optional, sort of - the number of units must be a number greater than 0 for signup based autoresponders, ignored for "hourly"
104
- * - offset-dir string either "before" or "after", ignored for "hourly"
105
- * - event string optional "signup" (default) to base this members added to a list, "date", "annual", or "birthday" to base this on merge field in the list, "campaignOpen" or "campaignClicka" to base this on any activity for a campaign, "campaignClicko" to base this on clicks on a specific URL in a campaign, "mergeChanged" to base this on a specific merge field being changed to a specific value
106
- * - event-datemerge string optional sort of, this is required if the event is "date", "annual", "birthday", or "mergeChanged"
107
- * - campaign_id string optional sort of, required for "campaignOpen", "campaignClicka", or "campaignClicko"
108
- * - campaign_url string optional sort of, required for "campaignClicko"
109
- * - schedule_hour int The hour of the day - 24 hour format in GMT - the autoresponder should be triggered, ignored for "hourly"
110
- * - use_import_time boolean whether or not imported subscribers (ie, <em>any</em> non-double optin subscribers) will receive
111
- * - days associative_array optional used for "daily" schedules only, an array of the <a href="http://en.wikipedia.org/wiki/ISO-8601#Week_dates" target="_blank">ISO-8601 weekday numbers</a> to send on<
112
- * - 1 bool optional Monday, defaults to true
113
- * - 2 bool optional Tuesday, defaults to true
114
- * - 3 bool optional Wednesday, defaults to true
115
- * - 4 bool optional Thursday, defaults to true
116
- * - 5 bool optional Friday, defaults to true
117
- * - 6 bool optional Saturday, defaults to true
118
- * - 7 bool optional Sunday, defaults to true
119
- * @return associative_array the new campaign's details - will return same data as single campaign from campaigns/list()
120
- */
121
- public function create($type, $options, $content, $segment_opts=null, $type_opts=null) {
122
- $_params = array("type" => $type, "options" => $options, "content" => $content, "segment_opts" => $segment_opts, "type_opts" => $type_opts);
123
- return $this->master->call('campaigns/create', $_params);
124
- }
125
-
126
- /**
127
- * Delete a campaign. Seriously, "poof, gone!" - be careful! Seriously, no one can undelete these.
128
- * @param string $cid
129
- * @return associative_array with a single entry:
130
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
131
- */
132
- public function delete($cid) {
133
- $_params = array("cid" => $cid);
134
- return $this->master->call('campaigns/delete', $_params);
135
- }
136
-
137
- /**
138
- * Get the list of campaigns and their details matching the specified filters
139
- * @param associative_array $filters
140
- * - campaign_id string optional - return the campaign using a know campaign_id. Accepts multiples separated by commas when not using exact matching.
141
- * - parent_id string optional - return the child campaigns using a known parent campaign_id. Accepts multiples separated by commas when not using exact matching.
142
- * - list_id string optional - the list to send this campaign to - get lists using lists/list(). Accepts multiples separated by commas when not using exact matching.
143
- * - folder_id int optional - only show campaigns from this folder id - get folders using folders/list(). Accepts multiples separated by commas when not using exact matching.
144
- * - template_id int optional - only show campaigns using this template id - get templates using templates/list(). Accepts multiples separated by commas when not using exact matching.
145
- * - status string optional - return campaigns of a specific status - one of "sent", "save", "paused", "schedule", "sending". Accepts multiples separated by commas when not using exact matching.
146
- * - type string optional - return campaigns of a specific type - one of "regular", "plaintext", "absplit", "rss", "auto". Accepts multiples separated by commas when not using exact matching.
147
- * - from_name string optional - only show campaigns that have this "From Name"
148
- * - from_email string optional - only show campaigns that have this "Reply-to Email"
149
- * - title string optional - only show campaigns that have this title
150
- * - subject string optional - only show campaigns that have this subject
151
- * - sendtime_start string optional - only show campaigns that have been sent since this date/time (in GMT) - - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" - if this is invalid the whole call fails
152
- * - sendtime_end string optional - only show campaigns that have been sent before this date/time (in GMT) - - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" - if this is invalid the whole call fails
153
- * - uses_segment boolean - whether to return just campaigns with or without segments
154
- * - exact boolean optional - flag for whether to filter on exact values when filtering, or search within content for filter values - defaults to true. Using this disables the use of any filters that accept multiples.
155
- * @param int $start
156
- * @param int $limit
157
- * @param string $sort_field
158
- * @param string $sort_dir
159
- * @return associative_array containing a count of all matching campaigns, the specific ones for the current page, and any errors from the filters provided
160
- * - total int the total number of campaigns matching the filters passed in
161
- * - data array structs for each campaign being returned
162
- * - id string Campaign Id (used for all other campaign functions)
163
- * - web_id int The Campaign id used in our web app, allows you to create a link directly to it
164
- * - list_id string The List used for this campaign
165
- * - folder_id int The Folder this campaign is in
166
- * - template_id int The Template this campaign uses
167
- * - content_type string How the campaign's content is put together - one of 'template', 'html', 'url'
168
- * - title string Title of the campaign
169
- * - type string The type of campaign this is (regular,plaintext,absplit,rss,inspection,auto)
170
- * - create_time string Creation time for the campaign
171
- * - send_time string Send time for the campaign - also the scheduled time for scheduled campaigns.
172
- * - emails_sent int Number of emails email was sent to
173
- * - status string Status of the given campaign (save,paused,schedule,sending,sent)
174
- * - from_name string From name of the given campaign
175
- * - from_email string Reply-to email of the given campaign
176
- * - subject string Subject of the given campaign
177
- * - to_name string Custom "To:" email string using merge variables
178
- * - archive_url string Archive link for the given campaign
179
- * - inline_css boolean Whether or not the campaign content's css was auto-inlined
180
- * - analytics string Either "google" if enabled or "N" if disabled
181
- * - analytics_tag string The name/tag the campaign's links were tagged with if analytics were enabled.
182
- * - authenticate boolean Whether or not the campaign was authenticated
183
- * - ecomm360 boolean Whether or not ecomm360 tracking was appended to links
184
- * - auto_tweet boolean Whether or not the campaign was auto tweeted after sending
185
- * - auto_fb_post string A comma delimited list of Facebook Profile/Page Ids the campaign was posted to after sending. If not used, blank.
186
- * - auto_footer boolean Whether or not the auto_footer was manually turned on
187
- * - timewarp boolean Whether or not the campaign used Timewarp
188
- * - timewarp_schedule string The time, in GMT, that the Timewarp campaign is being sent. For A/B Split campaigns, this is blank and is instead in their schedule_a and schedule_b in the type_opts array
189
- * - parent_id string the unique id of the parent campaign (currently only valid for rss children). Will be blank for non-rss child campaigns or parent campaign has been deleted.
190
- * - is_child boolean true if this is an RSS child campaign. Will return true even if the parent campaign has been deleted.
191
- * - tests_sent string tests sent
192
- * - tests_remain int test sends remaining
193
- * - tracking associative_array the various tracking options used
194
- * - html_clicks boolean whether or not tracking for html clicks was enabled.
195
- * - text_clicks boolean whether or not tracking for text clicks was enabled.
196
- * - opens boolean whether or not opens tracking was enabled.
197
- * - segment_text string a string marked-up with HTML explaining the segment used for the campaign in plain English
198
- * - segment_opts array the segment used for the campaign - can be passed to campaigns/segment-test or campaigns/create()
199
- * - saved_segment associative_array if a saved segment was used (match+conditions returned above):
200
- * - id int the saved segment id
201
- * - type string the saved segment type
202
- * - name string the saved segment name
203
- * - type_opts associative_array the type-specific options for the campaign - can be passed to campaigns/create()
204
- * - comments_total int total number of comments left on this campaign
205
- * - comments_unread int total number of unread comments for this campaign based on the login the apikey belongs to
206
- * - summary associative_array if available, the basic aggregate stats returned by reports/summary
207
- * - errors array structs of any errors found while loading lists - usually just from providing invalid list ids
208
- * - filter string the filter that caused the failure
209
- * - value string the filter value that caused the failure
210
- * - code int the error code
211
- * - error string the error message
212
- */
213
- public function getList($filters=array(), $start=0, $limit=25, $sort_field='create_time', $sort_dir='DESC') {
214
- $_params = array("filters" => $filters, "start" => $start, "limit" => $limit, "sort_field" => $sort_field, "sort_dir" => $sort_dir);
215
- return $this->master->call('campaigns/list', $_params);
216
- }
217
-
218
- /**
219
- * Pause an AutoResponder or RSS campaign from sending
220
- * @param string $cid
221
- * @return associative_array with a single entry:
222
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
223
- */
224
- public function pause($cid) {
225
- $_params = array("cid" => $cid);
226
- return $this->master->call('campaigns/pause', $_params);
227
- }
228
-
229
- /**
230
- * Returns information on whether a campaign is ready to send and possible issues we may have detected with it - very similar to the confirmation step in the app.
231
- * @param string $cid
232
- * @return associative_array containing:
233
- * - is_ready bool whether or not you're going to be able to send this campaign
234
- * - items array an array of structs explaining basically what the app's confirmation step would
235
- * - type string the item type - generally success, warning, or error
236
- * - heading string the item's heading in the app
237
- * - details string the item's details from the app, sans any html tags/links
238
- */
239
- public function ready($cid) {
240
- $_params = array("cid" => $cid);
241
- return $this->master->call('campaigns/ready', $_params);
242
- }
243
-
244
- /**
245
- * Replicate a campaign.
246
- * @param string $cid
247
- * @return associative_array the matching campaign's details - will return same data as single campaign from campaigns/list()
248
- */
249
- public function replicate($cid) {
250
- $_params = array("cid" => $cid);
251
- return $this->master->call('campaigns/replicate', $_params);
252
- }
253
-
254
- /**
255
- * Resume sending an AutoResponder or RSS campaign
256
- * @param string $cid
257
- * @return associative_array with a single entry:
258
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
259
- */
260
- public function resume($cid) {
261
- $_params = array("cid" => $cid);
262
- return $this->master->call('campaigns/resume', $_params);
263
- }
264
-
265
- /**
266
- * Schedule a campaign to be sent in the future
267
- * @param string $cid
268
- * @param string $schedule_time
269
- * @param string $schedule_time_b
270
- * @return associative_array with a single entry:
271
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
272
- */
273
- public function schedule($cid, $schedule_time, $schedule_time_b=null) {
274
- $_params = array("cid" => $cid, "schedule_time" => $schedule_time, "schedule_time_b" => $schedule_time_b);
275
- return $this->master->call('campaigns/schedule', $_params);
276
- }
277
-
278
- /**
279
- * Schedule a campaign to be sent in batches sometime in the future. Only valid for "regular" campaigns
280
- * @param string $cid
281
- * @param string $schedule_time
282
- * @param int $num_batches
283
- * @param int $stagger_mins
284
- * @return associative_array with a single entry:
285
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
286
- */
287
- public function scheduleBatch($cid, $schedule_time, $num_batches=2, $stagger_mins=5) {
288
- $_params = array("cid" => $cid, "schedule_time" => $schedule_time, "num_batches" => $num_batches, "stagger_mins" => $stagger_mins);
289
- return $this->master->call('campaigns/schedule-batch', $_params);
290
- }
291
-
292
- /**
293
- * Allows one to test their segmentation rules before creating a campaign using them.
294
- * @param string $list_id
295
- * @param associative_array $options
296
- * - saved_segment_id string a saved segment id from lists/segments() - this will take precendence, otherwise the match+conditions are required.
297
- * - match string controls whether to use AND or OR when applying your options - expects "<strong>any</strong>" (for OR) or "<strong>all</strong>" (for AND)
298
- * - conditions array of up to 5 structs for different criteria to apply while segmenting. Each criteria row must contain 3 keys - "<strong>field</strong>", "<strong>op</strong>", and "<strong>value</strong>" - and possibly a fourth, "<strong>extra</strong>", based on these definitions:
299
- * @return associative_array with a single entry:
300
- * - total int The total number of subscribers matching your segmentation options
301
- */
302
- public function segmentTest($list_id, $options) {
303
- $_params = array("list_id" => $list_id, "options" => $options);
304
- return $this->master->call('campaigns/segment-test', $_params);
305
- }
306
-
307
- /**
308
- * Send a given campaign immediately. For RSS campaigns, this will "start" them.
309
- * @param string $cid
310
- * @return associative_array with a single entry:
311
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
312
- */
313
- public function send($cid) {
314
- $_params = array("cid" => $cid);
315
- return $this->master->call('campaigns/send', $_params);
316
- }
317
-
318
- /**
319
- * Send a test of this campaign to the provided email addresses
320
- * @param string $cid
321
- * @param array $test_emails
322
- * @param string $send_type
323
- * @return associative_array with a single entry:
324
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
325
- */
326
- public function sendTest($cid, $test_emails=array(), $send_type='html') {
327
- $_params = array("cid" => $cid, "test_emails" => $test_emails, "send_type" => $send_type);
328
- return $this->master->call('campaigns/send-test', $_params);
329
- }
330
-
331
- /**
332
- * Get the HTML template content sections for a campaign. Note that this <strong>will</strong> return very jagged, non-standard results based on the template
333
- a campaign is using. You only want to use this if you want to allow editing template sections in your application.
334
- * @param string $cid
335
- * @return associative_array content containing all content section for the campaign - section name are dependent upon the template used and thus can't be documented
336
- */
337
- public function templateContent($cid) {
338
- $_params = array("cid" => $cid);
339
- return $this->master->call('campaigns/template-content', $_params);
340
- }
341
-
342
- /**
343
- * Unschedule a campaign that is scheduled to be sent in the future
344
- * @param string $cid
345
- * @return associative_array with a single entry:
346
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
347
- */
348
- public function unschedule($cid) {
349
- $_params = array("cid" => $cid);
350
- return $this->master->call('campaigns/unschedule', $_params);
351
- }
352
-
353
- /**
354
- * Update just about any setting besides type for a campaign that has <em>not</em> been sent. See campaigns/create() for details.
355
- Caveats:<br/><ul class='bullets'>
356
- <li>If you set a new list_id, all segmentation options will be deleted and must be re-added.</li>
357
- <li>If you set template_id, you need to follow that up by setting it's 'content'</li>
358
- <li>If you set segment_opts, you should have tested your options against campaigns/segment-test().</li>
359
- <li>To clear/unset segment_opts, pass an empty string or array as the value. Various wrappers may require one or the other.</li>
360
- </ul>
361
- * @param string $cid
362
- * @param string $name
363
- * @param array $value
364
- * @return associative_array updated campaign details and any errors
365
- * - data associative_array the update campaign details - will return same data as single campaign from campaigns/list()
366
- * - errors array for "options" only - structs containing:
367
- * - code int the error code
368
- * - message string the full error message
369
- * - name string the parameter name that failed
370
- */
371
- public function update($cid, $name, $value) {
372
- $_params = array("cid" => $cid, "name" => $name, "value" => $value);
373
- return $this->master->call('campaigns/update', $_params);
374
- }
375
-
376
- }
377
-
378
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Conversations.php DELETED
@@ -1,80 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Conversations {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Retrieve conversation metadata, includes message data for the most recent message in the conversation
10
- * @param string $list_id
11
- * @param string $leid
12
- * @param string $campaign_id
13
- * @param int $start
14
- * @param int $limit
15
- * @return associative_array Conversation data and metadata
16
- * - count int Total number of conversations, irrespective of pagination.
17
- * - data array An array of structs representing individual conversations
18
- * - unique_id string A string identifying this particular conversation
19
- * - message_count int The total number of messages in this conversation
20
- * - campaign_id string The unique identifier of the campaign this conversation is associated with
21
- * - list_id string The unique identifier of the list this conversation is associated with
22
- * - unread_messages int The number of messages in this conversation which have not yet been read.
23
- * - from_label string A label representing the sender of this message.
24
- * - from_email string The email address of the sender of this message.
25
- * - subject string The subject of the message.
26
- * - timestamp string Date the message was either sent or received.
27
- * - last_message associative_array The most recent message in the conversation
28
- * - from_label string A label representing the sender of this message.
29
- * - from_email string The email address of the sender of this message.
30
- * - subject string The subject of the message.
31
- * - message string The plain-text content of the message.
32
- * - read boolean Whether or not this message has been marked as read.
33
- * - timestamp string Date the message was either sent or received.
34
- */
35
- public function getList($list_id=null, $leid=null, $campaign_id=null, $start=0, $limit=25) {
36
- $_params = array("list_id" => $list_id, "leid" => $leid, "campaign_id" => $campaign_id, "start" => $start, "limit" => $limit);
37
- return $this->master->call('conversations/list', $_params);
38
- }
39
-
40
- /**
41
- * Retrieve conversation messages
42
- * @param string $conversation_id
43
- * @param boolean $mark_as_read
44
- * @param int $start
45
- * @param int $limit
46
- * @return associative_array Message data and metadata
47
- * - count int The number of messages in this conversation, irrespective of paging.
48
- * - data array An array of structs representing each message in a conversation
49
- * - from_label string A label representing the sender of this message.
50
- * - from_email string The email address of the sender of this message.
51
- * - subject string The subject of the message.
52
- * - message string The plain-text content of the message.
53
- * - read boolean Whether or not this message has been marked as read.
54
- * - timestamp string Date the message was either sent or received.
55
- */
56
- public function messages($conversation_id, $mark_as_read=false, $start=0, $limit=25) {
57
- $_params = array("conversation_id" => $conversation_id, "mark_as_read" => $mark_as_read, "start" => $start, "limit" => $limit);
58
- return $this->master->call('conversations/messages', $_params);
59
- }
60
-
61
- /**
62
- * Retrieve conversation messages
63
- * @param string $conversation_id
64
- * @param string $message
65
- * @return associative_array Message data from the created message
66
- * - from_label string A label representing the sender of this message.
67
- * - from_email string The email address of the sender of this message.
68
- * - subject string The subject of the message.
69
- * - message string The plain-text content of the message.
70
- * - read boolean Whether or not this message has been marked as read.
71
- * - timestamp string Date the message was either sent or received.
72
- */
73
- public function reply($conversation_id, $message) {
74
- $_params = array("conversation_id" => $conversation_id, "message" => $message);
75
- return $this->master->call('conversations/reply', $_params);
76
- }
77
-
78
- }
79
-
80
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Ecomm.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Ecomm {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Import Ecommerce Order Information to be used for Segmentation. This will generally be used by ecommerce package plugins
10
- <a href="http://connect.mailchimp.com/category/ecommerce" target="_blank">provided by us or by 3rd part system developers</a>.
11
- * @param associative_array $order
12
- * - id string the Order Id
13
- * - campaign_id string optional the Campaign Id to track this order against (see the "mc_cid" query string variable a campaign passes)
14
- * - email_id string optional (kind of) the Email Id of the subscriber we should attach this order to (see the "mc_eid" query string variable a campaign passes) - required if campaign_id is passed, otherwise either this or <strong>email</strong> is required. If both are provided, email_id takes precedence
15
- * - email string optional (kind of) the Email Address we should attach this order to - either this or <strong>email_id</strong> is required. If both are provided, email_id takes precedence
16
- * - total double The Order Total (ie, the full amount the customer ends up paying)
17
- * - order_date string optional the date of the order - if this is not provided, we will default the date to now. Should be in the format of 2012-12-30
18
- * - shipping double optional the total paid for Shipping Fees
19
- * - tax double optional the total tax paid
20
- * - store_id string a unique id for the store sending the order in (32 bytes max)
21
- * - store_name string optional a "nice" name for the store - typically the base web address (ie, "store.mailchimp.com"). We will automatically update this if it changes (based on store_id)
22
- * - items array structs for each individual line item including:
23
- * - line_num int optional the line number of the item on the order. We will generate these if they are not passed
24
- * - product_id int the store's internal Id for the product. Lines that do no contain this will be skipped
25
- * - sku string optional the store's internal SKU for the product. (max 30 bytes)
26
- * - product_name string the product name for the product_id associated with this item. We will auto update these as they change (based on product_id)
27
- * - category_id int (required) the store's internal Id for the (main) category associated with this product. Our testing has found this to be a "best guess" scenario
28
- * - category_name string (required) the category name for the category_id this product is in. Our testing has found this to be a "best guess" scenario. Our plugins walk the category heirarchy up and send "Root - SubCat1 - SubCat4", etc.
29
- * - qty double optional the quantity of the item ordered - defaults to 1
30
- * - cost double optional the cost of a single item (ie, not the extended cost of the line) - defaults to 0
31
- * @return associative_array with a single entry:
32
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
33
- */
34
- public function orderAdd($order) {
35
- $_params = array("order" => $order);
36
- return $this->master->call('ecomm/order-add', $_params);
37
- }
38
-
39
- /**
40
- * Delete Ecommerce Order Information used for segmentation. This will generally be used by ecommerce package plugins
41
- <a href="/plugins/ecomm360.phtml">that we provide</a> or by 3rd part system developers.
42
- * @param string $store_id
43
- * @param string $order_id
44
- * @return associative_array with a single entry:
45
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
46
- */
47
- public function orderDel($store_id, $order_id) {
48
- $_params = array("store_id" => $store_id, "order_id" => $order_id);
49
- return $this->master->call('ecomm/order-del', $_params);
50
- }
51
-
52
- /**
53
- * Retrieve the Ecommerce Orders for an account
54
- * @param string $cid
55
- * @param int $start
56
- * @param int $limit
57
- * @param string $since
58
- * @return associative_array the total matching orders and the specific orders for the requested page
59
- * - total int the total matching orders
60
- * - data array structs for each order being returned
61
- * - store_id string the store id generated by the plugin used to uniquely identify a store
62
- * - store_name string the store name collected by the plugin - often the domain name
63
- * - order_id string the internal order id the store tracked this order by
64
- * - email string the email address that received this campaign and is associated with this order
65
- * - order_total double the order total
66
- * - tax_total double the total tax for the order (if collected)
67
- * - ship_total double the shipping total for the order (if collected)
68
- * - order_date string the date the order was tracked - from the store if possible, otherwise the GMT time we received it
69
- * - items array structs for each line item on this order.:
70
- * - line_num int the line number
71
- * - product_id int the product id
72
- * - product_name string the product name
73
- * - product_sku string the sku for the product
74
- * - product_category_id int the category id for the product
75
- * - product_category_name string the category name for the product
76
- * - qty int the quantity ordered
77
- * - cost double the cost of the item
78
- */
79
- public function orders($cid=null, $start=0, $limit=100, $since=null) {
80
- $_params = array("cid" => $cid, "start" => $start, "limit" => $limit, "since" => $since);
81
- return $this->master->call('ecomm/orders', $_params);
82
- }
83
-
84
- }
85
-
86
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Exceptions.php DELETED
@@ -1,471 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Error extends Exception {}
4
- class Mailchimp_HttpError extends Mailchimp_Error {}
5
-
6
- /**
7
- * The parameters passed to the API call are invalid or not provided when required
8
- */
9
- class Mailchimp_ValidationError extends Mailchimp_Error {}
10
-
11
- /**
12
- * None
13
- */
14
- class Mailchimp_ServerError_MethodUnknown extends Mailchimp_Error {}
15
-
16
- /**
17
- * None
18
- */
19
- class Mailchimp_ServerError_InvalidParameters extends Mailchimp_Error {}
20
-
21
- /**
22
- * None
23
- */
24
- class Mailchimp_Unknown_Exception extends Mailchimp_Error {}
25
-
26
- /**
27
- * None
28
- */
29
- class Mailchimp_Request_TimedOut extends Mailchimp_Error {}
30
-
31
- /**
32
- * None
33
- */
34
- class Mailchimp_Zend_Uri_Exception extends Mailchimp_Error {}
35
-
36
- /**
37
- * None
38
- */
39
- class Mailchimp_PDOException extends Mailchimp_Error {}
40
-
41
- /**
42
- * None
43
- */
44
- class Mailchimp_Avesta_Db_Exception extends Mailchimp_Error {}
45
-
46
- /**
47
- * None
48
- */
49
- class Mailchimp_XML_RPC2_Exception extends Mailchimp_Error {}
50
-
51
- /**
52
- * None
53
- */
54
- class Mailchimp_XML_RPC2_FaultException extends Mailchimp_Error {}
55
-
56
- /**
57
- * None
58
- */
59
- class Mailchimp_Too_Many_Connections extends Mailchimp_Error {}
60
-
61
- /**
62
- * None
63
- */
64
- class Mailchimp_Parse_Exception extends Mailchimp_Error {}
65
-
66
- /**
67
- * None
68
- */
69
- class Mailchimp_User_Unknown extends Mailchimp_Error {}
70
-
71
- /**
72
- * None
73
- */
74
- class Mailchimp_User_Disabled extends Mailchimp_Error {}
75
-
76
- /**
77
- * None
78
- */
79
- class Mailchimp_User_DoesNotExist extends Mailchimp_Error {}
80
-
81
- /**
82
- * None
83
- */
84
- class Mailchimp_User_NotApproved extends Mailchimp_Error {}
85
-
86
- /**
87
- * None
88
- */
89
- class Mailchimp_Invalid_ApiKey extends Mailchimp_Error {}
90
-
91
- /**
92
- * None
93
- */
94
- class Mailchimp_User_UnderMaintenance extends Mailchimp_Error {}
95
-
96
- /**
97
- * None
98
- */
99
- class Mailchimp_Invalid_AppKey extends Mailchimp_Error {}
100
-
101
- /**
102
- * None
103
- */
104
- class Mailchimp_Invalid_IP extends Mailchimp_Error {}
105
-
106
- /**
107
- * None
108
- */
109
- class Mailchimp_User_DoesExist extends Mailchimp_Error {}
110
-
111
- /**
112
- * None
113
- */
114
- class Mailchimp_User_InvalidRole extends Mailchimp_Error {}
115
-
116
- /**
117
- * None
118
- */
119
- class Mailchimp_User_InvalidAction extends Mailchimp_Error {}
120
-
121
- /**
122
- * None
123
- */
124
- class Mailchimp_User_MissingEmail extends Mailchimp_Error {}
125
-
126
- /**
127
- * None
128
- */
129
- class Mailchimp_User_CannotSendCampaign extends Mailchimp_Error {}
130
-
131
- /**
132
- * None
133
- */
134
- class Mailchimp_User_MissingModuleOutbox extends Mailchimp_Error {}
135
-
136
- /**
137
- * None
138
- */
139
- class Mailchimp_User_ModuleAlreadyPurchased extends Mailchimp_Error {}
140
-
141
- /**
142
- * None
143
- */
144
- class Mailchimp_User_ModuleNotPurchased extends Mailchimp_Error {}
145
-
146
- /**
147
- * None
148
- */
149
- class Mailchimp_User_NotEnoughCredit extends Mailchimp_Error {}
150
-
151
- /**
152
- * None
153
- */
154
- class Mailchimp_MC_InvalidPayment extends Mailchimp_Error {}
155
-
156
- /**
157
- * None
158
- */
159
- class Mailchimp_List_DoesNotExist extends Mailchimp_Error {}
160
-
161
- /**
162
- * None
163
- */
164
- class Mailchimp_List_InvalidInterestFieldType extends Mailchimp_Error {}
165
-
166
- /**
167
- * None
168
- */
169
- class Mailchimp_List_InvalidOption extends Mailchimp_Error {}
170
-
171
- /**
172
- * None
173
- */
174
- class Mailchimp_List_InvalidUnsubMember extends Mailchimp_Error {}
175
-
176
- /**
177
- * None
178
- */
179
- class Mailchimp_List_InvalidBounceMember extends Mailchimp_Error {}
180
-
181
- /**
182
- * None
183
- */
184
- class Mailchimp_List_AlreadySubscribed extends Mailchimp_Error {}
185
-
186
- /**
187
- * None
188
- */
189
- class Mailchimp_List_NotSubscribed extends Mailchimp_Error {}
190
-
191
- /**
192
- * None
193
- */
194
- class Mailchimp_List_InvalidImport extends Mailchimp_Error {}
195
-
196
- /**
197
- * None
198
- */
199
- class Mailchimp_MC_PastedList_Duplicate extends Mailchimp_Error {}
200
-
201
- /**
202
- * None
203
- */
204
- class Mailchimp_MC_PastedList_InvalidImport extends Mailchimp_Error {}
205
-
206
- /**
207
- * None
208
- */
209
- class Mailchimp_Email_AlreadySubscribed extends Mailchimp_Error {}
210
-
211
- /**
212
- * None
213
- */
214
- class Mailchimp_Email_AlreadyUnsubscribed extends Mailchimp_Error {}
215
-
216
- /**
217
- * None
218
- */
219
- class Mailchimp_Email_NotExists extends Mailchimp_Error {}
220
-
221
- /**
222
- * None
223
- */
224
- class Mailchimp_Email_NotSubscribed extends Mailchimp_Error {}
225
-
226
- /**
227
- * None
228
- */
229
- class Mailchimp_List_MergeFieldRequired extends Mailchimp_Error {}
230
-
231
- /**
232
- * None
233
- */
234
- class Mailchimp_List_CannotRemoveEmailMerge extends Mailchimp_Error {}
235
-
236
- /**
237
- * None
238
- */
239
- class Mailchimp_List_Merge_InvalidMergeID extends Mailchimp_Error {}
240
-
241
- /**
242
- * None
243
- */
244
- class Mailchimp_List_TooManyMergeFields extends Mailchimp_Error {}
245
-
246
- /**
247
- * None
248
- */
249
- class Mailchimp_List_InvalidMergeField extends Mailchimp_Error {}
250
-
251
- /**
252
- * None
253
- */
254
- class Mailchimp_List_InvalidInterestGroup extends Mailchimp_Error {}
255
-
256
- /**
257
- * None
258
- */
259
- class Mailchimp_List_TooManyInterestGroups extends Mailchimp_Error {}
260
-
261
- /**
262
- * None
263
- */
264
- class Mailchimp_Campaign_DoesNotExist extends Mailchimp_Error {}
265
-
266
- /**
267
- * None
268
- */
269
- class Mailchimp_Campaign_StatsNotAvailable extends Mailchimp_Error {}
270
-
271
- /**
272
- * None
273
- */
274
- class Mailchimp_Campaign_InvalidAbsplit extends Mailchimp_Error {}
275
-
276
- /**
277
- * None
278
- */
279
- class Mailchimp_Campaign_InvalidContent extends Mailchimp_Error {}
280
-
281
- /**
282
- * None
283
- */
284
- class Mailchimp_Campaign_InvalidOption extends Mailchimp_Error {}
285
-
286
- /**
287
- * None
288
- */
289
- class Mailchimp_Campaign_InvalidStatus extends Mailchimp_Error {}
290
-
291
- /**
292
- * None
293
- */
294
- class Mailchimp_Campaign_NotSaved extends Mailchimp_Error {}
295
-
296
- /**
297
- * None
298
- */
299
- class Mailchimp_Campaign_InvalidSegment extends Mailchimp_Error {}
300
-
301
- /**
302
- * None
303
- */
304
- class Mailchimp_Campaign_InvalidRss extends Mailchimp_Error {}
305
-
306
- /**
307
- * None
308
- */
309
- class Mailchimp_Campaign_InvalidAuto extends Mailchimp_Error {}
310
-
311
- /**
312
- * None
313
- */
314
- class Mailchimp_MC_ContentImport_InvalidArchive extends Mailchimp_Error {}
315
-
316
- /**
317
- * None
318
- */
319
- class Mailchimp_Campaign_BounceMissing extends Mailchimp_Error {}
320
-
321
- /**
322
- * None
323
- */
324
- class Mailchimp_Campaign_InvalidTemplate extends Mailchimp_Error {}
325
-
326
- /**
327
- * None
328
- */
329
- class Mailchimp_Invalid_EcommOrder extends Mailchimp_Error {}
330
-
331
- /**
332
- * None
333
- */
334
- class Mailchimp_Absplit_UnknownError extends Mailchimp_Error {}
335
-
336
- /**
337
- * None
338
- */
339
- class Mailchimp_Absplit_UnknownSplitTest extends Mailchimp_Error {}
340
-
341
- /**
342
- * None
343
- */
344
- class Mailchimp_Absplit_UnknownTestType extends Mailchimp_Error {}
345
-
346
- /**
347
- * None
348
- */
349
- class Mailchimp_Absplit_UnknownWaitUnit extends Mailchimp_Error {}
350
-
351
- /**
352
- * None
353
- */
354
- class Mailchimp_Absplit_UnknownWinnerType extends Mailchimp_Error {}
355
-
356
- /**
357
- * None
358
- */
359
- class Mailchimp_Absplit_WinnerNotSelected extends Mailchimp_Error {}
360
-
361
- /**
362
- * None
363
- */
364
- class Mailchimp_Invalid_Analytics extends Mailchimp_Error {}
365
-
366
- /**
367
- * None
368
- */
369
- class Mailchimp_Invalid_DateTime extends Mailchimp_Error {}
370
-
371
- /**
372
- * None
373
- */
374
- class Mailchimp_Invalid_Email extends Mailchimp_Error {}
375
-
376
- /**
377
- * None
378
- */
379
- class Mailchimp_Invalid_SendType extends Mailchimp_Error {}
380
-
381
- /**
382
- * None
383
- */
384
- class Mailchimp_Invalid_Template extends Mailchimp_Error {}
385
-
386
- /**
387
- * None
388
- */
389
- class Mailchimp_Invalid_TrackingOptions extends Mailchimp_Error {}
390
-
391
- /**
392
- * None
393
- */
394
- class Mailchimp_Invalid_Options extends Mailchimp_Error {}
395
-
396
- /**
397
- * None
398
- */
399
- class Mailchimp_Invalid_Folder extends Mailchimp_Error {}
400
-
401
- /**
402
- * None
403
- */
404
- class Mailchimp_Invalid_URL extends Mailchimp_Error {}
405
-
406
- /**
407
- * None
408
- */
409
- class Mailchimp_Module_Unknown extends Mailchimp_Error {}
410
-
411
- /**
412
- * None
413
- */
414
- class Mailchimp_MonthlyPlan_Unknown extends Mailchimp_Error {}
415
-
416
- /**
417
- * None
418
- */
419
- class Mailchimp_Order_TypeUnknown extends Mailchimp_Error {}
420
-
421
- /**
422
- * None
423
- */
424
- class Mailchimp_Invalid_PagingLimit extends Mailchimp_Error {}
425
-
426
- /**
427
- * None
428
- */
429
- class Mailchimp_Invalid_PagingStart extends Mailchimp_Error {}
430
-
431
- /**
432
- * None
433
- */
434
- class Mailchimp_Max_Size_Reached extends Mailchimp_Error {}
435
-
436
- /**
437
- * None
438
- */
439
- class Mailchimp_MC_SearchException extends Mailchimp_Error {}
440
-
441
- /**
442
- * None
443
- */
444
- class Mailchimp_Goal_SaveFailed extends Mailchimp_Error {}
445
-
446
- /**
447
- * None
448
- */
449
- class Mailchimp_Conversation_DoesNotExist extends Mailchimp_Error {}
450
-
451
- /**
452
- * None
453
- */
454
- class Mailchimp_Conversation_ReplySaveFailed extends Mailchimp_Error {}
455
-
456
- /**
457
- * None
458
- */
459
- class Mailchimp_File_Not_Found_Exception extends Mailchimp_Error {}
460
-
461
- /**
462
- * None
463
- */
464
- class Mailchimp_Folder_Not_Found_Exception extends Mailchimp_Error {}
465
-
466
- /**
467
- * None
468
- */
469
- class Mailchimp_Folder_Exists_Exception extends Mailchimp_Error {}
470
-
471
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Folders.php DELETED
@@ -1,62 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Folders {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Add a new folder to file campaigns, autoresponders, or templates in
10
- * @param string $name
11
- * @param string $type
12
- * @return associative_array with a single value:
13
- * - folder_id int the folder_id of the newly created folder.
14
- */
15
- public function add($name, $type) {
16
- $_params = array("name" => $name, "type" => $type);
17
- return $this->master->call('folders/add', $_params);
18
- }
19
-
20
- /**
21
- * Delete a campaign, autoresponder, or template folder. Note that this will simply make whatever was in the folder appear unfiled, no other data is removed
22
- * @param int $fid
23
- * @param string $type
24
- * @return associative_array with a single entry:
25
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
26
- */
27
- public function del($fid, $type) {
28
- $_params = array("fid" => $fid, "type" => $type);
29
- return $this->master->call('folders/del', $_params);
30
- }
31
-
32
- /**
33
- * List all the folders of a certain type
34
- * @param string $type
35
- * @return array structs for each folder, including:
36
- * - folder_id int Folder Id for the given folder, this can be used in the campaigns/list() function to filter on.
37
- * - name string Name of the given folder
38
- * - date_created string The date/time the folder was created
39
- * - type string The type of the folders being returned, just to make sure you know.
40
- * - cnt int number of items in the folder.
41
- */
42
- public function getList($type) {
43
- $_params = array("type" => $type);
44
- return $this->master->call('folders/list', $_params);
45
- }
46
-
47
- /**
48
- * Update the name of a folder for campaigns, autoresponders, or templates
49
- * @param int $fid
50
- * @param string $name
51
- * @param string $type
52
- * @return associative_array with a single entry:
53
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
54
- */
55
- public function update($fid, $name, $type) {
56
- $_params = array("fid" => $fid, "name" => $name, "type" => $type);
57
- return $this->master->call('folders/update', $_params);
58
- }
59
-
60
- }
61
-
62
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Gallery.php DELETED
@@ -1,106 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Gallery {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Return a section of the image gallery
10
- * @param associative_array $opts
11
- * - type string optional the gallery type to return - images or files - default to images
12
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
13
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
14
- * - sort_by string optional field to sort by - one of size, time, name - defaults to time
15
- * - sort_dir string optional field to sort by - one of asc, desc - defaults to desc
16
- * - search_term string optional a term to search for in names
17
- * - folder_id int optional to return files that are in a specific folder. id returned by the list-folders call
18
- * @return associative_array the matching gallery items
19
- * - total int the total matching items
20
- * - data array structs for each item included in the set, including:
21
- * - id int the id of the file
22
- * - name string the file name
23
- * - time string the creation date for the item
24
- * - size int the file size in bytes
25
- * - full string the url to the actual item in the gallery
26
- * - thumb string a url for a thumbnail that can be used to represent the item, generally an image thumbnail or an icon for a file type
27
- */
28
- public function getList($opts=array()) {
29
- $_params = array("opts" => $opts);
30
- return $this->master->call('gallery/list', $_params);
31
- }
32
-
33
- /**
34
- * Return a list of the folders available to the file gallery
35
- * @param associative_array $opts
36
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
37
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
38
- * - search_term string optional a term to search for in names
39
- * @return associative_array the matching gallery folders
40
- * - total int the total matching folders
41
- * - data array structs for each folder included in the set, including:
42
- * - id int the id of the folder
43
- * - name string the file name
44
- * - file_count int the number of files in the folder
45
- */
46
- public function listFolders($opts=array()) {
47
- $_params = array("opts" => $opts);
48
- return $this->master->call('gallery/list-folders', $_params);
49
- }
50
-
51
- /**
52
- * Adds a folder to the file gallery
53
- * @param string $name
54
- * @return associative_array the new data for the created folder
55
- * - data.id int the id of the new folder
56
- */
57
- public function addFolder($name) {
58
- $_params = array("name" => $name);
59
- return $this->master->call('gallery/add-folder', $_params);
60
- }
61
-
62
- /**
63
- * Remove a folder
64
- * @param int $folder_id
65
- * @return boolean true/false for success/failure
66
- */
67
- public function removeFolder($folder_id) {
68
- $_params = array("folder_id" => $folder_id);
69
- return $this->master->call('gallery/remove-folder', $_params);
70
- }
71
-
72
- /**
73
- * Add a file to a folder
74
- * @param int $file_id
75
- * @param int $folder_id
76
- * @return boolean true/false for success/failure
77
- */
78
- public function addFileToFolder($file_id, $folder_id) {
79
- $_params = array("file_id" => $file_id, "folder_id" => $folder_id);
80
- return $this->master->call('gallery/add-file-to-folder', $_params);
81
- }
82
-
83
- /**
84
- * Remove a file from a folder
85
- * @param int $file_id
86
- * @param int $folder_id
87
- * @return boolean true/false for success/failure
88
- */
89
- public function removeFileFromFolder($file_id, $folder_id) {
90
- $_params = array("file_id" => $file_id, "folder_id" => $folder_id);
91
- return $this->master->call('gallery/remove-file-from-folder', $_params);
92
- }
93
-
94
- /**
95
- * Remove all files from a folder (Note that the files are not deleted, they are only removed from the folder)
96
- * @param int $folder_id
97
- * @return boolean true/false for success/failure
98
- */
99
- public function removeAllFilesFromFolder($folder_id) {
100
- $_params = array("folder_id" => $folder_id);
101
- return $this->master->call('gallery/remove-all-files-from-folder', $_params);
102
- }
103
-
104
- }
105
-
106
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Goal.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Goal {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Retrieve goal event data for a particular list member. Note: only unique events are returned. If a user triggers
10
- a particular event multiple times, you will still only receive one entry for that event.
11
- * @param string $list_id
12
- * @param associative_array $email
13
- * - email string an email address
14
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
15
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
16
- * @param int $start
17
- * @param int $limit
18
- * @return associative_array Event data and metadata
19
- * - data array An array of goal data structs for the specified list member in the following format
20
- * - event string The URL or name of the event that was triggered
21
- * - last_visited_at string A timestamp in the format 'YYYY-MM-DD HH:MM:SS' that represents the last time this event was seen.
22
- * - total int The total number of events that match your criteria.
23
- */
24
- public function events($list_id, $email, $start=0, $limit=25) {
25
- $_params = array("list_id" => $list_id, "email" => $email, "start" => $start, "limit" => $limit);
26
- return $this->master->call('goal/events', $_params);
27
- }
28
-
29
- /**
30
- * This allows programmatically trigger goal event collection without the use of front-end code.
31
- * @param string $list_id
32
- * @param associative_array $email
33
- * - email string an email address
34
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
35
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
36
- * @param string $campaign_id
37
- * @param string $event
38
- * @return associative_array Event data for the submitted event
39
- * - event string The URL or name of the event that was triggered
40
- * - last_visited_at string A timestamp in the format 'YYYY-MM-DD HH:MM:SS' that represents the last time this event was seen.
41
- */
42
- public function recordEvent($list_id, $email, $campaign_id, $event) {
43
- $_params = array("list_id" => $list_id, "email" => $email, "campaign_id" => $campaign_id, "event" => $event);
44
- return $this->master->call('goal/record-event', $_params);
45
- }
46
-
47
- }
48
-
49
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Helper.php DELETED
@@ -1,237 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Helper {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Retrieve lots of account information including payments made, plan info, some account stats, installed modules,
10
- contact info, and more. No private information like Credit Card numbers is available.
11
- * @param array $exclude
12
- * @return associative_array containing the details for the account tied to this API Key
13
- * - username string The company name associated with the account
14
- * - user_id string The Account user unique id (for building some links)
15
- * - is_trial bool Whether the Account is in Trial mode (can only send campaigns to less than 100 emails)
16
- * - is_approved bool Whether the Account has been approved for purchases
17
- * - has_activated bool Whether the Account has been activated
18
- * - timezone string The timezone for the Account - default is "US/Eastern"
19
- * - plan_type string Plan Type - "monthly", "payasyougo", or "free"
20
- * - plan_low int <em>only for Monthly plans</em> - the lower tier for list size
21
- * - plan_high int <em>only for Monthly plans</em> - the upper tier for list size
22
- * - plan_start_date string <em>only for Monthly plans</em> - the start date for a monthly plan
23
- * - emails_left int <em>only for Free and Pay-as-you-go plans</em> emails credits left for the account
24
- * - pending_monthly bool Whether the account is finishing Pay As You Go credits before switching to a Monthly plan
25
- * - first_payment string date of first payment
26
- * - last_payment string date of most recent payment
27
- * - times_logged_in int total number of times the account has been logged into via the web
28
- * - last_login string date/time of last login via the web
29
- * - affiliate_link string Monkey Rewards link for our Affiliate program
30
- * - industry string the user's selected industry
31
- * - contact associative_array Contact details for the account
32
- * - fname string First Name
33
- * - lname string Last Name
34
- * - email string Email Address
35
- * - company string Company Name
36
- * - address1 string Address Line 1
37
- * - address2 string Address Line 2
38
- * - city string City
39
- * - state string State or Province
40
- * - zip string Zip or Postal Code
41
- * - country string Country name
42
- * - url string Website URL
43
- * - phone string Phone number
44
- * - fax string Fax number
45
- * - modules array a struct for each addon module installed in the account
46
- * - id string An internal module id
47
- * - name string The module name
48
- * - added string The date the module was added
49
- * - data associative_array Any extra data associated with this module as key=>value pairs
50
- * - orders array a struct for each order for the account
51
- * - order_id int The order id
52
- * - type string The order type - either "monthly" or "credits"
53
- * - amount double The order amount
54
- * - date string The order date
55
- * - credits_used double The total credits used
56
- * - rewards associative_array Rewards details for the account including credits & inspections earned, number of referrals, referral details, and rewards used
57
- * - referrals_this_month int the total number of referrals this month
58
- * - notify_on string whether or not we notify the user when rewards are earned
59
- * - notify_email string the email address address used for rewards notifications
60
- * - credits associative_array Email credits earned:
61
- * - this_month int credits earned this month
62
- * - total_earned int credits earned all time
63
- * - remaining int credits remaining
64
- * - inspections associative_array Inbox Inspections earned:
65
- * - this_month int credits earned this month
66
- * - total_earned int credits earned all time
67
- * - remaining int credits remaining
68
- * - referrals array a struct for each referral, including:
69
- * - name string the name of the account
70
- * - email string the email address associated with the account
71
- * - signup_date string the signup date for the account
72
- * - type string the source for the referral
73
- * - applied array a struct for each applied rewards, including:
74
- * - value int the number of credits user
75
- * - date string the date applied
76
- * - order_id int the order number credits were applied to
77
- * - order_desc string the order description
78
- * - integrations array a struct for each connected integrations that can be used with campaigns, including:
79
- * - id int an internal id for the integration
80
- * - name string the integration name
81
- * - list_id string either "_any_" when globally accessible or the list id it's valid for use against
82
- * - user_id string if applicable, the user id for the integrated system
83
- * - account string if applicable, the user/account name for the integrated system
84
- * - profiles array For Facebook, users/page that can be posted to.
85
- * - id string the user or page id
86
- * - name string the user or page name
87
- * - is_page bool whether this is a user or a page
88
- */
89
- public function accountDetails($exclude=array()) {
90
- $_params = array("exclude" => $exclude);
91
- return $this->master->call('helper/account-details', $_params);
92
- }
93
-
94
- /**
95
- * Retrieve minimal data for all Campaigns a member was sent
96
- * @param associative_array $email
97
- * - email string an email address
98
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
99
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
100
- * @param associative_array $options
101
- * - list_id string optional A list_id to limit the campaigns to
102
- * @return array an array of structs containing campaign data for each matching campaign (ordered by send time ascending), including:
103
- * - id string the campaign unique id
104
- * - title string the campaign's title
105
- * - subject string the campaign's subject
106
- * - send_time string the time the campaign was sent
107
- * - type string the campaign type
108
- */
109
- public function campaignsForEmail($email, $options=null) {
110
- $_params = array("email" => $email, "options" => $options);
111
- return $this->master->call('helper/campaigns-for-email', $_params);
112
- }
113
-
114
- /**
115
- * Return the current Chimp Chatter messages for an account.
116
- * @return array An array of structs containing data for each chatter message
117
- * - message string The chatter message
118
- * - type string The type of the message - one of lists:new-subscriber, lists:unsubscribes, lists:profile-updates, campaigns:facebook-likes, campaigns:facebook-comments, campaigns:forward-to-friend, lists:imports, or campaigns:inbox-inspections
119
- * - url string a url into the web app that the message could link to, if applicable
120
- * - list_id string the list_id a message relates to, if applicable. Deleted lists will return -DELETED-
121
- * - campaign_id string the list_id a message relates to, if applicable. Deleted campaigns will return -DELETED-
122
- * - update_time string The date/time the message was last updated
123
- */
124
- public function chimpChatter() {
125
- $_params = array();
126
- return $this->master->call('helper/chimp-chatter', $_params);
127
- }
128
-
129
- /**
130
- * Have HTML content auto-converted to a text-only format. You can send: plain HTML, an existing Campaign Id, or an existing Template Id. Note that this will <strong>not</strong> save anything to or update any of your lists, campaigns, or templates.
131
- It's also not just Lynx and is very fine tuned for our template layouts - your mileage may vary.
132
- * @param string $type
133
- * @param associative_array $content
134
- * - html string optional a single string value,
135
- * - cid string a valid Campaign Id
136
- * - user_template_id string the id of a user template
137
- * - base_template_id string the id of a built in base/basic template
138
- * - gallery_template_id string the id of a built in gallery template
139
- * - url string a valid & public URL to pull html content from
140
- * @return associative_array the content pass in converted to text.
141
- * - text string the converted html
142
- */
143
- public function generateText($type, $content) {
144
- $_params = array("type" => $type, "content" => $content);
145
- return $this->master->call('helper/generate-text', $_params);
146
- }
147
-
148
- /**
149
- * Send your HTML content to have the CSS inlined and optionally remove the original styles.
150
- * @param string $html
151
- * @param bool $strip_css
152
- * @return associative_array with a "html" key
153
- * - html string Your HTML content with all CSS inlined, just like if we sent it.
154
- */
155
- public function inlineCss($html, $strip_css=false) {
156
- $_params = array("html" => $html, "strip_css" => $strip_css);
157
- return $this->master->call('helper/inline-css', $_params);
158
- }
159
-
160
- /**
161
- * Retrieve minimal List data for all lists a member is subscribed to.
162
- * @param associative_array $email
163
- * - email string an email address
164
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
165
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
166
- * @return array An array of structs with info on the list_id the member is subscribed to.
167
- * - id string the list unique id
168
- * - web_id int the id referenced in web interface urls
169
- * - name string the list name
170
- */
171
- public function listsForEmail($email) {
172
- $_params = array("email" => $email);
173
- return $this->master->call('helper/lists-for-email', $_params);
174
- }
175
-
176
- /**
177
- * "Ping" the MailChimp API - a simple method you can call that will return a constant value as long as everything is good. Note
178
- than unlike most all of our methods, we don't throw an Exception if we are having issues. You will simply receive a different
179
- string back that will explain our view on what is going on.
180
- * @return associative_array a with a "msg" key
181
- * - msg string containing "Everything's Chimpy!" if everything is chimpy, otherwise returns an error message
182
- */
183
- public function ping() {
184
- $_params = array();
185
- return $this->master->call('helper/ping', $_params);
186
- }
187
-
188
- /**
189
- * Search all campaigns for the specified query terms
190
- * @param string $query
191
- * @param int $offset
192
- * @param string $snip_start
193
- * @param string $snip_end
194
- * @return associative_array containing the total matches and current results
195
- * - total int total campaigns matching
196
- * - results array matching campaigns and snippets
197
- * - snippet string the matching snippet for the campaign
198
- * - campaign associative_array the matching campaign's details - will return same data as single campaign from campaigns/list()
199
- */
200
- public function searchCampaigns($query, $offset=0, $snip_start=null, $snip_end=null) {
201
- $_params = array("query" => $query, "offset" => $offset, "snip_start" => $snip_start, "snip_end" => $snip_end);
202
- return $this->master->call('helper/search-campaigns', $_params);
203
- }
204
-
205
- /**
206
- * Search account wide or on a specific list using the specified query terms
207
- * @param string $query
208
- * @param string $id
209
- * @param int $offset
210
- * @return associative_array An array of both exact matches and partial matches over a full search
211
- * - exact_matches associative_array containing the exact email address matches and current results
212
- * - total int total members matching
213
- * - members array each entry will be struct matching the data format for a single member as returned by lists/member-info()
214
- * - full_search associative_array containing the total matches and current results
215
- * - total int total members matching
216
- * - members array each entry will be struct matching the data format for a single member as returned by lists/member-info()
217
- */
218
- public function searchMembers($query, $id=null, $offset=0) {
219
- $_params = array("query" => $query, "id" => $id, "offset" => $offset);
220
- return $this->master->call('helper/search-members', $_params);
221
- }
222
-
223
- /**
224
- * Retrieve all domain verification records for an account
225
- * @return array structs for each domain verification has been attempted for
226
- * - domain string the verified domain
227
- * - status string the status of the verification - either "verified" or "pending"
228
- * - email string the email address used for verification - "pre-existing" if we automatically backfilled it at some point
229
- */
230
- public function verifiedDomains() {
231
- $_params = array();
232
- return $this->master->call('helper/verified-domains', $_params);
233
- }
234
-
235
- }
236
-
237
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Lists.php DELETED
@@ -1,904 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Lists {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Get all email addresses that complained about a campaign sent to a list
10
- * @param string $id
11
- * @param int $start
12
- * @param int $limit
13
- * @param string $since
14
- * @return associative_array the total of all reports and the specific reports reports this page
15
- * - total int the total number of matching abuse reports
16
- * - data array structs for the actual data for each reports, including:
17
- * - date string date+time the abuse report was received and processed
18
- * - email string the email address that reported abuse
19
- * - campaign_id string the unique id for the campaign that report was made against
20
- * - type string an internal type generally specifying the originating mail provider - may not be useful outside of filling report views
21
- */
22
- public function abuseReports($id, $start=0, $limit=500, $since=null) {
23
- $_params = array("id" => $id, "start" => $start, "limit" => $limit, "since" => $since);
24
- return $this->master->call('lists/abuse-reports', $_params);
25
- }
26
-
27
- /**
28
- * Access up to the previous 180 days of daily detailed aggregated activity stats for a given list. Does not include AutoResponder activity.
29
- * @param string $id
30
- * @return array of structs containing daily values, each containing:
31
- */
32
- public function activity($id) {
33
- $_params = array("id" => $id);
34
- return $this->master->call('lists/activity', $_params);
35
- }
36
-
37
- /**
38
- * Subscribe a batch of email addresses to a list at once. If you are using a serialized version of the API, we strongly suggest that you
39
- only run this method as a POST request, and <em>not</em> a GET request. Maximum batch sizes vary based on the amount of data in each record,
40
- though you should cap them at 5k - 10k records, depending on your experience. These calls are also long, so be sure you increase your timeout values.
41
- * @param string $id
42
- * @param array $batch
43
- * - email associative_array a struct with one of the following keys - failing to provide anything will produce an error relating to the email address. Provide multiples and we'll use the first we see in this same order.
44
- * - email string an email address
45
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
46
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
47
- * - email_type string for the email type option (html or text)
48
- * - merge_vars associative_array data for the various list specific and special merge vars documented in lists/subscribe
49
- * @param boolean $double_optin
50
- * @param boolean $update_existing
51
- * @param boolean $replace_interests
52
- * @return associative_array struct of result counts and associated data
53
- * - add_count int Number of email addresses that were successfully added
54
- * - adds array array of structs for each add
55
- * - email string the email address added
56
- * - euid string the email unique id
57
- * - leid string the list member's truly unique id
58
- * - update_count int Number of email addresses that were successfully updated
59
- * - updates array array of structs for each update
60
- * - email string the email address added
61
- * - euid string the email unique id
62
- * - leid string the list member's truly unique id
63
- * - error_count int Number of email addresses that failed during addition/updating
64
- * - errors array array of error structs including:
65
- * - email string whatever was passed in the batch record's email parameter
66
- * - email string the email address added
67
- * - euid string the email unique id
68
- * - leid string the list member's truly unique id
69
- * - code int the error code
70
- * - error string the full error message
71
- * - row associative_array the row from the batch that caused the error
72
- */
73
- public function batchSubscribe($id, $batch, $double_optin=true, $update_existing=false, $replace_interests=true) {
74
- $_params = array("id" => $id, "batch" => $batch, "double_optin" => $double_optin, "update_existing" => $update_existing, "replace_interests" => $replace_interests);
75
- return $this->master->call('lists/batch-subscribe', $_params);
76
- }
77
-
78
- /**
79
- * Unsubscribe a batch of email addresses from a list
80
- * @param string $id
81
- * @param array $batch
82
- * - email string an email address
83
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
84
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
85
- * @param boolean $delete_member
86
- * @param boolean $send_goodbye
87
- * @param boolean $send_notify
88
- * @return array Array of structs containing results and any errors that occurred
89
- * - success_count int Number of email addresses that were successfully removed
90
- * - error_count int Number of email addresses that failed during addition/updating
91
- * - errors array array of error structs including:
92
- * - email string whatever was passed in the batch record's email parameter
93
- * - email string the email address added
94
- * - euid string the email unique id
95
- * - leid string the list member's truly unique id
96
- * - code int the error code
97
- * - error string the full error message
98
- */
99
- public function batchUnsubscribe($id, $batch, $delete_member=false, $send_goodbye=true, $send_notify=false) {
100
- $_params = array("id" => $id, "batch" => $batch, "delete_member" => $delete_member, "send_goodbye" => $send_goodbye, "send_notify" => $send_notify);
101
- return $this->master->call('lists/batch-unsubscribe', $_params);
102
- }
103
-
104
- /**
105
- * Retrieve the clients that the list's subscribers have been tagged as being used based on user agents seen. Made possible by <a href="http://user-agent-string.info" target="_blank">user-agent-string.info</a>
106
- * @param string $id
107
- * @return associative_array the desktop and mobile user agents in use on the list
108
- * - desktop associative_array desktop user agents and percentages
109
- * - penetration double the percent of desktop clients in use
110
- * - clients array array of structs for each client including:
111
- * - client string the common name for the client
112
- * - icon string a url to an image representing this client
113
- * - percent string percent of list using the client
114
- * - members string total members using the client
115
- * - mobile associative_array mobile user agents and percentages
116
- * - penetration double the percent of mobile clients in use
117
- * - clients array array of structs for each client including:
118
- * - client string the common name for the client
119
- * - icon string a url to an image representing this client
120
- * - percent string percent of list using the client
121
- * - members string total members using the client
122
- */
123
- public function clients($id) {
124
- $_params = array("id" => $id);
125
- return $this->master->call('lists/clients', $_params);
126
- }
127
-
128
- /**
129
- * Access the Growth History by Month in aggregate or for a given list.
130
- * @param string $id
131
- * @return array array of structs containing months and growth data
132
- * - month string The Year and Month in question using YYYY-MM format
133
- * - existing int number of existing subscribers to start the month
134
- * - imports int number of subscribers imported during the month
135
- * - optins int number of subscribers who opted-in during the month
136
- */
137
- public function growthHistory($id=null) {
138
- $_params = array("id" => $id);
139
- return $this->master->call('lists/growth-history', $_params);
140
- }
141
-
142
- /**
143
- * Get the list of interest groupings for a given list, including the label, form information, and included groups for each
144
- * @param string $id
145
- * @param bool $counts
146
- * @return array array of structs of the interest groupings for the list
147
- * - id int The id for the Grouping
148
- * - name string Name for the Interest groups
149
- * - form_field string Gives the type of interest group: checkbox,radio,select
150
- * - groups array Array structs of the grouping options (interest groups) including:
151
- * - bit string the bit value - not really anything to be done with this
152
- * - name string the name of the group
153
- * - display_order string the display order of the group, if set
154
- * - subscribers int total number of subscribers who have this group if "counts" is true. otherwise empty
155
- */
156
- public function interestGroupings($id, $counts=false) {
157
- $_params = array("id" => $id, "counts" => $counts);
158
- return $this->master->call('lists/interest-groupings', $_params);
159
- }
160
-
161
- /**
162
- * Add a single Interest Group - if interest groups for the List are not yet enabled, adding the first
163
- group will automatically turn them on.
164
- * @param string $id
165
- * @param string $group_name
166
- * @param int $grouping_id
167
- * @return associative_array with a single entry:
168
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
169
- */
170
- public function interestGroupAdd($id, $group_name, $grouping_id=null) {
171
- $_params = array("id" => $id, "group_name" => $group_name, "grouping_id" => $grouping_id);
172
- return $this->master->call('lists/interest-group-add', $_params);
173
- }
174
-
175
- /**
176
- * Delete a single Interest Group - if the last group for a list is deleted, this will also turn groups for the list off.
177
- * @param string $id
178
- * @param string $group_name
179
- * @param int $grouping_id
180
- * @return associative_array with a single entry:
181
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
182
- */
183
- public function interestGroupDel($id, $group_name, $grouping_id=null) {
184
- $_params = array("id" => $id, "group_name" => $group_name, "grouping_id" => $grouping_id);
185
- return $this->master->call('lists/interest-group-del', $_params);
186
- }
187
-
188
- /**
189
- * Change the name of an Interest Group
190
- * @param string $id
191
- * @param string $old_name
192
- * @param string $new_name
193
- * @param int $grouping_id
194
- * @return associative_array with a single entry:
195
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
196
- */
197
- public function interestGroupUpdate($id, $old_name, $new_name, $grouping_id=null) {
198
- $_params = array("id" => $id, "old_name" => $old_name, "new_name" => $new_name, "grouping_id" => $grouping_id);
199
- return $this->master->call('lists/interest-group-update', $_params);
200
- }
201
-
202
- /**
203
- * Add a new Interest Grouping - if interest groups for the List are not yet enabled, adding the first
204
- grouping will automatically turn them on.
205
- * @param string $id
206
- * @param string $name
207
- * @param string $type
208
- * @param array $groups
209
- * @return associative_array with a single entry:
210
- * - id int the new grouping id if the request succeeds, otherwise an error will be thrown
211
- */
212
- public function interestGroupingAdd($id, $name, $type, $groups) {
213
- $_params = array("id" => $id, "name" => $name, "type" => $type, "groups" => $groups);
214
- return $this->master->call('lists/interest-grouping-add', $_params);
215
- }
216
-
217
- /**
218
- * Delete an existing Interest Grouping - this will permanently delete all contained interest groups and will remove those selections from all list members
219
- * @param int $grouping_id
220
- * @return associative_array with a single entry:
221
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
222
- */
223
- public function interestGroupingDel($grouping_id) {
224
- $_params = array("grouping_id" => $grouping_id);
225
- return $this->master->call('lists/interest-grouping-del', $_params);
226
- }
227
-
228
- /**
229
- * Update an existing Interest Grouping
230
- * @param int $grouping_id
231
- * @param string $name
232
- * @param string $value
233
- * @return associative_array with a single entry:
234
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
235
- */
236
- public function interestGroupingUpdate($grouping_id, $name, $value) {
237
- $_params = array("grouping_id" => $grouping_id, "name" => $name, "value" => $value);
238
- return $this->master->call('lists/interest-grouping-update', $_params);
239
- }
240
-
241
- /**
242
- * Retrieve the locations (countries) that the list's subscribers have been tagged to based on geocoding their IP address
243
- * @param string $id
244
- * @return array array of locations
245
- * - country string the country name
246
- * - cc string the ISO 3166 2 digit country code
247
- * - percent double the percent of subscribers in the country
248
- * - total double the total number of subscribers in the country
249
- */
250
- public function locations($id) {
251
- $_params = array("id" => $id);
252
- return $this->master->call('lists/locations', $_params);
253
- }
254
-
255
- /**
256
- * Get the most recent 100 activities for particular list members (open, click, bounce, unsub, abuse, sent to, etc.)
257
- * @param string $id
258
- * @param array $emails
259
- * - email string an email address - for new subscribers obviously this should be used
260
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
261
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
262
- * @return associative_array of data and success/error counts
263
- * - success_count int the number of subscribers successfully found on the list
264
- * - error_count int the number of subscribers who were not found on the list
265
- * - errors array array of error structs including:
266
- * - email string whatever was passed in the email parameter
267
- * - email string the email address added
268
- * - euid string the email unique id
269
- * - leid string the list member's truly unique id
270
- * - error string the error message
271
- * - code string the error code
272
- * - data array an array of structs where each activity record has:
273
- * - email string whatever was passed in the email parameter
274
- * - email string the email address added
275
- * - euid string the email unique id
276
- * - leid string the list member's truly unique id
277
- * - activity array an array of structs containing the activity, including:
278
- * - action string The action name, one of: open, click, bounce, unsub, abuse, sent, queued, ecomm, mandrill_send, mandrill_hard_bounce, mandrill_soft_bounce, mandrill_open, mandrill_click, mandrill_spam, mandrill_unsub, mandrill_reject
279
- * - timestamp string The date+time of the action (GMT)
280
- * - url string For click actions, the url clicked, otherwise this is empty
281
- * - type string If there's extra bounce, unsub, etc data it will show up here.
282
- * - campaign_id string The campaign id the action was related to, if it exists - otherwise empty (ie, direct unsub from list)
283
- * - campaign_data associative_array If not deleted, the campaigns/list data for the campaign
284
- */
285
- public function memberActivity($id, $emails) {
286
- $_params = array("id" => $id, "emails" => $emails);
287
- return $this->master->call('lists/member-activity', $_params);
288
- }
289
-
290
- /**
291
- * Get all the information for particular members of a list
292
- * @param string $id
293
- * @param array $emails
294
- * - email string an email address - for new subscribers obviously this should be used
295
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
296
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
297
- * @return associative_array of data and success/error counts
298
- * - success_count int the number of subscribers successfully found on the list
299
- * - error_count int the number of subscribers who were not found on the list
300
- * - errors array array of error structs including:
301
- * - email associative_array whatever was passed in the email parameter
302
- * - email string the email address added
303
- * - euid string the email unique id
304
- * - leid string the list member's truly unique id
305
- * - error string the error message
306
- * - data array array of structs for each valid list member
307
- * - id string The unique id (euid) for this email address on an account
308
- * - email string The email address associated with this record
309
- * - email_type string The type of emails this customer asked to get: html or text
310
- * - merges associative_array a struct containing a key for each merge tags and the data for those tags for this email address, plus:
311
- * - GROUPINGS array if Interest groupings are enabled, this will exist with structs for each grouping:
312
- * - id int the grouping id
313
- * - name string the interest group name
314
- * - groups array structs for each group in the grouping
315
- * - name string the group name
316
- * - interested bool whether the member has this group selected
317
- * - status string The subscription status for this email address, either pending, subscribed, unsubscribed, or cleaned
318
- * - ip_signup string IP Address this address signed up from. This may be blank if single optin is used.
319
- * - timestamp_signup string The date+time the double optin was initiated. This may be blank if single optin is used.
320
- * - ip_opt string IP Address this address opted in from.
321
- * - timestamp_opt string The date+time the optin completed
322
- * - member_rating int the rating of the subscriber. This will be 1 - 5 as described <a href="http://eepurl.com/f-2P" target="_blank">here</a>
323
- * - campaign_id string If the user is unsubscribed and they unsubscribed from a specific campaign, that campaign_id will be listed, otherwise this is not returned.
324
- * - lists array An array of structs for the other lists this member belongs to
325
- * - id string the list id
326
- * - status string the members status on that list
327
- * - timestamp string The date+time this email address entered it's current status
328
- * - info_changed string The last time this record was changed. If the record is old enough, this may be blank.
329
- * - web_id int The Member id used in our web app, allows you to create a link directly to it
330
- * - leid int The Member id used in our web app, allows you to create a link directly to it
331
- * - list_id string The list id the for the member record being returned
332
- * - list_name string The list name the for the member record being returned
333
- * - language string if set/detected, a language code from <a href="http://kb.mailchimp.com/article/can-i-see-what-languages-my-subscribers-use#code" target="_blank">here</a>
334
- * - is_gmonkey bool Whether the member is a <a href="http://mailchimp.com/features/golden-monkeys/" target="_blank">Golden Monkey</a> or not.
335
- * - geo associative_array the geographic information if we have it. including:
336
- * - latitude string the latitude
337
- * - longitude string the longitude
338
- * - gmtoff string GMT offset
339
- * - dstoff string GMT offset during daylight savings (if DST not observered, will be same as gmtoff)
340
- * - timezone string the timezone we've place them in
341
- * - cc string 2 digit ISO-3166 country code
342
- * - region string generally state, province, or similar
343
- * - clients associative_array the client we've tracked the address as using with two keys:
344
- * - name string the common name of the client
345
- * - icon_url string a url representing a path to an icon representing this client
346
- * - static_segments array structs for each static segments the member is a part of including:
347
- * - id int the segment id
348
- * - name string the name given to the segment
349
- * - added string the date the member was added
350
- * - notes array structs for each note entered for this member. For each note:
351
- * - id int the note id
352
- * - note string the text entered
353
- * - created string the date the note was created
354
- * - updated string the date the note was last updated
355
- * - created_by_name string the name of the user who created the note. This can change as users update their profile.
356
- */
357
- public function memberInfo($id, $emails) {
358
- $_params = array("id" => $id, "emails" => $emails);
359
- return $this->master->call('lists/member-info', $_params);
360
- }
361
-
362
- /**
363
- * Get all of the list members for a list that are of a particular status and potentially matching a segment. This will cause locking, so don't run multiples at once. Are you trying to get a dump including lots of merge
364
- data or specific members of a list? If so, checkout the <a href="/export/1.0/list.func.php">List Export API</a>
365
- * @param string $id
366
- * @param string $status
367
- * @param associative_array $opts
368
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
369
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
370
- * - sort_field string optional the data field to sort by - mergeX (1-30), your custom merge tags, "email", "rating","last_update_time", or "optin_time" - invalid fields will be ignored
371
- * - sort_dir string optional the direct - ASC or DESC. defaults to ASC (case insensitive)
372
- * - segment associative_array a properly formatted segment that works with campaigns/segment-test
373
- * @return associative_array of the total records matched and limited list member data for this page
374
- * - total int the total matching records
375
- * - data array structs for each member as returned by member-info
376
- */
377
- public function members($id, $status='subscribed', $opts=array()) {
378
- $_params = array("id" => $id, "status" => $status, "opts" => $opts);
379
- return $this->master->call('lists/members', $_params);
380
- }
381
-
382
- /**
383
- * Add a new merge tag to a given list
384
- * @param string $id
385
- * @param string $tag
386
- * @param string $name
387
- * @param associative_array $options
388
- * - field_type string optional one of: text, number, radio, dropdown, date, address, phone, url, imageurl, zip, birthday - defaults to text
389
- * - req boolean optional indicates whether the field is required - defaults to false
390
- * - public boolean optional indicates whether the field is displayed in public - defaults to true
391
- * - show boolean optional indicates whether the field is displayed in the app's list member view - defaults to true
392
- * - order int The order this merge tag should be displayed in - this will cause existing values to be reset so this fits
393
- * - default_value string optional the default value for the field. See lists/subscribe() for formatting info. Defaults to blank - max 255 bytes
394
- * - helptext string optional the help text to be used with some newer forms. Defaults to blank - max 255 bytes
395
- * - choices array optional kind of - an array of strings to use as the choices for radio and dropdown type fields
396
- * - dateformat string optional only valid for birthday and date fields. For birthday type, must be "MM/DD" (default) or "DD/MM". For date type, must be "MM/DD/YYYY" (default) or "DD/MM/YYYY". Any other values will be converted to the default.
397
- * - phoneformat string optional "US" is the default - any other value will cause them to be unformatted (international)
398
- * - defaultcountry string optional the <a href="http://www.iso.org/iso/english_country_names_and_code_elements" target="_blank">ISO 3166 2 digit character code</a> for the default country. Defaults to "US". Anything unrecognized will be converted to the default.
399
- * @return associative_array the full data for the new merge var, just like merge-vars returns
400
- * - name string Name/description of the merge field
401
- * - req bool Denotes whether the field is required (true) or not (false)
402
- * - field_type string The "data type" of this merge var. One of: email, text, number, radio, dropdown, date, address, phone, url, imageurl
403
- * - public bool Whether or not this field is visible to list subscribers
404
- * - show bool Whether the field is displayed in thelist dashboard
405
- * - order string The order this field displays in on forms
406
- * - default string The default value for this field
407
- * - helptext string The helptext for this field
408
- * - size string The width of the field to be used
409
- * - tag string The merge tag that's used for forms and lists/subscribe() and lists/update-member()
410
- * - choices array the options available for radio and dropdown field types
411
- * - id int an unchanging id for the merge var
412
- */
413
- public function mergeVarAdd($id, $tag, $name, $options=array()) {
414
- $_params = array("id" => $id, "tag" => $tag, "name" => $name, "options" => $options);
415
- return $this->master->call('lists/merge-var-add', $_params);
416
- }
417
-
418
- /**
419
- * Delete a merge tag from a given list and all its members. Seriously - the data is removed from all members as well!
420
- Note that on large lists this method may seem a bit slower than calls you typically make.
421
- * @param string $id
422
- * @param string $tag
423
- * @return associative_array with a single entry:
424
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
425
- */
426
- public function mergeVarDel($id, $tag) {
427
- $_params = array("id" => $id, "tag" => $tag);
428
- return $this->master->call('lists/merge-var-del', $_params);
429
- }
430
-
431
- /**
432
- * Completely resets all data stored in a merge var on a list. All data is removed and this action can not be undone.
433
- * @param string $id
434
- * @param string $tag
435
- * @return associative_array with a single entry:
436
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
437
- */
438
- public function mergeVarReset($id, $tag) {
439
- $_params = array("id" => $id, "tag" => $tag);
440
- return $this->master->call('lists/merge-var-reset', $_params);
441
- }
442
-
443
- /**
444
- * Sets a particular merge var to the specified value for every list member. Only merge var ids 1 - 30 may be modified this way. This is generally a dirty method
445
- unless you're fixing data since you should probably be using default_values and/or conditional content. as with lists/merge-var-reset(), this can not be undone.
446
- * @param string $id
447
- * @param string $tag
448
- * @param string $value
449
- * @return associative_array with a single entry:
450
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
451
- */
452
- public function mergeVarSet($id, $tag, $value) {
453
- $_params = array("id" => $id, "tag" => $tag, "value" => $value);
454
- return $this->master->call('lists/merge-var-set', $_params);
455
- }
456
-
457
- /**
458
- * Update most parameters for a merge tag on a given list. You cannot currently change the merge type
459
- * @param string $id
460
- * @param string $tag
461
- * @param associative_array $options
462
- * @return associative_array the full data for the new merge var, just like merge-vars returns
463
- * - name string Name/description of the merge field
464
- * - req bool Denotes whether the field is required (true) or not (false)
465
- * - field_type string The "data type" of this merge var. One of: email, text, number, radio, dropdown, date, address, phone, url, imageurl
466
- * - public bool Whether or not this field is visible to list subscribers
467
- * - show bool Whether the field is displayed in thelist dashboard
468
- * - order string The order this field to displays in on forms
469
- * - default string The default value for this field
470
- * - helptext string The helptext for this field
471
- * - size string The width of the field to be used
472
- * - tag string The merge tag that's used for forms and lists/subscribe() and lists/update-member()
473
- * - choices array the options available for radio and dropdown field types
474
- * - id int an unchanging id for the merge var
475
- */
476
- public function mergeVarUpdate($id, $tag, $options) {
477
- $_params = array("id" => $id, "tag" => $tag, "options" => $options);
478
- return $this->master->call('lists/merge-var-update', $_params);
479
- }
480
-
481
- /**
482
- * Get the list of merge tags for a given list, including their name, tag, and required setting
483
- * @param array $id
484
- * @return associative_array of data and success/error counts
485
- * - success_count int the number of subscribers successfully found on the list
486
- * - error_count int the number of subscribers who were not found on the list
487
- * - data array of structs for the merge tags on each list
488
- * - id string the list id
489
- * - name string the list name
490
- * - merge_vars array of structs for each merge var
491
- * - name string Name of the merge field
492
- * - req bool Denotes whether the field is required (true) or not (false)
493
- * - field_type string The "data type" of this merge var. One of the options accepted by field_type in lists/merge-var-add
494
- * - public bool Whether or not this field is visible to list subscribers
495
- * - show bool Whether the list owner has this field displayed on their list dashboard
496
- * - order string The order the list owner has set this field to display in
497
- * - default string The default value the list owner has set for this field
498
- * - helptext string The helptext for this field
499
- * - size string The width of the field to be used
500
- * - tag string The merge tag that's used for forms and lists/subscribe() and listUpdateMember()
501
- * - choices array For radio and dropdown field types, an array of the options available
502
- * - id int an unchanging id for the merge var
503
- * - errors array of error structs
504
- * - id string the passed list id that failed
505
- * - code int the resulting error code
506
- * - msg string the resulting error message
507
- */
508
- public function mergeVars($id) {
509
- $_params = array("id" => $id);
510
- return $this->master->call('lists/merge-vars', $_params);
511
- }
512
-
513
- /**
514
- * Retrieve all of Segments for a list.
515
- * @param string $id
516
- * @param string $type
517
- * @return associative_array with 2 keys:
518
- * - static array of structs with data for each segment
519
- * - id int the id of the segment
520
- * - name string the name for the segment
521
- * - created_date string the date+time the segment was created
522
- * - last_update string the date+time the segment was last updated (add or del)
523
- * - last_reset string the date+time the segment was last reset (ie had all members cleared from it)
524
- * - saved array of structs with data for each segment
525
- * - id int the id of the segment
526
- * - name string the name for the segment
527
- * - segment_opts string same match+conditions struct typically used
528
- * - segment_text string a textual description of the segment match/conditions
529
- * - created_date string the date+time the segment was created
530
- * - last_update string the date+time the segment was last updated (add or del)
531
- */
532
- public function segments($id, $type=null) {
533
- $_params = array("id" => $id, "type" => $type);
534
- return $this->master->call('lists/segments', $_params);
535
- }
536
-
537
- /**
538
- * Save a segment against a list for later use. There is no limit to the number of segments which can be saved. Static Segments <strong>are not</strong> tied
539
- to any merge data, interest groups, etc. They essentially allow you to configure an unlimited number of custom segments which will have standard performance.
540
- When using proper segments, Static Segments are one of the available options for segmentation just as if you used a merge var (and they can be used with other segmentation
541
- options), though performance may degrade at that point. Saved Segments (called "auto-updating" in the app) are essentially just the match+conditions typically
542
- used.
543
- * @param string $id
544
- * @param associative_array $opts
545
- * - type string either "static" or "saved"
546
- * - name string a unique name per list for the segment - 100 byte maximum length, anything longer will throw an error
547
- * - segment_opts associative_array for "saved" only, the standard segment match+conditions, just like campaigns/segment-test
548
- * - match string "any" or "all"
549
- * - conditions array structs for each condition, just like campaigns/segment-test
550
- * @return associative_array with a single entry:
551
- * - id int the id of the new segment, otherwise an error will be thrown.
552
- */
553
- public function segmentAdd($id, $opts) {
554
- $_params = array("id" => $id, "opts" => $opts);
555
- return $this->master->call('lists/segment-add', $_params);
556
- }
557
-
558
- /**
559
- * Delete a segment. Note that this will, of course, remove any member affiliations with any static segments deleted
560
- * @param string $id
561
- * @param int $seg_id
562
- * @return associative_array with a single entry:
563
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
564
- */
565
- public function segmentDel($id, $seg_id) {
566
- $_params = array("id" => $id, "seg_id" => $seg_id);
567
- return $this->master->call('lists/segment-del', $_params);
568
- }
569
-
570
- /**
571
- * Allows one to test their segmentation rules before creating a campaign using them - this is no different from campaigns/segment-test() and will eventually replace it.
572
- For the time being, the crazy segmenting condition documentation will continue to live over there.
573
- * @param string $list_id
574
- * @param associative_array $options
575
- * @return associative_array with a single entry:
576
- * - total int The total number of subscribers matching your segmentation options
577
- */
578
- public function segmentTest($list_id, $options) {
579
- $_params = array("list_id" => $list_id, "options" => $options);
580
- return $this->master->call('lists/segment-test', $_params);
581
- }
582
-
583
- /**
584
- * Update an existing segment. The list and type can not be changed.
585
- * @param string $id
586
- * @param int $seg_id
587
- * @param associative_array $opts
588
- * - name string a unique name per list for the segment - 100 byte maximum length, anything longer will throw an error
589
- * - segment_opts associative_array for "saved" only, the standard segment match+conditions, just like campaigns/segment-test
590
- * - match string "any" or "all"
591
- * - conditions array structs for each condition, just like campaigns/segment-test
592
- * @return associative_array with a single entry:
593
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
594
- */
595
- public function segmentUpdate($id, $seg_id, $opts) {
596
- $_params = array("id" => $id, "seg_id" => $seg_id, "opts" => $opts);
597
- return $this->master->call('lists/segment-update', $_params);
598
- }
599
-
600
- /**
601
- * Save a segment against a list for later use. There is no limit to the number of segments which can be saved. Static Segments <strong>are not</strong> tied
602
- to any merge data, interest groups, etc. They essentially allow you to configure an unlimited number of custom segments which will have standard performance.
603
- When using proper segments, Static Segments are one of the available options for segmentation just as if you used a merge var (and they can be used with other segmentation
604
- options), though performance may degrade at that point.
605
- * @param string $id
606
- * @param string $name
607
- * @return associative_array with a single entry:
608
- * - id int the id of the new segment, otherwise an error will be thrown.
609
- */
610
- public function staticSegmentAdd($id, $name) {
611
- $_params = array("id" => $id, "name" => $name);
612
- return $this->master->call('lists/static-segment-add', $_params);
613
- }
614
-
615
- /**
616
- * Delete a static segment. Note that this will, of course, remove any member affiliations with the segment
617
- * @param string $id
618
- * @param int $seg_id
619
- * @return associative_array with a single entry:
620
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
621
- */
622
- public function staticSegmentDel($id, $seg_id) {
623
- $_params = array("id" => $id, "seg_id" => $seg_id);
624
- return $this->master->call('lists/static-segment-del', $_params);
625
- }
626
-
627
- /**
628
- * Add list members to a static segment. It is suggested that you limit batch size to no more than 10,000 addresses per call. Email addresses must exist on the list
629
- in order to be included - this <strong>will not</strong> subscribe them to the list!
630
- * @param string $id
631
- * @param int $seg_id
632
- * @param array $batch
633
- * - email string an email address
634
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
635
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
636
- * @return associative_array an array with the results of the operation
637
- * - success_count int the total number of successful updates (will include members already in the segment)
638
- * - errors array structs for each error including:
639
- * - email string whatever was passed in the email parameter
640
- * - email string the email address added
641
- * - euid string the email unique id
642
- * - leid string the list member's truly unique id
643
- * - code string the error code
644
- * - error string the full error message
645
- */
646
- public function staticSegmentMembersAdd($id, $seg_id, $batch) {
647
- $_params = array("id" => $id, "seg_id" => $seg_id, "batch" => $batch);
648
- return $this->master->call('lists/static-segment-members-add', $_params);
649
- }
650
-
651
- /**
652
- * Remove list members from a static segment. It is suggested that you limit batch size to no more than 10,000 addresses per call. Email addresses must exist on the list
653
- in order to be removed - this <strong>will not</strong> unsubscribe them from the list!
654
- * @param string $id
655
- * @param int $seg_id
656
- * @param array $batch
657
- * - email string an email address
658
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
659
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
660
- * @return associative_array an array with the results of the operation
661
- * - success_count int the total number of successful removals
662
- * - error_count int the total number of unsuccessful removals
663
- * - errors array structs for each error including:
664
- * - email string whatever was passed in the email parameter
665
- * - email string the email address added
666
- * - euid string the email unique id
667
- * - leid string the list member's truly unique id
668
- * - code string the error code
669
- * - error string the full error message
670
- */
671
- public function staticSegmentMembersDel($id, $seg_id, $batch) {
672
- $_params = array("id" => $id, "seg_id" => $seg_id, "batch" => $batch);
673
- return $this->master->call('lists/static-segment-members-del', $_params);
674
- }
675
-
676
- /**
677
- * Resets a static segment - removes <strong>all</strong> members from the static segment. Note: does not actually affect list member data
678
- * @param string $id
679
- * @param int $seg_id
680
- * @return associative_array with a single entry:
681
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
682
- */
683
- public function staticSegmentReset($id, $seg_id) {
684
- $_params = array("id" => $id, "seg_id" => $seg_id);
685
- return $this->master->call('lists/static-segment-reset', $_params);
686
- }
687
-
688
- /**
689
- * Retrieve all of the Static Segments for a list.
690
- * @param string $id
691
- * @param boolean $get_counts
692
- * @param int $start
693
- * @param int $limit
694
- * @return array an of structs with data for each static segment
695
- * - id int the id of the segment
696
- * - name string the name for the segment
697
- * - member_count int the total number of subscribed members currently in a segment
698
- * - created_date string the date+time the segment was created
699
- * - last_update string the date+time the segment was last updated (add or del)
700
- * - last_reset string the date+time the segment was last reset (ie had all members cleared from it)
701
- */
702
- public function staticSegments($id, $get_counts=true, $start=0, $limit=null) {
703
- $_params = array("id" => $id, "get_counts" => $get_counts, "start" => $start, "limit" => $limit);
704
- return $this->master->call('lists/static-segments', $_params);
705
- }
706
-
707
- /**
708
- * Subscribe the provided email to a list. By default this sends a confirmation email - you will not see new members until the link contained in it is clicked!
709
- * @param string $id
710
- * @param associative_array $email
711
- * - email string an email address - for new subscribers obviously this should be used
712
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
713
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
714
- * @param associative_array $merge_vars
715
- * - new-email string set this to change the email address. This is only respected on calls using update_existing or when passed to lists/update.
716
- * - groupings array of Interest Grouping structs. Each should contain:
717
- * - id int Grouping "id" from lists/interest-groupings (either this or name must be present) - this id takes precedence and can't change (unlike the name)
718
- * - name string Grouping "name" from lists/interest-groupings (either this or id must be present)
719
- * - groups array an array of valid group names for this grouping.
720
- * - optin_ip string Set the Opt-in IP field. <em>Abusing this may cause your account to be suspended.</em> We do validate this and it must not be a private IP address.
721
- * - optin_time string Set the Opt-in Time field. <em>Abusing this may cause your account to be suspended.</em> We do validate this and it must be a valid date. Use - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" to be safe. Generally, though, anything strtotime() understands we'll understand - <a href="http://us2.php.net/strtotime" target="_blank">http://us2.php.net/strtotime</a>
722
- * - mc_location associative_array Set the member's geographic location either by optin_ip or geo data.
723
- * - latitude string use the specified latitude (longitude must exist for this to work)
724
- * - longitude string use the specified longitude (latitude must exist for this to work)
725
- * - anything string if this (or any other key exists here) we'll try to use the optin ip. NOTE - this will slow down each subscribe call a bit, especially for lat/lng pairs in sparsely populated areas. Currently our automated background processes can and will overwrite this based on opens and clicks.
726
- * - mc_language string Set the member's language preference. Supported codes are fully case-sensitive and can be found <a href="http://kb.mailchimp.com/article/can-i-see-what-languages-my-subscribers-use#code" target="_new">here</a>.
727
- * - mc_notes array of structs for managing notes - it may contain:
728
- * - note string the note to set. this is required unless you're deleting a note
729
- * - id int the note id to operate on. not including this (or using an invalid id) causes a new note to be added
730
- * - action string if the "id" key exists and is valid, an "update" key may be set to "append" (default), "prepend", "replace", or "delete" to handle how we should update existing notes. "delete", obviously, will only work with a valid "id" - passing that along with "note" and an invalid "id" is wrong and will be ignored.
731
- * @param string $email_type
732
- * @param bool $double_optin
733
- * @param bool $update_existing
734
- * @param bool $replace_interests
735
- * @param bool $send_welcome
736
- * @return associative_array the ids for this subscriber
737
- * - email string the email address added
738
- * - euid string the email unique id
739
- * - leid string the list member's truly unique id
740
- */
741
- public function subscribe($id, $email, $merge_vars=null, $email_type='html', $double_optin=true, $update_existing=false, $replace_interests=true, $send_welcome=false) {
742
- $_params = array("id" => $id, "email" => $email, "merge_vars" => $merge_vars, "email_type" => $email_type, "double_optin" => $double_optin, "update_existing" => $update_existing, "replace_interests" => $replace_interests, "send_welcome" => $send_welcome);
743
- return $this->master->call('lists/subscribe', $_params);
744
- }
745
-
746
- /**
747
- * Unsubscribe the given email address from the list
748
- * @param string $id
749
- * @param associative_array $email
750
- * - email string an email address
751
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
752
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
753
- * @param boolean $delete_member
754
- * @param boolean $send_goodbye
755
- * @param boolean $send_notify
756
- * @return associative_array with a single entry:
757
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
758
- */
759
- public function unsubscribe($id, $email, $delete_member=false, $send_goodbye=true, $send_notify=true) {
760
- $_params = array("id" => $id, "email" => $email, "delete_member" => $delete_member, "send_goodbye" => $send_goodbye, "send_notify" => $send_notify);
761
- return $this->master->call('lists/unsubscribe', $_params);
762
- }
763
-
764
- /**
765
- * Edit the email address, merge fields, and interest groups for a list member. If you are doing a batch update on lots of users,
766
- consider using lists/batch-subscribe() with the update_existing and possible replace_interests parameter.
767
- * @param string $id
768
- * @param associative_array $email
769
- * - email string an email address
770
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
771
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
772
- * @param array $merge_vars
773
- * @param string $email_type
774
- * @param boolean $replace_interests
775
- * @return associative_array the ids for this subscriber
776
- * - email string the email address added
777
- * - euid string the email unique id
778
- * - leid string the list member's truly unique id
779
- */
780
- public function updateMember($id, $email, $merge_vars, $email_type='', $replace_interests=true) {
781
- $_params = array("id" => $id, "email" => $email, "merge_vars" => $merge_vars, "email_type" => $email_type, "replace_interests" => $replace_interests);
782
- return $this->master->call('lists/update-member', $_params);
783
- }
784
-
785
- /**
786
- * Add a new Webhook URL for the given list
787
- * @param string $id
788
- * @param string $url
789
- * @param associative_array $actions
790
- * - subscribe bool optional as subscribes occur, defaults to true
791
- * - unsubscribe bool optional as subscribes occur, defaults to true
792
- * - profile bool optional as profile updates occur, defaults to true
793
- * - cleaned bool optional as emails are cleaned from the list, defaults to true
794
- * - upemail bool optional when subscribers change their email address, defaults to true
795
- * - campaign bool option when a campaign is sent or canceled, defaults to true
796
- * @param associative_array $sources
797
- * - user bool optional user/subscriber initiated actions, defaults to true
798
- * - admin bool optional admin actions in our web app, defaults to true
799
- * - api bool optional actions that happen via API calls, defaults to false
800
- * @return associative_array with a single entry:
801
- * - id int the id of the new webhook, otherwise an error will be thrown.
802
- */
803
- public function webhookAdd($id, $url, $actions=array(), $sources=array()) {
804
- $_params = array("id" => $id, "url" => $url, "actions" => $actions, "sources" => $sources);
805
- return $this->master->call('lists/webhook-add', $_params);
806
- }
807
-
808
- /**
809
- * Delete an existing Webhook URL from a given list
810
- * @param string $id
811
- * @param string $url
812
- * @return associative_array with a single entry:
813
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
814
- */
815
- public function webhookDel($id, $url) {
816
- $_params = array("id" => $id, "url" => $url);
817
- return $this->master->call('lists/webhook-del', $_params);
818
- }
819
-
820
- /**
821
- * Return the Webhooks configured for the given list
822
- * @param string $id
823
- * @return array of structs for each webhook
824
- * - url string the URL for this Webhook
825
- * - actions associative_array the possible actions and whether they are enabled
826
- * - subscribe bool triggered when subscribes happen
827
- * - unsubscribe bool triggered when unsubscribes happen
828
- * - profile bool triggered when profile updates happen
829
- * - cleaned bool triggered when a subscriber is cleaned (bounced) from a list
830
- * - upemail bool triggered when a subscriber's email address is changed
831
- * - campaign bool triggered when a campaign is sent or canceled
832
- * - sources associative_array the possible sources and whether they are enabled
833
- * - user bool whether user/subscriber triggered actions are returned
834
- * - admin bool whether admin (manual, in-app) triggered actions are returned
835
- * - api bool whether api triggered actions are returned
836
- */
837
- public function webhooks($id) {
838
- $_params = array("id" => $id);
839
- return $this->master->call('lists/webhooks', $_params);
840
- }
841
-
842
- /**
843
- * Retrieve all of the lists defined for your user account
844
- * @param associative_array $filters
845
- * - list_id string optional - return a single list using a known list_id. Accepts multiples separated by commas when not using exact matching
846
- * - list_name string optional - only lists that match this name
847
- * - from_name string optional - only lists that have a default from name matching this
848
- * - from_email string optional - only lists that have a default from email matching this
849
- * - from_subject string optional - only lists that have a default from email matching this
850
- * - created_before string optional - only show lists that were created before this date+time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
851
- * - created_after string optional - only show lists that were created since this date+time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
852
- * - exact boolean optional - flag for whether to filter on exact values when filtering, or search within content for filter values - defaults to true
853
- * @param int $start
854
- * @param int $limit
855
- * @param string $sort_field
856
- * @param string $sort_dir
857
- * @return associative_array result of the operation including valid data and any errors
858
- * - total int the total number of lists which matched the provided filters
859
- * - data array structs for the lists which matched the provided filters, including the following
860
- * - id string The list id for this list. This will be used for all other list management functions.
861
- * - web_id int The list id used in our web app, allows you to create a link directly to it
862
- * - name string The name of the list.
863
- * - date_created string The date that this list was created.
864
- * - email_type_option boolean Whether or not the List supports multiple formats for emails or just HTML
865
- * - use_awesomebar boolean Whether or not campaigns for this list use the Awesome Bar in archives by default
866
- * - default_from_name string Default From Name for campaigns using this list
867
- * - default_from_email string Default From Email for campaigns using this list
868
- * - default_subject string Default Subject Line for campaigns using this list
869
- * - default_language string Default Language for this list's forms
870
- * - list_rating double An auto-generated activity score for the list (0 - 5)
871
- * - subscribe_url_short string Our eepurl shortened version of this list's subscribe form (will not change)
872
- * - subscribe_url_long string The full version of this list's subscribe form (host will vary)
873
- * - beamer_address string The email address to use for this list's <a href="http://kb.mailchimp.com/article/how-do-i-import-a-campaign-via-email-email-beamer/">Email Beamer</a>
874
- * - visibility string Whether this list is Public (pub) or Private (prv). Used internally for projects like <a href="http://blog.mailchimp.com/introducing-wavelength/" target="_blank">Wavelength</a>
875
- * - stats associative_array various stats and counts for the list - many of these are cached for at least 5 minutes
876
- * - member_count double The number of active members in the given list.
877
- * - unsubscribe_count double The number of members who have unsubscribed from the given list.
878
- * - cleaned_count double The number of members cleaned from the given list.
879
- * - member_count_since_send double The number of active members in the given list since the last campaign was sent
880
- * - unsubscribe_count_since_send double The number of members who have unsubscribed from the given list since the last campaign was sent
881
- * - cleaned_count_since_send double The number of members cleaned from the given list since the last campaign was sent
882
- * - campaign_count double The number of campaigns in any status that use this list
883
- * - grouping_count double The number of Interest Groupings for this list
884
- * - group_count double The number of Interest Groups (regardless of grouping) for this list
885
- * - merge_var_count double The number of merge vars for this list (not including the required EMAIL one)
886
- * - avg_sub_rate double the average number of subscribe per month for the list (empty value if we haven't calculated this yet)
887
- * - avg_unsub_rate double the average number of unsubscribe per month for the list (empty value if we haven't calculated this yet)
888
- * - target_sub_rate double the target subscription rate for the list to keep it growing (empty value if we haven't calculated this yet)
889
- * - open_rate double the average open rate per campaign for the list (empty value if we haven't calculated this yet)
890
- * - click_rate double the average click rate per campaign for the list (empty value if we haven't calculated this yet)
891
- * - modules array Any list specific modules installed for this list (example is SocialPro)
892
- * - errors array structs of any errors found while loading lists - usually just from providing invalid list ids
893
- * - param string the data that caused the failure
894
- * - code int the error code
895
- * - error string the error message
896
- */
897
- public function getList($filters=array(), $start=0, $limit=25, $sort_field='created', $sort_dir='DESC') {
898
- $_params = array("filters" => $filters, "start" => $start, "limit" => $limit, "sort_field" => $sort_field, "sort_dir" => $sort_dir);
899
- return $this->master->call('lists/list', $_params);
900
- }
901
-
902
- }
903
-
904
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Mobile.php DELETED
@@ -1,10 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Mobile {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- }
9
-
10
-
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Neapolitan.php DELETED
@@ -1,10 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Neapolitan {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- }
9
-
10
-
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Reports.php DELETED
@@ -1,459 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Reports {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Get all email addresses that complained about a given campaign
10
- * @param string $cid
11
- * @param associative_array $opts
12
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
13
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
14
- * - since string optional pull only messages since this time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
15
- * @return associative_array abuse report data for this campaign
16
- * - total int the total reports matched
17
- * - data array a struct for the each report, including:
18
- * - date string date/time the abuse report was received and processed
19
- * - member string the email address that reported abuse - will only contain email if the list or member has been removed
20
- * - type string an internal type generally specifying the originating mail provider - may not be useful outside of filling report views
21
- */
22
- public function abuse($cid, $opts=array()) {
23
- $_params = array("cid" => $cid, "opts" => $opts);
24
- return $this->master->call('reports/abuse', $_params);
25
- }
26
-
27
- /**
28
- * Retrieve the text presented in our app for how a campaign performed and any advice we may have for you - best
29
- suited for display in customized reports pages. Note: some messages will contain HTML - clean tags as necessary
30
- * @param string $cid
31
- * @return array of structs for advice on the campaign's performance, each containing:
32
- * - msg string the advice message
33
- * - type string the "type" of the message. one of: negative, positive, or neutral
34
- */
35
- public function advice($cid) {
36
- $_params = array("cid" => $cid);
37
- return $this->master->call('reports/advice', $_params);
38
- }
39
-
40
- /**
41
- * Retrieve the most recent full bounce message for a specific email address on the given campaign.
42
- Messages over 30 days old are subject to being removed
43
- * @param string $cid
44
- * @param associative_array $email
45
- * - email string an email address - this is recommended for this method
46
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
47
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
48
- * @return associative_array the full bounce message for this email+campaign along with some extra data.
49
- * - date string date the bounce was received and processed
50
- * - member associative_array the member record as returned by lists/member-info()
51
- * - message string the entire bounce message received
52
- */
53
- public function bounceMessage($cid, $email) {
54
- $_params = array("cid" => $cid, "email" => $email);
55
- return $this->master->call('reports/bounce-message', $_params);
56
- }
57
-
58
- /**
59
- * Retrieve the full bounce messages for the given campaign. Note that this can return very large amounts
60
- of data depending on how large the campaign was and how much cruft the bounce provider returned. Also,
61
- messages over 30 days old are subject to being removed
62
- * @param string $cid
63
- * @param associative_array $opts
64
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
65
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
66
- * - since string optional pull only messages since this time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
67
- * @return associative_array data for the full bounce messages for this campaign
68
- * - total int that total number of bounce messages for the campaign
69
- * - data array structs containing the data for this page
70
- * - date string date the bounce was received and processed
71
- * - member associative_array the member record as returned by lists/member-info()
72
- * - message string the entire bounce message received
73
- */
74
- public function bounceMessages($cid, $opts=array()) {
75
- $_params = array("cid" => $cid, "opts" => $opts);
76
- return $this->master->call('reports/bounce-messages', $_params);
77
- }
78
-
79
- /**
80
- * Return the list of email addresses that clicked on a given url, and how many times they clicked
81
- * @param string $cid
82
- * @param int $tid
83
- * @param associative_array $opts
84
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
85
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
86
- * - sort_field string optional the data to sort by - "clicked" (order clicks occurred, default) or "clicks" (total number of opens). Invalid fields will fall back on the default.
87
- * - sort_dir string optional the direct - ASC or DESC. defaults to ASC (case insensitive)
88
- * @return associative_array containing the total records matched and the specific records for this page
89
- * - total int the total number of records matched
90
- * - data array structs for each email addresses that click the requested url
91
- * - member associative_array the member record as returned by lists/member-info()
92
- * - clicks int Total number of times the URL was clicked by this email address
93
- */
94
- public function clickDetail($cid, $tid, $opts=array()) {
95
- $_params = array("cid" => $cid, "tid" => $tid, "opts" => $opts);
96
- return $this->master->call('reports/click-detail', $_params);
97
- }
98
-
99
- /**
100
- * The urls tracked and their click counts for a given campaign.
101
- * @param string $cid
102
- * @return associative_array including:
103
- * - total array structs for each url tracked for the full campaign
104
- * - url string the url being tracked - urls are tracked individually, so duplicates can exist with vastly different stats
105
- * - clicks int Number of times the specific link was clicked
106
- * - clicks_percent double the percentage of total clicks "clicks" represents
107
- * - unique int Number of unique people who clicked on the specific link
108
- * - unique_percent double the percentage of unique clicks "unique" represents
109
- * - tid int the tracking id used in campaign links - used primarily for reports/click-activity. also can be used to order urls by the order they appeared in the campaign to recreate our heat map.
110
- * - a array if this was an absplit campaign, stat structs for the a group
111
- * - url string the url being tracked - urls are tracked individually, so duplicates can exist with vastly different stats
112
- * - clicks int Number of times the specific link was clicked
113
- * - clicks_percent double the percentage of total clicks "clicks" represents
114
- * - unique int Number of unique people who clicked on the specific link
115
- * - unique_percent double the percentage of unique clicks "unique" represents
116
- * - tid int the tracking id used in campaign links - used primarily for reports/click-activity. also can be used to order urls by the order they appeared in the campaign to recreate our heat map.
117
- * - b array if this was an absplit campaign, stat structs for the b group
118
- * - url string the url being tracked - urls are tracked individually, so duplicates can exist with vastly different stats
119
- * - clicks int Number of times the specific link was clicked
120
- * - clicks_percent double the percentage of total clicks "clicks" represents
121
- * - unique int Number of unique people who clicked on the specific link
122
- * - unique_percent double the percentage of unique clicks "unique" represents
123
- * - tid int the tracking id used in campaign links - used primarily for reports/click-activity. also can be used to order urls by the order they appeared in the campaign to recreate our heat map.
124
- */
125
- public function clicks($cid) {
126
- $_params = array("cid" => $cid);
127
- return $this->master->call('reports/clicks', $_params);
128
- }
129
-
130
- /**
131
- * Retrieve the Ecommerce Orders tracked by ecomm/order-add()
132
- * @param string $cid
133
- * @param associative_array $opts
134
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
135
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
136
- * - since string optional pull only messages since this time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
137
- * @return associative_array the total matching orders and the specific orders for the requested page
138
- * - total int the total matching orders
139
- * - data array structs for the actual data for each order being returned
140
- * - store_id string the store id generated by the plugin used to uniquely identify a store
141
- * - store_name string the store name collected by the plugin - often the domain name
142
- * - order_id string the internal order id the store tracked this order by
143
- * - member associative_array the member record as returned by lists/member-info() that received this campaign and is associated with this order
144
- * - order_total double the order total
145
- * - tax_total double the total tax for the order (if collected)
146
- * - ship_total double the shipping total for the order (if collected)
147
- * - order_date string the date the order was tracked - from the store if possible, otherwise the GMT time we received it
148
- * - lines array structs containing details of the order:
149
- * - line_num int the line number assigned to this line
150
- * - product_id int the product id assigned to this item
151
- * - product_name string the product name
152
- * - product_sku string the sku for the product
153
- * - product_category_id int the id for the product category
154
- * - product_category_name string the product category name
155
- * - qty double optional the quantity of the item ordered - defaults to 1
156
- * - cost double optional the cost of a single item (ie, not the extended cost of the line) - defaults to 0
157
- */
158
- public function ecommOrders($cid, $opts=array()) {
159
- $_params = array("cid" => $cid, "opts" => $opts);
160
- return $this->master->call('reports/ecomm-orders', $_params);
161
- }
162
-
163
- /**
164
- * Retrieve the eepurl stats from the web/Twitter mentions for this campaign
165
- * @param string $cid
166
- * @return associative_array containing tweets, retweets, clicks, and referrer related to using the campaign's eepurl
167
- * - twitter associative_array various Twitter related stats
168
- * - tweets int Total number of tweets seen
169
- * - first_tweet string date and time of the first tweet seen
170
- * - last_tweet string date and time of the last tweet seen
171
- * - retweets int Total number of retweets seen
172
- * - first_retweet string date and time of the first retweet seen
173
- * - last_retweet string date and time of the last retweet seen
174
- * - statuses array an structs for statuses recorded including:
175
- * - status string the text of the tweet/update
176
- * - screen_name string the screen name as recorded when first seen
177
- * - status_id string the status id of the tweet (they are really unsigned 64 bit ints)
178
- * - datetime string the date/time of the tweet
179
- * - is_retweet bool whether or not this was a retweet
180
- * - clicks associative_array stats related to click-throughs on the eepurl
181
- * - clicks int Total number of clicks seen
182
- * - first_click string date and time of the first click seen
183
- * - last_click string date and time of the first click seen
184
- * - locations array structs for geographic locations including:
185
- * - country string the country name the click was tracked to
186
- * - region string the region in the country the click was tracked to (if available)
187
- * - referrers array structs for referrers, including
188
- * - referrer string the referrer, truncated to 100 bytes
189
- * - clicks int Total number of clicks seen from this referrer
190
- * - first_click string date and time of the first click seen from this referrer
191
- * - last_click string date and time of the first click seen from this referrer
192
- */
193
- public function eepurl($cid) {
194
- $_params = array("cid" => $cid);
195
- return $this->master->call('reports/eepurl', $_params);
196
- }
197
-
198
- /**
199
- * Given a campaign and email address, return the entire click and open history with timestamps, ordered by time. If you need to dump the full activity for a campaign
200
- and/or get incremental results, you should use the <a href="http://apidocs.mailchimp.com/export/1.0/campaignsubscriberactivity.func.php" targret="_new">campaignSubscriberActivity Export API method</a>,
201
- <strong>not</strong> this, especially for large campaigns.
202
- * @param string $cid
203
- * @param array $emails
204
- * - email string an email address
205
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
206
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
207
- * @return associative_array of data and success/error counts
208
- * - success_count int the number of subscribers successfully found on the list
209
- * - error_count int the number of subscribers who were not found on the list
210
- * - errors array array of error structs including:
211
- * - email string whatever was passed in the email parameter
212
- * - email string the email address added
213
- * - euid string the email unique id
214
- * - leid string the list member's truly unique id
215
- * - msg string the error message
216
- * - data array an array of structs where each activity record has:
217
- * - email string whatever was passed in the email parameter
218
- * - email string the email address added
219
- * - euid string the email unique id
220
- * - leid string the list member's truly unique id
221
- * - member associative_array the member record as returned by lists/member-info()
222
- * - activity array an array of structs containing the activity, including:
223
- * - action string The action name - either open or click
224
- * - timestamp string The date/time of the action (GMT)
225
- * - url string For click actions, the url clicked, otherwise this is empty
226
- * - ip string The IP address the activity came from
227
- */
228
- public function memberActivity($cid, $emails) {
229
- $_params = array("cid" => $cid, "emails" => $emails);
230
- return $this->master->call('reports/member-activity', $_params);
231
- }
232
-
233
- /**
234
- * Retrieve the list of email addresses that did not open a given campaign
235
- * @param string $cid
236
- * @param associative_array $opts
237
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
238
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
239
- * @return associative_array a total of all matching emails and the specific emails for this page
240
- * - total int the total number of members who didn't open the campaign
241
- * - data array structs for each campaign member matching as returned by lists/member-info()
242
- */
243
- public function notOpened($cid, $opts=array()) {
244
- $_params = array("cid" => $cid, "opts" => $opts);
245
- return $this->master->call('reports/not-opened', $_params);
246
- }
247
-
248
- /**
249
- * Retrieve the list of email addresses that opened a given campaign with how many times they opened
250
- * @param string $cid
251
- * @param associative_array $opts
252
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
253
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
254
- * - sort_field string optional the data to sort by - "opened" (order opens occurred, default) or "opens" (total number of opens). Invalid fields will fall back on the default.
255
- * - sort_dir string optional the direct - ASC or DESC. defaults to ASC (case insensitive)
256
- * @return associative_array containing the total records matched and the specific records for this page
257
- * - total int the total number of records matched
258
- * - data array structs for the actual opens data, including:
259
- * - member associative_array the member record as returned by lists/member-info()
260
- * - opens int Total number of times the campaign was opened by this email address
261
- */
262
- public function opened($cid, $opts=array()) {
263
- $_params = array("cid" => $cid, "opts" => $opts);
264
- return $this->master->call('reports/opened', $_params);
265
- }
266
-
267
- /**
268
- * Get the top 5 performing email domains for this campaign. Users wanting more than 5 should use campaign reports/member-activity()
269
- or campaignEmailStatsAIMAll() and generate any additional stats they require.
270
- * @param string $cid
271
- * @return array domains structs for each email domains and their associated stats
272
- * - domain string Domain name or special "Other" to roll-up stats past 5 domains
273
- * - total_sent int Total Email across all domains - this will be the same in every row
274
- * - emails int Number of emails sent to this domain
275
- * - bounces int Number of bounces
276
- * - opens int Number of opens
277
- * - clicks int Number of clicks
278
- * - unsubs int Number of unsubs
279
- * - delivered int Number of deliveries
280
- * - emails_pct int Percentage of emails that went to this domain (whole number)
281
- * - bounces_pct int Percentage of bounces from this domain (whole number)
282
- * - opens_pct int Percentage of opens from this domain (whole number)
283
- * - clicks_pct int Percentage of clicks from this domain (whole number)
284
- * - unsubs_pct int Percentage of unsubs from this domain (whole number)
285
- */
286
- public function domainPerformance($cid) {
287
- $_params = array("cid" => $cid);
288
- return $this->master->call('reports/domain-performance', $_params);
289
- }
290
-
291
- /**
292
- * Retrieve the countries/regions and number of opens tracked for each. Email address are not returned.
293
- * @param string $cid
294
- * @return array an array of country structs where opens occurred
295
- * - code string The ISO3166 2 digit country code
296
- * - name string A version of the country name, if we have it
297
- * - opens int The total number of opens that occurred in the country
298
- * - regions array structs of data for each sub-region in the country
299
- * - code string An internal code for the region. When this is blank, it indicates we know the country, but not the region
300
- * - name string The name of the region, if we have one. For blank "code" values, this will be "Rest of Country"
301
- * - opens int The total number of opens that occurred in the country
302
- */
303
- public function geoOpens($cid) {
304
- $_params = array("cid" => $cid);
305
- return $this->master->call('reports/geo-opens', $_params);
306
- }
307
-
308
- /**
309
- * Retrieve the Google Analytics data we've collected for this campaign. Note, requires Google Analytics Add-on to be installed and configured.
310
- * @param string $cid
311
- * @return array of structs for analytics we've collected for the passed campaign.
312
- * - visits int number of visits
313
- * - pages int number of page views
314
- * - new_visits int new visits recorded
315
- * - bounces int vistors who "bounced" from your site
316
- * - time_on_site double the total time visitors spent on your sites
317
- * - goal_conversions int number of goals converted
318
- * - goal_value double value of conversion in dollars
319
- * - revenue double revenue generated by campaign
320
- * - transactions int number of transactions tracked
321
- * - ecomm_conversions int number Ecommerce transactions tracked
322
- * - goals array structs containing goal names and number of conversions
323
- * - name string the name of the goal
324
- * - conversions int the number of conversions for the goal
325
- */
326
- public function googleAnalytics($cid) {
327
- $_params = array("cid" => $cid);
328
- return $this->master->call('reports/google-analytics', $_params);
329
- }
330
-
331
- /**
332
- * Get email addresses the campaign was sent to
333
- * @param string $cid
334
- * @param associative_array $opts
335
- * - status string optional the status to pull - one of 'sent', 'hard' (bounce), or 'soft' (bounce). By default, all records are returned
336
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
337
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
338
- * @return associative_array a total of all matching emails and the specific emails for this page
339
- * - total int the total number of members for the campaign and status
340
- * - data array structs for each campaign member matching
341
- * - member associative_array the member record as returned by lists/member-info()
342
- * - status string the status of the send - one of 'sent', 'hard', 'soft'
343
- * - absplit_group string if this was an absplit campaign, one of 'a','b', or 'winner'
344
- * - tz_group string if this was an timewarp campaign the timezone GMT offset the member was included in
345
- */
346
- public function sentTo($cid, $opts=array()) {
347
- $_params = array("cid" => $cid, "opts" => $opts);
348
- return $this->master->call('reports/sent-to', $_params);
349
- }
350
-
351
- /**
352
- * Get the URL to a customized <a href="http://eepurl.com/gKmL" target="_blank">VIP Report</a> for the specified campaign and optionally send an email to someone with links to it. Note subsequent calls will overwrite anything already set for the same campign (eg, the password)
353
- * @param string $cid
354
- * @param array $opts
355
- * - to_email string optional - optional, comma delimited list of email addresses to share the report with - no value means an email will not be sent
356
- * - theme_id int optional - either a global or a user-specific theme id. Currently this needs to be pulled out of either the Share Report or Cobranding web views by grabbing the "theme" attribute from the list presented.
357
- * - css_url string optional - a link to an external CSS file to be included after our default CSS (http://vip-reports.net/css/vip.css) <strong>only if</strong> loaded via the "secure_url" - max 255 bytes
358
- * @return associative_array details for the shared report, including:
359
- * - title string The Title of the Campaign being shared
360
- * - url string The URL to the shared report
361
- * - secure_url string The URL to the shared report, including the password (good for loading in an IFRAME). For non-secure reports, this will not be returned
362
- * - password string If secured, the password for the report, otherwise this field will not be returned
363
- */
364
- public function share($cid, $opts=array()) {
365
- $_params = array("cid" => $cid, "opts" => $opts);
366
- return $this->master->call('reports/share', $_params);
367
- }
368
-
369
- /**
370
- * Retrieve relevant aggregate campaign statistics (opens, bounces, clicks, etc.)
371
- * @param string $cid
372
- * @return associative_array the statistics for this campaign
373
- * - syntax_errors int Number of email addresses in campaign that had syntactical errors.
374
- * - hard_bounces int Number of email addresses in campaign that hard bounced.
375
- * - soft_bounces int Number of email addresses in campaign that soft bounced.
376
- * - unsubscribes int Number of email addresses in campaign that unsubscribed.
377
- * - abuse_reports int Number of email addresses in campaign that reported campaign for abuse.
378
- * - forwards int Number of times email was forwarded to a friend.
379
- * - forwards_opens int Number of times a forwarded email was opened.
380
- * - opens int Number of times the campaign was opened.
381
- * - last_open string Date of the last time the email was opened.
382
- * - unique_opens int Number of people who opened the campaign.
383
- * - clicks int Number of times a link in the campaign was clicked.
384
- * - unique_clicks int Number of unique recipient/click pairs for the campaign.
385
- * - last_click string Date of the last time a link in the email was clicked.
386
- * - users_who_clicked int Number of unique recipients who clicked on a link in the campaign.
387
- * - emails_sent int Number of email addresses campaign was sent to.
388
- * - unique_likes int total number of unique likes (Facebook)
389
- * - recipient_likes int total number of recipients who liked (Facebook) the campaign
390
- * - facebook_likes int total number of likes (Facebook) that came from Facebook
391
- * - industry associative_array Various rates/percentages for the account's selected industry - empty otherwise. These will vary across calls, do not use them for anything important.
392
- * - type string the selected industry
393
- * - open_rate float industry open rate
394
- * - click_rate float industry click rate
395
- * - bounce_rate float industry bounce rate
396
- * - unopen_rate float industry unopen rate
397
- * - unsub_rate float industry unsub rate
398
- * - abuse_rate float industry abuse rate
399
- * - absplit associative_array If this was an absplit campaign, stats for the A and B groups will be returned - otherwise this is empty
400
- * - bounces_a int bounces for the A group
401
- * - bounces_b int bounces for the B group
402
- * - forwards_a int forwards for the A group
403
- * - forwards_b int forwards for the B group
404
- * - abuse_reports_a int abuse reports for the A group
405
- * - abuse_reports_b int abuse reports for the B group
406
- * - unsubs_a int unsubs for the A group
407
- * - unsubs_b int unsubs for the B group
408
- * - recipients_click_a int clicks for the A group
409
- * - recipients_click_b int clicks for the B group
410
- * - forwards_opens_a int opened forwards for the A group
411
- * - forwards_opens_b int opened forwards for the B group
412
- * - opens_a int total opens for the A group
413
- * - opens_b int total opens for the B group
414
- * - last_open_a string date/time of last open for the A group
415
- * - last_open_b string date/time of last open for the BG group
416
- * - unique_opens_a int unique opens for the A group
417
- * - unique_opens_b int unique opens for the B group
418
- * - timewarp array If this campaign was a Timewarp campaign, an array of structs from each timezone stats exist for. Each will contain:
419
- * - opens int opens for this timezone
420
- * - last_open string the date/time of the last open for this timezone
421
- * - unique_opens int the unique opens for this timezone
422
- * - clicks int the total clicks for this timezone
423
- * - last_click string the date/time of the last click for this timezone
424
- * - unique_opens int the unique clicks for this timezone
425
- * - bounces int the total bounces for this timezone
426
- * - total int the total number of members sent to in this timezone
427
- * - sent int the total number of members delivered to in this timezone
428
- * - timeseries array structs for the first 24 hours of the campaign, per-hour stats:
429
- * - timestamp string The timestemp in Y-m-d H:00:00 format
430
- * - emails_sent int the total emails sent during the hour
431
- * - unique_opens int unique opens seen during the hour
432
- * - recipients_click int unique clicks seen during the hour
433
- */
434
- public function summary($cid) {
435
- $_params = array("cid" => $cid);
436
- return $this->master->call('reports/summary', $_params);
437
- }
438
-
439
- /**
440
- * Get all unsubscribed email addresses for a given campaign
441
- * @param string $cid
442
- * @param associative_array $opts
443
- * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
444
- * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
445
- * @return associative_array a total of all unsubscribed emails and the specific members for this page
446
- * - total int the total number of unsubscribes for the campaign
447
- * - data array structs for the email addresses that unsubscribed
448
- * - member string the member that unsubscribed as returned by lists/member-info()
449
- * - reason string the reason collected for the unsubscribe. If populated, one of 'NORMAL','NOSIGNUP','INAPPROPRIATE','SPAM','OTHER'
450
- * - reason_text string if the reason is OTHER, the text entered.
451
- */
452
- public function unsubscribes($cid, $opts=array()) {
453
- $_params = array("cid" => $cid, "opts" => $opts);
454
- return $this->master->call('reports/unsubscribes', $_params);
455
- }
456
-
457
- }
458
-
459
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Templates.php DELETED
@@ -1,114 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Templates {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Create a new user template, <strong>NOT</strong> campaign content. These templates can then be applied while creating campaigns.
10
- * @param string $name
11
- * @param string $html
12
- * @param int $folder_id
13
- * @return associative_array with a single element:
14
- * - template_id int the new template id, otherwise an error is thrown.
15
- */
16
- public function add($name, $html, $folder_id=null) {
17
- $_params = array("name" => $name, "html" => $html, "folder_id" => $folder_id);
18
- return $this->master->call('templates/add', $_params);
19
- }
20
-
21
- /**
22
- * Delete (deactivate) a user template
23
- * @param int $template_id
24
- * @return associative_array with a single entry:
25
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
26
- */
27
- public function del($template_id) {
28
- $_params = array("template_id" => $template_id);
29
- return $this->master->call('templates/del', $_params);
30
- }
31
-
32
- /**
33
- * Pull details for a specific template to help support editing
34
- * @param int $template_id
35
- * @param string $type
36
- * @return associative_array info to be used when editing
37
- * - default_content associative_array the default content broken down into the named editable sections for the template - dependant upon template, so not documented
38
- * - sections associative_array the valid editable section names - dependant upon template, so not documented
39
- * - source string the full source of the template as if you exported it via our template editor
40
- * - preview string similar to the source, but the rendered version of the source from our popup preview
41
- */
42
- public function info($template_id, $type='user') {
43
- $_params = array("template_id" => $template_id, "type" => $type);
44
- return $this->master->call('templates/info', $_params);
45
- }
46
-
47
- /**
48
- * Retrieve various templates available in the system, allowing some thing similar to our template gallery to be created.
49
- * @param associative_array $types
50
- * - user boolean Custom templates for this user account. Defaults to true.
51
- * - gallery boolean Templates from our Gallery. Note that some templates that require extra configuration are withheld. (eg, the Etsy template). Defaults to false.
52
- * - base boolean Our "start from scratch" extremely basic templates. Defaults to false. As of the 9.0 update, "base" templates are no longer available via the API because they are now all saved Drag & Drop templates.
53
- * @param associative_array $filters
54
- * - category string optional for Gallery templates only, limit to a specific template category
55
- * - folder_id string user templates, limit to this folder_id
56
- * - include_inactive boolean user templates are not deleted, only set inactive. defaults to false.
57
- * - inactive_only boolean only include inactive user templates. defaults to false.
58
- * - include_drag_and_drop boolean Include templates created and saved using the new Drag & Drop editor. <strong>Note:</strong> You will not be able to edit or create new drag & drop templates via this API. This is useful only for creating a new campaign based on a drag & drop template.
59
- * @return associative_array for each type
60
- * - user array matching user templates, if requested.
61
- * - id int Id of the template
62
- * - name string Name of the template
63
- * - layout string General description of the layout of the template
64
- * - category string The category for the template, if there is one.
65
- * - preview_image string If we've generated it, the url of the preview image for the template. We do out best to keep these up to date, but Preview image urls are not guaranteed to be available
66
- * - date_created string The date/time the template was created
67
- * - active boolean whether or not the template is active and available for use.
68
- * - edit_source boolean Whether or not you are able to edit the source of a template.
69
- * - folder_id boolean if it's in one, the folder id
70
- * - gallery array matching gallery templates, if requested.
71
- * - id int Id of the template
72
- * - name string Name of the template
73
- * - layout string General description of the layout of the template
74
- * - category string The category for the template, if there is one.
75
- * - preview_image string If we've generated it, the url of the preview image for the template. We do out best to keep these up to date, but Preview image urls are not guaranteed to be available
76
- * - date_created string The date/time the template was created
77
- * - active boolean whether or not the template is active and available for use.
78
- * - edit_source boolean Whether or not you are able to edit the source of a template.
79
- * - base array matching base templates, if requested. (Will always be empty as of 9.0)
80
- */
81
- public function getList($types=array(), $filters=array()) {
82
- $_params = array("types" => $types, "filters" => $filters);
83
- return $this->master->call('templates/list', $_params);
84
- }
85
-
86
- /**
87
- * Undelete (reactivate) a user template
88
- * @param int $template_id
89
- * @return associative_array with a single entry:
90
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
91
- */
92
- public function undel($template_id) {
93
- $_params = array("template_id" => $template_id);
94
- return $this->master->call('templates/undel', $_params);
95
- }
96
-
97
- /**
98
- * Replace the content of a user template, <strong>NOT</strong> campaign content.
99
- * @param int $template_id
100
- * @param associative_array $values
101
- * - name string the name for the template - names must be unique and a max of 50 bytes
102
- * - html string a string specifying the entire template to be created. This is <strong>NOT</strong> campaign content. They are intended to utilize our <a href="http://www.mailchimp.com/resources/email-template-language/" target="_blank">template language</a>.
103
- * - folder_id int the folder to put this template in - 0 or a blank values will remove it from a folder.
104
- * @return associative_array with a single entry:
105
- * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
106
- */
107
- public function update($template_id, $values) {
108
- $_params = array("template_id" => $template_id, "values" => $values);
109
- return $this->master->call('templates/update', $_params);
110
- }
111
-
112
- }
113
-
114
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Users.php DELETED
@@ -1,105 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Users {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Invite a user to your account
10
- * @param string $email
11
- * @param string $role
12
- * @param string $msg
13
- * @return associative_array the method completion status
14
- * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
15
- */
16
- public function invite($email, $role='viewer', $msg='') {
17
- $_params = array("email" => $email, "role" => $role, "msg" => $msg);
18
- return $this->master->call('users/invite', $_params);
19
- }
20
-
21
- /**
22
- * Resend an invite a user to your account. Note, if the same address has been invited multiple times, this will simpy re-send the most recent invite
23
- * @param string $email
24
- * @return associative_array the method completion status
25
- * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
26
- */
27
- public function inviteResend($email) {
28
- $_params = array("email" => $email);
29
- return $this->master->call('users/invite-resend', $_params);
30
- }
31
-
32
- /**
33
- * Revoke an invitation sent to a user to your account. Note, if the same address has been invited multiple times, this will simpy revoke the most recent invite
34
- * @param string $email
35
- * @return associative_array the method completion status
36
- * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
37
- */
38
- public function inviteRevoke($email) {
39
- $_params = array("email" => $email);
40
- return $this->master->call('users/invite-revoke', $_params);
41
- }
42
-
43
- /**
44
- * Retrieve the list of pending users invitations have been sent for.
45
- * @return array structs for each invitation, including:
46
- * - email string the email address the invitation was sent to
47
- * - role string the role that will be assigned if they accept
48
- * - sent_at string the time the invitation was sent. this will change if it's resent.
49
- * - expiration string the expiration time for the invitation. this will change if it's resent.
50
- * - msg string the welcome message included with the invitation
51
- */
52
- public function invites() {
53
- $_params = array();
54
- return $this->master->call('users/invites', $_params);
55
- }
56
-
57
- /**
58
- * Revoke access for a specified login
59
- * @param string $username
60
- * @return associative_array the method completion status
61
- * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
62
- */
63
- public function loginRevoke($username) {
64
- $_params = array("username" => $username);
65
- return $this->master->call('users/login-revoke', $_params);
66
- }
67
-
68
- /**
69
- * Retrieve the list of active logins.
70
- * @return array structs for each user, including:
71
- * - id int the login id for this login
72
- * - username string the username used to log in
73
- * - name string a display name for the account - empty first/last names will return the username
74
- * - email string the email tied to the account used for passwords resets and the ilk
75
- * - role string the role assigned to the account
76
- * - avatar string if available, the url for the login's avatar
77
- * - global_user_id int the globally unique user id for the user account connected to
78
- * - dc_unique_id string the datacenter unique id for the user account connected to, like helper/account-details
79
- */
80
- public function logins() {
81
- $_params = array();
82
- return $this->master->call('users/logins', $_params);
83
- }
84
-
85
- /**
86
- * Retrieve the profile for the login owning the provided API Key
87
- * @return associative_array the current user's details, including:
88
- * - id int the login id for this login
89
- * - username string the username used to log in
90
- * - name string a display name for the account - empty first/last names will return the username
91
- * - email string the email tied to the account used for passwords resets and the ilk
92
- * - role string the role assigned to the account
93
- * - avatar string if available, the url for the login's avatar
94
- * - global_user_id int the globally unique user id for the user account connected to
95
- * - dc_unique_id string the datacenter unique id for the user account connected to, like helper/account-details
96
- * - account_name string The name of the account to which the API key belongs
97
- */
98
- public function profile() {
99
- $_params = array();
100
- return $this->master->call('users/profile', $_params);
101
- }
102
-
103
- }
104
-
105
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/Mailchimp/Vip.php DELETED
@@ -1,111 +0,0 @@
1
- <?php
2
-
3
- class Mailchimp_Vip {
4
- public function __construct(Mailchimp $master) {
5
- $this->master = $master;
6
- }
7
-
8
- /**
9
- * Retrieve all Activity (opens/clicks) for VIPs over the past 10 days
10
- * @return array structs for each activity recorded.
11
- * - action string The action taken - either "open" or "click"
12
- * - timestamp string The datetime the action occurred in GMT
13
- * - url string IF the action is a click, the url that was clicked
14
- * - unique_id string The campaign_id of the List the Member appears on
15
- * - title string The campaign title
16
- * - list_name string The name of the List the Member appears on
17
- * - list_id string The id of the List the Member appears on
18
- * - email string The email address of the member
19
- * - fname string IF a FNAME merge field exists on the list, that value for the member
20
- * - lname string IF a LNAME merge field exists on the list, that value for the member
21
- * - member_rating int the rating of the subscriber. This will be 1 - 5 as described <a href="http://eepurl.com/f-2P" target="_blank">here</a>
22
- * - member_since string the datetime the member was added and/or confirmed
23
- * - geo associative_array the geographic information if we have it. including:
24
- * - latitude string the latitude
25
- * - longitude string the longitude
26
- * - gmtoff string GMT offset
27
- * - dstoff string GMT offset during daylight savings (if DST not observered, will be same as gmtoff
28
- * - timezone string the timezone we've place them in
29
- * - cc string 2 digit ISO-3166 country code
30
- * - region string generally state, province, or similar
31
- */
32
- public function activity() {
33
- $_params = array();
34
- return $this->master->call('vip/activity', $_params);
35
- }
36
-
37
- /**
38
- * Add VIPs (previously called Golden Monkeys)
39
- * @param string $id
40
- * @param array $emails
41
- * - email string an email address - for new subscribers obviously this should be used
42
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
43
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
44
- * @return associative_array of data and success/error counts
45
- * - success_count int the number of successful adds
46
- * - error_count int the number of unsuccessful adds
47
- * - errors array array of error structs including:
48
- * - email associative_array whatever was passed in the email parameter
49
- * - email string the email address added
50
- * - euid string the email unique id
51
- * - leid string the list member's truly unique id
52
- * - code string the error code
53
- * - error string the error message
54
- * - data array array of structs for each member added
55
- * - email associative_array whatever was passed in the email parameter
56
- * - email string the email address added
57
- * - euid string the email unique id
58
- * - leid string the list member's truly unique id
59
- */
60
- public function add($id, $emails) {
61
- $_params = array("id" => $id, "emails" => $emails);
62
- return $this->master->call('vip/add', $_params);
63
- }
64
-
65
- /**
66
- * Remove VIPs - this does not affect list membership
67
- * @param string $id
68
- * @param array $emails
69
- * - email string an email address - for new subscribers obviously this should be used
70
- * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
71
- * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
72
- * @return associative_array of data and success/error counts
73
- * - success_count int the number of successful deletions
74
- * - error_count int the number of unsuccessful deletions
75
- * - errors array array of error structs including:
76
- * - email associative_array whatever was passed in the email parameter
77
- * - email string the email address
78
- * - euid string the email unique id
79
- * - leid string the list member's truly unique id
80
- * - code string the error code
81
- * - msg string the error message
82
- * - data array array of structs for each member deleted
83
- * - email associative_array whatever was passed in the email parameter
84
- * - email string the email address
85
- * - euid string the email unique id
86
- * - leid string the list member's truly unique id
87
- */
88
- public function del($id, $emails) {
89
- $_params = array("id" => $id, "emails" => $emails);
90
- return $this->master->call('vip/del', $_params);
91
- }
92
-
93
- /**
94
- * Retrieve all Golden Monkey(s) for an account
95
- * @return array structs for each Golden Monkey, including:
96
- * - list_id string The id of the List the Member appears on
97
- * - list_name string The name of the List the Member appears on
98
- * - email string The email address of the member
99
- * - fname string IF a FNAME merge field exists on the list, that value for the member
100
- * - lname string IF a LNAME merge field exists on the list, that value for the member
101
- * - member_rating int the rating of the subscriber. This will be 1 - 5 as described <a href="http://eepurl.com/f-2P" target="_blank">here</a>
102
- * - member_since string the datetime the member was added and/or confirmed
103
- */
104
- public function members() {
105
- $_params = array();
106
- return $this->master->call('vip/members', $_params);
107
- }
108
-
109
- }
110
-
111
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/mailchimp/mailchimp.php CHANGED
@@ -1,262 +1,569 @@
1
  <?php
2
 
3
- require_once 'Mailchimp/Folders.php';
4
- require_once 'Mailchimp/Templates.php';
5
- require_once 'Mailchimp/Users.php';
6
- require_once 'Mailchimp/Helper.php';
7
- require_once 'Mailchimp/Mobile.php';
8
- require_once 'Mailchimp/Conversations.php';
9
- require_once 'Mailchimp/Ecomm.php';
10
- require_once 'Mailchimp/Neapolitan.php';
11
- require_once 'Mailchimp/Lists.php';
12
- require_once 'Mailchimp/Campaigns.php';
13
- require_once 'Mailchimp/Vip.php';
14
- require_once 'Mailchimp/Reports.php';
15
- require_once 'Mailchimp/Gallery.php';
16
- require_once 'Mailchimp/Goal.php';
17
- require_once 'Mailchimp/Exceptions.php';
18
-
19
- class Mailchimp {
20
-
21
- public $apikey;
22
- public $ch;
23
- public $root = 'https://api.mailchimp.com/2.0';
24
- public $debug = false;
25
-
26
- public static $error_map = array(
27
- "ValidationError" => "Mailchimp_ValidationError",
28
- "ServerError_MethodUnknown" => "Mailchimp_ServerError_MethodUnknown",
29
- "ServerError_InvalidParameters" => "Mailchimp_ServerError_InvalidParameters",
30
- "Unknown_Exception" => "Mailchimp_Unknown_Exception",
31
- "Request_TimedOut" => "Mailchimp_Request_TimedOut",
32
- "Zend_Uri_Exception" => "Mailchimp_Zend_Uri_Exception",
33
- "PDOException" => "Mailchimp_PDOException",
34
- "Avesta_Db_Exception" => "Mailchimp_Avesta_Db_Exception",
35
- "XML_RPC2_Exception" => "Mailchimp_XML_RPC2_Exception",
36
- "XML_RPC2_FaultException" => "Mailchimp_XML_RPC2_FaultException",
37
- "Too_Many_Connections" => "Mailchimp_Too_Many_Connections",
38
- "Parse_Exception" => "Mailchimp_Parse_Exception",
39
- "User_Unknown" => "Mailchimp_User_Unknown",
40
- "User_Disabled" => "Mailchimp_User_Disabled",
41
- "User_DoesNotExist" => "Mailchimp_User_DoesNotExist",
42
- "User_NotApproved" => "Mailchimp_User_NotApproved",
43
- "Invalid_ApiKey" => "Mailchimp_Invalid_ApiKey",
44
- "User_UnderMaintenance" => "Mailchimp_User_UnderMaintenance",
45
- "Invalid_AppKey" => "Mailchimp_Invalid_AppKey",
46
- "Invalid_IP" => "Mailchimp_Invalid_IP",
47
- "User_DoesExist" => "Mailchimp_User_DoesExist",
48
- "User_InvalidRole" => "Mailchimp_User_InvalidRole",
49
- "User_InvalidAction" => "Mailchimp_User_InvalidAction",
50
- "User_MissingEmail" => "Mailchimp_User_MissingEmail",
51
- "User_CannotSendCampaign" => "Mailchimp_User_CannotSendCampaign",
52
- "User_MissingModuleOutbox" => "Mailchimp_User_MissingModuleOutbox",
53
- "User_ModuleAlreadyPurchased" => "Mailchimp_User_ModuleAlreadyPurchased",
54
- "User_ModuleNotPurchased" => "Mailchimp_User_ModuleNotPurchased",
55
- "User_NotEnoughCredit" => "Mailchimp_User_NotEnoughCredit",
56
- "MC_InvalidPayment" => "Mailchimp_MC_InvalidPayment",
57
- "List_DoesNotExist" => "Mailchimp_List_DoesNotExist",
58
- "List_InvalidInterestFieldType" => "Mailchimp_List_InvalidInterestFieldType",
59
- "List_InvalidOption" => "Mailchimp_List_InvalidOption",
60
- "List_InvalidUnsubMember" => "Mailchimp_List_InvalidUnsubMember",
61
- "List_InvalidBounceMember" => "Mailchimp_List_InvalidBounceMember",
62
- "List_AlreadySubscribed" => "Mailchimp_List_AlreadySubscribed",
63
- "List_NotSubscribed" => "Mailchimp_List_NotSubscribed",
64
- "List_InvalidImport" => "Mailchimp_List_InvalidImport",
65
- "MC_PastedList_Duplicate" => "Mailchimp_MC_PastedList_Duplicate",
66
- "MC_PastedList_InvalidImport" => "Mailchimp_MC_PastedList_InvalidImport",
67
- "Email_AlreadySubscribed" => "Mailchimp_Email_AlreadySubscribed",
68
- "Email_AlreadyUnsubscribed" => "Mailchimp_Email_AlreadyUnsubscribed",
69
- "Email_NotExists" => "Mailchimp_Email_NotExists",
70
- "Email_NotSubscribed" => "Mailchimp_Email_NotSubscribed",
71
- "List_MergeFieldRequired" => "Mailchimp_List_MergeFieldRequired",
72
- "List_CannotRemoveEmailMerge" => "Mailchimp_List_CannotRemoveEmailMerge",
73
- "List_Merge_InvalidMergeID" => "Mailchimp_List_Merge_InvalidMergeID",
74
- "List_TooManyMergeFields" => "Mailchimp_List_TooManyMergeFields",
75
- "List_InvalidMergeField" => "Mailchimp_List_InvalidMergeField",
76
- "List_InvalidInterestGroup" => "Mailchimp_List_InvalidInterestGroup",
77
- "List_TooManyInterestGroups" => "Mailchimp_List_TooManyInterestGroups",
78
- "Campaign_DoesNotExist" => "Mailchimp_Campaign_DoesNotExist",
79
- "Campaign_StatsNotAvailable" => "Mailchimp_Campaign_StatsNotAvailable",
80
- "Campaign_InvalidAbsplit" => "Mailchimp_Campaign_InvalidAbsplit",
81
- "Campaign_InvalidContent" => "Mailchimp_Campaign_InvalidContent",
82
- "Campaign_InvalidOption" => "Mailchimp_Campaign_InvalidOption",
83
- "Campaign_InvalidStatus" => "Mailchimp_Campaign_InvalidStatus",
84
- "Campaign_NotSaved" => "Mailchimp_Campaign_NotSaved",
85
- "Campaign_InvalidSegment" => "Mailchimp_Campaign_InvalidSegment",
86
- "Campaign_InvalidRss" => "Mailchimp_Campaign_InvalidRss",
87
- "Campaign_InvalidAuto" => "Mailchimp_Campaign_InvalidAuto",
88
- "MC_ContentImport_InvalidArchive" => "Mailchimp_MC_ContentImport_InvalidArchive",
89
- "Campaign_BounceMissing" => "Mailchimp_Campaign_BounceMissing",
90
- "Campaign_InvalidTemplate" => "Mailchimp_Campaign_InvalidTemplate",
91
- "Invalid_EcommOrder" => "Mailchimp_Invalid_EcommOrder",
92
- "Absplit_UnknownError" => "Mailchimp_Absplit_UnknownError",
93
- "Absplit_UnknownSplitTest" => "Mailchimp_Absplit_UnknownSplitTest",
94
- "Absplit_UnknownTestType" => "Mailchimp_Absplit_UnknownTestType",
95
- "Absplit_UnknownWaitUnit" => "Mailchimp_Absplit_UnknownWaitUnit",
96
- "Absplit_UnknownWinnerType" => "Mailchimp_Absplit_UnknownWinnerType",
97
- "Absplit_WinnerNotSelected" => "Mailchimp_Absplit_WinnerNotSelected",
98
- "Invalid_Analytics" => "Mailchimp_Invalid_Analytics",
99
- "Invalid_DateTime" => "Mailchimp_Invalid_DateTime",
100
- "Invalid_Email" => "Mailchimp_Invalid_Email",
101
- "Invalid_SendType" => "Mailchimp_Invalid_SendType",
102
- "Invalid_Template" => "Mailchimp_Invalid_Template",
103
- "Invalid_TrackingOptions" => "Mailchimp_Invalid_TrackingOptions",
104
- "Invalid_Options" => "Mailchimp_Invalid_Options",
105
- "Invalid_Folder" => "Mailchimp_Invalid_Folder",
106
- "Invalid_URL" => "Mailchimp_Invalid_URL",
107
- "Module_Unknown" => "Mailchimp_Module_Unknown",
108
- "MonthlyPlan_Unknown" => "Mailchimp_MonthlyPlan_Unknown",
109
- "Order_TypeUnknown" => "Mailchimp_Order_TypeUnknown",
110
- "Invalid_PagingLimit" => "Mailchimp_Invalid_PagingLimit",
111
- "Invalid_PagingStart" => "Mailchimp_Invalid_PagingStart",
112
- "Max_Size_Reached" => "Mailchimp_Max_Size_Reached",
113
- "MC_SearchException" => "Mailchimp_MC_SearchException",
114
- "Goal_SaveFailed" => "Mailchimp_Goal_SaveFailed",
115
- "Conversation_DoesNotExist" => "Mailchimp_Conversation_DoesNotExist",
116
- "Conversation_ReplySaveFailed" => "Mailchimp_Conversation_ReplySaveFailed",
117
- "File_Not_Found_Exception" => "Mailchimp_File_Not_Found_Exception",
118
- "Folder_Not_Found_Exception" => "Mailchimp_Folder_Not_Found_Exception",
119
- "Folder_Exists_Exception" => "Mailchimp_Folder_Exists_Exception"
120
- );
121
-
122
- public function __construct($apikey=null, $opts=array()) {
123
- if (!$apikey) {
124
- $apikey = getenv('MAILCHIMP_APIKEY');
125
- }
126
 
127
- if (!$apikey) {
128
- $apikey = $this->readConfigs();
129
- }
130
 
131
- if (!$apikey) {
132
- throw new Mailchimp_Error('You must provide a MailChimp API key');
133
- }
 
 
134
 
135
- $this->apikey = $apikey;
136
- $dc = "us1";
 
 
137
 
138
- if (strstr($this->apikey, "-")){
139
- list($key, $dc) = explode("-", $this->apikey, 2);
140
- if (!$dc) {
141
- $dc = "us1";
 
 
 
 
 
 
 
 
 
142
  }
 
 
 
 
143
  }
144
 
145
- $this->root = str_replace('https://api', 'https://' . $dc . '.api', $this->root);
146
- $this->root = rtrim($this->root, '/') . '/';
147
 
148
- if (!isset($opts['timeout']) || !is_int($opts['timeout'])){
149
- $opts['timeout'] = 600;
150
- }
151
- if (isset($opts['debug'])){
152
- $this->debug = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  }
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
- $this->ch = curl_init();
 
 
 
157
 
158
- if (isset($opts['CURLOPT_FOLLOWLOCATION']) && $opts['CURLOPT_FOLLOWLOCATION'] === true) {
159
- curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
 
 
160
  }
161
 
162
- curl_setopt($this->ch, CURLOPT_USERAGENT, 'MailChimp-PHP/2.0.5');
163
- curl_setopt($this->ch, CURLOPT_POST, true);
164
- curl_setopt($this->ch, CURLOPT_HEADER, false);
165
- curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
166
- curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 30);
167
- curl_setopt($this->ch, CURLOPT_TIMEOUT, $opts['timeout']);
168
-
169
-
170
- $this->folders = new Mailchimp_Folders($this);
171
- $this->templates = new Mailchimp_Templates($this);
172
- $this->users = new Mailchimp_Users($this);
173
- $this->helper = new Mailchimp_Helper($this);
174
- $this->mobile = new Mailchimp_Mobile($this);
175
- $this->conversations = new Mailchimp_Conversations($this);
176
- $this->ecomm = new Mailchimp_Ecomm($this);
177
- $this->neapolitan = new Mailchimp_Neapolitan($this);
178
- $this->lists = new Mailchimp_Lists($this);
179
- $this->campaigns = new Mailchimp_Campaigns($this);
180
- $this->vip = new Mailchimp_Vip($this);
181
- $this->reports = new Mailchimp_Reports($this);
182
- $this->gallery = new Mailchimp_Gallery($this);
183
- $this->goal = new Mailchimp_Goal($this);
184
  }
185
 
186
- public function __destruct() {
187
- curl_close($this->ch);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
 
190
- public function call($url, $params) {
191
- $params['apikey'] = $this->apikey;
192
-
193
- $params = json_encode($params);
194
- $ch = $this->ch;
195
-
196
- curl_setopt($ch, CURLOPT_URL, $this->root . $url . '.json');
197
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
198
- curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
199
- curl_setopt($ch, CURLOPT_VERBOSE, $this->debug);
200
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
201
-
202
- $start = microtime(true);
203
- $this->log('Call to ' . $this->root . $url . '.json: ' . $params);
204
- if($this->debug) {
205
- $curl_buffer = fopen('php://memory', 'w+');
206
- curl_setopt($ch, CURLOPT_STDERR, $curl_buffer);
207
- }
 
 
 
 
 
208
 
209
- $response_body = curl_exec($ch);
210
 
211
- $info = curl_getinfo($ch);
212
- $time = microtime(true) - $start;
213
- if($this->debug) {
214
- rewind($curl_buffer);
215
- $this->log(stream_get_contents($curl_buffer));
216
- fclose($curl_buffer);
 
 
217
  }
218
- $this->log('Completed in ' . number_format($time * 1000, 2) . 'ms');
219
- $this->log('Got response: ' . $response_body);
220
 
221
- if(curl_error($ch)) {
222
- throw new Mailchimp_HttpError("API call to $url failed: " . curl_error($ch));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  }
224
- $result = json_decode($response_body, true);
225
-
226
- if(floor($info['http_code'] / 100) >= 4) {
227
- throw $this->castError($result);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  }
229
 
230
- return $result;
231
  }
232
 
233
- public function readConfigs() {
234
- $paths = array('~/.mailchimp.key', '/etc/mailchimp.key');
235
- foreach($paths as $path) {
236
- if(file_exists($path)) {
237
- $apikey = trim(file_get_contents($path));
238
- if ($apikey) {
239
- return $apikey;
240
- }
 
 
 
 
 
 
 
 
 
 
 
241
  }
242
  }
243
- return false;
 
244
  }
245
 
246
- public function castError($result) {
247
- if ($result['status'] !== 'error' || !$result['name']) {
248
- throw new Mailchimp_Error('We received an unexpected error: ' . json_encode($result));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  }
250
 
251
- $class = (isset(self::$error_map[$result['name']])) ? self::$error_map[$result['name']] : 'Mailchimp_Error';
252
- return new $class($result['error'], $result['code']);
 
 
 
 
 
253
  }
254
 
255
- public function log($msg) {
256
- if ($this->debug) {
257
- error_log($msg);
 
 
 
 
 
 
 
258
  }
 
 
 
 
 
 
259
  }
260
- }
261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ /**
4
+ * Super-simple, minimum abstraction MailChimp API v3 wrapper
5
+ * MailChimp API v3: http://developer.mailchimp.com
6
+ * This wrapper: https://github.com/drewm/mailchimp-api
7
+ *
8
+ * @author Drew McLellan <drew.mclellan@gmail.com>
9
+ * @version 2.4
10
+ */
11
+ class MailChimp
12
+ {
13
+ private $api_key;
14
+ private $api_endpoint = 'https://<dc>.api.mailchimp.com/3.0';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ const TIMEOUT = 10;
 
 
17
 
18
+ /* SSL Verification
19
+ Read before disabling:
20
+ http://snippets.webaware.com.au/howto/stop-turning-off-curlopt_ssl_verifypeer-and-fix-your-php-config/
21
+ */
22
+ public $verify_ssl = true;
23
 
24
+ private $request_successful = false;
25
+ private $last_error = '';
26
+ private $last_response = array();
27
+ private $last_request = array();
28
 
29
+ /**
30
+ * Create a new instance
31
+ * @param string $api_key Your MailChimp API key
32
+ * @param string $api_endpoint Optional custom API endpoint
33
+ * @throws \Exception
34
+ */
35
+ public function __construct($api_key, $api_endpoint = null)
36
+ {
37
+ $this->api_key = $api_key;
38
+
39
+ if ($api_endpoint === null) {
40
+ if (strpos($this->api_key, '-') === false) {
41
+ throw new Exception("Invalid MailChimp API key `{$api_key}` supplied.");
42
  }
43
+ list(, $data_center) = explode('-', $this->api_key);
44
+ $this->api_endpoint = str_replace('<dc>', $data_center, $this->api_endpoint);
45
+ } else {
46
+ $this->api_endpoint = $api_endpoint;
47
  }
48
 
49
+ $this->last_response = array('headers' => null, 'body' => null);
50
+ }
51
 
52
+ /**
53
+ * Create a new instance of a Batch request. Optionally with the ID of an existing batch.
54
+ * @param string $batch_id Optional ID of an existing batch, if you need to check its status for example.
55
+ * @return Batch New Batch object.
56
+ */
57
+ public function new_batch($batch_id = null)
58
+ {
59
+ return new Batch($this, $batch_id);
60
+ }
61
+
62
+ /**
63
+ * @return string The url to the API endpoint
64
+ */
65
+ public function getApiEndpoint()
66
+ {
67
+ return $this->api_endpoint;
68
+ }
69
+
70
+
71
+ /**
72
+ * Convert an email address into a 'subscriber hash' for identifying the subscriber in a method URL
73
+ * @param string $email The subscriber's email address
74
+ * @return string Hashed version of the input
75
+ */
76
+ public function subscriberHash($email)
77
+ {
78
+ return md5(strtolower($email));
79
+ }
80
+
81
+ /**
82
+ * Was the last request successful?
83
+ * @return bool True for success, false for failure
84
+ */
85
+ public function success()
86
+ {
87
+ return $this->request_successful;
88
+ }
89
+
90
+ /**
91
+ * Get the last error returned by either the network transport, or by the API.
92
+ * If something didn't work, this should contain the string describing the problem.
93
+ * @return string|false describing the error
94
+ */
95
+ public function getLastError()
96
+ {
97
+ return $this->last_error ?: false;
98
+ }
99
+
100
+ /**
101
+ * Get an array containing the HTTP headers and the body of the API response.
102
+ * @return array Assoc array with keys 'headers' and 'body'
103
+ */
104
+ public function getLastResponse()
105
+ {
106
+ return $this->last_response;
107
+ }
108
+
109
+ /**
110
+ * Get an array containing the HTTP headers and the body of the API request.
111
+ * @return array Assoc array
112
+ */
113
+ public function getLastRequest()
114
+ {
115
+ return $this->last_request;
116
+ }
117
+
118
+ /**
119
+ * Make an HTTP DELETE request - for deleting data
120
+ * @param string $method URL of the API request method
121
+ * @param array $args Assoc array of arguments (if any)
122
+ * @param int $timeout Timeout limit for request in seconds
123
+ * @return array|false Assoc array of API response, decoded from JSON
124
+ */
125
+ public function delete($method, $args = array(), $timeout = self::TIMEOUT)
126
+ {
127
+ return $this->makeRequest('delete', $method, $args, $timeout);
128
+ }
129
+
130
+ /**
131
+ * Make an HTTP GET request - for retrieving data
132
+ * @param string $method URL of the API request method
133
+ * @param array $args Assoc array of arguments (usually your data)
134
+ * @param int $timeout Timeout limit for request in seconds
135
+ * @return array|false Assoc array of API response, decoded from JSON
136
+ */
137
+ public function get($method, $args = array(), $timeout = self::TIMEOUT)
138
+ {
139
+ return $this->makeRequest('get', $method, $args, $timeout);
140
+ }
141
+
142
+ /**
143
+ * Make an HTTP PATCH request - for performing partial updates
144
+ * @param string $method URL of the API request method
145
+ * @param array $args Assoc array of arguments (usually your data)
146
+ * @param int $timeout Timeout limit for request in seconds
147
+ * @return array|false Assoc array of API response, decoded from JSON
148
+ */
149
+ public function patch($method, $args = array(), $timeout = self::TIMEOUT)
150
+ {
151
+ return $this->makeRequest('patch', $method, $args, $timeout);
152
+ }
153
+
154
+ /**
155
+ * Make an HTTP POST request - for creating and updating items
156
+ * @param string $method URL of the API request method
157
+ * @param array $args Assoc array of arguments (usually your data)
158
+ * @param int $timeout Timeout limit for request in seconds
159
+ * @return array|false Assoc array of API response, decoded from JSON
160
+ */
161
+ public function post($method, $args = array(), $timeout = self::TIMEOUT)
162
+ {
163
+ return $this->makeRequest('post', $method, $args, $timeout);
164
+ }
165
+
166
+ /**
167
+ * Make an HTTP PUT request - for creating new items
168
+ * @param string $method URL of the API request method
169
+ * @param array $args Assoc array of arguments (usually your data)
170
+ * @param int $timeout Timeout limit for request in seconds
171
+ * @return array|false Assoc array of API response, decoded from JSON
172
+ */
173
+ public function put($method, $args = array(), $timeout = self::TIMEOUT)
174
+ {
175
+ return $this->makeRequest('put', $method, $args, $timeout);
176
+ }
177
+
178
+ /**
179
+ * Performs the underlying HTTP request. Not very exciting.
180
+ * @param string $http_verb The HTTP verb to use: get, post, put, patch, delete
181
+ * @param string $method The API method to be called
182
+ * @param array $args Assoc array of parameters to be passed
183
+ * @param int $timeout
184
+ * @return array|false Assoc array of decoded result
185
+ * @throws \Exception
186
+ */
187
+ private function makeRequest($http_verb, $method, $args = array(), $timeout = self::TIMEOUT)
188
+ {
189
+ if (!function_exists('curl_init') || !function_exists('curl_setopt')) {
190
+ throw new Exception("cURL support is required, but can't be found.");
191
  }
192
 
193
+ $url = $this->api_endpoint . '/' . $method;
194
+
195
+ $response = $this->prepareStateForRequest($http_verb, $method, $url, $timeout);
196
+
197
+ $ch = curl_init();
198
+ curl_setopt($ch, CURLOPT_URL, $url);
199
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array(
200
+ 'Accept: application/vnd.api+json',
201
+ 'Content-Type: application/vnd.api+json',
202
+ 'Authorization: apikey ' . $this->api_key
203
+ ));
204
+ curl_setopt($ch, CURLOPT_USERAGENT, 'DrewM/MailChimp-API/3.0 (github.com/drewm/mailchimp-api)');
205
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
206
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
207
+ curl_setopt($ch, CURLOPT_HEADER, true);
208
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
209
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl);
210
+ curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
211
+ curl_setopt($ch, CURLOPT_ENCODING, '');
212
+ curl_setopt($ch, CURLINFO_HEADER_OUT, true);
213
+
214
+ switch ($http_verb) {
215
+ case 'post':
216
+ curl_setopt($ch, CURLOPT_POST, true);
217
+ $this->attachRequestPayload($ch, $args);
218
+ break;
219
+
220
+ case 'get':
221
+ $query = http_build_query($args, '', '&');
222
+ curl_setopt($ch, CURLOPT_URL, $url . '?' . $query);
223
+ break;
224
+
225
+ case 'delete':
226
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
227
+ break;
228
 
229
+ case 'patch':
230
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
231
+ $this->attachRequestPayload($ch, $args);
232
+ break;
233
 
234
+ case 'put':
235
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
236
+ $this->attachRequestPayload($ch, $args);
237
+ break;
238
  }
239
 
240
+ $responseContent = curl_exec($ch);
241
+ $response['headers'] = curl_getinfo($ch);
242
+ $response = $this->setResponseState($response, $responseContent, $ch);
243
+ $formattedResponse = $this->formatResponse($response);
244
+
245
+ curl_close($ch);
246
+
247
+ $this->determineSuccess($response, $formattedResponse, $timeout);
248
+
249
+ return $formattedResponse;
 
 
 
 
 
 
 
 
 
 
 
 
250
  }
251
 
252
+ /**
253
+ * @param string $http_verb
254
+ * @param string $method
255
+ * @param string $url
256
+ * @param integer $timeout
257
+ */
258
+ private function prepareStateForRequest($http_verb, $method, $url, $timeout)
259
+ {
260
+ $this->last_error = '';
261
+
262
+ $this->request_successful = false;
263
+
264
+ $this->last_response = array(
265
+ 'headers' => null, // array of details from curl_getinfo()
266
+ 'httpHeaders' => null, // array of HTTP headers
267
+ 'body' => null // content of the response
268
+ );
269
+
270
+ $this->last_request = array(
271
+ 'method' => $http_verb,
272
+ 'path' => $method,
273
+ 'url' => $url,
274
+ 'body' => '',
275
+ 'timeout' => $timeout,
276
+ );
277
+
278
+ return $this->last_response;
279
  }
280
 
281
+ /**
282
+ * Get the HTTP headers as an array of header-name => header-value pairs.
283
+ *
284
+ * The "Link" header is parsed into an associative array based on the
285
+ * rel names it contains. The original value is available under
286
+ * the "_raw" key.
287
+ *
288
+ * @param string $headersAsString
289
+ * @return array
290
+ */
291
+ private function getHeadersAsArray($headersAsString)
292
+ {
293
+ $headers = array();
294
+
295
+ foreach (explode("\r\n", $headersAsString) as $i => $line) {
296
+ if ($i === 0) { // HTTP code
297
+ continue;
298
+ }
299
+
300
+ $line = trim($line);
301
+ if (empty($line)) {
302
+ continue;
303
+ }
304
 
305
+ list($key, $value) = explode(': ', $line);
306
 
307
+ if ($key == 'Link') {
308
+ $value = array_merge(
309
+ array('_raw' => $value),
310
+ $this->getLinkHeaderAsArray($value)
311
+ );
312
+ }
313
+
314
+ $headers[$key] = $value;
315
  }
 
 
316
 
317
+ return $headers;
318
+ }
319
+
320
+ /**
321
+ * Extract all rel => URL pairs from the provided Link header value
322
+ *
323
+ * Mailchimp only implements the URI reference and relation type from
324
+ * RFC 5988, so the value of the header is something like this:
325
+ *
326
+ * 'https://us13.api.mailchimp.com/schema/3.0/Lists/Instance.json; rel="describedBy", <https://us13.admin.mailchimp.com/lists/members/?id=XXXX>; rel="dashboard"'
327
+ *
328
+ * @param string $linkHeaderAsString
329
+ * @return array
330
+ */
331
+ private function getLinkHeaderAsArray($linkHeaderAsString)
332
+ {
333
+ $urls = array();
334
+
335
+ if (preg_match_all('/<(.*?)>\s*;\s*rel="(.*?)"\s*/', $linkHeaderAsString, $matches)) {
336
+ foreach ($matches[2] as $i => $relName) {
337
+ $urls[$relName] = $matches[1][$i];
338
+ }
339
  }
340
+
341
+ return $urls;
342
+ }
343
+
344
+ /**
345
+ * Encode the data and attach it to the request
346
+ * @param resource $ch cURL session handle, used by reference
347
+ * @param array $data Assoc array of data to attach
348
+ */
349
+ private function attachRequestPayload(&$ch, $data)
350
+ {
351
+ $encoded = json_encode($data);
352
+ $this->last_request['body'] = $encoded;
353
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
354
+ }
355
+
356
+ /**
357
+ * Decode the response and format any error messages for debugging
358
+ * @param array $response The response from the curl request
359
+ * @return array|false The JSON decoded into an array
360
+ */
361
+ private function formatResponse($response)
362
+ {
363
+ $this->last_response = $response;
364
+
365
+ if (!empty($response['body'])) {
366
+ return json_decode($response['body'], true);
367
  }
368
 
369
+ return false;
370
  }
371
 
372
+ /**
373
+ * Do post-request formatting and setting state from the response
374
+ * @param array $response The response from the curl request
375
+ * @param string $responseContent The body of the response from the curl request
376
+ * * @return array The modified response
377
+ */
378
+ private function setResponseState($response, $responseContent, $ch)
379
+ {
380
+ if ($responseContent === false) {
381
+ $this->last_error = curl_error($ch);
382
+ } else {
383
+
384
+ $headerSize = $response['headers']['header_size'];
385
+
386
+ $response['httpHeaders'] = $this->getHeadersAsArray(substr($responseContent, 0, $headerSize));
387
+ $response['body'] = substr($responseContent, $headerSize);
388
+
389
+ if (isset($response['headers']['request_header'])) {
390
+ $this->last_request['headers'] = $response['headers']['request_header'];
391
  }
392
  }
393
+
394
+ return $response;
395
  }
396
 
397
+ /**
398
+ * Check if the response was successful or a failure. If it failed, store the error.
399
+ * @param array $response The response from the curl request
400
+ * @param array|false $formattedResponse The response body payload from the curl request
401
+ * @param int $timeout The timeout supplied to the curl request.
402
+ * @return bool If the request was successful
403
+ */
404
+ private function determineSuccess($response, $formattedResponse, $timeout)
405
+ {
406
+ $status = $this->findHTTPStatus($response, $formattedResponse);
407
+
408
+ if ($status >= 200 && $status <= 299) {
409
+ $this->request_successful = true;
410
+ return true;
411
+ }
412
+
413
+ if (isset($formattedResponse['detail'])) {
414
+ $this->last_error = sprintf('%d: %s', $formattedResponse['status'], $formattedResponse['detail']);
415
+ return false;
416
  }
417
 
418
+ if( $timeout > 0 && $response['headers'] && $response['headers']['total_time'] >= $timeout ) {
419
+ $this->last_error = sprintf('Request timed out after %f seconds.', $response['headers']['total_time'] );
420
+ return false;
421
+ }
422
+
423
+ $this->last_error = 'Unknown error, call getLastResponse() to find out what happened.';
424
+ return false;
425
  }
426
 
427
+ /**
428
+ * Find the HTTP status code from the headers or API response body
429
+ * @param array $response The response from the curl request
430
+ * @param array|false $formattedResponse The response body payload from the curl request
431
+ * @return int HTTP status code
432
+ */
433
+ private function findHTTPStatus($response, $formattedResponse)
434
+ {
435
+ if (!empty($response['headers']) && isset($response['headers']['http_code'])) {
436
+ return (int) $response['headers']['http_code'];
437
  }
438
+
439
+ if (!empty($response['body']) && isset($formattedResponse['status'])) {
440
+ return (int) $formattedResponse['status'];
441
+ }
442
+
443
+ return 418;
444
  }
 
445
 
446
+ /**
447
+ * Get all the mailing list. Takes care of the request limit (50 records) from the MC API.
448
+ * @param array $args Assoc array of arguments
449
+ * @return array of all the lists with the MC account.
450
+ */
451
+ public function getLists( $args = array() ){
452
+ $defaults = array(
453
+ 'count' => 50,
454
+ 'offset' => 0,
455
+ 'sort_field' => 'date_created',
456
+ 'sort_dir' => 'ASC',
457
+ 'fields' => 'lists.name,lists.id,total_items'
458
+ );
459
+ $r = array_merge( $defaults, $args );
460
+
461
+ $result = $this->get( 'lists', $r );
462
+ $lists = array();
463
+
464
+ if ( isset( $result[ 'lists' ] ) ) {
465
+
466
+ $lists = $result[ 'lists' ];
467
+
468
+ if ( count( $lists ) < $result[ 'total_items' ] ) {
469
+ for ( $offset = 50; $offset < $result[ 'total_items' ]; $offset += 50 ) {
470
+ $r[ 'offset' ] = $offset;
471
+ $new_result = $this->get( 'lists', $r );
472
+ $lists = array_merge( $lists, $new_result[ 'lists' ] );
473
+ }
474
+ }
475
+ }
476
+
477
+ return $lists;
478
+ }
479
+
480
+ /**
481
+ * Get the list of interest groupings for a given list, including the label, form information, and included groups for each
482
+ * @param string $list_id
483
+ * @return array of structs of the interest groupings for the list
484
+ */
485
+ public function interestGroupings( $list_id ) {
486
+ if ( ! $list_id ) {
487
+ return;
488
+ }
489
+
490
+ $groups = array();
491
+ $results = $this->get(
492
+ 'lists/' . $list_id . '/interest-categories',
493
+ array(
494
+ 'fields' => 'categories.id,categories.title,total_items'
495
+ )
496
+ );
497
+
498
+ if ( $results[ 'total_items' ] > 0 ) {
499
+ foreach ( $results[ 'categories' ] as $category ) {
500
+ $subgroups = $this->get(
501
+ 'lists/' . $list_id . '/interest-categories/' . $category[ 'id' ] . '/interests',
502
+ array(
503
+ 'fields' => 'interests.id,interests.name,total_items'
504
+ )
505
+ );
506
 
507
+ if ( $subgroups[ 'total_items' ] > 0 ) {
508
+ $category[ 'groups' ] = $subgroups[ 'interests' ];
509
+ }
510
+
511
+ $groups[] = $category;
512
+ }
513
+ }
514
+
515
+ return $groups;
516
+ }
517
+
518
+ /**
519
+ * Subscribe a member to a list. It will automatically update member if exists.
520
+ * @param string $list_id
521
+ * @param array $data
522
+ * @return array
523
+ */
524
+ public function subscribe( $list_id, $data ){
525
+ if ( ! isset( $list_id ) || ! isset( $data[ 'email' ] ) ) {
526
+ return;
527
+ }
528
+
529
+ $member = $this->get_member( $list_id, $data[ 'email' ] );
530
+ if ( ! $this->getLastError() && 'unsubscribed' == $member[ 'status' ] ) {
531
+ // Re-subscribe member if their status is `unsubscribed`.
532
+ $data[ 'status' ] = 'pending';
533
+ }
534
+
535
+ $args = array(
536
+ 'email_address' => $data[ 'email' ],
537
+ 'status_if_new' => $data[ 'double_optin' ] ? 'pending' : 'subscribed',
538
+ 'status' => isset( $data[ 'status' ] ) ? $data[ 'status' ] : 'subscribed',
539
+ 'email_type' => 'html',
540
+ 'merge_fields' => array(
541
+ 'FNAME' => ! empty( $data[ 'FNAME' ] ) ? $data[ 'FNAME' ] : '',
542
+ 'LNAME' => ! empty( $data[ 'LNAME' ] ) ? $data[ 'LNAME' ] : ''
543
+ ),
544
+ 'interests' => (object) $data[ 'groups' ]
545
+ );
546
+
547
+ $email_hash = $this->subscriberHash( $data[ 'email' ] );
548
+ $results = $this->put( 'lists/' . $list_id . '/members/' . $email_hash, $args );
549
+
550
+ return $results;
551
+ }
552
+
553
+ /**
554
+ * Get information about a specific list member.
555
+ * @param string $list_id
556
+ * @param string $email
557
+ * @return array
558
+ */
559
+ public function get_member( $list_id, $email ){
560
+ if ( ! $email ) {
561
+ return;
562
+ }
563
+
564
+ $email_hash = $this->subscriberHash( $email );
565
+ $result = $this->get( 'lists/' . $list_id . '/members/' . $email_hash );
566
+
567
+ return $result;
568
+ }
569
+ }
js/build/builder.bundle.js ADDED
@@ -0,0 +1,20351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /******/ (function(modules) { // webpackBootstrap
2
+ /******/ // The module cache
3
+ /******/ var installedModules = {};
4
+ /******/
5
+ /******/ // The require function
6
+ /******/ function __webpack_require__(moduleId) {
7
+ /******/
8
+ /******/ // Check if module is in cache
9
+ /******/ if(installedModules[moduleId]) {
10
+ /******/ return installedModules[moduleId].exports;
11
+ /******/ }
12
+ /******/ // Create a new module (and put it into the cache)
13
+ /******/ var module = installedModules[moduleId] = {
14
+ /******/ i: moduleId,
15
+ /******/ l: false,
16
+ /******/ exports: {}
17
+ /******/ };
18
+ /******/
19
+ /******/ // Execute the module function
20
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21
+ /******/
22
+ /******/ // Flag the module as loaded
23
+ /******/ module.l = true;
24
+ /******/
25
+ /******/ // Return the exports of the module
26
+ /******/ return module.exports;
27
+ /******/ }
28
+ /******/
29
+ /******/
30
+ /******/ // expose the modules object (__webpack_modules__)
31
+ /******/ __webpack_require__.m = modules;
32
+ /******/
33
+ /******/ // expose the module cache
34
+ /******/ __webpack_require__.c = installedModules;
35
+ /******/
36
+ /******/ // define getter function for harmony exports
37
+ /******/ __webpack_require__.d = function(exports, name, getter) {
38
+ /******/ if(!__webpack_require__.o(exports, name)) {
39
+ /******/ Object.defineProperty(exports, name, {
40
+ /******/ configurable: false,
41
+ /******/ enumerable: true,
42
+ /******/ get: getter
43
+ /******/ });
44
+ /******/ }
45
+ /******/ };
46
+ /******/
47
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
48
+ /******/ __webpack_require__.n = function(module) {
49
+ /******/ var getter = module && module.__esModule ?
50
+ /******/ function getDefault() { return module['default']; } :
51
+ /******/ function getModuleExports() { return module; };
52
+ /******/ __webpack_require__.d(getter, 'a', getter);
53
+ /******/ return getter;
54
+ /******/ };
55
+ /******/
56
+ /******/ // Object.prototype.hasOwnProperty.call
57
+ /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58
+ /******/
59
+ /******/ // __webpack_public_path__
60
+ /******/ __webpack_require__.p = "";
61
+ /******/
62
+ /******/ // Load entry module and return exports
63
+ /******/ return __webpack_require__(__webpack_require__.s = 12);
64
+ /******/ })
65
+ /************************************************************************/
66
+ /******/ ([
67
+ /* 0 */
68
+ /***/ (function(module, exports) {
69
+
70
+ // shim for using process in browser
71
+ var process = module.exports = {};
72
+
73
+ // cached from whatever global is present so that test runners that stub it
74
+ // don't break things. But we need to wrap it in a try catch in case it is
75
+ // wrapped in strict mode code which doesn't define any globals. It's inside a
76
+ // function because try/catches deoptimize in certain engines.
77
+
78
+ var cachedSetTimeout;
79
+ var cachedClearTimeout;
80
+
81
+ function defaultSetTimout() {
82
+ throw new Error('setTimeout has not been defined');
83
+ }
84
+ function defaultClearTimeout () {
85
+ throw new Error('clearTimeout has not been defined');
86
+ }
87
+ (function () {
88
+ try {
89
+ if (typeof setTimeout === 'function') {
90
+ cachedSetTimeout = setTimeout;
91
+ } else {
92
+ cachedSetTimeout = defaultSetTimout;
93
+ }
94
+ } catch (e) {
95
+ cachedSetTimeout = defaultSetTimout;
96
+ }
97
+ try {
98
+ if (typeof clearTimeout === 'function') {
99
+ cachedClearTimeout = clearTimeout;
100
+ } else {
101
+ cachedClearTimeout = defaultClearTimeout;
102
+ }
103
+ } catch (e) {
104
+ cachedClearTimeout = defaultClearTimeout;
105
+ }
106
+ } ())
107
+ function runTimeout(fun) {
108
+ if (cachedSetTimeout === setTimeout) {
109
+ //normal enviroments in sane situations
110
+ return setTimeout(fun, 0);
111
+ }
112
+ // if setTimeout wasn't available but was latter defined
113
+ if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
114
+ cachedSetTimeout = setTimeout;
115
+ return setTimeout(fun, 0);
116
+ }
117
+ try {
118
+ // when when somebody has screwed with setTimeout but no I.E. maddness
119
+ return cachedSetTimeout(fun, 0);
120
+ } catch(e){
121
+ try {
122
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
123
+ return cachedSetTimeout.call(null, fun, 0);
124
+ } catch(e){
125
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
126
+ return cachedSetTimeout.call(this, fun, 0);
127
+ }
128
+ }
129
+
130
+
131
+ }
132
+ function runClearTimeout(marker) {
133
+ if (cachedClearTimeout === clearTimeout) {
134
+ //normal enviroments in sane situations
135
+ return clearTimeout(marker);
136
+ }
137
+ // if clearTimeout wasn't available but was latter defined
138
+ if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
139
+ cachedClearTimeout = clearTimeout;
140
+ return clearTimeout(marker);
141
+ }
142
+ try {
143
+ // when when somebody has screwed with setTimeout but no I.E. maddness
144
+ return cachedClearTimeout(marker);
145
+ } catch (e){
146
+ try {
147
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
148
+ return cachedClearTimeout.call(null, marker);
149
+ } catch (e){
150
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
151
+ // Some versions of I.E. have different rules for clearTimeout vs setTimeout
152
+ return cachedClearTimeout.call(this, marker);
153
+ }
154
+ }
155
+
156
+
157
+
158
+ }
159
+ var queue = [];
160
+ var draining = false;
161
+ var currentQueue;
162
+ var queueIndex = -1;
163
+
164
+ function cleanUpNextTick() {
165
+ if (!draining || !currentQueue) {
166
+ return;
167
+ }
168
+ draining = false;
169
+ if (currentQueue.length) {
170
+ queue = currentQueue.concat(queue);
171
+ } else {
172
+ queueIndex = -1;
173
+ }
174
+ if (queue.length) {
175
+ drainQueue();
176
+ }
177
+ }
178
+
179
+ function drainQueue() {
180
+ if (draining) {
181
+ return;
182
+ }
183
+ var timeout = runTimeout(cleanUpNextTick);
184
+ draining = true;
185
+
186
+ var len = queue.length;
187
+ while(len) {
188
+ currentQueue = queue;
189
+ queue = [];
190
+ while (++queueIndex < len) {
191
+ if (currentQueue) {
192
+ currentQueue[queueIndex].run();
193
+ }
194
+ }
195
+ queueIndex = -1;
196
+ len = queue.length;
197
+ }
198
+ currentQueue = null;
199
+ draining = false;
200
+ runClearTimeout(timeout);
201
+ }
202
+
203
+ process.nextTick = function (fun) {
204
+ var args = new Array(arguments.length - 1);
205
+ if (arguments.length > 1) {
206
+ for (var i = 1; i < arguments.length; i++) {
207
+ args[i - 1] = arguments[i];
208
+ }
209
+ }
210
+ queue.push(new Item(fun, args));
211
+ if (queue.length === 1 && !draining) {
212
+ runTimeout(drainQueue);
213
+ }
214
+ };
215
+
216
+ // v8 likes predictible objects
217
+ function Item(fun, array) {
218
+ this.fun = fun;
219
+ this.array = array;
220
+ }
221
+ Item.prototype.run = function () {
222
+ this.fun.apply(null, this.array);
223
+ };
224
+ process.title = 'browser';
225
+ process.browser = true;
226
+ process.env = {};
227
+ process.argv = [];
228
+ process.version = ''; // empty string to avoid regexp issues
229
+ process.versions = {};
230
+
231
+ function noop() {}
232
+
233
+ process.on = noop;
234
+ process.addListener = noop;
235
+ process.once = noop;
236
+ process.off = noop;
237
+ process.removeListener = noop;
238
+ process.removeAllListeners = noop;
239
+ process.emit = noop;
240
+ process.prependListener = noop;
241
+ process.prependOnceListener = noop;
242
+
243
+ process.listeners = function (name) { return [] }
244
+
245
+ process.binding = function (name) {
246
+ throw new Error('process.binding is not supported');
247
+ };
248
+
249
+ process.cwd = function () { return '/' };
250
+ process.chdir = function (dir) {
251
+ throw new Error('process.chdir is not supported');
252
+ };
253
+ process.umask = function() { return 0; };
254
+
255
+
256
+ /***/ }),
257
+ /* 1 */
258
+ /***/ (function(module, exports, __webpack_require__) {
259
+
260
+ "use strict";
261
+ /* WEBPACK VAR INJECTION */(function(process) {
262
+
263
+ if (process.env.NODE_ENV === 'production') {
264
+ module.exports = __webpack_require__(13);
265
+ } else {
266
+ module.exports = __webpack_require__(14);
267
+ }
268
+
269
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
270
+
271
+ /***/ }),
272
+ /* 2 */
273
+ /***/ (function(module, exports, __webpack_require__) {
274
+
275
+ "use strict";
276
+ /* WEBPACK VAR INJECTION */(function(process) {/**
277
+ * Copyright (c) 2013-present, Facebook, Inc.
278
+ *
279
+ * This source code is licensed under the MIT license found in the
280
+ * LICENSE file in the root directory of this source tree.
281
+ *
282
+ */
283
+
284
+
285
+
286
+ /**
287
+ * Use invariant() to assert state which your program assumes to be true.
288
+ *
289
+ * Provide sprintf-style format (only %s is supported) and arguments
290
+ * to provide information about what broke and what you were
291
+ * expecting.
292
+ *
293
+ * The invariant message will be stripped in production, but the invariant
294
+ * will remain to ensure logic does not differ in production.
295
+ */
296
+
297
+ var validateFormat = function validateFormat(format) {};
298
+
299
+ if (process.env.NODE_ENV !== 'production') {
300
+ validateFormat = function validateFormat(format) {
301
+ if (format === undefined) {
302
+ throw new Error('invariant requires an error message argument');
303
+ }
304
+ };
305
+ }
306
+
307
+ function invariant(condition, format, a, b, c, d, e, f) {
308
+ validateFormat(format);
309
+
310
+ if (!condition) {
311
+ var error;
312
+ if (format === undefined) {
313
+ error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
314
+ } else {
315
+ var args = [a, b, c, d, e, f];
316
+ var argIndex = 0;
317
+ error = new Error(format.replace(/%s/g, function () {
318
+ return args[argIndex++];
319
+ }));
320
+ error.name = 'Invariant Violation';
321
+ }
322
+
323
+ error.framesToPop = 1; // we don't care about invariant's own frame
324
+ throw error;
325
+ }
326
+ }
327
+
328
+ module.exports = invariant;
329
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
330
+
331
+ /***/ }),
332
+ /* 3 */
333
+ /***/ (function(module, exports, __webpack_require__) {
334
+
335
+ "use strict";
336
+
337
+
338
+ /**
339
+ * Copyright (c) 2013-present, Facebook, Inc.
340
+ *
341
+ * This source code is licensed under the MIT license found in the
342
+ * LICENSE file in the root directory of this source tree.
343
+ *
344
+ *
345
+ */
346
+
347
+ function makeEmptyFunction(arg) {
348
+ return function () {
349
+ return arg;
350
+ };
351
+ }
352
+
353
+ /**
354
+ * This function accepts and discards inputs; it has no side effects. This is
355
+ * primarily useful idiomatically for overridable function endpoints which
356
+ * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
357
+ */
358
+ var emptyFunction = function emptyFunction() {};
359
+
360
+ emptyFunction.thatReturns = makeEmptyFunction;
361
+ emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
362
+ emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
363
+ emptyFunction.thatReturnsNull = makeEmptyFunction(null);
364
+ emptyFunction.thatReturnsThis = function () {
365
+ return this;
366
+ };
367
+ emptyFunction.thatReturnsArgument = function (arg) {
368
+ return arg;
369
+ };
370
+
371
+ module.exports = emptyFunction;
372
+
373
+ /***/ }),
374
+ /* 4 */
375
+ /***/ (function(module, exports, __webpack_require__) {
376
+
377
+ "use strict";
378
+ /*
379
+ object-assign
380
+ (c) Sindre Sorhus
381
+ @license MIT
382
+ */
383
+
384
+
385
+ /* eslint-disable no-unused-vars */
386
+ var getOwnPropertySymbols = Object.getOwnPropertySymbols;
387
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
388
+ var propIsEnumerable = Object.prototype.propertyIsEnumerable;
389
+
390
+ function toObject(val) {
391
+ if (val === null || val === undefined) {
392
+ throw new TypeError('Object.assign cannot be called with null or undefined');
393
+ }
394
+
395
+ return Object(val);
396
+ }
397
+
398
+ function shouldUseNative() {
399
+ try {
400
+ if (!Object.assign) {
401
+ return false;
402
+ }
403
+
404
+ // Detect buggy property enumeration order in older V8 versions.
405
+
406
+ // https://bugs.chromium.org/p/v8/issues/detail?id=4118
407
+ var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
408
+ test1[5] = 'de';
409
+ if (Object.getOwnPropertyNames(test1)[0] === '5') {
410
+ return false;
411
+ }
412
+
413
+ // https://bugs.chromium.org/p/v8/issues/detail?id=3056
414
+ var test2 = {};
415
+ for (var i = 0; i < 10; i++) {
416
+ test2['_' + String.fromCharCode(i)] = i;
417
+ }
418
+ var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
419
+ return test2[n];
420
+ });
421
+ if (order2.join('') !== '0123456789') {
422
+ return false;
423
+ }
424
+
425
+ // https://bugs.chromium.org/p/v8/issues/detail?id=3056
426
+ var test3 = {};
427
+ 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
428
+ test3[letter] = letter;
429
+ });
430
+ if (Object.keys(Object.assign({}, test3)).join('') !==
431
+ 'abcdefghijklmnopqrst') {
432
+ return false;
433
+ }
434
+
435
+ return true;
436
+ } catch (err) {
437
+ // We don't expect any of the above to throw, but better to be safe.
438
+ return false;
439
+ }
440
+ }
441
+
442
+ module.exports = shouldUseNative() ? Object.assign : function (target, source) {
443
+ var from;
444
+ var to = toObject(target);
445
+ var symbols;
446
+
447
+ for (var s = 1; s < arguments.length; s++) {
448
+ from = Object(arguments[s]);
449
+
450
+ for (var key in from) {
451
+ if (hasOwnProperty.call(from, key)) {
452
+ to[key] = from[key];
453
+ }
454
+ }
455
+
456
+ if (getOwnPropertySymbols) {
457
+ symbols = getOwnPropertySymbols(from);
458
+ for (var i = 0; i < symbols.length; i++) {
459
+ if (propIsEnumerable.call(from, symbols[i])) {
460
+ to[symbols[i]] = from[symbols[i]];
461
+ }
462
+ }
463
+ }
464
+ }
465
+
466
+ return to;
467
+ };
468
+
469
+
470
+ /***/ }),
471
+ /* 5 */
472
+ /***/ (function(module, exports, __webpack_require__) {
473
+
474
+ "use strict";
475
+ /* WEBPACK VAR INJECTION */(function(process) {/**
476
+ * Copyright (c) 2013-present, Facebook, Inc.
477
+ *
478
+ * This source code is licensed under the MIT license found in the
479
+ * LICENSE file in the root directory of this source tree.
480
+ *
481
+ */
482
+
483
+
484
+
485
+ var emptyObject = {};
486
+
487
+ if (process.env.NODE_ENV !== 'production') {
488
+ Object.freeze(emptyObject);
489
+ }
490
+
491
+ module.exports = emptyObject;
492
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
493
+
494
+ /***/ }),
495
+ /* 6 */
496
+ /***/ (function(module, exports, __webpack_require__) {
497
+
498
+ "use strict";
499
+ /* WEBPACK VAR INJECTION */(function(process) {/**
500
+ * Copyright (c) 2014-present, Facebook, Inc.
501
+ *
502
+ * This source code is licensed under the MIT license found in the
503
+ * LICENSE file in the root directory of this source tree.
504
+ *
505
+ */
506
+
507
+
508
+
509
+ var emptyFunction = __webpack_require__(3);
510
+
511
+ /**
512
+ * Similar to invariant but only logs a warning if the condition is not met.
513
+ * This can be used to log issues in development environments in critical
514
+ * paths. Removing the logging code for production environments will keep the
515
+ * same logic and follow the same code paths.
516
+ */
517
+
518
+ var warning = emptyFunction;
519
+
520
+ if (process.env.NODE_ENV !== 'production') {
521
+ var printWarning = function printWarning(format) {
522
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
523
+ args[_key - 1] = arguments[_key];
524
+ }
525
+
526
+ var argIndex = 0;
527
+ var message = 'Warning: ' + format.replace(/%s/g, function () {
528
+ return args[argIndex++];
529
+ });
530
+ if (typeof console !== 'undefined') {
531
+ console.error(message);
532
+ }
533
+ try {
534
+ // --- Welcome to debugging React ---
535
+ // This error was thrown as a convenience so that you can use this stack
536
+ // to find the callsite that caused this warning to fire.
537
+ throw new Error(message);
538
+ } catch (x) {}
539
+ };
540
+
541
+ warning = function warning(condition, format) {
542
+ if (format === undefined) {
543
+ throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
544
+ }
545
+
546
+ if (format.indexOf('Failed Composite propType: ') === 0) {
547
+ return; // Ignore CompositeComponent proptype check.
548
+ }
549
+
550
+ if (!condition) {
551
+ for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
552
+ args[_key2 - 2] = arguments[_key2];
553
+ }
554
+
555
+ printWarning.apply(undefined, [format].concat(args));
556
+ }
557
+ };
558
+ }
559
+
560
+ module.exports = warning;
561
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
562
+
563
+ /***/ }),
564
+ /* 7 */
565
+ /***/ (function(module, exports, __webpack_require__) {
566
+
567
+ "use strict";
568
+ /* WEBPACK VAR INJECTION */(function(process) {/**
569
+ * Copyright (c) 2013-present, Facebook, Inc.
570
+ *
571
+ * This source code is licensed under the MIT license found in the
572
+ * LICENSE file in the root directory of this source tree.
573
+ */
574
+
575
+
576
+
577
+ if (process.env.NODE_ENV !== 'production') {
578
+ var invariant = __webpack_require__(2);
579
+ var warning = __webpack_require__(6);
580
+ var ReactPropTypesSecret = __webpack_require__(15);
581
+ var loggedTypeFailures = {};
582
+ }
583
+
584
+ /**
585
+ * Assert that the values match with the type specs.
586
+ * Error messages are memorized and will only be shown once.
587
+ *
588
+ * @param {object} typeSpecs Map of name to a ReactPropType
589
+ * @param {object} values Runtime values that need to be type-checked
590
+ * @param {string} location e.g. "prop", "context", "child context"
591
+ * @param {string} componentName Name of the component for error messages.
592
+ * @param {?Function} getStack Returns the component stack.
593
+ * @private
594
+ */
595
+ function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
596
+ if (process.env.NODE_ENV !== 'production') {
597
+ for (var typeSpecName in typeSpecs) {
598
+ if (typeSpecs.hasOwnProperty(typeSpecName)) {
599
+ var error;
600
+ // Prop type validation may throw. In case they do, we don't want to
601
+ // fail the render phase where it didn't fail before. So we log it.
602
+ // After these have been cleaned up, we'll let them throw.
603
+ try {
604
+ // This is intentionally an invariant that gets caught. It's the same
605
+ // behavior as without this statement except with a better message.
606
+ invariant(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'the `prop-types` package, but received `%s`.', componentName || 'React class', location, typeSpecName, typeof typeSpecs[typeSpecName]);
607
+ error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
608
+ } catch (ex) {
609
+ error = ex;
610
+ }
611
+ warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error);
612
+ if (error instanceof Error && !(error.message in loggedTypeFailures)) {
613
+ // Only monitor this failure once because there tends to be a lot of the
614
+ // same error.
615
+ loggedTypeFailures[error.message] = true;
616
+
617
+ var stack = getStack ? getStack() : '';
618
+
619
+ warning(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '');
620
+ }
621
+ }
622
+ }
623
+ }
624
+ }
625
+
626
+ module.exports = checkPropTypes;
627
+
628
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
629
+
630
+ /***/ }),
631
+ /* 8 */
632
+ /***/ (function(module, exports, __webpack_require__) {
633
+
634
+ "use strict";
635
+ /**
636
+ * Copyright (c) 2013-present, Facebook, Inc.
637
+ *
638
+ * This source code is licensed under the MIT license found in the
639
+ * LICENSE file in the root directory of this source tree.
640
+ *
641
+ */
642
+
643
+
644
+
645
+ var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
646
+
647
+ /**
648
+ * Simple, lightweight module assisting with the detection and context of
649
+ * Worker. Helps avoid circular dependencies and allows code to reason about
650
+ * whether or not they are in a Worker, even if they never include the main
651
+ * `ReactWorker` dependency.
652
+ */
653
+ var ExecutionEnvironment = {
654
+
655
+ canUseDOM: canUseDOM,
656
+
657
+ canUseWorkers: typeof Worker !== 'undefined',
658
+
659
+ canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),
660
+
661
+ canUseViewport: canUseDOM && !!window.screen,
662
+
663
+ isInWorker: !canUseDOM // For now, this is true - might change in the future.
664
+
665
+ };
666
+
667
+ module.exports = ExecutionEnvironment;
668
+
669
+ /***/ }),
670
+ /* 9 */
671
+ /***/ (function(module, exports, __webpack_require__) {
672
+
673
+ "use strict";
674
+
675
+
676
+ /**
677
+ * Copyright (c) 2013-present, Facebook, Inc.
678
+ *
679
+ * This source code is licensed under the MIT license found in the
680
+ * LICENSE file in the root directory of this source tree.
681
+ *
682
+ * @typechecks
683
+ */
684
+
685
+ /* eslint-disable fb-www/typeof-undefined */
686
+
687
+ /**
688
+ * Same as document.activeElement but wraps in a try-catch block. In IE it is
689
+ * not safe to call document.activeElement if there is nothing focused.
690
+ *
691
+ * The activeElement will be null only if the document or document body is not
692
+ * yet defined.
693
+ *
694
+ * @param {?DOMDocument} doc Defaults to current document.
695
+ * @return {?DOMElement}
696
+ */
697
+ function getActiveElement(doc) /*?DOMElement*/{
698
+ doc = doc || (typeof document !== 'undefined' ? document : undefined);
699
+ if (typeof doc === 'undefined') {
700
+ return null;
701
+ }
702
+ try {
703
+ return doc.activeElement || doc.body;
704
+ } catch (e) {
705
+ return doc.body;
706
+ }
707
+ }
708
+
709
+ module.exports = getActiveElement;
710
+
711
+ /***/ }),
712
+ /* 10 */
713
+ /***/ (function(module, exports, __webpack_require__) {
714
+
715
+ "use strict";
716
+ /**
717
+ * Copyright (c) 2013-present, Facebook, Inc.
718
+ *
719
+ * This source code is licensed under the MIT license found in the
720
+ * LICENSE file in the root directory of this source tree.
721
+ *
722
+ * @typechecks
723
+ *
724
+ */
725
+
726
+ /*eslint-disable no-self-compare */
727
+
728
+
729
+
730
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
731
+
732
+ /**
733
+ * inlined Object.is polyfill to avoid requiring consumers ship their own
734
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
735
+ */
736
+ function is(x, y) {
737
+ // SameValue algorithm
738
+ if (x === y) {
739
+ // Steps 1-5, 7-10
740
+ // Steps 6.b-6.e: +0 != -0
741
+ // Added the nonzero y check to make Flow happy, but it is redundant
742
+ return x !== 0 || y !== 0 || 1 / x === 1 / y;
743
+ } else {
744
+ // Step 6.a: NaN == NaN
745
+ return x !== x && y !== y;
746
+ }
747
+ }
748
+
749
+ /**
750
+ * Performs equality by iterating through keys on an object and returning false
751
+ * when any key has values which are not strictly equal between the arguments.
752
+ * Returns true when the values of all keys are strictly equal.
753
+ */
754
+ function shallowEqual(objA, objB) {
755
+ if (is(objA, objB)) {
756
+ return true;
757
+ }
758
+
759
+ if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
760
+ return false;
761
+ }
762
+
763
+ var keysA = Object.keys(objA);
764
+ var keysB = Object.keys(objB);
765
+
766
+ if (keysA.length !== keysB.length) {
767
+ return false;
768
+ }
769
+
770
+ // Test for A's keys different from B.
771
+ for (var i = 0; i < keysA.length; i++) {
772
+ if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
773
+ return false;
774
+ }
775
+ }
776
+
777
+ return true;
778
+ }
779
+
780
+ module.exports = shallowEqual;
781
+
782
+ /***/ }),
783
+ /* 11 */
784
+ /***/ (function(module, exports, __webpack_require__) {
785
+
786
+ "use strict";
787
+
788
+
789
+ /**
790
+ * Copyright (c) 2013-present, Facebook, Inc.
791
+ *
792
+ * This source code is licensed under the MIT license found in the
793
+ * LICENSE file in the root directory of this source tree.
794
+ *
795
+ *
796
+ */
797
+
798
+ var isTextNode = __webpack_require__(18);
799
+
800
+ /*eslint-disable no-bitwise */
801
+
802
+ /**
803
+ * Checks if a given DOM node contains or is another DOM node.
804
+ */
805
+ function containsNode(outerNode, innerNode) {
806
+ if (!outerNode || !innerNode) {
807
+ return false;
808
+ } else if (outerNode === innerNode) {
809
+ return true;
810
+ } else if (isTextNode(outerNode)) {
811
+ return false;
812
+ } else if (isTextNode(innerNode)) {
813
+ return containsNode(outerNode, innerNode.parentNode);
814
+ } else if ('contains' in outerNode) {
815
+ return outerNode.contains(innerNode);
816
+ } else if (outerNode.compareDocumentPosition) {
817
+ return !!(outerNode.compareDocumentPosition(innerNode) & 16);
818
+ } else {
819
+ return false;
820
+ }
821
+ }
822
+
823
+ module.exports = containsNode;
824
+
825
+ /***/ }),
826
+ /* 12 */
827
+ /***/ (function(module, exports, __webpack_require__) {
828
+
829
+ "use strict";
830
+
831
+
832
+ var _react = __webpack_require__(1);
833
+
834
+ var _react2 = _interopRequireDefault(_react);
835
+
836
+ var _reactDom = __webpack_require__(16);
837
+
838
+ var _reactDom2 = _interopRequireDefault(_reactDom);
839
+
840
+ var _errorBoundary = __webpack_require__(25);
841
+
842
+ var _errorBoundary2 = _interopRequireDefault(_errorBoundary);
843
+
844
+ var _ui = __webpack_require__(26);
845
+
846
+ var _ui2 = _interopRequireDefault(_ui);
847
+
848
+ __webpack_require__(31);
849
+
850
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
851
+
852
+ _reactDom2.default.render(_react2.default.createElement(
853
+ _errorBoundary2.default,
854
+ null,
855
+ _react2.default.createElement(_ui2.default, null)
856
+ ), document.getElementById('fl-ui-root'));
857
+
858
+ /***/ }),
859
+ /* 13 */
860
+ /***/ (function(module, exports, __webpack_require__) {
861
+
862
+ "use strict";
863
+ /** @license React v16.3.2
864
+ * react.production.min.js
865
+ *
866
+ * Copyright (c) 2013-present, Facebook, Inc.
867
+ *
868
+ * This source code is licensed under the MIT license found in the
869
+ * LICENSE file in the root directory of this source tree.
870
+ */
871
+
872
+ var m=__webpack_require__(4),n=__webpack_require__(2),p=__webpack_require__(5),q=__webpack_require__(3),r="function"===typeof Symbol&&Symbol["for"],t=r?Symbol["for"]("react.element"):60103,u=r?Symbol["for"]("react.portal"):60106,v=r?Symbol["for"]("react.fragment"):60107,w=r?Symbol["for"]("react.strict_mode"):60108,x=r?Symbol["for"]("react.provider"):60109,y=r?Symbol["for"]("react.context"):60110,z=r?Symbol["for"]("react.async_mode"):60111,A=r?Symbol["for"]("react.forward_ref"):
873
+ 60112,B="function"===typeof Symbol&&Symbol.iterator;function C(a){for(var b=arguments.length-1,e="http://reactjs.org/docs/error-decoder.html?invariant\x3d"+a,c=0;c<b;c++)e+="\x26args[]\x3d"+encodeURIComponent(arguments[c+1]);n(!1,"Minified React error #"+a+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",e)}var D={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}};
874
+ function E(a,b,e){this.props=a;this.context=b;this.refs=p;this.updater=e||D}E.prototype.isReactComponent={};E.prototype.setState=function(a,b){"object"!==typeof a&&"function"!==typeof a&&null!=a?C("85"):void 0;this.updater.enqueueSetState(this,a,b,"setState")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=p;this.updater=e||D}var H=G.prototype=new F;
875
+ H.constructor=G;m(H,E.prototype);H.isPureReactComponent=!0;var I={current:null},J=Object.prototype.hasOwnProperty,K={key:!0,ref:!0,__self:!0,__source:!0};
876
+ function L(a,b,e){var c=void 0,d={},g=null,h=null;if(null!=b)for(c in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(g=""+b.key),b)J.call(b,c)&&!K.hasOwnProperty(c)&&(d[c]=b[c]);var f=arguments.length-2;if(1===f)d.children=e;else if(1<f){for(var k=Array(f),l=0;l<f;l++)k[l]=arguments[l+2];d.children=k}if(a&&a.defaultProps)for(c in f=a.defaultProps,f)void 0===d[c]&&(d[c]=f[c]);return{$$typeof:t,type:a,key:g,ref:h,props:d,_owner:I.current}}
877
+ function M(a){return"object"===typeof a&&null!==a&&a.$$typeof===t}function escape(a){var b={"\x3d":"\x3d0",":":"\x3d2"};return"$"+(""+a).replace(/[=:]/g,function(a){return b[a]})}var N=/\/+/g,O=[];function P(a,b,e,c){if(O.length){var d=O.pop();d.result=a;d.keyPrefix=b;d.func=e;d.context=c;d.count=0;return d}return{result:a,keyPrefix:b,func:e,context:c,count:0}}function Q(a){a.result=null;a.keyPrefix=null;a.func=null;a.context=null;a.count=0;10>O.length&&O.push(a)}
878
+ function R(a,b,e,c){var d=typeof a;if("undefined"===d||"boolean"===d)a=null;var g=!1;if(null===a)g=!0;else switch(d){case "string":case "number":g=!0;break;case "object":switch(a.$$typeof){case t:case u:g=!0}}if(g)return e(c,a,""===b?"."+S(a,0):b),1;g=0;b=""===b?".":b+":";if(Array.isArray(a))for(var h=0;h<a.length;h++){d=a[h];var f=b+S(d,h);g+=R(d,f,e,c)}else if(null===a||"undefined"===typeof a?f=null:(f=B&&a[B]||a["@@iterator"],f="function"===typeof f?f:null),"function"===typeof f)for(a=f.call(a),
879
+ h=0;!(d=a.next()).done;)d=d.value,f=b+S(d,h++),g+=R(d,f,e,c);else"object"===d&&(e=""+a,C("31","[object Object]"===e?"object with keys {"+Object.keys(a).join(", ")+"}":e,""));return g}function S(a,b){return"object"===typeof a&&null!==a&&null!=a.key?escape(a.key):b.toString(36)}function T(a,b){a.func.call(a.context,b,a.count++)}
880
+ function U(a,b,e){var c=a.result,d=a.keyPrefix;a=a.func.call(a.context,b,a.count++);Array.isArray(a)?V(a,c,e,q.thatReturnsArgument):null!=a&&(M(a)&&(b=d+(!a.key||b&&b.key===a.key?"":(""+a.key).replace(N,"$\x26/")+"/")+e,a={$$typeof:t,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}),c.push(a))}function V(a,b,e,c,d){var g="";null!=e&&(g=(""+e).replace(N,"$\x26/")+"/");b=P(b,g,c,d);null==a||R(a,"",U,b);Q(b)}
881
+ var W={Children:{map:function(a,b,e){if(null==a)return a;var c=[];V(a,c,null,b,e);return c},forEach:function(a,b,e){if(null==a)return a;b=P(null,null,b,e);null==a||R(a,"",T,b);Q(b)},count:function(a){return null==a?0:R(a,"",q.thatReturnsNull,null)},toArray:function(a){var b=[];V(a,b,null,q.thatReturnsArgument);return b},only:function(a){M(a)?void 0:C("143");return a}},createRef:function(){return{current:null}},Component:E,PureComponent:G,createContext:function(a,b){void 0===b&&(b=null);a={$$typeof:y,
882
+ _calculateChangedBits:b,_defaultValue:a,_currentValue:a,_changedBits:0,Provider:null,Consumer:null};a.Provider={$$typeof:x,_context:a};return a.Consumer=a},forwardRef:function(a){return{$$typeof:A,render:a}},Fragment:v,StrictMode:w,unstable_AsyncMode:z,createElement:L,cloneElement:function(a,b,e){null===a||void 0===a?C("267",a):void 0;var c=void 0,d=m({},a.props),g=a.key,h=a.ref,f=a._owner;if(null!=b){void 0!==b.ref&&(h=b.ref,f=I.current);void 0!==b.key&&(g=""+b.key);var k=void 0;a.type&&a.type.defaultProps&&
883
+ (k=a.type.defaultProps);for(c in b)J.call(b,c)&&!K.hasOwnProperty(c)&&(d[c]=void 0===b[c]&&void 0!==k?k[c]:b[c])}c=arguments.length-2;if(1===c)d.children=e;else if(1<c){k=Array(c);for(var l=0;l<c;l++)k[l]=arguments[l+2];d.children=k}return{$$typeof:t,type:a.type,key:g,ref:h,props:d,_owner:f}},createFactory:function(a){var b=L.bind(null,a);b.type=a;return b},isValidElement:M,version:"16.3.2",__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{ReactCurrentOwner:I,assign:m}},X=Object.freeze({default:W}),
884
+ Y=X&&W||X;module.exports=Y["default"]?Y["default"]:Y;
885
+
886
+
887
+ /***/ }),
888
+ /* 14 */
889
+ /***/ (function(module, exports, __webpack_require__) {
890
+
891
+ "use strict";
892
+ /* WEBPACK VAR INJECTION */(function(process) {/** @license React v16.3.2
893
+ * react.development.js
894
+ *
895
+ * Copyright (c) 2013-present, Facebook, Inc.
896
+ *
897
+ * This source code is licensed under the MIT license found in the
898
+ * LICENSE file in the root directory of this source tree.
899
+ */
900
+
901
+
902
+
903
+
904
+
905
+ if (process.env.NODE_ENV !== "production") {
906
+ (function() {
907
+ 'use strict';
908
+
909
+ var _assign = __webpack_require__(4);
910
+ var invariant = __webpack_require__(2);
911
+ var emptyObject = __webpack_require__(5);
912
+ var warning = __webpack_require__(6);
913
+ var emptyFunction = __webpack_require__(3);
914
+ var checkPropTypes = __webpack_require__(7);
915
+
916
+ // TODO: this is special because it gets imported during build.
917
+
918
+ var ReactVersion = '16.3.2';
919
+
920
+ // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
921
+ // nor polyfill, then a plain number is used for performance.
922
+ var hasSymbol = typeof Symbol === 'function' && Symbol['for'];
923
+
924
+ var REACT_ELEMENT_TYPE = hasSymbol ? Symbol['for']('react.element') : 0xeac7;
925
+ var REACT_CALL_TYPE = hasSymbol ? Symbol['for']('react.call') : 0xeac8;
926
+ var REACT_RETURN_TYPE = hasSymbol ? Symbol['for']('react.return') : 0xeac9;
927
+ var REACT_PORTAL_TYPE = hasSymbol ? Symbol['for']('react.portal') : 0xeaca;
928
+ var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol['for']('react.fragment') : 0xeacb;
929
+ var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol['for']('react.strict_mode') : 0xeacc;
930
+ var REACT_PROVIDER_TYPE = hasSymbol ? Symbol['for']('react.provider') : 0xeacd;
931
+ var REACT_CONTEXT_TYPE = hasSymbol ? Symbol['for']('react.context') : 0xeace;
932
+ var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol['for']('react.async_mode') : 0xeacf;
933
+ var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol['for']('react.forward_ref') : 0xead0;
934
+
935
+ var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
936
+ var FAUX_ITERATOR_SYMBOL = '@@iterator';
937
+
938
+ function getIteratorFn(maybeIterable) {
939
+ if (maybeIterable === null || typeof maybeIterable === 'undefined') {
940
+ return null;
941
+ }
942
+ var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
943
+ if (typeof maybeIterator === 'function') {
944
+ return maybeIterator;
945
+ }
946
+ return null;
947
+ }
948
+
949
+ // Relying on the `invariant()` implementation lets us
950
+ // have preserve the format and params in the www builds.
951
+
952
+ /**
953
+ * Forked from fbjs/warning:
954
+ * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
955
+ *
956
+ * Only change is we use console.warn instead of console.error,
957
+ * and do nothing when 'console' is not supported.
958
+ * This really simplifies the code.
959
+ * ---
960
+ * Similar to invariant but only logs a warning if the condition is not met.
961
+ * This can be used to log issues in development environments in critical
962
+ * paths. Removing the logging code for production environments will keep the
963
+ * same logic and follow the same code paths.
964
+ */
965
+
966
+ var lowPriorityWarning = function () {};
967
+
968
+ {
969
+ var printWarning = function (format) {
970
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
971
+ args[_key - 1] = arguments[_key];
972
+ }
973
+
974
+ var argIndex = 0;
975
+ var message = 'Warning: ' + format.replace(/%s/g, function () {
976
+ return args[argIndex++];
977
+ });
978
+ if (typeof console !== 'undefined') {
979
+ console.warn(message);
980
+ }
981
+ try {
982
+ // --- Welcome to debugging React ---
983
+ // This error was thrown as a convenience so that you can use this stack
984
+ // to find the callsite that caused this warning to fire.
985
+ throw new Error(message);
986
+ } catch (x) {}
987
+ };
988
+
989
+ lowPriorityWarning = function (condition, format) {
990
+ if (format === undefined) {
991
+ throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
992
+ }
993
+ if (!condition) {
994
+ for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
995
+ args[_key2 - 2] = arguments[_key2];
996
+ }
997
+
998
+ printWarning.apply(undefined, [format].concat(args));
999
+ }
1000
+ };
1001
+ }
1002
+
1003
+ var lowPriorityWarning$1 = lowPriorityWarning;
1004
+
1005
+ var didWarnStateUpdateForUnmountedComponent = {};
1006
+
1007
+ function warnNoop(publicInstance, callerName) {
1008
+ {
1009
+ var _constructor = publicInstance.constructor;
1010
+ var componentName = _constructor && (_constructor.displayName || _constructor.name) || 'ReactClass';
1011
+ var warningKey = componentName + '.' + callerName;
1012
+ if (didWarnStateUpdateForUnmountedComponent[warningKey]) {
1013
+ return;
1014
+ }
1015
+ warning(false, "Can't call %s on a component that is not yet mounted. " + 'This is a no-op, but it might indicate a bug in your application. ' + 'Instead, assign to `this.state` directly or define a `state = {};` ' + 'class property with the desired state in the %s component.', callerName, componentName);
1016
+ didWarnStateUpdateForUnmountedComponent[warningKey] = true;
1017
+ }
1018
+ }
1019
+
1020
+ /**
1021
+ * This is the abstract API for an update queue.
1022
+ */
1023
+ var ReactNoopUpdateQueue = {
1024
+ /**
1025
+ * Checks whether or not this composite component is mounted.
1026
+ * @param {ReactClass} publicInstance The instance we want to test.
1027
+ * @return {boolean} True if mounted, false otherwise.
1028
+ * @protected
1029
+ * @final
1030
+ */
1031
+ isMounted: function (publicInstance) {
1032
+ return false;
1033
+ },
1034
+
1035
+ /**
1036
+ * Forces an update. This should only be invoked when it is known with
1037
+ * certainty that we are **not** in a DOM transaction.
1038
+ *
1039
+ * You may want to call this when you know that some deeper aspect of the
1040
+ * component's state has changed but `setState` was not called.
1041
+ *
1042
+ * This will not invoke `shouldComponentUpdate`, but it will invoke
1043
+ * `componentWillUpdate` and `componentDidUpdate`.
1044
+ *
1045
+ * @param {ReactClass} publicInstance The instance that should rerender.
1046
+ * @param {?function} callback Called after component is updated.
1047
+ * @param {?string} callerName name of the calling function in the public API.
1048
+ * @internal
1049
+ */
1050
+ enqueueForceUpdate: function (publicInstance, callback, callerName) {
1051
+ warnNoop(publicInstance, 'forceUpdate');
1052
+ },
1053
+
1054
+ /**
1055
+ * Replaces all of the state. Always use this or `setState` to mutate state.
1056
+ * You should treat `this.state` as immutable.
1057
+ *
1058
+ * There is no guarantee that `this.state` will be immediately updated, so
1059
+ * accessing `this.state` after calling this method may return the old value.
1060
+ *
1061
+ * @param {ReactClass} publicInstance The instance that should rerender.
1062
+ * @param {object} completeState Next state.
1063
+ * @param {?function} callback Called after component is updated.
1064
+ * @param {?string} callerName name of the calling function in the public API.
1065
+ * @internal
1066
+ */
1067
+ enqueueReplaceState: function (publicInstance, completeState, callback, callerName) {
1068
+ warnNoop(publicInstance, 'replaceState');
1069
+ },
1070
+
1071
+ /**
1072
+ * Sets a subset of the state. This only exists because _pendingState is
1073
+ * internal. This provides a merging strategy that is not available to deep
1074
+ * properties which is confusing. TODO: Expose pendingState or don't use it
1075
+ * during the merge.
1076
+ *
1077
+ * @param {ReactClass} publicInstance The instance that should rerender.
1078
+ * @param {object} partialState Next partial state to be merged with state.
1079
+ * @param {?function} callback Called after component is updated.
1080
+ * @param {?string} Name of the calling function in the public API.
1081
+ * @internal
1082
+ */
1083
+ enqueueSetState: function (publicInstance, partialState, callback, callerName) {
1084
+ warnNoop(publicInstance, 'setState');
1085
+ }
1086
+ };
1087
+
1088
+ /**
1089
+ * Base class helpers for the updating state of a component.
1090
+ */
1091
+ function Component(props, context, updater) {
1092
+ this.props = props;
1093
+ this.context = context;
1094
+ this.refs = emptyObject;
1095
+ // We initialize the default updater but the real one gets injected by the
1096
+ // renderer.
1097
+ this.updater = updater || ReactNoopUpdateQueue;
1098
+ }
1099
+
1100
+ Component.prototype.isReactComponent = {};
1101
+
1102
+ /**
1103
+ * Sets a subset of the state. Always use this to mutate
1104
+ * state. You should treat `this.state` as immutable.
1105
+ *
1106
+ * There is no guarantee that `this.state` will be immediately updated, so
1107
+ * accessing `this.state` after calling this method may return the old value.
1108
+ *
1109
+ * There is no guarantee that calls to `setState` will run synchronously,
1110
+ * as they may eventually be batched together. You can provide an optional
1111
+ * callback that will be executed when the call to setState is actually
1112
+ * completed.
1113
+ *
1114
+ * When a function is provided to setState, it will be called at some point in
1115
+ * the future (not synchronously). It will be called with the up to date
1116
+ * component arguments (state, props, context). These values can be different
1117
+ * from this.* because your function may be called after receiveProps but before
1118
+ * shouldComponentUpdate, and this new state, props, and context will not yet be
1119
+ * assigned to this.
1120
+ *
1121
+ * @param {object|function} partialState Next partial state or function to
1122
+ * produce next partial state to be merged with current state.
1123
+ * @param {?function} callback Called after state is updated.
1124
+ * @final
1125
+ * @protected
1126
+ */
1127
+ Component.prototype.setState = function (partialState, callback) {
1128
+ !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : void 0;
1129
+ this.updater.enqueueSetState(this, partialState, callback, 'setState');
1130
+ };
1131
+
1132
+ /**
1133
+ * Forces an update. This should only be invoked when it is known with
1134
+ * certainty that we are **not** in a DOM transaction.
1135
+ *
1136
+ * You may want to call this when you know that some deeper aspect of the
1137
+ * component's state has changed but `setState` was not called.
1138
+ *
1139
+ * This will not invoke `shouldComponentUpdate`, but it will invoke
1140
+ * `componentWillUpdate` and `componentDidUpdate`.
1141
+ *
1142
+ * @param {?function} callback Called after update is complete.
1143
+ * @final
1144
+ * @protected
1145
+ */
1146
+ Component.prototype.forceUpdate = function (callback) {
1147
+ this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
1148
+ };
1149
+
1150
+ /**
1151
+ * Deprecated APIs. These APIs used to exist on classic React classes but since
1152
+ * we would like to deprecate them, we're not going to move them over to this
1153
+ * modern base class. Instead, we define a getter that warns if it's accessed.
1154
+ */
1155
+ {
1156
+ var deprecatedAPIs = {
1157
+ isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'],
1158
+ replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).']
1159
+ };
1160
+ var defineDeprecationWarning = function (methodName, info) {
1161
+ Object.defineProperty(Component.prototype, methodName, {
1162
+ get: function () {
1163
+ lowPriorityWarning$1(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]);
1164
+ return undefined;
1165
+ }
1166
+ });
1167
+ };
1168
+ for (var fnName in deprecatedAPIs) {
1169
+ if (deprecatedAPIs.hasOwnProperty(fnName)) {
1170
+ defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
1171
+ }
1172
+ }
1173
+ }
1174
+
1175
+ function ComponentDummy() {}
1176
+ ComponentDummy.prototype = Component.prototype;
1177
+
1178
+ /**
1179
+ * Convenience component with default shallow equality check for sCU.
1180
+ */
1181
+ function PureComponent(props, context, updater) {
1182
+ this.props = props;
1183
+ this.context = context;
1184
+ this.refs = emptyObject;
1185
+ this.updater = updater || ReactNoopUpdateQueue;
1186
+ }
1187
+
1188
+ var pureComponentPrototype = PureComponent.prototype = new ComponentDummy();
1189
+ pureComponentPrototype.constructor = PureComponent;
1190
+ // Avoid an extra prototype jump for these methods.
1191
+ _assign(pureComponentPrototype, Component.prototype);
1192
+ pureComponentPrototype.isPureReactComponent = true;
1193
+
1194
+ // an immutable object with a single mutable value
1195
+ function createRef() {
1196
+ var refObject = {
1197
+ current: null
1198
+ };
1199
+ {
1200
+ Object.seal(refObject);
1201
+ }
1202
+ return refObject;
1203
+ }
1204
+
1205
+ /**
1206
+ * Keeps track of the current owner.
1207
+ *
1208
+ * The current owner is the component who should own any components that are
1209
+ * currently being constructed.
1210
+ */
1211
+ var ReactCurrentOwner = {
1212
+ /**
1213
+ * @internal
1214
+ * @type {ReactComponent}
1215
+ */
1216
+ current: null
1217
+ };
1218
+
1219
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
1220
+
1221
+ var RESERVED_PROPS = {
1222
+ key: true,
1223
+ ref: true,
1224
+ __self: true,
1225
+ __source: true
1226
+ };
1227
+
1228
+ var specialPropKeyWarningShown = void 0;
1229
+ var specialPropRefWarningShown = void 0;
1230
+
1231
+ function hasValidRef(config) {
1232
+ {
1233
+ if (hasOwnProperty.call(config, 'ref')) {
1234
+ var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
1235
+ if (getter && getter.isReactWarning) {
1236
+ return false;
1237
+ }
1238
+ }
1239
+ }
1240
+ return config.ref !== undefined;
1241
+ }
1242
+
1243
+ function hasValidKey(config) {
1244
+ {
1245
+ if (hasOwnProperty.call(config, 'key')) {
1246
+ var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
1247
+ if (getter && getter.isReactWarning) {
1248
+ return false;
1249
+ }
1250
+ }
1251
+ }
1252
+ return config.key !== undefined;
1253
+ }
1254
+
1255
+ function defineKeyPropWarningGetter(props, displayName) {
1256
+ var warnAboutAccessingKey = function () {
1257
+ if (!specialPropKeyWarningShown) {
1258
+ specialPropKeyWarningShown = true;
1259
+ warning(false, '%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName);
1260
+ }
1261
+ };
1262
+ warnAboutAccessingKey.isReactWarning = true;
1263
+ Object.defineProperty(props, 'key', {
1264
+ get: warnAboutAccessingKey,
1265
+ configurable: true
1266
+ });
1267
+ }
1268
+
1269
+ function defineRefPropWarningGetter(props, displayName) {
1270
+ var warnAboutAccessingRef = function () {
1271
+ if (!specialPropRefWarningShown) {
1272
+ specialPropRefWarningShown = true;
1273
+ warning(false, '%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName);
1274
+ }
1275
+ };
1276
+ warnAboutAccessingRef.isReactWarning = true;
1277
+ Object.defineProperty(props, 'ref', {
1278
+ get: warnAboutAccessingRef,
1279
+ configurable: true
1280
+ });
1281
+ }
1282
+
1283
+ /**
1284
+ * Factory method to create a new React element. This no longer adheres to
1285
+ * the class pattern, so do not use new to call it. Also, no instanceof check
1286
+ * will work. Instead test $$typeof field against Symbol.for('react.element') to check
1287
+ * if something is a React Element.
1288
+ *
1289
+ * @param {*} type
1290
+ * @param {*} key
1291
+ * @param {string|object} ref
1292
+ * @param {*} self A *temporary* helper to detect places where `this` is
1293
+ * different from the `owner` when React.createElement is called, so that we
1294
+ * can warn. We want to get rid of owner and replace string `ref`s with arrow
1295
+ * functions, and as long as `this` and owner are the same, there will be no
1296
+ * change in behavior.
1297
+ * @param {*} source An annotation object (added by a transpiler or otherwise)
1298
+ * indicating filename, line number, and/or other information.
1299
+ * @param {*} owner
1300
+ * @param {*} props
1301
+ * @internal
1302
+ */
1303
+ var ReactElement = function (type, key, ref, self, source, owner, props) {
1304
+ var element = {
1305
+ // This tag allows us to uniquely identify this as a React Element
1306
+ $$typeof: REACT_ELEMENT_TYPE,
1307
+
1308
+ // Built-in properties that belong on the element
1309
+ type: type,
1310
+ key: key,
1311
+ ref: ref,
1312
+ props: props,
1313
+
1314
+ // Record the component responsible for creating this element.
1315
+ _owner: owner
1316
+ };
1317
+
1318
+ {
1319
+ // The validation flag is currently mutative. We put it on
1320
+ // an external backing store so that we can freeze the whole object.
1321
+ // This can be replaced with a WeakMap once they are implemented in
1322
+ // commonly used development environments.
1323
+ element._store = {};
1324
+
1325
+ // To make comparing ReactElements easier for testing purposes, we make
1326
+ // the validation flag non-enumerable (where possible, which should
1327
+ // include every environment we run tests in), so the test framework
1328
+ // ignores it.
1329
+ Object.defineProperty(element._store, 'validated', {
1330
+ configurable: false,
1331
+ enumerable: false,
1332
+ writable: true,
1333
+ value: false
1334
+ });
1335
+ // self and source are DEV only properties.
1336
+ Object.defineProperty(element, '_self', {
1337
+ configurable: false,
1338
+ enumerable: false,
1339
+ writable: false,
1340
+ value: self
1341
+ });
1342
+ // Two elements created in two different places should be considered
1343
+ // equal for testing purposes and therefore we hide it from enumeration.
1344
+ Object.defineProperty(element, '_source', {
1345
+ configurable: false,
1346
+ enumerable: false,
1347
+ writable: false,
1348
+ value: source
1349
+ });
1350
+ if (Object.freeze) {
1351
+ Object.freeze(element.props);
1352
+ Object.freeze(element);
1353
+ }
1354
+ }
1355
+
1356
+ return element;
1357
+ };
1358
+
1359
+ /**
1360
+ * Create and return a new ReactElement of the given type.
1361
+ * See https://reactjs.org/docs/react-api.html#createelement
1362
+ */
1363
+ function createElement(type, config, children) {
1364
+ var propName = void 0;
1365
+
1366
+ // Reserved names are extracted
1367
+ var props = {};
1368
+
1369
+ var key = null;
1370
+ var ref = null;
1371
+ var self = null;
1372
+ var source = null;
1373
+
1374
+ if (config != null) {
1375
+ if (hasValidRef(config)) {
1376
+ ref = config.ref;
1377
+ }
1378
+ if (hasValidKey(config)) {
1379
+ key = '' + config.key;
1380
+ }
1381
+
1382
+ self = config.__self === undefined ? null : config.__self;
1383
+ source = config.__source === undefined ? null : config.__source;
1384
+ // Remaining properties are added to a new props object
1385
+ for (propName in config) {
1386
+ if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
1387
+ props[propName] = config[propName];
1388
+ }
1389
+ }
1390
+ }
1391
+
1392
+ // Children can be more than one argument, and those are transferred onto
1393
+ // the newly allocated props object.
1394
+ var childrenLength = arguments.length - 2;
1395
+ if (childrenLength === 1) {
1396
+ props.children = children;
1397
+ } else if (childrenLength > 1) {
1398
+ var childArray = Array(childrenLength);
1399
+ for (var i = 0; i < childrenLength; i++) {
1400
+ childArray[i] = arguments[i + 2];
1401
+ }
1402
+ {
1403
+ if (Object.freeze) {
1404
+ Object.freeze(childArray);
1405
+ }
1406
+ }
1407
+ props.children = childArray;
1408
+ }
1409
+
1410
+ // Resolve default props
1411
+ if (type && type.defaultProps) {
1412
+ var defaultProps = type.defaultProps;
1413
+ for (propName in defaultProps) {
1414
+ if (props[propName] === undefined) {
1415
+ props[propName] = defaultProps[propName];
1416
+ }
1417
+ }
1418
+ }
1419
+ {
1420
+ if (key || ref) {
1421
+ if (typeof props.$$typeof === 'undefined' || props.$$typeof !== REACT_ELEMENT_TYPE) {
1422
+ var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
1423
+ if (key) {
1424
+ defineKeyPropWarningGetter(props, displayName);
1425
+ }
1426
+ if (ref) {
1427
+ defineRefPropWarningGetter(props, displayName);
1428
+ }
1429
+ }
1430
+ }
1431
+ }
1432
+ return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
1433
+ }
1434
+
1435
+ /**
1436
+ * Return a function that produces ReactElements of a given type.
1437
+ * See https://reactjs.org/docs/react-api.html#createfactory
1438
+ */
1439
+
1440
+
1441
+ function cloneAndReplaceKey(oldElement, newKey) {
1442
+ var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);
1443
+
1444
+ return newElement;
1445
+ }
1446
+
1447
+ /**
1448
+ * Clone and return a new ReactElement using element as the starting point.
1449
+ * See https://reactjs.org/docs/react-api.html#cloneelement
1450
+ */
1451
+ function cloneElement(element, config, children) {
1452
+ !!(element === null || element === undefined) ? invariant(false, 'React.cloneElement(...): The argument must be a React element, but you passed %s.', element) : void 0;
1453
+
1454
+ var propName = void 0;
1455
+
1456
+ // Original props are copied
1457
+ var props = _assign({}, element.props);
1458
+
1459
+ // Reserved names are extracted
1460
+ var key = element.key;
1461
+ var ref = element.ref;
1462
+ // Self is preserved since the owner is preserved.
1463
+ var self = element._self;
1464
+ // Source is preserved since cloneElement is unlikely to be targeted by a
1465
+ // transpiler, and the original source is probably a better indicator of the
1466
+ // true owner.
1467
+ var source = element._source;
1468
+
1469
+ // Owner will be preserved, unless ref is overridden
1470
+ var owner = element._owner;
1471
+
1472
+ if (config != null) {
1473
+ if (hasValidRef(config)) {
1474
+ // Silently steal the ref from the parent.
1475
+ ref = config.ref;
1476
+ owner = ReactCurrentOwner.current;
1477
+ }
1478
+ if (hasValidKey(config)) {
1479
+ key = '' + config.key;
1480
+ }
1481
+
1482
+ // Remaining properties override existing props
1483
+ var defaultProps = void 0;
1484
+ if (element.type && element.type.defaultProps) {
1485
+ defaultProps = element.type.defaultProps;
1486
+ }
1487
+ for (propName in config) {
1488
+ if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
1489
+ if (config[propName] === undefined && defaultProps !== undefined) {
1490
+ // Resolve default props
1491
+ props[propName] = defaultProps[propName];
1492
+ } else {
1493
+ props[propName] = config[propName];
1494
+ }
1495
+ }
1496
+ }
1497
+ }
1498
+
1499
+ // Children can be more than one argument, and those are transferred onto
1500
+ // the newly allocated props object.
1501
+ var childrenLength = arguments.length - 2;
1502
+ if (childrenLength === 1) {
1503
+ props.children = children;
1504
+ } else if (childrenLength > 1) {
1505
+ var childArray = Array(childrenLength);
1506
+ for (var i = 0; i < childrenLength; i++) {
1507
+ childArray[i] = arguments[i + 2];
1508
+ }
1509
+ props.children = childArray;
1510
+ }
1511
+
1512
+ return ReactElement(element.type, key, ref, self, source, owner, props);
1513
+ }
1514
+
1515
+ /**
1516
+ * Verifies the object is a ReactElement.
1517
+ * See https://reactjs.org/docs/react-api.html#isvalidelement
1518
+ * @param {?object} object
1519
+ * @return {boolean} True if `object` is a valid component.
1520
+ * @final
1521
+ */
1522
+ function isValidElement(object) {
1523
+ return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
1524
+ }
1525
+
1526
+ var ReactDebugCurrentFrame = {};
1527
+
1528
+ {
1529
+ // Component that is being worked on
1530
+ ReactDebugCurrentFrame.getCurrentStack = null;
1531
+
1532
+ ReactDebugCurrentFrame.getStackAddendum = function () {
1533
+ var impl = ReactDebugCurrentFrame.getCurrentStack;
1534
+ if (impl) {
1535
+ return impl();
1536
+ }
1537
+ return null;
1538
+ };
1539
+ }
1540
+
1541
+ var SEPARATOR = '.';
1542
+ var SUBSEPARATOR = ':';
1543
+
1544
+ /**
1545
+ * Escape and wrap key so it is safe to use as a reactid
1546
+ *
1547
+ * @param {string} key to be escaped.
1548
+ * @return {string} the escaped key.
1549
+ */
1550
+ function escape(key) {
1551
+ var escapeRegex = /[=:]/g;
1552
+ var escaperLookup = {
1553
+ '=': '=0',
1554
+ ':': '=2'
1555
+ };
1556
+ var escapedString = ('' + key).replace(escapeRegex, function (match) {
1557
+ return escaperLookup[match];
1558
+ });
1559
+
1560
+ return '$' + escapedString;
1561
+ }
1562
+
1563
+ /**
1564
+ * TODO: Test that a single child and an array with one item have the same key
1565
+ * pattern.
1566
+ */
1567
+
1568
+ var didWarnAboutMaps = false;
1569
+
1570
+ var userProvidedKeyEscapeRegex = /\/+/g;
1571
+ function escapeUserProvidedKey(text) {
1572
+ return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/');
1573
+ }
1574
+
1575
+ var POOL_SIZE = 10;
1576
+ var traverseContextPool = [];
1577
+ function getPooledTraverseContext(mapResult, keyPrefix, mapFunction, mapContext) {
1578
+ if (traverseContextPool.length) {
1579
+ var traverseContext = traverseContextPool.pop();
1580
+ traverseContext.result = mapResult;
1581
+ traverseContext.keyPrefix = keyPrefix;
1582
+ traverseContext.func = mapFunction;
1583
+ traverseContext.context = mapContext;
1584
+ traverseContext.count = 0;
1585
+ return traverseContext;
1586
+ } else {
1587
+ return {
1588
+ result: mapResult,
1589
+ keyPrefix: keyPrefix,
1590
+ func: mapFunction,
1591
+ context: mapContext,
1592
+ count: 0
1593
+ };
1594
+ }
1595
+ }
1596
+
1597
+ function releaseTraverseContext(traverseContext) {
1598
+ traverseContext.result = null;
1599
+ traverseContext.keyPrefix = null;
1600
+ traverseContext.func = null;
1601
+ traverseContext.context = null;
1602
+ traverseContext.count = 0;
1603
+ if (traverseContextPool.length < POOL_SIZE) {
1604
+ traverseContextPool.push(traverseContext);
1605
+ }
1606
+ }
1607
+
1608
+ /**
1609
+ * @param {?*} children Children tree container.
1610
+ * @param {!string} nameSoFar Name of the key path so far.
1611
+ * @param {!function} callback Callback to invoke with each child found.
1612
+ * @param {?*} traverseContext Used to pass information throughout the traversal
1613
+ * process.
1614
+ * @return {!number} The number of children in this subtree.
1615
+ */
1616
+ function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {
1617
+ var type = typeof children;
1618
+
1619
+ if (type === 'undefined' || type === 'boolean') {
1620
+ // All of the above are perceived as null.
1621
+ children = null;
1622
+ }
1623
+
1624
+ var invokeCallback = false;
1625
+
1626
+ if (children === null) {
1627
+ invokeCallback = true;
1628
+ } else {
1629
+ switch (type) {
1630
+ case 'string':
1631
+ case 'number':
1632
+ invokeCallback = true;
1633
+ break;
1634
+ case 'object':
1635
+ switch (children.$$typeof) {
1636
+ case REACT_ELEMENT_TYPE:
1637
+ case REACT_PORTAL_TYPE:
1638
+ invokeCallback = true;
1639
+ }
1640
+ }
1641
+ }
1642
+
1643
+ if (invokeCallback) {
1644
+ callback(traverseContext, children,
1645
+ // If it's the only child, treat the name as if it was wrapped in an array
1646
+ // so that it's consistent if the number of children grows.
1647
+ nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);
1648
+ return 1;
1649
+ }
1650
+
1651
+ var child = void 0;
1652
+ var nextName = void 0;
1653
+ var subtreeCount = 0; // Count of children found in the current subtree.
1654
+ var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;
1655
+
1656
+ if (Array.isArray(children)) {
1657
+ for (var i = 0; i < children.length; i++) {
1658
+ child = children[i];
1659
+ nextName = nextNamePrefix + getComponentKey(child, i);
1660
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
1661
+ }
1662
+ } else {
1663
+ var iteratorFn = getIteratorFn(children);
1664
+ if (typeof iteratorFn === 'function') {
1665
+ {
1666
+ // Warn about using Maps as children
1667
+ if (iteratorFn === children.entries) {
1668
+ !didWarnAboutMaps ? warning(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.%s', ReactDebugCurrentFrame.getStackAddendum()) : void 0;
1669
+ didWarnAboutMaps = true;
1670
+ }
1671
+ }
1672
+
1673
+ var iterator = iteratorFn.call(children);
1674
+ var step = void 0;
1675
+ var ii = 0;
1676
+ while (!(step = iterator.next()).done) {
1677
+ child = step.value;
1678
+ nextName = nextNamePrefix + getComponentKey(child, ii++);
1679
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
1680
+ }
1681
+ } else if (type === 'object') {
1682
+ var addendum = '';
1683
+ {
1684
+ addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + ReactDebugCurrentFrame.getStackAddendum();
1685
+ }
1686
+ var childrenString = '' + children;
1687
+ invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum);
1688
+ }
1689
+ }
1690
+
1691
+ return subtreeCount;
1692
+ }
1693
+
1694
+ /**
1695
+ * Traverses children that are typically specified as `props.children`, but
1696
+ * might also be specified through attributes:
1697
+ *
1698
+ * - `traverseAllChildren(this.props.children, ...)`
1699
+ * - `traverseAllChildren(this.props.leftPanelChildren, ...)`
1700
+ *
1701
+ * The `traverseContext` is an optional argument that is passed through the
1702
+ * entire traversal. It can be used to store accumulations or anything else that
1703
+ * the callback might find relevant.
1704
+ *
1705
+ * @param {?*} children Children tree object.
1706
+ * @param {!function} callback To invoke upon traversing each child.
1707
+ * @param {?*} traverseContext Context for traversal.
1708
+ * @return {!number} The number of children in this subtree.
1709
+ */
1710
+ function traverseAllChildren(children, callback, traverseContext) {
1711
+ if (children == null) {
1712
+ return 0;
1713
+ }
1714
+
1715
+ return traverseAllChildrenImpl(children, '', callback, traverseContext);
1716
+ }
1717
+
1718
+ /**
1719
+ * Generate a key string that identifies a component within a set.
1720
+ *
1721
+ * @param {*} component A component that could contain a manual key.
1722
+ * @param {number} index Index that is used if a manual key is not provided.
1723
+ * @return {string}
1724
+ */
1725
+ function getComponentKey(component, index) {
1726
+ // Do some typechecking here since we call this blindly. We want to ensure
1727
+ // that we don't block potential future ES APIs.
1728
+ if (typeof component === 'object' && component !== null && component.key != null) {
1729
+ // Explicit key
1730
+ return escape(component.key);
1731
+ }
1732
+ // Implicit key determined by the index in the set
1733
+ return index.toString(36);
1734
+ }
1735
+
1736
+ function forEachSingleChild(bookKeeping, child, name) {
1737
+ var func = bookKeeping.func,
1738
+ context = bookKeeping.context;
1739
+
1740
+ func.call(context, child, bookKeeping.count++);
1741
+ }
1742
+
1743
+ /**
1744
+ * Iterates through children that are typically specified as `props.children`.
1745
+ *
1746
+ * See https://reactjs.org/docs/react-api.html#react.children.foreach
1747
+ *
1748
+ * The provided forEachFunc(child, index) will be called for each
1749
+ * leaf child.
1750
+ *
1751
+ * @param {?*} children Children tree container.
1752
+ * @param {function(*, int)} forEachFunc
1753
+ * @param {*} forEachContext Context for forEachContext.
1754
+ */
1755
+ function forEachChildren(children, forEachFunc, forEachContext) {
1756
+ if (children == null) {
1757
+ return children;
1758
+ }
1759
+ var traverseContext = getPooledTraverseContext(null, null, forEachFunc, forEachContext);
1760
+ traverseAllChildren(children, forEachSingleChild, traverseContext);
1761
+ releaseTraverseContext(traverseContext);
1762
+ }
1763
+
1764
+ function mapSingleChildIntoContext(bookKeeping, child, childKey) {
1765
+ var result = bookKeeping.result,
1766
+ keyPrefix = bookKeeping.keyPrefix,
1767
+ func = bookKeeping.func,
1768
+ context = bookKeeping.context;
1769
+
1770
+
1771
+ var mappedChild = func.call(context, child, bookKeeping.count++);
1772
+ if (Array.isArray(mappedChild)) {
1773
+ mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument);
1774
+ } else if (mappedChild != null) {
1775
+ if (isValidElement(mappedChild)) {
1776
+ mappedChild = cloneAndReplaceKey(mappedChild,
1777
+ // Keep both the (mapped) and old keys if they differ, just as
1778
+ // traverseAllChildren used to do for objects as children
1779
+ keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey);
1780
+ }
1781
+ result.push(mappedChild);
1782
+ }
1783
+ }
1784
+
1785
+ function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {
1786
+ var escapedPrefix = '';
1787
+ if (prefix != null) {
1788
+ escapedPrefix = escapeUserProvidedKey(prefix) + '/';
1789
+ }
1790
+ var traverseContext = getPooledTraverseContext(array, escapedPrefix, func, context);
1791
+ traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
1792
+ releaseTraverseContext(traverseContext);
1793
+ }
1794
+
1795
+ /**
1796
+ * Maps children that are typically specified as `props.children`.
1797
+ *
1798
+ * See https://reactjs.org/docs/react-api.html#react.children.map
1799
+ *
1800
+ * The provided mapFunction(child, key, index) will be called for each
1801
+ * leaf child.
1802
+ *
1803
+ * @param {?*} children Children tree container.
1804
+ * @param {function(*, int)} func The map function.
1805
+ * @param {*} context Context for mapFunction.
1806
+ * @return {object} Object containing the ordered map of results.
1807
+ */
1808
+ function mapChildren(children, func, context) {
1809
+ if (children == null) {
1810
+ return children;
1811
+ }
1812
+ var result = [];
1813
+ mapIntoWithKeyPrefixInternal(children, result, null, func, context);
1814
+ return result;
1815
+ }
1816
+
1817
+ /**
1818
+ * Count the number of children that are typically specified as
1819
+ * `props.children`.
1820
+ *
1821
+ * See https://reactjs.org/docs/react-api.html#react.children.count
1822
+ *
1823
+ * @param {?*} children Children tree container.
1824
+ * @return {number} The number of children.
1825
+ */
1826
+ function countChildren(children, context) {
1827
+ return traverseAllChildren(children, emptyFunction.thatReturnsNull, null);
1828
+ }
1829
+
1830
+ /**
1831
+ * Flatten a children object (typically specified as `props.children`) and
1832
+ * return an array with appropriately re-keyed children.
1833
+ *
1834
+ * See https://reactjs.org/docs/react-api.html#react.children.toarray
1835
+ */
1836
+ function toArray(children) {
1837
+ var result = [];
1838
+ mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument);
1839
+ return result;
1840
+ }
1841
+
1842
+ /**
1843
+ * Returns the first child in a collection of children and verifies that there
1844
+ * is only one child in the collection.
1845
+ *
1846
+ * See https://reactjs.org/docs/react-api.html#react.children.only
1847
+ *
1848
+ * The current implementation of this function assumes that a single child gets
1849
+ * passed without a wrapper, but the purpose of this helper function is to
1850
+ * abstract away the particular structure of children.
1851
+ *
1852
+ * @param {?object} children Child collection structure.
1853
+ * @return {ReactElement} The first and only `ReactElement` contained in the
1854
+ * structure.
1855
+ */
1856
+ function onlyChild(children) {
1857
+ !isValidElement(children) ? invariant(false, 'React.Children.only expected to receive a single React element child.') : void 0;
1858
+ return children;
1859
+ }
1860
+
1861
+ function createContext(defaultValue, calculateChangedBits) {
1862
+ if (calculateChangedBits === undefined) {
1863
+ calculateChangedBits = null;
1864
+ } else {
1865
+ {
1866
+ !(calculateChangedBits === null || typeof calculateChangedBits === 'function') ? warning(false, 'createContext: Expected the optional second argument to be a ' + 'function. Instead received: %s', calculateChangedBits) : void 0;
1867
+ }
1868
+ }
1869
+
1870
+ var context = {
1871
+ $$typeof: REACT_CONTEXT_TYPE,
1872
+ _calculateChangedBits: calculateChangedBits,
1873
+ _defaultValue: defaultValue,
1874
+ _currentValue: defaultValue,
1875
+ _changedBits: 0,
1876
+ // These are circular
1877
+ Provider: null,
1878
+ Consumer: null
1879
+ };
1880
+
1881
+ context.Provider = {
1882
+ $$typeof: REACT_PROVIDER_TYPE,
1883
+ _context: context
1884
+ };
1885
+ context.Consumer = context;
1886
+
1887
+ {
1888
+ context._currentRenderer = null;
1889
+ }
1890
+
1891
+ return context;
1892
+ }
1893
+
1894
+ function forwardRef(render) {
1895
+ {
1896
+ !(typeof render === 'function') ? warning(false, 'forwardRef requires a render function but was given %s.', render === null ? 'null' : typeof render) : void 0;
1897
+ }
1898
+
1899
+ return {
1900
+ $$typeof: REACT_FORWARD_REF_TYPE,
1901
+ render: render
1902
+ };
1903
+ }
1904
+
1905
+ var describeComponentFrame = function (name, source, ownerName) {
1906
+ return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
1907
+ };
1908
+
1909
+ function isValidElementType(type) {
1910
+ return typeof type === 'string' || typeof type === 'function' ||
1911
+ // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.
1912
+ type === REACT_FRAGMENT_TYPE || type === REACT_ASYNC_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE);
1913
+ }
1914
+
1915
+ function getComponentName(fiber) {
1916
+ var type = fiber.type;
1917
+
1918
+ if (typeof type === 'function') {
1919
+ return type.displayName || type.name;
1920
+ }
1921
+ if (typeof type === 'string') {
1922
+ return type;
1923
+ }
1924
+ switch (type) {
1925
+ case REACT_FRAGMENT_TYPE:
1926
+ return 'ReactFragment';
1927
+ case REACT_PORTAL_TYPE:
1928
+ return 'ReactPortal';
1929
+ case REACT_CALL_TYPE:
1930
+ return 'ReactCall';
1931
+ case REACT_RETURN_TYPE:
1932
+ return 'ReactReturn';
1933
+ }
1934
+ if (typeof type === 'object' && type !== null) {
1935
+ switch (type.$$typeof) {
1936
+ case REACT_FORWARD_REF_TYPE:
1937
+ var functionName = type.render.displayName || type.render.name || '';
1938
+ return functionName !== '' ? 'ForwardRef(' + functionName + ')' : 'ForwardRef';
1939
+ }
1940
+ }
1941
+ return null;
1942
+ }
1943
+
1944
+ /**
1945
+ * ReactElementValidator provides a wrapper around a element factory
1946
+ * which validates the props passed to the element. This is intended to be
1947
+ * used only in DEV and could be replaced by a static type checker for languages
1948
+ * that support it.
1949
+ */
1950
+
1951
+ var currentlyValidatingElement = void 0;
1952
+ var propTypesMisspellWarningShown = void 0;
1953
+
1954
+ var getDisplayName = function () {};
1955
+ var getStackAddendum = function () {};
1956
+
1957
+ {
1958
+ currentlyValidatingElement = null;
1959
+
1960
+ propTypesMisspellWarningShown = false;
1961
+
1962
+ getDisplayName = function (element) {
1963
+ if (element == null) {
1964
+ return '#empty';
1965
+ } else if (typeof element === 'string' || typeof element === 'number') {
1966
+ return '#text';
1967
+ } else if (typeof element.type === 'string') {
1968
+ return element.type;
1969
+ } else if (element.type === REACT_FRAGMENT_TYPE) {
1970
+ return 'React.Fragment';
1971
+ } else {
1972
+ return element.type.displayName || element.type.name || 'Unknown';
1973
+ }
1974
+ };
1975
+
1976
+ getStackAddendum = function () {
1977
+ var stack = '';
1978
+ if (currentlyValidatingElement) {
1979
+ var name = getDisplayName(currentlyValidatingElement);
1980
+ var owner = currentlyValidatingElement._owner;
1981
+ stack += describeComponentFrame(name, currentlyValidatingElement._source, owner && getComponentName(owner));
1982
+ }
1983
+ stack += ReactDebugCurrentFrame.getStackAddendum() || '';
1984
+ return stack;
1985
+ };
1986
+ }
1987
+
1988
+ function getDeclarationErrorAddendum() {
1989
+ if (ReactCurrentOwner.current) {
1990
+ var name = getComponentName(ReactCurrentOwner.current);
1991
+ if (name) {
1992
+ return '\n\nCheck the render method of `' + name + '`.';
1993
+ }
1994
+ }
1995
+ return '';
1996
+ }
1997
+
1998
+ function getSourceInfoErrorAddendum(elementProps) {
1999
+ if (elementProps !== null && elementProps !== undefined && elementProps.__source !== undefined) {
2000
+ var source = elementProps.__source;
2001
+ var fileName = source.fileName.replace(/^.*[\\\/]/, '');
2002
+ var lineNumber = source.lineNumber;
2003
+ return '\n\nCheck your code at ' + fileName + ':' + lineNumber + '.';
2004
+ }
2005
+ return '';
2006
+ }
2007
+
2008
+ /**
2009
+ * Warn if there's no key explicitly set on dynamic arrays of children or
2010
+ * object keys are not valid. This allows us to keep track of children between
2011
+ * updates.
2012
+ */
2013
+ var ownerHasKeyUseWarning = {};
2014
+
2015
+ function getCurrentComponentErrorInfo(parentType) {
2016
+ var info = getDeclarationErrorAddendum();
2017
+
2018
+ if (!info) {
2019
+ var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
2020
+ if (parentName) {
2021
+ info = '\n\nCheck the top-level render call using <' + parentName + '>.';
2022
+ }
2023
+ }
2024
+ return info;
2025
+ }
2026
+
2027
+ /**
2028
+ * Warn if the element doesn't have an explicit key assigned to it.
2029
+ * This element is in an array. The array could grow and shrink or be
2030
+ * reordered. All children that haven't already been validated are required to
2031
+ * have a "key" property assigned to it. Error statuses are cached so a warning
2032
+ * will only be shown once.
2033
+ *
2034
+ * @internal
2035
+ * @param {ReactElement} element Element that requires a key.
2036
+ * @param {*} parentType element's parent's type.
2037
+ */
2038
+ function validateExplicitKey(element, parentType) {
2039
+ if (!element._store || element._store.validated || element.key != null) {
2040
+ return;
2041
+ }
2042
+ element._store.validated = true;
2043
+
2044
+ var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
2045
+ if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
2046
+ return;
2047
+ }
2048
+ ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
2049
+
2050
+ // Usually the current owner is the offender, but if it accepts children as a
2051
+ // property, it may be the creator of the child that's responsible for
2052
+ // assigning it a key.
2053
+ var childOwner = '';
2054
+ if (element && element._owner && element._owner !== ReactCurrentOwner.current) {
2055
+ // Give the component that originally created this child.
2056
+ childOwner = ' It was passed a child from ' + getComponentName(element._owner) + '.';
2057
+ }
2058
+
2059
+ currentlyValidatingElement = element;
2060
+ {
2061
+ warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.%s', currentComponentErrorInfo, childOwner, getStackAddendum());
2062
+ }
2063
+ currentlyValidatingElement = null;
2064
+ }
2065
+
2066
+ /**
2067
+ * Ensure that every element either is passed in a static location, in an
2068
+ * array with an explicit keys property defined, or in an object literal
2069
+ * with valid key property.
2070
+ *
2071
+ * @internal
2072
+ * @param {ReactNode} node Statically passed child of any type.
2073
+ * @param {*} parentType node's parent's type.
2074
+ */
2075
+ function validateChildKeys(node, parentType) {
2076
+ if (typeof node !== 'object') {
2077
+ return;
2078
+ }
2079
+ if (Array.isArray(node)) {
2080
+ for (var i = 0; i < node.length; i++) {
2081
+ var child = node[i];
2082
+ if (isValidElement(child)) {
2083
+ validateExplicitKey(child, parentType);
2084
+ }
2085
+ }
2086
+ } else if (isValidElement(node)) {
2087
+ // This element was passed in a valid location.
2088
+ if (node._store) {
2089
+ node._store.validated = true;
2090
+ }
2091
+ } else if (node) {
2092
+ var iteratorFn = getIteratorFn(node);
2093
+ if (typeof iteratorFn === 'function') {
2094
+ // Entry iterators used to provide implicit keys,
2095
+ // but now we print a separate warning for them later.
2096
+ if (iteratorFn !== node.entries) {
2097
+ var iterator = iteratorFn.call(node);
2098
+ var step = void 0;
2099
+ while (!(step = iterator.next()).done) {
2100
+ if (isValidElement(step.value)) {
2101
+ validateExplicitKey(step.value, parentType);
2102
+ }
2103
+ }
2104
+ }
2105
+ }
2106
+ }
2107
+ }
2108
+
2109
+ /**
2110
+ * Given an element, validate that its props follow the propTypes definition,
2111
+ * provided by the type.
2112
+ *
2113
+ * @param {ReactElement} element
2114
+ */
2115
+ function validatePropTypes(element) {
2116
+ var componentClass = element.type;
2117
+ if (typeof componentClass !== 'function') {
2118
+ return;
2119
+ }
2120
+ var name = componentClass.displayName || componentClass.name;
2121
+ var propTypes = componentClass.propTypes;
2122
+ if (propTypes) {
2123
+ currentlyValidatingElement = element;
2124
+ checkPropTypes(propTypes, element.props, 'prop', name, getStackAddendum);
2125
+ currentlyValidatingElement = null;
2126
+ } else if (componentClass.PropTypes !== undefined && !propTypesMisspellWarningShown) {
2127
+ propTypesMisspellWarningShown = true;
2128
+ warning(false, 'Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', name || 'Unknown');
2129
+ }
2130
+ if (typeof componentClass.getDefaultProps === 'function') {
2131
+ !componentClass.getDefaultProps.isReactClassApproved ? warning(false, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : void 0;
2132
+ }
2133
+ }
2134
+
2135
+ /**
2136
+ * Given a fragment, validate that it can only be provided with fragment props
2137
+ * @param {ReactElement} fragment
2138
+ */
2139
+ function validateFragmentProps(fragment) {
2140
+ currentlyValidatingElement = fragment;
2141
+
2142
+ var keys = Object.keys(fragment.props);
2143
+ for (var i = 0; i < keys.length; i++) {
2144
+ var key = keys[i];
2145
+ if (key !== 'children' && key !== 'key') {
2146
+ warning(false, 'Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.%s', key, getStackAddendum());
2147
+ break;
2148
+ }
2149
+ }
2150
+
2151
+ if (fragment.ref !== null) {
2152
+ warning(false, 'Invalid attribute `ref` supplied to `React.Fragment`.%s', getStackAddendum());
2153
+ }
2154
+
2155
+ currentlyValidatingElement = null;
2156
+ }
2157
+
2158
+ function createElementWithValidation(type, props, children) {
2159
+ var validType = isValidElementType(type);
2160
+
2161
+ // We warn in this case but don't throw. We expect the element creation to
2162
+ // succeed and there will likely be errors in render.
2163
+ if (!validType) {
2164
+ var info = '';
2165
+ if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
2166
+ info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
2167
+ }
2168
+
2169
+ var sourceInfo = getSourceInfoErrorAddendum(props);
2170
+ if (sourceInfo) {
2171
+ info += sourceInfo;
2172
+ } else {
2173
+ info += getDeclarationErrorAddendum();
2174
+ }
2175
+
2176
+ info += getStackAddendum() || '';
2177
+
2178
+ var typeString = void 0;
2179
+ if (type === null) {
2180
+ typeString = 'null';
2181
+ } else if (Array.isArray(type)) {
2182
+ typeString = 'array';
2183
+ } else {
2184
+ typeString = typeof type;
2185
+ }
2186
+
2187
+ warning(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
2188
+ }
2189
+
2190
+ var element = createElement.apply(this, arguments);
2191
+
2192
+ // The result can be nullish if a mock or a custom function is used.
2193
+ // TODO: Drop this when these are no longer allowed as the type argument.
2194
+ if (element == null) {
2195
+ return element;
2196
+ }
2197
+
2198
+ // Skip key warning if the type isn't valid since our key validation logic
2199
+ // doesn't expect a non-string/function type and can throw confusing errors.
2200
+ // We don't want exception behavior to differ between dev and prod.
2201
+ // (Rendering will throw with a helpful message and as soon as the type is
2202
+ // fixed, the key warnings will appear.)
2203
+ if (validType) {
2204
+ for (var i = 2; i < arguments.length; i++) {
2205
+ validateChildKeys(arguments[i], type);
2206
+ }
2207
+ }
2208
+
2209
+ if (type === REACT_FRAGMENT_TYPE) {
2210
+ validateFragmentProps(element);
2211
+ } else {
2212
+ validatePropTypes(element);
2213
+ }
2214
+
2215
+ return element;
2216
+ }
2217
+
2218
+ function createFactoryWithValidation(type) {
2219
+ var validatedFactory = createElementWithValidation.bind(null, type);
2220
+ validatedFactory.type = type;
2221
+ // Legacy hook: remove it
2222
+ {
2223
+ Object.defineProperty(validatedFactory, 'type', {
2224
+ enumerable: false,
2225
+ get: function () {
2226
+ lowPriorityWarning$1(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.');
2227
+ Object.defineProperty(this, 'type', {
2228
+ value: type
2229
+ });
2230
+ return type;
2231
+ }
2232
+ });
2233
+ }
2234
+
2235
+ return validatedFactory;
2236
+ }
2237
+
2238
+ function cloneElementWithValidation(element, props, children) {
2239
+ var newElement = cloneElement.apply(this, arguments);
2240
+ for (var i = 2; i < arguments.length; i++) {
2241
+ validateChildKeys(arguments[i], newElement.type);
2242
+ }
2243
+ validatePropTypes(newElement);
2244
+ return newElement;
2245
+ }
2246
+
2247
+ var React = {
2248
+ Children: {
2249
+ map: mapChildren,
2250
+ forEach: forEachChildren,
2251
+ count: countChildren,
2252
+ toArray: toArray,
2253
+ only: onlyChild
2254
+ },
2255
+
2256
+ createRef: createRef,
2257
+ Component: Component,
2258
+ PureComponent: PureComponent,
2259
+
2260
+ createContext: createContext,
2261
+ forwardRef: forwardRef,
2262
+
2263
+ Fragment: REACT_FRAGMENT_TYPE,
2264
+ StrictMode: REACT_STRICT_MODE_TYPE,
2265
+ unstable_AsyncMode: REACT_ASYNC_MODE_TYPE,
2266
+
2267
+ createElement: createElementWithValidation,
2268
+ cloneElement: cloneElementWithValidation,
2269
+ createFactory: createFactoryWithValidation,
2270
+ isValidElement: isValidElement,
2271
+
2272
+ version: ReactVersion,
2273
+
2274
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
2275
+ ReactCurrentOwner: ReactCurrentOwner,
2276
+ // Used by renderers to avoid bundling object-assign twice in UMD bundles:
2277
+ assign: _assign
2278
+ }
2279
+ };
2280
+
2281
+ {
2282
+ _assign(React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, {
2283
+ // These should not be included in production.
2284
+ ReactDebugCurrentFrame: ReactDebugCurrentFrame,
2285
+ // Shim for React DOM 16.0.0 which still destructured (but not used) this.
2286
+ // TODO: remove in React 17.0.
2287
+ ReactComponentTreeHook: {}
2288
+ });
2289
+ }
2290
+
2291
+
2292
+
2293
+ var React$2 = Object.freeze({
2294
+ default: React
2295
+ });
2296
+
2297
+ var React$3 = ( React$2 && React ) || React$2;
2298
+
2299
+ // TODO: decide on the top-level export form.
2300
+ // This is hacky but makes it work with both Rollup and Jest.
2301
+ var react = React$3['default'] ? React$3['default'] : React$3;
2302
+
2303
+ module.exports = react;
2304
+ })();
2305
+ }
2306
+
2307
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
2308
+
2309
+ /***/ }),
2310
+ /* 15 */
2311
+ /***/ (function(module, exports, __webpack_require__) {
2312
+
2313
+ "use strict";
2314
+ /**
2315
+ * Copyright (c) 2013-present, Facebook, Inc.
2316
+ *
2317
+ * This source code is licensed under the MIT license found in the
2318
+ * LICENSE file in the root directory of this source tree.
2319
+ */
2320
+
2321
+
2322
+
2323
+ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
2324
+
2325
+ module.exports = ReactPropTypesSecret;
2326
+
2327
+
2328
+ /***/ }),
2329
+ /* 16 */
2330
+ /***/ (function(module, exports, __webpack_require__) {
2331
+
2332
+ "use strict";
2333
+ /* WEBPACK VAR INJECTION */(function(process) {
2334
+
2335
+ function checkDCE() {
2336
+ /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
2337
+ if (
2338
+ typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||
2339
+ typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'
2340
+ ) {
2341
+ return;
2342
+ }
2343
+ if (process.env.NODE_ENV !== 'production') {
2344
+ // This branch is unreachable because this function is only called
2345
+ // in production, but the condition is true only in development.
2346
+ // Therefore if the branch is still here, dead code elimination wasn't
2347
+ // properly applied.
2348
+ // Don't change the message. React DevTools relies on it. Also make sure
2349
+ // this message doesn't occur elsewhere in this function, or it will cause
2350
+ // a false positive.
2351
+ throw new Error('^_^');
2352
+ }
2353
+ try {
2354
+ // Verify that the code above has been dead code eliminated (DCE'd).
2355
+ __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
2356
+ } catch (err) {
2357
+ // DevTools shouldn't crash React, no matter what.
2358
+ // We should still report in case we break this code.
2359
+ console.error(err);
2360
+ }
2361
+ }
2362
+
2363
+ if (process.env.NODE_ENV === 'production') {
2364
+ // DCE check should happen before ReactDOM bundle executes so that
2365
+ // DevTools can report bad minification during injection.
2366
+ checkDCE();
2367
+ module.exports = __webpack_require__(17);
2368
+ } else {
2369
+ module.exports = __webpack_require__(20);
2370
+ }
2371
+
2372
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
2373
+
2374
+ /***/ }),
2375
+ /* 17 */
2376
+ /***/ (function(module, exports, __webpack_require__) {
2377
+
2378
+ "use strict";
2379
+ /** @license React v16.3.2
2380
+ * react-dom.production.min.js
2381
+ *
2382
+ * Copyright (c) 2013-present, Facebook, Inc.
2383
+ *
2384
+ * This source code is licensed under the MIT license found in the
2385
+ * LICENSE file in the root directory of this source tree.
2386
+ */
2387
+
2388
+ /*
2389
+ Modernizr 3.0.0pre (Custom Build) | MIT
2390
+ */
2391
+ var ba=__webpack_require__(2),ea=__webpack_require__(1),m=__webpack_require__(8),A=__webpack_require__(4),C=__webpack_require__(3),fa=__webpack_require__(9),ha=__webpack_require__(10),ja=__webpack_require__(11),ka=__webpack_require__(5);
2392
+ function D(a){for(var b=arguments.length-1,c="http://reactjs.org/docs/error-decoder.html?invariant\x3d"+a,d=0;d<b;d++)c+="\x26args[]\x3d"+encodeURIComponent(arguments[d+1]);ba(!1,"Minified React error #"+a+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",c)}ea?void 0:D("227");
2393
+ function ma(a,b,c,d,e,f,h,g,k){this._hasCaughtError=!1;this._caughtError=null;var v=Array.prototype.slice.call(arguments,3);try{b.apply(c,v)}catch(l){this._caughtError=l,this._hasCaughtError=!0}}
2394
+ var E={_caughtError:null,_hasCaughtError:!1,_rethrowError:null,_hasRethrowError:!1,invokeGuardedCallback:function(a,b,c,d,e,f,h,g,k){ma.apply(E,arguments)},invokeGuardedCallbackAndCatchFirstError:function(a,b,c,d,e,f,h,g,k){E.invokeGuardedCallback.apply(this,arguments);if(E.hasCaughtError()){var v=E.clearCaughtError();E._hasRethrowError||(E._hasRethrowError=!0,E._rethrowError=v)}},rethrowCaughtError:function(){return na.apply(E,arguments)},hasCaughtError:function(){return E._hasCaughtError},clearCaughtError:function(){if(E._hasCaughtError){var a=
2395
+ E._caughtError;E._caughtError=null;E._hasCaughtError=!1;return a}D("198")}};function na(){if(E._hasRethrowError){var a=E._rethrowError;E._rethrowError=null;E._hasRethrowError=!1;throw a;}}var oa=null,pa={};
2396
+ function qa(){if(oa)for(var a in pa){var b=pa[a],c=oa.indexOf(a);-1<c?void 0:D("96",a);if(!ra[c]){b.extractEvents?void 0:D("97",a);ra[c]=b;c=b.eventTypes;for(var d in c){var e=void 0;var f=c[d],h=b,g=d;sa.hasOwnProperty(g)?D("99",g):void 0;sa[g]=f;var k=f.phasedRegistrationNames;if(k){for(e in k)k.hasOwnProperty(e)&&ta(k[e],h,g);e=!0}else f.registrationName?(ta(f.registrationName,h,g),e=!0):e=!1;e?void 0:D("98",d,a)}}}}
2397
+ function ta(a,b,c){ua[a]?D("100",a):void 0;ua[a]=b;va[a]=b.eventTypes[c].dependencies}var ra=[],sa={},ua={},va={};function wa(a){oa?D("101"):void 0;oa=Array.prototype.slice.call(a);qa()}function xa(a){var b=!1,c;for(c in a)if(a.hasOwnProperty(c)){var d=a[c];pa.hasOwnProperty(c)&&pa[c]===d||(pa[c]?D("102",c):void 0,pa[c]=d,b=!0)}b&&qa()}
2398
+ var Ca=Object.freeze({plugins:ra,eventNameDispatchConfigs:sa,registrationNameModules:ua,registrationNameDependencies:va,possibleRegistrationNames:null,injectEventPluginOrder:wa,injectEventPluginsByName:xa}),Da=null,Ea=null,Fa=null;function Ga(a,b,c,d){b=a.type||"unknown-event";a.currentTarget=Fa(d);E.invokeGuardedCallbackAndCatchFirstError(b,c,void 0,a);a.currentTarget=null}
2399
+ function Ha(a,b){null==b?D("30"):void 0;if(null==a)return b;if(Array.isArray(a)){if(Array.isArray(b))return a.push.apply(a,b),a;a.push(b);return a}return Array.isArray(b)?[a].concat(b):[a,b]}function Ia(a,b,c){Array.isArray(a)?a.forEach(b,c):a&&b.call(c,a)}var Ja=null;
2400
+ function Ka(a,b){if(a){var c=a._dispatchListeners,d=a._dispatchInstances;if(Array.isArray(c))for(var e=0;e<c.length&&!a.isPropagationStopped();e++)Ga(a,b,c[e],d[e]);else c&&Ga(a,b,c,d);a._dispatchListeners=null;a._dispatchInstances=null;a.isPersistent()||a.constructor.release(a)}}function La(a){return Ka(a,!0)}function Ma(a){return Ka(a,!1)}var Na={injectEventPluginOrder:wa,injectEventPluginsByName:xa};
2401
+ function Oa(a,b){var c=a.stateNode;if(!c)return null;var d=Da(c);if(!d)return null;c=d[b];a:switch(b){case "onClick":case "onClickCapture":case "onDoubleClick":case "onDoubleClickCapture":case "onMouseDown":case "onMouseDownCapture":case "onMouseMove":case "onMouseMoveCapture":case "onMouseUp":case "onMouseUpCapture":(d=!d.disabled)||(a=a.type,d=!("button"===a||"input"===a||"select"===a||"textarea"===a));a=!d;break a;default:a=!1}if(a)return null;c&&"function"!==typeof c?D("231",b,typeof c):void 0;
2402
+ return c}function Pa(a,b){null!==a&&(Ja=Ha(Ja,a));a=Ja;Ja=null;a&&(b?Ia(a,La):Ia(a,Ma),Ja?D("95"):void 0,E.rethrowCaughtError())}function Qa(a,b,c,d){for(var e=null,f=0;f<ra.length;f++){var h=ra[f];h&&(h=h.extractEvents(a,b,c,d))&&(e=Ha(e,h))}Pa(e,!1)}var Ra=Object.freeze({injection:Na,getListener:Oa,runEventsInBatch:Pa,runExtractedEventsInBatch:Qa}),Sa=Math.random().toString(36).slice(2),F="__reactInternalInstance$"+Sa,Ta="__reactEventHandlers$"+Sa;
2403
+ function Ua(a){if(a[F])return a[F];for(;!a[F];)if(a.parentNode)a=a.parentNode;else return null;a=a[F];return 5===a.tag||6===a.tag?a:null}function Va(a){if(5===a.tag||6===a.tag)return a.stateNode;D("33")}function Xa(a){return a[Ta]||null}var bb=Object.freeze({precacheFiberNode:function(a,b){b[F]=a},getClosestInstanceFromNode:Ua,getInstanceFromNode:function(a){a=a[F];return!a||5!==a.tag&&6!==a.tag?null:a},getNodeFromInstance:Va,getFiberCurrentPropsFromNode:Xa,updateFiberProps:function(a,b){a[Ta]=b}});
2404
+ function L(a){do a=a["return"];while(a&&5!==a.tag);return a?a:null}function cb(a,b,c){for(var d=[];a;)d.push(a),a=L(a);for(a=d.length;0<a--;)b(d[a],"captured",c);for(a=0;a<d.length;a++)b(d[a],"bubbled",c)}function db(a,b,c){if(b=Oa(a,c.dispatchConfig.phasedRegistrationNames[b]))c._dispatchListeners=Ha(c._dispatchListeners,b),c._dispatchInstances=Ha(c._dispatchInstances,a)}function eb(a){a&&a.dispatchConfig.phasedRegistrationNames&&cb(a._targetInst,db,a)}
2405
+ function fb(a){if(a&&a.dispatchConfig.phasedRegistrationNames){var b=a._targetInst;b=b?L(b):null;cb(b,db,a)}}function gb(a,b,c){a&&c&&c.dispatchConfig.registrationName&&(b=Oa(a,c.dispatchConfig.registrationName))&&(c._dispatchListeners=Ha(c._dispatchListeners,b),c._dispatchInstances=Ha(c._dispatchInstances,a))}function hb(a){a&&a.dispatchConfig.registrationName&&gb(a._targetInst,null,a)}function ib(a){Ia(a,eb)}
2406
+ function jb(a,b,c,d){if(c&&d)a:{var e=c;for(var f=d,h=0,g=e;g;g=L(g))h++;g=0;for(var k=f;k;k=L(k))g++;for(;0<h-g;)e=L(e),h--;for(;0<g-h;)f=L(f),g--;for(;h--;){if(e===f||e===f.alternate)break a;e=L(e);f=L(f)}e=null}else e=null;f=e;for(e=[];c&&c!==f;){h=c.alternate;if(null!==h&&h===f)break;e.push(c);c=L(c)}for(c=[];d&&d!==f;){h=d.alternate;if(null!==h&&h===f)break;c.push(d);d=L(d)}for(d=0;d<e.length;d++)gb(e[d],"bubbled",a);for(a=c.length;0<a--;)gb(c[a],"captured",b)}
2407
+ var kb=Object.freeze({accumulateTwoPhaseDispatches:ib,accumulateTwoPhaseDispatchesSkipTarget:function(a){Ia(a,fb)},accumulateEnterLeaveDispatches:jb,accumulateDirectDispatches:function(a){Ia(a,hb)}}),lb=null;function mb(){!lb&&m.canUseDOM&&(lb="textContent"in document.documentElement?"textContent":"innerText");return lb}var M={_root:null,_startText:null,_fallbackText:null};
2408
+ function nb(){if(M._fallbackText)return M._fallbackText;var a,b=M._startText,c=b.length,d,e=ob(),f=e.length;for(a=0;a<c&&b[a]===e[a];a++);var h=c-a;for(d=1;d<=h&&b[c-d]===e[f-d];d++);M._fallbackText=e.slice(a,1<d?1-d:void 0);return M._fallbackText}function ob(){return"value"in M._root?M._root.value:M._root[mb()]}
2409
+ var pb="dispatchConfig _targetInst nativeEvent isDefaultPrevented isPropagationStopped _dispatchListeners _dispatchInstances".split(" "),qb={type:null,target:null,currentTarget:C.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(a){return a.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};
2410
+ function N(a,b,c,d){this.dispatchConfig=a;this._targetInst=b;this.nativeEvent=c;a=this.constructor.Interface;for(var e in a)a.hasOwnProperty(e)&&((b=a[e])?this[e]=b(c):"target"===e?this.target=d:this[e]=c[e]);this.isDefaultPrevented=(null!=c.defaultPrevented?c.defaultPrevented:!1===c.returnValue)?C.thatReturnsTrue:C.thatReturnsFalse;this.isPropagationStopped=C.thatReturnsFalse;return this}
2411
+ A(N.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():"unknown"!==typeof a.returnValue&&(a.returnValue=!1),this.isDefaultPrevented=C.thatReturnsTrue)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():"unknown"!==typeof a.cancelBubble&&(a.cancelBubble=!0),this.isPropagationStopped=C.thatReturnsTrue)},persist:function(){this.isPersistent=C.thatReturnsTrue},isPersistent:C.thatReturnsFalse,
2412
+ destructor:function(){var a=this.constructor.Interface,b;for(b in a)this[b]=null;for(a=0;a<pb.length;a++)this[pb[a]]=null}});N.Interface=qb;N.extend=function(a){function b(){}function c(){return d.apply(this,arguments)}var d=this;b.prototype=d.prototype;var e=new b;A(e,c.prototype);c.prototype=e;c.prototype.constructor=c;c.Interface=A({},d.Interface,a);c.extend=d.extend;rb(c);return c};rb(N);
2413
+ function sb(a,b,c,d){if(this.eventPool.length){var e=this.eventPool.pop();this.call(e,a,b,c,d);return e}return new this(a,b,c,d)}function tb(a){a instanceof this?void 0:D("223");a.destructor();10>this.eventPool.length&&this.eventPool.push(a)}function rb(a){a.eventPool=[];a.getPooled=sb;a.release=tb}var ub=N.extend({data:null}),vb=N.extend({data:null}),wb=[9,13,27,32],xb=m.canUseDOM&&"CompositionEvent"in window,yb=null;m.canUseDOM&&"documentMode"in document&&(yb=document.documentMode);
2414
+ var zb=m.canUseDOM&&"TextEvent"in window&&!yb,Ab=m.canUseDOM&&(!xb||yb&&8<yb&&11>=yb),Bb=String.fromCharCode(32),Kb={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["topCompositionEnd","topKeyPress","topTextInput","topPaste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"topBlur topCompositionEnd topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",
2415
+ captured:"onCompositionStartCapture"},dependencies:"topBlur topCompositionStart topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"topBlur topCompositionUpdate topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")}},Lb=!1;
2416
+ function Mb(a,b){switch(a){case "topKeyUp":return-1!==wb.indexOf(b.keyCode);case "topKeyDown":return 229!==b.keyCode;case "topKeyPress":case "topMouseDown":case "topBlur":return!0;default:return!1}}function Nb(a){a=a.detail;return"object"===typeof a&&"data"in a?a.data:null}var Ob=!1;function Pb(a,b){switch(a){case "topCompositionEnd":return Nb(b);case "topKeyPress":if(32!==b.which)return null;Lb=!0;return Bb;case "topTextInput":return a=b.data,a===Bb&&Lb?null:a;default:return null}}
2417
+ function Qb(a,b){if(Ob)return"topCompositionEnd"===a||!xb&&Mb(a,b)?(a=nb(),M._root=null,M._startText=null,M._fallbackText=null,Ob=!1,a):null;switch(a){case "topPaste":return null;case "topKeyPress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1<b.char.length)return b.char;if(b.which)return String.fromCharCode(b.which)}return null;case "topCompositionEnd":return Ab?null:b.data;default:return null}}
2418
+ var Rb={eventTypes:Kb,extractEvents:function(a,b,c,d){var e=void 0;var f=void 0;if(xb)b:{switch(a){case "topCompositionStart":e=Kb.compositionStart;break b;case "topCompositionEnd":e=Kb.compositionEnd;break b;case "topCompositionUpdate":e=Kb.compositionUpdate;break b}e=void 0}else Ob?Mb(a,c)&&(e=Kb.compositionEnd):"topKeyDown"===a&&229===c.keyCode&&(e=Kb.compositionStart);e?(Ab&&(Ob||e!==Kb.compositionStart?e===Kb.compositionEnd&&Ob&&(f=nb()):(M._root=d,M._startText=ob(),Ob=!0)),e=ub.getPooled(e,
2419
+ b,c,d),f?e.data=f:(f=Nb(c),null!==f&&(e.data=f)),ib(e),f=e):f=null;(a=zb?Pb(a,c):Qb(a,c))?(b=vb.getPooled(Kb.beforeInput,b,c,d),b.data=a,ib(b)):b=null;return null===f?b:null===b?f:[f,b]}},Sb=null,Tb={injectFiberControlledHostComponent:function(a){Sb=a}},Ub=null,Vb=null;function Wb(a){if(a=Ea(a)){Sb&&"function"===typeof Sb.restoreControlledState?void 0:D("194");var b=Da(a.stateNode);Sb.restoreControlledState(a.stateNode,a.type,b)}}function Xb(a){Ub?Vb?Vb.push(a):Vb=[a]:Ub=a}
2420
+ function Yb(){return null!==Ub||null!==Vb}function Zb(){if(Ub){var a=Ub,b=Vb;Vb=Ub=null;Wb(a);if(b)for(a=0;a<b.length;a++)Wb(b[a])}}var $b=Object.freeze({injection:Tb,enqueueStateRestore:Xb,needsStateRestore:Yb,restoreStateIfNeeded:Zb});function ac(a,b){return a(b)}function bc(a,b,c){return a(b,c)}function cc(){}var dc=!1;function ec(a,b){if(dc)return a(b);dc=!0;try{return ac(a,b)}finally{dc=!1,Yb()&&(cc(),Zb())}}
2421
+ var fc={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function gc(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return"input"===b?!!fc[a.type]:"textarea"===b?!0:!1}function hc(a){a=a.target||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:a}
2422
+ function ic(a,b){if(!m.canUseDOM||b&&!("addEventListener"in document))return!1;a="on"+a;b=a in document;b||(b=document.createElement("div"),b.setAttribute(a,"return;"),b="function"===typeof b[a]);return b}function jc(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===b)}
2423
+ function kc(a){var b=jc(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"function"===typeof c.get&&"function"===typeof c.set)return Object.defineProperty(a,b,{configurable:!0,get:function(){return c.get.call(this)},set:function(a){d=""+a;c.set.call(this,a)}}),Object.defineProperty(a,b,{enumerable:c.enumerable}),{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker=null;delete a[b]}}}
2424
+ function lc(a){a._valueTracker||(a._valueTracker=kc(a))}function mc(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=jc(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}
2425
+ var nc=ea.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,O="function"===typeof Symbol&&Symbol["for"],oc=O?Symbol["for"]("react.element"):60103,pc=O?Symbol["for"]("react.call"):60104,qc=O?Symbol["for"]("react.return"):60105,rc=O?Symbol["for"]("react.portal"):60106,sc=O?Symbol["for"]("react.fragment"):60107,tc=O?Symbol["for"]("react.strict_mode"):60108,uc=O?Symbol["for"]("react.provider"):60109,vc=O?Symbol["for"]("react.context"):60110,wc=O?Symbol["for"]("react.async_mode"):60111,
2426
+ xc=O?Symbol["for"]("react.forward_ref"):60112,yc="function"===typeof Symbol&&Symbol.iterator;function zc(a){if(null===a||"undefined"===typeof a)return null;a=yc&&a[yc]||a["@@iterator"];return"function"===typeof a?a:null}
2427
+ function Ac(a){a=a.type;if("function"===typeof a)return a.displayName||a.name;if("string"===typeof a)return a;switch(a){case sc:return"ReactFragment";case rc:return"ReactPortal";case pc:return"ReactCall";case qc:return"ReactReturn"}if("object"===typeof a&&null!==a)switch(a.$$typeof){case xc:return a=a.render.displayName||a.render.name||"",""!==a?"ForwardRef("+a+")":"ForwardRef"}return null}
2428
+ function Bc(a){var b="";do{a:switch(a.tag){case 0:case 1:case 2:case 5:var c=a._debugOwner,d=a._debugSource;var e=Ac(a);var f=null;c&&(f=Ac(c));c=d;e="\n in "+(e||"Unknown")+(c?" (at "+c.fileName.replace(/^.*[\\\/]/,"")+":"+c.lineNumber+")":f?" (created by "+f+")":"");break a;default:e=""}b+=e;a=a["return"]}while(a);return b}
2429
+ var Cc=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Dc={},Ec={};function Fc(a){if(Ec.hasOwnProperty(a))return!0;if(Dc.hasOwnProperty(a))return!1;if(Cc.test(a))return Ec[a]=!0;Dc[a]=!0;return!1}
2430
+ function Gc(a,b,c,d){if(null!==c&&0===c.type)return!1;switch(typeof b){case "function":case "symbol":return!0;case "boolean":if(d)return!1;if(null!==c)return!c.acceptsBooleans;a=a.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}function Hc(a,b,c,d){if(null===b||"undefined"===typeof b||Gc(a,b,c,d))return!0;if(null!==c)switch(c.type){case 3:return!b;case 4:return!1===b;case 5:return isNaN(b);case 6:return isNaN(b)||1>b}return!1}
2431
+ function U(a,b,c,d,e){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b}var V={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){V[a]=new U(a,0,!1,a,null)});
2432
+ [["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];V[b]=new U(b,1,!1,a[1],null)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){V[a]=new U(a,2,!1,a.toLowerCase(),null)});["autoReverse","externalResourcesRequired","preserveAlpha"].forEach(function(a){V[a]=new U(a,2,!1,a,null)});
2433
+ "allowFullScreen async autoFocus autoPlay controls default defer disabled formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){V[a]=new U(a,3,!1,a.toLowerCase(),null)});["checked","multiple","muted","selected"].forEach(function(a){V[a]=new U(a,3,!0,a.toLowerCase(),null)});["capture","download"].forEach(function(a){V[a]=new U(a,4,!1,a.toLowerCase(),null)});
2434
+ ["cols","rows","size","span"].forEach(function(a){V[a]=new U(a,6,!1,a.toLowerCase(),null)});["rowSpan","start"].forEach(function(a){V[a]=new U(a,5,!1,a.toLowerCase(),null)});var Sc=/[\-:]([a-z])/g;function Tc(a){return a[1].toUpperCase()}
2435
+ "accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=a.replace(Sc,
2436
+ Tc);V[b]=new U(b,1,!1,a,null)});"xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(Sc,Tc);V[b]=new U(b,1,!1,a,"http://www.w3.org/1999/xlink")});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(Sc,Tc);V[b]=new U(b,1,!1,a,"http://www.w3.org/XML/1998/namespace")});V.tabIndex=new U("tabIndex",1,!1,"tabindex",null);
2437
+ function Uc(a,b,c,d){var e=V.hasOwnProperty(b)?V[b]:null;var f=null!==e?0===e.type:d?!1:!(2<b.length)||"o"!==b[0]&&"O"!==b[0]||"n"!==b[1]&&"N"!==b[1]?!1:!0;f||(Hc(b,c,e,d)&&(c=null),d||null===e?Fc(b)&&(null===c?a.removeAttribute(b):a.setAttribute(b,""+c)):e.mustUseProperty?a[e.propertyName]=null===c?3===e.type?!1:"":c:(b=e.attributeName,d=e.attributeNamespace,null===c?a.removeAttribute(b):(e=e.type,c=3===e||4===e&&!0===c?"":""+c,d?a.setAttributeNS(d,b,c):a.setAttribute(b,c))))}
2438
+ function Vc(a,b){var c=b.checked;return A({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Wc(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=Xc(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function Yc(a,b){b=b.checked;null!=b&&Uc(a,"checked",b,!1)}
2439
+ function Zc(a,b){Yc(a,b);var c=Xc(b.value);if(null!=c)if("number"===b.type){if(0===c&&""===a.value||a.value!=c)a.value=""+c}else a.value!==""+c&&(a.value=""+c);b.hasOwnProperty("value")?$c(a,b.type,c):b.hasOwnProperty("defaultValue")&&$c(a,b.type,Xc(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}
2440
+ function ad(a,b){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue"))""===a.value&&(a.value=""+a._wrapperState.initialValue),a.defaultValue=""+a._wrapperState.initialValue;b=a.name;""!==b&&(a.name="");a.defaultChecked=!a.defaultChecked;a.defaultChecked=!a.defaultChecked;""!==b&&(a.name=b)}function $c(a,b,c){if("number"!==b||a.ownerDocument.activeElement!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}
2441
+ function Xc(a){switch(typeof a){case "boolean":case "number":case "object":case "string":case "undefined":return a;default:return""}}var bd={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:"topBlur topChange topClick topFocus topInput topKeyDown topKeyUp topSelectionChange".split(" ")}};function cd(a,b,c){a=N.getPooled(bd.change,a,b,c);a.type="change";Xb(c);ib(a);return a}var dd=null,ed=null;function fd(a){Pa(a,!1)}
2442
+ function gd(a){var b=Va(a);if(mc(b))return a}function hd(a,b){if("topChange"===a)return b}var id=!1;m.canUseDOM&&(id=ic("input")&&(!document.documentMode||9<document.documentMode));function jd(){dd&&(dd.detachEvent("onpropertychange",kd),ed=dd=null)}function kd(a){"value"===a.propertyName&&gd(ed)&&(a=cd(ed,a,hc(a)),ec(fd,a))}function ld(a,b,c){"topFocus"===a?(jd(),dd=b,ed=c,dd.attachEvent("onpropertychange",kd)):"topBlur"===a&&jd()}
2443
+ function md(a){if("topSelectionChange"===a||"topKeyUp"===a||"topKeyDown"===a)return gd(ed)}function nd(a,b){if("topClick"===a)return gd(b)}function od(a,b){if("topInput"===a||"topChange"===a)return gd(b)}
2444
+ var pd={eventTypes:bd,_isInputEventSupported:id,extractEvents:function(a,b,c,d){var e=b?Va(b):window,f=void 0,h=void 0,g=e.nodeName&&e.nodeName.toLowerCase();"select"===g||"input"===g&&"file"===e.type?f=hd:gc(e)?id?f=od:(f=md,h=ld):(g=e.nodeName)&&"input"===g.toLowerCase()&&("checkbox"===e.type||"radio"===e.type)&&(f=nd);if(f&&(f=f(a,b)))return cd(f,c,d);h&&h(a,e,b);"topBlur"===a&&null!=b&&(a=b._wrapperState||e._wrapperState)&&a.controlled&&"number"===e.type&&$c(e,"number",e.value)}},qd=N.extend({view:null,
2445
+ detail:null}),rd={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function sd(a){var b=this.nativeEvent;return b.getModifierState?b.getModifierState(a):(a=rd[a])?!!b[a]:!1}function td(){return sd}
2446
+ var ud=qd.extend({screenX:null,screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:td,button:null,buttons:null,relatedTarget:function(a){return a.relatedTarget||(a.fromElement===a.srcElement?a.toElement:a.fromElement)}}),vd={mouseEnter:{registrationName:"onMouseEnter",dependencies:["topMouseOut","topMouseOver"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["topMouseOut","topMouseOver"]}},wd={eventTypes:vd,extractEvents:function(a,
2447
+ b,c,d){if("topMouseOver"===a&&(c.relatedTarget||c.fromElement)||"topMouseOut"!==a&&"topMouseOver"!==a)return null;var e=d.window===d?d:(e=d.ownerDocument)?e.defaultView||e.parentWindow:window;"topMouseOut"===a?(a=b,b=(b=c.relatedTarget||c.toElement)?Ua(b):null):a=null;if(a===b)return null;var f=null==a?e:Va(a);e=null==b?e:Va(b);var h=ud.getPooled(vd.mouseLeave,a,c,d);h.type="mouseleave";h.target=f;h.relatedTarget=e;c=ud.getPooled(vd.mouseEnter,b,c,d);c.type="mouseenter";c.target=e;c.relatedTarget=
2448
+ f;jb(h,c,a,b);return[h,c]}};function xd(a){var b=a;if(a.alternate)for(;b["return"];)b=b["return"];else{if(0!==(b.effectTag&2))return 1;for(;b["return"];)if(b=b["return"],0!==(b.effectTag&2))return 1}return 3===b.tag?2:3}function yd(a){return(a=a._reactInternalFiber)?2===xd(a):!1}function zd(a){2!==xd(a)?D("188"):void 0}
2449
+ function Ad(a){var b=a.alternate;if(!b)return b=xd(a),3===b?D("188"):void 0,1===b?null:a;for(var c=a,d=b;;){var e=c["return"],f=e?e.alternate:null;if(!e||!f)break;if(e.child===f.child){for(var h=e.child;h;){if(h===c)return zd(e),a;if(h===d)return zd(e),b;h=h.sibling}D("188")}if(c["return"]!==d["return"])c=e,d=f;else{h=!1;for(var g=e.child;g;){if(g===c){h=!0;c=e;d=f;break}if(g===d){h=!0;d=e;c=f;break}g=g.sibling}if(!h){for(g=f.child;g;){if(g===c){h=!0;c=f;d=e;break}if(g===d){h=!0;d=f;c=e;break}g=g.sibling}h?
2450
+ void 0:D("189")}}c.alternate!==d?D("190"):void 0}3!==c.tag?D("188"):void 0;return c.stateNode.current===c?a:b}function Bd(a){a=Ad(a);if(!a)return null;for(var b=a;;){if(5===b.tag||6===b.tag)return b;if(b.child)b.child["return"]=b,b=b.child;else{if(b===a)break;for(;!b.sibling;){if(!b["return"]||b["return"]===a)return null;b=b["return"]}b.sibling["return"]=b["return"];b=b.sibling}}return null}
2451
+ function Cd(a){a=Ad(a);if(!a)return null;for(var b=a;;){if(5===b.tag||6===b.tag)return b;if(b.child&&4!==b.tag)b.child["return"]=b,b=b.child;else{if(b===a)break;for(;!b.sibling;){if(!b["return"]||b["return"]===a)return null;b=b["return"]}b.sibling["return"]=b["return"];b=b.sibling}}return null}var Dd=N.extend({animationName:null,elapsedTime:null,pseudoElement:null}),Ed=N.extend({clipboardData:function(a){return"clipboardData"in a?a.clipboardData:window.clipboardData}}),Fd=qd.extend({relatedTarget:null});
2452
+ function Gd(a){var b=a.keyCode;"charCode"in a?(a=a.charCode,0===a&&13===b&&(a=13)):a=b;10===a&&(a=13);return 32<=a||13===a?a:0}
2453
+ var Hd={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Id={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",
2454
+ 116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Jd=qd.extend({key:function(a){if(a.key){var b=Hd[a.key]||a.key;if("Unidentified"!==b)return b}return"keypress"===a.type?(a=Gd(a),13===a?"Enter":String.fromCharCode(a)):"keydown"===a.type||"keyup"===a.type?Id[a.keyCode]||"Unidentified":""},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:td,charCode:function(a){return"keypress"===
2455
+ a.type?Gd(a):0},keyCode:function(a){return"keydown"===a.type||"keyup"===a.type?a.keyCode:0},which:function(a){return"keypress"===a.type?Gd(a):"keydown"===a.type||"keyup"===a.type?a.keyCode:0}}),Kd=ud.extend({dataTransfer:null}),Ld=qd.extend({touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:td}),Md=N.extend({propertyName:null,elapsedTime:null,pseudoElement:null}),Nd=ud.extend({deltaX:function(a){return"deltaX"in a?a.deltaX:"wheelDeltaX"in
2456
+ a?-a.wheelDeltaX:0},deltaY:function(a){return"deltaY"in a?a.deltaY:"wheelDeltaY"in a?-a.wheelDeltaY:"wheelDelta"in a?-a.wheelDelta:0},deltaZ:null,deltaMode:null}),Od={},Pd={};function Qd(a,b){var c=a[0].toUpperCase()+a.slice(1),d="on"+c;c="top"+c;b={phasedRegistrationNames:{bubbled:d,captured:d+"Capture"},dependencies:[c],isInteractive:b};Od[a]=b;Pd[c]=b}
2457
+ "blur cancel click close contextMenu copy cut doubleClick dragEnd dragStart drop focus input invalid keyDown keyPress keyUp mouseDown mouseUp paste pause play rateChange reset seeked submit touchCancel touchEnd touchStart volumeChange".split(" ").forEach(function(a){Qd(a,!0)});
2458
+ "abort animationEnd animationIteration animationStart canPlay canPlayThrough drag dragEnter dragExit dragLeave dragOver durationChange emptied encrypted ended error load loadedData loadedMetadata loadStart mouseMove mouseOut mouseOver playing progress scroll seeking stalled suspend timeUpdate toggle touchMove transitionEnd waiting wheel".split(" ").forEach(function(a){Qd(a,!1)});
2459
+ var Rd={eventTypes:Od,isInteractiveTopLevelEventType:function(a){a=Pd[a];return void 0!==a&&!0===a.isInteractive},extractEvents:function(a,b,c,d){var e=Pd[a];if(!e)return null;switch(a){case "topKeyPress":if(0===Gd(c))return null;case "topKeyDown":case "topKeyUp":a=Jd;break;case "topBlur":case "topFocus":a=Fd;break;case "topClick":if(2===c.button)return null;case "topDoubleClick":case "topMouseDown":case "topMouseMove":case "topMouseUp":case "topMouseOut":case "topMouseOver":case "topContextMenu":a=
2460
+ ud;break;case "topDrag":case "topDragEnd":case "topDragEnter":case "topDragExit":case "topDragLeave":case "topDragOver":case "topDragStart":case "topDrop":a=Kd;break;case "topTouchCancel":case "topTouchEnd":case "topTouchMove":case "topTouchStart":a=Ld;break;case "topAnimationEnd":case "topAnimationIteration":case "topAnimationStart":a=Dd;break;case "topTransitionEnd":a=Md;break;case "topScroll":a=qd;break;case "topWheel":a=Nd;break;case "topCopy":case "topCut":case "topPaste":a=Ed;break;default:a=
2461
+ N}b=a.getPooled(e,b,c,d);ib(b);return b}},Sd=Rd.isInteractiveTopLevelEventType,Td=[];function Ud(a){var b=a.targetInst;do{if(!b){a.ancestors.push(b);break}var c;for(c=b;c["return"];)c=c["return"];c=3!==c.tag?null:c.stateNode.containerInfo;if(!c)break;a.ancestors.push(b);b=Ua(c)}while(b);for(c=0;c<a.ancestors.length;c++)b=a.ancestors[c],Qa(a.topLevelType,b,a.nativeEvent,hc(a.nativeEvent))}var Vd=!0;function Wd(a){Vd=!!a}
2462
+ function W(a,b,c){if(!c)return null;a=(Sd(a)?Xd:Yd).bind(null,a);c.addEventListener(b,a,!1)}function Zd(a,b,c){if(!c)return null;a=(Sd(a)?Xd:Yd).bind(null,a);c.addEventListener(b,a,!0)}function Xd(a,b){bc(Yd,a,b)}
2463
+ function Yd(a,b){if(Vd){var c=hc(b);c=Ua(c);null!==c&&"number"===typeof c.tag&&2!==xd(c)&&(c=null);if(Td.length){var d=Td.pop();d.topLevelType=a;d.nativeEvent=b;d.targetInst=c;a=d}else a={topLevelType:a,nativeEvent:b,targetInst:c,ancestors:[]};try{ec(Ud,a)}finally{a.topLevelType=null,a.nativeEvent=null,a.targetInst=null,a.ancestors.length=0,10>Td.length&&Td.push(a)}}}
2464
+ var $d=Object.freeze({get _enabled(){return Vd},setEnabled:Wd,isEnabled:function(){return Vd},trapBubbledEvent:W,trapCapturedEvent:Zd,dispatchEvent:Yd});function ae(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;c["ms"+a]="MS"+b;c["O"+a]="o"+b.toLowerCase();return c}
2465
+ var be={animationend:ae("Animation","AnimationEnd"),animationiteration:ae("Animation","AnimationIteration"),animationstart:ae("Animation","AnimationStart"),transitionend:ae("Transition","TransitionEnd")},ce={},de={};m.canUseDOM&&(de=document.createElement("div").style,"AnimationEvent"in window||(delete be.animationend.animation,delete be.animationiteration.animation,delete be.animationstart.animation),"TransitionEvent"in window||delete be.transitionend.transition);
2466
+ function ee(a){if(ce[a])return ce[a];if(!be[a])return a;var b=be[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in de)return ce[a]=b[c];return a}
2467
+ var fe={topAnimationEnd:ee("animationend"),topAnimationIteration:ee("animationiteration"),topAnimationStart:ee("animationstart"),topBlur:"blur",topCancel:"cancel",topChange:"change",topClick:"click",topClose:"close",topCompositionEnd:"compositionend",topCompositionStart:"compositionstart",topCompositionUpdate:"compositionupdate",topContextMenu:"contextmenu",topCopy:"copy",topCut:"cut",topDoubleClick:"dblclick",topDrag:"drag",topDragEnd:"dragend",topDragEnter:"dragenter",topDragExit:"dragexit",topDragLeave:"dragleave",
2468
+ topDragOver:"dragover",topDragStart:"dragstart",topDrop:"drop",topFocus:"focus",topInput:"input",topKeyDown:"keydown",topKeyPress:"keypress",topKeyUp:"keyup",topLoad:"load",topLoadStart:"loadstart",topMouseDown:"mousedown",topMouseMove:"mousemove",topMouseOut:"mouseout",topMouseOver:"mouseover",topMouseUp:"mouseup",topPaste:"paste",topScroll:"scroll",topSelectionChange:"selectionchange",topTextInput:"textInput",topToggle:"toggle",topTouchCancel:"touchcancel",topTouchEnd:"touchend",topTouchMove:"touchmove",
2469
+ topTouchStart:"touchstart",topTransitionEnd:ee("transitionend"),topWheel:"wheel"},ge={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",
2470
+ topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},he={},ie=0,je="_reactListenersID"+(""+Math.random()).slice(2);function ke(a){Object.prototype.hasOwnProperty.call(a,je)||(a[je]=ie++,he[a[je]]={});return he[a[je]]}function le(a){for(;a&&a.firstChild;)a=a.firstChild;return a}
2471
+ function me(a,b){var c=le(a);a=0;for(var d;c;){if(3===c.nodeType){d=a+c.textContent.length;if(a<=b&&d>=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=le(c)}}function ne(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&"text"===a.type||"textarea"===b||"true"===a.contentEditable)}
2472
+ var oe=m.canUseDOM&&"documentMode"in document&&11>=document.documentMode,pe={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:"topBlur topContextMenu topFocus topKeyDown topKeyUp topMouseDown topMouseUp topSelectionChange".split(" ")}},qe=null,re=null,se=null,te=!1;
2473
+ function ue(a,b){if(te||null==qe||qe!==fa())return null;var c=qe;"selectionStart"in c&&ne(c)?c={start:c.selectionStart,end:c.selectionEnd}:window.getSelection?(c=window.getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset}):c=void 0;return se&&ha(se,c)?null:(se=c,a=N.getPooled(pe.select,re,a,b),a.type="select",a.target=qe,ib(a),a)}
2474
+ var ve={eventTypes:pe,extractEvents:function(a,b,c,d){var e=d.window===d?d.document:9===d.nodeType?d:d.ownerDocument,f;if(!(f=!e)){a:{e=ke(e);f=va.onSelect;for(var h=0;h<f.length;h++){var g=f[h];if(!e.hasOwnProperty(g)||!e[g]){e=!1;break a}}e=!0}f=!e}if(f)return null;e=b?Va(b):window;switch(a){case "topFocus":if(gc(e)||"true"===e.contentEditable)qe=e,re=b,se=null;break;case "topBlur":se=re=qe=null;break;case "topMouseDown":te=!0;break;case "topContextMenu":case "topMouseUp":return te=!1,ue(c,d);case "topSelectionChange":if(oe)break;
2475
+ case "topKeyDown":case "topKeyUp":return ue(c,d)}return null}};Na.injectEventPluginOrder("ResponderEventPlugin SimpleEventPlugin TapEventPlugin EnterLeaveEventPlugin ChangeEventPlugin SelectEventPlugin BeforeInputEventPlugin".split(" "));Da=bb.getFiberCurrentPropsFromNode;Ea=bb.getInstanceFromNode;Fa=bb.getNodeFromInstance;Na.injectEventPluginsByName({SimpleEventPlugin:Rd,EnterLeaveEventPlugin:wd,ChangeEventPlugin:pd,SelectEventPlugin:ve,BeforeInputEventPlugin:Rb});
2476
+ function xe(a,b,c,d){this.tag=a;this.key=c;this.stateNode=this.type=null;this.sibling=this.child=this["return"]=null;this.index=0;this.ref=null;this.pendingProps=b;this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.effectTag=0;this.lastEffect=this.firstEffect=this.nextEffect=null;this.expirationTime=0;this.alternate=null}
2477
+ function ze(a,b,c){var d=a.alternate;null===d?(d=new xe(a.tag,b,a.key,a.mode),d.type=a.type,d.stateNode=a.stateNode,d.alternate=a,a.alternate=d):(d.pendingProps=b,d.effectTag=0,d.nextEffect=null,d.firstEffect=null,d.lastEffect=null);d.expirationTime=c;d.child=a.child;d.memoizedProps=a.memoizedProps;d.memoizedState=a.memoizedState;d.updateQueue=a.updateQueue;d.sibling=a.sibling;d.index=a.index;d.ref=a.ref;return d}
2478
+ function Ae(a,b,c){var d=a.type,e=a.key;a=a.props;var f=void 0;if("function"===typeof d)f=d.prototype&&d.prototype.isReactComponent?2:0;else if("string"===typeof d)f=5;else switch(d){case sc:return Be(a.children,b,c,e);case wc:f=11;b|=3;break;case tc:f=11;b|=2;break;case pc:f=7;break;case qc:f=9;break;default:if("object"===typeof d&&null!==d)switch(d.$$typeof){case uc:f=13;break;case vc:f=12;break;case xc:f=14;break;default:if("number"===typeof d.tag)return b=d,b.pendingProps=a,b.expirationTime=c,
2479
+ b;D("130",null==d?d:typeof d,"")}else D("130",null==d?d:typeof d,"")}b=new xe(f,a,e,b);b.type=d;b.expirationTime=c;return b}function Be(a,b,c,d){a=new xe(10,a,d,b);a.expirationTime=c;return a}function Ce(a,b,c){a=new xe(6,a,null,b);a.expirationTime=c;return a}function De(a,b,c){b=new xe(4,null!==a.children?a.children:[],a.key,b);b.expirationTime=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}var Ee=null,Fe=null;
2480
+ function Ge(a){return function(b){try{return a(b)}catch(c){}}}function He(a){if("undefined"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var b=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(b.isDisabled||!b.supportsFiber)return!0;try{var c=b.inject(a);Ee=Ge(function(a){return b.onCommitFiberRoot(c,a)});Fe=Ge(function(a){return b.onCommitFiberUnmount(c,a)})}catch(d){}return!0}function Ie(a){"function"===typeof Ee&&Ee(a)}function Je(a){"function"===typeof Fe&&Fe(a)}new Set;
2481
+ function Ke(a){return{baseState:a,expirationTime:0,first:null,last:null,callbackList:null,hasForceUpdate:!1,isInitialized:!1,capturedValues:null}}function Le(a,b){null===a.last?a.first=a.last=b:(a.last.next=b,a.last=b);if(0===a.expirationTime||a.expirationTime>b.expirationTime)a.expirationTime=b.expirationTime}var Me=void 0,Ne=void 0;
2482
+ function Oe(a){Me=Ne=null;var b=a.alternate,c=a.updateQueue;null===c&&(c=a.updateQueue=Ke(null));null!==b?(a=b.updateQueue,null===a&&(a=b.updateQueue=Ke(null))):a=null;Me=c;Ne=a!==c?a:null}function Pe(a,b){Oe(a);a=Me;var c=Ne;null===c?Le(a,b):null===a.last||null===c.last?(Le(a,b),Le(c,b)):(Le(a,b),c.last=b)}function Qe(a,b,c,d){a=a.partialState;return"function"===typeof a?a.call(b,c,d):a}
2483
+ function Re(a,b,c,d,e,f){null!==a&&a.updateQueue===c&&(c=b.updateQueue={baseState:c.baseState,expirationTime:c.expirationTime,first:c.first,last:c.last,isInitialized:c.isInitialized,capturedValues:c.capturedValues,callbackList:null,hasForceUpdate:!1});c.expirationTime=0;c.isInitialized?a=c.baseState:(a=c.baseState=b.memoizedState,c.isInitialized=!0);for(var h=!0,g=c.first,k=!1;null!==g;){var v=g.expirationTime;if(v>f){var l=c.expirationTime;if(0===l||l>v)c.expirationTime=v;k||(k=!0,c.baseState=a)}else{k||
2484
+ (c.first=g.next,null===c.first&&(c.last=null));if(g.isReplace)a=Qe(g,d,a,e),h=!0;else if(v=Qe(g,d,a,e))a=h?A({},a,v):A(a,v),h=!1;g.isForced&&(c.hasForceUpdate=!0);null!==g.callback&&(v=c.callbackList,null===v&&(v=c.callbackList=[]),v.push(g));null!==g.capturedValue&&(v=c.capturedValues,null===v?c.capturedValues=[g.capturedValue]:v.push(g.capturedValue))}g=g.next}null!==c.callbackList?b.effectTag|=32:null!==c.first||c.hasForceUpdate||null!==c.capturedValues||(b.updateQueue=null);k||(c.baseState=a);
2485
+ return a}function Se(a,b){var c=a.callbackList;if(null!==c)for(a.callbackList=null,a=0;a<c.length;a++){var d=c[a],e=d.callback;d.callback=null;"function"!==typeof e?D("191",e):void 0;e.call(b)}}
2486
+ function Te(a,b,c,d,e){function f(a,b,c,d,e,f){if(null===b||null!==a.updateQueue&&a.updateQueue.hasForceUpdate)return!0;var n=a.stateNode;a=a.type;return"function"===typeof n.shouldComponentUpdate?n.shouldComponentUpdate(c,e,f):a.prototype&&a.prototype.isPureReactComponent?!ha(b,c)||!ha(d,e):!0}function h(a,b){b.updater=r;a.stateNode=b;b._reactInternalFiber=a}function g(a,b,c,d){a=b.state;"function"===typeof b.componentWillReceiveProps&&b.componentWillReceiveProps(c,d);"function"===typeof b.UNSAFE_componentWillReceiveProps&&
2487
+ b.UNSAFE_componentWillReceiveProps(c,d);b.state!==a&&r.enqueueReplaceState(b,b.state,null)}function k(a,b,c,d){a=a.type;if("function"===typeof a.getDerivedStateFromProps)return a.getDerivedStateFromProps.call(null,c,d)}var v=a.cacheContext,l=a.getMaskedContext,p=a.getUnmaskedContext,z=a.isContextConsumer,B=a.hasContextChanged,r={isMounted:yd,enqueueSetState:function(a,d,e){a=a._reactInternalFiber;e=void 0===e?null:e;var f=c(a);Pe(a,{expirationTime:f,partialState:d,callback:e,isReplace:!1,isForced:!1,
2488
+ capturedValue:null,next:null});b(a,f)},enqueueReplaceState:function(a,d,e){a=a._reactInternalFiber;e=void 0===e?null:e;var f=c(a);Pe(a,{expirationTime:f,partialState:d,callback:e,isReplace:!0,isForced:!1,capturedValue:null,next:null});b(a,f)},enqueueForceUpdate:function(a,d){a=a._reactInternalFiber;d=void 0===d?null:d;var e=c(a);Pe(a,{expirationTime:e,partialState:null,callback:d,isReplace:!1,isForced:!0,capturedValue:null,next:null});b(a,e)}};return{adoptClassInstance:h,callGetDerivedStateFromProps:k,
2489
+ constructClassInstance:function(a,b){var c=a.type,d=p(a),e=z(a),f=e?l(a,d):ka;c=new c(b,f);var n=null!==c.state&&void 0!==c.state?c.state:null;h(a,c);a.memoizedState=n;b=k(a,c,b,n);null!==b&&void 0!==b&&(a.memoizedState=A({},a.memoizedState,b));e&&v(a,d,f);return c},mountClassInstance:function(a,b){var c=a.type,d=a.alternate,e=a.stateNode,f=a.pendingProps,n=p(a);e.props=f;e.state=a.memoizedState;e.refs=ka;e.context=l(a,n);"function"===typeof c.getDerivedStateFromProps||"function"===typeof e.getSnapshotBeforeUpdate||
2490
+ "function"!==typeof e.UNSAFE_componentWillMount&&"function"!==typeof e.componentWillMount||(c=e.state,"function"===typeof e.componentWillMount&&e.componentWillMount(),"function"===typeof e.UNSAFE_componentWillMount&&e.UNSAFE_componentWillMount(),c!==e.state&&r.enqueueReplaceState(e,e.state,null),c=a.updateQueue,null!==c&&(e.state=Re(d,a,c,e,f,b)));"function"===typeof e.componentDidMount&&(a.effectTag|=4)},resumeMountClassInstance:function(a,b){var c=a.type,n=a.stateNode;n.props=a.memoizedProps;n.state=
2491
+ a.memoizedState;var h=a.memoizedProps,r=a.pendingProps,z=n.context,q=p(a);q=l(a,q);(c="function"===typeof c.getDerivedStateFromProps||"function"===typeof n.getSnapshotBeforeUpdate)||"function"!==typeof n.UNSAFE_componentWillReceiveProps&&"function"!==typeof n.componentWillReceiveProps||(h!==r||z!==q)&&g(a,n,r,q);z=a.memoizedState;b=null!==a.updateQueue?Re(null,a,a.updateQueue,n,r,b):z;var u=void 0;h!==r&&(u=k(a,n,r,b));if(null!==u&&void 0!==u){b=null===b||void 0===b?u:A({},b,u);var t=a.updateQueue;
2492
+ null!==t&&(t.baseState=A({},t.baseState,u))}if(!(h!==r||z!==b||B()||null!==a.updateQueue&&a.updateQueue.hasForceUpdate))return"function"===typeof n.componentDidMount&&(a.effectTag|=4),!1;(h=f(a,h,r,z,b,q))?(c||"function"!==typeof n.UNSAFE_componentWillMount&&"function"!==typeof n.componentWillMount||("function"===typeof n.componentWillMount&&n.componentWillMount(),"function"===typeof n.UNSAFE_componentWillMount&&n.UNSAFE_componentWillMount()),"function"===typeof n.componentDidMount&&(a.effectTag|=
2493
+ 4)):("function"===typeof n.componentDidMount&&(a.effectTag|=4),d(a,r),e(a,b));n.props=r;n.state=b;n.context=q;return h},updateClassInstance:function(a,b,c){var n=b.type,x=b.stateNode;x.props=b.memoizedProps;x.state=b.memoizedState;var h=b.memoizedProps,r=b.pendingProps,q=x.context,u=p(b);u=l(b,u);(n="function"===typeof n.getDerivedStateFromProps||"function"===typeof x.getSnapshotBeforeUpdate)||"function"!==typeof x.UNSAFE_componentWillReceiveProps&&"function"!==typeof x.componentWillReceiveProps||
2494
+ (h!==r||q!==u)&&g(b,x,r,u);q=b.memoizedState;c=null!==b.updateQueue?Re(a,b,b.updateQueue,x,r,c):q;var t=void 0;h!==r&&(t=k(b,x,r,c));if(null!==t&&void 0!==t){c=null===c||void 0===c?t:A({},c,t);var y=b.updateQueue;null!==y&&(y.baseState=A({},y.baseState,t))}if(!(h!==r||q!==c||B()||null!==b.updateQueue&&b.updateQueue.hasForceUpdate))return"function"!==typeof x.componentDidUpdate||h===a.memoizedProps&&q===a.memoizedState||(b.effectTag|=4),"function"!==typeof x.getSnapshotBeforeUpdate||h===a.memoizedProps&&
2495
+ q===a.memoizedState||(b.effectTag|=2048),!1;(t=f(b,h,r,q,c,u))?(n||"function"!==typeof x.UNSAFE_componentWillUpdate&&"function"!==typeof x.componentWillUpdate||("function"===typeof x.componentWillUpdate&&x.componentWillUpdate(r,c,u),"function"===typeof x.UNSAFE_componentWillUpdate&&x.UNSAFE_componentWillUpdate(r,c,u)),"function"===typeof x.componentDidUpdate&&(b.effectTag|=4),"function"===typeof x.getSnapshotBeforeUpdate&&(b.effectTag|=2048)):("function"!==typeof x.componentDidUpdate||h===a.memoizedProps&&
2496
+ q===a.memoizedState||(b.effectTag|=4),"function"!==typeof x.getSnapshotBeforeUpdate||h===a.memoizedProps&&q===a.memoizedState||(b.effectTag|=2048),d(b,r),e(b,c));x.props=r;x.state=c;x.context=u;return t}}}var Ue=Array.isArray;
2497
+ function Ve(a,b,c){a=c.ref;if(null!==a&&"function"!==typeof a&&"object"!==typeof a){if(c._owner){c=c._owner;var d=void 0;c&&(2!==c.tag?D("110"):void 0,d=c.stateNode);d?void 0:D("147",a);var e=""+a;if(null!==b&&null!==b.ref&&b.ref._stringRef===e)return b.ref;b=function(a){var b=d.refs===ka?d.refs={}:d.refs;null===a?delete b[e]:b[e]=a};b._stringRef=e;return b}"string"!==typeof a?D("148"):void 0;c._owner?void 0:D("254",a)}return a}
2498
+ function We(a,b){"textarea"!==a.type&&D("31","[object Object]"===Object.prototype.toString.call(b)?"object with keys {"+Object.keys(b).join(", ")+"}":b,"")}
2499
+ function Xe(a){function b(b,c){if(a){var d=b.lastEffect;null!==d?(d.nextEffect=c,b.lastEffect=c):b.firstEffect=b.lastEffect=c;c.nextEffect=null;c.effectTag=8}}function c(c,d){if(!a)return null;for(;null!==d;)b(c,d),d=d.sibling;return null}function d(a,b){for(a=new Map;null!==b;)null!==b.key?a.set(b.key,b):a.set(b.index,b),b=b.sibling;return a}function e(a,b,c){a=ze(a,b,c);a.index=0;a.sibling=null;return a}function f(b,c,d){b.index=d;if(!a)return c;d=b.alternate;if(null!==d)return d=d.index,d<c?(b.effectTag=
2500
+ 2,c):d;b.effectTag=2;return c}function h(b){a&&null===b.alternate&&(b.effectTag=2);return b}function g(a,b,c,d){if(null===b||6!==b.tag)return b=Ce(c,a.mode,d),b["return"]=a,b;b=e(b,c,d);b["return"]=a;return b}function k(a,b,c,d){if(null!==b&&b.type===c.type)return d=e(b,c.props,d),d.ref=Ve(a,b,c),d["return"]=a,d;d=Ae(c,a.mode,d);d.ref=Ve(a,b,c);d["return"]=a;return d}function v(a,b,c,d){if(null===b||4!==b.tag||b.stateNode.containerInfo!==c.containerInfo||b.stateNode.implementation!==c.implementation)return b=
2501
+ De(c,a.mode,d),b["return"]=a,b;b=e(b,c.children||[],d);b["return"]=a;return b}function l(a,b,c,d,f){if(null===b||10!==b.tag)return b=Be(c,a.mode,d,f),b["return"]=a,b;b=e(b,c,d);b["return"]=a;return b}function p(a,b,c){if("string"===typeof b||"number"===typeof b)return b=Ce(""+b,a.mode,c),b["return"]=a,b;if("object"===typeof b&&null!==b){switch(b.$$typeof){case oc:return c=Ae(b,a.mode,c),c.ref=Ve(a,null,b),c["return"]=a,c;case rc:return b=De(b,a.mode,c),b["return"]=a,b}if(Ue(b)||zc(b))return b=Be(b,
2502
+ a.mode,c,null),b["return"]=a,b;We(a,b)}return null}function z(a,b,c,d){var e=null!==b?b.key:null;if("string"===typeof c||"number"===typeof c)return null!==e?null:g(a,b,""+c,d);if("object"===typeof c&&null!==c){switch(c.$$typeof){case oc:return c.key===e?c.type===sc?l(a,b,c.props.children,d,e):k(a,b,c,d):null;case rc:return c.key===e?v(a,b,c,d):null}if(Ue(c)||zc(c))return null!==e?null:l(a,b,c,d,null);We(a,c)}return null}function B(a,b,c,d,e){if("string"===typeof d||"number"===typeof d)return a=a.get(c)||
2503
+ null,g(b,a,""+d,e);if("object"===typeof d&&null!==d){switch(d.$$typeof){case oc:return a=a.get(null===d.key?c:d.key)||null,d.type===sc?l(b,a,d.props.children,e,d.key):k(b,a,d,e);case rc:return a=a.get(null===d.key?c:d.key)||null,v(b,a,d,e)}if(Ue(d)||zc(d))return a=a.get(c)||null,l(b,a,d,e,null);We(b,d)}return null}function r(e,l,g,h){for(var r=null,k=null,q=l,u=l=0,t=null;null!==q&&u<g.length;u++){q.index>u?(t=q,q=null):t=q.sibling;var n=z(e,q,g[u],h);if(null===n){null===q&&(q=t);break}a&&q&&null===
2504
+ n.alternate&&b(e,q);l=f(n,l,u);null===k?r=n:k.sibling=n;k=n;q=t}if(u===g.length)return c(e,q),r;if(null===q){for(;u<g.length;u++)if(q=p(e,g[u],h))l=f(q,l,u),null===k?r=q:k.sibling=q,k=q;return r}for(q=d(e,q);u<g.length;u++)if(t=B(q,e,u,g[u],h)){if(a&&null!==t.alternate)q["delete"](null===t.key?u:t.key);l=f(t,l,u);null===k?r=t:k.sibling=t;k=t}a&&q.forEach(function(a){return b(e,a)});return r}function Q(e,l,g,h){var r=zc(g);"function"!==typeof r?D("150"):void 0;g=r.call(g);null==g?D("151"):void 0;for(var k=
2505
+ r=null,q=l,u=l=0,t=null,n=g.next();null!==q&&!n.done;u++,n=g.next()){q.index>u?(t=q,q=null):t=q.sibling;var H=z(e,q,n.value,h);if(null===H){q||(q=t);break}a&&q&&null===H.alternate&&b(e,q);l=f(H,l,u);null===k?r=H:k.sibling=H;k=H;q=t}if(n.done)return c(e,q),r;if(null===q){for(;!n.done;u++,n=g.next())n=p(e,n.value,h),null!==n&&(l=f(n,l,u),null===k?r=n:k.sibling=n,k=n);return r}for(q=d(e,q);!n.done;u++,n=g.next())if(n=B(q,e,u,n.value,h),null!==n){if(a&&null!==n.alternate)q["delete"](null===n.key?u:n.key);
2506
+ l=f(n,l,u);null===k?r=n:k.sibling=n;k=n}a&&q.forEach(function(a){return b(e,a)});return r}return function(a,d,f,l){"object"===typeof f&&null!==f&&f.type===sc&&null===f.key&&(f=f.props.children);var g="object"===typeof f&&null!==f;if(g)switch(f.$$typeof){case oc:a:{var k=f.key;for(g=d;null!==g;){if(g.key===k)if(10===g.tag?f.type===sc:g.type===f.type){c(a,g.sibling);d=e(g,f.type===sc?f.props.children:f.props,l);d.ref=Ve(a,g,f);d["return"]=a;a=d;break a}else{c(a,g);break}else b(a,g);g=g.sibling}f.type===
2507
+ sc?(d=Be(f.props.children,a.mode,l,f.key),d["return"]=a,a=d):(l=Ae(f,a.mode,l),l.ref=Ve(a,d,f),l["return"]=a,a=l)}return h(a);case rc:a:{for(g=f.key;null!==d;){if(d.key===g)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[],l);d["return"]=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=De(f,a.mode,l);d["return"]=a;a=d}return h(a)}if("string"===typeof f||"number"===typeof f)return f=""+f,null!==d&&
2508
+ 6===d.tag?(c(a,d.sibling),d=e(d,f,l),d["return"]=a,a=d):(c(a,d),d=Ce(f,a.mode,l),d["return"]=a,a=d),h(a);if(Ue(f))return r(a,d,f,l);if(zc(f))return Q(a,d,f,l);g&&We(a,f);if("undefined"===typeof f)switch(a.tag){case 2:case 1:l=a.type,D("152",l.displayName||l.name||"Component")}return c(a,d)}}var Ye=Xe(!0),Ze=Xe(!1);
2509
+ function $e(a,b,c,d,e,f,h){function g(a,b,c){k(a,b,c,b.expirationTime)}function k(a,b,c,d){b.child=null===a?Ze(b,null,c,d):Ye(b,a.child,c,d)}function v(a,b){var c=b.ref;if(null===a&&null!==c||null!==a&&a.ref!==c)b.effectTag|=128}function l(a,b,c,d,e,f){v(a,b);if(!c&&!e)return d&&y(b,!1),r(a,b);c=b.stateNode;nc.current=b;var l=e?null:c.render();b.effectTag|=1;e&&(k(a,b,null,f),b.child=null);k(a,b,l,f);b.memoizedState=c.state;b.memoizedProps=c.props;d&&y(b,!0);return b.child}function p(a){var b=a.stateNode;
2510
+ b.pendingContext?t(a,b.pendingContext,b.pendingContext!==b.context):b.context&&t(a,b.context,!1);Y(a,b.containerInfo)}function z(a,b,c,d){var e=a.child;for(null!==e&&(e["return"]=a);null!==e;){switch(e.tag){case 12:var f=e.stateNode|0;if(e.type===b&&0!==(f&c)){for(f=e;null!==f;){var l=f.alternate;if(0===f.expirationTime||f.expirationTime>d)f.expirationTime=d,null!==l&&(0===l.expirationTime||l.expirationTime>d)&&(l.expirationTime=d);else if(null!==l&&(0===l.expirationTime||l.expirationTime>d))l.expirationTime=
2511
+ d;else break;f=f["return"]}f=null}else f=e.child;break;case 13:f=e.type===a.type?null:e.child;break;default:f=e.child}if(null!==f)f["return"]=e;else for(f=e;null!==f;){if(f===a){f=null;break}e=f.sibling;if(null!==e){f=e;break}f=f["return"]}e=f}}function B(a,b,c){var d=b.type._context,e=b.pendingProps,f=b.memoizedProps;if(!q()&&f===e)return b.stateNode=0,G(b),r(a,b);var l=e.value;b.memoizedProps=e;if(null===f)l=1073741823;else if(f.value===e.value){if(f.children===e.children)return b.stateNode=0,G(b),
2512
+ r(a,b);l=0}else{var h=f.value;if(h===l&&(0!==h||1/h===1/l)||h!==h&&l!==l){if(f.children===e.children)return b.stateNode=0,G(b),r(a,b);l=0}else if(l="function"===typeof d._calculateChangedBits?d._calculateChangedBits(h,l):1073741823,l|=0,0===l){if(f.children===e.children)return b.stateNode=0,G(b),r(a,b)}else z(b,d,l,c)}b.stateNode=l;G(b);g(a,b,e.children);return b.child}function r(a,b){null!==a&&b.child!==a.child?D("153"):void 0;if(null!==b.child){a=b.child;var c=ze(a,a.pendingProps,a.expirationTime);
2513
+ b.child=c;for(c["return"]=b;null!==a.sibling;)a=a.sibling,c=c.sibling=ze(a,a.pendingProps,a.expirationTime),c["return"]=b;c.sibling=null}return b.child}var Q=a.shouldSetTextContent,n=a.shouldDeprioritizeSubtree,x=b.pushHostContext,Y=b.pushHostContainer,G=d.pushProvider,R=c.getMaskedContext,S=c.getUnmaskedContext,q=c.hasContextChanged,u=c.pushContextProvider,t=c.pushTopLevelContextObject,y=c.invalidateContextProvider,H=e.enterHydrationState,Wa=e.resetHydrationState,Cb=e.tryToClaimNextHydratableInstance;
2514
+ a=Te(c,f,h,function(a,b){a.memoizedProps=b},function(a,b){a.memoizedState=b});var Jc=a.adoptClassInstance,Kc=a.callGetDerivedStateFromProps,Lc=a.constructClassInstance,Db=a.mountClassInstance,Mc=a.resumeMountClassInstance,Eb=a.updateClassInstance;return{beginWork:function(a,b,c){if(0===b.expirationTime||b.expirationTime>c){switch(b.tag){case 3:p(b);break;case 2:u(b);break;case 4:Y(b,b.stateNode.containerInfo);break;case 13:G(b)}return null}switch(b.tag){case 0:null!==a?D("155"):void 0;var d=b.type,
2515
+ e=b.pendingProps,f=S(b);f=R(b,f);d=d(e,f);b.effectTag|=1;"object"===typeof d&&null!==d&&"function"===typeof d.render&&void 0===d.$$typeof?(f=b.type,b.tag=2,b.memoizedState=null!==d.state&&void 0!==d.state?d.state:null,"function"===typeof f.getDerivedStateFromProps&&(e=Kc(b,d,e,b.memoizedState),null!==e&&void 0!==e&&(b.memoizedState=A({},b.memoizedState,e))),e=u(b),Jc(b,d),Db(b,c),a=l(a,b,!0,e,!1,c)):(b.tag=1,g(a,b,d),b.memoizedProps=e,a=b.child);return a;case 1:return e=b.type,c=b.pendingProps,q()||
2516
+ b.memoizedProps!==c?(d=S(b),d=R(b,d),e=e(c,d),b.effectTag|=1,g(a,b,e),b.memoizedProps=c,a=b.child):a=r(a,b),a;case 2:e=u(b);null===a?null===b.stateNode?(Lc(b,b.pendingProps),Db(b,c),d=!0):d=Mc(b,c):d=Eb(a,b,c);f=!1;var h=b.updateQueue;null!==h&&null!==h.capturedValues&&(f=d=!0);return l(a,b,d,e,f,c);case 3:a:if(p(b),d=b.updateQueue,null!==d){f=b.memoizedState;e=Re(a,b,d,null,null,c);b.memoizedState=e;d=b.updateQueue;if(null!==d&&null!==d.capturedValues)d=null;else if(f===e){Wa();a=r(a,b);break a}else d=
2517
+ e.element;f=b.stateNode;(null===a||null===a.child)&&f.hydrate&&H(b)?(b.effectTag|=2,b.child=Ze(b,null,d,c)):(Wa(),g(a,b,d));b.memoizedState=e;a=b.child}else Wa(),a=r(a,b);return a;case 5:a:{x(b);null===a&&Cb(b);e=b.type;h=b.memoizedProps;d=b.pendingProps;f=null!==a?a.memoizedProps:null;if(!q()&&h===d){if(h=b.mode&1&&n(e,d))b.expirationTime=1073741823;if(!h||1073741823!==c){a=r(a,b);break a}}h=d.children;Q(e,d)?h=null:f&&Q(e,f)&&(b.effectTag|=16);v(a,b);1073741823!==c&&b.mode&1&&n(e,d)?(b.expirationTime=
2518
+ 1073741823,b.memoizedProps=d,a=null):(g(a,b,h),b.memoizedProps=d,a=b.child)}return a;case 6:return null===a&&Cb(b),b.memoizedProps=b.pendingProps,null;case 8:b.tag=7;case 7:return e=b.pendingProps,q()||b.memoizedProps!==e||(e=b.memoizedProps),d=e.children,b.stateNode=null===a?Ze(b,b.stateNode,d,c):Ye(b,a.stateNode,d,c),b.memoizedProps=e,b.stateNode;case 9:return null;case 4:return Y(b,b.stateNode.containerInfo),e=b.pendingProps,q()||b.memoizedProps!==e?(null===a?b.child=Ye(b,null,e,c):g(a,b,e),b.memoizedProps=
2519
+ e,a=b.child):a=r(a,b),a;case 14:return c=b.type.render,c=c(b.pendingProps,b.ref),g(a,b,c),b.memoizedProps=c,b.child;case 10:return c=b.pendingProps,q()||b.memoizedProps!==c?(g(a,b,c),b.memoizedProps=c,a=b.child):a=r(a,b),a;case 11:return c=b.pendingProps.children,q()||null!==c&&b.memoizedProps!==c?(g(a,b,c),b.memoizedProps=c,a=b.child):a=r(a,b),a;case 13:return B(a,b,c);case 12:a:{d=b.type;f=b.pendingProps;h=b.memoizedProps;e=d._currentValue;var t=d._changedBits;if(q()||0!==t||h!==f){b.memoizedProps=
2520
+ f;var k=f.unstable_observedBits;if(void 0===k||null===k)k=1073741823;b.stateNode=k;if(0!==(t&k))z(b,d,t,c);else if(h===f){a=r(a,b);break a}c=f.children;c=c(e);g(a,b,c);a=b.child}else a=r(a,b)}return a;default:D("156")}}}}
2521
+ function af(a,b,c,d,e){function f(a){a.effectTag|=4}var h=a.createInstance,g=a.createTextInstance,k=a.appendInitialChild,v=a.finalizeInitialChildren,l=a.prepareUpdate,p=a.persistence,z=b.getRootHostContainer,B=b.popHostContext,r=b.getHostContext,Q=b.popHostContainer,n=c.popContextProvider,x=c.popTopLevelContextObject,Y=d.popProvider,G=e.prepareToHydrateHostInstance,R=e.prepareToHydrateHostTextInstance,S=e.popHydrationState,q=void 0,u=void 0,t=void 0;a.mutation?(q=function(){},u=function(a,b,c){(b.updateQueue=
2522
+ c)&&f(b)},t=function(a,b,c,d){c!==d&&f(b)}):p?D("235"):D("236");return{completeWork:function(a,b,c){var d=b.pendingProps;switch(b.tag){case 1:return null;case 2:return n(b),a=b.stateNode,d=b.updateQueue,null!==d&&null!==d.capturedValues&&(b.effectTag&=-65,"function"===typeof a.componentDidCatch?b.effectTag|=256:d.capturedValues=null),null;case 3:Q(b);x(b);d=b.stateNode;d.pendingContext&&(d.context=d.pendingContext,d.pendingContext=null);if(null===a||null===a.child)S(b),b.effectTag&=-3;q(b);a=b.updateQueue;
2523
+ null!==a&&null!==a.capturedValues&&(b.effectTag|=256);return null;case 5:B(b);c=z();var e=b.type;if(null!==a&&null!=b.stateNode){var p=a.memoizedProps,H=b.stateNode,y=r();H=l(H,e,p,d,c,y);u(a,b,H,e,p,d,c,y);a.ref!==b.ref&&(b.effectTag|=128)}else{if(!d)return null===b.stateNode?D("166"):void 0,null;a=r();if(S(b))G(b,c,a)&&f(b);else{p=h(e,d,c,a,b);a:for(y=b.child;null!==y;){if(5===y.tag||6===y.tag)k(p,y.stateNode);else if(4!==y.tag&&null!==y.child){y.child["return"]=y;y=y.child;continue}if(y===b)break;
2524
+ for(;null===y.sibling;){if(null===y["return"]||y["return"]===b)break a;y=y["return"]}y.sibling["return"]=y["return"];y=y.sibling}v(p,e,d,c,a)&&f(b);b.stateNode=p}null!==b.ref&&(b.effectTag|=128)}return null;case 6:if(a&&null!=b.stateNode)t(a,b,a.memoizedProps,d);else{if("string"!==typeof d)return null===b.stateNode?D("166"):void 0,null;a=z();c=r();S(b)?R(b)&&f(b):b.stateNode=g(d,a,c,b)}return null;case 7:(d=b.memoizedProps)?void 0:D("165");b.tag=8;e=[];a:for((p=b.stateNode)&&(p["return"]=b);null!==
2525
+ p;){if(5===p.tag||6===p.tag||4===p.tag)D("247");else if(9===p.tag)e.push(p.pendingProps.value);else if(null!==p.child){p.child["return"]=p;p=p.child;continue}for(;null===p.sibling;){if(null===p["return"]||p["return"]===b)break a;p=p["return"]}p.sibling["return"]=p["return"];p=p.sibling}p=d.handler;d=p(d.props,e);b.child=Ye(b,null!==a?a.child:null,d,c);return b.child;case 8:return b.tag=7,null;case 9:return null;case 14:return null;case 10:return null;case 11:return null;case 4:return Q(b),q(b),null;
2526
+ case 13:return Y(b),null;case 12:return null;case 0:D("167");default:D("156")}}}}
2527
+ function bf(a,b,c,d,e){var f=a.popHostContainer,h=a.popHostContext,g=b.popContextProvider,k=b.popTopLevelContextObject,v=c.popProvider;return{throwException:function(a,b,c){b.effectTag|=512;b.firstEffect=b.lastEffect=null;b={value:c,source:b,stack:Bc(b)};do{switch(a.tag){case 3:Oe(a);a.updateQueue.capturedValues=[b];a.effectTag|=1024;return;case 2:if(c=a.stateNode,0===(a.effectTag&64)&&null!==c&&"function"===typeof c.componentDidCatch&&!e(c)){Oe(a);c=a.updateQueue;var d=c.capturedValues;null===d?
2528
+ c.capturedValues=[b]:d.push(b);a.effectTag|=1024;return}}a=a["return"]}while(null!==a)},unwindWork:function(a){switch(a.tag){case 2:g(a);var b=a.effectTag;return b&1024?(a.effectTag=b&-1025|64,a):null;case 3:return f(a),k(a),b=a.effectTag,b&1024?(a.effectTag=b&-1025|64,a):null;case 5:return h(a),null;case 4:return f(a),null;case 13:return v(a),null;default:return null}},unwindInterruptedWork:function(a){switch(a.tag){case 2:g(a);break;case 3:f(a);k(a);break;case 5:h(a);break;case 4:f(a);break;case 13:v(a)}}}}
2529
+ function cf(a,b){var c=b.source;null===b.stack&&Bc(c);null!==c&&Ac(c);b=b.value;null!==a&&2===a.tag&&Ac(a);try{b&&b.suppressReactErrorLogging||console.error(b)}catch(d){d&&d.suppressReactErrorLogging||console.error(d)}}
2530
+ function df(a,b,c,d,e){function f(a){var c=a.ref;if(null!==c)if("function"===typeof c)try{c(null)}catch(t){b(a,t)}else c.current=null}function h(a){"function"===typeof Je&&Je(a);switch(a.tag){case 2:f(a);var c=a.stateNode;if("function"===typeof c.componentWillUnmount)try{c.props=a.memoizedProps,c.state=a.memoizedState,c.componentWillUnmount()}catch(t){b(a,t)}break;case 5:f(a);break;case 7:g(a.stateNode);break;case 4:p&&v(a)}}function g(a){for(var b=a;;)if(h(b),null===b.child||p&&4===b.tag){if(b===
2531
+ a)break;for(;null===b.sibling;){if(null===b["return"]||b["return"]===a)return;b=b["return"]}b.sibling["return"]=b["return"];b=b.sibling}else b.child["return"]=b,b=b.child}function k(a){return 5===a.tag||3===a.tag||4===a.tag}function v(a){for(var b=a,c=!1,d=void 0,e=void 0;;){if(!c){c=b["return"];a:for(;;){null===c?D("160"):void 0;switch(c.tag){case 5:d=c.stateNode;e=!1;break a;case 3:d=c.stateNode.containerInfo;e=!0;break a;case 4:d=c.stateNode.containerInfo;e=!0;break a}c=c["return"]}c=!0}if(5===
2532
+ b.tag||6===b.tag)g(b),e?S(d,b.stateNode):R(d,b.stateNode);else if(4===b.tag?d=b.stateNode.containerInfo:h(b),null!==b.child){b.child["return"]=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b["return"]||b["return"]===a)return;b=b["return"];4===b.tag&&(c=!1)}b.sibling["return"]=b["return"];b=b.sibling}}var l=a.getPublicInstance,p=a.mutation;a=a.persistence;p||(a?D("235"):D("236"));var z=p.commitMount,B=p.commitUpdate,r=p.resetTextContent,Q=p.commitTextUpdate,n=p.appendChild,
2533
+ x=p.appendChildToContainer,Y=p.insertBefore,G=p.insertInContainerBefore,R=p.removeChild,S=p.removeChildFromContainer;return{commitBeforeMutationLifeCycles:function(a,b){switch(b.tag){case 2:if(b.effectTag&2048&&null!==a){var c=a.memoizedProps,d=a.memoizedState;a=b.stateNode;a.props=b.memoizedProps;a.state=b.memoizedState;b=a.getSnapshotBeforeUpdate(c,d);a.__reactInternalSnapshotBeforeUpdate=b}break;case 3:case 5:case 6:case 4:break;default:D("163")}},commitResetTextContent:function(a){r(a.stateNode)},
2534
+ commitPlacement:function(a){a:{for(var b=a["return"];null!==b;){if(k(b)){var c=b;break a}b=b["return"]}D("160");c=void 0}var d=b=void 0;switch(c.tag){case 5:b=c.stateNode;d=!1;break;case 3:b=c.stateNode.containerInfo;d=!0;break;case 4:b=c.stateNode.containerInfo;d=!0;break;default:D("161")}c.effectTag&16&&(r(b),c.effectTag&=-17);a:b:for(c=a;;){for(;null===c.sibling;){if(null===c["return"]||k(c["return"])){c=null;break a}c=c["return"]}c.sibling["return"]=c["return"];for(c=c.sibling;5!==c.tag&&6!==
2535
+ c.tag;){if(c.effectTag&2)continue b;if(null===c.child||4===c.tag)continue b;else c.child["return"]=c,c=c.child}if(!(c.effectTag&2)){c=c.stateNode;break a}}for(var e=a;;){if(5===e.tag||6===e.tag)c?d?G(b,e.stateNode,c):Y(b,e.stateNode,c):d?x(b,e.stateNode):n(b,e.stateNode);else if(4!==e.tag&&null!==e.child){e.child["return"]=e;e=e.child;continue}if(e===a)break;for(;null===e.sibling;){if(null===e["return"]||e["return"]===a)return;e=e["return"]}e.sibling["return"]=e["return"];e=e.sibling}},commitDeletion:function(a){v(a);
2536
+ a["return"]=null;a.child=null;a.alternate&&(a.alternate.child=null,a.alternate["return"]=null)},commitWork:function(a,b){switch(b.tag){case 2:break;case 5:var c=b.stateNode;if(null!=c){var d=b.memoizedProps;a=null!==a?a.memoizedProps:d;var e=b.type,f=b.updateQueue;b.updateQueue=null;null!==f&&B(c,f,e,a,d,b)}break;case 6:null===b.stateNode?D("162"):void 0;c=b.memoizedProps;Q(b.stateNode,null!==a?a.memoizedProps:c,c);break;case 3:break;default:D("163")}},commitLifeCycles:function(a,b,c){switch(c.tag){case 2:a=
2537
+ c.stateNode;if(c.effectTag&4)if(null===b)a.props=c.memoizedProps,a.state=c.memoizedState,a.componentDidMount();else{var d=b.memoizedProps;b=b.memoizedState;a.props=c.memoizedProps;a.state=c.memoizedState;a.componentDidUpdate(d,b,a.__reactInternalSnapshotBeforeUpdate)}c=c.updateQueue;null!==c&&Se(c,a);break;case 3:b=c.updateQueue;if(null!==b){a=null;if(null!==c.child)switch(c.child.tag){case 5:a=l(c.child.stateNode);break;case 2:a=c.child.stateNode}Se(b,a)}break;case 5:a=c.stateNode;null===b&&c.effectTag&
2538
+ 4&&z(a,c.type,c.memoizedProps,c);break;case 6:break;case 4:break;default:D("163")}},commitErrorLogging:function(a,b){switch(a.tag){case 2:var c=a.type;b=a.stateNode;var d=a.updateQueue;null===d||null===d.capturedValues?D("264"):void 0;var f=d.capturedValues;d.capturedValues=null;"function"!==typeof c.getDerivedStateFromCatch&&e(b);b.props=a.memoizedProps;b.state=a.memoizedState;for(c=0;c<f.length;c++){d=f[c];var l=d.value,g=d.stack;cf(a,d);b.componentDidCatch(l,{componentStack:null!==g?g:""})}break;
2539
+ case 3:c=a.updateQueue;null===c||null===c.capturedValues?D("264"):void 0;f=c.capturedValues;c.capturedValues=null;for(c=0;c<f.length;c++)d=f[c],cf(a,d),b(d.value);break;default:D("265")}},commitAttachRef:function(a){var b=a.ref;if(null!==b){var c=a.stateNode;switch(a.tag){case 5:a=l(c);break;default:a=c}"function"===typeof b?b(a):b.current=a}},commitDetachRef:function(a){a=a.ref;null!==a&&("function"===typeof a?a(null):a.current=null)}}}var ef={};
2540
+ function ff(a,b){function c(a){a===ef?D("174"):void 0;return a}var d=a.getChildHostContext,e=a.getRootHostContext;a=b.createCursor;var f=b.push,h=b.pop,g=a(ef),k=a(ef),v=a(ef);return{getHostContext:function(){return c(g.current)},getRootHostContainer:function(){return c(v.current)},popHostContainer:function(a){h(g,a);h(k,a);h(v,a)},popHostContext:function(a){k.current===a&&(h(g,a),h(k,a))},pushHostContainer:function(a,b){f(v,b,a);f(k,a,a);f(g,ef,a);b=e(b);h(g,a);f(g,b,a)},pushHostContext:function(a){var b=
2541
+ c(v.current),e=c(g.current);b=d(e,a.type,b);e!==b&&(f(k,a,a),f(g,b,a))}}}
2542
+ function gf(a){function b(a,b){var c=new xe(5,null,null,0);c.type="DELETED";c.stateNode=b;c["return"]=a;c.effectTag=8;null!==a.lastEffect?(a.lastEffect.nextEffect=c,a.lastEffect=c):a.firstEffect=a.lastEffect=c}function c(a,b){switch(a.tag){case 5:return b=f(b,a.type,a.pendingProps),null!==b?(a.stateNode=b,!0):!1;case 6:return b=h(b,a.pendingProps),null!==b?(a.stateNode=b,!0):!1;default:return!1}}function d(a){for(a=a["return"];null!==a&&5!==a.tag&&3!==a.tag;)a=a["return"];p=a}var e=a.shouldSetTextContent;
2543
+ a=a.hydration;if(!a)return{enterHydrationState:function(){return!1},resetHydrationState:function(){},tryToClaimNextHydratableInstance:function(){},prepareToHydrateHostInstance:function(){D("175")},prepareToHydrateHostTextInstance:function(){D("176")},popHydrationState:function(){return!1}};var f=a.canHydrateInstance,h=a.canHydrateTextInstance,g=a.getNextHydratableSibling,k=a.getFirstHydratableChild,v=a.hydrateInstance,l=a.hydrateTextInstance,p=null,z=null,B=!1;return{enterHydrationState:function(a){z=
2544
+ k(a.stateNode.containerInfo);p=a;return B=!0},resetHydrationState:function(){z=p=null;B=!1},tryToClaimNextHydratableInstance:function(a){if(B){var d=z;if(d){if(!c(a,d)){d=g(d);if(!d||!c(a,d)){a.effectTag|=2;B=!1;p=a;return}b(p,z)}p=a;z=k(d)}else a.effectTag|=2,B=!1,p=a}},prepareToHydrateHostInstance:function(a,b,c){b=v(a.stateNode,a.type,a.memoizedProps,b,c,a);a.updateQueue=b;return null!==b?!0:!1},prepareToHydrateHostTextInstance:function(a){return l(a.stateNode,a.memoizedProps,a)},popHydrationState:function(a){if(a!==
2545
+ p)return!1;if(!B)return d(a),B=!0,!1;var c=a.type;if(5!==a.tag||"head"!==c&&"body"!==c&&!e(c,a.memoizedProps))for(c=z;c;)b(a,c),c=g(c);d(a);z=p?g(a.stateNode):null;return!0}}}
2546
+ function hf(a){function b(a,b,c){a=a.stateNode;a.__reactInternalMemoizedUnmaskedChildContext=b;a.__reactInternalMemoizedMaskedChildContext=c}function c(a){return 2===a.tag&&null!=a.type.childContextTypes}function d(a,b){var c=a.stateNode,d=a.type.childContextTypes;if("function"!==typeof c.getChildContext)return b;c=c.getChildContext();for(var e in c)e in d?void 0:D("108",Ac(a)||"Unknown",e);return A({},b,c)}var e=a.createCursor,f=a.push,h=a.pop,g=e(ka),k=e(!1),v=ka;return{getUnmaskedContext:function(a){return c(a)?
2547
+ v:g.current},cacheContext:b,getMaskedContext:function(a,c){var d=a.type.contextTypes;if(!d)return ka;var e=a.stateNode;if(e&&e.__reactInternalMemoizedUnmaskedChildContext===c)return e.__reactInternalMemoizedMaskedChildContext;var f={},g;for(g in d)f[g]=c[g];e&&b(a,c,f);return f},hasContextChanged:function(){return k.current},isContextConsumer:function(a){return 2===a.tag&&null!=a.type.contextTypes},isContextProvider:c,popContextProvider:function(a){c(a)&&(h(k,a),h(g,a))},popTopLevelContextObject:function(a){h(k,
2548
+ a);h(g,a)},pushTopLevelContextObject:function(a,b,c){null!=g.cursor?D("168"):void 0;f(g,b,a);f(k,c,a)},processChildContext:d,pushContextProvider:function(a){if(!c(a))return!1;var b=a.stateNode;b=b&&b.__reactInternalMemoizedMergedChildContext||ka;v=g.current;f(g,b,a);f(k,k.current,a);return!0},invalidateContextProvider:function(a,b){var c=a.stateNode;c?void 0:D("169");if(b){var e=d(a,v);c.__reactInternalMemoizedMergedChildContext=e;h(k,a);h(g,a);f(g,e,a)}else h(k,a);f(k,b,a)},findCurrentUnmaskedContext:function(a){for(2!==
2549
+ xd(a)||2!==a.tag?D("170"):void 0;3!==a.tag;){if(c(a))return a.stateNode.__reactInternalMemoizedMergedChildContext;(a=a["return"])?void 0:D("171")}return a.stateNode.context}}}
2550
+ function jf(a){var b=a.createCursor,c=a.push,d=a.pop,e=b(null),f=b(null),h=b(0);return{pushProvider:function(a){var b=a.type._context;c(h,b._changedBits,a);c(f,b._currentValue,a);c(e,a,a);b._currentValue=a.pendingProps.value;b._changedBits=a.stateNode},popProvider:function(a){var b=h.current,c=f.current;d(e,a);d(f,a);d(h,a);a=a.type._context;a._currentValue=c;a._changedBits=b}}}
2551
+ function kf(){var a=[],b=-1;return{createCursor:function(a){return{current:a}},isEmpty:function(){return-1===b},pop:function(c){0>b||(c.current=a[b],a[b]=null,b--)},push:function(c,d){b++;a[b]=c.current;c.current=d},checkThatStackIsEmpty:function(){},resetStackAfterFatalErrorInDev:function(){}}}
2552
+ function lf(a){function b(){if(null!==I)for(var a=I["return"];null!==a;)Lc(a),a=a["return"];Ya=null;Z=0;I=null;Nc=!1}function c(a){return null!==ya&&ya.has(a)}function d(a){for(;;){var b=a.alternate,c=a["return"],d=a.sibling;if(0===(a.effectTag&512)){b=Cb(b,a,Z);var e=a;if(1073741823===Z||1073741823!==e.expirationTime){b:switch(e.tag){case 3:case 2:var f=e.updateQueue;f=null===f?0:f.expirationTime;break b;default:f=0}for(var g=e.child;null!==g;)0!==g.expirationTime&&(0===f||f>g.expirationTime)&&(f=
2553
+ g.expirationTime),g=g.sibling;e.expirationTime=f}if(null!==b)return b;null!==c&&0===(c.effectTag&512)&&(null===c.firstEffect&&(c.firstEffect=a.firstEffect),null!==a.lastEffect&&(null!==c.lastEffect&&(c.lastEffect.nextEffect=a.firstEffect),c.lastEffect=a.lastEffect),1<a.effectTag&&(null!==c.lastEffect?c.lastEffect.nextEffect=a:c.firstEffect=a,c.lastEffect=a));if(null!==d)return d;if(null!==c)a=c;else{Nc=!0;break}}else{a=Kc(a);if(null!==a)return a.effectTag&=2559,a;null!==c&&(c.firstEffect=c.lastEffect=
2554
+ null,c.effectTag|=512);if(null!==d)return d;if(null!==c)a=c;else break}}return null}function e(a){var b=Wa(a.alternate,a,Z);null===b&&(b=d(a));nc.current=null;return b}function f(a,c,f){ca?D("243"):void 0;ca=!0;if(c!==Z||a!==Ya||null===I)b(),Ya=a,Z=c,I=ze(Ya.current,null,Z),a.pendingCommitExpirationTime=0;var g=!1;do{try{if(f)for(;null!==I&&!S();)I=e(I);else for(;null!==I;)I=e(I)}catch(Oc){if(null===I){g=!0;q(Oc);break}f=I;var h=f["return"];if(null===h){g=!0;q(Oc);break}Jc(h,f,Oc);I=d(f)}break}while(1);
2555
+ ca=!1;if(g||null!==I)return null;if(Nc)return a.pendingCommitExpirationTime=c,a.current.alternate;D("262")}function h(a,b,c,d){a={value:c,source:a,stack:Bc(a)};Pe(b,{expirationTime:d,partialState:null,callback:null,isReplace:!1,isForced:!1,capturedValue:a,next:null});v(b,d)}function g(a,b){a:{ca&&!Za?D("263"):void 0;for(var d=a["return"];null!==d;){switch(d.tag){case 2:var e=d.stateNode;if("function"===typeof d.type.getDerivedStateFromCatch||"function"===typeof e.componentDidCatch&&!c(e)){h(a,d,b,
2556
+ 1);a=void 0;break a}break;case 3:h(a,d,b,1);a=void 0;break a}d=d["return"]}3===a.tag&&h(a,a,b,1);a=void 0}return a}function k(a){a=0!==ia?ia:ca?Za?1:Z:a.mode&1?za?10*(((l()+15)/10|0)+1):25*(((l()+500)/25|0)+1):1;za&&(0===da||a>da)&&(da=a);return a}function v(a,c){a:{for(;null!==a;){if(0===a.expirationTime||a.expirationTime>c)a.expirationTime=c;null!==a.alternate&&(0===a.alternate.expirationTime||a.alternate.expirationTime>c)&&(a.alternate.expirationTime=c);if(null===a["return"])if(3===a.tag){var d=
2557
+ a.stateNode;!ca&&0!==Z&&c<Z&&b();ca&&!Za&&Ya===d||B(d,c);Fb>xg&&D("185")}else{c=void 0;break a}a=a["return"]}c=void 0}return c}function l(){ye=Ic()-Pc;return yg=(ye/10|0)+2}function p(a,b,c,d,e){var f=ia;ia=1;try{return a(b,c,d,e)}finally{ia=f}}function z(a){if(0!==Gb){if(a>Gb)return;mg(Qc)}var b=Ic()-Pc;Gb=a;Qc=lg(Q,{timeout:10*(a-2)-b})}function B(a,b){if(null===a.nextScheduledRoot)a.remainingExpirationTime=b,null===K?(la=K=a,a.nextScheduledRoot=a):(K=K.nextScheduledRoot=a,K.nextScheduledRoot=la);
2558
+ else{var c=a.remainingExpirationTime;if(0===c||b<c)a.remainingExpirationTime=b}T||(J?Hb&&(aa=a,P=1,G(a,1,!1)):1===b?n():z(b))}function r(){var a=0,b=null;if(null!==K)for(var c=K,d=la;null!==d;){var e=d.remainingExpirationTime;if(0===e){null===c||null===K?D("244"):void 0;if(d===d.nextScheduledRoot){la=K=d.nextScheduledRoot=null;break}else if(d===la)la=e=d.nextScheduledRoot,K.nextScheduledRoot=e,d.nextScheduledRoot=null;else if(d===K){K=c;K.nextScheduledRoot=la;d.nextScheduledRoot=null;break}else c.nextScheduledRoot=
2559
+ d.nextScheduledRoot,d.nextScheduledRoot=null;d=c.nextScheduledRoot}else{if(0===a||e<a)a=e,b=d;if(d===K)break;c=d;d=d.nextScheduledRoot}}c=aa;null!==c&&c===b&&1===a?Fb++:Fb=0;aa=b;P=a}function Q(a){x(0,!0,a)}function n(){x(1,!1,null)}function x(a,b,c){$a=c;r();if(b)for(;null!==aa&&0!==P&&(0===a||a>=P)&&(!Ib||l()>=P);)G(aa,P,!Ib),r();else for(;null!==aa&&0!==P&&(0===a||a>=P);)G(aa,P,!1),r();null!==$a&&(Gb=0,Qc=-1);0!==P&&z(P);$a=null;Ib=!1;Y()}function Y(){Fb=0;if(null!==Aa){var a=Aa;Aa=null;for(var b=
2560
+ 0;b<a.length;b++){var c=a[b];try{c._onComplete()}catch(wg){Ba||(Ba=!0,Jb=wg)}}}if(Ba)throw a=Jb,Jb=null,Ba=!1,a;}function G(a,b,c){T?D("245"):void 0;T=!0;c?(c=a.finishedWork,null!==c?R(a,c,b):(a.finishedWork=null,c=f(a,b,!0),null!==c&&(S()?a.finishedWork=c:R(a,c,b)))):(c=a.finishedWork,null!==c?R(a,c,b):(a.finishedWork=null,c=f(a,b,!1),null!==c&&R(a,c,b)));T=!1}function R(a,b,c){var d=a.firstBatch;if(null!==d&&d._expirationTime<=c&&(null===Aa?Aa=[d]:Aa.push(d),d._defer)){a.finishedWork=b;a.remainingExpirationTime=
2561
+ 0;return}a.finishedWork=null;Za=ca=!0;c=b.stateNode;c.current===b?D("177"):void 0;d=c.pendingCommitExpirationTime;0===d?D("261"):void 0;c.pendingCommitExpirationTime=0;var e=l();nc.current=null;if(1<b.effectTag)if(null!==b.lastEffect){b.lastEffect.nextEffect=b;var f=b.firstEffect}else f=b;else f=b.firstEffect;zg(c.containerInfo);for(w=f;null!==w;){var h=!1,k=void 0;try{for(;null!==w;)w.effectTag&2048&&Db(w.alternate,w),w=w.nextEffect}catch(ab){h=!0,k=ab}h&&(null===w?D("178"):void 0,g(w,k),null!==
2562
+ w&&(w=w.nextEffect))}for(w=f;null!==w;){h=!1;k=void 0;try{for(;null!==w;){var p=w.effectTag;p&16&&Mc(w);if(p&128){var n=w.alternate;null!==n&&kg(n)}switch(p&14){case 2:Eb(w);w.effectTag&=-3;break;case 6:Eb(w);w.effectTag&=-3;we(w.alternate,w);break;case 4:we(w.alternate,w);break;case 8:gg(w)}w=w.nextEffect}}catch(ab){h=!0,k=ab}h&&(null===w?D("178"):void 0,g(w,k),null!==w&&(w=w.nextEffect))}Ag(c.containerInfo);c.current=b;for(w=f;null!==w;){p=!1;n=void 0;try{for(f=c,h=e,k=d;null!==w;){var r=w.effectTag;
2563
+ r&36&&hg(f,w.alternate,w,h,k);r&256&&ig(w,q);r&128&&jg(w);var t=w.nextEffect;w.nextEffect=null;w=t}}catch(ab){p=!0,n=ab}p&&(null===w?D("178"):void 0,g(w,n),null!==w&&(w=w.nextEffect))}ca=Za=!1;"function"===typeof Ie&&Ie(b.stateNode);b=c.current.expirationTime;0===b&&(ya=null);a.remainingExpirationTime=b}function S(){return null===$a||$a.timeRemaining()>Bg?!1:Ib=!0}function q(a){null===aa?D("246"):void 0;aa.remainingExpirationTime=0;Ba||(Ba=!0,Jb=a)}var u=kf(),t=ff(a,u),y=hf(u);u=jf(u);var H=gf(a),
2564
+ Wa=$e(a,t,y,u,H,v,k).beginWork,Cb=af(a,t,y,u,H).completeWork;t=bf(t,y,u,v,c);var Jc=t.throwException,Kc=t.unwindWork,Lc=t.unwindInterruptedWork;t=df(a,g,v,k,function(a){null===ya?ya=new Set([a]):ya.add(a)},l);var Db=t.commitBeforeMutationLifeCycles,Mc=t.commitResetTextContent,Eb=t.commitPlacement,gg=t.commitDeletion,we=t.commitWork,hg=t.commitLifeCycles,ig=t.commitErrorLogging,jg=t.commitAttachRef,kg=t.commitDetachRef,Ic=a.now,lg=a.scheduleDeferredCallback,mg=a.cancelDeferredCallback,zg=a.prepareForCommit,
2565
+ Ag=a.resetAfterCommit,Pc=Ic(),yg=2,ye=Pc,Rc=0,ia=0,ca=!1,I=null,Ya=null,Z=0,w=null,Za=!1,Nc=!1,ya=null,la=null,K=null,Gb=0,Qc=-1,T=!1,aa=null,P=0,da=0,Ib=!1,Ba=!1,Jb=null,$a=null,J=!1,Hb=!1,za=!1,Aa=null,xg=1E3,Fb=0,Bg=1;return{recalculateCurrentTime:l,computeExpirationForFiber:k,scheduleWork:v,requestWork:B,flushRoot:function(a,b){T?D("253"):void 0;aa=a;P=b;G(a,b,!1);n();Y()},batchedUpdates:function(a,b){var c=J;J=!0;try{return a(b)}finally{(J=c)||T||n()}},unbatchedUpdates:function(a,b){if(J&&!Hb){Hb=
2566
+ !0;try{return a(b)}finally{Hb=!1}}return a(b)},flushSync:function(a,b){T?D("187"):void 0;var c=J;J=!0;try{return p(a,b)}finally{J=c,n()}},flushControlled:function(a){var b=J;J=!0;try{p(a)}finally{(J=b)||T||x(1,!1,null)}},deferredUpdates:function(a){var b=ia;ia=25*(((l()+500)/25|0)+1);try{return a()}finally{ia=b}},syncUpdates:p,interactiveUpdates:function(a,b,c){if(za)return a(b,c);J||T||0===da||(x(da,!1,null),da=0);var d=za,e=J;J=za=!0;try{return a(b,c)}finally{za=d,(J=e)||T||n()}},flushInteractiveUpdates:function(){T||
2567
+ 0===da||(x(da,!1,null),da=0)},computeUniqueAsyncExpiration:function(){var a=25*(((l()+500)/25|0)+1);a<=Rc&&(a=Rc+1);return Rc=a},legacyContext:y}}
2568
+ function mf(a){function b(a,b,c,d,e,h){d=b.current;if(c){c=c._reactInternalFiber;var l=g(c);c=k(c)?v(c,l):l}else c=ka;null===b.context?b.context=c:b.pendingContext=c;b=h;Pe(d,{expirationTime:e,partialState:{element:a},callback:void 0===b?null:b,isReplace:!1,isForced:!1,capturedValue:null,next:null});f(d,e);return e}var c=a.getPublicInstance;a=lf(a);var d=a.recalculateCurrentTime,e=a.computeExpirationForFiber,f=a.scheduleWork,h=a.legacyContext,g=h.findCurrentUnmaskedContext,k=h.isContextProvider,v=
2569
+ h.processChildContext;return{createContainer:function(a,b,c){b=new xe(3,null,null,b?3:0);a={current:b,containerInfo:a,pendingChildren:null,pendingCommitExpirationTime:0,finishedWork:null,context:null,pendingContext:null,hydrate:c,remainingExpirationTime:0,firstBatch:null,nextScheduledRoot:null};return b.stateNode=a},updateContainer:function(a,c,f,h){var g=c.current,k=d();g=e(g);return b(a,c,f,k,g,h)},updateContainerAtExpirationTime:function(a,c,e,f,g){var h=d();return b(a,c,e,h,f,g)},flushRoot:a.flushRoot,
2570
+ requestWork:a.requestWork,computeUniqueAsyncExpiration:a.computeUniqueAsyncExpiration,batchedUpdates:a.batchedUpdates,unbatchedUpdates:a.unbatchedUpdates,deferredUpdates:a.deferredUpdates,syncUpdates:a.syncUpdates,interactiveUpdates:a.interactiveUpdates,flushInteractiveUpdates:a.flushInteractiveUpdates,flushControlled:a.flushControlled,flushSync:a.flushSync,getPublicRootInstance:function(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return c(a.child.stateNode);default:return a.child.stateNode}},
2571
+ findHostInstance:function(a){var b=a._reactInternalFiber;void 0===b&&("function"===typeof a.render?D("188"):D("268",Object.keys(a)));a=Bd(b);return null===a?null:a.stateNode},findHostInstanceWithNoPortals:function(a){a=Cd(a);return null===a?null:a.stateNode},injectIntoDevTools:function(a){var b=a.findFiberByHostInstance;return He(A({},a,{findHostInstanceByFiber:function(a){a=Bd(a);return null===a?null:a.stateNode},findFiberByHostInstance:function(a){return b?b(a):null}}))}}}
2572
+ var nf=Object.freeze({default:mf}),of=nf&&mf||nf,pf=of["default"]?of["default"]:of;function qf(a,b,c){var d=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:rc,key:null==d?null:""+d,children:a,containerInfo:b,implementation:c}}var rf="object"===typeof performance&&"function"===typeof performance.now,sf=void 0;sf=rf?function(){return performance.now()}:function(){return Date.now()};var tf=void 0,uf=void 0;
2573
+ if(m.canUseDOM)if("function"!==typeof requestIdleCallback||"function"!==typeof cancelIdleCallback){var vf=null,wf=!1,xf=-1,yf=!1,zf=0,Af=33,Bf=33,Cf=void 0;Cf=rf?{didTimeout:!1,timeRemaining:function(){var a=zf-performance.now();return 0<a?a:0}}:{didTimeout:!1,timeRemaining:function(){var a=zf-Date.now();return 0<a?a:0}};var Df="__reactIdleCallback$"+Math.random().toString(36).slice(2);window.addEventListener("message",function(a){if(a.source===window&&a.data===Df){wf=!1;a=sf();if(0>=zf-a)if(-1!==
2574
+ xf&&xf<=a)Cf.didTimeout=!0;else{yf||(yf=!0,requestAnimationFrame(Ef));return}else Cf.didTimeout=!1;xf=-1;a=vf;vf=null;null!==a&&a(Cf)}},!1);var Ef=function(a){yf=!1;var b=a-zf+Bf;b<Bf&&Af<Bf?(8>b&&(b=8),Bf=b<Af?Af:b):Af=b;zf=a+Bf;wf||(wf=!0,window.postMessage(Df,"*"))};tf=function(a,b){vf=a;null!=b&&"number"===typeof b.timeout&&(xf=sf()+b.timeout);yf||(yf=!0,requestAnimationFrame(Ef));return 0};uf=function(){vf=null;wf=!1;xf=-1}}else tf=window.requestIdleCallback,uf=window.cancelIdleCallback;else tf=
2575
+ function(a){return setTimeout(function(){a({timeRemaining:function(){return Infinity},didTimeout:!1})})},uf=function(a){clearTimeout(a)};function Ff(a){var b="";ea.Children.forEach(a,function(a){null==a||"string"!==typeof a&&"number"!==typeof a||(b+=a)});return b}function Gf(a,b){a=A({children:void 0},b);if(b=Ff(b.children))a.children=b;return a}
2576
+ function Hf(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e<c.length;e++)b["$"+c[e]]=!0;for(c=0;c<a.length;c++)e=b.hasOwnProperty("$"+a[c].value),a[c].selected!==e&&(a[c].selected=e),e&&d&&(a[c].defaultSelected=!0)}else{c=""+c;b=null;for(e=0;e<a.length;e++){if(a[e].value===c){a[e].selected=!0;d&&(a[e].defaultSelected=!0);return}null!==b||a[e].disabled||(b=a[e])}null!==b&&(b.selected=!0)}}
2577
+ function If(a,b){var c=b.value;a._wrapperState={initialValue:null!=c?c:b.defaultValue,wasMultiple:!!b.multiple}}function Jf(a,b){null!=b.dangerouslySetInnerHTML?D("91"):void 0;return A({},b,{value:void 0,defaultValue:void 0,children:""+a._wrapperState.initialValue})}function Kf(a,b){var c=b.value;null==c&&(c=b.defaultValue,b=b.children,null!=b&&(null!=c?D("92"):void 0,Array.isArray(b)&&(1>=b.length?void 0:D("93"),b=b[0]),c=""+b),null==c&&(c=""));a._wrapperState={initialValue:""+c}}
2578
+ function Lf(a,b){var c=b.value;null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&(a.defaultValue=c));null!=b.defaultValue&&(a.defaultValue=b.defaultValue)}function Mf(a){var b=a.textContent;b===a._wrapperState.initialValue&&(a.value=b)}var Nf={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};
2579
+ function Of(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function Pf(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?Of(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}
2580
+ var Qf=void 0,Rf=function(a){return"undefined"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,c,d,e)})}:a}(function(a,b){if(a.namespaceURI!==Nf.svg||"innerHTML"in a)a.innerHTML=b;else{Qf=Qf||document.createElement("div");Qf.innerHTML="\x3csvg\x3e"+b+"\x3c/svg\x3e";for(b=Qf.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});
2581
+ function Sf(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}
2582
+ var Tf={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,
2583
+ stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Uf=["Webkit","ms","Moz","O"];Object.keys(Tf).forEach(function(a){Uf.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);Tf[b]=Tf[a]})});
2584
+ function Vf(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--");var e=c;var f=b[c];e=null==f||"boolean"===typeof f||""===f?"":d||"number"!==typeof f||0===f||Tf.hasOwnProperty(e)&&Tf[e]?(""+f).trim():f+"px";"float"===c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}var Wf=A({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});
2585
+ function Xf(a,b,c){b&&(Wf[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML?D("137",a,c()):void 0),null!=b.dangerouslySetInnerHTML&&(null!=b.children?D("60"):void 0,"object"===typeof b.dangerouslySetInnerHTML&&"__html"in b.dangerouslySetInnerHTML?void 0:D("61")),null!=b.style&&"object"!==typeof b.style?D("62",c()):void 0)}
2586
+ function Yf(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;default:return!0}}var Zf=C.thatReturns("");
2587
+ function $f(a,b){a=9===a.nodeType||11===a.nodeType?a:a.ownerDocument;var c=ke(a);b=va[b];for(var d=0;d<b.length;d++){var e=b[d];c.hasOwnProperty(e)&&c[e]||("topScroll"===e?Zd("topScroll","scroll",a):"topFocus"===e||"topBlur"===e?(Zd("topFocus","focus",a),Zd("topBlur","blur",a),c.topBlur=!0,c.topFocus=!0):"topCancel"===e?(ic("cancel",!0)&&Zd("topCancel","cancel",a),c.topCancel=!0):"topClose"===e?(ic("close",!0)&&Zd("topClose","close",a),c.topClose=!0):fe.hasOwnProperty(e)&&W(e,fe[e],a),c[e]=!0)}}
2588
+ function ag(a,b,c,d){c=9===c.nodeType?c:c.ownerDocument;d===Nf.html&&(d=Of(a));d===Nf.html?"script"===a?(a=c.createElement("div"),a.innerHTML="\x3cscript\x3e\x3c/script\x3e",a=a.removeChild(a.firstChild)):a="string"===typeof b.is?c.createElement(a,{is:b.is}):c.createElement(a):a=c.createElementNS(d,a);return a}function bg(a,b){return(9===b.nodeType?b:b.ownerDocument).createTextNode(a)}
2589
+ function cg(a,b,c,d){var e=Yf(b,c);switch(b){case "iframe":case "object":W("topLoad","load",a);var f=c;break;case "video":case "audio":for(f in ge)ge.hasOwnProperty(f)&&W(f,ge[f],a);f=c;break;case "source":W("topError","error",a);f=c;break;case "img":case "image":case "link":W("topError","error",a);W("topLoad","load",a);f=c;break;case "form":W("topReset","reset",a);W("topSubmit","submit",a);f=c;break;case "details":W("topToggle","toggle",a);f=c;break;case "input":Wc(a,c);f=Vc(a,c);W("topInvalid",
2590
+ "invalid",a);$f(d,"onChange");break;case "option":f=Gf(a,c);break;case "select":If(a,c);f=A({},c,{value:void 0});W("topInvalid","invalid",a);$f(d,"onChange");break;case "textarea":Kf(a,c);f=Jf(a,c);W("topInvalid","invalid",a);$f(d,"onChange");break;default:f=c}Xf(b,f,Zf);var h=f,g;for(g in h)if(h.hasOwnProperty(g)){var k=h[g];"style"===g?Vf(a,k,Zf):"dangerouslySetInnerHTML"===g?(k=k?k.__html:void 0,null!=k&&Rf(a,k)):"children"===g?"string"===typeof k?("textarea"!==b||""!==k)&&Sf(a,k):"number"===typeof k&&
2591
+ Sf(a,""+k):"suppressContentEditableWarning"!==g&&"suppressHydrationWarning"!==g&&"autoFocus"!==g&&(ua.hasOwnProperty(g)?null!=k&&$f(d,g):null!=k&&Uc(a,g,k,e))}switch(b){case "input":lc(a);ad(a,c);break;case "textarea":lc(a);Mf(a,c);break;case "option":null!=c.value&&a.setAttribute("value",c.value);break;case "select":a.multiple=!!c.multiple;b=c.value;null!=b?Hf(a,!!c.multiple,b,!1):null!=c.defaultValue&&Hf(a,!!c.multiple,c.defaultValue,!0);break;default:"function"===typeof f.onClick&&(a.onclick=C)}}
2592
+ function dg(a,b,c,d,e){var f=null;switch(b){case "input":c=Vc(a,c);d=Vc(a,d);f=[];break;case "option":c=Gf(a,c);d=Gf(a,d);f=[];break;case "select":c=A({},c,{value:void 0});d=A({},d,{value:void 0});f=[];break;case "textarea":c=Jf(a,c);d=Jf(a,d);f=[];break;default:"function"!==typeof c.onClick&&"function"===typeof d.onClick&&(a.onclick=C)}Xf(b,d,Zf);b=a=void 0;var h=null;for(a in c)if(!d.hasOwnProperty(a)&&c.hasOwnProperty(a)&&null!=c[a])if("style"===a){var g=c[a];for(b in g)g.hasOwnProperty(b)&&(h||
2593
+ (h={}),h[b]="")}else"dangerouslySetInnerHTML"!==a&&"children"!==a&&"suppressContentEditableWarning"!==a&&"suppressHydrationWarning"!==a&&"autoFocus"!==a&&(ua.hasOwnProperty(a)?f||(f=[]):(f=f||[]).push(a,null));for(a in d){var k=d[a];g=null!=c?c[a]:void 0;if(d.hasOwnProperty(a)&&k!==g&&(null!=k||null!=g))if("style"===a)if(g){for(b in g)!g.hasOwnProperty(b)||k&&k.hasOwnProperty(b)||(h||(h={}),h[b]="");for(b in k)k.hasOwnProperty(b)&&g[b]!==k[b]&&(h||(h={}),h[b]=k[b])}else h||(f||(f=[]),f.push(a,h)),
2594
+ h=k;else"dangerouslySetInnerHTML"===a?(k=k?k.__html:void 0,g=g?g.__html:void 0,null!=k&&g!==k&&(f=f||[]).push(a,""+k)):"children"===a?g===k||"string"!==typeof k&&"number"!==typeof k||(f=f||[]).push(a,""+k):"suppressContentEditableWarning"!==a&&"suppressHydrationWarning"!==a&&(ua.hasOwnProperty(a)?(null!=k&&$f(e,a),f||g===k||(f=[])):(f=f||[]).push(a,k))}h&&(f=f||[]).push("style",h);return f}
2595
+ function eg(a,b,c,d,e){"input"===c&&"radio"===e.type&&null!=e.name&&Yc(a,e);Yf(c,d);d=Yf(c,e);for(var f=0;f<b.length;f+=2){var h=b[f],g=b[f+1];"style"===h?Vf(a,g,Zf):"dangerouslySetInnerHTML"===h?Rf(a,g):"children"===h?Sf(a,g):Uc(a,h,g,d)}switch(c){case "input":Zc(a,e);break;case "textarea":Lf(a,e);break;case "select":a._wrapperState.initialValue=void 0,b=a._wrapperState.wasMultiple,a._wrapperState.wasMultiple=!!e.multiple,c=e.value,null!=c?Hf(a,!!e.multiple,c,!1):b!==!!e.multiple&&(null!=e.defaultValue?
2596
+ Hf(a,!!e.multiple,e.defaultValue,!0):Hf(a,!!e.multiple,e.multiple?[]:"",!1))}}
2597
+ function fg(a,b,c,d,e){switch(b){case "iframe":case "object":W("topLoad","load",a);break;case "video":case "audio":for(var f in ge)ge.hasOwnProperty(f)&&W(f,ge[f],a);break;case "source":W("topError","error",a);break;case "img":case "image":case "link":W("topError","error",a);W("topLoad","load",a);break;case "form":W("topReset","reset",a);W("topSubmit","submit",a);break;case "details":W("topToggle","toggle",a);break;case "input":Wc(a,c);W("topInvalid","invalid",a);$f(e,"onChange");break;case "select":If(a,
2598
+ c);W("topInvalid","invalid",a);$f(e,"onChange");break;case "textarea":Kf(a,c),W("topInvalid","invalid",a),$f(e,"onChange")}Xf(b,c,Zf);d=null;for(var h in c)c.hasOwnProperty(h)&&(f=c[h],"children"===h?"string"===typeof f?a.textContent!==f&&(d=["children",f]):"number"===typeof f&&a.textContent!==""+f&&(d=["children",""+f]):ua.hasOwnProperty(h)&&null!=f&&$f(e,h));switch(b){case "input":lc(a);ad(a,c);break;case "textarea":lc(a);Mf(a,c);break;case "select":case "option":break;default:"function"===typeof c.onClick&&
2599
+ (a.onclick=C)}return d}function ng(a,b){return a.nodeValue!==b}
2600
+ var og=Object.freeze({createElement:ag,createTextNode:bg,setInitialProperties:cg,diffProperties:dg,updateProperties:eg,diffHydratedProperties:fg,diffHydratedText:ng,warnForUnmatchedText:function(){},warnForDeletedHydratableElement:function(){},warnForDeletedHydratableText:function(){},warnForInsertedHydratedElement:function(){},warnForInsertedHydratedText:function(){},restoreControlledState:function(a,b,c){switch(b){case "input":Zc(a,c);b=c.name;if("radio"===c.type&&null!=b){for(c=a;c.parentNode;)c=
2601
+ c.parentNode;c=c.querySelectorAll("input[name\x3d"+JSON.stringify(""+b)+'][type\x3d"radio"]');for(b=0;b<c.length;b++){var d=c[b];if(d!==a&&d.form===a.form){var e=Xa(d);e?void 0:D("90");mc(d);Zc(d,e)}}}break;case "textarea":Lf(a,c);break;case "select":b=c.value,null!=b&&Hf(a,!!c.multiple,b,!1)}}});Tb.injectFiberControlledHostComponent(og);var pg=null,qg=null;
2602
+ function rg(a){this._expirationTime=X.computeUniqueAsyncExpiration();this._root=a;this._callbacks=this._next=null;this._hasChildren=this._didComplete=!1;this._children=null;this._defer=!0}rg.prototype.render=function(a){this._defer?void 0:D("250");this._hasChildren=!0;this._children=a;var b=this._root._internalRoot,c=this._expirationTime,d=new sg;X.updateContainerAtExpirationTime(a,b,null,c,d._onCommit);return d};
2603
+ rg.prototype.then=function(a){if(this._didComplete)a();else{var b=this._callbacks;null===b&&(b=this._callbacks=[]);b.push(a)}};
2604
+ rg.prototype.commit=function(){var a=this._root._internalRoot,b=a.firstBatch;this._defer&&null!==b?void 0:D("251");if(this._hasChildren){var c=this._expirationTime;if(b!==this){this._hasChildren&&(c=this._expirationTime=b._expirationTime,this.render(this._children));for(var d=null,e=b;e!==this;)d=e,e=e._next;null===d?D("251"):void 0;d._next=e._next;this._next=b;a.firstBatch=this}this._defer=!1;X.flushRoot(a,c);b=this._next;this._next=null;b=a.firstBatch=b;null!==b&&b._hasChildren&&b.render(b._children)}else this._next=
2605
+ null,this._defer=!1};rg.prototype._onComplete=function(){if(!this._didComplete){this._didComplete=!0;var a=this._callbacks;if(null!==a)for(var b=0;b<a.length;b++)(0,a[b])()}};function sg(){this._callbacks=null;this._didCommit=!1;this._onCommit=this._onCommit.bind(this)}sg.prototype.then=function(a){if(this._didCommit)a();else{var b=this._callbacks;null===b&&(b=this._callbacks=[]);b.push(a)}};
2606
+ sg.prototype._onCommit=function(){if(!this._didCommit){this._didCommit=!0;var a=this._callbacks;if(null!==a)for(var b=0;b<a.length;b++){var c=a[b];"function"!==typeof c?D("191",c):void 0;c()}}};function tg(a,b,c){this._internalRoot=X.createContainer(a,b,c)}tg.prototype.render=function(a,b){var c=this._internalRoot,d=new sg;b=void 0===b?null:b;null!==b&&d.then(b);X.updateContainer(a,c,null,d._onCommit);return d};
2607
+ tg.prototype.unmount=function(a){var b=this._internalRoot,c=new sg;a=void 0===a?null:a;null!==a&&c.then(a);X.updateContainer(null,b,null,c._onCommit);return c};tg.prototype.legacy_renderSubtreeIntoContainer=function(a,b,c){var d=this._internalRoot,e=new sg;c=void 0===c?null:c;null!==c&&e.then(c);X.updateContainer(b,d,a,e._onCommit);return e};
2608
+ tg.prototype.createBatch=function(){var a=new rg(this),b=a._expirationTime,c=this._internalRoot,d=c.firstBatch;if(null===d)c.firstBatch=a,a._next=null;else{for(c=null;null!==d&&d._expirationTime<=b;)c=d,d=d._next;a._next=d;null!==c&&(c._next=a)}return a};function ug(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType&&(8!==a.nodeType||" react-mount-point-unstable "!==a.nodeValue))}
2609
+ function vg(a,b){switch(a){case "button":case "input":case "select":case "textarea":return!!b.autoFocus}return!1}
2610
+ var X=pf({getRootHostContext:function(a){var b=a.nodeType;switch(b){case 9:case 11:a=(a=a.documentElement)?a.namespaceURI:Pf(null,"");break;default:b=8===b?a.parentNode:a,a=b.namespaceURI||null,b=b.tagName,a=Pf(a,b)}return a},getChildHostContext:function(a,b){return Pf(a,b)},getPublicInstance:function(a){return a},prepareForCommit:function(){pg=Vd;var a=fa();if(ne(a)){if("selectionStart"in a)var b={start:a.selectionStart,end:a.selectionEnd};else a:{var c=window.getSelection&&window.getSelection();
2611
+ if(c&&0!==c.rangeCount){b=c.anchorNode;var d=c.anchorOffset,e=c.focusNode;c=c.focusOffset;try{b.nodeType,e.nodeType}catch(B){b=null;break a}var f=0,h=-1,g=-1,k=0,v=0,l=a,p=null;b:for(;;){for(var z;;){l!==b||0!==d&&3!==l.nodeType||(h=f+d);l!==e||0!==c&&3!==l.nodeType||(g=f+c);3===l.nodeType&&(f+=l.nodeValue.length);if(null===(z=l.firstChild))break;p=l;l=z}for(;;){if(l===a)break b;p===b&&++k===d&&(h=f);p===e&&++v===c&&(g=f);if(null!==(z=l.nextSibling))break;l=p;p=l.parentNode}l=z}b=-1===h||-1===g?null:
2612
+ {start:h,end:g}}else b=null}b=b||{start:0,end:0}}else b=null;qg={focusedElem:a,selectionRange:b};Wd(!1)},resetAfterCommit:function(){var a=qg,b=fa(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&ja(document.documentElement,c)){if(ne(c))if(b=d.start,a=d.end,void 0===a&&(a=b),"selectionStart"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);else if(window.getSelection){b=window.getSelection();var e=c[mb()].length;a=Math.min(d.start,e);d=void 0===d.end?a:Math.min(d.end,e);!b.extend&&a>
2613
+ d&&(e=d,d=a,a=e);e=me(c,a);var f=me(c,d);if(e&&f&&(1!==b.rangeCount||b.anchorNode!==e.node||b.anchorOffset!==e.offset||b.focusNode!==f.node||b.focusOffset!==f.offset)){var h=document.createRange();h.setStart(e.node,e.offset);b.removeAllRanges();a>d?(b.addRange(h),b.extend(f.node,f.offset)):(h.setEnd(f.node,f.offset),b.addRange(h))}}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});c.focus();for(c=0;c<b.length;c++)a=b[c],a.element.scrollLeft=a.left,
2614
+ a.element.scrollTop=a.top}qg=null;Wd(pg);pg=null},createInstance:function(a,b,c,d,e){a=ag(a,b,c,d);a[F]=e;a[Ta]=b;return a},appendInitialChild:function(a,b){a.appendChild(b)},finalizeInitialChildren:function(a,b,c,d){cg(a,b,c,d);return vg(b,c)},prepareUpdate:function(a,b,c,d,e){return dg(a,b,c,d,e)},shouldSetTextContent:function(a,b){return"textarea"===a||"string"===typeof b.children||"number"===typeof b.children||"object"===typeof b.dangerouslySetInnerHTML&&null!==b.dangerouslySetInnerHTML&&"string"===
2615
+ typeof b.dangerouslySetInnerHTML.__html},shouldDeprioritizeSubtree:function(a,b){return!!b.hidden},createTextInstance:function(a,b,c,d){a=bg(a,b);a[F]=d;return a},now:sf,mutation:{commitMount:function(a,b,c){vg(b,c)&&a.focus()},commitUpdate:function(a,b,c,d,e){a[Ta]=e;eg(a,b,c,d,e)},resetTextContent:function(a){Sf(a,"")},commitTextUpdate:function(a,b,c){a.nodeValue=c},appendChild:function(a,b){a.appendChild(b)},appendChildToContainer:function(a,b){8===a.nodeType?a.parentNode.insertBefore(b,a):a.appendChild(b)},
2616
+ insertBefore:function(a,b,c){a.insertBefore(b,c)},insertInContainerBefore:function(a,b,c){8===a.nodeType?a.parentNode.insertBefore(b,c):a.insertBefore(b,c)},removeChild:function(a,b){a.removeChild(b)},removeChildFromContainer:function(a,b){8===a.nodeType?a.parentNode.removeChild(b):a.removeChild(b)}},hydration:{canHydrateInstance:function(a,b){return 1!==a.nodeType||b.toLowerCase()!==a.nodeName.toLowerCase()?null:a},canHydrateTextInstance:function(a,b){return""===b||3!==a.nodeType?null:a},getNextHydratableSibling:function(a){for(a=
2617
+ a.nextSibling;a&&1!==a.nodeType&&3!==a.nodeType;)a=a.nextSibling;return a},getFirstHydratableChild:function(a){for(a=a.firstChild;a&&1!==a.nodeType&&3!==a.nodeType;)a=a.nextSibling;return a},hydrateInstance:function(a,b,c,d,e,f){a[F]=f;a[Ta]=c;return fg(a,b,c,e,d)},hydrateTextInstance:function(a,b,c){a[F]=c;return ng(a,b)},didNotMatchHydratedContainerTextInstance:function(){},didNotMatchHydratedTextInstance:function(){},didNotHydrateContainerInstance:function(){},didNotHydrateInstance:function(){},
2618
+ didNotFindHydratableContainerInstance:function(){},didNotFindHydratableContainerTextInstance:function(){},didNotFindHydratableInstance:function(){},didNotFindHydratableTextInstance:function(){}},scheduleDeferredCallback:tf,cancelDeferredCallback:uf}),Cg=X;ac=Cg.batchedUpdates;bc=Cg.interactiveUpdates;cc=Cg.flushInteractiveUpdates;
2619
+ function Dg(a,b){b||(b=a?9===a.nodeType?a.documentElement:a.firstChild:null,b=!(!b||1!==b.nodeType||!b.hasAttribute("data-reactroot")));if(!b)for(var c;c=a.lastChild;)a.removeChild(c);return new tg(a,!1,b)}
2620
+ function Eg(a,b,c,d,e){ug(c)?void 0:D("200");var f=c._reactRootContainer;if(f){if("function"===typeof e){var h=e;e=function(){var a=X.getPublicRootInstance(f._internalRoot);h.call(a)}}null!=a?f.legacy_renderSubtreeIntoContainer(a,b,e):f.render(b,e)}else{f=c._reactRootContainer=Dg(c,d);if("function"===typeof e){var g=e;e=function(){var a=X.getPublicRootInstance(f._internalRoot);g.call(a)}}X.unbatchedUpdates(function(){null!=a?f.legacy_renderSubtreeIntoContainer(a,b,e):f.render(b,e)})}return X.getPublicRootInstance(f._internalRoot)}
2621
+ function Fg(a,b){var c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;ug(b)?void 0:D("200");return qf(a,b,null,c)}
2622
+ var Gg={createPortal:Fg,findDOMNode:function(a){return null==a?null:1===a.nodeType?a:X.findHostInstance(a)},hydrate:function(a,b,c){return Eg(null,a,b,!0,c)},render:function(a,b,c){return Eg(null,a,b,!1,c)},unstable_renderSubtreeIntoContainer:function(a,b,c,d){null==a||void 0===a._reactInternalFiber?D("38"):void 0;return Eg(a,b,c,!1,d)},unmountComponentAtNode:function(a){ug(a)?void 0:D("40");return a._reactRootContainer?(X.unbatchedUpdates(function(){Eg(null,null,a,!1,function(){a._reactRootContainer=
2623
+ null})}),!0):!1},unstable_createPortal:function(){return Fg.apply(void 0,arguments)},unstable_batchedUpdates:X.batchedUpdates,unstable_deferredUpdates:X.deferredUpdates,flushSync:X.flushSync,unstable_flushControlled:X.flushControlled,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{EventPluginHub:Ra,EventPluginRegistry:Ca,EventPropagators:kb,ReactControlledComponent:$b,ReactDOMComponentTree:bb,ReactDOMEventListener:$d},unstable_createRoot:function(a,b){return new tg(a,!0,null!=b&&!0===b.hydrate)}};
2624
+ X.injectIntoDevTools({findFiberByHostInstance:Ua,bundleType:0,version:"16.3.2",rendererPackageName:"react-dom"});var Hg=Object.freeze({default:Gg}),Ig=Hg&&Gg||Hg;module.exports=Ig["default"]?Ig["default"]:Ig;
2625
+
2626
+
2627
+ /***/ }),
2628
+ /* 18 */
2629
+ /***/ (function(module, exports, __webpack_require__) {
2630
+
2631
+ "use strict";
2632
+
2633
+
2634
+ /**
2635
+ * Copyright (c) 2013-present, Facebook, Inc.
2636
+ *
2637
+ * This source code is licensed under the MIT license found in the
2638
+ * LICENSE file in the root directory of this source tree.
2639
+ *
2640
+ * @typechecks
2641
+ */
2642
+
2643
+ var isNode = __webpack_require__(19);
2644
+
2645
+ /**
2646
+ * @param {*} object The object to check.
2647
+ * @return {boolean} Whether or not the object is a DOM text node.
2648
+ */
2649
+ function isTextNode(object) {
2650
+ return isNode(object) && object.nodeType == 3;
2651
+ }
2652
+
2653
+ module.exports = isTextNode;
2654
+
2655
+ /***/ }),
2656
+ /* 19 */
2657
+ /***/ (function(module, exports, __webpack_require__) {
2658
+
2659
+ "use strict";
2660
+
2661
+
2662
+ /**
2663
+ * Copyright (c) 2013-present, Facebook, Inc.
2664
+ *
2665
+ * This source code is licensed under the MIT license found in the
2666
+ * LICENSE file in the root directory of this source tree.
2667
+ *
2668
+ * @typechecks
2669
+ */
2670
+
2671
+ /**
2672
+ * @param {*} object The object to check.
2673
+ * @return {boolean} Whether or not the object is a DOM node.
2674
+ */
2675
+ function isNode(object) {
2676
+ var doc = object ? object.ownerDocument || object : document;
2677
+ var defaultView = doc.defaultView || window;
2678
+ return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
2679
+ }
2680
+
2681
+ module.exports = isNode;
2682
+
2683
+ /***/ }),
2684
+ /* 20 */
2685
+ /***/ (function(module, exports, __webpack_require__) {
2686
+
2687
+ "use strict";
2688
+ /* WEBPACK VAR INJECTION */(function(process) {/** @license React v16.3.2
2689
+ * react-dom.development.js
2690
+ *
2691
+ * Copyright (c) 2013-present, Facebook, Inc.
2692
+ *
2693
+ * This source code is licensed under the MIT license found in the
2694
+ * LICENSE file in the root directory of this source tree.
2695
+ */
2696
+
2697
+
2698
+
2699
+
2700
+
2701
+ if (process.env.NODE_ENV !== "production") {
2702
+ (function() {
2703
+ 'use strict';
2704
+
2705
+ var invariant = __webpack_require__(2);
2706
+ var React = __webpack_require__(1);
2707
+ var warning = __webpack_require__(6);
2708
+ var ExecutionEnvironment = __webpack_require__(8);
2709
+ var _assign = __webpack_require__(4);
2710
+ var emptyFunction = __webpack_require__(3);
2711
+ var checkPropTypes = __webpack_require__(7);
2712
+ var getActiveElement = __webpack_require__(9);
2713
+ var shallowEqual = __webpack_require__(10);
2714
+ var containsNode = __webpack_require__(11);
2715
+ var emptyObject = __webpack_require__(5);
2716
+ var hyphenateStyleName = __webpack_require__(21);
2717
+ var camelizeStyleName = __webpack_require__(23);
2718
+
2719
+ // Relying on the `invariant()` implementation lets us
2720
+ // have preserve the format and params in the www builds.
2721
+
2722
+ !React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0;
2723
+
2724
+ var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) {
2725
+ this._hasCaughtError = false;
2726
+ this._caughtError = null;
2727
+ var funcArgs = Array.prototype.slice.call(arguments, 3);
2728
+ try {
2729
+ func.apply(context, funcArgs);
2730
+ } catch (error) {
2731
+ this._caughtError = error;
2732
+ this._hasCaughtError = true;
2733
+ }
2734
+ };
2735
+
2736
+ {
2737
+ // In DEV mode, we swap out invokeGuardedCallback for a special version
2738
+ // that plays more nicely with the browser's DevTools. The idea is to preserve
2739
+ // "Pause on exceptions" behavior. Because React wraps all user-provided
2740
+ // functions in invokeGuardedCallback, and the production version of
2741
+ // invokeGuardedCallback uses a try-catch, all user exceptions are treated
2742
+ // like caught exceptions, and the DevTools won't pause unless the developer
2743
+ // takes the extra step of enabling pause on caught exceptions. This is
2744
+ // untintuitive, though, because even though React has caught the error, from
2745
+ // the developer's perspective, the error is uncaught.
2746
+ //
2747
+ // To preserve the expected "Pause on exceptions" behavior, we don't use a
2748
+ // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
2749
+ // DOM node, and call the user-provided callback from inside an event handler
2750
+ // for that fake event. If the callback throws, the error is "captured" using
2751
+ // a global event handler. But because the error happens in a different
2752
+ // event loop context, it does not interrupt the normal program flow.
2753
+ // Effectively, this gives us try-catch behavior without actually using
2754
+ // try-catch. Neat!
2755
+
2756
+ // Check that the browser supports the APIs we need to implement our special
2757
+ // DEV version of invokeGuardedCallback
2758
+ if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
2759
+ var fakeNode = document.createElement('react');
2760
+
2761
+ var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
2762
+ // If document doesn't exist we know for sure we will crash in this method
2763
+ // when we call document.createEvent(). However this can cause confusing
2764
+ // errors: https://github.com/facebookincubator/create-react-app/issues/3482
2765
+ // So we preemptively throw with a better message instead.
2766
+ !(typeof document !== 'undefined') ? invariant(false, 'The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.') : void 0;
2767
+ var evt = document.createEvent('Event');
2768
+
2769
+ // Keeps track of whether the user-provided callback threw an error. We
2770
+ // set this to true at the beginning, then set it to false right after
2771
+ // calling the function. If the function errors, `didError` will never be
2772
+ // set to false. This strategy works even if the browser is flaky and
2773
+ // fails to call our global error handler, because it doesn't rely on
2774
+ // the error event at all.
2775
+ var didError = true;
2776
+
2777
+ // Create an event handler for our fake event. We will synchronously
2778
+ // dispatch our fake event using `dispatchEvent`. Inside the handler, we
2779
+ // call the user-provided callback.
2780
+ var funcArgs = Array.prototype.slice.call(arguments, 3);
2781
+ function callCallback() {
2782
+ // We immediately remove the callback from event listeners so that
2783
+ // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
2784
+ // nested call would trigger the fake event handlers of any call higher
2785
+ // in the stack.
2786
+ fakeNode.removeEventListener(evtType, callCallback, false);
2787
+ func.apply(context, funcArgs);
2788
+ didError = false;
2789
+ }
2790
+
2791
+ // Create a global error event handler. We use this to capture the value
2792
+ // that was thrown. It's possible that this error handler will fire more
2793
+ // than once; for example, if non-React code also calls `dispatchEvent`
2794
+ // and a handler for that event throws. We should be resilient to most of
2795
+ // those cases. Even if our error event handler fires more than once, the
2796
+ // last error event is always used. If the callback actually does error,
2797
+ // we know that the last error event is the correct one, because it's not
2798
+ // possible for anything else to have happened in between our callback
2799
+ // erroring and the code that follows the `dispatchEvent` call below. If
2800
+ // the callback doesn't error, but the error event was fired, we know to
2801
+ // ignore it because `didError` will be false, as described above.
2802
+ var error = void 0;
2803
+ // Use this to track whether the error event is ever called.
2804
+ var didSetError = false;
2805
+ var isCrossOriginError = false;
2806
+
2807
+ function onError(event) {
2808
+ error = event.error;
2809
+ didSetError = true;
2810
+ if (error === null && event.colno === 0 && event.lineno === 0) {
2811
+ isCrossOriginError = true;
2812
+ }
2813
+ }
2814
+
2815
+ // Create a fake event type.
2816
+ var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
2817
+
2818
+ // Attach our event handlers
2819
+ window.addEventListener('error', onError);
2820
+ fakeNode.addEventListener(evtType, callCallback, false);
2821
+
2822
+ // Synchronously dispatch our fake event. If the user-provided function
2823
+ // errors, it will trigger our global error handler.
2824
+ evt.initEvent(evtType, false, false);
2825
+ fakeNode.dispatchEvent(evt);
2826
+
2827
+ if (didError) {
2828
+ if (!didSetError) {
2829
+ // The callback errored, but the error event never fired.
2830
+ error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
2831
+ } else if (isCrossOriginError) {
2832
+ error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
2833
+ }
2834
+ this._hasCaughtError = true;
2835
+ this._caughtError = error;
2836
+ } else {
2837
+ this._hasCaughtError = false;
2838
+ this._caughtError = null;
2839
+ }
2840
+
2841
+ // Remove our event listeners
2842
+ window.removeEventListener('error', onError);
2843
+ };
2844
+
2845
+ invokeGuardedCallback = invokeGuardedCallbackDev;
2846
+ }
2847
+ }
2848
+
2849
+ var invokeGuardedCallback$1 = invokeGuardedCallback;
2850
+
2851
+ var ReactErrorUtils = {
2852
+ // Used by Fiber to simulate a try-catch.
2853
+ _caughtError: null,
2854
+ _hasCaughtError: false,
2855
+
2856
+ // Used by event system to capture/rethrow the first error.
2857
+ _rethrowError: null,
2858
+ _hasRethrowError: false,
2859
+
2860
+ /**
2861
+ * Call a function while guarding against errors that happens within it.
2862
+ * Returns an error if it throws, otherwise null.
2863
+ *
2864
+ * In production, this is implemented using a try-catch. The reason we don't
2865
+ * use a try-catch directly is so that we can swap out a different
2866
+ * implementation in DEV mode.
2867
+ *
2868
+ * @param {String} name of the guard to use for logging or debugging
2869
+ * @param {Function} func The function to invoke
2870
+ * @param {*} context The context to use when calling the function
2871
+ * @param {...*} args Arguments for function
2872
+ */
2873
+ invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) {
2874
+ invokeGuardedCallback$1.apply(ReactErrorUtils, arguments);
2875
+ },
2876
+
2877
+ /**
2878
+ * Same as invokeGuardedCallback, but instead of returning an error, it stores
2879
+ * it in a global so it can be rethrown by `rethrowCaughtError` later.
2880
+ * TODO: See if _caughtError and _rethrowError can be unified.
2881
+ *
2882
+ * @param {String} name of the guard to use for logging or debugging
2883
+ * @param {Function} func The function to invoke
2884
+ * @param {*} context The context to use when calling the function
2885
+ * @param {...*} args Arguments for function
2886
+ */
2887
+ invokeGuardedCallbackAndCatchFirstError: function (name, func, context, a, b, c, d, e, f) {
2888
+ ReactErrorUtils.invokeGuardedCallback.apply(this, arguments);
2889
+ if (ReactErrorUtils.hasCaughtError()) {
2890
+ var error = ReactErrorUtils.clearCaughtError();
2891
+ if (!ReactErrorUtils._hasRethrowError) {
2892
+ ReactErrorUtils._hasRethrowError = true;
2893
+ ReactErrorUtils._rethrowError = error;
2894
+ }
2895
+ }
2896
+ },
2897
+
2898
+ /**
2899
+ * During execution of guarded functions we will capture the first error which
2900
+ * we will rethrow to be handled by the top level error handler.
2901
+ */
2902
+ rethrowCaughtError: function () {
2903
+ return rethrowCaughtError.apply(ReactErrorUtils, arguments);
2904
+ },
2905
+
2906
+ hasCaughtError: function () {
2907
+ return ReactErrorUtils._hasCaughtError;
2908
+ },
2909
+
2910
+ clearCaughtError: function () {
2911
+ if (ReactErrorUtils._hasCaughtError) {
2912
+ var error = ReactErrorUtils._caughtError;
2913
+ ReactErrorUtils._caughtError = null;
2914
+ ReactErrorUtils._hasCaughtError = false;
2915
+ return error;
2916
+ } else {
2917
+ invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
2918
+ }
2919
+ }
2920
+ };
2921
+
2922
+ var rethrowCaughtError = function () {
2923
+ if (ReactErrorUtils._hasRethrowError) {
2924
+ var error = ReactErrorUtils._rethrowError;
2925
+ ReactErrorUtils._rethrowError = null;
2926
+ ReactErrorUtils._hasRethrowError = false;
2927
+ throw error;
2928
+ }
2929
+ };
2930
+
2931
+ /**
2932
+ * Injectable ordering of event plugins.
2933
+ */
2934
+ var eventPluginOrder = null;
2935
+
2936
+ /**
2937
+ * Injectable mapping from names to event plugin modules.
2938
+ */
2939
+ var namesToPlugins = {};
2940
+
2941
+ /**
2942
+ * Recomputes the plugin list using the injected plugins and plugin ordering.
2943
+ *
2944
+ * @private
2945
+ */
2946
+ function recomputePluginOrdering() {
2947
+ if (!eventPluginOrder) {
2948
+ // Wait until an `eventPluginOrder` is injected.
2949
+ return;
2950
+ }
2951
+ for (var pluginName in namesToPlugins) {
2952
+ var pluginModule = namesToPlugins[pluginName];
2953
+ var pluginIndex = eventPluginOrder.indexOf(pluginName);
2954
+ !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
2955
+ if (plugins[pluginIndex]) {
2956
+ continue;
2957
+ }
2958
+ !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
2959
+ plugins[pluginIndex] = pluginModule;
2960
+ var publishedEvents = pluginModule.eventTypes;
2961
+ for (var eventName in publishedEvents) {
2962
+ !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
2963
+ }
2964
+ }
2965
+ }
2966
+
2967
+ /**
2968
+ * Publishes an event so that it can be dispatched by the supplied plugin.
2969
+ *
2970
+ * @param {object} dispatchConfig Dispatch configuration for the event.
2971
+ * @param {object} PluginModule Plugin publishing the event.
2972
+ * @return {boolean} True if the event was successfully published.
2973
+ * @private
2974
+ */
2975
+ function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
2976
+ !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
2977
+ eventNameDispatchConfigs[eventName] = dispatchConfig;
2978
+
2979
+ var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
2980
+ if (phasedRegistrationNames) {
2981
+ for (var phaseName in phasedRegistrationNames) {
2982
+ if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
2983
+ var phasedRegistrationName = phasedRegistrationNames[phaseName];
2984
+ publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
2985
+ }
2986
+ }
2987
+ return true;
2988
+ } else if (dispatchConfig.registrationName) {
2989
+ publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
2990
+ return true;
2991
+ }
2992
+ return false;
2993
+ }
2994
+
2995
+ /**
2996
+ * Publishes a registration name that is used to identify dispatched events.
2997
+ *
2998
+ * @param {string} registrationName Registration name to add.
2999
+ * @param {object} PluginModule Plugin publishing the event.
3000
+ * @private
3001
+ */
3002
+ function publishRegistrationName(registrationName, pluginModule, eventName) {
3003
+ !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
3004
+ registrationNameModules[registrationName] = pluginModule;
3005
+ registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
3006
+
3007
+ {
3008
+ var lowerCasedName = registrationName.toLowerCase();
3009
+ possibleRegistrationNames[lowerCasedName] = registrationName;
3010
+
3011
+ if (registrationName === 'onDoubleClick') {
3012
+ possibleRegistrationNames.ondblclick = registrationName;
3013
+ }
3014
+ }
3015
+ }
3016
+
3017
+ /**
3018
+ * Registers plugins so that they can extract and dispatch events.
3019
+ *
3020
+ * @see {EventPluginHub}
3021
+ */
3022
+
3023
+ /**
3024
+ * Ordered list of injected plugins.
3025
+ */
3026
+ var plugins = [];
3027
+
3028
+ /**
3029
+ * Mapping from event name to dispatch config
3030
+ */
3031
+ var eventNameDispatchConfigs = {};
3032
+
3033
+ /**
3034
+ * Mapping from registration name to plugin module
3035
+ */
3036
+ var registrationNameModules = {};
3037
+
3038
+ /**
3039
+ * Mapping from registration name to event name
3040
+ */
3041
+ var registrationNameDependencies = {};
3042
+
3043
+ /**
3044
+ * Mapping from lowercase registration names to the properly cased version,
3045
+ * used to warn in the case of missing event handlers. Available
3046
+ * only in true.
3047
+ * @type {Object}
3048
+ */
3049
+ var possibleRegistrationNames = {};
3050
+ // Trust the developer to only use possibleRegistrationNames in true
3051
+
3052
+ /**
3053
+ * Injects an ordering of plugins (by plugin name). This allows the ordering
3054
+ * to be decoupled from injection of the actual plugins so that ordering is
3055
+ * always deterministic regardless of packaging, on-the-fly injection, etc.
3056
+ *
3057
+ * @param {array} InjectedEventPluginOrder
3058
+ * @internal
3059
+ * @see {EventPluginHub.injection.injectEventPluginOrder}
3060
+ */
3061
+ function injectEventPluginOrder(injectedEventPluginOrder) {
3062
+ !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;
3063
+ // Clone the ordering so it cannot be dynamically mutated.
3064
+ eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
3065
+ recomputePluginOrdering();
3066
+ }
3067
+
3068
+ /**
3069
+ * Injects plugins to be used by `EventPluginHub`. The plugin names must be
3070
+ * in the ordering injected by `injectEventPluginOrder`.
3071
+ *
3072
+ * Plugins can be injected as part of page initialization or on-the-fly.
3073
+ *
3074
+ * @param {object} injectedNamesToPlugins Map from names to plugin modules.
3075
+ * @internal
3076
+ * @see {EventPluginHub.injection.injectEventPluginsByName}
3077
+ */
3078
+ function injectEventPluginsByName(injectedNamesToPlugins) {
3079
+ var isOrderingDirty = false;
3080
+ for (var pluginName in injectedNamesToPlugins) {
3081
+ if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
3082
+ continue;
3083
+ }
3084
+ var pluginModule = injectedNamesToPlugins[pluginName];
3085
+ if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
3086
+ !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
3087
+ namesToPlugins[pluginName] = pluginModule;
3088
+ isOrderingDirty = true;
3089
+ }
3090
+ }
3091
+ if (isOrderingDirty) {
3092
+ recomputePluginOrdering();
3093
+ }
3094
+ }
3095
+
3096
+ var EventPluginRegistry = Object.freeze({
3097
+ plugins: plugins,
3098
+ eventNameDispatchConfigs: eventNameDispatchConfigs,
3099
+ registrationNameModules: registrationNameModules,
3100
+ registrationNameDependencies: registrationNameDependencies,
3101
+ possibleRegistrationNames: possibleRegistrationNames,
3102
+ injectEventPluginOrder: injectEventPluginOrder,
3103
+ injectEventPluginsByName: injectEventPluginsByName
3104
+ });
3105
+
3106
+ var getFiberCurrentPropsFromNode = null;
3107
+ var getInstanceFromNode = null;
3108
+ var getNodeFromInstance = null;
3109
+
3110
+ var injection$1 = {
3111
+ injectComponentTree: function (Injected) {
3112
+ getFiberCurrentPropsFromNode = Injected.getFiberCurrentPropsFromNode;
3113
+ getInstanceFromNode = Injected.getInstanceFromNode;
3114
+ getNodeFromInstance = Injected.getNodeFromInstance;
3115
+
3116
+ {
3117
+ !(getNodeFromInstance && getInstanceFromNode) ? warning(false, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
3118
+ }
3119
+ }
3120
+ };
3121
+
3122
+
3123
+
3124
+
3125
+
3126
+
3127
+ var validateEventDispatches = void 0;
3128
+ {
3129
+ validateEventDispatches = function (event) {
3130
+ var dispatchListeners = event._dispatchListeners;
3131
+ var dispatchInstances = event._dispatchInstances;
3132
+
3133
+ var listenersIsArr = Array.isArray(dispatchListeners);
3134
+ var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
3135
+
3136
+ var instancesIsArr = Array.isArray(dispatchInstances);
3137
+ var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
3138
+
3139
+ !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warning(false, 'EventPluginUtils: Invalid `event`.') : void 0;
3140
+ };
3141
+ }
3142
+
3143
+ /**
3144
+ * Dispatch the event to the listener.
3145
+ * @param {SyntheticEvent} event SyntheticEvent to handle
3146
+ * @param {boolean} simulated If the event is simulated (changes exn behavior)
3147
+ * @param {function} listener Application-level callback
3148
+ * @param {*} inst Internal component instance
3149
+ */
3150
+ function executeDispatch(event, simulated, listener, inst) {
3151
+ var type = event.type || 'unknown-event';
3152
+ event.currentTarget = getNodeFromInstance(inst);
3153
+ ReactErrorUtils.invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
3154
+ event.currentTarget = null;
3155
+ }
3156
+
3157
+ /**
3158
+ * Standard/simple iteration through an event's collected dispatches.
3159
+ */
3160
+ function executeDispatchesInOrder(event, simulated) {
3161
+ var dispatchListeners = event._dispatchListeners;
3162
+ var dispatchInstances = event._dispatchInstances;
3163
+ {
3164
+ validateEventDispatches(event);
3165
+ }
3166
+ if (Array.isArray(dispatchListeners)) {
3167
+ for (var i = 0; i < dispatchListeners.length; i++) {
3168
+ if (event.isPropagationStopped()) {
3169
+ break;
3170
+ }
3171
+ // Listeners and Instances are two parallel arrays that are always in sync.
3172
+ executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]);
3173
+ }
3174
+ } else if (dispatchListeners) {
3175
+ executeDispatch(event, simulated, dispatchListeners, dispatchInstances);
3176
+ }
3177
+ event._dispatchListeners = null;
3178
+ event._dispatchInstances = null;
3179
+ }
3180
+
3181
+ /**
3182
+ * @see executeDispatchesInOrderStopAtTrueImpl
3183
+ */
3184
+
3185
+
3186
+ /**
3187
+ * Execution of a "direct" dispatch - there must be at most one dispatch
3188
+ * accumulated on the event or it is considered an error. It doesn't really make
3189
+ * sense for an event with multiple dispatches (bubbled) to keep track of the
3190
+ * return values at each dispatch execution, but it does tend to make sense when
3191
+ * dealing with "direct" dispatches.
3192
+ *
3193
+ * @return {*} The return value of executing the single dispatch.
3194
+ */
3195
+
3196
+
3197
+ /**
3198
+ * @param {SyntheticEvent} event
3199
+ * @return {boolean} True iff number of dispatches accumulated is greater than 0.
3200
+ */
3201
+
3202
+ /**
3203
+ * Accumulates items that must not be null or undefined into the first one. This
3204
+ * is used to conserve memory by avoiding array allocations, and thus sacrifices
3205
+ * API cleanness. Since `current` can be null before being passed in and not
3206
+ * null after this function, make sure to assign it back to `current`:
3207
+ *
3208
+ * `a = accumulateInto(a, b);`
3209
+ *
3210
+ * This API should be sparingly used. Try `accumulate` for something cleaner.
3211
+ *
3212
+ * @return {*|array<*>} An accumulation of items.
3213
+ */
3214
+
3215
+ function accumulateInto(current, next) {
3216
+ !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
3217
+
3218
+ if (current == null) {
3219
+ return next;
3220
+ }
3221
+
3222
+ // Both are not empty. Warning: Never call x.concat(y) when you are not
3223
+ // certain that x is an Array (x could be a string with concat method).
3224
+ if (Array.isArray(current)) {
3225
+ if (Array.isArray(next)) {
3226
+ current.push.apply(current, next);
3227
+ return current;
3228
+ }
3229
+ current.push(next);
3230
+ return current;
3231
+ }
3232
+
3233
+ if (Array.isArray(next)) {
3234
+ // A bit too dangerous to mutate `next`.
3235
+ return [current].concat(next);
3236
+ }
3237
+
3238
+ return [current, next];
3239
+ }
3240
+
3241
+ /**
3242
+ * @param {array} arr an "accumulation" of items which is either an Array or
3243
+ * a single item. Useful when paired with the `accumulate` module. This is a
3244
+ * simple utility that allows us to reason about a collection of items, but
3245
+ * handling the case when there is exactly one item (and we do not need to
3246
+ * allocate an array).
3247
+ * @param {function} cb Callback invoked with each element or a collection.
3248
+ * @param {?} [scope] Scope used as `this` in a callback.
3249
+ */
3250
+ function forEachAccumulated(arr, cb, scope) {
3251
+ if (Array.isArray(arr)) {
3252
+ arr.forEach(cb, scope);
3253
+ } else if (arr) {
3254
+ cb.call(scope, arr);
3255
+ }
3256
+ }
3257
+
3258
+ /**
3259
+ * Internal queue of events that have accumulated their dispatches and are
3260
+ * waiting to have their dispatches executed.
3261
+ */
3262
+ var eventQueue = null;
3263
+
3264
+ /**
3265
+ * Dispatches an event and releases it back into the pool, unless persistent.
3266
+ *
3267
+ * @param {?object} event Synthetic event to be dispatched.
3268
+ * @param {boolean} simulated If the event is simulated (changes exn behavior)
3269
+ * @private
3270
+ */
3271
+ var executeDispatchesAndRelease = function (event, simulated) {
3272
+ if (event) {
3273
+ executeDispatchesInOrder(event, simulated);
3274
+
3275
+ if (!event.isPersistent()) {
3276
+ event.constructor.release(event);
3277
+ }
3278
+ }
3279
+ };
3280
+ var executeDispatchesAndReleaseSimulated = function (e) {
3281
+ return executeDispatchesAndRelease(e, true);
3282
+ };
3283
+ var executeDispatchesAndReleaseTopLevel = function (e) {
3284
+ return executeDispatchesAndRelease(e, false);
3285
+ };
3286
+
3287
+ function isInteractive(tag) {
3288
+ return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
3289
+ }
3290
+
3291
+ function shouldPreventMouseEvent(name, type, props) {
3292
+ switch (name) {
3293
+ case 'onClick':
3294
+ case 'onClickCapture':
3295
+ case 'onDoubleClick':
3296
+ case 'onDoubleClickCapture':
3297
+ case 'onMouseDown':
3298
+ case 'onMouseDownCapture':
3299
+ case 'onMouseMove':
3300
+ case 'onMouseMoveCapture':
3301
+ case 'onMouseUp':
3302
+ case 'onMouseUpCapture':
3303
+ return !!(props.disabled && isInteractive(type));
3304
+ default:
3305
+ return false;
3306
+ }
3307
+ }
3308
+
3309
+ /**
3310
+ * This is a unified interface for event plugins to be installed and configured.
3311
+ *
3312
+ * Event plugins can implement the following properties:
3313
+ *
3314
+ * `extractEvents` {function(string, DOMEventTarget, string, object): *}
3315
+ * Required. When a top-level event is fired, this method is expected to
3316
+ * extract synthetic events that will in turn be queued and dispatched.
3317
+ *
3318
+ * `eventTypes` {object}
3319
+ * Optional, plugins that fire events must publish a mapping of registration
3320
+ * names that are used to register listeners. Values of this mapping must
3321
+ * be objects that contain `registrationName` or `phasedRegistrationNames`.
3322
+ *
3323
+ * `executeDispatch` {function(object, function, string)}
3324
+ * Optional, allows plugins to override how an event gets dispatched. By
3325
+ * default, the listener is simply invoked.
3326
+ *
3327
+ * Each plugin that is injected into `EventsPluginHub` is immediately operable.
3328
+ *
3329
+ * @public
3330
+ */
3331
+
3332
+ /**
3333
+ * Methods for injecting dependencies.
3334
+ */
3335
+ var injection = {
3336
+ /**
3337
+ * @param {array} InjectedEventPluginOrder
3338
+ * @public
3339
+ */
3340
+ injectEventPluginOrder: injectEventPluginOrder,
3341
+
3342
+ /**
3343
+ * @param {object} injectedNamesToPlugins Map from names to plugin modules.
3344
+ */
3345
+ injectEventPluginsByName: injectEventPluginsByName
3346
+ };
3347
+
3348
+ /**
3349
+ * @param {object} inst The instance, which is the source of events.
3350
+ * @param {string} registrationName Name of listener (e.g. `onClick`).
3351
+ * @return {?function} The stored callback.
3352
+ */
3353
+ function getListener(inst, registrationName) {
3354
+ var listener = void 0;
3355
+
3356
+ // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
3357
+ // live here; needs to be moved to a better place soon
3358
+ var stateNode = inst.stateNode;
3359
+ if (!stateNode) {
3360
+ // Work in progress (ex: onload events in incremental mode).
3361
+ return null;
3362
+ }
3363
+ var props = getFiberCurrentPropsFromNode(stateNode);
3364
+ if (!props) {
3365
+ // Work in progress.
3366
+ return null;
3367
+ }
3368
+ listener = props[registrationName];
3369
+ if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
3370
+ return null;
3371
+ }
3372
+ !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
3373
+ return listener;
3374
+ }
3375
+
3376
+ /**
3377
+ * Allows registered plugins an opportunity to extract events from top-level
3378
+ * native browser events.
3379
+ *
3380
+ * @return {*} An accumulation of synthetic events.
3381
+ * @internal
3382
+ */
3383
+ function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3384
+ var events = null;
3385
+ for (var i = 0; i < plugins.length; i++) {
3386
+ // Not every plugin in the ordering may be loaded at runtime.
3387
+ var possiblePlugin = plugins[i];
3388
+ if (possiblePlugin) {
3389
+ var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
3390
+ if (extractedEvents) {
3391
+ events = accumulateInto(events, extractedEvents);
3392
+ }
3393
+ }
3394
+ }
3395
+ return events;
3396
+ }
3397
+
3398
+ function runEventsInBatch(events, simulated) {
3399
+ if (events !== null) {
3400
+ eventQueue = accumulateInto(eventQueue, events);
3401
+ }
3402
+
3403
+ // Set `eventQueue` to null before processing it so that we can tell if more
3404
+ // events get enqueued while processing.
3405
+ var processingEventQueue = eventQueue;
3406
+ eventQueue = null;
3407
+
3408
+ if (!processingEventQueue) {
3409
+ return;
3410
+ }
3411
+
3412
+ if (simulated) {
3413
+ forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
3414
+ } else {
3415
+ forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
3416
+ }
3417
+ !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
3418
+ // This would be a good time to rethrow if any of the event handlers threw.
3419
+ ReactErrorUtils.rethrowCaughtError();
3420
+ }
3421
+
3422
+ function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3423
+ var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
3424
+ runEventsInBatch(events, false);
3425
+ }
3426
+
3427
+ var EventPluginHub = Object.freeze({
3428
+ injection: injection,
3429
+ getListener: getListener,
3430
+ runEventsInBatch: runEventsInBatch,
3431
+ runExtractedEventsInBatch: runExtractedEventsInBatch
3432
+ });
3433
+
3434
+ var IndeterminateComponent = 0; // Before we know whether it is functional or class
3435
+ var FunctionalComponent = 1;
3436
+ var ClassComponent = 2;
3437
+ var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
3438
+ var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
3439
+ var HostComponent = 5;
3440
+ var HostText = 6;
3441
+ var CallComponent = 7;
3442
+ var CallHandlerPhase = 8;
3443
+ var ReturnComponent = 9;
3444
+ var Fragment = 10;
3445
+ var Mode = 11;
3446
+ var ContextConsumer = 12;
3447
+ var ContextProvider = 13;
3448
+ var ForwardRef = 14;
3449
+
3450
+ var randomKey = Math.random().toString(36).slice(2);
3451
+ var internalInstanceKey = '__reactInternalInstance$' + randomKey;
3452
+ var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
3453
+
3454
+ function precacheFiberNode$1(hostInst, node) {
3455
+ node[internalInstanceKey] = hostInst;
3456
+ }
3457
+
3458
+ /**
3459
+ * Given a DOM node, return the closest ReactDOMComponent or
3460
+ * ReactDOMTextComponent instance ancestor.
3461
+ */
3462
+ function getClosestInstanceFromNode(node) {
3463
+ if (node[internalInstanceKey]) {
3464
+ return node[internalInstanceKey];
3465
+ }
3466
+
3467
+ while (!node[internalInstanceKey]) {
3468
+ if (node.parentNode) {
3469
+ node = node.parentNode;
3470
+ } else {
3471
+ // Top of the tree. This node must not be part of a React tree (or is
3472
+ // unmounted, potentially).
3473
+ return null;
3474
+ }
3475
+ }
3476
+
3477
+ var inst = node[internalInstanceKey];
3478
+ if (inst.tag === HostComponent || inst.tag === HostText) {
3479
+ // In Fiber, this will always be the deepest root.
3480
+ return inst;
3481
+ }
3482
+
3483
+ return null;
3484
+ }
3485
+
3486
+ /**
3487
+ * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
3488
+ * instance, or null if the node was not rendered by this React.
3489
+ */
3490
+ function getInstanceFromNode$1(node) {
3491
+ var inst = node[internalInstanceKey];
3492
+ if (inst) {
3493
+ if (inst.tag === HostComponent || inst.tag === HostText) {
3494
+ return inst;
3495
+ } else {
3496
+ return null;
3497
+ }
3498
+ }
3499
+ return null;
3500
+ }
3501
+
3502
+ /**
3503
+ * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
3504
+ * DOM node.
3505
+ */
3506
+ function getNodeFromInstance$1(inst) {
3507
+ if (inst.tag === HostComponent || inst.tag === HostText) {
3508
+ // In Fiber this, is just the state node right now. We assume it will be
3509
+ // a host component or host text.
3510
+ return inst.stateNode;
3511
+ }
3512
+
3513
+ // Without this first invariant, passing a non-DOM-component triggers the next
3514
+ // invariant for a missing parent, which is super confusing.
3515
+ invariant(false, 'getNodeFromInstance: Invalid argument.');
3516
+ }
3517
+
3518
+ function getFiberCurrentPropsFromNode$1(node) {
3519
+ return node[internalEventHandlersKey] || null;
3520
+ }
3521
+
3522
+ function updateFiberProps$1(node, props) {
3523
+ node[internalEventHandlersKey] = props;
3524
+ }
3525
+
3526
+ var ReactDOMComponentTree = Object.freeze({
3527
+ precacheFiberNode: precacheFiberNode$1,
3528
+ getClosestInstanceFromNode: getClosestInstanceFromNode,
3529
+ getInstanceFromNode: getInstanceFromNode$1,
3530
+ getNodeFromInstance: getNodeFromInstance$1,
3531
+ getFiberCurrentPropsFromNode: getFiberCurrentPropsFromNode$1,
3532
+ updateFiberProps: updateFiberProps$1
3533
+ });
3534
+
3535
+ function getParent(inst) {
3536
+ do {
3537
+ inst = inst['return'];
3538
+ // TODO: If this is a HostRoot we might want to bail out.
3539
+ // That is depending on if we want nested subtrees (layers) to bubble
3540
+ // events to their parent. We could also go through parentNode on the
3541
+ // host node but that wouldn't work for React Native and doesn't let us
3542
+ // do the portal feature.
3543
+ } while (inst && inst.tag !== HostComponent);
3544
+ if (inst) {
3545
+ return inst;
3546
+ }
3547
+ return null;
3548
+ }
3549
+
3550
+ /**
3551
+ * Return the lowest common ancestor of A and B, or null if they are in
3552
+ * different trees.
3553
+ */
3554
+ function getLowestCommonAncestor(instA, instB) {
3555
+ var depthA = 0;
3556
+ for (var tempA = instA; tempA; tempA = getParent(tempA)) {
3557
+ depthA++;
3558
+ }
3559
+ var depthB = 0;
3560
+ for (var tempB = instB; tempB; tempB = getParent(tempB)) {
3561
+ depthB++;
3562
+ }
3563
+
3564
+ // If A is deeper, crawl up.
3565
+ while (depthA - depthB > 0) {
3566
+ instA = getParent(instA);
3567
+ depthA--;
3568
+ }
3569
+
3570
+ // If B is deeper, crawl up.
3571
+ while (depthB - depthA > 0) {
3572
+ instB = getParent(instB);
3573
+ depthB--;
3574
+ }
3575
+
3576
+ // Walk in lockstep until we find a match.
3577
+ var depth = depthA;
3578
+ while (depth--) {
3579
+ if (instA === instB || instA === instB.alternate) {
3580
+ return instA;
3581
+ }
3582
+ instA = getParent(instA);
3583
+ instB = getParent(instB);
3584
+ }
3585
+ return null;
3586
+ }
3587
+
3588
+ /**
3589
+ * Return if A is an ancestor of B.
3590
+ */
3591
+
3592
+
3593
+ /**
3594
+ * Return the parent instance of the passed-in instance.
3595
+ */
3596
+ function getParentInstance(inst) {
3597
+ return getParent(inst);
3598
+ }
3599
+
3600
+ /**
3601
+ * Simulates the traversal of a two-phase, capture/bubble event dispatch.
3602
+ */
3603
+ function traverseTwoPhase(inst, fn, arg) {
3604
+ var path = [];
3605
+ while (inst) {
3606
+ path.push(inst);
3607
+ inst = getParent(inst);
3608
+ }
3609
+ var i = void 0;
3610
+ for (i = path.length; i-- > 0;) {
3611
+ fn(path[i], 'captured', arg);
3612
+ }
3613
+ for (i = 0; i < path.length; i++) {
3614
+ fn(path[i], 'bubbled', arg);
3615
+ }
3616
+ }
3617
+
3618
+ /**
3619
+ * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
3620
+ * should would receive a `mouseEnter` or `mouseLeave` event.
3621
+ *
3622
+ * Does not invoke the callback on the nearest common ancestor because nothing
3623
+ * "entered" or "left" that element.
3624
+ */
3625
+ function traverseEnterLeave(from, to, fn, argFrom, argTo) {
3626
+ var common = from && to ? getLowestCommonAncestor(from, to) : null;
3627
+ var pathFrom = [];
3628
+ while (true) {
3629
+ if (!from) {
3630
+ break;
3631
+ }
3632
+ if (from === common) {
3633
+ break;
3634
+ }
3635
+ var alternate = from.alternate;
3636
+ if (alternate !== null && alternate === common) {
3637
+ break;
3638
+ }
3639
+ pathFrom.push(from);
3640
+ from = getParent(from);
3641
+ }
3642
+ var pathTo = [];
3643
+ while (true) {
3644
+ if (!to) {
3645
+ break;
3646
+ }
3647
+ if (to === common) {
3648
+ break;
3649
+ }
3650
+ var _alternate = to.alternate;
3651
+ if (_alternate !== null && _alternate === common) {
3652
+ break;
3653
+ }
3654
+ pathTo.push(to);
3655
+ to = getParent(to);
3656
+ }
3657
+ for (var i = 0; i < pathFrom.length; i++) {
3658
+ fn(pathFrom[i], 'bubbled', argFrom);
3659
+ }
3660
+ for (var _i = pathTo.length; _i-- > 0;) {
3661
+ fn(pathTo[_i], 'captured', argTo);
3662
+ }
3663
+ }
3664
+
3665
+ /**
3666
+ * Some event types have a notion of different registration names for different
3667
+ * "phases" of propagation. This finds listeners by a given phase.
3668
+ */
3669
+ function listenerAtPhase(inst, event, propagationPhase) {
3670
+ var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
3671
+ return getListener(inst, registrationName);
3672
+ }
3673
+
3674
+ /**
3675
+ * A small set of propagation patterns, each of which will accept a small amount
3676
+ * of information, and generate a set of "dispatch ready event objects" - which
3677
+ * are sets of events that have already been annotated with a set of dispatched
3678
+ * listener functions/ids. The API is designed this way to discourage these
3679
+ * propagation strategies from actually executing the dispatches, since we
3680
+ * always want to collect the entire set of dispatches before executing even a
3681
+ * single one.
3682
+ */
3683
+
3684
+ /**
3685
+ * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
3686
+ * here, allows us to not have to bind or create functions for each event.
3687
+ * Mutating the event's members allows us to not have to create a wrapping
3688
+ * "dispatch" object that pairs the event with the listener.
3689
+ */
3690
+ function accumulateDirectionalDispatches(inst, phase, event) {
3691
+ {
3692
+ !inst ? warning(false, 'Dispatching inst must not be null') : void 0;
3693
+ }
3694
+ var listener = listenerAtPhase(inst, event, phase);
3695
+ if (listener) {
3696
+ event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
3697
+ event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
3698
+ }
3699
+ }
3700
+
3701
+ /**
3702
+ * Collect dispatches (must be entirely collected before dispatching - see unit
3703
+ * tests). Lazily allocate the array to conserve memory. We must loop through
3704
+ * each event and perform the traversal for each one. We cannot perform a
3705
+ * single traversal for the entire collection of events because each event may
3706
+ * have a different target.
3707
+ */
3708
+ function accumulateTwoPhaseDispatchesSingle(event) {
3709
+ if (event && event.dispatchConfig.phasedRegistrationNames) {
3710
+ traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
3711
+ }
3712
+ }
3713
+
3714
+ /**
3715
+ * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
3716
+ */
3717
+ function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
3718
+ if (event && event.dispatchConfig.phasedRegistrationNames) {
3719
+ var targetInst = event._targetInst;
3720
+ var parentInst = targetInst ? getParentInstance(targetInst) : null;
3721
+ traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
3722
+ }
3723
+ }
3724
+
3725
+ /**
3726
+ * Accumulates without regard to direction, does not look for phased
3727
+ * registration names. Same as `accumulateDirectDispatchesSingle` but without
3728
+ * requiring that the `dispatchMarker` be the same as the dispatched ID.
3729
+ */
3730
+ function accumulateDispatches(inst, ignoredDirection, event) {
3731
+ if (inst && event && event.dispatchConfig.registrationName) {
3732
+ var registrationName = event.dispatchConfig.registrationName;
3733
+ var listener = getListener(inst, registrationName);
3734
+ if (listener) {
3735
+ event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
3736
+ event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
3737
+ }
3738
+ }
3739
+ }
3740
+
3741
+ /**
3742
+ * Accumulates dispatches on an `SyntheticEvent`, but only for the
3743
+ * `dispatchMarker`.
3744
+ * @param {SyntheticEvent} event
3745
+ */
3746
+ function accumulateDirectDispatchesSingle(event) {
3747
+ if (event && event.dispatchConfig.registrationName) {
3748
+ accumulateDispatches(event._targetInst, null, event);
3749
+ }
3750
+ }
3751
+
3752
+ function accumulateTwoPhaseDispatches(events) {
3753
+ forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
3754
+ }
3755
+
3756
+ function accumulateTwoPhaseDispatchesSkipTarget(events) {
3757
+ forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
3758
+ }
3759
+
3760
+ function accumulateEnterLeaveDispatches(leave, enter, from, to) {
3761
+ traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
3762
+ }
3763
+
3764
+ function accumulateDirectDispatches(events) {
3765
+ forEachAccumulated(events, accumulateDirectDispatchesSingle);
3766
+ }
3767
+
3768
+ var EventPropagators = Object.freeze({
3769
+ accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
3770
+ accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
3771
+ accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
3772
+ accumulateDirectDispatches: accumulateDirectDispatches
3773
+ });
3774
+
3775
+ var contentKey = null;
3776
+
3777
+ /**
3778
+ * Gets the key used to access text content on a DOM node.
3779
+ *
3780
+ * @return {?string} Key used to access text content.
3781
+ * @internal
3782
+ */
3783
+ function getTextContentAccessor() {
3784
+ if (!contentKey && ExecutionEnvironment.canUseDOM) {
3785
+ // Prefer textContent to innerText because many browsers support both but
3786
+ // SVG <text> elements don't support innerText even when <div> does.
3787
+ contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
3788
+ }
3789
+ return contentKey;
3790
+ }
3791
+
3792
+ /**
3793
+ * This helper object stores information about text content of a target node,
3794
+ * allowing comparison of content before and after a given event.
3795
+ *
3796
+ * Identify the node where selection currently begins, then observe
3797
+ * both its text content and its current position in the DOM. Since the
3798
+ * browser may natively replace the target node during composition, we can
3799
+ * use its position to find its replacement.
3800
+ *
3801
+ *
3802
+ */
3803
+ var compositionState = {
3804
+ _root: null,
3805
+ _startText: null,
3806
+ _fallbackText: null
3807
+ };
3808
+
3809
+ function initialize(nativeEventTarget) {
3810
+ compositionState._root = nativeEventTarget;
3811
+ compositionState._startText = getText();
3812
+ return true;
3813
+ }
3814
+
3815
+ function reset() {
3816
+ compositionState._root = null;
3817
+ compositionState._startText = null;
3818
+ compositionState._fallbackText = null;
3819
+ }
3820
+
3821
+ function getData() {
3822
+ if (compositionState._fallbackText) {
3823
+ return compositionState._fallbackText;
3824
+ }
3825
+
3826
+ var start = void 0;
3827
+ var startValue = compositionState._startText;
3828
+ var startLength = startValue.length;
3829
+ var end = void 0;
3830
+ var endValue = getText();
3831
+ var endLength = endValue.length;
3832
+
3833
+ for (start = 0; start < startLength; start++) {
3834
+ if (startValue[start] !== endValue[start]) {
3835
+ break;
3836
+ }
3837
+ }
3838
+
3839
+ var minEnd = startLength - start;
3840
+ for (end = 1; end <= minEnd; end++) {
3841
+ if (startValue[startLength - end] !== endValue[endLength - end]) {
3842
+ break;
3843
+ }
3844
+ }
3845
+
3846
+ var sliceTail = end > 1 ? 1 - end : undefined;
3847
+ compositionState._fallbackText = endValue.slice(start, sliceTail);
3848
+ return compositionState._fallbackText;
3849
+ }
3850
+
3851
+ function getText() {
3852
+ if ('value' in compositionState._root) {
3853
+ return compositionState._root.value;
3854
+ }
3855
+ return compositionState._root[getTextContentAccessor()];
3856
+ }
3857
+
3858
+ /* eslint valid-typeof: 0 */
3859
+
3860
+ var didWarnForAddedNewProperty = false;
3861
+ var EVENT_POOL_SIZE = 10;
3862
+
3863
+ var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];
3864
+
3865
+ /**
3866
+ * @interface Event
3867
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
3868
+ */
3869
+ var EventInterface = {
3870
+ type: null,
3871
+ target: null,
3872
+ // currentTarget is set when dispatching; no use in copying it here
3873
+ currentTarget: emptyFunction.thatReturnsNull,
3874
+ eventPhase: null,
3875
+ bubbles: null,
3876
+ cancelable: null,
3877
+ timeStamp: function (event) {
3878
+ return event.timeStamp || Date.now();
3879
+ },
3880
+ defaultPrevented: null,
3881
+ isTrusted: null
3882
+ };
3883
+
3884
+ /**
3885
+ * Synthetic events are dispatched by event plugins, typically in response to a
3886
+ * top-level event delegation handler.
3887
+ *
3888
+ * These systems should generally use pooling to reduce the frequency of garbage
3889
+ * collection. The system should check `isPersistent` to determine whether the
3890
+ * event should be released into the pool after being dispatched. Users that
3891
+ * need a persisted event should invoke `persist`.
3892
+ *
3893
+ * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
3894
+ * normalizing browser quirks. Subclasses do not necessarily have to implement a
3895
+ * DOM interface; custom application-specific events can also subclass this.
3896
+ *
3897
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
3898
+ * @param {*} targetInst Marker identifying the event target.
3899
+ * @param {object} nativeEvent Native browser event.
3900
+ * @param {DOMEventTarget} nativeEventTarget Target node.
3901
+ */
3902
+ function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
3903
+ {
3904
+ // these have a getter/setter for warnings
3905
+ delete this.nativeEvent;
3906
+ delete this.preventDefault;
3907
+ delete this.stopPropagation;
3908
+ }
3909
+
3910
+ this.dispatchConfig = dispatchConfig;
3911
+ this._targetInst = targetInst;
3912
+ this.nativeEvent = nativeEvent;
3913
+
3914
+ var Interface = this.constructor.Interface;
3915
+ for (var propName in Interface) {
3916
+ if (!Interface.hasOwnProperty(propName)) {
3917
+ continue;
3918
+ }
3919
+ {
3920
+ delete this[propName]; // this has a getter/setter for warnings
3921
+ }
3922
+ var normalize = Interface[propName];
3923
+ if (normalize) {
3924
+ this[propName] = normalize(nativeEvent);
3925
+ } else {
3926
+ if (propName === 'target') {
3927
+ this.target = nativeEventTarget;
3928
+ } else {
3929
+ this[propName] = nativeEvent[propName];
3930
+ }
3931
+ }
3932
+ }
3933
+
3934
+ var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
3935
+ if (defaultPrevented) {
3936
+ this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
3937
+ } else {
3938
+ this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
3939
+ }
3940
+ this.isPropagationStopped = emptyFunction.thatReturnsFalse;
3941
+ return this;
3942
+ }
3943
+
3944
+ _assign(SyntheticEvent.prototype, {
3945
+ preventDefault: function () {
3946
+ this.defaultPrevented = true;
3947
+ var event = this.nativeEvent;
3948
+ if (!event) {
3949
+ return;
3950
+ }
3951
+
3952
+ if (event.preventDefault) {
3953
+ event.preventDefault();
3954
+ } else if (typeof event.returnValue !== 'unknown') {
3955
+ event.returnValue = false;
3956
+ }
3957
+ this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
3958
+ },
3959
+
3960
+ stopPropagation: function () {
3961
+ var event = this.nativeEvent;
3962
+ if (!event) {
3963
+ return;
3964
+ }
3965
+
3966
+ if (event.stopPropagation) {
3967
+ event.stopPropagation();
3968
+ } else if (typeof event.cancelBubble !== 'unknown') {
3969
+ // The ChangeEventPlugin registers a "propertychange" event for
3970
+ // IE. This event does not support bubbling or cancelling, and
3971
+ // any references to cancelBubble throw "Member not found". A
3972
+ // typeof check of "unknown" circumvents this issue (and is also
3973
+ // IE specific).
3974
+ event.cancelBubble = true;
3975
+ }
3976
+
3977
+ this.isPropagationStopped = emptyFunction.thatReturnsTrue;
3978
+ },
3979
+
3980
+ /**
3981
+ * We release all dispatched `SyntheticEvent`s after each event loop, adding
3982
+ * them back into the pool. This allows a way to hold onto a reference that
3983
+ * won't be added back into the pool.
3984
+ */
3985
+ persist: function () {
3986
+ this.isPersistent = emptyFunction.thatReturnsTrue;
3987
+ },
3988
+
3989
+ /**
3990
+ * Checks if this event should be released back into the pool.
3991
+ *
3992
+ * @return {boolean} True if this should not be released, false otherwise.
3993
+ */
3994
+ isPersistent: emptyFunction.thatReturnsFalse,
3995
+
3996
+ /**
3997
+ * `PooledClass` looks for `destructor` on each instance it releases.
3998
+ */
3999
+ destructor: function () {
4000
+ var Interface = this.constructor.Interface;
4001
+ for (var propName in Interface) {
4002
+ {
4003
+ Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
4004
+ }
4005
+ }
4006
+ for (var i = 0; i < shouldBeReleasedProperties.length; i++) {
4007
+ this[shouldBeReleasedProperties[i]] = null;
4008
+ }
4009
+ {
4010
+ Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
4011
+ Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction));
4012
+ Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction));
4013
+ }
4014
+ }
4015
+ });
4016
+
4017
+ SyntheticEvent.Interface = EventInterface;
4018
+
4019
+ /**
4020
+ * Helper to reduce boilerplate when creating subclasses.
4021
+ */
4022
+ SyntheticEvent.extend = function (Interface) {
4023
+ var Super = this;
4024
+
4025
+ var E = function () {};
4026
+ E.prototype = Super.prototype;
4027
+ var prototype = new E();
4028
+
4029
+ function Class() {
4030
+ return Super.apply(this, arguments);
4031
+ }
4032
+ _assign(prototype, Class.prototype);
4033
+ Class.prototype = prototype;
4034
+ Class.prototype.constructor = Class;
4035
+
4036
+ Class.Interface = _assign({}, Super.Interface, Interface);
4037
+ Class.extend = Super.extend;
4038
+ addEventPoolingTo(Class);
4039
+
4040
+ return Class;
4041
+ };
4042
+
4043
+ /** Proxying after everything set on SyntheticEvent
4044
+ * to resolve Proxy issue on some WebKit browsers
4045
+ * in which some Event properties are set to undefined (GH#10010)
4046
+ */
4047
+ {
4048
+ var isProxySupported = typeof Proxy === 'function' &&
4049
+ // https://github.com/facebook/react/issues/12011
4050
+ !Object.isSealed(new Proxy({}, {}));
4051
+
4052
+ if (isProxySupported) {
4053
+ /*eslint-disable no-func-assign */
4054
+ SyntheticEvent = new Proxy(SyntheticEvent, {
4055
+ construct: function (target, args) {
4056
+ return this.apply(target, Object.create(target.prototype), args);
4057
+ },
4058
+ apply: function (constructor, that, args) {
4059
+ return new Proxy(constructor.apply(that, args), {
4060
+ set: function (target, prop, value) {
4061
+ if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {
4062
+ !(didWarnForAddedNewProperty || target.isPersistent()) ? warning(false, "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0;
4063
+ didWarnForAddedNewProperty = true;
4064
+ }
4065
+ target[prop] = value;
4066
+ return true;
4067
+ }
4068
+ });
4069
+ }
4070
+ });
4071
+ /*eslint-enable no-func-assign */
4072
+ }
4073
+ }
4074
+
4075
+ addEventPoolingTo(SyntheticEvent);
4076
+
4077
+ /**
4078
+ * Helper to nullify syntheticEvent instance properties when destructing
4079
+ *
4080
+ * @param {String} propName
4081
+ * @param {?object} getVal
4082
+ * @return {object} defineProperty object
4083
+ */
4084
+ function getPooledWarningPropertyDefinition(propName, getVal) {
4085
+ var isFunction = typeof getVal === 'function';
4086
+ return {
4087
+ configurable: true,
4088
+ set: set,
4089
+ get: get
4090
+ };
4091
+
4092
+ function set(val) {
4093
+ var action = isFunction ? 'setting the method' : 'setting the property';
4094
+ warn(action, 'This is effectively a no-op');
4095
+ return val;
4096
+ }
4097
+
4098
+ function get() {
4099
+ var action = isFunction ? 'accessing the method' : 'accessing the property';
4100
+ var result = isFunction ? 'This is a no-op function' : 'This is set to null';
4101
+ warn(action, result);
4102
+ return getVal;
4103
+ }
4104
+
4105
+ function warn(action, result) {
4106
+ var warningCondition = false;
4107
+ !warningCondition ? warning(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
4108
+ }
4109
+ }
4110
+
4111
+ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
4112
+ var EventConstructor = this;
4113
+ if (EventConstructor.eventPool.length) {
4114
+ var instance = EventConstructor.eventPool.pop();
4115
+ EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
4116
+ return instance;
4117
+ }
4118
+ return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
4119
+ }
4120
+
4121
+ function releasePooledEvent(event) {
4122
+ var EventConstructor = this;
4123
+ !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
4124
+ event.destructor();
4125
+ if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
4126
+ EventConstructor.eventPool.push(event);
4127
+ }
4128
+ }
4129
+
4130
+ function addEventPoolingTo(EventConstructor) {
4131
+ EventConstructor.eventPool = [];
4132
+ EventConstructor.getPooled = getPooledEvent;
4133
+ EventConstructor.release = releasePooledEvent;
4134
+ }
4135
+
4136
+ var SyntheticEvent$1 = SyntheticEvent;
4137
+
4138
+ /**
4139
+ * @interface Event
4140
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
4141
+ */
4142
+ var SyntheticCompositionEvent = SyntheticEvent$1.extend({
4143
+ data: null
4144
+ });
4145
+
4146
+ /**
4147
+ * @interface Event
4148
+ * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
4149
+ * /#events-inputevents
4150
+ */
4151
+ var SyntheticInputEvent = SyntheticEvent$1.extend({
4152
+ data: null
4153
+ });
4154
+
4155
+ var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
4156
+ var START_KEYCODE = 229;
4157
+
4158
+ var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window;
4159
+
4160
+ var documentMode = null;
4161
+ if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) {
4162
+ documentMode = document.documentMode;
4163
+ }
4164
+
4165
+ // Webkit offers a very useful `textInput` event that can be used to
4166
+ // directly represent `beforeInput`. The IE `textinput` event is not as
4167
+ // useful, so we don't use it.
4168
+ var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode;
4169
+
4170
+ // In IE9+, we have access to composition events, but the data supplied
4171
+ // by the native compositionend event may be incorrect. Japanese ideographic
4172
+ // spaces, for instance (\u3000) are not recorded correctly.
4173
+ var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
4174
+
4175
+ var SPACEBAR_CODE = 32;
4176
+ var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
4177
+
4178
+ // Events and their corresponding property names.
4179
+ var eventTypes = {
4180
+ beforeInput: {
4181
+ phasedRegistrationNames: {
4182
+ bubbled: 'onBeforeInput',
4183
+ captured: 'onBeforeInputCapture'
4184
+ },
4185
+ dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste']
4186
+ },
4187
+ compositionEnd: {
4188
+ phasedRegistrationNames: {
4189
+ bubbled: 'onCompositionEnd',
4190
+ captured: 'onCompositionEndCapture'
4191
+ },
4192
+ dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
4193
+ },
4194
+ compositionStart: {
4195
+ phasedRegistrationNames: {
4196
+ bubbled: 'onCompositionStart',
4197
+ captured: 'onCompositionStartCapture'
4198
+ },
4199
+ dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
4200
+ },
4201
+ compositionUpdate: {
4202
+ phasedRegistrationNames: {
4203
+ bubbled: 'onCompositionUpdate',
4204
+ captured: 'onCompositionUpdateCapture'
4205
+ },
4206
+ dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
4207
+ }
4208
+ };
4209
+
4210
+ // Track whether we've ever handled a keypress on the space key.
4211
+ var hasSpaceKeypress = false;
4212
+
4213
+ /**
4214
+ * Return whether a native keypress event is assumed to be a command.
4215
+ * This is required because Firefox fires `keypress` events for key commands
4216
+ * (cut, copy, select-all, etc.) even though no character is inserted.
4217
+ */
4218
+ function isKeypressCommand(nativeEvent) {
4219
+ return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
4220
+ // ctrlKey && altKey is equivalent to AltGr, and is not a command.
4221
+ !(nativeEvent.ctrlKey && nativeEvent.altKey);
4222
+ }
4223
+
4224
+ /**
4225
+ * Translate native top level events into event types.
4226
+ *
4227
+ * @param {string} topLevelType
4228
+ * @return {object}
4229
+ */
4230
+ function getCompositionEventType(topLevelType) {
4231
+ switch (topLevelType) {
4232
+ case 'topCompositionStart':
4233
+ return eventTypes.compositionStart;
4234
+ case 'topCompositionEnd':
4235
+ return eventTypes.compositionEnd;
4236
+ case 'topCompositionUpdate':
4237
+ return eventTypes.compositionUpdate;
4238
+ }
4239
+ }
4240
+
4241
+ /**
4242
+ * Does our fallback best-guess model think this event signifies that
4243
+ * composition has begun?
4244
+ *
4245
+ * @param {string} topLevelType
4246
+ * @param {object} nativeEvent
4247
+ * @return {boolean}
4248
+ */
4249
+ function isFallbackCompositionStart(topLevelType, nativeEvent) {
4250
+ return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
4251
+ }
4252
+
4253
+ /**
4254
+ * Does our fallback mode think that this event is the end of composition?
4255
+ *
4256
+ * @param {string} topLevelType
4257
+ * @param {object} nativeEvent
4258
+ * @return {boolean}
4259
+ */
4260
+ function isFallbackCompositionEnd(topLevelType, nativeEvent) {
4261
+ switch (topLevelType) {
4262
+ case 'topKeyUp':
4263
+ // Command keys insert or clear IME input.
4264
+ return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
4265
+ case 'topKeyDown':
4266
+ // Expect IME keyCode on each keydown. If we get any other
4267
+ // code we must have exited earlier.
4268
+ return nativeEvent.keyCode !== START_KEYCODE;
4269
+ case 'topKeyPress':
4270
+ case 'topMouseDown':
4271
+ case 'topBlur':
4272
+ // Events are not possible without cancelling IME.
4273
+ return true;
4274
+ default:
4275
+ return false;
4276
+ }
4277
+ }
4278
+
4279
+ /**
4280
+ * Google Input Tools provides composition data via a CustomEvent,
4281
+ * with the `data` property populated in the `detail` object. If this
4282
+ * is available on the event object, use it. If not, this is a plain
4283
+ * composition event and we have nothing special to extract.
4284
+ *
4285
+ * @param {object} nativeEvent
4286
+ * @return {?string}
4287
+ */
4288
+ function getDataFromCustomEvent(nativeEvent) {
4289
+ var detail = nativeEvent.detail;
4290
+ if (typeof detail === 'object' && 'data' in detail) {
4291
+ return detail.data;
4292
+ }
4293
+ return null;
4294
+ }
4295
+
4296
+ // Track the current IME composition status, if any.
4297
+ var isComposing = false;
4298
+
4299
+ /**
4300
+ * @return {?object} A SyntheticCompositionEvent.
4301
+ */
4302
+ function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4303
+ var eventType = void 0;
4304
+ var fallbackData = void 0;
4305
+
4306
+ if (canUseCompositionEvent) {
4307
+ eventType = getCompositionEventType(topLevelType);
4308
+ } else if (!isComposing) {
4309
+ if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
4310
+ eventType = eventTypes.compositionStart;
4311
+ }
4312
+ } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
4313
+ eventType = eventTypes.compositionEnd;
4314
+ }
4315
+
4316
+ if (!eventType) {
4317
+ return null;
4318
+ }
4319
+
4320
+ if (useFallbackCompositionData) {
4321
+ // The current composition is stored statically and must not be
4322
+ // overwritten while composition continues.
4323
+ if (!isComposing && eventType === eventTypes.compositionStart) {
4324
+ isComposing = initialize(nativeEventTarget);
4325
+ } else if (eventType === eventTypes.compositionEnd) {
4326
+ if (isComposing) {
4327
+ fallbackData = getData();
4328
+ }
4329
+ }
4330
+ }
4331
+
4332
+ var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
4333
+
4334
+ if (fallbackData) {
4335
+ // Inject data generated from fallback path into the synthetic event.
4336
+ // This matches the property of native CompositionEventInterface.
4337
+ event.data = fallbackData;
4338
+ } else {
4339
+ var customData = getDataFromCustomEvent(nativeEvent);
4340
+ if (customData !== null) {
4341
+ event.data = customData;
4342
+ }
4343
+ }
4344
+
4345
+ accumulateTwoPhaseDispatches(event);
4346
+ return event;
4347
+ }
4348
+
4349
+ /**
4350
+ * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`.
4351
+ * @param {object} nativeEvent Native browser event.
4352
+ * @return {?string} The string corresponding to this `beforeInput` event.
4353
+ */
4354
+ function getNativeBeforeInputChars(topLevelType, nativeEvent) {
4355
+ switch (topLevelType) {
4356
+ case 'topCompositionEnd':
4357
+ return getDataFromCustomEvent(nativeEvent);
4358
+ case 'topKeyPress':
4359
+ /**
4360
+ * If native `textInput` events are available, our goal is to make
4361
+ * use of them. However, there is a special case: the spacebar key.
4362
+ * In Webkit, preventing default on a spacebar `textInput` event
4363
+ * cancels character insertion, but it *also* causes the browser
4364
+ * to fall back to its default spacebar behavior of scrolling the
4365
+ * page.
4366
+ *
4367
+ * Tracking at:
4368
+ * https://code.google.com/p/chromium/issues/detail?id=355103
4369
+ *
4370
+ * To avoid this issue, use the keypress event as if no `textInput`
4371
+ * event is available.
4372
+ */
4373
+ var which = nativeEvent.which;
4374
+ if (which !== SPACEBAR_CODE) {
4375
+ return null;
4376
+ }
4377
+
4378
+ hasSpaceKeypress = true;
4379
+ return SPACEBAR_CHAR;
4380
+
4381
+ case 'topTextInput':
4382
+ // Record the characters to be added to the DOM.
4383
+ var chars = nativeEvent.data;
4384
+
4385
+ // If it's a spacebar character, assume that we have already handled
4386
+ // it at the keypress level and bail immediately. Android Chrome
4387
+ // doesn't give us keycodes, so we need to blacklist it.
4388
+ if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
4389
+ return null;
4390
+ }
4391
+
4392
+ return chars;
4393
+
4394
+ default:
4395
+ // For other native event types, do nothing.
4396
+ return null;
4397
+ }
4398
+ }
4399
+
4400
+ /**
4401
+ * For browsers that do not provide the `textInput` event, extract the
4402
+ * appropriate string to use for SyntheticInputEvent.
4403
+ *
4404
+ * @param {string} topLevelType Record from `BrowserEventConstants`.
4405
+ * @param {object} nativeEvent Native browser event.
4406
+ * @return {?string} The fallback string for this `beforeInput` event.
4407
+ */
4408
+ function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
4409
+ // If we are currently composing (IME) and using a fallback to do so,
4410
+ // try to extract the composed characters from the fallback object.
4411
+ // If composition event is available, we extract a string only at
4412
+ // compositionevent, otherwise extract it at fallback events.
4413
+ if (isComposing) {
4414
+ if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
4415
+ var chars = getData();
4416
+ reset();
4417
+ isComposing = false;
4418
+ return chars;
4419
+ }
4420
+ return null;
4421
+ }
4422
+
4423
+ switch (topLevelType) {
4424
+ case 'topPaste':
4425
+ // If a paste event occurs after a keypress, throw out the input
4426
+ // chars. Paste events should not lead to BeforeInput events.
4427
+ return null;
4428
+ case 'topKeyPress':
4429
+ /**
4430
+ * As of v27, Firefox may fire keypress events even when no character
4431
+ * will be inserted. A few possibilities:
4432
+ *
4433
+ * - `which` is `0`. Arrow keys, Esc key, etc.
4434
+ *
4435
+ * - `which` is the pressed key code, but no char is available.
4436
+ * Ex: 'AltGr + d` in Polish. There is no modified character for
4437
+ * this key combination and no character is inserted into the
4438
+ * document, but FF fires the keypress for char code `100` anyway.
4439
+ * No `input` event will occur.
4440
+ *
4441
+ * - `which` is the pressed key code, but a command combination is
4442
+ * being used. Ex: `Cmd+C`. No character is inserted, and no
4443
+ * `input` event will occur.
4444
+ */
4445
+ if (!isKeypressCommand(nativeEvent)) {
4446
+ // IE fires the `keypress` event when a user types an emoji via
4447
+ // Touch keyboard of Windows. In such a case, the `char` property
4448
+ // holds an emoji character like `\uD83D\uDE0A`. Because its length
4449
+ // is 2, the property `which` does not represent an emoji correctly.
4450
+ // In such a case, we directly return the `char` property instead of
4451
+ // using `which`.
4452
+ if (nativeEvent.char && nativeEvent.char.length > 1) {
4453
+ return nativeEvent.char;
4454
+ } else if (nativeEvent.which) {
4455
+ return String.fromCharCode(nativeEvent.which);
4456
+ }
4457
+ }
4458
+ return null;
4459
+ case 'topCompositionEnd':
4460
+ return useFallbackCompositionData ? null : nativeEvent.data;
4461
+ default:
4462
+ return null;
4463
+ }
4464
+ }
4465
+
4466
+ /**
4467
+ * Extract a SyntheticInputEvent for `beforeInput`, based on either native
4468
+ * `textInput` or fallback behavior.
4469
+ *
4470
+ * @return {?object} A SyntheticInputEvent.
4471
+ */
4472
+ function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4473
+ var chars = void 0;
4474
+
4475
+ if (canUseTextInputEvent) {
4476
+ chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
4477
+ } else {
4478
+ chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
4479
+ }
4480
+
4481
+ // If no characters are being inserted, no BeforeInput event should
4482
+ // be fired.
4483
+ if (!chars) {
4484
+ return null;
4485
+ }
4486
+
4487
+ var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
4488
+
4489
+ event.data = chars;
4490
+ accumulateTwoPhaseDispatches(event);
4491
+ return event;
4492
+ }
4493
+
4494
+ /**
4495
+ * Create an `onBeforeInput` event to match
4496
+ * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
4497
+ *
4498
+ * This event plugin is based on the native `textInput` event
4499
+ * available in Chrome, Safari, Opera, and IE. This event fires after
4500
+ * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
4501
+ *
4502
+ * `beforeInput` is spec'd but not implemented in any browsers, and
4503
+ * the `input` event does not provide any useful information about what has
4504
+ * actually been added, contrary to the spec. Thus, `textInput` is the best
4505
+ * available event to identify the characters that have actually been inserted
4506
+ * into the target node.
4507
+ *
4508
+ * This plugin is also responsible for emitting `composition` events, thus
4509
+ * allowing us to share composition fallback code for both `beforeInput` and
4510
+ * `composition` event types.
4511
+ */
4512
+ var BeforeInputEventPlugin = {
4513
+ eventTypes: eventTypes,
4514
+
4515
+ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4516
+ var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
4517
+
4518
+ var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
4519
+
4520
+ if (composition === null) {
4521
+ return beforeInput;
4522
+ }
4523
+
4524
+ if (beforeInput === null) {
4525
+ return composition;
4526
+ }
4527
+
4528
+ return [composition, beforeInput];
4529
+ }
4530
+ };
4531
+
4532
+ // Use to restore controlled state after a change event has fired.
4533
+
4534
+ var fiberHostComponent = null;
4535
+
4536
+ var ReactControlledComponentInjection = {
4537
+ injectFiberControlledHostComponent: function (hostComponentImpl) {
4538
+ // The fiber implementation doesn't use dynamic dispatch so we need to
4539
+ // inject the implementation.
4540
+ fiberHostComponent = hostComponentImpl;
4541
+ }
4542
+ };
4543
+
4544
+ var restoreTarget = null;
4545
+ var restoreQueue = null;
4546
+
4547
+ function restoreStateOfTarget(target) {
4548
+ // We perform this translation at the end of the event loop so that we
4549
+ // always receive the correct fiber here
4550
+ var internalInstance = getInstanceFromNode(target);
4551
+ if (!internalInstance) {
4552
+ // Unmounted
4553
+ return;
4554
+ }
4555
+ !(fiberHostComponent && typeof fiberHostComponent.restoreControlledState === 'function') ? invariant(false, 'Fiber needs to be injected to handle a fiber target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4556
+ var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
4557
+ fiberHostComponent.restoreControlledState(internalInstance.stateNode, internalInstance.type, props);
4558
+ }
4559
+
4560
+ var injection$2 = ReactControlledComponentInjection;
4561
+
4562
+ function enqueueStateRestore(target) {
4563
+ if (restoreTarget) {
4564
+ if (restoreQueue) {
4565
+ restoreQueue.push(target);
4566
+ } else {
4567
+ restoreQueue = [target];
4568
+ }
4569
+ } else {
4570
+ restoreTarget = target;
4571
+ }
4572
+ }
4573
+
4574
+ function needsStateRestore() {
4575
+ return restoreTarget !== null || restoreQueue !== null;
4576
+ }
4577
+
4578
+ function restoreStateIfNeeded() {
4579
+ if (!restoreTarget) {
4580
+ return;
4581
+ }
4582
+ var target = restoreTarget;
4583
+ var queuedTargets = restoreQueue;
4584
+ restoreTarget = null;
4585
+ restoreQueue = null;
4586
+
4587
+ restoreStateOfTarget(target);
4588
+ if (queuedTargets) {
4589
+ for (var i = 0; i < queuedTargets.length; i++) {
4590
+ restoreStateOfTarget(queuedTargets[i]);
4591
+ }
4592
+ }
4593
+ }
4594
+
4595
+ var ReactControlledComponent = Object.freeze({
4596
+ injection: injection$2,
4597
+ enqueueStateRestore: enqueueStateRestore,
4598
+ needsStateRestore: needsStateRestore,
4599
+ restoreStateIfNeeded: restoreStateIfNeeded
4600
+ });
4601
+
4602
+ // Used as a way to call batchedUpdates when we don't have a reference to
4603
+ // the renderer. Such as when we're dispatching events or if third party
4604
+ // libraries need to call batchedUpdates. Eventually, this API will go away when
4605
+ // everything is batched by default. We'll then have a similar API to opt-out of
4606
+ // scheduled work and instead do synchronous work.
4607
+
4608
+ // Defaults
4609
+ var _batchedUpdates = function (fn, bookkeeping) {
4610
+ return fn(bookkeeping);
4611
+ };
4612
+ var _interactiveUpdates = function (fn, a, b) {
4613
+ return fn(a, b);
4614
+ };
4615
+ var _flushInteractiveUpdates = function () {};
4616
+
4617
+ var isBatching = false;
4618
+ function batchedUpdates(fn, bookkeeping) {
4619
+ if (isBatching) {
4620
+ // If we are currently inside another batch, we need to wait until it
4621
+ // fully completes before restoring state.
4622
+ return fn(bookkeeping);
4623
+ }
4624
+ isBatching = true;
4625
+ try {
4626
+ return _batchedUpdates(fn, bookkeeping);
4627
+ } finally {
4628
+ // Here we wait until all updates have propagated, which is important
4629
+ // when using controlled components within layers:
4630
+ // https://github.com/facebook/react/issues/1698
4631
+ // Then we restore state of any controlled component.
4632
+ isBatching = false;
4633
+ var controlledComponentsHavePendingUpdates = needsStateRestore();
4634
+ if (controlledComponentsHavePendingUpdates) {
4635
+ // If a controlled event was fired, we may need to restore the state of
4636
+ // the DOM node back to the controlled value. This is necessary when React
4637
+ // bails out of the update without touching the DOM.
4638
+ _flushInteractiveUpdates();
4639
+ restoreStateIfNeeded();
4640
+ }
4641
+ }
4642
+ }
4643
+
4644
+ function interactiveUpdates(fn, a, b) {
4645
+ return _interactiveUpdates(fn, a, b);
4646
+ }
4647
+
4648
+
4649
+
4650
+ var injection$3 = {
4651
+ injectRenderer: function (renderer) {
4652
+ _batchedUpdates = renderer.batchedUpdates;
4653
+ _interactiveUpdates = renderer.interactiveUpdates;
4654
+ _flushInteractiveUpdates = renderer.flushInteractiveUpdates;
4655
+ }
4656
+ };
4657
+
4658
+ /**
4659
+ * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
4660
+ */
4661
+ var supportedInputTypes = {
4662
+ color: true,
4663
+ date: true,
4664
+ datetime: true,
4665
+ 'datetime-local': true,
4666
+ email: true,
4667
+ month: true,
4668
+ number: true,
4669
+ password: true,
4670
+ range: true,
4671
+ search: true,
4672
+ tel: true,
4673
+ text: true,
4674
+ time: true,
4675
+ url: true,
4676
+ week: true
4677
+ };
4678
+
4679
+ function isTextInputElement(elem) {
4680
+ var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
4681
+
4682
+ if (nodeName === 'input') {
4683
+ return !!supportedInputTypes[elem.type];
4684
+ }
4685
+
4686
+ if (nodeName === 'textarea') {
4687
+ return true;
4688
+ }
4689
+
4690
+ return false;
4691
+ }
4692
+
4693
+ /**
4694
+ * HTML nodeType values that represent the type of the node
4695
+ */
4696
+
4697
+ var ELEMENT_NODE = 1;
4698
+ var TEXT_NODE = 3;
4699
+ var COMMENT_NODE = 8;
4700
+ var DOCUMENT_NODE = 9;
4701
+ var DOCUMENT_FRAGMENT_NODE = 11;
4702
+
4703
+ /**
4704
+ * Gets the target node from a native browser event by accounting for
4705
+ * inconsistencies in browser DOM APIs.
4706
+ *
4707
+ * @param {object} nativeEvent Native browser event.
4708
+ * @return {DOMEventTarget} Target node.
4709
+ */
4710
+ function getEventTarget(nativeEvent) {
4711
+ var target = nativeEvent.target || window;
4712
+
4713
+ // Normalize SVG <use> element events #4963
4714
+ if (target.correspondingUseElement) {
4715
+ target = target.correspondingUseElement;
4716
+ }
4717
+
4718
+ // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
4719
+ // @see http://www.quirksmode.org/js/events_properties.html
4720
+ return target.nodeType === TEXT_NODE ? target.parentNode : target;
4721
+ }
4722
+
4723
+ /**
4724
+ * Checks if an event is supported in the current execution environment.
4725
+ *
4726
+ * NOTE: This will not work correctly for non-generic events such as `change`,
4727
+ * `reset`, `load`, `error`, and `select`.
4728
+ *
4729
+ * Borrows from Modernizr.
4730
+ *
4731
+ * @param {string} eventNameSuffix Event name, e.g. "click".
4732
+ * @param {?boolean} capture Check if the capture phase is supported.
4733
+ * @return {boolean} True if the event is supported.
4734
+ * @internal
4735
+ * @license Modernizr 3.0.0pre (Custom Build) | MIT
4736
+ */
4737
+ function isEventSupported(eventNameSuffix, capture) {
4738
+ if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) {
4739
+ return false;
4740
+ }
4741
+
4742
+ var eventName = 'on' + eventNameSuffix;
4743
+ var isSupported = eventName in document;
4744
+
4745
+ if (!isSupported) {
4746
+ var element = document.createElement('div');
4747
+ element.setAttribute(eventName, 'return;');
4748
+ isSupported = typeof element[eventName] === 'function';
4749
+ }
4750
+
4751
+ return isSupported;
4752
+ }
4753
+
4754
+ function isCheckable(elem) {
4755
+ var type = elem.type;
4756
+ var nodeName = elem.nodeName;
4757
+ return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
4758
+ }
4759
+
4760
+ function getTracker(node) {
4761
+ return node._valueTracker;
4762
+ }
4763
+
4764
+ function detachTracker(node) {
4765
+ node._valueTracker = null;
4766
+ }
4767
+
4768
+ function getValueFromNode(node) {
4769
+ var value = '';
4770
+ if (!node) {
4771
+ return value;
4772
+ }
4773
+
4774
+ if (isCheckable(node)) {
4775
+ value = node.checked ? 'true' : 'false';
4776
+ } else {
4777
+ value = node.value;
4778
+ }
4779
+
4780
+ return value;
4781
+ }
4782
+
4783
+ function trackValueOnNode(node) {
4784
+ var valueField = isCheckable(node) ? 'checked' : 'value';
4785
+ var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
4786
+
4787
+ var currentValue = '' + node[valueField];
4788
+
4789
+ // if someone has already defined a value or Safari, then bail
4790
+ // and don't track value will cause over reporting of changes,
4791
+ // but it's better then a hard failure
4792
+ // (needed for certain tests that spyOn input values and Safari)
4793
+ if (node.hasOwnProperty(valueField) || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
4794
+ return;
4795
+ }
4796
+
4797
+ Object.defineProperty(node, valueField, {
4798
+ configurable: true,
4799
+ get: function () {
4800
+ return descriptor.get.call(this);
4801
+ },
4802
+ set: function (value) {
4803
+ currentValue = '' + value;
4804
+ descriptor.set.call(this, value);
4805
+ }
4806
+ });
4807
+ // We could've passed this the first time
4808
+ // but it triggers a bug in IE11 and Edge 14/15.
4809
+ // Calling defineProperty() again should be equivalent.
4810
+ // https://github.com/facebook/react/issues/11768
4811
+ Object.defineProperty(node, valueField, {
4812
+ enumerable: descriptor.enumerable
4813
+ });
4814
+
4815
+ var tracker = {
4816
+ getValue: function () {
4817
+ return currentValue;
4818
+ },
4819
+ setValue: function (value) {
4820
+ currentValue = '' + value;
4821
+ },
4822
+ stopTracking: function () {
4823
+ detachTracker(node);
4824
+ delete node[valueField];
4825
+ }
4826
+ };
4827
+ return tracker;
4828
+ }
4829
+
4830
+ function track(node) {
4831
+ if (getTracker(node)) {
4832
+ return;
4833
+ }
4834
+
4835
+ // TODO: Once it's just Fiber we can move this to node._wrapperState
4836
+ node._valueTracker = trackValueOnNode(node);
4837
+ }
4838
+
4839
+ function updateValueIfChanged(node) {
4840
+ if (!node) {
4841
+ return false;
4842
+ }
4843
+
4844
+ var tracker = getTracker(node);
4845
+ // if there is no tracker at this point it's unlikely
4846
+ // that trying again will succeed
4847
+ if (!tracker) {
4848
+ return true;
4849
+ }
4850
+
4851
+ var lastValue = tracker.getValue();
4852
+ var nextValue = getValueFromNode(node);
4853
+ if (nextValue !== lastValue) {
4854
+ tracker.setValue(nextValue);
4855
+ return true;
4856
+ }
4857
+ return false;
4858
+ }
4859
+
4860
+ var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
4861
+
4862
+ var ReactCurrentOwner = ReactInternals.ReactCurrentOwner;
4863
+ var ReactDebugCurrentFrame = ReactInternals.ReactDebugCurrentFrame;
4864
+
4865
+ var describeComponentFrame = function (name, source, ownerName) {
4866
+ return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
4867
+ };
4868
+
4869
+ // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
4870
+ // nor polyfill, then a plain number is used for performance.
4871
+ var hasSymbol = typeof Symbol === 'function' && Symbol['for'];
4872
+
4873
+ var REACT_ELEMENT_TYPE = hasSymbol ? Symbol['for']('react.element') : 0xeac7;
4874
+ var REACT_CALL_TYPE = hasSymbol ? Symbol['for']('react.call') : 0xeac8;
4875
+ var REACT_RETURN_TYPE = hasSymbol ? Symbol['for']('react.return') : 0xeac9;
4876
+ var REACT_PORTAL_TYPE = hasSymbol ? Symbol['for']('react.portal') : 0xeaca;
4877
+ var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol['for']('react.fragment') : 0xeacb;
4878
+ var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol['for']('react.strict_mode') : 0xeacc;
4879
+ var REACT_PROVIDER_TYPE = hasSymbol ? Symbol['for']('react.provider') : 0xeacd;
4880
+ var REACT_CONTEXT_TYPE = hasSymbol ? Symbol['for']('react.context') : 0xeace;
4881
+ var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol['for']('react.async_mode') : 0xeacf;
4882
+ var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol['for']('react.forward_ref') : 0xead0;
4883
+
4884
+ var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
4885
+ var FAUX_ITERATOR_SYMBOL = '@@iterator';
4886
+
4887
+ function getIteratorFn(maybeIterable) {
4888
+ if (maybeIterable === null || typeof maybeIterable === 'undefined') {
4889
+ return null;
4890
+ }
4891
+ var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
4892
+ if (typeof maybeIterator === 'function') {
4893
+ return maybeIterator;
4894
+ }
4895
+ return null;
4896
+ }
4897
+
4898
+ function getComponentName(fiber) {
4899
+ var type = fiber.type;
4900
+
4901
+ if (typeof type === 'function') {
4902
+ return type.displayName || type.name;
4903
+ }
4904
+ if (typeof type === 'string') {
4905
+ return type;
4906
+ }
4907
+ switch (type) {
4908
+ case REACT_FRAGMENT_TYPE:
4909
+ return 'ReactFragment';
4910
+ case REACT_PORTAL_TYPE:
4911
+ return 'ReactPortal';
4912
+ case REACT_CALL_TYPE:
4913
+ return 'ReactCall';
4914
+ case REACT_RETURN_TYPE:
4915
+ return 'ReactReturn';
4916
+ }
4917
+ if (typeof type === 'object' && type !== null) {
4918
+ switch (type.$$typeof) {
4919
+ case REACT_FORWARD_REF_TYPE:
4920
+ var functionName = type.render.displayName || type.render.name || '';
4921
+ return functionName !== '' ? 'ForwardRef(' + functionName + ')' : 'ForwardRef';
4922
+ }
4923
+ }
4924
+ return null;
4925
+ }
4926
+
4927
+ function describeFiber(fiber) {
4928
+ switch (fiber.tag) {
4929
+ case IndeterminateComponent:
4930
+ case FunctionalComponent:
4931
+ case ClassComponent:
4932
+ case HostComponent:
4933
+ var owner = fiber._debugOwner;
4934
+ var source = fiber._debugSource;
4935
+ var name = getComponentName(fiber);
4936
+ var ownerName = null;
4937
+ if (owner) {
4938
+ ownerName = getComponentName(owner);
4939
+ }
4940
+ return describeComponentFrame(name, source, ownerName);
4941
+ default:
4942
+ return '';
4943
+ }
4944
+ }
4945
+
4946
+ // This function can only be called with a work-in-progress fiber and
4947
+ // only during begin or complete phase. Do not call it under any other
4948
+ // circumstances.
4949
+ function getStackAddendumByWorkInProgressFiber(workInProgress) {
4950
+ var info = '';
4951
+ var node = workInProgress;
4952
+ do {
4953
+ info += describeFiber(node);
4954
+ // Otherwise this return pointer might point to the wrong tree:
4955
+ node = node['return'];
4956
+ } while (node);
4957
+ return info;
4958
+ }
4959
+
4960
+ function getCurrentFiberOwnerName$1() {
4961
+ {
4962
+ var fiber = ReactDebugCurrentFiber.current;
4963
+ if (fiber === null) {
4964
+ return null;
4965
+ }
4966
+ var owner = fiber._debugOwner;
4967
+ if (owner !== null && typeof owner !== 'undefined') {
4968
+ return getComponentName(owner);
4969
+ }
4970
+ }
4971
+ return null;
4972
+ }
4973
+
4974
+ function getCurrentFiberStackAddendum$1() {
4975
+ {
4976
+ var fiber = ReactDebugCurrentFiber.current;
4977
+ if (fiber === null) {
4978
+ return null;
4979
+ }
4980
+ // Safe because if current fiber exists, we are reconciling,
4981
+ // and it is guaranteed to be the work-in-progress version.
4982
+ return getStackAddendumByWorkInProgressFiber(fiber);
4983
+ }
4984
+ return null;
4985
+ }
4986
+
4987
+ function resetCurrentFiber() {
4988
+ ReactDebugCurrentFrame.getCurrentStack = null;
4989
+ ReactDebugCurrentFiber.current = null;
4990
+ ReactDebugCurrentFiber.phase = null;
4991
+ }
4992
+
4993
+ function setCurrentFiber(fiber) {
4994
+ ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1;
4995
+ ReactDebugCurrentFiber.current = fiber;
4996
+ ReactDebugCurrentFiber.phase = null;
4997
+ }
4998
+
4999
+ function setCurrentPhase(phase) {
5000
+ ReactDebugCurrentFiber.phase = phase;
5001
+ }
5002
+
5003
+ var ReactDebugCurrentFiber = {
5004
+ current: null,
5005
+ phase: null,
5006
+ resetCurrentFiber: resetCurrentFiber,
5007
+ setCurrentFiber: setCurrentFiber,
5008
+ setCurrentPhase: setCurrentPhase,
5009
+ getCurrentFiberOwnerName: getCurrentFiberOwnerName$1,
5010
+ getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1
5011
+ };
5012
+
5013
+ // A reserved attribute.
5014
+ // It is handled by React separately and shouldn't be written to the DOM.
5015
+ var RESERVED = 0;
5016
+
5017
+ // A simple string attribute.
5018
+ // Attributes that aren't in the whitelist are presumed to have this type.
5019
+ var STRING = 1;
5020
+
5021
+ // A string attribute that accepts booleans in React. In HTML, these are called
5022
+ // "enumerated" attributes with "true" and "false" as possible values.
5023
+ // When true, it should be set to a "true" string.
5024
+ // When false, it should be set to a "false" string.
5025
+ var BOOLEANISH_STRING = 2;
5026
+
5027
+ // A real boolean attribute.
5028
+ // When true, it should be present (set either to an empty string or its name).
5029
+ // When false, it should be omitted.
5030
+ var BOOLEAN = 3;
5031
+
5032
+ // An attribute that can be used as a flag as well as with a value.
5033
+ // When true, it should be present (set either to an empty string or its name).
5034
+ // When false, it should be omitted.
5035
+ // For any other value, should be present with that value.
5036
+ var OVERLOADED_BOOLEAN = 4;
5037
+
5038
+ // An attribute that must be numeric or parse as a numeric.
5039
+ // When falsy, it should be removed.
5040
+ var NUMERIC = 5;
5041
+
5042
+ // An attribute that must be positive numeric or parse as a positive numeric.
5043
+ // When falsy, it should be removed.
5044
+ var POSITIVE_NUMERIC = 6;
5045
+
5046
+ /* eslint-disable max-len */
5047
+ var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
5048
+ /* eslint-enable max-len */
5049
+ var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
5050
+
5051
+
5052
+ var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
5053
+ var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
5054
+
5055
+ var illegalAttributeNameCache = {};
5056
+ var validatedAttributeNameCache = {};
5057
+
5058
+ function isAttributeNameSafe(attributeName) {
5059
+ if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {
5060
+ return true;
5061
+ }
5062
+ if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {
5063
+ return false;
5064
+ }
5065
+ if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
5066
+ validatedAttributeNameCache[attributeName] = true;
5067
+ return true;
5068
+ }
5069
+ illegalAttributeNameCache[attributeName] = true;
5070
+ {
5071
+ warning(false, 'Invalid attribute name: `%s`', attributeName);
5072
+ }
5073
+ return false;
5074
+ }
5075
+
5076
+ function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
5077
+ if (propertyInfo !== null) {
5078
+ return propertyInfo.type === RESERVED;
5079
+ }
5080
+ if (isCustomComponentTag) {
5081
+ return false;
5082
+ }
5083
+ if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
5084
+ return true;
5085
+ }
5086
+ return false;
5087
+ }
5088
+
5089
+ function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
5090
+ if (propertyInfo !== null && propertyInfo.type === RESERVED) {
5091
+ return false;
5092
+ }
5093
+ switch (typeof value) {
5094
+ case 'function':
5095
+ // $FlowIssue symbol is perfectly valid here
5096
+ case 'symbol':
5097
+ // eslint-disable-line
5098
+ return true;
5099
+ case 'boolean':
5100
+ {
5101
+ if (isCustomComponentTag) {
5102
+ return false;
5103
+ }
5104
+ if (propertyInfo !== null) {
5105
+ return !propertyInfo.acceptsBooleans;
5106
+ } else {
5107
+ var prefix = name.toLowerCase().slice(0, 5);
5108
+ return prefix !== 'data-' && prefix !== 'aria-';
5109
+ }
5110
+ }
5111
+ default:
5112
+ return false;
5113
+ }
5114
+ }
5115
+
5116
+ function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
5117
+ if (value === null || typeof value === 'undefined') {
5118
+ return true;
5119
+ }
5120
+ if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
5121
+ return true;
5122
+ }
5123
+ if (propertyInfo !== null) {
5124
+ switch (propertyInfo.type) {
5125
+ case BOOLEAN:
5126
+ return !value;
5127
+ case OVERLOADED_BOOLEAN:
5128
+ return value === false;
5129
+ case NUMERIC:
5130
+ return isNaN(value);
5131
+ case POSITIVE_NUMERIC:
5132
+ return isNaN(value) || value < 1;
5133
+ }
5134
+ }
5135
+ return false;
5136
+ }
5137
+
5138
+ function getPropertyInfo(name) {
5139
+ return properties.hasOwnProperty(name) ? properties[name] : null;
5140
+ }
5141
+
5142
+ function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
5143
+ this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
5144
+ this.attributeName = attributeName;
5145
+ this.attributeNamespace = attributeNamespace;
5146
+ this.mustUseProperty = mustUseProperty;
5147
+ this.propertyName = name;
5148
+ this.type = type;
5149
+ }
5150
+
5151
+ // When adding attributes to this list, be sure to also add them to
5152
+ // the `possibleStandardNames` module to ensure casing and incorrect
5153
+ // name warnings.
5154
+ var properties = {};
5155
+
5156
+ // These props are reserved by React. They shouldn't be written to the DOM.
5157
+ ['children', 'dangerouslySetInnerHTML',
5158
+ // TODO: This prevents the assignment of defaultValue to regular
5159
+ // elements (not just inputs). Now that ReactDOMInput assigns to the
5160
+ // defaultValue property -- do we need this?
5161
+ 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
5162
+ properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
5163
+ name, // attributeName
5164
+ null);
5165
+ });
5166
+
5167
+ // A few React string attributes have a different name.
5168
+ // This is a mapping from React prop names to the attribute names.
5169
+ [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
5170
+ var name = _ref[0],
5171
+ attributeName = _ref[1];
5172
+
5173
+ properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
5174
+ attributeName, // attributeName
5175
+ null);
5176
+ });
5177
+
5178
+ // These are "enumerated" HTML attributes that accept "true" and "false".
5179
+ // In React, we let users pass `true` and `false` even though technically
5180
+ // these aren't boolean attributes (they are coerced to strings).
5181
+ ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
5182
+ properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
5183
+ name.toLowerCase(), // attributeName
5184
+ null);
5185
+ });
5186
+
5187
+ // These are "enumerated" SVG attributes that accept "true" and "false".
5188
+ // In React, we let users pass `true` and `false` even though technically
5189
+ // these aren't boolean attributes (they are coerced to strings).
5190
+ // Since these are SVG attributes, their attribute names are case-sensitive.
5191
+ ['autoReverse', 'externalResourcesRequired', 'preserveAlpha'].forEach(function (name) {
5192
+ properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
5193
+ name, // attributeName
5194
+ null);
5195
+ });
5196
+
5197
+ // These are HTML boolean attributes.
5198
+ ['allowFullScreen', 'async',
5199
+ // Note: there is a special case that prevents it from being written to the DOM
5200
+ // on the client side because the browsers are inconsistent. Instead we call focus().
5201
+ 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
5202
+ // Microdata
5203
+ 'itemScope'].forEach(function (name) {
5204
+ properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
5205
+ name.toLowerCase(), // attributeName
5206
+ null);
5207
+ });
5208
+
5209
+ // These are the few React props that we set as DOM properties
5210
+ // rather than attributes. These are all booleans.
5211
+ ['checked',
5212
+ // Note: `option.selected` is not updated if `select.multiple` is
5213
+ // disabled with `removeAttribute`. We have special logic for handling this.
5214
+ 'multiple', 'muted', 'selected'].forEach(function (name) {
5215
+ properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
5216
+ name.toLowerCase(), // attributeNam